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

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2005-09-21 04:00:00 +0400
committerKornel LesiƄski <kornel@geekhood.net>2016-05-28 02:15:44 +0300
commitd66cf2fcf3cc3667f76f1ea50e8360f1c2813753 (patch)
tree22ffe1a5473b0e988ab1626a0294e1e1b80ca3ee
parent31e7b924e826b529aa3ad412730a02ee06959985 (diff)
4.27 beta
-rwxr-xr-x7zip/Archive/7z/7z.dsp8
-rwxr-xr-x7zip/Archive/7z/7zDecode.cpp8
-rwxr-xr-x7zip/Archive/7z/7zExtract.cpp8
-rwxr-xr-x7zip/Archive/7z/7zFolderInStream.cpp22
-rwxr-xr-x7zip/Archive/7z/7zFolderInStream.h1
-rwxr-xr-x7zip/Archive/7z/7zFolderOutStream.cpp9
-rwxr-xr-x7zip/Archive/7z/7zFolderOutStream.h1
-rwxr-xr-x7zip/Archive/7z/7zHandler.h4
-rwxr-xr-x7zip/Archive/7z/7zIn.cpp11
-rwxr-xr-x7zip/Archive/7z/7zOut.cpp11
-rwxr-xr-x7zip/Archive/7z/7zSpecStream.cpp10
-rwxr-xr-x7zip/Archive/7z/7zSpecStream.h1
-rwxr-xr-x7zip/Archive/7z/7zUpdate.cpp116
-rwxr-xr-x7zip/Archive/7z/7zUpdate.h2
-rwxr-xr-x7zip/Archive/7z/makefile1
-rwxr-xr-x7zip/Archive/7z_C/makefile.gcc50
-rwxr-xr-x7zip/Archive/Arj/Arj.dsp24
-rwxr-xr-x7zip/Archive/Arj/ArjHandler.cpp4
-rwxr-xr-x7zip/Archive/Arj/ArjIn.cpp6
-rwxr-xr-x7zip/Archive/Arj/DllExports.cpp4
-rwxr-xr-x7zip/Archive/Arj/makefile6
-rwxr-xr-x7zip/Archive/BZip2/BZip2.dsp8
-rwxr-xr-x7zip/Archive/BZip2/BZip2Handler.cpp6
-rwxr-xr-x7zip/Archive/BZip2/DllExports.cpp4
-rwxr-xr-x7zip/Archive/BZip2/makefile1
-rwxr-xr-x7zip/Archive/Cab/Cab.dsp126
-rwxr-xr-x7zip/Archive/Cab/CabBlockInStream.cpp194
-rwxr-xr-x7zip/Archive/Cab/CabBlockInStream.h56
-rwxr-xr-x7zip/Archive/Cab/CabCopyDecoder.cpp73
-rwxr-xr-x7zip/Archive/Cab/CabCopyDecoder.h41
-rwxr-xr-x7zip/Archive/Cab/CabHandler.cpp794
-rwxr-xr-x7zip/Archive/Cab/CabHandler.h5
-rwxr-xr-x7zip/Archive/Cab/CabHeader.h79
-rwxr-xr-x7zip/Archive/Cab/CabIn.cpp352
-rwxr-xr-x7zip/Archive/Cab/CabIn.h131
-rwxr-xr-x7zip/Archive/Cab/CabInBuffer.cpp175
-rwxr-xr-x7zip/Archive/Cab/CabInBuffer.h66
-rwxr-xr-x7zip/Archive/Cab/CabItem.h54
-rwxr-xr-x7zip/Archive/Cab/DllExports.cpp6
-rwxr-xr-x7zip/Archive/Cab/LZXBitDecoder.h111
-rwxr-xr-x7zip/Archive/Cab/LZXConst.h110
-rwxr-xr-x7zip/Archive/Cab/LZXDecoder.cpp310
-rwxr-xr-x7zip/Archive/Cab/LZXDecoder.h95
-rwxr-xr-x7zip/Archive/Cab/LZXExtConst.h30
-rwxr-xr-x7zip/Archive/Cab/MSZipConst.h92
-rwxr-xr-x7zip/Archive/Cab/MSZipDecoder.cpp268
-rwxr-xr-x7zip/Archive/Cab/MSZipDecoder.h85
-rwxr-xr-x7zip/Archive/Cab/MSZipExtConst.h20
-rwxr-xr-x7zip/Archive/Cab/makefile24
-rwxr-xr-x7zip/Archive/Chm/Chm.dsp337
-rwxr-xr-x7zip/Archive/Chm/Chm.dsw29
-rwxr-xr-x7zip/Archive/Chm/ChmHandler.cpp729
-rwxr-xr-x7zip/Archive/Chm/ChmHandler.h46
-rwxr-xr-x7zip/Archive/Chm/ChmHeader.cpp24
-rwxr-xr-x7zip/Archive/Chm/ChmHeader.h28
-rwxr-xr-x7zip/Archive/Chm/ChmIn.cpp924
-rwxr-xr-x7zip/Archive/Chm/ChmIn.h242
-rwxr-xr-x7zip/Archive/Chm/DllExports.cpp77
-rwxr-xr-x7zip/Archive/Chm/StdAfx.cpp3
-rwxr-xr-x7zip/Archive/Chm/StdAfx.h8
-rwxr-xr-x7zip/Archive/Chm/makefile68
-rwxr-xr-x7zip/Archive/Chm/resource.rc3
-rwxr-xr-x7zip/Archive/Common/DummyOutStream.cpp10
-rwxr-xr-x7zip/Archive/Common/DummyOutStream.h1
-rwxr-xr-x7zip/Archive/Common/FilterCoder.cpp26
-rwxr-xr-x7zip/Archive/Common/FilterCoder.h2
-rwxr-xr-x7zip/Archive/Common/InStreamWithCRC.cpp24
-rwxr-xr-x7zip/Archive/Common/InStreamWithCRC.h2
-rwxr-xr-x7zip/Archive/Common/MultiStream.cpp16
-rwxr-xr-x7zip/Archive/Common/MultiStream.h2
-rwxr-xr-x7zip/Archive/Common/OutStreamWithCRC.cpp20
-rwxr-xr-x7zip/Archive/Common/OutStreamWithCRC.h1
-rwxr-xr-x7zip/Archive/Cpio/makefile2
-rwxr-xr-x7zip/Archive/Deb/Deb.dsp16
-rwxr-xr-x7zip/Archive/Deb/DebIn.cpp82
-rwxr-xr-x7zip/Archive/Deb/DllExports.cpp4
-rwxr-xr-x7zip/Archive/Deb/makefile2
-rwxr-xr-x7zip/Archive/GZip/DllExports.cpp4
-rwxr-xr-x7zip/Archive/GZip/GZip.dsp8
-rwxr-xr-x7zip/Archive/GZip/GZipHandler.cpp8
-rwxr-xr-x7zip/Archive/GZip/GZipIn.cpp4
-rwxr-xr-x7zip/Archive/GZip/GZipOut.cpp3
-rwxr-xr-x7zip/Archive/GZip/makefile1
-rwxr-xr-x7zip/Archive/IArchive.h94
-rwxr-xr-x7zip/Archive/Lzh/DllExports.cpp4
-rwxr-xr-x7zip/Archive/Lzh/Lzh.dsp16
-rwxr-xr-x7zip/Archive/Lzh/LzhIn.cpp6
-rwxr-xr-x7zip/Archive/Lzh/LzhItem.h7
-rwxr-xr-x7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp23
-rwxr-xr-x7zip/Archive/Lzh/LzhOutStreamWithCRC.h1
-rwxr-xr-x7zip/Archive/Lzh/makefile2
-rwxr-xr-x7zip/Archive/RPM/DllExports.cpp4
-rwxr-xr-x7zip/Archive/RPM/Rpm.dsp8
-rwxr-xr-x7zip/Archive/RPM/RpmIn.cpp6
-rwxr-xr-x7zip/Archive/RPM/makefile1
-rwxr-xr-x7zip/Archive/Rar/DllExports.cpp4
-rwxr-xr-x7zip/Archive/Rar/Rar.dsp16
-rwxr-xr-x7zip/Archive/Rar/RarHandler.cpp7
-rwxr-xr-x7zip/Archive/Rar/RarHeader.h13
-rwxr-xr-x7zip/Archive/Rar/RarIn.cpp56
-rwxr-xr-x7zip/Archive/Rar/RarIn.h3
-rwxr-xr-x7zip/Archive/Rar/RarVolumeInStream.cpp8
-rwxr-xr-x7zip/Archive/Rar/RarVolumeInStream.h1
-rwxr-xr-x7zip/Archive/Rar/makefile2
-rwxr-xr-x7zip/Archive/Split/DllExports.cpp4
-rwxr-xr-x7zip/Archive/Split/Split.dsp10
-rwxr-xr-x7zip/Archive/Split/makefile1
-rwxr-xr-x7zip/Archive/Tar/DllExports.cpp4
-rwxr-xr-x7zip/Archive/Tar/Tar.dsp16
-rwxr-xr-x7zip/Archive/Tar/TarHeader.cpp2
-rwxr-xr-x7zip/Archive/Tar/TarHeader.h4
-rwxr-xr-x7zip/Archive/Tar/TarIn.cpp74
-rwxr-xr-x7zip/Archive/Tar/TarItem.h8
-rwxr-xr-x7zip/Archive/Tar/TarOut.cpp14
-rwxr-xr-x7zip/Archive/Tar/makefile2
-rwxr-xr-x7zip/Archive/Z/DllExports.cpp8
-rwxr-xr-x7zip/Archive/Z/Z.dsp8
-rwxr-xr-x7zip/Archive/Z/ZHandler.cpp3
-rwxr-xr-x7zip/Archive/Z/makefile1
-rwxr-xr-x7zip/Archive/Zip/Zip.dsp8
-rwxr-xr-x7zip/Archive/Zip/ZipHandler.cpp3
-rwxr-xr-x7zip/Archive/Zip/ZipHeader.h3
-rwxr-xr-x7zip/Archive/Zip/ZipIn.cpp9
-rwxr-xr-x7zip/Archive/Zip/ZipOut.cpp3
-rwxr-xr-x7zip/Archive/Zip/makefile1
-rwxr-xr-x7zip/Archive/cpio/CpioIn.cpp47
-rwxr-xr-x7zip/Archive/cpio/DllExports.cpp4
-rwxr-xr-x7zip/Archive/cpio/cpio.dsp16
-rwxr-xr-x7zip/Archive/makefile1
-rwxr-xr-x7zip/Bundles/Alone/Alone.dsp8
-rwxr-xr-x7zip/Bundles/Alone/makefile1
-rwxr-xr-x7zip/Bundles/Format7z/Format7z.dsp12
-rwxr-xr-x7zip/Bundles/Format7z/makefile1
-rwxr-xr-x7zip/Bundles/Format7zExtract/Format7z.dsp12
-rwxr-xr-x7zip/Bundles/Format7zExtract/makefile1
-rwxr-xr-x7zip/Bundles/SFXCon/SFXCon.dsp8
-rwxr-xr-x7zip/Bundles/SFXCon/makefile1
-rwxr-xr-x7zip/Bundles/SFXSetup/SFXSetup.dsp8
-rwxr-xr-x7zip/Bundles/SFXSetup/makefile1
-rwxr-xr-x7zip/Bundles/SFXWin/SFXWin.dsp8
-rwxr-xr-x7zip/Bundles/SFXWin/makefile1
-rwxr-xr-x7zip/Common/FileStreams.cpp29
-rwxr-xr-x7zip/Common/FileStreams.h4
-rwxr-xr-x7zip/Common/InBuffer.cpp9
-rwxr-xr-x7zip/Common/InBuffer.h10
-rwxr-xr-x7zip/Common/InOutTempBuffer.cpp35
-rwxr-xr-x7zip/Common/InOutTempBuffer.h2
-rwxr-xr-x7zip/Common/LSBFDecoder.h16
-rwxr-xr-x7zip/Common/LimitedStreams.cpp14
-rwxr-xr-x7zip/Common/LimitedStreams.h1
-rwxr-xr-x7zip/Common/LockedStream.cpp21
-rwxr-xr-x7zip/Common/LockedStream.h2
-rwxr-xr-x7zip/Common/MSBFDecoder.h5
-rwxr-xr-x7zip/Common/OffsetStream.cpp8
-rwxr-xr-x7zip/Common/OffsetStream.h1
-rwxr-xr-x7zip/Common/OutBuffer.cpp73
-rwxr-xr-x7zip/Common/OutBuffer.h30
-rwxr-xr-x7zip/Common/StreamBinder.cpp38
-rwxr-xr-x7zip/Common/StreamBinder.h6
-rwxr-xr-x7zip/Common/StreamObjects.cpp100
-rwxr-xr-x7zip/Common/StreamObjects.h66
-rwxr-xr-x7zip/Common/StreamUtils.cpp44
-rwxr-xr-x7zip/Common/StreamUtils.h11
-rwxr-xr-x7zip/Compress/Arj/ArjDecoder1.cpp (renamed from 7zip/Compress/Arj/Decoder1.cpp)2
-rwxr-xr-x7zip/Compress/Arj/ArjDecoder1.h (renamed from 7zip/Compress/Arj/Decoder1.h)0
-rwxr-xr-x7zip/Compress/Arj/ArjDecoder2.cpp (renamed from 7zip/Compress/Arj/Decoder2.cpp)2
-rwxr-xr-x7zip/Compress/Arj/ArjDecoder2.h (renamed from 7zip/Compress/Arj/Decoder2.h)0
-rwxr-xr-x7zip/Compress/BZip2/BZip2CRC.cpp2
-rwxr-xr-x7zip/Compress/BZip2/BZip2Decoder.cpp20
-rwxr-xr-x7zip/Compress/Branch/x86_2.cpp15
-rwxr-xr-x7zip/Compress/Copy/Copy.dsp12
-rwxr-xr-x7zip/Compress/Copy/CopyCoder.cpp5
-rwxr-xr-x7zip/Compress/Copy/makefile6
-rwxr-xr-x7zip/Compress/Deflate/DeflateDecoder.cpp404
-rwxr-xr-x7zip/Compress/Deflate/DeflateDecoder.h80
-rwxr-xr-x7zip/Compress/Huffman/HuffmanDecoder.h125
-rwxr-xr-x7zip/Compress/Implode/ImplodeDecoder.cpp48
-rwxr-xr-x7zip/Compress/Implode/ImplodeDecoder.h5
-rwxr-xr-x7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp11
-rwxr-xr-x7zip/Compress/Implode/ImplodeHuffmanDecoder.h3
-rwxr-xr-x7zip/Compress/LZ/LZInWindow.cpp2
-rwxr-xr-x7zip/Compress/LZ/LZOutWindow.cpp72
-rwxr-xr-x7zip/Compress/LZ/LZOutWindow.h47
-rwxr-xr-x7zip/Compress/LZMA/LZMA.dsp8
-rwxr-xr-x7zip/Compress/LZMA/LZMADecoder.cpp162
-rwxr-xr-x7zip/Compress/LZMA/LZMADecoder.h21
-rwxr-xr-x7zip/Compress/LZMA/LZMAEncoder.cpp3
-rwxr-xr-x7zip/Compress/LZMA/makefile1
-rwxr-xr-x7zip/Compress/LZMA_Alone/AloneLZMA.dsp8
-rwxr-xr-x7zip/Compress/LZMA_Alone/LzmaAlone.cpp27
-rwxr-xr-x7zip/Compress/LZMA_Alone/LzmaBench.cpp20
-rwxr-xr-x7zip/Compress/LZMA_Alone/LzmaRam.cpp14
-rwxr-xr-x7zip/Compress/LZMA_Alone/makefile7
-rwxr-xr-x7zip/Compress/LZMA_C/LzmaDecodeSize.c31
-rwxr-xr-x7zip/Compress/LZMA_C/LzmaTest.c10
-rwxr-xr-x7zip/Compress/Lzx/Lzx.h61
-rwxr-xr-x7zip/Compress/Lzx/Lzx86Converter.cpp (renamed from 7zip/Archive/Cab/LZXi86Converter.cpp)63
-rwxr-xr-x7zip/Compress/Lzx/Lzx86Converter.h (renamed from 7zip/Archive/Cab/LZXi86Converter.h)37
-rwxr-xr-x7zip/Compress/Lzx/LzxDecoder.cpp382
-rwxr-xr-x7zip/Compress/Lzx/LzxDecoder.h181
-rwxr-xr-x7zip/Compress/Lzx/StdAfx.h8
-rwxr-xr-x7zip/Compress/PPMD/PPMD.dsp8
-rwxr-xr-x7zip/Compress/PPMD/PPMDContext.h153
-rwxr-xr-x7zip/Compress/PPMD/PPMDDecode.h12
-rwxr-xr-x7zip/Compress/PPMD/PPMDDecoder.cpp166
-rwxr-xr-x7zip/Compress/PPMD/PPMDDecoder.h35
-rwxr-xr-x7zip/Compress/PPMD/PPMDEncode.h12
-rwxr-xr-x7zip/Compress/PPMD/PPMDEncoder.cpp99
-rwxr-xr-x7zip/Compress/PPMD/PPMDEncoder.h31
-rwxr-xr-x7zip/Compress/PPMD/PPMDSubAlloc.h147
-rwxr-xr-x7zip/Compress/PPMD/PPMDType.h6
-rwxr-xr-x7zip/Compress/PPMD/makefile1
-rwxr-xr-x7zip/Compress/Quantum/QuantumDecoder.cpp174
-rwxr-xr-x7zip/Compress/Quantum/QuantumDecoder.h287
-rwxr-xr-x7zip/Compress/Rar20/DllExports.cpp66
-rwxr-xr-x7zip/Compress/Rar20/Rar20Const.h65
-rwxr-xr-x7zip/Compress/Rar20/Rar20Decoder.cpp319
-rwxr-xr-x7zip/Compress/Rar20/Rar20Decoder.h95
-rwxr-xr-x7zip/Compress/Rar20/Rar20ExtConst.h21
-rwxr-xr-x7zip/Compress/Rar20/Rar20Multimedia.cpp128
-rwxr-xr-x7zip/Compress/Rar20/Rar20Multimedia.h43
-rwxr-xr-x7zip/Compress/Rar20/StdAfx.cpp3
-rwxr-xr-x7zip/Compress/Rar20/StdAfx.h8
-rwxr-xr-x7zip/Compress/Rar29/DllExports.cpp105
-rwxr-xr-x7zip/Compress/Rar29/Original/archive.hpp128
-rwxr-xr-x7zip/Compress/Rar29/Original/array.hpp121
-rwxr-xr-x7zip/Compress/Rar29/Original/cmddata.hpp56
-rwxr-xr-x7zip/Compress/Rar29/Original/coder.cpp47
-rwxr-xr-x7zip/Compress/Rar29/Original/coder.hpp24
-rwxr-xr-x7zip/Compress/Rar29/Original/compress.hpp36
-rwxr-xr-x7zip/Compress/Rar29/Original/consio.hpp42
-rwxr-xr-x7zip/Compress/Rar29/Original/crc.cpp61
-rwxr-xr-x7zip/Compress/Rar29/Original/crc.hpp10
-rwxr-xr-x7zip/Compress/Rar29/Original/crypt.hpp60
-rwxr-xr-x7zip/Compress/Rar29/Original/encname.hpp20
-rwxr-xr-x7zip/Compress/Rar29/Original/errhnd.cpp356
-rwxr-xr-x7zip/Compress/Rar29/Original/errhnd.hpp61
-rwxr-xr-x7zip/Compress/Rar29/Original/extinfo.hpp8
-rwxr-xr-x7zip/Compress/Rar29/Original/extract.hpp40
-rwxr-xr-x7zip/Compress/Rar29/Original/filcreat.hpp12
-rwxr-xr-x7zip/Compress/Rar29/Original/file.hpp100
-rwxr-xr-x7zip/Compress/Rar29/Original/filefn.hpp39
-rwxr-xr-x7zip/Compress/Rar29/Original/filestr.hpp8
-rwxr-xr-x7zip/Compress/Rar29/Original/find.hpp48
-rwxr-xr-x7zip/Compress/Rar29/Original/getbits.cpp24
-rwxr-xr-x7zip/Compress/Rar29/Original/getbits.hpp37
-rwxr-xr-x7zip/Compress/Rar29/Original/global.hpp14
-rwxr-xr-x7zip/Compress/Rar29/Original/headers.hpp304
-rwxr-xr-x7zip/Compress/Rar29/Original/int64.cpp274
-rwxr-xr-x7zip/Compress/Rar29/Original/int64.hpp86
-rwxr-xr-x7zip/Compress/Rar29/Original/isnt.hpp6
-rwxr-xr-x7zip/Compress/Rar29/Original/list.hpp6
-rwxr-xr-x7zip/Compress/Rar29/Original/loclang.hpp340
-rwxr-xr-x7zip/Compress/Rar29/Original/log.hpp18
-rwxr-xr-x7zip/Compress/Rar29/Original/match.hpp16
-rwxr-xr-x7zip/Compress/Rar29/Original/model.cpp600
-rwxr-xr-x7zip/Compress/Rar29/Original/model.hpp126
-rwxr-xr-x7zip/Compress/Rar29/Original/options.hpp129
-rwxr-xr-x7zip/Compress/Rar29/Original/os.hpp235
-rwxr-xr-x7zip/Compress/Rar29/Original/pathfn.hpp44
-rwxr-xr-x7zip/Compress/Rar29/Original/rar.hpp80
-rwxr-xr-x7zip/Compress/Rar29/Original/rardefs.hpp21
-rwxr-xr-x7zip/Compress/Rar29/Original/rarfn.hpp7
-rwxr-xr-x7zip/Compress/Rar29/Original/rarlang.hpp10
-rwxr-xr-x7zip/Compress/Rar29/Original/raros.hpp41
-rwxr-xr-x7zip/Compress/Rar29/Original/rartypes.hpp21
-rwxr-xr-x7zip/Compress/Rar29/Original/rarvm.cpp1050
-rwxr-xr-x7zip/Compress/Rar29/Original/rarvm.hpp110
-rwxr-xr-x7zip/Compress/Rar29/Original/rarvmtbl.cpp53
-rwxr-xr-x7zip/Compress/Rar29/Original/rawread.hpp32
-rwxr-xr-x7zip/Compress/Rar29/Original/rdwrfn.cpp306
-rwxr-xr-x7zip/Compress/Rar29/Original/rdwrfn.hpp104
-rwxr-xr-x7zip/Compress/Rar29/Original/recvol.hpp16
-rwxr-xr-x7zip/Compress/Rar29/Original/resource.cpp12
-rwxr-xr-x7zip/Compress/Rar29/Original/resource.hpp14
-rwxr-xr-x7zip/Compress/Rar29/Original/rijndael.hpp37
-rwxr-xr-x7zip/Compress/Rar29/Original/rs.hpp32
-rwxr-xr-x7zip/Compress/Rar29/Original/savepos.hpp15
-rwxr-xr-x7zip/Compress/Rar29/Original/scantree.hpp52
-rwxr-xr-x7zip/Compress/Rar29/Original/sha1.hpp16
-rwxr-xr-x7zip/Compress/Rar29/Original/smallfn.cpp17
-rwxr-xr-x7zip/Compress/Rar29/Original/smallfn.hpp7
-rwxr-xr-x7zip/Compress/Rar29/Original/strfn.hpp24
-rwxr-xr-x7zip/Compress/Rar29/Original/strlist.hpp39
-rwxr-xr-x7zip/Compress/Rar29/Original/suballoc.cpp241
-rwxr-xr-x7zip/Compress/Rar29/Original/suballoc.hpp81
-rwxr-xr-x7zip/Compress/Rar29/Original/system.cpp79
-rwxr-xr-x7zip/Compress/Rar29/Original/system.hpp10
-rwxr-xr-x7zip/Compress/Rar29/Original/timefn.hpp57
-rwxr-xr-x7zip/Compress/Rar29/Original/ulinks.hpp9
-rwxr-xr-x7zip/Compress/Rar29/Original/unicode.hpp82
-rwxr-xr-x7zip/Compress/Rar29/Original/unpack.cpp939
-rwxr-xr-x7zip/Compress/Rar29/Original/unpack.hpp205
-rwxr-xr-x7zip/Compress/Rar29/Original/unpack15.cpp507
-rwxr-xr-x7zip/Compress/Rar29/Original/version.hpp6
-rwxr-xr-x7zip/Compress/Rar29/Original/volume.hpp11
-rwxr-xr-x7zip/Compress/Rar29/Rar29.dsp415
-rwxr-xr-x7zip/Compress/Rar29/Rar29.dsw29
-rwxr-xr-x7zip/Compress/Rar29/Rar29Decoder.cpp153
-rwxr-xr-x7zip/Compress/Rar29/Rar29Decoder.h97
-rwxr-xr-x7zip/Compress/Rar29/StdAfx.cpp3
-rwxr-xr-x7zip/Compress/Rar29/StdAfx.h8
-rwxr-xr-x7zip/Compress/Rar29/makefile62
-rwxr-xr-x7zip/Compress/Rar29/resource.rc3
-rwxr-xr-x7zip/Crypto/7zAES/7zAES.cpp5
-rwxr-xr-x7zip/Crypto/7zAES/7zAES.dsp8
-rwxr-xr-x7zip/Crypto/7zAES/makefile1
-rwxr-xr-x7zip/Crypto/RarAES/RarAES.cpp22
-rwxr-xr-x7zip/Crypto/RarAES/RarAES.h3
-rwxr-xr-x7zip/Crypto/RarAES/sha1.cpp35
-rwxr-xr-x7zip/Crypto/RarAES/sha1.h11
-rwxr-xr-x7zip/Crypto/Zip/ZipCipher.cpp6
-rwxr-xr-x7zip/FileManager/App.cpp3
-rwxr-xr-x7zip/FileManager/App.h4
-rwxr-xr-x7zip/FileManager/FSFolder.cpp34
-rwxr-xr-x7zip/FileManager/FSFolder.h4
-rwxr-xr-x7zip/FileManager/IFolder.h231
-rwxr-xr-x7zip/FileManager/MyLoadMenu.cpp5
-rwxr-xr-x7zip/FileManager/OptionsDialog.cpp3
-rwxr-xr-x7zip/FileManager/Panel.cpp2
-rwxr-xr-x7zip/FileManager/Panel.h13
-rwxr-xr-x7zip/FileManager/PanelFolderChange.cpp8
-rwxr-xr-x7zip/FileManager/PanelItems.cpp75
-rwxr-xr-x7zip/FileManager/PanelKey.cpp3
-rwxr-xr-x7zip/FileManager/PanelListNotify.cpp11
-rwxr-xr-x7zip/FileManager/PanelMenu.cpp3
-rwxr-xr-x7zip/FileManager/PanelOperations.cpp70
-rwxr-xr-x7zip/FileManager/PanelSelect.cpp21
-rwxr-xr-x7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp18
-rwxr-xr-x7zip/FileManager/StringUtils.cpp3
-rwxr-xr-x7zip/FileManager/TextPairs.cpp18
-rwxr-xr-x7zip/FileManager/resource.h1
-rwxr-xr-x7zip/FileManager/resource.rc1
-rwxr-xr-x7zip/Guid.txt152
-rwxr-xr-x7zip/ICoder.h110
-rwxr-xr-x7zip/IPassword.h34
-rwxr-xr-x7zip/IProgress.h1
-rwxr-xr-x7zip/IStream.h91
-rwxr-xr-x7zip/MyVersion.h8
-rwxr-xr-x7zip/UI/Agent/AgentOut.cpp5
-rwxr-xr-x7zip/UI/Agent/AgentProxy.cpp3
-rwxr-xr-x7zip/UI/Agent/ArchiveFolderOpen.cpp11
-rwxr-xr-x7zip/UI/Client7z/Client7z.cpp4
-rwxr-xr-x7zip/UI/Common/ArchiveCommandLine.cpp2
-rwxr-xr-x7zip/UI/Common/ArchiveCommandLine.h2
-rwxr-xr-x7zip/UI/Common/ArchiverInfo.cpp36
-rwxr-xr-x7zip/UI/Common/ArchiverInfo.h23
-rwxr-xr-x7zip/UI/Common/EnumDirItems.cpp7
-rwxr-xr-x7zip/UI/Common/Extract.h1
-rwxr-xr-x7zip/UI/Common/OpenArchive.cpp7
-rwxr-xr-x7zip/UI/Common/SortUtils.cpp21
-rwxr-xr-x7zip/UI/Common/Update.cpp9
-rwxr-xr-x7zip/UI/Console/Console.dsp8
-rwxr-xr-x7zip/UI/Console/Main.cpp4
-rwxr-xr-x7zip/UI/Console/makefile1
-rwxr-xr-x7zip/UI/Explorer/ContextMenu.cpp11
-rwxr-xr-x7zip/UI/Explorer/Explorer.dsp8
-rwxr-xr-x7zip/UI/Explorer/makefile1
-rwxr-xr-x7zip/UI/Far/Far.dsp8
-rwxr-xr-x7zip/UI/Far/Messages.h1
-rwxr-xr-x7zip/UI/Far/PluginRead.cpp63
-rwxr-xr-x7zip/UI/Far/PluginWrite.cpp2
-rwxr-xr-x7zip/UI/Far/makefile1
-rwxr-xr-x7zip/UI/GUI/CompressDialog.cpp29
-rwxr-xr-x7zip/UI/GUI/GUI.dsp8
-rwxr-xr-x7zip/UI/GUI/makefile1
-rwxr-xr-xBuild.mak3
-rwxr-xr-xCommon/Buffer.h2
-rwxr-xr-xCommon/Copy of StringConvert.cpp93
-rwxr-xr-xCommon/Copy of StringConvert.h71
-rwxr-xr-xCommon/Copy of UTFConvert.cpp91
-rwxr-xr-xCommon/Copy of UTFConvert.h11
-rwxr-xr-xCommon/MyCom.h4
-rwxr-xr-xCommon/MyGuidDef.h8
-rwxr-xr-xCommon/MyWindows.h1
-rwxr-xr-xCommon/String.h4
-rwxr-xr-xCommon/StringConvert.h8
-rwxr-xr-xCommon/StringToInt.cpp19
-rwxr-xr-xCommon/StringToInt.h1
-rwxr-xr-xCommon/Vector.h64
-rwxr-xr-xDOC/7zFormat.txt4
-rwxr-xr-xDOC/7zip.nsi73
-rwxr-xr-xDOC/Methods.txt11
-rwxr-xr-xDOC/history.txt8
-rwxr-xr-xDOC/lzma.txt4
-rwxr-xr-xDOC/readme.txt62
-rwxr-xr-xDOC/unRarLicense.txt41
-rwxr-xr-xWindows/Control/ListView.h4
-rwxr-xr-xWindows/FileIO.cpp61
-rwxr-xr-xWindows/FileIO.h2
-rwxr-xr-xWindows/PropVariant.cpp4
-rwxr-xr-xWindows/PropVariant.h4
-rwxr-xr-xWindows/PropVariantConversions.cpp3
393 files changed, 17299 insertions, 4697 deletions
diff --git a/7zip/Archive/7z/7z.dsp b/7zip/Archive/7z/7z.dsp
index 2e05281d..83e48cef 100755
--- a/7zip/Archive/7z/7z.dsp
+++ b/7zip/Archive/7z/7z.dsp
@@ -496,6 +496,14 @@ SOURCE=..\..\Common\StreamObjects.cpp
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 "Windows"
diff --git a/7zip/Archive/7z/7zDecode.cpp b/7zip/Archive/7z/7zDecode.cpp
index e6dbeefd..2deffc12 100755
--- a/7zip/Archive/7z/7zDecode.cpp
+++ b/7zip/Archive/7z/7zDecode.cpp
@@ -1,4 +1,4 @@
-// Decode.cpp
+// 7zDecode.cpp
#include "StdAfx.h"
@@ -136,10 +136,10 @@ static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2)
CDecoder::CDecoder(bool multiThread)
{
- _multiThread = true;
- #ifdef _ST_MODE
- _multiThread = multiThread;
+ #ifndef _ST_MODE
+ multiThread = true;
#endif
+ _multiThread = multiThread;
_bindInfoExPrevIsDefinded = false;
#ifndef EXCLUDE_COM
LoadMethodMap();
diff --git a/7zip/Archive/7z/7zExtract.cpp b/7zip/Archive/7z/7zExtract.cpp
index 1fcccfd7..bf827dc0 100755
--- a/7zip/Archive/7z/7zExtract.cpp
+++ b/7zip/Archive/7z/7zExtract.cpp
@@ -142,7 +142,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
extractCallback->SetTotal(importantTotalUnPacked);
- CDecoder decoder(true);
+ CDecoder decoder(
+ #ifdef _ST_MODE
+ false
+ #else
+ true
+ #endif
+ );
// CDecoder1 decoder;
UInt64 currentImportantTotalUnPacked = 0;
diff --git a/7zip/Archive/7z/7zFolderInStream.cpp b/7zip/Archive/7z/7zFolderInStream.cpp
index 91b39fa9..1b3e2a06 100755
--- a/7zip/Archive/7z/7zFolderInStream.cpp
+++ b/7zip/Archive/7z/7zFolderInStream.cpp
@@ -79,7 +79,7 @@ HRESULT CFolderInStream::CloseStream()
return S_OK;
}
-STDMETHODIMP CFolderInStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
+STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessedSize = 0;
while ((_fileIndex < _numFiles || _fileIsOpen) && size > 0)
@@ -87,7 +87,7 @@ STDMETHODIMP CFolderInStream::ReadPart(void *data, UInt32 size, UInt32 *processe
if (_fileIsOpen)
{
UInt32 localProcessedSize;
- RINOK(_inStreamWithHash->ReadPart(
+ RINOK(_inStreamWithHash->Read(
((Byte *)data) + realProcessedSize, size, &localProcessedSize));
if (localProcessedSize == 0)
{
@@ -109,24 +109,6 @@ STDMETHODIMP CFolderInStream::ReadPart(void *data, UInt32 size, UInt32 *processe
return S_OK;
}
-STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
-{
- UInt32 realProcessedSize = 0;
- while (size > 0)
- {
- UInt32 localProcessedSize;
- RINOK(ReadPart(((Byte *)data) + realProcessedSize, size, &localProcessedSize));
- if (localProcessedSize == 0)
- break;
- size -= localProcessedSize;
- realProcessedSize += localProcessedSize;
- }
- if (processedSize != 0)
- *processedSize = realProcessedSize;
- return S_OK;
-}
-
-
STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
{
*value = 0;
diff --git a/7zip/Archive/7z/7zFolderInStream.h b/7zip/Archive/7z/7zFolderInStream.h
index 12a2ac07..9a720c8b 100755
--- a/7zip/Archive/7z/7zFolderInStream.h
+++ b/7zip/Archive/7z/7zFolderInStream.h
@@ -26,7 +26,6 @@ public:
CFolderInStream();
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
private:
diff --git a/7zip/Archive/7z/7zFolderOutStream.cpp b/7zip/Archive/7z/7zFolderOutStream.cpp
index c09271f5..bb770ccc 100755
--- a/7zip/Archive/7z/7zFolderOutStream.cpp
+++ b/7zip/Archive/7z/7zFolderOutStream.cpp
@@ -91,7 +91,8 @@ STDMETHODIMP CFolderOutStream::Write(const void *data,
UInt64(size - realProcessedSize));
UInt32 processedSizeLocal;
- RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize, numBytesToWrite, &processedSizeLocal));
+ RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize,
+ numBytesToWrite, &processedSizeLocal));
_filePos += processedSizeLocal;
realProcessedSize += processedSizeLocal;
@@ -130,12 +131,6 @@ STDMETHODIMP CFolderOutStream::Write(const void *data,
return S_OK;
}
-STDMETHODIMP CFolderOutStream::WritePart(const void *data,
- UInt32 size, UInt32 *processedSize)
-{
- return Write(data, size, processedSize);
-}
-
HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult)
{
while(_currentIndex < _extractStatuses->Size())
diff --git a/7zip/Archive/7z/7zFolderOutStream.h b/7zip/Archive/7z/7zFolderOutStream.h
index 9153070e..c132c79a 100755
--- a/7zip/Archive/7z/7zFolderOutStream.h
+++ b/7zip/Archive/7z/7zFolderOutStream.h
@@ -22,7 +22,6 @@ public:
CFolderOutStream();
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
private:
COutStreamWithCRC *_outStreamWithHashSpec;
diff --git a/7zip/Archive/7z/7zHandler.h b/7zip/Archive/7z/7zHandler.h
index 7966b86c..b7a53b20 100755
--- a/7zip/Archive/7z/7zHandler.h
+++ b/7zip/Archive/7z/7zHandler.h
@@ -50,9 +50,9 @@ struct COneMethodInfo
};
#endif
-// {23170F69-40C1-278A-1000-000110050000}
+// {23170F69-40C1-278A-1000-000110070000}
DEFINE_GUID(CLSID_CFormat7z,
- 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 0x00, 0x00);
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);
class CHandler:
public IInArchive,
diff --git a/7zip/Archive/7z/7zIn.cpp b/7zip/Archive/7z/7zIn.cpp
index 93a72c75..c35a77ce 100755
--- a/7zip/Archive/7z/7zIn.cpp
+++ b/7zip/Archive/7z/7zIn.cpp
@@ -6,6 +6,7 @@
#include "7zMethods.h"
#include "7zDecode.h"
#include "../../Common/StreamObjects.h"
+#include "../../Common/StreamUtils.h"
#include "../../../Common/CRC.h"
namespace NArchive {
@@ -69,7 +70,7 @@ HRESULT CInArchive::ReadDirect(IInStream *stream, void *data, UInt32 size,
UInt32 *processedSize)
{
UInt32 realProcessedSize;
- HRESULT result = stream->Read(data, size, &realProcessedSize);
+ HRESULT result = ReadStream(stream, data, size, &realProcessedSize);
if(processedSize != NULL)
*processedSize = realProcessedSize;
_position += realProcessedSize;
@@ -850,7 +851,13 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(UInt64 baseOffset,
// database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader;
CNum packIndex = 0;
- CDecoder decoder(false);
+ CDecoder decoder(
+ #ifdef _ST_MODE
+ false
+ #else
+ true
+ #endif
+ );
UInt64 dataStartPos = baseOffset + dataOffset;
for(int i = 0; i < folders.Size(); i++)
{
diff --git a/7zip/Archive/7z/7zOut.cpp b/7zip/Archive/7z/7zOut.cpp
index b2ba2db3..116cb0cc 100755
--- a/7zip/Archive/7z/7zOut.cpp
+++ b/7zip/Archive/7z/7zOut.cpp
@@ -11,10 +11,10 @@ static HRESULT WriteBytes(ISequentialOutStream *stream, const void *data, size_t
{
while (size > 0)
{
- UInt32 curSize = (UInt32)(MyMin(size, (size_t)0xFFFFFFFF));
+ UInt32 curSize = (UInt32)MyMin(size, (size_t)0xFFFFFFFF);
UInt32 processedSize;
- RINOK(stream->WritePart(data, curSize, &processedSize));
- if(processedSize == 0 || processedSize > curSize)
+ RINOK(stream->Write(data, curSize, &processedSize));
+ if(processedSize == 0)
return E_FAIL;
data = (const void *)((const Byte *)data + processedSize);
size -= processedSize;
@@ -111,7 +111,10 @@ HRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker)
{
SeqStream.QueryInterface(IID_IOutStream, &Stream);
if (!Stream)
- endMarker = true;
+ {
+ return E_NOTIMPL;
+ // endMarker = true;
+ }
}
#ifdef _7Z_VOL
if (endMarker)
diff --git a/7zip/Archive/7z/7zSpecStream.cpp b/7zip/Archive/7z/7zSpecStream.cpp
index fb42d98c..80d303a4 100755
--- a/7zip/Archive/7z/7zSpecStream.cpp
+++ b/7zip/Archive/7z/7zSpecStream.cpp
@@ -14,16 +14,6 @@ STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32
return result;
}
-STDMETHODIMP CSequentialInStreamSizeCount2::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
-{
- UInt32 realProcessedSize;
- HRESULT result = _stream->ReadPart(data, size, &realProcessedSize);
- _size += realProcessedSize;
- if (processedSize != 0)
- *processedSize = realProcessedSize;
- return result;
-}
-
STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(
UInt64 subStream, UInt64 *value)
{
diff --git a/7zip/Archive/7z/7zSpecStream.h b/7zip/Archive/7z/7zSpecStream.h
index 7d3cf538..0253c421 100755
--- a/7zip/Archive/7z/7zSpecStream.h
+++ b/7zip/Archive/7z/7zSpecStream.h
@@ -28,7 +28,6 @@ public:
MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
};
diff --git a/7zip/Archive/7z/7zUpdate.cpp b/7zip/Archive/7z/7zUpdate.cpp
index 5722aba4..e5d82764 100755
--- a/7zip/Archive/7z/7zUpdate.cpp
+++ b/7zip/Archive/7z/7zUpdate.cpp
@@ -89,11 +89,13 @@ UString CUpdateItem::GetExtension() const
return Name.Mid(GetExtensionPos());
}
+/*
struct CFolderRef
{
const CArchiveDatabaseEx *Database;
int FolderIndex;
};
+*/
#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
@@ -159,31 +161,31 @@ static int CompareFiles(const CFileItem &f1, const CFileItem &f2)
return MyStringCollateNoCase(f1.Name, f2.Name);
}
-static int __cdecl CompareFolderRefs(const void *p1, const void *p2)
+static int CompareFolderRefs(const int *p1, const int *p2, void *param)
{
- const CFolderRef &a1 = *((const CFolderRef *)p1);
- const CFolderRef &a2 = *((const CFolderRef *)p2);
- const CArchiveDatabaseEx &d1 = *a1.Database;
- const CArchiveDatabaseEx &d2 = *a2.Database;
+ int i1 = *p1;
+ int i2 = *p2;
+ const CArchiveDatabaseEx &db = *(const CArchiveDatabaseEx *)param;
RINOZ(CompareFolders(
- d1.Folders[a1.FolderIndex],
- d2.Folders[a2.FolderIndex]));
+ db.Folders[i1],
+ db.Folders[i2]));
RINOZ(MyCompare(
- d1.NumUnPackStreamsVector[a1.FolderIndex],
- d2.NumUnPackStreamsVector[a2.FolderIndex]));
- if (d1.NumUnPackStreamsVector[a1.FolderIndex] == 0)
+ db.NumUnPackStreamsVector[i1],
+ db.NumUnPackStreamsVector[i2]));
+ if (db.NumUnPackStreamsVector[i1] == 0)
return 0;
return CompareFiles(
- d1.Files[d1.FolderStartFileIndex[a1.FolderIndex]],
- d2.Files[d2.FolderStartFileIndex[a2.FolderIndex]]);
+ db.Files[db.FolderStartFileIndex[i1]],
+ db.Files[db.FolderStartFileIndex[i2]]);
}
////////////////////////////////////////////////////////////
-static int __cdecl CompareEmptyItems(const void *p1, const void *p2)
+static int CompareEmptyItems(const int *p1, const int *p2, void *param)
{
- const CUpdateItem &u1 = **((CUpdateItem **)p1);
- const CUpdateItem &u2 = **((CUpdateItem **)p2);
+ const CObjectVector<CUpdateItem> &updateItems = *(const CObjectVector<CUpdateItem> *)param;
+ const CUpdateItem &u1 = updateItems[*p1];
+ const CUpdateItem &u2 = updateItems[*p2];
if (u1.IsDirectory != u2.IsDirectory)
{
if (u1.IsDirectory)
@@ -234,10 +236,10 @@ struct CRefItem
}
};
-static int __cdecl CompareUpdateItems(const void *p1, const void *p2)
+static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *param)
{
- const CRefItem &a1 = *((CRefItem *)p1);
- const CRefItem &a2 = *((CRefItem *)p2);
+ const CRefItem &a1 = *p1;
+ const CRefItem &a2 = *p2;
const CUpdateItem &u1 = *a1.UpdateItem;
const CUpdateItem &u2 = *a2.UpdateItem;
int n;
@@ -455,7 +457,7 @@ static void FromUpdateItemToFileItem(const CUpdateItem &updateItem,
static HRESULT Update2(
IInStream *inStream,
const CArchiveDatabaseEx *database,
- CObjectVector<CUpdateItem> &updateItems,
+ const CObjectVector<CUpdateItem> &updateItems,
ISequentialOutStream *seqOutStream,
IArchiveUpdateCallback *updateCallback,
const CUpdateOptions &options)
@@ -496,38 +498,32 @@ static HRESULT Update2(
fileIndexToUpdateIndexMap[index] = i;
}
- CRecordVector<CFolderRef> folderRefs;
+ CRecordVector<int> folderRefs;
if (database != 0)
{
- for(i = 0; i < database->Folders.Size(); i++)
- {
- CNum indexInFolder = 0;
- CNum numCopyItems = 0;
- CNum numUnPackStreams = database->NumUnPackStreamsVector[i];
- for (CNum fileIndex = database->FolderStartFileIndex[i];
- indexInFolder < numUnPackStreams; fileIndex++)
+ for(i = 0; i < database->Folders.Size(); i++)
{
- if (database->Files[fileIndex].HasStream)
+ CNum indexInFolder = 0;
+ CNum numCopyItems = 0;
+ CNum numUnPackStreams = database->NumUnPackStreamsVector[i];
+ for (CNum fileIndex = database->FolderStartFileIndex[i];
+ indexInFolder < numUnPackStreams; fileIndex++)
{
- indexInFolder++;
- int updateIndex = fileIndexToUpdateIndexMap[fileIndex];
- if (updateIndex >= 0)
- if (!updateItems[updateIndex].NewData)
- numCopyItems++;
+ if (database->Files[fileIndex].HasStream)
+ {
+ indexInFolder++;
+ int updateIndex = fileIndexToUpdateIndexMap[fileIndex];
+ if (updateIndex >= 0)
+ if (!updateItems[updateIndex].NewData)
+ numCopyItems++;
+ }
}
+ if (numCopyItems != numUnPackStreams && numCopyItems != 0)
+ return E_NOTIMPL; // It needs repacking !!!
+ if (numCopyItems > 0)
+ folderRefs.Add(i);
}
- if (numCopyItems != numUnPackStreams && numCopyItems != 0)
- return E_NOTIMPL; // It needs repacking !!!
- if (numCopyItems > 0)
- {
- CFolderRef folderRef;
- folderRef.Database = database;
- folderRef.FolderIndex = i;
- folderRefs.Add(folderRef);
- }
- }
- qsort(&folderRefs.Front(), folderRefs.Size(), sizeof(folderRefs[0]),
- CompareFolderRefs);
+ folderRefs.Sort(CompareFolderRefs, (void *)database);
}
CArchiveDatabase newDatabase;
@@ -535,7 +531,7 @@ static HRESULT Update2(
/////////////////////////////////////////
// Write Empty Files & Folders
- CRecordVector<const CUpdateItem *> emptyRefs;
+ CRecordVector<int> emptyRefs;
for(i = 0; i < updateItems.Size(); i++)
{
const CUpdateItem &updateItem = updateItems[i];
@@ -548,13 +544,12 @@ static HRESULT Update2(
if (updateItem.IndexInArchive != -1)
if (database->Files[updateItem.IndexInArchive].HasStream)
continue;
- emptyRefs.Add(&updateItem);
+ emptyRefs.Add(i);
}
- qsort(&emptyRefs.Front(), emptyRefs.Size(), sizeof(emptyRefs[0]),
- CompareEmptyItems);
+ emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems);
for(i = 0; i < emptyRefs.Size(); i++)
{
- const CUpdateItem &updateItem = *emptyRefs[i];
+ const CUpdateItem &updateItem = updateItems[emptyRefs[i]];
CFileItem file;
if (updateItem.NewProperties)
FromUpdateItemToFileItem(updateItem, file);
@@ -566,11 +561,11 @@ static HRESULT Update2(
////////////////////////////
COutArchive archive;
- archive.Create(seqOutStream, false);
+ RINOK(archive.Create(seqOutStream, false));
RINOK(archive.SkeepPrefixArchiveHeader());
UInt64 complexity = 0;
for(i = 0; i < folderRefs.Size(); i++)
- complexity += database->GetFolderFullPackSize(folderRefs[i].FolderIndex);
+ complexity += database->GetFolderFullPackSize(folderRefs[i]);
for(i = 0; i < updateItems.Size(); i++)
{
const CUpdateItem &updateItem = updateItems[i];
@@ -586,7 +581,7 @@ static HRESULT Update2(
for(i = 0; i < folderRefs.Size(); i++)
{
- int folderIndex = folderRefs[i].FolderIndex;
+ int folderIndex = folderRefs[i];
RINOK(WriteRange(inStream, archive.SeqStream,
database->GetFolderStreamPos(folderIndex, 0),
@@ -652,7 +647,7 @@ static HRESULT Update2(
for (i = 0; i < numFiles; i++)
refItems.Add(CRefItem(group.Indices[i],
updateItems[group.Indices[i]], numSolidFiles > 1));
- qsort(&refItems.Front(), refItems.Size(), sizeof(refItems[0]), CompareUpdateItems);
+ refItems.Sort(CompareUpdateItems, 0);
CRecordVector<UInt32> indices;
indices.Reserve(numFiles);
@@ -862,7 +857,7 @@ HRESULT UpdateVolume(
RINOK(volumeCallback->GetVolumeStream(volumeIndex, &volumeStream));
COutArchive archive;
- archive.Create(volumeStream, true);
+ RINOK(archive.Create(volumeStream, true));
RINOK(archive.SkeepPrefixArchiveHeader());
CSequentialInStreamWithCRC *inCrcStreamSpec = new CSequentialInStreamWithCRC;
@@ -914,7 +909,6 @@ public:
HRESULT Flush();
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
};
HRESULT COutVolumeStream::Flush()
@@ -943,7 +937,7 @@ STDMETHODIMP COutVolumeStream::Write(const void *data, UInt32 size, UInt32 *proc
RINOK(VolumeCallback->GetVolumeStream(_volIndex, &_volumeStream));
_volIndex++;
_curPos = 0;
- _archive.Create(_volumeStream, true);
+ RINOK(_archive.Create(_volumeStream, true));
RINOK(_archive.SkeepPrefixArchiveHeader());
_crc.Init();
continue;
@@ -959,7 +953,7 @@ STDMETHODIMP COutVolumeStream::Write(const void *data, UInt32 size, UInt32 *proc
if(processedSize != NULL)
*processedSize += realProcessed;
_curPos += realProcessed;
- if (realProcessed != curSize)
+ if (realProcessed != curSize && realProcessed == 0)
return E_FAIL;
if (_curPos == pureSize)
{
@@ -969,16 +963,12 @@ STDMETHODIMP COutVolumeStream::Write(const void *data, UInt32 size, UInt32 *proc
return S_OK;
}
-STDMETHODIMP COutVolumeStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize)
-{
- return Write(data, size, processedSize);
-}
#endif
HRESULT Update(
IInStream *inStream,
const CArchiveDatabaseEx *database,
- CObjectVector<CUpdateItem> &updateItems,
+ const CObjectVector<CUpdateItem> &updateItems,
ISequentialOutStream *seqOutStream,
IArchiveUpdateCallback *updateCallback,
const CUpdateOptions &options)
diff --git a/7zip/Archive/7z/7zUpdate.h b/7zip/Archive/7z/7zUpdate.h
index ab6cff4f..7567864a 100755
--- a/7zip/Archive/7z/7zUpdate.h
+++ b/7zip/Archive/7z/7zUpdate.h
@@ -60,7 +60,7 @@ struct CUpdateOptions
HRESULT Update(
IInStream *inStream,
const CArchiveDatabaseEx *database,
- CObjectVector<CUpdateItem> &updateItems,
+ const CObjectVector<CUpdateItem> &updateItems,
ISequentialOutStream *seqOutStream,
IArchiveUpdateCallback *updateCallback,
const CUpdateOptions &options);
diff --git a/7zip/Archive/7z/makefile b/7zip/Archive/7z/makefile
index 5c58e960..97bbbaaf 100755
--- a/7zip/Archive/7z/makefile
+++ b/7zip/Archive/7z/makefile
@@ -48,6 +48,7 @@ WIN_OBJS = \
$O\ProgressUtils.obj \
$O\StreamBinder.obj \
$O\StreamObjects.obj \
+ $O\StreamUtils.obj \
AR_COMMON_OBJS = \
$O\CodecsPath.obj \
diff --git a/7zip/Archive/7z_C/makefile.gcc b/7zip/Archive/7z_C/makefile.gcc
new file mode 100755
index 00000000..21b7df47
--- /dev/null
+++ b/7zip/Archive/7z_C/makefile.gcc
@@ -0,0 +1,50 @@
+PROG = 7zDec
+CXX = g++
+LIB =
+RM = rm -f
+CFLAGS = -c -O2 -Wall
+
+OBJS = 7zAlloc.o 7zBuffer.o 7zCrc.o 7zDecode.o 7zExtract.o 7zHeader.o 7zIn.o 7zItem.o 7zMain.o 7zMethodID.o LzmaDecode.o
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB)
+
+7zAlloc.o: 7zAlloc.c
+ $(CXX) $(CFLAGS) 7zAlloc.c
+
+7zBuffer.o: 7zBuffer.c
+ $(CXX) $(CFLAGS) 7zBuffer.c
+
+7zCrc.o: 7zCrc.c
+ $(CXX) $(CFLAGS) 7zCrc.c
+
+7zDecode.o: 7zDecode.c
+ $(CXX) $(CFLAGS) 7zDecode.c
+
+7zExtract.o: 7zExtract.c
+ $(CXX) $(CFLAGS) 7zExtract.c
+
+7zHeader.o: 7zHeader.c
+ $(CXX) $(CFLAGS) 7zHeader.c
+
+7zIn.o: 7zIn.c
+ $(CXX) $(CFLAGS) 7zIn.c
+
+7zItem.o: 7zItem.c
+ $(CXX) $(CFLAGS) 7zItem.c
+
+7zMain.o: 7zMain.c
+ $(CXX) $(CFLAGS) 7zMain.c
+
+7zMethodID.o: 7zMethodID.c
+ $(CXX) $(CFLAGS) 7zMethodID.c
+
+LzmaDecode.o: ../../Compress/LZMA_C/LzmaDecode.c
+ $(CXX) $(CFLAGS) ../../Compress/LZMA_C/LzmaDecode.c
+
+
+clean:
+ -$(RM) $(PROG) $(OBJS)
+
diff --git a/7zip/Archive/Arj/Arj.dsp b/7zip/Archive/Arj/Arj.dsp
index 0963ce38..3bc6fa91 100755
--- a/7zip/Archive/Arj/Arj.dsp
+++ b/7zip/Archive/Arj/Arj.dsp
@@ -213,19 +213,19 @@ SOURCE=.\ArjItem.h
# PROP Default_Filter ""
# Begin Source File
-SOURCE=..\..\Compress\Arj\Decoder1.cpp
+SOURCE=..\..\Compress\Arj\ArjDecoder1.cpp
# End Source File
# Begin Source File
-SOURCE=..\..\Compress\Arj\Decoder1.h
+SOURCE=..\..\Compress\Arj\ArjDecoder1.h
# End Source File
# Begin Source File
-SOURCE=..\..\Compress\Arj\Decoder2.cpp
+SOURCE=..\..\Compress\Arj\ArjDecoder2.cpp
# End Source File
# Begin Source File
-SOURCE=..\..\Compress\Arj\Decoder2.h
+SOURCE=..\..\Compress\Arj\ArjDecoder2.h
# End Source File
# End Group
# Begin Group "LZ"
@@ -278,12 +278,28 @@ SOURCE=..\..\Common\MSBFDecoder.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\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
# End Group
# Begin Group "Archive Common"
diff --git a/7zip/Archive/Arj/ArjHandler.cpp b/7zip/Archive/Arj/ArjHandler.cpp
index 7701da3b..ab75493f 100755
--- a/7zip/Archive/Arj/ArjHandler.cpp
+++ b/7zip/Archive/Arj/ArjHandler.cpp
@@ -19,8 +19,8 @@
#include "../../Common/LimitedStreams.h"
#include "../../Compress/Copy/CopyCoder.h"
-#include "../../Compress/Arj/Decoder1.h"
-#include "../../Compress/Arj/Decoder2.h"
+#include "../../Compress/Arj/ArjDecoder1.h"
+#include "../../Compress/Arj/ArjDecoder2.h"
#include "../Common/ItemNameUtils.h"
#include "../Common/OutStreamWithCRC.h"
diff --git a/7zip/Archive/Arj/ArjIn.cpp b/7zip/Archive/Arj/ArjIn.cpp
index c019055c..03346824 100755
--- a/7zip/Archive/Arj/ArjIn.cpp
+++ b/7zip/Archive/Arj/ArjIn.cpp
@@ -6,6 +6,8 @@
#include "Common/Buffer.h"
#include "Common/CRC.h"
+#include "../../Common/StreamUtils.h"
+
#include "ArjIn.h"
namespace NArchive {
@@ -14,7 +16,7 @@ namespace NArj {
HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessedSize;
- HRESULT result = _stream->Read(data, size, &realProcessedSize);
+ HRESULT result = ReadStream(_stream, data, size, &realProcessedSize);
if(processedSize != NULL)
*processedSize = realProcessedSize;
IncreasePositionValue(realProcessedSize);
@@ -162,7 +164,7 @@ bool CInArchive::ReadBlock()
{
_blockPos = 0;
_blockSize = SafeReadUInt16();
- if (_blockSize == 0)
+ if (_blockSize == 0 || _blockSize > kMaxBlockSize)
return false;
SafeReadBytes(_block, _blockSize);
UInt32 crcFromFile = SafeReadUInt32();
diff --git a/7zip/Archive/Arj/DllExports.cpp b/7zip/Archive/Arj/DllExports.cpp
index abedc1f7..202fbe0d 100755
--- a/7zip/Archive/Arj/DllExports.cpp
+++ b/7zip/Archive/Arj/DllExports.cpp
@@ -8,9 +8,9 @@
#include "../../ICoder.h"
#include "ArjHandler.h"
-// {23170F69-40C1-278A-1000-0001100A0000}
+// {23170F69-40C1-278A-1000-000110040000}
DEFINE_GUID(CLSID_CArjHandler,
- 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x0A, 0x00, 0x00);
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x04, 0x00, 0x00);
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
diff --git a/7zip/Archive/Arj/makefile b/7zip/Archive/Arj/makefile
index d45975b4..2609998b 100755
--- a/7zip/Archive/Arj/makefile
+++ b/7zip/Archive/Arj/makefile
@@ -22,15 +22,17 @@ WIN_OBJS = \
7ZIP_COMMON_OBJS = \
$O\InBuffer.obj \
$O\LimitedStreams.obj \
+ $O\OutBuffer.obj \
$O\ProgressUtils.obj \
+ $O\StreamUtils.obj \
AR_COMMON_OBJS = \
$O\ItemNameUtils.obj \
$O\OutStreamWithCRC.obj \
COMPRESS_ARJ_OBJS = \
- $O\Decoder1.obj \
- $O\Decoder2.obj \
+ $O\ArjDecoder1.obj \
+ $O\ArjDecoder2.obj \
OBJS = \
$O\StdAfx.obj \
diff --git a/7zip/Archive/BZip2/BZip2.dsp b/7zip/Archive/BZip2/BZip2.dsp
index 0e28884f..ccae8d3b 100755
--- a/7zip/Archive/BZip2/BZip2.dsp
+++ b/7zip/Archive/BZip2/BZip2.dsp
@@ -256,6 +256,14 @@ SOURCE=..\..\Common\ProgressUtils.cpp
SOURCE=..\..\Common\ProgressUtils.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 Source File
diff --git a/7zip/Archive/BZip2/BZip2Handler.cpp b/7zip/Archive/BZip2/BZip2Handler.cpp
index 97ea155c..88e5da1f 100755
--- a/7zip/Archive/BZip2/BZip2Handler.cpp
+++ b/7zip/Archive/BZip2/BZip2Handler.cpp
@@ -7,7 +7,7 @@
#include "Common/Defs.h"
#include "../../Common/ProgressUtils.h"
-// #include "Interface/EnumStatProp.h"
+#include "../../Common/StreamUtils.h"
#include "Windows/PropVariant.h"
#include "Windows/Defs.h"
@@ -111,7 +111,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
const int kSignatureSize = 3;
Byte buffer[kSignatureSize];
UInt32 processedSize;
- RINOK(stream->Read(buffer, kSignatureSize, &processedSize));
+ RINOK(ReadStream(stream, buffer, kSignatureSize, &processedSize));
if (processedSize != kSignatureSize)
return S_FALSE;
if (buffer[0] != 'B' || buffer[1] != 'Z' || buffer[2] != 'h')
@@ -221,7 +221,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
const int kSignatureSize = 3;
Byte buffer[kSignatureSize];
UInt32 processedSize;
- RINOK(_stream->Read(buffer, kSignatureSize, &processedSize));
+ RINOK(ReadStream(_stream, buffer, kSignatureSize, &processedSize));
if (processedSize < kSignatureSize)
{
if (firstItem)
diff --git a/7zip/Archive/BZip2/DllExports.cpp b/7zip/Archive/BZip2/DllExports.cpp
index 52e9cca4..932a75bb 100755
--- a/7zip/Archive/BZip2/DllExports.cpp
+++ b/7zip/Archive/BZip2/DllExports.cpp
@@ -16,9 +16,9 @@ DEFINE_GUID(CLSID_CCompressBZip2Encoder,
DEFINE_GUID(CLSID_CCompressBZip2Decoder,
0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
-// {23170F69-40C1-278A-1000-000110070000}
+// {23170F69-40C1-278A-1000-000110020000}
DEFINE_GUID(CLSID_CBZip2Handler,
-0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);
+0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x02, 0x00, 0x00);
HINSTANCE g_hInstance;
diff --git a/7zip/Archive/BZip2/makefile b/7zip/Archive/BZip2/makefile
index 936abdcc..85095122 100755
--- a/7zip/Archive/BZip2/makefile
+++ b/7zip/Archive/BZip2/makefile
@@ -22,6 +22,7 @@ WIN_OBJS = \
7ZIP_COMMON_OBJS = \
$O\ProgressUtils.obj \
+ $O\StreamUtils.obj \
AR_COMMON_OBJS = \
$O\CodecsPath.obj \
diff --git a/7zip/Archive/Cab/Cab.dsp b/7zip/Archive/Cab/Cab.dsp
index f96be2e0..565661f6 100755
--- a/7zip/Archive/Cab/Cab.dsp
+++ b/7zip/Archive/Cab/Cab.dsp
@@ -43,7 +43,7 @@ RSC=rc.exe
# 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 "CAB_EXPORTS" /YX /FD /c
-# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /Yu"StdAfx.h" /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /FAs /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"
@@ -70,7 +70,7 @@ LINK32=link.exe
# 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 "CAB_EXPORTS" /YX /FD /GZ /c
-# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c
+# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /FAcs /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"
@@ -190,11 +190,11 @@ SOURCE=..\..\..\Windows\PropVariant.h
# PROP Default_Filter ""
# Begin Source File
-SOURCE=.\CabCopyDecoder.cpp
+SOURCE=.\CabBlockInStream.cpp
# End Source File
# Begin Source File
-SOURCE=.\CabCopyDecoder.h
+SOURCE=.\CabBlockInStream.h
# End Source File
# Begin Source File
@@ -222,110 +222,168 @@ SOURCE=.\CabIn.h
# End Source File
# Begin Source File
-SOURCE=.\CabInBuffer.cpp
+SOURCE=.\CabItem.h
# End Source File
+# End Group
+# Begin Group "7zip Common"
+
+# PROP Default_Filter ""
# Begin Source File
-SOURCE=.\CabInBuffer.h
+SOURCE=..\..\Common\InBuffer.cpp
# End Source File
# Begin Source File
-SOURCE=.\CabItem.h
+SOURCE=..\..\Common\InBuffer.h
# End Source File
# Begin Source File
-SOURCE=.\LZXBitDecoder.h
+SOURCE=..\..\Common\LSBFDecoder.cpp
# End Source File
# Begin Source File
-SOURCE=.\LZXConst.h
+SOURCE=..\..\Common\LSBFDecoder.h
# End Source File
# Begin Source File
-SOURCE=.\LZXDecoder.cpp
+SOURCE=..\..\Common\MSBFDecoder.h
# End Source File
# Begin Source File
-SOURCE=.\LZXDecoder.h
+SOURCE=..\..\Common\OutBuffer.cpp
# End Source File
# Begin Source File
-SOURCE=.\LZXExtConst.h
+SOURCE=..\..\Common\OutBuffer.h
# End Source File
# Begin Source File
-SOURCE=.\LZXi86Converter.cpp
+SOURCE=..\..\Common\StreamUtils.cpp
# End Source File
# Begin Source File
-SOURCE=.\LZXi86Converter.h
+SOURCE=..\..\Common\StreamUtils.h
# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Group "LZ"
+
+# PROP Default_Filter ""
# Begin Source File
-SOURCE=.\MSZipConst.h
+SOURCE=..\..\Compress\LZ\LZOutWindow.cpp
# End Source File
# Begin Source File
-SOURCE=.\MSZipDecoder.cpp
+SOURCE=..\..\Compress\LZ\LZOutWindow.h
# End Source File
+# End Group
+# Begin Group "Lzx"
+
+# PROP Default_Filter ""
# Begin Source File
-SOURCE=.\MSZipDecoder.h
+SOURCE=..\..\Compress\Lzx\Lzx.h
# End Source File
# Begin Source File
-SOURCE=.\MSZipExtConst.h
+SOURCE=..\..\Compress\Lzx\Lzx86Converter.cpp
+
+!IF "$(CFG)" == "Cab - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Cab - Win32 Debug"
+
+!ENDIF
+
# End Source File
-# End Group
-# Begin Group "7zip Common"
+# Begin Source File
-# PROP Default_Filter ""
+SOURCE=..\..\Compress\Lzx\Lzx86Converter.h
+# End Source File
# Begin Source File
-SOURCE=..\..\Common\InBuffer.cpp
+SOURCE=..\..\Compress\Lzx\LzxDecoder.cpp
+
+!IF "$(CFG)" == "Cab - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Cab - Win32 Debug"
+
+!ENDIF
+
# End Source File
# Begin Source File
-SOURCE=..\..\Common\InBuffer.h
+SOURCE=..\..\Compress\Lzx\LzxDecoder.h
# End Source File
+# End Group
+# Begin Group "Deflate"
+
+# PROP Default_Filter ""
# Begin Source File
-SOURCE=..\..\Common\LSBFDecoder.cpp
+SOURCE=..\..\Compress\Deflate\DeflateConst.h
# End Source File
# Begin Source File
-SOURCE=..\..\Common\LSBFDecoder.h
+SOURCE=..\..\Compress\Deflate\DeflateDecoder.cpp
+
+!IF "$(CFG)" == "Cab - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Cab - Win32 Debug"
+
+!ENDIF
+
# End Source File
# Begin Source File
-SOURCE=..\..\Common\OutBuffer.cpp
+SOURCE=..\..\Compress\Deflate\DeflateDecoder.h
# End Source File
# Begin Source File
-SOURCE=..\..\Common\OutBuffer.h
+SOURCE=..\..\Compress\Deflate\DeflateExtConst.h
# End Source File
+# End Group
+# Begin Group "Copy"
+
+# PROP Default_Filter ""
# Begin Source File
-SOURCE=..\..\Common\ProgressUtils.cpp
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
# End Source File
# Begin Source File
-SOURCE=..\..\Common\ProgressUtils.h
+SOURCE=..\..\Compress\Copy\CopyCoder.h
# End Source File
# End Group
-# Begin Group "Compress"
+# Begin Group "Quantum"
# PROP Default_Filter ""
-# Begin Group "LZ"
+# Begin Source File
-# PROP Default_Filter ""
+SOURCE=..\..\Compress\Quantum\QuantumDecoder.cpp
+# End Source File
# Begin Source File
-SOURCE=..\..\Compress\LZ\LZOutWindow.cpp
+SOURCE=..\..\Compress\Quantum\QuantumDecoder.h
# End Source File
+# End Group
+# Begin Group "Huffman"
+
+# PROP Default_Filter ""
# Begin Source File
-SOURCE=..\..\Compress\LZ\LZOutWindow.h
+SOURCE=..\..\Compress\Huffman\HuffmanDecoder.h
# End Source File
# End Group
# End Group
diff --git a/7zip/Archive/Cab/CabBlockInStream.cpp b/7zip/Archive/Cab/CabBlockInStream.cpp
new file mode 100755
index 00000000..b775c105
--- /dev/null
+++ b/7zip/Archive/Cab/CabBlockInStream.cpp
@@ -0,0 +1,194 @@
+// CabBlockInStream.cpp
+
+#include "StdAfx.h"
+
+#include "Common/Alloc.h"
+#include "Common/Defs.h"
+
+#include "../../Common/StreamUtils.h"
+
+#include "CabBlockInStream.h"
+
+namespace NArchive {
+namespace NCab {
+
+static const UInt32 kBlockSize = (1 << 16);
+
+bool CCabBlockInStream::Create()
+{
+ if (!_buffer)
+ _buffer = (Byte *)::MyAlloc(kBlockSize);
+ return (_buffer != 0);
+}
+
+CCabBlockInStream::~CCabBlockInStream()
+{
+ MyFree(_buffer);
+}
+
+class CCheckSum2
+{
+ UInt32 m_Value;
+ int m_Pos;
+ Byte m_Hist[4];
+public:
+ CCheckSum2(): m_Value(0){};
+ void Init() { m_Value = 0; m_Pos = 0; }
+ void Update(const void *data, UInt32 size);
+ void FinishDataUpdate()
+ {
+ for (int i = 0; i < m_Pos; i++)
+ m_Value ^= ((UInt32)(m_Hist[i])) << (8 * (m_Pos - i - 1));
+ }
+ void UpdateUInt32(UInt32 v) { m_Value ^= v; }
+ UInt32 GetResult() const { return m_Value; }
+};
+
+void CCheckSum2::Update(const void *data, UInt32 size)
+{
+ UInt32 checkSum = m_Value;
+ const Byte *dataPointer = (const Byte *)data;
+
+ while (size != 0 && m_Pos != 0)
+ {
+ m_Hist[m_Pos] = *dataPointer++;
+ m_Pos = (m_Pos + 1) & 3;
+ size--;
+ if (m_Pos == 0)
+ for (int i = 0; i < 4; i++)
+ checkSum ^= ((UInt32)m_Hist[i]) << (8 * i);
+ }
+
+ int numWords = size / 4;
+
+ while (numWords-- != 0)
+ {
+ UInt32 temp = *dataPointer++;
+ temp |= ((UInt32)(*dataPointer++)) << 8;
+ temp |= ((UInt32)(*dataPointer++)) << 16;
+ temp |= ((UInt32)(*dataPointer++)) << 24;
+ checkSum ^= temp;
+ }
+ m_Value = checkSum;
+
+ size &= 3;
+
+ while (size != 0)
+ {
+ m_Hist[m_Pos] = *dataPointer++;
+ m_Pos = (m_Pos + 1) & 3;
+ size--;
+ }
+}
+
+static const UInt32 kDataBlockHeaderSize = 8;
+
+class CTempCabInBuffer2
+{
+public:
+ Byte Buffer[kDataBlockHeaderSize];
+ UInt32 Pos;
+ Byte ReadByte()
+ {
+ return Buffer[Pos++];
+ }
+ UInt32 ReadUInt32()
+ {
+ UInt32 value = 0;
+ for (int i = 0; i < 4; i++)
+ value |= (((UInt32)ReadByte()) << (8 * i));
+ return value;
+ }
+ UInt16 ReadUInt16()
+ {
+ UInt16 value = 0;
+ for (int i = 0; i < 2; i++)
+ value |= (((UInt16)ReadByte()) << (8 * i));
+ return value;
+ }
+};
+
+HRESULT CCabBlockInStream::PreRead(UInt32 &packSize, UInt32 &unpackSize)
+{
+ CTempCabInBuffer2 inBuffer;
+ inBuffer.Pos = 0;
+ UInt32 processedSizeLoc;
+ RINOK(ReadStream(_stream, inBuffer.Buffer, kDataBlockHeaderSize, &processedSizeLoc))
+ if (processedSizeLoc != kDataBlockHeaderSize)
+ return S_FALSE; // bad block
+
+ UInt32 checkSum = inBuffer.ReadUInt32();
+ packSize = inBuffer.ReadUInt16();
+ unpackSize = inBuffer.ReadUInt16();
+ if (ReservedSize != 0)
+ {
+ RINOK(ReadStream(_stream, _buffer, ReservedSize, &processedSizeLoc));
+ if(ReservedSize != processedSizeLoc)
+ return S_FALSE; // bad block;
+ }
+ _pos = 0;
+ CCheckSum2 checkSumCalc;
+ checkSumCalc.Init();
+ UInt32 packSize2 = packSize;
+ if (MsZip && _size == 0)
+ {
+ if (packSize < 2)
+ return S_FALSE; // bad block;
+ Byte sig[2];
+ RINOK(ReadStream(_stream, sig, 2, &processedSizeLoc));
+ if(processedSizeLoc != 2)
+ return S_FALSE;
+ if (sig[0] != 0x43 || sig[1] != 0x4B)
+ return S_FALSE;
+ packSize2 -= 2;
+ checkSumCalc.Update(sig, 2);
+ }
+
+ if (kBlockSize - _size < packSize2)
+ return S_FALSE;
+
+ UInt32 curSize = packSize2;
+ if (curSize != 0)
+ {
+ RINOK(ReadStream(_stream, _buffer + _size, curSize, &processedSizeLoc));
+ checkSumCalc.Update(_buffer + _size, processedSizeLoc);
+ _size += processedSizeLoc;
+ if (processedSizeLoc != curSize)
+ return S_FALSE;
+ }
+ TotalPackSize = _size;
+
+ checkSumCalc.FinishDataUpdate();
+
+ bool dataError;
+ if (checkSum == 0)
+ dataError = false;
+ else
+ {
+ checkSumCalc.UpdateUInt32(packSize | (((UInt32)unpackSize) << 16));
+ dataError = (checkSumCalc.GetResult() != checkSum);
+ }
+ DataError |= dataError;
+ return dataError ? S_FALSE : S_OK;
+}
+
+STDMETHODIMP CCabBlockInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (processedSize != 0)
+ *processedSize = 0;
+ if (size == 0)
+ return S_OK;
+ if (_size != 0)
+ {
+ size = MyMin(_size, size);
+ memmove(data, _buffer + _pos, size);
+ _pos += size;
+ _size -= size;
+ if (processedSize != 0)
+ *processedSize = size;
+ return S_OK;
+ }
+ return S_OK; // no blocks data
+}
+
+}}
diff --git a/7zip/Archive/Cab/CabBlockInStream.h b/7zip/Archive/Cab/CabBlockInStream.h
new file mode 100755
index 00000000..46e15222
--- /dev/null
+++ b/7zip/Archive/Cab/CabBlockInStream.h
@@ -0,0 +1,56 @@
+// CabBlockInStream.cpp
+
+#ifndef __CABBLOCKINSTREAM_H
+#define __CABBLOCKINSTREAM_H
+
+#include "Common/MyCom.h"
+#include "../../IStream.h"
+
+namespace NArchive {
+namespace NCab {
+
+class CCabBlockInStream:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ CMyComPtr<ISequentialInStream> _stream;
+ Byte *_buffer;
+ UInt32 _pos;
+ UInt32 _size;
+ int _align;
+
+public:
+ UInt32 TotalPackSize;
+ UInt32 ReservedSize;
+ bool DataError;
+ bool MsZip;
+
+ CCabBlockInStream(): _buffer(0), ReservedSize(0), MsZip(false), DataError(false), _align(0), TotalPackSize(0) {}
+ ~CCabBlockInStream();
+ bool Create();
+ void SetStream(ISequentialInStream *stream) { _stream = stream; }
+
+ void InitForNewFolder()
+ {
+ _align = 0;
+ TotalPackSize = 0;
+ }
+
+ void InitForNewBlock()
+ {
+ _size = 0;
+ _align = (_align + (int)TotalPackSize) & 1;
+ }
+
+ int GetAlign() const { return _align; }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+
+ HRESULT PreRead(UInt32 &packSize, UInt32 &unpackSize);
+};
+
+}}
+
+#endif
diff --git a/7zip/Archive/Cab/CabCopyDecoder.cpp b/7zip/Archive/Cab/CabCopyDecoder.cpp
deleted file mode 100755
index 541d4d93..00000000
--- a/7zip/Archive/Cab/CabCopyDecoder.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-// CabCopyDecoder.cpp
-
-#include "StdAfx.h"
-
-#include "CabCopyDecoder.h"
-#include "Common/Defs.h"
-#include "Windows/Defs.h"
-
-namespace NArchive {
-namespace NCab {
-
-static const UInt32 kBufferSize = 1 << 17;
-
-void CCopyDecoder::ReleaseStreams()
-{
- m_InStream.ReleaseStream();
- m_OutStream.ReleaseStream();
-}
-
-class CCopyDecoderFlusher
-{
- CCopyDecoder *m_Decoder;
-public:
- CCopyDecoderFlusher(CCopyDecoder *decoder): m_Decoder(decoder) {}
- ~CCopyDecoderFlusher()
- {
- m_Decoder->Flush();
- m_Decoder->ReleaseStreams();
- }
-};
-
-STDMETHODIMP CCopyDecoder::Code(ISequentialInStream *inStream,
- ISequentialOutStream *outStream,
- const UInt64 *inSize, const UInt64 *outSize,
- ICompressProgressInfo *progress)
-{
- if (outSize == NULL)
- return E_INVALIDARG;
- UInt64 size = *outSize;
-
- if (!m_OutStream.Create(1 << 20))
- return E_OUTOFMEMORY;
- if (!m_InStream.Create(1 << 20))
- return E_OUTOFMEMORY;
-
- m_InStream.SetStream(inStream);
- m_InStream.Init(m_ReservedSize, m_NumInDataBlocks);
- m_OutStream.SetStream(outStream);
- m_OutStream.Init();
- CCopyDecoderFlusher decoderFlusher(this);
-
- UInt64 nowPos64 = 0;
- while(nowPos64 < size)
- {
- UInt32 blockSize;
- bool dataAreCorrect;
- RINOK(m_InStream.ReadBlock(blockSize, dataAreCorrect));
- if (!dataAreCorrect)
- {
- throw 123456;
- }
- for (UInt32 i = 0; i < blockSize; i++)
- m_OutStream.WriteByte(m_InStream.ReadByte());
- nowPos64 += blockSize;
- if (progress != NULL)
- {
- RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
- }
- }
- return S_OK;
-}
-
-}}
diff --git a/7zip/Archive/Cab/CabCopyDecoder.h b/7zip/Archive/Cab/CabCopyDecoder.h
deleted file mode 100755
index 21545d39..00000000
--- a/7zip/Archive/Cab/CabCopyDecoder.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// CabCopyDecoder.h
-
-#ifndef __ARCHIVE_CAB_COPY_DECODER_H
-#define __ARCHIVE_CAB_COPY_DECODER_H
-
-#include "Common/MyCom.h"
-#include "../../ICoder.h"
-#include "../../Common/OutBuffer.h"
-#include "CabInBuffer.h"
-
-namespace NArchive {
-namespace NCab {
-
-class CCopyDecoder:
- public ICompressCoder,
- public CMyUnknownImp
-{
- CInBuffer m_InStream;
- COutBuffer m_OutStream;
- Byte m_ReservedSize;
- UInt32 m_NumInDataBlocks;
-public:
- MY_UNKNOWN_IMP
- STDMETHOD(Code)(ISequentialInStream *inStream,
- ISequentialOutStream *outStream,
- const UInt64 *inSize, const UInt64 *outSize,
- ICompressProgressInfo *progress);
-
- void ReleaseStreams();
- HRESULT Flush() { return m_OutStream.Flush(); }
- void SetParams(Byte reservedSize, UInt32 numInDataBlocks)
- {
- m_ReservedSize = reservedSize;
- m_NumInDataBlocks = numInDataBlocks;
- }
-
-};
-
-}}
-
-#endif \ No newline at end of file
diff --git a/7zip/Archive/Cab/CabHandler.cpp b/7zip/Archive/Cab/CabHandler.cpp
index 669de218..c3dd061f 100755
--- a/7zip/Archive/Cab/CabHandler.cpp
+++ b/7zip/Archive/Cab/CabHandler.cpp
@@ -1,9 +1,10 @@
-// Cab/Handler.cpp
+// CabHandler.cpp
#include "StdAfx.h"
#include "Common/StringConvert.h"
#include "Common/Defs.h"
+#include "Common/Alloc.h"
#include "Common/UTFConvert.h"
#include "Common/ComTry.h"
#include "Common/IntToString.h"
@@ -11,32 +12,45 @@
#include "Windows/PropVariant.h"
#include "Windows/Time.h"
-#include "CabCopyDecoder.h"
-#include "LZXDecoder.h"
-#include "MSZipDecoder.h"
-
#include "CabHandler.h"
+#include "CabBlockInStream.h"
-#include "../../Common/ProgressUtils.h"
+#include "../../Compress/Copy/CopyCoder.h"
+#include "../../Compress/Deflate/DeflateDecoder.h"
+#include "../../Compress/Lzx/LzxDecoder.h"
+#include "../../Compress/Quantum/QuantumDecoder.h"
using namespace NWindows;
-using namespace NTime;
namespace NArchive {
namespace NCab {
+// #define _CAB_DETAILS
+
+#ifdef _CAB_DETAILS
+enum
+{
+ kpidBlockReal = kpidUserDefined,
+ kpidOffset,
+ kpidVolume,
+};
+#endif
+
STATPROPSTG kProperties[] =
{
{ NULL, kpidPath, VT_BSTR},
- { NULL, kpidIsFolder, VT_BOOL},
+ // { NULL, kpidIsFolder, VT_BOOL},
{ NULL, kpidSize, VT_UI8},
{ NULL, kpidLastWriteTime, VT_FILETIME},
{ NULL, kpidAttributes, VT_UI4},
-
{ NULL, kpidMethod, VT_BSTR},
- // { NULL, kpidDictionarySize, VT_UI4},
-
- { NULL, kpidBlock, VT_UI4}
+ { NULL, kpidBlock, VT_I4}
+ #ifdef _CAB_DETAILS
+ ,
+ { L"BlockReal", kpidBlockReal, VT_UI4},
+ { L"Offset", kpidOffset, VT_UI4},
+ { L"Volume", kpidVolume, VT_UI4}
+ #endif
};
static const int kNumProperties = sizeof(kProperties) / sizeof(kProperties[0]);
@@ -72,7 +86,10 @@ STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
const STATPROPSTG &srcItem = kProperties[index];
*propID = srcItem.propid;
*varType = srcItem.vt;
- *name = 0;
+ if (srcItem.lpwstrName == 0)
+ *name = 0;
+ else
+ *name = ::SysAllocString(srcItem.lpwstrName);
return S_OK;
}
@@ -92,31 +109,35 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant;
- const CItem &fileInfo = m_Files[index];
+
+ const CMvItem &mvItem = m_Database.Items[index];
+ const CDatabaseEx &db = m_Database.Volumes[mvItem.VolumeIndex];
+ int itemIndex = mvItem.ItemIndex;
+ const CItem &item = db.Items[itemIndex];
switch(propID)
{
case kpidPath:
- if (fileInfo.IsNameUTF())
+ if (item.IsNameUTF())
{
UString unicodeName;
- if (!ConvertUTF8ToUnicode(fileInfo.Name, unicodeName))
+ if (!ConvertUTF8ToUnicode(item.Name, unicodeName))
propVariant = L"";
else
propVariant = unicodeName;
}
else
- propVariant = MultiByteToUnicodeString(fileInfo.Name, CP_ACP);
+ propVariant = MultiByteToUnicodeString(item.Name, CP_ACP);
break;
case kpidIsFolder:
- propVariant = fileInfo.IsDirectory();
+ propVariant = item.IsDirectory();
break;
case kpidSize:
- propVariant = fileInfo.UnPackSize;
+ propVariant = item.Size;
break;
case kpidLastWriteTime:
{
FILETIME localFileTime, utcFileTime;
- if (DosTimeToFileTime(fileInfo.Time, localFileTime))
+ if (NTime::DosTimeToFileTime(item.Time, localFileTime))
{
if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
@@ -127,21 +148,17 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
break;
}
case kpidAttributes:
- propVariant = fileInfo.GetWinAttributes();
+ propVariant = item.GetWinAttributes();
break;
case kpidMethod:
{
- UInt16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex(
- m_Folders.Size(), fileInfo.FolderIndex);
- const NHeader::CFolder &folder = m_Folders[realFolderIndex];
- UString method;
+ UInt16 realFolderIndex = item.GetFolderIndex(db.Folders.Size());
+ const CFolder &folder = db.Folders[realFolderIndex];
int methodIndex = folder.GetCompressionMethod();
- if (methodIndex < kNumMethods)
- method = kMethods[methodIndex];
- else
- method = kUnknownMethod;
- if (methodIndex == NHeader::NCompressionMethodMajor::kLZX)
+ UString method = (methodIndex < kNumMethods) ? kMethods[methodIndex] : kUnknownMethod;
+ if (methodIndex == NHeader::NCompressionMethodMajor::kLZX ||
+ methodIndex == NHeader::NCompressionMethodMajor::kQuantum)
{
method += L":";
wchar_t temp[32];
@@ -152,14 +169,29 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
break;
}
case kpidBlock:
- propVariant = UInt32(fileInfo.FolderIndex);
+ propVariant = (Int32)m_Database.GetFolderIndex(&mvItem);
break;
+
+ #ifdef _CAB_DETAILS
+
+ case kpidBlockReal:
+ propVariant = UInt32(item.FolderIndex);
+ break;
+ case kpidOffset:
+ propVariant = (UInt32)item.Offset;
+ break;
+ case kpidVolume:
+ propVariant = (UInt32)mvItem.VolumeIndex;
+ break;
+
+ #endif
}
propVariant.Detach(value);
return S_OK;
COM_TRY_END
}
+/*
class CPropgressImp: public CProgressVirt
{
CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallback;
@@ -183,36 +215,113 @@ STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles)
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
return S_OK;
}
+*/
STDMETHODIMP CHandler::Open(IInStream *inStream,
const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openArchiveCallback)
{
COM_TRY_BEGIN
- m_Stream.Release();
- // try
+ Close();
+ HRESULT res;
+ CInArchive archive;
+ CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
{
- CInArchive archive;
- m_Files.Clear();
- CPropgressImp progressImp;
- progressImp.Init(openArchiveCallback);
- RINOK(archive.Open(inStream, maxCheckStartPosition,
- m_ArchiveInfo, m_Folders, m_Files, &progressImp));
- m_Stream = inStream;
+ CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = openArchiveCallback;
+ openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback);
+ }
+
+ CMyComPtr<IInStream> nextStream = inStream;
+ bool prevChecked = false;
+ UInt64 numItems = 0;
+ try
+ {
+ while(nextStream != 0)
+ {
+ CDatabaseEx db;
+ db.Stream = nextStream;
+ res = archive.Open(maxCheckStartPosition, db);
+ if (res == S_OK)
+ {
+ if (!m_Database.Volumes.IsEmpty())
+ {
+ const CDatabaseEx &dbPrev = m_Database.Volumes[prevChecked ? m_Database.Volumes.Size() - 1 : 0];
+ if (dbPrev.ArchiveInfo.SetID != db.ArchiveInfo.SetID ||
+ dbPrev.ArchiveInfo.CabinetNumber + (prevChecked ? 1: - 1) !=
+ db.ArchiveInfo.CabinetNumber)
+ res = S_FALSE;
+ }
+ }
+ if (res == S_OK)
+ m_Database.Volumes.Insert(prevChecked ? m_Database.Volumes.Size() : 0, db);
+ else if (res != S_FALSE)
+ return res;
+ else
+ {
+ if (m_Database.Volumes.IsEmpty())
+ return S_FALSE;
+ if (prevChecked)
+ break;
+ prevChecked = true;
+ }
+
+ numItems += db.Items.Size();
+ RINOK(openArchiveCallback->SetCompleted(&numItems, NULL));
+
+ nextStream = 0;
+ while(true)
+ {
+ const COtherArchive *otherArchive = 0;
+ if (!prevChecked)
+ {
+ const CInArchiveInfo &ai = m_Database.Volumes.Front().ArchiveInfo;
+ if (ai.IsTherePrev())
+ otherArchive = &ai.PreviousArchive;
+ else
+ prevChecked = true;
+ }
+ if (otherArchive == 0)
+ {
+ const CInArchiveInfo &ai = m_Database.Volumes.Back().ArchiveInfo;
+ if (ai.IsThereNext())
+ otherArchive = &ai.NextArchive;
+ }
+ if (!otherArchive)
+ break;
+ const UString fullName = MultiByteToUnicodeString(otherArchive->FileName, CP_ACP);
+ HRESULT result = openVolumeCallback->GetStream(fullName, &nextStream);
+ if (result == S_OK)
+ break;
+ if (result != S_FALSE)
+ return result;
+ if (prevChecked)
+ break;
+ prevChecked = true;
+ }
+ }
+ if (res == S_OK)
+ {
+ m_Database.FillSortAndShrink();
+ if (!m_Database.Check())
+ res = S_FALSE;
+ }
}
- /*
catch(...)
{
- return S_FALSE;
+ res = S_FALSE;
+ }
+ if (res != S_OK)
+ {
+ Close();
+ return res;
}
- */
COM_TRY_END
return S_OK;
}
STDMETHODIMP CHandler::Close()
{
- m_Stream.Release();
+ m_Database.Clear();
return S_OK;
}
@@ -224,405 +333,472 @@ public:
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
private:
- const CObjectVector<NHeader::CFolder> *m_Folders;
- const CObjectVector<CItem> *m_Files;
- const CRecordVector<int> *m_FileIndexes;
+ const CMvDatabaseEx *m_Database;
const CRecordVector<bool> *m_ExtractStatuses;
int m_StartIndex;
int m_CurrentIndex;
- int m_NumFiles;
- UInt64 m_CurrentDataPos;
CMyComPtr<IArchiveExtractCallback> m_ExtractCallback;
bool m_TestMode;
+ CMyComPtr<ISequentialOutStream> m_RealOutStream;
+
+ bool m_IsOk;
bool m_FileIsOpen;
- CMyComPtr<ISequentialOutStream> realOutStream;
- UInt64 m_FilePos;
+ UInt64 m_RemainFileSize;
+ UInt64 m_FolderSize;
+ UInt64 m_PosInFolder;
- HRESULT OpenFile(int indexIndex, ISequentialOutStream **realOutStream);
- HRESULT WriteEmptyFiles();
- UInt64 m_StartImportantTotalUnPacked;
+ HRESULT OpenFile();
+ HRESULT Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK);
public:
+ HRESULT WriteEmptyFiles();
+
void Init(
- const CObjectVector<NHeader::CFolder> *folders,
- const CObjectVector<CItem> *files,
- const CRecordVector<int> *fileIndices,
+ const CMvDatabaseEx *database,
const CRecordVector<bool> *extractStatuses,
int startIndex,
- int numFiles,
+ UInt64 folderSize,
IArchiveExtractCallback *extractCallback,
- UInt64 startImportantTotalUnPacked,
bool testMode);
HRESULT FlushCorrupted();
HRESULT Unsupported();
+
+ UInt64 GetRemain() const { return m_FolderSize - m_PosInFolder; }
+ UInt64 GetPosInFolder() const { return m_PosInFolder; }
};
void CCabFolderOutStream::Init(
- const CObjectVector<NHeader::CFolder> *folders,
- const CObjectVector<CItem> *files,
- const CRecordVector<int> *fileIndices,
+ const CMvDatabaseEx *database,
const CRecordVector<bool> *extractStatuses,
int startIndex,
- int numFiles,
+ UInt64 folderSize,
IArchiveExtractCallback *extractCallback,
- UInt64 startImportantTotalUnPacked,
bool testMode)
{
- m_Folders = folders;
- m_Files = files;
- m_FileIndexes = fileIndices;
+ m_Database = database;
m_ExtractStatuses = extractStatuses;
m_StartIndex = startIndex;
- m_NumFiles = numFiles;
+ m_FolderSize = folderSize;
+
m_ExtractCallback = extractCallback;
- m_StartImportantTotalUnPacked = startImportantTotalUnPacked;
m_TestMode = testMode;
m_CurrentIndex = 0;
+ m_PosInFolder = 0;
m_FileIsOpen = false;
+ m_IsOk = true;
}
-HRESULT CCabFolderOutStream::OpenFile(int indexIndex, ISequentialOutStream **realOutStream)
+HRESULT CCabFolderOutStream::OpenFile()
{
- // RINOK(m_ExtractCallback->SetCompleted(&m_StartImportantTotalUnPacked));
-
- int fullIndex = m_StartIndex + indexIndex;
-
- Int32 askMode;
- if((*m_ExtractStatuses)[fullIndex])
- askMode = m_TestMode ?
- NArchive::NExtract::NAskMode::kTest :
- NArchive::NExtract::NAskMode::kExtract;
- else
+ 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 = NArchive::NExtract::NAskMode::kSkip;
-
- int index = (*m_FileIndexes)[fullIndex];
- const CItem &fileInfo = (*m_Files)[index];
- UInt16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex(
- m_Folders->Size(), fileInfo.FolderIndex);
-
- RINOK(m_ExtractCallback->GetStream(index, realOutStream, askMode));
-
- UInt64 currentUnPackSize = fileInfo.UnPackSize;
-
- bool mustBeProcessedAnywhere = (indexIndex < m_NumFiles - 1);
-
- if (realOutStream || mustBeProcessedAnywhere)
- {
- if (!realOutStream && !m_TestMode)
- askMode = NArchive::NExtract::NAskMode::kSkip;
- RINOK(m_ExtractCallback->PrepareOperation(askMode));
- return S_OK;
- }
- else
- return S_FALSE;
+ return m_ExtractCallback->PrepareOperation(askMode);
}
-
HRESULT CCabFolderOutStream::WriteEmptyFiles()
{
- for(;m_CurrentIndex < m_NumFiles; m_CurrentIndex++)
+ if (m_FileIsOpen)
+ return S_OK;
+ for(;m_CurrentIndex < m_ExtractStatuses->Size(); m_CurrentIndex++)
{
- int index = (*m_FileIndexes)[m_StartIndex + m_CurrentIndex];
- const CItem &fileInfo = (*m_Files)[index];
- if (fileInfo.UnPackSize != 0)
+ 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;
- realOutStream.Release();
- HRESULT result = OpenFile(m_CurrentIndex, &realOutStream);
- realOutStream.Release();
- if (result == S_FALSE)
- {
- }
- else if (result == S_OK)
- {
- RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
- }
- else
- return result;
+ HRESULT result = OpenFile();
+ m_RealOutStream.Release();
+ RINOK(result);
+ RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
}
return S_OK;
}
-STDMETHODIMP CCabFolderOutStream::Write(const void *data,
- UInt32 size, UInt32 *processedSize)
+// This is Write function
+HRESULT CCabFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK)
{
- UInt32 processedSizeReal = 0;
- while(m_CurrentIndex < m_NumFiles)
+ UInt32 realProcessed = 0;
+ if (processedSize != NULL)
+ *processedSize = 0;
+ while(size != 0)
{
if (m_FileIsOpen)
{
- int index = (*m_FileIndexes)[m_StartIndex + m_CurrentIndex];
- const CItem &fileInfo = (*m_Files)[index];
- UInt64 fileSize = fileInfo.UnPackSize;
-
- UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - m_FilePos,
- UInt64(size - processedSizeReal));
-
- UInt32 processedSizeLocal;
- if (!realOutStream)
- {
- processedSizeLocal = numBytesToWrite;
- }
- else
+ UInt32 numBytesToWrite = (UInt32)MyMin(m_RemainFileSize, (UInt64)(size));
+ HRESULT res = S_OK;
+ if (numBytesToWrite > 0)
{
- RINOK(realOutStream->Write((const Byte *)data + processedSizeReal, numBytesToWrite, &processedSizeLocal));
+ if (!isOK)
+ m_IsOk = false;
+ if (m_RealOutStream)
+ {
+ UInt32 processedSizeLocal = 0;
+ res = m_RealOutStream->Write((const Byte *)data, numBytesToWrite, &processedSizeLocal);
+ numBytesToWrite = processedSizeLocal;
+ }
}
- m_FilePos += processedSizeLocal;
- processedSizeReal += processedSizeLocal;
- if (m_FilePos == fileInfo.UnPackSize)
+ realProcessed += numBytesToWrite;
+ if (processedSize != NULL)
+ *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)
{
- realOutStream.Release();
- RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ m_RealOutStream.Release();
+ RINOK(m_ExtractCallback->SetOperationResult(
+ m_IsOk ?
+ NArchive::NExtract::NOperationResult::kOK:
+ NArchive::NExtract::NOperationResult::kDataError));
m_FileIsOpen = false;
- m_CurrentIndex++;
- }
- if (processedSizeReal == size)
- {
- RINOK(WriteEmptyFiles());
- if (processedSize != NULL)
- *processedSize = processedSizeReal;
- return S_OK;
}
+ if (realProcessed > 0)
+ break; // with this break this function works as Write-Part
}
else
{
- HRESULT result = OpenFile(m_CurrentIndex, &realOutStream);
- if (result != S_FALSE && result != S_OK)
- return result;
- m_FileIsOpen = true;
- m_FilePos = 0;
+ if (m_CurrentIndex >= m_ExtractStatuses->Size())
+ 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 = (UInt32)MyMin((UInt64)fileOffset - m_PosInFolder, UInt64(size));
+ realProcessed += numBytesToWrite;
+ if (processedSize != NULL)
+ *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;
+ }
}
}
- if (processedSize != NULL)
- *processedSize = size;
- return S_OK;
+ return WriteEmptyFiles();
+}
+
+STDMETHODIMP CCabFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ return Write2(data, size, processedSize, true);
}
HRESULT CCabFolderOutStream::FlushCorrupted()
{
- // UInt32 processedSizeReal = 0;
- while(m_CurrentIndex < m_NumFiles)
+ const UInt32 kBufferSize = (1 << 10);
+ Byte buffer[kBufferSize];
+ for (int i = 0; i < kBufferSize; i++)
+ buffer[i] = 0;
+ while(true)
{
- if (m_FileIsOpen)
- {
- int index = (*m_FileIndexes)[m_StartIndex + m_CurrentIndex];
- const CItem &fileInfo = (*m_Files)[index];
- UInt64 fileSize = fileInfo.UnPackSize;
-
- realOutStream.Release();
- RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError));
- m_FileIsOpen = false;
- m_CurrentIndex++;
- }
- else
- {
- HRESULT result = OpenFile(m_CurrentIndex, &realOutStream);
- if (result != S_FALSE && result != S_OK)
- return result;
- m_FileIsOpen = true;
- }
+ UInt64 remain = GetRemain();
+ if (remain == 0)
+ return S_OK;
+ UInt32 size = (UInt32)MyMin(remain, (UInt64)kBufferSize);
+ UInt32 processedSizeLocal = 0;
+ RINOK(Write2(buffer, size, &processedSizeLocal, false));
}
- return S_OK;
}
HRESULT CCabFolderOutStream::Unsupported()
{
- while(m_CurrentIndex < m_NumFiles)
+ while(m_CurrentIndex < m_ExtractStatuses->Size())
{
- HRESULT result = OpenFile(m_CurrentIndex, &realOutStream);
+ HRESULT result = OpenFile();
if (result != S_FALSE && result != S_OK)
return result;
- realOutStream.Release();
+ m_RealOutStream.Release();
RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
m_CurrentIndex++;
}
return S_OK;
}
-STDMETHODIMP CCabFolderOutStream::WritePart(const void *data,
- UInt32 size, UInt32 *processedSize)
-{
- return Write(data, size, processedSize);
-}
-
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
{
COM_TRY_BEGIN
- bool allFilesMode = (numItems == UInt32(-1));
+ bool allFilesMode = (numItems == (UInt32)(-1));
if (allFilesMode)
- numItems = m_Files.Size();
+ numItems = m_Database.Items.Size();
if(numItems == 0)
return S_OK;
bool testMode = (_aTestMode != 0);
- UInt64 censoredTotalUnPacked = 0, importantTotalUnPacked = 0;
+ UInt64 totalUnPacked = 0;
int lastIndex = 0;
- CRecordVector<int> folderIndexes;
- CRecordVector<int> importantIndices;
- CRecordVector<bool> extractStatuses;
UInt32 i;
+ int lastFolder = -2;
+ UInt64 lastFolderSize = 0;
for(i = 0; i < numItems; i++)
{
int index = allFilesMode ? i : indices[i];
- const CItem &fileInfo = m_Files[index];
- censoredTotalUnPacked += fileInfo.UnPackSize;
-
- int folderIndex = fileInfo.FolderIndex;
- if (folderIndexes.IsEmpty())
- folderIndexes.Add(folderIndex);
- else
- {
- if (folderIndex != folderIndexes.Back())
- folderIndexes.Add(folderIndex);
- }
-
- int j;
- for(j = index - 1; j >= lastIndex; j--)
- if(m_Files[j].FolderIndex != folderIndex)
- break;
- for(j++; j <= index; j++)
- {
- const CItem &fileInfo = m_Files[j];
- importantTotalUnPacked += fileInfo.UnPackSize;
- importantIndices.Add(j);
- extractStatuses.Add(j == index);
- }
- lastIndex = index + 1;
+ const CMvItem &mvItem = m_Database.Items[index];
+ const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
+ if (item.IsDirectory())
+ continue;
+ int folderIndex = m_Database.GetFolderIndex(&mvItem);
+ if (folderIndex != lastFolder)
+ totalUnPacked += lastFolderSize;
+ lastFolder = folderIndex;
+ lastFolderSize = item.GetEndOffset();
}
+ totalUnPacked += lastFolderSize;
+
+ extractCallback->SetTotal(totalUnPacked);
- extractCallback->SetTotal(importantTotalUnPacked);
- UInt64 currentImportantTotalUnPacked = 0;
- UInt64 currentImportantTotalPacked = 0;
+ totalUnPacked = 0;
- CCopyDecoder *storeDecoderSpec = NULL;
- CMyComPtr<ICompressCoder> storeDecoder;
+ NCompress::CCopyCoder *copyCoderSpec = NULL;
+ CMyComPtr<ICompressCoder> copyCoder;
- NMSZip::CDecoder *msZipDecoderSpec = NULL;
- CMyComPtr<ICompressCoder> msZipDecoder;
+ NCompress::NDeflate::NDecoder::CCOMCoder *deflateDecoderSpec = NULL;
+ CMyComPtr<ICompressCoder> deflateDecoder;
- NLZX::CDecoder *lzxDecoderSpec = NULL;
+ NCompress::NLzx::CDecoder *lzxDecoderSpec = NULL;
CMyComPtr<ICompressCoder> lzxDecoder;
+ NCompress::NQuantum::CDecoder *quantumDecoderSpec = NULL;
+ CMyComPtr<ICompressCoder> quantumDecoder;
- int curImportantIndexIndex = 0;
- UInt64 totalFolderUnPacked;
- for(i = 0; i < (UInt32)folderIndexes.Size(); i++, currentImportantTotalUnPacked += totalFolderUnPacked)
+ CCabBlockInStream *cabBlockInStreamSpec = new CCabBlockInStream();
+ CMyComPtr<ISequentialInStream> cabBlockInStream = cabBlockInStreamSpec;
+ if (!cabBlockInStreamSpec->Create())
+ return E_OUTOFMEMORY;
+
+ CRecordVector<bool> extractStatuses;
+ for(i = 0; i < numItems;)
{
- int folderIndex = folderIndexes[i];
- UInt16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex(
- m_Folders.Size(), folderIndex);
-
- RINOK(extractCallback->SetCompleted(&currentImportantTotalUnPacked));
- totalFolderUnPacked = 0;
- int j;
- for (j = curImportantIndexIndex; j < importantIndices.Size(); j++)
+ int index = allFilesMode ? i : indices[i];
+
+ const CMvItem &mvItem = m_Database.Items[index];
+ const CDatabaseEx &db = m_Database.Volumes[mvItem.VolumeIndex];
+ int itemIndex = mvItem.ItemIndex;
+ const CItem &item = db.Items[itemIndex];
+
+ i++;
+ if (item.IsDirectory())
{
- const CItem &fileInfo = m_Files[importantIndices[j]];
- if (fileInfo.FolderIndex != folderIndex)
+ Int32 askMode= testMode ?
+ NArchive::NExtract::NAskMode::kTest :
+ NArchive::NExtract::NAskMode::kExtract;
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
+ RINOK(extractCallback->PrepareOperation(askMode));
+ realOutStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ continue;
+ }
+ int folderIndex = m_Database.GetFolderIndex(&mvItem);
+ if (folderIndex < 0)
+ {
+ // If we need previous archive
+ Int32 askMode= testMode ?
+ NArchive::NExtract::NAskMode::kTest :
+ NArchive::NExtract::NAskMode::kExtract;
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
+ RINOK(extractCallback->PrepareOperation(askMode));
+ realOutStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ int startIndex2 = m_Database.FolderStartFileIndex[folderIndex];
+ int startIndex = startIndex2;
+ extractStatuses.Clear();
+ for (; startIndex < index; startIndex++)
+ extractStatuses.Add(false);
+ extractStatuses.Add(true);
+ startIndex++;
+ UInt64 curUnpack = item.GetEndOffset();
+ for(;i < numItems; i++)
+ {
+ int indexNext = allFilesMode ? i : indices[i];
+ const CMvItem &mvItem = m_Database.Items[indexNext];
+ const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
+ if (item.IsDirectory())
+ continue;
+ int newFolderIndex = m_Database.GetFolderIndex(&mvItem);
+
+ if (newFolderIndex != folderIndex)
break;
- totalFolderUnPacked += fileInfo.UnPackSize;
+ for (; startIndex < indexNext; startIndex++)
+ extractStatuses.Add(false);
+ extractStatuses.Add(true);
+ startIndex++;
+ curUnpack = item.GetEndOffset();
}
+
+ RINOK(extractCallback->SetCompleted(&totalUnPacked));
- CCabFolderOutStream *cabFolderOutStream = new CCabFolderOutStream;
+ CCabFolderOutStream *cabFolderOutStream = new CCabFolderOutStream;
CMyComPtr<ISequentialOutStream> outStream(cabFolderOutStream);
- const NHeader::CFolder &folder = m_Folders[realFolderIndex];
+ const CFolder &folder = db.Folders[item.GetFolderIndex(db.Folders.Size())];
- cabFolderOutStream->Init(&m_Folders, &m_Files, &importantIndices,
- &extractStatuses, curImportantIndexIndex, j - curImportantIndexIndex,
- extractCallback, currentImportantTotalUnPacked,
- folder.GetCompressionMethod() == NHeader::NCompressionMethodMajor::kQuantum?
- true: testMode);
-
- curImportantIndexIndex = j;
-
- UInt64 pos = folder.DataStart; // test it (+ archiveStart)
- RINOK(m_Stream->Seek(pos, STREAM_SEEK_SET, NULL));
-
- CLocalProgress *localProgressSpec = new CLocalProgress;
- CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
- localProgressSpec->Init(extractCallback, false);
-
- CLocalCompressProgressInfo *localCompressProgressSpec =
- new CLocalCompressProgressInfo;
- CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
- localCompressProgressSpec->Init(progress,
- NULL, &currentImportantTotalUnPacked);
-
- Byte reservedSize = m_ArchiveInfo.ReserveBlockPresent() ?
- m_ArchiveInfo.PerDataSizes.PerDatablockAreaSize : 0;
+ cabFolderOutStream->Init(&m_Database, &extractStatuses, startIndex2,
+ curUnpack, extractCallback, testMode);
+ cabBlockInStreamSpec->MsZip = false;
switch(folder.GetCompressionMethod())
{
case NHeader::NCompressionMethodMajor::kNone:
- {
- if(storeDecoderSpec == NULL)
+ if(copyCoderSpec == NULL)
{
- storeDecoderSpec = new CCopyDecoder;
- storeDecoder = storeDecoderSpec;
- }
- try
- {
- storeDecoderSpec->SetParams(reservedSize, folder.NumDataBlocks);
- RINOK(storeDecoder->Code(m_Stream, outStream,
- NULL, &totalFolderUnPacked, compressProgress));
- }
- catch(...)
- {
- RINOK(cabFolderOutStream->FlushCorrupted());
- continue;
+ copyCoderSpec = new NCompress::CCopyCoder;
+ copyCoder = copyCoderSpec;
}
break;
- }
case NHeader::NCompressionMethodMajor::kMSZip:
- {
- if(lzxDecoderSpec == NULL)
+ if(deflateDecoderSpec == NULL)
{
- msZipDecoderSpec = new NMSZip::CDecoder;
- msZipDecoder = msZipDecoderSpec;
+ deflateDecoderSpec = new NCompress::NDeflate::NDecoder::CCOMCoder;
+ deflateDecoder = deflateDecoderSpec;
}
- try
+ cabBlockInStreamSpec->MsZip = true;
+ break;
+ case NHeader::NCompressionMethodMajor::kLZX:
+ if(lzxDecoderSpec == NULL)
{
- msZipDecoderSpec->SetParams(reservedSize, folder.NumDataBlocks);
- RINOK(msZipDecoder->Code(m_Stream, outStream,
- NULL, &totalFolderUnPacked, compressProgress));
+ lzxDecoderSpec = new NCompress::NLzx::CDecoder;
+ lzxDecoder = lzxDecoderSpec;
}
- catch(...)
+ RINOK(lzxDecoderSpec->SetParams(folder.CompressionTypeMinor));
+ break;
+ case NHeader::NCompressionMethodMajor::kQuantum:
+ if(quantumDecoderSpec == NULL)
{
- RINOK(cabFolderOutStream->FlushCorrupted());
- continue;
+ quantumDecoderSpec = new NCompress::NQuantum::CDecoder;
+ quantumDecoder = quantumDecoderSpec;
}
+ quantumDecoderSpec->SetParams(folder.CompressionTypeMinor);
break;
+ default:
+ {
+ RINOK(cabFolderOutStream->Unsupported());
+ totalUnPacked += curUnpack;
+ continue;
}
- case NHeader::NCompressionMethodMajor::kLZX:
+ }
+
+ cabBlockInStreamSpec->InitForNewFolder();
+
+ HRESULT res = S_OK;
+
+ {
+ int volIndex = mvItem.VolumeIndex;
+ int locFolderIndex = item.GetFolderIndex(db.Folders.Size());
+ bool keepHistory = false;
+ bool keepInputBuffer = false;
+ for (UInt32 f = 0; cabFolderOutStream->GetRemain() != 0;)
{
- if(lzxDecoderSpec == NULL)
+ if (volIndex >= m_Database.Volumes.Size())
{
- lzxDecoderSpec = new NLZX::CDecoder;
- lzxDecoder = lzxDecoderSpec;
+ res = S_FALSE;
+ break;
}
- try
+
+ const CDatabaseEx &db = m_Database.Volumes[volIndex];
+ const CFolder &folder = db.Folders[locFolderIndex];
+ if (f == 0)
{
- lzxDecoderSpec->SetParams(reservedSize, folder.NumDataBlocks,
- folder.CompressionTypeMinor);
- RINOK(lzxDecoder->Code(m_Stream, outStream,
- NULL, &totalFolderUnPacked, compressProgress));
+ cabBlockInStreamSpec->SetStream(db.Stream);
+ cabBlockInStreamSpec->ReservedSize = db.ArchiveInfo.GetDataBlockReserveSize();
+ RINOK(db.Stream->Seek(db.StartPosition + folder.DataStart, STREAM_SEEK_SET, NULL));
}
- catch(...)
+ if (f == folder.NumDataBlocks)
{
- RINOK(cabFolderOutStream->FlushCorrupted());
+ volIndex++;
+ locFolderIndex = 0;
+ f = 0;
continue;
}
- break;
+ f++;
+
+ cabBlockInStreamSpec->DataError = false;
+
+ if (!keepInputBuffer)
+ cabBlockInStreamSpec->InitForNewBlock();
+
+ UInt32 packSize, unpackSize;
+ res = cabBlockInStreamSpec->PreRead(packSize, unpackSize);
+ if (res == S_FALSE)
+ break;
+ RINOK(res);
+ keepInputBuffer = (unpackSize == 0);
+ if (keepInputBuffer)
+ continue;
+
+
+ UInt64 totalUnPacked2 = totalUnPacked + cabFolderOutStream->GetPosInFolder();
+ RINOK(extractCallback->SetCompleted(&totalUnPacked2));
+ UInt64 unpackRemain = cabFolderOutStream->GetRemain();
+
+ const UInt32 kBlockSizeMax = (1 << 15);
+ if (unpackRemain > kBlockSizeMax)
+ unpackRemain = kBlockSizeMax;
+ if (unpackRemain > unpackSize)
+ unpackRemain = unpackSize;
+
+ switch(folder.GetCompressionMethod())
+ {
+ case NHeader::NCompressionMethodMajor::kNone:
+ res = copyCoder->Code(cabBlockInStream, outStream, NULL, &unpackRemain, NULL);
+ break;
+ case NHeader::NCompressionMethodMajor::kMSZip:
+ deflateDecoderSpec->SetKeepHistory(keepHistory);
+ res = deflateDecoder->Code(cabBlockInStream, outStream, NULL, &unpackRemain, NULL);
+ break;
+ case NHeader::NCompressionMethodMajor::kLZX:
+ lzxDecoderSpec->SetKeepHistory(keepHistory, cabBlockInStreamSpec->GetAlign());
+ res = lzxDecoder->Code(cabBlockInStream, outStream, NULL, &unpackRemain, NULL);
+ break;
+ case NHeader::NCompressionMethodMajor::kQuantum:
+ quantumDecoderSpec->SetKeepHistory(keepHistory);
+ res = quantumDecoder->Code(cabBlockInStream, outStream, NULL, &unpackRemain, NULL);
+ break;
+ }
+ if (res != S_OK)
+ {
+ if (res != S_FALSE)
+ RINOK(res);
+ break;
+ }
+ keepHistory = true;
+ }
+ if (res == S_OK)
+ {
+ RINOK(cabFolderOutStream->WriteEmptyFiles());
}
- default:
- RINOK(cabFolderOutStream->Unsupported());
- // return E_FAIL;
}
+ if (res != S_OK || cabFolderOutStream->GetRemain() != 0)
+ {
+ RINOK(cabFolderOutStream->FlushCorrupted());
+ }
+ totalUnPacked += curUnpack;
}
return S_OK;
COM_TRY_END
@@ -631,9 +807,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
COM_TRY_BEGIN
- *numItems = m_Files.Size();
+ *numItems = m_Database.Items.Size();
return S_OK;
COM_TRY_END
}
-}} \ No newline at end of file
+}}
diff --git a/7zip/Archive/Cab/CabHandler.h b/7zip/Archive/Cab/CabHandler.h
index 584dadf8..2c14d468 100755
--- a/7zip/Archive/Cab/CabHandler.h
+++ b/7zip/Archive/Cab/CabHandler.h
@@ -37,10 +37,7 @@ public:
BSTR *name, PROPID *propID, VARTYPE *varType);
private:
- CObjectVector<NHeader::CFolder> m_Folders;
- CObjectVector<CItem> m_Files;
- CInArchiveInfo m_ArchiveInfo;
- CMyComPtr<IInStream> m_Stream;
+ CMvDatabaseEx m_Database;
};
}}
diff --git a/7zip/Archive/Cab/CabHeader.h b/7zip/Archive/Cab/CabHeader.h
index 2eac96bf..5c122743 100755
--- a/7zip/Archive/Cab/CabHeader.h
+++ b/7zip/Archive/Cab/CabHeader.h
@@ -9,53 +9,15 @@ namespace NArchive {
namespace NCab {
namespace NHeader{
-namespace NArchive {
-
+namespace NArchive
+{
extern UInt32 kSignature;
-
namespace NFlags
{
const int kPrevCabinet = 0x0001;
const int kNextCabinet = 0x0002;
const int kReservePresent = 0x0004;
}
-
- const UInt32 kArchiveHeaderSize = 36;
- /*
- struct CBlock
- {
- UInt32 Signature; // cabinet file signature
- UInt32 Reserved1; // reserved
- UInt32 Size; // size of this cabinet file in bytes
- UInt32 Reserved2; // reserved
- UInt32 FileOffset; // offset of the first CFFILE entry
- UInt32 Reserved3; // reserved
- Byte VersionMinor; // cabinet file format version, minor
- Byte VersionMajor; // cabinet file format version, major
- UInt16 NumFolders; // number of CFFOLDER entries in this cabinet
- UInt16 NumFiles; // number of CFFILE entries in this cabinet
- UInt16 Flags; // cabinet file option indicators
- UInt16 SetID; // must be the same for all cabinets in a set
- UInt16 CabinetNumber; // number of this cabinet file in a set
- };
- */
-
- const UInt32 kPerDataSizesHeaderSize = 4;
-
- struct CPerDataSizes
- {
- UInt16 PerCabinetAreaSize; // (optional) size of per-cabinet reserved area
- Byte PerFolderAreaSize; // (optional) size of per-folder reserved area
- Byte PerDatablockAreaSize; // (optional) size of per-datablock reserved area
- };
-
- /*
- Byte abReserve[]; // (optional) per-cabinet reserved area
- Byte szCabinetPrev[]; // (optional) name of previous cabinet file
- Byte szDiskPrev[]; // (optional) name of previous disk
- Byte szCabinetNext[]; // (optional) name of next cabinet file
- Byte szDiskNext[]; // (optional) name of next disk
- */
}
namespace NCompressionMethodMajor
@@ -66,17 +28,6 @@ namespace NCompressionMethodMajor
const Byte kLZX = 3;
}
-const UInt32 kFolderHeaderSize = 8;
-struct CFolder
-{
- UInt32 DataStart; // offset of the first CFDATA block in this folder
- UInt16 NumDataBlocks; // number of CFDATA blocks in this folder
- Byte CompressionTypeMajor;
- Byte CompressionTypeMinor;
- // Byte abReserve[]; // (optional) per-folder reserved area
- Byte GetCompressionMethod() const { return CompressionTypeMajor & 0xF; }
-};
-
const int kFileNameIsUTFAttributeMask = 0x80;
namespace NFolderIndex
@@ -84,34 +35,8 @@ namespace NFolderIndex
const int kContinuedFromPrev = 0xFFFD;
const int kContinuedToNext = 0xFFFE;
const int kContinuedPrevAndNext = 0xFFFF;
- inline UInt16 GetRealFolderIndex(UInt16 aNumFolders, UInt16 aFolderIndex)
- {
- switch(aFolderIndex)
- {
- case kContinuedFromPrev:
- return 0;
- case kContinuedToNext:
- case kContinuedPrevAndNext:
- return aNumFolders - 1;
- default:
- return aFolderIndex;
- }
- }
}
-const UInt32 kFileHeaderSize = 16;
-/*
-struct CFile
-{
- UInt32 UnPackSize; // uncompressed size of this file in bytes
- UInt32 UnPackOffset; // uncompressed offset of this file in the folder
- UInt16 FolderIndex; // index into the CFFOLDER area
- UInt16 PureDate;
- UInt16 PureTime; // Time
- UInt16 Attributes; // attribute flags for this file
- Byte szName[]; // name of this file
-};
-*/
}}}
#endif
diff --git a/7zip/Archive/Cab/CabIn.cpp b/7zip/Archive/Cab/CabIn.cpp
index a9d40726..1d47502c 100755
--- a/7zip/Archive/Cab/CabIn.cpp
+++ b/7zip/Archive/Cab/CabIn.cpp
@@ -6,7 +6,8 @@
#include "Common/MyCom.h"
#include "CabIn.h"
#include "Windows/Defs.h"
-#include "../../Common/InBuffer.h"
+
+#include "../../Common/StreamUtils.h"
namespace NArchive{
namespace NCab{
@@ -14,7 +15,7 @@ namespace NCab{
static HRESULT ReadBytes(IInStream *inStream, void *data, UInt32 size)
{
UInt32 realProcessedSize;
- RINOK(inStream->Read(data, size, &realProcessedSize));
+ RINOK(ReadStream(inStream, data, size, &realProcessedSize));
if(realProcessedSize != size)
return S_FALSE;
return S_OK;
@@ -23,7 +24,7 @@ static HRESULT ReadBytes(IInStream *inStream, void *data, UInt32 size)
static HRESULT SafeRead(IInStream *inStream, void *data, UInt32 size)
{
UInt32 realProcessedSize;
- RINOK(inStream->Read(data, size, &realProcessedSize));
+ RINOK(ReadStream(inStream, data, size, &realProcessedSize));
if(realProcessedSize != size)
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
return S_OK;
@@ -37,25 +38,12 @@ static void SafeInByteRead(::CInBuffer &inBuffer, void *data, UInt32 size)
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
}
-static void SafeReadName(::CInBuffer &inBuffer, AString &name)
-{
- name.Empty();
- while(true)
- {
- Byte b;
- if (!inBuffer.ReadByte(b))
- throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
- if (b == 0)
- return;
- name += char(b);
- }
-}
-
Byte CInArchive::ReadByte()
{
- if (_blockPos >= _blockSize)
- throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
- return _block[_blockPos++];
+ Byte b;
+ if (!inBuffer.ReadByte(b))
+ throw CInArchiveException(CInArchiveException::kUnsupported);
+ return b;
}
UInt16 CInArchive::ReadUInt16()
@@ -80,20 +68,38 @@ UInt32 CInArchive::ReadUInt32()
return value;
}
-HRESULT CInArchive::Open(IInStream *inStream,
- const UInt64 *searchHeaderSizeLimit,
- CInArchiveInfo &inArchiveInfo,
- CObjectVector<NHeader::CFolder> &folders,
- CObjectVector<CItem> &files,
- CProgressVirt *progressVirt)
+AString CInArchive::SafeReadName()
{
- UInt64 startPosition;
- RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &startPosition));
+ AString name;
+ while(true)
+ {
+ Byte b = ReadByte();
+ if (b == 0)
+ return name;
+ name += (char)b;
+ }
+}
- // NHeader::NArchive::CBlock archiveHeader;
+void CInArchive::ReadOtherArchive(COtherArchive &oa)
+{
+ oa.FileName = SafeReadName();
+ oa.DiskName = SafeReadName();
+}
+
+void CInArchive::Skeep(size_t size)
+{
+ while (size-- != 0)
+ ReadByte();
+}
+
+HRESULT CInArchive::Open2(IInStream *inStream,
+ const UInt64 *searchHeaderSizeLimit,
+ CDatabase &database)
+{
+ database.Clear();
+ RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &database.StartPosition));
{
- ::CInBuffer inBuffer;
if (!inBuffer.Create(1 << 17))
return E_OUTOFMEMORY;
inBuffer.SetStream(inStream);
@@ -117,141 +123,219 @@ HRESULT CInArchive::Open(IInStream *inStream,
return S_FALSE;
}
}
- startPosition += inBuffer.GetProcessedSize() - kSignatureSize;
+ database.StartPosition += inBuffer.GetProcessedSize() - kSignatureSize;
}
- RINOK(inStream->Seek(startPosition, STREAM_SEEK_SET, NULL));
-
- RINOK(ReadBytes(inStream, _block, NHeader::NArchive::kArchiveHeaderSize));
- _blockSize = NHeader::NArchive::kArchiveHeaderSize;
- _blockPos = 0;
-
- ReadUInt32(); // Signature; // cabinet file signature
- // if (archiveHeader.Signature != NHeader::NArchive::kSignature)
- // return S_FALSE;
-
- UInt32 reserved1 = ReadUInt32();
- UInt32 size = ReadUInt32(); // size of this cabinet file in bytes
- UInt32 reserved2 = ReadUInt32();
- UInt32 fileOffset = ReadUInt32(); // offset of the first CFFILE entry
- UInt32 reserved3 = ReadUInt32();
-
- inArchiveInfo.VersionMinor = ReadByte(); // cabinet file format version, minor
- inArchiveInfo.VersionMajor = ReadByte(); // cabinet file format version, major
- inArchiveInfo.NumFolders = ReadUInt16(); // number of CFFOLDER entries in this cabinet
- inArchiveInfo.NumFiles = ReadUInt16(); // number of CFFILE entries in this cabinet
- inArchiveInfo.Flags = ReadUInt16(); // number of CFFILE entries in this cabinet
- UInt16 setID = ReadUInt16(); // must be the same for all cabinets in a set
- UInt16 cabinetNumber = ReadUInt16(); // number of this cabinet file in a set
-
- if (reserved1 != 0 || reserved2 != 0 || reserved3 != 0)
- throw CInArchiveException(CInArchiveException::kUnsupported);
- if (inArchiveInfo.ReserveBlockPresent())
+ CInArchiveInfo &archiveInfo = database.ArchiveInfo;
+
+ archiveInfo.Size = ReadUInt32(); // size of this cabinet file in bytes
+ if (ReadUInt32() != 0)
+ return S_FALSE;
+ archiveInfo.FileHeadersOffset = ReadUInt32(); // offset of the first CFFILE entry
+ if (ReadUInt32() != 0)
+ return S_FALSE;
+
+ archiveInfo.VersionMinor = ReadByte(); // cabinet file format version, minor
+ archiveInfo.VersionMajor = ReadByte(); // cabinet file format version, major
+ archiveInfo.NumFolders = ReadUInt16(); // number of CFFOLDER entries in this cabinet
+ archiveInfo.NumFiles = ReadUInt16(); // number of CFFILE entries in this cabinet
+ archiveInfo.Flags = ReadUInt16(); // number of CFFILE entries in this cabinet
+ archiveInfo.SetID = ReadUInt16(); // must be the same for all cabinets in a set
+ archiveInfo.CabinetNumber = ReadUInt16(); // number of this cabinet file in a set
+
+ if (archiveInfo.ReserveBlockPresent())
{
- RINOK(SafeRead(inStream, _block, NHeader::NArchive::kPerDataSizesHeaderSize));
- _blockSize = NHeader::NArchive::kPerDataSizesHeaderSize;
- _blockPos = 0;
-
- inArchiveInfo.PerDataSizes.PerCabinetAreaSize = ReadUInt16(); // (optional) size of per-cabinet reserved area
- inArchiveInfo.PerDataSizes.PerFolderAreaSize = ReadByte(); // (optional) size of per-folder reserved area
- inArchiveInfo.PerDataSizes.PerDatablockAreaSize = ReadByte(); // (optional) size of per-datablock reserved area
- RINOK(inStream->Seek(inArchiveInfo.PerDataSizes.PerCabinetAreaSize,
- STREAM_SEEK_CUR, NULL));
+ archiveInfo.PerCabinetAreaSize = ReadUInt16(); // (optional) size of per-cabinet reserved area
+ archiveInfo.PerFolderAreaSize = ReadByte(); // (optional) size of per-folder reserved area
+ archiveInfo.PerDataBlockAreaSize = ReadByte(); // (optional) size of per-datablock reserved area
+
+ Skeep(archiveInfo.PerCabinetAreaSize);
}
{
- UInt64 foldersStartPosition;
- RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &foldersStartPosition));
- ::CInBuffer inBuffer;
- if (!inBuffer.Create(1 << 17))
- return E_OUTOFMEMORY;
- inBuffer.SetStream(inStream);
- inBuffer.Init();
- if ((inArchiveInfo.Flags & NHeader::NArchive::NFlags::kPrevCabinet) != 0)
- {
- SafeReadName(inBuffer, inArchiveInfo.PreviousCabinetName);
- SafeReadName(inBuffer, inArchiveInfo.PreviousDiskName);
- }
- if ((inArchiveInfo.Flags & NHeader::NArchive::NFlags::kNextCabinet) != 0)
- {
- SafeReadName(inBuffer, inArchiveInfo.NextCabinetName);
- SafeReadName(inBuffer, inArchiveInfo.NextDiskName);
- }
- foldersStartPosition += inBuffer.GetProcessedSize();
- RINOK(inStream->Seek(foldersStartPosition, STREAM_SEEK_SET, NULL));
+ if (archiveInfo.IsTherePrev())
+ ReadOtherArchive(archiveInfo.PreviousArchive);
+ if (archiveInfo.IsThereNext())
+ ReadOtherArchive(archiveInfo.NextArchive);
}
- if (progressVirt != NULL)
- {
- UInt64 numFiles = inArchiveInfo.NumFiles;
- RINOK(progressVirt->SetTotal(&numFiles));
- }
- folders.Clear();
int i;
- for(i = 0; i < inArchiveInfo.NumFolders; i++)
+ for(i = 0; i < archiveInfo.NumFolders; i++)
{
- if (progressVirt != NULL)
- {
- UInt64 numFiles = 0;
- RINOK(progressVirt->SetCompleted(&numFiles));
- }
- NHeader::CFolder folder;
- RINOK(SafeRead(inStream, _block, NHeader::kFolderHeaderSize));
- _blockSize = NHeader::kFolderHeaderSize;
- _blockPos = 0;
+ CFolder folder;
folder.DataStart = ReadUInt32();
folder.NumDataBlocks = ReadUInt16();
folder.CompressionTypeMajor = ReadByte();
folder.CompressionTypeMinor = ReadByte();
- if (inArchiveInfo.ReserveBlockPresent())
- {
- RINOK(inStream->Seek(
- inArchiveInfo.PerDataSizes.PerFolderAreaSize, STREAM_SEEK_CUR, NULL));
- }
- folder.DataStart += (UInt32)startPosition;
- folders.Add(folder);
+ Skeep(archiveInfo.PerFolderAreaSize);
+ database.Folders.Add(folder);
}
- RINOK(inStream->Seek(startPosition + fileOffset,
- STREAM_SEEK_SET, NULL));
+ RINOK(inStream->Seek(database.StartPosition + archiveInfo.FileHeadersOffset, STREAM_SEEK_SET, NULL));
- ::CInBuffer inBuffer;
- if (!inBuffer.Create(1 << 17))
- return E_OUTOFMEMORY;
inBuffer.SetStream(inStream);
inBuffer.Init();
- files.Clear();
- if (progressVirt != NULL)
- {
- UInt64 numFiles = files.Size();
- RINOK(progressVirt->SetCompleted(&numFiles));
- }
- for(i = 0; i < inArchiveInfo.NumFiles; i++)
+ for(i = 0; i < archiveInfo.NumFiles; i++)
{
- SafeInByteRead(inBuffer, _block, NHeader::kFileHeaderSize);
- _blockSize = NHeader::kFileHeaderSize;
- _blockPos = 0;
CItem item;
- item.UnPackSize = ReadUInt32();
- item.UnPackOffset = ReadUInt32();
+ item.Size = ReadUInt32();
+ item.Offset = ReadUInt32();
item.FolderIndex = ReadUInt16();
- if (item.FolderIndex > inArchiveInfo.NumFolders)
- return S_FALSE;
UInt16 pureDate = ReadUInt16();
UInt16 pureTime = ReadUInt16();
item.Time = ((UInt32(pureDate) << 16)) | pureTime;
item.Attributes = ReadUInt16();
- SafeReadName(inBuffer, item.Name);
- files.Add(item);
- if (progressVirt != NULL)
+ item.Name = SafeReadName();
+ int folderIndex = item.GetFolderIndex(database.Folders.Size());
+ if (folderIndex >= database.Folders.Size())
+ return S_FALSE;
+ database.Items.Add(item);
+ }
+ return S_OK;
+}
+
+#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
+
+HRESULT CInArchive::Open(
+ const UInt64 *searchHeaderSizeLimit,
+ CDatabaseEx &database)
+{
+ return Open2(database.Stream, searchHeaderSizeLimit, database);
+}
+
+
+static int CompareMvItems2(const CMvItem *p1, const CMvItem *p2)
+{
+ RINOZ(MyCompare(p1->VolumeIndex, p2->VolumeIndex));
+ return MyCompare(p1->ItemIndex, p2->ItemIndex);
+}
+
+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.IsDirectory();
+ bool isDir2 = item2.IsDirectory();
+ 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));
+ return CompareMvItems2(p1, p2);
+}
+
+bool CMvDatabaseEx::AreItemsEqual(int i1, int 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];;
+ int f1 = GetFolderIndex(p1);
+ int f2 = GetFolderIndex(p2);
+ if (f1 != f2)
+ return false;
+ if (item1.Offset != item2.Offset)
+ return false;
+ if (item1.Size != item2.Size)
+ return false;
+
+ return true;
+}
+
+void CMvDatabaseEx::FillSortAndShrink()
+{
+ Items.Clear();
+ StartFolderOfVol.Clear();
+ FolderStartFileIndex.Clear();
+ int offset = 0;
+ for (int v = 0; v < Volumes.Size(); v++)
+ {
+ const CDatabaseEx &db = Volumes[v];
+ int curOffset = offset;
+ if (db.IsTherePrevFolder())
+ curOffset--;
+ StartFolderOfVol.Add(curOffset);
+ offset += db.GetNumberOfNewFolders();
+
+ CMvItem mvItem;
+ mvItem.VolumeIndex = v;
+ for (int i = 0 ; i < db.Items.Size(); i++)
{
- UInt64 numFiles = files.Size();
- RINOK(progressVirt->SetCompleted(&numFiles));
+ mvItem.ItemIndex = i;
+ Items.Add(mvItem);
}
}
- return S_OK;
+
+ Items.Sort(CompareMvItems, (void *)this);
+ int j = 1;
+ int i;
+ for (i = 1; i < Items.Size(); i++)
+ if (!AreItemsEqual(i, i -1))
+ Items[j++] = Items[i];
+ Items.DeleteFrom(j);
+
+ for (i = 0; i < Items.Size(); i++)
+ {
+ const CMvItem &mvItem = Items[i];
+ int folderIndex = GetFolderIndex(&mvItem);
+ if (folderIndex >= FolderStartFileIndex.Size())
+ FolderStartFileIndex.Add(i);
+ }
+}
+
+bool CMvDatabaseEx::Check()
+{
+ for (int 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.CompressionTypeMajor != f1.CompressionTypeMajor ||
+ f0.CompressionTypeMinor != f1.CompressionTypeMinor)
+ return false;
+ }
+ }
+ UInt64 maxPos = 0;
+ int prevFolder = -2;
+ for(int i = 0; i < Items.Size(); i++)
+ {
+ const CMvItem &mvItem = Items[i];
+ int fIndex = GetFolderIndex(&mvItem);
+ if (fIndex >= FolderStartFileIndex.Size())
+ return false;
+ const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
+ if (item.IsDirectory())
+ continue;
+ int folderIndex = GetFolderIndex(&mvItem);
+ if (folderIndex != prevFolder)
+ {
+ prevFolder = folderIndex;
+ maxPos = 0;
+ continue;
+ }
+ if (item.Offset < maxPos)
+ return false;
+ maxPos = item.GetEndOffset();
+ if (maxPos < item.Offset)
+ return false;
+ }
+ return true;
}
}}
diff --git a/7zip/Archive/Cab/CabIn.h b/7zip/Archive/Cab/CabIn.h
index 82a9ea0d..4e817e94 100755
--- a/7zip/Archive/Cab/CabIn.h
+++ b/7zip/Archive/Cab/CabIn.h
@@ -4,6 +4,7 @@
#define __ARCHIVE_CAB_IN_H
#include "../../IStream.h"
+#include "../../Common/InBuffer.h"
#include "CabHeader.h"
#include "CabItem.h"
@@ -22,10 +23,14 @@ public:
CInArchiveException(CCauseType cause) : Cause(cause) {}
};
-class CInArchiveInfo
+struct COtherArchive
+{
+ AString FileName;
+ AString DiskName;
+};
+
+struct CArchiveInfo
{
-public:
- UInt32 Size; /* size of this cabinet file in bytes */
Byte VersionMinor; /* cabinet file format version, minor */
Byte VersionMajor; /* cabinet file format version, major */
UInt16 NumFolders; /* number of CFFOLDER entries in this cabinet */
@@ -35,39 +40,125 @@ public:
UInt16 CabinetNumber; /* number of this cabinet file in a set */
bool ReserveBlockPresent() const { return (Flags & NHeader::NArchive::NFlags::kReservePresent) != 0; }
- NHeader::NArchive::CPerDataSizes PerDataSizes;
- AString PreviousCabinetName;
- AString PreviousDiskName;
- AString NextCabinetName;
- AString NextDiskName;
+ bool IsTherePrev() const { return (Flags & NHeader::NArchive::NFlags::kPrevCabinet) != 0; }
+ bool IsThereNext() const { return (Flags & NHeader::NArchive::NFlags::kNextCabinet) != 0; }
+
+ UInt16 PerCabinetAreaSize; // (optional) size of per-cabinet reserved area
+ Byte PerFolderAreaSize; // (optional) size of per-folder reserved area
+ Byte PerDataBlockAreaSize; // (optional) size of per-datablock reserved area
+
+ Byte GetDataBlockReserveSize() const { return (Byte)(ReserveBlockPresent() ? PerDataBlockAreaSize : 0); }
+
+ COtherArchive PreviousArchive;
+ COtherArchive NextArchive;
+
+ CArchiveInfo()
+ {
+ Clear();
+ }
+
+ void Clear()
+ {
+ PerCabinetAreaSize = 0;
+ PerFolderAreaSize = 0;
+ PerDataBlockAreaSize = 0;
+ }
+};
+
+struct CInArchiveInfo: public CArchiveInfo
+{
+ UInt32 Size; /* size of this cabinet file in bytes */
+ UInt32 FileHeadersOffset; //offset of the first CFFILE entry
+};
+
+
+class CDatabase
+{
+public:
+ UInt64 StartPosition;
+ CInArchiveInfo ArchiveInfo;
+ CObjectVector<CFolder> Folders;
+ CObjectVector<CItem> Items;
+ void Clear()
+ {
+ ArchiveInfo.Clear();
+ Folders.Clear();
+ Items.Clear();
+ }
+ bool IsTherePrevFolder() const
+ {
+ for (int i = 0; i < Items.Size(); i++)
+ if (Items[i].ContinuedFromPrev())
+ return true;
+ return false;
+ }
+ int GetNumberOfNewFolders() const
+ {
+ int res = Folders.Size();
+ if (IsTherePrevFolder())
+ res--;
+ return res;
+ }
+ UInt32 GetFileOffset(int index) const { return Items[index].Offset; }
+ UInt32 GetFileSize(int index) const { return Items[index].Size; }
};
-class CProgressVirt
+class CDatabaseEx: public CDatabase
{
public:
- STDMETHOD(SetTotal)(const UInt64 *numFiles) PURE;
- STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE;
+ CMyComPtr<IInStream> Stream;
+};
+
+struct CMvItem
+{
+ int VolumeIndex;
+ int ItemIndex;
};
-const UInt32 kMaxBlockSize = NHeader::NArchive::kArchiveHeaderSize;
+class CMvDatabaseEx
+{
+ bool AreItemsEqual(int i1, int i2);
+public:
+ CObjectVector<CDatabaseEx> Volumes;
+ CRecordVector<CMvItem> Items;
+ CRecordVector<int> StartFolderOfVol;
+ CRecordVector<int> 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
{
- UInt16 _blockSize;
- Byte _block[kMaxBlockSize];
- UInt32 _blockPos;
+ CInBuffer inBuffer;
Byte ReadByte();
UInt16 ReadUInt16();
UInt32 ReadUInt32();
+ AString SafeReadName();
+ void Skeep(size_t size);
+ void ReadOtherArchive(COtherArchive &oa);
+
+ HRESULT Open2(IInStream *inStream,
+ const UInt64 *searchHeaderSizeLimit,
+ CDatabase &database);
public:
- HRESULT Open(IInStream *inStream,
+ HRESULT Open(
const UInt64 *searchHeaderSizeLimit,
- CInArchiveInfo &inArchiveInfo,
- CObjectVector<NHeader::CFolder> &folders,
- CObjectVector<CItem> &files,
- CProgressVirt *progressVirt);
+ CDatabaseEx &database);
};
}}
diff --git a/7zip/Archive/Cab/CabInBuffer.cpp b/7zip/Archive/Cab/CabInBuffer.cpp
deleted file mode 100755
index c429033c..00000000
--- a/7zip/Archive/Cab/CabInBuffer.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-// Archive/CabInBuffer.cpp
-
-#include "StdAfx.h"
-
-#include "../../../Common/Alloc.h"
-#include "../../../Common/MyCom.h"
-#include "../../../Windows/Defs.h"
-#include "CabInBuffer.h"
-
-namespace NArchive {
-namespace NCab {
-
-static const UInt32 kDataBlockHeaderSize = 8;
-/*
-struct CDataBlockHeader
-{
- UInt32 CheckSum; // checksum of this CFDATA entry
- UInt16 PackSize; // number of compressed bytes in this block
- UInt16 UnPackSize; // number of uncompressed bytes in this block
- // Byte abReserve[]; // (optional) per-datablock reserved area
- // Byte ab[cbData]; // compressed data bytes
-};
-*/
-
-class CTempCabInBuffer
-{
-public:
- Byte *Buffer;
- UInt32 Size;
- UInt32 Pos;
- Byte ReadByte()
- {
- if (Pos >= Size)
- throw "overflow";
- return Buffer[Pos++];
- }
- UInt32 ReadUInt32()
- {
- UInt32 value = 0;
- for (int i = 0; i < 4; i++)
- value |= (((UInt32)ReadByte()) << (8 * i));
- return value;
- }
- UInt16 ReadUInt16()
- {
- UInt16 value = 0;
- for (int i = 0; i < 2; i++)
- value |= (((UInt16)ReadByte()) << (8 * i));
- return value;
- }
-};
-
-bool CInBuffer::Create(UInt32 bufferSize)
-{
- const UInt32 kMinBlockSize = 1;
- if (bufferSize < kMinBlockSize)
- bufferSize = kMinBlockSize;
- if (m_Buffer != 0 && m_BufferSize == bufferSize)
- return true;
- Free();
- m_BufferSize = bufferSize;
- m_Buffer = (Byte *)::BigAlloc(bufferSize);
- return (m_Buffer != 0);
-}
-
-void CInBuffer::Free()
-{
- BigFree(m_Buffer);
- m_Buffer = 0;
-}
-
-void CInBuffer::Init(Byte reservedSize, UInt32 numBlocks)
-{
- m_ReservedSize = reservedSize;
- m_NumBlocks = numBlocks;
- m_CurrentBlockIndex = 0;
- m_ProcessedSize = 0;
- m_Pos = 0;
- m_NumReadBytesInBuffer = 0;
-}
-
-class CCheckSum
-{
- UInt32 m_Value;
-public:
- CCheckSum(): m_Value(0){};
- void Init() { m_Value = 0; }
- void Update(const void *data, UInt32 size);
- void UpdateUInt32(UInt32 v) { m_Value ^= v; }
- UInt32 GetResult() const { return m_Value; }
-};
-
-void CCheckSum::Update(const void *data, UInt32 size)
-{
- UInt32 checkSum = m_Value;
- const Byte *dataPointer = (const Byte *)data;
- int numUINT32Words = size / 4; // Number of ULONGs
-
- UInt32 temp;
- while (numUINT32Words-- > 0)
- {
- temp = *dataPointer++;
- temp |= (((UInt32)(*dataPointer++)) << 8);
- temp |= (((UInt32)(*dataPointer++)) << 16);
- temp |= (((UInt32)(*dataPointer++)) << 24);
- checkSum ^= temp;
- }
-
- temp = 0;
- int rem = (size & 3);
- if (rem >= 3)
- temp |= (((UInt32)(*dataPointer++)) << 16);
- if (rem >= 2)
- temp |= (((UInt32)(*dataPointer++)) << 8);
- if (rem >= 1)
- temp |= *dataPointer++;
- checkSum ^= temp;
- m_Value = checkSum;
-}
-
-HRESULT CInBuffer::ReadBlock(UInt32 &uncompressedSize, bool &dataAreCorrect)
-{
- if (m_CurrentBlockIndex >= m_NumBlocks)
- throw "there is no more data blocks";
-
- m_ProcessedSize += m_NumReadBytesInBuffer;
-
- Byte buffer[kDataBlockHeaderSize];
- UInt32 numProcessedBytes;
- RINOK(m_Stream->Read(buffer, kDataBlockHeaderSize, &numProcessedBytes));
- if (numProcessedBytes != kDataBlockHeaderSize)
- throw "bad block";
-
- CTempCabInBuffer inBuffer;
- inBuffer.Size = kDataBlockHeaderSize;
- inBuffer.Buffer = (Byte *)buffer;
- inBuffer.Pos = 0;
-
- UInt32 checkSum = inBuffer.ReadUInt32(); // checksum of this CFDATA entry
- UInt16 packSize = inBuffer.ReadUInt16(); // number of compressed bytes in this block
- UInt16 unPackSize = inBuffer.ReadUInt16(); // number of uncompressed bytes in this block
-
- if (m_ReservedSize != 0)
- {
- Byte reservedArea[256];
- RINOK(m_Stream->Read(reservedArea, m_ReservedSize, &numProcessedBytes));
- if (numProcessedBytes != m_ReservedSize)
- throw "bad block";
- }
-
- RINOK(m_Stream->Read(m_Buffer, packSize, &m_NumReadBytesInBuffer));
- if (m_NumReadBytesInBuffer != packSize)
- throw "bad block";
-
- // Cab specification:
- // checkSum: May be set to zero if the checksum is not supplied.
- // but seems it's stupid rule.
- if (checkSum == 0)
- dataAreCorrect = true;
- else
- {
- CCheckSum checkSumCalc;
- checkSumCalc.Update(m_Buffer, packSize);
- checkSumCalc.UpdateUInt32(packSize | (((UInt32)unPackSize) << 16));
- dataAreCorrect = (checkSumCalc.GetResult() == checkSum);
- }
-
- m_Pos = 0;
- uncompressedSize = unPackSize;
-
- m_CurrentBlockIndex++;
- return S_OK;
-}
-
-}}
diff --git a/7zip/Archive/Cab/CabInBuffer.h b/7zip/Archive/Cab/CabInBuffer.h
deleted file mode 100755
index 1b94f77f..00000000
--- a/7zip/Archive/Cab/CabInBuffer.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Archive/CabInBuffer.h
-
-#ifndef __ARCHIVE_CAB_INBUFFER_H
-#define __ARCHIVE_CAB_INBUFFER_H
-
-#include "../../IStream.h"
-#include "../../../Common/MyCom.h"
-
-namespace NArchive {
-namespace NCab {
-
-class CInBuffer
-{
- UInt64 m_ProcessedSize;
- UInt32 m_Pos;
- UInt32 m_NumReadBytesInBuffer;
- Byte *m_Buffer;
- CMyComPtr<ISequentialInStream> m_Stream;
- UInt32 m_BufferSize;
-
- UInt32 m_NumBlocks;
- UInt32 m_CurrentBlockIndex;
- UInt32 m_ReservedSize;
-
-public:
- CInBuffer(): m_Buffer(0) {}
- ~CInBuffer() { Free(); }
- bool Create(UInt32 bufferSize);
- void Free();
-
- void SetStream(ISequentialInStream *inStream) { m_Stream = inStream; }
- void ReleaseStream() { m_Stream.Release(); }
-
- void Init(Byte reservedSize, UInt32 numBlocks);
- void Init() {}
-
- bool ReadByte(Byte &b)
- {
- if(m_Pos >= m_NumReadBytesInBuffer)
- return false;
- b = m_Buffer[m_Pos++];
- return true;
- }
- Byte ReadByte()
- {
- if(m_Pos >= m_NumReadBytesInBuffer)
- return 0;
- return m_Buffer[m_Pos++];
- }
- /*
- void ReadBytes(void *data, UInt32 size, UInt32 &aProcessedSize)
- {
- Byte *aDataPointer = (Byte *)data;
- for(int i = 0; i < size; i++)
- if (!ReadByte(aDataPointer[i]))
- break;
- aProcessedSize = i;
- }
- */
- HRESULT ReadBlock(UInt32 &uncompressedSize, bool &dataAreCorrect);
- UInt64 GetProcessedSize() const { return m_ProcessedSize + m_Pos; }
-};
-
-}}
-
-#endif
diff --git a/7zip/Archive/Cab/CabItem.h b/7zip/Archive/Cab/CabItem.h
index b1ebeb60..d8b56325 100755
--- a/7zip/Archive/Cab/CabItem.h
+++ b/7zip/Archive/Cab/CabItem.h
@@ -1,7 +1,7 @@
-// Archive/Cab/ItemInfo.h
+// Archive/CabItem.h
-#ifndef __ARCHIVE_RAR_ITEMINFO_H
-#define __ARCHIVE_RAR_ITEMINFO_H
+#ifndef __ARCHIVE_CAB_ITEM_H
+#define __ARCHIVE_CAB_ITEM_H
#include "Common/Types.h"
#include "Common/String.h"
@@ -10,23 +10,53 @@
namespace NArchive {
namespace NCab {
+struct CFolder
+{
+ UInt32 DataStart; // offset of the first CFDATA block in this folder
+ UInt16 NumDataBlocks; // number of CFDATA blocks in this folder
+ Byte CompressionTypeMajor;
+ Byte CompressionTypeMinor;
+ Byte GetCompressionMethod() const { return (Byte)(CompressionTypeMajor & 0xF); }
+};
+
class CItem
{
public:
- UInt16 Flags;
- UInt64 UnPackSize;
- UInt32 UnPackOffset;
- UInt16 FolderIndex;
+ AString Name;
+ UInt32 Offset;
+ UInt32 Size;
UInt32 Time;
- UInt16 Attributes;
- UInt32 GetWinAttributes() const { return Attributes & (Attributes & ~NHeader::kFileNameIsUTFAttributeMask); }
+ UInt16 FolderIndex;
+ UInt16 Flags;
+ UInt16 Attributes;
+ UInt64 GetEndOffset() const { return (UInt64)Offset + Size; }
+ UInt32 GetWinAttributes() const { return (Attributes & ~NHeader::kFileNameIsUTFAttributeMask); }
bool IsNameUTF() const { return (Attributes & NHeader::kFileNameIsUTFAttributeMask) != 0; }
bool IsDirectory() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; }
- AString Name;
+
+ 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(int numFolders) const
+ {
+ if (ContinuedFromPrev())
+ return 0;
+ if (ContinuedToNext())
+ return (numFolders - 1);
+ return FolderIndex;
+ }
};
}}
#endif
-
-
diff --git a/7zip/Archive/Cab/DllExports.cpp b/7zip/Archive/Cab/DllExports.cpp
index b92504fd..fa17f10b 100755
--- a/7zip/Archive/Cab/DllExports.cpp
+++ b/7zip/Archive/Cab/DllExports.cpp
@@ -8,12 +8,12 @@
#include "CabHandler.h"
#include "../../ICoder.h"
-// {23170F69-40C1-278A-1000-000110060000}
+// {23170F69-40C1-278A-1000-000110080000}
DEFINE_GUID(CLSID_CCabHandler,
- 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x06, 0x00, 0x00);
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x08, 0x00, 0x00);
extern "C"
-BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID)
{
return TRUE;
}
diff --git a/7zip/Archive/Cab/LZXBitDecoder.h b/7zip/Archive/Cab/LZXBitDecoder.h
deleted file mode 100755
index 51737135..00000000
--- a/7zip/Archive/Cab/LZXBitDecoder.h
+++ /dev/null
@@ -1,111 +0,0 @@
-// Archive/Cab/LZXBitDecoder.h
-
-#ifndef __ARCHIVE_CAB_LZXBITDECODER_H
-#define __ARCHIVE_CAB_LZXBITDECODER_H
-
-#include "CabInBuffer.h"
-
-namespace NArchive {
-namespace NCab {
-namespace NLZX {
-namespace NBitStream {
-
-const int kNumBigValueBits = 8 * 4;
-
-const int kNumValueBits = 17;
-const int kBitDecoderValueMask = (1 << kNumValueBits) - 1;
-
-class CDecoder
-{
-protected:
- CInBuffer m_Stream;
- UInt32 m_BitPos;
- UInt32 m_Value;
-public:
- bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }
- void SetStream(ISequentialInStream *s) { m_Stream.SetStream(s); }
- void ReleaseStream() { m_Stream.ReleaseStream(); }
- void Init(Byte reservedSize, UInt32 numBlocks)
- {
- m_Stream.Init(reservedSize, numBlocks);
- }
- UInt64 GetProcessedSize() const
- { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; }
- UInt32 GetBitPosition() const
- { return UInt32(m_Stream.GetProcessedSize() * 8 - (kNumBigValueBits - m_BitPos)); }
-
- void Init()
- {
- m_BitPos = kNumBigValueBits;
- Normalize();
- }
-
- void Normalize()
- {
- for (;m_BitPos >= 16; m_BitPos -= 16)
- {
- Byte b0 = m_Stream.ReadByte();
- Byte b1 = m_Stream.ReadByte();
- m_Value = (m_Value << 8) | b1;
- m_Value = (m_Value << 8) | b0;
- }
- }
-
- UInt32 GetValue(UInt32 numBits)
- {
- return ((m_Value >> ((32 - kNumValueBits) - m_BitPos)) & kBitDecoderValueMask) >>
- (kNumValueBits - numBits);
- }
-
- void MovePos(UInt32 numBits)
- {
- m_BitPos += numBits;
- Normalize();
- }
-
- UInt32 ReadBits(UInt32 numBits)
- {
- UInt32 res = GetValue(numBits);
- MovePos(numBits);
- return res;
- }
- UInt32 ReadBitsBig(UInt32 numBits)
- {
- UInt32 numBits0 = numBits / 2;
- UInt32 numBits1 = numBits - numBits0;
- UInt32 res = ReadBits(numBits0) << numBits1;
- return res + ReadBits(numBits1);
- }
-
- Byte DirectReadByte()
- {
- if (m_BitPos == kNumBigValueBits)
- return m_Stream.ReadByte();
- Byte res;
- switch(m_BitPos)
- {
- case 0:
- res = Byte(m_Value >> 16);
- break;
- case 8:
- res = Byte(m_Value >> 24);
- break;
- case 16:
- res = Byte(m_Value);
- break;
- case 24:
- res = Byte(m_Value >> 8);
- break;
- }
- m_BitPos += 8;
- return res;
- }
-
- HRESULT ReadBlock(UInt32 &uncompressedSize, bool &dataAreCorrect)
- { return m_Stream.ReadBlock(uncompressedSize, dataAreCorrect); }
-};
-
-
-}}}}
-
-#endif
diff --git a/7zip/Archive/Cab/LZXConst.h b/7zip/Archive/Cab/LZXConst.h
deleted file mode 100755
index f4648024..00000000
--- a/7zip/Archive/Cab/LZXConst.h
+++ /dev/null
@@ -1,110 +0,0 @@
-// Archive/Cab/LZXConst.h
-
-#ifndef __ARCHIVE_CAB_LZXCONST_H
-#define __ARCHIVE_CAB_LZXCONST_H
-
-#include "LZXExtConst.h"
-
-namespace NArchive {
-namespace NCab {
-namespace NLZX {
-
-namespace NBlockType
-{
- const int kNumBits = 3;
- enum EEnum
- {
- kVerbatim = 1,
- kAligned = 2,
- kUncompressed = 3
- };
-}
-
-const int kUncompressedBlockSizeNumBits = 24;
-
-const UInt32 kLevelTableSize = 20;
-
-const UInt32 kNumBitsForPreTreeLevel = 4;
-
-const int kLevelSymbolZeros = 17;
-const int kLevelSymbolZerosBig = 18;
-const int kLevelSymbolSame = 19;
-
-const int kLevelSymbolZerosStartValue = 4;
-const int kLevelSymbolZerosNumBits = 4;
-
-const int kLevelSymbolZerosBigStartValue = kLevelSymbolZerosStartValue +
- (1 << kLevelSymbolZerosNumBits);
-const int kLevelSymbolZerosBigNumBits = 5;
-
-const int kNumBitsForAlignLevel = 3;
-
-const int kLevelSymbolSameNumBits = 1;
-const int kLevelSymbolSameStartValue = 4;
-
-// const UInt32 kMainTableSize = 256 + kNumPosLenSlots + 1;
-
-/*
-const UInt32 kLenTableSize = 28;
-
-const UInt32 kLenTableStart = kMainTableSize;
-const UInt32 kAlignTableStart = kLenTableStart + kLenTableSize;
-
-const UInt32 kHeapTablesSizesSum = kMainTableSize + kLenTableSize + kAlignTableSize;
-
-
-const UInt32 kMaxTableSize = kHeapTablesSizesSum;
-
-const UInt32 kTableDirectLevels = 16;
-const UInt32 kTableLevelRepNumber = kTableDirectLevels;
-const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1;
-const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1;
-
-const UInt32 kLevelMask = 0xF;
-
-const UInt32 kPosLenNumber = 256;
-const UInt32 kReadTableNumber = 256 + kNumPosLenSlots;
-
-//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[] =
-{ 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,65536,98304,131072,196608,
- 0x40000,
- 0x60000,
- 0x80000,
- 0xA0000,
- 0xC0000,
- 0xE0000,
-
- 0x100000,
- 0x120000,
- 0x140000,
- 0x160000,
- 0x180000,
- 0x1A0000,
- 0x1C0000,
- 0x1E0000
-};
-const Byte kDistDirectBits[] =
-{
- 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,
- 17, 17, 17, 17, 17, 17,
- 17, 17,17, 17, 17, 17, 17, 17
-};
-
-/*
-const Byte kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7};
-
-const UInt32 kDistLimit2 = 0x101 - 1;
-*/
-
-}}}
-
-#endif
diff --git a/7zip/Archive/Cab/LZXDecoder.cpp b/7zip/Archive/Cab/LZXDecoder.cpp
deleted file mode 100755
index 49f87ed7..00000000
--- a/7zip/Archive/Cab/LZXDecoder.cpp
+++ /dev/null
@@ -1,310 +0,0 @@
-// Archive/Cab/LZXDecoder.cpp
-
-#include "StdAfx.h"
-
-#include "LZXDecoder.h"
-
-#include "Common/Defs.h"
-#include "Windows/Defs.h"
-
-namespace NArchive {
-namespace NCab {
-namespace NLZX {
-
-static const UInt32 kHistorySize = (1 << 21);
-
-CDecoder::CDecoder()
-{
- m_i86TranslationOutStreamSpec = new Ci86TranslationOutStream;
- m_i86TranslationOutStream = m_i86TranslationOutStreamSpec;
-}
-
-void CDecoder::ReleaseStreams()
-{
- m_OutWindowStream.ReleaseStream();
- m_InBitStream.ReleaseStream();
- m_i86TranslationOutStreamSpec->ReleaseStream();
-}
-
-STDMETHODIMP CDecoder::Flush()
-{
- RINOK(m_OutWindowStream.Flush());
- return m_i86TranslationOutStreamSpec->Flush();
-}
-
-void CDecoder::ReadTable(Byte *lastLevels, Byte *newLevels, UInt32 numSymbols)
-{
- Byte levelLevels[kLevelTableSize];
- UInt32 i;
- for (i = 0; i < kLevelTableSize; i++)
- levelLevels[i] = Byte(m_InBitStream.ReadBits(kNumBitsForPreTreeLevel));
- m_LevelDecoder.SetCodeLengths(levelLevels);
- for (i = 0; i < numSymbols;)
- {
- UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
- if (number <= kNumHuffmanBits)
- newLevels[i++] = Byte((17 + lastLevels[i] - number) % (kNumHuffmanBits + 1));
- else if (number == kLevelSymbolZeros || number == kLevelSymbolZerosBig)
- {
- int num;
- if (number == kLevelSymbolZeros)
- num = kLevelSymbolZerosStartValue +
- m_InBitStream.ReadBits(kLevelSymbolZerosNumBits);
- else
- num = kLevelSymbolZerosBigStartValue +
- m_InBitStream.ReadBits(kLevelSymbolZerosBigNumBits);
- for (;num > 0 && i < numSymbols; num--, i++)
- newLevels[i] = 0;
- }
- else if (number == kLevelSymbolSame)
- {
- int num = kLevelSymbolSameStartValue + m_InBitStream.ReadBits(kLevelSymbolSameNumBits);
- UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
- if (number > kNumHuffmanBits)
- throw "bad data";
- Byte symbol = Byte((17 + lastLevels[i] - number) % (kNumHuffmanBits + 1));
- for (; num > 0 && i < numSymbols; num--, i++)
- newLevels[i] = symbol;
- }
- else
- throw "bad data";
- }
-
- memmove(lastLevels, newLevels, numSymbols);
-}
-
-void CDecoder::ReadTables(void)
-{
- int blockType = m_InBitStream.ReadBits(NBlockType::kNumBits);
-
- if (blockType != NBlockType::kVerbatim && blockType != NBlockType::kAligned &&
- blockType != NBlockType::kUncompressed)
- throw "bad data";
-
- m_UnCompressedBlockSize = m_InBitStream.ReadBitsBig(kUncompressedBlockSizeNumBits);
-
- if (blockType == NBlockType::kUncompressed)
- {
- m_UncompressedBlock = true;
- UInt32 bitPos = m_InBitStream.GetBitPosition() % 16;
- m_InBitStream.ReadBits(16 - bitPos);
- for (int i = 0; i < kNumRepDistances; i++)
- {
- m_RepDistances[i] = 0;
- for (int j = 0; j < 4; j++)
- m_RepDistances[i] |= (m_InBitStream.DirectReadByte()) << (8 * j);
- m_RepDistances[i]--;
- }
- return;
- }
-
- m_UncompressedBlock = false;
-
- m_AlignIsUsed = (blockType == NBlockType::kAligned);
-
- Byte newLevels[kMaxTableSize];
-
- if (m_AlignIsUsed)
- {
- for(int i = 0; i < kAlignTableSize; i++)
- newLevels[i] = m_InBitStream.ReadBits(kNumBitsForAlignLevel);
- m_AlignDecoder.SetCodeLengths(newLevels);
- }
-
- ReadTable(m_LastByteLevels, newLevels, 256);
- ReadTable(m_LastPosLenLevels, newLevels + 256, m_NumPosLenSlots);
- for (int i = m_NumPosLenSlots; i < kNumPosSlotLenSlotSymbols; i++)
- newLevels[256 + i] = 0;
- m_MainDecoder.SetCodeLengths(newLevels);
-
- ReadTable(m_LastLenLevels, newLevels, kNumLenSymbols);
- m_LenDecoder.SetCodeLengths(newLevels);
-
-}
-
-class CDecoderFlusher
-{
- CDecoder *m_Decoder;
-public:
- CDecoderFlusher(CDecoder *decoder): m_Decoder(decoder) {}
- ~CDecoderFlusher()
- {
- m_Decoder->Flush();
- m_Decoder->ReleaseStreams();
- }
-};
-
-
-void CDecoder::ClearPrevLeveles()
-{
- memset(m_LastByteLevels, 0, 256);
- memset(m_LastPosLenLevels, 0, kNumPosSlotLenSlotSymbols);
- memset(m_LastLenLevels, 0, kNumLenSymbols);
-};
-
-
-STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
- ISequentialOutStream *outStream,
- const UInt64 *inSize, const UInt64 *outSize,
- ICompressProgressInfo *progress)
-{
- if (outSize == NULL)
- return E_INVALIDARG;
- UInt64 size = *outSize;
-
- if (!m_OutWindowStream.Create(kHistorySize))
- return E_OUTOFMEMORY;
- if (!m_InBitStream.Create(1 << 20))
- return E_OUTOFMEMORY;
-
- m_OutWindowStream.SetStream(m_i86TranslationOutStream);
- m_OutWindowStream.Init();
-
- m_InBitStream.SetStream(inStream);
- m_InBitStream.Init(m_ReservedSize, m_NumInDataBlocks);
-
- CDecoderFlusher flusher(this);
-
- UInt32 uncompressedCFDataBlockSize;
- bool dataAreCorrect;
- RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect));
- if (!dataAreCorrect)
- {
- throw "Data Error";
- }
- UInt32 uncompressedCFDataCurrentValue = 0;
- m_InBitStream.Init();
-
- ClearPrevLeveles();
-
- if (m_InBitStream.ReadBits(1) == 0)
- m_i86TranslationOutStreamSpec->Init(outStream, false, 0);
- else
- {
- UInt32 i86TranslationSize = m_InBitStream.ReadBits(16) << 16;
- i86TranslationSize |= m_InBitStream.ReadBits(16);
- m_i86TranslationOutStreamSpec->Init(outStream, true , i86TranslationSize);
- }
-
- for(int i = 0 ; i < kNumRepDistances; i++)
- m_RepDistances[i] = 0;
-
- UInt64 nowPos64 = 0;
- while(nowPos64 < size)
- {
- if (uncompressedCFDataCurrentValue == uncompressedCFDataBlockSize)
- {
- bool dataAreCorrect;
- RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect));
- if (!dataAreCorrect)
- {
- throw "Data Error";
- }
- m_InBitStream.Init();
- uncompressedCFDataCurrentValue = 0;
- }
- ReadTables();
- UInt32 nowPos = 0;
- UInt32 next = (UInt32)MyMin((UInt64)m_UnCompressedBlockSize, size - nowPos64);
- if (m_UncompressedBlock)
- {
- while(nowPos < next)
- {
- m_OutWindowStream.PutByte(m_InBitStream.DirectReadByte());
- nowPos++;
- uncompressedCFDataCurrentValue++;
- if (uncompressedCFDataCurrentValue == uncompressedCFDataBlockSize)
- {
- bool dataAreCorrect;
- RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect));
- if (!dataAreCorrect)
- {
- throw "Data Error";
- }
- // m_InBitStream.Init();
- uncompressedCFDataCurrentValue = 0;
- continue;
- }
- }
- int bitPos = m_InBitStream.GetBitPosition() % 16;
- if (bitPos == 8)
- m_InBitStream.DirectReadByte();
- m_InBitStream.Normalize();
- }
- else for (;nowPos < next;)
- {
- if (uncompressedCFDataCurrentValue == uncompressedCFDataBlockSize)
- {
- bool dataAreCorrect;
- RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect));
- if (!dataAreCorrect)
- {
- throw "Data Error";
- }
- m_InBitStream.Init();
- uncompressedCFDataCurrentValue = 0;
- }
- UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
- if (number < 256)
- {
- m_OutWindowStream.PutByte(Byte(number));
- nowPos++;
- uncompressedCFDataCurrentValue++;
- // continue;
- }
- else if (number < 256 + m_NumPosLenSlots)
- {
- UInt32 posLenSlot = number - 256;
- UInt32 posSlot = posLenSlot / kNumLenSlots;
- UInt32 lenSlot = posLenSlot % kNumLenSlots;
- UInt32 length = 2 + lenSlot;
- if (lenSlot == kNumLenSlots - 1)
- length += m_LenDecoder.DecodeSymbol(&m_InBitStream);
-
- if (posSlot < kNumRepDistances)
- {
- UInt32 distance = m_RepDistances[posSlot];
- m_OutWindowStream.CopyBlock(distance, length);
- if (posSlot != 0)
- {
- m_RepDistances[posSlot] = m_RepDistances[0];
- m_RepDistances[0] = distance;
- }
- }
- else
- {
- UInt32 pos = kDistStart[posSlot];
- UInt32 posDirectBits = kDistDirectBits[posSlot];
- if (m_AlignIsUsed && posDirectBits >= kNumAlignBits)
- {
- pos += (m_InBitStream.ReadBits(posDirectBits - kNumAlignBits) << kNumAlignBits);
- pos += m_AlignDecoder.DecodeSymbol(&m_InBitStream);
- }
- else
- pos += m_InBitStream.ReadBits(posDirectBits);
- UInt32 distance = pos - kNumRepDistances;
- if (distance >= nowPos64 + nowPos)
- throw 777123;
- m_OutWindowStream.CopyBlock(distance, length);
- m_RepDistances[2] = m_RepDistances[1];
- m_RepDistances[1] = m_RepDistances[0];
- m_RepDistances[0] = distance;
- }
- nowPos += length;
- uncompressedCFDataCurrentValue += length;
- }
- else
- throw 98112823;
- }
- if (progress != NULL)
- {
- UInt64 inSize = m_InBitStream.GetProcessedSize();
- UInt64 outSize = nowPos64 + nowPos;
- RINOK(progress->SetRatioInfo(&inSize, &outSize));
- }
- nowPos64 += nowPos;
- }
- return S_OK;
-}
-
-}}}
diff --git a/7zip/Archive/Cab/LZXDecoder.h b/7zip/Archive/Cab/LZXDecoder.h
deleted file mode 100755
index 257de7b9..00000000
--- a/7zip/Archive/Cab/LZXDecoder.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Archive/Cab/LZXDecoder.h
-
-#ifndef __ARCHIVE_CAB_LZXDECODER_H
-#define __ARCHIVE_CAB_LZXDECODER_H
-
-#include "../../ICoder.h"
-
-#include "../../Compress/Huffman/HuffmanDecoder.h"
-#include "../../Compress/LZ/LZOutWindow.h"
-
-#include "LZXExtConst.h"
-#include "LZXBitDecoder.h"
-
-#include "LZXi86Converter.h"
-#include "LZXConst.h"
-
-namespace NArchive {
-namespace NCab {
-namespace NLZX {
-
-const int kMainTableSize = 256 + kNumPosSlotLenSlotSymbols;
-
-class CDecoder :
- public ICompressCoder,
- public CMyUnknownImp
-{
- CLZOutWindow m_OutWindowStream;
- NBitStream::CDecoder m_InBitStream;
-
- NCompress::NHuffman::CDecoder<kNumHuffmanBits, kMainTableSize> m_MainDecoder;
- NCompress::NHuffman::CDecoder<kNumHuffmanBits, kNumLenSymbols> m_LenDecoder;
- NCompress::NHuffman::CDecoder<kNumHuffmanBits, kAlignTableSize> m_AlignDecoder;
- NCompress::NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder;
-
- UInt32 m_RepDistances[kNumRepDistances];
-
- Byte m_LastByteLevels[256];
- Byte m_LastPosLenLevels[kNumPosSlotLenSlotSymbols];
- Byte m_LastLenLevels[kNumLenSymbols];
-
- UInt32 m_DictionarySizePowerOf2;
- UInt32 m_NumPosSlots;
- UInt32 m_NumPosLenSlots;
-
- // bool m_i86PreprocessingUsed;
- // UInt32 m_i86TranslationSize;
-
- bool m_UncompressedBlock;
- bool m_AlignIsUsed;
-
- UInt32 m_UnCompressedBlockSize;
-
- Ci86TranslationOutStream *m_i86TranslationOutStreamSpec;
- CMyComPtr<ISequentialOutStream> m_i86TranslationOutStream;
-
- Byte m_ReservedSize;
- UInt32 m_NumInDataBlocks;
-
- void ReadTable(Byte *lastLevels, Byte *newLevels, UInt32 numSymbols);
- void ReadTables();
- void ClearPrevLeveles();
-
-public:
- CDecoder();
-
- MY_UNKNOWN_IMP
-
- void ReleaseStreams();
- STDMETHOD(Flush)();
-
- // ICompressCoder interface
- STDMETHOD(Code)(ISequentialInStream *inStream,
- ISequentialOutStream *outStream,
- const UInt64 *inSize, const UInt64 *outSize,
- ICompressProgressInfo *progress);
-
- void SetParams(Byte reservedSize, UInt32 numInDataBlocks,
- UInt32 dictionarySizePowerOf2)
- {
- m_ReservedSize = reservedSize;
- m_NumInDataBlocks = numInDataBlocks;
- m_DictionarySizePowerOf2 = dictionarySizePowerOf2;
- if (dictionarySizePowerOf2 < 20)
- m_NumPosSlots = 30 + (dictionarySizePowerOf2 - 15) * 2;
- else if (dictionarySizePowerOf2 == 20)
- m_NumPosSlots = 42;
- else
- m_NumPosSlots = 50;
- m_NumPosLenSlots = m_NumPosSlots * kNumLenSlots;
- }
-};
-
-}}}
-
-#endif \ No newline at end of file
diff --git a/7zip/Archive/Cab/LZXExtConst.h b/7zip/Archive/Cab/LZXExtConst.h
deleted file mode 100755
index df2ef6cf..00000000
--- a/7zip/Archive/Cab/LZXExtConst.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Archive/Cab/LZXExtConst.h
-
-#ifndef __ARCHIVE_CAB_LZXEXTCONST_H
-#define __ARCHIVE_CAB_LZXEXTCONST_H
-
-namespace NArchive {
-namespace NCab {
-namespace NLZX {
-
-const UInt32 kNumRepDistances = 3;
-
-const UInt32 kNumLenSlots = 8;
-const UInt32 kMatchMinLen = 2;
-const UInt32 kNumLenSymbols = 249;
-const UInt32 kMatchMaxLen = kMatchMinLen + (kNumLenSlots - 1) + kNumLenSymbols - 1;
-
-const Byte kNumAlignBits = 3;
-const UInt32 kAlignTableSize = 1 << kNumAlignBits;
-
-const UInt32 kNumHuffmanBits = 16;
-
-const int kNumPosSlotSymbols = 50;
-const int kNumPosSlotLenSlotSymbols = kNumPosSlotSymbols * kNumLenSlots;
-
-const int kMaxTableSize = 256 + kNumPosSlotLenSlotSymbols;
-
-
-}}}
-
-#endif
diff --git a/7zip/Archive/Cab/MSZipConst.h b/7zip/Archive/Cab/MSZipConst.h
deleted file mode 100755
index f2dfda86..00000000
--- a/7zip/Archive/Cab/MSZipConst.h
+++ /dev/null
@@ -1,92 +0,0 @@
-// MSZipConst.h
-
-#ifndef __MSZIP_CONST_H
-#define __MSZIP_CONST_H
-
-#include "MSZipExtConst.h"
-
-namespace NArchive {
-namespace NCab {
-namespace NMSZip {
-
-const UInt32 kLenTableSize = 29;
-
-const UInt32 kStaticDistTableSize = 32;
-const UInt32 kStaticLenTableSize = 31;
-
-const UInt32 kReadTableNumber = 0x100;
-const UInt32 kMatchNumber = kReadTableNumber + 1;
-
-const UInt32 kMainTableSize = kMatchNumber + kLenTableSize; //298;
-const UInt32 kStaticMainTableSize = kMatchNumber + kStaticLenTableSize; //298;
-
-const UInt32 kDistTableStart = kMainTableSize;
-
-const UInt32 kHeapTablesSizesSum = kMainTableSize + kDistTableSize;
-
-const UInt32 kLevelTableSize = 19;
-
-const UInt32 kMaxTableSize = kHeapTablesSizesSum; // test it
-const UInt32 kStaticMaxTableSize = kStaticMainTableSize + kStaticDistTableSize;
-
-const UInt32 kTableDirectLevels = 16;
-const UInt32 kTableLevelRepNumber = kTableDirectLevels;
-const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1;
-const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1;
-
-const UInt32 kLevelMask = 0xF;
-
-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, 255};
-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, 0};
-
-
-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};
-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};
-
-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 kCodeLengthAlphabetOrder[kLevelTableSize] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
-const UInt32 kMatchMinLen = 3;
-const UInt32 kMatchMaxLen = kNumLenCombinations + kMatchMinLen - 1; //255 + 2; test it
-
-const int kFinalBlockFieldSize = 1;
-
-namespace NFinalBlockField
-{
-enum
-{
- kNotFinalBlock = 0,
- kFinalBlock = 1
-};
-}
-
-const int kBlockTypeFieldSize = 2;
-
-namespace NBlockType
-{
- enum
- {
- kStored = 0,
- kFixedHuffman = 1,
- kDynamicHuffman = 2,
- kReserved = 3
- };
-}
-
-const UInt32 kDeflateNumberOfLengthCodesFieldSize = 5;
-const UInt32 kDeflateNumberOfDistanceCodesFieldSize = 5;
-const UInt32 kDeflateNumberOfLevelCodesFieldSize = 4;
-
-const UInt32 kDeflateNumberOfLitLenCodesMin = 257;
-
-const UInt32 kDeflateNumberOfDistanceCodesMin = 1;
-const UInt32 kDeflateNumberOfLevelCodesMin = 4;
-
-const UInt32 kDeflateLevelCodeFieldSize = 3;
-
-const UInt32 kDeflateStoredBlockLengthFieldSizeSize = 16;
-
-}}}
-
-#endif \ No newline at end of file
diff --git a/7zip/Archive/Cab/MSZipDecoder.cpp b/7zip/Archive/Cab/MSZipDecoder.cpp
deleted file mode 100755
index 9e004bf9..00000000
--- a/7zip/Archive/Cab/MSZipDecoder.cpp
+++ /dev/null
@@ -1,268 +0,0 @@
-// Archive/Cab/MSZipDecoder.cpp
-
-#include "StdAfx.h"
-
-#include "MSZipDecoder.h"
-
-#include "Windows/Defs.h"
-
-namespace NArchive {
-namespace NCab {
-namespace NMSZip {
-
-CDecoder::CDecoder(){}
-
-HRESULT CDecoder::Flush()
-{
- return m_OutWindowStream.Flush();
-}
-
-void CDecoder::ReleaseStreams()
-{
- m_OutWindowStream.ReleaseStream();
- m_InBitStream.ReleaseStream();
-}
-
-void CDecoder::DeCodeLevelTable(Byte *newLevels, int numLevels)
-{
- int i = 0;
- while (i < numLevels)
- {
- UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
- if (number < kTableDirectLevels)
- newLevels[i++] = Byte(number);
- else
- {
- if (number == kTableLevelRepNumber)
- {
- int t = m_InBitStream.ReadBits(2) + 3;
- for (int reps = t; reps > 0 && i < numLevels ; reps--, i++)
- newLevels[i] = newLevels[i - 1];
- }
- else
- {
- int num;
- if (number == kTableLevel0Number)
- num = m_InBitStream.ReadBits(3) + 3;
- else
- num = m_InBitStream.ReadBits(7) + 11;
- for (;num > 0 && i < numLevels; num--)
- newLevels[i++] = 0;
- }
- }
- }
-}
-
-void CDecoder::ReadTables(void)
-{
- if(m_FinalBlock) // test it
- throw CDecoderException(CDecoderException::kData);
-
- m_FinalBlock = (m_InBitStream.ReadBits(kFinalBlockFieldSize) == NFinalBlockField::kFinalBlock);
-
- int blockType = m_InBitStream.ReadBits(kBlockTypeFieldSize);
-
- switch(blockType)
- {
- case NBlockType::kStored:
- {
- m_StoredMode = true;
- UInt32 currentBitPosition = m_InBitStream.GetBitPosition();
- UInt32 numBitsForAlign = currentBitPosition > 0 ? (8 - currentBitPosition): 0;
- if (numBitsForAlign > 0)
- m_InBitStream.ReadBits(numBitsForAlign);
- m_StoredBlockSize = m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize);
- WORD onesComplementReverse = ~WORD(m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize));
- if (m_StoredBlockSize != onesComplementReverse)
- throw CDecoderException(CDecoderException::kData);
- break;
- }
- case NBlockType::kFixedHuffman:
- case NBlockType::kDynamicHuffman:
- {
- m_StoredMode = false;
- Byte litLenLevels[kStaticMainTableSize];
- Byte distLevels[kStaticDistTableSize];
- if (blockType == NBlockType::kFixedHuffman)
- {
- int i;
-
- // Leteral / length levels
- for (i = 0; i < 144; i++)
- litLenLevels[i] = 8;
- for (; i < 256; i++)
- litLenLevels[i] = 9;
- for (; i < 280; i++)
- litLenLevels[i] = 7;
- for (; i < 288; i++) /* make a complete, but wrong code set */
- litLenLevels[i] = 8;
-
- // Distance levels
- for (i = 0; i < kStaticDistTableSize; i++) // test it: infozip only use kDistTableSize
- distLevels[i] = 5;
- }
- else // in case when (blockType == kDeflateBlockTypeFixedHuffman)
- {
- int numLitLenLevels = m_InBitStream.ReadBits(kDeflateNumberOfLengthCodesFieldSize) +
- kDeflateNumberOfLitLenCodesMin;
- int numDistLevels = m_InBitStream.ReadBits(kDeflateNumberOfDistanceCodesFieldSize) +
- kDeflateNumberOfDistanceCodesMin;
- int numLevelCodes = m_InBitStream.ReadBits(kDeflateNumberOfLevelCodesFieldSize) +
- kDeflateNumberOfLevelCodesMin;
-
- int numLevels;
- numLevels = kHeapTablesSizesSum;
-
- Byte levelLevels[kLevelTableSize];
- int i;
- for (i = 0; i < kLevelTableSize; i++)
- {
- int position = kCodeLengthAlphabetOrder[i];
- if(i < numLevelCodes)
- levelLevels[position] = Byte(m_InBitStream.ReadBits(kDeflateLevelCodeFieldSize));
- else
- levelLevels[position] = 0;
- }
-
- try
- {
- m_LevelDecoder.SetCodeLengths(levelLevels);
- }
- catch(...)
- {
- throw CDecoderException(CDecoderException::kData);
- }
-
- Byte tmpLevels[kStaticMaxTableSize];
- DeCodeLevelTable(tmpLevels, numLitLenLevels + numDistLevels);
-
- memmove(litLenLevels, tmpLevels, numLitLenLevels);
- memset(litLenLevels + numLitLenLevels, 0,
- kStaticMainTableSize - numLitLenLevels);
-
- memmove(distLevels, tmpLevels + numLitLenLevels, numDistLevels);
- memset(distLevels + numDistLevels, 0, kStaticDistTableSize - numDistLevels);
- }
- try
- {
- m_MainDecoder.SetCodeLengths(litLenLevels);
- m_DistDecoder.SetCodeLengths(distLevels);
- }
- catch(...)
- {
- throw CDecoderException(CDecoderException::kData);
- }
- break;
- }
- default:
- throw CDecoderException(CDecoderException::kData);
- }
-}
-
-class CCoderReleaser
-{
- CDecoder *m_Coder;
-public:
- CCoderReleaser(CDecoder *aCoder): m_Coder(aCoder) {}
- ~CCoderReleaser()
- {
- m_Coder->Flush();
- m_Coder->ReleaseStreams();
- }
-};
-
-STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
- ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
- ICompressProgressInfo *progress)
-{
- if (outSize == NULL)
- return E_INVALIDARG;
- UInt64 size = *outSize;
-
- if (!m_OutWindowStream.Create(kHistorySize))
- return E_OUTOFMEMORY;
- if (!m_InBitStream.Create(1 << 20))
- return E_OUTOFMEMORY;
-
- m_OutWindowStream.SetStream(outStream);
- m_OutWindowStream.Init(false);
-
- m_InBitStream.SetStream(inStream);
- m_InBitStream.InitMain(m_ReservedSize, m_NumInDataBlocks);
- CCoderReleaser coderReleaser(this);
-
- UInt64 nowPos = 0;
- while(nowPos < size)
- {
- if (progress != NULL)
- {
- UInt64 packSize = m_InBitStream.GetProcessedSize();
- RINOK(progress->SetRatioInfo(&packSize, &nowPos));
- }
- UInt32 uncompressedCFDataBlockSize;
- bool dataAreCorrect;
- RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect));
- if (!dataAreCorrect)
- {
- throw "Data Error";
- }
- m_InBitStream.Init();
- if (m_InBitStream.ReadBits(8) != 0x43)
- throw CDecoderException(CDecoderException::kData);
- if (m_InBitStream.ReadBits(8) != 0x4B)
- throw CDecoderException(CDecoderException::kData);
- UInt32 uncompressedCFDataCurrentValue = 0;
- m_FinalBlock = false;
- while (uncompressedCFDataCurrentValue < uncompressedCFDataBlockSize)
- {
- ReadTables();
- if(m_StoredMode)
- {
- for (UInt32 i = 0; i < m_StoredBlockSize; i++)
- m_OutWindowStream.PutByte(Byte(m_InBitStream.ReadBits(8)));
- nowPos += m_StoredBlockSize;
- uncompressedCFDataCurrentValue += m_StoredBlockSize;
- continue;
- }
- while(true)
- {
- UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
-
- if (number < 256)
- {
- m_OutWindowStream.PutByte(Byte(number));
- nowPos++;
- uncompressedCFDataCurrentValue++;
- continue;
- }
- else if (number >= kMatchNumber)
- {
- number -= kMatchNumber;
- UInt32 length = UInt32(kLenStart[number]) + kMatchMinLen;
- UInt32 numBits;
- if ((numBits = kLenDirectBits[number]) > 0)
- length += m_InBitStream.ReadBits(numBits);
-
- number = m_DistDecoder.DecodeSymbol(&m_InBitStream);
- UInt32 distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]);
- /*
- if (distance >= nowPos)
- throw "data error";
- */
- m_OutWindowStream.CopyBlock(distance, length);
- nowPos += length;
- uncompressedCFDataCurrentValue += length;
- }
- else if (number == kReadTableNumber)
- {
- break;
- }
- else
- throw CDecoderException(CDecoderException::kData);
- }
- }
- }
- return S_OK;
-}
-
-}}}
diff --git a/7zip/Archive/Cab/MSZipDecoder.h b/7zip/Archive/Cab/MSZipDecoder.h
deleted file mode 100755
index f83a5ab7..00000000
--- a/7zip/Archive/Cab/MSZipDecoder.h
+++ /dev/null
@@ -1,85 +0,0 @@
-// Archive/Cab/MSZipDecoder.h
-
-#ifndef __ARCHIVE_CAB_DECODER_H
-#define __ARCHIVE_CAB_DECODER_H
-
-#include "Common/MyCom.h"
-#include "../../ICoder.h"
-#include "../../Common/LSBFDecoder.h"
-#include "../../Compress/Huffman/HuffmanDecoder.h"
-#include "../../Compress/LZ/LZOutWindow.h"
-
-#include "CabInBuffer.h"
-#include "MSZipExtConst.h"
-#include "MSZipConst.h"
-
-namespace NArchive {
-namespace NCab {
-namespace NMSZip {
-
-class CDecoderException
-{
-public:
- enum ECauseType
- {
- kData
- } m_Cause;
- CDecoderException(ECauseType aCause): m_Cause(aCause) {}
-};
-
-class CMSZipBitDecoder: public NStream::NLSBF::CDecoder<NCab::CInBuffer>
-{
-public:
- void InitMain(Byte reservedSize, UInt32 aNumBlocks)
- {
- m_Stream.Init(reservedSize, aNumBlocks);
- Init();
- }
- HRESULT ReadBlock(UInt32 &uncompressedSize, bool &dataAreCorrect)
- {
- return m_Stream.ReadBlock(uncompressedSize, dataAreCorrect);
- }
-};
-
-class CDecoder :
- public ICompressCoder,
- public CMyUnknownImp
-{
- CLZOutWindow m_OutWindowStream;
- CMSZipBitDecoder m_InBitStream;
- NCompress::NHuffman::CDecoder<kNumHuffmanBits, kStaticMainTableSize> m_MainDecoder;
- NCompress::NHuffman::CDecoder<kNumHuffmanBits, kStaticDistTableSize> m_DistDecoder;
- NCompress::NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder;
-
- bool m_FinalBlock;
- bool m_StoredMode;
- UInt32 m_StoredBlockSize;
-
- Byte m_ReservedSize;
- UInt32 m_NumInDataBlocks;
-
- void DeCodeLevelTable(Byte *newLevels, int numLevels);
- void ReadTables();
-public:
- CDecoder();
-
- MY_UNKNOWN_IMP
-
- HRESULT Flush();
- void ReleaseStreams();
-
- STDMETHOD(Code)(ISequentialInStream *inStream,
- ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
- ICompressProgressInfo *progress);
-
- void SetParams(Byte reservedSize, UInt32 numInDataBlocks)
- {
- m_ReservedSize = reservedSize;
- m_NumInDataBlocks = numInDataBlocks;
- }
-
-};
-
-}}}
-
-#endif \ No newline at end of file
diff --git a/7zip/Archive/Cab/MSZipExtConst.h b/7zip/Archive/Cab/MSZipExtConst.h
deleted file mode 100755
index f51eebb8..00000000
--- a/7zip/Archive/Cab/MSZipExtConst.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// DeflateExtConst.h
-
-#ifndef __DEFLATEEXTCONST_H
-#define __DEFLATEEXTCONST_H
-
-#include "Common/Types.h"
-
-namespace NArchive {
-namespace NCab {
-namespace NMSZip {
-
- const UInt32 kDistTableSize = 30;
- const UInt32 kHistorySize = 0x8000;
- const UInt32 kNumLenCombinations = 256;
-
- const UInt32 kNumHuffmanBits = 15;
-
-}}}
-
-#endif
diff --git a/7zip/Archive/Cab/makefile b/7zip/Archive/Cab/makefile
index ab635c5d..672afed3 100755
--- a/7zip/Archive/Cab/makefile
+++ b/7zip/Archive/Cab/makefile
@@ -5,14 +5,10 @@ LIBS = $(LIBS) oleaut32.lib user32.lib
CAB_OBJS = \
$O\DllExports.obj \
- $O\CabCopyDecoder.obj \
+ $O\CabBlockInStream.obj \
$O\CabHandler.obj \
$O\CabHeader.obj \
$O\CabIn.obj \
- $O\CabInBuffer.obj \
- $O\LZXDecoder.obj \
- $O\LZXi86Converter.obj \
- $O\MSZipDecoder.obj \
COMMON_OBJS = \
$O\Alloc.obj \
@@ -32,6 +28,11 @@ WIN_OBJS = \
$O\LSBFDecoder.obj \
$O\OutBuffer.obj \
$O\ProgressUtils.obj \
+ $O\StreamUtils.obj \
+
+COMPRESS_LZX_OBJS = \
+ $O\LzxDecoder.obj \
+ $O\Lzx86Converter.obj \
OBJS = \
$O\StdAfx.obj \
@@ -39,7 +40,11 @@ OBJS = \
$(COMMON_OBJS) \
$(WIN_OBJS) \
$(7ZIP_COMMON_OBJS) \
+ $(COMPRESS_LZX_OBJS) \
+ $O\DeflateDecoder.obj \
+ $O\QuantumDecoder.obj \
$O\LZOutWindow.obj \
+ $O\CopyCoder.obj \
$O\resource.res
!include "../../../Build.mak"
@@ -52,5 +57,14 @@ $(WIN_OBJS): ../../../Windows/$(*B).cpp
$(COMPL)
$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
$(COMPL)
+$(COMPRESS_LZX_OBJS): ../../Compress/Lzx/$(*B).cpp
+ $(COMPL_O2)
+$O\DeflateDecoder.obj: ../../Compress/Deflate/$(*B).cpp
+ $(COMPL_O2)
+$O\QuantumDecoder.obj: ../../Compress/Quantum/$(*B).cpp
+ $(COMPL)
$O\LZOutWindow.obj: ../../Compress/LZ/$(*B).cpp
$(COMPL)
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
+
diff --git a/7zip/Archive/Chm/Chm.dsp b/7zip/Archive/Chm/Chm.dsp
new file mode 100755
index 00000000..7e0b7c66
--- /dev/null
+++ b/7zip/Archive/Chm/Chm.dsp
@@ -0,0 +1,337 @@
+# Microsoft Developer Studio Project File - Name="Chm" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=Chm - 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 "Chm.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 "Chm.mak" CFG="Chm - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Chm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Chm - 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)" == "Chm - 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 "CHM_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CHM_EXPORTS" /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:\Program Files\7-Zip\Formats\chm.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Chm - 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 "CHM_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CHM_EXPORTS" /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:\Program Files\7-Zip\Formats\chm.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "Chm - Win32 Release"
+# Name "Chm - Win32 Debug"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Archive.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\DllExports.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=.\ChmHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ChmHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ChmHeader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ChmHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ChmIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ChmIn.h
+# End Source File
+# End Group
+# Begin Group "7zip Common"
+
+# PROP Default_Filter ""
+# 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\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\Alloc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Alloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Buffer.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\String.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\String.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\Vector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Vector.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# End Group
+# Begin Group "Archive Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Common\ItemNameUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ItemNameUtils.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Group "LZ"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\LZOutWindow.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\LZOutWindow.h
+# End Source File
+# End Group
+# Begin Group "Lzx"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Lzx\Lzx.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Lzx\Lzx86Converter.cpp
+
+!IF "$(CFG)" == "Chm - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Chm - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Lzx\Lzx86Converter.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Lzx\LzxDecoder.cpp
+
+!IF "$(CFG)" == "Chm - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Chm - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Lzx\LzxDecoder.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/7zip/Archive/Chm/Chm.dsw b/7zip/Archive/Chm/Chm.dsw
new file mode 100755
index 00000000..58cb09b2
--- /dev/null
+++ b/7zip/Archive/Chm/Chm.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Chm"=.\Chm.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/7zip/Archive/Chm/ChmHandler.cpp b/7zip/Archive/Chm/ChmHandler.cpp
new file mode 100755
index 00000000..3f2d3cc7
--- /dev/null
+++ b/7zip/Archive/Chm/ChmHandler.cpp
@@ -0,0 +1,729 @@
+// Chm/Handler.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StringConvert.h"
+#include "Common/Defs.h"
+#include "Common/UTFConvert.h"
+#include "Common/ComTry.h"
+
+#include "Windows/PropVariant.h"
+#include "Windows/Time.h"
+
+#include "../../Common/LimitedStreams.h"
+#include "../../Common/StreamUtils.h"
+#include "../../Common/ProgressUtils.h"
+
+#include "../../Compress/Copy/CopyCoder.h"
+#include "../../Compress/Lzx/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,
+ kpidOffset
+};
+
+#endif
+
+STATPROPSTG kProperties[] =
+{
+ { NULL, kpidPath, VT_BSTR},
+ // { NULL, kpidIsFolder, VT_BOOL},
+ { NULL, kpidSize, VT_UI8},
+ { NULL, kpidMethod, VT_BSTR},
+ { NULL, kpidBlock, VT_UI4}
+
+ #ifdef _CHM_DETAILS
+ ,
+ { L"Section", kpidSection, VT_UI4},
+ { L"Offset", kpidOffset, VT_UI4}
+ #endif
+};
+
+static const int kNumProperties = sizeof(kProperties) / sizeof(kProperties[0]);
+
+STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
+{
+ value->vt = VT_EMPTY;
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
+{
+ *numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType)
+{
+ if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
+ return E_INVALIDARG;
+ const STATPROPSTG &srcItem = kProperties[index];
+ *propID = srcItem.propid;
+ *varType = srcItem.vt;
+ if (srcItem.lpwstrName == 0)
+ *name = 0;
+ else
+ *name = ::SysAllocString(srcItem.lpwstrName);
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
+{
+ *numProperties = 0;
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType)
+{
+ return E_INVALIDARG;
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant propVariant;
+ if (m_Database.NewFormat)
+ {
+ switch(propID)
+ {
+ case kpidSize:
+ propVariant = (UInt64)m_Database.NewFormatString.Length();
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ }
+ int 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.Length() > 1)
+ if (us[0] == L'/')
+ us.Delete(0);
+ }
+ propVariant = NItemName::GetOSName2(us);
+ }
+ break;
+ }
+ case kpidIsFolder:
+ propVariant = item.IsDirectory();
+ break;
+ case kpidSize:
+ propVariant = item.Size;
+ break;
+ case kpidMethod:
+ {
+ if (!item.IsDirectory())
+ if (item.Section == 0)
+ propVariant = L"Copy";
+ else if (item.Section < m_Database.Sections.Size())
+ propVariant = m_Database.Sections[(size_t)item.Section].GetMethodName();
+ break;
+ }
+ case kpidBlock:
+ if (m_Database.LowLevel)
+ propVariant = item.Section;
+ else if (item.Section != 0)
+ propVariant = m_Database.GetFolder(index);
+ break;
+
+ #ifdef _CHM_DETAILS
+
+ case kpidSection:
+ propVariant = (UInt32)item.Section;
+ break;
+ case kpidOffset:
+ propVariant = (UInt32)item.Offset;
+ break;
+
+ #endif
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+class CPropgressImp: public CProgressVirt
+{
+ CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallback;
+public:
+ STDMETHOD(SetTotal)(const UInt64 *numFiles);
+ STDMETHOD(SetCompleted)(const UInt64 *numFiles);
+ void Init(IArchiveOpenCallback *openArchiveCallback)
+ { m_OpenArchiveCallback = openArchiveCallback; }
+};
+
+STDMETHODIMP CPropgressImp::SetTotal(const UInt64 *numFiles)
+{
+ if (m_OpenArchiveCallback)
+ return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
+ return S_OK;
+}
+
+STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles)
+{
+ if (m_OpenArchiveCallback)
+ return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::Open(IInStream *inStream,
+ const UInt64 *maxCheckStartPosition,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ COM_TRY_BEGIN
+ m_Stream.Release();
+ try
+ {
+ CInArchive archive;
+ CPropgressImp progressImp;
+ progressImp.Init(openArchiveCallback);
+ RINOK(archive.Open(inStream, maxCheckStartPosition, m_Database));
+ /*
+ if (m_Database.LowLevel)
+ return S_FALSE;
+ */
+ m_Stream = inStream;
+ }
+ catch(...)
+ {
+ return S_FALSE;
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ 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<bool> *m_ExtractStatuses;
+ int m_StartIndex;
+ int m_CurrentIndex;
+ int m_NumFiles;
+
+private:
+ const CFilesDatabase *m_Database;
+ CMyComPtr<IArchiveExtractCallback> m_ExtractCallback;
+ bool m_TestMode;
+
+ bool m_IsOk;
+ bool m_FileIsOpen;
+ UInt64 m_RemainFileSize;
+ CMyComPtr<ISequentialOutStream> m_RealOutStream;
+
+ HRESULT OpenFile();
+ HRESULT WriteEmptyFiles();
+public:
+ void Init(
+ const CFilesDatabase *database,
+ IArchiveExtractCallback *extractCallback,
+ bool testMode);
+ HRESULT FlushCorrupted();
+};
+
+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 = NArchive::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(NArchive::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 != NULL)
+ *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 != NULL)
+ *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 ?
+ NArchive::NExtract::NOperationResult::kOK:
+ NArchive::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)
+ return E_FAIL;
+ int 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 != NULL)
+ *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()
+{
+ const UInt32 kBufferSize = (1 << 10);
+ Byte buffer[kBufferSize];
+ for (int i = 0; i < kBufferSize; i++)
+ buffer[i] = 0;
+ while(m_PosInFolder < m_FolderSize)
+ {
+ UInt32 size = (UInt32)MyMin(m_FolderSize - m_PosInFolder, (UInt64)kBufferSize);
+ UInt32 processedSizeLocal = 0;
+ RINOK(Write2(buffer, size, &processedSizeLocal, false));
+ }
+ return S_OK;
+}
+
+
+STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
+ Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ bool allFilesMode = (numItems == UInt32(-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 = (_aTestMode != 0);
+
+ UInt64 currentTotalSize = 0;
+
+ CMyComPtr<ICompressCoder> copyCoder;
+ UInt32 i;
+
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+ CMyComPtr<ISequentialInStream> inStream(streamSpec);
+
+ if (m_Database.LowLevel)
+ {
+ UInt64 currentItemSize = 0;
+ UInt64 totalSize = 0;
+ if (m_Database.NewFormat)
+ totalSize = m_Database.NewFormatString.Length();
+ 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)
+ {
+ RINOK(extractCallback->SetCompleted(&currentTotalSize));
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ Int32 askMode;
+ askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
+ NArchive::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.Length();
+ RINOK(WriteStream(realOutStream, (const char *)m_Database.NewFormatString, size, 0));
+ }
+ RINOK(extractCallback->SetOperationResult(NArchive::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(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+ continue;
+ }
+
+ if (testMode)
+ {
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ continue;
+ }
+
+ RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL));
+ streamSpec->Init(m_Stream, item.Size);
+
+ CLocalProgress *localProgressSpec = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
+ localProgressSpec->Init(extractCallback, false);
+
+ CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
+ CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
+ localCompressProgressSpec->Init(progress, &currentTotalSize, &currentTotalSize);
+
+ if(!copyCoder)
+ copyCoder = new NCompress::CCopyCoder;
+ RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, compressProgress));
+ realOutStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ }
+ return S_OK;
+ }
+
+ UInt64 lastFolderIndex = ((UInt64)0 - 1);
+ for(i = 0; i < numItems; i++)
+ {
+ UInt32 index = allFilesMode ? i : indices[i];
+ int entryIndex = m_Database.Indices[index];
+ const CItem &item = m_Database.Items[entryIndex];
+ UInt64 sectionIndex = item.Section;
+ if (item.IsDirectory() || item.Size == 0)
+ continue;
+ if (sectionIndex == 0)
+ {
+ currentTotalSize += item.Size;
+ continue;
+ }
+ const CSectionInfo &section = m_Database.Sections[(size_t)item.Section];
+ 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 = 0;
+ CMyComPtr<ICompressCoder> lzxDecoder;
+ CChmFolderOutStream *chmFolderOutStream = 0;
+ CMyComPtr<ISequentialOutStream> outStream;
+
+ currentTotalSize = 0;
+
+ CRecordVector<bool> extractStatuses;
+ for(i = 0; i < numItems;)
+ {
+ RINOK(extractCallback->SetCompleted(&currentTotalSize));
+ UInt32 index = allFilesMode ? i : indices[i];
+ i++;
+ int entryIndex = m_Database.Indices[index];
+ const CItem &item = m_Database.Items[entryIndex];
+ UInt64 sectionIndex = item.Section;
+ Int32 askMode= testMode ?
+ NArchive::NExtract::NAskMode::kTest :
+ NArchive::NExtract::NAskMode::kExtract;
+ if (item.IsDirectory())
+ {
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
+ RINOK(extractCallback->PrepareOperation(askMode));
+ realOutStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ continue;
+ }
+
+ CLocalProgress *localProgressSpec = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
+ localProgressSpec->Init(extractCallback, false);
+
+ CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
+ CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
+ localCompressProgressSpec->Init(progress, NULL, &currentTotalSize);
+
+ if (item.Size == 0 || sectionIndex == 0)
+ {
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
+ if(!testMode && (!realOutStream))
+ continue;
+ RINOK(extractCallback->PrepareOperation(askMode));
+ if (!testMode && item.Size != 0)
+ {
+ RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL));
+ streamSpec->Init(m_Stream, item.Size);
+ if(!copyCoder)
+ copyCoder = new NCompress::CCopyCoder;
+ RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, compressProgress));
+ }
+ realOutStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ currentTotalSize += item.Size;
+ continue;
+ }
+
+ const CSectionInfo &section = m_Database.Sections[(size_t)sectionIndex];
+
+ if (!section.IsLzx())
+ {
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
+ if(!testMode && (!realOutStream))
+ continue;
+ RINOK(extractCallback->PrepareOperation(askMode));
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+ continue;
+ }
+
+ const CLzxInfo &lzxInfo = section.Methods[0].LzxInfo;
+
+ if (chmFolderOutStream == 0)
+ {
+ chmFolderOutStream = new CChmFolderOutStream;
+ outStream = chmFolderOutStream;
+ }
+
+ chmFolderOutStream->Init(&m_Database, extractCallback, testMode);
+
+ if(lzxDecoderSpec == NULL)
+ {
+ lzxDecoderSpec = new NCompress::NLzx::CDecoder;
+ lzxDecoder = lzxDecoderSpec;
+ }
+
+ UInt64 folderIndex = m_Database.GetFolder(index);
+
+ UInt64 compressedPos = m_Database.ContentOffset + section.Offset;
+ UInt32 numDictBits = lzxInfo.GetNumDictBits();
+ RINOK(lzxDecoderSpec->SetParams(numDictBits));
+
+ const CItem *lastItem = &item;
+ extractStatuses.Clear();
+ extractStatuses.Add(true);
+
+ for (;true; folderIndex++)
+ {
+ RINOK(extractCallback->SetCompleted(&currentTotalSize));
+
+ 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++)
+ {
+ UInt32 nextIndex = allFilesMode ? i : indices[i];
+ int entryIndex = m_Database.Indices[nextIndex];
+ const CItem &nextItem = m_Database.Items[entryIndex];
+ 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 startOffset = rt.ResetOffsets[(int)startBlock];
+ UInt64 offset = rt.ResetOffsets[(int)bCur];
+ UInt64 compressedSize;
+ rt.GetCompressedSizeOfBlock(bCur, compressedSize);
+ UInt64 rem = finishPos - chmFolderOutStream->m_PosInSection;
+ if (rem > rt.BlockSize)
+ rem = rt.BlockSize;
+ const UInt64 *offsets = (const UInt64 *)&rt.ResetOffsets.Front();
+ RINOK(m_Stream->Seek(compressedPos + offset, STREAM_SEEK_SET, NULL));
+ streamSpec->Init(m_Stream, compressedSize);
+ lzxDecoderSpec->SetKeepHistory(b > 0, (int)((offset - startOffset) & 1));
+ RINOK(lzxDecoder->Code(inStream, outStream, NULL, &rem, NULL));
+ }
+ }
+ catch(...)
+ {
+ RINOK(chmFolderOutStream->FlushCorrupted());
+ }
+ currentTotalSize += folderSize;
+ if (folderIndex == lastFolderIndex)
+ break;
+ extractStatuses.Clear();
+ }
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ COM_TRY_BEGIN
+ *numItems = m_Database.NewFormat ? 1:
+ (m_Database.LowLevel ?
+ m_Database.Items.Size():
+ m_Database.Indices.Size());
+ return S_OK;
+ COM_TRY_END
+}
+
+}}
diff --git a/7zip/Archive/Chm/ChmHandler.h b/7zip/Archive/Chm/ChmHandler.h
new file mode 100755
index 00000000..54f01b84
--- /dev/null
+++ b/7zip/Archive/Chm/ChmHandler.h
@@ -0,0 +1,46 @@
+// 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_IMP
+
+ STDMETHOD(Open)(IInStream *stream,
+ const UInt64 *maxCheckStartPosition,
+ IArchiveOpenCallback *openArchiveCallback);
+ STDMETHOD(Close)();
+ STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
+ STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
+ STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems,
+ Int32 testMode, IArchiveExtractCallback *extractCallback);
+
+ STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value);
+
+ STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
+ STDMETHOD(GetPropertyInfo)(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType);
+
+ STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties);
+ STDMETHOD(GetArchivePropertyInfo)(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType);
+
+private:
+ CFilesDatabase m_Database;
+ CMyComPtr<IInStream> m_Stream;
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/7zip/Archive/Chm/ChmHeader.cpp b/7zip/Archive/Chm/ChmHeader.cpp
new file mode 100755
index 00000000..4d485b6c
--- /dev/null
+++ b/7zip/Archive/Chm/ChmHeader.cpp
@@ -0,0 +1,24 @@
+// Archive/Chm/Header.h
+
+#include "StdAfx.h"
+
+#include "ChmHeader.h"
+
+namespace NArchive{
+namespace NChm{
+namespace NHeader{
+
+UInt32 kItsfSignature = 0x46535449 + 1;
+UInt32 kItolSignature = 0x4C4F5449 + 1;
+static class CSignatureInitializer
+{
+public:
+ CSignatureInitializer()
+ {
+ kItsfSignature--;
+ kItolSignature--;
+ }
+}g_SignatureInitializer;
+
+
+}}}
diff --git a/7zip/Archive/Chm/ChmHeader.h b/7zip/Archive/Chm/ChmHeader.h
new file mode 100755
index 00000000..9f1bd42b
--- /dev/null
+++ b/7zip/Archive/Chm/ChmHeader.h
@@ -0,0 +1,28 @@
+// Archive/Chm/Header.h
+
+#ifndef __ARCHIVE_CHM_HEADER_H
+#define __ARCHIVE_CHM_HEADER_H
+
+#include "Common/Types.h"
+
+namespace NArchive {
+namespace NChm {
+namespace NHeader{
+
+const UInt32 kItspSignature = 0x50535449;
+const UInt32 kPmglSignature = 0x4C474D50;
+const UInt32 kLzxcSignature = 0x43585A4C;
+
+const UInt32 kIfcmSignature = 0x4D434649;
+const UInt32 kAollSignature = 0x4C4C4F41;
+const UInt32 kCaolSignature = 0x4C4F4143;
+
+extern UInt32 kItsfSignature;
+
+extern UInt32 kItolSignature;
+const UInt32 kItlsSignature = 0x534C5449;
+UInt64 inline GetHxsSignature() { return ((UInt64)kItlsSignature << 32) | kItolSignature; }
+
+}}}
+
+#endif
diff --git a/7zip/Archive/Chm/ChmIn.cpp b/7zip/Archive/Chm/ChmIn.cpp
new file mode 100755
index 00000000..79e934ad
--- /dev/null
+++ b/7zip/Archive/Chm/ChmIn.cpp
@@ -0,0 +1,924 @@
+// Archive/ChmIn.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StringConvert.h"
+#include "Common/MyCom.h"
+#include "Common/UTFConvert.h"
+#include "Common/IntToString.h"
+#include "Windows/Defs.h"
+
+#include "../../Common/LimitedStreams.h"
+#include "ChmIn.h"
+
+namespace NArchive{
+namespace NChm{
+
+// 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(Byte value)
+{
+ return (value < 10) ? ('0' + value) : ('A' + (value - 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 = L"LZX:";
+ UInt32 numDictBits = LzxInfo.GetNumDictBits();
+ wchar_t temp[32];
+ ConvertUInt64ToString(numDictBits, temp);
+ s += temp;
+ }
+ else
+ {
+ AString s2;
+ if (IsDes())
+ s2 = "DES";
+ else
+ {
+ s2 = GetGuidString();
+ if (ControlData.GetCapacity() > 0)
+ {
+ s2 += ":";
+ for (size_t i = 0; i < ControlData.GetCapacity(); 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 += L": ";
+ }
+ for (int i = 0; i < Methods.Size(); i++)
+ {
+ if (i != 0)
+ s += L" ";
+ s += Methods[i].GetName();
+ }
+ return s;
+}
+
+Byte CInArchive::ReadByte()
+{
+ Byte b;
+ if (!_inBuffer.ReadByte(b))
+ throw 1;
+ return b;
+}
+
+void CInArchive::Skeep(size_t size)
+{
+ while (size-- != 0)
+ ReadByte();
+}
+
+void CInArchive::ReadBytes(Byte *data, UInt32 size)
+{
+ for (UInt32 i = 0; i < size; i++)
+ data[i] = ReadByte();
+}
+
+UInt16 CInArchive::ReadUInt16()
+{
+ UInt16 value = 0;
+ for (int i = 0; i < 2; i++)
+ value |= ((UInt16)(ReadByte()) << (8 * i));
+ return value;
+}
+
+UInt32 CInArchive::ReadUInt32()
+{
+ UInt32 value = 0;
+ for (int i = 0; i < 4; i++)
+ value |= ((UInt32)(ReadByte()) << (8 * i));
+ return value;
+}
+
+UInt64 CInArchive::ReadUInt64()
+{
+ UInt64 value = 0;
+ for (int i = 0; i < 8; i++)
+ value |= ((UInt64)(ReadByte()) << (8 * i));
+ return value;
+}
+
+UInt64 CInArchive::ReadEncInt()
+{
+ UInt64 val = 0;;
+ for (int i = 0; i < 10; i++)
+ {
+ Byte b = ReadByte();
+ val |= (b & 0x7F);
+ if (b < 0x80)
+ return val;
+ val <<= 7;
+ }
+ throw 1;
+}
+
+void CInArchive::ReadGUID(GUID &g)
+{
+ g.Data1 = ReadUInt32();
+ g.Data2 = ReadUInt16();
+ g.Data3 = ReadUInt16();
+ ReadBytes(g.Data4, 8);
+}
+
+void CInArchive::ReadString(int size, AString &s)
+{
+ s.Empty();
+ while(size-- != 0)
+ {
+ char c = (char)ReadByte();
+ if (c == 0)
+ {
+ Skeep(size);
+ return;
+ }
+ s += c;
+ }
+}
+
+void CInArchive::ReadUString(int size, UString &s)
+{
+ s.Empty();
+ while(size-- != 0)
+ {
+ wchar_t c = ReadUInt16();
+ if (c == 0)
+ {
+ Skeep(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<ISequentialInStream> limitedStream(streamSpec);
+ streamSpec->Init(inStream, size);
+ _inBuffer.SetStream(limitedStream);
+ _inBuffer.Init();
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadDirEntry(CDatabase &database)
+{
+ CItem item;
+ UInt64 nameLength = ReadEncInt();
+ if (nameLength == 0 || nameLength >= 0x10000000)
+ return S_FALSE;
+ ReadString((int)nameLength, 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;
+ UInt32 unknown1 = ReadUInt32();
+ if (unknown1 != 0 && unknown1 != 1) // it's 0 in one .sll file
+ return S_FALSE;
+ 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 int kNumSections = 2;
+ UInt64 sectionOffsets[kNumSections];
+ UInt64 sectionSizes[kNumSections];
+ int i;
+ for (i = 0; i < kNumSections; i++)
+ {
+ sectionOffsets[i] = ReadUInt64();
+ sectionSizes[i] = ReadUInt64();
+ }
+ // if (chmVersion == 3)
+ database.ContentOffset = ReadUInt64();
+ /*
+ else
+ database.ContentOffset = _startPosition + 0x58
+ */
+
+ /*
+ // Section 0
+ ReadChunk(inStream, sectionOffsets[0], sectionSizes[0]);
+ if (sectionSizes[0] != 0x18)
+ return S_FALSE;
+ ReadUInt32(); // unknown: 01FE
+ ReadUInt32(); // unknown: 0
+ UInt64 fileSize = ReadUInt64();
+ ReadUInt32(); // unknown: 0
+ ReadUInt32(); // unknown: 0
+ */
+
+ // Section 1: The Directory Listing
+ ReadChunk(inStream, sectionOffsets[1], sectionSizes[1]);
+ if (ReadUInt32() != NHeader::kItspSignature)
+ 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() == NHeader::kPmglSignature)
+ {
+ // 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(); // Length 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)
+ int numItems = 0;
+ while (true)
+ {
+ UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos;
+ UInt32 offsetLimit = dirChunkSize - quickrefLength;
+ if (offset > offsetLimit)
+ return S_FALSE;
+ if (offset == offsetLimit)
+ break;
+ RINOK(ReadDirEntry(database));
+ numItems++;
+ }
+ Skeep(quickrefLength - 2);
+ if (ReadUInt16() != numItems)
+ return S_FALSE;
+ }
+ else
+ Skeep(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 int kNumHeaderSectionsMax = 5;
+ if (numHeaderSections != kNumHeaderSectionsMax)
+ return S_FALSE;
+ ReadUInt32(); // Length 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();
+ }
+
+ // 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() != NHeader::kCaolSignature)
+ return S_FALSE;
+ if (ReadUInt32() != 2) // (Most likely a version number)
+ return S_FALSE;
+ UInt32 caolLength = ReadUInt32(); // $50 (Length 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)
+ {
+ database.ContentOffset = 0;
+ database.NewFormat = true;
+ }
+ else if (caolLength == 0x50)
+ {
+ ReadUInt32(); // 0 (Unknown)
+ if (ReadUInt32() != NHeader::kItsfSignature)
+ 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 = _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, _startPosition + sectionOffsets[0], sectionSizes[0]);
+ if (sectionSizes[0] != 0x18)
+ return S_FALSE;
+ ReadUInt32(); // unknown: 01FE
+ ReadUInt32(); // unknown: 0
+ UInt64 fileSize = ReadUInt64();
+ ReadUInt32(); // unknown: 0
+ ReadUInt32(); // unknown: 0
+ */
+
+ // Section 1: The Directory Listing
+ ReadChunk(inStream, _startPosition + sectionOffsets[1], sectionSizes[1]);
+ if (ReadUInt32() != NHeader::kIfcmSignature)
+ 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() == NHeader::kAollSignature)
+ {
+ UInt32 quickrefLength = ReadUInt32(); // Length 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)
+
+ int numItems = 0;
+ while (true)
+ {
+ UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos;
+ UInt32 offsetLimit = dirChunkSize - quickrefLength;
+ if (offset > offsetLimit)
+ return S_FALSE;
+ if (offset == offsetLimit)
+ break;
+ if (database.NewFormat)
+ {
+ UInt16 nameLength = ReadUInt16();
+ if (nameLength == 0)
+ return S_FALSE;
+ UString name;
+ ReadUString((int)nameLength, name);
+ AString s;
+ ConvertUnicodeToUTF8(name, s);
+ Byte b = ReadByte();
+ s += ' ';
+ PrintByte(b, s);
+ s += ' ';
+ 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++;
+ }
+ Skeep(quickrefLength - 2);
+ if (ReadUInt16() != numItems)
+ return S_FALSE;
+ if (numItems > numDirEntries)
+ return S_FALSE;
+ numDirEntries -= numItems;
+ }
+ else
+ Skeep(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)
+{
+ return AString(kStorage) + name + AString("/");
+}
+
+#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
+
+static int CompareFiles(const int *p1, const int *p2, void *param)
+{
+ const CObjectVector<CItem> &items = *(const CObjectVector<CItem> *)param;
+ const CItem &item1 = items[*p1];
+ const CItem &item2 = items[*p2];
+ bool isDir1 = item1.IsDirectory();
+ bool isDir2 = item2.IsDirectory();
+ if (isDir1 && !isDir2)
+ return -1;
+ if (isDir2)
+ {
+ if (isDir1)
+ return MyCompare(*p1, *p2);
+ return 1;
+ }
+ 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 (int i = 0; i < Items.Size(); i++)
+ {
+ const CItem &item = Items[i];
+ if (item.IsUserItem() && item.Name.Length() != 1)
+ Indices.Add(i);
+ }
+}
+
+void CFilesDatabase::Sort()
+{
+ Indices.Sort(CompareFiles, (void *)&Items);
+}
+
+bool CFilesDatabase::Check()
+{
+ UInt64 maxPos = 0;
+ UInt64 prevSection = 0;
+ for(int i = 0; i < Indices.Size(); i++)
+ {
+ const CItem &item = Items[Indices[i]];
+ if (item.Section == 0 || item.IsDirectory())
+ 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;
+}
+
+HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
+{
+ {
+ // The NameList file
+ RINOK(DecompressStream(inStream, database, kNameList));
+ UInt16 length = ReadUInt16();
+ UInt16 numSections = ReadUInt16();
+ for (int i = 0; i < numSections; i++)
+ {
+ CSectionInfo section;
+ UInt16 nameLength = ReadUInt16();
+ UString name;
+ ReadUString(nameLength, name);
+ if (ReadUInt16() != 0)
+ return S_FALSE;
+ if (!ConvertUnicodeToUTF8(name, section.Name))
+ return S_FALSE;
+ database.Sections.Add(section);
+ }
+ }
+
+ int i;
+ for (i = 1; i < database.Sections.Size(); i++)
+ {
+ CSectionInfo &section = database.Sections[i];
+ 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;
+ int numGuids = (int)(_chunkSize / 0x10);
+ if (numGuids < 1)
+ return S_FALSE;
+ for (int 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 (int mi = 0; mi < section.Methods.Size(); mi++)
+ {
+ CMethodInfo &method = section.Methods[mi];
+ UInt32 numDWORDS = ReadUInt32();
+ if (method.IsLzx())
+ {
+ if (numDWORDS < 5)
+ return S_FALSE;
+ if (ReadUInt32() != NHeader::kLzxcSignature)
+ return S_FALSE;
+ CLzxInfo &li = method.LzxInfo;
+ li.Version = ReadUInt32();
+ if (li.Version != 2 && li.Version != 3)
+ return S_FALSE;
+ li.ResetInterval = ReadUInt32();
+ li.WindowSize = ReadUInt32();
+ li.CacheSize = ReadUInt32();
+ if (li.ResetInterval != 2 && li.ResetInterval != 4)
+ return S_FALSE;
+ if (li.WindowSize != 2 && li.WindowSize != 4)
+ return S_FALSE;
+ numDWORDS -= 5;
+ while (numDWORDS-- != 0)
+ ReadUInt32();
+ }
+ else
+ {
+ UInt32 numBytes = numDWORDS * 4;
+ method.ControlData.SetCapacity(numBytes);
+ ReadBytes(method.ControlData, numBytes);
+ }
+ }
+ }
+
+ {
+ // SpanInfo
+ RINOK(DecompressStream(inStream, database, sectionPrefix + kSpanInfo));
+ section.UncompressedSize = ReadUInt64();
+ }
+
+ // read ResetTable for LZX
+ for (int mi = 0; mi < section.Methods.Size(); mi++)
+ {
+ 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();
+ if (ReadUInt32() != 8) // Size of table entry (bytes)
+ return S_FALSE;
+ if (ReadUInt32() != 0x28) // Length of table header
+ return S_FALSE;
+ rt.UncompressedSize = ReadUInt64();
+ rt.CompressedSize = ReadUInt64();
+ rt.BlockSize = ReadUInt64(); // 0x8000 block size for locations below
+ if (rt.BlockSize != 0x8000)
+ return S_FALSE;
+ rt.ResetOffsets.Reserve(numEntries);
+ for (UInt32 i = 0; i < numEntries; i++)
+ rt.ResetOffsets.Add(ReadUInt64());
+ }
+ }
+ }
+ }
+
+ database.SetIndices();
+ database.Sort();
+ return database.Check() ? S_OK : S_FALSE;
+}
+
+HRESULT CInArchive::Open2(IInStream *inStream,
+ const UInt64 *searchHeaderSizeLimit,
+ CFilesDatabase &database)
+{
+ database.Clear();
+
+ RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &_startPosition));
+
+ database.Help2Format = false;
+ const UInt32 chmVersion = 3;
+ {
+ if (!_inBuffer.Create(1 << 14))
+ return E_OUTOFMEMORY;
+ _inBuffer.SetStream(inStream);
+ _inBuffer.Init();
+ UInt64 value = 0;
+ const int kSignatureSize = 8;
+ UInt64 hxsSignature = NHeader::GetHxsSignature();
+ UInt64 chmSignature = ((UInt64)chmVersion << 32)| NHeader::kItsfSignature;
+ while(true)
+ {
+ Byte b;
+ if (!_inBuffer.ReadByte(b))
+ return S_FALSE;
+ value >>= 8;
+ value |= ((UInt64)b) << ((kSignatureSize - 1) * 8);
+ if (_inBuffer.GetProcessedSize() >= kSignatureSize)
+ {
+ if (value == chmSignature)
+ break;
+ if (value == hxsSignature)
+ {
+ database.Help2Format = true;
+ break;
+ }
+ if (searchHeaderSizeLimit != NULL)
+ if (_inBuffer.GetProcessedSize() > (*searchHeaderSizeLimit))
+ return S_FALSE;
+ }
+ }
+ _startPosition += _inBuffer.GetProcessedSize() - kSignatureSize;
+ }
+
+ if (database.Help2Format)
+ {
+ RINOK(OpenHelp2(inStream, database));
+ if (database.NewFormat)
+ return S_OK;
+ }
+ else
+ {
+ RINOK(OpenChm(inStream, database));
+ }
+
+ #ifndef CHM_LOW
+ try
+ {
+ HRESULT res = OpenHighLevel(inStream, database);
+ if (res == S_FALSE)
+ {
+ database.HighLevelClear();
+ return S_OK;
+ }
+ RINOK(res);
+ database.LowLevel = false;
+ }
+ catch(...)
+ {
+ return S_OK;
+ }
+ #endif
+ return S_OK;
+}
+
+HRESULT CInArchive::Open(IInStream *inStream,
+ const UInt64 *searchHeaderSizeLimit,
+ CFilesDatabase &database)
+{
+ try
+ {
+ HRESULT res = Open2(inStream, searchHeaderSizeLimit, database);
+ _inBuffer.ReleaseStream();
+ return res;
+ }
+ catch(...)
+ {
+ _inBuffer.ReleaseStream();
+ throw;
+ }
+}
+
+}}
diff --git a/7zip/Archive/Chm/ChmIn.h b/7zip/Archive/Chm/ChmIn.h
new file mode 100755
index 00000000..d2ddb378
--- /dev/null
+++ b/7zip/Archive/Chm/ChmIn.h
@@ -0,0 +1,242 @@
+// Archive/ChmIn.h
+
+#ifndef __ARCHIVE_CHM_IN_H
+#define __ARCHIVE_CHM_IN_H
+
+#include "Common/String.h"
+#include "Common/Buffer.h"
+#include "../../IStream.h"
+#include "../../Common/InBuffer.h"
+#include "ChmHeader.h"
+
+namespace NArchive {
+namespace NChm {
+
+struct CItem
+{
+ UInt64 Section;
+ UInt64 Offset;
+ UInt64 Size;
+ AString Name;
+
+ bool IsFormatRelatedItem() const
+ {
+ if (Name.Length() < 2)
+ return false;
+ return Name[0] == ':' && Name[1] == ':';
+ }
+
+ bool IsUserItem() const
+ {
+ if (Name.Length() < 2)
+ return false;
+ return Name[0] == '/';
+ }
+
+ bool IsDirectory() const
+ {
+ if (Name.Length() == 0)
+ return false;
+ return (Name[Name.Length() - 1] == '/');
+ }
+};
+
+struct CDatabase
+{
+ UInt64 ContentOffset;
+ CObjectVector<CItem> Items;
+ AString NewFormatString;
+ bool Help2Format;
+ bool NewFormat;
+
+ int FindItem(const AString &name) const
+ {
+ for (int i = 0; i < Items.Size(); i++)
+ if (Items[i].Name == name)
+ return i;
+ return -1;
+ }
+
+ void Clear()
+ {
+ NewFormat = false;
+ NewFormatString.Empty();
+ Help2Format = false;
+ Items.Clear();
+ }
+};
+
+struct CResetTable
+{
+ UInt64 UncompressedSize;
+ UInt64 CompressedSize;
+ UInt64 BlockSize;
+ CRecordVector<UInt64> ResetOffsets;
+ bool GetCompressedSizeOfBlocks(UInt64 blockIndex, UInt32 numBlocks, UInt64 &size) const
+ {
+ if (blockIndex >= ResetOffsets.Size())
+ return false;
+ UInt64 startPos = ResetOffsets[(size_t)blockIndex];
+ if (blockIndex + numBlocks >= ResetOffsets.Size())
+ size = CompressedSize - startPos;
+ else
+ size = ResetOffsets[(size_t)blockIndex + numBlocks] - startPos;
+ return true;
+ }
+ bool GetCompressedSizeOfBlock(UInt64 blockIndex, UInt64 &size) const
+ {
+ return GetCompressedSizeOfBlocks(blockIndex, 1, size);
+ }
+ UInt64 GetNumBlocks(UInt64 size) const
+ {
+ return (size + BlockSize - 1) / BlockSize;
+ }
+};
+
+struct CLzxInfo
+{
+ UInt32 Version;
+ UInt32 ResetInterval;
+ UInt32 WindowSize;
+ UInt32 CacheSize;
+ CResetTable ResetTable;
+
+ UInt32 GetNumDictBits() const
+ {
+ if (Version == 2 || Version == 3)
+ {
+ for (int i = 0; i <= 31; i++)
+ if (((UInt32)1 << i) >= WindowSize)
+ return 15 + i;
+ }
+ return 0;
+ }
+
+ UInt64 GetFolderSize() const { return ResetTable.BlockSize * ResetInterval; };
+ UInt64 GetFolder(UInt64 offset) const { return offset / GetFolderSize(); };
+ UInt64 GetFolderPos(UInt64 folderIndex) const { return folderIndex * GetFolderSize(); };
+ UInt64 GetBlockIndexFromFolderIndex(UInt64 folderIndex) const { return folderIndex * ResetInterval; };
+ bool GetOffsetOfFolder(UInt64 folderIndex, UInt64 &offset) const
+ {
+ UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex);
+ if (blockIndex >= ResetTable.ResetOffsets.Size())
+ return false;
+ offset = ResetTable.ResetOffsets[(size_t)blockIndex];
+ return true;
+ }
+ bool GetCompressedSizeOfFolder(UInt64 folderIndex, UInt64 &size) const
+ {
+ UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex);
+ return ResetTable.GetCompressedSizeOfBlocks(blockIndex, ResetInterval, 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<CMethodInfo> Methods;
+
+ bool IsLzx() const;
+ UString GetMethodName() const;
+};
+
+class CFilesDatabase: public CDatabase
+{
+public:
+ bool LowLevel;
+ CRecordVector<int> Indices;
+ CObjectVector<CSectionInfo> Sections;
+
+ UInt64 GetFileSize(int fileIndex) const { return Items[Indices[fileIndex]].Size; }
+ UInt64 GetFileOffset(int fileIndex) const { return Items[Indices[fileIndex]].Offset; }
+
+ UInt64 GetFolder(int fileIndex) const
+ {
+ const CItem &item = Items[Indices[fileIndex]];
+ const CSectionInfo &section = Sections[(size_t)item.Section];
+ if (section.IsLzx())
+ return section.Methods[0].LzxInfo.GetFolder(item.Offset);
+ return 0;
+ }
+
+ UInt64 GetLastFolder(int fileIndex) const
+ {
+ const CItem &item = Items[Indices[fileIndex]];
+ const CSectionInfo &section = Sections[(size_t)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();
+};
+
+class CProgressVirt
+{
+public:
+ STDMETHOD(SetTotal)(const UInt64 *numFiles) PURE;
+ STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE;
+};
+
+class CInArchive
+{
+ UInt64 _startPosition;
+ ::CInBuffer _inBuffer;
+ UInt64 _chunkSize;
+
+ Byte ReadByte();
+ void ReadBytes(Byte *data, UInt32 size);
+ void Skeep(size_t size);
+ UInt16 ReadUInt16();
+ UInt32 ReadUInt32();
+ UInt64 ReadUInt64();
+ UInt64 ReadEncInt();
+ void ReadString(int size, AString &s);
+ void ReadUString(int 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:
+ 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 --git a/7zip/Archive/Chm/DllExports.cpp b/7zip/Archive/Chm/DllExports.cpp
new file mode 100755
index 00000000..edc87a8c
--- /dev/null
+++ b/7zip/Archive/Chm/DllExports.cpp
@@ -0,0 +1,77 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+#include "ChmHandler.h"
+#include "../../ICoder.h"
+
+// {23170F69-40C1-278A-1000-000110E90000}
+DEFINE_GUID(CLSID_CChmHandler,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xE9, 0x00, 0x00);
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ return TRUE;
+}
+
+STDAPI CreateObject(
+ const GUID *classID,
+ const GUID *interfaceID,
+ void **outObject)
+{
+ COM_TRY_BEGIN
+ *outObject = 0;
+ if (*classID != CLSID_CChmHandler)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ if (*interfaceID != IID_IInArchive)
+ return E_NOINTERFACE;
+ CMyComPtr<IInArchive> inArchive = (IInArchive *)new NArchive::NChm::CHandler;
+ *outObject = inArchive.Detach();
+ COM_TRY_END
+ return S_OK;
+}
+
+STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
+{
+ NWindows::NCOM::CPropVariant propVariant;
+ switch(propID)
+ {
+ case NArchive::kName:
+ propVariant = L"Chm";
+ break;
+ case NArchive::kClassID:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CChmHandler, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NArchive::kExtension:
+ propVariant = L"chm chi chq chw hxs hxi hxr hxq hxw lit";
+ break;
+ case NArchive::kUpdate:
+ propVariant = false;
+ break;
+ case NArchive::kKeepName:
+ propVariant = false;
+ break;
+ case NArchive::kStartSignature:
+ {
+ const char sig[] = { 'I', 'T', 'S', 'F' };
+ if ((value->bstrVal = ::SysAllocStringByteLen(sig, 4)) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NArchive::kAssociate:
+ {
+ propVariant = false;
+ break;
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/7zip/Archive/Chm/StdAfx.cpp b/7zip/Archive/Chm/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/7zip/Archive/Chm/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/7zip/Archive/Chm/StdAfx.h b/7zip/Archive/Chm/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/7zip/Archive/Chm/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/7zip/Archive/Chm/makefile b/7zip/Archive/Chm/makefile
new file mode 100755
index 00000000..4adce2f5
--- /dev/null
+++ b/7zip/Archive/Chm/makefile
@@ -0,0 +1,68 @@
+PROG = chm.dll
+DEF_FILE = ../Archive.def
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib user32.lib
+
+CHM_OBJS = \
+ $O\DllExports.obj \
+ $O\ChmHandler.obj \
+ $O\ChmHeader.obj \
+ $O\ChmIn.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\IntToString.obj \
+ $O\NewHandler.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\UTFConvert.obj \
+ $O\Vector.obj \
+
+WIN_OBJS = \
+ $O\PropVariant.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\InBuffer.obj \
+ $O\LimitedStreams.obj \
+ $O\OutBuffer.obj \
+ $O\ProgressUtils.obj \
+ $O\StreamUtils.obj \
+
+AR_COMMON_OBJS = \
+ $O\ItemNameUtils.obj \
+
+COMPRESS_LZX_OBJS = \
+ $O\LzxDecoder.obj \
+ $O\Lzx86Converter.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(CHM_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $(COMPRESS_LZX_OBJS) \
+ $O\LZOutWindow.obj \
+ $O\CopyCoder.obj \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(CHM_OBJS): $(*B).cpp
+ $(COMPL)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$(AR_COMMON_OBJS): ../Common/$(*B).cpp
+ $(COMPL)
+$(COMPRESS_LZX_OBJS): ../../Compress/Lzx/$(*B).cpp
+ $(COMPL_O2)
+$O\LZOutWindow.obj: ../../Compress/LZ/$(*B).cpp
+ $(COMPL)
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
+
diff --git a/7zip/Archive/Chm/resource.rc b/7zip/Archive/Chm/resource.rc
new file mode 100755
index 00000000..fc93ae4f
--- /dev/null
+++ b/7zip/Archive/Chm/resource.rc
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("Chm Plugin", "chm")
diff --git a/7zip/Archive/Common/DummyOutStream.cpp b/7zip/Archive/Common/DummyOutStream.cpp
index f188ac05..b1d49913 100755
--- a/7zip/Archive/Common/DummyOutStream.cpp
+++ b/7zip/Archive/Common/DummyOutStream.cpp
@@ -18,13 +18,3 @@ STDMETHODIMP CDummyOutStream::Write(const void *data,
*processedSize = size;
return S_OK;
}
-
-STDMETHODIMP CDummyOutStream::WritePart(const void *data,
- UInt32 size, UInt32 *processedSize)
-{
- if(m_Stream)
- return m_Stream->WritePart(data, size, processedSize);
- if(processedSize != NULL)
- *processedSize = size;
- return S_OK;
-}
diff --git a/7zip/Archive/Common/DummyOutStream.h b/7zip/Archive/Common/DummyOutStream.h
index 2e66cd3d..51690787 100755
--- a/7zip/Archive/Common/DummyOutStream.h
+++ b/7zip/Archive/Common/DummyOutStream.h
@@ -14,7 +14,6 @@ public:
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
private:
CMyComPtr<ISequentialOutStream> m_Stream;
public:
diff --git a/7zip/Archive/Common/FilterCoder.cpp b/7zip/Archive/Common/FilterCoder.cpp
index 3a7a95b6..1ad0f5de 100755
--- a/7zip/Archive/Common/FilterCoder.cpp
+++ b/7zip/Archive/Common/FilterCoder.cpp
@@ -5,6 +5,7 @@
#include "FilterCoder.h"
#include "../../../Common/Alloc.h"
#include "../../../Common/Defs.h"
+#include "../../Common/StreamUtils.h"
static const int kBufferSize = 1 << 17;
@@ -27,7 +28,7 @@ HRESULT CFilterCoder::WriteWithLimit(ISequentialOutStream *outStream, UInt32 siz
size = (UInt32)remSize;
}
UInt32 processedSize = 0;
- RINOK(outStream->Write(_buffer, size, &processedSize));
+ RINOK(WriteStream(outStream, _buffer, size, &processedSize));
if (size != processedSize)
return E_FAIL;
_nowPos64 += processedSize;
@@ -47,8 +48,10 @@ STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream,
while(NeedMore())
{
UInt32 processedSize;
- UInt32 size = kBufferSize - bufferPos;
- RINOK(inStream->Read(_buffer + bufferPos, size, &processedSize));
+
+ // Change it: It can be optimized using ReadPart
+ RINOK(ReadStream(inStream, _buffer + bufferPos, kBufferSize - bufferPos, &processedSize));
+
UInt32 endPos = bufferPos + processedSize;
bufferPos = Filter->Filter(_buffer, endPos);
@@ -131,11 +134,6 @@ STDMETHODIMP CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processe
return S_OK;
}
-STDMETHODIMP CFilterCoder::WritePart(const void *data, UInt32 size, UInt32 *processedSize)
-{
- return Write(data, size, processedSize);
-}
-
STDMETHODIMP CFilterCoder::Flush()
{
if (_bufferPos != 0)
@@ -149,7 +147,7 @@ STDMETHODIMP CFilterCoder::Flush()
return E_FAIL;
}
UInt32 processedSize;
- RINOK(_outStream->Write(_buffer, _bufferPos, &processedSize));
+ RINOK(WriteStream(_outStream, _buffer, _bufferPos, &processedSize));
if (_bufferPos != processedSize)
return E_FAIL;
_bufferPos = 0;
@@ -189,7 +187,7 @@ STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize)
data = (void *)((Byte *)data + sizeTemp);
size -= sizeTemp;
processedSizeTotal += sizeTemp;
- continue;
+ break;
}
int i;
for (i = 0; _convertedPosEnd + i < _bufferPos; i++)
@@ -198,7 +196,8 @@ STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize)
_convertedPosBegin = _convertedPosEnd = 0;
UInt32 processedSizeTemp;
UInt32 size0 = kBufferSize - _bufferPos;
- RINOK(_inStream->Read(_buffer + _bufferPos, size0, &processedSizeTemp));
+ // Optimize it:
+ RINOK(ReadStream(_inStream, _buffer + _bufferPos, size0, &processedSizeTemp));
_bufferPos = _bufferPos + processedSizeTemp;
_convertedPosEnd = Filter->Filter(_buffer, _bufferPos);
if (_convertedPosEnd == 0)
@@ -217,11 +216,6 @@ STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize)
return S_OK;
}
-STDMETHODIMP CFilterCoder::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
-{
- return Read(data, size, processedSize);
-}
-
// #endif // _ST_MODE
#ifndef _NO_CRYPTO
diff --git a/7zip/Archive/Common/FilterCoder.h b/7zip/Archive/Common/FilterCoder.h
index a37e7715..4db7f28a 100755
--- a/7zip/Archive/Common/FilterCoder.h
+++ b/7zip/Archive/Common/FilterCoder.h
@@ -94,11 +94,9 @@ public:
STDMETHOD(ReleaseInStream)();
STDMETHOD(SetInStream)(ISequentialInStream *inStream);
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); \
- STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); \
STDMETHOD(SetOutStream)(ISequentialOutStream *outStream);
STDMETHOD(ReleaseOutStream)();
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Flush)();
// #endif
diff --git a/7zip/Archive/Common/InStreamWithCRC.cpp b/7zip/Archive/Common/InStreamWithCRC.cpp
index e1b98383..86151b9d 100755
--- a/7zip/Archive/Common/InStreamWithCRC.cpp
+++ b/7zip/Archive/Common/InStreamWithCRC.cpp
@@ -16,18 +16,6 @@ STDMETHODIMP CSequentialInStreamWithCRC::Read(void *data,
return result;
}
-STDMETHODIMP CSequentialInStreamWithCRC::ReadPart(void *data,
- UInt32 size, UInt32 *processedSize)
-{
- UInt32 realProcessedSize;
- HRESULT result = _stream->ReadPart(data, size, &realProcessedSize);
- _size += realProcessedSize;
- _crc.Update(data, realProcessedSize);
- if(processedSize != NULL)
- *processedSize = realProcessedSize;
- return result;
-}
-
STDMETHODIMP CInStreamWithCRC::Read(void *data,
UInt32 size, UInt32 *processedSize)
{
@@ -40,18 +28,6 @@ STDMETHODIMP CInStreamWithCRC::Read(void *data,
return result;
}
-STDMETHODIMP CInStreamWithCRC::ReadPart(void *data,
- UInt32 size, UInt32 *processedSize)
-{
- UInt32 realProcessedSize;
- HRESULT result = _stream->ReadPart(data, size, &realProcessedSize);
- _size += realProcessedSize;
- _crc.Update(data, realProcessedSize);
- if(processedSize != NULL)
- *processedSize = realProcessedSize;
- return result;
-}
-
STDMETHODIMP CInStreamWithCRC::Seek(Int64 offset,
UInt32 seekOrigin, UInt64 *newPosition)
{
diff --git a/7zip/Archive/Common/InStreamWithCRC.h b/7zip/Archive/Common/InStreamWithCRC.h
index 112af5d0..9628a6f2 100755
--- a/7zip/Archive/Common/InStreamWithCRC.h
+++ b/7zip/Archive/Common/InStreamWithCRC.h
@@ -15,7 +15,6 @@ public:
MY_UNKNOWN_IMP
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
private:
CMyComPtr<ISequentialInStream> _stream;
UInt64 _size;
@@ -40,7 +39,6 @@ public:
MY_UNKNOWN_IMP
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
private:
CMyComPtr<IInStream> _stream;
diff --git a/7zip/Archive/Common/MultiStream.cpp b/7zip/Archive/Common/MultiStream.cpp
index cdcb8886..7ef4f155 100755
--- a/7zip/Archive/Common/MultiStream.cpp
+++ b/7zip/Archive/Common/MultiStream.cpp
@@ -28,17 +28,11 @@ STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
_pos += realProcessed;
_seekPos += realProcessed;
RINOK(result);
- if (realProcessed == 0)
- break;
+ break;
}
return S_OK;
}
-STDMETHODIMP CMultiStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
-{
- return Read(data, size, processedSize);
-}
-
STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin,
UInt64 *newPosition)
{
@@ -113,7 +107,6 @@ public:
HRESULT Flush();
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
};
HRESULT COutVolumeStream::Flush()
@@ -179,17 +172,12 @@ STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *proce
_streamIndex++;
_offsetPos = 0;
}
- if (realProcessed != curSize)
+ if (realProcessed != curSize && realProcessed == 0)
return E_FAIL;
}
return S_OK;
}
-STDMETHODIMP COutMultiStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize)
-{
- return Write(data, size, processedSize);
-}
-
STDMETHODIMP COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
if(seekOrigin >= 3)
diff --git a/7zip/Archive/Common/MultiStream.h b/7zip/Archive/Common/MultiStream.h
index b6e2abc5..5a7cc687 100755
--- a/7zip/Archive/Common/MultiStream.h
+++ b/7zip/Archive/Common/MultiStream.h
@@ -36,7 +36,6 @@ public:
MY_UNKNOWN_IMP1(IInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
};
@@ -70,7 +69,6 @@ public:
MY_UNKNOWN_IMP1(IOutStream)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
};
*/
diff --git a/7zip/Archive/Common/OutStreamWithCRC.cpp b/7zip/Archive/Common/OutStreamWithCRC.cpp
index ae832eef..4fbce564 100755
--- a/7zip/Archive/Common/OutStreamWithCRC.cpp
+++ b/7zip/Archive/Common/OutStreamWithCRC.cpp
@@ -7,24 +7,6 @@
STDMETHODIMP COutStreamWithCRC::Write(const void *data,
UInt32 size, UInt32 *processedSize)
{
- HRESULT result;
- UInt32 realProcessedSize;
- 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;
-}
-
-STDMETHODIMP COutStreamWithCRC::WritePart(const void *data,
- UInt32 size, UInt32 *processedSize)
-{
UInt32 realProcessedSize;
HRESULT result;
if(!_stream)
@@ -33,7 +15,7 @@ STDMETHODIMP COutStreamWithCRC::WritePart(const void *data,
result = S_OK;
}
else
- result = _stream->WritePart(data, size, &realProcessedSize);
+ result = _stream->Write(data, size, &realProcessedSize);
_crc.Update(data, realProcessedSize);
if(processedSize != NULL)
*processedSize = realProcessedSize;
diff --git a/7zip/Archive/Common/OutStreamWithCRC.h b/7zip/Archive/Common/OutStreamWithCRC.h
index 2668885c..23c69e04 100755
--- a/7zip/Archive/Common/OutStreamWithCRC.h
+++ b/7zip/Archive/Common/OutStreamWithCRC.h
@@ -15,7 +15,6 @@ public:
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
private:
CCRC _crc;
CMyComPtr<ISequentialOutStream> _stream;
diff --git a/7zip/Archive/Cpio/makefile b/7zip/Archive/Cpio/makefile
index 6c5fb3f4..d7760281 100755
--- a/7zip/Archive/Cpio/makefile
+++ b/7zip/Archive/Cpio/makefile
@@ -14,6 +14,7 @@ COMMON_OBJS = \
$O\NewHandler.obj \
$O\String.obj \
$O\StringConvert.obj \
+ $O\StringToInt.obj \
$O\Vector.obj \
WIN_OBJS = \
@@ -22,6 +23,7 @@ WIN_OBJS = \
7ZIP_COMMON_OBJS = \
$O\LimitedStreams.obj \
$O\ProgressUtils.obj \
+ $O\StreamUtils.obj \
AR_COMMON_OBJS = \
$O\ItemNameUtils.obj \
diff --git a/7zip/Archive/Deb/Deb.dsp b/7zip/Archive/Deb/Deb.dsp
index 42f354a7..56689305 100755
--- a/7zip/Archive/Deb/Deb.dsp
+++ b/7zip/Archive/Deb/Deb.dsp
@@ -154,6 +154,14 @@ 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\Vector.cpp
# End Source File
# Begin Source File
@@ -248,6 +256,14 @@ SOURCE=..\..\Common\ProgressUtils.cpp
SOURCE=..\..\Common\ProgressUtils.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
# End Target
# End Project
diff --git a/7zip/Archive/Deb/DebIn.cpp b/7zip/Archive/Deb/DebIn.cpp
index 55f1e034..4900517b 100755
--- a/7zip/Archive/Deb/DebIn.cpp
+++ b/7zip/Archive/Deb/DebIn.cpp
@@ -5,8 +5,11 @@
#include "DebIn.h"
#include "DebHeader.h"
+#include "Common/StringToInt.h"
#include "Windows/Defs.h"
+#include "../../Common/StreamUtils.h"
+
namespace NArchive {
namespace NDeb {
@@ -14,7 +17,7 @@ using namespace NHeader;
HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
{
- RINOK(m_Stream->Read(data, size, &processedSize));
+ RINOK(ReadStream(m_Stream, data, size, &processedSize));
m_Position += processedSize;
return S_OK;
}
@@ -24,7 +27,7 @@ HRESULT CInArchive::Open(IInStream *inStream)
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position));
char signature[kSignatureLen];
UInt32 processedSize;
- RINOK(inStream->Read(signature, kSignatureLen, &processedSize));
+ RINOK(ReadStream(inStream, signature, kSignatureLen, &processedSize));
m_Position += processedSize;
if (processedSize != kSignatureLen)
return S_FALSE;
@@ -34,40 +37,50 @@ HRESULT CInArchive::Open(IInStream *inStream)
return S_OK;
}
-static bool CheckString(const char *srcString, int numChars, int radix)
+static bool OctalToNumber(const char *s, int size, UInt64 &res)
{
- for(int i = 0; i < numChars; i++)
- {
- char c = srcString[i];
- if (c == 0)
- return true;
- if (c >= '0' && c <= '0' + radix - 1)
- continue;
- if (c != ' ')
- return false;
- }
- return true;
+ char sz[32];
+ strncpy(sz, s, size);
+ sz[size] = 0;
+ const char *end;
+ int i;
+ for (i = 0; sz[i] == ' '; i++);
+ res = ConvertOctStringToUInt64(sz + i, &end);
+ return (*end == ' ' || *end == 0);
+}
+
+static bool OctalToNumber32(const char *s, int size, UInt32 &res)
+{
+ UInt64 res64;
+ if (!OctalToNumber(s, size, res64))
+ return false;
+ res = (UInt32)res64;
+ return (res64 <= 0xFFFFFFFF);
}
-static bool CheckOctalString(const char *srcString, int numChars)
- { return CheckString(srcString, numChars, 8); }
-static bool CheckDecimalString(const char *srcString, int numChars)
- { return CheckString(srcString, numChars, 10); }
-#define ReturnIfBadOctal(x, y) { if (!CheckOctalString((x), (y))) return S_FALSE; }
-#define ReturnIfBadDecimal(x, y) { if (!CheckDecimalString((x), (y))) return S_FALSE; }
+static bool DecimalToNumber(const char *s, int size, UInt64 &res)
+{
+ char sz[32];
+ strncpy(sz, s, size);
+ sz[size] = 0;
+ const char *end;
+ int i;
+ for (i = 0; sz[i] == ' '; i++);
+ res = ConvertStringToUInt64(sz + i, &end);
+ return (*end == ' ' || *end == 0);
+}
-static UInt32 StringToNumber(const char *srcString, int numChars, int radix)
+static bool DecimalToNumber32(const char *s, int size, UInt32 &res)
{
- AString modString;
- for (int i = 0; i < numChars; i++)
- modString += srcString[i];
- char *endPtr;
- return strtoul(modString, &endPtr, radix);
+ UInt64 res64;
+ if (!DecimalToNumber(s, size, res64))
+ return false;
+ res = (UInt32)res64;
+ return (res64 <= 0xFFFFFFFF);
}
-static UInt32 OctalToNumber(const char *srcString, int numChars)
- { return StringToNumber(srcString, numChars, 8); }
-static UInt32 DecimalToNumber(const char *srcString, int numChars)
- { return StringToNumber(srcString, numChars, 10); }
+
+#define RIF(x) { if (!(x)) return S_FALSE; }
+
HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item)
{
@@ -93,18 +106,15 @@ HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item)
if (((Byte)item.Name[i]) < 0x20)
return S_FALSE;
- ReturnIfBadDecimal(cur, kTimeSize);
- item.ModificationTime = DecimalToNumber(cur, kTimeSize);
+ RIF(DecimalToNumber32(cur, kTimeSize, item.ModificationTime));
cur += kTimeSize;
cur += 6 + 6;
- ReturnIfBadOctal(cur, kModeSize);
- item.Mode = OctalToNumber(cur, kModeSize);
+ RIF(OctalToNumber32(cur, kModeSize, item.Mode));
cur += kModeSize;
- ReturnIfBadDecimal(cur, kSizeSize);
- item.Size = DecimalToNumber(cur, kSizeSize);
+ RIF(DecimalToNumber(cur, kSizeSize, item.Size));
cur += kSizeSize;
filled = true;
diff --git a/7zip/Archive/Deb/DllExports.cpp b/7zip/Archive/Deb/DllExports.cpp
index 66bf7c38..cb314000 100755
--- a/7zip/Archive/Deb/DllExports.cpp
+++ b/7zip/Archive/Deb/DllExports.cpp
@@ -8,9 +8,9 @@
#include "DebHandler.h"
#include "../../ICoder.h"
-// {23170F69-40C1-278A-1000-0001100C0000}
+// {23170F69-40C1-278A-1000-000110EC0000}
DEFINE_GUID(CLSID_CDebHandler,
- 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x0C, 0x00, 0x00);
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xEC, 0x00, 0x00);
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
diff --git a/7zip/Archive/Deb/makefile b/7zip/Archive/Deb/makefile
index 8cff91a2..a74f33de 100755
--- a/7zip/Archive/Deb/makefile
+++ b/7zip/Archive/Deb/makefile
@@ -14,6 +14,7 @@ COMMON_OBJS = \
$O\NewHandler.obj \
$O\String.obj \
$O\StringConvert.obj \
+ $O\StringToInt.obj \
$O\Vector.obj \
WIN_OBJS = \
@@ -22,6 +23,7 @@ WIN_OBJS = \
7ZIP_COMMON_OBJS = \
$O\LimitedStreams.obj \
$O\ProgressUtils.obj \
+ $O\StreamUtils.obj \
AR_COMMON_OBJS = \
$O\ItemNameUtils.obj \
diff --git a/7zip/Archive/GZip/DllExports.cpp b/7zip/Archive/GZip/DllExports.cpp
index 4a0aca73..2b32f16b 100755
--- a/7zip/Archive/GZip/DllExports.cpp
+++ b/7zip/Archive/GZip/DllExports.cpp
@@ -8,9 +8,9 @@
#include "../../ICoder.h"
#include "GZipHandler.h"
-// {23170F69-40C1-278A-1000-000110030000}
+// {23170F69-40C1-278A-1000-000110EF0000}
DEFINE_GUID(CLSID_CGZipHandler,
-0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x03, 0x00, 0x00);
+0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xEF, 0x00, 0x00);
// {23170F69-40C1-278B-0401-080000000100}
DEFINE_GUID(CLSID_CCompressDeflateEncoder,
diff --git a/7zip/Archive/GZip/GZip.dsp b/7zip/Archive/GZip/GZip.dsp
index aa880e63..4507e833 100755
--- a/7zip/Archive/GZip/GZip.dsp
+++ b/7zip/Archive/GZip/GZip.dsp
@@ -264,6 +264,14 @@ SOURCE=..\..\Common\ProgressUtils.cpp
SOURCE=..\..\Common\ProgressUtils.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 "Archive Common"
diff --git a/7zip/Archive/GZip/GZipHandler.cpp b/7zip/Archive/GZip/GZipHandler.cpp
index f3d0d065..e234e96d 100755
--- a/7zip/Archive/GZip/GZipHandler.cpp
+++ b/7zip/Archive/GZip/GZipHandler.cpp
@@ -58,12 +58,14 @@ static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
static const wchar_t *kUnknownOS = L"Unknown";
+/*
enum // PropID
{
- // kpidExtraIsPresent = kpidUserDefined,
- // kpidExtraFlags,
- // kpidIsText
+ kpidExtraIsPresent = kpidUserDefined,
+ kpidExtraFlags,
+ kpidIsText
};
+*/
STATPROPSTG kProperties[] =
{
diff --git a/7zip/Archive/GZip/GZipIn.cpp b/7zip/Archive/GZip/GZipIn.cpp
index 69270fb1..d36ce5d0 100755
--- a/7zip/Archive/GZip/GZipIn.cpp
+++ b/7zip/Archive/GZip/GZipIn.cpp
@@ -8,13 +8,15 @@
#include "Common/MyCom.h"
#include "Windows/Defs.h"
+#include "../../Common/StreamUtils.h"
+
namespace NArchive {
namespace NGZip {
HRESULT CInArchive::ReadBytes(ISequentialInStream *inStream, void *data, UInt32 size)
{
UInt32 realProcessedSize;
- RINOK(inStream->Read(data, size, &realProcessedSize));
+ RINOK(ReadStream(inStream, data, size, &realProcessedSize));
m_Position += realProcessedSize;
if(realProcessedSize != size)
return S_FALSE;
diff --git a/7zip/Archive/GZip/GZipOut.cpp b/7zip/Archive/GZip/GZipOut.cpp
index e88ede19..99b08319 100755
--- a/7zip/Archive/GZip/GZipOut.cpp
+++ b/7zip/Archive/GZip/GZipOut.cpp
@@ -5,6 +5,7 @@
#include "GZipOut.h"
#include "Common/CRC.h"
#include "Windows/Defs.h"
+#include "../../Common/StreamUtils.h"
namespace NArchive {
namespace NGZip {
@@ -12,7 +13,7 @@ namespace NGZip {
HRESULT COutArchive::WriteBytes(const void *buffer, UInt32 size)
{
UInt32 processedSize;
- RINOK(m_Stream->Write(buffer, size, &processedSize));
+ RINOK(WriteStream(m_Stream, buffer, size, &processedSize));
if(processedSize != size)
return E_FAIL;
return S_OK;
diff --git a/7zip/Archive/GZip/makefile b/7zip/Archive/GZip/makefile
index 3c1c94a5..06d8908d 100755
--- a/7zip/Archive/GZip/makefile
+++ b/7zip/Archive/GZip/makefile
@@ -26,6 +26,7 @@ WIN_OBJS = \
7ZIP_COMMON_OBJS = \
$O\ProgressUtils.obj \
+ $O\StreamUtils.obj \
AR_COMMON_OBJS = \
$O\CodecsPath.obj \
diff --git a/7zip/Archive/IArchive.h b/7zip/Archive/IArchive.h
index 9c74b1bf..d6cbe804 100755
--- a/7zip/Archive/IArchive.h
+++ b/7zip/Archive/IArchive.h
@@ -7,6 +7,14 @@
#include "../IProgress.h"
#include "../PropID.h"
+// MIDL_INTERFACE("23170F69-40C1-278A-0000-000600xx0000")
+#define ARCHIVE_INTERFACE_SUB(i, base, x) \
+DEFINE_GUID(IID_ ## i, \
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x06, 0x00, x, 0x00, 0x00); \
+struct i: public base
+
+#define ARCHIVE_INTERFACE(i, x) ARCHIVE_INTERFACE_SUB(i, IUnknown, x)
+
namespace NFileTimeType
{
enum EEnum
@@ -29,6 +37,7 @@ namespace NArchive
kKeepName,
kStartSignature,
kFinishSignature,
+ kAssociate
};
namespace NExtract
@@ -66,24 +75,15 @@ namespace NArchive
}
}
-// {23170F69-40C1-278A-0000-000100010000}
-DEFINE_GUID(IID_IArchiveOpenCallback,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000100010000")
-IArchiveOpenCallback: public IUnknown
+ARCHIVE_INTERFACE(IArchiveOpenCallback, 0x10)
{
-public:
STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes) PURE;
STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes) PURE;
};
-// {23170F69-40C1-278A-0000-000100090000}
-DEFINE_GUID(IID_IArchiveExtractCallback,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000100090000")
-IArchiveExtractCallback: public IProgress
+
+ARCHIVE_INTERFACE_SUB(IArchiveExtractCallback, IProgress, 0x20)
{
-public:
STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream,
Int32 askExtractMode) PURE;
// GetStream OUT: S_OK - OK, S_FALSE - skeep this file
@@ -92,36 +92,27 @@ public:
};
-// {23170F69-40C1-278A-0000-0001000D0000}
-DEFINE_GUID(IID_IArchiveOpenVolumeCallback,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0D, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-0001000D0000")
-IArchiveOpenVolumeCallback: public IUnknown
+ARCHIVE_INTERFACE(IArchiveOpenVolumeCallback, 0x30)
{
-public:
STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) PURE;
STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) PURE;
};
-// {23170F69-40C1-278A-0000-0001000D0100}
-DEFINE_GUID(IID_IArchiveOpenSetSubArchiveName,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0D, 0x01, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-0001000D0100")
-IArchiveOpenSetSubArchiveName: public IUnknown
+ARCHIVE_INTERFACE(IInArchiveGetStream, 0x40)
+{
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) PURE;
+};
+
+
+ARCHIVE_INTERFACE(IArchiveOpenSetSubArchiveName, 0x50)
{
-public:
STDMETHOD(SetSubArchiveName)(const wchar_t *name) PURE;
};
-// {23170F69-40C1-278A-0000-000100080000}
-DEFINE_GUID(IID_IInArchive,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000100080000")
-IInArchive: public IUnknown
+ARCHIVE_INTERFACE(IInArchive, 0x60)
{
-public:
STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openArchiveCallback) PURE;
STDMETHOD(Close)() PURE;
@@ -129,6 +120,9 @@ public:
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE;
STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback) PURE;
+ // indices must be sorted
+ // numItems = 0xFFFFFFFF means all files
+ // testMode != 0 means "test files operation"
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) PURE;
@@ -141,25 +135,9 @@ public:
BSTR *name, PROPID *propID, VARTYPE *varType) PURE;
};
-// {23170F69-40C1-278A-0000-000100080100}
-DEFINE_GUID(IID_IInArchiveGetStream,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x01, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000100080100")
-IInArchiveGetStream: public IUnknown
-{
-public:
- STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) PURE;
-};
-
-// {23170F69-40C1-278A-0000-000100040000}
-DEFINE_GUID(IID_IArchiveUpdateCallback,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000100040000")
-IArchiveUpdateCallback: public IProgress
+ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback, IProgress, 0x80)
{
-public:
- // STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator) PURE;
STDMETHOD(GetUpdateItemInfo)(UInt32 index,
Int32 *newData, // 1 - new data, 0 - old data
Int32 *newProperties, // 1 - new properties, 0 - old properties
@@ -170,33 +148,23 @@ public:
STDMETHOD(SetOperationResult)(Int32 operationResult) PURE;
};
-// {23170F69-40C1-278A-0000-000100040002}
-DEFINE_GUID(IID_IArchiveUpdateCallback2,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000100040002")
-IArchiveUpdateCallback2: public IArchiveUpdateCallback
+
+ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82)
{
-public:
STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size) PURE;
STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream) PURE;
};
-// {23170F69-40C1-278A-0000-000100020000}
-DEFINE_GUID(IID_IOutArchive,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000100020000")
-IOutArchive: public IUnknown
+
+ARCHIVE_INTERFACE(IOutArchive, 0xA0)
{
STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems,
IArchiveUpdateCallback *updateCallback) PURE;
STDMETHOD(GetFileTimeType)(UInt32 *type) PURE;
};
-// {23170F69-40C1-278A-0000-000100030000}
-DEFINE_GUID(IID_ISetProperties,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000100030000")
-ISetProperties: public IUnknown
+
+ARCHIVE_INTERFACE(ISetProperties, 0x03)
{
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) PURE;
};
diff --git a/7zip/Archive/Lzh/DllExports.cpp b/7zip/Archive/Lzh/DllExports.cpp
index 567d4bf8..ee5006f3 100755
--- a/7zip/Archive/Lzh/DllExports.cpp
+++ b/7zip/Archive/Lzh/DllExports.cpp
@@ -8,9 +8,9 @@
#include "../../ICoder.h"
#include "LzhHandler.h"
-// {23170F69-40C1-278A-1000-0001100E0000}
+// {23170F69-40C1-278A-1000-000110060000}
DEFINE_GUID(CLSID_CLzhHandler,
- 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x0E, 0x00, 0x00);
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x06, 0x00, 0x00);
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
diff --git a/7zip/Archive/Lzh/Lzh.dsp b/7zip/Archive/Lzh/Lzh.dsp
index 9f5b21b0..ad00699c 100755
--- a/7zip/Archive/Lzh/Lzh.dsp
+++ b/7zip/Archive/Lzh/Lzh.dsp
@@ -290,12 +290,28 @@ SOURCE=..\..\Common\MSBFDecoder.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\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
# End Group
# Begin Group "Archive Common"
diff --git a/7zip/Archive/Lzh/LzhIn.cpp b/7zip/Archive/Lzh/LzhIn.cpp
index f9b5daff..5344ef13 100755
--- a/7zip/Archive/Lzh/LzhIn.cpp
+++ b/7zip/Archive/Lzh/LzhIn.cpp
@@ -1,4 +1,4 @@
-/ Archive/arj/InEngine.cpp
+// Archive/arj/InEngine.cpp
#include "StdAfx.h"
@@ -6,6 +6,8 @@
#include "Common/Buffer.h"
#include "Common/CRC.h"
+#include "../../Common/StreamUtils.h"
+
#include "LzhIn.h"
namespace NArchive {
@@ -13,7 +15,7 @@ namespace NLzh {
HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
{
- RINOK(m_Stream->Read(data, size, &processedSize));
+ RINOK(ReadStream(m_Stream, data, size, &processedSize));
m_Position += processedSize;
return S_OK;
}
diff --git a/7zip/Archive/Lzh/LzhItem.h b/7zip/Archive/Lzh/LzhItem.h
index 36ccb672..b9b5f914 100755
--- a/7zip/Archive/Lzh/LzhItem.h
+++ b/7zip/Archive/Lzh/LzhItem.h
@@ -115,7 +115,14 @@ public:
{
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 = data[0] |
((UInt32)data[1] << 8) |
diff --git a/7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp b/7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp
index ddefec88..2281a884 100755
--- a/7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp
+++ b/7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp
@@ -7,26 +7,7 @@
namespace NArchive {
namespace NLzh {
-STDMETHODIMP COutStreamWithCRC::Write(const void *data,
- UInt32 size, UInt32 *processedSize)
-{
- HRESULT result;
- UInt32 realProcessedSize;
- 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;
-}
-
-STDMETHODIMP COutStreamWithCRC::WritePart(const void *data,
- UInt32 size, UInt32 *processedSize)
+STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessedSize;
HRESULT result;
@@ -36,7 +17,7 @@ STDMETHODIMP COutStreamWithCRC::WritePart(const void *data,
result = S_OK;
}
else
- result = _stream->WritePart(data, size, &realProcessedSize);
+ result = _stream->Write(data, size, &realProcessedSize);
_crc.Update(data, realProcessedSize);
if(processedSize != NULL)
*processedSize = realProcessedSize;
diff --git a/7zip/Archive/Lzh/LzhOutStreamWithCRC.h b/7zip/Archive/Lzh/LzhOutStreamWithCRC.h
index fc5fc1c9..31b536b7 100755
--- a/7zip/Archive/Lzh/LzhOutStreamWithCRC.h
+++ b/7zip/Archive/Lzh/LzhOutStreamWithCRC.h
@@ -18,7 +18,6 @@ public:
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
private:
CCRC _crc;
CMyComPtr<ISequentialOutStream> _stream;
diff --git a/7zip/Archive/Lzh/makefile b/7zip/Archive/Lzh/makefile
index caa61334..6f8fd2a0 100755
--- a/7zip/Archive/Lzh/makefile
+++ b/7zip/Archive/Lzh/makefile
@@ -23,7 +23,9 @@ WIN_OBJS = \
7ZIP_COMMON_OBJS = \
$O\InBuffer.obj \
$O\LimitedStreams.obj \
+ $O\OutBuffer.obj \
$O\ProgressUtils.obj \
+ $O\StreamUtils.obj \
AR_COMMON_OBJS = \
$O\ItemNameUtils.obj \
diff --git a/7zip/Archive/RPM/DllExports.cpp b/7zip/Archive/RPM/DllExports.cpp
index d712abfe..2319857c 100755
--- a/7zip/Archive/RPM/DllExports.cpp
+++ b/7zip/Archive/RPM/DllExports.cpp
@@ -8,9 +8,9 @@
#include "../../ICoder.h"
#include "RpmHandler.h"
-// {23170F69-40C1-278A-1000-000110090000}
+// {23170F69-40C1-278A-1000-000110EB0000}
DEFINE_GUID(CLSID_CRpmHandler,
- 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x09, 0x00, 0x00);
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xEB, 0x00, 0x00);
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
diff --git a/7zip/Archive/RPM/Rpm.dsp b/7zip/Archive/RPM/Rpm.dsp
index e0a828b3..085fe137 100755
--- a/7zip/Archive/RPM/Rpm.dsp
+++ b/7zip/Archive/RPM/Rpm.dsp
@@ -140,6 +140,14 @@ SOURCE=..\..\Common\ProgressUtils.cpp
SOURCE=..\..\Common\ProgressUtils.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 "Compress"
diff --git a/7zip/Archive/RPM/RpmIn.cpp b/7zip/Archive/RPM/RpmIn.cpp
index 9b48a0ae..03373d9c 100755
--- a/7zip/Archive/RPM/RpmIn.cpp
+++ b/7zip/Archive/RPM/RpmIn.cpp
@@ -9,6 +9,8 @@
#include "Windows/Defs.h"
#include "Common/MyCom.h"
+#include "../../Common/StreamUtils.h"
+
namespace NArchive {
namespace NRpm {
@@ -31,7 +33,7 @@ static HRESULT RedSigHeaderSig(IInStream *inStream, CSigHeaderSig &h)
char dat[kCSigHeaderSigSize];
char *cur = dat;
UInt32 processedSize;
- RINOK(inStream->Read(dat, kCSigHeaderSigSize, &processedSize));
+ RINOK(ReadStream(inStream, dat, kCSigHeaderSigSize, &processedSize));
if (kCSigHeaderSigSize != processedSize)
return S_FALSE;
memmove(h.Magic, cur, 4);
@@ -50,7 +52,7 @@ HRESULT OpenArchive(IInStream *inStream)
char *cur = leadData;
CLead lead;
UInt32 processedSize;
- RINOK(inStream->Read(leadData, kLeadSize, &processedSize));
+ RINOK(ReadStream(inStream, leadData, kLeadSize, &processedSize));
if (kLeadSize != processedSize)
return S_FALSE;
memmove(lead.Magic, cur, 4);
diff --git a/7zip/Archive/RPM/makefile b/7zip/Archive/RPM/makefile
index 310c09a8..afda1289 100755
--- a/7zip/Archive/RPM/makefile
+++ b/7zip/Archive/RPM/makefile
@@ -17,6 +17,7 @@ WIN_OBJS = \
7ZIP_COMMON_OBJS = \
$O\ProgressUtils.obj \
+ $O\StreamUtils.obj \
OBJS = \
$O\StdAfx.obj \
diff --git a/7zip/Archive/Rar/DllExports.cpp b/7zip/Archive/Rar/DllExports.cpp
index 7e24047c..0df1ac47 100755
--- a/7zip/Archive/Rar/DllExports.cpp
+++ b/7zip/Archive/Rar/DllExports.cpp
@@ -46,9 +46,9 @@ DEFINE_GUID(CLSID_CCryptoRar29Decoder,
0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00);
*/
-// {23170F69-40C1-278A-1000-000110020000}
+// {23170F69-40C1-278A-1000-000110030000}
DEFINE_GUID(CLSID_CRarHandler,
- 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x02, 0x00, 0x00);
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x03, 0x00, 0x00);
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
diff --git a/7zip/Archive/Rar/Rar.dsp b/7zip/Archive/Rar/Rar.dsp
index 9fe9b840..9aee468e 100755
--- a/7zip/Archive/Rar/Rar.dsp
+++ b/7zip/Archive/Rar/Rar.dsp
@@ -178,6 +178,14 @@ 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\Vector.cpp
# End Source File
# Begin Source File
@@ -400,6 +408,14 @@ SOURCE=..\..\Common\StreamObjects.cpp
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 "7z"
diff --git a/7zip/Archive/Rar/RarHandler.cpp b/7zip/Archive/Rar/RarHandler.cpp
index d38b65a4..56187156 100755
--- a/7zip/Archive/Rar/RarHandler.cpp
+++ b/7zip/Archive/Rar/RarHandler.cpp
@@ -186,7 +186,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
switch(propID)
{
case kpidPath:
- if (item.HasUnicodeName())
+ if (item.HasUnicodeName() && !item.UnicodeName.IsEmpty())
propVariant = item.UnicodeName;
else
propVariant = (const wchar_t *)MultiByteToUnicodeString(item.Name, CP_OEMCP);
@@ -615,6 +615,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
NCrypto::NRar20::CDecoder *rar20CryptoDecoderSpec;
CMyComPtr<ICompressFilter> rar20CryptoDecoder;
+ NCrypto::NRar29::CDecoder *rar29CryptoDecoderSpec;
CMyComPtr<ICompressFilter> rar29CryptoDecoder;
CFolderInStream *folderInStreamSpec = NULL;
@@ -727,9 +728,11 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
{
if (!rar29CryptoDecoder)
{
- rar29CryptoDecoder = new NCrypto::NRar29::CDecoder;
+ rar29CryptoDecoderSpec = new NCrypto::NRar29::CDecoder;
+ rar29CryptoDecoder = rar29CryptoDecoderSpec;
// RINOK(rar29CryptoDecoder.CoCreateInstance(CLSID_CCryptoRar29Decoder));
}
+ rar29CryptoDecoderSpec->SetRar350Mode(item.UnPackVersion < 36);
CMyComPtr<ICompressSetDecoderProperties2> cryptoProperties;
RINOK(rar29CryptoDecoder.QueryInterface(IID_ICompressSetDecoderProperties2,
&cryptoProperties));
diff --git a/7zip/Archive/Rar/RarHeader.h b/7zip/Archive/Rar/RarHeader.h
index f7e6f711..832a21c0 100755
--- a/7zip/Archive/Rar/RarHeader.h
+++ b/7zip/Archive/Rar/RarHeader.h
@@ -42,7 +42,10 @@ namespace NArchive
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 there is EncryptVer Byte in End of MainHeader
+ const int kHeaderSizeMin = 7;
+
struct CBlock
{
UInt16 CRC;
@@ -53,9 +56,19 @@ namespace NArchive
UInt32 Reserved2;
// UInt16 GetRealCRC() const;
};
+
const int kArchiveHeaderSize = 13;
const int kBlockHeadersAreEncrypted = 0x80;
+
+ struct CHeader360: public CBlock
+ {
+ Byte EncryptVersion;
+ bool IsEncrypted() const { return (Flags & NHeader::NArchive::kBlockEncryption) != 0; }
+ bool IsThereEncryptVer() const { return (Flags & NHeader::NArchive::kEncryptVer) != 0; }
+ bool IsEncryptOld() const { return (!IsThereEncryptVer() || EncryptVersion < 36); }
+ UInt32 GetBaseSize() const { return kArchiveHeaderSize + (IsEncryptOld() ? 0 : 1); }
+ };
}
namespace NFile
diff --git a/7zip/Archive/Rar/RarIn.cpp b/7zip/Archive/Rar/RarIn.cpp
index f6a4891f..36d8b824 100755
--- a/7zip/Archive/Rar/RarIn.cpp
+++ b/7zip/Archive/Rar/RarIn.cpp
@@ -4,9 +4,11 @@
#include "Common/StringConvert.h"
#include "Common/CRC.h"
+#include "Common/UTFConvert.h"
#include "RarIn.h"
#include "../../Common/LimitedStreams.h"
+#include "../../Common/StreamUtils.h"
namespace NArchive {
namespace NRar {
@@ -115,7 +117,7 @@ bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size)
return (i == size);
}
UInt32 processedSize;
- m_Stream->Read(data, size, &processedSize);
+ ReadStream(m_Stream, data, size, &processedSize);
return (processedSize == size);
}
@@ -128,7 +130,7 @@ void CInArchive::ReadBytesAndTestResult(void *data, UInt32 size)
HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessedSize;
- HRESULT result = m_Stream->Read(data, size, &realProcessedSize);
+ HRESULT result = ReadStream(m_Stream, data, size, &realProcessedSize);
if(processedSize != NULL)
*processedSize = realProcessedSize;
AddToSeekValue(realProcessedSize);
@@ -155,6 +157,7 @@ bool CInArchive::ReadMarkerAndArchiveHeader(const UInt64 *searchHeaderSizeLimit)
m_ArchiveHeader.Size = ReadUInt16();
m_ArchiveHeader.Reserved1 = ReadUInt16();
m_ArchiveHeader.Reserved2 = ReadUInt32();
+ m_ArchiveHeader.EncryptVersion = 0;
CCRC crc;
crc.UpdateByte(m_ArchiveHeader.Type);
@@ -163,6 +166,14 @@ bool CInArchive::ReadMarkerAndArchiveHeader(const UInt64 *searchHeaderSizeLimit)
crc.UpdateUInt16(m_ArchiveHeader.Reserved1);
crc.UpdateUInt32(m_ArchiveHeader.Reserved2);
+ if (m_ArchiveHeader.IsThereEncryptVer() && m_ArchiveHeader.Size > NHeader::NArchive::kArchiveHeaderSize)
+ {
+ ReadBytes(&m_ArchiveHeader.EncryptVersion, 1, &processedSize);
+ if (processedSize != 1)
+ return false;
+ crc.UpdateByte(m_ArchiveHeader.EncryptVersion);
+ }
+
UInt32 u = crc.GetDigest();
if(m_ArchiveHeader.CRC != (crc.GetDigest() & 0xFFFF))
ThrowExceptionWithCode(CInArchiveException::kArchiveHeaderCRCError);
@@ -177,7 +188,7 @@ void CInArchive::SkipArchiveComment()
{
if (!m_SeekOnArchiveComment)
return;
- AddToSeekValue(m_ArchiveHeader.Size - NHeader::NArchive::kArchiveHeaderSize);
+ AddToSeekValue(m_ArchiveHeader.Size - m_ArchiveHeader.GetBaseSize());
m_SeekOnArchiveComment = false;
}
@@ -256,15 +267,18 @@ void CInArchive::ReadName(CItemEx &item, int nameSize)
buffer[mainLen] = '\0';
item.Name = buffer;
- int unicodeNameSizeMax = MyMin(nameSize, (0x400));
- _unicodeNameBuffer.EnsureCapacity(unicodeNameSizeMax + 1);
-
- if((m_BlockHeader.Flags & NHeader::NFile::kUnicodeName) != 0 &&
- mainLen < nameSize)
+ if(item.HasUnicodeName())
{
- DecodeUnicodeFileName(buffer, (const Byte *)buffer + mainLen + 1,
- nameSize - (mainLen + 1), _unicodeNameBuffer, unicodeNameSizeMax);
- item.UnicodeName = _unicodeNameBuffer;
+ if(mainLen < nameSize)
+ {
+ int unicodeNameSizeMax = MyMin(nameSize, (0x400));
+ _unicodeNameBuffer.EnsureCapacity(unicodeNameSizeMax + 1);
+ DecodeUnicodeFileName(buffer, (const Byte *)buffer + mainLen + 1,
+ nameSize - (mainLen + 1), _unicodeNameBuffer, unicodeNameSizeMax);
+ item.UnicodeName = _unicodeNameBuffer;
+ }
+ else if (!ConvertUTF8ToUnicode(item.Name, item.UnicodeName))
+ item.UnicodeName.Empty();
}
}
else
@@ -398,6 +412,8 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa
m_RarAESSpec = new NCrypto::NRar29::CDecoder;
m_RarAES = m_RarAESSpec;
}
+ m_RarAESSpec->SetRar350Mode(m_ArchiveHeader.IsEncryptOld());
+
// Salt
const UInt32 kSaltSize = 8;
Byte salt[kSaltSize];
@@ -410,9 +426,17 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa
RINOK(getTextPassword->CryptoGetTextPassword(&password))
UString unicodePassword(password);
- RINOK(m_RarAESSpec->CryptoSetPassword(
- (const Byte *)(const wchar_t *)unicodePassword,
- unicodePassword.Length() * 2));
+ CByteBuffer buffer;
+ const UInt32 sizeInBytes = unicodePassword.Length() * 2;
+ buffer.SetCapacity(sizeInBytes);
+ for (int i = 0; i < unicodePassword.Length(); i++)
+ {
+ wchar_t c = unicodePassword[i];
+ ((Byte *)buffer)[i * 2] = (Byte)c;
+ ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
+ }
+
+ RINOK(m_RarAESSpec->CryptoSetPassword((const Byte *)buffer, sizeInBytes));
const UInt32 kDecryptedBufferSize = (1 << 12);
if (m_DecryptedData.GetCapacity() == 0)
@@ -420,7 +444,7 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa
m_DecryptedData.SetCapacity(kDecryptedBufferSize);
}
RINOK(m_RarAES->Init());
- RINOK(m_Stream->Read((Byte *)m_DecryptedData, kDecryptedBufferSize, &m_DecryptedDataSize));
+ RINOK(ReadStream(m_Stream, (Byte *)m_DecryptedData, kDecryptedBufferSize, &m_DecryptedDataSize));
m_DecryptedDataSize = m_RarAES->Filter((Byte *)m_DecryptedData, m_DecryptedDataSize);
m_CryptoMode = true;
@@ -486,7 +510,7 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa
void CInArchive::DirectGetBytes(void *data, UInt32 size)
{
- m_Stream->Read(data, size, NULL);
+ ReadStream(m_Stream, data, size, NULL);
}
bool CInArchive::SeekInArchive(UInt64 position)
diff --git a/7zip/Archive/Rar/RarIn.h b/7zip/Archive/Rar/RarIn.h
index c370733a..22262a74 100755
--- a/7zip/Archive/Rar/RarIn.h
+++ b/7zip/Archive/Rar/RarIn.h
@@ -41,6 +41,7 @@ public:
bool IsCommented() const { return (Flags & NHeader::NArchive::kComment) != 0; }
bool IsVolume() const { return (Flags & NHeader::NArchive::kVolume) != 0; }
bool HaveNewVolumeName() const { return (Flags & NHeader::NArchive::kNewVolName) != 0; }
+ bool IsEncrypted() const { return (Flags & NHeader::NArchive::kBlockEncryption) != 0; }
};
class CInArchive
@@ -51,7 +52,7 @@ class CInArchive
UInt64 m_Position;
UInt64 m_ArchiveStartPosition;
- NHeader::NArchive::CBlock m_ArchiveHeader;
+ NHeader::NArchive::CHeader360 m_ArchiveHeader;
CDynamicBuffer<char> m_NameBuffer;
CDynamicBuffer<wchar_t> _unicodeNameBuffer;
bool m_SeekOnArchiveComment;
diff --git a/7zip/Archive/Rar/RarVolumeInStream.cpp b/7zip/Archive/Rar/RarVolumeInStream.cpp
index 5a185707..32078e6d 100755
--- a/7zip/Archive/Rar/RarVolumeInStream.cpp
+++ b/7zip/Archive/Rar/RarVolumeInStream.cpp
@@ -64,6 +64,7 @@ STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSiz
}
realProcessedSize += localProcessedSize;
size -= localProcessedSize;
+ break;
}
else
{
@@ -75,9 +76,4 @@ STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSiz
return S_OK;
}
-STDMETHODIMP CFolderInStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
-{
- return Read(data, size, processedSize);
-}
-
-}} \ No newline at end of file
+}}
diff --git a/7zip/Archive/Rar/RarVolumeInStream.h b/7zip/Archive/Rar/RarVolumeInStream.h
index 53156306..4c9a9e96 100755
--- a/7zip/Archive/Rar/RarVolumeInStream.h
+++ b/7zip/Archive/Rar/RarVolumeInStream.h
@@ -25,7 +25,6 @@ public:
MY_UNKNOWN_IMP
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
private:
CObjectVector<CInArchive> *_archives;
diff --git a/7zip/Archive/Rar/makefile b/7zip/Archive/Rar/makefile
index 0799edf3..42942f74 100755
--- a/7zip/Archive/Rar/makefile
+++ b/7zip/Archive/Rar/makefile
@@ -18,6 +18,7 @@ COMMON_OBJS = \
$O\NewHandler.obj \
$O\String.obj \
$O\StringConvert.obj \
+ $O\UTFConvert.obj \
$O\Vector.obj \
WIN_OBJS = \
@@ -29,6 +30,7 @@ WIN_OBJS = \
$O\LimitedStreams.obj \
$O\ProgressUtils.obj \
$O\StreamObjects.obj \
+ $O\StreamUtils.obj \
AR_COMMON_OBJS = \
$O\CodecsPath.obj \
diff --git a/7zip/Archive/Split/DllExports.cpp b/7zip/Archive/Split/DllExports.cpp
index d8ea97c7..f9e8a83b 100755
--- a/7zip/Archive/Split/DllExports.cpp
+++ b/7zip/Archive/Split/DllExports.cpp
@@ -8,9 +8,9 @@
#include "SplitHandler.h"
#include "../../ICoder.h"
-// {23170F69-40C1-278A-1000-0001100B0000}
+// {23170F69-40C1-278A-1000-000110EA0000}
DEFINE_GUID(CLSID_CSplitHandler,
- 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x0B, 0x00, 0x00);
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xEA, 0x00, 0x00);
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
diff --git a/7zip/Archive/Split/Split.dsp b/7zip/Archive/Split/Split.dsp
index 5758e3b3..d6229d98 100755
--- a/7zip/Archive/Split/Split.dsp
+++ b/7zip/Archive/Split/Split.dsp
@@ -204,6 +204,14 @@ SOURCE=..\..\Common\ProgressUtils.cpp
SOURCE=..\..\Common\ProgressUtils.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 "Interface"
@@ -223,7 +231,7 @@ SOURCE=.\SplitHandler.h
# End Source File
# Begin Source File
-SOURCE=.\SplitHanlerOut.cpp
+SOURCE=.\SplitHandlerOut.cpp
# End Source File
# End Target
# End Project
diff --git a/7zip/Archive/Split/makefile b/7zip/Archive/Split/makefile
index a821b2f8..650c750b 100755
--- a/7zip/Archive/Split/makefile
+++ b/7zip/Archive/Split/makefile
@@ -20,6 +20,7 @@ WIN_OBJS = \
7ZIP_COMMON_OBJS = \
$O\ProgressUtils.obj \
+ $O\StreamUtils.obj \
AR_COMMON_OBJS = \
$O\MultiStream.obj \
diff --git a/7zip/Archive/Tar/DllExports.cpp b/7zip/Archive/Tar/DllExports.cpp
index 7f4f5c04..9d80a651 100755
--- a/7zip/Archive/Tar/DllExports.cpp
+++ b/7zip/Archive/Tar/DllExports.cpp
@@ -8,9 +8,9 @@
#include "../../ICoder.h"
#include "TarHandler.h"
-// {23170F69-40C1-278A-1000-000110040000}
+// {23170F69-40C1-278A-1000-000110EE0000}
DEFINE_GUID(CLSID_CTarHandler,
- 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x04, 0x00, 0x00);
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xEE, 0x00, 0x00);
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
diff --git a/7zip/Archive/Tar/Tar.dsp b/7zip/Archive/Tar/Tar.dsp
index bba8ab2b..c01e7383 100755
--- a/7zip/Archive/Tar/Tar.dsp
+++ b/7zip/Archive/Tar/Tar.dsp
@@ -162,6 +162,14 @@ 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\Vector.cpp
# End Source File
# Begin Source File
@@ -276,6 +284,14 @@ SOURCE=..\..\Common\ProgressUtils.cpp
SOURCE=..\..\Common\ProgressUtils.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
# End Target
# End Project
diff --git a/7zip/Archive/Tar/TarHeader.cpp b/7zip/Archive/Tar/TarHeader.cpp
index 9bf408c0..41fb2137 100755
--- a/7zip/Archive/Tar/TarHeader.cpp
+++ b/7zip/Archive/Tar/TarHeader.cpp
@@ -16,7 +16,7 @@ namespace NFileHeader {
// The magic field is filled with this if uname and gname are valid.
namespace NMagic
{
- const char *kUsTar = "ustar "; // 7 chars and a null
+ 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"; // 7 chars and a null
}
diff --git a/7zip/Archive/Tar/TarHeader.h b/7zip/Archive/Tar/TarHeader.h
index c32092ca..1436293f 100755
--- a/7zip/Archive/Tar/TarHeader.h
+++ b/7zip/Archive/Tar/TarHeader.h
@@ -14,6 +14,7 @@ namespace NFileHeader
const int kNameSize = 100;
const int kUserNameSize = 32;
const int kGroupNameSize = 32;
+ const int kPrefixSize = 155;
/*
struct CHeader
@@ -32,6 +33,7 @@ namespace NFileHeader
char GroupName[kGroupNameSize];
char DeviceMajor[8];
char DeviceMinor[8];
+ char Prefix[155];
};
union CRecord
{
@@ -84,7 +86,7 @@ namespace NFileHeader
// The magic field is filled with this if uname and gname are valid.
namespace NMagic
{
- extern const char *kUsTar; // = "ustar "; // 7 chars and a null
+ extern const char *kUsTar; // = "ustar"; // 5 chars
extern const char *kGNUTar; // = "GNUtar "; // 7 chars and a null
extern const char *kEmpty; // = "GNUtar "; // 7 chars and a null
}
diff --git a/7zip/Archive/Tar/TarIn.cpp b/7zip/Archive/Tar/TarIn.cpp
index f9bfacd6..fad27587 100755
--- a/7zip/Archive/Tar/TarIn.cpp
+++ b/7zip/Archive/Tar/TarIn.cpp
@@ -5,14 +5,17 @@
#include "TarIn.h"
#include "TarHeader.h"
+#include "Common/StringToInt.h"
#include "Windows/Defs.h"
+#include "../../Common/StreamUtils.h"
+
namespace NArchive {
namespace NTar {
HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
{
- RINOK(m_Stream->Read(data, size, &processedSize));
+ RINOK(ReadStream(m_Stream, data, size, &processedSize));
m_Position += processedSize;
return S_OK;
}
@@ -24,28 +27,28 @@ HRESULT CInArchive::Open(IInStream *inStream)
return S_OK;
}
-static UInt32 OctalToNumber(const char *srcString)
+static bool OctalToNumber(const char *srcString, int size, UInt64 &res)
{
- char *endPtr;
- return(strtoul(srcString, &endPtr, 8));
+ char sz[32];
+ strncpy(sz, srcString, size);
+ sz[size] = 0;
+ const char *end;
+ int i;
+ for (i = 0; sz[i] == ' '; i++);
+ res = ConvertOctStringToUInt64(sz + i, &end);
+ return (*end == ' ' || *end == 0);
}
-static bool CheckOctalString(const char *srcString, int numChars)
+static bool OctalToNumber32(const char *srcString, int size, UInt32 &res)
{
- for(int i = 0; i < numChars; i++)
- {
- char c = srcString[i];
- if (c == 0)
- return true;
- if (c >= '0' && c <= '7')
- continue;
- if (c != ' ')
- return false;
- }
- return true;
+ UInt64 res64;
+ if (!OctalToNumber(srcString, size, res64))
+ return false;
+ res = (UInt32)res64;
+ return (res64 <= 0xFFFFFFFF);
}
-#define ReturnIfBadOctal(x, y) { if (!CheckOctalString((x), (y))) return S_FALSE; }
+#define RIF(x) { if (!(x)) return S_FALSE; }
static bool IsRecordLast(const char *record)
{
@@ -57,9 +60,9 @@ static bool IsRecordLast(const char *record)
static void ReadString(const char *s, int size, AString &result)
{
- if (size > NFileHeader::kNameSize)
+ if (size > NFileHeader::kRecordSize)
size = NFileHeader::kNameSize;
- char tempString[NFileHeader::kNameSize + 1];
+ char tempString[NFileHeader::kRecordSize + 1];
strncpy(tempString, s, size);
tempString[size] = '\0';
result = tempString;
@@ -114,28 +117,23 @@ HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item)
item.Name += c;
}
- ReturnIfBadOctal(cur, 8);
- item.Mode = OctalToNumber(cur);
+ RIF(OctalToNumber32(cur, 8, item.Mode));
cur += 8;
- ReturnIfBadOctal(cur, 8);
- item.UID = OctalToNumber(cur);
+ RIF(OctalToNumber32(cur, 8, item.UID));
cur += 8;
- ReturnIfBadOctal(cur, 8);
- item.GID = OctalToNumber(cur);
+ RIF(OctalToNumber32(cur, 8, item.GID));
cur += 8;
- ReturnIfBadOctal(cur, 12);
- item.Size = OctalToNumber(cur);
+ RIF(OctalToNumber(cur, 12, item.Size));
cur += 12;
- ReturnIfBadOctal(cur, 12);
- item.ModificationTime = OctalToNumber(cur);
+ RIF(OctalToNumber32(cur, 12, item.ModificationTime));
cur += 12;
- ReturnIfBadOctal(cur, 8);
- UInt32 checkSum = OctalToNumber(cur);
+ UInt32 checkSum;
+ RIF(OctalToNumber32(cur, 8, checkSum));
memmove(cur, NFileHeader::kCheckSumBlanks, 8);
cur += 8;
@@ -153,17 +151,19 @@ HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item)
ReadString(cur, NFileHeader::kUserNameSize, item.GroupName);
cur += NFileHeader::kUserNameSize;
- ReturnIfBadOctal(cur, 8);
item.DeviceMajorDefined = (cur[0] != 0);
- if (item.DeviceMajorDefined)
- item.DeviceMajor = OctalToNumber(cur);
+ RIF(OctalToNumber32(cur, 8, item.DeviceMajor));
+ cur += 8;
- ReturnIfBadOctal(cur, 8);
item.DeviceMinorDefined = (cur[0] != 0);
- if (item.DeviceMinorDefined)
- item.DeviceMinor = OctalToNumber(cur);
+ RIF(OctalToNumber32(cur, 8, item.DeviceMinor));
cur += 8;
+ AString prefix;
+ ReadString(cur, NFileHeader::kPrefixSize, prefix);
+ cur += NFileHeader::kPrefixSize;
+ if (!prefix.IsEmpty() && item.IsMagic())
+ item.Name = prefix + AString('/') + item.Name;
if (item.LinkFlag == NFileHeader::NLinkFlag::kLink)
item.Size = 0;
diff --git a/7zip/Archive/Tar/TarItem.h b/7zip/Archive/Tar/TarItem.h
index 7637b537..71fff7ba 100755
--- a/7zip/Archive/Tar/TarItem.h
+++ b/7zip/Archive/Tar/TarItem.h
@@ -45,6 +45,14 @@ public:
}
return false;
}
+
+ bool IsMagic() const
+ {
+ for (int i = 0; i < 5; i++)
+ if (Magic[i] != NFileHeader::NMagic::kUsTar[i])
+ return false;
+ return true;
+ }
};
class CItemEx: public CItem
diff --git a/7zip/Archive/Tar/TarOut.cpp b/7zip/Archive/Tar/TarOut.cpp
index 45c7ef1d..28146c34 100755
--- a/7zip/Archive/Tar/TarOut.cpp
+++ b/7zip/Archive/Tar/TarOut.cpp
@@ -7,6 +7,7 @@
#include "Common/IntToString.h"
#include "Windows/Defs.h"
+#include "../../Common/StreamUtils.h"
namespace NArchive {
namespace NTar {
@@ -14,7 +15,7 @@ namespace NTar {
HRESULT COutArchive::WriteBytes(const void *buffer, UInt32 size)
{
UInt32 processedSize;
- RINOK(m_Stream->Write(buffer, size, &processedSize));
+ RINOK(WriteStream(m_Stream, buffer, size, &processedSize));
if(processedSize != size)
return E_FAIL;
return S_OK;
@@ -165,10 +166,15 @@ HRESULT COutArchive::FillDataResidual(UInt64 dataSize)
HRESULT COutArchive::WriteFinishHeader()
{
- char record[NFileHeader::kRecordSize];
- for (int i = 0; i < NFileHeader::kRecordSize; i++)
+ Byte record[NFileHeader::kRecordSize];
+ int i;
+ for (i = 0; i < NFileHeader::kRecordSize; i++)
record[i] = 0;
- return WriteBytes(record, NFileHeader::kRecordSize);
+ for (i = 0; i < 2; i++)
+ {
+ RINOK(WriteBytes(record, NFileHeader::kRecordSize));
+ }
+ return S_OK;
}
}}
diff --git a/7zip/Archive/Tar/makefile b/7zip/Archive/Tar/makefile
index b9670b28..f892c303 100755
--- a/7zip/Archive/Tar/makefile
+++ b/7zip/Archive/Tar/makefile
@@ -18,6 +18,7 @@ COMMON_OBJS = \
$O\NewHandler.obj \
$O\String.obj \
$O\StringConvert.obj \
+ $O\StringToInt.obj \
$O\Vector.obj \
WIN_OBJS = \
@@ -26,6 +27,7 @@ WIN_OBJS = \
7ZIP_COMMON_OBJS = \
$O\LimitedStreams.obj \
$O\ProgressUtils.obj \
+ $O\StreamUtils.obj \
AR_COMMON_OBJS = \
$O\ItemNameUtils.obj \
diff --git a/7zip/Archive/Z/DllExports.cpp b/7zip/Archive/Z/DllExports.cpp
index 7d4e0d23..d96cd303 100755
--- a/7zip/Archive/Z/DllExports.cpp
+++ b/7zip/Archive/Z/DllExports.cpp
@@ -8,13 +8,9 @@
#include "ZHandler.h"
#include "../../ICoder.h"
-// {23170F69-40C1-278B-0402-050000000000}
-DEFINE_GUID(CLSID_CCompressZDecoder,
-0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00);
-
-// {23170F69-40C1-278A-1000-0001100D0000}
+// {23170F69-40C1-278A-1000-000110050000}
DEFINE_GUID(CLSID_CZHandler,
-0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x0D, 0x00, 0x00);
+0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 0x00, 0x00);
HINSTANCE g_hInstance;
diff --git a/7zip/Archive/Z/Z.dsp b/7zip/Archive/Z/Z.dsp
index 56873229..e1f72522 100755
--- a/7zip/Archive/Z/Z.dsp
+++ b/7zip/Archive/Z/Z.dsp
@@ -220,6 +220,14 @@ SOURCE=..\..\Common\ProgressUtils.cpp
SOURCE=..\..\Common\ProgressUtils.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 Source File
diff --git a/7zip/Archive/Z/ZHandler.cpp b/7zip/Archive/Z/ZHandler.cpp
index e7b13a75..5787273b 100755
--- a/7zip/Archive/Z/ZHandler.cpp
+++ b/7zip/Archive/Z/ZHandler.cpp
@@ -8,6 +8,7 @@
#include "../../Common/ProgressUtils.h"
#include "../../Compress/Z/ZDecoder.h"
+#include "../../Common/StreamUtils.h"
#include "Windows/PropVariant.h"
#include "Windows/Defs.h"
@@ -98,7 +99,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition));
Byte buffer[kSignatureSize];
UInt32 processedSize;
- RINOK(stream->Read(buffer, kSignatureSize, &processedSize));
+ RINOK(ReadStream(stream, buffer, kSignatureSize, &processedSize));
if (processedSize != kSignatureSize)
return S_FALSE;
if (buffer[0] != 0x1F || buffer[1] != 0x9D)
diff --git a/7zip/Archive/Z/makefile b/7zip/Archive/Z/makefile
index fbd9d6ad..aff4fc42 100755
--- a/7zip/Archive/Z/makefile
+++ b/7zip/Archive/Z/makefile
@@ -18,6 +18,7 @@ WIN_OBJS = \
$O\InBuffer.obj \
$O\OutBuffer.obj \
$O\ProgressUtils.obj \
+ $O\StreamUtils.obj \
AR_COMMON_OBJS = \
$O\DummyOutStream.obj \
diff --git a/7zip/Archive/Zip/Zip.dsp b/7zip/Archive/Zip/Zip.dsp
index 7a5ebdbf..44852ec1 100755
--- a/7zip/Archive/Zip/Zip.dsp
+++ b/7zip/Archive/Zip/Zip.dsp
@@ -320,6 +320,14 @@ SOURCE=..\..\Common\StreamObjects.cpp
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 "Engine"
diff --git a/7zip/Archive/Zip/ZipHandler.cpp b/7zip/Archive/Zip/ZipHandler.cpp
index 922a69c7..00a61f57 100755
--- a/7zip/Archive/Zip/ZipHandler.cpp
+++ b/7zip/Archive/Zip/ZipHandler.cpp
@@ -148,6 +148,7 @@ const wchar_t *kMethods[] =
const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]);
const wchar_t *kUnknownMethod = L"Unknown";
+const wchar_t *kPPMdMethod = L"PPMd";
CHandler::CHandler():
m_ArchiveIsOpen(false)
@@ -258,6 +259,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID aPropID, PROPVARIANT *a
UString method;
if (item.CompressionMethod < kNumMethods)
method = kMethods[item.CompressionMethod];
+ else if (item.CompressionMethod == NFileHeader::NCompressionMethod::kWinZipPPMd)
+ method = kPPMdMethod;
else
method = kUnknownMethod;
propVariant = method;
diff --git a/7zip/Archive/Zip/ZipHeader.h b/7zip/Archive/Zip/ZipHeader.h
index e6d1288a..7d023715 100755
--- a/7zip/Archive/Zip/ZipHeader.h
+++ b/7zip/Archive/Zip/ZipHeader.h
@@ -67,7 +67,8 @@ namespace NFileHeader
kDeflated64 = 9,
kPKImploding = 10,
- kBZip2 = 12
+ kBZip2 = 12,
+ kWinZipPPMd = 0x62
};
const int kNumCompressionMethods = 11;
const Byte kMadeByProgramVersion = 20;
diff --git a/7zip/Archive/Zip/ZipIn.cpp b/7zip/Archive/Zip/ZipIn.cpp
index 4b4481ed..59f1e0ae 100755
--- a/7zip/Archive/Zip/ZipIn.cpp
+++ b/7zip/Archive/Zip/ZipIn.cpp
@@ -7,6 +7,7 @@
#include "Common/StringConvert.h"
#include "Common/DynamicBuffer.h"
#include "../../Common/LimitedStreams.h"
+#include "../../Common/StreamUtils.h"
namespace NArchive {
namespace NZip {
@@ -87,13 +88,10 @@ bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit)
}
}
-//////////////////////////////////////
-// Read Operations
-
HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessedSize;
- HRESULT result = m_Stream->Read(data, size, &realProcessedSize);
+ HRESULT result = ReadStream(m_Stream, data, size, &realProcessedSize);
if(processedSize != NULL)
*processedSize = realProcessedSize;
m_Position += realProcessedSize;
@@ -158,9 +156,6 @@ UInt64 CInArchive::ReadUInt64()
return value;
}
-//////////////////////////////////
-// Read headers
-
bool CInArchive::ReadUInt32(UInt32 &value)
{
value = 0;
diff --git a/7zip/Archive/Zip/ZipOut.cpp b/7zip/Archive/Zip/ZipOut.cpp
index 7e46d6ca..6e4e7335 100755
--- a/7zip/Archive/Zip/ZipOut.cpp
+++ b/7zip/Archive/Zip/ZipOut.cpp
@@ -6,6 +6,7 @@
#include "Common/StringConvert.h"
#include "Common/CRC.h"
#include "../../Common/OffsetStream.h"
+#include "../../Common/StreamUtils.h"
namespace NArchive {
namespace NZip {
@@ -46,7 +47,7 @@ void COutArchive::PrepareWriteCompressedData2(UInt16 fileNameLength, UInt64 unPa
void COutArchive::WriteBytes(const void *buffer, UInt32 size)
{
UInt32 processedSize;
- if(m_Stream->Write(buffer, size, &processedSize) != S_OK)
+ if(WriteStream(m_Stream, buffer, size, &processedSize) != S_OK)
throw 0;
if(processedSize != size)
throw 0;
diff --git a/7zip/Archive/Zip/makefile b/7zip/Archive/Zip/makefile
index 22d59801..4d59fb0c 100755
--- a/7zip/Archive/Zip/makefile
+++ b/7zip/Archive/Zip/makefile
@@ -38,6 +38,7 @@ WIN_OBJS = \
$O\OutBuffer.obj \
$O\ProgressUtils.obj \
$O\StreamObjects.obj \
+ $O\StreamUtils.obj \
AR_COMMON_OBJS = \
$O\CodecsPath.obj \
diff --git a/7zip/Archive/cpio/CpioIn.cpp b/7zip/Archive/cpio/CpioIn.cpp
index ce2ab023..32b9f77d 100755
--- a/7zip/Archive/cpio/CpioIn.cpp
+++ b/7zip/Archive/cpio/CpioIn.cpp
@@ -4,8 +4,11 @@
#include "CpioIn.h"
+#include "Common/StringToInt.h"
#include "Windows/Defs.h"
+#include "../../Common/StreamUtils.h"
+
#include "CpioHeader.h"
namespace NArchive {
@@ -13,7 +16,7 @@ namespace NCpio {
HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
{
- RINOK(m_Stream->Read(data, size, &processedSize));
+ RINOK(ReadStream(m_Stream, data, size, &processedSize));
m_Position += processedSize;
return S_OK;
}
@@ -75,24 +78,37 @@ bool CInArchive::ReadNumber(UInt32 &resultValue)
return true;
}
+static bool OctalToNumber(const char *s, UInt64 &res)
+{
+ const char *end;
+ res = ConvertOctStringToUInt64(s, &end);
+ return (*end == ' ' || *end == 0);
+}
+
+static bool OctalToNumber32(const char *s, UInt32 &res)
+{
+ UInt64 res64;
+ if (!OctalToNumber(s, res64))
+ return false;
+ res = (UInt32)res64;
+ return (res64 <= 0xFFFFFFFF);
+}
+
bool CInArchive::ReadOctNumber(int size, UInt32 &resultValue)
{
- char s[32];
+ char sz[32 + 4];
int i;
for (i = 0; i < size && i < 32; i++)
- s[i] = char(ReadByte());
- s[i] = 0;
- char *endPtr;
- resultValue = strtoul(s, &endPtr, 8);
- return true;
+ sz[i] = (char)ReadByte();
+ sz[i] = 0;
+ return OctalToNumber32(sz, resultValue);
}
-#define GetFromHex(y) { if (!ReadNumber(y)) return E_FAIL; }
-#define GetFromOct6(y) { if (!ReadOctNumber(6, y)) return E_FAIL; }
-#define GetFromOct11(y) { if (!ReadOctNumber(11, y)) return E_FAIL; }
+#define GetFromHex(y) { if (!ReadNumber(y)) return S_FALSE; }
+#define GetFromOct6(y) { if (!ReadOctNumber(6, y)) return S_FALSE; }
+#define GetFromOct11(y) { if (!ReadOctNumber(11, y)) return S_FALSE; }
-static unsigned short ConvertValue(
- unsigned short value, bool convert)
+static unsigned short ConvertValue(unsigned short value, bool convert)
{
if (!convert)
return value;
@@ -109,13 +125,6 @@ static UInt32 GetAlignedSize(UInt32 size, UInt32 align)
HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
{
- /*
- union
- {
- NFileHeader::CRecord record;
- NFileHeader::CRecord2 record2;
- };
- */
filled = false;
UInt32 processedSize;
diff --git a/7zip/Archive/cpio/DllExports.cpp b/7zip/Archive/cpio/DllExports.cpp
index a72058a5..32473235 100755
--- a/7zip/Archive/cpio/DllExports.cpp
+++ b/7zip/Archive/cpio/DllExports.cpp
@@ -8,9 +8,9 @@
#include "CpioHandler.h"
#include "../../ICoder.h"
-// {23170F69-40C1-278A-1000-000110080000}
+// {23170F69-40C1-278A-1000-000110ED0000}
DEFINE_GUID(CLSID_CCpioHandler,
- 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x08, 0x00, 0x00);
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xED, 0x00, 0x00);
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
diff --git a/7zip/Archive/cpio/cpio.dsp b/7zip/Archive/cpio/cpio.dsp
index 5f555d9b..f30c3e63 100755
--- a/7zip/Archive/cpio/cpio.dsp
+++ b/7zip/Archive/cpio/cpio.dsp
@@ -150,6 +150,14 @@ 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\Vector.cpp
# End Source File
# Begin Source File
@@ -244,6 +252,14 @@ SOURCE=..\..\Common\ProgressUtils.cpp
SOURCE=..\..\Common\ProgressUtils.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
# End Target
# End Project
diff --git a/7zip/Archive/makefile b/7zip/Archive/makefile
index a5858144..24df1961 100755
--- a/7zip/Archive/makefile
+++ b/7zip/Archive/makefile
@@ -3,6 +3,7 @@ DIRS = \
Arj\~ \
BZip2\~ \
Cab\~ \
+ Chm\~ \
Cpio\~ \
Deb\~ \
GZip\~ \
diff --git a/7zip/Bundles/Alone/Alone.dsp b/7zip/Bundles/Alone/Alone.dsp
index 9cb637bc..bcb415a9 100755
--- a/7zip/Bundles/Alone/Alone.dsp
+++ b/7zip/Bundles/Alone/Alone.dsp
@@ -635,6 +635,14 @@ SOURCE=..\..\Common\StreamObjects.cpp
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 "Compress"
diff --git a/7zip/Bundles/Alone/makefile b/7zip/Bundles/Alone/makefile
index f5cae4a0..f2e890bc 100755
--- a/7zip/Bundles/Alone/makefile
+++ b/7zip/Bundles/Alone/makefile
@@ -79,6 +79,7 @@ WIN_OBJS = \
$O\ProgressUtils.obj \
$O\StreamBinder.obj \
$O\StreamObjects.obj \
+ $O\StreamUtils.obj \
UI_COMMON_OBJS = \
$O\ArchiveCommandLine.obj \
diff --git a/7zip/Bundles/Format7z/Format7z.dsp b/7zip/Bundles/Format7z/Format7z.dsp
index 786f50e4..597f2bd7 100755
--- a/7zip/Bundles/Format7z/Format7z.dsp
+++ b/7zip/Bundles/Format7z/Format7z.dsp
@@ -93,11 +93,11 @@ LINK32=link.exe
# PROP Default_Filter ""
# Begin Source File
-SOURCE=..\..\Archive\7z\7z.def
+SOURCE=..\..\Archive\7z\7z.ico
# End Source File
# Begin Source File
-SOURCE=..\..\Archive\7z\7z.ico
+SOURCE=..\..\Archive\Archive.def
# End Source File
# Begin Source File
@@ -948,6 +948,14 @@ SOURCE=..\..\Common\StreamObjects.cpp
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
# End Target
# End Project
diff --git a/7zip/Bundles/Format7z/makefile b/7zip/Bundles/Format7z/makefile
index 2567f37b..02ce7144 100755
--- a/7zip/Bundles/Format7z/makefile
+++ b/7zip/Bundles/Format7z/makefile
@@ -44,6 +44,7 @@ WIN_OBJS = \
$O\ProgressUtils.obj \
$O\StreamBinder.obj \
$O\StreamObjects.obj \
+ $O\StreamUtils.obj \
AR_COMMON_OBJS = \
$O\CoderMixer2.obj \
diff --git a/7zip/Bundles/Format7zExtract/Format7z.dsp b/7zip/Bundles/Format7zExtract/Format7z.dsp
index 82800b08..d3a7d434 100755
--- a/7zip/Bundles/Format7zExtract/Format7z.dsp
+++ b/7zip/Bundles/Format7zExtract/Format7z.dsp
@@ -93,11 +93,11 @@ LINK32=link.exe
# PROP Default_Filter ""
# Begin Source File
-SOURCE=..\..\Archive\7z\7z.def
+SOURCE=..\..\Archive\7z\7z.ico
# End Source File
# Begin Source File
-SOURCE=..\..\Archive\7z\7z.ico
+SOURCE=..\..\Archive\Archive.def
# End Source File
# Begin Source File
@@ -804,6 +804,14 @@ SOURCE=..\..\Common\StreamObjects.cpp
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
# End Target
# End Project
diff --git a/7zip/Bundles/Format7zExtract/makefile b/7zip/Bundles/Format7zExtract/makefile
index 56b9ff50..fbe77392 100755
--- a/7zip/Bundles/Format7zExtract/makefile
+++ b/7zip/Bundles/Format7zExtract/makefile
@@ -45,6 +45,7 @@ WIN_OBJS = \
$O\ProgressUtils.obj \
$O\StreamBinder.obj \
$O\StreamObjects.obj \
+ $O\StreamUtils.obj \
AR_COMMON_OBJS = \
$O\CoderMixer2.obj \
diff --git a/7zip/Bundles/SFXCon/SFXCon.dsp b/7zip/Bundles/SFXCon/SFXCon.dsp
index 05899e39..c6859282 100755
--- a/7zip/Bundles/SFXCon/SFXCon.dsp
+++ b/7zip/Bundles/SFXCon/SFXCon.dsp
@@ -654,6 +654,14 @@ SOURCE=..\..\Common\StreamObjects.cpp
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"
diff --git a/7zip/Bundles/SFXCon/makefile b/7zip/Bundles/SFXCon/makefile
index 27aaabc3..3164dc39 100755
--- a/7zip/Bundles/SFXCon/makefile
+++ b/7zip/Bundles/SFXCon/makefile
@@ -58,6 +58,7 @@ WIN_OBJS = \
$O\ProgressUtils.obj \
$O\StreamBinder.obj \
$O\StreamObjects.obj \
+ $O\StreamUtils.obj \
UI_COMMON_OBJS = \
$O\ArchiveExtractCallback.obj \
diff --git a/7zip/Bundles/SFXSetup/SFXSetup.dsp b/7zip/Bundles/SFXSetup/SFXSetup.dsp
index 1e686014..a58feab5 100755
--- a/7zip/Bundles/SFXSetup/SFXSetup.dsp
+++ b/7zip/Bundles/SFXSetup/SFXSetup.dsp
@@ -567,6 +567,14 @@ SOURCE=..\..\Common\StreamObjects.cpp
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"
diff --git a/7zip/Bundles/SFXSetup/makefile b/7zip/Bundles/SFXSetup/makefile
index 85459496..1f86c42c 100755
--- a/7zip/Bundles/SFXSetup/makefile
+++ b/7zip/Bundles/SFXSetup/makefile
@@ -57,6 +57,7 @@ WIN_CTRL_OBJS = \
$O\ProgressUtils.obj \
$O\StreamBinder.obj \
$O\StreamObjects.obj \
+ $O\StreamUtils.obj \
UI_COMMON_OBJS = \
$O\ArchiveOpenCallback.obj \
diff --git a/7zip/Bundles/SFXWin/SFXWin.dsp b/7zip/Bundles/SFXWin/SFXWin.dsp
index f49239ba..ca9ce881 100755
--- a/7zip/Bundles/SFXWin/SFXWin.dsp
+++ b/7zip/Bundles/SFXWin/SFXWin.dsp
@@ -506,6 +506,14 @@ SOURCE=..\..\Common\StreamObjects.cpp
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 "File Manager"
diff --git a/7zip/Bundles/SFXWin/makefile b/7zip/Bundles/SFXWin/makefile
index 58d56e2c..af10c3fe 100755
--- a/7zip/Bundles/SFXWin/makefile
+++ b/7zip/Bundles/SFXWin/makefile
@@ -61,6 +61,7 @@ WIN_CTRL_OBJS = \
$O\ProgressUtils.obj \
$O\StreamBinder.obj \
$O\StreamObjects.obj \
+ $O\StreamUtils.obj \
UI_COMMON_OBJS = \
$O\ArchiveExtractCallback.obj \
diff --git a/7zip/Common/FileStreams.cpp b/7zip/Common/FileStreams.cpp
index 5cdd4d6e..8a000e4e 100755
--- a/7zip/Common/FileStreams.cpp
+++ b/7zip/Common/FileStreams.cpp
@@ -39,7 +39,7 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
#ifdef _WIN32
UInt32 realProcessedSize;
- bool result = File.Read(data, size, realProcessedSize);
+ bool result = File.ReadPart(data, size, realProcessedSize);
if(processedSize != NULL)
*processedSize = realProcessedSize;
return ConvertBoolToHRESULT(result);
@@ -54,14 +54,9 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
if(processedSize != NULL)
*processedSize = (UInt32)res;
return S_OK;
-
+
#endif
}
-
-STDMETHODIMP CInFileStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
-{
- return Read(data, size, processedSize);
-}
#ifndef _WIN32_WCE
STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
@@ -95,10 +90,6 @@ STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSi
#endif
}
-STDMETHODIMP CStdInFileStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
-{
- return Read(data, size, processedSize);
-}
#endif
STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin,
@@ -155,7 +146,7 @@ STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *proces
#ifdef _WIN32
UInt32 realProcessedSize;
- bool result = File.Write(data, size, realProcessedSize);
+ bool result = File.WritePart(data, size, realProcessedSize);
if(processedSize != NULL)
*processedSize = realProcessedSize;
return ConvertBoolToHRESULT(result);
@@ -174,12 +165,6 @@ STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *proces
#endif
}
-STDMETHODIMP COutFileStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize)
-{
- return Write(data, size, processedSize);
-}
-
-
STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin,
UInt64 *newPosition)
{
@@ -229,7 +214,7 @@ STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *pro
#ifdef _WIN32
UInt32 realProcessedSize;
BOOL res = TRUE;
- while (size > 0)
+ if (size > 0)
{
// Seems that Windows doesn't like big amounts writing to stdout.
// So we limit portions by 32KB.
@@ -238,8 +223,6 @@ STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *pro
sizeTemp = size;
res = ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),
data, sizeTemp, (DWORD *)&realProcessedSize, NULL);
- if (realProcessedSize == 0)
- break;
size -= realProcessedSize;
data = (const void *)((const Byte *)data + realProcessedSize);
if(processedSize != NULL)
@@ -265,8 +248,4 @@ STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *pro
#endif
}
-STDMETHODIMP CStdOutFileStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize)
-{
- return Write(data, size, processedSize);
-}
#endif
diff --git a/7zip/Common/FileStreams.h b/7zip/Common/FileStreams.h
index ea79e1b9..9326372a 100755
--- a/7zip/Common/FileStreams.h
+++ b/7zip/Common/FileStreams.h
@@ -36,7 +36,6 @@ public:
MY_UNKNOWN_IMP2(IInStream, IStreamGetSize)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
STDMETHOD(GetSize)(UInt64 *size);
@@ -55,7 +54,6 @@ public:
virtual ~CStdInFileStream() {}
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
};
#endif
@@ -80,7 +78,6 @@ public:
MY_UNKNOWN_IMP1(IOutStream)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
STDMETHOD(SetSize)(Int64 newSize);
};
@@ -95,7 +92,6 @@ public:
virtual ~CStdOutFileStream() {}
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
};
#endif
diff --git a/7zip/Common/InBuffer.cpp b/7zip/Common/InBuffer.cpp
index 8c05874b..f1d58756 100755
--- a/7zip/Common/InBuffer.cpp
+++ b/7zip/Common/InBuffer.cpp
@@ -59,7 +59,7 @@ bool CInBuffer::ReadBlock()
return false;
_processedSize += (_buffer - _bufferBase);
UInt32 numProcessedBytes;
- HRESULT result = _stream->ReadPart(_bufferBase, _bufferSize, &numProcessedBytes);
+ HRESULT result = _stream->Read(_bufferBase, _bufferSize, &numProcessedBytes);
#ifdef _NO_EXCEPTIONS
ErrorCode = result;
#else
@@ -71,3 +71,10 @@ bool CInBuffer::ReadBlock()
_wasFinished = (numProcessedBytes == 0);
return (!_wasFinished);
}
+
+Byte CInBuffer::ReadBlock2()
+{
+ if(!ReadBlock())
+ return 0xFF;
+ return *_buffer++;
+}
diff --git a/7zip/Common/InBuffer.h b/7zip/Common/InBuffer.h
index 3d53eb51..057caa16 100755
--- a/7zip/Common/InBuffer.h
+++ b/7zip/Common/InBuffer.h
@@ -17,15 +17,16 @@ public:
class CInBuffer
{
- UInt64 _processedSize;
- Byte *_bufferBase;
- UInt32 _bufferSize;
Byte *_buffer;
Byte *_bufferLimit;
+ Byte *_bufferBase;
CMyComPtr<ISequentialInStream> _stream;
+ UInt64 _processedSize;
+ UInt32 _bufferSize;
bool _wasFinished;
bool ReadBlock();
+ Byte ReadBlock2();
public:
#ifdef _NO_EXCEPTIONS
@@ -53,8 +54,7 @@ public:
Byte ReadByte()
{
if(_buffer >= _bufferLimit)
- if(!ReadBlock())
- return 0xFF;
+ return ReadBlock2();
return *_buffer++;
}
void ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
diff --git a/7zip/Common/InOutTempBuffer.cpp b/7zip/Common/InOutTempBuffer.cpp
index d7fb79d7..d24212de 100755
--- a/7zip/Common/InOutTempBuffer.cpp
+++ b/7zip/Common/InOutTempBuffer.cpp
@@ -6,6 +6,8 @@
#include "../../Common/Defs.h"
// #include "Windows/Defs.h"
+#include "StreamUtils.h"
+
using namespace NWindows;
using namespace NFile;
using namespace NDirectory;
@@ -86,34 +88,12 @@ bool CInOutTempBuffer::InitReading()
return true;
}
-/*
-bool CInOutTempBuffer::Read(void *data, UInt32 maxSize, UInt32 &processedSize)
-{
- processedSize = 0;
- if (_currentPositionInBuffer < _bufferPosition)
- {
- UInt32 sizeToRead = MyMin(_bufferPosition - _currentPositionInBuffer, maxSize);
- memmove(data, _buffer + _currentPositionInBuffer, sizeToRead);
- data = ((Byte *)data) + sizeToRead;
- _currentPositionInBuffer += sizeToRead;
- processedSize += sizeToRead;
- maxSize -= sizeToRead;
- }
- if (maxSize == 0 || !_tmpFileCreated)
- return true;
- UInt32 localProcessedSize;
- bool result = _inFile.Read(data, maxSize, localProcessedSize);
- processedSize += localProcessedSize;
- return result;
-}
-*/
-
HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream)
{
if (_currentPositionInBuffer < _bufferPosition)
{
UInt32 sizeToWrite = _bufferPosition - _currentPositionInBuffer;
- RINOK(stream->Write(_buffer + _currentPositionInBuffer, sizeToWrite, NULL));
+ RINOK(WriteStream(stream, _buffer + _currentPositionInBuffer, sizeToWrite, NULL));
_currentPositionInBuffer += sizeToWrite;
}
if (!_tmpFileCreated)
@@ -121,11 +101,11 @@ HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream)
while(true)
{
UInt32 localProcessedSize;
- if (!_inFile.Read(_buffer, kTmpBufferMemorySize, localProcessedSize))
+ if (!_inFile.ReadPart(_buffer, kTmpBufferMemorySize, localProcessedSize))
return E_FAIL;
if (localProcessedSize == 0)
return S_OK;
- RINOK(stream->Write(_buffer, localProcessedSize, NULL));
+ RINOK(WriteStream(stream, _buffer, localProcessedSize, NULL));
}
}
@@ -141,8 +121,3 @@ STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UInt32 size, U
*processedSize = size;
return S_OK;
}
-
-STDMETHODIMP CSequentialOutTempBufferImp::WritePart(const void *data, UInt32 size, UInt32 *processedSize)
-{
- return Write(data, size, processedSize);
-}
diff --git a/7zip/Common/InOutTempBuffer.h b/7zip/Common/InOutTempBuffer.h
index 97ed56d0..3abe76ec 100755
--- a/7zip/Common/InOutTempBuffer.h
+++ b/7zip/Common/InOutTempBuffer.h
@@ -33,7 +33,6 @@ public:
UInt64 GetDataSize() const { return _fileSize; }
bool FlushWrite();
bool InitReading();
- // bool Read(void *data, UInt32 maxSize, UInt32 &processedSize);
HRESULT WriteToStream(ISequentialOutStream *stream);
};
@@ -51,7 +50,6 @@ public:
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
};
#endif
diff --git a/7zip/Common/LSBFDecoder.h b/7zip/Common/LSBFDecoder.h
index 0fb31a3e..1f5dcb59 100755
--- a/7zip/Common/LSBFDecoder.h
+++ b/7zip/Common/LSBFDecoder.h
@@ -22,7 +22,7 @@ template<class TInByte>
class CBaseDecoder
{
protected:
- UInt32 m_BitPos;
+ int m_BitPos;
UInt32 m_Value;
TInByte m_Stream;
public:
@@ -41,7 +41,7 @@ public:
{ return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; }
UInt64 GetProcessedBitsSize() const
{ return (m_Stream.GetProcessedSize() << 3) - (kNumBigValueBits - m_BitPos); }
- UInt32 GetBitPosition() const { return (m_BitPos & 7); }
+ int GetBitPosition() const { return (m_BitPos & 7); }
void Normalize()
{
@@ -57,7 +57,7 @@ public:
}
}
- UInt32 ReadBits(UInt32 numBits)
+ UInt32 ReadBits(int numBits)
{
Normalize();
UInt32 res = m_Value & ((1 << numBits) - 1);
@@ -65,12 +65,12 @@ public:
m_Value >>= numBits;
return res;
}
-
+
bool ExtraBitsWereRead() const
{
if (NumExtraBytes == 0)
return false;
- return ((kNumBigValueBits - m_BitPos) < (NumExtraBytes << 3));
+ return ((UInt32)(kNumBigValueBits - m_BitPos) < (NumExtraBytes << 3));
}
};
@@ -101,19 +101,19 @@ public:
}
}
- UInt32 GetValue(UInt32 numBits)
+ UInt32 GetValue(int numBits)
{
Normalize();
return ((this->m_Value >> (8 - this->m_BitPos)) & kMask) >> (kNumValueBits - numBits);
}
- void MovePos(UInt32 numBits)
+ void MovePos(int numBits)
{
this->m_BitPos += numBits;
m_NormalValue >>= numBits;
}
- UInt32 ReadBits(UInt32 numBits)
+ UInt32 ReadBits(int numBits)
{
Normalize();
UInt32 res = m_NormalValue & ( (1 << numBits) - 1);
diff --git a/7zip/Common/LimitedStreams.cpp b/7zip/Common/LimitedStreams.cpp
index 6de13c05..c048d49d 100755
--- a/7zip/Common/LimitedStreams.cpp
+++ b/7zip/Common/LimitedStreams.cpp
@@ -11,8 +11,7 @@ void CLimitedSequentialInStream::Init(ISequentialInStream *stream, UInt64 stream
_size = streamSize;
}
-STDMETHODIMP CLimitedSequentialInStream::Read(void *data,
- UInt32 size, UInt32 *processedSize)
+STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 processedSizeReal;
UInt32 sizeToRead = UInt32(MyMin(_size, UInt64(size)));
@@ -22,15 +21,4 @@ STDMETHODIMP CLimitedSequentialInStream::Read(void *data,
*processedSize = processedSizeReal;
return result;
}
-
-STDMETHODIMP CLimitedSequentialInStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
-{
- UInt32 processedSizeReal;
- UInt32 sizeToRead = UInt32(MyMin(_size, UInt64(size)));
- HRESULT result = _stream->ReadPart(data, sizeToRead, &processedSizeReal);
- _size -= processedSizeReal;
- if(processedSize != NULL)
- *processedSize = processedSizeReal;
- return result;
-}
diff --git a/7zip/Common/LimitedStreams.h b/7zip/Common/LimitedStreams.h
index 02633bc6..d40be974 100755
--- a/7zip/Common/LimitedStreams.h
+++ b/7zip/Common/LimitedStreams.h
@@ -18,7 +18,6 @@ public:
MY_UNKNOWN_IMP
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
};
#endif
diff --git a/7zip/Common/LockedStream.cpp b/7zip/Common/LockedStream.cpp
index 44af676d..36be1ceb 100755
--- a/7zip/Common/LockedStream.cpp
+++ b/7zip/Common/LockedStream.cpp
@@ -5,22 +5,13 @@
#include "LockedStream.h"
HRESULT CLockedInStream::Read(UInt64 startPos, void *data, UInt32 size,
- UInt32 *processedSize)
-{
- NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
- RINOK(_stream->Seek(startPos, STREAM_SEEK_SET, NULL));
- return _stream->Read(data, size, processedSize);
-}
-
-HRESULT CLockedInStream::ReadPart(UInt64 startPos, void *data, UInt32 size,
UInt32 *processedSize)
{
NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
RINOK(_stream->Seek(startPos, STREAM_SEEK_SET, NULL));
- return _stream->ReadPart(data, size, processedSize);
+ return _stream->Read(data, size, processedSize);
}
-
STDMETHODIMP CLockedSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessedSize = 0;
@@ -30,13 +21,3 @@ STDMETHODIMP CLockedSequentialInStreamImp::Read(void *data, UInt32 size, UInt32
*processedSize = realProcessedSize;
return result;
}
-
-STDMETHODIMP CLockedSequentialInStreamImp::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
-{
- UInt32 realProcessedSize = 0;
- HRESULT result = _lockedInStream->ReadPart(_pos, data, size, &realProcessedSize);
- _pos += realProcessedSize;
- if (processedSize != NULL)
- *processedSize = realProcessedSize;
- return result;
-}
diff --git a/7zip/Common/LockedStream.h b/7zip/Common/LockedStream.h
index 90f28330..1c1e1793 100755
--- a/7zip/Common/LockedStream.h
+++ b/7zip/Common/LockedStream.h
@@ -15,7 +15,6 @@ public:
void Init(IInStream *stream)
{ _stream = stream; }
HRESULT Read(UInt64 startPos, void *data, UInt32 size, UInt32 *processedSize);
- HRESULT ReadPart(UInt64 startPos, void *data, UInt32 size, UInt32 *processedSize);
};
class CLockedSequentialInStreamImp:
@@ -34,7 +33,6 @@ public:
MY_UNKNOWN_IMP
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
};
#endif
diff --git a/7zip/Common/MSBFDecoder.h b/7zip/Common/MSBFDecoder.h
index c21d5547..dc80c0f7 100755
--- a/7zip/Common/MSBFDecoder.h
+++ b/7zip/Common/MSBFDecoder.h
@@ -4,6 +4,9 @@
#ifndef __STREAM_MSBFDECODER_H
#define __STREAM_MSBFDECODER_H
+#include "../../Common/Types.h"
+#include "../IStream.h"
+
namespace NStream {
namespace NMSBF {
@@ -16,10 +19,10 @@ const UInt32 kMask = (1 << kNumValueBits) - 1;
template<class TInByte>
class CDecoder
{
- TInByte m_Stream;
UInt32 m_BitPos;
UInt32 m_Value;
public:
+ TInByte m_Stream;
bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }
void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream);}
void ReleaseStream() { m_Stream.ReleaseStream();}
diff --git a/7zip/Common/OffsetStream.cpp b/7zip/Common/OffsetStream.cpp
index cc93c0db..997ccae2 100755
--- a/7zip/Common/OffsetStream.cpp
+++ b/7zip/Common/OffsetStream.cpp
@@ -12,17 +12,11 @@ HRESULT COffsetOutStream::Init(IOutStream *stream, UInt64 offset)
return _stream->Seek(offset, STREAM_SEEK_SET, NULL);
}
-STDMETHODIMP COffsetOutStream::Write(const void *data, UInt32 size,
- UInt32 *processedSize)
+STDMETHODIMP COffsetOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
return _stream->Write(data, size, processedSize);
}
-STDMETHODIMP COffsetOutStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize)
-{
- return _stream->WritePart(data, size, processedSize);
-}
-
STDMETHODIMP COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin,
UInt64 *newPosition)
{
diff --git a/7zip/Common/OffsetStream.h b/7zip/Common/OffsetStream.h
index 20c65452..57a055cc 100755
--- a/7zip/Common/OffsetStream.h
+++ b/7zip/Common/OffsetStream.h
@@ -18,7 +18,6 @@ public:
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
STDMETHOD(SetSize)(Int64 newSize);
};
diff --git a/7zip/Common/OutBuffer.cpp b/7zip/Common/OutBuffer.cpp
index ab4651b4..38827de1 100755
--- a/7zip/Common/OutBuffer.cpp
+++ b/7zip/Common/OutBuffer.cpp
@@ -32,35 +32,78 @@ void COutBuffer::SetStream(ISequentialOutStream *stream)
void COutBuffer::Init()
{
- _processedSize = 0;
+ _streamPos = 0;
+ _limitPos = _bufferSize;
_pos = 0;
+ _processedSize = 0;
#ifdef _NO_EXCEPTIONS
ErrorCode = S_OK;
#endif
}
-HRESULT COutBuffer::Flush()
+UInt64 COutBuffer::GetProcessedSize() const
+{
+ UInt64 res = _processedSize + _pos - _streamPos;
+ if (_streamPos > _pos)
+ res += _bufferSize;
+ return res;
+}
+
+HRESULT COutBuffer::FlushPart()
{
- if (_pos == 0)
- return S_OK;
- UInt32 processedSize;
- HRESULT result = _stream->Write(_buffer, _pos, &processedSize);
- if (result != S_OK)
+ UInt32 size = (_streamPos >= _pos) ? (_bufferSize - _streamPos) : (_pos - _streamPos);
+ HRESULT result = S_OK;
+ #ifdef _NO_EXCEPTIONS
+ if (ErrorCode != S_OK)
+ result = ErrorCode;
+ #endif
+ if (size == 0)
return result;
- if (_pos != processedSize)
- return E_FAIL;
- _processedSize += processedSize;
- _pos = 0;
- return S_OK;
+ if (_buffer2 != 0)
+ {
+ memmove(_buffer2, _buffer + _streamPos, size);
+ _buffer2 += size;
+ }
+
+ if (_stream != 0
+ #ifdef _NO_EXCEPTIONS
+ && (ErrorCode != S_OK)
+ #endif
+ )
+ {
+ UInt32 processedSize = 0;
+ result = _stream->Write(_buffer + _streamPos, size, &processedSize);
+ size = processedSize;
+ }
+ _streamPos += size;
+ _limitPos = (_streamPos > _pos) ? _streamPos : _bufferSize;
+ if (_streamPos == _bufferSize)
+ _streamPos = 0;
+ _processedSize += size;
+ return result;
}
-void COutBuffer::WriteBlock()
+HRESULT COutBuffer::Flush()
{
#ifdef _NO_EXCEPTIONS
if (ErrorCode != S_OK)
- return;
+ return ErrorCode;
#endif
- HRESULT result = Flush();
+
+ while(_streamPos != _pos)
+ {
+ HRESULT result = FlushPart();
+ if (result != S_OK)
+ return result;
+ }
+ return S_OK;
+}
+
+void COutBuffer::FlushWithCheck()
+{
+ HRESULT result = FlushPart();
+ if (_pos == _bufferSize)
+ _pos = 0;
#ifdef _NO_EXCEPTIONS
ErrorCode = result;
#else
diff --git a/7zip/Common/OutBuffer.h b/7zip/Common/OutBuffer.h
index b161ad65..51ccb659 100755
--- a/7zip/Common/OutBuffer.h
+++ b/7zip/Common/OutBuffer.h
@@ -16,48 +16,40 @@ struct COutBufferException
class COutBuffer
{
+protected:
Byte *_buffer;
UInt32 _pos;
+ UInt32 _limitPos;
+ UInt32 _streamPos;
UInt32 _bufferSize;
CMyComPtr<ISequentialOutStream> _stream;
UInt64 _processedSize;
+ Byte *_buffer2;
- void WriteBlock();
+ HRESULT FlushPart();
+ void FlushWithCheck();
public:
#ifdef _NO_EXCEPTIONS
HRESULT ErrorCode;
#endif
- COutBuffer(): _buffer(0), _pos(0), _stream(0) {}
+ COutBuffer(): _buffer(0), _pos(0), _stream(0), _buffer2(0) {}
~COutBuffer() { Free(); }
bool Create(UInt32 bufferSize);
void Free();
+ void SetMemStream(Byte *buffer) { _buffer2 = buffer; }
void SetStream(ISequentialOutStream *stream);
void Init();
HRESULT Flush();
void ReleaseStream() { _stream.Release(); }
- /*
- void *GetBuffer(UInt32 &sizeAvail)
- {
- sizeAvail = _bufferSize - _pos;
- return _buffer + _pos;
- }
- void MovePos(UInt32 num)
- {
- _pos += num;
- if(_pos >= _bufferSize)
- WriteBlock();
- }
- */
-
void WriteByte(Byte b)
{
_buffer[_pos++] = b;
- if(_pos >= _bufferSize)
- WriteBlock();
+ if(_pos == _limitPos)
+ FlushWithCheck();
}
void WriteBytes(const void *data, size_t size)
{
@@ -65,7 +57,7 @@ public:
WriteByte(((const Byte *)data)[i]);
}
- UInt64 GetProcessedSize() const { return _processedSize + _pos; }
+ UInt64 GetProcessedSize() const;
};
#endif
diff --git a/7zip/Common/StreamBinder.cpp b/7zip/Common/StreamBinder.cpp
index fb4ca59f..2984c2d9 100755
--- a/7zip/Common/StreamBinder.cpp
+++ b/7zip/Common/StreamBinder.cpp
@@ -17,7 +17,6 @@ public:
MY_UNKNOWN_IMP
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
private:
CStreamBinder *m_StreamBinder;
public:
@@ -27,9 +26,6 @@ public:
STDMETHODIMP CSequentialInStreamForBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
{ return m_StreamBinder->Read(data, size, processedSize); }
-
-STDMETHODIMP CSequentialInStreamForBinder::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
- { return m_StreamBinder->ReadPart(data, size, processedSize); }
class CSequentialOutStreamForBinder:
public ISequentialOutStream,
@@ -39,7 +35,6 @@ public:
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
private:
CStreamBinder *m_StreamBinder;
@@ -51,9 +46,6 @@ public:
STDMETHODIMP CSequentialOutStreamForBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)
{ return m_StreamBinder->Write(data, size, processedSize); }
-STDMETHODIMP CSequentialOutStreamForBinder::WritePart(const void *data, UInt32 size, UInt32 *processedSize)
- { return m_StreamBinder->WritePart(data, size, processedSize); }
-
//////////////////////////
// CStreamBinder
@@ -106,7 +98,7 @@ void CStreamBinder::CreateStreams(ISequentialInStream **inStream,
ProcessedSize = 0;
}
-STDMETHODIMP CStreamBinder::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
+HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 sizeToRead = size;
if (size > 0)
@@ -132,33 +124,12 @@ STDMETHODIMP CStreamBinder::ReadPart(void *data, UInt32 size, UInt32 *processedS
return S_OK;
}
-STDMETHODIMP CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
-{
- UInt32 fullProcessedSize = 0;
- UInt32 realProcessedSize;
- HRESULT result = S_OK;
- while(size > 0)
- {
- result = ReadPart(data, size, &realProcessedSize);
- size -= realProcessedSize;
- data = (void *)((Byte *)data + realProcessedSize);
- fullProcessedSize += realProcessedSize;
- if (result != S_OK)
- break;
- if (realProcessedSize == 0)
- break;
- }
- if (processedSize != NULL)
- *processedSize = fullProcessedSize;
- return result;
-}
-
void CStreamBinder::CloseRead()
{
_readStreamIsClosedEvent->Set();
}
-STDMETHODIMP CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)
+HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
if (size > 0)
{
@@ -184,11 +155,6 @@ STDMETHODIMP CStreamBinder::Write(const void *data, UInt32 size, UInt32 *process
return S_OK;
}
-STDMETHODIMP CStreamBinder::WritePart(const void *data, UInt32 size, UInt32 *processedSize)
-{
- return Write(data, size, processedSize);
-}
-
void CStreamBinder::CloseWrite()
{
// _bufferSize must be = 0
diff --git a/7zip/Common/StreamBinder.h b/7zip/Common/StreamBinder.h
index 588713ed..a66c3acb 100755
--- a/7zip/Common/StreamBinder.h
+++ b/7zip/Common/StreamBinder.h
@@ -26,12 +26,10 @@ public:
void CreateStreams(ISequentialInStream **inStream,
ISequentialOutStream **outStream);
- STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
+ HRESULT Read(void *data, UInt32 size, UInt32 *processedSize);
void CloseRead();
- STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
+ HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize);
void CloseWrite();
void ReInit();
};
diff --git a/7zip/Common/StreamObjects.cpp b/7zip/Common/StreamObjects.cpp
index 8632cff4..c89f64e1 100755
--- a/7zip/Common/StreamObjects.cpp
+++ b/7zip/Common/StreamObjects.cpp
@@ -5,45 +5,6 @@
#include "StreamObjects.h"
#include "../../Common/Defs.h"
-/*
-STDMETHODIMP COutStreamImp::Read(void *data, ULONG size, ULONG *processedSize)
- { return E_NOTIMPL; }
-
-STDMETHODIMP COutStreamImp::Write(void const *data, ULONG size, ULONG *processedSize)
-{
- size_t newCapacity = _size + size;
- _buffer.EnsureCapacity(newCapacity);
- memmove(_buffer + _size, data, size);
- if(processedSize != NULL)
- *processedSize = size;
- _size += size;
- return S_OK;
-}
-
-void CInStreamImp::Init(Byte *dataPointer, size_t size)
-{
- _dataPointer = dataPointer;
- _size = size;
- _pos = 0;
-}
-
-STDMETHODIMP CInStreamImp::Read(void *data, ULONG size, ULONG *processedSize)
-{
- UInt32 numBytesToRead = MyMin(_pos + (UInt32)size, _size) - _pos;
- if(processedSize != NULL)
- *processedSize = numBytesToRead;
- memmove(data, _dataPointer + _pos, numBytesToRead);
- _pos += numBytesToRead;
- if(numBytesToRead == size)
- return S_OK;
- else
- return S_FALSE;
-}
-
-STDMETHODIMP CInStreamImp::Write(void const *data, ULONG size, ULONG *processedSize)
- { return E_NOTIMPL; }
-*/
-
STDMETHODIMP CSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *processedSize)
{
@@ -55,13 +16,6 @@ STDMETHODIMP CSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *proce
return S_OK;
}
-STDMETHODIMP CSequentialInStreamImp::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
-{
- return Read(data, size, processedSize);
-}
-
-////////////////////
-
void CWriteBuffer::Write(const void *data, size_t size)
{
@@ -79,11 +33,6 @@ STDMETHODIMP CSequentialOutStreamImp::Write(const void *data, UInt32 size, UInt3
return S_OK;
}
-STDMETHODIMP CSequentialOutStreamImp::WritePart(const void *data, UInt32 size, UInt32 *processedSize)
-{
- return Write(data, size, processedSize);
-}
-
STDMETHODIMP CSequentialOutStreamImp2::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 newSize = size;
@@ -98,13 +47,6 @@ STDMETHODIMP CSequentialOutStreamImp2::Write(const void *data, UInt32 size, UInt
return S_OK;
}
-STDMETHODIMP CSequentialOutStreamImp2::WritePart(const void *data, UInt32 size, UInt32 *processedSize)
-{
- return Write(data, size, processedSize);
-}
-
-
-
STDMETHODIMP CSequentialInStreamSizeCount::Read(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessedSize;
@@ -115,37 +57,8 @@ STDMETHODIMP CSequentialInStreamSizeCount::Read(void *data, UInt32 size, UInt32
return result;
}
-STDMETHODIMP CSequentialInStreamSizeCount::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
-{
- UInt32 realProcessedSize;
- HRESULT result = _stream->ReadPart(data, size, &realProcessedSize);
- _size += realProcessedSize;
- if (processedSize != 0)
- *processedSize = realProcessedSize;
- return result;
-}
-
STDMETHODIMP CSequentialInStreamRollback::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- HRESULT result = S_OK;
- UInt32 realProcessedSizeTotal = 0;
- while (size > 0)
- {
- UInt32 realProcessedSize = 0;
- result = ReadPart(data, size, &realProcessedSize);
- size -= realProcessedSize;
- data = ((Byte *)data + realProcessedSize);
- realProcessedSizeTotal += realProcessedSize;
- if (realProcessedSize == 0 || result != S_OK)
- break;
- }
- if (processedSize != 0)
- *processedSize = realProcessedSizeTotal;
- return result;
-}
-
-STDMETHODIMP CSequentialInStreamRollback::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
-{
if (_currentPos != _currentSize)
{
size_t curSize = _currentSize - _currentPos;
@@ -160,7 +73,7 @@ STDMETHODIMP CSequentialInStreamRollback::ReadPart(void *data, UInt32 size, UInt
UInt32 realProcessedSize;
if (size > _bufferSize)
size = (UInt32)_bufferSize;
- HRESULT result = _stream->ReadPart(_buffer, size, &realProcessedSize);
+ HRESULT result = _stream->Read(_buffer, size, &realProcessedSize);
memmove(data, _buffer, realProcessedSize);
_size += realProcessedSize;
_currentSize = realProcessedSize;
@@ -178,7 +91,6 @@ HRESULT CSequentialInStreamRollback::Rollback(size_t rollbackSize)
return S_OK;
}
-
STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessedSize;
@@ -188,13 +100,3 @@ STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size,
*processedSize = realProcessedSize;
return result;
}
-
-STDMETHODIMP CSequentialOutStreamSizeCount::WritePart(const void *data, UInt32 size, UInt32 *processedSize)
-{
- UInt32 realProcessedSize;
- HRESULT result = _stream->WritePart(data, size, &realProcessedSize);
- _size += realProcessedSize;
- if (processedSize != 0)
- *processedSize = realProcessedSize;
- return result;
-}
diff --git a/7zip/Common/StreamObjects.h b/7zip/Common/StreamObjects.h
index 78e31980..4dd01e47 100755
--- a/7zip/Common/StreamObjects.h
+++ b/7zip/Common/StreamObjects.h
@@ -7,44 +7,6 @@
#include "../../Common/MyCom.h"
#include "../IStream.h"
-/*
-class COutStreamImp:
- public ISequentialStream,
- public CMyUnknownImp
-{
- CByteDynamicBuffer _buffer;
- size_t _size;
-public:
- COutStreamImp(): _size(0) {}
- void Init(){ _size = 0; }
- size_t GetSize() const { return _size; }
- const CByteDynamicBuffer& GetBuffer() const { return _buffer; }
-
- MY_UNKNOWN_IMP
-
- STDMETHODIMP Read(void *data, ULONG size, ULONG *processedSize);
- STDMETHODIMP Write(void const *data, ULONG size, ULONG *processedSize);
-};
-
-class CInStreamImp:
- public ISequentialStream,
- public CMyUnknownImp
-{
- Byte *_dataPointer;
- size_t _size;
- size_t _pos;
-
-public:
- CInStreamImp(): _size(0xFFFFFFFF), _pos(0), _dataPointer(NULL) {}
- void Init(Byte *dataPointer, size_t size);
-
- MY_UNKNOWN_IMP
-
- STDMETHODIMP Read(void *data, ULONG size, ULONG *processedSize);
- STDMETHODIMP Write(void const *data, ULONG size, ULONG *processedSize);
-};
-*/
-
class CSequentialInStreamImp:
public ISequentialInStream,
public CMyUnknownImp
@@ -64,7 +26,6 @@ public:
MY_UNKNOWN_IMP
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
};
@@ -74,15 +35,7 @@ class CWriteBuffer
size_t _size;
public:
CWriteBuffer(): _size(0) {}
- // void Init(size_t size = 0)
- void Init()
- {
- /*
- if (size > 0)
- _buffer.EnsureCapacity(size);
- */
- _size = 0;
- }
+ void Init() { _size = 0; }
void Write(const void *data, size_t size);
size_t GetSize() const { return _size; }
const CByteDynamicBuffer& GetBuffer() const { return _buffer; }
@@ -94,24 +47,13 @@ class CSequentialOutStreamImp:
{
CWriteBuffer _writeBuffer;
public:
- void Init()
- {
- _writeBuffer.Init();
- }
-
- /*
- void Init(size_t size = 0)
- {
- _writeBuffer.Init(size);
- }
- */
+ void Init() { _writeBuffer.Init(); }
size_t GetSize() const { return _writeBuffer.GetSize(); }
const CByteDynamicBuffer& GetBuffer() const { return _writeBuffer.GetBuffer(); }
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
};
class CSequentialOutStreamImp2:
@@ -133,7 +75,6 @@ public:
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
};
class CSequentialInStreamSizeCount:
@@ -153,7 +94,6 @@ public:
MY_UNKNOWN_IMP
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
};
class CSequentialInStreamRollback:
@@ -191,7 +131,6 @@ public:
MY_UNKNOWN_IMP
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
HRESULT Rollback(size_t rollbackSize);
};
@@ -212,7 +151,6 @@ public:
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
};
#endif
diff --git a/7zip/Common/StreamUtils.cpp b/7zip/Common/StreamUtils.cpp
new file mode 100755
index 00000000..a5d9ac0e
--- /dev/null
+++ b/7zip/Common/StreamUtils.cpp
@@ -0,0 +1,44 @@
+// StreamUtils.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/MyCom.h"
+#include "StreamUtils.h"
+
+HRESULT ReadStream(ISequentialInStream *stream, void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (processedSize != 0)
+ *processedSize = 0;
+ while(size != 0)
+ {
+ UInt32 processedSizeLoc;
+ HRESULT res = stream->Read(data, size, &processedSizeLoc);
+ if (processedSize != 0)
+ *processedSize += processedSizeLoc;
+ data = (Byte *)((Byte *)data + processedSizeLoc);
+ size -= processedSizeLoc;
+ RINOK(res);
+ if (processedSizeLoc == 0)
+ return S_OK;
+ }
+ return S_OK;
+}
+
+HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (processedSize != 0)
+ *processedSize = 0;
+ while(size != 0)
+ {
+ UInt32 processedSizeLoc;
+ HRESULT res = stream->Write(data, size, &processedSizeLoc);
+ if (processedSize != 0)
+ *processedSize += processedSizeLoc;
+ data = (const void *)((const Byte *)data + processedSizeLoc);
+ size -= processedSizeLoc;
+ RINOK(res);
+ if (processedSizeLoc == 0)
+ break;
+ }
+ return S_OK;
+}
diff --git a/7zip/Common/StreamUtils.h b/7zip/Common/StreamUtils.h
new file mode 100755
index 00000000..59f88733
--- /dev/null
+++ b/7zip/Common/StreamUtils.h
@@ -0,0 +1,11 @@
+// StreamUtils.h
+
+#ifndef __STREAMUTILS_H
+#define __STREAMUTILS_H
+
+#include "../IStream.h"
+
+HRESULT ReadStream(ISequentialInStream *stream, void *data, UInt32 size, UInt32 *processedSize);
+HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size, UInt32 *processedSize);
+
+#endif
diff --git a/7zip/Compress/Arj/Decoder1.cpp b/7zip/Compress/Arj/ArjDecoder1.cpp
index b9f2881c..a560f443 100755
--- a/7zip/Compress/Arj/Decoder1.cpp
+++ b/7zip/Compress/Arj/ArjDecoder1.cpp
@@ -2,7 +2,7 @@
#include "StdAfx.h"
-#include "Decoder1.h"
+#include "ArjDecoder1.h"
#include "Windows/Defs.h"
diff --git a/7zip/Compress/Arj/Decoder1.h b/7zip/Compress/Arj/ArjDecoder1.h
index 22b1002b..22b1002b 100755
--- a/7zip/Compress/Arj/Decoder1.h
+++ b/7zip/Compress/Arj/ArjDecoder1.h
diff --git a/7zip/Compress/Arj/Decoder2.cpp b/7zip/Compress/Arj/ArjDecoder2.cpp
index ab6c57fa..1fb20649 100755
--- a/7zip/Compress/Arj/Decoder2.cpp
+++ b/7zip/Compress/Arj/ArjDecoder2.cpp
@@ -2,7 +2,7 @@
#include "StdAfx.h"
-#include "Decoder2.h"
+#include "ArjDecoder2.h"
namespace NCompress{
namespace NArj {
diff --git a/7zip/Compress/Arj/Decoder2.h b/7zip/Compress/Arj/ArjDecoder2.h
index bc54c1dd..bc54c1dd 100755
--- a/7zip/Compress/Arj/Decoder2.h
+++ b/7zip/Compress/Arj/ArjDecoder2.h
diff --git a/7zip/Compress/BZip2/BZip2CRC.cpp b/7zip/Compress/BZip2/BZip2CRC.cpp
index d3ca5e15..ba9ddb7e 100755
--- a/7zip/Compress/BZip2/BZip2CRC.cpp
+++ b/7zip/Compress/BZip2/BZip2CRC.cpp
@@ -23,4 +23,4 @@ class CBZip2CRCTableInit
{
public:
CBZip2CRCTableInit() { CBZip2CRC::InitTable(); }
-} g_CRCTableInit;
+} g_BZip2CRCTableInit;
diff --git a/7zip/Compress/BZip2/BZip2Decoder.cpp b/7zip/Compress/BZip2/BZip2Decoder.cpp
index e620f027..0f0fbbfa 100755
--- a/7zip/Compress/BZip2/BZip2Decoder.cpp
+++ b/7zip/Compress/BZip2/BZip2Decoder.cpp
@@ -174,7 +174,8 @@ HRESULT CDecoder::ReadBlock(UInt32 blockSizeMax, CState &state)
}
for (; i < kMaxAlphaSize; i++)
lens[i] = 0;
- m_HuffmanDecoders[t].SetCodeLengths(lens);
+ if(!m_HuffmanDecoders[t].SetCodeLengths(lens))
+ return S_FALSE;
}
while(++t < numTables);
@@ -202,7 +203,7 @@ HRESULT CDecoder::ReadBlock(UInt32 blockSizeMax, CState &state)
}
groupSize--; \
- int nextSym = (int)huffmanDecoder->DecodeSymbol(&m_InStream);
+ UInt32 nextSym = huffmanDecoder->DecodeSymbol(&m_InStream);
if (nextSym < 2)
{
@@ -220,13 +221,18 @@ HRESULT CDecoder::ReadBlock(UInt32 blockSizeMax, CState &state)
while(--runCounter != 0);
runPower = 0;
}
- if (nextSym > numInUse)
+ if (nextSym <= (UInt32)numInUse)
+ {
+ Byte b = mtf.GetAndMove((int)nextSym - 1);
+ if (blockSize >= blockSizeMax)
+ return S_FALSE;
+ state.CharCounters[b]++;
+ state.tt[blockSize++] = (UInt32)b;
+ }
+ else if (nextSym == (UInt32)numInUse + 1)
break;
- Byte b = mtf.GetAndMove(nextSym - 1);
- if (blockSize >= blockSizeMax)
+ else
return S_FALSE;
- state.CharCounters[b]++;
- state.tt[blockSize++] = (UInt32)b;
}
}
if (state.OrigPtr >= blockSize)
diff --git a/7zip/Compress/Branch/x86_2.cpp b/7zip/Compress/Branch/x86_2.cpp
index 2f67899f..00f1ea7a 100755
--- a/7zip/Compress/Branch/x86_2.cpp
+++ b/7zip/Compress/Branch/x86_2.cpp
@@ -102,7 +102,6 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
UInt32 nowPos = 0;
UInt64 nowPos64 = 0;
UInt32 bufferPos = 0;
- UInt32 processedSize;
Byte prevByte = 0;
@@ -112,8 +111,18 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
while(true)
{
- UInt32 size = kBufferSize - bufferPos;
- RINOK(inStream->Read(_buffer + bufferPos, size, &processedSize));
+ UInt32 processedSize = 0;
+ while(true)
+ {
+ UInt32 size = kBufferSize - (bufferPos + processedSize);
+ UInt32 processedSizeLoc;
+ if (size == 0)
+ break;
+ RINOK(inStream->Read(_buffer + bufferPos + processedSize, size, &processedSizeLoc));
+ if (processedSizeLoc == 0)
+ break;
+ processedSize += processedSizeLoc;
+ }
UInt32 endPos = bufferPos + processedSize;
if (endPos < 5)
diff --git a/7zip/Compress/Copy/Copy.dsp b/7zip/Compress/Copy/Copy.dsp
index ddf4d66b..099a433d 100755
--- a/7zip/Compress/Copy/Copy.dsp
+++ b/7zip/Compress/Copy/Copy.dsp
@@ -125,6 +125,18 @@ SOURCE=..\..\..\Common\Alloc.cpp
SOURCE=..\..\..\Common\Alloc.h
# End Source File
# End Group
+# Begin Group "7-Zip Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# End Group
# Begin Source File
SOURCE=.\CopyCoder.cpp
diff --git a/7zip/Compress/Copy/CopyCoder.cpp b/7zip/Compress/Copy/CopyCoder.cpp
index d8c7635b..dac68711 100755
--- a/7zip/Compress/Copy/CopyCoder.cpp
+++ b/7zip/Compress/Copy/CopyCoder.cpp
@@ -4,6 +4,7 @@
#include "CopyCoder.h"
#include "../../../Common/Alloc.h"
+#include "../../Common/StreamUtils.h"
namespace NCompress {
@@ -34,10 +35,10 @@ STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
if (outSize != 0)
if (size > *outSize - TotalSize)
size = (UInt32)(*outSize - TotalSize);
- RINOK(inStream->ReadPart(_buffer, size, &realProcessedSize));
+ RINOK(inStream->Read(_buffer, size, &realProcessedSize));
if(realProcessedSize == 0)
break;
- RINOK(outStream->Write(_buffer, realProcessedSize, NULL));
+ RINOK(WriteStream(outStream, _buffer, realProcessedSize, NULL));
TotalSize += realProcessedSize;
if (progress != NULL)
{
diff --git a/7zip/Compress/Copy/makefile b/7zip/Compress/Copy/makefile
index 6c04af97..8c108fbc 100755
--- a/7zip/Compress/Copy/makefile
+++ b/7zip/Compress/Copy/makefile
@@ -10,10 +10,14 @@ COPY_OBJS = \
COMMON_OBJS = \
$O\Alloc.obj \
+7ZIP_COMMON_OBJS = \
+ $O\StreamUtils.obj \
+
OBJS = \
$O\StdAfx.obj \
$(COPY_OBJS) \
$(COMMON_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
$O\resource.res
!include "../../../Build.mak"
@@ -22,3 +26,5 @@ $(COPY_OBJS): $(*B).cpp
$(COMPL)
$(COMMON_OBJS): ../../../Common/$(*B).cpp
$(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
diff --git a/7zip/Compress/Deflate/DeflateDecoder.cpp b/7zip/Compress/Deflate/DeflateDecoder.cpp
index 96da47b3..16369326 100755
--- a/7zip/Compress/Deflate/DeflateDecoder.cpp
+++ b/7zip/Compress/Deflate/DeflateDecoder.cpp
@@ -8,7 +8,10 @@ namespace NCompress {
namespace NDeflate {
namespace NDecoder {
-CCoder::CCoder(bool deflate64Mode): _deflate64Mode(deflate64Mode) {}
+const int kLenIdFinished = -1;
+const int kLenIdNeedInit = -2;
+
+CCoder::CCoder(bool deflate64Mode): _deflate64Mode(deflate64Mode), _keepHistory(false) {}
void CCoder::DeCodeLevelTable(Byte *newLevels, int numLevels)
{
@@ -40,211 +43,256 @@ void CCoder::DeCodeLevelTable(Byte *newLevels, int numLevels)
}
}
-void CCoder::ReadTables(void)
-{
- if(m_FinalBlock) // test it
- throw CException(CException::kData);
+#define RIF(x) { if (!(x)) return false; }
+bool CCoder::ReadTables(void)
+{
m_FinalBlock = (m_InBitStream.ReadBits(kFinalBlockFieldSize) == NFinalBlockField::kFinalBlock);
-
int blockType = m_InBitStream.ReadBits(kBlockTypeFieldSize);
+ if (blockType > NBlockType::kDynamicHuffman)
+ return false;
- switch(blockType)
+ if (blockType == NBlockType::kStored)
{
- case NBlockType::kStored:
- {
- m_StoredMode = true;
- UInt32 currentBitPosition = m_InBitStream.GetBitPosition();
- UInt32 numBitsForAlign = currentBitPosition > 0 ? (8 - currentBitPosition): 0;
- if (numBitsForAlign > 0)
- m_InBitStream.ReadBits(numBitsForAlign);
- m_StoredBlockSize = m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize);
- UInt16 onesComplementReverse = ~(UInt16)(m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize));
- if (m_StoredBlockSize != onesComplementReverse)
- throw CException(CException::kData);
- break;
- }
- case NBlockType::kFixedHuffman:
- case NBlockType::kDynamicHuffman:
- {
- m_StoredMode = false;
- Byte litLenLevels[kStaticMainTableSize];
- Byte distLevels[kStaticDistTableSize];
- if (blockType == NBlockType::kFixedHuffman)
- {
- int i;
-
- // Leteral / length levels
- for (i = 0; i < 144; i++)
- litLenLevels[i] = 8;
- for (; i < 256; i++)
- litLenLevels[i] = 9;
- for (; i < 280; i++)
- litLenLevels[i] = 7;
- for (; i < 288; i++) /* make a complete, but wrong code set */
- litLenLevels[i] = 8;
-
- // Distance levels
- for (i = 0; i < kStaticDistTableSize; i++) // test it: infozip only use kDistTableSize
- distLevels[i] = 5;
- }
- else // in case when (blockType == kDeflateBlockTypeFixedHuffman)
- {
- int numLitLenLevels = m_InBitStream.ReadBits(kDeflateNumberOfLengthCodesFieldSize) +
- kDeflateNumberOfLitLenCodesMin;
- int numDistLevels = m_InBitStream.ReadBits(kDeflateNumberOfDistanceCodesFieldSize) +
- kDeflateNumberOfDistanceCodesMin;
- int numLevelCodes = m_InBitStream.ReadBits(kDeflateNumberOfLevelCodesFieldSize) +
- kDeflateNumberOfLevelCodesMin;
-
- int numLevels = _deflate64Mode ? kHeapTablesSizesSum64 :
- kHeapTablesSizesSum32;
-
- Byte levelLevels[kLevelTableSize];
- int i;
- for (i = 0; i < kLevelTableSize; i++)
- {
- int position = kCodeLengthAlphabetOrder[i];
- if(i < numLevelCodes)
- levelLevels[position] = Byte(m_InBitStream.ReadBits(kDeflateLevelCodeFieldSize));
- else
- levelLevels[position] = 0;
- }
-
- try
- {
- m_LevelDecoder.SetCodeLengths(levelLevels);
- }
- catch(...)
- {
- throw CException(CException::kData);
- }
-
- Byte tmpLevels[kStaticMaxTableSize];
- DeCodeLevelTable(tmpLevels, numLitLenLevels + numDistLevels);
-
- memmove(litLenLevels, tmpLevels, numLitLenLevels);
- memset(litLenLevels + numLitLenLevels, 0,
- kStaticMainTableSize - numLitLenLevels);
-
- memmove(distLevels, tmpLevels + numLitLenLevels, numDistLevels);
- memset(distLevels + numDistLevels, 0, kStaticDistTableSize - numDistLevels);
- }
- try
- {
- m_MainDecoder.SetCodeLengths(litLenLevels);
- m_DistDecoder.SetCodeLengths(distLevels);
- }
- catch(...)
- {
- throw CException(CException::kData);
- }
- break;
- }
- default:
- throw CException(CException::kData);
+ m_StoredMode = true;
+ UInt32 currentBitPosition = m_InBitStream.GetBitPosition();
+ UInt32 numBitsForAlign = currentBitPosition > 0 ? (8 - currentBitPosition): 0;
+ if (numBitsForAlign > 0)
+ m_InBitStream.ReadBits(numBitsForAlign);
+ m_StoredBlockSize = m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize);
+ UInt16 onesComplementReverse = ~(UInt16)(m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize));
+ return (m_StoredBlockSize == onesComplementReverse);
}
+
+ m_StoredMode = false;
+ Byte litLenLevels[kStaticMainTableSize];
+ Byte distLevels[kStaticDistTableSize];
+ if (blockType == NBlockType::kFixedHuffman)
+ {
+ int i;
+
+ for (i = 0; i < 144; i++)
+ litLenLevels[i] = 8;
+ for (; i < 256; i++)
+ litLenLevels[i] = 9;
+ for (; i < 280; i++)
+ litLenLevels[i] = 7;
+ for (; i < 288; i++) // make a complete, but wrong code set
+ litLenLevels[i] = 8;
+
+ for (i = 0; i < kStaticDistTableSize; i++) // test it: InfoZip only uses kDistTableSize
+ distLevels[i] = 5;
+ }
+ else // (blockType == kDynamicHuffman)
+ {
+ int numLitLenLevels = m_InBitStream.ReadBits(kDeflateNumberOfLengthCodesFieldSize) +
+ kDeflateNumberOfLitLenCodesMin;
+ int numDistLevels = m_InBitStream.ReadBits(kDeflateNumberOfDistanceCodesFieldSize) +
+ kDeflateNumberOfDistanceCodesMin;
+ int numLevelCodes = m_InBitStream.ReadBits(kDeflateNumberOfLevelCodesFieldSize) +
+ kDeflateNumberOfLevelCodesMin;
+
+ int numLevels = _deflate64Mode ? kHeapTablesSizesSum64 : kHeapTablesSizesSum32;
+
+ Byte levelLevels[kLevelTableSize];
+ for (int i = 0; i < kLevelTableSize; i++)
+ {
+ int position = kCodeLengthAlphabetOrder[i];
+ if(i < numLevelCodes)
+ levelLevels[position] = Byte(m_InBitStream.ReadBits(kDeflateLevelCodeFieldSize));
+ else
+ levelLevels[position] = 0;
+ }
+
+ RIF(m_LevelDecoder.SetCodeLengths(levelLevels));
+
+ Byte tmpLevels[kStaticMaxTableSize];
+ DeCodeLevelTable(tmpLevels, numLitLenLevels + numDistLevels);
+
+ memmove(litLenLevels, tmpLevels, numLitLenLevels);
+ memset(litLenLevels + numLitLenLevels, 0, kStaticMainTableSize - numLitLenLevels);
+
+ memmove(distLevels, tmpLevels + numLitLenLevels, numDistLevels);
+ memset(distLevels + numDistLevels, 0, kStaticDistTableSize - numDistLevels);
+ }
+ RIF(m_MainDecoder.SetCodeLengths(litLenLevels));
+ return m_DistDecoder.SetCodeLengths(distLevels);
}
-HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
- ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
- ICompressProgressInfo *progress)
+HRESULT CCoder::CodeSpec(UInt32 curSize)
{
- if (!m_OutWindowStream.Create(_deflate64Mode ? kHistorySize64: kHistorySize32))
- return E_OUTOFMEMORY;
- if (!m_InBitStream.Create(1 << 17))
- return E_OUTOFMEMORY;
- UInt64 pos = 0;
- m_OutWindowStream.SetStream(outStream);
- m_OutWindowStream.Init(false);
- m_InBitStream.SetStream(inStream);
- m_InBitStream.Init();
- CCoderReleaser coderReleaser(this);
+ if (_remainLen == kLenIdFinished)
+ return S_OK;
+ if (_remainLen == kLenIdNeedInit)
+ {
+ if (!_keepHistory)
+ {
+ if (!m_OutWindowStream.Create(_deflate64Mode ? kHistorySize64: kHistorySize32))
+ return E_OUTOFMEMORY;
+ }
+ if (!m_InBitStream.Create(1 << 17))
+ return E_OUTOFMEMORY;
+ m_OutWindowStream.Init(_keepHistory);
+ m_InBitStream.Init();
+ m_FinalBlock = false;
+ _remainLen = 0;
+ _needReadTable = true;
+ }
- m_FinalBlock = false;
+ if (curSize == 0)
+ return S_OK;
- while(!m_FinalBlock)
+ while(_remainLen > 0 && curSize > 0)
{
- if (progress != NULL)
+ _remainLen--;
+ Byte b = m_OutWindowStream.GetByte(_rep0);
+ m_OutWindowStream.PutByte(b);
+ curSize--;
+ }
+
+ while(curSize > 0)
+ {
+ if (_needReadTable)
{
- UInt64 packSize = m_InBitStream.GetProcessedSize();
- RINOK(progress->SetRatioInfo(&packSize, &pos));
+ if (m_FinalBlock)
+ {
+ _remainLen = kLenIdFinished;
+ break;
+ }
+ if (!ReadTables())
+ return S_FALSE;
+ _needReadTable = false;
}
- ReadTables();
+
if(m_StoredMode)
{
- for (UInt32 i = 0; i < m_StoredBlockSize; i++)
- m_OutWindowStream.PutByte(Byte(m_InBitStream.ReadBits(8)));
- pos += m_StoredBlockSize;
+ for (; m_StoredBlockSize > 0 && curSize > 0; m_StoredBlockSize--, curSize--)
+ m_OutWindowStream.PutByte((Byte)m_InBitStream.ReadBits(8));
+ _needReadTable = (m_StoredBlockSize == 0);
continue;
}
- while(true)
+ while(curSize > 0)
{
if (m_InBitStream.NumExtraBytes > 4)
- throw CException(CException::kData);
+ return S_FALSE;
UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
if (number < 256)
{
- if (outSize != NULL)
- if (pos >= *outSize)
- throw CException(CException::kData);
- m_OutWindowStream.PutByte(Byte(number));
- pos++;
+ m_OutWindowStream.PutByte((Byte)number);
+ curSize--;
continue;
}
else if (number >= kMatchNumber)
{
- if (outSize != NULL)
- if (pos >= *outSize)
- throw CException(CException::kData);
number -= kMatchNumber;
-
- UInt32 length;
- if (_deflate64Mode)
- {
- length = UInt32(kLenStart64[number]) + kMatchMinLen;
- UInt32 numBits = kLenDirectBits64[number];
- if (numBits > 0)
- length += m_InBitStream.ReadBits(numBits);
- }
- else
+ UInt32 len;
{
- length = UInt32(kLenStart32[number]) + kMatchMinLen;
- UInt32 numBits = kLenDirectBits32[number];
- if (numBits > 0)
- length += m_InBitStream.ReadBits(numBits);
+ int numBits;
+ if (_deflate64Mode)
+ {
+ len = kLenStart64[number];
+ numBits = kLenDirectBits64[number];
+ }
+ else
+ {
+ len = kLenStart32[number];
+ numBits = kLenDirectBits32[number];
+ }
+ len += kMatchMinLen + m_InBitStream.ReadBits(numBits);
}
-
-
+ UInt32 locLen = len;
+ if (locLen > curSize)
+ locLen = (UInt32)curSize;
number = m_DistDecoder.DecodeSymbol(&m_InBitStream);
+ if (number >= kStaticDistTableSize)
+ return S_FALSE;
UInt32 distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]);
- if (distance >= pos)
- throw "data error";
- m_OutWindowStream.CopyBlock(distance, length);
- pos += length;
+ if (!m_OutWindowStream.CopyBlock(distance, locLen))
+ return S_FALSE;
+ curSize -= locLen;
+ len -= locLen;
+ if (len != 0)
+ {
+ _remainLen = (int)len;
+ _rep0 = distance;
+ break;
+ }
}
else if (number == kReadTableNumber)
+ {
+ _needReadTable = true;
break;
+ }
else
- throw CException(CException::kData);
+ return S_FALSE;
}
}
- coderReleaser.NeedFlush = false;
- return m_OutWindowStream.Flush();
+ return S_OK;
}
-HRESULT CCoder::BaseCode(ISequentialInStream *inStream,
- ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *, 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; }
+ SetInStream(inStream);
+ m_OutWindowStream.SetStream(outStream);
+ SetOutStreamSize(outSize);
+ CCoderReleaser flusher(this);
+
+ const UInt64 start = m_OutWindowStream.GetProcessedSize();
+ while(true)
+ {
+ UInt32 curSize = 1 << 18;
+ if (outSize != 0)
+ {
+ const UInt64 rem = *outSize - (m_OutWindowStream.GetProcessedSize() - start);
+ if (curSize > rem)
+ curSize = (UInt32)rem;
+ }
+ if (curSize == 0)
+ break;
+ RINOK(CodeSpec(curSize));
+ if (_remainLen == kLenIdFinished)
+ break;
+ if (progress != NULL)
+ {
+ UInt64 inSize = m_InBitStream.GetProcessedSize();
+ UInt64 nowPos64 = m_OutWindowStream.GetProcessedSize() - start;
+ RINOK(progress->SetRatioInfo(&inSize, &nowPos64));
+ }
+ }
+ flusher.NeedFlush = false;
+ return Flush();
+}
+
+
+#ifdef _NO_EXCEPTIONS
+
+#define DEFLATE_TRY_BEGIN
+#define DEFLATE_TRY_END
+
+#else
+
+#define DEFLATE_TRY_BEGIN try {
+#define DEFLATE_TRY_END } \
+ catch(const CInBufferException &e) { return e.ErrorCode; } \
+ catch(const CLZOutWindowException &e) { return e.ErrorCode; } \
catch(...) { return S_FALSE; }
+
+#endif
+
+HRESULT CCoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ DEFLATE_TRY_BEGIN
+ return CodeReal(inStream, outStream, inSize, outSize, progress);
+ DEFLATE_TRY_END
}
-HRESULT CCoder::BaseGetInStreamProcessedSize(UInt64 *value)
+STDMETHODIMP CCoder::GetInStreamProcessedSize(UInt64 *value)
{
if (value == NULL)
return E_INVALIDARG;
@@ -252,29 +300,41 @@ HRESULT CCoder::BaseGetInStreamProcessedSize(UInt64 *value)
return S_OK;
}
-STDMETHODIMP CCOMCoder::GetInStreamProcessedSize(UInt64 *value)
+STDMETHODIMP CCoder::SetInStream(ISequentialInStream *inStream)
{
- return BaseGetInStreamProcessedSize(value);
+ m_InBitStream.SetStream(inStream);
+ return S_OK;
}
-HRESULT CCOMCoder::Code(ISequentialInStream *inStream,
- ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
- ICompressProgressInfo *progress)
+STDMETHODIMP CCoder::ReleaseInStream()
{
- return BaseCode(inStream, outStream, inSize, outSize, progress);
+ m_InBitStream.ReleaseStream();
+ return S_OK;
}
-STDMETHODIMP CCOMCoder64::GetInStreamProcessedSize(UInt64 *value)
+STDMETHODIMP CCoder::SetOutStreamSize(const UInt64 *outSize)
{
- return BaseGetInStreamProcessedSize(value);
+ _remainLen = kLenIdNeedInit;
+ m_OutWindowStream.Init(_keepHistory);
+ return S_OK;
}
-HRESULT CCOMCoder64::Code(ISequentialInStream *inStream,
- ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
- ICompressProgressInfo *progress)
+#ifdef _ST_MODE
+
+STDMETHODIMP CCoder::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- return BaseCode(inStream, outStream, inSize, outSize, progress);
+ DEFLATE_TRY_BEGIN
+ if (processedSize)
+ *processedSize = 0;
+ const UInt64 startPos = m_OutWindowStream.GetProcessedSize();
+ m_OutWindowStream.SetMemStream((Byte *)data);
+ RINOK(CodeSpec(size));
+ if (processedSize)
+ *processedSize = (UInt32)(m_OutWindowStream.GetProcessedSize() - startPos);
+ return Flush();
+ DEFLATE_TRY_END
}
+#endif
}}}
diff --git a/7zip/Compress/Deflate/DeflateDecoder.h b/7zip/Compress/Deflate/DeflateDecoder.h
index b1be0084..628af839 100755
--- a/7zip/Compress/Deflate/DeflateDecoder.h
+++ b/7zip/Compress/Deflate/DeflateDecoder.h
@@ -30,7 +30,15 @@ public:
typedef NStream::NLSBF::CDecoder<CInBuffer> CInBit;
-class CCoder
+class CCoder:
+ public ICompressCoder,
+ public ICompressGetInStreamProcessedSize,
+ #ifdef _ST_MODE
+ public ICompressSetInStream,
+ public ICompressSetOutStreamSize,
+ public ISequentialInStream,
+ #endif
+ public CMyUnknownImp
{
CLZOutWindow m_OutWindowStream;
CInBit m_InBitStream;
@@ -38,20 +46,27 @@ class CCoder
NCompress::NHuffman::CDecoder<kNumHuffmanBits, kStaticDistTableSize> m_DistDecoder;
NCompress::NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder;
- bool m_FinalBlock;
- bool m_StoredMode;
UInt32 m_StoredBlockSize;
+ bool m_FinalBlock;
+ bool m_StoredMode;
bool _deflate64Mode;
+ bool _keepHistory;
+ int _remainLen;
+ UInt32 _rep0;
+ bool _needReadTable;
+
void DeCodeLevelTable(Byte *newLevels, int numLevels);
- void ReadTables();
+ bool ReadTables();
void CCoder::ReleaseStreams()
{
m_OutWindowStream.ReleaseStream();
- m_InBitStream.ReleaseStream();
+ ReleaseInStream();
}
+
+ HRESULT Flush() { return m_OutWindowStream.Flush(); }
class CCoderReleaser
{
CCoder *m_Coder;
@@ -61,63 +76,60 @@ class CCoder
~CCoderReleaser()
{
if (NeedFlush)
- m_Coder->m_OutWindowStream.Flush();
+ m_Coder->Flush();
m_Coder->ReleaseStreams();
}
};
friend class CCoderReleaser;
+ HRESULT CodeSpec(UInt32 curSize);
public:
- CCoder(bool deflate64Mode = false);
+ CCoder(bool deflate64Mode);
+ void SetKeepHistory(bool keepHistory) { _keepHistory = keepHistory; }
HRESULT CodeReal(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress);
- HRESULT BaseCode(ISequentialInStream *inStream,
+ #ifdef _ST_MODE
+ MY_UNKNOWN_IMP4(
+ ICompressGetInStreamProcessedSize,
+ ICompressSetInStream,
+ ICompressSetOutStreamSize,
+ ISequentialInStream
+ )
+ #else
+ MY_UNKNOWN_IMP1(
+ 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);
+
+ #ifdef _ST_MODE
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ #endif
+
// IGetInStreamProcessedSize
- HRESULT BaseGetInStreamProcessedSize(UInt64 *aValue);
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
};
class CCOMCoder :
- public ICompressCoder,
- public ICompressGetInStreamProcessedSize,
- public CMyUnknownImp,
public CCoder
{
public:
-
- MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
-
- STDMETHOD(Code)(ISequentialInStream *inStream,
- ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
- ICompressProgressInfo *progress);
-
- // IGetInStreamProcessedSize
- STDMETHOD(GetInStreamProcessedSize)(UInt64 *aValue);
-
CCOMCoder(): CCoder(false) {}
};
class CCOMCoder64 :
- public ICompressCoder,
- public ICompressGetInStreamProcessedSize,
- public CMyUnknownImp,
public CCoder
{
public:
- MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
-
- STDMETHOD(Code)(ISequentialInStream *inStream,
- ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
- ICompressProgressInfo *progress);
-
- // IGetInStreamProcessedSize
- STDMETHOD(GetInStreamProcessedSize)(UInt64 *aValue);
-
CCOMCoder64(): CCoder(true) {}
};
diff --git a/7zip/Compress/Huffman/HuffmanDecoder.h b/7zip/Compress/Huffman/HuffmanDecoder.h
index c956869e..57115197 100755
--- a/7zip/Compress/Huffman/HuffmanDecoder.h
+++ b/7zip/Compress/Huffman/HuffmanDecoder.h
@@ -8,86 +8,81 @@
namespace NCompress {
namespace NHuffman {
-class CDecoderException{};
+const int kNumTableBits = 9;
-const UInt32 kValueTableBits = 9;
-
-template <int kNumBitsInLongestCode, UInt32 m_NumSymbols>
+template <int kNumBitsMax, UInt32 m_NumSymbols>
class CDecoder
{
- UInt32 m_Limits[kNumBitsInLongestCode + 1]; // m_Limits[i] = value limit for symbols with length = i
- UInt32 m_Positions[kNumBitsInLongestCode + 1]; // m_Positions[i] = index in m_Symbols[] of first symbol with length = i
- UInt32 m_Symbols[m_NumSymbols]; // symbols: at first with len = 1 then 2, ... 15.
- Byte m_Lengths[1 << kValueTableBits];
+ UInt32 m_Limits[kNumBitsMax + 1]; // m_Limits[i] = value limit for symbols with length = i
+ UInt32 m_Positions[kNumBitsMax + 1]; // m_Positions[i] = index in m_Symbols[] of first symbol with length = i
+ UInt32 m_Symbols[m_NumSymbols];
+ Byte m_Lengths[1 << kNumTableBits]; // Table oh length for short codes.
+
public:
- void SetCodeLengths(const Byte *codeLengths);
+
+ bool SetCodeLengths(const Byte *codeLengths)
+ {
+ int lenCounts[kNumBitsMax + 1], tmpPositions[kNumBitsMax + 1];
+ int i;
+ for(i = 1; i <= kNumBitsMax; i++)
+ lenCounts[i] = 0;
+ UInt32 symbol;
+ for (symbol = 0; symbol < m_NumSymbols; symbol++)
+ {
+ int len = codeLengths[symbol];
+ if (len > kNumBitsMax)
+ return false;
+ lenCounts[len]++;
+ m_Symbols[symbol] = 0xFFFFFFFF;
+ }
+ lenCounts[0] = 0;
+ m_Positions[0] = m_Limits[0] = 0;
+ UInt32 startPos = 0;
+ UInt32 index = 0;
+ const UInt32 kMaxValue = (1 << kNumBitsMax);
+ for (i = 1; i <= kNumBitsMax; i++)
+ {
+ startPos += lenCounts[i] << (kNumBitsMax - i);
+ if (startPos > kMaxValue)
+ return false;
+ m_Limits[i] = (i == kNumBitsMax) ? kMaxValue : startPos;
+ m_Positions[i] = m_Positions[i - 1] + lenCounts[i - 1];
+ tmpPositions[i] = m_Positions[i];
+ if(i <= kNumTableBits)
+ {
+ UInt32 limit = (m_Limits[i] >> (kNumBitsMax - kNumTableBits));
+ for (; index < limit; index++)
+ m_Lengths[index] = (Byte)i;
+ }
+ }
+ for (symbol = 0; symbol < m_NumSymbols; symbol++)
+ {
+ int len = codeLengths[symbol];
+ if (len != 0)
+ m_Symbols[tmpPositions[len]++] = symbol;
+ }
+ return true;
+ }
+
template <class TBitDecoder>
UInt32 DecodeSymbol(TBitDecoder *bitStream)
{
- UInt32 numBits;
-
- UInt32 value = bitStream->GetValue(kNumBitsInLongestCode);
-
- if (value < m_Limits[kValueTableBits])
- numBits = m_Lengths[value >> (kNumBitsInLongestCode - kValueTableBits)];
+ int numBits;
+ UInt32 value = bitStream->GetValue(kNumBitsMax);
+ if (value < m_Limits[kNumTableBits])
+ numBits = m_Lengths[value >> (kNumBitsMax - kNumTableBits)];
else
- for (numBits = kValueTableBits + 1; numBits < kNumBitsInLongestCode; numBits++)
- if (value < m_Limits[numBits])
- break;
+ for (numBits = kNumTableBits + 1; value >= m_Limits[numBits]; numBits++);
bitStream->MovePos(numBits);
UInt32 index = m_Positions[numBits] +
- ((value - m_Limits[numBits - 1]) >> (kNumBitsInLongestCode - numBits));
+ ((value - m_Limits[numBits - 1]) >> (kNumBitsMax - numBits));
if (index >= m_NumSymbols)
- throw CDecoderException(); // test it
+ // throw CDecoderException(); // test it
+ return 0xFFFFFFFF;
return m_Symbols[index];
}
};
-template <int kNumBitsInLongestCode, UInt32 m_NumSymbols>
-void CDecoder<kNumBitsInLongestCode, m_NumSymbols>::SetCodeLengths(const Byte *codeLengths)
-{
- int lenCounts[kNumBitsInLongestCode + 1], tmpPositions[kNumBitsInLongestCode + 1];
- int i;
- for(i = 1; i <= kNumBitsInLongestCode; i++)
- lenCounts[i] = 0;
- UInt32 symbol;
- for (symbol = 0; symbol < m_NumSymbols; symbol++)
- {
- Byte codeLength = codeLengths[symbol];
- if (codeLength > kNumBitsInLongestCode)
- throw CDecoderException();
- lenCounts[codeLength]++;
- }
- lenCounts[0] = 0;
- tmpPositions[0] = m_Positions[0] = m_Limits[0] = 0;
- UInt32 startPos = 0;
- UInt32 index = 0;
- const UInt32 kMaxValue = (1 << kNumBitsInLongestCode);
- for (i = 1; i <= kNumBitsInLongestCode; i++)
- {
- startPos += lenCounts[i] << (kNumBitsInLongestCode - i);
- if (startPos > kMaxValue)
- throw CDecoderException();
- m_Limits[i] = startPos;
- m_Positions[i] = m_Positions[i - 1] + lenCounts[i - 1];
- tmpPositions[i] = m_Positions[i];
-
- if(i <= kValueTableBits)
- {
- UInt32 limit = (m_Limits[i] >> (kNumBitsInLongestCode - kValueTableBits)); // change it
- memset(m_Lengths + index, Byte(i), limit - index);
- index = limit;
- }
- }
-
- // if (startPos != kMaxValue)
- // throw CDecoderException();
-
- for (symbol = 0; symbol < m_NumSymbols; symbol++)
- if (codeLengths[symbol] != 0)
- m_Symbols[tmpPositions[codeLengths[symbol]]++] = symbol;
-}
-
}}
#endif
diff --git a/7zip/Compress/Implode/ImplodeDecoder.cpp b/7zip/Compress/Implode/ImplodeDecoder.cpp
index d8b5daea..b7689f62 100755
--- a/7zip/Compress/Implode/ImplodeDecoder.cpp
+++ b/7zip/Compress/Implode/ImplodeDecoder.cpp
@@ -74,7 +74,7 @@ void CCoder::ReleaseStreams()
m_InBitStream.ReleaseStream();
}
-void CCoder::ReadLevelItems(NImplode::NHuffman::CDecoder &decoder,
+bool CCoder::ReadLevelItems(NImplode::NHuffman::CDecoder &decoder,
Byte *levels, int numLevelItems)
{
int numCodedStructures = m_InBitStream.ReadBits(kNumBitsInByte) +
@@ -92,32 +92,26 @@ void CCoder::ReadLevelItems(NImplode::NHuffman::CDecoder &decoder,
levels[currentIndex++] = level;
}
if (currentIndex != numLevelItems)
- throw CException(CException::kData);
- try
- {
- decoder.SetCodeLengths(levels);
- }
- catch(const NImplode::NHuffman::CDecoderException &)
- {
- throw CException(CException::kData);
- }
+ return false;
+ return decoder.SetCodeLengths(levels);
}
-void CCoder::ReadTables(void)
+bool CCoder::ReadTables(void)
{
if (m_LiteralsOn)
{
Byte literalLevels[kLiteralTableSize];
- ReadLevelItems(m_LiteralDecoder, literalLevels, kLiteralTableSize);
+ if (!ReadLevelItems(m_LiteralDecoder, literalLevels, kLiteralTableSize))
+ return false;
}
Byte lengthLevels[kLengthTableSize];
- ReadLevelItems(m_LengthDecoder, lengthLevels, kLengthTableSize);
+ if (!ReadLevelItems(m_LengthDecoder, lengthLevels, kLengthTableSize))
+ return false;
Byte distanceLevels[kDistanceTableSize];
- ReadLevelItems(m_DistanceDecoder, distanceLevels, kDistanceTableSize);
-
+ return ReadLevelItems(m_DistanceDecoder, distanceLevels, kDistanceTableSize);
}
class CCoderReleaser
@@ -146,7 +140,8 @@ STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream,
m_InBitStream.Init();
CCoderReleaser coderReleaser(this);
- ReadTables();
+ if (!ReadTables())
+ return S_FALSE;
while(pos < unPackSize)
{
@@ -158,10 +153,13 @@ STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream,
if(m_InBitStream.ReadBits(1) == kMatchId) // match
{
UInt32 lowDistBits = m_InBitStream.ReadBits(m_NumDistanceLowDirectBits);
- UInt32 distance = (m_DistanceDecoder.DecodeSymbol(&m_InBitStream) <<
- m_NumDistanceLowDirectBits) + lowDistBits;
-
+ 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);
@@ -177,8 +175,16 @@ STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream,
}
else
{
- Byte b = Byte(m_LiteralsOn ? m_LiteralDecoder.DecodeSymbol(&m_InBitStream) :
- m_InBitStream.ReadBits(kNumBitsInByte));
+ 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++;
}
diff --git a/7zip/Compress/Implode/ImplodeDecoder.h b/7zip/Compress/Implode/ImplodeDecoder.h
index 7dd35003..627edba4 100755
--- a/7zip/Compress/Implode/ImplodeDecoder.h
+++ b/7zip/Compress/Implode/ImplodeDecoder.h
@@ -32,9 +32,8 @@ class CCoder :
int m_NumDistanceLowDirectBits;
UInt32 m_MinMatchLength;
- void ReadLevelItems(NImplode::NHuffman::CDecoder &table,
- Byte *levels, int numLevelItems);
- void ReadTables();
+ bool ReadLevelItems(NImplode::NHuffman::CDecoder &table, Byte *levels, int numLevelItems);
+ bool ReadTables();
void DeCodeLevelTable(Byte *newLevels, int numLevels);
public:
CCoder();
diff --git a/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp b/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp
index 15046d55..2fbb77fd 100755
--- a/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp
+++ b/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp
@@ -19,7 +19,7 @@ CDecoder::~CDecoder()
delete []m_Symbols;
}
-void CDecoder::SetCodeLengths(const Byte *codeLengths)
+bool CDecoder::SetCodeLengths(const Byte *codeLengths)
{
// int lenCounts[kNumBitsInLongestCode + 1], tmpPositions[kNumBitsInLongestCode + 1];
int lenCounts[kNumBitsInLongestCode + 2], tmpPositions[kNumBitsInLongestCode + 1];
@@ -44,7 +44,7 @@ void CDecoder::SetCodeLengths(const Byte *codeLengths)
{
startPos += lenCounts[i] << (kNumBitsInLongestCode - i);
if (startPos > kMaxValue)
- throw CDecoderException();
+ return false;
m_Limitits[i] = startPos;
m_Positions[i] = m_Positions[i + 1] + lenCounts[i + 1];
tmpPositions[i] = m_Positions[i] + lenCounts[i];
@@ -54,12 +54,13 @@ void CDecoder::SetCodeLengths(const Byte *codeLengths)
// if _ZIP_MODE do not throw exception for trees containing only one node
// #ifndef _ZIP_MODE
if (startPos != kMaxValue)
- throw CDecoderException();
+ 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)
@@ -76,12 +77,12 @@ UInt32 CDecoder::DecodeSymbol(CInBit *inStream)
}
}
if (i == 0)
- throw CDecoderException();
+ return 0xFFFFFFFF;
inStream->MovePos(numBits);
UInt32 index = m_Positions[numBits] +
((value - m_Limitits[numBits + 1]) >> (kNumBitsInLongestCode - numBits));
if (index >= m_NumSymbols)
- throw CDecoderException(); // test it
+ return 0xFFFFFFFF;
return m_Symbols[index];
}
diff --git a/7zip/Compress/Implode/ImplodeHuffmanDecoder.h b/7zip/Compress/Implode/ImplodeHuffmanDecoder.h
index 5a8b4e90..9f7aeca1 100755
--- a/7zip/Compress/Implode/ImplodeHuffmanDecoder.h
+++ b/7zip/Compress/Implode/ImplodeHuffmanDecoder.h
@@ -11,7 +11,6 @@ namespace NImplode {
namespace NHuffman {
const int kNumBitsInLongestCode = 16;
-class CDecoderException{};
typedef NStream::NLSBF::CDecoder<CInBuffer> CInBit;
@@ -25,7 +24,7 @@ public:
CDecoder(UInt32 numSymbols);
~CDecoder();
- void SetCodeLengths(const Byte *codeLengths);
+ bool SetCodeLengths(const Byte *codeLengths);
UInt32 DecodeSymbol(CInBit *inStream);
};
diff --git a/7zip/Compress/LZ/LZInWindow.cpp b/7zip/Compress/LZ/LZInWindow.cpp
index a16a2c19..64928806 100755
--- a/7zip/Compress/LZ/LZInWindow.cpp
+++ b/7zip/Compress/LZ/LZInWindow.cpp
@@ -72,7 +72,7 @@ HRESULT CLZInWindow::ReadBlock()
if(size == 0)
return S_OK;
UInt32 numReadBytes;
- RINOK(_stream->ReadPart(_buffer + _streamPos, size, &numReadBytes));
+ RINOK(_stream->Read(_buffer + _streamPos, size, &numReadBytes));
if(numReadBytes == 0)
{
_posLimit = _streamPos;
diff --git a/7zip/Compress/LZ/LZOutWindow.cpp b/7zip/Compress/LZ/LZOutWindow.cpp
index 4101079b..093c9ce8 100755
--- a/7zip/Compress/LZ/LZOutWindow.cpp
+++ b/7zip/Compress/LZ/LZOutWindow.cpp
@@ -5,62 +5,29 @@
#include "../../../Common/Alloc.h"
#include "LZOutWindow.h"
-bool CLZOutWindow::Create(UInt32 windowSize)
-{
- const UInt32 kMinBlockSize = 1;
- if (windowSize < kMinBlockSize)
- windowSize = kMinBlockSize;
- if (_buffer != 0 && _windowSize == windowSize)
- return true;
-
- // It's here to allow Solid decoding / and calling Create for RAR
- _pos = 0;
- _streamPos = 0;
-
- Free();
- _windowSize = windowSize;
- _buffer = (Byte *)::BigAlloc(windowSize);
- return (_buffer != 0);
-}
-
-void CLZOutWindow::Free()
-{
- ::BigFree(_buffer);
- _buffer = 0;
-}
-
-void CLZOutWindow::SetStream(ISequentialOutStream *stream)
-{
- ReleaseStream();
- _stream = stream;
- _stream->AddRef();
-}
-
void CLZOutWindow::Init(bool solid)
{
if(!solid)
{
_streamPos = 0;
+ _limitPos = _bufferSize;
_pos = 0;
+ _processedSize = 0;
+ _overDict = false;
}
#ifdef _NO_EXCEPTIONS
ErrorCode = S_OK;
#endif
}
-void CLZOutWindow::ReleaseStream()
+void CLZOutWindow::FlushWithCheck()
{
- if(_stream != 0)
+ HRESULT result = FlushPart();
+ if (_pos == _bufferSize)
{
- // Flush(); // Test it
- _stream->Release();
- _stream = 0;
+ _pos = 0;
+ _overDict = true;
}
-}
-
-void CLZOutWindow::FlushWithCheck()
-{
- HRESULT result = Flush();
#ifdef _NO_EXCEPTIONS
ErrorCode = result;
#else
@@ -69,27 +36,4 @@ void CLZOutWindow::FlushWithCheck()
#endif
}
-HRESULT CLZOutWindow::Flush()
-{
- UInt32 size = _pos - _streamPos;
- if(size == 0)
- return S_OK;
- #ifdef _NO_EXCEPTIONS
- if (ErrorCode != S_OK)
- return ErrorCode;
- #endif
- if(_stream != 0)
- {
- UInt32 processedSize;
- HRESULT result = _stream->Write(_buffer + _streamPos, size, &processedSize);
- if (result != S_OK)
- return result;
- if (size != processedSize)
- return E_FAIL;
- }
- if (_pos >= _windowSize)
- _pos = 0;
- _streamPos = _pos;
- return S_OK;
-}
diff --git a/7zip/Compress/LZ/LZOutWindow.h b/7zip/Compress/LZ/LZOutWindow.h
index 16bbc9e2..f2a182c0 100755
--- a/7zip/Compress/LZ/LZOutWindow.h
+++ b/7zip/Compress/LZ/LZOutWindow.h
@@ -4,6 +4,7 @@
#define __LZ_OUT_WINDOW_H
#include "../../IStream.h"
+#include "../../Common/OutBuffer.h"
#ifndef _NO_EXCEPTIONS
class CLZOutWindowException
@@ -14,57 +15,47 @@ public:
};
#endif
-class CLZOutWindow
+class CLZOutWindow: public COutBuffer
{
- Byte *_buffer;
- UInt32 _pos;
- UInt32 _windowSize;
- UInt32 _streamPos;
- ISequentialOutStream *_stream;
+ bool _overDict;
void FlushWithCheck();
public:
- #ifdef _NO_EXCEPTIONS
- HRESULT ErrorCode;
- #endif
-
- void Free();
- CLZOutWindow(): _buffer(0), _stream(0) {}
- ~CLZOutWindow() { Free(); ReleaseStream(); }
- bool Create(UInt32 windowSize);
-
- void SetStream(ISequentialOutStream *stream);
void Init(bool solid = false);
- HRESULT Flush();
- void ReleaseStream();
- void CopyBlock(UInt32 distance, UInt32 len)
+ // distance >= 0, len > 0,
+ bool CopyBlock(UInt32 distance, UInt32 len)
{
UInt32 pos = _pos - distance - 1;
- if (pos >= _windowSize)
- pos += _windowSize;
- for(; len > 0; len--)
+ if (pos >= _bufferSize)
+ {
+ if (!_overDict)
+ return false;
+ pos += _bufferSize;
+ }
+ do
{
- if (pos >= _windowSize)
+ if (pos == _bufferSize)
pos = 0;
_buffer[_pos++] = _buffer[pos++];
- if (_pos >= _windowSize)
+ if (_pos == _limitPos)
FlushWithCheck();
- // PutOneByte(GetOneByte(distance));
}
+ while(--len != 0);
+ return true;
}
void PutByte(Byte b)
{
_buffer[_pos++] = b;
- if (_pos >= _windowSize)
+ if (_pos == _limitPos)
FlushWithCheck();
}
Byte GetByte(UInt32 distance) const
{
UInt32 pos = _pos - distance - 1;
- if (pos >= _windowSize)
- pos += _windowSize;
+ if (pos >= _bufferSize)
+ pos += _bufferSize;
return _buffer[pos];
}
};
diff --git a/7zip/Compress/LZMA/LZMA.dsp b/7zip/Compress/LZMA/LZMA.dsp
index 0e9edda3..3fd32e1d 100755
--- a/7zip/Compress/LZMA/LZMA.dsp
+++ b/7zip/Compress/LZMA/LZMA.dsp
@@ -132,6 +132,14 @@ SOURCE=..\..\Common\OutBuffer.cpp
SOURCE=..\..\Common\OutBuffer.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 "RangeCoder"
diff --git a/7zip/Compress/LZMA/LZMADecoder.cpp b/7zip/Compress/LZMA/LZMADecoder.cpp
index 0863186b..57ab5a8d 100755
--- a/7zip/Compress/LZMA/LZMADecoder.cpp
+++ b/7zip/Compress/LZMA/LZMADecoder.cpp
@@ -8,6 +8,9 @@
namespace NCompress {
namespace NLZMA {
+const int kLenIdFinished = -1;
+const int kLenIdNeedInit = -2;
+
void CDecoder::Init()
{
{
@@ -41,11 +44,18 @@ void CDecoder::Init()
_reps[0] = _reps[1] = _reps[2] = _reps[3] = 0;
}
-HRESULT CDecoder::CodeSpec(Byte *buffer, UInt32 curSize)
+HRESULT CDecoder::CodeSpec(UInt32 curSize)
{
- if (_remainLen == -1)
+ if (_outSizeDefined)
+ {
+ const UInt64 rem = _outSize - _outWindowStream.GetProcessedSize();
+ if (curSize > rem)
+ curSize = (UInt32)rem;
+ }
+
+ if (_remainLen == kLenIdFinished)
return S_OK;
- if (_remainLen == -2)
+ if (_remainLen == kLenIdNeedInit)
{
_rangeDecoder.Init();
Init();
@@ -54,8 +64,6 @@ HRESULT CDecoder::CodeSpec(Byte *buffer, UInt32 curSize)
if (curSize == 0)
return S_OK;
- UInt64 nowPos64 = _nowPos64;
-
UInt32 rep0 = _reps[0];
UInt32 rep1 = _reps[1];
UInt32 rep2 = _reps[2];
@@ -67,12 +75,10 @@ HRESULT CDecoder::CodeSpec(Byte *buffer, UInt32 curSize)
{
previousByte = _outWindowStream.GetByte(rep0);
_outWindowStream.PutByte(previousByte);
- if (buffer)
- *buffer++ = previousByte;
- nowPos64++;
_remainLen--;
curSize--;
}
+ UInt64 nowPos64 = _outWindowStream.GetProcessedSize();
if (nowPos64 == 0)
previousByte = 0;
else
@@ -97,8 +103,6 @@ HRESULT CDecoder::CodeSpec(Byte *buffer, UInt32 curSize)
previousByte = _literalDecoder.DecodeNormal(&_rangeDecoder,
(UInt32)nowPos64, previousByte);
_outWindowStream.PutByte(previousByte);
- if (buffer)
- *buffer++ = previousByte;
state.UpdateChar();
curSize--;
nowPos64++;
@@ -108,20 +112,14 @@ HRESULT CDecoder::CodeSpec(Byte *buffer, UInt32 curSize)
UInt32 len;
if(_isRep[state.Index].Decode(&_rangeDecoder) == 1)
{
+ bool readLen = true;
if(_isRepG0[state.Index].Decode(&_rangeDecoder) == 0)
{
if(_isRep0Long[state.Index][posState].Decode(&_rangeDecoder) == 0)
{
- if (nowPos64 == 0)
- return S_FALSE;
state.UpdateShortRep();
- previousByte = _outWindowStream.GetByte(rep0);
- _outWindowStream.PutByte(previousByte);
- if (buffer)
- *buffer++ = previousByte;
- curSize--;
- nowPos64++;
- continue;
+ readLen = false;
+ len = 1;
}
}
else
@@ -143,8 +141,11 @@ HRESULT CDecoder::CodeSpec(Byte *buffer, UInt32 curSize)
rep1 = rep0;
rep0 = distance;
}
- len = _repMatchLenDecoder.Decode(&_rangeDecoder, posState) + kMatchMinLen;
- state.UpdateRep();
+ if (readLen)
+ {
+ len = _repMatchLenDecoder.Decode(&_rangeDecoder, posState) + kMatchMinLen;
+ state.UpdateRep();
+ }
}
else
{
@@ -167,36 +168,22 @@ HRESULT CDecoder::CodeSpec(Byte *buffer, UInt32 curSize)
rep0 += (_rangeDecoder.DecodeDirectBits(
numDirectBits - kNumAlignBits) << kNumAlignBits);
rep0 += _posAlignDecoder.ReverseDecode(&_rangeDecoder);
+ if (rep0 == 0xFFFFFFFF)
+ {
+ _remainLen = kLenIdFinished;
+ return S_OK;
+ }
}
}
else
rep0 = posSlot;
- if (rep0 >= nowPos64 || rep0 >= _dictionarySizeCheck)
- {
- if (rep0 != (UInt32)(Int32)(-1))
- return S_FALSE;
- _nowPos64 = nowPos64;
- _remainLen = -1;
- return S_OK;
- }
}
UInt32 locLen = len;
if (len > curSize)
locLen = (UInt32)curSize;
- if (buffer)
- {
- for (UInt32 i = locLen; i != 0; i--)
- {
- previousByte = _outWindowStream.GetByte(rep0);
- *buffer++ = previousByte;
- _outWindowStream.PutByte(previousByte);
- }
- }
- else
- {
- _outWindowStream.CopyBlock(rep0, locLen);
- previousByte = _outWindowStream.GetByte(0);
- }
+ if (!_outWindowStream.CopyBlock(rep0, locLen))
+ return S_FALSE;
+ previousByte = _outWindowStream.GetByte(0);
curSize -= locLen;
nowPos64 += locLen;
len -= locLen;
@@ -215,7 +202,6 @@ HRESULT CDecoder::CodeSpec(Byte *buffer, UInt32 curSize)
}
if (_rangeDecoder.Stream.WasFinished())
return S_FALSE;
- _nowPos64 = nowPos64;
_reps[0] = rep0;
_reps[1] = rep1;
_reps[2] = rep2;
@@ -238,40 +224,47 @@ STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream,
while (true)
{
UInt32 curSize = 1 << 18;
- if (_outSize != (UInt64)(Int64)(-1))
- if (curSize > _outSize - _nowPos64)
- curSize = (UInt32)(_outSize - _nowPos64);
- RINOK(CodeSpec(0, curSize));
- if (_remainLen == -1)
+ RINOK(CodeSpec(curSize));
+ if (_remainLen == kLenIdFinished)
break;
if (progress != NULL)
{
UInt64 inSize = _rangeDecoder.GetProcessedSize();
- RINOK(progress->SetRatioInfo(&inSize, &_nowPos64));
+ UInt64 nowPos64 = _outWindowStream.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&inSize, &nowPos64));
}
- if (_outSize != (UInt64)(Int64)(-1))
- if (_nowPos64 >= _outSize)
+ if (_outSizeDefined)
+ if (_outWindowStream.GetProcessedSize() >= _outSize)
break;
}
flusher.NeedFlush = false;
return Flush();
}
+
+#ifdef _NO_EXCEPTIONS
+
+#define LZMA_TRY_BEGIN
+#define LZMA_TRY_END
+
+#else
+
+#define LZMA_TRY_BEGIN try {
+#define LZMA_TRY_END } \
+ catch(const CInBufferException &e) { return e.ErrorCode; } \
+ catch(const CLZOutWindowException &e) { return e.ErrorCode; } \
+ catch(...) { return S_FALSE; }
+
+#endif
+
+
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress)
{
- #ifndef _NO_EXCEPTIONS
- try
- {
- #endif
- return CodeReal(inStream, outStream, inSize, outSize, progress);
- #ifndef _NO_EXCEPTIONS
- }
- catch(const CInBufferException &e) { return e.ErrorCode; }
- catch(const CLZOutWindowException &e) { return e.ErrorCode; }
- catch(...) { return S_FALSE; }
- #endif
+ LZMA_TRY_BEGIN
+ return CodeReal(inStream, outStream, inSize, outSize, progress);
+ LZMA_TRY_END
}
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *properties, UInt32 size)
@@ -288,9 +281,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *properties, UInt32 size
UInt32 dictionarySize = 0;
for (int i = 0; i < 4; i++)
dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8);
- _dictionarySizeCheck = MyMax(dictionarySize, UInt32(1));
- UInt32 blockSize = MyMax(_dictionarySizeCheck, UInt32(1 << 12));
- if (!_outWindowStream.Create(blockSize))
+ if (!_outWindowStream.Create(dictionarySize))
return E_OUTOFMEMORY;
if (!_literalDecoder.Create(lp, lc))
return E_OUTOFMEMORY;
@@ -319,38 +310,29 @@ STDMETHODIMP CDecoder::ReleaseInStream()
STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
{
- _outSize = (outSize == NULL) ? (UInt64)(Int64)(-1) : *outSize;
- _nowPos64 = 0;
- _remainLen = -2; // -2 means need_init
+ if (_outSizeDefined = (outSize != NULL))
+ _outSize = *outSize;
+ _remainLen = kLenIdNeedInit;
_outWindowStream.Init();
return S_OK;
}
+#ifdef _ST_MODE
+
STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- #ifndef _NO_EXCEPTIONS
- try
- {
- #endif
- UInt64 startPos = _nowPos64;
- if (_outSize != (UInt64)(Int64)(-1))
- if (size > _outSize - _nowPos64)
- size = (UInt32)(_outSize - _nowPos64);
- HRESULT res = CodeSpec((Byte *)data, size);
+ LZMA_TRY_BEGIN
if (processedSize)
- *processedSize = (UInt32)(_nowPos64 - startPos);
- return res;
- #ifndef _NO_EXCEPTIONS
- }
- catch(const CInBufferException &e) { return e.ErrorCode; }
- catch(const CLZOutWindowException &e) { return e.ErrorCode; }
- catch(...) { return S_FALSE; }
- #endif
+ *processedSize = 0;
+ const UInt64 startPos = _outWindowStream.GetProcessedSize();
+ _outWindowStream.SetMemStream((Byte *)data);
+ RINOK(CodeSpec(size));
+ if (processedSize)
+ *processedSize = (UInt32)(_outWindowStream.GetProcessedSize() - startPos);
+ return Flush();
+ LZMA_TRY_END
}
-STDMETHODIMP CDecoder::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
-{
- return Read(data, size, processedSize);
-}
+#endif
}}
diff --git a/7zip/Compress/LZMA/LZMADecoder.h b/7zip/Compress/LZMA/LZMADecoder.h
index 5cfd72ad..16e49269 100755
--- a/7zip/Compress/LZMA/LZMADecoder.h
+++ b/7zip/Compress/LZMA/LZMADecoder.h
@@ -145,9 +145,11 @@ public:
class CDecoder:
public ICompressCoder,
public ICompressSetDecoderProperties2,
+ #ifdef _ST_MODE
public ICompressSetInStream,
public ICompressSetOutStreamSize,
public ISequentialInStream,
+ #endif
public CMyUnknownImp
{
CLZOutWindow _outWindowStream;
@@ -170,26 +172,30 @@ class CDecoder:
CLiteralDecoder _literalDecoder;
- UInt32 _dictionarySizeCheck;
-
UInt32 _posStateMask;
///////////////////
// State
- UInt64 _outSize;
- UInt64 _nowPos64;
UInt32 _reps[4];
CState _state;
Int32 _remainLen; // -1 means end of stream. // -2 means need Init
+ UInt64 _outSize;
+ bool _outSizeDefined;
void Init();
- HRESULT CodeSpec(Byte *buffer, UInt32 size);
+ HRESULT CodeSpec(UInt32 size);
public:
+
+ #ifdef _ST_MODE
MY_UNKNOWN_IMP4(
ICompressSetDecoderProperties2,
ICompressSetInStream,
ICompressSetOutStreamSize,
ISequentialInStream)
+ #else
+ MY_UNKNOWN_IMP1(
+ ICompressSetDecoderProperties2)
+ #endif
void ReleaseStreams()
{
@@ -228,9 +234,12 @@ public:
STDMETHOD(SetInStream)(ISequentialInStream *inStream);
STDMETHOD(ReleaseInStream)();
STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
+
+ #ifdef _ST_MODE
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
+ #endif
+ CDecoder(): _outSizeDefined(false) {}
virtual ~CDecoder() {}
};
diff --git a/7zip/Compress/LZMA/LZMAEncoder.cpp b/7zip/Compress/LZMA/LZMAEncoder.cpp
index 2e8cba15..447130e0 100755
--- a/7zip/Compress/LZMA/LZMAEncoder.cpp
+++ b/7zip/Compress/LZMA/LZMAEncoder.cpp
@@ -3,6 +3,7 @@
#include "StdAfx.h"
#include "../../../Common/Defs.h"
+#include "../../Common/StreamUtils.h"
#include "LZMAEncoder.h"
@@ -498,7 +499,7 @@ STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
properties[0] = (_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits;
for (int i = 0; i < 4; i++)
properties[1 + i] = Byte(_dictionarySize >> (8 * i));
- return outStream->Write(properties, kPropSize, NULL);
+ return WriteStream(outStream, properties, kPropSize, NULL);
}
STDMETHODIMP CEncoder::SetOutStream(ISequentialOutStream *outStream)
diff --git a/7zip/Compress/LZMA/makefile b/7zip/Compress/LZMA/makefile
index 3ec9151d..14672b6a 100755
--- a/7zip/Compress/LZMA/makefile
+++ b/7zip/Compress/LZMA/makefile
@@ -20,6 +20,7 @@ WIN_OBJS = \
7ZIP_COMMON_OBJS = \
$O\InBuffer.obj \
$O\OutBuffer.obj \
+ $O\StreamUtils.obj \
LZ_OBJS = \
$O\LZInWindow.obj \
diff --git a/7zip/Compress/LZMA_Alone/AloneLZMA.dsp b/7zip/Compress/LZMA_Alone/AloneLZMA.dsp
index 3f0efbdc..f9f3eb69 100755
--- a/7zip/Compress/LZMA_Alone/AloneLZMA.dsp
+++ b/7zip/Compress/LZMA_Alone/AloneLZMA.dsp
@@ -477,6 +477,14 @@ SOURCE=..\..\Common\OutBuffer.cpp
SOURCE=..\..\Common\OutBuffer.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 Source File
diff --git a/7zip/Compress/LZMA_Alone/LzmaAlone.cpp b/7zip/Compress/LZMA_Alone/LzmaAlone.cpp
index d3965656..76b6d886 100755
--- a/7zip/Compress/LZMA_Alone/LzmaAlone.cpp
+++ b/7zip/Compress/LZMA_Alone/LzmaAlone.cpp
@@ -20,6 +20,7 @@
#include "../../../Common/StringToInt.h"
#include "../../Common/FileStreams.h"
+#include "../../Common/StreamUtils.h"
#include "../LZMA/LZMADecoder.h"
#include "../LZMA/LZMAEncoder.h"
@@ -35,6 +36,8 @@ extern "C"
using namespace NCommandLineParser;
static const char *kCantAllocate = "Can not allocate memory";
+static const char *kReadError = "Read error";
+static const char *kWriteError = "Write error";
namespace NKey {
enum Enum
@@ -131,7 +134,7 @@ static bool GetNumber(const wchar_t *s, UInt32 &value)
int main2(int n, const char *args[])
{
- fprintf(stderr, "\nLZMA 4.26 Copyright (c) 1999-2005 Igor Pavlov 2005-08-02\n");
+ fprintf(stderr, "\nLZMA 4.27 Copyright (c) 1999-2005 Igor Pavlov 2005-08-07\n");
if (n == 1)
{
@@ -269,7 +272,7 @@ int main2(int n, const char *args[])
}
UInt32 processedSize;
- if (inStream->Read(inBuffer, (UInt32)inSize, &processedSize) != S_OK)
+ if (ReadStream(inStream, inBuffer, (UInt32)inSize, &processedSize) != S_OK)
throw "Can not read";
if ((UInt32)inSize != processedSize)
throw "Read size error";
@@ -311,8 +314,8 @@ int main2(int n, const char *args[])
if (res != 0)
throw "LzmaDecoder error";
}
- if (outStream->Write(outBuffer, (UInt32)outSizeProcessed, &processedSize) != S_OK)
- throw "Can not write";
+ if (WriteStream(outStream, outBuffer, (UInt32)outSizeProcessed, &processedSize) != S_OK)
+ throw kWriteError;
MyFree(outBuffer);
MyFree(inBuffer);
return 0;
@@ -408,9 +411,9 @@ int main2(int n, const char *args[])
for (int i = 0; i < 8; i++)
{
Byte b = Byte(fileSize >> (8 * i));
- if (outStream->Write(&b, sizeof(b), 0) != S_OK)
+ if (outStream->Write(&b, 1, 0) != S_OK)
{
- fprintf(stderr, "Write error");
+ fprintf(stderr, kWriteError);
return 1;
}
}
@@ -434,14 +437,14 @@ int main2(int n, const char *args[])
const UInt32 kPropertiesSize = 5;
Byte properties[kPropertiesSize];
UInt32 processedSize;
- if (inStream->Read(properties, kPropertiesSize, &processedSize) != S_OK)
+ if (ReadStream(inStream, properties, kPropertiesSize, &processedSize) != S_OK)
{
- fprintf(stderr, "Read error");
+ fprintf(stderr, kReadError);
return 1;
}
if (processedSize != kPropertiesSize)
{
- fprintf(stderr, "Read error");
+ fprintf(stderr, kReadError);
return 1;
}
if (decoderSpec->SetDecoderProperties2(properties, kPropertiesSize) != S_OK)
@@ -453,14 +456,14 @@ int main2(int n, const char *args[])
for (int i = 0; i < 8; i++)
{
Byte b;
- if (inStream->Read(&b, sizeof(b), &processedSize) != S_OK)
+ if (inStream->Read(&b, 1, &processedSize) != S_OK)
{
- fprintf(stderr, "Read error");
+ fprintf(stderr, kReadError);
return 1;
}
if (processedSize != 1)
{
- fprintf(stderr, "Read error");
+ fprintf(stderr, kReadError);
return 1;
}
fileSize |= ((UInt64)b) << (8 * i);
diff --git a/7zip/Compress/LZMA_Alone/LzmaBench.cpp b/7zip/Compress/LZMA_Alone/LzmaBench.cpp
index c491f97b..21e27849 100755
--- a/7zip/Compress/LZMA_Alone/LzmaBench.cpp
+++ b/7zip/Compress/LZMA_Alone/LzmaBench.cpp
@@ -148,7 +148,6 @@ public:
Pos = 0;
}
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
};
STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
@@ -157,20 +156,13 @@ STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processed
if (size > remain)
size = remain;
for (UInt32 i = 0; i < size; i++)
- {
((Byte *)data)[i] = Data[Pos + i];
- }
Pos += size;
if(processedSize != NULL)
*processedSize = size;
return S_OK;
}
-STDMETHODIMP CBenchmarkInStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
-{
- return Read(data, size, processedSize);
-}
-
class CBenchmarkOutStream:
public ISequentialOutStream,
public CMyUnknownImp
@@ -193,7 +185,6 @@ public:
}
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
};
STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
@@ -211,11 +202,6 @@ STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *p
return S_OK;
}
-STDMETHODIMP CBenchmarkOutStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize)
-{
- return Write(data, size, processedSize);
-}
-
class CCrcOutStream:
public ISequentialOutStream,
public CMyUnknownImp
@@ -225,7 +211,6 @@ public:
MY_UNKNOWN_IMP
void Init() { CRC.Init(); }
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
};
STDMETHODIMP CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
@@ -236,11 +221,6 @@ STDMETHODIMP CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *process
return S_OK;
}
-STDMETHODIMP CCrcOutStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize)
-{
- return Write(data, size, processedSize);
-}
-
static UInt64 GetTimeCount()
{
#ifdef _WIN32
diff --git a/7zip/Compress/LZMA_Alone/LzmaRam.cpp b/7zip/Compress/LZMA_Alone/LzmaRam.cpp
index 387162b2..090d73d8 100755
--- a/7zip/Compress/LZMA_Alone/LzmaRam.cpp
+++ b/7zip/Compress/LZMA_Alone/LzmaRam.cpp
@@ -27,7 +27,6 @@ public:
Pos = 0;
}
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
};
STDMETHODIMP CInStreamRam::Read(void *data, UInt32 size, UInt32 *processedSize)
@@ -36,20 +35,13 @@ STDMETHODIMP CInStreamRam::Read(void *data, UInt32 size, UInt32 *processedSize)
if (size > remain)
size = remain;
for (UInt32 i = 0; i < size; i++)
- {
((Byte *)data)[i] = Data[Pos + i];
- }
Pos += size;
if(processedSize != NULL)
*processedSize = size;
return S_OK;
}
-STDMETHODIMP CInStreamRam::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
-{
- return Read(data, size, processedSize);
-}
-
class COutStreamRam:
public ISequentialOutStream,
public CMyUnknownImp
@@ -83,7 +75,6 @@ public:
return S_OK;
}
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
};
STDMETHODIMP COutStreamRam::Write(const void *data, UInt32 size, UInt32 *processedSize)
@@ -101,11 +92,6 @@ STDMETHODIMP COutStreamRam::Write(const void *data, UInt32 size, UInt32 *process
return S_OK;
}
-STDMETHODIMP COutStreamRam::WritePart(const void *data, UInt32 size, UInt32 *processedSize)
-{
- return Write(data, size, processedSize);
-}
-
#define SZE_FAIL (1)
#define SZE_OUTOFMEMORY (2)
#define SZE_OUT_OVERFLOW (3)
diff --git a/7zip/Compress/LZMA_Alone/makefile b/7zip/Compress/LZMA_Alone/makefile
index b6f6541a..63a63ae4 100755
--- a/7zip/Compress/LZMA_Alone/makefile
+++ b/7zip/Compress/LZMA_Alone/makefile
@@ -41,12 +41,10 @@ COMMON_OBJS = \
$O\StringToInt.obj \
$O\Vector.obj
-WIN_OBJS = \
- $O\Synchronization.obj
-
7ZIP_COMMON_OBJS = \
$O\InBuffer.obj \
$O\OutBuffer.obj \
+ $O\StreamUtils.obj \
LZ_OBJS = \
$O\LZInWindow.obj \
@@ -57,7 +55,6 @@ OBJS = \
$(LZMA_OBJS) \
$(LZMA_OPT_OBJS) \
$(COMMON_OBJS) \
- $(WIN_OBJS) \
$(7ZIP_COMMON_OBJS) \
$(LZ_OBJS) \
$O\LzmaRamDecode.obj \
@@ -85,8 +82,6 @@ $(LZMA_OPT_OBJS): ../LZMA/$(*B).cpp
$(COMPL_O2)
$(COMMON_OBJS): ../../../Common/$(*B).cpp
$(COMPL)
-$(WIN_OBJS): ../../../Windows/$(*B).cpp
- $(COMPL)
$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
$(COMPL)
$(LZ_OBJS): ../LZ/$(*B).cpp
diff --git a/7zip/Compress/LZMA_C/LzmaDecodeSize.c b/7zip/Compress/LZMA_C/LzmaDecodeSize.c
index 59bfba6e..3dbdb2fd 100755
--- a/7zip/Compress/LZMA_C/LzmaDecodeSize.c
+++ b/7zip/Compress/LZMA_C/LzmaDecodeSize.c
@@ -2,7 +2,7 @@
LzmaDecodeSize.c
LZMA Decoder (optimized for Size version)
- LZMA SDK 4.22 Copyright (c) 1999-2005 Igor Pavlov (2005-06-10)
+ LZMA SDK 4.27 Copyright (c) 1999-2005 Igor Pavlov (2005-08-07)
http://www.7-zip.org/
LZMA SDK is licensed under two licenses:
@@ -66,17 +66,14 @@ Byte RangeDecoderReadByte(CRangeDecoder *rd)
/* #define ReadByte (*rd->Buffer++) */
#define ReadByte (RangeDecoderReadByte(rd))
-void RangeDecoderInit(CRangeDecoder *rd,
- #ifdef _LZMA_IN_CB
- ILzmaInCallback *inCallback
- #else
- const Byte *stream, SizeT bufferSize
+void RangeDecoderInit(CRangeDecoder *rd
+ #ifndef _LZMA_IN_CB
+ , const Byte *stream, SizeT bufferSize
#endif
)
{
int i;
#ifdef _LZMA_IN_CB
- rd->InCallback = inCallback;
rd->Buffer = rd->BufferLim = 0;
#else
rd->Buffer = stream;
@@ -398,6 +395,7 @@ int LzmaDecode(CLzmaDecoderState *vs,
rd.Range = vs->Range;
rd.Code = vs->Code;
#ifdef _LZMA_IN_CB
+ rd.InCallback = InCallback;
rd.Buffer = vs->Buffer;
rd.BufferLim = vs->BufferLim;
#else
@@ -432,11 +430,9 @@ int LzmaDecode(CLzmaDecoderState *vs,
distanceLimit = 0;
dictionaryPos = 0;
dictionary[dictionarySize - 1] = 0;
- RangeDecoderInit(&rd,
- #ifdef _LZMA_IN_CB
- InCallback
- #else
- inStream, inSize
+ RangeDecoderInit(&rd
+ #ifndef _LZMA_IN_CB
+ , inStream, inSize
#endif
);
#ifdef _LZMA_IN_CB
@@ -486,11 +482,12 @@ int LzmaDecode(CLzmaDecoderState *vs,
p[i] = kBitModelTotal >> 1;
}
- RangeDecoderInit(&rd,
- #ifdef _LZMA_IN_CB
- InCallback
- #else
- inStream, inSize
+ #ifdef _LZMA_IN_CB
+ rd.InCallback = InCallback;
+ #endif
+ RangeDecoderInit(&rd
+ #ifndef _LZMA_IN_CB
+ , inStream, inSize
#endif
);
diff --git a/7zip/Compress/LZMA_C/LzmaTest.c b/7zip/Compress/LZMA_C/LzmaTest.c
index b4ca5422..f95a753b 100755
--- a/7zip/Compress/LZMA_C/LzmaTest.c
+++ b/7zip/Compress/LZMA_C/LzmaTest.c
@@ -3,7 +3,7 @@ LzmaTest.c
Test application for LZMA Decoder
This file written and distributed to public domain by Igor Pavlov.
-This file is part of LZMA SDK 4.26 (2005-08-02)
+This file is part of LZMA SDK 4.26 (2005-08-05)
*/
#include <stdio.h>
@@ -173,12 +173,12 @@ int main3(FILE *inFile, FILE *outFile, char *rs)
if (state.Probs == 0
#ifdef _LZMA_OUT_READ
- || state.Dictionary == 0 && state.Properties.DictionarySize != 0
+ || (state.Dictionary == 0 && state.Properties.DictionarySize != 0)
#else
- || outStream == 0 && outSizeFull != 0
+ || (outStream == 0 && outSizeFull != 0)
#endif
#ifndef _LZMA_IN_CB
- || inStream == 0 && compressedSize != 0
+ || (inStream == 0 && compressedSize != 0)
#endif
)
{
@@ -307,7 +307,7 @@ int main2(int numArgs, const char *args[], char *rs)
FILE *outFile = 0;
int res;
- sprintf(rs + strlen(rs), "\nLZMA Decoder 4.26 Copyright (c) 1999-2005 Igor Pavlov 2005-08-02\n");
+ sprintf(rs + strlen(rs), "\nLZMA Decoder 4.26 Copyright (c) 1999-2005 Igor Pavlov 2005-08-05\n");
if (numArgs < 2 || numArgs > 3)
{
sprintf(rs + strlen(rs), "\nUsage: lzmadec file.lzma [outFile]\n");
diff --git a/7zip/Compress/Lzx/Lzx.h b/7zip/Compress/Lzx/Lzx.h
new file mode 100755
index 00000000..386a17c3
--- /dev/null
+++ b/7zip/Compress/Lzx/Lzx.h
@@ -0,0 +1,61 @@
+// Lzx.h
+
+#ifndef __COMPRESS_LZX_H
+#define __COMPRESS_LZX_H
+
+namespace NCompress {
+namespace NLzx {
+
+const int kNumHuffmanBits = 16;
+const UInt32 kNumRepDistances = 3;
+
+const UInt32 kNumLenSlots = 8;
+const UInt32 kMatchMinLen = 2;
+const UInt32 kNumLenSymbols = 249;
+const UInt32 kMatchMaxLen = kMatchMinLen + (kNumLenSlots - 1) + kNumLenSymbols - 1;
+
+const int kNumAlignBits = 3;
+const UInt32 kAlignTableSize = 1 << kNumAlignBits;
+
+const UInt32 kNumPosSlots = 50;
+const UInt32 kNumPosLenSlots = kNumPosSlots * kNumLenSlots;
+
+const UInt32 kMainTableSize = 256 + kNumPosLenSlots;
+const UInt32 kLevelTableSize = 20;
+const UInt32 kMaxTableSize = kMainTableSize;
+
+const int kNumBlockTypeBits = 3;
+const int kBlockTypeVerbatim = 1;
+const int kBlockTypeAligned = 2;
+const int kBlockTypeUncompressed = 3;
+
+const int kUncompressedBlockSizeNumBits = 24;
+
+const int kNumBitsForPreTreeLevel = 4;
+
+const int kLevelSymbolZeros = 17;
+const int kLevelSymbolZerosBig = 18;
+const int kLevelSymbolSame = 19;
+
+const int kLevelSymbolZerosStartValue = 4;
+const int kLevelSymbolZerosNumBits = 4;
+
+const int kLevelSymbolZerosBigStartValue = kLevelSymbolZerosStartValue +
+ (1 << kLevelSymbolZerosNumBits);
+const int kLevelSymbolZerosBigNumBits = 5;
+
+const int kLevelSymbolSameNumBits = 1;
+const int kLevelSymbolSameStartValue = 4;
+
+const int kNumBitsForAlignLevel = 3;
+
+const int kNumDictionaryBitsMin = 15;
+const int kNumDictionaryBitsMax = 21;
+const UInt32 kDictionarySizeMax = (1 << kNumDictionaryBitsMax);
+
+const int kNumLinearPosSlotBits = 17;
+const UInt32 kNumPowerPosSlots = 0x26;
+
+}}
+
+#endif
diff --git a/7zip/Archive/Cab/LZXi86Converter.cpp b/7zip/Compress/Lzx/Lzx86Converter.cpp
index ec70a211..1265dba0 100755
--- a/7zip/Archive/Cab/LZXi86Converter.cpp
+++ b/7zip/Compress/Lzx/Lzx86Converter.cpp
@@ -1,62 +1,54 @@
-// Archive/Cab/LZXi86Converter.cpp
+// Lzx86Converter.cpp
#include "StdAfx.h"
#include "Common/Defs.h"
-#include "LZXi86Converter.h"
+#include "Lzx86Converter.h"
-namespace NArchive {
-namespace NCab {
-namespace NLZX {
+namespace NCompress {
+namespace NLzx {
static const int kResidue = 6 + 4;
-void Ci86TranslationOutStream::MakeTranslation()
+void Cx86ConvertOutStream::MakeTranslation()
{
if (m_Pos <= kResidue)
return;
UInt32 numBytes = m_Pos - kResidue;
+ Byte *buffer = m_Buffer;
for (UInt32 i = 0; i < numBytes;)
{
- if (m_Buffer[i] == 0xE8)
+ if (buffer[i++] == 0xE8)
{
- i++;
Int32 absValue = 0;
int j;
for(j = 0; j < 4; j++)
- absValue += UInt32(m_Buffer[i + j]) << (j * 8);
-
- Int32 pos = m_ProcessedSize + i - 1;
- UInt32 offset;
- if (absValue < -pos || absValue >= Int32(m_TranslationSize))
- {
- }
- else
+ absValue += (UInt32)buffer[i + j] << (j * 8);
+ Int32 pos = (Int32)(m_ProcessedSize + i - 1);
+ if (absValue >= -pos && absValue < (Int32)m_TranslationSize)
{
- offset = (absValue >= 0) ?
+ UInt32 offset = (absValue >= 0) ?
absValue - pos :
absValue + m_TranslationSize;
for(j = 0; j < 4; j++)
{
- m_Buffer[i + j] = Byte(offset & 0xFF);
+ buffer[i + j] = (Byte)(offset & 0xFF);
offset >>= 8;
}
}
i += 4;
}
- else
- i++;
}
}
-STDMETHODIMP Ci86TranslationOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+STDMETHODIMP Cx86ConvertOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
+ if (processedSize != NULL)
+ *processedSize = 0;
if (!m_TranslationMode)
return m_Stream->Write(data, size, processedSize);
-
UInt32 realProcessedSize = 0;
-
while (realProcessedSize < size)
{
UInt32 writeSize = MyMin(size - realProcessedSize, kUncompressedBlockSize - m_Pos);
@@ -73,21 +65,26 @@ STDMETHODIMP Ci86TranslationOutStream::Write(const void *data, UInt32 size, UInt
return S_OK;
}
-STDMETHODIMP Ci86TranslationOutStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize)
-{
- return Write(data, size, processedSize);
-}
-
-HRESULT Ci86TranslationOutStream::Flush()
+HRESULT Cx86ConvertOutStream::Flush()
{
if (m_Pos == 0)
return S_OK;
- MakeTranslation();
- RINOK(m_Stream->Write(m_Buffer, m_Pos, NULL));
+ if (m_TranslationMode)
+ MakeTranslation();
+ UInt32 pos = 0;
+ do
+ {
+ UInt32 processed;
+ RINOK(m_Stream->Write(m_Buffer + pos, m_Pos - pos, &processed));
+ if (processed == 0)
+ return E_FAIL;
+ pos += processed;
+ }
+ while(pos < m_Pos);
m_ProcessedSize += m_Pos;
m_Pos = 0;
- m_TranslationMode = (m_ProcessedSize < (1 << 30));
+ m_TranslationMode = (m_TranslationMode && (m_ProcessedSize < (1 << 30)));
return S_OK;
}
-}}}
+}}
diff --git a/7zip/Archive/Cab/LZXi86Converter.h b/7zip/Compress/Lzx/Lzx86Converter.h
index 625fa506..b507a612 100755
--- a/7zip/Archive/Cab/LZXi86Converter.h
+++ b/7zip/Compress/Lzx/Lzx86Converter.h
@@ -1,50 +1,45 @@
-// Archive/Cab/LZXi86Converter.h
+// Lzx/x86Converter.h
-#ifndef __ARCHIVE_CAB_LZXI86CONVERTER_H
-#define __ARCHIVE_CAB_LZXI86CONVERTER_H
+#ifndef __LZX_X86CONVERTER_H
+#define __LZX_X86CONVERTER_H
#include "Common/MyCom.h"
#include "../../IStream.h"
-namespace NArchive {
-namespace NCab {
-namespace NLZX {
+namespace NCompress {
+namespace NLzx {
const int kUncompressedBlockSize = 1 << 15;
-class Ci86TranslationOutStream:
+class Cx86ConvertOutStream:
public ISequentialOutStream,
public CMyUnknownImp
{
- bool m_TranslationMode;
CMyComPtr<ISequentialOutStream> m_Stream;
UInt32 m_ProcessedSize;
- Byte m_Buffer[kUncompressedBlockSize];
UInt32 m_Pos;
UInt32 m_TranslationSize;
+ bool m_TranslationMode;
+ Byte m_Buffer[kUncompressedBlockSize];
void MakeTranslation();
public:
- Ci86TranslationOutStream(): m_Pos(0) {}
- ~Ci86TranslationOutStream() { Flush(); }
-
- MY_UNKNOWN_IMP
-
- STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
-public:
- void Init(ISequentialOutStream *outStream, bool translationMode, UInt32 translationSize)
+ void SetStream(ISequentialOutStream *outStream) { m_Stream = outStream; }
+ void ReleaseStream() { m_Stream.Release(); }
+ void Init(bool translationMode, UInt32 translationSize)
{
- m_Stream = outStream;
m_TranslationMode = translationMode;
m_TranslationSize = translationSize;
m_ProcessedSize = 0;
m_Pos = 0;
}
- void ReleaseStream() { m_Stream.Release(); }
HRESULT Flush();
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
-}}}
+}}
#endif
diff --git a/7zip/Compress/Lzx/LzxDecoder.cpp b/7zip/Compress/Lzx/LzxDecoder.cpp
new file mode 100755
index 00000000..341e47c0
--- /dev/null
+++ b/7zip/Compress/Lzx/LzxDecoder.cpp
@@ -0,0 +1,382 @@
+// LzxDecoder.cpp
+
+#include "StdAfx.h"
+
+#include "LzxDecoder.h"
+
+#include "Common/Defs.h"
+#include "Common/Alloc.h"
+#include "Windows/Defs.h"
+
+namespace NCompress {
+namespace NLzx {
+
+const int kLenIdNeedInit = -2;
+
+CDecoder::CDecoder():
+ _keepHistory(false),
+ m_AlignPos(0)
+{
+ m_x86ConvertOutStreamSpec = new Cx86ConvertOutStream;
+ m_x86ConvertOutStream = m_x86ConvertOutStreamSpec;
+}
+
+void CDecoder::ReleaseStreams()
+{
+ m_OutWindowStream.ReleaseStream();
+ m_InBitStream.ReleaseStream();
+ m_x86ConvertOutStreamSpec->ReleaseStream();
+}
+
+STDMETHODIMP CDecoder::Flush()
+{
+ RINOK(m_OutWindowStream.Flush());
+ return m_x86ConvertOutStreamSpec->Flush();
+}
+
+UInt32 CDecoder::ReadBits(UInt32 numBits) { return m_InBitStream.ReadBits(numBits); }
+
+#define RIF(x) { if (!(x)) return false; }
+
+bool CDecoder::ReadTable(Byte *lastLevels, Byte *newLevels, UInt32 numSymbols)
+{
+ Byte levelLevels[kLevelTableSize];
+ UInt32 i;
+ for (i = 0; i < kLevelTableSize; i++)
+ levelLevels[i] = (Byte)ReadBits(kNumBitsForPreTreeLevel);
+ RIF(m_LevelDecoder.SetCodeLengths(levelLevels));
+ int num = 0;
+ Byte symbol = 0;
+ for (i = 0; i < numSymbols;)
+ {
+ if (num != 0)
+ {
+ lastLevels[i] = newLevels[i] = symbol;
+ i++;
+ num--;
+ continue;
+ }
+ UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
+ if (number == kLevelSymbolZeros)
+ {
+ num = kLevelSymbolZerosStartValue + ReadBits(kLevelSymbolZerosNumBits);
+ symbol = 0;
+ }
+ else if (number == kLevelSymbolZerosBig)
+ {
+ num = kLevelSymbolZerosBigStartValue + ReadBits(kLevelSymbolZerosBigNumBits);
+ symbol = 0;
+ }
+ else if (number == kLevelSymbolSame || number <= kNumHuffmanBits)
+ {
+ if (number <= kNumHuffmanBits)
+ num = 1;
+ else
+ {
+ num = kLevelSymbolSameStartValue + ReadBits(kLevelSymbolSameNumBits);
+ number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
+ if (number > kNumHuffmanBits)
+ return false;
+ }
+ symbol = Byte((17 + lastLevels[i] - number) % (kNumHuffmanBits + 1));
+ }
+ else
+ return false;
+ }
+ return true;
+}
+
+bool CDecoder::ReadTables(void)
+{
+ Byte newLevels[kMaxTableSize];
+ {
+ int blockType = (int)ReadBits(kNumBlockTypeBits);
+ if (blockType > kBlockTypeUncompressed)
+ return false;
+ m_UnCompressedBlockSize = m_InBitStream.ReadBitsBig(kUncompressedBlockSizeNumBits);
+
+ if (m_IsUncompressedBlock = (blockType == kBlockTypeUncompressed))
+ {
+ m_InBitStream.ReadBits(16 - m_InBitStream.GetBitPosition());
+ if (!m_InBitStream.ReadUInt32(m_RepDistances[0]))
+ return false;
+ m_RepDistances[0]--;
+ for (int i = 1; i < kNumRepDistances; i++)
+ {
+ UInt32 rep = 0;
+ for (int j = 0; j < 4; j++)
+ rep |= (UInt32)m_InBitStream.DirectReadByte() << (8 * j);
+ m_RepDistances[i] = rep - 1;
+ }
+ return true;
+ }
+ if (m_AlignIsUsed = (blockType == kBlockTypeAligned))
+ {
+ for(int i = 0; i < kAlignTableSize; i++)
+ newLevels[i] = ReadBits(kNumBitsForAlignLevel);
+ RIF(m_AlignDecoder.SetCodeLengths(newLevels));
+ }
+ }
+
+ RIF(ReadTable(m_LastMainLevels, newLevels, 256));
+ RIF(ReadTable(m_LastMainLevels + 256, newLevels + 256, m_NumPosLenSlots));
+ for (UInt32 i = 256 + m_NumPosLenSlots; i < kMainTableSize; i++)
+ newLevels[i] = 0;
+ RIF(m_MainDecoder.SetCodeLengths(newLevels));
+
+ RIF(ReadTable(m_LastLenLevels, newLevels, kNumLenSymbols));
+ return m_LenDecoder.SetCodeLengths(newLevels);
+}
+
+class CDecoderFlusher
+{
+ CDecoder *m_Decoder;
+public:
+ bool NeedFlush;
+ CDecoderFlusher(CDecoder *decoder): m_Decoder(decoder), NeedFlush(true) {}
+ ~CDecoderFlusher()
+ {
+ if (NeedFlush)
+ m_Decoder->Flush();
+ m_Decoder->ReleaseStreams();
+ }
+};
+
+
+void CDecoder::ClearPrevLevels()
+{
+ int i;
+ for (i = 0; i < kMainTableSize; i++)
+ m_LastMainLevels[i] = 0;
+ for (i = 0; i < kNumLenSymbols; i++)
+ m_LastLenLevels[i] = 0;
+};
+
+
+HRESULT CDecoder::CodeSpec(UInt32 curSize)
+{
+ if (_remainLen == kLenIdNeedInit)
+ {
+ _remainLen = 0;
+ if (_keepHistory && m_IsUncompressedBlock && m_UnCompressedBlockSize > 0)
+ m_InBitStream.InitDirect();
+ else
+ m_InBitStream.InitNormal();
+ if (!_keepHistory)
+ {
+ m_UnCompressedBlockSize = 0;
+ ClearPrevLevels();
+ UInt32 i86TranslationSize = 0;
+ bool translationMode = (ReadBits(1) != 0);
+ if (translationMode)
+ {
+ i86TranslationSize = ReadBits(16) << 16;
+ i86TranslationSize |= ReadBits(16);
+ }
+ m_x86ConvertOutStreamSpec->Init(translationMode, i86TranslationSize);
+
+ for(int i = 0 ; i < kNumRepDistances; i++)
+ m_RepDistances[i] = 0;
+ }
+ }
+
+ if (curSize == 0)
+ return S_OK;
+
+ while(_remainLen > 0 && curSize > 0)
+ {
+ m_OutWindowStream.PutByte(m_OutWindowStream.GetByte(m_RepDistances[0]));
+ _remainLen--;
+ curSize--;
+ }
+
+ while(curSize > 0)
+ {
+ if (m_UnCompressedBlockSize == 0)
+ if (!ReadTables())
+ return S_FALSE;
+ UInt32 nowPos = 0;
+ UInt32 next = (Int32)MyMin(m_UnCompressedBlockSize, curSize);
+ curSize -= next;
+ m_UnCompressedBlockSize -= next;
+ if (m_IsUncompressedBlock)
+ {
+ while(next > 0)
+ {
+ m_OutWindowStream.PutByte(m_InBitStream.DirectReadByte());
+ next--;
+ }
+ if (m_UnCompressedBlockSize == 0)
+ {
+ m_InBitStream.Align(m_AlignPos);
+ m_AlignPos = 0;
+ }
+ }
+ else while(next > 0)
+ {
+ UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
+ if (number < 256)
+ {
+ m_OutWindowStream.PutByte((Byte)number);
+ next--;
+ }
+ else
+ {
+ UInt32 posLenSlot = number - 256;
+ if (posLenSlot >= m_NumPosLenSlots)
+ return S_FALSE;
+ UInt32 posSlot = posLenSlot / kNumLenSlots;
+ UInt32 lenSlot = posLenSlot % kNumLenSlots;
+ UInt32 len = kMatchMinLen + lenSlot;
+ if (lenSlot == kNumLenSlots - 1)
+ {
+ UInt32 lenTemp = m_LenDecoder.DecodeSymbol(&m_InBitStream);
+ if (lenTemp >= kNumLenSymbols)
+ return S_FALSE;
+ len += lenTemp;
+ }
+
+ if (posSlot < kNumRepDistances)
+ {
+ UInt32 distance = m_RepDistances[posSlot];
+ m_RepDistances[posSlot] = m_RepDistances[0];
+ m_RepDistances[0] = distance;
+ }
+ else
+ {
+ UInt32 distance;
+ int numDirectBits;
+ if (posSlot < kNumPowerPosSlots)
+ {
+ numDirectBits = (posSlot >> 1) - 1;
+ distance = ((2 | (posSlot & 1)) << numDirectBits);
+ }
+ else
+ {
+ numDirectBits = kNumLinearPosSlotBits;
+ distance = ((posSlot - 0x22) << kNumLinearPosSlotBits);
+ }
+
+ if (m_AlignIsUsed && numDirectBits >= kNumAlignBits)
+ {
+ distance += (m_InBitStream.ReadBits(numDirectBits - kNumAlignBits) << kNumAlignBits);
+ UInt32 alignTemp = m_AlignDecoder.DecodeSymbol(&m_InBitStream);
+ if (alignTemp >= kAlignTableSize)
+ return S_FALSE;
+ distance += alignTemp;
+ }
+ else
+ distance += m_InBitStream.ReadBits(numDirectBits);
+ m_RepDistances[2] = m_RepDistances[1];
+ m_RepDistances[1] = m_RepDistances[0];
+ m_RepDistances[0] = distance - kNumRepDistances;
+ }
+
+ UInt32 locLen = len;
+ if (locLen > next)
+ locLen = next;
+
+ if (!m_OutWindowStream.CopyBlock(m_RepDistances[0], locLen))
+ return S_FALSE;
+
+ len -= locLen;
+ next -= locLen;
+ if (len != 0)
+ {
+ _remainLen = len;
+ return S_OK;
+ }
+ }
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CDecoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ if (outSize == NULL)
+ return E_INVALIDARG;
+ UInt64 size = *outSize;
+ const UInt64 startSize = size;
+
+ RINOK(SetInStream(inStream));
+ m_x86ConvertOutStreamSpec->SetStream(outStream);
+ m_OutWindowStream.SetStream(m_x86ConvertOutStream);
+ RINOK(SetOutStreamSize(outSize));
+
+ CDecoderFlusher flusher(this);
+
+ const UInt64 start = m_OutWindowStream.GetProcessedSize();
+ while(true)
+ {
+ UInt32 curSize = 1 << 18;
+ UInt64 rem = size - (m_OutWindowStream.GetProcessedSize() - start);
+ if (curSize > rem)
+ curSize = (UInt32)rem;
+ if (curSize == 0)
+ break;
+ RINOK(CodeSpec(curSize));
+ if (progress != NULL)
+ {
+ UInt64 inSize = m_InBitStream.GetProcessedSize();
+ UInt64 nowPos64 = m_OutWindowStream.GetProcessedSize() - start;
+ RINOK(progress->SetRatioInfo(&inSize, &nowPos64));
+ }
+ }
+ flusher.NeedFlush = false;
+ return Flush();
+}
+
+HRESULT CDecoder::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 CDecoder::SetInStream(ISequentialInStream *inStream)
+{
+ m_InBitStream.SetStream(inStream);
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::ReleaseInStream()
+{
+ m_InBitStream.ReleaseStream();
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
+{
+ if (outSize == NULL)
+ return E_FAIL;
+ _remainLen = kLenIdNeedInit;
+ m_OutWindowStream.Init(_keepHistory);
+ return S_OK;
+}
+
+HRESULT CDecoder::SetParams(int numDictBits)
+{
+ if (numDictBits < kNumDictionaryBitsMin || numDictBits > kNumDictionaryBitsMax)
+ return E_INVALIDARG;
+ UInt32 numPosSlots;
+ if (numDictBits < 20)
+ numPosSlots = 30 + (numDictBits - 15) * 2;
+ else if (numDictBits == 20)
+ numPosSlots = 42;
+ else
+ numPosSlots = 50;
+ m_NumPosLenSlots = numPosSlots * kNumLenSlots;
+ if (!m_OutWindowStream.Create(kDictionarySizeMax))
+ return E_OUTOFMEMORY;
+ if (!m_InBitStream.Create(1 << 16))
+ return E_OUTOFMEMORY;
+ return S_OK;
+}
+
+}}
diff --git a/7zip/Compress/Lzx/LzxDecoder.h b/7zip/Compress/Lzx/LzxDecoder.h
new file mode 100755
index 00000000..a62662ec
--- /dev/null
+++ b/7zip/Compress/Lzx/LzxDecoder.h
@@ -0,0 +1,181 @@
+// LzxDecoder.h
+
+#ifndef __LZXDECODER_H
+#define __LZXDECODER_H
+
+#include "../../ICoder.h"
+
+#include "../../Compress/Huffman/HuffmanDecoder.h"
+#include "../../Compress/LZ/LZOutWindow.h"
+#include "../../Common/InBuffer.h"
+
+#include "Lzx.h"
+#include "Lzx86Converter.h"
+
+namespace NCompress {
+namespace NLzx {
+
+namespace NBitStream {
+
+const int kNumBigValueBits = 8 * 4;
+const int kNumValueBits = 17;
+const UInt32 kBitDecoderValueMask = (1 << kNumValueBits) - 1;
+
+class CDecoder
+{
+ CInBuffer m_Stream;
+ UInt32 m_Value;
+ int m_BitPos;
+public:
+ CDecoder() {}
+ bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }
+
+ void SetStream(ISequentialInStream *s) { m_Stream.SetStream(s); }
+ void ReleaseStream() { m_Stream.ReleaseStream(); }
+
+ void InitNormal()
+ {
+ m_Stream.Init();
+ m_BitPos = kNumBigValueBits;
+ Normalize();
+ }
+
+ void InitDirect()
+ {
+ m_Stream.Init();
+ m_BitPos = kNumBigValueBits;
+ }
+
+ UInt64 GetProcessedSize() const
+ { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; }
+
+ int GetBitPosition() const { return m_BitPos & 0xF; }
+
+ void Normalize()
+ {
+ for (;m_BitPos >= 16; m_BitPos -= 16)
+ {
+ Byte b0 = m_Stream.ReadByte();
+ Byte b1 = m_Stream.ReadByte();
+ m_Value = (m_Value << 8) | b1;
+ m_Value = (m_Value << 8) | b0;
+ }
+ }
+
+ UInt32 GetValue(int numBits) const
+ {
+ return ((m_Value >> ((32 - kNumValueBits) - m_BitPos)) & kBitDecoderValueMask) >>
+ (kNumValueBits - numBits);
+ }
+
+ void MovePos(UInt32 numBits)
+ {
+ m_BitPos += numBits;
+ Normalize();
+ }
+
+ UInt32 ReadBits(int numBits)
+ {
+ UInt32 res = GetValue(numBits);
+ MovePos(numBits);
+ return res;
+ }
+
+ UInt32 ReadBitsBig(int numBits)
+ {
+ UInt32 numBits0 = numBits / 2;
+ UInt32 numBits1 = numBits - numBits0;
+ UInt32 res = ReadBits(numBits0) << numBits1;
+ return res + ReadBits(numBits1);
+ }
+
+ bool ReadUInt32(UInt32 &v)
+ {
+ if (m_BitPos != 0)
+ return false;
+ v = ((m_Value >> 16) & 0xFFFF) | ((m_Value << 16) & 0xFFFF0000);
+ m_BitPos = kNumBigValueBits;
+ return true;
+ }
+
+ Byte DirectReadByte() { return m_Stream.ReadByte(); }
+
+ void Align(int alignPos)
+ {
+ if (((m_Stream.GetProcessedSize() + alignPos) & 1) != 0)
+ m_Stream.ReadByte();
+ Normalize();
+ }
+};
+}
+
+class CDecoder :
+ public ICompressCoder,
+ public CMyUnknownImp
+{
+ NBitStream::CDecoder m_InBitStream;
+ CLZOutWindow m_OutWindowStream;
+
+ UInt32 m_RepDistances[kNumRepDistances];
+ UInt32 m_NumPosLenSlots;
+
+ bool m_IsUncompressedBlock;
+ bool m_AlignIsUsed;
+
+ NCompress::NHuffman::CDecoder<kNumHuffmanBits, kMainTableSize> m_MainDecoder;
+ NCompress::NHuffman::CDecoder<kNumHuffmanBits, kNumLenSymbols> m_LenDecoder;
+ NCompress::NHuffman::CDecoder<kNumHuffmanBits, kAlignTableSize> m_AlignDecoder;
+ NCompress::NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder;
+
+ Byte m_LastMainLevels[kMainTableSize];
+ Byte m_LastLenLevels[kNumLenSymbols];
+
+ Cx86ConvertOutStream *m_x86ConvertOutStreamSpec;
+ CMyComPtr<ISequentialOutStream> m_x86ConvertOutStream;
+
+ UInt32 m_UnCompressedBlockSize;
+
+ bool _keepHistory;
+ int _remainLen;
+ int m_AlignPos;
+
+ UInt32 ReadBits(UInt32 numBits);
+ bool ReadTable(Byte *lastLevels, Byte *newLevels, UInt32 numSymbols);
+ bool ReadTables();
+ void ClearPrevLevels();
+
+ HRESULT CodeSpec(UInt32 size);
+
+ HRESULT CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+public:
+ CDecoder();
+
+ MY_UNKNOWN_IMP
+
+ void ReleaseStreams();
+ STDMETHOD(Flush)();
+
+ // ICompressCoder interface
+ 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);
+
+ HRESULT SetParams(int numDictBits);
+ void SetKeepHistory(bool keepHistory, int alignPos)
+ {
+ _keepHistory = keepHistory;
+ m_AlignPos = alignPos;
+ }
+};
+
+}}
+
+#endif
diff --git a/7zip/Compress/Lzx/StdAfx.h b/7zip/Compress/Lzx/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/7zip/Compress/Lzx/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/7zip/Compress/PPMD/PPMD.dsp b/7zip/Compress/PPMD/PPMD.dsp
index 09c3d7f8..9e512f6c 100755
--- a/7zip/Compress/PPMD/PPMD.dsp
+++ b/7zip/Compress/PPMD/PPMD.dsp
@@ -192,6 +192,14 @@ SOURCE=..\..\Common\OutBuffer.cpp
SOURCE=..\..\Common\OutBuffer.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 "RangeCoder"
diff --git a/7zip/Compress/PPMD/PPMDContext.h b/7zip/Compress/PPMD/PPMDContext.h
index 1b926585..6f154fc4 100755
--- a/7zip/Compress/PPMD/PPMDContext.h
+++ b/7zip/Compress/PPMD/PPMDContext.h
@@ -15,9 +15,9 @@ namespace NPPMD {
const int INT_BITS=7, PERIOD_BITS=7, TOT_BITS=INT_BITS+PERIOD_BITS,
INTERVAL=1 << INT_BITS, BIN_SCALE=1 << TOT_BITS, MAX_FREQ=124;
-#pragma pack(1)
struct SEE2_CONTEXT
-{ // SEE-contexts for PPM-contexts with masked symbols
+{
+ // SEE-contexts for PPM-contexts with masked symbols
UInt16 Summ;
Byte Shift, Count;
void init(int InitVal) { Summ=InitVal << (Shift=PERIOD_BITS-4); Count=4; }
@@ -39,9 +39,25 @@ struct SEE2_CONTEXT
struct PPM_CONTEXT
{
- UInt16 NumStats,SummFreq; // sizeof(UInt16) > sizeof(Byte)
- struct STATE { Byte Symbol, Freq; PPM_CONTEXT* Successor; } _PACK_ATTR * Stats;
- PPM_CONTEXT* Suffix;
+ UInt16 NumStats; // sizeof(UInt16) > sizeof(Byte)
+ UInt16 SummFreq;
+
+ struct STATE
+ {
+ Byte Symbol, Freq;
+ UInt16 SuccessorLow;
+ UInt16 SuccessorHigh;
+
+ UInt32 GetSuccessor() const { return SuccessorLow | ((UInt32)SuccessorHigh << 16); }
+ void SetSuccessor(UInt32 v)
+ {
+ SuccessorLow = (UInt16)(v & 0xFFFF);
+ SuccessorHigh = (UInt16)((v >> 16) & 0xFFFF);
+ }
+ };
+
+ UInt32 Stats;
+ UInt32 Suffix;
PPM_CONTEXT* createChild(CSubAllocator &subAllocator, STATE* pStats, STATE& FirstState)
{
@@ -50,15 +66,14 @@ struct PPM_CONTEXT
{
pc->NumStats = 1;
pc->oneState() = FirstState;
- pc->Suffix = this;
- pStats->Successor = pc;
+ pc->Suffix = subAllocator.GetOffset(this);
+ pStats->SetSuccessor(subAllocator.GetOffsetNoCheck(pc));
}
return pc;
}
STATE& oneState() const { return (STATE&) SummFreq; }
};
-#pragma pack()
/////////////////////////////////
@@ -68,8 +83,8 @@ const UInt16 InitBinEsc[] =
struct CInfo
{
CSubAllocator SubAllocator;
- SEE2_CONTEXT _PACK_ATTR SEE2Cont[25][16], DummySEE2Cont;
- PPM_CONTEXT _PACK_ATTR * MinContext, * MaxContext;
+ SEE2_CONTEXT SEE2Cont[25][16], DummySEE2Cont;
+ PPM_CONTEXT * MinContext, * MaxContext;
PPM_CONTEXT::STATE* FoundState; // found next state transition
int NumMasked, InitEsc, OrderFall, RunLength, InitRL, MaxOrder;
@@ -86,6 +101,11 @@ struct CInfo
((RunLength >> 26) & 0x20)];
}
+ PPM_CONTEXT *GetContext(UInt32 offset) const { return (PPM_CONTEXT *)SubAllocator.GetPtr(offset); }
+ PPM_CONTEXT *GetContextNoCheck(UInt32 offset) const { return (PPM_CONTEXT *)SubAllocator.GetPtrNoCheck(offset); }
+ PPM_CONTEXT::STATE *GetState(UInt32 offset) const { return (PPM_CONTEXT::STATE *)SubAllocator.GetPtr(offset); }
+ PPM_CONTEXT::STATE *GetStateNoCheck(UInt32 offset) const { return (PPM_CONTEXT::STATE *)SubAllocator.GetPtr(offset); }
+
void RestartModelRare()
{
int i, k, m;
@@ -93,15 +113,17 @@ struct CInfo
SubAllocator.InitSubAllocator();
InitRL = -((MaxOrder < 12) ? MaxOrder : 12) - 1;
MinContext = MaxContext = (PPM_CONTEXT*) SubAllocator.AllocContext();
- MinContext->Suffix = NULL;
+ MinContext->Suffix = 0;
OrderFall = MaxOrder;
MinContext->SummFreq = (MinContext->NumStats = 256) + 1;
- FoundState = MinContext->Stats = (PPM_CONTEXT::STATE*) SubAllocator.AllocUnits(256 / 2);
+ FoundState = (PPM_CONTEXT::STATE*)SubAllocator.AllocUnits(256 / 2);
+ MinContext->Stats = SubAllocator.GetOffsetNoCheck(FoundState);
for (RunLength = InitRL, PrevSuccess = i = 0; i < 256; i++)
{
- MinContext->Stats[i].Symbol = i;
- MinContext->Stats[i].Freq = 1;
- MinContext->Stats[i].Successor = NULL;
+ PPM_CONTEXT::STATE &state = FoundState[i];
+ state.Symbol = i;
+ state.Freq = 1;
+ state.SetSuccessor(0);
}
for (i = 0; i < 128; i++)
for (k = 0; k < 8; k++)
@@ -121,12 +143,12 @@ struct CInfo
memset(CharMask,0,sizeof(CharMask));
OrderFall = this->MaxOrder;
MinContext = MaxContext;
- while (MinContext->Suffix != NULL)
+ while (MinContext->Suffix != 0)
{
- MinContext = MinContext->Suffix;
- OrderFall--;
+ MinContext = GetContextNoCheck(MinContext->Suffix);
+ OrderFall--;
}
- FoundState = MinContext->Stats;
+ FoundState = GetState(MinContext->Stats);
MinContext = MaxContext;
}
else
@@ -160,7 +182,8 @@ struct CInfo
// static PPM_CONTEXT::STATE UpState;
PPM_CONTEXT::STATE UpState;
- PPM_CONTEXT* pc = MinContext, * UpBranch = FoundState->Successor;
+ PPM_CONTEXT *pc = MinContext;
+ PPM_CONTEXT *UpBranch = GetContext(FoundState->GetSuccessor());
PPM_CONTEXT::STATE * p, * ps[MAX_O], ** pps = ps;
if ( !skip )
{
@@ -171,23 +194,23 @@ struct CInfo
if ( p1 )
{
p = p1;
- pc = pc->Suffix;
+ pc = GetContext(pc->Suffix);
goto LOOP_ENTRY;
}
do
{
- pc = pc->Suffix;
+ pc = GetContext(pc->Suffix);
if (pc->NumStats != 1)
{
- if ((p = pc->Stats)->Symbol != FoundState->Symbol)
+ if ((p = GetStateNoCheck(pc->Stats))->Symbol != FoundState->Symbol)
do { p++; } while (p->Symbol != FoundState->Symbol);
}
else
p = &(pc->oneState());
LOOP_ENTRY:
- if (p->Successor != UpBranch)
+ if (GetContext(p->GetSuccessor()) != UpBranch)
{
- pc = p->Successor;
+ pc = GetContext(p->GetSuccessor());
break;
}
*pps++ = p;
@@ -197,10 +220,10 @@ NO_LOOP:
if (pps == ps)
return pc;
UpState.Symbol = *(Byte*) UpBranch;
- UpState.Successor = (PPM_CONTEXT*) (((Byte*) UpBranch)+1);
+ UpState.SetSuccessor(SubAllocator.GetOffset(UpBranch) + 1);
if (pc->NumStats != 1)
{
- if ((p = pc->Stats)->Symbol != UpState.Symbol)
+ if ((p = GetStateNoCheck(pc->Stats))->Symbol != UpState.Symbol)
do { p++; } while (p->Symbol != UpState.Symbol);
unsigned int cf = p->Freq-1;
unsigned int s0 = pc->SummFreq - pc->NumStats - cf;
@@ -224,11 +247,13 @@ NO_LOOP:
PPM_CONTEXT::STATE fs = *FoundState, * p = NULL;
PPM_CONTEXT* pc, * Successor;
unsigned int ns1, ns, cf, sf, s0;
- if (fs.Freq < MAX_FREQ/4 && (pc=MinContext->Suffix) != NULL)
+ if (fs.Freq < MAX_FREQ / 4 && MinContext->Suffix != 0)
{
+ pc = GetContextNoCheck(MinContext->Suffix);
+
if (pc->NumStats != 1)
{
- if ((p = pc->Stats)->Symbol != fs.Symbol)
+ if ((p = GetStateNoCheck(pc->Stats))->Symbol != fs.Symbol)
{
do { p++; } while (p->Symbol != fs.Symbol);
if (p[0].Freq >= p[-1].Freq)
@@ -251,8 +276,9 @@ NO_LOOP:
}
if ( !OrderFall )
{
- MinContext = MaxContext = FoundState->Successor = CreateSuccessors(true, p);
- if ( !MinContext )
+ MinContext = MaxContext = CreateSuccessors(true, p);
+ FoundState->SetSuccessor(SubAllocator.GetOffset(MinContext));
+ if (MinContext == 0)
goto RESTART_MODEL;
return;
}
@@ -260,31 +286,36 @@ NO_LOOP:
Successor = (PPM_CONTEXT*) SubAllocator.pText;
if (SubAllocator.pText >= SubAllocator.UnitsStart)
goto RESTART_MODEL;
- if ( fs.Successor )
+ if (fs.GetSuccessor() != 0)
{
- if ((Byte*) fs.Successor <= SubAllocator.pText &&
- (fs.Successor=CreateSuccessors(false, p)) == NULL)
- goto RESTART_MODEL;
+ if ((Byte *)GetContext(fs.GetSuccessor()) <= SubAllocator.pText)
+ {
+ PPM_CONTEXT* cs = CreateSuccessors(false, p);
+ fs.SetSuccessor(SubAllocator.GetOffset(cs));
+ if (cs == NULL)
+ goto RESTART_MODEL;
+ }
if ( !--OrderFall )
{
- Successor = fs.Successor;
+ Successor = GetContext(fs.GetSuccessor());
SubAllocator.pText -= (MaxContext != MinContext);
}
}
else
{
- FoundState->Successor = Successor;
- fs.Successor = MinContext;
+ FoundState->SetSuccessor(SubAllocator.GetOffsetNoCheck(Successor));
+ fs.SetSuccessor(SubAllocator.GetOffsetNoCheck(MinContext));
}
s0 = MinContext->SummFreq - (ns = MinContext->NumStats) - (fs.Freq - 1);
- for (pc = MaxContext; pc != MinContext; pc = pc->Suffix)
+ for (pc = MaxContext; pc != MinContext; pc = GetContext(pc->Suffix))
{
if ((ns1 = pc->NumStats) != 1)
{
if ((ns1 & 1) == 0)
{
- pc->Stats = (PPM_CONTEXT::STATE*) SubAllocator.ExpandUnits(pc->Stats, ns1 >> 1);
- if ( !pc->Stats )
+ void *ppp = SubAllocator.ExpandUnits(GetState(pc->Stats), ns1 >> 1);
+ pc->Stats = SubAllocator.GetOffset(ppp);
+ if (!ppp)
goto RESTART_MODEL;
}
pc->SummFreq += (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) &
@@ -296,7 +327,7 @@ NO_LOOP:
if ( !p )
goto RESTART_MODEL;
*p = pc->oneState();
- pc->Stats = p;
+ pc->Stats = SubAllocator.GetOffsetNoCheck(p);
if (p->Freq < MAX_FREQ / 4 - 1)
p->Freq += p->Freq;
else
@@ -315,13 +346,13 @@ NO_LOOP:
cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf);
pc->SummFreq += cf;
}
- p = pc->Stats + ns1;
- p->Successor = Successor;
+ p = GetState(pc->Stats) + ns1;
+ p->SetSuccessor(SubAllocator.GetOffset(Successor));
p->Symbol = fs.Symbol;
p->Freq = cf;
pc->NumStats = ++ns1;
}
- MaxContext = MinContext = fs.Successor;
+ MaxContext = MinContext = GetContext(fs.GetSuccessor());
return;
RESTART_MODEL:
RestartModelRare();
@@ -366,8 +397,11 @@ RESTART_MODEL:
SEE2_CONTEXT* psee2c;
if (MinContext->NumStats != 256)
{
- psee2c = SEE2Cont[NS2Indx[Diff-1]] + (Diff < MinContext->Suffix->NumStats - MinContext->NumStats)+
- 2 * (MinContext->SummFreq < 11 * MinContext->NumStats) + 4 * (NumMasked > Diff) + HiBitsFlag;
+ psee2c = SEE2Cont[NS2Indx[Diff-1]] +
+ (Diff < (GetContext(MinContext->Suffix))->NumStats - MinContext->NumStats) +
+ 2 * (MinContext->SummFreq < 11 * MinContext->NumStats) +
+ 4 * (NumMasked > Diff) +
+ HiBitsFlag;
scale = psee2c->getMean();
}
else
@@ -384,9 +418,10 @@ RESTART_MODEL:
{
int OldNS = MinContext->NumStats, i = MinContext->NumStats - 1, Adder, EscFreq;
PPM_CONTEXT::STATE* p1, * p;
- for (p = FoundState; p != MinContext->Stats; p--)
+ PPM_CONTEXT::STATE *stats = GetStateNoCheck(MinContext->Stats);
+ for (p = FoundState; p != stats; p--)
_PPMD_SWAP(p[0], p[-1]);
- MinContext->Stats->Freq += 4;
+ stats->Freq += 4;
MinContext->SummFreq += 4;
EscFreq = MinContext->SummFreq - p->Freq;
Adder = (OrderFall != 0);
@@ -398,7 +433,11 @@ RESTART_MODEL:
if (p[0].Freq > p[-1].Freq)
{
PPM_CONTEXT::STATE tmp = *(p1 = p);
- do { p1[0] = p1[-1]; } while (--p1 != MinContext->Stats && tmp.Freq > p1[-1].Freq);
+ do
+ {
+ p1[0] = p1[-1];
+ }
+ while (--p1 != stats && tmp.Freq > p1[-1].Freq);
*p1 = tmp;
}
}
@@ -409,24 +448,24 @@ RESTART_MODEL:
EscFreq += i;
if ((MinContext->NumStats -= i) == 1)
{
- PPM_CONTEXT::STATE tmp = *MinContext->Stats;
+ PPM_CONTEXT::STATE tmp = *stats;
do { tmp.Freq -= (tmp.Freq >> 1); EscFreq >>= 1; } while (EscFreq > 1);
- SubAllocator.FreeUnits(MinContext->Stats, (OldNS+1) >> 1);
+ SubAllocator.FreeUnits(stats, (OldNS+1) >> 1);
*(FoundState = &MinContext->oneState()) = tmp; return;
}
}
MinContext->SummFreq += (EscFreq -= (EscFreq >> 1));
int n0 = (OldNS+1) >> 1, n1 = (MinContext->NumStats + 1) >> 1;
if (n0 != n1)
- MinContext->Stats =
- (PPM_CONTEXT::STATE*) SubAllocator.ShrinkUnits(MinContext->Stats, n0, n1);
- FoundState = MinContext->Stats;
+ MinContext->Stats = SubAllocator.GetOffset(SubAllocator.ShrinkUnits(stats, n0, n1));
+ FoundState = GetState(MinContext->Stats);
}
void NextContext()
{
- if (!OrderFall && (Byte*) FoundState->Successor > SubAllocator.pText)
- MinContext = MaxContext = FoundState->Successor;
+ PPM_CONTEXT *c = GetContext(FoundState->GetSuccessor());
+ if (!OrderFall && (Byte *)c > SubAllocator.pText)
+ MinContext = MaxContext = c;
else
{
UpdateModel();
diff --git a/7zip/Compress/PPMD/PPMDDecode.h b/7zip/Compress/PPMD/PPMDDecode.h
index 83445718..56afbe66 100755
--- a/7zip/Compress/PPMD/PPMDDecode.h
+++ b/7zip/Compress/PPMD/PPMDDecode.h
@@ -14,7 +14,7 @@ struct CDecodeInfo: public CInfo
void DecodeBinSymbol(NRangeCoder::CDecoder *rangeDecoder)
{
PPM_CONTEXT::STATE& rs = MinContext->oneState();
- UInt16& bs = GetBinSumm(rs, MinContext->Suffix->NumStats);
+ UInt16& bs = GetBinSumm(rs, GetContextNoCheck(MinContext->Suffix)->NumStats);
if (rangeDecoder->DecodeBit(bs, TOT_BITS) == 0)
{
FoundState = &rs;
@@ -36,13 +36,13 @@ struct CDecodeInfo: public CInfo
void DecodeSymbol1(NRangeCoder::CDecoder *rangeDecoder)
{
- PPM_CONTEXT::STATE* p = MinContext->Stats;
+ PPM_CONTEXT::STATE* p = GetStateNoCheck(MinContext->Stats);
int i, count, hiCnt;
if ((count = rangeDecoder->GetThreshold(MinContext->SummFreq)) < (hiCnt = p->Freq))
{
PrevSuccess = (2 * hiCnt > MinContext->SummFreq);
RunLength += PrevSuccess;
- rangeDecoder->Decode(0, MinContext->Stats->Freq); // MinContext->SummFreq);
+ rangeDecoder->Decode(0, p->Freq); // MinContext->SummFreq);
(FoundState = p)->Freq=(hiCnt += 4);
MinContext->SummFreq += 4;
if (hiCnt > MAX_FREQ)
@@ -72,7 +72,7 @@ struct CDecodeInfo: public CInfo
int count, hiCnt, i = MinContext->NumStats - NumMasked;
UInt32 freqSum;
SEE2_CONTEXT* psee2c = makeEscFreq2(i, freqSum);
- PPM_CONTEXT::STATE* ps[256], ** pps = ps, * p = MinContext->Stats-1;
+ PPM_CONTEXT::STATE* ps[256], ** pps = ps, * p = GetStateNoCheck(MinContext->Stats)-1;
hiCnt = 0;
do
{
@@ -119,8 +119,8 @@ struct CDecodeInfo: public CInfo
do
{
OrderFall++;
- MinContext = MinContext->Suffix;
- if ( !MinContext )
+ MinContext = GetContext(MinContext->Suffix);
+ if (MinContext == 0)
return -1;
}
while (MinContext->NumStats == NumMasked);
diff --git a/7zip/Compress/PPMD/PPMDDecoder.cpp b/7zip/Compress/PPMD/PPMDDecoder.cpp
index 5677daf2..50200053 100755
--- a/7zip/Compress/PPMD/PPMDDecoder.cpp
+++ b/7zip/Compress/PPMD/PPMDDecoder.cpp
@@ -10,6 +10,9 @@
namespace NCompress {
namespace NPPMD {
+const int kLenIdFinished = -1;
+const int kLenIdNeedInit = -2;
+
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *properties, UInt32 size)
{
if (size < 5)
@@ -18,6 +21,15 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *properties, UInt32 size
_usedMemorySize = 0;
for (int i = 0; i < 4; i++)
_usedMemorySize += ((UInt32)(properties[1 + i])) << (i * 8);
+
+ if (_usedMemorySize > kMaxMemBlockSize)
+ return E_NOTIMPL;
+
+ if (!_rangeDecoder.Create(1 << 20))
+ return E_OUTOFMEMORY;
+ if (!_info.SubAllocator.StartSubAllocator(_usedMemorySize))
+ return E_OUTOFMEMORY;
+
return S_OK;
}
@@ -25,76 +37,146 @@ class CDecoderFlusher
{
CDecoder *_coder;
public:
- CDecoderFlusher(CDecoder *coder): _coder(coder) {}
+ bool NeedFlush;
+ CDecoderFlusher(CDecoder *coder): _coder(coder), NeedFlush(true) {}
~CDecoderFlusher()
{
- _coder->Flush();
+ if (NeedFlush)
+ _coder->Flush();
_coder->ReleaseStreams();
}
};
-UInt32 GetMatchLen(const Byte *pointer1, const Byte *pointer2,
- UInt32 limit)
-{
- UInt32 i;
- for(i = 0; i < limit && *pointer1 == *pointer2;
- pointer1++, pointer2++, i++);
- return i;
+HRESULT CDecoder::CodeSpec(UInt32 size, Byte *memStream)
+{
+ const startSize = size;
+ if (_outSizeDefined)
+ {
+ const UInt64 rem = _outSize - _processedSize;
+ if (size > rem)
+ size = (UInt32)rem;
+ }
+
+ if (_remainLen == kLenIdFinished)
+ return S_OK;
+ if (_remainLen == kLenIdNeedInit)
+ {
+ _rangeDecoder.Init();
+ _remainLen = 0;
+ _info.MaxOrder = 0;
+ _info.StartModelRare(_order);
+ }
+ while (size != 0)
+ {
+ int symbol = _info.DecodeSymbol(&_rangeDecoder);
+ if (symbol < 0)
+ {
+ _remainLen = kLenIdFinished;
+ break;
+ }
+ if (memStream != 0)
+ *memStream++ = symbol;
+ else
+ _outStream.WriteByte((Byte)symbol);
+ size--;
+ }
+ _processedSize += startSize - size;
+ return S_OK;
}
STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress)
{
- if (!_rangeDecoder.Create(1 << 20))
- return E_OUTOFMEMORY;
if (!_outStream.Create(1 << 20))
return E_OUTOFMEMORY;
-
- _rangeDecoder.SetStream(inStream);
- _rangeDecoder.Init();
+
+ SetInStream(inStream);
_outStream.SetStream(outStream);
- _outStream.Init();
-
+ SetOutStreamSize(outSize);
CDecoderFlusher flusher(this);
- UInt64 progressPosValuePrev = 0, pos = 0;
-
- if (!_info.SubAllocator.StartSubAllocator(_usedMemorySize))
- return E_OUTOFMEMORY;
-
- // _info.Init();
- // _info.MaxOrder = _order;
- _info.MaxOrder = 0;
- _info.StartModelRare(_order);
-
- UInt64 size = (outSize == NULL) ? (UInt64)(Int64)(-1) : *outSize;
-
- while(pos < size)
+ while(true)
{
- pos++;
- int symbol = _info.DecodeSymbol(&_rangeDecoder);
- if (symbol < 0)
- return S_OK;
- _outStream.WriteByte(symbol);
- if (pos - progressPosValuePrev >= (1 << 18) && progress != NULL)
+ _processedSize = _outStream.GetProcessedSize();
+ UInt32 curSize = (1 << 18);
+ RINOK(CodeSpec(curSize, NULL));
+ if (_remainLen == kLenIdFinished)
+ break;
+ if (progress != NULL)
{
UInt64 inSize = _rangeDecoder.GetProcessedSize();
- RINOK(progress->SetRatioInfo(&inSize, &pos));
- progressPosValuePrev = pos;
+ RINOK(progress->SetRatioInfo(&inSize, &_processedSize));
}
+ if (_outSizeDefined)
+ if (_outStream.GetProcessedSize() >= _outSize)
+ break;
}
- return S_OK;
+ flusher.NeedFlush = false;
+ return Flush();
}
+#ifdef _NO_EXCEPTIONS
+
+#define PPMD_TRY_BEGIN
+#define PPMD_TRY_END
+
+#else
+
+#define PPMD_TRY_BEGIN try {
+#define PPMD_TRY_END } \
+ catch(const CInBufferException &e) { return e.ErrorCode; } \
+ catch(const COutBufferException &e) { return e.ErrorCode; } \
+ catch(...) { return S_FALSE; }
+
+#endif
+
+
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 COutBufferException &e) { return e.ErrorCode; }
- catch(const CInBufferException &e) { return e.ErrorCode; }
- catch(...) { return E_FAIL; }
+ PPMD_TRY_BEGIN
+ return CodeReal(inStream, outStream, inSize, outSize, progress);
+ PPMD_TRY_END
+}
+
+STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream)
+{
+ _rangeDecoder.SetStream(inStream);
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::ReleaseInStream()
+{
+ _rangeDecoder.ReleaseStream();
+ return S_OK;
}
+STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
+{
+ if (_outSizeDefined = (outSize != NULL))
+ _outSize = *outSize;
+ _remainLen = kLenIdNeedInit;
+ _outStream.Init();
+ return S_OK;
+}
+
+#ifdef _ST_MODE
+
+STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ PPMD_TRY_BEGIN
+ if (processedSize)
+ *processedSize = 0;
+ const UInt64 startPos = _processedSize;
+ RINOK(CodeSpec(size, (Byte *)data));
+ if (processedSize)
+ *processedSize = (UInt32)(_processedSize - startPos);
+ return Flush();
+ PPMD_TRY_END
+}
+
+#endif
+
}}
diff --git a/7zip/Compress/PPMD/PPMDDecoder.h b/7zip/Compress/PPMD/PPMDDecoder.h
index a5c2d18e..bbb68ac5 100755
--- a/7zip/Compress/PPMD/PPMDDecoder.h
+++ b/7zip/Compress/PPMD/PPMDDecoder.h
@@ -17,6 +17,11 @@ namespace NPPMD {
class CDecoder :
public ICompressCoder,
public ICompressSetDecoderProperties2,
+ #ifdef _ST_MODE
+ public ICompressSetInStream,
+ public ICompressSetOutStreamSize,
+ public ISequentialInStream,
+ #endif
public CMyUnknownImp
{
NRangeCoder::CDecoder _rangeDecoder;
@@ -28,13 +33,28 @@ class CDecoder :
Byte _order;
UInt32 _usedMemorySize;
+ int _remainLen;
+ UInt64 _outSize;
+ bool _outSizeDefined;
+ UInt64 _processedSize;
+
+ HRESULT CodeSpec(UInt32 num, Byte *memStream);
public:
- MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)
+ #ifdef _ST_MODE
+ MY_UNKNOWN_IMP4(
+ ICompressSetDecoderProperties2,
+ ICompressSetInStream,
+ ICompressSetOutStreamSize,
+ ISequentialInStream)
+ #else
+ MY_UNKNOWN_IMP1(
+ ICompressSetDecoderProperties2)
+ #endif
void ReleaseStreams()
{
- _rangeDecoder.ReleaseStream();
+ ReleaseInStream();
_outStream.ReleaseStream();
}
@@ -51,6 +71,17 @@ public:
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+
+ STDMETHOD(SetInStream)(ISequentialInStream *inStream);
+ STDMETHOD(ReleaseInStream)();
+ STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
+
+ #ifdef _ST_MODE
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ #endif
+
+ CDecoder(): _outSizeDefined(false) {}
+
};
}}
diff --git a/7zip/Compress/PPMD/PPMDEncode.h b/7zip/Compress/PPMD/PPMDEncode.h
index c2342058..860310a2 100755
--- a/7zip/Compress/PPMD/PPMDEncode.h
+++ b/7zip/Compress/PPMD/PPMDEncode.h
@@ -15,7 +15,7 @@ struct CEncodeInfo: public CInfo
void EncodeBinSymbol(int symbol, NRangeCoder::CEncoder *rangeEncoder)
{
PPM_CONTEXT::STATE& rs = MinContext->oneState();
- UInt16 &bs = GetBinSumm(rs, MinContext->Suffix->NumStats);
+ UInt16 &bs = GetBinSumm(rs, GetContextNoCheck(MinContext->Suffix)->NumStats);
if (rs.Symbol == symbol)
{
FoundState = &rs;
@@ -39,12 +39,12 @@ struct CEncodeInfo: public CInfo
void EncodeSymbol1(int symbol, NRangeCoder::CEncoder *rangeEncoder)
{
- PPM_CONTEXT::STATE* p = MinContext->Stats;
+ PPM_CONTEXT::STATE* p = GetStateNoCheck(MinContext->Stats);
if (p->Symbol == symbol)
{
PrevSuccess = (2 * (p->Freq) > MinContext->SummFreq);
RunLength += PrevSuccess;
- rangeEncoder->Encode(0, MinContext->Stats->Freq, MinContext->SummFreq);
+ rangeEncoder->Encode(0, p->Freq, MinContext->SummFreq);
(FoundState = p)->Freq += 4;
MinContext->SummFreq += 4;
if (p->Freq > MAX_FREQ)
@@ -76,7 +76,7 @@ struct CEncodeInfo: public CInfo
int hiCnt, i = MinContext->NumStats - NumMasked;
UInt32 scale;
SEE2_CONTEXT* psee2c = makeEscFreq2(i, scale);
- PPM_CONTEXT::STATE* p = MinContext->Stats - 1;
+ PPM_CONTEXT::STATE* p = GetStateNoCheck(MinContext->Stats) - 1;
hiCnt = 0;
do
{
@@ -126,8 +126,8 @@ SYMBOL_FOUND:
do
{
OrderFall++;
- MinContext = MinContext->Suffix;
- if ( !MinContext )
+ MinContext = GetContext(MinContext->Suffix);
+ if (MinContext == 0)
return; // S_OK;
}
while (MinContext->NumStats == NumMasked);
diff --git a/7zip/Compress/PPMD/PPMDEncoder.cpp b/7zip/Compress/PPMD/PPMDEncoder.cpp
index 16eaea60..b661f018 100755
--- a/7zip/Compress/PPMD/PPMDEncoder.cpp
+++ b/7zip/Compress/PPMD/PPMDEncoder.cpp
@@ -9,6 +9,8 @@
#include "Common/Defs.h"
+#include "../../Common/StreamUtils.h"
+
#include "PPMDEncoder.h"
namespace NCompress {
@@ -40,19 +42,7 @@ public:
}
};
-
CCounter g_Counter;
-
-
-/*
-// ISetRangeEncoder
-STDMETHODIMP CEncoder::SetRangeEncoder(CRangeEncoder *aRangeEncoder)
-{
- _rangeEncoder = aRangeEncoder;
- RINOK(_rangeEncoder.QueryInterface(&m_InitOutCoder));
-
- return S_OK;
-}
*/
STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
@@ -60,22 +50,22 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
{
for (UInt32 i = 0; i < numProperties; i++)
{
- const PROPVARIANT &aProperty = properties[i];
+ const PROPVARIANT &prop = properties[i];
switch(propIDs[i])
{
case NCoderPropID::kUsedMemorySize:
- if (aProperty.vt != VT_UI4)
+ if (prop.vt != VT_UI4)
return E_INVALIDARG;
- if (aProperty.ulVal < kMinMemSize)
+ if (prop.ulVal < kMinMemSize || prop.ulVal > kMaxMemBlockSize)
return E_INVALIDARG;
- _usedMemorySize = aProperty.ulVal;
+ _usedMemorySize = (UInt32)prop.ulVal;
break;
case NCoderPropID::kOrder:
- if (aProperty.vt != VT_UI4)
+ if (prop.vt != VT_UI4)
return E_INVALIDARG;
- if (aProperty.ulVal < kMinOrder || aProperty.ulVal > kMaxOrderCompress)
+ if (prop.ulVal < kMinOrder || prop.ulVal > kMaxOrderCompress)
return E_INVALIDARG;
- _order = Byte(aProperty.ulVal);
+ _order = (Byte)prop.ulVal;
break;
default:
return E_INVALIDARG;
@@ -91,7 +81,7 @@ STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
properties[0] = _order;
for (int i = 0; i < 4; i++)
properties[1 + i] = Byte(_usedMemorySize >> (8 * i));
- return outStream->Write(properties, kPropSize, NULL);
+ return WriteStream(outStream, properties, kPropSize, NULL);
}
const UInt32 kUsedMemorySizeDefault = (1 << 24);
@@ -101,30 +91,9 @@ CEncoder::CEncoder():
_usedMemorySize(kUsedMemorySizeDefault),
_order(kOrderDefault)
{
- // SubAllocator.StartSubAllocator(kSubAllocator);
}
-HRESULT CEncoder::Flush()
-{
- _rangeEncoder.FlushData();
- return _rangeEncoder.FlushStream();
-}
-
-class CEncoderFlusher
-{
- CEncoder *_encoder;
-public:
- CEncoderFlusher(CEncoder *encoder): _encoder(encoder) {}
- ~CEncoderFlusher()
- {
- _encoder->Flush();
- _encoder->ReleaseStreams();
- }
-};
-
-
-
HRESULT CEncoder::CodeReal(ISequentialInStream *inStream,
ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize,
@@ -134,50 +103,41 @@ HRESULT CEncoder::CodeReal(ISequentialInStream *inStream,
return E_OUTOFMEMORY;
if (!_rangeEncoder.Create(1 << 20))
return E_OUTOFMEMORY;
+ if (!_info.SubAllocator.StartSubAllocator(_usedMemorySize))
+ return E_OUTOFMEMORY;
_inStream.SetStream(inStream);
_inStream.Init();
+
_rangeEncoder.SetStream(outStream);
_rangeEncoder.Init();
CEncoderFlusher flusher(this);
- UInt64 pos = 0;
- UInt64 prevProgressPos = 0;
-
- try
- {
- if ( !_info.SubAllocator.StartSubAllocator(_usedMemorySize) )
- return E_OUTOFMEMORY;
- }
- catch(...)
- {
- return E_OUTOFMEMORY;
- }
-
-
_info.MaxOrder = 0;
_info.StartModelRare(_order);
-
- while (true)
+ while(true)
{
- Byte symbol;
- if (!_inStream.ReadByte(symbol))
+ UInt32 size = (1 << 18);
+ do
{
- // here we can write End Mark for stream version.
- // In current version this feature is not used.
- // _info.EncodeSymbol(-1, &_rangeEncoder);
-
- return S_OK;
+ Byte symbol;
+ if (!_inStream.ReadByte(symbol))
+ {
+ // here we can write End Mark for stream version.
+ // In current version this feature is not used.
+ // _info.EncodeSymbol(-1, &_rangeEncoder);
+ return S_OK;
+ }
+ _info.EncodeSymbol(symbol, &_rangeEncoder);
}
- _info.EncodeSymbol(symbol, &_rangeEncoder);
- pos++;
- if (pos - prevProgressPos >= (1 << 18) && progress != NULL)
+ while (--size != 0);
+ if (progress != NULL)
{
+ UInt64 inSize = _inStream.GetProcessedSize();
UInt64 outSize = _rangeEncoder.GetProcessedSize();
- RINOK(progress->SetRatioInfo(&pos, &outSize));
- prevProgressPos = pos;
+ RINOK(progress->SetRatioInfo(&inSize, &outSize));
}
}
}
@@ -193,4 +153,3 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
}
}}
-
diff --git a/7zip/Compress/PPMD/PPMDEncoder.h b/7zip/Compress/PPMD/PPMDEncoder.h
index 80ac7391..915180b9 100755
--- a/7zip/Compress/PPMD/PPMDEncoder.h
+++ b/7zip/Compress/PPMD/PPMDEncoder.h
@@ -29,14 +29,12 @@ public:
UInt32 _usedMemorySize;
Byte _order;
-public:
-
- MY_UNKNOWN_IMP2(
- ICompressSetCoderProperties,
- ICompressWriteCoderProperties)
+ HRESULT Flush()
+ {
+ _rangeEncoder.FlushData();
+ return _rangeEncoder.FlushStream();
+ }
- // ICoder interface
- HRESULT Flush();
void ReleaseStreams()
{
_inStream.ReleaseStream();
@@ -46,6 +44,25 @@ public:
HRESULT CodeReal(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress);
+
+ class CEncoderFlusher
+ {
+ CEncoder *_encoder;
+ public:
+ CEncoderFlusher(CEncoder *encoder): _encoder(encoder) {}
+ ~CEncoderFlusher()
+ {
+ _encoder->Flush();
+ _encoder->ReleaseStreams();
+ }
+ };
+
+public:
+
+ MY_UNKNOWN_IMP2(
+ ICompressSetCoderProperties,
+ ICompressWriteCoderProperties)
+
STDMETHOD(Code)(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress);
diff --git a/7zip/Compress/PPMD/PPMDSubAlloc.h b/7zip/Compress/PPMD/PPMDSubAlloc.h
index 5a333fe3..fd64d577 100755
--- a/7zip/Compress/PPMD/PPMDSubAlloc.h
+++ b/7zip/Compress/PPMD/PPMDSubAlloc.h
@@ -11,39 +11,47 @@
const UINT N1=4, N2=4, N3=4, N4=(128+3-1*N1-2*N2-3*N3)/4;
const UINT UNIT_SIZE=12, N_INDEXES=N1+N2+N3+N4;
-#pragma pack(1)
+// Extra 1 * UNIT_SIZE for NULL support
+// Extra 2 * UNIT_SIZE for s0 in GlueFreeBlocks()
+const UInt32 kExtraSize = (UNIT_SIZE * 3);
+const UInt32 kMaxMemBlockSize = 0xFFFFFFFF - kExtraSize;
+
struct MEM_BLK
{
UInt16 Stamp, NU;
- MEM_BLK *Next, *Prev;
- void InsertAt(MEM_BLK* p)
+ UInt32 Next, Prev;
+ void InsertAt(Byte *Base, UInt32 p)
{
- Next = (Prev = p)->Next;
- p->Next = Next->Prev = this;
+ Prev = p;
+ MEM_BLK *pp = (MEM_BLK *)(Base + p);
+ Next = pp->Next;
+ pp->Next = ((MEM_BLK *)(Base + Next))->Prev = (Byte *)this - Base;
}
- void Remove()
+ void Remove(Byte *Base)
{
- Prev->Next=Next;
- Next->Prev=Prev;
+ ((MEM_BLK *)(Base + Prev))->Next = Next;
+ ((MEM_BLK *)(Base + Next))->Prev = Prev;
}
-} _PACK_ATTR;
-#pragma pack()
+};
class CSubAllocator
{
UInt32 SubAllocatorSize;
Byte Indx2Units[N_INDEXES], Units2Indx[128], GlueCount;
- struct NODE { NODE* Next; } FreeList[N_INDEXES];
+ UInt32 FreeList[N_INDEXES];
+
+ Byte *Base;
+ Byte *HeapStart, *LoUnit, *HiUnit;
public:
- Byte* HeapStart, *pText, *UnitsStart, *LoUnit, *HiUnit;
+ Byte *pText, *UnitsStart;
CSubAllocator():
SubAllocatorSize(0),
GlueCount(0),
- pText(0),
- UnitsStart(0),
LoUnit(0),
- HiUnit(0)
+ HiUnit(0),
+ pText(0),
+ UnitsStart(0)
{
memset(Indx2Units, 0, sizeof(Indx2Units));
memset(FreeList, 0, sizeof(FreeList));
@@ -53,21 +61,28 @@ public:
StopSubAllocator();
};
+ void *GetPtr(UInt32 offset) const { return (offset == 0) ? 0 : (void *)(Base + offset); }
+ void *GetPtrNoCheck(UInt32 offset) const { return (void *)(Base + offset); }
+ UInt32 GetOffset(void *ptr) const { return (ptr == 0) ? 0 : (UInt32)((Byte *)ptr - Base); }
+ UInt32 GetOffsetNoCheck(void *ptr) const { return (UInt32)((Byte *)ptr - Base); }
+ MEM_BLK *GetBlk(UInt32 offset) const { return (MEM_BLK *)(Base + offset); }
+ UInt32 *GetNode(UInt32 offset) const { return (UInt32 *)(Base + offset); }
void InsertNode(void* p, int indx)
{
- ((NODE*) p)->Next = FreeList[indx].Next;
- FreeList[indx].Next = (NODE*)p;
+ *(UInt32 *)p = FreeList[indx];
+ FreeList[indx] = GetOffsetNoCheck(p);
}
void* RemoveNode(int indx)
{
- NODE* RetVal = FreeList[indx].Next;
- FreeList[indx].Next = RetVal->Next;
- return RetVal;
+ UInt32 offset = FreeList[indx];
+ UInt32 *p = GetNode(offset);
+ FreeList[indx] = *p;
+ return (void *)p;
}
- UINT U2B(int NU) { return 8 * NU + 4 * NU; }
+ UINT U2B(int NU) const { return (UINT)(NU) * UNIT_SIZE; }
void SplitBlock(void* pv, int oldIndx, int newIndx)
{
@@ -82,25 +97,22 @@ public:
InsertNode(p, Units2Indx[UDiff - 1]);
}
- UInt32 GetUsedMemory()
+ UInt32 GetUsedMemory() const
{
- UInt32 i, k, RetVal = SubAllocatorSize - (UInt32)(HiUnit - LoUnit) - (UInt32)(UnitsStart - pText);
- for (k = i = 0; i < N_INDEXES; i++, k = 0)
- {
- for (NODE* pn = FreeList + i;(pn = pn->Next) != NULL; k++)
- ;
- RetVal -= UNIT_SIZE*Indx2Units[i] * k;
- }
+ UInt32 RetVal = SubAllocatorSize - (UInt32)(HiUnit - LoUnit) - (UInt32)(UnitsStart - pText);
+ for (UInt32 i = 0; i < N_INDEXES; i++)
+ for (UInt32 pn = FreeList[i]; pn != 0; RetVal -= (UInt32)Indx2Units[i] * UNIT_SIZE)
+ pn = *GetNode(pn);
return (RetVal >> 2);
}
void StopSubAllocator()
{
- if ( SubAllocatorSize )
+ if (SubAllocatorSize != 0)
{
- BigFree(HeapStart);
+ BigFree(Base);
SubAllocatorSize = 0;
- HeapStart = 0;
+ Base = 0;
}
}
@@ -110,10 +122,13 @@ public:
return true;
StopSubAllocator();
if (size == 0)
- HeapStart = 0;
+ Base = 0;
else
- if ((HeapStart = (Byte *)::BigAlloc(size)) == 0)
+ {
+ if ((Base = (Byte *)::BigAlloc(size + kExtraSize)) == 0)
return false;
+ HeapStart = Base + UNIT_SIZE; // we need such code to support NULL;
+ }
SubAllocatorSize = size;
return true;
}
@@ -138,34 +153,52 @@ public:
void GlueFreeBlocks()
{
- MEM_BLK s0, *p, *p1;
- int i, k, sz;
+ UInt32 s0 = (UInt32)(HeapStart + SubAllocatorSize - Base);
+
+ // We need add exta MEM_BLK with Stamp=0
+ GetBlk(s0)->Stamp = 0;
+ s0 += UNIT_SIZE;
+ MEM_BLK *ps0 = GetBlk(s0);
+
+ UInt32 p;
+ int i;
if (LoUnit != HiUnit)
*LoUnit=0;
- for (i = 0, s0.Next = s0.Prev = &s0; i < N_INDEXES; i++)
- while ( FreeList[i].Next )
+ ps0->Next = ps0->Prev = s0;
+
+ for (i = 0; i < N_INDEXES; i++)
+ while (FreeList[i] != 0)
{
- p = (MEM_BLK*) RemoveNode(i);
- p->InsertAt(&s0);
- p->Stamp = 0xFFFF;
- p->NU = Indx2Units[i];
+ MEM_BLK *pp = (MEM_BLK *)RemoveNode(i);
+ pp->InsertAt(Base, s0);
+ pp->Stamp = 0xFFFF;
+ pp->NU = Indx2Units[i];
}
- for (p=s0.Next; p != &s0; p =p->Next)
- while ((p1 = p + p->NU)->Stamp == 0xFFFF && int(p->NU) + p1->NU < 0x10000)
+ for (p = ps0->Next; p != s0; p = GetBlk(p)->Next)
+ {
+ while (true)
{
- p1->Remove();
- p->NU += p1->NU;
+ MEM_BLK *pp = GetBlk(p);
+ MEM_BLK *pp1 = GetBlk(p + pp->NU * UNIT_SIZE);
+ if (pp1->Stamp != 0xFFFF || int(pp->NU) + pp1->NU >= 0x10000)
+ break;
+ pp1->Remove(Base);
+ pp->NU += pp1->NU;
}
- while ((p=s0.Next) != &s0)
+ }
+ while ((p = ps0->Next) != s0)
{
- for (p->Remove(), sz=p->NU; sz > 128; sz -= 128, p += 128)
- InsertNode(p, N_INDEXES - 1);
+ MEM_BLK *pp = GetBlk(p);
+ pp->Remove(Base);
+ int sz;
+ for (sz = pp->NU; sz > 128; sz -= 128, p += 128 * UNIT_SIZE)
+ InsertNode(Base + p, N_INDEXES - 1);
if (Indx2Units[i = Units2Indx[sz-1]] != sz)
{
- k = sz-Indx2Units[--i];
- InsertNode(p + (sz - k), k - 1);
+ int k = sz - Indx2Units[--i];
+ InsertNode(Base + p + (sz - k) * UNIT_SIZE, k - 1);
}
- InsertNode(p,i);
+ InsertNode(Base + p, i);
}
}
void* AllocUnitsRare(int indx)
@@ -174,7 +207,7 @@ public:
{
GlueCount = 255;
GlueFreeBlocks();
- if (FreeList[indx].Next)
+ if (FreeList[indx] != 0)
return RemoveNode(indx);
}
int i = indx;
@@ -186,7 +219,7 @@ public:
i = U2B(Indx2Units[indx]);
return (UnitsStart - pText > i) ? (UnitsStart -= i) : (NULL);
}
- } while (!FreeList[i].Next);
+ } while (FreeList[i] == 0);
void* RetVal = RemoveNode(i);
SplitBlock(RetVal, i, indx);
return RetVal;
@@ -195,7 +228,7 @@ public:
void* AllocUnits(int NU)
{
int indx = Units2Indx[NU - 1];
- if (FreeList[indx].Next)
+ if (FreeList[indx] != 0)
return RemoveNode(indx);
void* RetVal = LoUnit;
LoUnit += U2B(Indx2Units[indx]);
@@ -209,7 +242,7 @@ public:
{
if (HiUnit != LoUnit)
return (HiUnit -= UNIT_SIZE);
- if (FreeList->Next)
+ if (FreeList[0] != 0)
return RemoveNode(0);
return AllocUnitsRare(0);
}
@@ -233,7 +266,7 @@ public:
int i0 = Units2Indx[oldNU - 1], i1 = Units2Indx[newNU - 1];
if (i0 == i1)
return oldPtr;
- if ( FreeList[i1].Next )
+ if (FreeList[i1] != 0)
{
void* ptr = RemoveNode(i1);
memcpy(ptr, oldPtr, U2B(newNU));
diff --git a/7zip/Compress/PPMD/PPMDType.h b/7zip/Compress/PPMD/PPMDType.h
index 5a67ac84..5200fa54 100755
--- a/7zip/Compress/PPMD/PPMDType.h
+++ b/7zip/Compress/PPMD/PPMDType.h
@@ -13,12 +13,6 @@
const int kMaxOrderCompress = 32;
const int MAX_O = 255; /* maximum allowed model order */
-#if defined(__GNUC__)
-#define _PACK_ATTR __attribute__ ((packed))
-#else
-#define _PACK_ATTR
-#endif /* defined(__GNUC__) */
-
template <class T>
inline void _PPMD_SWAP(T& t1,T& t2) { T tmp = t1; t1 = t2; t2 = tmp; }
diff --git a/7zip/Compress/PPMD/makefile b/7zip/Compress/PPMD/makefile
index 9f12f423..2e687a70 100755
--- a/7zip/Compress/PPMD/makefile
+++ b/7zip/Compress/PPMD/makefile
@@ -16,6 +16,7 @@ COMMON_OBJS = \
7ZIP_COMMON_OBJS = \
$O\InBuffer.obj \
$O\OutBuffer.obj \
+ $O\StreamUtils.obj \
OBJS = \
diff --git a/7zip/Compress/Quantum/QuantumDecoder.cpp b/7zip/Compress/Quantum/QuantumDecoder.cpp
new file mode 100755
index 00000000..8dcd736a
--- /dev/null
+++ b/7zip/Compress/Quantum/QuantumDecoder.cpp
@@ -0,0 +1,174 @@
+// QuantumDecoder.cpp
+
+#include "StdAfx.h"
+
+#include "QuantumDecoder.h"
+#include "../../../Common/Defs.h"
+
+namespace NCompress {
+namespace NQuantum {
+
+const UInt32 kDictionarySizeMax = (1 << 21);
+
+const int kLenIdNeedInit = -2;
+
+void CDecoder::Init()
+{
+ m_Selector.Init(kNumSelectors);
+ for (unsigned int i = 0; i < kNumLitSelectors; i++)
+ m_Literals[i].Init(kNumLitSymbols);
+ unsigned int numItems = _numDictBits << 1;
+ m_PosSlot[0].Init(MyMin(numItems, kNumLen3PosSymbolsMax));
+ m_PosSlot[1].Init(MyMin(numItems, kNumLen4PosSymbolsMax));
+ m_PosSlot[2].Init(MyMin(numItems, kNumLen5PosSymbolsMax));
+ m_LenSlot.Init(kNumLenSymbols);
+}
+
+HRESULT CDecoder::CodeSpec(UInt32 curSize)
+{
+ if (_remainLen == kLenIdNeedInit)
+ {
+ if (!_keepHistory)
+ {
+ if (!_outWindowStream.Create(_dictionarySize))
+ return E_OUTOFMEMORY;
+ Init();
+ }
+ if (!_rangeDecoder.Create(1 << 20))
+ return E_OUTOFMEMORY;
+ _rangeDecoder.Init();
+ _remainLen = 0;
+ }
+ if (curSize == 0)
+ return S_OK;
+
+ while(_remainLen > 0 && curSize > 0)
+ {
+ _remainLen--;
+ Byte b = _outWindowStream.GetByte(_rep0);
+ _outWindowStream.PutByte(b);
+ curSize--;
+ }
+
+ while(curSize > 0)
+ {
+ if (_rangeDecoder.Stream.WasFinished())
+ return S_FALSE;
+
+ unsigned int selector = m_Selector.Decode(&_rangeDecoder);
+ if (selector < kNumLitSelectors)
+ {
+ Byte b = (Byte)((selector << (8 - kNumLitSelectorBits)) + m_Literals[selector].Decode(&_rangeDecoder));
+ _outWindowStream.PutByte(b);
+ curSize--;
+ }
+ else
+ {
+ selector -= kNumLitSelectors;
+ unsigned int len = selector + kMatchMinLen;
+ if (selector == 2)
+ {
+ unsigned int lenSlot = m_LenSlot.Decode(&_rangeDecoder);;
+ if (lenSlot >= kNumSimpleLenSlots)
+ {
+ lenSlot -= 2;
+ int numDirectBits = (int)(lenSlot >> 2);
+ len += ((4 | (lenSlot & 3)) << numDirectBits) - 2;
+ if (numDirectBits < 6)
+ len += _rangeDecoder.Stream.ReadBits(numDirectBits);
+ }
+ else
+ len += lenSlot;
+ }
+ UInt32 rep0 = m_PosSlot[selector].Decode(&_rangeDecoder);;
+ if (rep0 >= kNumSimplePosSlots)
+ {
+ int numDirectBits = (int)((rep0 >> 1) - 1);
+ rep0 = ((2 | (rep0 & 1)) << numDirectBits) + _rangeDecoder.Stream.ReadBits(numDirectBits);
+ }
+ unsigned int locLen = len;
+ if (len > curSize)
+ locLen = (unsigned int)curSize;
+ if (!_outWindowStream.CopyBlock(rep0, locLen))
+ return S_FALSE;
+ curSize -= locLen;
+ len -= locLen;
+ if (len != 0)
+ {
+ _remainLen = (int)len;
+ _rep0 = rep0;
+ break;
+ }
+ }
+ }
+ return _rangeDecoder.Stream.WasFinished() ? S_FALSE : S_OK;
+}
+
+HRESULT CDecoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ if (outSize == NULL)
+ return E_INVALIDARG;
+ UInt64 size = *outSize;
+ const UInt64 startSize = size;
+
+ SetInStream(inStream);
+ _outWindowStream.SetStream(outStream);
+ SetOutStreamSize(outSize);
+ CDecoderFlusher flusher(this);
+
+ const UInt64 start = _outWindowStream.GetProcessedSize();
+ while(true)
+ {
+ UInt32 curSize = 1 << 18;
+ UInt64 rem = size - (_outWindowStream.GetProcessedSize() - start);
+ if (curSize > rem)
+ curSize = (UInt32)rem;
+ if (curSize == 0)
+ break;
+ RINOK(CodeSpec(curSize));
+ if (progress != NULL)
+ {
+ UInt64 inSize = _rangeDecoder.GetProcessedSize();
+ UInt64 nowPos64 = _outWindowStream.GetProcessedSize() - start;
+ RINOK(progress->SetRatioInfo(&inSize, &nowPos64));
+ }
+ }
+ flusher.NeedFlush = false;
+ return 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::SetInStream(ISequentialInStream *inStream)
+{
+ _rangeDecoder.SetStream(inStream);
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::ReleaseInStream()
+{
+ _rangeDecoder.ReleaseStream();
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
+{
+ if (outSize == NULL)
+ return E_FAIL;
+ _remainLen = kLenIdNeedInit;
+ _outWindowStream.Init(_keepHistory);
+ return S_OK;
+}
+
+}}
diff --git a/7zip/Compress/Quantum/QuantumDecoder.h b/7zip/Compress/Quantum/QuantumDecoder.h
new file mode 100755
index 00000000..2574368f
--- /dev/null
+++ b/7zip/Compress/Quantum/QuantumDecoder.h
@@ -0,0 +1,287 @@
+// QuantumDecoder.h
+
+#ifndef __QUANTUM_DECODER_H
+#define __QUANTUM_DECODER_H
+
+#include "../../../Common/MyCom.h"
+
+#include "../../Common/InBuffer.h"
+#include "../../ICoder.h"
+#include "../LZ/LZOutWindow.h"
+
+namespace NCompress {
+namespace NQuantum {
+
+class CStreamBitDecoder
+{
+ UInt32 m_Value;
+ CInBuffer m_Stream;
+public:
+ bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }
+ void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream);}
+ void ReleaseStream() { m_Stream.ReleaseStream();}
+
+ void Finish() { m_Value = 0x10000; }
+
+ void Init()
+ {
+ m_Stream.Init();
+ m_Value = 0x10000;
+ }
+
+ UInt64 GetProcessedSize() const { return m_Stream.GetProcessedSize(); }
+ bool WasFinished() const { return m_Stream.WasFinished(); };
+
+ UInt32 ReadBit()
+ {
+ if (m_Value >= 0x10000)
+ m_Value = 0x100 | m_Stream.ReadByte();
+ UInt32 res = (m_Value >> 7) & 1;
+ m_Value <<= 1;
+ return res;
+ }
+
+ UInt32 ReadBits(int numBits) // numBits > 0
+ {
+ UInt32 res = 0;
+ do
+ res = (res << 1) | ReadBit();
+ while(--numBits != 0);
+ return res;
+ }
+};
+
+const int kNumLitSelectorBits = 2;
+const unsigned int kNumLitSelectors = (1 << kNumLitSelectorBits);
+const unsigned int kNumLitSymbols = 1 << (8 - kNumLitSelectorBits);
+const unsigned int kNumMatchSelectors = 3;
+const unsigned int kNumSelectors = kNumLitSelectors + kNumMatchSelectors;
+const unsigned int kNumLen3PosSymbolsMax = 24;
+const unsigned int kNumLen4PosSymbolsMax = 36;
+const unsigned int kNumLen5PosSymbolsMax = 42;
+const unsigned int kNumLenSymbols = 27;
+
+const unsigned int kNumSymbolsMax = kNumLitSymbols; // 64
+
+const unsigned int kMatchMinLen = 3;
+const unsigned int kNumSimplePosSlots = 4;
+const unsigned int kNumSimpleLenSlots = 6;
+
+namespace NRangeCoder {
+
+class CDecoder
+{
+ UInt32 Low;
+ UInt32 Range;
+ UInt32 Code;
+public:
+ CStreamBitDecoder Stream;
+ bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
+ void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); }
+ void ReleaseStream() { Stream.ReleaseStream(); }
+
+ void Init()
+ {
+ Stream.Init();
+ Low = 0;
+ Range = 0x10000;
+ Code = Stream.ReadBits(16);
+ }
+
+ void Finish()
+ {
+ // we need these extra two Bit_reads
+ Stream.ReadBit();
+ Stream.ReadBit();
+ Stream.Finish();
+ }
+
+ UInt64 GetProcessedSize() const { return Stream.GetProcessedSize(); }
+
+ 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;
+ while (true)
+ {
+ 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 UInt16 kUpdateStep = 8;
+const UInt16 kFreqSumMax = 3800;
+const UInt16 kReorderCountStart = 4;
+const UInt16 kReorderCount = 50;
+
+class CModelDecoder
+{
+ unsigned int NumItems;
+ unsigned int ReorderCount;
+ UInt16 Freqs[kNumSymbolsMax + 1];
+ Byte Values[kNumSymbolsMax];
+public:
+ void Init(unsigned int numItems)
+ {
+ NumItems = numItems;
+ ReorderCount = kReorderCountStart;
+ for(unsigned int i = 0; i < numItems; i++)
+ {
+ Freqs[i] = (UInt16)(numItems - i);
+ Values[i] = (Byte)i;
+ }
+ Freqs[numItems] = 0;
+ }
+
+ unsigned int Decode(CDecoder *rangeDecoder)
+ {
+ UInt32 threshold = rangeDecoder->GetThreshold(Freqs[0]);
+ unsigned int i;
+ for (i = 1; Freqs[i] > threshold; i++);
+ rangeDecoder->Decode(Freqs[i], Freqs[i - 1], Freqs[0]);
+ unsigned int res = Values[--i];
+ do
+ Freqs[i] += kUpdateStep;
+ while(i-- != 0);
+
+ if (Freqs[0] > kFreqSumMax)
+ {
+ if (--ReorderCount == 0)
+ {
+ ReorderCount = kReorderCount;
+ for(i = 0; i < NumItems; i++)
+ Freqs[i] = ((Freqs[i] - Freqs[i + 1]) + 1) >> 1;
+ for(i = 0; i < NumItems - 1; i++)
+ for(unsigned int j = i + 1; j < NumItems; j++)
+ if (Freqs[i] < Freqs[j])
+ {
+ UInt16 tmpFreq = Freqs[i];
+ Byte tmpVal = Values[i];
+ Freqs[i] = Freqs[j];
+ Values[i] = Values[j];
+ Freqs[j] = tmpFreq;
+ Values[j] = tmpVal;
+ }
+ do
+ Freqs[i] += Freqs[i + 1];
+ while(i-- != 0);
+ }
+ else
+ {
+ i = NumItems - 1;
+ do
+ {
+ Freqs[i] >>= 1;
+ if (Freqs[i] <= Freqs[i + 1])
+ Freqs[i] = Freqs[i + 1] + 1;
+ }
+ while(i-- != 0);
+ }
+ }
+ return res;
+ };
+};
+
+}
+
+class CDecoder:
+ public ICompressCoder,
+ public ICompressSetInStream,
+ public ICompressSetOutStreamSize,
+ public CMyUnknownImp
+{
+ CLZOutWindow _outWindowStream;
+ NRangeCoder::CDecoder _rangeDecoder;
+
+ ///////////////////
+ // State
+ UInt64 _outSize;
+ // UInt64 _nowPos64;
+ int _remainLen; // -1 means end of stream. // -2 means need Init
+ UInt32 _rep0;
+
+ int _numDictBits;
+ UInt32 _dictionarySize;
+
+ NRangeCoder::CModelDecoder m_Selector;
+ NRangeCoder::CModelDecoder m_Literals[kNumLitSelectors];
+ NRangeCoder::CModelDecoder m_PosSlot[kNumMatchSelectors];
+ NRangeCoder::CModelDecoder m_LenSlot;
+
+ bool _keepHistory;
+
+ void Init();
+ HRESULT CodeSpec(UInt32 size);
+public:
+ MY_UNKNOWN_IMP2(
+ ICompressSetInStream,
+ ICompressSetOutStreamSize)
+
+ void ReleaseStreams()
+ {
+ _outWindowStream.ReleaseStream();
+ ReleaseInStream();
+ }
+
+ class CDecoderFlusher
+ {
+ CDecoder *_decoder;
+ public:
+ bool NeedFlush;
+ CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {}
+ ~CDecoderFlusher()
+ {
+ if (NeedFlush)
+ _decoder->Flush();
+ _decoder->ReleaseStreams();
+ }
+ };
+
+ HRESULT Flush() { return _outWindowStream.Flush(); }
+
+ 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(SetInStream)(ISequentialInStream *inStream);
+ STDMETHOD(ReleaseInStream)();
+ STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
+
+ void SetParams(int numDictBits)
+ {
+ _numDictBits = numDictBits;
+ _dictionarySize = (UInt32)1 << numDictBits;
+ }
+ void SetKeepHistory(bool keepHistory)
+ {
+ _keepHistory = keepHistory;
+ }
+
+ CDecoder(): _keepHistory(false) {}
+ virtual ~CDecoder() {}
+};
+
+}}
+
+#endif
diff --git a/7zip/Compress/Rar20/DllExports.cpp b/7zip/Compress/Rar20/DllExports.cpp
new file mode 100755
index 00000000..599d71c3
--- /dev/null
+++ b/7zip/Compress/Rar20/DllExports.cpp
@@ -0,0 +1,66 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+
+#include "Rar20Decoder.h"
+
+// {23170F69-40C1-278B-0403-020000000000}
+DEFINE_GUID(CLSID_CCompressRar20Decoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ return TRUE;
+}
+
+STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
+{
+ COM_TRY_BEGIN
+ *outObject = 0;
+ if (*clsid != CLSID_CCompressRar20Decoder)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ if (*iid != IID_ICompressCoder)
+ return E_NOINTERFACE;
+ CMyComPtr<ICompressCoder> coder = (ICompressCoder *)new
+ NCompress::NRar20::CDecoder;
+ *outObject = coder.Detach();
+ COM_TRY_END
+ return S_OK;
+}
+
+STDAPI GetNumberOfMethods(UINT32 *numMethods)
+{
+ *numMethods = 1;
+ return S_OK;
+}
+
+STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
+{
+ if (index != 0)
+ return E_INVALIDARG;
+ ::VariantClear((tagVARIANT *)value);
+ switch(propID)
+ {
+ case NMethodPropID::kID:
+ {
+ const char id[] = { 0x04, 0x03, 0x02 };
+ if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NMethodPropID::kName:
+ if ((value->bstrVal = ::SysAllocString(L"Rar20")) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ case NMethodPropID::kDecoder:
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CCompressRar20Decoder, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ return S_OK;
+}
diff --git a/7zip/Compress/Rar20/Rar20Const.h b/7zip/Compress/Rar20/Rar20Const.h
new file mode 100755
index 00000000..6c5fecb6
--- /dev/null
+++ b/7zip/Compress/Rar20/Rar20Const.h
@@ -0,0 +1,65 @@
+// Rar20CoderConst.h
+// According to unRAR license,
+// this code may not be used to develop a
+// RAR (WinRAR) compatible archiver
+
+#ifndef __RAR20_CONST_H
+#define __RAR20_CONST_H
+
+#include "Rar20ExtConst.h"
+
+namespace NCompress {
+namespace NRar20 {
+
+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;
+
+}}
+
+#endif
diff --git a/7zip/Compress/Rar20/Rar20Decoder.cpp b/7zip/Compress/Rar20/Rar20Decoder.cpp
new file mode 100755
index 00000000..8da544f7
--- /dev/null
+++ b/7zip/Compress/Rar20/Rar20Decoder.cpp
@@ -0,0 +1,319 @@
+// Rar20Decoder.cpp
+// According to unRAR license,
+// this code may not be used to develop a
+// RAR (WinRAR) compatible archiver
+
+#include "StdAfx.h"
+
+#include "Rar20Decoder.h"
+#include "Rar20Const.h"
+
+namespace NCompress {
+namespace NRar20 {
+
+class CException
+{
+public:
+ enum ECauseType
+ {
+ kData
+ } Cause;
+ CException(ECauseType cause): Cause(cause) {}
+};
+
+static const char *kNumberErrorMessage = "Number error";
+
+static const UInt32 kHistorySize = 1 << 20;
+
+static const int kNumStats = 11;
+
+static const UInt32 kWindowReservSize = (1 << 22) + 256;
+
+CDecoder::CDecoder():
+ m_IsSolid(false)
+{
+}
+
+void CDecoder::InitStructures()
+{
+ m_Predictor.Init();
+ for(int i = 0; i < kNumRepDists; i++)
+ m_RepDists[i] = 0;
+ m_RepDistPtr = 0;
+ m_LastLength = 0;
+ memset(m_LastLevels, 0, kMaxTableSize);
+}
+
+#define RIF(x) { if (!(x)) return false; }
+
+bool CDecoder::ReadTables(void)
+{
+ Byte levelLevels[kLevelTableSize];
+ Byte newLevels[kMaxTableSize];
+ m_AudioMode = (m_InBitStream.ReadBits(1) == 1);
+
+ if (m_InBitStream.ReadBits(1) == 0)
+ memset(m_LastLevels, 0, kMaxTableSize);
+ int numLevels;
+ if (m_AudioMode)
+ {
+ m_NumChannels = m_InBitStream.ReadBits(2) + 1;
+ if (m_Predictor.CurrentChannel >= m_NumChannels)
+ m_Predictor.CurrentChannel = 0;
+ numLevels = m_NumChannels * kMMTableSize;
+ }
+ else
+ numLevels = kHeapTablesSizesSum;
+
+ int i;
+ for (i = 0; i < kLevelTableSize; i++)
+ levelLevels[i] = Byte(m_InBitStream.ReadBits(4));
+ RIF(m_LevelDecoder.SetCodeLengths(levelLevels));
+ i = 0;
+ while (i < numLevels)
+ {
+ UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
+ if (number < kTableDirectLevels)
+ {
+ newLevels[i] = Byte((number + m_LastLevels[i]) & kLevelMask);
+ i++;
+ }
+ else
+ {
+ if (number == kTableLevelRepNumber)
+ {
+ int t = m_InBitStream.ReadBits(2) + 3;
+ for (int reps = t; reps > 0 && i < numLevels ; reps--, i++)
+ newLevels[i] = newLevels[i - 1];
+ }
+ else
+ {
+ int num;
+ if (number == kTableLevel0Number)
+ num = m_InBitStream.ReadBits(3) + 3;
+ else if (number == kTableLevel0Number2)
+ num = m_InBitStream.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].SetCodeLengths(&newLevels[i * kMMTableSize]));
+ }
+ else
+ {
+ RIF(m_MainDecoder.SetCodeLengths(&newLevels[0]));
+ RIF(m_DistDecoder.SetCodeLengths(&newLevels[kMainTableSize]));
+ RIF(m_LenDecoder.SetCodeLengths(&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_Predictor.CurrentChannel].DecodeSymbol(&m_InBitStream);
+ if (symbol == 256)
+ return ReadTables();
+ if (symbol >= kMMTableSize)
+ return false;
+ }
+ else
+ {
+ UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
+ if (number == kReadTableNumber)
+ return ReadTables();
+ if (number >= kMainTableSize)
+ return false;
+ }
+ return true;
+}
+
+class CCoderReleaser
+{
+ CDecoder *m_Coder;
+public:
+ CCoderReleaser(CDecoder *coder): m_Coder(coder) {}
+ ~CCoderReleaser()
+ {
+ m_Coder->ReleaseStreams();
+ }
+};
+
+STDMETHODIMP 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;
+ }
+
+ while(pos < unPackSize)
+ {
+ if (m_AudioMode)
+ while(pos < unPackSize)
+ {
+ UInt32 symbol = m_MMDecoders[m_Predictor.CurrentChannel].DecodeSymbol(&m_InBitStream);
+ if (symbol == 256)
+ {
+ if (progress != 0)
+ {
+ UInt64 packSize = m_InBitStream.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&packSize, &pos));
+ }
+ if (!ReadTables())
+ return S_FALSE;
+ break;
+ }
+ if (symbol >= kMMTableSize)
+ return S_FALSE;
+ Byte byPredict = m_Predictor.Predict();
+ Byte byReal = byPredict - Byte(symbol);
+ m_Predictor.Update(byReal, byPredict);
+ m_OutWindowStream.PutByte(byReal);
+ if (++m_Predictor.CurrentChannel == m_NumChannels)
+ m_Predictor.CurrentChannel = 0;
+ pos++;
+ }
+ else
+ while(pos < unPackSize)
+ {
+ UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
+ UInt32 length, distance;
+ if (number < 256)
+ {
+ m_OutWindowStream.PutByte(Byte(number));
+ pos++;
+ continue;
+ }
+ else if (number >= kMatchNumber)
+ {
+ number -= kMatchNumber;
+ length = kNormalMatchMinLen + UInt32(kLenStart[number]) +
+ m_InBitStream.ReadBits(kLenDirectBits[number]);
+ number = m_DistDecoder.DecodeSymbol(&m_InBitStream);
+ if (number >= kDistTableSize)
+ return S_FALSE;
+ distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]);
+ if (distance >= kDistLimit3)
+ {
+ length += 2 - ((distance - kDistLimit4) >> 31);
+ // length++;
+ // if (distance >= kDistLimit4)
+ // length++;
+ }
+ }
+ else if (number == kRepBothNumber)
+ {
+ length = m_LastLength;
+ distance = m_RepDists[(m_RepDistPtr + 4 - 1) & 3];
+ }
+ else if (number < kLen2Number)
+ {
+ distance = m_RepDists[(m_RepDistPtr - (number - kRepNumber + 1)) & 3];
+ number = m_LenDecoder.DecodeSymbol(&m_InBitStream);
+ if (number >= kLenTableSize)
+ return S_FALSE;
+ length = 2 + kLenStart[number] + m_InBitStream.ReadBits(kLenDirectBits[number]);
+ if (distance >= kDistLimit2)
+ {
+ length++;
+ if (distance >= kDistLimit3)
+ {
+ length += 2 - ((distance - kDistLimit4) >> 31);
+ // length++;
+ // if (distance >= kDistLimit4)
+ // length++;
+ }
+ }
+ }
+ else if (number < kReadTableNumber)
+ {
+ number -= kLen2Number;
+ distance = kLen2DistStarts[number] +
+ m_InBitStream.ReadBits(kLen2DistDirectBits[number]);
+ length = 2;
+ }
+ else if (number == kReadTableNumber)
+ {
+ if (progress != 0)
+ {
+ UInt64 packSize = m_InBitStream.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&packSize, &pos));
+ }
+ if (!ReadTables())
+ return S_FALSE;
+ break;
+ }
+ else
+ return S_FALSE;
+ CopyBackBlockOp(distance, length);
+ pos += length;
+ }
+ }
+ if (pos > unPackSize)
+ throw CException(CException::kData);
+
+ 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 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] != 0);
+ return S_OK;
+}
+
+}}
diff --git a/7zip/Compress/Rar20/Rar20Decoder.h b/7zip/Compress/Rar20/Rar20Decoder.h
new file mode 100755
index 00000000..071b3635
--- /dev/null
+++ b/7zip/Compress/Rar20/Rar20Decoder.h
@@ -0,0 +1,95 @@
+// Rar20Decoder.h
+// According to unRAR license,
+// this code may not be used to develop a
+// RAR (WinRAR) compatible archiver
+
+#ifndef __RAR20_DECODER_H
+#define __RAR20_DECODER_H
+
+#include "../../../Common/MyCom.h"
+
+#include "../../ICoder.h"
+#include "../../Common/MSBFDecoder.h"
+#include "../../Common/InBuffer.h"
+
+#include "../LZ/LZOutWindow.h"
+#include "../Huffman/HuffmanDecoder.h"
+
+#include "Rar20Multimedia.h"
+#include "Rar20Const.h"
+
+namespace NCompress {
+namespace NRar20 {
+
+typedef NStream::NMSBF::CDecoder<CInBuffer> CBitDecoder;
+
+const int kNumHuffmanBits = 15;
+
+class CDecoder :
+ public ICompressCoder,
+ public ICompressSetDecoderProperties2,
+ public CMyUnknownImp
+{
+ CLZOutWindow m_OutWindowStream;
+ CBitDecoder m_InBitStream;
+ NHuffman::CDecoder<kNumHuffmanBits, kMainTableSize> m_MainDecoder;
+ NHuffman::CDecoder<kNumHuffmanBits, kDistTableSize> m_DistDecoder;
+ NHuffman::CDecoder<kNumHuffmanBits, kLenTableSize> m_LenDecoder;
+ NHuffman::CDecoder<kNumHuffmanBits, kMMTableSize> m_MMDecoders[NMultimedia::kNumChanelsMax];
+ NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder;
+
+ bool m_AudioMode;
+
+ NMultimedia::CPredictor m_Predictor;
+ int m_NumChannels;
+
+ UInt32 m_RepDists[kNumRepDists];
+ UInt32 m_RepDistPtr;
+
+ UInt32 m_LastLength;
+
+ Byte m_LastLevels[kMaxTableSize];
+
+ UInt64 m_PackSize;
+ bool m_IsSolid;
+
+ void InitStructures();
+ bool ReadTables();
+ bool ReadLastTables();
+ void CopyBackBlockOp(UInt32 aDistance, UInt32 aLength)
+ {
+ /*
+ if(m_Position <= aDistance)
+ throw CDecoderException(CDecoderException::kData);
+ */
+ m_RepDists[m_RepDistPtr++ & 3] = aDistance;
+ m_LastLength = aLength;
+ m_OutWindowStream.CopyBlock(aDistance, aLength);
+ }
+
+public:
+ CDecoder();
+
+ MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)
+
+ void ReleaseStreams()
+ {
+ m_OutWindowStream.ReleaseStream();
+ m_InBitStream.ReleaseStream();
+ }
+
+ 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);
+
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+
+};
+
+}}
+
+#endif
diff --git a/7zip/Compress/Rar20/Rar20ExtConst.h b/7zip/Compress/Rar20/Rar20ExtConst.h
new file mode 100755
index 00000000..b74bc0cf
--- /dev/null
+++ b/7zip/Compress/Rar20/Rar20ExtConst.h
@@ -0,0 +1,21 @@
+// Rar20ExtConst.h
+// According to unRAR license,
+// this code may not be used to develop a
+// RAR (WinRAR) compatible archiver
+
+#ifndef __RAR20_EXTCONST_H
+#define __RAR20_EXTCONST_H
+
+#include "../../../Common/Types.h"
+
+namespace NCompress {
+namespace NRar20 {
+
+const UInt32 kNumRepDists = 4;
+const UInt32 kDistTableSize = 48;
+
+const int kMMTableSize = 256 + 1;
+
+}}
+
+#endif
diff --git a/7zip/Compress/Rar20/Rar20Multimedia.cpp b/7zip/Compress/Rar20/Rar20Multimedia.cpp
new file mode 100755
index 00000000..3c0a13af
--- /dev/null
+++ b/7zip/Compress/Rar20/Rar20Multimedia.cpp
@@ -0,0 +1,128 @@
+// Rar20Multimedia.cpp
+// According to unRAR license,
+// this code may not be used to develop a
+// RAR (WinRAR) compatible archiver
+
+#include "StdAfx.h"
+
+#include "Rar20Multimedia.h"
+
+namespace NCompress {
+namespace NRar20 {
+namespace NMultimedia {
+
+void CAudioVariables::Init()
+{
+ memset(this, 0, sizeof(CAudioVariables));
+}
+
+void CPredictor::Init()
+{
+ for(int i = 0; i < kNumChanelsMax; i++)
+ m_AudioVariablesArray[i].Init();
+ m_ChannelDelta = 0;
+ CurrentChannel = 0;
+}
+
+Byte CPredictor::Predict()
+{
+ CAudioVariables *v = &m_AudioVariablesArray[CurrentChannel];
+ v->ByteCount++;
+ v->D4 = v->D3;
+ v->D3 = v->D2;
+ v->D2 = v->LastDelta-v->D1;
+ v->D1 = v->LastDelta;
+ int pCh = 8 * v->LastChar +
+ v->K1 * v->D1 +
+ v->K2 * v->D2 +
+ v->K3 * v->D3 +
+ v->K4 * v->D4 +
+ v->K5*m_ChannelDelta;
+ pCh = (pCh >> 3) & 0xFF;
+ return Byte(pCh);
+}
+
+void CPredictor::Update(Byte realValue, int predictedValue)
+{
+ struct CAudioVariables *v = &m_AudioVariablesArray[CurrentChannel];
+
+ int delta = predictedValue - realValue;
+ int i = ((signed char)delta) << 3;
+
+ v->Dif[0] += abs(i);
+ v->Dif[1] += abs(i - v->D1);
+ v->Dif[2] += abs(i + v->D1);
+ v->Dif[3] += abs(i - v->D2);
+ v->Dif[4] += abs(i + v->D2);
+ v->Dif[5] += abs(i - v->D3);
+ v->Dif[6] += abs(i + v->D3);
+ v->Dif[7] += abs(i - v->D4);
+ v->Dif[8] += abs(i + v->D4);
+ v->Dif[9] += abs(i - m_ChannelDelta);
+ v->Dif[10] += abs(i + m_ChannelDelta);
+
+ m_ChannelDelta = v->LastDelta = (signed char)(realValue - v->LastChar);
+ v->LastChar = realValue;
+
+ UInt32 numMinDif, minDif;
+ if ((v->ByteCount & 0x1F)==0)
+ {
+ minDif = v->Dif[0];
+ numMinDif = 0;
+ v->Dif[0] = 0;
+ for (i = 1; i < sizeof(v->Dif) / sizeof(v->Dif[0]); i++)
+ {
+ if (v->Dif[i] < minDif)
+ {
+ minDif = v->Dif[i];
+ numMinDif = i;
+ }
+ v->Dif[i] = 0;
+ }
+ switch(numMinDif)
+ {
+ case 1:
+ if (v->K1 >= -16)
+ v->K1--;
+ break;
+ case 2:
+ if (v->K1 < 16)
+ v->K1++;
+ break;
+ case 3:
+ if (v->K2 >= -16)
+ v->K2--;
+ break;
+ case 4:
+ if (v->K2 < 16)
+ v->K2++;
+ break;
+ case 5:
+ if (v->K3 >= -16)
+ v->K3--;
+ break;
+ case 6:
+ if (v->K3 < 16)
+ v->K3++;
+ break;
+ case 7:
+ if (v->K4 >= -16)
+ v->K4--;
+ break;
+ case 8:
+ if (v->K4 < 16)
+ v->K4++;
+ break;
+ case 9:
+ if (v->K5 >= -16)
+ v->K5--;
+ break;
+ case 10:
+ if (v->K5 < 16)
+ v->K5++;
+ break;
+ }
+ }
+}
+
+}}}
diff --git a/7zip/Compress/Rar20/Rar20Multimedia.h b/7zip/Compress/Rar20/Rar20Multimedia.h
new file mode 100755
index 00000000..7af86d07
--- /dev/null
+++ b/7zip/Compress/Rar20/Rar20Multimedia.h
@@ -0,0 +1,43 @@
+// Rar20Multimedia.h
+// According to unRAR license,
+// this code may not be used to develop a
+// RAR (WinRAR) compatible archiver
+
+#ifndef __RAR20_MULTIMEDIA_H
+#define __RAR20_MULTIMEDIA_H
+
+#include "../../../Common/Types.h"
+
+namespace NCompress {
+namespace NRar20 {
+namespace NMultimedia {
+
+struct CAudioVariables
+{
+ int K1,K2,K3,K4,K5;
+ int D1,D2,D3,D4;
+ int LastDelta;
+ UInt32 Dif[11];
+ UInt32 ByteCount;
+ int LastChar;
+
+ void Init();
+};
+
+const int kNumChanelsMax = 4;
+
+class CPredictor
+{
+ CAudioVariables m_AudioVariablesArray[kNumChanelsMax];
+ int m_ChannelDelta;
+public:
+ int CurrentChannel;
+
+ void Init();
+ Byte Predict();
+ void Update(Byte realValue, int predictedValue);
+};
+
+}}}
+
+#endif
diff --git a/7zip/Compress/Rar20/StdAfx.cpp b/7zip/Compress/Rar20/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/7zip/Compress/Rar20/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/7zip/Compress/Rar20/StdAfx.h b/7zip/Compress/Rar20/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/7zip/Compress/Rar20/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/7zip/Compress/Rar29/DllExports.cpp b/7zip/Compress/Rar29/DllExports.cpp
new file mode 100755
index 00000000..ed5197f8
--- /dev/null
+++ b/7zip/Compress/Rar29/DllExports.cpp
@@ -0,0 +1,105 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+
+#include "../Rar20/Rar20Decoder.h"
+#include "Rar29Decoder.h"
+
+// {23170F69-40C1-278B-0403-010000000000}
+DEFINE_GUID(CLSID_CCompressRar15Decoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+// {23170F69-40C1-278B-0403-020000000000}
+DEFINE_GUID(CLSID_CCompressRar20Decoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+// {23170F69-40C1-278B-0403-030000000000}
+DEFINE_GUID(CLSID_CCompressRar29Decoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ return TRUE;
+}
+
+STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
+{
+ COM_TRY_BEGIN
+ *outObject = 0;
+
+ int correctInterface = (*iid == IID_ICompressCoder);
+ CMyComPtr<ICompressCoder> coder;
+ if (*clsid == CLSID_CCompressRar15Decoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder = (ICompressCoder *)new NCompress::NRar15::CDecoder;
+ }
+ else if (*clsid == CLSID_CCompressRar20Decoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder = (ICompressCoder *)new NCompress::NRar20::CDecoder;
+ }
+ else if (*clsid == CLSID_CCompressRar29Decoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder = (ICompressCoder *)new NCompress::NRar29::CDecoder;
+ }
+ else
+ return CLASS_E_CLASSNOTAVAILABLE;
+ *outObject = coder.Detach();
+ COM_TRY_END
+ return S_OK;
+}
+
+struct CRarMethodItem
+{
+ char ID[3];
+ const wchar_t *UserName;
+ const GUID *Decoder;
+};
+
+static CRarMethodItem g_Methods[] =
+{
+ { { 0x04, 0x03, 0x01 }, L"Rar15", &CLSID_CCompressRar15Decoder },
+ { { 0x04, 0x03, 0x02 }, L"Rar20", &CLSID_CCompressRar20Decoder },
+ { { 0x04, 0x03, 0x03 }, L"Rar29", &CLSID_CCompressRar29Decoder }
+};
+
+STDAPI GetNumberOfMethods(UINT32 *numMethods)
+{
+ *numMethods = sizeof(g_Methods) / sizeof(g_Methods[1]);
+ return S_OK;
+}
+
+STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
+{
+ if (index > sizeof(g_Methods) / sizeof(g_Methods[1]))
+ return E_INVALIDARG;
+ VariantClear((tagVARIANT *)value);
+ const CRarMethodItem &method = g_Methods[index];
+ switch(propID)
+ {
+ case NMethodPropID::kID:
+ if ((value->bstrVal = ::SysAllocStringByteLen(method.ID,
+ sizeof(method.ID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ case NMethodPropID::kName:
+ if ((value->bstrVal = ::SysAllocString(method.UserName)) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ case NMethodPropID::kDecoder:
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)method.Decoder, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ return S_OK;
+}
diff --git a/7zip/Compress/Rar29/Original/archive.hpp b/7zip/Compress/Rar29/Original/archive.hpp
new file mode 100755
index 00000000..c076b5b7
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/archive.hpp
@@ -0,0 +1,128 @@
+#ifndef _RAR_ARCHIVE_
+#define _RAR_ARCHIVE_
+
+class Pack;
+
+enum {EN_LOCK=1,EN_VOL=2,EN_FIRSTVOL=4};
+
+class Archive:public File
+{
+ private:
+ bool IsSignature(byte *D);
+ void UpdateLatestTime(FileHeader *CurBlock);
+ void Protect(int RecSectors);
+ void ConvertNameCase(char *Name);
+ void ConvertNameCase(wchar *Name);
+ void ConvertUnknownHeader();
+ bool AddArcComment(char *NameToShow);
+ int ReadOldHeader();
+ void PrepareExtraTime(FileHeader *hd,EXTTIME_MODE etm,EXTTIME_MODE etc,EXTTIME_MODE eta,EXTTIME_MODE etarc,Array<byte> &TimeData);
+
+#if !defined(SHELL_EXT) && !defined(NOCRYPT)
+ CryptData HeadersCrypt;
+ byte HeadersSalt[SALT_SIZE];
+#endif
+#ifndef SHELL_EXT
+ ComprDataIO SubDataIO;
+ byte SubDataSalt[SALT_SIZE];
+#endif
+ RAROptions *Cmd,DummyCmd;
+
+ MarkHeader MarkHead;
+ OldMainHeader OldMhd;
+
+ int RecoverySectors;
+ Int64 RecoveryPos;
+
+ RarTime LatestTime;
+ int LastReadBlock;
+ int CurHeaderType;
+
+ bool SilentOpen;
+ public:
+ Archive(RAROptions *InitCmd=NULL);
+ bool IsArchive(bool EnableBroken);
+ int SearchBlock(int BlockType);
+ int SearchSubBlock(const char *Type);
+ int ReadBlock(int BlockType);
+ void WriteBlock(int BlockType,BaseBlock *wb=NULL);
+ int PrepareNamesToWrite(char *Name,wchar *NameW,char *DestName,byte *DestNameW);
+ void SetLhdSize();
+ int ReadHeader();
+ void CheckArc(bool EnableBroken);
+ void CheckOpen(char *Name,wchar *NameW=NULL);
+ bool WCheckOpen(char *Name,wchar *NameW=NULL);
+ bool TestLock(int Mode);
+ void MakeTemp();
+ void CopyMainHeader(Archive &Src,bool CopySFX=true,char *NameToDisplay=NULL);
+ bool ProcessToFileHead(Archive &Src,bool LastBlockAdded,
+ Pack *Pack=NULL,const char *SkipName=NULL);
+ void TmpToArc(Archive &Src);
+ void CloseNew(int AdjustRecovery,bool CloseVolume);
+ void WriteEndBlock(bool CloseVolume);
+ void CopyFileRecord(Archive &Src);
+ void CopyArchiveData(Archive &Src);
+ bool GetComment(Array<byte> &CmtData);
+ void ViewComment();
+ void ViewFileComment();
+ void SetLatestTime(RarTime *NewTime);
+ void SeekToNext();
+ bool CheckAccess();
+ bool IsArcDir();
+ bool IsArcLabel();
+ void ConvertAttributes();
+ int GetRecoverySize(bool Required);
+ void VolSubtractHeaderSize(int SubSize);
+ void AddSubData(byte *SrcData,int DataSize,File *SrcFile,char *Name,bool AllowSplit);
+ bool ReadSubData(Array<byte> *UnpData,File *DestFile);
+ int GetHeaderType() {return(CurHeaderType);};
+ int ReadCommentData(Array<byte> &CmtData);
+ void WriteCommentData(byte *Data,int DataSize,bool FileComment);
+ RAROptions* GetRAROptions() {return(Cmd);}
+ void SetSilentOpen(bool Mode) {SilentOpen=Mode;}
+
+ BaseBlock ShortBlock;
+ MainHeader NewMhd;
+ FileHeader NewLhd;
+ EndArcHeader EndArcHead;
+ SubBlockHeader SubBlockHead;
+ FileHeader SubHead;
+ CommentHeader CommHead;
+ ProtectHeader ProtectHead;
+ AVHeader AVHead;
+ SignHeader SignHead;
+ UnixOwnersHeader UOHead;
+ MacFInfoHeader MACHead;
+ EAHeader EAHead;
+ StreamHeader StreamHead;
+
+ Int64 CurBlockPos;
+ Int64 NextBlockPos;
+
+ bool OldFormat;
+ bool Solid;
+ bool Volume;
+ bool MainComment;
+ bool Locked;
+ bool Signed;
+ bool NotFirstVolume;
+ bool Protected;
+ bool Encrypted;
+ uint SFXSize;
+ bool BrokenFileHeader;
+
+ bool Splitting;
+
+ ushort HeaderCRC;
+
+ Int64 VolWrite;
+ Int64 AddingFilesSize;
+ uint AddingHeadersSize;
+
+ bool NewArchive;
+
+ char FirstVolumeName[NM];
+ wchar FirstVolumeNameW[NM];
+};
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/array.hpp b/7zip/Compress/Rar29/Original/array.hpp
new file mode 100755
index 00000000..3afec70c
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/array.hpp
@@ -0,0 +1,121 @@
+#ifndef _RAR_ARRAY_
+#define _RAR_ARRAY_
+
+extern ErrorHandler ErrHandler;
+
+template <class T> class Array
+{
+ private:
+ T *Buffer;
+ int BufSize;
+ int AllocSize;
+ public:
+ Array();
+ Array(int Size);
+ ~Array();
+ inline void CleanData();
+ inline T& operator [](int Item);
+ inline int Size();
+ void Add(int Items);
+ void Alloc(int Items);
+ void Reset();
+ void operator = (Array<T> &Src);
+ void Push(T Item);
+};
+
+template <class T> void Array<T>::CleanData()
+{
+ Buffer=NULL;
+ BufSize=0;
+ AllocSize=0;
+}
+
+
+template <class T> Array<T>::Array()
+{
+ CleanData();
+}
+
+
+template <class T> Array<T>::Array(int Size)
+{
+ Buffer=(T *)rarmalloc(sizeof(T)*Size);
+ if (Buffer==NULL && Size!=0)
+ ErrHandler.MemoryError();
+
+ AllocSize=BufSize=Size;
+}
+
+
+template <class T> Array<T>::~Array()
+{
+ if (Buffer!=NULL)
+ rarfree(Buffer);
+}
+
+
+template <class T> inline T& Array<T>::operator [](int Item)
+{
+ return(Buffer[Item]);
+}
+
+
+template <class T> inline int Array<T>::Size()
+{
+ return(BufSize);
+}
+
+
+template <class T> void Array<T>::Add(int Items)
+{
+ BufSize+=Items;
+ if (BufSize>AllocSize)
+ {
+ int Suggested=AllocSize+AllocSize/4+32;
+ int NewSize=Max(BufSize,Suggested);
+
+ Buffer=(T *)rarrealloc(Buffer,NewSize*sizeof(T));
+ if (Buffer==NULL)
+ ErrHandler.MemoryError();
+ AllocSize=NewSize;
+ }
+}
+
+
+template <class T> void Array<T>::Alloc(int Items)
+{
+ if (Items>AllocSize)
+ Add(Items-BufSize);
+ else
+ BufSize=Items;
+}
+
+
+template <class T> void Array<T>::Reset()
+{
+ if (Buffer!=NULL)
+ {
+ rarfree(Buffer);
+ Buffer=NULL;
+ }
+ BufSize=0;
+ AllocSize=0;
+}
+
+
+template <class T> void Array<T>::operator =(Array<T> &Src)
+{
+ Reset();
+ Alloc(Src.BufSize);
+ if (Src.BufSize!=0)
+ memcpy((void *)Buffer,(void *)Src.Buffer,Src.BufSize*sizeof(T));
+}
+
+
+template <class T> void Array<T>::Push(T Item)
+{
+ Add(1);
+ (*this)[Size()-1]=Item;
+}
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/cmddata.hpp b/7zip/Compress/Rar29/Original/cmddata.hpp
new file mode 100755
index 00000000..08b92c11
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/cmddata.hpp
@@ -0,0 +1,56 @@
+#ifndef _RAR_CMDDATA_
+#define _RAR_CMDDATA_
+
+#define DefaultStoreList "ace;arj;bz2;cab;gz;jpeg;jpg;lha;lzh;mp3;rar;zip;taz;tgz;z"
+
+class CommandData:public RAROptions
+{
+ private:
+ void ProcessSwitchesString(char *Str);
+ void ProcessSwitch(char *Switch);
+ void BadSwitch(char *Switch);
+ bool ExclCheckArgs(StringList *Args,char *CheckName,bool CheckFullPath,int MatchMode);
+ uint GetExclAttr(char *Str);
+
+ bool FileLists;
+ bool NoMoreSwitches;
+ bool TimeConverted;
+ bool BareOutput;
+ public:
+ CommandData();
+ ~CommandData();
+ void Init();
+ void Close();
+ void ParseArg(char *Arg,wchar *ArgW);
+ void ParseDone();
+ void ParseEnvVar();
+ void ReadConfig(int argc,char *argv[]);
+ bool IsConfigEnabled(int argc,char *argv[]);
+ void OutTitle();
+ void OutHelp();
+ bool IsSwitch(int Ch);
+ bool ExclCheck(char *CheckName,bool CheckFullPath);
+ bool StoreCheck(char *CheckName);
+ bool TimeCheck(RarTime &ft);
+ int IsProcessFile(FileHeader &NewLhd,bool *ExactMatch=NULL,int MatchType=MATCH_WILDSUBPATH);
+ void ProcessCommand();
+ void AddArcName(char *Name,wchar *NameW);
+ bool GetArcName(char *Name,wchar *NameW,int MaxSize);
+ bool CheckWinSize();
+
+ int GetRecoverySize(char *Str,int DefSize);
+
+ char Command[NM+16];
+ wchar CommandW[NM+16];
+
+ char ArcName[NM];
+ wchar ArcNameW[NM];
+
+ StringList *FileArgs;
+ StringList *ExclArgs;
+ StringList *InclArgs;
+ StringList *ArcNames;
+ StringList *StoreArgs;
+};
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/coder.cpp b/7zip/Compress/Rar29/Original/coder.cpp
new file mode 100755
index 00000000..cb6a8836
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/coder.cpp
@@ -0,0 +1,47 @@
+
+
+inline unsigned int RangeCoder::GetChar()
+{
+ return(UnpackRead->GetChar());
+}
+
+
+void RangeCoder::InitDecoder(Unpack *UnpackRead)
+{
+ RangeCoder::UnpackRead=UnpackRead;
+
+ low=code=0;
+ range=uint(-1);
+ for (int i=0;i < 4;i++)
+ code=(code << 8) | GetChar();
+}
+
+
+#define ARI_DEC_NORMALIZE(code,low,range,read) \
+{ \
+ while ((low^(low+range))<TOP || range<BOT && ((range=-low&(BOT-1)),1)) \
+ { \
+ code=(code << 8) | read->GetChar(); \
+ range <<= 8; \
+ low <<= 8; \
+ } \
+}
+
+
+inline int RangeCoder::GetCurrentCount()
+{
+ return (code-low)/(range /= SubRange.scale);
+}
+
+
+inline uint RangeCoder::GetCurrentShiftCount(uint SHIFT)
+{
+ return (code-low)/(range >>= SHIFT);
+}
+
+
+inline void RangeCoder::Decode()
+{
+ low += range*SubRange.LowCount;
+ range *= SubRange.HighCount-SubRange.LowCount;
+}
diff --git a/7zip/Compress/Rar29/Original/coder.hpp b/7zip/Compress/Rar29/Original/coder.hpp
new file mode 100755
index 00000000..f09f911c
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/coder.hpp
@@ -0,0 +1,24 @@
+/****************************************************************************
+ * Contents: 'Carryless rangecoder' by Dmitry Subbotin *
+ ****************************************************************************/
+
+const uint TOP=1 << 24, BOT=1 << 15;
+
+class RangeCoder
+{
+ public:
+ void InitDecoder(Unpack *UnpackRead);
+ inline int GetCurrentCount();
+ inline uint GetCurrentShiftCount(uint SHIFT);
+ inline void Decode();
+ inline void PutChar(unsigned int c);
+ inline unsigned int GetChar();
+
+ uint low, code, range;
+ struct SUBRANGE
+ {
+ uint LowCount, HighCount, scale;
+ } SubRange;
+
+ Unpack *UnpackRead;
+};
diff --git a/7zip/Compress/Rar29/Original/compress.hpp b/7zip/Compress/Rar29/Original/compress.hpp
new file mode 100755
index 00000000..2ba7b23e
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/compress.hpp
@@ -0,0 +1,36 @@
+#ifndef _RAR_COMPRESS_
+#define _RAR_COMPRESS_
+
+class ComprDataIO;
+class PackingFileTable;
+
+#define CODEBUFSIZE 0x4000
+#define MAXWINSIZE 0x400000
+#define MAXWINMASK (MAXWINSIZE-1)
+
+#define LOW_DIST_REP_COUNT 16
+
+#define NC 299 /* alphabet = {0, 1, 2, ..., NC - 1} */
+#define DC 60
+#define LDC 17
+#define RC 28
+#define HUFF_TABLE_SIZE (NC+DC+RC+LDC)
+#define BC 20
+
+#define NC20 298 /* alphabet = {0, 1, 2, ..., NC - 1} */
+#define DC20 48
+#define RC20 28
+#define BC20 19
+#define MC20 257
+
+enum {CODE_HUFFMAN,CODE_LZ,CODE_LZ2,CODE_REPEATLZ,CODE_CACHELZ,
+ CODE_STARTFILE,CODE_ENDFILE,CODE_VM,CODE_VMDATA};
+
+
+enum FilterType {
+ FILTER_NONE, FILTER_PPM /*dummy*/, FILTER_E8, FILTER_E8E9,
+ FILTER_UPCASETOLOW, FILTER_AUDIO, FILTER_RGB, FILTER_DELTA,
+ FILTER_ITANIUM, FILTER_E8E9V2
+};
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/consio.hpp b/7zip/Compress/Rar29/Original/consio.hpp
new file mode 100755
index 00000000..780ae7f3
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/consio.hpp
@@ -0,0 +1,42 @@
+#ifndef _RAR_CONSIO_
+#define _RAR_CONSIO_
+
+enum {ALARM_SOUND,ERROR_SOUND,QUESTION_SOUND};
+
+enum PASSWORD_TYPE {PASSWORD_GLOBAL,PASSWORD_FILE,PASSWORD_ARCHIVE};
+
+void InitConsoleOptions(MESSAGE_TYPE MsgStream,bool Sound);
+
+#ifndef SILENT
+void mprintf(const char *fmt,...);
+void eprintf(const char *fmt,...);
+void Alarm();
+void GetPasswordText(char *Str,int MaxLength);
+unsigned int GetKey();
+bool GetPassword(PASSWORD_TYPE Type,const char *FileName,char *Password,int MaxLength);
+int Ask(const char *AskStr);
+#endif
+
+int KbdAnsi(char *Addr,int Size);
+void OutComment(char *Comment,int Size);
+
+#ifdef SILENT
+#ifdef __GNUC__
+ #define mprintf(args...)
+ #define eprintf(args...)
+#else
+ inline void mprintf(const char *fmt,const char *a=NULL,const char *b=NULL) {}
+ inline void eprintf(const char *fmt,const char *a=NULL,const char *b=NULL) {}
+ inline void mprintf(const char *fmt,int b) {}
+ inline void eprintf(const char *fmt,int b) {}
+ inline void mprintf(const char *fmt,const char *a,int b) {}
+ inline void eprintf(const char *fmt,const char *a,int b) {}
+#endif
+inline void Alarm() {}
+inline void GetPasswordText(char *Str,int MaxLength) {}
+inline unsigned int GetKey() {return(0);}
+inline bool GetPassword(PASSWORD_TYPE Type,const char *FileName,char *Password,int MaxLength) {return(false);}
+inline int Ask(const char *AskStr) {return(0);}
+#endif
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/crc.cpp b/7zip/Compress/Rar29/Original/crc.cpp
new file mode 100755
index 00000000..c19f8595
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/crc.cpp
@@ -0,0 +1,61 @@
+#include "rar.hpp"
+
+uint CRCTab[256];
+
+void InitCRC()
+{
+ for (int I=0;I<256;I++)
+ {
+ uint C=I;
+ for (int J=0;J<8;J++)
+ C=(C & 1) ? (C>>1)^0xEDB88320L : (C>>1);
+ CRCTab[I]=C;
+ }
+}
+
+
+uint CRC(uint StartCRC,const void *Addr,uint Size)
+{
+ if (CRCTab[1]==0)
+ InitCRC();
+ byte *Data=(byte *)Addr;
+#if defined(LITTLE_ENDIAN) && defined(PRESENT_INT32)
+ while (Size>0 && ((long)Data & 7))
+ {
+ StartCRC=CRCTab[(byte)(StartCRC^Data[0])]^(StartCRC>>8);
+ Size--;
+ Data++;
+ }
+ while (Size>=8)
+ {
+ StartCRC^=*(uint32 *)Data;
+ StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8);
+ StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8);
+ StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8);
+ StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8);
+ StartCRC^=*(uint32 *)(Data+4);
+ StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8);
+ StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8);
+ StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8);
+ StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8);
+ Data+=8;
+ Size-=8;
+ }
+#endif
+ for (int I=0;I<Size;I++)
+ StartCRC=CRCTab[(byte)(StartCRC^Data[I])]^(StartCRC>>8);
+ return(StartCRC);
+}
+
+#ifndef SFX_MODULE
+ushort OldCRC(ushort StartCRC,const void *Addr,uint Size)
+{
+ byte *Data=(byte *)Addr;
+ for (int I=0;I<Size;I++)
+ {
+ StartCRC=(StartCRC+Data[I])&0xffff;
+ StartCRC=((StartCRC<<1)|(StartCRC>>15))&0xffff;
+ }
+ return(StartCRC);
+}
+#endif
diff --git a/7zip/Compress/Rar29/Original/crc.hpp b/7zip/Compress/Rar29/Original/crc.hpp
new file mode 100755
index 00000000..47ee7e23
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/crc.hpp
@@ -0,0 +1,10 @@
+#ifndef _RAR_CRC_
+#define _RAR_CRC_
+
+extern uint CRCTab[256];
+
+void InitCRC();
+uint CRC(uint StartCRC,const void *Addr,uint Size);
+ushort OldCRC(ushort StartCRC,const void *Addr,uint Size);
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/crypt.hpp b/7zip/Compress/Rar29/Original/crypt.hpp
new file mode 100755
index 00000000..809d76a5
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/crypt.hpp
@@ -0,0 +1,60 @@
+#ifndef _RAR_CRYPT_
+#define _RAR_CRYPT_
+
+enum { OLD_DECODE=0,OLD_ENCODE=1,NEW_CRYPT=2 };
+
+struct CryptKeyCacheItem
+{
+#ifndef _SFX_RTL_
+ CryptKeyCacheItem()
+ {
+ *Password=0;
+ }
+
+ ~CryptKeyCacheItem()
+ {
+ memset(AESKey,0,sizeof(AESKey));
+ memset(AESInit,0,sizeof(AESInit));
+ memset(Password,0,sizeof(Password));
+ }
+#endif
+ byte AESKey[16],AESInit[16];
+ char Password[MAXPASSWORD];
+ bool SaltPresent;
+ byte Salt[SALT_SIZE];
+};
+
+class CryptData
+{
+ private:
+ void Encode13(byte *Data,uint Count);
+ void Decode13(byte *Data,uint Count);
+ void Crypt15(byte *Data,uint Count);
+ void UpdKeys(byte *Buf);
+ void Swap(byte *Ch1,byte *Ch2);
+ void SetOldKeys(char *Password);
+
+ Rijndael rin;
+
+ byte SubstTable[256];
+ uint Key[4];
+ ushort OldKey[4];
+ byte PN1,PN2,PN3;
+
+ byte AESKey[16],AESInit[16];
+
+ static CryptKeyCacheItem Cache[4];
+ static int CachePos;
+ public:
+ void SetCryptKeys(char *Password,byte *Salt,bool Encrypt,bool OldOnly=false);
+ void SetAV15Encryption();
+ void SetCmt13Encryption();
+ void EncryptBlock20(byte *Buf);
+ void DecryptBlock20(byte *Buf);
+ void EncryptBlock(byte *Buf,int Size);
+ void DecryptBlock(byte *Buf,int Size);
+ void Crypt(byte *Data,uint Count,int Method);
+ static void SetSalt(byte *Salt,int SaltSize);
+};
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/encname.hpp b/7zip/Compress/Rar29/Original/encname.hpp
new file mode 100755
index 00000000..586f4216
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/encname.hpp
@@ -0,0 +1,20 @@
+#ifndef _RAR_ENCNAME_
+#define _RAR_ENCNAME_
+
+class EncodeFileName
+{
+ private:
+ void AddFlags(int Value);
+
+ byte *EncName;
+ byte Flags;
+ int FlagBits;
+ int FlagsPos;
+ int DestSize;
+ public:
+ EncodeFileName();
+ int Encode(char *Name,wchar *NameW,byte *EncName);
+ void Decode(char *Name,byte *EncName,int EncSize,wchar *NameW,int MaxDecSize);
+};
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/errhnd.cpp b/7zip/Compress/Rar29/Original/errhnd.cpp
new file mode 100755
index 00000000..6e162217
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/errhnd.cpp
@@ -0,0 +1,356 @@
+#include "rar.hpp"
+
+
+static bool UserBreak;
+
+ErrorHandler::ErrorHandler()
+{
+ Clean();
+}
+
+
+void ErrorHandler::Clean()
+{
+ ExitCode=SUCCESS;
+ ErrCount=0;
+ EnableBreak=true;
+ Silent=false;
+ DoShutdown=false;
+}
+
+
+void ErrorHandler::MemoryError()
+{
+ MemoryErrorMsg();
+ Throw(MEMORY_ERROR);
+}
+
+
+void ErrorHandler::OpenError(const char *FileName)
+{
+#ifndef SILENT
+ OpenErrorMsg(FileName);
+ Throw(OPEN_ERROR);
+#endif
+}
+
+
+void ErrorHandler::CloseError(const char *FileName)
+{
+#ifndef SILENT
+ if (!UserBreak)
+ {
+ ErrMsg(NULL,St(MErrFClose),FileName);
+ SysErrMsg();
+ }
+#endif
+#if !defined(SILENT) || defined(RARDLL)
+ Throw(FATAL_ERROR);
+#endif
+}
+
+
+void ErrorHandler::ReadError(const char *FileName)
+{
+#ifndef SILENT
+ ReadErrorMsg(NULL,FileName);
+#endif
+#if !defined(SILENT) || defined(RARDLL)
+ Throw(FATAL_ERROR);
+#endif
+}
+
+
+bool ErrorHandler::AskRepeatRead(const char *FileName)
+{
+#if !defined(SILENT) && !defined(SFX_MODULE) && !defined(_WIN_CE)
+ if (!Silent)
+ {
+ mprintf("\n");
+ Log(NULL,St(MErrRead),FileName);
+ return(Ask(St(MRetryAbort))==1);
+ }
+#endif
+ return(false);
+}
+
+
+void ErrorHandler::WriteError(const char *ArcName,const char *FileName)
+{
+#ifndef SILENT
+ WriteErrorMsg(ArcName,FileName);
+#endif
+#if !defined(SILENT) || defined(RARDLL)
+ Throw(WRITE_ERROR);
+#endif
+}
+
+
+#ifdef _WIN_32
+void ErrorHandler::WriteErrorFAT(const char *FileName)
+{
+#if !defined(SILENT) && !defined(SFX_MODULE)
+ SysErrMsg();
+ ErrMsg(NULL,St(MNTFSRequired),FileName);
+#endif
+#if !defined(SILENT) && !defined(SFX_MODULE) || defined(RARDLL)
+ Throw(WRITE_ERROR);
+#endif
+}
+#endif
+
+
+bool ErrorHandler::AskRepeatWrite(const char *FileName)
+{
+#if !defined(SILENT) && !defined(_WIN_CE)
+ if (!Silent)
+ {
+ mprintf("\n");
+ Log(NULL,St(MErrWrite),FileName);
+ return(Ask(St(MRetryAbort))==1);
+ }
+#endif
+ return(false);
+}
+
+
+void ErrorHandler::SeekError(const char *FileName)
+{
+#ifndef SILENT
+ if (!UserBreak)
+ {
+ ErrMsg(NULL,St(MErrSeek),FileName);
+ SysErrMsg();
+ }
+#endif
+#if !defined(SILENT) || defined(RARDLL)
+ Throw(FATAL_ERROR);
+#endif
+}
+
+
+void ErrorHandler::MemoryErrorMsg()
+{
+#ifndef SILENT
+ ErrMsg(NULL,St(MErrOutMem));
+#endif
+}
+
+
+void ErrorHandler::OpenErrorMsg(const char *FileName)
+{
+ OpenErrorMsg(NULL,FileName);
+}
+
+
+void ErrorHandler::OpenErrorMsg(const char *ArcName,const char *FileName)
+{
+#ifndef SILENT
+ Log(ArcName && *ArcName ? ArcName:NULL,St(MCannotOpen),FileName);
+ Alarm();
+ SysErrMsg();
+#endif
+}
+
+
+void ErrorHandler::CreateErrorMsg(const char *FileName)
+{
+ CreateErrorMsg(NULL,FileName);
+}
+
+
+void ErrorHandler::CreateErrorMsg(const char *ArcName,const char *FileName)
+{
+#ifndef SILENT
+ Log(ArcName && *ArcName ? ArcName:NULL,St(MCannotCreate),FileName);
+ Alarm();
+#if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE) && defined(MAXPATH)
+ if (GetLastError()==ERROR_PATH_NOT_FOUND)
+ {
+ int NameLength=strlen(FileName);
+ if (!IsFullPath(FileName))
+ {
+ char CurDir[NM];
+ GetCurrentDirectory(sizeof(CurDir),CurDir);
+ NameLength+=strlen(CurDir)+1;
+ }
+ if (NameLength>MAXPATH)
+ {
+ Log(ArcName && *ArcName ? ArcName:NULL,St(MMaxPathLimit),MAXPATH);
+ }
+ }
+#endif
+ SysErrMsg();
+#endif
+}
+
+
+void ErrorHandler::ReadErrorMsg(const char *ArcName,const char *FileName)
+{
+#ifndef SILENT
+ ErrMsg(ArcName,St(MErrRead),FileName);
+ SysErrMsg();
+#endif
+}
+
+
+void ErrorHandler::WriteErrorMsg(const char *ArcName,const char *FileName)
+{
+#ifndef SILENT
+ ErrMsg(ArcName,St(MErrWrite),FileName);
+ SysErrMsg();
+#endif
+}
+
+
+void ErrorHandler::Exit(int ExitCode)
+{
+#ifndef SFX_MODULE
+ Alarm();
+#endif
+ Throw(ExitCode);
+}
+
+
+#ifndef GUI
+void ErrorHandler::ErrMsg(const char *ArcName,const char *fmt,...)
+{
+ safebuf char Msg[NM+1024];
+ va_list argptr;
+ va_start(argptr,fmt);
+ vsprintf(Msg,fmt,argptr);
+ va_end(argptr);
+#ifdef _WIN_32
+ if (UserBreak)
+ Sleep(5000);
+#endif
+ Alarm();
+ if (*Msg)
+ {
+ Log(ArcName,"\n%s",Msg);
+ mprintf("\n%s\n",St(MProgAborted));
+ }
+}
+#endif
+
+
+void ErrorHandler::SetErrorCode(int Code)
+{
+ switch(Code)
+ {
+ case WARNING:
+ case USER_BREAK:
+ if (ExitCode==SUCCESS)
+ ExitCode=Code;
+ break;
+ case FATAL_ERROR:
+ if (ExitCode==SUCCESS || ExitCode==WARNING)
+ ExitCode=FATAL_ERROR;
+ break;
+ default:
+ ExitCode=Code;
+ break;
+ }
+ ErrCount++;
+}
+
+
+#if !defined(GUI) && !defined(_SFX_RTL_)
+#ifdef _WIN_32
+BOOL __stdcall ProcessSignal(DWORD SigType)
+#else
+#if defined(__sun)
+extern "C"
+#endif
+void _stdfunction ProcessSignal(int SigType)
+#endif
+{
+#ifdef _WIN_32
+ if (SigType==CTRL_LOGOFF_EVENT)
+ return(TRUE);
+#endif
+ UserBreak=true;
+ mprintf(St(MBreak));
+ for (int I=0;
+ // Igor Pavlov
+ // !File::RemoveCreated() &&
+ I<3;I++)
+ {
+#ifdef _WIN_32
+ Sleep(100);
+#endif
+ }
+#if defined(USE_RC) && !defined(SFX_MODULE) && !defined(_WIN_CE)
+ ExtRes.UnloadDLL();
+#endif
+ exit(USER_BREAK);
+#ifdef _WIN_32
+ return(TRUE);
+#endif
+}
+#endif
+
+
+void ErrorHandler::SetSignalHandlers(bool Enable)
+{
+ EnableBreak=Enable;
+#if !defined(GUI) && !defined(_SFX_RTL_)
+#ifdef _WIN_32
+ SetConsoleCtrlHandler(Enable ? ProcessSignal:NULL,TRUE);
+// signal(SIGBREAK,Enable ? ProcessSignal:SIG_IGN);
+#else
+ signal(SIGINT,Enable ? ProcessSignal:SIG_IGN);
+ signal(SIGTERM,Enable ? ProcessSignal:SIG_IGN);
+#endif
+#endif
+}
+
+
+void ErrorHandler::Throw(int Code)
+{
+ if (Code==USER_BREAK && !EnableBreak)
+ return;
+ ErrHandler.SetErrorCode(Code);
+#ifdef ALLOW_EXCEPTIONS
+ throw Code;
+#else
+ // Igor Pavlov
+ // File::RemoveCreated();
+ exit(Code);
+#endif
+}
+
+
+void ErrorHandler::SysErrMsg()
+{
+#if defined(_WIN_32) && !defined(SFX_MODULE) && !defined(SILENT)
+ #define STRCHR strchr
+ #define ERRCHAR char
+ ERRCHAR *lpMsgBuf=NULL;
+ int ErrType=GetLastError();
+ if (ErrType!=0 && FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,ErrType,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR)&lpMsgBuf,0,NULL))
+ {
+ ERRCHAR *CurMsg=lpMsgBuf;
+ while (CurMsg!=NULL)
+ {
+ while (*CurMsg=='\r' || *CurMsg=='\n')
+ CurMsg++;
+ if (*CurMsg==0)
+ break;
+ ERRCHAR *EndMsg=STRCHR(CurMsg,'\r');
+ if (EndMsg==NULL)
+ EndMsg=STRCHR(CurMsg,'\n');
+ if (EndMsg!=NULL)
+ {
+ *EndMsg=0;
+ EndMsg++;
+ }
+ Log(NULL,"\n%s",CurMsg);
+ CurMsg=EndMsg;
+ }
+ }
+ LocalFree( lpMsgBuf );
+#endif
+}
diff --git a/7zip/Compress/Rar29/Original/errhnd.hpp b/7zip/Compress/Rar29/Original/errhnd.hpp
new file mode 100755
index 00000000..9e276222
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/errhnd.hpp
@@ -0,0 +1,61 @@
+#ifndef _RAR_ERRHANDLER_
+#define _RAR_ERRHANDLER_
+
+#if (defined(GUI) || !defined(_WIN_32)) && !defined(SFX_MODULE) && !defined(_WIN_CE) || defined(RARDLL)
+#define ALLOW_EXCEPTIONS
+#endif
+
+
+
+#define rarmalloc malloc
+#define rarcalloc calloc
+#define rarrealloc realloc
+#define rarfree free
+#define rarstrdup strdup
+
+
+
+enum { SUCCESS,WARNING,FATAL_ERROR,CRC_ERROR,LOCK_ERROR,WRITE_ERROR,
+ OPEN_ERROR,USER_ERROR,MEMORY_ERROR,CREATE_ERROR,USER_BREAK=255};
+
+class ErrorHandler
+{
+ private:
+ void ErrMsg(const char *ArcName,const char *fmt,...);
+
+ int ExitCode;
+ int ErrCount;
+ bool EnableBreak;
+ bool Silent;
+ bool DoShutdown;
+ public:
+ ErrorHandler();
+ void Clean();
+ void MemoryError();
+ void OpenError(const char *FileName);
+ void CloseError(const char *FileName);
+ void ReadError(const char *FileName);
+ bool AskRepeatRead(const char *FileName);
+ void WriteError(const char *ArcName,const char *FileName);
+ void WriteErrorFAT(const char *FileName);
+ bool AskRepeatWrite(const char *FileName);
+ void SeekError(const char *FileName);
+ void MemoryErrorMsg();
+ void OpenErrorMsg(const char *FileName);
+ void OpenErrorMsg(const char *ArcName,const char *FileName);
+ void CreateErrorMsg(const char *FileName);
+ void CreateErrorMsg(const char *ArcName,const char *FileName);
+ void ReadErrorMsg(const char *ArcName,const char *FileName);
+ void WriteErrorMsg(const char *ArcName,const char *FileName);
+ void Exit(int ExitCode);
+ void SetErrorCode(int Code);
+ int GetErrorCode() {return(ExitCode);}
+ int GetErrorCount() {return(ErrCount);}
+ void SetSignalHandlers(bool Enable);
+ void Throw(int Code);
+ void SetSilent(bool Mode) {Silent=Mode;};
+ void SetShutdown(bool Mode) {DoShutdown=Mode;};
+ void SysErrMsg();
+};
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/extinfo.hpp b/7zip/Compress/Rar29/Original/extinfo.hpp
new file mode 100755
index 00000000..db7cea53
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/extinfo.hpp
@@ -0,0 +1,8 @@
+#ifndef _RAR_EXTINFO_
+#define _RAR_EXTINFO_
+
+
+void SetExtraInfo(CommandData *Cmd,Archive &Arc,char *Name,wchar *NameW);
+void SetExtraInfoNew(CommandData *Cmd,Archive &Arc,char *Name,wchar *NameW);
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/extract.hpp b/7zip/Compress/Rar29/Original/extract.hpp
new file mode 100755
index 00000000..b78c988d
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/extract.hpp
@@ -0,0 +1,40 @@
+#ifndef _RAR_EXTRACT_
+#define _RAR_EXTRACT_
+
+enum EXTRACT_ARC_CODE {EXTRACT_ARC_NEXT,EXTRACT_ARC_REPEAT};
+
+class CmdExtract
+{
+ private:
+ ComprDataIO DataIO;
+ Unpack *Unp;
+ long TotalFileCount;
+
+ long FileCount;
+ long MatchedArgs;
+ bool FirstFile;
+ bool AllMatchesExact;
+ bool ReconstructDone;
+
+ char ArcName[NM];
+ wchar ArcNameW[NM];
+
+ char Password[MAXPASSWORD];
+ bool PasswordAll;
+ bool PrevExtracted;
+ bool SignatureFound;
+ char DestFileName[NM];
+ wchar DestFileNameW[NM];
+ bool PasswordCancelled;
+ public:
+ CmdExtract();
+ ~CmdExtract();
+ void DoExtract(CommandData *Cmd);
+ void ExtractArchiveInit(CommandData *Cmd,Archive &Arc);
+ EXTRACT_ARC_CODE ExtractArchive(CommandData *Cmd);
+ bool ExtractCurrentFile(CommandData *Cmd,Archive &Arc,int HeaderSize,
+ bool &Repeat);
+ static void UnstoreFile(ComprDataIO &DataIO,Int64 DestUnpSize);
+};
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/filcreat.hpp b/7zip/Compress/Rar29/Original/filcreat.hpp
new file mode 100755
index 00000000..fa1fddd0
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/filcreat.hpp
@@ -0,0 +1,12 @@
+#ifndef _RAR_FILECREATE_
+#define _RAR_FILECREATE_
+
+bool FileCreate(RAROptions *Cmd,File *NewFile,char *Name,wchar *NameW,
+ OVERWRITE_MODE Mode,bool *UserReject,Int64 FileSize=INT64ERR,
+ uint FileTime=0);
+
+#if defined(_WIN_32) && !defined(_WIN_CE)
+bool UpdateExistingShortName(char *Name,wchar *NameW);
+#endif
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/file.hpp b/7zip/Compress/Rar29/Original/file.hpp
new file mode 100755
index 00000000..afa9529c
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/file.hpp
@@ -0,0 +1,100 @@
+#ifndef _RAR_FILE_
+#define _RAR_FILE_
+
+#ifdef _WIN_32
+typedef HANDLE FileHandle;
+#define BAD_HANDLE INVALID_HANDLE_VALUE
+#else
+typedef FILE* FileHandle;
+#define BAD_HANDLE NULL
+#endif
+
+class RAROptions;
+
+enum FILE_HANDLETYPE {FILE_HANDLENORMAL,FILE_HANDLESTD,FILE_HANDLEERR};
+
+enum FILE_ERRORTYPE {FILE_SUCCESS,FILE_NOTFOUND,FILE_READERROR};
+
+struct FileStat
+{
+ uint FileAttr;
+ uint FileTime;
+ Int64 FileSize;
+ bool IsDir;
+};
+
+
+class File
+{
+ private:
+ void AddFileToList(FileHandle hFile);
+
+ FileHandle hFile;
+ bool LastWrite;
+ FILE_HANDLETYPE HandleType;
+ bool SkipClose;
+ bool IgnoreReadErrors;
+ bool NewFile;
+ bool AllowDelete;
+ bool AllowExceptions;
+#ifdef _WIN_32
+ bool NoSequentialRead;
+#endif
+ protected:
+ bool OpenShared;
+ public:
+ char FileName[NM];
+ wchar FileNameW[NM];
+
+ FILE_ERRORTYPE ErrorType;
+
+ uint CloseCount;
+ public:
+ File();
+ virtual ~File();
+ void operator = (File &SrcFile);
+ bool Open(const char *Name,const wchar *NameW=NULL,bool OpenShared=false,bool Update=false);
+ void TOpen(const char *Name,const wchar *NameW=NULL);
+ bool WOpen(const char *Name,const wchar *NameW=NULL);
+ bool Create(const char *Name,const wchar *NameW=NULL);
+ void TCreate(const char *Name,const wchar *NameW=NULL);
+ bool WCreate(const char *Name,const wchar *NameW=NULL);
+ bool Close();
+ void Flush();
+ bool Delete();
+ bool Rename(const char *NewName);
+ void Write(const void *Data,int Size);
+ int Read(void *Data,int Size);
+ int DirectRead(void *Data,int Size);
+ void Seek(Int64 Offset,int Method);
+ bool RawSeek(Int64 Offset,int Method);
+ Int64 Tell();
+ void Prealloc(Int64 Size);
+ byte GetByte();
+ void PutByte(byte Byte);
+ bool Truncate();
+ void SetOpenFileTime(RarTime *ftm,RarTime *ftc=NULL,RarTime *fta=NULL);
+ void SetCloseFileTime(RarTime *ftm,RarTime *fta=NULL);
+ static void SetCloseFileTimeByName(const char *Name,RarTime *ftm,RarTime *fta);
+ void SetOpenFileStat(RarTime *ftm,RarTime *ftc,RarTime *fta);
+ void SetCloseFileStat(RarTime *ftm,RarTime *fta,uint FileAttr);
+ void GetOpenFileTime(RarTime *ft);
+ bool IsOpened() {return(hFile!=BAD_HANDLE);};
+ Int64 FileLength();
+ void SetHandleType(FILE_HANDLETYPE Type);
+ FILE_HANDLETYPE GetHandleType() {return(HandleType);};
+ bool IsDevice();
+ void fprintf(const char *fmt,...);
+ static bool RemoveCreated();
+ FileHandle GetHandle() {return(hFile);};
+ void SetIgnoreReadErrors(bool Mode) {IgnoreReadErrors=Mode;};
+ char *GetName() {return(FileName);}
+ long Copy(File &Dest,Int64 Length=INT64ERR);
+ void SetAllowDelete(bool Allow) {AllowDelete=Allow;}
+ void SetExceptions(bool Allow) {AllowExceptions=Allow;}
+#ifdef _WIN_32
+ void RemoveSequentialFlag() {NoSequentialRead=true;}
+#endif
+};
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/filefn.hpp b/7zip/Compress/Rar29/Original/filefn.hpp
new file mode 100755
index 00000000..3ad31b5e
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/filefn.hpp
@@ -0,0 +1,39 @@
+#ifndef _RAR_FILEFN_
+#define _RAR_FILEFN_
+
+enum MKDIR_CODE {MKDIR_SUCCESS,MKDIR_ERROR,MKDIR_BADPATH};
+
+MKDIR_CODE MakeDir(const char *Name,const wchar *NameW,uint Attr);
+void CreatePath(const char *Path,const wchar *PathW,bool SkipLastName);
+void SetDirTime(const char *Name,RarTime *ftm,RarTime *ftc,RarTime *fta);
+bool IsRemovable(const char *Name);
+Int64 GetFreeDisk(const char *Name);
+bool FileExist(const char *Name,const wchar *NameW=NULL);
+bool WildFileExist(const char *Name,const wchar *NameW=NULL);
+bool IsDir(uint Attr);
+bool IsUnreadable(uint Attr);
+bool IsLabel(uint Attr);
+bool IsLink(uint Attr);
+void SetSFXMode(const char *FileName);
+void EraseDiskContents(const char *FileName);
+bool IsDeleteAllowed(uint FileAttr);
+void PrepareToDelete(const char *Name,const wchar *NameW=NULL);
+uint GetFileAttr(const char *Name,const wchar *NameW=NULL);
+bool SetFileAttr(const char *Name,const wchar *NameW,uint Attr);
+void ConvertNameToFull(const char *Src,char *Dest);
+void ConvertNameToFull(const wchar *Src,wchar *Dest);
+char* MkTemp(char *Name);
+
+
+uint CalcFileCRC(File *SrcFile,Int64 Size=INT64ERR);
+bool RenameFile(const char *SrcName,const wchar *SrcNameW,const char *DestName,const wchar *DestNameW);
+bool DelFile(const char *Name);
+bool DelFile(const char *Name,const wchar *NameW);
+bool DelDir(const char *Name);
+bool DelDir(const char *Name,const wchar *NameW);
+
+#if defined(_WIN_32) && !defined(_WIN_CE)
+bool SetFileCompression(char *Name,wchar *NameW,bool State);
+#endif
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/filestr.hpp b/7zip/Compress/Rar29/Original/filestr.hpp
new file mode 100755
index 00000000..b2bcbe0e
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/filestr.hpp
@@ -0,0 +1,8 @@
+#ifndef _RAR_FILESTR_
+#define _RAR_FILESTR_
+
+bool ReadTextFile(char *Name,StringList *List,bool Config,
+ bool AbortOnError=false,bool ConvertToAnsi=false,
+ bool Unquote=false,bool SkipComments=false);
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/find.hpp b/7zip/Compress/Rar29/Original/find.hpp
new file mode 100755
index 00000000..81548199
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/find.hpp
@@ -0,0 +1,48 @@
+#ifndef _RAR_FINDDATA_
+#define _RAR_FINDDATA_
+
+struct FindData
+{
+ char Name[NM];
+ wchar NameW[NM];
+ Int64 Size;
+ uint FileAttr;
+ uint FileTime;
+ bool IsDir;
+ RarTime mtime;
+ RarTime ctime;
+ RarTime atime;
+#ifdef _WIN_32
+ char ShortName[NM];
+ FILETIME ftCreationTime;
+ FILETIME ftLastAccessTime;
+ FILETIME ftLastWriteTime;
+#endif
+ bool Error;
+};
+
+class FindFile
+{
+ private:
+#ifdef _WIN_32
+ static HANDLE Win32Find(HANDLE hFind,const char *Mask,const wchar *MaskW,struct FindData *fd);
+#endif
+
+ char FindMask[NM];
+ wchar FindMaskW[NM];
+ int FirstCall;
+#ifdef _WIN_32
+ HANDLE hFind;
+#else
+ DIR *dirp;
+#endif
+ public:
+ FindFile();
+ ~FindFile();
+ void SetMask(const char *FindMask);
+ void SetMaskW(const wchar *FindMaskW);
+ bool Next(struct FindData *fd,bool GetSymLink=false);
+ static bool FastFind(const char *FindMask,const wchar *FindMaskW,struct FindData *fd,bool GetSymLink=false);
+};
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/getbits.cpp b/7zip/Compress/Rar29/Original/getbits.cpp
new file mode 100755
index 00000000..71ecfc87
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/getbits.cpp
@@ -0,0 +1,24 @@
+#include "rar.hpp"
+
+BitInput::BitInput()
+{
+ InBuf=new byte[MAX_SIZE];
+}
+
+
+BitInput::~BitInput()
+{
+ delete[] InBuf;
+}
+
+
+void BitInput::faddbits(int Bits)
+{
+ addbits(Bits);
+}
+
+
+unsigned int BitInput::fgetbits()
+{
+ return(getbits());
+}
diff --git a/7zip/Compress/Rar29/Original/getbits.hpp b/7zip/Compress/Rar29/Original/getbits.hpp
new file mode 100755
index 00000000..8819f53a
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/getbits.hpp
@@ -0,0 +1,37 @@
+#ifndef _RAR_GETBITS_
+#define _RAR_GETBITS_
+
+class BitInput
+{
+ public:
+ enum BufferSize {MAX_SIZE=0x8000};
+ protected:
+ int InAddr,InBit;
+ public:
+ BitInput();
+ ~BitInput();
+
+ byte *InBuf;
+
+ void InitBitInput()
+ {
+ InAddr=InBit=0;
+ }
+ void addbits(int Bits)
+ {
+ Bits+=InBit;
+ InAddr+=Bits>>3;
+ InBit=Bits&7;
+ }
+ unsigned int getbits()
+ {
+ unsigned int BitField=(uint)InBuf[InAddr] << 16;
+ BitField|=(uint)InBuf[InAddr+1] << 8;
+ BitField|=(uint)InBuf[InAddr+2];
+ BitField >>= (8-InBit);
+ return(BitField & 0xffff);
+ }
+ void faddbits(int Bits);
+ unsigned int fgetbits();
+};
+#endif
diff --git a/7zip/Compress/Rar29/Original/global.hpp b/7zip/Compress/Rar29/Original/global.hpp
new file mode 100755
index 00000000..35c6cf91
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/global.hpp
@@ -0,0 +1,14 @@
+#ifndef _RAR_GLOBAL_
+#define _RAR_GLOBAL_
+
+#ifdef INCLUDEGLOBAL
+ #define EXTVAR
+#else
+ #define EXTVAR extern
+#endif
+
+EXTVAR ErrorHandler ErrHandler;
+
+
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/headers.hpp b/7zip/Compress/Rar29/Original/headers.hpp
new file mode 100755
index 00000000..f719a7ec
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/headers.hpp
@@ -0,0 +1,304 @@
+#ifndef _RAR_HEADERS_
+#define _RAR_HEADERS_
+
+#define SIZEOF_MARKHEAD 7
+#define SIZEOF_OLDMHD 7
+#define SIZEOF_NEWMHD 13
+#define SIZEOF_OLDLHD 21
+#define SIZEOF_NEWLHD 32
+#define SIZEOF_SHORTBLOCKHEAD 7
+#define SIZEOF_LONGBLOCKHEAD 11
+#define SIZEOF_SUBBLOCKHEAD 14
+#define SIZEOF_COMMHEAD 13
+#define SIZEOF_PROTECTHEAD 26
+#define SIZEOF_AVHEAD 14
+#define SIZEOF_SIGNHEAD 15
+#define SIZEOF_UOHEAD 18
+#define SIZEOF_MACHEAD 22
+#define SIZEOF_EAHEAD 24
+#define SIZEOF_BEEAHEAD 24
+#define SIZEOF_STREAMHEAD 26
+
+#define PACK_VER 29
+#define PACK_CRYPT_VER 29
+#define UNP_VER 29
+#define CRYPT_VER 29
+#define AV_VER 20
+#define PROTECT_VER 20
+
+#define MHD_VOLUME 0x0001
+#define MHD_COMMENT 0x0002
+#define MHD_LOCK 0x0004
+#define MHD_SOLID 0x0008
+#define MHD_PACK_COMMENT 0x0010
+#define MHD_NEWNUMBERING 0x0010
+#define MHD_AV 0x0020
+#define MHD_PROTECT 0x0040
+#define MHD_PASSWORD 0x0080
+#define MHD_FIRSTVOLUME 0x0100
+
+#define LHD_SPLIT_BEFORE 0x0001
+#define LHD_SPLIT_AFTER 0x0002
+#define LHD_PASSWORD 0x0004
+#define LHD_COMMENT 0x0008
+#define LHD_SOLID 0x0010
+
+#define LHD_WINDOWMASK 0x00e0
+#define LHD_WINDOW64 0x0000
+#define LHD_WINDOW128 0x0020
+#define LHD_WINDOW256 0x0040
+#define LHD_WINDOW512 0x0060
+#define LHD_WINDOW1024 0x0080
+#define LHD_WINDOW2048 0x00a0
+#define LHD_WINDOW4096 0x00c0
+#define LHD_DIRECTORY 0x00e0
+
+#define LHD_LARGE 0x0100
+#define LHD_UNICODE 0x0200
+#define LHD_SALT 0x0400
+#define LHD_VERSION 0x0800
+#define LHD_EXTTIME 0x1000
+#define LHD_EXTFLAGS 0x2000
+
+#define SKIP_IF_UNKNOWN 0x4000
+#define LONG_BLOCK 0x8000
+
+#define EARC_NEXT_VOLUME 0x0001
+#define EARC_DATACRC 0x0002
+#define EARC_REVSPACE 0x0004
+#define EARC_VOLNUMBER 0x0008
+
+enum HEADER_TYPE {
+ MARK_HEAD=0x72,MAIN_HEAD=0x73,FILE_HEAD=0x74,COMM_HEAD=0x75,AV_HEAD=0x76,
+ SUB_HEAD=0x77,PROTECT_HEAD=0x78,SIGN_HEAD=0x79,NEWSUB_HEAD=0x7a,
+ ENDARC_HEAD=0x7b
+};
+
+enum { EA_HEAD=0x100,UO_HEAD=0x101,MAC_HEAD=0x102,BEEA_HEAD=0x103,
+ NTACL_HEAD=0x104,STREAM_HEAD=0x105 };
+
+enum HOST_SYSTEM {
+ HOST_MSDOS=0,HOST_OS2=1,HOST_WIN32=2,HOST_UNIX=3,HOST_MACOS=4,
+ HOST_BEOS=5,HOST_MAX
+};
+
+#define SUBHEAD_TYPE_CMT "CMT"
+#define SUBHEAD_TYPE_ACL "ACL"
+#define SUBHEAD_TYPE_STREAM "STM"
+#define SUBHEAD_TYPE_UOWNER "UOW"
+#define SUBHEAD_TYPE_AV "AV"
+#define SUBHEAD_TYPE_RR "RR"
+#define SUBHEAD_TYPE_OS2EA "EA2"
+#define SUBHEAD_TYPE_BEOSEA "EABE"
+
+/* new file inherits a subblock when updating a host file */
+#define SUBHEAD_FLAGS_INHERITED 0x80000000
+
+#define SUBHEAD_FLAGS_CMT_UNICODE 0x00000001
+
+struct OldMainHeader
+{
+ byte Mark[4];
+ ushort HeadSize;
+ byte Flags;
+};
+
+
+struct OldFileHeader
+{
+ uint PackSize;
+ uint UnpSize;
+ ushort FileCRC;
+ ushort HeadSize;
+ uint FileTime;
+ byte FileAttr;
+ byte Flags;
+ byte UnpVer;
+ byte NameSize;
+ byte Method;
+};
+
+
+struct MarkHeader
+{
+ byte Mark[7];
+};
+
+
+struct BaseBlock
+{
+ ushort HeadCRC;
+ HEADER_TYPE HeadType;//byte
+ ushort Flags;
+ ushort HeadSize;
+
+ bool IsSubBlock()
+ {
+ if (HeadType==SUB_HEAD)
+ return(true);
+ if (HeadType==NEWSUB_HEAD && (Flags & LHD_SOLID)!=0)
+ return(true);
+ return(false);
+ }
+};
+
+struct BlockHeader:BaseBlock
+{
+ union {
+ uint DataSize;
+ uint PackSize;
+ };
+};
+
+
+struct MainHeader:BlockHeader
+{
+ ushort HighPosAV;
+ uint PosAV;
+};
+
+
+#define SALT_SIZE 8
+
+struct FileHeader:BlockHeader
+{
+ uint UnpSize;
+ byte HostOS;
+ uint FileCRC;
+ uint FileTime;
+ byte UnpVer;
+ byte Method;
+ ushort NameSize;
+ union {
+ uint FileAttr;
+ uint SubFlags;
+ };
+/* optional */
+ uint HighPackSize;
+ uint HighUnpSize;
+/* names */
+ char FileName[NM];
+ wchar FileNameW[NM];
+/* optional */
+ Array<byte> SubData;
+ byte Salt[SALT_SIZE];
+
+ RarTime mtime;
+ RarTime ctime;
+ RarTime atime;
+ RarTime arctime;
+/* dummy */
+ Int64 FullPackSize;
+ Int64 FullUnpSize;
+
+ void Clear(int SubDataSize)
+ {
+ SubData.Alloc(SubDataSize);
+ Flags=LONG_BLOCK;
+ SubFlags=0;
+ }
+
+ bool CmpName(const char *Name)
+ {
+ return(strcmp(FileName,Name)==0);
+ }
+
+ FileHeader& operator = (FileHeader &hd)
+ {
+ SubData.Reset();
+ memcpy(this,&hd,sizeof(*this));
+ SubData.CleanData();
+ SubData=hd.SubData;
+ return(*this);
+ }
+};
+
+
+struct EndArcHeader:BaseBlock
+{
+ uint ArcDataCRC;
+ ushort VolNumber;
+};
+
+
+struct SubBlockHeader:BlockHeader
+{
+ ushort SubType;
+ byte Level;
+};
+
+
+struct CommentHeader:BaseBlock
+{
+ ushort UnpSize;
+ byte UnpVer;
+ byte Method;
+ ushort CommCRC;
+};
+
+
+struct ProtectHeader:BlockHeader
+{
+ byte Version;
+ ushort RecSectors;
+ uint TotalBlocks;
+ byte Mark[8];
+};
+
+
+struct AVHeader:BaseBlock
+{
+ byte UnpVer;
+ byte Method;
+ byte AVVer;
+ uint AVInfoCRC;
+};
+
+
+struct SignHeader:BaseBlock
+{
+ uint CreationTime;
+ ushort ArcNameSize;
+ ushort UserNameSize;
+};
+
+
+struct UnixOwnersHeader:SubBlockHeader
+{
+ ushort OwnerNameSize;
+ ushort GroupNameSize;
+/* dummy */
+ char OwnerName[NM];
+ char GroupName[NM];
+};
+
+
+struct EAHeader:SubBlockHeader
+{
+ uint UnpSize;
+ byte UnpVer;
+ byte Method;
+ uint EACRC;
+};
+
+
+struct StreamHeader:SubBlockHeader
+{
+ uint UnpSize;
+ byte UnpVer;
+ byte Method;
+ uint StreamCRC;
+ ushort StreamNameSize;
+/* dummy */
+ byte StreamName[NM];
+};
+
+
+struct MacFInfoHeader:SubBlockHeader
+{
+ uint fileType;
+ uint fileCreator;
+};
+
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/int64.cpp b/7zip/Compress/Rar29/Original/int64.cpp
new file mode 100755
index 00000000..996d0ea6
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/int64.cpp
@@ -0,0 +1,274 @@
+#include "rar.hpp"
+
+#ifndef NATIVE_INT64
+
+Int64::Int64()
+{
+}
+
+
+Int64::Int64(uint n)
+{
+ HighPart=0;
+ LowPart=n;
+}
+
+
+Int64::Int64(uint HighPart,uint LowPart)
+{
+ Int64::HighPart=HighPart;
+ Int64::LowPart=LowPart;
+}
+
+
+/*
+Int64 Int64::operator = (Int64 n)
+{
+ HighPart=n.HighPart;
+ LowPart=n.LowPart;
+ return(*this);
+}
+*/
+
+
+Int64 Int64::operator << (int n)
+{
+ Int64 res=*this;
+ while (n--)
+ {
+ res.HighPart<<=1;
+ if (res.LowPart & 0x80000000)
+ res.HighPart|=1;
+ res.LowPart<<=1;
+ }
+ return(res);
+}
+
+
+Int64 Int64::operator >> (int n)
+{
+ Int64 res=*this;
+ while (n--)
+ {
+ res.LowPart>>=1;
+ if (res.HighPart & 1)
+ res.LowPart|=0x80000000;
+ res.HighPart>>=1;
+ }
+ return(res);
+}
+
+
+Int64 operator / (Int64 n1,Int64 n2)
+{
+ if (n1.HighPart==0 && n2.HighPart==0)
+ return(Int64(0,n1.LowPart/n2.LowPart));
+ int ShiftCount=0;
+ while (n1>n2)
+ {
+ n2=n2<<1;
+ if (++ShiftCount>64)
+ return(0);
+ }
+ Int64 res=0;
+ while (ShiftCount-- >= 0)
+ {
+ res=res<<1;
+ if (n1>=n2)
+ {
+ n1-=n2;
+ ++res;
+ }
+ n2=n2>>1;
+ }
+ return(res);
+}
+
+
+Int64 operator * (Int64 n1,Int64 n2)
+{
+ if (n1<0x10000 && n2<0x10000)
+ return(Int64(0,n1.LowPart*n2.LowPart));
+ Int64 res=0;
+ for (int I=0;I<64;I++)
+ {
+ if (n2.LowPart & 1)
+ res+=n1;
+ n1=n1<<1;
+ n2=n2>>1;
+ }
+ return(res);
+}
+
+
+Int64 operator % (Int64 n1,Int64 n2)
+{
+ if (n1.HighPart==0 && n2.HighPart==0)
+ return(Int64(0,n1.LowPart%n2.LowPart));
+ return(n1-n1/n2*n2);
+}
+
+
+Int64 operator + (Int64 n1,Int64 n2)
+{
+ n1.LowPart+=n2.LowPart;
+ if (n1.LowPart<n2.LowPart)
+ n1.HighPart++;
+ n1.HighPart+=n2.HighPart;
+ return(n1);
+}
+
+
+Int64 operator - (Int64 n1,Int64 n2)
+{
+ if (n1.LowPart<n2.LowPart)
+ n1.HighPart--;
+ n1.LowPart-=n2.LowPart;
+ n1.HighPart-=n2.HighPart;
+ return(n1);
+}
+
+
+Int64 operator += (Int64 &n1,Int64 n2)
+{
+ n1=n1+n2;
+ return(n1);
+}
+
+
+Int64 operator -= (Int64 &n1,Int64 n2)
+{
+ n1=n1-n2;
+ return(n1);
+}
+
+
+Int64 operator *= (Int64 &n1,Int64 n2)
+{
+ n1=n1*n2;
+ return(n1);
+}
+
+
+Int64 operator /= (Int64 &n1,Int64 n2)
+{
+ n1=n1/n2;
+ return(n1);
+}
+
+
+Int64 operator | (Int64 n1,Int64 n2)
+{
+ n1.LowPart|=n2.LowPart;
+ n1.HighPart|=n2.HighPart;
+ return(n1);
+}
+
+
+Int64 operator & (Int64 n1,Int64 n2)
+{
+ n1.LowPart&=n2.LowPart;
+ n1.HighPart&=n2.HighPart;
+ return(n1);
+}
+
+
+/*
+inline void operator -= (Int64 &n1,unsigned int n2)
+{
+ if (n1.LowPart<n2)
+ n1.HighPart--;
+ n1.LowPart-=n2;
+}
+
+
+inline void operator ++ (Int64 &n)
+{
+ if (++n.LowPart == 0)
+ ++n.HighPart;
+}
+
+
+inline void operator -- (Int64 &n)
+{
+ if (n.LowPart-- == 0)
+ n.HighPart--;
+}
+*/
+
+bool operator == (Int64 n1,Int64 n2)
+{
+ return(n1.LowPart==n2.LowPart && n1.HighPart==n2.HighPart);
+}
+
+
+bool operator > (Int64 n1,Int64 n2)
+{
+ return((int)n1.HighPart>(int)n2.HighPart || n1.HighPart==n2.HighPart && n1.LowPart>n2.LowPart);
+}
+
+
+bool operator < (Int64 n1,Int64 n2)
+{
+ return((int)n1.HighPart<(int)n2.HighPart || n1.HighPart==n2.HighPart && n1.LowPart<n2.LowPart);
+}
+
+
+bool operator != (Int64 n1,Int64 n2)
+{
+ return(n1.LowPart!=n2.LowPart || n1.HighPart!=n2.HighPart);
+}
+
+
+bool operator >= (Int64 n1,Int64 n2)
+{
+ return(n1>n2 || n1==n2);
+}
+
+
+bool operator <= (Int64 n1,Int64 n2)
+{
+ return(n1<n2 || n1==n2);
+}
+
+
+void Int64::Set(uint HighPart,uint LowPart)
+{
+ Int64::HighPart=HighPart;
+ Int64::LowPart=LowPart;
+}
+#endif
+
+void itoa(Int64 n,char *Str)
+{
+ if (n<=0xffffffff)
+ {
+ sprintf(Str,"%u",int64to32(n));
+ return;
+ }
+
+ char NumStr[50];
+ int Pos=0;
+
+ do
+ {
+ NumStr[Pos++]=int64to32(n%10)+'0';
+ n=n/10;
+ } while (n!=0);
+
+ for (int I=0;I<Pos;I++)
+ Str[I]=NumStr[Pos-I-1];
+ Str[Pos]=0;
+}
+
+
+Int64 atoil(char *Str)
+{
+ Int64 n=0;
+ while (*Str>='0' && *Str<='9')
+ {
+ n=n*10+*Str-'0';
+ Str++;
+ }
+ return(n);
+}
diff --git a/7zip/Compress/Rar29/Original/int64.hpp b/7zip/Compress/Rar29/Original/int64.hpp
new file mode 100755
index 00000000..a8057522
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/int64.hpp
@@ -0,0 +1,86 @@
+#ifndef _RAR_INT64_
+#define _RAR_INT64_
+
+#if defined(__BORLANDC__) || defined(_MSC_VER)
+#define NATIVE_INT64
+typedef __int64 Int64;
+#endif
+
+#if defined(__GNUC__) || defined(__HP_aCC)
+#define NATIVE_INT64
+typedef long long Int64;
+#endif
+
+#ifdef NATIVE_INT64
+
+#define int64to32(x) ((uint)(x))
+#define int32to64(high,low) ((((Int64)(high))<<32)+(low))
+#define is64plus(x) (x>=0)
+
+#else
+
+class Int64
+{
+ public:
+ Int64();
+ Int64(uint n);
+ Int64(uint HighPart,uint LowPart);
+
+// Int64 operator = (Int64 n);
+ Int64 operator << (int n);
+ Int64 operator >> (int n);
+
+ friend Int64 operator / (Int64 n1,Int64 n2);
+ friend Int64 operator * (Int64 n1,Int64 n2);
+ friend Int64 operator % (Int64 n1,Int64 n2);
+ friend Int64 operator + (Int64 n1,Int64 n2);
+ friend Int64 operator - (Int64 n1,Int64 n2);
+ friend Int64 operator += (Int64 &n1,Int64 n2);
+ friend Int64 operator -= (Int64 &n1,Int64 n2);
+ friend Int64 operator *= (Int64 &n1,Int64 n2);
+ friend Int64 operator /= (Int64 &n1,Int64 n2);
+ friend Int64 operator | (Int64 n1,Int64 n2);
+ friend Int64 operator & (Int64 n1,Int64 n2);
+ inline friend void operator -= (Int64 &n1,unsigned int n2)
+ {
+ if (n1.LowPart<n2)
+ n1.HighPart--;
+ n1.LowPart-=n2;
+ }
+ inline friend void operator ++ (Int64 &n)
+ {
+ if (++n.LowPart == 0)
+ ++n.HighPart;
+ }
+ inline friend void operator -- (Int64 &n)
+ {
+ if (n.LowPart-- == 0)
+ n.HighPart--;
+ }
+ friend bool operator == (Int64 n1,Int64 n2);
+ friend bool operator > (Int64 n1,Int64 n2);
+ friend bool operator < (Int64 n1,Int64 n2);
+ friend bool operator != (Int64 n1,Int64 n2);
+ friend bool operator >= (Int64 n1,Int64 n2);
+ friend bool operator <= (Int64 n1,Int64 n2);
+
+ void Set(uint HighPart,uint LowPart);
+ uint GetLowPart() {return(LowPart);}
+
+ uint LowPart;
+ uint HighPart;
+};
+
+inline uint int64to32(Int64 n) {return(n.GetLowPart());}
+#define int32to64(high,low) (Int64((high),(low)))
+#define is64plus(x) ((int)(x).HighPart>=0)
+
+#endif
+
+#define INT64ERR int32to64(0x80000000,0)
+#define INT64MAX int32to64(0x7fffffff,0)
+
+void itoa(Int64 n,char *Str);
+Int64 atoil(char *Str);
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/isnt.hpp b/7zip/Compress/Rar29/Original/isnt.hpp
new file mode 100755
index 00000000..02652361
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/isnt.hpp
@@ -0,0 +1,6 @@
+#ifndef _RAR_ISNT_
+#define _RAR_ISNT_
+
+int WinNT();
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/list.hpp b/7zip/Compress/Rar29/Original/list.hpp
new file mode 100755
index 00000000..7721ae52
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/list.hpp
@@ -0,0 +1,6 @@
+#ifndef _RAR_LIST_
+#define _RAR_LIST_
+
+void ListArchive(CommandData *Cmd);
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/loclang.hpp b/7zip/Compress/Rar29/Original/loclang.hpp
new file mode 100755
index 00000000..05eefdde
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/loclang.hpp
@@ -0,0 +1,340 @@
+#define MYesNo "_Yes_No"
+#define MYesNoAll "_Yes_No_All"
+#define MYesNoAllRenQ "_Yes_No_All_nEver_Rename_Quit"
+#define MContinueQuit "_Continue_Quit"
+#define MRetryAbort "_Retry_Abort"
+#define MCopyright "\nRAR %s Copyright (c) 1993-%d Alexander Roshal %d %s %d"
+#define MRegTo "\nRegistered to %s\n"
+#define MShare "\nShareware version Type RAR -? for help\n"
+#define MUCopyright "\nUNRAR %s freeware Copyright (c) 1993-%d Alexander Roshal\n"
+#define MBeta "beta"
+#define MMonthJan "Jan"
+#define MMonthFeb "Feb"
+#define MMonthMar "Mar"
+#define MMonthApr "Apr"
+#define MMonthMay "May"
+#define MMonthJun "Jun"
+#define MMonthJul "Jul"
+#define MMonthAug "Aug"
+#define MMonthSep "Sep"
+#define MMonthOct "Oct"
+#define MMonthNov "Nov"
+#define MMonthDec "Dec"
+#define MRARTitle1 "\nUsage: rar <command> -<switch 1> -<switch N> <archive> <files...>"
+#define MUNRARTitle1 "\nUsage: unrar <command> -<switch 1> -<switch N> <archive> <files...>"
+#define MRARTitle2 "\n <@listfiles...> <path_to_extract\\>"
+#define MCHelpCmd "\n\n<Commands>"
+#define MCHelpCmdA "\n a Add files to archive"
+#define MCHelpCmdC "\n c Add archive comment"
+#define MCHelpCmdCF "\n cf Add files comment"
+#define MCHelpCmdCW "\n cw Write archive comment to file"
+#define MCHelpCmdD "\n d Delete files from archive"
+#define MCHelpCmdE "\n e Extract files to current directory"
+#define MCHelpCmdF "\n f Freshen files in archive"
+#define MCHelpCmdI "\n i[par]=<str> Find string in archives"
+#define MCHelpCmdK "\n k Lock archive"
+#define MCHelpCmdL "\n l[t,b] List archive [technical, bare]"
+#define MCHelpCmdM "\n m[f] Move to archive [files only]"
+#define MCHelpCmdP "\n p Print file to stdout"
+#define MCHelpCmdR "\n r Repair archive"
+#define MCHelpCmdRC "\n rc Reconstruct missing volumes"
+#define MCHelpCmdRN "\n rn Rename archived files"
+#define MCHelpCmdRR "\n rr[N] Add data recovery record"
+#define MCHelpCmdRV "\n rv[N] Create recovery volumes"
+#define MCHelpCmdS "\n s[name|-] Convert archive to or from SFX"
+#define MCHelpCmdT "\n t Test archive files"
+#define MCHelpCmdU "\n u Update files in archive"
+#define MCHelpCmdV "\n v[t,b] Verbosely list archive [technical,bare]"
+#define MCHelpCmdX "\n x Extract files with full path"
+#define MCHelpSw "\n\n<Switches>"
+#define MCHelpSwm "\n - Stop switches scanning"
+#define MCHelpSwAC "\n ac Clear Archive attribute after compression or extraction"
+#define MCHelpSwAD "\n ad Append archive name to destination path"
+#define MCHelpSwAG "\n ag[format] Generate archive name using the current date"
+#define MCHelpSwAO "\n ao Add files with Archive attribute set"
+#define MCHelpSwAP "\n ap<path> Set path inside archive"
+#define MCHelpSwAS "\n as Synchronize archive contents"
+#define MCHelpSwAV "\n av Put authenticity verification (registered versions only)"
+#define MCHelpSwAVm "\n av- Disable authenticity verification check"
+#define MCHelpSwCm "\n c- Disable comments show"
+#define MCHelpSwCFGm "\n cfg- Disable read configuration"
+#define MCHelpSwCL "\n cl Convert names to lower case"
+#define MCHelpSwCU "\n cu Convert names to upper case"
+#define MCHelpSwDF "\n df Delete files after archiving"
+#define MCHelpSwDH "\n dh Open shared files"
+#define MCHelpSwDS "\n ds Disable name sort for solid archive"
+#define MCHelpSwEa "\n e[+]<attr> Set file exclude and include attributes"
+#define MCHelpSwED "\n ed Do not add empty directories"
+#define MCHelpSwEE "\n ee Do not save and extract extended attributes"
+#define MCHelpSwEN "\n en Do not put 'end of archive' block"
+#define MCHelpSwEP "\n ep Exclude paths from names"
+#define MCHelpSwEP1 "\n ep1 Exclude base directory from names"
+#define MCHelpSwEP2 "\n ep2 Expand paths to full"
+#define MCHelpSwEP3 "\n ep3 Expand paths to full including the drive letter"
+#define MCHelpSwF "\n f Freshen files"
+#define MCHelpSwHP "\n hp[password] Encrypt both file data and headers"
+#define MCHelpSwIDP "\n id[c,d,p,q] Disable messages"
+#define MCHelpSwIEML "\n ieml[addr] Send archive by email"
+#define MCHelpSwIERR "\n ierr Send all messages to stderr"
+#define MCHelpSwILOG "\n ilog[name] Log errors to file (registered versions only)"
+#define MCHelpSwINUL "\n inul Disable all messages"
+#define MCHelpSwIOFF "\n ioff Turn PC off after completing an operation"
+#define MCHelpSwISND "\n isnd Enable sound"
+#define MCHelpSwK "\n k Lock archive"
+#define MCHelpSwKB "\n kb Keep broken extracted files"
+#define MCHelpSwMn "\n m<0..5> Set compression level (0-store...3-default...5-maximal)"
+#define MCHelpSwMC "\n mc<par> Set advanced compression parameters"
+#define MCHelpSwMD "\n md<size> Dictionary size in KB (64,128,256,512,1024,2048,4096 or A-G)"
+#define MCHelpSwMS "\n ms[ext;ext] Specify file types to store"
+#define MCHelpSwN "\n n<file> Include only specified file"
+#define MCHelpSwNa "\n n@ Read file names to include from stdin"
+#define MCHelpSwNal "\n n@<list> Include files in specified list file"
+#define MCHelpSwOp "\n o+ Overwrite existing files"
+#define MCHelpSwOm "\n o- Do not overwrite existing files"
+#define MCHelpSwOC "\n oc Set NTFS Compressed attribute"
+#define MCHelpSwOL "\n ol Save symbolic links as the link instead of the file"
+#define MCHelpSwOS "\n os Save NTFS streams"
+#define MCHelpSwOW "\n ow Save or restore file owner and group"
+#define MCHelpSwP "\n p[password] Set password"
+#define MCHelpSwPm "\n p- Do not query password"
+#define MCHelpSwR "\n r Recurse subdirectories"
+#define MCHelpSwR0 "\n r0 Recurse subdirectories for wildcard names only"
+#define MCHelpSwRI "\n ri<P>[:<S>] Set priority (0-default,1-min..15-max) and sleep time in ms"
+#define MCHelpSwRR "\n rr[N] Add data recovery record"
+#define MCHelpSwRV "\n rv[N] Create recovery volumes"
+#define MCHelpSwS "\n s[<N>,v[-],e] Create solid archive"
+#define MCHelpSwSm "\n s- Disable solid archiving"
+#define MCHelpSwSFX "\n sfx[name] Create SFX archive"
+#define MCHelpSwSI "\n si[name] Read data from standard input (stdin)"
+#define MCHelpSwT "\n t Test files after archiving"
+#define MCHelpSwTK "\n tk Keep original archive time"
+#define MCHelpSwTL "\n tl Set archive time to latest file"
+#define MCHelpSwTN "\n tn<time> Process files newer than <time>"
+#define MCHelpSwTO "\n to<time> Process files older than <time>"
+#define MCHelpSwTA "\n ta<date> Process files modified after <date> in YYYYMMDDHHMMSS format"
+#define MCHelpSwTB "\n tb<date> Process files modified before <date> in YYYYMMDDHHMMSS format"
+#define MCHelpSwTS "\n ts<m,c,a>[N] Save or restore file time (modification, creation, access)"
+#define MCHelpSwU "\n u Update files"
+#define MCHelpSwV "\n v Create volumes with size autodetection or list all volumes"
+#define MCHelpSwVUnr "\n v List all volumes"
+#define MCHelpSwVn "\n v<size>[k,b] Create volumes with size=<size>*1000 [*1024, *1]"
+#define MCHelpSwVD "\n vd Erase disk contents before creating volume"
+#define MCHelpSwVER "\n ver[n] File version control"
+#define MCHelpSwVN "\n vn Use the old style volume naming scheme"
+#define MCHelpSwVP "\n vp Pause before each volume"
+#define MCHelpSwW "\n w<path> Assign work directory"
+#define MCHelpSwX "\n x<file> Exclude specified file"
+#define MCHelpSwXa "\n x@ Read file names to exclude from stdin"
+#define MCHelpSwXal "\n x@<list> Exclude files in specified list file"
+#define MCHelpSwY "\n y Assume Yes on all queries"
+#define MCHelpSwZ "\n z<file> Read archive comment from file"
+#define MBadArc "\nERROR: Bad archive %s\n"
+#define MAskPsw "Enter password (will not be echoed)"
+#define MAskPswEcho "Enter password"
+#define MReAskPsw "\nReenter password: "
+#define MFor " for "
+#define MNotMatchPsw "\nERROR: Passwords do not match\n"
+#define MErrWrite "Write error in the file %s"
+#define MErrRead "Read error in the file %s"
+#define MErrSeek "Seek error in the file %s"
+#define MErrFClose "Cannot close the file %s"
+#define MErrOutMem "Not enough memory"
+#define MErrBrokenArc "Corrupt archive - use 'Repair' command"
+#define MProgAborted "Program aborted"
+#define MErrRename "\nCannot rename %s to %s"
+#define MAbsNextVol "\nCannot find volume %s"
+#define MBreak "\nUser break\n"
+#define MAskCreatVol "\nCreate next volume ?"
+#define MAskNextDisk "\nDisk full. Insert next"
+#define MCreatVol "\n\nCreating %sarchive %s\n"
+#define MAskNextVol "\nInsert disk with %s"
+#define MTestVol "\n\nTesting archive %s\n"
+#define MExtrVol "\n\nExtracting from %s\n"
+#define MConverting "\nConverting %s"
+#define MCvtToSFX "\nConvert archives to SFX"
+#define MCvtFromSFX "\nRemoving SFX module"
+#define MNotSFX "\n%s is not SFX archive"
+#define MNotRAR "\n%s is not RAR archive"
+#define MNotFirstVol "\n%s is not the first volume"
+#define MCvtOldFormat "\n%s - cannot convert to SFX archive with old format"
+#define MCannotCreate "\nCannot create %s"
+#define MCannotOpen "\nCannot open %s"
+#define MUnknownMeth "\nUnknown method in %s"
+#define MVerRequired "\nYou need RAR %d.%d to unpack it"
+#define MOk " OK"
+#define MDone "\nDone"
+#define MLockingArc "\nLocking archive"
+#define MNotMdfOld "\n\nERROR: Cannot modify old format archive"
+#define MNotMdfLock "\n\nERROR: Locked archive"
+#define MNotMdfVol "\n\nERROR: Cannot modify volume"
+#define MVerifyAV "\nVerifying authenticity information ... "
+#define MFailedAV " Failed\n"
+#define MStrAV1 "\n\nArchive %s"
+#define MStrAV2 "\ncreated at %s"
+#define MStrAV3 "\nby %s\n"
+#define MLogFailedAV "Invalid authenticity information"
+#define MAddingAV "\nAdding authenticity verification "
+#define MAVOldStyle "\n\nOld style authenticity information"
+#define MPackAskReg "\nEvaluation copy. Please register.\n"
+#define MCreateArchive "\nCreating %sarchive %s\n"
+#define MUpdateArchive "\nUpdating %sarchive %s\n"
+#define MAddSolid "solid "
+#define MAddFile "\nAdding %-58s "
+#define MUpdFile "\nUpdating %-58s "
+#define MAddPoints "\n... %-58s "
+#define MCannotUpdPswSolid "\nERROR: Cannot update solid archives with password\n"
+#define MMoveDelFiles "\n\nDeleting files %s..."
+#define MMoveDelDirs "and directories"
+#define MMoveDelFile "\nDeleting %-30s"
+#define MMoveDeleted " deleted"
+#define MMoveNotDeleted " NOT DELETED"
+#define MClearAttrib "\n\nClearing attributes..."
+#define MMoveDelDir "\nDeleting directory %-30s"
+#define MWarErrFOpen "\nWARNING: Cannot open %d %s"
+#define MErrOpenFiles "files"
+#define MErrOpenFile "file"
+#define MAddNoFiles "\nWARNING: No files"
+#define MMdfEncrSol "\n%s: encrypted"
+#define MCannotMdfEncrSol "\nCannot modify solid archive containing encrypted files"
+#define MAddAnalyze "\nAnalyzing archived files: "
+#define MRepacking "\nRepacking archived files: "
+#define MCRCFailed "\n%-20s - CRC failed"
+#define MExtrTest "\n\nTesting archive %s\n"
+#define MExtracting "\n\nExtracting from %s\n"
+#define MUseCurPsw "\n%s - use current password ?"
+#define MCreatDir "\nCreating %-56s"
+#define MExtrSkipFile "\nSkipping %-56s"
+#define MExtrTestFile "\nTesting %-56s"
+#define MExtrFile "\nExtracting %-56s"
+#define MExtrPoints "\n... %-56s"
+#define MExtrErrMkDir "\nCannot create directory %s"
+#define MExtrPrinting "\n------ Printing %s\n\n"
+#define MEncrBadCRC "\nEncrypted file: CRC failed in %s (password incorrect ?)"
+#define MExtrNoFiles "\nNo files to extract"
+#define MExtrAllOk "\nAll OK"
+#define MExtrTotalErr "\nTotal errors: %ld"
+#define MFileExists "\n\n%s already exists. Overwrite it ?"
+#define MAskOverwrite "\nOverwrite %s ?"
+#define MAskNewName "\nEnter new name: "
+#define MLogMainHead "\nThe archive header is corrupt"
+#define MLogFileHead "\n%s - the file header is corrupt"
+#define MLogCommHead "\nThe comment header is corrupt\n"
+#define MLogProtectHead "The data recovery header is corrupt"
+#define MReadStdinCmt "\nReading comment from stdin\n"
+#define MReadCommFrom "\nReading comment from %s"
+#define MDelComment "\nDeleting comment from %s"
+#define MAddComment "\nAdding comment to %s"
+#define MFCommAdd "\nAdding file comments"
+#define MAskFComm "\n\nReading comment for %s : %s from stdin\n"
+#define MLogCommBrk "\nThe archive comment is corrupt"
+#define MCommAskCont "\nPress 'Enter' to continue or 'Q' to quit:"
+#define MLogBrokFCmt "\nThe file comment is corrupt"
+#define MAbsDestName "\nDestination file name required"
+#define MWriteCommTo "\nWrite comment to %s"
+#define MCommNotPres "\nComment is not present"
+#define MDelFrom "\nDeleting from %s"
+#define MDeleting "\nDeleting %s"
+#define MEraseArc "\nErasing empty archive %s"
+#define MNoDelFiles "\nNo files to delete"
+#define MLogTitle "\n\n-------- %2d %s %d, archive %s\n"
+#define MPathTooLong "\nERROR: Path too long\n"
+#define MListSolid "Solid "
+#define MListSFX "SFX "
+#define MListVol1 "volume"
+#define MListVol2 "Volume"
+#define MListArc1 "archive"
+#define MListArc2 "Archive"
+#define MListRecRec "\nRecovery record is present\n"
+#define MListLock "\nLock is present\n"
+#define MListPathComm "\nPathname/Comment\n "
+#define MListName "\n Name "
+#define MListTitle " Size Packed Ratio Date Time Attr CRC Meth Ver\n"
+#define MListTechTitle " Host OS Solid Old\n"
+#define MListEAHead "\n OS/2 extended attributes"
+#define MListUOHead "\n Unix Owner/Group data: %-14s %-14s"
+#define MListBeEAHead "\n BeOS extended attributes"
+#define MListNTACLHead "\n NTFS security data"
+#define MListStrmHead "\n NTFS stream: %s"
+#define MListUnkHead "\n Unknown subheader type: 0x%04x"
+#define MFileComment "\nComment: "
+#define MYes "Yes"
+#define MNo "No"
+#define MListNoFiles " 0 files\n"
+#define MRprReconstr "\nReconstructing %s"
+#define MRprBuild "\nBuilding %s"
+#define MRprOldFormat "\nCannot repair archive with old format"
+#define MRprFind "\nFound %s"
+#define MRprAskIsSol "\nThe archive header is corrupt. Mark archive as solid ?"
+#define MRprNoFiles "\nNo files found"
+#define MRprSuspEntry "\n\nSuspicious entry %s"
+#define MRprDir "\nDirectory"
+#define MRprSuspSize "\nSize %ld Packed %ld"
+#define MRprSuspAdd "\nAdd it to archive ?"
+#define MLogUnexpEOF "\nUnexpected end of archive"
+#define MRepAskReconst "\nReconstruct archive structure ?"
+#define MRecScanning "\nScanning..."
+#define MRecRNotFound "\nData recovery record not found"
+#define MRecRFound "\nData recovery record found"
+#define MRecSecDamage "\nSector %ld (offsets %lX...%lX) damaged"
+#define MRecCorrected " - data recovered"
+#define MRecFailed " - cannot recover data"
+#define MAddRecRec "\nAdding data recovery record"
+#define MEraseForVolume "\n\nErasing contents of drive %c:\n"
+#define MGetOwnersError "\nWARNING: Cannot get %s owner and group\n"
+#define MErrGetOwnerID "\nWARNING: Cannot get owner %s ID\n"
+#define MErrGetGroupID "\nWARNING: Cannot get group %s ID\n"
+#define MOwnersBroken "\nERROR: %s group and owner data are corrupt\n"
+#define MSetOwnersError "\nWARNING: Cannot set %s owner and group\n"
+#define MErrLnkRead "\nWARNING: Cannot read symbolic link %s"
+#define MErrCreateLnk "\nWARNING: Cannot create link %s"
+#define MSymLinkExists "\nWARNING: Symbolic link %s already exists"
+#define MAskRetryCreate "\nCannot create %s. Retry ?"
+#define MListMACHead1 "\n MacOS file type: %c%c%c%c ; "
+#define MListMACHead2 "file creator: %c%c%c%c\n"
+#define MDataBadCRC "\n%-20s : packed data CRC failed in volume %s"
+#define MFileRO "\n%s is read-only"
+#define MACLGetError "\nWARNING: Cannot get %s security data\n"
+#define MACLSetError "\nWARNING: Cannot set %s security data\n"
+#define MACLBroken "\nERROR: %s security data are corrupt\n"
+#define MACLUnknown "\nWARNING: Unknown format of %s security data\n"
+#define MStreamBroken "\nERROR: %s stream data are corrupt\n"
+#define MStreamUnknown "\nWARNING: Unknown format of %s stream data\n"
+#define MInvalidName "\nERROR: Invalid file name %s"
+#define MEABroken "\nERROR: %s extended attributes are corrupt\n"
+#define MEAUnknHeader "\nWARNING: %s - unknown format of extended attributes\n"
+#define MCannotSetEA "\nWARNING: cannot set extended attributes to %s\n"
+#define MCannotGetEA "\nERROR: Cannot get extended attributes of %s\n"
+#define MShowEA " (+EA)"
+#define MSkipEA "\n...skipping extended attributes"
+#define MProcessArc "\n\nProcessing archive %s"
+#define MSyncScanError "\nFile search errors, cannot synchronize archive"
+#define MCorrectingName "\nWARNING: Attempting to correct the invalid file name"
+#define MUnpCannotMerge "\nWARNING: You need to start extraction from a previous volume to unpack %s"
+#define MUnknownOption "\nERROR: Unknown option: %s"
+#define MSubHeadCorrupt "\nERROR: Corrupt data header found, ignored"
+#define MSubHeadUnknown "\nWARNING: Unknown data header format, ignored"
+#define MSubHeadDataCRC "\nERROR: Corrupt %s data block"
+#define MSubHeadType "\nData header type: %s"
+#define MScanError "\nCannot read contents of %s"
+#define MNotVolume "\n%s is not volume"
+#define MRecVolDiffSets "\nERROR: %s and %s belong to different sets"
+#define MRecVolMissing "\n%d volumes missing"
+#define MRecVolFound "\n%d recovery volumes found"
+#define MRecVolAllExist "\nNothing to reconstruct"
+#define MRecVolCannotFix "\nReconstruction impossible"
+#define MReconstructing "\nReconstructing..."
+#define MCreating "\nCreating %s"
+#define MRenaming "\nRenaming %s to %s"
+#define MNTFSRequired "\nWrite error: only NTFS file system supports files larger than 4 GB"
+#define MErrChangeAttr "\nWARNING: Cannot change attributes of %s"
+#define MWrongSFXVer "\nERROR: default SFX module does not support RAR %d.%d archives"
+#define MCannotEncName "\nCannot encrypt archive already contained encrypted files"
+#define MCannotEmail "\nCannot email the file %s"
+#define MCopyrightS "\nRAR SFX archive"
+#define MSHelpCmd "\n\n<Commands>"
+#define MSHelpCmdE "\n -x Extract from archive (default)"
+#define MSHelpCmdT "\n -t Test archive files"
+#define MSHelpCmdV "\n -v Verbosely list contents of archive"
+#define MMaxPathLimit "\nTotal path and file name length must not exceed %d characters"
+#define MRecVolLimit "\nTotal number of usual and recovery volumes must not exceed 255"
+#define MVolumeNumber "volume %d"
diff --git a/7zip/Compress/Rar29/Original/log.hpp b/7zip/Compress/Rar29/Original/log.hpp
new file mode 100755
index 00000000..52d6b8d5
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/log.hpp
@@ -0,0 +1,18 @@
+#ifndef _RAR_LOG_
+#define _RAR_LOG_
+
+void InitLogOptions(char *LogName);
+
+#ifndef SILENT
+void Log(const char *ArcName,const char *Format,...);
+#endif
+
+#ifdef SILENT
+#ifdef __GNUC__
+#define Log(args...)
+#else
+inline void Log(const char *a,const char *b,const char *c=NULL,const char *d=NULL) {}
+#endif
+#endif
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/match.hpp b/7zip/Compress/Rar29/Original/match.hpp
new file mode 100755
index 00000000..a7367772
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/match.hpp
@@ -0,0 +1,16 @@
+#ifndef _RAR_MATCH_
+#define _RAR_MATCH_
+
+enum {MATCH_NAMES,MATCH_PATH,MATCH_EXACTPATH,MATCH_SUBPATH,MATCH_WILDSUBPATH};
+
+#define MATCH_MODEMASK 0x0000ffff
+
+bool CmpName(char *Wildcard,char *Name,int CmpPath);
+bool CmpName(wchar *Wildcard,wchar *Name,int CmpPath);
+
+int stricompc(const char *Str1,const char *Str2);
+int stricompcw(const wchar *Str1,const wchar *Str2);
+int strnicompc(const char *Str1,const char *Str2,int N);
+int strnicompcw(const wchar *Str1,const wchar *Str2,int N);
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/model.cpp b/7zip/Compress/Rar29/Original/model.cpp
new file mode 100755
index 00000000..e708feb2
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/model.cpp
@@ -0,0 +1,600 @@
+/****************************************************************************
+ * This file is part of PPMd project *
+ * Written and distributed to public domain by Dmitry Shkarin 1997, *
+ * 1999-2000 *
+ * Contents: model description and encoding/decoding routines *
+ ****************************************************************************/
+
+inline PPM_CONTEXT* PPM_CONTEXT::createChild(ModelPPM *Model,STATE* pStats,
+ STATE& FirstState)
+{
+ PPM_CONTEXT* pc = (PPM_CONTEXT*) Model->SubAlloc.AllocContext();
+ if ( pc )
+ {
+ pc->NumStats=1;
+ pc->OneState=FirstState;
+ pc->Suffix=this;
+ pStats->Successor=pc;
+ }
+ return pc;
+}
+
+
+ModelPPM::ModelPPM()
+{
+ MinContext=NULL;
+ MaxContext=NULL;
+ MedContext=NULL;
+}
+
+
+void ModelPPM::RestartModelRare()
+{
+ int i, k, m;
+ memset(CharMask,0,sizeof(CharMask));
+ SubAlloc.InitSubAllocator();
+ InitRL=-(MaxOrder < 12 ? MaxOrder:12)-1;
+ MinContext = MaxContext = (PPM_CONTEXT*) SubAlloc.AllocContext();
+ MinContext->Suffix=NULL;
+ OrderFall=MaxOrder;
+ MinContext->U.SummFreq=(MinContext->NumStats=256)+1;
+ FoundState=MinContext->U.Stats=(STATE*)SubAlloc.AllocUnits(256/2);
+ for (RunLength=InitRL, PrevSuccess=i=0;i < 256;i++)
+ {
+ MinContext->U.Stats[i].Symbol=i;
+ MinContext->U.Stats[i].Freq=1;
+ MinContext->U.Stats[i].Successor=NULL;
+ }
+
+ static const ushort InitBinEsc[]={
+ 0x3CDD,0x1F3F,0x59BF,0x48F3,0x64A1,0x5ABC,0x6632,0x6051
+ };
+
+ for (i=0;i < 128;i++)
+ for (k=0;k < 8;k++)
+ for (m=0;m < 64;m += 8)
+ BinSumm[i][k+m]=BIN_SCALE-InitBinEsc[k]/(i+2);
+ for (i=0;i < 25;i++)
+ for (k=0;k < 16;k++)
+ SEE2Cont[i][k].init(5*i+10);
+}
+
+
+void ModelPPM::StartModelRare(int MaxOrder)
+{
+ int i, k, m ,Step;
+ EscCount=1;
+/*
+ if (MaxOrder < 2)
+ {
+ memset(CharMask,0,sizeof(CharMask));
+ OrderFall=ModelPPM::MaxOrder;
+ MinContext=MaxContext;
+ while (MinContext->Suffix != NULL)
+ {
+ MinContext=MinContext->Suffix;
+ OrderFall--;
+ }
+ FoundState=MinContext->U.Stats;
+ MinContext=MaxContext;
+ }
+ else
+*/
+ {
+ ModelPPM::MaxOrder=MaxOrder;
+ RestartModelRare();
+ NS2BSIndx[0]=2*0;
+ NS2BSIndx[1]=2*1;
+ memset(NS2BSIndx+2,2*2,9);
+ memset(NS2BSIndx+11,2*3,256-11);
+ for (i=0;i < 3;i++)
+ NS2Indx[i]=i;
+ for (m=i, k=Step=1;i < 256;i++)
+ {
+ NS2Indx[i]=m;
+ if ( !--k )
+ {
+ k = ++Step;
+ m++;
+ }
+ }
+ memset(HB2Flag,0,0x40);
+ memset(HB2Flag+0x40,0x08,0x100-0x40);
+ DummySEE2Cont.Shift=PERIOD_BITS;
+ }
+}
+
+
+void PPM_CONTEXT::rescale(ModelPPM *Model)
+{
+ int OldNS=NumStats, i=NumStats-1, Adder, EscFreq;
+ STATE* p1, * p;
+ for (p=Model->FoundState;p != U.Stats;p--)
+ _PPMD_SWAP(p[0],p[-1]);
+ U.Stats->Freq += 4;
+ U.SummFreq += 4;
+ EscFreq=U.SummFreq-p->Freq;
+ Adder=(Model->OrderFall != 0);
+ U.SummFreq = (p->Freq=(p->Freq+Adder) >> 1);
+ do
+ {
+ EscFreq -= (++p)->Freq;
+ U.SummFreq += (p->Freq=(p->Freq+Adder) >> 1);
+ if (p[0].Freq > p[-1].Freq)
+ {
+ STATE tmp=*(p1=p);
+ do
+ {
+ p1[0]=p1[-1];
+ } while (--p1 != U.Stats && tmp.Freq > p1[-1].Freq);
+ *p1=tmp;
+ }
+ } while ( --i );
+ if (p->Freq == 0)
+ {
+ do
+ {
+ i++;
+ } while ((--p)->Freq == 0);
+ EscFreq += i;
+ if ((NumStats -= i) == 1)
+ {
+ STATE tmp=*U.Stats;
+ do
+ {
+ tmp.Freq-=(tmp.Freq >> 1);
+ EscFreq>>=1;
+ } while (EscFreq > 1);
+ Model->SubAlloc.FreeUnits(U.Stats,(OldNS+1) >> 1);
+ *(Model->FoundState=&OneState)=tmp; return;
+ }
+ }
+ U.SummFreq += (EscFreq -= (EscFreq >> 1));
+ int n0=(OldNS+1) >> 1, n1=(NumStats+1) >> 1;
+ if (n0 != n1)
+ U.Stats = (STATE*) Model->SubAlloc.ShrinkUnits(U.Stats,n0,n1);
+ Model->FoundState=U.Stats;
+}
+
+
+inline PPM_CONTEXT* ModelPPM::CreateSuccessors(bool Skip,STATE* p1)
+{
+#ifdef __ICL
+ static
+#endif
+ STATE UpState;
+ PPM_CONTEXT* pc=MinContext, * UpBranch=FoundState->Successor;
+ STATE * p, * ps[MAX_O], ** pps=ps;
+ if ( !Skip )
+ {
+ *pps++ = FoundState;
+ if ( !pc->Suffix )
+ goto NO_LOOP;
+ }
+ if ( p1 )
+ {
+ p=p1;
+ pc=pc->Suffix;
+ goto LOOP_ENTRY;
+ }
+ do
+ {
+ pc=pc->Suffix;
+ if (pc->NumStats != 1)
+ {
+ if ((p=pc->U.Stats)->Symbol != FoundState->Symbol)
+ do
+ {
+ p++;
+ } while (p->Symbol != FoundState->Symbol);
+ }
+ else
+ p=&(pc->OneState);
+LOOP_ENTRY:
+ if (p->Successor != UpBranch)
+ {
+ pc=p->Successor;
+ break;
+ }
+ *pps++ = p;
+ } while ( pc->Suffix );
+NO_LOOP:
+ if (pps == ps)
+ return pc;
+ UpState.Symbol=*(byte*) UpBranch;
+ UpState.Successor=(PPM_CONTEXT*) (((byte*) UpBranch)+1);
+ if (pc->NumStats != 1)
+ {
+ if ((byte*) pc <= SubAlloc.pText)
+ return(NULL);
+ if ((p=pc->U.Stats)->Symbol != UpState.Symbol)
+ do
+ {
+ p++;
+ } while (p->Symbol != UpState.Symbol);
+ uint cf=p->Freq-1;
+ uint s0=pc->U.SummFreq-pc->NumStats-cf;
+ UpState.Freq=1+((2*cf <= s0)?(5*cf > s0):((2*cf+3*s0-1)/(2*s0)));
+ }
+ else
+ UpState.Freq=pc->OneState.Freq;
+ do
+ {
+ pc = pc->createChild(this,*--pps,UpState);
+ if ( !pc )
+ return NULL;
+ } while (pps != ps);
+ return pc;
+}
+
+
+inline void ModelPPM::UpdateModel()
+{
+ STATE fs = *FoundState, *p = NULL;
+ PPM_CONTEXT *pc, *Successor;
+ uint ns1, ns, cf, sf, s0;
+ if (fs.Freq < MAX_FREQ/4 && (pc=MinContext->Suffix) != NULL)
+ {
+ if (pc->NumStats != 1)
+ {
+ if ((p=pc->U.Stats)->Symbol != fs.Symbol)
+ {
+ do
+ {
+ p++;
+ } while (p->Symbol != fs.Symbol);
+ if (p[0].Freq >= p[-1].Freq)
+ {
+ _PPMD_SWAP(p[0],p[-1]);
+ p--;
+ }
+ }
+ if (p->Freq < MAX_FREQ-9)
+ {
+ p->Freq += 2;
+ pc->U.SummFreq += 2;
+ }
+ }
+ else
+ {
+ p=&(pc->OneState);
+ p->Freq += (p->Freq < 32);
+ }
+ }
+ if ( !OrderFall )
+ {
+ MinContext=MaxContext=FoundState->Successor=CreateSuccessors(TRUE,p);
+ if ( !MinContext )
+ goto RESTART_MODEL;
+ return;
+ }
+ *SubAlloc.pText++ = fs.Symbol;
+ Successor = (PPM_CONTEXT*) SubAlloc.pText;
+ if (SubAlloc.pText >= SubAlloc.FakeUnitsStart)
+ goto RESTART_MODEL;
+ if ( fs.Successor )
+ {
+ if ((byte*) fs.Successor <= SubAlloc.pText &&
+ (fs.Successor=CreateSuccessors(FALSE,p)) == NULL)
+ goto RESTART_MODEL;
+ if ( !--OrderFall )
+ {
+ Successor=fs.Successor;
+ SubAlloc.pText -= (MaxContext != MinContext);
+ }
+ }
+ else
+ {
+ FoundState->Successor=Successor;
+ fs.Successor=MinContext;
+ }
+ s0=MinContext->U.SummFreq-(ns=MinContext->NumStats)-(fs.Freq-1);
+ for (pc=MaxContext;pc != MinContext;pc=pc->Suffix)
+ {
+ if ((ns1=pc->NumStats) != 1)
+ {
+ if ((ns1 & 1) == 0)
+ {
+ pc->U.Stats=(STATE*) SubAlloc.ExpandUnits(pc->U.Stats,ns1 >> 1);
+ if ( !pc->U.Stats )
+ goto RESTART_MODEL;
+ }
+ pc->U.SummFreq += (2*ns1 < ns)+2*((4*ns1 <= ns) & (pc->U.SummFreq <= 8*ns1));
+ }
+ else
+ {
+ p=(STATE*) SubAlloc.AllocUnits(1);
+ if ( !p )
+ goto RESTART_MODEL;
+ *p=pc->OneState;
+ pc->U.Stats=p;
+ if (p->Freq < MAX_FREQ/4-1)
+ p->Freq += p->Freq;
+ else
+ p->Freq = MAX_FREQ-4;
+ pc->U.SummFreq=p->Freq+InitEsc+(ns > 3);
+ }
+ cf=2*fs.Freq*(pc->U.SummFreq+6);
+ sf=s0+pc->U.SummFreq;
+ if (cf < 6*sf)
+ {
+ cf=1+(cf > sf)+(cf >= 4*sf);
+ pc->U.SummFreq += 3;
+ }
+ else
+ {
+ cf=4+(cf >= 9*sf)+(cf >= 12*sf)+(cf >= 15*sf);
+ pc->U.SummFreq += cf;
+ }
+ p=pc->U.Stats+ns1;
+ p->Successor=Successor;
+ p->Symbol = fs.Symbol;
+ p->Freq = cf;
+ pc->NumStats=++ns1;
+ }
+ MaxContext=MinContext=fs.Successor;
+ return;
+RESTART_MODEL:
+ RestartModelRare();
+ EscCount=0;
+}
+
+
+// Tabulated escapes for exponential symbol distribution
+static const byte ExpEscape[16]={ 25,14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
+#define GET_MEAN(SUMM,SHIFT,ROUND) ((SUMM+(1 << (SHIFT-ROUND))) >> (SHIFT))
+
+
+
+inline void PPM_CONTEXT::decodeBinSymbol(ModelPPM *Model)
+{
+ STATE& rs=OneState;
+ Model->HiBitsFlag=Model->HB2Flag[Model->FoundState->Symbol];
+ ushort& bs=Model->BinSumm[rs.Freq-1][Model->PrevSuccess+
+ Model->NS2BSIndx[Suffix->NumStats-1]+
+ Model->HiBitsFlag+2*Model->HB2Flag[rs.Symbol]+
+ ((Model->RunLength >> 26) & 0x20)];
+ if (Model->Coder.GetCurrentShiftCount(TOT_BITS) < bs)
+ {
+ Model->FoundState=&rs;
+ rs.Freq += (rs.Freq < 128);
+ Model->Coder.SubRange.LowCount=0;
+ Model->Coder.SubRange.HighCount=bs;
+ bs = SHORT16(bs+INTERVAL-GET_MEAN(bs,PERIOD_BITS,2));
+ Model->PrevSuccess=1;
+ Model->RunLength++;
+ }
+ else
+ {
+ Model->Coder.SubRange.LowCount=bs;
+ bs = SHORT16(bs-GET_MEAN(bs,PERIOD_BITS,2));
+ Model->Coder.SubRange.HighCount=BIN_SCALE;
+ Model->InitEsc=ExpEscape[bs >> 10];
+ Model->NumMasked=1;
+ Model->CharMask[rs.Symbol]=Model->EscCount;
+ Model->PrevSuccess=0;
+ Model->FoundState=NULL;
+ }
+}
+
+
+inline void PPM_CONTEXT::update1(ModelPPM *Model,STATE* p)
+{
+ (Model->FoundState=p)->Freq += 4;
+ U.SummFreq += 4;
+ if (p[0].Freq > p[-1].Freq)
+ {
+ _PPMD_SWAP(p[0],p[-1]);
+ Model->FoundState=--p;
+ if (p->Freq > MAX_FREQ)
+ rescale(Model);
+ }
+}
+
+
+
+
+inline bool PPM_CONTEXT::decodeSymbol1(ModelPPM *Model)
+{
+ Model->Coder.SubRange.scale=U.SummFreq;
+ STATE* p=U.Stats;
+ int i, HiCnt;
+ int count=Model->Coder.GetCurrentCount();
+ if (count>=Model->Coder.SubRange.scale)
+ return(false);
+ if (count < (HiCnt=p->Freq))
+ {
+ Model->PrevSuccess=(2*(Model->Coder.SubRange.HighCount=HiCnt) > Model->Coder.SubRange.scale);
+ Model->RunLength += Model->PrevSuccess;
+ (Model->FoundState=p)->Freq=(HiCnt += 4);
+ U.SummFreq += 4;
+ if (HiCnt > MAX_FREQ)
+ rescale(Model);
+ Model->Coder.SubRange.LowCount=0;
+ return(true);
+ }
+ else
+ if (Model->FoundState==NULL)
+ return(false);
+ Model->PrevSuccess=0;
+ i=NumStats-1;
+ while ((HiCnt += (++p)->Freq) <= count)
+ if (--i == 0)
+ {
+ Model->HiBitsFlag=Model->HB2Flag[Model->FoundState->Symbol];
+ Model->Coder.SubRange.LowCount=HiCnt;
+ Model->CharMask[p->Symbol]=Model->EscCount;
+ i=(Model->NumMasked=NumStats)-1;
+ Model->FoundState=NULL;
+ do
+ {
+ Model->CharMask[(--p)->Symbol]=Model->EscCount;
+ } while ( --i );
+ Model->Coder.SubRange.HighCount=Model->Coder.SubRange.scale;
+ return(true);
+ }
+ Model->Coder.SubRange.LowCount=(Model->Coder.SubRange.HighCount=HiCnt)-p->Freq;
+ update1(Model,p);
+ return(true);
+}
+
+
+inline void PPM_CONTEXT::update2(ModelPPM *Model,STATE* p)
+{
+ (Model->FoundState=p)->Freq += 4;
+ U.SummFreq += 4;
+ if (p->Freq > MAX_FREQ)
+ rescale(Model);
+ Model->EscCount++;
+ Model->RunLength=Model->InitRL;
+}
+
+
+inline SEE2_CONTEXT* PPM_CONTEXT::makeEscFreq2(ModelPPM *Model,int Diff)
+{
+ SEE2_CONTEXT* psee2c;
+ if (NumStats != 256)
+ {
+ psee2c=Model->SEE2Cont[Model->NS2Indx[Diff-1]]+
+ (Diff < Suffix->NumStats-NumStats)+
+ 2*(U.SummFreq < 11*NumStats)+4*(Model->NumMasked > Diff)+
+ Model->HiBitsFlag;
+ Model->Coder.SubRange.scale=psee2c->getMean();
+ }
+ else
+ {
+ psee2c=&Model->DummySEE2Cont;
+ Model->Coder.SubRange.scale=1;
+ }
+ return psee2c;
+}
+
+
+
+
+inline bool PPM_CONTEXT::decodeSymbol2(ModelPPM *Model)
+{
+ int count, HiCnt, i=NumStats-Model->NumMasked;
+ SEE2_CONTEXT* psee2c=makeEscFreq2(Model,i);
+ STATE* ps[256], ** pps=ps, * p=U.Stats-1;
+ HiCnt=0;
+ do
+ {
+ do
+ {
+ p++;
+ } while (Model->CharMask[p->Symbol] == Model->EscCount);
+ HiCnt += p->Freq;
+ *pps++ = p;
+ } while ( --i );
+ Model->Coder.SubRange.scale += HiCnt;
+ count=Model->Coder.GetCurrentCount();
+ if (count>=Model->Coder.SubRange.scale)
+ return(false);
+ p=*(pps=ps);
+ if (count < HiCnt)
+ {
+ HiCnt=0;
+ while ((HiCnt += p->Freq) <= count)
+ p=*++pps;
+ Model->Coder.SubRange.LowCount = (Model->Coder.SubRange.HighCount=HiCnt)-p->Freq;
+ psee2c->update();
+ update2(Model,p);
+ }
+ else
+ {
+ Model->Coder.SubRange.LowCount=HiCnt;
+ Model->Coder.SubRange.HighCount=Model->Coder.SubRange.scale;
+ i=NumStats-Model->NumMasked;
+ pps--;
+ do
+ {
+ Model->CharMask[(*++pps)->Symbol]=Model->EscCount;
+ } while ( --i );
+ psee2c->Summ += Model->Coder.SubRange.scale;
+ Model->NumMasked = NumStats;
+ }
+ return(true);
+}
+
+
+inline void ModelPPM::ClearMask()
+{
+ EscCount=1;
+ memset(CharMask,0,sizeof(CharMask));
+}
+
+
+
+
+bool ModelPPM::DecodeInit(Unpack *UnpackRead,int &EscChar)
+{
+ int MaxOrder=UnpackRead->GetChar();
+
+ // Igor Pavlov
+ bool Reset = ((MaxOrder & 0x20) != 0);
+
+ int MaxMB;
+ if (Reset)
+ MaxMB=UnpackRead->GetChar();
+ else
+ if (SubAlloc.GetAllocatedMemory()==0)
+ return(false);
+ if (MaxOrder & 0x40)
+ EscChar=UnpackRead->GetChar();
+ Coder.InitDecoder(UnpackRead);
+ if (Reset)
+ {
+ MaxOrder=(MaxOrder & 0x1f)+1;
+ if (MaxOrder>16)
+ MaxOrder=16+(MaxOrder-16)*3;
+ if (MaxOrder==1)
+ {
+ SubAlloc.StopSubAllocator();
+ return(false);
+ }
+ SubAlloc.StartSubAllocator(MaxMB+1);
+ StartModelRare(MaxOrder);
+ }
+ return(MinContext!=NULL);
+}
+
+
+int ModelPPM::DecodeChar()
+{
+ if ((byte*)MinContext <= SubAlloc.pText || (byte*)MinContext>SubAlloc.HeapEnd)
+ return(-1);
+ if (MinContext->NumStats != 1)
+ {
+ if (!MinContext->decodeSymbol1(this))
+ return(-1);
+ }
+ else
+ MinContext->decodeBinSymbol(this);
+ Coder.Decode();
+ while ( !FoundState )
+ {
+ ARI_DEC_NORMALIZE(Coder.code,Coder.low,Coder.range,Coder.UnpackRead);
+ do
+ {
+ OrderFall++;
+ MinContext=MinContext->Suffix;
+ if ((byte*)MinContext <= SubAlloc.pText || (byte*)MinContext>SubAlloc.HeapEnd)
+ return(-1);
+ } while (MinContext->NumStats == NumMasked);
+ if (!MinContext->decodeSymbol2(this))
+ return(-1);
+ Coder.Decode();
+ }
+ int Symbol=FoundState->Symbol;
+ if (!OrderFall && (byte*) FoundState->Successor > SubAlloc.pText)
+ MinContext=MaxContext=FoundState->Successor;
+ else
+ {
+ UpdateModel();
+ if (EscCount == 0)
+ ClearMask();
+ }
+ ARI_DEC_NORMALIZE(Coder.code,Coder.low,Coder.range,Coder.UnpackRead);
+ return(Symbol);
+}
diff --git a/7zip/Compress/Rar29/Original/model.hpp b/7zip/Compress/Rar29/Original/model.hpp
new file mode 100755
index 00000000..1c3742b9
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/model.hpp
@@ -0,0 +1,126 @@
+#ifndef _RAR_PPMMODEL_
+#define _RAR_PPMMODEL_
+
+#include "coder.hpp"
+#include "suballoc.hpp"
+
+const int MAX_O=64; /* maximum allowed model order */
+
+const int INT_BITS=7, PERIOD_BITS=7, TOT_BITS=INT_BITS+PERIOD_BITS,
+ INTERVAL=1 << INT_BITS, BIN_SCALE=1 << TOT_BITS, MAX_FREQ=124;
+
+#pragma pack(1)
+
+struct SEE2_CONTEXT
+{ // SEE-contexts for PPM-contexts with masked symbols
+ ushort Summ;
+ byte Shift, Count;
+ void init(int InitVal)
+ {
+ Summ=InitVal << (Shift=PERIOD_BITS-4);
+ Count=4;
+ }
+ uint getMean()
+ {
+ uint RetVal=SHORT16(Summ) >> Shift;
+ Summ -= RetVal;
+ return RetVal+(RetVal == 0);
+ }
+ void update()
+ {
+ if (Shift < PERIOD_BITS && --Count == 0)
+ {
+ Summ += Summ;
+ Count=3 << Shift++;
+ }
+ }
+};
+
+
+class ModelPPM;
+struct PPM_CONTEXT;
+
+struct STATE
+{
+ byte Symbol;
+ byte Freq;
+ PPM_CONTEXT* Successor;
+};
+
+struct FreqData
+{
+ ushort SummFreq;
+ STATE _PACK_ATTR * Stats;
+};
+
+struct PPM_CONTEXT
+{
+ ushort NumStats;
+ union
+ {
+ FreqData U;
+ STATE OneState;
+ };
+
+ PPM_CONTEXT* Suffix;
+ inline void encodeBinSymbol(ModelPPM *Model,int symbol); // MaxOrder:
+ inline void encodeSymbol1(ModelPPM *Model,int symbol); // ABCD context
+ inline void encodeSymbol2(ModelPPM *Model,int symbol); // BCD suffix
+ inline void decodeBinSymbol(ModelPPM *Model); // BCDE successor
+ inline bool decodeSymbol1(ModelPPM *Model); // other orders:
+ inline bool decodeSymbol2(ModelPPM *Model); // BCD context
+ inline void update1(ModelPPM *Model,STATE* p); // CD suffix
+ inline void update2(ModelPPM *Model,STATE* p); // BCDE successor
+ void rescale(ModelPPM *Model);
+ inline PPM_CONTEXT* createChild(ModelPPM *Model,STATE* pStats,STATE& FirstState);
+ inline SEE2_CONTEXT* makeEscFreq2(ModelPPM *Model,int Diff);
+};
+#ifdef _AIX
+#pragma pack(pop)
+#else
+#pragma pack()
+#endif
+
+const uint UNIT_SIZE=sizeof(PPM_CONTEXT);
+const uint FIXED_UNIT_SIZE=12;
+
+/*
+inline PPM_CONTEXT::PPM_CONTEXT(STATE* pStats,PPM_CONTEXT* ShorterContext):
+ NumStats(1), Suffix(ShorterContext) { pStats->Successor=this; }
+inline PPM_CONTEXT::PPM_CONTEXT(): NumStats(0) {}
+*/
+
+template <class T>
+inline void _PPMD_SWAP(T& t1,T& t2) { T tmp=t1; t1=t2; t2=tmp; }
+
+
+class ModelPPM
+{
+ private:
+ friend struct PPM_CONTEXT;
+
+ _PACK_ATTR SEE2_CONTEXT SEE2Cont[25][16], DummySEE2Cont;
+
+ struct PPM_CONTEXT *MinContext, *MedContext, *MaxContext;
+ STATE* FoundState; // found next state transition
+ int NumMasked, InitEsc, OrderFall, MaxOrder, RunLength, InitRL;
+ byte CharMask[256], NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
+ byte EscCount, PrevSuccess, HiBitsFlag;
+ ushort BinSumm[128][64]; // binary SEE-contexts
+
+ RangeCoder Coder;
+ SubAllocator SubAlloc;
+
+ void RestartModelRare();
+ void StartModelRare(int MaxOrder);
+ inline PPM_CONTEXT* CreateSuccessors(bool Skip,STATE* p1);
+
+ inline void UpdateModel();
+ inline void ClearMask();
+ public:
+ ModelPPM();
+ bool DecodeInit(Unpack *UnpackRead,int &EscChar);
+ int DecodeChar();
+};
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/options.hpp b/7zip/Compress/Rar29/Original/options.hpp
new file mode 100755
index 00000000..b43739f6
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/options.hpp
@@ -0,0 +1,129 @@
+#ifndef _RAR_OPTIONS_
+#define _RAR_OPTIONS_
+
+#define DEFAULT_RECOVERY -1
+
+#define DEFAULT_RECVOLUMES -10
+
+enum PathExclMode {
+ EXCL_NONE,EXCL_BASEPATH,EXCL_SKIPWHOLEPATH,EXCL_SAVEFULLPATH,
+ EXCL_SKIPABSPATH,EXCL_ABSPATH
+};
+enum {SOLID_NONE=0,SOLID_NORMAL=1,SOLID_COUNT=2,SOLID_FILEEXT=4,
+ SOLID_VOLUME_DEPENDENT=8,SOLID_VOLUME_INDEPENDENT=16};
+enum {ARCTIME_NONE,ARCTIME_KEEP,ARCTIME_LATEST};
+enum EXTTIME_MODE {
+ EXTTIME_NONE,EXTTIME_1S,EXTTIME_HIGH1,EXTTIME_HIGH2,EXTTIME_HIGH3
+};
+enum {NAMES_ORIGINALCASE,NAMES_UPPERCASE,NAMES_LOWERCASE};
+enum MESSAGE_TYPE {MSG_STDOUT,MSG_STDERR,MSG_ERRONLY,MSG_NULL};
+enum OVERWRITE_MODE { OVERWRITE_ASK,OVERWRITE_ALL,OVERWRITE_NONE};
+
+#define MAX_FILTERS 16
+enum FilterState {FILTER_DEFAULT=0,FILTER_AUTO,FILTER_FORCE,FILTER_DISABLE};
+
+
+struct FilterMode
+{
+ FilterState State;
+ int Param1;
+ int Param2;
+};
+
+
+class RAROptions
+{
+ public:
+ RAROptions();
+ ~RAROptions();
+ void Init();
+
+ uint ExclFileAttr;
+ uint InclFileAttr;
+ bool InclAttrSet;
+ uint WinSize;
+ char TempPath[NM];
+ char SFXModule[NM];
+ char ExtrPath[NM];
+ wchar ExtrPathW[NM];
+ char CommentFile[NM];
+ char ArcPath[NM];
+ char Password[MAXPASSWORD];
+ bool EncryptHeaders;
+ char LogName[NM];
+ MESSAGE_TYPE MsgStream;
+ bool Sound;
+ OVERWRITE_MODE Overwrite;
+ int Method;
+ int Recovery;
+ int RecVolNumber;
+ bool DisablePercentage;
+ bool DisableCopyright;
+ bool DisableDone;
+ int Solid;
+ int SolidCount;
+ bool ClearArc;
+ bool AddArcOnly;
+ bool AV;
+ bool DisableComment;
+ bool FreshFiles;
+ bool UpdateFiles;
+ PathExclMode ExclPath;
+ int Recurse;
+ Int64 VolSize;
+ Array<Int64> NextVolSizes;
+ int CurVolNum;
+ bool AllYes;
+ bool DisableViewAV;
+ bool DisableSortSolid;
+ int ArcTime;
+ int ConvertNames;
+ bool ProcessOwners;
+ bool SaveLinks;
+ int Priority;
+ int SleepTime;
+ bool KeepBroken;
+ bool EraseDisk;
+ bool OpenShared;
+ bool ExclEmptyDir;
+ bool DeleteFiles;
+ bool SyncFiles;
+ bool GenerateArcName;
+ char GenerateMask[80];
+ bool ProcessEA;
+ bool SaveStreams;
+ bool SetCompressedAttr;
+ uint FileTimeOlder;
+ uint FileTimeNewer;
+ RarTime FileTimeBefore;
+ RarTime FileTimeAfter;
+ bool OldNumbering;
+ bool Lock;
+ bool Test;
+ bool VolumePause;
+ FilterMode FilterModes[MAX_FILTERS];
+ char EmailTo[NM];
+ int VersionControl;
+ bool NoEndBlock;
+ bool AppendArcNameToPath;
+ bool Shutdown;
+ EXTTIME_MODE xmtime;
+ EXTTIME_MODE xctime;
+ EXTTIME_MODE xatime;
+ EXTTIME_MODE xarctime;
+ char CompressStdin[NM];
+
+
+
+#ifdef RARDLL
+ char DllDestName[NM];
+ wchar DllDestNameW[NM];
+ int DllOpMode;
+ int DllError;
+ LONG UserData;
+ UNRARCALLBACK Callback;
+ CHANGEVOLPROC ChangeVolProc;
+ PROCESSDATAPROC ProcessDataProc;
+#endif
+};
+#endif
diff --git a/7zip/Compress/Rar29/Original/os.hpp b/7zip/Compress/Rar29/Original/os.hpp
new file mode 100755
index 00000000..29da46a1
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/os.hpp
@@ -0,0 +1,235 @@
+#ifndef _RAR_OS_
+#define _RAR_OS_
+
+#define FALSE 0
+#define TRUE 1
+
+#ifdef __EMX__
+ #define INCL_BASE
+#endif
+
+#if defined(_WIN_32) || defined(_EMX)
+#define ENABLE_BAD_ALLOC
+#endif
+
+
+#if defined(_WIN_32) || defined(_EMX)
+
+#define LITTLE_ENDIAN
+#define NM 1024
+
+#ifdef _WIN_32
+
+// Igor Pavlov
+#ifndef STRICT
+#define STRICT
+#endif
+
+#undef WINVER
+#undef _WIN32_WINNT
+#define WINVER 0x0400
+#define _WIN32_WINNT 0x0300
+
+#define WIN32_LEAN_AND_MEAN
+
+#include <windows.h>
+#include <prsht.h>
+
+#ifndef _WIN_CE
+#include <winioctl.h>
+#endif
+
+#endif
+
+#ifndef _WIN_CE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dos.h>
+#endif
+
+#if !defined(_EMX) && !defined(_MSC_VER) && !defined(_WIN_CE)
+ #define ENABLE_MKTEMP
+ #include <dir.h>
+#endif
+#ifdef _MSC_VER
+ #define for if (0) ; else for
+#ifndef _WIN_CE
+ #include <direct.h>
+#endif
+#else
+ #include <dirent.h>
+#endif
+
+#ifndef _WIN_CE
+#include <share.h>
+#endif
+
+#if defined(ENABLE_BAD_ALLOC) && !defined(_WIN_CE)
+ #include <new.h>
+#endif
+
+#ifdef _EMX
+ #include <unistd.h>
+ #include <pwd.h>
+ #include <grp.h>
+ #include <errno.h>
+ #ifdef _DJGPP
+ #include <utime.h>
+ #else
+ #include <os2.h>
+ #include <sys/utime.h>
+ #include <emx/syscalls.h>
+ #endif
+#else
+ #if defined(_MSC_VER) || defined(__MINGW32__)
+ #include <exception>
+ #else
+ #include <except.h>
+ #endif
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
+#ifndef _WIN_CE
+ #include <fcntl.h>
+ #include <dos.h>
+ #include <io.h>
+ #include <time.h>
+ #include <signal.h>
+#endif
+
+/*
+#ifdef _WIN_32
+#pragma hdrstop
+#endif
+*/
+
+#define ENABLE_ACCESS
+
+#define DefConfigName "rar.ini"
+#define DefLogName "rar.log"
+
+
+#define PATHDIVIDER "\\"
+#define PATHDIVIDERW L"\\"
+#define CPATHDIVIDER '\\'
+#define MASKALL "*"
+#define MASKALLW L"*"
+
+#define READBINARY "rb"
+#define READTEXT "rt"
+#define UPDATEBINARY "r+b"
+#define CREATEBINARY "w+b"
+#define APPENDTEXT "at"
+
+#if defined(_WIN_32)
+ #ifdef _MSC_VER
+ #define _stdfunction __cdecl
+ #else
+ #define _stdfunction _USERENTRY
+ #endif
+#else
+ #define _stdfunction
+#endif
+
+#endif
+
+#ifdef _UNIX
+
+#define NM 1024
+
+#ifdef _BEOS
+#include <be/kernel/fs_info.h>
+#include <be/kernel/fs_attr.h>
+#endif
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#if defined(__QNXNTO__)
+ #include <sys/param.h>
+#endif
+#if defined(__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined(__APPLE__)
+ #include <sys/param.h>
+ #include <sys/mount.h>
+#else
+#endif
+#include <pwd.h>
+#include <grp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dirent.h>
+#include <time.h>
+#include <signal.h>
+#include <utime.h>
+#include <locale.h>
+
+#ifdef S_IFLNK
+#define SAVE_LINKS
+#endif
+
+#define ENABLE_ACCESS
+
+#define DefConfigName ".rarrc"
+#define DefLogName ".rarlog"
+
+
+#define PATHDIVIDER "/"
+#define PATHDIVIDERW L"/"
+#define CPATHDIVIDER '/'
+#define MASKALL "*"
+#define MASKALLW L"*"
+
+#define READBINARY "r"
+#define READTEXT "r"
+#define UPDATEBINARY "r+"
+#define CREATEBINARY "w+"
+#define APPENDTEXT "a"
+
+#define _stdfunction
+
+#ifdef _APPLE
+ #ifndef BIG_ENDIAN
+ #define BIG_ENDIAN
+ #endif
+ #ifdef LITTLE_ENDIAN
+ #undef LITTLE_ENDIAN
+ #endif
+#endif
+
+#if defined(__sparc) || defined(sparc) || defined(__hpux)
+ #ifndef BIG_ENDIAN
+ #define BIG_ENDIAN
+ #endif
+#endif
+
+#endif
+
+typedef const char* MSGID;
+
+#define safebuf static
+
+#if defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
+ #if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN
+ #undef LITTLE_ENDIAN
+ #elif defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN
+ #undef BIG_ENDIAN
+ #else
+ #error "Both LITTLE_ENDIAN and BIG_ENDIAN are defined. Undef something one"
+ #endif
+#endif
+
+#if !defined(BIG_ENDIAN) && !defined(_WIN_CE) && defined(_WIN_32)
+#define ALLOW_NOT_ALIGNED_INT
+#endif
+
+#endif // _RAR_OS_
diff --git a/7zip/Compress/Rar29/Original/pathfn.hpp b/7zip/Compress/Rar29/Original/pathfn.hpp
new file mode 100755
index 00000000..c6d2d9b9
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/pathfn.hpp
@@ -0,0 +1,44 @@
+#ifndef _RAR_PATHFN_
+#define _RAR_PATHFN_
+
+char* PointToName(const char *Path);
+wchar* PointToName(const wchar *Path);
+char* PointToLastChar(const char *Path);
+char* ConvertPath(const char *SrcPath,char *DestPath);
+wchar* ConvertPath(const wchar *SrcPath,wchar *DestPath);
+void SetExt(char *Name,const char *NewExt);
+void SetExt(wchar *Name,const wchar *NewExt);
+void SetSFXExt(char *SFXName);
+void SetSFXExt(wchar *SFXName);
+char *GetExt(const char *Name);
+wchar *GetExt(const wchar *Name);
+bool CmpExt(const char *Name,const char *Ext);
+bool IsWildcard(const char *Str,const wchar *StrW=NULL);
+bool IsPathDiv(int Ch);
+bool IsDriveDiv(int Ch);
+int GetPathDisk(const char *Path);
+void AddEndSlash(char *Path);
+void AddEndSlash(wchar *Path);
+void GetFilePath(const char *FullName,char *Path);
+void GetFilePath(const wchar *FullName,wchar *Path);
+void RemoveNameFromPath(char *Path);
+void RemoveNameFromPath(wchar *Path);
+bool EnumConfigPaths(char *Path,int Number);
+void GetConfigName(const char *Name,char *FullName,bool CheckExist);
+char* GetVolNumPart(char *ArcName);
+void NextVolumeName(char *ArcName,bool OldNumbering);
+bool IsNameUsable(const char *Name);
+void MakeNameUsable(char *Name,bool Extended);
+char* UnixSlashToDos(char *SrcName,char *DestName=NULL,uint MaxLength=NM);
+char* DosSlashToUnix(char *SrcName,char *DestName=NULL,uint MaxLength=NM);
+bool IsFullPath(const char *Path);
+bool IsDiskLetter(const char *Path);
+void GetPathRoot(const char *Path,char *Root);
+int ParseVersionFileName(char *Name,wchar *NameW,bool Truncate);
+char* VolNameToFirstName(const char *VolName,char *FirstName,bool NewNumbering);
+wchar* GetWideName(const char *Name,const wchar *NameW,wchar *DestW);
+
+
+inline char* GetOutputName(const char *Name) {return((char *)Name);};
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/rar.hpp b/7zip/Compress/Rar29/Original/rar.hpp
new file mode 100755
index 00000000..70b6826b
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/rar.hpp
@@ -0,0 +1,80 @@
+#ifndef _RAR_RARCOMMON_
+#define _RAR_RARCOMMON_
+
+#include "raros.hpp"
+#include "os.hpp"
+
+
+#ifdef RARDLL
+#include "dll.hpp"
+#endif
+
+#ifndef _WIN_CE
+#include "version.hpp"
+#endif
+#include "rartypes.hpp"
+#include "rardefs.hpp"
+#include "rarlang.hpp"
+#include "int64.hpp"
+#include "unicode.hpp"
+#include "errhnd.hpp"
+#include "array.hpp"
+#include "timefn.hpp"
+#include "headers.hpp"
+#include "rarfn.hpp"
+#include "pathfn.hpp"
+#include "strfn.hpp"
+#include "strlist.hpp"
+#include "file.hpp"
+#include "sha1.hpp"
+#include "crc.hpp"
+#include "rijndael.hpp"
+#include "crypt.hpp"
+#include "filefn.hpp"
+#include "filestr.hpp"
+#include "find.hpp"
+#include "scantree.hpp"
+#include "savepos.hpp"
+#include "getbits.hpp"
+#include "rdwrfn.hpp"
+#include "options.hpp"
+#include "archive.hpp"
+#include "match.hpp"
+#include "cmddata.hpp"
+#include "filcreat.hpp"
+#include "consio.hpp"
+#include "system.hpp"
+#include "isnt.hpp"
+#include "log.hpp"
+#include "rawread.hpp"
+#include "encname.hpp"
+#include "resource.hpp"
+#include "compress.hpp"
+
+
+#include "rarvm.hpp"
+#include "model.hpp"
+
+
+#include "unpack.hpp"
+
+
+#include "extinfo.hpp"
+#include "extract.hpp"
+
+
+
+#include "list.hpp"
+
+
+
+#include "rs.hpp"
+#include "recvol.hpp"
+#include "volume.hpp"
+#include "smallfn.hpp"
+#include "ulinks.hpp"
+
+#include "global.hpp"
+
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/rardefs.hpp b/7zip/Compress/Rar29/Original/rardefs.hpp
new file mode 100755
index 00000000..51661658
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/rardefs.hpp
@@ -0,0 +1,21 @@
+#ifndef _RAR_DEFS_
+#define _RAR_DEFS_
+
+#define Min(x,y) (((x)<(y)) ? (x):(y))
+#define Max(x,y) (((x)>(y)) ? (x):(y))
+
+#define MAXPASSWORD 128
+
+#define DefSFXName "default.sfx"
+#define DefSortListName "rarfiles.lst"
+
+#ifndef FA_RDONLY
+ #define FA_RDONLY 0x01
+ #define FA_HIDDEN 0x02
+ #define FA_SYSTEM 0x04
+ #define FA_LABEL 0x08
+ #define FA_DIREC 0x10
+ #define FA_ARCH 0x20
+#endif
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/rarfn.hpp b/7zip/Compress/Rar29/Original/rarfn.hpp
new file mode 100755
index 00000000..05ffdbcf
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/rarfn.hpp
@@ -0,0 +1,7 @@
+#ifndef _RAR_FN_
+#define _RAR_FN_
+
+void RARInitData();
+
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/rarlang.hpp b/7zip/Compress/Rar29/Original/rarlang.hpp
new file mode 100755
index 00000000..6151d15a
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/rarlang.hpp
@@ -0,0 +1,10 @@
+#ifndef _RAR_LANG_
+#define _RAR_LANG_
+
+ #ifdef USE_RC
+ #include "rarres.hpp"
+ #else
+ #include "loclang.hpp"
+ #endif
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/raros.hpp b/7zip/Compress/Rar29/Original/raros.hpp
new file mode 100755
index 00000000..e6867981
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/raros.hpp
@@ -0,0 +1,41 @@
+#ifndef _RAR_RAROS_
+#define _RAR_RAROS_
+
+#ifdef __EMX__
+ #define _EMX
+#endif
+
+#ifdef __DJGPP__
+ #define _DJGPP
+ #define _EMX
+#endif
+
+#if defined(__WIN32__) || defined(_WIN32)
+ #define _WIN_32
+#endif
+
+#ifdef _WIN32_WCE
+ #define _WIN_32
+ #define _WIN_CE
+ #ifdef WM_FILECHANGEINFO
+ #define PC2002
+ #else
+ #undef PC2002
+ #endif
+#endif
+
+#ifdef __BEOS__
+ #define _UNIX
+ #define _BEOS
+#endif
+
+#ifdef __APPLE__
+ #define _UNIX
+ #define _APPLE
+#endif
+
+#if !defined(_EMX) && !defined(_WIN_32) && !defined(_BEOS) && !defined(_APPLE)
+ #define _UNIX
+#endif
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/rartypes.hpp b/7zip/Compress/Rar29/Original/rartypes.hpp
new file mode 100755
index 00000000..9e4f640f
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/rartypes.hpp
@@ -0,0 +1,21 @@
+#ifndef _RAR_TYPES_
+#define _RAR_TYPES_
+
+typedef unsigned char byte; //8 bits
+typedef unsigned short ushort; //preferably 16 bits, but can be more
+typedef unsigned int uint; //32 bits or more
+
+typedef unsigned int uint32; //32 bits exactly
+typedef int sint32; //signed 32 bits exactly
+#define PRESENT_INT32
+
+#if defined(_WIN_32) || defined(__GNUC__) || defined(__sgi) || defined(_AIX) || defined(__sun) || defined(__hpux)
+typedef wchar_t wchar;
+#else
+typedef ushort wchar;
+#endif
+
+#define SHORT16(x) (sizeof(ushort)==2 ? (ushort)(x):((x)&0xffff))
+#define UINT32(x) (sizeof(uint32)==4 ? (uint32)(x):((x)&0xffffffff))
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/rarvm.cpp b/7zip/Compress/Rar29/Original/rarvm.cpp
new file mode 100755
index 00000000..09585f5a
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/rarvm.cpp
@@ -0,0 +1,1050 @@
+#include "rar.hpp"
+
+#include "rarvmtbl.cpp"
+
+RarVM::RarVM()
+{
+ Mem=NULL;
+}
+
+
+RarVM::~RarVM()
+{
+ delete[] Mem;
+}
+
+
+void RarVM::Init()
+{
+ if (Mem==NULL)
+ Mem=new byte[VM_MEMSIZE+4];
+}
+
+
+inline uint RarVM::GetValue(bool ByteMode,uint *Addr)
+{
+ if (ByteMode)
+ return(*(byte *)Addr);
+ else
+ {
+#if defined(BIG_ENDIAN) || !defined(ALLOW_NOT_ALIGNED_INT)
+ byte *B=(byte *)Addr;
+ return UINT32((uint)B[0]|((uint)B[1]<<8)|((uint)B[2]<<16)|((uint)B[3]<<24));
+#else
+ return UINT32(*Addr);
+#endif
+ }
+}
+
+#if defined(BIG_ENDIAN) || !defined(ALLOW_NOT_ALIGNED_INT)
+ #define GET_VALUE(ByteMode,Addr) GetValue(ByteMode,(uint *)Addr)
+#else
+ #define GET_VALUE(ByteMode,Addr) ((ByteMode) ? (*(byte *)(Addr)):UINT32(*(uint *)(Addr)))
+#endif
+
+
+inline void RarVM::SetValue(bool ByteMode,uint *Addr,uint Value)
+{
+ if (ByteMode)
+ *(byte *)Addr=Value;
+ else
+ {
+#if defined(BIG_ENDIAN) || !defined(ALLOW_NOT_ALIGNED_INT) || !defined(PRESENT_INT32)
+ ((byte *)Addr)[0]=(byte)Value;
+ ((byte *)Addr)[1]=(byte)(Value>>8);
+ ((byte *)Addr)[2]=(byte)(Value>>16);
+ ((byte *)Addr)[3]=(byte)(Value>>24);
+#else
+ *(uint32 *)Addr=Value;
+#endif
+ }
+}
+
+#if defined(BIG_ENDIAN) || !defined(ALLOW_NOT_ALIGNED_INT) || !defined(PRESENT_INT32)
+ #define SET_VALUE(ByteMode,Addr,Value) SetValue(ByteMode,(uint *)Addr,Value)
+#else
+ #define SET_VALUE(ByteMode,Addr,Value) ((ByteMode) ? (*(byte *)(Addr)=(Value)):(*(uint32 *)(Addr)=((uint32)(Value))))
+#endif
+
+
+void RarVM::SetValue(uint *Addr,uint Value)
+{
+ SetValue(false,Addr,Value);
+}
+
+
+inline uint* RarVM::GetOperand(VM_PreparedOperand *CmdOp)
+{
+ if (CmdOp->Type==VM_OPREGMEM)
+ return((uint *)&Mem[(*CmdOp->Addr+CmdOp->Base)&VM_MEMMASK]);
+ else
+ return(CmdOp->Addr);
+}
+
+
+void RarVM::Execute(VM_PreparedProgram *Prg)
+{
+ memcpy(R,Prg->InitR,sizeof(Prg->InitR));
+ unsigned int GlobalSize=Min(Prg->GlobalData.Size(),VM_GLOBALMEMSIZE);
+ if (GlobalSize)
+ memcpy(Mem+VM_GLOBALMEMADDR,&Prg->GlobalData[0],GlobalSize);
+ unsigned int StaticSize=Min(Prg->StaticData.Size(),VM_GLOBALMEMSIZE-GlobalSize);
+ if (StaticSize)
+ memcpy(Mem+VM_GLOBALMEMADDR+GlobalSize,&Prg->StaticData[0],StaticSize);
+
+ R[7]=VM_MEMSIZE;
+ Flags=0;
+
+ VM_PreparedCommand *PreparedCode=Prg->AltCmd ? Prg->AltCmd:&Prg->Cmd[0];
+ if (!ExecuteCode(PreparedCode,Prg->CmdCount))
+ PreparedCode[0].OpCode=VM_RET;
+ uint NewBlockPos=GET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x20])&VM_MEMMASK;
+ uint NewBlockSize=GET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x1c])&VM_MEMMASK;
+ if (NewBlockPos+NewBlockSize>=VM_MEMSIZE)
+ NewBlockPos=NewBlockSize=0;
+ Prg->FilteredData=Mem+NewBlockPos;
+ Prg->FilteredDataSize=NewBlockSize;
+
+ Prg->GlobalData.Reset();
+ uint DataSize=Min(GET_VALUE(false,(uint*)&Mem[VM_GLOBALMEMADDR+0x30]),VM_GLOBALMEMSIZE);
+ if (DataSize!=0)
+ {
+ Prg->GlobalData.Add(DataSize+VM_FIXEDGLOBALSIZE);
+ memcpy(&Prg->GlobalData[0],&Mem[VM_GLOBALMEMADDR],DataSize+VM_FIXEDGLOBALSIZE);
+ }
+}
+
+
+#define SET_IP(IP) \
+ if ((IP)>=CodeSize) \
+ return(true); \
+ if (--MaxOpCount<=0) \
+ return(false); \
+ Cmd=PreparedCode+(IP);
+
+bool RarVM::ExecuteCode(VM_PreparedCommand *PreparedCode,int CodeSize)
+{
+ int MaxOpCount=25000000;
+ VM_PreparedCommand *Cmd=PreparedCode;
+ while (1)
+ {
+ uint *Op1=GetOperand(&Cmd->Op1);
+ uint *Op2=GetOperand(&Cmd->Op2);
+ switch(Cmd->OpCode)
+ {
+#ifndef NORARVM
+ case VM_MOV:
+ SET_VALUE(Cmd->ByteMode,Op1,GET_VALUE(Cmd->ByteMode,Op2));
+ break;
+#ifdef VM_OPTIMIZE
+ case VM_MOVB:
+ SET_VALUE(true,Op1,GET_VALUE(true,Op2));
+ break;
+ case VM_MOVD:
+ SET_VALUE(false,Op1,GET_VALUE(false,Op2));
+ break;
+#endif
+ case VM_CMP:
+ {
+ uint Value1=GET_VALUE(Cmd->ByteMode,Op1);
+ uint Result=UINT32(Value1-GET_VALUE(Cmd->ByteMode,Op2));
+ Flags=Result==0 ? VM_FZ:(Result>Value1)|(Result&VM_FS);
+ }
+ break;
+#ifdef VM_OPTIMIZE
+ case VM_CMPB:
+ {
+ uint Value1=GET_VALUE(true,Op1);
+ uint Result=UINT32(Value1-GET_VALUE(true,Op2));
+ Flags=Result==0 ? VM_FZ:(Result>Value1)|(Result&VM_FS);
+ }
+ break;
+ case VM_CMPD:
+ {
+ uint Value1=GET_VALUE(false,Op1);
+ uint Result=UINT32(Value1-GET_VALUE(false,Op2));
+ Flags=Result==0 ? VM_FZ:(Result>Value1)|(Result&VM_FS);
+ }
+ break;
+#endif
+ case VM_ADD:
+ {
+ uint Value1=GET_VALUE(Cmd->ByteMode,Op1);
+ uint Result=UINT32(Value1+GET_VALUE(Cmd->ByteMode,Op2));
+ Flags=Result==0 ? VM_FZ:(Result<Value1)|(Result&VM_FS);
+ SET_VALUE(Cmd->ByteMode,Op1,Result);
+ }
+ break;
+#ifdef VM_OPTIMIZE
+ case VM_ADDB:
+ SET_VALUE(true,Op1,GET_VALUE(true,Op1)+GET_VALUE(true,Op2));
+ break;
+ case VM_ADDD:
+ SET_VALUE(false,Op1,GET_VALUE(false,Op1)+GET_VALUE(false,Op2));
+ break;
+#endif
+ case VM_SUB:
+ {
+ uint Value1=GET_VALUE(Cmd->ByteMode,Op1);
+ uint Result=UINT32(Value1-GET_VALUE(Cmd->ByteMode,Op2));
+ Flags=Result==0 ? VM_FZ:(Result>Value1)|(Result&VM_FS);
+ SET_VALUE(Cmd->ByteMode,Op1,Result);
+ }
+ break;
+#ifdef VM_OPTIMIZE
+ case VM_SUBB:
+ SET_VALUE(true,Op1,GET_VALUE(true,Op1)-GET_VALUE(true,Op2));
+ break;
+ case VM_SUBD:
+ SET_VALUE(false,Op1,GET_VALUE(false,Op1)-GET_VALUE(false,Op2));
+ break;
+#endif
+ case VM_JZ:
+ if ((Flags & VM_FZ)!=0)
+ {
+ SET_IP(GET_VALUE(false,Op1));
+ continue;
+ }
+ break;
+ case VM_JNZ:
+ if ((Flags & VM_FZ)==0)
+ {
+ SET_IP(GET_VALUE(false,Op1));
+ continue;
+ }
+ break;
+ case VM_INC:
+ {
+ uint Result=UINT32(GET_VALUE(Cmd->ByteMode,Op1)+1);
+ SET_VALUE(Cmd->ByteMode,Op1,Result);
+ Flags=Result==0 ? VM_FZ:Result&VM_FS;
+ }
+ break;
+#ifdef VM_OPTIMIZE
+ case VM_INCB:
+ SET_VALUE(true,Op1,GET_VALUE(true,Op1)+1);
+ break;
+ case VM_INCD:
+ SET_VALUE(false,Op1,GET_VALUE(false,Op1)+1);
+ break;
+#endif
+ case VM_DEC:
+ {
+ uint Result=UINT32(GET_VALUE(Cmd->ByteMode,Op1)-1);
+ SET_VALUE(Cmd->ByteMode,Op1,Result);
+ Flags=Result==0 ? VM_FZ:Result&VM_FS;
+ }
+ break;
+#ifdef VM_OPTIMIZE
+ case VM_DECB:
+ SET_VALUE(true,Op1,GET_VALUE(true,Op1)-1);
+ break;
+ case VM_DECD:
+ SET_VALUE(false,Op1,GET_VALUE(false,Op1)-1);
+ break;
+#endif
+ case VM_JMP:
+ SET_IP(GET_VALUE(false,Op1));
+ continue;
+ case VM_XOR:
+ {
+ uint Result=UINT32(GET_VALUE(Cmd->ByteMode,Op1)^GET_VALUE(Cmd->ByteMode,Op2));
+ Flags=Result==0 ? VM_FZ:Result&VM_FS;
+ SET_VALUE(Cmd->ByteMode,Op1,Result);
+ }
+ break;
+ case VM_AND:
+ {
+ uint Result=UINT32(GET_VALUE(Cmd->ByteMode,Op1)&GET_VALUE(Cmd->ByteMode,Op2));
+ Flags=Result==0 ? VM_FZ:Result&VM_FS;
+ SET_VALUE(Cmd->ByteMode,Op1,Result);
+ }
+ break;
+ case VM_OR:
+ {
+ uint Result=UINT32(GET_VALUE(Cmd->ByteMode,Op1)|GET_VALUE(Cmd->ByteMode,Op2));
+ Flags=Result==0 ? VM_FZ:Result&VM_FS;
+ SET_VALUE(Cmd->ByteMode,Op1,Result);
+ }
+ break;
+ case VM_TEST:
+ {
+ uint Result=UINT32(GET_VALUE(Cmd->ByteMode,Op1)&GET_VALUE(Cmd->ByteMode,Op2));
+ Flags=Result==0 ? VM_FZ:Result&VM_FS;
+ }
+ break;
+ case VM_JS:
+ if ((Flags & VM_FS)!=0)
+ {
+ SET_IP(GET_VALUE(false,Op1));
+ continue;
+ }
+ break;
+ case VM_JNS:
+ if ((Flags & VM_FS)==0)
+ {
+ SET_IP(GET_VALUE(false,Op1));
+ continue;
+ }
+ break;
+ case VM_JB:
+ if ((Flags & VM_FC)!=0)
+ {
+ SET_IP(GET_VALUE(false,Op1));
+ continue;
+ }
+ break;
+ case VM_JBE:
+ if ((Flags & (VM_FC|VM_FZ))!=0)
+ {
+ SET_IP(GET_VALUE(false,Op1));
+ continue;
+ }
+ break;
+ case VM_JA:
+ if ((Flags & (VM_FC|VM_FZ))==0)
+ {
+ SET_IP(GET_VALUE(false,Op1));
+ continue;
+ }
+ break;
+ case VM_JAE:
+ if ((Flags & VM_FC)==0)
+ {
+ SET_IP(GET_VALUE(false,Op1));
+ continue;
+ }
+ break;
+ case VM_PUSH:
+ R[7]-=4;
+ SET_VALUE(false,(uint *)&Mem[R[7]&VM_MEMMASK],GET_VALUE(false,Op1));
+ break;
+ case VM_POP:
+ SET_VALUE(false,Op1,GET_VALUE(false,(uint *)&Mem[R[7] & VM_MEMMASK]));
+ R[7]+=4;
+ break;
+ case VM_CALL:
+ R[7]-=4;
+ SET_VALUE(false,(uint *)&Mem[R[7]&VM_MEMMASK],Cmd-PreparedCode+1);
+ SET_IP(GET_VALUE(false,Op1));
+ continue;
+ case VM_NOT:
+ SET_VALUE(Cmd->ByteMode,Op1,~GET_VALUE(Cmd->ByteMode,Op1));
+ break;
+ case VM_SHL:
+ {
+ uint Value1=GET_VALUE(Cmd->ByteMode,Op1);
+ uint Value2=GET_VALUE(Cmd->ByteMode,Op2);
+ uint Result=UINT32(Value1<<Value2);
+ Flags=(Result==0 ? VM_FZ:(Result&VM_FS))|((Value1<<(Value2-1))&0x80000000 ? VM_FC:0);
+ SET_VALUE(Cmd->ByteMode,Op1,Result);
+ }
+ break;
+ case VM_SHR:
+ {
+ uint Value1=GET_VALUE(Cmd->ByteMode,Op1);
+ uint Value2=GET_VALUE(Cmd->ByteMode,Op2);
+ uint Result=UINT32(Value1>>Value2);
+ Flags=(Result==0 ? VM_FZ:(Result&VM_FS))|((Value1>>(Value2-1))&VM_FC);
+ SET_VALUE(Cmd->ByteMode,Op1,Result);
+ }
+ break;
+ case VM_SAR:
+ {
+ uint Value1=GET_VALUE(Cmd->ByteMode,Op1);
+ uint Value2=GET_VALUE(Cmd->ByteMode,Op2);
+ uint Result=UINT32(((int)Value1)>>Value2);
+ Flags=(Result==0 ? VM_FZ:(Result&VM_FS))|((Value1>>(Value2-1))&VM_FC);
+ SET_VALUE(Cmd->ByteMode,Op1,Result);
+ }
+ break;
+ case VM_NEG:
+ {
+ uint Result=UINT32(-GET_VALUE(Cmd->ByteMode,Op1));
+ Flags=Result==0 ? VM_FZ:VM_FC|(Result&VM_FS);
+ SET_VALUE(Cmd->ByteMode,Op1,Result);
+ }
+ break;
+#ifdef VM_OPTIMIZE
+ case VM_NEGB:
+ SET_VALUE(true,Op1,-GET_VALUE(true,Op1));
+ break;
+ case VM_NEGD:
+ SET_VALUE(false,Op1,-GET_VALUE(false,Op1));
+ break;
+#endif
+ case VM_PUSHA:
+ {
+ const int RegCount=sizeof(R)/sizeof(R[0]);
+ for (int I=0,SP=R[7]-4;I<RegCount;I++,SP-=4)
+ SET_VALUE(false,(uint *)&Mem[SP & VM_MEMMASK],R[I]);
+ R[7]-=RegCount*4;
+ }
+ break;
+ case VM_POPA:
+ {
+ const int RegCount=sizeof(R)/sizeof(R[0]);
+ for (uint I=0,SP=R[7];I<RegCount;I++,SP+=4)
+ R[7-I]=GET_VALUE(false,(uint *)&Mem[SP & VM_MEMMASK]);
+ }
+ break;
+ case VM_PUSHF:
+ R[7]-=4;
+ SET_VALUE(false,(uint *)&Mem[R[7]&VM_MEMMASK],Flags);
+ break;
+ case VM_POPF:
+ Flags=GET_VALUE(false,(uint *)&Mem[R[7] & VM_MEMMASK]);
+ R[7]+=4;
+ break;
+ case VM_MOVZX:
+ SET_VALUE(false,Op1,GET_VALUE(true,Op2));
+ break;
+ case VM_MOVSX:
+ SET_VALUE(false,Op1,(signed char)GET_VALUE(true,Op2));
+ break;
+ case VM_XCHG:
+ {
+ uint Value1=GET_VALUE(Cmd->ByteMode,Op1);
+ SET_VALUE(Cmd->ByteMode,Op1,GET_VALUE(Cmd->ByteMode,Op2));
+ SET_VALUE(Cmd->ByteMode,Op2,Value1);
+ }
+ break;
+ case VM_MUL:
+ {
+ uint Result=GET_VALUE(Cmd->ByteMode,Op1)*GET_VALUE(Cmd->ByteMode,Op2);
+ SET_VALUE(Cmd->ByteMode,Op1,Result);
+ }
+ break;
+ case VM_DIV:
+ {
+ uint Divider=GET_VALUE(Cmd->ByteMode,Op2);
+ if (Divider!=0)
+ {
+ uint Result=GET_VALUE(Cmd->ByteMode,Op1)/Divider;
+ SET_VALUE(Cmd->ByteMode,Op1,Result);
+ }
+ }
+ break;
+ case VM_ADC:
+ {
+ uint Value1=GET_VALUE(Cmd->ByteMode,Op1);
+ uint FC=(Flags&VM_FC);
+ uint Result=UINT32(Value1+GET_VALUE(Cmd->ByteMode,Op2)+FC);
+ Flags=Result==0 ? VM_FZ:(Result<Value1 || Result==Value1 && FC)|(Result&VM_FS);
+ SET_VALUE(Cmd->ByteMode,Op1,Result);
+ }
+ break;
+ case VM_SBB:
+ {
+ uint Value1=GET_VALUE(Cmd->ByteMode,Op1);
+ uint FC=(Flags&VM_FC);
+ uint Result=UINT32(Value1-GET_VALUE(Cmd->ByteMode,Op2)-FC);
+ Flags=Result==0 ? VM_FZ:(Result>Value1 || Result==Value1 && FC)|(Result&VM_FS);
+ SET_VALUE(Cmd->ByteMode,Op1,Result);
+ }
+ break;
+#endif
+ case VM_RET:
+ if (R[7]>=VM_MEMSIZE)
+ return(true);
+ SET_IP(GET_VALUE(false,(uint *)&Mem[R[7] & VM_MEMMASK]));
+ R[7]+=4;
+ continue;
+#ifdef VM_STANDARDFILTERS
+ case VM_STANDARD:
+ ExecuteStandardFilter((VM_StandardFilters)Cmd->Op1.Data);
+ break;
+#endif
+ case VM_PRINT:
+#ifdef DEBUG
+ PrintState(Cmd-PreparedCode);
+#endif
+ break;
+ }
+ Cmd++;
+ --MaxOpCount;
+ }
+}
+
+
+void RarVM::PrintState(uint IP)
+{
+#if defined(DEBUG) && !defined(GUI) && !defined(SILENT)
+ mprintf("\n");
+ for (int I=0;I<sizeof(R)/sizeof(R[0]);I++)
+ mprintf("R%d=%08X\t%s",I,R[I],I==3 ? "\n":"");
+ mprintf("\nIP=%08X\tFlags: C=%d S=%d",IP,(Flags & VM_FC)!=0,(Flags & VM_FS)!=0);
+ mprintf("\n");
+#endif
+}
+
+
+void RarVM::Prepare(byte *Code,int CodeSize,VM_PreparedProgram *Prg)
+{
+ InitBitInput();
+ memcpy(InBuf,Code,Min(CodeSize,BitInput::MAX_SIZE));
+
+ byte XorSum=0;
+ for (int I=1;I<CodeSize;I++)
+ XorSum^=Code[I];
+
+ faddbits(8);
+
+ Prg->CmdCount=0;
+ if (XorSum==Code[0])
+ {
+#ifdef VM_STANDARDFILTERS
+ VM_StandardFilters FilterType=IsStandardFilter(Code,CodeSize);
+ if (FilterType!=VMSF_NONE)
+ {
+ Prg->Cmd.Add(1);
+ VM_PreparedCommand *CurCmd=&Prg->Cmd[Prg->CmdCount++];
+ CurCmd->OpCode=VM_STANDARD;
+ CurCmd->Op1.Data=FilterType;
+ CurCmd->Op1.Addr=&CurCmd->Op1.Data;
+ CurCmd->Op2.Addr=&CurCmd->Op2.Data;
+ CurCmd->Op1.Type=CurCmd->Op2.Type=VM_OPNONE;
+ CodeSize=0;
+ }
+#endif
+ uint DataFlag=fgetbits();
+ faddbits(1);
+ if (DataFlag&0x8000)
+ {
+ int DataSize=ReadData(*this)+1;
+ for (int I=0;InAddr<CodeSize && I<DataSize;I++)
+ {
+ Prg->StaticData.Add(1);
+ Prg->StaticData[I]=fgetbits()>>8;
+ faddbits(8);
+ }
+ }
+ while (InAddr<CodeSize)
+ {
+ Prg->Cmd.Add(1);
+ VM_PreparedCommand *CurCmd=&Prg->Cmd[Prg->CmdCount];
+ uint Data=fgetbits();
+ if ((Data&0x8000)==0)
+ {
+ CurCmd->OpCode=(VM_Commands)(Data>>12);
+ faddbits(4);
+ }
+ else
+ {
+ CurCmd->OpCode=(VM_Commands)((Data>>10)-24);
+ faddbits(6);
+ }
+ if (VM_CmdFlags[CurCmd->OpCode] & VMCF_BYTEMODE)
+ {
+ // Igor Pavlov
+ CurCmd->ByteMode = ((fgetbits() >> 15) != 0);
+
+ faddbits(1);
+ }
+ else
+ CurCmd->ByteMode=0;
+ CurCmd->Op1.Type=CurCmd->Op2.Type=VM_OPNONE;
+ int OpNum=(VM_CmdFlags[CurCmd->OpCode] & VMCF_OPMASK);
+ CurCmd->Op1.Addr=CurCmd->Op2.Addr=NULL;
+ if (OpNum>0)
+ {
+ DecodeArg(CurCmd->Op1,CurCmd->ByteMode);
+ if (OpNum==2)
+ DecodeArg(CurCmd->Op2,CurCmd->ByteMode);
+ else
+ {
+ if (CurCmd->Op1.Type==VM_OPINT && (VM_CmdFlags[CurCmd->OpCode]&(VMCF_JUMP|VMCF_PROC)))
+ {
+ int Distance=CurCmd->Op1.Data;
+ if (Distance>=256)
+ Distance-=256;
+ else
+ {
+ if (Distance>=136)
+ Distance-=264;
+ else
+ if (Distance>=16)
+ Distance-=8;
+ else
+ if (Distance>=8)
+ Distance-=16;
+ Distance+=Prg->CmdCount;
+ }
+ CurCmd->Op1.Data=Distance;
+ }
+ }
+ }
+ Prg->CmdCount++;
+ }
+ }
+ Prg->Cmd.Add(1);
+ VM_PreparedCommand *CurCmd=&Prg->Cmd[Prg->CmdCount++];
+ CurCmd->OpCode=VM_RET;
+ CurCmd->Op1.Addr=&CurCmd->Op1.Data;
+ CurCmd->Op2.Addr=&CurCmd->Op2.Data;
+ CurCmd->Op1.Type=CurCmd->Op2.Type=VM_OPNONE;
+
+ for (int I=0;I<Prg->CmdCount;I++)
+ {
+ VM_PreparedCommand *Cmd=&Prg->Cmd[I];
+ if (Cmd->Op1.Addr==NULL)
+ Cmd->Op1.Addr=&Cmd->Op1.Data;
+ if (Cmd->Op2.Addr==NULL)
+ Cmd->Op2.Addr=&Cmd->Op2.Data;
+ }
+
+#ifdef VM_OPTIMIZE
+ if (CodeSize!=0)
+ Optimize(Prg);
+#endif
+}
+
+
+void RarVM::DecodeArg(VM_PreparedOperand &Op,bool ByteMode)
+{
+ uint Data=fgetbits();
+ if (Data & 0x8000)
+ {
+ Op.Type=VM_OPREG;
+ Op.Data=(Data>>12)&7;
+ Op.Addr=&R[Op.Data];
+ faddbits(4);
+ }
+ else
+ if ((Data & 0xc000)==0)
+ {
+ Op.Type=VM_OPINT;
+ if (ByteMode)
+ {
+ Op.Data=(Data>>6) & 0xff;
+ faddbits(10);
+ }
+ else
+ {
+ faddbits(2);
+ Op.Data=ReadData(*this);
+ }
+ }
+ else
+ {
+ Op.Type=VM_OPREGMEM;
+ if ((Data & 0x2000)==0)
+ {
+ Op.Data=(Data>>10)&7;
+ Op.Addr=&R[Op.Data];
+ Op.Base=0;
+ faddbits(6);
+ }
+ else
+ {
+ if ((Data & 0x1000)==0)
+ {
+ Op.Data=(Data>>9)&7;
+ Op.Addr=&R[Op.Data];
+ faddbits(7);
+ }
+ else
+ {
+ Op.Data=0;
+ faddbits(4);
+ }
+ Op.Base=ReadData(*this);
+ }
+ }
+}
+
+
+uint RarVM::ReadData(BitInput &Inp)
+{
+ uint Data=Inp.fgetbits();
+ switch(Data&0xc000)
+ {
+ case 0:
+ Inp.faddbits(6);
+ return((Data>>10)&0xf);
+ case 0x4000:
+ if ((Data&0x3c00)==0)
+ {
+ Data=0xffffff00|((Data>>2)&0xff);
+ Inp.faddbits(14);
+ }
+ else
+ {
+ Data=(Data>>6)&0xff;
+ Inp.faddbits(10);
+ }
+ return(Data);
+ case 0x8000:
+ Inp.faddbits(2);
+ Data=Inp.fgetbits();
+ Inp.faddbits(16);
+ return(Data);
+ default:
+ Inp.faddbits(2);
+ Data=(Inp.fgetbits()<<16);
+ Inp.faddbits(16);
+ Data|=Inp.fgetbits();
+ Inp.faddbits(16);
+ return(Data);
+ }
+}
+
+
+void RarVM::SetMemory(unsigned int Pos,byte *Data,unsigned int DataSize)
+{
+ if (Pos<VM_MEMSIZE && Data!=Mem+Pos)
+ memmove(Mem+Pos,Data,Min(DataSize,VM_MEMSIZE-Pos));
+}
+
+
+#ifdef VM_OPTIMIZE
+void RarVM::Optimize(VM_PreparedProgram *Prg)
+{
+ VM_PreparedCommand *Code=&Prg->Cmd[0];
+ int CodeSize=Prg->CmdCount;
+
+ for (int I=0;I<CodeSize;I++)
+ {
+ VM_PreparedCommand *Cmd=Code+I;
+ switch(Cmd->OpCode)
+ {
+ case VM_MOV:
+ Cmd->OpCode=Cmd->ByteMode ? VM_MOVB:VM_MOVD;
+ continue;
+ case VM_CMP:
+ Cmd->OpCode=Cmd->ByteMode ? VM_CMPB:VM_CMPD;
+ continue;
+ }
+ if ((VM_CmdFlags[Cmd->OpCode] & VMCF_CHFLAGS)==0)
+ continue;
+ bool FlagsRequired=false;
+ for (int J=I+1;J<CodeSize;J++)
+ {
+ int Flags=VM_CmdFlags[Code[J].OpCode];
+ if (Flags & (VMCF_JUMP|VMCF_PROC|VMCF_USEFLAGS))
+ {
+ FlagsRequired=true;
+ break;
+ }
+ if (Flags & VMCF_CHFLAGS)
+ break;
+ }
+ if (FlagsRequired)
+ continue;
+ switch(Cmd->OpCode)
+ {
+ case VM_ADD:
+ Cmd->OpCode=Cmd->ByteMode ? VM_ADDB:VM_ADDD;
+ continue;
+ case VM_SUB:
+ Cmd->OpCode=Cmd->ByteMode ? VM_SUBB:VM_SUBD;
+ continue;
+ case VM_INC:
+ Cmd->OpCode=Cmd->ByteMode ? VM_INCB:VM_INCD;
+ continue;
+ case VM_DEC:
+ Cmd->OpCode=Cmd->ByteMode ? VM_DECB:VM_DECD;
+ continue;
+ case VM_NEG:
+ Cmd->OpCode=Cmd->ByteMode ? VM_NEGB:VM_NEGD;
+ continue;
+ }
+ }
+}
+#endif
+
+
+#ifdef VM_STANDARDFILTERS
+VM_StandardFilters RarVM::IsStandardFilter(byte *Code,int CodeSize)
+{
+ struct StandardFilterSignature
+ {
+ int Length;
+ uint CRC;
+ VM_StandardFilters Type;
+ } StdList[]={
+ 53, 0xad576887, VMSF_E8,
+ 57, 0x3cd7e57e, VMSF_E8E9,
+ 120, 0x3769893f, VMSF_ITANIUM,
+ 29, 0x0e06077d, VMSF_DELTA,
+ 149, 0x1c2c5dc8, VMSF_RGB,
+ 216, 0xbc85e701, VMSF_AUDIO,
+ 40, 0x46b9c560, VMSF_UPCASE
+ };
+ uint CodeCRC=CRC(0xffffffff,Code,CodeSize)^0xffffffff;
+ for (int I=0;I<sizeof(StdList)/sizeof(StdList[0]);I++)
+ if (StdList[I].CRC==CodeCRC && StdList[I].Length==CodeSize)
+ return(StdList[I].Type);
+ return(VMSF_NONE);
+}
+
+
+void RarVM::ExecuteStandardFilter(VM_StandardFilters FilterType)
+{
+ switch(FilterType)
+ {
+ case VMSF_E8:
+ case VMSF_E8E9:
+ {
+ byte *Data=Mem;
+ int DataSize=R[4];
+ uint FileOffset=R[6];
+
+ if (DataSize>=VM_GLOBALMEMADDR)
+ break;
+
+ const int FileSize=0x1000000;
+ byte CmpByte2=FilterType==VMSF_E8E9 ? 0xe9:0xe8;
+ for (uint CurPos=0;CurPos<DataSize-4;)
+ {
+ byte CurByte=*(Data++);
+ CurPos++;
+ if (CurByte==0xe8 || CurByte==CmpByte2)
+ {
+#ifdef PRESENT_INT32
+ sint32 Offset=CurPos+FileOffset;
+ sint32 Addr=GET_VALUE(false,Data);
+ if (Addr<0)
+ {
+ if (Addr+Offset>=0)
+ SET_VALUE(false,Data,Addr+FileSize);
+ }
+ else
+ if (Addr<FileSize)
+ SET_VALUE(false,Data,Addr-Offset);
+#else
+ long Offset=CurPos+FileOffset;
+ long Addr=GET_VALUE(false,Data);
+ if ((Addr & 0x80000000)!=0)
+ {
+ if (((Addr+Offset) & 0x80000000)==0)
+ SET_VALUE(false,Data,Addr+FileSize);
+ }
+ else
+ if (((Addr-FileSize) & 0x80000000)!=0)
+ SET_VALUE(false,Data,Addr-Offset);
+#endif
+ Data+=4;
+ CurPos+=4;
+ }
+ }
+ }
+ break;
+ case VMSF_ITANIUM:
+ {
+ byte *Data=Mem;
+ int DataSize=R[4];
+ uint FileOffset=R[6];
+
+ if (DataSize>=VM_GLOBALMEMADDR)
+ break;
+
+ uint CurPos=0;
+
+ FileOffset>>=4;
+
+ while (CurPos<DataSize-21)
+ {
+ int Byte=(Data[0]&0x1f)-0x10;
+ if (Byte>=0)
+ {
+ static byte Masks[16]={4,4,6,6,0,0,7,7,4,4,0,0,4,4,0,0};
+ byte CmdMask=Masks[Byte];
+ if (CmdMask!=0)
+ for (int I=0;I<=2;I++)
+ if (CmdMask & (1<<I))
+ {
+ int StartPos=I*41+5;
+ int OpType=FilterItanium_GetBits(Data,StartPos+37,4);
+ if (OpType==5)
+ {
+ int Offset=FilterItanium_GetBits(Data,StartPos+13,20);
+ FilterItanium_SetBits(Data,(Offset-FileOffset)&0xfffff,StartPos+13,20);
+ }
+ }
+ }
+ Data+=16;
+ CurPos+=16;
+ FileOffset++;
+ }
+ }
+ break;
+ case VMSF_DELTA:
+ {
+ int DataSize=R[4],Channels=R[0],SrcPos=0,Border=DataSize*2;
+ SET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x20],DataSize);
+ if (DataSize>=VM_GLOBALMEMADDR/2)
+ break;
+ for (int CurChannel=0;CurChannel<Channels;CurChannel++)
+ {
+ byte PrevByte=0;
+ for (int DestPos=DataSize+CurChannel;DestPos<Border;DestPos+=Channels)
+ Mem[DestPos]=(PrevByte-=Mem[SrcPos++]);
+ }
+ }
+ break;
+ case VMSF_RGB:
+ {
+ int DataSize=R[4],Width=R[0]-3,PosR=R[1];
+ byte *SrcData=Mem,*DestData=SrcData+DataSize;
+ const int Channels=3;
+ SET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x20],DataSize);
+ if (DataSize>=VM_GLOBALMEMADDR/2)
+ break;
+ for (int CurChannel=0;CurChannel<Channels;CurChannel++)
+ {
+ unsigned int PrevByte=0;
+
+ for (int I=CurChannel;I<DataSize;I+=Channels)
+ {
+ unsigned int Predicted;
+ int UpperPos=I-Width;
+ if (UpperPos>=3)
+ {
+ byte *UpperData=DestData+UpperPos;
+ unsigned int UpperByte=*UpperData;
+ unsigned int UpperLeftByte=*(UpperData-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;
+ }
+ else
+ Predicted=PrevByte;
+ DestData[I]=PrevByte=(byte)(Predicted-*(SrcData++));
+ }
+ }
+ for (int I=PosR,Border=DataSize-2;I<Border;I+=3)
+ {
+ byte G=DestData[I+1];
+ DestData[I]+=G;
+ DestData[I+2]+=G;
+ }
+ }
+ break;
+ case VMSF_AUDIO:
+ {
+ int DataSize=R[4],Channels=R[0];
+ byte *SrcData=Mem,*DestData=SrcData+DataSize;
+ SET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x20],DataSize);
+ if (DataSize>=VM_GLOBALMEMADDR/2)
+ break;
+ for (int CurChannel=0;CurChannel<Channels;CurChannel++)
+ {
+ unsigned int PrevByte=0,PrevDelta=0,Dif[7];
+ int D1=0,D2=0,D3;
+ int K1=0,K2=0,K3=0;
+ memset(Dif,0,sizeof(Dif));
+
+ for (int I=CurChannel,ByteCount=0;I<DataSize;I+=Channels,ByteCount++)
+ {
+ D3=D2;
+ D2=PrevDelta-D1;
+ D1=PrevDelta;
+
+ unsigned int Predicted=8*PrevByte+K1*D1+K2*D2+K3*D3;
+ Predicted=(Predicted>>3) & 0xff;
+
+ unsigned int CurByte=*(SrcData++);
+
+ Predicted-=CurByte;
+ DestData[I]=Predicted;
+ PrevDelta=(signed char)(Predicted-PrevByte);
+ PrevByte=Predicted;
+
+ int D=((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)
+ {
+ unsigned int MinDif=Dif[0],NumMinDif=0;
+ Dif[0]=0;
+ for (int J=1;J<sizeof(Dif)/sizeof(Dif[0]);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;
+ }
+ }
+ }
+ }
+ }
+ break;
+ case VMSF_UPCASE:
+ {
+ int DataSize=R[4],SrcPos=0,DestPos=DataSize;
+ if (DataSize>=VM_GLOBALMEMADDR/2)
+ break;
+ while (SrcPos<DataSize)
+ {
+ byte CurByte=Mem[SrcPos++];
+ if (CurByte==2 && (CurByte=Mem[SrcPos++])!=2)
+ CurByte-=32;
+ Mem[DestPos++]=CurByte;
+ }
+ SET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x1c],DestPos-DataSize);
+ SET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x20],DataSize);
+ }
+ break;
+ }
+}
+
+
+unsigned int RarVM::FilterItanium_GetBits(byte *Data,int BitPos,int BitCount)
+{
+ int InAddr=BitPos/8;
+ int InBit=BitPos&7;
+ unsigned int BitField=(uint)Data[InAddr++];
+ BitField|=(uint)Data[InAddr++] << 8;
+ BitField|=(uint)Data[InAddr++] << 16;
+ BitField|=(uint)Data[InAddr] << 24;
+ BitField >>= InBit;
+ return(BitField & (0xffffffff>>(32-BitCount)));
+}
+
+
+void RarVM::FilterItanium_SetBits(byte *Data,unsigned int BitField,int BitPos,
+ int BitCount)
+{
+ int InAddr=BitPos/8;
+ int InBit=BitPos&7;
+ unsigned int AndMask=0xffffffff>>(32-BitCount);
+ AndMask=~(AndMask<<InBit);
+
+ BitField<<=InBit;
+
+ for (int I=0;I<4;I++)
+ {
+ Data[InAddr+I]&=AndMask;
+ Data[InAddr+I]|=BitField;
+ AndMask=(AndMask>>8)|0xff000000;
+ BitField>>=8;
+ }
+}
+#endif
diff --git a/7zip/Compress/Rar29/Original/rarvm.hpp b/7zip/Compress/Rar29/Original/rarvm.hpp
new file mode 100755
index 00000000..f330390b
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/rarvm.hpp
@@ -0,0 +1,110 @@
+#ifndef _RAR_VM_
+#define _RAR_VM_
+
+#define VM_STANDARDFILTERS
+
+#ifndef SFX_MODULE
+#define VM_OPTIMIZE
+#endif
+
+
+#define VM_MEMSIZE 0x40000
+#define VM_MEMMASK (VM_MEMSIZE-1)
+#define VM_GLOBALMEMADDR 0x3C000
+#define VM_GLOBALMEMSIZE 0x2000
+#define VM_FIXEDGLOBALSIZE 64
+
+enum VM_Commands
+{
+ VM_MOV, VM_CMP, VM_ADD, VM_SUB, VM_JZ, VM_JNZ, VM_INC, VM_DEC,
+ VM_JMP, VM_XOR, VM_AND, VM_OR, VM_TEST, VM_JS, VM_JNS, VM_JB,
+ VM_JBE, VM_JA, VM_JAE, VM_PUSH, VM_POP, VM_CALL, VM_RET, VM_NOT,
+ VM_SHL, VM_SHR, VM_SAR, VM_NEG, VM_PUSHA,VM_POPA, VM_PUSHF,VM_POPF,
+ VM_MOVZX,VM_MOVSX,VM_XCHG, VM_MUL, VM_DIV, VM_ADC, VM_SBB, VM_PRINT,
+
+#ifdef VM_OPTIMIZE
+ VM_MOVB, VM_MOVD, VM_CMPB, VM_CMPD,
+
+ VM_ADDB, VM_ADDD, VM_SUBB, VM_SUBD, VM_INCB, VM_INCD, VM_DECB, VM_DECD,
+ VM_NEGB, VM_NEGD,
+#endif
+
+ VM_STANDARD
+};
+
+enum VM_StandardFilters {
+ VMSF_NONE, VMSF_E8, VMSF_E8E9, VMSF_ITANIUM, VMSF_RGB, VMSF_AUDIO,
+ VMSF_DELTA, VMSF_UPCASE
+};
+
+enum VM_Flags {VM_FC=1,VM_FZ=2,VM_FS=0x80000000};
+
+enum VM_OpType {VM_OPREG,VM_OPINT,VM_OPREGMEM,VM_OPNONE};
+
+struct VM_PreparedOperand
+{
+ VM_OpType Type;
+ uint Data;
+ uint Base;
+ uint *Addr;
+};
+
+struct VM_PreparedCommand
+{
+ VM_Commands OpCode;
+ bool ByteMode;
+ VM_PreparedOperand Op1,Op2;
+};
+
+
+struct VM_PreparedProgram
+{
+ VM_PreparedProgram() {AltCmd=NULL;}
+
+ Array<VM_PreparedCommand> Cmd;
+ VM_PreparedCommand *AltCmd;
+ int CmdCount;
+
+ Array<byte> GlobalData;
+ Array<byte> StaticData;
+ uint InitR[7];
+
+ byte *FilteredData;
+ unsigned int FilteredDataSize;
+};
+
+class RarVM:private BitInput
+{
+ private:
+ inline uint GetValue(bool ByteMode,uint *Addr);
+ inline void SetValue(bool ByteMode,uint *Addr,uint Value);
+ inline uint* GetOperand(VM_PreparedOperand *CmdOp);
+ void PrintState(uint IP);
+ void DecodeArg(VM_PreparedOperand &Op,bool ByteMode);
+#ifdef VM_OPTIMIZE
+ void Optimize(VM_PreparedProgram *Prg);
+#endif
+ bool ExecuteCode(VM_PreparedCommand *PreparedCode,int CodeSize);
+#ifdef VM_STANDARDFILTERS
+ VM_StandardFilters IsStandardFilter(byte *Code,int CodeSize);
+ void ExecuteStandardFilter(VM_StandardFilters FilterType);
+ unsigned int FilterItanium_GetBits(byte *Data,int BitPos,int BitCount);
+ void FilterItanium_SetBits(byte *Data,unsigned int BitField,int BitPos,
+ int BitCount);
+#endif
+
+ byte *Mem;
+ uint R[8];
+ uint Flags;
+ public:
+ RarVM();
+ ~RarVM();
+ void Init();
+ void Prepare(byte *Code,int CodeSize,VM_PreparedProgram *Prg);
+ void Execute(VM_PreparedProgram *Prg);
+ void SetValue(uint *Addr,uint Value);
+ void SetMemory(unsigned int Pos,byte *Data,unsigned int DataSize);
+ static uint ReadData(BitInput &Inp);
+};
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/rarvmtbl.cpp b/7zip/Compress/Rar29/Original/rarvmtbl.cpp
new file mode 100755
index 00000000..b5e6c720
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/rarvmtbl.cpp
@@ -0,0 +1,53 @@
+#define VMCF_OP0 0
+#define VMCF_OP1 1
+#define VMCF_OP2 2
+#define VMCF_OPMASK 3
+#define VMCF_BYTEMODE 4
+#define VMCF_JUMP 8
+#define VMCF_PROC 16
+#define VMCF_USEFLAGS 32
+#define VMCF_CHFLAGS 64
+
+static byte VM_CmdFlags[]=
+{
+ /* VM_MOV */ VMCF_OP2 | VMCF_BYTEMODE ,
+ /* VM_CMP */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
+ /* VM_ADD */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
+ /* VM_SUB */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
+ /* VM_JZ */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
+ /* VM_JNZ */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
+ /* VM_INC */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
+ /* VM_DEC */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
+ /* VM_JMP */ VMCF_OP1 | VMCF_JUMP ,
+ /* VM_XOR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
+ /* VM_AND */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
+ /* VM_OR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
+ /* VM_TEST */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
+ /* VM_JS */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
+ /* VM_JNS */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
+ /* VM_JB */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
+ /* VM_JBE */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
+ /* VM_JA */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
+ /* VM_JAE */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
+ /* VM_PUSH */ VMCF_OP1 ,
+ /* VM_POP */ VMCF_OP1 ,
+ /* VM_CALL */ VMCF_OP1 | VMCF_PROC ,
+ /* VM_RET */ VMCF_OP0 | VMCF_PROC ,
+ /* VM_NOT */ VMCF_OP1 | VMCF_BYTEMODE ,
+ /* VM_SHL */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
+ /* VM_SHR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
+ /* VM_SAR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
+ /* VM_NEG */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
+ /* VM_PUSHA */ VMCF_OP0 ,
+ /* VM_POPA */ VMCF_OP0 ,
+ /* VM_PUSHF */ VMCF_OP0 | VMCF_USEFLAGS ,
+ /* VM_POPF */ VMCF_OP0 | VMCF_CHFLAGS ,
+ /* VM_MOVZX */ VMCF_OP2 ,
+ /* VM_MOVSX */ VMCF_OP2 ,
+ /* VM_XCHG */ VMCF_OP2 | VMCF_BYTEMODE ,
+ /* VM_MUL */ VMCF_OP2 | VMCF_BYTEMODE ,
+ /* VM_DIV */ VMCF_OP2 | VMCF_BYTEMODE ,
+ /* VM_ADC */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_USEFLAGS | VMCF_CHFLAGS ,
+ /* VM_SBB */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_USEFLAGS | VMCF_CHFLAGS ,
+ /* VM_PRINT */ VMCF_OP0
+};
diff --git a/7zip/Compress/Rar29/Original/rawread.hpp b/7zip/Compress/Rar29/Original/rawread.hpp
new file mode 100755
index 00000000..47c2bbcb
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/rawread.hpp
@@ -0,0 +1,32 @@
+#ifndef _RAR_RAWREAD_
+#define _RAR_RAWREAD_
+
+class RawRead
+{
+ private:
+ Array<byte> Data;
+ File *SrcFile;
+ int DataSize;
+ int ReadPos;
+#ifndef SHELL_EXT
+ CryptData *Crypt;
+#endif
+ public:
+ RawRead(File *SrcFile);
+ void Read(int Size);
+ void Read(byte *SrcData,int Size);
+ void Get(byte &Field);
+ void Get(ushort &Field);
+ void Get(uint &Field);
+ void Get8(Int64 &Field);
+ void Get(byte *Field,int Size);
+ void Get(wchar *Field,int Size);
+ uint GetCRC(bool ProcessedOnly);
+ int Size() {return DataSize;}
+ int PaddedSize() {return Data.Size()-DataSize;}
+#ifndef SHELL_EXT
+ void SetCrypt(CryptData *Crypt) {RawRead::Crypt=Crypt;}
+#endif
+};
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/rdwrfn.cpp b/7zip/Compress/Rar29/Original/rdwrfn.cpp
new file mode 100755
index 00000000..7340ea67
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/rdwrfn.cpp
@@ -0,0 +1,306 @@
+#include "rar.hpp"
+
+// Igor Pavlov
+#include "../../../Common/StreamUtils.h"
+
+ComprDataIO::ComprDataIO()
+{
+ Init();
+}
+
+
+void ComprDataIO::Init()
+{
+ UnpackFromMemory=false;
+ UnpackToMemory=false;
+ UnpPackedSize=0;
+ ShowProgress=true;
+ TestMode=false;
+ SkipUnpCRC=false;
+ PackVolume=false;
+ UnpVolume=false;
+ NextVolumeMissing=false;
+ SrcFile=NULL;
+ DestFile=NULL;
+ UnpWrSize=0;
+ Command=NULL;
+ Encryption=0;
+ Decryption=0;
+ TotalPackRead=0;
+ CurPackRead=CurPackWrite=CurUnpRead=CurUnpWrite=0;
+ PackFileCRC=UnpFileCRC=PackedCRC=0xffffffff;
+ LastPercent=-1;
+ // Igor Pavlov
+ /*
+ SubHead=NULL;
+ SubHeadPos=NULL;
+ */
+ CurrentCommand=0;
+ ProcessedArcSize=TotalArcSize=0;
+}
+
+
+
+
+int ComprDataIO::UnpRead(byte *Addr,uint Count)
+{
+ int RetCode=0,TotalRead=0;
+ byte *ReadAddr;
+ ReadAddr=Addr;
+ while (Count > 0)
+ {
+ Archive *SrcArc=(Archive *)SrcFile;
+
+ uint ReadSize=(Count>UnpPackedSize) ? int64to32(UnpPackedSize):Count;
+ if (UnpackFromMemory)
+ {
+ memcpy(Addr,UnpackFromMemoryAddr,UnpackFromMemorySize);
+ RetCode=UnpackFromMemorySize;
+ UnpackFromMemorySize=0;
+ }
+ else
+ {
+ // Igor Pavlov
+ if (!SrcFile)
+ // if (!SrcFile->IsOpened())
+ return(-1);
+
+ // Igor Pavlov
+ UInt32 processedSize;
+ HRESULT result = ReadStream(SrcFile, ReadAddr, ReadSize, &processedSize);
+ RetCode = processedSize;
+
+ // Igor Pavlov
+ /*
+ FileHeader *hd=SubHead!=NULL ? SubHead:&SrcArc->NewLhd;
+ if (hd->Flags & LHD_SPLIT_AFTER)
+ PackedCRC=CRC(PackedCRC,ReadAddr,ReadSize);
+ */
+ }
+ CurUnpRead+=RetCode;
+ ReadAddr+=RetCode;
+ TotalRead+=RetCode;
+ Count-=RetCode;
+ UnpPackedSize-=RetCode;
+ if (UnpPackedSize == 0 && UnpVolume)
+ {
+#ifndef NOVOLUME
+ if (!MergeArchive(*SrcArc,this,true,CurrentCommand))
+#endif
+ {
+ NextVolumeMissing=true;
+ return(-1);
+ }
+ }
+ else
+ break;
+ }
+ // Igor Pavlov
+ /*
+ Archive *SrcArc=(Archive *)SrcFile;
+ if (SrcArc!=NULL)
+ ShowUnpRead(SrcArc->CurBlockPos+CurUnpRead,UnpArcSize);
+ */
+ if (RetCode!=-1)
+ {
+ RetCode=TotalRead;
+#ifndef NOCRYPT
+ if (Decryption)
+#ifndef SFX_MODULE
+ if (Decryption<20)
+ Decrypt.Crypt(Addr,RetCode,(Decryption==15) ? NEW_CRYPT : OLD_DECODE);
+ else
+ if (Decryption==20)
+ for (uint I=0;I<RetCode;I+=16)
+ Decrypt.DecryptBlock20(&Addr[I]);
+ else
+#endif
+ {
+ int CryptSize=(RetCode & 0xf)==0 ? RetCode:((RetCode & ~0xf)+16);
+ Decrypt.DecryptBlock(Addr,CryptSize);
+ }
+#endif
+ }
+ Wait();
+ return(RetCode);
+}
+
+
+void ComprDataIO::UnpWrite(byte *Addr,uint Count)
+{
+#ifdef RARDLL
+ RAROptions *Cmd=((Archive *)SrcFile)->GetRAROptions();
+ if (Cmd->DllOpMode!=RAR_SKIP)
+ {
+ if (Cmd->Callback!=NULL &&
+ Cmd->Callback(UCM_PROCESSDATA,Cmd->UserData,(LONG)Addr,Count)==-1)
+ ErrHandler.Exit(USER_BREAK);
+ if (Cmd->ProcessDataProc!=NULL)
+ {
+#ifdef _WIN_32
+ _EBX=_ESP;
+#endif
+ int RetCode=Cmd->ProcessDataProc(Addr,Count);
+#ifdef _WIN_32
+ _ESP=_EBX;
+#endif
+ if (RetCode==0)
+ ErrHandler.Exit(USER_BREAK);
+ }
+ }
+#endif
+ UnpWrAddr=Addr;
+ UnpWrSize=Count;
+ if (UnpackToMemory)
+ {
+ if (Count <= UnpackToMemorySize)
+ {
+ memcpy(UnpackToMemoryAddr,Addr,Count);
+ UnpackToMemoryAddr+=Count;
+ UnpackToMemorySize-=Count;
+ }
+ }
+ else
+ if (!TestMode)
+ {
+ // Igor Pavlov
+ // DestFile->Write(Addr,Count);
+ WriteStream(DestFile, Addr,Count, 0);
+ }
+ CurUnpWrite+=Count;
+ // Igor Pavlov
+ /*
+ if (!SkipUnpCRC)
+#ifndef SFX_MODULE
+ if (((Archive *)SrcFile)->OldFormat)
+ UnpFileCRC=OldCRC((ushort)UnpFileCRC,Addr,Count);
+ else
+#endif
+ UnpFileCRC=CRC(UnpFileCRC,Addr,Count);
+ */
+ ShowUnpWrite();
+ Wait();
+}
+
+
+
+
+
+
+void ComprDataIO::ShowUnpRead(Int64 ArcPos,Int64 ArcSize)
+{
+ if (ShowProgress && SrcFile!=NULL)
+ {
+ Archive *SrcArc=(Archive *)SrcFile;
+ RAROptions *Cmd=SrcArc->GetRAROptions();
+ if (TotalArcSize!=0)
+ ArcSize=TotalArcSize;
+ ArcPos+=ProcessedArcSize;
+ if (!SrcArc->Volume)
+ {
+ int CurPercent=ToPercent(ArcPos,ArcSize);
+ if (!Cmd->DisablePercentage && CurPercent!=LastPercent)
+ {
+ mprintf("\b\b\b\b%3d%%",CurPercent);
+ LastPercent=CurPercent;
+ }
+ }
+ }
+}
+
+
+void ComprDataIO::ShowUnpWrite()
+{
+ // Igor Pavlov
+ if (Progress)
+ {
+ UInt64 unPackSize = CurUnpWrite;
+ HRESULT result = Progress->SetRatioInfo(NULL, &unPackSize);
+ if (result != S_OK)
+ throw CExitCode(result);
+ }
+}
+
+
+
+
+
+
+
+// Igor Pavlov
+/*
+void ComprDataIO::SetFiles(File *SrcFile,File *DestFile)
+{
+ if (SrcFile!=NULL)
+ ComprDataIO::SrcFile=SrcFile;
+ if (DestFile!=NULL)
+ ComprDataIO::DestFile=DestFile;
+ LastPercent=-1;
+}
+*/
+
+void ComprDataIO::GetUnpackedData(byte **Data,uint *Size)
+{
+ *Data=UnpWrAddr;
+ *Size=UnpWrSize;
+}
+
+// Igor Pavlov
+/*
+void ComprDataIO::SetEncryption(int Method,char *Password,byte *Salt,bool Encrypt)
+{
+ if (Encrypt)
+ {
+ Encryption=*Password ? Method:0;
+#ifndef NOCRYPT
+ Crypt.SetCryptKeys(Password,Salt,Encrypt);
+#endif
+ }
+ else
+ {
+ Decryption=*Password ? Method:0;
+#ifndef NOCRYPT
+ Decrypt.SetCryptKeys(Password,Salt,Encrypt,Method<29);
+#endif
+ }
+}
+
+
+#ifndef SFX_MODULE
+void ComprDataIO::SetAV15Encryption()
+{
+ Decryption=15;
+ Decrypt.SetAV15Encryption();
+}
+#endif
+
+
+#ifndef SFX_MODULE
+void ComprDataIO::SetCmt13Encryption()
+{
+ Decryption=13;
+ Decrypt.SetCmt13Encryption();
+}
+#endif
+
+*/
+
+
+
+void ComprDataIO::SetUnpackToMemory(byte *Addr,uint Size)
+{
+ UnpackToMemory=true;
+ UnpackToMemoryAddr=Addr;
+ UnpackToMemorySize=Size;
+}
+
+// Igor Pavlov
+void ComprDataIO::SetFiles(ISequentialInStream *srcFile,
+ ISequentialOutStream *destFile, ICompressProgressInfo *progress)
+{
+ SrcFile = srcFile;
+ DestFile = destFile;
+ Progress = progress;
+ LastPercent = -1;
+}
+
diff --git a/7zip/Compress/Rar29/Original/rdwrfn.hpp b/7zip/Compress/Rar29/Original/rdwrfn.hpp
new file mode 100755
index 00000000..d2feb842
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/rdwrfn.hpp
@@ -0,0 +1,104 @@
+#ifndef _RAR_DATAIO_
+#define _RAR_DATAIO_
+
+// Igor Pavlov
+#include "../../../ICoder.h"
+
+class CmdAdd;
+class Unpack;
+
+// Igor Pavlov
+struct CExitCode
+{
+ HRESULT Result;
+ CExitCode(HRESULT result): Result(result) {};
+};
+
+class ComprDataIO
+{
+ private:
+ void ShowUnpRead(Int64 ArcPos,Int64 ArcSize);
+ void ShowUnpWrite();
+
+
+ bool UnpackFromMemory;
+ uint UnpackFromMemorySize;
+ byte *UnpackFromMemoryAddr;
+
+ bool UnpackToMemory;
+ uint UnpackToMemorySize;
+ byte *UnpackToMemoryAddr;
+
+ uint UnpWrSize;
+ byte *UnpWrAddr;
+
+ Int64 UnpPackedSize;
+
+ bool ShowProgress;
+ bool TestMode;
+ bool SkipUnpCRC;
+
+ // Igor Pavlov
+ // File *SrcFile;
+ // File *DestFile;
+ ISequentialInStream *SrcFile;
+ ISequentialOutStream *DestFile;
+ ICompressProgressInfo *Progress;
+
+ CmdAdd *Command;
+
+ // Igor Pavlov
+ /*
+ FileHeader *SubHead;
+ Int64 *SubHeadPos;
+ */
+
+#ifndef NOCRYPT
+ CryptData Crypt;
+ CryptData Decrypt;
+#endif
+
+
+ int LastPercent;
+
+ char CurrentCommand;
+
+ public:
+ ComprDataIO();
+ void Init();
+ int UnpRead(byte *Addr,uint Count);
+ void UnpWrite(byte *Addr,uint Count);
+ void EnableShowProgress(bool Show) {ShowProgress=Show;}
+ void GetUnpackedData(byte **Data,uint *Size);
+ void SetPackedSizeToRead(Int64 Size) {UnpPackedSize=Size;}
+ void SetTestMode(bool Mode) {TestMode=Mode;}
+ void SetSkipUnpCRC(bool Skip) {SkipUnpCRC=Skip;}
+ // Igor Pavlov
+ // void SetFiles(File *SrcFile,File *DestFile);
+ void SetFiles(ISequentialInStream *srcFile,
+ ISequentialOutStream *destFile, ICompressProgressInfo *progress);
+
+ void SetCommand(CmdAdd *Cmd) {Command=Cmd;}
+ // Igor Pavlov
+ // void SetSubHeader(FileHeader *hd,Int64 *Pos) {SubHead=hd;SubHeadPos=Pos;}
+ // void SetEncryption(int Method,char *Password,byte *Salt,bool Encrypt);
+ // void SetAV15Encryption();
+ // void SetCmt13Encryption();
+ void SetUnpackToMemory(byte *Addr,uint Size);
+ void SetCurrentCommand(char Cmd) {CurrentCommand=Cmd;}
+
+ bool PackVolume;
+ bool UnpVolume;
+ bool NextVolumeMissing;
+ Int64 TotalPackRead;
+ Int64 UnpArcSize;
+ Int64 CurPackRead,CurPackWrite,CurUnpRead,CurUnpWrite;
+ Int64 ProcessedArcSize,TotalArcSize;
+
+ uint PackFileCRC,UnpFileCRC,PackedCRC;
+
+ int Encryption;
+ int Decryption;
+};
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/recvol.hpp b/7zip/Compress/Rar29/Original/recvol.hpp
new file mode 100755
index 00000000..5a0abe58
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/recvol.hpp
@@ -0,0 +1,16 @@
+#ifndef _RAR_RECVOL_
+#define _RAR_RECVOL_
+
+class RecVolumes
+{
+ private:
+ File *SrcFile[256];
+ Array<byte> Buf;
+ public:
+ RecVolumes();
+ ~RecVolumes();
+ void Make(RAROptions *Cmd,char *ArcName,wchar *ArcNameW);
+ bool Restore(RAROptions *Cmd,const char *Name,const wchar *NameW,bool Silent);
+};
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/resource.cpp b/7zip/Compress/Rar29/Original/resource.cpp
new file mode 100755
index 00000000..f2a46573
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/resource.cpp
@@ -0,0 +1,12 @@
+#include "rar.hpp"
+
+
+
+#if !defined(SILENT) || !defined(RARDLL)
+const char *St(MSGID StringId)
+{
+ return(StringId);
+}
+#endif
+
+
diff --git a/7zip/Compress/Rar29/Original/resource.hpp b/7zip/Compress/Rar29/Original/resource.hpp
new file mode 100755
index 00000000..581b34b4
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/resource.hpp
@@ -0,0 +1,14 @@
+#ifndef _RAR_RESOURCE_
+#define _RAR_RESOURCE_
+
+#if defined(SILENT) && defined(RARDLL)
+#define St(x) ("")
+#else
+const char *St(MSGID StringId);
+#endif
+
+
+inline const char *StT(MSGID StringId) {return(St(StringId));}
+
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/rijndael.hpp b/7zip/Compress/Rar29/Original/rijndael.hpp
new file mode 100755
index 00000000..6a8eddeb
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/rijndael.hpp
@@ -0,0 +1,37 @@
+#ifndef _RIJNDAEL_H_
+#define _RIJNDAEL_H_
+
+/**************************************************************************
+ * This code is based on Szymon Stefanek AES implementation: *
+ * http://www.esat.kuleuven.ac.be/~rijmen/rijndael/rijndael-cpplib.tar.gz *
+ * *
+ * Dynamic tables generation is based on the Brian Gladman's work: *
+ * http://fp.gladman.plus.com/cryptography_technology/rijndael *
+ **************************************************************************/
+
+#define _MAX_KEY_COLUMNS (256/32)
+#define _MAX_ROUNDS 14
+#define MAX_IV_SIZE 16
+
+class Rijndael
+{
+ public:
+ enum Direction { Encrypt , Decrypt };
+ private:
+ void keySched(byte key[_MAX_KEY_COLUMNS][4]);
+ void keyEncToDec();
+ void encrypt(const byte a[16], byte b[16]);
+ void decrypt(const byte a[16], byte b[16]);
+ void GenerateTables();
+
+ Direction m_direction;
+ byte m_initVector[MAX_IV_SIZE];
+ byte m_expandedKey[_MAX_ROUNDS+1][4][4];
+ public:
+ Rijndael();
+ void init(Direction dir,const byte *key,byte *initVector);
+ int blockEncrypt(const byte *input, int inputLen, byte *outBuffer);
+ int blockDecrypt(const byte *input, int inputLen, byte *outBuffer);
+};
+
+#endif // _RIJNDAEL_H_
diff --git a/7zip/Compress/Rar29/Original/rs.hpp b/7zip/Compress/Rar29/Original/rs.hpp
new file mode 100755
index 00000000..2f099f00
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/rs.hpp
@@ -0,0 +1,32 @@
+#ifndef _RAR_RS_
+#define _RAR_RS_
+
+#define MAXPAR 255
+#define MAXPOL 512
+
+class RSCoder
+{
+ private:
+ void gfInit();
+ int gfMult(int a,int b);
+ void pnInit();
+ void pnMult(int *p1,int *p2,int *r);
+
+ int gfExp[MAXPOL];
+ int gfLog[MAXPAR+1];
+
+ int GXPol[MAXPOL*2];
+
+ int ErrorLocs[MAXPAR+1],ErrCount;
+ int Dn[MAXPAR+1];
+
+ int ParSize;
+ int PolB[MAXPOL];
+ bool FirstBlockDone;
+ public:
+ RSCoder(int ParSize);
+ void Encode(byte *Data,int DataSize,byte *DestData);
+ bool Decode(byte *Data,int DataSize,int *EraLoc,int EraSize);
+};
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/savepos.hpp b/7zip/Compress/Rar29/Original/savepos.hpp
new file mode 100755
index 00000000..303550a0
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/savepos.hpp
@@ -0,0 +1,15 @@
+#ifndef _RAR_SAVEPOS_
+#define _RAR_SAVEPOS_
+
+class SaveFilePos
+{
+ private:
+ File *SaveFile;
+ Int64 SavePos;
+ uint CloseCount;
+ public:
+ SaveFilePos(File &SaveFile);
+ ~SaveFilePos();
+};
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/scantree.hpp b/7zip/Compress/Rar29/Original/scantree.hpp
new file mode 100755
index 00000000..2f206ba1
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/scantree.hpp
@@ -0,0 +1,52 @@
+#ifndef _RAR_SCANTREE_
+#define _RAR_SCANTREE_
+
+enum { RECURSE_NONE=0,RECURSE_ALWAYS,RECURSE_WILDCARDS };
+enum { SCAN_SKIPDIRS=0,SCAN_GETDIRS,SCAN_GETDIRSTWICE,SCAN_GETCURDIRS };
+enum { SCAN_SUCCESS,SCAN_DONE,SCAN_ERROR,SCAN_NEXT };
+
+#define MAXSCANDEPTH (NM/2)
+
+class CommandData;
+
+class ScanTree
+{
+ private:
+ bool PrepareMasks();
+ int FindProc(FindData *FindData);
+
+ FindFile *FindStack[MAXSCANDEPTH];
+ int Depth;
+
+ int SetAllMaskDepth;
+
+ StringList *FileMasks;
+ int Recurse;
+ bool GetLinks;
+ int GetDirs;
+ int Errors;
+
+ char CurMask[NM];
+ wchar CurMaskW[NM];
+ char OrigCurMask[NM];
+ wchar OrigCurMaskW[NM];
+ bool SearchAllInRoot;
+ bool FastFindFile;
+ int SpecPathLength;
+ int SpecPathLengthW;
+
+ char ErrArcName[NM];
+
+ CommandData *Cmd;
+ public:
+ ScanTree(StringList *FileMasks,int Recurse,bool GetLinks,int GetDirs);
+ ~ScanTree();
+ int GetNext(FindData *FindData);
+ int GetSpecPathLength() {return(SpecPathLength);};
+ int GetSpecPathLengthW() {return(SpecPathLengthW);};
+ int GetErrors() {return(Errors);};
+ void SetErrArcName(const char *Name) {strcpy(ErrArcName,Name);}
+ void SetCommandData(CommandData *Cmd) {ScanTree::Cmd=Cmd;}
+};
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/sha1.hpp b/7zip/Compress/Rar29/Original/sha1.hpp
new file mode 100755
index 00000000..96cef44e
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/sha1.hpp
@@ -0,0 +1,16 @@
+#ifndef _RAR_SHA1_
+#define _RAR_SHA1_
+
+#define HW 5
+
+typedef struct {
+ uint32 state[5];
+ uint32 count[2];
+ unsigned char buffer[64];
+} hash_context;
+
+void hash_initial( hash_context * c );
+void hash_process( hash_context * c, unsigned char * data, unsigned len );
+void hash_final( hash_context * c, uint32[HW] );
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/smallfn.cpp b/7zip/Compress/Rar29/Original/smallfn.cpp
new file mode 100755
index 00000000..094691f0
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/smallfn.cpp
@@ -0,0 +1,17 @@
+#include "rar.hpp"
+
+int ToPercent(Int64 N1,Int64 N2)
+{
+ if (N2==0)
+ return(0);
+ if (N2<N1)
+ return(100);
+ return(int64to32(N1*100/N2));
+}
+
+
+void RARInitData()
+{
+ InitCRC();
+ ErrHandler.Clean();
+}
diff --git a/7zip/Compress/Rar29/Original/smallfn.hpp b/7zip/Compress/Rar29/Original/smallfn.hpp
new file mode 100755
index 00000000..096ffef1
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/smallfn.hpp
@@ -0,0 +1,7 @@
+#ifndef _RAR_SMALLFN_
+#define _RAR_SMALLFN_
+
+int ToPercent(Int64 N1,Int64 N2);
+void RARInitData();
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/strfn.hpp b/7zip/Compress/Rar29/Original/strfn.hpp
new file mode 100755
index 00000000..57813e52
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/strfn.hpp
@@ -0,0 +1,24 @@
+#ifndef _RAR_STRFN_
+#define _RAR_STRFN_
+
+const char *NullToEmpty(const char *Str);
+const wchar *NullToEmpty(const wchar *Str);
+char *IntNameToExt(const char *Name);
+void ExtToInt(const char *Src,char *Dest);
+void IntToExt(const char *Src,char *Dest);
+char* strlower(char *Str);
+char* strupper(char *Str);
+int stricomp(const char *Str1,const char *Str2);
+int strnicomp(const char *Str1,const char *Str2,int N);
+char* RemoveEOL(char *Str);
+char* RemoveLF(char *Str);
+unsigned int loctolower(byte ch);
+unsigned int loctoupper(byte ch);
+
+
+
+bool LowAscii(const char *Str);
+bool LowAscii(const wchar *Str);
+
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/strlist.hpp b/7zip/Compress/Rar29/Original/strlist.hpp
new file mode 100755
index 00000000..c4d3b017
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/strlist.hpp
@@ -0,0 +1,39 @@
+#ifndef _RAR_STRLIST_
+#define _RAR_STRLIST_
+
+class StringList
+{
+ private:
+ Array<char> StringData;
+ unsigned int CurPos;
+
+ Array<wchar> StringDataW;
+ unsigned int CurPosW;
+
+ Array<int> PosDataW;
+ uint PosDataItem;
+
+ uint StringsCount;
+
+ uint SaveCurPos[16],SaveCurPosW[16],SavePosDataItem[16],SavePosNumber;
+ public:
+ StringList();
+ ~StringList();
+ void Reset();
+ unsigned int AddString(const char *Str);
+ unsigned int AddString(const char *Str,const wchar *StrW);
+ bool GetString(char *Str,int MaxLength);
+ bool GetString(char *Str,wchar *StrW,int MaxLength);
+ bool GetString(char *Str,wchar *StrW,int MaxLength,int StringNum);
+ char* GetString();
+ bool GetString(char **Str,wchar **StrW);
+ char* GetString(unsigned int StringPos);
+ void Rewind();
+ unsigned int ItemsCount() {return(StringsCount);};
+ int GetBufferSize();
+ bool Search(char *Str,wchar *StrW,bool CaseSensitive);
+ void SavePosition();
+ void RestorePosition();
+};
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/suballoc.cpp b/7zip/Compress/Rar29/Original/suballoc.cpp
new file mode 100755
index 00000000..bffc7632
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/suballoc.cpp
@@ -0,0 +1,241 @@
+/****************************************************************************
+ * This file is part of PPMd project *
+ * Written and distributed to public domain by Dmitry Shkarin 1997, *
+ * 1999-2000 *
+ * Contents: memory allocation routines *
+ ****************************************************************************/
+
+SubAllocator::SubAllocator()
+{
+ Clean();
+}
+
+
+void SubAllocator::Clean()
+{
+ SubAllocatorSize=0;
+}
+
+
+inline void SubAllocator::InsertNode(void* p,int indx)
+{
+ ((RAR_NODE*) p)->next=FreeList[indx].next;
+ FreeList[indx].next=(RAR_NODE*) p;
+}
+
+
+inline void* SubAllocator::RemoveNode(int indx)
+{
+ RAR_NODE* RetVal=FreeList[indx].next;
+ FreeList[indx].next=RetVal->next;
+ return RetVal;
+}
+
+
+inline uint SubAllocator::U2B(int NU)
+{
+ return /*8*NU+4*NU*/UNIT_SIZE*NU;
+}
+
+
+inline void SubAllocator::SplitBlock(void* pv,int OldIndx,int NewIndx)
+{
+ int i, UDiff=Indx2Units[OldIndx]-Indx2Units[NewIndx];
+ byte* p=((byte*) pv)+U2B(Indx2Units[NewIndx]);
+ if (Indx2Units[i=Units2Indx[UDiff-1]] != UDiff)
+ {
+ InsertNode(p,--i);
+ p += U2B(i=Indx2Units[i]);
+ UDiff -= i;
+ }
+ InsertNode(p,Units2Indx[UDiff-1]);
+}
+
+
+
+
+void SubAllocator::StopSubAllocator()
+{
+ if ( SubAllocatorSize )
+ {
+ SubAllocatorSize=0;
+ rarfree(HeapStart);
+ }
+}
+
+
+bool SubAllocator::StartSubAllocator(int SASize)
+{
+ uint t=SASize << 20;
+ if (SubAllocatorSize == t)
+ return TRUE;
+ StopSubAllocator();
+ uint AllocSize=t/FIXED_UNIT_SIZE*UNIT_SIZE+UNIT_SIZE;
+ if ((HeapStart=(byte *)rarmalloc(AllocSize)) == NULL)
+ {
+ ErrHandler.MemoryError();
+ return FALSE;
+ }
+ HeapEnd=HeapStart+AllocSize-UNIT_SIZE;
+ SubAllocatorSize=t;
+ return TRUE;
+}
+
+
+void SubAllocator::InitSubAllocator()
+{
+ int i, k;
+ memset(FreeList,0,sizeof(FreeList));
+ pText=HeapStart;
+ uint Size2=FIXED_UNIT_SIZE*(SubAllocatorSize/8/FIXED_UNIT_SIZE*7);
+ uint RealSize2=Size2/FIXED_UNIT_SIZE*UNIT_SIZE;
+ uint Size1=SubAllocatorSize-Size2;
+ uint RealSize1=Size1/FIXED_UNIT_SIZE*UNIT_SIZE+Size1%FIXED_UNIT_SIZE;
+ HiUnit=HeapStart+SubAllocatorSize;
+ LoUnit=UnitsStart=HeapStart+RealSize1;
+ FakeUnitsStart=HeapStart+Size1;
+ HiUnit=LoUnit+RealSize2;
+ for (i=0,k=1;i < N1 ;i++,k += 1)
+ Indx2Units[i]=k;
+ for (k++;i < N1+N2 ;i++,k += 2)
+ Indx2Units[i]=k;
+ for (k++;i < N1+N2+N3 ;i++,k += 3)
+ Indx2Units[i]=k;
+ for (k++;i < N1+N2+N3+N4;i++,k += 4)
+ Indx2Units[i]=k;
+ for (GlueCount=k=i=0;k < 128;k++)
+ {
+ i += (Indx2Units[i] < k+1);
+ Units2Indx[k]=i;
+ }
+}
+
+
+inline void SubAllocator::GlueFreeBlocks()
+{
+ RAR_MEM_BLK s0, * p, * p1;
+ int i, k, sz;
+ if (LoUnit != HiUnit)
+ *LoUnit=0;
+ for (i=0, s0.next=s0.prev=&s0;i < N_INDEXES;i++)
+ while ( FreeList[i].next )
+ {
+ p=(RAR_MEM_BLK*)RemoveNode(i);
+ p->insertAt(&s0);
+ p->Stamp=0xFFFF;
+ p->NU=Indx2Units[i];
+ }
+ for (p=s0.next;p != &s0;p=p->next)
+ while ((p1=p+p->NU)->Stamp == 0xFFFF && int(p->NU)+p1->NU < 0x10000)
+ {
+ p1->remove();
+ p->NU += p1->NU;
+ }
+ while ((p=s0.next) != &s0)
+ {
+ for (p->remove(), sz=p->NU;sz > 128;sz -= 128, p += 128)
+ InsertNode(p,N_INDEXES-1);
+ if (Indx2Units[i=Units2Indx[sz-1]] != sz)
+ {
+ k=sz-Indx2Units[--i];
+ InsertNode(p+(sz-k),k-1);
+ }
+ InsertNode(p,i);
+ }
+}
+
+void* SubAllocator::AllocUnitsRare(int indx)
+{
+ if ( !GlueCount )
+ {
+ GlueCount = 255;
+ GlueFreeBlocks();
+ if ( FreeList[indx].next )
+ return RemoveNode(indx);
+ }
+ int i=indx;
+ do
+ {
+ if (++i == N_INDEXES)
+ {
+ GlueCount--;
+ i=U2B(Indx2Units[indx]);
+ int j=12*Indx2Units[indx];
+ if (FakeUnitsStart-pText > j)
+ {
+ FakeUnitsStart-=j;
+ UnitsStart -= i;
+ return(UnitsStart);
+ }
+ return(NULL);
+ }
+ } while ( !FreeList[i].next );
+ void* RetVal=RemoveNode(i);
+ SplitBlock(RetVal,i,indx);
+ return RetVal;
+}
+
+
+inline void* SubAllocator::AllocUnits(int NU)
+{
+ int indx=Units2Indx[NU-1];
+ if ( FreeList[indx].next )
+ return RemoveNode(indx);
+ void* RetVal=LoUnit;
+ LoUnit += U2B(Indx2Units[indx]);
+ if (LoUnit <= HiUnit)
+ return RetVal;
+ LoUnit -= U2B(Indx2Units[indx]);
+ return AllocUnitsRare(indx);
+}
+
+
+void* SubAllocator::AllocContext()
+{
+ if (HiUnit != LoUnit)
+ return (HiUnit -= UNIT_SIZE);
+ if ( FreeList->next )
+ return RemoveNode(0);
+ return AllocUnitsRare(0);
+}
+
+
+void* SubAllocator::ExpandUnits(void* OldPtr,int OldNU)
+{
+ int i0=Units2Indx[OldNU-1], i1=Units2Indx[OldNU-1+1];
+ if (i0 == i1)
+ return OldPtr;
+ void* ptr=AllocUnits(OldNU+1);
+ if ( ptr )
+ {
+ memcpy(ptr,OldPtr,U2B(OldNU));
+ InsertNode(OldPtr,i0);
+ }
+ return ptr;
+}
+
+
+void* SubAllocator::ShrinkUnits(void* OldPtr,int OldNU,int NewNU)
+{
+ int i0=Units2Indx[OldNU-1], i1=Units2Indx[NewNU-1];
+ if (i0 == i1)
+ return OldPtr;
+ if ( FreeList[i1].next )
+ {
+ void* ptr=RemoveNode(i1);
+ memcpy(ptr,OldPtr,U2B(NewNU));
+ InsertNode(OldPtr,i0);
+ return ptr;
+ }
+ else
+ {
+ SplitBlock(OldPtr,i0,i1);
+ return OldPtr;
+ }
+}
+
+
+void SubAllocator::FreeUnits(void* ptr,int OldNU)
+{
+ InsertNode(ptr,Units2Indx[OldNU-1]);
+}
diff --git a/7zip/Compress/Rar29/Original/suballoc.hpp b/7zip/Compress/Rar29/Original/suballoc.hpp
new file mode 100755
index 00000000..08174eea
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/suballoc.hpp
@@ -0,0 +1,81 @@
+/****************************************************************************
+ * This file is part of PPMd project *
+ * Written and distributed to public domain by Dmitry Shkarin 1997, *
+ * 1999-2000 *
+ * Contents: interface to memory allocation routines *
+ ****************************************************************************/
+#if !defined(_SUBALLOC_H_)
+#define _SUBALLOC_H_
+
+const int N1=4, N2=4, N3=4, N4=(128+3-1*N1-2*N2-3*N3)/4;
+const int N_INDEXES=N1+N2+N3+N4;
+
+#if defined(__GNUC__)
+#define _PACK_ATTR __attribute__ ((packed))
+#else
+#define _PACK_ATTR
+#endif /* defined(__GNUC__) */
+
+#pragma pack(1)
+struct RAR_MEM_BLK
+{
+ ushort Stamp, NU;
+ RAR_MEM_BLK* next, * prev;
+ void insertAt(RAR_MEM_BLK* p)
+ {
+ next=(prev=p)->next;
+ p->next=next->prev=this;
+ }
+ void remove()
+ {
+ prev->next=next;
+ next->prev=prev;
+ }
+} _PACK_ATTR;
+
+#ifdef _AIX
+#pragma pack(pop)
+#else
+#pragma pack()
+#endif
+
+
+struct RAR_NODE
+{
+ RAR_NODE* next;
+};
+
+class SubAllocator
+{
+ private:
+ inline void InsertNode(void* p,int indx);
+ inline void* RemoveNode(int indx);
+ inline uint U2B(int NU);
+ inline void SplitBlock(void* pv,int OldIndx,int NewIndx);
+ uint GetUsedMemory();
+ inline void GlueFreeBlocks();
+ void* AllocUnitsRare(int indx);
+
+ long SubAllocatorSize;
+ byte Indx2Units[N_INDEXES], Units2Indx[128], GlueCount;
+ byte *HeapStart,*LoUnit, *HiUnit;
+ struct RAR_NODE FreeList[N_INDEXES];
+ public:
+ SubAllocator();
+ ~SubAllocator() {StopSubAllocator();}
+ void Clean();
+ bool StartSubAllocator(int SASize);
+ void StopSubAllocator();
+ void InitSubAllocator();
+ inline void* AllocContext();
+ inline void* AllocUnits(int NU);
+ inline void* ExpandUnits(void* ptr,int OldNU);
+ inline void* ShrinkUnits(void* ptr,int OldNU,int NewNU);
+ inline void FreeUnits(void* ptr,int OldNU);
+ long GetAllocatedMemory() {return(SubAllocatorSize);};
+
+ byte *pText, *UnitsStart,*HeapEnd,*FakeUnitsStart;
+};
+
+
+#endif /* !defined(_SUBALLOC_H_) */
diff --git a/7zip/Compress/Rar29/Original/system.cpp b/7zip/Compress/Rar29/Original/system.cpp
new file mode 100755
index 00000000..1d3cdafe
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/system.cpp
@@ -0,0 +1,79 @@
+#include "rar.hpp"
+
+#ifndef _WIN_CE
+static int SleepTime=0;
+
+void InitSystemOptions(int SleepTime)
+{
+ ::SleepTime=SleepTime;
+}
+#endif
+
+
+#if !defined(SFX_MODULE) && !defined(_WIN_CE)
+
+#if defined(_WIN_32) && !defined(BELOW_NORMAL_PRIORITY_CLASS)
+#define BELOW_NORMAL_PRIORITY_CLASS 0x00004000
+#define ABOVE_NORMAL_PRIORITY_CLASS 0x00008000
+#endif
+
+void SetPriority(int Priority)
+{
+#ifdef _WIN_32
+ uint PriorityClass;
+ int PriorityLevel;
+ if (Priority<1 || Priority>15)
+ return;
+
+ if (Priority==1)
+ {
+ PriorityClass=IDLE_PRIORITY_CLASS;
+ PriorityLevel=THREAD_PRIORITY_IDLE;
+ }
+ else
+ if (Priority<7)
+ {
+ PriorityClass=IDLE_PRIORITY_CLASS;
+ PriorityLevel=Priority-4;
+ }
+ else
+ if (Priority==7)
+ {
+ PriorityClass=BELOW_NORMAL_PRIORITY_CLASS;
+ PriorityLevel=THREAD_PRIORITY_ABOVE_NORMAL;
+ }
+ else
+ if (Priority<10)
+ {
+ PriorityClass=NORMAL_PRIORITY_CLASS;
+ PriorityLevel=Priority-7;
+ }
+ else
+ if (Priority==10)
+ {
+ PriorityClass=ABOVE_NORMAL_PRIORITY_CLASS;
+ PriorityLevel=THREAD_PRIORITY_NORMAL;
+ }
+ else
+ {
+ PriorityClass=HIGH_PRIORITY_CLASS;
+ PriorityLevel=Priority-13;
+ }
+ SetPriorityClass(GetCurrentProcess(),PriorityClass);
+ SetThreadPriority(GetCurrentThread(),PriorityLevel);
+#endif
+}
+#endif
+
+
+void Wait()
+{
+#if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE)
+ if (SleepTime!=0)
+ Sleep(SleepTime);
+#endif
+}
+
+
+
+
diff --git a/7zip/Compress/Rar29/Original/system.hpp b/7zip/Compress/Rar29/Original/system.hpp
new file mode 100755
index 00000000..89582ece
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/system.hpp
@@ -0,0 +1,10 @@
+#ifndef _RAR_SYSTEM_
+#define _RAR_SYSTEM_
+
+void InitSystemOptions(int SleepTime);
+void SetPriority(int Priority);
+void Wait();
+bool EmailFile(char *FileName,char *MailTo);
+void Shutdown();
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/timefn.hpp b/7zip/Compress/Rar29/Original/timefn.hpp
new file mode 100755
index 00000000..9ab5032f
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/timefn.hpp
@@ -0,0 +1,57 @@
+#ifndef _RAR_TIMEFN_
+#define _RAR_TIMEFN_
+
+struct RarLocalTime
+{
+ uint Year;
+ uint Month;
+ uint Day;
+ uint Hour;
+ uint Minute;
+ uint Second;
+ uint Reminder;
+ uint wDay;
+ uint yDay;
+};
+
+
+class RarTime
+{
+ private:
+ Int64 GetRaw();
+ void SetRaw(Int64 RawTime);
+
+ RarLocalTime rlt;
+
+ Int64 Time;
+ public:
+ RarTime();
+#ifdef _WIN_32
+ RarTime& operator =(FILETIME &ft);
+ void GetWin32(FILETIME *ft);
+#endif
+#if defined(_UNIX) || defined(_EMX)
+ RarTime& operator =(time_t ut);
+ time_t GetUnix();
+#endif
+ bool operator == (RarTime &rt);
+ bool operator < (RarTime &rt);
+ bool operator <= (RarTime &rt);
+ bool operator > (RarTime &rt);
+ bool operator >= (RarTime &rt);
+ void GetLocal(RarLocalTime *lt) {*lt=rlt;}
+ void SetLocal(RarLocalTime *lt) {rlt=*lt;}
+ uint GetDos();
+ void SetDos(uint DosTime);
+ void GetText(char *DateStr,bool FullYear);
+ void SetIsoText(char *TimeText);
+ void SetAgeText(char *TimeText);
+ void SetCurrentTime();
+ void Reset() {rlt.Year=0;}
+ bool IsSet() {return(rlt.Year!=0);}
+};
+
+const char *GetMonthName(int Month);
+bool IsLeapYear(int Year);
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/ulinks.hpp b/7zip/Compress/Rar29/Original/ulinks.hpp
new file mode 100755
index 00000000..69b0e9f8
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/ulinks.hpp
@@ -0,0 +1,9 @@
+#ifndef _RAR_ULINKS_
+#define _RAR_ULINKS_
+
+void SaveLinkData(ComprDataIO &DataIO,Archive &TempArc,FileHeader &hd,
+ char *Name);
+int ExtractLink(ComprDataIO &DataIO,Archive &Arc,char *DestName,
+ uint &LinkCRC,bool Create);
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/unicode.hpp b/7zip/Compress/Rar29/Original/unicode.hpp
new file mode 100755
index 00000000..a1bdbbe1
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/unicode.hpp
@@ -0,0 +1,82 @@
+#ifndef _RAR_UNICODE_
+#define _RAR_UNICODE_
+
+#ifndef _EMX
+#define MBFUNCTIONS
+#endif
+
+#if defined(MBFUNCTIONS) || defined(_WIN_32) || defined(_EMX) && !defined(_DJGPP)
+#define UNICODE_SUPPORTED
+#endif
+
+#ifdef _WIN_32
+#define DBCS_SUPPORTED
+#endif
+
+#ifdef _EMX
+int uni_init(int codepage);
+int uni_done();
+#endif
+
+bool WideToChar(const wchar *Src,char *Dest,int DestSize=0x10000000);
+bool CharToWide(const char *Src,wchar *Dest,int DestSize=0x10000000);
+byte* WideToRaw(const wchar *Src,byte *Dest,int DestSize=0x10000000);
+wchar* RawToWide(const byte *Src,wchar *Dest,int DestSize=0x10000000);
+void WideToUtf(const wchar *Src,char *Dest,int DestSize);
+void UtfToWide(const char *Src,wchar *Dest,int DestSize);
+bool UnicodeEnabled();
+
+int strlenw(const wchar *str);
+wchar* strcpyw(wchar *dest,const wchar *src);
+wchar* strncpyw(wchar *dest,const wchar *src,int n);
+wchar* strcatw(wchar *dest,const wchar *src);
+wchar* strncatw(wchar *dest,const wchar *src,int n);
+int strcmpw(const wchar *s1,const wchar *s2);
+int strncmpw(const wchar *s1,const wchar *s2,int n);
+int stricmpw(const wchar *s1,const wchar *s2);
+int strnicmpw(const wchar *s1,const wchar *s2,int n);
+wchar *strchrw(const wchar *s,int c);
+wchar* strrchrw(const wchar *s,int c);
+wchar* strpbrkw(const wchar *s1,const wchar *s2);
+wchar* strlowerw(wchar *Str);
+wchar* strupperw(wchar *Str);
+int toupperw(int ch);
+int atoiw(const wchar *s);
+
+#ifdef DBCS_SUPPORTED
+class SupportDBCS
+{
+ public:
+ SupportDBCS();
+ void Init();
+
+ char* charnext(const char *s);
+ uint strlend(const char *s);
+ char *strchrd(const char *s, int c);
+ char *strrchrd(const char *s, int c);
+ void copychrd(char *dest,const char *src);
+
+ bool IsLeadByte[256];
+ bool DBCSMode;
+};
+
+extern SupportDBCS gdbcs;
+
+inline char* charnext(const char *s) {return (char *)(gdbcs.DBCSMode ? gdbcs.charnext(s):s+1);}
+inline uint strlend(const char *s) {return (uint)(gdbcs.DBCSMode ? gdbcs.strlend(s):strlen(s));}
+inline char* strchrd(const char *s, int c) {return (char *)(gdbcs.DBCSMode ? gdbcs.strchrd(s,c):strchr(s,c));}
+inline char* strrchrd(const char *s, int c) {return (char *)(gdbcs.DBCSMode ? gdbcs.strrchrd(s,c):strrchr(s,c));}
+inline void copychrd(char *dest,const char *src) {if (gdbcs.DBCSMode) gdbcs.copychrd(dest,src); else *dest=*src;}
+inline bool IsDBCSMode() {return(gdbcs.DBCSMode);}
+inline void InitDBCS() {gdbcs.Init();}
+
+#else
+#define charnext(s) ((s)+1)
+#define strlend strlen
+#define strchrd strchr
+#define strrchrd strrchr
+#define IsDBCSMode() (true)
+inline void copychrd(char *dest,const char *src) {*dest=*src;}
+#endif
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/unpack.cpp b/7zip/Compress/Rar29/Original/unpack.cpp
new file mode 100755
index 00000000..e72d83cf
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/unpack.cpp
@@ -0,0 +1,939 @@
+#include "rar.hpp"
+
+#include "coder.cpp"
+#include "suballoc.cpp"
+#include "model.cpp"
+#ifndef SFX_MODULE
+#include "unpack15.cpp"
+// Igor Pavlov
+// #include "unpack20.cpp"
+#endif
+
+Unpack::Unpack(ComprDataIO *DataIO)
+{
+ UnpIO=DataIO;
+ Window=NULL;
+ ExternalWindow=false;
+ Suspended=false;
+ UnpAllBuf=false;
+ UnpSomeRead=false;
+}
+
+
+Unpack::~Unpack()
+{
+ if (Window!=NULL && !ExternalWindow)
+ delete[] Window;
+ InitFilters();
+}
+
+
+void Unpack::Init(byte *Window)
+{
+ if (Window==NULL)
+ {
+ Unpack::Window=new byte[MAXWINSIZE];
+#ifndef ALLOW_EXCEPTIONS
+ if (Unpack::Window==NULL)
+ ErrHandler.MemoryError();
+#endif
+ }
+ else
+ {
+ Unpack::Window=Window;
+ ExternalWindow=true;
+ }
+ UnpInitData(false);
+}
+
+
+void Unpack::DoUnpack(int Method,bool Solid)
+{
+ switch(Method)
+ {
+#ifndef SFX_MODULE
+ case 15:
+ Unpack15(Solid);
+ break;
+ // Igor Pavlov
+ /*
+ case 20:
+ case 26:
+ Unpack20(Solid);
+ break;
+ */
+#endif
+ case 29:
+ Unpack29(Solid);
+ break;
+ }
+}
+
+
+inline void Unpack::InsertOldDist(unsigned int Distance)
+{
+ OldDist[3]=OldDist[2];
+ OldDist[2]=OldDist[1];
+ OldDist[1]=OldDist[0];
+ OldDist[0]=Distance;
+}
+
+
+inline void Unpack::InsertLastMatch(unsigned int Length,unsigned int Distance)
+{
+ LastDist=Distance;
+ LastLength=Length;
+}
+
+
+void Unpack::CopyString(unsigned int Length,unsigned int Distance)
+{
+ unsigned int DestPtr=UnpPtr-Distance;
+ if (DestPtr<MAXWINSIZE-260 && UnpPtr<MAXWINSIZE-260)
+ {
+ Window[UnpPtr++]=Window[DestPtr++];
+ while (--Length>0)
+ Window[UnpPtr++]=Window[DestPtr++];
+ }
+ else
+ while (Length--)
+ {
+ Window[UnpPtr]=Window[DestPtr++ & MAXWINMASK];
+ UnpPtr=(UnpPtr+1) & MAXWINMASK;
+ }
+}
+
+
+int Unpack::DecodeNumber(struct Decode *Dec)
+{
+ unsigned int Bits;
+ unsigned int BitField=getbits() & 0xfffe;
+ if (BitField<Dec->DecodeLen[8])
+ if (BitField<Dec->DecodeLen[4])
+ if (BitField<Dec->DecodeLen[2])
+ if (BitField<Dec->DecodeLen[1])
+ Bits=1;
+ else
+ Bits=2;
+ else
+ if (BitField<Dec->DecodeLen[3])
+ Bits=3;
+ else
+ Bits=4;
+ else
+ if (BitField<Dec->DecodeLen[6])
+ if (BitField<Dec->DecodeLen[5])
+ Bits=5;
+ else
+ Bits=6;
+ else
+ if (BitField<Dec->DecodeLen[7])
+ Bits=7;
+ else
+ Bits=8;
+ else
+ if (BitField<Dec->DecodeLen[12])
+ if (BitField<Dec->DecodeLen[10])
+ if (BitField<Dec->DecodeLen[9])
+ Bits=9;
+ else
+ Bits=10;
+ else
+ if (BitField<Dec->DecodeLen[11])
+ Bits=11;
+ else
+ Bits=12;
+ else
+ if (BitField<Dec->DecodeLen[14])
+ if (BitField<Dec->DecodeLen[13])
+ Bits=13;
+ else
+ Bits=14;
+ else
+ Bits=15;
+
+ addbits(Bits);
+ unsigned int N=Dec->DecodePos[Bits]+((BitField-Dec->DecodeLen[Bits-1])>>(16-Bits));
+ if (N>=Dec->MaxNum)
+ N=0;
+ return(Dec->DecodeNum[N]);
+}
+
+
+void Unpack::Unpack29(bool Solid)
+{
+ static unsigned char LDecode[]={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 unsigned char LBits[]= {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 int DDecode[DC];
+ static byte DBits[DC];
+ static int DBitLengthCounts[]= {4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,14,0,12};
+ static unsigned char SDDecode[]={0,4,8,16,32,64,128,192};
+ static unsigned char SDBits[]= {2,2,3, 4, 5, 6, 6, 6};
+ unsigned int Bits;
+
+ if (DDecode[1]==0)
+ {
+ int Dist=0,BitLength=0,Slot=0;
+ for (int I=0;I<sizeof(DBitLengthCounts)/sizeof(DBitLengthCounts[0]);I++,BitLength++)
+ for (int J=0;J<DBitLengthCounts[I];J++,Slot++,Dist+=(1<<BitLength))
+ {
+ DDecode[Slot]=Dist;
+ DBits[Slot]=BitLength;
+ }
+ }
+
+ FileExtracted=true;
+
+ if (!Suspended)
+ {
+ UnpInitData(Solid);
+ if (!UnpReadBuf())
+ return;
+ if ((!Solid || !TablesRead) && !ReadTables())
+ return;
+ }
+
+ if (PPMError)
+ return;
+
+ while (true)
+ {
+ UnpPtr&=MAXWINMASK;
+
+ if (InAddr>ReadBorder)
+ {
+ if (!UnpReadBuf())
+ break;
+ }
+ if (((WrPtr-UnpPtr) & MAXWINMASK)<260 && WrPtr!=UnpPtr)
+ {
+ UnpWriteBuf();
+ if (WrittenFileSize>DestUnpSize)
+ return;
+ if (Suspended)
+ {
+ FileExtracted=false;
+ return;
+ }
+ }
+ if (UnpBlockType==BLOCK_PPM)
+ {
+ int Ch=PPM.DecodeChar();
+ if (Ch==-1)
+ {
+ PPMError=true;
+ break;
+ }
+ if (Ch==PPMEscChar)
+ {
+ int NextCh=PPM.DecodeChar();
+ if (NextCh==0)
+ {
+ if (!ReadTables())
+ break;
+ continue;
+ }
+ if (NextCh==2 || NextCh==-1)
+ break;
+ if (NextCh==3)
+ {
+ if (!ReadVMCodePPM())
+ break;
+ continue;
+ }
+ if (NextCh==4)
+ {
+ unsigned int Distance=0,Length;
+ bool Failed=false;
+ for (int I=0;I<4 && !Failed;I++)
+ {
+ int Ch=PPM.DecodeChar();
+ if (Ch==-1)
+ Failed=true;
+ else
+ if (I==3)
+ Length=(byte)Ch;
+ else
+ Distance=(Distance<<8)+(byte)Ch;
+ }
+ if (Failed)
+ break;
+ CopyString(Length+32,Distance+2);
+ continue;
+ }
+ if (NextCh==5)
+ {
+ int Length=PPM.DecodeChar();
+ if (Length==-1)
+ break;
+ CopyString(Length+4,1);
+ continue;
+ }
+ }
+ Window[UnpPtr++]=Ch;
+ continue;
+ }
+
+ int Number=DecodeNumber((struct Decode *)&LD);
+ if (Number<256)
+ {
+ Window[UnpPtr++]=(byte)Number;
+ continue;
+ }
+ if (Number>=271)
+ {
+ int Length=LDecode[Number-=271]+3;
+ if ((Bits=LBits[Number])>0)
+ {
+ Length+=getbits()>>(16-Bits);
+ addbits(Bits);
+ }
+
+ int DistNumber=DecodeNumber((struct Decode *)&DD);
+ unsigned int Distance=DDecode[DistNumber]+1;
+ if ((Bits=DBits[DistNumber])>0)
+ {
+ if (DistNumber>9)
+ {
+ if (Bits>4)
+ {
+ Distance+=((getbits()>>(20-Bits))<<4);
+ addbits(Bits-4);
+ }
+ if (LowDistRepCount>0)
+ {
+ LowDistRepCount--;
+ Distance+=PrevLowDist;
+ }
+ else
+ {
+ int LowDist=DecodeNumber((struct Decode *)&LDD);
+ if (LowDist==16)
+ {
+ LowDistRepCount=LOW_DIST_REP_COUNT-1;
+ Distance+=PrevLowDist;
+ }
+ else
+ {
+ Distance+=LowDist;
+ PrevLowDist=LowDist;
+ }
+ }
+ }
+ else
+ {
+ Distance+=getbits()>>(16-Bits);
+ addbits(Bits);
+ }
+ }
+
+ if (Distance>=0x2000)
+ {
+ Length++;
+ if (Distance>=0x40000L)
+ Length++;
+ }
+
+ InsertOldDist(Distance);
+ InsertLastMatch(Length,Distance);
+ CopyString(Length,Distance);
+ continue;
+ }
+ if (Number==256)
+ {
+ if (!ReadEndOfBlock())
+ break;
+ continue;
+ }
+ if (Number==257)
+ {
+ if (!ReadVMCode())
+ break;
+ continue;
+ }
+ if (Number==258)
+ {
+ if (LastLength!=0)
+ CopyString(LastLength,LastDist);
+ continue;
+ }
+ if (Number<263)
+ {
+ int DistNum=Number-259;
+ unsigned int Distance=OldDist[DistNum];
+ for (int I=DistNum;I>0;I--)
+ OldDist[I]=OldDist[I-1];
+ OldDist[0]=Distance;
+
+ int LengthNumber=DecodeNumber((struct Decode *)&RD);
+ int Length=LDecode[LengthNumber]+2;
+ if ((Bits=LBits[LengthNumber])>0)
+ {
+ Length+=getbits()>>(16-Bits);
+ addbits(Bits);
+ }
+ InsertLastMatch(Length,Distance);
+ CopyString(Length,Distance);
+ continue;
+ }
+ if (Number<272)
+ {
+ unsigned int Distance=SDDecode[Number-=263]+1;
+ if ((Bits=SDBits[Number])>0)
+ {
+ Distance+=getbits()>>(16-Bits);
+ addbits(Bits);
+ }
+ InsertOldDist(Distance);
+ InsertLastMatch(2,Distance);
+ CopyString(2,Distance);
+ continue;
+ }
+ }
+ UnpWriteBuf();
+}
+
+
+bool Unpack::ReadEndOfBlock()
+{
+ unsigned int BitField=getbits();
+ bool NewTable,NewFile=false;
+ if (BitField & 0x8000)
+ {
+ NewTable=true;
+ addbits(1);
+ }
+ else
+ {
+ NewFile=true;
+
+ // Igor Pavlov
+ NewTable = ((BitField & 0x4000) != 0);
+
+ addbits(2);
+ }
+ TablesRead=!NewTable;
+ return !(NewFile || NewTable && !ReadTables());
+}
+
+
+bool Unpack::ReadVMCode()
+{
+ unsigned int FirstByte=getbits()>>8;
+ addbits(8);
+ int Length=(FirstByte & 7)+1;
+ if (Length==7)
+ {
+ Length=(getbits()>>8)+7;
+ addbits(8);
+ }
+ else
+ if (Length==8)
+ {
+ Length=getbits();
+ addbits(16);
+ }
+ Array<byte> VMCode(Length);
+ for (int I=0;I<Length;I++)
+ {
+ if (InAddr>=ReadTop-1 && !UnpReadBuf() && I<Length-1)
+ return(false);
+ VMCode[I]=getbits()>>8;
+ addbits(8);
+ }
+ return(AddVMCode(FirstByte,&VMCode[0],Length));
+}
+
+
+bool Unpack::ReadVMCodePPM()
+{
+ unsigned int FirstByte=PPM.DecodeChar();
+ if ((int)FirstByte==-1)
+ return(false);
+ int Length=(FirstByte & 7)+1;
+ if (Length==7)
+ {
+ int B1=PPM.DecodeChar();
+ if (B1==-1)
+ return(false);
+ Length=B1+7;
+ }
+ else
+ if (Length==8)
+ {
+ int B1=PPM.DecodeChar();
+ if (B1==-1)
+ return(false);
+ int B2=PPM.DecodeChar();
+ if (B2==-1)
+ return(false);
+ Length=B1*256+B2;
+ }
+ Array<byte> VMCode(Length);
+ for (int I=0;I<Length;I++)
+ {
+ int Ch=PPM.DecodeChar();
+ if (Ch==-1)
+ return(false);
+ VMCode[I]=Ch;
+ }
+ return(AddVMCode(FirstByte,&VMCode[0],Length));
+}
+
+
+bool Unpack::AddVMCode(unsigned int FirstByte,byte *Code,int CodeSize)
+{
+ BitInput Inp;
+ Inp.InitBitInput();
+ memcpy(Inp.InBuf,Code,Min(BitInput::MAX_SIZE,CodeSize));
+ VM.Init();
+
+ uint FiltPos;
+ if (FirstByte & 0x80)
+ {
+ FiltPos=RarVM::ReadData(Inp);
+ if (FiltPos==0)
+ InitFilters();
+ else
+ FiltPos--;
+ }
+ else
+ FiltPos=LastFilter;
+ if (FiltPos>Filters.Size() || FiltPos>OldFilterLengths.Size())
+ return(false);
+ LastFilter=FiltPos;
+ bool NewFilter=(FiltPos==Filters.Size());
+
+ UnpackFilter *Filter;
+ if (NewFilter)
+ {
+ Filters.Add(1);
+ Filters[Filters.Size()-1]=Filter=new UnpackFilter;
+ OldFilterLengths.Add(1);
+ Filter->ExecCount=0;
+ }
+ else
+ {
+ Filter=Filters[FiltPos];
+ Filter->ExecCount++;
+ }
+
+ UnpackFilter *StackFilter=new UnpackFilter;
+
+ int EmptyCount=0;
+ for (int I=0;I<PrgStack.Size();I++)
+ {
+ PrgStack[I-EmptyCount]=PrgStack[I];
+ if (PrgStack[I]==NULL)
+ EmptyCount++;
+ if (EmptyCount>0)
+ PrgStack[I]=NULL;
+ }
+ if (EmptyCount==0)
+ {
+ PrgStack.Add(1);
+ EmptyCount=1;
+ }
+ int StackPos=PrgStack.Size()-EmptyCount;
+ PrgStack[StackPos]=StackFilter;
+ StackFilter->ExecCount=Filter->ExecCount;
+
+ uint BlockStart=RarVM::ReadData(Inp);
+ if (FirstByte & 0x40)
+ BlockStart+=258;
+ StackFilter->BlockStart=(BlockStart+UnpPtr)&MAXWINMASK;
+ if (FirstByte & 0x20)
+ StackFilter->BlockLength=RarVM::ReadData(Inp);
+ else
+ StackFilter->BlockLength=FiltPos<OldFilterLengths.Size() ? OldFilterLengths[FiltPos]:0;
+ StackFilter->NextWindow=WrPtr!=UnpPtr && ((WrPtr-UnpPtr)&MAXWINMASK)<=BlockStart;
+
+// DebugLog("\nNextWindow: UnpPtr=%08x WrPtr=%08x BlockStart=%08x",UnpPtr,WrPtr,BlockStart);
+
+ OldFilterLengths[FiltPos]=StackFilter->BlockLength;
+
+ memset(StackFilter->Prg.InitR,0,sizeof(StackFilter->Prg.InitR));
+ StackFilter->Prg.InitR[3]=VM_GLOBALMEMADDR;
+ StackFilter->Prg.InitR[4]=StackFilter->BlockLength;
+ StackFilter->Prg.InitR[5]=StackFilter->ExecCount;
+ if (FirstByte & 0x10)
+ {
+ unsigned int InitMask=Inp.fgetbits()>>9;
+ Inp.faddbits(7);
+ for (int I=0;I<7;I++)
+ if (InitMask & (1<<I))
+ StackFilter->Prg.InitR[I]=RarVM::ReadData(Inp);
+ }
+ if (NewFilter)
+ {
+ uint VMCodeSize=RarVM::ReadData(Inp);
+ if (VMCodeSize>=0x10000 || VMCodeSize==0)
+ return(false);
+ Array<byte> VMCode(VMCodeSize);
+ for (int I=0;I<VMCodeSize;I++)
+ {
+ VMCode[I]=Inp.fgetbits()>>8;
+ Inp.faddbits(8);
+ }
+ VM.Prepare(&VMCode[0],VMCodeSize,&Filter->Prg);
+ }
+ StackFilter->Prg.AltCmd=&Filter->Prg.Cmd[0];
+ StackFilter->Prg.CmdCount=Filter->Prg.CmdCount;
+
+ int StaticDataSize=Filter->Prg.StaticData.Size();
+ if (StaticDataSize>0 && StaticDataSize<VM_GLOBALMEMSIZE)
+ {
+ StackFilter->Prg.StaticData.Add(StaticDataSize);
+ memcpy(&StackFilter->Prg.StaticData[0],&Filter->Prg.StaticData[0],StaticDataSize);
+ }
+
+ if (StackFilter->Prg.GlobalData.Size()<VM_FIXEDGLOBALSIZE)
+ {
+ StackFilter->Prg.GlobalData.Reset();
+ StackFilter->Prg.GlobalData.Add(VM_FIXEDGLOBALSIZE);
+ }
+ byte *GlobalData=&StackFilter->Prg.GlobalData[0];
+ for (int I=0;I<7;I++)
+ VM.SetValue((uint *)&GlobalData[I*4],StackFilter->Prg.InitR[I]);
+ VM.SetValue((uint *)&GlobalData[0x1c],StackFilter->BlockLength);
+ VM.SetValue((uint *)&GlobalData[0x20],0);
+ VM.SetValue((uint *)&GlobalData[0x2c],StackFilter->ExecCount);
+ memset(&GlobalData[0x30],0,16);
+
+ if (FirstByte & 8)
+ {
+ uint DataSize=RarVM::ReadData(Inp);
+ if (DataSize>=0x10000)
+ return(false);
+ unsigned int CurSize=StackFilter->Prg.GlobalData.Size();
+ if (CurSize<DataSize+VM_FIXEDGLOBALSIZE)
+ StackFilter->Prg.GlobalData.Add(DataSize+VM_FIXEDGLOBALSIZE-CurSize);
+ byte *GlobalData=&StackFilter->Prg.GlobalData[VM_FIXEDGLOBALSIZE];
+ for (int I=0;I<DataSize;I++)
+ {
+ GlobalData[I]=Inp.fgetbits()>>8;
+ Inp.faddbits(8);
+ }
+ }
+ return(true);
+}
+
+
+bool Unpack::UnpReadBuf()
+{
+ int DataSize=ReadTop-InAddr;
+ if (DataSize<0)
+ return(false);
+ if (InAddr>BitInput::MAX_SIZE/2)
+ {
+ if (DataSize>0)
+ memmove(InBuf,InBuf+InAddr,DataSize);
+ InAddr=0;
+ ReadTop=DataSize;
+ }
+ else
+ DataSize=ReadTop;
+ int ReadCode=UnpIO->UnpRead(InBuf+DataSize,(BitInput::MAX_SIZE-DataSize)&~0xf);
+ if (ReadCode>0)
+ ReadTop+=ReadCode;
+ ReadBorder=ReadTop-30;
+ return(ReadCode!=-1);
+}
+
+
+void Unpack::UnpWriteBuf()
+{
+ unsigned int WrittenBorder=WrPtr;
+ unsigned int WriteSize=(UnpPtr-WrittenBorder)&MAXWINMASK;
+ for (int I=0;I<PrgStack.Size();I++)
+ {
+ UnpackFilter *flt=PrgStack[I];
+ if (flt==NULL)
+ continue;
+ if (flt->NextWindow)
+ {
+ flt->NextWindow=false;
+ continue;
+ }
+ unsigned int BlockStart=flt->BlockStart;
+ unsigned int BlockLength=flt->BlockLength;
+ if (((BlockStart-WrittenBorder)&MAXWINMASK)<WriteSize)
+ {
+ if (WrittenBorder!=BlockStart)
+ {
+ UnpWriteArea(WrittenBorder,BlockStart);
+ WrittenBorder=BlockStart;
+ WriteSize=(UnpPtr-WrittenBorder)&MAXWINMASK;
+ }
+ if (BlockLength<=WriteSize)
+ {
+ unsigned int BlockEnd=(BlockStart+BlockLength)&MAXWINMASK;
+ if (BlockStart<BlockEnd || BlockEnd==0)
+ VM.SetMemory(0,Window+BlockStart,BlockLength);
+ else
+ {
+ unsigned int FirstPartLength=MAXWINSIZE-BlockStart;
+ VM.SetMemory(0,Window+BlockStart,FirstPartLength);
+ VM.SetMemory(FirstPartLength,Window,BlockEnd);
+ }
+ VM_PreparedProgram *Prg=&flt->Prg;
+ ExecuteCode(Prg);
+
+ byte *FilteredData=Prg->FilteredData;
+ unsigned int FilteredDataSize=Prg->FilteredDataSize;
+
+ delete PrgStack[I];
+ PrgStack[I]=NULL;
+ while (I+1<PrgStack.Size())
+ {
+ UnpackFilter *NextFilter=PrgStack[I+1];
+ if (NextFilter==NULL || NextFilter->BlockStart!=BlockStart ||
+ NextFilter->BlockLength!=FilteredDataSize || NextFilter->NextWindow)
+ break;
+ VM.SetMemory(0,FilteredData,FilteredDataSize);
+ VM_PreparedProgram *NextPrg=&PrgStack[I+1]->Prg;
+ ExecuteCode(NextPrg);
+ FilteredData=NextPrg->FilteredData;
+ FilteredDataSize=NextPrg->FilteredDataSize;
+ I++;
+ delete PrgStack[I];
+ PrgStack[I]=NULL;
+ }
+ UnpIO->UnpWrite(FilteredData,FilteredDataSize);
+ UnpSomeRead=true;
+ WrittenFileSize+=FilteredDataSize;
+ WrittenBorder=BlockEnd;
+ WriteSize=(UnpPtr-WrittenBorder)&MAXWINMASK;
+ }
+ else
+ {
+ for (int J=I;J<PrgStack.Size();J++)
+ {
+ UnpackFilter *flt=PrgStack[J];
+ if (flt!=NULL && flt->NextWindow)
+ flt->NextWindow=false;
+ }
+ WrPtr=WrittenBorder;
+ return;
+ }
+ }
+ }
+
+ UnpWriteArea(WrittenBorder,UnpPtr);
+ WrPtr=UnpPtr;
+}
+
+
+void Unpack::ExecuteCode(VM_PreparedProgram *Prg)
+{
+ if (Prg->GlobalData.Size()>0)
+ {
+ Prg->InitR[6]=int64to32(WrittenFileSize);
+ VM.SetValue((uint *)&Prg->GlobalData[0x24],int64to32(WrittenFileSize));
+ VM.SetValue((uint *)&Prg->GlobalData[0x28],int64to32(WrittenFileSize>>32));
+ VM.Execute(Prg);
+ }
+}
+
+
+void Unpack::UnpWriteArea(unsigned int StartPtr,unsigned int EndPtr)
+{
+ if (EndPtr!=StartPtr)
+ UnpSomeRead=true;
+ if (EndPtr<StartPtr)
+ {
+ UnpWriteData(&Window[StartPtr],-StartPtr & MAXWINMASK);
+ UnpWriteData(Window,EndPtr);
+ UnpAllBuf=true;
+ }
+ else
+ UnpWriteData(&Window[StartPtr],EndPtr-StartPtr);
+}
+
+
+void Unpack::UnpWriteData(byte *Data,int Size)
+{
+ if (WrittenFileSize>=DestUnpSize)
+ return;
+ int WriteSize=Size;
+ Int64 LeftToWrite=DestUnpSize-WrittenFileSize;
+ if (WriteSize>LeftToWrite)
+ WriteSize=int64to32(LeftToWrite);
+ UnpIO->UnpWrite(Data,WriteSize);
+ WrittenFileSize+=Size;
+}
+
+
+bool Unpack::ReadTables()
+{
+ byte BitLength[BC];
+ unsigned char Table[HUFF_TABLE_SIZE];
+ if (InAddr>ReadTop-25)
+ if (!UnpReadBuf())
+ return(false);
+ faddbits((8-InBit)&7);
+ unsigned int BitField=fgetbits();
+ if (BitField & 0x8000)
+ {
+ UnpBlockType=BLOCK_PPM;
+ return(PPM.DecodeInit(this,PPMEscChar));
+ }
+ UnpBlockType=BLOCK_LZ;
+
+ PrevLowDist=0;
+ LowDistRepCount=0;
+
+ if (!(BitField & 0x4000))
+ memset(UnpOldTable,0,sizeof(UnpOldTable));
+ faddbits(2);
+
+ for (int I=0;I<BC;I++)
+ {
+ int Length=(byte)(fgetbits() >> 12);
+ faddbits(4);
+ if (Length==15)
+ {
+ int ZeroCount=(byte)(fgetbits() >> 12);
+ faddbits(4);
+ if (ZeroCount==0)
+ BitLength[I]=15;
+ else
+ {
+ ZeroCount+=2;
+ while (ZeroCount-- > 0 && I<sizeof(BitLength)/sizeof(BitLength[0]))
+ BitLength[I++]=0;
+ I--;
+ }
+ }
+ else
+ BitLength[I]=Length;
+ }
+ MakeDecodeTables(BitLength,(struct Decode *)&BD,BC);
+
+ const int TableSize=HUFF_TABLE_SIZE;
+ for (int I=0;I<TableSize;)
+ {
+ if (InAddr>ReadTop-5)
+ if (!UnpReadBuf())
+ return(false);
+ int Number=DecodeNumber((struct Decode *)&BD);
+ if (Number<16)
+ {
+ Table[I]=(Number+UnpOldTable[I]) & 0xf;
+ I++;
+ }
+ else
+ if (Number<18)
+ {
+ int N;
+ if (Number==16)
+ {
+ N=(fgetbits() >> 13)+3;
+ faddbits(3);
+ }
+ else
+ {
+ N=(fgetbits() >> 9)+11;
+ faddbits(7);
+ }
+ while (N-- > 0 && I<TableSize)
+ {
+ Table[I]=Table[I-1];
+ I++;
+ }
+ }
+ else
+ {
+ int N;
+ if (Number==18)
+ {
+ N=(fgetbits() >> 13)+3;
+ faddbits(3);
+ }
+ else
+ {
+ N=(fgetbits() >> 9)+11;
+ faddbits(7);
+ }
+ while (N-- > 0 && I<TableSize)
+ Table[I++]=0;
+ }
+ }
+ TablesRead=true;
+ if (InAddr>ReadTop)
+ return(false);
+ MakeDecodeTables(&Table[0],(struct Decode *)&LD,NC);
+ MakeDecodeTables(&Table[NC],(struct Decode *)&DD,DC);
+ MakeDecodeTables(&Table[NC+DC],(struct Decode *)&LDD,LDC);
+ MakeDecodeTables(&Table[NC+DC+LDC],(struct Decode *)&RD,RC);
+ memcpy(UnpOldTable,Table,sizeof(UnpOldTable));
+ return(true);
+}
+
+
+void Unpack::UnpInitData(int Solid)
+{
+ if (!Solid)
+ {
+ TablesRead=false;
+ memset(OldDist,0,sizeof(OldDist));
+ OldDistPtr=0;
+ LastDist=LastLength=0;
+// memset(Window,0,MAXWINSIZE);
+ memset(UnpOldTable,0,sizeof(UnpOldTable));
+ UnpPtr=WrPtr=0;
+ PPMEscChar=2;
+
+ InitFilters();
+ }
+ InitBitInput();
+ PPMError=false;
+ WrittenFileSize=0;
+ ReadTop=0;
+ ReadBorder=0;
+#ifndef SFX_MODULE
+ // Igor Pavlov
+ // UnpInitData20(Solid);
+#endif
+}
+
+
+void Unpack::InitFilters()
+{
+ OldFilterLengths.Reset();
+ LastFilter=0;
+
+ for (int I=0;I<Filters.Size();I++)
+ delete Filters[I];
+ Filters.Reset();
+ for (int I=0;I<PrgStack.Size();I++)
+ delete PrgStack[I];
+ PrgStack.Reset();
+}
+
+
+void Unpack::MakeDecodeTables(unsigned char *LenTab,struct Decode *Dec,int Size)
+{
+ int LenCount[16],TmpPos[16],I;
+ long M,N;
+ memset(LenCount,0,sizeof(LenCount));
+ memset(Dec->DecodeNum,0,Size*sizeof(*Dec->DecodeNum));
+ for (I=0;I<Size;I++)
+ LenCount[LenTab[I] & 0xF]++;
+
+ LenCount[0]=0;
+ for (TmpPos[0]=Dec->DecodePos[0]=Dec->DecodeLen[0]=0,N=0,I=1;I<16;I++)
+ {
+ N=2*(N+LenCount[I]);
+ M=N<<(15-I);
+ if (M>0xFFFF)
+ M=0xFFFF;
+ Dec->DecodeLen[I]=(unsigned int)M;
+ TmpPos[I]=Dec->DecodePos[I]=Dec->DecodePos[I-1]+LenCount[I-1];
+ }
+
+ for (I=0;I<Size;I++)
+ if (LenTab[I]!=0)
+ Dec->DecodeNum[TmpPos[LenTab[I] & 0xF]++]=I;
+ Dec->MaxNum=Size;
+}
diff --git a/7zip/Compress/Rar29/Original/unpack.hpp b/7zip/Compress/Rar29/Original/unpack.hpp
new file mode 100755
index 00000000..83fb0f02
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/unpack.hpp
@@ -0,0 +1,205 @@
+#ifndef _RAR_UNPACK_
+#define _RAR_UNPACK_
+
+enum BLOCK_TYPES {BLOCK_LZ,BLOCK_PPM};
+
+struct Decode
+{
+ unsigned int MaxNum;
+ unsigned int DecodeLen[16];
+ unsigned int DecodePos[16];
+ unsigned int DecodeNum[2];
+};
+
+struct LitDecode
+{
+ unsigned int MaxNum;
+ unsigned int DecodeLen[16];
+ unsigned int DecodePos[16];
+ unsigned int DecodeNum[NC];
+};
+
+struct DistDecode
+{
+ unsigned int MaxNum;
+ unsigned int DecodeLen[16];
+ unsigned int DecodePos[16];
+ unsigned int DecodeNum[DC];
+};
+
+struct LowDistDecode
+{
+ unsigned int MaxNum;
+ unsigned int DecodeLen[16];
+ unsigned int DecodePos[16];
+ unsigned int DecodeNum[LDC];
+};
+
+struct RepDecode
+{
+ unsigned int MaxNum;
+ unsigned int DecodeLen[16];
+ unsigned int DecodePos[16];
+ unsigned int DecodeNum[RC];
+};
+
+struct BitDecode
+{
+ unsigned int MaxNum;
+ unsigned int DecodeLen[16];
+ unsigned int DecodePos[16];
+ unsigned int DecodeNum[BC];
+};
+
+struct UnpackFilter
+{
+ unsigned int BlockStart;
+ unsigned int BlockLength;
+ unsigned int ExecCount;
+ bool NextWindow;
+ VM_PreparedProgram Prg;
+};
+
+/***************************** Unpack v 2.0 *********************************/
+struct MultDecode
+{
+ unsigned int MaxNum;
+ unsigned int DecodeLen[16];
+ unsigned int DecodePos[16];
+ unsigned int DecodeNum[MC20];
+};
+
+struct AudioVariables
+{
+ int K1,K2,K3,K4,K5;
+ int D1,D2,D3,D4;
+ int LastDelta;
+ unsigned int Dif[11];
+ unsigned int ByteCount;
+ int LastChar;
+};
+/***************************** Unpack v 2.0 *********************************/
+
+
+class Unpack:private BitInput
+{
+ private:
+ friend class Pack;
+
+ void Unpack29(bool Solid);
+ bool UnpReadBuf();
+ void UnpWriteBuf();
+ void ExecuteCode(VM_PreparedProgram *Prg);
+ void UnpWriteArea(unsigned int StartPtr,unsigned int EndPtr);
+ void UnpWriteData(byte *Data,int Size);
+ bool ReadTables();
+ void MakeDecodeTables(unsigned char *LenTab,struct Decode *Dec,int Size);
+ int DecodeNumber(struct Decode *Dec);
+ void CopyString();
+ inline void InsertOldDist(unsigned int Distance);
+ inline void InsertLastMatch(unsigned int Length,unsigned int Distance);
+ void UnpInitData(int Solid);
+ void CopyString(unsigned int Length,unsigned int Distance);
+ bool ReadEndOfBlock();
+ bool ReadVMCode();
+ bool ReadVMCodePPM();
+ bool AddVMCode(unsigned int FirstByte,byte *Code,int CodeSize);
+ void InitFilters();
+
+ ComprDataIO *UnpIO;
+ ModelPPM PPM;
+ int PPMEscChar;
+
+ RarVM VM;
+ Array<UnpackFilter*> Filters;
+ Array<UnpackFilter*> PrgStack;
+ Array<int> OldFilterLengths;
+ int LastFilter;
+
+ bool TablesRead;
+ struct LitDecode LD;
+ struct DistDecode DD;
+ struct LowDistDecode LDD;
+ struct RepDecode RD;
+ struct BitDecode BD;
+
+ unsigned int OldDist[4],OldDistPtr;
+ unsigned int LastDist,LastLength;
+
+ unsigned int UnpPtr,WrPtr;
+
+ int ReadTop;
+ int ReadBorder;
+
+ unsigned char UnpOldTable[HUFF_TABLE_SIZE];
+
+ int UnpBlockType;
+
+ byte *Window;
+ bool ExternalWindow;
+
+
+ Int64 DestUnpSize;
+
+ bool Suspended;
+ bool UnpAllBuf;
+ bool UnpSomeRead;
+ Int64 WrittenFileSize;
+ bool FileExtracted;
+ bool PPMError;
+
+ int PrevLowDist,LowDistRepCount;
+
+/***************************** Unpack v 1.5 *********************************/
+ void Unpack15(bool Solid);
+ void ShortLZ();
+ void LongLZ();
+ void HuffDecode();
+ void GetFlagsBuf();
+ void OldUnpInitData(int Solid);
+ void InitHuff();
+ void CorrHuff(unsigned int *CharSet,unsigned int *NumToPlace);
+ void OldCopyString(unsigned int Distance,unsigned int Length);
+ unsigned int DecodeNum(int Num,unsigned int StartPos,
+ unsigned int *DecTab,unsigned int *PosTab);
+ void OldUnpWriteBuf();
+
+ unsigned int ChSet[256],ChSetA[256],ChSetB[256],ChSetC[256];
+ unsigned int Place[256],PlaceA[256],PlaceB[256],PlaceC[256];
+ unsigned int NToPl[256],NToPlB[256],NToPlC[256];
+ unsigned int FlagBuf,AvrPlc,AvrPlcB,AvrLn1,AvrLn2,AvrLn3;
+ int Buf60,NumHuf,StMode,LCount,FlagsCnt;
+ unsigned int Nhfb,Nlzb,MaxDist3;
+/***************************** Unpack v 1.5 *********************************/
+
+/***************************** Unpack v 2.0 *********************************/
+ void Unpack20(bool Solid);
+ struct MultDecode MD[4];
+ unsigned char UnpOldTable20[MC20*4];
+ int UnpAudioBlock,UnpChannels,UnpCurChannel,UnpChannelDelta;
+ void CopyString20(unsigned int Length,unsigned int Distance);
+ bool ReadTables20();
+ void UnpInitData20(int Solid);
+ void ReadLastTables();
+ byte DecodeAudio(int Delta);
+ struct AudioVariables AudV[4];
+/***************************** Unpack v 2.0 *********************************/
+
+ public:
+ Unpack(ComprDataIO *DataIO);
+ ~Unpack();
+ void Init(byte *Window=NULL);
+ void DoUnpack(int Method,bool Solid);
+ bool IsFileExtracted() {return(FileExtracted);}
+ void SetDestSize(Int64 DestSize) {DestUnpSize=DestSize;FileExtracted=false;}
+ void SetSuspended(bool Suspended) {Unpack::Suspended=Suspended;}
+
+ unsigned int GetChar()
+ {
+ if (InAddr>BitInput::MAX_SIZE-30)
+ UnpReadBuf();
+ return(InBuf[InAddr++]);
+ }
+};
+
+#endif
diff --git a/7zip/Compress/Rar29/Original/unpack15.cpp b/7zip/Compress/Rar29/Original/unpack15.cpp
new file mode 100755
index 00000000..a0fa897f
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/unpack15.cpp
@@ -0,0 +1,507 @@
+#define STARTL1 2
+static unsigned int DecL1[]={0x8000,0xa000,0xc000,0xd000,0xe000,0xea00,
+ 0xee00,0xf000,0xf200,0xf200,0xffff};
+static unsigned int PosL1[]={0,0,0,2,3,5,7,11,16,20,24,32,32};
+
+#define STARTL2 3
+static unsigned int DecL2[]={0xa000,0xc000,0xd000,0xe000,0xea00,0xee00,
+ 0xf000,0xf200,0xf240,0xffff};
+static unsigned int PosL2[]={0,0,0,0,5,7,9,13,18,22,26,34,36};
+
+#define STARTHF0 4
+static unsigned int DecHf0[]={0x8000,0xc000,0xe000,0xf200,0xf200,0xf200,
+ 0xf200,0xf200,0xffff};
+static unsigned int PosHf0[]={0,0,0,0,0,8,16,24,33,33,33,33,33};
+
+
+#define STARTHF1 5
+static unsigned int DecHf1[]={0x2000,0xc000,0xe000,0xf000,0xf200,0xf200,
+ 0xf7e0,0xffff};
+static unsigned int PosHf1[]={0,0,0,0,0,0,4,44,60,76,80,80,127};
+
+
+#define STARTHF2 5
+static unsigned int DecHf2[]={0x1000,0x2400,0x8000,0xc000,0xfa00,0xffff,
+ 0xffff,0xffff};
+static unsigned int PosHf2[]={0,0,0,0,0,0,2,7,53,117,233,0,0};
+
+
+#define STARTHF3 6
+static unsigned int DecHf3[]={0x800,0x2400,0xee00,0xfe80,0xffff,0xffff,
+ 0xffff};
+static unsigned int PosHf3[]={0,0,0,0,0,0,0,2,16,218,251,0,0};
+
+
+#define STARTHF4 8
+static unsigned int DecHf4[]={0xff00,0xffff,0xffff,0xffff,0xffff,0xffff};
+static unsigned int PosHf4[]={0,0,0,0,0,0,0,0,0,255,0,0,0};
+
+
+void Unpack::Unpack15(bool Solid)
+{
+ if (Suspended)
+ UnpPtr=WrPtr;
+ else
+ {
+ UnpInitData(Solid);
+ OldUnpInitData(Solid);
+ UnpReadBuf();
+ if (!Solid)
+ {
+ InitHuff();
+ UnpPtr=0;
+ }
+ else
+ UnpPtr=WrPtr;
+ --DestUnpSize;
+ }
+ if (DestUnpSize>=0)
+ {
+ GetFlagsBuf();
+ FlagsCnt=8;
+ }
+
+ while (DestUnpSize>=0)
+ {
+ UnpPtr&=MAXWINMASK;
+
+ if (InAddr>ReadTop-30 && !UnpReadBuf())
+ break;
+ if (((WrPtr-UnpPtr) & MAXWINMASK)<270 && WrPtr!=UnpPtr)
+ {
+ OldUnpWriteBuf();
+ if (Suspended)
+ return;
+ }
+ if (StMode)
+ {
+ HuffDecode();
+ continue;
+ }
+
+ if (--FlagsCnt < 0)
+ {
+ GetFlagsBuf();
+ FlagsCnt=7;
+ }
+
+ if (FlagBuf & 0x80)
+ {
+ FlagBuf<<=1;
+ if (Nlzb > Nhfb)
+ LongLZ();
+ else
+ HuffDecode();
+ }
+ else
+ {
+ FlagBuf<<=1;
+ if (--FlagsCnt < 0)
+ {
+ GetFlagsBuf();
+ FlagsCnt=7;
+ }
+ if (FlagBuf & 0x80)
+ {
+ FlagBuf<<=1;
+ if (Nlzb > Nhfb)
+ HuffDecode();
+ else
+ LongLZ();
+ }
+ else
+ {
+ FlagBuf<<=1;
+ ShortLZ();
+ }
+ }
+ }
+ OldUnpWriteBuf();
+}
+
+
+void Unpack::OldUnpWriteBuf()
+{
+ if (UnpPtr!=WrPtr)
+ UnpSomeRead=true;
+ if (UnpPtr<WrPtr)
+ {
+ UnpIO->UnpWrite(&Window[WrPtr],-WrPtr & MAXWINMASK);
+ UnpIO->UnpWrite(Window,UnpPtr);
+ UnpAllBuf=true;
+ }
+ else
+ UnpIO->UnpWrite(&Window[WrPtr],UnpPtr-WrPtr);
+ WrPtr=UnpPtr;
+}
+
+
+void Unpack::ShortLZ()
+{
+ static unsigned int ShortLen1[]={1,3,4,4,5,6,7,8,8,4,4,5,6,6,4,0};
+ static unsigned int ShortXor1[]={0,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xfe,
+ 0xff,0xc0,0x80,0x90,0x98,0x9c,0xb0};
+ static unsigned int ShortLen2[]={2,3,3,3,4,4,5,6,6,4,4,5,6,6,4,0};
+ static unsigned int ShortXor2[]={0,0x40,0x60,0xa0,0xd0,0xe0,0xf0,0xf8,
+ 0xfc,0xc0,0x80,0x90,0x98,0x9c,0xb0};
+
+
+ unsigned int Length,SaveLength;
+ unsigned int LastDistance;
+ unsigned int Distance;
+ int DistancePlace;
+ NumHuf=0;
+
+ unsigned int BitField=fgetbits();
+ if (LCount==2)
+ {
+ faddbits(1);
+ if (BitField >= 0x8000)
+ {
+ OldCopyString((unsigned int)LastDist,LastLength);
+ return;
+ }
+ BitField <<= 1;
+ LCount=0;
+ }
+
+ BitField>>=8;
+
+ ShortLen1[1]=ShortLen2[3]=Buf60+3;
+
+ if (AvrLn1<37)
+ {
+ for (Length=0;;Length++)
+ if (((BitField^ShortXor1[Length]) & (~(0xff>>ShortLen1[Length])))==0)
+ break;
+ faddbits(ShortLen1[Length]);
+ }
+ else
+ {
+ for (Length=0;;Length++)
+ if (((BitField^ShortXor2[Length]) & (~(0xff>>ShortLen2[Length])))==0)
+ break;
+ faddbits(ShortLen2[Length]);
+ }
+
+ if (Length >= 9)
+ {
+ if (Length == 9)
+ {
+ LCount++;
+ OldCopyString((unsigned int)LastDist,LastLength);
+ return;
+ }
+ if (Length == 14)
+ {
+ LCount=0;
+ Length=DecodeNum(fgetbits(),STARTL2,DecL2,PosL2)+5;
+ Distance=(fgetbits()>>1) | 0x8000;
+ faddbits(15);
+ LastLength=Length;
+ LastDist=Distance;
+ OldCopyString(Distance,Length);
+ return;
+ }
+
+ LCount=0;
+ SaveLength=Length;
+ Distance=OldDist[(OldDistPtr-(Length-9)) & 3];
+ Length=DecodeNum(fgetbits(),STARTL1,DecL1,PosL1)+2;
+ if (Length==0x101 && SaveLength==10)
+ {
+ Buf60 ^= 1;
+ return;
+ }
+ if (Distance > 256)
+ Length++;
+ if (Distance >= MaxDist3)
+ Length++;
+
+ OldDist[OldDistPtr++]=Distance;
+ OldDistPtr = OldDistPtr & 3;
+ LastLength=Length;
+ LastDist=Distance;
+ OldCopyString(Distance,Length);
+ return;
+ }
+
+ LCount=0;
+ AvrLn1 += Length;
+ AvrLn1 -= AvrLn1 >> 4;
+
+ DistancePlace=DecodeNum(fgetbits(),STARTHF2,DecHf2,PosHf2) & 0xff;
+ Distance=ChSetA[DistancePlace];
+ if (--DistancePlace != -1)
+ {
+ PlaceA[Distance]--;
+ LastDistance=ChSetA[DistancePlace];
+ PlaceA[LastDistance]++;
+ ChSetA[DistancePlace+1]=LastDistance;
+ ChSetA[DistancePlace]=Distance;
+ }
+ Length+=2;
+ OldDist[OldDistPtr++] = ++Distance;
+ OldDistPtr = OldDistPtr & 3;
+ LastLength=Length;
+ LastDist=Distance;
+ OldCopyString(Distance,Length);
+}
+
+
+void Unpack::LongLZ()
+{
+ unsigned int Length;
+ unsigned int Distance;
+ unsigned int DistancePlace,NewDistancePlace;
+ unsigned int OldAvr2,OldAvr3;
+
+ NumHuf=0;
+ Nlzb+=16;
+ if (Nlzb > 0xff)
+ {
+ Nlzb=0x90;
+ Nhfb >>= 1;
+ }
+ OldAvr2=AvrLn2;
+
+ unsigned int BitField=fgetbits();
+ if (AvrLn2 >= 122)
+ Length=DecodeNum(BitField,STARTL2,DecL2,PosL2);
+ else
+ if (AvrLn2 >= 64)
+ Length=DecodeNum(BitField,STARTL1,DecL1,PosL1);
+ else
+ if (BitField < 0x100)
+ {
+ Length=BitField;
+ faddbits(16);
+ }
+ else
+ {
+ for (Length=0;((BitField<<Length)&0x8000)==0;Length++)
+ ;
+ faddbits(Length+1);
+ }
+
+ AvrLn2 += Length;
+ AvrLn2 -= AvrLn2 >> 5;
+
+ BitField=fgetbits();
+ if (AvrPlcB > 0x28ff)
+ DistancePlace=DecodeNum(BitField,STARTHF2,DecHf2,PosHf2);
+ else
+ if (AvrPlcB > 0x6ff)
+ DistancePlace=DecodeNum(BitField,STARTHF1,DecHf1,PosHf1);
+ else
+ DistancePlace=DecodeNum(BitField,STARTHF0,DecHf0,PosHf0);
+
+ AvrPlcB += DistancePlace;
+ AvrPlcB -= AvrPlcB >> 8;
+ while (1)
+ {
+ Distance = ChSetB[DistancePlace & 0xff];
+ NewDistancePlace = NToPlB[Distance++ & 0xff]++;
+ if (!(Distance & 0xff))
+ CorrHuff(ChSetB,NToPlB);
+ else
+ break;
+ }
+
+ ChSetB[DistancePlace]=ChSetB[NewDistancePlace];
+ ChSetB[NewDistancePlace]=Distance;
+
+ Distance=((Distance & 0xff00) | (fgetbits() >> 8)) >> 1;
+ faddbits(7);
+
+ OldAvr3=AvrLn3;
+ if (Length!=1 && Length!=4)
+ if (Length==0 && Distance <= MaxDist3)
+ {
+ AvrLn3++;
+ AvrLn3 -= AvrLn3 >> 8;
+ }
+ else
+ if (AvrLn3 > 0)
+ AvrLn3--;
+ Length+=3;
+ if (Distance >= MaxDist3)
+ Length++;
+ if (Distance <= 256)
+ Length+=8;
+ if (OldAvr3 > 0xb0 || AvrPlc >= 0x2a00 && OldAvr2 < 0x40)
+ MaxDist3=0x7f00;
+ else
+ MaxDist3=0x2001;
+ OldDist[OldDistPtr++]=Distance;
+ OldDistPtr = OldDistPtr & 3;
+ LastLength=Length;
+ LastDist=Distance;
+ OldCopyString(Distance,Length);
+}
+
+
+void Unpack::HuffDecode()
+{
+ unsigned int CurByte,NewBytePlace;
+ unsigned int Length;
+ unsigned int Distance;
+ int BytePlace;
+
+ unsigned int BitField=fgetbits();
+
+ if (AvrPlc > 0x75ff)
+ BytePlace=DecodeNum(BitField,STARTHF4,DecHf4,PosHf4);
+ else
+ if (AvrPlc > 0x5dff)
+ BytePlace=DecodeNum(BitField,STARTHF3,DecHf3,PosHf3);
+ else
+ if (AvrPlc > 0x35ff)
+ BytePlace=DecodeNum(BitField,STARTHF2,DecHf2,PosHf2);
+ else
+ if (AvrPlc > 0x0dff)
+ BytePlace=DecodeNum(BitField,STARTHF1,DecHf1,PosHf1);
+ else
+ BytePlace=DecodeNum(BitField,STARTHF0,DecHf0,PosHf0);
+ BytePlace&=0xff;
+ if (StMode)
+ {
+ if (BytePlace==0 && BitField > 0xfff)
+ BytePlace=0x100;
+ if (--BytePlace==-1)
+ {
+ BitField=fgetbits();
+ faddbits(1);
+ if (BitField & 0x8000)
+ {
+ NumHuf=StMode=0;
+ return;
+ }
+ else
+ {
+ Length = (BitField & 0x4000) ? 4 : 3;
+ faddbits(1);
+ Distance=DecodeNum(fgetbits(),STARTHF2,DecHf2,PosHf2);
+ Distance = (Distance << 5) | (fgetbits() >> 11);
+ faddbits(5);
+ OldCopyString(Distance,Length);
+ return;
+ }
+ }
+ }
+ else
+ if (NumHuf++ >= 16 && FlagsCnt==0)
+ StMode=1;
+ AvrPlc += BytePlace;
+ AvrPlc -= AvrPlc >> 8;
+ Nhfb+=16;
+ if (Nhfb > 0xff)
+ {
+ Nhfb=0x90;
+ Nlzb >>= 1;
+ }
+
+ Window[UnpPtr++]=(byte)(ChSet[BytePlace]>>8);
+ --DestUnpSize;
+
+ while (1)
+ {
+ CurByte=ChSet[BytePlace];
+ NewBytePlace=NToPl[CurByte++ & 0xff]++;
+ if ((CurByte & 0xff) > 0xa1)
+ CorrHuff(ChSet,NToPl);
+ else
+ break;
+ }
+
+ ChSet[BytePlace]=ChSet[NewBytePlace];
+ ChSet[NewBytePlace]=CurByte;
+}
+
+
+void Unpack::GetFlagsBuf()
+{
+ unsigned int Flags,NewFlagsPlace;
+ unsigned int FlagsPlace=DecodeNum(fgetbits(),STARTHF2,DecHf2,PosHf2);
+
+ while (1)
+ {
+ 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 Unpack::OldUnpInitData(int Solid)
+{
+ if (!Solid)
+ {
+ AvrPlcB=AvrLn1=AvrLn2=AvrLn3=NumHuf=Buf60=0;
+ AvrPlc=0x3500;
+ MaxDist3=0x2001;
+ Nhfb=Nlzb=0x80;
+ }
+ FlagsCnt=0;
+ FlagBuf=0;
+ StMode=0;
+ LCount=0;
+ ReadTop=0;
+}
+
+
+void Unpack::InitHuff()
+{
+ for (unsigned int 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);
+}
+
+
+void Unpack::CorrHuff(unsigned int *CharSet,unsigned int *NumToPlace)
+{
+ int I,J;
+ for (I=7;I>=0;I--)
+ for (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 Unpack::OldCopyString(unsigned int Distance,unsigned int Length)
+{
+ DestUnpSize-=Length;
+ while (Length--)
+ {
+ Window[UnpPtr]=Window[(UnpPtr-Distance) & MAXWINMASK];
+ UnpPtr=(UnpPtr+1) & MAXWINMASK;
+ }
+}
+
+
+unsigned int Unpack::DecodeNum(int Num,unsigned int StartPos,
+ unsigned int *DecTab,unsigned int *PosTab)
+{
+ int I;
+ for (Num&=0xfff0,I=0;DecTab[I]<=Num;I++)
+ StartPos++;
+ faddbits(StartPos);
+ return(((Num-(I ? DecTab[I-1]:0))>>(16-StartPos))+PosTab[StartPos]);
+}
diff --git a/7zip/Compress/Rar29/Original/version.hpp b/7zip/Compress/Rar29/Original/version.hpp
new file mode 100755
index 00000000..6a5c653d
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/version.hpp
@@ -0,0 +1,6 @@
+#define RARVER_MAJOR 3
+#define RARVER_MINOR 50
+#define RARVER_BETA 0
+#define RARVER_DAY 3
+#define RARVER_MONTH 8
+#define RARVER_YEAR 2005
diff --git a/7zip/Compress/Rar29/Original/volume.hpp b/7zip/Compress/Rar29/Original/volume.hpp
new file mode 100755
index 00000000..64653405
--- /dev/null
+++ b/7zip/Compress/Rar29/Original/volume.hpp
@@ -0,0 +1,11 @@
+#ifndef _RAR_VOLUME_
+#define _RAR_VOLUME_
+
+void SplitArchive(Archive &Arc,FileHeader *fh,Int64 *HeaderPos,
+ ComprDataIO *DataIO);
+bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName,
+ char Command);
+void SetVolWrite(Archive &Dest,Int64 VolSize);
+bool AskNextVol(char *ArcName);
+
+#endif
diff --git a/7zip/Compress/Rar29/Rar29.dsp b/7zip/Compress/Rar29/Rar29.dsp
new file mode 100755
index 00000000..7c3f3ba2
--- /dev/null
+++ b/7zip/Compress/Rar29/Rar29.dsp
@@ -0,0 +1,415 @@
+# Microsoft Developer Studio Project File - Name="Rar29" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=Rar29 - 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 "RAR29.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 "RAR29.mak" CFG="Rar29 - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Rar29 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Rar29 - 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)" == "Rar29 - 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 "RAR29_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RAR29_EXPORTS" /D "SILENT" /D "NOCRYPT" /D "NOVOLUME" /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:\Program Files\7-Zip\Codecs\Rar29.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Rar29 - 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 "RAR29_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 "RAR29_EXPORTS" /D "SILENT" /D "NOCRYPT" /D "NOVOLUME" /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:\Program Files\7-Zip\Codecs\Rar29.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "Rar29 - Win32 Release"
+# Name "Rar29 - Win32 Debug"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Codec.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\DllExports.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 "7zip Common"
+
+# PROP Default_Filter ""
+# 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\MSBFDecoder.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\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# End Group
+# Begin Group "UnRar Sources"
+
+# PROP Default_Filter ""
+# Begin Group "hpp"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\Original\int64.hpp
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=Original\crc.cpp
+
+!IF "$(CFG)" == "Rar29 - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=Original\errhnd.cpp
+
+!IF "$(CFG)" == "Rar29 - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=Original\getbits.cpp
+
+!IF "$(CFG)" == "Rar29 - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=Original\rar.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=Original\rarvm.cpp
+
+!IF "$(CFG)" == "Rar29 - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=Original\rdwrfn.cpp
+
+!IF "$(CFG)" == "Rar29 - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=Original\rdwrfn.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=Original\resource.cpp
+
+!IF "$(CFG)" == "Rar29 - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=Original\smallfn.cpp
+
+!IF "$(CFG)" == "Rar29 - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=Original\system.cpp
+
+!IF "$(CFG)" == "Rar29 - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=Original\unpack.cpp
+
+!IF "$(CFG)" == "Rar29 - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=Original\unpack.hpp
+# End Source File
+# End Group
+# Begin Group "Rar20"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Rar20\Rar20Const.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Rar20\Rar20Decoder.cpp
+
+!IF "$(CFG)" == "Rar29 - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\Rar20\Rar20Decoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Rar20\Rar20ExtConst.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Rar20\Rar20Multimedia.cpp
+
+!IF "$(CFG)" == "Rar29 - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\Rar20\Rar20Multimedia.h
+# End Source File
+# End Group
+# Begin Group "LZ"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\LZ\LZOutWindow.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\LZOutWindow.h
+# End Source File
+# End Group
+# Begin Group "Huffman"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Huffman\HuffmanDecoder.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\Alloc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Alloc.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\Rar29Decoder.cpp
+
+!IF "$(CFG)" == "Rar29 - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\Rar29Decoder.h
+# End Source File
+# End Target
+# End Project
diff --git a/7zip/Compress/Rar29/Rar29.dsw b/7zip/Compress/Rar29/Rar29.dsw
new file mode 100755
index 00000000..61cbfecb
--- /dev/null
+++ b/7zip/Compress/Rar29/Rar29.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "RAR29"=.\RAR29.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/7zip/Compress/Rar29/Rar29Decoder.cpp b/7zip/Compress/Rar29/Rar29Decoder.cpp
new file mode 100755
index 00000000..35daea87
--- /dev/null
+++ b/7zip/Compress/Rar29/Rar29Decoder.cpp
@@ -0,0 +1,153 @@
+// Rar29Decoder.cpp
+// According to unRAR license,
+// this code may not be used to develop a
+// RAR (WinRAR) compatible archiver
+
+#include "StdAfx.h"
+
+#include "Rar29Decoder.h"
+
+#include "Windows/Defs.h"
+
+// #include "Original/unpack15.cpp"
+
+ErrorHandler ErrHandler;
+
+namespace NCompress {
+namespace NRar29 {
+
+CDecoder::CDecoder():
+ m_IsSolid(false),
+ // DataIO(NULL)
+ DataIO()
+{
+ Unp = new Unpack(&DataIO);
+ Unp->Init(NULL);
+}
+
+CDecoder::~CDecoder()
+{
+ delete Unp;
+}
+
+STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ // CCoderReleaser coderReleaser(this);
+
+ DataIO.CurUnpRead=0;
+ DataIO.CurUnpWrite=0;
+ DataIO.UnpFileCRC=0xffffffff;
+ DataIO.PackedCRC=0xffffffff;
+ /*
+ DataIO.SetEncryption(
+ 0,0,
+ NULL,false);
+ */
+
+ DataIO.SetPackedSizeToRead(*inSize);
+ DataIO.SetFiles(inStream, outStream, progress);
+ DataIO.SetTestMode(false);
+ // DataIO.SetSkipUnpCRC(SkipSolid);
+ /*
+ if (!TestMode && Arc.NewLhd.FullUnpSize>0x1000)
+ CurFile.Prealloc(Arc.NewLhd.FullUnpSize);
+
+ CurFile.SetAllowDelete(!Cmd->KeepBroken);
+ */
+
+ Unp->SetDestSize(*outSize);
+
+ Unp->DoUnpack(29, m_IsSolid);
+ return S_OK;
+}
+
+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 CExitCode &exitCode) { return exitCode.Result; }
+ catch(...) { return S_FALSE; }
+}
+
+STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
+{
+ if (size < 1)
+ return E_INVALIDARG;
+ m_IsSolid = (data[0] != 0);
+ return S_OK;
+}
+
+}
+
+
+namespace NRar15 {
+
+CDecoder::CDecoder():
+ m_IsSolid(false),
+ DataIO()
+{
+ Unp=new Unpack(&DataIO);
+ Unp->Init(NULL);
+}
+
+CDecoder::~CDecoder()
+{
+ delete Unp;
+}
+
+
+STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ // CCoderReleaser coderReleaser(this);
+
+ DataIO.CurUnpRead=0;
+ DataIO.CurUnpWrite=0;
+ DataIO.UnpFileCRC=0xffffffff;
+ DataIO.PackedCRC=0xffffffff;
+ /*
+ DataIO.SetEncryption(
+ 0,0,
+ NULL,false);
+ */
+
+ DataIO.SetPackedSizeToRead(*inSize);
+ DataIO.SetFiles(inStream, outStream, progress);
+ DataIO.SetTestMode(false);
+ // DataIO.SetSkipUnpCRC(SkipSolid);
+ /*
+ if (!TestMode && Arc.NewLhd.FullUnpSize>0x1000)
+ CurFile.Prealloc(Arc.NewLhd.FullUnpSize);
+
+ CurFile.SetAllowDelete(!Cmd->KeepBroken);
+ */
+ Unp->SetDestSize(*outSize);
+ Unp->DoUnpack(15, m_IsSolid);
+ return S_OK;
+}
+
+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 CExitCode &exitCode) { return exitCode.Result; }
+ catch(...) { return S_FALSE;}
+}
+
+STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
+{
+ if (size < 1)
+ return E_INVALIDARG;
+ m_IsSolid = (data[0] != 0);
+ return S_OK;
+}
+
+}
+
+}
diff --git a/7zip/Compress/Rar29/Rar29Decoder.h b/7zip/Compress/Rar29/Rar29Decoder.h
new file mode 100755
index 00000000..de0044fd
--- /dev/null
+++ b/7zip/Compress/Rar29/Rar29Decoder.h
@@ -0,0 +1,97 @@
+// Rar29Decoder.h
+// According to unRAR license,
+// this code may not be used to develop a
+// RAR (WinRAR) compatible archiver
+
+#ifndef __RAR_DECODER_H
+#define __RAR_DECODER_H
+
+#include "Common/MyCom.h"
+
+#include "../../ICoder.h"
+
+#include "Original/rar.hpp"
+
+namespace NCompress {
+
+namespace NRar29 {
+
+class CDecoder :
+ public ICompressCoder,
+ public ICompressSetDecoderProperties2,
+ public CMyUnknownImp
+{
+ Unpack *Unp;
+ bool m_IsSolid;
+public:
+ ComprDataIO DataIO;
+ CDecoder();
+ ~CDecoder();
+ /*
+ class CCoderReleaser
+ {
+ CCoder *m_Coder;
+ public:
+ CCoderReleaser(CCoder *aCoder): m_Coder(aCoder) {}
+ ~CCoderReleaser()
+ {
+ m_Coder->DataIO.ReleaseStreams();
+ }
+ };
+ */
+ MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)
+
+ // void ReleaseStreams();
+ 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);
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+};
+
+}
+
+namespace NRar15{
+
+class CDecoder :
+ public ICompressCoder,
+ public ICompressSetDecoderProperties2,
+ public CMyUnknownImp
+{
+ Unpack *Unp;
+ bool m_IsSolid;
+public:
+ ComprDataIO DataIO;
+ CDecoder();
+ ~CDecoder();
+ /*
+ class CCoderReleaser
+ {
+ CDecoder *m_Coder;
+ public:
+ CCoderReleaser(CDecoder *coder): m_Coder(coder) {}
+ ~CCoderReleaser()
+ {
+ m_Coder->DataIO.ReleaseStreams();
+ }
+ };
+ */
+ MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)
+
+ // void ReleaseStreams();
+ 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);
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+};
+
+}
+
+}
+
+#endif
diff --git a/7zip/Compress/Rar29/StdAfx.cpp b/7zip/Compress/Rar29/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/7zip/Compress/Rar29/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/7zip/Compress/Rar29/StdAfx.h b/7zip/Compress/Rar29/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/7zip/Compress/Rar29/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/7zip/Compress/Rar29/makefile b/7zip/Compress/Rar29/makefile
new file mode 100755
index 00000000..19082cb9
--- /dev/null
+++ b/7zip/Compress/Rar29/makefile
@@ -0,0 +1,62 @@
+PROG = Rar29.dll
+DEF_FILE = ../Codec.def
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib
+
+RAR29_OBJS = \
+ $O\DllExports.obj \
+ $O\Rar29Decoder.obj \
+
+RAR29_OPT_OBJS = \
+ $O\crc.obj \
+ $O\errhnd.obj \
+ $O\getbits.obj \
+ $O\rarvm.obj \
+ $O\rdwrfn.obj \
+ $O\resource.obj \
+ $O\smallfn.obj \
+ $O\system.obj \
+ $O\unpack.obj \
+
+RAR20_OPT_OBJS = \
+ $O\Rar20Decoder.obj \
+ $O\Rar20Multimedia.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\InBuffer.obj \
+ $O\OutBuffer.obj \
+ $O\StreamUtils.obj \
+
+LZ_OBJS = \
+ $O\LZOutWindow.obj \
+
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(RAR29_OBJS) \
+ $(RAR29_OPT_OBJS) \
+ $(RAR20_OPT_OBJS) \
+ $(COMMON_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(LZ_OBJS) \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+COMPL_SPEC = $(CPP) $(CFLAGS_O2) -DSILENT -DNOCRYPT -DNOVOLUME $**
+
+$(RAR29_OBJS): $(*B).cpp
+ $(COMPL)
+$(RAR29_OPT_OBJS): Original/$(*B).cpp
+ $(COMPL_SPEC)
+$(RAR20_OPT_OBJS): ../Rar20/$(*B).cpp
+ $(COMPL_O2)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$(LZ_OBJS): ../LZ/$(*B).cpp
+ $(COMPL)
diff --git a/7zip/Compress/Rar29/resource.rc b/7zip/Compress/Rar29/resource.rc
new file mode 100755
index 00000000..bb5e2ec9
--- /dev/null
+++ b/7zip/Compress/Rar29/resource.rc
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("Rar29 Codec", "Rar29")
diff --git a/7zip/Crypto/7zAES/7zAES.cpp b/7zip/Crypto/7zAES/7zAES.cpp
index dcf69cb6..a0d0882b 100755
--- a/7zip/Crypto/7zAES/7zAES.cpp
+++ b/7zip/Crypto/7zAES/7zAES.cpp
@@ -5,6 +5,7 @@
#include "Windows/Defs.h"
#include "Windows/Synchronization.h"
#include "../../Common/StreamObjects.h"
+#include "../../Common/StreamUtils.h"
#include "7zAES.h"
// #include "../../Hash/Common/CryptoHashInterface.h"
@@ -169,11 +170,11 @@ STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
RINOK(outStream->Write(&secondByte, 1, NULL));
if (_key.SaltSize > 0)
{
- RINOK(outStream->Write(_key.Salt, _key.SaltSize, NULL));
+ RINOK(WriteStream(outStream, _key.Salt, _key.SaltSize, NULL));
}
if (ivSize > 0)
{
- RINOK(outStream->Write(_iv, ivSize, NULL));
+ RINOK(WriteStream(outStream, _iv, ivSize, NULL));
}
return S_OK;
}
diff --git a/7zip/Crypto/7zAES/7zAES.dsp b/7zip/Crypto/7zAES/7zAES.dsp
index d329ea6f..1c177670 100755
--- a/7zip/Crypto/7zAES/7zAES.dsp
+++ b/7zip/Crypto/7zAES/7zAES.dsp
@@ -154,6 +154,14 @@ 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\StringConvert.cpp
# End Source File
# Begin Source File
diff --git a/7zip/Crypto/7zAES/makefile b/7zip/Crypto/7zAES/makefile
index 49b0fbf0..d8daaf69 100755
--- a/7zip/Crypto/7zAES/makefile
+++ b/7zip/Crypto/7zAES/makefile
@@ -22,6 +22,7 @@ WIN_OBJS = \
7ZIP_COMMON_OBJS = \
$O\StreamObjects.obj \
+ $O\StreamUtils.obj \
OBJS = \
$O\StdAfx.obj \
diff --git a/7zip/Crypto/RarAES/RarAES.cpp b/7zip/Crypto/RarAES/RarAES.cpp
index 16a48349..00699158 100755
--- a/7zip/Crypto/RarAES/RarAES.cpp
+++ b/7zip/Crypto/RarAES/RarAES.cpp
@@ -17,7 +17,8 @@ namespace NRar29 {
CDecoder::CDecoder():
_thereIsSalt(false),
- _needCalculate(true)
+ _needCalculate(true),
+ _rar350Mode(false)
{
for (int i = 0; i < sizeof(_salt); i++)
_salt[i] = 0;
@@ -53,8 +54,12 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
return S_OK;
}
+static const int kMaxPasswordLength = 127 * 2;
+
STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size)
{
+ if (size > kMaxPasswordLength)
+ size = kMaxPasswordLength;
bool same = false;
if (size == buffer.GetCapacity())
{
@@ -104,10 +109,9 @@ void CDecoder::Calculate()
{
if (_needCalculate)
{
- const int MAXPASSWORD = 128;
- const int SALT_SIZE = 8;
+ const int kSaltSize = 8;
- Byte rawPassword[2 * MAXPASSWORD+ SALT_SIZE];
+ Byte rawPassword[kMaxPasswordLength + kSaltSize];
memcpy(rawPassword, buffer, buffer.GetCapacity());
@@ -115,24 +119,24 @@ void CDecoder::Calculate()
if (_thereIsSalt)
{
- memcpy(rawPassword + rawLength, _salt, SALT_SIZE);
- rawLength += SALT_SIZE;
+ memcpy(rawPassword + rawLength, _salt, kSaltSize);
+ rawLength += kSaltSize;
}
CSHA1 sha;
sha.Init();
-
+
// seems rar reverts hash for sha.
const int hashRounds = 0x40000;
int i;
for (i = 0; i < hashRounds; i++)
{
- sha.Update(rawPassword, rawLength);
+ sha.Update(rawPassword, rawLength, _rar350Mode);
Byte pswNum[3];
pswNum[0] = (Byte)i;
pswNum[1] = (Byte)(i >> 8);
pswNum[2] = (Byte)(i >> 16);
- sha.Update(pswNum, 3);
+ sha.Update(pswNum, 3, _rar350Mode);
if (i % (hashRounds / 16) == 0)
{
CSHA1 shaTemp = sha;
diff --git a/7zip/Crypto/RarAES/RarAES.h b/7zip/Crypto/RarAES/RarAES.h
index 91473269..d86d0d17 100755
--- a/7zip/Crypto/RarAES/RarAES.h
+++ b/7zip/Crypto/RarAES/RarAES.h
@@ -30,6 +30,8 @@ class CDecoder:
CCoderLibrary _aesLib;
CMyComPtr<ICompressFilter> _aesFilter;
+ bool _rar350Mode;
+
void Calculate();
HRESULT CreateFilter();
@@ -48,6 +50,7 @@ public:
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
CDecoder();
+ void SetRar350Mode(bool rar350Mode) { _rar350Mode = rar350Mode; }
};
}}
diff --git a/7zip/Crypto/RarAES/sha1.cpp b/7zip/Crypto/RarAES/sha1.cpp
index d1a28ed4..4e76de9f 100755
--- a/7zip/Crypto/RarAES/sha1.cpp
+++ b/7zip/Crypto/RarAES/sha1.cpp
@@ -6,7 +6,7 @@
#include "sha1.h"
-static inline rotlFixed(UInt32 x, int n)
+static inline UInt32 rotlFixed(UInt32 x, int n)
{
return (x << n) | (x >> (32 - n));
}
@@ -29,7 +29,7 @@ static inline rotlFixed(UInt32 x, int n)
/* Hash a single 512-bit block. This is the core of the algorithm. */
-void CSHA1::Transform(const UInt32 data[16])
+void CSHA1::Transform(UInt32 data[16], bool returnRes)
{
UInt32 a, b, c, d, e;
UInt32 W[16];
@@ -67,6 +67,9 @@ void CSHA1::Transform(const UInt32 data[16])
m_State[2] += c;
m_State[3] += d;
m_State[4] += e;
+ if (returnRes)
+ for (int i = 0 ; i < 16; i++)
+ data[i] = W[i];
/* Wipe variables */
a = b = c = d = e = 0;
@@ -84,10 +87,11 @@ void CSHA1::Init()
}
-void CSHA1::WriteByteBlock()
+void CSHA1::WriteByteBlock(bool returnRes)
{
UInt32 data32[16];
- for (int i = 0; i < 16; i++)
+ int i;
+ for (i = 0; i < 16; i++)
{
data32[i] =
(UInt32(_buffer[i * 4 + 0]) << 24) +
@@ -95,11 +99,21 @@ void CSHA1::WriteByteBlock()
(UInt32(_buffer[i * 4 + 2]) << 8) +
UInt32(_buffer[i * 4 + 3]);
}
- Transform(data32);
+ Transform(data32, returnRes);
+ if (returnRes)
+ for (i = 0; i < 16; i++)
+ {
+ UInt32 d = data32[i];
+ _buffer[i * 4 + 0] = (Byte)(d >> 0);
+ _buffer[i * 4 + 1] = (Byte)(d >> 8);
+ _buffer[i * 4 + 2] = (Byte)(d >> 16);
+ _buffer[i * 4 + 3] = (Byte)(d >> 24);
+ }
}
-void CSHA1::Update(const Byte *data, size_t size)
+void CSHA1::Update(Byte *data, size_t size, bool rar350Mode)
{
+ bool returnRes = false;
UInt32 curBufferPos = UInt32(m_Count) & 0x3F;
while (size > 0)
{
@@ -112,7 +126,11 @@ void CSHA1::Update(const Byte *data, size_t size)
if (curBufferPos == 64)
{
curBufferPos = 0;
- WriteByteBlock();
+ WriteByteBlock(returnRes);
+ if (returnRes)
+ for (int i = 0; i < 64; i++)
+ data[i - 64] = _buffer[i];
+ returnRes = rar350Mode;
}
}
}
@@ -129,7 +147,8 @@ void CSHA1::Final(Byte *digest)
WriteByteBlock();
_buffer[curBufferPos++] = 0;
}
- for (int i = 0; i < 8; i++)
+ int i;
+ for (i = 0; i < 8; i++)
{
_buffer[curBufferPos++] = Byte(lenInBits >> 56);
lenInBits <<= 8;
diff --git a/7zip/Crypto/RarAES/sha1.h b/7zip/Crypto/RarAES/sha1.h
index 295f4131..a7cf9a16 100755
--- a/7zip/Crypto/RarAES/sha1.h
+++ b/7zip/Crypto/RarAES/sha1.h
@@ -10,17 +10,22 @@
#define HW 5
+// Sha1 implementation in RAR before version 3.60 has bug:
+// it changes data bytes in some cases.
+// So this class supports both versions: normal_SHA and rar3Mode
+
struct CSHA1
{
UInt32 m_State[5];
UInt64 m_Count;
unsigned char _buffer[64];
- void Transform(const UInt32 data[16]);
- void WriteByteBlock();
+ void Transform(UInt32 data[16], bool returnRes = false);
+ void WriteByteBlock(bool returnRes = false);
+public:
void Init();
- void Update(const Byte *data, size_t size);
+ void Update(Byte *data, size_t size, bool rar350Mode = false);
void Final(Byte *digest);
};
diff --git a/7zip/Crypto/Zip/ZipCipher.cpp b/7zip/Crypto/Zip/ZipCipher.cpp
index 9098f6c9..47e2e712 100755
--- a/7zip/Crypto/Zip/ZipCipher.cpp
+++ b/7zip/Crypto/Zip/ZipCipher.cpp
@@ -5,6 +5,8 @@
#include "ZipCipher.h"
#include "Windows/Defs.h"
+#include "../../Common/StreamUtils.h"
+
namespace NCrypto {
namespace NZip {
@@ -56,7 +58,7 @@ HRESULT CEncoder::WriteHeader(ISequentialOutStream *outStream)
UInt32 processedSize;
_cipher.EncryptHeader(header);
- RINOK(outStream->Write(header, kHeaderSize, &processedSize));
+ RINOK(WriteStream(outStream, header, kHeaderSize, &processedSize));
if (processedSize != kHeaderSize)
return E_FAIL;
return S_OK;
@@ -81,7 +83,7 @@ HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream)
UInt64 nowPos = 0;
Byte header[kHeaderSize];
UInt32 processedSize;
- RINOK(inStream->Read(header, kHeaderSize, &processedSize));
+ RINOK(ReadStream(inStream, header, kHeaderSize, &processedSize));
if (processedSize != kHeaderSize)
return E_FAIL;
_cipher.DecryptHeader(header);
diff --git a/7zip/FileManager/App.cpp b/7zip/FileManager/App.cpp
index ed78bb70..c85d4cef 100755
--- a/7zip/FileManager/App.cpp
+++ b/7zip/FileManager/App.cpp
@@ -340,7 +340,8 @@ void CApp::Create(HWND hwnd, const UString &mainPath, int xSizes[2])
ReadToolbar();
ReloadRebar(hwnd);
- for (int i = 0; i < kNumPanelsMax; i++)
+ int i;
+ for (i = 0; i < kNumPanelsMax; i++)
PanelsCreated[i] = false;
_window.Attach(hwnd);
diff --git a/7zip/FileManager/App.h b/7zip/FileManager/App.h
index 229c4806..45436ccb 100755
--- a/7zip/FileManager/App.h
+++ b/7zip/FileManager/App.h
@@ -200,8 +200,8 @@ public:
{ OnCopy(false, false, GetFocusedPanelIndex()); }
void MoveTo()
{ OnCopy(true, false, GetFocusedPanelIndex()); }
- void Delete()
- { GetFocusedPanel().DeleteItems(); }
+ void Delete(bool toRecycleBin)
+ { GetFocusedPanel().DeleteItems(toRecycleBin); }
void Split();
void Combine();
void Properties()
diff --git a/7zip/FileManager/FSFolder.cpp b/7zip/FileManager/FSFolder.cpp
index a6cf5701..e75a73a8 100755
--- a/7zip/FileManager/FSFolder.cpp
+++ b/7zip/FileManager/FSFolder.cpp
@@ -508,6 +508,40 @@ STDMETHODIMP CFSFolder::Delete(const UINT32 *indices, UINT32 numItems,
return S_OK;
}
+/*
+STDMETHODIMP CFSFolder::DeleteToRecycleBin(const UINT32 *indices, UINT32 numItems,
+ IProgress *progress)
+{
+ RINOK(progress->SetTotal(numItems));
+ for (UINT32 i = 0; i < numItems; i++)
+ {
+ int index = indices[i];
+ const CFileInfoW &fileInfo = _files[indices[i]];
+ const UString fullPath = _path + fileInfo.Name;
+ CBuffer<TCHAR> buffer;
+ const CSysString fullPathSys = GetSystemString(fullPath);
+ buffer.SetCapacity(fullPathSys.Length() + 2);
+ memmove((TCHAR *)buffer, (const TCHAR *)fullPathSys, (fullPathSys.Length() + 1) * sizeof(TCHAR));
+ ((TCHAR *)buffer)[fullPathSys.Length() + 1] = 0;
+ SHFILEOPSTRUCT fo;
+ fo.hwnd = 0;
+ fo.wFunc = FO_DELETE;
+ fo.pFrom = (const TCHAR *)buffer;
+ fo.pTo = 0;
+ fo.fFlags = FOF_ALLOWUNDO;
+ fo.fAnyOperationsAborted = FALSE;
+ fo.hNameMappings = 0;
+ fo.lpszProgressTitle = 0;
+ int res = SHFileOperation(&fo);
+ if (fo.fAnyOperationsAborted)
+ return E_ABORT;
+ UINT64 completed = i;
+ RINOK(progress->SetCompleted(&completed));
+ }
+ return S_OK;
+}
+*/
+
STDMETHODIMP CFSFolder::SetProperty(UINT32 index, PROPID propID,
const PROPVARIANT *value, IProgress *progress)
{
diff --git a/7zip/FileManager/FSFolder.h b/7zip/FileManager/FSFolder.h
index 08a987dc..3de312b1 100755
--- a/7zip/FileManager/FSFolder.h
+++ b/7zip/FileManager/FSFolder.h
@@ -28,6 +28,7 @@ class CFSFolder:
public IFolderGetPath,
public IFolderWasChanged,
public IFolderOperations,
+ // public IFolderOperationsDeleteToRecycleBin,
public IFolderGetItemFullSize,
public IFolderClone,
public IFolderGetSystemIconIndex,
@@ -40,6 +41,7 @@ public:
MY_QUERYINTERFACE_ENTRY(IFolderGetTypeID)
MY_QUERYINTERFACE_ENTRY(IFolderGetPath)
MY_QUERYINTERFACE_ENTRY(IFolderWasChanged)
+ // MY_QUERYINTERFACE_ENTRY(IFolderOperationsDeleteToRecycleBin)
MY_QUERYINTERFACE_ENTRY(IFolderOperations)
MY_QUERYINTERFACE_ENTRY(IFolderGetItemFullSize)
MY_QUERYINTERFACE_ENTRY(IFolderClone)
@@ -80,6 +82,8 @@ public:
STDMETHOD(SetProperty)(UINT32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress);
STDMETHOD(GetSystemIconIndex)(UINT32 index, INT32 *iconIndex);
+ // STDMETHOD(DeleteToRecycleBin)(const UINT32 *indices, UINT32 numItems, IProgress *progress);
+
private:
UINT _fileCodePage;
UString _path;
diff --git a/7zip/FileManager/IFolder.h b/7zip/FileManager/IFolder.h
index 10734f7b..8ab4d196 100755
--- a/7zip/FileManager/IFolder.h
+++ b/7zip/FileManager/IFolder.h
@@ -5,6 +5,15 @@
#include "../IProgress.h"
+#define FOLDER_INTERFACE_SUB(i, b, x, y) \
+DEFINE_GUID(IID_ ## i, \
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, x, y, 0x00); \
+struct i: public b
+
+#define FOLDER_INTERFACE2(i, x, y) FOLDER_INTERFACE_SUB(i, IUnknown, x, y)
+
+#define FOLDER_INTERFACE(i, x) FOLDER_INTERFACE2(i, x, 0x00)
+
namespace NPlugin
{
enum
@@ -16,85 +25,50 @@ namespace NPlugin
};
}
-// {23170F69-40C1-278A-0000-000800000000}
-DEFINE_GUID(IID_IFolderFolder,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000800000000")
-IFolderFolder: public IUnknown
-{
-public:
- STDMETHOD(LoadItems)() = 0;
- STDMETHOD(GetNumberOfItems)(UINT32 *numItems) = 0;
- // STDMETHOD(GetNumberOfSubFolders)(UINT32 *numSubFolders) = 0;
- STDMETHOD(GetProperty)(UINT32 itemIndex, PROPID propID, PROPVARIANT *value) = 0;
- STDMETHOD(BindToFolder)(UINT32 index, IFolderFolder **resultFolder) = 0;
- STDMETHOD(BindToFolder)(const wchar_t *name, IFolderFolder **resultFolder) = 0;
- STDMETHOD(BindToParentFolder)(IFolderFolder **resultFolder) = 0;
- STDMETHOD(GetName)(BSTR *name) = 0;
-};
-
-// {23170F69-40C1-278A-0000-000800010000}
-DEFINE_GUID(IID_IEnumProperties,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000800010000")
-IEnumProperties: public IUnknown
-{
-public:
- // STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator) = 0;
- STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties) = 0;
+FOLDER_INTERFACE(IFolderFolder, 0x00)
+{
+ STDMETHOD(LoadItems)() PURE;
+ STDMETHOD(GetNumberOfItems)(UINT32 *numItems) PURE;
+ // STDMETHOD(GetNumberOfSubFolders)(UINT32 *numSubFolders) PURE;
+ STDMETHOD(GetProperty)(UINT32 itemIndex, PROPID propID, PROPVARIANT *value) PURE;
+ STDMETHOD(BindToFolder)(UINT32 index, IFolderFolder **resultFolder) PURE;
+ STDMETHOD(BindToFolder)(const wchar_t *name, IFolderFolder **resultFolder) PURE;
+ STDMETHOD(BindToParentFolder)(IFolderFolder **resultFolder) PURE;
+ STDMETHOD(GetName)(BSTR *name) PURE;
+};
+
+FOLDER_INTERFACE(IEnumProperties, 0x01)
+{
+ // STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator) PURE;
+ STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties) PURE;
STDMETHOD(GetPropertyInfo)(UINT32 index,
- BSTR *name, PROPID *propID, VARTYPE *varType) = 0;
+ BSTR *name, PROPID *propID, VARTYPE *varType) PURE;
};
-// {23170F69-40C1-278A-0000-000800020000}
-DEFINE_GUID(IID_IFolderGetTypeID,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000800020000")
-IFolderGetTypeID: public IUnknown
+FOLDER_INTERFACE(IFolderGetTypeID, 0x02)
{
-public:
- STDMETHOD(GetTypeID)(BSTR *name) = 0;
+ STDMETHOD(GetTypeID)(BSTR *name) PURE;
};
-// {23170F69-40C1-278A-0000-000800030000}
-DEFINE_GUID(IID_IFolderGetPath,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000800030000")
-IFolderGetPath: public IUnknown
+FOLDER_INTERFACE(IFolderGetPath, 0x03)
{
-public:
- STDMETHOD(GetPath)(BSTR *path) = 0;
+ STDMETHOD(GetPath)(BSTR *path) PURE;
};
-// {23170F69-40C1-278A-0000-000800040000}
-DEFINE_GUID(IID_IFolderWasChanged,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000800040000")
-IFolderWasChanged: public IUnknown
+FOLDER_INTERFACE(IFolderWasChanged, 0x04)
{
-public:
- STDMETHOD(WasChanged)(INT32 *wasChanged) = 0;
+ STDMETHOD(WasChanged)(INT32 *wasChanged) PURE;
};
/*
-// {23170F69-40C1-278A-0000-000800050000}
-DEFINE_GUID(IID_IFolderReload,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000800050000")
-IFolderReload: public IUnknown
+FOLDER_INTERFACE(IFolderReload, 0x05)
{
-public:
- STDMETHOD(Reload)() = 0;
+ STDMETHOD(Reload)() PURE;
};
*/
-// {23170F69-40C1-278A-0000-000800060100}
-DEFINE_GUID(IID_IFolderOperationsExtractCallback,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x06, 0x01, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000800060100")
-IFolderOperationsExtractCallback: public IProgress
+FOLDER_INTERFACE_SUB(IFolderOperationsExtractCallback, IProgress, 0x06, 0x01)
{
-public:
STDMETHOD(AskWrite)(
const wchar_t *srcPath,
INT32 srcIsFolder,
@@ -102,19 +76,14 @@ public:
const UINT64 *srcSize,
const wchar_t *destPathRequest,
BSTR *destPathResult,
- INT32 *writeAnswer) = 0;
- STDMETHOD(ShowMessage)(const wchar_t *message) = 0;
- STDMETHOD(SetCurrentFilePath)(const wchar_t *filePath) = 0;
+ INT32 *writeAnswer) PURE;
+ STDMETHOD(ShowMessage)(const wchar_t *message) PURE;
+ STDMETHOD(SetCurrentFilePath)(const wchar_t *filePath) PURE;
};
/*
-// {23170F69-40C1-278A-0000-000800060200}
-DEFINE_GUID(IID_IFolderOperationsUpdateCallback,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x06, 0x02, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000800060200")
-IFolderOperationsUpdateCallback: public IProgress
+FOLDER_INTERFACE_SUB(IFolderOperationsUpdateCallback, IProgress, 0x06, 0x02)
{
-public:
STDMETHOD(AskOverwrite)(
const wchar_t *srcPath,
INT32 destIsFolder,
@@ -127,124 +96,88 @@ public:
};
*/
-// {23170F69-40C1-278A-0000-000800060000}
-DEFINE_GUID(IID_IFolderOperations,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000800060000")
-IFolderOperations: public IUnknown
-{
-public:
- STDMETHOD(CreateFolder)(const wchar_t *name, IProgress *progress) = 0;
- STDMETHOD(CreateFile)(const wchar_t *name, IProgress *progress) = 0;
- STDMETHOD(Rename)(UINT32 index, const wchar_t *newName, IProgress *progress) = 0;
- STDMETHOD(Delete)(const UINT32 *indices, UINT32 numItems, IProgress *progress) = 0;
+FOLDER_INTERFACE(IFolderOperations, 0x06)
+{
+ STDMETHOD(CreateFolder)(const wchar_t *name, IProgress *progress) PURE;
+ STDMETHOD(CreateFile)(const wchar_t *name, IProgress *progress) PURE;
+ STDMETHOD(Rename)(UINT32 index, const wchar_t *newName, IProgress *progress) PURE;
+ STDMETHOD(Delete)(const UINT32 *indices, UINT32 numItems, IProgress *progress) PURE;
STDMETHOD(CopyTo)(const UINT32 *indices, UINT32 numItems,
- const wchar_t *path, IFolderOperationsExtractCallback *callback) = 0;
+ const wchar_t *path, IFolderOperationsExtractCallback *callback) PURE;
STDMETHOD(MoveTo)(const UINT32 *indices, UINT32 numItems,
- const wchar_t *path, IFolderOperationsExtractCallback *callback) = 0;
+ const wchar_t *path, IFolderOperationsExtractCallback *callback) PURE;
STDMETHOD(CopyFrom)(const wchar_t *fromFolderPath,
- const wchar_t **itemsPaths, UINT32 numItems, IProgress *progress) = 0;
- STDMETHOD(SetProperty)(UINT32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress) = 0;
+ const wchar_t **itemsPaths, UINT32 numItems, IProgress *progress) PURE;
+ STDMETHOD(SetProperty)(UINT32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress) PURE;
};
-// {23170F69-40C1-278A-0000-000800070000}
-DEFINE_GUID(IID_IFolderGetSystemIconIndex,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x07, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000800070000")
-IFolderGetSystemIconIndex: public IUnknown
+/*
+FOLDER_INTERFACE2(IFolderOperationsDeleteToRecycleBin, 0x06, 0x03)
{
-public:
- STDMETHOD(GetSystemIconIndex)(UINT32 index, INT32 *iconIndex) = 0;
+ STDMETHOD(DeleteToRecycleBin)(const UINT32 *indices, UINT32 numItems, IProgress *progress) PURE;
};
+*/
-// {23170F69-40C1-278A-0000-000800080000}
-DEFINE_GUID(IID_IFolderGetItemFullSize,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000800080000")
-IFolderGetItemFullSize: public IUnknown
+FOLDER_INTERFACE(IFolderGetSystemIconIndex, 0x07)
{
-public:
- STDMETHOD(GetItemFullSize)(UINT32 index, PROPVARIANT *value, IProgress *progress) = 0;
+ STDMETHOD(GetSystemIconIndex)(UINT32 index, INT32 *iconIndex) PURE;
};
-// {23170F69-40C1-278A-0000-000800090000}
-DEFINE_GUID(IID_IFolderClone,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x09, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000800090000")
-IFolderClone: public IUnknown
+FOLDER_INTERFACE(IFolderGetItemFullSize, 0x08)
{
-public:
- STDMETHOD(Clone)(IFolderFolder **resultFolder) = 0;
+ STDMETHOD(GetItemFullSize)(UINT32 index, PROPVARIANT *value, IProgress *progress) PURE;
+};
+
+FOLDER_INTERFACE(IFolderClone, 0x09)
+{
+ STDMETHOD(Clone)(IFolderFolder **resultFolder) PURE;
};
/*
-// {23170F69-40C1-278A-0000-0008000A0000}
-DEFINE_GUID(IID_IFolderOpen,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0A, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-0008000A0000")
-IFolderOpen: public IUnknown
+FOLDER_INTERFACE(IFolderOpen, 0x0A)
{
STDMETHOD(FolderOpen)(
const wchar_t *aFileName,
// IArchiveHandler100 **anArchiveHandler,
// NZipRootRegistry::CArchiverInfo &anArchiverInfoResult,
// UString &aDefaultName,
- IOpenArchive2CallBack *anOpenArchive2CallBack) = 0;
+ IOpenArchive2CallBack *anOpenArchive2CallBack) PURE;
};
*/
-// {23170F69-40C1-278A-0000-000900000000}
-DEFINE_GUID(IID_IFolderManager,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000900000000")
-IFolderManager: public IUnknown
+#define FOLDER_MANAGER_INTERFACE(i, x) \
+DEFINE_GUID(IID_ ## i, \
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x09, 0x00, x, 0x00, 0x00); \
+struct i: public IUnknown
+
+FOLDER_MANAGER_INTERFACE(IFolderManager, 0x00)
{
- STDMETHOD(OpenFolderFile)(const wchar_t *filePath, IFolderFolder **resultFolder, IProgress *progress) = 0;
- STDMETHOD(GetTypes)(BSTR *types);
- STDMETHOD(GetExtension)(const wchar_t *type, BSTR *extension);
- STDMETHOD(CreateFolderFile)(const wchar_t *type, const wchar_t *filePath, IProgress *progress) = 0;
+ STDMETHOD(OpenFolderFile)(const wchar_t *filePath, IFolderFolder **resultFolder, IProgress *progress) PURE;
+ STDMETHOD(GetTypes)(BSTR *types) PURE;
+ STDMETHOD(GetExtension)(const wchar_t *type, BSTR *extension) PURE;
+ STDMETHOD(CreateFolderFile)(const wchar_t *type, const wchar_t *filePath, IProgress *progress) PURE;
};
-// {23170F69-40C1-278A-0000-000900010000}
-DEFINE_GUID(IID_IFolderManagerGetIconPath,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000900010000")
-IFolderManagerGetIconPath: public IUnknown
+FOLDER_MANAGER_INTERFACE(IFolderManagerGetIconPath, 0x01)
{
- STDMETHOD(GetIconPath)(const wchar_t *type, BSTR *iconPath) = 0;
+ STDMETHOD(GetIconPath)(const wchar_t *type, BSTR *iconPath) PURE;
};
/*
-// {23170F69-40C1-278A-0000-000800050A00}
-DEFINE_GUID(IID_IFolderExtract,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x0A, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000800050A00")
-IFolderExtract: public IUnknown
+FOLDER_INTERFACE(IFolderExtract, 0x05, 0x0A);
{
-public:
- STDMETHOD(Clone)(IFolderFolder **aFolder) = 0;
+ STDMETHOD(Clone)(IFolderFolder **aFolder) PURE;
};
-*/
-/*
-// {23170F69-40C1-278A-0000-000800050400}
-DEFINE_GUID(IID_IFolderChangeNotify,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x04, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000800050400")
+FOLDER_INTERFACE(IFolderChangeNotify,0x05, 0x04, 0x00);
IFolderChangeNotify: public IUnknown
{
-public:
- STDMETHOD(OnChanged)() = 0;
+ STDMETHOD(OnChanged)() PURE;
};
-// {23170F69-40C1-278A-0000-000800050500}
-DEFINE_GUID(IID_IFolderSetChangeNotify,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x05, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000800050500")
-IFolderSetChangeNotify: public IUnknown
+FOLDER_INTERFACE(IFolderSetChangeNotify, 0x05, 0x05);
{
-public:
- STDMETHOD(SetChangeNotify)(IFolderChangeNotify *aChangeNotify) = 0;
+ STDMETHOD(SetChangeNotify)(IFolderChangeNotify *aChangeNotify) PURE;
};
*/
diff --git a/7zip/FileManager/MyLoadMenu.cpp b/7zip/FileManager/MyLoadMenu.cpp
index 51b8fa56..9b684ec4 100755
--- a/7zip/FileManager/MyLoadMenu.cpp
+++ b/7zip/FileManager/MyLoadMenu.cpp
@@ -600,8 +600,11 @@ bool ExecuteFileCommand(int id)
g_App.MoveTo();
break;
case IDM_DELETE:
- g_App.Delete();
+ {
+ bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0;
+ g_App.Delete(!shift);
break;
+ }
case IDM_FILE_SPLIT:
g_App.Split();
break;
diff --git a/7zip/FileManager/OptionsDialog.cpp b/7zip/FileManager/OptionsDialog.cpp
index fc94a153..350d5263 100755
--- a/7zip/FileManager/OptionsDialog.cpp
+++ b/7zip/FileManager/OptionsDialog.cpp
@@ -94,7 +94,10 @@ void OptionsDialog(HWND hwndOwner, HINSTANCE hInstance)
if (::PropertySheet(&sheet) != -1)
{
if (langPage._langWasChanged)
+ {
+ g_App._window.SetText(LangLoadStringW(IDS_APP_TITLE, 0x03000000));
MyLoadMenu();
+ }
g_App.SetListSettings();
g_App.SetShowSystemMenu();
g_App.RefreshAllPanels();
diff --git a/7zip/FileManager/Panel.cpp b/7zip/FileManager/Panel.cpp
index 8a06ac29..43905e0b 100755
--- a/7zip/FileManager/Panel.cpp
+++ b/7zip/FileManager/Panel.cpp
@@ -736,7 +736,7 @@ void CPanel::AddToArchive()
names.Front(), (names.Size() > 1), false);
CompressFiles(_currentFolderPrefix, archiveName,
names, false, true, false);
- KillSelection();
+ // KillSelection();
}
void CPanel::ExtractArchives()
diff --git a/7zip/FileManager/Panel.h b/7zip/FileManager/Panel.h
index fc0a9c68..95ab0d3c 100755
--- a/7zip/FileManager/Panel.h
+++ b/7zip/FileManager/Panel.h
@@ -136,8 +136,9 @@ struct CSelectedState
{
int FocusedItem;
UString FocusedName;
+ bool SelectFocused;
UStringVector SelectedNames;
- CSelectedState(): FocusedItem(-1) {}
+ CSelectedState(): FocusedItem(-1), SelectFocused(false) {}
};
class CPanel:public NWindows::NControl::CWindow2
@@ -173,7 +174,7 @@ class CPanel:public NWindows::NControl::CWindow2
public:
CPanelCallback *_panelCallback;
- void DeleteItems();
+ void DeleteItems(bool toRecycleBin);
void CreateFolder();
void CreateFile();
@@ -185,8 +186,8 @@ private:
// void InitColumns2(PROPID sortID);
void InsertColumn(int index);
- void SetFocusedSelectedItem(int index);
- void RefreshListCtrl(const UString &focusedName, int focusedPos,
+ void SetFocusedSelectedItem(int index, bool select);
+ void RefreshListCtrl(const UString &focusedName, int focusedPos, bool selectFocused,
const UStringVector &selectedNames);
void OnShiftSelectMessage();
@@ -224,6 +225,7 @@ public:
bool _showRealFileIcons;
// bool _virtualMode;
// CUIntVector _realIndices;
+ bool _enableItemChangeNotify;
bool _mySelectMode;
CBoolVector _selectedStatusVector;
@@ -312,7 +314,8 @@ public:
_selectionIsDefined(false),
_ListViewMode(3),
_xSize(300),
- _mySelectMode(false)
+ _mySelectMode(false),
+ _enableItemChangeNotify(true)
{}
void SetExtendedStyle()
diff --git a/7zip/FileManager/PanelFolderChange.cpp b/7zip/FileManager/PanelFolderChange.cpp
index c38989f7..e632c5f7 100755
--- a/7zip/FileManager/PanelFolderChange.cpp
+++ b/7zip/FileManager/PanelFolderChange.cpp
@@ -95,7 +95,7 @@ HRESULT CPanel::BindToPathAndRefresh(const UString &path)
{
CDisableTimerProcessing disableTimerProcessing1(*this);
RINOK(BindToPath(path));
- RefreshListCtrl(UString(), -1, UStringVector());
+ RefreshListCtrl(UString(), -1, true, UStringVector());
return S_OK;
}
@@ -112,7 +112,7 @@ void CPanel::OpenBookmark(int index)
UString GetFolderPath(IFolderFolder * folder)
{
CMyComPtr<IFolderGetPath> folderGetPath;
- if (folder->QueryInterface(&folderGetPath) == S_OK)
+ if (folder->QueryInterface(IID_IFolderGetPath, (void **)&folderGetPath) == S_OK)
{
CMyComBSTR path;
if (folderGetPath->GetPath(&path) == S_OK)
@@ -310,7 +310,7 @@ void CPanel::OpenParentFolder()
*/
LoadFullPath();
::SetCurrentDirectory(::GetSystemString(_currentFolderPrefix));
- RefreshListCtrl(focucedName, -1, selectedItems);
+ RefreshListCtrl(focucedName, -1, true, selectedItems);
_listView.EnsureVisible(_listView.GetFocusedItem(), false);
RefreshStatusBar();
}
@@ -336,7 +336,7 @@ void CPanel::OpenRootFolder()
CDisableTimerProcessing disableTimerProcessing1(*this);
_parentFolders.Clear();
SetToRootFolder();
- RefreshListCtrl(UString(), 0, UStringVector());
+ RefreshListCtrl(UString(), -1, true, UStringVector());
// ::SetCurrentDirectory(::GetSystemString(_currentFolderPrefix));
/*
BeforeChangeFolder();
diff --git a/7zip/FileManager/PanelItems.cpp b/7zip/FileManager/PanelItems.cpp
index d400015b..b839cc8f 100755
--- a/7zip/FileManager/PanelItems.cpp
+++ b/7zip/FileManager/PanelItems.cpp
@@ -12,10 +12,12 @@
#include "../PropID.h"
#include "Panel.h"
+#include "resource.h"
#include "RootFolder.h"
#include "PropertyName.h"
+#include "LangUtils.h"
using namespace NWindows;
@@ -201,7 +203,7 @@ void CPanel::InsertColumn(int index)
void CPanel::RefreshListCtrl()
{
- RefreshListCtrl(UString(), 0, UStringVector());
+ RefreshListCtrl(UString(), -1, true, UStringVector());
}
int CALLBACK CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData);
@@ -245,35 +247,42 @@ 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 = GetItemName(realIndex);
- /*
- const int kSize = 1024;
- TCHAR name[kSize + 1];
- LVITEM item;
- item.iItem = focusedItem;
- item.pszText = name;
- item.cchTextMax = kSize;
- item.iSubItem = 0;
- item.mask = LVIF_TEXT;
- if (_listView.GetItem(&item))
- focusedName = GetUnicodeString(item.pszText);
- */
- }
if (!_focusedName.IsEmpty())
{
s.FocusedName = _focusedName;
+ s.SelectFocused = true;
_focusedName.Empty();
}
+ else
+ {
+ if (s.FocusedItem >= 0)
+ {
+ int realIndex = GetRealItemIndex(s.FocusedItem);
+ if (realIndex != kParentIndex)
+ s.FocusedName = GetItemName(realIndex);
+ /*
+ const int kSize = 1024;
+ TCHAR name[kSize + 1];
+ LVITEM item;
+ item.iItem = focusedItem;
+ item.pszText = name;
+ item.cchTextMax = kSize;
+ item.iSubItem = 0;
+ item.mask = LVIF_TEXT;
+ if (_listView.GetItem(&item))
+ focusedName = GetUnicodeString(item.pszText);
+ */
+ }
+ }
GetSelectedNames(s.SelectedNames);
}
void CPanel::RefreshListCtrl(const CSelectedState &s)
{
- RefreshListCtrl(s.FocusedName, s.FocusedItem, s.SelectedNames);
+ bool selectFocused = s.SelectFocused;
+ if (_mySelectMode)
+ selectFocused = true;
+ RefreshListCtrl(s.FocusedName, s.FocusedItem, selectFocused, s.SelectedNames);
}
void CPanel::RefreshListCtrlSaveFocused()
@@ -283,11 +292,13 @@ void CPanel::RefreshListCtrlSaveFocused()
RefreshListCtrl(state);
}
-void CPanel::SetFocusedSelectedItem(int index)
+void CPanel::SetFocusedSelectedItem(int index, bool select)
{
- UINT state = LVIS_FOCUSED | LVIS_SELECTED;
+ UINT state = LVIS_FOCUSED;
+ if (select)
+ state |= LVIS_SELECTED;
_listView.SetItemState(index, state, state);
- if (!_mySelectMode)
+ if (!_mySelectMode && select)
{
int realIndex = GetRealItemIndex(index);
if (realIndex != kParentIndex)
@@ -295,7 +306,7 @@ void CPanel::SetFocusedSelectedItem(int index)
}
}
-void CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos,
+void CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool selectFocused,
const UStringVector &selectedNames)
{
LoadFullPathAndShow();
@@ -468,13 +479,13 @@ void CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos,
// OutputDebugStringA("End2\n");
if(_listView.GetItemCount() > 0 && cursorIndex >= 0)
- SetFocusedSelectedItem(cursorIndex);
+ SetFocusedSelectedItem(cursorIndex, selectFocused);
_listView.SortItems(CompareItems, (LPARAM)this);
if (cursorIndex < 0 && _listView.GetItemCount() > 0)
{
if (focusedPos >= _listView.GetItemCount())
focusedPos = _listView.GetItemCount() - 1;
- SetFocusedSelectedItem(focusedPos);
+ SetFocusedSelectedItem(focusedPos, true);
}
// m_RedrawEnabled = true;
_listView.EnsureVisible(_listView.GetFocusedItem(), false);
@@ -514,9 +525,12 @@ void CPanel::GetOperatedItemIndices(CRecordVector<UINT32> &indices) const
int focusedItem = _listView.GetFocusedItem();
if (focusedItem >= 0)
{
- int realIndex = GetRealItemIndex(focusedItem);
- if (realIndex != kParentIndex)
+ if(_listView.GetItemState(focusedItem, LVIS_SELECTED) == LVIS_SELECTED)
+ {
+ int realIndex = GetRealItemIndex(focusedItem);
+ if (realIndex != kParentIndex)
indices.Add(realIndex);
+ }
}
}
@@ -571,7 +585,7 @@ void CPanel::OpenSelectedItems(bool tryInternal)
GetOperatedItemIndices(indices);
if (indices.Size() > 20)
{
- MessageBox(L"Too much items");
+ MessageBox(LangLoadStringW(IDS_TOO_MANY_ITEMS, 0x02000606));
return;
}
@@ -659,7 +673,8 @@ void CPanel::ReadListViewInfo()
void CPanel::SaveListViewInfo()
{
- for(int i = 0; i < _visibleProperties.Size(); i++)
+ int i;
+ for(i = 0; i < _visibleProperties.Size(); i++)
{
CItemProperty &property = _visibleProperties[i];
LVCOLUMN winColumnInfo;
diff --git a/7zip/FileManager/PanelKey.cpp b/7zip/FileManager/PanelKey.cpp
index d14c024a..f623332a 100755
--- a/7zip/FileManager/PanelKey.cpp
+++ b/7zip/FileManager/PanelKey.cpp
@@ -152,8 +152,7 @@ bool CPanel::OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result)
*/
case VK_DELETE:
{
- // if (shift)
- DeleteItems();
+ DeleteItems(!shift);
return true;
}
case VK_INSERT:
diff --git a/7zip/FileManager/PanelListNotify.cpp b/7zip/FileManager/PanelListNotify.cpp
index ec88abc5..ac8c069d 100755
--- a/7zip/FileManager/PanelListNotify.cpp
+++ b/7zip/FileManager/PanelListNotify.cpp
@@ -169,9 +169,12 @@ bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result)
{
case LVN_ITEMCHANGED:
{
- if (!_mySelectMode)
- OnItemChanged((LPNMLISTVIEW)header);
- RefreshStatusBar();
+ if (_enableItemChangeNotify)
+ {
+ if (!_mySelectMode)
+ OnItemChanged((LPNMLISTVIEW)header);
+ RefreshStatusBar();
+ }
return false;
}
/*
@@ -257,6 +260,8 @@ bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result)
*/
case NM_CLICK:
{
+ // we need SetFocusToList, if we drag-select items from other panel.
+ SetFocusToList();
RefreshStatusBar();
if(_mySelectMode)
if(g_ComCtl32Version >= MAKELONG(71, 4))
diff --git a/7zip/FileManager/PanelMenu.cpp b/7zip/FileManager/PanelMenu.cpp
index 091f0317..f10fa1aa 100755
--- a/7zip/FileManager/PanelMenu.cpp
+++ b/7zip/FileManager/PanelMenu.cpp
@@ -261,7 +261,8 @@ void CPanel::CreateSevenZipMenu(HMENU menuSpec,
return;
UString currentFolderUnicode = _currentFolderPrefix;
UStringVector names;
- for(int i = 0; i < operatedIndices.Size(); i++)
+ int i;
+ for(i = 0; i < operatedIndices.Size(); i++)
names.Add(currentFolderUnicode + GetItemName(operatedIndices[i]));
CRecordVector<const wchar_t *> namePointers;
for(i = 0; i < operatedIndices.Size(); i++)
diff --git a/7zip/FileManager/PanelOperations.cpp b/7zip/FileManager/PanelOperations.cpp
index 5e23cbcb..5efbc2d7 100755
--- a/7zip/FileManager/PanelOperations.cpp
+++ b/7zip/FileManager/PanelOperations.cpp
@@ -7,6 +7,7 @@
#include "Panel.h"
#include "Common/StringConvert.h"
+#include "Common/DynamicBuffer.h"
#include "Windows/FileDir.h"
#include "Windows/ResourceString.h"
#include "Windows/Thread.h"
@@ -35,8 +36,7 @@ struct CThreadDelete
{
NCOM::CComInitializer comInitializer;
UpdateCallbackSpec->ProgressDialog.WaitCreating();
- Result = FolderOperations->Delete(&Indices.Front(),
- Indices.Size(), UpdateCallback);
+ Result = FolderOperations->Delete(&Indices.Front(), Indices.Size(), UpdateCallback);
UpdateCallbackSpec->ProgressDialog.MyClose();
return 0;
}
@@ -47,15 +47,8 @@ struct CThreadDelete
}
};
-void CPanel::DeleteItems()
+void CPanel::DeleteItems(bool toRecycleBin)
{
- CMyComPtr<IFolderOperations> folderOperations;
- if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
- {
- MessageBox(LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
- return;
- }
-
CPanel::CDisableTimerProcessing disableTimerProcessing2(*this);
CRecordVector<UInt32> indices;
GetOperatedItemIndices(indices);
@@ -63,6 +56,55 @@ void CPanel::DeleteItems()
return;
CSelectedState state;
SaveSelectedState(state);
+ if (IsFSFolder())
+ {
+ CDynamicBuffer<TCHAR> buffer;
+ size_t size = 0;
+ for (int i = 0; i < indices.Size(); i++)
+ {
+ const CSysString path = GetSystemString(GetFsPath() + GetItemName(indices[i]));
+ buffer.EnsureCapacity(size + path.Length() + 1);
+ memmove(((TCHAR *)buffer) + size, (const TCHAR *)path, (path.Length() + 1) * sizeof(TCHAR));
+ size += path.Length() + 1;
+ }
+ buffer.EnsureCapacity(size + 1);
+ ((TCHAR *)buffer)[size] = 0;
+ SHFILEOPSTRUCT fo;
+ fo.hwnd = GetParent();
+ fo.wFunc = FO_DELETE;
+ fo.pFrom = (const TCHAR *)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 = SHFileOperation(&fo);
+ /*
+ if (fo.fAnyOperationsAborted)
+ {
+ MessageBoxError(result, LangLoadStringW(IDS_ERROR_DELETING, 0x03020217));
+ }
+ */
+ /*
+ (!result)
+ return GetLastError();
+ */
+ }
+ else
+ {
+
+ CMyComPtr<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ {
+ MessageBox(LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
+ return;
+ }
UString title;
UString message;
@@ -112,6 +154,7 @@ void CPanel::DeleteItems()
HRESULT result = deleter.Result;
if (result != S_OK)
MessageBoxError(result, LangLoadStringW(IDS_ERROR_DELETING, 0x03020217));
+ }
RefreshListCtrl(state);
}
@@ -152,6 +195,11 @@ BOOL CPanel::OnEndLabelEdit(LV_DISPINFO * lpnmh)
// Can't use RefreshListCtrl here.
// RefreshListCtrlSaveFocused();
_focusedName = newName;
+
+ // We need clear all items to disable GetText before Reload:
+ // number of items can change.
+ _listView.DeleteAllItems();
+
PostMessage(kReLoadMessage);
return TRUE;
}
@@ -186,6 +234,7 @@ void CPanel::CreateFolder()
if (!_mySelectMode)
state.SelectedNames.Clear();
state.FocusedName = newName;
+ state.SelectFocused = true;
RefreshListCtrl(state);
}
@@ -219,6 +268,7 @@ void CPanel::CreateFile()
if (!_mySelectMode)
state.SelectedNames.Clear();
state.FocusedName = newName;
+ state.SelectFocused = true;
RefreshListCtrl(state);
}
diff --git a/7zip/FileManager/PanelSelect.cpp b/7zip/FileManager/PanelSelect.cpp
index 595a19e4..cbbc13b6 100755
--- a/7zip/FileManager/PanelSelect.cpp
+++ b/7zip/FileManager/PanelSelect.cpp
@@ -129,6 +129,8 @@ void CPanel::UpdateSelection()
{
if (!_mySelectMode)
{
+ bool enableTemp = _enableItemChangeNotify;
+ _enableItemChangeNotify = false;
int numItems = _listView.GetItemCount();
for (int i = 0; i < numItems; i++)
{
@@ -140,6 +142,7 @@ void CPanel::UpdateSelection()
_listView.SetItemState(i, value, LVIS_SELECTED);
}
}
+ _enableItemChangeNotify = enableTemp;
}
_listView.RedrawAllItems();
}
@@ -213,6 +216,24 @@ void CPanel::SelectAll(bool selectMode)
void CPanel::InvertSelection()
{
+ if (!_mySelectMode)
+ {
+ int numSelected = 0;
+ for (int i = 0; i < _selectedStatusVector.Size(); i++)
+ 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 (int i = 0; i < _selectedStatusVector.Size(); i++)
_selectedStatusVector[i] = !_selectedStatusVector[i];
UpdateSelection();
diff --git a/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp b/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp
index dc050d11..8ea16ea8 100755
--- a/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp
+++ b/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp
@@ -499,7 +499,6 @@ public:
Pos = 0;
}
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize);
};
STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
@@ -517,11 +516,6 @@ STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processed
return S_OK;
}
-STDMETHODIMP CBenchmarkInStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
-{
- return Read(data, size, processedSize);
-}
-
class CBenchmarkOutStream:
public ISequentialOutStream,
public CMyUnknownImp
@@ -542,7 +536,6 @@ public:
}
MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
};
STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
@@ -560,11 +553,6 @@ STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *p
return S_OK;
}
-STDMETHODIMP CBenchmarkOutStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize)
-{
- return Write(data, size, processedSize);
-}
-
class CCompareOutStream:
public ISequentialOutStream,
public CMyUnknownImp
@@ -574,7 +562,6 @@ public:
MY_UNKNOWN_IMP
void Init() { CRC.Init(); }
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
};
STDMETHODIMP CCompareOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
@@ -585,11 +572,6 @@ STDMETHODIMP CCompareOutStream::Write(const void *data, UInt32 size, UInt32 *pro
return S_OK;
}
-STDMETHODIMP CCompareOutStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize)
-{
- return Write(data, size, processedSize);
-}
-
typedef UInt32 (WINAPI * CreateObjectPointer)(const GUID *clsID,
const GUID *interfaceID, void **outObject);
diff --git a/7zip/FileManager/StringUtils.cpp b/7zip/FileManager/StringUtils.cpp
index 93fbe094..47560b05 100755
--- a/7zip/FileManager/StringUtils.cpp
+++ b/7zip/FileManager/StringUtils.cpp
@@ -9,7 +9,8 @@ void SplitStringToTwoStrings(const UString &src, UString &dest1, UString &dest2)
dest1.Empty();
dest2.Empty();
bool quoteMode = false;
- for (int i = 0; i < src.Length(); i++)
+ int i;
+ for (i = 0; i < src.Length(); i++)
{
wchar_t c = src[i];
if (c == L'\"')
diff --git a/7zip/FileManager/TextPairs.cpp b/7zip/FileManager/TextPairs.cpp
index 6ccc6bf7..b32d02cf 100755
--- a/7zip/FileManager/TextPairs.cpp
+++ b/7zip/FileManager/TextPairs.cpp
@@ -119,19 +119,15 @@ static int ComparePairIDs(const UString &s1, const UString &s2)
{ return s1.CollateNoCase(s2); }
static int ComparePairItems(const CTextPair &p1, const CTextPair &p2)
{ return ComparePairIDs(p1.ID, p2.ID); }
-static int __cdecl ComparePairItems(const void *a1, const void *a2)
-{
- return ComparePairItems(
- *(*((const CTextPair **)a1)),
- *(*((const CTextPair **)a2)));
-}
+
+// typedef void* MY_PVOID;
+
+// static int ComparePairItems(const MY_PVOID *a1, const MY_PVOID *a2, void *param)
+static int ComparePairItems(void *const *a1, void *const *a2, void *param)
+ { return ComparePairItems(**(const CTextPair **)a1, **(const CTextPair **)a2); }
void CPairsStorage::Sort()
-{
- CPointerVector &pointerVector = Pairs;
- qsort(&pointerVector[0], Pairs.Size(), sizeof(void *),
- ComparePairItems);
-}
+ { Pairs.Sort(ComparePairItems, 0); }
int CPairsStorage::FindID(const UString &id, int &insertPos)
{
diff --git a/7zip/FileManager/resource.h b/7zip/FileManager/resource.h
index 2f76f1e4..d7063043 100755
--- a/7zip/FileManager/resource.h
+++ b/7zip/FileManager/resource.h
@@ -105,6 +105,7 @@
#define IDS_SELECT_MASK 2252
#define IDS_FOLDERS_HISTORY 2260
#define IDS_N_SELECTED_ITEMS 2270
+#define IDS_TOO_MANY_ITEMS 2279
#define IDS_WANT_UPDATE_MODIFIED_FILE 2280
#define IDS_CANNOT_UPDATE_FILE 2281
#define IDS_CANNOT_START_EDITOR 2282
diff --git a/7zip/FileManager/resource.rc b/7zip/FileManager/resource.rc
index 1f8946e3..8e92d804 100755
--- a/7zip/FileManager/resource.rc
+++ b/7zip/FileManager/resource.rc
@@ -176,6 +176,7 @@ BEGIN
IDS_COMMENT "Comment"
IDS_COMMENT2 "&Comment:"
IDS_SYSTEM "System"
+ IDS_TOO_MANY_ITEMS "Too many items"
IDS_WANT_UPDATE_MODIFIED_FILE "File '{0}' was modified.\nDo you want to update it in the archive?"
IDS_CANNOT_UPDATE_FILE "Can not update file\n'{0}'"
IDS_CANNOT_START_EDITOR "Cannot start editor."
diff --git a/7zip/Guid.txt b/7zip/Guid.txt
new file mode 100755
index 00000000..66d202e1
--- /dev/null
+++ b/7zip/Guid.txt
@@ -0,0 +1,152 @@
+{23170F69-40C1-278A-0000-}
+
+000000xx0000 IProgress.h
+
+05 IProgress
+
+
+000300xx0000 IStream.h
+
+01 ISequentialInStream
+02 ISequentialOutStream
+03 IInStream
+04 IOutStream
+06 IStreamGetSize
+07 IOutStreamFlush
+
+
+000400xx0000 ICoder.h
+
+04 ICompressProgressInfo
+05 ICompressCoder
+18 ICompressCoder2
+20 ICompressSetCoderProperties
+21 ICompressSetDecoderProperties //
+22 ICompressSetDecoderProperties2
+23 ICompressWriteCoderProperties
+24 ICompressGetInStreamProcessedSize
+30 ICompressGetSubStreamSize
+31 ICompressSetInStream
+32 ICompressSetOutStream
+33 ICompressSetInStreamSize
+34 ICompressSetOutStreamSize
+40 ICompressFilter
+80 ICryptoProperties
+90 ICryptoSetPassword
+A0 ICryptoSetCRC
+
+
+000500xx0000 IPassword.h
+
+10 ICryptoGetTextPassword
+11 ICryptoGetTextPassword2
+
+
+000600xx0000 IArchive.h
+
+03 ISetProperties
+
+10 IArchiveOpenCallback
+20 IArchiveExtractCallback
+30 IArchiveOpenVolumeCallback
+40 IInArchiveGetStream
+50 IArchiveOpenSetSubArchiveName
+60 IInArchive
+
+80 IArchiveUpdateCallback
+82 IArchiveUpdateCallback2
+A0 IOutArchive
+
+
+000100050001 Agent.h::IArchiveFolderInternal
+
+
+000100xx0000 IFolderArchive.h
+
+05 IArchiveFolder
+06 IInFolderArchive
+07 IFileExtractCallback.h::IFolderArchiveExtractCallback
+0A IOutFolderArchive
+0B IFolderArchiveUpdateCallback
+
+
+
+
+000800xxyy00 FolderInterface.h::
+
+00 IFolderFolder
+01 IEnumProperties
+02 IFolderGetTypeID
+03 IFolderGetPath
+04 IFolderWasChanged
+05 IFolderReload //
+0504 IFolderChangeNotify
+0505 IFolderSetChangeNotify
+050A IFolderExtract //
+06 IFolderOperations
+0601 IFolderOperationsExtractCallback
+0602 IFolderOperationsUpdateCallback //
+0603 IFolderOperationsDeleteToRecycleBin //
+07 IFolderGetSystemIconIndex
+08 IFolderGetItemFullSize
+09 IFolderClone
+0A IFolderOpen //
+
+000900000000} FolderInterface.h::IFolderManager
+000900010000} FolderInterface.h::IFolderManagerGetIconPath
+
+
+{23170F69-40C1-278D-0000-000100010000} PluginInterface::IInitContextMenu
+{23170F69-40C1-278D-0000-000100020100} PluginInterface::IPluginOptionsCallback
+{23170F69-40C1-278D-0000-000100020000} PluginInterface::IPluginOptions
+
+
+Handler GUIDs:
+
+{23170F69-40C1-278A-1000-000110xx0000}
+
+01 Zip
+02 BZip2
+03 Rar
+04 Arj
+05 Z
+06 Lzh
+07 7z
+08 Cab
+
+E9 Chm
+EA Split
+EB Rpm
+EC Deb
+ED Cpio
+EE Tar
+EF GZip
+
+{23170F69-40C1-278A-1000-000100030000} CAgentArchiveHandle
+{23170F69-40C1-278A-1000-000100020000} ContextMenu.h::CZipContextMenu
+
+{23170F69-40C1-278B-
+
+0000-000000000000} Copy
+0203-020000000000} Swap2
+0203-040000000000} Swap4
+0301-01000000ee00} LZMA
+0303-xxdd0000ee00} Branch
+0304-01000000ee00} PPMD
+0401-01000000ee00} Shrink
+0401-06000000ee00} Implode
+0401-08000000ee00} Deflate
+0401-09000000ee00} Deflate64
+0402-02000000ee00} Bzip2
+0402-050000000000} Z
+0403-010000000000} Rar15
+0403-020000000000} Rar20
+0403-030000000000} Rar29
+0601-01000000ee00} AES128_CBC
+0601-81000000ee00} AES256_CBC
+06F1-070100000000} 7zAES
+
+
+
+{23170F69-40C1-278D-1000-000100020000} OptionsDialog.h::CLSID_CSevenZipOptions
+
diff --git a/7zip/ICoder.h b/7zip/ICoder.h
index 631df96c..8d556fdc 100755
--- a/7zip/ICoder.h
+++ b/7zip/ICoder.h
@@ -5,33 +5,27 @@
#include "IStream.h"
-// {23170F69-40C1-278A-0000-000200040000}
-DEFINE_GUID(IID_ICompressProgressInfo,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000200040000")
-ICompressProgressInfo: public IUnknown
+// "23170F69-40C1-278A-0000-000400xx0000"
+#define CODER_INTERFACE(i, x) \
+DEFINE_GUID(IID_ ## i, \
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x04, 0x00, x, 0x00, 0x00); \
+struct i: public IUnknown
+
+CODER_INTERFACE(ICompressProgressInfo, 0x04)
{
- STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) = 0;
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) PURE;
};
-// {23170F69-40C1-278A-0000-000200050000}
-DEFINE_GUID(IID_ICompressCoder,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000200050000")
-ICompressCoder: public IUnknown
+CODER_INTERFACE(ICompressCoder, 0x05)
{
STDMETHOD(Code)(ISequentialInStream *inStream,
ISequentialOutStream *outStream,
const UInt64 *inSize,
const UInt64 *outSize,
- ICompressProgressInfo *progress) = 0;
+ ICompressProgressInfo *progress) PURE;
};
-// {23170F69-40C1-278A-0000-000200180000}
-DEFINE_GUID(IID_ICompressCoder2,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x18, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000200180000")
-ICompressCoder2: public IUnknown
+CODER_INTERFACE(ICompressCoder2, 0x18)
{
STDMETHOD(Code)(ISequentialInStream **inStreams,
const UInt64 **inSizes,
@@ -61,106 +55,62 @@ namespace NCoderPropID
};
}
-// {23170F69-40C1-278A-0000-000200200000}
-DEFINE_GUID(IID_ICompressSetCoderProperties,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x20, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000200200000")
-ICompressSetCoderProperties: public IUnknown
+CODER_INTERFACE(ICompressSetCoderProperties, 0x20)
{
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
const PROPVARIANT *properties, UInt32 numProperties) PURE;
};
/*
-// {23170F69-40C1-278A-0000-000200210000}
-DEFINE_GUID(IID_ICompressSetDecoderProperties,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x21, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000200210000")
-ICompressSetDecoderProperties: public IUnknown
+CODER_INTERFACE(ICompressSetCoderProperties, 0x21)
{
STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE;
};
*/
-// {23170F69-40C1-278A-0000-000200210200}
-DEFINE_GUID(IID_ICompressSetDecoderProperties2,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x21, 0x02, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000200210200")
-ICompressSetDecoderProperties2: public IUnknown
+CODER_INTERFACE(ICompressSetDecoderProperties2, 0x22)
{
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size) PURE;
};
-// {23170F69-40C1-278A-0000-000200230000}
-DEFINE_GUID(IID_ICompressWriteCoderProperties,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x23, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000200230000")
-ICompressWriteCoderProperties: public IUnknown
+CODER_INTERFACE(ICompressWriteCoderProperties, 0x23)
{
STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStreams) PURE;
};
-// {23170F69-40C1-278A-0000-000200240000}
-DEFINE_GUID(IID_ICompressGetInStreamProcessedSize,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x24, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000200240000")
-ICompressGetInStreamProcessedSize: public IUnknown
+CODER_INTERFACE(ICompressGetInStreamProcessedSize, 0x24)
{
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE;
};
-// {23170F69-40C1-278A-0000-000200250000}
-DEFINE_GUID(IID_ICompressGetSubStreamSize,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x25, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000200250000")
-ICompressGetSubStreamSize: public IUnknown
+CODER_INTERFACE(ICompressGetSubStreamSize, 0x30)
{
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value) PURE;
};
-// {23170F69-40C1-278A-0000-000200260000}
-DEFINE_GUID(IID_ICompressSetInStream,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x26, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000200260000")
-ICompressSetInStream: public IUnknown
+CODER_INTERFACE(ICompressSetInStream, 0x31)
{
STDMETHOD(SetInStream)(ISequentialInStream *inStream) PURE;
STDMETHOD(ReleaseInStream)() PURE;
};
-// {23170F69-40C1-278A-0000-000200270000}
-DEFINE_GUID(IID_ICompressSetOutStream,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000200270000")
-ICompressSetOutStream: public IUnknown
+CODER_INTERFACE(ICompressSetOutStream, 0x32)
{
STDMETHOD(SetOutStream)(ISequentialOutStream *outStream) PURE;
STDMETHOD(ReleaseOutStream)() PURE;
};
-// {23170F69-40C1-278A-0000-000200280000}
-DEFINE_GUID(IID_ICompressSetInStreamSize,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000200280000")
-ICompressSetInStreamSize: public IUnknown
+CODER_INTERFACE(ICompressSetInStreamSize, 0x33)
{
STDMETHOD(SetInStreamSize)(const UInt64 *inSize) PURE;
};
-// {23170F69-40C1-278A-0000-000200290000}
-DEFINE_GUID(IID_ICompressSetOutStreamSize,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x29, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000200290000")
-ICompressSetOutStreamSize: public IUnknown
+CODER_INTERFACE(ICompressSetOutStreamSize, 0x34)
{
STDMETHOD(SetOutStreamSize)(const UInt64 *outSize) PURE;
};
-// {23170F69-40C1-278A-0000-000200400000}
-DEFINE_GUID(IID_ICompressFilter,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000200400000")
-ICompressFilter: public IUnknown
+CODER_INTERFACE(ICompressFilter, 0x40)
{
STDMETHOD(Init)() PURE;
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) PURE;
@@ -171,16 +121,22 @@ ICompressFilter: public IUnknown
// (it's for crypto block algorithms).
};
-// {23170F69-40C1-278A-0000-000200800000}
-DEFINE_GUID(IID_ICryptoProperties,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x80, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000200800000")
-ICryptoProperties: public IUnknown
+CODER_INTERFACE(ICryptoProperties, 0x80)
{
STDMETHOD(SetKey)(const Byte *data, UInt32 size) PURE;
STDMETHOD(SetInitVector)(const Byte *data, UInt32 size) PURE;
};
+CODER_INTERFACE(ICryptoSetPassword, 0x90)
+{
+ STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size) PURE;
+};
+
+CODER_INTERFACE(ICryptoSetCRC, 0xA0)
+{
+ STDMETHOD(CryptoSetCRC)(UInt32 crc) PURE;
+};
+
//////////////////////
// It's for DLL file
namespace NMethodPropID
diff --git a/7zip/IPassword.h b/7zip/IPassword.h
index a302b26c..8f2adcca 100755
--- a/7zip/IPassword.h
+++ b/7zip/IPassword.h
@@ -6,38 +6,18 @@
#include "../Common/MyUnknown.h"
#include "../Common/Types.h"
-// {23170F69-40C1-278A-0000-000200250000}
-DEFINE_GUID(IID_ICryptoSetPassword,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x25, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000200250000")
-ICryptoSetPassword: public IUnknown
-{
- STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size) PURE;
-};
-
-// {23170F69-40C1-278A-0000-000200251000}
-DEFINE_GUID(IID_ICryptoSetCRC,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x25, 0x10, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000200251000")
-ICryptoSetCRC: public IUnknown
-{
- STDMETHOD(CryptoSetCRC)(UInt32 crc) PURE;
-};
+// MIDL_INTERFACE("23170F69-40C1-278A-0000-000500xx0000")
+#define PASSWORD_INTERFACE(i, x) \
+DEFINE_GUID(IID_ ## i, \
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x05, 0x00, x, 0x00, 0x00); \
+struct i: public IUnknown
-// {23170F69-40C1-278A-0000-000200270000}
-DEFINE_GUID(IID_ICryptoGetTextPassword,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000200270000")
-ICryptoGetTextPassword: public IUnknown
+PASSWORD_INTERFACE(ICryptoGetTextPassword, 0x10)
{
STDMETHOD(CryptoGetTextPassword)(BSTR *password) PURE;
};
-// {23170F69-40C1-278A-0000-000200270200}
-DEFINE_GUID(IID_ICryptoGetTextPassword2,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, 0x02, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000200270200")
-ICryptoGetTextPassword2: public IUnknown
+PASSWORD_INTERFACE(ICryptoGetTextPassword2, 0x11)
{
STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password) PURE;
};
diff --git a/7zip/IProgress.h b/7zip/IProgress.h
index 23edfc73..aa3b64cc 100755
--- a/7zip/IProgress.h
+++ b/7zip/IProgress.h
@@ -12,7 +12,6 @@ DEFINE_GUID(IID_IProgress,
MIDL_INTERFACE("23170F69-40C1-278A-0000-000000050000")
IProgress: public IUnknown
{
-public:
STDMETHOD(SetTotal)(UInt64 total) PURE;
STDMETHOD(SetCompleted)(const UInt64 *completeValue) PURE;
};
diff --git a/7zip/IStream.h b/7zip/IStream.h
index fd98f771..bba21a31 100755
--- a/7zip/IStream.h
+++ b/7zip/IStream.h
@@ -1,79 +1,62 @@
// IStream.h
-#ifndef __ISTREAMS_H
-#define __ISTREAMS_H
+#ifndef __ISTREAM_H
+#define __ISTREAM_H
#include "../Common/MyUnknown.h"
#include "../Common/Types.h"
-// {23170F69-40C1-278A-0000-000000010000}
-DEFINE_GUID(IID_ISequentialInStream,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000000010000")
-ISequentialInStream : public IUnknown
+// "23170F69-40C1-278A-0000-000300xx0000"
+
+#define STREAM_INTERFACE_SUB(i, b, x) \
+DEFINE_GUID(IID_ ## i, \
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x03, 0x00, x, 0x00, 0x00); \
+struct i: public b
+
+#define STREAM_INTERFACE(i, x) STREAM_INTERFACE_SUB(i, IUnknown, x)
+
+STREAM_INTERFACE(ISequentialInStream, 0x01)
{
-public:
- STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) = 0;
- STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize) = 0;
-
- // For both functions Out: if (*processedSize == 0) then
- // there are no more bytes in stream.
- // Read function always tries to read "size" bytes from stream. It
- // can read less only if it reaches end of stream.
- // ReadPart function can read X bytes: (0<=X<="size") and X can
- // be less than number of remaining bytes in stream.
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE;
+ /*
+ Out: if size != 0, return_value = S_OK and (*processedSize == 0),
+ then there are no more bytes in stream.
+ if (size > 0) && there are bytes in stream,
+ this function must read at least 1 byte.
+ This function is allowed to read less than number of remaining bytes in stream.
+ You must call Read function in loop, if you need exact amount of data
+ */
};
-// {23170F69-40C1-278A-0000-000000020000}
-DEFINE_GUID(IID_ISequentialOutStream,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000000020000")
-ISequentialOutStream : public IUnknown
+STREAM_INTERFACE(ISequentialOutStream, 0x02)
{
-public:
- STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) = 0;
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize) = 0;
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) PURE;
+ /*
+ if (size > 0) this function must write at least 1 byte.
+ This function is allowed to write less than "size".
+ You must call Write function in loop, if you need to write exact amount of data
+ */
};
-// {23170F69-40C1-278A-0000-000000030000}
-DEFINE_GUID(IID_IInStream,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000000030000")
-IInStream : public ISequentialInStream
+STREAM_INTERFACE_SUB(IInStream, ISequentialInStream, 0x03)
{
-public:
- STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) = 0;
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;
};
-// {23170F69-40C1-278A-0000-000000040000}
-DEFINE_GUID(IID_IOutStream,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000000040000")
-IOutStream : public ISequentialOutStream
+STREAM_INTERFACE_SUB(IOutStream, ISequentialOutStream, 0x04)
{
-public:
- STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) = 0;
- STDMETHOD(SetSize)(Int64 newSize) = 0;
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;
+ STDMETHOD(SetSize)(Int64 newSize) PURE;
};
-// {23170F69-40C1-278A-0000-000000060000}
-DEFINE_GUID(IID_IStreamGetSize,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000000060000")
-IStreamGetSize : public IUnknown
+STREAM_INTERFACE(IStreamGetSize, 0x06)
{
-public:
- STDMETHOD(GetSize)(UInt64 *size) = 0;
+ STDMETHOD(GetSize)(UInt64 *size) PURE;
};
-// {23170F69-40C1-278A-0000-000000070000}
-DEFINE_GUID(IID_IOutStreamFlush,
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00);
-MIDL_INTERFACE("23170F69-40C1-278A-0000-000000070000")
-IOutStreamFlush : public IUnknown
+STREAM_INTERFACE(IOutStreamFlush, 0x07)
{
-public:
- STDMETHOD(Flush)() = 0;
+ STDMETHOD(Flush)() PURE;
};
#endif
diff --git a/7zip/MyVersion.h b/7zip/MyVersion.h
index 4f3c3cd4..61f68ccf 100755
--- a/7zip/MyVersion.h
+++ b/7zip/MyVersion.h
@@ -1,7 +1,7 @@
#define MY_VER_MAJOR 4
-#define MY_VER_MINOR 26
-#define MY_VERSION "4.26 beta"
-#define MY_7ZIP_VERSION "7-Zip 4.26 beta"
-#define MY_DATE "2005-08-05"
+#define MY_VER_MINOR 27
+#define MY_VERSION "4.27 beta"
+#define MY_7ZIP_VERSION "7-Zip 4.27 beta"
+#define MY_DATE "2005-09-21"
#define MY_COPYRIGHT "Copyright (c) 1999-2005 Igor Pavlov"
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE
diff --git a/7zip/UI/Agent/AgentOut.cpp b/7zip/UI/Agent/AgentOut.cpp
index ea556d49..d31d40da 100755
--- a/7zip/UI/Agent/AgentOut.cpp
+++ b/7zip/UI/Agent/AgentOut.cpp
@@ -154,7 +154,8 @@ STDMETHODIMP CAgent::DoOperation(
if (!CanUpdate())
return E_NOTIMPL;
NUpdateArchive::CActionSet actionSet;
- for (int i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
+ int i;
+ for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
actionSet.StateActions[i] = (NUpdateArchive::NPairAction::EEnum)stateActions[i];
CObjectVector<CDirItem> dirItems;
@@ -242,7 +243,7 @@ STDMETHODIMP CAgent::DoOperation(
}
CMyComPtr<ISetProperties> setProperties;
- if (outArchive->QueryInterface(&setProperties) == S_OK)
+ if (outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties) == S_OK)
{
if (m_PropNames.Size() == 0)
{
diff --git a/7zip/UI/Agent/AgentProxy.cpp b/7zip/UI/Agent/AgentProxy.cpp
index a77656bb..23b3e9d1 100755
--- a/7zip/UI/Agent/AgentProxy.cpp
+++ b/7zip/UI/Agent/AgentProxy.cpp
@@ -98,7 +98,8 @@ void CProxyFolder::AddRealIndices(CUIntVector &realIndices) const
{
if (IsLeaf)
realIndices.Add(Index);
- for(int i = 0; i < Folders.Size(); i++)
+ int i;
+ for(i = 0; i < Folders.Size(); i++)
Folders[i].AddRealIndices(realIndices);
for(i = 0; i < Files.Size(); i++)
realIndices.Add(Files[i].Index);
diff --git a/7zip/UI/Agent/ArchiveFolderOpen.cpp b/7zip/UI/Agent/ArchiveFolderOpen.cpp
index 0cc088cf..258e3b77 100755
--- a/7zip/UI/Agent/ArchiveFolderOpen.cpp
+++ b/7zip/UI/Agent/ArchiveFolderOpen.cpp
@@ -57,9 +57,12 @@ STDMETHODIMP CArchiveFolderManager::GetTypes(BSTR *types)
UString typesStrings;
for(int i = 0; i < _formats.Size(); i++)
{
+ const CArchiverInfo &ai = _formats[i];
+ if (!ai.Associate)
+ continue;
if (i != 0)
typesStrings += L' ';
- typesStrings += _formats[i].Name;
+ typesStrings += ai.Name;
}
CMyComBSTR valueTemp = typesStrings;
*types = valueTemp.Detach();
@@ -72,8 +75,7 @@ STDMETHODIMP CArchiveFolderManager::GetExtension(const wchar_t *type, BSTR *exte
int formatIndex = FindFormat(type);
if (formatIndex < 0)
return E_INVALIDARG;
- // CMyComBSTR valueTemp = _formats[formatIndex].GetAllExtensions();
- CMyComBSTR valueTemp = _formats[formatIndex].Extensions[0].Extension;
+ CMyComBSTR valueTemp = _formats[formatIndex].Extensions[0].Ext;
*extension = valueTemp.Detach();
return S_OK;
}
@@ -93,6 +95,3 @@ STDMETHODIMP CArchiveFolderManager::CreateFolderFile(const wchar_t *type, const
{
return E_NOTIMPL;
}
-
-
-
diff --git a/7zip/UI/Client7z/Client7z.cpp b/7zip/UI/Client7z/Client7z.cpp
index 970e85a9..90d6cfd3 100755
--- a/7zip/UI/Client7z/Client7z.cpp
+++ b/7zip/UI/Client7z/Client7z.cpp
@@ -11,9 +11,9 @@
#include "Windows/PropVariantConversions.h"
#include "Windows/DLL.h"
-// {23170F69-40C1-278A-1000-000110050000}
+// {23170F69-40C1-278A-1000-000110070000}
DEFINE_GUID(CLSID_CFormat7z,
- 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 0x00, 0x00);
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);
typedef UINT32 (WINAPI * CreateObjectFunc)(
const GUID *clsID,
diff --git a/7zip/UI/Common/ArchiveCommandLine.cpp b/7zip/UI/Common/ArchiveCommandLine.cpp
index 70c2d804..3a3a8c33 100755
--- a/7zip/UI/Common/ArchiveCommandLine.cpp
+++ b/7zip/UI/Common/ArchiveCommandLine.cpp
@@ -691,7 +691,7 @@ static void SetArchiveType(const UString &archiveType,
CArchiveCommandLineParser::CArchiveCommandLineParser(): parser(kNumSwitches) {}
-void CArchiveCommandLineParser::Parse1(UStringVector commandStrings,
+void CArchiveCommandLineParser::Parse1(const UStringVector &commandStrings,
CArchiveCommandLineOptions &options)
{
try
diff --git a/7zip/UI/Common/ArchiveCommandLine.h b/7zip/UI/Common/ArchiveCommandLine.h
index d4cacb17..48bf026d 100755
--- a/7zip/UI/Common/ArchiveCommandLine.h
+++ b/7zip/UI/Common/ArchiveCommandLine.h
@@ -77,7 +77,7 @@ class CArchiveCommandLineParser
NCommandLineParser::CParser parser;
public:
CArchiveCommandLineParser();
- void Parse1(const UStringVector commandStrings, CArchiveCommandLineOptions &options);
+ void Parse1(const UStringVector &commandStrings, CArchiveCommandLineOptions &options);
void Parse2(CArchiveCommandLineOptions &options);
};
diff --git a/7zip/UI/Common/ArchiverInfo.cpp b/7zip/UI/Common/ArchiverInfo.cpp
index 5e88d432..6c7178b3 100755
--- a/7zip/UI/Common/ArchiverInfo.cpp
+++ b/7zip/UI/Common/ArchiverInfo.cpp
@@ -53,15 +53,6 @@ static void SplitString(const UString &srcString, UStringVector &destStrings)
typedef UInt32 (WINAPI * GetHandlerPropertyFunc)(
PROPID propID, PROPVARIANT *value);
-/*
-UString GetCurrentModulePath()
-{
- TCHAR fullPath[MAX_PATH + 1];
- ::GetModuleFileName(g_hInstance, fullPath, MAX_PATH);
- return fullPath;
-}
-*/
-
static UString GetModuleFolderPrefix()
{
UString path;
@@ -132,7 +123,6 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
{
CArchiverInfo item;
item.UpdateEnabled = true;
- item.KeepName = false;
item.Name = L"7z";
item.Extensions.Add(CArchiverExtInfo(L"7z"));
#ifndef _SFX
@@ -163,7 +153,6 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
{
CArchiverInfo item;
item.UpdateEnabled = true;
- item.KeepName = false;
item.Name = L"GZip";
item.Extensions.Add(CArchiverExtInfo(L"gz"));
item.Extensions.Add(CArchiverExtInfo(L"tgz", L".tar"));
@@ -190,7 +179,6 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
{
CArchiverInfo item;
item.UpdateEnabled = true;
- item.KeepName = false;
item.Name = L"Tar";
item.Extensions.Add(CArchiverExtInfo(L"tar"));
archivers.Add(item);
@@ -201,7 +189,6 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
{
CArchiverInfo item;
item.UpdateEnabled = true;
- item.KeepName = false;
item.Name = L"Zip";
item.Extensions.Add(CArchiverExtInfo(L"zip"));
#ifndef _SFX
@@ -215,7 +202,6 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
#ifdef FORMAT_CPIO
{
CArchiverInfo item;
- item.UpdateEnabled = false;
item.Name = L"Cpio";
item.Extensions.Add(CArchiverExtInfo(L"cpio"));
archivers.Add(item);
@@ -225,7 +211,6 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
#ifdef FORMAT_RPM
{
CArchiverInfo item;
- item.UpdateEnabled = false;
item.Name = L"Rpm";
item.Extensions.Add(CArchiverExtInfo(L"rpm", L".cpio.gz"));
archivers.Add(item);
@@ -235,7 +220,6 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
#ifdef FORMAT_ARJ
{
CArchiverInfo item;
- item.UpdateEnabled = false;
item.Name = L"Arj";
item.Extensions.Add(CArchiverExtInfo(L"arj"));
#ifndef _SFX
@@ -249,7 +233,6 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
#ifdef FORMAT_Z
{
CArchiverInfo item;
- item.UpdateEnabled = false;
item.Name = L"Z";
item.Extensions.Add(CArchiverExtInfo(L"Z"));
#ifndef _SFX
@@ -309,11 +292,10 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
continue;
UString ext = prop.bstrVal;
- // item.Extension = prop.bstrVal;
- prop.Clear();
-
UString addExt;
+ prop.Clear();
+
if (getHandlerProperty(NArchive::kAddExtension, &prop) != S_OK)
continue;
if (prop.vt == VT_BSTR)
@@ -332,11 +314,11 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
for (int i = 0; i < exts.Size(); i++)
{
CArchiverExtInfo extInfo;
- extInfo.Extension = exts[i];
+ extInfo.Ext = exts[i];
if (addExts.Size() > 0)
- extInfo.AddExtension = addExts[i];
- if (extInfo.AddExtension == L"*")
- extInfo.AddExtension.Empty();
+ extInfo.AddExt = addExts[i];
+ if (extInfo.AddExt == L"*")
+ extInfo.AddExt.Empty();
item.Extensions.Add(extInfo);
}
@@ -364,6 +346,12 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
}
prop.Clear();
+ if (getHandlerProperty(NArchive::kAssociate, &prop) == S_OK)
+ if (prop.vt == VT_BOOL)
+ item.Associate = VARIANT_BOOLToBool(prop.boolVal);
+ prop.Clear();
+
+
archivers.Add(item);
}
diff --git a/7zip/UI/Common/ArchiverInfo.h b/7zip/UI/Common/ArchiverInfo.h
index 0ce057fa..b05d0614 100755
--- a/7zip/UI/Common/ArchiverInfo.h
+++ b/7zip/UI/Common/ArchiverInfo.h
@@ -9,13 +9,11 @@
struct CArchiverExtInfo
{
- UString Extension;
- UString AddExtension;
+ UString Ext;
+ UString AddExt;
CArchiverExtInfo() {}
- CArchiverExtInfo(const UString &extension):
- Extension(extension) {}
- CArchiverExtInfo(const UString &extension, const UString &addExtension):
- Extension(extension), AddExtension(addExtension) {}
+ CArchiverExtInfo(const UString &ext): Ext(ext) {}
+ CArchiverExtInfo(const UString &ext, const UString &addExt): Ext(ext), AddExt(addExt) {}
};
struct CArchiverInfo
@@ -29,11 +27,12 @@ struct CArchiverInfo
#ifndef _SFX
CByteBuffer StartSignature;
CByteBuffer FinishSignature;
+ bool Associate;
#endif
int FindExtension(const UString &ext) const
{
for (int i = 0; i < Extensions.Size(); i++)
- if (ext.CollateNoCase(Extensions[i].Extension) == 0)
+ if (ext.CollateNoCase(Extensions[i].Ext) == 0)
return i;
return -1;
}
@@ -44,16 +43,22 @@ struct CArchiverInfo
{
if (i > 0)
s += ' ';
- s += Extensions[i].Extension;
+ s += Extensions[i].Ext;
}
return s;
}
const UString &GetMainExtension() const
{
- return Extensions[0].Extension;
+ return Extensions[0].Ext;
}
bool UpdateEnabled;
bool KeepName;
+
+ CArchiverInfo(): UpdateEnabled(false), KeepName(false)
+ #ifndef _SFX
+ ,Associate(true)
+ #endif
+ {}
};
void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers);
diff --git a/7zip/UI/Common/EnumDirItems.cpp b/7zip/UI/Common/EnumDirItems.cpp
index f4212e95..dddc05a9 100755
--- a/7zip/UI/Common/EnumDirItems.cpp
+++ b/7zip/UI/Common/EnumDirItems.cpp
@@ -226,8 +226,11 @@ static HRESULT EnumerateDirItems(
bool enterToSubFolders2 = enterToSubFolders;
UStringVector addArchivePrefixNew = addArchivePrefix;
addArchivePrefixNew.Add(name);
- if (curNode.CheckPathToRoot(false, UStringVector(addArchivePrefixNew), !fileInfo.IsDirectory()))
- continue;
+ {
+ UStringVector addArchivePrefixNewTemp(addArchivePrefixNew);
+ if (curNode.CheckPathToRoot(false, addArchivePrefixNewTemp, !fileInfo.IsDirectory()))
+ continue;
+ }
if (curNode.CheckPathToRoot(true, addArchivePrefixNew, !fileInfo.IsDirectory()))
{
AddDirFileInfo(archivePrefix, diskPrefix + name, fileInfo, dirItems);
diff --git a/7zip/UI/Common/Extract.h b/7zip/UI/Common/Extract.h
index e124d466..8823b08b 100755
--- a/7zip/UI/Common/Extract.h
+++ b/7zip/UI/Common/Extract.h
@@ -7,7 +7,6 @@
#include "Windows/FileFind.h"
#include "../../Archive/IArchive.h"
-#include "../Common/ZipRegistry.h"
#include "ArchiveExtractCallback.h"
#include "ArchiveOpenCallback.h"
diff --git a/7zip/UI/Common/OpenArchive.cpp b/7zip/UI/Common/OpenArchive.cpp
index 91339d47..88a231a4 100755
--- a/7zip/UI/Common/OpenArchive.cpp
+++ b/7zip/UI/Common/OpenArchive.cpp
@@ -12,6 +12,7 @@
#include "Windows/PropVariant.h"
#include "../../Common/FileStreams.h"
+#include "../../Common/StreamUtils.h"
#include "Common/StringConvert.h"
@@ -179,7 +180,7 @@ HRESULT OpenArchive(
Byte *buffer = byteBuffer;
RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
UInt32 processedSize;
- RINOK(inStream->Read(buffer, kBufferSize, &processedSize));
+ RINOK(ReadStream(inStream, buffer, kBufferSize, &processedSize));
int numFinded = 0;
for (int pos = (int)processedSize; pos >= 0 ; pos--)
{
@@ -281,8 +282,8 @@ HRESULT OpenArchive(
if (subExtIndex < 0)
subExtIndex = 0;
defaultItemName = GetDefaultName2(fileName,
- archiverInfo.Extensions[subExtIndex].Extension,
- archiverInfo.Extensions[subExtIndex].AddExtension);
+ archiverInfo.Extensions[subExtIndex].Ext,
+ archiverInfo.Extensions[subExtIndex].AddExt);
return S_OK;
}
diff --git a/7zip/UI/Common/SortUtils.cpp b/7zip/UI/Common/SortUtils.cpp
index 1c647d53..8c953750 100755
--- a/7zip/UI/Common/SortUtils.cpp
+++ b/7zip/UI/Common/SortUtils.cpp
@@ -4,29 +4,22 @@
#include "SortUtils.h"
-static int __cdecl CompareStrings(const void *a1, const void *a2)
+static int CompareStrings(const int *p1, const int *p2, void *param)
{
- const UString &s1 = *(*(*((const UString ***)a1)));
- const UString &s2 = *(*(*((const UString ***)a2)));
+ const UStringVector &strings = *(const UStringVector *)param;
+ const UString &s1 = strings[*p1];
+ const UString &s2 = strings[*p2];
return s1.CompareNoCase(s2);
}
void SortStringsToIndices(const UStringVector &strings, CIntVector &indices)
{
indices.Clear();
- if (strings.IsEmpty())
- return;
int numItems = strings.Size();
- CPointerVector pointers;
- pointers.Reserve(numItems);
indices.Reserve(numItems);
- int i;
- for(i = 0; i < numItems; i++)
- pointers.Add((void *)&strings.CPointerVector::operator[](i));
- void **stringsBase = (void **)pointers[0];
- qsort(&pointers[0], numItems, sizeof(void *), CompareStrings);
- for(i = 0; i < numItems; i++)
- indices.Add((int)((void **)pointers[i] - stringsBase));
+ for(int i = 0; i < numItems; i++)
+ indices.Add(i);
+ indices.Sort(CompareStrings, (void *)&strings);
}
void SortStrings(const UStringVector &src, UStringVector &dest)
diff --git a/7zip/UI/Common/Update.cpp b/7zip/UI/Common/Update.cpp
index e2fde3de..a241c9c4 100755
--- a/7zip/UI/Common/Update.cpp
+++ b/7zip/UI/Common/Update.cpp
@@ -129,7 +129,6 @@ public:
MY_UNKNOWN_IMP1(IOutStream)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
STDMETHOD(SetSize)(Int64 newSize);
};
@@ -207,17 +206,13 @@ STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *pr
_streamIndex++;
_offsetPos = 0;
}
- if (realProcessed != curSize)
+ if (realProcessed == 0 && curSize != 0)
return E_FAIL;
+ break;
}
return S_OK;
}
-STDMETHODIMP COutMultiVolStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize)
-{
- return Write(data, size, processedSize);
-}
-
STDMETHODIMP COutMultiVolStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
if(seekOrigin >= 3)
diff --git a/7zip/UI/Console/Console.dsp b/7zip/UI/Console/Console.dsp
index f6764fa1..29f10b2f 100755
--- a/7zip/UI/Console/Console.dsp
+++ b/7zip/UI/Console/Console.dsp
@@ -618,6 +618,14 @@ SOURCE=..\..\Common\FileStreams.cpp
SOURCE=..\..\Common\FileStreams.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 "Compress"
diff --git a/7zip/UI/Console/Main.cpp b/7zip/UI/Console/Main.cpp
index 3f000188..a72bfca7 100755
--- a/7zip/UI/Console/Main.cpp
+++ b/7zip/UI/Console/Main.cpp
@@ -91,7 +91,7 @@ static const char *kHelpString =
" -si: read data from stdin\n"
" -so: write data to stdout\n"
" -t{Type}: Set type of archive\n"
- " -v{Size}}[b|k|m|g]: Create volumes\n"
+ " -v{Size}[b|k|m|g]: Create volumes\n"
" -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName]: Update options\n"
" -w[{path}]: assign Work directory. Empty path means a temporary directory\n"
" -x[r[-|0]]]{@listfile|!wildcard}: eXclude filenames\n"
@@ -232,6 +232,8 @@ int Main2(
if (ecs->NumFileErrors != 0)
stdStream << "Sub items Errors: " << ecs->NumFileErrors << endl;
}
+ if (result != S_OK)
+ throw CSystemException(result);
return NExitCode::kFatalError;
}
if (result != S_OK)
diff --git a/7zip/UI/Console/makefile b/7zip/UI/Console/makefile
index b5f97e48..b9a5ef0b 100755
--- a/7zip/UI/Console/makefile
+++ b/7zip/UI/Console/makefile
@@ -42,6 +42,7 @@ WIN_OBJS = \
7ZIP_COMMON_OBJS = \
$O\FilePathAutoRename.obj \
$O\FileStreams.obj \
+ $O\StreamUtils.obj \
UI_COMMON_OBJS = \
$O\ArchiveCommandLine.obj \
diff --git a/7zip/UI/Explorer/ContextMenu.cpp b/7zip/UI/Explorer/ContextMenu.cpp
index 06465e86..94cf1bd4 100755
--- a/7zip/UI/Explorer/ContextMenu.cpp
+++ b/7zip/UI/Explorer/ContextMenu.cpp
@@ -583,6 +583,7 @@ struct CThreadCompressMain
};
*/
+#ifndef _WIN64
static bool IsItWindowsNT()
{
OSVERSIONINFO versionInfo;
@@ -591,6 +592,7 @@ static bool IsItWindowsNT()
return false;
return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
}
+#endif
static UString GetProgramCommand()
{
@@ -598,11 +600,12 @@ static UString GetProgramCommand()
UString folder;
if (GetProgramFolderPath(folder))
path += folder;
+ path += L"7zFM";
+ #ifndef _WIN64
if (IsItWindowsNT())
- path += L"7zFMn.exe";
- else
- path += L"7zFM.exe";
- path += L"\"";
+ path += L"n";
+ #endif
+ path += L".exe\"";
return path;
}
diff --git a/7zip/UI/Explorer/Explorer.dsp b/7zip/UI/Explorer/Explorer.dsp
index 371c9ac4..34555372 100755
--- a/7zip/UI/Explorer/Explorer.dsp
+++ b/7zip/UI/Explorer/Explorer.dsp
@@ -744,6 +744,14 @@ SOURCE=..\..\Common\FileStreams.cpp
SOURCE=..\..\Common\FileStreams.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 "Compress"
diff --git a/7zip/UI/Explorer/makefile b/7zip/UI/Explorer/makefile
index 99059538..d1938716 100755
--- a/7zip/UI/Explorer/makefile
+++ b/7zip/UI/Explorer/makefile
@@ -50,6 +50,7 @@ WIN_CTRL_OBJS = \
7ZIP_COMMON_OBJS = \
$O\FilePathAutoRename.obj \
$O\FileStreams.obj \
+ $O\StreamUtils.obj \
UI_COMMON_OBJS = \
$O\ArchiveExtractCallback.obj \
diff --git a/7zip/UI/Far/Far.dsp b/7zip/UI/Far/Far.dsp
index dab36478..47c44c69 100755
--- a/7zip/UI/Far/Far.dsp
+++ b/7zip/UI/Far/Far.dsp
@@ -548,6 +548,14 @@ SOURCE=..\..\Common\FileStreams.cpp
SOURCE=..\..\Common\FileStreams.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
# End Target
# End Project
diff --git a/7zip/UI/Far/Messages.h b/7zip/UI/Far/Messages.h
index a0f1098c..8b6e2a49 100755
--- a/7zip/UI/Far/Messages.h
+++ b/7zip/UI/Far/Messages.h
@@ -63,6 +63,7 @@ enum EEnum
kExtractOwerwritePrompt,
kExtractOwerwriteSkip,
kExtractOwerwriteAutoRename,
+ kExtractOwerwriteAutoRenameExisting,
kExtractFilesMode,
kExtractFilesSelected,
diff --git a/7zip/UI/Far/PluginRead.cpp b/7zip/UI/Far/PluginRead.cpp
index e9b6f98c..79409142 100755
--- a/7zip/UI/Far/PluginRead.cpp
+++ b/7zip/UI/Far/PluginRead.cpp
@@ -112,19 +112,22 @@ NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *pa
const int kPathModeRadioIndex = 4;
const int kOverwriteModeRadioIndex = kPathModeRadioIndex + 4;
- const int kFilesModeIndex = kOverwriteModeRadioIndex + 5;
- const int kYSize = 18;
+ const int kNumOverwriteOptions = 6;
+ const int kFilesModeIndex = kOverwriteModeRadioIndex + kNumOverwriteOptions;
+ const int kXSize = 76;
+ const int kYSize = 19;
+ const int kPasswordYPos = 12;
- const int kXMid = 38;
+ const int kXMid = kXSize / 2;
AString oemPassword = UnicodeStringToMultiByte(password, CP_OEMCP);
struct CInitDialogItem initItems[]={
- { DI_DOUBLEBOX, 3, 1, 72, kYSize - 2, false, false, 0, false, NMessageID::kExtractTitle, NULL, NULL },
+ { 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, 70, 3, true, false, DIF_HISTORY, false, -1, destPath, kExractPathHistoryName},
- // { DI_EDIT, 5, 3, 70, 3, true, false, 0, false, -1, destPath, 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,
@@ -137,7 +140,7 @@ NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *pa
extractionInfo.PathMode == NExtract::NPathMode::kNoPathnames,
false, 0, NMessageID::kExtractPathNo, NULL, NULL },
- { DI_SINGLEBOX, kXMid, 5, 70, 5 + 5, false, false, 0, false, NMessageID::kExtractOwerwriteMode, 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::kAskBefore,
DIF_GROUP, false, NMessageID::kExtractOwerwriteAsk, NULL, NULL },
@@ -150,13 +153,16 @@ NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *pa
{ DI_RADIOBUTTON, kXMid + 2, 9, 0, 0, false,
extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kAutoRename,
0, false, NMessageID::kExtractOwerwriteAutoRename, NULL, NULL },
+ { DI_RADIOBUTTON, kXMid + 2, 10, 0, 0, false,
+ extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kAutoRenameExisting,
+ 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, 11, 70, 11 + 2, false, false, 0, false, NMessageID::kExtractPassword, NULL, NULL },
- { DI_PSWEDIT, kXMid + 2, 12, 70 - 2, 12, false, false, 0, false, -1, oemPassword, 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 },
@@ -173,7 +179,7 @@ NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *pa
g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems);
while(true)
{
- int askCode = g_StartupInfo.ShowDialog(76, kYSize,
+ int askCode = g_StartupInfo.ShowDialog(kXSize, kYSize,
kHelpTopicExtrFromSevenZip, dialogItems, kNumDialogItems);
if (askCode != kOkButtonIndex)
return NFileOperationReturnCode::kInterruptedByUser;
@@ -211,6 +217,8 @@ NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *pa
extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kSkipExisting;
else if (dialogItems[kOverwriteModeRadioIndex + 3].Selected)
extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kAutoRename;
+ else if (dialogItems[kOverwriteModeRadioIndex + 4].Selected)
+ extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kAutoRenameExisting;
else
throw 31806;
@@ -247,41 +255,8 @@ NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *pa
for (int i = 0; i < itemsNumber; i++)
indices.Add(panelItems[i].UserData);
- NExtract::NPathMode::EEnum pathMode;
- NExtract::NOverwriteMode::EEnum overwriteMode;
- switch (extractionInfo.OverwriteMode)
- {
- case NExtract::NOverwriteMode::kAskBefore:
- overwriteMode = NExtract::NOverwriteMode::kAskBefore;
- break;
- case NExtract::NOverwriteMode::kWithoutPrompt:
- overwriteMode = NExtract::NOverwriteMode::kWithoutPrompt;
- break;
- case NExtract::NOverwriteMode::kSkipExisting:
- overwriteMode = NExtract::NOverwriteMode::kSkipExisting;
- break;
- case NExtract::NOverwriteMode::kAutoRename:
- overwriteMode = NExtract::NOverwriteMode::kAutoRename;
- break;
- default:
- throw 12334454;
- }
- switch (extractionInfo.PathMode)
- {
- case NExtract::NPathMode::kFullPathnames:
- pathMode = NExtract::NPathMode::kFullPathnames;
- break;
- case NExtract::NPathMode::kCurrentPathnames:
- pathMode = NExtract::NPathMode::kCurrentPathnames;
- break;
- case NExtract::NPathMode::kNoPathnames:
- pathMode = NExtract::NPathMode::kNoPathnames;
- break;
- default:
- throw 12334455;
- }
HRESULT result = ExtractFiles(decompressAllItems, &indices.Front(), itemsNumber,
- !showBox, pathMode, overwriteMode,
+ !showBox, extractionInfo.PathMode, extractionInfo.OverwriteMode,
MultiByteToUnicodeString(destPath, CP_OEMCP),
passwordIsDefined, password);
// HRESULT result = ExtractFiles(decompressAllItems, realIndices, !showBox,
diff --git a/7zip/UI/Far/PluginWrite.cpp b/7zip/UI/Far/PluginWrite.cpp
index e9581c59..0342be2e 100755
--- a/7zip/UI/Far/PluginWrite.cpp
+++ b/7zip/UI/Far/PluginWrite.cpp
@@ -40,7 +40,7 @@ static UINT32 g_MethodMap[] = { 0, 1, 3, 5, 7, 9 };
static HRESULT SetOutProperties(IOutFolderArchive *outArchive, UINT32 method)
{
CMyComPtr<ISetProperties> setProperties;
- if (outArchive->QueryInterface(&setProperties) == S_OK)
+ if (outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties) == S_OK)
{
UStringVector realNames;
realNames.Add(UString(L"x"));
diff --git a/7zip/UI/Far/makefile b/7zip/UI/Far/makefile
index 5b9d8bcd..d5819130 100755
--- a/7zip/UI/Far/makefile
+++ b/7zip/UI/Far/makefile
@@ -42,6 +42,7 @@ WIN_OBJS = \
7ZIP_COMMON_OBJS = \
$O\FilePathAutoRename.obj \
$O\FileStreams.obj \
+ $O\StreamUtils.obj \
UI_COMMON_OBJS = \
$O\ArchiveExtractCallback.obj \
diff --git a/7zip/UI/GUI/CompressDialog.cpp b/7zip/UI/GUI/CompressDialog.cpp
index 7bb40248..2a0147c3 100755
--- a/7zip/UI/GUI/CompressDialog.cpp
+++ b/7zip/UI/GUI/CompressDialog.cpp
@@ -509,20 +509,8 @@ void CCompressDialog::OnOK()
_passwordControl.GetText(Info.Password);
SaveOptionsInMem();
- int currentItem = m_ArchivePath.GetCurSel();
UString s;
- if(currentItem == CB_ERR)
- {
- m_ArchivePath.GetText(s);
- if(m_ArchivePath.GetCount() >= kHistorySize)
- currentItem = m_ArchivePath.GetCount() - 1;
- }
- else
- {
- CSysString sTemp;
- m_ArchivePath.GetLBText(currentItem, sTemp);
- s = GetUnicodeString(sTemp);
- }
+ m_ArchivePath.GetText(s);
s.Trim();
m_RegistryInfo.HistoryArchives.Clear();
AddUniqueString(m_RegistryInfo.HistoryArchives, GetSystemString(s));
@@ -555,13 +543,14 @@ void CCompressDialog::OnOK()
}
for(int i = 0; i < m_ArchivePath.GetCount(); i++)
- if(i != currentItem)
- {
- CSysString sTemp;
- m_ArchivePath.GetLBText(i, sTemp);
- sTemp.Trim();
- AddUniqueString(m_RegistryInfo.HistoryArchives, sTemp);
- }
+ {
+ CSysString sTemp;
+ m_ArchivePath.GetLBText(i, sTemp);
+ sTemp.Trim();
+ AddUniqueString(m_RegistryInfo.HistoryArchives, sTemp);
+ }
+ if (m_RegistryInfo.HistoryArchives.Size() > kHistorySize)
+ m_RegistryInfo.HistoryArchives.DeleteBack();
////////////////////
// Method
diff --git a/7zip/UI/GUI/GUI.dsp b/7zip/UI/GUI/GUI.dsp
index 3473cc76..e8db155c 100755
--- a/7zip/UI/GUI/GUI.dsp
+++ b/7zip/UI/GUI/GUI.dsp
@@ -847,6 +847,14 @@ SOURCE=..\..\Common\FileStreams.cpp
SOURCE=..\..\Common\FileStreams.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 "Compress"
diff --git a/7zip/UI/GUI/makefile b/7zip/UI/GUI/makefile
index cfe1493c..20c6caaa 100755
--- a/7zip/UI/GUI/makefile
+++ b/7zip/UI/GUI/makefile
@@ -50,6 +50,7 @@ WIN_CTRL_OBJS = \
7ZIP_COMMON_OBJS = \
$O\FilePathAutoRename.obj \
$O\FileStreams.obj \
+ $O\StreamUtils.obj \
UI_COMMON_OBJS = \
$O\ArchiveCommandLine.obj \
diff --git a/Build.mak b/Build.mak
index 2c44d453..d4f08684 100755
--- a/Build.mak
+++ b/Build.mak
@@ -1,5 +1,6 @@
!IFDEF CPU
LIBS = $(LIBS) bufferoverflowU.lib
+CFLAGS = $(CFLAGS) -GS- -Zc:forScope
!ENDIF
!IFNDEF O
@@ -10,7 +11,7 @@ O=O
!ENDIF
!ENDIF
-CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -EHsc -Gz -GS-
+CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -EHsc -Gz -WX
!IFDEF MY_STATIC_LINK
!IFNDEF MY_SINGLE_THREAD
CFLAGS = $(CFLAGS) -MT
diff --git a/Common/Buffer.h b/Common/Buffer.h
index 9d5fcaec..9bd881cf 100755
--- a/Common/Buffer.h
+++ b/Common/Buffer.h
@@ -26,6 +26,8 @@ public:
size_t GetCapacity() const { return _capacity; }
void SetCapacity(size_t newCapacity)
{
+ if (newCapacity == _capacity)
+ return;
T *newBuffer;
if (newCapacity > 0)
{
diff --git a/Common/Copy of StringConvert.cpp b/Common/Copy of StringConvert.cpp
deleted file mode 100755
index d6d05d6c..00000000
--- a/Common/Copy of StringConvert.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-// Common/StringConvert.cpp
-
-#include "StdAfx.h"
-
-#include "StringConvert.h"
-
-#ifndef _WIN32
-#include <stdlib.h>
-#endif
-
-#ifdef _WIN32
-UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
-{
- UString resultString;
- if(!srcString.IsEmpty())
- {
- int numChars = MultiByteToWideChar(codePage, 0, srcString,
- srcString.Length(), resultString.GetBuffer(srcString.Length()),
- srcString.Length() + 1);
- #ifndef _WIN32_WCE
- if(numChars == 0)
- throw 282228;
- #endif
- resultString.ReleaseBuffer(numChars);
- }
- return resultString;
-}
-
-AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage)
-{
- AString resultString;
- if(!srcString.IsEmpty())
- {
- int numRequiredBytes = srcString.Length() * 2;
- int numChars = WideCharToMultiByte(codePage, 0, srcString,
- srcString.Length(), resultString.GetBuffer(numRequiredBytes),
- numRequiredBytes + 1, NULL, NULL);
- #ifndef _WIN32_WCE
- if(numChars == 0)
- throw 282229;
- #endif
- resultString.ReleaseBuffer(numChars);
- }
- return resultString;
-}
-
-#ifndef _WIN32_WCE
-AString SystemStringToOemString(const CSysString &srcString)
-{
- AString result;
- CharToOem(srcString, result.GetBuffer(srcString.Length() * 2));
- result.ReleaseBuffer();
- return result;
-}
-#endif
-
-#else
-
-UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
-{
- UString resultString;
- for (int i = 0; i < srcString.Length(); i++)
- resultString += wchar_t(srcString[i]);
- /*
- if(!srcString.IsEmpty())
- {
- int numChars = mbstowcs(resultString.GetBuffer(srcString.Length()), srcString, srcString.Length() + 1);
- if (numChars < 0) throw "Your environment does not support UNICODE";
- resultString.ReleaseBuffer(numChars);
- }
- */
- return resultString;
-}
-
-AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage)
-{
- AString resultString;
- for (int i = 0; i < srcString.Length(); i++)
- resultString += char(srcString[i]);
- /*
- if(!srcString.IsEmpty())
- {
- int numRequiredBytes = srcString.Length() * 6 + 1;
- int numChars = wcstombs(resultString.GetBuffer(numRequiredBytes), srcString, numRequiredBytes);
- if (numChars < 0) throw "Your environment does not support UNICODE";
- resultString.ReleaseBuffer(numChars);
- }
- */
- return resultString;
-}
-
-#endif
-
diff --git a/Common/Copy of StringConvert.h b/Common/Copy of StringConvert.h
deleted file mode 100755
index daee50b0..00000000
--- a/Common/Copy of StringConvert.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Common/StringConvert.h
-
-#ifndef __COMMON_STRINGCONVERT_H
-#define __COMMON_STRINGCONVERT_H
-
-#include "MyWindows.h"
-#include "Common/String.h"
-#include "Types.h"
-
-UString MultiByteToUnicodeString(const AString &srcString, UINT codePage = CP_ACP);
-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 codePage)
- { return unicodeString; }
-inline const UString& GetUnicodeString(const UString &unicodeString, UINT codePage)
- { 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 codePage)
- { return multiByteString; }
- inline const char * GetSystemString(const char *multiByteString, UINT codePage)
- { 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 _WIN32_WCE
-AString SystemStringToOemString(const CSysString &srcString);
-#endif
-
-#endif
diff --git a/Common/Copy of UTFConvert.cpp b/Common/Copy of UTFConvert.cpp
deleted file mode 100755
index e15695bb..00000000
--- a/Common/Copy of UTFConvert.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-// UTFConvert.cpp
-
-#include "StdAfx.h"
-
-#include "UTFConvert.h"
-#include "Types.h"
-
-static Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
-
-// These functions are for UTF8 <-> UTF16 conversion.
-
-bool ConvertUTF8ToUnicode(const AString &src, UString &dest)
-{
- dest.Empty();
- for(int i = 0; i < src.Length();)
- {
- Byte c = (Byte)src[i++];
- if (c < 0x80)
- {
- dest += (wchar_t)c;
- continue;
- }
- if(c < 0xC0)
- return false;
- int numAdds;
- for (numAdds = 1; numAdds < 5; numAdds++)
- if (c < kUtf8Limits[numAdds])
- break;
- UInt32 value = (c - kUtf8Limits[numAdds - 1]);
- do
- {
- if (i >= src.Length())
- return false;
- Byte c2 = (Byte)src[i++];
- if (c2 < 0x80 || c2 >= 0xC0)
- return false;
- value <<= 6;
- value |= (c2 - 0x80);
- numAdds--;
- }
- while(numAdds > 0);
- if (value < 0x10000)
- dest += (wchar_t)(value);
- else
- {
- value -= 0x10000;
- if (value >= 0x100000)
- return false;
- dest += (wchar_t)(0xD800 + (value >> 10));
- dest += (wchar_t)(0xDC00 + (value & 0x3FF));
- }
- }
- return true;
-}
-
-bool ConvertUnicodeToUTF8(const UString &src, AString &dest)
-{
- dest.Empty();
- for(int i = 0; i < src.Length();)
- {
- UInt32 value = (UInt32)src[i++];
- if (value < 0x80)
- {
- dest += (char)value;
- continue;
- }
- if (value >= 0xD800 && value < 0xE000)
- {
- if (value >= 0xDC00)
- return false;
- if (i >= src.Length())
- return false;
- UInt32 c2 = (UInt32)src[i++];
- if (c2 < 0xDC00 || c2 >= 0xE000)
- return false;
- value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
- }
- int numAdds;
- for (numAdds = 1; numAdds < 5; numAdds++)
- if (value < (((UInt32)1) << (numAdds * 5 + 6)))
- break;
- dest += (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
- do
- {
- numAdds--;
- dest += (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
- }
- while(numAdds > 0);
- }
- return true;
-}
diff --git a/Common/Copy of UTFConvert.h b/Common/Copy of UTFConvert.h
deleted file mode 100755
index 47434111..00000000
--- a/Common/Copy of UTFConvert.h
+++ /dev/null
@@ -1,11 +0,0 @@
-// Common/UTFConvert.h
-
-#ifndef __COMMON_UTFCONVERT_H
-#define __COMMON_UTFCONVERT_H
-
-#include "Common/String.h"
-
-bool ConvertUTF8ToUnicode(const AString &utfString, UString &resultString);
-bool ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString);
-
-#endif
diff --git a/Common/MyCom.h b/Common/MyCom.h
index 4101d815..e9034930 100755
--- a/Common/MyCom.h
+++ b/Common/MyCom.h
@@ -166,7 +166,9 @@ STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \
MY_ADDREF_RELEASE
-#define MY_UNKNOWN_IMP MY_UNKNOWN_IMP_SPEC(;)
+#define MY_UNKNOWN_IMP STDMETHOD(QueryInterface)(REFGUID, void **) { \
+ MY_QUERYINTERFACE_END \
+ MY_ADDREF_RELEASE
#define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \
MY_QUERYINTERFACE_ENTRY(i) \
diff --git a/Common/MyGuidDef.h b/Common/MyGuidDef.h
index 2fb7df65..2c954f81 100755
--- a/Common/MyGuidDef.h
+++ b/Common/MyGuidDef.h
@@ -3,10 +3,12 @@
#ifndef GUID_DEFINED
#define GUID_DEFINED
+#include "Types.h"
+
typedef struct {
- unsigned long Data1;
- unsigned short Data2;
- unsigned short Data3;
+ UInt32 Data1;
+ UInt16 Data2;
+ UInt16 Data3;
unsigned char Data4[8];
} GUID;
diff --git a/Common/MyWindows.h b/Common/MyWindows.h
index d93afc1c..6df08d6f 100755
--- a/Common/MyWindows.h
+++ b/Common/MyWindows.h
@@ -12,7 +12,6 @@
#include <stddef.h> // for wchar_t
#include <string.h>
-#include "Types.h"
#include "MyGuidDef.h"
typedef char CHAR;
diff --git a/Common/String.h b/Common/String.h
index 56509016..a34e8347 100755
--- a/Common/String.h
+++ b/Common/String.h
@@ -34,9 +34,9 @@ inline wchar_t* MyStringGetNextCharPointer(wchar_t *p)
{ return (p + 1); }
inline const wchar_t* MyStringGetNextCharPointer(const wchar_t *p)
{ return (p + 1); }
-inline wchar_t* MyStringGetPrevCharPointer(const wchar_t *base, wchar_t *p)
+inline wchar_t* MyStringGetPrevCharPointer(const wchar_t *, wchar_t *p)
{ return (p - 1); }
-inline const wchar_t* MyStringGetPrevCharPointer(const wchar_t *base, const wchar_t *p)
+inline const wchar_t* MyStringGetPrevCharPointer(const wchar_t *, const wchar_t *p)
{ return (p - 1); }
#ifdef _WIN32
diff --git a/Common/StringConvert.h b/Common/StringConvert.h
index daee50b0..648ca028 100755
--- a/Common/StringConvert.h
+++ b/Common/StringConvert.h
@@ -18,9 +18,9 @@ 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 codePage)
+inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString, UINT)
{ return unicodeString; }
-inline const UString& GetUnicodeString(const UString &unicodeString, UINT codePage)
+inline const UString& GetUnicodeString(const UString &unicodeString, UINT)
{ return unicodeString; }
inline const char* GetAnsiString(const char* ansiString)
@@ -54,9 +54,9 @@ inline AString GetOemString(const UString &unicodeString)
#else
inline const char* GetSystemString(const char *ansiString)
{ return ansiString; }
- inline const AString& GetSystemString(const AString &multiByteString, UINT codePage)
+ inline const AString& GetSystemString(const AString &multiByteString, UINT)
{ return multiByteString; }
- inline const char * GetSystemString(const char *multiByteString, UINT codePage)
+ inline const char * GetSystemString(const char *multiByteString, UINT)
{ return multiByteString; }
inline AString GetSystemString(const UString &unicodeString)
{ return UnicodeStringToMultiByte(unicodeString); }
diff --git a/Common/StringToInt.cpp b/Common/StringToInt.cpp
index 9f02ec9d..1fa8ef21 100755
--- a/Common/StringToInt.cpp
+++ b/Common/StringToInt.cpp
@@ -22,6 +22,25 @@ UInt64 ConvertStringToUInt64(const char *s, const char **end)
}
}
+UInt64 ConvertOctStringToUInt64(const char *s, const char **end)
+{
+ UInt64 result = 0;
+ while(true)
+ {
+ char c = *s;
+ if (c < '0' || c > '7')
+ {
+ if (end != NULL)
+ *end = s;
+ return result;
+ }
+ result <<= 3;
+ result += (c - '0');
+ s++;
+ }
+}
+
+
UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end)
{
UInt64 result = 0;
diff --git a/Common/StringToInt.h b/Common/StringToInt.h
index f3fc22e8..bb971f62 100755
--- a/Common/StringToInt.h
+++ b/Common/StringToInt.h
@@ -7,6 +7,7 @@
#include "Types.h"
UInt64 ConvertStringToUInt64(const char *s, const char **end);
+UInt64 ConvertOctStringToUInt64(const char *s, const char **end);
UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end);
Int64 ConvertStringToInt64(const char *s, const char **end);
diff --git a/Common/Vector.h b/Common/Vector.h
index 858e53d3..984fddc1 100755
--- a/Common/Vector.h
+++ b/Common/Vector.h
@@ -70,14 +70,46 @@ public:
T& Front() { return operator[](0); }
const T& Back() const { return operator[](_size - 1); }
T& Back() { return operator[](_size - 1); }
- static int
- #ifdef _MSC_VER
- __cdecl
- #endif
- CompareRecordItems(const void *a1, const void *a2)
- { return MyCompare(*((const T *)a1), *((const T *)a2)); }
- void Sort()
- { qsort(&Front(), Size(), _itemSize, CompareRecordItems); }
+
+ void Swap(int i, int j)
+ {
+ T temp = operator[](i);
+ operator[](i) = operator[](j);
+ operator[](j) = temp;
+ }
+
+ void Sort(int left, int right)
+ {
+ if (right - left < 2)
+ return;
+ Swap(left, (left + right) / 2);
+ int last = left;
+ for (int i = left; i < right; i++)
+ if (operator[](i) < operator[](left))
+ Swap(++last, i);
+ Swap(left, last);
+ Sort(left, last);
+ Sort(last + 1, right);
+ }
+ void Sort() { Sort(0, Size()); }
+ void Sort(int left, int right, int (*compare)(const T*, const T*, void *), void *param)
+ {
+ if (right - left < 2)
+ return;
+ Swap(left, (left + right) / 2);
+ int last = left;
+ for (int i = left; i < right; i++)
+ if (compare(&operator[](i), &operator[](left), param) < 0)
+ Swap(++last, i);
+ Swap(left, last);
+ Sort(left, last, compare, param);
+ Sort(last + 1, right, compare, param);
+ }
+
+ void Sort(int (*compare)(const T*, const T*, void *), void *param)
+ {
+ Sort(0, Size(), compare, param);
+ }
};
typedef CRecordVector<int> CIntVector;
@@ -167,17 +199,13 @@ public:
Insert(right, item);
return right;
}
- static int
- #ifdef _MSC_VER
- __cdecl
- #endif
- CompareObjectItems(const void *a1, const void *a2)
+
+ void Sort(int (*compare)(void *const *, void *const *, void *), void *param)
+ { CPointerVector::Sort(compare, param); }
+
+ static int CompareObjectItems(void *const *a1, void *const *a2, void *param)
{ return MyCompare(*(*((const T **)a1)), *(*((const T **)a2))); }
- void Sort()
- {
- CPointerVector &pointerVector = *this;
- qsort(&pointerVector[0], Size(), sizeof(void *), CompareObjectItems);
- }
+ void Sort() { CPointerVector::Sort(CompareObjectItems, 0); }
};
#endif
diff --git a/DOC/7zFormat.txt b/DOC/7zFormat.txt
index 045fc853..56ff817c 100755
--- a/DOC/7zFormat.txt
+++ b/DOC/7zFormat.txt
@@ -171,8 +171,8 @@ SignatureHeader
ArchiveVersion
{
- BYTE Major; // now it = 0
- BYTE Minor; // now it = 1
+ BYTE Major; // now = 0
+ BYTE Minor; // now = 2
};
UINT32 StartHeaderCRC;
diff --git a/DOC/7zip.nsi b/DOC/7zip.nsi
index d6c532b8..ec91560a 100755
--- a/DOC/7zip.nsi
+++ b/DOC/7zip.nsi
@@ -2,10 +2,30 @@
;Defines
!define VERSION_MAJOR 4
-!define VERSION_MINOR 24
+!define VERSION_MINOR 27
!define VERSION_POSTFIX_FULL " beta"
-!define NAME_FULL "7-Zip ${VERSION_MAJOR}.${VERSION_MINOR}${VERSION_POSTFIX_FULL}"
+!ifdef WIN64
+!ifdef IA64
+!define VERSION_SYS_POSTFIX_FULL " for Windows IA-64"
+!else
+!define VERSION_SYS_POSTFIX_FULL " for Windows x64"
+!endif
+!else
+!define VERSION_SYS_POSTFIX_FULL ""
+!endif
+!define NAME_FULL "7-Zip ${VERSION_MAJOR}.${VERSION_MINOR}${VERSION_POSTFIX_FULL}${VERSION_SYS_POSTFIX_FULL}"
!define VERSION_POSTFIX ""
+!ifdef WIN64
+!ifdef IA64
+!define VERSION_SYS_POSTFIX "-ia64"
+!else
+!define VERSION_SYS_POSTFIX "-x64"
+!endif
+!else
+!define VERSION_SYS_POSTFIX ""
+!endif
+
+
!define FM_LINK "7-Zip File Manager.lnk"
!define HELP_LINK "7-Zip Help.lnk"
@@ -23,7 +43,7 @@
;General
Name "${NAME_FULL}"
BrandingText "www.7-zip.org"
- OutFile "..\7z${VERSION_MAJOR}${VERSION_MINOR}${VERSION_POSTFIX}.exe"
+ OutFile "..\7z${VERSION_MAJOR}${VERSION_MINOR}${VERSION_POSTFIX}${VERSION_SYS_POSTFIX}.exe"
;Folder selection page
InstallDir "$PROGRAMFILES\7-Zip"
@@ -34,7 +54,11 @@
;Compressor
!ifndef NO_COMPRESSION
SetCompressor /SOLID lzma
+!ifdef IA64
+ SetCompressorDictSize 8
+!else
SetCompressorDictSize 4
+!endif
!else
SetCompressor zlib
SetCompress off
@@ -97,16 +121,22 @@ Section
File License.txt
File copying.txt
File readme.txt
+ !ifndef WIN64
File 7zip_pad.xml
+ !endif
# File 7-zip.dll
# File 7-zipn.dll
File 7zFM.exe
+ !ifndef WIN64
File 7zFMn.exe
+ !endif
File 7z.exe
File 7za.exe
File 7zg.exe
+ !ifndef WIN64
File 7zgn.exe
+ !endif
File 7z.sfx
File 7zCon.sfx
@@ -120,9 +150,11 @@ Section
File arj.dll
File bz2.dll
File cab.dll
+ File chm.dll
File cpio.dll
File deb.dll
File gz.dll
+ File lzh.dll
File rar.dll
File rpm.dll
File split.dll
@@ -172,6 +204,7 @@ Section
File hr.txt
File hu.txt
File id.txt
+ File io.txt
File it.txt
File ja.txt
File ka.txt
@@ -195,6 +228,7 @@ Section
File ta.txt
File th.txt
File tr.txt
+ File tt.txt
File uk.txt
File uz.txt
File va.txt
@@ -215,6 +249,13 @@ Section
SetShellVarContext all
+ !ifdef WIN64
+
+ !insertmacro InstallLib DLL NOTSHARED REBOOT_NOTPROTECTED 7-zip.dll $INSTDIR\7-zip.dll $INSTDIR
+ StrCpy "$MyDllPath" "7-zip.dll"
+
+ !else
+
StrCpy $0 0
System::Call "kernel32::GetVersion() i .r0"
IntCmpU $0 0x80000000 0 regNT 0
@@ -228,14 +269,22 @@ Section
StrCpy "$MyDllPath" "7-zipn.dll"
doneReg:
+ !endif
+
ClearErrors
# create start menu icons
SetOutPath $INSTDIR # working directory
CreateDirectory $SMPROGRAMS\7-Zip
+
+ !ifdef WIN64
+ StrCpy $1 ""
+ !else
StrCpy $1 "n"
IntCmpU $0 0x80000000 0 +2 0
StrCpy $1 ""
+ !endif
+
CreateShortcut "$SMPROGRAMS\7-Zip\${FM_LINK}" $INSTDIR\7zFM$1.exe
CreateShortcut "$SMPROGRAMS\7-Zip\${HELP_LINK}" $INSTDIR\7-zip.chm
@@ -270,8 +319,10 @@ Section
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\7zFM.exe" "" "$INSTDIR\7zFM.exe"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\7zFM.exe" "Path" "$INSTDIR"
+ !ifndef WIN64
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\7zFMn.exe" "" "$INSTDIR\7zFMn.exe"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\7zFMn.exe" "Path" "$INSTDIR"
+ !endif
# create uninstaller
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\7-Zip" "DisplayName" "${NAME_FULL}"
@@ -280,6 +331,10 @@ Section
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\7-Zip" "NoRepair" 1
WriteUninstaller $INSTDIR\Uninstall.exe
+ !ifdef WIN64
+ ExecWait 'regsvr32 /s "$INSTDIR\7-zip.dll"'
+ !endif
+
SectionEnd
@@ -310,13 +365,19 @@ Section "Uninstall"
Delete $INSTDIR\7zip_pad.xml
Delete /REBOOTOK $INSTDIR\7-zip.dll
+ !ifndef WIN64
Delete /REBOOTOK $INSTDIR\7-zipn.dll
+ !endif
Delete $INSTDIR\7zFM.exe
+ !ifndef WIN64
Delete $INSTDIR\7zFMn.exe
+ !endif
Delete $INSTDIR\7z.exe
Delete $INSTDIR\7za.exe
Delete $INSTDIR\7zg.exe
+ !ifndef WIN64
Delete $INSTDIR\7zgn.exe
+ !endif
Delete $INSTDIR\7z.sfx
Delete $INSTDIR\7zCon.sfx
@@ -328,9 +389,11 @@ Section "Uninstall"
Delete $INSTDIR\Formats\arj.dll
Delete $INSTDIR\Formats\bz2.dll
Delete $INSTDIR\Formats\cab.dll
+ Delete $INSTDIR\Formats\chm.dll
Delete $INSTDIR\Formats\cpio.dll
Delete $INSTDIR\Formats\deb.dll
Delete $INSTDIR\Formats\gz.dll
+ Delete $INSTDIR\Formats\lzh.dll
Delete $INSTDIR\Formats\rar.dll
Delete $INSTDIR\Formats\rpm.dll
Delete $INSTDIR\Formats\split.dll
@@ -380,6 +443,7 @@ Section "Uninstall"
Delete $INSTDIR\Lang\hr.txt
Delete $INSTDIR\Lang\hu.txt
Delete $INSTDIR\Lang\id.txt
+ Delete $INSTDIR\Lang\io.txt
Delete $INSTDIR\Lang\it.txt
Delete $INSTDIR\Lang\ja.txt
Delete $INSTDIR\Lang\ka.txt
@@ -403,6 +467,7 @@ Section "Uninstall"
Delete $INSTDIR\Lang\ta.txt
Delete $INSTDIR\Lang\th.txt
Delete $INSTDIR\Lang\tr.txt
+ Delete $INSTDIR\Lang\tt.txt
Delete $INSTDIR\Lang\uk.txt
Delete $INSTDIR\Lang\uz.txt
Delete $INSTDIR\Lang\va.txt
@@ -442,7 +507,9 @@ Section "Uninstall"
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\7-Zip"
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\7zFM.exe"
+ !ifndef WIN64
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\7zFMn.exe"
+ !endif
DeleteRegKey HKLM "Software\7-Zip"
DeleteRegKey HKCU "Software\7-Zip"
diff --git a/DOC/Methods.txt b/DOC/Methods.txt
index 593e911e..34e1a5a9 100755
--- a/DOC/Methods.txt
+++ b/DOC/Methods.txt
@@ -1,5 +1,5 @@
-Compression method IDs (4.16 beta)
-----------------------------------
+Compression method IDs (4.27)
+-----------------------------
Each compression method in 7z has unique binary value (ID).
The length of ID in bytes is arbitrary but it can not exceed 15 bytes.
@@ -59,9 +59,10 @@ List of defined IDs
04 - Arj
01 - Arj (1,2,3)
02 - Arj 4
- 05 - Lzh
-
- 07 - Reserved
+ 05 - Z
+ 06 - Lzh
+ 07 - Reserved for 7z
+ 08 - Cab
06 - Crypto
diff --git a/DOC/history.txt b/DOC/history.txt
index 3f340525..3944a491 100755
--- a/DOC/history.txt
+++ b/DOC/history.txt
@@ -1,6 +1,14 @@
Sources history of the 7-Zip
----------------------------
+ Version 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
+
+
Version 4.26 beta 2005-08-05
--------------------------------------
- MyAlloc(0)/BigAlloc(0) now return 0
diff --git a/DOC/lzma.txt b/DOC/lzma.txt
index b7816774..61119a27 100755
--- a/DOC/lzma.txt
+++ b/DOC/lzma.txt
@@ -1,7 +1,7 @@
-LZMA SDK 4.26
+LZMA SDK 4.27
-------------
-LZMA SDK 4.26 Copyright (C) 1999-2005 Igor Pavlov
+LZMA SDK 4.27 Copyright (C) 1999-2005 Igor Pavlov
LZMA SDK provides developers with documentation, source code,
and sample code necessary to write software that uses LZMA compression.
diff --git a/DOC/readme.txt b/DOC/readme.txt
index 3c883eca..72de51d2 100755
--- a/DOC/readme.txt
+++ b/DOC/readme.txt
@@ -1,4 +1,4 @@
-7-Zip 4.25 Sources
+7-Zip 4.27 Sources
------------------
7-Zip is a file archiver for Windows 95/98/ME/NT/2000/2003/XP.
@@ -9,6 +9,27 @@
License Info
------------
+Most of 7-Zip source code is under GNU LGPL.
+
+Files in folders
+ 7zip/Compress/Rar20
+ 7zip/Compress/Rar29
+ 7zip/Compress/Rar29/Original
+are licensed under "unRAR license + GNU LGPL" license.
+Source code files in all other folders of this package are under GNU LGPL.
+
+"unRAR license + GNU LGPL" means that you must follow
+GNU LGPL in all aspects while it is in agreement
+with unRAR license. But you can not break unRAR license rules.
+It means that unRAR license is main license in that pair.
+
+You can find unRAR license in file unrarLicense.txt
+You can find GNU LGPL license in file copying.txt
+
+
+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
@@ -24,6 +45,31 @@ License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+unRAR license + GNU LGPL Notes
+------------------------------
+
+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.
+
+
+7zip\Compress\Rar29\Original folder contains files that are modified
+versions of original unRAR source code files.
+
+
License notes
-------------
@@ -37,7 +83,7 @@ http://www.7-zip.org/support.html
Also this package contains files from LZMA SDK
you can download LZMA SDK from this page:
http://www.7-zip.org/sdk.html
-read about license for LZMA SDk in file
+read about addtional licenses for LZMA SDK in file
DOC/lzma.txt
@@ -58,18 +104,15 @@ Tools / Options / Directories
- Library files
-Also if you want to compile Original BZip2 code you must
-download BZip source to folder
-7zip/Compress/BZip2Original/Original
-You can find BZip2 sources from that page:
-http://sources.redhat.com/bzip2/index.html
+To compile 7-Zip for AMD64 and IA64 you need:
+ Windows Server 2003 SP1 Platform SDK from microsoft.com
Compiling under Unix/Linux
--------------------------
-If sizeof(wchar_t) == 4 in your compiler,
-you must use only 2 low bytes of wchar_t.
+Check this site for Posix/Linux version:
+http://sourceforge.net/projects/p7zip/
Notes:
@@ -94,6 +137,7 @@ DOC Documentation
---
7zFormat.txt - 7z format description
copying.txt - GNU LGPL license
+ unRarLicense.txt - License for unRAR part of source code
history.txt - Sources history
Methods.txt - Compression method IDs
readme.txt - Readme file
diff --git a/DOC/unRarLicense.txt b/DOC/unRarLicense.txt
new file mode 100755
index 00000000..5f78b728
--- /dev/null
+++ b/DOC/unRarLicense.txt
@@ -0,0 +1,41 @@
+ ****** ***** ****** 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.
+
+
+ Alexander L. Roshal \ No newline at end of file
diff --git a/Windows/Control/ListView.h b/Windows/Control/ListView.h
index 49a1e0ea..845a8945 100755
--- a/Windows/Control/ListView.h
+++ b/Windows/Control/ListView.h
@@ -38,7 +38,7 @@ public:
int GetItemCount() const
{ return ListView_GetItemCount(_window); }
- INT GetSelectionMark()
+ INT GetSelectionMark() const
{ return ListView_GetSelectionMark(_window); }
void SetItemCount(int numItems)
@@ -63,7 +63,7 @@ public:
void SetItemState(int index, UINT state, UINT mask)
{ ListView_SetItemState(_window, index, state, mask); }
- UINT GetItemState(int index, UINT mask)
+ UINT GetItemState(int index, UINT mask) const
{ return ListView_GetItemState(_window, index, mask); }
bool GetColumn(int columnIndex, LVCOLUMN* columnInfo) const
diff --git a/Windows/FileIO.cpp b/Windows/FileIO.cpp
index 67a2397b..f265f537 100755
--- a/Windows/FileIO.cpp
+++ b/Windows/FileIO.cpp
@@ -146,10 +146,40 @@ bool CInFile::Open(LPCWSTR fileName)
}
#endif
+// 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;
+ DWORD processedLoc = 0;
+ bool res = BOOLToBool(::ReadFile(_handle, data, size, &processedLoc, NULL));
+ processedSize = (UINT32)processedLoc;
+ return res;
+}
+
bool CInFile::Read(void *data, UINT32 size, UINT32 &processedSize)
{
- return BOOLToBool(::ReadFile(_handle, data, size,
- (DWORD *)&processedSize, NULL));
+ processedSize = 0;
+ do
+ {
+ UINT32 processedLoc = 0;
+ bool res = ReadPart(data, size, processedLoc);
+ processedSize += processedLoc;
+ if (!res)
+ return false;
+ if (processedLoc == 0)
+ return true;
+ data = (void *)((unsigned char *)data + processedLoc);
+ size -= processedLoc;
+ }
+ while (size > 0);
+ return true;
}
/////////////////////////
@@ -210,10 +240,33 @@ bool COutFile::SetLastWriteTime(const FILETIME *lastWriteTime)
return SetTime(NULL, NULL, lastWriteTime);
}
+bool COutFile::WritePart(const void *data, UINT32 size, UINT32 &processedSize)
+{
+ 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)
{
- return BOOLToBool(::WriteFile(_handle, data, size,
- (DWORD *)&processedSize, NULL));
+ processedSize = 0;
+ do
+ {
+ UINT32 processedLoc = 0;
+ bool res = WritePart(data, size, processedLoc);
+ processedSize += processedLoc;
+ if (!res)
+ return false;
+ if (processedLoc == 0)
+ return true;
+ data = (const void *)((const unsigned char *)data + processedLoc);
+ size -= processedLoc;
+ }
+ while (size > 0);
+ return true;
}
bool COutFile::SetEndOfFile()
diff --git a/Windows/FileIO.h b/Windows/FileIO.h
index 36f69df7..b4d8361d 100755
--- a/Windows/FileIO.h
+++ b/Windows/FileIO.h
@@ -60,6 +60,7 @@ public:
DWORD creationDisposition, DWORD flagsAndAttributes);
bool Open(LPCWSTR fileName);
#endif
+ bool ReadPart(void *data, UINT32 size, UINT32 &processedSize);
bool Read(void *data, UINT32 size, UINT32 &processedSize);
};
@@ -90,6 +91,7 @@ public:
bool SetTime(const FILETIME *creationTime,
const FILETIME *lastAccessTime, const FILETIME *lastWriteTime);
bool SetLastWriteTime(const FILETIME *lastWriteTime);
+ bool WritePart(const void *data, UINT32 size, UINT32 &processedSize);
bool Write(const void *data, UINT32 size, UINT32 &processedSize);
bool SetEndOfFile();
bool SetLength(UINT64 length);
diff --git a/Windows/PropVariant.cpp b/Windows/PropVariant.cpp
index 82d71457..48321bc2 100755
--- a/Windows/PropVariant.cpp
+++ b/Windows/PropVariant.cpp
@@ -142,7 +142,8 @@ CPropVariant& CPropVariant::operator=(Int16 value)
return *this;
}
-CPropVariant& CPropVariant::operator=(long value)
+/*
+CPropVariant& CPropVariant::operator=(LONG value)
{
if (vt != VT_I4)
{
@@ -152,6 +153,7 @@ CPropVariant& CPropVariant::operator=(long value)
lVal = value;
return *this;
}
+*/
static HRESULT MyPropVariantClear(PROPVARIANT *propVariant)
{
diff --git a/Windows/PropVariant.h b/Windows/PropVariant.h
index 548ed6fe..71035073 100755
--- a/Windows/PropVariant.h
+++ b/Windows/PropVariant.h
@@ -25,7 +25,7 @@ public:
CPropVariant(Int32 value) { vt = VT_I4; lVal = value; }
CPropVariant(Byte value) { vt = VT_UI1; bVal = value; }
CPropVariant(Int16 value) { vt = VT_I2; iVal = value; }
- CPropVariant(long value, VARTYPE vtSrc = VT_I4) { vt = vtSrc; lVal = value; }
+ // CPropVariant(LONG value, VARTYPE vtSrc = VT_I4) { vt = vtSrc; lVal = value; }
CPropVariant& operator=(const CPropVariant& varSrc);
CPropVariant& operator=(const PROPVARIANT& varSrc);
@@ -39,7 +39,7 @@ public:
CPropVariant& operator=(Int32 value);
CPropVariant& operator=(Byte value);
CPropVariant& operator=(Int16 value);
- CPropVariant& operator=(long value);
+ // CPropVariant& operator=(LONG value);
HRESULT Clear();
HRESULT Copy(const PROPVARIANT* pSrc);
diff --git a/Windows/PropVariantConversions.cpp b/Windows/PropVariantConversions.cpp
index f7743d6e..073eb069 100755
--- a/Windows/PropVariantConversions.cpp
+++ b/Windows/PropVariantConversions.cpp
@@ -6,14 +6,11 @@
#include "PropVariantConversions.h"
-#include "Windows/NationalTime.h"
#include "Windows/Defs.h"
#include "Common/StringConvert.h"
#include "Common/IntToString.h"
-using namespace NWindows;
-
static UString ConvertUInt64ToString(UInt64 value)
{
wchar_t buffer[32];