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
path: root/CPP/7zip
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/7zip')
-rwxr-xr-xCPP/7zip/Archive/7z/7z.dsp593
-rwxr-xr-xCPP/7zip/Archive/7z/7z.dsw29
-rwxr-xr-xCPP/7zip/Archive/7z/7z.icobin0 -> 4710 bytes
-rwxr-xr-xCPP/7zip/Archive/7z/7zCompressionMode.cpp3
-rwxr-xr-xCPP/7zip/Archive/7z/7zCompressionMode.h64
-rwxr-xr-xCPP/7zip/Archive/7z/7zDecode.cpp444
-rwxr-xr-xCPP/7zip/Archive/7z/7zDecode.h71
-rwxr-xr-xCPP/7zip/Archive/7z/7zEncode.cpp614
-rwxr-xr-xCPP/7zip/Archive/7z/7zEncode.h58
-rwxr-xr-xCPP/7zip/Archive/7z/7zExtract.cpp265
-rwxr-xr-xCPP/7zip/Archive/7z/7zFolderInStream.cpp129
-rwxr-xr-xCPP/7zip/Archive/7z/7zFolderInStream.h66
-rwxr-xr-xCPP/7zip/Archive/7z/7zFolderOutStream.cpp162
-rwxr-xr-xCPP/7zip/Archive/7z/7zFolderOutStream.h57
-rwxr-xr-xCPP/7zip/Archive/7z/7zHandler.cpp794
-rwxr-xr-xCPP/7zip/Archive/7z/7zHandler.h249
-rwxr-xr-xCPP/7zip/Archive/7z/7zHandlerOut.cpp1148
-rwxr-xr-xCPP/7zip/Archive/7z/7zHeader.cpp19
-rwxr-xr-xCPP/7zip/Archive/7z/7zHeader.h96
-rwxr-xr-xCPP/7zip/Archive/7z/7zIn.cpp1335
-rwxr-xr-xCPP/7zip/Archive/7z/7zIn.h288
-rwxr-xr-xCPP/7zip/Archive/7z/7zItem.h181
-rwxr-xr-xCPP/7zip/Archive/7z/7zMethodID.cpp76
-rwxr-xr-xCPP/7zip/Archive/7z/7zMethodID.h29
-rwxr-xr-xCPP/7zip/Archive/7z/7zMethods.cpp174
-rwxr-xr-xCPP/7zip/Archive/7z/7zMethods.h36
-rwxr-xr-xCPP/7zip/Archive/7z/7zOut.cpp1136
-rwxr-xr-xCPP/7zip/Archive/7z/7zOut.h192
-rwxr-xr-xCPP/7zip/Archive/7z/7zProperties.cpp166
-rwxr-xr-xCPP/7zip/Archive/7z/7zProperties.h22
-rwxr-xr-xCPP/7zip/Archive/7z/7zSpecStream.cpp24
-rwxr-xr-xCPP/7zip/Archive/7z/7zSpecStream.h35
-rwxr-xr-xCPP/7zip/Archive/7z/7zUpdate.cpp1099
-rwxr-xr-xCPP/7zip/Archive/7z/7zUpdate.h79
-rwxr-xr-xCPP/7zip/Archive/7z/DllExports.cpp113
-rwxr-xr-xCPP/7zip/Archive/7z/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Archive/7z/StdAfx.h9
-rwxr-xr-xCPP/7zip/Archive/7z/makefile89
-rwxr-xr-xCPP/7zip/Archive/7z/resource.rc5
-rwxr-xr-xCPP/7zip/Archive/Archive.def3
-rwxr-xr-xCPP/7zip/Archive/Arj/Arj.dsp329
-rwxr-xr-xCPP/7zip/Archive/Arj/Arj.dsw29
-rwxr-xr-xCPP/7zip/Archive/Arj/ArjHandler.cpp485
-rwxr-xr-xCPP/7zip/Archive/Arj/ArjHandler.h47
-rwxr-xr-xCPP/7zip/Archive/Arj/ArjHeader.h121
-rwxr-xr-xCPP/7zip/Archive/Arj/ArjIn.cpp283
-rwxr-xr-xCPP/7zip/Archive/Arj/ArjIn.h75
-rwxr-xr-xCPP/7zip/Archive/Arj/ArjItem.h75
-rwxr-xr-xCPP/7zip/Archive/Arj/DllExports.cpp72
-rwxr-xr-xCPP/7zip/Archive/Arj/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Archive/Arj/StdAfx.h8
-rwxr-xr-xCPP/7zip/Archive/Arj/arj.icobin0 -> 3638 bytes
-rwxr-xr-xCPP/7zip/Archive/Arj/makefile66
-rwxr-xr-xCPP/7zip/Archive/Arj/resource.rc5
-rwxr-xr-xCPP/7zip/Archive/BZip2/BZip2.dsp281
-rwxr-xr-xCPP/7zip/Archive/BZip2/BZip2.dsw29
-rwxr-xr-xCPP/7zip/Archive/BZip2/BZip2Handler.cpp287
-rwxr-xr-xCPP/7zip/Archive/BZip2/BZip2Handler.h83
-rwxr-xr-xCPP/7zip/Archive/BZip2/BZip2HandlerOut.cpp156
-rwxr-xr-xCPP/7zip/Archive/BZip2/BZip2Item.h20
-rwxr-xr-xCPP/7zip/Archive/BZip2/BZip2Update.cpp84
-rwxr-xr-xCPP/7zip/Archive/BZip2/BZip2Update.h24
-rwxr-xr-xCPP/7zip/Archive/BZip2/DllExports.cpp127
-rwxr-xr-xCPP/7zip/Archive/BZip2/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Archive/BZip2/StdAfx.h8
-rwxr-xr-xCPP/7zip/Archive/BZip2/bz2.icobin0 -> 3638 bytes
-rwxr-xr-xCPP/7zip/Archive/BZip2/makefile55
-rwxr-xr-xCPP/7zip/Archive/BZip2/resource.rc5
-rwxr-xr-xCPP/7zip/Archive/Cab/Cab.dsp395
-rwxr-xr-xCPP/7zip/Archive/Cab/Cab.dsw29
-rwxr-xr-xCPP/7zip/Archive/Cab/CabBlockInStream.cpp194
-rwxr-xr-xCPP/7zip/Archive/Cab/CabBlockInStream.h56
-rwxr-xr-xCPP/7zip/Archive/Cab/CabHandler.cpp812
-rwxr-xr-xCPP/7zip/Archive/Cab/CabHandler.h45
-rwxr-xr-xCPP/7zip/Archive/Cab/CabHeader.cpp19
-rwxr-xr-xCPP/7zip/Archive/Cab/CabHeader.h42
-rwxr-xr-xCPP/7zip/Archive/Cab/CabIn.cpp343
-rwxr-xr-xCPP/7zip/Archive/Cab/CabIn.h166
-rwxr-xr-xCPP/7zip/Archive/Cab/CabItem.h62
-rwxr-xr-xCPP/7zip/Archive/Cab/DllExports.cpp72
-rwxr-xr-xCPP/7zip/Archive/Cab/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Archive/Cab/StdAfx.h8
-rwxr-xr-xCPP/7zip/Archive/Cab/cab.icobin0 -> 3638 bytes
-rwxr-xr-xCPP/7zip/Archive/Cab/makefile70
-rwxr-xr-xCPP/7zip/Archive/Cab/resource.rc5
-rwxr-xr-xCPP/7zip/Archive/Chm/Chm.dsp337
-rwxr-xr-xCPP/7zip/Archive/Chm/Chm.dsw29
-rwxr-xr-xCPP/7zip/Archive/Chm/ChmHandler.cpp731
-rwxr-xr-xCPP/7zip/Archive/Chm/ChmHandler.h46
-rwxr-xr-xCPP/7zip/Archive/Chm/ChmHeader.cpp24
-rwxr-xr-xCPP/7zip/Archive/Chm/ChmHeader.h28
-rwxr-xr-xCPP/7zip/Archive/Chm/ChmIn.cpp925
-rwxr-xr-xCPP/7zip/Archive/Chm/ChmIn.h242
-rwxr-xr-xCPP/7zip/Archive/Chm/DllExports.cpp77
-rwxr-xr-xCPP/7zip/Archive/Chm/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Archive/Chm/StdAfx.h8
-rwxr-xr-xCPP/7zip/Archive/Chm/makefile68
-rwxr-xr-xCPP/7zip/Archive/Chm/resource.rc3
-rwxr-xr-xCPP/7zip/Archive/Common/CodecsPath.cpp34
-rwxr-xr-xCPP/7zip/Archive/Common/CodecsPath.h12
-rwxr-xr-xCPP/7zip/Archive/Common/CoderLoader.cpp31
-rwxr-xr-xCPP/7zip/Archive/Common/CoderLoader.h147
-rwxr-xr-xCPP/7zip/Archive/Common/CoderMixer2.cpp121
-rwxr-xr-xCPP/7zip/Archive/Common/CoderMixer2.h168
-rwxr-xr-xCPP/7zip/Archive/Common/CoderMixer2MT.cpp359
-rwxr-xr-xCPP/7zip/Archive/Common/CoderMixer2MT.h121
-rwxr-xr-xCPP/7zip/Archive/Common/CoderMixer2ST.cpp238
-rwxr-xr-xCPP/7zip/Archive/Common/CoderMixer2ST.h88
-rwxr-xr-xCPP/7zip/Archive/Common/CrossThreadProgress.cpp15
-rwxr-xr-xCPP/7zip/Archive/Common/CrossThreadProgress.h31
-rwxr-xr-xCPP/7zip/Archive/Common/DummyOutStream.cpp20
-rwxr-xr-xCPP/7zip/Archive/Common/DummyOutStream.h23
-rwxr-xr-xCPP/7zip/Archive/Common/FilterCoder.cpp243
-rwxr-xr-xCPP/7zip/Archive/Common/FilterCoder.h130
-rwxr-xr-xCPP/7zip/Archive/Common/InStreamWithCRC.cpp41
-rwxr-xr-xCPP/7zip/Archive/Common/InStreamWithCRC.h65
-rwxr-xr-xCPP/7zip/Archive/Common/ItemNameUtils.cpp59
-rwxr-xr-xCPP/7zip/Archive/Common/ItemNameUtils.h24
-rwxr-xr-xCPP/7zip/Archive/Common/MultiStream.cpp201
-rwxr-xr-xCPP/7zip/Archive/Common/MultiStream.h76
-rwxr-xr-xCPP/7zip/Archive/Common/OutStreamWithCRC.cpp24
-rwxr-xr-xCPP/7zip/Archive/Common/OutStreamWithCRC.h37
-rwxr-xr-xCPP/7zip/Archive/Common/ParseProperties.cpp171
-rwxr-xr-xCPP/7zip/Archive/Common/ParseProperties.h17
-rwxr-xr-xCPP/7zip/Archive/Common/StdAfx.h9
-rwxr-xr-xCPP/7zip/Archive/Cpio/CpioHandler.cpp289
-rwxr-xr-xCPP/7zip/Archive/Cpio/CpioHandler.h47
-rwxr-xr-xCPP/7zip/Archive/Cpio/CpioHeader.cpp23
-rwxr-xr-xCPP/7zip/Archive/Cpio/CpioHeader.h70
-rwxr-xr-xCPP/7zip/Archive/Cpio/CpioIn.cpp271
-rwxr-xr-xCPP/7zip/Archive/Cpio/CpioIn.h41
-rwxr-xr-xCPP/7zip/Archive/Cpio/CpioItem.h55
-rwxr-xr-xCPP/7zip/Archive/Cpio/DllExports.cpp65
-rwxr-xr-xCPP/7zip/Archive/Cpio/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Archive/Cpio/StdAfx.h8
-rwxr-xr-xCPP/7zip/Archive/Cpio/cpio.dsp265
-rwxr-xr-xCPP/7zip/Archive/Cpio/cpio.dsw29
-rwxr-xr-xCPP/7zip/Archive/Cpio/cpio.icobin0 -> 3638 bytes
-rwxr-xr-xCPP/7zip/Archive/Cpio/makefile55
-rwxr-xr-xCPP/7zip/Archive/Cpio/resource.rc5
-rwxr-xr-xCPP/7zip/Archive/Deb/Deb.dsp269
-rwxr-xr-xCPP/7zip/Archive/Deb/Deb.dsw29
-rwxr-xr-xCPP/7zip/Archive/Deb/DebHandler.cpp255
-rwxr-xr-xCPP/7zip/Archive/Deb/DebHandler.h47
-rwxr-xr-xCPP/7zip/Archive/Deb/DebHeader.cpp13
-rwxr-xr-xCPP/7zip/Archive/Deb/DebHeader.h38
-rwxr-xr-xCPP/7zip/Archive/Deb/DebIn.cpp165
-rwxr-xr-xCPP/7zip/Archive/Deb/DebIn.h29
-rwxr-xr-xCPP/7zip/Archive/Deb/DebItem.h32
-rwxr-xr-xCPP/7zip/Archive/Deb/DllExports.cpp73
-rwxr-xr-xCPP/7zip/Archive/Deb/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Archive/Deb/StdAfx.h8
-rwxr-xr-xCPP/7zip/Archive/Deb/deb.icobin0 -> 3638 bytes
-rwxr-xr-xCPP/7zip/Archive/Deb/makefile54
-rwxr-xr-xCPP/7zip/Archive/Deb/resource.rc5
-rwxr-xr-xCPP/7zip/Archive/GZip/DllExports.cpp125
-rwxr-xr-xCPP/7zip/Archive/GZip/GZip.dsp321
-rwxr-xr-xCPP/7zip/Archive/GZip/GZip.dsw29
-rwxr-xr-xCPP/7zip/Archive/GZip/GZipHandler.cpp361
-rwxr-xr-xCPP/7zip/Archive/GZip/GZipHandler.h79
-rwxr-xr-xCPP/7zip/Archive/GZip/GZipHandlerOut.cpp200
-rwxr-xr-xCPP/7zip/Archive/GZip/GZipHeader.cpp20
-rwxr-xr-xCPP/7zip/Archive/GZip/GZipHeader.h85
-rwxr-xr-xCPP/7zip/Archive/GZip/GZipIn.cpp121
-rwxr-xr-xCPP/7zip/Archive/GZip/GZipIn.h31
-rwxr-xr-xCPP/7zip/Archive/GZip/GZipItem.h59
-rwxr-xr-xCPP/7zip/Archive/GZip/GZipOut.cpp69
-rwxr-xr-xCPP/7zip/Archive/GZip/GZipOut.h29
-rwxr-xr-xCPP/7zip/Archive/GZip/GZipUpdate.cpp120
-rwxr-xr-xCPP/7zip/Archive/GZip/GZipUpdate.h32
-rwxr-xr-xCPP/7zip/Archive/GZip/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Archive/GZip/StdAfx.h8
-rwxr-xr-xCPP/7zip/Archive/GZip/gz.icobin0 -> 3638 bytes
-rwxr-xr-xCPP/7zip/Archive/GZip/makefile60
-rwxr-xr-xCPP/7zip/Archive/GZip/resource.rc5
-rwxr-xr-xCPP/7zip/Archive/IArchive.h173
-rwxr-xr-xCPP/7zip/Archive/Iso/DllExports.cpp88
-rwxr-xr-xCPP/7zip/Archive/Iso/Iso.dsp273
-rwxr-xr-xCPP/7zip/Archive/Iso/Iso.dsw29
-rwxr-xr-xCPP/7zip/Archive/Iso/Iso.icobin0 -> 3638 bytes
-rwxr-xr-xCPP/7zip/Archive/Iso/IsoHandler.cpp301
-rwxr-xr-xCPP/7zip/Archive/Iso/IsoHandler.h59
-rwxr-xr-xCPP/7zip/Archive/Iso/IsoHeader.cpp21
-rwxr-xr-xCPP/7zip/Archive/Iso/IsoHeader.h61
-rwxr-xr-xCPP/7zip/Archive/Iso/IsoIn.cpp438
-rwxr-xr-xCPP/7zip/Archive/Iso/IsoIn.h301
-rwxr-xr-xCPP/7zip/Archive/Iso/IsoItem.h145
-rwxr-xr-xCPP/7zip/Archive/Iso/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Archive/Iso/StdAfx.h9
-rwxr-xr-xCPP/7zip/Archive/Iso/makefile55
-rwxr-xr-xCPP/7zip/Archive/Iso/resource.rc5
-rwxr-xr-xCPP/7zip/Archive/Lzh/DllExports.cpp72
-rwxr-xr-xCPP/7zip/Archive/Lzh/Lzh.def7
-rwxr-xr-xCPP/7zip/Archive/Lzh/Lzh.dsp333
-rwxr-xr-xCPP/7zip/Archive/Lzh/Lzh.dsw29
-rwxr-xr-xCPP/7zip/Archive/Lzh/LzhCRC.cpp43
-rwxr-xr-xCPP/7zip/Archive/Lzh/LzhCRC.h27
-rwxr-xr-xCPP/7zip/Archive/Lzh/LzhHandler.cpp464
-rwxr-xr-xCPP/7zip/Archive/Lzh/LzhHandler.h47
-rwxr-xr-xCPP/7zip/Archive/Lzh/LzhHeader.h19
-rwxr-xr-xCPP/7zip/Archive/Lzh/LzhIn.cpp171
-rwxr-xr-xCPP/7zip/Archive/Lzh/LzhIn.h29
-rwxr-xr-xCPP/7zip/Archive/Lzh/LzhItem.h172
-rwxr-xr-xCPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp27
-rwxr-xr-xCPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.h38
-rwxr-xr-xCPP/7zip/Archive/Lzh/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Archive/Lzh/StdAfx.h8
-rwxr-xr-xCPP/7zip/Archive/Lzh/lzh.icobin0 -> 3638 bytes
-rwxr-xr-xCPP/7zip/Archive/Lzh/makefile65
-rwxr-xr-xCPP/7zip/Archive/Lzh/resource.rc5
-rwxr-xr-xCPP/7zip/Archive/Nsis/DllExports.cpp110
-rwxr-xr-xCPP/7zip/Archive/Nsis/Nsis.dsp337
-rwxr-xr-xCPP/7zip/Archive/Nsis/Nsis.dsw29
-rwxr-xr-xCPP/7zip/Archive/Nsis/NsisDecode.cpp150
-rwxr-xr-xCPP/7zip/Archive/Nsis/NsisDecode.h47
-rwxr-xr-xCPP/7zip/Archive/Nsis/NsisHandler.cpp484
-rwxr-xr-xCPP/7zip/Archive/Nsis/NsisHandler.h41
-rwxr-xr-xCPP/7zip/Archive/Nsis/NsisIn.cpp1169
-rwxr-xr-xCPP/7zip/Archive/Nsis/NsisIn.h166
-rwxr-xr-xCPP/7zip/Archive/Nsis/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Archive/Nsis/StdAfx.h9
-rwxr-xr-xCPP/7zip/Archive/Nsis/makefile67
-rwxr-xr-xCPP/7zip/Archive/Nsis/resource.rc3
-rwxr-xr-xCPP/7zip/Archive/RPM/DllExports.cpp68
-rwxr-xr-xCPP/7zip/Archive/RPM/Rpm.dsp205
-rwxr-xr-xCPP/7zip/Archive/RPM/Rpm.dsw29
-rwxr-xr-xCPP/7zip/Archive/RPM/RpmHandler.cpp194
-rwxr-xr-xCPP/7zip/Archive/RPM/RpmHandler.h46
-rwxr-xr-xCPP/7zip/Archive/RPM/RpmHeader.h63
-rwxr-xr-xCPP/7zip/Archive/RPM/RpmIn.cpp112
-rwxr-xr-xCPP/7zip/Archive/RPM/RpmIn.h15
-rwxr-xr-xCPP/7zip/Archive/RPM/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Archive/RPM/StdAfx.h8
-rwxr-xr-xCPP/7zip/Archive/RPM/makefile42
-rwxr-xr-xCPP/7zip/Archive/RPM/resource.rc5
-rwxr-xr-xCPP/7zip/Archive/RPM/rpm.icobin0 -> 3638 bytes
-rwxr-xr-xCPP/7zip/Archive/Rar/DllExports.cpp142
-rwxr-xr-xCPP/7zip/Archive/Rar/Rar.dsp459
-rwxr-xr-xCPP/7zip/Archive/Rar/Rar.dsw29
-rwxr-xr-xCPP/7zip/Archive/Rar/RarHandler.cpp941
-rwxr-xr-xCPP/7zip/Archive/Rar/RarHandler.h63
-rwxr-xr-xCPP/7zip/Archive/Rar/RarHeader.cpp21
-rwxr-xr-xCPP/7zip/Archive/Rar/RarHeader.h224
-rwxr-xr-xCPP/7zip/Archive/Rar/RarIn.cpp535
-rwxr-xr-xCPP/7zip/Archive/Rar/RarIn.h124
-rwxr-xr-xCPP/7zip/Archive/Rar/RarItem.cpp118
-rwxr-xr-xCPP/7zip/Archive/Rar/RarItem.h91
-rwxr-xr-xCPP/7zip/Archive/Rar/RarVolumeInStream.cpp79
-rwxr-xr-xCPP/7zip/Archive/Rar/RarVolumeInStream.h50
-rwxr-xr-xCPP/7zip/Archive/Rar/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Archive/Rar/StdAfx.h8
-rwxr-xr-xCPP/7zip/Archive/Rar/makefile90
-rwxr-xr-xCPP/7zip/Archive/Rar/rar.icobin0 -> 3638 bytes
-rwxr-xr-xCPP/7zip/Archive/Rar/resource.rc5
-rwxr-xr-xCPP/7zip/Archive/Split/DllExports.cpp65
-rwxr-xr-xCPP/7zip/Archive/Split/Split.dsp237
-rwxr-xr-xCPP/7zip/Archive/Split/Split.dsw29
-rwxr-xr-xCPP/7zip/Archive/Split/Split.icobin0 -> 3638 bytes
-rwxr-xr-xCPP/7zip/Archive/Split/SplitHandler.cpp415
-rwxr-xr-xCPP/7zip/Archive/Split/SplitHandler.h62
-rwxr-xr-xCPP/7zip/Archive/Split/SplitHandlerOut.cpp102
-rwxr-xr-xCPP/7zip/Archive/Split/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Archive/Split/StdAfx.h8
-rwxr-xr-xCPP/7zip/Archive/Split/makefile51
-rwxr-xr-xCPP/7zip/Archive/Split/resource.rc5
-rwxr-xr-xCPP/7zip/Archive/Tar/DllExports.cpp86
-rwxr-xr-xCPP/7zip/Archive/Tar/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Archive/Tar/StdAfx.h9
-rwxr-xr-xCPP/7zip/Archive/Tar/Tar.dsp297
-rwxr-xr-xCPP/7zip/Archive/Tar/Tar.dsw29
-rwxr-xr-xCPP/7zip/Archive/Tar/TarHandler.cpp282
-rwxr-xr-xCPP/7zip/Archive/Tar/TarHandler.h56
-rwxr-xr-xCPP/7zip/Archive/Tar/TarHandlerOut.cpp126
-rwxr-xr-xCPP/7zip/Archive/Tar/TarHeader.cpp25
-rwxr-xr-xCPP/7zip/Archive/Tar/TarHeader.h99
-rwxr-xr-xCPP/7zip/Archive/Tar/TarIn.cpp248
-rwxr-xr-xCPP/7zip/Archive/Tar/TarIn.h30
-rwxr-xr-xCPP/7zip/Archive/Tar/TarItem.h69
-rwxr-xr-xCPP/7zip/Archive/Tar/TarOut.cpp191
-rwxr-xr-xCPP/7zip/Archive/Tar/TarOut.h28
-rwxr-xr-xCPP/7zip/Archive/Tar/TarUpdate.cpp162
-rwxr-xr-xCPP/7zip/Archive/Tar/TarUpdate.h36
-rwxr-xr-xCPP/7zip/Archive/Tar/makefile59
-rwxr-xr-xCPP/7zip/Archive/Tar/resource.rc5
-rwxr-xr-xCPP/7zip/Archive/Tar/tar.icobin0 -> 3638 bytes
-rwxr-xr-xCPP/7zip/Archive/Z/DllExports.cpp91
-rwxr-xr-xCPP/7zip/Archive/Z/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Archive/Z/StdAfx.h8
-rwxr-xr-xCPP/7zip/Archive/Z/Z.dsp237
-rwxr-xr-xCPP/7zip/Archive/Z/Z.dsw29
-rwxr-xr-xCPP/7zip/Archive/Z/Z.icobin0 -> 3638 bytes
-rwxr-xr-xCPP/7zip/Archive/Z/ZHandler.cpp202
-rwxr-xr-xCPP/7zip/Archive/Z/ZHandler.h47
-rwxr-xr-xCPP/7zip/Archive/Z/makefile52
-rwxr-xr-xCPP/7zip/Archive/Z/resource.rc5
-rwxr-xr-xCPP/7zip/Archive/Zip/DllExports.cpp152
-rwxr-xr-xCPP/7zip/Archive/Zip/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Archive/Zip/StdAfx.h8
-rwxr-xr-xCPP/7zip/Archive/Zip/Zip.dsp651
-rwxr-xr-xCPP/7zip/Archive/Zip/Zip.dsw29
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipAddCommon.cpp309
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipAddCommon.h58
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipCompressionMode.h39
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipHandler.cpp766
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipHandler.h100
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipHandlerOut.cpp393
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipHeader.cpp36
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipHeader.h248
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipIn.cpp797
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipIn.h111
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipItem.cpp137
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipItem.h191
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipItemEx.h29
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipOut.cpp259
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipOut.h51
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipUpdate.cpp734
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipUpdate.h52
-rwxr-xr-xCPP/7zip/Archive/Zip/makefile124
-rwxr-xr-xCPP/7zip/Archive/Zip/resource.rc5
-rwxr-xr-xCPP/7zip/Archive/Zip/zip.icobin0 -> 3638 bytes
-rwxr-xr-xCPP/7zip/Archive/makefile23
-rwxr-xr-xCPP/7zip/Bundles/Alone/Alone.dsp2301
-rwxr-xr-xCPP/7zip/Bundles/Alone/Alone.dsw29
-rwxr-xr-xCPP/7zip/Bundles/Alone/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Bundles/Alone/StdAfx.h9
-rwxr-xr-xCPP/7zip/Bundles/Alone/afxres.h1
-rwxr-xr-xCPP/7zip/Bundles/Alone/makefile390
-rwxr-xr-xCPP/7zip/Bundles/Alone/resource.rc3
-rwxr-xr-xCPP/7zip/Bundles/Alone7z/Alone.dsp1358
-rwxr-xr-xCPP/7zip/Bundles/Alone7z/Alone.dsw29
-rwxr-xr-xCPP/7zip/Bundles/Alone7z/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Bundles/Alone7z/StdAfx.h9
-rwxr-xr-xCPP/7zip/Bundles/Alone7z/makefile196
-rwxr-xr-xCPP/7zip/Bundles/Alone7z/resource.rc3
-rwxr-xr-xCPP/7zip/Bundles/Format7z/Format7z.dsp1006
-rwxr-xr-xCPP/7zip/Bundles/Format7z/Format7z.dsw29
-rwxr-xr-xCPP/7zip/Bundles/Format7z/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Bundles/Format7z/StdAfx.h9
-rwxr-xr-xCPP/7zip/Bundles/Format7z/makefile201
-rwxr-xr-xCPP/7zip/Bundles/Format7z/resource.rc5
-rwxr-xr-xCPP/7zip/Bundles/Format7zExtract/Format7z.dsp813
-rwxr-xr-xCPP/7zip/Bundles/Format7zExtract/Format7z.dsw29
-rwxr-xr-xCPP/7zip/Bundles/Format7zExtract/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Bundles/Format7zExtract/StdAfx.h9
-rwxr-xr-xCPP/7zip/Bundles/Format7zExtract/makefile174
-rwxr-xr-xCPP/7zip/Bundles/Format7zExtract/resource.rc5
-rwxr-xr-xCPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Bundles/Format7zExtractR/StdAfx.h9
-rwxr-xr-xCPP/7zip/Bundles/Format7zExtractR/makefile117
-rwxr-xr-xCPP/7zip/Bundles/Format7zExtractR/resource.rc5
-rwxr-xr-xCPP/7zip/Bundles/Format7zR/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Bundles/Format7zR/StdAfx.h9
-rwxr-xr-xCPP/7zip/Bundles/Format7zR/makefile150
-rwxr-xr-xCPP/7zip/Bundles/Format7zR/resource.rc5
-rwxr-xr-xCPP/7zip/Bundles/SFXCon/7z.icobin0 -> 1078 bytes
-rwxr-xr-xCPP/7zip/Bundles/SFXCon/Main.cpp416
-rwxr-xr-xCPP/7zip/Bundles/SFXCon/SFXCon.dsp759
-rwxr-xr-xCPP/7zip/Bundles/SFXCon/SFXCon.dsw29
-rwxr-xr-xCPP/7zip/Bundles/SFXCon/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Bundles/SFXCon/StdAfx.h9
-rwxr-xr-xCPP/7zip/Bundles/SFXCon/makefile180
-rwxr-xr-xCPP/7zip/Bundles/SFXCon/resource.rc5
-rwxr-xr-xCPP/7zip/Bundles/SFXSetup/ExtractCallback.cpp249
-rwxr-xr-xCPP/7zip/Bundles/SFXSetup/ExtractCallback.h96
-rwxr-xr-xCPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp139
-rwxr-xr-xCPP/7zip/Bundles/SFXSetup/ExtractEngine.h17
-rwxr-xr-xCPP/7zip/Bundles/SFXSetup/Main.cpp335
-rwxr-xr-xCPP/7zip/Bundles/SFXSetup/SFXSetup.dsp696
-rwxr-xr-xCPP/7zip/Bundles/SFXSetup/SFXSetup.dsw29
-rwxr-xr-xCPP/7zip/Bundles/SFXSetup/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Bundles/SFXSetup/StdAfx.h10
-rwxr-xr-xCPP/7zip/Bundles/SFXSetup/makefile156
-rwxr-xr-xCPP/7zip/Bundles/SFXSetup/resource.h6
-rwxr-xr-xCPP/7zip/Bundles/SFXSetup/resource.rc16
-rwxr-xr-xCPP/7zip/Bundles/SFXSetup/setup.icobin0 -> 1078 bytes
-rwxr-xr-xCPP/7zip/Bundles/SFXWin/7z.icobin0 -> 1078 bytes
-rwxr-xr-xCPP/7zip/Bundles/SFXWin/Main.cpp115
-rwxr-xr-xCPP/7zip/Bundles/SFXWin/SFXWin.dsp847
-rwxr-xr-xCPP/7zip/Bundles/SFXWin/SFXWin.dsw29
-rwxr-xr-xCPP/7zip/Bundles/SFXWin/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Bundles/SFXWin/StdAfx.h12
-rwxr-xr-xCPP/7zip/Bundles/SFXWin/makefile207
-rwxr-xr-xCPP/7zip/Bundles/SFXWin/resource.h7
-rwxr-xr-xCPP/7zip/Bundles/SFXWin/resource.rc34
-rwxr-xr-xCPP/7zip/Bundles/makefile15
-rwxr-xr-xCPP/7zip/Common/FilePathAutoRename.cpp57
-rwxr-xr-xCPP/7zip/Common/FilePathAutoRename.h10
-rwxr-xr-xCPP/7zip/Common/FileStreams.cpp251
-rwxr-xr-xCPP/7zip/Common/FileStreams.h98
-rwxr-xr-xCPP/7zip/Common/InBuffer.cpp80
-rwxr-xr-xCPP/7zip/Common/InBuffer.h76
-rwxr-xr-xCPP/7zip/Common/InMemStream.cpp222
-rwxr-xr-xCPP/7zip/Common/InMemStream.h282
-rwxr-xr-xCPP/7zip/Common/InOutTempBuffer.cpp122
-rwxr-xr-xCPP/7zip/Common/InOutTempBuffer.h55
-rwxr-xr-xCPP/7zip/Common/LSBFDecoder.cpp27
-rwxr-xr-xCPP/7zip/Common/LSBFDecoder.h127
-rwxr-xr-xCPP/7zip/Common/LSBFEncoder.cpp29
-rwxr-xr-xCPP/7zip/Common/LSBFEncoder.h51
-rwxr-xr-xCPP/7zip/Common/LimitedStreams.cpp24
-rwxr-xr-xCPP/7zip/Common/LimitedStreams.h33
-rwxr-xr-xCPP/7zip/Common/LockedStream.cpp23
-rwxr-xr-xCPP/7zip/Common/LockedStream.h38
-rwxr-xr-xCPP/7zip/Common/MSBFDecoder.h69
-rwxr-xr-xCPP/7zip/Common/MSBFEncoder.h59
-rwxr-xr-xCPP/7zip/Common/MemBlocks.cpp184
-rwxr-xr-xCPP/7zip/Common/MemBlocks.h73
-rwxr-xr-xCPP/7zip/Common/OffsetStream.cpp35
-rwxr-xr-xCPP/7zip/Common/OffsetStream.h25
-rwxr-xr-xCPP/7zip/Common/OutBuffer.cpp116
-rwxr-xr-xCPP/7zip/Common/OutBuffer.h64
-rwxr-xr-xCPP/7zip/Common/OutMemStream.cpp137
-rwxr-xr-xCPP/7zip/Common/OutMemStream.h88
-rwxr-xr-xCPP/7zip/Common/ProgressMt.cpp53
-rwxr-xr-xCPP/7zip/Common/ProgressMt.h47
-rwxr-xr-xCPP/7zip/Common/ProgressUtils.cpp55
-rwxr-xr-xCPP/7zip/Common/ProgressUtils.h43
-rwxr-xr-xCPP/7zip/Common/StdAfx.h9
-rwxr-xr-xCPP/7zip/Common/StreamBinder.cpp162
-rwxr-xr-xCPP/7zip/Common/StreamBinder.h37
-rwxr-xr-xCPP/7zip/Common/StreamObjects.cpp68
-rwxr-xr-xCPP/7zip/Common/StreamObjects.h117
-rwxr-xr-xCPP/7zip/Common/StreamUtils.cpp44
-rwxr-xr-xCPP/7zip/Common/StreamUtils.h11
-rwxr-xr-xCPP/7zip/Compress/Arj/ArjDecoder1.cpp319
-rwxr-xr-xCPP/7zip/Compress/Arj/ArjDecoder1.h105
-rwxr-xr-xCPP/7zip/Compress/Arj/ArjDecoder2.cpp93
-rwxr-xr-xCPP/7zip/Compress/Arj/ArjDecoder2.h65
-rwxr-xr-xCPP/7zip/Compress/Arj/StdAfx.h8
-rwxr-xr-xCPP/7zip/Compress/BWT/BlockSort.cpp487
-rwxr-xr-xCPP/7zip/Compress/BWT/BlockSort.h21
-rwxr-xr-xCPP/7zip/Compress/BWT/Mtf8.h195
-rwxr-xr-xCPP/7zip/Compress/BWT/StdAfx.h6
-rwxr-xr-xCPP/7zip/Compress/BZip2/BZip2.dsp303
-rwxr-xr-xCPP/7zip/Compress/BZip2/BZip2.dsw29
-rwxr-xr-xCPP/7zip/Compress/BZip2/BZip2CRC.cpp26
-rwxr-xr-xCPP/7zip/Compress/BZip2/BZip2CRC.h31
-rwxr-xr-xCPP/7zip/Compress/BZip2/BZip2Const.h54
-rwxr-xr-xCPP/7zip/Compress/BZip2/BZip2Decoder.cpp770
-rwxr-xr-xCPP/7zip/Compress/BZip2/BZip2Decoder.h164
-rwxr-xr-xCPP/7zip/Compress/BZip2/BZip2Encoder.cpp883
-rwxr-xr-xCPP/7zip/Compress/BZip2/BZip2Encoder.h246
-rwxr-xr-xCPP/7zip/Compress/BZip2/DllExports.cpp93
-rwxr-xr-xCPP/7zip/Compress/BZip2/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Compress/BZip2/StdAfx.h8
-rwxr-xr-xCPP/7zip/Compress/BZip2/makefile56
-rwxr-xr-xCPP/7zip/Compress/BZip2/resource.rc3
-rwxr-xr-xCPP/7zip/Compress/BZip2Original/BZip2Decoder.cpp131
-rwxr-xr-xCPP/7zip/Compress/BZip2Original/BZip2Decoder.h38
-rwxr-xr-xCPP/7zip/Compress/BZip2Original/BZip2Encoder.cpp120
-rwxr-xr-xCPP/7zip/Compress/BZip2Original/BZip2Encoder.h30
-rwxr-xr-xCPP/7zip/Compress/BZip2Original/BZip2Error.cpp10
-rwxr-xr-xCPP/7zip/Compress/BZip2Original/DllExports.cpp86
-rwxr-xr-xCPP/7zip/Compress/BZip2Original/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Compress/BZip2Original/StdAfx.h8
-rwxr-xr-xCPP/7zip/Compress/Branch/ARM.cpp16
-rwxr-xr-xCPP/7zip/Compress/Branch/ARM.h10
-rwxr-xr-xCPP/7zip/Compress/Branch/ARMThumb.cpp16
-rwxr-xr-xCPP/7zip/Compress/Branch/ARMThumb.h10
-rwxr-xr-xCPP/7zip/Compress/Branch/Branch.dsp298
-rwxr-xr-xCPP/7zip/Compress/Branch/Branch.dsw29
-rwxr-xr-xCPP/7zip/Compress/Branch/BranchCoder.cpp18
-rwxr-xr-xCPP/7zip/Compress/Branch/BranchCoder.h54
-rwxr-xr-xCPP/7zip/Compress/Branch/DllExports.cpp152
-rwxr-xr-xCPP/7zip/Compress/Branch/IA64.cpp16
-rwxr-xr-xCPP/7zip/Compress/Branch/IA64.h10
-rwxr-xr-xCPP/7zip/Compress/Branch/PPC.cpp17
-rwxr-xr-xCPP/7zip/Compress/Branch/PPC.h10
-rwxr-xr-xCPP/7zip/Compress/Branch/SPARC.cpp17
-rwxr-xr-xCPP/7zip/Compress/Branch/SPARC.h10
-rwxr-xr-xCPP/7zip/Compress/Branch/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Compress/Branch/StdAfx.h8
-rwxr-xr-xCPP/7zip/Compress/Branch/makefile48
-rwxr-xr-xCPP/7zip/Compress/Branch/resource.rc3
-rwxr-xr-xCPP/7zip/Compress/Branch/x86.cpp18
-rwxr-xr-xCPP/7zip/Compress/Branch/x86.h19
-rwxr-xr-xCPP/7zip/Compress/Branch/x86_2.cpp412
-rwxr-xr-xCPP/7zip/Compress/Branch/x86_2.h133
-rwxr-xr-xCPP/7zip/Compress/ByteSwap/ByteSwap.cpp38
-rwxr-xr-xCPP/7zip/Compress/ByteSwap/ByteSwap.dsp125
-rwxr-xr-xCPP/7zip/Compress/ByteSwap/ByteSwap.dsw29
-rwxr-xr-xCPP/7zip/Compress/ByteSwap/ByteSwap.h37
-rwxr-xr-xCPP/7zip/Compress/ByteSwap/DllExports.cpp91
-rwxr-xr-xCPP/7zip/Compress/ByteSwap/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Compress/ByteSwap/StdAfx.h8
-rwxr-xr-xCPP/7zip/Compress/ByteSwap/makefile23
-rwxr-xr-xCPP/7zip/Compress/ByteSwap/resource.rc3
-rwxr-xr-xCPP/7zip/Compress/Codec.def4
-rwxr-xr-xCPP/7zip/Compress/Copy/Copy.dsp149
-rwxr-xr-xCPP/7zip/Compress/Copy/Copy.dsw29
-rwxr-xr-xCPP/7zip/Compress/Copy/CopyCoder.cpp52
-rwxr-xr-xCPP/7zip/Compress/Copy/CopyCoder.h31
-rwxr-xr-xCPP/7zip/Compress/Copy/DllExports.cpp70
-rwxr-xr-xCPP/7zip/Compress/Copy/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Compress/Copy/StdAfx.h8
-rwxr-xr-xCPP/7zip/Compress/Copy/makefile30
-rwxr-xr-xCPP/7zip/Compress/Copy/resource.rc3
-rwxr-xr-xCPP/7zip/Compress/Deflate/Deflate.dsp341
-rwxr-xr-xCPP/7zip/Compress/Deflate/Deflate.dsw29
-rwxr-xr-xCPP/7zip/Compress/Deflate/DeflateConst.h134
-rwxr-xr-xCPP/7zip/Compress/Deflate/DeflateDecoder.cpp339
-rwxr-xr-xCPP/7zip/Compress/Deflate/DeflateDecoder.h134
-rwxr-xr-xCPP/7zip/Compress/Deflate/DeflateEncoder.cpp963
-rwxr-xr-xCPP/7zip/Compress/Deflate/DeflateEncoder.h221
-rwxr-xr-xCPP/7zip/Compress/Deflate/DllExports.cpp157
-rwxr-xr-xCPP/7zip/Compress/Deflate/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Compress/Deflate/StdAfx.h8
-rwxr-xr-xCPP/7zip/Compress/Deflate/makefile63
-rwxr-xr-xCPP/7zip/Compress/Deflate/resource.rc3
-rwxr-xr-xCPP/7zip/Compress/Huffman/HuffmanDecoder.h88
-rwxr-xr-xCPP/7zip/Compress/Huffman/StdAfx.h6
-rwxr-xr-xCPP/7zip/Compress/Implode/DllExports.cpp65
-rwxr-xr-xCPP/7zip/Compress/Implode/ImplodeDecoder.cpp222
-rwxr-xr-xCPP/7zip/Compress/Implode/ImplodeDecoder.h60
-rwxr-xr-xCPP/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp89
-rwxr-xr-xCPP/7zip/Compress/Implode/ImplodeHuffmanDecoder.h33
-rwxr-xr-xCPP/7zip/Compress/Implode/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Compress/Implode/StdAfx.h8
-rwxr-xr-xCPP/7zip/Compress/LZ/LZOutWindow.cpp17
-rwxr-xr-xCPP/7zip/Compress/LZ/LZOutWindow.h56
-rwxr-xr-xCPP/7zip/Compress/LZ/StdAfx.h6
-rwxr-xr-xCPP/7zip/Compress/LZMA/DllExports.cpp109
-rwxr-xr-xCPP/7zip/Compress/LZMA/LZMA.dsp478
-rwxr-xr-xCPP/7zip/Compress/LZMA/LZMA.dsw29
-rwxr-xr-xCPP/7zip/Compress/LZMA/LZMA.h82
-rwxr-xr-xCPP/7zip/Compress/LZMA/LZMADecoder.cpp338
-rwxr-xr-xCPP/7zip/Compress/LZMA/LZMADecoder.h251
-rwxr-xr-xCPP/7zip/Compress/LZMA/LZMAEncoder.cpp1530
-rwxr-xr-xCPP/7zip/Compress/LZMA/LZMAEncoder.h435
-rwxr-xr-xCPP/7zip/Compress/LZMA/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Compress/LZMA/StdAfx.h8
-rwxr-xr-xCPP/7zip/Compress/LZMA/makefile69
-rwxr-xr-xCPP/7zip/Compress/LZMA/resource.rc3
-rwxr-xr-xCPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp449
-rwxr-xr-xCPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsw29
-rwxr-xr-xCPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp526
-rwxr-xr-xCPP/7zip/Compress/LZMA_Alone/LzmaBench.cpp506
-rwxr-xr-xCPP/7zip/Compress/LZMA_Alone/LzmaBench.h11
-rwxr-xr-xCPP/7zip/Compress/LZMA_Alone/LzmaRam.cpp227
-rwxr-xr-xCPP/7zip/Compress/LZMA_Alone/LzmaRam.h46
-rwxr-xr-xCPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.c79
-rwxr-xr-xCPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.h55
-rwxr-xr-xCPP/7zip/Compress/LZMA_Alone/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Compress/LZMA_Alone/StdAfx.h8
-rwxr-xr-xCPP/7zip/Compress/LZMA_Alone/makefile124
-rwxr-xr-xCPP/7zip/Compress/LZMA_Alone/makefile.gcc117
-rwxr-xr-xCPP/7zip/Compress/Lzh/LzhDecoder.cpp216
-rwxr-xr-xCPP/7zip/Compress/Lzh/LzhDecoder.h103
-rwxr-xr-xCPP/7zip/Compress/Lzx/Lzx.h61
-rwxr-xr-xCPP/7zip/Compress/Lzx/Lzx86Converter.cpp90
-rwxr-xr-xCPP/7zip/Compress/Lzx/Lzx86Converter.h45
-rwxr-xr-xCPP/7zip/Compress/Lzx/LzxDecoder.cpp382
-rwxr-xr-xCPP/7zip/Compress/Lzx/LzxDecoder.h181
-rwxr-xr-xCPP/7zip/Compress/Lzx/StdAfx.h8
-rwxr-xr-xCPP/7zip/Compress/PPMD/DllExports.cpp93
-rwxr-xr-xCPP/7zip/Compress/PPMD/PPMD.dsp229
-rwxr-xr-xCPP/7zip/Compress/PPMD/PPMD.dsw29
-rwxr-xr-xCPP/7zip/Compress/PPMD/PPMDContext.h489
-rwxr-xr-xCPP/7zip/Compress/PPMD/PPMDDecode.h154
-rwxr-xr-xCPP/7zip/Compress/PPMD/PPMDDecoder.cpp184
-rwxr-xr-xCPP/7zip/Compress/PPMD/PPMDDecoder.h89
-rwxr-xr-xCPP/7zip/Compress/PPMD/PPMDEncode.h142
-rwxr-xr-xCPP/7zip/Compress/PPMD/PPMDEncoder.cpp155
-rwxr-xr-xCPP/7zip/Compress/PPMD/PPMDEncoder.h81
-rwxr-xr-xCPP/7zip/Compress/PPMD/PPMDSubAlloc.h292
-rwxr-xr-xCPP/7zip/Compress/PPMD/PPMDType.h19
-rwxr-xr-xCPP/7zip/Compress/PPMD/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Compress/PPMD/StdAfx.h8
-rwxr-xr-xCPP/7zip/Compress/PPMD/makefile41
-rwxr-xr-xCPP/7zip/Compress/PPMD/resource.rc3
-rwxr-xr-xCPP/7zip/Compress/Quantum/QuantumDecoder.cpp173
-rwxr-xr-xCPP/7zip/Compress/Quantum/QuantumDecoder.h287
-rwxr-xr-xCPP/7zip/Compress/RangeCoder/RangeCoder.h205
-rwxr-xr-xCPP/7zip/Compress/RangeCoder/RangeCoderBit.cpp80
-rwxr-xr-xCPP/7zip/Compress/RangeCoder/RangeCoderBit.h120
-rwxr-xr-xCPP/7zip/Compress/RangeCoder/RangeCoderBitTree.h161
-rwxr-xr-xCPP/7zip/Compress/RangeCoder/RangeCoderOpt.h31
-rwxr-xr-xCPP/7zip/Compress/RangeCoder/StdAfx.h6
-rwxr-xr-xCPP/7zip/Compress/Rar/DllExports.cpp91
-rwxr-xr-xCPP/7zip/Compress/Rar/Rar1Decoder.cpp485
-rwxr-xr-xCPP/7zip/Compress/Rar/Rar1Decoder.h90
-rwxr-xr-xCPP/7zip/Compress/Rar/Rar29.dsp297
-rwxr-xr-xCPP/7zip/Compress/Rar/Rar29.dsw29
-rwxr-xr-xCPP/7zip/Compress/Rar/Rar2Decoder.cpp401
-rwxr-xr-xCPP/7zip/Compress/Rar/Rar2Decoder.h176
-rwxr-xr-xCPP/7zip/Compress/Rar/Rar3Decoder.cpp832
-rwxr-xr-xCPP/7zip/Compress/Rar/Rar3Decoder.h294
-rwxr-xr-xCPP/7zip/Compress/Rar/Rar3Vm.cpp1089
-rwxr-xr-xCPP/7zip/Compress/Rar/Rar3Vm.h219
-rwxr-xr-xCPP/7zip/Compress/Rar/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Compress/Rar/StdAfx.h8
-rwxr-xr-xCPP/7zip/Compress/Rar/makefile49
-rwxr-xr-xCPP/7zip/Compress/Rar/resource.rc3
-rwxr-xr-xCPP/7zip/Compress/Shrink/DllExports.cpp64
-rwxr-xr-xCPP/7zip/Compress/Shrink/ShrinkDecoder.cpp149
-rwxr-xr-xCPP/7zip/Compress/Shrink/ShrinkDecoder.h39
-rwxr-xr-xCPP/7zip/Compress/Shrink/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Compress/Shrink/StdAfx.h8
-rwxr-xr-xCPP/7zip/Compress/Z/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Compress/Z/StdAfx.h8
-rwxr-xr-xCPP/7zip/Compress/Z/ZDecoder.cpp172
-rwxr-xr-xCPP/7zip/Compress/Z/ZDecoder.h44
-rwxr-xr-xCPP/7zip/Compress/makefile14
-rwxr-xr-xCPP/7zip/Crypto/7zAES/7zAES.cpp305
-rwxr-xr-xCPP/7zip/Crypto/7zAES/7zAES.dsp245
-rwxr-xr-xCPP/7zip/Crypto/7zAES/7zAES.dsw29
-rwxr-xr-xCPP/7zip/Crypto/7zAES/7zAES.h122
-rwxr-xr-xCPP/7zip/Crypto/7zAES/DllExports.cpp111
-rwxr-xr-xCPP/7zip/Crypto/7zAES/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Crypto/7zAES/StdAfx.h8
-rwxr-xr-xCPP/7zip/Crypto/7zAES/makefile52
-rwxr-xr-xCPP/7zip/Crypto/7zAES/resource.rc3
-rwxr-xr-xCPP/7zip/Crypto/AES/AES.dsp203
-rwxr-xr-xCPP/7zip/Crypto/AES/AES.dsw29
-rwxr-xr-xCPP/7zip/Crypto/AES/AES_CBC.h39
-rwxr-xr-xCPP/7zip/Crypto/AES/DllExports.cpp100
-rwxr-xr-xCPP/7zip/Crypto/AES/MyAES.cpp94
-rwxr-xr-xCPP/7zip/Crypto/AES/MyAES.h106
-rwxr-xr-xCPP/7zip/Crypto/AES/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Crypto/AES/StdAfx.h8
-rwxr-xr-xCPP/7zip/Crypto/AES/aes.h103
-rwxr-xr-xCPP/7zip/Crypto/AES/aescpp.h55
-rwxr-xr-xCPP/7zip/Crypto/AES/aescrypt.c421
-rwxr-xr-xCPP/7zip/Crypto/AES/aeskey.c363
-rwxr-xr-xCPP/7zip/Crypto/AES/aesopt.h839
-rwxr-xr-xCPP/7zip/Crypto/AES/aestab.c494
-rwxr-xr-xCPP/7zip/Crypto/AES/makefile31
-rwxr-xr-xCPP/7zip/Crypto/AES/resource.rc3
-rwxr-xr-xCPP/7zip/Crypto/Codec.def4
-rwxr-xr-xCPP/7zip/Crypto/Hash/HmacSha1.cpp109
-rwxr-xr-xCPP/7zip/Crypto/Hash/HmacSha1.h39
-rwxr-xr-xCPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.cpp83
-rwxr-xr-xCPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.h21
-rwxr-xr-xCPP/7zip/Crypto/Hash/RandGen.cpp78
-rwxr-xr-xCPP/7zip/Crypto/Hash/RandGen.h21
-rwxr-xr-xCPP/7zip/Crypto/Hash/RotateDefs.h19
-rwxr-xr-xCPP/7zip/Crypto/Hash/Sha1.cpp210
-rwxr-xr-xCPP/7zip/Crypto/Hash/Sha1.h68
-rwxr-xr-xCPP/7zip/Crypto/Hash/Sha256.cpp210
-rwxr-xr-xCPP/7zip/Crypto/Hash/Sha256.h30
-rwxr-xr-xCPP/7zip/Crypto/Hash/StdAfx.h8
-rwxr-xr-xCPP/7zip/Crypto/Rar20/Rar20Cipher.cpp76
-rwxr-xr-xCPP/7zip/Crypto/Rar20/Rar20Cipher.h35
-rwxr-xr-xCPP/7zip/Crypto/Rar20/Rar20Crypto.cpp124
-rwxr-xr-xCPP/7zip/Crypto/Rar20/Rar20Crypto.h33
-rwxr-xr-xCPP/7zip/Crypto/Rar20/StdAfx.h8
-rwxr-xr-xCPP/7zip/Crypto/RarAES/RarAES.cpp187
-rwxr-xr-xCPP/7zip/Crypto/RarAES/RarAES.h61
-rwxr-xr-xCPP/7zip/Crypto/RarAES/StdAfx.h8
-rwxr-xr-xCPP/7zip/Crypto/WzAES/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/Crypto/WzAES/StdAfx.h8
-rwxr-xr-xCPP/7zip/Crypto/WzAES/WzAES.cpp246
-rwxr-xr-xCPP/7zip/Crypto/WzAES/WzAES.h126
-rwxr-xr-xCPP/7zip/Crypto/Zip/StdAfx.h8
-rwxr-xr-xCPP/7zip/Crypto/Zip/ZipCipher.cpp85
-rwxr-xr-xCPP/7zip/Crypto/Zip/ZipCipher.h59
-rwxr-xr-xCPP/7zip/Crypto/Zip/ZipCrypto.cpp65
-rwxr-xr-xCPP/7zip/Crypto/Zip/ZipCrypto.h26
-rwxr-xr-xCPP/7zip/Crypto/makefile8
-rwxr-xr-xCPP/7zip/FileManager/7zFM.exe.manifest1
-rwxr-xr-xCPP/7zip/FileManager/7zipLogo.icobin0 -> 9150 bytes
-rwxr-xr-xCPP/7zip/FileManager/Add.bmpbin0 -> 982 bytes
-rwxr-xr-xCPP/7zip/FileManager/Add2.bmpbin0 -> 406 bytes
-rwxr-xr-xCPP/7zip/FileManager/App.cpp759
-rwxr-xr-xCPP/7zip/FileManager/App.h332
-rwxr-xr-xCPP/7zip/FileManager/AppState.h114
-rwxr-xr-xCPP/7zip/FileManager/ClassDefs.cpp15
-rwxr-xr-xCPP/7zip/FileManager/Copy.bmpbin0 -> 982 bytes
-rwxr-xr-xCPP/7zip/FileManager/Copy2.bmpbin0 -> 406 bytes
-rwxr-xr-xCPP/7zip/FileManager/Delete.bmpbin0 -> 982 bytes
-rwxr-xr-xCPP/7zip/FileManager/Delete2.bmpbin0 -> 406 bytes
-rwxr-xr-xCPP/7zip/FileManager/EnumFormatEtc.cpp108
-rwxr-xr-xCPP/7zip/FileManager/EnumFormatEtc.h10
-rwxr-xr-xCPP/7zip/FileManager/Extract.bmpbin0 -> 982 bytes
-rwxr-xr-xCPP/7zip/FileManager/Extract2.bmpbin0 -> 406 bytes
-rwxr-xr-xCPP/7zip/FileManager/ExtractCallback.cpp382
-rwxr-xr-xCPP/7zip/FileManager/ExtractCallback.h124
-rwxr-xr-xCPP/7zip/FileManager/FM.cpp788
-rwxr-xr-xCPP/7zip/FileManager/FM.dsp1251
-rwxr-xr-xCPP/7zip/FileManager/FM.dsw29
-rwxr-xr-xCPP/7zip/FileManager/FM.icobin0 -> 4846 bytes
-rwxr-xr-xCPP/7zip/FileManager/FSDrives.cpp240
-rwxr-xr-xCPP/7zip/FileManager/FSDrives.h66
-rwxr-xr-xCPP/7zip/FileManager/FSFolder.cpp655
-rwxr-xr-xCPP/7zip/FileManager/FSFolder.h141
-rwxr-xr-xCPP/7zip/FileManager/FSFolderCopy.cpp490
-rwxr-xr-xCPP/7zip/FileManager/FileFolderPluginOpen.cpp111
-rwxr-xr-xCPP/7zip/FileManager/FileFolderPluginOpen.h9
-rwxr-xr-xCPP/7zip/FileManager/FilePlugins.cpp113
-rwxr-xr-xCPP/7zip/FileManager/FilePlugins.h54
-rwxr-xr-xCPP/7zip/FileManager/FormatUtils.cpp40
-rwxr-xr-xCPP/7zip/FileManager/FormatUtils.h18
-rwxr-xr-xCPP/7zip/FileManager/HelpUtils.cpp23
-rwxr-xr-xCPP/7zip/FileManager/HelpUtils.h10
-rwxr-xr-xCPP/7zip/FileManager/IFolder.h190
-rwxr-xr-xCPP/7zip/FileManager/Info.bmpbin0 -> 982 bytes
-rwxr-xr-xCPP/7zip/FileManager/Info2.bmpbin0 -> 406 bytes
-rwxr-xr-xCPP/7zip/FileManager/LangUtils.cpp185
-rwxr-xr-xCPP/7zip/FileManager/LangUtils.h41
-rwxr-xr-xCPP/7zip/FileManager/Move.bmpbin0 -> 982 bytes
-rwxr-xr-xCPP/7zip/FileManager/Move2.bmpbin0 -> 406 bytes
-rwxr-xr-xCPP/7zip/FileManager/MyCom2.h48
-rwxr-xr-xCPP/7zip/FileManager/MyLoadMenu.cpp694
-rwxr-xr-xCPP/7zip/FileManager/MyLoadMenu.h16
-rwxr-xr-xCPP/7zip/FileManager/NetFolder.cpp315
-rwxr-xr-xCPP/7zip/FileManager/NetFolder.h66
-rwxr-xr-xCPP/7zip/FileManager/OpenCallback.cpp113
-rwxr-xr-xCPP/7zip/FileManager/OpenCallback.h85
-rwxr-xr-xCPP/7zip/FileManager/OptionsDialog.cpp65
-rwxr-xr-xCPP/7zip/FileManager/Panel.cpp856
-rwxr-xr-xCPP/7zip/FileManager/Panel.h510
-rwxr-xr-xCPP/7zip/FileManager/PanelCopy.cpp208
-rwxr-xr-xCPP/7zip/FileManager/PanelCrc.cpp361
-rwxr-xr-xCPP/7zip/FileManager/PanelDrag.cpp796
-rwxr-xr-xCPP/7zip/FileManager/PanelFolderChange.cpp414
-rwxr-xr-xCPP/7zip/FileManager/PanelItemOpen.cpp546
-rwxr-xr-xCPP/7zip/FileManager/PanelItems.cpp822
-rwxr-xr-xCPP/7zip/FileManager/PanelKey.cpp297
-rwxr-xr-xCPP/7zip/FileManager/PanelListNotify.cpp388
-rwxr-xr-xCPP/7zip/FileManager/PanelMenu.cpp422
-rwxr-xr-xCPP/7zip/FileManager/PanelOperations.cpp396
-rwxr-xr-xCPP/7zip/FileManager/PanelSelect.cpp297
-rwxr-xr-xCPP/7zip/FileManager/PanelSort.cpp163
-rwxr-xr-xCPP/7zip/FileManager/PanelSplitFile.cpp477
-rwxr-xr-xCPP/7zip/FileManager/PhysDriveFolder.cpp274
-rwxr-xr-xCPP/7zip/FileManager/PhysDriveFolder.h89
-rwxr-xr-xCPP/7zip/FileManager/PluginInterface.h42
-rwxr-xr-xCPP/7zip/FileManager/PluginLoader.h32
-rwxr-xr-xCPP/7zip/FileManager/ProgramLocation.cpp24
-rwxr-xr-xCPP/7zip/FileManager/ProgramLocation.h10
-rwxr-xr-xCPP/7zip/FileManager/PropertyName.cpp74
-rwxr-xr-xCPP/7zip/FileManager/PropertyName.h10
-rwxr-xr-xCPP/7zip/FileManager/RegistryAssociations.cpp270
-rwxr-xr-xCPP/7zip/FileManager/RegistryAssociations.h45
-rwxr-xr-xCPP/7zip/FileManager/RegistryPlugins.cpp130
-rwxr-xr-xCPP/7zip/FileManager/RegistryPlugins.h32
-rwxr-xr-xCPP/7zip/FileManager/RegistryUtils.cpp150
-rwxr-xr-xCPP/7zip/FileManager/RegistryUtils.h46
-rwxr-xr-xCPP/7zip/FileManager/Resource/AboutDialog/7zipLogo.icobin0 -> 9150 bytes
-rwxr-xr-xCPP/7zip/FileManager/Resource/AboutDialog/AboutDialog.cpp60
-rwxr-xr-xCPP/7zip/FileManager/Resource/AboutDialog/AboutDialog.h18
-rwxr-xr-xCPP/7zip/FileManager/Resource/AboutDialog/StdAfx.h16
-rwxr-xr-xCPP/7zip/FileManager/Resource/AboutDialog/resource.h6
-rwxr-xr-xCPP/7zip/FileManager/Resource/AboutDialog/resource.rc41
-rwxr-xr-xCPP/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp976
-rwxr-xr-xCPP/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.h136
-rwxr-xr-xCPP/7zip/FileManager/Resource/BenchmarkDialog/StdAfx.h16
-rwxr-xr-xCPP/7zip/FileManager/Resource/BenchmarkDialog/resource.h34
-rwxr-xr-xCPP/7zip/FileManager/Resource/BenchmarkDialog/resource.rc87
-rwxr-xr-xCPP/7zip/FileManager/Resource/ComboDialog/ComboDialog.cpp53
-rwxr-xr-xCPP/7zip/FileManager/Resource/ComboDialog/ComboDialog.h25
-rwxr-xr-xCPP/7zip/FileManager/Resource/ComboDialog/StdAfx.h16
-rwxr-xr-xCPP/7zip/FileManager/Resource/ComboDialog/resource.h4
-rwxr-xr-xCPP/7zip/FileManager/Resource/ComboDialog/resource.rc24
-rwxr-xr-xCPP/7zip/FileManager/Resource/CopyDialog/CopyDialog.cpp81
-rwxr-xr-xCPP/7zip/FileManager/Resource/CopyDialog/CopyDialog.h26
-rwxr-xr-xCPP/7zip/FileManager/Resource/CopyDialog/StdAfx.h16
-rwxr-xr-xCPP/7zip/FileManager/Resource/CopyDialog/resource.h7
-rwxr-xr-xCPP/7zip/FileManager/Resource/CopyDialog/resource.rc28
-rwxr-xr-xCPP/7zip/FileManager/Resource/EditPage/EditPage.cpp91
-rwxr-xr-xCPP/7zip/FileManager/Resource/EditPage/EditPage.h21
-rwxr-xr-xCPP/7zip/FileManager/Resource/EditPage/StdAfx.h16
-rwxr-xr-xCPP/7zip/FileManager/Resource/EditPage/resource.h4
-rwxr-xr-xCPP/7zip/FileManager/Resource/EditPage/resource.rc16
-rwxr-xr-xCPP/7zip/FileManager/Resource/LangPage/LangPage.cpp90
-rwxr-xr-xCPP/7zip/FileManager/Resource/LangPage/LangPage.h21
-rwxr-xr-xCPP/7zip/FileManager/Resource/LangPage/StdAfx.h16
-rwxr-xr-xCPP/7zip/FileManager/Resource/LangPage/resource.h6
-rwxr-xr-xCPP/7zip/FileManager/Resource/LangPage/resource.rc21
-rwxr-xr-xCPP/7zip/FileManager/Resource/ListBoxDialog/StdAfx.h16
-rwxr-xr-xCPP/7zip/FileManager/Resource/ListBoxDialog/resource.h3
-rwxr-xr-xCPP/7zip/FileManager/Resource/ListBoxDialog/resource.rc22
-rwxr-xr-xCPP/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.cpp102
-rwxr-xr-xCPP/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.h30
-rwxr-xr-xCPP/7zip/FileManager/Resource/ListViewDialog/StdAfx.h16
-rwxr-xr-xCPP/7zip/FileManager/Resource/ListViewDialog/resource.h3
-rwxr-xr-xCPP/7zip/FileManager/Resource/ListViewDialog/resource.rc26
-rwxr-xr-xCPP/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.cpp100
-rwxr-xr-xCPP/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.h22
-rwxr-xr-xCPP/7zip/FileManager/Resource/MessagesDialog/StdAfx.h16
-rwxr-xr-xCPP/7zip/FileManager/Resource/MessagesDialog/resource.h3
-rwxr-xr-xCPP/7zip/FileManager/Resource/MessagesDialog/resource.rc25
-rwxr-xr-xCPP/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.cpp124
-rwxr-xr-xCPP/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.h34
-rwxr-xr-xCPP/7zip/FileManager/Resource/OverwriteDialog/StdAfx.h16
-rwxr-xr-xCPP/7zip/FileManager/Resource/OverwriteDialog/resource.h19
-rwxr-xr-xCPP/7zip/FileManager/Resource/OverwriteDialog/resource.rc47
-rwxr-xr-xCPP/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.cpp50
-rwxr-xr-xCPP/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.h21
-rwxr-xr-xCPP/7zip/FileManager/Resource/PasswordDialog/StdAfx.h16
-rwxr-xr-xCPP/7zip/FileManager/Resource/PasswordDialog/resource.h4
-rwxr-xr-xCPP/7zip/FileManager/Resource/PasswordDialog/resource.rc26
-rwxr-xr-xCPP/7zip/FileManager/Resource/PluginsPage/PluginsPage.cpp220
-rwxr-xr-xCPP/7zip/FileManager/Resource/PluginsPage/PluginsPage.h26
-rwxr-xr-xCPP/7zip/FileManager/Resource/PluginsPage/StdAfx.h16
-rwxr-xr-xCPP/7zip/FileManager/Resource/PluginsPage/resource.h4
-rwxr-xr-xCPP/7zip/FileManager/Resource/PluginsPage/resource.rc19
-rwxr-xr-xCPP/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.cpp175
-rwxr-xr-xCPP/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.h129
-rwxr-xr-xCPP/7zip/FileManager/Resource/ProgressDialog/StdAfx.h16
-rwxr-xr-xCPP/7zip/FileManager/Resource/ProgressDialog/resource.h3
-rwxr-xr-xCPP/7zip/FileManager/Resource/ProgressDialog/resource.rc20
-rwxr-xr-xCPP/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.cpp432
-rwxr-xr-xCPP/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.h184
-rwxr-xr-xCPP/7zip/FileManager/Resource/ProgressDialog2/StdAfx.h16
-rwxr-xr-xCPP/7zip/FileManager/Resource/ProgressDialog2/resource.h17
-rwxr-xr-xCPP/7zip/FileManager/Resource/ProgressDialog2/resource.rc56
-rwxr-xr-xCPP/7zip/FileManager/Resource/PropertyName/resource.h28
-rwxr-xr-xCPP/7zip/FileManager/Resource/PropertyName/resource.rc35
-rwxr-xr-xCPP/7zip/FileManager/Resource/SettingsPage/SettingsPage.cpp113
-rwxr-xr-xCPP/7zip/FileManager/Resource/SettingsPage/SettingsPage.h19
-rwxr-xr-xCPP/7zip/FileManager/Resource/SettingsPage/StdAfx.h16
-rwxr-xr-xCPP/7zip/FileManager/Resource/SettingsPage/resource.h11
-rwxr-xr-xCPP/7zip/FileManager/Resource/SettingsPage/resource.rc35
-rwxr-xr-xCPP/7zip/FileManager/Resource/SplitDialog/SplitDialog.cpp89
-rwxr-xr-xCPP/7zip/FileManager/Resource/SplitDialog/SplitDialog.h27
-rwxr-xr-xCPP/7zip/FileManager/Resource/SplitDialog/StdAfx.h18
-rwxr-xr-xCPP/7zip/FileManager/Resource/SplitDialog/resource.h8
-rwxr-xr-xCPP/7zip/FileManager/Resource/SplitDialog/resource.rc32
-rwxr-xr-xCPP/7zip/FileManager/Resource/SystemPage/StdAfx.h16
-rwxr-xr-xCPP/7zip/FileManager/Resource/SystemPage/SystemPage.cpp435
-rwxr-xr-xCPP/7zip/FileManager/Resource/SystemPage/SystemPage.h40
-rwxr-xr-xCPP/7zip/FileManager/Resource/SystemPage/resource.h7
-rwxr-xr-xCPP/7zip/FileManager/Resource/SystemPage/resource.rc31
-rwxr-xr-xCPP/7zip/FileManager/RootFolder.cpp204
-rwxr-xr-xCPP/7zip/FileManager/RootFolder.h49
-rwxr-xr-xCPP/7zip/FileManager/SplitUtils.cpp85
-rwxr-xr-xCPP/7zip/FileManager/SplitUtils.h15
-rwxr-xr-xCPP/7zip/FileManager/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/FileManager/StdAfx.h23
-rwxr-xr-xCPP/7zip/FileManager/StringUtils.cpp68
-rwxr-xr-xCPP/7zip/FileManager/StringUtils.h13
-rwxr-xr-xCPP/7zip/FileManager/SysIconUtils.cpp157
-rwxr-xr-xCPP/7zip/FileManager/SysIconUtils.h51
-rwxr-xr-xCPP/7zip/FileManager/Test.bmpbin0 -> 982 bytes
-rwxr-xr-xCPP/7zip/FileManager/Test2.bmpbin0 -> 406 bytes
-rwxr-xr-xCPP/7zip/FileManager/TextPairs.cpp216
-rwxr-xr-xCPP/7zip/FileManager/TextPairs.h32
-rwxr-xr-xCPP/7zip/FileManager/UpdateCallback100.cpp92
-rwxr-xr-xCPP/7zip/FileManager/UpdateCallback100.h67
-rwxr-xr-xCPP/7zip/FileManager/ViewSettings.cpp429
-rwxr-xr-xCPP/7zip/FileManager/ViewSettings.h99
-rwxr-xr-xCPP/7zip/FileManager/makefile187
-rwxr-xr-xCPP/7zip/FileManager/resource.h154
-rwxr-xr-xCPP/7zip/FileManager/resource.rc232
-rwxr-xr-xCPP/7zip/GuiCommon.rc37
-rwxr-xr-xCPP/7zip/Guid.txt157
-rwxr-xr-xCPP/7zip/ICoder.h163
-rwxr-xr-xCPP/7zip/IPassword.h26
-rwxr-xr-xCPP/7zip/IProgress.h32
-rwxr-xr-xCPP/7zip/IStream.h62
-rwxr-xr-xCPP/7zip/MyVersion.h8
-rwxr-xr-xCPP/7zip/MyVersionInfo.rc41
-rwxr-xr-xCPP/7zip/PropID.h51
-rwxr-xr-xCPP/7zip/SubBuild.mak3
-rwxr-xr-xCPP/7zip/UI/Agent/Agent.cpp578
-rwxr-xr-xCPP/7zip/UI/Agent/Agent.h314
-rwxr-xr-xCPP/7zip/UI/Agent/AgentOut.cpp518
-rwxr-xr-xCPP/7zip/UI/Agent/AgentProxy.cpp203
-rwxr-xr-xCPP/7zip/UI/Agent/AgentProxy.h56
-rwxr-xr-xCPP/7zip/UI/Agent/ArchiveFolder.cpp72
-rwxr-xr-xCPP/7zip/UI/Agent/ArchiveFolderOpen.cpp98
-rwxr-xr-xCPP/7zip/UI/Agent/ArchiveFolderOut.cpp215
-rwxr-xr-xCPP/7zip/UI/Agent/IFolderArchive.h90
-rwxr-xr-xCPP/7zip/UI/Agent/UpdateCallbackAgent.cpp80
-rwxr-xr-xCPP/7zip/UI/Agent/UpdateCallbackAgent.h24
-rwxr-xr-xCPP/7zip/UI/Client7z/Client7z.cpp850
-rwxr-xr-xCPP/7zip/UI/Client7z/Client7z.dsp226
-rwxr-xr-xCPP/7zip/UI/Client7z/Client7z.dsw29
-rwxr-xr-xCPP/7zip/UI/Client7z/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/UI/Client7z/StdAfx.h9
-rwxr-xr-xCPP/7zip/UI/Client7z/makefile45
-rwxr-xr-xCPP/7zip/UI/Common/ArchiveCommandLine.cpp985
-rwxr-xr-xCPP/7zip/UI/Common/ArchiveCommandLine.h95
-rwxr-xr-xCPP/7zip/UI/Common/ArchiveExtractCallback.cpp448
-rwxr-xr-xCPP/7zip/UI/Common/ArchiveExtractCallback.h111
-rwxr-xr-xCPP/7zip/UI/Common/ArchiveName.cpp46
-rwxr-xr-xCPP/7zip/UI/Common/ArchiveName.h10
-rwxr-xr-xCPP/7zip/UI/Common/ArchiveOpenCallback.cpp127
-rwxr-xr-xCPP/7zip/UI/Common/ArchiveOpenCallback.h89
-rwxr-xr-xCPP/7zip/UI/Common/ArchiverInfo.cpp372
-rwxr-xr-xCPP/7zip/UI/Common/ArchiverInfo.h66
-rwxr-xr-xCPP/7zip/UI/Common/CompressCall.cpp367
-rwxr-xr-xCPP/7zip/UI/Common/CompressCall.h28
-rwxr-xr-xCPP/7zip/UI/Common/DefaultName.cpp26
-rwxr-xr-xCPP/7zip/UI/Common/DefaultName.h11
-rwxr-xr-xCPP/7zip/UI/Common/DirItem.h34
-rwxr-xr-xCPP/7zip/UI/Common/EnumDirItems.cpp281
-rwxr-xr-xCPP/7zip/UI/Common/EnumDirItems.h39
-rwxr-xr-xCPP/7zip/UI/Common/ExitCode.h27
-rwxr-xr-xCPP/7zip/UI/Common/Extract.cpp152
-rwxr-xr-xCPP/7zip/UI/Common/Extract.h59
-rwxr-xr-xCPP/7zip/UI/Common/ExtractMode.h31
-rwxr-xr-xCPP/7zip/UI/Common/ExtractingFilePath.cpp75
-rwxr-xr-xCPP/7zip/UI/Common/ExtractingFilePath.h12
-rwxr-xr-xCPP/7zip/UI/Common/HandlerLoader.h38
-rwxr-xr-xCPP/7zip/UI/Common/IFileExtractCallback.h46
-rwxr-xr-xCPP/7zip/UI/Common/OpenArchive.cpp531
-rwxr-xr-xCPP/7zip/UI/Common/OpenArchive.h134
-rwxr-xr-xCPP/7zip/UI/Common/PropIDUtils.cpp90
-rwxr-xr-xCPP/7zip/UI/Common/PropIDUtils.h11
-rwxr-xr-xCPP/7zip/UI/Common/Property.h14
-rwxr-xr-xCPP/7zip/UI/Common/SetProperties.cpp65
-rwxr-xr-xCPP/7zip/UI/Common/SetProperties.h10
-rwxr-xr-xCPP/7zip/UI/Common/SortUtils.cpp78
-rwxr-xr-xCPP/7zip/UI/Common/SortUtils.h11
-rwxr-xr-xCPP/7zip/UI/Common/StdAfx.h9
-rwxr-xr-xCPP/7zip/UI/Common/TempFiles.cpp22
-rwxr-xr-xCPP/7zip/UI/Common/TempFiles.h16
-rwxr-xr-xCPP/7zip/UI/Common/Update.cpp818
-rwxr-xr-xCPP/7zip/UI/Common/Update.h158
-rwxr-xr-xCPP/7zip/UI/Common/UpdateAction.cpp64
-rwxr-xr-xCPP/7zip/UI/Common/UpdateAction.h57
-rwxr-xr-xCPP/7zip/UI/Common/UpdateCallback.cpp258
-rwxr-xr-xCPP/7zip/UI/Common/UpdateCallback.h70
-rwxr-xr-xCPP/7zip/UI/Common/UpdatePair.cpp175
-rwxr-xr-xCPP/7zip/UI/Common/UpdatePair.h24
-rwxr-xr-xCPP/7zip/UI/Common/UpdateProduce.cpp63
-rwxr-xr-xCPP/7zip/UI/Common/UpdateProduce.h31
-rwxr-xr-xCPP/7zip/UI/Common/WorkDir.cpp64
-rwxr-xr-xCPP/7zip/UI/Common/WorkDir.h10
-rwxr-xr-xCPP/7zip/UI/Common/ZipRegistry.cpp420
-rwxr-xr-xCPP/7zip/UI/Common/ZipRegistry.h99
-rwxr-xr-xCPP/7zip/UI/Console/Console.dsp667
-rwxr-xr-xCPP/7zip/UI/Console/Console.dsw29
-rwxr-xr-xCPP/7zip/UI/Console/ConsoleClose.cpp65
-rwxr-xr-xCPP/7zip/UI/Console/ConsoleClose.h24
-rwxr-xr-xCPP/7zip/UI/Console/ExtractCallbackConsole.cpp235
-rwxr-xr-xCPP/7zip/UI/Console/ExtractCallbackConsole.h65
-rwxr-xr-xCPP/7zip/UI/Console/List.cpp532
-rwxr-xr-xCPP/7zip/UI/Console/List.h13
-rwxr-xr-xCPP/7zip/UI/Console/Main.cpp382
-rwxr-xr-xCPP/7zip/UI/Console/MainAr.cpp169
-rwxr-xr-xCPP/7zip/UI/Console/OpenCallbackConsole.cpp58
-rwxr-xr-xCPP/7zip/UI/Console/OpenCallbackConsole.h27
-rwxr-xr-xCPP/7zip/UI/Console/PercentPrinter.cpp90
-rwxr-xr-xCPP/7zip/UI/Console/PercentPrinter.h31
-rwxr-xr-xCPP/7zip/UI/Console/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/UI/Console/StdAfx.h9
-rwxr-xr-xCPP/7zip/UI/Console/UpdateCallbackConsole.cpp196
-rwxr-xr-xCPP/7zip/UI/Console/UpdateCallbackConsole.h75
-rwxr-xr-xCPP/7zip/UI/Console/UserInputUtils.cpp58
-rwxr-xr-xCPP/7zip/UI/Console/UserInputUtils.h24
-rwxr-xr-xCPP/7zip/UI/Console/afxres.h1
-rwxr-xr-xCPP/7zip/UI/Console/makefile93
-rwxr-xr-xCPP/7zip/UI/Console/resource.rc3
-rwxr-xr-xCPP/7zip/UI/Explorer/7-zip.dll.manifest1
-rwxr-xr-xCPP/7zip/UI/Explorer/ContextMenu.cpp682
-rwxr-xr-xCPP/7zip/UI/Explorer/ContextMenu.h86
-rwxr-xr-xCPP/7zip/UI/Explorer/ContextMenuFlags.h34
-rwxr-xr-xCPP/7zip/UI/Explorer/DllExports.cpp315
-rwxr-xr-xCPP/7zip/UI/Explorer/Explorer.def12
-rwxr-xr-xCPP/7zip/UI/Explorer/Explorer.dsp818
-rwxr-xr-xCPP/7zip/UI/Explorer/Explorer.dsw29
-rwxr-xr-xCPP/7zip/UI/Explorer/FoldersPage/FoldersPage.cpp157
-rwxr-xr-xCPP/7zip/UI/Explorer/FoldersPage/FoldersPage.h30
-rwxr-xr-xCPP/7zip/UI/Explorer/FoldersPage/resource.h12
-rwxr-xr-xCPP/7zip/UI/Explorer/FoldersPage/resource.rc36
-rwxr-xr-xCPP/7zip/UI/Explorer/MyMessages.cpp58
-rwxr-xr-xCPP/7zip/UI/Explorer/MyMessages.h30
-rwxr-xr-xCPP/7zip/UI/Explorer/OptionsDialog.cpp71
-rwxr-xr-xCPP/7zip/UI/Explorer/OptionsDialog.h23
-rwxr-xr-xCPP/7zip/UI/Explorer/RegistryContextMenu.cpp128
-rwxr-xr-xCPP/7zip/UI/Explorer/RegistryContextMenu.h13
-rwxr-xr-xCPP/7zip/UI/Explorer/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/UI/Explorer/StdAfx.h26
-rwxr-xr-xCPP/7zip/UI/Explorer/SystemPage/SystemPage.cpp212
-rwxr-xr-xCPP/7zip/UI/Explorer/SystemPage/SystemPage.h25
-rwxr-xr-xCPP/7zip/UI/Explorer/SystemPage/resource.h6
-rwxr-xr-xCPP/7zip/UI/Explorer/SystemPage/resource.rc24
-rwxr-xr-xCPP/7zip/UI/Explorer/makefile137
-rwxr-xr-xCPP/7zip/UI/Explorer/resource.h31
-rwxr-xr-xCPP/7zip/UI/Explorer/resource.rc38
-rwxr-xr-xCPP/7zip/UI/Far/CLSIDConst.cpp8
-rwxr-xr-xCPP/7zip/UI/Far/ExtractEngine.cpp168
-rwxr-xr-xCPP/7zip/UI/Far/ExtractEngine.h68
-rwxr-xr-xCPP/7zip/UI/Far/Far.def20
-rwxr-xr-xCPP/7zip/UI/Far/Far.dsp561
-rwxr-xr-xCPP/7zip/UI/Far/Far.dsw29
-rwxr-xr-xCPP/7zip/UI/Far/FarPlugin.h577
-rwxr-xr-xCPP/7zip/UI/Far/FarUtils.cpp416
-rwxr-xr-xCPP/7zip/UI/Far/FarUtils.h185
-rwxr-xr-xCPP/7zip/UI/Far/Main.cpp622
-rwxr-xr-xCPP/7zip/UI/Far/Messages.h152
-rwxr-xr-xCPP/7zip/UI/Far/OverwriteDialog.cpp109
-rwxr-xr-xCPP/7zip/UI/Far/OverwriteDialog.h33
-rwxr-xr-xCPP/7zip/UI/Far/Plugin.cpp693
-rwxr-xr-xCPP/7zip/UI/Far/Plugin.h99
-rwxr-xr-xCPP/7zip/UI/Far/PluginCommon.cpp50
-rwxr-xr-xCPP/7zip/UI/Far/PluginDelete.cpp169
-rwxr-xr-xCPP/7zip/UI/Far/PluginRead.cpp278
-rwxr-xr-xCPP/7zip/UI/Far/PluginWrite.cpp696
-rwxr-xr-xCPP/7zip/UI/Far/ProgressBox.cpp103
-rwxr-xr-xCPP/7zip/UI/Far/ProgressBox.h35
-rwxr-xr-xCPP/7zip/UI/Far/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/UI/Far/StdAfx.h12
-rwxr-xr-xCPP/7zip/UI/Far/UpdateCallback100.cpp54
-rwxr-xr-xCPP/7zip/UI/Far/UpdateCallback100.h45
-rwxr-xr-xCPP/7zip/UI/Far/makefile102
-rwxr-xr-xCPP/7zip/UI/Far/resource.rc3
-rwxr-xr-xCPP/7zip/UI/GUI/7zG.exe.manifest1
-rwxr-xr-xCPP/7zip/UI/GUI/CompressDialog.cpp1373
-rwxr-xr-xCPP/7zip/UI/GUI/CompressDialog.h171
-rwxr-xr-xCPP/7zip/UI/GUI/ExtractDialog.cpp371
-rwxr-xr-xCPP/7zip/UI/GUI/ExtractDialog.h77
-rwxr-xr-xCPP/7zip/UI/GUI/ExtractGUI.cpp172
-rwxr-xr-xCPP/7zip/UI/GUI/ExtractGUI.h20
-rwxr-xr-xCPP/7zip/UI/GUI/FM.icobin0 -> 4846 bytes
-rwxr-xr-xCPP/7zip/UI/GUI/GUI.cpp260
-rwxr-xr-xCPP/7zip/UI/GUI/GUI.dsp904
-rwxr-xr-xCPP/7zip/UI/GUI/GUI.dsw29
-rwxr-xr-xCPP/7zip/UI/GUI/OpenCallbackGUI.cpp65
-rwxr-xr-xCPP/7zip/UI/GUI/OpenCallbackGUI.h35
-rwxr-xr-xCPP/7zip/UI/GUI/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/UI/GUI/StdAfx.h13
-rwxr-xr-xCPP/7zip/UI/GUI/UpdateCallbackGUI.cpp167
-rwxr-xr-xCPP/7zip/UI/GUI/UpdateCallbackGUI.h63
-rwxr-xr-xCPP/7zip/UI/GUI/UpdateGUI.cpp397
-rwxr-xr-xCPP/7zip/UI/GUI/UpdateGUI.h20
-rwxr-xr-xCPP/7zip/UI/GUI/makefile135
-rwxr-xr-xCPP/7zip/UI/GUI/resource.h45
-rwxr-xr-xCPP/7zip/UI/GUI/resource.rc57
-rwxr-xr-xCPP/7zip/UI/Resource/CompressDialog/resource.h40
-rwxr-xr-xCPP/7zip/UI/Resource/CompressDialog/resource.rc117
-rwxr-xr-xCPP/7zip/UI/Resource/Extract/resource.h15
-rwxr-xr-xCPP/7zip/UI/Resource/Extract/resource.rc19
-rwxr-xr-xCPP/7zip/UI/Resource/ExtractDialog/resource.h26
-rwxr-xr-xCPP/7zip/UI/Resource/ExtractDialog/resource.rc80
-rwxr-xr-xCPP/7zip/UI/makefile10
-rwxr-xr-xCPP/7zip/makefile16
1030 files changed, 136605 insertions, 0 deletions
diff --git a/CPP/7zip/Archive/7z/7z.dsp b/CPP/7zip/Archive/7z/7z.dsp
new file mode 100755
index 00000000..e57115ef
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7z.dsp
@@ -0,0 +1,593 @@
+# Microsoft Developer Studio Project File - Name="7z" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=7z - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "7z.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "7z.mak" CFG="7z - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "7z - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "7z - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-zip\Formats\7z.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-zip\Formats\7z.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "7z - Win32 Release"
+# Name "7z - Win32 Debug"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Archive.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\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=.\7zCompressionMode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zCompressionMode.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zDecode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zEncode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zEncode.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zExtract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zFolderInStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zFolderInStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zFolderOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zFolderOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zHandlerOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zHeader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zMethodID.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zMethodID.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zMethods.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zMethods.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zOut.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zProperties.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zProperties.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zSpecStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zSpecStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zUpdate.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zUpdate.h
+# End Source File
+# End Group
+# Begin Group "Interface"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\IArchive.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\ICoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IMyUnknown.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IPassword.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IProgress.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\PropID.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\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\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\DynamicBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.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\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
+
+SOURCE=..\..\..\Common\Vector.h
+# End Source File
+# End Group
+# Begin Group "Archive Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Common\CodecsPath.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CodecsPath.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CoderLoader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CoderLoader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CoderMixer2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CoderMixer2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CoderMixer2MT.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CoderMixer2MT.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CrossThreadProgress.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CrossThreadProgress.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\FilterCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\FilterCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\InStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\InStreamWithCRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ItemNameUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ItemNameUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\MultiStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\MultiStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\OutStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\OutStreamWithCRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ParseProperties.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ParseProperties.h
+# End Source File
+# End Group
+# Begin Group "7-Zip Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\InOutTempBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InOutTempBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\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\StreamBinder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Handle.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Thread.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\7z.ico
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/Archive/7z/7z.dsw b/CPP/7zip/Archive/7z/7z.dsw
new file mode 100755
index 00000000..702a86c7
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7z.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "7z"=".\7z.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Archive/7z/7z.ico b/CPP/7zip/Archive/7z/7z.ico
new file mode 100755
index 00000000..319753a1
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7z.ico
Binary files differ
diff --git a/CPP/7zip/Archive/7z/7zCompressionMode.cpp b/CPP/7zip/Archive/7z/7zCompressionMode.cpp
new file mode 100755
index 00000000..6774fc48
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zCompressionMode.cpp
@@ -0,0 +1,3 @@
+// CompressionMethod.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Archive/7z/7zCompressionMode.h b/CPP/7zip/Archive/7z/7zCompressionMode.h
new file mode 100755
index 00000000..fe54e8a6
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zCompressionMode.h
@@ -0,0 +1,64 @@
+// 7zCompressionMode.h
+
+#ifndef __7Z_COMPRESSION_MODE_H
+#define __7Z_COMPRESSION_MODE_H
+
+#include "../../../Windows/PropVariant.h"
+
+#include "7zMethodID.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CProperty
+{
+ PROPID PropID;
+ NWindows::NCOM::CPropVariant Value;
+};
+
+struct CMethodFull
+{
+ CMethodID MethodID;
+ UInt32 NumInStreams;
+ UInt32 NumOutStreams;
+ bool IsSimpleCoder() const
+ { return (NumInStreams == 1) && (NumOutStreams == 1); }
+
+ #ifdef EXCLUDE_COM
+ #else
+ CLSID EncoderClassID;
+ CSysString FilePath;
+ #endif
+
+ CObjectVector<CProperty> CoderProperties;
+};
+
+struct CBind
+{
+ UInt32 InCoder;
+ UInt32 InStream;
+ UInt32 OutCoder;
+ UInt32 OutStream;
+};
+
+struct CCompressionMethodMode
+{
+ CObjectVector<CMethodFull> Methods;
+ CRecordVector<CBind> Binds;
+ #ifdef COMPRESS_MT
+ UInt32 NumThreads;
+ #endif
+ bool PasswordIsDefined;
+ UString Password;
+
+ bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
+ CCompressionMethodMode(): PasswordIsDefined(false)
+ #ifdef COMPRESS_MT
+ , NumThreads(1)
+ #endif
+ {}
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/7z/7zDecode.cpp b/CPP/7zip/Archive/7z/7zDecode.cpp
new file mode 100755
index 00000000..5c58f817
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zDecode.cpp
@@ -0,0 +1,444 @@
+// 7zDecode.cpp
+
+#include "StdAfx.h"
+
+#include "7zDecode.h"
+
+#include "../../IPassword.h"
+#include "../../Common/LockedStream.h"
+#include "../../Common/StreamObjects.h"
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/LimitedStreams.h"
+#include "../Common/FilterCoder.h"
+
+#include "7zMethods.h"
+
+#ifdef COMPRESS_LZMA
+#include "../../Compress/LZMA/LZMADecoder.h"
+static NArchive::N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
+#endif
+
+#ifdef COMPRESS_PPMD
+#include "../../Compress/PPMD/PPMDDecoder.h"
+static NArchive::N7z::CMethodID k_PPMD = { { 0x3, 0x4, 0x1 }, 3 };
+#endif
+
+#ifdef COMPRESS_BCJ_X86
+#include "../../Compress/Branch/x86.h"
+static NArchive::N7z::CMethodID k_BCJ_X86 = { { 0x3, 0x3, 0x1, 0x3 }, 4 };
+#endif
+
+#ifdef COMPRESS_BCJ2
+#include "../../Compress/Branch/x86_2.h"
+static NArchive::N7z::CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 };
+#endif
+
+#ifdef COMPRESS_DEFLATE
+#ifndef COMPRESS_DEFLATE_DECODER
+#define COMPRESS_DEFLATE_DECODER
+#endif
+#endif
+
+#ifdef COMPRESS_DEFLATE_DECODER
+#include "../../Compress/Deflate/DeflateDecoder.h"
+static NArchive::N7z::CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
+#endif
+
+#ifdef COMPRESS_BZIP2
+#ifndef COMPRESS_BZIP2_DECODER
+#define COMPRESS_BZIP2_DECODER
+#endif
+#endif
+
+#ifdef COMPRESS_BZIP2_DECODER
+#include "../../Compress/BZip2/BZip2Decoder.h"
+static NArchive::N7z::CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
+#endif
+
+#ifdef COMPRESS_COPY
+#include "../../Compress/Copy/CopyCoder.h"
+static NArchive::N7z::CMethodID k_Copy = { { 0x0 }, 1 };
+#endif
+
+#ifdef CRYPTO_7ZAES
+#include "../../Crypto/7zAES/7zAES.h"
+static NArchive::N7z::CMethodID k_7zAES = { { 0x6, 0xF1, 0x07, 0x01 }, 4 };
+#endif
+
+namespace NArchive {
+namespace N7z {
+
+static void ConvertFolderItemInfoToBindInfo(const CFolder &folder,
+ CBindInfoEx &bindInfo)
+{
+ bindInfo.Clear();
+ int i;
+ for (i = 0; i < folder.BindPairs.Size(); i++)
+ {
+ NCoderMixer2::CBindPair bindPair;
+ bindPair.InIndex = (UInt32)folder.BindPairs[i].InIndex;
+ bindPair.OutIndex = (UInt32)folder.BindPairs[i].OutIndex;
+ bindInfo.BindPairs.Add(bindPair);
+ }
+ UInt32 outStreamIndex = 0;
+ for (i = 0; i < folder.Coders.Size(); i++)
+ {
+ NCoderMixer2::CCoderStreamsInfo coderStreamsInfo;
+ const CCoderInfo &coderInfo = folder.Coders[i];
+ coderStreamsInfo.NumInStreams = (UInt32)coderInfo.NumInStreams;
+ coderStreamsInfo.NumOutStreams = (UInt32)coderInfo.NumOutStreams;
+ bindInfo.Coders.Add(coderStreamsInfo);
+ const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
+ bindInfo.CoderMethodIDs.Add(altCoderInfo.MethodID);
+ for (UInt32 j = 0; j < coderStreamsInfo.NumOutStreams; j++, outStreamIndex++)
+ if (folder.FindBindPairForOutStream(outStreamIndex) < 0)
+ bindInfo.OutStreams.Add(outStreamIndex);
+ }
+ for (i = 0; i < folder.PackStreams.Size(); i++)
+ bindInfo.InStreams.Add((UInt32)folder.PackStreams[i]);
+}
+
+static bool AreCodersEqual(const NCoderMixer2::CCoderStreamsInfo &a1,
+ const NCoderMixer2::CCoderStreamsInfo &a2)
+{
+ return (a1.NumInStreams == a2.NumInStreams) &&
+ (a1.NumOutStreams == a2.NumOutStreams);
+}
+
+static bool AreBindPairsEqual(const NCoderMixer2::CBindPair &a1, const NCoderMixer2::CBindPair &a2)
+{
+ return (a1.InIndex == a2.InIndex) &&
+ (a1.OutIndex == a2.OutIndex);
+}
+
+static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2)
+{
+ if (a1.Coders.Size() != a2.Coders.Size())
+ return false;
+ int i;
+ for (i = 0; i < a1.Coders.Size(); i++)
+ if (!AreCodersEqual(a1.Coders[i], a2.Coders[i]))
+ return false;
+ if (a1.BindPairs.Size() != a2.BindPairs.Size())
+ return false;
+ for (i = 0; i < a1.BindPairs.Size(); i++)
+ if (!AreBindPairsEqual(a1.BindPairs[i], a2.BindPairs[i]))
+ return false;
+ for (i = 0; i < a1.CoderMethodIDs.Size(); i++)
+ if (a1.CoderMethodIDs[i] != a2.CoderMethodIDs[i])
+ return false;
+ if (a1.InStreams.Size() != a2.InStreams.Size())
+ return false;
+ if (a1.OutStreams.Size() != a2.OutStreams.Size())
+ return false;
+ return true;
+}
+
+CDecoder::CDecoder(bool multiThread)
+{
+ #ifndef _ST_MODE
+ multiThread = true;
+ #endif
+ _multiThread = multiThread;
+ _bindInfoExPrevIsDefined = false;
+ #ifndef EXCLUDE_COM
+ LoadMethodMap();
+ #endif
+}
+
+HRESULT CDecoder::Decode(IInStream *inStream,
+ UInt64 startPos,
+ const UInt64 *packSizes,
+ const CFolder &folderInfo,
+ ISequentialOutStream *outStream,
+ ICompressProgressInfo *compressProgress
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPassword
+ #endif
+ #ifdef COMPRESS_MT
+ , bool mtMode, UInt32 numThreads
+ #endif
+ )
+{
+ CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
+
+ CLockedInStream lockedInStream;
+ lockedInStream.Init(inStream);
+
+ for (int j = 0; j < folderInfo.PackStreams.Size(); j++)
+ {
+ CLockedSequentialInStreamImp *lockedStreamImpSpec = new
+ CLockedSequentialInStreamImp;
+ CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec;
+ lockedStreamImpSpec->Init(&lockedInStream, startPos);
+ startPos += packSizes[j];
+
+ CLimitedSequentialInStream *streamSpec = new
+ CLimitedSequentialInStream;
+ CMyComPtr<ISequentialInStream> inStream = streamSpec;
+ streamSpec->SetStream(lockedStreamImp);
+ streamSpec->Init(packSizes[j]);
+ inStreams.Add(inStream);
+ }
+
+ int numCoders = folderInfo.Coders.Size();
+
+ CBindInfoEx bindInfo;
+ ConvertFolderItemInfoToBindInfo(folderInfo, bindInfo);
+ bool createNewCoders;
+ if (!_bindInfoExPrevIsDefined)
+ createNewCoders = true;
+ else
+ createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev);
+ if (createNewCoders)
+ {
+ int i;
+ _decoders.Clear();
+ // _decoders2.Clear();
+
+ _mixerCoder.Release();
+
+ if (_multiThread)
+ {
+ _mixerCoderMTSpec = new NCoderMixer2::CCoderMixer2MT;
+ _mixerCoder = _mixerCoderMTSpec;
+ _mixerCoderCommon = _mixerCoderMTSpec;
+ }
+ else
+ {
+ #ifdef _ST_MODE
+ _mixerCoderSTSpec = new NCoderMixer2::CCoderMixer2ST;
+ _mixerCoder = _mixerCoderSTSpec;
+ _mixerCoderCommon = _mixerCoderSTSpec;
+ #endif
+ }
+ _mixerCoderCommon->SetBindInfo(bindInfo);
+
+ for (i = 0; i < numCoders; i++)
+ {
+ const CCoderInfo &coderInfo = folderInfo.Coders[i];
+ const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
+ #ifndef EXCLUDE_COM
+ CMethodInfo methodInfo;
+ if (!GetMethodInfo(altCoderInfo.MethodID, methodInfo))
+ return E_NOTIMPL;
+ #endif
+
+ if (coderInfo.IsSimpleCoder())
+ {
+ CMyComPtr<ICompressCoder> decoder;
+ CMyComPtr<ICompressFilter> filter;
+
+ #ifdef COMPRESS_LZMA
+ if (altCoderInfo.MethodID == k_LZMA)
+ decoder = new NCompress::NLZMA::CDecoder;
+ #endif
+
+ #ifdef COMPRESS_PPMD
+ if (altCoderInfo.MethodID == k_PPMD)
+ decoder = new NCompress::NPPMD::CDecoder;
+ #endif
+
+ #ifdef COMPRESS_BCJ_X86
+ if (altCoderInfo.MethodID == k_BCJ_X86)
+ filter = new CBCJ_x86_Decoder;
+ #endif
+
+ #ifdef COMPRESS_DEFLATE_DECODER
+ if (altCoderInfo.MethodID == k_Deflate)
+ decoder = new NCompress::NDeflate::NDecoder::CCOMCoder;
+ #endif
+
+ #ifdef COMPRESS_BZIP2_DECODER
+ if (altCoderInfo.MethodID == k_BZip2)
+ decoder = new NCompress::NBZip2::CDecoder;
+ #endif
+
+ #ifdef COMPRESS_COPY
+ if (altCoderInfo.MethodID == k_Copy)
+ decoder = new NCompress::CCopyCoder;
+ #endif
+
+ #ifdef CRYPTO_7ZAES
+ if (altCoderInfo.MethodID == k_7zAES)
+ filter = new NCrypto::NSevenZ::CDecoder;
+ #endif
+
+ if (filter)
+ {
+ CFilterCoder *coderSpec = new CFilterCoder;
+ decoder = coderSpec;
+ coderSpec->Filter = filter;
+ }
+ #ifndef EXCLUDE_COM
+ if (decoder == 0)
+ {
+ RINOK(_libraries.CreateCoderSpec(methodInfo.FilePath,
+ methodInfo.Decoder, &decoder));
+ }
+ #endif
+
+ if (decoder == 0)
+ return E_NOTIMPL;
+
+ _decoders.Add((IUnknown *)decoder);
+
+ if (_multiThread)
+ _mixerCoderMTSpec->AddCoder(decoder);
+ #ifdef _ST_MODE
+ else
+ _mixerCoderSTSpec->AddCoder(decoder, false);
+ #endif
+ }
+ else
+ {
+ CMyComPtr<ICompressCoder2> decoder;
+
+ #ifdef COMPRESS_BCJ2
+ if (altCoderInfo.MethodID == k_BCJ2)
+ decoder = new CBCJ2_x86_Decoder;
+ #endif
+
+ #ifndef EXCLUDE_COM
+ if (decoder == 0)
+ {
+ RINOK(_libraries.CreateCoder2(methodInfo.FilePath,
+ methodInfo.Decoder, &decoder));
+ }
+ #endif
+
+ if (decoder == 0)
+ return E_NOTIMPL;
+
+ _decoders.Add((IUnknown *)decoder);
+ if (_multiThread)
+ _mixerCoderMTSpec->AddCoder2(decoder);
+ #ifdef _ST_MODE
+ else
+ _mixerCoderSTSpec->AddCoder2(decoder, false);
+ #endif
+ }
+ }
+ _bindInfoExPrev = bindInfo;
+ _bindInfoExPrevIsDefined = true;
+ }
+ int i;
+ _mixerCoderCommon->ReInit();
+
+ UInt32 packStreamIndex = 0, unPackStreamIndex = 0;
+ UInt32 coderIndex = 0;
+ // UInt32 coder2Index = 0;
+
+ for (i = 0; i < numCoders; i++)
+ {
+ const CCoderInfo &coderInfo = folderInfo.Coders[i];
+ const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
+ CMyComPtr<IUnknown> &decoder = _decoders[coderIndex];
+
+ {
+ CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
+ decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
+ if (setDecoderProperties)
+ {
+ const CByteBuffer &properties = altCoderInfo.Properties;
+ size_t size = properties.GetCapacity();
+ if (size > 0xFFFFFFFF)
+ return E_NOTIMPL;
+ if (size > 0)
+ {
+ RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)properties, (UInt32)size));
+ }
+ }
+ }
+
+ #ifdef COMPRESS_MT
+ if (mtMode)
+ {
+ CMyComPtr<ICompressSetCoderMt> setCoderMt;
+ decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
+ if (setCoderMt)
+ {
+ RINOK(setCoderMt->SetNumberOfThreads(numThreads));
+ }
+ }
+ #endif
+
+ #ifndef _NO_CRYPTO
+ {
+ CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
+ decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
+ if (cryptoSetPassword)
+ {
+ if (getTextPassword == 0)
+ return E_FAIL;
+ CMyComBSTR password;
+ RINOK(getTextPassword->CryptoGetTextPassword(&password));
+ CByteBuffer buffer;
+ UString unicodePassword(password);
+ 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(cryptoSetPassword->CryptoSetPassword(
+ (const Byte *)buffer, sizeInBytes));
+ }
+ }
+ #endif
+
+ coderIndex++;
+
+ UInt32 numInStreams = (UInt32)coderInfo.NumInStreams;
+ UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams;
+ CRecordVector<const UInt64 *> packSizesPointers;
+ CRecordVector<const UInt64 *> unPackSizesPointers;
+ packSizesPointers.Reserve(numInStreams);
+ unPackSizesPointers.Reserve(numOutStreams);
+ UInt32 j;
+ for (j = 0; j < numOutStreams; j++, unPackStreamIndex++)
+ unPackSizesPointers.Add(&folderInfo.UnPackSizes[unPackStreamIndex]);
+
+ for (j = 0; j < numInStreams; j++, packStreamIndex++)
+ {
+ int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex);
+ if (bindPairIndex >= 0)
+ packSizesPointers.Add(
+ &folderInfo.UnPackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]);
+ else
+ {
+ int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex);
+ if (index < 0)
+ return E_FAIL;
+ packSizesPointers.Add(&packSizes[index]);
+ }
+ }
+
+ _mixerCoderCommon->SetCoderInfo(i,
+ &packSizesPointers.Front(),
+ &unPackSizesPointers.Front());
+ }
+ UInt32 mainCoder, temp;
+ bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp);
+
+ if (_multiThread)
+ _mixerCoderMTSpec->SetProgressCoderIndex(mainCoder);
+ /*
+ else
+ _mixerCoderSTSpec->SetProgressCoderIndex(mainCoder);;
+ */
+
+ if (numCoders == 0)
+ return 0;
+ CRecordVector<ISequentialInStream *> inStreamPointers;
+ inStreamPointers.Reserve(inStreams.Size());
+ for (i = 0; i < inStreams.Size(); i++)
+ inStreamPointers.Add(inStreams[i]);
+ ISequentialOutStream *outStreamPointer = outStream;
+ return _mixerCoder->Code(&inStreamPointers.Front(), NULL,
+ inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress);
+}
+
+}}
diff --git a/CPP/7zip/Archive/7z/7zDecode.h b/CPP/7zip/Archive/7z/7zDecode.h
new file mode 100755
index 00000000..50f80d4c
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zDecode.h
@@ -0,0 +1,71 @@
+// 7zDecode.h
+
+#ifndef __7Z_DECODE_H
+#define __7Z_DECODE_H
+
+#include "../../IStream.h"
+#include "../../IPassword.h"
+
+#include "../Common/CoderMixer2.h"
+#include "../Common/CoderMixer2MT.h"
+#ifdef _ST_MODE
+#include "../Common/CoderMixer2ST.h"
+#endif
+#ifndef EXCLUDE_COM
+#include "../Common/CoderLoader.h"
+#endif
+
+#include "7zItem.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CBindInfoEx: public NCoderMixer2::CBindInfo
+{
+ CRecordVector<CMethodID> CoderMethodIDs;
+ void Clear()
+ {
+ CBindInfo::Clear();
+ CoderMethodIDs.Clear();
+ }
+};
+
+class CDecoder
+{
+ #ifndef EXCLUDE_COM
+ CCoderLibraries _libraries;
+ #endif
+
+ bool _bindInfoExPrevIsDefined;
+ CBindInfoEx _bindInfoExPrev;
+
+ bool _multiThread;
+ #ifdef _ST_MODE
+ NCoderMixer2::CCoderMixer2ST *_mixerCoderSTSpec;
+ #endif
+ NCoderMixer2::CCoderMixer2MT *_mixerCoderMTSpec;
+ NCoderMixer2::CCoderMixer2 *_mixerCoderCommon;
+
+ CMyComPtr<ICompressCoder2> _mixerCoder;
+ CObjectVector<CMyComPtr<IUnknown> > _decoders;
+ // CObjectVector<CMyComPtr<ICompressCoder2> > _decoders2;
+public:
+ CDecoder(bool multiThread);
+ HRESULT Decode(IInStream *inStream,
+ UInt64 startPos,
+ const UInt64 *packSizes,
+ const CFolder &folder,
+ ISequentialOutStream *outStream,
+ ICompressProgressInfo *compressProgress
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPasswordSpec
+ #endif
+ #ifdef COMPRESS_MT
+ , bool mtMode, UInt32 numThreads
+ #endif
+ );
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/7z/7zEncode.cpp b/CPP/7zip/Archive/7z/7zEncode.cpp
new file mode 100755
index 00000000..a9fe2d0a
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zEncode.cpp
@@ -0,0 +1,614 @@
+// Encode.cpp
+
+#include "StdAfx.h"
+
+#include "7zEncode.h"
+#include "7zSpecStream.h"
+#include "7zMethods.h"
+
+#include "../../IPassword.h"
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/LimitedStreams.h"
+#include "../../Common/InOutTempBuffer.h"
+#include "../../Common/StreamObjects.h"
+#include "../Common/FilterCoder.h"
+
+#ifdef COMPRESS_COPY
+static NArchive::N7z::CMethodID k_Copy = { { 0x0 }, 1 };
+#include "../../Compress/Copy/CopyCoder.h"
+#endif
+
+static NArchive::N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
+static NArchive::N7z::CMethodID k_LZMA2 = { { 0x3, 0x1, 0x2 }, 3 };
+
+#ifdef COMPRESS_LZMA
+#include "../../Compress/LZMA/LZMAEncoder.h"
+#endif
+
+#ifdef COMPRESS_PPMD
+#include "../../Compress/PPMD/PPMDEncoder.h"
+static NArchive::N7z::CMethodID k_PPMD = { { 0x3, 0x4, 0x1 }, 3 };
+#endif
+
+#ifdef COMPRESS_BCJ_X86
+static NArchive::N7z::CMethodID k_BCJ_X86 = { { 0x3, 0x3, 0x1, 0x3 }, 4 };
+#include "../../Compress/Branch/x86.h"
+#endif
+
+#ifdef COMPRESS_BCJ2
+static NArchive::N7z::CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 };
+#include "../../Compress/Branch/x86_2.h"
+#endif
+
+#ifdef COMPRESS_DEFLATE
+#ifndef COMPRESS_DEFLATE_ENCODER
+#define COMPRESS_DEFLATE_ENCODER
+#endif
+#endif
+
+#ifdef COMPRESS_DEFLATE_ENCODER
+#include "../../Compress/Deflate/DeflateEncoder.h"
+static NArchive::N7z::CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
+#endif
+
+#ifdef COMPRESS_BZIP2
+#ifndef COMPRESS_BZIP2_ENCODER
+#define COMPRESS_BZIP2_ENCODER
+#endif
+#endif
+
+#ifdef COMPRESS_BZIP2_ENCODER
+#include "../../Compress/BZip2/BZip2Encoder.h"
+static NArchive::N7z::CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
+#endif
+
+static NArchive::N7z::CMethodID k_AES = { { 0x6, 0xF1, 0x7, 0x1}, 4 };
+
+#ifndef EXCLUDE_COM
+static const wchar_t *kCryproMethod = L"7zAES";
+/*
+// {23170F69-40C1-278B-06F1-070100000100}
+DEFINE_GUID(CLSID_CCrypto7zAESEncoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x07, 0x01, 0x00, 0x00, 0x01, 0x00);
+*/
+#endif
+
+#ifdef CRYPTO_7ZAES
+#include "../../Crypto/7zAES/7zAES.h"
+#endif
+
+namespace NArchive {
+namespace N7z {
+
+static void ConvertBindInfoToFolderItemInfo(const NCoderMixer2::CBindInfo &bindInfo,
+ const CRecordVector<CMethodID> decompressionMethods,
+ CFolder &folder)
+{
+ folder.Coders.Clear();
+ // bindInfo.CoderMethodIDs.Clear();
+ // folder.OutStreams.Clear();
+ folder.PackStreams.Clear();
+ folder.BindPairs.Clear();
+ int i;
+ for (i = 0; i < bindInfo.BindPairs.Size(); i++)
+ {
+ CBindPair bindPair;
+ bindPair.InIndex = bindInfo.BindPairs[i].InIndex;
+ bindPair.OutIndex = bindInfo.BindPairs[i].OutIndex;
+ folder.BindPairs.Add(bindPair);
+ }
+ for (i = 0; i < bindInfo.Coders.Size(); i++)
+ {
+ CCoderInfo coderInfo;
+ const NCoderMixer2::CCoderStreamsInfo &coderStreamsInfo = bindInfo.Coders[i];
+ coderInfo.NumInStreams = coderStreamsInfo.NumInStreams;
+ coderInfo.NumOutStreams = coderStreamsInfo.NumOutStreams;
+
+ // coderInfo.MethodID = decompressionMethods[i];
+ // if (coderInfo.AltCoders.Size() == 0)
+ coderInfo.AltCoders.Add(CAltCoderInfo());
+ CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
+ altCoderInfo.MethodID = decompressionMethods[i];
+
+ folder.Coders.Add(coderInfo);
+ }
+ for (i = 0; i < bindInfo.InStreams.Size(); i++)
+ folder.PackStreams.Add(bindInfo.InStreams[i]);
+}
+
+HRESULT CEncoder::CreateMixerCoder(const UInt64 *inSizeForReduce)
+{
+ _mixerCoderSpec = new NCoderMixer2::CCoderMixer2MT;
+ _mixerCoder = _mixerCoderSpec;
+ _mixerCoderSpec->SetBindInfo(_bindInfo);
+ for (int i = 0; i < _options.Methods.Size(); i++)
+ {
+ const CMethodFull &methodFull = _options.Methods[i];
+ _codersInfo.Add(CCoderInfo());
+ CCoderInfo &encodingInfo = _codersInfo.Back();
+ CMyComPtr<ICompressCoder> encoder;
+ CMyComPtr<ICompressFilter> filter;
+ CMyComPtr<ICompressCoder2> encoder2;
+
+ if (methodFull.IsSimpleCoder())
+ {
+ #ifdef COMPRESS_LZMA
+ if (methodFull.MethodID == k_LZMA)
+ encoder = new NCompress::NLZMA::CEncoder;
+ #endif
+
+ #ifdef COMPRESS_PPMD
+ if (methodFull.MethodID == k_PPMD)
+ encoder = new NCompress::NPPMD::CEncoder;
+ #endif
+
+ #ifdef COMPRESS_BCJ_X86
+ if (methodFull.MethodID == k_BCJ_X86)
+ filter = new CBCJ_x86_Encoder;
+ #endif
+
+ #ifdef COMPRESS_COPY
+ if (methodFull.MethodID == k_Copy)
+ encoder = new NCompress::CCopyCoder;
+ #endif
+
+ #ifdef COMPRESS_BZIP2_ENCODER
+ if (methodFull.MethodID == k_BZip2)
+ encoder = new NCompress::NBZip2::CEncoder;
+ #endif
+
+ #ifdef COMPRESS_DEFLATE_ENCODER
+ if (methodFull.MethodID == k_Deflate)
+ encoder = new NCompress::NDeflate::NEncoder::CCOMCoder;
+ #endif
+
+ #ifdef CRYPTO_7ZAES
+ if (methodFull.MethodID == k_AES)
+ filter = new NCrypto::NSevenZ::CEncoder;
+ #endif
+
+ if (filter)
+ {
+ CFilterCoder *coderSpec = new CFilterCoder;
+ encoder = coderSpec;
+ coderSpec->Filter = filter;
+ }
+
+ #ifndef EXCLUDE_COM
+ if (encoder == 0)
+ {
+ RINOK(_libraries.CreateCoderSpec(methodFull.FilePath,
+ methodFull.EncoderClassID, &encoder));
+ }
+ #endif
+
+ if (encoder == 0)
+ return E_FAIL;
+
+ }
+ else
+ {
+ #ifdef COMPRESS_BCJ2
+ if (methodFull.MethodID == k_BCJ2)
+ encoder2 = new CBCJ2_x86_Encoder;
+ #endif
+
+ #ifndef EXCLUDE_COM
+ if (encoder2 == 0)
+ {
+ RINOK(_libraries.CreateCoder2(methodFull.FilePath,
+ methodFull.EncoderClassID, &encoder2));
+ }
+ #else
+
+ if (encoder2 == 0)
+ return E_FAIL;
+ #endif
+ }
+
+ bool tryReduce = false;
+ UInt32 reducedDictionarySize = 1 << 10;
+ if (inSizeForReduce != 0 && (methodFull.MethodID == k_LZMA || methodFull.MethodID == k_LZMA2))
+ {
+ for (;;)
+ {
+ const UInt32 step = (reducedDictionarySize >> 1);
+ if (reducedDictionarySize >= *inSizeForReduce)
+ {
+ tryReduce = true;
+ break;
+ }
+ reducedDictionarySize += step;
+ if (reducedDictionarySize >= *inSizeForReduce)
+ {
+ tryReduce = true;
+ break;
+ }
+ if (reducedDictionarySize >= ((UInt32)11 << 30))
+ break;
+ reducedDictionarySize += step;
+ }
+ }
+
+ CMyComPtr<IUnknown> encoderCommon = methodFull.IsSimpleCoder() ? (IUnknown *)encoder : (IUnknown *)encoder2;
+
+ #ifdef COMPRESS_MT
+ {
+ CMyComPtr<ICompressSetCoderMt> setCoderMt;
+ encoderCommon.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
+ if (setCoderMt)
+ {
+ RINOK(setCoderMt->SetNumberOfThreads(_options.NumThreads));
+ }
+ }
+ #endif
+
+ if (methodFull.CoderProperties.Size() > 0)
+ {
+ CRecordVector<PROPID> propIDs;
+ int numProperties = methodFull.CoderProperties.Size();
+ NWindows::NCOM::CPropVariant *values = new NWindows::NCOM::CPropVariant[numProperties];
+ try
+ {
+ for (int i = 0; i < numProperties; i++)
+ {
+ const CProperty &property = methodFull.CoderProperties[i];
+ propIDs.Add(property.PropID);
+ NWindows::NCOM::CPropVariant value = property.Value;
+ if (tryReduce && property.PropID == NCoderPropID::kDictionarySize && value.vt == VT_UI4 && reducedDictionarySize < value.ulVal)
+ value.ulVal = reducedDictionarySize;
+ values[i] = value;
+ }
+ CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
+ RINOK(encoderCommon.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties));
+ RINOK(setCoderProperties->SetCoderProperties(&propIDs.Front(), values, numProperties));
+ }
+ catch(...)
+ {
+ delete []values;
+ throw;
+ }
+ delete []values;
+ }
+
+ CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
+
+ encoderCommon.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProperties);
+
+ if (writeCoderProperties != NULL)
+ {
+ CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
+ CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
+ outStreamSpec->Init();
+ writeCoderProperties->WriteCoderProperties(outStream);
+
+ size_t size = outStreamSpec->GetSize();
+
+ // encodingInfo.Properties.SetCapacity(size);
+ if (encodingInfo.AltCoders.Size() == 0)
+ encodingInfo.AltCoders.Add(CAltCoderInfo());
+ CAltCoderInfo &altCoderInfo = encodingInfo.AltCoders.Front();
+ altCoderInfo.Properties.SetCapacity(size);
+
+ memmove(altCoderInfo.Properties, outStreamSpec->GetBuffer(), size);
+ }
+
+ CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
+ encoderCommon.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
+
+ if (cryptoSetPassword)
+ {
+ CByteBuffer buffer;
+ const UInt32 sizeInBytes = _options.Password.Length() * 2;
+ buffer.SetCapacity(sizeInBytes);
+ for (int i = 0; i < _options.Password.Length(); i++)
+ {
+ wchar_t c = _options.Password[i];
+ ((Byte *)buffer)[i * 2] = (Byte)c;
+ ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
+ }
+ RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes));
+ }
+
+ if (methodFull.IsSimpleCoder())
+ _mixerCoderSpec->AddCoder(encoder);
+ else
+ _mixerCoderSpec->AddCoder2(encoder2);
+ }
+ return S_OK;
+}
+
+HRESULT CEncoder::Encode(ISequentialInStream *inStream,
+ const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
+ CFolder &folderItem,
+ ISequentialOutStream *outStream,
+ CRecordVector<UInt64> &packSizes,
+ ICompressProgressInfo *compressProgress)
+{
+ if (_mixerCoderSpec == NULL)
+ {
+ RINOK(CreateMixerCoder(inSizeForReduce));
+ }
+ _mixerCoderSpec->ReInit();
+ // _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress);
+
+ CObjectVector<CInOutTempBuffer> inOutTempBuffers;
+ CObjectVector<CSequentialOutTempBufferImp *> tempBufferSpecs;
+ CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers;
+ int numMethods = _bindInfo.Coders.Size();
+ int i;
+ for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
+ {
+ inOutTempBuffers.Add(CInOutTempBuffer());
+ inOutTempBuffers.Back().Create();
+ inOutTempBuffers.Back().InitWriting();
+ }
+ for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
+ {
+ CSequentialOutTempBufferImp *tempBufferSpec =
+ new CSequentialOutTempBufferImp;
+ CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;
+ tempBufferSpec->Init(&inOutTempBuffers[i - 1]);
+ tempBuffers.Add(tempBuffer);
+ tempBufferSpecs.Add(tempBufferSpec);
+ }
+
+ for (i = 0; i < numMethods; i++)
+ _mixerCoderSpec->SetCoderInfo(i, NULL, NULL);
+
+ if (_bindInfo.InStreams.IsEmpty())
+ return E_FAIL;
+ UInt32 mainCoderIndex, mainStreamIndex;
+ _bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex);
+ _mixerCoderSpec->SetProgressCoderIndex(mainCoderIndex);
+ if (inStreamSize != NULL)
+ {
+ CRecordVector<const UInt64 *> sizePointers;
+ for (UInt32 i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++)
+ if (i == mainStreamIndex)
+ sizePointers.Add(inStreamSize);
+ else
+ sizePointers.Add(NULL);
+ _mixerCoderSpec->SetCoderInfo(mainCoderIndex, &sizePointers.Front(), NULL);
+ }
+
+
+ // UInt64 outStreamStartPos;
+ // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));
+
+ CSequentialInStreamSizeCount2 *inStreamSizeCountSpec =
+ new CSequentialInStreamSizeCount2;
+ CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
+ CSequentialOutStreamSizeCount *outStreamSizeCountSpec =
+ new CSequentialOutStreamSizeCount;
+ CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec;
+
+ inStreamSizeCountSpec->Init(inStream);
+ outStreamSizeCountSpec->SetStream(outStream);
+ outStreamSizeCountSpec->Init();
+
+ CRecordVector<ISequentialInStream *> inStreamPointers;
+ CRecordVector<ISequentialOutStream *> outStreamPointers;
+ inStreamPointers.Add(inStreamSizeCount);
+ outStreamPointers.Add(outStreamSizeCount);
+ for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
+ outStreamPointers.Add(tempBuffers[i - 1]);
+
+ RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
+ &outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));
+
+ ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods,
+ folderItem);
+
+ packSizes.Add(outStreamSizeCountSpec->GetSize());
+
+ for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
+ {
+ CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1];
+ inOutTempBuffer.FlushWrite();
+ inOutTempBuffer.InitReading();
+ inOutTempBuffer.WriteToStream(outStream);
+ packSizes.Add(inOutTempBuffer.GetDataSize());
+ }
+
+ for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++)
+ {
+ int binder = _bindInfo.FindBinderForInStream(
+ _bindReverseConverter->DestOutToSrcInMap[i]);
+ UInt64 streamSize;
+ if (binder < 0)
+ streamSize = inStreamSizeCountSpec->GetSize();
+ else
+ streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder);
+ folderItem.UnPackSizes.Add(streamSize);
+ }
+ for (i = numMethods - 1; i >= 0; i--)
+ {
+ // folderItem.Coders[numMethods - 1 - i].Properties = _codersInfo[i].Properties;
+ for (int j = 0; j < _codersInfo[i].AltCoders.Size(); j++)
+ folderItem.Coders[numMethods - 1 - i].AltCoders[j].Properties
+ = _codersInfo[i].AltCoders[j].Properties;
+ }
+ return S_OK;
+}
+
+
+CEncoder::CEncoder(const CCompressionMethodMode &options):
+ _bindReverseConverter(0)
+{
+ if (options.IsEmpty())
+ throw 1;
+
+ _options = options;
+ _mixerCoderSpec = NULL;
+
+ if (options.Methods.IsEmpty())
+ {
+ // it has only password method;
+ if (!options.PasswordIsDefined)
+ throw 1;
+ if (!options.Binds.IsEmpty())
+ throw 1;
+ NCoderMixer2::CCoderStreamsInfo coderStreamsInfo;
+ CMethodFull method;
+
+ method.NumInStreams = 1;
+ method.NumOutStreams = 1;
+ coderStreamsInfo.NumInStreams = method.NumOutStreams;
+ coderStreamsInfo.NumOutStreams = method.NumInStreams;
+ method.MethodID = k_AES;
+
+
+ #ifndef EXCLUDE_COM
+ CMethodInfo2 methodInfo;
+ if (!GetMethodInfo(kCryproMethod, methodInfo))
+ throw 2;
+ method.FilePath = methodInfo.FilePath;
+ method.EncoderClassID = methodInfo.Encoder;
+ // method.EncoderClassID = CLSID_CCrypto7zAESEncoder;
+ #endif
+
+ _options.Methods.Add(method);
+ _bindInfo.Coders.Add(coderStreamsInfo);
+
+ _bindInfo.InStreams.Add(0);
+ _bindInfo.OutStreams.Add(0);
+ }
+ else
+ {
+
+ UInt32 numInStreams = 0, numOutStreams = 0;
+ int i;
+ for (i = 0; i < options.Methods.Size(); i++)
+ {
+ const CMethodFull &methodFull = options.Methods[i];
+ NCoderMixer2::CCoderStreamsInfo coderStreamsInfo;
+ coderStreamsInfo.NumInStreams = methodFull.NumOutStreams;
+ coderStreamsInfo.NumOutStreams = methodFull.NumInStreams;
+ if (options.Binds.IsEmpty())
+ {
+ if (i < options.Methods.Size() - 1)
+ {
+ NCoderMixer2::CBindPair bindPair;
+ bindPair.InIndex = numInStreams + coderStreamsInfo.NumInStreams;
+ bindPair.OutIndex = numOutStreams;
+ _bindInfo.BindPairs.Add(bindPair);
+ }
+ else
+ _bindInfo.OutStreams.Insert(0, numOutStreams);
+ for (UInt32 j = 1; j < coderStreamsInfo.NumOutStreams; j++)
+ _bindInfo.OutStreams.Add(numOutStreams + j);
+ }
+
+ numInStreams += coderStreamsInfo.NumInStreams;
+ numOutStreams += coderStreamsInfo.NumOutStreams;
+
+ _bindInfo.Coders.Add(coderStreamsInfo);
+ }
+
+ if (!options.Binds.IsEmpty())
+ {
+ for (i = 0; i < options.Binds.Size(); i++)
+ {
+ NCoderMixer2::CBindPair bindPair;
+ const CBind &bind = options.Binds[i];
+ bindPair.InIndex = _bindInfo.GetCoderInStreamIndex(bind.InCoder) + bind.InStream;
+ bindPair.OutIndex = _bindInfo.GetCoderOutStreamIndex(bind.OutCoder) + bind.OutStream;
+ _bindInfo.BindPairs.Add(bindPair);
+ }
+ for (i = 0; i < (int)numOutStreams; i++)
+ if (_bindInfo.FindBinderForOutStream(i) == -1)
+ _bindInfo.OutStreams.Add(i);
+ }
+
+ for (i = 0; i < (int)numInStreams; i++)
+ if (_bindInfo.FindBinderForInStream(i) == -1)
+ _bindInfo.InStreams.Add(i);
+
+ if (_bindInfo.InStreams.IsEmpty())
+ throw 1; // this is error
+
+ // Make main stream first in list
+ int inIndex = _bindInfo.InStreams[0];
+ for (;;)
+ {
+ UInt32 coderIndex, coderStreamIndex;
+ _bindInfo.FindInStream(inIndex, coderIndex, coderStreamIndex);
+ UInt32 outIndex = _bindInfo.GetCoderOutStreamIndex(coderIndex);
+ int binder = _bindInfo.FindBinderForOutStream(outIndex);
+ if (binder >= 0)
+ {
+ inIndex = _bindInfo.BindPairs[binder].InIndex;
+ continue;
+ }
+ for (i = 0; i < _bindInfo.OutStreams.Size(); i++)
+ if (_bindInfo.OutStreams[i] == outIndex)
+ {
+ _bindInfo.OutStreams.Delete(i);
+ _bindInfo.OutStreams.Insert(0, outIndex);
+ break;
+ }
+ break;
+ }
+
+ if (_options.PasswordIsDefined)
+ {
+ int numCryptoStreams = _bindInfo.OutStreams.Size();
+
+ for (i = 0; i < numCryptoStreams; i++)
+ {
+ NCoderMixer2::CBindPair bindPair;
+ bindPair.InIndex = numInStreams + i;
+ bindPair.OutIndex = _bindInfo.OutStreams[i];
+ _bindInfo.BindPairs.Add(bindPair);
+ }
+ _bindInfo.OutStreams.Clear();
+
+ /*
+ if (numCryptoStreams == 0)
+ numCryptoStreams = 1;
+ */
+
+ for (i = 0; i < numCryptoStreams; i++)
+ {
+ NCoderMixer2::CCoderStreamsInfo coderStreamsInfo;
+ CMethodFull method;
+ method.NumInStreams = 1;
+ method.NumOutStreams = 1;
+ coderStreamsInfo.NumInStreams = method.NumOutStreams;
+ coderStreamsInfo.NumOutStreams = method.NumInStreams;
+ method.MethodID = k_AES;
+
+ #ifndef EXCLUDE_COM
+ CMethodInfo2 methodInfo;
+ if (!GetMethodInfo(kCryproMethod, methodInfo))
+ throw 2;
+ method.FilePath = methodInfo.FilePath;
+ method.EncoderClassID = methodInfo.Encoder;
+ // method.EncoderClassID = CLSID_CCrypto7zAESEncoder;
+ #endif
+
+ _options.Methods.Add(method);
+ _bindInfo.Coders.Add(coderStreamsInfo);
+ _bindInfo.OutStreams.Add(numOutStreams + i);
+ }
+ }
+
+ }
+
+ for (int i = _options.Methods.Size() - 1; i >= 0; i--)
+ {
+ const CMethodFull &methodFull = _options.Methods[i];
+ _decompressionMethods.Add(methodFull.MethodID);
+ }
+
+ _bindReverseConverter = new NCoderMixer2::CBindReverseConverter(_bindInfo);
+ _bindReverseConverter->CreateReverseBindInfo(_decompressBindInfo);
+}
+
+CEncoder::~CEncoder()
+{
+ delete _bindReverseConverter;
+}
+
+}}
diff --git a/CPP/7zip/Archive/7z/7zEncode.h b/CPP/7zip/Archive/7z/7zEncode.h
new file mode 100755
index 00000000..efd8bba6
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zEncode.h
@@ -0,0 +1,58 @@
+// 7zEncode.h
+
+#ifndef __7Z_ENCODE_H
+#define __7Z_ENCODE_H
+
+// #include "../../Common/StreamObjects.h"
+
+#include "7zCompressionMode.h"
+
+#include "../Common/CoderMixer2.h"
+#include "../Common/CoderMixer2MT.h"
+#ifdef _ST_MODE
+#include "../Common/CoderMixer2ST.h"
+#endif
+#ifndef EXCLUDE_COM
+#include "../Common/CoderLoader.h"
+#endif
+#include "7zMethods.h"
+#include "7zItem.h"
+
+namespace NArchive {
+namespace N7z {
+
+class CEncoder
+{
+ #ifndef EXCLUDE_COM
+ // CMethodMap _methodMap;
+ // it must be in top of objects
+ CCoderLibraries _libraries;
+ #endif
+
+ NCoderMixer2::CCoderMixer2MT *_mixerCoderSpec;
+ CMyComPtr<ICompressCoder2> _mixerCoder;
+
+ CObjectVector<CCoderInfo> _codersInfo;
+
+ CCompressionMethodMode _options;
+ NCoderMixer2::CBindInfo _bindInfo;
+ NCoderMixer2::CBindInfo _decompressBindInfo;
+ NCoderMixer2::CBindReverseConverter *_bindReverseConverter;
+ CRecordVector<CMethodID> _decompressionMethods;
+
+ HRESULT CreateMixerCoder(const UInt64 *inSizeForReduce);
+
+public:
+ CEncoder(const CCompressionMethodMode &options);
+ ~CEncoder();
+ HRESULT Encode(ISequentialInStream *inStream,
+ const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
+ CFolder &folderItem,
+ ISequentialOutStream *outStream,
+ CRecordVector<UInt64> &packSizes,
+ ICompressProgressInfo *compressProgress);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/7z/7zExtract.cpp b/CPP/7zip/Archive/7z/7zExtract.cpp
new file mode 100755
index 00000000..540241f7
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zExtract.cpp
@@ -0,0 +1,265 @@
+// 7zExtract.cpp
+
+#include "StdAfx.h"
+
+#include "7zHandler.h"
+#include "7zFolderOutStream.h"
+#include "7zMethods.h"
+#include "7zDecode.h"
+// #include "7z1Decode.h"
+
+#include "../../../Common/ComTry.h"
+#include "../../Common/StreamObjects.h"
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/LimitedStreams.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CExtractFolderInfo
+{
+ #ifdef _7Z_VOL
+ int VolumeIndex;
+ #endif
+ CNum FileIndex;
+ CNum FolderIndex;
+ CBoolVector ExtractStatuses;
+ UInt64 UnPackSize;
+ CExtractFolderInfo(
+ #ifdef _7Z_VOL
+ int volumeIndex,
+ #endif
+ CNum fileIndex, CNum folderIndex):
+ #ifdef _7Z_VOL
+ VolumeIndex(volumeIndex),
+ #endif
+ FileIndex(fileIndex),
+ FolderIndex(folderIndex),
+ UnPackSize(0)
+ {
+ if (fileIndex != kNumNoIndex)
+ {
+ ExtractStatuses.Reserve(1);
+ ExtractStatuses.Add(true);
+ }
+ };
+};
+
+STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
+ Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)
+{
+ COM_TRY_BEGIN
+ bool testMode = (testModeSpec != 0);
+ CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
+ UInt64 importantTotalUnPacked = 0;
+
+ bool allFilesMode = (numItems == UInt32(-1));
+ if (allFilesMode)
+ numItems =
+ #ifdef _7Z_VOL
+ _refs.Size();
+ #else
+ _database.Files.Size();
+ #endif
+
+ if(numItems == 0)
+ return S_OK;
+
+ /*
+ if(_volumes.Size() != 1)
+ return E_FAIL;
+ const CVolume &volume = _volumes.Front();
+ const CArchiveDatabaseEx &_database = volume.Database;
+ IInStream *_inStream = volume.Stream;
+ */
+
+ CObjectVector<CExtractFolderInfo> extractFolderInfoVector;
+ for(UInt32 ii = 0; ii < numItems; ii++)
+ {
+ // UInt32 fileIndex = allFilesMode ? indexIndex : indices[indexIndex];
+ UInt32 ref2Index = allFilesMode ? ii : indices[ii];
+ // const CRef2 &ref2 = _refs[ref2Index];
+
+ // for(UInt32 ri = 0; ri < ref2.Refs.Size(); ri++)
+ {
+ #ifdef _7Z_VOL
+ // const CRef &ref = ref2.Refs[ri];
+ const CRef &ref = _refs[ref2Index];
+
+ int volumeIndex = ref.VolumeIndex;
+ const CVolume &volume = _volumes[volumeIndex];
+ const CArchiveDatabaseEx &database = volume.Database;
+ UInt32 fileIndex = ref.ItemIndex;
+ #else
+ const CArchiveDatabaseEx &database = _database;
+ UInt32 fileIndex = ref2Index;
+ #endif
+
+ CNum folderIndex = database.FileIndexToFolderIndexMap[fileIndex];
+ if (folderIndex == kNumNoIndex)
+ {
+ extractFolderInfoVector.Add(CExtractFolderInfo(
+ #ifdef _7Z_VOL
+ volumeIndex,
+ #endif
+ fileIndex, kNumNoIndex));
+ continue;
+ }
+ if (extractFolderInfoVector.IsEmpty() ||
+ folderIndex != extractFolderInfoVector.Back().FolderIndex
+ #ifdef _7Z_VOL
+ || volumeIndex != extractFolderInfoVector.Back().VolumeIndex
+ #endif
+ )
+ {
+ extractFolderInfoVector.Add(CExtractFolderInfo(
+ #ifdef _7Z_VOL
+ volumeIndex,
+ #endif
+ kNumNoIndex, folderIndex));
+ const CFolder &folderInfo = database.Folders[folderIndex];
+ UInt64 unPackSize = folderInfo.GetUnPackSize();
+ importantTotalUnPacked += unPackSize;
+ extractFolderInfoVector.Back().UnPackSize = unPackSize;
+ }
+
+ CExtractFolderInfo &efi = extractFolderInfoVector.Back();
+
+ // const CFolderInfo &folderInfo = m_dam_Folders[folderIndex];
+ CNum startIndex = database.FolderStartFileIndex[folderIndex];
+ for (CNum index = efi.ExtractStatuses.Size();
+ index <= fileIndex - startIndex; index++)
+ {
+ // UInt64 unPackSize = _database.Files[startIndex + index].UnPackSize;
+ // Count partial_folder_size
+ // efi.UnPackSize += unPackSize;
+ // importantTotalUnPacked += unPackSize;
+ efi.ExtractStatuses.Add(index == fileIndex - startIndex);
+ }
+ }
+ }
+
+ extractCallback->SetTotal(importantTotalUnPacked);
+
+ CDecoder decoder(
+ #ifdef _ST_MODE
+ false
+ #else
+ true
+ #endif
+ );
+ // CDecoder1 decoder;
+
+ UInt64 currentImportantTotalUnPacked = 0;
+ UInt64 totalFolderUnPacked;
+
+ for(int i = 0; i < extractFolderInfoVector.Size(); i++,
+ currentImportantTotalUnPacked += totalFolderUnPacked)
+ {
+ const CExtractFolderInfo &efi = extractFolderInfoVector[i];
+ totalFolderUnPacked = efi.UnPackSize;
+
+ RINOK(extractCallback->SetCompleted(&currentImportantTotalUnPacked));
+
+ CFolderOutStream *folderOutStream = new CFolderOutStream;
+ CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
+
+ #ifdef _7Z_VOL
+ const CVolume &volume = _volumes[efi.VolumeIndex];
+ const CArchiveDatabaseEx &database = volume.Database;
+ #else
+ const CArchiveDatabaseEx &database = _database;
+ #endif
+
+ CNum startIndex;
+ if (efi.FileIndex != kNumNoIndex)
+ startIndex = efi.FileIndex;
+ else
+ startIndex = database.FolderStartFileIndex[efi.FolderIndex];
+
+
+ HRESULT result = folderOutStream->Init(&database,
+ #ifdef _7Z_VOL
+ volume.StartRef2Index,
+ #else
+ 0,
+ #endif
+ startIndex,
+ &efi.ExtractStatuses, extractCallback, testMode);
+
+ RINOK(result);
+
+ if (efi.FileIndex != kNumNoIndex)
+ continue;
+
+ CNum folderIndex = efi.FolderIndex;
+ const CFolder &folderInfo = database.Folders[folderIndex];
+
+ 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);
+
+ CNum packStreamIndex = database.FolderStartPackStreamIndex[folderIndex];
+ UInt64 folderStartPackPos = database.GetFolderStreamPos(folderIndex, 0);
+
+ #ifndef _NO_CRYPTO
+ CMyComPtr<ICryptoGetTextPassword> getTextPassword;
+ if (extractCallback)
+ extractCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
+ #endif
+
+ try
+ {
+ HRESULT result = decoder.Decode(
+ #ifdef _7Z_VOL
+ volume.Stream,
+ #else
+ _inStream,
+ #endif
+ folderStartPackPos,
+ &database.PackSizes[packStreamIndex],
+ folderInfo,
+ outStream,
+ compressProgress
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ #ifdef COMPRESS_MT
+ , true, _numThreads
+ #endif
+ );
+
+ if (result == S_FALSE)
+ {
+ RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ if (result == E_NOTIMPL)
+ {
+ RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+ continue;
+ }
+ if (result != S_OK)
+ return result;
+ if (folderOutStream->WasWritingFinished() != S_OK)
+ {
+ RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ }
+ catch(...)
+ {
+ RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+}}
diff --git a/CPP/7zip/Archive/7z/7zFolderInStream.cpp b/CPP/7zip/Archive/7z/7zFolderInStream.cpp
new file mode 100755
index 00000000..fb1cfd3a
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zFolderInStream.cpp
@@ -0,0 +1,129 @@
+// 7zFolderInStream.cpp
+
+#include "StdAfx.h"
+
+#include "7zFolderInStream.h"
+
+namespace NArchive {
+namespace N7z {
+
+CFolderInStream::CFolderInStream()
+{
+ _inStreamWithHashSpec = new CSequentialInStreamWithCRC;
+ _inStreamWithHash = _inStreamWithHashSpec;
+}
+
+void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback,
+ const UInt32 *fileIndices, UInt32 numFiles)
+{
+ _updateCallback = updateCallback;
+ _numFiles = numFiles;
+ _fileIndex = 0;
+ _fileIndices = fileIndices;
+ Processed.Clear();
+ CRCs.Clear();
+ Sizes.Clear();
+ _fileIsOpen = false;
+ _currentSizeIsDefined = false;
+}
+
+HRESULT CFolderInStream::OpenStream()
+{
+ _filePos = 0;
+ while (_fileIndex < _numFiles)
+ {
+ _currentSizeIsDefined = false;
+ CMyComPtr<ISequentialInStream> stream;
+ HRESULT result = _updateCallback->GetStream(_fileIndices[_fileIndex], &stream);
+ if (result != S_OK && result != S_FALSE)
+ return result;
+ _fileIndex++;
+ _inStreamWithHashSpec->SetStream(stream);
+ _inStreamWithHashSpec->Init();
+ if (!stream)
+ {
+ RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
+ Sizes.Add(0);
+ Processed.Add(result == S_OK);
+ AddDigest();
+ continue;
+ }
+ CMyComPtr<IStreamGetSize> streamGetSize;
+ if (stream.QueryInterface(IID_IStreamGetSize, &streamGetSize) == S_OK)
+ {
+ if(streamGetSize)
+ {
+ _currentSizeIsDefined = true;
+ RINOK(streamGetSize->GetSize(&_currentSize));
+ }
+ }
+
+ _fileIsOpen = true;
+ return S_OK;
+ }
+ return S_OK;
+}
+
+void CFolderInStream::AddDigest()
+{
+ CRCs.Add(_inStreamWithHashSpec->GetCRC());
+}
+
+HRESULT CFolderInStream::CloseStream()
+{
+ RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
+ _inStreamWithHashSpec->ReleaseStream();
+ _fileIsOpen = false;
+ Processed.Add(true);
+ Sizes.Add(_filePos);
+ AddDigest();
+ return S_OK;
+}
+
+STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize = 0;
+ while ((_fileIndex < _numFiles || _fileIsOpen) && size > 0)
+ {
+ if (_fileIsOpen)
+ {
+ UInt32 localProcessedSize;
+ RINOK(_inStreamWithHash->Read(
+ ((Byte *)data) + realProcessedSize, size, &localProcessedSize));
+ if (localProcessedSize == 0)
+ {
+ RINOK(CloseStream());
+ continue;
+ }
+ realProcessedSize += localProcessedSize;
+ _filePos += localProcessedSize;
+ size -= localProcessedSize;
+ break;
+ }
+ else
+ {
+ RINOK(OpenStream());
+ }
+ }
+ if (processedSize != 0)
+ *processedSize = realProcessedSize;
+ return S_OK;
+}
+
+STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
+{
+ *value = 0;
+ if (subStream < Sizes.Size())
+ {
+ *value= Sizes[(int)(size_t)subStream];
+ return S_OK;
+ }
+ if (subStream > Sizes.Size())
+ return E_FAIL;
+ if (!_currentSizeIsDefined)
+ return S_FALSE;
+ *value = _currentSize;
+ return S_OK;
+}
+
+}}
diff --git a/CPP/7zip/Archive/7z/7zFolderInStream.h b/CPP/7zip/Archive/7z/7zFolderInStream.h
new file mode 100755
index 00000000..9a720c8b
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zFolderInStream.h
@@ -0,0 +1,66 @@
+// 7z/FolderInStream.h
+
+#ifndef __7Z_FOLDERINSTREAM_H
+#define __7Z_FOLDERINSTREAM_H
+
+#include "7zItem.h"
+#include "7zHeader.h"
+
+#include "../IArchive.h"
+#include "../Common/InStreamWithCRC.h"
+#include "../../IStream.h"
+#include "../../ICoder.h"
+
+namespace NArchive {
+namespace N7z {
+
+class CFolderInStream:
+ public ISequentialInStream,
+ public ICompressGetSubStreamSize,
+ public CMyUnknownImp
+{
+public:
+
+ MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
+
+ CFolderInStream();
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+
+ STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
+private:
+ CSequentialInStreamWithCRC *_inStreamWithHashSpec;
+ CMyComPtr<ISequentialInStream> _inStreamWithHash;
+ CMyComPtr<IArchiveUpdateCallback> _updateCallback;
+
+ bool _currentSizeIsDefined;
+ UInt64 _currentSize;
+
+ bool _fileIsOpen;
+ UInt64 _filePos;
+
+ const UInt32 *_fileIndices;
+ UInt32 _numFiles;
+ UInt32 _fileIndex;
+
+ HRESULT OpenStream();
+ HRESULT CloseStream();
+ void AddDigest();
+public:
+ void Init(IArchiveUpdateCallback *updateCallback,
+ const UInt32 *fileIndices, UInt32 numFiles);
+ CRecordVector<bool> Processed;
+ CRecordVector<UInt32> CRCs;
+ CRecordVector<UInt64> Sizes;
+ UInt64 GetFullSize() const
+ {
+ UInt64 size = 0;
+ for (int i = 0; i < Sizes.Size(); i++)
+ size += Sizes[i];
+ return size;
+ }
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/7z/7zFolderOutStream.cpp b/CPP/7zip/Archive/7z/7zFolderOutStream.cpp
new file mode 100755
index 00000000..93bed3d9
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zFolderOutStream.cpp
@@ -0,0 +1,162 @@
+// 7zFolderOutStream.cpp
+
+#include "StdAfx.h"
+
+#include "7zFolderOutStream.h"
+
+namespace NArchive {
+namespace N7z {
+
+CFolderOutStream::CFolderOutStream()
+{
+ _outStreamWithHashSpec = new COutStreamWithCRC;
+ _outStreamWithHash = _outStreamWithHashSpec;
+}
+
+HRESULT CFolderOutStream::Init(
+ const CArchiveDatabaseEx *archiveDatabase,
+ UInt32 ref2Offset,
+ UInt32 startIndex,
+ const CBoolVector *extractStatuses,
+ IArchiveExtractCallback *extractCallback,
+ bool testMode)
+{
+ _archiveDatabase = archiveDatabase;
+ _ref2Offset = ref2Offset;
+ _startIndex = startIndex;
+
+ _extractStatuses = extractStatuses;
+ _extractCallback = extractCallback;
+ _testMode = testMode;
+
+ _currentIndex = 0;
+ _fileIsOpen = false;
+ return WriteEmptyFiles();
+}
+
+HRESULT CFolderOutStream::OpenFile()
+{
+ Int32 askMode;
+ if((*_extractStatuses)[_currentIndex])
+ askMode = _testMode ?
+ NArchive::NExtract::NAskMode::kTest :
+ NArchive::NExtract::NAskMode::kExtract;
+ else
+ askMode = NArchive::NExtract::NAskMode::kSkip;
+ CMyComPtr<ISequentialOutStream> realOutStream;
+
+ UInt32 index = _startIndex + _currentIndex;
+ RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode));
+
+ _outStreamWithHashSpec->SetStream(realOutStream);
+ _outStreamWithHashSpec->Init();
+ if (askMode == NArchive::NExtract::NAskMode::kExtract &&
+ (!realOutStream))
+ {
+ const CFileItem &fileInfo = _archiveDatabase->Files[index];
+ if (!fileInfo.IsAnti && !fileInfo.IsDirectory)
+ askMode = NArchive::NExtract::NAskMode::kSkip;
+ }
+ return _extractCallback->PrepareOperation(askMode);
+}
+
+HRESULT CFolderOutStream::WriteEmptyFiles()
+{
+ for(;_currentIndex < _extractStatuses->Size(); _currentIndex++)
+ {
+ UInt32 index = _startIndex + _currentIndex;
+ const CFileItem &fileInfo = _archiveDatabase->Files[index];
+ if (!fileInfo.IsAnti && !fileInfo.IsDirectory && fileInfo.UnPackSize != 0)
+ return S_OK;
+ RINOK(OpenFile());
+ RINOK(_extractCallback->SetOperationResult(
+ NArchive::NExtract::NOperationResult::kOK));
+ _outStreamWithHashSpec->ReleaseStream();
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CFolderOutStream::Write(const void *data,
+ UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize = 0;
+ while(_currentIndex < _extractStatuses->Size())
+ {
+ if (_fileIsOpen)
+ {
+ UInt32 index = _startIndex + _currentIndex;
+ const CFileItem &fileInfo = _archiveDatabase->Files[index];
+ UInt64 fileSize = fileInfo.UnPackSize;
+
+ UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - _filePos,
+ UInt64(size - realProcessedSize));
+
+ UInt32 processedSizeLocal;
+ RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize,
+ numBytesToWrite, &processedSizeLocal));
+
+ _filePos += processedSizeLocal;
+ realProcessedSize += processedSizeLocal;
+ if (_filePos == fileSize)
+ {
+ bool digestsAreEqual;
+ if (fileInfo.IsFileCRCDefined)
+ digestsAreEqual = fileInfo.FileCRC == _outStreamWithHashSpec->GetCRC();
+ else
+ digestsAreEqual = true;
+
+ RINOK(_extractCallback->SetOperationResult(
+ digestsAreEqual ?
+ NArchive::NExtract::NOperationResult::kOK :
+ NArchive::NExtract::NOperationResult::kCRCError));
+ _outStreamWithHashSpec->ReleaseStream();
+ _fileIsOpen = false;
+ _currentIndex++;
+ }
+ if (realProcessedSize == size)
+ {
+ if (processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return WriteEmptyFiles();
+ }
+ }
+ else
+ {
+ RINOK(OpenFile());
+ _fileIsOpen = true;
+ _filePos = 0;
+ }
+ }
+ if (processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
+
+HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult)
+{
+ while(_currentIndex < _extractStatuses->Size())
+ {
+ if (_fileIsOpen)
+ {
+ RINOK(_extractCallback->SetOperationResult(resultEOperationResult));
+ _outStreamWithHashSpec->ReleaseStream();
+ _fileIsOpen = false;
+ _currentIndex++;
+ }
+ else
+ {
+ RINOK(OpenFile());
+ _fileIsOpen = true;
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CFolderOutStream::WasWritingFinished()
+{
+ if (_currentIndex == _extractStatuses->Size())
+ return S_OK;
+ return E_FAIL;
+}
+
+}}
diff --git a/CPP/7zip/Archive/7z/7zFolderOutStream.h b/CPP/7zip/Archive/7z/7zFolderOutStream.h
new file mode 100755
index 00000000..c132c79a
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zFolderOutStream.h
@@ -0,0 +1,57 @@
+// 7zFolderOutStream.h
+
+#ifndef __7Z_FOLDEROUTSTREAM_H
+#define __7Z_FOLDEROUTSTREAM_H
+
+#include "7zIn.h"
+
+#include "../../IStream.h"
+#include "../IArchive.h"
+#include "../Common/OutStreamWithCRC.h"
+
+namespace NArchive {
+namespace N7z {
+
+class CFolderOutStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ CFolderOutStream();
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+private:
+
+ COutStreamWithCRC *_outStreamWithHashSpec;
+ CMyComPtr<ISequentialOutStream> _outStreamWithHash;
+ const CArchiveDatabaseEx *_archiveDatabase;
+ const CBoolVector *_extractStatuses;
+ UInt32 _startIndex;
+ UInt32 _ref2Offset;
+ int _currentIndex;
+ // UInt64 _currentDataPos;
+ CMyComPtr<IArchiveExtractCallback> _extractCallback;
+ bool _testMode;
+
+ bool _fileIsOpen;
+ UInt64 _filePos;
+
+ HRESULT OpenFile();
+ HRESULT WriteEmptyFiles();
+public:
+ HRESULT Init(
+ const CArchiveDatabaseEx *archiveDatabase,
+ UInt32 ref2Offset,
+ UInt32 startIndex,
+ const CBoolVector *extractStatuses,
+ IArchiveExtractCallback *extractCallback,
+ bool testMode);
+ HRESULT FlushCorrupted(Int32 resultEOperationResult);
+ HRESULT WasWritingFinished();
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/7z/7zHandler.cpp b/CPP/7zip/Archive/7z/7zHandler.cpp
new file mode 100755
index 00000000..3321fd71
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zHandler.cpp
@@ -0,0 +1,794 @@
+// 7zHandler.cpp
+
+#include "StdAfx.h"
+
+#include "7zHandler.h"
+#include "7zProperties.h"
+
+#include "../../../Common/IntToString.h"
+#include "../../../Common/ComTry.h"
+#include "../../../Windows/Defs.h"
+
+#include "../Common/ItemNameUtils.h"
+#ifdef _7Z_VOL
+#include "../Common/MultiStream.h"
+#endif
+
+#ifdef __7Z_SET_PROPERTIES
+#ifdef EXTRACT_ONLY
+#include "../Common/ParseProperties.h"
+#endif
+#endif
+
+using namespace NWindows;
+
+namespace NArchive {
+namespace N7z {
+
+CHandler::CHandler()
+{
+ #ifdef COMPRESS_MT
+ _numThreads = NWindows::NSystem::GetNumberOfProcessors();
+ #endif
+ #ifndef EXTRACT_ONLY
+ Init();
+ #endif
+ #ifndef EXCLUDE_COM
+ LoadMethodMap();
+ #endif
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems =
+ #ifdef _7Z_VOL
+ _refs.Size();
+ #else
+ *numItems = _database.Files.Size();
+ #endif
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
+{
+ value->vt = VT_EMPTY;
+ return S_OK;
+}
+
+#ifdef _SFX
+
+STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 * /* numProperties */)
+{
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,
+ BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
+{
+ return E_NOTIMPL;
+}
+
+#endif
+
+
+STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
+{
+ *numProperties = 0;
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
+ BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
+{
+ return E_NOTIMPL;
+}
+
+
+static void MySetFileTime(bool timeDefined, FILETIME unixTime,
+ NWindows::NCOM::CPropVariant &propVariant)
+{
+ if (timeDefined)
+ propVariant = unixTime;
+}
+
+#ifndef _SFX
+
+static UString ConvertUInt32ToString(UInt32 value)
+{
+ wchar_t buffer[32];
+ ConvertUInt64ToString(value, buffer);
+ return buffer;
+}
+
+static UString GetStringForSizeValue(UInt32 value)
+{
+ for (int i = 31; i >= 0; i--)
+ if ((UInt32(1) << i) == value)
+ return ConvertUInt32ToString(i);
+ UString result;
+ if (value % (1 << 20) == 0)
+ {
+ result += ConvertUInt32ToString(value >> 20);
+ result += L"m";
+ }
+ else if (value % (1 << 10) == 0)
+ {
+ result += ConvertUInt32ToString(value >> 10);
+ result += L"k";
+ }
+ else
+ {
+ result += ConvertUInt32ToString(value);
+ result += L"b";
+ }
+ return result;
+}
+
+static CMethodID k_Copy = { { 0x0 }, 1 };
+static CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
+static CMethodID k_BCJ = { { 0x3, 0x3, 0x1, 0x3 }, 4 };
+static CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 };
+static CMethodID k_PPMD = { { 0x3, 0x4, 0x1 }, 3 };
+static CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
+static CMethodID k_Deflate64 = { { 0x4, 0x1, 0x9 }, 3 };
+static CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
+
+static wchar_t GetHex(Byte value)
+{
+ return (wchar_t)((value < 10) ? (L'0' + value) : (L'A' + (value - 10)));
+}
+static inline UString GetHex2(Byte value)
+{
+ UString result;
+ result += GetHex((Byte)(value >> 4));
+ result += GetHex((Byte)(value & 0xF));
+ return result;
+}
+
+#endif
+
+static CMethodID k_AES = { { 0x6, 0xF1, 0x7, 0x1}, 4 };
+
+static inline UInt32 GetUInt32FromMemLE(const Byte *p)
+{
+ return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);
+}
+
+bool CHandler::IsEncrypted(UInt32 index2) const
+{
+ CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
+ if (folderIndex != kNumNoIndex)
+ {
+ const CFolder &folderInfo = _database.Folders[folderIndex];
+ for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
+ {
+ const CCoderInfo &coderInfo = folderInfo.Coders[i];
+ for (int j = 0; j < coderInfo.AltCoders.Size(); j++)
+ if (coderInfo.AltCoders[j].MethodID == k_AES)
+ return true;
+ }
+ }
+ return false;
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant propVariant;
+
+ /*
+ const CRef2 &ref2 = _refs[index];
+ if (ref2.Refs.IsEmpty())
+ return E_FAIL;
+ const CRef &ref = ref2.Refs.Front();
+ */
+
+ #ifdef _7Z_VOL
+ const CRef &ref = _refs[index];
+ const CVolume &volume = _volumes[ref.VolumeIndex];
+ const CArchiveDatabaseEx &_database = volume.Database;
+ UInt32 index2 = ref.ItemIndex;
+ const CFileItem &item = _database.Files[index2];
+ #else
+ const CFileItem &item = _database.Files[index];
+ UInt32 index2 = index;
+ #endif
+
+ switch(propID)
+ {
+ case kpidPath:
+ {
+ if (!item.Name.IsEmpty())
+ propVariant = NItemName::GetOSName(item.Name);
+ break;
+ }
+ case kpidIsFolder:
+ propVariant = item.IsDirectory;
+ break;
+ case kpidSize:
+ {
+ propVariant = item.UnPackSize;
+ // propVariant = ref2.UnPackSize;
+ break;
+ }
+ case kpidPosition:
+ {
+ /*
+ if (ref2.Refs.Size() > 1)
+ propVariant = ref2.StartPos;
+ else
+ */
+ if (item.IsStartPosDefined)
+ propVariant = item.StartPos;
+ break;
+ }
+ case kpidPackedSize:
+ {
+ // propVariant = ref2.PackSize;
+ {
+ CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
+ if (folderIndex != kNumNoIndex)
+ {
+ if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2)
+ propVariant = _database.GetFolderFullPackSize(folderIndex);
+ /*
+ else
+ propVariant = UInt64(0);
+ */
+ }
+ else
+ propVariant = UInt64(0);
+ }
+ break;
+ }
+ case kpidLastAccessTime:
+ MySetFileTime(item.IsLastAccessTimeDefined, item.LastAccessTime, propVariant);
+ break;
+ case kpidCreationTime:
+ MySetFileTime(item.IsCreationTimeDefined, item.CreationTime, propVariant);
+ break;
+ case kpidLastWriteTime:
+ MySetFileTime(item.IsLastWriteTimeDefined, item.LastWriteTime, propVariant);
+ break;
+ case kpidAttributes:
+ if (item.AreAttributesDefined)
+ propVariant = item.Attributes;
+ break;
+ case kpidCRC:
+ if (item.IsFileCRCDefined)
+ propVariant = item.FileCRC;
+ break;
+ case kpidEncrypted:
+ {
+ propVariant = IsEncrypted(index2);
+ break;
+ }
+ #ifndef _SFX
+ case kpidMethod:
+ {
+ CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
+ if (folderIndex != kNumNoIndex)
+ {
+ const CFolder &folderInfo = _database.Folders[folderIndex];
+ UString methodsString;
+ for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
+ {
+ const CCoderInfo &coderInfo = folderInfo.Coders[i];
+ if (!methodsString.IsEmpty())
+ methodsString += L' ';
+ CMethodInfo methodInfo;
+
+ bool methodIsKnown;
+
+ for (int j = 0; j < coderInfo.AltCoders.Size(); j++)
+ {
+ if (j > 0)
+ methodsString += L"|";
+ const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders[j];
+
+ UString methodName;
+ #ifdef NO_REGISTRY
+
+ methodIsKnown = true;
+ if (altCoderInfo.MethodID == k_Copy)
+ methodName = L"Copy";
+ else if (altCoderInfo.MethodID == k_LZMA)
+ methodName = L"LZMA";
+ else if (altCoderInfo.MethodID == k_BCJ)
+ methodName = L"BCJ";
+ else if (altCoderInfo.MethodID == k_BCJ2)
+ methodName = L"BCJ2";
+ else if (altCoderInfo.MethodID == k_PPMD)
+ methodName = L"PPMD";
+ else if (altCoderInfo.MethodID == k_Deflate)
+ methodName = L"Deflate";
+ else if (altCoderInfo.MethodID == k_Deflate64)
+ methodName = L"Deflate64";
+ else if (altCoderInfo.MethodID == k_BZip2)
+ methodName = L"BZip2";
+ else if (altCoderInfo.MethodID == k_AES)
+ methodName = L"7zAES";
+ else
+ methodIsKnown = false;
+
+ #else
+
+ methodIsKnown = GetMethodInfo(
+ altCoderInfo.MethodID, methodInfo);
+ methodName = methodInfo.Name;
+
+ #endif
+
+ if (methodIsKnown)
+ {
+ methodsString += methodName;
+ if (altCoderInfo.MethodID == k_LZMA)
+ {
+ if (altCoderInfo.Properties.GetCapacity() >= 5)
+ {
+ methodsString += L":";
+ UInt32 dicSize = GetUInt32FromMemLE(
+ ((const Byte *)altCoderInfo.Properties + 1));
+ methodsString += GetStringForSizeValue(dicSize);
+ }
+ }
+ else if (altCoderInfo.MethodID == k_PPMD)
+ {
+ if (altCoderInfo.Properties.GetCapacity() >= 5)
+ {
+ Byte order = *(const Byte *)altCoderInfo.Properties;
+ methodsString += L":o";
+ methodsString += ConvertUInt32ToString(order);
+ methodsString += L":mem";
+ UInt32 dicSize = GetUInt32FromMemLE(
+ ((const Byte *)altCoderInfo.Properties + 1));
+ methodsString += GetStringForSizeValue(dicSize);
+ }
+ }
+ else if (altCoderInfo.MethodID == k_AES)
+ {
+ if (altCoderInfo.Properties.GetCapacity() >= 1)
+ {
+ methodsString += L":";
+ const Byte *data = (const Byte *)altCoderInfo.Properties;
+ Byte firstByte = *data++;
+ UInt32 numCyclesPower = firstByte & 0x3F;
+ methodsString += ConvertUInt32ToString(numCyclesPower);
+ /*
+ if ((firstByte & 0xC0) != 0)
+ {
+ methodsString += L":";
+ return S_OK;
+ UInt32 saltSize = (firstByte >> 7) & 1;
+ UInt32 ivSize = (firstByte >> 6) & 1;
+ if (altCoderInfo.Properties.GetCapacity() >= 2)
+ {
+ Byte secondByte = *data++;
+ saltSize += (secondByte >> 4);
+ ivSize += (secondByte & 0x0F);
+ }
+ }
+ */
+ }
+ }
+ else
+ {
+ if (altCoderInfo.Properties.GetCapacity() > 0)
+ {
+ methodsString += L":[";
+ for (size_t bi = 0; bi < altCoderInfo.Properties.GetCapacity(); bi++)
+ {
+ if (bi > 5 && bi + 1 < altCoderInfo.Properties.GetCapacity())
+ {
+ methodsString += L"..";
+ break;
+ }
+ else
+ methodsString += GetHex2(altCoderInfo.Properties[bi]);
+ }
+ methodsString += L"]";
+ }
+ }
+ }
+ else
+ {
+ methodsString += altCoderInfo.MethodID.ConvertToString();
+ }
+ }
+ }
+ propVariant = methodsString;
+ }
+ }
+ break;
+ case kpidBlock:
+ {
+ CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
+ if (folderIndex != kNumNoIndex)
+ propVariant = (UInt32)folderIndex;
+ }
+ break;
+ case kpidPackedSize0:
+ case kpidPackedSize1:
+ case kpidPackedSize2:
+ case kpidPackedSize3:
+ case kpidPackedSize4:
+ {
+ CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
+ if (folderIndex != kNumNoIndex)
+ {
+ const CFolder &folderInfo = _database.Folders[folderIndex];
+ if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
+ folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0))
+ {
+ propVariant = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
+ }
+ else
+ propVariant = UInt64(0);
+ }
+ else
+ propVariant = UInt64(0);
+ }
+ break;
+ #endif
+ case kpidIsAnti:
+ propVariant = item.IsAnti;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+static const wchar_t *kExt = L"7z";
+static const wchar_t *kAfterPart = L".7z";
+
+#ifdef _7Z_VOL
+
+class CVolumeName
+{
+ bool _first;
+ UString _unchangedPart;
+ UString _changedPart;
+ UString _afterPart;
+public:
+ bool InitName(const UString &name)
+ {
+ _first = true;
+ int dotPos = name.ReverseFind('.');
+ UString basePart = name;
+ if (dotPos >= 0)
+ {
+ UString ext = name.Mid(dotPos + 1);
+ if (ext.CompareNoCase(kExt)==0 ||
+ ext.CompareNoCase(L"EXE") == 0)
+ {
+ _afterPart = kAfterPart;
+ basePart = name.Left(dotPos);
+ }
+ }
+
+ int numLetters = 1;
+ bool splitStyle = false;
+ if (basePart.Right(numLetters) == L"1")
+ {
+ while (numLetters < basePart.Length())
+ {
+ if (basePart[basePart.Length() - numLetters - 1] != '0')
+ break;
+ numLetters++;
+ }
+ }
+ else
+ return false;
+ _unchangedPart = basePart.Left(basePart.Length() - numLetters);
+ _changedPart = basePart.Right(numLetters);
+ return true;
+ }
+
+ UString GetNextName()
+ {
+ UString newName;
+ // if (_newStyle || !_first)
+ {
+ int i;
+ int numLetters = _changedPart.Length();
+ for (i = numLetters - 1; i >= 0; i--)
+ {
+ wchar_t c = _changedPart[i];
+ if (c == L'9')
+ {
+ c = L'0';
+ newName = c + newName;
+ if (i == 0)
+ newName = UString(L'1') + newName;
+ continue;
+ }
+ c++;
+ newName = UString(c) + newName;
+ i--;
+ for (; i >= 0; i--)
+ newName = _changedPart[i] + newName;
+ break;
+ }
+ _changedPart = newName;
+ }
+ _first = false;
+ return _unchangedPart + _changedPart + _afterPart;
+ }
+};
+
+#endif
+
+STDMETHODIMP CHandler::Open(IInStream *stream,
+ const UInt64 *maxCheckStartPosition,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ COM_TRY_BEGIN
+ Close();
+ #ifndef _SFX
+ _fileInfoPopIDs.Clear();
+ #endif
+ try
+ {
+ CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;
+ #ifdef _7Z_VOL
+ CVolumeName seqName;
+
+ CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
+ #endif
+
+ #ifndef _NO_CRYPTO
+ CMyComPtr<ICryptoGetTextPassword> getTextPassword;
+ if (openArchiveCallback)
+ {
+ openArchiveCallbackTemp.QueryInterface(
+ IID_ICryptoGetTextPassword, &getTextPassword);
+ }
+ #endif
+ #ifdef _7Z_VOL
+ if (openArchiveCallback)
+ {
+ openArchiveCallbackTemp.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback);
+ }
+ for (;;)
+ {
+ CMyComPtr<IInStream> inStream;
+ if (!_volumes.IsEmpty())
+ {
+ if (!openVolumeCallback)
+ break;
+ if(_volumes.Size() == 1)
+ {
+ UString baseName;
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant));
+ if (propVariant.vt != VT_BSTR)
+ break;
+ baseName = propVariant.bstrVal;
+ }
+ seqName.InitName(baseName);
+ }
+
+ UString fullName = seqName.GetNextName();
+ HRESULT result = openVolumeCallback->GetStream(fullName, &inStream);
+ if (result == S_FALSE)
+ break;
+ if (result != S_OK)
+ return result;
+ if (!stream)
+ break;
+ }
+ else
+ inStream = stream;
+
+ CInArchive archive;
+ RINOK(archive.Open(inStream, maxCheckStartPosition));
+
+ _volumes.Add(CVolume());
+ CVolume &volume = _volumes.Back();
+ CArchiveDatabaseEx &database = volume.Database;
+ volume.Stream = inStream;
+ volume.StartRef2Index = _refs.Size();
+
+ HRESULT result = archive.ReadDatabase(database
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ );
+ if (result != S_OK)
+ {
+ _volumes.Clear();
+ return result;
+ }
+ database.Fill();
+ for(int i = 0; i < database.Files.Size(); i++)
+ {
+ CRef refNew;
+ refNew.VolumeIndex = _volumes.Size() - 1;
+ refNew.ItemIndex = i;
+ _refs.Add(refNew);
+ /*
+ const CFileItem &file = database.Files[i];
+ int j;
+ */
+ /*
+ for (j = _refs.Size() - 1; j >= 0; j--)
+ {
+ CRef2 &ref2 = _refs[j];
+ const CRef &ref = ref2.Refs.Back();
+ const CVolume &volume2 = _volumes[ref.VolumeIndex];
+ const CArchiveDatabaseEx &database2 = volume2.Database;
+ const CFileItem &file2 = database2.Files[ref.ItemIndex];
+ if (file2.Name.CompareNoCase(file.Name) == 0)
+ {
+ if (!file.IsStartPosDefined)
+ continue;
+ if (file.StartPos != ref2.StartPos + ref2.UnPackSize)
+ continue;
+ ref2.Refs.Add(refNew);
+ break;
+ }
+ }
+ */
+ /*
+ j = -1;
+ if (j < 0)
+ {
+ CRef2 ref2New;
+ ref2New.Refs.Add(refNew);
+ j = _refs.Add(ref2New);
+ }
+ CRef2 &ref2 = _refs[j];
+ ref2.UnPackSize += file.UnPackSize;
+ ref2.PackSize += database.GetFilePackSize(i);
+ if (ref2.Refs.Size() == 1 && file.IsStartPosDefined)
+ ref2.StartPos = file.StartPos;
+ */
+ }
+ if (database.Files.Size() != 1)
+ break;
+ const CFileItem &file = database.Files.Front();
+ if (!file.IsStartPosDefined)
+ break;
+ }
+ #else
+ CInArchive archive;
+ RINOK(archive.Open(stream, maxCheckStartPosition));
+ HRESULT result = archive.ReadDatabase(_database
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ );
+ RINOK(result);
+ _database.Fill();
+ _inStream = stream;
+ #endif
+ }
+ catch(...)
+ {
+ Close();
+ return S_FALSE;
+ }
+ // _inStream = stream;
+ #ifndef _SFX
+ FillPopIDs();
+ #endif
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ COM_TRY_BEGIN
+ #ifdef _7Z_VOL
+ _volumes.Clear();
+ _refs.Clear();
+ #else
+ _inStream.Release();
+ _database.Clear();
+ #endif
+ return S_OK;
+ COM_TRY_END
+}
+
+#ifdef _7Z_VOL
+STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
+{
+ if (index != 0)
+ return E_INVALIDARG;
+ *stream = 0;
+ CMultiStream *streamSpec = new CMultiStream;
+ CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
+
+ UInt64 pos = 0;
+ const UString *fileName;
+ for (int i = 0; i < _refs.Size(); i++)
+ {
+ const CRef &ref = _refs[i];
+ const CVolume &volume = _volumes[ref.VolumeIndex];
+ const CArchiveDatabaseEx &database = volume.Database;
+ const CFileItem &file = database.Files[ref.ItemIndex];
+ if (i == 0)
+ fileName = &file.Name;
+ else
+ if (fileName->Compare(file.Name) != 0)
+ return S_FALSE;
+ if (!file.IsStartPosDefined)
+ return S_FALSE;
+ if (file.StartPos != pos)
+ return S_FALSE;
+ CNum folderIndex = database.FileIndexToFolderIndexMap[ref.ItemIndex];
+ if (folderIndex == kNumNoIndex)
+ {
+ if (file.UnPackSize != 0)
+ return E_FAIL;
+ continue;
+ }
+ if (database.NumUnPackStreamsVector[folderIndex] != 1)
+ return S_FALSE;
+ const CFolder &folder = database.Folders[folderIndex];
+ if (folder.Coders.Size() != 1)
+ return S_FALSE;
+ const CCoderInfo &coder = folder.Coders.Front();
+ if (coder.NumInStreams != 1 || coder.NumOutStreams != 1)
+ return S_FALSE;
+ const CAltCoderInfo &altCoder = coder.AltCoders.Front();
+ if (altCoder.MethodID.IDSize != 1 || altCoder.MethodID.ID[0] != 0)
+ return S_FALSE;
+
+ pos += file.UnPackSize;
+ CMultiStream::CSubStreamInfo subStreamInfo;
+ subStreamInfo.Stream = volume.Stream;
+ subStreamInfo.Pos = database.GetFolderStreamPos(folderIndex, 0);
+ subStreamInfo.Size = file.UnPackSize;
+ streamSpec->Streams.Add(subStreamInfo);
+ }
+ streamSpec->Init();
+ *stream = streamTemp.Detach();
+ return S_OK;
+}
+#endif
+
+
+#ifdef __7Z_SET_PROPERTIES
+#ifdef EXTRACT_ONLY
+
+STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
+{
+ COM_TRY_BEGIN
+ #ifdef COMPRESS_MT
+ const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
+ _numThreads = numProcessors;
+ #endif
+
+ for (int i = 0; i < numProperties; i++)
+ {
+ UString name = names[i];
+ name.MakeUpper();
+ if (name.IsEmpty())
+ return E_INVALIDARG;
+ const PROPVARIANT &value = values[i];
+ UInt32 number;
+ int index = ParseStringToUInt32(name, number);
+ if (index == 0)
+ {
+ if(name.Left(2).CompareNoCase(L"MT") == 0)
+ {
+ #ifdef COMPRESS_MT
+ RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
+ #endif
+ continue;
+ }
+ else
+ return E_INVALIDARG;
+ }
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+#endif
+#endif
+
+}}
diff --git a/CPP/7zip/Archive/7z/7zHandler.h b/CPP/7zip/Archive/7z/7zHandler.h
new file mode 100755
index 00000000..8be9f398
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zHandler.h
@@ -0,0 +1,249 @@
+// 7z/Handler.h
+
+#ifndef __7Z_HANDLER_H
+#define __7Z_HANDLER_H
+
+#include "../IArchive.h"
+#include "7zIn.h"
+
+#include "7zCompressionMode.h"
+
+#ifndef _SFX
+#include "7zMethods.h"
+#endif
+
+#ifdef COMPRESS_MT
+#include "../../../Windows/System.h"
+#endif
+
+namespace NArchive {
+namespace N7z {
+
+#ifdef _7Z_VOL
+struct CRef
+{
+ int VolumeIndex;
+ int ItemIndex;
+};
+
+/*
+struct CRef2
+{
+ CRecordVector<CRef> Refs;
+ UInt64 UnPackSize;
+ UInt64 PackSize;
+ UInt64 StartPos;
+ CRef2(): UnPackSize(0), PackSize(0), StartPos(0) {}
+};
+*/
+
+struct CVolume
+{
+ int StartRef2Index;
+ CMyComPtr<IInStream> Stream;
+ CArchiveDatabaseEx Database;
+};
+#endif
+
+#ifndef EXTRACT_ONLY
+
+struct COneMethodInfo
+{
+ CObjectVector<CProperty> CoderProperties;
+ UString MethodName;
+};
+#endif
+
+// {23170F69-40C1-278A-1000-000110070000}
+DEFINE_GUID(CLSID_CFormat7z,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);
+
+#ifndef __7Z_SET_PROPERTIES
+
+#ifdef EXTRACT_ONLY
+#ifdef COMPRESS_MT
+#define __7Z_SET_PROPERTIES
+#endif
+#else
+#define __7Z_SET_PROPERTIES
+#endif
+
+#endif
+
+
+class CHandler:
+ public IInArchive,
+ #ifdef _7Z_VOL
+ public IInArchiveGetStream,
+ #endif
+ #ifdef __7Z_SET_PROPERTIES
+ public ISetProperties,
+ #endif
+ #ifndef EXTRACT_ONLY
+ public IOutArchive,
+ #endif
+ public CMyUnknownImp
+{
+public:
+ #if !defined(_7Z_VOL) && !defined(__7Z_SET_PROPERTIES) && defined(EXTRACT_ONLY)
+ MY_UNKNOWN_IMP
+ #else
+ MY_QUERYINTERFACE_BEGIN
+ #ifdef _7Z_VOL
+ MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream)
+ #endif
+ #ifdef __7Z_SET_PROPERTIES
+ MY_QUERYINTERFACE_ENTRY(ISetProperties)
+ #endif
+ #ifndef EXTRACT_ONLY
+ MY_QUERYINTERFACE_ENTRY(IOutArchive)
+ #endif
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
+ #endif
+
+
+ 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);
+
+ #ifdef _7Z_VOL
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
+ #endif
+
+ #ifdef __7Z_SET_PROPERTIES
+ STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
+ #endif
+
+ #ifndef EXTRACT_ONLY
+ // IOutArchiveHandler
+ STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems,
+ IArchiveUpdateCallback *updateCallback);
+
+ STDMETHOD(GetFileTimeType)(UInt32 *type);
+
+ // ISetProperties
+
+ HRESULT SetSolidSettings(const UString &s);
+ HRESULT SetSolidSettings(const PROPVARIANT &value);
+ #endif
+
+ CHandler();
+
+private:
+ #ifdef _7Z_VOL
+ CObjectVector<CVolume> _volumes;
+ CObjectVector<CRef> _refs;
+ #else
+ CMyComPtr<IInStream> _inStream;
+ NArchive::N7z::CArchiveDatabaseEx _database;
+ #endif
+
+ #ifdef COMPRESS_MT
+ UInt32 _numThreads;
+ #endif
+
+ #ifndef EXTRACT_ONLY
+ CObjectVector<COneMethodInfo> _methods;
+ CRecordVector<CBind> _binds;
+ bool _removeSfxBlock;
+ UInt64 _numSolidFiles;
+ UInt64 _numSolidBytes;
+ bool _numSolidBytesDefined;
+ bool _solidExtension;
+
+ bool _compressHeaders;
+ bool _compressHeadersFull;
+ bool _encryptHeaders;
+
+ bool WriteModified;
+ bool WriteCreated;
+ bool WriteAccessed;
+
+
+ bool _autoFilter;
+ UInt32 _level;
+
+ bool _volumeMode;
+
+
+ HRESULT SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value);
+ HRESULT SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString);
+
+ HRESULT SetPassword(CCompressionMethodMode &methodMode, IArchiveUpdateCallback *updateCallback);
+
+ HRESULT SetCompressionMethod(CCompressionMethodMode &method,
+ CObjectVector<COneMethodInfo> &methodsInfo
+ #ifdef COMPRESS_MT
+ , UInt32 numThreads
+ #endif
+ );
+
+ HRESULT SetCompressionMethod(
+ CCompressionMethodMode &method,
+ CCompressionMethodMode &headerMethod);
+
+ #endif
+
+ bool IsEncrypted(UInt32 index2) const;
+ #ifndef _SFX
+
+ CRecordVector<UInt64> _fileInfoPopIDs;
+ void FillPopIDs();
+
+ #endif
+
+ #ifndef EXTRACT_ONLY
+
+ void InitSolidFiles() { _numSolidFiles = UInt64(Int64(-1)); }
+ void InitSolidSize() { _numSolidBytes = UInt64(Int64(-1)); }
+ void InitSolid()
+ {
+ InitSolidFiles();
+ InitSolidSize();
+ _solidExtension = false;
+ _numSolidBytesDefined = false;
+ }
+
+ void Init()
+ {
+ _removeSfxBlock = false;
+ _compressHeaders = true;
+ _compressHeadersFull = true;
+ _encryptHeaders = false;
+
+ WriteModified = true;
+ WriteCreated = false;
+ WriteAccessed = false;
+
+ #ifdef COMPRESS_MT
+ _numThreads = NWindows::NSystem::GetNumberOfProcessors();
+ #endif
+
+ _level = 5;
+ _autoFilter = true;
+ _volumeMode = false;
+ InitSolid();
+ }
+ #endif
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/7z/7zHandlerOut.cpp b/CPP/7zip/Archive/7z/7zHandlerOut.cpp
new file mode 100755
index 00000000..8be88c38
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zHandlerOut.cpp
@@ -0,0 +1,1148 @@
+// 7z/OutHandler.cpp
+
+#include "StdAfx.h"
+
+#include "7zHandler.h"
+#include "7zOut.h"
+#include "7zUpdate.h"
+#include "7zMethods.h"
+
+#include "../../../Windows/PropVariant.h"
+
+#include "../../../Common/ComTry.h"
+#include "../../../Common/StringToInt.h"
+#include "../../IPassword.h"
+#include "../../ICoder.h"
+
+#include "../Common/ItemNameUtils.h"
+#include "../Common/ParseProperties.h"
+
+using namespace NWindows;
+
+namespace NArchive {
+namespace N7z {
+
+#ifdef COMPRESS_LZMA
+static CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
+static CMethodID k_LZMA2 = { { 0x3, 0x1, 0x2 }, 3 };
+#endif
+
+#ifdef COMPRESS_PPMD
+static CMethodID k_PPMD = { { 0x3, 0x4, 0x1 }, 3 };
+#endif
+
+#ifdef COMPRESS_BCJ_X86
+static CMethodID k_BCJ_X86 = { { 0x3, 0x3, 0x1, 0x3 }, 4 };
+#endif
+
+#ifdef COMPRESS_BCJ2
+static CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 };
+#endif
+
+#ifdef COMPRESS_COPY
+static CMethodID k_Copy = { { 0x0 }, 1 };
+#endif
+
+#ifdef COMPRESS_DEFLATE
+#ifndef COMPRESS_DEFLATE_ENCODER
+#define COMPRESS_DEFLATE_ENCODER
+#endif
+#endif
+
+#ifdef COMPRESS_DEFLATE_ENCODER
+static CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
+#endif
+
+#ifdef COMPRESS_BZIP2
+#ifndef COMPRESS_BZIP2_ENCODER
+#define COMPRESS_BZIP2_ENCODER
+#endif
+#endif
+
+#ifdef COMPRESS_BZIP2_ENCODER
+static CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
+#endif
+
+const wchar_t *kCopyMethod = L"Copy";
+const wchar_t *kLZMAMethodName = L"LZMA";
+const wchar_t *kLZMA2MethodName = L"LZMA2";
+const wchar_t *kBZip2MethodName = L"BZip2";
+const wchar_t *kPpmdMethodName = L"PPMd";
+const wchar_t *kDeflateMethodName = L"Deflate";
+const wchar_t *kDeflate64MethodName = L"Deflate64";
+
+static const wchar_t *kLzmaMatchFinderX1 = L"HC4";
+static const wchar_t *kLzmaMatchFinderX5 = L"BT4";
+
+static const UInt32 kLzmaAlgorithmX1 = 0;
+static const UInt32 kLzmaAlgorithmX5 = 1;
+
+static const UInt32 kLzmaDicSizeX1 = 1 << 16;
+static const UInt32 kLzmaDicSizeX3 = 1 << 20;
+static const UInt32 kLzmaDicSizeX5 = 1 << 22;
+static const UInt32 kLzmaDicSizeX7 = 1 << 24;
+static const UInt32 kLzmaDicSizeX9 = 1 << 26;
+
+static const UInt32 kLzmaFastBytesX1 = 32;
+static const UInt32 kLzmaFastBytesX7 = 64;
+
+static const UInt32 kPpmdMemSizeX1 = (1 << 22);
+static const UInt32 kPpmdMemSizeX5 = (1 << 24);
+static const UInt32 kPpmdMemSizeX7 = (1 << 26);
+static const UInt32 kPpmdMemSizeX9 = (192 << 20);
+
+static const UInt32 kPpmdOrderX1 = 4;
+static const UInt32 kPpmdOrderX5 = 6;
+static const UInt32 kPpmdOrderX7 = 16;
+static const UInt32 kPpmdOrderX9 = 32;
+
+static const UInt32 kDeflateFastBytesX1 = 32;
+static const UInt32 kDeflateFastBytesX7 = 64;
+static const UInt32 kDeflateFastBytesX9 = 128;
+
+static const UInt32 kDeflatePassesX1 = 1;
+static const UInt32 kDeflatePassesX7 = 3;
+static const UInt32 kDeflatePassesX9 = 10;
+
+static const UInt32 kBZip2NumPassesX1 = 1;
+static const UInt32 kBZip2NumPassesX7 = 2;
+static const UInt32 kBZip2NumPassesX9 = 7;
+
+static const UInt32 kBZip2DicSizeX1 = 100000;
+static const UInt32 kBZip2DicSizeX3 = 500000;
+static const UInt32 kBZip2DicSizeX5 = 900000;
+
+const wchar_t *kDefaultMethodName = kLZMAMethodName;
+
+static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";
+static const UInt32 kDictionaryForHeaders = 1 << 20;
+static const UInt32 kNumFastBytesForHeaders = 273;
+static const UInt32 kAlgorithmForHeaders = kLzmaAlgorithmX5;
+
+static bool IsCopyMethod(const UString &methodName)
+ { return (methodName.CompareNoCase(kCopyMethod) == 0); }
+
+static bool IsLZMAMethod(const UString &methodName)
+{
+ return
+ (methodName.CompareNoCase(kLZMAMethodName) == 0) ||
+ (methodName.CompareNoCase(kLZMA2MethodName) == 0);
+}
+
+/*
+static bool IsLZMethod(const UString &methodName)
+ { return IsLZMAMethod(methodName); }
+*/
+
+static bool IsBZip2Method(const UString &methodName)
+ { return (methodName.CompareNoCase(kBZip2MethodName) == 0); }
+
+static bool IsPpmdMethod(const UString &methodName)
+ { return (methodName.CompareNoCase(kPpmdMethodName) == 0); }
+
+static bool IsDeflateMethod(const UString &methodName)
+ { return (methodName.CompareNoCase(kDeflateMethodName) == 0) ||
+ (methodName.CompareNoCase(kDeflate64MethodName) == 0); }
+
+STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
+{
+ *type = NFileTimeType::kWindows;
+ return S_OK;
+}
+
+HRESULT CHandler::SetPassword(CCompressionMethodMode &methodMode,
+ IArchiveUpdateCallback *updateCallback)
+{
+ CMyComPtr<ICryptoGetTextPassword2> getTextPassword;
+ if (!getTextPassword)
+ {
+ CMyComPtr<IArchiveUpdateCallback> udateCallback2(updateCallback);
+ udateCallback2.QueryInterface(IID_ICryptoGetTextPassword2, &getTextPassword);
+ }
+
+ if (getTextPassword)
+ {
+ CMyComBSTR password;
+ Int32 passwordIsDefined;
+ RINOK(getTextPassword->CryptoGetTextPassword2(
+ &passwordIsDefined, &password));
+ methodMode.PasswordIsDefined = IntToBool(passwordIsDefined);
+ if (methodMode.PasswordIsDefined)
+ methodMode.Password = password;
+ }
+ else
+ methodMode.PasswordIsDefined = false;
+ return S_OK;
+}
+
+struct CNameToPropID
+{
+ PROPID PropID;
+ VARTYPE VarType;
+ const wchar_t *Name;
+};
+
+CNameToPropID g_NameToPropID[] =
+{
+ { NCoderPropID::kOrder, VT_UI4, L"O" },
+ { NCoderPropID::kPosStateBits, VT_UI4, L"PB" },
+ { NCoderPropID::kLitContextBits, VT_UI4, L"LC" },
+ { NCoderPropID::kLitPosBits, VT_UI4, L"LP" },
+
+ { NCoderPropID::kNumPasses, VT_UI4, L"Pass" },
+ { NCoderPropID::kNumFastBytes, VT_UI4, L"fb" },
+ { NCoderPropID::kMatchFinderCycles, VT_UI4, L"mc" },
+ { NCoderPropID::kAlgorithm, VT_UI4, L"a" },
+ { NCoderPropID::kMatchFinder, VT_BSTR, L"mf" },
+ { NCoderPropID::kNumThreads, VT_UI4, L"mt" }
+};
+
+bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType,
+ NCOM::CPropVariant &destProp)
+{
+ if (varType == srcProp.vt)
+ {
+ destProp = srcProp;
+ return true;
+ }
+ if (varType == VT_UI1)
+ {
+ if(srcProp.vt == VT_UI4)
+ {
+ UInt32 value = srcProp.ulVal;
+ if (value > 0xFF)
+ return false;
+ destProp = Byte(value);
+ return true;
+ }
+ }
+ return false;
+}
+
+const int kNumNameToPropIDItems = sizeof(g_NameToPropID) / sizeof(g_NameToPropID[0]);
+
+int FindPropIdFromStringName(const UString &name)
+{
+ for (int i = 0; i < kNumNameToPropIDItems; i++)
+ if (name.CompareNoCase(g_NameToPropID[i].Name) == 0)
+ return i;
+ return -1;
+}
+
+HRESULT CHandler::SetCompressionMethod(
+ CCompressionMethodMode &methodMode,
+ CCompressionMethodMode &headerMethod)
+{
+ HRESULT res = SetCompressionMethod(methodMode, _methods
+ #ifdef COMPRESS_MT
+ , _numThreads
+ #endif
+ );
+ RINOK(res);
+ methodMode.Binds = _binds;
+ if (_compressHeadersFull)
+ _compressHeaders = true;
+
+ if (_compressHeaders)
+ {
+ // headerMethod.Methods.Add(methodMode.Methods.Back());
+
+ CObjectVector<COneMethodInfo> headerMethodInfoVector;
+ COneMethodInfo oneMethodInfo;
+ oneMethodInfo.MethodName = kLZMAMethodName;
+ {
+ CProperty property;
+ property.PropID = NCoderPropID::kMatchFinder;
+ property.Value = kLzmaMatchFinderForHeaders;
+ oneMethodInfo.CoderProperties.Add(property);
+ }
+ {
+ CProperty property;
+ property.PropID = NCoderPropID::kAlgorithm;
+ property.Value = kAlgorithmForHeaders;
+ oneMethodInfo.CoderProperties.Add(property);
+ }
+ {
+ CProperty property;
+ property.PropID = NCoderPropID::kNumFastBytes;
+ property.Value = UInt32(kNumFastBytesForHeaders);
+ oneMethodInfo.CoderProperties.Add(property);
+ }
+ {
+ CProperty property;
+ property.PropID = NCoderPropID::kDictionarySize;
+ property.Value = UInt32(kDictionaryForHeaders);
+ oneMethodInfo.CoderProperties.Add(property);
+ }
+ headerMethodInfoVector.Add(oneMethodInfo);
+ HRESULT res = SetCompressionMethod(headerMethod, headerMethodInfoVector
+ #ifdef COMPRESS_MT
+ ,1
+ #endif
+ );
+ RINOK(res);
+ }
+ return S_OK;
+}
+
+static void SetOneMethodProp(COneMethodInfo &oneMethodInfo, PROPID propID,
+ const NWindows::NCOM::CPropVariant &value)
+{
+ int j;
+ for (j = 0; j < oneMethodInfo.CoderProperties.Size(); j++)
+ if (oneMethodInfo.CoderProperties[j].PropID == propID)
+ break;
+ if (j != oneMethodInfo.CoderProperties.Size())
+ return;
+ CProperty property;
+ property.PropID = propID;
+ property.Value = value;
+ oneMethodInfo.CoderProperties.Add(property);
+}
+
+HRESULT CHandler::SetCompressionMethod(
+ CCompressionMethodMode &methodMode,
+ CObjectVector<COneMethodInfo> &methodsInfo
+ #ifdef COMPRESS_MT
+ , UInt32 numThreads
+ #endif
+ )
+{
+ #ifndef EXCLUDE_COM
+ /*
+ CObjectVector<CMethodInfo2> methodInfoVector;
+ if (!NRegistryInfo::EnumerateAllMethods(methodInfoVector))
+ return E_FAIL;
+ */
+ #endif
+
+
+ UInt32 level = _level;
+
+ if (methodsInfo.IsEmpty())
+ {
+ COneMethodInfo oneMethodInfo;
+ oneMethodInfo.MethodName = ((level == 0) ? kCopyMethod : kDefaultMethodName);
+ methodsInfo.Add(oneMethodInfo);
+ }
+
+ bool needSolid = false;
+ for(int i = 0; i < methodsInfo.Size(); i++)
+ {
+ COneMethodInfo &oneMethodInfo = methodsInfo[i];
+ if (oneMethodInfo.MethodName.IsEmpty())
+ oneMethodInfo.MethodName = kDefaultMethodName;
+
+ if (!IsCopyMethod(oneMethodInfo.MethodName))
+ needSolid = true;
+
+ if (IsLZMAMethod(oneMethodInfo.MethodName))
+ {
+ UInt32 dicSize =
+ (level >= 9 ? kLzmaDicSizeX9 :
+ (level >= 7 ? kLzmaDicSizeX7 :
+ (level >= 5 ? kLzmaDicSizeX5 :
+ (level >= 3 ? kLzmaDicSizeX3 :
+ kLzmaDicSizeX1))));
+
+ UInt32 algorithm =
+ (level >= 5 ? kLzmaAlgorithmX5 :
+ kLzmaAlgorithmX1);
+
+ UInt32 fastBytes =
+ (level >= 7 ? kLzmaFastBytesX7 :
+ kLzmaFastBytesX1);
+
+ const wchar_t *matchFinder =
+ (level >= 5 ? kLzmaMatchFinderX5 :
+ kLzmaMatchFinderX1);
+
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algorithm);
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kMatchFinder, matchFinder);
+ #ifdef COMPRESS_MT
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
+ #endif
+ }
+ else if (IsDeflateMethod(oneMethodInfo.MethodName))
+ {
+ UInt32 fastBytes =
+ (level >= 9 ? kDeflateFastBytesX9 :
+ (level >= 7 ? kDeflateFastBytesX7 :
+ kDeflateFastBytesX1));
+
+ UInt32 numPasses =
+ (level >= 9 ? kDeflatePassesX9 :
+ (level >= 7 ? kDeflatePassesX7 :
+ kDeflatePassesX1));
+
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
+ }
+ else if (IsBZip2Method(oneMethodInfo.MethodName))
+ {
+ UInt32 numPasses =
+ (level >= 9 ? kBZip2NumPassesX9 :
+ (level >= 7 ? kBZip2NumPassesX7 :
+ kBZip2NumPassesX1));
+
+ UInt32 dicSize =
+ (level >= 5 ? kBZip2DicSizeX5 :
+ (level >= 3 ? kBZip2DicSizeX3 :
+ kBZip2DicSizeX1));
+
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
+ #ifdef COMPRESS_MT
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
+ #endif
+ }
+ else if (IsPpmdMethod(oneMethodInfo.MethodName))
+ {
+ UInt32 useMemSize =
+ (level >= 9 ? kPpmdMemSizeX9 :
+ (level >= 7 ? kPpmdMemSizeX7 :
+ (level >= 5 ? kPpmdMemSizeX5 :
+ kPpmdMemSizeX1)));
+
+ UInt32 order =
+ (level >= 9 ? kPpmdOrderX9 :
+ (level >= 7 ? kPpmdOrderX7 :
+ (level >= 5 ? kPpmdOrderX5 :
+ kPpmdOrderX1)));
+
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kUsedMemorySize, useMemSize);
+ SetOneMethodProp(oneMethodInfo, NCoderPropID::kOrder, order);
+ }
+
+
+ CMethodFull methodFull;
+ methodFull.NumInStreams = 1;
+ methodFull.NumOutStreams = 1;
+
+ bool defined = false;
+
+ #ifdef COMPRESS_LZMA
+ if (oneMethodInfo.MethodName.CompareNoCase(L"LZMA") == 0)
+ {
+ defined = true;
+ methodFull.MethodID = k_LZMA;
+ }
+ #endif
+
+ #ifdef COMPRESS_PPMD
+ if (oneMethodInfo.MethodName.CompareNoCase(L"PPMD") == 0)
+ {
+ defined = true;
+ methodFull.MethodID = k_PPMD;
+ }
+ #endif
+
+ #ifdef COMPRESS_BCJ_X86
+ if (oneMethodInfo.MethodName.CompareNoCase(L"BCJ") == 0)
+ {
+ defined = true;
+ methodFull.MethodID = k_BCJ_X86;
+ }
+ #endif
+
+ #ifdef COMPRESS_BCJ2
+ if (oneMethodInfo.MethodName.CompareNoCase(L"BCJ2") == 0)
+ {
+ defined = true;
+ methodFull.MethodID = k_BCJ2;
+ methodFull.NumInStreams = 4;
+ methodFull.NumOutStreams = 1;
+ }
+ #endif
+
+ #ifdef COMPRESS_DEFLATE_ENCODER
+ if (oneMethodInfo.MethodName.CompareNoCase(L"Deflate") == 0)
+ {
+ defined = true;
+ methodFull.MethodID = k_Deflate;
+ }
+ #endif
+
+ #ifdef COMPRESS_BZIP2_ENCODER
+ if (oneMethodInfo.MethodName.CompareNoCase(L"BZip2") == 0)
+ {
+ defined = true;
+ methodFull.MethodID = k_BZip2;
+ }
+ #endif
+
+ #ifdef COMPRESS_COPY
+ if (oneMethodInfo.MethodName.CompareNoCase(L"Copy") == 0)
+ {
+ defined = true;
+ methodFull.MethodID = k_Copy;
+ }
+
+ #endif
+
+ #ifndef EXCLUDE_COM
+
+ if (!defined)
+ {
+ CMethodInfo2 methodInfo;
+ if (!GetMethodInfo(oneMethodInfo.MethodName, methodInfo))
+ return E_INVALIDARG;
+ if (!methodInfo.EncoderIsAssigned)
+ return E_INVALIDARG;
+
+ methodFull.MethodID = methodInfo.MethodID;
+ methodFull.NumInStreams = methodInfo.NumInStreams;
+ methodFull.NumOutStreams = methodInfo.NumOutStreams;
+
+ methodFull.EncoderClassID = methodInfo.Encoder;
+ methodFull.FilePath = methodInfo.FilePath;
+ defined = true;
+ }
+
+ #endif
+ if (!defined)
+ return E_INVALIDARG;
+
+ methodFull.CoderProperties = oneMethodInfo.CoderProperties;
+ methodMode.Methods.Add(methodFull);
+
+ if (!_numSolidBytesDefined)
+ {
+ for (int j = 0; j < methodFull.CoderProperties.Size(); j++)
+ {
+ const CProperty &prop = methodFull.CoderProperties[j];
+ if ((prop.PropID == NCoderPropID::kDictionarySize ||
+ prop.PropID == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI4)
+ {
+ _numSolidBytes = ((UInt64)prop.Value.ulVal) << 7;
+ const UInt64 kMinSize = (1 << 24);
+ if (_numSolidBytes < kMinSize)
+ _numSolidBytes = kMinSize;
+ _numSolidBytesDefined = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!needSolid && !_numSolidBytesDefined)
+ {
+ _numSolidBytesDefined = true;
+ _numSolidBytes = 0;
+ }
+ return S_OK;
+}
+
+static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, PROPID propID, CArchiveFileTime &filetime, bool &filetimeIsDefined)
+{
+ filetimeIsDefined = false;
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(index, propID, &propVariant));
+ if (propVariant.vt == VT_FILETIME)
+ {
+ filetime = propVariant.filetime;
+ filetimeIsDefined = true;
+ }
+ else if (propVariant.vt != VT_EMPTY)
+ return E_INVALIDARG;
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
+ IArchiveUpdateCallback *updateCallback)
+{
+ COM_TRY_BEGIN
+
+ const CArchiveDatabaseEx *database = 0;
+ #ifdef _7Z_VOL
+ if(_volumes.Size() > 1)
+ return E_FAIL;
+ const CVolume *volume = 0;
+ if (_volumes.Size() == 1)
+ {
+ volume = &_volumes.Front();
+ database = &volume->Database;
+ }
+ #else
+ if (_inStream != 0)
+ database = &_database;
+ #endif
+
+ // CRecordVector<bool> compressStatuses;
+ CObjectVector<CUpdateItem> updateItems;
+ // CRecordVector<UInt32> copyIndices;
+
+ // CMyComPtr<IUpdateCallback2> updateCallback2;
+ // updateCallback->QueryInterface(&updateCallback2);
+
+ for(UInt32 i = 0; i < numItems; i++)
+ {
+ Int32 newData;
+ Int32 newProperties;
+ UInt32 indexInArchive;
+ if (!updateCallback)
+ return E_FAIL;
+ RINOK(updateCallback->GetUpdateItemInfo(i,
+ &newData, &newProperties, &indexInArchive));
+ CUpdateItem updateItem;
+ updateItem.NewProperties = IntToBool(newProperties);
+ updateItem.NewData = IntToBool(newData);
+ updateItem.IndexInArchive = indexInArchive;
+ updateItem.IndexInClient = i;
+ updateItem.IsAnti = false;
+ updateItem.Size = 0;
+
+ if (updateItem.IndexInArchive != -1)
+ {
+ const CFileItem &fileItem = database->Files[updateItem.IndexInArchive];
+ updateItem.Name = fileItem.Name;
+ updateItem.IsDirectory = fileItem.IsDirectory;
+ updateItem.Size = fileItem.UnPackSize;
+ updateItem.IsAnti = fileItem.IsAnti;
+
+ updateItem.CreationTime = fileItem.CreationTime;
+ updateItem.IsCreationTimeDefined = fileItem.IsCreationTimeDefined;
+ updateItem.LastWriteTime = fileItem.LastWriteTime;
+ updateItem.IsLastWriteTimeDefined = fileItem.IsLastWriteTimeDefined;
+ updateItem.LastAccessTime = fileItem.LastAccessTime;
+ updateItem.IsLastAccessTimeDefined = fileItem.IsLastAccessTimeDefined;
+ }
+
+ if (updateItem.NewProperties)
+ {
+ bool nameIsDefined;
+ bool folderStatusIsDefined;
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ updateItem.AttributesAreDefined = false;
+ else if (propVariant.vt != VT_UI4)
+ return E_INVALIDARG;
+ else
+ {
+ updateItem.Attributes = propVariant.ulVal;
+ updateItem.AttributesAreDefined = true;
+ }
+ }
+
+ RINOK(GetTime(updateCallback, i, kpidCreationTime, updateItem.CreationTime, updateItem.IsCreationTimeDefined));
+ RINOK(GetTime(updateCallback, i, kpidLastWriteTime, updateItem.LastWriteTime , updateItem.IsLastWriteTimeDefined));
+ RINOK(GetTime(updateCallback, i, kpidLastAccessTime, updateItem.LastAccessTime, updateItem.IsLastAccessTimeDefined));
+
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(i, kpidPath, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ nameIsDefined = false;
+ else if (propVariant.vt != VT_BSTR)
+ return E_INVALIDARG;
+ else
+ {
+ updateItem.Name = NItemName::MakeLegalName(propVariant.bstrVal);
+ nameIsDefined = true;
+ }
+ }
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(i, kpidIsFolder, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ folderStatusIsDefined = false;
+ else if (propVariant.vt != VT_BOOL)
+ return E_INVALIDARG;
+ else
+ {
+ updateItem.IsDirectory = (propVariant.boolVal != VARIANT_FALSE);
+ folderStatusIsDefined = true;
+ }
+ }
+
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(i, kpidIsAnti, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ updateItem.IsAnti = false;
+ else if (propVariant.vt != VT_BOOL)
+ return E_INVALIDARG;
+ else
+ updateItem.IsAnti = (propVariant.boolVal != VARIANT_FALSE);
+ }
+
+ if (updateItem.IsAnti)
+ {
+ updateItem.AttributesAreDefined = false;
+
+ updateItem.IsCreationTimeDefined = false;
+ updateItem.IsLastWriteTimeDefined = false;
+ updateItem.IsLastAccessTimeDefined = false;
+
+ updateItem.Size = 0;
+ }
+
+ if (!folderStatusIsDefined && updateItem.AttributesAreDefined)
+ updateItem.SetDirectoryStatusFromAttributes();
+ }
+
+ if (updateItem.NewData)
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant));
+ if (propVariant.vt != VT_UI8)
+ return E_INVALIDARG;
+ updateItem.Size = (UInt64)propVariant.uhVal.QuadPart;
+ if (updateItem.Size != 0 && updateItem.IsAnti)
+ return E_INVALIDARG;
+ }
+ updateItems.Add(updateItem);
+ }
+
+ CCompressionMethodMode methodMode, headerMethod;
+ RINOK(SetCompressionMethod(methodMode, headerMethod));
+ #ifdef COMPRESS_MT
+ methodMode.NumThreads = _numThreads;
+ headerMethod.NumThreads = 1;
+ #endif
+
+ RINOK(SetPassword(methodMode, updateCallback));
+
+ bool useAdditionalHeaderStreams = true;
+ bool compressMainHeader = false;
+
+ if (_compressHeadersFull)
+ {
+ useAdditionalHeaderStreams = false;
+ compressMainHeader = true;
+ }
+ if (methodMode.PasswordIsDefined)
+ {
+ useAdditionalHeaderStreams = false;
+ compressMainHeader = true;
+ if(_encryptHeaders)
+ RINOK(SetPassword(headerMethod, updateCallback));
+ }
+
+ if (numItems < 2)
+ compressMainHeader = false;
+
+ CUpdateOptions options;
+ options.Method = &methodMode;
+ options.HeaderMethod = (_compressHeaders ||
+ (methodMode.PasswordIsDefined && _encryptHeaders)) ?
+ &headerMethod : 0;
+ options.UseFilters = _level != 0 && _autoFilter;
+ options.MaxFilter = _level >= 8;
+
+ options.HeaderOptions.UseAdditionalHeaderStreams = useAdditionalHeaderStreams;
+ options.HeaderOptions.CompressMainHeader = compressMainHeader;
+ options.HeaderOptions.WriteModified = WriteModified;
+ options.HeaderOptions.WriteCreated = WriteCreated;
+ options.HeaderOptions.WriteAccessed = WriteAccessed;
+
+ options.NumSolidFiles = _numSolidFiles;
+ options.NumSolidBytes = _numSolidBytes;
+ options.SolidExtension = _solidExtension;
+ options.RemoveSfxBlock = _removeSfxBlock;
+ options.VolumeMode = _volumeMode;
+ return Update(
+ #ifdef _7Z_VOL
+ volume ? volume->Stream: 0,
+ volume ? database: 0,
+ #else
+ _inStream,
+ database,
+ #endif
+ updateItems, outStream, updateCallback, options);
+ COM_TRY_END
+}
+
+static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream)
+{
+ stream = 0;
+ int index = ParseStringToUInt32(srcString, coder);
+ if (index == 0)
+ return E_INVALIDARG;
+ srcString.Delete(0, index);
+ if (srcString[0] == 'S')
+ {
+ srcString.Delete(0);
+ int index = ParseStringToUInt32(srcString, stream);
+ if (index == 0)
+ return E_INVALIDARG;
+ srcString.Delete(0, index);
+ }
+ return S_OK;
+}
+
+static HRESULT GetBindInfo(UString &srcString, CBind &bind)
+{
+ RINOK(GetBindInfoPart(srcString, bind.OutCoder, bind.OutStream));
+ if (srcString[0] != ':')
+ return E_INVALIDARG;
+ srcString.Delete(0);
+ RINOK(GetBindInfoPart(srcString, bind.InCoder, bind.InStream));
+ if (!srcString.IsEmpty())
+ return E_INVALIDARG;
+ return S_OK;
+}
+
+static void SplitParams(const UString &srcString, UStringVector &subStrings)
+{
+ subStrings.Clear();
+ UString name;
+ int len = srcString.Length();
+ if (len == 0)
+ return;
+ for (int i = 0; i < len; i++)
+ {
+ wchar_t c = srcString[i];
+ if (c == L':')
+ {
+ subStrings.Add(name);
+ name.Empty();
+ }
+ else
+ name += c;
+ }
+ subStrings.Add(name);
+}
+
+static void SplitParam(const UString &param, UString &name, UString &value)
+{
+ int eqPos = param.Find(L'=');
+ if (eqPos >= 0)
+ {
+ name = param.Left(eqPos);
+ value = param.Mid(eqPos + 1);
+ return;
+ }
+ for(int i = 0; i < param.Length(); i++)
+ {
+ wchar_t c = param[i];
+ if (c >= L'0' && c <= L'9')
+ {
+ name = param.Left(i);
+ value = param.Mid(i);
+ return;
+ }
+ }
+ name = param;
+}
+
+HRESULT CHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value)
+{
+ CProperty property;
+ if (name.CompareNoCase(L"D") == 0 || name.CompareNoCase(L"MEM") == 0)
+ {
+ UInt32 dicSize;
+ RINOK(ParsePropDictionaryValue(value, dicSize));
+ if (name.CompareNoCase(L"D") == 0)
+ property.PropID = NCoderPropID::kDictionarySize;
+ else
+ property.PropID = NCoderPropID::kUsedMemorySize;
+ property.Value = dicSize;
+ oneMethodInfo.CoderProperties.Add(property);
+ }
+ else
+ {
+ int index = FindPropIdFromStringName(name);
+ if (index < 0)
+ return E_INVALIDARG;
+
+ const CNameToPropID &nameToPropID = g_NameToPropID[index];
+ property.PropID = nameToPropID.PropID;
+
+ NCOM::CPropVariant propValue;
+
+
+ if (nameToPropID.VarType == VT_BSTR)
+ propValue = value;
+ else
+ {
+ UInt32 number;
+ if (ParseStringToUInt32(value, number) == value.Length())
+ propValue = number;
+ else
+ propValue = value;
+ }
+
+ if (!ConvertProperty(propValue, nameToPropID.VarType, property.Value))
+ return E_INVALIDARG;
+
+ oneMethodInfo.CoderProperties.Add(property);
+ }
+ return S_OK;
+}
+
+HRESULT CHandler::SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString)
+{
+ UStringVector params;
+ SplitParams(srcString, params);
+ if (params.Size() > 0)
+ oneMethodInfo.MethodName = params[0];
+ for (int i = 1; i < params.Size(); i++)
+ {
+ const UString &param = params[i];
+ UString name, value;
+ SplitParam(param, name, value);
+ RINOK(SetParam(oneMethodInfo, name, value));
+ }
+ return S_OK;
+}
+
+HRESULT CHandler::SetSolidSettings(const UString &s)
+{
+ UString s2 = s;
+ s2.MakeUpper();
+ if (s2.IsEmpty() || s2.Compare(L"ON") == 0)
+ {
+ InitSolid();
+ return S_OK;
+ }
+ if (s2.Compare(L"OFF") == 0)
+ {
+ _numSolidFiles = 1;
+ return S_OK;
+ }
+ for (int i = 0; i < s2.Length();)
+ {
+ const wchar_t *start = ((const wchar_t *)s2) + i;
+ const wchar_t *end;
+ UInt64 v = ConvertStringToUInt64(start, &end);
+ if (start == end)
+ {
+ if (s2[i++] != 'E')
+ return E_INVALIDARG;
+ _solidExtension = true;
+ continue;
+ }
+ i += (int)(end - start);
+ if (i == s2.Length())
+ return E_INVALIDARG;
+ wchar_t c = s2[i++];
+ switch(c)
+ {
+ case 'F':
+ if (v < 1)
+ v = 1;
+ _numSolidFiles = v;
+ break;
+ case 'B':
+ _numSolidBytes = v;
+ _numSolidBytesDefined = true;
+ break;
+ case 'K':
+ _numSolidBytes = (v << 10);
+ _numSolidBytesDefined = true;
+ break;
+ case 'M':
+ _numSolidBytes = (v << 20);
+ _numSolidBytesDefined = true;
+ break;
+ case 'G':
+ _numSolidBytes = (v << 30);
+ _numSolidBytesDefined = true;
+ break;
+ default:
+ return E_INVALIDARG;
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CHandler::SetSolidSettings(const PROPVARIANT &value)
+{
+ switch(value.vt)
+ {
+ case VT_EMPTY:
+ InitSolid();
+ return S_OK;
+ case VT_BSTR:
+ return SetSolidSettings(value.bstrVal);
+ default:
+ return E_INVALIDARG;
+ }
+}
+
+STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
+{
+ COM_TRY_BEGIN
+ _methods.Clear();
+ _binds.Clear();
+ Init();
+ #ifdef COMPRESS_MT
+ const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
+ #endif
+
+ UInt32 mainDicSize = 0xFFFFFFFF;
+ UInt32 mainDicMethodIndex = 0xFFFFFFFF;
+
+ UInt32 minNumber = 0;
+
+ for (int i = 0; i < numProperties; i++)
+ {
+ UString name = names[i];
+ name.MakeUpper();
+ if (name.IsEmpty())
+ return E_INVALIDARG;
+
+ const PROPVARIANT &value = values[i];
+
+ if (name[0] == 'X')
+ {
+ name.Delete(0);
+ _level = 9;
+ RINOK(ParsePropValue(name, value, _level));
+ continue;
+ }
+
+ if (name[0] == 'B')
+ {
+ name.Delete(0);
+ CBind bind;
+ RINOK(GetBindInfo(name, bind));
+ _binds.Add(bind);
+ continue;
+ }
+
+ if (name[0] == L'S')
+ {
+ name.Delete(0);
+ if (name.IsEmpty())
+ {
+ RINOK(SetSolidSettings(value));
+ }
+ else
+ {
+ RINOK(SetSolidSettings(name));
+ }
+ continue;
+ }
+
+
+ UInt32 number;
+ int index = ParseStringToUInt32(name, number);
+ UString realName = name.Mid(index);
+ if (index == 0)
+ {
+ if(name.Left(2).CompareNoCase(L"MT") == 0)
+ {
+ #ifdef COMPRESS_MT
+ RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
+ #endif
+ continue;
+ }
+ else if (name.CompareNoCase(L"RSFX") == 0)
+ {
+ RINOK(SetBoolProperty(_removeSfxBlock, value));
+ continue;
+ }
+ else if (name.CompareNoCase(L"F") == 0)
+ {
+ RINOK(SetBoolProperty(_autoFilter, value));
+ continue;
+ }
+ else if (name.CompareNoCase(L"HC") == 0)
+ {
+ RINOK(SetBoolProperty(_compressHeaders, value));
+ continue;
+ }
+ else if (name.CompareNoCase(L"HCF") == 0)
+ {
+ RINOK(SetBoolProperty(_compressHeadersFull, value));
+ continue;
+ }
+ else if (name.CompareNoCase(L"HE") == 0)
+ {
+ RINOK(SetBoolProperty(_encryptHeaders, value));
+ continue;
+ }
+ else if (name.CompareNoCase(L"TM") == 0)
+ {
+ RINOK(SetBoolProperty(WriteModified, value));
+ continue;
+ }
+ else if (name.CompareNoCase(L"TC") == 0)
+ {
+ RINOK(SetBoolProperty(WriteCreated, value));
+ continue;
+ }
+ else if (name.CompareNoCase(L"TA") == 0)
+ {
+ RINOK(SetBoolProperty(WriteAccessed, value));
+ continue;
+ }
+ else if (name.CompareNoCase(L"V") == 0)
+ {
+ RINOK(SetBoolProperty(_volumeMode, value));
+ continue;
+ }
+ number = 0;
+ }
+ if (number > 10000)
+ return E_FAIL;
+ if (number < minNumber)
+ return E_INVALIDARG;
+ number -= minNumber;
+ for(int j = _methods.Size(); j <= (int)number; j++)
+ {
+ COneMethodInfo oneMethodInfo;
+ _methods.Add(oneMethodInfo);
+ }
+
+ COneMethodInfo &oneMethodInfo = _methods[number];
+
+ if (realName.Length() == 0)
+ {
+ if (value.vt != VT_BSTR)
+ return E_INVALIDARG;
+
+ // oneMethodInfo.MethodName = UnicodeStringToMultiByte(UString(value.bstrVal));
+ RINOK(SetParams(oneMethodInfo, value.bstrVal));
+ }
+ else
+ {
+ CProperty property;
+ if (realName.Left(1).CompareNoCase(L"D") == 0)
+ {
+ UInt32 dicSize;
+ RINOK(ParsePropDictionaryValue(realName.Mid(1), value, dicSize));
+ property.PropID = NCoderPropID::kDictionarySize;
+ property.Value = dicSize;
+ oneMethodInfo.CoderProperties.Add(property);
+ if (number <= mainDicMethodIndex)
+ mainDicSize = dicSize;
+ }
+ else if (realName.Left(3).CompareNoCase(L"MEM") == 0)
+ {
+ UInt32 dicSize;
+ RINOK(ParsePropDictionaryValue(realName.Mid(3), value, dicSize));
+ property.PropID = NCoderPropID::kUsedMemorySize;
+ property.Value = dicSize;
+ oneMethodInfo.CoderProperties.Add(property);
+ if (number <= mainDicMethodIndex)
+ mainDicSize = dicSize;
+ }
+ else
+ {
+ int index = FindPropIdFromStringName(realName);
+ if (index < 0)
+ return E_INVALIDARG;
+
+ const CNameToPropID &nameToPropID = g_NameToPropID[index];
+ property.PropID = nameToPropID.PropID;
+
+ if (!ConvertProperty(value, nameToPropID.VarType, property.Value))
+ return E_INVALIDARG;
+
+ oneMethodInfo.CoderProperties.Add(property);
+ }
+ }
+ }
+
+ return S_OK;
+ COM_TRY_END
+}
+
+}}
diff --git a/CPP/7zip/Archive/7z/7zHeader.cpp b/CPP/7zip/Archive/7z/7zHeader.cpp
new file mode 100755
index 00000000..cff4d121
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zHeader.cpp
@@ -0,0 +1,19 @@
+// 7z/Header.cpp
+
+#include "StdAfx.h"
+#include "7zHeader.h"
+
+namespace NArchive {
+namespace N7z {
+
+Byte kSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C};
+Byte kFinishSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C + 1};
+
+class SignatureInitializer
+{
+public:
+ SignatureInitializer() { kSignature[0]--; kFinishSignature[0]--;};
+} g_SignatureInitializer;
+
+}}
+
diff --git a/CPP/7zip/Archive/7z/7zHeader.h b/CPP/7zip/Archive/7z/7zHeader.h
new file mode 100755
index 00000000..59bc7fe5
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zHeader.h
@@ -0,0 +1,96 @@
+// 7z/7zHeader.h
+
+#ifndef __7Z_HEADER_H
+#define __7Z_HEADER_H
+
+#include "7zMethodID.h"
+
+namespace NArchive {
+namespace N7z {
+
+const int kSignatureSize = 6;
+extern Byte kSignature[kSignatureSize];
+
+// #define _7Z_VOL
+// 7z-MultiVolume is not finished yet.
+// It can work already, but I still do not like some
+// things of that new multivolume format.
+// So please keep it commented.
+
+#ifdef _7Z_VOL
+extern Byte kFinishSignature[kSignatureSize];
+#endif
+
+struct CArchiveVersion
+{
+ Byte Major;
+ Byte Minor;
+};
+
+const Byte kMajorVersion = 0;
+
+struct CStartHeader
+{
+ UInt64 NextHeaderOffset;
+ UInt64 NextHeaderSize;
+ UInt32 NextHeaderCRC;
+};
+
+const UInt32 kStartHeaderSize = 20;
+
+#ifdef _7Z_VOL
+struct CFinishHeader: public CStartHeader
+{
+ UInt64 ArchiveStartOffset; // data offset from end if that struct
+ UInt64 AdditionalStartBlockSize; // start signature & start header size
+};
+
+const UInt32 kFinishHeaderSize = kStartHeaderSize + 16;
+#endif
+
+namespace NID
+{
+ enum EEnum
+ {
+ kEnd,
+
+ kHeader,
+
+ kArchiveProperties,
+
+ kAdditionalStreamsInfo,
+ kMainStreamsInfo,
+ kFilesInfo,
+
+ kPackInfo,
+ kUnPackInfo,
+ kSubStreamsInfo,
+
+ kSize,
+ kCRC,
+
+ kFolder,
+
+ kCodersUnPackSize,
+ kNumUnPackStream,
+
+ kEmptyStream,
+ kEmptyFile,
+ kAnti,
+
+ kName,
+ kCreationTime,
+ kLastAccessTime,
+ kLastWriteTime,
+ kWinAttributes,
+ kComment,
+
+ kEncodedHeader,
+
+ kStartPos
+ };
+}
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/7z/7zIn.cpp b/CPP/7zip/Archive/7z/7zIn.cpp
new file mode 100755
index 00000000..53d78b1a
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zIn.cpp
@@ -0,0 +1,1335 @@
+// 7zIn.cpp
+
+#include "StdAfx.h"
+
+#include "7zIn.h"
+#include "7zMethods.h"
+#include "7zDecode.h"
+#include "../../Common/StreamObjects.h"
+#include "../../Common/StreamUtils.h"
+#include "../../../Common/CRC.h"
+
+// define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader
+// #define FORMAT_7Z_RECOVERY
+
+namespace NArchive {
+namespace N7z {
+
+class CStreamSwitch
+{
+ CInArchive *_archive;
+ bool _needRemove;
+public:
+ CStreamSwitch(): _needRemove(false) {}
+ ~CStreamSwitch() { Remove(); }
+ void Remove();
+ void Set(CInArchive *archive, const Byte *data, size_t size);
+ void Set(CInArchive *archive, const CByteBuffer &byteBuffer);
+ HRESULT Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector);
+};
+
+void CStreamSwitch::Remove()
+{
+ if (_needRemove)
+ {
+ _archive->DeleteByteStream();
+ _needRemove = false;
+ }
+}
+
+void CStreamSwitch::Set(CInArchive *archive, const Byte *data, size_t size)
+{
+ Remove();
+ _archive = archive;
+ _archive->AddByteStream(data, size);
+ _needRemove = true;
+}
+
+void CStreamSwitch::Set(CInArchive *archive, const CByteBuffer &byteBuffer)
+{
+ Set(archive, byteBuffer, byteBuffer.GetCapacity());
+}
+
+HRESULT CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector)
+{
+ Remove();
+ Byte external;
+ RINOK(archive->ReadByte(external));
+ if (external != 0)
+ {
+ CNum dataIndex;
+ RINOK(archive->ReadNum(dataIndex));
+ Set(archive, (*dataVector)[dataIndex]);
+ }
+ return S_OK;
+}
+
+
+CInArchiveException::CInArchiveException(CCauseType cause):
+ Cause(cause)
+{}
+
+HRESULT CInArchive::ReadDirect(IInStream *stream, void *data, UInt32 size,
+ UInt32 *processedSize)
+{
+ UInt32 realProcessedSize;
+ HRESULT result = ReadStream(stream, data, size, &realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ _position += realProcessedSize;
+ return result;
+}
+
+HRESULT CInArchive::ReadDirect(void *data, UInt32 size, UInt32 *processedSize)
+{
+ return ReadDirect(_stream, data, size, processedSize);
+}
+
+HRESULT CInArchive::SafeReadDirect(void *data, UInt32 size)
+{
+ UInt32 realProcessedSize;
+ RINOK(ReadDirect(data, size, &realProcessedSize));
+ if (realProcessedSize != size)
+ throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
+ return S_OK;
+}
+
+HRESULT CInArchive::SafeReadDirectByte(Byte &b)
+{
+ return SafeReadDirect(&b, 1);
+}
+
+HRESULT CInArchive::SafeReadDirectUInt32(UInt32 &value)
+{
+ value = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ Byte b;
+ RINOK(SafeReadDirectByte(b));
+ value |= (UInt32(b) << (8 * i));
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::SafeReadDirectUInt64(UInt64 &value)
+{
+ value = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ Byte b;
+ RINOK(SafeReadDirectByte(b));
+ value |= (UInt64(b) << (8 * i));
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadNumber(UInt64 &value)
+{
+ Byte firstByte;
+ RINOK(ReadByte(firstByte));
+ Byte mask = 0x80;
+ value = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ if ((firstByte & mask) == 0)
+ {
+ UInt64 highPart = firstByte & (mask - 1);
+ value += (highPart << (i * 8));
+ return S_OK;
+ }
+ Byte b;
+ RINOK(ReadByte(b));
+ value |= (UInt64(b) << (8 * i));
+ mask >>= 1;
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadNum(CNum &value)
+{
+ UInt64 value64;
+ RINOK(ReadNumber(value64));
+ if (value64 > kNumMax)
+ return E_FAIL;
+ value = (CNum)value64;
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadUInt32(UInt32 &value)
+{
+ value = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ Byte b;
+ RINOK(ReadByte(b));
+ value |= (UInt32(b) << (8 * i));
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadUInt64(UInt64 &value)
+{
+ value = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ Byte b;
+ RINOK(ReadByte(b));
+ value |= (UInt64(b) << (8 * i));
+ }
+ return S_OK;
+}
+
+static inline bool TestSignatureCandidate(const void *testBytes)
+{
+ for (int i = 0; i < kSignatureSize; i++)
+ if (((const Byte *)testBytes)[i] != kSignature[i])
+ return false;
+ return true;
+}
+
+#ifdef _7Z_VOL
+static inline bool TestFinishSignatureCandidate(const void *testBytes)
+{
+ for (int i = 0; i < kSignatureSize; i++)
+ if (((const Byte *)testBytes)[i] != kFinishSignature[i])
+ return false;
+ return true;
+}
+#endif
+
+HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
+{
+ _position = _arhiveBeginStreamPosition;
+ RINOK(stream->Seek(_arhiveBeginStreamPosition, STREAM_SEEK_SET, NULL));
+
+ Byte signature[kSignatureSize];
+ UInt32 processedSize;
+ RINOK(ReadDirect(stream, signature, kSignatureSize, &processedSize));
+ if(processedSize != kSignatureSize)
+ return S_FALSE;
+ if (TestSignatureCandidate(signature))
+ return S_OK;
+
+ CByteBuffer byteBuffer;
+ const UInt32 kBufferSize = (1 << 16);
+ byteBuffer.SetCapacity(kBufferSize);
+ Byte *buffer = byteBuffer;
+ UInt32 numPrevBytes = kSignatureSize - 1;
+ memmove(buffer, signature + 1, numPrevBytes);
+ UInt64 curTestPos = _arhiveBeginStreamPosition + 1;
+ for (;;)
+ {
+ if (searchHeaderSizeLimit != NULL)
+ if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit)
+ break;
+ UInt32 numReadBytes = kBufferSize - numPrevBytes;
+ RINOK(ReadDirect(stream, buffer + numPrevBytes, numReadBytes, &processedSize));
+ UInt32 numBytesInBuffer = numPrevBytes + processedSize;
+ if (numBytesInBuffer < kSignatureSize)
+ break;
+ UInt32 numTests = numBytesInBuffer - kSignatureSize + 1;
+ for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++)
+ {
+ if (TestSignatureCandidate(buffer + pos))
+ {
+ _arhiveBeginStreamPosition = curTestPos;
+ _position = curTestPos + kSignatureSize;
+ return stream->Seek(_position, STREAM_SEEK_SET, NULL);
+ }
+ }
+ numPrevBytes = numBytesInBuffer - numTests;
+ memmove(buffer, buffer + numTests, numPrevBytes);
+ }
+ return S_FALSE;
+}
+
+// Out: _position must point to end of signature
+
+#ifdef _7Z_VOL
+HRESULT CInArchive::FindFinishSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
+{
+ RINOK(stream->Seek(0, STREAM_SEEK_END, &_position));
+ if (_position < kSignatureSize)
+ return S_FALSE;
+
+ CByteBuffer byteBuffer;
+ const UInt32 kBufferSize = (1 << 18);
+ byteBuffer.SetCapacity(kBufferSize);
+ Byte *buffer = byteBuffer;
+ UInt32 numPrevBytes = 0;
+ UInt64 limitPos = 0;
+ if (searchHeaderSizeLimit != NULL)
+ if (*searchHeaderSizeLimit < _position)
+ limitPos = _position - *searchHeaderSizeLimit;
+
+ while(_position >= limitPos)
+ {
+ UInt32 numReadBytes = kBufferSize - numPrevBytes;
+ if (numReadBytes > _position)
+ numReadBytes = (UInt32)_position;
+ UInt32 numBytesInBuffer = numPrevBytes + numReadBytes;
+ if (numBytesInBuffer < kSignatureSize)
+ return S_FALSE;
+ _position -= numReadBytes;
+ RINOK(stream->Seek(_position, STREAM_SEEK_SET, &_position));
+ UInt32 startPos = kBufferSize - numBytesInBuffer;
+ UInt32 processedSize;
+ RINOK(ReadDirect(stream, buffer + startPos, numReadBytes, &processedSize));
+ if (processedSize != numReadBytes)
+ return S_FALSE;
+ _position -= processedSize;
+ for(UInt32 pos = kBufferSize; pos >= startPos + kSignatureSize; pos--)
+ {
+ if (TestFinishSignatureCandidate(buffer + pos - kSignatureSize))
+ {
+ _position += pos - startPos;
+ return stream->Seek(_position, STREAM_SEEK_SET, NULL);
+ }
+ }
+ numPrevBytes = kSignatureSize - 1;
+ memmove(buffer + kBufferSize - numPrevBytes, buffer + startPos + 1, numPrevBytes);
+ }
+ return S_FALSE;
+}
+#endif
+
+// S_FALSE means that file is not archive
+HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
+{
+ Close();
+ RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition))
+ _position = _arhiveBeginStreamPosition;
+ #ifdef _7Z_VOL
+ HRESULT result = FindFinishSignature(stream, searchHeaderSizeLimit);
+ if (result == S_OK)
+ _finishSignature = true;
+ else
+ {
+ if (result != S_FALSE)
+ return result;
+ _finishSignature = false;
+ RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit));
+ }
+ #else
+ RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit));
+ #endif
+ _stream = stream;
+ return S_OK;
+}
+
+void CInArchive::Close()
+{
+ _stream.Release();
+}
+
+HRESULT CInArchive::SkeepData(UInt64 size)
+{
+ for (UInt64 i = 0; i < size; i++)
+ {
+ Byte temp;
+ RINOK(ReadByte(temp));
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::SkeepData()
+{
+ UInt64 size;
+ RINOK(ReadNumber(size));
+ return SkeepData(size);
+}
+
+HRESULT CInArchive::ReadArchiveProperties(CInArchiveInfo & /* archiveInfo */)
+{
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(ReadID(type));
+ if (type == NID::kEnd)
+ break;
+ SkeepData();
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::GetNextFolderItem(CFolder &folder)
+{
+ CNum numCoders;
+ RINOK(ReadNum(numCoders));
+
+ folder.Coders.Clear();
+ folder.Coders.Reserve((int)numCoders);
+ CNum numInStreams = 0;
+ CNum numOutStreams = 0;
+ CNum i;
+ for (i = 0; i < numCoders; i++)
+ {
+ folder.Coders.Add(CCoderInfo());
+ CCoderInfo &coder = folder.Coders.Back();
+
+ for (;;)
+ {
+ coder.AltCoders.Add(CAltCoderInfo());
+ CAltCoderInfo &altCoder = coder.AltCoders.Back();
+ Byte mainByte = 0;
+ RINOK(ReadByte(mainByte));
+ altCoder.MethodID.IDSize = (Byte)(mainByte & 0xF);
+ RINOK(ReadBytes(altCoder.MethodID.ID, altCoder.MethodID.IDSize));
+ if ((mainByte & 0x10) != 0)
+ {
+ RINOK(ReadNum(coder.NumInStreams));
+ RINOK(ReadNum(coder.NumOutStreams));
+ }
+ else
+ {
+ coder.NumInStreams = 1;
+ coder.NumOutStreams = 1;
+ }
+ if ((mainByte & 0x20) != 0)
+ {
+ CNum propertiesSize = 0;
+ RINOK(ReadNum(propertiesSize));
+ altCoder.Properties.SetCapacity((size_t)propertiesSize);
+ RINOK(ReadBytes((Byte *)altCoder.Properties, (size_t)propertiesSize));
+ }
+ if ((mainByte & 0x80) == 0)
+ break;
+ }
+ numInStreams += coder.NumInStreams;
+ numOutStreams += coder.NumOutStreams;
+ }
+
+ CNum numBindPairs;
+ // RINOK(ReadNumber(numBindPairs));
+ numBindPairs = numOutStreams - 1;
+ folder.BindPairs.Clear();
+ folder.BindPairs.Reserve(numBindPairs);
+ for (i = 0; i < numBindPairs; i++)
+ {
+ CBindPair bindPair;
+ RINOK(ReadNum(bindPair.InIndex));
+ RINOK(ReadNum(bindPair.OutIndex));
+ folder.BindPairs.Add(bindPair);
+ }
+
+ CNum numPackedStreams = numInStreams - numBindPairs;
+ folder.PackStreams.Reserve(numPackedStreams);
+ if (numPackedStreams == 1)
+ {
+ for (CNum j = 0; j < numInStreams; j++)
+ if (folder.FindBindPairForInStream(j) < 0)
+ {
+ folder.PackStreams.Add(j);
+ break;
+ }
+ }
+ else
+ for(i = 0; i < numPackedStreams; i++)
+ {
+ CNum packStreamInfo;
+ RINOK(ReadNum(packStreamInfo));
+ folder.PackStreams.Add(packStreamInfo);
+ }
+
+ return S_OK;
+}
+
+HRESULT CInArchive::WaitAttribute(UInt64 attribute)
+{
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(ReadID(type));
+ if (type == attribute)
+ return S_OK;
+ if (type == NID::kEnd)
+ return S_FALSE;
+ RINOK(SkeepData());
+ }
+}
+
+HRESULT CInArchive::ReadHashDigests(int numItems,
+ CRecordVector<bool> &digestsDefined,
+ CRecordVector<UInt32> &digests)
+{
+ RINOK(ReadBoolVector2(numItems, digestsDefined));
+ digests.Clear();
+ digests.Reserve(numItems);
+ for(int i = 0; i < numItems; i++)
+ {
+ UInt32 crc = 0;
+ if (digestsDefined[i])
+ RINOK(ReadUInt32(crc));
+ digests.Add(crc);
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadPackInfo(
+ UInt64 &dataOffset,
+ CRecordVector<UInt64> &packSizes,
+ CRecordVector<bool> &packCRCsDefined,
+ CRecordVector<UInt32> &packCRCs)
+{
+ RINOK(ReadNumber(dataOffset));
+ CNum numPackStreams;
+ RINOK(ReadNum(numPackStreams));
+
+ RINOK(WaitAttribute(NID::kSize));
+ packSizes.Clear();
+ packSizes.Reserve(numPackStreams);
+ for(CNum i = 0; i < numPackStreams; i++)
+ {
+ UInt64 size;
+ RINOK(ReadNumber(size));
+ packSizes.Add(size);
+ }
+
+ UInt64 type;
+ for (;;)
+ {
+ RINOK(ReadID(type));
+ if (type == NID::kEnd)
+ break;
+ if (type == NID::kCRC)
+ {
+ RINOK(ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs));
+ continue;
+ }
+ RINOK(SkeepData());
+ }
+ if (packCRCsDefined.IsEmpty())
+ {
+ packCRCsDefined.Reserve(numPackStreams);
+ packCRCsDefined.Clear();
+ packCRCs.Reserve(numPackStreams);
+ packCRCs.Clear();
+ for(CNum i = 0; i < numPackStreams; i++)
+ {
+ packCRCsDefined.Add(false);
+ packCRCs.Add(0);
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadUnPackInfo(
+ const CObjectVector<CByteBuffer> *dataVector,
+ CObjectVector<CFolder> &folders)
+{
+ RINOK(WaitAttribute(NID::kFolder));
+ CNum numFolders;
+ RINOK(ReadNum(numFolders));
+
+ {
+ CStreamSwitch streamSwitch;
+ RINOK(streamSwitch.Set(this, dataVector));
+ folders.Clear();
+ folders.Reserve((UInt32)numFolders);
+ for(CNum i = 0; i < numFolders; i++)
+ {
+ folders.Add(CFolder());
+ RINOK(GetNextFolderItem(folders.Back()));
+ }
+ }
+
+ RINOK(WaitAttribute(NID::kCodersUnPackSize));
+
+ CNum i;
+ for(i = 0; i < numFolders; i++)
+ {
+ CFolder &folder = folders[i];
+ CNum numOutStreams = folder.GetNumOutStreams();
+ folder.UnPackSizes.Reserve(numOutStreams);
+ for(CNum j = 0; j < numOutStreams; j++)
+ {
+ UInt64 unPackSize;
+ RINOK(ReadNumber(unPackSize));
+ folder.UnPackSizes.Add(unPackSize);
+ }
+ }
+
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(ReadID(type));
+ if (type == NID::kEnd)
+ return S_OK;
+ if (type == NID::kCRC)
+ {
+ CRecordVector<bool> crcsDefined;
+ CRecordVector<UInt32> crcs;
+ RINOK(ReadHashDigests(numFolders, crcsDefined, crcs));
+ for(i = 0; i < numFolders; i++)
+ {
+ CFolder &folder = folders[i];
+ folder.UnPackCRCDefined = crcsDefined[i];
+ folder.UnPackCRC = crcs[i];
+ }
+ continue;
+ }
+ RINOK(SkeepData());
+ }
+}
+
+HRESULT CInArchive::ReadSubStreamsInfo(
+ const CObjectVector<CFolder> &folders,
+ CRecordVector<CNum> &numUnPackStreamsInFolders,
+ CRecordVector<UInt64> &unPackSizes,
+ CRecordVector<bool> &digestsDefined,
+ CRecordVector<UInt32> &digests)
+{
+ numUnPackStreamsInFolders.Clear();
+ numUnPackStreamsInFolders.Reserve(folders.Size());
+ UInt64 type;
+ for (;;)
+ {
+ RINOK(ReadID(type));
+ if (type == NID::kNumUnPackStream)
+ {
+ for(int i = 0; i < folders.Size(); i++)
+ {
+ CNum value;
+ RINOK(ReadNum(value));
+ numUnPackStreamsInFolders.Add(value);
+ }
+ continue;
+ }
+ if (type == NID::kCRC || type == NID::kSize)
+ break;
+ if (type == NID::kEnd)
+ break;
+ RINOK(SkeepData());
+ }
+
+ if (numUnPackStreamsInFolders.IsEmpty())
+ for(int i = 0; i < folders.Size(); i++)
+ numUnPackStreamsInFolders.Add(1);
+
+ int i;
+ for(i = 0; i < numUnPackStreamsInFolders.Size(); i++)
+ {
+ // v3.13 incorrectly worked with empty folders
+ // v4.07: we check that folder is empty
+ CNum numSubstreams = numUnPackStreamsInFolders[i];
+ if (numSubstreams == 0)
+ continue;
+ UInt64 sum = 0;
+ for (CNum j = 1; j < numSubstreams; j++)
+ {
+ UInt64 size;
+ if (type == NID::kSize)
+ {
+ RINOK(ReadNumber(size));
+ unPackSizes.Add(size);
+ sum += size;
+ }
+ }
+ unPackSizes.Add(folders[i].GetUnPackSize() - sum);
+ }
+ if (type == NID::kSize)
+ {
+ RINOK(ReadID(type));
+ }
+
+ int numDigests = 0;
+ int numDigestsTotal = 0;
+ for(i = 0; i < folders.Size(); i++)
+ {
+ CNum numSubstreams = numUnPackStreamsInFolders[i];
+ if (numSubstreams != 1 || !folders[i].UnPackCRCDefined)
+ numDigests += numSubstreams;
+ numDigestsTotal += numSubstreams;
+ }
+
+ for (;;)
+ {
+ if (type == NID::kCRC)
+ {
+ CRecordVector<bool> digestsDefined2;
+ CRecordVector<UInt32> digests2;
+ RINOK(ReadHashDigests(numDigests, digestsDefined2, digests2));
+ int digestIndex = 0;
+ for (i = 0; i < folders.Size(); i++)
+ {
+ CNum numSubstreams = numUnPackStreamsInFolders[i];
+ const CFolder &folder = folders[i];
+ if (numSubstreams == 1 && folder.UnPackCRCDefined)
+ {
+ digestsDefined.Add(true);
+ digests.Add(folder.UnPackCRC);
+ }
+ else
+ for (CNum j = 0; j < numSubstreams; j++, digestIndex++)
+ {
+ digestsDefined.Add(digestsDefined2[digestIndex]);
+ digests.Add(digests2[digestIndex]);
+ }
+ }
+ }
+ else if (type == NID::kEnd)
+ {
+ if (digestsDefined.IsEmpty())
+ {
+ digestsDefined.Clear();
+ digests.Clear();
+ for (int i = 0; i < numDigestsTotal; i++)
+ {
+ digestsDefined.Add(false);
+ digests.Add(0);
+ }
+ }
+ return S_OK;
+ }
+ else
+ {
+ RINOK(SkeepData());
+ }
+ RINOK(ReadID(type));
+ }
+}
+
+HRESULT CInArchive::ReadStreamsInfo(
+ const CObjectVector<CByteBuffer> *dataVector,
+ UInt64 &dataOffset,
+ CRecordVector<UInt64> &packSizes,
+ CRecordVector<bool> &packCRCsDefined,
+ CRecordVector<UInt32> &packCRCs,
+ CObjectVector<CFolder> &folders,
+ CRecordVector<CNum> &numUnPackStreamsInFolders,
+ CRecordVector<UInt64> &unPackSizes,
+ CRecordVector<bool> &digestsDefined,
+ CRecordVector<UInt32> &digests)
+{
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(ReadID(type));
+ switch(type)
+ {
+ case NID::kEnd:
+ return S_OK;
+ case NID::kPackInfo:
+ {
+ RINOK(ReadPackInfo(dataOffset, packSizes,
+ packCRCsDefined, packCRCs));
+ break;
+ }
+ case NID::kUnPackInfo:
+ {
+ RINOK(ReadUnPackInfo(dataVector, folders));
+ break;
+ }
+ case NID::kSubStreamsInfo:
+ {
+ RINOK(ReadSubStreamsInfo(folders, numUnPackStreamsInFolders,
+ unPackSizes, digestsDefined, digests));
+ break;
+ }
+ }
+ }
+}
+
+HRESULT CInArchive::ReadFileNames(CObjectVector<CFileItem> &files)
+{
+ for(int i = 0; i < files.Size(); i++)
+ {
+ UString &name = files[i].Name;
+ name.Empty();
+ for (;;)
+ {
+ wchar_t c;
+ RINOK(ReadWideCharLE(c));
+ if (c == L'\0')
+ break;
+ name += c;
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadBoolVector(int numItems, CBoolVector &v)
+{
+ v.Clear();
+ v.Reserve(numItems);
+ Byte b = 0;
+ Byte mask = 0;
+ for(int i = 0; i < numItems; i++)
+ {
+ if (mask == 0)
+ {
+ RINOK(ReadByte(b));
+ mask = 0x80;
+ }
+ v.Add((b & mask) != 0);
+ mask >>= 1;
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadBoolVector2(int numItems, CBoolVector &v)
+{
+ Byte allAreDefined;
+ RINOK(ReadByte(allAreDefined));
+ if (allAreDefined == 0)
+ return ReadBoolVector(numItems, v);
+ v.Clear();
+ v.Reserve(numItems);
+ for (int i = 0; i < numItems; i++)
+ v.Add(true);
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadTime(const CObjectVector<CByteBuffer> &dataVector,
+ CObjectVector<CFileItem> &files, UInt64 type)
+{
+ CBoolVector boolVector;
+ RINOK(ReadBoolVector2(files.Size(), boolVector))
+
+ CStreamSwitch streamSwitch;
+ RINOK(streamSwitch.Set(this, &dataVector));
+
+ for(int i = 0; i < files.Size(); i++)
+ {
+ CFileItem &file = files[i];
+ CArchiveFileTime fileTime;
+ fileTime.dwLowDateTime = 0;
+ fileTime.dwHighDateTime = 0;
+ bool defined = boolVector[i];
+ if (defined)
+ {
+ UInt32 low, high;
+ RINOK(ReadUInt32(low));
+ RINOK(ReadUInt32(high));
+ fileTime.dwLowDateTime = low;
+ fileTime.dwHighDateTime = high;
+ }
+ switch(type)
+ {
+ case NID::kCreationTime:
+ file.IsCreationTimeDefined = defined;
+ if (defined)
+ file.CreationTime = fileTime;
+ break;
+ case NID::kLastWriteTime:
+ file.IsLastWriteTimeDefined = defined;
+ if (defined)
+ file.LastWriteTime = fileTime;
+ break;
+ case NID::kLastAccessTime:
+ file.IsLastAccessTimeDefined = defined;
+ if (defined)
+ file.LastAccessTime = fileTime;
+ break;
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadAndDecodePackedStreams(UInt64 baseOffset,
+ UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPassword
+ #endif
+ )
+{
+ CRecordVector<UInt64> packSizes;
+ CRecordVector<bool> packCRCsDefined;
+ CRecordVector<UInt32> packCRCs;
+ CObjectVector<CFolder> folders;
+
+ CRecordVector<CNum> numUnPackStreamsInFolders;
+ CRecordVector<UInt64> unPackSizes;
+ CRecordVector<bool> digestsDefined;
+ CRecordVector<UInt32> digests;
+
+ RINOK(ReadStreamsInfo(NULL,
+ dataOffset,
+ packSizes,
+ packCRCsDefined,
+ packCRCs,
+ folders,
+ numUnPackStreamsInFolders,
+ unPackSizes,
+ digestsDefined,
+ digests));
+
+ // database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader;
+
+ CNum packIndex = 0;
+ CDecoder decoder(
+ #ifdef _ST_MODE
+ false
+ #else
+ true
+ #endif
+ );
+ UInt64 dataStartPos = baseOffset + dataOffset;
+ for(int i = 0; i < folders.Size(); i++)
+ {
+ const CFolder &folder = folders[i];
+ dataVector.Add(CByteBuffer());
+ CByteBuffer &data = dataVector.Back();
+ UInt64 unPackSize = folder.GetUnPackSize();
+ if (unPackSize > kNumMax)
+ return E_FAIL;
+ if (unPackSize > 0xFFFFFFFF)
+ return E_FAIL;
+ data.SetCapacity((size_t)unPackSize);
+
+ CSequentialOutStreamImp2 *outStreamSpec = new CSequentialOutStreamImp2;
+ CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
+ outStreamSpec->Init(data, (size_t)unPackSize);
+
+ HRESULT result = decoder.Decode(_stream, dataStartPos,
+ &packSizes[packIndex], folder, outStream, NULL
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ #ifdef COMPRESS_MT
+ , false, 1
+ #endif
+ );
+ RINOK(result);
+
+ if (folder.UnPackCRCDefined)
+ if (!CCRC::VerifyDigest(folder.UnPackCRC, data, (UInt32)unPackSize))
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+ for (int j = 0; j < folder.PackStreams.Size(); j++)
+ dataStartPos += packSizes[packIndex++];
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadHeader(CArchiveDatabaseEx &database
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPassword
+ #endif
+ )
+{
+ UInt64 type;
+ RINOK(ReadID(type));
+
+ if (type == NID::kArchiveProperties)
+ {
+ RINOK(ReadArchiveProperties(database.ArchiveInfo));
+ RINOK(ReadID(type));
+ }
+
+ CObjectVector<CByteBuffer> dataVector;
+
+ if (type == NID::kAdditionalStreamsInfo)
+ {
+ HRESULT result = ReadAndDecodePackedStreams(
+ database.ArchiveInfo.StartPositionAfterHeader,
+ database.ArchiveInfo.DataStartPosition2,
+ dataVector
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ );
+ RINOK(result);
+ database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader;
+ RINOK(ReadID(type));
+ }
+
+ CRecordVector<UInt64> unPackSizes;
+ CRecordVector<bool> digestsDefined;
+ CRecordVector<UInt32> digests;
+
+ if (type == NID::kMainStreamsInfo)
+ {
+ RINOK(ReadStreamsInfo(&dataVector,
+ database.ArchiveInfo.DataStartPosition,
+ database.PackSizes,
+ database.PackCRCsDefined,
+ database.PackCRCs,
+ database.Folders,
+ database.NumUnPackStreamsVector,
+ unPackSizes,
+ digestsDefined,
+ digests));
+ database.ArchiveInfo.DataStartPosition += database.ArchiveInfo.StartPositionAfterHeader;
+ RINOK(ReadID(type));
+ }
+ else
+ {
+ for(int i = 0; i < database.Folders.Size(); i++)
+ {
+ database.NumUnPackStreamsVector.Add(1);
+ CFolder &folder = database.Folders[i];
+ unPackSizes.Add(folder.GetUnPackSize());
+ digestsDefined.Add(folder.UnPackCRCDefined);
+ digests.Add(folder.UnPackCRC);
+ }
+ }
+
+ database.Files.Clear();
+
+ if (type == NID::kEnd)
+ return S_OK;
+ if (type != NID::kFilesInfo)
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+
+ CNum numFiles;
+ RINOK(ReadNum(numFiles));
+ database.Files.Reserve(numFiles);
+ CNum i;
+ for(i = 0; i < numFiles; i++)
+ database.Files.Add(CFileItem());
+
+ database.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize);
+ if (!database.PackSizes.IsEmpty())
+ database.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo);
+ if (numFiles > 0 && !digests.IsEmpty())
+ database.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC);
+
+ CBoolVector emptyStreamVector;
+ emptyStreamVector.Reserve((int)numFiles);
+ for(i = 0; i < numFiles; i++)
+ emptyStreamVector.Add(false);
+ CBoolVector emptyFileVector;
+ CBoolVector antiFileVector;
+ CNum numEmptyStreams = 0;
+
+ // int sizePrev = -1;
+ // int posPrev = 0;
+
+ for (;;)
+ {
+ /*
+ if (sizePrev >= 0)
+ if (sizePrev != _inByteBack->GetProcessedSize() - posPrev)
+ throw 2;
+ */
+ UInt64 type;
+ RINOK(ReadID(type));
+ if (type == NID::kEnd)
+ break;
+ UInt64 size;
+ RINOK(ReadNumber(size));
+
+ // sizePrev = size;
+ // posPrev = _inByteBack->GetProcessedSize();
+
+ database.ArchiveInfo.FileInfoPopIDs.Add(type);
+ switch(type)
+ {
+ case NID::kName:
+ {
+ CStreamSwitch streamSwitch;
+ RINOK(streamSwitch.Set(this, &dataVector));
+ RINOK(ReadFileNames(database.Files))
+ break;
+ }
+ case NID::kWinAttributes:
+ {
+ CBoolVector boolVector;
+ RINOK(ReadBoolVector2(database.Files.Size(), boolVector))
+ CStreamSwitch streamSwitch;
+ RINOK(streamSwitch.Set(this, &dataVector));
+ for(i = 0; i < numFiles; i++)
+ {
+ CFileItem &file = database.Files[i];
+ file.AreAttributesDefined = boolVector[i];
+ if (file.AreAttributesDefined)
+ {
+ RINOK(ReadUInt32(file.Attributes));
+ }
+ }
+ break;
+ }
+ case NID::kStartPos:
+ {
+ CBoolVector boolVector;
+ RINOK(ReadBoolVector2(database.Files.Size(), boolVector))
+ CStreamSwitch streamSwitch;
+ RINOK(streamSwitch.Set(this, &dataVector));
+ for(i = 0; i < numFiles; i++)
+ {
+ CFileItem &file = database.Files[i];
+ file.IsStartPosDefined = boolVector[i];
+ if (file.IsStartPosDefined)
+ {
+ RINOK(ReadUInt64(file.StartPos));
+ }
+ }
+ break;
+ }
+ case NID::kEmptyStream:
+ {
+ RINOK(ReadBoolVector(numFiles, emptyStreamVector))
+ for (i = 0; i < (CNum)emptyStreamVector.Size(); i++)
+ if (emptyStreamVector[i])
+ numEmptyStreams++;
+ emptyFileVector.Reserve(numEmptyStreams);
+ antiFileVector.Reserve(numEmptyStreams);
+ for (i = 0; i < numEmptyStreams; i++)
+ {
+ emptyFileVector.Add(false);
+ antiFileVector.Add(false);
+ }
+ break;
+ }
+ case NID::kEmptyFile:
+ {
+ RINOK(ReadBoolVector(numEmptyStreams, emptyFileVector))
+ break;
+ }
+ case NID::kAnti:
+ {
+ RINOK(ReadBoolVector(numEmptyStreams, antiFileVector))
+ break;
+ }
+ case NID::kCreationTime:
+ case NID::kLastWriteTime:
+ case NID::kLastAccessTime:
+ {
+ RINOK(ReadTime(dataVector, database.Files, type))
+ break;
+ }
+ default:
+ {
+ database.ArchiveInfo.FileInfoPopIDs.DeleteBack();
+ RINOK(SkeepData(size));
+ }
+ }
+ }
+
+ CNum emptyFileIndex = 0;
+ CNum sizeIndex = 0;
+ for(i = 0; i < numFiles; i++)
+ {
+ CFileItem &file = database.Files[i];
+ file.HasStream = !emptyStreamVector[i];
+ if(file.HasStream)
+ {
+ file.IsDirectory = false;
+ file.IsAnti = false;
+ file.UnPackSize = unPackSizes[sizeIndex];
+ file.FileCRC = digests[sizeIndex];
+ file.IsFileCRCDefined = digestsDefined[sizeIndex];
+ sizeIndex++;
+ }
+ else
+ {
+ file.IsDirectory = !emptyFileVector[emptyFileIndex];
+ file.IsAnti = antiFileVector[emptyFileIndex];
+ emptyFileIndex++;
+ file.UnPackSize = 0;
+ file.IsFileCRCDefined = false;
+ }
+ }
+ return S_OK;
+}
+
+
+void CArchiveDatabaseEx::FillFolderStartPackStream()
+{
+ FolderStartPackStreamIndex.Clear();
+ FolderStartPackStreamIndex.Reserve(Folders.Size());
+ CNum startPos = 0;
+ for(int i = 0; i < Folders.Size(); i++)
+ {
+ FolderStartPackStreamIndex.Add(startPos);
+ startPos += (CNum)Folders[i].PackStreams.Size();
+ }
+}
+
+void CArchiveDatabaseEx::FillStartPos()
+{
+ PackStreamStartPositions.Clear();
+ PackStreamStartPositions.Reserve(PackSizes.Size());
+ UInt64 startPos = 0;
+ for(int i = 0; i < PackSizes.Size(); i++)
+ {
+ PackStreamStartPositions.Add(startPos);
+ startPos += PackSizes[i];
+ }
+}
+
+void CArchiveDatabaseEx::FillFolderStartFileIndex()
+{
+ FolderStartFileIndex.Clear();
+ FolderStartFileIndex.Reserve(Folders.Size());
+ FileIndexToFolderIndexMap.Clear();
+ FileIndexToFolderIndexMap.Reserve(Files.Size());
+
+ int folderIndex = 0;
+ CNum indexInFolder = 0;
+ for (int i = 0; i < Files.Size(); i++)
+ {
+ const CFileItem &file = Files[i];
+ bool emptyStream = !file.HasStream;
+ if (emptyStream && indexInFolder == 0)
+ {
+ FileIndexToFolderIndexMap.Add(kNumNoIndex);
+ continue;
+ }
+ if (indexInFolder == 0)
+ {
+ // v3.13 incorrectly worked with empty folders
+ // v4.07: Loop for skipping empty folders
+ for (;;)
+ {
+ if (folderIndex >= Folders.Size())
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+ FolderStartFileIndex.Add(i); // check it
+ if (NumUnPackStreamsVector[folderIndex] != 0)
+ break;
+ folderIndex++;
+ }
+ }
+ FileIndexToFolderIndexMap.Add(folderIndex);
+ if (emptyStream)
+ continue;
+ indexInFolder++;
+ if (indexInFolder >= NumUnPackStreamsVector[folderIndex])
+ {
+ folderIndex++;
+ indexInFolder = 0;
+ }
+ }
+}
+
+HRESULT CInArchive::ReadDatabase(CArchiveDatabaseEx &database
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPassword
+ #endif
+ )
+{
+ database.Clear();
+ database.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition;
+
+
+ RINOK(SafeReadDirect(&database.ArchiveInfo.Version.Major, 1));
+ RINOK(SafeReadDirect(&database.ArchiveInfo.Version.Minor, 1));
+ if (database.ArchiveInfo.Version.Major != kMajorVersion)
+ throw CInArchiveException(CInArchiveException::kUnsupportedVersion);
+
+ #ifdef _7Z_VOL
+ if (_finishSignature)
+ {
+ RINOK(_stream->Seek(_position - (4 + kFinishHeaderSize) -
+ (kSignatureSize + 2), STREAM_SEEK_SET, &_position));
+ }
+ #endif
+
+ UInt32 crcFromArchive;
+ UInt64 nextHeaderOffset;
+ UInt64 nextHeaderSize;
+ UInt32 nextHeaderCRC;
+ CCRC crc;
+ RINOK(SafeReadDirectUInt32(crcFromArchive));
+ RINOK(SafeReadDirectUInt64(nextHeaderOffset));
+ RINOK(SafeReadDirectUInt64(nextHeaderSize));
+ RINOK(SafeReadDirectUInt32(nextHeaderCRC));
+
+ #ifdef FORMAT_7Z_RECOVERY
+ if (crcFromArchive == 0 && nextHeaderOffset == 0 && nextHeaderSize == 0 && nextHeaderCRC == 0)
+ {
+ UInt64 cur, cur2;
+ RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &cur));
+ const int kCheckSize = 500;
+ Byte buf[kCheckSize];
+ RINOK(_stream->Seek(0, STREAM_SEEK_END, &cur2));
+ int checkSize = kCheckSize;
+ if (cur2 - cur < kCheckSize)
+ checkSize = (int)(cur2 - cur);
+ RINOK(_stream->Seek(-checkSize, STREAM_SEEK_END, &cur2));
+
+ UInt32 realProcessedSize;
+ RINOK(ReadDirect(buf, (UInt32)kCheckSize, &realProcessedSize));
+
+ int i;
+ for (i = (int)realProcessedSize - 2; i >= 0; i--)
+ if (buf[i] == 0x17 && buf[i + 1] == 0x6 || buf[i] == 0x01 && buf[i + 1] == 0x04)
+ break;
+ if (i < 0)
+ return S_FALSE;
+ nextHeaderSize = realProcessedSize - i;
+ nextHeaderOffset = cur2 - cur + i;
+ nextHeaderCRC = CCRC::CalculateDigest(buf + i, (size_t)nextHeaderSize);
+ RINOK(_stream->Seek(cur, STREAM_SEEK_SET, &_position));
+ }
+ #endif
+
+ crc.UpdateUInt64(nextHeaderOffset);
+ crc.UpdateUInt64(nextHeaderSize);
+ crc.UpdateUInt32(nextHeaderCRC);
+
+ #ifdef FORMAT_7Z_RECOVERY
+ crcFromArchive = crc.GetDigest();
+ #endif
+
+ #ifdef _7Z_VOL
+ UInt64 archiveStartOffset; // data offset from end if that struct
+ UInt64 additionalStartBlockSize; // start signature & start header size
+ if (_finishSignature)
+ {
+ RINOK(SafeReadDirectUInt64(archiveStartOffset));
+ crc.UpdateUInt64(archiveStartOffset);
+ RINOK(SafeReadDirectUInt64(additionalStartBlockSize));
+ crc.UpdateUInt64(additionalStartBlockSize);
+ database.ArchiveInfo.StartPositionAfterHeader = _position + archiveStartOffset;
+ }
+ else
+ #endif
+ {
+ database.ArchiveInfo.StartPositionAfterHeader = _position;
+ }
+ if (crc.GetDigest() != crcFromArchive)
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+
+ if (nextHeaderSize == 0)
+ return S_OK;
+
+ if (nextHeaderSize >= 0xFFFFFFFF)
+ return E_FAIL;
+
+ RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, &_position));
+
+ CByteBuffer buffer2;
+ buffer2.SetCapacity((size_t)nextHeaderSize);
+ RINOK(SafeReadDirect(buffer2, (UInt32)nextHeaderSize));
+ if (!CCRC::VerifyDigest(nextHeaderCRC, buffer2, (UInt32)nextHeaderSize))
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+
+ CStreamSwitch streamSwitch;
+ streamSwitch.Set(this, buffer2);
+
+ CObjectVector<CByteBuffer> dataVector;
+
+ for (;;)
+ {
+ UInt64 type;
+ RINOK(ReadID(type));
+ if (type == NID::kHeader)
+ break;
+ if (type != NID::kEncodedHeader)
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+ HRESULT result = ReadAndDecodePackedStreams(
+ database.ArchiveInfo.StartPositionAfterHeader,
+ database.ArchiveInfo.DataStartPosition2,
+ dataVector
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ );
+ RINOK(result);
+ if (dataVector.Size() == 0)
+ return S_OK;
+ if (dataVector.Size() > 1)
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+ streamSwitch.Remove();
+ streamSwitch.Set(this, dataVector.Front());
+ }
+
+ return ReadHeader(database
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ );
+}
+
+}}
diff --git a/CPP/7zip/Archive/7z/7zIn.h b/CPP/7zip/Archive/7z/7zIn.h
new file mode 100755
index 00000000..4f27aa75
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zIn.h
@@ -0,0 +1,288 @@
+// 7zIn.h
+
+#ifndef __7Z_IN_H
+#define __7Z_IN_H
+
+#include "../../IStream.h"
+#include "../../IPassword.h"
+#include "../../../Common/MyCom.h"
+#include "../../Common/InBuffer.h"
+
+#include "7zHeader.h"
+#include "7zItem.h"
+
+namespace NArchive {
+namespace N7z {
+
+class CInArchiveException
+{
+public:
+ enum CCauseType
+ {
+ kUnsupportedVersion = 0,
+ kUnexpectedEndOfArchive = 0,
+ kIncorrectHeader,
+ } Cause;
+ CInArchiveException(CCauseType cause);
+};
+
+struct CInArchiveInfo
+{
+ CArchiveVersion Version;
+ UInt64 StartPosition;
+ UInt64 StartPositionAfterHeader;
+ UInt64 DataStartPosition;
+ UInt64 DataStartPosition2;
+ CRecordVector<UInt64> FileInfoPopIDs;
+ void Clear()
+ {
+ FileInfoPopIDs.Clear();
+ }
+};
+
+
+struct CArchiveDatabaseEx: public CArchiveDatabase
+{
+ CInArchiveInfo ArchiveInfo;
+ CRecordVector<UInt64> PackStreamStartPositions;
+ CRecordVector<CNum> FolderStartPackStreamIndex;
+ CRecordVector<CNum> FolderStartFileIndex;
+ CRecordVector<CNum> FileIndexToFolderIndexMap;
+
+ void Clear()
+ {
+ CArchiveDatabase::Clear();
+ ArchiveInfo.Clear();
+ PackStreamStartPositions.Clear();
+ FolderStartPackStreamIndex.Clear();
+ FolderStartFileIndex.Clear();
+ FileIndexToFolderIndexMap.Clear();
+ }
+
+ void FillFolderStartPackStream();
+ void FillStartPos();
+ void FillFolderStartFileIndex();
+
+ void Fill()
+ {
+ FillFolderStartPackStream();
+ FillStartPos();
+ FillFolderStartFileIndex();
+ }
+
+ UInt64 GetFolderStreamPos(int folderIndex, int indexInFolder) const
+ {
+ return ArchiveInfo.DataStartPosition +
+ PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] +
+ indexInFolder];
+ }
+
+ UInt64 GetFolderFullPackSize(int folderIndex) const
+ {
+ CNum packStreamIndex = FolderStartPackStreamIndex[folderIndex];
+ const CFolder &folder = Folders[folderIndex];
+ UInt64 size = 0;
+ for (int i = 0; i < folder.PackStreams.Size(); i++)
+ size += PackSizes[packStreamIndex + i];
+ return size;
+ }
+
+ UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const
+ {
+ return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
+ }
+
+ UInt64 GetFilePackSize(CNum fileIndex) const
+ {
+ CNum folderIndex = FileIndexToFolderIndexMap[fileIndex];
+ if (folderIndex >= 0)
+ {
+ if (FolderStartFileIndex[folderIndex] == fileIndex)
+ return GetFolderFullPackSize(folderIndex);
+ }
+ return 0;
+ }
+};
+
+class CInByte2
+{
+ const Byte *_buffer;
+ size_t _size;
+ size_t _pos;
+public:
+ void Init(const Byte *buffer, size_t size)
+ {
+ _buffer = buffer;
+ _size = size;
+ _pos = 0;
+ }
+ bool ReadByte(Byte &b)
+ {
+ if(_pos >= _size)
+ return false;
+ b = _buffer[_pos++];
+ return true;
+ }
+ void ReadBytes(void *data, size_t size, size_t &processedSize)
+ {
+ for(processedSize = 0; processedSize < size && _pos < _size; processedSize++)
+ ((Byte *)data)[processedSize] = _buffer[_pos++];
+ }
+
+ bool ReadBytes(void *data, size_t size)
+ {
+ size_t processedSize;
+ ReadBytes(data, size, processedSize);
+ return (processedSize == size);
+ }
+
+ size_t GetProcessedSize() const { return _pos; }
+};
+
+class CStreamSwitch;
+class CInArchive
+{
+ friend class CStreamSwitch;
+
+ CMyComPtr<IInStream> _stream;
+ #ifdef _7Z_VOL
+ bool _finishSignature;
+ #endif
+
+ CObjectVector<CInByte2> _inByteVector;
+ CInByte2 *_inByteBack;
+
+ UInt64 _arhiveBeginStreamPosition;
+ UInt64 _position;
+
+ void AddByteStream(const Byte *buffer, size_t size)
+ {
+ _inByteVector.Add(CInByte2());
+ _inByteBack = &_inByteVector.Back();
+ _inByteBack->Init(buffer, size);
+ }
+
+ void DeleteByteStream()
+ {
+ _inByteVector.DeleteBack();
+ if (!_inByteVector.IsEmpty())
+ _inByteBack = &_inByteVector.Back();
+ }
+
+private:
+ HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
+ #ifdef _7Z_VOL
+ HRESULT FindFinishSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
+ #endif
+
+ HRESULT ReadFileNames(CObjectVector<CFileItem> &files);
+
+ HRESULT ReadDirect(IInStream *stream, void *data, UInt32 size,
+ UInt32 *processedSize);
+ HRESULT ReadDirect(void *data, UInt32 size, UInt32 *processedSize);
+ HRESULT SafeReadDirect(void *data, UInt32 size);
+ HRESULT SafeReadDirectByte(Byte &b);
+ HRESULT SafeReadDirectUInt32(UInt32 &value);
+ HRESULT SafeReadDirectUInt64(UInt64 &value);
+
+ HRESULT ReadBytes(void *data, size_t size)
+ {
+ if (!_inByteBack->ReadBytes(data, size))
+ return E_FAIL;
+ return S_OK;
+ }
+
+ HRESULT ReadByte(Byte &b)
+ {
+ if (!_inByteBack->ReadByte(b))
+ return E_FAIL;
+ return S_OK;
+ }
+
+ HRESULT ReadWideCharLE(wchar_t &c)
+ {
+ Byte b1 = 0;
+ if (!_inByteBack->ReadByte(b1))
+ return E_FAIL;
+ Byte b2 = 0;
+ if (!_inByteBack->ReadByte(b2))
+ return E_FAIL;
+ c = (wchar_t)(((wchar_t)(b2) << 8) + b1);
+ return S_OK;
+ }
+
+ HRESULT ReadNumber(UInt64 &value);
+ HRESULT ReadNum(CNum &value);
+ HRESULT ReadID(UInt64 &value) { return ReadNumber(value); }
+ HRESULT ReadUInt32(UInt32 &value);
+ HRESULT ReadUInt64(UInt64 &value);
+
+ HRESULT SkeepData(UInt64 size);
+ HRESULT SkeepData();
+ HRESULT WaitAttribute(UInt64 attribute);
+
+ HRESULT ReadArchiveProperties(CInArchiveInfo &archiveInfo);
+ HRESULT GetNextFolderItem(CFolder &itemInfo);
+ HRESULT ReadHashDigests(int numItems,
+ CRecordVector<bool> &digestsDefined, CRecordVector<UInt32> &digests);
+
+ HRESULT ReadPackInfo(
+ UInt64 &dataOffset,
+ CRecordVector<UInt64> &packSizes,
+ CRecordVector<bool> &packCRCsDefined,
+ CRecordVector<UInt32> &packCRCs);
+
+ HRESULT ReadUnPackInfo(
+ const CObjectVector<CByteBuffer> *dataVector,
+ CObjectVector<CFolder> &folders);
+
+ HRESULT ReadSubStreamsInfo(
+ const CObjectVector<CFolder> &folders,
+ CRecordVector<CNum> &numUnPackStreamsInFolders,
+ CRecordVector<UInt64> &unPackSizes,
+ CRecordVector<bool> &digestsDefined,
+ CRecordVector<UInt32> &digests);
+
+ HRESULT ReadStreamsInfo(
+ const CObjectVector<CByteBuffer> *dataVector,
+ UInt64 &dataOffset,
+ CRecordVector<UInt64> &packSizes,
+ CRecordVector<bool> &packCRCsDefined,
+ CRecordVector<UInt32> &packCRCs,
+ CObjectVector<CFolder> &folders,
+ CRecordVector<CNum> &numUnPackStreamsInFolders,
+ CRecordVector<UInt64> &unPackSizes,
+ CRecordVector<bool> &digestsDefined,
+ CRecordVector<UInt32> &digests);
+
+
+ HRESULT GetNextFileItem(CFileItem &itemInfo);
+ HRESULT ReadBoolVector(int numItems, CBoolVector &v);
+ HRESULT ReadBoolVector2(int numItems, CBoolVector &v);
+ HRESULT ReadTime(const CObjectVector<CByteBuffer> &dataVector,
+ CObjectVector<CFileItem> &files, UInt64 type);
+ HRESULT ReadAndDecodePackedStreams(UInt64 baseOffset, UInt64 &dataOffset,
+ CObjectVector<CByteBuffer> &dataVector
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPassword
+ #endif
+ );
+ HRESULT ReadHeader(CArchiveDatabaseEx &database
+ #ifndef _NO_CRYPTO
+ ,ICryptoGetTextPassword *getTextPassword
+ #endif
+ );
+public:
+ HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
+ void Close();
+
+ HRESULT ReadDatabase(CArchiveDatabaseEx &database
+ #ifndef _NO_CRYPTO
+ ,ICryptoGetTextPassword *getTextPassword
+ #endif
+ );
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/7z/7zItem.h b/CPP/7zip/Archive/7z/7zItem.h
new file mode 100755
index 00000000..08ea61f4
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zItem.h
@@ -0,0 +1,181 @@
+// 7zItem.h
+
+#ifndef __7Z_ITEM_H
+#define __7Z_ITEM_H
+
+#include "../../../Common/Buffer.h"
+#include "7zMethodID.h"
+#include "7zHeader.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CAltCoderInfo
+{
+ CMethodID MethodID;
+ CByteBuffer Properties;
+};
+
+typedef UInt32 CNum;
+const CNum kNumMax = 0x7FFFFFFF;
+const CNum kNumNoIndex = 0xFFFFFFFF;
+
+struct CCoderInfo
+{
+ CNum NumInStreams;
+ CNum NumOutStreams;
+ CObjectVector<CAltCoderInfo> AltCoders;
+ bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
+};
+
+struct CBindPair
+{
+ CNum InIndex;
+ CNum OutIndex;
+};
+
+struct CFolder
+{
+ CObjectVector<CCoderInfo> Coders;
+ CRecordVector<CBindPair> BindPairs;
+ CRecordVector<CNum> PackStreams;
+ CRecordVector<UInt64> UnPackSizes;
+ UInt32 UnPackCRC;
+ bool UnPackCRCDefined;
+
+ CFolder(): UnPackCRCDefined(false) {}
+
+ UInt64 GetUnPackSize() const // test it
+ {
+ if (UnPackSizes.IsEmpty())
+ return 0;
+ for (int i = UnPackSizes.Size() - 1; i >= 0; i--)
+ if (FindBindPairForOutStream(i) < 0)
+ return UnPackSizes[i];
+ throw 1;
+ }
+
+ CNum GetNumOutStreams() const
+ {
+ CNum result = 0;
+ for (int i = 0; i < Coders.Size(); i++)
+ result += Coders[i].NumOutStreams;
+ return result;
+ }
+
+ int FindBindPairForInStream(CNum inStreamIndex) const
+ {
+ for(int i = 0; i < BindPairs.Size(); i++)
+ if (BindPairs[i].InIndex == inStreamIndex)
+ return i;
+ return -1;
+ }
+ int FindBindPairForOutStream(CNum outStreamIndex) const
+ {
+ for(int i = 0; i < BindPairs.Size(); i++)
+ if (BindPairs[i].OutIndex == outStreamIndex)
+ return i;
+ return -1;
+ }
+ int FindPackStreamArrayIndex(CNum inStreamIndex) const
+ {
+ for(int i = 0; i < PackStreams.Size(); i++)
+ if (PackStreams[i] == inStreamIndex)
+ return i;
+ return -1;
+ }
+};
+
+typedef FILETIME CArchiveFileTime;
+
+class CFileItem
+{
+public:
+ CArchiveFileTime CreationTime;
+ CArchiveFileTime LastWriteTime;
+ CArchiveFileTime LastAccessTime;
+ UInt64 UnPackSize;
+ UInt64 StartPos;
+ UInt32 Attributes;
+ UInt32 FileCRC;
+ UString Name;
+
+ bool HasStream; // Test it !!! it means that there is
+ // stream in some folder. It can be empty stream
+ bool IsDirectory;
+ bool IsAnti;
+ bool IsFileCRCDefined;
+ bool AreAttributesDefined;
+ bool IsCreationTimeDefined;
+ bool IsLastWriteTimeDefined;
+ bool IsLastAccessTimeDefined;
+ bool IsStartPosDefined;
+
+ /*
+ const bool HasStream() const {
+ return !IsDirectory && !IsAnti && UnPackSize != 0; }
+ */
+ CFileItem():
+ HasStream(true),
+ IsDirectory(false),
+ IsAnti(false),
+ IsFileCRCDefined(false),
+ AreAttributesDefined(false),
+ IsCreationTimeDefined(false),
+ IsLastWriteTimeDefined(false),
+ IsLastAccessTimeDefined(false),
+ IsStartPosDefined(false)
+ {}
+ void SetAttributes(UInt32 attributes)
+ {
+ AreAttributesDefined = true;
+ Attributes = attributes;
+ }
+ void SetCreationTime(const CArchiveFileTime &creationTime)
+ {
+ IsCreationTimeDefined = true;
+ CreationTime = creationTime;
+ }
+ void SetLastWriteTime(const CArchiveFileTime &lastWriteTime)
+ {
+ IsLastWriteTimeDefined = true;
+ LastWriteTime = lastWriteTime;
+ }
+ void SetLastAccessTime(const CArchiveFileTime &lastAccessTime)
+ {
+ IsLastAccessTimeDefined = true;
+ LastAccessTime = lastAccessTime;
+ }
+};
+
+struct CArchiveDatabase
+{
+ CRecordVector<UInt64> PackSizes;
+ CRecordVector<bool> PackCRCsDefined;
+ CRecordVector<UInt32> PackCRCs;
+ CObjectVector<CFolder> Folders;
+ CRecordVector<CNum> NumUnPackStreamsVector;
+ CObjectVector<CFileItem> Files;
+ void Clear()
+ {
+ PackSizes.Clear();
+ PackCRCsDefined.Clear();
+ PackCRCs.Clear();
+ Folders.Clear();
+ NumUnPackStreamsVector.Clear();
+ Files.Clear();
+ }
+ bool IsEmpty() const
+ {
+ return (PackSizes.IsEmpty() &&
+ PackCRCsDefined.IsEmpty() &&
+ PackCRCs.IsEmpty() &&
+ Folders.IsEmpty() &&
+ NumUnPackStreamsVector.IsEmpty() &&
+ Files.IsEmpty());
+ }
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/7z/7zMethodID.cpp b/CPP/7zip/Archive/7z/7zMethodID.cpp
new file mode 100755
index 00000000..0d45b732
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zMethodID.cpp
@@ -0,0 +1,76 @@
+// 7zMethodID.cpp
+
+#include "StdAfx.h"
+
+#include "7zMethodID.h"
+
+namespace NArchive {
+namespace N7z {
+
+static wchar_t GetHex(Byte value)
+{
+ return (wchar_t)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
+}
+
+static bool HexCharToInt(wchar_t value, Byte &result)
+{
+ if (value >= '0' && value <= '9')
+ result = (Byte)(value - '0');
+ else if (value >= 'a' && value <= 'f')
+ result = (Byte)(10 + value - 'a');
+ else if (value >= 'A' && value <= 'F')
+ result = (Byte)(10 + value - 'A');
+ else
+ return false;
+ return true;
+}
+
+static bool TwoHexCharsToInt(wchar_t valueHigh, wchar_t valueLow, Byte &result)
+{
+ Byte resultHigh, resultLow;
+ if (!HexCharToInt(valueHigh, resultHigh))
+ return false;
+ if (!HexCharToInt(valueLow, resultLow))
+ return false;
+ result = (Byte)((resultHigh << 4) + resultLow);
+ return true;
+}
+
+UString CMethodID::ConvertToString() const
+{
+ UString result;
+ for (int i = 0; i < IDSize; i++)
+ {
+ Byte b = ID[i];
+ result += GetHex((Byte)(b >> 4));
+ result += GetHex((Byte)(b & 0xF));
+ }
+ return result;
+}
+
+bool CMethodID::ConvertFromString(const UString &srcString)
+{
+ int length = srcString.Length();
+ if ((length & 1) != 0 || (length >> 1) > kMethodIDSize)
+ return false;
+ IDSize = (Byte)(length / 2);
+ UInt32 i;
+ for(i = 0; i < IDSize; i++)
+ if (!TwoHexCharsToInt(srcString[i * 2], srcString[i * 2 + 1], ID[i]))
+ return false;
+ for(; i < kMethodIDSize; i++)
+ ID[i] = 0;
+ return true;
+}
+
+bool operator==(const CMethodID &a1, const CMethodID &a2)
+{
+ if (a1.IDSize != a2.IDSize)
+ return false;
+ for (UInt32 i = 0; i < a1.IDSize; i++)
+ if (a1.ID[i] != a2.ID[i])
+ return false;
+ return true;
+}
+
+}}
diff --git a/CPP/7zip/Archive/7z/7zMethodID.h b/CPP/7zip/Archive/7z/7zMethodID.h
new file mode 100755
index 00000000..54561054
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zMethodID.h
@@ -0,0 +1,29 @@
+// 7zMethodID.h
+
+#ifndef __7Z_METHOD_ID_H
+#define __7Z_METHOD_ID_H
+
+#include "../../../Common/String.h"
+#include "../../../Common/Types.h"
+
+namespace NArchive {
+namespace N7z {
+
+const int kMethodIDSize = 15;
+
+struct CMethodID
+{
+ Byte ID[kMethodIDSize];
+ Byte IDSize;
+ UString ConvertToString() const;
+ bool ConvertFromString(const UString &srcString);
+};
+
+bool operator==(const CMethodID &a1, const CMethodID &a2);
+
+inline bool operator!=(const CMethodID &a1, const CMethodID &a2)
+ { return !(a1 == a2); }
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/7z/7zMethods.cpp b/CPP/7zip/Archive/7z/7zMethods.cpp
new file mode 100755
index 00000000..19270aa4
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zMethods.cpp
@@ -0,0 +1,174 @@
+// 7zMethods.cpp
+
+#include "StdAfx.h"
+
+#include "7zMethods.h"
+
+#include "../../../Windows/FileFind.h"
+#include "../../../Windows/DLL.h"
+#include "../../../Windows/PropVariant.h"
+#include "../../../Windows/Synchronization.h"
+
+#include "../../ICoder.h"
+#include "../Common/CodecsPath.h"
+
+using namespace NWindows;
+
+namespace NArchive {
+namespace N7z {
+
+static CObjectVector<CMethodInfo2> g_Methods;
+static bool g_Loaded = false;
+
+typedef UInt32 (WINAPI *GetNumberOfMethodsFunc)(UInt32 *numMethods);
+
+typedef UInt32 (WINAPI *GetMethodPropertyFunc)(
+ UInt32 index, PROPID propID, PROPVARIANT *value);
+
+static void Load(const CSysString &folderPrefix)
+{
+ NFile::NFind::CEnumerator enumerator(folderPrefix + CSysString(TEXT("*")));
+ NFile::NFind::CFileInfo fileInfo;
+ while (enumerator.Next(fileInfo))
+ {
+ if (fileInfo.IsDirectory())
+ continue;
+ CSysString filePath = folderPrefix + fileInfo.Name;
+ {
+ NDLL::CLibrary library;
+ if (!library.LoadEx(filePath, LOAD_LIBRARY_AS_DATAFILE))
+ continue;
+ }
+ NDLL::CLibrary library;
+ if (!library.Load(filePath))
+ continue;
+ GetMethodPropertyFunc getMethodProperty = (GetMethodPropertyFunc)
+ library.GetProcAddress("GetMethodProperty");
+ if (getMethodProperty == NULL)
+ continue;
+
+ UInt32 numMethods = 1;
+ GetNumberOfMethodsFunc getNumberOfMethodsFunc = (GetNumberOfMethodsFunc)
+ library.GetProcAddress("GetNumberOfMethods");
+ if (getNumberOfMethodsFunc != NULL)
+ if (getNumberOfMethodsFunc(&numMethods) != S_OK)
+ continue;
+
+ for(UInt32 i = 0; i < numMethods; i++)
+ {
+ CMethodInfo2 info;
+ info.FilePath = filePath;
+
+ NWindows::NCOM::CPropVariant propVariant;
+ if (getMethodProperty(i, NMethodPropID::kID, &propVariant) != S_OK)
+ continue;
+ if (propVariant.vt != VT_BSTR)
+ continue;
+ info.MethodID.IDSize = (Byte)SysStringByteLen(propVariant.bstrVal);
+ memmove(info.MethodID.ID, propVariant.bstrVal, info.MethodID.IDSize);
+ propVariant.Clear();
+
+ if (getMethodProperty(i, NMethodPropID::kName, &propVariant) != S_OK)
+ continue;
+ if (propVariant.vt == VT_EMPTY)
+ {
+ }
+ else if (propVariant.vt == VT_BSTR)
+ info.Name = propVariant.bstrVal;
+ else
+ continue;
+ propVariant.Clear();
+
+ if (getMethodProperty (i, NMethodPropID::kEncoder, &propVariant) != S_OK)
+ continue;
+ if (propVariant.vt == VT_EMPTY)
+ info.EncoderIsAssigned = false;
+ else if (propVariant.vt == VT_BSTR)
+ {
+ info.EncoderIsAssigned = true;
+ info.Encoder = *(const GUID *)propVariant.bstrVal;
+ }
+ else
+ continue;
+ propVariant.Clear();
+
+ if (getMethodProperty (i, NMethodPropID::kDecoder, &propVariant) != S_OK)
+ continue;
+ if (propVariant.vt == VT_EMPTY)
+ info.DecoderIsAssigned = false;
+ else if (propVariant.vt == VT_BSTR)
+ {
+ info.DecoderIsAssigned = true;
+ info.Decoder = *(const GUID *)propVariant.bstrVal;
+ }
+ else
+ continue;
+ propVariant.Clear();
+
+ if (getMethodProperty (i, NMethodPropID::kInStreams, &propVariant) != S_OK)
+ continue;
+ if (propVariant.vt == VT_EMPTY)
+ info.NumInStreams = 1;
+ else if (propVariant.vt == VT_UI4)
+ info.NumInStreams = propVariant.ulVal;
+ else
+ continue;
+ propVariant.Clear();
+
+ if (getMethodProperty (i, NMethodPropID::kOutStreams, &propVariant) != S_OK)
+ continue;
+ if (propVariant.vt == VT_EMPTY)
+ info.NumOutStreams = 1;
+ else if (propVariant.vt == VT_UI4)
+ info.NumOutStreams = propVariant.ulVal;
+ else
+ continue;
+ propVariant.Clear();
+
+ g_Methods.Add(info);
+ }
+ }
+}
+
+static NSynchronization::CCriticalSection g_CriticalSection;
+
+void LoadMethodMap()
+{
+ NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
+ if (g_Loaded)
+ return;
+ g_Loaded = true;
+ Load(GetCodecsFolderPrefix());
+}
+
+bool GetMethodInfo(const CMethodID &methodID, CMethodInfo &methodInfo)
+{
+ for(int i = 0; i < g_Methods.Size(); i++)
+ {
+ const CMethodInfo2 &method = g_Methods[i];
+ if (method.MethodID == methodID)
+ {
+ methodInfo = (CMethodInfo)method;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool GetMethodInfo(const UString &name, CMethodInfo2 &methodInfo)
+{
+ for(int i = 0; i < g_Methods.Size(); i++)
+ {
+ const CMethodInfo2 &method = g_Methods[i];
+ if (method.Name.CompareNoCase(name) == 0)
+ {
+ methodInfo = method;
+ return true;
+ }
+ }
+ return false;
+}
+
+}}
+
+
diff --git a/CPP/7zip/Archive/7z/7zMethods.h b/CPP/7zip/Archive/7z/7zMethods.h
new file mode 100755
index 00000000..231f3183
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zMethods.h
@@ -0,0 +1,36 @@
+// 7zMethods.h
+
+#ifndef __7Z_METHODS_H
+#define __7Z_METHODS_H
+
+#include "7zMethodID.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CMethodInfo
+{
+ UString Name;
+ bool EncoderIsAssigned;
+ bool DecoderIsAssigned;
+ UInt32 NumInStreams;
+ UInt32 NumOutStreams;
+ CLSID Encoder;
+ CLSID Decoder;
+ // UString Description;
+ CSysString FilePath;
+};
+
+struct CMethodInfo2: public CMethodInfo
+{
+ CMethodID MethodID;
+};
+
+void LoadMethodMap();
+bool GetMethodInfo(const CMethodID &methodID, CMethodInfo &methodInfo);
+bool GetMethodInfo(const UString &name, CMethodInfo2 &methodInfo);
+
+}}
+
+#endif
+
diff --git a/CPP/7zip/Archive/7z/7zOut.cpp b/CPP/7zip/Archive/7z/7zOut.cpp
new file mode 100755
index 00000000..5a81a0d5
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zOut.cpp
@@ -0,0 +1,1136 @@
+// 7zOut.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/AutoPtr.h"
+#include "../../Common/StreamObjects.h"
+
+#include "7zOut.h"
+
+static HRESULT WriteBytes(ISequentialOutStream *stream, const void *data, size_t size)
+{
+ while (size > 0)
+ {
+ UInt32 curSize = (UInt32)MyMin(size, (size_t)0xFFFFFFFF);
+ UInt32 processedSize;
+ RINOK(stream->Write(data, curSize, &processedSize));
+ if(processedSize == 0)
+ return E_FAIL;
+ data = (const void *)((const Byte *)data + processedSize);
+ size -= processedSize;
+ }
+ return S_OK;
+}
+
+namespace NArchive {
+namespace N7z {
+
+HRESULT COutArchive::WriteDirect(const void *data, UInt32 size)
+{
+ return ::WriteBytes(SeqStream, data, size);
+}
+
+HRESULT COutArchive::WriteDirectUInt32(UInt32 value)
+{
+ for (int i = 0; i < 4; i++)
+ {
+ RINOK(WriteDirectByte((Byte)value));
+ value >>= 8;
+ }
+ return S_OK;
+}
+
+HRESULT COutArchive::WriteDirectUInt64(UInt64 value)
+{
+ for (int i = 0; i < 8; i++)
+ {
+ RINOK(WriteDirectByte((Byte)value));
+ value >>= 8;
+ }
+ return S_OK;
+}
+
+HRESULT COutArchive::WriteSignature()
+{
+ RINOK(WriteDirect(kSignature, kSignatureSize));
+ RINOK(WriteDirectByte(kMajorVersion));
+ return WriteDirectByte(2);
+}
+
+#ifdef _7Z_VOL
+HRESULT COutArchive::WriteFinishSignature()
+{
+ RINOK(WriteDirect(kFinishSignature, kSignatureSize));
+ CArchiveVersion av;
+ av.Major = kMajorVersion;
+ av.Minor = 2;
+ RINOK(WriteDirectByte(av.Major));
+ return WriteDirectByte(av.Minor);
+}
+#endif
+
+HRESULT COutArchive::WriteStartHeader(const CStartHeader &h)
+{
+ CCRC crc;
+ crc.UpdateUInt64(h.NextHeaderOffset);
+ crc.UpdateUInt64(h.NextHeaderSize);
+ crc.UpdateUInt32(h.NextHeaderCRC);
+ RINOK(WriteDirectUInt32(crc.GetDigest()));
+ RINOK(WriteDirectUInt64(h.NextHeaderOffset));
+ RINOK(WriteDirectUInt64(h.NextHeaderSize));
+ return WriteDirectUInt32(h.NextHeaderCRC);
+}
+
+#ifdef _7Z_VOL
+HRESULT COutArchive::WriteFinishHeader(const CFinishHeader &h)
+{
+ CCRC crc;
+ crc.UpdateUInt64(h.NextHeaderOffset);
+ crc.UpdateUInt64(h.NextHeaderSize);
+ crc.UpdateUInt32(h.NextHeaderCRC);
+ crc.UpdateUInt64(h.ArchiveStartOffset);
+ crc.UpdateUInt64(h.AdditionalStartBlockSize);
+ RINOK(WriteDirectUInt32(crc.GetDigest()));
+ RINOK(WriteDirectUInt64(h.NextHeaderOffset));
+ RINOK(WriteDirectUInt64(h.NextHeaderSize));
+ RINOK(WriteDirectUInt32(h.NextHeaderCRC));
+ RINOK(WriteDirectUInt64(h.ArchiveStartOffset));
+ return WriteDirectUInt64(h.AdditionalStartBlockSize);
+}
+#endif
+
+HRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker)
+{
+ Close();
+ #ifdef _7Z_VOL
+ // endMarker = false;
+ _endMarker = endMarker;
+ #endif
+ SeqStream = stream;
+ if (!endMarker)
+ {
+ SeqStream.QueryInterface(IID_IOutStream, &Stream);
+ if (!Stream)
+ {
+ return E_NOTIMPL;
+ // endMarker = true;
+ }
+ }
+ #ifdef _7Z_VOL
+ if (endMarker)
+ {
+ /*
+ CStartHeader sh;
+ sh.NextHeaderOffset = (UInt32)(Int32)-1;
+ sh.NextHeaderSize = (UInt32)(Int32)-1;
+ sh.NextHeaderCRC = 0;
+ WriteStartHeader(sh);
+ */
+ }
+ else
+ #endif
+ {
+ if (!Stream)
+ return E_FAIL;
+ WriteSignature();
+ RINOK(Stream->Seek(0, STREAM_SEEK_CUR, &_prefixHeaderPos));
+ }
+ return S_OK;
+}
+
+void COutArchive::Close()
+{
+ SeqStream.Release();
+ Stream.Release();
+}
+
+HRESULT COutArchive::SkeepPrefixArchiveHeader()
+{
+ #ifdef _7Z_VOL
+ if (_endMarker)
+ return S_OK;
+ #endif
+ return Stream->Seek(24, STREAM_SEEK_CUR, NULL);
+}
+
+HRESULT COutArchive::WriteBytes(const void *data, size_t size)
+{
+ if (_mainMode)
+ {
+ if (_dynamicMode)
+ _dynamicBuffer.Write(data, size);
+ else
+ _outByte.WriteBytes(data, size);
+ _crc.Update(data, size);
+ }
+ else
+ {
+ if (_countMode)
+ _countSize += size;
+ else
+ RINOK(_outByte2.Write(data, size));
+ }
+ return S_OK;
+}
+
+HRESULT COutArchive::WriteBytes(const CByteBuffer &data)
+{
+ return WriteBytes(data, data.GetCapacity());
+}
+
+HRESULT COutArchive::WriteByte(Byte b)
+{
+ return WriteBytes(&b, 1);
+}
+
+HRESULT COutArchive::WriteUInt32(UInt32 value)
+{
+ for (int i = 0; i < 4; i++)
+ {
+ RINOK(WriteByte((Byte)value));
+ value >>= 8;
+ }
+ return S_OK;
+}
+
+HRESULT COutArchive::WriteNumber(UInt64 value)
+{
+ Byte firstByte = 0;
+ Byte mask = 0x80;
+ int i;
+ for (i = 0; i < 8; i++)
+ {
+ if (value < ((UInt64(1) << ( 7 * (i + 1)))))
+ {
+ firstByte |= Byte(value >> (8 * i));
+ break;
+ }
+ firstByte |= mask;
+ mask >>= 1;
+ }
+ RINOK(WriteByte(firstByte));
+ for (;i > 0; i--)
+ {
+ RINOK(WriteByte((Byte)value));
+ value >>= 8;
+ }
+ return S_OK;
+}
+
+static UInt32 GetBigNumberSize(UInt64 value)
+{
+ int i;
+ for (i = 0; i < 8; i++)
+ if (value < ((UInt64(1) << ( 7 * (i + 1)))))
+ break;
+ return 1 + i;
+}
+
+#ifdef _7Z_VOL
+UInt32 COutArchive::GetVolHeadersSize(UInt64 dataSize, int nameLength, bool props)
+{
+ UInt32 result = GetBigNumberSize(dataSize) * 2 + 41;
+ if (nameLength != 0)
+ {
+ nameLength = (nameLength + 1) * 2;
+ result += nameLength + GetBigNumberSize(nameLength) + 2;
+ }
+ if (props)
+ {
+ result += 20;
+ }
+ if (result >= 128)
+ result++;
+ result += kSignatureSize + 2 + kFinishHeaderSize;
+ return result;
+}
+
+UInt64 COutArchive::GetVolPureSize(UInt64 volSize, int nameLength, bool props)
+{
+ UInt32 headersSizeBase = COutArchive::GetVolHeadersSize(1, nameLength, props);
+ int testSize;
+ if (volSize > headersSizeBase)
+ testSize = volSize - headersSizeBase;
+ else
+ testSize = 1;
+ UInt32 headersSize = COutArchive::GetVolHeadersSize(testSize, nameLength, props);
+ UInt64 pureSize = 1;
+ if (volSize > headersSize)
+ pureSize = volSize - headersSize;
+ return pureSize;
+}
+#endif
+
+HRESULT COutArchive::WriteFolder(const CFolder &folder)
+{
+ RINOK(WriteNumber(folder.Coders.Size()));
+ int i;
+ for (i = 0; i < folder.Coders.Size(); i++)
+ {
+ const CCoderInfo &coder = folder.Coders[i];
+ for (int j = 0; j < coder.AltCoders.Size(); j++)
+ {
+ const CAltCoderInfo &altCoder = coder.AltCoders[j];
+ size_t propertiesSize = altCoder.Properties.GetCapacity();
+
+ Byte b;
+ b = (Byte)(altCoder.MethodID.IDSize & 0xF);
+ bool isComplex = !coder.IsSimpleCoder();
+ b |= (isComplex ? 0x10 : 0);
+ b |= ((propertiesSize != 0) ? 0x20 : 0 );
+ b |= ((j == coder.AltCoders.Size() - 1) ? 0 : 0x80 );
+ RINOK(WriteByte(b));
+ RINOK(WriteBytes(altCoder.MethodID.ID, altCoder.MethodID.IDSize));
+ if (isComplex)
+ {
+ RINOK(WriteNumber(coder.NumInStreams));
+ RINOK(WriteNumber(coder.NumOutStreams));
+ }
+ if (propertiesSize == 0)
+ continue;
+ RINOK(WriteNumber(propertiesSize));
+ RINOK(WriteBytes(altCoder.Properties, propertiesSize));
+ }
+ }
+ for (i = 0; i < folder.BindPairs.Size(); i++)
+ {
+ const CBindPair &bindPair = folder.BindPairs[i];
+ RINOK(WriteNumber(bindPair.InIndex));
+ RINOK(WriteNumber(bindPair.OutIndex));
+ }
+ if (folder.PackStreams.Size() > 1)
+ for (i = 0; i < folder.PackStreams.Size(); i++)
+ {
+ RINOK(WriteNumber(folder.PackStreams[i]));
+ }
+ return S_OK;
+}
+
+HRESULT COutArchive::WriteBoolVector(const CBoolVector &boolVector)
+{
+ Byte b = 0;
+ Byte mask = 0x80;
+ for(int i = 0; i < boolVector.Size(); i++)
+ {
+ if (boolVector[i])
+ b |= mask;
+ mask >>= 1;
+ if (mask == 0)
+ {
+ RINOK(WriteByte(b));
+ mask = 0x80;
+ b = 0;
+ }
+ }
+ if (mask != 0x80)
+ {
+ RINOK(WriteByte(b));
+ }
+ return S_OK;
+}
+
+
+HRESULT COutArchive::WriteHashDigests(
+ const CRecordVector<bool> &digestsDefined,
+ const CRecordVector<UInt32> &digests)
+{
+ int numDefined = 0;
+ int i;
+ for(i = 0; i < digestsDefined.Size(); i++)
+ if (digestsDefined[i])
+ numDefined++;
+ if (numDefined == 0)
+ return S_OK;
+
+ RINOK(WriteByte(NID::kCRC));
+ if (numDefined == digestsDefined.Size())
+ {
+ RINOK(WriteByte(1));
+ }
+ else
+ {
+ RINOK(WriteByte(0));
+ RINOK(WriteBoolVector(digestsDefined));
+ }
+ for(i = 0; i < digests.Size(); i++)
+ {
+ if(digestsDefined[i])
+ RINOK(WriteUInt32(digests[i]));
+ }
+ return S_OK;
+}
+
+HRESULT COutArchive::WritePackInfo(
+ UInt64 dataOffset,
+ const CRecordVector<UInt64> &packSizes,
+ const CRecordVector<bool> &packCRCsDefined,
+ const CRecordVector<UInt32> &packCRCs)
+{
+ if (packSizes.IsEmpty())
+ return S_OK;
+ RINOK(WriteByte(NID::kPackInfo));
+ RINOK(WriteNumber(dataOffset));
+ RINOK(WriteNumber(packSizes.Size()));
+ RINOK(WriteByte(NID::kSize));
+ for(int i = 0; i < packSizes.Size(); i++)
+ RINOK(WriteNumber(packSizes[i]));
+
+ RINOK(WriteHashDigests(packCRCsDefined, packCRCs));
+
+ return WriteByte(NID::kEnd);
+}
+
+HRESULT COutArchive::WriteUnPackInfo(
+ bool externalFolders,
+ CNum externalFoldersStreamIndex,
+ const CObjectVector<CFolder> &folders)
+{
+ if (folders.IsEmpty())
+ return S_OK;
+
+ RINOK(WriteByte(NID::kUnPackInfo));
+
+ RINOK(WriteByte(NID::kFolder));
+ RINOK(WriteNumber(folders.Size()));
+ if (externalFolders)
+ {
+ RINOK(WriteByte(1));
+ RINOK(WriteNumber(externalFoldersStreamIndex));
+ }
+ else
+ {
+ RINOK(WriteByte(0));
+ for(int i = 0; i < folders.Size(); i++)
+ RINOK(WriteFolder(folders[i]));
+ }
+
+ RINOK(WriteByte(NID::kCodersUnPackSize));
+ int i;
+ for(i = 0; i < folders.Size(); i++)
+ {
+ const CFolder &folder = folders[i];
+ for (int j = 0; j < folder.UnPackSizes.Size(); j++)
+ RINOK(WriteNumber(folder.UnPackSizes[j]));
+ }
+
+ CRecordVector<bool> unPackCRCsDefined;
+ CRecordVector<UInt32> unPackCRCs;
+ for(i = 0; i < folders.Size(); i++)
+ {
+ const CFolder &folder = folders[i];
+ unPackCRCsDefined.Add(folder.UnPackCRCDefined);
+ unPackCRCs.Add(folder.UnPackCRC);
+ }
+ RINOK(WriteHashDigests(unPackCRCsDefined, unPackCRCs));
+
+ return WriteByte(NID::kEnd);
+}
+
+HRESULT COutArchive::WriteSubStreamsInfo(
+ const CObjectVector<CFolder> &folders,
+ const CRecordVector<CNum> &numUnPackStreamsInFolders,
+ const CRecordVector<UInt64> &unPackSizes,
+ const CRecordVector<bool> &digestsDefined,
+ const CRecordVector<UInt32> &digests)
+{
+ RINOK(WriteByte(NID::kSubStreamsInfo));
+
+ int i;
+ for(i = 0; i < numUnPackStreamsInFolders.Size(); i++)
+ {
+ if (numUnPackStreamsInFolders[i] != 1)
+ {
+ RINOK(WriteByte(NID::kNumUnPackStream));
+ for(i = 0; i < numUnPackStreamsInFolders.Size(); i++)
+ RINOK(WriteNumber(numUnPackStreamsInFolders[i]));
+ break;
+ }
+ }
+
+
+ bool needFlag = true;
+ CNum index = 0;
+ for(i = 0; i < numUnPackStreamsInFolders.Size(); i++)
+ for (CNum j = 0; j < numUnPackStreamsInFolders[i]; j++)
+ {
+ if (j + 1 != numUnPackStreamsInFolders[i])
+ {
+ if (needFlag)
+ RINOK(WriteByte(NID::kSize));
+ needFlag = false;
+ RINOK(WriteNumber(unPackSizes[index]));
+ }
+ index++;
+ }
+
+ CRecordVector<bool> digestsDefined2;
+ CRecordVector<UInt32> digests2;
+
+ int digestIndex = 0;
+ for (i = 0; i < folders.Size(); i++)
+ {
+ int numSubStreams = (int)numUnPackStreamsInFolders[i];
+ if (numSubStreams == 1 && folders[i].UnPackCRCDefined)
+ digestIndex++;
+ else
+ for (int j = 0; j < numSubStreams; j++, digestIndex++)
+ {
+ digestsDefined2.Add(digestsDefined[digestIndex]);
+ digests2.Add(digests[digestIndex]);
+ }
+ }
+ RINOK(WriteHashDigests(digestsDefined2, digests2));
+ return WriteByte(NID::kEnd);
+}
+
+HRESULT COutArchive::WriteTime(
+ const CObjectVector<CFileItem> &files, Byte type,
+ bool isExternal, CNum externalDataIndex)
+{
+ /////////////////////////////////////////////////
+ // CreationTime
+ CBoolVector boolVector;
+ boolVector.Reserve(files.Size());
+ bool thereAreDefined = false;
+ bool allDefined = true;
+ int i;
+ for(i = 0; i < files.Size(); i++)
+ {
+ const CFileItem &item = files[i];
+ bool defined;
+ switch(type)
+ {
+ case NID::kCreationTime:
+ defined = item.IsCreationTimeDefined;
+ break;
+ case NID::kLastWriteTime:
+ defined = item.IsLastWriteTimeDefined;
+ break;
+ case NID::kLastAccessTime:
+ defined = item.IsLastAccessTimeDefined;
+ break;
+ default:
+ throw 1;
+ }
+ boolVector.Add(defined);
+ thereAreDefined = (thereAreDefined || defined);
+ allDefined = (allDefined && defined);
+ }
+ if (!thereAreDefined)
+ return S_OK;
+ RINOK(WriteByte(type));
+ size_t dataSize = 1 + 1;
+ if (isExternal)
+ dataSize += GetBigNumberSize(externalDataIndex);
+ else
+ dataSize += files.Size() * 8;
+ if (allDefined)
+ {
+ RINOK(WriteNumber(dataSize));
+ WriteByte(1);
+ }
+ else
+ {
+ RINOK(WriteNumber(1 + (boolVector.Size() + 7) / 8 + dataSize));
+ WriteByte(0);
+ RINOK(WriteBoolVector(boolVector));
+ }
+ if (isExternal)
+ {
+ RINOK(WriteByte(1));
+ RINOK(WriteNumber(externalDataIndex));
+ return S_OK;
+ }
+ RINOK(WriteByte(0));
+ for(i = 0; i < files.Size(); i++)
+ {
+ if (boolVector[i])
+ {
+ const CFileItem &item = files[i];
+ CArchiveFileTime timeValue;
+ timeValue.dwLowDateTime = 0;
+ timeValue.dwHighDateTime = 0;
+ switch(type)
+ {
+ case NID::kCreationTime:
+ timeValue = item.CreationTime;
+ break;
+ case NID::kLastWriteTime:
+ timeValue = item.LastWriteTime;
+ break;
+ case NID::kLastAccessTime:
+ timeValue = item.LastAccessTime;
+ break;
+ }
+ RINOK(WriteUInt32(timeValue.dwLowDateTime));
+ RINOK(WriteUInt32(timeValue.dwHighDateTime));
+ }
+ }
+ return S_OK;
+}
+
+HRESULT COutArchive::EncodeStream(CEncoder &encoder, const Byte *data, size_t dataSize,
+ CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders)
+{
+ CSequentialInStreamImp *streamSpec = new CSequentialInStreamImp;
+ CMyComPtr<ISequentialInStream> stream = streamSpec;
+ streamSpec->Init(data, dataSize);
+ CFolder folderItem;
+ folderItem.UnPackCRCDefined = true;
+ folderItem.UnPackCRC = CCRC::CalculateDigest(data, dataSize);
+ UInt64 dataSize64 = dataSize;
+ RINOK(encoder.Encode(stream, NULL, &dataSize64, folderItem, SeqStream, packSizes, NULL));
+ folders.Add(folderItem);
+ return S_OK;
+}
+
+HRESULT COutArchive::EncodeStream(CEncoder &encoder, const CByteBuffer &data,
+ CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders)
+{
+ return EncodeStream(encoder, data, data.GetCapacity(), packSizes, folders);
+}
+
+static void WriteUInt32ToBuffer(Byte *data, UInt32 value)
+{
+ for (int i = 0; i < 4; i++)
+ {
+ *data++ = (Byte)value;
+ value >>= 8;
+ }
+}
+
+static void WriteUInt64ToBuffer(Byte *data, UInt64 value)
+{
+ for (int i = 0; i < 8; i++)
+ {
+ *data++ = (Byte)value;
+ value >>= 8;
+ }
+}
+
+
+HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database,
+ const CCompressionMethodMode *options,
+ const CHeaderOptions &headerOptions,
+ UInt64 &headerOffset)
+{
+ CObjectVector<CFolder> folders;
+
+ bool compressHeaders = (options != NULL);
+ CMyAutoPtr<CEncoder> encoder;
+ if (compressHeaders)
+ {
+ // it's for gcc2.95.2
+ CMyAutoPtr<CEncoder> tmp(new CEncoder(*options));
+ encoder = tmp;
+ }
+
+ CRecordVector<UInt64> packSizes;
+
+ CNum dataIndex = 0;
+
+ //////////////////////////
+ // Folders
+
+ CNum externalFoldersStreamIndex = 0;
+ bool externalFolders = (compressHeaders && database.Folders.Size() > 8);
+ if (externalFolders)
+ {
+ _mainMode = false;
+ _countMode = true;
+ _countSize = 0;
+ int i;
+ for(i = 0; i < database.Folders.Size(); i++)
+ {
+ RINOK(WriteFolder(database.Folders[i]));
+ }
+
+ _countMode = false;
+
+ CByteBuffer foldersData;
+ foldersData.SetCapacity(_countSize);
+ _outByte2.Init(foldersData, foldersData.GetCapacity());
+
+ for(i = 0; i < database.Folders.Size(); i++)
+ {
+ RINOK(WriteFolder(database.Folders[i]));
+ }
+
+ {
+ externalFoldersStreamIndex = dataIndex++;
+ RINOK(EncodeStream(*encoder, foldersData, packSizes, folders));
+ }
+ }
+
+
+ int i;
+
+ /////////////////////////////////
+ // Names
+
+ CNum numDefinedNames = 0;
+ size_t namesDataSize = 0;
+ for(i = 0; i < database.Files.Size(); i++)
+ {
+ const UString &name = database.Files[i].Name;
+ if (!name.IsEmpty())
+ numDefinedNames++;
+ namesDataSize += (name.Length() + 1) * 2;
+ }
+
+ CByteBuffer namesData;
+ CNum externalNamesStreamIndex = 0;
+ bool externalNames = (compressHeaders && database.Files.Size() > 8);
+ if (numDefinedNames > 0)
+ {
+ namesData.SetCapacity((size_t)namesDataSize);
+ size_t pos = 0;
+ for(int i = 0; i < database.Files.Size(); i++)
+ {
+ const UString &name = database.Files[i].Name;
+ for (int t = 0; t < name.Length(); t++)
+ {
+ wchar_t c = name[t];
+ namesData[pos++] = Byte(c);
+ namesData[pos++] = Byte(c >> 8);
+ }
+ namesData[pos++] = 0;
+ namesData[pos++] = 0;
+ }
+
+ if (externalNames)
+ {
+ externalNamesStreamIndex = dataIndex++;
+ RINOK(EncodeStream(*encoder, namesData, packSizes, folders));
+ }
+ }
+
+ /////////////////////////////////
+ // Write Attributes
+ CBoolVector attributesBoolVector;
+ attributesBoolVector.Reserve(database.Files.Size());
+ int numDefinedAttributes = 0;
+ for(i = 0; i < database.Files.Size(); i++)
+ {
+ bool defined = database.Files[i].AreAttributesDefined;
+ attributesBoolVector.Add(defined);
+ if (defined)
+ numDefinedAttributes++;
+ }
+
+ CByteBuffer attributesData;
+ CNum externalAttributesStreamIndex = 0;
+ bool externalAttributes = (compressHeaders && numDefinedAttributes > 8);
+ if (numDefinedAttributes > 0)
+ {
+ attributesData.SetCapacity(numDefinedAttributes * 4);
+ size_t pos = 0;
+ for(i = 0; i < database.Files.Size(); i++)
+ {
+ const CFileItem &file = database.Files[i];
+ if (file.AreAttributesDefined)
+ {
+ WriteUInt32ToBuffer(attributesData + pos, file.Attributes);
+ pos += 4;
+ }
+ }
+ if (externalAttributes)
+ {
+ externalAttributesStreamIndex = dataIndex++;
+ RINOK(EncodeStream(*encoder, attributesData, packSizes, folders));
+ }
+ }
+
+ /////////////////////////////////
+ // Write StartPos
+ CBoolVector startsBoolVector;
+ startsBoolVector.Reserve(database.Files.Size());
+ int numDefinedStarts = 0;
+ for(i = 0; i < database.Files.Size(); i++)
+ {
+ bool defined = database.Files[i].IsStartPosDefined;
+ startsBoolVector.Add(defined);
+ if (defined)
+ numDefinedStarts++;
+ }
+
+ CByteBuffer startsData;
+ CNum externalStartStreamIndex = 0;
+ bool externalStarts = (compressHeaders && numDefinedStarts > 8);
+ if (numDefinedStarts > 0)
+ {
+ startsData.SetCapacity(numDefinedStarts * 8);
+ size_t pos = 0;
+ for(i = 0; i < database.Files.Size(); i++)
+ {
+ const CFileItem &file = database.Files[i];
+ if (file.IsStartPosDefined)
+ {
+ WriteUInt64ToBuffer(startsData + pos, file.StartPos);
+ pos += 8;
+ }
+ }
+ if (externalStarts)
+ {
+ externalStartStreamIndex = dataIndex++;
+ RINOK(EncodeStream(*encoder, startsData, packSizes, folders));
+ }
+ }
+
+ /////////////////////////////////
+ // Write Last Write Time
+ CNum externalLastWriteTimeStreamIndex = 0;
+ bool externalLastWriteTime = false;
+ // /*
+ CNum numDefinedLastWriteTimes = 0;
+ for(i = 0; i < database.Files.Size(); i++)
+ if (database.Files[i].IsLastWriteTimeDefined)
+ numDefinedLastWriteTimes++;
+
+ externalLastWriteTime = (compressHeaders && numDefinedLastWriteTimes > 64);
+ if (numDefinedLastWriteTimes > 0)
+ {
+ CByteBuffer lastWriteTimeData;
+ lastWriteTimeData.SetCapacity(numDefinedLastWriteTimes * 8);
+ size_t pos = 0;
+ for(i = 0; i < database.Files.Size(); i++)
+ {
+ const CFileItem &file = database.Files[i];
+ if (file.IsLastWriteTimeDefined)
+ {
+ WriteUInt32ToBuffer(lastWriteTimeData + pos, file.LastWriteTime.dwLowDateTime);
+ pos += 4;
+ WriteUInt32ToBuffer(lastWriteTimeData + pos, file.LastWriteTime.dwHighDateTime);
+ pos += 4;
+ }
+ }
+ if (externalLastWriteTime)
+ {
+ externalLastWriteTimeStreamIndex = dataIndex++;
+ RINOK(EncodeStream(*encoder, lastWriteTimeData, packSizes, folders));
+ }
+ }
+ // */
+
+
+ UInt64 packedSize = 0;
+ for(i = 0; i < database.PackSizes.Size(); i++)
+ packedSize += database.PackSizes[i];
+ UInt64 headerPackSize = 0;
+ for (i = 0; i < packSizes.Size(); i++)
+ headerPackSize += packSizes[i];
+
+ headerOffset = packedSize + headerPackSize;
+
+ _mainMode = true;
+
+ _outByte.SetStream(SeqStream);
+ _outByte.Init();
+ _crc.Init();
+
+
+ RINOK(WriteByte(NID::kHeader));
+
+ // Archive Properties
+
+ if (folders.Size() > 0)
+ {
+ RINOK(WriteByte(NID::kAdditionalStreamsInfo));
+ RINOK(WritePackInfo(packedSize, packSizes,
+ CRecordVector<bool>(), CRecordVector<UInt32>()));
+ RINOK(WriteUnPackInfo(false, 0, folders));
+ RINOK(WriteByte(NID::kEnd));
+ }
+
+ ////////////////////////////////////////////////////
+
+ if (database.Folders.Size() > 0)
+ {
+ RINOK(WriteByte(NID::kMainStreamsInfo));
+ RINOK(WritePackInfo(0, database.PackSizes,
+ database.PackCRCsDefined,
+ database.PackCRCs));
+
+ RINOK(WriteUnPackInfo(externalFolders, externalFoldersStreamIndex, database.Folders));
+
+ CRecordVector<UInt64> unPackSizes;
+ CRecordVector<bool> digestsDefined;
+ CRecordVector<UInt32> digests;
+ for (i = 0; i < database.Files.Size(); i++)
+ {
+ const CFileItem &file = database.Files[i];
+ if (!file.HasStream)
+ continue;
+ unPackSizes.Add(file.UnPackSize);
+ digestsDefined.Add(file.IsFileCRCDefined);
+ digests.Add(file.FileCRC);
+ }
+
+ RINOK(WriteSubStreamsInfo(
+ database.Folders,
+ database.NumUnPackStreamsVector,
+ unPackSizes,
+ digestsDefined,
+ digests));
+ RINOK(WriteByte(NID::kEnd));
+ }
+
+ if (database.Files.IsEmpty())
+ {
+ RINOK(WriteByte(NID::kEnd));
+ return _outByte.Flush();
+ }
+
+ RINOK(WriteByte(NID::kFilesInfo));
+ RINOK(WriteNumber(database.Files.Size()));
+
+ CBoolVector emptyStreamVector;
+ emptyStreamVector.Reserve(database.Files.Size());
+ int numEmptyStreams = 0;
+ for(i = 0; i < database.Files.Size(); i++)
+ if (database.Files[i].HasStream)
+ emptyStreamVector.Add(false);
+ else
+ {
+ emptyStreamVector.Add(true);
+ numEmptyStreams++;
+ }
+ if (numEmptyStreams > 0)
+ {
+ RINOK(WriteByte(NID::kEmptyStream));
+ RINOK(WriteNumber((emptyStreamVector.Size() + 7) / 8));
+ RINOK(WriteBoolVector(emptyStreamVector));
+
+ CBoolVector emptyFileVector, antiVector;
+ emptyFileVector.Reserve(numEmptyStreams);
+ antiVector.Reserve(numEmptyStreams);
+ CNum numEmptyFiles = 0, numAntiItems = 0;
+ for(i = 0; i < database.Files.Size(); i++)
+ {
+ const CFileItem &file = database.Files[i];
+ if (!file.HasStream)
+ {
+ emptyFileVector.Add(!file.IsDirectory);
+ if (!file.IsDirectory)
+ numEmptyFiles++;
+ antiVector.Add(file.IsAnti);
+ if (file.IsAnti)
+ numAntiItems++;
+ }
+ }
+
+ if (numEmptyFiles > 0)
+ {
+ RINOK(WriteByte(NID::kEmptyFile));
+ RINOK(WriteNumber((emptyFileVector.Size() + 7) / 8));
+ RINOK(WriteBoolVector(emptyFileVector));
+ }
+
+ if (numAntiItems > 0)
+ {
+ RINOK(WriteByte(NID::kAnti));
+ RINOK(WriteNumber((antiVector.Size() + 7) / 8));
+ RINOK(WriteBoolVector(antiVector));
+ }
+ }
+
+ if (numDefinedNames > 0)
+ {
+ /////////////////////////////////////////////////
+ RINOK(WriteByte(NID::kName));
+ if (externalNames)
+ {
+ RINOK(WriteNumber(1 + GetBigNumberSize(externalNamesStreamIndex)));
+ RINOK(WriteByte(1));
+ RINOK(WriteNumber(externalNamesStreamIndex));
+ }
+ else
+ {
+ RINOK(WriteNumber(1 + namesData.GetCapacity()));
+ RINOK(WriteByte(0));
+ RINOK(WriteBytes(namesData));
+ }
+
+ }
+
+ if (headerOptions.WriteCreated)
+ {
+ RINOK(WriteTime(database.Files, NID::kCreationTime, false, 0));
+ }
+ if (headerOptions.WriteModified)
+ {
+ RINOK(WriteTime(database.Files, NID::kLastWriteTime,
+ // false, 0));
+ externalLastWriteTime, externalLastWriteTimeStreamIndex));
+ }
+ if (headerOptions.WriteAccessed)
+ {
+ RINOK(WriteTime(database.Files, NID::kLastAccessTime, false, 0));
+ }
+
+ if (numDefinedAttributes > 0)
+ {
+ RINOK(WriteByte(NID::kWinAttributes));
+ size_t size = 2;
+ if (numDefinedAttributes != database.Files.Size())
+ size += (attributesBoolVector.Size() + 7) / 8 + 1;
+ if (externalAttributes)
+ size += GetBigNumberSize(externalAttributesStreamIndex);
+ else
+ size += attributesData.GetCapacity();
+
+ RINOK(WriteNumber(size));
+ if (numDefinedAttributes == database.Files.Size())
+ {
+ RINOK(WriteByte(1));
+ }
+ else
+ {
+ RINOK(WriteByte(0));
+ RINOK(WriteBoolVector(attributesBoolVector));
+ }
+
+ if (externalAttributes)
+ {
+ RINOK(WriteByte(1));
+ RINOK(WriteNumber(externalAttributesStreamIndex));
+ }
+ else
+ {
+ RINOK(WriteByte(0));
+ RINOK(WriteBytes(attributesData));
+ }
+ }
+
+ if (numDefinedStarts > 0)
+ {
+ RINOK(WriteByte(NID::kStartPos));
+ size_t size = 2;
+ if (numDefinedStarts != database.Files.Size())
+ size += (startsBoolVector.Size() + 7) / 8 + 1;
+ if (externalStarts)
+ size += GetBigNumberSize(externalStartStreamIndex);
+ else
+ size += startsData.GetCapacity();
+
+ RINOK(WriteNumber(size));
+ if (numDefinedStarts == database.Files.Size())
+ {
+ RINOK(WriteByte(1));
+ }
+ else
+ {
+ RINOK(WriteByte(0));
+ RINOK(WriteBoolVector(startsBoolVector));
+ }
+
+ if (externalAttributes)
+ {
+ RINOK(WriteByte(1));
+ RINOK(WriteNumber(externalStartStreamIndex));
+ }
+ else
+ {
+ RINOK(WriteByte(0));
+ RINOK(WriteBytes(startsData));
+ }
+ }
+
+ RINOK(WriteByte(NID::kEnd)); // for files
+ RINOK(WriteByte(NID::kEnd)); // for headers
+
+ return _outByte.Flush();
+}
+
+HRESULT COutArchive::WriteDatabase(const CArchiveDatabase &database,
+ const CCompressionMethodMode *options,
+ const CHeaderOptions &headerOptions)
+{
+ UInt64 headerOffset;
+ UInt32 headerCRC;
+ UInt64 headerSize;
+ if (database.IsEmpty())
+ {
+ headerSize = 0;
+ headerOffset = 0;
+ headerCRC = CCRC::CalculateDigest(0, 0);
+ }
+ else
+ {
+ _dynamicBuffer.Init();
+ _dynamicMode = false;
+
+ if (options != 0)
+ if (options->IsEmpty())
+ options = 0;
+ const CCompressionMethodMode *additionalStreamsOptions = options;
+ if (!headerOptions.UseAdditionalHeaderStreams)
+ additionalStreamsOptions = 0;
+ /*
+ if (database.Files.Size() < 2)
+ compressMainHeader = false;
+ */
+ if (options != 0)
+ if (options->PasswordIsDefined || headerOptions.CompressMainHeader)
+ _dynamicMode = true;
+ RINOK(WriteHeader(database, additionalStreamsOptions, headerOptions, headerOffset));
+
+ if (_dynamicMode)
+ {
+ CCompressionMethodMode encryptOptions;
+ encryptOptions.PasswordIsDefined = options->PasswordIsDefined;
+ encryptOptions.Password = options->Password;
+ CEncoder encoder(headerOptions.CompressMainHeader ? *options : encryptOptions);
+ CRecordVector<UInt64> packSizes;
+ CObjectVector<CFolder> folders;
+ RINOK(EncodeStream(encoder, _dynamicBuffer,
+ _dynamicBuffer.GetSize(), packSizes, folders));
+ _dynamicMode = false;
+ _mainMode = true;
+
+ _outByte.SetStream(SeqStream);
+ _outByte.Init();
+ _crc.Init();
+
+ if (folders.Size() == 0)
+ throw 1;
+
+ RINOK(WriteID(NID::kEncodedHeader));
+ RINOK(WritePackInfo(headerOffset, packSizes,
+ CRecordVector<bool>(), CRecordVector<UInt32>()));
+ RINOK(WriteUnPackInfo(false, 0, folders));
+ RINOK(WriteByte(NID::kEnd));
+ for (int i = 0; i < packSizes.Size(); i++)
+ headerOffset += packSizes[i];
+ RINOK(_outByte.Flush());
+ }
+ headerCRC = _crc.GetDigest();
+ headerSize = _outByte.GetProcessedSize();
+ }
+ #ifdef _7Z_VOL
+ if (_endMarker)
+ {
+ CFinishHeader h;
+ h.NextHeaderSize = headerSize;
+ h.NextHeaderCRC = headerCRC;
+ h.NextHeaderOffset =
+ UInt64(0) - (headerSize +
+ 4 + kFinishHeaderSize);
+ h.ArchiveStartOffset = h.NextHeaderOffset - headerOffset;
+ h.AdditionalStartBlockSize = 0;
+ RINOK(WriteFinishHeader(h));
+ return WriteFinishSignature();
+ }
+ else
+ #endif
+ {
+ CStartHeader h;
+ h.NextHeaderSize = headerSize;
+ h.NextHeaderCRC = headerCRC;
+ h.NextHeaderOffset = headerOffset;
+ RINOK(Stream->Seek(_prefixHeaderPos, STREAM_SEEK_SET, NULL));
+ return WriteStartHeader(h);
+ }
+}
+
+}}
diff --git a/CPP/7zip/Archive/7z/7zOut.h b/CPP/7zip/Archive/7z/7zOut.h
new file mode 100755
index 00000000..cccc813a
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zOut.h
@@ -0,0 +1,192 @@
+// 7z/Out.h
+
+#ifndef __7Z_OUT_H
+#define __7Z_OUT_H
+
+#include "7zHeader.h"
+#include "7zItem.h"
+#include "7zCompressionMode.h"
+#include "7zEncode.h"
+
+#include "../../Common/OutBuffer.h"
+#include "../../../Common/DynamicBuffer.h"
+#include "../../../Common/CRC.h"
+
+namespace NArchive {
+namespace N7z {
+
+class CWriteBufferLoc
+{
+ Byte *_data;
+ size_t _size;
+ size_t _pos;
+public:
+ CWriteBufferLoc(): _size(0), _pos(0) {}
+ void Init(Byte *data, size_t size)
+ {
+ _pos = 0;
+ _data = data;
+ _size = size;
+ }
+ HRESULT Write(const void *data, size_t size)
+ {
+ if (_pos + size > _size)
+ return E_FAIL;
+ memmove(_data + _pos, data, size);
+ _pos += size;
+ return S_OK;
+ }
+};
+
+class CWriteDynamicBuffer
+{
+ CByteDynamicBuffer _buffer;
+ size_t _pos;
+public:
+ CWriteDynamicBuffer(): _pos(0) {}
+ void Init()
+ {
+ _pos = 0;
+ }
+ void Write(const void *data, size_t size)
+ {
+ if (_pos + size > _buffer.GetCapacity())
+ _buffer.EnsureCapacity(_pos + size);
+ memmove(((Byte *)_buffer) +_pos, data, size);
+ _pos += size;
+ }
+ operator Byte *() { return (Byte *)_buffer; };
+ operator const Byte *() const { return (const Byte *)_buffer; };
+ size_t GetSize() const { return _pos; }
+};
+
+struct CHeaderOptions
+{
+ bool UseAdditionalHeaderStreams;
+ bool CompressMainHeader;
+ bool WriteModified;
+ bool WriteCreated;
+ bool WriteAccessed;
+
+ CHeaderOptions():
+ UseAdditionalHeaderStreams(false),
+ CompressMainHeader(true),
+ WriteModified(true),
+ WriteCreated(false),
+ WriteAccessed(false) {}
+};
+
+class COutArchive
+{
+ UInt64 _prefixHeaderPos;
+
+ HRESULT WriteDirect(const void *data, UInt32 size);
+ HRESULT WriteDirectByte(Byte b) { return WriteDirect(&b, 1); }
+ HRESULT WriteDirectUInt32(UInt32 value);
+ HRESULT WriteDirectUInt64(UInt64 value);
+
+ HRESULT WriteBytes(const void *data, size_t size);
+ HRESULT WriteBytes(const CByteBuffer &data);
+ HRESULT WriteByte(Byte b);
+ HRESULT WriteUInt32(UInt32 value);
+ HRESULT WriteNumber(UInt64 value);
+ HRESULT WriteID(UInt64 value) { return WriteNumber(value); }
+
+ HRESULT WriteFolder(const CFolder &folder);
+ HRESULT WriteFileHeader(const CFileItem &itemInfo);
+ HRESULT WriteBoolVector(const CBoolVector &boolVector);
+ HRESULT WriteHashDigests(
+ const CRecordVector<bool> &digestsDefined,
+ const CRecordVector<UInt32> &hashDigests);
+
+ HRESULT WritePackInfo(
+ UInt64 dataOffset,
+ const CRecordVector<UInt64> &packSizes,
+ const CRecordVector<bool> &packCRCsDefined,
+ const CRecordVector<UInt32> &packCRCs);
+
+ HRESULT WriteUnPackInfo(
+ bool externalFolders,
+ CNum externalFoldersStreamIndex,
+ const CObjectVector<CFolder> &folders);
+
+ HRESULT WriteSubStreamsInfo(
+ const CObjectVector<CFolder> &folders,
+ const CRecordVector<CNum> &numUnPackStreamsInFolders,
+ const CRecordVector<UInt64> &unPackSizes,
+ const CRecordVector<bool> &digestsDefined,
+ const CRecordVector<UInt32> &hashDigests);
+
+ /*
+ HRESULT WriteStreamsInfo(
+ UInt64 dataOffset,
+ const CRecordVector<UInt64> &packSizes,
+ const CRecordVector<bool> &packCRCsDefined,
+ const CRecordVector<UInt32> &packCRCs,
+ bool externalFolders,
+ UInt64 externalFoldersStreamIndex,
+ const CObjectVector<CFolder> &folders,
+ const CRecordVector<CNum> &numUnPackStreamsInFolders,
+ const CRecordVector<UInt64> &unPackSizes,
+ const CRecordVector<bool> &digestsDefined,
+ const CRecordVector<UInt32> &hashDigests);
+ */
+
+
+ HRESULT WriteTime(const CObjectVector<CFileItem> &files, Byte type,
+ bool isExternal, CNum externalDataIndex);
+
+ HRESULT EncodeStream(CEncoder &encoder, const Byte *data, size_t dataSize,
+ CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
+ HRESULT EncodeStream(CEncoder &encoder, const CByteBuffer &data,
+ CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
+ HRESULT WriteHeader(const CArchiveDatabase &database,
+ const CCompressionMethodMode *options,
+ const CHeaderOptions &headerOptions,
+ UInt64 &headerOffset);
+
+ bool _mainMode;
+
+ bool _dynamicMode;
+
+ bool _countMode;
+ size_t _countSize;
+ COutBuffer _outByte;
+ CWriteBufferLoc _outByte2;
+ CWriteDynamicBuffer _dynamicBuffer;
+ CCRC _crc;
+
+ #ifdef _7Z_VOL
+ bool _endMarker;
+ #endif
+
+ HRESULT WriteSignature();
+ #ifdef _7Z_VOL
+ HRESULT WriteFinishSignature();
+ #endif
+ HRESULT WriteStartHeader(const CStartHeader &h);
+ #ifdef _7Z_VOL
+ HRESULT WriteFinishHeader(const CFinishHeader &h);
+ #endif
+ CMyComPtr<IOutStream> Stream;
+public:
+
+ COutArchive() { _outByte.Create(1 << 16); }
+ CMyComPtr<ISequentialOutStream> SeqStream;
+ HRESULT Create(ISequentialOutStream *stream, bool endMarker);
+ void Close();
+ HRESULT SkeepPrefixArchiveHeader();
+ HRESULT WriteDatabase(const CArchiveDatabase &database,
+ const CCompressionMethodMode *options,
+ const CHeaderOptions &headerOptions);
+
+ #ifdef _7Z_VOL
+ static UInt32 GetVolHeadersSize(UInt64 dataSize, int nameLength = 0, bool props = false);
+ static UInt64 GetVolPureSize(UInt64 volSize, int nameLength = 0, bool props = false);
+ #endif
+
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/7z/7zProperties.cpp b/CPP/7zip/Archive/7z/7zProperties.cpp
new file mode 100755
index 00000000..316f4f09
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zProperties.cpp
@@ -0,0 +1,166 @@
+// 7zProperties.cpp
+
+#include "StdAfx.h"
+
+#include "7zProperties.h"
+#include "7zHeader.h"
+#include "7zHandler.h"
+
+// #define _MULTI_PACK
+
+namespace NArchive {
+namespace N7z {
+
+struct CPropMap
+{
+ UInt64 FilePropID;
+ STATPROPSTG StatPROPSTG;
+};
+
+CPropMap kPropMap[] =
+{
+ { NID::kName, NULL, kpidPath, VT_BSTR},
+ { NID::kSize, NULL, kpidSize, VT_UI8},
+ { NID::kPackInfo, NULL, kpidPackedSize, VT_UI8},
+
+ #ifdef _MULTI_PACK
+ { 100, L"Pack0", kpidPackedSize0, VT_UI8},
+ { 101, L"Pack1", kpidPackedSize1, VT_UI8},
+ { 102, L"Pack2", kpidPackedSize2, VT_UI8},
+ { 103, L"Pack3", kpidPackedSize3, VT_UI8},
+ { 104, L"Pack4", kpidPackedSize4, VT_UI8},
+ #endif
+
+ { NID::kCreationTime, NULL, kpidCreationTime, VT_FILETIME},
+ { NID::kLastWriteTime, NULL, kpidLastWriteTime, VT_FILETIME},
+ { NID::kLastAccessTime, NULL, kpidLastAccessTime, VT_FILETIME},
+ { NID::kWinAttributes, NULL, kpidAttributes, VT_UI4},
+ { NID::kStartPos, NULL, kpidPosition, VT_UI4},
+
+
+ { NID::kCRC, NULL, kpidCRC, VT_UI4},
+
+ { NID::kAnti, L"Anti", kpidIsAnti, VT_BOOL},
+ // { 97, NULL, kpidSolid, VT_BOOL},
+ #ifndef _SFX
+ { 98, NULL, kpidMethod, VT_BSTR},
+ { 99, L"Block", kpidBlock, VT_UI4}
+ #endif
+ // { L"ID", kpidID, VT_BSTR},
+ // { L"UnPack Version", kpidUnPackVersion, VT_UI1},
+ // { L"Host OS", kpidHostOS, VT_BSTR}
+};
+
+static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]);
+
+static int FindPropInMap(UInt64 filePropID)
+{
+ for (int i = 0; i < kPropMapSize; i++)
+ if (kPropMap[i].FilePropID == filePropID)
+ return i;
+ return -1;
+}
+
+static void CopyOneItem(CRecordVector<UInt64> &src,
+ CRecordVector<UInt64> &dest, UInt32 item)
+{
+ for (int i = 0; i < src.Size(); i++)
+ if (src[i] == item)
+ {
+ dest.Add(item);
+ src.Delete(i);
+ return;
+ }
+}
+
+static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item)
+{
+ for (int i = 0; i < src.Size(); i++)
+ if (src[i] == item)
+ {
+ src.Delete(i);
+ return;
+ }
+}
+
+static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item)
+{
+ for (int i = 0; i < dest.Size(); i++)
+ if (dest[i] == item)
+ {
+ dest.Delete(i);
+ break;
+ }
+ dest.Insert(0, item);
+}
+
+void CHandler::FillPopIDs()
+{
+ _fileInfoPopIDs.Clear();
+
+ #ifdef _7Z_VOL
+ if(_volumes.Size() < 1)
+ return;
+ const CVolume &volume = _volumes.Front();
+ const CArchiveDatabaseEx &_database = volume.Database;
+ #endif
+
+ CRecordVector<UInt64> fileInfoPopIDs = _database.ArchiveInfo.FileInfoPopIDs;
+
+ RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream);
+ RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);
+
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kName);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kAnti);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kSize);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kPackInfo);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCreationTime);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastWriteTime);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastAccessTime);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC);
+ CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment);
+ _fileInfoPopIDs += fileInfoPopIDs;
+
+ #ifndef _SFX
+ _fileInfoPopIDs.Add(98);
+ _fileInfoPopIDs.Add(99);
+ #endif
+ #ifdef _MULTI_PACK
+ _fileInfoPopIDs.Add(100);
+ _fileInfoPopIDs.Add(101);
+ _fileInfoPopIDs.Add(102);
+ _fileInfoPopIDs.Add(103);
+ _fileInfoPopIDs.Add(104);
+ #endif
+
+ #ifndef _SFX
+ InsertToHead(_fileInfoPopIDs, NID::kLastWriteTime);
+ InsertToHead(_fileInfoPopIDs, NID::kPackInfo);
+ InsertToHead(_fileInfoPopIDs, NID::kSize);
+ InsertToHead(_fileInfoPopIDs, NID::kName);
+ #endif
+}
+
+STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
+{
+ *numProperties = _fileInfoPopIDs.Size();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType)
+{
+ if((int)index >= _fileInfoPopIDs.Size())
+ return E_INVALIDARG;
+ int indexInMap = FindPropInMap(_fileInfoPopIDs[index]);
+ if (indexInMap == -1)
+ return E_INVALIDARG;
+ const STATPROPSTG &srcItem = kPropMap[indexInMap].StatPROPSTG;
+ *propID = srcItem.propid;
+ *varType = srcItem.vt;
+ *name = 0;
+ return S_OK;
+}
+
+}}
diff --git a/CPP/7zip/Archive/7z/7zProperties.h b/CPP/7zip/Archive/7z/7zProperties.h
new file mode 100755
index 00000000..a09839bb
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zProperties.h
@@ -0,0 +1,22 @@
+// 7zProperties.h
+
+#ifndef __7Z_PROPERTIES_H
+#define __7Z_PROPERTIES_H
+
+#include "../../PropID.h"
+
+namespace NArchive {
+namespace N7z {
+
+enum // PropID
+{
+ kpidPackedSize0 = kpidUserDefined,
+ kpidPackedSize1,
+ kpidPackedSize2,
+ kpidPackedSize3,
+ kpidPackedSize4,
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/7z/7zSpecStream.cpp b/CPP/7zip/Archive/7z/7zSpecStream.cpp
new file mode 100755
index 00000000..80d303a4
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zSpecStream.cpp
@@ -0,0 +1,24 @@
+// 7zSpecStream.cpp
+
+#include "StdAfx.h"
+
+#include "7zSpecStream.h"
+
+STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize;
+ HRESULT result = _stream->Read(data, size, &realProcessedSize);
+ _size += realProcessedSize;
+ if (processedSize != 0)
+ *processedSize = realProcessedSize;
+ return result;
+}
+
+STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(
+ UInt64 subStream, UInt64 *value)
+{
+ if (_getSubStreamSize == NULL)
+ return E_NOTIMPL;
+ return _getSubStreamSize->GetSubStreamSize(subStream, value);
+}
+
diff --git a/CPP/7zip/Archive/7z/7zSpecStream.h b/CPP/7zip/Archive/7z/7zSpecStream.h
new file mode 100755
index 00000000..0253c421
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zSpecStream.h
@@ -0,0 +1,35 @@
+// 7zSpecStream.h
+
+#ifndef __7Z_SPEC_STREAM_H
+#define __7Z_SPEC_STREAM_H
+
+#include "../../IStream.h"
+#include "../../ICoder.h"
+#include "../../../Common/MyCom.h"
+
+class CSequentialInStreamSizeCount2:
+ public ISequentialInStream,
+ public ICompressGetSubStreamSize,
+ public CMyUnknownImp
+{
+ CMyComPtr<ISequentialInStream> _stream;
+ CMyComPtr<ICompressGetSubStreamSize> _getSubStreamSize;
+ UInt64 _size;
+public:
+ void Init(ISequentialInStream *stream)
+ {
+ _stream = stream;
+ _getSubStreamSize = 0;
+ _stream.QueryInterface(IID_ICompressGetSubStreamSize, &_getSubStreamSize);
+ _size = 0;
+ }
+ UInt64 GetSize() const { return _size; }
+
+ MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+
+ STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
+};
+
+#endif
diff --git a/CPP/7zip/Archive/7z/7zUpdate.cpp b/CPP/7zip/Archive/7z/7zUpdate.cpp
new file mode 100755
index 00000000..b3d5009a
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zUpdate.cpp
@@ -0,0 +1,1099 @@
+// UpdateMain.cpp
+
+#include "StdAfx.h"
+
+#include "7zUpdate.h"
+#include "7zFolderInStream.h"
+#include "7zEncode.h"
+#include "7zHandler.h"
+#include "7zOut.h"
+
+#ifndef EXCLUDE_COM
+#include "7zMethods.h"
+#endif
+
+#include "../../Compress/Copy/CopyCoder.h"
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/LimitedStreams.h"
+#include "../../Common/LimitedStreams.h"
+#include "../Common/ItemNameUtils.h"
+
+namespace NArchive {
+namespace N7z {
+
+static const wchar_t *kMatchFinderForBCJ2_LZMA = L"BT2";
+static const UInt32 kDictionaryForBCJ2_LZMA = 1 << 20;
+static const UInt32 kAlgorithmForBCJ2_LZMA = 1;
+static const UInt32 kNumFastBytesForBCJ2_LZMA = 64;
+
+static HRESULT CopyBlock(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, ICompressProgressInfo *progress)
+{
+ CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
+ return copyCoder->Code(inStream, outStream, NULL, NULL, progress);
+}
+
+static HRESULT WriteRange(
+ ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ UInt64 size,
+ IProgress *progress,
+ UInt64 &currentComplexity)
+{
+ CLimitedSequentialInStream *streamSpec = new
+ CLimitedSequentialInStream;
+ CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);
+ streamSpec->SetStream(inStream);
+ streamSpec->Init(size);
+
+ CLocalProgress *localProgressSpec = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
+ localProgressSpec->Init(progress, true);
+
+ CLocalCompressProgressInfo *localCompressProgressSpec =
+ new CLocalCompressProgressInfo;
+ CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
+
+ localCompressProgressSpec->Init(localProgress, &currentComplexity, &currentComplexity);
+
+ HRESULT result = CopyBlock(inStreamLimited, outStream, compressProgress);
+ currentComplexity += size;
+ return result;
+}
+
+
+static HRESULT WriteRange(IInStream *inStream,
+ ISequentialOutStream *outStream,
+ UInt64 position,
+ UInt64 size,
+ IProgress *progress,
+ UInt64 &currentComplexity)
+{
+ inStream->Seek(position, STREAM_SEEK_SET, 0);
+ return WriteRange(inStream, outStream,
+ size, progress, currentComplexity);
+}
+
+static int GetReverseSlashPos(const UString &name)
+{
+ int slashPos = name.ReverseFind(L'/');
+ #ifdef _WIN32
+ int slash1Pos = name.ReverseFind(L'\\');
+ slashPos = MyMax(slashPos, slash1Pos);
+ #endif
+ return slashPos;
+}
+
+int CUpdateItem::GetExtensionPos() const
+{
+ int slashPos = GetReverseSlashPos(Name);
+ int dotPos = Name.ReverseFind(L'.');
+ if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0))
+ return Name.Length();
+ return dotPos + 1;
+}
+
+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; }
+
+static int CompareMethodIDs(const CMethodID &a1, const CMethodID &a2)
+{
+ for (int i = 0; i < a1.IDSize && i < a2.IDSize; i++)
+ RINOZ(MyCompare(a1.ID[i], a2.ID[i]));
+ return MyCompare(a1.IDSize, a2.IDSize);
+}
+
+static int CompareBuffers(const CByteBuffer &a1, const CByteBuffer &a2)
+{
+ size_t c1 = a1.GetCapacity();
+ size_t c2 = a2.GetCapacity();
+ RINOZ(MyCompare(c1, c2));
+ for (size_t i = 0; i < c1; i++)
+ RINOZ(MyCompare(a1[i], a2[i]));
+ return 0;
+}
+
+static int CompareAltCoders(const CAltCoderInfo &a1, const CAltCoderInfo &a2)
+{
+ RINOZ(CompareMethodIDs(a1.MethodID, a2.MethodID));
+ return CompareBuffers(a1.Properties, a2.Properties);
+}
+
+static int CompareCoders(const CCoderInfo &c1, const CCoderInfo &c2)
+{
+ RINOZ(MyCompare(c1.NumInStreams, c2.NumInStreams));
+ RINOZ(MyCompare(c1.NumOutStreams, c2.NumOutStreams));
+ int s1 = c1.AltCoders.Size();
+ int s2 = c2.AltCoders.Size();
+ RINOZ(MyCompare(s1, s2));
+ for (int i = 0; i < s1; i++)
+ RINOZ(CompareAltCoders(c1.AltCoders[i], c2.AltCoders[i]));
+ return 0;
+}
+
+static int CompareBindPairs(const CBindPair &b1, const CBindPair &b2)
+{
+ RINOZ(MyCompare(b1.InIndex, b2.InIndex));
+ return MyCompare(b1.OutIndex, b2.OutIndex);
+}
+
+static int CompareFolders(const CFolder &f1, const CFolder &f2)
+{
+ int s1 = f1.Coders.Size();
+ int s2 = f2.Coders.Size();
+ RINOZ(MyCompare(s1, s2));
+ int i;
+ for (i = 0; i < s1; i++)
+ RINOZ(CompareCoders(f1.Coders[i], f2.Coders[i]));
+ s1 = f1.BindPairs.Size();
+ s2 = f2.BindPairs.Size();
+ RINOZ(MyCompare(s1, s2));
+ for (i = 0; i < s1; i++)
+ RINOZ(CompareBindPairs(f1.BindPairs[i], f2.BindPairs[i]));
+ return 0;
+}
+
+static int CompareFiles(const CFileItem &f1, const CFileItem &f2)
+{
+ return MyStringCompareNoCase(f1.Name, f2.Name);
+}
+
+static int CompareFolderRefs(const int *p1, const int *p2, void *param)
+{
+ int i1 = *p1;
+ int i2 = *p2;
+ const CArchiveDatabaseEx &db = *(const CArchiveDatabaseEx *)param;
+ RINOZ(CompareFolders(
+ db.Folders[i1],
+ db.Folders[i2]));
+ RINOZ(MyCompare(
+ db.NumUnPackStreamsVector[i1],
+ db.NumUnPackStreamsVector[i2]));
+ if (db.NumUnPackStreamsVector[i1] == 0)
+ return 0;
+ return CompareFiles(
+ db.Files[db.FolderStartFileIndex[i1]],
+ db.Files[db.FolderStartFileIndex[i2]]);
+}
+
+////////////////////////////////////////////////////////////
+
+static int CompareEmptyItems(const int *p1, const int *p2, void *param)
+{
+ const CObjectVector<CUpdateItem> &updateItems = *(const CObjectVector<CUpdateItem> *)param;
+ const CUpdateItem &u1 = updateItems[*p1];
+ const CUpdateItem &u2 = updateItems[*p2];
+ if (u1.IsDirectory != u2.IsDirectory)
+ return (u1.IsDirectory) ? 1 : -1;
+ if (u1.IsDirectory)
+ {
+ if (u1.IsAnti != u2.IsAnti)
+ return (u1.IsAnti ? 1 : -1);
+ int n = MyStringCompareNoCase(u1.Name, u2.Name);
+ return -n;
+ }
+ if (u1.IsAnti != u2.IsAnti)
+ return (u1.IsAnti ? 1 : -1);
+ return MyStringCompareNoCase(u1.Name, u2.Name);
+}
+
+static const char *g_Exts =
+ " lzma 7z ace arc arj bz bz2 deb lzo lzx gz pak rpm sit tgz tbz tbz2 tgz cab ha lha lzh rar zoo"
+ " zip jar ear war msi"
+ " 3gp avi mov mpeg mpg mpe wmv"
+ " aac ape fla flac la mp3 m4a mp4 ofr ogg pac ra rm rka shn swa tta wv wma wav"
+ " swf "
+ " chm hxi hxs"
+ " gif jpeg jpg jp2 png tiff bmp ico psd psp"
+ " awg ps eps cgm dxf svg vrml wmf emf ai md"
+ " cad dwg pps key sxi"
+ " max 3ds"
+ " iso bin nrg mdf img pdi tar cpio xpi"
+ " vfd vhd vud vmc vsv"
+ " vmdk dsk nvram vmem vmsd vmsn vmss vmtm"
+ " inl inc idl acf asa h hpp hxx c cpp cxx rc java cs pas bas vb cls ctl frm dlg def"
+ " f77 f f90 f95"
+ " asm sql manifest dep "
+ " mak clw csproj vcproj sln dsp dsw "
+ " class "
+ " bat cmd"
+ " xml xsd xsl xslt hxk hxc htm html xhtml xht mht mhtml htw asp aspx css cgi jsp shtml"
+ " awk sed hta js php php3 php4 php5 phptml pl pm py pyo rb sh tcl vbs"
+ " text txt tex ans asc srt reg ini doc docx mcw dot rtf hlp xls xlr xlt xlw ppt pdf"
+ " sxc sxd sxi sxg sxw stc sti stw stm odt ott odg otg odp otp ods ots odf"
+ " abw afp cwk lwp wpd wps wpt wrf wri"
+ " abf afm bdf fon mgf otf pcf pfa snf ttf"
+ " dbf mdb nsf ntf wdb db fdb gdb"
+ " exe dll ocx vbx sfx sys tlb awx com obj lib out o so "
+ " pdb pch idb ncb opt";
+
+int GetExtIndex(const char *ext)
+{
+ int extIndex = 1;
+ const char *p = g_Exts;
+ for (;;)
+ {
+ char c = *p++;
+ if (c == 0)
+ return extIndex;
+ if (c == ' ')
+ continue;
+ int pos = 0;
+ for (;;)
+ {
+ char c2 = ext[pos++];
+ if (c2 == 0 && (c == 0 || c == ' '))
+ return extIndex;
+ if (c != c2)
+ break;
+ c = *p++;
+ }
+ extIndex++;
+ for (;;)
+ {
+ if (c == 0)
+ return extIndex;
+ if (c == ' ')
+ break;
+ c = *p++;
+ }
+ }
+}
+
+struct CRefItem
+{
+ UInt32 Index;
+ const CUpdateItem *UpdateItem;
+ UInt32 ExtensionPos;
+ UInt32 NamePos;
+ int ExtensionIndex;
+ CRefItem(UInt32 index, const CUpdateItem &updateItem, bool sortByType):
+ Index(index),
+ UpdateItem(&updateItem),
+ ExtensionPos(0),
+ NamePos(0),
+ ExtensionIndex(0)
+ {
+ if (sortByType)
+ {
+ int slashPos = GetReverseSlashPos(updateItem.Name);
+ NamePos = ((slashPos >= 0) ? (slashPos + 1) : 0);
+ int dotPos = updateItem.Name.ReverseFind(L'.');
+ if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0))
+ ExtensionPos = updateItem.Name.Length();
+ else
+ {
+ ExtensionPos = dotPos + 1;
+ UString us = updateItem.Name.Mid(ExtensionPos);
+ if (!us.IsEmpty())
+ {
+ us.MakeLower();
+ int i;
+ AString s;
+ for (i = 0; i < us.Length(); i++)
+ {
+ wchar_t c = us[i];
+ if (c >= 0x80)
+ break;
+ s += (char)c;
+ }
+ if (i == us.Length())
+ ExtensionIndex = GetExtIndex(s);
+ else
+ ExtensionIndex = 0;
+ }
+ }
+ }
+ }
+};
+
+static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *param)
+{
+ const CRefItem &a1 = *p1;
+ const CRefItem &a2 = *p2;
+ const CUpdateItem &u1 = *a1.UpdateItem;
+ const CUpdateItem &u2 = *a2.UpdateItem;
+ int n;
+ if (u1.IsDirectory != u2.IsDirectory)
+ return (u1.IsDirectory) ? 1 : -1;
+ if (u1.IsDirectory)
+ {
+ if (u1.IsAnti != u2.IsAnti)
+ return (u1.IsAnti ? 1 : -1);
+ n = MyStringCompareNoCase(u1.Name, u2.Name);
+ return -n;
+ }
+ bool sortByType = *(bool *)param;
+ if (sortByType)
+ {
+ RINOZ(MyCompare(a1.ExtensionIndex, a2.ExtensionIndex))
+ RINOZ(MyStringCompareNoCase(u1.Name + a1.ExtensionPos, u2.Name + a2.ExtensionPos));
+ RINOZ(MyStringCompareNoCase(u1.Name + a1.NamePos, u2.Name + a2.NamePos));
+ if (u1.IsLastWriteTimeDefined && u2.IsLastWriteTimeDefined)
+ RINOZ(CompareFileTime(&u1.LastWriteTime, &u2.LastWriteTime));
+ RINOZ(MyCompare(u1.Size, u2.Size))
+ }
+ return MyStringCompareNoCase(u1.Name, u2.Name);
+}
+
+struct CSolidGroup
+{
+ CCompressionMethodMode Method;
+ CRecordVector<UInt32> Indices;
+};
+
+static wchar_t *g_ExeExts[] =
+{
+ L"dll",
+ L"exe",
+ L"ocx",
+ L"sfx",
+ L"sys"
+};
+
+static bool IsExeFile(const UString &ext)
+{
+ for (int i = 0; i < sizeof(g_ExeExts) / sizeof(g_ExeExts[0]); i++)
+ if (ext.CompareNoCase(g_ExeExts[i]) == 0)
+ return true;
+ return false;
+}
+
+static CMethodID k_BCJ_X86 = { { 0x3, 0x3, 0x1, 0x3 }, 4 };
+static CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 };
+static CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
+
+static bool GetMethodFull(const CMethodID &methodID,
+ UInt32 numInStreams, CMethodFull &methodResult)
+{
+ methodResult.MethodID = methodID;
+ methodResult.NumInStreams = numInStreams;
+ methodResult.NumOutStreams = 1;
+
+ #ifndef EXCLUDE_COM
+ CMethodInfo methodInfo;
+ if (!GetMethodInfo(methodID, methodInfo))
+ return false;
+ if (!methodInfo.EncoderIsAssigned)
+ return false;
+ methodResult.EncoderClassID = methodInfo.Encoder;
+ methodResult.FilePath = methodInfo.FilePath;
+ if (methodInfo.NumOutStreams != 1 || methodInfo.NumInStreams != numInStreams)
+ return false;
+ #endif
+ return true;
+}
+
+static bool MakeExeMethod(const CCompressionMethodMode &method,
+ bool bcj2Filter, CCompressionMethodMode &exeMethod)
+{
+ exeMethod = method;
+ if (bcj2Filter)
+ {
+ CMethodFull methodFull;
+ if (!GetMethodFull(k_BCJ2, 4, methodFull))
+ return false;
+ exeMethod.Methods.Insert(0, methodFull);
+ if (!GetMethodFull(k_LZMA, 1, methodFull))
+ return false;
+ {
+ CProperty property;
+ property.PropID = NCoderPropID::kAlgorithm;
+ property.Value = kAlgorithmForBCJ2_LZMA;
+ methodFull.CoderProperties.Add(property);
+ }
+ {
+ CProperty property;
+ property.PropID = NCoderPropID::kMatchFinder;
+ property.Value = kMatchFinderForBCJ2_LZMA;
+ methodFull.CoderProperties.Add(property);
+ }
+ {
+ CProperty property;
+ property.PropID = NCoderPropID::kDictionarySize;
+ property.Value = kDictionaryForBCJ2_LZMA;
+ methodFull.CoderProperties.Add(property);
+ }
+ {
+ CProperty property;
+ property.PropID = NCoderPropID::kNumFastBytes;
+ property.Value = kNumFastBytesForBCJ2_LZMA;
+ methodFull.CoderProperties.Add(property);
+ }
+
+ exeMethod.Methods.Add(methodFull);
+ exeMethod.Methods.Add(methodFull);
+ CBind bind;
+
+ bind.OutCoder = 0;
+ bind.InStream = 0;
+
+ bind.InCoder = 1;
+ bind.OutStream = 0;
+ exeMethod.Binds.Add(bind);
+
+ bind.InCoder = 2;
+ bind.OutStream = 1;
+ exeMethod.Binds.Add(bind);
+
+ bind.InCoder = 3;
+ bind.OutStream = 2;
+ exeMethod.Binds.Add(bind);
+ }
+ else
+ {
+ CMethodFull methodFull;
+ if (!GetMethodFull(k_BCJ_X86, 1, methodFull))
+ return false;
+ exeMethod.Methods.Insert(0, methodFull);
+ CBind bind;
+ bind.OutCoder = 0;
+ bind.InStream = 0;
+ bind.InCoder = 1;
+ bind.OutStream = 0;
+ exeMethod.Binds.Add(bind);
+ }
+ return true;
+}
+
+static void SplitFilesToGroups(
+ const CCompressionMethodMode &method,
+ bool useFilters, bool maxFilter,
+ const CObjectVector<CUpdateItem> &updateItems,
+ CObjectVector<CSolidGroup> &groups)
+{
+ if (method.Methods.Size() != 1 || method.Binds.Size() != 0)
+ useFilters = false;
+ groups.Clear();
+ groups.Add(CSolidGroup());
+ groups.Add(CSolidGroup());
+ CSolidGroup &generalGroup = groups[0];
+ CSolidGroup &exeGroup = groups[1];
+ generalGroup.Method = method;
+ int i;
+ for (i = 0; i < updateItems.Size(); i++)
+ {
+ const CUpdateItem &updateItem = updateItems[i];
+ if (!updateItem.NewData)
+ continue;
+ if (!updateItem.HasStream())
+ continue;
+ if (useFilters)
+ {
+ const UString name = updateItem.Name;
+ int dotPos = name.ReverseFind(L'.');
+ if (dotPos >= 0)
+ {
+ UString ext = name.Mid(dotPos + 1);
+ if (IsExeFile(ext))
+ {
+ exeGroup.Indices.Add(i);
+ continue;
+ }
+ }
+ }
+ generalGroup.Indices.Add(i);
+ }
+ if (exeGroup.Indices.Size() > 0)
+ if (!MakeExeMethod(method, maxFilter, exeGroup.Method))
+ exeGroup.Method = method;
+ for (i = 0; i < groups.Size();)
+ if (groups[i].Indices.Size() == 0)
+ groups.Delete(i);
+ else
+ i++;
+}
+
+static void FromUpdateItemToFileItem(const CUpdateItem &updateItem,
+ CFileItem &file)
+{
+ file.Name = NItemName::MakeLegalName(updateItem.Name);
+ if (updateItem.AttributesAreDefined)
+ file.SetAttributes(updateItem.Attributes);
+
+ if (updateItem.IsCreationTimeDefined)
+ file.SetCreationTime(updateItem.CreationTime);
+ if (updateItem.IsLastWriteTimeDefined)
+ file.SetLastWriteTime(updateItem.LastWriteTime);
+ if (updateItem.IsLastAccessTimeDefined)
+ file.SetLastAccessTime(updateItem.LastAccessTime);
+
+ file.UnPackSize = updateItem.Size;
+ file.IsDirectory = updateItem.IsDirectory;
+ file.IsAnti = updateItem.IsAnti;
+ file.HasStream = updateItem.HasStream();
+}
+
+static HRESULT Update2(
+ IInStream *inStream,
+ const CArchiveDatabaseEx *database,
+ const CObjectVector<CUpdateItem> &updateItems,
+ ISequentialOutStream *seqOutStream,
+ IArchiveUpdateCallback *updateCallback,
+ const CUpdateOptions &options)
+{
+ UInt64 numSolidFiles = options.NumSolidFiles;
+ if (numSolidFiles == 0)
+ numSolidFiles = 1;
+ /*
+ CMyComPtr<IOutStream> outStream;
+ RINOK(seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStream));
+ if (!outStream)
+ return E_NOTIMPL;
+ */
+
+ UInt64 startBlockSize = database != 0 ?
+ database->ArchiveInfo.StartPosition: 0;
+ if (startBlockSize > 0 && !options.RemoveSfxBlock)
+ {
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+ CMyComPtr<ISequentialInStream> limitedStream(streamSpec);
+ RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
+ streamSpec->SetStream(inStream);
+ streamSpec->Init(startBlockSize);
+ RINOK(CopyBlock(limitedStream, seqOutStream, NULL));
+ }
+
+ CRecordVector<int> fileIndexToUpdateIndexMap;
+ if (database != 0)
+ {
+ fileIndexToUpdateIndexMap.Reserve(database->Files.Size());
+ for (int i = 0; i < database->Files.Size(); i++)
+ fileIndexToUpdateIndexMap.Add(-1);
+ }
+ int i;
+ for(i = 0; i < updateItems.Size(); i++)
+ {
+ int index = updateItems[i].IndexInArchive;
+ if (index != -1)
+ fileIndexToUpdateIndexMap[index] = i;
+ }
+
+ 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++)
+ {
+ 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);
+ }
+ folderRefs.Sort(CompareFolderRefs, (void *)database);
+ }
+
+ CArchiveDatabase newDatabase;
+
+ ////////////////////////////
+
+ COutArchive archive;
+ RINOK(archive.Create(seqOutStream, false));
+ RINOK(archive.SkeepPrefixArchiveHeader());
+ UInt64 complexity = 0;
+ for(i = 0; i < folderRefs.Size(); i++)
+ complexity += database->GetFolderFullPackSize(folderRefs[i]);
+ UInt64 inSizeForReduce = 0;
+ for(i = 0; i < updateItems.Size(); i++)
+ {
+ const CUpdateItem &updateItem = updateItems[i];
+ if (updateItem.NewData)
+ {
+ complexity += updateItem.Size;
+ if (numSolidFiles == 1)
+ {
+ if (updateItem.Size > inSizeForReduce)
+ inSizeForReduce = updateItem.Size;
+ }
+ else
+ inSizeForReduce += updateItem.Size;
+ }
+ }
+ RINOK(updateCallback->SetTotal(complexity));
+ complexity = 0;
+ RINOK(updateCallback->SetCompleted(&complexity));
+
+ /////////////////////////////////////////
+ // Write Copy Items
+
+ for(i = 0; i < folderRefs.Size(); i++)
+ {
+ int folderIndex = folderRefs[i];
+
+ RINOK(WriteRange(inStream, archive.SeqStream,
+ database->GetFolderStreamPos(folderIndex, 0),
+ database->GetFolderFullPackSize(folderIndex),
+ updateCallback, complexity));
+
+ const CFolder &folder = database->Folders[folderIndex];
+ CNum startIndex = database->FolderStartPackStreamIndex[folderIndex];
+ for (int j = 0; j < folder.PackStreams.Size(); j++)
+ {
+ newDatabase.PackSizes.Add(database->PackSizes[startIndex + j]);
+ // newDatabase.PackCRCsDefined.Add(database.PackCRCsDefined[startIndex + j]);
+ // newDatabase.PackCRCs.Add(database.PackCRCs[startIndex + j]);
+ }
+ newDatabase.Folders.Add(folder);
+
+ CNum numUnPackStreams = database->NumUnPackStreamsVector[folderIndex];
+ newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
+
+ CNum indexInFolder = 0;
+ for (CNum fi = database->FolderStartFileIndex[folderIndex];
+ indexInFolder < numUnPackStreams; fi++)
+ {
+ CFileItem file = database->Files[fi];
+ if (file.HasStream)
+ {
+ indexInFolder++;
+ int updateIndex = fileIndexToUpdateIndexMap[fi];
+ if (updateIndex >= 0)
+ {
+ const CUpdateItem &updateItem = updateItems[updateIndex];
+ if (updateItem.NewProperties)
+ {
+ CFileItem file2;
+ FromUpdateItemToFileItem(updateItem, file2);
+ file2.UnPackSize = file.UnPackSize;
+ file2.FileCRC = file.FileCRC;
+ file2.IsFileCRCDefined = file.IsFileCRCDefined;
+ file2.HasStream = file.HasStream;
+ file = file2;
+ }
+ }
+ newDatabase.Files.Add(file);
+ }
+ }
+ }
+
+ /////////////////////////////////////////
+ // Compress New Files
+
+ CObjectVector<CSolidGroup> groups;
+ SplitFilesToGroups(*options.Method, options.UseFilters, options.MaxFilter,
+ updateItems, groups);
+
+ const UInt32 kMinReduceSize = (1 << 16);
+ if (inSizeForReduce < kMinReduceSize)
+ inSizeForReduce = kMinReduceSize;
+
+ for (int groupIndex = 0; groupIndex < groups.Size(); groupIndex++)
+ {
+ const CSolidGroup &group = groups[groupIndex];
+ int numFiles = group.Indices.Size();
+ if (numFiles == 0)
+ continue;
+ CRecordVector<CRefItem> refItems;
+ refItems.Reserve(numFiles);
+ bool sortByType = (numSolidFiles > 1);
+ for (i = 0; i < numFiles; i++)
+ refItems.Add(CRefItem(group.Indices[i], updateItems[group.Indices[i]], sortByType));
+ refItems.Sort(CompareUpdateItems, (void *)&sortByType);
+
+ CRecordVector<UInt32> indices;
+ indices.Reserve(numFiles);
+
+ for (i = 0; i < numFiles; i++)
+ {
+ UInt32 index = refItems[i].Index;
+ indices.Add(index);
+ /*
+ const CUpdateItem &updateItem = updateItems[index];
+ CFileItem file;
+ if (updateItem.NewProperties)
+ FromUpdateItemToFileItem(updateItem, file);
+ else
+ file = database.Files[updateItem.IndexInArchive];
+ if (file.IsAnti || file.IsDirectory)
+ return E_FAIL;
+ newDatabase.Files.Add(file);
+ */
+ }
+
+ CEncoder encoder(group.Method);
+
+ for (i = 0; i < numFiles;)
+ {
+ UInt64 totalSize = 0;
+ int numSubFiles;
+ UString prevExtension;
+ for (numSubFiles = 0; i + numSubFiles < numFiles &&
+ numSubFiles < numSolidFiles; numSubFiles++)
+ {
+ const CUpdateItem &updateItem = updateItems[indices[i + numSubFiles]];
+ totalSize += updateItem.Size;
+ if (totalSize > options.NumSolidBytes)
+ break;
+ if (options.SolidExtension)
+ {
+ UString ext = updateItem.GetExtension();
+ if (numSubFiles == 0)
+ prevExtension = ext;
+ else
+ if (ext.CompareNoCase(prevExtension) != 0)
+ break;
+ }
+ }
+ if (numSubFiles < 1)
+ numSubFiles = 1;
+
+ CFolderInStream *inStreamSpec = new CFolderInStream;
+ CMyComPtr<ISequentialInStream> solidInStream(inStreamSpec);
+ inStreamSpec->Init(updateCallback, &indices[i], numSubFiles);
+
+ CFolder folderItem;
+ CLocalProgress *localProgressSpec = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
+ localProgressSpec->Init(updateCallback, true);
+ CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
+ CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
+ localCompressProgressSpec->Init(localProgress, &complexity, NULL);
+
+ RINOK(encoder.Encode(solidInStream, NULL, &inSizeForReduce, folderItem,
+ archive.SeqStream, newDatabase.PackSizes, compressProgress));
+ // for()
+ // newDatabase.PackCRCsDefined.Add(false);
+ // newDatabase.PackCRCs.Add(0);
+
+ newDatabase.Folders.Add(folderItem);
+
+ CNum numUnPackStreams = 0;
+ for (int subIndex = 0; subIndex < numSubFiles; subIndex++)
+ {
+ const CUpdateItem &updateItem = updateItems[indices[i + subIndex]];
+ CFileItem file;
+ if (updateItem.NewProperties)
+ FromUpdateItemToFileItem(updateItem, file);
+ else
+ file = database->Files[updateItem.IndexInArchive];
+ if (file.IsAnti || file.IsDirectory)
+ return E_FAIL;
+
+ /*
+ CFileItem &file = newDatabase.Files[
+ startFileIndexInDatabase + i + subIndex];
+ */
+ if (!inStreamSpec->Processed[subIndex])
+ {
+ continue;
+ // file.Name += L".locked";
+ }
+
+ file.FileCRC = inStreamSpec->CRCs[subIndex];
+ file.UnPackSize = inStreamSpec->Sizes[subIndex];
+ if (file.UnPackSize != 0)
+ {
+ file.IsFileCRCDefined = true;
+ file.HasStream = true;
+ numUnPackStreams++;
+ complexity += file.UnPackSize;
+ }
+ else
+ {
+ file.IsFileCRCDefined = false;
+ file.HasStream = false;
+ }
+ newDatabase.Files.Add(file);
+ }
+ // numUnPackStreams = 0 is very bad case for locked files
+ // v3.13 doesn't understand it.
+ newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
+ i += numSubFiles;
+ }
+ }
+
+ {
+ /////////////////////////////////////////
+ // Write Empty Files & Folders
+
+ CRecordVector<int> emptyRefs;
+ for(i = 0; i < updateItems.Size(); i++)
+ {
+ const CUpdateItem &updateItem = updateItems[i];
+ if (updateItem.NewData)
+ {
+ if (updateItem.HasStream())
+ continue;
+ }
+ else
+ if (updateItem.IndexInArchive != -1)
+ if (database->Files[updateItem.IndexInArchive].HasStream)
+ continue;
+ emptyRefs.Add(i);
+ }
+ emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems);
+ for(i = 0; i < emptyRefs.Size(); i++)
+ {
+ const CUpdateItem &updateItem = updateItems[emptyRefs[i]];
+ CFileItem file;
+ if (updateItem.NewProperties)
+ FromUpdateItemToFileItem(updateItem, file);
+ else
+ file = database->Files[updateItem.IndexInArchive];
+ newDatabase.Files.Add(file);
+ }
+ }
+
+ /*
+ if (newDatabase.Files.Size() != updateItems.Size())
+ return E_FAIL;
+ */
+
+ return archive.WriteDatabase(newDatabase, options.HeaderMethod, options.HeaderOptions);
+}
+
+#ifdef _7Z_VOL
+
+static HRESULT WriteVolumeHeader(COutArchive &archive, CFileItem &file, const CUpdateOptions &options)
+{
+ CAltCoderInfo altCoder;
+ altCoder.MethodID.IDSize = 1;
+ altCoder.MethodID.ID[0] = 0;
+ CCoderInfo coder;
+ coder.NumInStreams = coder.NumOutStreams = 1;
+ coder.AltCoders.Add(altCoder);
+
+ CFolder folder;
+ folder.Coders.Add(coder);
+ folder.PackStreams.Add(0);
+
+ CNum numUnPackStreams = 0;
+ if (file.UnPackSize != 0)
+ {
+ file.IsFileCRCDefined = true;
+ file.HasStream = true;
+ numUnPackStreams++;
+ }
+ else
+ {
+ throw 1;
+ file.IsFileCRCDefined = false;
+ file.HasStream = false;
+ }
+ folder.UnPackSizes.Add(file.UnPackSize);
+
+ CArchiveDatabase newDatabase;
+ newDatabase.Files.Add(file);
+ newDatabase.Folders.Add(folder);
+ newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
+ newDatabase.PackSizes.Add(file.UnPackSize);
+ newDatabase.PackCRCsDefined.Add(false);
+ newDatabase.PackCRCs.Add(file.FileCRC);
+
+ return archive.WriteDatabase(newDatabase,
+ options.HeaderMethod,
+ false,
+ false);
+}
+
+HRESULT UpdateVolume(
+ IInStream *inStream,
+ const CArchiveDatabaseEx *database,
+ CObjectVector<CUpdateItem> &updateItems,
+ ISequentialOutStream *seqOutStream,
+ IArchiveUpdateCallback *updateCallback,
+ const CUpdateOptions &options)
+{
+ if (updateItems.Size() != 1)
+ return E_NOTIMPL;
+
+ CMyComPtr<IArchiveUpdateCallback2> volumeCallback;
+ RINOK(updateCallback->QueryInterface(IID_IArchiveUpdateCallback2, (void **)&volumeCallback));
+ if (!volumeCallback)
+ return E_NOTIMPL;
+
+ CMyComPtr<ISequentialInStream> fileStream;
+ HRESULT result = updateCallback->GetStream(0, &fileStream);
+ if (result != S_OK && result != S_FALSE)
+ return result;
+ if (result == S_FALSE)
+ return E_FAIL;
+
+ CFileItem file;
+
+ const CUpdateItem &updateItem = updateItems[0];
+ if (updateItem.NewProperties)
+ FromUpdateItemToFileItem(updateItem, file);
+ else
+ file = database->Files[updateItem.IndexInArchive];
+ if (file.IsAnti || file.IsDirectory)
+ return E_FAIL;
+
+ UInt64 complexity = 0;
+ file.IsStartPosDefined = true;
+ file.StartPos = 0;
+ for (UInt64 volumeIndex = 0; true; volumeIndex++)
+ {
+ UInt64 volSize;
+ RINOK(volumeCallback->GetVolumeSize(volumeIndex, &volSize));
+ UInt64 pureSize = COutArchive::GetVolPureSize(volSize, file.Name.Length(), true);
+ CMyComPtr<ISequentialOutStream> volumeStream;
+ RINOK(volumeCallback->GetVolumeStream(volumeIndex, &volumeStream));
+
+ COutArchive archive;
+ RINOK(archive.Create(volumeStream, true));
+ RINOK(archive.SkeepPrefixArchiveHeader());
+
+ CSequentialInStreamWithCRC *inCrcStreamSpec = new CSequentialInStreamWithCRC;
+ CMyComPtr<ISequentialInStream> inCrcStream = inCrcStreamSpec;
+ inCrcStreamSpec->Init(fileStream);
+
+ RINOK(WriteRange(inCrcStream, volumeStream, pureSize,
+ updateCallback, complexity));
+ file.UnPackSize = inCrcStreamSpec->GetSize();
+ if (file.UnPackSize == 0)
+ break;
+ file.FileCRC = inCrcStreamSpec->GetCRC();
+ RINOK(WriteVolumeHeader(archive, file, options));
+ file.StartPos += file.UnPackSize;
+ if (file.UnPackSize < pureSize)
+ break;
+ }
+ return S_OK;
+}
+
+class COutVolumeStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ int _volIndex;
+ UInt64 _volSize;
+ UInt64 _curPos;
+ CMyComPtr<ISequentialOutStream> _volumeStream;
+ COutArchive _archive;
+ CCRC _crc;
+
+public:
+ MY_UNKNOWN_IMP
+
+ CFileItem _file;
+ CUpdateOptions _options;
+ CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
+ void Init(IArchiveUpdateCallback2 *volumeCallback,
+ const UString &name)
+ {
+ _file.Name = name;
+ _file.IsStartPosDefined = true;
+ _file.StartPos = 0;
+
+ VolumeCallback = volumeCallback;
+ _volIndex = 0;
+ _volSize = 0;
+ }
+
+ HRESULT Flush();
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+HRESULT COutVolumeStream::Flush()
+{
+ if (_volumeStream)
+ {
+ _file.UnPackSize = _curPos;
+ _file.FileCRC = _crc.GetDigest();
+ RINOK(WriteVolumeHeader(_archive, _file, _options));
+ _archive.Close();
+ _volumeStream.Release();
+ _file.StartPos += _file.UnPackSize;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP COutVolumeStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if(processedSize != NULL)
+ *processedSize = 0;
+ while(size > 0)
+ {
+ if (!_volumeStream)
+ {
+ RINOK(VolumeCallback->GetVolumeSize(_volIndex, &_volSize));
+ RINOK(VolumeCallback->GetVolumeStream(_volIndex, &_volumeStream));
+ _volIndex++;
+ _curPos = 0;
+ RINOK(_archive.Create(_volumeStream, true));
+ RINOK(_archive.SkeepPrefixArchiveHeader());
+ _crc.Init();
+ continue;
+ }
+ UInt64 pureSize = COutArchive::GetVolPureSize(_volSize, _file.Name.Length());
+ UInt32 curSize = (UInt32)MyMin(UInt64(size), pureSize - _curPos);
+
+ _crc.Update(data, curSize);
+ UInt32 realProcessed;
+ RINOK(_volumeStream->Write(data, curSize, &realProcessed))
+ data = (void *)((Byte *)data + realProcessed);
+ size -= realProcessed;
+ if(processedSize != NULL)
+ *processedSize += realProcessed;
+ _curPos += realProcessed;
+ if (realProcessed != curSize && realProcessed == 0)
+ return E_FAIL;
+ if (_curPos == pureSize)
+ {
+ RINOK(Flush());
+ }
+ }
+ return S_OK;
+}
+
+#endif
+
+HRESULT Update(
+ IInStream *inStream,
+ const CArchiveDatabaseEx *database,
+ const CObjectVector<CUpdateItem> &updateItems,
+ ISequentialOutStream *seqOutStream,
+ IArchiveUpdateCallback *updateCallback,
+ const CUpdateOptions &options)
+{
+ #ifdef _7Z_VOL
+ if (seqOutStream)
+ #endif
+ return Update2(inStream, database, updateItems,
+ seqOutStream, updateCallback, options);
+ #ifdef _7Z_VOL
+ if (options.VolumeMode)
+ return UpdateVolume(inStream, database, updateItems,
+ seqOutStream, updateCallback, options);
+ COutVolumeStream *volStreamSpec = new COutVolumeStream;
+ CMyComPtr<ISequentialOutStream> volStream = volStreamSpec;
+ CMyComPtr<IArchiveUpdateCallback2> volumeCallback;
+ RINOK(updateCallback->QueryInterface(IID_IArchiveUpdateCallback2, (void **)&volumeCallback));
+ if (!volumeCallback)
+ return E_NOTIMPL;
+ volStreamSpec->Init(volumeCallback, L"a.7z");
+ volStreamSpec->_options = options;
+ RINOK(Update2(inStream, database, updateItems,
+ volStream, updateCallback, options));
+ return volStreamSpec->Flush();
+ #endif
+}
+
+}}
diff --git a/CPP/7zip/Archive/7z/7zUpdate.h b/CPP/7zip/Archive/7z/7zUpdate.h
new file mode 100755
index 00000000..385bd942
--- /dev/null
+++ b/CPP/7zip/Archive/7z/7zUpdate.h
@@ -0,0 +1,79 @@
+// 7zUpdate.h
+
+#ifndef __7Z_UPDATE_H
+#define __7Z_UPDATE_H
+
+#include "7zIn.h"
+#include "7zOut.h"
+#include "7zCompressionMode.h"
+
+#include "../IArchive.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CUpdateItem
+{
+ bool NewData;
+ bool NewProperties;
+ int IndexInArchive;
+ int IndexInClient;
+
+ UInt32 Attributes;
+ FILETIME CreationTime;
+ FILETIME LastWriteTime;
+ FILETIME LastAccessTime;
+
+ UInt64 Size;
+ UString Name;
+
+ bool IsAnti;
+ bool IsDirectory;
+
+ bool IsCreationTimeDefined;
+ bool IsLastWriteTimeDefined;
+ bool IsLastAccessTimeDefined;
+ bool AttributesAreDefined;
+
+ const bool HasStream() const
+ { return !IsDirectory && !IsAnti && Size != 0; }
+ CUpdateItem():
+ IsAnti(false),
+ AttributesAreDefined(false),
+ IsCreationTimeDefined(false),
+ IsLastWriteTimeDefined(false),
+ IsLastAccessTimeDefined(false)
+ {}
+ void SetDirectoryStatusFromAttributes()
+ { IsDirectory = ((Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); };
+
+ int GetExtensionPos() const;
+ UString GetExtension() const;
+};
+
+struct CUpdateOptions
+{
+ const CCompressionMethodMode *Method;
+ const CCompressionMethodMode *HeaderMethod;
+ bool UseFilters;
+ bool MaxFilter;
+
+ CHeaderOptions HeaderOptions;
+
+ UInt64 NumSolidFiles;
+ UInt64 NumSolidBytes;
+ bool SolidExtension;
+ bool RemoveSfxBlock;
+ bool VolumeMode;
+};
+
+HRESULT Update(
+ IInStream *inStream,
+ const CArchiveDatabaseEx *database,
+ const CObjectVector<CUpdateItem> &updateItems,
+ ISequentialOutStream *seqOutStream,
+ IArchiveUpdateCallback *updateCallback,
+ const CUpdateOptions &options);
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/7z/DllExports.cpp b/CPP/7zip/Archive/7z/DllExports.cpp
new file mode 100755
index 00000000..2d70d4de
--- /dev/null
+++ b/CPP/7zip/Archive/7z/DllExports.cpp
@@ -0,0 +1,113 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/MyInitGuid.h"
+#include "../../../Common/ComTry.h"
+#ifdef _WIN32
+#include "../../../Common/Alloc.h"
+#endif
+
+#include "../../ICoder.h"
+
+#include "7zHandler.h"
+
+#ifndef EXCLUDE_COM
+// {23170F69-40C1-278B-06F1-070100000100}
+DEFINE_GUID(CLSID_CCrypto7zAESEncoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x07, 0x01, 0x00, 0x00, 0x01, 0x00);
+#endif
+
+HINSTANCE g_hInstance;
+#ifndef _UNICODE
+bool g_IsNT = false;
+static bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+#endif
+
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ g_hInstance = hInstance;
+ #ifndef _UNICODE
+ g_IsNT = IsItWindowsNT();
+ #endif
+ #ifdef _WIN32
+ SetLargePageSize();
+ #endif
+ }
+ return TRUE;
+}
+
+
+STDAPI CreateObject(
+ const GUID *classID,
+ const GUID *interfaceID,
+ void **outObject)
+{
+ COM_TRY_BEGIN
+ *outObject = 0;
+ if (*classID != NArchive::N7z::CLSID_CFormat7z)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ if (*interfaceID == IID_IInArchive)
+ {
+ CMyComPtr<IInArchive> inArchive = new NArchive::N7z::CHandler;
+ *outObject = inArchive.Detach();
+ }
+ #ifndef EXTRACT_ONLY
+ else if (*interfaceID == IID_IOutArchive)
+ {
+ CMyComPtr<IOutArchive> outArchive = new NArchive::N7z::CHandler;
+ *outObject = outArchive.Detach();
+ }
+ #endif
+ else
+ return E_NOINTERFACE;
+ COM_TRY_END
+ return S_OK;
+}
+
+STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
+{
+ NWindows::NCOM::CPropVariant propVariant;
+ switch(propID)
+ {
+ case NArchive::kName:
+ propVariant = L"7z";
+ break;
+ case NArchive::kClassID:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&NArchive::N7z::CLSID_CFormat7z, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NArchive::kExtension:
+ propVariant = L"7z";
+ break;
+ case NArchive::kUpdate:
+ propVariant = true;
+ break;
+ case NArchive::kKeepName:
+ propVariant = false;
+ break;
+ case NArchive::kStartSignature:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen((const char *)NArchive::N7z::kSignature,
+ NArchive::N7z::kSignatureSize)) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/CPP/7zip/Archive/7z/StdAfx.cpp b/CPP/7zip/Archive/7z/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Archive/7z/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Archive/7z/StdAfx.h b/CPP/7zip/Archive/7z/StdAfx.h
new file mode 100755
index 00000000..2e4be10b
--- /dev/null
+++ b/CPP/7zip/Archive/7z/StdAfx.h
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/Archive/7z/makefile b/CPP/7zip/Archive/7z/makefile
new file mode 100755
index 00000000..06bf2f37
--- /dev/null
+++ b/CPP/7zip/Archive/7z/makefile
@@ -0,0 +1,89 @@
+PROG = 7z.dll
+DEF_FILE = ../Archive.def
+CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_MT
+LIBS = $(LIBS) oleaut32.lib user32.lib
+
+7Z_OBJS = \
+ $O\7zCompressionMode.obj \
+ $O\7zDecode.obj \
+ $O\7zEncode.obj \
+ $O\7zExtract.obj \
+ $O\7zFolderInStream.obj \
+ $O\7zFolderOutStream.obj \
+ $O\7zHandler.obj \
+ $O\7zHandlerOut.obj \
+ $O\7zHeader.obj \
+ $O\7zIn.obj \
+ $O\7zMethodID.obj \
+ $O\7zMethods.obj \
+ $O\7zOut.obj \
+ $O\7zProperties.obj \
+ $O\7zSpecStream.obj \
+ $O\7zUpdate.obj \
+ $O\DllExports.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\CRC.obj \
+ $O\IntToString.obj \
+ $O\NewHandler.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\Vector.obj \
+
+WIN_OBJS = \
+ $O\DLL.obj \
+ $O\FileDir.obj \
+ $O\FileFind.obj \
+ $O\FileIO.obj \
+ $O\PropVariant.obj \
+ $O\Synchronization.obj
+
+7ZIP_COMMON_OBJS = \
+ $O\InOutTempBuffer.obj \
+ $O\LimitedStreams.obj \
+ $O\LockedStream.obj \
+ $O\OutBuffer.obj \
+ $O\ProgressUtils.obj \
+ $O\StreamBinder.obj \
+ $O\StreamObjects.obj \
+ $O\StreamUtils.obj \
+
+AR_COMMON_OBJS = \
+ $O\CodecsPath.obj \
+ $O\CoderLoader.obj \
+ $O\CoderMixer2.obj \
+ $O\CoderMixer2MT.obj \
+ $O\CrossThreadProgress.obj \
+ $O\FilterCoder.obj \
+ $O\InStreamWithCRC.obj \
+ $O\ItemNameUtils.obj \
+ $O\MultiStream.obj \
+ $O\OutStreamWithCRC.obj \
+ $O\ParseProperties.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(7Z_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $O\CopyCoder.obj \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(7Z_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)
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/Archive/7z/resource.rc b/CPP/7zip/Archive/7z/resource.rc
new file mode 100755
index 00000000..8868173c
--- /dev/null
+++ b/CPP/7zip/Archive/7z/resource.rc
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("7z Plugin", "7z")
+
+101 ICON "7z.ico"
diff --git a/CPP/7zip/Archive/Archive.def b/CPP/7zip/Archive/Archive.def
new file mode 100755
index 00000000..befc7d83
--- /dev/null
+++ b/CPP/7zip/Archive/Archive.def
@@ -0,0 +1,3 @@
+EXPORTS
+ CreateObject PRIVATE
+ GetHandlerProperty PRIVATE
diff --git a/CPP/7zip/Archive/Arj/Arj.dsp b/CPP/7zip/Archive/Arj/Arj.dsp
new file mode 100755
index 00000000..3bc6fa91
--- /dev/null
+++ b/CPP/7zip/Archive/Arj/Arj.dsp
@@ -0,0 +1,329 @@
+# Microsoft Developer Studio Project File - Name="arj" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=arj - 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 "arj.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 "arj.mak" CFG="arj - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "arj - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "arj - 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)" == "arj - 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 "ARJ_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARJ_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\arj.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "arj - 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 "ARJ_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 "ARJ_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\arj.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "arj - Win32 Release"
+# Name "arj - 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
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\Alloc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Alloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.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\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 "Engine"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\ArjHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ArjHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ArjHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ArjIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ArjIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ArjItem.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Group "Codecs"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Arj\ArjDecoder1.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Arj\ArjDecoder1.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Arj\ArjDecoder2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Arj\ArjDecoder2.h
+# End Source File
+# End Group
+# 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 "Copy"
+
+# PROP Default_Filter ""
+# 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 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\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"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Common\ItemNameUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ItemNameUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\OutStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\OutStreamWithCRC.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\arj.ico
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/Archive/Arj/Arj.dsw b/CPP/7zip/Archive/Arj/Arj.dsw
new file mode 100755
index 00000000..7ce4bca5
--- /dev/null
+++ b/CPP/7zip/Archive/Arj/Arj.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "arj"=.\arj.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Archive/Arj/ArjHandler.cpp b/CPP/7zip/Archive/Arj/ArjHandler.cpp
new file mode 100755
index 00000000..a61cc775
--- /dev/null
+++ b/CPP/7zip/Archive/Arj/ArjHandler.cpp
@@ -0,0 +1,485 @@
+// ArjHandler.cpp
+
+#include "StdAfx.h"
+
+#include "Common/Defs.h"
+#include "Common/CRC.h"
+#include "Common/StringConvert.h"
+#include "Common/ComTry.h"
+
+#include "Windows/Time.h"
+#include "Windows/PropVariant.h"
+
+#include "ArjHandler.h"
+
+#include "../../ICoder.h"
+
+#include "../../Common/StreamObjects.h"
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/LimitedStreams.h"
+
+#include "../../Compress/Copy/CopyCoder.h"
+#include "../../Compress/Arj/ArjDecoder1.h"
+#include "../../Compress/Arj/ArjDecoder2.h"
+
+#include "../Common/ItemNameUtils.h"
+#include "../Common/OutStreamWithCRC.h"
+
+using namespace NWindows;
+using namespace NTime;
+
+namespace NArchive {
+namespace NArj{
+
+const wchar_t *kHostOS[] =
+{
+ L"MSDOS",
+ L"PRIMOS",
+ L"Unix",
+ L"AMIGA",
+ L"Mac",
+ L"OS/2",
+ L"APPLE GS",
+ L"Atari ST",
+ L"Next",
+ L"VAX VMS",
+ L"WIN95"
+};
+
+
+const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
+
+const wchar_t *kUnknownOS = L"Unknown";
+
+
+/*
+enum // PropID
+{
+ kpidHostOS = kpidUserDefined,
+ kpidUnPackVersion,
+ kpidMethod,
+};
+*/
+
+STATPROPSTG kProperties[] =
+{
+ { NULL, kpidPath, VT_BSTR},
+ { NULL, kpidIsFolder, VT_BOOL},
+ { NULL, kpidSize, VT_UI8},
+ { NULL, kpidPackedSize, VT_UI8},
+ { NULL, kpidLastWriteTime, VT_FILETIME},
+ { NULL, kpidAttributes, VT_UI4},
+
+ { NULL, kpidEncrypted, VT_BOOL},
+ // { NULL, kpidCommented, VT_BOOL},
+
+ { NULL, kpidCRC, VT_UI4},
+
+ { NULL, kpidMethod, VT_UI1},
+ { NULL, kpidHostOS, VT_BSTR}
+
+ // { L"UnPack Version", kpidUnPackVersion, VT_UI1},
+ // { L"Method", kpidMethod, VT_UI1},
+ // { L"Host OS", kpidHostOS, VT_BSTR}
+};
+
+
+CHandler::CHandler()
+{}
+
+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;
+ *name = 0;
+ 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_NOTIMPL;
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = _items.Size();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant propVariant;
+ const CItemEx &item = _items[index];
+ switch(propID)
+ {
+ case kpidPath:
+ propVariant =
+ NItemName::GetOSName(MultiByteToUnicodeString(item.Name, CP_OEMCP));
+ /*
+ NItemName::GetOSName2(
+ MultiByteToUnicodeString(item.Name, item.GetCodePage()));
+ */
+ break;
+ case kpidIsFolder:
+ propVariant = item.IsDirectory();
+ break;
+ case kpidSize:
+ propVariant = item.Size;
+ break;
+ case kpidPackedSize:
+ propVariant = item.PackSize;
+ break;
+ case kpidLastWriteTime:
+ {
+ FILETIME localFileTime, utcFileTime;
+ if (DosTimeToFileTime(item.ModifiedTime, localFileTime))
+ {
+ if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
+ utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
+ }
+ else
+ utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
+ propVariant = utcFileTime;
+ break;
+ }
+ case kpidAttributes:
+ propVariant = item.GetWinAttributes();
+ break;
+ case kpidEncrypted:
+ propVariant = item.IsEncrypted();
+ break;
+ /*
+ case kpidCommented:
+ propVariant = item.IsCommented();
+ break;
+ */
+ case kpidCRC:
+ propVariant = item.FileCRC;
+ break;
+ case kpidMethod:
+ propVariant = item.Method;
+ break;
+ case kpidHostOS:
+ propVariant = (item.HostOS < kNumHostOSes) ?
+ (kHostOS[item.HostOS]) : kUnknownOS;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+/*
+class CPropgressImp: public CProgressVirt
+{
+public:
+ CMyComPtr<IArchiveOpenCallback> Callback;
+ STDMETHOD(SetCompleted)(const UInt64 *numFiles);
+};
+
+STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles)
+{
+ if (Callback)
+ return Callback->SetCompleted(numFiles, NULL);
+ return S_OK;
+}
+*/
+
+STDMETHODIMP CHandler::Open(IInStream *inStream,
+ const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)
+{
+ COM_TRY_BEGIN
+ try
+ {
+ _items.Clear();
+ CInArchive archive;
+ if(!archive.Open(inStream, maxCheckStartPosition))
+ return S_FALSE;
+ if (callback != NULL)
+ {
+ RINOK(callback->SetTotal(NULL, NULL));
+ UInt64 numFiles = _items.Size();
+ RINOK(callback->SetCompleted(&numFiles, NULL));
+ }
+ for (;;)
+ {
+ CItemEx itemInfo;
+ bool filled;
+ HRESULT result = archive.GetNextItem(filled, itemInfo);
+ if (result == S_FALSE)
+ return S_FALSE;
+ if (result != S_OK)
+ return S_FALSE;
+ if (!filled)
+ break;
+ _items.Add(itemInfo);
+ archive.IncreaseRealPosition(itemInfo.PackSize);
+ if (callback != NULL)
+ {
+ UInt64 numFiles = _items.Size();
+ RINOK(callback->SetCompleted(&numFiles, NULL));
+ }
+ }
+ _stream = inStream;
+ }
+ catch(...)
+ {
+ return S_FALSE;
+ }
+ COM_TRY_END
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ _items.Clear();
+ _stream.Release();
+ return S_OK;
+}
+
+
+
+//////////////////////////////////////
+// CHandler::DecompressItems
+
+STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
+ Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ bool testMode = (testModeSpec != 0);
+ UInt64 totalUnPacked = 0, totalPacked = 0;
+ bool allFilesMode = (numItems == UInt32(-1));
+ if (allFilesMode)
+ numItems = _items.Size();
+ if(numItems == 0)
+ return S_OK;
+ UInt32 i;
+ for(i = 0; i < numItems; i++)
+ {
+ const CItemEx &itemInfo = _items[allFilesMode ? i : indices[i]];
+ totalUnPacked += itemInfo.Size;
+ totalPacked += itemInfo.PackSize;
+ }
+ extractCallback->SetTotal(totalUnPacked);
+
+ UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0;
+ UInt64 currentItemUnPacked, currentItemPacked;
+
+ CMyComPtr<ICompressCoder> arj1Decoder;
+ CMyComPtr<ICompressCoder> arj2Decoder;
+ CMyComPtr<ICompressCoder> copyCoder;
+
+ for(i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked,
+ currentTotalPacked += currentItemPacked)
+ {
+ currentItemUnPacked = 0;
+ currentItemPacked = 0;
+
+ RINOK(extractCallback->SetCompleted(&currentTotalUnPacked));
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ Int32 askMode;
+ askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
+ NArchive::NExtract::NAskMode::kExtract;
+ Int32 index = allFilesMode ? i : indices[i];
+ const CItemEx &itemInfo = _items[index];
+ RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
+
+ if(itemInfo.IsDirectory())
+ {
+ // if (!testMode)
+ {
+ RINOK(extractCallback->PrepareOperation(askMode));
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ }
+ continue;
+ }
+
+ if (!testMode && (!realOutStream))
+ continue;
+
+ RINOK(extractCallback->PrepareOperation(askMode));
+ currentItemUnPacked = itemInfo.Size;
+ currentItemPacked = itemInfo.PackSize;
+
+ {
+ COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
+ CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
+ outStreamSpec->SetStream(realOutStream);
+ outStreamSpec->Init();
+ realOutStream.Release();
+
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+ CMyComPtr<ISequentialInStream> inStream(streamSpec);
+
+ UInt64 pos;
+ _stream->Seek(itemInfo.DataPosition, STREAM_SEEK_SET, &pos);
+
+ streamSpec->SetStream(_stream);
+ streamSpec->Init(itemInfo.PackSize);
+
+
+ CLocalProgress *localProgressSpec = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
+ localProgressSpec->Init(extractCallback, false);
+
+
+ CLocalCompressProgressInfo *localCompressProgressSpec =
+ new CLocalCompressProgressInfo;
+ CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
+ localCompressProgressSpec->Init(progress,
+ &currentTotalPacked,
+ &currentTotalUnPacked);
+
+ if (itemInfo.IsEncrypted())
+ {
+ RINOK(extractCallback->SetOperationResult(
+ NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+ continue;
+ }
+
+ HRESULT result;
+
+ switch(itemInfo.Method)
+ {
+ case NFileHeader::NCompressionMethod::kStored:
+ {
+ if(!copyCoder)
+ copyCoder = new NCompress::CCopyCoder;
+ try
+ {
+ if (itemInfo.IsEncrypted())
+ {
+ RINOK(extractCallback->SetOperationResult(
+ NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+ continue;
+ }
+ else
+ {
+ result = copyCoder->Code(inStream, outStream,
+ NULL, NULL, compressProgress);
+ }
+ if (result == S_FALSE)
+ throw "data error";
+ if (result != S_OK)
+ return result;
+ }
+ catch(...)
+ {
+ outStream.Release();
+ RINOK(extractCallback->SetOperationResult(
+ NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ break;
+ }
+ case NFileHeader::NCompressionMethod::kCompressed1a:
+ case NFileHeader::NCompressionMethod::kCompressed1b:
+ case NFileHeader::NCompressionMethod::kCompressed1c:
+ {
+ if(!arj1Decoder)
+ {
+ arj1Decoder = new NCompress::NArj::NDecoder1::CCoder;
+ }
+ try
+ {
+ if (itemInfo.IsEncrypted())
+ {
+ RINOK(extractCallback->SetOperationResult(
+ NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+ continue;
+ }
+ else
+ {
+ result = arj1Decoder->Code(inStream, outStream,
+ NULL, &currentItemUnPacked, compressProgress);
+ }
+ if (result == S_FALSE)
+ throw "data error";
+ if (result != S_OK)
+ return result;
+ }
+ catch(...)
+ {
+ outStream.Release();
+ RINOK(extractCallback->SetOperationResult(
+ NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ break;
+ }
+ case NFileHeader::NCompressionMethod::kCompressed2:
+ {
+ if(!arj2Decoder)
+ {
+ arj2Decoder = new NCompress::NArj::NDecoder2::CCoder;
+ }
+ try
+ {
+ if (itemInfo.IsEncrypted())
+ {
+ RINOK(extractCallback->SetOperationResult(
+ NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+ continue;
+ }
+ else
+ {
+ result = arj2Decoder->Code(inStream, outStream,
+ NULL, &currentItemUnPacked, compressProgress);
+ }
+ if (result == S_FALSE)
+ throw "data error";
+ if (result != S_OK)
+ return result;
+ }
+ catch(...)
+ {
+ outStream.Release();
+ RINOK(extractCallback->SetOperationResult(
+ NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ break;
+ }
+ default:
+ RINOK(extractCallback->SetOperationResult(
+ NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+ continue;
+ }
+ bool crcOK = outStreamSpec->GetCRC() == itemInfo.FileCRC;
+ outStream.Release();
+ if(crcOK)
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK))
+ else
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError))
+ }
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+
+}}
diff --git a/CPP/7zip/Archive/Arj/ArjHandler.h b/CPP/7zip/Archive/Arj/ArjHandler.h
new file mode 100755
index 00000000..a1e69ba6
--- /dev/null
+++ b/CPP/7zip/Archive/Arj/ArjHandler.h
@@ -0,0 +1,47 @@
+// ArjHandler.h
+
+#ifndef __ARJ_HANDLER_H
+#define __ARJ_HANDLER_H
+
+#include "Common/MyCom.h"
+#include "../IArchive.h"
+#include "ArjIn.h"
+
+namespace NArchive {
+namespace NArj {
+
+class CHandler:
+ public IInArchive,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Open)(IInStream *inStream,
+ const UInt64 *maxCheckStartPosition,
+ IArchiveOpenCallback *callback);
+ STDMETHOD(Close)();
+ STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
+ STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
+ STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems,
+ Int32 testMode, IArchiveExtractCallback *anExtractCallback);
+
+ 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);
+
+ CHandler();
+private:
+ CObjectVector<CItemEx> _items;
+ CMyComPtr<IInStream> _stream;
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Arj/ArjHeader.h b/CPP/7zip/Archive/Arj/ArjHeader.h
new file mode 100755
index 00000000..58ee8c27
--- /dev/null
+++ b/CPP/7zip/Archive/Arj/ArjHeader.h
@@ -0,0 +1,121 @@
+// Archive/Arj/Header.h
+
+#ifndef __ARCHIVE_ARJ_HEADER_H
+#define __ARCHIVE_ARJ_HEADER_H
+
+#include "Common/Types.h"
+
+namespace NArchive {
+namespace NArj {
+
+const int kMaxBlockSize = 2600;
+
+namespace NSignature
+{
+ const Byte kSig0 = 0x60;
+ const Byte kSig1 = 0xEA;
+}
+
+/*
+struct CArchiveHeader
+{
+ // UInt16 BasicHeaderSize;
+ Byte FirstHeaderSize;
+ Byte Version;
+ Byte ExtractVersion;
+ Byte HostOS;
+ Byte Flags;
+ Byte SecuryVersion;
+ Byte FileType;
+ Byte Reserved;
+ UInt32 CreatedTime;
+ UInt32 ModifiedTime;
+ UInt32 ArchiveSize;
+ UInt32 SecurityEnvelopeFilePosition;
+ UInt16 FilespecPositionInFilename;
+ UInt16 LengthOfSecurityEnvelopeSata;
+ Byte EncryptionVersion;
+ Byte LastChapter;
+};
+*/
+
+namespace NFileHeader
+{
+ namespace NCompressionMethod
+ {
+ enum EType
+ {
+ kStored = 0,
+ kCompressed1a = 1,
+ kCompressed1b = 2,
+ kCompressed1c = 3,
+ kCompressed2 = 4,
+ kNoDataNoCRC = 8,
+ kNoData = 9,
+ };
+ }
+ namespace NFileType
+ {
+ enum EType
+ {
+ kBinary = 0,
+ k7BitText = 1,
+ kDirectory = 3,
+ kVolumeLablel = 4,
+ kChapterLabel = 5,
+ };
+ }
+ namespace NFlags
+ {
+ const Byte kGarbled = 1;
+ const Byte kVolume = 4;
+ const Byte kExtFile = 8;
+ const Byte kPathSym = 0x10;
+ const Byte kBackup= 0x20;
+ }
+
+ /*
+ struct CHeader
+ {
+ Byte FirstHeaderSize;
+ Byte Version;
+ Byte ExtractVersion;
+ Byte HostOS;
+ Byte Flags;
+ Byte Method;
+ Byte FileType;
+ Byte Reserved;
+ UInt32 ModifiedTime;
+ UInt32 PackSize;
+ UInt32 Size;
+ UInt32 FileCRC;
+ UInt16 FilespecPositionInFilename;
+ UInt16 FileAccessMode;
+ Byte FirstChapter;
+ Byte LastChapter;
+ };
+ */
+
+ namespace NHostOS
+ {
+ enum EEnum
+ {
+ kMSDOS = 0, // filesystem used by MS-DOS, OS/2, Win32
+ // pkarj 2.50 (FAT / VFAT / FAT32 file systems)
+ kPRIMOS = 1,
+ kUnix = 2, // VAX/VMS
+ kAMIGA = 3,
+ kMac = 4,
+ kOS_2 = 5, // what if it's a minix filesystem? [cjh]
+ kAPPLE_GS = 6, // filesystem used by OS/2 (and NT 3.x)
+ kAtari_ST = 7,
+ kNext = 8,
+ kVAX_VMS = 9,
+ kWIN95 = 10
+ };
+ }
+}
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Arj/ArjIn.cpp b/CPP/7zip/Archive/Arj/ArjIn.cpp
new file mode 100755
index 00000000..5d03ea65
--- /dev/null
+++ b/CPP/7zip/Archive/Arj/ArjIn.cpp
@@ -0,0 +1,283 @@
+// Archive/arj/InEngine.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StringConvert.h"
+#include "Common/Buffer.h"
+#include "Common/CRC.h"
+
+#include "../../Common/StreamUtils.h"
+
+#include "ArjIn.h"
+
+namespace NArchive {
+namespace NArj {
+
+HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize;
+ HRESULT result = ReadStream(_stream, data, size, &realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ IncreasePositionValue(realProcessedSize);
+ return result;
+}
+
+static inline UInt16 GetUInt16FromMemLE(const Byte *p)
+{
+ return (UInt16)(p[0] | (((UInt16)p[1]) << 8));
+}
+
+static inline UInt32 GetUInt32FromMemLE(const Byte *p)
+{
+ return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);
+}
+
+inline bool TestMarkerCandidate(const void *testBytes, UInt32 maxSize)
+{
+ if (maxSize < 2 + 2 + 4)
+ return false;
+ const Byte *block = ((const Byte *)(testBytes));
+ if (block[0] != NSignature::kSig0 || block[1] != NSignature::kSig1)
+ return false;
+ UInt32 blockSize = GetUInt16FromMemLE(block + 2);
+ if (maxSize < 2 + 2 + blockSize + 4)
+ return false;
+ block += 4;
+ if (blockSize == 0 || blockSize > 2600)
+ return false;
+ UInt32 crcFromFile = GetUInt32FromMemLE(block + blockSize);
+ return (CCRC::VerifyDigest(crcFromFile, block, blockSize));
+}
+
+bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit)
+{
+ // _archiveInfo.StartPosition = 0;
+ _position = _streamStartPosition;
+ if(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL) != S_OK)
+ return false;
+
+ const int kMarkerSizeMax = 2 + 2 + kMaxBlockSize + 4;
+
+ CByteBuffer byteBuffer;
+ static const UInt32 kSearchMarkerBufferSize = 0x10000;
+ byteBuffer.SetCapacity(kSearchMarkerBufferSize);
+ Byte *buffer = byteBuffer;
+
+ UInt32 processedSize;
+ ReadBytes(buffer, kMarkerSizeMax, &processedSize);
+ if (processedSize == 0)
+ return false;
+ if (TestMarkerCandidate(buffer, processedSize))
+ {
+ _position = _streamStartPosition;
+ if(_stream->Seek(_position, STREAM_SEEK_SET, NULL) != S_OK)
+ return false;
+ return true;
+ }
+
+ UInt32 numBytesPrev = processedSize - 1;
+ memmove(buffer, buffer + 1, numBytesPrev);
+ UInt64 curTestPos = _streamStartPosition + 1;
+ for (;;)
+ {
+ if (searchHeaderSizeLimit != NULL)
+ if (curTestPos - _streamStartPosition > *searchHeaderSizeLimit)
+ return false;
+ UInt32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev;
+ ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize);
+ UInt32 numBytesInBuffer = numBytesPrev + processedSize;
+ if (numBytesInBuffer < 1)
+ return false;
+ UInt32 numTests = numBytesInBuffer;
+ for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++)
+ {
+ if (TestMarkerCandidate(buffer + pos, numBytesInBuffer - pos))
+ {
+ // _archiveInfo.StartPosition = curTestPos;
+ _position = curTestPos;
+ if(_stream->Seek(_position, STREAM_SEEK_SET, NULL) != S_OK)
+ return false;
+ return true;
+ }
+ }
+ numBytesPrev = numBytesInBuffer - numTests;
+ memmove(buffer, buffer + numTests, numBytesPrev);
+ }
+}
+
+void CInArchive::IncreasePositionValue(UInt64 addValue)
+{
+ _position += addValue;
+}
+
+void CInArchive::IncreaseRealPosition(UInt64 addValue)
+{
+ if(_stream->Seek(addValue, STREAM_SEEK_CUR, &_position) != S_OK)
+ throw CInArchiveException(CInArchiveException::kSeekStreamError);
+}
+
+bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size)
+{
+ UInt32 realProcessedSize;
+ if(ReadBytes(data, size, &realProcessedSize) != S_OK)
+ throw CInArchiveException(CInArchiveException::kReadStreamError);
+ return (realProcessedSize == size);
+}
+
+void CInArchive::SafeReadBytes(void *data, UInt32 size)
+{
+ if(!ReadBytesAndTestSize(data, size))
+ throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
+}
+
+Byte CInArchive::SafeReadByte()
+{
+ Byte b;
+ SafeReadBytes(&b, 1);
+ return b;
+}
+
+UInt16 CInArchive::SafeReadUInt16()
+{
+ UInt16 value = 0;
+ for (int i = 0; i < 2; i++)
+ {
+ Byte b = SafeReadByte();
+ value |= (UInt16(b) << (8 * i));
+ }
+ return value;
+}
+
+UInt32 CInArchive::SafeReadUInt32()
+{
+ UInt32 value = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ Byte b = SafeReadByte();
+ value |= (UInt32(b) << (8 * i));
+ }
+ return value;
+}
+
+bool CInArchive::ReadBlock()
+{
+ _blockPos = 0;
+ _blockSize = SafeReadUInt16();
+ if (_blockSize == 0 || _blockSize > kMaxBlockSize)
+ return false;
+ SafeReadBytes(_block, _blockSize);
+ UInt32 crcFromFile = SafeReadUInt32();
+ if (!CCRC::VerifyDigest(crcFromFile, _block, _blockSize))
+ throw CInArchiveException(CInArchiveException::kCRCError);
+ return true;
+}
+
+bool CInArchive::ReadBlock2()
+{
+ Byte id[2];
+ ReadBytesAndTestSize(id, 2);
+ if (id[0] != NSignature::kSig0 || id[1] != NSignature::kSig1)
+ throw CInArchiveException(CInArchiveException::kIncorrectArchive);
+ return ReadBlock();
+}
+
+bool CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit)
+{
+ _stream = inStream;
+ if(_stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition) != S_OK)
+ return false;
+ _position = _streamStartPosition;
+ if (!FindAndReadMarker(searchHeaderSizeLimit))
+ return false;
+ if (!ReadBlock2())
+ return false;
+ for (;;)
+ if (!ReadBlock())
+ break;
+ return true;
+}
+
+void CInArchive::Close()
+{
+ _stream.Release();
+}
+
+void CInArchive::ThrowIncorrectArchiveException()
+{
+ throw CInArchiveException(CInArchiveException::kIncorrectArchive);
+}
+
+Byte CInArchive::ReadByte()
+{
+ if (_blockPos >= _blockSize)
+ ThrowIncorrectArchiveException();
+ return _block[_blockPos++];
+}
+
+UInt16 CInArchive::ReadUInt16()
+{
+ UInt16 value = 0;
+ for (int i = 0; i < 2; i++)
+ {
+ Byte b = ReadByte();
+ value |= (UInt16(b) << (8 * i));
+ }
+ return value;
+}
+
+UInt32 CInArchive::ReadUInt32()
+{
+ UInt32 value = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ Byte b = ReadByte();
+ value |= (UInt32(b) << (8 * i));
+ }
+ return value;
+}
+
+HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
+{
+ filled = false;
+ if (!ReadBlock2())
+ return S_OK;
+
+ Byte firstHeaderSize = ReadByte();
+ item.Version = ReadByte();
+ item.ExtractVersion = ReadByte();
+ item.HostOS = ReadByte();
+ item.Flags = ReadByte();
+ item.Method = ReadByte();
+ item.FileType = ReadByte();
+ ReadByte(); // Reserved
+ item.ModifiedTime = ReadUInt32();
+ item.PackSize = ReadUInt32();
+ item.Size = ReadUInt32();
+ item.FileCRC = ReadUInt32();
+ ReadUInt16(); // FilespecPositionInFilename
+ item.FileAccessMode = ReadUInt16();
+ ReadByte(); // FirstChapter
+ ReadByte(); // LastChapter
+
+ /*
+ UInt32 extraData;
+ if ((header.Flags & NFileHeader::NFlags::kExtFile) != 0)
+ extraData = GetUInt32FromMemLE(_block + pos);
+ */
+ _blockPos = firstHeaderSize;
+
+ for (; _blockPos < _blockSize;)
+ item.Name += (char)ReadByte();
+
+ for (;;)
+ if (!ReadBlock())
+ break;
+
+ item.DataPosition = _position;
+
+ filled = true;
+ return S_OK;
+}
+
+}}
diff --git a/CPP/7zip/Archive/Arj/ArjIn.h b/CPP/7zip/Archive/Arj/ArjIn.h
new file mode 100755
index 00000000..b73d7dba
--- /dev/null
+++ b/CPP/7zip/Archive/Arj/ArjIn.h
@@ -0,0 +1,75 @@
+// Archive/ArjIn.h
+
+#ifndef __ARCHIVE_ARJIN_H
+#define __ARCHIVE_ARJIN_H
+
+#include "Common/MyCom.h"
+#include "../../IStream.h"
+
+#include "ArjItem.h"
+
+namespace NArchive {
+namespace NArj {
+
+class CInArchiveException
+{
+public:
+ enum CCauseType
+ {
+ kUnexpectedEndOfArchive = 0,
+ kCRCError,
+ kIncorrectArchive,
+ kReadStreamError,
+ kSeekStreamError
+ }
+ Cause;
+ CInArchiveException(CCauseType cause): Cause(cause) {};
+};
+
+class CProgressVirt
+{
+public:
+ STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE;
+};
+
+class CInArchive
+{
+ CMyComPtr<IInStream> _stream;
+ UInt64 _streamStartPosition;
+ UInt64 _position;
+ UInt16 _blockSize;
+ Byte _block[kMaxBlockSize];
+ UInt32 _blockPos;
+
+
+ bool FindAndReadMarker(const UInt64 *searchHeaderSizeLimit);
+
+ bool ReadBlock();
+ bool ReadBlock2();
+
+ Byte ReadByte();
+ UInt16 ReadUInt16();
+ UInt32 ReadUInt32();
+
+ HRESULT ReadBytes(void *data, UInt32 size, UInt32 *processedSize);
+ bool ReadBytesAndTestSize(void *data, UInt32 size);
+ void SafeReadBytes(void *data, UInt32 size);
+ Byte SafeReadByte();
+ UInt16 SafeReadUInt16();
+ UInt32 SafeReadUInt32();
+
+ void IncreasePositionValue(UInt64 addValue);
+ void ThrowIncorrectArchiveException();
+
+public:
+ HRESULT GetNextItem(bool &filled, CItemEx &item);
+
+ bool Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit);
+ void Close();
+
+ void IncreaseRealPosition(UInt64 addValue);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Arj/ArjItem.h b/CPP/7zip/Archive/Arj/ArjItem.h
new file mode 100755
index 00000000..d48fe38d
--- /dev/null
+++ b/CPP/7zip/Archive/Arj/ArjItem.h
@@ -0,0 +1,75 @@
+// Archive/ArjItem.h
+
+#ifndef __ARCHIVE_ARJ_ITEM_H
+#define __ARCHIVE_ARJ_ITEM_H
+
+#include "Common/Types.h"
+#include "Common/String.h"
+#include "ArjHeader.h"
+
+namespace NArchive {
+namespace NArj {
+
+struct CVersion
+{
+ Byte Version;
+ Byte HostOS;
+};
+
+inline bool operator==(const CVersion &v1, const CVersion &v2)
+ { return (v1.Version == v2.Version) && (v1.HostOS == v2.HostOS); }
+inline bool operator!=(const CVersion &v1, const CVersion &v2)
+ { return !(v1 == v2); }
+
+class CItem
+{
+public:
+ Byte Version;
+ Byte ExtractVersion;
+ Byte HostOS;
+ Byte Flags;
+ Byte Method;
+ Byte FileType;
+ UInt32 ModifiedTime;
+ UInt32 PackSize;
+ UInt32 Size;
+ UInt32 FileCRC;
+
+ // UInt16 FilespecPositionInFilename;
+ UInt16 FileAccessMode;
+ // Byte FirstChapter;
+ // Byte LastChapter;
+
+ AString Name;
+
+ bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kGarbled) != 0; }
+ bool IsDirectory() const { return (FileType == NFileHeader::NFileType::kDirectory); }
+ UInt32 GetWinAttributes() const
+ {
+ UInt32 winAtrributes;
+ switch(HostOS)
+ {
+ case NFileHeader::NHostOS::kMSDOS:
+ case NFileHeader::NHostOS::kWIN95:
+ winAtrributes = FileAccessMode;
+ break;
+ default:
+ winAtrributes = 0;
+ }
+ if (IsDirectory())
+ winAtrributes |= FILE_ATTRIBUTE_DIRECTORY;
+ return winAtrributes;
+ }
+};
+
+class CItemEx: public CItem
+{
+public:
+ UInt64 DataPosition;
+};
+
+}}
+
+#endif
+
+
diff --git a/CPP/7zip/Archive/Arj/DllExports.cpp b/CPP/7zip/Archive/Arj/DllExports.cpp
new file mode 100755
index 00000000..d32ca2d6
--- /dev/null
+++ b/CPP/7zip/Archive/Arj/DllExports.cpp
@@ -0,0 +1,72 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+#include "../../ICoder.h"
+#include "ArjHandler.h"
+
+// {23170F69-40C1-278A-1000-000110040000}
+DEFINE_GUID(CLSID_CArjHandler,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x04, 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_CArjHandler)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ if (*interfaceID != IID_IInArchive)
+ return E_NOINTERFACE;
+ CMyComPtr<IInArchive> inArchive = (IInArchive *)new NArchive::NArj::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"Arj";
+ break;
+ case NArchive::kClassID:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CArjHandler, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NArchive::kExtension:
+ propVariant = L"arj";
+ break;
+ case NArchive::kUpdate:
+ propVariant = false;
+ break;
+ case NArchive::kKeepName:
+ propVariant = false;
+ break;
+ case NArchive::kStartSignature:
+ {
+ const unsigned char sig[] = { 0x60, 0xEA };
+ if ((value->bstrVal = ::SysAllocStringByteLen((const char *)sig, 2)) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/CPP/7zip/Archive/Arj/StdAfx.cpp b/CPP/7zip/Archive/Arj/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Archive/Arj/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Archive/Arj/StdAfx.h b/CPP/7zip/Archive/Arj/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Archive/Arj/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Archive/Arj/arj.ico b/CPP/7zip/Archive/Arj/arj.ico
new file mode 100755
index 00000000..c0f8b141
--- /dev/null
+++ b/CPP/7zip/Archive/Arj/arj.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Arj/makefile b/CPP/7zip/Archive/Arj/makefile
new file mode 100755
index 00000000..2609998b
--- /dev/null
+++ b/CPP/7zip/Archive/Arj/makefile
@@ -0,0 +1,66 @@
+PROG = arj.dll
+DEF_FILE = ../Archive.def
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib user32.lib
+
+ARJ_OBJS = \
+ $O\DllExports.obj \
+ $O\ArjHandler.obj \
+ $O\ArjIn.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\CRC.obj \
+ $O\NewHandler.obj \
+ $O\String.obj \
+ $O\StringConvert.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 \
+ $O\OutStreamWithCRC.obj \
+
+COMPRESS_ARJ_OBJS = \
+ $O\ArjDecoder1.obj \
+ $O\ArjDecoder2.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(ARJ_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $(COMPRESS_ARJ_OBJS) \
+ $O\CopyCoder.obj \
+ $O\LZOutWindow.obj \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(ARJ_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_ARJ_OBJS): ../../Compress/Arj/$(*B).cpp
+ $(COMPL)
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
+$O\LZOutWindow.obj: ../../Compress/LZ/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/Archive/Arj/resource.rc b/CPP/7zip/Archive/Arj/resource.rc
new file mode 100755
index 00000000..5158e405
--- /dev/null
+++ b/CPP/7zip/Archive/Arj/resource.rc
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("Arj Plugin", "arj")
+
+101 ICON "arj.ico"
diff --git a/CPP/7zip/Archive/BZip2/BZip2.dsp b/CPP/7zip/Archive/BZip2/BZip2.dsp
new file mode 100755
index 00000000..1d14aedb
--- /dev/null
+++ b/CPP/7zip/Archive/BZip2/BZip2.dsp
@@ -0,0 +1,281 @@
+# Microsoft Developer Studio Project File - Name="BZip2" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=BZip2 - 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 "BZip2.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 "BZip2.mak" CFG="BZip2 - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "BZip2 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "BZip2 - 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)" == "BZip2 - 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 "BZIP2_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /D "COMPRESS_MT" /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\bz2.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "BZip2 - 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 "BZIP2_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 "BZIP2_EXPORTS" /D "COMPRESS_MT" /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\bz2.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "BZip2 - Win32 Release"
+# Name "BZip2 - Win32 Debug"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Archive.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\BZip2.ico
+# 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 "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\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.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\StringToInt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringToInt.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# End Group
+# Begin Group "Compression"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.h
+# End Source File
+# End Group
+# Begin Group "Archive Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Common\CodecsPath.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CodecsPath.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CoderLoader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\DummyOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\DummyOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ParseProperties.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ParseProperties.h
+# End Source File
+# End Group
+# Begin Group "Engine"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\BZip2Handler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\BZip2Handler.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\BZip2HandlerOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\BZip2Item.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\BZip2Update.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\BZip2Update.h
+# End Source File
+# End Group
+# Begin Group "7zip common"
+
+# PROP Default_Filter ""
+# 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 Source File
+
+SOURCE=.\bz2.ico
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/Archive/BZip2/BZip2.dsw b/CPP/7zip/Archive/BZip2/BZip2.dsw
new file mode 100755
index 00000000..697e5095
--- /dev/null
+++ b/CPP/7zip/Archive/BZip2/BZip2.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "BZip2"=.\BZip2.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Archive/BZip2/BZip2Handler.cpp b/CPP/7zip/Archive/BZip2/BZip2Handler.cpp
new file mode 100755
index 00000000..169b2597
--- /dev/null
+++ b/CPP/7zip/Archive/BZip2/BZip2Handler.cpp
@@ -0,0 +1,287 @@
+// BZip2Handler.cpp
+
+#include "StdAfx.h"
+
+#include "BZip2Handler.h"
+
+#include "Common/Defs.h"
+
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/StreamUtils.h"
+
+#include "Windows/PropVariant.h"
+#include "Windows/Defs.h"
+#include "Common/ComTry.h"
+
+#include "../Common/DummyOutStream.h"
+
+#ifdef COMPRESS_BZIP2
+#include "../../Compress/BZip2/BZip2Decoder.h"
+#else
+// {23170F69-40C1-278B-0402-020000000000}
+DEFINE_GUID(CLSID_CCompressBZip2Decoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
+#include "../Common/CoderLoader.h"
+extern CSysString GetBZip2CodecPath();
+#endif
+
+using namespace NWindows;
+
+namespace NArchive {
+namespace NBZip2 {
+
+STATPROPSTG kProperties[] =
+{
+ { NULL, kpidPath, VT_BSTR},
+ // { NULL, kpidIsFolder, VT_BOOL},
+ // { NULL, kpidSize, VT_UI8},
+ { NULL, kpidPackedSize, VT_UI8},
+};
+
+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;
+ *name = 0;
+ 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::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = 1;
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant propVariant;
+ if (index != 0)
+ return E_INVALIDARG;
+ switch(propID)
+ {
+ case kpidIsFolder:
+ propVariant = false;
+ break;
+ case kpidPackedSize:
+ propVariant = _item.PackSize;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Open(IInStream *stream,
+ const UInt64 * /* maxCheckStartPosition */,
+ IArchiveOpenCallback * /* openArchiveCallback */)
+{
+ COM_TRY_BEGIN
+ try
+ {
+ RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition));
+ const int kSignatureSize = 3;
+ Byte buffer[kSignatureSize];
+ UInt32 processedSize;
+ RINOK(ReadStream(stream, buffer, kSignatureSize, &processedSize));
+ if (processedSize != kSignatureSize)
+ return S_FALSE;
+ if (buffer[0] != 'B' || buffer[1] != 'Z' || buffer[2] != 'h')
+ return S_FALSE;
+
+ UInt64 endPosition;
+ RINOK(stream->Seek(0, STREAM_SEEK_END, &endPosition));
+ _item.PackSize = endPosition - _streamStartPosition;
+
+ _stream = stream;
+ }
+ catch(...)
+ {
+ return S_FALSE;
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ _stream.Release();
+ return S_OK;
+}
+
+
+STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
+ Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ bool allFilesMode = (numItems == UInt32(-1));
+ if (!allFilesMode)
+ {
+ if (numItems == 0)
+ return S_OK;
+ if (numItems != 1)
+ return E_INVALIDARG;
+ if (indices[0] != 0)
+ return E_INVALIDARG;
+ }
+
+ bool testMode = (testModeSpec != 0);
+
+ extractCallback->SetTotal(_item.PackSize);
+
+ UInt64 currentTotalPacked = 0, currentTotalUnPacked = 0;
+
+ RINOK(extractCallback->SetCompleted(&currentTotalPacked));
+
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ Int32 askMode;
+ askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
+ NArchive::NExtract::NAskMode::kExtract;
+
+ RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
+
+ if(!testMode && !realOutStream)
+ return S_OK;
+
+
+ extractCallback->PrepareOperation(askMode);
+
+ #ifndef COMPRESS_BZIP2
+ CCoderLibrary lib;
+ #endif
+ CMyComPtr<ICompressCoder> decoder;
+ #ifdef COMPRESS_BZIP2
+ decoder = new NCompress::NBZip2::CDecoder;
+ #else
+ HRESULT loadResult = lib.LoadAndCreateCoder(
+ GetBZip2CodecPath(),
+ CLSID_CCompressBZip2Decoder, &decoder);
+ if (loadResult != S_OK)
+ {
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+ return S_OK;
+ }
+ #endif
+
+ #ifdef COMPRESS_MT
+ {
+ CMyComPtr<ICompressSetCoderMt> setCoderMt;
+ decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
+ if (setCoderMt)
+ {
+ RINOK(setCoderMt->SetNumberOfThreads(_numThreads));
+ }
+ }
+ #endif
+
+ CDummyOutStream *outStreamSpec = new CDummyOutStream;
+ CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
+ outStreamSpec->Init(realOutStream);
+
+ realOutStream.Release();
+
+ CLocalProgress *localProgressSpec = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
+ localProgressSpec->Init(extractCallback, true);
+
+ CLocalCompressProgressInfo *localCompressProgressSpec =
+ new CLocalCompressProgressInfo;
+ CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
+
+ RINOK(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL));
+
+
+ HRESULT result = S_OK;
+
+ bool firstItem = true;
+ for (;;)
+ {
+ localCompressProgressSpec->Init(progress,
+ &currentTotalPacked,
+ &currentTotalUnPacked);
+
+ const int kSignatureSize = 3;
+ Byte buffer[kSignatureSize];
+ UInt32 processedSize;
+ RINOK(ReadStream(_stream, buffer, kSignatureSize, &processedSize));
+ if (processedSize < kSignatureSize)
+ {
+ if (firstItem)
+ return E_FAIL;
+ break;
+ }
+ if (buffer[0] != 'B' || buffer[1] != 'Z' || buffer[2] != 'h')
+ {
+ if (firstItem)
+ return E_FAIL;
+ outStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK))
+ return S_OK;
+ }
+ firstItem = false;
+
+ UInt64 dataStartPos;
+ RINOK(_stream->Seek((UInt64)(Int64)(-3), STREAM_SEEK_CUR, &dataStartPos));
+
+ result = decoder->Code(_stream, outStream, NULL, NULL, compressProgress);
+
+ if (result != S_OK)
+ break;
+
+ CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize;
+ decoder.QueryInterface(IID_ICompressGetInStreamProcessedSize,
+ &getInStreamProcessedSize);
+ if (!getInStreamProcessedSize)
+ break;
+
+ UInt64 packSize;
+ RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&packSize));
+ UInt64 pos;
+ RINOK(_stream->Seek(dataStartPos + packSize, STREAM_SEEK_SET, &pos));
+ currentTotalPacked = pos - _streamStartPosition;
+ }
+ outStream.Release();
+
+ int retResult;
+ if (result == S_OK)
+ retResult = NArchive::NExtract::NOperationResult::kOK;
+ else if (result == S_FALSE)
+ retResult = NArchive::NExtract::NOperationResult::kDataError;
+ else
+ return result;
+
+ RINOK(extractCallback->SetOperationResult(retResult));
+
+ return S_OK;
+ COM_TRY_END
+}
+
+}}
diff --git a/CPP/7zip/Archive/BZip2/BZip2Handler.h b/CPP/7zip/Archive/BZip2/BZip2Handler.h
new file mode 100755
index 00000000..7977334e
--- /dev/null
+++ b/CPP/7zip/Archive/BZip2/BZip2Handler.h
@@ -0,0 +1,83 @@
+// BZip2/Handler.h
+
+#ifndef __BZIP2_HANDLER_H
+#define __BZIP2_HANDLER_H
+
+#include "Common/MyCom.h"
+#include "../IArchive.h"
+#include "BZip2Item.h"
+
+#ifdef COMPRESS_MT
+#include "../../../Windows/System.h"
+#endif
+
+namespace NArchive {
+namespace NBZip2 {
+
+class CHandler:
+ public IInArchive,
+ public IOutArchive,
+ public ISetProperties,
+ public CMyUnknownImp
+{
+ CMyComPtr<IInStream> _stream;
+ NArchive::NBZip2::CItem _item;
+ UInt64 _streamStartPosition;
+
+ UInt32 _level;
+ UInt32 _dicSize;
+ UInt32 _numPasses;
+ #ifdef COMPRESS_MT
+ UInt32 _numThreads;
+ #endif
+ void InitMethodProperties()
+ {
+ _level = 5;
+ _dicSize =
+ _numPasses = 0xFFFFFFFF;
+ #ifdef COMPRESS_MT
+ _numThreads = NWindows::NSystem::GetNumberOfProcessors();;
+ #endif
+ }
+
+public:
+ MY_UNKNOWN_IMP3(
+ IInArchive,
+ IOutArchive,
+ ISetProperties
+ )
+
+ 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);
+
+ // IOutArchiveHandler
+
+ STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems,
+ IArchiveUpdateCallback *updateCallback);
+ STDMETHOD(GetFileTimeType)(UInt32 *type);
+
+ // ISetProperties
+ STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
+
+ CHandler() { InitMethodProperties(); }
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/BZip2/BZip2HandlerOut.cpp b/CPP/7zip/Archive/BZip2/BZip2HandlerOut.cpp
new file mode 100755
index 00000000..b5fc72a9
--- /dev/null
+++ b/CPP/7zip/Archive/BZip2/BZip2HandlerOut.cpp
@@ -0,0 +1,156 @@
+// BZip2HandlerOut.cpp
+
+#include "StdAfx.h"
+
+#include "BZip2Handler.h"
+#include "BZip2Update.h"
+
+#include "Common/Defs.h"
+#include "Common/String.h"
+
+#include "Windows/PropVariant.h"
+
+#include "../../Compress/Copy/CopyCoder.h"
+
+#include "../Common/ParseProperties.h"
+
+using namespace NWindows;
+
+static const UInt32 kNumPassesX1 = 1;
+static const UInt32 kNumPassesX7 = 2;
+static const UInt32 kNumPassesX9 = 7;
+
+static const UInt32 kDicSizeX1 = 100000;
+static const UInt32 kDicSizeX3 = 500000;
+static const UInt32 kDicSizeX5 = 900000;
+
+namespace NArchive {
+namespace NBZip2 {
+
+STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
+{
+ *type = NFileTimeType::kUnix;
+ return S_OK;
+}
+
+static HRESULT CopyStreams(ISequentialInStream *inStream, ISequentialOutStream *outStream)
+{
+ CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
+ return copyCoder->Code(inStream, outStream, NULL, NULL, NULL);
+}
+
+STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
+ IArchiveUpdateCallback *updateCallback)
+{
+ if (numItems != 1)
+ return E_INVALIDARG;
+
+ Int32 newData;
+ Int32 newProperties;
+ UInt32 indexInArchive;
+ if (!updateCallback)
+ return E_FAIL;
+ RINOK(updateCallback->GetUpdateItemInfo(0,
+ &newData, &newProperties, &indexInArchive));
+
+ if (IntToBool(newProperties))
+ {
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(0, kpidIsFolder, &propVariant));
+ if (propVariant.vt == VT_BOOL)
+ {
+ if (propVariant.boolVal != VARIANT_FALSE)
+ return E_INVALIDARG;
+ }
+ else if (propVariant.vt != VT_EMPTY)
+ return E_INVALIDARG;
+ }
+ }
+
+ if (IntToBool(newData))
+ {
+ UInt64 size;
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(0, kpidSize, &propVariant));
+ if (propVariant.vt != VT_UI8)
+ return E_INVALIDARG;
+ size = propVariant.uhVal.QuadPart;
+ }
+
+ UInt32 dicSize = _dicSize;
+ if (dicSize == 0xFFFFFFFF)
+ dicSize = (_level >= 5 ? kDicSizeX5 :
+ (_level >= 3 ? kDicSizeX3 :
+ kDicSizeX1));
+
+ UInt32 numPasses = _numPasses;
+ if (numPasses == 0xFFFFFFFF)
+ numPasses = (_level >= 9 ? kNumPassesX9 :
+ (_level >= 7 ? kNumPassesX7 :
+ kNumPassesX1));
+
+ return UpdateArchive(size, outStream, 0, dicSize, numPasses,
+ #ifdef COMPRESS_MT
+ _numThreads,
+ #endif
+ updateCallback);
+ }
+ if (indexInArchive != 0)
+ return E_INVALIDARG;
+ RINOK(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL));
+ return CopyStreams(_stream, outStream);
+}
+
+STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
+{
+ InitMethodProperties();
+ #ifdef COMPRESS_MT
+ const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
+ _numThreads = numProcessors;
+ #endif
+
+ for (int i = 0; i < numProperties; i++)
+ {
+ UString name = UString(names[i]);
+ name.MakeUpper();
+ if (name.IsEmpty())
+ return E_INVALIDARG;
+
+ const PROPVARIANT &prop = values[i];
+
+ if (name[0] == 'X')
+ {
+ UInt32 level = 9;
+ RINOK(ParsePropValue(name.Mid(1), prop, level));
+ _level = level;
+ continue;
+ }
+ if (name[0] == 'D')
+ {
+ UInt32 dicSize = kDicSizeX5;
+ RINOK(ParsePropDictionaryValue(name.Mid(1), prop, dicSize));
+ _dicSize = dicSize;
+ continue;
+ }
+ if (name.Left(4) == L"PASS")
+ {
+ UInt32 num = kNumPassesX9;
+ RINOK(ParsePropValue(name.Mid(4), prop, num));
+ _numPasses = num;
+ continue;
+ }
+ if (name.Left(2) == L"MT")
+ {
+ #ifdef COMPRESS_MT
+ RINOK(ParseMtProp(name.Mid(2), prop, numProcessors, _numThreads));
+ #endif
+ continue;
+ }
+ return E_INVALIDARG;
+ }
+ return S_OK;
+}
+
+}}
diff --git a/CPP/7zip/Archive/BZip2/BZip2Item.h b/CPP/7zip/Archive/BZip2/BZip2Item.h
new file mode 100755
index 00000000..d7508ab9
--- /dev/null
+++ b/CPP/7zip/Archive/BZip2/BZip2Item.h
@@ -0,0 +1,20 @@
+// Archive/BZip2Item.h
+
+#ifndef __ARCHIVE_BZIP2_ITEM_H
+#define __ARCHIVE_BZIP2_ITEM_H
+
+namespace NArchive {
+namespace NBZip2 {
+
+struct CItem
+{
+ UInt64 PackSize;
+ UInt64 UnPackSize;
+};
+
+}}
+
+#endif
+
+
+
diff --git a/CPP/7zip/Archive/BZip2/BZip2Update.cpp b/CPP/7zip/Archive/BZip2/BZip2Update.cpp
new file mode 100755
index 00000000..d9bdf963
--- /dev/null
+++ b/CPP/7zip/Archive/BZip2/BZip2Update.cpp
@@ -0,0 +1,84 @@
+// BZip2Update.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/ProgressUtils.h"
+#include "Windows/PropVariant.h"
+
+#include "BZip2Update.h"
+
+#ifdef COMPRESS_BZIP2
+#include "../../Compress/BZip2/BZip2Encoder.h"
+#else
+// {23170F69-40C1-278B-0402-020000000100}
+DEFINE_GUID(CLSID_CCompressBZip2Encoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00);
+#include "../Common/CoderLoader.h"
+extern CSysString GetBZip2CodecPath();
+#endif
+
+namespace NArchive {
+namespace NBZip2 {
+
+HRESULT UpdateArchive(UInt64 unpackSize,
+ ISequentialOutStream *outStream,
+ int indexInClient,
+ UInt32 dictionary,
+ UInt32 numPasses,
+ #ifdef COMPRESS_MT
+ UInt32 numThreads,
+ #endif
+ IArchiveUpdateCallback *updateCallback)
+{
+ RINOK(updateCallback->SetTotal(unpackSize));
+ UInt64 complexity = 0;
+ RINOK(updateCallback->SetCompleted(&complexity));
+
+ CMyComPtr<ISequentialInStream> fileInStream;
+
+ RINOK(updateCallback->GetStream(indexInClient, &fileInStream));
+
+ CLocalProgress *localProgressSpec = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
+ localProgressSpec->Init(updateCallback, true);
+
+ #ifndef COMPRESS_BZIP2
+ CCoderLibrary lib;
+ #endif
+ CMyComPtr<ICompressCoder> encoder;
+ #ifdef COMPRESS_BZIP2
+ encoder = new NCompress::NBZip2::CEncoder;
+ #else
+ RINOK(lib.LoadAndCreateCoder(GetBZip2CodecPath(),
+ CLSID_CCompressBZip2Encoder, &encoder));
+ #endif
+
+ CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
+ encoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties);
+ if (setCoderProperties)
+ {
+ NWindows::NCOM::CPropVariant properties[] =
+ {
+ dictionary,
+ numPasses
+ #ifdef COMPRESS_MT
+ , numThreads
+ #endif
+ };
+ PROPID propIDs[] =
+ {
+ NCoderPropID::kDictionarySize,
+ NCoderPropID::kNumPasses
+ #ifdef COMPRESS_MT
+ , NCoderPropID::kNumThreads
+ #endif
+ };
+ RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, sizeof(propIDs) / sizeof(propIDs[0])));
+ }
+
+ RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, localProgress));
+
+ return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
+}
+
+}}
diff --git a/CPP/7zip/Archive/BZip2/BZip2Update.h b/CPP/7zip/Archive/BZip2/BZip2Update.h
new file mode 100755
index 00000000..ce20e323
--- /dev/null
+++ b/CPP/7zip/Archive/BZip2/BZip2Update.h
@@ -0,0 +1,24 @@
+// BZip2Update.h
+
+#ifndef __BZIP2_UPDATE_H
+#define __BZIP2_UPDATE_H
+
+#include "../IArchive.h"
+
+namespace NArchive {
+namespace NBZip2 {
+
+HRESULT UpdateArchive(
+ UInt64 unpackSize,
+ ISequentialOutStream *outStream,
+ int indexInClient,
+ UInt32 dictionary,
+ UInt32 numPasses,
+ #ifdef COMPRESS_MT
+ UInt32 numThreads,
+ #endif
+ IArchiveUpdateCallback *updateCallback);
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/BZip2/DllExports.cpp b/CPP/7zip/Archive/BZip2/DllExports.cpp
new file mode 100755
index 00000000..5a861318
--- /dev/null
+++ b/CPP/7zip/Archive/BZip2/DllExports.cpp
@@ -0,0 +1,127 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+#include "BZip2Handler.h"
+#include "../../ICoder.h"
+
+// {23170F69-40C1-278B-0402-020000000100}
+DEFINE_GUID(CLSID_CCompressBZip2Encoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00);
+
+// {23170F69-40C1-278B-0402-020000000000}
+DEFINE_GUID(CLSID_CCompressBZip2Decoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+// {23170F69-40C1-278A-1000-000110020000}
+DEFINE_GUID(CLSID_CBZip2Handler,
+0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x02, 0x00, 0x00);
+
+HINSTANCE g_hInstance;
+#ifndef _UNICODE
+bool g_IsNT = false;
+static bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+#endif
+
+#ifndef COMPRESS_BZIP2
+#include "../Common/CodecsPath.h"
+CSysString GetBZip2CodecPath()
+{
+ return GetCodecsFolderPrefix() + TEXT("BZip2.dll");
+}
+#endif
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ g_hInstance = hInstance;
+ #ifndef _UNICODE
+ g_IsNT = IsItWindowsNT();
+ #endif
+ }
+ return TRUE;
+}
+
+STDAPI CreateObject(
+ const GUID *classID,
+ const GUID *interfaceID,
+ void **outObject)
+{
+ COM_TRY_BEGIN
+ *outObject = 0;
+ if (*classID != CLSID_CBZip2Handler)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ int needIn = *interfaceID == IID_IInArchive;
+ int needOut = *interfaceID == IID_IOutArchive;
+ if (needIn || needOut)
+ {
+ NArchive::NBZip2::CHandler *temp = new NArchive::NBZip2::CHandler;
+ if (needIn)
+ {
+ CMyComPtr<IInArchive> inArchive = (IInArchive *)temp;
+ *outObject = inArchive.Detach();
+ }
+ else
+ {
+ CMyComPtr<IOutArchive> outArchive = (IOutArchive *)temp;
+ *outObject = outArchive.Detach();
+ }
+ }
+ else
+ return E_NOINTERFACE;
+ COM_TRY_END
+ return S_OK;
+}
+
+
+STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
+{
+ NWindows::NCOM::CPropVariant propVariant;
+ switch(propID)
+ {
+ case NArchive::kName:
+ propVariant = L"BZip2";
+ break;
+ case NArchive::kClassID:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CBZip2Handler, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NArchive::kExtension:
+ propVariant = L"bz2 bzip2 tbz2 tbz";
+ break;
+ case NArchive::kAddExtension:
+ propVariant = L"* * .tar .tar";
+ break;
+ case NArchive::kUpdate:
+ propVariant = true;
+ break;
+ case NArchive::kKeepName:
+ propVariant = true;
+ break;
+ case NArchive::kStartSignature:
+ {
+ const char sig[] = { 'B', 'Z', 'h' };
+ if ((value->bstrVal = ::SysAllocStringByteLen(sig, 3)) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/CPP/7zip/Archive/BZip2/StdAfx.cpp b/CPP/7zip/Archive/BZip2/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Archive/BZip2/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Archive/BZip2/StdAfx.h b/CPP/7zip/Archive/BZip2/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Archive/BZip2/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Archive/BZip2/bz2.ico b/CPP/7zip/Archive/BZip2/bz2.ico
new file mode 100755
index 00000000..614e3540
--- /dev/null
+++ b/CPP/7zip/Archive/BZip2/bz2.ico
Binary files differ
diff --git a/CPP/7zip/Archive/BZip2/makefile b/CPP/7zip/Archive/BZip2/makefile
new file mode 100755
index 00000000..20f20bdb
--- /dev/null
+++ b/CPP/7zip/Archive/BZip2/makefile
@@ -0,0 +1,55 @@
+PROG = bz2.dll
+DEF_FILE = ../Archive.def
+CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_MT
+LIBS = $(LIBS) oleaut32.lib user32.lib
+
+BZ2_OBJS = \
+ $O\BZip2Handler.obj \
+ $O\BZip2HandlerOut.obj \
+ $O\BZip2Update.obj \
+ $O\DllExports.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\NewHandler.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+
+WIN_OBJS = \
+ $O\DLL.obj \
+ $O\PropVariant.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\ProgressUtils.obj \
+ $O\StreamUtils.obj \
+
+AR_COMMON_OBJS = \
+ $O\CodecsPath.obj \
+ $O\DummyOutStream.obj \
+ $O\ParseProperties.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(BZ2_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $O\CopyCoder.obj \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(BZ2_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)
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/Archive/BZip2/resource.rc b/CPP/7zip/Archive/BZip2/resource.rc
new file mode 100755
index 00000000..2d4f27e3
--- /dev/null
+++ b/CPP/7zip/Archive/BZip2/resource.rc
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("BZip2 Plugin", "bz2")
+
+101 ICON "bz2.ico"
diff --git a/CPP/7zip/Archive/Cab/Cab.dsp b/CPP/7zip/Archive/Cab/Cab.dsp
new file mode 100755
index 00000000..565661f6
--- /dev/null
+++ b/CPP/7zip/Archive/Cab/Cab.dsp
@@ -0,0 +1,395 @@
+# Microsoft Developer Studio Project File - Name="Cab" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=Cab - 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 "Cab.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 "Cab.mak" CFG="Cab - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Cab - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Cab - 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)" == "Cab - 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 "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" /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"
+# 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\cab.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Cab - 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 "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" /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"
+# 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\cab.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "Cab - Win32 Release"
+# Name "Cab - 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
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\Alloc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Alloc.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\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.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 "Engine"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\CabBlockInStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CabBlockInStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CabHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CabHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CabHeader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CabHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CabIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CabIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CabItem.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\LSBFDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFDecoder.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 "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)" == "Cab - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Cab - 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)" == "Cab - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Cab - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Lzx\LzxDecoder.h
+# End Source File
+# End Group
+# Begin Group "Deflate"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Deflate\DeflateConst.h
+# End Source File
+# Begin Source File
+
+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=..\..\Compress\Deflate\DeflateDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Deflate\DeflateExtConst.h
+# End Source File
+# End Group
+# Begin Group "Copy"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.h
+# End Source File
+# End Group
+# Begin Group "Quantum"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Quantum\QuantumDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Quantum\QuantumDecoder.h
+# End Source File
+# End Group
+# Begin Group "Huffman"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Huffman\HuffmanDecoder.h
+# End Source File
+# End Group
+# End Group
+# Begin Source File
+
+SOURCE=.\cab.ico
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/Archive/Cab/Cab.dsw b/CPP/7zip/Archive/Cab/Cab.dsw
new file mode 100755
index 00000000..470cb1b3
--- /dev/null
+++ b/CPP/7zip/Archive/Cab/Cab.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Cab"=.\Cab.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Archive/Cab/CabBlockInStream.cpp b/CPP/7zip/Archive/Cab/CabBlockInStream.cpp
new file mode 100755
index 00000000..b775c105
--- /dev/null
+++ b/CPP/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/CPP/7zip/Archive/Cab/CabBlockInStream.h b/CPP/7zip/Archive/Cab/CabBlockInStream.h
new file mode 100755
index 00000000..46e15222
--- /dev/null
+++ b/CPP/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/CPP/7zip/Archive/Cab/CabHandler.cpp b/CPP/7zip/Archive/Cab/CabHandler.cpp
new file mode 100755
index 00000000..cac79b11
--- /dev/null
+++ b/CPP/7zip/Archive/Cab/CabHandler.cpp
@@ -0,0 +1,812 @@
+// 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"
+
+#include "Windows/PropVariant.h"
+#include "Windows/Time.h"
+
+#include "CabHandler.h"
+#include "CabBlockInStream.h"
+
+#include "../../Compress/Copy/CopyCoder.h"
+#include "../../Compress/Deflate/DeflateDecoder.h"
+#include "../../Compress/Lzx/LzxDecoder.h"
+#include "../../Compress/Quantum/QuantumDecoder.h"
+
+#include "../Common/ItemNameUtils.h"
+
+using namespace NWindows;
+
+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, kpidSize, VT_UI8},
+ { NULL, kpidLastWriteTime, VT_FILETIME},
+ { NULL, kpidAttributes, VT_UI4},
+ { NULL, kpidMethod, VT_BSTR},
+ { 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]);
+
+static const wchar_t *kMethods[] =
+{
+ L"None",
+ L"MSZip",
+ L"Quantum",
+ L"LZX"
+};
+
+static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]);
+static const wchar_t *kUnknownMethod = L"Unknown";
+
+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;
+
+ 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:
+ {
+ UString unicodeName;
+ if (item.IsNameUTF())
+ ConvertUTF8ToUnicode(item.Name, unicodeName);
+ else
+ unicodeName = MultiByteToUnicodeString(item.Name, CP_ACP);
+ propVariant = (const wchar_t *)NItemName::WinNameToOSName(unicodeName);
+ break;
+ }
+ case kpidIsFolder:
+ propVariant = item.IsDirectory();
+ break;
+ case kpidSize:
+ propVariant = item.Size;
+ break;
+ case kpidLastWriteTime:
+ {
+ FILETIME localFileTime, utcFileTime;
+ if (NTime::DosTimeToFileTime(item.Time, localFileTime))
+ {
+ if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
+ utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
+ }
+ else
+ utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
+ propVariant = utcFileTime;
+ break;
+ }
+ case kpidAttributes:
+ propVariant = item.GetWinAttributes();
+ break;
+
+ case kpidMethod:
+ {
+ UInt32 realFolderIndex = item.GetFolderIndex(db.Folders.Size());
+ const CFolder &folder = db.Folders[realFolderIndex];
+ int methodIndex = folder.GetCompressionMethod();
+ UString method = (methodIndex < kNumMethods) ? kMethods[methodIndex] : kUnknownMethod;
+ if (methodIndex == NHeader::NCompressionMethodMajor::kLZX ||
+ methodIndex == NHeader::NCompressionMethodMajor::kQuantum)
+ {
+ method += L":";
+ wchar_t temp[32];
+ ConvertUInt64ToString(folder.CompressionTypeMinor, temp);
+ method += temp;
+ }
+ propVariant = method;
+ break;
+ }
+ case kpidBlock:
+ 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;
+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
+ Close();
+ HRESULT res = S_FALSE;
+ CInArchive archive;
+ CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
+ {
+ 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;
+ for (;;)
+ {
+ 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(...)
+ {
+ res = S_FALSE;
+ }
+ if (res != S_OK)
+ {
+ Close();
+ return res;
+ }
+ COM_TRY_END
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ m_Database.Clear();
+ return S_OK;
+}
+
+class CCabFolderOutStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+private:
+ const CMvDatabaseEx *m_Database;
+ const CRecordVector<bool> *m_ExtractStatuses;
+ int m_StartIndex;
+ int m_CurrentIndex;
+ CMyComPtr<IArchiveExtractCallback> m_ExtractCallback;
+ bool m_TestMode;
+
+ CMyComPtr<ISequentialOutStream> m_RealOutStream;
+
+ bool m_IsOk;
+ bool m_FileIsOpen;
+ UInt64 m_RemainFileSize;
+ UInt64 m_FolderSize;
+ UInt64 m_PosInFolder;
+
+ HRESULT OpenFile();
+ HRESULT Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK);
+public:
+ HRESULT WriteEmptyFiles();
+
+ void Init(
+ const CMvDatabaseEx *database,
+ const CRecordVector<bool> *extractStatuses,
+ int startIndex,
+ UInt64 folderSize,
+ IArchiveExtractCallback *extractCallback,
+ bool testMode);
+ HRESULT FlushCorrupted();
+ HRESULT Unsupported();
+
+ UInt64 GetRemain() const { return m_FolderSize - m_PosInFolder; }
+ UInt64 GetPosInFolder() const { return m_PosInFolder; }
+};
+
+void CCabFolderOutStream::Init(
+ const CMvDatabaseEx *database,
+ const CRecordVector<bool> *extractStatuses,
+ int startIndex,
+ UInt64 folderSize,
+ IArchiveExtractCallback *extractCallback,
+ bool testMode)
+{
+ m_Database = database;
+ m_ExtractStatuses = extractStatuses;
+ m_StartIndex = startIndex;
+ m_FolderSize = folderSize;
+
+ m_ExtractCallback = extractCallback;
+ m_TestMode = testMode;
+
+ m_CurrentIndex = 0;
+ m_PosInFolder = 0;
+ m_FileIsOpen = false;
+ m_IsOk = true;
+}
+
+HRESULT CCabFolderOutStream::OpenFile()
+{
+ 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;
+ return m_ExtractCallback->PrepareOperation(askMode);
+}
+
+HRESULT CCabFolderOutStream::WriteEmptyFiles()
+{
+ if (m_FileIsOpen)
+ return S_OK;
+ for(;m_CurrentIndex < m_ExtractStatuses->Size(); m_CurrentIndex++)
+ {
+ const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex];
+ const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
+ UInt64 fileSize = item.Size;
+ if (fileSize != 0)
+ return S_OK;
+ HRESULT result = OpenFile();
+ m_RealOutStream.Release();
+ RINOK(result);
+ RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ }
+ return S_OK;
+}
+
+// This is Write function
+HRESULT CCabFolderOutStream::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_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_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;
+ }
+ }
+ }
+ return WriteEmptyFiles();
+}
+
+STDMETHODIMP CCabFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ return Write2(data, size, processedSize, true);
+}
+
+HRESULT CCabFolderOutStream::FlushCorrupted()
+{
+ const UInt32 kBufferSize = (1 << 10);
+ Byte buffer[kBufferSize];
+ for (int i = 0; i < kBufferSize; i++)
+ buffer[i] = 0;
+ for (;;)
+ {
+ 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));
+ }
+}
+
+HRESULT CCabFolderOutStream::Unsupported()
+{
+ while(m_CurrentIndex < m_ExtractStatuses->Size())
+ {
+ HRESULT result = OpenFile();
+ if (result != S_FALSE && result != S_OK)
+ return result;
+ m_RealOutStream.Release();
+ RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+ m_CurrentIndex++;
+ }
+ 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.Items.Size();
+ if(numItems == 0)
+ return S_OK;
+ bool testMode = (_aTestMode != 0);
+ UInt64 totalUnPacked = 0;
+
+ UInt32 i;
+ int lastFolder = -2;
+ UInt64 lastFolderSize = 0;
+ for(i = 0; i < numItems; i++)
+ {
+ int index = allFilesMode ? i : indices[i];
+ const CMvItem &mvItem = m_Database.Items[index];
+ const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
+ if (item.IsDirectory())
+ continue;
+ int folderIndex = m_Database.GetFolderIndex(&mvItem);
+ if (folderIndex != lastFolder)
+ totalUnPacked += lastFolderSize;
+ lastFolder = folderIndex;
+ lastFolderSize = item.GetEndOffset();
+ }
+ totalUnPacked += lastFolderSize;
+
+ extractCallback->SetTotal(totalUnPacked);
+
+ totalUnPacked = 0;
+
+ NCompress::CCopyCoder *copyCoderSpec = NULL;
+ CMyComPtr<ICompressCoder> copyCoder;
+
+ NCompress::NDeflate::NDecoder::CCOMCoder *deflateDecoderSpec = NULL;
+ CMyComPtr<ICompressCoder> deflateDecoder;
+
+ NCompress::NLzx::CDecoder *lzxDecoderSpec = NULL;
+ CMyComPtr<ICompressCoder> lzxDecoder;
+
+ NCompress::NQuantum::CDecoder *quantumDecoderSpec = NULL;
+ CMyComPtr<ICompressCoder> quantumDecoder;
+
+ CCabBlockInStream *cabBlockInStreamSpec = new CCabBlockInStream();
+ CMyComPtr<ISequentialInStream> cabBlockInStream = cabBlockInStreamSpec;
+ if (!cabBlockInStreamSpec->Create())
+ return E_OUTOFMEMORY;
+
+ CRecordVector<bool> extractStatuses;
+ for(i = 0; i < numItems;)
+ {
+ 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())
+ {
+ 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;
+ for (; startIndex < indexNext; startIndex++)
+ extractStatuses.Add(false);
+ extractStatuses.Add(true);
+ startIndex++;
+ curUnpack = item.GetEndOffset();
+ }
+
+ RINOK(extractCallback->SetCompleted(&totalUnPacked));
+
+ CCabFolderOutStream *cabFolderOutStream = new CCabFolderOutStream;
+ CMyComPtr<ISequentialOutStream> outStream(cabFolderOutStream);
+
+ const CFolder &folder = db.Folders[item.GetFolderIndex(db.Folders.Size())];
+
+ cabFolderOutStream->Init(&m_Database, &extractStatuses, startIndex2,
+ curUnpack, extractCallback, testMode);
+
+ cabBlockInStreamSpec->MsZip = false;
+ switch(folder.GetCompressionMethod())
+ {
+ case NHeader::NCompressionMethodMajor::kNone:
+ if(copyCoderSpec == NULL)
+ {
+ copyCoderSpec = new NCompress::CCopyCoder;
+ copyCoder = copyCoderSpec;
+ }
+ break;
+ case NHeader::NCompressionMethodMajor::kMSZip:
+ if(deflateDecoderSpec == NULL)
+ {
+ deflateDecoderSpec = new NCompress::NDeflate::NDecoder::CCOMCoder;
+ deflateDecoder = deflateDecoderSpec;
+ }
+ cabBlockInStreamSpec->MsZip = true;
+ break;
+ case NHeader::NCompressionMethodMajor::kLZX:
+ if(lzxDecoderSpec == NULL)
+ {
+ lzxDecoderSpec = new NCompress::NLzx::CDecoder;
+ lzxDecoder = lzxDecoderSpec;
+ }
+ RINOK(lzxDecoderSpec->SetParams(folder.CompressionTypeMinor));
+ break;
+ case NHeader::NCompressionMethodMajor::kQuantum:
+ if(quantumDecoderSpec == NULL)
+ {
+ quantumDecoderSpec = new NCompress::NQuantum::CDecoder;
+ quantumDecoder = quantumDecoderSpec;
+ }
+ quantumDecoderSpec->SetParams(folder.CompressionTypeMinor);
+ break;
+ default:
+ {
+ RINOK(cabFolderOutStream->Unsupported());
+ totalUnPacked += curUnpack;
+ continue;
+ }
+ }
+
+ 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 (volIndex >= m_Database.Volumes.Size())
+ {
+ res = S_FALSE;
+ break;
+ }
+
+ const CDatabaseEx &db = m_Database.Volumes[volIndex];
+ const CFolder &folder = db.Folders[locFolderIndex];
+ if (f == 0)
+ {
+ cabBlockInStreamSpec->SetStream(db.Stream);
+ cabBlockInStreamSpec->ReservedSize = db.ArchiveInfo.GetDataBlockReserveSize();
+ RINOK(db.Stream->Seek(db.StartPosition + folder.DataStart, STREAM_SEEK_SET, NULL));
+ }
+ if (f == folder.NumDataBlocks)
+ {
+ volIndex++;
+ locFolderIndex = 0;
+ f = 0;
+ continue;
+ }
+ 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());
+ }
+ }
+ if (res != S_OK || cabFolderOutStream->GetRemain() != 0)
+ {
+ RINOK(cabFolderOutStream->FlushCorrupted());
+ }
+ totalUnPacked += curUnpack;
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = m_Database.Items.Size();
+ return S_OK;
+}
+
+}}
diff --git a/CPP/7zip/Archive/Cab/CabHandler.h b/CPP/7zip/Archive/Cab/CabHandler.h
new file mode 100755
index 00000000..245586b6
--- /dev/null
+++ b/CPP/7zip/Archive/Cab/CabHandler.h
@@ -0,0 +1,45 @@
+// CabHandler.h
+
+#ifndef __CAB_HANDLER_H
+#define __CAB_HANDLER_H
+
+#include "Common/MyCom.h"
+#include "../IArchive.h"
+#include "CabIn.h"
+
+namespace NArchive {
+namespace NCab {
+
+class CHandler:
+ public IInArchive,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_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:
+ CMvDatabaseEx m_Database;
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Cab/CabHeader.cpp b/CPP/7zip/Archive/Cab/CabHeader.cpp
new file mode 100755
index 00000000..37533dff
--- /dev/null
+++ b/CPP/7zip/Archive/Cab/CabHeader.cpp
@@ -0,0 +1,19 @@
+// Archive/Cab/Header.h
+
+#include "StdAfx.h"
+
+#include "CabHeader.h"
+
+namespace NArchive{
+namespace NCab{
+namespace NHeader{
+
+namespace NArchive {
+
+UInt32 kSignature = 0x4643534d + 1;
+static class CSignatureInitializer
+{ public: CSignatureInitializer() { kSignature--; }} g_SignatureInitializer;
+
+}
+
+}}}
diff --git a/CPP/7zip/Archive/Cab/CabHeader.h b/CPP/7zip/Archive/Cab/CabHeader.h
new file mode 100755
index 00000000..5c122743
--- /dev/null
+++ b/CPP/7zip/Archive/Cab/CabHeader.h
@@ -0,0 +1,42 @@
+// Archive/Cab/Header.h
+
+#ifndef __ARCHIVE_CAB_HEADER_H
+#define __ARCHIVE_CAB_HEADER_H
+
+#include "Common/Types.h"
+
+namespace NArchive {
+namespace NCab {
+namespace NHeader{
+
+namespace NArchive
+{
+ extern UInt32 kSignature;
+ namespace NFlags
+ {
+ const int kPrevCabinet = 0x0001;
+ const int kNextCabinet = 0x0002;
+ const int kReservePresent = 0x0004;
+ }
+}
+
+namespace NCompressionMethodMajor
+{
+ const Byte kNone = 0;
+ const Byte kMSZip = 1;
+ const Byte kQuantum = 2;
+ const Byte kLZX = 3;
+}
+
+const int kFileNameIsUTFAttributeMask = 0x80;
+
+namespace NFolderIndex
+{
+ const int kContinuedFromPrev = 0xFFFD;
+ const int kContinuedToNext = 0xFFFE;
+ const int kContinuedPrevAndNext = 0xFFFF;
+}
+
+}}}
+
+#endif
diff --git a/CPP/7zip/Archive/Cab/CabIn.cpp b/CPP/7zip/Archive/Cab/CabIn.cpp
new file mode 100755
index 00000000..ae774f19
--- /dev/null
+++ b/CPP/7zip/Archive/Cab/CabIn.cpp
@@ -0,0 +1,343 @@
+// Archive/CabIn.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StringConvert.h"
+#include "Common/MyCom.h"
+#include "CabIn.h"
+#include "Windows/Defs.h"
+
+#include "../../Common/StreamUtils.h"
+
+namespace NArchive{
+namespace NCab{
+
+/*
+static HRESULT ReadBytes(IInStream *inStream, void *data, UInt32 size)
+{
+ UInt32 realProcessedSize;
+ RINOK(ReadStream(inStream, data, size, &realProcessedSize));
+ if(realProcessedSize != size)
+ return S_FALSE;
+ return S_OK;
+}
+
+static HRESULT SafeRead(IInStream *inStream, void *data, UInt32 size)
+{
+ UInt32 realProcessedSize;
+ RINOK(ReadStream(inStream, data, size, &realProcessedSize));
+ if(realProcessedSize != size)
+ throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
+ return S_OK;
+}
+
+static void SafeInByteRead(::CInBuffer &inBuffer, void *data, UInt32 size)
+{
+ UInt32 realProcessedSize;
+ inBuffer.ReadBytes(data, size, realProcessedSize);
+ if(realProcessedSize != size)
+ throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
+}
+*/
+
+Byte CInArchive::ReadByte()
+{
+ Byte b;
+ if (!inBuffer.ReadByte(b))
+ throw CInArchiveException(CInArchiveException::kUnsupported);
+ return b;
+}
+
+UInt16 CInArchive::ReadUInt16()
+{
+ UInt16 value = 0;
+ for (int i = 0; i < 2; i++)
+ {
+ Byte b = ReadByte();
+ value |= (UInt16(b) << (8 * i));
+ }
+ return value;
+}
+
+UInt32 CInArchive::ReadUInt32()
+{
+ UInt32 value = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ Byte b = ReadByte();
+ value |= (UInt32(b) << (8 * i));
+ }
+ return value;
+}
+
+AString CInArchive::SafeReadName()
+{
+ AString name;
+ for (;;)
+ {
+ Byte b = ReadByte();
+ if (b == 0)
+ return name;
+ name += (char)b;
+ }
+}
+
+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));
+
+ {
+ if (!inBuffer.Create(1 << 17))
+ return E_OUTOFMEMORY;
+ inBuffer.SetStream(inStream);
+ inBuffer.Init();
+ UInt64 value = 0;
+ const int kSignatureSize = 8;
+ UInt64 kSignature64 = NHeader::NArchive::kSignature;
+ for (;;)
+ {
+ Byte b;
+ if (!inBuffer.ReadByte(b))
+ return S_FALSE;
+ value >>= 8;
+ value |= ((UInt64)b) << ((kSignatureSize - 1) * 8);
+ if (inBuffer.GetProcessedSize() >= kSignatureSize)
+ {
+ if (value == kSignature64)
+ break;
+ if (searchHeaderSizeLimit != NULL)
+ if (inBuffer.GetProcessedSize() > (*searchHeaderSizeLimit))
+ return S_FALSE;
+ }
+ }
+ database.StartPosition += inBuffer.GetProcessedSize() - kSignatureSize;
+ }
+
+ 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())
+ {
+ 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);
+ }
+
+ {
+ if (archiveInfo.IsTherePrev())
+ ReadOtherArchive(archiveInfo.PreviousArchive);
+ if (archiveInfo.IsThereNext())
+ ReadOtherArchive(archiveInfo.NextArchive);
+ }
+
+ int i;
+ for(i = 0; i < archiveInfo.NumFolders; i++)
+ {
+ CFolder folder;
+
+ folder.DataStart = ReadUInt32();
+ folder.NumDataBlocks = ReadUInt16();
+ folder.CompressionTypeMajor = ReadByte();
+ folder.CompressionTypeMinor = ReadByte();
+
+ Skeep(archiveInfo.PerFolderAreaSize);
+ database.Folders.Add(folder);
+ }
+
+ RINOK(inStream->Seek(database.StartPosition + archiveInfo.FileHeadersOffset, STREAM_SEEK_SET, NULL));
+
+ inBuffer.SetStream(inStream);
+ inBuffer.Init();
+ for(i = 0; i < archiveInfo.NumFiles; i++)
+ {
+ CItem item;
+ item.Size = ReadUInt32();
+ item.Offset = ReadUInt32();
+ item.FolderIndex = ReadUInt16();
+ UInt16 pureDate = ReadUInt16();
+ UInt16 pureTime = ReadUInt16();
+ item.Time = ((UInt32(pureDate) << 16)) | pureTime;
+ item.Attributes = ReadUInt16();
+ 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++)
+ {
+ mvItem.ItemIndex = i;
+ Items.Add(mvItem);
+ }
+ }
+
+ 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/CPP/7zip/Archive/Cab/CabIn.h b/CPP/7zip/Archive/Cab/CabIn.h
new file mode 100755
index 00000000..aa3008f1
--- /dev/null
+++ b/CPP/7zip/Archive/Cab/CabIn.h
@@ -0,0 +1,166 @@
+// Archive/CabIn.h
+
+#ifndef __ARCHIVE_CAB_IN_H
+#define __ARCHIVE_CAB_IN_H
+
+#include "../../IStream.h"
+#include "../../Common/InBuffer.h"
+#include "CabHeader.h"
+#include "CabItem.h"
+
+namespace NArchive {
+namespace NCab {
+
+class CInArchiveException
+{
+public:
+ enum CCauseType
+ {
+ kUnexpectedEndOfArchive = 0,
+ kIncorrectArchive,
+ kUnsupported,
+ } Cause;
+ CInArchiveException(CCauseType cause) : Cause(cause) {}
+};
+
+struct COtherArchive
+{
+ AString FileName;
+ AString DiskName;
+};
+
+struct CArchiveInfo
+{
+ 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 */
+
+ bool ReserveBlockPresent() const { return (Flags & NHeader::NArchive::NFlags::kReservePresent) != 0; }
+
+ 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 CDatabaseEx: public CDatabase
+{
+public:
+ CMyComPtr<IInStream> Stream;
+};
+
+struct CMvItem
+{
+ int VolumeIndex;
+ int ItemIndex;
+};
+
+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
+{
+ 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(
+ const UInt64 *searchHeaderSizeLimit,
+ CDatabaseEx &database);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Cab/CabItem.h b/CPP/7zip/Archive/Cab/CabItem.h
new file mode 100755
index 00000000..21327eca
--- /dev/null
+++ b/CPP/7zip/Archive/Cab/CabItem.h
@@ -0,0 +1,62 @@
+// Archive/CabItem.h
+
+#ifndef __ARCHIVE_CAB_ITEM_H
+#define __ARCHIVE_CAB_ITEM_H
+
+#include "Common/Types.h"
+#include "Common/String.h"
+#include "CabHeader.h"
+
+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:
+ AString Name;
+ UInt32 Offset;
+ UInt32 Size;
+ UInt32 Time;
+ 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; }
+
+ 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/CPP/7zip/Archive/Cab/DllExports.cpp b/CPP/7zip/Archive/Cab/DllExports.cpp
new file mode 100755
index 00000000..fa17f10b
--- /dev/null
+++ b/CPP/7zip/Archive/Cab/DllExports.cpp
@@ -0,0 +1,72 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+#include "CabHandler.h"
+#include "../../ICoder.h"
+
+// {23170F69-40C1-278A-1000-000110080000}
+DEFINE_GUID(CLSID_CCabHandler,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x08, 0x00, 0x00);
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID)
+{
+ return TRUE;
+}
+
+STDAPI CreateObject(
+ const GUID *classID,
+ const GUID *interfaceID,
+ void **outObject)
+{
+ COM_TRY_BEGIN
+ *outObject = 0;
+ if (*classID != CLSID_CCabHandler)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ if (*interfaceID != IID_IInArchive)
+ return E_NOINTERFACE;
+ CMyComPtr<IInArchive> inArchive = (IInArchive *)new NArchive::NCab::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"Cab";
+ break;
+ case NArchive::kClassID:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CCabHandler, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NArchive::kExtension:
+ propVariant = L"cab";
+ break;
+ case NArchive::kUpdate:
+ propVariant = false;
+ break;
+ case NArchive::kKeepName:
+ propVariant = false;
+ break;
+ case NArchive::kStartSignature:
+ {
+ const char sig[] = { 0x4D, 0x53, 0x43, 0x46 };
+ if ((value->bstrVal = ::SysAllocStringByteLen(sig, 4)) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/CPP/7zip/Archive/Cab/StdAfx.cpp b/CPP/7zip/Archive/Cab/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Archive/Cab/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Archive/Cab/StdAfx.h b/CPP/7zip/Archive/Cab/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Archive/Cab/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Archive/Cab/cab.ico b/CPP/7zip/Archive/Cab/cab.ico
new file mode 100755
index 00000000..cc2007fc
--- /dev/null
+++ b/CPP/7zip/Archive/Cab/cab.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Cab/makefile b/CPP/7zip/Archive/Cab/makefile
new file mode 100755
index 00000000..672afed3
--- /dev/null
+++ b/CPP/7zip/Archive/Cab/makefile
@@ -0,0 +1,70 @@
+PROG = cab.dll
+DEF_FILE = ../Archive.def
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib user32.lib
+
+CAB_OBJS = \
+ $O\DllExports.obj \
+ $O\CabBlockInStream.obj \
+ $O\CabHandler.obj \
+ $O\CabHeader.obj \
+ $O\CabIn.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\IntToString.obj \
+ $O\NewHandler.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\UTFConvert.obj \
+ $O\Vector.obj \
+
+WIN_OBJS = \
+ $O\PropVariant.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\InBuffer.obj \
+ $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 \
+ $(CAB_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"
+
+$(CAB_OBJS): $(*B).cpp
+ $(COMPL)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(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/CPP/7zip/Archive/Cab/resource.rc b/CPP/7zip/Archive/Cab/resource.rc
new file mode 100755
index 00000000..fa0792bd
--- /dev/null
+++ b/CPP/7zip/Archive/Cab/resource.rc
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("Cab Plugin", "cab")
+
+101 ICON "cab.ico"
diff --git a/CPP/7zip/Archive/Chm/Chm.dsp b/CPP/7zip/Archive/Chm/Chm.dsp
new file mode 100755
index 00000000..7e0b7c66
--- /dev/null
+++ b/CPP/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/CPP/7zip/Archive/Chm/Chm.dsw b/CPP/7zip/Archive/Chm/Chm.dsw
new file mode 100755
index 00000000..58cb09b2
--- /dev/null
+++ b/CPP/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/CPP/7zip/Archive/Chm/ChmHandler.cpp b/CPP/7zip/Archive/Chm/ChmHandler.cpp
new file mode 100755
index 00000000..6b37c73e
--- /dev/null
+++ b/CPP/7zip/Archive/Chm/ChmHandler.cpp
@@ -0,0 +1,731 @@
+// 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[(int)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_Database.Clear();
+ m_Stream.Release();
+ return S_OK;
+}
+
+class CChmFolderOutStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ HRESULT Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK);
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+
+ UInt64 m_FolderSize;
+ UInt64 m_PosInFolder;
+ UInt64 m_PosInSection;
+ const CRecordVector<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->SetStream(m_Stream);
+ streamSpec->Init(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[(int)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->SetStream(m_Stream);
+ streamSpec->Init(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[(int)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 (;; 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->SetStream(m_Stream);
+ streamSpec->Init(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)
+{
+ *numItems = m_Database.NewFormat ? 1:
+ (m_Database.LowLevel ?
+ m_Database.Items.Size():
+ m_Database.Indices.Size());
+ return S_OK;
+}
+
+}}
diff --git a/CPP/7zip/Archive/Chm/ChmHandler.h b/CPP/7zip/Archive/Chm/ChmHandler.h
new file mode 100755
index 00000000..dd0692ba
--- /dev/null
+++ b/CPP/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
diff --git a/CPP/7zip/Archive/Chm/ChmHeader.cpp b/CPP/7zip/Archive/Chm/ChmHeader.cpp
new file mode 100755
index 00000000..4d485b6c
--- /dev/null
+++ b/CPP/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/CPP/7zip/Archive/Chm/ChmHeader.h b/CPP/7zip/Archive/Chm/ChmHeader.h
new file mode 100755
index 00000000..9f1bd42b
--- /dev/null
+++ b/CPP/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/CPP/7zip/Archive/Chm/ChmIn.cpp b/CPP/7zip/Archive/Chm/ChmIn.cpp
new file mode 100755
index 00000000..8c56ec91
--- /dev/null
+++ b/CPP/7zip/Archive/Chm/ChmIn.cpp
@@ -0,0 +1,925 @@
+// 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 (char)((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->SetStream(inStream);
+ streamSpec->Init(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;
+ for (;;)
+ {
+ 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;
+ for (;;)
+ {
+ 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;
+ for (;;)
+ {
+ 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/CPP/7zip/Archive/Chm/ChmIn.h b/CPP/7zip/Archive/Chm/ChmIn.h
new file mode 100755
index 00000000..ebf3c4be
--- /dev/null
+++ b/CPP/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[(int)blockIndex];
+ if (blockIndex + numBlocks >= ResetOffsets.Size())
+ size = CompressedSize - startPos;
+ else
+ size = ResetOffsets[(int)(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[(int)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[(int)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[(int)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/CPP/7zip/Archive/Chm/DllExports.cpp b/CPP/7zip/Archive/Chm/DllExports.cpp
new file mode 100755
index 00000000..ad822094
--- /dev/null
+++ b/CPP/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/CPP/7zip/Archive/Chm/StdAfx.cpp b/CPP/7zip/Archive/Chm/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Archive/Chm/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Archive/Chm/StdAfx.h b/CPP/7zip/Archive/Chm/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/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/CPP/7zip/Archive/Chm/makefile b/CPP/7zip/Archive/Chm/makefile
new file mode 100755
index 00000000..4adce2f5
--- /dev/null
+++ b/CPP/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/CPP/7zip/Archive/Chm/resource.rc b/CPP/7zip/Archive/Chm/resource.rc
new file mode 100755
index 00000000..fc93ae4f
--- /dev/null
+++ b/CPP/7zip/Archive/Chm/resource.rc
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("Chm Plugin", "chm")
diff --git a/CPP/7zip/Archive/Common/CodecsPath.cpp b/CPP/7zip/Archive/Common/CodecsPath.cpp
new file mode 100755
index 00000000..7ee89875
--- /dev/null
+++ b/CPP/7zip/Archive/Common/CodecsPath.cpp
@@ -0,0 +1,34 @@
+// CodecsPath.cpp
+
+#include "StdAfx.h"
+#include "../../../Common/String.h"
+
+extern HINSTANCE g_hInstance;
+
+static CSysString GetLibraryPath()
+{
+ TCHAR fullPath[MAX_PATH + 1];
+ ::GetModuleFileName(g_hInstance, fullPath, MAX_PATH);
+ return fullPath;
+}
+
+static CSysString GetLibraryFolderPrefix()
+{
+ CSysString path = GetLibraryPath();
+ int pos = path.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
+ return path.Left(pos + 1);
+}
+
+CSysString GetBaseFolderPrefix()
+{
+ CSysString libPrefix = GetLibraryFolderPrefix();
+ CSysString temp = libPrefix;
+ temp.Delete(temp.Length() - 1);
+ int pos = temp.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
+ return temp.Left(pos + 1);
+}
+
+CSysString GetCodecsFolderPrefix()
+{
+ return GetBaseFolderPrefix() + (CSysString)(TEXT("Codecs")) + (CSysString)(TEXT(STRING_PATH_SEPARATOR));
+}
diff --git a/CPP/7zip/Archive/Common/CodecsPath.h b/CPP/7zip/Archive/Common/CodecsPath.h
new file mode 100755
index 00000000..11145a03
--- /dev/null
+++ b/CPP/7zip/Archive/Common/CodecsPath.h
@@ -0,0 +1,12 @@
+// CodecsPath.h
+
+#ifndef __CODECSPATH_H
+#define __CODECSPATH_H
+
+#include "../../../Common/String.h"
+
+CSysString GetBaseFolderPrefix();
+CSysString GetCodecsFolderPrefix();
+
+#endif
+
diff --git a/CPP/7zip/Archive/Common/CoderLoader.cpp b/CPP/7zip/Archive/Common/CoderLoader.cpp
new file mode 100755
index 00000000..bf54f6e0
--- /dev/null
+++ b/CPP/7zip/Archive/Common/CoderLoader.cpp
@@ -0,0 +1,31 @@
+// CoderLoader.cpp
+
+#include "StdAfx.h"
+
+#include "CoderLoader.h"
+#include "FilterCoder.h"
+
+HRESULT CCoderLibrary::CreateCoderSpec(REFGUID clsID, ICompressCoder **coder)
+{
+ HRESULT result = CreateObject(clsID, IID_ICompressCoder, (void **)coder);
+ if (result == S_OK || result != E_NOINTERFACE)
+ return result;
+ CMyComPtr<ICompressFilter> filter;
+ RINOK(CreateObject(clsID, IID_ICompressFilter, (void **)&filter));
+ CFilterCoder *filterCoderSpec = new CFilterCoder;
+ CMyComPtr<ICompressCoder> filterCoder = filterCoderSpec;
+ filterCoderSpec->Filter = filter;
+ *coder = filterCoder.Detach();
+ return S_OK;
+}
+
+
+HRESULT CCoderLibrary::LoadAndCreateCoderSpec(LPCTSTR filePath, REFGUID clsID, ICompressCoder **coder)
+{
+ CCoderLibrary libTemp;
+ if (!libTemp.Load(filePath))
+ return GetLastError();
+ RINOK(libTemp.CreateCoderSpec(clsID, coder));
+ Attach(libTemp.Detach());
+ return S_OK;
+}
diff --git a/CPP/7zip/Archive/Common/CoderLoader.h b/CPP/7zip/Archive/Common/CoderLoader.h
new file mode 100755
index 00000000..02322d8c
--- /dev/null
+++ b/CPP/7zip/Archive/Common/CoderLoader.h
@@ -0,0 +1,147 @@
+// CoderLoader.h
+
+#ifndef __CODERLOADER_H
+#define __CODERLOADER_H
+
+#include "../../../Common/String.h"
+#include "../../../Common/MyCom.h"
+#include "../../../Windows/DLL.h"
+#include "../../ICoder.h"
+
+typedef UInt32 (WINAPI * CreateObjectPointer)(
+ const GUID *clsID,
+ const GUID *interfaceID,
+ void **outObject);
+
+class CCoderLibrary: public NWindows::NDLL::CLibrary
+{
+public:
+ HRESULT CreateObject(REFGUID clsID, REFGUID iid, void **obj)
+ {
+ CreateObjectPointer createObject = (CreateObjectPointer)
+ GetProcAddress("CreateObject");
+ if (createObject == NULL)
+ return GetLastError();
+ return createObject(&clsID, &iid, obj);
+ }
+
+ HRESULT CreateFilter(REFGUID clsID, ICompressFilter **filter)
+ {
+ return CreateObject(clsID, IID_ICompressFilter, (void **)filter);
+ }
+
+ HRESULT CreateCoder(REFGUID clsID, ICompressCoder **coder)
+ {
+ return CreateObject(clsID, IID_ICompressCoder, (void **)coder);
+ }
+
+ HRESULT CreateCoderSpec(REFGUID clsID, ICompressCoder **coder);
+
+ HRESULT LoadAndCreateFilter(LPCTSTR filePath, REFGUID clsID, ICompressFilter **filter)
+ {
+ CCoderLibrary libTemp;
+ if (!libTemp.Load(filePath))
+ return GetLastError();
+ RINOK(libTemp.CreateFilter(clsID, filter));
+ Attach(libTemp.Detach());
+ return S_OK;
+ }
+
+
+ HRESULT LoadAndCreateCoder(LPCTSTR filePath, REFGUID clsID, ICompressCoder **coder)
+ {
+ CCoderLibrary libTemp;
+ if (!libTemp.Load(filePath))
+ return GetLastError();
+ RINOK(libTemp.CreateCoder(clsID, coder));
+ Attach(libTemp.Detach());
+ return S_OK;
+ }
+
+ HRESULT LoadAndCreateCoderSpec(LPCTSTR filePath, REFGUID clsID, ICompressCoder **coder);
+ HRESULT CreateCoder2(REFGUID clsID, ICompressCoder2 **coder)
+ {
+ CreateObjectPointer createObject = (CreateObjectPointer)
+ GetProcAddress("CreateObject");
+ if (createObject == NULL)
+ return GetLastError();
+ return createObject(&clsID, &IID_ICompressCoder2, (void **)coder);
+ }
+ HRESULT LoadAndCreateCoder2(LPCTSTR filePath, REFGUID clsID, ICompressCoder2 **coder)
+ {
+ CCoderLibrary libTemp;
+ if (!libTemp.Load(filePath))
+ return GetLastError();
+ RINOK(libTemp.CreateCoder2(clsID, coder));
+ Attach(libTemp.Detach());
+ return S_OK;
+ }
+};
+
+
+class CCoderLibraries
+{
+ struct CPathToLibraryPair
+ {
+ CSysString Path;
+ CCoderLibrary Libary;
+ };
+ CObjectVector<CPathToLibraryPair> Pairs;
+public:
+ int FindPath(LPCTSTR filePath)
+ {
+ for (int i = 0; i < Pairs.Size(); i++)
+ if (Pairs[i].Path.CompareNoCase(filePath) == 0)
+ return i;
+ return -1;
+ }
+
+ HRESULT CreateCoder(LPCTSTR filePath, REFGUID clsID, ICompressCoder **coder)
+ {
+ int index = FindPath(filePath);
+ if (index < 0)
+ {
+ CPathToLibraryPair pair;
+ RINOK(pair.Libary.LoadAndCreateCoder(filePath, clsID, coder));
+ pair.Path = filePath;
+ Pairs.Add(pair);
+ pair.Libary.Detach();
+ return S_OK;
+ }
+ return Pairs[index].Libary.CreateCoder(clsID, coder);
+ }
+
+ HRESULT CreateCoderSpec(LPCTSTR filePath, REFGUID clsID, ICompressCoder **coder)
+ {
+ int index = FindPath(filePath);
+ if (index < 0)
+ {
+ CPathToLibraryPair pair;
+ RINOK(pair.Libary.LoadAndCreateCoderSpec(filePath, clsID, coder));
+ pair.Path = filePath;
+ Pairs.Add(pair);
+ pair.Libary.Detach();
+ return S_OK;
+ }
+ return Pairs[index].Libary.CreateCoderSpec(clsID, coder);
+ }
+
+ HRESULT CreateCoder2(LPCTSTR filePath, REFGUID clsID, ICompressCoder2 **coder)
+ {
+ int index = FindPath(filePath);
+ if (index < 0)
+ {
+ CPathToLibraryPair pair;
+ RINOK(pair.Libary.LoadAndCreateCoder2(filePath, clsID, coder));
+ pair.Path = filePath;
+ Pairs.Add(pair);
+ pair.Libary.Detach();
+ return S_OK;
+ }
+ return Pairs[index].Libary.CreateCoder2(clsID, coder);
+ }
+};
+
+
+#endif
+
diff --git a/CPP/7zip/Archive/Common/CoderMixer2.cpp b/CPP/7zip/Archive/Common/CoderMixer2.cpp
new file mode 100755
index 00000000..8f46e985
--- /dev/null
+++ b/CPP/7zip/Archive/Common/CoderMixer2.cpp
@@ -0,0 +1,121 @@
+// CoderMixer2.cpp
+
+#include "StdAfx.h"
+
+#include "CoderMixer2.h"
+
+namespace NCoderMixer2 {
+
+CBindReverseConverter::CBindReverseConverter(const CBindInfo &srcBindInfo):
+ _srcBindInfo(srcBindInfo)
+{
+ srcBindInfo.GetNumStreams(NumSrcInStreams, _numSrcOutStreams);
+
+ UInt32 j;
+ for (j = 0; j < NumSrcInStreams; j++)
+ {
+ _srcInToDestOutMap.Add(0);
+ DestOutToSrcInMap.Add(0);
+ }
+ for (j = 0; j < _numSrcOutStreams; j++)
+ {
+ _srcOutToDestInMap.Add(0);
+ _destInToSrcOutMap.Add(0);
+ }
+
+ UInt32 destInOffset = 0;
+ UInt32 destOutOffset = 0;
+ UInt32 srcInOffset = NumSrcInStreams;
+ UInt32 srcOutOffset = _numSrcOutStreams;
+
+ for (int i = srcBindInfo.Coders.Size() - 1; i >= 0; i--)
+ {
+ const CCoderStreamsInfo &srcCoderInfo = srcBindInfo.Coders[i];
+
+ srcInOffset -= srcCoderInfo.NumInStreams;
+ srcOutOffset -= srcCoderInfo.NumOutStreams;
+
+ UInt32 j;
+ for (j = 0; j < srcCoderInfo.NumInStreams; j++, destOutOffset++)
+ {
+ UInt32 index = srcInOffset + j;
+ _srcInToDestOutMap[index] = destOutOffset;
+ DestOutToSrcInMap[destOutOffset] = index;
+ }
+ for (j = 0; j < srcCoderInfo.NumOutStreams; j++, destInOffset++)
+ {
+ UInt32 index = srcOutOffset + j;
+ _srcOutToDestInMap[index] = destInOffset;
+ _destInToSrcOutMap[destInOffset] = index;
+ }
+ }
+}
+
+void CBindReverseConverter::CreateReverseBindInfo(CBindInfo &destBindInfo)
+{
+ destBindInfo.Coders.Clear();
+ destBindInfo.BindPairs.Clear();
+ destBindInfo.InStreams.Clear();
+ destBindInfo.OutStreams.Clear();
+
+ int i;
+ for (i = _srcBindInfo.Coders.Size() - 1; i >= 0; i--)
+ {
+ const CCoderStreamsInfo &srcCoderInfo = _srcBindInfo.Coders[i];
+ CCoderStreamsInfo destCoderInfo;
+ destCoderInfo.NumInStreams = srcCoderInfo.NumOutStreams;
+ destCoderInfo.NumOutStreams = srcCoderInfo.NumInStreams;
+ destBindInfo.Coders.Add(destCoderInfo);
+ }
+ for (i = _srcBindInfo.BindPairs.Size() - 1; i >= 0; i--)
+ {
+ const CBindPair &srcBindPair = _srcBindInfo.BindPairs[i];
+ CBindPair destBindPair;
+ destBindPair.InIndex = _srcOutToDestInMap[srcBindPair.OutIndex];
+ destBindPair.OutIndex = _srcInToDestOutMap[srcBindPair.InIndex];
+ destBindInfo.BindPairs.Add(destBindPair);
+ }
+ for (i = 0; i < _srcBindInfo.InStreams.Size(); i++)
+ destBindInfo.OutStreams.Add(_srcInToDestOutMap[_srcBindInfo.InStreams[i]]);
+ for (i = 0; i < _srcBindInfo.OutStreams.Size(); i++)
+ destBindInfo.InStreams.Add(_srcOutToDestInMap[_srcBindInfo.OutStreams[i]]);
+}
+
+CCoderInfo::CCoderInfo(UInt32 numInStreams, UInt32 numOutStreams):
+ NumInStreams(numInStreams),
+ NumOutStreams(numOutStreams)
+{
+ InSizes.Reserve(NumInStreams);
+ InSizePointers.Reserve(NumInStreams);
+ OutSizePointers.Reserve(NumOutStreams);
+ OutSizePointers.Reserve(NumOutStreams);
+}
+
+static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
+ CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
+{
+ sizes.Clear();
+ sizePointers.Clear();
+ for(UInt32 i = 0; i < numItems; i++)
+ {
+ if (srcSizes == 0 || srcSizes[i] == NULL)
+ {
+ sizes.Add(0);
+ sizePointers.Add(NULL);
+ }
+ else
+ {
+ sizes.Add(*srcSizes[i]);
+ sizePointers.Add(&sizes.Back());
+ }
+ }
+}
+
+void CCoderInfo::SetCoderInfo(const UInt64 **inSizes,
+ const UInt64 **outSizes)
+{
+ SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);
+ SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);
+}
+
+}
diff --git a/CPP/7zip/Archive/Common/CoderMixer2.h b/CPP/7zip/Archive/Common/CoderMixer2.h
new file mode 100755
index 00000000..78a3f280
--- /dev/null
+++ b/CPP/7zip/Archive/Common/CoderMixer2.h
@@ -0,0 +1,168 @@
+// CoderMixer2.h
+
+#ifndef __CODER_MIXER2_H
+#define __CODER_MIXER2_H
+
+#include "../../../Common/Vector.h"
+#include "../../../Common/Types.h"
+#include "../../../Common/MyCom.h"
+#include "../../ICoder.h"
+
+namespace NCoderMixer2 {
+
+struct CBindPair
+{
+ UInt32 InIndex;
+ UInt32 OutIndex;
+};
+
+struct CCoderStreamsInfo
+{
+ UInt32 NumInStreams;
+ UInt32 NumOutStreams;
+};
+
+struct CBindInfo
+{
+ CRecordVector<CCoderStreamsInfo> Coders;
+ CRecordVector<CBindPair> BindPairs;
+ CRecordVector<UInt32> InStreams;
+ CRecordVector<UInt32> OutStreams;
+
+ void Clear()
+ {
+ Coders.Clear();
+ BindPairs.Clear();
+ InStreams.Clear();
+ OutStreams.Clear();
+ }
+
+ /*
+ UInt32 GetCoderStartOutStream(UInt32 coderIndex) const
+ {
+ UInt32 numOutStreams = 0;
+ for (UInt32 i = 0; i < coderIndex; i++)
+ numOutStreams += Coders[i].NumOutStreams;
+ return numOutStreams;
+ }
+ */
+
+
+ void GetNumStreams(UInt32 &numInStreams, UInt32 &numOutStreams) const
+ {
+ numInStreams = 0;
+ numOutStreams = 0;
+ for (int i = 0; i < Coders.Size(); i++)
+ {
+ const CCoderStreamsInfo &coderStreamsInfo = Coders[i];
+ numInStreams += coderStreamsInfo.NumInStreams;
+ numOutStreams += coderStreamsInfo.NumOutStreams;
+ }
+ }
+
+ int FindBinderForInStream(UInt32 inStream) const
+ {
+ for (int i = 0; i < BindPairs.Size(); i++)
+ if (BindPairs[i].InIndex == inStream)
+ return i;
+ return -1;
+ }
+ int FindBinderForOutStream(UInt32 outStream) const
+ {
+ for (int i = 0; i < BindPairs.Size(); i++)
+ if (BindPairs[i].OutIndex == outStream)
+ return i;
+ return -1;
+ }
+
+ UInt32 GetCoderInStreamIndex(UInt32 coderIndex) const
+ {
+ UInt32 streamIndex = 0;
+ for (UInt32 i = 0; i < coderIndex; i++)
+ streamIndex += Coders[i].NumInStreams;
+ return streamIndex;
+ }
+
+ UInt32 GetCoderOutStreamIndex(UInt32 coderIndex) const
+ {
+ UInt32 streamIndex = 0;
+ for (UInt32 i = 0; i < coderIndex; i++)
+ streamIndex += Coders[i].NumOutStreams;
+ return streamIndex;
+ }
+
+
+ void FindInStream(UInt32 streamIndex, UInt32 &coderIndex,
+ UInt32 &coderStreamIndex) const
+ {
+ for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++)
+ {
+ UInt32 curSize = Coders[coderIndex].NumInStreams;
+ if (streamIndex < curSize)
+ {
+ coderStreamIndex = streamIndex;
+ return;
+ }
+ streamIndex -= curSize;
+ }
+ throw 1;
+ }
+ void FindOutStream(UInt32 streamIndex, UInt32 &coderIndex,
+ UInt32 &coderStreamIndex) const
+ {
+ for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++)
+ {
+ UInt32 curSize = Coders[coderIndex].NumOutStreams;
+ if (streamIndex < curSize)
+ {
+ coderStreamIndex = streamIndex;
+ return;
+ }
+ streamIndex -= curSize;
+ }
+ throw 1;
+ }
+};
+
+class CBindReverseConverter
+{
+ UInt32 _numSrcOutStreams;
+ NCoderMixer2::CBindInfo _srcBindInfo;
+ CRecordVector<UInt32> _srcInToDestOutMap;
+ CRecordVector<UInt32> _srcOutToDestInMap;
+ CRecordVector<UInt32> _destInToSrcOutMap;
+public:
+ UInt32 NumSrcInStreams;
+ CRecordVector<UInt32> DestOutToSrcInMap;
+
+ CBindReverseConverter(const NCoderMixer2::CBindInfo &srcBindInfo);
+ void CreateReverseBindInfo(NCoderMixer2::CBindInfo &destBindInfo);
+};
+
+struct CCoderInfo
+{
+ CMyComPtr<ICompressCoder> Coder;
+ CMyComPtr<ICompressCoder2> Coder2;
+ UInt32 NumInStreams;
+ UInt32 NumOutStreams;
+
+ CRecordVector<UInt64> InSizes;
+ CRecordVector<UInt64> OutSizes;
+ CRecordVector<const UInt64 *> InSizePointers;
+ CRecordVector<const UInt64 *> OutSizePointers;
+
+ CCoderInfo(UInt32 numInStreams, UInt32 numOutStreams);
+ void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);
+};
+
+class CCoderMixer2
+{
+public:
+ virtual void SetBindInfo(const CBindInfo &bindInfo) = 0;
+ virtual void ReInit() = 0;
+ virtual void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes) = 0;
+};
+
+}
+#endif
+
diff --git a/CPP/7zip/Archive/Common/CoderMixer2MT.cpp b/CPP/7zip/Archive/Common/CoderMixer2MT.cpp
new file mode 100755
index 00000000..9d7944b1
--- /dev/null
+++ b/CPP/7zip/Archive/Common/CoderMixer2MT.cpp
@@ -0,0 +1,359 @@
+// CoderMixer2MT.cpp
+
+#include "StdAfx.h"
+
+#include "CoderMixer2MT.h"
+#include "CrossThreadProgress.h"
+
+using namespace NWindows;
+using namespace NSynchronization;
+
+namespace NCoderMixer2 {
+
+CThreadCoderInfo::CThreadCoderInfo(UInt32 numInStreams, UInt32 numOutStreams):
+ ExitEvent(NULL),
+ CompressEvent(NULL),
+ CompressionCompletedEvent(NULL),
+ CCoderInfo(numInStreams, numOutStreams)
+{
+ InStreams.Reserve(NumInStreams);
+ InStreamPointers.Reserve(NumInStreams);
+ OutStreams.Reserve(NumOutStreams);
+ OutStreamPointers.Reserve(NumOutStreams);
+}
+
+void CThreadCoderInfo::CreateEvents()
+{
+ CompressEvent = new CAutoResetEvent(false);
+ CompressionCompletedEvent = new CAutoResetEvent(false);
+}
+
+CThreadCoderInfo::~CThreadCoderInfo()
+{
+ if (CompressEvent != NULL)
+ delete CompressEvent;
+ if (CompressionCompletedEvent != NULL)
+ delete CompressionCompletedEvent;
+}
+
+class CCoderInfoFlusher2
+{
+ CThreadCoderInfo *m_CoderInfo;
+public:
+ CCoderInfoFlusher2(CThreadCoderInfo *coderInfo): m_CoderInfo(coderInfo) {}
+ ~CCoderInfoFlusher2()
+ {
+ int i;
+ for (i = 0; i < m_CoderInfo->InStreams.Size(); i++)
+ m_CoderInfo->InStreams[i].Release();
+ for (i = 0; i < m_CoderInfo->OutStreams.Size(); i++)
+ m_CoderInfo->OutStreams[i].Release();
+ m_CoderInfo->CompressionCompletedEvent->Set();
+ }
+};
+
+bool CThreadCoderInfo::WaitAndCode()
+{
+ HANDLE events[2] = { ExitEvent, *CompressEvent };
+ DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
+ if (waitResult == WAIT_OBJECT_0 + 0)
+ return false;
+
+ {
+ InStreamPointers.Clear();
+ OutStreamPointers.Clear();
+ UInt32 i;
+ for (i = 0; i < NumInStreams; i++)
+ {
+ if (InSizePointers[i] != NULL)
+ InSizePointers[i] = &InSizes[i];
+ InStreamPointers.Add(InStreams[i]);
+ }
+ for (i = 0; i < NumOutStreams; i++)
+ {
+ if (OutSizePointers[i] != NULL)
+ OutSizePointers[i] = &OutSizes[i];
+ OutStreamPointers.Add(OutStreams[i]);
+ }
+ CCoderInfoFlusher2 coderInfoFlusher(this);
+ if (Coder)
+ Result = Coder->Code(InStreamPointers[0],
+ OutStreamPointers[0],
+ InSizePointers[0],
+ OutSizePointers[0],
+ Progress);
+ else
+ Result = Coder2->Code(&InStreamPointers.Front(),
+ &InSizePointers.Front(),
+ NumInStreams,
+ &OutStreamPointers.Front(),
+ &OutSizePointers.Front(),
+ NumOutStreams,
+ Progress);
+ }
+ return true;
+}
+
+static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
+ CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
+{
+ sizes.Clear();
+ sizePointers.Clear();
+ for(UInt32 i = 0; i < numItems; i++)
+ {
+ if (srcSizes == 0 || srcSizes[i] == NULL)
+ {
+ sizes.Add(0);
+ sizePointers.Add(NULL);
+ }
+ else
+ {
+ sizes.Add(*srcSizes[i]);
+ sizePointers.Add(&sizes.Back());
+ }
+ }
+}
+
+
+void CThreadCoderInfo::SetCoderInfo(const UInt64 **inSizes,
+ const UInt64 **outSizes, ICompressProgressInfo *progress)
+{
+ Progress = progress;
+ SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);
+ SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);
+}
+
+static DWORD WINAPI CoderThread(void *threadCoderInfo)
+{
+ for (;;)
+ {
+ if (!((CThreadCoderInfo *)threadCoderInfo)->WaitAndCode())
+ return 0;
+ }
+}
+
+//////////////////////////////////////
+// CCoderMixer2MT
+
+static DWORD WINAPI MainCoderThread(void *threadCoderInfo)
+{
+ for (;;)
+ {
+ if (!((CCoderMixer2MT *)threadCoderInfo)->MyCode())
+ return 0;
+ }
+}
+
+CCoderMixer2MT::CCoderMixer2MT()
+{
+ if (!_mainThread.Create(MainCoderThread, this))
+ throw 271825;
+}
+
+CCoderMixer2MT::~CCoderMixer2MT()
+{
+ _exitEvent.Set();
+ _mainThread.Wait();
+ for(int i = 0; i < _threads.Size(); i++)
+ {
+ _threads[i].Wait();
+ _threads[i].Close();
+ }
+}
+
+void CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo)
+{
+ _bindInfo = bindInfo;
+ _streamBinders.Clear();
+ for(int i = 0; i < _bindInfo.BindPairs.Size(); i++)
+ {
+ _streamBinders.Add(CStreamBinder());
+ _streamBinders.Back().CreateEvents();
+ }
+}
+
+void CCoderMixer2MT::AddCoderCommon()
+{
+ int index = _coderInfoVector.Size();
+ const CCoderStreamsInfo &CoderStreamsInfo = _bindInfo.Coders[index];
+
+ CThreadCoderInfo threadCoderInfo(CoderStreamsInfo.NumInStreams,
+ CoderStreamsInfo.NumOutStreams);
+ _coderInfoVector.Add(threadCoderInfo);
+ _coderInfoVector.Back().CreateEvents();
+ _coderInfoVector.Back().ExitEvent = _exitEvent;
+ _compressingCompletedEvents.Add(*_coderInfoVector.Back().CompressionCompletedEvent);
+
+ NWindows::CThread newThread;
+ _threads.Add(newThread);
+ if (!_threads.Back().Create(CoderThread, &_coderInfoVector.Back()))
+ throw 271824;
+}
+
+void CCoderMixer2MT::AddCoder(ICompressCoder *coder)
+{
+ AddCoderCommon();
+ _coderInfoVector.Back().Coder = coder;
+}
+
+void CCoderMixer2MT::AddCoder2(ICompressCoder2 *coder)
+{
+ AddCoderCommon();
+ _coderInfoVector.Back().Coder2 = coder;
+}
+
+/*
+void CCoderMixer2MT::FinishAddingCoders()
+{
+ for(int i = 0; i < _coderInfoVector.Size(); i++)
+ {
+ DWORD id;
+ HANDLE newThread = ::CreateThread(NULL, 0, CoderThread,
+ &_coderInfoVector[i], 0, &id);
+ if (newThread == 0)
+ throw 271824;
+ _threads.Add(newThread);
+ }
+}
+*/
+
+void CCoderMixer2MT::ReInit()
+{
+ for(int i = 0; i < _streamBinders.Size(); i++)
+ _streamBinders[i].ReInit();
+}
+
+
+STDMETHODIMP CCoderMixer2MT::Init(ISequentialInStream **inStreams,
+ ISequentialOutStream **outStreams)
+{
+ if (_coderInfoVector.Size() != _bindInfo.Coders.Size())
+ throw 0;
+ int i;
+ for(i = 0; i < _coderInfoVector.Size(); i++)
+ {
+ CThreadCoderInfo &coderInfo = _coderInfoVector[i];
+ const CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[i];
+ coderInfo.InStreams.Clear();
+ UInt32 j;
+ for(j = 0; j < coderStreamsInfo.NumInStreams; j++)
+ coderInfo.InStreams.Add(NULL);
+ coderInfo.OutStreams.Clear();
+ for(j = 0; j < coderStreamsInfo.NumOutStreams; j++)
+ coderInfo.OutStreams.Add(NULL);
+ }
+
+ for(i = 0; i < _bindInfo.BindPairs.Size(); i++)
+ {
+ const CBindPair &bindPair = _bindInfo.BindPairs[i];
+ UInt32 inCoderIndex, inCoderStreamIndex;
+ UInt32 outCoderIndex, outCoderStreamIndex;
+ _bindInfo.FindInStream(bindPair.InIndex, inCoderIndex, inCoderStreamIndex);
+ _bindInfo.FindOutStream(bindPair.OutIndex, outCoderIndex, outCoderStreamIndex);
+
+ _streamBinders[i].CreateStreams(
+ &_coderInfoVector[inCoderIndex].InStreams[inCoderStreamIndex],
+ &_coderInfoVector[outCoderIndex].OutStreams[outCoderStreamIndex]);
+ }
+
+ for(i = 0; i < _bindInfo.InStreams.Size(); i++)
+ {
+ UInt32 inCoderIndex, inCoderStreamIndex;
+ _bindInfo.FindInStream(_bindInfo.InStreams[i], inCoderIndex, inCoderStreamIndex);
+ _coderInfoVector[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i];
+ }
+
+ for(i = 0; i < _bindInfo.OutStreams.Size(); i++)
+ {
+ UInt32 outCoderIndex, outCoderStreamIndex;
+ _bindInfo.FindOutStream(_bindInfo.OutStreams[i], outCoderIndex, outCoderStreamIndex);
+ _coderInfoVector[outCoderIndex].OutStreams[outCoderStreamIndex] = outStreams[i];
+ }
+ return S_OK;
+}
+
+
+bool CCoderMixer2MT::MyCode()
+{
+ HANDLE events[2] = { _exitEvent, _startCompressingEvent };
+ DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
+ if (waitResult == WAIT_OBJECT_0 + 0)
+ return false;
+
+ for(int i = 0; i < _coderInfoVector.Size(); i++)
+ _coderInfoVector[i].CompressEvent->Set();
+ /* DWORD result = */ ::WaitForMultipleObjects(_compressingCompletedEvents.Size(),
+ &_compressingCompletedEvents.Front(), TRUE, INFINITE);
+
+ _compressingFinishedEvent.Set();
+
+ return true;
+}
+
+
+STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
+ const UInt64 ** /* inSizes */,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 ** /* outSizes */,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress)
+{
+ if (numInStreams != (UInt32)_bindInfo.InStreams.Size() ||
+ numOutStreams != (UInt32)_bindInfo.OutStreams.Size())
+ return E_INVALIDARG;
+
+ Init(inStreams, outStreams);
+
+ _compressingFinishedEvent.Reset(); // ?
+
+ CCrossThreadProgress *progressSpec = new CCrossThreadProgress;
+ CMyComPtr<ICompressProgressInfo> crossProgress = progressSpec;
+ progressSpec->Init();
+ _coderInfoVector[_progressCoderIndex].Progress = crossProgress;
+
+ _startCompressingEvent.Set();
+
+
+ for (;;)
+ {
+ HANDLE events[2] = {_compressingFinishedEvent, progressSpec->ProgressEvent };
+ DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
+ if (waitResult == WAIT_OBJECT_0 + 0)
+ break;
+ if (progress != NULL)
+ progressSpec->Result = progress->SetRatioInfo(progressSpec->InSize,
+ progressSpec->OutSize);
+ else
+ progressSpec->Result = S_OK;
+ progressSpec->WaitEvent.Set();
+ }
+
+ int i;
+ for(i = 0; i < _coderInfoVector.Size(); i++)
+ {
+ HRESULT result = _coderInfoVector[i].Result;
+ if (result == S_FALSE)
+ return result;
+ }
+ for(i = 0; i < _coderInfoVector.Size(); i++)
+ {
+ HRESULT result = _coderInfoVector[i].Result;
+ if (result != S_OK && result != E_FAIL)
+ return result;
+ }
+ for(i = 0; i < _coderInfoVector.Size(); i++)
+ {
+ HRESULT result = _coderInfoVector[i].Result;
+ if (result != S_OK)
+ return result;
+ }
+ return S_OK;
+}
+
+UInt64 CCoderMixer2MT::GetWriteProcessedSize(UInt32 binderIndex) const
+{
+ return _streamBinders[binderIndex].ProcessedSize;
+}
+
+}
diff --git a/CPP/7zip/Archive/Common/CoderMixer2MT.h b/CPP/7zip/Archive/Common/CoderMixer2MT.h
new file mode 100755
index 00000000..78d752de
--- /dev/null
+++ b/CPP/7zip/Archive/Common/CoderMixer2MT.h
@@ -0,0 +1,121 @@
+// CoderMixer2MT.h
+
+#ifndef __CODER_MIXER2_MT_H
+#define __CODER_MIXER2_MT_H
+
+#include "CoderMixer2.h"
+#include "../../../Common/MyCom.h"
+#include "../../../Windows/Thread.h"
+#include "../../Common/StreamBinder.h"
+
+namespace NCoderMixer2 {
+
+// CreateEvents();
+// {
+// SetCoderInfo()
+// Init Streams
+// set CompressEvent()
+// wait CompressionCompletedEvent
+// }
+
+struct CThreadCoderInfo: public CCoderInfo
+{
+ NWindows::NSynchronization::CAutoResetEvent *CompressEvent;
+ HANDLE ExitEvent;
+ NWindows::NSynchronization::CAutoResetEvent *CompressionCompletedEvent;
+
+ CObjectVector< CMyComPtr<ISequentialInStream> > InStreams;
+ CObjectVector< CMyComPtr<ISequentialOutStream> > OutStreams;
+ CRecordVector<ISequentialInStream *> InStreamPointers;
+ CRecordVector<ISequentialOutStream *> OutStreamPointers;
+
+ CMyComPtr<ICompressProgressInfo> Progress; // CMyComPtr
+ HRESULT Result;
+
+ CThreadCoderInfo(UInt32 numInStreams, UInt32 numOutStreams);
+ void SetCoderInfo(const UInt64 **inSizes,
+ const UInt64 **outSizes, ICompressProgressInfo *progress);
+ ~CThreadCoderInfo();
+ bool WaitAndCode();
+ void CreateEvents();
+};
+
+
+// SetBindInfo()
+// for each coder
+// {
+// AddCoder[2]()
+// }
+//
+// for each file
+// {
+// ReInit()
+// for each coder
+// {
+// SetCoderInfo
+// }
+// SetProgressIndex(UInt32 coderIndex);
+// Code
+// }
+
+
+class CCoderMixer2MT:
+ public ICompressCoder2,
+ public CCoderMixer2,
+ public CMyUnknownImp
+{
+ MY_UNKNOWN_IMP
+
+public:
+ STDMETHOD(Init)(ISequentialInStream **inStreams,
+ ISequentialOutStream **outStreams);
+
+ STDMETHOD(Code)(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+
+
+ CCoderMixer2MT();
+ ~CCoderMixer2MT();
+ void AddCoderCommon();
+ void AddCoder(ICompressCoder *coder);
+ void AddCoder2(ICompressCoder2 *coder);
+
+ void ReInit();
+ void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes)
+ { _coderInfoVector[coderIndex].SetCoderInfo(inSizes, outSizes, NULL); }
+ void SetProgressCoderIndex(UInt32 coderIndex)
+ { _progressCoderIndex = coderIndex; }
+
+
+ UInt64 GetWriteProcessedSize(UInt32 binderIndex) const;
+
+
+ bool MyCode();
+
+private:
+ CBindInfo _bindInfo;
+ CObjectVector<CStreamBinder> _streamBinders;
+ CObjectVector<CThreadCoderInfo> _coderInfoVector;
+ CRecordVector<NWindows::CThread> _threads;
+ NWindows::CThread _mainThread;
+
+ NWindows::NSynchronization::CAutoResetEvent _startCompressingEvent;
+ CRecordVector<HANDLE> _compressingCompletedEvents;
+ NWindows::NSynchronization::CAutoResetEvent _compressingFinishedEvent;
+
+ NWindows::NSynchronization::CManualResetEvent _exitEvent;
+ UInt32 _progressCoderIndex;
+
+public:
+ void SetBindInfo(const CBindInfo &bindInfo);
+
+};
+
+}
+#endif
+
diff --git a/CPP/7zip/Archive/Common/CoderMixer2ST.cpp b/CPP/7zip/Archive/Common/CoderMixer2ST.cpp
new file mode 100755
index 00000000..c01b776d
--- /dev/null
+++ b/CPP/7zip/Archive/Common/CoderMixer2ST.cpp
@@ -0,0 +1,238 @@
+// CoderMixer2ST.cpp
+
+#include "StdAfx.h"
+
+#include "CoderMixer2ST.h"
+
+namespace NCoderMixer2 {
+
+CCoderMixer2ST::CCoderMixer2ST() {}
+
+CCoderMixer2ST::~CCoderMixer2ST(){ }
+
+void CCoderMixer2ST::SetBindInfo(const CBindInfo &bindInfo)
+{
+ _bindInfo = bindInfo;
+}
+
+void CCoderMixer2ST::AddCoderCommon(bool isMain)
+{
+ const CCoderStreamsInfo &csi = _bindInfo.Coders[_coders.Size()];
+ _coders.Add(CSTCoderInfo(csi.NumInStreams, csi.NumOutStreams, isMain));
+}
+
+void CCoderMixer2ST::AddCoder(ICompressCoder *coder, bool isMain)
+{
+ AddCoderCommon(isMain);
+ _coders.Back().Coder = coder;
+}
+
+void CCoderMixer2ST::AddCoder2(ICompressCoder2 *coder, bool isMain)
+{
+ AddCoderCommon(isMain);
+ _coders.Back().Coder2 = coder;
+}
+
+void CCoderMixer2ST::ReInit() { }
+
+HRESULT CCoderMixer2ST::GetInStream(
+ ISequentialInStream **inStreams, const UInt64 **inSizes,
+ UInt32 streamIndex, ISequentialInStream **inStreamRes)
+{
+ CMyComPtr<ISequentialInStream> seqInStream;
+ int i;
+ for(i = 0; i < _bindInfo.InStreams.Size(); i++)
+ if (_bindInfo.InStreams[i] == streamIndex)
+ {
+ seqInStream = inStreams[i];
+ *inStreamRes = seqInStream.Detach();
+ return S_OK;
+ }
+ int binderIndex = _bindInfo.FindBinderForInStream(streamIndex);
+ if (binderIndex < 0)
+ return E_INVALIDARG;
+
+ UInt32 coderIndex, coderStreamIndex;
+ _bindInfo.FindOutStream(_bindInfo.BindPairs[binderIndex].OutIndex,
+ coderIndex, coderStreamIndex);
+
+ CCoderInfo &coder = _coders[coderIndex];
+ if (!coder.Coder)
+ return E_NOTIMPL;
+ coder.Coder.QueryInterface(IID_ISequentialInStream, &seqInStream);
+ if (!seqInStream)
+ return E_NOTIMPL;
+
+ UInt32 startIndex = _bindInfo.GetCoderInStreamIndex(coderIndex);
+
+ CMyComPtr<ICompressSetInStream> setInStream;
+ if (!coder.Coder)
+ return E_NOTIMPL;
+ coder.Coder.QueryInterface(IID_ICompressSetInStream, &setInStream);
+ if (!setInStream)
+ return E_NOTIMPL;
+
+ if (coder.NumInStreams > 1)
+ return E_NOTIMPL;
+ for (i = 0; i < (int)coder.NumInStreams; i++)
+ {
+ CMyComPtr<ISequentialInStream> seqInStream2;
+ RINOK(GetInStream(inStreams, inSizes, startIndex + i, &seqInStream2));
+ RINOK(setInStream->SetInStream(seqInStream2));
+ }
+ *inStreamRes = seqInStream.Detach();
+ return S_OK;
+}
+
+HRESULT CCoderMixer2ST::GetOutStream(
+ ISequentialOutStream **outStreams, const UInt64 **outSizes,
+ UInt32 streamIndex, ISequentialOutStream **outStreamRes)
+{
+ CMyComPtr<ISequentialOutStream> seqOutStream;
+ int i;
+ for(i = 0; i < _bindInfo.OutStreams.Size(); i++)
+ if (_bindInfo.OutStreams[i] == streamIndex)
+ {
+ seqOutStream = outStreams[i];
+ *outStreamRes = seqOutStream.Detach();
+ return S_OK;
+ }
+ int binderIndex = _bindInfo.FindBinderForOutStream(streamIndex);
+ if (binderIndex < 0)
+ return E_INVALIDARG;
+
+ UInt32 coderIndex, coderStreamIndex;
+ _bindInfo.FindInStream(_bindInfo.BindPairs[binderIndex].InIndex,
+ coderIndex, coderStreamIndex);
+
+ CCoderInfo &coder = _coders[coderIndex];
+ if (!coder.Coder)
+ return E_NOTIMPL;
+ coder.Coder.QueryInterface(IID_ISequentialOutStream, &seqOutStream);
+ if (!seqOutStream)
+ return E_NOTIMPL;
+
+ UInt32 startIndex = _bindInfo.GetCoderOutStreamIndex(coderIndex);
+
+ CMyComPtr<ICompressSetOutStream> setOutStream;
+ if (!coder.Coder)
+ return E_NOTIMPL;
+ coder.Coder.QueryInterface(IID_ICompressSetOutStream, &setOutStream);
+ if (!setOutStream)
+ return E_NOTIMPL;
+
+ if (coder.NumOutStreams > 1)
+ return E_NOTIMPL;
+ for (i = 0; i < (int)coder.NumOutStreams; i++)
+ {
+ CMyComPtr<ISequentialOutStream> seqOutStream2;
+ RINOK(GetOutStream(outStreams, outSizes, startIndex + i, &seqOutStream2));
+ RINOK(setOutStream->SetOutStream(seqOutStream2));
+ }
+ *outStreamRes = seqOutStream.Detach();
+ return S_OK;
+}
+
+
+STDMETHODIMP CCoderMixer2ST::Code(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress)
+{
+ if (numInStreams != (UInt32)_bindInfo.InStreams.Size() ||
+ numOutStreams != (UInt32)_bindInfo.OutStreams.Size())
+ return E_INVALIDARG;
+
+ // Find main coder
+ int _mainCoderIndex = -1;
+ int i;
+ for (i = 0; i < _coders.Size(); i++)
+ if (_coders[i].IsMain)
+ {
+ _mainCoderIndex = i;
+ break;
+ }
+ if (_mainCoderIndex < 0)
+ for (i = 0; i < _coders.Size(); i++)
+ if (_coders[i].NumInStreams > 1)
+ {
+ if (_mainCoderIndex >= 0)
+ return E_NOTIMPL;
+ _mainCoderIndex = i;
+ }
+ if (_mainCoderIndex < 0)
+ _mainCoderIndex = 0;
+
+ // _mainCoderIndex = 0;
+ // _mainCoderIndex = _coders.Size() - 1;
+ CCoderInfo &mainCoder = _coders[_mainCoderIndex];
+
+ CObjectVector< CMyComPtr<ISequentialInStream> > seqInStreams;
+ CObjectVector< CMyComPtr<ISequentialOutStream> > seqOutStreams;
+ UInt32 startInIndex = _bindInfo.GetCoderInStreamIndex(_mainCoderIndex);
+ UInt32 startOutIndex = _bindInfo.GetCoderOutStreamIndex(_mainCoderIndex);
+ for (i = 0; i < (int)mainCoder.NumInStreams; i++)
+ {
+ CMyComPtr<ISequentialInStream> seqInStream;
+ RINOK(GetInStream(inStreams, inSizes, startInIndex + i, &seqInStream));
+ seqInStreams.Add(seqInStream);
+ }
+ for (i = 0; i < (int)mainCoder.NumOutStreams; i++)
+ {
+ CMyComPtr<ISequentialOutStream> seqOutStream;
+ RINOK(GetOutStream(outStreams, outSizes, startOutIndex + i, &seqOutStream));
+ seqOutStreams.Add(seqOutStream);
+ }
+ CRecordVector< ISequentialInStream * > seqInStreamsSpec;
+ CRecordVector< ISequentialOutStream * > seqOutStreamsSpec;
+ for (i = 0; i < (int)mainCoder.NumInStreams; i++)
+ seqInStreamsSpec.Add(seqInStreams[i]);
+ for (i = 0; i < (int)mainCoder.NumOutStreams; i++)
+ seqOutStreamsSpec.Add(seqOutStreams[i]);
+
+ for (i = 0; i < _coders.Size(); i++)
+ {
+ if (i == _mainCoderIndex)
+ continue;
+ CCoderInfo &coder = _coders[i];
+ CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize;
+ coder.Coder.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize);
+ if (setOutStreamSize)
+ {
+ RINOK(setOutStreamSize->SetOutStreamSize(coder.OutSizePointers[0]));
+ }
+ }
+ if (mainCoder.Coder)
+ {
+ RINOK(mainCoder.Coder->Code(
+ seqInStreamsSpec[0], seqOutStreamsSpec[0],
+ mainCoder.InSizePointers[0], mainCoder.OutSizePointers[0],
+ progress));
+ }
+ else
+ {
+ RINOK(mainCoder.Coder2->Code(
+ &seqInStreamsSpec.Front(),
+ &mainCoder.InSizePointers.Front(), mainCoder.NumInStreams,
+ &seqOutStreamsSpec.Front(),
+ &mainCoder.OutSizePointers.Front(), mainCoder.NumOutStreams,
+ progress));
+ }
+ CMyComPtr<IOutStreamFlush> flush;
+ seqOutStreams.Front().QueryInterface(IID_IOutStreamFlush, &flush);
+ if (flush)
+ return flush->Flush();
+ return S_OK;
+}
+
+/*
+UInt64 CCoderMixer2ST::GetWriteProcessedSize(UInt32 binderIndex) const
+{
+ return _streamBinders[binderIndex].ProcessedSize;
+}
+*/
+
+}
diff --git a/CPP/7zip/Archive/Common/CoderMixer2ST.h b/CPP/7zip/Archive/Common/CoderMixer2ST.h
new file mode 100755
index 00000000..3144918b
--- /dev/null
+++ b/CPP/7zip/Archive/Common/CoderMixer2ST.h
@@ -0,0 +1,88 @@
+// CoderMixer2ST.h
+
+#ifndef __CODER_MIXER2_ST_H
+#define __CODER_MIXER2_ST_H
+
+#include "CoderMixer2.h"
+#include "../../../Common/MyCom.h"
+#include "../../ICoder.h"
+
+namespace NCoderMixer2 {
+
+// SetBindInfo()
+// for each coder
+// {
+// AddCoder[2]()
+// }
+//
+// for each file
+// {
+// ReInit()
+// for each coder
+// {
+// SetCoderInfo
+// }
+// SetProgressIndex(UInt32 coderIndex);
+// Code
+// }
+
+struct CSTCoderInfo: public CCoderInfo
+{
+ bool IsMain;
+ CSTCoderInfo(UInt32 numInStreams, UInt32 numOutStreams, bool isMain):
+ CCoderInfo(numInStreams, numOutStreams),IsMain(isMain) {}
+};
+
+class CCoderMixer2ST:
+ public ICompressCoder2,
+ public CCoderMixer2,
+ public CMyUnknownImp
+{
+ MY_UNKNOWN_IMP
+
+ HRESULT GetInStream(
+ ISequentialInStream **inStreams, const UInt64 **inSizes,
+ UInt32 streamIndex, ISequentialInStream **inStreamRes);
+ HRESULT GetOutStream(
+ ISequentialOutStream **outStreams, const UInt64 **outSizes,
+ UInt32 streamIndex, ISequentialOutStream **outStreamRes);
+public:
+ STDMETHOD(Code)(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+
+ CCoderMixer2ST();
+ ~CCoderMixer2ST();
+ void AddCoderCommon(bool isMain);
+ void AddCoder(ICompressCoder *coder, bool isMain);
+ void AddCoder2(ICompressCoder2 *coder, bool isMain);
+
+ void ReInit();
+ void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes)
+ {
+ { _coders[coderIndex].SetCoderInfo(inSizes, outSizes); }
+ }
+
+ void SetProgressCoderIndex(UInt32 /*coderIndex*/)
+ {
+ // _progressCoderIndex = coderIndex;
+ }
+
+ // UInt64 GetWriteProcessedSize(UInt32 binderIndex) const;
+
+private:
+ CBindInfo _bindInfo;
+ CObjectVector<CSTCoderInfo> _coders;
+ int _mainCoderIndex;
+public:
+ void SetBindInfo(const CBindInfo &bindInfo);
+
+};
+
+}
+#endif
+
diff --git a/CPP/7zip/Archive/Common/CrossThreadProgress.cpp b/CPP/7zip/Archive/Common/CrossThreadProgress.cpp
new file mode 100755
index 00000000..a974b54c
--- /dev/null
+++ b/CPP/7zip/Archive/Common/CrossThreadProgress.cpp
@@ -0,0 +1,15 @@
+// CrossThreadProgress.cpp
+
+#include "StdAfx.h"
+
+#include "CrossThreadProgress.h"
+
+STDMETHODIMP CCrossThreadProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
+{
+ InSize = inSize;
+ OutSize = outSize;
+ ProgressEvent.Set();
+ WaitEvent.Lock();
+ return Result;
+}
+
diff --git a/CPP/7zip/Archive/Common/CrossThreadProgress.h b/CPP/7zip/Archive/Common/CrossThreadProgress.h
new file mode 100755
index 00000000..5dd339dc
--- /dev/null
+++ b/CPP/7zip/Archive/Common/CrossThreadProgress.h
@@ -0,0 +1,31 @@
+// CrossThreadProgress.h
+
+#ifndef __CROSSTHREADPROGRESS_H
+#define __CROSSTHREADPROGRESS_H
+
+#include "../../ICoder.h"
+#include "../../../Windows/Synchronization.h"
+#include "../../../Common/MyCom.h"
+
+class CCrossThreadProgress:
+ public ICompressProgressInfo,
+ public CMyUnknownImp
+{
+public:
+ const UInt64 *InSize;
+ const UInt64 *OutSize;
+ HRESULT Result;
+ NWindows::NSynchronization::CAutoResetEvent ProgressEvent;
+ NWindows::NSynchronization::CAutoResetEvent WaitEvent;
+ void Init()
+ {
+ ProgressEvent.Reset();
+ WaitEvent.Reset();
+ }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+};
+
+#endif
diff --git a/CPP/7zip/Archive/Common/DummyOutStream.cpp b/CPP/7zip/Archive/Common/DummyOutStream.cpp
new file mode 100755
index 00000000..b1d49913
--- /dev/null
+++ b/CPP/7zip/Archive/Common/DummyOutStream.cpp
@@ -0,0 +1,20 @@
+// DummyOutStream.cpp
+
+#include "StdAfx.h"
+
+#include "DummyOutStream.h"
+
+void CDummyOutStream::Init(ISequentialOutStream *outStream)
+{
+ m_Stream = outStream;
+}
+
+STDMETHODIMP CDummyOutStream::Write(const void *data,
+ UInt32 size, UInt32 *processedSize)
+{
+ if(m_Stream)
+ return m_Stream->Write(data, size, processedSize);
+ if(processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
diff --git a/CPP/7zip/Archive/Common/DummyOutStream.h b/CPP/7zip/Archive/Common/DummyOutStream.h
new file mode 100755
index 00000000..51690787
--- /dev/null
+++ b/CPP/7zip/Archive/Common/DummyOutStream.h
@@ -0,0 +1,23 @@
+// DummyOutStream.h
+
+#ifndef __DUMMYOUTSTREAM_H
+#define __DUMMYOUTSTREAM_H
+
+#include "../../IStream.h"
+#include "Common/MyCom.h"
+
+class CDummyOutStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+private:
+ CMyComPtr<ISequentialOutStream> m_Stream;
+public:
+ void Init(ISequentialOutStream *outStream);
+};
+
+#endif
diff --git a/CPP/7zip/Archive/Common/FilterCoder.cpp b/CPP/7zip/Archive/Common/FilterCoder.cpp
new file mode 100755
index 00000000..5e104c84
--- /dev/null
+++ b/CPP/7zip/Archive/Common/FilterCoder.cpp
@@ -0,0 +1,243 @@
+// FilterCoder.cpp
+
+#include "StdAfx.h"
+
+#include "FilterCoder.h"
+#include "../../../Common/Alloc.h"
+#include "../../../Common/Defs.h"
+#include "../../Common/StreamUtils.h"
+
+static const int kBufferSize = 1 << 17;
+
+CFilterCoder::CFilterCoder()
+{
+ _buffer = (Byte *)::MidAlloc(kBufferSize);
+}
+
+CFilterCoder::~CFilterCoder()
+{
+ ::MidFree(_buffer);
+}
+
+HRESULT CFilterCoder::WriteWithLimit(ISequentialOutStream *outStream, UInt32 size)
+{
+ if (_outSizeIsDefined)
+ {
+ UInt64 remSize = _outSize - _nowPos64;
+ if (size > remSize)
+ size = (UInt32)remSize;
+ }
+ UInt32 processedSize = 0;
+ RINOK(WriteStream(outStream, _buffer, size, &processedSize));
+ if (size != processedSize)
+ return E_FAIL;
+ _nowPos64 += processedSize;
+ return S_OK;
+}
+
+
+STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ RINOK(Init());
+ UInt32 bufferPos = 0;
+ _outSizeIsDefined = (outSize != 0);
+ if (_outSizeIsDefined)
+ _outSize = *outSize;
+
+ while(NeedMore())
+ {
+ UInt32 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);
+ if (bufferPos > endPos)
+ {
+ for (; endPos< bufferPos; endPos++)
+ _buffer[endPos] = 0;
+ bufferPos = Filter->Filter(_buffer, endPos);
+ }
+
+ if (bufferPos == 0)
+ {
+ if (endPos > 0)
+ return WriteWithLimit(outStream, endPos);
+ return S_OK;
+ }
+ RINOK(WriteWithLimit(outStream, bufferPos));
+ if (progress != NULL)
+ {
+ RINOK(progress->SetRatioInfo(&_nowPos64, &_nowPos64));
+ }
+ UInt32 i = 0;
+ while(bufferPos < endPos)
+ _buffer[i++] = _buffer[bufferPos++];
+ bufferPos = i;
+ }
+ return S_OK;
+}
+
+// #ifdef _ST_MODE
+STDMETHODIMP CFilterCoder::SetOutStream(ISequentialOutStream *outStream)
+{
+ _bufferPos = 0;
+ _outStream = outStream;
+ return Init();
+}
+
+STDMETHODIMP CFilterCoder::ReleaseOutStream()
+{
+ _outStream.Release();
+ return S_OK;
+};
+
+
+STDMETHODIMP CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 processedSizeTotal = 0;
+ while(size > 0)
+ {
+ UInt32 sizeMax = kBufferSize - _bufferPos;
+ UInt32 sizeTemp = size;
+ if (sizeTemp > sizeMax)
+ sizeTemp = sizeMax;
+ memmove(_buffer + _bufferPos, data, sizeTemp);
+ size -= sizeTemp;
+ processedSizeTotal += sizeTemp;
+ data = (const Byte *)data + sizeTemp;
+ UInt32 endPos = _bufferPos + sizeTemp;
+ _bufferPos = Filter->Filter(_buffer, endPos);
+ if (_bufferPos == 0)
+ {
+ _bufferPos = endPos;
+ break;
+ }
+ if (_bufferPos > endPos)
+ {
+ if (size != 0)
+ return E_FAIL;
+ break;
+ }
+ RINOK(WriteWithLimit(_outStream, _bufferPos));
+ UInt32 i = 0;
+ while(_bufferPos < endPos)
+ _buffer[i++] = _buffer[_bufferPos++];
+ _bufferPos = i;
+ }
+ if (processedSize != NULL)
+ *processedSize = processedSizeTotal;
+ return S_OK;
+}
+
+STDMETHODIMP CFilterCoder::Flush()
+{
+ if (_bufferPos != 0)
+ {
+ UInt32 endPos = Filter->Filter(_buffer, _bufferPos);
+ if (endPos > _bufferPos)
+ {
+ for (; _bufferPos < endPos; _bufferPos++)
+ _buffer[_bufferPos] = 0;
+ if (Filter->Filter(_buffer, endPos) != endPos)
+ return E_FAIL;
+ }
+ UInt32 processedSize;
+ RINOK(WriteStream(_outStream, _buffer, _bufferPos, &processedSize));
+ if (_bufferPos != processedSize)
+ return E_FAIL;
+ _bufferPos = 0;
+ }
+ CMyComPtr<IOutStreamFlush> flush;
+ _outStream.QueryInterface(IID_IOutStreamFlush, &flush);
+ if (flush)
+ return flush->Flush();
+ return S_OK;
+}
+
+
+STDMETHODIMP CFilterCoder::SetInStream(ISequentialInStream *inStream)
+{
+ _convertedPosBegin = _convertedPosEnd = _bufferPos = 0;
+ _inStream = inStream;
+ return Init();
+}
+
+STDMETHODIMP CFilterCoder::ReleaseInStream()
+{
+ _inStream.Release();
+ return S_OK;
+};
+
+STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 processedSizeTotal = 0;
+ while(size > 0)
+ {
+ if (_convertedPosBegin != _convertedPosEnd)
+ {
+ UInt32 sizeTemp = MyMin(size, _convertedPosEnd - _convertedPosBegin);
+ memmove(data, _buffer + _convertedPosBegin, sizeTemp);
+ _convertedPosBegin += sizeTemp;
+ data = (void *)((Byte *)data + sizeTemp);
+ size -= sizeTemp;
+ processedSizeTotal += sizeTemp;
+ break;
+ }
+ int i;
+ for (i = 0; _convertedPosEnd + i < _bufferPos; i++)
+ _buffer[i] = _buffer[i + _convertedPosEnd];
+ _bufferPos = i;
+ _convertedPosBegin = _convertedPosEnd = 0;
+ UInt32 processedSizeTemp;
+ UInt32 size0 = kBufferSize - _bufferPos;
+ // Optimize it:
+ RINOK(ReadStream(_inStream, _buffer + _bufferPos, size0, &processedSizeTemp));
+ _bufferPos = _bufferPos + processedSizeTemp;
+ _convertedPosEnd = Filter->Filter(_buffer, _bufferPos);
+ if (_convertedPosEnd == 0)
+ {
+ if (_bufferPos == 0)
+ break;
+ else
+ {
+ _convertedPosEnd = _bufferPos; // check it
+ continue;
+ }
+ }
+ if (_convertedPosEnd > _bufferPos)
+ {
+ for (; _bufferPos < _convertedPosEnd; _bufferPos++)
+ _buffer[_bufferPos] = 0;
+ _convertedPosEnd = Filter->Filter(_buffer, _bufferPos);
+ }
+ }
+ if (processedSize != NULL)
+ *processedSize = processedSizeTotal;
+ return S_OK;
+}
+
+// #endif // _ST_MODE
+
+#ifndef _NO_CRYPTO
+STDMETHODIMP CFilterCoder::CryptoSetPassword(const Byte *data, UInt32 size)
+{
+ return _setPassword->CryptoSetPassword(data, size);
+}
+#endif
+
+#ifndef EXTRACT_ONLY
+STDMETHODIMP CFilterCoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{
+ return _writeCoderProperties->WriteCoderProperties(outStream);
+}
+#endif
+
+STDMETHODIMP CFilterCoder::SetDecoderProperties2(const Byte *data, UInt32 size)
+{
+ return _setDecoderProperties->SetDecoderProperties2(data, size);
+}
diff --git a/CPP/7zip/Archive/Common/FilterCoder.h b/CPP/7zip/Archive/Common/FilterCoder.h
new file mode 100755
index 00000000..45618172
--- /dev/null
+++ b/CPP/7zip/Archive/Common/FilterCoder.h
@@ -0,0 +1,130 @@
+// FilterCoder.h
+
+#ifndef __FILTERCODER_H
+#define __FILTERCODER_H
+
+#include "../../../Common/MyCom.h"
+#include "../../ICoder.h"
+#include "../../IPassword.h"
+
+#define MY_QUERYINTERFACE_ENTRY_AG(i, sub0, sub) if (iid == IID_ ## i) \
+{ if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \
+*outObject = (void *)(i *)this; AddRef(); return S_OK; }
+
+class CFilterCoder:
+ public ICompressCoder,
+ // #ifdef _ST_MODE
+ public ICompressSetInStream,
+ public ISequentialInStream,
+ public ICompressSetOutStream,
+ public ISequentialOutStream,
+ public IOutStreamFlush,
+ // #endif
+
+ #ifndef _NO_CRYPTO
+ public ICryptoSetPassword,
+ #endif
+ #ifndef EXTRACT_ONLY
+ public ICompressWriteCoderProperties,
+ #endif
+ public ICompressSetDecoderProperties2,
+ public CMyUnknownImp
+{
+protected:
+ Byte *_buffer;
+ // #ifdef _ST_MODE
+ CMyComPtr<ISequentialInStream> _inStream;
+ CMyComPtr<ISequentialOutStream> _outStream;
+ UInt32 _bufferPos;
+ UInt32 _convertedPosBegin;
+ UInt32 _convertedPosEnd;
+ // #endif
+ bool _outSizeIsDefined;
+ UInt64 _outSize;
+ UInt64 _nowPos64;
+
+ HRESULT Init()
+ {
+ _nowPos64 = 0;
+ _outSizeIsDefined = false;
+ return Filter->Init();
+ }
+
+ CMyComPtr<ICryptoSetPassword> _setPassword;
+ #ifndef EXTRACT_ONLY
+ CMyComPtr<ICompressWriteCoderProperties> _writeCoderProperties;
+ #endif
+ CMyComPtr<ICompressSetDecoderProperties2> _setDecoderProperties;
+public:
+ CMyComPtr<ICompressFilter> Filter;
+
+ CFilterCoder();
+ ~CFilterCoder();
+ HRESULT WriteWithLimit(ISequentialOutStream *outStream, UInt32 size);
+ bool NeedMore() const
+ { return (!_outSizeIsDefined || (_nowPos64 < _outSize)); }
+
+public:
+ MY_QUERYINTERFACE_BEGIN
+ MY_QUERYINTERFACE_ENTRY(ICompressCoder)
+ // #ifdef _ST_MODE
+ MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
+ MY_QUERYINTERFACE_ENTRY(ISequentialInStream)
+
+ MY_QUERYINTERFACE_ENTRY(ICompressSetOutStream)
+ MY_QUERYINTERFACE_ENTRY(ISequentialOutStream)
+ MY_QUERYINTERFACE_ENTRY(IOutStreamFlush)
+ // #endif
+
+ #ifndef _NO_CRYPTO
+ MY_QUERYINTERFACE_ENTRY_AG(ICryptoSetPassword, Filter, _setPassword)
+ #endif
+
+ #ifndef EXTRACT_ONLY
+ MY_QUERYINTERFACE_ENTRY_AG(ICompressWriteCoderProperties, Filter, _writeCoderProperties)
+ #endif
+
+ MY_QUERYINTERFACE_ENTRY_AG(ICompressSetDecoderProperties2, Filter, _setDecoderProperties)
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+ // #ifdef _ST_MODE
+ STDMETHOD(ReleaseInStream)();
+ STDMETHOD(SetInStream)(ISequentialInStream *inStream);
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); \
+ STDMETHOD(SetOutStream)(ISequentialOutStream *outStream);
+ STDMETHOD(ReleaseOutStream)();
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Flush)();
+ // #endif
+
+ #ifndef _NO_CRYPTO
+ STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
+ #endif
+ #ifndef EXTRACT_ONLY
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+ #endif
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+};
+
+// #ifdef _ST_MODE
+class CInStreamReleaser
+{
+public:
+ CFilterCoder *FilterCoder;
+ CInStreamReleaser(): FilterCoder(0) {}
+ ~CInStreamReleaser() { if (FilterCoder) FilterCoder->ReleaseInStream(); }
+};
+
+class COutStreamReleaser
+{
+public:
+ CFilterCoder *FilterCoder;
+ COutStreamReleaser(): FilterCoder(0) {}
+ ~COutStreamReleaser() { if (FilterCoder) FilterCoder->ReleaseOutStream(); }
+};
+// #endif
+
+#endif
diff --git a/CPP/7zip/Archive/Common/InStreamWithCRC.cpp b/CPP/7zip/Archive/Common/InStreamWithCRC.cpp
new file mode 100755
index 00000000..74dff7e1
--- /dev/null
+++ b/CPP/7zip/Archive/Common/InStreamWithCRC.cpp
@@ -0,0 +1,41 @@
+// InStreamWithCRC.cpp
+
+#include "StdAfx.h"
+
+#include "InStreamWithCRC.h"
+
+STDMETHODIMP CSequentialInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize;
+ HRESULT result = _stream->Read(data, size, &realProcessedSize);
+ _size += realProcessedSize;
+ if (size > 0 && realProcessedSize == 0)
+ _wasFinished = true;
+ _crc.Update(data, realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return result;
+}
+
+STDMETHODIMP CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize;
+ HRESULT result = _stream->Read(data, size, &realProcessedSize);
+ if (size > 0 && realProcessedSize == 0)
+ _wasFinished = true;
+ _size += realProcessedSize;
+ _crc.Update(data, realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return result;
+}
+
+STDMETHODIMP CInStreamWithCRC::Seek(Int64 offset,
+ UInt32 seekOrigin, UInt64 *newPosition)
+{
+ if (seekOrigin != STREAM_SEEK_SET || offset != 0)
+ return E_FAIL;
+ _size = 0;
+ _crc.Init();
+ return _stream->Seek(offset, seekOrigin, newPosition);
+}
diff --git a/CPP/7zip/Archive/Common/InStreamWithCRC.h b/CPP/7zip/Archive/Common/InStreamWithCRC.h
new file mode 100755
index 00000000..770a1437
--- /dev/null
+++ b/CPP/7zip/Archive/Common/InStreamWithCRC.h
@@ -0,0 +1,65 @@
+// InStreamWithCRC.h
+
+#ifndef __INSTREAMWITHCRC_H
+#define __INSTREAMWITHCRC_H
+
+#include "../../../Common/CRC.h"
+#include "../../../Common/MyCom.h"
+#include "../../IStream.h"
+
+class CSequentialInStreamWithCRC:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+private:
+ CMyComPtr<ISequentialInStream> _stream;
+ UInt64 _size;
+ CCRC _crc;
+ bool _wasFinished;
+public:
+ void SetStream(ISequentialInStream *stream) { _stream = stream; }
+ void Init()
+ {
+ _size = 0;
+ _wasFinished = false;
+ _crc.Init();
+ }
+ void ReleaseStream() { _stream.Release(); }
+ UInt32 GetCRC() const { return _crc.GetDigest(); }
+ UInt64 GetSize() const { return _size; }
+ bool WasFinished() const { return _wasFinished; }
+};
+
+class CInStreamWithCRC:
+ public IInStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP1(IInStream)
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+private:
+ CMyComPtr<IInStream> _stream;
+ UInt64 _size;
+ CCRC _crc;
+ bool _wasFinished;
+public:
+ void SetStream(IInStream *stream) { _stream = stream; }
+ void Init()
+ {
+ _size = 0;
+ _wasFinished = false;
+ _crc.Init();
+ }
+ void ReleaseStream() { _stream.Release(); }
+ UInt32 GetCRC() const { return _crc.GetDigest(); }
+ UInt64 GetSize() const { return _size; }
+ bool WasFinished() const { return _wasFinished; }
+};
+
+#endif
diff --git a/CPP/7zip/Archive/Common/ItemNameUtils.cpp b/CPP/7zip/Archive/Common/ItemNameUtils.cpp
new file mode 100755
index 00000000..f7c3fcd9
--- /dev/null
+++ b/CPP/7zip/Archive/Common/ItemNameUtils.cpp
@@ -0,0 +1,59 @@
+// Archive/Common/ItemNameUtils.cpp
+
+#include "StdAfx.h"
+
+#include "ItemNameUtils.h"
+
+namespace NArchive {
+namespace NItemName {
+
+static const wchar_t kOSDirDelimiter = WCHAR_PATH_SEPARATOR;
+static const wchar_t kDirDelimiter = L'/';
+
+UString MakeLegalName(const UString &name)
+{
+ UString zipName = name;
+ zipName.Replace(kOSDirDelimiter, kDirDelimiter);
+ return zipName;
+}
+
+UString GetOSName(const UString &name)
+{
+ UString newName = name;
+ newName.Replace(kDirDelimiter, kOSDirDelimiter);
+ return newName;
+}
+
+UString GetOSName2(const UString &name)
+{
+ if (name.IsEmpty())
+ return UString();
+ UString newName = GetOSName(name);
+ if (newName[newName.Length() - 1] == kOSDirDelimiter)
+ newName.Delete(newName.Length() - 1);
+ return newName;
+}
+
+bool HasTailSlash(const AString &name, UINT codePage)
+{
+ if (name.IsEmpty())
+ return false;
+ LPCSTR prev =
+ #ifdef _WIN32
+ CharPrevExA((WORD)codePage, name, &name[name.Length()], 0);
+ #else
+ (LPCSTR)(name) + (name.Length() - 1);
+ #endif
+ return (*prev == '/');
+}
+
+#ifndef _WIN32
+UString WinNameToOSName(const UString &name)
+{
+ UString newName = name;
+ newName.Replace(L'\\', kOSDirDelimiter);
+ return newName;
+}
+#endif
+
+}}
diff --git a/CPP/7zip/Archive/Common/ItemNameUtils.h b/CPP/7zip/Archive/Common/ItemNameUtils.h
new file mode 100755
index 00000000..63a01563
--- /dev/null
+++ b/CPP/7zip/Archive/Common/ItemNameUtils.h
@@ -0,0 +1,24 @@
+// Archive/Common/ItemNameUtils.h
+
+#ifndef __ARCHIVE_ITEMNAMEUTILS_H
+#define __ARCHIVE_ITEMNAMEUTILS_H
+
+#include "../../../Common/String.h"
+
+namespace NArchive {
+namespace NItemName {
+
+ UString MakeLegalName(const UString &name);
+ UString GetOSName(const UString &name);
+ UString GetOSName2(const UString &name);
+ bool HasTailSlash(const AString &name, UINT codePage);
+
+ #ifdef _WIN32
+ inline UString WinNameToOSName(const UString &name) { return name; }
+ #else
+ UString WinNameToOSName(const UString &name);
+ #endif
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Common/MultiStream.cpp b/CPP/7zip/Archive/Common/MultiStream.cpp
new file mode 100755
index 00000000..a8cb333e
--- /dev/null
+++ b/CPP/7zip/Archive/Common/MultiStream.cpp
@@ -0,0 +1,201 @@
+// MultiStream.cpp
+
+#include "StdAfx.h"
+
+#include "MultiStream.h"
+
+STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ if(processedSize != NULL)
+ *processedSize = 0;
+ while(_streamIndex < Streams.Size() && size > 0)
+ {
+ CSubStreamInfo &s = Streams[_streamIndex];
+ if (_pos == s.Size)
+ {
+ _streamIndex++;
+ _pos = 0;
+ continue;
+ }
+ RINOK(s.Stream->Seek(s.Pos + _pos, STREAM_SEEK_SET, 0));
+ UInt32 sizeToRead = UInt32(MyMin((UInt64)size, s.Size - _pos));
+ UInt32 realProcessed;
+ HRESULT result = s.Stream->Read(data, sizeToRead, &realProcessed);
+ data = (void *)((Byte *)data + realProcessed);
+ size -= realProcessed;
+ if(processedSize != NULL)
+ *processedSize += realProcessed;
+ _pos += realProcessed;
+ _seekPos += realProcessed;
+ RINOK(result);
+ break;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin,
+ UInt64 *newPosition)
+{
+ UInt64 newPos;
+ switch(seekOrigin)
+ {
+ case STREAM_SEEK_SET:
+ newPos = offset;
+ break;
+ case STREAM_SEEK_CUR:
+ newPos = _seekPos + offset;
+ break;
+ case STREAM_SEEK_END:
+ newPos = _totalLength + offset;
+ break;
+ default:
+ return STG_E_INVALIDFUNCTION;
+ }
+ _seekPos = 0;
+ for (_streamIndex = 0; _streamIndex < Streams.Size(); _streamIndex++)
+ {
+ UInt64 size = Streams[_streamIndex].Size;
+ if (newPos < _seekPos + size)
+ {
+ _pos = newPos - _seekPos;
+ _seekPos += _pos;
+ if (newPosition != 0)
+ *newPosition = newPos;
+ return S_OK;
+ }
+ _seekPos += size;
+ }
+ if (newPos == _seekPos)
+ {
+ if (newPosition != 0)
+ *newPosition = newPos;
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+
+/*
+class COutVolumeStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ int _volIndex;
+ UInt64 _volSize;
+ UInt64 _curPos;
+ CMyComPtr<ISequentialOutStream> _volumeStream;
+ COutArchive _archive;
+ CCRC _crc;
+
+public:
+ MY_UNKNOWN_IMP
+
+ CFileItem _file;
+ CUpdateOptions _options;
+ CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
+ void Init(IArchiveUpdateCallback2 *volumeCallback,
+ const UString &name)
+ {
+ _file.Name = name;
+ _file.IsStartPosDefined = true;
+ _file.StartPos = 0;
+
+ VolumeCallback = volumeCallback;
+ _volIndex = 0;
+ _volSize = 0;
+ }
+
+ HRESULT Flush();
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+HRESULT COutVolumeStream::Flush()
+{
+ if (_volumeStream)
+ {
+ _file.UnPackSize = _curPos;
+ _file.FileCRC = _crc.GetDigest();
+ RINOK(WriteVolumeHeader(_archive, _file, _options));
+ _archive.Close();
+ _volumeStream.Release();
+ _file.StartPos += _file.UnPackSize;
+ }
+ return S_OK;
+}
+*/
+
+/*
+STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if(processedSize != NULL)
+ *processedSize = 0;
+ while(size > 0)
+ {
+ if (_streamIndex >= Streams.Size())
+ {
+ CSubStreamInfo subStream;
+ RINOK(VolumeCallback->GetVolumeSize(Streams.Size(), &subStream.Size));
+ RINOK(VolumeCallback->GetVolumeStream(Streams.Size(), &subStream.Stream));
+ subStream.Pos = 0;
+ Streams.Add(subStream);
+ continue;
+ }
+ CSubStreamInfo &subStream = Streams[_streamIndex];
+ if (_offsetPos >= subStream.Size)
+ {
+ _offsetPos -= subStream.Size;
+ _streamIndex++;
+ continue;
+ }
+ if (_offsetPos != subStream.Pos)
+ {
+ CMyComPtr<IOutStream> outStream;
+ RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream));
+ RINOK(outStream->Seek(_offsetPos, STREAM_SEEK_SET, NULL));
+ subStream.Pos = _offsetPos;
+ }
+
+ UInt32 curSize = (UInt32)MyMin((UInt64)size, subStream.Size - subStream.Pos);
+ UInt32 realProcessed;
+ RINOK(subStream.Stream->Write(data, curSize, &realProcessed));
+ data = (void *)((Byte *)data + realProcessed);
+ size -= realProcessed;
+ subStream.Pos += realProcessed;
+ _offsetPos += realProcessed;
+ _absPos += realProcessed;
+ if (_absPos > _length)
+ _length = _absPos;
+ if(processedSize != NULL)
+ *processedSize += realProcessed;
+ if (subStream.Pos == subStream.Size)
+ {
+ _streamIndex++;
+ _offsetPos = 0;
+ }
+ if (realProcessed != curSize && realProcessed == 0)
+ return E_FAIL;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+{
+ if(seekOrigin >= 3)
+ return STG_E_INVALIDFUNCTION;
+ switch(seekOrigin)
+ {
+ case STREAM_SEEK_SET:
+ _absPos = offset;
+ break;
+ case STREAM_SEEK_CUR:
+ _absPos += offset;
+ break;
+ case STREAM_SEEK_END:
+ _absPos = _length + offset;
+ break;
+ }
+ _offsetPos = _absPos;
+ _streamIndex = 0;
+ return S_OK;
+}
+*/
diff --git a/CPP/7zip/Archive/Common/MultiStream.h b/CPP/7zip/Archive/Common/MultiStream.h
new file mode 100755
index 00000000..5a7cc687
--- /dev/null
+++ b/CPP/7zip/Archive/Common/MultiStream.h
@@ -0,0 +1,76 @@
+// MultiStream.h
+
+#ifndef __MULTISTREAM_H
+#define __MULTISTREAM_H
+
+#include "../../../Common/MyCom.h"
+#include "../../../Common/Vector.h"
+#include "../../Archive/IArchive.h"
+
+class CMultiStream:
+ public IInStream,
+ public CMyUnknownImp
+{
+ int _streamIndex;
+ UInt64 _pos;
+ UInt64 _seekPos;
+ UInt64 _totalLength;
+public:
+ struct CSubStreamInfo
+ {
+ CMyComPtr<IInStream> Stream;
+ UInt64 Pos;
+ UInt64 Size;
+ };
+ CObjectVector<CSubStreamInfo> Streams;
+ void Init()
+ {
+ _streamIndex = 0;
+ _pos = 0;
+ _seekPos = 0;
+ _totalLength = 0;
+ for (int i = 0; i < Streams.Size(); i++)
+ _totalLength += Streams[i].Size;
+ }
+
+ MY_UNKNOWN_IMP1(IInStream)
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+};
+
+/*
+class COutMultiStream:
+ public IOutStream,
+ public CMyUnknownImp
+{
+ int _streamIndex; // required stream
+ UInt64 _offsetPos; // offset from start of _streamIndex index
+ UInt64 _absPos;
+ UInt64 _length;
+
+ struct CSubStreamInfo
+ {
+ CMyComPtr<ISequentialOutStream> Stream;
+ UInt64 Size;
+ UInt64 Pos;
+ };
+ CObjectVector<CSubStreamInfo> Streams;
+public:
+ CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
+ void Init()
+ {
+ _streamIndex = 0;
+ _offsetPos = 0;
+ _absPos = 0;
+ _length = 0;
+ }
+
+ MY_UNKNOWN_IMP1(IOutStream)
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+};
+*/
+
+#endif
diff --git a/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp b/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp
new file mode 100755
index 00000000..7ac3f123
--- /dev/null
+++ b/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp
@@ -0,0 +1,24 @@
+// OutStreamWithCRC.cpp
+
+#include "StdAfx.h"
+
+#include "OutStreamWithCRC.h"
+
+STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize;
+ HRESULT result;
+ if(!_stream)
+ {
+ realProcessedSize = size;
+ result = S_OK;
+ }
+ else
+ result = _stream->Write(data, size, &realProcessedSize);
+ if (_calculateCrc)
+ _crc.Update(data, realProcessedSize);
+ _size += realProcessedSize;
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return result;
+}
diff --git a/CPP/7zip/Archive/Common/OutStreamWithCRC.h b/CPP/7zip/Archive/Common/OutStreamWithCRC.h
new file mode 100755
index 00000000..0feb542b
--- /dev/null
+++ b/CPP/7zip/Archive/Common/OutStreamWithCRC.h
@@ -0,0 +1,37 @@
+// OutStreamWithCRC.h
+
+#ifndef __OUTSTREAMWITHCRC_H
+#define __OUTSTREAMWITHCRC_H
+
+#include "../../../Common/CRC.h"
+#include "../../../Common/MyCom.h"
+#include "../../IStream.h"
+
+class COutStreamWithCRC:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+private:
+ CMyComPtr<ISequentialOutStream> _stream;
+ UInt64 _size;
+ CCRC _crc;
+ bool _calculateCrc;
+public:
+ void SetStream(ISequentialOutStream *stream) { _stream = stream; }
+ void Init(bool calculateCrc = true)
+ {
+ _size = 0;
+ _calculateCrc = calculateCrc;
+ _crc.Init();
+ }
+ void ReleaseStream() { _stream.Release(); }
+ UInt64 GetSize() const { return _size; }
+ UInt32 GetCRC() const { return _crc.GetDigest(); }
+ void InitCRC() { _crc.Init(); }
+};
+
+#endif
diff --git a/CPP/7zip/Archive/Common/ParseProperties.cpp b/CPP/7zip/Archive/Common/ParseProperties.cpp
new file mode 100755
index 00000000..9866d900
--- /dev/null
+++ b/CPP/7zip/Archive/Common/ParseProperties.cpp
@@ -0,0 +1,171 @@
+// ParseProperties.cpp
+
+#include "StdAfx.h"
+
+#include "ParseProperties.h"
+
+#include "Common/StringToInt.h"
+#include "Common/MyCom.h"
+
+HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
+{
+ if (prop.vt == VT_UI4)
+ {
+ if (!name.IsEmpty())
+ return E_INVALIDARG;
+ resValue = prop.ulVal;
+ }
+ else if (prop.vt == VT_EMPTY)
+ {
+ if(!name.IsEmpty())
+ {
+ const wchar_t *start = name;
+ const wchar_t *end;
+ UInt64 v = ConvertStringToUInt64(start, &end);
+ if (end - start != name.Length())
+ return E_INVALIDARG;
+ resValue = (UInt32)v;
+ }
+ }
+ else
+ return E_INVALIDARG;
+ return S_OK;
+}
+
+static const int kLogarithmicSizeLimit = 32;
+static const wchar_t kByteSymbol = L'B';
+static const wchar_t kKiloByteSymbol = L'K';
+static const wchar_t kMegaByteSymbol = L'M';
+
+HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize)
+{
+ UString srcString = srcStringSpec;
+ srcString.MakeUpper();
+
+ const wchar_t *start = srcString;
+ const wchar_t *end;
+ UInt64 number = ConvertStringToUInt64(start, &end);
+ int numDigits = (int)(end - start);
+ if (numDigits == 0 || srcString.Length() > numDigits + 1)
+ return E_INVALIDARG;
+ if (srcString.Length() == numDigits)
+ {
+ if (number >= kLogarithmicSizeLimit)
+ return E_INVALIDARG;
+ dicSize = (UInt32)1 << (int)number;
+ return S_OK;
+ }
+ switch (srcString[numDigits])
+ {
+ case kByteSymbol:
+ if (number >= ((UInt64)1 << kLogarithmicSizeLimit))
+ return E_INVALIDARG;
+ dicSize = (UInt32)number;
+ break;
+ case kKiloByteSymbol:
+ if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 10)))
+ return E_INVALIDARG;
+ dicSize = (UInt32)(number << 10);
+ break;
+ case kMegaByteSymbol:
+ if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 20)))
+ return E_INVALIDARG;
+ dicSize = (UInt32)(number << 20);
+ break;
+ default:
+ return E_INVALIDARG;
+ }
+ return S_OK;
+}
+
+HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
+{
+ if (name.IsEmpty())
+ {
+ if (prop.vt == VT_UI4)
+ {
+ UInt32 logDicSize = prop.ulVal;
+ if (logDicSize >= 32)
+ return E_INVALIDARG;
+ resValue = (UInt32)1 << logDicSize;
+ return S_OK;
+ }
+ if (prop.vt == VT_BSTR)
+ return ParsePropDictionaryValue(prop.bstrVal, resValue);
+ return E_INVALIDARG;
+ }
+ return ParsePropDictionaryValue(name, resValue);
+}
+
+HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value)
+{
+ switch(value.vt)
+ {
+ case VT_EMPTY:
+ dest = true;
+ break;
+ /*
+ case VT_UI4:
+ dest = (value.ulVal != 0);
+ break;
+ */
+ case VT_BSTR:
+ {
+ UString valueString = value.bstrVal;
+ valueString.MakeUpper();
+ if (valueString.Compare(L"ON") == 0)
+ dest = true;
+ else if (valueString.Compare(L"OFF") == 0)
+ dest = false;
+ else
+ return E_INVALIDARG;
+ break;
+ }
+ default:
+ return E_INVALIDARG;
+ }
+ return S_OK;
+}
+
+int ParseStringToUInt32(const UString &srcString, UInt32 &number)
+{
+ const wchar_t *start = srcString;
+ const wchar_t *end;
+ UInt64 number64 = ConvertStringToUInt64(start, &end);
+ if (number64 > 0xFFFFFFFF)
+ {
+ number = 0;
+ return 0;
+ }
+ number = (UInt32)number64;
+ return (int)(end - start);
+}
+
+HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads)
+{
+ if (name.IsEmpty())
+ {
+ switch(prop.vt)
+ {
+ case VT_UI4:
+ numThreads = prop.ulVal;
+ break;
+ default:
+ {
+ bool val;
+ RINOK(SetBoolProperty(val, prop));
+ numThreads = (val ? defaultNumThreads : 1);
+ break;
+ }
+ }
+ }
+ else
+ {
+ UInt32 number;
+ int index = ParseStringToUInt32(name, number);
+ if (index != name.Length())
+ return E_INVALIDARG;
+ numThreads = number;
+ }
+ return S_OK;
+}
diff --git a/CPP/7zip/Archive/Common/ParseProperties.h b/CPP/7zip/Archive/Common/ParseProperties.h
new file mode 100755
index 00000000..e6db316b
--- /dev/null
+++ b/CPP/7zip/Archive/Common/ParseProperties.h
@@ -0,0 +1,17 @@
+// ParseProperties.h
+
+#ifndef __PARSEPROPERTIES_H
+#define __PARSEPROPERTIES_H
+
+#include "Common/String.h"
+#include "Common/Types.h"
+
+HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
+HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize);
+HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
+
+HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value);
+int ParseStringToUInt32(const UString &srcString, UInt32 &number);
+HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads);
+
+#endif
diff --git a/CPP/7zip/Archive/Common/StdAfx.h b/CPP/7zip/Archive/Common/StdAfx.h
new file mode 100755
index 00000000..2e4be10b
--- /dev/null
+++ b/CPP/7zip/Archive/Common/StdAfx.h
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/Archive/Cpio/CpioHandler.cpp b/CPP/7zip/Archive/Cpio/CpioHandler.cpp
new file mode 100755
index 00000000..601afbd6
--- /dev/null
+++ b/CPP/7zip/Archive/Cpio/CpioHandler.cpp
@@ -0,0 +1,289 @@
+// Archive/cpio/Handler.cpp
+
+#include "StdAfx.h"
+
+#include "CpioHandler.h"
+
+#include "Common/Defs.h"
+#include "Common/StringConvert.h"
+#include "Common/NewHandler.h"
+#include "Common/ComTry.h"
+
+#include "Windows/Time.h"
+#include "Windows/PropVariant.h"
+
+#include "../../Common/ProgressUtils.h"
+#include "../../Common//LimitedStreams.h"
+
+#include "../../Compress/Copy/CopyCoder.h"
+#include "../Common/ItemNameUtils.h"
+#include "CpioIn.h"
+
+using namespace NWindows;
+using namespace NTime;
+
+namespace NArchive {
+namespace NCpio {
+
+enum // PropID
+{
+ kpidinode = kpidUserDefined,
+ kpidiChkSum
+};
+
+STATPROPSTG kProperties[] =
+{
+ { NULL, kpidPath, VT_BSTR},
+ { NULL, kpidIsFolder, VT_BOOL},
+ { NULL, kpidSize, VT_UI8},
+ { NULL, kpidPackedSize, VT_UI8},
+ { NULL, kpidLastWriteTime, VT_FILETIME},
+ // { NULL, kpidUser, VT_BSTR},
+ // { NULL, kpidGroup, VT_BSTR},
+ // { L"inode", kpidinode, VT_UI4}
+ // { L"CheckSum", kpidiChkSum, VT_UI4}
+};
+
+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;
+ *name = 0;
+ 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::Open(IInStream *inStream,
+ const UInt64 * /* maxCheckStartPosition */,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ COM_TRY_BEGIN
+ // try
+ {
+ CInArchive archive;
+
+ if(archive.Open(inStream) != S_OK)
+ return S_FALSE;
+
+ m_Items.Clear();
+
+ if (openArchiveCallback != NULL)
+ {
+ RINOK(openArchiveCallback->SetTotal(NULL, NULL));
+ UInt64 numFiles = m_Items.Size();
+ RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
+ }
+
+ for (;;)
+ {
+ CItemEx itemInfo;
+ bool filled;
+ HRESULT result = archive.GetNextItem(filled, itemInfo);
+ if (result == S_FALSE)
+ return S_FALSE;
+ if (result != S_OK)
+ return S_FALSE;
+ if (!filled)
+ break;
+ m_Items.Add(itemInfo);
+ archive.SkeepDataRecords(itemInfo.Size, itemInfo.Align);
+ if (openArchiveCallback != NULL)
+ {
+ UInt64 numFiles = m_Items.Size();
+ RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
+ }
+ }
+ if (m_Items.Size() == 0)
+ return S_FALSE;
+
+ m_InStream = inStream;
+ }
+ /*
+ catch(...)
+ {
+ return S_FALSE;
+ }
+ */
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ m_Items.Clear();
+ m_InStream.Release();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = m_Items.Size();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant propVariant;
+ const CItemEx &item = m_Items[index];
+
+ switch(propID)
+ {
+ case kpidPath:
+ propVariant = (const wchar_t *)NItemName::GetOSName(
+ MultiByteToUnicodeString(item.Name, CP_OEMCP));
+ break;
+ case kpidIsFolder:
+ propVariant = item.IsDirectory();
+ break;
+ case kpidSize:
+ case kpidPackedSize:
+ propVariant = item.Size;
+ break;
+ case kpidLastWriteTime:
+ {
+ FILETIME utcFileTime;
+ if (item.ModificationTime != 0)
+ NTime::UnixTimeToFileTime(item.ModificationTime, utcFileTime);
+ else
+ {
+ utcFileTime.dwLowDateTime = 0;
+ utcFileTime.dwHighDateTime = 0;
+ }
+ propVariant = utcFileTime;
+ break;
+ }
+ case kpidinode:
+ propVariant = item.inode;
+ break;
+ /*
+ case kpidiChkSum:
+ propVariant = item.ChkSum;
+ break;
+ */
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
+ Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ bool allFilesMode = (numItems == UInt32(-1));
+ if (allFilesMode)
+ numItems = m_Items.Size();
+ if(numItems == 0)
+ return S_OK;
+ bool testMode = (_aTestMode != 0);
+ UInt64 totalSize = 0;
+ UInt32 i;
+ for(i = 0; i < numItems; i++)
+ totalSize += m_Items[allFilesMode ? i : indices[i]].Size;
+ extractCallback->SetTotal(totalSize);
+
+ UInt64 currentTotalSize = 0;
+ UInt64 currentItemSize;
+
+ CMyComPtr<ICompressCoder> copyCoder;
+
+ 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];
+ const CItemEx &itemInfo = m_Items[index];
+
+ RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
+
+ currentItemSize = itemInfo.Size;
+
+ if(itemInfo.IsDirectory())
+ {
+ RINOK(extractCallback->PrepareOperation(askMode));
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ continue;
+ }
+ if(!testMode && (!realOutStream))
+ {
+ continue;
+ }
+ RINOK(extractCallback->PrepareOperation(askMode));
+ {
+ if (testMode)
+ {
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ continue;
+ }
+
+ RINOK(m_InStream->Seek(itemInfo.GetDataPosition(), STREAM_SEEK_SET, NULL));
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+ CMyComPtr<ISequentialInStream> inStream(streamSpec);
+ streamSpec->SetStream(m_InStream);
+ streamSpec->Init(itemInfo.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 == NULL)
+ {
+ copyCoder = new NCompress::CCopyCoder;
+ }
+ try
+ {
+ RINOK(copyCoder->Code(inStream, realOutStream,
+ NULL, NULL, compressProgress));
+ }
+ catch(...)
+ {
+ realOutStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ realOutStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ }
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+}}
diff --git a/CPP/7zip/Archive/Cpio/CpioHandler.h b/CPP/7zip/Archive/Cpio/CpioHandler.h
new file mode 100755
index 00000000..39702541
--- /dev/null
+++ b/CPP/7zip/Archive/Cpio/CpioHandler.h
@@ -0,0 +1,47 @@
+// Archive/cpio/Handler.h
+
+#ifndef __ARCHIVE_CPIO_HANDLER_H
+#define __ARCHIVE_CPIO_HANDLER_H
+
+#include "Common/MyCom.h"
+#include "../IArchive.h"
+
+#include "CpioItem.h"
+
+namespace NArchive {
+namespace NCpio {
+
+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:
+ CObjectVector<CItemEx> m_Items;
+ CMyComPtr<IInStream> m_InStream;
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Cpio/CpioHeader.cpp b/CPP/7zip/Archive/Cpio/CpioHeader.cpp
new file mode 100755
index 00000000..9e4d99cb
--- /dev/null
+++ b/CPP/7zip/Archive/Cpio/CpioHeader.cpp
@@ -0,0 +1,23 @@
+// Archive/cpio/Header.h
+
+#include "StdAfx.h"
+
+#include "CpioHeader.h"
+
+namespace NArchive {
+namespace NCpio {
+namespace NFileHeader {
+
+ namespace NMagic
+ {
+ extern const char *kMagic1 = "070701";
+ extern const char *kMagic2 = "070702";
+ extern const char *kMagic3 = "070707";
+ extern const char *kEndName = "TRAILER!!!";
+
+ const Byte kMagicForRecord2[2] = { 0xC7, 0x71 };
+ // unsigned short kMagicForRecord2BE = 0xC771;
+ }
+
+}}}
+
diff --git a/CPP/7zip/Archive/Cpio/CpioHeader.h b/CPP/7zip/Archive/Cpio/CpioHeader.h
new file mode 100755
index 00000000..40a0014a
--- /dev/null
+++ b/CPP/7zip/Archive/Cpio/CpioHeader.h
@@ -0,0 +1,70 @@
+// Archive/cpio/Header.h
+
+#ifndef __ARCHIVE_CPIO_HEADER_H
+#define __ARCHIVE_CPIO_HEADER_H
+
+#include "Common/Types.h"
+
+namespace NArchive {
+namespace NCpio {
+
+namespace NFileHeader
+{
+ namespace NMagic
+ {
+ extern const char *kMagic1;
+ extern const char *kMagic2;
+ extern const char *kMagic3;
+ extern const char *kEndName;
+ extern const Byte kMagicForRecord2[2];
+ }
+
+ const UInt32 kRecord2Size = 26;
+ /*
+ struct CRecord2
+ {
+ unsigned short c_magic;
+ short c_dev;
+ unsigned short c_ino;
+ unsigned short c_mode;
+ unsigned short c_uid;
+ unsigned short c_gid;
+ unsigned short c_nlink;
+ short c_rdev;
+ unsigned short c_mtimes[2];
+ unsigned short c_namesize;
+ unsigned short c_filesizes[2];
+ };
+ */
+
+ const UInt32 kRecordSize = 110;
+ /*
+ struct CRecord
+ {
+ char Magic[6]; // "070701" for "new" portable format, "070702" for CRC format
+ char inode[8];
+ char Mode[8];
+ char UID[8];
+ char GID[8];
+ char nlink[8];
+ char mtime[8];
+ char Size[8]; // must be 0 for FIFOs and directories
+ char DevMajor[8];
+ char DevMinor[8];
+ char RDevMajor[8]; //only valid for chr and blk special files
+ char RDevMinor[8]; //only valid for chr and blk special files
+ char NameSize[8]; // count includes terminating NUL in pathname
+ char ChkSum[8]; // 0 for "new" portable format; for CRC format the sum of all the bytes in the file
+ bool CheckMagic() const
+ { return memcmp(Magic, NMagic::kMagic1, 6) == 0 ||
+ memcmp(Magic, NMagic::kMagic2, 6) == 0; };
+ };
+ */
+
+ const UInt32 kOctRecordSize = 76;
+
+}
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Cpio/CpioIn.cpp b/CPP/7zip/Archive/Cpio/CpioIn.cpp
new file mode 100755
index 00000000..91399362
--- /dev/null
+++ b/CPP/7zip/Archive/Cpio/CpioIn.cpp
@@ -0,0 +1,271 @@
+// Archive/cpioIn.cpp
+
+#include "StdAfx.h"
+
+#include "CpioIn.h"
+
+#include "Common/StringToInt.h"
+#include "Windows/Defs.h"
+
+#include "../../Common/StreamUtils.h"
+
+#include "CpioHeader.h"
+
+namespace NArchive {
+namespace NCpio {
+
+HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
+{
+ RINOK(ReadStream(m_Stream, data, size, &processedSize));
+ m_Position += processedSize;
+ return S_OK;
+}
+
+Byte CInArchive::ReadByte()
+{
+ if (_blockPos >= _blockSize)
+ throw "Incorrect cpio archive";
+ return _block[_blockPos++];
+}
+
+UInt16 CInArchive::ReadUInt16()
+{
+ UInt16 value = 0;
+ for (int i = 0; i < 2; i++)
+ {
+ Byte b = ReadByte();
+ value |= (UInt16(b) << (8 * i));
+ }
+ return value;
+}
+
+UInt32 CInArchive::ReadUInt32()
+{
+ UInt32 value = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ Byte b = ReadByte();
+ value |= (UInt32(b) << (8 * i));
+ }
+ return value;
+}
+
+HRESULT CInArchive::Open(IInStream *inStream)
+{
+ RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position));
+ m_Stream = inStream;
+ return S_OK;
+}
+
+bool CInArchive::ReadNumber(UInt32 &resultValue)
+{
+ resultValue = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ char c = char(ReadByte());
+ int d;
+ if (c >= '0' && c <= '9')
+ d = c - '0';
+ else if (c >= 'A' && c <= 'F')
+ d = 10 + c - 'A';
+ else if (c >= 'a' && c <= 'f')
+ d = 10 + c - 'a';
+ else
+ return false;
+ resultValue *= 0x10;
+ resultValue += d;
+ }
+ 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 sz[32 + 4];
+ int i;
+ for (i = 0; i < size && i < 32; i++)
+ sz[i] = (char)ReadByte();
+ sz[i] = 0;
+ return OctalToNumber32(sz, resultValue);
+}
+
+#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)
+{
+ if (!convert)
+ return value;
+ return (unsigned short)((((unsigned short)(value & 0xFF)) << 8) | (value >> 8));
+}
+
+static UInt32 GetAlignedSize(UInt32 size, UInt32 align)
+{
+ while ((size & (align - 1)) != 0)
+ size++;
+ return size;
+}
+
+
+HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
+{
+ filled = false;
+
+ UInt32 processedSize;
+ item.HeaderPosition = m_Position;
+
+ _blockSize = kMaxBlockSize;
+ RINOK(ReadBytes(_block, 2, processedSize));
+ if (processedSize != 2)
+ return S_FALSE;
+ _blockPos = 0;
+
+ UInt32 nameSize;
+
+ bool oldBE =
+ _block[0] == NFileHeader::NMagic::kMagicForRecord2[1] &&
+ _block[1] == NFileHeader::NMagic::kMagicForRecord2[0];
+
+ bool binMode = (_block[0] == NFileHeader::NMagic::kMagicForRecord2[0] &&
+ _block[1] == NFileHeader::NMagic::kMagicForRecord2[1]) ||
+ oldBE;
+
+ if (binMode)
+ {
+ RINOK(ReadBytes(_block + 2, NFileHeader::kRecord2Size - 2, processedSize));
+ if (processedSize != NFileHeader::kRecord2Size - 2)
+ return S_FALSE;
+ item.Align = 2;
+ _blockPos = 2;
+ item.DevMajor = 0;
+ item.DevMinor = ConvertValue(ReadUInt16(), oldBE);
+ item.inode = ConvertValue(ReadUInt16(), oldBE);
+ item.Mode = ConvertValue(ReadUInt16(), oldBE);
+ item.UID = ConvertValue(ReadUInt16(), oldBE);
+ item.GID = ConvertValue(ReadUInt16(), oldBE);
+ item.NumLinks = ConvertValue(ReadUInt16(), oldBE);
+ item.RDevMajor =0;
+ item.RDevMinor = ConvertValue(ReadUInt16(), oldBE);
+ UInt16 timeHigh = ConvertValue(ReadUInt16(), oldBE);
+ UInt16 timeLow = ConvertValue(ReadUInt16(), oldBE);
+ item.ModificationTime = (UInt32(timeHigh) << 16) + timeLow;
+ nameSize = ConvertValue(ReadUInt16(), oldBE);
+ UInt16 sizeHigh = ConvertValue(ReadUInt16(), oldBE);
+ UInt16 sizeLow = ConvertValue(ReadUInt16(), oldBE);
+ item.Size = (UInt32(sizeHigh) << 16) + sizeLow;
+
+ item.ChkSum = 0;
+ item.HeaderSize = GetAlignedSize(
+ nameSize + NFileHeader::kRecord2Size, item.Align);
+ nameSize = item.HeaderSize - NFileHeader::kRecord2Size;
+ }
+ else
+ {
+ RINOK(ReadBytes(_block + 2, 4, processedSize));
+ if (processedSize != 4)
+ return S_FALSE;
+
+ bool magicOK =
+ memcmp(_block, NFileHeader::NMagic::kMagic1, 6) == 0 ||
+ memcmp(_block, NFileHeader::NMagic::kMagic2, 6) == 0;
+ _blockPos = 6;
+ if (magicOK)
+ {
+ RINOK(ReadBytes(_block + 6, NFileHeader::kRecordSize - 6, processedSize));
+ if (processedSize != NFileHeader::kRecordSize - 6)
+ return S_FALSE;
+ item.Align = 4;
+
+ GetFromHex(item.inode);
+ GetFromHex(item.Mode);
+ GetFromHex(item.UID);
+ GetFromHex(item.GID);
+ GetFromHex(item.NumLinks);
+ UInt32 modificationTime;
+ GetFromHex(modificationTime);
+ item.ModificationTime = modificationTime;
+ GetFromHex(item.Size);
+ GetFromHex(item.DevMajor);
+ GetFromHex(item.DevMinor);
+ GetFromHex(item.RDevMajor);
+ GetFromHex(item.RDevMinor);
+ GetFromHex(nameSize);
+ GetFromHex(item.ChkSum);
+ item.HeaderSize = GetAlignedSize(
+ nameSize + NFileHeader::kRecordSize, item.Align);
+ nameSize = item.HeaderSize - NFileHeader::kRecordSize;
+ }
+ else
+ {
+ if (!memcmp(_block, NFileHeader::NMagic::kMagic3, 6) == 0)
+ return S_FALSE;
+ RINOK(ReadBytes(_block + 6, NFileHeader::kOctRecordSize - 6, processedSize));
+ if (processedSize != NFileHeader::kOctRecordSize - 6)
+ return S_FALSE;
+ item.Align = 1;
+ item.DevMajor = 0;
+ GetFromOct6(item.DevMinor);
+ GetFromOct6(item.inode);
+ GetFromOct6(item.Mode);
+ GetFromOct6(item.UID);
+ GetFromOct6(item.GID);
+ GetFromOct6(item.NumLinks);
+ item.RDevMajor = 0;
+ GetFromOct6(item.RDevMinor);
+ UInt32 modificationTime;
+ GetFromOct11(modificationTime);
+ item.ModificationTime = modificationTime;
+ GetFromOct6(nameSize);
+ GetFromOct11(item.Size); // ?????
+ item.HeaderSize = GetAlignedSize(
+ nameSize + NFileHeader::kOctRecordSize, item.Align);
+ nameSize = item.HeaderSize - NFileHeader::kOctRecordSize;
+ }
+ }
+ if (nameSize == 0 || nameSize >= (1 << 27))
+ return E_FAIL;
+ RINOK(ReadBytes(item.Name.GetBuffer(nameSize),
+ nameSize, processedSize));
+ if (processedSize != nameSize)
+ return E_FAIL;
+ item.Name.ReleaseBuffer();
+ if (strcmp(item.Name, NFileHeader::NMagic::kEndName) == 0)
+ return S_OK;
+ filled = true;
+ return S_OK;
+}
+
+HRESULT CInArchive::Skeep(UInt64 numBytes)
+{
+ UInt64 newPostion;
+ RINOK(m_Stream->Seek(numBytes, STREAM_SEEK_CUR, &newPostion));
+ m_Position += numBytes;
+ if (m_Position != newPostion)
+ return E_FAIL;
+ return S_OK;
+}
+
+HRESULT CInArchive::SkeepDataRecords(UInt64 dataSize, UInt32 align)
+{
+ while ((dataSize & (align - 1)) != 0)
+ dataSize++;
+ return Skeep(dataSize);
+}
+
+}}
diff --git a/CPP/7zip/Archive/Cpio/CpioIn.h b/CPP/7zip/Archive/Cpio/CpioIn.h
new file mode 100755
index 00000000..19e3da10
--- /dev/null
+++ b/CPP/7zip/Archive/Cpio/CpioIn.h
@@ -0,0 +1,41 @@
+// CpioIn.h
+
+#ifndef __ARCHIVE_CPIO_IN_H
+#define __ARCHIVE_CPIO_IN_H
+
+#include "Common/MyCom.h"
+#include "Common/Types.h"
+#include "../../IStream.h"
+#include "CpioItem.h"
+
+namespace NArchive {
+namespace NCpio {
+
+const UInt32 kMaxBlockSize = NFileHeader::kRecordSize;
+
+class CInArchive
+{
+ CMyComPtr<IInStream> m_Stream;
+ UInt64 m_Position;
+
+ UInt16 _blockSize;
+ Byte _block[kMaxBlockSize];
+ UInt32 _blockPos;
+ Byte ReadByte();
+ UInt16 ReadUInt16();
+ UInt32 ReadUInt32();
+
+ bool ReadNumber(UInt32 &resultValue);
+ bool ReadOctNumber(int size, UInt32 &resultValue);
+
+ HRESULT ReadBytes(void *data, UInt32 size, UInt32 &processedSize);
+public:
+ HRESULT Open(IInStream *inStream);
+ HRESULT GetNextItem(bool &filled, CItemEx &itemInfo);
+ HRESULT Skeep(UInt64 numBytes);
+ HRESULT SkeepDataRecords(UInt64 dataSize, UInt32 align);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Cpio/CpioItem.h b/CPP/7zip/Archive/Cpio/CpioItem.h
new file mode 100755
index 00000000..0eb2a0b4
--- /dev/null
+++ b/CPP/7zip/Archive/Cpio/CpioItem.h
@@ -0,0 +1,55 @@
+// Archive/cpio/ItemInfo.h
+
+#ifndef __ARCHIVE_CPIO_ITEMINFO_H
+#define __ARCHIVE_CPIO_ITEMINFO_H
+
+#include <sys/stat.h>
+
+#include "Common/Types.h"
+#include "Common/String.h"
+#include "CpioHeader.h"
+
+namespace NArchive {
+namespace NCpio {
+
+struct CItem
+{
+ AString Name;
+ UInt32 inode;
+ UInt32 Mode;
+ UInt32 UID;
+ UInt32 GID;
+ UInt32 Size;
+ UInt32 ModificationTime;
+
+ // char LinkFlag;
+ // AString LinkName; ?????
+ char Magic[8];
+ UInt32 NumLinks;
+ UInt32 DevMajor;
+ UInt32 DevMinor;
+ UInt32 RDevMajor;
+ UInt32 RDevMinor;
+ UInt32 ChkSum;
+
+ UInt32 Align;
+
+ bool IsDirectory() const
+#ifdef _WIN32
+ { return (Mode & _S_IFMT) == _S_IFDIR; }
+#else
+ { return (Mode & S_IFMT) == S_IFDIR; }
+#endif
+};
+
+class CItemEx: public CItem
+{
+public:
+ UInt64 HeaderPosition;
+ UInt32 HeaderSize;
+ UInt64 GetDataPosition() const { return HeaderPosition + HeaderSize; };
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Cpio/DllExports.cpp b/CPP/7zip/Archive/Cpio/DllExports.cpp
new file mode 100755
index 00000000..8eb38bfd
--- /dev/null
+++ b/CPP/7zip/Archive/Cpio/DllExports.cpp
@@ -0,0 +1,65 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+#include "CpioHandler.h"
+#include "../../ICoder.h"
+
+// {23170F69-40C1-278A-1000-000110ED0000}
+DEFINE_GUID(CLSID_CCpioHandler,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xED, 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_CCpioHandler)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ if (*interfaceID != IID_IInArchive)
+ return E_NOINTERFACE;
+ CMyComPtr<IInArchive> inArchive = (IInArchive *)new NArchive::NCpio::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"Cpio";
+ break;
+ case NArchive::kClassID:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CCpioHandler, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NArchive::kExtension:
+ propVariant = L"cpio";
+ break;
+ case NArchive::kUpdate:
+ propVariant = false;
+ break;
+ case NArchive::kKeepName:
+ propVariant = false;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/CPP/7zip/Archive/Cpio/StdAfx.cpp b/CPP/7zip/Archive/Cpio/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Archive/Cpio/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Archive/Cpio/StdAfx.h b/CPP/7zip/Archive/Cpio/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Archive/Cpio/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Archive/Cpio/cpio.dsp b/CPP/7zip/Archive/Cpio/cpio.dsp
new file mode 100755
index 00000000..f30c3e63
--- /dev/null
+++ b/CPP/7zip/Archive/Cpio/cpio.dsp
@@ -0,0 +1,265 @@
+# Microsoft Developer Studio Project File - Name="cpio" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=cpio - 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 "cpio.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 "cpio.mak" CFG="cpio - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "cpio - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "cpio - 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)" == "cpio - 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 "CPIO_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CPIO_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\cpio.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "cpio - 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 "CPIO_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 "CPIO_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\cpio.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "cpio - Win32 Release"
+# Name "cpio - Win32 Debug"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Archive.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\cpio.ico
+# 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 "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\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# 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\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
+
+SOURCE=..\..\..\Common\Vector.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.h
+# End Source File
+# End Group
+# Begin Group "Engine"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\CpioHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CpioHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CpioHeader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CpioHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CpioIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CpioIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CpioItem.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 "7zip Common"
+
+# PROP Default_Filter ""
+# 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\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
+# End Target
+# End Project
diff --git a/CPP/7zip/Archive/Cpio/cpio.dsw b/CPP/7zip/Archive/Cpio/cpio.dsw
new file mode 100755
index 00000000..b1b6d98f
--- /dev/null
+++ b/CPP/7zip/Archive/Cpio/cpio.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "cpio"=.\cpio.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Archive/Cpio/cpio.ico b/CPP/7zip/Archive/Cpio/cpio.ico
new file mode 100755
index 00000000..9abaabc7
--- /dev/null
+++ b/CPP/7zip/Archive/Cpio/cpio.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Cpio/makefile b/CPP/7zip/Archive/Cpio/makefile
new file mode 100755
index 00000000..d7760281
--- /dev/null
+++ b/CPP/7zip/Archive/Cpio/makefile
@@ -0,0 +1,55 @@
+PROG = cpio.dll
+DEF_FILE = ../Archive.def
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib user32.lib
+
+CPIO_OBJS = \
+ $O\DllExports.obj \
+ $O\CpioHandler.obj \
+ $O\CpioHeader.obj \
+ $O\CpioIn.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\NewHandler.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\Vector.obj \
+
+WIN_OBJS = \
+ $O\PropVariant.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\LimitedStreams.obj \
+ $O\ProgressUtils.obj \
+ $O\StreamUtils.obj \
+
+AR_COMMON_OBJS = \
+ $O\ItemNameUtils.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(CPIO_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $(COMPRESS_CPIO_OBJS) \
+ $O\CopyCoder.obj \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(CPIO_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)
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/Archive/Cpio/resource.rc b/CPP/7zip/Archive/Cpio/resource.rc
new file mode 100755
index 00000000..d5456e5a
--- /dev/null
+++ b/CPP/7zip/Archive/Cpio/resource.rc
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("Cpio Plugin", "cpio")
+
+101 ICON "cpio.ico"
diff --git a/CPP/7zip/Archive/Deb/Deb.dsp b/CPP/7zip/Archive/Deb/Deb.dsp
new file mode 100755
index 00000000..56689305
--- /dev/null
+++ b/CPP/7zip/Archive/Deb/Deb.dsp
@@ -0,0 +1,269 @@
+# Microsoft Developer Studio Project File - Name="Deb" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=Deb - 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 "Deb.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 "Deb.mak" CFG="Deb - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Deb - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Deb - 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)" == "Deb - 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 "DEB_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DEB_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\deb.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Deb - 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 "DEB_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 "DEB_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\deb.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "Deb - Win32 Release"
+# Name "Deb - Win32 Debug"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Archive.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\Deb.ico
+# 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 "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\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.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\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
+
+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 "Compress"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.h
+# End Source File
+# End Group
+# Begin Group "Engine"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\DebHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\DebHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\DebHeader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\DebHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\DebIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\DebIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\DebItem.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 "7zip Common"
+
+# PROP Default_Filter ""
+# 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\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
+# End Target
+# End Project
diff --git a/CPP/7zip/Archive/Deb/Deb.dsw b/CPP/7zip/Archive/Deb/Deb.dsw
new file mode 100755
index 00000000..c7169534
--- /dev/null
+++ b/CPP/7zip/Archive/Deb/Deb.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Deb"=.\Deb.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Archive/Deb/DebHandler.cpp b/CPP/7zip/Archive/Deb/DebHandler.cpp
new file mode 100755
index 00000000..8728cec8
--- /dev/null
+++ b/CPP/7zip/Archive/Deb/DebHandler.cpp
@@ -0,0 +1,255 @@
+// DebHandler.cpp
+
+#include "StdAfx.h"
+
+#include "DebHandler.h"
+#include "DebIn.h"
+
+#include "Common/Defs.h"
+#include "Common/StringConvert.h"
+#include "Common/NewHandler.h"
+#include "Common/ComTry.h"
+
+#include "Windows/Time.h"
+#include "Windows/PropVariant.h"
+
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/LimitedStreams.h"
+
+#include "../../Compress/Copy/CopyCoder.h"
+
+#include "../Common/ItemNameUtils.h"
+
+using namespace NWindows;
+using namespace NTime;
+
+namespace NArchive {
+namespace NDeb {
+
+STATPROPSTG kProperties[] =
+{
+ { NULL, kpidPath, VT_BSTR},
+ // { NULL, kpidIsFolder, VT_BOOL},
+ { NULL, kpidSize, VT_UI8},
+ { NULL, kpidPackedSize, VT_UI8},
+ { NULL, kpidLastWriteTime, VT_FILETIME}
+};
+
+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;
+ *name = 0;
+ 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::Open(IInStream *stream,
+ const UInt64 * /* maxCheckStartPosition */,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ COM_TRY_BEGIN
+ {
+ CInArchive archive;
+ if(archive.Open(stream) != S_OK)
+ return S_FALSE;
+ _items.Clear();
+
+ if (openArchiveCallback != NULL)
+ {
+ RINOK(openArchiveCallback->SetTotal(NULL, NULL));
+ UInt64 numFiles = _items.Size();
+ RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
+ }
+
+ for (;;)
+ {
+ CItemEx itemInfo;
+ bool filled;
+ HRESULT result = archive.GetNextItem(filled, itemInfo);
+ if (result == S_FALSE)
+ return S_FALSE;
+ if (result != S_OK)
+ return S_FALSE;
+ if (!filled)
+ break;
+ _items.Add(itemInfo);
+ archive.SkeepData(itemInfo.Size);
+ if (openArchiveCallback != NULL)
+ {
+ UInt64 numFiles = _items.Size();
+ RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
+ }
+ }
+ _inStream = stream;
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ _inStream.Release();
+ _items.Clear();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = _items.Size();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant propVariant;
+ const CItemEx &item = _items[index];
+
+ switch(propID)
+ {
+ case kpidPath:
+ propVariant = (const wchar_t *)NItemName::GetOSName2(
+ MultiByteToUnicodeString(item.Name, CP_OEMCP));
+ break;
+ case kpidIsFolder:
+ propVariant = false;
+ break;
+ case kpidSize:
+ case kpidPackedSize:
+ propVariant = item.Size;
+ break;
+ case kpidLastWriteTime:
+ {
+ FILETIME utcFileTime;
+ if (item.ModificationTime != 0)
+ NTime::UnixTimeToFileTime(item.ModificationTime, utcFileTime);
+ else
+ {
+ utcFileTime.dwLowDateTime = 0;
+ utcFileTime.dwHighDateTime = 0;
+ }
+ propVariant = utcFileTime;
+ break;
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
+ Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ bool allFilesMode = (numItems == UInt32(-1));
+ if (allFilesMode)
+ numItems = _items.Size();
+ if(numItems == 0)
+ return S_OK;
+ bool testMode = (_aTestMode != 0);
+ UInt64 totalSize = 0;
+ UInt32 i;
+ for(i = 0; i < numItems; i++)
+ totalSize += _items[allFilesMode ? i : indices[i]].Size;
+ extractCallback->SetTotal(totalSize);
+
+ UInt64 currentTotalSize = 0;
+ UInt64 currentItemSize;
+
+ CMyComPtr<ICompressCoder> copyCoder;
+
+ 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];
+ const CItemEx &itemInfo = _items[index];
+
+ RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
+
+ currentItemSize = itemInfo.Size;
+
+ if(!testMode && (!realOutStream))
+ {
+ continue;
+ }
+ RINOK(extractCallback->PrepareOperation(askMode));
+ {
+ if (testMode)
+ {
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ continue;
+ }
+
+ RINOK(_inStream->Seek(itemInfo.GetDataPosition(), STREAM_SEEK_SET, NULL));
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+ CMyComPtr<ISequentialInStream> inStream(streamSpec);
+ streamSpec->SetStream(_inStream);
+ streamSpec->Init(itemInfo.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 == NULL)
+ {
+ copyCoder = new NCompress::CCopyCoder;
+ }
+ try
+ {
+ RINOK(copyCoder->Code(inStream, realOutStream,
+ NULL, NULL, compressProgress));
+ }
+ catch(...)
+ {
+ realOutStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ realOutStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ }
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+}}
diff --git a/CPP/7zip/Archive/Deb/DebHandler.h b/CPP/7zip/Archive/Deb/DebHandler.h
new file mode 100755
index 00000000..47de0224
--- /dev/null
+++ b/CPP/7zip/Archive/Deb/DebHandler.h
@@ -0,0 +1,47 @@
+// DebHandler.h
+
+#ifndef __DEB_HANDLER_H
+#define __DEB_HANDLER_H
+
+#include "Common/MyCom.h"
+#include "../IArchive.h"
+
+#include "DebItem.h"
+
+namespace NArchive {
+namespace NDeb {
+
+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:
+ CObjectVector<CItemEx> _items;
+ CMyComPtr<IInStream> _inStream;
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Deb/DebHeader.cpp b/CPP/7zip/Archive/Deb/DebHeader.cpp
new file mode 100755
index 00000000..dce00e1b
--- /dev/null
+++ b/CPP/7zip/Archive/Deb/DebHeader.cpp
@@ -0,0 +1,13 @@
+// Archive/Deb/Header.h
+
+#include "StdAfx.h"
+
+#include "DebHeader.h"
+
+namespace NArchive {
+namespace NDeb {
+namespace NHeader {
+
+const char *kSignature = "!<arch>\n";
+
+}}}
diff --git a/CPP/7zip/Archive/Deb/DebHeader.h b/CPP/7zip/Archive/Deb/DebHeader.h
new file mode 100755
index 00000000..c2884000
--- /dev/null
+++ b/CPP/7zip/Archive/Deb/DebHeader.h
@@ -0,0 +1,38 @@
+// Archive/Deb/Header.h
+
+#ifndef __ARCHIVE_DEB_HEADER_H
+#define __ARCHIVE_DEB_HEADER_H
+
+#include "Common/Types.h"
+
+namespace NArchive {
+namespace NDeb {
+
+namespace NHeader
+{
+ const int kSignatureLen = 8;
+ extern const char *kSignature;
+ const int kNameSize = 16;
+ const int kTimeSize = 12;
+ const int kModeSize = 8;
+ const int kSizeSize = 10;
+
+ /*
+ struct CHeader
+ {
+ char Name[kNameSize];
+ char ModificationTime[kTimeSize];
+ char Number0[6];
+ char Number1[6];
+ char Mode[kModeSize];
+ char Size[kSizeSize];
+ char Quote;
+ char NewLine;
+ };
+ */
+ const int kHeaderSize = kNameSize + kTimeSize + 6 + 6 + kModeSize + kSizeSize + 1 + 1;
+}
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Deb/DebIn.cpp b/CPP/7zip/Archive/Deb/DebIn.cpp
new file mode 100755
index 00000000..c2221d12
--- /dev/null
+++ b/CPP/7zip/Archive/Deb/DebIn.cpp
@@ -0,0 +1,165 @@
+// Archive/DebIn.cpp
+
+#include "StdAfx.h"
+
+#include "DebIn.h"
+#include "DebHeader.h"
+
+#include "Common/StringToInt.h"
+#include "Windows/Defs.h"
+
+#include "../../Common/StreamUtils.h"
+
+namespace NArchive {
+namespace NDeb {
+
+using namespace NHeader;
+
+HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
+{
+ RINOK(ReadStream(m_Stream, data, size, &processedSize));
+ m_Position += processedSize;
+ return S_OK;
+}
+
+HRESULT CInArchive::Open(IInStream *inStream)
+{
+ RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position));
+ char signature[kSignatureLen];
+ UInt32 processedSize;
+ RINOK(ReadStream(inStream, signature, kSignatureLen, &processedSize));
+ m_Position += processedSize;
+ if (processedSize != kSignatureLen)
+ return S_FALSE;
+ if (memcmp(signature, kSignature, kSignatureLen) != 0)
+ return S_FALSE;
+ m_Stream = inStream;
+ return S_OK;
+}
+
+static void MyStrNCpy(char *dest, const char *src, int size)
+{
+ for (int i = 0; i < size; i++)
+ {
+ char c = src[i];
+ dest[i] = c;
+ if (c == 0)
+ break;
+ }
+}
+
+static bool OctalToNumber(const char *s, int size, UInt64 &res)
+{
+ char sz[32];
+ MyStrNCpy(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 DecimalToNumber(const char *s, int size, UInt64 &res)
+{
+ char sz[32];
+ MyStrNCpy(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 bool DecimalToNumber32(const char *s, int size, UInt32 &res)
+{
+ UInt64 res64;
+ if (!DecimalToNumber(s, size, res64))
+ return false;
+ res = (UInt32)res64;
+ return (res64 <= 0xFFFFFFFF);
+}
+
+#define RIF(x) { if (!(x)) return S_FALSE; }
+
+
+HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item)
+{
+ filled = false;
+
+ char header[NHeader::kHeaderSize];
+ const char *cur = header;
+
+ UInt32 processedSize;
+ item.HeaderPosition = m_Position;
+ RINOK(ReadBytes(header, sizeof(header), processedSize));
+ if (processedSize < sizeof(header))
+ return S_OK;
+
+ char tempString[kNameSize + 1];
+ MyStrNCpy(tempString, cur, kNameSize);
+ cur += kNameSize;
+ tempString[kNameSize] = '\0';
+ item.Name = tempString;
+ item.Name.Trim();
+
+ for (int i = 0; i < item.Name.Length(); i++)
+ if (((Byte)item.Name[i]) < 0x20)
+ return S_FALSE;
+
+ RIF(DecimalToNumber32(cur, kTimeSize, item.ModificationTime));
+ cur += kTimeSize;
+
+ cur += 6 + 6;
+
+ RIF(OctalToNumber32(cur, kModeSize, item.Mode));
+ cur += kModeSize;
+
+ RIF(DecimalToNumber(cur, kSizeSize, item.Size));
+ cur += kSizeSize;
+
+ filled = true;
+ return S_OK;
+}
+
+HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
+{
+ for (;;)
+ {
+ RINOK(GetNextItemReal(filled, item));
+ if (!filled)
+ return S_OK;
+ if (item.Name.CompareNoCase("debian-binary") != 0)
+ return S_OK;
+ if (item.Size != 4)
+ return S_OK;
+ SkeepData(item.Size);
+ }
+}
+
+HRESULT CInArchive::Skeep(UInt64 numBytes)
+{
+ UInt64 newPostion;
+ RINOK(m_Stream->Seek(numBytes, STREAM_SEEK_CUR, &newPostion));
+ m_Position += numBytes;
+ if (m_Position != newPostion)
+ return E_FAIL;
+ return S_OK;
+}
+
+HRESULT CInArchive::SkeepData(UInt64 dataSize)
+{
+ return Skeep((dataSize + 1) & (~((UInt64)0x1)));
+}
+
+}}
diff --git a/CPP/7zip/Archive/Deb/DebIn.h b/CPP/7zip/Archive/Deb/DebIn.h
new file mode 100755
index 00000000..c1b72b6e
--- /dev/null
+++ b/CPP/7zip/Archive/Deb/DebIn.h
@@ -0,0 +1,29 @@
+// Archive/DebIn.h
+
+#ifndef __ARCHIVE_DEB_IN_H
+#define __ARCHIVE_DEB_IN_H
+
+#include "Common/MyCom.h"
+#include "../../IStream.h"
+#include "DebItem.h"
+
+namespace NArchive {
+namespace NDeb {
+
+class CInArchive
+{
+ CMyComPtr<IInStream> m_Stream;
+ UInt64 m_Position;
+
+ HRESULT ReadBytes(void *data, UInt32 size, UInt32 &processedSize);
+ HRESULT GetNextItemReal(bool &filled, CItemEx &itemInfo);
+ HRESULT Skeep(UInt64 numBytes);
+public:
+ HRESULT Open(IInStream *inStream);
+ HRESULT GetNextItem(bool &filled, CItemEx &itemInfo);
+ HRESULT SkeepData(UInt64 dataSize);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Deb/DebItem.h b/CPP/7zip/Archive/Deb/DebItem.h
new file mode 100755
index 00000000..f587f3f5
--- /dev/null
+++ b/CPP/7zip/Archive/Deb/DebItem.h
@@ -0,0 +1,32 @@
+// Archive/Deb/ItemInfo.h
+
+#ifndef __ARCHIVE_DEB_ITEMINFO_H
+#define __ARCHIVE_DEB_ITEMINFO_H
+
+#include "Common/Types.h"
+#include "Common/String.h"
+#include "DebHeader.h"
+
+namespace NArchive {
+namespace NDeb {
+
+class CItem
+{
+public:
+ AString Name;
+ UInt64 Size;
+ UInt32 ModificationTime;
+ UInt32 Mode;
+};
+
+class CItemEx: public CItem
+{
+public:
+ UInt64 HeaderPosition;
+ UInt64 GetDataPosition() const { return HeaderPosition + NHeader::kHeaderSize; };
+ // UInt64 GetFullSize() const { return NFileHeader::kRecordSize + Size; };
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Deb/DllExports.cpp b/CPP/7zip/Archive/Deb/DllExports.cpp
new file mode 100755
index 00000000..fe320531
--- /dev/null
+++ b/CPP/7zip/Archive/Deb/DllExports.cpp
@@ -0,0 +1,73 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+#include "DebHandler.h"
+#include "../../ICoder.h"
+
+// {23170F69-40C1-278A-1000-000110EC0000}
+DEFINE_GUID(CLSID_CDebHandler,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xEC, 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_CDebHandler)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ if (*interfaceID != IID_IInArchive)
+ return E_NOINTERFACE;
+ CMyComPtr<IInArchive> inArchive = (IInArchive *)new NArchive::NDeb::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"Deb";
+ break;
+ case NArchive::kClassID:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CDebHandler, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NArchive::kExtension:
+ propVariant = L"deb";
+ break;
+ case NArchive::kUpdate:
+ propVariant = false;
+ break;
+ case NArchive::kKeepName:
+ propVariant = false;
+ break;
+ case NArchive::kStartSignature:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)NArchive::NDeb::NHeader::kSignature,
+ NArchive::NDeb::NHeader::kSignatureLen)) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/CPP/7zip/Archive/Deb/StdAfx.cpp b/CPP/7zip/Archive/Deb/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Archive/Deb/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Archive/Deb/StdAfx.h b/CPP/7zip/Archive/Deb/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Archive/Deb/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Archive/Deb/deb.ico b/CPP/7zip/Archive/Deb/deb.ico
new file mode 100755
index 00000000..97a08654
--- /dev/null
+++ b/CPP/7zip/Archive/Deb/deb.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Deb/makefile b/CPP/7zip/Archive/Deb/makefile
new file mode 100755
index 00000000..a74f33de
--- /dev/null
+++ b/CPP/7zip/Archive/Deb/makefile
@@ -0,0 +1,54 @@
+PROG = deb.dll
+DEF_FILE = ../Archive.def
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib user32.lib
+
+DEB_OBJS = \
+ $O\DllExports.obj \
+ $O\DebHandler.obj \
+ $O\DebHeader.obj \
+ $O\DebIn.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\NewHandler.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\Vector.obj \
+
+WIN_OBJS = \
+ $O\PropVariant.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\LimitedStreams.obj \
+ $O\ProgressUtils.obj \
+ $O\StreamUtils.obj \
+
+AR_COMMON_OBJS = \
+ $O\ItemNameUtils.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(DEB_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $O\CopyCoder.obj \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(DEB_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)
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/Archive/Deb/resource.rc b/CPP/7zip/Archive/Deb/resource.rc
new file mode 100755
index 00000000..a80edced
--- /dev/null
+++ b/CPP/7zip/Archive/Deb/resource.rc
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("Deb Plugin", "deb")
+
+101 ICON "deb.ico"
diff --git a/CPP/7zip/Archive/GZip/DllExports.cpp b/CPP/7zip/Archive/GZip/DllExports.cpp
new file mode 100755
index 00000000..3bddcfb9
--- /dev/null
+++ b/CPP/7zip/Archive/GZip/DllExports.cpp
@@ -0,0 +1,125 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+#include "../../ICoder.h"
+#include "GZipHandler.h"
+
+// {23170F69-40C1-278A-1000-000110EF0000}
+DEFINE_GUID(CLSID_CGZipHandler,
+0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xEF, 0x00, 0x00);
+
+// {23170F69-40C1-278B-0401-080000000100}
+DEFINE_GUID(CLSID_CCompressDeflateEncoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00);
+
+// {23170F69-40C1-278B-0401-080000000000}
+DEFINE_GUID(CLSID_CCompressDeflateDecoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+HINSTANCE g_hInstance;
+#ifndef _UNICODE
+bool g_IsNT = false;
+static bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+#endif
+
+#ifndef COMPRESS_DEFLATE
+#include "../Common/CodecsPath.h"
+CSysString GetDeflateCodecPath()
+{
+ return GetCodecsFolderPrefix() + TEXT("Deflate.dll");
+}
+#endif
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ g_hInstance = hInstance;
+ #ifndef _UNICODE
+ g_IsNT = IsItWindowsNT();
+ #endif
+ }
+ return TRUE;
+}
+
+STDAPI CreateObject(
+ const GUID *classID,
+ const GUID *interfaceID,
+ void **outObject)
+{
+ COM_TRY_BEGIN
+ *outObject = 0;
+ if (*classID != CLSID_CGZipHandler)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ int needIn = *interfaceID == IID_IInArchive;
+ int needOut = *interfaceID == IID_IOutArchive;
+ if (needIn || needOut)
+ {
+ NArchive::NGZip::CHandler *temp = new NArchive::NGZip::CHandler;
+ if (needIn)
+ {
+ CMyComPtr<IInArchive> inArchive = (IInArchive *)temp;
+ *outObject = inArchive.Detach();
+ }
+ else
+ {
+ CMyComPtr<IOutArchive> outArchive = (IOutArchive *)temp;
+ *outObject = outArchive.Detach();
+ }
+ }
+ else
+ return E_NOINTERFACE;
+ COM_TRY_END
+ return S_OK;
+}
+
+STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
+{
+ NWindows::NCOM::CPropVariant propVariant;
+ switch(propID)
+ {
+ case NArchive::kName:
+ propVariant = L"GZip";
+ break;
+ case NArchive::kClassID:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CGZipHandler, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NArchive::kExtension:
+ propVariant = L"gz gzip tgz tpz";
+ break;
+ case NArchive::kAddExtension:
+ propVariant = L"* * .tar .tar";
+ break;
+ case NArchive::kUpdate:
+ propVariant = true;
+ break;
+ case NArchive::kKeepName:
+ propVariant = true;
+ break;
+ case NArchive::kStartSignature:
+ {
+ const unsigned char sig[] = { 0x1F, 0x8B };
+ if ((value->bstrVal = ::SysAllocStringByteLen((const char *)sig, 2)) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/CPP/7zip/Archive/GZip/GZip.dsp b/CPP/7zip/Archive/GZip/GZip.dsp
new file mode 100755
index 00000000..3af06b46
--- /dev/null
+++ b/CPP/7zip/Archive/GZip/GZip.dsp
@@ -0,0 +1,321 @@
+# Microsoft Developer Studio Project File - Name="GZip" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=GZip - 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 "GZip.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 "GZip.mak" CFG="GZip - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "GZip - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "GZip - 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)" == "GZip - 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 "GZIP_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GZIP_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\gz.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "GZip - 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 "GZIP_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 "GZIP_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\gz.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "GZip - Win32 Release"
+# Name "GZip - 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=.\GZip.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "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\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\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\StringToInt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringToInt.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# End Group
+# Begin Group "Compression"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.h
+# End Source File
+# End Group
+# Begin Group "Engine"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\GZipHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\GZipHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\GZipHandlerOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\GZipHeader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\GZipHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\GZipIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\GZipIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\GZipItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\GZipOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\GZipOut.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\GZipUpdate.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\GZipUpdate.h
+# End Source File
+# End Group
+# Begin Group "7zip Common"
+
+# PROP Default_Filter ""
+# 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"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Common\CodecsPath.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CodecsPath.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CoderLoader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\InStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\InStreamWithCRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\OutStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\OutStreamWithCRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ParseProperties.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ParseProperties.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\gz.ico
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/Archive/GZip/GZip.dsw b/CPP/7zip/Archive/GZip/GZip.dsw
new file mode 100755
index 00000000..5ff50d2c
--- /dev/null
+++ b/CPP/7zip/Archive/GZip/GZip.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "GZip"=.\GZip.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Archive/GZip/GZipHandler.cpp b/CPP/7zip/Archive/GZip/GZipHandler.cpp
new file mode 100755
index 00000000..ff592324
--- /dev/null
+++ b/CPP/7zip/Archive/GZip/GZipHandler.cpp
@@ -0,0 +1,361 @@
+// GZipHandler.cpp
+
+#include "StdAfx.h"
+
+#include "GZipHandler.h"
+
+#include "Common/Defs.h"
+#include "Common/CRC.h"
+#include "Common/StringConvert.h"
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+#include "Windows/Time.h"
+
+#include "../../ICoder.h"
+#include "../../Common/ProgressUtils.h"
+#include "../Common/OutStreamWithCRC.h"
+
+#ifdef COMPRESS_DEFLATE
+#include "../../Compress/Deflate/DeflateDecoder.h"
+#else
+// {23170F69-40C1-278B-0401-080000000000}
+DEFINE_GUID(CLSID_CCompressDeflateDecoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00);
+#include "../Common/CoderLoader.h"
+extern CSysString GetDeflateCodecPath();
+#endif
+
+using namespace NWindows;
+
+namespace NArchive {
+namespace NGZip {
+
+const wchar_t *kHostOS[] =
+{
+ L"FAT",
+ L"AMIGA",
+ L"VMS",
+ L"Unix",
+ L"VM_CMS",
+ L"Atari", // what if it's a minix filesystem? [cjh]
+ L"HPFS", // filesystem used by OS/2 (and NT 3.x)
+ L"Mac",
+ L"Z_System",
+ L"CPM",
+ L"TOPS20", // pkzip 2.50 NTFS
+ L"NTFS", // filesystem used by Windows NT
+ L"QDOS ", // SMS/QDOS
+ L"Acorn", // Archimedes Acorn RISC OS
+ L"VFAT", // filesystem used by Windows 95, NT
+ L"MVS",
+ L"BeOS", // hybrid POSIX/database filesystem
+ // BeBOX or PowerMac
+ L"Tandem",
+ L"THEOS"
+};
+
+static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
+
+static const wchar_t *kUnknownOS = L"Unknown";
+
+/*
+enum // PropID
+{
+ kpidExtraIsPresent = kpidUserDefined,
+ kpidExtraFlags,
+ kpidIsText
+};
+*/
+
+STATPROPSTG kProperties[] =
+{
+ { NULL, kpidPath, VT_BSTR},
+ // { NULL, kpidIsFolder, VT_BOOL},
+ { NULL, kpidSize, VT_UI8},
+ { NULL, kpidPackedSize, VT_UI8},
+
+ { NULL, kpidLastWriteTime, VT_FILETIME},
+ // { NULL, kpidCommented, VT_BOOL},
+ // { NULL, kpidMethod, VT_UI1},
+ { NULL, kpidHostOS, VT_BSTR},
+
+ { NULL, kpidCRC, VT_UI4}
+ // { L"Extra", kpidExtraIsPresent, VT_BOOL}
+ // { L"Extra flags", kpidExtraFlags, VT_UI1},
+ // { L"Is Text", kpidIsText, VT_BOOL},
+};
+
+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)
+{
+ const STATPROPSTG &prop = kProperties[index];
+ *propID = prop.propid;
+ *varType = prop.vt;
+ *name = 0;
+ 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_NOTIMPL;
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = 1;
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant propVariant;
+ switch(propID)
+ {
+ case kpidPath:
+ if (m_Item.NameIsPresent())
+ propVariant = MultiByteToUnicodeString(m_Item.Name, CP_ACP);
+ break;
+ case kpidIsFolder:
+ propVariant = false;
+ break;
+ case kpidLastWriteTime:
+ {
+ FILETIME utcTime;
+ if (m_Item.Time != 0)
+ {
+ NTime::UnixTimeToFileTime((UInt32)m_Item.Time, utcTime);
+ propVariant = utcTime;
+ }
+ else
+ {
+ // utcTime.dwLowDateTime = utcTime.dwHighDateTime = 0;
+ // propVariant = utcTime;
+ }
+ break;
+ }
+ case kpidSize:
+ propVariant = UInt64(m_Item.UnPackSize32);
+ break;
+ case kpidPackedSize:
+ propVariant = m_PackSize;
+ break;
+ case kpidCommented:
+ propVariant = m_Item.CommentIsPresent();
+ break;
+ case kpidHostOS:
+ propVariant = (m_Item.HostOS < kNumHostOSes) ?
+ kHostOS[m_Item.HostOS] : kUnknownOS;
+ break;
+ case kpidMethod:
+ propVariant = m_Item.CompressionMethod;
+ break;
+ case kpidCRC:
+ propVariant = m_Item.FileCRC;
+ break;
+ /*
+ case kpidExtraFlags:
+ propVariant = m_Item.ExtraFlags;
+ break;
+ case kpidIsText:
+ propVariant = m_Item.IsText();
+ break;
+ case kpidExtraIsPresent:
+ propVariant = m_Item.ExtraFieldIsPresent();
+ break;
+ */
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Open(IInStream *inStream,
+ const UInt64 * /* maxCheckStartPosition */,
+ IArchiveOpenCallback * /* openArchiveCallback */)
+{
+ COM_TRY_BEGIN
+ try
+ {
+ CInArchive archive;
+ RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition));
+ RINOK(archive.ReadHeader(inStream, m_Item));
+ m_DataOffset = archive.GetOffset();
+ UInt64 newPosition;
+ RINOK(inStream->Seek(-8, STREAM_SEEK_END, &newPosition));
+ m_PackSize = newPosition - (m_StreamStartPosition + m_DataOffset);
+ if (archive.ReadPostHeader(inStream, m_Item) != S_OK)
+ 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;
+}
+
+STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
+ Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ bool allFilesMode = (numItems == UInt32(-1));
+ if (!allFilesMode)
+ {
+ if (numItems == 0)
+ return S_OK;
+ if (numItems != 1)
+ return E_INVALIDARG;
+ if (indices[0] != 0)
+ return E_INVALIDARG;
+ }
+
+ bool testMode = (_aTestMode != 0);
+
+ extractCallback->SetTotal(m_PackSize);
+
+ UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0;
+
+ RINOK(extractCallback->SetCompleted(&currentTotalPacked));
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ Int32 askMode;
+ askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
+ NArchive::NExtract::NAskMode::kExtract;
+
+ RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
+
+ if(!testMode && !realOutStream)
+ return S_OK;
+
+ extractCallback->PrepareOperation(askMode);
+
+ COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
+ CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
+ outStreamSpec->SetStream(realOutStream);
+ outStreamSpec->Init();
+ realOutStream.Release();
+
+ CLocalProgress *localProgressSpec = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
+ localProgressSpec->Init(extractCallback, true);
+
+ CLocalCompressProgressInfo *localCompressProgressSpec =
+ new CLocalCompressProgressInfo;
+ CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
+
+ #ifndef COMPRESS_DEFLATE
+ CCoderLibrary lib;
+ #endif
+ CMyComPtr<ICompressCoder> deflateDecoder;
+ bool firstItem = true;
+ RINOK(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL));
+ for (;;)
+ {
+ localCompressProgressSpec->Init(progress,
+ &currentTotalPacked,
+ &currentTotalUnPacked);
+
+ CInArchive archive;
+ CItem item;
+ HRESULT result = archive.ReadHeader(m_Stream, item);
+ if (result != S_OK)
+ {
+ if (firstItem)
+ return E_FAIL;
+ outStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK))
+ return S_OK;
+ }
+ firstItem = false;
+
+ UInt64 dataStartPos;
+ RINOK(m_Stream->Seek(0, STREAM_SEEK_CUR, &dataStartPos));
+
+ outStreamSpec->InitCRC();
+
+ switch(item.CompressionMethod)
+ {
+ case NFileHeader::NCompressionMethod::kDeflate:
+ {
+ if(!deflateDecoder)
+ {
+ #ifdef COMPRESS_DEFLATE
+ deflateDecoder = new NCompress::NDeflate::NDecoder::CCOMCoder;
+ #else
+ RINOK(lib.LoadAndCreateCoder(GetDeflateCodecPath(),
+ CLSID_CCompressDeflateDecoder, &deflateDecoder));
+ #endif
+ }
+ try
+ {
+ HRESULT result = deflateDecoder->Code(m_Stream, outStream, NULL, NULL, compressProgress);
+ if (result == S_FALSE)
+ throw "data error";
+ if (result != S_OK)
+ return result;
+ }
+ catch(...)
+ {
+ outStream.Release();
+ RINOK(extractCallback->SetOperationResult(
+ NArchive::NExtract::NOperationResult::kDataError));
+ return S_OK;
+ }
+ break;
+ }
+ default:
+ outStream.Release();
+ RINOK(extractCallback->SetOperationResult(
+ NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+ return S_OK;
+ }
+ CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize;
+ RINOK(deflateDecoder.QueryInterface(IID_ICompressGetInStreamProcessedSize,
+ &getInStreamProcessedSize));
+ UInt64 packSize;
+ RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&packSize));
+ UInt64 pos;
+ RINOK(m_Stream->Seek(dataStartPos + packSize, STREAM_SEEK_SET, &pos));
+
+ currentTotalPacked = pos - m_StreamStartPosition;
+
+ CItem postItem;
+ if (archive.ReadPostHeader(m_Stream, postItem) != S_OK)
+ return E_FAIL;
+ if((outStreamSpec->GetCRC() != postItem.FileCRC))
+ {
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError))
+ break;
+ }
+ }
+ COM_TRY_END
+ return S_OK;
+}
+
+}}
diff --git a/CPP/7zip/Archive/GZip/GZipHandler.h b/CPP/7zip/Archive/GZip/GZipHandler.h
new file mode 100755
index 00000000..9af7e4a4
--- /dev/null
+++ b/CPP/7zip/Archive/GZip/GZipHandler.h
@@ -0,0 +1,79 @@
+// GZip/Handler.h
+
+#ifndef __GZIP_HANDLER_H
+#define __GZIP_HANDLER_H
+
+#include "Common/MyCom.h"
+
+#include "../IArchive.h"
+
+#include "GZipIn.h"
+#include "GZipUpdate.h"
+
+namespace NArchive {
+namespace NGZip {
+
+class CHandler:
+ public IInArchive,
+ public IOutArchive,
+ public ISetProperties,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP3(
+ IInArchive,
+ IOutArchive,
+ ISetProperties)
+
+ STDMETHOD(Open)(IInStream *inStream,
+ 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);
+
+ // IOutArchive
+
+ STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems,
+ IArchiveUpdateCallback *updateCallback);
+
+ STDMETHOD(GetFileTimeType)(UInt32 *timeType);
+
+ // ISetProperties
+ STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
+
+public:
+ CHandler() { InitMethodProperties(); }
+
+private:
+ NArchive::NGZip::CItem m_Item;
+ UInt64 m_StreamStartPosition;
+ UInt64 m_DataOffset;
+ UInt64 m_PackSize;
+ CMyComPtr<IInStream> m_Stream;
+ CCompressionMethodMode m_Method;
+ UInt32 m_Level;
+
+ void InitMethodProperties()
+ {
+ m_Method.NumMatchFinderCyclesDefined = false;
+ m_Level = m_Method.NumPasses = m_Method.NumFastBytes = m_Method.NumMatchFinderCycles = 0xFFFFFFFF;
+ }
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/GZip/GZipHandlerOut.cpp b/CPP/7zip/Archive/GZip/GZipHandlerOut.cpp
new file mode 100755
index 00000000..cc896016
--- /dev/null
+++ b/CPP/7zip/Archive/GZip/GZipHandlerOut.cpp
@@ -0,0 +1,200 @@
+// Archive/GZip/OutHandler.cpp
+
+#include "StdAfx.h"
+
+#include "GZipHandler.h"
+#include "GZipUpdate.h"
+
+#include "Common/StringConvert.h"
+#include "Common/StringToInt.h"
+
+#include "Windows/Time.h"
+#include "Windows/FileFind.h"
+#include "Windows/PropVariant.h"
+
+#include "../../Compress/Copy/CopyCoder.h"
+#include "../Common/ParseProperties.h"
+
+using namespace NWindows;
+using namespace NTime;
+
+namespace NArchive {
+namespace NGZip {
+
+static const UInt32 kNumPassesX1 = 1;
+static const UInt32 kNumPassesX7 = 3;
+static const UInt32 kNumPassesX9 = 10;
+
+static const UInt32 kNumFastBytesX1 = 32;
+static const UInt32 kNumFastBytesX7 = 64;
+static const UInt32 kNumFastBytesX9 = 128;
+
+
+STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType)
+{
+ *timeType = NFileTimeType::kUnix;
+ return S_OK;
+}
+
+static HRESULT CopyStreams(ISequentialInStream *inStream, ISequentialOutStream *outStream)
+{
+ CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
+ return copyCoder->Code(inStream, outStream, NULL, NULL, NULL);
+}
+
+STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
+ IArchiveUpdateCallback *updateCallback)
+{
+ if (numItems != 1)
+ return E_INVALIDARG;
+
+ UInt64 size;
+ Int32 newData;
+ Int32 newProperties;
+ UInt32 indexInArchive;
+ UInt32 itemIndex = 0;
+ if (!updateCallback)
+ return E_FAIL;
+ RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProperties, &indexInArchive));
+
+ CItem newItem = m_Item;
+ newItem.ExtraFlags = 0;
+ newItem.Flags = 0;
+ if (IntToBool(newProperties))
+ {
+ UInt32 attributes;
+ FILETIME utcTime;
+ UString name;
+ bool isDirectory;
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(itemIndex, kpidAttributes, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ attributes = 0;
+ else if (propVariant.vt != VT_UI4)
+ return E_INVALIDARG;
+ else
+ attributes = propVariant.ulVal;
+ }
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(itemIndex, kpidLastWriteTime, &propVariant));
+ if (propVariant.vt != VT_FILETIME)
+ return E_INVALIDARG;
+ utcTime = propVariant.filetime;
+ }
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(itemIndex, kpidPath, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ name.Empty();
+ else if (propVariant.vt != VT_BSTR)
+ return E_INVALIDARG;
+ else
+ name = propVariant.bstrVal;
+ }
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(itemIndex, kpidIsFolder, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ isDirectory = false;
+ else if (propVariant.vt != VT_BOOL)
+ return E_INVALIDARG;
+ else
+ isDirectory = (propVariant.boolVal != VARIANT_FALSE);
+ }
+ if (isDirectory || NFile::NFind::NAttributes::IsDirectory(attributes))
+ return E_INVALIDARG;
+ if(!FileTimeToUnixTime(utcTime, newItem.Time))
+ return E_INVALIDARG;
+ newItem.Name = UnicodeStringToMultiByte(name, CP_ACP);
+ int dirDelimiterPos = newItem.Name.ReverseFind(CHAR_PATH_SEPARATOR);
+ if (dirDelimiterPos >= 0)
+ newItem.Name = newItem.Name.Mid(dirDelimiterPos + 1);
+
+ newItem.SetNameIsPresentFlag(!newItem.Name.IsEmpty());
+ }
+
+ if (IntToBool(newData))
+ {
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(itemIndex, kpidSize, &propVariant));
+ if (propVariant.vt != VT_UI8)
+ return E_INVALIDARG;
+ size = propVariant.uhVal.QuadPart;
+ }
+ newItem.UnPackSize32 = (UInt32)size;
+
+ UInt32 level = m_Level;
+ if (level == 0xFFFFFFFF)
+ level = 5;
+ if (m_Method.NumPasses == 0xFFFFFFFF)
+ m_Method.NumPasses = (level >= 9 ? kNumPassesX9 :
+ (level >= 7 ? kNumPassesX7 :
+ kNumPassesX1));
+ if (m_Method.NumFastBytes == 0xFFFFFFFF)
+ m_Method.NumFastBytes = (level >= 9 ? kNumFastBytesX9 :
+ (level >= 7 ? kNumFastBytesX7 :
+ kNumFastBytesX1));
+
+ return UpdateArchive(m_Stream, size, outStream, newItem, m_Method, itemIndex, updateCallback);
+ }
+
+ if (indexInArchive != 0)
+ return E_INVALIDARG;
+
+ if (IntToBool(newProperties))
+ {
+ COutArchive outArchive;
+ outArchive.Create(outStream);
+ outArchive.WriteHeader(newItem);
+ RINOK(m_Stream->Seek(m_StreamStartPosition + m_DataOffset, STREAM_SEEK_SET, NULL));
+ }
+ else
+ {
+ RINOK(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL));
+ }
+ return CopyStreams(m_Stream, outStream);
+}
+
+STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
+{
+ InitMethodProperties();
+ for (int i = 0; i < numProperties; i++)
+ {
+ UString name = names[i];
+ name.MakeUpper();
+ const PROPVARIANT &prop = values[i];
+ if (name[0] == L'X')
+ {
+ UInt32 level = 9;
+ RINOK(ParsePropValue(name.Mid(1), prop, level));
+ m_Level = level;
+ }
+ else if (name.Left(4) == L"PASS")
+ {
+ UInt32 num = kNumPassesX9;
+ RINOK(ParsePropValue(name.Mid(4), prop, num));
+ m_Method.NumPasses = num;
+ }
+ else if (name.Left(2) == L"FB")
+ {
+ UInt32 num = kNumFastBytesX9;
+ RINOK(ParsePropValue(name.Mid(2), prop, num));
+ m_Method.NumFastBytes = num;
+ }
+ else if (name.Left(2) == L"MC")
+ {
+ UInt32 num = 0xFFFFFFFF;
+ RINOK(ParsePropValue(name.Mid(2), prop, num));
+ m_Method.NumMatchFinderCycles = num;
+ m_Method.NumMatchFinderCyclesDefined = true;
+ }
+ else
+ return E_INVALIDARG;
+ }
+ return S_OK;
+}
+
+}}
diff --git a/CPP/7zip/Archive/GZip/GZipHeader.cpp b/CPP/7zip/Archive/GZip/GZipHeader.cpp
new file mode 100755
index 00000000..5e697fa9
--- /dev/null
+++ b/CPP/7zip/Archive/GZip/GZipHeader.cpp
@@ -0,0 +1,20 @@
+// Archive/GZip/Header.h
+
+#include "StdAfx.h"
+
+#include "GZipHeader.h"
+
+namespace NArchive {
+namespace NGZip {
+
+extern UInt16 kSignature = 0x8B1F + 1;
+
+static class CMarkersInitializer
+{
+public:
+ CMarkersInitializer()
+ { kSignature--; }
+} g_MarkerInitializer;
+
+}}
+
diff --git a/CPP/7zip/Archive/GZip/GZipHeader.h b/CPP/7zip/Archive/GZip/GZipHeader.h
new file mode 100755
index 00000000..e83548eb
--- /dev/null
+++ b/CPP/7zip/Archive/GZip/GZipHeader.h
@@ -0,0 +1,85 @@
+// Archive/GZip/Header.h
+
+#ifndef __ARCHIVE_GZIP_HEADER_H
+#define __ARCHIVE_GZIP_HEADER_H
+
+#include "Common/Types.h"
+
+namespace NArchive {
+namespace NGZip {
+
+extern UInt16 kSignature;
+static const UInt32 kSignatureSize = 2;
+
+namespace NFileHeader
+{
+ /*
+ struct CBlock
+ {
+ UInt16 Id;
+ Byte CompressionMethod;
+ Byte Flags;
+ UInt32 Time;
+ Byte ExtraFlags;
+ Byte HostOS;
+ };
+ */
+
+ namespace NFlags
+ {
+ const int kDataIsText = 1 << 0;
+ const int kHeaderCRCIsPresent = 1 << 1;
+ const int kExtraIsPresent = 1 << 2;
+ const int kNameIsPresent = 1 << 3;
+ const int kComentIsPresent = 1 << 4;
+ }
+
+ namespace NExtraFlags
+ {
+ enum EEnum
+ {
+ kMaximum = 2,
+ kFastest = 4
+ };
+ }
+
+ namespace NCompressionMethod
+ {
+ const Byte kDeflate = 8;
+ }
+
+ namespace NHostOS
+ {
+ enum EEnum
+ {
+ kFAT = 0, // filesystem used by MS-DOS, OS/2, Win32
+ // pkzip 2.50 (FAT / VFAT / FAT32 file systems)
+ kAMIGA = 1,
+ kVMS = 2, // VAX/VMS
+ kUnix = 3,
+ kVM_CMS = 4,
+ kAtari = 5, // what if it's a minix filesystem? [cjh]
+ kHPFS = 6, // filesystem used by OS/2 (and NT 3.x)
+ kMac = 7,
+ kZ_System = 8,
+ kCPM = 9,
+ kTOPS20 = 10, // pkzip 2.50 NTFS
+ kNTFS = 11, // filesystem used by Windows NT
+ kQDOS = 12, // SMS/QDOS
+ kAcorn = 13, // Archimedes Acorn RISC OS
+ kVFAT = 14, // filesystem used by Windows 95, NT
+ kMVS = 15,
+ kBeOS = 16, // hybrid POSIX/database filesystem
+ // BeBOX or PowerMac
+ kTandem = 17,
+ kTHEOS = 18,
+
+ kUnknown = 255
+ };
+ const int kNumHostSystems = 19;
+ }
+}
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/GZip/GZipIn.cpp b/CPP/7zip/Archive/GZip/GZipIn.cpp
new file mode 100755
index 00000000..2b16d369
--- /dev/null
+++ b/CPP/7zip/Archive/GZip/GZipIn.cpp
@@ -0,0 +1,121 @@
+// Archive/GZipIn.cpp
+
+#include "StdAfx.h"
+
+#include "GZipIn.h"
+
+#include "Common/Defs.h"
+#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(ReadStream(inStream, data, size, &realProcessedSize));
+ m_Position += realProcessedSize;
+ if(realProcessedSize != size)
+ return S_FALSE;
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadByte(ISequentialInStream *inStream, Byte &value)
+{
+ return ReadBytes(inStream, &value, 1);
+}
+
+HRESULT CInArchive::ReadUInt16(ISequentialInStream *inStream, UInt16 &value)
+{
+ value = 0;
+ for (int i = 0; i < 2; i++)
+ {
+ Byte b;
+ RINOK(ReadByte(inStream, b));
+ value |= (UInt16(b) << (8 * i));
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadUInt32(ISequentialInStream *inStream, UInt32 &value)
+{
+ value = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ Byte b;
+ RINOK(ReadByte(inStream, b));
+ value |= (UInt32(b) << (8 * i));
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadZeroTerminatedString(ISequentialInStream *inStream, AString &resString, CCRC &crc)
+{
+ resString.Empty();
+ for (;;)
+ {
+ Byte c;
+ RINOK(ReadByte(inStream, c));
+ crc.UpdateByte(c);
+ if (c == 0)
+ return S_OK;
+ resString += char(c);
+ }
+}
+
+HRESULT CInArchive::ReadHeader(ISequentialInStream *inStream, CItem &item)
+{
+ item.Clear();
+ m_Position = 0;
+
+ UInt16 signature;
+ RINOK(ReadUInt16(inStream, signature));
+ if (signature != kSignature)
+ return S_FALSE;
+ RINOK(ReadByte(inStream, item.CompressionMethod));
+ RINOK(ReadByte(inStream, item.Flags));
+ RINOK(ReadUInt32(inStream, item.Time));
+ RINOK(ReadByte(inStream, item.ExtraFlags));
+ RINOK(ReadByte(inStream, item.HostOS));
+
+ CCRC crc;
+ crc.Update(&signature, 2);
+ crc.UpdateByte(item.CompressionMethod);
+ crc.UpdateByte(item.Flags);
+ crc.UpdateUInt32(item.Time);
+ crc.UpdateByte(item.ExtraFlags);
+ crc.UpdateByte(item.HostOS);
+
+ if (item.ExtraFieldIsPresent())
+ {
+ UInt16 extraSize;
+ RINOK(ReadUInt16(inStream, extraSize));
+ crc.UpdateUInt16(extraSize);
+ item.Extra.SetCapacity(extraSize);
+ RINOK(ReadBytes(inStream, item.Extra, extraSize));
+ crc.Update(item.Extra, extraSize);
+ }
+ if (item.NameIsPresent())
+ RINOK(ReadZeroTerminatedString(inStream, item.Name, crc));
+ if (item.CommentIsPresent())
+ RINOK(ReadZeroTerminatedString(inStream, item.Comment, crc));
+ if (item.HeaderCRCIsPresent())
+ {
+ UInt16 headerCRC;
+ RINOK(ReadUInt16(inStream, headerCRC));
+ if ((UInt16)crc.GetDigest() != headerCRC)
+ return S_FALSE;
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadPostHeader(ISequentialInStream *inStream, CItem &item)
+{
+ RINOK(ReadUInt32(inStream, item.FileCRC));
+ return ReadUInt32(inStream, item.UnPackSize32);
+}
+
+}}
diff --git a/CPP/7zip/Archive/GZip/GZipIn.h b/CPP/7zip/Archive/GZip/GZipIn.h
new file mode 100755
index 00000000..998470e0
--- /dev/null
+++ b/CPP/7zip/Archive/GZip/GZipIn.h
@@ -0,0 +1,31 @@
+// Archive/GZipIn.h
+
+#ifndef __ARCHIVE_GZIP_IN_H
+#define __ARCHIVE_GZIP_IN_H
+
+#include "GZipHeader.h"
+#include "GZipItem.h"
+#include "Common/CRC.h"
+#include "../../IStream.h"
+
+namespace NArchive {
+namespace NGZip {
+
+class CInArchive
+{
+ UInt64 m_Position;
+
+ HRESULT ReadBytes(ISequentialInStream *inStream, void *data, UInt32 size);
+ HRESULT ReadZeroTerminatedString(ISequentialInStream *inStream, AString &resString, CCRC &crc);
+ HRESULT ReadByte(ISequentialInStream *inStream, Byte &value);
+ HRESULT ReadUInt16(ISequentialInStream *inStream, UInt16 &value);
+ HRESULT ReadUInt32(ISequentialInStream *inStream, UInt32 &value);
+public:
+ HRESULT ReadHeader(ISequentialInStream *inStream, CItem &item);
+ HRESULT ReadPostHeader(ISequentialInStream *inStream, CItem &item);
+ UInt64 GetOffset() const { return m_Position; }
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/GZip/GZipItem.h b/CPP/7zip/Archive/GZip/GZipItem.h
new file mode 100755
index 00000000..7006dfb3
--- /dev/null
+++ b/CPP/7zip/Archive/GZip/GZipItem.h
@@ -0,0 +1,59 @@
+// Archive/GZipItem.h
+
+#ifndef __ARCHIVE_GZIP_ITEM_H
+#define __ARCHIVE_GZIP_ITEM_H
+
+#include "Common/Types.h"
+#include "Common/String.h"
+#include "Common/Buffer.h"
+
+namespace NArchive {
+namespace NGZip {
+
+class CItem
+{
+private:
+ bool TestFlag(Byte flag) const { return ((Flags & flag) != 0); }
+public:
+ Byte CompressionMethod;
+ Byte Flags;
+ UInt32 Time;
+ Byte ExtraFlags;
+ Byte HostOS;
+ UInt32 FileCRC;
+ UInt32 UnPackSize32;
+
+ AString Name;
+ AString Comment;
+ CByteBuffer Extra;
+
+ bool IsText() const
+ { return TestFlag(NFileHeader::NFlags::kDataIsText); }
+ bool HeaderCRCIsPresent() const
+ { return TestFlag(NFileHeader::NFlags::kHeaderCRCIsPresent); }
+ bool ExtraFieldIsPresent() const
+ { return TestFlag(NFileHeader::NFlags::kExtraIsPresent); }
+ bool NameIsPresent() const
+ { return TestFlag(NFileHeader::NFlags::kNameIsPresent); }
+ bool CommentIsPresent() const
+ { return TestFlag(NFileHeader::NFlags::kComentIsPresent); }
+
+ void SetNameIsPresentFlag(bool nameIsPresent)
+ {
+ if (nameIsPresent)
+ Flags |= NFileHeader::NFlags::kNameIsPresent;
+ else
+ Flags &= (~NFileHeader::NFlags::kNameIsPresent);
+ }
+
+ void Clear()
+ {
+ Name.Empty();
+ Comment.Empty();;
+ Extra.SetCapacity(0);
+ }
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/GZip/GZipOut.cpp b/CPP/7zip/Archive/GZip/GZipOut.cpp
new file mode 100755
index 00000000..afa8a931
--- /dev/null
+++ b/CPP/7zip/Archive/GZip/GZipOut.cpp
@@ -0,0 +1,69 @@
+// Archive/GZipOut.cpp
+
+#include "StdAfx.h"
+
+#include "GZipOut.h"
+#include "Common/CRC.h"
+#include "Windows/Defs.h"
+#include "../../Common/StreamUtils.h"
+
+namespace NArchive {
+namespace NGZip {
+
+HRESULT COutArchive::WriteBytes(const void *buffer, UInt32 size)
+{
+ UInt32 processedSize;
+ RINOK(WriteStream(m_Stream, buffer, size, &processedSize));
+ if(processedSize != size)
+ return E_FAIL;
+ return S_OK;
+}
+
+HRESULT COutArchive::WriteByte(Byte value)
+{
+ return WriteBytes(&value, 1);
+}
+
+HRESULT COutArchive::WriteUInt16(UInt16 value)
+{
+ for (int i = 0; i < 2; i++)
+ {
+ RINOK(WriteByte((Byte)value));
+ value >>= 8;
+ }
+ return S_OK;
+}
+
+HRESULT COutArchive::WriteUInt32(UInt32 value)
+{
+ for (int i = 0; i < 4; i++)
+ {
+ RINOK(WriteByte((Byte)value));
+ value >>= 8;
+ }
+ return S_OK;
+}
+
+HRESULT COutArchive::WriteHeader(const CItem &item)
+{
+ RINOK(WriteUInt16(kSignature));
+ RINOK(WriteByte(item.CompressionMethod));
+ RINOK(WriteByte((Byte)(item.Flags & NFileHeader::NFlags::kNameIsPresent)));
+ RINOK(WriteUInt32(item.Time));
+ RINOK(WriteByte(item.ExtraFlags));
+ RINOK(WriteByte(item.HostOS));
+ if (item.NameIsPresent())
+ {
+ RINOK(WriteBytes((const char *)item.Name, item.Name.Length()));
+ RINOK(WriteByte(0));
+ }
+ return S_OK;
+}
+
+HRESULT COutArchive::WritePostHeader(const CItem &item)
+{
+ RINOK(WriteUInt32(item.FileCRC));
+ return WriteUInt32(item.UnPackSize32);
+}
+
+}}
diff --git a/CPP/7zip/Archive/GZip/GZipOut.h b/CPP/7zip/Archive/GZip/GZipOut.h
new file mode 100755
index 00000000..a2ba2ebf
--- /dev/null
+++ b/CPP/7zip/Archive/GZip/GZipOut.h
@@ -0,0 +1,29 @@
+// Archive/GZipOut.h
+
+#ifndef __ARCHIVE_GZIP_OUT_H
+#define __ARCHIVE_GZIP_OUT_H
+
+#include "Common/MyCom.h"
+#include "GZipHeader.h"
+#include "GZipItem.h"
+#include "../../IStream.h"
+
+namespace NArchive {
+namespace NGZip {
+
+class COutArchive
+{
+ CMyComPtr<ISequentialOutStream> m_Stream;
+ HRESULT WriteBytes(const void *buffer, UInt32 size);
+ HRESULT WriteByte(Byte value);
+ HRESULT WriteUInt16(UInt16 value);
+ HRESULT WriteUInt32(UInt32 value);
+public:
+ void Create(ISequentialOutStream *outStream) { m_Stream = outStream; }
+ HRESULT WriteHeader(const CItem &item);
+ HRESULT WritePostHeader(const CItem &item);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/GZip/GZipUpdate.cpp b/CPP/7zip/Archive/GZip/GZipUpdate.cpp
new file mode 100755
index 00000000..45e6e985
--- /dev/null
+++ b/CPP/7zip/Archive/GZip/GZipUpdate.cpp
@@ -0,0 +1,120 @@
+// GZipUpdate.cpp
+
+#include "StdAfx.h"
+
+#include "GZipUpdate.h"
+
+#include "Common/Defs.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+
+#include "../../ICoder.h"
+#include "../../Common/ProgressUtils.h"
+#include "../../Compress/Copy/CopyCoder.h"
+
+#include "../Common/InStreamWithCRC.h"
+
+#ifdef COMPRESS_DEFLATE
+#include "../../Compress/Deflate/DeflateEncoder.h"
+#else
+// {23170F69-40C1-278B-0401-080000000100}
+DEFINE_GUID(CLSID_CCompressDeflateEncoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00);
+#include "../Common/CoderLoader.h"
+extern CSysString GetDeflateCodecPath();
+#endif
+
+namespace NArchive {
+namespace NGZip {
+
+static const Byte kHostOS = NFileHeader::NHostOS::kFAT;
+
+HRESULT UpdateArchive(IInStream * /* inStream */,
+ UInt64 unpackSize,
+ ISequentialOutStream *outStream,
+ const CItem &newItem,
+ const CCompressionMethodMode &compressionMethod,
+ int indexInClient,
+ IArchiveUpdateCallback *updateCallback)
+{
+ UInt64 complexity = 0;
+
+ complexity += unpackSize;
+
+ RINOK(updateCallback->SetTotal(complexity));
+
+ #ifndef COMPRESS_DEFLATE
+ CCoderLibrary lib;
+ #endif
+ CMyComPtr<ICompressCoder> deflateEncoder;
+
+ complexity = 0;
+ RINOK(updateCallback->SetCompleted(&complexity));
+
+ CMyComPtr<ISequentialInStream> fileInStream;
+
+ RINOK(updateCallback->GetStream(indexInClient, &fileInStream));
+
+ CSequentialInStreamWithCRC *inStreamSpec = new CSequentialInStreamWithCRC;
+ CMyComPtr<ISequentialInStream> crcStream(inStreamSpec);
+ inStreamSpec->SetStream(fileInStream);
+ inStreamSpec->Init();
+
+ CLocalProgress *localProgressSpec = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
+ localProgressSpec->Init(updateCallback, true);
+
+ CLocalCompressProgressInfo *localCompressProgressSpec =
+ new CLocalCompressProgressInfo;
+ CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
+
+ COutArchive outArchive;
+ outArchive.Create(outStream);
+
+ CItem item = newItem;
+ item.CompressionMethod = NFileHeader::NCompressionMethod::kDeflate;
+ item.ExtraFlags = 0;
+ item.HostOS = kHostOS;
+
+ RINOK(outArchive.WriteHeader(item));
+
+ localCompressProgressSpec->Init(localProgress, &complexity, NULL);
+
+ {
+ #ifdef COMPRESS_DEFLATE
+ deflateEncoder = new NCompress::NDeflate::NEncoder::CCOMCoder;
+ #else
+ RINOK(lib.LoadAndCreateCoder(GetDeflateCodecPath(),
+ CLSID_CCompressDeflateEncoder, &deflateEncoder));
+ #endif
+
+ NWindows::NCOM::CPropVariant properties[] =
+ {
+ compressionMethod.NumPasses,
+ compressionMethod.NumFastBytes,
+ compressionMethod.NumMatchFinderCycles
+ };
+ PROPID propIDs[] =
+ {
+ NCoderPropID::kNumPasses,
+ NCoderPropID::kNumFastBytes,
+ NCoderPropID::kMatchFinderCycles
+ };
+ int numProps = sizeof(propIDs) / sizeof(propIDs[0]);
+ if (!compressionMethod.NumMatchFinderCyclesDefined)
+ numProps--;
+ CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
+ RINOK(deflateEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties));
+ RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, numProps));
+ }
+ RINOK(deflateEncoder->Code(crcStream, outStream, NULL, NULL, compressProgress));
+
+ item.FileCRC = inStreamSpec->GetCRC();
+ item.UnPackSize32 = (UInt32)inStreamSpec->GetSize();
+ RINOK(outArchive.WritePostHeader(item));
+ return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
+}
+
+}}
diff --git a/CPP/7zip/Archive/GZip/GZipUpdate.h b/CPP/7zip/Archive/GZip/GZipUpdate.h
new file mode 100755
index 00000000..c06e8a4c
--- /dev/null
+++ b/CPP/7zip/Archive/GZip/GZipUpdate.h
@@ -0,0 +1,32 @@
+// GZip/Update.h
+
+#ifndef __GZIP_UPDATE_H
+#define __GZIP_UPDATE_H
+
+#include "../IArchive.h"
+
+#include "GZipOut.h"
+#include "GZipItem.h"
+
+namespace NArchive {
+namespace NGZip {
+
+struct CCompressionMethodMode
+{
+ UInt32 NumPasses;
+ UInt32 NumFastBytes;
+ bool NumMatchFinderCyclesDefined;
+ UInt32 NumMatchFinderCycles;
+};
+
+HRESULT UpdateArchive(IInStream *inStream,
+ UInt64 unpackSize,
+ ISequentialOutStream *outStream,
+ const CItem &newItem,
+ const CCompressionMethodMode &compressionMethod,
+ int indexInClient,
+ IArchiveUpdateCallback *updateCallback);
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/GZip/StdAfx.cpp b/CPP/7zip/Archive/GZip/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Archive/GZip/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Archive/GZip/StdAfx.h b/CPP/7zip/Archive/GZip/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Archive/GZip/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Archive/GZip/gz.ico b/CPP/7zip/Archive/GZip/gz.ico
new file mode 100755
index 00000000..f50d8c08
--- /dev/null
+++ b/CPP/7zip/Archive/GZip/gz.ico
Binary files differ
diff --git a/CPP/7zip/Archive/GZip/makefile b/CPP/7zip/Archive/GZip/makefile
new file mode 100755
index 00000000..abc3f1e4
--- /dev/null
+++ b/CPP/7zip/Archive/GZip/makefile
@@ -0,0 +1,60 @@
+PROG = gz.dll
+DEF_FILE = ../Archive.def
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib user32.lib
+
+GZ_OBJS = \
+ $O\GZipHandler.obj \
+ $O\GZipHandlerOut.obj \
+ $O\GZipHeader.obj \
+ $O\GZipIn.obj \
+ $O\GZipOut.obj \
+ $O\GZipUpdate.obj \
+ $O\DllExports.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\CRC.obj \
+ $O\NewHandler.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+
+WIN_OBJS = \
+ $O\DLL.obj \
+ $O\PropVariant.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\ProgressUtils.obj \
+ $O\StreamUtils.obj \
+
+AR_COMMON_OBJS = \
+ $O\CodecsPath.obj \
+ $O\InStreamWithCRC.obj \
+ $O\OutStreamWithCRC.obj \
+ $O\ParseProperties.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(GZ_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $O\CopyCoder.obj \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(GZ_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)
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/Archive/GZip/resource.rc b/CPP/7zip/Archive/GZip/resource.rc
new file mode 100755
index 00000000..29fb4825
--- /dev/null
+++ b/CPP/7zip/Archive/GZip/resource.rc
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("GZip Plugin", "gz")
+
+101 ICON "gz.ico"
diff --git a/CPP/7zip/Archive/IArchive.h b/CPP/7zip/Archive/IArchive.h
new file mode 100755
index 00000000..d6cbe804
--- /dev/null
+++ b/CPP/7zip/Archive/IArchive.h
@@ -0,0 +1,173 @@
+// IArchive.h
+
+#ifndef __IARCHIVE_H
+#define __IARCHIVE_H
+
+#include "../IStream.h"
+#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
+ {
+ kWindows,
+ kUnix,
+ kDOS
+ };
+}
+
+namespace NArchive
+{
+ enum
+ {
+ kName = 0,
+ kClassID,
+ kExtension,
+ kAddExtension,
+ kUpdate,
+ kKeepName,
+ kStartSignature,
+ kFinishSignature,
+ kAssociate
+ };
+
+ namespace NExtract
+ {
+ namespace NAskMode
+ {
+ enum
+ {
+ kExtract = 0,
+ kTest,
+ kSkip,
+ };
+ }
+ namespace NOperationResult
+ {
+ enum
+ {
+ kOK = 0,
+ kUnSupportedMethod,
+ kDataError,
+ kCRCError,
+ };
+ }
+ }
+ namespace NUpdate
+ {
+ namespace NOperationResult
+ {
+ enum
+ {
+ kOK = 0,
+ kError,
+ };
+ }
+ }
+}
+
+ARCHIVE_INTERFACE(IArchiveOpenCallback, 0x10)
+{
+ STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes) PURE;
+ STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes) PURE;
+};
+
+
+ARCHIVE_INTERFACE_SUB(IArchiveExtractCallback, IProgress, 0x20)
+{
+ STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream,
+ Int32 askExtractMode) PURE;
+ // GetStream OUT: S_OK - OK, S_FALSE - skeep this file
+ STDMETHOD(PrepareOperation)(Int32 askExtractMode) PURE;
+ STDMETHOD(SetOperationResult)(Int32 resultEOperationResult) PURE;
+};
+
+
+ARCHIVE_INTERFACE(IArchiveOpenVolumeCallback, 0x30)
+{
+ STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) PURE;
+ STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) PURE;
+};
+
+
+ARCHIVE_INTERFACE(IInArchiveGetStream, 0x40)
+{
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) PURE;
+};
+
+
+ARCHIVE_INTERFACE(IArchiveOpenSetSubArchiveName, 0x50)
+{
+ STDMETHOD(SetSubArchiveName)(const wchar_t *name) PURE;
+};
+
+
+ARCHIVE_INTERFACE(IInArchive, 0x60)
+{
+ STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition,
+ IArchiveOpenCallback *openArchiveCallback) PURE;
+ STDMETHOD(Close)() PURE;
+ STDMETHOD(GetNumberOfItems)(UInt32 *numItems) PURE;
+ 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;
+
+ STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) PURE;
+ STDMETHOD(GetPropertyInfo)(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType) PURE;
+
+ STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties) PURE;
+ STDMETHOD(GetArchivePropertyInfo)(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType) PURE;
+};
+
+
+ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback, IProgress, 0x80)
+{
+ STDMETHOD(GetUpdateItemInfo)(UInt32 index,
+ Int32 *newData, // 1 - new data, 0 - old data
+ Int32 *newProperties, // 1 - new properties, 0 - old properties
+ UInt32 *indexInArchive // -1 if there is no in archive, or if doesn't matter
+ ) PURE;
+ STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE;
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) PURE;
+ STDMETHOD(SetOperationResult)(Int32 operationResult) PURE;
+};
+
+
+ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82)
+{
+ STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size) PURE;
+ STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream) PURE;
+};
+
+
+ARCHIVE_INTERFACE(IOutArchive, 0xA0)
+{
+ STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems,
+ IArchiveUpdateCallback *updateCallback) PURE;
+ STDMETHOD(GetFileTimeType)(UInt32 *type) PURE;
+};
+
+
+ARCHIVE_INTERFACE(ISetProperties, 0x03)
+{
+ STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) PURE;
+};
+
+
+#endif
diff --git a/CPP/7zip/Archive/Iso/DllExports.cpp b/CPP/7zip/Archive/Iso/DllExports.cpp
new file mode 100755
index 00000000..f746eea1
--- /dev/null
+++ b/CPP/7zip/Archive/Iso/DllExports.cpp
@@ -0,0 +1,88 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+#include "../../ICoder.h"
+#include "IsoHandler.h"
+
+// {23170F69-40C1-278A-1000-000110E70000}
+DEFINE_GUID(CLSID_CIsoHandler,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xE7, 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_CIsoHandler)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ int needIn = *interfaceID == IID_IInArchive;
+ // int needOut = *interfaceID == IID_IOutArchive;
+ if (needIn /*|| needOut */)
+ {
+ NArchive::NIso::CHandler *temp = new NArchive::NIso::CHandler;
+ if (needIn)
+ {
+ CMyComPtr<IInArchive> inArchive = (IInArchive *)temp;
+ *outObject = inArchive.Detach();
+ }
+ /*
+ else
+ {
+ CMyComPtr<IOutArchive> outArchive = (IOutArchive *)temp;
+ *outObject = outArchive.Detach();
+ }
+ */
+ }
+ else
+ return E_NOINTERFACE;
+ COM_TRY_END
+ return S_OK;
+}
+
+STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
+{
+ NWindows::NCOM::CPropVariant propVariant;
+ switch(propID)
+ {
+ case NArchive::kName:
+ propVariant = L"Iso";
+ break;
+ case NArchive::kClassID:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CIsoHandler, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NArchive::kExtension:
+ propVariant = L"iso";
+ break;
+ case NArchive::kUpdate:
+ propVariant = false;
+ break;
+ case NArchive::kKeepName:
+ propVariant = false;
+ break;
+ case NArchive::kStartSignature:
+ {
+ const unsigned char sig[] = { 'C', 'D', '0', '0', '1', 0x1 };
+ if ((value->bstrVal = ::SysAllocStringByteLen((const char *)sig, 7)) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/CPP/7zip/Archive/Iso/Iso.dsp b/CPP/7zip/Archive/Iso/Iso.dsp
new file mode 100755
index 00000000..a204e9cd
--- /dev/null
+++ b/CPP/7zip/Archive/Iso/Iso.dsp
@@ -0,0 +1,273 @@
+# Microsoft Developer Studio Project File - Name="Iso" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=Iso - 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 "Iso.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 "Iso.mak" CFG="Iso - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Iso - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Iso - 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)" == "Iso - 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 "TAR_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TAR_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\Iso.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Iso - 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 "TAR_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 "TAR_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\Iso.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "Iso - Win32 Release"
+# Name "Iso - 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=.\Iso.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "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\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.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\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 "Compress"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.h
+# End Source File
+# End Group
+# Begin Group "Engine"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\IsoHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\IsoHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\IsoHeader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\IsoHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\IsoIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\IsoIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\IsoItem.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 "7zip Common"
+
+# PROP Default_Filter ""
+# 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\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
+# End Target
+# End Project
diff --git a/CPP/7zip/Archive/Iso/Iso.dsw b/CPP/7zip/Archive/Iso/Iso.dsw
new file mode 100755
index 00000000..27728dd2
--- /dev/null
+++ b/CPP/7zip/Archive/Iso/Iso.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Iso"=.\Iso.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Archive/Iso/Iso.ico b/CPP/7zip/Archive/Iso/Iso.ico
new file mode 100755
index 00000000..2538e408
--- /dev/null
+++ b/CPP/7zip/Archive/Iso/Iso.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Iso/IsoHandler.cpp b/CPP/7zip/Archive/Iso/IsoHandler.cpp
new file mode 100755
index 00000000..1831e913
--- /dev/null
+++ b/CPP/7zip/Archive/Iso/IsoHandler.cpp
@@ -0,0 +1,301 @@
+// Iso/Handler.cpp
+
+#include "StdAfx.h"
+
+#include "IsoHandler.h"
+
+#include "Common/Defs.h"
+#include "Common/StringConvert.h"
+#include "Common/IntToString.h"
+#include "Common/NewHandler.h"
+#include "Common/ComTry.h"
+
+#include "Windows/Time.h"
+#include "Windows/PropVariant.h"
+
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/LimitedStreams.h"
+#include "../../Compress/Copy/CopyCoder.h"
+
+#include "../Common/ItemNameUtils.h"
+
+using namespace NWindows;
+using namespace NTime;
+
+namespace NArchive {
+namespace NIso {
+
+STATPROPSTG kProperties[] =
+{
+ { NULL, kpidPath, VT_BSTR},
+ { NULL, kpidIsFolder, VT_BOOL},
+ { NULL, kpidSize, VT_UI8},
+ { NULL, kpidPackedSize, VT_UI8},
+ { NULL, kpidLastWriteTime, VT_FILETIME}
+};
+
+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;
+ *name = 0;
+ 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::Open(IInStream *stream,
+ const UInt64 * /* maxCheckStartPosition */,
+ IArchiveOpenCallback * /* openArchiveCallback */)
+{
+ COM_TRY_BEGIN
+ Close();
+ // try
+ {
+ if(_archive.Open(stream) != S_OK)
+ return S_FALSE;
+ _inStream = stream;
+ }
+ // catch(...) { return S_FALSE; }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ _archive.Clear();
+ _inStream.Release();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = _archive.Refs.Size() + _archive.BootEntries.Size();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant propVariant;
+ if (index >= (UInt32)_archive.Refs.Size())
+ {
+ index -= _archive.Refs.Size();
+ const CBootInitialEntry &be = _archive.BootEntries[index];
+ switch(propID)
+ {
+ case kpidPath:
+ {
+ // wchar_t name[32];
+ // ConvertUInt64ToString(index + 1, name);
+ UString s = L"[BOOT]" WSTRING_PATH_SEPARATOR;
+ // s += name;
+ // s += L"-";
+ s += be.GetName();
+ propVariant = (const wchar_t *)s;
+ break;
+ }
+ case kpidIsFolder:
+ propVariant = false;
+ break;
+ case kpidSize:
+ case kpidPackedSize:
+ {
+ propVariant = (UInt64)_archive.GetBootItemSize(index);
+ break;
+ }
+ }
+ }
+ else
+ {
+ const CRef &ref = _archive.Refs[index];
+ const CDir &item = ref.Dir->_subItems[ref.Index];
+ switch(propID)
+ {
+ case kpidPath:
+ if (item.FileId.GetCapacity() >= 0)
+ {
+ UString s;
+ if (_archive.IsJoliet())
+ s = item.GetPathU();
+ else
+ s = MultiByteToUnicodeString(item.GetPath(_archive.IsSusp, _archive.SuspSkipSize), CP_OEMCP);
+
+ int pos = s.ReverseFind(L';');
+ if (pos >= 0 && pos == s.Length() - 2)
+ if (s[s.Length() - 1] == L'1')
+ s = s.Left(pos);
+ if (!s.IsEmpty())
+ if (s[s.Length() - 1] == L'.')
+ s = s.Left(s.Length() - 1);
+ propVariant = (const wchar_t *)NItemName::GetOSName2(s);
+ }
+ break;
+ case kpidIsFolder:
+ propVariant = item.IsDir();
+ break;
+ case kpidSize:
+ case kpidPackedSize:
+ if (!item.IsDir())
+ propVariant = (UInt64)item.DataLength;
+ break;
+ case kpidLastWriteTime:
+ {
+ FILETIME utcFileTime;
+ if (item.DateTime.GetFileTime(utcFileTime))
+ propVariant = utcFileTime;
+ /*
+ else
+ {
+ utcFileTime.dwLowDateTime = 0;
+ utcFileTime.dwHighDateTime = 0;
+ }
+ */
+ break;
+ }
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
+ Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ bool testMode = (_aTestMode != 0);
+ bool allFilesMode = (numItems == UInt32(-1));
+ if (allFilesMode)
+ numItems = _archive.Refs.Size();
+ UInt64 totalSize = 0;
+ if(numItems == 0)
+ return S_OK;
+ UInt32 i;
+ for(i = 0; i < numItems; i++)
+ {
+ UInt32 index = (allFilesMode ? i : indices[i]);
+ if (index < (UInt32)_archive.Refs.Size())
+ {
+ const CRef &ref = _archive.Refs[index];
+ const CDir &item = ref.Dir->_subItems[ref.Index];
+ totalSize += item.DataLength;
+ }
+ else
+ {
+ totalSize += _archive.GetBootItemSize(index - _archive.Refs.Size());
+ }
+ }
+ extractCallback->SetTotal(totalSize);
+
+ UInt64 currentTotalSize = 0;
+ UInt64 currentItemSize;
+
+ CMyComPtr<ICompressCoder> copyCoder;
+
+ for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
+ {
+ currentItemSize = 0;
+ RINOK(extractCallback->SetCompleted(&currentTotalSize));
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ Int32 askMode;
+ askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract;
+ UInt32 index = allFilesMode ? i : indices[i];
+
+ RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
+
+ UInt64 blockIndex;
+ if (index < (UInt32)_archive.Refs.Size())
+ {
+ const CRef &ref = _archive.Refs[index];
+ const CDir &item = ref.Dir->_subItems[ref.Index];
+ if(item.IsDir())
+ {
+ RINOK(extractCallback->PrepareOperation(askMode));
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ continue;
+ }
+ currentItemSize = item.DataLength;
+ blockIndex = item.ExtentLocation;
+ }
+ else
+ {
+ int bootIndex = index - _archive.Refs.Size();
+ const CBootInitialEntry &be = _archive.BootEntries[bootIndex];
+ currentItemSize = _archive.GetBootItemSize(bootIndex);
+ blockIndex = be.LoadRBA;
+ }
+
+ if(!testMode && (!realOutStream))
+ continue;
+
+ RINOK(extractCallback->PrepareOperation(askMode));
+ {
+ if (testMode)
+ {
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ continue;
+ }
+
+ RINOK(_inStream->Seek(blockIndex * _archive.BlockSize, STREAM_SEEK_SET, NULL));
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+ CMyComPtr<ISequentialInStream> inStream(streamSpec);
+ streamSpec->SetStream(_inStream);
+ streamSpec->Init(currentItemSize);
+
+ 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);
+
+ Int32 res = NArchive::NExtract::NOperationResult::kOK;
+ if(!copyCoder)
+ {
+ copyCoder = new NCompress::CCopyCoder;
+ }
+ try
+ {
+ RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, compressProgress));
+ }
+ catch(...)
+ {
+ res = NArchive::NExtract::NOperationResult::kDataError;
+ }
+ realOutStream.Release();
+ RINOK(extractCallback->SetOperationResult(res));
+ }
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+}}
diff --git a/CPP/7zip/Archive/Iso/IsoHandler.h b/CPP/7zip/Archive/Iso/IsoHandler.h
new file mode 100755
index 00000000..e545d2a7
--- /dev/null
+++ b/CPP/7zip/Archive/Iso/IsoHandler.h
@@ -0,0 +1,59 @@
+// Tar/Handler.h
+
+#ifndef __ISO_HANDLER_H
+#define __ISO_HANDLER_H
+
+#include "Common/MyCom.h"
+#include "../IArchive.h"
+
+#include "IsoItem.h"
+#include "IsoIn.h"
+
+namespace NArchive {
+namespace NIso {
+
+class CHandler:
+ public IInArchive,
+ // public IOutArchive,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP1(
+ IInArchive
+ // IOutArchive
+ )
+
+ 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);
+
+ /*
+ // IOutArchive
+ STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems,
+ IArchiveUpdateCallback *updateCallback);
+ STDMETHOD(GetFileTimeType)(UInt32 *type);
+ */
+
+private:
+ CMyComPtr<IInStream> _inStream;
+ CInArchive _archive;
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Iso/IsoHeader.cpp b/CPP/7zip/Archive/Iso/IsoHeader.cpp
new file mode 100755
index 00000000..9555e49b
--- /dev/null
+++ b/CPP/7zip/Archive/Iso/IsoHeader.cpp
@@ -0,0 +1,21 @@
+// Archive/Iso/Header.h
+
+#include "StdAfx.h"
+
+#include "IsoHeader.h"
+
+namespace NArchive {
+namespace NIso {
+
+const char *kElToritoSpec = "EL TORITO SPECIFICATION\0\0\0\0\0\0\0\0\0";
+
+const wchar_t *kMediaTypes[5] =
+{
+ L"NoEmulation",
+ L"1.2M",
+ L"1.44M",
+ L"2.88M",
+ L"HardDisk"
+};
+
+}}
diff --git a/CPP/7zip/Archive/Iso/IsoHeader.h b/CPP/7zip/Archive/Iso/IsoHeader.h
new file mode 100755
index 00000000..9702d70a
--- /dev/null
+++ b/CPP/7zip/Archive/Iso/IsoHeader.h
@@ -0,0 +1,61 @@
+// Archive/IsoHeader.h
+
+#ifndef __ARCHIVE_ISO_HEADER_H
+#define __ARCHIVE_ISO_HEADER_H
+
+#include "Common/Types.h"
+
+namespace NArchive {
+namespace NIso {
+
+namespace NVolDescType
+{
+ const Byte kBootRecord = 0;
+ const Byte kPrimaryVol = 1;
+ const Byte kSupplementaryVol = 2;
+ const Byte kVolParttition = 3;
+ const Byte kTerminator = 255;
+}
+
+const Byte kVersion = 1;
+
+namespace NFileFlags
+{
+ const Byte kDirectory = 1 << 1;
+}
+
+extern const char *kElToritoSpec;
+
+const UInt32 kStartPos = 0x8000;
+
+namespace NBootEntryId
+{
+ const Byte kValidationEntry = 1;
+ const Byte kInitialEntryNotBootable = 0;
+ const Byte kInitialEntryBootable = 0x88;
+}
+
+namespace NBootPlatformId
+{
+ const Byte kX86 = 0;
+ const Byte kPowerPC = 1;
+ const Byte kMac = 2;
+}
+
+const BYTE kBootMediaTypeMask = 0xF;
+
+namespace NBootMediaType
+{
+ const Byte kNoEmulation = 0;
+ const Byte k1d2Floppy = 1;
+ const Byte k1d44Floppy = 2;
+ const Byte k2d88Floppy = 3;
+ const Byte kHardDisk = 4;
+}
+
+const int kNumBootMediaTypes = 5;
+extern const wchar_t *kMediaTypes[];
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Iso/IsoIn.cpp b/CPP/7zip/Archive/Iso/IsoIn.cpp
new file mode 100755
index 00000000..213b3014
--- /dev/null
+++ b/CPP/7zip/Archive/Iso/IsoIn.cpp
@@ -0,0 +1,438 @@
+// Archive/IsoIn.cpp
+
+#include "StdAfx.h"
+
+#include "IsoIn.h"
+#include "IsoHeader.h"
+
+#include "Windows/Defs.h"
+
+#include "../../Common/StreamUtils.h"
+
+namespace NArchive {
+namespace NIso {
+
+HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
+{
+ return ReadStream(_stream, data, size, &processedSize);
+}
+
+Byte CInArchive::ReadByte()
+{
+ if (m_BufferPos >= BlockSize)
+ m_BufferPos = 0;
+ if (m_BufferPos == 0)
+ {
+ UInt32 processedSize;
+ if (ReadBytes(m_Buffer, BlockSize, processedSize) != S_OK)
+ throw 1;
+ if (processedSize != BlockSize)
+ throw 1;
+ }
+ Byte b = m_Buffer[m_BufferPos++];
+ _position++;
+ return b;
+}
+
+void CInArchive::ReadBytes(Byte *data, UInt32 size)
+{
+ for (UInt32 i = 0; i < size; i++)
+ data[i] = ReadByte();
+}
+
+void CInArchive::Skeep(size_t size)
+{
+ while (size-- != 0)
+ ReadByte();
+}
+
+void CInArchive::SkeepZeros(size_t size)
+{
+ while (size-- != 0)
+ {
+ Byte b = ReadByte();
+ if (b != 0)
+ throw 1;
+ }
+}
+
+UInt16 CInArchive::ReadUInt16Spec()
+{
+ UInt16 value = 0;
+ for (int i = 0; i < 2; i++)
+ value |= ((UInt16)(ReadByte()) << (8 * i));
+ return value;
+}
+
+
+UInt16 CInArchive::ReadUInt16()
+{
+ Byte b[4];
+ ReadBytes(b, 4);
+ UInt32 value = 0;
+ for (int i = 0; i < 2; i++)
+ {
+ if (b[i] != b[3 - i])
+ throw 1;
+ value |= ((UInt16)(b[i]) << (8 * i));
+ }
+ return (UInt16)value;
+}
+
+UInt32 CInArchive::ReadUInt32Le()
+{
+ UInt32 value = 0;
+ for (int i = 0; i < 4; i++)
+ value |= ((UInt32)(ReadByte()) << (8 * i));
+ return value;
+}
+
+UInt32 CInArchive::ReadUInt32Be()
+{
+ UInt32 value = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ value <<= 8;
+ value |= ReadByte();
+ }
+ return value;
+}
+
+UInt32 CInArchive::ReadUInt32()
+{
+ Byte b[8];
+ ReadBytes(b, 8);
+ UInt32 value = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ if (b[i] != b[7 - i])
+ throw 1;
+ value |= ((UInt32)(b[i]) << (8 * i));
+ }
+ return value;
+}
+
+UInt32 CInArchive::ReadDigits(int numDigits)
+{
+ UInt32 res = 0;
+ for (int i = 0; i < numDigits; i++)
+ {
+ Byte b = ReadByte();
+ if (b < '0' || b > '9')
+ {
+ if (b == 0) // it's bug in some CD's
+ b = '0';
+ else
+ throw 1;
+ }
+ UInt32 d = (UInt32)(b - '0');
+ res *= 10;
+ res += d;
+ }
+ return res;
+}
+
+void CInArchive::ReadDateTime(CDateTime &d)
+{
+ d.Year = (UInt16)ReadDigits(4);
+ d.Month = (Byte)ReadDigits(2);
+ d.Day = (Byte)ReadDigits(2);
+ d.Hour = (Byte)ReadDigits(2);
+ d.Minute = (Byte)ReadDigits(2);
+ d.Second = (Byte)ReadDigits(2);
+ d.Hundredths = (Byte)ReadDigits(2);
+ d.GmtOffset = (signed char)ReadByte();
+}
+
+void CInArchive::ReadBootRecordDescriptor(CBootRecordDescriptor &d)
+{
+ ReadBytes(d.BootSystemId, sizeof(d.BootSystemId));
+ ReadBytes(d.BootId, sizeof(d.BootId));
+ ReadBytes(d.BootSystemUse, sizeof(d.BootSystemUse));
+}
+
+void CInArchive::ReadRecordingDateTime(CRecordingDateTime &t)
+{
+ t.Year = ReadByte();
+ t.Month = ReadByte();
+ t.Day = ReadByte();
+ t.Hour = ReadByte();
+ t.Minute = ReadByte();
+ t.Second = ReadByte();
+ t.GmtOffset = (signed char)ReadByte();
+}
+
+void CInArchive::ReadDirRecord2(CDirRecord &r, Byte len)
+{
+ r.ExtendedAttributeRecordLen = ReadByte();
+ if (r.ExtendedAttributeRecordLen != 0)
+ throw 1;
+ r.ExtentLocation = ReadUInt32();
+ r.DataLength = ReadUInt32();
+ ReadRecordingDateTime(r.DateTime);
+ r.FileFlags = ReadByte();
+ r.FileUnitSize = ReadByte();
+ r.InterleaveGapSize = ReadByte();
+ r.VolSequenceNumber = ReadUInt16();
+ Byte idLen = ReadByte();
+ r.FileId.SetCapacity(idLen);
+ ReadBytes((Byte *)r.FileId, idLen);
+ int padSize = 1 - (idLen & 1);
+
+ // SkeepZeros(1 - (idLen & 1));
+ Skeep(1 - (idLen & 1)); // it's bug in some cd's. Must be zeros
+
+ int curPos = 33 + idLen + padSize;
+ if (curPos > len)
+ throw 1;
+ int rem = len - curPos;
+ r.SystemUse.SetCapacity(rem);
+ ReadBytes((Byte *)r.SystemUse, rem);
+}
+
+void CInArchive::ReadDirRecord(CDirRecord &r)
+{
+ Byte len = ReadByte();
+ ReadDirRecord2(r, len);
+}
+
+void CInArchive::ReadVolumeDescriptor(CVolumeDescriptor &d)
+{
+ d.VolFlags = ReadByte();
+ ReadBytes(d.SystemId, sizeof(d.SystemId));
+ ReadBytes(d.VolumeId, sizeof(d.VolumeId));
+ SkeepZeros(8);
+ d.VolumeSpaceSize = ReadUInt32();
+ ReadBytes(d.EscapeSequence, sizeof(d.EscapeSequence));
+ d.VolumeSetSize = ReadUInt16();
+ d.VolumeSequenceNumber = ReadUInt16();
+ d.LogicalBlockSize = ReadUInt16();
+ d.PathTableSize = ReadUInt32();
+ d.LPathTableLocation = ReadUInt32Le();
+ d.LOptionalPathTableLocation = ReadUInt32Le();
+ d.MPathTableLocation = ReadUInt32Be();
+ d.MOptionalPathTableLocation = ReadUInt32Be();
+ ReadDirRecord(d.RootDirRecord);
+ ReadBytes(d.VolumeSetId, sizeof(d.VolumeSetId));
+ ReadBytes(d.PublisherId, sizeof(d.PublisherId));
+ ReadBytes(d.DataPreparerId, sizeof(d.DataPreparerId));
+ ReadBytes(d.ApplicationId, sizeof(d.ApplicationId));
+ ReadBytes(d.CopyrightFileId, sizeof(d.CopyrightFileId));
+ ReadBytes(d.AbstractFileId, sizeof(d.AbstractFileId));
+ ReadBytes(d.BibFileId, sizeof(d.BibFileId));
+ ReadDateTime(d.CreationTime);
+ ReadDateTime(d.ModificationTime);
+ ReadDateTime(d.ExpirationTime);
+ ReadDateTime(d.EffectiveTime);
+ d.FileStructureVersion = ReadByte(); // = 1
+ SkeepZeros(1);
+ ReadBytes(d.ApplicationUse, sizeof(d.ApplicationUse));
+ SkeepZeros(653);
+}
+
+static inline bool CheckDescriptorSignature(const Byte *sig)
+{
+ return sig[0] == 'C' &&
+ sig[1] == 'D' &&
+ sig[2] == '0' &&
+ sig[3] == '0' &&
+ sig[4] == '1';
+}
+
+void CInArchive::SeekToBlock(UInt32 blockIndex)
+{
+ if (_stream->Seek((UInt64)blockIndex * VolDescs[MainVolDescIndex].LogicalBlockSize, STREAM_SEEK_SET, &_position) != S_OK)
+ throw 1;
+ m_BufferPos = 0;
+}
+
+void CInArchive::ReadDir(CDir &d, int level)
+{
+ if (!d.IsDir())
+ return;
+ SeekToBlock(d.ExtentLocation);
+ UInt64 startPos = _position;
+
+ bool firstItem = true;
+ for (;;)
+ {
+ UInt64 offset = _position - startPos;
+ if (offset >= d.DataLength)
+ break;
+ Byte len = ReadByte();
+ if (len == 0)
+ continue;
+ CDir subItem;
+ ReadDirRecord2(subItem, len);
+ if (firstItem && level == 0)
+ IsSusp = subItem.CheckSusp(SuspSkipSize);
+
+ if (!subItem.IsSystemItem())
+ d._subItems.Add(subItem);
+
+ firstItem = false;
+ }
+ for (int i = 0; i < d._subItems.Size(); i++)
+ ReadDir(d._subItems[i], level + 1);
+}
+
+void CInArchive::CreateRefs(CDir &d)
+{
+ if (!d.IsDir())
+ return;
+ for (int i = 0; i < d._subItems.Size(); i++)
+ {
+ CRef ref;
+ CDir &subItem = d._subItems[i];
+ subItem.Parent = &d;
+ ref.Dir = &d;
+ ref.Index = i;
+ Refs.Add(ref);
+ CreateRefs(subItem);
+ }
+}
+
+void CInArchive::ReadBootInfo()
+{
+ if (!_bootIsDefined)
+ return;
+ if (memcmp(_bootDesc.BootSystemId, kElToritoSpec, sizeof(_bootDesc.BootSystemId)) != 0)
+ return;
+
+ const Byte *p = (const Byte *)_bootDesc.BootSystemUse;
+ UInt32 blockIndex = p[0] | ((UInt32)p[1] << 8) | ((UInt32)p[2] << 16) | ((UInt32)p[3] << 24);
+ SeekToBlock(blockIndex);
+ Byte b = ReadByte();
+ if (b != NBootEntryId::kValidationEntry)
+ return;
+ {
+ CBootValidationEntry e;
+ e.PlatformId = ReadByte();
+ if (ReadUInt16Spec() != 0)
+ throw 1;
+ ReadBytes(e.Id, sizeof(e.Id));
+ /* UInt16 checkSum = */ ReadUInt16Spec();
+ if (ReadByte() != 0x55)
+ throw 1;
+ if (ReadByte() != 0xAA)
+ throw 1;
+ }
+ b = ReadByte();
+ if (b == NBootEntryId::kInitialEntryBootable || b == NBootEntryId::kInitialEntryNotBootable)
+ {
+ CBootInitialEntry e;
+ e.Bootable = (b == NBootEntryId::kInitialEntryBootable);
+ e.BootMediaType = ReadByte();
+ e.LoadSegment = ReadUInt16Spec();
+ e.SystemType = ReadByte();
+ if (ReadByte() != 0)
+ throw 1;
+ e.SectorCount = ReadUInt16Spec();
+ e.LoadRBA = ReadUInt32Le();
+ if (ReadByte() != 0)
+ throw 1;
+ BootEntries.Add(e);
+ }
+ else
+ return;
+}
+
+HRESULT CInArchive::Open2()
+{
+ Clear();
+ RINOK(_stream->Seek(kStartPos, STREAM_SEEK_CUR, &_position));
+
+ bool primVolDescDefined = false;
+ m_BufferPos = 0;
+ BlockSize = kBlockSize;
+ VolDescs.Add(CVolumeDescriptor());
+ for (;;)
+ {
+ Byte sig[6];
+ ReadBytes(sig, 6);
+ if (!CheckDescriptorSignature(sig + 1))
+ return S_FALSE;
+ // version = 2 for ISO 9660:1999?
+ Byte ver = ReadByte();
+ if (ver > 2)
+ throw S_FALSE;
+
+ if (sig[0] == NVolDescType::kTerminator)
+ break;
+ switch(sig[0])
+ {
+ case NVolDescType::kBootRecord:
+ {
+ _bootIsDefined = true;
+ ReadBootRecordDescriptor(_bootDesc);
+ break;
+ }
+ case NVolDescType::kPrimaryVol:
+ {
+ if (primVolDescDefined)
+ return S_FALSE;
+ primVolDescDefined = true;
+ CVolumeDescriptor &volDesc = VolDescs[0];
+ ReadVolumeDescriptor(volDesc);
+ // some burners write "Joliet" Escape Sequence to primary volume
+ memset(volDesc.EscapeSequence, 0, sizeof(volDesc.EscapeSequence));
+ break;
+ }
+ case NVolDescType::kSupplementaryVol:
+ {
+ CVolumeDescriptor sd;
+ ReadVolumeDescriptor(sd);
+ VolDescs.Add(sd);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ MainVolDescIndex = 0;
+ if (!primVolDescDefined)
+ return S_FALSE;
+ for (int i = VolDescs.Size() - 1; i >= 0; i--)
+ {
+ if (VolDescs[i].IsJoliet())
+ {
+ MainVolDescIndex = i;
+ break;
+ }
+ }
+ // MainVolDescIndex = 0; // to read primary volume
+ if (VolDescs[MainVolDescIndex].LogicalBlockSize != kBlockSize)
+ return S_FALSE;
+ (CDirRecord &)_rootDir = VolDescs[MainVolDescIndex].RootDirRecord;
+ ReadDir(_rootDir, 0);
+ CreateRefs(_rootDir);
+ ReadBootInfo();
+ return S_OK;
+}
+
+HRESULT CInArchive::Open(IInStream *inStream)
+{
+ _stream = inStream;
+ UInt64 pos;
+ RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &pos));
+ RINOK(_stream->Seek(0, STREAM_SEEK_END, &_archiveSize));
+ RINOK(_stream->Seek(pos, STREAM_SEEK_SET, &_position));
+ HRESULT res = S_FALSE;
+ try { res = Open2(); }
+ catch(...) { Clear(); res = S_FALSE; }
+ _stream.Release();
+ return res;
+}
+
+void CInArchive::Clear()
+{
+ Refs.Clear();
+ _rootDir.Clear();
+ VolDescs.Clear();
+ _bootIsDefined = false;
+ BootEntries.Clear();
+ SuspSkipSize = 0;
+ IsSusp = false;
+}
+
+}}
diff --git a/CPP/7zip/Archive/Iso/IsoIn.h b/CPP/7zip/Archive/Iso/IsoIn.h
new file mode 100755
index 00000000..ab850bd9
--- /dev/null
+++ b/CPP/7zip/Archive/Iso/IsoIn.h
@@ -0,0 +1,301 @@
+// Archive/IsoIn.h
+
+#ifndef __ARCHIVE_ISO_IN_H
+#define __ARCHIVE_ISO_IN_H
+
+#include "Common/MyCom.h"
+#include "Common/IntToString.h"
+
+#include "../../IStream.h"
+
+#include "IsoItem.h"
+#include "IsoHeader.h"
+
+namespace NArchive {
+namespace NIso {
+
+struct CDir: public CDirRecord
+{
+ CDir *Parent;
+ CObjectVector<CDir> _subItems;
+
+ void Clear()
+ {
+ Parent = 0;
+ _subItems.Clear();
+ }
+
+ int GetLength(bool checkSusp, int skipSize) const
+ {
+ int len = GetLengthCur(checkSusp, skipSize);
+ if (Parent != 0)
+ if (Parent->Parent != 0)
+ len += 1 + Parent->GetLength(checkSusp, skipSize);
+ return len;
+ }
+
+ int GetLengthU() const
+ {
+ int len = (int)(FileId.GetCapacity() / 2);
+ if (Parent != 0)
+ if (Parent->Parent != 0)
+ len += 1 + Parent->GetLengthU();
+ return len;
+ }
+
+ AString GetPath(bool checkSusp, int skipSize) const
+ {
+ AString s;
+ int len = GetLength(checkSusp, skipSize);
+ char *p = s.GetBuffer(len + 1);
+ p += len;
+ *p = 0;
+ const CDir *cur = this;
+ for (;;)
+ {
+ int curLen = cur->GetLengthCur(checkSusp, skipSize);
+ p -= curLen;
+ memmove(p, (const char *)(const Byte *)cur->GetNameCur(checkSusp, skipSize), curLen);
+ cur = cur->Parent;
+ if (cur == 0)
+ break;
+ if (cur->Parent == 0)
+ break;
+ p--;
+ *p = CHAR_PATH_SEPARATOR;
+ }
+ s.ReleaseBuffer();
+ return s;
+ }
+
+ UString GetPathU() const
+ {
+ UString s;
+ int len = GetLengthU();
+ wchar_t *p = s.GetBuffer(len + 1);
+ p += len;
+ *p = 0;
+ const CDir *cur = this;
+ for (;;)
+ {
+ int curLen = (int)(cur->FileId.GetCapacity() / 2);
+ p -= curLen;
+ for (int i = 0; i < curLen; i++)
+ {
+ Byte b0 = ((const Byte *)cur->FileId)[i * 2];
+ Byte b1 = ((const Byte *)cur->FileId)[i * 2 + 1];
+ p[i] = (wchar_t)(((wchar_t)b0 << 8) | b1);
+ }
+ cur = cur->Parent;
+ if (cur == 0)
+ break;
+ if (cur->Parent == 0)
+ break;
+ p--;
+ *p = WCHAR_PATH_SEPARATOR;
+ }
+ s.ReleaseBuffer();
+ return s;
+ }
+};
+
+struct CDateTime
+{
+ UInt16 Year;
+ Byte Month;
+ Byte Day;
+ Byte Hour;
+ Byte Minute;
+ Byte Second;
+ Byte Hundredths;
+ signed char GmtOffset; // min intervals from -48 (West) to +52 (East) recorded.
+ bool NotSpecified() const { return Year == 0 && Month == 0 && Day == 0 &&
+ Hour == 0 && Minute == 0 && Second == 0 && GmtOffset == 0; }
+};
+
+struct CBootRecordDescriptor
+{
+ Byte BootSystemId[32]; // a-characters
+ Byte BootId[32]; // a-characters
+ Byte BootSystemUse[1977];
+};
+
+struct CBootValidationEntry
+{
+ Byte PlatformId;
+ Byte Id[24]; // to identify the manufacturer/developer of the CD-ROM.
+};
+
+struct CBootInitialEntry
+{
+ bool Bootable;
+ Byte BootMediaType;
+ UInt16 LoadSegment;
+ /* This is the load segment for the initial boot image. If this
+ value is 0 the system will use the traditional segment of 7C0. If this value
+ is non-zero the system will use the specified segment. This applies to x86
+ architectures only. For "flat" model architectures (such as Motorola) this
+ is the address divided by 10. */
+ Byte SystemType; // This must be a copy of byte 5 (System Type) from the
+ // Partition Table found in the boot image.
+ UInt16 SectorCount; // This is the number of virtual/emulated sectors the system
+ // will store at Load Segment during the initial boot procedure.
+ UInt32 LoadRBA; // This is the start address of the virtual disk. CD’s use
+ // Relative/Logical block addressing.
+
+ UInt64 GetSize() const
+ {
+ // if (BootMediaType == NBootMediaType::k1d44Floppy) (1440 << 10);
+ return SectorCount * 512;
+ }
+
+ UString GetName() const
+ {
+ UString s;
+ if (Bootable)
+ s += L"Bootable";
+ else
+ s += L"NotBootable";
+ s += L"_";
+ if (BootMediaType >= kNumBootMediaTypes)
+ {
+ wchar_t name[32];
+ ConvertUInt64ToString(BootMediaType, name);
+ s += name;
+ }
+ else
+ s += kMediaTypes[BootMediaType];
+ s += L".img";
+ return s;
+ }
+};
+
+struct CVolumeDescriptor
+{
+ Byte VolFlags;
+ Byte SystemId[32]; // a-characters. An identification of a system
+ // which can recognize and act upon the content of the Logical
+ // Sectors with logical Sector Numbers 0 to 15 of the volume.
+ Byte VolumeId[32]; // d-characters. An identification of the volume.
+ UInt32 VolumeSpaceSize; // the number of Logical Blocks in which the Volume Space of the volume is recorded
+ Byte EscapeSequence[32];
+ UInt16 VolumeSetSize;
+ UInt16 VolumeSequenceNumber; // the ordinal number of the volume in the Volume Set of which the volume is a member.
+ UInt16 LogicalBlockSize;
+ UInt32 PathTableSize;
+ UInt32 LPathTableLocation;
+ UInt32 LOptionalPathTableLocation;
+ UInt32 MPathTableLocation;
+ UInt32 MOptionalPathTableLocation;
+ CDirRecord RootDirRecord;
+ Byte VolumeSetId[128];
+ Byte PublisherId[128];
+ Byte DataPreparerId[128];
+ Byte ApplicationId[128];
+ Byte CopyrightFileId[37];
+ Byte AbstractFileId[37];
+ Byte BibFileId[37];
+ CDateTime CreationTime;
+ CDateTime ModificationTime;
+ CDateTime ExpirationTime;
+ CDateTime EffectiveTime;
+ Byte FileStructureVersion; // = 1;
+ Byte ApplicationUse[512];
+
+ bool IsJoliet() const
+ {
+ if ((VolFlags & 1) != 0)
+ return false;
+ Byte b = EscapeSequence[2];
+ return (EscapeSequence[0] == 0x25 && EscapeSequence[1] == 0x2F &&
+ (b == 0x40 || b == 0x43 || b == 0x45));
+ }
+};
+
+struct CRef
+{
+ CDir *Dir;
+ UInt32 Index;
+};
+
+const UInt32 kBlockSize = 1 << 11;
+
+class CInArchive
+{
+ CMyComPtr<IInStream> _stream;
+ UInt64 _position;
+
+ Byte m_Buffer[kBlockSize];
+ UInt32 m_BufferPos;
+
+ CDir _rootDir;
+ bool _bootIsDefined;
+ CBootRecordDescriptor _bootDesc;
+
+ HRESULT ReadBytes(void *data, UInt32 size, UInt32 &processedSize);
+ void Skeep(size_t size);
+ void SkeepZeros(size_t size);
+ Byte ReadByte();
+ void ReadBytes(Byte *data, UInt32 size);
+ UInt16 ReadUInt16Spec();
+ UInt16 ReadUInt16();
+ UInt32 ReadUInt32Le();
+ UInt32 ReadUInt32Be();
+ UInt32 ReadUInt32();
+ UInt64 ReadUInt64();
+ UInt32 ReadDigits(int numDigits);
+ void ReadDateTime(CDateTime &d);
+ void ReadRecordingDateTime(CRecordingDateTime &t);
+ void ReadDirRecord2(CDirRecord &r, Byte len);
+ void ReadDirRecord(CDirRecord &r);
+
+ void ReadBootRecordDescriptor(CBootRecordDescriptor &d);
+ void ReadVolumeDescriptor(CVolumeDescriptor &d);
+
+ void SeekToBlock(UInt32 blockIndex);
+ void ReadDir(CDir &d, int level);
+ void CreateRefs(CDir &d);
+
+ void ReadBootInfo();
+ HRESULT Open2();
+public:
+ HRESULT Open(IInStream *inStream);
+ void Clear();
+
+ UInt64 _archiveSize;
+
+ CRecordVector<CRef> Refs;
+ CObjectVector<CVolumeDescriptor> VolDescs;
+ int MainVolDescIndex;
+ UInt32 BlockSize;
+ CObjectVector<CBootInitialEntry> BootEntries;
+
+
+ bool IsJoliet() const { return VolDescs[MainVolDescIndex].IsJoliet(); }
+
+ UInt64 GetBootItemSize(int index) const
+ {
+ const CBootInitialEntry &be = BootEntries[index];
+ UInt64 size = be.GetSize();
+ if (be.BootMediaType == NBootMediaType::k1d2Floppy)
+ size = (1200 << 10);
+ else if (be.BootMediaType == NBootMediaType::k1d44Floppy)
+ size = (1440 << 10);
+ else if (be.BootMediaType == NBootMediaType::k2d88Floppy)
+ size = (2880 << 10);
+ UInt64 startPos = be.LoadRBA * BlockSize;
+ if (startPos < _archiveSize)
+ {
+ if (_archiveSize - startPos < size)
+ size = _archiveSize - startPos;
+ }
+ return size;
+ }
+
+ bool IsSusp;
+ int SuspSkipSize;
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Iso/IsoItem.h b/CPP/7zip/Archive/Iso/IsoItem.h
new file mode 100755
index 00000000..14024d8d
--- /dev/null
+++ b/CPP/7zip/Archive/Iso/IsoItem.h
@@ -0,0 +1,145 @@
+// Archive/IsoItem.h
+
+#ifndef __ARCHIVE_ISO_ITEM_H
+#define __ARCHIVE_ISO_ITEM_H
+
+#include "Common/Types.h"
+#include "Common/String.h"
+#include "Common/Buffer.h"
+
+#include "IsoHeader.h"
+
+namespace NArchive {
+namespace NIso {
+
+struct CRecordingDateTime
+{
+ Byte Year;
+ Byte Month;
+ Byte Day;
+ Byte Hour;
+ Byte Minute;
+ Byte Second;
+ signed char GmtOffset; // min intervals from -48 (West) to +52 (East) recorded.
+
+ bool GetFileTime(FILETIME &ft) const
+ {
+ SYSTEMTIME st;
+ st.wYear = (WORD)(Year + 1900);
+ st.wMonth = Month;
+ st.wDayOfWeek = 0; // check it
+ st.wDay = Day;
+ st.wHour = Hour;
+ st.wMinute = Minute;
+ st.wSecond = Second;
+ st.wMilliseconds = 0;
+ if (!SystemTimeToFileTime(&st, &ft))
+ return false;
+ UInt64 value = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
+ value += (UInt64)((Int64)(int)GmtOffset * 15 * 60);
+ ft.dwLowDateTime = (DWORD)value;
+ ft.dwHighDateTime = DWORD(value >> 32);
+ return true;
+ }
+};
+
+struct CDirRecord
+{
+ Byte ExtendedAttributeRecordLen;
+ UInt32 ExtentLocation;
+ UInt32 DataLength;
+ CRecordingDateTime DateTime;
+ Byte FileFlags;
+ Byte FileUnitSize;
+ Byte InterleaveGapSize;
+ UInt16 VolSequenceNumber;
+ CByteBuffer FileId;
+ CByteBuffer SystemUse;
+
+ bool IsDir() const { return (FileFlags & NFileFlags::kDirectory) != 0; }
+ bool IsSystemItem() const
+ {
+ if (FileId.GetCapacity() != 1)
+ return false;
+ Byte b = *(const Byte *)FileId;
+ return (b == 0 || b == 1);
+ }
+
+ const Byte* FindSuspName(int skipSize, int &lenRes) const
+ {
+ lenRes = 0;
+ const Byte *p = (const Byte *)SystemUse + skipSize;
+ int length = (int)(SystemUse.GetCapacity() - skipSize);
+ while (length >= 5)
+ {
+ int len = p[2];
+ if (p[0] == 'N' && p[1] == 'M' && p[3] == 1)
+ {
+ lenRes = len - 5;
+ return p + 5;
+ }
+ p += len;
+ length -= len;
+ }
+ return 0;
+ }
+
+ int GetLengthCur(bool checkSusp, int skipSize) const
+ {
+ if (checkSusp)
+ {
+ int len;
+ const Byte *res = FindSuspName(skipSize, len);
+ if (res != 0)
+ return len;
+ }
+ return (int)FileId.GetCapacity();
+ }
+
+ const Byte* GetNameCur(bool checkSusp, int skipSize) const
+ {
+ if (checkSusp)
+ {
+ int len;
+ const Byte *res = FindSuspName(skipSize, len);
+ if (res != 0)
+ return res;
+ }
+ return (const Byte *)FileId;
+ }
+
+
+ bool CheckSusp(const Byte *p, int &startPos) const
+ {
+ if (p[0] == 'S' &&
+ p[1] == 'P' &&
+ p[2] == 0x7 &&
+ p[3] == 0x1 &&
+ p[4] == 0xBE &&
+ p[5] == 0xEF)
+ {
+ startPos = p[6];
+ return true;
+ }
+ return false;
+ }
+
+ bool CheckSusp(int &startPos) const
+ {
+ const Byte *p = (const Byte *)SystemUse;
+ int length = (int)SystemUse.GetCapacity();
+ const int kMinLen = 7;
+ if (length < kMinLen)
+ return false;
+ if (CheckSusp(p, startPos))
+ return true;
+ const int kOffset2 = 14;
+ if (length < kOffset2 + kMinLen)
+ return false;
+ return CheckSusp(p + kOffset2, startPos);
+ }
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Iso/StdAfx.cpp b/CPP/7zip/Archive/Iso/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Archive/Iso/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Archive/Iso/StdAfx.h b/CPP/7zip/Archive/Iso/StdAfx.h
new file mode 100755
index 00000000..2e4be10b
--- /dev/null
+++ b/CPP/7zip/Archive/Iso/StdAfx.h
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/Archive/Iso/makefile b/CPP/7zip/Archive/Iso/makefile
new file mode 100755
index 00000000..100a3cd0
--- /dev/null
+++ b/CPP/7zip/Archive/Iso/makefile
@@ -0,0 +1,55 @@
+PROG = iso.dll
+DEF_FILE = ../Archive.def
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib user32.lib
+
+TAR_OBJS = \
+ $O\DllExports.obj \
+ $O\IsoHandler.obj \
+ $O\IsoHeader.obj \
+ $O\IsoIn.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\IntToString.obj \
+ $O\NewHandler.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\Vector.obj \
+
+WIN_OBJS = \
+ $O\PropVariant.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\LimitedStreams.obj \
+ $O\ProgressUtils.obj \
+ $O\StreamUtils.obj \
+
+AR_COMMON_OBJS = \
+ $O\ItemNameUtils.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(TAR_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $(COMPRESS_TAR_OBJS) \
+ $O\CopyCoder.obj \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(TAR_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)
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/Archive/Iso/resource.rc b/CPP/7zip/Archive/Iso/resource.rc
new file mode 100755
index 00000000..86929b0e
--- /dev/null
+++ b/CPP/7zip/Archive/Iso/resource.rc
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("Iso Plugin", "iso")
+
+101 ICON "iso.ico"
diff --git a/CPP/7zip/Archive/Lzh/DllExports.cpp b/CPP/7zip/Archive/Lzh/DllExports.cpp
new file mode 100755
index 00000000..c2b30945
--- /dev/null
+++ b/CPP/7zip/Archive/Lzh/DllExports.cpp
@@ -0,0 +1,72 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+#include "../../ICoder.h"
+#include "LzhHandler.h"
+
+// {23170F69-40C1-278A-1000-000110060000}
+DEFINE_GUID(CLSID_CLzhHandler,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x06, 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_CLzhHandler)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ if (*interfaceID != IID_IInArchive)
+ return E_NOINTERFACE;
+ CMyComPtr<IInArchive> inArchive = (IInArchive *)new NArchive::NLzh::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"Lzh";
+ break;
+ case NArchive::kClassID:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CLzhHandler, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NArchive::kExtension:
+ propVariant = L"lzh lha";
+ break;
+ case NArchive::kUpdate:
+ propVariant = false;
+ break;
+ case NArchive::kKeepName:
+ propVariant = false;
+ break;
+ case NArchive::kStartSignature:
+ {
+ const unsigned char sig[] = { '-', 'l' };
+ if ((value->bstrVal = ::SysAllocStringByteLen((const char *)sig, 2)) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/CPP/7zip/Archive/Lzh/Lzh.def b/CPP/7zip/Archive/Lzh/Lzh.def
new file mode 100755
index 00000000..e240b3f2
--- /dev/null
+++ b/CPP/7zip/Archive/Lzh/Lzh.def
@@ -0,0 +1,7 @@
+; Arj.def
+
+LIBRARY Arj.dll
+
+EXPORTS
+ CreateObject PRIVATE
+ GetHandlerProperty PRIVATE
diff --git a/CPP/7zip/Archive/Lzh/Lzh.dsp b/CPP/7zip/Archive/Lzh/Lzh.dsp
new file mode 100755
index 00000000..ad00699c
--- /dev/null
+++ b/CPP/7zip/Archive/Lzh/Lzh.dsp
@@ -0,0 +1,333 @@
+# Microsoft Developer Studio Project File - Name="Lzh" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=Lzh - 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 "lzh.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 "lzh.mak" CFG="Lzh - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Lzh - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Lzh - 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)" == "Lzh - 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 "ARJ_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARJ_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\lzh.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Lzh - 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 "ARJ_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 "ARJ_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\lzh.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "Lzh - Win32 Release"
+# Name "Lzh - 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
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\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\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.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\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 "Engine"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\LzhCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzhCRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzhHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzhHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzhHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzhIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzhIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzhItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzhOutStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzhOutStreamWithCRC.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Group "Codecs"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Lzh\LzhDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Lzh\LzhDecoder.h
+# End Source File
+# End Group
+# 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 "Copy"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.h
+# End Source File
+# End Group
+# Begin Group "Huffman"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Huffman\HuffmanDecoder.h
+# End Source File
+# End Group
+# 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\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"
+
+# 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 Source File
+
+SOURCE=.\lzh.ico
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/Archive/Lzh/Lzh.dsw b/CPP/7zip/Archive/Lzh/Lzh.dsw
new file mode 100755
index 00000000..41ab2218
--- /dev/null
+++ b/CPP/7zip/Archive/Lzh/Lzh.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "lzh"=.\lzh.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Archive/Lzh/LzhCRC.cpp b/CPP/7zip/Archive/Lzh/LzhCRC.cpp
new file mode 100755
index 00000000..ca1235bb
--- /dev/null
+++ b/CPP/7zip/Archive/Lzh/LzhCRC.cpp
@@ -0,0 +1,43 @@
+// LzhCRC.cpp
+
+#include "StdAfx.h"
+
+#include "LzhCRC.h"
+
+namespace NArchive {
+namespace NLzh {
+
+static const UInt16 kCRCPoly = 0xA001;
+
+UInt16 CCRC::Table[256];
+
+void CCRC::InitTable()
+{
+ for (UInt32 i = 0; i < 256; i++)
+ {
+ UInt32 r = i;
+ for (int j = 0; j < 8; j++)
+ if (r & 1)
+ r = (r >> 1) ^ kCRCPoly;
+ else
+ r >>= 1;
+ CCRC::Table[i] = (UInt16)r;
+ }
+}
+
+class CCRCTableInit
+{
+public:
+ CCRCTableInit() { CCRC::InitTable(); }
+} g_CRCTableInit;
+
+void CCRC::Update(const void *data, size_t size)
+{
+ UInt16 v = _value;
+ const Byte *p = (const Byte *)data;
+ for (; size > 0; size--, p++)
+ v = (UInt16)(Table[((Byte)(v)) ^ *p] ^ (v >> 8));
+ _value = v;
+}
+
+}}
diff --git a/CPP/7zip/Archive/Lzh/LzhCRC.h b/CPP/7zip/Archive/Lzh/LzhCRC.h
new file mode 100755
index 00000000..e49d649c
--- /dev/null
+++ b/CPP/7zip/Archive/Lzh/LzhCRC.h
@@ -0,0 +1,27 @@
+// LzhCRC.h
+
+#ifndef __LZH_CRC_H
+#define __LZH_CRC_H
+
+#include <stddef.h>
+#include "Common/Types.h"
+
+namespace NArchive {
+namespace NLzh {
+
+class CCRC
+{
+ UInt16 _value;
+public:
+ static UInt16 Table[256];
+ static void InitTable();
+
+ CCRC(): _value(0){};
+ void Init() { _value = 0; }
+ void Update(const void *data, size_t size);
+ UInt16 GetDigest() const { return _value; }
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Lzh/LzhHandler.cpp b/CPP/7zip/Archive/Lzh/LzhHandler.cpp
new file mode 100755
index 00000000..03af11d1
--- /dev/null
+++ b/CPP/7zip/Archive/Lzh/LzhHandler.cpp
@@ -0,0 +1,464 @@
+// LzhHandler.cpp
+
+#include "StdAfx.h"
+
+#include "Common/Defs.h"
+#include "Common/StringConvert.h"
+#include "Common/ComTry.h"
+
+#include "Windows/Time.h"
+#include "Windows/PropVariant.h"
+
+#include "LzhHandler.h"
+#include "LzhOutStreamWithCRC.h"
+
+#include "../../ICoder.h"
+
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/LimitedStreams.h"
+
+#include "../../Compress/Copy/CopyCoder.h"
+#include "../../Compress/Lzh/LzhDecoder.h"
+
+#include "../Common/ItemNameUtils.h"
+
+using namespace NWindows;
+using namespace NTime;
+
+namespace NArchive {
+namespace NLzh{
+
+struct COsPair
+{
+ Byte Id;
+ const wchar_t *Name;
+};
+
+COsPair g_OsPairs[] =
+{
+ { 'M', L"MS-DOS" },
+ { '2', L"OS/2" },
+ { '9', L"OS9" },
+ { 'K', L"OS/68K" },
+ { '3', L"OS/386" },
+ { 'H', L"HUMAN" },
+ { 'U', L"UNIX" },
+ { 'C', L"CP/M" },
+ { 'F', L"FLEX" },
+ { 'm', L"Mac" },
+ { 'R', L"Runser" },
+ { 'T', L"TownsOS" },
+ { 'X', L"XOSK" },
+ { 'w', L"Windows95" },
+ { 'W', L"WindowsNT" },
+ { 0, L"MS-DOS" },
+ { 'J', L"Java VM" }
+};
+
+const wchar_t *kUnknownOS = L"Unknown";
+
+const int kNumHostOSes = sizeof(g_OsPairs) / sizeof(g_OsPairs[0]);
+
+static const wchar_t *GetOS(Byte osId)
+{
+ for (int i = 0; i < kNumHostOSes; i++)
+ if (g_OsPairs[i].Id == osId)
+ return g_OsPairs[i].Name;
+ return kUnknownOS;
+};
+
+STATPROPSTG kProperties[] =
+{
+ { NULL, kpidPath, VT_BSTR},
+ { NULL, kpidIsFolder, VT_BOOL},
+ { NULL, kpidSize, VT_UI8},
+ { NULL, kpidPackedSize, VT_UI8},
+ { NULL, kpidLastWriteTime, VT_FILETIME},
+ { NULL, kpidAttributes, VT_UI4},
+
+ // { NULL, kpidCommented, VT_BOOL},
+
+ { NULL, kpidCRC, VT_UI4},
+
+ { NULL, kpidMethod, VT_UI1},
+ { NULL, kpidHostOS, VT_BSTR}
+
+};
+
+
+CHandler::CHandler()
+{}
+
+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;
+ *name = 0;
+ 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_NOTIMPL;
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = _items.Size();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant propVariant;
+ const CItemEx &item = _items[index];
+ switch(propID)
+ {
+ case kpidPath:
+ {
+ UString s = NItemName::WinNameToOSName(MultiByteToUnicodeString(item.GetName(), CP_OEMCP));
+ if (!s.IsEmpty())
+ {
+ if (s[s.Length() - 1] == WCHAR_PATH_SEPARATOR)
+ s.Delete(s.Length() - 1);
+ propVariant = s;
+ }
+ break;
+ }
+ case kpidIsFolder:
+ propVariant = item.IsDirectory();
+ break;
+ case kpidSize:
+ propVariant = item.Size;
+ break;
+ case kpidPackedSize:
+ propVariant = item.PackSize;
+ break;
+ case kpidLastWriteTime:
+ {
+ FILETIME utcFileTime;
+ UInt32 unixTime;
+ if (item.GetUnixTime(unixTime))
+ {
+ NTime::UnixTimeToFileTime(unixTime, utcFileTime);
+ }
+ else
+ {
+ FILETIME localFileTime;
+ if (DosTimeToFileTime(item.ModifiedTime, localFileTime))
+ {
+ if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
+ utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
+ }
+ else
+ utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
+ }
+ propVariant = utcFileTime;
+ break;
+ }
+ /*
+ case kpidAttributes:
+ propVariant = (UInt32)item.Attributes;
+ break;
+ case kpidCommented:
+ propVariant = item.IsCommented();
+ break;
+ */
+ case kpidCRC:
+ propVariant = (UInt32)item.CRC;
+ break;
+ case kpidMethod:
+ {
+ wchar_t method2[kMethodIdSize + 1];
+ method2[kMethodIdSize] = 0;
+ for (int i = 0; i < kMethodIdSize; i++)
+ method2[i] = item.Method[i];
+ propVariant = method2;
+ break;
+ }
+ case kpidHostOS:
+ propVariant = GetOS(item.OsId);
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+/*
+class CPropgressImp: public CProgressVirt
+{
+public:
+ CMyComPtr<IArchiveOpenCallback> Callback;
+ STDMETHOD(SetCompleted)(const UInt64 *numFiles);
+};
+
+STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles)
+{
+ if (Callback)
+ return Callback->SetCompleted(numFiles, NULL);
+ return S_OK;
+}
+*/
+
+STDMETHODIMP CHandler::Open(IInStream *inStream,
+ const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback *callback)
+{
+ COM_TRY_BEGIN
+ try
+ {
+ _items.Clear();
+ CInArchive archive;
+ RINOK(archive.Open(inStream));
+ if (callback != NULL)
+ {
+ RINOK(callback->SetTotal(NULL, NULL));
+ UInt64 numFiles = _items.Size();
+ RINOK(callback->SetCompleted(&numFiles, NULL));
+ }
+ for (;;)
+ {
+ CItemEx itemInfo;
+ bool filled;
+ HRESULT result = archive.GetNextItem(filled, itemInfo);
+ if (result == S_FALSE)
+ return S_FALSE;
+ if (result != S_OK)
+ return S_FALSE;
+ if (!filled)
+ break;
+ _items.Add(itemInfo);
+ archive.Skeep(itemInfo.PackSize);
+ if (callback != NULL)
+ {
+ UInt64 numFiles = _items.Size();
+ RINOK(callback->SetCompleted(&numFiles, NULL));
+ }
+ }
+ if (_items.IsEmpty())
+ return S_FALSE;
+
+ _stream = inStream;
+ }
+ catch(...)
+ {
+ return S_FALSE;
+ }
+ COM_TRY_END
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ _items.Clear();
+ _stream.Release();
+ return S_OK;
+}
+
+
+
+//////////////////////////////////////
+// CHandler::DecompressItems
+
+STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
+ Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ bool testMode = (testModeSpec != 0);
+ UInt64 totalUnPacked = 0, totalPacked = 0;
+ bool allFilesMode = (numItems == UInt32(-1));
+ if (allFilesMode)
+ numItems = _items.Size();
+ if(numItems == 0)
+ return S_OK;
+ UInt32 i;
+ for(i = 0; i < numItems; i++)
+ {
+ const CItemEx &itemInfo = _items[allFilesMode ? i : indices[i]];
+ totalUnPacked += itemInfo.Size;
+ totalPacked += itemInfo.PackSize;
+ }
+ extractCallback->SetTotal(totalUnPacked);
+
+ UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0;
+ UInt64 currentItemUnPacked, currentItemPacked;
+
+ NCompress::NLzh::NDecoder::CCoder *lzhDecoderSpec = 0;
+ CMyComPtr<ICompressCoder> lzhDecoder;
+ CMyComPtr<ICompressCoder> lzh1Decoder;
+ CMyComPtr<ICompressCoder> arj2Decoder;
+ CMyComPtr<ICompressCoder> copyCoder;
+
+ for(i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked,
+ currentTotalPacked += currentItemPacked)
+ {
+ currentItemUnPacked = 0;
+ currentItemPacked = 0;
+
+ RINOK(extractCallback->SetCompleted(&currentTotalUnPacked));
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ Int32 askMode;
+ askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
+ NArchive::NExtract::NAskMode::kExtract;
+ Int32 index = allFilesMode ? i : indices[i];
+ const CItemEx &itemInfo = _items[index];
+ RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
+
+ if(itemInfo.IsDirectory())
+ {
+ // if (!testMode)
+ {
+ RINOK(extractCallback->PrepareOperation(askMode));
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ }
+ continue;
+ }
+
+ if (!testMode && (!realOutStream))
+ continue;
+
+ RINOK(extractCallback->PrepareOperation(askMode));
+ currentItemUnPacked = itemInfo.Size;
+ currentItemPacked = itemInfo.PackSize;
+
+ {
+ COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
+ CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
+ outStreamSpec->Init(realOutStream);
+ realOutStream.Release();
+
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+ CMyComPtr<ISequentialInStream> inStream(streamSpec);
+
+ UInt64 pos;
+ _stream->Seek(itemInfo.DataPosition, STREAM_SEEK_SET, &pos);
+
+ streamSpec->SetStream(_stream);
+ streamSpec->Init(itemInfo.PackSize);
+
+
+ CLocalProgress *localProgressSpec = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
+ localProgressSpec->Init(extractCallback, false);
+
+
+ CLocalCompressProgressInfo *localCompressProgressSpec =
+ new CLocalCompressProgressInfo;
+ CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
+ localCompressProgressSpec->Init(progress,
+ &currentTotalPacked,
+ &currentTotalUnPacked);
+
+ HRESULT result;
+
+ if (itemInfo.IsCopyMethod())
+ {
+ if(!copyCoder)
+ copyCoder = new NCompress::CCopyCoder;
+ try
+ {
+ result = copyCoder->Code(inStream, outStream, NULL, NULL, compressProgress);
+ if (result == S_FALSE)
+ throw "data error";
+ if (result != S_OK)
+ return result;
+ }
+ catch(...)
+ {
+ outStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ }
+ else if (itemInfo.IsLh4GroupMethod())
+ {
+ if(!lzhDecoder)
+ {
+ lzhDecoderSpec = new NCompress::NLzh::NDecoder::CCoder;
+ lzhDecoder = lzhDecoderSpec;
+ }
+ try
+ {
+ lzhDecoderSpec->SetDictionary(itemInfo.GetNumDictBits());
+ result = lzhDecoder->Code(inStream, outStream, NULL, &currentItemUnPacked, compressProgress);
+ if (result == S_FALSE)
+ throw "data error";
+ if (result != S_OK)
+ return result;
+ }
+ catch(...)
+ {
+ outStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ }
+ /*
+ else if (itemInfo.IsLh1GroupMethod())
+ {
+ if(!lzh1Decoder)
+ {
+ lzh1DecoderSpec = new NCompress::NLzh1::NDecoder::CCoder;
+ lzh1Decoder = lzh1DecoderSpec;
+ }
+ try
+ {
+ lzh1DecoderSpec->SetDictionary(itemInfo.GetNumDictBits());
+ result = lzh1Decoder->Code(inStream, outStream, NULL, &currentItemUnPacked, compressProgress);
+ if (result == S_FALSE)
+ throw "data error";
+ if (result != S_OK)
+ return result;
+ }
+ catch(...)
+ {
+ outStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ }
+ */
+ else
+ {
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+ continue;
+ }
+
+ bool crcOK = (outStreamSpec->GetCRC() == itemInfo.CRC);
+ outStream.Release();
+ if(crcOK)
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK))
+ else
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError))
+ }
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+
+}}
diff --git a/CPP/7zip/Archive/Lzh/LzhHandler.h b/CPP/7zip/Archive/Lzh/LzhHandler.h
new file mode 100755
index 00000000..2dc89494
--- /dev/null
+++ b/CPP/7zip/Archive/Lzh/LzhHandler.h
@@ -0,0 +1,47 @@
+// LzhHandler.h
+
+#ifndef __LZH_HANDLER_H
+#define __LZH_HANDLER_H
+
+#include "Common/MyCom.h"
+#include "../IArchive.h"
+#include "LzhIn.h"
+
+namespace NArchive {
+namespace NLzh {
+
+class CHandler:
+ public IInArchive,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Open)(IInStream *inStream,
+ const UInt64 *maxCheckStartPosition,
+ IArchiveOpenCallback *callback);
+ STDMETHOD(Close)();
+ STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
+ STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
+ STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems,
+ Int32 testMode, IArchiveExtractCallback *anExtractCallback);
+
+ 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);
+
+ CHandler();
+private:
+ CObjectVector<CItemEx> _items;
+ CMyComPtr<IInStream> _stream;
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Lzh/LzhHeader.h b/CPP/7zip/Archive/Lzh/LzhHeader.h
new file mode 100755
index 00000000..845b9a21
--- /dev/null
+++ b/CPP/7zip/Archive/Lzh/LzhHeader.h
@@ -0,0 +1,19 @@
+// Archive/Lzh/Header.h
+
+#ifndef __ARCHIVE_LZH_HEADER_H
+#define __ARCHIVE_LZH_HEADER_H
+
+#include "Common/Types.h"
+
+namespace NArchive {
+namespace NLzh {
+
+const int kMethodIdSize = 5;
+
+const Byte kExtIdFileName = 0x01;
+const Byte kExtIdDirName = 0x02;
+const Byte kExtIdUnixTime = 0x54;
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Lzh/LzhIn.cpp b/CPP/7zip/Archive/Lzh/LzhIn.cpp
new file mode 100755
index 00000000..42ef50e4
--- /dev/null
+++ b/CPP/7zip/Archive/Lzh/LzhIn.cpp
@@ -0,0 +1,171 @@
+// Archive/arj/InEngine.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StringConvert.h"
+#include "Common/Buffer.h"
+#include "Common/CRC.h"
+
+#include "../../Common/StreamUtils.h"
+
+#include "LzhIn.h"
+
+namespace NArchive {
+namespace NLzh {
+
+HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
+{
+ RINOK(ReadStream(m_Stream, data, size, &processedSize));
+ m_Position += processedSize;
+ return S_OK;
+}
+
+HRESULT CInArchive::CheckReadBytes(void *data, UInt32 size)
+{
+ UInt32 processedSize;
+ RINOK(ReadBytes(data, size, processedSize));
+ return (processedSize == size) ? S_OK: S_FALSE;
+}
+
+HRESULT CInArchive::Open(IInStream *inStream)
+{
+ RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position));
+ m_Stream = inStream;
+ return S_OK;
+}
+
+static const Byte *ReadUInt32(const Byte *p, UInt32 &v)
+{
+ v = 0;
+ for (int i = 0; i < 4; i++)
+ v |= ((UInt32)(*p++) << (i * 8));
+ return p;
+}
+
+static const Byte *ReadUInt16(const Byte *p, UInt16 &v)
+{
+ v = 0;
+ for (int i = 0; i < 2; i++)
+ v |= ((UInt16)(*p++) << (i * 8));
+ return p;
+}
+
+static const Byte *ReadString(const Byte *p, size_t size, AString &s)
+{
+ s.Empty();
+ for (size_t i = 0; i < size; i++)
+ {
+ char c = p[i];
+ if (c == 0)
+ break;
+ s += c;
+ }
+ return p + size;
+}
+
+static Byte CalcSum(const Byte *data, size_t size)
+{
+ Byte sum = 0;
+ for (size_t i = 0; i < size; i++)
+ sum = (Byte)(sum + data[i]);
+ return sum;
+}
+
+HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
+{
+ filled = false;
+
+ UInt32 processedSize;
+ Byte startHeader[2];
+ RINOK(ReadBytes(startHeader, 2, processedSize))
+ if (processedSize == 0)
+ return S_OK;
+ if (processedSize == 1)
+ return (startHeader[0] == 0) ? S_OK: S_FALSE;
+ if (startHeader[0] == 0 && startHeader[1] == 0)
+ return S_OK;
+
+ Byte header[256];
+ const UInt32 kBasicPartSize = 22;
+ RINOK(ReadBytes(header, kBasicPartSize, processedSize));
+ if (processedSize != kBasicPartSize)
+ return (startHeader[0] == 0) ? S_OK: S_FALSE;
+
+ const Byte *p = header;
+ memmove(item.Method, p, kMethodIdSize);
+ if (!item.IsValidMethod())
+ return S_OK;
+ p += kMethodIdSize;
+ p = ReadUInt32(p, item.PackSize);
+ p = ReadUInt32(p, item.Size);
+ p = ReadUInt32(p, item.ModifiedTime);
+ item.Attributes = *p++;
+ item.Level = *p++;
+ if (item.Level > 2)
+ return S_FALSE;
+ UInt32 headerSize;
+ if (item.Level < 2)
+ {
+ headerSize = startHeader[0];
+ if (headerSize < kBasicPartSize)
+ return S_FALSE;
+ UInt32 remain = headerSize - kBasicPartSize;
+ RINOK(CheckReadBytes(header + kBasicPartSize, remain));
+ if (startHeader[1] != CalcSum(header, headerSize))
+ return S_FALSE;
+ size_t nameLength = *p++;
+ if ((p - header) + nameLength + 2 > headerSize)
+ return S_FALSE;
+ p = ReadString(p, nameLength, item.Name);
+ }
+ else
+ headerSize = startHeader[0] | ((UInt32)startHeader[1] << 8);
+ p = ReadUInt16(p, item.CRC);
+ if (item.Level != 0)
+ {
+ if (item.Level == 2)
+ {
+ RINOK(CheckReadBytes(header + kBasicPartSize, 2));
+ }
+ if ((size_t)(p - header) + 3 > headerSize)
+ return S_FALSE;
+ item.OsId = *p++;
+ UInt16 nextSize;
+ p = ReadUInt16(p, nextSize);
+ while (nextSize != 0)
+ {
+ if (nextSize < 3)
+ return S_FALSE;
+ if (item.Level == 1)
+ {
+ if (item.PackSize < nextSize)
+ return S_FALSE;
+ item.PackSize -= nextSize;
+ }
+ CExtension ext;
+ RINOK(CheckReadBytes(&ext.Type, 1))
+ nextSize -= 3;
+ ext.Data.SetCapacity(nextSize);
+ RINOK(CheckReadBytes((Byte *)ext.Data, nextSize))
+ item.Extensions.Add(ext);
+ Byte hdr2[2];
+ RINOK(CheckReadBytes(hdr2, 2));
+ ReadUInt16(hdr2, nextSize);
+ }
+ }
+ item.DataPosition = m_Position;
+ filled = true;
+ return S_OK;
+}
+
+HRESULT CInArchive::Skeep(UInt64 numBytes)
+{
+ UInt64 newPostion;
+ RINOK(m_Stream->Seek(numBytes, STREAM_SEEK_CUR, &newPostion));
+ m_Position += numBytes;
+ if (m_Position != newPostion)
+ return E_FAIL;
+ return S_OK;
+}
+
+}}
diff --git a/CPP/7zip/Archive/Lzh/LzhIn.h b/CPP/7zip/Archive/Lzh/LzhIn.h
new file mode 100755
index 00000000..344a133f
--- /dev/null
+++ b/CPP/7zip/Archive/Lzh/LzhIn.h
@@ -0,0 +1,29 @@
+// Archive/LzhIn.h
+
+#ifndef __ARCHIVE_LZHIN_H
+#define __ARCHIVE_LZHIN_H
+
+#include "Common/MyCom.h"
+#include "../../IStream.h"
+
+#include "LzhItem.h"
+
+namespace NArchive {
+namespace NLzh {
+
+class CInArchive
+{
+ CMyComPtr<IInStream> m_Stream;
+ UInt64 m_Position;
+
+ HRESULT ReadBytes(void *data, UInt32 size, UInt32 &processedSize);
+ HRESULT CheckReadBytes(void *data, UInt32 size);
+public:
+ HRESULT Open(IInStream *inStream);
+ HRESULT GetNextItem(bool &filled, CItemEx &itemInfo);
+ HRESULT Skeep(UInt64 numBytes);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Lzh/LzhItem.h b/CPP/7zip/Archive/Lzh/LzhItem.h
new file mode 100755
index 00000000..66d4ed75
--- /dev/null
+++ b/CPP/7zip/Archive/Lzh/LzhItem.h
@@ -0,0 +1,172 @@
+// Archive/LzhItem.h
+
+#ifndef __ARCHIVE_LZH_ITEM_H
+#define __ARCHIVE_LZH_ITEM_H
+
+#include "Common/Types.h"
+#include "Common/String.h"
+#include "Common/Buffer.h"
+#include "LzhHeader.h"
+
+namespace NArchive {
+namespace NLzh {
+
+struct CExtension
+{
+ Byte Type;
+ CByteBuffer Data;
+ AString GetString() const
+ {
+ AString s;
+ for (size_t i = 0; i < Data.GetCapacity(); i++)
+ {
+ char c = (char)Data[i];
+ if (c == 0)
+ break;
+ s += c;
+ }
+ return s;
+ }
+};
+
+struct CItem
+{
+public:
+ AString Name;
+ Byte Method[kMethodIdSize];
+ UInt32 PackSize;
+ UInt32 Size;
+ UInt32 ModifiedTime;
+ Byte Attributes;
+ Byte Level;
+ UInt16 CRC;
+ Byte OsId;
+ CObjectVector<CExtension> Extensions;
+
+ bool IsValidMethod() const { return (Method[0] == '-' && Method[1] == 'l' && Method[4] == '-'); }
+ bool IsLhMethod() const {return (IsValidMethod() && Method[2] == 'h'); }
+ bool IsDirectory() const {return (IsLhMethod() && Method[3] == 'd'); }
+
+ bool IsCopyMethod() const
+ {
+ return (IsLhMethod() && Method[3] == '0') ||
+ (IsValidMethod() && Method[2] == 'z' && Method[3] == '4');
+ }
+
+ bool IsLh1GroupMethod() const
+ {
+ if (!IsLhMethod())
+ return false;
+ switch(Method[3])
+ {
+ case '1':
+ return true;
+ }
+ return false;
+ }
+
+ bool IsLh4GroupMethod() const
+ {
+ if (!IsLhMethod())
+ return false;
+ switch(Method[3])
+ {
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ return true;
+ }
+ return false;
+ }
+
+ int GetNumDictBits() const
+ {
+ if (!IsLhMethod())
+ return 0;
+ switch(Method[3])
+ {
+ case '1':
+ return 12;
+ case '2':
+ return 13;
+ case '3':
+ return 13;
+ case '4':
+ return 12;
+ case '5':
+ return 13;
+ case '6':
+ return 15;
+ case '7':
+ return 16;
+ }
+ return 0;
+ }
+
+ int FindExt(Byte type) const
+ {
+ for (int i = 0; i < Extensions.Size(); i++)
+ if (Extensions[i].Type == type)
+ return i;
+ return -1;
+ }
+ bool GetUnixTime(UInt32 &value) const
+ {
+ 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) |
+ ((UInt32)data[2] << 16) |
+ ((UInt32)data[3] << 24);
+ return true;
+ }
+
+ AString GetDirName() const
+ {
+ int index = FindExt(kExtIdDirName);
+ if (index < 0)
+ return AString();
+ return Extensions[index].GetString();
+ }
+
+ AString GetFileName() const
+ {
+ int index = FindExt(kExtIdFileName);
+ if (index < 0)
+ return Name;
+ return Extensions[index].GetString();
+ }
+
+ AString GetName() const
+ {
+ AString dirName = GetDirName();
+ dirName.Replace((char)(unsigned char)0xFF, '\\');
+ if (!dirName.IsEmpty())
+ {
+ char c = dirName[dirName.Length() - 1];
+ if (c != '\\')
+ dirName += '\\';
+ }
+ return dirName + GetFileName();
+ }
+};
+
+class CItemEx: public CItem
+{
+public:
+ UInt64 DataPosition;
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp b/CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp
new file mode 100755
index 00000000..2281a884
--- /dev/null
+++ b/CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp
@@ -0,0 +1,27 @@
+// LzhOutStreamWithCRC.cpp
+
+#include "StdAfx.h"
+
+#include "LzhOutStreamWithCRC.h"
+
+namespace NArchive {
+namespace NLzh {
+
+STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize;
+ HRESULT result;
+ if(!_stream)
+ {
+ realProcessedSize = size;
+ result = S_OK;
+ }
+ else
+ result = _stream->Write(data, size, &realProcessedSize);
+ _crc.Update(data, realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return result;
+}
+
+}}
diff --git a/CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.h b/CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.h
new file mode 100755
index 00000000..31b536b7
--- /dev/null
+++ b/CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.h
@@ -0,0 +1,38 @@
+// LzhOutStreamWithCRC.h
+
+#ifndef __LZHOUTSTREAMWITHCRC_H
+#define __LZHOUTSTREAMWITHCRC_H
+
+#include "LzhCRC.h"
+#include "../../../Common/MyCom.h"
+#include "../../IStream.h"
+
+namespace NArchive {
+namespace NLzh {
+
+class COutStreamWithCRC:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+private:
+ CCRC _crc;
+ CMyComPtr<ISequentialOutStream> _stream;
+public:
+ void Init(ISequentialOutStream *stream)
+ {
+ _stream = stream;
+ _crc.Init();
+ }
+ void ReleaseStream() { _stream.Release(); }
+ UInt32 GetCRC() const { return _crc.GetDigest(); }
+ void InitCRC() { _crc.Init(); }
+
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Lzh/StdAfx.cpp b/CPP/7zip/Archive/Lzh/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Archive/Lzh/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Archive/Lzh/StdAfx.h b/CPP/7zip/Archive/Lzh/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Archive/Lzh/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Archive/Lzh/lzh.ico b/CPP/7zip/Archive/Lzh/lzh.ico
new file mode 100755
index 00000000..84dab49c
--- /dev/null
+++ b/CPP/7zip/Archive/Lzh/lzh.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Lzh/makefile b/CPP/7zip/Archive/Lzh/makefile
new file mode 100755
index 00000000..6f8fd2a0
--- /dev/null
+++ b/CPP/7zip/Archive/Lzh/makefile
@@ -0,0 +1,65 @@
+PROG = lzh.dll
+DEF_FILE = ../Archive.def
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib user32.lib
+
+LZH_OBJS = \
+ $O\DllExports.obj \
+ $O\LzhCRC.obj \
+ $O\LzhHandler.obj \
+ $O\LzhIn.obj \
+ $O\LzhOutStreamWithCRC.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\NewHandler.obj \
+ $O\String.obj \
+ $O\StringConvert.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_LZH_OBJS = \
+ $O\LzhDecoder.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(LZH_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $(COMPRESS_LZH_OBJS) \
+ $O\CopyCoder.obj \
+ $O\LZOutWindow.obj \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(LZH_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_LZH_OBJS): ../../Compress/Lzh/$(*B).cpp
+ $(COMPL)
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
+$O\LZOutWindow.obj: ../../Compress/LZ/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/Archive/Lzh/resource.rc b/CPP/7zip/Archive/Lzh/resource.rc
new file mode 100755
index 00000000..2870e520
--- /dev/null
+++ b/CPP/7zip/Archive/Lzh/resource.rc
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("Lzh Plugin", "lzh")
+
+101 ICON "lzh.ico"
diff --git a/CPP/7zip/Archive/Nsis/DllExports.cpp b/CPP/7zip/Archive/Nsis/DllExports.cpp
new file mode 100755
index 00000000..f10f56ea
--- /dev/null
+++ b/CPP/7zip/Archive/Nsis/DllExports.cpp
@@ -0,0 +1,110 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+#include "../../ICoder.h"
+#include "NsisHandler.h"
+
+// {23170F69-40C1-278A-1000-000110090000}
+DEFINE_GUID(CLSID_CNsisHandler,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x09, 0x00, 0x00);
+
+HINSTANCE g_hInstance;
+#ifndef _UNICODE
+bool g_IsNT = false;
+static bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+#endif
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ g_hInstance = hInstance;
+ #ifndef _UNICODE
+ g_IsNT = IsItWindowsNT();
+ #endif
+ }
+ return TRUE;
+}
+
+STDAPI CreateObject(
+ const GUID *classID,
+ const GUID *interfaceID,
+ void **outObject)
+{
+ COM_TRY_BEGIN
+ *outObject = 0;
+ if (*classID != CLSID_CNsisHandler)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ int needIn = *interfaceID == IID_IInArchive;
+ // int needOut = *interfaceID == IID_IOutArchive;
+ if (needIn /*|| needOut */)
+ {
+ NArchive::NNsis::CHandler *temp = new NArchive::NNsis::CHandler;
+ if (needIn)
+ {
+ CMyComPtr<IInArchive> inArchive = (IInArchive *)temp;
+ *outObject = inArchive.Detach();
+ }
+ /*
+ else
+ {
+ CMyComPtr<IOutArchive> outArchive = (IOutArchive *)temp;
+ *outObject = outArchive.Detach();
+ }
+ */
+ }
+ else
+ return E_NOINTERFACE;
+ COM_TRY_END
+ return S_OK;
+}
+
+STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
+{
+ NWindows::NCOM::CPropVariant propVariant;
+ switch(propID)
+ {
+ case NArchive::kName:
+ propVariant = L"Nsis";
+ break;
+ case NArchive::kClassID:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CNsisHandler, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NArchive::kExtension:
+ propVariant = L"exe";
+ break;
+ case NArchive::kUpdate:
+ propVariant = false;
+ break;
+ case NArchive::kStartSignature:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen((const char *)NArchive::NNsis::kSignature,
+ NArchive::NNsis::kSignatureSize)) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NArchive::kAssociate:
+ {
+ propVariant = false;
+ break;
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/CPP/7zip/Archive/Nsis/Nsis.dsp b/CPP/7zip/Archive/Nsis/Nsis.dsp
new file mode 100755
index 00000000..45ce0386
--- /dev/null
+++ b/CPP/7zip/Archive/Nsis/Nsis.dsp
@@ -0,0 +1,337 @@
+# Microsoft Developer Studio Project File - Name="Nsis" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=Nsis - 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 "Nsis.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 "Nsis.mak" CFG="Nsis - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Nsis - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Nsis - 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)" == "Nsis - 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 "TAR_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TAR_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\nsis.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Nsis - 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 "TAR_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 "TAR_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\nsis.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "Nsis - Win32 Release"
+# Name "Nsis - 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=.\Nsis.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "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\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.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\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\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.h
+# End Source File
+# End Group
+# Begin Group "Engine"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\NsisDecode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NsisDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NsisHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NsisHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NsisIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NsisIn.h
+# End Source File
+# End Group
+# Begin Group "Archive Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Common\CodecsPath.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CodecsPath.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CoderLoader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CoderLoader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\FilterCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\FilterCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ItemNameUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ItemNameUtils.h
+# End Source File
+# End Group
+# Begin Group "7zip Common"
+
+# PROP Default_Filter ""
+# 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\ProgressUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# End Group
+# Begin Group "7z"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\7z\7zMethodID.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\7z\7zMethodID.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\7z\7zMethods.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\7z\7zMethods.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/CPP/7zip/Archive/Nsis/Nsis.dsw b/CPP/7zip/Archive/Nsis/Nsis.dsw
new file mode 100755
index 00000000..d3df6d27
--- /dev/null
+++ b/CPP/7zip/Archive/Nsis/Nsis.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Nsis"=.\Nsis.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Archive/Nsis/NsisDecode.cpp b/CPP/7zip/Archive/Nsis/NsisDecode.cpp
new file mode 100755
index 00000000..d49b2312
--- /dev/null
+++ b/CPP/7zip/Archive/Nsis/NsisDecode.cpp
@@ -0,0 +1,150 @@
+// NsisDecode.cpp
+
+#include "StdAfx.h"
+
+#include "NsisDecode.h"
+
+#include "../../Common/StreamUtils.h"
+
+#include "../7z/7zMethods.h"
+
+namespace NArchive {
+namespace NNsis {
+
+static const N7z::CMethodID k_Copy = { { 0x0 }, 1 };
+static const N7z::CMethodID k_Deflate = { { 0x4, 0x9, 0x1 }, 3 };
+static const N7z::CMethodID k_BZip2 = { { 0x4, 0x9, 0x2 }, 3 };
+static const N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
+static const N7z::CMethodID k_BCJ_X86 = { { 0x3, 0x3, 0x1, 0x3 }, 4 };
+
+CDecoder::CDecoder()
+{
+ N7z::LoadMethodMap();
+}
+
+HRESULT CDecoder::Init(IInStream *inStream, NMethodType::EEnum method, bool thereIsFilterFlag, bool &useFilter)
+{
+ useFilter = false;
+ CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
+
+ if (_decoderInStream)
+ if (method != _method)
+ Release();
+ _method = method;
+ if (!_codecInStream)
+ {
+ const NArchive::N7z::CMethodID *methodID = 0;
+ switch (method)
+ {
+ case NMethodType::kCopy:
+ methodID = &k_Copy;
+ break;
+ case NMethodType::kDeflate:
+ methodID = &k_Deflate;
+ break;
+ case NMethodType::kBZip2:
+ methodID = &k_BZip2;
+ break;
+ case NMethodType::kLZMA:
+ methodID = &k_LZMA;
+ break;
+ default:
+ return E_NOTIMPL;
+ }
+ N7z::CMethodInfo methodInfo;
+ if (!N7z::GetMethodInfo(*methodID, methodInfo))
+ return E_NOTIMPL;
+ CMyComPtr<ICompressCoder> coder;
+ RINOK(_libraries.CreateCoder(methodInfo.FilePath, methodInfo.Decoder, &coder));
+ coder.QueryInterface(IID_ISequentialInStream, &_codecInStream);
+ if (!_codecInStream)
+ return E_NOTIMPL;
+ }
+
+ if (thereIsFilterFlag)
+ {
+ UInt32 processedSize;
+ BYTE flag;
+ RINOK(inStream->Read(&flag, 1, &processedSize));
+ if (processedSize != 1)
+ return E_FAIL;
+ if (flag > 1)
+ return E_NOTIMPL;
+ useFilter = (flag != 0);
+ }
+
+ if (useFilter)
+ {
+ if (!_filterInStream)
+ {
+ N7z::CMethodInfo methodInfo;
+ if (!N7z::GetMethodInfo(k_BCJ_X86, methodInfo))
+ return E_NOTIMPL;
+ CMyComPtr<ICompressCoder> coder;
+ RINOK(_libraries.CreateCoderSpec(methodInfo.FilePath, methodInfo.Decoder, &coder));
+ coder.QueryInterface(IID_ISequentialInStream, &_filterInStream);
+ if (!_filterInStream)
+ return E_NOTIMPL;
+ }
+ CMyComPtr<ICompressSetInStream> setInStream;
+ _filterInStream.QueryInterface(IID_ICompressSetInStream, &setInStream);
+ if (!setInStream)
+ return E_NOTIMPL;
+ RINOK(setInStream->SetInStream(_codecInStream));
+ _decoderInStream = _filterInStream;
+ }
+ else
+ _decoderInStream = _codecInStream;
+
+ if (method == NMethodType::kLZMA)
+ {
+ CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
+ _codecInStream.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
+ if (setDecoderProperties)
+ {
+ static const UInt32 kPropertiesSize = 5;
+ BYTE properties[kPropertiesSize];
+ UInt32 processedSize;
+ RINOK(inStream->Read(properties, kPropertiesSize, &processedSize));
+ if (processedSize != kPropertiesSize)
+ return E_FAIL;
+ RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)properties, kPropertiesSize));
+ }
+ }
+
+ {
+ CMyComPtr<ICompressSetInStream> setInStream;
+ _codecInStream.QueryInterface(IID_ICompressSetInStream, &setInStream);
+ if (!setInStream)
+ return E_NOTIMPL;
+ RINOK(setInStream->SetInStream(inStream));
+ }
+
+ {
+ CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize;
+ _codecInStream.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize);
+ if (!setOutStreamSize)
+ return E_NOTIMPL;
+ RINOK(setOutStreamSize->SetOutStreamSize(NULL));
+ }
+
+ if (useFilter)
+ {
+ /*
+ CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize;
+ _filterInStream.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize);
+ if (!setOutStreamSize)
+ return E_NOTIMPL;
+ RINOK(setOutStreamSize->SetOutStreamSize(NULL));
+ */
+ }
+
+ return S_OK;
+}
+
+HRESULT CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ return ReadStream(_decoderInStream, data, size, processedSize);;
+}
+
+}}
diff --git a/CPP/7zip/Archive/Nsis/NsisDecode.h b/CPP/7zip/Archive/Nsis/NsisDecode.h
new file mode 100755
index 00000000..1bec178f
--- /dev/null
+++ b/CPP/7zip/Archive/Nsis/NsisDecode.h
@@ -0,0 +1,47 @@
+// NsisDecode.h
+
+#ifndef __NSIS_DECODE_H
+#define __NSIS_DECODE_H
+
+#include "../../IStream.h"
+
+#include "../Common/CoderLoader.h"
+
+namespace NArchive {
+namespace NNsis {
+
+namespace NMethodType
+{
+ enum EEnum
+ {
+ kCopy,
+ kDeflate,
+ kBZip2,
+ kLZMA
+ };
+}
+
+class CDecoder
+{
+ NMethodType::EEnum _method;
+ CCoderLibraries _libraries;
+
+ CMyComPtr<ISequentialInStream> _filterInStream;
+ CMyComPtr<ISequentialInStream> _codecInStream;
+ CMyComPtr<ISequentialInStream> _decoderInStream;
+
+public:
+ CDecoder();
+ void Release()
+ {
+ _filterInStream.Release();
+ _codecInStream.Release();
+ _decoderInStream.Release();
+ }
+ HRESULT Init(IInStream *inStream, NMethodType::EEnum method, bool thereIsFilterFlag, bool &useFilter);
+ HRESULT Read(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Nsis/NsisHandler.cpp b/CPP/7zip/Archive/Nsis/NsisHandler.cpp
new file mode 100755
index 00000000..0d840479
--- /dev/null
+++ b/CPP/7zip/Archive/Nsis/NsisHandler.cpp
@@ -0,0 +1,484 @@
+// NSisHandler.cpp
+
+#include "StdAfx.h"
+
+#include "NsisHandler.h"
+
+#include "Common/StringConvert.h"
+#include "Common/IntToString.h"
+#include "Common/NewHandler.h"
+#include "Common/ComTry.h"
+
+#include "Windows/PropVariant.h"
+
+#include "../Common/ItemNameUtils.h"
+
+using namespace NWindows;
+
+namespace NArchive {
+namespace NNsis {
+
+static const wchar_t *kBcjMethod = L"BCJ";
+static const wchar_t *kUnknownMethod = L"Unknown";
+
+static const wchar_t *kMethods[] =
+{
+ L"Copy",
+ L"Deflate",
+ L"BZip2",
+ L"LZMA"
+};
+
+static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]);
+
+STATPROPSTG kProperties[] =
+{
+ { NULL, kpidPath, VT_BSTR},
+ { NULL, kpidIsFolder, VT_BOOL},
+ { NULL, kpidSize, VT_UI8},
+ { NULL, kpidPackedSize, VT_UI8},
+ { NULL, kpidLastWriteTime, VT_FILETIME},
+ { NULL, kpidMethod, VT_BSTR},
+ { NULL, kpidSolid, VT_BOOL}
+};
+
+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;
+ *name = 0;
+ 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::Open(IInStream *stream, const UInt64 * maxCheckStartPosition, IArchiveOpenCallback * /* openArchiveCallback */)
+{
+ COM_TRY_BEGIN
+ Close();
+ {
+ if(_archive.Open(stream, maxCheckStartPosition) != S_OK)
+ return S_FALSE;
+ _inStream = stream;
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ _archive.Clear();
+ _archive.Release();
+ _inStream.Release();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = _archive.Items.Size()
+ #ifdef NSIS_SCRIPT
+ + 1
+ #endif
+ ;
+ return S_OK;
+}
+
+static UString ConvertUInt32ToString(UInt32 value)
+{
+ wchar_t buffer[32];
+ ConvertUInt64ToString(value, buffer);
+ return buffer;
+}
+
+static UString GetStringForSizeValue(UInt32 value)
+{
+ for (int i = 31; i >= 0; i--)
+ if ((UInt32(1) << i) == value)
+ return ConvertUInt32ToString(i);
+ UString result;
+ if (value % (1 << 20) == 0)
+ {
+ result += ConvertUInt32ToString(value >> 20);
+ result += L"m";
+ }
+ else if (value % (1 << 10) == 0)
+ {
+ result += ConvertUInt32ToString(value >> 10);
+ result += L"k";
+ }
+ else
+ {
+ result += ConvertUInt32ToString(value);
+ result += L"b";
+ }
+ return result;
+}
+
+bool CHandler::GetUncompressedSize(int index, UInt32 &size)
+{
+ size = 0;
+ const CItem &item = _archive.Items[index];
+ if (item.SizeIsDefined)
+ size = item.Size;
+ else if (_archive.IsSolid && item.EstimatedSizeIsDefined)
+ size = item.EstimatedSize;
+ else
+ return false;
+ return true;
+}
+
+bool CHandler::GetCompressedSize(int index, UInt32 &size)
+{
+ size = 0;
+ const CItem &item = _archive.Items[index];
+ if (item.CompressedSizeIsDefined)
+ size = item.CompressedSize;
+ else
+ {
+ if (_archive.IsSolid)
+ {
+ if (index == 0)
+ size = _archive.FirstHeader.GetDataSize();
+ else
+ return false;
+ }
+ else
+ {
+ if (!item.IsCompressed)
+ size = item.Size;
+ else
+ return false;
+ }
+ }
+ return true;
+}
+
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant propVariant;
+ #ifdef NSIS_SCRIPT
+ if (index >= (UInt32)_archive.Items.Size())
+ {
+ switch(propID)
+ {
+ case kpidPath:
+ propVariant = L"[NSIS].nsi";
+ break;
+ case kpidIsFolder:
+ propVariant = false;
+ break;
+ case kpidSize:
+ case kpidPackedSize:
+ propVariant = (UInt64)_archive.Script.Length();
+ break;
+ case kpidSolid:
+ propVariant = false;
+ break;
+ }
+ }
+ else
+ #endif
+ {
+ const CItem &item = _archive.Items[index];
+ switch(propID)
+ {
+ case kpidPath:
+ {
+ const UString s = NItemName::WinNameToOSName(MultiByteToUnicodeString(item.GetReducedName(), CP_ACP));
+ propVariant = (const wchar_t *)s;
+ break;
+ }
+ case kpidIsFolder:
+ propVariant = false;
+ break;
+ case kpidSize:
+ {
+ UInt32 size;
+ if (GetUncompressedSize(index, size))
+ propVariant = (UInt64)size;
+ break;
+ }
+ case kpidPackedSize:
+ {
+ UInt32 size;
+ if (GetCompressedSize(index, size))
+ propVariant = (UInt64)size;
+ break;
+ }
+ case kpidLastWriteTime:
+ {
+ if (item.DateTime.dwHighDateTime > 0x01000000 &&
+ item.DateTime.dwHighDateTime < 0xFF000000)
+ propVariant = item.DateTime;
+ break;
+ }
+ case kpidMethod:
+ {
+ NMethodType::EEnum methodIndex = _archive.Method;
+ UString method;
+ if (_archive.IsSolid && _archive.UseFilter || !_archive.IsSolid && item.UseFilter)
+ {
+ method += kBcjMethod;
+ method += L" ";
+ }
+ method += (methodIndex < kNumMethods) ? kMethods[methodIndex] : kUnknownMethod;
+ if (methodIndex == NMethodType::kLZMA)
+ {
+ method += L":";
+ method += GetStringForSizeValue(_archive.IsSolid ? _archive.DictionarySize: item.DictionarySize);
+ }
+ propVariant = method;
+ break;
+ }
+ case kpidSolid:
+ propVariant = _archive.IsSolid;
+ break;
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
+ Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ bool testMode = (_aTestMode != 0);
+ bool allFilesMode = (numItems == UInt32(-1));
+ if (allFilesMode)
+ GetNumberOfItems(&numItems);
+ if(numItems == 0)
+ return S_OK;
+ UInt64 totalSize = 0;
+
+ UInt32 i;
+ for(i = 0; i < numItems; i++)
+ {
+ UInt32 index = (allFilesMode ? i : indices[i]);
+ #ifdef NSIS_SCRIPT
+ if (index >= (UInt32)_archive.Items.Size())
+ totalSize += _archive.Script.Length();
+ else
+ #endif
+ {
+ UInt32 size;
+ if (_archive.IsSolid)
+ {
+ GetUncompressedSize(index, size);
+ UInt64 pos = _archive.GetPosOfSolidItem(index);
+ if (pos > totalSize)
+ totalSize = pos + size;
+ }
+ else
+ {
+ GetCompressedSize(index, size);
+ totalSize += size;
+ }
+ }
+ }
+ extractCallback->SetTotal(totalSize);
+
+ UInt64 currentTotalSize = 0;
+ UInt32 currentItemSize = 0;
+
+ UInt64 streamPos = 0;
+ if (_archive.IsSolid)
+ {
+ RINOK(_inStream->Seek(_archive.StreamOffset, STREAM_SEEK_SET, NULL));
+ bool useFilter;
+ RINOK(_archive.Decoder.Init(_inStream, _archive.Method, _archive.FilterFlag, useFilter));
+ }
+
+ bool dataError = false;
+ for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
+ {
+ currentItemSize = 0;
+ RINOK(extractCallback->SetCompleted(&currentTotalSize));
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ Int32 askMode;
+ askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract;
+ UInt32 index = allFilesMode ? i : indices[i];
+
+ RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
+
+ #ifdef NSIS_SCRIPT
+ if (index >= (UInt32)_archive.Items.Size())
+ {
+ currentItemSize = _archive.Script.Length();
+ if(!testMode && (!realOutStream))
+ continue;
+ RINOK(extractCallback->PrepareOperation(askMode));
+ if (!testMode)
+ RINOK(realOutStream->Write((const char *)_archive.Script, (UInt32)_archive.Script.Length(), NULL));
+ }
+ else
+ #endif
+ {
+ const CItem &item = _archive.Items[index];
+
+ if (_archive.IsSolid)
+ GetUncompressedSize(index, currentItemSize);
+ else
+ GetCompressedSize(index, currentItemSize);
+
+ if(!testMode && (!realOutStream))
+ continue;
+
+ RINOK(extractCallback->PrepareOperation(askMode));
+
+ if (!dataError)
+ {
+ bool needDecompress = false;
+ bool sizeIsKnown = false;
+ UInt32 fullSize = 0;
+
+ const UInt32 kBufferLength = 1 << 11;
+ Byte buffer[kBufferLength];
+
+ if (_archive.IsSolid)
+ {
+ UInt64 pos = _archive.GetPosOfSolidItem(index);
+ while(streamPos < pos)
+ {
+ UInt32 curSize = (UInt32)MyMin(pos - streamPos, (UInt64)kBufferLength);
+ UInt32 processedSize;
+ HRESULT res = _archive.Decoder.Read(buffer, curSize, &processedSize);
+ if (res != S_OK)
+ {
+ if (res != S_FALSE)
+ return res;
+ dataError = true;
+ break;
+ }
+ if (processedSize == 0)
+ {
+ dataError = true;
+ break;
+ }
+ streamPos += processedSize;
+ }
+ if (streamPos == pos)
+ {
+ UInt32 processedSize;
+ RINOK(_archive.Decoder.Read(buffer, 4, &processedSize));
+ if (processedSize != 4)
+ return E_FAIL;
+ streamPos += processedSize;
+ fullSize = GetUInt32FromMemLE(buffer);
+ sizeIsKnown = true;
+ needDecompress = true;
+ }
+ }
+ else
+ {
+ RINOK(_inStream->Seek(_archive.GetPosOfNonSolidItem(index) + 4, STREAM_SEEK_SET, NULL));
+ if (item.IsCompressed)
+ {
+ needDecompress = true;
+ bool useFilter;
+ RINOK(_archive.Decoder.Init(_inStream, _archive.Method, _archive.FilterFlag, useFilter));
+ fullSize = GetUInt32FromMemLE(buffer);
+ }
+ else
+ fullSize = item.Size;
+ }
+ if (!dataError)
+ {
+ if (needDecompress)
+ {
+ UInt64 offset = 0;
+ while(!sizeIsKnown || fullSize > 0)
+ {
+ UInt32 curSize = kBufferLength;
+ if (sizeIsKnown && curSize > fullSize)
+ curSize = fullSize;
+ UInt32 processedSize;
+ HRESULT res = _archive.Decoder.Read(buffer, curSize, &processedSize);
+ if (res != S_OK)
+ {
+ if (res != S_FALSE)
+ return res;
+ dataError = true;
+ break;
+ }
+ if (processedSize == 0)
+ {
+ if (sizeIsKnown)
+ dataError = true;
+ break;
+ }
+
+ fullSize -= processedSize;
+ streamPos += processedSize;
+ offset += processedSize;
+
+ UInt64 completed;
+ if (_archive.IsSolid)
+ completed = streamPos;
+ else
+ completed = currentTotalSize + offset;
+ RINOK(extractCallback->SetCompleted(&completed));
+ if (!testMode)
+ RINOK(realOutStream->Write(buffer, processedSize, NULL));
+ }
+ }
+ else
+ {
+ while(fullSize > 0)
+ {
+ UInt32 curSize = MyMin(fullSize, kBufferLength);
+ UInt32 processedSize;
+ RINOK(_inStream->Read(buffer, curSize, &processedSize));
+ if (processedSize == 0)
+ {
+ dataError = true;
+ break;
+ }
+ fullSize -= processedSize;
+ streamPos += processedSize;
+ if (!testMode)
+ RINOK(realOutStream->Write(buffer, processedSize, 0));
+ }
+ }
+ }
+ }
+ }
+ if (!testMode)
+ realOutStream.Release();
+ RINOK(extractCallback->SetOperationResult(dataError ?
+ NArchive::NExtract::NOperationResult::kDataError :
+ NArchive::NExtract::NOperationResult::kOK));
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+}}
diff --git a/CPP/7zip/Archive/Nsis/NsisHandler.h b/CPP/7zip/Archive/Nsis/NsisHandler.h
new file mode 100755
index 00000000..1ff8b776
--- /dev/null
+++ b/CPP/7zip/Archive/Nsis/NsisHandler.h
@@ -0,0 +1,41 @@
+// NSisHandler.h
+
+#ifndef __NSIS_HANDLER_H
+#define __NSIS_HANDLER_H
+
+#include "Common/MyCom.h"
+#include "../IArchive.h"
+
+#include "NsisIn.h"
+
+namespace NArchive {
+namespace NNsis {
+
+class CHandler:
+ public IInArchive,
+ public CMyUnknownImp
+{
+ CMyComPtr<IInStream> _inStream;
+ CInArchive _archive;
+
+ bool GetUncompressedSize(int index, UInt32 &size);
+ bool GetCompressedSize(int index, UInt32 &size);
+
+public:
+ MY_UNKNOWN_IMP1(IInArchive)
+
+ 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);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Nsis/NsisIn.cpp b/CPP/7zip/Archive/Nsis/NsisIn.cpp
new file mode 100755
index 00000000..0db6ccfd
--- /dev/null
+++ b/CPP/7zip/Archive/Nsis/NsisIn.cpp
@@ -0,0 +1,1169 @@
+// Archive/NsisIn.cpp
+
+#include "StdAfx.h"
+
+#include "NsisIn.h"
+#include "NsisDecode.h"
+
+#include "Windows/Defs.h"
+
+#include "../../Common/StreamUtils.h"
+
+#include "Common/IntToString.h"
+
+namespace NArchive {
+namespace NNsis {
+
+Byte kSignature[kSignatureSize] = { 0xEF + 1, 0xBE, 0xAD, 0xDE,
+0x4E, 0x75, 0x6C, 0x6C, 0x73, 0x6F, 0x66, 0x74, 0x49, 0x6E, 0x73, 0x74};
+
+class SignatureInitializer
+{
+public:
+ SignatureInitializer() { kSignature[0]--; };
+} g_SignatureInitializer;
+
+static const char *kCrLf = "\x0D\x0A";
+
+UInt32 GetUInt32FromMemLE(const Byte *p)
+{
+ return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);
+}
+
+Byte CInArchive::ReadByte()
+{
+ if (_posInData >= _size)
+ throw 1;
+ return _data[_posInData++];
+}
+
+UInt32 CInArchive::ReadUInt32()
+{
+ UInt32 value = 0;
+ for (int i = 0; i < 4; i++)
+ value |= ((UInt32)(ReadByte()) << (8 * i));
+ return value;
+}
+
+void CInArchive::ReadBlockHeader(CBlockHeader &bh)
+{
+ bh.Offset = ReadUInt32();
+ bh.Num = ReadUInt32();
+}
+
+#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
+
+static int CompareItems(void *const *p1, void *const *p2, void * /* param */)
+{
+ RINOZ(MyCompare(
+ (**(const CItem **)p1).Pos,
+ (**(const CItem **)p2).Pos));
+ return 0;
+}
+
+AString CInArchive::ReadString(UInt32 pos)
+{
+ AString s;
+ UInt32 offset = GetOffset() + _stringsPos + pos;
+ for (;;)
+ {
+ if (offset >= _size)
+ throw 1;
+ char c = _data[offset++];
+ if (c == 0)
+ break;
+ s += c;
+ }
+ return s;
+}
+
+/*
+static AString ParsePrefix(const AString &prefix)
+{
+ AString res = prefix;
+ if (prefix.Length() >= 3)
+ {
+ if ((Byte)prefix[0] == 0xFD && (Byte)prefix[1] == 0x95 && (Byte)prefix[2] == 0x80)
+ res = "$INSTDIR" + prefix.Mid(3);
+ else if ((Byte)prefix[0] == 0xFD && (Byte)prefix[1] == 0x96 && (Byte)prefix[2] == 0x80)
+ res = "$OUTDIR" + prefix.Mid(3);
+ }
+ return res;
+}
+*/
+
+#define SYSREGKEY "Software\\Microsoft\\Windows\\CurrentVersion"
+
+/*
+# define CSIDL_PROGRAMS 0x2
+# define CSIDL_PRINTERS 0x4
+# define CSIDL_PERSONAL 0x5
+# define CSIDL_FAVORITES 0x6
+# define CSIDL_STARTUP 0x7
+# define CSIDL_RECENT 0x8
+# define CSIDL_SENDTO 0x9
+# define CSIDL_STARTMENU 0xB
+# define CSIDL_MYMUSIC 0xD
+# define CSIDL_MYVIDEO 0xE
+
+# define CSIDL_DESKTOPDIRECTORY 0x10
+# define CSIDL_NETHOOD 0x13
+# define CSIDL_FONTS 0x14
+# define CSIDL_TEMPLATES 0x15
+# define CSIDL_COMMON_STARTMENU 0x16
+# define CSIDL_COMMON_PROGRAMS 0x17
+# define CSIDL_COMMON_STARTUP 0x18
+# define CSIDL_COMMON_DESKTOPDIRECTORY 0x19
+# define CSIDL_APPDATA 0x1A
+# define CSIDL_PRINTHOOD 0x1B
+# define CSIDL_LOCAL_APPDATA 0x1C
+# define CSIDL_ALTSTARTUP 0x1D
+# define CSIDL_COMMON_ALTSTARTUP 0x1E
+# define CSIDL_COMMON_FAVORITES 0x1F
+
+# define CSIDL_INTERNET_CACHE 0x20
+# define CSIDL_COOKIES 0x21
+# define CSIDL_HISTORY 0x22
+# define CSIDL_COMMON_APPDATA 0x23
+# define CSIDL_WINDOWS 0x24
+# define CSIDL_SYSTEM 0x25
+# define CSIDL_PROGRAM_FILES 0x26
+# define CSIDL_MYPICTURES 0x27
+# define CSIDL_PROFILE 0x28
+# define CSIDL_PROGRAM_FILES_COMMON 0x2B
+# define CSIDL_COMMON_TEMPLATES 0x2D
+# define CSIDL_COMMON_DOCUMENTS 0x2E
+# define CSIDL_COMMON_ADMINTOOLS 0x2F
+
+# define CSIDL_ADMINTOOLS 0x30
+# define CSIDL_COMMON_MUSIC 0x35
+# define CSIDL_COMMON_PICTURES 0x36
+# define CSIDL_COMMON_VIDEO 0x37
+# define CSIDL_RESOURCES 0x38
+# define CSIDL_RESOURCES_LOCALIZED 0x39
+# define CSIDL_CDBURN_AREA 0x3B
+*/
+
+struct CCommandPair
+{
+ int NumParams;
+ const char *Name;
+};
+
+enum
+{
+ // 0
+ EW_INVALID_OPCODE, // zero is invalid. useful for catching errors. (otherwise an all zeroes instruction
+ // does nothing, which is easily ignored but means something is wrong.
+ EW_RET, // return from function call
+ EW_NOP, // Nop/Jump, do nothing: 1, [?new address+1:advance one]
+ EW_ABORT, // Abort: 1 [status]
+ EW_QUIT, // Quit: 0
+ EW_CALL, // Call: 1 [new address+1]
+ EW_UPDATETEXT, // Update status text: 2 [update str, ui_st_updateflag=?ui_st_updateflag:this]
+ EW_SLEEP, // Sleep: 1 [sleep time in milliseconds]
+ EW_BRINGTOFRONT, // BringToFront: 0
+ EW_CHDETAILSVIEW, // SetDetailsView: 2 [listaction,buttonaction]
+
+ // 10
+ EW_SETFILEATTRIBUTES, // SetFileAttributes: 2 [filename, attributes]
+ EW_CREATEDIR, // Create directory: 2, [path, ?update$INSTDIR]
+ EW_IFFILEEXISTS, // IfFileExists: 3, [file name, jump amount if exists, jump amount if not exists]
+ EW_SETFLAG, // Sets a flag: 2 [id, data]
+ EW_IFFLAG, // If a flag: 4 [on, off, id, new value mask]
+ EW_GETFLAG, // Gets a flag: 2 [output, id]
+ EW_RENAME, // Rename: 3 [old, new, rebootok]
+ EW_GETFULLPATHNAME, // GetFullPathName: 2 [output, input, ?lfn:sfn]
+ EW_SEARCHPATH, // SearchPath: 2 [output, filename]
+ EW_GETTEMPFILENAME, // GetTempFileName: 2 [output, base_dir]
+
+ // 20
+ EW_EXTRACTFILE, // File to extract: 6 [overwriteflag, output filename, compressed filedata, filedatetimelow, filedatetimehigh, allow ignore]
+ // overwriteflag: 0x1 = no. 0x0=force, 0x2=try, 0x3=if date is newer
+ EW_DELETEFILE, // Delete File: 2, [filename, rebootok]
+ EW_MESSAGEBOX, // MessageBox: 5,[MB_flags,text,retv1:retv2,moveonretv1:moveonretv2]
+ EW_RMDIR, // RMDir: 2 [path, recursiveflag]
+ EW_STRLEN, // StrLen: 2 [output, input]
+ EW_ASSIGNVAR, // Assign: 4 [variable (0-9) to assign, string to assign, maxlen, startpos]
+ EW_STRCMP, // StrCmp: 5 [str1, str2, jump_if_equal, jump_if_not_equal, case-sensitive?]
+ EW_READENVSTR, // ReadEnvStr/ExpandEnvStrings: 3 [output, string_with_env_variables, IsRead]
+ EW_INTCMP, // IntCmp: 6 [val1, val2, equal, val1<val2, val1>val2, unsigned?]
+ EW_INTOP, // IntOp: 4 [output, input1, input2, op] where op: 0=add, 1=sub, 2=mul, 3=div, 4=bor, 5=band, 6=bxor, 7=bnot input1, 8=lnot input1, 9=lor, 10=land], 11=1%2
+
+ // 30
+ EW_INTFMT, // IntFmt: [output, format, input]
+ EW_PUSHPOP, // Push/Pop/Exchange: 3 [variable/string, ?pop:push, ?exch]
+ EW_FINDWINDOW, // FindWindow: 5, [outputvar, window class,window name, window_parent, window_after]
+ EW_SENDMESSAGE, // SendMessage: 6 [output, hwnd, msg, wparam, lparam, [wparamstring?1:0 | lparamstring?2:0 | timeout<<2]
+ EW_ISWINDOW, // IsWindow: 3 [hwnd, jump_if_window, jump_if_notwindow]
+ EW_GETDLGITEM, // GetDlgItem: 3: [outputvar, dialog, item_id]
+ EW_SETCTLCOLORS, // SerCtlColors: 3: [hwnd, pointer to struct colors]
+ EW_SETBRANDINGIMAGE, // SetBrandingImage: 1: [Bitmap file]
+ EW_CREATEFONT, // CreateFont: 5: [handle output, face name, height, weight, flags]
+ EW_SHOWWINDOW, // ShowWindow: 2: [hwnd, show state]
+
+ // 40
+ EW_SHELLEXEC, // ShellExecute program: 4, [shell action, complete commandline, parameters, showwindow]
+ EW_EXECUTE, // Execute program: 3,[complete command line,waitflag,>=0?output errorcode]
+ EW_GETFILETIME, // GetFileTime; 3 [file highout lowout]
+ EW_GETDLLVERSION, // GetDLLVersion: 3 [file highout lowout]
+ EW_REGISTERDLL, // Register DLL: 3,[DLL file name, string ptr of function to call, text to put in display (<0 if none/pass parms), 1 - no unload, 0 - unload]
+ EW_CREATESHORTCUT, // Make Shortcut: 5, [link file, target file, parameters, icon file, iconindex|show mode<<8|hotkey<<16]
+ EW_COPYFILES, // CopyFiles: 3 [source mask, destination location, flags]
+ EW_REBOOT, // Reboot: 0
+ EW_WRITEINI, // Write INI String: 4, [Section, Name, Value, INI File]
+ EW_READINISTR, // ReadINIStr: 4 [output, section, name, ini_file]
+
+ // 50
+ EW_DELREG, // DeleteRegValue/DeleteRegKey: 4, [root key(int), KeyName, ValueName, delkeyonlyifempty]. ValueName is -1 if delete key
+ EW_WRITEREG, // Write Registry value: 5, [RootKey(int),KeyName,ItemName,ItemData,typelen]
+ // typelen=1 for str, 2 for dword, 3 for binary, 0 for expanded str
+ EW_READREGSTR, // ReadRegStr: 5 [output, rootkey(int), keyname, itemname, ==1?int::str]
+ EW_REGENUM, // RegEnum: 5 [output, rootkey, keyname, index, ?key:value]
+ EW_FCLOSE, // FileClose: 1 [handle]
+ EW_FOPEN, // FileOpen: 4 [name, openmode, createmode, outputhandle]
+ EW_FPUTS, // FileWrite: 3 [handle, string, ?int:string]
+ EW_FGETS, // FileRead: 4 [handle, output, maxlen, ?getchar:gets]
+ EW_FSEEK, // FileSeek: 4 [handle, offset, mode, >=0?positionoutput]
+ EW_FINDCLOSE, // FindClose: 1 [handle]
+
+ // 60
+ EW_FINDNEXT, // FindNext: 2 [output, handle]
+ EW_FINDFIRST, // FindFirst: 2 [filespec, output, handleoutput]
+ EW_WRITEUNINSTALLER, // WriteUninstaller: 3 [name, offset, icon_size]
+ EW_LOG, // LogText: 2 [0, text] / LogSet: [1, logstate]
+ EW_SECTIONSET, // SectionSetText: 3: [idx, 0, text]
+ // SectionGetText: 3: [idx, 1, output]
+ // SectionSetFlags: 3: [idx, 2, flags]
+ // SectionGetFlags: 3: [idx, 3, output]
+ EW_INSTTYPESET, // InstTypeSetFlags: 3: [idx, 0, flags]
+ // InstTypeGetFlags: 3: [idx, 1, output]
+ // instructions not actually implemented in exehead, but used in compiler.
+ EW_GETLABELADDR, // both of these get converted to EW_ASSIGNVAR
+ EW_GETFUNCTIONADDR,
+
+ EW_LOCKWINDOW
+};
+
+static CCommandPair kCommandPairs[] =
+{
+ { 0, "Invalid" },
+ { 0, "Return" },
+ { 1, "Goto" },
+ { 0, "Abort" },
+ { 0, "Quit" },
+ { 1, "Call" },
+ { 2, "UpdateSatusText" },
+ { 1, "Sleep" },
+ { 0, "BringToFront" },
+ { 2, "SetDetailsView" },
+
+ { 2, "SetFileAttributes" },
+ { 2, "SetOutPath" },
+ { 3, "IfFileExists" },
+ { 2, "SetFlag" },
+ { 4, "IfFlag" },
+ { 2, "GetFlag" },
+ { 3, "Rename" },
+ { 2, "GetFullPathName" },
+ { 2, "SearchPath" },
+ { 2, "GetTempFileName" },
+
+ { 6, "File" },
+ { 2, "Delete" },
+ { 5, "MessageBox" },
+ { 2, "RMDir" },
+ { 2, "Assign" },
+ { 4, "StrCpy" },
+ { 5, "StrCmp" },
+ { 3, "ReadEnvStr" },
+ { 6, "IntCmp" },
+ { 4, "IntOp" },
+
+ { 3, "IntFmt" },
+ { 3, "PushPop" },
+ { 5, "FindWindow" },
+ { 6, "SendMessage" },
+ { 3, "IsWindow" },
+ { 3, "GetDlgItem" },
+ { 3, "SerCtlColors" },
+ { 1, "SetBrandingImage" },
+ { 5, "CreateFont" },
+ { 2, "ShowWindow" },
+
+ { 4, "ShellExecute" },
+ { 3, "Execute" },
+ { 3, "GetFileTime" },
+ { 3, "GetDLLVersion" },
+ { 3, "RegisterDLL" },
+ { 5, "CreateShortCut" },
+ { 3, "CopyFiles" },
+ { 0, "Reboot" },
+ { 4, "WriteINIStr" },
+ { 4, "ReadINIStr" },
+
+ { 4, "DelReg" },
+ { 5, "WriteReg" },
+ { 5, "ReadRegStr" },
+ { 5, "RegEnum" },
+ { 1, "FileClose" },
+ { 4, "FileOpen" },
+ { 3, "FileWrite" },
+ { 4, "FileRead" },
+ { 4, "FileSeek" },
+ { 1, "FindClose" },
+
+ { 2, "FindNext" },
+ { 2, "FindFirst" },
+ { 3, "WriteUninstaller" },
+ { 2, "LogText" },
+ { 3, "Section?etText" },
+ { 3, "InstType?etFlags" },
+ { 6, "GetLabelAddr" },
+ { 2, "GetFunctionAddress" },
+ { 6, "LockWindow" }
+};
+
+
+static const char *kShellStrings[] =
+{
+ "",
+ "",
+
+ "SMPROGRAMS",
+ "",
+ "PRINTERS",
+ "DOCUMENTS",
+ "FAVORITES",
+ "SMSTARTUP",
+ "RECENT",
+ "SENDTO",
+ "",
+ "STARTMENU",
+ "",
+ "MUSIC",
+ "VIDEO",
+ "",
+
+ "DESKTOP",
+ "",
+ "",
+ "NETHOOD",
+ "FONTS",
+ "TEMPLATES",
+ "COMMONSTARTMENU",
+ "COMMONFILES",
+ "COMMON_STARTUP",
+ "COMMON_DESKTOPDIRECTORY",
+ "QUICKLAUNCH",
+ "PRINTHOOD",
+ "LOCALAPPDATA",
+ "ALTSTARTUP",
+ "ALTSTARTUP",
+ "FAVORITES",
+
+ "INTERNET_CACHE",
+ "COOKIES",
+ "HISTORY",
+ "APPDATA",
+ "WINDIR",
+ "SYSDIR",
+ "PROGRAMFILES",
+ "PICTURES",
+ "PROFILE",
+ "",
+ "",
+ "COMMONFILES",
+ "",
+ "TEMPLATES",
+ "DOCUMENTS",
+ "ADMINTOOLS",
+
+ "ADMINTOOLS",
+ "",
+ "",
+ "",
+ "",
+ "MUSIC",
+ "PICTURES",
+ "VIDEO",
+ "RESOURCES",
+ "RESOURCES_LOCALIZED",
+ "",
+ "CDBURN_AREA"
+};
+
+static const int kNumShellStrings = sizeof(kShellStrings) / sizeof(kShellStrings[0]);
+
+/*
+# define CMDLINE 20 // everything before here doesn't have trailing slash removal
+# define INSTDIR 21
+# define OUTDIR 22
+# define EXEDIR 23
+# define LANGUAGE 24
+# define TEMP 25
+# define PLUGINSDIR 26
+# define HWNDPARENT 27
+# define _CLICK 28
+# define _OUTDIR 29
+*/
+
+static const char *kVarStrings[] =
+{
+ "CMDLINE",
+ "INSTDIR",
+ "OUTDIR",
+ "EXEDIR",
+ "LANGUAGE",
+ "TEMP",
+ "PLUGINSDIR",
+ "HWNDPARENT",
+ "_CLICK",
+ "_OUTDIR"
+};
+
+static const int kNumVarStrings = sizeof(kVarStrings) / sizeof(kVarStrings[0]);
+
+
+static AString UIntToString(UInt32 v)
+{
+ char sz[32];
+ ConvertUInt64ToString(v, sz);
+ return sz;
+}
+
+static AString IntToString(Int32 v)
+{
+ char sz[32];
+ ConvertInt64ToString(v, sz);
+ return sz;
+}
+
+static AString GetVar(UInt32 index)
+{
+ AString res = "$";
+ if (index < 10)
+ res += UIntToString(index);
+ else if (index < 20)
+ {
+ res += "R";
+ res += UIntToString(index - 10);
+ }
+ else if (index < 20 + kNumVarStrings)
+ res += kVarStrings[index - 20];
+ else
+ {
+ res += "[";
+ res += UIntToString(index);
+ res += "]";
+ }
+ return res;
+}
+
+// $0..$9, $INSTDIR, etc are encoded as ASCII bytes starting from this value.
+#define NS_SKIP_CODE 252
+#define NS_VAR_CODE 253
+#define NS_SHELL_CODE 254
+#define NS_LANG_CODE 255
+#define NS_CODES_START NS_SKIP_CODE
+
+// Based on Dave Laundon's simplified process_string
+AString GetNsisString(const AString &s)
+{
+ AString res;
+ for (int i = 0; i < s.Length();)
+ {
+ unsigned char nVarIdx = s[i++];
+ if (nVarIdx > NS_CODES_START && i + 2 <= s.Length())
+ {
+ int nData = s[i++] & 0x7F;
+ unsigned char c1 = s[i++];
+ nData |= (((int)(c1 & 0x7F)) << 7);
+
+ if (nVarIdx == NS_SHELL_CODE)
+ {
+ UInt32 index = c1;
+ bool needPrint = true;
+ res += "$";
+ if (index < kNumShellStrings)
+ {
+ const char *sz = kShellStrings[index];
+ if (sz[0] != 0)
+ {
+ res += sz;
+ needPrint = false;
+ }
+ }
+ if (needPrint)
+ {
+ res += "SHELL[";
+ res += UIntToString(index);
+ res += "]";
+ }
+ }
+ else if (nVarIdx == NS_VAR_CODE)
+ res += GetVar(nData);
+ else if (nVarIdx == NS_LANG_CODE)
+ res += "NS_LANG_CODE";
+ }
+ else if (nVarIdx == NS_SKIP_CODE)
+ {
+ if (i < s.Length())
+ res += s[i++];
+ }
+ else // Normal char
+ res += (char)nVarIdx;
+ }
+ return res;
+}
+
+AString CInArchive::ReadString2(UInt32 pos)
+{
+ return GetNsisString(ReadString(pos));
+}
+
+#define DEL_DIR 1
+#define DEL_RECURSE 2
+#define DEL_REBOOT 4
+// #define DEL_SIMPLE 8
+
+static const int kNumEntryParams = 6;
+
+struct CEntry
+{
+ UInt32 Which;
+ UInt32 Params[kNumEntryParams];
+ AString GetParamsString(int numParams);
+ CEntry()
+ {
+ Which = 0;
+ for (UInt32 j = 0; j < kNumEntryParams; j++)
+ Params[j] = 0;
+ }
+};
+
+AString CEntry::GetParamsString(int numParams)
+{
+ AString s;
+ for (int i = 0; i < numParams; i++)
+ {
+ s += " ";
+ UInt32 v = Params[i];
+ if (v > 0xFFF00000)
+ s += IntToString((Int32)Params[i]);
+ else
+ s += UIntToString(Params[i]);
+ }
+ return s;
+}
+
+HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
+{
+ _posInData = bh.Offset + GetOffset();
+ AString prefix;
+ for (UInt32 i = 0; i < bh.Num; i++)
+ {
+ CEntry e;
+ e.Which = ReadUInt32();
+ for (UInt32 j = 0; j < kNumEntryParams; j++)
+ e.Params[j] = ReadUInt32();
+ #ifdef NSIS_SCRIPT
+ if (e.Which != EW_PUSHPOP && e.Which < sizeof(kCommandPairs) / sizeof(kCommandPairs[0]))
+ {
+ const CCommandPair &pair = kCommandPairs[e.Which];
+ Script += pair.Name;
+ }
+ #endif
+
+ switch (e.Which)
+ {
+ case EW_CREATEDIR:
+ {
+ prefix.Empty();
+ prefix = ReadString2(e.Params[0]);
+ #ifdef NSIS_SCRIPT
+ Script += " ";
+ Script += prefix;
+ #endif
+ break;
+ }
+
+ case EW_EXTRACTFILE:
+ {
+ CItem item;
+ item.Prefix = prefix;
+ /* UInt32 overwriteFlag = e.Params[0]; */
+ item.Name = ReadString2(e.Params[1]);
+ item.Pos = e.Params[2];
+ item.DateTime.dwLowDateTime = e.Params[3];
+ item.DateTime.dwHighDateTime = e.Params[4];
+ /* UInt32 allowIgnore = e.Params[5]; */
+ if (Items.Size() > 0)
+ {
+ /*
+ if (item.Pos == Items.Back().Pos)
+ continue;
+ */
+ }
+ Items.Add(item);
+ #ifdef NSIS_SCRIPT
+ Script += " ";
+ Script += item.Name;
+ #endif
+ break;
+ }
+
+
+ #ifdef NSIS_SCRIPT
+ case EW_UPDATETEXT:
+ {
+ Script += " ";
+ Script += ReadString2(e.Params[0]);
+ Script += " ";
+ Script += UIntToString(e.Params[1]);
+ break;
+ }
+ case EW_SETFILEATTRIBUTES:
+ {
+ Script += " ";
+ Script += ReadString2(e.Params[0]);
+ Script += " ";
+ Script += UIntToString(e.Params[1]);
+ break;
+ }
+ case EW_IFFILEEXISTS:
+ {
+ Script += " ";
+ Script += ReadString2(e.Params[0]);
+ Script += " ";
+ Script += UIntToString(e.Params[1]);
+ Script += " ";
+ Script += UIntToString(e.Params[2]);
+ break;
+ }
+ case EW_RENAME:
+ {
+ Script += " ";
+ Script += ReadString2(e.Params[0]);
+ Script += " ";
+ Script += ReadString2(e.Params[1]);
+ Script += " ";
+ Script += UIntToString(e.Params[2]);
+ break;
+ }
+ case EW_GETFULLPATHNAME:
+ {
+ Script += " ";
+ Script += ReadString2(e.Params[0]);
+ Script += " ";
+ Script += ReadString2(e.Params[1]);
+ Script += " ";
+ Script += UIntToString(e.Params[2]);
+ break;
+ }
+ case EW_SEARCHPATH:
+ {
+ Script += " ";
+ Script += ReadString2(e.Params[0]);
+ Script += " ";
+ Script += ReadString2(e.Params[1]);
+ break;
+ }
+ case EW_GETTEMPFILENAME:
+ {
+ AString s;
+ Script += " ";
+ Script += ReadString2(e.Params[0]);
+ Script += " ";
+ Script += ReadString2(e.Params[1]);
+ break;
+ }
+
+ case EW_DELETEFILE:
+ {
+ UInt64 flag = e.Params[1];
+ if (flag != 0)
+ {
+ Script += " ";
+ if (flag == DEL_REBOOT)
+ Script += "/REBOOTOK";
+ else
+ Script += UIntToString(e.Params[1]);
+ }
+ Script += " ";
+ Script += ReadString2(e.Params[0]);
+ break;
+ }
+ case EW_RMDIR:
+ {
+ UInt64 flag = e.Params[1];
+ if (flag != 0)
+ {
+ if ((flag & DEL_REBOOT) != 0)
+ Script += " /REBOOTOK";
+ if ((flag & DEL_RECURSE) != 0)
+ Script += " /r";
+ }
+ Script += " ";
+ Script += ReadString2(e.Params[0]);
+ break;
+ }
+ case EW_ASSIGNVAR:
+ {
+ Script += " ";
+ Script += GetVar(e.Params[0]);;
+ Script += " \"";
+ AString maxLen, startOffset;
+ Script += ReadString2(e.Params[1]);
+ Script += "\"";
+ if (e.Params[2] != 0)
+ maxLen = ReadString(e.Params[2]);
+ if (e.Params[3] != 0)
+ startOffset = ReadString(e.Params[3]);
+ if (!maxLen.IsEmpty() || !startOffset.IsEmpty())
+ {
+ Script += " ";
+ if (maxLen.IsEmpty())
+ Script += "\"\"";
+ else
+ Script += maxLen;
+ if (!startOffset.IsEmpty())
+ {
+ Script += " ";
+ Script += startOffset;
+ }
+ }
+ break;
+ }
+ case EW_STRCMP:
+ {
+ Script += " ";
+
+ Script += " \"";
+ Script += ReadString2(e.Params[0]);
+ Script += "\"";
+
+ Script += " \"";
+ Script += ReadString2(e.Params[1]);
+ Script += "\"";
+
+ for (int j = 2; j < 5; j++)
+ {
+ Script += " ";
+ Script += UIntToString(e.Params[j]);
+ }
+ break;
+ }
+
+ case EW_PUSHPOP:
+ {
+ int isPop = (e.Params[1] != 0);
+ if (isPop)
+ {
+ Script += "Pop";
+ Script += " ";
+ Script += GetVar(e.Params[0]);;
+ }
+ else
+ {
+ int isExch = (e.Params[2] != 0);
+ if (isExch)
+ {
+ Script += "Exch";
+ }
+ else
+ {
+ Script += "Push";
+ Script += " ";
+ Script += ReadString2(e.Params[0]);
+ }
+ }
+ break;
+ }
+
+ /*
+ case EW_SENDMESSAGE:
+ {
+ Script += " ";
+ Script += IntToString(e.Params[0]);
+ Script += " ";
+ Script += GetVar(e.Params[1]);
+ Script += " ";
+ Script += ReadString2(e.Params[2]);
+ Script += " ";
+ Script += UIntToString(e.Params[3]);
+ Script += " ";
+ Script += IntToString(e.Params[4]);
+ Script += " ";
+ Script += UIntToString(e.Params[5]);
+ break;
+ }
+ */
+
+ case EW_REGISTERDLL:
+ {
+ Script += " ";
+ Script += ReadString2(e.Params[0]);
+ Script += " ";
+ Script += ReadString2(e.Params[1]);
+ Script += " ";
+ Script += UIntToString(e.Params[2]);
+ break;
+ }
+
+ case EW_CREATESHORTCUT:
+ {
+ AString s;
+
+ Script += " ";
+ Script += " \"";
+ Script += ReadString2(e.Params[0]);
+ Script += " \"";
+
+ Script += " ";
+ Script += " \"";
+ Script += ReadString2(e.Params[1]);
+ Script += " \"";
+
+ for (int j = 2; j < 5; j++)
+ {
+ Script += " ";
+ Script += UIntToString(e.Params[j]);
+ }
+ break;
+ }
+
+ /*
+ case EW_DELREG:
+ {
+ AString keyName, valueName;
+ keyName = ReadString2(e.Params[1]);
+ bool isValue = (e.Params[2] != -1);
+ if (isValue)
+ {
+ valueName = ReadString2(e.Params[2]);
+ Script += "Key";
+ }
+ else
+ Script += "Value";
+ Script += " ";
+ Script += UIntToString(e.Params[0]);
+ Script += " ";
+ Script += keyName;
+ if (isValue)
+ {
+ Script += " ";
+ Script += valueName;
+ }
+ Script += " ";
+ Script += UIntToString(e.Params[3]);
+ break;
+ }
+ */
+
+ case EW_WRITEUNINSTALLER:
+ {
+ Script += " ";
+ Script += ReadString2(e.Params[0]);
+ for (int j = 1; j < 3; j++)
+ {
+ Script += " ";
+ Script += UIntToString(e.Params[j]);
+ }
+ break;
+ }
+
+ default:
+ {
+ int numParams = kNumEntryParams;
+ if (e.Which < sizeof(kCommandPairs) / sizeof(kCommandPairs[0]))
+ {
+ const CCommandPair &pair = kCommandPairs[e.Which];
+ // Script += pair.Name;
+ numParams = pair.NumParams;
+ }
+ else
+ {
+ Script += "Unknown";
+ Script += UIntToString(e.Which);
+ }
+ Script += e.GetParamsString(numParams);
+ }
+ #endif
+ }
+ #ifdef NSIS_SCRIPT
+ Script += kCrLf;
+ #endif
+ }
+
+ {
+ Items.Sort(CompareItems, 0);
+ int i;
+ for (i = 0; i + 1 < Items.Size();)
+ {
+ if (Items[i].Pos == Items[i + 1].Pos)
+ Items.Delete(i + 1);
+ else
+ i++;
+ }
+ for (i = 0; i + 1 < Items.Size(); i++)
+ {
+ CItem &item = Items[i];
+ item.EstimatedSizeIsDefined = true;
+ item.EstimatedSize = Items[i + 1].Pos - item.Pos - 4;
+ }
+ if (!IsSolid)
+ {
+ for (i = 0; i < Items.Size(); i++)
+ {
+ CItem &item = Items[i];
+ RINOK(_stream->Seek(GetPosOfNonSolidItem(i), STREAM_SEEK_SET, NULL));
+ const UInt32 kSigSize = 4 + 1 + 5;
+ BYTE sig[kSigSize];
+ UInt32 processedSize;
+ RINOK(ReadStream(_stream, sig, kSigSize, &processedSize));
+ if (processedSize < 4)
+ return S_FALSE;
+ UInt32 size = GetUInt32FromMemLE(sig);
+ if ((size & 0x80000000) != 0)
+ {
+ item.IsCompressed = true;
+ // is compressed;
+ size &= ~0x80000000;
+ if (Method == NMethodType::kLZMA)
+ {
+ if (processedSize < 9)
+ return S_FALSE;
+ if (FilterFlag)
+ item.UseFilter = (sig[4] != 0);
+ item.DictionarySize = GetUInt32FromMemLE(sig + 5 + (FilterFlag ? 1 : 0));
+ }
+ }
+ else
+ {
+ item.IsCompressed = false;
+ item.Size = size;
+ item.SizeIsDefined = true;
+ }
+ item.CompressedSize = size;
+ item.CompressedSizeIsDefined = true;
+ }
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::Parse()
+{
+ // UInt32 offset = ReadUInt32();
+ // ???? offset == FirstHeader.HeaderLength
+ /* UInt32 ehFlags = */ ReadUInt32();
+ CBlockHeader bhPages, bhSections, bhEntries, bhStrings, bhLangTables, bhCtlColors, bhData;
+ // CBlockHeader bgFont;
+ ReadBlockHeader(bhPages);
+ ReadBlockHeader(bhSections);
+ ReadBlockHeader(bhEntries);
+ ReadBlockHeader(bhStrings);
+ ReadBlockHeader(bhLangTables);
+ ReadBlockHeader(bhCtlColors);
+ // ReadBlockHeader(bgFont);
+ ReadBlockHeader(bhData);
+
+ _stringsPos = bhStrings.Offset;
+
+ return ReadEntries(bhEntries);
+}
+
+static bool IsLZMA(const Byte *p, UInt32 &dictionary)
+{
+ dictionary = GetUInt32FromMemLE(p + 1);
+ return (p[0] == 0x5D && p[1] == 0x00 && p[2] == 0x00 && p[5] == 0x00);
+}
+
+static bool IsLZMA(const Byte *p, UInt32 &dictionary, bool &thereIsFlag)
+{
+ if (IsLZMA(p, dictionary))
+ {
+ thereIsFlag = false;
+ return true;
+ }
+ if (IsLZMA(p + 1, dictionary))
+ {
+ thereIsFlag = true;
+ return true;
+ }
+ return false;
+}
+
+HRESULT CInArchive::Open2()
+{
+ RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &StreamOffset));
+
+ const UInt32 kSigSize = 4 + 1 + 5 + 1; // size, flag, lzma props, lzma first byte
+ BYTE sig[kSigSize];
+ UInt32 processedSize;
+ RINOK(ReadStream(_stream, sig, kSigSize, &processedSize));
+ if (processedSize != kSigSize)
+ return S_FALSE;
+ UInt64 position;
+ RINOK(_stream->Seek(StreamOffset, STREAM_SEEK_SET, &position));
+
+ _headerIsCompressed = true;
+ IsSolid = true;
+ FilterFlag = false;
+
+ UInt32 compressedHeaderSize = GetUInt32FromMemLE(sig);
+
+ if (compressedHeaderSize == FirstHeader.HeaderLength)
+ {
+ _headerIsCompressed = false;
+ IsSolid = false;
+ Method = NMethodType::kCopy;
+ }
+ else if (IsLZMA(sig, DictionarySize, FilterFlag))
+ {
+ Method = NMethodType::kLZMA;
+ }
+ else if (IsLZMA(sig + 4, DictionarySize, FilterFlag))
+ {
+ IsSolid = false;
+ Method = NMethodType::kLZMA;
+ }
+ else if (sig[3] == 0x80)
+ {
+ IsSolid = false;
+ Method = NMethodType::kDeflate;
+ }
+ else
+ {
+ Method = NMethodType::kDeflate;
+ }
+
+ _posInData = 0;
+ if (!IsSolid)
+ {
+ _headerIsCompressed = ((compressedHeaderSize & 0x80000000) != 0);
+ if (_headerIsCompressed)
+ compressedHeaderSize &= ~0x80000000;
+ _nonSolidStartOffset = compressedHeaderSize;
+ RINOK(_stream->Seek(StreamOffset + 4, STREAM_SEEK_SET, NULL));
+ }
+ UInt32 unpackSize = FirstHeader.HeaderLength;
+ if (_headerIsCompressed)
+ {
+ // unpackSize = (1 << 23);
+ _data.SetCapacity(unpackSize);
+ RINOK(Decoder.Init(_stream, Method, FilterFlag, UseFilter));
+ UInt32 processedSize;
+ RINOK(Decoder.Read(_data, unpackSize, &processedSize));
+ if (processedSize != unpackSize)
+ return S_FALSE;
+ _size = (size_t)processedSize;
+ if (IsSolid)
+ {
+ UInt32 size2 = ReadUInt32();
+ if (size2 < _size)
+ _size = size2;
+ }
+ }
+ else
+ {
+ _data.SetCapacity(unpackSize);
+ _size = (size_t)unpackSize;
+ RINOK(ReadStream(_stream, (Byte *)_data, unpackSize, &processedSize));
+ if (processedSize != unpackSize)
+ return S_FALSE;
+ }
+ return Parse();
+}
+
+/*
+NsisExe =
+{
+ ExeStub
+ Archive // must start from 512 * N
+ #ifndef NSIS_CONFIG_CRC_ANAL
+ {
+ Some additional data
+ }
+}
+
+Archive
+{
+ FirstHeader
+ Data
+ #ifdef NSIS_CONFIG_CRC_SUPPORT && FirstHeader.ThereIsCrc()
+ {
+ CRC
+ }
+}
+
+FirstHeader
+{
+ UInt32 Flags;
+ Byte Signature[16];
+ // points to the header+sections+entries+stringtable in the datablock
+ UInt32 HeaderLength;
+ UInt32 ArchiveSize;
+}
+*/
+
+HRESULT CInArchive::Open(IInStream *inStream, const UInt64 *maxCheckStartPosition)
+{
+ Clear();
+ UInt64 pos;
+ RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &pos));
+ RINOK(inStream->Seek(0, STREAM_SEEK_END, &_archiveSize));
+ UInt64 position;
+ RINOK(inStream->Seek(pos, STREAM_SEEK_SET, &position));
+ UInt64 maxSize = (maxCheckStartPosition != 0) ? *maxCheckStartPosition : (1 << 20);
+ const UInt32 kStep = 512;
+ const UInt32 kStartHeaderSize = 4 * 7;
+ Byte buffer[kStep];
+ bool found = false;
+
+ UInt64 headerPosition = 0;
+ while (position <= maxSize)
+ {
+ UInt32 processedSize;
+ RINOK(ReadStream(inStream, buffer, kStartHeaderSize, &processedSize));
+ if (processedSize != kStartHeaderSize)
+ return S_FALSE;
+ headerPosition = position;
+ position += processedSize;
+ if(memcmp(buffer + 4, kSignature, kSignatureSize) == 0)
+ {
+ found = true;
+ break;
+ }
+ const UInt32 kRem = kStep - kStartHeaderSize;
+ RINOK(ReadStream(inStream, buffer + kStartHeaderSize, kRem, &processedSize));
+ if (processedSize != kRem)
+ return S_FALSE;
+ position += processedSize;
+ }
+ if (!found)
+ return S_FALSE;
+ FirstHeader.Flags = GetUInt32FromMemLE(buffer);
+ FirstHeader.HeaderLength = GetUInt32FromMemLE(buffer + kSignatureSize + 4);
+ FirstHeader.ArchiveSize = GetUInt32FromMemLE(buffer + kSignatureSize + 8);
+ if (_archiveSize - headerPosition < FirstHeader.ArchiveSize)
+ return S_FALSE;
+
+ _stream = inStream;
+ HRESULT res = S_FALSE;
+ try { res = Open2(); }
+ catch(...) { Clear(); res = S_FALSE; }
+ _stream.Release();
+ return res;
+}
+
+void CInArchive::Clear()
+{
+ #ifdef NSIS_SCRIPT
+ Script.Empty();
+ #endif
+ Items.Clear();
+}
+
+}}
diff --git a/CPP/7zip/Archive/Nsis/NsisIn.h b/CPP/7zip/Archive/Nsis/NsisIn.h
new file mode 100755
index 00000000..d75a9e6e
--- /dev/null
+++ b/CPP/7zip/Archive/Nsis/NsisIn.h
@@ -0,0 +1,166 @@
+// Archive/NsisIn.h
+
+#ifndef __ARCHIVE_NSIS_IN_H
+#define __ARCHIVE_NSIS_IN_H
+
+#include "Common/MyCom.h"
+#include "Common/IntToString.h"
+#include "Common/Buffer.h"
+
+#include "../../IStream.h"
+
+#include "NsisDecode.h"
+
+// #define NSIS_SCRIPT
+
+namespace NArchive {
+namespace NNsis {
+
+const int kSignatureSize = 16;
+extern Byte kSignature[kSignatureSize];
+
+const UInt32 kFlagsMask = 0xF;
+namespace NFlags
+{
+ const UInt32 kUninstall = 1;
+ const UInt32 kSilent = 2;
+ const UInt32 kNoCrc = 4;
+ const UInt32 kForceCrc = 8;
+}
+
+struct CFirstHeader
+{
+ UInt32 Flags;
+ UInt32 HeaderLength;
+
+ UInt32 ArchiveSize;
+
+ bool ThereIsCrc() const
+ {
+ if ((Flags & NFlags::kForceCrc ) != 0)
+ return true;
+ return ((Flags & NFlags::kNoCrc) == 0);
+ }
+
+ UInt32 GetDataSize() const { return ArchiveSize - (ThereIsCrc() ? 4 : 0); }
+};
+
+
+struct CBlockHeader
+{
+ UInt32 Offset;
+ UInt32 Num;
+};
+
+struct CItem
+{
+ AString Prefix;
+ AString Name;
+ UInt32 Pos;
+ bool SizeIsDefined;
+ bool CompressedSizeIsDefined;
+ bool EstimatedSizeIsDefined;
+ UInt32 Size;
+ UInt32 CompressedSize;
+ UInt32 EstimatedSize;
+ FILETIME DateTime;
+ UInt32 DictionarySize;
+ bool IsCompressed;
+ bool UseFilter;
+ CItem(): UseFilter(false), SizeIsDefined(false), EstimatedSizeIsDefined(false),
+ IsCompressed(true), CompressedSizeIsDefined(false), Size(0) {}
+
+ bool IsINSTDIR() const
+ {
+ if (Prefix.Length() < 3)
+ return false;
+ return true;
+ }
+
+ AString GetReducedName() const
+ {
+ AString prefix = Prefix;
+ if (prefix.Length() > 0)
+ if (prefix[prefix.Length() - 1] != '\\')
+ prefix += '\\';
+ AString s2 = prefix + Name;
+ const int len = 9;
+ if (s2.Left(len).CompareNoCase("$INSTDIR\\") == 0)
+ s2 = s2.Mid(len);
+ return s2;
+ }
+
+};
+
+class CInArchive
+{
+ UInt64 _archiveSize;
+ CMyComPtr<IInStream> _stream;
+
+ Byte ReadByte();
+ UInt32 ReadUInt32();
+ HRESULT Open2();
+ void ReadBlockHeader(CBlockHeader &bh);
+ AString ReadString(UInt32 pos);
+ AString ReadString2(UInt32 pos);
+ HRESULT ReadEntries(const CBlockHeader &bh);
+ HRESULT Parse();
+
+ CByteBuffer _data;
+ UInt64 _size;
+
+ size_t _posInData;
+
+ UInt32 _stringsPos;
+
+
+ bool _headerIsCompressed;
+ UInt32 _nonSolidStartOffset;
+public:
+ HRESULT Open(IInStream *inStream, const UInt64 *maxCheckStartPosition);
+ void Clear();
+
+ UInt64 StreamOffset;
+ CDecoder Decoder;
+ CObjectVector<CItem> Items;
+ bool IsSolid;
+ CFirstHeader FirstHeader;
+ NMethodType::EEnum Method;
+ bool UseFilter;
+ UInt32 DictionarySize;
+ bool FilterFlag;
+
+ #ifdef NSIS_SCRIPT
+ AString Script;
+ #endif
+ UInt32 GetOffset() const { return IsSolid ? 4 : 0; }
+ UInt64 GetDataPos(int index)
+ {
+ const CItem &item = Items[index];
+ return GetOffset() + FirstHeader.HeaderLength + item.Pos;
+ }
+
+ UInt64 GetPosOfSolidItem(int index) const
+ {
+ const CItem &item = Items[index];
+ return 4 + FirstHeader.HeaderLength + item.Pos;
+ }
+
+ UInt64 GetPosOfNonSolidItem(int index) const
+ {
+ const CItem &item = Items[index];
+ return StreamOffset + _nonSolidStartOffset + 4 + item.Pos;
+ }
+
+ void Release()
+ {
+ Decoder.Release();
+ }
+
+};
+
+UInt32 GetUInt32FromMemLE(const Byte *p);
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Nsis/StdAfx.cpp b/CPP/7zip/Archive/Nsis/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Archive/Nsis/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Archive/Nsis/StdAfx.h b/CPP/7zip/Archive/Nsis/StdAfx.h
new file mode 100755
index 00000000..2e4be10b
--- /dev/null
+++ b/CPP/7zip/Archive/Nsis/StdAfx.h
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/Archive/Nsis/makefile b/CPP/7zip/Archive/Nsis/makefile
new file mode 100755
index 00000000..69fcf523
--- /dev/null
+++ b/CPP/7zip/Archive/Nsis/makefile
@@ -0,0 +1,67 @@
+PROG = nsis.dll
+DEF_FILE = ../Archive.def
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib user32.lib
+
+TAR_OBJS = \
+ $O\DllExports.obj \
+ $O\NsisDecode.obj \
+ $O\NsisHandler.obj \
+ $O\NsisIn.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\IntToString.obj \
+ $O\NewHandler.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\Vector.obj \
+
+WIN_OBJS = \
+ $O\DLL.obj \
+ $O\FileFind.obj \
+ $O\PropVariant.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\LimitedStreams.obj \
+ $O\ProgressUtils.obj \
+ $O\StreamUtils.obj \
+
+AR_COMMON_OBJS = \
+ $O\CodecsPath.obj \
+ $O\CoderLoader.obj \
+ $O\ItemNameUtils.obj \
+ $O\FilterCoder.obj \
+
+7Z_OBJS = \
+ $O\7zMethodID.obj \
+ $O\7zMethods.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(TAR_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $(7Z_OBJS) \
+ $(COMPRESS_TAR_OBJS) \
+ $O\CopyCoder.obj \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(TAR_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)
+$(7Z_OBJS): ../7z/$(*B).cpp
+ $(COMPL)
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/Archive/Nsis/resource.rc b/CPP/7zip/Archive/Nsis/resource.rc
new file mode 100755
index 00000000..487eb4ee
--- /dev/null
+++ b/CPP/7zip/Archive/Nsis/resource.rc
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("Nsis Plugin", "nsis")
diff --git a/CPP/7zip/Archive/RPM/DllExports.cpp b/CPP/7zip/Archive/RPM/DllExports.cpp
new file mode 100755
index 00000000..ed21e64f
--- /dev/null
+++ b/CPP/7zip/Archive/RPM/DllExports.cpp
@@ -0,0 +1,68 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+#include "../../ICoder.h"
+#include "RpmHandler.h"
+
+// {23170F69-40C1-278A-1000-000110EB0000}
+DEFINE_GUID(CLSID_CRpmHandler,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xEB, 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_CRpmHandler)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ if (*interfaceID != IID_IInArchive)
+ return E_NOINTERFACE;
+ CMyComPtr<IInArchive> inArchive = (IInArchive *)new NArchive::NRpm::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"Rpm";
+ break;
+ case NArchive::kClassID:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CRpmHandler, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NArchive::kExtension:
+ propVariant = L"rpm";
+ break;
+ case NArchive::kAddExtension:
+ propVariant = L".cpio.gz";
+ break;
+ case NArchive::kUpdate:
+ propVariant = false;
+ break;
+ case NArchive::kKeepName:
+ propVariant = false;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/CPP/7zip/Archive/RPM/Rpm.dsp b/CPP/7zip/Archive/RPM/Rpm.dsp
new file mode 100755
index 00000000..085fe137
--- /dev/null
+++ b/CPP/7zip/Archive/RPM/Rpm.dsp
@@ -0,0 +1,205 @@
+# Microsoft Developer Studio Project File - Name="Rpm" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=Rpm - 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 "Rpm.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 "Rpm.mak" CFG="Rpm - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Rpm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Rpm - 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)" == "Rpm - 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 "RPM_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RPM_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 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-zip\Formats\rpm.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Rpm - 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 "RPM_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 "RPM_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 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-zip\Formats\rpm.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "Rpm - Win32 Release"
+# Name "Rpm - 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=.\Rpm.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# End Group
+# Begin Group "7-zip Common"
+
+# PROP Default_Filter ""
+# 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 "Compress"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.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\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\RpmHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\RpmHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\RpmHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\RpmIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\RpmIn.h
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/Archive/RPM/Rpm.dsw b/CPP/7zip/Archive/RPM/Rpm.dsw
new file mode 100755
index 00000000..a67232ed
--- /dev/null
+++ b/CPP/7zip/Archive/RPM/Rpm.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Rpm"=.\Rpm.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Archive/RPM/RpmHandler.cpp b/CPP/7zip/Archive/RPM/RpmHandler.cpp
new file mode 100755
index 00000000..b1a5bf7d
--- /dev/null
+++ b/CPP/7zip/Archive/RPM/RpmHandler.cpp
@@ -0,0 +1,194 @@
+// RPM/Handler.cpp
+
+#include "StdAfx.h"
+
+#include "RpmHandler.h"
+#include "RpmIn.h"
+
+#include "Common/Defs.h"
+#include "Common/StringConvert.h"
+#include "Common/NewHandler.h"
+#include "Common/ComTry.h"
+
+#include "Windows/PropVariant.h"
+#include "Windows/Defs.h"
+
+#include "../../Common/StreamObjects.h"
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/LimitedStreams.h"
+
+#include "../../Compress/Copy/CopyCoder.h"
+#include "../Common/ItemNameUtils.h"
+
+using namespace NWindows;
+
+namespace NArchive {
+namespace NRpm {
+
+STATPROPSTG kProperties[] =
+{
+// { NULL, kpidPath, VT_BSTR},
+// { NULL, kpidIsFolder, VT_BOOL},
+ { NULL, kpidSize, VT_UI8},
+ { NULL, kpidPackedSize, VT_UI8}
+};
+
+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;
+ *name = 0;
+ 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::Open(IInStream *inStream,
+ const UInt64 * /* maxCheckStartPosition */,
+ IArchiveOpenCallback * /* openArchiveCallback */)
+{
+ COM_TRY_BEGIN
+ try
+ {
+ if(OpenArchive(inStream) != S_OK)
+ return S_FALSE;
+ RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Pos));
+ m_InStream = inStream;
+ UInt64 endPosition;
+ RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPosition));
+ m_Size = endPosition - m_Pos;
+ return S_OK;
+ }
+ catch(...)
+ {
+ return S_FALSE;
+ }
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ m_InStream.Release();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = 1;
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant propVariant;
+
+ switch(propID)
+ {
+ /*
+ case kpidPath:
+ propVariant = (const wchar_t *)L"a.cpio.gz";
+ break;
+ */
+ case kpidIsFolder:
+ propVariant = false;
+ break;
+ case kpidSize:
+ case kpidPackedSize:
+ propVariant = m_Size;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
+ Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ bool allFilesMode = (numItems == UInt32(-1));
+ if (allFilesMode)
+ numItems = 1;
+ if(numItems == 0)
+ return S_OK;
+ if(numItems != 1)
+ return E_FAIL;
+ if (indices[0] != 0)
+ return E_FAIL;
+
+ bool testMode = (_aTestMode != 0);
+
+ UInt64 currentTotalSize = 0;
+ RINOK(extractCallback->SetTotal(m_Size));
+ RINOK(extractCallback->SetCompleted(&currentTotalSize));
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ Int32 askMode;
+ askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
+ NArchive::NExtract::NAskMode::kExtract;
+ Int32 index = 0;
+
+ RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
+
+ if(!testMode && (!realOutStream))
+ return S_OK;
+
+ RINOK(extractCallback->PrepareOperation(askMode));
+
+ if (testMode)
+ {
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ return S_OK;
+ }
+
+ RINOK(m_InStream->Seek(m_Pos, STREAM_SEEK_SET, NULL));
+
+ CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
+
+ CLocalProgress *localProgressSpec = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
+ localProgressSpec->Init(extractCallback, false);
+
+ try
+ {
+ RINOK(copyCoder->Code(m_InStream, realOutStream, NULL, NULL, progress));
+ }
+ catch(...)
+ {
+ realOutStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
+ return S_OK;
+ }
+ realOutStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ return S_OK;
+ COM_TRY_END
+}
+
+}}
diff --git a/CPP/7zip/Archive/RPM/RpmHandler.h b/CPP/7zip/Archive/RPM/RpmHandler.h
new file mode 100755
index 00000000..484c6c54
--- /dev/null
+++ b/CPP/7zip/Archive/RPM/RpmHandler.h
@@ -0,0 +1,46 @@
+// RPM/Handler.h
+
+#ifndef __RPM_HANDLER_H
+#define __RPM_HANDLER_H
+
+#include "Common/MyCom.h"
+#include "../IArchive.h"
+
+namespace NArchive {
+namespace NRpm {
+
+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:
+ CMyComPtr<IInStream> m_InStream;
+ UInt64 m_Pos;
+ UInt64 m_Size;
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/RPM/RpmHeader.h b/CPP/7zip/Archive/RPM/RpmHeader.h
new file mode 100755
index 00000000..d76963bd
--- /dev/null
+++ b/CPP/7zip/Archive/RPM/RpmHeader.h
@@ -0,0 +1,63 @@
+// Archive/RpmHeader.h
+
+#ifndef __ARCHIVE_RPM_HEADER_H
+#define __ARCHIVE_RPM_HEADER_H
+
+#include "Common/Types.h"
+
+namespace NArchive {
+namespace NRpm {
+
+/* Reference: lib/signature.h of rpm package */
+#define RPMSIG_NONE 0 /* Do not change! */
+/* The following types are no longer generated */
+#define RPMSIG_PGP262_1024 1 /* No longer generated */ /* 256 byte */
+/* These are the new-style signatures. They are Header structures. */
+/* Inside them we can put any number of any type of signature we like. */
+
+#define RPMSIG_HEADERSIG 5 /* New Header style signature */
+
+const UInt32 kLeadSize = 96;
+struct CLead
+{
+ unsigned char Magic[4];
+ unsigned char Major; // not supported ver1, only support 2,3 and lator
+ unsigned char Minor;
+ UInt16 Type;
+ UInt16 ArchNum;
+ char Name[66];
+ UInt16 OSNum;
+ UInt16 SignatureType;
+ char Reserved[16]; // pad to 96 bytes -- 8 byte aligned
+ bool MagicCheck() const
+ { return Magic[0] == 0xed && Magic[1] == 0xab && Magic[2] == 0xee && Magic[3] == 0xdb; };
+};
+
+const UInt32 kEntryInfoSize = 16;
+/*
+struct CEntryInfo
+{
+ int Tag;
+ int Type;
+ int Offset; // Offset from beginning of data segment, only defined on disk
+ int Count;
+};
+*/
+
+// case: SignatureType == RPMSIG_HEADERSIG
+const UInt32 kCSigHeaderSigSize = 16;
+struct CSigHeaderSig
+{
+ unsigned char Magic[4];
+ UInt32 Reserved;
+ UInt32 IndexLen; // count of index entries
+ UInt32 DataLen; // number of bytes
+ bool MagicCheck()
+ { return Magic[0] == 0x8e && Magic[1] == 0xad && Magic[2] == 0xe8 && Magic[3] == 0x01; };
+ UInt32 GetLostHeaderLen()
+ { return IndexLen * kEntryInfoSize + DataLen; };
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/RPM/RpmIn.cpp b/CPP/7zip/Archive/RPM/RpmIn.cpp
new file mode 100755
index 00000000..c1600894
--- /dev/null
+++ b/CPP/7zip/Archive/RPM/RpmIn.cpp
@@ -0,0 +1,112 @@
+// Archive/RpmIn.cpp
+
+#include "StdAfx.h"
+
+#include "RpmIn.h"
+
+#include "RpmHeader.h"
+
+#include "Windows/Defs.h"
+#include "Common/MyCom.h"
+
+#include "../../Common/StreamUtils.h"
+
+namespace NArchive {
+namespace NRpm {
+
+static UInt16 GetUInt16(const char *data)
+{
+ return (UInt16)((Byte)data[1] | (((UInt16)(Byte)data[0]) << 8));
+}
+
+static UInt32 GetUInt32(const char *data)
+{
+ return
+ ((UInt32)(Byte)data[3]) |
+ (((UInt32)(Byte)data[2]) << 8) |
+ (((UInt32)(Byte)data[1]) << 16) |
+ (((UInt32)(Byte)data[0]) << 24);
+}
+
+static HRESULT RedSigHeaderSig(IInStream *inStream, CSigHeaderSig &h)
+{
+ char dat[kCSigHeaderSigSize];
+ char *cur = dat;
+ UInt32 processedSize;
+ RINOK(ReadStream(inStream, dat, kCSigHeaderSigSize, &processedSize));
+ if (kCSigHeaderSigSize != processedSize)
+ return S_FALSE;
+ memmove(h.Magic, cur, 4);
+ cur += 4;
+ cur += 4;
+ h.IndexLen = GetUInt32(cur);
+ cur += 4;
+ h.DataLen = GetUInt32(cur);
+ return S_OK;
+}
+
+HRESULT OpenArchive(IInStream *inStream)
+{
+ UInt64 pos;
+ char leadData[kLeadSize];
+ char *cur = leadData;
+ CLead lead;
+ UInt32 processedSize;
+ RINOK(ReadStream(inStream, leadData, kLeadSize, &processedSize));
+ if (kLeadSize != processedSize)
+ return S_FALSE;
+ memmove(lead.Magic, cur, 4);
+ cur += 4;
+ lead.Major = *cur++;
+ lead.Minor = *cur++;
+ lead.Type = GetUInt16(cur);
+ cur += 2;
+ lead.ArchNum = GetUInt16(cur);
+ cur += 2;
+ memmove(lead.Name, cur, sizeof(lead.Name));
+ cur += sizeof(lead.Name);
+ lead.OSNum = GetUInt16(cur);
+ cur += 2;
+ lead.SignatureType = GetUInt16(cur);
+ cur += 2;
+
+ if (!lead.MagicCheck() || lead.Major < 3)
+ return S_FALSE;
+
+ CSigHeaderSig sigHeader, header;
+ if(lead.SignatureType == RPMSIG_NONE)
+ {
+ ;
+ }
+ else if(lead.SignatureType == RPMSIG_PGP262_1024)
+ {
+ UInt64 pos;
+ RINOK(inStream->Seek(256, STREAM_SEEK_CUR, &pos));
+ }
+ else if(lead.SignatureType == RPMSIG_HEADERSIG)
+ {
+ RINOK(RedSigHeaderSig(inStream, sigHeader));
+ if(!sigHeader.MagicCheck())
+ return S_FALSE;
+ UInt32 len = sigHeader.GetLostHeaderLen();
+ RINOK(inStream->Seek(len, STREAM_SEEK_CUR, &pos));
+ if((pos % 8) != 0)
+ {
+ RINOK(inStream->Seek((pos / 8 + 1) * 8 - pos,
+ STREAM_SEEK_CUR, &pos));
+ }
+ }
+ else
+ return S_FALSE;
+
+ RINOK(RedSigHeaderSig(inStream, header));
+ if(!header.MagicCheck())
+ return S_FALSE;
+ int headerLen = header.GetLostHeaderLen();
+ if(headerLen == -1)
+ return S_FALSE;
+ RINOK(inStream->Seek(headerLen, STREAM_SEEK_CUR, &pos));
+ return S_OK;
+}
+
+}}
diff --git a/CPP/7zip/Archive/RPM/RpmIn.h b/CPP/7zip/Archive/RPM/RpmIn.h
new file mode 100755
index 00000000..ec798cb8
--- /dev/null
+++ b/CPP/7zip/Archive/RPM/RpmIn.h
@@ -0,0 +1,15 @@
+// Archive/RpmIn.h
+
+#ifndef __ARCHIVE_RPM_IN_H
+#define __ARCHIVE_RPM_IN_H
+
+#include "../../IStream.h"
+
+namespace NArchive {
+namespace NRpm {
+
+HRESULT OpenArchive(IInStream *inStream);
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/RPM/StdAfx.cpp b/CPP/7zip/Archive/RPM/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Archive/RPM/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Archive/RPM/StdAfx.h b/CPP/7zip/Archive/RPM/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Archive/RPM/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Archive/RPM/makefile b/CPP/7zip/Archive/RPM/makefile
new file mode 100755
index 00000000..afda1289
--- /dev/null
+++ b/CPP/7zip/Archive/RPM/makefile
@@ -0,0 +1,42 @@
+PROG = rpm.dll
+DEF_FILE = ../Archive.def
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib
+
+RPM_OBJS = \
+ $O\DllExports.obj \
+ $O\RpmHandler.obj \
+ $O\RpmIn.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\NewHandler.obj \
+
+WIN_OBJS = \
+ $O\PropVariant.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\ProgressUtils.obj \
+ $O\StreamUtils.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(RPM_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $O\CopyCoder.obj \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(RPM_OBJS): $(*B).cpp
+ $(COMPL)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/Archive/RPM/resource.rc b/CPP/7zip/Archive/RPM/resource.rc
new file mode 100755
index 00000000..926f09aa
--- /dev/null
+++ b/CPP/7zip/Archive/RPM/resource.rc
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("Rpm Plugin", "rpm")
+
+101 ICON "rpm.ico"
diff --git a/CPP/7zip/Archive/RPM/rpm.ico b/CPP/7zip/Archive/RPM/rpm.ico
new file mode 100755
index 00000000..cdeb8d1b
--- /dev/null
+++ b/CPP/7zip/Archive/RPM/rpm.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Rar/DllExports.cpp b/CPP/7zip/Archive/Rar/DllExports.cpp
new file mode 100755
index 00000000..921bffb2
--- /dev/null
+++ b/CPP/7zip/Archive/Rar/DllExports.cpp
@@ -0,0 +1,142 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+#include "../../ICoder.h"
+#include "../../IPassword.h"
+#include "../Common/CodecsPath.h"
+
+// {23170F69-40C1-278B-0601-010000000000}
+DEFINE_GUID(CLSID_CCrypto_AES128_Decoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+#include "RarHandler.h"
+
+HINSTANCE g_hInstance;
+#ifndef _UNICODE
+bool g_IsNT = false;
+static bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+#endif
+
+void GetCryptoFolderPrefix(TCHAR *path)
+{
+ CSysString s = GetCodecsFolderPrefix();
+ lstrcpy(path, s);
+}
+
+
+// {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);
+
+/*
+// {23170F69-40C1-278B-06F1-0302000000000}
+DEFINE_GUID(CLSID_CCryptoRar20Decoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00);
+
+// {23170F69-40C1-278B-06F1-0303000000000}
+DEFINE_GUID(CLSID_CCryptoRar29Decoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00);
+*/
+
+// {23170F69-40C1-278A-1000-000110030000}
+DEFINE_GUID(CLSID_CRarHandler,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x03, 0x00, 0x00);
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ g_hInstance = hInstance;
+ #ifndef _UNICODE
+ g_IsNT = IsItWindowsNT();
+ #endif
+ }
+ return TRUE;
+}
+
+STDAPI CreateObject(
+ const GUID *classID,
+ const GUID *interfaceID,
+ void **outObject)
+{
+ COM_TRY_BEGIN
+ *outObject = 0;
+ if (*classID != CLSID_CRarHandler)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ int needIn = *interfaceID == IID_IInArchive;
+ if (needIn)
+ {
+ NArchive::NRar::CHandler *temp = new NArchive::NRar::CHandler;
+ if (needIn)
+ {
+ CMyComPtr<IInArchive> inArchive = (IInArchive *)temp;
+ *outObject = inArchive.Detach();
+ }
+ else
+ {
+ CMyComPtr<IOutArchive> outArchive = (IOutArchive *)temp;
+ *outObject = outArchive.Detach();
+ }
+ }
+ else
+ return E_NOINTERFACE;
+ COM_TRY_END
+ return S_OK;
+}
+
+STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
+{
+ NWindows::NCOM::CPropVariant propVariant;
+ switch(propID)
+ {
+ case NArchive::kName:
+ propVariant = L"Rar";
+ break;
+ case NArchive::kClassID:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CRarHandler, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NArchive::kExtension:
+ propVariant = L"rar";
+ break;
+ case NArchive::kUpdate:
+ propVariant = false;
+ break;
+ case NArchive::kKeepName:
+ propVariant = false;
+ break;
+ case NArchive::kStartSignature:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)NArchive::NRar::NHeader::kMarker,
+ NArchive::NRar::NHeader::kMarkerSize)) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/CPP/7zip/Archive/Rar/Rar.dsp b/CPP/7zip/Archive/Rar/Rar.dsp
new file mode 100755
index 00000000..739024da
--- /dev/null
+++ b/CPP/7zip/Archive/Rar/Rar.dsp
@@ -0,0 +1,459 @@
+# Microsoft Developer Studio Project File - Name="Rar" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=Rar - 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 "Rar.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 "Rar.mak" CFG="Rar - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Rar - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Rar - 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)" == "Rar - 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 "RAR_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RAR_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\rar.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Rar - 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 "RAR_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 "RAR_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\rar.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "Rar - Win32 Release"
+# Name "Rar - 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 "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\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\DynamicBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.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\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
+
+SOURCE=..\..\..\Common\Vector.h
+# End Source File
+# End Group
+# Begin Group "Archive Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Common\CodecsPath.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CodecsPath.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CoderLoader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\FilterCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\FilterCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\IArchiveHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\InStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\InStreamWithCRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\OutStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\OutStreamWithCRC.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Handle.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Thread.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.h
+# End Source File
+# End Group
+# Begin Group "Engine"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\RarHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\RarHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\RarHeader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\RarHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\RarIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\RarIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\RarItem.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\RarItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\RarVolumeInStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\RarVolumeInStream.h
+# End Source File
+# End Group
+# Begin Group "Crypto"
+
+# PROP Default_Filter ""
+# Begin Group "Rar29"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\RarAES\RarAES.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\RarAES\RarAES.h
+# End Source File
+# End Group
+# Begin Group "Rar20"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\Rar20\Rar20Cipher.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Rar20\Rar20Cipher.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Rar20\Rar20Crypto.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Rar20\Rar20Crypto.h
+# End Source File
+# End Group
+# Begin Group "Hash"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\Sha1.cpp
+
+!IF "$(CFG)" == "Rar - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Rar - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\Sha1.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "7-zip Common"
+
+# PROP Default_Filter ""
+# 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\ProgressUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# End Group
+# Begin Group "7z"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\7z\7zMethodID.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\7z\7zMethodID.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\7z\7zMethods.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\7z\7zMethods.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\Rar.ico
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/Archive/Rar/Rar.dsw b/CPP/7zip/Archive/Rar/Rar.dsw
new file mode 100755
index 00000000..3dab87aa
--- /dev/null
+++ b/CPP/7zip/Archive/Rar/Rar.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Rar"=.\Rar.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Archive/Rar/RarHandler.cpp b/CPP/7zip/Archive/Rar/RarHandler.cpp
new file mode 100755
index 00000000..3389f0e2
--- /dev/null
+++ b/CPP/7zip/Archive/Rar/RarHandler.cpp
@@ -0,0 +1,941 @@
+// RarHandler.cpp
+
+#include "StdAfx.h"
+
+#include "RarHandler.h"
+
+#include "Common/StringConvert.h"
+#include "Common/ComTry.h"
+#include "Common/IntToString.h"
+
+#include "Windows/PropVariant.h"
+#include "Windows/Time.h"
+
+#include "../../IPassword.h"
+
+#include "../../Common//ProgressUtils.h"
+#include "../../Compress/Copy/CopyCoder.h"
+
+#include "../../Crypto/Rar20/Rar20Cipher.h"
+#include "../../Crypto/RarAES/RarAES.h"
+
+#include "../Common/OutStreamWithCRC.h"
+#include "../Common/CoderLoader.h"
+#include "../Common/CodecsPath.h"
+#include "../Common/FilterCoder.h"
+#include "../Common/ItemNameUtils.h"
+
+#include "../7z/7zMethods.h"
+
+using namespace NWindows;
+using namespace NTime;
+
+// {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);
+
+
+namespace NArchive {
+namespace NRar {
+
+static const wchar_t *kHostOS[] =
+{
+ L"MS DOS",
+ L"OS/2",
+ L"Win32",
+ L"Unix",
+ L"Mac OS",
+ L"BeOS"
+};
+
+static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
+
+static const wchar_t *kUnknownOS = L"Unknown";
+
+enum // PropID
+{
+ kpidUnPackVersion = kpidUserDefined
+};
+
+STATPROPSTG kProperties[] =
+{
+ { NULL, kpidPath, VT_BSTR},
+ { NULL, kpidIsFolder, VT_BOOL},
+ { NULL, kpidSize, VT_UI8},
+ { NULL, kpidPackedSize, VT_UI8},
+ { NULL, kpidLastWriteTime, VT_FILETIME},
+ { NULL, kpidCreationTime, VT_FILETIME},
+ { NULL, kpidLastAccessTime, VT_FILETIME},
+ { NULL, kpidAttributes, VT_UI4},
+
+
+ { NULL, kpidEncrypted, VT_BOOL},
+ { NULL, kpidSolid, VT_BOOL},
+ { NULL, kpidCommented, VT_BOOL},
+ { NULL, kpidSplitBefore, VT_BOOL},
+ { NULL, kpidSplitAfter, VT_BOOL},
+ { NULL, kpidCRC, VT_UI4},
+ { NULL, kpidHostOS, VT_BSTR},
+ { NULL, kpidMethod, VT_BSTR}
+ // { NULL, kpidDictionarySize, VT_UI4},
+ // { L"UnPack Version", kpidUnPackVersion, VT_UI1}
+};
+
+STATPROPSTG kArchiveProperties[] =
+{
+ { NULL, kpidSolid, VT_BOOL},
+ { NULL, kpidCommented, VT_BOOL},
+};
+
+UInt64 CHandler::GetPackSize(int refIndex) const
+{
+ const CRefItem &refItem = _refItems[refIndex];
+ UInt64 totalPackSize = 0;
+ for (int i = 0; i < refItem.NumItems; i++)
+ totalPackSize += _items[refItem.ItemIndex + i].PackSize;
+ return totalPackSize;
+}
+
+STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant propVariant;
+ switch(propID)
+ {
+ case kpidSolid:
+ propVariant = _archiveInfo.IsSolid();
+ break;
+ case kpidCommented:
+ propVariant = _archiveInfo.IsCommented();
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+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;
+ *name = 0;
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
+{
+ *numProperties = sizeof(kArchiveProperties) / sizeof(kArchiveProperties[0]);
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType)
+{
+ if(index >= sizeof(kArchiveProperties) / sizeof(kArchiveProperties[0]))
+ return E_INVALIDARG;
+ const STATPROPSTG &srcItem = kArchiveProperties[index];
+ *propID = srcItem.propid;
+ *varType = srcItem.vt;
+ *name = 0;
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = _refItems.Size();
+ return S_OK;
+}
+
+static bool RarTimeToFileTime(const CRarTime &rarTime, FILETIME &result)
+{
+ if (!DosTimeToFileTime(rarTime.DosTime, result))
+ return false;
+ UInt64 value = (((UInt64)result.dwHighDateTime) << 32) + result.dwLowDateTime;
+ value += (UInt64)rarTime.LowSecond * 10000000;
+ value += ((UInt64)rarTime.SubTime[2] << 16) +
+ ((UInt64)rarTime.SubTime[1] << 8) +
+ ((UInt64)rarTime.SubTime[0]);
+ result.dwLowDateTime = (DWORD)value;
+ result.dwHighDateTime = DWORD(value >> 32);
+ return true;
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant propVariant;
+ const CRefItem &refItem = _refItems[index];
+ const CItemEx &item = _items[refItem.ItemIndex];
+ switch(propID)
+ {
+ case kpidPath:
+ {
+ UString u;
+ if (item.HasUnicodeName() && !item.UnicodeName.IsEmpty())
+ u = item.UnicodeName;
+ else
+ u = MultiByteToUnicodeString(item.Name, CP_OEMCP);
+ propVariant = (const wchar_t *)NItemName::WinNameToOSName(u);
+ break;
+ }
+ case kpidIsFolder:
+ propVariant = item.IsDirectory();
+ break;
+ case kpidSize:
+ propVariant = item.UnPackSize;
+ break;
+ case kpidPackedSize:
+ {
+ propVariant = GetPackSize(index);
+ break;
+ }
+ case kpidLastWriteTime:
+ {
+ FILETIME localFileTime, utcFileTime;
+ if (RarTimeToFileTime(item.LastWriteTime, localFileTime))
+ {
+ if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
+ utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
+ }
+ else
+ utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
+ propVariant = utcFileTime;
+ break;
+ }
+ case kpidCreationTime:
+ {
+ if (item.IsCreationTimeDefined)
+ {
+ FILETIME localFileTime, utcFileTime;
+ if (RarTimeToFileTime(item.CreationTime, localFileTime))
+ {
+ if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
+ utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
+ }
+ else
+ utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
+ propVariant = utcFileTime;
+ }
+ break;
+ }
+ case kpidLastAccessTime:
+ {
+ if (item.IsLastAccessTimeDefined)
+ {
+ FILETIME localFileTime, utcFileTime;
+ if (RarTimeToFileTime(item.LastAccessTime, localFileTime))
+ {
+ if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
+ utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
+ }
+ else
+ utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
+ propVariant = utcFileTime;
+ }
+ break;
+ }
+ case kpidAttributes:
+ propVariant = item.GetWinAttributes();
+ break;
+ case kpidEncrypted:
+ propVariant = item.IsEncrypted();
+ break;
+ case kpidSolid:
+ propVariant = IsSolid(index);
+ break;
+ case kpidCommented:
+ propVariant = item.IsCommented();
+ break;
+ case kpidSplitBefore:
+ propVariant = item.IsSplitBefore();
+ break;
+ case kpidSplitAfter:
+ propVariant = _items[refItem.ItemIndex + refItem.NumItems - 1].IsSplitAfter();
+ break;
+ /*
+ case kpidDictionarySize:
+ if (!item.IsDirectory())
+ propVariant = UInt32(0x10000 << item.GetDictSize());
+ break;
+ */
+ case kpidCRC:
+ {
+ const CItemEx &lastItem =
+ _items[refItem.ItemIndex + refItem.NumItems - 1];
+ if (lastItem.IsSplitAfter())
+ propVariant = item.FileCRC;
+ else
+ propVariant = lastItem.FileCRC;
+ break;
+ }
+ case kpidUnPackVersion:
+ propVariant = item.UnPackVersion;
+ break;
+ case kpidMethod:
+ {
+ UString method;
+ if (item.Method >= Byte('0') && item.Method <= Byte('5'))
+ {
+ method = L"m";
+ wchar_t temp[32];
+ ConvertUInt64ToString(item.Method - Byte('0'), temp);
+ method += temp;
+ if (!item.IsDirectory())
+ {
+ method += L":";
+ ConvertUInt64ToString(16 + item.GetDictSize(), temp);
+ method += temp;
+ }
+ }
+ else
+ {
+ wchar_t temp[32];
+ ConvertUInt64ToString(item.Method, temp);
+ method += temp;
+ }
+ propVariant = method;
+ break;
+ }
+ case kpidHostOS:
+ propVariant = (item.HostOS < kNumHostOSes) ?
+ (kHostOS[item.HostOS]) : kUnknownOS;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+class CVolumeName
+{
+ bool _first;
+ bool _newStyle;
+ UString _unchangedPart;
+ UString _changedPart;
+ UString _afterPart;
+public:
+ CVolumeName(): _newStyle(true) {};
+
+ bool InitName(const UString &name, bool newStyle)
+ {
+ _first = true;
+ _newStyle = newStyle;
+ int dotPos = name.ReverseFind('.');
+ UString basePart = name;
+ if (dotPos >= 0)
+ {
+ UString ext = name.Mid(dotPos + 1);
+ if (ext.CompareNoCase(L"RAR")==0 ||
+ ext.CompareNoCase(L"EXE") == 0)
+ {
+ _afterPart = L".rar";
+ basePart = name.Left(dotPos);
+ }
+ }
+
+ if (!_newStyle)
+ {
+ _afterPart.Empty();
+ _unchangedPart = basePart + UString(L".");
+ _changedPart = L"r00";
+ return true;;
+ }
+
+ int numLetters = 1;
+ if (basePart.Right(numLetters) == L"1")
+ {
+ while (numLetters < basePart.Length())
+ {
+ if (basePart[basePart.Length() - numLetters - 1] != '0')
+ break;
+ numLetters++;
+ }
+ }
+ else
+ return false;
+ _unchangedPart = basePart.Left(basePart.Length() - numLetters);
+ _changedPart = basePart.Right(numLetters);
+ return true;
+ }
+
+ UString GetNextName()
+ {
+ UString newName;
+ if (_newStyle || !_first)
+ {
+ int i;
+ int numLetters = _changedPart.Length();
+ for (i = numLetters - 1; i >= 0; i--)
+ {
+ wchar_t c = _changedPart[i];
+ if (c == L'9')
+ {
+ c = L'0';
+ newName = c + newName;
+ if (i == 0)
+ newName = UString(L'1') + newName;
+ continue;
+ }
+ c++;
+ newName = UString(c) + newName;
+ i--;
+ for (; i >= 0; i--)
+ newName = _changedPart[i] + newName;
+ break;
+ }
+ _changedPart = newName;
+ }
+ _first = false;
+ return _unchangedPart + _changedPart + _afterPart;
+ }
+};
+
+STDMETHODIMP CHandler::Open(IInStream *stream,
+ const UInt64 *maxCheckStartPosition,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ COM_TRY_BEGIN
+ Close();
+ try
+ {
+ CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
+ CMyComPtr<ICryptoGetTextPassword> getTextPassword;
+ CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = openArchiveCallback;
+
+ CVolumeName seqName;
+
+ if (openArchiveCallback != NULL)
+ {
+ openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback);
+ RINOK(openArchiveCallback->SetTotal(NULL, NULL));
+ UInt64 numFiles = _items.Size();
+ RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
+ openArchiveCallbackWrap.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
+ }
+
+ for (;;)
+ {
+ CMyComPtr<IInStream> inStream;
+ if (!_archives.IsEmpty())
+ {
+ if (!openVolumeCallback)
+ break;
+
+ if(_archives.Size() == 1)
+ {
+ if (!_archiveInfo.IsVolume())
+ break;
+ UString baseName;
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant));
+ if (propVariant.vt != VT_BSTR)
+ break;
+ baseName = propVariant.bstrVal;
+ }
+ seqName.InitName(baseName, _archiveInfo.HaveNewVolumeName());
+ }
+
+ UString fullName = seqName.GetNextName();
+ HRESULT result = openVolumeCallback->GetStream(fullName, &inStream);
+ if (result == S_FALSE)
+ break;
+ if (result != S_OK)
+ return result;
+ if (!stream)
+ break;
+ }
+ else
+ inStream = stream;
+
+ NArchive::NRar::CInArchive archive;
+ if(!archive.Open(inStream, maxCheckStartPosition))
+ return S_FALSE;
+
+ if (_archives.IsEmpty())
+ archive.GetArchiveInfo(_archiveInfo);
+
+ CItemEx item;
+ for (;;)
+ {
+ HRESULT result = archive.GetNextItem(item, getTextPassword);
+ if (result == S_FALSE)
+ break;
+ RINOK(result);
+ if (item.IgnoreItem())
+ continue;
+
+ bool needAdd = true;
+ if (item.IsSplitBefore())
+ {
+ if (!_refItems.IsEmpty())
+ {
+ CRefItem &refItem = _refItems.Back();
+ refItem.NumItems++;
+ needAdd = false;
+ }
+ }
+ if (needAdd)
+ {
+ CRefItem refItem;
+ refItem.ItemIndex = _items.Size();
+ refItem.NumItems = 1;
+ refItem.VolumeIndex = _archives.Size();
+ _refItems.Add(refItem);
+ }
+ _items.Add(item);
+ if (openArchiveCallback != NULL)
+ {
+ UInt64 numFiles = _items.Size();
+ RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
+ }
+ }
+ _archives.Add(archive);
+ }
+ }
+ catch(...)
+ {
+ return S_FALSE;
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ COM_TRY_BEGIN
+ _refItems.Clear();
+ _items.Clear();
+ _archives.Clear();
+ return S_OK;
+ COM_TRY_END
+}
+
+struct CMethodItem
+{
+ Byte RarUnPackVersion;
+ CMyComPtr<ICompressCoder> Coder;
+};
+
+
+STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
+ Int32 _aTestMode, IArchiveExtractCallback *_anExtractCallback)
+{
+ COM_TRY_BEGIN
+ CMyComPtr<ICryptoGetTextPassword> getTextPassword;
+ bool testMode = (_aTestMode != 0);
+ CMyComPtr<IArchiveExtractCallback> extractCallback = _anExtractCallback;
+ UInt64 censoredTotalUnPacked = 0,
+ // censoredTotalPacked = 0,
+ importantTotalUnPacked = 0;
+ // importantTotalPacked = 0;
+ bool allFilesMode = (numItems == UInt32(-1));
+ if (allFilesMode)
+ numItems = _refItems.Size();
+ if(numItems == 0)
+ return S_OK;
+ int lastIndex = 0;
+ CRecordVector<int> importantIndexes;
+ CRecordVector<bool> extractStatuses;
+
+ for(UInt32 t = 0; t < numItems; t++)
+ {
+ int index = allFilesMode ? t : indices[t];
+ const CRefItem &refItem = _refItems[index];
+ const CItemEx &item = _items[refItem.ItemIndex];
+ censoredTotalUnPacked += item.UnPackSize;
+ // censoredTotalPacked += item.PackSize;
+ int j;
+ for(j = lastIndex; j <= index; j++)
+ // if(!_items[_refItems[j].ItemIndex].IsSolid())
+ if(!IsSolid(j))
+ lastIndex = j;
+ for(j = lastIndex; j <= index; j++)
+ {
+ const CRefItem &refItem = _refItems[j];
+ const CItemEx &item = _items[refItem.ItemIndex];
+
+ // const CItemEx &item = _items[j];
+
+ importantTotalUnPacked += item.UnPackSize;
+ // importantTotalPacked += item.PackSize;
+ importantIndexes.Add(j);
+ extractStatuses.Add(j == index);
+ }
+ lastIndex = index + 1;
+ }
+
+ extractCallback->SetTotal(importantTotalUnPacked);
+ UInt64 currentImportantTotalUnPacked = 0;
+ UInt64 currentImportantTotalPacked = 0;
+ UInt64 currentUnPackSize, currentPackSize;
+
+ /*
+ CSysString path = GetCodecsFolderPrefix() + TEXT("Rar29.dll");
+ TCHAR compressLibPath[MAX_PATH + 64];
+ if (!GetCompressFolderPrefix(compressLibPath))
+ return ::GetLastError();
+ lstrcat(compressLibPath, TEXT("Rar29.dll"));
+ */
+ N7z::LoadMethodMap();
+ CCoderLibraries libraries;
+ CObjectVector<CMethodItem> methodItems;
+
+ /*
+ CCoderLibrary compressLib;
+ CMyComPtr<ICompressCoder> decoder15;
+ CMyComPtr<ICompressCoder> decoder20;
+ CMyComPtr<ICompressCoder> decoder29;
+ */
+
+ NCompress::CCopyCoder *copyCoderSpec = NULL;
+ CMyComPtr<ICompressCoder> copyCoder;
+
+ // CCoderMixer *mixerCoderSpec;
+ // CMyComPtr<ICompressCoder> mixerCoder;
+ // bool mixerCoderStoreMethod;
+ // int mixerCryptoVersion;
+
+ CFilterCoder *filterStreamSpec = new CFilterCoder;
+ CMyComPtr<ISequentialInStream> filterStream = filterStreamSpec;
+
+ NCrypto::NRar20::CDecoder *rar20CryptoDecoderSpec = NULL;
+ CMyComPtr<ICompressFilter> rar20CryptoDecoder;
+ NCrypto::NRar29::CDecoder *rar29CryptoDecoderSpec = NULL;
+ CMyComPtr<ICompressFilter> rar29CryptoDecoder;
+
+ CFolderInStream *folderInStreamSpec = NULL;
+ CMyComPtr<ISequentialInStream> folderInStream;
+
+ for(int i = 0; i < importantIndexes.Size(); i++,
+ currentImportantTotalUnPacked += currentUnPackSize,
+ currentImportantTotalPacked += currentPackSize)
+ {
+ RINOK(extractCallback->SetCompleted(
+ &currentImportantTotalUnPacked));
+ CMyComPtr<ISequentialOutStream> realOutStream;
+
+ Int32 askMode;
+ if(extractStatuses[i])
+ askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
+ NArchive::NExtract::NAskMode::kExtract;
+ else
+ askMode = NArchive::NExtract::NAskMode::kSkip;
+
+ UInt32 index = importantIndexes[i];
+
+ const CRefItem &refItem = _refItems[index];
+ const CItemEx &item = _items[refItem.ItemIndex];
+
+ currentUnPackSize = item.UnPackSize;
+
+ currentPackSize = GetPackSize(index);
+
+ if(item.IgnoreItem())
+ continue;
+
+ RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
+
+ if(item.IsDirectory())
+ {
+ RINOK(extractCallback->PrepareOperation(askMode));
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ continue;
+ }
+
+ bool mustBeProcessedAnywhere = false;
+ if(i < importantIndexes.Size() - 1)
+ {
+ // const CRefItem &nextRefItem = _refItems[importantIndexes[i + 1]];
+ // const CItemEx &nextItemInfo = _items[nextRefItem.ItemIndex];
+ // mustBeProcessedAnywhere = nextItemInfo.IsSolid();
+ mustBeProcessedAnywhere = IsSolid(importantIndexes[i + 1]);
+ }
+
+ if (!mustBeProcessedAnywhere && !testMode && !realOutStream)
+ continue;
+
+ if (!realOutStream && !testMode)
+ askMode = NArchive::NExtract::NAskMode::kSkip;
+
+ RINOK(extractCallback->PrepareOperation(askMode));
+
+ COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
+ CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
+ outStreamSpec->SetStream(realOutStream);
+ outStreamSpec->Init();
+ realOutStream.Release();
+
+ UInt64 packedPos = currentImportantTotalPacked;
+ UInt64 unpackedPos = currentImportantTotalUnPacked;
+
+ /*
+ for (int partIndex = 0; partIndex < 1; partIndex++)
+ {
+ CMyComPtr<ISequentialInStream> inStream;
+
+ // item redefinition
+ const CItemEx &item = _items[refItem.ItemIndex + partIndex];
+
+ NArchive::NRar::CInArchive &archive = _archives[refItem.VolumeIndex + partIndex];
+
+ inStream.Attach(archive.CreateLimitedStream(item.GetDataPosition(),
+ item.PackSize));
+ */
+ if (!folderInStream)
+ {
+ folderInStreamSpec = new CFolderInStream;
+ folderInStream = folderInStreamSpec;
+ }
+
+ folderInStreamSpec->Init(&_archives, &_items, refItem);
+
+
+ CLocalProgress *localProgressSpec = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
+ localProgressSpec->Init(extractCallback, false);
+
+ CLocalCompressProgressInfo *localCompressProgressSpec =
+ new CLocalCompressProgressInfo;
+ CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
+ localCompressProgressSpec->Init(progress,
+ &packedPos,
+ &unpackedPos);
+
+ UInt64 packSize = currentPackSize;
+
+ // packedPos += item.PackSize;
+ // unpackedPos += 0;
+
+ CMyComPtr<ISequentialInStream> inStream;
+ if (item.IsEncrypted())
+ {
+ CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
+ if (item.UnPackVersion >= 29)
+ {
+ if (!rar29CryptoDecoder)
+ {
+ 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));
+ RINOK(cryptoProperties->SetDecoderProperties2(item.Salt, item.HasSalt() ? sizeof(item.Salt) : 0));
+ filterStreamSpec->Filter = rar29CryptoDecoder;
+ }
+ else if (item.UnPackVersion >= 20)
+ {
+ if (!rar20CryptoDecoder)
+ {
+ rar20CryptoDecoderSpec = new NCrypto::NRar20::CDecoder;
+ rar20CryptoDecoder = rar20CryptoDecoderSpec;
+ // RINOK(rar20CryptoDecoder.CoCreateInstance(CLSID_CCryptoRar20Decoder));
+ }
+ filterStreamSpec->Filter = rar20CryptoDecoder;
+ }
+ else
+ {
+ outStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+ continue;
+ }
+ RINOK(filterStreamSpec->Filter.QueryInterface(IID_ICryptoSetPassword,
+ &cryptoSetPassword));
+
+ if (!getTextPassword)
+ extractCallback.QueryInterface(IID_ICryptoGetTextPassword,
+ &getTextPassword);
+ if (getTextPassword)
+ {
+ CMyComBSTR password;
+ RINOK(getTextPassword->CryptoGetTextPassword(&password));
+ if (item.UnPackVersion >= 29)
+ {
+ CByteBuffer buffer;
+ UString unicodePassword(password);
+ 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(cryptoSetPassword->CryptoSetPassword(
+ (const Byte *)buffer, sizeInBytes));
+ }
+ else
+ {
+ AString oemPassword = UnicodeStringToMultiByte(
+ (const wchar_t *)password, CP_OEMCP);
+ RINOK(cryptoSetPassword->CryptoSetPassword(
+ (const Byte *)(const char *)oemPassword, oemPassword.Length()));
+ }
+ }
+ else
+ {
+ RINOK(cryptoSetPassword->CryptoSetPassword(0, 0));
+ }
+ filterStreamSpec->SetInStream(folderInStream);
+ inStream = filterStream;
+ }
+ else
+ {
+ inStream = folderInStream;
+ }
+ CMyComPtr<ICompressCoder> commonCoder;
+ switch(item.Method)
+ {
+ case '0':
+ {
+ if(copyCoderSpec == NULL)
+ {
+ copyCoderSpec = new NCompress::CCopyCoder;
+ copyCoder = copyCoderSpec;
+ }
+ commonCoder = copyCoder;
+ break;
+ }
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ {
+ /*
+ if (item.UnPackVersion >= 29)
+ {
+ outStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+ continue;
+ }
+ */
+ int m;
+ for (m = 0; m < methodItems.Size(); m++)
+ if (methodItems[m].RarUnPackVersion == item.UnPackVersion)
+ break;
+ if (m == methodItems.Size())
+ {
+ CMethodItem mi;
+ mi.RarUnPackVersion = item.UnPackVersion;
+ N7z::CMethodID methodID = { { 0x04, 0x03 } , 3 };
+
+ Byte myID;
+ if (item.UnPackVersion < 20)
+ myID = 1;
+ else if (item.UnPackVersion < 29)
+ myID = 2;
+ else
+ myID = 3;
+ methodID.ID[2] = myID;
+ N7z::CMethodInfo methodInfo;
+ if (!N7z::GetMethodInfo(methodID, methodInfo))
+ {
+ RINOK(extractCallback->SetOperationResult(
+ NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+ continue;
+ }
+ RINOK(libraries.CreateCoder(methodInfo.FilePath,
+ methodInfo.Decoder, &mi.Coder));
+ m = methodItems.Add(mi);
+ }
+ CMyComPtr<ICompressCoder> decoder = methodItems[m].Coder;
+
+ CMyComPtr<ICompressSetDecoderProperties2> compressSetDecoderProperties;
+ RINOK(decoder.QueryInterface(IID_ICompressSetDecoderProperties2,
+ &compressSetDecoderProperties));
+
+ Byte isSolid = (Byte)((IsSolid(index) || item.IsSplitBefore()) ? 1: 0);
+
+ RINOK(compressSetDecoderProperties->SetDecoderProperties2(&isSolid, 1));
+
+ commonCoder = decoder;
+ break;
+ }
+ default:
+ outStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+ continue;
+ }
+ HRESULT result = commonCoder->Code(inStream, outStream,
+ &packSize, &item.UnPackSize, compressProgress);
+ if (item.IsEncrypted())
+ filterStreamSpec->ReleaseInStream();
+ if (result == S_FALSE)
+ {
+ outStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ if (result != S_OK)
+ return result;
+
+ /*
+ if (refItem.NumItems == 1 &&
+ !item.IsSplitBefore() && !item.IsSplitAfter())
+ */
+ {
+ const CItemEx &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1];
+ bool crcOK = outStreamSpec->GetCRC() == lastItem.FileCRC;
+ outStream.Release();
+ RINOK(extractCallback->SetOperationResult(crcOK ? NArchive::NExtract::NOperationResult::kOK:
+ NArchive::NExtract::NOperationResult::kCRCError));
+ }
+ /*
+ else
+ {
+ bool crcOK = true;
+ for (int partIndex = 0; partIndex < refItem.NumItems; partIndex++)
+ {
+ const CItemEx &item = _items[refItem.ItemIndex + partIndex];
+ if (item.FileCRC != folderInStreamSpec->CRCs[partIndex])
+ {
+ crcOK = false;
+ break;
+ }
+ }
+ RINOK(extractCallback->SetOperationResult(crcOK ? NArchive::NExtract::NOperationResult::kOK:
+ NArchive::NExtract::NOperationResult::kCRCError));
+ }
+ */
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+/*
+STDMETHODIMP CHandler::ExtractAllItems(Int32 testMode,
+ IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ CRecordVector<UInt32> indices;
+ indices.Reserve(_refItems.Size());
+ for(int i = 0; i < _refItems.Size(); i++)
+ indices.Add(i);
+ return Extract(&indices.Front(), _refItems.Size(), testMode, extractCallback);
+ COM_TRY_END
+}
+*/
+
+}}
diff --git a/CPP/7zip/Archive/Rar/RarHandler.h b/CPP/7zip/Archive/Rar/RarHandler.h
new file mode 100755
index 00000000..ea13e01e
--- /dev/null
+++ b/CPP/7zip/Archive/Rar/RarHandler.h
@@ -0,0 +1,63 @@
+// Rar/Handler.h
+
+#ifndef __RAR_HANDLER_H
+#define __RAR_HANDLER_H
+
+#include "../IArchive.h"
+#include "RarIn.h"
+#include "RarVolumeInStream.h"
+
+namespace NArchive {
+namespace NRar {
+
+class CHandler:
+ public IInArchive,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Open)(IInStream *aStream,
+ const UInt64 *aMaxCheckStartPosition,
+ IArchiveOpenCallback *anOpenArchiveCallback);
+ STDMETHOD(Close)();
+ STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
+ STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
+ STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems,
+ Int32 testMode, IArchiveExtractCallback *anExtractCallback);
+
+ 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:
+ CRecordVector<CRefItem> _refItems;
+ CObjectVector<CItemEx> _items;
+ CObjectVector<CInArchive> _archives;
+ NArchive::NRar::CInArchiveInfo _archiveInfo;
+
+ UInt64 GetPackSize(int refIndex) const;
+ // NArchive::NRar::CInArchive _archive;
+
+ bool IsSolid(int refIndex)
+ {
+ const CItemEx &item = _items[_refItems[refIndex].ItemIndex];
+ if (item.UnPackVersion < 20)
+ {
+ if (_archiveInfo.IsSolid())
+ return (refIndex > 0);
+ return false;
+ }
+ return item.IsSolid();
+ }
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Rar/RarHeader.cpp b/CPP/7zip/Archive/Rar/RarHeader.cpp
new file mode 100755
index 00000000..94481e02
--- /dev/null
+++ b/CPP/7zip/Archive/Rar/RarHeader.cpp
@@ -0,0 +1,21 @@
+// Archive/Rar/Headers.cpp
+
+#include "StdAfx.h"
+
+#include "RarHeader.h"
+
+namespace NArchive{
+namespace NRar{
+namespace NHeader{
+
+Byte kMarker[kMarkerSize] = {0x52 + 1, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00};
+
+class CMarkerInitializer
+{
+public:
+ CMarkerInitializer() { kMarker[0]--; };
+};
+
+static CMarkerInitializer markerInitializer;
+
+}}}
diff --git a/CPP/7zip/Archive/Rar/RarHeader.h b/CPP/7zip/Archive/Rar/RarHeader.h
new file mode 100755
index 00000000..832a21c0
--- /dev/null
+++ b/CPP/7zip/Archive/Rar/RarHeader.h
@@ -0,0 +1,224 @@
+// Archive/RarHeader.h
+
+#ifndef __ARCHIVE_RAR_HEADER_H
+#define __ARCHIVE_RAR_HEADER_H
+
+#include "Common/Types.h"
+
+namespace NArchive{
+namespace NRar{
+namespace NHeader{
+
+const int kMarkerSize = 7;
+extern Byte kMarker[kMarkerSize];
+
+const int kArchiveSolid = 0x1;
+
+namespace NBlockType
+{
+ enum EBlockType
+ {
+ kMarker = 0x72,
+ kArchiveHeader = 0x73,
+ kFileHeader = 0x74,
+ kCommentHeader = 0x75,
+ kOldAuthenticity = 0x76,
+ kSubBlock = 0x77,
+ kRecoveryRecord = 0x78,
+ kAuthenticity = 0x79,
+
+ kEndOfArchive = 0x7B // Is not safe
+ };
+}
+
+namespace NArchive
+{
+ const UInt16 kVolume = 1;
+ const UInt16 kComment = 2;
+ const UInt16 kLock = 4;
+ const UInt16 kSolid = 8;
+ const UInt16 kNewVolName = 0x10; // ('volname.partN.rar')
+ const UInt16 kAuthenticity = 0x20;
+ const UInt16 kRecovery = 0x40;
+ const UInt16 kBlockEncryption = 0x80;
+ const UInt16 kFirstVolume = 0x100; // (set only by RAR 3.0 and later)
+ const UInt16 kEncryptVer = 0x200; // RAR 3.6 there is EncryptVer Byte in End of MainHeader
+
+ const int kHeaderSizeMin = 7;
+
+ struct CBlock
+ {
+ UInt16 CRC;
+ Byte Type;
+ UInt16 Flags;
+ UInt16 Size;
+ UInt16 Reserved1;
+ 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
+{
+ const int kSplitBefore = 1 << 0;
+ const int kSplitAfter = 1 << 1;
+ const int kEncrypted = 1 << 2;
+ const int kComment = 1 << 3;
+ const int kSolid = 1 << 4;
+
+ const int kDictBitStart = 5;
+ const int kNumDictBits = 3;
+ const int kDictMask = (1 << kNumDictBits) - 1;
+ const int kDictDirectoryValue = 0x7;
+
+ const int kSize64Bits = 1 << 8;
+ const int kUnicodeName = 1 << 9;
+ const int kSalt = 1 << 10;
+ const int kOldVersion = 1 << 11;
+ const int kExtTime = 1 << 12;
+ // const int kExtFlags = 1 << 13;
+ // const int kSkipIfUnknown = 1 << 14;
+
+ const int kLongBlock = 1 << 15;
+
+ /*
+ struct CBlock
+ {
+ // UInt16 HeadCRC;
+ // Byte Type;
+ // UInt16 Flags;
+ // UInt16 HeadSize;
+ UInt32 PackSize;
+ UInt32 UnPackSize;
+ Byte HostOS;
+ UInt32 FileCRC;
+ UInt32 Time;
+ Byte UnPackVersion;
+ Byte Method;
+ UInt16 NameSize;
+ UInt32 Attributes;
+ };
+ */
+
+ /*
+ struct CBlock32
+ {
+ UInt16 HeadCRC;
+ Byte Type;
+ UInt16 Flags;
+ UInt16 HeadSize;
+ UInt32 PackSize;
+ UInt32 UnPackSize;
+ Byte HostOS;
+ UInt32 FileCRC;
+ UInt32 Time;
+ Byte UnPackVersion;
+ Byte Method;
+ UInt16 NameSize;
+ UInt32 Attributes;
+ UInt16 GetRealCRC(const void *aName, UInt32 aNameSize,
+ bool anExtraDataDefined = false, Byte *anExtraData = 0) const;
+ };
+ struct CBlock64
+ {
+ UInt16 HeadCRC;
+ Byte Type;
+ UInt16 Flags;
+ UInt16 HeadSize;
+ UInt32 PackSizeLow;
+ UInt32 UnPackSizeLow;
+ Byte HostOS;
+ UInt32 FileCRC;
+ UInt32 Time;
+ Byte UnPackVersion;
+ Byte Method;
+ UInt16 NameSize;
+ UInt32 Attributes;
+ UInt32 PackSizeHigh;
+ UInt32 UnPackSizeHigh;
+ UInt16 GetRealCRC(const void *aName, UInt32 aNameSize) const;
+ };
+ */
+
+ const int kLabelFileAttribute = 0x08;
+ const int kWinFileDirectoryAttributeMask = 0x10;
+
+ enum CHostOS
+ {
+ kHostMSDOS = 0,
+ kHostOS2 = 1,
+ kHostWin32 = 2,
+ kHostUnix = 3,
+ kHostMacOS = 4,
+ kHostBeOS = 5
+ };
+}
+
+namespace NBlock
+{
+ const UInt16 kLongBlock = 1 << 15;
+ struct CBlock
+ {
+ UInt16 CRC;
+ Byte Type;
+ UInt16 Flags;
+ UInt16 HeadSize;
+ // UInt32 DataSize;
+ };
+}
+
+/*
+struct CSubBlock
+{
+ UInt16 HeadCRC;
+ Byte HeadType;
+ UInt16 Flags;
+ UInt16 HeadSize;
+ UInt32 DataSize;
+ UInt16 SubType;
+ Byte Level; // Reserved : Must be 0
+};
+
+struct CCommentBlock
+{
+ UInt16 HeadCRC;
+ Byte HeadType;
+ UInt16 Flags;
+ UInt16 HeadSize;
+ UInt16 UnpSize;
+ Byte UnpVer;
+ Byte Method;
+ UInt16 CommCRC;
+};
+
+
+struct CProtectHeader
+{
+ UInt16 HeadCRC;
+ Byte HeadType;
+ UInt16 Flags;
+ UInt16 HeadSize;
+ UInt32 DataSize;
+ Byte Version;
+ UInt16 RecSectors;
+ UInt32 TotalBlocks;
+ Byte Mark[8];
+};
+*/
+
+}}}
+
+#endif
diff --git a/CPP/7zip/Archive/Rar/RarIn.cpp b/CPP/7zip/Archive/Rar/RarIn.cpp
new file mode 100755
index 00000000..9a88feb7
--- /dev/null
+++ b/CPP/7zip/Archive/Rar/RarIn.cpp
@@ -0,0 +1,535 @@
+// Archive/RarIn.cpp
+
+#include "StdAfx.h"
+
+#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 {
+
+static const char kEndOfString = '\0';
+
+void CInArchive::ThrowExceptionWithCode(
+ CInArchiveException::CCauseType cause)
+{
+ throw CInArchiveException(cause);
+}
+
+bool CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit)
+{
+ m_CryptoMode = false;
+ if(inStream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition) != S_OK)
+ return false;
+ m_Position = m_StreamStartPosition;
+ m_Stream = inStream;
+ if (ReadMarkerAndArchiveHeader(searchHeaderSizeLimit))
+ return true;
+ m_Stream.Release();
+ return false;
+}
+
+void CInArchive::Close()
+{
+ m_Stream.Release();
+}
+
+
+static inline bool TestMarkerCandidate(const void *aTestBytes)
+{
+ for (UInt32 i = 0; i < NHeader::kMarkerSize; i++)
+ if (((const Byte *)aTestBytes)[i] != NHeader::kMarker[i])
+ return false;
+ return true;
+}
+
+bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit)
+{
+ // if (m_Length < NHeader::kMarkerSize)
+ // return false;
+ m_ArchiveStartPosition = 0;
+ m_Position = m_StreamStartPosition;
+ if(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL) != S_OK)
+ return false;
+
+ Byte marker[NHeader::kMarkerSize];
+ UInt32 processedSize;
+ ReadBytes(marker, NHeader::kMarkerSize, &processedSize);
+ if(processedSize != NHeader::kMarkerSize)
+ return false;
+ if (TestMarkerCandidate(marker))
+ return true;
+
+ CByteDynamicBuffer dynamicBuffer;
+ static const UInt32 kSearchMarkerBufferSize = 0x10000;
+ dynamicBuffer.EnsureCapacity(kSearchMarkerBufferSize);
+ Byte *buffer = dynamicBuffer;
+ UInt32 numBytesPrev = NHeader::kMarkerSize - 1;
+ memmove(buffer, marker + 1, numBytesPrev);
+ UInt64 curTestPos = m_StreamStartPosition + 1;
+ for (;;)
+ {
+ if (searchHeaderSizeLimit != NULL)
+ if (curTestPos - m_StreamStartPosition > *searchHeaderSizeLimit)
+ break;
+ UInt32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev;
+ ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize);
+ UInt32 numBytesInBuffer = numBytesPrev + processedSize;
+ if (numBytesInBuffer < NHeader::kMarkerSize)
+ break;
+ UInt32 numTests = numBytesInBuffer - NHeader::kMarkerSize + 1;
+ for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++)
+ {
+ if (TestMarkerCandidate(buffer + pos))
+ {
+ m_ArchiveStartPosition = curTestPos;
+ m_Position = curTestPos + NHeader::kMarkerSize;
+ if(m_Stream->Seek(m_Position, STREAM_SEEK_SET, NULL) != S_OK)
+ return false;
+ return true;
+ }
+ }
+ numBytesPrev = numBytesInBuffer - numTests;
+ memmove(buffer, buffer + numTests, numBytesPrev);
+ }
+ return false;
+}
+
+void CInArchive::ThrowUnexpectedEndOfArchiveException()
+{
+ ThrowExceptionWithCode(CInArchiveException::kUnexpectedEndOfArchive);
+}
+
+bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size)
+{
+ if (m_CryptoMode)
+ {
+ const Byte *bufData = (const Byte *)m_DecryptedData;
+ UInt32 bufSize = m_DecryptedDataSize;
+ UInt32 i;
+ for (i = 0; i < size && m_CryptoPos < bufSize; i++)
+ ((Byte *)data)[i] = bufData[m_CryptoPos++];
+ return (i == size);
+ }
+ UInt32 processedSize;
+ ReadStream(m_Stream, data, size, &processedSize);
+ return (processedSize == size);
+}
+
+void CInArchive::ReadBytesAndTestResult(void *data, UInt32 size)
+{
+ if(!ReadBytesAndTestSize(data,size))
+ ThrowUnexpectedEndOfArchiveException();
+}
+
+HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize;
+ HRESULT result = ReadStream(m_Stream, data, size, &realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ AddToSeekValue(realProcessedSize);
+ return result;
+}
+
+bool CInArchive::ReadMarkerAndArchiveHeader(const UInt64 *searchHeaderSizeLimit)
+{
+ if (!FindAndReadMarker(searchHeaderSizeLimit))
+ return false;
+
+ Byte buf[NHeader::NArchive::kArchiveHeaderSize];
+ UInt32 processedSize;
+ ReadBytes(buf, sizeof(buf), &processedSize);
+ if (processedSize != sizeof(buf))
+ return false;
+ m_CurData = buf;
+ m_CurPos = 0;
+ m_PosLimit = sizeof(buf);
+
+ m_ArchiveHeader.CRC = ReadUInt16();
+ m_ArchiveHeader.Type = ReadByte();
+ m_ArchiveHeader.Flags = ReadUInt16();
+ m_ArchiveHeader.Size = ReadUInt16();
+ m_ArchiveHeader.Reserved1 = ReadUInt16();
+ m_ArchiveHeader.Reserved2 = ReadUInt32();
+ m_ArchiveHeader.EncryptVersion = 0;
+
+ CCRC crc;
+ crc.UpdateByte(m_ArchiveHeader.Type);
+ crc.UpdateUInt16(m_ArchiveHeader.Flags);
+ crc.UpdateUInt16(m_ArchiveHeader.Size);
+ 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);
+ }
+
+ if(m_ArchiveHeader.CRC != (crc.GetDigest() & 0xFFFF))
+ ThrowExceptionWithCode(CInArchiveException::kArchiveHeaderCRCError);
+ if (m_ArchiveHeader.Type != NHeader::NBlockType::kArchiveHeader)
+ return false;
+ m_ArchiveCommentPosition = m_Position;
+ m_SeekOnArchiveComment = true;
+ return true;
+}
+
+void CInArchive::SkipArchiveComment()
+{
+ if (!m_SeekOnArchiveComment)
+ return;
+ AddToSeekValue(m_ArchiveHeader.Size - m_ArchiveHeader.GetBaseSize());
+ m_SeekOnArchiveComment = false;
+}
+
+void CInArchive::GetArchiveInfo(CInArchiveInfo &archiveInfo) const
+{
+ archiveInfo.StartPosition = m_ArchiveStartPosition;
+ archiveInfo.Flags = m_ArchiveHeader.Flags;
+ archiveInfo.CommentPosition = m_ArchiveCommentPosition;
+ archiveInfo.CommentSize = (UInt16)(m_ArchiveHeader.Size - NHeader::NArchive::kArchiveHeaderSize);
+}
+
+static void DecodeUnicodeFileName(const char *name, const Byte *encName,
+ int encSize, wchar_t *unicodeName, int maxDecSize)
+{
+ int encPos = 0;
+ int decPos = 0;
+ int flagBits = 0;
+ Byte flags = 0;
+ Byte highByte = encName[encPos++];
+ while (encPos < encSize && decPos < maxDecSize)
+ {
+ if (flagBits == 0)
+ {
+ flags = encName[encPos++];
+ flagBits = 8;
+ }
+ switch(flags >> 6)
+ {
+ case 0:
+ unicodeName[decPos++] = encName[encPos++];
+ break;
+ case 1:
+ unicodeName[decPos++] = (wchar_t)(encName[encPos++] + (highByte << 8));
+ break;
+ case 2:
+ unicodeName[decPos++] = (wchar_t)(encName[encPos] + (encName[encPos + 1] << 8));
+ encPos += 2;
+ break;
+ case 3:
+ {
+ int length = encName[encPos++];
+ if (length & 0x80)
+ {
+ Byte correction = encName[encPos++];
+ for (length = (length & 0x7f) + 2;
+ length > 0 && decPos < maxDecSize; length--, decPos++)
+ unicodeName[decPos] = (wchar_t)(((name[decPos] + correction) & 0xff) + (highByte << 8));
+ }
+ else
+ for (length += 2; length > 0 && decPos < maxDecSize; length--, decPos++)
+ unicodeName[decPos] = name[decPos];
+ }
+ break;
+ }
+ flags <<= 2;
+ flagBits -= 2;
+ }
+ unicodeName[decPos < maxDecSize ? decPos : maxDecSize - 1] = 0;
+}
+
+void CInArchive::ReadName(CItemEx &item, int nameSize)
+{
+ item.UnicodeName.Empty();
+ if (nameSize > 0)
+ {
+ m_NameBuffer.EnsureCapacity(nameSize + 1);
+ char *buffer = (char *)m_NameBuffer;
+
+ for (int i = 0; i < nameSize; i++)
+ buffer[i] = ReadByte();
+
+ int mainLen;
+ for (mainLen = 0; mainLen < nameSize; mainLen++)
+ if (buffer[mainLen] == '\0')
+ break;
+ buffer[mainLen] = '\0';
+ item.Name = buffer;
+
+ if(item.HasUnicodeName())
+ {
+ 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
+ item.Name.Empty();
+}
+
+Byte CInArchive::ReadByte()
+{
+ if (m_CurPos >= m_PosLimit)
+ throw CInArchiveException(CInArchiveException::kIncorrectArchive);
+ return m_CurData[m_CurPos++];
+}
+
+UInt16 CInArchive::ReadUInt16()
+{
+ UInt16 value = 0;
+ for (int i = 0; i < 2; i++)
+ {
+ Byte b = ReadByte();
+ value |= (UInt16(b) << (8 * i));
+ }
+ return value;
+}
+
+UInt32 CInArchive::ReadUInt32()
+{
+ UInt32 value = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ Byte b = ReadByte();
+ value |= (UInt32(b) << (8 * i));
+ }
+ return value;
+}
+
+void CInArchive::ReadTime(Byte mask, CRarTime &rarTime)
+{
+ rarTime.LowSecond = (Byte)(((mask & 4) != 0) ? 1 : 0);
+ int numDigits = (mask & 3);
+ rarTime.SubTime[0] = rarTime.SubTime[1] = rarTime.SubTime[2] = 0;
+ for (int i = 0; i < numDigits; i++)
+ rarTime.SubTime[3 - numDigits + i] = ReadByte();
+}
+
+void CInArchive::ReadHeaderReal(CItemEx &item)
+{
+ item.Flags = m_BlockHeader.Flags;
+ item.PackSize = ReadUInt32();
+ item.UnPackSize = ReadUInt32();
+ item.HostOS = ReadByte();
+ item.FileCRC = ReadUInt32();
+ item.LastWriteTime.DosTime = ReadUInt32();
+ item.UnPackVersion = ReadByte();
+ item.Method = ReadByte();
+ int nameSize = ReadUInt16();
+ item.Attributes = ReadUInt32();
+
+ item.LastWriteTime.LowSecond = 0;
+ item.LastWriteTime.SubTime[0] =
+ item.LastWriteTime.SubTime[1] =
+ item.LastWriteTime.SubTime[2] = 0;
+
+ if((item.Flags & NHeader::NFile::kSize64Bits) != 0)
+ {
+ item.PackSize |= ((UInt64)ReadUInt32() << 32);
+ item.UnPackSize |= ((UInt64)ReadUInt32() << 32);
+ }
+
+ ReadName(item, nameSize);
+
+ if (item.HasSalt())
+ for (int i = 0; i < sizeof(item.Salt); i++)
+ item.Salt[i] = ReadByte();
+
+ // some rar archives have HasExtTime flag without field.
+ if (m_CurPos < m_PosLimit && item.HasExtTime())
+ {
+ Byte accessMask = (Byte)(ReadByte() >> 4);
+ Byte b = ReadByte();
+ Byte modifMask = (Byte)(b >> 4);
+ Byte createMask = (Byte)(b & 0xF);
+ if ((modifMask & 8) != 0)
+ ReadTime(modifMask, item.LastWriteTime);
+ item.IsCreationTimeDefined = ((createMask & 8) != 0);
+ if (item.IsCreationTimeDefined)
+ {
+ item.CreationTime.DosTime = ReadUInt32();
+ ReadTime(createMask, item.CreationTime);
+ }
+ item.IsLastAccessTimeDefined = ((accessMask & 8) != 0);
+ if (item.IsLastAccessTimeDefined)
+ {
+ item.LastAccessTime.DosTime = ReadUInt32();
+ ReadTime(accessMask, item.LastAccessTime);
+ }
+ }
+
+ UInt16 fileHeaderWithNameSize = (UInt16)m_CurPos;
+
+ item.Position = m_Position;
+ item.MainPartSize = fileHeaderWithNameSize;
+ item.CommentSize = (UInt16)(m_BlockHeader.HeadSize - fileHeaderWithNameSize);
+
+ if (m_CryptoMode)
+ item.AlignSize = (UInt16)((16 - ((m_BlockHeader.HeadSize) & 0xF)) & 0xF);
+ else
+ item.AlignSize = 0;
+ AddToSeekValue(m_BlockHeader.HeadSize);
+}
+
+void CInArchive::AddToSeekValue(UInt64 addValue)
+{
+ m_Position += addValue;
+}
+
+HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword)
+{
+ if (m_SeekOnArchiveComment)
+ SkipArchiveComment();
+ for (;;)
+ {
+ if(!SeekInArchive(m_Position))
+ return S_FALSE;
+ if (!m_CryptoMode && (m_ArchiveHeader.Flags &
+ NHeader::NArchive::kBlockHeadersAreEncrypted) != 0)
+ {
+ m_CryptoMode = false;
+ if (getTextPassword == 0)
+ return S_FALSE;
+ if(!SeekInArchive(m_Position))
+ return S_FALSE;
+ if (!m_RarAES)
+ {
+ m_RarAESSpec = new NCrypto::NRar29::CDecoder;
+ m_RarAES = m_RarAESSpec;
+ }
+ m_RarAESSpec->SetRar350Mode(m_ArchiveHeader.IsEncryptOld());
+
+ // Salt
+ const UInt32 kSaltSize = 8;
+ Byte salt[kSaltSize];
+ if(!ReadBytesAndTestSize(salt, kSaltSize))
+ return false;
+ m_Position += kSaltSize;
+ RINOK(m_RarAESSpec->SetDecoderProperties2(salt, kSaltSize))
+ // Password
+ CMyComBSTR password;
+ RINOK(getTextPassword->CryptoGetTextPassword(&password))
+ UString unicodePassword(password);
+
+ 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)
+ {
+ m_DecryptedData.SetCapacity(kDecryptedBufferSize);
+ }
+ RINOK(m_RarAES->Init());
+ RINOK(ReadStream(m_Stream, (Byte *)m_DecryptedData, kDecryptedBufferSize, &m_DecryptedDataSize));
+ m_DecryptedDataSize = m_RarAES->Filter((Byte *)m_DecryptedData, m_DecryptedDataSize);
+
+ m_CryptoMode = true;
+ m_CryptoPos = 0;
+ }
+
+ m_FileHeaderData.EnsureCapacity(7);
+ if(!ReadBytesAndTestSize((Byte *)m_FileHeaderData, 7))
+ return S_FALSE;
+
+ m_CurData = (Byte *)m_FileHeaderData;
+ m_CurPos = 0;
+ m_PosLimit = 7;
+ m_BlockHeader.CRC = ReadUInt16();
+ m_BlockHeader.Type = ReadByte();
+ m_BlockHeader.Flags = ReadUInt16();
+ m_BlockHeader.HeadSize = ReadUInt16();
+
+ if (m_BlockHeader.HeadSize < 7)
+ ThrowExceptionWithCode(CInArchiveException::kIncorrectArchive);
+
+ if (m_BlockHeader.Type == NHeader::NBlockType::kEndOfArchive)
+ return S_FALSE;
+
+ if (m_BlockHeader.Type == NHeader::NBlockType::kFileHeader)
+ {
+ m_FileHeaderData.EnsureCapacity(m_BlockHeader.HeadSize);
+ m_CurData = (Byte *)m_FileHeaderData;
+ m_PosLimit = m_BlockHeader.HeadSize;
+ ReadBytesAndTestResult(m_CurData + m_CurPos, m_BlockHeader.HeadSize - 7);
+ ReadHeaderReal(item);
+ if ((CCRC::CalculateDigest(m_CurData + 2,
+ m_BlockHeader.HeadSize - item.CommentSize - 2) & 0xFFFF) != m_BlockHeader.CRC)
+ ThrowExceptionWithCode(CInArchiveException::kFileHeaderCRCError);
+
+ FinishCryptoBlock();
+ m_CryptoMode = false;
+ SeekInArchive(m_Position); // Move Position to compressed Data;
+ AddToSeekValue(item.PackSize); // m_Position points to next header;
+ return S_OK;
+ }
+ if (m_CryptoMode && m_BlockHeader.HeadSize > (1 << 12))
+ return E_FAIL; // it's for bad passwords
+ if ((m_BlockHeader.Flags & NHeader::NBlock::kLongBlock) != 0)
+ {
+ m_FileHeaderData.EnsureCapacity(7 + 4);
+ m_CurData = (Byte *)m_FileHeaderData;
+ ReadBytesAndTestResult(m_CurData + m_CurPos, 4); // test it
+ m_PosLimit = 7 + 4;
+ UInt32 dataSize = ReadUInt32();
+ AddToSeekValue(dataSize);
+ if (m_CryptoMode && dataSize > (1 << 27))
+ return E_FAIL; // it's for bad passwords
+ m_CryptoPos = m_BlockHeader.HeadSize;
+ }
+ else
+ m_CryptoPos = 0;
+ AddToSeekValue(m_BlockHeader.HeadSize);
+ FinishCryptoBlock();
+ m_CryptoMode = false;
+ }
+}
+
+void CInArchive::DirectGetBytes(void *data, UInt32 size)
+{
+ ReadStream(m_Stream, data, size, NULL);
+}
+
+bool CInArchive::SeekInArchive(UInt64 position)
+{
+ UInt64 newPosition;
+ m_Stream->Seek(position, STREAM_SEEK_SET, &newPosition);
+ return newPosition == position;
+}
+
+ISequentialInStream* CInArchive::CreateLimitedStream(UInt64 position, UInt64 size)
+{
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+ CMyComPtr<ISequentialInStream> inStream(streamSpec);
+ SeekInArchive(position);
+ streamSpec->SetStream(m_Stream);
+ streamSpec->Init(size);
+ return inStream.Detach();
+}
+
+}}
diff --git a/CPP/7zip/Archive/Rar/RarIn.h b/CPP/7zip/Archive/Rar/RarIn.h
new file mode 100755
index 00000000..22262a74
--- /dev/null
+++ b/CPP/7zip/Archive/Rar/RarIn.h
@@ -0,0 +1,124 @@
+// RarIn.h
+
+#ifndef __ARCHIVE_RAR_IN_H
+#define __ARCHIVE_RAR_IN_H
+
+#include "Common/DynamicBuffer.h"
+#include "Common/Exception.h"
+#include "Common/MyCom.h"
+#include "../../IStream.h"
+#include "../../ICoder.h"
+#include "../../Common/StreamObjects.h"
+#include "../../Crypto/RarAES/RarAES.h"
+#include "RarHeader.h"
+#include "RarItem.h"
+
+namespace NArchive {
+namespace NRar {
+
+class CInArchiveException
+{
+public:
+ enum CCauseType
+ {
+ kUnexpectedEndOfArchive = 0,
+ kArchiveHeaderCRCError,
+ kFileHeaderCRCError,
+ kIncorrectArchive,
+ }
+ Cause;
+ CInArchiveException(CCauseType cause) : Cause(cause) {}
+};
+
+class CInArchiveInfo
+{
+public:
+ UInt64 StartPosition;
+ WORD Flags;
+ UInt64 CommentPosition;
+ WORD CommentSize;
+ bool IsSolid() const { return (Flags & NHeader::NArchive::kSolid) != 0; }
+ 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
+{
+ CMyComPtr<IInStream> m_Stream;
+
+ UInt64 m_StreamStartPosition;
+ UInt64 m_Position;
+ UInt64 m_ArchiveStartPosition;
+
+ NHeader::NArchive::CHeader360 m_ArchiveHeader;
+ CDynamicBuffer<char> m_NameBuffer;
+ CDynamicBuffer<wchar_t> _unicodeNameBuffer;
+ bool m_SeekOnArchiveComment;
+ UInt64 m_ArchiveCommentPosition;
+
+ void ReadName(CItemEx &item, int nameSize);
+ void ReadHeaderReal(CItemEx &item);
+
+ HRESULT ReadBytes(void *data, UInt32 size, UInt32 *aProcessedSize);
+ bool ReadBytesAndTestSize(void *data, UInt32 size);
+ void ReadBytesAndTestResult(void *data, UInt32 size);
+
+ bool FindAndReadMarker(const UInt64 *searchHeaderSizeLimit);
+ void ThrowExceptionWithCode(CInArchiveException::CCauseType cause);
+ void ThrowUnexpectedEndOfArchiveException();
+
+ void AddToSeekValue(UInt64 addValue);
+
+protected:
+
+ CDynamicBuffer<Byte> m_FileHeaderData;
+
+ NHeader::NBlock::CBlock m_BlockHeader;
+
+ NCrypto::NRar29::CDecoder *m_RarAESSpec;
+ CMyComPtr<ICompressFilter> m_RarAES;
+
+ Byte *m_CurData; // it must point to start of Rar::Block
+ UInt32 m_CurPos;
+ UInt32 m_PosLimit;
+ Byte ReadByte();
+ UInt16 ReadUInt16();
+ UInt32 ReadUInt32();
+ void ReadTime(Byte mask, CRarTime &rarTime);
+
+ CBuffer<Byte> m_DecryptedData;
+ UInt32 m_DecryptedDataSize;
+
+ bool m_CryptoMode;
+ UInt32 m_CryptoPos;
+ void FinishCryptoBlock()
+ {
+ if (m_CryptoMode)
+ while ((m_CryptoPos & 0xF) != 0)
+ {
+ m_CryptoPos++;
+ m_Position++;
+ }
+ }
+
+ bool ReadMarkerAndArchiveHeader(const UInt64 *searchHeaderSizeLimit);
+public:
+ bool Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit);
+ void Close();
+ HRESULT GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword);
+
+ void SkipArchiveComment();
+
+ void GetArchiveInfo(CInArchiveInfo &archiveInfo) const;
+
+ void DirectGetBytes(void *data, UInt32 size);
+
+ bool SeekInArchive(UInt64 position);
+ ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Rar/RarItem.cpp b/CPP/7zip/Archive/Rar/RarItem.cpp
new file mode 100755
index 00000000..61a72557
--- /dev/null
+++ b/CPP/7zip/Archive/Rar/RarItem.cpp
@@ -0,0 +1,118 @@
+// RarItem.cpp
+
+#include "StdAfx.h"
+
+#include "RarItem.h"
+#include "RarHeader.h"
+
+namespace NArchive{
+namespace NRar{
+
+bool CItem::IsEncrypted() const
+ { return (Flags & NHeader::NFile::kEncrypted) != 0; }
+bool CItem::IsSolid() const
+ { return (Flags & NHeader::NFile::kSolid) != 0; }
+bool CItem::IsCommented() const
+ { return (Flags & NHeader::NFile::kComment) != 0; }
+bool CItem::IsSplitBefore() const
+ { return (Flags & NHeader::NFile::kSplitBefore) != 0; }
+bool CItem::IsSplitAfter() const
+ { return (Flags & NHeader::NFile::kSplitAfter) != 0; }
+bool CItem::HasSalt() const
+ { return (Flags & NHeader::NFile::kSalt) != 0; }
+bool CItem::HasExtTime() const
+ { return (Flags & NHeader::NFile::kExtTime) != 0; }
+bool CItem::HasUnicodeName() const
+ { return (Flags & NHeader::NFile::kUnicodeName) != 0; }
+bool CItem::IsOldVersion() const
+ { return (Flags & NHeader::NFile::kOldVersion) != 0; }
+
+bool CItem::IgnoreItem() const
+{
+ switch(HostOS)
+ {
+ case NHeader::NFile::kHostMSDOS:
+ case NHeader::NFile::kHostOS2:
+ case NHeader::NFile::kHostWin32:
+ return ((Attributes & NHeader::NFile::kLabelFileAttribute) != 0);
+ }
+ return false;
+}
+
+UInt32 CItem::GetDictSize() const
+{ return (Flags >> NHeader::NFile::kDictBitStart) & NHeader::NFile::kDictMask; }
+
+bool CItem::IsDirectory() const
+{
+ if (GetDictSize() == NHeader::NFile::kDictDirectoryValue)
+ return true;
+ switch(HostOS)
+ {
+ case NHeader::NFile::kHostMSDOS:
+ case NHeader::NFile::kHostOS2:
+ case NHeader::NFile::kHostWin32:
+ if ((Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
+ return true;
+ }
+ return false;
+}
+
+UInt32 CItem::GetWinAttributes() const
+{
+ UInt32 winAttributes;
+ switch(HostOS)
+ {
+ case NHeader::NFile::kHostMSDOS:
+ case NHeader::NFile::kHostOS2:
+ case NHeader::NFile::kHostWin32:
+ winAttributes = Attributes;
+ break;
+ default:
+ winAttributes = 0; // must be converted from unix value;;
+ }
+ if (IsDirectory()) // test it;
+ winAttributes |= NHeader::NFile::kWinFileDirectoryAttributeMask;
+ return winAttributes;
+}
+
+void CItem::ClearFlags()
+{ Flags = 0; }
+
+void CItem::SetFlagBits(int startBitNumber, int numBits, int value)
+{
+ UInt16 mask = (UInt16)(((1 << numBits) - 1) << startBitNumber);
+ Flags &= ~mask;
+ Flags |= value << startBitNumber;
+}
+
+void CItem::SetBitMask(int bitMask, bool enable)
+{
+ if(enable)
+ Flags |= bitMask;
+ else
+ Flags &= ~bitMask;
+}
+
+void CItem::SetDictSize(UInt32 size)
+{
+ SetFlagBits(NHeader::NFile::kDictBitStart, NHeader::NFile::kNumDictBits, (size & NHeader::NFile::kDictMask));
+}
+
+void CItem::SetAsDirectory(bool directory)
+{
+ if (directory)
+ SetDictSize(NHeader::NFile::kDictDirectoryValue);
+}
+
+void CItem::SetEncrypted(bool encrypted)
+ { SetBitMask(NHeader::NFile::kEncrypted, encrypted); }
+void CItem::SetSolid(bool solid)
+ { SetBitMask(NHeader::NFile::kSolid, solid); }
+void CItem::SetCommented(bool commented)
+ { SetBitMask(NHeader::NFile::kComment, commented); }
+void CItem::SetSplitBefore(bool splitBefore)
+ { SetBitMask(NHeader::NFile::kSplitBefore, splitBefore); }
+void CItem::SetSplitAfter(bool splitAfter)
+ { SetBitMask(NHeader::NFile::kSplitAfter, splitAfter); }
+
+}}
diff --git a/CPP/7zip/Archive/Rar/RarItem.h b/CPP/7zip/Archive/Rar/RarItem.h
new file mode 100755
index 00000000..85050a42
--- /dev/null
+++ b/CPP/7zip/Archive/Rar/RarItem.h
@@ -0,0 +1,91 @@
+// RarItem.h
+
+#ifndef __ARCHIVE_RAR_ITEM_H
+#define __ARCHIVE_RAR_ITEM_H
+
+#include "Common/Types.h"
+#include "Common/String.h"
+
+namespace NArchive{
+namespace NRar{
+
+struct CRarTime
+{
+ UInt32 DosTime;
+ Byte LowSecond;
+ Byte SubTime[3];
+};
+
+class CItem
+{
+public:
+ UInt16 Flags;
+ UInt64 PackSize;
+ UInt64 UnPackSize;
+ Byte HostOS;
+ UInt32 FileCRC;
+
+ CRarTime CreationTime;
+ CRarTime LastWriteTime;
+ CRarTime LastAccessTime;
+ bool IsCreationTimeDefined;
+ // bool IsLastWriteTimeDefined;
+ bool IsLastAccessTimeDefined;
+
+ Byte UnPackVersion;
+ Byte Method;
+ UInt32 Attributes;
+ AString Name;
+ UString UnicodeName;
+
+ Byte Salt[8];
+
+ bool IsEncrypted() const;
+ bool IsSolid() const;
+ bool IsCommented() const;
+ bool IsSplitBefore() const;
+ bool IsSplitAfter() const;
+ bool HasSalt() const;
+ bool HasExtTime() const;
+
+ bool HasUnicodeName() const;
+ bool IsOldVersion() const;
+
+ UInt32 GetDictSize() const;
+ bool IsDirectory() const;
+ bool IgnoreItem() const;
+ UInt32 GetWinAttributes() const;
+
+ CItem(): IsCreationTimeDefined(false), IsLastAccessTimeDefined(false) {}
+private:
+ void SetFlagBits(int startBitNumber, int numBits, int value);
+ void SetBitMask(int bitMask, bool enable);
+public:
+ void ClearFlags();
+ void SetDictSize(UInt32 size);
+ void SetAsDirectory(bool directory);
+ void SetEncrypted(bool encrypted);
+ void SetSolid(bool solid);
+ void SetCommented(bool commented);
+ void SetSplitBefore(bool splitBefore);
+ void SetSplitAfter(bool splitAfter);
+};
+
+class CItemEx: public CItem
+{
+public:
+ UInt64 Position;
+ UInt16 MainPartSize;
+ UInt16 CommentSize;
+ UInt16 AlignSize;
+ UInt64 GetFullSize() const { return MainPartSize + CommentSize + AlignSize + PackSize; };
+ // DWORD GetHeaderWithCommentSize() const { return MainPartSize + CommentSize; };
+ UInt64 GetCommentPosition() const { return Position + MainPartSize; };
+ UInt64 GetDataPosition() const { return GetCommentPosition() + CommentSize + AlignSize; };
+};
+
+}}
+
+#endif
+
+
diff --git a/CPP/7zip/Archive/Rar/RarVolumeInStream.cpp b/CPP/7zip/Archive/Rar/RarVolumeInStream.cpp
new file mode 100755
index 00000000..32078e6d
--- /dev/null
+++ b/CPP/7zip/Archive/Rar/RarVolumeInStream.cpp
@@ -0,0 +1,79 @@
+// RarVolumeInStream.cpp
+
+#include "StdAfx.h"
+
+#include "RarVolumeInStream.h"
+
+#include "Windows/Defs.h"
+#include "Common/Defs.h"
+
+namespace NArchive {
+namespace NRar {
+
+void CFolderInStream::Init(
+ CObjectVector<CInArchive> *archives,
+ const CObjectVector<CItemEx> *items,
+ const CRefItem &refItem)
+{
+ _archives = archives;
+ _items = items;
+ _refItem = refItem;
+ _curIndex = 0;
+ CRCs.Clear();
+ _fileIsOpen = false;
+}
+
+HRESULT CFolderInStream::OpenStream()
+{
+ while (_curIndex < _refItem.NumItems)
+ {
+ const CItemEx &item = (*_items)[_refItem.ItemIndex + _curIndex];
+ _stream.Attach((*_archives)[_refItem.VolumeIndex + _curIndex].
+ CreateLimitedStream(item.GetDataPosition(), item.PackSize));
+ _curIndex++;
+ _fileIsOpen = true;
+ _crc.Init();
+ return S_OK;
+ }
+ return S_OK;
+}
+
+HRESULT CFolderInStream::CloseStream()
+{
+ CRCs.Add(_crc.GetDigest());
+ _stream.Release();
+ _fileIsOpen = false;
+ return S_OK;
+}
+
+STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize = 0;
+ while ((_curIndex < _refItem.NumItems || _fileIsOpen) && size > 0)
+ {
+ if (_fileIsOpen)
+ {
+ UInt32 localProcessedSize;
+ RINOK(_stream->Read(
+ ((Byte *)data) + realProcessedSize, size, &localProcessedSize));
+ _crc.Update(((Byte *)data) + realProcessedSize, localProcessedSize);
+ if (localProcessedSize == 0)
+ {
+ RINOK(CloseStream());
+ continue;
+ }
+ realProcessedSize += localProcessedSize;
+ size -= localProcessedSize;
+ break;
+ }
+ else
+ {
+ RINOK(OpenStream());
+ }
+ }
+ if (processedSize != 0)
+ *processedSize = realProcessedSize;
+ return S_OK;
+}
+
+}}
diff --git a/CPP/7zip/Archive/Rar/RarVolumeInStream.h b/CPP/7zip/Archive/Rar/RarVolumeInStream.h
new file mode 100755
index 00000000..4c9a9e96
--- /dev/null
+++ b/CPP/7zip/Archive/Rar/RarVolumeInStream.h
@@ -0,0 +1,50 @@
+// RarVolumeInStream.h
+
+#ifndef __RAR_VOLUME_IN_STREAM_H
+#define __RAR_VOLUME_IN_STREAM_H
+
+#include "../../IStream.h"
+#include "Common/CRC.h"
+#include "RarIn.h"
+
+namespace NArchive {
+namespace NRar {
+
+struct CRefItem
+{
+ int VolumeIndex;
+ int ItemIndex;
+ int NumItems;
+};
+
+class CFolderInStream:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+
+private:
+ CObjectVector<CInArchive> *_archives;
+ const CObjectVector<CItemEx> *_items;
+ CRefItem _refItem;
+ int _curIndex;
+ CCRC _crc;
+ bool _fileIsOpen;
+ CMyComPtr<ISequentialInStream> _stream;
+
+ HRESULT OpenStream();
+ HRESULT CloseStream();
+public:
+ void Init(CObjectVector<CInArchive> *archives,
+ const CObjectVector<CItemEx> *items,
+ const CRefItem &refItem);
+
+ CRecordVector<UInt32> CRCs;
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Rar/StdAfx.cpp b/CPP/7zip/Archive/Rar/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Archive/Rar/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Archive/Rar/StdAfx.h b/CPP/7zip/Archive/Rar/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Archive/Rar/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Archive/Rar/makefile b/CPP/7zip/Archive/Rar/makefile
new file mode 100755
index 00000000..678dd412
--- /dev/null
+++ b/CPP/7zip/Archive/Rar/makefile
@@ -0,0 +1,90 @@
+PROG = rar.dll
+DEF_FILE = ../Archive.def
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib user32.lib
+
+RAR_OBJS = \
+ $O\DllExports.obj \
+ $O\RarHandler.obj \
+ $O\RarHeader.obj \
+ $O\RarIn.obj \
+ $O\RarItem.obj \
+ $O\RarVolumeInStream.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\CRC.obj \
+ $O\IntToString.obj \
+ $O\NewHandler.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\UTFConvert.obj \
+ $O\Vector.obj \
+
+WIN_OBJS = \
+ $O\DLL.obj \
+ $O\FileFind.obj \
+ $O\PropVariant.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\LimitedStreams.obj \
+ $O\ProgressUtils.obj \
+ $O\StreamObjects.obj \
+ $O\StreamUtils.obj \
+
+AR_COMMON_OBJS = \
+ $O\CodecsPath.obj \
+ $O\FilterCoder.obj \
+ $O\InStreamWithCRC.obj \
+ $O\OutStreamWithCRC.obj \
+
+7Z_OBJS = \
+ $O\7zMethodID.obj \
+ $O\7zMethods.obj \
+
+CRYPTO_HASH_OBJS = \
+ $O\Sha1.obj \
+
+CRYPTO_RAR20_OBJS = \
+ $O\Rar20Cipher.obj \
+ $O\Rar20Crypto.obj \
+
+CRYPTO_RARAES_OBJS = \
+ $O\RarAES.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(RAR_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $(7Z_OBJS) \
+ $(CRYPTO_HASH_OBJS) \
+ $(CRYPTO_RAR20_OBJS) \
+ $(CRYPTO_RARAES_OBJS) \
+ $O\CopyCoder.obj \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(RAR_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)
+$(7Z_OBJS): ../7z/$(*B).cpp
+ $(COMPL)
+$(CRYPTO_HASH_OBJS): ../../Crypto/Hash/$(*B).cpp
+ $(COMPL_O2)
+$(CRYPTO_RAR20_OBJS): ../../Crypto/Rar20/$(*B).cpp
+ $(COMPL)
+$(CRYPTO_RARAES_OBJS): ../../Crypto/RarAES/$(*B).cpp
+ $(COMPL)
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/Archive/Rar/rar.ico b/CPP/7zip/Archive/Rar/rar.ico
new file mode 100755
index 00000000..2918d294
--- /dev/null
+++ b/CPP/7zip/Archive/Rar/rar.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Rar/resource.rc b/CPP/7zip/Archive/Rar/resource.rc
new file mode 100755
index 00000000..94b4198b
--- /dev/null
+++ b/CPP/7zip/Archive/Rar/resource.rc
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("Rar Plugin", "rar")
+
+101 ICON "rar.ico"
diff --git a/CPP/7zip/Archive/Split/DllExports.cpp b/CPP/7zip/Archive/Split/DllExports.cpp
new file mode 100755
index 00000000..e28f64ce
--- /dev/null
+++ b/CPP/7zip/Archive/Split/DllExports.cpp
@@ -0,0 +1,65 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+#include "SplitHandler.h"
+#include "../../ICoder.h"
+
+// {23170F69-40C1-278A-1000-000110EA0000}
+DEFINE_GUID(CLSID_CSplitHandler,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xEA, 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_CSplitHandler)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ if (*interfaceID != IID_IInArchive)
+ return E_NOINTERFACE;
+ CMyComPtr<IInArchive> inArchive = (IInArchive *)new NArchive::NSplit::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"Split";
+ break;
+ case NArchive::kClassID:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CSplitHandler, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NArchive::kExtension:
+ propVariant = L"001";
+ break;
+ case NArchive::kUpdate:
+ propVariant = false;
+ break;
+ case NArchive::kKeepName:
+ propVariant = true;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/CPP/7zip/Archive/Split/Split.dsp b/CPP/7zip/Archive/Split/Split.dsp
new file mode 100755
index 00000000..d6229d98
--- /dev/null
+++ b/CPP/7zip/Archive/Split/Split.dsp
@@ -0,0 +1,237 @@
+# Microsoft Developer Studio Project File - Name="Split" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=Split - 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 "Split.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 "Split.mak" CFG="Split - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Split - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Split - 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)" == "Split - 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 "SPLIT_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SPLIT_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\split.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Split - 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 "SPLIT_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 "SPLIT_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\split.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "Split - Win32 Release"
+# Name "Split - 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=.\Split.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\Alloc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Alloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\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\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 "Compress"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.h
+# End Source File
+# End Group
+# Begin Group "7zip Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Common\MultiStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\MultiStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\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 "Interface"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\IArchive.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\SplitHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\SplitHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\SplitHandlerOut.cpp
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/Archive/Split/Split.dsw b/CPP/7zip/Archive/Split/Split.dsw
new file mode 100755
index 00000000..988ca30a
--- /dev/null
+++ b/CPP/7zip/Archive/Split/Split.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Split"=.\Split.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Archive/Split/Split.ico b/CPP/7zip/Archive/Split/Split.ico
new file mode 100755
index 00000000..5cb93e84
--- /dev/null
+++ b/CPP/7zip/Archive/Split/Split.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Split/SplitHandler.cpp b/CPP/7zip/Archive/Split/SplitHandler.cpp
new file mode 100755
index 00000000..e919154f
--- /dev/null
+++ b/CPP/7zip/Archive/Split/SplitHandler.cpp
@@ -0,0 +1,415 @@
+// Tar/Handler.cpp
+
+#include "StdAfx.h"
+
+#include "SplitHandler.h"
+
+#include "Common/Defs.h"
+#include "Common/StringConvert.h"
+#include "Common/NewHandler.h"
+#include "Common/ComTry.h"
+
+#include "Windows/Time.h"
+#include "Windows/PropVariant.h"
+
+#include "../../Common/ProgressUtils.h"
+#include "../../Compress/Copy/CopyCoder.h"
+#include "../Common/ItemNameUtils.h"
+#include "../Common/MultiStream.h"
+
+using namespace NWindows;
+using namespace NTime;
+
+namespace NArchive {
+namespace NSplit {
+
+STATPROPSTG kProperties[] =
+{
+ { NULL, kpidPath, VT_BSTR},
+// { NULL, kpidIsFolder, VT_BOOL},
+ { NULL, kpidSize, VT_UI8},
+ { NULL, kpidPackedSize, VT_UI8},
+};
+
+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;
+ *name = 0;
+ 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;
+}
+
+class CSeqName
+{
+public:
+ UString _unchangedPart;
+ UString _changedPart;
+ bool _splitStyle;
+ UString GetNextName()
+ {
+ UString newName;
+ if (_splitStyle)
+ {
+ int i;
+ int numLetters = _changedPart.Length();
+ for (i = numLetters - 1; i >= 0; i--)
+ {
+ wchar_t c = _changedPart[i];
+ if (c == 'z')
+ {
+ c = 'a';
+ newName = c + newName;
+ continue;
+ }
+ else if (c == 'Z')
+ {
+ c = 'A';
+ newName = c + newName;
+ continue;
+ }
+ c++;
+ if ((c == 'z' || c == 'Z') && i == 0)
+ {
+ _unchangedPart += c;
+ wchar_t newChar = (c == 'z') ? L'a' : L'A';
+ newName.Empty();
+ numLetters++;
+ for (int k = 0; k < numLetters; k++)
+ newName += newChar;
+ break;
+ }
+ newName = c + newName;
+ i--;
+ for (; i >= 0; i--)
+ newName = _changedPart[i] + newName;
+ break;
+ }
+ }
+ else
+ {
+ int i;
+ int numLetters = _changedPart.Length();
+ for (i = numLetters - 1; i >= 0; i--)
+ {
+ wchar_t c = _changedPart[i];
+ if (c == L'9')
+ {
+ c = L'0';
+ newName = c + newName;
+ if (i == 0)
+ newName = UString(L'1') + newName;
+ continue;
+ }
+ c++;
+ newName = c + newName;
+ i--;
+ for (; i >= 0; i--)
+ newName = _changedPart[i] + newName;
+ break;
+ }
+ }
+ _changedPart = newName;
+ return _unchangedPart + _changedPart;
+ }
+};
+
+STDMETHODIMP CHandler::Open(IInStream *stream,
+ const UInt64 * /* maxCheckStartPosition */,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ COM_TRY_BEGIN
+ Close();
+ if (openArchiveCallback == 0)
+ return S_FALSE;
+ // try
+ {
+ CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
+ CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = openArchiveCallback;
+ if (openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback,
+ &openVolumeCallback) != S_OK)
+ return S_FALSE;
+
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant));
+ if (propVariant.vt != VT_BSTR)
+ return S_FALSE;
+ _name = propVariant.bstrVal;
+ }
+
+ int dotPos = _name.ReverseFind('.');
+ UString prefix, ext;
+ if (dotPos >= 0)
+ {
+ prefix = _name.Left(dotPos + 1);
+ ext = _name.Mid(dotPos + 1);
+ }
+ else
+ ext = _name;
+ UString extBig = ext;
+ extBig.MakeUpper();
+
+ CSeqName seqName;
+
+ int numLetters = 2;
+ bool splitStyle = false;
+ if (extBig.Right(2) == L"AA")
+ {
+ splitStyle = true;
+ while (numLetters < extBig.Length())
+ {
+ if (extBig[extBig.Length() - numLetters - 1] != 'A')
+ break;
+ numLetters++;
+ }
+ }
+ else if (ext.Right(2) == L"01")
+ {
+ while (numLetters < extBig.Length())
+ {
+ if (extBig[extBig.Length() - numLetters - 1] != '0')
+ break;
+ numLetters++;
+ }
+ if (numLetters != ext.Length())
+ return S_FALSE;
+ }
+ else
+ return S_FALSE;
+
+ _streams.Add(stream);
+
+ seqName._unchangedPart = prefix + ext.Left(extBig.Length() - numLetters);
+ seqName._changedPart = ext.Right(numLetters);
+ seqName._splitStyle = splitStyle;
+
+ if (prefix.Length() < 1)
+ _subName = L"file";
+ else
+ _subName = prefix.Left(prefix.Length() - 1);
+
+ _totalSize = 0;
+ UInt64 size;
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(openVolumeCallback->GetProperty(kpidSize, &propVariant));
+ if (propVariant.vt != VT_UI8)
+ return E_INVALIDARG;
+ size = propVariant.uhVal.QuadPart;
+ }
+ _totalSize += size;
+ _sizes.Add(size);
+
+ if (openArchiveCallback != NULL)
+ {
+ RINOK(openArchiveCallback->SetTotal(NULL, NULL));
+ UInt64 numFiles = _streams.Size();
+ RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
+ }
+
+ for (;;)
+ {
+ UString fullName = seqName.GetNextName();
+ CMyComPtr<IInStream> nextStream;
+ HRESULT result = openVolumeCallback->GetStream(fullName, &nextStream);
+ if (result == S_FALSE)
+ break;
+ if (result != S_OK)
+ return result;
+ if (!stream)
+ break;
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(openVolumeCallback->GetProperty(kpidSize, &propVariant));
+ if (propVariant.vt != VT_UI8)
+ return E_INVALIDARG;
+ size = propVariant.uhVal.QuadPart;
+ }
+ _totalSize += size;
+ _sizes.Add(size);
+ _streams.Add(nextStream);
+ if (openArchiveCallback != NULL)
+ {
+ UInt64 numFiles = _streams.Size();
+ RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
+ }
+ }
+ }
+ /*
+ catch(...)
+ {
+ return S_FALSE;
+ }
+ */
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ _sizes.Clear();
+ _streams.Clear();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = _streams.IsEmpty() ? 0 : 1;
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant propVariant;
+
+ switch(propID)
+ {
+ case kpidPath:
+ propVariant = _subName;
+ break;
+ case kpidIsFolder:
+ propVariant = false;
+ break;
+ case kpidSize:
+ case kpidPackedSize:
+ propVariant = _totalSize;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
+ Int32 _aTestMode, IArchiveExtractCallback *_anExtractCallback)
+{
+ COM_TRY_BEGIN
+
+ if (numItems != UInt32(-1))
+ {
+ if (numItems != 1)
+ return E_INVALIDARG;
+ if (indices[0] != 0)
+ return E_INVALIDARG;
+ }
+ bool testMode = (_aTestMode != 0);
+ CMyComPtr<IArchiveExtractCallback> extractCallback = _anExtractCallback;
+ extractCallback->SetTotal(_totalSize);
+
+ /*
+ CMyComPtr<IArchiveVolumeExtractCallback> volumeExtractCallback;
+ if (extractCallback.QueryInterface(&volumeExtractCallback) != S_OK)
+ return E_FAIL;
+ */
+
+ UInt64 currentTotalSize = 0;
+ UInt64 currentItemSize;
+
+ RINOK(extractCallback->SetCompleted(&currentTotalSize));
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ Int32 askMode;
+ askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
+ NArchive::NExtract::NAskMode::kExtract;
+ Int32 index = 0;
+ RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
+
+ RINOK(extractCallback->PrepareOperation(askMode));
+ if (testMode)
+ {
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ return S_OK;
+ }
+ // currentItemSize = itemInfo.Size;
+
+ if(!testMode && (!realOutStream))
+ {
+ return S_OK;
+ }
+
+ NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
+ CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
+
+ for(int i = 0; i < _streams.Size(); i++, currentTotalSize += currentItemSize)
+ {
+ // CMyComPtr<ISequentialInStream> inStream;
+ // RINOK(volumeExtractCallback->GetInStream(_names[i], &inStream));
+
+ 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);
+ IInStream *inStream = _streams[i];
+ RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
+ try
+ {
+ RINOK(copyCoder->Code(inStream, realOutStream,
+ NULL, NULL, compressProgress));
+ }
+ catch(...)
+ {
+ realOutStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
+ return S_OK;;
+ }
+ currentItemSize = copyCoderSpec->TotalSize;
+ }
+ realOutStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
+{
+ if (index != 0)
+ return E_INVALIDARG;
+ *stream = 0;
+ CMultiStream *streamSpec = new CMultiStream;
+ CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
+ for (int i = 0; i < _streams.Size(); i++)
+ {
+ CMultiStream::CSubStreamInfo subStreamInfo;
+ subStreamInfo.Stream = _streams[i];
+ subStreamInfo.Pos = 0;
+ subStreamInfo.Size = _sizes[i];
+ streamSpec->Streams.Add(subStreamInfo);
+ }
+ streamSpec->Init();
+ *stream = streamTemp.Detach();
+ return S_OK;
+}
+
+}}
diff --git a/CPP/7zip/Archive/Split/SplitHandler.h b/CPP/7zip/Archive/Split/SplitHandler.h
new file mode 100755
index 00000000..8b3fcb70
--- /dev/null
+++ b/CPP/7zip/Archive/Split/SplitHandler.h
@@ -0,0 +1,62 @@
+// Split/Handler.h
+
+#ifndef __SPLIT_HANDLER_H
+#define __SPLIT_HANDLER_H
+
+#include "Common/MyCom.h"
+#include "Common/String.h"
+#include "../IArchive.h"
+
+namespace NArchive {
+namespace NSplit {
+
+class CHandler:
+ public IInArchive,
+ public IInArchiveGetStream,
+ // public IOutArchive,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP1(IInArchiveGetStream)
+
+ 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);
+
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
+
+ // IOutArchiveHandler
+ /*
+ STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems,
+ IArchiveUpdateCallback *updateCallback);
+
+ STDMETHOD(GetFileTimeType)(UInt32 *type);
+ */
+
+private:
+ UString _subName;
+ UString _name;
+ CObjectVector<CMyComPtr<IInStream> > _streams;
+ CRecordVector<UInt64> _sizes;
+
+ UInt64 _totalSize;
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Split/SplitHandlerOut.cpp b/CPP/7zip/Archive/Split/SplitHandlerOut.cpp
new file mode 100755
index 00000000..ea86c281
--- /dev/null
+++ b/CPP/7zip/Archive/Split/SplitHandlerOut.cpp
@@ -0,0 +1,102 @@
+// Split/OutHandler.cpp
+
+#include "StdAfx.h"
+
+#include "SplitHandler.h"
+#include "../../../Windows/PropVariant.h"
+#include "../../../Common/ComTry.h"
+#include "../../../Common/StringToInt.h"
+
+using namespace NWindows;
+
+namespace NArchive {
+namespace NSplit {
+
+/*
+STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
+{
+ *type = NFileTimeType::kWindows;
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
+ IArchiveUpdateCallback *updateCallback)
+{
+ COM_TRY_BEGIN
+
+ if (numItems != 1)
+ return E_INVALIDARG;
+
+ UInt64 volumeSize = 0;
+
+ CMyComPtr<IArchiveUpdateCallback2> callback2;
+ updateCallback->QueryInterface(IID_IArchiveUpdateCallback2,
+ (void **)&callback2);
+
+ RINOK(callback2->GetVolumeSize(0, &volumeSize));
+
+ Int32 newData;
+ Int32 newProperties;
+ UInt32 indexInArchive;
+ if (!updateCallback)
+ return E_FAIL;
+
+ UInt32 fileIndex = 0;
+ RINOK(updateCallback->GetUpdateItemInfo(fileIndex,
+ &newData, &newProperties, &indexInArchive));
+
+ if (newProperties != 0)
+ {
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(fileIndex, kpidIsFolder, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ {
+ }
+ else if (propVariant.vt != VT_BOOL)
+ return E_INVALIDARG;
+ else
+ {
+ if (propVariant.boolVal != VARIANT_FALSE)
+ return E_INVALIDARG;
+ }
+ }
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(fileIndex, kpidIsAnti, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ {
+ }
+ else if (propVariant.vt != VT_BOOL)
+ return E_INVALIDARG;
+ else
+ {
+ if (propVariant.boolVal != VARIANT_FALSE)
+ return E_INVALIDARG;
+ }
+ }
+ }
+ UInt64 newSize;
+ bool thereIsCopyData = false;
+ if (newData != 0)
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(fileIndex, kpidSize, &propVariant));
+ if (propVariant.vt != VT_UI8)
+ return E_INVALIDARG;
+ newSize = propVariant.uhVal.QuadPart;
+ }
+ else
+ thereIsCopyData = true;
+
+ UInt64 pos = 0;
+ while(pos < newSize)
+ {
+
+ }
+ return S_OK;
+ COM_TRY_END
+}
+*/
+
+}}
diff --git a/CPP/7zip/Archive/Split/StdAfx.cpp b/CPP/7zip/Archive/Split/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Archive/Split/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Archive/Split/StdAfx.h b/CPP/7zip/Archive/Split/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Archive/Split/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Archive/Split/makefile b/CPP/7zip/Archive/Split/makefile
new file mode 100755
index 00000000..650c750b
--- /dev/null
+++ b/CPP/7zip/Archive/Split/makefile
@@ -0,0 +1,51 @@
+PROG = split.dll
+DEF_FILE = ../Archive.def
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib user32.lib
+
+SPLIT_OBJS = \
+ $O\DllExports.obj \
+ $O\SplitHandler.obj \
+ $O\SplitHandlerOut.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\NewHandler.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\Vector.obj \
+
+WIN_OBJS = \
+ $O\PropVariant.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\ProgressUtils.obj \
+ $O\StreamUtils.obj \
+
+AR_COMMON_OBJS = \
+ $O\MultiStream.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(SPLIT_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $O\CopyCoder.obj \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(SPLIT_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)
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/Archive/Split/resource.rc b/CPP/7zip/Archive/Split/resource.rc
new file mode 100755
index 00000000..3e301754
--- /dev/null
+++ b/CPP/7zip/Archive/Split/resource.rc
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("Split Plugin", "split")
+
+101 ICON "Split.ico"
diff --git a/CPP/7zip/Archive/Tar/DllExports.cpp b/CPP/7zip/Archive/Tar/DllExports.cpp
new file mode 100755
index 00000000..afa2fd24
--- /dev/null
+++ b/CPP/7zip/Archive/Tar/DllExports.cpp
@@ -0,0 +1,86 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+#include "../../ICoder.h"
+#include "TarHandler.h"
+
+// {23170F69-40C1-278A-1000-000110EE0000}
+DEFINE_GUID(CLSID_CTarHandler,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xEE, 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_CTarHandler)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ int needIn = *interfaceID == IID_IInArchive;
+ int needOut = *interfaceID == IID_IOutArchive;
+ if (needIn || needOut)
+ {
+ NArchive::NTar::CHandler *temp = new NArchive::NTar::CHandler;
+ if (needIn)
+ {
+ CMyComPtr<IInArchive> inArchive = (IInArchive *)temp;
+ *outObject = inArchive.Detach();
+ }
+ else
+ {
+ CMyComPtr<IOutArchive> outArchive = (IOutArchive *)temp;
+ *outObject = outArchive.Detach();
+ }
+ }
+ else
+ return E_NOINTERFACE;
+ COM_TRY_END
+ return S_OK;
+}
+
+STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
+{
+ NWindows::NCOM::CPropVariant propVariant;
+ switch(propID)
+ {
+ case NArchive::kName:
+ propVariant = L"Tar";
+ break;
+ case NArchive::kClassID:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CTarHandler, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NArchive::kExtension:
+ propVariant = L"tar";
+ break;
+ case NArchive::kUpdate:
+ propVariant = true;
+ break;
+ case NArchive::kKeepName:
+ propVariant = false;
+ break;
+ case NArchive::kStartSignature:
+ {
+ const unsigned char sig[] = { 'u', 's', 't', 'a', 'r' };
+ if ((value->bstrVal = ::SysAllocStringByteLen((const char *)sig, 5)) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/CPP/7zip/Archive/Tar/StdAfx.cpp b/CPP/7zip/Archive/Tar/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Archive/Tar/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Archive/Tar/StdAfx.h b/CPP/7zip/Archive/Tar/StdAfx.h
new file mode 100755
index 00000000..2e4be10b
--- /dev/null
+++ b/CPP/7zip/Archive/Tar/StdAfx.h
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/Archive/Tar/Tar.dsp b/CPP/7zip/Archive/Tar/Tar.dsp
new file mode 100755
index 00000000..c01e7383
--- /dev/null
+++ b/CPP/7zip/Archive/Tar/Tar.dsp
@@ -0,0 +1,297 @@
+# Microsoft Developer Studio Project File - Name="Tar" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=Tar - 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 "Tar.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 "Tar.mak" CFG="Tar - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Tar - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Tar - 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)" == "Tar - 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 "TAR_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TAR_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\tar.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Tar - 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 "TAR_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 "TAR_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\tar.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "Tar - Win32 Release"
+# Name "Tar - 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
+# Begin Source File
+
+SOURCE=.\Tar.ico
+# 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\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\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\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
+
+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 "Compress"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.h
+# End Source File
+# End Group
+# Begin Group "Engine"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\TarHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\TarHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\TarHandlerOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\TarHeader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\TarHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\TarIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\TarIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\TarItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\TarOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\TarOut.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\TarUpdate.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\TarUpdate.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 "7zip Common"
+
+# PROP Default_Filter ""
+# 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\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
+# End Target
+# End Project
diff --git a/CPP/7zip/Archive/Tar/Tar.dsw b/CPP/7zip/Archive/Tar/Tar.dsw
new file mode 100755
index 00000000..318cce1c
--- /dev/null
+++ b/CPP/7zip/Archive/Tar/Tar.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Tar"=.\Tar.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Archive/Tar/TarHandler.cpp b/CPP/7zip/Archive/Tar/TarHandler.cpp
new file mode 100755
index 00000000..9c2cd006
--- /dev/null
+++ b/CPP/7zip/Archive/Tar/TarHandler.cpp
@@ -0,0 +1,282 @@
+// Tar/Handler.cpp
+
+#include "StdAfx.h"
+
+#include "TarHandler.h"
+#include "TarIn.h"
+
+#include "Common/Defs.h"
+#include "Common/StringConvert.h"
+#include "Common/NewHandler.h"
+#include "Common/ComTry.h"
+
+#include "Windows/Time.h"
+#include "Windows/PropVariant.h"
+
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/LimitedStreams.h"
+#include "../../Compress/Copy/CopyCoder.h"
+
+#include "../Common/ItemNameUtils.h"
+
+using namespace NWindows;
+using namespace NTime;
+
+namespace NArchive {
+namespace NTar {
+
+STATPROPSTG kProperties[] =
+{
+ { NULL, kpidPath, VT_BSTR},
+ { NULL, kpidIsFolder, VT_BOOL},
+ { NULL, kpidSize, VT_UI8},
+ { NULL, kpidPackedSize, VT_UI8},
+ { NULL, kpidLastWriteTime, VT_FILETIME},
+ { NULL, kpidUser, VT_BSTR},
+ { NULL, kpidGroup, VT_BSTR},
+};
+
+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;
+ *name = 0;
+ 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::Open(IInStream *stream,
+ const UInt64 * /* maxCheckStartPosition */,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ COM_TRY_BEGIN
+ // try
+ {
+ CInArchive archive;
+
+ if(archive.Open(stream) != S_OK)
+ return S_FALSE;
+
+ _items.Clear();
+
+ if (openArchiveCallback != NULL)
+ {
+ RINOK(openArchiveCallback->SetTotal(NULL, NULL));
+ UInt64 numFiles = _items.Size();
+ RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
+ }
+
+ for (;;)
+ {
+ CItemEx item;
+ bool filled;
+ HRESULT result = archive.GetNextItem(filled, item);
+ if (result == S_FALSE)
+ return S_FALSE;
+ if (result != S_OK)
+ return S_FALSE;
+ if (!filled)
+ break;
+ _items.Add(item);
+ archive.SkeepDataRecords(item.Size);
+ if (openArchiveCallback != NULL)
+ {
+ UInt64 numFiles = _items.Size();
+ RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
+ }
+ }
+ if (_items.Size() == 0)
+ return S_FALSE;
+
+ _inStream = stream;
+ }
+ /*
+ catch(...)
+ {
+ return S_FALSE;
+ }
+ */
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ _items.Clear();
+ _inStream.Release();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = _items.Size();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant propVariant;
+ const NArchive::NTar::CItemEx &item = _items[index];
+
+ switch(propID)
+ {
+ case kpidPath:
+ propVariant = (const wchar_t *)NItemName::GetOSName2(
+ MultiByteToUnicodeString(item.Name, CP_OEMCP));
+ break;
+ case kpidIsFolder:
+ propVariant = item.IsDirectory();
+ break;
+ case kpidSize:
+ case kpidPackedSize:
+ propVariant = (UInt64)item.Size;
+ break;
+ case kpidLastWriteTime:
+ {
+ FILETIME utcFileTime;
+ if (item.ModificationTime != 0)
+ NTime::UnixTimeToFileTime((UInt32)item.ModificationTime, utcFileTime);
+ else
+ {
+ utcFileTime.dwLowDateTime = 0;
+ utcFileTime.dwHighDateTime = 0;
+ }
+ propVariant = utcFileTime;
+ break;
+ }
+ case kpidUser:
+ propVariant = (const wchar_t *)
+ MultiByteToUnicodeString(item.UserName, CP_OEMCP);
+ break;
+ case kpidGroup:
+ propVariant = (const wchar_t *)
+ MultiByteToUnicodeString(item.GroupName, CP_OEMCP);
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
+ Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ bool testMode = (_aTestMode != 0);
+ bool allFilesMode = (numItems == UInt32(-1));
+ if (allFilesMode)
+ numItems = _items.Size();
+ UInt64 totalSize = 0;
+ if(numItems == 0)
+ return S_OK;
+ UInt32 i;
+ for(i = 0; i < numItems; i++)
+ totalSize += _items[allFilesMode ? i : indices[i]].Size;
+ extractCallback->SetTotal(totalSize);
+
+ UInt64 currentTotalSize = 0;
+ UInt64 currentItemSize;
+
+ CMyComPtr<ICompressCoder> copyCoder;
+
+ 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];
+ const CItemEx &item = _items[index];
+
+ RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
+
+ currentItemSize = item.Size;
+
+ if(item.IsDirectory())
+ {
+ RINOK(extractCallback->PrepareOperation(askMode));
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ continue;
+ }
+ if(!testMode && (!realOutStream))
+ {
+ continue;
+ }
+ RINOK(extractCallback->PrepareOperation(askMode));
+ {
+ if (testMode)
+ {
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ continue;
+ }
+
+ RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL));
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+ CMyComPtr<ISequentialInStream> inStream(streamSpec);
+ streamSpec->SetStream(_inStream);
+ streamSpec->Init(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;
+ }
+ try
+ {
+ RINOK(copyCoder->Code(inStream, realOutStream,
+ NULL, NULL, compressProgress));
+ }
+ catch(...)
+ {
+ realOutStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ realOutStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ }
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+}}
diff --git a/CPP/7zip/Archive/Tar/TarHandler.h b/CPP/7zip/Archive/Tar/TarHandler.h
new file mode 100755
index 00000000..7b6e3a40
--- /dev/null
+++ b/CPP/7zip/Archive/Tar/TarHandler.h
@@ -0,0 +1,56 @@
+// Tar/Handler.h
+
+#ifndef __TAR_HANDLER_H
+#define __TAR_HANDLER_H
+
+#include "Common/MyCom.h"
+#include "../IArchive.h"
+
+#include "TarItem.h"
+
+namespace NArchive {
+namespace NTar {
+
+class CHandler:
+ public IInArchive,
+ public IOutArchive,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP2(
+ IInArchive,
+ IOutArchive
+ )
+
+ 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);
+
+ // IOutArchive
+ STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems,
+ IArchiveUpdateCallback *updateCallback);
+ STDMETHOD(GetFileTimeType)(UInt32 *type);
+
+private:
+ CObjectVector<CItemEx> _items;
+ CMyComPtr<IInStream> _inStream;
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp
new file mode 100755
index 00000000..110833fb
--- /dev/null
+++ b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp
@@ -0,0 +1,126 @@
+// Tar/HandlerOut.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StringConvert.h"
+#include "Common/ComTry.h"
+
+#include "Windows/PropVariant.h"
+#include "Windows/Time.h"
+
+#include "../Common/ItemNameUtils.h"
+
+#include "TarHandler.h"
+#include "TarUpdate.h"
+
+using namespace NWindows;
+using namespace NCOM;
+using namespace NTime;
+
+namespace NArchive {
+namespace NTar {
+
+STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
+{
+ *type = NFileTimeType::kUnix;
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
+ IArchiveUpdateCallback *updateCallback)
+{
+ COM_TRY_BEGIN
+ CObjectVector<CUpdateItemInfo> updateItems;
+ for(UInt32 i = 0; i < numItems; i++)
+ {
+ CUpdateItemInfo updateItem;
+ Int32 newData;
+ Int32 newProperties;
+ UInt32 indexInArchive;
+ if (!updateCallback)
+ return E_FAIL;
+ RINOK(updateCallback->GetUpdateItemInfo(i,
+ &newData, &newProperties, &indexInArchive));
+ updateItem.NewProperties = IntToBool(newProperties);
+ updateItem.NewData = IntToBool(newData);
+ updateItem.IndexInArchive = indexInArchive;
+ updateItem.IndexInClient = i;
+
+ if (IntToBool(newProperties))
+ {
+ FILETIME utcTime;
+ UString name;
+ bool isDirectoryStatusDefined;
+ UInt32 attributes;
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ attributes = 0;
+ else if (propVariant.vt != VT_UI4)
+ return E_INVALIDARG;
+ else
+ attributes = propVariant.ulVal;
+ }
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(i, kpidLastWriteTime, &propVariant));
+ if (propVariant.vt != VT_FILETIME)
+ return E_INVALIDARG;
+ utcTime = propVariant.filetime;
+ }
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(i, kpidPath, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ name.Empty();
+ else if (propVariant.vt != VT_BSTR)
+ return E_INVALIDARG;
+ else
+ name = propVariant.bstrVal;
+ }
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(i, kpidIsFolder, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ isDirectoryStatusDefined = false;
+ else if (propVariant.vt != VT_BOOL)
+ return E_INVALIDARG;
+ else
+ {
+ updateItem.IsDirectory = (propVariant.boolVal != VARIANT_FALSE);
+ isDirectoryStatusDefined = true;
+ }
+ }
+ updateItem.Name = UnicodeStringToMultiByte(
+ NItemName::MakeLegalName(name), CP_OEMCP);
+ if (!isDirectoryStatusDefined)
+ updateItem.IsDirectory = ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
+ if (updateItem.IsDirectory)
+ updateItem.Name += '/';
+
+ if(!FileTimeToUnixTime(utcTime, updateItem.Time))
+ {
+ updateItem.Time = 0;
+ // return E_INVALIDARG;
+ }
+ }
+ if (IntToBool(newData))
+ {
+ UInt64 size;
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant));
+ if (propVariant.vt != VT_UI8)
+ return E_INVALIDARG;
+ size = propVariant.uhVal.QuadPart;
+ }
+ updateItem.Size = size;
+ }
+ updateItems.Add(updateItem);
+ }
+ return UpdateArchive(_inStream, outStream, _items, updateItems, updateCallback);
+ COM_TRY_END
+}
+
+}}
diff --git a/CPP/7zip/Archive/Tar/TarHeader.cpp b/CPP/7zip/Archive/Tar/TarHeader.cpp
new file mode 100755
index 00000000..35f0d0cf
--- /dev/null
+++ b/CPP/7zip/Archive/Tar/TarHeader.cpp
@@ -0,0 +1,25 @@
+// Archive/Tar/Header.h
+
+#include "StdAfx.h"
+
+#include "TarHeader.h"
+
+namespace NArchive {
+namespace NTar {
+namespace NFileHeader {
+
+ // The checksum field is filled with this while the checksum is computed.
+ const char *kCheckSumBlanks = " "; // 8 blanks, no null
+
+ const char *kLongLink = "././@LongLink";
+ const char *kLongLink2 = "@LongLink";
+
+ // The magic field is filled with this if uname and gname are valid.
+ namespace NMagic
+ {
+ const char *kUsTar = "ustar"; // 5 chars
+ const char *kGNUTar = "GNUtar "; // 7 chars and a null
+ const char *kEmpty = "\0\0\0\0\0\0\0\0"; // 7 chars and a null
+ }
+
+}}}
diff --git a/CPP/7zip/Archive/Tar/TarHeader.h b/CPP/7zip/Archive/Tar/TarHeader.h
new file mode 100755
index 00000000..0ab31e52
--- /dev/null
+++ b/CPP/7zip/Archive/Tar/TarHeader.h
@@ -0,0 +1,99 @@
+// Archive/Tar/Header.h
+
+#ifndef __ARCHIVE_TAR_HEADER_H
+#define __ARCHIVE_TAR_HEADER_H
+
+#include "Common/Types.h"
+
+namespace NArchive {
+namespace NTar {
+
+namespace NFileHeader
+{
+ const int kRecordSize = 512;
+ const int kNameSize = 100;
+ const int kUserNameSize = 32;
+ const int kGroupNameSize = 32;
+ const int kPrefixSize = 155;
+
+ /*
+ struct CHeader
+ {
+ char Name[kNameSize];
+ char Mode[8];
+ char UID[8];
+ char GID[8];
+ char Size[12];
+ char ModificationTime[12];
+ char CheckSum[8];
+ char LinkFlag;
+ char LinkName[kNameSize];
+ char Magic[8];
+ char UserName[kUserNameSize];
+ char GroupName[kGroupNameSize];
+ char DeviceMajor[8];
+ char DeviceMinor[8];
+ char Prefix[155];
+ };
+ union CRecord
+ {
+ CHeader Header;
+ Byte Padding[kRecordSize];
+ };
+ */
+
+ namespace NMode
+ {
+ const int kSetUID = 04000; // Set UID on execution
+ const int kSetGID = 02000; // Set GID on execution
+ const int kSaveText = 01000; // Save text (sticky bit)
+ }
+
+ namespace NFilePermissions
+ {
+ const int kUserRead = 00400; // read by owner
+ const int kUserWrite = 00200; // write by owner
+ const int kUserExecute = 00100; // execute/search by owner
+ const int kGroupRead = 00040; // read by group
+ const int kGroupWrite = 00020; // write by group
+ const int kGroupExecute = 00010; // execute/search by group
+ const int kOtherRead = 00004; // read by other
+ const int kOtherWrite = 00002; // write by other
+ const int kOtherExecute = 00001; // execute/search by other
+ }
+
+
+ // The linkflag defines the type of file
+ namespace NLinkFlag
+ {
+ const char kOldNormal = '\0'; // Normal disk file, Unix compatible
+ const char kNormal = '0'; // Normal disk file
+ const char kLink = '1'; // Link to previously dumped file
+ const char kSymbolicLink = '2'; // Symbolic link
+ const char kCharacter = '3'; // Character special file
+ const char kBlock = '4'; // Block special file
+ const char kDirectory = '5'; // Directory
+ const char kFIFO = '6'; // FIFO special file
+ const char kContiguous = '7'; // Contiguous file
+ }
+ // Further link types may be defined later.
+
+ // The checksum field is filled with this while the checksum is computed.
+ extern const char *kCheckSumBlanks;// = " "; // 8 blanks, no null
+
+ extern const char *kLongLink; // = "././@LongLink";
+ extern const char *kLongLink2; // = "@LongLink";
+
+ // The magic field is filled with this if uname and gname are valid.
+ namespace NMagic
+ {
+ 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
+ }
+
+}
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Tar/TarIn.cpp b/CPP/7zip/Archive/Tar/TarIn.cpp
new file mode 100755
index 00000000..86afc482
--- /dev/null
+++ b/CPP/7zip/Archive/Tar/TarIn.cpp
@@ -0,0 +1,248 @@
+// Archive/TarIn.cpp
+
+#include "StdAfx.h"
+
+#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(ReadStream(m_Stream, data, size, &processedSize));
+ m_Position += processedSize;
+ return S_OK;
+}
+
+HRESULT CInArchive::Open(IInStream *inStream)
+{
+ RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position));
+ m_Stream = inStream;
+ return S_OK;
+}
+
+static void MyStrNCpy(char *dest, const char *src, int size)
+{
+ for (int i = 0; i < size; i++)
+ {
+ char c = src[i];
+ dest[i] = c;
+ if (c == 0)
+ break;
+ }
+}
+
+static bool OctalToNumber(const char *srcString, int size, UInt64 &res)
+{
+ char sz[32];
+ MyStrNCpy(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 OctalToNumber32(const char *srcString, int size, UInt32 &res)
+{
+ UInt64 res64;
+ if (!OctalToNumber(srcString, size, res64))
+ return false;
+ res = (UInt32)res64;
+ return (res64 <= 0xFFFFFFFF);
+}
+
+#define RIF(x) { if (!(x)) return S_FALSE; }
+
+static bool IsRecordLast(const char *record)
+{
+ for (int i = 0; i < NFileHeader::kRecordSize; i++)
+ if (record[i] != 0)
+ return false;
+ return true;
+}
+
+static void ReadString(const char *s, int size, AString &result)
+{
+ if (size > NFileHeader::kRecordSize)
+ size = NFileHeader::kNameSize;
+ char tempString[NFileHeader::kRecordSize + 1];
+ MyStrNCpy(tempString, s, size);
+ tempString[size] = '\0';
+ result = tempString;
+}
+
+static char GetHex(Byte value)
+{
+ return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
+}
+
+HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item)
+{
+ item.LongLinkSize = 0;
+ // NFileHeader::CRecord record;
+ char record[NFileHeader::kRecordSize];
+ char *cur = record;
+
+ filled = false;
+
+ UInt32 processedSize;
+ item.HeaderPosition = m_Position;
+ RINOK(ReadBytes(record, NFileHeader::kRecordSize, processedSize));
+ if (processedSize == 0 ||
+ (processedSize == NFileHeader::kRecordSize && IsRecordLast(record)))
+ return S_OK;
+ if (processedSize < NFileHeader::kRecordSize)
+ return S_FALSE;
+
+ // NFileHeader::CHeader &header = record.Header;
+
+ AString name;
+ ReadString(cur, NFileHeader::kNameSize, name);
+ cur += NFileHeader::kNameSize;
+
+ item.Name.Empty();
+ int i;
+ for (i = 0; i < name.Length(); i++)
+ {
+ char c = name[i];
+ if (((Byte)c) < 0x08)
+ {
+ return S_FALSE;
+ }
+ if (((Byte)c) < 0x20)
+ {
+ item.Name += '[';
+ item.Name += GetHex((Byte)(((Byte)c) >> 4));
+ item.Name += GetHex((Byte)(((Byte)c) & 0xF));
+ item.Name += ']';
+ }
+ else
+ item.Name += c;
+ }
+
+ RIF(OctalToNumber32(cur, 8, item.Mode));
+ cur += 8;
+
+ if (!OctalToNumber32(cur, 8, item.UID))
+ item.UID = 0;
+ cur += 8;
+
+ if (!OctalToNumber32(cur, 8, item.GID))
+ item.GID = 0;
+ cur += 8;
+
+ RIF(OctalToNumber(cur, 12, item.Size));
+ cur += 12;
+
+ RIF(OctalToNumber32(cur, 12, item.ModificationTime));
+ cur += 12;
+
+ UInt32 checkSum;
+ RIF(OctalToNumber32(cur, 8, checkSum));
+ memmove(cur, NFileHeader::kCheckSumBlanks, 8);
+ cur += 8;
+
+ item.LinkFlag = *cur++;
+
+ ReadString(cur, NFileHeader::kNameSize, item.LinkName);
+ cur += NFileHeader::kNameSize;
+
+ memmove(item.Magic, cur, 8);
+ cur += 8;
+
+ ReadString(cur, NFileHeader::kUserNameSize, item.UserName);
+ cur += NFileHeader::kUserNameSize;
+ ReadString(cur, NFileHeader::kUserNameSize, item.GroupName);
+ cur += NFileHeader::kUserNameSize;
+
+ item.DeviceMajorDefined = (cur[0] != 0);
+ RIF(OctalToNumber32(cur, 8, item.DeviceMajor));
+ cur += 8;
+
+ item.DeviceMinorDefined = (cur[0] != 0);
+ 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;
+
+
+ UInt32 checkSumReal = 0;
+ for(i = 0; i < NFileHeader::kRecordSize; i++)
+ checkSumReal += Byte(record[i]);
+
+ if (checkSumReal != checkSum)
+ return S_FALSE;
+
+ filled = true;
+ return S_OK;
+}
+
+HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
+{
+ RINOK(GetNextItemReal(filled, item));
+ if (!filled)
+ return S_OK;
+ // GNUtar extension
+ if (item.LinkFlag == 'L')
+ {
+ if (item.Name.Compare(NFileHeader::kLongLink) != 0)
+ if (item.Name.Compare(NFileHeader::kLongLink2) != 0)
+ return S_FALSE;
+ UInt64 headerPosition = item.HeaderPosition;
+
+ UInt32 processedSize;
+ AString fullName;
+ char *buffer = fullName.GetBuffer((UInt32)item.Size + 1);
+ RINOK(ReadBytes(buffer, (UInt32)item.Size, processedSize));
+ buffer[item.Size] = '\0';
+ fullName.ReleaseBuffer();
+ if (processedSize != item.Size)
+ return S_FALSE;
+ RINOK(Skeep((0 - item.Size) & 0x1FF));
+ RINOK(GetNextItemReal(filled, item));
+ item.Name = fullName;
+ item.LongLinkSize = item.HeaderPosition - headerPosition;
+ item.HeaderPosition = headerPosition;
+ }
+ else if (item.LinkFlag == 'g' || item.LinkFlag == 'x')
+ {
+ // pax Extended Header
+ return S_OK;
+ }
+ else if (item.LinkFlag > '7' || (item.LinkFlag < '0' && item.LinkFlag != 0))
+ return S_FALSE;
+ return S_OK;
+}
+
+HRESULT CInArchive::Skeep(UInt64 numBytes)
+{
+ UInt64 newPostion;
+ RINOK(m_Stream->Seek(numBytes, STREAM_SEEK_CUR, &newPostion));
+ m_Position += numBytes;
+ if (m_Position != newPostion)
+ return E_FAIL;
+ return S_OK;
+}
+
+
+HRESULT CInArchive::SkeepDataRecords(UInt64 dataSize)
+{
+ return Skeep((dataSize + 0x1FF) & (~((UInt64)0x1FF)));
+}
+
+}}
diff --git a/CPP/7zip/Archive/Tar/TarIn.h b/CPP/7zip/Archive/Tar/TarIn.h
new file mode 100755
index 00000000..28781375
--- /dev/null
+++ b/CPP/7zip/Archive/Tar/TarIn.h
@@ -0,0 +1,30 @@
+// Archive/TarIn.h
+
+#ifndef __ARCHIVE_TAR_IN_H
+#define __ARCHIVE_TAR_IN_H
+
+#include "Common/MyCom.h"
+#include "../../IStream.h"
+
+#include "TarItem.h"
+
+namespace NArchive {
+namespace NTar {
+
+class CInArchive
+{
+ CMyComPtr<IInStream> m_Stream;
+ UInt64 m_Position;
+
+ HRESULT ReadBytes(void *data, UInt32 size, UInt32 &processedSize);
+public:
+ HRESULT Open(IInStream *inStream);
+ HRESULT GetNextItemReal(bool &filled, CItemEx &itemInfo);
+ HRESULT GetNextItem(bool &filled, CItemEx &itemInfo);
+ HRESULT Skeep(UInt64 numBytes);
+ HRESULT SkeepDataRecords(UInt64 dataSize);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Tar/TarItem.h b/CPP/7zip/Archive/Tar/TarItem.h
new file mode 100755
index 00000000..71fff7ba
--- /dev/null
+++ b/CPP/7zip/Archive/Tar/TarItem.h
@@ -0,0 +1,69 @@
+// Archive/Tar/Item.h
+
+#ifndef __ARCHIVE_TAR_ITEM_H
+#define __ARCHIVE_TAR_ITEM_H
+
+#include <time.h>
+
+#include "Common/Types.h"
+#include "Common/String.h"
+
+#include "../Common/ItemNameUtils.h"
+#include "TarHeader.h"
+
+namespace NArchive {
+namespace NTar {
+
+class CItem
+{
+public:
+ AString Name;
+ UInt32 Mode;
+ UInt32 UID;
+ UInt32 GID;
+ UInt64 Size;
+ UInt32 ModificationTime;
+ char LinkFlag;
+ AString LinkName;
+ char Magic[8];
+ AString UserName;
+ AString GroupName;
+
+ bool DeviceMajorDefined;
+ UInt32 DeviceMajor;
+ bool DeviceMinorDefined;
+ UInt32 DeviceMinor;
+
+ bool IsDirectory() const
+ {
+ if (LinkFlag == NFileHeader::NLinkFlag::kDirectory)
+ return true;
+ if (LinkFlag == NFileHeader::NLinkFlag::kOldNormal ||
+ LinkFlag == NFileHeader::NLinkFlag::kNormal)
+ {
+ return NItemName::HasTailSlash(Name, CP_OEMCP);
+ }
+ 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
+{
+public:
+ UInt64 HeaderPosition;
+ UInt64 LongLinkSize;
+ UInt64 GetDataPosition() const { return HeaderPosition + LongLinkSize + NFileHeader::kRecordSize; };
+ UInt64 GetFullSize() const { return LongLinkSize + NFileHeader::kRecordSize + Size; };
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Tar/TarOut.cpp b/CPP/7zip/Archive/Tar/TarOut.cpp
new file mode 100755
index 00000000..e278edda
--- /dev/null
+++ b/CPP/7zip/Archive/Tar/TarOut.cpp
@@ -0,0 +1,191 @@
+// Archive/TarOut.cpp
+
+#include "StdAfx.h"
+
+#include "TarOut.h"
+#include "TarHeader.h"
+
+#include "Common/IntToString.h"
+#include "Windows/Defs.h"
+#include "../../Common/StreamUtils.h"
+
+namespace NArchive {
+namespace NTar {
+
+HRESULT COutArchive::WriteBytes(const void *buffer, UInt32 size)
+{
+ UInt32 processedSize;
+ RINOK(WriteStream(m_Stream, buffer, size, &processedSize));
+ if(processedSize != size)
+ return E_FAIL;
+ return S_OK;
+}
+
+void COutArchive::Create(ISequentialOutStream *outStream)
+{
+ m_Stream = outStream;
+}
+
+static AString MakeOctalString(UInt64 value)
+{
+ char s[32];
+ ConvertUInt64ToString(value, s, 8);
+ return AString(s) + ' ';
+}
+
+static void MyStrNCpy(char *dest, const char *src, int size)
+{
+ for (int i = 0; i < size; i++)
+ {
+ char c = src[i];
+ dest[i] = c;
+ if (c == 0)
+ break;
+ }
+}
+
+static bool MakeOctalString8(char *s, UInt32 value)
+{
+ AString tempString = MakeOctalString(value);
+
+ const int kMaxSize = 8;
+ if (tempString.Length() >= kMaxSize)
+ return false;
+ int numSpaces = kMaxSize - (tempString.Length() + 1);
+ for(int i = 0; i < numSpaces; i++)
+ s[i] = ' ';
+ MyStringCopy(s + numSpaces, (const char *)tempString);
+ return true;
+}
+
+static bool MakeOctalString12(char *s, UInt64 value)
+{
+ AString tempString = MakeOctalString(value);
+ const int kMaxSize = 12;
+ if (tempString.Length() > kMaxSize)
+ return false;
+ int numSpaces = kMaxSize - tempString.Length();
+ for(int i = 0; i < numSpaces; i++)
+ s[i] = ' ';
+ memmove(s + numSpaces, (const char *)tempString, tempString.Length());
+ return true;
+}
+
+static bool CopyString(char *dest, const AString &src, int maxSize)
+{
+ if (src.Length() >= maxSize)
+ return false;
+ MyStringCopy(dest, (const char *)src);
+ return true;
+}
+
+#define RETURN_IF_NOT_TRUE(x) { if (!(x)) return E_FAIL; }
+
+HRESULT COutArchive::WriteHeaderReal(const CItem &item)
+{
+ char record[NFileHeader::kRecordSize];
+ char *cur = record;
+ int i;
+ for (i = 0; i < NFileHeader::kRecordSize; i++)
+ record[i] = 0;
+
+ // RETURN_IF_NOT_TRUE(CopyString(header.Name, item.Name, NFileHeader::kNameSize));
+ if (item.Name.Length() > NFileHeader::kNameSize)
+ return E_FAIL;
+ MyStrNCpy(cur, item.Name, NFileHeader::kNameSize);
+ cur += NFileHeader::kNameSize;
+
+ RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.Mode));
+ cur += 8;
+ RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.UID));
+ cur += 8;
+ RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.GID));
+ cur += 8;
+
+ RETURN_IF_NOT_TRUE(MakeOctalString12(cur, item.Size));
+ cur += 12;
+ RETURN_IF_NOT_TRUE(MakeOctalString12(cur, item.ModificationTime));
+ cur += 12;
+
+ memmove(cur, NFileHeader::kCheckSumBlanks, 8);
+ cur += 8;
+
+ *cur++ = item.LinkFlag;
+
+ RETURN_IF_NOT_TRUE(CopyString(cur, item.LinkName, NFileHeader::kNameSize));
+ cur += NFileHeader::kNameSize;
+
+ memmove(cur, item.Magic, 8);
+ cur += 8;
+
+ RETURN_IF_NOT_TRUE(CopyString(cur, item.UserName, NFileHeader::kUserNameSize));
+ cur += NFileHeader::kUserNameSize;
+ RETURN_IF_NOT_TRUE(CopyString(cur, item.GroupName, NFileHeader::kGroupNameSize));
+ cur += NFileHeader::kUserNameSize;
+
+
+ if (item.DeviceMajorDefined)
+ RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.DeviceMajor));
+ cur += 8;
+
+ if (item.DeviceMinorDefined)
+ RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.DeviceMinor));
+ cur += 8;
+
+
+ UInt32 checkSumReal = 0;
+ for(i = 0; i < NFileHeader::kRecordSize; i++)
+ checkSumReal += Byte(record[i]);
+
+ RETURN_IF_NOT_TRUE(MakeOctalString8(record + 148, checkSumReal));
+
+ return WriteBytes(record, NFileHeader::kRecordSize);
+}
+
+HRESULT COutArchive::WriteHeader(const CItem &item)
+{
+ int nameSize = item.Name.Length();
+ if (nameSize < NFileHeader::kNameSize)
+ return WriteHeaderReal(item);
+
+ CItem modifiedItem = item;
+ int nameStreamSize = nameSize + 1;
+ modifiedItem.Size = nameStreamSize;
+ modifiedItem.LinkFlag = 'L';
+ modifiedItem.Name = NFileHeader::kLongLink;
+ modifiedItem.LinkName.Empty();
+ RINOK(WriteHeaderReal(modifiedItem));
+ RINOK(WriteBytes(item.Name, nameStreamSize));
+ RINOK(FillDataResidual(nameStreamSize));
+
+ modifiedItem = item;
+ modifiedItem.Name = item.Name.Left(NFileHeader::kNameSize - 1);
+ return WriteHeaderReal(modifiedItem);
+}
+
+HRESULT COutArchive::FillDataResidual(UInt64 dataSize)
+{
+ UInt32 lastRecordSize = UInt32(dataSize & (NFileHeader::kRecordSize - 1));
+ if (lastRecordSize == 0)
+ return S_OK;
+ UInt32 residualSize = NFileHeader::kRecordSize - lastRecordSize;
+ Byte residualBytes[NFileHeader::kRecordSize];
+ for (UInt32 i = 0; i < residualSize; i++)
+ residualBytes[i] = 0;
+ return WriteBytes(residualBytes, residualSize);
+}
+
+HRESULT COutArchive::WriteFinishHeader()
+{
+ Byte record[NFileHeader::kRecordSize];
+ int i;
+ for (i = 0; i < NFileHeader::kRecordSize; i++)
+ record[i] = 0;
+ for (i = 0; i < 2; i++)
+ {
+ RINOK(WriteBytes(record, NFileHeader::kRecordSize));
+ }
+ return S_OK;
+}
+
+}}
diff --git a/CPP/7zip/Archive/Tar/TarOut.h b/CPP/7zip/Archive/Tar/TarOut.h
new file mode 100755
index 00000000..ef837869
--- /dev/null
+++ b/CPP/7zip/Archive/Tar/TarOut.h
@@ -0,0 +1,28 @@
+// Archive/TarOut.h
+
+#ifndef __ARCHIVE_TAR_OUT_H
+#define __ARCHIVE_TAR_OUT_H
+
+#include "TarItem.h"
+
+#include "Common/MyCom.h"
+#include "../../IStream.h"
+
+namespace NArchive {
+namespace NTar {
+
+class COutArchive
+{
+ CMyComPtr<ISequentialOutStream> m_Stream;
+ HRESULT WriteBytes(const void *buffer, UInt32 size);
+public:
+ void Create(ISequentialOutStream *outStream);
+ HRESULT WriteHeaderReal(const CItem &item);
+ HRESULT WriteHeader(const CItem &item);
+ HRESULT FillDataResidual(UInt64 dataSize);
+ HRESULT WriteFinishHeader();
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Tar/TarUpdate.cpp b/CPP/7zip/Archive/Tar/TarUpdate.cpp
new file mode 100755
index 00000000..9a6f64e2
--- /dev/null
+++ b/CPP/7zip/Archive/Tar/TarUpdate.cpp
@@ -0,0 +1,162 @@
+// TarUpdate.cpp
+
+#include "StdAfx.h"
+
+#include "Common/Defs.h"
+#include "Common/StringConvert.h"
+#include "Windows/Defs.h"
+
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/LimitedStreams.h"
+#include "../../Compress/Copy/CopyCoder.h"
+
+#include "TarOut.h"
+#include "TarUpdate.h"
+
+static const UInt64 kOneItemComplexity = 512;
+
+namespace NArchive {
+namespace NTar {
+
+static HRESULT CopyBlock(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, ICompressProgressInfo *progress,
+ UInt64 *totalSize = NULL)
+{
+ NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
+ CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
+ HRESULT result = copyCoder->Code(inStream, outStream, NULL, NULL, progress);
+ if (totalSize != NULL)
+ *totalSize = copyCoderSpec->TotalSize;
+ return result;
+}
+
+HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
+ const CObjectVector<NArchive::NTar::CItemEx> &inputItems,
+ const CObjectVector<CUpdateItemInfo> &updateItems,
+ IArchiveUpdateCallback *updateCallback)
+{
+ COutArchive outArchive;
+ outArchive.Create(outStream);
+
+ UInt64 complexity = 0;
+
+ int i;
+ for(i = 0; i < updateItems.Size(); i++)
+ {
+ const CUpdateItemInfo &updateItem = updateItems[i];
+ if (updateItem.NewData)
+ complexity += updateItem.Size;
+ else
+ complexity += inputItems[updateItem.IndexInArchive].GetFullSize();
+ complexity += kOneItemComplexity;
+ }
+
+ RINOK(updateCallback->SetTotal(complexity));
+
+ complexity = 0;
+
+ for(i = 0; i < updateItems.Size(); i++)
+ {
+ RINOK(updateCallback->SetCompleted(&complexity));
+
+ CLocalProgress *localProgressSpec = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
+ localProgressSpec->Init(updateCallback, true);
+
+ CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
+ CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
+
+ localCompressProgressSpec->Init(localProgress, &complexity, NULL);
+
+ const CUpdateItemInfo &updateItem = updateItems[i];
+ CItem item;
+ if (updateItem.NewProperties)
+ {
+ item.Mode = 0777;
+ item.Name = (updateItem.Name);
+ if (updateItem.IsDirectory)
+ {
+ item.LinkFlag = NFileHeader::NLinkFlag::kDirectory;
+ item.Size = 0;
+ }
+ else
+ {
+ item.LinkFlag = NFileHeader::NLinkFlag::kNormal;
+ item.Size = updateItem.Size;
+ }
+ item.ModificationTime = updateItem.Time;
+ item.DeviceMajorDefined = false;
+ item.DeviceMinorDefined = false;
+ item.UID = 0;
+ item.GID = 0;
+ memmove(item.Magic, NFileHeader::NMagic::kEmpty, 8);
+ }
+ else
+ {
+ const CItemEx &existItemInfo = inputItems[updateItem.IndexInArchive];
+ item = existItemInfo;
+ }
+ if (updateItem.NewData)
+ {
+ item.Size = updateItem.Size;
+ if (item.Size == UInt64(Int64(-1)))
+ return E_INVALIDARG;
+ }
+ else
+ {
+ const CItemEx &existItemInfo = inputItems[updateItem.IndexInArchive];
+ item.Size = existItemInfo.Size;
+ }
+
+ if (updateItem.NewData)
+ {
+ CMyComPtr<ISequentialInStream> fileInStream;
+ HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream);
+ if (res != S_FALSE)
+ {
+ RINOK(res);
+ RINOK(outArchive.WriteHeader(item));
+ if (!updateItem.IsDirectory)
+ {
+ UInt64 totalSize;
+ RINOK(CopyBlock(fileInStream, outStream, compressProgress, &totalSize));
+ if (totalSize != item.Size)
+ return E_FAIL;
+ RINOK(outArchive.FillDataResidual(item.Size));
+ }
+ }
+ complexity += updateItem.Size;
+ RINOK(updateCallback->SetOperationResult(
+ NArchive::NUpdate::NOperationResult::kOK));
+ }
+ else
+ {
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+ CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);
+ const CItemEx &existItemInfo = inputItems[updateItem.IndexInArchive];
+ if (updateItem.NewProperties)
+ {
+ RINOK(outArchive.WriteHeader(item));
+ RINOK(inStream->Seek(existItemInfo.GetDataPosition(),
+ STREAM_SEEK_SET, NULL));
+ streamSpec->SetStream(inStream);
+ streamSpec->Init(existItemInfo.Size);
+ }
+ else
+ {
+ RINOK(inStream->Seek(existItemInfo.HeaderPosition,
+ STREAM_SEEK_SET, NULL));
+ streamSpec->SetStream(inStream);
+ streamSpec->Init(existItemInfo.GetFullSize());
+ }
+ RINOK(CopyBlock(inStreamLimited, outStream, compressProgress));
+ RINOK(outArchive.FillDataResidual(existItemInfo.Size));
+ complexity += existItemInfo.GetFullSize();
+ }
+ complexity += kOneItemComplexity;
+ }
+ return outArchive.WriteFinishHeader();
+}
+
+}}
+
diff --git a/CPP/7zip/Archive/Tar/TarUpdate.h b/CPP/7zip/Archive/Tar/TarUpdate.h
new file mode 100755
index 00000000..92f5cebb
--- /dev/null
+++ b/CPP/7zip/Archive/Tar/TarUpdate.h
@@ -0,0 +1,36 @@
+// Tar/Update.h
+
+#ifndef __TAR_UPDATE_H
+#define __TAR_UPDATE_H
+
+#include "Common/Vector.h"
+#include "Common/Types.h"
+#include "Common/String.h"
+
+#include "../IArchive.h"
+#include "TarItem.h"
+
+namespace NArchive {
+namespace NTar {
+
+struct CUpdateItemInfo
+{
+ bool NewData;
+ bool NewProperties;
+ int IndexInArchive;
+ int IndexInClient;
+
+ UInt32 Time;
+ UInt64 Size;
+ AString Name;
+ bool IsDirectory;
+};
+
+HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
+ const CObjectVector<CItemEx> &inputItems,
+ const CObjectVector<CUpdateItemInfo> &updateItems,
+ IArchiveUpdateCallback *updateCallback);
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Tar/makefile b/CPP/7zip/Archive/Tar/makefile
new file mode 100755
index 00000000..f892c303
--- /dev/null
+++ b/CPP/7zip/Archive/Tar/makefile
@@ -0,0 +1,59 @@
+PROG = tar.dll
+DEF_FILE = ../Archive.def
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib user32.lib
+
+TAR_OBJS = \
+ $O\DllExports.obj \
+ $O\TarHandler.obj \
+ $O\TarHandlerOut.obj \
+ $O\TarHeader.obj \
+ $O\TarIn.obj \
+ $O\TarOut.obj \
+ $O\TarUpdate.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\IntToString.obj \
+ $O\NewHandler.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\Vector.obj \
+
+WIN_OBJS = \
+ $O\PropVariant.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\LimitedStreams.obj \
+ $O\ProgressUtils.obj \
+ $O\StreamUtils.obj \
+
+AR_COMMON_OBJS = \
+ $O\ItemNameUtils.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(TAR_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $(COMPRESS_TAR_OBJS) \
+ $O\CopyCoder.obj \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(TAR_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)
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/Archive/Tar/resource.rc b/CPP/7zip/Archive/Tar/resource.rc
new file mode 100755
index 00000000..3d37f440
--- /dev/null
+++ b/CPP/7zip/Archive/Tar/resource.rc
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("Tar Plugin", "tar")
+
+101 ICON "tar.ico"
diff --git a/CPP/7zip/Archive/Tar/tar.ico b/CPP/7zip/Archive/Tar/tar.ico
new file mode 100755
index 00000000..6835885b
--- /dev/null
+++ b/CPP/7zip/Archive/Tar/tar.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Z/DllExports.cpp b/CPP/7zip/Archive/Z/DllExports.cpp
new file mode 100755
index 00000000..b8df85f4
--- /dev/null
+++ b/CPP/7zip/Archive/Z/DllExports.cpp
@@ -0,0 +1,91 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+#include "ZHandler.h"
+#include "../../ICoder.h"
+
+// {23170F69-40C1-278A-1000-000110050000}
+DEFINE_GUID(CLSID_CZHandler,
+0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 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_CZHandler)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ int needIn = *interfaceID == IID_IInArchive;
+ int needOut = *interfaceID == IID_IOutArchive;
+ if (needIn || needOut)
+ {
+ NArchive::NZ::CHandler *temp = new NArchive::NZ::CHandler;
+ if (needIn)
+ {
+ CMyComPtr<IInArchive> inArchive = (IInArchive *)temp;
+ *outObject = inArchive.Detach();
+ }
+ else
+ {
+ CMyComPtr<IOutArchive> outArchive = (IOutArchive *)temp;
+ *outObject = outArchive.Detach();
+ }
+ }
+ else
+ return E_NOINTERFACE;
+ COM_TRY_END
+ return S_OK;
+}
+
+
+STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
+{
+ NWindows::NCOM::CPropVariant propVariant;
+ switch(propID)
+ {
+ case NArchive::kName:
+ propVariant = L"Z";
+ break;
+ case NArchive::kClassID:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CZHandler, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NArchive::kExtension:
+ propVariant = L"z taz";
+ break;
+ case NArchive::kAddExtension:
+ propVariant = L"* .tar";
+ break;
+ case NArchive::kUpdate:
+ propVariant = false;
+ break;
+ case NArchive::kKeepName:
+ propVariant = true;
+ break;
+ case NArchive::kStartSignature:
+ {
+ const unsigned char sig[] = { 0x1F, 0x9D };
+ if ((value->bstrVal = ::SysAllocStringByteLen((const char *)sig, 2)) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/CPP/7zip/Archive/Z/StdAfx.cpp b/CPP/7zip/Archive/Z/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Archive/Z/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Archive/Z/StdAfx.h b/CPP/7zip/Archive/Z/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Archive/Z/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Archive/Z/Z.dsp b/CPP/7zip/Archive/Z/Z.dsp
new file mode 100755
index 00000000..e1f72522
--- /dev/null
+++ b/CPP/7zip/Archive/Z/Z.dsp
@@ -0,0 +1,237 @@
+# Microsoft Developer Studio Project File - Name="Z" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=Z - 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 "Z.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 "Z.mak" CFG="Z - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Z - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Z - 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)" == "Z - 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 "BZIP2_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_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\z.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Z - 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 "BZIP2_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 "BZIP2_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\z.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "Z - Win32 Release"
+# Name "Z - 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
+# Begin Source File
+
+SOURCE=.\Z.ico
+# 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\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.h
+# End Source File
+# 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 "Compression"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Z\ZDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Z\ZDecoder.h
+# End Source File
+# End Group
+# Begin Group "Archive Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Common\DummyOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\DummyOutStream.h
+# End Source File
+# End Group
+# Begin Group "Engine"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\ZHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ZHandler.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\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 Source File
+
+SOURCE=.\z.ico
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/Archive/Z/Z.dsw b/CPP/7zip/Archive/Z/Z.dsw
new file mode 100755
index 00000000..1f67186a
--- /dev/null
+++ b/CPP/7zip/Archive/Z/Z.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Z"=.\Z.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Archive/Z/Z.ico b/CPP/7zip/Archive/Z/Z.ico
new file mode 100755
index 00000000..2db53583
--- /dev/null
+++ b/CPP/7zip/Archive/Z/Z.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Z/ZHandler.cpp b/CPP/7zip/Archive/Z/ZHandler.cpp
new file mode 100755
index 00000000..33887690
--- /dev/null
+++ b/CPP/7zip/Archive/Z/ZHandler.cpp
@@ -0,0 +1,202 @@
+// ZHandler.cpp
+
+#include "StdAfx.h"
+
+#include "ZHandler.h"
+
+#include "Common/Defs.h"
+
+#include "../../Common/ProgressUtils.h"
+#include "../../Compress/Z/ZDecoder.h"
+#include "../../Common/StreamUtils.h"
+
+#include "Windows/PropVariant.h"
+#include "Windows/Defs.h"
+#include "Common/ComTry.h"
+
+#include "../Common/DummyOutStream.h"
+
+namespace NArchive {
+namespace NZ {
+
+STATPROPSTG kProperties[] =
+{
+ { NULL, kpidPath, VT_BSTR},
+ { NULL, kpidPackedSize, VT_UI8},
+};
+
+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;
+ *name = 0;
+ 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::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = 1;
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant propVariant;
+ if (index != 0)
+ return E_INVALIDARG;
+ switch(propID)
+ {
+ case kpidIsFolder:
+ propVariant = false;
+ break;
+ case kpidPackedSize:
+ propVariant = _packSize;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+static const int kSignatureSize = 3;
+
+STDMETHODIMP CHandler::Open(IInStream *stream,
+ const UInt64 * /* maxCheckStartPosition */,
+ IArchiveOpenCallback * /* openArchiveCallback */)
+{
+ COM_TRY_BEGIN
+ try
+ {
+ RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition));
+ Byte buffer[kSignatureSize];
+ UInt32 processedSize;
+ RINOK(ReadStream(stream, buffer, kSignatureSize, &processedSize));
+ if (processedSize != kSignatureSize)
+ return S_FALSE;
+ if (buffer[0] != 0x1F || buffer[1] != 0x9D)
+ return S_FALSE;
+ _properties = buffer[2];
+
+ UInt64 endPosition;
+ RINOK(stream->Seek(0, STREAM_SEEK_END, &endPosition));
+ _packSize = endPosition - _streamStartPosition - kSignatureSize;
+
+ _stream = stream;
+ }
+ catch(...)
+ {
+ return S_FALSE;
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ _stream.Release();
+ return S_OK;
+}
+
+
+STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
+ Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ bool allFilesMode = (numItems == (UInt32)(-1));
+ if (!allFilesMode)
+ {
+ if (numItems == 0)
+ return S_OK;
+ if (numItems != 1)
+ return E_INVALIDARG;
+ if (indices[0] != 0)
+ return E_INVALIDARG;
+ }
+
+ bool testMode = (testModeSpec != 0);
+
+ extractCallback->SetTotal(_packSize);
+
+ UInt64 currentTotalPacked = 0;
+
+ RINOK(extractCallback->SetCompleted(&currentTotalPacked));
+
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ Int32 askMode;
+ askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
+ NArchive::NExtract::NAskMode::kExtract;
+
+ RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
+
+ if(!testMode && !realOutStream)
+ return S_OK;
+
+ extractCallback->PrepareOperation(askMode);
+
+ CDummyOutStream *outStreamSpec = new CDummyOutStream;
+ CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
+ outStreamSpec->Init(realOutStream);
+
+ realOutStream.Release();
+
+ CLocalProgress *localProgressSpec = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
+ localProgressSpec->Init(extractCallback, true);
+
+ RINOK(_stream->Seek(_streamStartPosition + kSignatureSize, STREAM_SEEK_SET, NULL));
+
+ CMyComPtr<ICompressCoder> decoder;
+ NCompress::NZ::CDecoder *decoderSpec = new NCompress::NZ::CDecoder;
+ decoder = decoderSpec;
+
+ HRESULT result = decoderSpec->SetDecoderProperties2(&_properties, 1);
+
+ int opResult;
+ if (result != S_OK)
+ opResult = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
+ else
+ {
+ result = decoder->Code(_stream, outStream, NULL, NULL, progress);
+ outStream.Release();
+ if (result == S_FALSE)
+ opResult = NArchive::NExtract::NOperationResult::kDataError;
+ else if (result == S_OK)
+ opResult = NArchive::NExtract::NOperationResult::kOK;
+ else
+ return result;
+ }
+ RINOK(extractCallback->SetOperationResult(opResult));
+ return S_OK;
+ COM_TRY_END
+}
+
+}}
diff --git a/CPP/7zip/Archive/Z/ZHandler.h b/CPP/7zip/Archive/Z/ZHandler.h
new file mode 100755
index 00000000..7abba29f
--- /dev/null
+++ b/CPP/7zip/Archive/Z/ZHandler.h
@@ -0,0 +1,47 @@
+// ZHandler.h
+
+#ifndef __Z_HANDLER_H
+#define __Z_HANDLER_H
+
+#include "Common/MyCom.h"
+#include "../IArchive.h"
+
+namespace NArchive {
+namespace NZ {
+
+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:
+ CMyComPtr<IInStream> _stream;
+ UInt64 _streamStartPosition;
+ UInt64 _packSize;
+ Byte _properties;
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Z/makefile b/CPP/7zip/Archive/Z/makefile
new file mode 100755
index 00000000..aff4fc42
--- /dev/null
+++ b/CPP/7zip/Archive/Z/makefile
@@ -0,0 +1,52 @@
+PROG = z.dll
+DEF_FILE = ../Archive.def
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib
+
+Z_OBJS = \
+ $O\DllExports.obj \
+ $O\ZHandler.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\NewHandler.obj \
+
+WIN_OBJS = \
+ $O\PropVariant.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\InBuffer.obj \
+ $O\OutBuffer.obj \
+ $O\ProgressUtils.obj \
+ $O\StreamUtils.obj \
+
+AR_COMMON_OBJS = \
+ $O\DummyOutStream.obj \
+
+COMPRESS_Z_OBJS = \
+ $O\ZDecoder.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(Z_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $(COMPRESS_Z_OBJS) \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(Z_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_Z_OBJS): ../../Compress/Z/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/Archive/Z/resource.rc b/CPP/7zip/Archive/Z/resource.rc
new file mode 100755
index 00000000..05a81423
--- /dev/null
+++ b/CPP/7zip/Archive/Z/resource.rc
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("Z Plugin", "z")
+
+101 ICON "Z.ico"
diff --git a/CPP/7zip/Archive/Zip/DllExports.cpp b/CPP/7zip/Archive/Zip/DllExports.cpp
new file mode 100755
index 00000000..da2a15a4
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/DllExports.cpp
@@ -0,0 +1,152 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#include "ZipHandler.h"
+#include "Windows/PropVariant.h"
+#include "../../ICoder.h"
+#include "../../IPassword.h"
+#include "../../Crypto/WzAES/WzAES.h"
+#include "../Common/CodecsPath.h"
+
+// {23170F69-40C1-278B-0401-080000000100}
+DEFINE_GUID(CLSID_CCompressDeflateEncoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00);
+
+// {23170F69-40C1-278B-0401-080000000000}
+DEFINE_GUID(CLSID_CCompressDeflateDecoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+// {23170F69-40C1-278B-0401-090000000100}
+DEFINE_GUID(CLSID_CCompressDeflate64Encoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00);
+
+// {23170F69-40C1-278B-0401-090000000000}
+DEFINE_GUID(CLSID_CCompressDeflate64Decoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+// {23170F69-40C1-278B-0402-020000000100}
+DEFINE_GUID(CLSID_CCompressBZip2Encoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00);
+
+// {23170F69-40C1-278B-0402-020000000000}
+DEFINE_GUID(CLSID_CCompressBZip2Decoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+// {23170F69-40C1-278B-0401-060000000000}
+DEFINE_GUID(CLSID_CCompressImplodeDecoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+// {23170F69-40C1-278B-06F1-0101000000100}
+DEFINE_GUID(CLSID_CCryptoZipEncoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00);
+
+// {23170F69-40C1-278B-06F1-0101000000000}
+DEFINE_GUID(CLSID_CCryptoZipDecoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00);
+
+// {23170F69-40C1-278A-1000-000110010000}
+DEFINE_GUID(CLSID_CZipHandler,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x01, 0x00, 0x00);
+
+HINSTANCE g_hInstance;
+#ifndef _UNICODE
+bool g_IsNT = false;
+static bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+#endif
+
+void GetCryptoFolderPrefix(TCHAR *path)
+{
+ CSysString s = GetCodecsFolderPrefix();
+ lstrcpy(path, s);
+}
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ g_hInstance = hInstance;
+ #ifndef _UNICODE
+ g_IsNT = IsItWindowsNT();
+ #endif
+ }
+ return TRUE;
+}
+
+
+STDAPI CreateObject(
+ const GUID *classID,
+ const GUID *interfaceID,
+ void **outObject)
+{
+ COM_TRY_BEGIN
+ *outObject = 0;
+ if (*classID != CLSID_CZipHandler)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ int needIn = *interfaceID == IID_IInArchive;
+ int needOut = *interfaceID == IID_IOutArchive;
+ if (needIn || needOut)
+ {
+ NArchive::NZip::CHandler *temp = new NArchive::NZip::CHandler;
+ if (needIn)
+ {
+ CMyComPtr<IInArchive> inArchive = (IInArchive *)temp;
+ *outObject = inArchive.Detach();
+ }
+ else
+ {
+ CMyComPtr<IOutArchive> outArchive = (IOutArchive *)temp;
+ *outObject = outArchive.Detach();
+ }
+ }
+ else
+ return E_NOINTERFACE;
+ COM_TRY_END
+ return S_OK;
+}
+
+STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
+{
+ NWindows::NCOM::CPropVariant propVariant;
+ switch(propID)
+ {
+ case NArchive::kName:
+ propVariant = L"Zip";
+ break;
+ case NArchive::kClassID:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CZipHandler, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NArchive::kExtension:
+ propVariant = L"zip jar xpi";
+ break;
+ case NArchive::kUpdate:
+ propVariant = true;
+ break;
+ case NArchive::kKeepName:
+ propVariant = false;
+ break;
+ case NArchive::kStartSignature:
+ {
+ const char sig[] = { 0x50, 0x4B, 0x03, 0x04 };
+ if ((value->bstrVal = ::SysAllocStringByteLen(sig, 4)) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/CPP/7zip/Archive/Zip/StdAfx.cpp b/CPP/7zip/Archive/Zip/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Archive/Zip/StdAfx.h b/CPP/7zip/Archive/Zip/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Archive/Zip/Zip.dsp b/CPP/7zip/Archive/Zip/Zip.dsp
new file mode 100755
index 00000000..2ac27f4f
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/Zip.dsp
@@ -0,0 +1,651 @@
+# Microsoft Developer Studio Project File - Name="Zip" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=Zip - 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 "Zip.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 "Zip.mak" CFG="Zip - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Zip - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Zip - 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)" == "Zip - 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 "ZIP_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZIP_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\zip.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Zip - 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 "ZIP_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 "ZIP_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\zip.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "Zip - Win32 Release"
+# Name "Zip - 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
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\Alloc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Alloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\AutoPtr.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Buffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Random.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Random.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\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\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
+
+SOURCE=..\..\..\Common\Vector.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Thread.h
+# End Source File
+# End Group
+# Begin Group "Archive Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Common\CodecsPath.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CodecsPath.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CoderLoader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CoderLoader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\FilterCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\FilterCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\InStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\InStreamWithCRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ItemNameUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ItemNameUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\OutStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\OutStreamWithCRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ParseProperties.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ParseProperties.h
+# End Source File
+# End Group
+# Begin Group "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\LSBFDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MemBlocks.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MemBlocks.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OffsetStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OffsetStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutMemStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutMemStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressMt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressMt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# End Group
+# Begin Group "Engine"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\ZipAddCommon.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ZipAddCommon.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ZipCompressionMode.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ZipHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ZipHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ZipHandlerOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ZipHeader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ZipHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ZipIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ZipIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ZipItem.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ZipItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ZipItemEx.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ZipOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ZipOut.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ZipUpdate.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ZipUpdate.h
+# End Source File
+# End Group
+# Begin Group "Crypto"
+
+# PROP Default_Filter ""
+# Begin Group "WzAes"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\WzAES\WzAES.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\WzAES\WzAES.h
+# End Source File
+# End Group
+# Begin Group "Hash"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\HmacSha1.cpp
+
+!IF "$(CFG)" == "Zip - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Zip - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\HmacSha1.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\Pbkdf2HmacSha1.cpp
+
+!IF "$(CFG)" == "Zip - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Zip - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\Pbkdf2HmacSha1.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\RandGen.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\RandGen.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\RotateDefs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\Sha1.cpp
+
+!IF "$(CFG)" == "Zip - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Zip - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\Sha1.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\Crypto\Zip\ZipCipher.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Zip\ZipCipher.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Zip\ZipCrypto.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Zip\ZipCrypto.h
+# End Source File
+# End Group
+# Begin Group "7z"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\7z\7zMethodID.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\7z\7zMethodID.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\7z\7zMethods.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\7z\7zMethods.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Group "Shrink"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Shrink\ShrinkDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Shrink\ShrinkDecoder.h
+# End Source File
+# End Group
+# Begin Group "copy"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.h
+# End Source File
+# End Group
+# Begin Group "Implode"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Implode\ImplodeDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Implode\ImplodeDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Implode\ImplodeHuffmanDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Implode\ImplodeHuffmanDecoder.h
+# End Source File
+# End Group
+# 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
+# End Group
+# Begin Source File
+
+SOURCE=.\zip.ico
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/Archive/Zip/Zip.dsw b/CPP/7zip/Archive/Zip/Zip.dsw
new file mode 100755
index 00000000..0a355329
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/Zip.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Zip"=.\Zip.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
new file mode 100755
index 00000000..7eb2787f
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
@@ -0,0 +1,309 @@
+// AddCommon.cpp
+
+#include "StdAfx.h"
+
+#include "Common/CRC.h"
+#include "Windows/PropVariant.h"
+#include "Windows/Defs.h"
+#include "../../ICoder.h"
+#include "../../IPassword.h"
+#include "../Common/InStreamWithCRC.h"
+#include "../7z/7zMethods.h"
+
+#include "ZipAddCommon.h"
+#include "ZipHeader.h"
+
+#ifdef COMPRESS_DEFLATE
+#include "../../Compress/Deflate/DeflateEncoder.h"
+#else
+// {23170F69-40C1-278B-0401-080000000100}
+DEFINE_GUID(CLSID_CCompressDeflateEncoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00);
+#endif
+
+#ifdef COMPRESS_DEFLATE64
+#include "../../Compress/Deflate/DeflateEncoder.h"
+#else
+// {23170F69-40C1-278B-0401-090000000100}
+DEFINE_GUID(CLSID_CCompressDeflate64Encoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00);
+#endif
+
+#ifdef COMPRESS_BZIP2
+#include "../../Compress/BZip2/BZip2Encoder.h"
+#else
+// {23170F69-40C1-278B-0402-020000000100}
+DEFINE_GUID(CLSID_CCompressBZip2Encoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00);
+#endif
+
+
+#ifdef CRYPTO_ZIP
+#include "../../Crypto/Zip/ZipCipher.h"
+#else
+// {23170F69-40C1-278B-06F1-0101000000100}
+DEFINE_GUID(CLSID_CCryptoZipEncoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00);
+#endif
+
+namespace NArchive {
+namespace NZip {
+
+CAddCommon::CAddCommon(const CCompressionMethodMode &options):
+ _options(options),
+ _copyCoderSpec(NULL),
+ _cryptoStreamSpec(0)
+ {}
+
+static HRESULT GetStreamCRC(ISequentialInStream *inStream, UInt32 &resultCRC)
+{
+ CCRC crc;
+ crc.Init();
+ const UInt32 kBufferSize = (1 << 14);
+ Byte buffer[kBufferSize];
+ for (;;)
+ {
+ UInt32 realProcessedSize;
+ RINOK(inStream->Read(buffer, kBufferSize, &realProcessedSize));
+ if(realProcessedSize == 0)
+ {
+ resultCRC = crc.GetDigest();
+ return S_OK;
+ }
+ crc.Update(buffer, realProcessedSize);
+ }
+}
+
+HRESULT CAddCommon::Compress(ISequentialInStream *inStream, IOutStream *outStream,
+ ICompressProgressInfo *progress, CCompressingResult &operationResult)
+{
+ CSequentialInStreamWithCRC *inSecCrcStreamSpec = 0;
+ CInStreamWithCRC *inCrcStreamSpec = 0;
+ CMyComPtr<ISequentialInStream> inCrcStream;
+ {
+ CMyComPtr<IInStream> inStream2;
+ // we don't support stdin, since stream from stdin can require 64-bit size header
+ RINOK(inStream->QueryInterface(IID_IInStream, (void **)&inStream2));
+ if (inStream2)
+ {
+ inCrcStreamSpec = new CInStreamWithCRC;
+ inCrcStream = inCrcStreamSpec;
+ inCrcStreamSpec->SetStream(inStream2);
+ inCrcStreamSpec->Init();
+ }
+ else
+ {
+ inSecCrcStreamSpec = new CSequentialInStreamWithCRC;
+ inCrcStream = inSecCrcStreamSpec;
+ inSecCrcStreamSpec->SetStream(inStream);
+ inSecCrcStreamSpec->Init();
+ }
+ }
+
+ int numTestMethods = _options.MethodSequence.Size();
+ if (numTestMethods > 1 || _options.PasswordIsDefined)
+ {
+ if (inCrcStreamSpec == 0)
+ {
+ if (_options.PasswordIsDefined)
+ return E_NOTIMPL;
+ numTestMethods = 1;
+ }
+ }
+ Byte method = 0;
+ COutStreamReleaser outStreamReleaser;
+ for(int i = 0; i < numTestMethods; i++)
+ {
+ if (inCrcStreamSpec != 0)
+ RINOK(inCrcStreamSpec->Seek(0, STREAM_SEEK_SET, NULL));
+ RINOK(outStream->Seek(0, STREAM_SEEK_SET, NULL));
+ if (_options.PasswordIsDefined)
+ {
+ if (!_cryptoStream)
+ {
+ _cryptoStreamSpec = new CFilterCoder;
+ _cryptoStream = _cryptoStreamSpec;
+ }
+ if (_options.IsAesMode)
+ {
+ _cryptoStreamSpec->Filter = _aesFilter = _filterAesSpec = new NCrypto::NWzAES::CEncoder;
+ _filterAesSpec->SetKeyMode(_options.AesKeyMode);
+ RINOK(_filterAesSpec->CryptoSetPassword(
+ (const Byte *)(const char *)_options.Password, _options.Password.Length()));
+ RINOK(_filterAesSpec->WriteHeader(outStream));
+ }
+ else
+ {
+ _cryptoStreamSpec->Filter = _zipCryptoFilter = _filterSpec = new NCrypto::NZip::CEncoder;
+ RINOK(_filterSpec->CryptoSetPassword(
+ (const Byte *)(const char *)_options.Password, _options.Password.Length()));
+ UInt32 crc = 0;
+ RINOK(GetStreamCRC(inStream, crc));
+ RINOK(inCrcStreamSpec->Seek(0, STREAM_SEEK_SET, NULL));
+ RINOK(_filterSpec->CryptoSetCRC(crc));
+ RINOK(_filterSpec->WriteHeader(outStream));
+ }
+ RINOK(_cryptoStreamSpec->SetOutStream(outStream));
+ outStreamReleaser.FilterCoder = _cryptoStreamSpec;
+ }
+
+ method = _options.MethodSequence[i];
+ switch(method)
+ {
+ case NFileHeader::NCompressionMethod::kStored:
+ {
+ if(_copyCoderSpec == NULL)
+ {
+ _copyCoderSpec = new NCompress::CCopyCoder;
+ _copyCoder = _copyCoderSpec;
+ }
+ CMyComPtr<ISequentialOutStream> outStreamNew;
+ if (_options.PasswordIsDefined)
+ outStreamNew = _cryptoStream;
+ else
+ outStreamNew = outStream;
+ RINOK(_copyCoder->Code(inCrcStream, outStreamNew, NULL, NULL, progress));
+ operationResult.ExtractVersion = NFileHeader::NCompressionMethod::kStoreExtractVersion;
+ break;
+ }
+ default:
+ {
+ if(!_compressEncoder)
+ {
+ // RINOK(m_MatchFinder.CoCreateInstance(CLSID_CMatchFinderBT3));
+ #ifndef COMPRESS_DEFLATE
+ UString methodName;
+ N7z::LoadMethodMap();
+ #endif
+ switch(method)
+ {
+ case NFileHeader::NCompressionMethod::kDeflated:
+ {
+ #ifdef COMPRESS_DEFLATE
+ _compressEncoder = new NCompress::NDeflate::NEncoder::CCOMCoder;
+ #else
+ methodName = L"Deflate";
+ #endif
+ break;
+ }
+ case NFileHeader::NCompressionMethod::kDeflated64:
+ {
+ #ifdef COMPRESS_DEFLATE64
+ _compressEncoder = new NCompress::NDeflate::NEncoder::CCOMCoder64;
+ #else
+ methodName = L"Deflate64";
+ #endif
+ break;
+ }
+ case NFileHeader::NCompressionMethod::kBZip2:
+ {
+ #ifdef COMPRESS_BZIP2
+ _compressEncoder = new NCompress::NBZip2::CEncoder;
+ #else
+ methodName = L"BZip2";
+ #endif
+ break;
+ }
+ }
+ #ifndef COMPRESS_DEFLATE
+ N7z::CMethodInfo2 methodInfo;
+ if (!N7z::GetMethodInfo(methodName, methodInfo))
+ return E_NOTIMPL;
+ RINOK(_compressLib.LoadAndCreateCoder(
+ methodInfo.FilePath, methodInfo.Encoder, &_compressEncoder));
+ #endif
+
+ if (method == NFileHeader::NCompressionMethod::kDeflated ||
+ method == NFileHeader::NCompressionMethod::kDeflated64)
+ {
+ NWindows::NCOM::CPropVariant properties[] =
+ {
+ _options.NumPasses,
+ _options.NumFastBytes,
+ _options.NumMatchFinderCycles
+ };
+ PROPID propIDs[] =
+ {
+ NCoderPropID::kNumPasses,
+ NCoderPropID::kNumFastBytes,
+ NCoderPropID::kMatchFinderCycles
+ };
+ int numProps = sizeof(propIDs) / sizeof(propIDs[0]);
+ if (!_options.NumMatchFinderCyclesDefined)
+ numProps--;
+ CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
+ _compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties);
+ if (setCoderProperties)
+ {
+ RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, numProps));
+ }
+ }
+ else if (method == NFileHeader::NCompressionMethod::kBZip2)
+ {
+ NWindows::NCOM::CPropVariant properties[] =
+ {
+ _options.DicSize,
+ _options.NumPasses
+ #ifdef COMPRESS_MT
+ , _options.NumThreads
+ #endif
+ };
+ PROPID propIDs[] =
+ {
+ NCoderPropID::kDictionarySize,
+ NCoderPropID::kNumPasses
+ #ifdef COMPRESS_MT
+ , NCoderPropID::kNumThreads
+ #endif
+ };
+ CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
+ _compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties);
+ if (setCoderProperties)
+ {
+ RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, sizeof(propIDs) / sizeof(propIDs[0])));
+ }
+ }
+ }
+ CMyComPtr<ISequentialOutStream> outStreamNew;
+ if (_options.PasswordIsDefined)
+ outStreamNew = _cryptoStream;
+ else
+ outStreamNew = outStream;
+ RINOK(_compressEncoder->Code(inCrcStream, outStreamNew, NULL, NULL, progress));
+ operationResult.ExtractVersion = NFileHeader::NCompressionMethod::kDeflateExtractVersion;
+ break;
+ }
+ }
+
+ RINOK(outStream->Seek(0, STREAM_SEEK_CUR, &operationResult.PackSize));
+
+ if (inCrcStreamSpec != 0)
+ {
+ operationResult.CRC = inCrcStreamSpec->GetCRC();
+ operationResult.UnpackSize = inCrcStreamSpec->GetSize();
+ }
+ else
+ {
+ operationResult.CRC = inSecCrcStreamSpec->GetCRC();
+ operationResult.UnpackSize = inSecCrcStreamSpec->GetSize();
+ }
+
+ if (_options.PasswordIsDefined)
+ {
+ if (operationResult.PackSize < operationResult.UnpackSize +
+ (_options.IsAesMode ? _filterAesSpec->GetHeaderSize() : NCrypto::NZip::kHeaderSize))
+ break;
+ }
+ else if (operationResult.PackSize < operationResult.UnpackSize)
+ break;
+ }
+ if (_options.IsAesMode)
+ {
+ RINOK(_filterAesSpec->WriteFooter(outStream));
+ RINOK(outStream->Seek(0, STREAM_SEEK_CUR, &operationResult.PackSize));
+ }
+ operationResult.Method = method;
+ return outStream->SetSize(operationResult.PackSize);
+}
+
+}}
diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.h b/CPP/7zip/Archive/Zip/ZipAddCommon.h
new file mode 100755
index 00000000..26cec643
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/ZipAddCommon.h
@@ -0,0 +1,58 @@
+// Zip/AddCommon.h
+
+#ifndef __ZIP_ADDCOMMON_H
+#define __ZIP_ADDCOMMON_H
+
+#include "../../ICoder.h"
+#include "../../IProgress.h"
+#include "../../Compress/Copy/CopyCoder.h"
+#ifndef COMPRESS_DEFLATE
+#include "../Common/CoderLoader.h"
+#endif
+#include "../Common/FilterCoder.h"
+#include "ZipCompressionMode.h"
+#include "../../Crypto/Zip/ZipCipher.h"
+#include "../../Crypto/WzAES/WzAES.h"
+
+namespace NArchive {
+namespace NZip {
+
+struct CCompressingResult
+{
+ UInt64 UnpackSize;
+ UInt64 PackSize;
+ UInt32 CRC;
+ UInt16 Method;
+ Byte ExtractVersion;
+};
+
+class CAddCommon
+{
+ CCompressionMethodMode _options;
+ NCompress::CCopyCoder *_copyCoderSpec;
+ CMyComPtr<ICompressCoder> _copyCoder;
+
+ #ifndef COMPRESS_DEFLATE
+ CCoderLibrary _compressLib;
+ #endif
+ CMyComPtr<ICompressCoder> _compressEncoder;
+
+ CFilterCoder *_cryptoStreamSpec;
+ CMyComPtr<ISequentialOutStream> _cryptoStream;
+
+ NCrypto::NZip::CEncoder *_filterSpec;
+ NCrypto::NWzAES::CEncoder *_filterAesSpec;
+
+ CMyComPtr<ICompressFilter> _zipCryptoFilter;
+ CMyComPtr<ICompressFilter> _aesFilter;
+
+
+public:
+ CAddCommon(const CCompressionMethodMode &options);
+ HRESULT Compress(ISequentialInStream *inStream, IOutStream *outStream,
+ ICompressProgressInfo *progress, CCompressingResult &operationResult);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Zip/ZipCompressionMode.h b/CPP/7zip/Archive/Zip/ZipCompressionMode.h
new file mode 100755
index 00000000..f1c79918
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/ZipCompressionMode.h
@@ -0,0 +1,39 @@
+// CompressionMode.h
+
+#ifndef __ZIP_COMPRESSIONMETHOD_H
+#define __ZIP_COMPRESSIONMETHOD_H
+
+#include "Common/Vector.h"
+#include "Common/String.h"
+
+namespace NArchive {
+namespace NZip {
+
+struct CCompressionMethodMode
+{
+ CRecordVector<Byte> MethodSequence;
+ // bool MaximizeRatio;
+ UInt32 NumPasses;
+ UInt32 NumFastBytes;
+ bool NumMatchFinderCyclesDefined;
+ UInt32 NumMatchFinderCycles;
+ UInt32 DicSize;
+ #ifdef COMPRESS_MT
+ UInt32 NumThreads;
+ #endif
+ bool PasswordIsDefined;
+ AString Password;
+ bool IsAesMode;
+ Byte AesKeyMode;
+
+ CCompressionMethodMode():
+ NumMatchFinderCyclesDefined(false),
+ PasswordIsDefined(false),
+ IsAesMode(false),
+ AesKeyMode(3)
+ {}
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Zip/ZipHandler.cpp b/CPP/7zip/Archive/Zip/ZipHandler.cpp
new file mode 100755
index 00000000..4672d768
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/ZipHandler.cpp
@@ -0,0 +1,766 @@
+// ZipHandler.cpp
+
+#include "StdAfx.h"
+
+#include "ZipHandler.h"
+
+#include "Common/Defs.h"
+#include "Common/CRC.h"
+#include "Common/StringConvert.h"
+#include "Common/ComTry.h"
+#include "Common/IntToString.h"
+
+#include "Windows/Time.h"
+#include "Windows/PropVariant.h"
+
+#include "../../IPassword.h"
+
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/StreamObjects.h"
+
+#include "../../Compress/Copy/CopyCoder.h"
+
+#include "../Common/ItemNameUtils.h"
+#include "../Common/OutStreamWithCRC.h"
+#include "../Common/FilterCoder.h"
+#include "../7z/7zMethods.h"
+
+#include "../../Compress/Shrink/ShrinkDecoder.h"
+#include "../../Compress/Implode/ImplodeDecoder.h"
+
+#ifdef COMPRESS_DEFLATE
+#include "../../Compress/Deflate/DeflateDecoder.h"
+#else
+// {23170F69-40C1-278B-0401-080000000000}
+DEFINE_GUID(CLSID_CCompressDeflateDecoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00);
+#endif
+
+#ifdef COMPRESS_DEFLATE64
+#include "../../Compress/Deflate/DeflateDecoder.h"
+#else
+// {23170F69-40C1-278B-0401-090000000000}
+DEFINE_GUID(CLSID_CCompressDeflate64Decoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00);
+#endif
+
+/*
+#ifdef COMPRESS_IMPLODE
+#else
+// {23170F69-40C1-278B-0401-060000000000}
+DEFINE_GUID(CLSID_CCompressImplodeDecoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00);
+#endif
+*/
+
+#ifdef COMPRESS_BZIP2
+#include "../../Compress/BZip2/BZip2Decoder.h"
+#else
+// {23170F69-40C1-278B-0402-020000000000}
+DEFINE_GUID(CLSID_CCompressBZip2Decoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
+#endif
+
+#include "../../Crypto/Zip/ZipCipher.h"
+#include "../../Crypto/WzAES/WzAES.h"
+
+#ifndef EXCLUDE_COM
+#include "../Common/CoderLoader.h"
+#endif
+
+using namespace NWindows;
+using namespace NTime;
+
+namespace NArchive {
+namespace NZip {
+
+const wchar_t *kHostOS[] =
+{
+ L"FAT",
+ L"AMIGA",
+ L"VMS",
+ L"Unix",
+ L"VM_CMS",
+ L"Atari", // what if it's a minix filesystem? [cjh]
+ L"HPFS", // filesystem used by OS/2 (and NT 3.x)
+ L"Mac",
+ L"Z_System",
+ L"CPM",
+ L"TOPS20", // pkzip 2.50 NTFS
+ L"NTFS", // filesystem used by Windows NT
+ L"QDOS ", // SMS/QDOS
+ L"Acorn", // Archimedes Acorn RISC OS
+ L"VFAT", // filesystem used by Windows 95, NT
+ L"MVS",
+ L"BeOS", // hybrid POSIX/database filesystem
+ // BeBOX or PowerMac
+ L"Tandem",
+ L"THEOS"
+};
+
+
+static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
+
+static const wchar_t *kUnknownOS = L"Unknown";
+
+
+/*
+enum // PropID
+{
+ kpidUnPackVersion,
+};
+*/
+
+STATPROPSTG kProperties[] =
+{
+ { NULL, kpidPath, VT_BSTR},
+ { NULL, kpidIsFolder, VT_BOOL},
+ { NULL, kpidSize, VT_UI8},
+ { NULL, kpidPackedSize, VT_UI8},
+ { NULL, kpidLastWriteTime, VT_FILETIME},
+ { NULL, kpidAttributes, VT_UI4},
+
+ { NULL, kpidEncrypted, VT_BOOL},
+ { NULL, kpidComment, VT_BSTR},
+
+ { NULL, kpidCRC, VT_UI4},
+
+ { NULL, kpidMethod, VT_BSTR},
+ { NULL, kpidHostOS, VT_BSTR}
+
+ // { L"UnPack Version", kpidUnPackVersion, VT_UI1},
+};
+
+const wchar_t *kMethods[] =
+{
+ L"Store",
+ L"Shrink",
+ L"Reduced1",
+ L"Reduced2",
+ L"Reduced2",
+ L"Reduced3",
+ L"Implode",
+ L"Tokenizing",
+ L"Deflate",
+ L"Deflate64",
+ L"PKImploding",
+ L"Unknown",
+ L"BZip2"
+};
+
+const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]);
+// const wchar_t *kUnknownMethod = L"Unknown";
+const wchar_t *kPPMdMethod = L"PPMd";
+const wchar_t *kAESMethod = L"AES";
+const wchar_t *kZipCryptoMethod = L"ZipCrypto";
+
+CHandler::CHandler():
+ m_ArchiveIsOpen(false)
+{
+ InitMethodProperties();
+}
+
+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;
+ *name = 0;
+ 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_NOTIMPL;
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = m_Items.Size();
+ return S_OK;
+}
+
+static void MyStrNCpy(char *dest, const char *src, int size)
+{
+ for (int i = 0; i < size; i++)
+ {
+ char c = src[i];
+ dest[i] = c;
+ if (c == 0)
+ break;
+ }
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID aPropID, PROPVARIANT *aValue)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant propVariant;
+ const CItemEx &item = m_Items[index];
+ switch(aPropID)
+ {
+ case kpidPath:
+ propVariant = NItemName::GetOSName2(
+ MultiByteToUnicodeString(item.Name, item.GetCodePage()));
+ break;
+ case kpidIsFolder:
+ propVariant = item.IsDirectory();
+ break;
+ case kpidSize:
+ propVariant = item.UnPackSize;
+ break;
+ case kpidPackedSize:
+ propVariant = item.PackSize;
+ break;
+ case kpidLastWriteTime:
+ {
+ FILETIME aLocalFileTime, anUTCFileTime;
+ if (DosTimeToFileTime(item.Time, aLocalFileTime))
+ {
+ if (!LocalFileTimeToFileTime(&aLocalFileTime, &anUTCFileTime))
+ anUTCFileTime.dwHighDateTime = anUTCFileTime.dwLowDateTime = 0;
+ }
+ else
+ anUTCFileTime.dwHighDateTime = anUTCFileTime.dwLowDateTime = 0;
+ propVariant = anUTCFileTime;
+ break;
+ }
+ case kpidAttributes:
+ propVariant = item.GetWinAttributes();
+ break;
+ case kpidEncrypted:
+ propVariant = item.IsEncrypted();
+ break;
+ case kpidComment:
+ {
+ int size = (int)item.Comment.GetCapacity();
+ if (size > 0)
+ {
+ AString s;
+ char *p = s.GetBuffer(size + 1);
+ MyStrNCpy(p, (const char *)(const Byte *)item.Comment, size);
+ p[size] = '\0';
+ s.ReleaseBuffer();
+ propVariant = MultiByteToUnicodeString(s, item.GetCodePage());
+ }
+ break;
+ }
+ case kpidCRC:
+ if (item.IsThereCrc())
+ propVariant = item.FileCRC;
+ break;
+ case kpidMethod:
+ {
+ UInt16 methodId = item.CompressionMethod;
+ UString method;
+ if (item.IsEncrypted())
+ {
+ if (methodId == NFileHeader::NCompressionMethod::kWzAES)
+ {
+ method = kAESMethod;
+ CWzAesExtraField aesField;
+ if (item.CentralExtra.GetWzAesField(aesField))
+ {
+ method += L"-";
+ wchar_t s[32];
+ ConvertUInt64ToString((aesField.Strength + 1) * 64 , s);
+ method += s;
+ method += L" ";
+ methodId = aesField.Method;
+ }
+ }
+ else
+ {
+ method += kZipCryptoMethod;
+ method += L" ";
+ }
+ }
+ if (methodId < kNumMethods)
+ method += kMethods[methodId];
+ else if (methodId == NFileHeader::NCompressionMethod::kWzPPMd)
+ method += kPPMdMethod;
+ else
+ {
+ wchar_t s[32];
+ ConvertUInt64ToString(methodId, s);
+ method += s;
+ }
+ propVariant = method;
+ break;
+ }
+ case kpidHostOS:
+ propVariant = (item.MadeByVersion.HostOS < kNumHostOSes) ?
+ (kHostOS[item.MadeByVersion.HostOS]) : kUnknownOS;
+ break;
+ }
+ propVariant.Detach(aValue);
+ return S_OK;
+ COM_TRY_END
+}
+
+class CPropgressImp: public CProgressVirt
+{
+ CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallback;
+public:
+ STDMETHOD(SetCompleted)(const UInt64 *numFiles);
+ void Init(IArchiveOpenCallback *openArchiveCallback)
+ { m_OpenArchiveCallback = openArchiveCallback; }
+};
+
+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
+ // try
+ {
+ if(!m_Archive.Open(inStream, maxCheckStartPosition))
+ return S_FALSE;
+ m_ArchiveIsOpen = true;
+ m_Items.Clear();
+ if (openArchiveCallback != NULL)
+ {
+ RINOK(openArchiveCallback->SetTotal(NULL, NULL));
+ }
+ CPropgressImp propgressImp;
+ propgressImp.Init(openArchiveCallback);
+ RINOK(m_Archive.ReadHeaders(m_Items, &propgressImp));
+ }
+ /*
+ catch(...)
+ {
+ return S_FALSE;
+ }
+ */
+ COM_TRY_END
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ m_Items.Clear();
+ m_Archive.Close();
+ m_ArchiveIsOpen = false;
+ return S_OK;
+}
+
+//////////////////////////////////////
+// CHandler::DecompressItems
+
+struct CMethodItem
+{
+ UInt16 ZipMethod;
+ CMyComPtr<ICompressCoder> Coder;
+};
+
+class CZipDecoder
+{
+ NCrypto::NZip::CDecoder *_zipCryptoDecoderSpec;
+ NCrypto::NWzAES::CDecoder *_aesDecoderSpec;
+ CMyComPtr<ICompressFilter> _zipCryptoDecoder;
+ CMyComPtr<ICompressFilter> _aesDecoder;
+ CFilterCoder *filterStreamSpec;
+ CMyComPtr<ISequentialInStream> filterStream;
+ CMyComPtr<ICryptoGetTextPassword> getTextPassword;
+ #ifndef EXCLUDE_COM
+ CCoderLibraries libraries;
+ #endif
+ CObjectVector<CMethodItem> methodItems;
+
+public:
+ CZipDecoder(): _zipCryptoDecoderSpec(0), _aesDecoderSpec(0), filterStreamSpec(0) {}
+
+ static void Init()
+ {
+ #ifndef EXCLUDE_COM
+ N7z::LoadMethodMap();
+ #endif
+ }
+
+ HRESULT Decode(CInArchive &archive, const CItemEx &item,
+ ISequentialOutStream *realOutStream,
+ IArchiveExtractCallback *extractCallback,
+ ICompressProgressInfo *compressProgress,
+ UInt32 numThreads, Int32 &res);
+};
+
+HRESULT CZipDecoder::Decode(CInArchive &archive, const CItemEx &item,
+ ISequentialOutStream *realOutStream,
+ IArchiveExtractCallback *extractCallback,
+ ICompressProgressInfo *compressProgress,
+ UInt32 numThreads, Int32 &res)
+{
+ res = NArchive::NExtract::NOperationResult::kDataError;
+ CInStreamReleaser inStreamReleaser;
+
+ bool needCRC = true;
+ bool aesMode = false;
+ UInt16 methodId = item.CompressionMethod;
+ if (item.IsEncrypted())
+ if (methodId == NFileHeader::NCompressionMethod::kWzAES)
+ {
+ CWzAesExtraField aesField;
+ if (item.CentralExtra.GetWzAesField(aesField))
+ {
+ aesMode = true;
+ needCRC = aesField.NeedCrc();
+ }
+ }
+
+ COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;;
+ CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
+ outStreamSpec->SetStream(realOutStream);
+ outStreamSpec->Init(needCRC);
+
+ UInt64 authenticationPos;
+
+ CMyComPtr<ISequentialInStream> inStream;
+ {
+ UInt64 packSize = item.PackSize;
+ if (aesMode)
+ {
+ if (packSize < NCrypto::NWzAES::kMacSize)
+ return S_OK;
+ packSize -= NCrypto::NWzAES::kMacSize;
+ }
+ UInt64 dataPos = item.GetDataPosition();
+ inStream.Attach(archive.CreateLimitedStream(dataPos, packSize));
+ authenticationPos = dataPos + packSize;
+ }
+
+ CMyComPtr<ICompressFilter> cryptoFilter;
+ if (item.IsEncrypted())
+ {
+ if (aesMode)
+ {
+ CWzAesExtraField aesField;
+ if (!item.CentralExtra.GetWzAesField(aesField))
+ return S_OK;
+ methodId = aesField.Method;
+ if (!_aesDecoder)
+ {
+ _aesDecoderSpec = new NCrypto::NWzAES::CDecoder;
+ _aesDecoder = _aesDecoderSpec;
+ }
+ cryptoFilter = _aesDecoder;
+ Byte properties = aesField.Strength;
+ RINOK(_aesDecoderSpec->SetDecoderProperties2(&properties, 1));
+ }
+ else
+ {
+ if (!_zipCryptoDecoder)
+ {
+ _zipCryptoDecoderSpec = new NCrypto::NZip::CDecoder;
+ _zipCryptoDecoder = _zipCryptoDecoderSpec;
+ }
+ cryptoFilter = _zipCryptoDecoder;
+ }
+ CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
+ RINOK(cryptoFilter.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword));
+
+ if (!getTextPassword)
+ extractCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getTextPassword);
+
+ if (getTextPassword)
+ {
+ CMyComBSTR password;
+ RINOK(getTextPassword->CryptoGetTextPassword(&password));
+ AString charPassword;
+ if (aesMode)
+ {
+ charPassword = UnicodeStringToMultiByte((const wchar_t *)password, CP_ACP);
+ /*
+ for (int i = 0;; i++)
+ {
+ wchar_t c = password[i];
+ if (c == 0)
+ break;
+ if (c >= 0x80)
+ {
+ res = NArchive::NExtract::NOperationResult::kDataError;
+ return S_OK;
+ }
+ charPassword += (char)c;
+ }
+ */
+ }
+ else
+ {
+ // we use OEM. WinZip/Windows probably use ANSI for some files
+ charPassword = UnicodeStringToMultiByte((const wchar_t *)password, CP_OEMCP);
+ }
+ HRESULT res = cryptoSetPassword->CryptoSetPassword(
+ (const Byte *)(const char *)charPassword, charPassword.Length());
+ if (res != S_OK)
+ return S_OK;
+ }
+ else
+ {
+ RINOK(cryptoSetPassword->CryptoSetPassword(0, 0));
+ }
+ }
+
+ int m;
+ for (m = 0; m < methodItems.Size(); m++)
+ if (methodItems[m].ZipMethod == methodId)
+ break;
+
+ if (m == methodItems.Size())
+ {
+ CMethodItem mi;
+ mi.ZipMethod = methodId;
+ if (methodId == NFileHeader::NCompressionMethod::kStored)
+ mi.Coder = new NCompress::CCopyCoder;
+ else if (methodId == NFileHeader::NCompressionMethod::kShrunk)
+ mi.Coder = new NCompress::NShrink::CDecoder;
+ else if (methodId == NFileHeader::NCompressionMethod::kImploded)
+ mi.Coder = new NCompress::NImplode::NDecoder::CCoder;
+ else
+ {
+ #ifdef EXCLUDE_COM
+ switch(methodId)
+ {
+ case NFileHeader::NCompressionMethod::kDeflated:
+ mi.Coder = new NCompress::NDeflate::NDecoder::CCOMCoder;
+ break;
+ case NFileHeader::NCompressionMethod::kDeflated64:
+ mi.Coder = new NCompress::NDeflate::NDecoder::CCOMCoder64;
+ break;
+ case NFileHeader::NCompressionMethod::kBZip2:
+ mi.Coder = new NCompress::NBZip2::CDecoder;
+ break;
+ default:
+ res = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
+ return S_OK;
+ }
+ #else
+ N7z::CMethodID methodID = { { 0x04, 0x01 } , 3 };
+ if (methodId > 0xFF)
+ {
+ res = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
+ return S_OK;
+ }
+ methodID.ID[2] = (Byte)methodId;
+ if (methodId == NFileHeader::NCompressionMethod::kStored)
+ {
+ methodID.ID[0] = 0;
+ methodID.IDSize = 1;
+ }
+ else if (methodId == NFileHeader::NCompressionMethod::kBZip2)
+ {
+ methodID.ID[1] = 0x02;
+ methodID.ID[2] = 0x02;
+ }
+
+ N7z::CMethodInfo methodInfo;
+ if (!N7z::GetMethodInfo(methodID, methodInfo))
+ {
+ res = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
+ return S_OK;
+ }
+ RINOK(libraries.CreateCoder(methodInfo.FilePath, methodInfo.Decoder, &mi.Coder));
+ #endif
+ }
+ m = methodItems.Add(mi);
+ }
+ ICompressCoder *coder = methodItems[m].Coder;
+
+ {
+ CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
+ coder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties);
+ if (setDecoderProperties)
+ {
+ Byte properties = (Byte)item.Flags;
+ RINOK(setDecoderProperties->SetDecoderProperties2(&properties, 1));
+ }
+ }
+
+ #ifdef COMPRESS_MT
+ {
+ CMyComPtr<ICompressSetCoderMt> setCoderMt;
+ coder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt);
+ if (setCoderMt)
+ {
+ RINOK(setCoderMt->SetNumberOfThreads(numThreads));
+ }
+ }
+ #endif
+
+ {
+ HRESULT result;
+ CMyComPtr<ISequentialInStream> inStreamNew;
+ if (item.IsEncrypted())
+ {
+ if (!filterStream)
+ {
+ filterStreamSpec = new CFilterCoder;
+ filterStream = filterStreamSpec;
+ }
+ filterStreamSpec->Filter = cryptoFilter;
+ if (aesMode)
+ {
+ RINOK(_aesDecoderSpec->ReadHeader(inStream));
+ }
+ else
+ {
+ RINOK(_zipCryptoDecoderSpec->ReadHeader(inStream));
+ }
+ RINOK(filterStreamSpec->SetInStream(inStream));
+ inStreamReleaser.FilterCoder = filterStreamSpec;
+ inStreamNew = filterStream;
+
+ if (aesMode)
+ {
+ if (!_aesDecoderSpec->CheckPasswordVerifyCode())
+ return S_OK;
+ }
+ }
+ else
+ inStreamNew = inStream;
+ result = coder->Code(inStreamNew, outStream, NULL, &item.UnPackSize, compressProgress);
+ if (result == S_FALSE)
+ return S_OK;
+ RINOK(result);
+ }
+ bool crcOK = true;
+ bool authOk = true;
+ if (needCRC)
+ crcOK = (outStreamSpec->GetCRC() == item.FileCRC);
+ if (aesMode)
+ {
+ inStream.Attach(archive.CreateLimitedStream(authenticationPos, NCrypto::NWzAES::kMacSize));
+ if (_aesDecoderSpec->CheckMac(inStream, authOk) != S_OK)
+ authOk = false;
+ }
+
+ res = ((crcOK && authOk) ?
+ NArchive::NExtract::NOperationResult::kOK :
+ NArchive::NExtract::NOperationResult::kCRCError);
+ return S_OK;
+}
+
+
+STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
+ Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ CZipDecoder myDecoder;
+ bool testMode = (_aTestMode != 0);
+ UInt64 totalUnPacked = 0, totalPacked = 0;
+ bool allFilesMode = (numItems == UInt32(-1));
+ if (allFilesMode)
+ numItems = m_Items.Size();
+ if(numItems == 0)
+ return S_OK;
+ UInt32 i;
+ for(i = 0; i < numItems; i++)
+ {
+ const CItemEx &item = m_Items[allFilesMode ? i : indices[i]];
+ totalUnPacked += item.UnPackSize;
+ totalPacked += item.PackSize;
+ }
+ extractCallback->SetTotal(totalUnPacked);
+
+ UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0;
+ UInt64 currentItemUnPacked, currentItemPacked;
+
+ CLocalProgress *localProgressSpec = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
+ CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
+ CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
+
+ CZipDecoder::Init();
+
+ for (i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked,
+ currentTotalPacked += currentItemPacked)
+ {
+ currentItemUnPacked = 0;
+ currentItemPacked = 0;
+
+ RINOK(extractCallback->SetCompleted(&currentTotalUnPacked));
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ Int32 askMode = testMode ?
+ NArchive::NExtract::NAskMode::kTest :
+ NArchive::NExtract::NAskMode::kExtract;
+ Int32 index = allFilesMode ? i : indices[i];
+
+ RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
+
+ CItemEx item = m_Items[index];
+ if (!item.FromLocal)
+ {
+ HRESULT res = m_Archive.ReadLocalItemAfterCdItem(item);
+ if (res == S_FALSE)
+ {
+ if (item.IsDirectory() || realOutStream || testMode)
+ {
+ RINOK(extractCallback->PrepareOperation(askMode));
+ realOutStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+ }
+ continue;
+ }
+ RINOK(res);
+ }
+
+ if (item.IsDirectory() || item.IgnoreItem())
+ {
+ // if (!testMode)
+ {
+ RINOK(extractCallback->PrepareOperation(askMode));
+ realOutStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ }
+ continue;
+ }
+
+ currentItemUnPacked = item.UnPackSize;
+ currentItemPacked = item.PackSize;
+
+ if (!testMode && (!realOutStream))
+ continue;
+
+ RINOK(extractCallback->PrepareOperation(askMode));
+
+ localProgressSpec->Init(extractCallback, false);
+ localCompressProgressSpec->Init(progress, &currentTotalPacked, &currentTotalUnPacked);
+
+ Int32 res;
+ RINOK(myDecoder.Decode(m_Archive, item, realOutStream, extractCallback,
+ compressProgress, _numThreads, res));
+ realOutStream.Release();
+
+ RINOK(extractCallback->SetOperationResult(res))
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+}}
diff --git a/CPP/7zip/Archive/Zip/ZipHandler.h b/CPP/7zip/Archive/Zip/ZipHandler.h
new file mode 100755
index 00000000..ea6becd0
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/ZipHandler.h
@@ -0,0 +1,100 @@
+// Zip/Handler.h
+
+#ifndef __ZIP_HANDLER_H
+#define __ZIP_HANDLER_H
+
+#include "Common/DynamicBuffer.h"
+#include "../../ICoder.h"
+#include "../IArchive.h"
+
+#include "ZipIn.h"
+#include "ZipCompressionMode.h"
+
+#ifdef COMPRESS_MT
+#include "../../../Windows/System.h"
+#endif
+
+namespace NArchive {
+namespace NZip {
+
+class CHandler:
+ public IInArchive,
+ public IOutArchive,
+ public ISetProperties,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP3(
+ IInArchive,
+ IOutArchive,
+ ISetProperties
+ )
+
+ STDMETHOD(Open)(IInStream *aStream,
+ const UInt64 *aMaxCheckStartPosition,
+ IArchiveOpenCallback *anOpenArchiveCallback);
+ STDMETHOD(Close)();
+ STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
+ STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
+ STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems,
+ Int32 testMode, IArchiveExtractCallback *anExtractCallback);
+
+ 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);
+
+ // IOutArchive
+ STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems,
+ IArchiveUpdateCallback *updateCallback);
+ STDMETHOD(GetFileTimeType)(UInt32 *timeType);
+
+ // ISetProperties
+ STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
+
+ CHandler();
+private:
+ CObjectVector<CItemEx> m_Items;
+ CInArchive m_Archive;
+ bool m_ArchiveIsOpen;
+
+ int m_Level;
+ int m_MainMethod;
+ UInt32 m_DicSize;
+ UInt32 m_NumPasses;
+ UInt32 m_NumFastBytes;
+ UInt32 m_NumMatchFinderCycles;
+ bool m_NumMatchFinderCyclesDefined;
+
+ bool m_IsAesMode;
+ Byte m_AesKeyMode;
+
+ #ifdef COMPRESS_MT
+ UInt32 _numThreads;
+ #endif
+
+ void InitMethodProperties()
+ {
+ m_Level = -1;
+ m_MainMethod = -1;
+ m_DicSize =
+ m_NumPasses =
+ m_NumFastBytes =
+ m_NumMatchFinderCycles = 0xFFFFFFFF;
+ m_NumMatchFinderCyclesDefined = false;
+ m_IsAesMode = false;
+ m_AesKeyMode = 3; // aes-256
+ #ifdef COMPRESS_MT
+ _numThreads = NWindows::NSystem::GetNumberOfProcessors();;
+ #endif
+ }
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
new file mode 100755
index 00000000..e2394172
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
@@ -0,0 +1,393 @@
+// Zip/HandlerOut.cpp
+
+#include "StdAfx.h"
+
+#include "ZipHandler.h"
+#include "ZipUpdate.h"
+
+#include "Common/StringConvert.h"
+#include "Common/ComTry.h"
+#include "Common/StringToInt.h"
+
+#include "Windows/PropVariant.h"
+#include "Windows/Time.h"
+
+#include "../../IPassword.h"
+#include "../Common/ItemNameUtils.h"
+#include "../Common/ParseProperties.h"
+#include "../../Crypto/WzAES/WzAES.h"
+
+using namespace NWindows;
+using namespace NCOM;
+using namespace NTime;
+
+namespace NArchive {
+namespace NZip {
+
+static const UInt32 kDeflateNumPassesX1 = 1;
+static const UInt32 kDeflateNumPassesX7 = 3;
+static const UInt32 kDeflateNumPassesX9 = 10;
+
+static const UInt32 kNumFastBytesX1 = 32;
+static const UInt32 kNumFastBytesX7 = 64;
+static const UInt32 kNumFastBytesX9 = 128;
+
+static const UInt32 kBZip2NumPassesX1 = 1;
+static const UInt32 kBZip2NumPassesX7 = 2;
+static const UInt32 kBZip2NumPassesX9 = 7;
+
+static const UInt32 kBZip2DicSizeX1 = 100000;
+static const UInt32 kBZip2DicSizeX3 = 500000;
+static const UInt32 kBZip2DicSizeX5 = 900000;
+
+STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType)
+{
+ *timeType = NFileTimeType::kDOS;
+ return S_OK;
+}
+
+static bool IsAsciiString(const UString &s)
+{
+ for (int i = 0; i < s.Length(); i++)
+ {
+ wchar_t c = s[i];
+ if (c < 0x20 || c > 0x7F)
+ return false;
+ }
+ return true;
+}
+
+STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
+ IArchiveUpdateCallback *updateCallback)
+{
+ COM_TRY_BEGIN
+ CObjectVector<CUpdateItem> updateItems;
+ for(UInt32 i = 0; i < numItems; i++)
+ {
+ CUpdateItem updateItem;
+ Int32 newData;
+ Int32 newProperties;
+ UInt32 indexInArchive;
+ if (!updateCallback)
+ return E_FAIL;
+ RINOK(updateCallback->GetUpdateItemInfo(i,
+ &newData, // 1 - compress 0 - copy
+ &newProperties,
+ &indexInArchive));
+ updateItem.NewProperties = IntToBool(newProperties);
+ updateItem.NewData = IntToBool(newData);
+ updateItem.IndexInArchive = indexInArchive;
+ updateItem.IndexInClient = i;
+ // bool existInArchive = (indexInArchive != UInt32(-1));
+ if (IntToBool(newProperties))
+ {
+ FILETIME utcFileTime;
+ UString name;
+ bool isDirectoryStatusDefined;
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ updateItem.Attributes = 0;
+ else if (propVariant.vt != VT_UI4)
+ return E_INVALIDARG;
+ else
+ updateItem.Attributes = propVariant.ulVal;
+ }
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(i, kpidLastWriteTime, &propVariant));
+ if (propVariant.vt != VT_FILETIME)
+ return E_INVALIDARG;
+ utcFileTime = propVariant.filetime;
+ }
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(i, kpidPath, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ name.Empty();
+ else if (propVariant.vt != VT_BSTR)
+ return E_INVALIDARG;
+ else
+ name = propVariant.bstrVal;
+ }
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(i, kpidIsFolder, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ isDirectoryStatusDefined = false;
+ else if (propVariant.vt != VT_BOOL)
+ return E_INVALIDARG;
+ else
+ {
+ updateItem.IsDirectory = (propVariant.boolVal != VARIANT_FALSE);
+ isDirectoryStatusDefined = true;
+ }
+ }
+ FILETIME localFileTime;
+ if(!FileTimeToLocalFileTime(&utcFileTime, &localFileTime))
+ return E_INVALIDARG;
+ if(!FileTimeToDosTime(localFileTime, updateItem.Time))
+ {
+ // return E_INVALIDARG;
+ }
+
+ if (!isDirectoryStatusDefined)
+ updateItem.IsDirectory = ((updateItem.Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
+
+ name = NItemName::MakeLegalName(name);
+ bool needSlash = updateItem.IsDirectory;
+ const wchar_t kSlash = L'/';
+ if (!name.IsEmpty())
+ {
+ if (name[name.Length() - 1] == kSlash)
+ {
+ if (!updateItem.IsDirectory)
+ return E_INVALIDARG;
+ needSlash = false;
+ }
+ }
+ if (needSlash)
+ name += kSlash;
+ updateItem.Name = UnicodeStringToMultiByte(name, CP_OEMCP);
+ if (updateItem.Name.Length() > 0xFFFF)
+ return E_INVALIDARG;
+
+ updateItem.IndexInClient = i;
+ /*
+ if(existInArchive)
+ {
+ const CItemEx &itemInfo = m_Items[indexInArchive];
+ // updateItem.Commented = itemInfo.IsCommented();
+ updateItem.Commented = false;
+ if(updateItem.Commented)
+ {
+ updateItem.CommentRange.Position = itemInfo.GetCommentPosition();
+ updateItem.CommentRange.Size = itemInfo.CommentSize;
+ }
+ }
+ else
+ updateItem.Commented = false;
+ */
+ }
+ if (IntToBool(newData))
+ {
+ UInt64 size;
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant));
+ if (propVariant.vt != VT_UI8)
+ return E_INVALIDARG;
+ size = propVariant.uhVal.QuadPart;
+ }
+ updateItem.Size = size;
+ }
+ updateItems.Add(updateItem);
+ }
+
+ CMyComPtr<ICryptoGetTextPassword2> getTextPassword;
+ if (!getTextPassword)
+ {
+ CMyComPtr<IArchiveUpdateCallback> udateCallBack2(updateCallback);
+ udateCallBack2.QueryInterface(IID_ICryptoGetTextPassword2, &getTextPassword);
+ }
+ CCompressionMethodMode options;
+
+ if (getTextPassword)
+ {
+ CMyComBSTR password;
+ Int32 passwordIsDefined;
+ RINOK(getTextPassword->CryptoGetTextPassword2(&passwordIsDefined, &password));
+ options.PasswordIsDefined = IntToBool(passwordIsDefined);
+ if (options.PasswordIsDefined)
+ {
+ if (!IsAsciiString((const wchar_t *)password))
+ return E_INVALIDARG;
+ if (m_IsAesMode)
+ {
+ if (options.Password.Length() > NCrypto::NWzAES::kPasswordSizeMax)
+ return E_INVALIDARG;
+ }
+ options.Password = UnicodeStringToMultiByte((const wchar_t *)password, CP_OEMCP);
+ options.IsAesMode = m_IsAesMode;
+ options.AesKeyMode = m_AesKeyMode;
+ }
+ }
+ else
+ options.PasswordIsDefined = false;
+
+ int level = m_Level;
+ if (level < 0)
+ level = 5;
+
+ Byte mainMethod;
+ if (m_MainMethod < 0)
+ mainMethod = (Byte)(((level == 0) ?
+ NFileHeader::NCompressionMethod::kStored :
+ NFileHeader::NCompressionMethod::kDeflated));
+ else
+ mainMethod = (Byte)m_MainMethod;
+ options.MethodSequence.Add(mainMethod);
+ if (mainMethod != NFileHeader::NCompressionMethod::kStored)
+ options.MethodSequence.Add(NFileHeader::NCompressionMethod::kStored);
+ bool isDeflate = (mainMethod == NFileHeader::NCompressionMethod::kDeflated) ||
+ (mainMethod == NFileHeader::NCompressionMethod::kDeflated64);
+ bool isBZip2 = (mainMethod == NFileHeader::NCompressionMethod::kBZip2);
+ options.NumPasses = m_NumPasses;
+ options.DicSize = m_DicSize;
+ options.NumFastBytes = m_NumFastBytes;
+ options.NumMatchFinderCycles = m_NumMatchFinderCycles;
+ options.NumMatchFinderCyclesDefined = m_NumMatchFinderCyclesDefined;
+ #ifdef COMPRESS_MT
+ options.NumThreads = _numThreads;
+ #endif
+ if (isDeflate)
+ {
+ if (options.NumPasses == 0xFFFFFFFF)
+ options.NumPasses = (level >= 9 ? kDeflateNumPassesX9 :
+ (level >= 7 ? kDeflateNumPassesX7 :
+ kDeflateNumPassesX1));
+ if (options.NumFastBytes == 0xFFFFFFFF)
+ options.NumFastBytes = (level >= 9 ? kNumFastBytesX9 :
+ (level >= 7 ? kNumFastBytesX7 :
+ kNumFastBytesX1));
+ }
+ if (isBZip2)
+ {
+ if (options.NumPasses == 0xFFFFFFFF)
+ options.NumPasses = (level >= 9 ? kBZip2NumPassesX9 :
+ (level >= 7 ? kBZip2NumPassesX7 :
+ kBZip2NumPassesX1));
+ if (options.DicSize == 0xFFFFFFFF)
+ options.DicSize = (level >= 5 ? kBZip2DicSizeX5 :
+ (level >= 3 ? kBZip2DicSizeX3 :
+ kBZip2DicSizeX1));
+ }
+
+ return Update(m_Items, updateItems, outStream,
+ m_ArchiveIsOpen ? &m_Archive : NULL, &options, updateCallback);
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
+{
+ #ifdef COMPRESS_MT
+ const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
+ _numThreads = numProcessors;
+ #endif
+ InitMethodProperties();
+ for (int i = 0; i < numProperties; i++)
+ {
+ UString name = UString(names[i]);
+ name.MakeUpper();
+ if (name.IsEmpty())
+ return E_INVALIDARG;
+
+ const PROPVARIANT &prop = values[i];
+
+ if (name[0] == L'X')
+ {
+ UInt32 level = 9;
+ RINOK(ParsePropValue(name.Mid(1), prop, level));
+ m_Level = level;
+ continue;
+ }
+ else if (name == L"M")
+ {
+ if (prop.vt == VT_BSTR)
+ {
+ UString valueString = prop.bstrVal;
+ valueString.MakeUpper();
+ if (valueString == L"COPY")
+ m_MainMethod = NFileHeader::NCompressionMethod::kStored;
+ else if (valueString == L"DEFLATE")
+ m_MainMethod = NFileHeader::NCompressionMethod::kDeflated;
+ else if (valueString == L"DEFLATE64")
+ m_MainMethod = NFileHeader::NCompressionMethod::kDeflated64;
+ else if (valueString == L"BZIP2")
+ m_MainMethod = NFileHeader::NCompressionMethod::kBZip2;
+ else
+ return E_INVALIDARG;
+ }
+ else if (prop.vt == VT_UI4)
+ {
+ switch(prop.ulVal)
+ {
+ case NFileHeader::NCompressionMethod::kStored:
+ case NFileHeader::NCompressionMethod::kDeflated:
+ case NFileHeader::NCompressionMethod::kDeflated64:
+ case NFileHeader::NCompressionMethod::kBZip2:
+ m_MainMethod = (Byte)prop.ulVal;
+ break;
+ default:
+ return E_INVALIDARG;
+ }
+ }
+ else
+ return E_INVALIDARG;
+ }
+ else if (name.Left(2) == L"EM")
+ {
+ if (prop.vt == VT_BSTR)
+ {
+ UString valueString = prop.bstrVal;
+ valueString.MakeUpper();
+ if (valueString.Left(3) == L"AES")
+ {
+ valueString = valueString.Mid(3);
+ if (valueString == L"128")
+ m_AesKeyMode = 1;
+ else if (valueString == L"192")
+ m_AesKeyMode = 2;
+ else if (valueString == L"256" || valueString.IsEmpty())
+ m_AesKeyMode = 3;
+ else
+ return E_INVALIDARG;
+ m_IsAesMode = true;
+ }
+ else if (valueString == L"ZIPCRYPTO")
+ m_IsAesMode = false;
+ else
+ return E_INVALIDARG;
+ }
+ else
+ return E_INVALIDARG;
+ }
+ else if (name[0] == L'D')
+ {
+ UInt32 dicSize = kBZip2DicSizeX5;
+ RINOK(ParsePropDictionaryValue(name.Mid(1), prop, dicSize));
+ m_DicSize = dicSize;
+ }
+ else if (name.Left(4) == L"PASS")
+ {
+ UInt32 num = kDeflateNumPassesX9;
+ RINOK(ParsePropValue(name.Mid(4), prop, num));
+ m_NumPasses = num;
+ }
+ else if (name.Left(2) == L"FB")
+ {
+ UInt32 num = kNumFastBytesX9;
+ RINOK(ParsePropValue(name.Mid(2), prop, num));
+ m_NumFastBytes = num;
+ }
+ else if (name.Left(2) == L"MC")
+ {
+ UInt32 num = 0xFFFFFFFF;
+ RINOK(ParsePropValue(name.Mid(2), prop, num));
+ m_NumMatchFinderCycles = num;
+ m_NumMatchFinderCyclesDefined = true;
+ }
+ else if (name.Left(2) == L"MT")
+ {
+ #ifdef COMPRESS_MT
+ RINOK(ParseMtProp(name.Mid(2), prop, numProcessors, _numThreads));
+ #endif
+ }
+ else
+ return E_INVALIDARG;
+ }
+ return S_OK;
+}
+
+}}
diff --git a/CPP/7zip/Archive/Zip/ZipHeader.cpp b/CPP/7zip/Archive/Zip/ZipHeader.cpp
new file mode 100755
index 00000000..fd8856bb
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/ZipHeader.cpp
@@ -0,0 +1,36 @@
+// Archive/Zip/Header.h
+
+#include "StdAfx.h"
+
+#include "ZipHeader.h"
+
+namespace NArchive {
+namespace NZip {
+
+namespace NSignature
+{
+ UInt32 kLocalFileHeader = 0x04034B50 + 1;
+ UInt32 kDataDescriptor = 0x08074B50 + 1;
+ UInt32 kCentralFileHeader = 0x02014B50 + 1;
+ UInt32 kEndOfCentralDir = 0x06054B50 + 1;
+ UInt32 kZip64EndOfCentralDir = 0x06064B50 + 1;
+ UInt32 kZip64EndOfCentralDirLocator = 0x07064B50 + 1;
+
+ class CMarkersInitializer
+ {
+ public:
+ CMarkersInitializer()
+ {
+ kLocalFileHeader--;
+ kDataDescriptor--;
+ kCentralFileHeader--;
+ kEndOfCentralDir--;
+ kZip64EndOfCentralDir--;
+ kZip64EndOfCentralDirLocator--;
+ }
+ };
+ static CMarkersInitializer g_MarkerInitializer;
+}
+
+}}
+
diff --git a/CPP/7zip/Archive/Zip/ZipHeader.h b/CPP/7zip/Archive/Zip/ZipHeader.h
new file mode 100755
index 00000000..ac98ea76
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/ZipHeader.h
@@ -0,0 +1,248 @@
+// Archive/Zip/Header.h
+
+#ifndef __ARCHIVE_ZIP_HEADER_H
+#define __ARCHIVE_ZIP_HEADER_H
+
+#include "Common/Types.h"
+
+namespace NArchive {
+namespace NZip {
+
+namespace NSignature
+{
+ extern UInt32 kLocalFileHeader;
+ extern UInt32 kDataDescriptor;
+ extern UInt32 kCentralFileHeader;
+ extern UInt32 kEndOfCentralDir;
+ extern UInt32 kZip64EndOfCentralDir;
+ extern UInt32 kZip64EndOfCentralDirLocator;
+
+ static const UInt32 kMarkerSize = 4;
+}
+
+const UInt32 kEcdSize = 22;
+const UInt32 kZip64EcdSize = 44;
+const UInt32 kZip64EcdLocatorSize = 20;
+/*
+struct CEndOfCentralDirectoryRecord
+{
+ UInt16 ThisDiskNumber;
+ UInt16 StartCentralDirectoryDiskNumber;
+ UInt16 NumEntriesInCentaralDirectoryOnThisDisk;
+ UInt16 NumEntriesInCentaralDirectory;
+ UInt32 CentralDirectorySize;
+ UInt32 CentralDirectoryStartOffset;
+ UInt16 CommentSize;
+};
+
+struct CEndOfCentralDirectoryRecordFull
+{
+ UInt32 Signature;
+ CEndOfCentralDirectoryRecord Header;
+};
+*/
+
+namespace NFileHeader
+{
+ /*
+ struct CVersion
+ {
+ Byte Version;
+ Byte HostOS;
+ };
+ */
+
+ namespace NCompressionMethod
+ {
+ enum EType
+ {
+ kStored = 0,
+ kShrunk = 1,
+ kReduced1 = 2,
+ kReduced2 = 3,
+ kReduced3 = 4,
+ kReduced4 = 5,
+ kImploded = 6,
+ kReservedTokenizing = 7, // reserved for tokenizing
+ kDeflated = 8,
+ kDeflated64 = 9,
+ kPKImploding = 10,
+
+ kBZip2 = 12,
+ kWzPPMd = 0x62,
+ kWzAES = 0x63
+ };
+ const int kNumCompressionMethods = 11;
+ const Byte kMadeByProgramVersion = 20;
+
+ const Byte kDeflateExtractVersion = 20;
+ const Byte kStoreExtractVersion = 10;
+
+ const Byte kSupportedVersion = 20;
+ }
+
+ namespace NExtraID
+ {
+ enum
+ {
+ kZip64 = 0x01,
+ kWzAES = 0x9901
+ };
+ }
+
+ const UInt32 kLocalBlockSize = 26;
+ /*
+ struct CLocalBlock
+ {
+ CVersion ExtractVersion;
+
+ UInt16 Flags;
+ UInt16 CompressionMethod;
+ UInt32 Time;
+ UInt32 FileCRC;
+ UInt32 PackSize;
+ UInt32 UnPackSize;
+ UInt16 NameSize;
+ UInt16 ExtraSize;
+ };
+ */
+
+ const UInt32 kDataDescriptorSize = 16;
+ /*
+ struct CDataDescriptor
+ {
+ UInt32 Signature;
+ UInt32 FileCRC;
+ UInt32 PackSize;
+ UInt32 UnPackSize;
+ };
+
+ struct CLocalBlockFull
+ {
+ UInt32 Signature;
+ CLocalBlock Header;
+ };
+ */
+
+ const UInt32 kCentralBlockSize = 42;
+ /*
+ struct CBlock
+ {
+ CVersion MadeByVersion;
+ CVersion ExtractVersion;
+ UInt16 Flags;
+ UInt16 CompressionMethod;
+ UInt32 Time;
+ UInt32 FileCRC;
+ UInt32 PackSize;
+ UInt32 UnPackSize;
+ UInt16 NameSize;
+ UInt16 ExtraSize;
+ UInt16 CommentSize;
+ UInt16 DiskNumberStart;
+ UInt16 InternalAttributes;
+ UInt32 ExternalAttributes;
+ UInt32 LocalHeaderOffset;
+ };
+
+ struct CBlockFull
+ {
+ UInt32 Signature;
+ CBlock Header;
+ };
+ */
+
+ namespace NFlags
+ {
+ const int kNumUsedBits = 4;
+ const int kUsedBitsMask = (1 << kNumUsedBits) - 1;
+
+ const int kEncryptedMask = 1 << 0;
+ const int kDescriptorUsedMask = 1 << 3;
+
+ const int kImplodeDictionarySizeMask = 1 << 1;
+ const int kImplodeLiteralsOnMask = 1 << 2;
+
+ const int kDeflateTypeBitStart = 1;
+ const int kNumDeflateTypeBits = 2;
+ const int kNumDeflateTypes = (1 << kNumDeflateTypeBits);
+ const int kDeflateTypeMask = (1 << kNumDeflateTypeBits) - 1;
+ }
+
+ namespace NHostOS
+ {
+ enum EEnum
+ {
+ kFAT = 0, // filesystem used by MS-DOS, OS/2, Win32
+ // pkzip 2.50 (FAT / VFAT / FAT32 file systems)
+ kAMIGA = 1,
+ kVMS = 2, // VAX/VMS
+ kUnix = 3,
+ kVM_CMS = 4,
+ kAtari = 5, // what if it's a minix filesystem? [cjh]
+ kHPFS = 6, // filesystem used by OS/2 (and NT 3.x)
+ kMac = 7,
+ kZ_System = 8,
+ kCPM = 9,
+ kTOPS20 = 10, // pkzip 2.50 NTFS
+ kNTFS = 11, // filesystem used by Windows NT
+ kQDOS = 12, // SMS/QDOS
+ kAcorn = 13, // Archimedes Acorn RISC OS
+ kVFAT = 14, // filesystem used by Windows 95, NT
+ kMVS = 15,
+ kBeOS = 16, // hybrid POSIX/database filesystem
+ // BeBOX or PowerMac
+ kTandem = 17,
+ kTHEOS = 18
+ };
+ // const int kNumHostSystems = 19;
+ }
+ namespace NUnixAttribute
+ {
+ const UInt32 kIFMT = 0170000; /* Unix file type mask */
+
+ const UInt32 kIFDIR = 0040000; /* Unix directory */
+ const UInt32 kIFREG = 0100000; /* Unix regular file */
+ const UInt32 kIFSOCK = 0140000; /* Unix socket (BSD, not SysV or Amiga) */
+ const UInt32 kIFLNK = 0120000; /* Unix symbolic link (not SysV, Amiga) */
+ const UInt32 kIFBLK = 0060000; /* Unix block special (not Amiga) */
+ const UInt32 kIFCHR = 0020000; /* Unix character special (not Amiga) */
+ const UInt32 kIFIFO = 0010000; /* Unix fifo (BCC, not MSC or Amiga) */
+
+ const UInt32 kISUID = 04000; /* Unix set user id on execution */
+ const UInt32 kISGID = 02000; /* Unix set group id on execution */
+ const UInt32 kISVTX = 01000; /* Unix directory permissions control */
+ const UInt32 kENFMT = kISGID; /* Unix record locking enforcement flag */
+ const UInt32 kIRWXU = 00700; /* Unix read, write, execute: owner */
+ const UInt32 kIRUSR = 00400; /* Unix read permission: owner */
+ const UInt32 kIWUSR = 00200; /* Unix write permission: owner */
+ const UInt32 kIXUSR = 00100; /* Unix execute permission: owner */
+ const UInt32 kIRWXG = 00070; /* Unix read, write, execute: group */
+ const UInt32 kIRGRP = 00040; /* Unix read permission: group */
+ const UInt32 kIWGRP = 00020; /* Unix write permission: group */
+ const UInt32 kIXGRP = 00010; /* Unix execute permission: group */
+ const UInt32 kIRWXO = 00007; /* Unix read, write, execute: other */
+ const UInt32 kIROTH = 00004; /* Unix read permission: other */
+ const UInt32 kIWOTH = 00002; /* Unix write permission: other */
+ const UInt32 kIXOTH = 00001; /* Unix execute permission: other */
+ }
+
+ namespace NAmigaAttribute
+ {
+ const UInt32 kIFMT = 06000; /* Amiga file type mask */
+ const UInt32 kIFDIR = 04000; /* Amiga directory */
+ const UInt32 kIFREG = 02000; /* Amiga regular file */
+ const UInt32 kIHIDDEN = 00200; /* to be supported in AmigaDOS 3.x */
+ const UInt32 kISCRIPT = 00100; /* executable script (text command file) */
+ const UInt32 kIPURE = 00040; /* allow loading into resident memory */
+ const UInt32 kIARCHIVE = 00020; /* not modified since bit was last set */
+ const UInt32 kIREAD = 00010; /* can be opened for reading */
+ const UInt32 kIWRITE = 00004; /* can be opened for writing */
+ const UInt32 kIEXECUTE = 00002; /* executable image, a loadable runfile */
+ const UInt32 kIDELETE = 00001; /* can be deleted */
+ }
+}
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Zip/ZipIn.cpp b/CPP/7zip/Archive/Zip/ZipIn.cpp
new file mode 100755
index 00000000..c9e3a7d1
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/ZipIn.cpp
@@ -0,0 +1,797 @@
+// Archive/ZipIn.cpp
+
+#include "StdAfx.h"
+
+#include "ZipIn.h"
+#include "Windows/Defs.h"
+#include "Common/StringConvert.h"
+#include "Common/DynamicBuffer.h"
+#include "../../Common/LimitedStreams.h"
+#include "../../Common/StreamUtils.h"
+
+namespace NArchive {
+namespace NZip {
+
+// static const char kEndOfString = '\0';
+
+bool CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit)
+{
+ m_Stream = inStream;
+ if(m_Stream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition) != S_OK)
+ return false;
+ m_Position = m_StreamStartPosition;
+ return FindAndReadMarker(searchHeaderSizeLimit);
+}
+
+void CInArchive::Close()
+{
+ m_Stream.Release();
+}
+
+HRESULT CInArchive::Seek(UInt64 offset)
+{
+ return m_Stream->Seek(offset, STREAM_SEEK_SET, NULL);
+}
+
+//////////////////////////////////////
+// Markers
+
+static inline bool TestMarkerCandidate(const Byte *p, UInt32 &value)
+{
+ value = p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);
+ return (value == NSignature::kLocalFileHeader) ||
+ (value == NSignature::kEndOfCentralDir);
+}
+
+bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit)
+{
+ m_ArchiveInfo.Clear();
+ m_Position = m_StreamStartPosition;
+ if(Seek(m_StreamStartPosition) != S_OK)
+ return false;
+
+ Byte marker[NSignature::kMarkerSize];
+ UInt32 processedSize;
+ ReadBytes(marker, NSignature::kMarkerSize, &processedSize);
+ if(processedSize != NSignature::kMarkerSize)
+ return false;
+ if (TestMarkerCandidate(marker, m_Signature))
+ return true;
+
+ CByteDynamicBuffer dynamicBuffer;
+ static const UInt32 kSearchMarkerBufferSize = 0x10000;
+ dynamicBuffer.EnsureCapacity(kSearchMarkerBufferSize);
+ Byte *buffer = dynamicBuffer;
+ UInt32 numBytesPrev = NSignature::kMarkerSize - 1;
+ memmove(buffer, marker + 1, numBytesPrev);
+ UInt64 curTestPos = m_StreamStartPosition + 1;
+ for (;;)
+ {
+ if (searchHeaderSizeLimit != NULL)
+ if (curTestPos - m_StreamStartPosition > *searchHeaderSizeLimit)
+ break;
+ UInt32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev;
+ ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize);
+ UInt32 numBytesInBuffer = numBytesPrev + processedSize;
+ if (numBytesInBuffer < NSignature::kMarkerSize)
+ break;
+ UInt32 numTests = numBytesInBuffer - NSignature::kMarkerSize + 1;
+ for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++)
+ {
+ if (TestMarkerCandidate(buffer + pos, m_Signature))
+ {
+ m_ArchiveInfo.StartPosition = curTestPos;
+ // m_ArchiveInfo.Base = m_ArchiveInfo.StartPosition;
+ // m_ArchiveInfo.Base = 0;
+ m_Position = curTestPos + NSignature::kMarkerSize;
+ if(Seek(m_Position) != S_OK)
+ return false;
+ return true;
+ }
+ }
+ numBytesPrev = numBytesInBuffer - numTests;
+ memmove(buffer, buffer + numTests, numBytesPrev);
+ }
+ return false;
+}
+
+HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize;
+ HRESULT result = ReadStream(m_Stream, data, size, &realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ m_Position += realProcessedSize;
+ return result;
+}
+
+void CInArchive::IncreaseRealPosition(UInt64 addValue)
+{
+ if(m_Stream->Seek(addValue, STREAM_SEEK_CUR, &m_Position) != S_OK)
+ throw CInArchiveException(CInArchiveException::kSeekStreamError);
+}
+
+bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size)
+{
+ UInt32 realProcessedSize;
+ if(ReadBytes(data, size, &realProcessedSize) != S_OK)
+ throw CInArchiveException(CInArchiveException::kReadStreamError);
+ return (realProcessedSize == size);
+}
+
+void CInArchive::SafeReadBytes(void *data, UInt32 size)
+{
+ if(!ReadBytesAndTestSize(data, size))
+ throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
+}
+
+void CInArchive::ReadBuffer(CByteBuffer &buffer, UInt32 size)
+{
+ buffer.SetCapacity(size);
+ if (size > 0)
+ SafeReadBytes(buffer, size);
+}
+
+Byte CInArchive::ReadByte()
+{
+ Byte b;
+ SafeReadBytes(&b, 1);
+ return b;
+}
+
+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;
+}
+
+bool CInArchive::ReadUInt32(UInt32 &value)
+{
+ value = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ Byte b;
+ if (!ReadBytesAndTestSize(&b, 1))
+ return false;
+ value |= (UInt32(b) << (8 * i));
+ }
+ return true;
+}
+
+
+AString CInArchive::ReadFileName(UInt32 nameSize)
+{
+ if (nameSize == 0)
+ return AString();
+ SafeReadBytes(m_NameBuffer.GetBuffer(nameSize), nameSize);
+ m_NameBuffer.ReleaseBuffer(nameSize);
+ return m_NameBuffer;
+}
+
+void CInArchive::GetArchiveInfo(CInArchiveInfo &archiveInfo) const
+{
+ archiveInfo = m_ArchiveInfo;
+}
+
+/*
+void CInArchive::ThrowIncorrectArchiveException()
+{
+ throw CInArchiveException(CInArchiveException::kIncorrectArchive);
+}
+*/
+
+static UInt32 GetUInt32(const Byte *data)
+{
+ return
+ ((UInt32)(Byte)data[0]) |
+ (((UInt32)(Byte)data[1]) << 8) |
+ (((UInt32)(Byte)data[2]) << 16) |
+ (((UInt32)(Byte)data[3]) << 24);
+}
+
+/*
+static UInt16 GetUInt16(const Byte *data)
+{
+ return
+ ((UInt16)(Byte)data[0]) |
+ (((UInt16)(Byte)data[1]) << 8);
+}
+*/
+
+static UInt64 GetUInt64(const Byte *data)
+{
+ return GetUInt32(data) | ((UInt64)GetUInt32(data + 4) << 32);
+}
+
+
+
+void CInArchive::ReadExtra(UInt32 extraSize, CExtraBlock &extraBlock,
+ UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber)
+{
+ extraBlock.Clear();
+ UInt32 remain = extraSize;
+ while(remain >= 4)
+ {
+ CExtraSubBlock subBlock;
+ subBlock.ID = ReadUInt16();
+ UInt32 dataSize = ReadUInt16();
+ remain -= 4;
+ if (dataSize > remain) // it's bug
+ dataSize = remain;
+ if (subBlock.ID == NFileHeader::NExtraID::kZip64)
+ {
+ if (unpackSize == 0xFFFFFFFF)
+ {
+ if (dataSize < 8)
+ break;
+ unpackSize = ReadUInt64();
+ remain -= 8;
+ dataSize -= 8;
+ }
+ if (packSize == 0xFFFFFFFF)
+ {
+ if (dataSize < 8)
+ break;
+ packSize = ReadUInt64();
+ remain -= 8;
+ dataSize -= 8;
+ }
+ if (localHeaderOffset == 0xFFFFFFFF)
+ {
+ if (dataSize < 8)
+ break;
+ localHeaderOffset = ReadUInt64();
+ remain -= 8;
+ dataSize -= 8;
+ }
+ if (diskStartNumber == 0xFFFF)
+ {
+ if (dataSize < 4)
+ break;
+ diskStartNumber = ReadUInt32();
+ remain -= 4;
+ dataSize -= 4;
+ }
+ for (UInt32 i = 0; i < dataSize; i++)
+ ReadByte();
+ }
+ else
+ {
+ ReadBuffer(subBlock.Data, dataSize);
+ extraBlock.SubBlocks.Add(subBlock);
+ }
+ remain -= dataSize;
+ }
+ IncreaseRealPosition(remain);
+}
+
+HRESULT CInArchive::ReadLocalItem(CItemEx &item)
+{
+ item.ExtractVersion.Version = ReadByte();
+ item.ExtractVersion.HostOS = ReadByte();
+ item.Flags = ReadUInt16(); // & NFileHeader::NFlags::kUsedBitsMask;
+ item.CompressionMethod = ReadUInt16();
+ item.Time = ReadUInt32();
+ item.FileCRC = ReadUInt32();
+ item.PackSize = ReadUInt32();
+ item.UnPackSize = ReadUInt32();
+ UInt32 fileNameSize = ReadUInt16();
+ item.LocalExtraSize = ReadUInt16();
+ item.Name = ReadFileName(fileNameSize);
+ item.FileHeaderWithNameSize = 4 + NFileHeader::kLocalBlockSize + fileNameSize;
+ if (item.LocalExtraSize > 0)
+ {
+ UInt64 localHeaderOffset = 0;
+ UInt32 diskStartNumber = 0;
+ ReadExtra(item.LocalExtraSize, item.LocalExtra, item.UnPackSize, item.PackSize,
+ localHeaderOffset, diskStartNumber);
+ }
+ /*
+ if (item.IsDirectory())
+ item.UnPackSize = 0; // check It
+ */
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadLocalItemAfterCdItem(CItemEx &item)
+{
+ if (item.FromLocal)
+ return S_OK;
+ try
+ {
+ RINOK(Seek(m_ArchiveInfo.Base + item.LocalHeaderPosition));
+ CItemEx localItem;
+ if (ReadUInt32() != NSignature::kLocalFileHeader)
+ return S_FALSE;
+ RINOK(ReadLocalItem(localItem));
+ if (item.Flags != localItem.Flags)
+ {
+ if (item.CompressionMethod != NFileHeader::NCompressionMethod::kDeflated ||
+ (item.Flags & 0xFFFC) != (localItem.Flags & 0xFFFC))
+ return S_FALSE;
+ }
+
+ if (item.CompressionMethod != localItem.CompressionMethod ||
+ // item.Time != localItem.Time ||
+ (!localItem.HasDescriptor() &&
+ (
+ item.FileCRC != localItem.FileCRC ||
+ item.PackSize != localItem.PackSize ||
+ item.UnPackSize != localItem.UnPackSize
+ )
+ ) ||
+ item.Name.Length() != localItem.Name.Length()
+ )
+ return S_FALSE;
+ item.FileHeaderWithNameSize = localItem.FileHeaderWithNameSize;
+ item.LocalExtraSize = localItem.LocalExtraSize;
+ item.LocalExtra = localItem.LocalExtra;
+ item.FromLocal = true;
+ }
+ catch(...) { return S_FALSE; }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadLocalItemDescriptor(CItemEx &item)
+{
+ if (item.HasDescriptor())
+ {
+ const int kBufferSize = (1 << 12);
+ Byte buffer[kBufferSize];
+
+ UInt32 numBytesInBuffer = 0;
+ UInt32 packedSize = 0;
+
+ bool descriptorWasFound = false;
+ for (;;)
+ {
+ UInt32 processedSize;
+ RINOK(ReadBytes(buffer + numBytesInBuffer, kBufferSize - numBytesInBuffer, &processedSize));
+ numBytesInBuffer += processedSize;
+ if (numBytesInBuffer < NFileHeader::kDataDescriptorSize)
+ return S_FALSE;
+ UInt32 i;
+ for (i = 0; i <= numBytesInBuffer - NFileHeader::kDataDescriptorSize; i++)
+ {
+ // descriptorSignature field is Info-ZIP's extension
+ // to Zip specification.
+ UInt32 descriptorSignature = GetUInt32(buffer + i);
+
+ // !!!! It must be fixed for Zip64 archives
+ UInt32 descriptorPackSize = GetUInt32(buffer + i + 8);
+ if (descriptorSignature== NSignature::kDataDescriptor && descriptorPackSize == packedSize + i)
+ {
+ descriptorWasFound = true;
+ item.FileCRC = GetUInt32(buffer + i + 4);
+ item.PackSize = descriptorPackSize;
+ item.UnPackSize = GetUInt32(buffer + i + 12);
+ IncreaseRealPosition(Int64(Int32(0 - (numBytesInBuffer - i - NFileHeader::kDataDescriptorSize))));
+ break;
+ }
+ }
+ if (descriptorWasFound)
+ break;
+ packedSize += i;
+ int j;
+ for (j = 0; i < numBytesInBuffer; i++, j++)
+ buffer[j] = buffer[i];
+ numBytesInBuffer = j;
+ }
+ }
+ else
+ IncreaseRealPosition(item.PackSize);
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadLocalItemAfterCdItemFull(CItemEx &item)
+{
+ if (item.FromLocal)
+ return S_OK;
+ try
+ {
+ RINOK(ReadLocalItemAfterCdItem(item));
+ if (item.HasDescriptor())
+ {
+ RINOK(Seek(m_ArchiveInfo.Base + item.GetDataPosition() + item.PackSize));
+ if (ReadUInt32() != NSignature::kDataDescriptor)
+ return S_FALSE;
+ UInt32 crc = ReadUInt32();
+ UInt32 packSize = ReadUInt32();
+ UInt32 unpackSize = ReadUInt32();
+ if (crc != item.FileCRC || item.PackSize != packSize || item.UnPackSize != unpackSize)
+ return S_FALSE;
+ }
+ }
+ catch(...) { return S_FALSE; }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadCdItem(CItemEx &item)
+{
+ item.FromCentral = true;
+ item.MadeByVersion.Version = ReadByte();
+ item.MadeByVersion.HostOS = ReadByte();
+ item.ExtractVersion.Version = ReadByte();
+ item.ExtractVersion.HostOS = ReadByte();
+ item.Flags = ReadUInt16(); // & NFileHeader::NFlags::kUsedBitsMask;
+ item.CompressionMethod = ReadUInt16();
+ item.Time = ReadUInt32();
+ item.FileCRC = ReadUInt32();
+ item.PackSize = ReadUInt32();
+ item.UnPackSize = ReadUInt32();
+ UInt16 headerNameSize = ReadUInt16();
+ UInt16 headerExtraSize = ReadUInt16();
+ UInt16 headerCommentSize = ReadUInt16();
+ UInt32 headerDiskNumberStart = ReadUInt16();
+ item.InternalAttributes = ReadUInt16();
+ item.ExternalAttributes = ReadUInt32();
+ item.LocalHeaderPosition = ReadUInt32();
+ item.Name = ReadFileName(headerNameSize);
+
+ if (headerExtraSize > 0)
+ {
+ ReadExtra(headerExtraSize, item.CentralExtra, item.UnPackSize, item.PackSize,
+ item.LocalHeaderPosition, headerDiskNumberStart);
+ }
+
+ if (headerDiskNumberStart != 0)
+ throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported);
+
+ // May be these strings must be deleted
+ /*
+ if (item.IsDirectory())
+ item.UnPackSize = 0;
+ */
+
+ ReadBuffer(item.Comment, headerCommentSize);
+ return S_OK;
+}
+
+HRESULT CInArchive::TryEcd64(UInt64 offset, CCdInfo &cdInfo)
+{
+ RINOK(Seek(offset));
+ const UInt32 kEcd64Size = 56;
+ Byte buf[kEcd64Size];
+ if(!ReadBytesAndTestSize(buf, kEcd64Size))
+ return S_FALSE;
+ if (GetUInt32(buf) != NSignature::kZip64EndOfCentralDir)
+ return S_FALSE;
+ // cdInfo.NumEntries = GetUInt64(buf + 24);
+ cdInfo.Size = GetUInt64(buf + 40);
+ cdInfo.Offset = GetUInt64(buf + 48);
+ return S_OK;
+}
+
+HRESULT CInArchive::FindCd(CCdInfo &cdInfo)
+{
+ UInt64 endPosition;
+ RINOK(m_Stream->Seek(0, STREAM_SEEK_END, &endPosition));
+ const UInt32 kBufSizeMax = (1 << 16) + kEcdSize + kZip64EcdLocatorSize;
+ Byte buf[kBufSizeMax];
+ UInt32 bufSize = (endPosition < kBufSizeMax) ? (UInt32)endPosition : kBufSizeMax;
+ if (bufSize < kEcdSize)
+ return S_FALSE;
+ UInt64 startPosition = endPosition - bufSize;
+ RINOK(m_Stream->Seek(startPosition, STREAM_SEEK_SET, &m_Position));
+ if (m_Position != startPosition)
+ return S_FALSE;
+ if (!ReadBytesAndTestSize(buf, bufSize))
+ return S_FALSE;
+ for (int i = (int)(bufSize - kEcdSize); i >= 0; i--)
+ {
+ if (GetUInt32(buf + i) == NSignature::kEndOfCentralDir)
+ {
+ if (i >= kZip64EcdLocatorSize)
+ {
+ const Byte *locator = buf + i - kZip64EcdLocatorSize;
+ if (GetUInt32(locator) == NSignature::kZip64EndOfCentralDirLocator)
+ {
+ UInt64 ecd64Offset = GetUInt64(locator + 8);
+ if (TryEcd64(ecd64Offset, cdInfo) == S_OK)
+ return S_OK;
+ if (TryEcd64(m_ArchiveInfo.StartPosition + ecd64Offset, cdInfo) == S_OK)
+ {
+ m_ArchiveInfo.Base = m_ArchiveInfo.StartPosition;
+ return S_OK;
+ }
+ }
+ }
+ if (GetUInt32(buf + i + 4) == 0)
+ {
+ // cdInfo.NumEntries = GetUInt16(buf + i + 10);
+ cdInfo.Size = GetUInt32(buf + i + 12);
+ cdInfo.Offset = GetUInt32(buf + i + 16);
+ return S_OK;
+ }
+ }
+ }
+ return S_FALSE;
+}
+
+HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, UInt64 cdOffset, UInt64 cdSize)
+{
+ items.Clear();
+ RINOK(m_Stream->Seek(cdOffset, STREAM_SEEK_SET, &m_Position));
+ if (m_Position != cdOffset)
+ return S_FALSE;
+ while(m_Position - cdOffset < cdSize)
+ {
+ if(ReadUInt32() != NSignature::kCentralFileHeader)
+ return S_FALSE;
+ CItemEx cdItem;
+ RINOK(ReadCdItem(cdItem));
+ items.Add(cdItem);
+ }
+ return (m_Position - cdOffset == cdSize) ? S_OK : S_FALSE;
+}
+
+HRESULT CInArchive::ReadCd(CObjectVector<CItemEx> &items, UInt64 &cdOffset, UInt64 &cdSize)
+{
+ m_ArchiveInfo.Base = 0;
+ CCdInfo cdInfo;
+ RINOK(FindCd(cdInfo));
+ HRESULT res = S_FALSE;
+ cdSize = cdInfo.Size;
+ cdOffset = cdInfo.Offset;
+ res = TryReadCd(items, m_ArchiveInfo.Base + cdOffset, cdSize);
+ if (res == S_FALSE && m_ArchiveInfo.Base == 0)
+ {
+ res = TryReadCd(items, cdInfo.Offset + m_ArchiveInfo.StartPosition, cdSize);
+ if (res == S_OK)
+ m_ArchiveInfo.Base = m_ArchiveInfo.StartPosition;
+ }
+ if (!ReadUInt32(m_Signature))
+ return S_FALSE;
+ return res;
+}
+
+HRESULT CInArchive::ReadLocalsAndCd(CObjectVector<CItemEx> &items, CProgressVirt *progress, UInt64 &cdOffset)
+{
+ items.Clear();
+ while (m_Signature == NSignature::kLocalFileHeader)
+ {
+ // FSeek points to next byte after signature
+ // NFileHeader::CLocalBlock localHeader;
+ CItemEx item;
+ item.LocalHeaderPosition = m_Position - m_StreamStartPosition - 4; // points to signature;
+ RINOK(ReadLocalItem(item));
+ item.FromLocal = true;
+ ReadLocalItemDescriptor(item);
+ items.Add(item);
+ if (progress != 0)
+ {
+ UInt64 numItems = items.Size();
+ RINOK(progress->SetCompleted(&numItems));
+ }
+ if (!ReadUInt32(m_Signature))
+ break;
+ }
+ cdOffset = m_Position - 4;
+ for(int i = 0; i < items.Size(); i++)
+ {
+ if (progress != 0)
+ {
+ UInt64 numItems = items.Size();
+ RINOK(progress->SetCompleted(&numItems));
+ }
+ if(m_Signature != NSignature::kCentralFileHeader)
+ return S_FALSE;
+
+ CItemEx cdItem;
+ RINOK(ReadCdItem(cdItem));
+
+ if (i == 0)
+ {
+ if (cdItem.LocalHeaderPosition == 0)
+ m_ArchiveInfo.Base = m_ArchiveInfo.StartPosition;
+ }
+
+ int index;
+ int left = 0, right = items.Size();
+ for (;;)
+ {
+ if (left >= right)
+ return S_FALSE;
+ index = (left + right) / 2;
+ UInt64 position = items[index].LocalHeaderPosition - m_ArchiveInfo.Base;
+ if (cdItem.LocalHeaderPosition == position)
+ break;
+ if (cdItem.LocalHeaderPosition < position)
+ right = index;
+ else
+ left = index + 1;
+ }
+ CItemEx &item = items[index];
+ item.LocalHeaderPosition = cdItem.LocalHeaderPosition;
+ item.MadeByVersion = cdItem.MadeByVersion;
+ item.CentralExtra = cdItem.CentralExtra;
+
+ if (
+ // item.ExtractVersion != cdItem.ExtractVersion ||
+ item.Flags != cdItem.Flags ||
+ item.CompressionMethod != cdItem.CompressionMethod ||
+ // item.Time != cdItem.Time ||
+ item.FileCRC != cdItem.FileCRC)
+ return S_FALSE;
+
+ if (item.Name.Length() != cdItem.Name.Length() ||
+ item.PackSize != cdItem.PackSize ||
+ item.UnPackSize != cdItem.UnPackSize
+ )
+ return S_FALSE;
+ item.Name = cdItem.Name;
+ item.InternalAttributes = cdItem.InternalAttributes;
+ item.ExternalAttributes = cdItem.ExternalAttributes;
+ item.Comment = cdItem.Comment;
+ item.FromCentral = cdItem.FromCentral;
+ if (!ReadUInt32(m_Signature))
+ return S_FALSE;
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *progress)
+{
+ // m_Signature must be kLocalFileHeaderSignature or
+ // kEndOfCentralDirSignature
+ // m_Position points to next byte after signature
+
+ items.Clear();
+ if (progress != 0)
+ {
+ UInt64 numItems = items.Size();
+ RINOK(progress->SetCompleted(&numItems));
+ }
+
+ UInt64 cdSize, cdStartOffset;
+ HRESULT res = ReadCd(items, cdStartOffset, cdSize);
+ if (res != S_FALSE && res != S_OK)
+ return res;
+
+ /*
+ if (res != S_OK)
+ return res;
+ res = S_FALSE;
+ */
+
+ if (res == S_FALSE)
+ {
+ m_ArchiveInfo.Base = 0;
+ RINOK(m_Stream->Seek(m_ArchiveInfo.StartPosition, STREAM_SEEK_SET, &m_Position));
+ if (m_Position != m_ArchiveInfo.StartPosition)
+ return S_FALSE;
+ if (!ReadUInt32(m_Signature))
+ return S_FALSE;
+ RINOK(ReadLocalsAndCd(items, progress, cdStartOffset));
+ cdSize = (m_Position - 4) - cdStartOffset;
+ cdStartOffset -= m_ArchiveInfo.Base;
+ }
+
+ UInt32 thisDiskNumber = 0;
+ UInt32 startCDDiskNumber = 0;
+ UInt64 numEntriesInCDOnThisDisk = 0;
+ UInt64 numEntriesInCD = 0;
+ UInt64 cdSizeFromRecord = 0;
+ UInt64 cdStartOffsetFromRecord = 0;
+ bool isZip64 = false;
+ UInt64 zip64EcdStartOffset = m_Position - 4 - m_ArchiveInfo.Base;
+ if(m_Signature == NSignature::kZip64EndOfCentralDir)
+ {
+ isZip64 = true;
+ UInt64 recordSize = ReadUInt64();
+ /* UInt16 versionMade = */ ReadUInt16();
+ /* UInt16 versionNeedExtract = */ ReadUInt16();
+ thisDiskNumber = ReadUInt32();
+ startCDDiskNumber = ReadUInt32();
+ numEntriesInCDOnThisDisk = ReadUInt64();
+ numEntriesInCD = ReadUInt64();
+ cdSizeFromRecord = ReadUInt64();
+ cdStartOffsetFromRecord = ReadUInt64();
+ IncreaseRealPosition(recordSize - kZip64EcdSize);
+ if (!ReadUInt32(m_Signature))
+ return S_FALSE;
+ if (thisDiskNumber != 0 || startCDDiskNumber != 0)
+ throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported);
+ if (numEntriesInCDOnThisDisk != items.Size() ||
+ numEntriesInCD != items.Size() ||
+ cdSizeFromRecord != cdSize ||
+ (cdStartOffsetFromRecord != cdStartOffset &&
+ (!items.IsEmpty())))
+ return S_FALSE;
+ }
+ if(m_Signature == NSignature::kZip64EndOfCentralDirLocator)
+ {
+ /* UInt32 startEndCDDiskNumber = */ ReadUInt32();
+ UInt64 endCDStartOffset = ReadUInt64();
+ /* UInt32 numberOfDisks = */ ReadUInt32();
+ if (zip64EcdStartOffset != endCDStartOffset)
+ return S_FALSE;
+ if (!ReadUInt32(m_Signature))
+ return S_FALSE;
+ }
+ if(m_Signature != NSignature::kEndOfCentralDir)
+ return S_FALSE;
+
+ UInt16 thisDiskNumber16 = ReadUInt16();
+ if (!isZip64 || thisDiskNumber16)
+ thisDiskNumber = thisDiskNumber16;
+
+ UInt16 startCDDiskNumber16 = ReadUInt16();
+ if (!isZip64 || startCDDiskNumber16 != 0xFFFF)
+ startCDDiskNumber = startCDDiskNumber16;
+
+ UInt16 numEntriesInCDOnThisDisk16 = ReadUInt16();
+ if (!isZip64 || numEntriesInCDOnThisDisk16 != 0xFFFF)
+ numEntriesInCDOnThisDisk = numEntriesInCDOnThisDisk16;
+
+ UInt16 numEntriesInCD16 = ReadUInt16();
+ if (!isZip64 || numEntriesInCD16 != 0xFFFF)
+ numEntriesInCD = numEntriesInCD16;
+
+ UInt32 cdSizeFromRecord32 = ReadUInt32();
+ if (!isZip64 || cdSizeFromRecord32 != 0xFFFFFFFF)
+ cdSizeFromRecord = cdSizeFromRecord32;
+
+ UInt32 cdStartOffsetFromRecord32 = ReadUInt32();
+ if (!isZip64 || cdStartOffsetFromRecord32 != 0xFFFFFFFF)
+ cdStartOffsetFromRecord = cdStartOffsetFromRecord32;
+
+ UInt16 commentSize = ReadUInt16();
+ ReadBuffer(m_ArchiveInfo.Comment, commentSize);
+
+ if (thisDiskNumber != 0 || startCDDiskNumber != 0)
+ throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported);
+ if ((UInt16)numEntriesInCDOnThisDisk != ((UInt16)items.Size()) ||
+ (UInt16)numEntriesInCD != ((UInt16)items.Size()) ||
+ (UInt32)cdSizeFromRecord != (UInt32)cdSize ||
+ ((UInt32)(cdStartOffsetFromRecord) != (UInt32)cdStartOffset &&
+ (!items.IsEmpty())))
+ return S_FALSE;
+
+ return S_OK;
+}
+
+ISequentialInStream* CInArchive::CreateLimitedStream(UInt64 position, UInt64 size)
+{
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+ CMyComPtr<ISequentialInStream> inStream(streamSpec);
+ SeekInArchive(m_ArchiveInfo.Base + position);
+ streamSpec->SetStream(m_Stream);
+ streamSpec->Init(size);
+ return inStream.Detach();
+}
+
+IInStream* CInArchive::CreateStream()
+{
+ CMyComPtr<IInStream> inStream = m_Stream;
+ return inStream.Detach();
+}
+
+bool CInArchive::SeekInArchive(UInt64 position)
+{
+ UInt64 newPosition;
+ if(m_Stream->Seek(position, STREAM_SEEK_SET, &newPosition) != S_OK)
+ return false;
+ return (newPosition == position);
+}
+
+}}
+
diff --git a/CPP/7zip/Archive/Zip/ZipIn.h b/CPP/7zip/Archive/Zip/ZipIn.h
new file mode 100755
index 00000000..80de2272
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/ZipIn.h
@@ -0,0 +1,111 @@
+// Archive/ZipIn.h
+
+#ifndef __ZIP_IN_H
+#define __ZIP_IN_H
+
+#include "Common/MyCom.h"
+#include "../../IStream.h"
+
+#include "ZipHeader.h"
+#include "ZipItemEx.h"
+
+namespace NArchive {
+namespace NZip {
+
+class CInArchiveException
+{
+public:
+ enum ECauseType
+ {
+ kUnexpectedEndOfArchive = 0,
+ kArchiceHeaderCRCError,
+ kFileHeaderCRCError,
+ kIncorrectArchive,
+ kDataDescroptorsAreNotSupported,
+ kMultiVolumeArchiveAreNotSupported,
+ kReadStreamError,
+ kSeekStreamError
+ }
+ Cause;
+ CInArchiveException(ECauseType cause): Cause(cause) {}
+};
+
+class CInArchiveInfo
+{
+public:
+ UInt64 Base;
+ UInt64 StartPosition;
+ CByteBuffer Comment;
+ CInArchiveInfo(): Base(0), StartPosition(0) {}
+ void Clear()
+ {
+ Base = 0;
+ StartPosition = 0;
+ Comment.SetCapacity(0);
+ }
+};
+
+class CProgressVirt
+{
+public:
+ STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE;
+};
+
+struct CCdInfo
+{
+ // UInt64 NumEntries;
+ UInt64 Size;
+ UInt64 Offset;
+};
+
+class CInArchive
+{
+ CMyComPtr<IInStream> m_Stream;
+ UInt32 m_Signature;
+ UInt64 m_StreamStartPosition;
+ UInt64 m_Position;
+ CInArchiveInfo m_ArchiveInfo;
+ AString m_NameBuffer;
+
+ HRESULT Seek(UInt64 offset);
+
+ bool FindAndReadMarker(const UInt64 *searchHeaderSizeLimit);
+ bool ReadUInt32(UInt32 &signature);
+ AString ReadFileName(UInt32 nameSize);
+
+ HRESULT ReadBytes(void *data, UInt32 size, UInt32 *processedSize);
+ bool ReadBytesAndTestSize(void *data, UInt32 size);
+ void SafeReadBytes(void *data, UInt32 size);
+ void ReadBuffer(CByteBuffer &buffer, UInt32 size);
+ Byte ReadByte();
+ UInt16 ReadUInt16();
+ UInt32 ReadUInt32();
+ UInt64 ReadUInt64();
+
+ void IncreaseRealPosition(UInt64 addValue);
+
+ void ReadExtra(UInt32 extraSize, CExtraBlock &extraBlock,
+ UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber);
+ HRESULT ReadLocalItem(CItemEx &item);
+ HRESULT ReadLocalItemDescriptor(CItemEx &item);
+ HRESULT ReadCdItem(CItemEx &item);
+ HRESULT TryEcd64(UInt64 offset, CCdInfo &cdInfo);
+ HRESULT FindCd(CCdInfo &cdInfo);
+ HRESULT TryReadCd(CObjectVector<CItemEx> &items, UInt64 cdOffset, UInt64 cdSize);
+ HRESULT ReadCd(CObjectVector<CItemEx> &items, UInt64 &cdOffset, UInt64 &cdSize);
+ HRESULT ReadLocalsAndCd(CObjectVector<CItemEx> &items, CProgressVirt *progress, UInt64 &cdOffset);
+public:
+ HRESULT ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *progress);
+ HRESULT ReadLocalItemAfterCdItem(CItemEx &item);
+ HRESULT ReadLocalItemAfterCdItemFull(CItemEx &item);
+ bool Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit);
+ void Close();
+ void GetArchiveInfo(CInArchiveInfo &archiveInfo) const;
+ bool SeekInArchive(UInt64 position);
+ ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size);
+ IInStream* CreateStream();
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Zip/ZipItem.cpp b/CPP/7zip/Archive/Zip/ZipItem.cpp
new file mode 100755
index 00000000..1934c357
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/ZipItem.cpp
@@ -0,0 +1,137 @@
+// Archive/ZipItem.cpp
+
+#include "StdAfx.h"
+
+#include "ZipHeader.h"
+#include "ZipItem.h"
+#include "../Common/ItemNameUtils.h"
+
+namespace NArchive {
+namespace NZip {
+
+bool operator==(const CVersion &v1, const CVersion &v2)
+{
+ return (v1.Version == v2.Version) && (v1.HostOS == v2.HostOS);
+}
+
+bool operator!=(const CVersion &v1, const CVersion &v2)
+{
+ return !(v1 == v2);
+}
+
+bool CLocalItem::IsEncrypted() const
+{ return (Flags & NFileHeader::NFlags::kEncryptedMask) != 0; }
+bool CLocalItem::HasDescriptor() const
+ { return (Flags & NFileHeader::NFlags::kDescriptorUsedMask) != 0; }
+
+bool CLocalItem::IsImplodeBigDictionary() const
+{
+if (CompressionMethod != NFileHeader::NCompressionMethod::kImploded)
+ throw 12312212;
+ return (Flags & NFileHeader::NFlags::kImplodeDictionarySizeMask) != 0;
+}
+
+bool CLocalItem::IsImplodeLiteralsOn() const
+{
+ if (CompressionMethod != NFileHeader::NCompressionMethod::kImploded)
+ throw 12312213;
+ return (Flags & NFileHeader::NFlags::kImplodeLiteralsOnMask) != 0;
+}
+
+static const char *kUnknownAttributes = "Unknown file attributes";
+
+bool CLocalItem::IsDirectory() const
+{
+ return NItemName::HasTailSlash(Name, GetCodePage());
+}
+
+bool CItem::IsDirectory() const
+{
+ if (NItemName::HasTailSlash(Name, GetCodePage()))
+ return true;
+ if (!FromCentral)
+ return false;
+ WORD highAttributes = WORD((ExternalAttributes >> 16 ) & 0xFFFF);
+ switch(MadeByVersion.HostOS)
+ {
+ case NFileHeader::NHostOS::kAMIGA:
+ switch (highAttributes & NFileHeader::NAmigaAttribute::kIFMT)
+ {
+ case NFileHeader::NAmigaAttribute::kIFDIR:
+ return true;
+ case NFileHeader::NAmigaAttribute::kIFREG:
+ return false;
+ default:
+ return false; // change it throw kUnknownAttributes;
+ }
+ case NFileHeader::NHostOS::kFAT:
+ case NFileHeader::NHostOS::kNTFS:
+ case NFileHeader::NHostOS::kHPFS:
+ case NFileHeader::NHostOS::kVFAT:
+ return ((ExternalAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
+ case NFileHeader::NHostOS::kAtari:
+ case NFileHeader::NHostOS::kMac:
+ case NFileHeader::NHostOS::kVMS:
+ case NFileHeader::NHostOS::kVM_CMS:
+ case NFileHeader::NHostOS::kAcorn:
+ case NFileHeader::NHostOS::kMVS:
+ return false; // change it throw kUnknownAttributes;
+ default:
+ /*
+ switch (highAttributes & NFileHeader::NUnixAttribute::kIFMT)
+ {
+ case NFileHeader::NUnixAttribute::kIFDIR:
+ return true;
+ default:
+ return false;
+ }
+ */
+ return false;
+ }
+}
+
+UInt32 CLocalItem::GetWinAttributes() const
+{
+ DWORD winAttributes = 0;
+ if (IsDirectory())
+ winAttributes |= FILE_ATTRIBUTE_DIRECTORY;
+ return winAttributes;
+}
+
+UInt32 CItem::GetWinAttributes() const
+{
+ DWORD winAttributes = 0;
+ switch(MadeByVersion.HostOS)
+ {
+ case NFileHeader::NHostOS::kFAT:
+ case NFileHeader::NHostOS::kNTFS:
+ if (FromCentral)
+ winAttributes = ExternalAttributes;
+ break;
+ default:
+ winAttributes = 0; // must be converted from unix value;
+ }
+ if (IsDirectory()) // test it;
+ winAttributes |= FILE_ATTRIBUTE_DIRECTORY;
+ return winAttributes;
+}
+
+void CLocalItem::SetFlagBits(int startBitNumber, int numBits, int value)
+{
+ UInt16 mask = (UInt16)(((1 << numBits) - 1) << startBitNumber);
+ Flags &= ~mask;
+ Flags |= value << startBitNumber;
+}
+
+void CLocalItem::SetBitMask(int bitMask, bool enable)
+{
+ if(enable)
+ Flags |= bitMask;
+ else
+ Flags &= ~bitMask;
+}
+
+void CLocalItem::SetEncrypted(bool encrypted)
+ { SetBitMask(NFileHeader::NFlags::kEncryptedMask, encrypted); }
+
+}}
diff --git a/CPP/7zip/Archive/Zip/ZipItem.h b/CPP/7zip/Archive/Zip/ZipItem.h
new file mode 100755
index 00000000..765bfd85
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/ZipItem.h
@@ -0,0 +1,191 @@
+// Archive/ZipItem.h
+
+#ifndef __ARCHIVE_ZIP_ITEM_H
+#define __ARCHIVE_ZIP_ITEM_H
+
+#include "Common/Types.h"
+#include "Common/String.h"
+#include "Common/Buffer.h"
+
+#include "ZipHeader.h"
+
+namespace NArchive {
+namespace NZip {
+
+struct CVersion
+{
+ Byte Version;
+ Byte HostOS;
+};
+
+bool operator==(const CVersion &v1, const CVersion &v2);
+bool operator!=(const CVersion &v1, const CVersion &v2);
+
+struct CExtraSubBlock
+{
+ UInt16 ID;
+ CByteBuffer Data;
+};
+
+struct CWzAesExtraField
+{
+ UInt16 VendorVersion; // 0x0001 - AE-1, 0x0002 - AE-2,
+ // UInt16 VendorId; // "AE"
+ Byte Strength; // 1 - 128-bit , 2 - 192-bit , 3 - 256-bit
+ UInt16 Method;
+
+ CWzAesExtraField(): VendorVersion(2), Strength(3), Method(0) {}
+
+ bool NeedCrc() const { return (VendorVersion == 1); }
+
+ bool ParseFromSubBlock(const CExtraSubBlock &sb)
+ {
+ if (sb.ID != NFileHeader::NExtraID::kWzAES)
+ return false;
+ if (sb.Data.GetCapacity() < 7)
+ return false;
+ const Byte *p = (const Byte *)sb.Data;
+ VendorVersion = (((UInt16)p[1]) << 8) | p[0];
+ if (p[2] != 'A' || p[3] != 'E')
+ return false;
+ Strength = p[4];
+ Method = (((UInt16)p[6]) << 16) | p[5];
+ return true;
+ }
+ void SetSubBlock(CExtraSubBlock &sb) const
+ {
+ sb.Data.SetCapacity(7);
+ sb.ID = NFileHeader::NExtraID::kWzAES;
+ Byte *p = (Byte *)sb.Data;
+ p[0] = (Byte)VendorVersion;
+ p[1] = (Byte)(VendorVersion >> 8);
+ p[2] = 'A';
+ p[3] = 'E';
+ p[4] = Strength;
+ p[5] = (Byte)Method;
+ p[6] = (Byte)(Method >> 8);
+ }
+};
+
+struct CExtraBlock
+{
+ CObjectVector<CExtraSubBlock> SubBlocks;
+ void Clear() { SubBlocks.Clear(); }
+ size_t GetSize() const
+ {
+ size_t res = 0;
+ for (int i = 0; i < SubBlocks.Size(); i++)
+ res += SubBlocks[i].Data.GetCapacity() + 2 + 2;
+ return res;
+ }
+ bool GetWzAesField(CWzAesExtraField &aesField) const
+ {
+ // size_t res = 0;
+ for (int i = 0; i < SubBlocks.Size(); i++)
+ if (aesField.ParseFromSubBlock(SubBlocks[i]))
+ return true;
+ return false;
+ }
+
+ bool HasWzAesField() const
+ {
+ CWzAesExtraField aesField;
+ return GetWzAesField(aesField);
+ }
+
+ void RemoveUnknownSubBlocks()
+ {
+ for (int i = SubBlocks.Size() - 1; i >= 0;)
+ {
+ const CExtraSubBlock &subBlock = SubBlocks[i];
+ if (subBlock.ID != NFileHeader::NExtraID::kWzAES)
+ SubBlocks.Delete(i);
+ else
+ i--;
+ }
+ }
+};
+
+
+class CLocalItem
+{
+public:
+ CVersion ExtractVersion;
+ UInt16 Flags;
+ UInt16 CompressionMethod;
+ UInt32 Time;
+ UInt32 FileCRC;
+ UInt64 PackSize;
+ UInt64 UnPackSize;
+
+ AString Name;
+
+ CExtraBlock LocalExtra;
+
+ bool IsEncrypted() const;
+
+ bool IsImplodeBigDictionary() const;
+ bool IsImplodeLiteralsOn() const;
+
+ bool IsDirectory() const;
+ bool IgnoreItem() const { return false; }
+ UInt32 GetWinAttributes() const;
+
+ bool HasDescriptor() const;
+
+private:
+ void SetFlagBits(int startBitNumber, int numBits, int value);
+ void SetBitMask(int bitMask, bool enable);
+public:
+ void ClearFlags() { Flags = 0; }
+ void SetEncrypted(bool encrypted);
+
+ WORD GetCodePage() const
+ {
+ return CP_OEMCP;
+ }
+};
+
+class CItem: public CLocalItem
+{
+public:
+ CVersion MadeByVersion;
+ UInt16 InternalAttributes;
+ UInt32 ExternalAttributes;
+
+ UInt64 LocalHeaderPosition;
+
+ CExtraBlock CentralExtra;
+ CByteBuffer Comment;
+
+ bool FromLocal;
+ bool FromCentral;
+
+ bool IsDirectory() const;
+ UInt32 GetWinAttributes() const;
+
+ bool IsThereCrc() const
+ {
+ if (CompressionMethod == NFileHeader::NCompressionMethod::kWzAES)
+ {
+ CWzAesExtraField aesField;
+ if (CentralExtra.GetWzAesField(aesField))
+ return aesField.NeedCrc();
+ }
+ return true;
+ }
+
+ WORD GetCodePage() const
+ {
+ return (WORD)((MadeByVersion.HostOS == NFileHeader::NHostOS::kFAT
+ || MadeByVersion.HostOS == NFileHeader::NHostOS::kNTFS
+ ) ? CP_OEMCP : CP_ACP);
+ }
+ CItem() : FromLocal(false), FromCentral(false) {}
+};
+
+}}
+
+#endif
+
+
diff --git a/CPP/7zip/Archive/Zip/ZipItemEx.h b/CPP/7zip/Archive/Zip/ZipItemEx.h
new file mode 100755
index 00000000..3cacc0e7
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/ZipItemEx.h
@@ -0,0 +1,29 @@
+// Archive/ZipItemEx.h
+
+#ifndef __ARCHIVE_ZIP_ITEMEX_H
+#define __ARCHIVE_ZIP_ITEMEX_H
+
+#include "ZipHeader.h"
+#include "ZipItem.h"
+
+namespace NArchive {
+namespace NZip {
+
+class CItemEx: public CItem
+{
+public:
+ UInt32 FileHeaderWithNameSize;
+ UInt16 LocalExtraSize;
+
+ UInt64 GetLocalFullSize() const
+ { return FileHeaderWithNameSize + LocalExtraSize + PackSize +
+ (HasDescriptor() ? NFileHeader::kDataDescriptorSize : 0); };
+ UInt64 GetLocalExtraPosition() const
+ { return LocalHeaderPosition + FileHeaderWithNameSize; };
+ UInt64 GetDataPosition() const
+ { return GetLocalExtraPosition() + LocalExtraSize; };
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Zip/ZipOut.cpp b/CPP/7zip/Archive/Zip/ZipOut.cpp
new file mode 100755
index 00000000..7575d320
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/ZipOut.cpp
@@ -0,0 +1,259 @@
+// ZipOut.cpp
+
+#include "StdAfx.h"
+
+#include "ZipOut.h"
+#include "Common/StringConvert.h"
+#include "Common/CRC.h"
+#include "../../Common/OffsetStream.h"
+#include "../../Common/StreamUtils.h"
+
+namespace NArchive {
+namespace NZip {
+
+void COutArchive::Create(IOutStream *outStream)
+{
+ m_Stream = outStream;
+ m_BasePosition = 0;
+}
+
+void COutArchive::MoveBasePosition(UInt64 distanceToMove)
+{
+ m_BasePosition += distanceToMove; // test overflow
+}
+
+void COutArchive::PrepareWriteCompressedDataZip64(UInt16 fileNameLength, bool isZip64, bool aesEncryption)
+{
+ m_IsZip64 = isZip64;
+ m_ExtraSize = isZip64 ? (4 + 8 + 8) : 0;
+ if (aesEncryption)
+ m_ExtraSize += 4 + 7;
+ m_LocalFileHeaderSize = 4 + NFileHeader::kLocalBlockSize + fileNameLength + m_ExtraSize;
+}
+
+void COutArchive::PrepareWriteCompressedData(UInt16 fileNameLength, UInt64 unPackSize, bool aesEncryption)
+{
+ // We test it to 0xF8000000 to support case when compressed size
+ // can be larger than uncompressed size.
+ PrepareWriteCompressedDataZip64(fileNameLength, unPackSize >= 0xF8000000, aesEncryption);
+}
+
+void COutArchive::PrepareWriteCompressedData2(UInt16 fileNameLength, UInt64 unPackSize, UInt64 packSize, bool aesEncryption)
+{
+ bool isUnPack64 = unPackSize >= 0xFFFFFFFF;
+ bool isPack64 = packSize >= 0xFFFFFFFF;
+ bool isZip64 = isPack64 || isUnPack64;
+ PrepareWriteCompressedDataZip64(fileNameLength, isZip64, aesEncryption);
+}
+
+void COutArchive::WriteBytes(const void *buffer, UInt32 size)
+{
+ UInt32 processedSize;
+ if(WriteStream(m_Stream, buffer, size, &processedSize) != S_OK)
+ throw 0;
+ if(processedSize != size)
+ throw 0;
+ m_BasePosition += size;
+}
+
+void COutArchive::WriteByte(Byte b)
+{
+ WriteBytes(&b, 1);
+}
+
+void COutArchive::WriteUInt16(UInt16 value)
+{
+ for (int i = 0; i < 2; i++)
+ {
+ WriteByte((Byte)value);
+ value >>= 8;
+ }
+}
+
+void COutArchive::WriteUInt32(UInt32 value)
+{
+ for (int i = 0; i < 4; i++)
+ {
+ WriteByte((Byte)value);
+ value >>= 8;
+ }
+}
+
+void COutArchive::WriteUInt64(UInt64 value)
+{
+ for (int i = 0; i < 8; i++)
+ {
+ WriteByte((Byte)value);
+ value >>= 8;
+ }
+}
+
+void COutArchive::WriteExtra(const CExtraBlock &extra)
+{
+ if (extra.SubBlocks.Size() != 0)
+ {
+ for (int i = 0; i < extra.SubBlocks.Size(); i++)
+ {
+ const CExtraSubBlock &subBlock = extra.SubBlocks[i];
+ WriteUInt16(subBlock.ID);
+ WriteUInt16((UInt16)subBlock.Data.GetCapacity());
+ WriteBytes(subBlock.Data, (UInt32)subBlock.Data.GetCapacity());
+ }
+ }
+}
+
+HRESULT COutArchive::WriteLocalHeader(const CLocalItem &item)
+{
+ m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL);
+
+ bool isZip64 = m_IsZip64 || item.PackSize >= 0xFFFFFFFF || item.UnPackSize >= 0xFFFFFFFF;
+
+ WriteUInt32(NSignature::kLocalFileHeader);
+ WriteByte(item.ExtractVersion.Version);
+ WriteByte(item.ExtractVersion.HostOS);
+ WriteUInt16(item.Flags);
+ WriteUInt16(item.CompressionMethod);
+ WriteUInt32(item.Time);
+ WriteUInt32(item.FileCRC);
+ WriteUInt32(isZip64 ? 0xFFFFFFFF: (UInt32)item.PackSize);
+ WriteUInt32(isZip64 ? 0xFFFFFFFF: (UInt32)item.UnPackSize);
+ WriteUInt16((UInt16)item.Name.Length());
+ {
+ UInt16 localExtraSize = (UInt16)((isZip64 ? (4 + 16): 0) + item.LocalExtra.GetSize());
+ if (localExtraSize > m_ExtraSize)
+ return E_FAIL;
+ }
+ WriteUInt16((UInt16)m_ExtraSize); // test it;
+ WriteBytes((const char *)item.Name, item.Name.Length());
+
+ UInt32 extraPos = 0;
+ if (isZip64)
+ {
+ extraPos += 4 + 16;
+ WriteUInt16(NFileHeader::NExtraID::kZip64);
+ WriteUInt16(16);
+ WriteUInt64(item.UnPackSize);
+ WriteUInt64(item.PackSize);
+ }
+
+ WriteExtra(item.LocalExtra);
+ extraPos += (UInt32)item.LocalExtra.GetSize();
+ for (; extraPos < m_ExtraSize; extraPos++)
+ WriteByte(0);
+
+ MoveBasePosition(item.PackSize);
+ return m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL);
+}
+
+void COutArchive::WriteCentralHeader(const CItem &item)
+{
+ m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL);
+
+ bool isUnPack64 = item.UnPackSize >= 0xFFFFFFFF;
+ bool isPack64 = item.PackSize >= 0xFFFFFFFF;
+ bool isPosition64 = item.LocalHeaderPosition >= 0xFFFFFFFF;
+ bool isZip64 = isPack64 || isUnPack64 || isPosition64;
+
+ WriteUInt32(NSignature::kCentralFileHeader);
+ WriteByte(item.MadeByVersion.Version);
+ WriteByte(item.MadeByVersion.HostOS);
+ WriteByte(item.ExtractVersion.Version);
+ WriteByte(item.ExtractVersion.HostOS);
+ WriteUInt16(item.Flags);
+ WriteUInt16(item.CompressionMethod);
+ WriteUInt32(item.Time);
+ WriteUInt32(item.FileCRC);
+ WriteUInt32(isPack64 ? 0xFFFFFFFF: (UInt32)item.PackSize);
+ WriteUInt32(isUnPack64 ? 0xFFFFFFFF: (UInt32)item.UnPackSize);
+ WriteUInt16((UInt16)item.Name.Length());
+ UInt16 zip64ExtraSize = (UInt16)((isUnPack64 ? 8: 0) + (isPack64 ? 8: 0) + (isPosition64 ? 8: 0));
+ UInt16 centralExtraSize = (UInt16)(isZip64 ? (4 + zip64ExtraSize) : 0);
+ centralExtraSize = (UInt16)(centralExtraSize + item.CentralExtra.GetSize());
+ WriteUInt16(centralExtraSize); // test it;
+ WriteUInt16((UInt16)item.Comment.GetCapacity());
+ WriteUInt16(0); // DiskNumberStart;
+ WriteUInt16(item.InternalAttributes);
+ WriteUInt32(item.ExternalAttributes);
+ WriteUInt32(isPosition64 ? 0xFFFFFFFF: (UInt32)item.LocalHeaderPosition);
+ WriteBytes((const char *)item.Name, item.Name.Length());
+ if (isZip64)
+ {
+ WriteUInt16(NFileHeader::NExtraID::kZip64);
+ WriteUInt16(zip64ExtraSize);
+ if(isUnPack64)
+ WriteUInt64(item.UnPackSize);
+ if(isPack64)
+ WriteUInt64(item.PackSize);
+ if(isPosition64)
+ WriteUInt64(item.LocalHeaderPosition);
+ }
+ WriteExtra(item.CentralExtra);
+ if (item.Comment.GetCapacity() > 0)
+ WriteBytes(item.Comment, (UInt32)item.Comment.GetCapacity());
+}
+
+void COutArchive::WriteCentralDir(const CObjectVector<CItem> &items, const CByteBuffer &comment)
+{
+ m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL);
+
+ UInt64 cdOffset = GetCurrentPosition();
+ for(int i = 0; i < items.Size(); i++)
+ WriteCentralHeader(items[i]);
+ UInt64 cd64EndOffset = GetCurrentPosition();
+ UInt64 cdSize = cd64EndOffset - cdOffset;
+ bool cdOffset64 = cdOffset >= 0xFFFFFFFF;
+ bool cdSize64 = cdSize >= 0xFFFFFFFF;
+ bool items64 = items.Size() >= 0xFFFF;
+ bool isZip64 = (cdOffset64 || cdSize64 || items64);
+
+ if (isZip64)
+ {
+ WriteUInt32(NSignature::kZip64EndOfCentralDir);
+ WriteUInt64(kZip64EcdSize); // ThisDiskNumber = 0;
+ WriteUInt16(45); // version
+ WriteUInt16(45); // version
+ WriteUInt32(0); // ThisDiskNumber = 0;
+ WriteUInt32(0); // StartCentralDirectoryDiskNumber;;
+ WriteUInt64((UInt64)items.Size());
+ WriteUInt64((UInt64)items.Size());
+ WriteUInt64((UInt64)cdSize);
+ WriteUInt64((UInt64)cdOffset);
+
+ WriteUInt32(NSignature::kZip64EndOfCentralDirLocator);
+ WriteUInt32(0); // number of the disk with the start of the zip64 end of central directory
+ WriteUInt64(cd64EndOffset);
+ WriteUInt32(1); // total number of disks
+ }
+ WriteUInt32(NSignature::kEndOfCentralDir);
+ WriteUInt16(0); // ThisDiskNumber = 0;
+ WriteUInt16(0); // StartCentralDirectoryDiskNumber;
+ WriteUInt16((UInt16)(items64 ? 0xFFFF: items.Size()));
+ WriteUInt16((UInt16)(items64 ? 0xFFFF: items.Size()));
+ WriteUInt32(cdSize64 ? 0xFFFFFFFF: (UInt32)cdSize);
+ WriteUInt32(cdOffset64 ? 0xFFFFFFFF: (UInt32)cdOffset);
+ UInt16 commentSize = (UInt16)comment.GetCapacity();
+ WriteUInt16(commentSize);
+ if (commentSize > 0)
+ WriteBytes((const Byte *)comment, commentSize);
+}
+
+void COutArchive::CreateStreamForCompressing(IOutStream **outStream)
+{
+ COffsetOutStream *streamSpec = new COffsetOutStream;
+ CMyComPtr<IOutStream> tempStream(streamSpec);
+ streamSpec->Init(m_Stream, m_BasePosition + m_LocalFileHeaderSize);
+ *outStream = tempStream.Detach();
+}
+
+void COutArchive::SeekToPackedDataPosition()
+{
+ m_Stream->Seek(m_BasePosition + m_LocalFileHeaderSize, STREAM_SEEK_SET, NULL);
+}
+
+void COutArchive::CreateStreamForCopying(ISequentialOutStream **outStream)
+{
+ CMyComPtr<ISequentialOutStream> tempStream(m_Stream);
+ *outStream = tempStream.Detach();
+}
+
+}}
diff --git a/CPP/7zip/Archive/Zip/ZipOut.h b/CPP/7zip/Archive/Zip/ZipOut.h
new file mode 100755
index 00000000..e08c306e
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/ZipOut.h
@@ -0,0 +1,51 @@
+// ZipOut.h
+
+#ifndef __ZIP_OUT_H
+#define __ZIP_OUT_H
+
+#include "Common/MyCom.h"
+
+#include "../../IStream.h"
+
+#include "ZipItem.h"
+
+namespace NArchive {
+namespace NZip {
+
+class COutArchive
+{
+ CMyComPtr<IOutStream> m_Stream;
+
+ UInt64 m_BasePosition;
+ UInt32 m_LocalFileHeaderSize;
+ UInt32 m_ExtraSize;
+ bool m_IsZip64;
+
+ void WriteBytes(const void *buffer, UInt32 size);
+ void WriteByte(Byte b);
+ void WriteUInt16(UInt16 value);
+ void WriteUInt32(UInt32 value);
+ void WriteUInt64(UInt64 value);
+
+ void WriteExtraHeader(const CItem &item);
+ void WriteCentralHeader(const CItem &item);
+ void WriteExtra(const CExtraBlock &extra);
+public:
+ void Create(IOutStream *outStream);
+ void MoveBasePosition(UInt64 distanceToMove);
+ UInt64 GetCurrentPosition() const { return m_BasePosition; };
+ void PrepareWriteCompressedDataZip64(UInt16 fileNameLength, bool isZip64, bool aesEncryption);
+ void PrepareWriteCompressedData(UInt16 fileNameLength, UInt64 unPackSize, bool aesEncryption);
+ void PrepareWriteCompressedData2(UInt16 fileNameLength, UInt64 unPackSize, UInt64 packSize, bool aesEncryption);
+ HRESULT WriteLocalHeader(const CLocalItem &item);
+
+ void WriteCentralDir(const CObjectVector<CItem> &items, const CByteBuffer &comment);
+
+ void CreateStreamForCompressing(IOutStream **outStream);
+ void CreateStreamForCopying(ISequentialOutStream **outStream);
+ void SeekToPackedDataPosition();
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.cpp b/CPP/7zip/Archive/Zip/ZipUpdate.cpp
new file mode 100755
index 00000000..f66fcef9
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/ZipUpdate.cpp
@@ -0,0 +1,734 @@
+// ZipUpdate.cpp
+
+#include "StdAfx.h"
+
+#include <stdio.h>
+
+#include "ZipUpdate.h"
+#include "ZipAddCommon.h"
+#include "ZipOut.h"
+
+#include "Common/Defs.h"
+#include "Common/AutoPtr.h"
+#include "Common/StringConvert.h"
+#include "Windows/Defs.h"
+#include "Windows/Thread.h"
+
+#include "../../Common/ProgressUtils.h"
+#ifdef COMPRESS_MT
+#include "../../Common/ProgressMt.h"
+#endif
+#include "../../Common/LimitedStreams.h"
+#include "../../Common/OutMemStream.h"
+
+#include "../../Compress/Copy/CopyCoder.h"
+
+using namespace NWindows;
+using namespace NSynchronization;
+
+namespace NArchive {
+namespace NZip {
+
+class CCriticalSectionLock2
+{
+ CCriticalSection *_object;
+ void Unlock() { if (_object != 0) _object->Leave(); }
+public:
+ CCriticalSectionLock2(): _object(0) {}
+ void Set(CCriticalSection &object) { _object = &object; _object->Enter(); }
+ ~CCriticalSectionLock2() { Unlock(); }
+};
+
+static const Byte kMadeByHostOS = NFileHeader::NHostOS::kFAT;
+static const Byte kExtractHostOS = NFileHeader::NHostOS::kFAT;
+
+static const Byte kMethodForDirectory = NFileHeader::NCompressionMethod::kStored;
+static const Byte kExtractVersionForDirectory = NFileHeader::NCompressionMethod::kStoreExtractVersion;
+
+static HRESULT CopyBlockToArchive(ISequentialInStream *inStream,
+ COutArchive &outArchive, ICompressProgressInfo *progress)
+{
+ CMyComPtr<ISequentialOutStream> outStream;
+ outArchive.CreateStreamForCopying(&outStream);
+ CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
+ return copyCoder->Code(inStream, outStream, NULL, NULL, progress);
+}
+
+static HRESULT WriteRange(IInStream *inStream, COutArchive &outArchive,
+ const CUpdateRange &range, ICompressProgressInfo *progress)
+{
+ UInt64 position;
+ RINOK(inStream->Seek(range.Position, STREAM_SEEK_SET, &position));
+
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+ CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);
+ streamSpec->SetStream(inStream);
+ streamSpec->Init(range.Size);
+
+ RINOK(CopyBlockToArchive(inStreamLimited, outArchive, progress));
+ return progress->SetRatioInfo(&range.Size, &range.Size);
+}
+
+static void SetFileHeader(
+ COutArchive &archive,
+ const CCompressionMethodMode &options,
+ const CUpdateItem &updateItem,
+ CItem &item)
+{
+ item.UnPackSize = updateItem.Size;
+ bool isDirectory;
+
+ if (updateItem.NewProperties)
+ {
+ isDirectory = updateItem.IsDirectory;
+ item.Name = updateItem.Name;
+ item.ExternalAttributes = updateItem.Attributes;
+ item.Time = updateItem.Time;
+ }
+ else
+ isDirectory = item.IsDirectory();
+
+ item.LocalHeaderPosition = archive.GetCurrentPosition();
+ item.MadeByVersion.HostOS = kMadeByHostOS;
+ item.MadeByVersion.Version = NFileHeader::NCompressionMethod::kMadeByProgramVersion;
+
+ item.ExtractVersion.HostOS = kExtractHostOS;
+
+ item.InternalAttributes = 0; // test it
+ item.ClearFlags();
+ item.SetEncrypted(!isDirectory && options.PasswordIsDefined);
+ if (isDirectory)
+ {
+ item.ExtractVersion.Version = kExtractVersionForDirectory;
+ item.CompressionMethod = kMethodForDirectory;
+ item.PackSize = 0;
+ item.FileCRC = 0; // test it
+ }
+}
+
+static void SetItemInfoFromCompressingResult(const CCompressingResult &compressingResult,
+ bool isAesMode, Byte aesKeyMode, CItem &item)
+{
+ item.ExtractVersion.Version = compressingResult.ExtractVersion;
+ item.CompressionMethod = compressingResult.Method;
+ item.FileCRC = compressingResult.CRC;
+ item.UnPackSize = compressingResult.UnpackSize;
+ item.PackSize = compressingResult.PackSize;
+
+ item.LocalExtra.Clear();
+ item.CentralExtra.Clear();
+
+ if (isAesMode)
+ {
+ CWzAesExtraField wzAesField;
+ wzAesField.Strength = aesKeyMode;
+ wzAesField.Method = compressingResult.Method;
+ item.CompressionMethod = NFileHeader::NCompressionMethod::kWzAES;
+ item.FileCRC = 0;
+ CExtraSubBlock sb;
+ wzAesField.SetSubBlock(sb);
+ item.LocalExtra.SubBlocks.Add(sb);
+ item.CentralExtra.SubBlocks.Add(sb);
+ }
+}
+
+#ifdef COMPRESS_MT
+
+static DWORD WINAPI CoderThread(void *threadCoderInfo);
+
+struct CThreadInfo
+{
+ NWindows::CThread Thread;
+ CAutoResetEvent *CompressEvent;
+ CAutoResetEvent *CompressionCompletedEvent;
+ bool ExitThread;
+
+ CMtCompressProgress *ProgressSpec;
+ CMyComPtr<ICompressProgressInfo> Progress;
+
+ COutMemStream *OutStreamSpec;
+ CMyComPtr<IOutStream> OutStream;
+ CMyComPtr<ISequentialInStream> InStream;
+
+ CAddCommon Coder;
+ HRESULT Result;
+ CCompressingResult CompressingResult;
+
+ bool IsFree;
+ UInt32 UpdateIndex;
+
+ CThreadInfo(const CCompressionMethodMode &options):
+ CompressEvent(NULL),
+ CompressionCompletedEvent(NULL),
+ ExitThread(false),
+ ProgressSpec(0),
+ OutStreamSpec(0),
+ Coder(options)
+ {}
+
+ void CreateEvents()
+ {
+ CompressEvent = new CAutoResetEvent(false);
+ CompressionCompletedEvent = new CAutoResetEvent(false);
+ }
+ bool CreateThread() { return Thread.Create(CoderThread, this); }
+ ~CThreadInfo();
+
+ void WaitAndCode();
+ void StopWaitClose()
+ {
+ ExitThread = true;
+ if (OutStreamSpec != 0)
+ OutStreamSpec->StopWriting(E_ABORT);
+ if (CompressEvent != NULL)
+ CompressEvent->Set();
+ Thread.Wait();
+ Thread.Close();
+ }
+
+};
+
+CThreadInfo::~CThreadInfo()
+{
+ if (CompressEvent != NULL)
+ delete CompressEvent;
+ if (CompressionCompletedEvent != NULL)
+ delete CompressionCompletedEvent;
+}
+
+void CThreadInfo::WaitAndCode()
+{
+ for (;;)
+ {
+ CompressEvent->Lock();
+ if (ExitThread)
+ return;
+ Result = Coder.Compress(InStream, OutStream, Progress, CompressingResult);
+ if (Result == S_OK && Progress)
+ Result = Progress->SetRatioInfo(&CompressingResult.UnpackSize, &CompressingResult.PackSize);
+ CompressionCompletedEvent->Set();
+ }
+}
+
+static DWORD WINAPI CoderThread(void *threadCoderInfo)
+{
+ ((CThreadInfo *)threadCoderInfo)->WaitAndCode();
+ return 0;
+}
+
+class CThreads
+{
+public:
+ CObjectVector<CThreadInfo> Threads;
+ ~CThreads()
+ {
+ for (int i = 0; i < Threads.Size(); i++)
+ Threads[i].StopWaitClose();
+ }
+};
+
+struct CMemBlocks2: public CMemLockBlocks
+{
+ CCompressingResult CompressingResult;
+ bool Defined;
+ bool Skip;
+ CMemBlocks2(): Defined(false), Skip(false) {}
+};
+
+class CMemRefs
+{
+public:
+ CMemBlockManagerMt *Manager;
+ CObjectVector<CMemBlocks2> Refs;
+ CMemRefs(CMemBlockManagerMt *manager): Manager(manager) {} ;
+ ~CMemRefs()
+ {
+ for (int i = 0; i < Refs.Size(); i++)
+ Refs[i].FreeOpt(Manager);
+ }
+};
+
+#endif
+
+
+static HRESULT UpdateItemOldData(COutArchive &archive,
+ IInStream *inStream,
+ const CUpdateItem &updateItem, CItemEx &item, ICompressProgressInfo *progress,
+ UInt64 &complexity)
+{
+ if (updateItem.NewProperties)
+ {
+ if (item.HasDescriptor())
+ return E_NOTIMPL;
+
+ // use old name size.
+ // CUpdateRange range(item.GetLocalExtraPosition(), item.LocalExtraSize + item.PackSize);
+ CUpdateRange range(item.GetDataPosition(), item.PackSize);
+
+ // item.ExternalAttributes = updateItem.Attributes;
+ // Test it
+ item.Name = updateItem.Name;
+ item.Time = updateItem.Time;
+ item.CentralExtra.RemoveUnknownSubBlocks();
+ item.LocalExtra.RemoveUnknownSubBlocks();
+
+ archive.PrepareWriteCompressedData2((UInt16)item.Name.Length(), item.UnPackSize, item.PackSize, item.LocalExtra.HasWzAesField());
+ item.LocalHeaderPosition = archive.GetCurrentPosition();
+ archive.SeekToPackedDataPosition();
+ RINOK(WriteRange(inStream, archive, range, progress));
+ complexity += range.Size;
+ archive.WriteLocalHeader(item);
+ }
+ else
+ {
+ CUpdateRange range(item.LocalHeaderPosition, item.GetLocalFullSize());
+
+ // set new header position
+ item.LocalHeaderPosition = archive.GetCurrentPosition();
+
+ RINOK(WriteRange(inStream, archive, range, progress));
+ complexity += range.Size;
+ archive.MoveBasePosition(range.Size);
+ }
+ return S_OK;
+}
+
+static HRESULT WriteDirHeader(COutArchive &archive, const CCompressionMethodMode *options,
+ const CUpdateItem &updateItem, CItemEx &item)
+{
+ SetFileHeader(archive, *options, updateItem, item);
+ archive.PrepareWriteCompressedData((UInt16)item.Name.Length(), updateItem.Size, options->IsAesMode);
+ return archive.WriteLocalHeader(item);
+}
+
+static HRESULT Update2St(COutArchive &archive,
+ CInArchive *inArchive,
+ IInStream *inStream,
+ const CObjectVector<CItemEx> &inputItems,
+ const CObjectVector<CUpdateItem> &updateItems,
+ const CCompressionMethodMode *options,
+ const CByteBuffer &comment,
+ IArchiveUpdateCallback *updateCallback)
+{
+ CLocalProgress *localProgressSpec = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
+ localProgressSpec->Init(updateCallback, true);
+
+ CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
+ CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
+
+ CAddCommon compressor(*options);
+
+ CObjectVector<CItem> items;
+ UInt64 complexity = 0;
+
+ for (int itemIndex = 0; itemIndex < updateItems.Size(); itemIndex++)
+ {
+ RINOK(updateCallback->SetCompleted(&complexity));
+ const CUpdateItem &updateItem = updateItems[itemIndex];
+ CItemEx item;
+ if (!updateItem.NewProperties || !updateItem.NewData)
+ {
+ item = inputItems[updateItem.IndexInArchive];
+ if (inArchive->ReadLocalItemAfterCdItemFull(item) != S_OK)
+ return E_NOTIMPL;
+ }
+
+ if (updateItem.NewData)
+ {
+ bool isDirectory = ((updateItem.NewProperties) ? updateItem.IsDirectory : item.IsDirectory());
+ if (isDirectory)
+ {
+ RINOK(WriteDirHeader(archive, options, updateItem, item));
+ }
+ else
+ {
+ CMyComPtr<ISequentialInStream> fileInStream;
+ HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream);
+ if (res == S_FALSE)
+ {
+ complexity += updateItem.Size + NFileHeader::kLocalBlockSize;
+ RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
+ continue;
+ }
+ RINOK(res);
+
+ // file Size can be 64-bit !!!
+ SetFileHeader(archive, *options, updateItem, item);
+ archive.PrepareWriteCompressedData((UInt16)item.Name.Length(), updateItem.Size, options->IsAesMode);
+ CCompressingResult compressingResult;
+ CMyComPtr<IOutStream> outStream;
+ archive.CreateStreamForCompressing(&outStream);
+ localCompressProgressSpec->Init(localProgress, &complexity, NULL);
+ RINOK(compressor.Compress(fileInStream, outStream, compressProgress, compressingResult));
+ SetItemInfoFromCompressingResult(compressingResult, options->IsAesMode, options->AesKeyMode, item);
+ RINOK(archive.WriteLocalHeader(item));
+ RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
+ complexity += item.UnPackSize;
+ }
+ }
+ else
+ {
+ localCompressProgressSpec->Init(localProgress, &complexity, NULL);
+ RINOK(UpdateItemOldData(archive, inStream, updateItem, item, compressProgress, complexity));
+ }
+ items.Add(item);
+ complexity += NFileHeader::kLocalBlockSize;
+ }
+ archive.WriteCentralDir(items, comment);
+ return S_OK;
+}
+
+static HRESULT Update2(COutArchive &archive,
+ CInArchive *inArchive,
+ IInStream *inStream,
+ const CObjectVector<CItemEx> &inputItems,
+ const CObjectVector<CUpdateItem> &updateItems,
+ const CCompressionMethodMode *options,
+ const CByteBuffer &comment,
+ IArchiveUpdateCallback *updateCallback)
+{
+ UInt64 complexity = 0;
+ UInt64 numFilesToCompress = 0;
+ UInt64 numBytesToCompress = 0;
+
+ int i;
+ for(i = 0; i < updateItems.Size(); i++)
+ {
+ const CUpdateItem &updateItem = updateItems[i];
+ if (updateItem.NewData)
+ {
+ complexity += updateItem.Size;
+ numBytesToCompress += updateItem.Size;
+ numFilesToCompress++;
+ /*
+ if (updateItem.Commented)
+ complexity += updateItem.CommentRange.Size;
+ */
+ }
+ else
+ {
+ CItemEx inputItem = inputItems[updateItem.IndexInArchive];
+ if (inArchive->ReadLocalItemAfterCdItemFull(inputItem) != S_OK)
+ return E_NOTIMPL;
+ complexity += inputItem.GetLocalFullSize();
+ // complexity += inputItem.GetCentralExtraPlusCommentSize();
+ }
+ complexity += NFileHeader::kLocalBlockSize;
+ complexity += NFileHeader::kCentralBlockSize;
+ }
+
+ if (comment != 0)
+ complexity += comment.GetCapacity();
+ complexity++; // end of central
+ updateCallback->SetTotal(complexity);
+
+ CAddCommon compressor(*options);
+
+ complexity = 0;
+
+ #ifdef COMPRESS_MT
+
+ const size_t kNumMaxThreads = (1 << 10);
+ UInt32 numThreads = options->NumThreads;
+ if (numThreads > kNumMaxThreads)
+ numThreads = kNumMaxThreads;
+
+ const size_t kMemPerThread = (1 << 25);
+ const size_t kBlockSize = 1 << 16;
+
+ CCompressionMethodMode options2;
+ if (options != 0)
+ options2 = *options;
+
+ bool mtMode = ((options != 0) && (numThreads > 1));
+
+ if (numFilesToCompress <= 1)
+ mtMode = false;
+
+ if (mtMode)
+ {
+ Byte method = options->MethodSequence.Front();
+ if (method == NFileHeader::NCompressionMethod::kStored && !options->PasswordIsDefined)
+ mtMode = false;
+ if (method == NFileHeader::NCompressionMethod::kBZip2)
+ {
+ UInt64 averageSize = numBytesToCompress / numFilesToCompress;
+ UInt32 blockSize = options->DicSize;
+ if (blockSize == 0)
+ blockSize = 1;
+ UInt64 averageNumberOfBlocks = averageSize / blockSize;
+ UInt32 numBZip2Threads = 32;
+ if (averageNumberOfBlocks < numBZip2Threads)
+ numBZip2Threads = (UInt32)averageNumberOfBlocks;
+ if (numBZip2Threads < 1)
+ numBZip2Threads = 1;
+ numThreads = numThreads / numBZip2Threads;
+ options2.NumThreads = numBZip2Threads;
+ if (numThreads <= 1)
+ mtMode = false;
+ }
+ }
+
+ if (!mtMode)
+ #endif
+ return Update2St(archive, inArchive,inStream,
+ inputItems, updateItems, options, comment, updateCallback);
+
+
+ #ifdef COMPRESS_MT
+
+ CObjectVector<CItem> items;
+
+ CLocalProgress *localProgressSpec = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
+ localProgressSpec->Init(updateCallback, true);
+
+ CMtCompressProgressMixer mtCompressProgressMixer;
+ mtCompressProgressMixer.Init(numThreads + 1, localProgress);
+
+ // we need one item for main stream
+ CMtCompressProgress *progressMainSpec = new CMtCompressProgress();
+ CMyComPtr<ICompressProgressInfo> progressMain = progressMainSpec;
+ progressMainSpec->Init(&mtCompressProgressMixer, (int)numThreads);
+
+ CMemBlockManagerMt memManager(kBlockSize);
+ CMemRefs refs(&memManager);
+
+ CThreads threads;
+ CRecordVector<HANDLE> compressingCompletedEvents;
+ CRecordVector<int> threadIndices; // list threads in order of updateItems
+
+ {
+ if (!memManager.AllocateSpaceAlways((size_t)numThreads * (kMemPerThread / kBlockSize)))
+ return E_OUTOFMEMORY;
+ for(i = 0; i < updateItems.Size(); i++)
+ refs.Refs.Add(CMemBlocks2());
+
+ UInt32 i;
+ for (i = 0; i < numThreads; i++)
+ threads.Threads.Add(CThreadInfo(options2));
+
+ for (i = 0; i < numThreads; i++)
+ {
+ CThreadInfo &threadInfo = threads.Threads[i];
+ threadInfo.CreateEvents();
+ threadInfo.OutStreamSpec = new COutMemStream(&memManager);
+ threadInfo.OutStream = threadInfo.OutStreamSpec;
+ threadInfo.IsFree = true;
+ threadInfo.ProgressSpec = new CMtCompressProgress();
+ threadInfo.Progress = threadInfo.ProgressSpec;
+ threadInfo.ProgressSpec->Init(&mtCompressProgressMixer, (int)i);
+ if (!threadInfo.CreateThread())
+ return ::GetLastError();
+ }
+ }
+ int mtItemIndex = 0;
+
+ int itemIndex = 0;
+ int lastRealStreamItemIndex = -1;
+
+ while (itemIndex < updateItems.Size())
+ {
+ if ((UInt32)threadIndices.Size() < numThreads && mtItemIndex < updateItems.Size())
+ {
+ const CUpdateItem &updateItem = updateItems[mtItemIndex++];
+ if (!updateItem.NewData)
+ continue;
+ CItemEx item;
+ if (updateItem.NewProperties)
+ {
+ if (updateItem.IsDirectory)
+ continue;
+ }
+ else
+ {
+ item = inputItems[updateItem.IndexInArchive];
+ if (inArchive->ReadLocalItemAfterCdItemFull(item) != S_OK)
+ return E_NOTIMPL;
+ if (item.IsDirectory())
+ continue;
+ }
+ CMyComPtr<ISequentialInStream> fileInStream;
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(mtCompressProgressMixer.CriticalSection);
+ HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream);
+ if (res == S_FALSE)
+ {
+ complexity += updateItem.Size;
+ complexity++;
+ RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
+ refs.Refs[mtItemIndex - 1].Skip = true;
+ continue;
+ }
+ RINOK(res);
+ RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
+ }
+
+ for (UInt32 i = 0; i < numThreads; i++)
+ {
+ CThreadInfo &threadInfo = threads.Threads[i];
+ if (threadInfo.IsFree)
+ {
+ threadInfo.IsFree = false;
+ threadInfo.InStream = fileInStream;
+ threadInfo.OutStreamSpec->Init();
+ threadInfo.ProgressSpec->Reinit();
+ threadInfo.CompressEvent->Set();
+ threadInfo.UpdateIndex = mtItemIndex - 1;
+
+ compressingCompletedEvents.Add(*threadInfo.CompressionCompletedEvent);
+ threadIndices.Add(i);
+ break;
+ }
+ }
+ continue;
+ }
+
+ if (refs.Refs[itemIndex].Skip)
+ {
+ itemIndex++;
+ continue;
+ }
+
+ const CUpdateItem &updateItem = updateItems[itemIndex];
+
+ CItemEx item;
+ if (!updateItem.NewProperties || !updateItem.NewData)
+ {
+ item = inputItems[updateItem.IndexInArchive];
+ if (inArchive->ReadLocalItemAfterCdItemFull(item) != S_OK)
+ return E_NOTIMPL;
+ }
+
+ if (updateItem.NewData)
+ {
+ bool isDirectory = ((updateItem.NewProperties) ? updateItem.IsDirectory : item.IsDirectory());
+ if (isDirectory)
+ {
+ RINOK(WriteDirHeader(archive, options, updateItem, item));
+ }
+ else
+ {
+ if (lastRealStreamItemIndex < itemIndex)
+ {
+ lastRealStreamItemIndex = itemIndex;
+ SetFileHeader(archive, *options, updateItem, item);
+ // file Size can be 64-bit !!!
+ archive.PrepareWriteCompressedData((UInt16)item.Name.Length(), updateItem.Size, options->IsAesMode);
+ }
+
+ CMemBlocks2 &memRef = refs.Refs[itemIndex];
+ if (memRef.Defined)
+ {
+ CMyComPtr<IOutStream> outStream;
+ archive.CreateStreamForCompressing(&outStream);
+ memRef.WriteToStream(memManager.GetBlockSize(), outStream);
+ SetItemInfoFromCompressingResult(memRef.CompressingResult,
+ options->IsAesMode, options->AesKeyMode, item);
+ SetFileHeader(archive, *options, updateItem, item);
+ RINOK(archive.WriteLocalHeader(item));
+ complexity += item.UnPackSize;
+ // RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
+ memRef.FreeOpt(&memManager);
+ }
+ else
+ {
+ {
+ CThreadInfo &thread = threads.Threads[threadIndices.Front()];
+ if (!thread.OutStreamSpec->WasUnlockEventSent())
+ {
+ CMyComPtr<IOutStream> outStream;
+ archive.CreateStreamForCompressing(&outStream);
+ thread.OutStreamSpec->SetOutStream(outStream);
+ thread.OutStreamSpec->SetRealStreamMode();
+ }
+ }
+
+ DWORD result = ::WaitForMultipleObjects(compressingCompletedEvents.Size(),
+ &compressingCompletedEvents.Front(), FALSE, INFINITE);
+ int t = (int)(result - WAIT_OBJECT_0);
+ CThreadInfo &threadInfo = threads.Threads[threadIndices[t]];
+ threadInfo.InStream.Release();
+ threadInfo.IsFree = true;
+ RINOK(threadInfo.Result);
+ threadIndices.Delete(t);
+ compressingCompletedEvents.Delete(t);
+ if (t == 0)
+ {
+ RINOK(threadInfo.OutStreamSpec->WriteToRealStream());
+ threadInfo.OutStreamSpec->ReleaseOutStream();
+ SetItemInfoFromCompressingResult(threadInfo.CompressingResult,
+ options->IsAesMode, options->AesKeyMode, item);
+ SetFileHeader(archive, *options, updateItem, item);
+ RINOK(archive.WriteLocalHeader(item));
+ complexity += item.UnPackSize;
+ }
+ else
+ {
+ CMemBlocks2 &memRef = refs.Refs[threadInfo.UpdateIndex];
+ threadInfo.OutStreamSpec->DetachData(memRef);
+ memRef.CompressingResult = threadInfo.CompressingResult;
+ memRef.Defined = true;
+ continue;
+ }
+ }
+ }
+ }
+ else
+ {
+ progressMainSpec->Reinit();
+ RINOK(UpdateItemOldData(archive, inStream, updateItem, item, progressMain, complexity));
+ }
+ items.Add(item);
+ complexity += NFileHeader::kLocalBlockSize;
+ itemIndex++;
+ }
+ archive.WriteCentralDir(items, comment);
+ return S_OK;
+ #endif
+}
+
+HRESULT Update(
+ const CObjectVector<CItemEx> &inputItems,
+ const CObjectVector<CUpdateItem> &updateItems,
+ ISequentialOutStream *seqOutStream,
+ CInArchive *inArchive,
+ CCompressionMethodMode *compressionMethodMode,
+ IArchiveUpdateCallback *updateCallback)
+{
+ CMyComPtr<IOutStream> outStream;
+ RINOK(seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStream));
+ if (!outStream)
+ return E_NOTIMPL;
+
+ CInArchiveInfo archiveInfo;
+ if(inArchive != 0)
+ {
+ inArchive->GetArchiveInfo(archiveInfo);
+ if (archiveInfo.Base != 0)
+ return E_NOTIMPL;
+ }
+ else
+ archiveInfo.StartPosition = 0;
+
+ COutArchive outArchive;
+ outArchive.Create(outStream);
+ if (archiveInfo.StartPosition > 0)
+ {
+ CMyComPtr<ISequentialInStream> inStream;
+ inStream.Attach(inArchive->CreateLimitedStream(0, archiveInfo.StartPosition));
+ RINOK(CopyBlockToArchive(inStream, outArchive, NULL));
+ outArchive.MoveBasePosition(archiveInfo.StartPosition);
+ }
+ CMyComPtr<IInStream> inStream;
+ if(inArchive != 0)
+ inStream.Attach(inArchive->CreateStream());
+
+ return Update2(outArchive, inArchive, inStream,
+ inputItems, updateItems,
+ compressionMethodMode,
+ archiveInfo.Comment, updateCallback);
+}
+
+}}
diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.h b/CPP/7zip/Archive/Zip/ZipUpdate.h
new file mode 100755
index 00000000..d846b05f
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/ZipUpdate.h
@@ -0,0 +1,52 @@
+// Zip/Update.h
+
+#ifndef __ZIP_UPDATE_H
+#define __ZIP_UPDATE_H
+
+#include "Common/Vector.h"
+#include "Common/Types.h"
+
+#include "../../ICoder.h"
+#include "../IArchive.h"
+
+#include "ZipCompressionMode.h"
+#include "ZipIn.h"
+
+namespace NArchive {
+namespace NZip {
+
+struct CUpdateRange
+{
+ UInt64 Position;
+ UInt64 Size;
+ CUpdateRange() {};
+ CUpdateRange(UInt64 position, UInt64 size): Position(position), Size(size) {};
+};
+
+struct CUpdateItem
+{
+ bool NewData;
+ bool NewProperties;
+ bool IsDirectory;
+ int IndexInArchive;
+ int IndexInClient;
+ UInt32 Attributes;
+ UInt32 Time;
+ UInt64 Size;
+ AString Name;
+ // bool Commented;
+ // CUpdateRange CommentRange;
+ CUpdateItem(): Size(0) {}
+};
+
+HRESULT Update(
+ const CObjectVector<CItemEx> &inputItems,
+ const CObjectVector<CUpdateItem> &updateItems,
+ ISequentialOutStream *seqOutStream,
+ CInArchive *inArchive,
+ CCompressionMethodMode *compressionMethodMode,
+ IArchiveUpdateCallback *updateCallback);
+
+}}
+
+#endif
diff --git a/CPP/7zip/Archive/Zip/makefile b/CPP/7zip/Archive/Zip/makefile
new file mode 100755
index 00000000..eaf1031f
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/makefile
@@ -0,0 +1,124 @@
+PROG = zip.dll
+DEF_FILE = ../Archive.def
+CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_MT
+LIBS = $(LIBS) oleaut32.lib user32.lib
+
+ZIP_OBJS = \
+ $O\DllExports.obj \
+ $O\ZipAddCommon.obj \
+ $O\ZipHandler.obj \
+ $O\ZipHandlerOut.obj \
+ $O\ZipHeader.obj \
+ $O\ZipIn.obj \
+ $O\ZipItem.obj \
+ $O\ZipOut.obj \
+ $O\ZipUpdate.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\CRC.obj \
+ $O\IntToString.obj \
+ $O\NewHandler.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\Vector.obj \
+
+WIN_OBJS = \
+ $O\DLL.obj \
+ $O\FileFind.obj \
+ $O\PropVariant.obj \
+ $O\Synchronization.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\InBuffer.obj \
+ $O\LimitedStreams.obj \
+ $O\LSBFDecoder.obj \
+ $O\MemBlocks.obj \
+ $O\OffsetStream.obj \
+ $O\OutBuffer.obj \
+ $O\OutMemStream.obj \
+ $O\ProgressMt.obj \
+ $O\ProgressUtils.obj \
+ $O\StreamObjects.obj \
+ $O\StreamUtils.obj \
+
+AR_COMMON_OBJS = \
+ $O\CodecsPath.obj \
+ $O\CoderLoader.obj \
+ $O\FilterCoder.obj \
+ $O\InStreamWithCRC.obj \
+ $O\ItemNameUtils.obj \
+ $O\OutStreamWithCRC.obj \
+ $O\ParseProperties.obj \
+
+7Z_OBJS = \
+ $O\7zMethodID.obj \
+ $O\7zMethods.obj \
+
+IMPLODE_OBJS = \
+ $O\ImplodeDecoder.obj \
+ $O\ImplodeHuffmanDecoder.obj \
+
+SHRINK_OBJS = \
+ $O\ShrinkDecoder.obj \
+
+CRYPTO_HASH_OBJS = \
+ $O\HmacSha1.obj \
+ $O\Pbkdf2HmacSha1.obj \
+ $O\RandGen.obj \
+ $O\Sha1.obj \
+
+CRYPTO_WZAES_OBJS = \
+ $O\WzAES.obj \
+
+CRYPTO_ZIP_OBJS = \
+ $O\ZipCipher.obj \
+ $O\ZipCrypto.obj \
+
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(ZIP_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $(7Z_OBJS) \
+ $(CRYPTO_HASH_OBJS) \
+ $(CRYPTO_WZAES_OBJS) \
+ $(CRYPTO_ZIP_OBJS) \
+ $(IMPLODE_OBJS) \
+ $(SHRINK_OBJS) \
+ $O\CopyCoder.obj \
+ $O\LZOutWindow.obj \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(ZIP_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)
+$(7Z_OBJS): ../7z/$(*B).cpp
+ $(COMPL)
+$(CRYPTO_HASH_OBJS): ../../Crypto/Hash/$(*B).cpp
+ $(COMPL_O2)
+$(CRYPTO_ZIP_OBJS): ../../Crypto/Zip/$(*B).cpp
+ $(COMPL)
+$(CRYPTO_WZAES_OBJS): ../../Crypto/WzAES/$(*B).cpp
+ $(COMPL_O2)
+$(IMPLODE_OBJS): ../../Compress/Implode/$(*B).cpp
+ $(COMPL)
+$(SHRINK_OBJS): ../../Compress/Shrink/$(*B).cpp
+ $(COMPL)
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
+$O\LZOutWindow.obj: ../../Compress/LZ/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/Archive/Zip/resource.rc b/CPP/7zip/Archive/Zip/resource.rc
new file mode 100755
index 00000000..388f349e
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/resource.rc
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("Zip Plugin", "zip")
+
+101 ICON "zip.ico"
diff --git a/CPP/7zip/Archive/Zip/zip.ico b/CPP/7zip/Archive/Zip/zip.ico
new file mode 100755
index 00000000..2af46066
--- /dev/null
+++ b/CPP/7zip/Archive/Zip/zip.ico
Binary files differ
diff --git a/CPP/7zip/Archive/makefile b/CPP/7zip/Archive/makefile
new file mode 100755
index 00000000..7512ad56
--- /dev/null
+++ b/CPP/7zip/Archive/makefile
@@ -0,0 +1,23 @@
+DIRS = \
+ 7z\~ \
+ Arj\~ \
+ BZip2\~ \
+ Cab\~ \
+ Chm\~ \
+ Cpio\~ \
+ Deb\~ \
+ GZip\~ \
+ Iso\~ \
+ Lzh\~ \
+ Nsis\~ \
+ Rar\~ \
+ RPM\~ \
+ Split\~ \
+ Tar\~ \
+ Z\~ \
+ Zip\~ \
+
+all: $(DIRS)
+
+$(DIRS):
+!include "../SubBuild.mak"
diff --git a/CPP/7zip/Bundles/Alone/Alone.dsp b/CPP/7zip/Bundles/Alone/Alone.dsp
new file mode 100755
index 00000000..982cfb31
--- /dev/null
+++ b/CPP/7zip/Bundles/Alone/Alone.dsp
@@ -0,0 +1,2301 @@
+# Microsoft Developer Studio Project File - Name="Alone" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=Alone - Win32 DebugU
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "Alone.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "Alone.mak" CFG="Alone - Win32 DebugU"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Alone - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "Alone - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "Alone - Win32 ReleaseU" (based on "Win32 (x86) Console Application")
+!MESSAGE "Alone - Win32 DebugU" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "FORMAT_Z" /D "FORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_DEFLATE64" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /D "COMPRESS_MT" /D "COMPRESS_BZIP2_MT" /Yu"StdAfx.h" /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7za.exe" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "FORMAT_Z" /D "FORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_DEFLATE64" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /D "COMPRESS_MT" /D "COMPRESS_BZIP2_MT" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7za.exe" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ReleaseU"
+# PROP BASE Intermediate_Dir "ReleaseU"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ReleaseU"
+# PROP Intermediate_Dir "ReleaseU"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /Yu"StdAfx.h" /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "FORMAT_Z" /D "FORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_DEFLATE64" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /D "COMPRESS_MT" /D "COMPRESS_BZIP2_MT" /Yu"StdAfx.h" /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7za.exe" /opt:NOWIN98
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7zan.exe" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "DebugU"
+# PROP BASE Intermediate_Dir "DebugU"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "DebugU"
+# PROP Intermediate_Dir "DebugU"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c
+# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "FORMAT_Z" /D "FORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_DEFLATE64" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /D "COMPRESS_MT" /D "COMPRESS_BZIP2_MT" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7za.exe" /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7zan.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "Alone - Win32 Release"
+# Name "Alone - Win32 Debug"
+# Name "Alone - Win32 ReleaseU"
+# Name "Alone - Win32 DebugU"
+# Begin Group "Console"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ArError.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\CompressionMode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ConsoleClose.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ConsoleClose.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ExtractCallbackConsole.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ExtractCallbackConsole.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\List.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\List.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\Main.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\MainAr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\OpenCallbackConsole.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\OpenCallbackConsole.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\PercentPrinter.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\PercentPrinter.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\UpdateCallbackConsole.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\UpdateCallbackConsole.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\UserInputUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\UserInputUtils.h
+# End Source File
+# End Group
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\AlignedBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\AlignedBuffer.h
+# End Source File
+# 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\AutoPtr.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Buffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\ComTry.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Defs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\DynamicBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Exception.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\ListFileUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\ListFileUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyCom.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyGuidDef.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyInitGuid.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyUnknown.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyWindows.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyWindows.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Random.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Random.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdInStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdInStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\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\StringToInt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringToInt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Types.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\UTFConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\UTFConvert.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Vector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Vector.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Defs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Device.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Error.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Error.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Handle.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\MemoryLock.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\MemoryLock.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Thread.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Time.h
+# End Source File
+# End Group
+# Begin Group "7zip Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilePathAutoRename.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilePathAutoRename.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InOutTempBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InOutTempBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFEncoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFEncoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MemBlocks.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MSBFDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MSBFEncoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OffsetStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OffsetStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutMemStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutMemStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressMt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressMt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Group "Branch"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\Coder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86_2.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86_2.h
+# End Source File
+# End Group
+# Begin Group "BZip2"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\BZip2\BZip2CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BZip2\BZip2CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BZip2\BZip2Decoder.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BZip2\BZip2Decoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BZip2\BZip2Encoder.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BZip2\BZip2Encoder.h
+# End Source File
+# End Group
+# Begin Group "Copy"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.h
+# End Source File
+# End Group
+# Begin Group "Deflate"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Deflate\DeflateConst.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Deflate\DeflateDecoder.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Deflate\DeflateDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Deflate\DeflateEncoder.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Deflate\DeflateEncoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Deflate\DeflateExtConst.h
+# End Source File
+# End Group
+# Begin Group "Huffman"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Huffman\HuffmanDecoder.h
+# End Source File
+# End Group
+# Begin Group "Implode"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Implode\ImplodeDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Implode\ImplodeDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Implode\ImplodeHuffmanDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Implode\ImplodeHuffmanDecoder.h
+# End Source File
+# End Group
+# Begin Group "LZ"
+
+# PROP Default_Filter ""
+# Begin Group "MT"
+
+# PROP Default_Filter ""
+# End Group
+# Begin Group "HC"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\HashChain\HC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\HashChain\HC2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\HashChain\HC3.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\HashChain\HC4.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\HashChain\HC4b.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\HashChain\HCMain.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\IMatchFinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\LZOutWindow.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O1
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O1
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\LZOutWindow.h
+# End Source File
+# End Group
+# Begin Group "LZMA"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMA.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMADecoder.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMADecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMAEncoder.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMAEncoder.h
+# End Source File
+# End Group
+# Begin Group "PPMd"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDContext.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDDecoder.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDEncode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDEncoder.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDEncoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDSubAlloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDType.h
+# End Source File
+# End Group
+# Begin Group "RangeCoder"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O1
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O1
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoderBitTree.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoderOpt.h
+# End Source File
+# End Group
+# Begin Group "Shrink"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Shrink\ShrinkDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Shrink\ShrinkDecoder.h
+# End Source File
+# End Group
+# Begin Group "Z"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Z\ZDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Z\ZDecoder.h
+# End Source File
+# End Group
+# Begin Group "BWT"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\BWT\BlockSort.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BWT\BlockSort.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BWT\Mtf8.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
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Lzx\Lzx86Converter.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Lzx\LzxDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Lzx\LzxDecoder.h
+# End Source File
+# End Group
+# Begin Group "Quantum"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Quantum\QuantumDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Quantum\QuantumDecoder.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "Archive"
+
+# PROP Default_Filter ""
+# Begin Group "7z"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zCompressionMode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zCompressionMode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zEncode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zEncode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zExtract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderInStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderInStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandlerOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHeader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zMethodID.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zMethodID.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zOut.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zProperties.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zProperties.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zSpecStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zSpecStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zUpdate.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zUpdate.h
+# End Source File
+# End Group
+# Begin Group "bz2"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\BZip2\BZip2Handler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\BZip2\BZip2Handler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\BZip2\BZip2HandlerOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\BZip2\BZip2Item.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\BZip2\BZip2Update.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\BZip2\BZip2Update.h
+# End Source File
+# End Group
+# Begin Group "gz"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\GZip\GZipHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\GZip\GZipHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\GZip\GZipHandlerOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\GZip\GZipHeader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\GZip\GZipHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\GZip\GZipIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\GZip\GZipIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\GZip\GZipItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\GZip\GZipOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\GZip\GZipOut.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\GZip\GZipUpdate.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\GZip\GZipUpdate.h
+# End Source File
+# End Group
+# Begin Group "tar"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Tar\TarHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Tar\TarHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Tar\TarHandlerOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Tar\TarHeader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Tar\TarHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Tar\TarIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Tar\TarIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Tar\TarItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Tar\TarOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Tar\TarOut.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Tar\TarUpdate.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Tar\TarUpdate.h
+# End Source File
+# End Group
+# Begin Group "zip"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Zip\ZipAddCommon.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Zip\ZipAddCommon.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Zip\ZipCompressionMode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Zip\ZipHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Zip\ZipHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Zip\ZipHandlerOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Zip\ZipHeader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Zip\ZipHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Zip\ZipIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Zip\ZipIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Zip\ZipItem.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Zip\ZipItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Zip\ZipItemEx.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Zip\ZipOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Zip\ZipOut.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Zip\ZipUpdate.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Zip\ZipUpdate.h
+# End Source File
+# End Group
+# Begin Group "Archive Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2MT.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2ST.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2ST.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\DummyOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\DummyOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\FilterCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\FilterCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\InStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\InStreamWithCRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\MultiStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\MultiStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ParseProperties.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ParseProperties.h
+# End Source File
+# End Group
+# Begin Group "split"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Split\SplitHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Split\SplitHandler.h
+# End Source File
+# End Group
+# Begin Group "Z Format"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Z\ZHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Z\ZHandler.h
+# End Source File
+# End Group
+# Begin Group "cab"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Cab\CabBlockInStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Cab\CabBlockInStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Cab\CabHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Cab\CabHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Cab\CabHeader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Cab\CabHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Cab\CabIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Cab\CabIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Cab\CabItem.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "UI Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveCommandLine.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveCommandLine.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveExtractCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveOpenCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiverInfo.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiverInfo.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\DefaultName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\DefaultName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\EnumDirItems.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\EnumDirItems.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Extract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Extract.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ExtractingFilePath.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ExtractingFilePath.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\OpenArchive.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\OpenArchive.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\PropIDUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\PropIDUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\SetProperties.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\SetProperties.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\SortUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\SortUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\TempFiles.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\TempFiles.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Update.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Update.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdateAction.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdateAction.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdateCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdateCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdatePair.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdatePair.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdateProduce.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdateProduce.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\WorkDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\WorkDir.h
+# End Source File
+# End Group
+# Begin Group "Crypto"
+
+# PROP Default_Filter ""
+# Begin Group "Zip Crypto"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\Zip\ZipCipher.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O1
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O1
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Zip\ZipCipher.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Zip\ZipCrypto.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O1
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O1
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Zip\ZipCrypto.h
+# End Source File
+# End Group
+# Begin Group "AES"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aes.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\AES_CBC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aescpp.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aescrypt.c
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aeskey.c
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aesopt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aestab.c
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\MyAES.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\MyAES.h
+# End Source File
+# End Group
+# Begin Group "7z AES"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAES\7zAES.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAES\7zAES.h
+# End Source File
+# End Group
+# Begin Group "WzAES"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\WzAES\WzAES.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\WzAES\WzAES.h
+# End Source File
+# End Group
+# Begin Group "Hash"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\HmacSha1.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\HmacSha1.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\Pbkdf2HmacSha1.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\Pbkdf2HmacSha1.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\RandGen.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\RandGen.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\Sha1.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\Sha1.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\Sha256.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\Sha256.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "7-zip"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\ICoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IMyUnknown.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IPassword.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IProgress.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\PropID.h
+# End Source File
+# End Group
+# Begin Group "C"
+
+# PROP Default_Filter ""
+# Begin Group "C-Compress"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Huffman\HuffmanEncode.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Huffman\HuffmanEncode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\LzHash.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinderMt.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinderMt.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrc.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\IStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Sort.c
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Sort.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Threads.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Threads.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Types.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/CPP/7zip/Bundles/Alone/Alone.dsw b/CPP/7zip/Bundles/Alone/Alone.dsw
new file mode 100755
index 00000000..65eca43f
--- /dev/null
+++ b/CPP/7zip/Bundles/Alone/Alone.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Alone"=.\Alone.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Bundles/Alone/StdAfx.cpp b/CPP/7zip/Bundles/Alone/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Bundles/Alone/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Bundles/Alone/StdAfx.h b/CPP/7zip/Bundles/Alone/StdAfx.h
new file mode 100755
index 00000000..2e4be10b
--- /dev/null
+++ b/CPP/7zip/Bundles/Alone/StdAfx.h
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/Bundles/Alone/afxres.h b/CPP/7zip/Bundles/Alone/afxres.h
new file mode 100755
index 00000000..c2fadd4a
--- /dev/null
+++ b/CPP/7zip/Bundles/Alone/afxres.h
@@ -0,0 +1 @@
+#include <winresrc.h>
diff --git a/CPP/7zip/Bundles/Alone/makefile b/CPP/7zip/Bundles/Alone/makefile
new file mode 100755
index 00000000..e076ed3a
--- /dev/null
+++ b/CPP/7zip/Bundles/Alone/makefile
@@ -0,0 +1,390 @@
+PROG = 7za.exe
+LIBS = $(LIBS) user32.lib oleaut32.lib Advapi32.lib
+
+CFLAGS = $(CFLAGS) -I ../../../ \
+ -DEXCLUDE_COM \
+ -DNO_REGISTRY \
+ -DWIN_LONG_PATH \
+ -DFORMAT_7Z \
+ -DFORMAT_BZIP2 \
+ -DFORMAT_CAB \
+ -DFORMAT_GZIP \
+ -DFORMAT_SPLIT \
+ -DFORMAT_TAR \
+ -DFORMAT_Z \
+ -DFORMAT_ZIP \
+ -DCOMPRESS_MT \
+ -DCOMPRESS_BCJ_X86 \
+ -DCOMPRESS_BCJ2 \
+ -DCOMPRESS_BZIP2 \
+ -DCOMPRESS_BZIP2_MT \
+ -DCOMPRESS_COPY \
+ -DCOMPRESS_DEFLATE \
+ -DCOMPRESS_DEFLATE64 \
+ -DCOMPRESS_IMPLODE \
+ -DCOMPRESS_LZMA \
+ -DCOMPRESS_MF_MT \
+ -DCOMPRESS_PPMD \
+ -DCRYPTO_7ZAES \
+ -DCRYPTO_AES \
+ -DCRYPTO_ZIP \
+
+
+CONSOLE_OBJS = \
+ $O\ConsoleClose.obj \
+ $O\ExtractCallbackConsole.obj \
+ $O\List.obj \
+ $O\Main.obj \
+ $O\MainAr.obj \
+ $O\OpenCallbackConsole.obj \
+ $O\PercentPrinter.obj \
+ $O\UpdateCallbackConsole.obj \
+ $O\UserInputUtils.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\CommandLineParser.obj \
+ $O\CRC.obj \
+ $O\IntToString.obj \
+ $O\ListFileUtils.obj \
+ $O\NewHandler.obj \
+ $O\StdInStream.obj \
+ $O\StdOutStream.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\UTFConvert.obj \
+ $O\Vector.obj \
+ $O\Wildcard.obj \
+
+WIN_OBJS = \
+ $O\DLL.obj \
+ $O\Error.obj \
+ $O\FileDir.obj \
+ $O\FileFind.obj \
+ $O\FileIO.obj \
+ $O\FileName.obj \
+ $O\MemoryLock.obj \
+ $O\PropVariant.obj \
+ $O\PropVariantConversions.obj \
+ $O\Synchronization.obj
+
+7ZIP_COMMON_OBJS = \
+ $O\FilePathAutoRename.obj \
+ $O\FileStreams.obj \
+ $O\InBuffer.obj \
+ $O\InOutTempBuffer.obj \
+ $O\LimitedStreams.obj \
+ $O\LockedStream.obj \
+ $O\LSBFDecoder.obj \
+ $O\LSBFEncoder.obj \
+ $O\MemBlocks.obj \
+ $O\OffsetStream.obj \
+ $O\OutBuffer.obj \
+ $O\OutMemStream.obj \
+ $O\ProgressMt.obj \
+ $O\ProgressUtils.obj \
+ $O\StreamBinder.obj \
+ $O\StreamObjects.obj \
+ $O\StreamUtils.obj \
+
+UI_COMMON_OBJS = \
+ $O\ArchiveCommandLine.obj \
+ $O\ArchiveExtractCallback.obj \
+ $O\ArchiveOpenCallback.obj \
+ $O\ArchiverInfo.obj \
+ $O\DefaultName.obj \
+ $O\EnumDirItems.obj \
+ $O\Extract.obj \
+ $O\ExtractingFilePath.obj \
+ $O\OpenArchive.obj \
+ $O\PropIDUtils.obj \
+ $O\SetProperties.obj \
+ $O\SortUtils.obj \
+ $O\TempFiles.obj \
+ $O\Update.obj \
+ $O\UpdateAction.obj \
+ $O\UpdateCallback.obj \
+ $O\UpdatePair.obj \
+ $O\UpdateProduce.obj \
+ $O\WorkDir.obj \
+
+AR_COMMON_OBJS = \
+ $O\CoderMixer2.obj \
+ $O\CoderMixer2MT.obj \
+ $O\CrossThreadProgress.obj \
+ $O\DummyOutStream.obj \
+ $O\FilterCoder.obj \
+ $O\InStreamWithCRC.obj \
+ $O\ItemNameUtils.obj \
+ $O\MultiStream.obj \
+ $O\OutStreamWithCRC.obj \
+ $O\ParseProperties.obj \
+
+
+7Z_OBJS = \
+ $O\7zCompressionMode.obj \
+ $O\7zDecode.obj \
+ $O\7zEncode.obj \
+ $O\7zExtract.obj \
+ $O\7zFolderInStream.obj \
+ $O\7zFolderOutStream.obj \
+ $O\7zHandler.obj \
+ $O\7zHandlerOut.obj \
+ $O\7zHeader.obj \
+ $O\7zIn.obj \
+ $O\7zMethodID.obj \
+ $O\7zOut.obj \
+ $O\7zProperties.obj \
+ $O\7zSpecStream.obj \
+ $O\7zUpdate.obj \
+
+BZ2_OBJS = \
+ $O\BZip2Handler.obj \
+ $O\BZip2HandlerOut.obj \
+ $O\BZip2Update.obj \
+
+CAB_OBJS = \
+ $O\CabBlockInStream.obj \
+ $O\CabHandler.obj \
+ $O\CabHeader.obj \
+ $O\CabIn.obj \
+
+GZ_OBJS = \
+ $O\GZipHandler.obj \
+ $O\GZipHandlerOut.obj \
+ $O\GZipHeader.obj \
+ $O\GZipIn.obj \
+ $O\GZipOut.obj \
+ $O\GZipUpdate.obj \
+
+SPLIT_OBJS = \
+ $O\SplitHandler.obj \
+ $O\SplitHandlerOut.obj \
+
+TAR_OBJS = \
+ $O\TarHandler.obj \
+ $O\TarHandlerOut.obj \
+ $O\TarHeader.obj \
+ $O\TarIn.obj \
+ $O\TarOut.obj \
+ $O\TarUpdate.obj \
+
+Z_OBJS = \
+ $O\ZHandler.obj \
+
+ZIP_OBJS = \
+ $O\ZipAddCommon.obj \
+ $O\ZipHandler.obj \
+ $O\ZipHandlerOut.obj \
+ $O\ZipHeader.obj \
+ $O\ZipIn.obj \
+ $O\ZipItem.obj \
+ $O\ZipOut.obj \
+ $O\ZipUpdate.obj \
+
+
+BRANCH_OPT_OBJS = \
+ $O\BranchCoder.obj \
+ $O\x86.obj \
+ $O\x86_2.obj \
+
+BZIP2_OBJS = \
+ $O\BZip2CRC.obj \
+
+BZIP2_OPT_OBJS = \
+ $O\BZip2Decoder.obj \
+ $O\BZip2Encoder.obj \
+
+DEFLATE_OPT_OBJS = \
+ $O\DeflateDecoder.obj \
+ $O\DeflateEncoder.obj \
+
+LZ_OBJS = \
+ $O\LzOutWindow.obj \
+
+LZMA_OPT_OBJS = \
+ $O\LZMADecoder.obj \
+ $O\LZMAEncoder.obj \
+
+LZX_OBJS = \
+ $O\LzxDecoder.obj \
+ $O\Lzx86Converter.obj \
+
+IMPLODE_OBJS = \
+ $O\ImplodeDecoder.obj \
+ $O\ImplodeHuffmanDecoder.obj \
+
+PPMD_OPT_OBJS = \
+ $O\PPMDDecoder.obj \
+ $O\PPMDEncoder.obj \
+
+SHRINK_OBJS = \
+ $O\ShrinkDecoder.obj \
+
+COMPRESS_Z_OBJS = \
+ $O\ZDecoder.obj \
+
+
+7ZAES_OPT_OBJS = \
+ $O\7zAES.obj \
+
+AES_OPT_OBJS = \
+ $O\MyAES.obj \
+
+AES_ORIG_OBJS = \
+ $O\aescrypt.obj \
+ $O\aeskey.obj \
+ $O\aestab.obj \
+
+CRYPTO_HASH_OBJS = \
+ $O\HmacSha1.obj \
+ $O\Pbkdf2HmacSha1.obj \
+ $O\RandGen.obj \
+ $O\Sha1.obj \
+ $O\Sha256.obj \
+
+CRYPTO_WZAES_OBJS = \
+ $O\WzAES.obj \
+
+CRYPTO_ZIP_OBJS = \
+ $O\ZipCipher.obj \
+ $O\ZipCrypto.obj \
+
+C_OBJS = \
+ $O\7zCrc.obj \
+ $O\Sort.obj \
+ $O\Threads.obj \
+
+C_LZ_OBJS = \
+ $O\MatchFinder.obj \
+ $O\MatchFinderMt.obj \
+
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(CONSOLE_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(UI_COMMON_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $(7Z_OBJS) \
+ $(BZ2_OBJS) \
+ $(CAB_OBJS) \
+ $(GZ_OBJS) \
+ $(SPLIT_OBJS) \
+ $(TAR_OBJS) \
+ $(Z_OBJS) \
+ $(ZIP_OBJS) \
+ $(BZIP2_OBJS) \
+ $(BZIP2_OPT_OBJS) \
+ $(BRANCH_OPT_OBJS) \
+ $(DEFLATE_OPT_OBJS) \
+ $(IMPLODE_OBJS) \
+ $(LZ_OBJS) \
+ $(LZMA_OPT_OBJS) \
+ $(LZX_OBJS) \
+ $(PPMD_OPT_OBJS) \
+ $(SHRINK_OBJS) \
+ $(COMPRESS_Z_OBJS) \
+ $(C_OBJS) \
+ $(C_LZ_OBJS) \
+ $O\BlockSort.obj \
+ $O\CopyCoder.obj \
+ $O\HuffmanEncode.obj \
+ $O\RangeCoderBit.obj \
+ $(7ZAES_OPT_OBJS) \
+ $(AES_OPT_OBJS) \
+ $(AES_ORIG_OBJS) \
+ $(CRYPTO_HASH_OBJS) \
+ $(CRYPTO_ZIP_OBJS) \
+ $(CRYPTO_WZAES_OBJS) \
+ $O\QuantumDecoder.obj \
+ $O\resource.res
+
+
+!include "../../../Build.mak"
+
+$(CONSOLE_OBJS): ../../UI/Console/$(*B).cpp
+ $(COMPL)
+
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp
+ $(COMPL)
+$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
+ $(COMPL)
+
+$(7Z_OBJS): ../../Archive/7z/$(*B).cpp
+ $(COMPL)
+$(BZ2_OBJS): ../../Archive/BZip2/$(*B).cpp
+ $(COMPL)
+$(CAB_OBJS): ../../Archive/Cab/$(*B).cpp
+ $(COMPL)
+$(GZ_OBJS): ../../Archive/GZip/$(*B).cpp
+ $(COMPL)
+$(SPLIT_OBJS): ../../Archive/Split/$(*B).cpp
+ $(COMPL)
+$(TAR_OBJS): ../../Archive/Tar/$(*B).cpp
+ $(COMPL)
+$(Z_OBJS): ../../Archive/Z/$(*B).cpp
+ $(COMPL)
+$(ZIP_OBJS): ../../Archive/Zip/$(*B).cpp
+ $(COMPL)
+
+$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp
+ $(COMPL_O2)
+$(BZIP2_OBJS): ../../Compress/BZip2/$(*B).cpp
+ $(COMPL)
+$(BZIP2_OPT_OBJS): ../../Compress/BZip2/$(*B).cpp
+ $(COMPL_O2)
+$(DEFLATE_OPT_OBJS): ../../Compress/Deflate/$(*B).cpp
+ $(COMPL_O2)
+$(IMPLODE_OBJS): ../../Compress/Implode/$(*B).cpp
+ $(COMPL)
+$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp
+ $(COMPL_O2)
+$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp
+ $(COMPL_O2)
+$(LZX_OBJS): ../../Compress/Lzx/$(*B).cpp
+ $(COMPL_O2)
+$(PPMD_OPT_OBJS): ../../Compress/PPMD/$(*B).cpp
+ $(COMPL_O2)
+$(SHRINK_OBJS): ../../Compress/Shrink/$(*B).cpp
+ $(COMPL)
+$(COMPRESS_Z_OBJS): ../../Compress/Z/$(*B).cpp
+ $(COMPL)
+
+$O\BlockSort.obj: ../../Compress/BWT/$(*B).cpp
+ $(COMPL_O2)
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
+$O\RangeCoderBit.obj: ../../Compress/RangeCoder/$(*B).cpp
+ $(COMPL)
+$O\QuantumDecoder.obj: ../../Compress/Quantum/$(*B).cpp
+ $(COMPL)
+
+$(AES_OPT_OBJS): ../../Crypto/AES/$(*B).cpp
+ $(COMPL_O2)
+$(AES_ORIG_OBJS): ../../Crypto/AES/$(*B).c
+ $(COMPL_O2_W3)
+$(7ZAES_OPT_OBJS): ../../Crypto/7zAES/$(*B).cpp
+ $(COMPL_O2)
+$(CRYPTO_HASH_OBJS): ../../Crypto/Hash/$(*B).cpp
+ $(COMPL_O2)
+$(CRYPTO_ZIP_OBJS): ../../Crypto/Zip/$(*B).cpp
+ $(COMPL)
+$(CRYPTO_WZAES_OBJS): ../../Crypto/WzAES/$(*B).cpp
+ $(COMPL_O2)
+
+$(C_OBJS): ../../../../C/$(*B).c
+ $(COMPL_O2)
+$(C_LZ_OBJS): ../../../../C/Compress/Lz/$(*B).c
+ $(COMPL_O2)
+$O\HuffmanEncode.obj: ../../../../C/Compress/Huffman/$(*B).c
+ $(COMPL_O2)
diff --git a/CPP/7zip/Bundles/Alone/resource.rc b/CPP/7zip/Bundles/Alone/resource.rc
new file mode 100755
index 00000000..fc9063c1
--- /dev/null
+++ b/CPP/7zip/Bundles/Alone/resource.rc
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_APP("7-Zip Standalone Console", "7za")
diff --git a/CPP/7zip/Bundles/Alone7z/Alone.dsp b/CPP/7zip/Bundles/Alone7z/Alone.dsp
new file mode 100755
index 00000000..5ff71f2c
--- /dev/null
+++ b/CPP/7zip/Bundles/Alone7z/Alone.dsp
@@ -0,0 +1,1358 @@
+# Microsoft Developer Studio Project File - Name="Alone" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=Alone - Win32 DebugU
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "Alone.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "Alone.mak" CFG="Alone - Win32 DebugU"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Alone - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "Alone - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "Alone - Win32 ReleaseU" (based on "Win32 (x86) Console Application")
+!MESSAGE "Alone - Win32 DebugU" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMFORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7zr.exe" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMFORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7zr.exe" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ReleaseU"
+# PROP BASE Intermediate_Dir "ReleaseU"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ReleaseU"
+# PROP Intermediate_Dir "ReleaseU"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /Yu"StdAfx.h" /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMFORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7za.exe" /opt:NOWIN98
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7zr.exe" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "DebugU"
+# PROP BASE Intermediate_Dir "DebugU"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "DebugU"
+# PROP Intermediate_Dir "DebugU"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c
+# ADD CPP /nologo /Gz /W4 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMFORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7za.exe" /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7zr.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "Alone - Win32 Release"
+# Name "Alone - Win32 Debug"
+# Name "Alone - Win32 ReleaseU"
+# Name "Alone - Win32 DebugU"
+# Begin Group "Console"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ArError.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\CompressionMode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ConsoleClose.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ConsoleClose.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ExtractCallbackConsole.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ExtractCallbackConsole.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\List.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\List.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\Main.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\MainAr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\OpenCallbackConsole.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\OpenCallbackConsole.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\PercentPrinter.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\PercentPrinter.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\UpdateCallbackConsole.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\UpdateCallbackConsole.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\UserInputUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\UserInputUtils.h
+# End Source File
+# End Group
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\AlignedBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\AlignedBuffer.h
+# End Source File
+# 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\AutoPtr.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Buffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\ComTry.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Defs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\DynamicBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Exception.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\ListFileUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\ListFileUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyCom.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyGuidDef.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyInitGuid.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyUnknown.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyWindows.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyWindows.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Random.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Random.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdInStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdInStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\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\StringToInt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringToInt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Types.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\UTFConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\UTFConvert.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Vector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Vector.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Defs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Device.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Error.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Error.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Handle.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\MemoryLock.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\MemoryLock.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Thread.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Time.h
+# End Source File
+# End Group
+# Begin Group "7zip Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilePathAutoRename.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilePathAutoRename.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InOutTempBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InOutTempBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFEncoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFEncoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MSBFDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MSBFEncoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OffsetStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OffsetStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressMt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressMt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Group "Branch"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\Coder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86_2.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86_2.h
+# End Source File
+# End Group
+# Begin Group "Copy"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.h
+# End Source File
+# End Group
+# Begin Group "LZ"
+
+# PROP Default_Filter ""
+# Begin Group "MT"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\MT\MT.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\MT\MT.h
+# End Source File
+# End Group
+# Begin Group "HC"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\HashChain\HC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\HashChain\HC2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\HashChain\HC3.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\HashChain\HC4.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\HashChain\HC4b.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\HashChain\HCMain.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\IMatchFinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\LZInWindow.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O1
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O1
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\LZInWindow.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\LZOutWindow.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O1
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O1
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\LZOutWindow.h
+# End Source File
+# End Group
+# Begin Group "LZMA"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMA.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMADecoder.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMADecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMAEncoder.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMAEncoder.h
+# End Source File
+# End Group
+# Begin Group "RangeCoder"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.cpp
+
+!IF "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O1
+
+!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O1
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoderBitTree.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoderOpt.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "Archive"
+
+# PROP Default_Filter ""
+# Begin Group "7z"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zCompressionMode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zCompressionMode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zEncode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zEncode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zExtract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderInStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderInStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandlerOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHeader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zMethodID.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zMethodID.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zOut.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zProperties.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zProperties.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zSpecStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zSpecStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zUpdate.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zUpdate.h
+# End Source File
+# End Group
+# Begin Group "Archive Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2MT.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2ST.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2ST.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\DummyOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\DummyOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\FilterCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\FilterCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\InStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\InStreamWithCRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\MultiStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\MultiStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ParseProperties.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ParseProperties.h
+# End Source File
+# End Group
+# Begin Group "split"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Split\SplitHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Split\SplitHandler.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "UI Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveCommandLine.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveCommandLine.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveExtractCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveOpenCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiverInfo.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiverInfo.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\DefaultName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\DefaultName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\EnumDirItems.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\EnumDirItems.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Extract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Extract.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ExtractingFilePath.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ExtractingFilePath.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\OpenArchive.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\OpenArchive.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\PropIDUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\PropIDUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\SetProperties.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\SetProperties.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\SortUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\SortUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\TempFiles.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\TempFiles.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Update.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Update.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdateAction.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdateAction.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdateCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdateCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdatePair.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdatePair.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdateProduce.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdateProduce.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\WorkDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\WorkDir.h
+# End Source File
+# End Group
+# Begin Group "7-zip"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\ICoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IMyUnknown.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IPassword.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IProgress.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\PropID.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/CPP/7zip/Bundles/Alone7z/Alone.dsw b/CPP/7zip/Bundles/Alone7z/Alone.dsw
new file mode 100755
index 00000000..65eca43f
--- /dev/null
+++ b/CPP/7zip/Bundles/Alone7z/Alone.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Alone"=.\Alone.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Bundles/Alone7z/StdAfx.cpp b/CPP/7zip/Bundles/Alone7z/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Bundles/Alone7z/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Bundles/Alone7z/StdAfx.h b/CPP/7zip/Bundles/Alone7z/StdAfx.h
new file mode 100755
index 00000000..2e4be10b
--- /dev/null
+++ b/CPP/7zip/Bundles/Alone7z/StdAfx.h
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/Bundles/Alone7z/makefile b/CPP/7zip/Bundles/Alone7z/makefile
new file mode 100755
index 00000000..9bec8059
--- /dev/null
+++ b/CPP/7zip/Bundles/Alone7z/makefile
@@ -0,0 +1,196 @@
+PROG = 7za.exe
+LIBS = $(LIBS) user32.lib oleaut32.lib Advapi32.lib
+
+CFLAGS = $(CFLAGS) -I ../../../ \
+ -DEXCLUDE_COM \
+ -DNO_REGISTRY \
+ -D_NO_CRYPTO \
+ -DWIN_LONG_PATH \
+ -DFORMAT_7Z \
+ -DCOMPRESS_MT \
+ -DCOMPRESS_BCJ_X86 \
+ -DCOMPRESS_BCJ2 \
+ -DCOMPRESS_COPY \
+ -DCOMPRESS_LZMA \
+ -DCOMPRESS_MF_MT \
+ -D_NO_CRYPTO
+
+
+CONSOLE_OBJS = \
+ $O\ConsoleClose.obj \
+ $O\ExtractCallbackConsole.obj \
+ $O\List.obj \
+ $O\Main.obj \
+ $O\MainAr.obj \
+ $O\OpenCallbackConsole.obj \
+ $O\PercentPrinter.obj \
+ $O\UpdateCallbackConsole.obj \
+ $O\UserInputUtils.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\CommandLineParser.obj \
+ $O\CRC.obj \
+ $O\IntToString.obj \
+ $O\ListFileUtils.obj \
+ $O\NewHandler.obj \
+ $O\StdInStream.obj \
+ $O\StdOutStream.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\UTFConvert.obj \
+ $O\Vector.obj \
+ $O\Wildcard.obj \
+
+WIN_OBJS = \
+ $O\DLL.obj \
+ $O\Error.obj \
+ $O\FileDir.obj \
+ $O\FileFind.obj \
+ $O\FileIO.obj \
+ $O\FileName.obj \
+ $O\MemoryLock.obj \
+ $O\PropVariant.obj \
+ $O\PropVariantConversions.obj \
+ $O\Synchronization.obj
+
+7ZIP_COMMON_OBJS = \
+ $O\FilePathAutoRename.obj \
+ $O\FileStreams.obj \
+ $O\InBuffer.obj \
+ $O\InOutTempBuffer.obj \
+ $O\LimitedStreams.obj \
+ $O\LockedStream.obj \
+ $O\OffsetStream.obj \
+ $O\OutBuffer.obj \
+ $O\ProgressUtils.obj \
+ $O\StreamBinder.obj \
+ $O\StreamObjects.obj \
+ $O\StreamUtils.obj \
+
+UI_COMMON_OBJS = \
+ $O\ArchiveCommandLine.obj \
+ $O\ArchiveExtractCallback.obj \
+ $O\ArchiveOpenCallback.obj \
+ $O\ArchiverInfo.obj \
+ $O\DefaultName.obj \
+ $O\EnumDirItems.obj \
+ $O\Extract.obj \
+ $O\ExtractingFilePath.obj \
+ $O\OpenArchive.obj \
+ $O\PropIDUtils.obj \
+ $O\SetProperties.obj \
+ $O\SortUtils.obj \
+ $O\TempFiles.obj \
+ $O\Update.obj \
+ $O\UpdateAction.obj \
+ $O\UpdateCallback.obj \
+ $O\UpdatePair.obj \
+ $O\UpdateProduce.obj \
+ $O\WorkDir.obj \
+
+AR_COMMON_OBJS = \
+ $O\CoderMixer2.obj \
+ $O\CoderMixer2MT.obj \
+ $O\CrossThreadProgress.obj \
+ $O\DummyOutStream.obj \
+ $O\FilterCoder.obj \
+ $O\InStreamWithCRC.obj \
+ $O\ItemNameUtils.obj \
+ $O\MultiStream.obj \
+ $O\OutStreamWithCRC.obj \
+ $O\ParseProperties.obj \
+
+
+7Z_OBJS = \
+ $O\7zCompressionMode.obj \
+ $O\7zDecode.obj \
+ $O\7zEncode.obj \
+ $O\7zExtract.obj \
+ $O\7zFolderInStream.obj \
+ $O\7zFolderOutStream.obj \
+ $O\7zHandler.obj \
+ $O\7zHandlerOut.obj \
+ $O\7zHeader.obj \
+ $O\7zIn.obj \
+ $O\7zMethodID.obj \
+ $O\7zOut.obj \
+ $O\7zProperties.obj \
+ $O\7zSpecStream.obj \
+ $O\7zUpdate.obj \
+
+
+BRANCH_OPT_OBJS = \
+ $O\BranchCoder.obj \
+ $O\x86.obj \
+ $O\x86_2.obj \
+
+LZ_OBJS = \
+ $O\LZOutWindow.obj \
+
+LZMA_OPT_OBJS = \
+ $O\LZMADecoder.obj \
+ $O\LZMAEncoder.obj \
+
+C_OBJS = \
+ $O\7zCrc.obj \
+ $O\Sort.obj \
+ $O\Threads.obj \
+
+C_LZ_OBJS = \
+ $O\MatchFinder.obj \
+ $O\MatchFinderMt.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(CONSOLE_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(UI_COMMON_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $(7Z_OBJS) \
+ $(BRANCH_OPT_OBJS) \
+ $(LZ_OBJS) \
+ $(LZMA_OPT_OBJS) \
+ $(C_OBJS) \
+ $(C_LZ_OBJS) \
+ $O\CopyCoder.obj \
+ $O\RangeCoderBit.obj \
+ $O\resource.res
+
+
+!include "../../../Build.mak"
+
+$(CONSOLE_OBJS): ../../UI/Console/$(*B).cpp
+ $(COMPL)
+
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp
+ $(COMPL)
+$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
+ $(COMPL)
+
+$(7Z_OBJS): ../../Archive/7z/$(*B).cpp
+ $(COMPL)
+$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp
+ $(COMPL_O2)
+$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp
+ $(COMPL)
+$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp
+ $(COMPL_O2)
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
+$O\RangeCoderBit.obj: ../../Compress/RangeCoder/$(*B).cpp
+ $(COMPL)
+
+$(C_OBJS): ../../../../C/$(*B).c
+ $(COMPL_O2)
+$(C_LZ_OBJS): ../../../../C/Compress/Lz/$(*B).c
+ $(COMPL_O2)
diff --git a/CPP/7zip/Bundles/Alone7z/resource.rc b/CPP/7zip/Bundles/Alone7z/resource.rc
new file mode 100755
index 00000000..fc9063c1
--- /dev/null
+++ b/CPP/7zip/Bundles/Alone7z/resource.rc
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_APP("7-Zip Standalone Console", "7za")
diff --git a/CPP/7zip/Bundles/Format7z/Format7z.dsp b/CPP/7zip/Bundles/Format7z/Format7z.dsp
new file mode 100755
index 00000000..a59cd581
--- /dev/null
+++ b/CPP/7zip/Bundles/Format7z/Format7z.dsp
@@ -0,0 +1,1006 @@
+# Microsoft Developer Studio Project File - Name="7z" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=7z - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "Format7z.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "Format7z.mak" CFG="7z - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "7z - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "7z - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE_DECODER" /D "COMPRESS_BZIP2_DECODER" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /D "COMPRESS_MT" /D "COMPRESS_BZIP2_MT" /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\7za.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none /debug
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\..\SDK" /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE_DECODER" /D "COMPRESS_BZIP2_DECODER" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /D "COMPRESS_MT" /D "COMPRESS_BZIP2_MT" /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\7za.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "7z - Win32 Release"
+# Name "7z - Win32 Debug"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7z.ico
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Archive.def
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\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 "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\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# 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\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
+
+SOURCE=..\..\..\Common\Vector.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.h
+# End Source File
+# End Group
+# Begin Group "Archive common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2MT.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\FilterCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\FilterCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\InStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\InStreamWithCRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ParseProperties.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ParseProperties.h
+# End Source File
+# End Group
+# Begin Group "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 "PPMD"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDContext.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDDecoder.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDEncode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDEncoder.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDEncoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDSubAlloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDType.h
+# End Source File
+# End Group
+# Begin Group "Branch"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86_2.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86_2.h
+# End Source File
+# End Group
+# Begin Group "LZMA"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMA.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMADecoder.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMADecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMAEncoder.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMAEncoder.h
+# End Source File
+# End Group
+# Begin Group "Copy"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.h
+# End Source File
+# End Group
+# Begin Group "RangeCoder"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoderBitTree.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoderOpt.h
+# End Source File
+# End Group
+# Begin Group "Deflate"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Deflate\DeflateConst.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Deflate\DeflateDecoder.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Deflate\DeflateDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Deflate\DeflateExtConst.h
+# End Source File
+# End Group
+# Begin Group "BZip2"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\BZip2\BZip2Const.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BZip2\BZip2CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BZip2\BZip2CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BZip2\BZip2Decoder.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BZip2\BZip2Decoder.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "Crypto"
+
+# PROP Default_Filter ""
+# Begin Group "AES"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aes.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\AES_CBC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aescpp.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aescrypt.c
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aeskey.c
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aesopt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aestab.c
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\MyAES.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\MyAES.h
+# End Source File
+# End Group
+# Begin Group "7zAES"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAES\7zAES.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAES\7zAES.h
+# End Source File
+# End Group
+# Begin Group "Hash"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\Sha256.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\Sha256.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "7z"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zCompressionMode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zCompressionMode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zEncode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zEncode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zExtract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderInStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderInStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandlerOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHeader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zMethodID.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zMethodID.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zMethods.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zOut.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zProperties.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zProperties.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zSpecStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zSpecStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zUpdate.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zUpdate.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zUpdateItem.h
+# End Source File
+# End Group
+# Begin Group "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\InOutTempBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InOutTempBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFDecoder.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\StreamBinder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# End Group
+# Begin Group "C"
+
+# PROP Default_Filter ""
+# Begin Group "C-Lz"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\LzHash.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.c
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinderMt.c
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinderMt.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrc.c
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Threads.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Threads.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/CPP/7zip/Bundles/Format7z/Format7z.dsw b/CPP/7zip/Bundles/Format7z/Format7z.dsw
new file mode 100755
index 00000000..324dab1f
--- /dev/null
+++ b/CPP/7zip/Bundles/Format7z/Format7z.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "7z"=.\Format7z.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Bundles/Format7z/StdAfx.cpp b/CPP/7zip/Bundles/Format7z/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Bundles/Format7z/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Bundles/Format7z/StdAfx.h b/CPP/7zip/Bundles/Format7z/StdAfx.h
new file mode 100755
index 00000000..2e4be10b
--- /dev/null
+++ b/CPP/7zip/Bundles/Format7z/StdAfx.h
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/Bundles/Format7z/makefile b/CPP/7zip/Bundles/Format7z/makefile
new file mode 100755
index 00000000..1134faee
--- /dev/null
+++ b/CPP/7zip/Bundles/Format7z/makefile
@@ -0,0 +1,201 @@
+PROG = 7za.dll
+DEF_FILE = ../../Archive/Archive.def
+LIBS = $(LIBS) user32.lib oleaut32.lib
+CFLAGS = $(CFLAGS) -I ../../../ \
+ -DEXCLUDE_COM \
+ -DNO_REGISTRY \
+ -DFORMAT_7Z \
+ -DCOMPRESS_MT \
+ -DCOMPRESS_BCJ_X86 \
+ -DCOMPRESS_BCJ2 \
+ -DCOMPRESS_BZIP2_DECODER \
+ -DCOMPRESS_BZIP2_MT \
+ -DCOMPRESS_COPY \
+ -DCOMPRESS_DEFLATE_DECODER \
+ -DCOMPRESS_LZMA \
+ -DCOMPRESS_MF_MT \
+ -DCOMPRESS_PPMD \
+ -DCRYPTO_7ZAES \
+ -DCRYPTO_AES \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\CRC.obj \
+ $O\IntToString.obj \
+ $O\NewHandler.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\Vector.obj \
+ $O\Wildcard.obj \
+
+WIN_OBJS = \
+ $O\FileDir.obj \
+ $O\FileFind.obj \
+ $O\FileIO.obj \
+ $O\PropVariant.obj \
+ $O\Synchronization.obj
+
+7ZIP_COMMON_OBJS = \
+ $O\InBuffer.obj \
+ $O\InOutTempBuffer.obj \
+ $O\LimitedStreams.obj \
+ $O\LockedStream.obj \
+ $O\LSBFDecoder.obj \
+ $O\OutBuffer.obj \
+ $O\ProgressUtils.obj \
+ $O\StreamBinder.obj \
+ $O\StreamObjects.obj \
+ $O\StreamUtils.obj \
+
+AR_COMMON_OBJS = \
+ $O\CoderMixer2.obj \
+ $O\CoderMixer2MT.obj \
+ $O\CrossThreadProgress.obj \
+ $O\FilterCoder.obj \
+ $O\InStreamWithCRC.obj \
+ $O\ItemNameUtils.obj \
+ $O\OutStreamWithCRC.obj \
+ $O\ParseProperties.obj \
+
+
+7Z_OBJS = \
+ $O\DllExports.obj \
+ $O\7zCompressionMode.obj \
+ $O\7zDecode.obj \
+ $O\7zEncode.obj \
+ $O\7zExtract.obj \
+ $O\7zFolderInStream.obj \
+ $O\7zFolderOutStream.obj \
+ $O\7zHandler.obj \
+ $O\7zHandlerOut.obj \
+ $O\7zHeader.obj \
+ $O\7zIn.obj \
+ $O\7zMethodID.obj \
+ $O\7zOut.obj \
+ $O\7zProperties.obj \
+ $O\7zSpecStream.obj \
+ $O\7zUpdate.obj \
+
+
+BRANCH_OPT_OBJS = \
+ $O\BranchCoder.obj \
+ $O\x86.obj \
+ $O\x86_2.obj \
+
+BZIP2_OBJS = \
+ $O\BZip2CRC.obj \
+
+BZIP2_OPT_OBJS = \
+ $O\BZip2Decoder.obj \
+
+DEFLATE_OPT_OBJS = \
+ $O\DeflateDecoder.obj \
+
+LZ_OBJS = \
+ $O\LZOutWindow.obj \
+
+LZMA_OPT_OBJS = \
+ $O\LZMADecoder.obj \
+ $O\LZMAEncoder.obj \
+
+PPMD_OPT_OBJS = \
+ $O\PPMDDecoder.obj \
+ $O\PPMDEncoder.obj \
+
+
+7ZAES_OPT_OBJS = \
+ $O\7zAES.obj \
+
+AES_OPT_OBJS = \
+ $O\MyAES.obj \
+
+AES_ORIG_OBJS = \
+ $O\aescrypt.obj \
+ $O\aeskey.obj \
+ $O\aestab.obj \
+
+CRYPTO_HASH_OBJS = \
+ $O\Sha256.obj \
+
+C_OBJS = \
+ $O\7zCrc.obj \
+ $O\Threads.obj \
+
+C_LZ_OBJS = \
+ $O\MatchFinder.obj \
+ $O\MatchFinderMt.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(CONSOLE_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $(7Z_OBJS) \
+ $(BZIP2_OBJS) \
+ $(BZIP2_OPT_OBJS) \
+ $(BRANCH_OPT_OBJS) \
+ $(DEFLATE_OPT_OBJS) \
+ $(LZ_OBJS) \
+ $(LZMA_OPT_OBJS) \
+ $(PPMD_OPT_OBJS) \
+ $(C_OBJS) \
+ $(C_LZ_OBJS) \
+ $O\CopyCoder.obj \
+ $O\RangeCoderBit.obj \
+ $(7ZAES_OPT_OBJS) \
+ $(AES_OPT_OBJS) \
+ $(AES_ORIG_OBJS) \
+ $(CRYPTO_HASH_OBJS) \
+ $O\resource.res
+
+
+!include "../../../Build.mak"
+
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
+ $(COMPL)
+
+$(7Z_OBJS): ../../Archive/7z/$(*B).cpp
+ $(COMPL)
+
+$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp
+ $(COMPL_O2)
+$(BZIP2_OBJS): ../../Compress/BZip2/$(*B).cpp
+ $(COMPL)
+$(BZIP2_OPT_OBJS): ../../Compress/BZip2/$(*B).cpp
+ $(COMPL_O2)
+$(DEFLATE_OPT_OBJS): ../../Compress/Deflate/$(*B).cpp
+ $(COMPL_O2)
+$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp
+ $(COMPL)
+$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp
+ $(COMPL_O2)
+$(PPMD_OPT_OBJS): ../../Compress/PPMD/$(*B).cpp
+ $(COMPL_O2)
+
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
+$O\RangeCoderBit.obj: ../../Compress/RangeCoder/$(*B).cpp
+ $(COMPL)
+
+$(AES_OPT_OBJS): ../../Crypto/AES/$(*B).cpp
+ $(COMPL_O2)
+$(AES_ORIG_OBJS): ../../Crypto/AES/$(*B).c
+ $(COMPL_O2_W3)
+$(7ZAES_OPT_OBJS): ../../Crypto/7zAES/$(*B).cpp
+ $(COMPL_O2)
+$(CRYPTO_HASH_OBJS): ../../Crypto/Hash/$(*B).cpp
+ $(COMPL_O2)
+
+$(C_OBJS): ../../../../C/$(*B).c
+ $(COMPL_O2)
+$(C_LZ_OBJS): ../../../../C/Compress/Lz/$(*B).c
+ $(COMPL_O2)
diff --git a/CPP/7zip/Bundles/Format7z/resource.rc b/CPP/7zip/Bundles/Format7z/resource.rc
new file mode 100755
index 00000000..5b3f363e
--- /dev/null
+++ b/CPP/7zip/Bundles/Format7z/resource.rc
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("7z Standalone Plugin", "7za")
+
+101 ICON "../../Archive/7z/7z.ico"
diff --git a/CPP/7zip/Bundles/Format7zExtract/Format7z.dsp b/CPP/7zip/Bundles/Format7zExtract/Format7z.dsp
new file mode 100755
index 00000000..d049d00c
--- /dev/null
+++ b/CPP/7zip/Bundles/Format7zExtract/Format7z.dsp
@@ -0,0 +1,813 @@
+# Microsoft Developer Studio Project File - Name="7z" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=7z - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "Format7z.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "Format7z.mak" CFG="7z - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "7z - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "7z - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "EXTRACT_ONLY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE_DECODER" /D "COMPRESS_BZIP2_DECODER" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /D "COMPRESS_MT" /D "COMPRESS_BZIP2_MT" /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\7zxa.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none /debug
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\..\SDK" /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "EXTRACT_ONLY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE_DECODER" /D "COMPRESS_BZIP2_DECODER" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /D "COMPRESS_MT" /D "COMPRESS_BZIP2_MT" /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\7zxa.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "7z - Win32 Release"
+# Name "7z - Win32 Debug"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7z.ico
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Archive.def
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\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 "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\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.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\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
+
+SOURCE=..\..\..\Common\Vector.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.h
+# End Source File
+# End Group
+# Begin Group "Archive common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2MT.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\FilterCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\FilterCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ParseProperties.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ParseProperties.h
+# End Source File
+# End Group
+# Begin Group "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 "PPMD"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDContext.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDDecoder.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDSubAlloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDType.h
+# End Source File
+# End Group
+# Begin Group "Branch"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86_2.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86_2.h
+# End Source File
+# End Group
+# Begin Group "LZMA"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMA.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMADecoder.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMADecoder.h
+# End Source File
+# End Group
+# Begin Group "Copy"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.h
+# End Source File
+# End Group
+# Begin Group "RangeCoder"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoderBitTree.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoderOpt.h
+# End Source File
+# End Group
+# Begin Group "Deflate"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Deflate\DeflateConst.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Deflate\DeflateDecoder.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Deflate\DeflateDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Deflate\DeflateExtConst.h
+# End Source File
+# End Group
+# Begin Group "BZip2"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\BZip2\BZip2Const.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BZip2\BZip2CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BZip2\BZip2CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BZip2\BZip2Decoder.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BZip2\BZip2Decoder.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "Crypto"
+
+# PROP Default_Filter ""
+# Begin Group "AES"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aes.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\AES_CBC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aescpp.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aescrypt.c
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aeskey.c
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aesopt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aestab.c
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\MyAES.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\MyAES.h
+# End Source File
+# End Group
+# Begin Group "7zAES"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAES\7zAES.cpp
+
+!IF "$(CFG)" == "7z - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7z - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAES\7zAES.h
+# End Source File
+# End Group
+# Begin Group "Hash"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\Sha256.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\Sha256.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "7z"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zExtract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHeader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zMethodID.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zMethodID.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zMethods.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zProperties.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zProperties.h
+# End Source File
+# 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\LockedStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFDecoder.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\StreamBinder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/CPP/7zip/Bundles/Format7zExtract/Format7z.dsw b/CPP/7zip/Bundles/Format7zExtract/Format7z.dsw
new file mode 100755
index 00000000..324dab1f
--- /dev/null
+++ b/CPP/7zip/Bundles/Format7zExtract/Format7z.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "7z"=.\Format7z.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Bundles/Format7zExtract/StdAfx.cpp b/CPP/7zip/Bundles/Format7zExtract/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Bundles/Format7zExtract/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Bundles/Format7zExtract/StdAfx.h b/CPP/7zip/Bundles/Format7zExtract/StdAfx.h
new file mode 100755
index 00000000..2e4be10b
--- /dev/null
+++ b/CPP/7zip/Bundles/Format7zExtract/StdAfx.h
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/Bundles/Format7zExtract/makefile b/CPP/7zip/Bundles/Format7zExtract/makefile
new file mode 100755
index 00000000..e52ab019
--- /dev/null
+++ b/CPP/7zip/Bundles/Format7zExtract/makefile
@@ -0,0 +1,174 @@
+PROG = 7zxa.dll
+DEF_FILE = ../../Archive/Archive.def
+LIBS = $(LIBS) user32.lib oleaut32.lib
+CFLAGS = $(CFLAGS) -I ../../../ \
+ -DEXCLUDE_COM \
+ -DNO_REGISTRY \
+ -DEXTRACT_ONLY \
+ -DFORMAT_7Z \
+ -DCOMPRESS_MT \
+ -DCOMPRESS_BCJ_X86 \
+ -DCOMPRESS_BCJ2 \
+ -DCOMPRESS_BZIP2_DECODER \
+ -DCOMPRESS_BZIP2_MT \
+ -DCOMPRESS_COPY \
+ -DCOMPRESS_DEFLATE_DECODER \
+ -DCOMPRESS_LZMA \
+ -DCOMPRESS_PPMD \
+ -DCRYPTO_7ZAES \
+ -DCRYPTO_AES \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\CRC.obj \
+ $O\IntToString.obj \
+ $O\NewHandler.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\Vector.obj \
+ $O\Wildcard.obj \
+
+WIN_OBJS = \
+ $O\FileDir.obj \
+ $O\FileFind.obj \
+ $O\FileIO.obj \
+ $O\PropVariant.obj \
+ $O\Synchronization.obj
+
+7ZIP_COMMON_OBJS = \
+ $O\InBuffer.obj \
+ $O\InOutTempBuffer.obj \
+ $O\LimitedStreams.obj \
+ $O\LockedStream.obj \
+ $O\LSBFDecoder.obj \
+ $O\OutBuffer.obj \
+ $O\ProgressUtils.obj \
+ $O\StreamBinder.obj \
+ $O\StreamObjects.obj \
+ $O\StreamUtils.obj \
+
+AR_COMMON_OBJS = \
+ $O\CoderMixer2.obj \
+ $O\CoderMixer2MT.obj \
+ $O\CrossThreadProgress.obj \
+ $O\FilterCoder.obj \
+ $O\ItemNameUtils.obj \
+ $O\OutStreamWithCRC.obj \
+ $O\ParseProperties.obj \
+
+
+7Z_OBJS = \
+ $O\DllExports.obj \
+ $O\7zCompressionMode.obj \
+ $O\7zDecode.obj \
+ $O\7zExtract.obj \
+ $O\7zFolderOutStream.obj \
+ $O\7zHandler.obj \
+ $O\7zHeader.obj \
+ $O\7zIn.obj \
+ $O\7zMethodID.obj \
+ $O\7zProperties.obj \
+
+
+BRANCH_OPT_OBJS = \
+ $O\BranchCoder.obj \
+ $O\x86.obj \
+ $O\x86_2.obj \
+
+BZIP2_OBJS = \
+ $O\BZip2CRC.obj \
+
+BZIP2_OPT_OBJS = \
+ $O\BZip2Decoder.obj \
+
+DEFLATE_OPT_OBJS = \
+ $O\DeflateDecoder.obj \
+
+LZ_OBJS = \
+ $O\LZOutWindow.obj \
+
+LZMA_OPT_OBJS = \
+ $O\LZMADecoder.obj \
+
+PPMD_OPT_OBJS = \
+ $O\PPMDDecoder.obj \
+
+
+7ZAES_OPT_OBJS = \
+ $O\7zAES.obj \
+
+AES_OPT_OBJS = \
+ $O\MyAES.obj \
+
+AES_ORIG_OBJS = \
+ $O\aescrypt.obj \
+ $O\aeskey.obj \
+ $O\aestab.obj \
+
+CRYPTO_HASH_OBJS = \
+ $O\Sha256.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(CONSOLE_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $(7Z_OBJS) \
+ $(BZIP2_OBJS) \
+ $(BZIP2_OPT_OBJS) \
+ $(BRANCH_OPT_OBJS) \
+ $(DEFLATE_OPT_OBJS) \
+ $(LZ_OBJS) \
+ $(LZMA_OPT_OBJS) \
+ $(PPMD_OPT_OBJS) \
+ $O\CopyCoder.obj \
+ $(7ZAES_OPT_OBJS) \
+ $(AES_OPT_OBJS) \
+ $(AES_ORIG_OBJS) \
+ $(CRYPTO_HASH_OBJS) \
+ $O\resource.res
+
+
+!include "../../../Build.mak"
+
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
+ $(COMPL)
+
+$(7Z_OBJS): ../../Archive/7z/$(*B).cpp
+ $(COMPL)
+
+$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp
+ $(COMPL_O2)
+$(BZIP2_OBJS): ../../Compress/BZip2/$(*B).cpp
+ $(COMPL)
+$(BZIP2_OPT_OBJS): ../../Compress/BZip2/$(*B).cpp
+ $(COMPL_O2)
+$(DEFLATE_OPT_OBJS): ../../Compress/Deflate/$(*B).cpp
+ $(COMPL_O2)
+$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp
+ $(COMPL)
+$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp
+ $(COMPL_O2)
+$(PPMD_OPT_OBJS): ../../Compress/PPMD/$(*B).cpp
+ $(COMPL_O2)
+
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
+
+$(AES_OPT_OBJS): ../../Crypto/AES/$(*B).cpp
+ $(COMPL_O2)
+$(AES_ORIG_OBJS): ../../Crypto/AES/$(*B).c
+ $(COMPL_O2_W3)
+$(7ZAES_OPT_OBJS): ../../Crypto/7zAES/$(*B).cpp
+ $(COMPL_O2)
+$(CRYPTO_HASH_OBJS): ../../Crypto/Hash/$(*B).cpp
+ $(COMPL_O2)
diff --git a/CPP/7zip/Bundles/Format7zExtract/resource.rc b/CPP/7zip/Bundles/Format7zExtract/resource.rc
new file mode 100755
index 00000000..56e6b5d7
--- /dev/null
+++ b/CPP/7zip/Bundles/Format7zExtract/resource.rc
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("7z Standalone Extracting Plugin", "7zxa")
+
+101 ICON "../../Archive/7z/7z.ico"
diff --git a/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp b/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h b/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h
new file mode 100755
index 00000000..2e4be10b
--- /dev/null
+++ b/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/Bundles/Format7zExtractR/makefile b/CPP/7zip/Bundles/Format7zExtractR/makefile
new file mode 100755
index 00000000..b8bfde85
--- /dev/null
+++ b/CPP/7zip/Bundles/Format7zExtractR/makefile
@@ -0,0 +1,117 @@
+PROG = 7zxr.dll
+DEF_FILE = ../../Archive/Archive.def
+LIBS = $(LIBS) user32.lib oleaut32.lib
+CFLAGS = $(CFLAGS) -I ../../../ \
+ -DEXCLUDE_COM \
+ -DNO_REGISTRY \
+ -DEXTRACT_ONLY \
+ -DFORMAT_7Z \
+ -DCOMPRESS_MT \
+ -DCOMPRESS_BCJ_X86 \
+ -DCOMPRESS_BCJ2 \
+ -DCOMPRESS_COPY \
+ -DCOMPRESS_LZMA \
+ -D_NO_CRYPTO
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\CRC.obj \
+ $O\IntToString.obj \
+ $O\NewHandler.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\Vector.obj \
+ $O\Wildcard.obj \
+
+WIN_OBJS = \
+ $O\FileDir.obj \
+ $O\FileFind.obj \
+ $O\FileIO.obj \
+ $O\PropVariant.obj \
+ $O\Synchronization.obj
+
+7ZIP_COMMON_OBJS = \
+ $O\InBuffer.obj \
+ $O\InOutTempBuffer.obj \
+ $O\LimitedStreams.obj \
+ $O\LockedStream.obj \
+ $O\OutBuffer.obj \
+ $O\ProgressUtils.obj \
+ $O\StreamBinder.obj \
+ $O\StreamObjects.obj \
+ $O\StreamUtils.obj \
+
+AR_COMMON_OBJS = \
+ $O\CoderMixer2.obj \
+ $O\CoderMixer2MT.obj \
+ $O\CrossThreadProgress.obj \
+ $O\FilterCoder.obj \
+ $O\ItemNameUtils.obj \
+ $O\OutStreamWithCRC.obj \
+ $O\ParseProperties.obj \
+
+
+7Z_OBJS = \
+ $O\DllExports.obj \
+ $O\7zCompressionMode.obj \
+ $O\7zDecode.obj \
+ $O\7zExtract.obj \
+ $O\7zFolderOutStream.obj \
+ $O\7zHandler.obj \
+ $O\7zHeader.obj \
+ $O\7zIn.obj \
+ $O\7zMethodID.obj \
+ $O\7zProperties.obj \
+
+
+BRANCH_OPT_OBJS = \
+ $O\BranchCoder.obj \
+ $O\x86.obj \
+ $O\x86_2.obj \
+
+LZ_OBJS = \
+ $O\LZOutWindow.obj \
+
+LZMA_OPT_OBJS = \
+ $O\LZMADecoder.obj \
+
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(CONSOLE_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $(7Z_OBJS) \
+ $(BRANCH_OPT_OBJS) \
+ $(LZ_OBJS) \
+ $(LZMA_OPT_OBJS) \
+ $O\CopyCoder.obj \
+ $O\resource.res
+
+
+!include "../../../Build.mak"
+
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
+ $(COMPL)
+
+$(7Z_OBJS): ../../Archive/7z/$(*B).cpp
+ $(COMPL)
+
+$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp
+ $(COMPL_O2)
+$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp
+ $(COMPL)
+$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp
+ $(COMPL_O2)
+
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/Bundles/Format7zExtractR/resource.rc b/CPP/7zip/Bundles/Format7zExtractR/resource.rc
new file mode 100755
index 00000000..09708cff
--- /dev/null
+++ b/CPP/7zip/Bundles/Format7zExtractR/resource.rc
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("7z Standalone Extracting Plugin", "7zxr")
+
+101 ICON "../../Archive/7z/7z.ico"
diff --git a/CPP/7zip/Bundles/Format7zR/StdAfx.cpp b/CPP/7zip/Bundles/Format7zR/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Bundles/Format7zR/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Bundles/Format7zR/StdAfx.h b/CPP/7zip/Bundles/Format7zR/StdAfx.h
new file mode 100755
index 00000000..2e4be10b
--- /dev/null
+++ b/CPP/7zip/Bundles/Format7zR/StdAfx.h
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/Bundles/Format7zR/makefile b/CPP/7zip/Bundles/Format7zR/makefile
new file mode 100755
index 00000000..d3cc3d55
--- /dev/null
+++ b/CPP/7zip/Bundles/Format7zR/makefile
@@ -0,0 +1,150 @@
+PROG = 7zra.dll
+DEF_FILE = ../../Archive/Archive.def
+LIBS = $(LIBS) user32.lib oleaut32.lib
+CFLAGS = $(CFLAGS) -I ../../../ \
+ -DEXCLUDE_COM \
+ -DNO_REGISTRY \
+ -DFORMAT_7Z \
+ -DCOMPRESS_MT \
+ -DCOMPRESS_BCJ_X86 \
+ -DCOMPRESS_BCJ2 \
+ -DCOMPRESS_COPY \
+ -DCOMPRESS_LZMA \
+ -DCOMPRESS_MF_MT \
+ -D_NO_CRYPTO
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\CRC.obj \
+ $O\IntToString.obj \
+ $O\NewHandler.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\Vector.obj \
+ $O\Wildcard.obj \
+
+WIN_OBJS = \
+ $O\FileDir.obj \
+ $O\FileFind.obj \
+ $O\FileIO.obj \
+ $O\PropVariant.obj \
+ $O\Synchronization.obj
+
+7ZIP_COMMON_OBJS = \
+ $O\InBuffer.obj \
+ $O\InOutTempBuffer.obj \
+ $O\LimitedStreams.obj \
+ $O\LockedStream.obj \
+ $O\OutBuffer.obj \
+ $O\ProgressUtils.obj \
+ $O\StreamBinder.obj \
+ $O\StreamObjects.obj \
+ $O\StreamUtils.obj \
+
+AR_COMMON_OBJS = \
+ $O\CoderMixer2.obj \
+ $O\CoderMixer2MT.obj \
+ $O\CrossThreadProgress.obj \
+ $O\FilterCoder.obj \
+ $O\InStreamWithCRC.obj \
+ $O\ItemNameUtils.obj \
+ $O\OutStreamWithCRC.obj \
+ $O\ParseProperties.obj \
+
+
+7Z_OBJS = \
+ $O\DllExports.obj \
+ $O\7zCompressionMode.obj \
+ $O\7zDecode.obj \
+ $O\7zEncode.obj \
+ $O\7zExtract.obj \
+ $O\7zFolderInStream.obj \
+ $O\7zFolderOutStream.obj \
+ $O\7zHandler.obj \
+ $O\7zHandlerOut.obj \
+ $O\7zHeader.obj \
+ $O\7zIn.obj \
+ $O\7zMethodID.obj \
+ $O\7zOut.obj \
+ $O\7zProperties.obj \
+ $O\7zSpecStream.obj \
+ $O\7zUpdate.obj \
+
+
+BRANCH_OPT_OBJS = \
+ $O\BranchCoder.obj \
+ $O\x86.obj \
+ $O\x86_2.obj \
+
+LZ_OBJS = \
+ $O\LZOutWindow.obj \
+
+LZMA_OPT_OBJS = \
+ $O\LZMADecoder.obj \
+ $O\LZMAEncoder.obj \
+
+C_OBJS = \
+ $O\7zCrc.obj \
+ $O\Sort.obj \
+ $O\Threads.obj \
+
+C_LZ_OBJS = \
+ $O\MatchFinder.obj \
+ $O\MatchFinderMt.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(CONSOLE_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $(7Z_OBJS) \
+ $(BZIP2_OBJS) \
+ $(BZIP2_OPT_OBJS) \
+ $(BRANCH_OPT_OBJS) \
+ $(DEFLATE_OPT_OBJS) \
+ $(LZ_OBJS) \
+ $(LZMA_OPT_OBJS) \
+ $(PPMD_OPT_OBJS) \
+ $(C_OBJS) \
+ $(C_LZ_OBJS) \
+ $O\CopyCoder.obj \
+ $O\RangeCoderBit.obj \
+ $(7ZAES_OPT_OBJS) \
+ $(AES_OPT_OBJS) \
+ $(AES_ORIG_OBJS) \
+ $(CRYPTO_HASH_OBJS) \
+ $O\resource.res
+
+
+!include "../../../Build.mak"
+
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
+ $(COMPL)
+
+$(7Z_OBJS): ../../Archive/7z/$(*B).cpp
+ $(COMPL)
+
+$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp
+ $(COMPL_O2)
+$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp
+ $(COMPL)
+$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp
+ $(COMPL_O2)
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
+$O\RangeCoderBit.obj: ../../Compress/RangeCoder/$(*B).cpp
+ $(COMPL)
+
+$(C_OBJS): ../../../../C/$(*B).c
+ $(COMPL_O2)
+$(C_LZ_OBJS): ../../../../C/Compress/Lz/$(*B).c
+ $(COMPL_O2)
diff --git a/CPP/7zip/Bundles/Format7zR/resource.rc b/CPP/7zip/Bundles/Format7zR/resource.rc
new file mode 100755
index 00000000..60a17fe8
--- /dev/null
+++ b/CPP/7zip/Bundles/Format7zR/resource.rc
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("7z Standalone Plugin", "7zr")
+
+101 ICON "../../Archive/7z/7z.ico"
diff --git a/CPP/7zip/Bundles/SFXCon/7z.ico b/CPP/7zip/Bundles/SFXCon/7z.ico
new file mode 100755
index 00000000..47ffb781
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXCon/7z.ico
Binary files differ
diff --git a/CPP/7zip/Bundles/SFXCon/Main.cpp b/CPP/7zip/Bundles/SFXCon/Main.cpp
new file mode 100755
index 00000000..65ed8931
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXCon/Main.cpp
@@ -0,0 +1,416 @@
+// Main.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+
+#include "Common/CommandLineParser.h"
+#include "Common/StdOutStream.h"
+#include "Common/Wildcard.h"
+#include "Common/StringConvert.h"
+#include "Common/MyCom.h"
+#include "Common/Exception.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileName.h"
+#include "Windows/Defs.h"
+
+#include "../../IPassword.h"
+#include "../../ICoder.h"
+
+#include "../../UI/Common/OpenArchive.h"
+#include "../../UI/Common/DefaultName.h"
+#include "../../UI/Common/ExitCode.h"
+#include "../../UI/Common/Extract.h"
+
+#include "../../UI/Console/List.h"
+#include "../../UI/Console/OpenCallbackConsole.h"
+#include "../../UI/Console/ExtractCallbackConsole.h"
+
+#include "../../MyVersion.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NCommandLineParser;
+
+extern CStdOutStream *g_StdStream;
+
+static const char *kCopyrightString =
+"\n7-Zip SFX " MY_VERSION_COPYRIGHT_DATE "\n";
+
+static const int kNumSwitches = 6;
+
+#ifdef _WIN32
+static const wchar_t *kDefaultExt = L".exe";
+static const int kDefaultExtLength = 4;
+#endif
+
+namespace NKey {
+enum Enum
+{
+ kHelp1 = 0,
+ kHelp2,
+ kDisablePercents,
+ kYes,
+ kPassword,
+ kOutputDir
+};
+
+}
+
+namespace NRecursedType {
+enum EEnum
+{
+ kRecursed,
+ kWildCardOnlyRecursed,
+ kNonRecursed,
+};
+}
+
+static const char kRecursedIDChar = 'R';
+static const wchar_t *kRecursedPostCharSet = L"0-";
+
+namespace NRecursedPostCharIndex {
+ enum EEnum
+ {
+ kWildCardRecursionOnly = 0,
+ kNoRecursion = 1
+ };
+}
+
+static const char kFileListID = '@';
+static const char kImmediateNameID = '!';
+
+static const char kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be
+static const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be
+
+static const CSwitchForm kSwitchForms[kNumSwitches] =
+ {
+ { L"?", NSwitchType::kSimple, false },
+ { L"H", NSwitchType::kSimple, false },
+ { L"BD", NSwitchType::kSimple, false },
+ { L"Y", NSwitchType::kSimple, false },
+ { L"P", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"O", NSwitchType::kUnLimitedPostString, false, 1 },
+ };
+
+static const int kNumCommandForms = 3;
+
+namespace NCommandType {
+enum EEnum
+{
+ kTest = 0,
+ // kExtract,
+ kFullExtract,
+ kList
+};
+
+}
+
+static const CCommandForm commandForms[kNumCommandForms] =
+{
+ { L"T", false },
+ // { "E", false },
+ { L"X", false },
+ { L"L", false }
+};
+
+static const NRecursedType::EEnum kCommandRecursedDefault[kNumCommandForms] =
+{
+ NRecursedType::kRecursed
+};
+
+static const bool kTestExtractRecursedDefault = true;
+static const bool kAddRecursedDefault = false;
+
+static const int kMaxCmdLineSize = 1000;
+static const wchar_t *kUniversalWildcard = L"*";
+static const int kMinNonSwitchWords = 1;
+static const int kCommandIndex = 0;
+
+static const char *kHelpString =
+ "\nUsage: 7zSFX [<command>] [<switches>...]\n"
+ "\n"
+ "<Commands>\n"
+ " l: List contents of archive\n"
+ " t: Test integrity of archive\n"
+ " x: eXtract files with full pathname (default)\n"
+ "<Switches>\n"
+ // " -bd Disable percentage indicator\n"
+ " -o{Directory}: set Output directory\n"
+ " -p{Password}: set Password\n"
+ " -y: assume Yes on all queries\n";
+
+
+// ---------------------------
+// exception messages
+
+static const char *kUserErrorMessage = "Incorrect command line"; // NExitCode::kUserError
+static const char *kIncorrectListFile = "Incorrect wildcard in listfile";
+static const char *kIncorrectWildCardInCommandLine = "Incorrect wildcard in command line";
+
+// static const CSysString kFileIsNotArchiveMessageBefore = "File \"";
+// static const CSysString kFileIsNotArchiveMessageAfter = "\" is not archive";
+
+static const char *kProcessArchiveMessage = " archive: ";
+
+static const char *kCantFindSFX = " cannot find sfx";
+
+
+struct CArchiveCommand
+{
+ NCommandType::EEnum CommandType;
+ NRecursedType::EEnum DefaultRecursedType() const;
+};
+
+NRecursedType::EEnum CArchiveCommand::DefaultRecursedType() const
+{
+ return kCommandRecursedDefault[CommandType];
+}
+
+void PrintHelp(void)
+{
+ g_StdOut << kHelpString;
+}
+
+static void ShowMessageAndThrowException(const char *message, NExitCode::EEnum code)
+{
+ g_StdOut << message << endl;
+ throw code;
+}
+
+static void PrintHelpAndExit() // yyy
+{
+ PrintHelp();
+ ShowMessageAndThrowException(kUserErrorMessage, NExitCode::kUserError);
+}
+
+bool ParseArchiveCommand(const UString &commandString, CArchiveCommand &command)
+{
+ UString commandStringUpper = commandString;
+ commandStringUpper.MakeUpper();
+ UString postString;
+ int commandIndex = ParseCommand(kNumCommandForms, commandForms, commandStringUpper,
+ postString) ;
+ if (commandIndex < 0)
+ return false;
+ command.CommandType = (NCommandType::EEnum)commandIndex;
+ return true;
+}
+
+// ------------------------------------------------------------------
+// filenames functions
+
+static bool AddNameToCensor(NWildcard::CCensor &wildcardCensor,
+ const UString &name, bool include, NRecursedType::EEnum type)
+{
+ /*
+ if(!IsWildCardFilePathLegal(name))
+ return false;
+ */
+ bool isWildCard = DoesNameContainWildCard(name);
+ bool recursed = false;
+
+ switch (type)
+ {
+ case NRecursedType::kWildCardOnlyRecursed:
+ recursed = isWildCard;
+ break;
+ case NRecursedType::kRecursed:
+ recursed = true;
+ break;
+ case NRecursedType::kNonRecursed:
+ recursed = false;
+ break;
+ }
+ wildcardCensor.AddItem(include, name, recursed);
+ return true;
+}
+
+void AddCommandLineWildCardToCensor(NWildcard::CCensor &wildcardCensor,
+ const UString &name, bool include, NRecursedType::EEnum type)
+{
+ if (!AddNameToCensor(wildcardCensor, name, include, type))
+ ShowMessageAndThrowException(kIncorrectWildCardInCommandLine, NExitCode::kUserError);
+}
+
+void AddToCensorFromNonSwitchesStrings(NWildcard::CCensor &wildcardCensor,
+ const UStringVector & /* nonSwitchStrings */, NRecursedType::EEnum type,
+ bool /* thereAreSwitchIncludeWildCards */)
+{
+ AddCommandLineWildCardToCensor(wildcardCensor, kUniversalWildcard, true, type);
+}
+
+
+#ifndef _WIN32
+static void GetArguments(int numArguments, const char *arguments[], UStringVector &parts)
+{
+ parts.Clear();
+ for(int i = 0; i < numArguments; i++)
+ {
+ UString s = MultiByteToUnicodeString(arguments[i]);
+ parts.Add(s);
+ }
+}
+#endif
+
+int Main2(
+ #ifndef _WIN32
+ int numArguments, const char *arguments[]
+ #endif
+)
+{
+ #ifdef _WIN32
+ SetFileApisToOEM();
+ #endif
+
+ g_StdOut << kCopyrightString;
+
+ UStringVector commandStrings;
+ #ifdef _WIN32
+ NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
+ #else
+ GetArguments(numArguments, arguments, commandStrings);
+ #endif
+
+ UString archiveName = commandStrings.Front();
+
+ commandStrings.Delete(0);
+
+ NCommandLineParser::CParser parser(kNumSwitches);
+ try
+ {
+ parser.ParseStrings(kSwitchForms, commandStrings);
+ }
+ catch(...)
+ {
+ PrintHelpAndExit();
+ }
+
+ if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
+ {
+ PrintHelp();
+ return 0;
+ }
+ const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
+
+ int numNonSwitchStrings = nonSwitchStrings.Size();
+
+ CArchiveCommand command;
+ if (numNonSwitchStrings == 0)
+ command.CommandType = NCommandType::kFullExtract;
+ else
+ {
+ if (numNonSwitchStrings > 1)
+ PrintHelpAndExit();
+ if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], command))
+ PrintHelpAndExit();
+ }
+
+
+ NRecursedType::EEnum recursedType;
+ recursedType = command.DefaultRecursedType();
+
+ NWildcard::CCensor wildcardCensor;
+
+ bool thereAreSwitchIncludeWildCards;
+ thereAreSwitchIncludeWildCards = false;
+ AddToCensorFromNonSwitchesStrings(wildcardCensor, nonSwitchStrings, recursedType,
+ thereAreSwitchIncludeWildCards);
+
+ bool yesToAll = parser[NKey::kYes].ThereIs;
+
+ #ifdef _WIN32
+ if (archiveName.Right(kDefaultExtLength).CompareNoCase(kDefaultExt) != 0)
+ archiveName += kDefaultExt;
+ #endif
+
+ // NExtractMode::EEnum extractMode;
+ // bool isExtractGroupCommand = command.IsFromExtractGroup(extractMode);
+
+ bool passwordEnabled = parser[NKey::kPassword].ThereIs;
+
+ UString password;
+ if(passwordEnabled)
+ password = parser[NKey::kPassword].PostStrings[0];
+
+ NFind::CFileInfoW archiveFileInfo;
+ if (!NFind::FindFile(archiveName, archiveFileInfo))
+ throw kCantFindSFX;
+ if (archiveFileInfo.IsDirectory())
+ throw kCantFindSFX;
+
+ UString outputDir;
+ if(parser[NKey::kOutputDir].ThereIs)
+ {
+ outputDir = parser[NKey::kOutputDir].PostStrings[0];
+ NName::NormalizeDirPathPrefix(outputDir);
+ }
+
+ {
+ UStringVector v1, v2;
+ v1.Add(archiveName);
+ v2.Add(archiveName);
+ const NWildcard::CCensorNode &wildcardCensorHead =
+ wildcardCensor.Pairs.Front().Head;
+ if(command.CommandType != NCommandType::kList)
+ {
+ CExtractCallbackConsole *ecs = new CExtractCallbackConsole;
+ CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
+ ecs->OutStream = g_StdStream;
+ ecs->PasswordIsDefined = passwordEnabled;
+ ecs->Password = password;
+ ecs->Init();
+
+ COpenCallbackConsole openCallback;
+ openCallback.OutStream = g_StdStream;
+ openCallback.PasswordIsDefined = passwordEnabled;
+ openCallback.Password = password;
+
+ CExtractOptions eo;
+ eo.StdOutMode = false;
+ eo.PathMode = NExtract::NPathMode::kFullPathnames;
+ eo.TestMode = command.CommandType == NCommandType::kTest;
+ eo.OverwriteMode = yesToAll ?
+ NExtract::NOverwriteMode::kWithoutPrompt :
+ NExtract::NOverwriteMode::kAskBefore;
+ eo.OutputDir = outputDir;
+ eo.YesToAll = yesToAll;
+
+ UString errorMessage;
+ HRESULT result = DecompressArchives(
+ v1, v2,
+ wildcardCensorHead,
+ eo, &openCallback, ecs, errorMessage);
+ if (!errorMessage.IsEmpty())
+ {
+ (*g_StdStream) << endl << "Error: " << errorMessage;;
+ if (result == S_OK)
+ result = E_FAIL;
+ }
+
+ if (ecs->NumArchiveErrors != 0 || ecs->NumFileErrors != 0)
+ {
+ if (ecs->NumArchiveErrors != 0)
+ (*g_StdStream) << endl << "Archive Errors: " << ecs->NumArchiveErrors << endl;
+ if (ecs->NumFileErrors != 0)
+ (*g_StdStream) << endl << "Sub items Errors: " << ecs->NumFileErrors << endl;
+ return NExitCode::kFatalError;
+ }
+ if (result != S_OK)
+ throw CSystemException(result);
+ }
+ else
+ {
+ HRESULT result = ListArchives(
+ v1, v2,
+ wildcardCensorHead,
+ true, false,
+ passwordEnabled,
+ password);
+ if (result != S_OK)
+ throw CSystemException(result);
+ }
+ }
+ return 0;
+}
diff --git a/CPP/7zip/Bundles/SFXCon/SFXCon.dsp b/CPP/7zip/Bundles/SFXCon/SFXCon.dsp
new file mode 100755
index 00000000..5b61dae3
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXCon/SFXCon.dsp
@@ -0,0 +1,759 @@
+# Microsoft Developer Studio Project File - Name="SFXCon" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=SFXCon - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "SFXCon.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "SFXCon.mak" CFG="SFXCon - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "SFXCon - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "SFXCon - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "SFXCon - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "COMPRESS_BCJ2" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_COPY" /D "COMPRESS_PPMD" /D "_SFX" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\Util\7zCon.sfx" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "SFXCon - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "..\..\..\..\\" /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_COPY" /D "COMPRESS_PPMD" /D "_SFX" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\Util\7zCon.sfx" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "SFXCon - Win32 Release"
+# Name "SFXCon - Win32 Debug"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Archive Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2MT.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2ST.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2ST.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\FilterCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\FilterCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.h
+# End Source File
+# End Group
+# Begin Group "Console"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ConsoleClose.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ConsoleClose.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ExtractCallbackConsole.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ExtractCallbackConsole.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\List.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\List.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\MainAr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\OpenCallbackConsole.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\OpenCallbackConsole.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\UserInputUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\UserInputUtils.h
+# End Source File
+# End Group
+# Begin Group "7z"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zExtract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHeader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zMethodID.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zMethodID.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Group "LZMA"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMADecoder.cpp
+# End Source File
+# End Group
+# Begin Group "Branch"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86_2.cpp
+# End Source File
+# End Group
+# Begin Group "PPMD"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDDecoder.cpp
+# End Source File
+# End Group
+# 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 "Copy"
+
+# PROP Default_Filter ""
+# 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 Group
+# Begin Group "Crypto"
+
+# PROP Default_Filter ""
+# Begin Group "7zAES"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAES\7zAES.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAES\7zAES.h
+# End Source File
+# End Group
+# Begin Group "AES"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aes.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\AES_CBC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aescpp.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aescrypt.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aeskey.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aesopt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aestab.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\MyAES.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\MyAES.h
+# End Source File
+# End Group
+# Begin Group "Hash"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\RotateDefs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\Sha256.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\Sha256.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "SDK"
+
+# PROP Default_Filter ""
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Error.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Error.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.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\CommandLineParser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdInStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdInStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\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\Vector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Vector.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.h
+# End Source File
+# End Group
+# Begin Group "7zip Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\FilePathAutoRename.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilePathAutoRename.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OffsetStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OffsetStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# End Group
+# Begin Group "UI"
+
+# PROP Default_Filter ""
+# Begin Group "UI Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveExtractCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveOpenCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiverInfo.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiverInfo.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\DefaultName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\DefaultName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ExitCode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Extract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Extract.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ExtractingFilePath.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ExtractingFilePath.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ExtractMode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\OpenArchive.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\OpenArchive.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\PropIDUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\PropIDUtils.h
+# End Source File
+# End Group
+# End Group
+# Begin Source File
+
+SOURCE=.\7z.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\Main.cpp
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/Bundles/SFXCon/SFXCon.dsw b/CPP/7zip/Bundles/SFXCon/SFXCon.dsw
new file mode 100755
index 00000000..27bf7e6d
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXCon/SFXCon.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "SFXCon"=.\SFXCon.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Bundles/SFXCon/StdAfx.cpp b/CPP/7zip/Bundles/SFXCon/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXCon/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Bundles/SFXCon/StdAfx.h b/CPP/7zip/Bundles/SFXCon/StdAfx.h
new file mode 100755
index 00000000..2e4be10b
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXCon/StdAfx.h
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/Bundles/SFXCon/makefile b/CPP/7zip/Bundles/SFXCon/makefile
new file mode 100755
index 00000000..7501a497
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXCon/makefile
@@ -0,0 +1,180 @@
+PROG = 7zCon.sfx
+LIBS = $(LIBS) user32.lib oleaut32.lib
+CFLAGS = $(CFLAGS) -I ../../../ \
+ -DEXCLUDE_COM \
+ -DNO_REGISTRY \
+ -DEXTRACT_ONLY \
+ -D_SFX \
+ -DFORMAT_7Z \
+ -DCOMPRESS_BCJ_X86 \
+ -DCOMPRESS_BCJ2 \
+ -DCOMPRESS_COPY \
+ -DCOMPRESS_LZMA \
+ -DCOMPRESS_PPMD \
+ -DCRYPTO_7ZAES \
+ -DCRYPTO_AES \
+
+SFX_CONSOLE_OBJS = \
+ $O\Main.obj \
+
+CONSOLE_OBJS = \
+ $O\ConsoleClose.obj \
+ $O\ExtractCallbackConsole.obj \
+ $O\List.obj \
+ $O\MainAr.obj \
+ $O\OpenCallbackConsole.obj \
+ $O\UserInputUtils.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\CommandLineParser.obj \
+ $O\CRC.obj \
+ $O\IntToString.obj \
+ $O\NewHandler.obj \
+ $O\StdInStream.obj \
+ $O\StdOutStream.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\Vector.obj \
+ $O\Wildcard.obj \
+
+WIN_OBJS = \
+ $O\Error.obj \
+ $O\FileDir.obj \
+ $O\FileFind.obj \
+ $O\FileIO.obj \
+ $O\FileName.obj \
+ $O\PropVariant.obj \
+ $O\PropVariantConversions.obj \
+ $O\Synchronization.obj
+
+7ZIP_COMMON_OBJS = \
+ $O\FilePathAutoRename.obj \
+ $O\FileStreams.obj \
+ $O\InBuffer.obj \
+ $O\LimitedStreams.obj \
+ $O\LockedStream.obj \
+ $O\OutBuffer.obj \
+ $O\ProgressUtils.obj \
+ $O\StreamBinder.obj \
+ $O\StreamObjects.obj \
+ $O\StreamUtils.obj \
+
+UI_COMMON_OBJS = \
+ $O\ArchiveExtractCallback.obj \
+ $O\ArchiveOpenCallback.obj \
+ $O\ArchiverInfo.obj \
+ $O\DefaultName.obj \
+ $O\Extract.obj \
+ $O\ExtractingFilePath.obj \
+ $O\OpenArchive.obj \
+ $O\PropIDUtils.obj \
+
+AR_COMMON_OBJS = \
+ $O\CoderMixer2.obj \
+ $O\CoderMixer2MT.obj \
+ $O\CrossThreadProgress.obj \
+ $O\FilterCoder.obj \
+ $O\ItemNameUtils.obj \
+ $O\OutStreamWithCRC.obj \
+
+
+7Z_OBJS = \
+ $O\7zDecode.obj \
+ $O\7zExtract.obj \
+ $O\7zFolderOutStream.obj \
+ $O\7zHandler.obj \
+ $O\7zHeader.obj \
+ $O\7zIn.obj \
+ $O\7zMethodID.obj \
+
+BRANCH_OPT_OBJS = \
+ $O\BranchCoder.obj \
+ $O\x86.obj \
+ $O\x86_2.obj \
+
+LZ_OBJS = \
+ $O\LZOutWindow.obj \
+
+LZMA_OPT_OBJS = \
+ $O\LZMADecoder.obj \
+
+PPMD_OPT_OBJS = \
+ $O\PPMDDecoder.obj \
+
+7ZAES_OPT_OBJS = \
+ $O\7zAES.obj \
+
+AES_OPT_OBJS = \
+ $O\MyAES.obj \
+
+AES_ORIG_OBJS = \
+ $O\aescrypt.obj \
+ $O\aeskey.obj \
+ $O\aestab.obj \
+
+CRYPTO_HASH_OBJS = \
+ $O\Sha256.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(SFX_CONSOLE_OBJS) \
+ $(CONSOLE_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(UI_COMMON_OBJS) \
+ $(AR_COMMON_OBJS) \
+ $(7Z_OBJS) \
+ $(BRANCH_OPT_OBJS) \
+ $(LZ_OBJS) \
+ $(LZMA_OPT_OBJS) \
+ $(PPMD_OPT_OBJS) \
+ $O\CopyCoder.obj \
+ $(7ZAES_OPT_OBJS) \
+ $(AES_OPT_OBJS) \
+ $(AES_ORIG_OBJS) \
+ $(CRYPTO_HASH_OBJS) \
+ $O\resource.res
+
+
+!include "../../../Build.mak"
+
+$(SFX_CONSOLE_OBJS): $(*B).cpp
+ $(COMPL)
+
+$(CONSOLE_OBJS): ../../UI/Console/$(*B).cpp
+ $(COMPL)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp
+ $(COMPL)
+$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
+ $(COMPL)
+
+$(7Z_OBJS): ../../Archive/7z/$(*B).cpp
+ $(COMPL)
+$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp
+ $(COMPL)
+$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp
+ $(COMPL)
+$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp
+ $(COMPL)
+$(PPMD_OPT_OBJS): ../../Compress/PPMD/$(*B).cpp
+ $(COMPL)
+
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
+
+$(AES_OPT_OBJS): ../../Crypto/AES/$(*B).cpp
+ $(COMPL)
+$(AES_ORIG_OBJS): ../../Crypto/AES/$(*B).c
+ $(COMPL_O1_W3)
+$(7ZAES_OPT_OBJS): ../../Crypto/7zAES/$(*B).cpp
+ $(COMPL)
+$(CRYPTO_HASH_OBJS): ../../Crypto/Hash/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/Bundles/SFXCon/resource.rc b/CPP/7zip/Bundles/SFXCon/resource.rc
new file mode 100755
index 00000000..58331b81
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXCon/resource.rc
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_APP("7z Console SFX", "7z.sfx")
+
+101 ICON "7z.ico" \ No newline at end of file
diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractCallback.cpp b/CPP/7zip/Bundles/SFXSetup/ExtractCallback.cpp
new file mode 100755
index 00000000..6294516c
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXSetup/ExtractCallback.cpp
@@ -0,0 +1,249 @@
+// ExtractCallback.h
+
+#include "StdAfx.h"
+
+#include "ExtractCallback.h"
+
+#include "Common/Wildcard.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/COM.h"
+#include "Windows/FileDir.h"
+#include "Windows/FileFind.h"
+#include "Windows/Time.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+
+#include "Windows/PropVariantConversions.h"
+
+using namespace NWindows;
+using namespace NFile;
+
+static LPCWSTR kErrorTitle = L"7-Zip";
+static LPCWSTR kCantDeleteFile = L"Can not delete output file";
+static LPCWSTR kCantOpenFile = L"Can not open output file";
+static LPCWSTR kUnsupportedMethod = L"Unsupported Method";
+// static LPCWSTR kCRCFailed = L"CRC Failed";
+// static LPCWSTR kDataError = L"Data Error";
+// static LPCWSTR kUnknownError = L""Unknown Error";
+
+void CExtractCallbackImp::Init(IInArchive *archiveHandler,
+ const UString &directoryPath,
+ const UString &itemDefaultName,
+ const FILETIME &utcLastWriteTimeDefault,
+ UInt32 attributesDefault)
+{
+ _message.Empty();
+ _isCorrupt = false;
+ _itemDefaultName = itemDefaultName;
+ _utcLastWriteTimeDefault = utcLastWriteTimeDefault;
+ _attributesDefault = attributesDefault;
+ _archiveHandler = archiveHandler;
+ _directoryPath = directoryPath;
+ NName::NormalizeDirPathPrefix(_directoryPath);
+}
+
+STDMETHODIMP CExtractCallbackImp::SetTotal(UInt64 size)
+{
+ #ifndef _NO_PROGRESS
+ ProgressDialog.ProgressSynch.SetProgress(size, 0);
+ #endif
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::SetCompleted(const UInt64 *completeValue)
+{
+ #ifndef _NO_PROGRESS
+ for (;;)
+ {
+ if(ProgressDialog.ProgressSynch.GetStopped())
+ return E_ABORT;
+ if(!ProgressDialog.ProgressSynch.GetPaused())
+ break;
+ ::Sleep(100);
+ }
+ if (completeValue != NULL)
+ ProgressDialog.ProgressSynch.SetPos(*completeValue);
+ #endif
+ return S_OK;
+}
+
+void CExtractCallbackImp::CreateComplexDirectory(const UStringVector &dirPathParts)
+{
+ UString fullPath = _directoryPath;
+ for(int i = 0; i < dirPathParts.Size(); i++)
+ {
+ fullPath += dirPathParts[i];
+ NDirectory::MyCreateDirectory(fullPath);
+ fullPath += NName::kDirDelimiter;
+ }
+}
+
+STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index,
+ ISequentialOutStream **outStream, Int32 askExtractMode)
+{
+ #ifndef _NO_PROGRESS
+ if(ProgressDialog.ProgressSynch.GetStopped())
+ return E_ABORT;
+ #endif
+ _outFileStream.Release();
+ NCOM::CPropVariant propVariantName;
+ RINOK(_archiveHandler->GetProperty(index, kpidPath, &propVariantName));
+ UString fullPath;
+ if(propVariantName.vt == VT_EMPTY)
+ fullPath = _itemDefaultName;
+ else
+ {
+ if(propVariantName.vt != VT_BSTR)
+ return E_FAIL;
+ fullPath = propVariantName.bstrVal;
+ }
+ _filePath = fullPath;
+
+ // m_CurrentFilePath = GetSystemString(fullPath, _codePage);
+
+ if(askExtractMode == NArchive::NExtract::NAskMode::kExtract)
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(_archiveHandler->GetProperty(index, kpidAttributes, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ _processedFileInfo.Attributes = _attributesDefault;
+ else
+ {
+ if (propVariant.vt != VT_UI4)
+ return E_FAIL;
+ _processedFileInfo.Attributes = propVariant.ulVal;
+ }
+
+ RINOK(_archiveHandler->GetProperty(index, kpidIsFolder, &propVariant));
+ _processedFileInfo.IsDirectory = VARIANT_BOOLToBool(propVariant.boolVal);
+
+ bool isAnti = false;
+ {
+ NCOM::CPropVariant propVariantTemp;
+ RINOK(_archiveHandler->GetProperty(index, kpidIsAnti,
+ &propVariantTemp));
+ if (propVariantTemp.vt == VT_BOOL)
+ isAnti = VARIANT_BOOLToBool(propVariantTemp.boolVal);
+ }
+
+ RINOK(_archiveHandler->GetProperty(index, kpidLastWriteTime, &propVariant));
+ switch(propVariant.vt)
+ {
+ case VT_EMPTY:
+ _processedFileInfo.UTCLastWriteTime = _utcLastWriteTimeDefault;
+ break;
+ case VT_FILETIME:
+ _processedFileInfo.UTCLastWriteTime = propVariant.filetime;
+ break;
+ default:
+ return E_FAIL;
+ }
+
+ UStringVector pathParts;
+ SplitPathToParts(fullPath, pathParts);
+ if(pathParts.IsEmpty())
+ return E_FAIL;
+
+ UString processedPath = fullPath;
+
+ if(!_processedFileInfo.IsDirectory)
+ pathParts.DeleteBack();
+ if (!pathParts.IsEmpty())
+ {
+ if (!isAnti)
+ CreateComplexDirectory(pathParts);
+ }
+
+ UString fullProcessedPath = _directoryPath + processedPath;
+
+ if(_processedFileInfo.IsDirectory)
+ {
+ _diskFilePath = fullProcessedPath;
+
+ if (isAnti)
+ NDirectory::MyRemoveDirectory(_diskFilePath);
+ return S_OK;
+ }
+
+ NFind::CFileInfoW fileInfo;
+ if(NFind::FindFile(fullProcessedPath, fileInfo))
+ {
+ if (!NDirectory::DeleteFileAlways(fullProcessedPath))
+ {
+ _message = kCantDeleteFile;
+ return E_FAIL;
+ }
+ }
+
+ if (!isAnti)
+ {
+ _outFileStreamSpec = new COutFileStream;
+ CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
+ if (!_outFileStreamSpec->Create(fullProcessedPath, true))
+ {
+ _message = kCantOpenFile;
+ return E_FAIL;
+ }
+ _outFileStream = outStreamLoc;
+ *outStream = outStreamLoc.Detach();
+ }
+ _diskFilePath = fullProcessedPath;
+ }
+ else
+ {
+ *outStream = NULL;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::PrepareOperation(Int32 askExtractMode)
+{
+ _extractMode = false;
+ switch (askExtractMode)
+ {
+ case NArchive::NExtract::NAskMode::kExtract:
+ _extractMode = true;
+ break;
+ };
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 resultEOperationResult)
+{
+ switch(resultEOperationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kOK:
+ {
+ break;
+ }
+ default:
+ {
+ _outFileStream.Release();
+ switch(resultEOperationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
+ _message = kUnsupportedMethod;
+ break;
+ case NArchive::NExtract::NOperationResult::kCRCError:
+ _isCorrupt = true;
+ // _message = kCRCFailed;
+ break;
+ case NArchive::NExtract::NOperationResult::kDataError:
+ _isCorrupt = true;
+ // _message = kDataError;
+ break;
+ default:
+ _isCorrupt = true;
+ }
+ return E_FAIL;
+ }
+ }
+ if(_outFileStream != NULL)
+ _outFileStreamSpec->File.SetLastWriteTime(&_processedFileInfo.UTCLastWriteTime);
+ _outFileStream.Release();
+ if (_extractMode)
+ NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attributes);
+ return S_OK;
+}
+
diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractCallback.h b/CPP/7zip/Bundles/SFXSetup/ExtractCallback.h
new file mode 100755
index 00000000..f3880890
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXSetup/ExtractCallback.h
@@ -0,0 +1,96 @@
+// ExtractCallback.h
+
+#ifndef __EXTRACTCALLBACK_H
+#define __EXTRACTCALLBACK_H
+
+#include "resource.h"
+
+#include "Common/String.h"
+#include "Windows/ResourceString.h"
+
+#include "../../Archive/IArchive.h"
+
+#include "../../Common/FileStreams.h"
+#include "../../ICoder.h"
+
+#ifndef _NO_PROGRESS
+#include "../../FileManager/Resource/ProgressDialog/ProgressDialog.h"
+#endif
+
+class CExtractCallbackImp:
+ public IArchiveExtractCallback,
+ public CMyUnknownImp
+{
+public:
+
+ MY_UNKNOWN_IMP
+
+ // IProgress
+ STDMETHOD(SetTotal)(UInt64 size);
+ STDMETHOD(SetCompleted)(const UInt64 *completeValue);
+
+ // IExtractCallback
+ STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream,
+ Int32 askExtractMode);
+ STDMETHOD(PrepareOperation)(Int32 askExtractMode);
+ STDMETHOD(SetOperationResult)(Int32 resultEOperationResult);
+
+private:
+ CMyComPtr<IInArchive> _archiveHandler;
+ UString _directoryPath;
+
+ UString _filePath;
+
+ UString _diskFilePath;
+
+ bool _extractMode;
+ struct CProcessedFileInfo
+ {
+ FILETIME UTCLastWriteTime;
+ bool IsDirectory;
+ UInt32 Attributes;
+ } _processedFileInfo;
+
+ COutFileStream *_outFileStreamSpec;
+ CMyComPtr<ISequentialOutStream> _outFileStream;
+
+ UString _itemDefaultName;
+ FILETIME _utcLastWriteTimeDefault;
+ UInt32 _attributesDefault;
+
+ void CreateComplexDirectory(const UStringVector &dirPathParts);
+public:
+ #ifndef _NO_PROGRESS
+ CProgressDialog ProgressDialog;
+ #endif
+
+ bool _isCorrupt;
+ UString _message;
+
+ void Init(IInArchive *archiveHandler,
+ const UString &directoryPath,
+ const UString &itemDefaultName,
+ const FILETIME &utcLastWriteTimeDefault,
+ UInt32 attributesDefault);
+
+ #ifndef _NO_PROGRESS
+ HRESULT StartProgressDialog(const UString &title)
+ {
+ ProgressDialog.Create(title, 0);
+ {
+ #ifdef LANG
+ ProgressDialog.SetText(LangLoadString(IDS_PROGRESS_EXTRACTING, 0x02000890));
+ #else
+ ProgressDialog.SetText(NWindows::MyLoadStringW(IDS_PROGRESS_EXTRACTING));
+ #endif
+ }
+
+ ProgressDialog.Show(SW_SHOWNORMAL);
+ return S_OK;
+ }
+ virtual ~CExtractCallbackImp() { ProgressDialog.Destroy(); }
+ #endif
+
+};
+
+#endif
diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp b/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp
new file mode 100755
index 00000000..19fcb0d2
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp
@@ -0,0 +1,139 @@
+// ExtractEngine.cpp
+
+#include "StdAfx.h"
+
+#include "ExtractEngine.h"
+
+#include "Common/StringConvert.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileFind.h"
+#include "Windows/Thread.h"
+
+#include "../../UI/Common/OpenArchive.h"
+
+#include "../../UI/Explorer/MyMessages.h"
+#include "../../FileManager/FormatUtils.h"
+
+#include "ExtractCallback.h"
+
+using namespace NWindows;
+
+struct CThreadExtracting
+{
+ CArchiveLink ArchiveLink;
+
+ CExtractCallbackImp *ExtractCallbackSpec;
+ CMyComPtr<IArchiveExtractCallback> ExtractCallback;
+
+ #ifndef _NO_PROGRESS
+ HRESULT Result;
+
+ HRESULT Extract()
+ {
+ return ArchiveLink.GetArchive()->Extract(0, (UInt32)-1 , BoolToInt(false), ExtractCallback);
+ }
+ DWORD Process()
+ {
+ ExtractCallbackSpec->ProgressDialog.WaitCreating();
+ Result = Extract();
+ ExtractCallbackSpec->ProgressDialog.MyClose();
+ return 0;
+ }
+ static DWORD WINAPI MyThreadFunction(void *param)
+ {
+ return ((CThreadExtracting *)param)->Process();
+ }
+ #endif
+};
+
+static const LPCWSTR kCantFindArchive = L"Can not find archive file";
+static const LPCWSTR kCantOpenArchive = L"File is not correct archive";
+
+HRESULT ExtractArchive(
+ const UString &fileName,
+ const UString &folderName,
+ COpenCallbackGUI *openCallback,
+ bool showProgress,
+ bool &isCorrupt,
+ UString &errorMessage)
+{
+ isCorrupt = false;
+ NFile::NFind::CFileInfoW archiveFileInfo;
+ if (!NFile::NFind::FindFile(fileName, archiveFileInfo))
+ {
+ errorMessage = kCantFindArchive;
+ return E_FAIL;
+ }
+
+ CThreadExtracting extracter;
+
+ HRESULT result = MyOpenArchive(fileName, extracter.ArchiveLink, openCallback);
+
+ if (result != S_OK)
+ {
+ errorMessage = kCantOpenArchive;
+ return result;
+ }
+
+ UString directoryPath = folderName;
+ NFile::NName::NormalizeDirPathPrefix(directoryPath);
+
+ /*
+ UString directoryPath;
+ {
+ UString fullPath;
+ int fileNamePartStartIndex;
+ if (!NWindows::NFile::NDirectory::MyGetFullPathName(fileName, fullPath, fileNamePartStartIndex))
+ {
+ MessageBox(NULL, "Error 1329484", "7-Zip", 0);
+ return E_FAIL;
+ }
+ directoryPath = fullPath.Left(fileNamePartStartIndex);
+ }
+ */
+
+ if(!NFile::NDirectory::CreateComplexDirectory(directoryPath))
+ {
+ errorMessage = MyFormatNew(IDS_CANNOT_CREATE_FOLDER,
+ #ifdef LANG
+ 0x02000603,
+ #endif
+ directoryPath);
+ return E_FAIL;
+ }
+
+ extracter.ExtractCallbackSpec = new CExtractCallbackImp;
+ extracter.ExtractCallback = extracter.ExtractCallbackSpec;
+
+ extracter.ExtractCallbackSpec->Init(
+ extracter.ArchiveLink.GetArchive(),
+ directoryPath, L"Default", archiveFileInfo.LastWriteTime, 0);
+
+ #ifndef _NO_PROGRESS
+
+ if (showProgress)
+ {
+ CThread thread;
+ if (!thread.Create(CThreadExtracting::MyThreadFunction, &extracter))
+ throw 271824;
+
+ UString title;
+ #ifdef LANG
+ title = LangLoadString(IDS_PROGRESS_EXTRACTING, 0x02000890);
+ #else
+ title = NWindows::MyLoadStringW(IDS_PROGRESS_EXTRACTING);
+ #endif
+ extracter.ExtractCallbackSpec->StartProgressDialog(title);
+ result = extracter.Result;
+ }
+ else
+
+ #endif
+ {
+ result = extracter.Extract();
+ }
+ errorMessage = extracter.ExtractCallbackSpec->_message;
+ isCorrupt = extracter.ExtractCallbackSpec->_isCorrupt;
+ return result;
+}
diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h b/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h
new file mode 100755
index 00000000..595d2b29
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h
@@ -0,0 +1,17 @@
+// ExtractEngine.h
+
+#ifndef __EXTRACTENGINE_H
+#define __EXTRACTENGINE_H
+
+#include "Common/String.h"
+#include "../../UI/GUI/OpenCallbackGUI.h"
+
+HRESULT ExtractArchive(
+ const UString &fileName,
+ const UString &folderName,
+ COpenCallbackGUI *openCallback,
+ bool showProgress,
+ bool &isCorrupt,
+ UString &errorMessage);
+
+#endif
diff --git a/CPP/7zip/Bundles/SFXSetup/Main.cpp b/CPP/7zip/Bundles/SFXSetup/Main.cpp
new file mode 100755
index 00000000..12de5c01
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXSetup/Main.cpp
@@ -0,0 +1,335 @@
+// Main.cpp
+
+#include "StdAfx.h"
+
+#include <initguid.h>
+
+#include "Common/StringConvert.h"
+#include "Common/Random.h"
+#include "Common/TextConfig.h"
+#include "Common/CommandLineParser.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileIO.h"
+#include "Windows/FileFind.h"
+#include "Windows/FileName.h"
+#include "Windows/DLL.h"
+#include "Windows/ResourceString.h"
+
+#include "../../IPassword.h"
+#include "../../ICoder.h"
+#include "../../Archive/IArchive.h"
+#include "../../UI/Explorer/MyMessages.h"
+
+// #include "../../UI/GUI/ExtractGUI.h"
+
+#include "ExtractEngine.h"
+
+#include "resource.h"
+
+using namespace NWindows;
+
+HINSTANCE g_hInstance;
+
+static LPCTSTR kTempDirPrefix = TEXT("7zS");
+
+#define _SHELL_EXECUTE
+
+static bool ReadDataString(LPCWSTR fileName, LPCSTR startID,
+ LPCSTR endID, AString &stringResult)
+{
+ stringResult.Empty();
+ NFile::NIO::CInFile inFile;
+ if (!inFile.Open(fileName))
+ return false;
+ const int kBufferSize = (1 << 12);
+
+ Byte buffer[kBufferSize];
+ int signatureStartSize = lstrlenA(startID);
+ int signatureEndSize = lstrlenA(endID);
+
+ UInt32 numBytesPrev = 0;
+ bool writeMode = false;
+ UInt64 posTotal = 0;
+ for (;;)
+ {
+ if (posTotal > (1 << 20))
+ return (stringResult.IsEmpty());
+ UInt32 numReadBytes = kBufferSize - numBytesPrev;
+ UInt32 processedSize;
+ if (!inFile.Read(buffer + numBytesPrev, numReadBytes, processedSize))
+ return false;
+ if (processedSize == 0)
+ return true;
+ UInt32 numBytesInBuffer = numBytesPrev + processedSize;
+ UInt32 pos = 0;
+ for (;;)
+ {
+ if (writeMode)
+ {
+ if (pos > numBytesInBuffer - signatureEndSize)
+ break;
+ if (memcmp(buffer + pos, endID, signatureEndSize) == 0)
+ return true;
+ char b = buffer[pos];
+ if (b == 0)
+ return false;
+ stringResult += b;
+ pos++;
+ }
+ else
+ {
+ if (pos > numBytesInBuffer - signatureStartSize)
+ break;
+ if (memcmp(buffer + pos, startID, signatureStartSize) == 0)
+ {
+ writeMode = true;
+ pos += signatureStartSize;
+ }
+ else
+ pos++;
+ }
+ }
+ numBytesPrev = numBytesInBuffer - pos;
+ posTotal += pos;
+ memmove(buffer, buffer + pos, numBytesPrev);
+ }
+}
+
+static char kStartID[] = ",!@Install@!UTF-8!";
+static char kEndID[] = ",!@InstallEnd@!";
+
+class CInstallIDInit
+{
+public:
+ CInstallIDInit()
+ {
+ kStartID[0] = ';';
+ kEndID[0] = ';';
+ };
+} g_CInstallIDInit;
+
+
+class CCurrentDirRestorer
+{
+ CSysString m_CurrentDirectory;
+public:
+ CCurrentDirRestorer()
+ { NFile::NDirectory::MyGetCurrentDirectory(m_CurrentDirectory); }
+ ~CCurrentDirRestorer()
+ { RestoreDirectory();}
+ bool RestoreDirectory()
+ { return BOOLToBool(::SetCurrentDirectory(m_CurrentDirectory)); }
+};
+
+#ifndef _UNICODE
+bool g_IsNT = false;
+static inline bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+#endif
+
+int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, LPSTR /* lpCmdLine */,int /* nCmdShow */)
+{
+ g_hInstance = (HINSTANCE)hInstance;
+ #ifndef _UNICODE
+ g_IsNT = IsItWindowsNT();
+ #endif
+ InitCommonControls();
+
+ UString archiveName, switches;
+ #ifdef _SHELL_EXECUTE
+ UString executeFile, executeParameters;
+ #endif
+ NCommandLineParser::SplitCommandLine(GetCommandLineW(), archiveName, switches);
+
+ UString fullPath;
+ NDLL::MyGetModuleFileName(g_hInstance, fullPath);
+
+ switches.Trim();
+ bool assumeYes = false;
+ if (switches.Left(2).CompareNoCase(UString(L"-y")) == 0)
+ {
+ assumeYes = true;
+ switches = switches.Mid(2);
+ switches.Trim();
+ }
+
+ AString config;
+ if (!ReadDataString(fullPath, kStartID, kEndID, config))
+ {
+ if (!assumeYes)
+ MyMessageBox(L"Can't load config info");
+ return 1;
+ }
+
+ UString dirPrefix = L".\\";
+ UString appLaunched;
+ bool showProgress = true;
+ if (!config.IsEmpty())
+ {
+ CObjectVector<CTextConfigPair> pairs;
+ if (!GetTextConfig(config, pairs))
+ {
+ if (!assumeYes)
+ MyMessageBox(L"Config failed");
+ return 1;
+ }
+ UString friendlyName = GetTextConfigValue(pairs, L"Title");
+ UString installPrompt = GetTextConfigValue(pairs, L"BeginPrompt");
+ UString progress = GetTextConfigValue(pairs, L"Progress");
+ if (progress.CompareNoCase(L"no") == 0)
+ showProgress = false;
+ int index = FindTextConfigItem(pairs, L"Directory");
+ if (index >= 0)
+ dirPrefix = pairs[index].String;
+ if (!installPrompt.IsEmpty() && !assumeYes)
+ {
+ if (MessageBoxW(0, installPrompt, friendlyName, MB_YESNO |
+ MB_ICONQUESTION) != IDYES)
+ return 0;
+ }
+ appLaunched = GetTextConfigValue(pairs, L"RunProgram");
+
+ #ifdef _SHELL_EXECUTE
+ executeFile = GetTextConfigValue(pairs, L"ExecuteFile");
+ executeParameters = GetTextConfigValue(pairs, L"ExecuteParameters") + switches;
+ #endif
+ }
+
+ NFile::NDirectory::CTempDirectory tempDir;
+ if (!tempDir.Create(kTempDirPrefix))
+ {
+ if (!assumeYes)
+ MyMessageBox(L"Can not create temp folder archive");
+ return 1;
+ }
+
+ COpenCallbackGUI openCallback;
+
+ UString tempDirPath = GetUnicodeString(tempDir.GetPath());
+ {
+ bool isCorrupt = false;
+ UString errorMessage;
+ HRESULT result = ExtractArchive(fullPath, tempDirPath, &openCallback, showProgress,
+ isCorrupt, errorMessage);
+
+ if (result != S_OK)
+ {
+ if (!assumeYes)
+ {
+ if (result == S_FALSE || isCorrupt)
+ {
+ errorMessage = NWindows::MyLoadStringW(IDS_EXTRACTION_ERROR_MESSAGE);
+ result = E_FAIL;
+ }
+ if (result != E_ABORT && !errorMessage.IsEmpty())
+ ::MessageBoxW(0, errorMessage, NWindows::MyLoadStringW(IDS_EXTRACTION_ERROR_TITLE), MB_ICONERROR);
+ }
+ return 1;
+ }
+ }
+
+ CCurrentDirRestorer currentDirRestorer;
+
+ if (!SetCurrentDirectory(tempDir.GetPath()))
+ return 1;
+
+ HANDLE hProcess = 0;
+#ifdef _SHELL_EXECUTE
+ if (!executeFile.IsEmpty())
+ {
+ CSysString filePath = GetSystemString(executeFile);
+ SHELLEXECUTEINFO execInfo;
+ execInfo.cbSize = sizeof(execInfo);
+ execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT;
+ execInfo.hwnd = NULL;
+ execInfo.lpVerb = NULL;
+ execInfo.lpFile = filePath;
+
+ if (!switches.IsEmpty())
+ executeParameters += switches;
+
+ CSysString parametersSys = GetSystemString(executeParameters);
+ if (parametersSys.IsEmpty())
+ execInfo.lpParameters = NULL;
+ else
+ execInfo.lpParameters = parametersSys;
+
+ execInfo.lpDirectory = NULL;
+ execInfo.nShow = SW_SHOWNORMAL;
+ execInfo.hProcess = 0;
+ /* BOOL success = */ ::ShellExecuteEx(&execInfo);
+ UINT32 result = (UINT32)(UINT_PTR)execInfo.hInstApp;
+ if(result <= 32)
+ {
+ if (!assumeYes)
+ MyMessageBox(L"Can not open file");
+ return 1;
+ }
+ hProcess = execInfo.hProcess;
+ }
+ else
+#endif
+ {
+ if (appLaunched.IsEmpty())
+ {
+ appLaunched = L"setup.exe";
+ if (!NFile::NFind::DoesFileExist(GetSystemString(appLaunched)))
+ {
+ if (!assumeYes)
+ MyMessageBox(L"Can not find setup.exe");
+ return 1;
+ }
+ }
+
+ {
+ UString s2 = tempDirPath;
+ NFile::NName::NormalizeDirPathPrefix(s2);
+ appLaunched.Replace(L"%%T\\", s2);
+ }
+
+ appLaunched.Replace(L"%%T", tempDirPath);
+
+ if (!switches.IsEmpty())
+ {
+ appLaunched += L' ';
+ appLaunched += switches;
+ }
+ STARTUPINFO startupInfo;
+ startupInfo.cb = sizeof(startupInfo);
+ startupInfo.lpReserved = 0;
+ startupInfo.lpDesktop = 0;
+ startupInfo.lpTitle = 0;
+ startupInfo.dwFlags = 0;
+ startupInfo.cbReserved2 = 0;
+ startupInfo.lpReserved2 = 0;
+
+ PROCESS_INFORMATION processInformation;
+
+ CSysString appLaunchedSys = GetSystemString(dirPrefix + appLaunched);
+
+ BOOL createResult = CreateProcess(NULL, (LPTSTR)(LPCTSTR)appLaunchedSys,
+ NULL, NULL, FALSE, 0, NULL, NULL /*tempDir.GetPath() */,
+ &startupInfo, &processInformation);
+ if (createResult == 0)
+ {
+ if (!assumeYes)
+ ShowLastErrorMessage();
+ return 1;
+ }
+ ::CloseHandle(processInformation.hThread);
+ hProcess = processInformation.hProcess;
+ }
+ if (hProcess != 0)
+ {
+ WaitForSingleObject(hProcess, INFINITE);
+ ::CloseHandle(hProcess);
+ }
+ return 0;
+}
diff --git a/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp b/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp
new file mode 100755
index 00000000..a58feab5
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp
@@ -0,0 +1,696 @@
+# Microsoft Developer Studio Project File - Name="SFXSetup" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=SFXSetup - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "SFXSetup.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "SFXSetup.mak" CFG="SFXSetup - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "SFXSetup - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "SFXSetup - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE "SFXSetup - Win32 ReleaseD" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "SFXSetup - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "_SFX" /D "_NO_CRYPTO" /Yu"StdAfx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zS.sfx" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "SFXSetup - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "_SFX" /D "_NO_CRYPTO" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\UTIL\7zSfxS.exe" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "SFXSetup - Win32 ReleaseD"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ReleaseD"
+# PROP BASE Intermediate_Dir "ReleaseD"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ReleaseD"
+# PROP Intermediate_Dir "ReleaseD"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "_SFX" /Yu"StdAfx.h" /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "_SFX" /D "_NO_CRYPTO" /Yu"StdAfx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\UTIL\7zWinSR.exe"
+# SUBTRACT BASE LINK32 /debug /nodefaultlib
+# ADD LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zSD.sfx" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "SFXSetup - Win32 Release"
+# Name "SFXSetup - Win32 Debug"
+# Name "SFXSetup - Win32 ReleaseD"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Interface"
+
+# PROP Default_Filter ""
+# End Group
+# Begin Group "7z"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zExtract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHeader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zMethodID.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zMethodID.h
+# End Source File
+# End Group
+# Begin Group "Archive Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2MT.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\FilterCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\FilterCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Group "LZMA"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMADecoder.cpp
+# End Source File
+# End Group
+# Begin Group "Branch"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86_2.cpp
+# End Source File
+# End Group
+# Begin Group "Copy"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.h
+# End Source File
+# End Group
+# 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
+# End Group
+# Begin Group "SDK"
+
+# PROP Default_Filter ""
+# 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\CommandLineParser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.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\TextConfig.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\TextConfig.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\UTFConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\UTFConvert.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Vector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Vector.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Group "Control"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\Dialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\Dialog.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Error.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Error.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\ResourceString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\ResourceString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Window.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Window.h
+# End Source File
+# End Group
+# Begin Group "7z Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# End Group
+# Begin Group "UI"
+
+# PROP Default_Filter ""
+# Begin Group "Explorer"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\Explorer\MyMessages.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Explorer\MyMessages.h
+# End Source File
+# End Group
+# Begin Group "UI Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveOpenCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiverInfo.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiverInfo.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\DefaultName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\DefaultName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ExtractMode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\OpenArchive.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\OpenArchive.h
+# End Source File
+# End Group
+# Begin Group "GUI"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\GUI\OpenCallbackGUI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\GUI\OpenCallbackGUI.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "File Manager"
+
+# PROP Default_Filter ""
+# Begin Group "Dialog"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\ProgressDialog\ProgressDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\ProgressDialog\ProgressDialog.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\FileManager\FormatUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\FormatUtils.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\ExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ExtractCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ExtractEngine.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ExtractEngine.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Main.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\setup.ico
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw b/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw
new file mode 100755
index 00000000..f563b21f
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "SFXSetup"=.\SFXSetup.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Bundles/SFXSetup/StdAfx.cpp b/CPP/7zip/Bundles/SFXSetup/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXSetup/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Bundles/SFXSetup/StdAfx.h b/CPP/7zip/Bundles/SFXSetup/StdAfx.h
new file mode 100755
index 00000000..19ece34b
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXSetup/StdAfx.h
@@ -0,0 +1,10 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+#include <commctrl.h>
+
+#endif
diff --git a/CPP/7zip/Bundles/SFXSetup/makefile b/CPP/7zip/Bundles/SFXSetup/makefile
new file mode 100755
index 00000000..1f86c42c
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXSetup/makefile
@@ -0,0 +1,156 @@
+PROG = 7zS.sfx
+LIBS = $(LIBS) user32.lib oleaut32.lib shell32.lib ole32.lib comctl32.lib
+CFLAGS = $(CFLAGS) -I ../../../ \
+ -DEXCLUDE_COM \
+ -DNO_REGISTRY \
+ -DEXTRACT_ONLY \
+ -D_SFX \
+ -DFORMAT_7Z \
+ -DCOMPRESS_BCJ_X86 \
+ -DCOMPRESS_BCJ2 \
+ -DCOMPRESS_COPY \
+ -DCOMPRESS_LZMA \
+ -D_NO_CRYPTO
+
+SFX_WIN_OBJS = \
+ $O\Main.obj \
+ $O\ExtractCallback.obj \
+ $O\ExtractEngine.obj \
+
+GUI_OBJS = \
+ $O\OpenCallbackGUI.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\CommandLineParser.obj \
+ $O\CRC.obj \
+ $O\IntToString.obj \
+ $O\NewHandler.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\TextConfig.obj \
+ $O\UTFConvert.obj \
+ $O\Vector.obj \
+ $O\Wildcard.obj \
+
+WIN_OBJS = \
+ $O\DLL.obj \
+ $O\Error.obj \
+ $O\FileDir.obj \
+ $O\FileFind.obj \
+ $O\FileIO.obj \
+ $O\FileName.obj \
+ $O\PropVariant.obj \
+ $O\ResourceString.obj \
+ $O\Synchronization.obj \
+ $O\Window.obj \
+
+WIN_CTRL_OBJS = \
+ $O\Dialog.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\FileStreams.obj \
+ $O\InBuffer.obj \
+ $O\LimitedStreams.obj \
+ $O\LockedStream.obj \
+ $O\OutBuffer.obj \
+ $O\ProgressUtils.obj \
+ $O\StreamBinder.obj \
+ $O\StreamObjects.obj \
+ $O\StreamUtils.obj \
+
+UI_COMMON_OBJS = \
+ $O\ArchiveOpenCallback.obj \
+ $O\ArchiverInfo.obj \
+ $O\DefaultName.obj \
+ $O\OpenArchive.obj \
+
+FM_OBJS = \
+ $O\FormatUtils.obj \
+
+AR_COMMON_OBJS = \
+ $O\CoderMixer2.obj \
+ $O\CoderMixer2MT.obj \
+ $O\CrossThreadProgress.obj \
+ $O\FilterCoder.obj \
+ $O\ItemNameUtils.obj \
+ $O\OutStreamWithCRC.obj \
+
+7Z_OBJS = \
+ $O\7zDecode.obj \
+ $O\7zExtract.obj \
+ $O\7zFolderOutStream.obj \
+ $O\7zHandler.obj \
+ $O\7zHeader.obj \
+ $O\7zIn.obj \
+ $O\7zMethodID.obj \
+
+BRANCH_OPT_OBJS = \
+ $O\BranchCoder.obj \
+ $O\x86.obj \
+ $O\x86_2.obj \
+
+LZ_OBJS = \
+ $O\LZOutWindow.obj \
+
+LZMA_OPT_OBJS = \
+ $O\LZMADecoder.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(SFX_WIN_OBJS) \
+ $(GUI_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(WIN_CTRL_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(UI_COMMON_OBJS) \
+ $(FM_OBJS)\
+ $(AR_COMMON_OBJS) \
+ $(7Z_OBJS) \
+ $(BRANCH_OPT_OBJS) \
+ $(LZ_OBJS) \
+ $(LZMA_OPT_OBJS) \
+ $O\CopyCoder.obj \
+ $O\MyMessages.obj \
+ $O\ProgressDialog.obj \
+ $O\resource.res
+
+
+!include "../../../Build.mak"
+
+$(SFX_WIN_OBJS): $(*B).cpp
+ $(COMPL)
+
+$(GUI_OBJS): ../../UI/GUI/$(*B).cpp
+ $(COMPL)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(WIN_CTRL_OBJS): ../../../Windows/Control/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp
+ $(COMPL)
+$(FM_OBJS): ../../FileManager/$(*B).cpp
+ $(COMPL)
+$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
+ $(COMPL)
+
+$(7Z_OBJS): ../../Archive/7z/$(*B).cpp
+ $(COMPL)
+$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp
+ $(COMPL)
+$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp
+ $(COMPL)
+$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp
+ $(COMPL)
+
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
+$O\MyMessages.obj: ../../UI/Explorer/MyMessages.cpp
+ $(COMPL)
+$O\ProgressDialog.obj: ../../FileManager/Resource/ProgressDialog/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/Bundles/SFXSetup/resource.h b/CPP/7zip/Bundles/SFXSetup/resource.h
new file mode 100755
index 00000000..2c7e5a22
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXSetup/resource.h
@@ -0,0 +1,6 @@
+#define IDI_ICON3 159
+
+#define IDS_EXTRACTION_ERROR_TITLE 7
+#define IDS_EXTRACTION_ERROR_MESSAGE 8
+#define IDS_CANNOT_CREATE_FOLDER 9
+#define IDS_PROGRESS_EXTRACTING 69
diff --git a/CPP/7zip/Bundles/SFXSetup/resource.rc b/CPP/7zip/Bundles/SFXSetup/resource.rc
new file mode 100755
index 00000000..4bf6a585
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXSetup/resource.rc
@@ -0,0 +1,16 @@
+#include "../../MyVersionInfo.rc"
+#include "resource.h"
+
+MY_VERSION_INFO_APP("7z Setup SFX", "7zS.sfx")
+
+IDI_ICON3 ICON "setup.ico"
+
+STRINGTABLE
+BEGIN
+ IDS_EXTRACTION_ERROR_TITLE "Extraction Failed"
+ IDS_EXTRACTION_ERROR_MESSAGE "File is corrupt"
+ IDS_CANNOT_CREATE_FOLDER "Cannot create folder '{0}'"
+ IDS_PROGRESS_EXTRACTING "Extracting"
+END
+
+#include "../../FileManager/Resource/ProgressDialog/resource.rc"
diff --git a/CPP/7zip/Bundles/SFXSetup/setup.ico b/CPP/7zip/Bundles/SFXSetup/setup.ico
new file mode 100755
index 00000000..bb455be1
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXSetup/setup.ico
Binary files differ
diff --git a/CPP/7zip/Bundles/SFXWin/7z.ico b/CPP/7zip/Bundles/SFXWin/7z.ico
new file mode 100755
index 00000000..47ffb781
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXWin/7z.ico
Binary files differ
diff --git a/CPP/7zip/Bundles/SFXWin/Main.cpp b/CPP/7zip/Bundles/SFXWin/Main.cpp
new file mode 100755
index 00000000..166d58cb
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXWin/Main.cpp
@@ -0,0 +1,115 @@
+// Main.cpp
+
+#include "StdAfx.h"
+
+#include <initguid.h>
+
+#include "Common/StringConvert.h"
+#include "Common/CommandLineParser.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileName.h"
+#include "Windows/DLL.h"
+
+#include "../../ICoder.h"
+#include "../../IPassword.h"
+#include "../../Archive/IArchive.h"
+#include "../../UI/Common/Extract.h"
+#include "../../UI/Explorer/MyMessages.h"
+#include "../../UI/GUI/ExtractGUI.h"
+
+HINSTANCE g_hInstance;
+#ifndef _UNICODE
+bool g_IsNT = false;
+static inline bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+#endif
+
+int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, LPSTR /* lpCmdLine */, int /* nCmdShow */)
+{
+ g_hInstance = (HINSTANCE)hInstance;
+ #ifndef _UNICODE
+ g_IsNT = IsItWindowsNT();
+ #endif
+
+ UString password;
+ bool assumeYes = false;
+ bool outputFolderDefined = false;
+ UString outputFolder;
+ UStringVector subStrings;
+ NCommandLineParser::SplitCommandLine(GetCommandLineW(), subStrings);
+ for (int i = 1; i < subStrings.Size(); i++)
+ {
+ const UString &s = subStrings[i];
+ if (s.CompareNoCase(L"-y") == 0)
+ assumeYes = true;
+ else if (s.Left(2).CompareNoCase(L"-o") == 0)
+ {
+ outputFolder = s.Mid(2);
+ NWindows::NFile::NName::NormalizeDirPathPrefix(outputFolder);
+ outputFolderDefined = !outputFolder.IsEmpty();
+ }
+ else if (s.Left(2).CompareNoCase(L"-p") == 0)
+ {
+ password = s.Mid(2);
+ }
+ }
+
+ UString path;
+ NWindows::NDLL::MyGetModuleFileName(g_hInstance, path);
+
+ UString fullPath;
+ int fileNamePartStartIndex;
+ if (!NWindows::NFile::NDirectory::MyGetFullPathName(path, fullPath, fileNamePartStartIndex))
+ {
+ MyMessageBox(L"Error 1329484");
+ return 1;
+ }
+
+ COpenCallbackGUI openCallback;
+
+ openCallback.PasswordIsDefined = !password.IsEmpty();
+ openCallback.Password = password;
+
+ CExtractCallbackImp *ecs = new CExtractCallbackImp;
+ CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
+ ecs->Init();
+ ecs->PasswordIsDefined = !password.IsEmpty();
+ ecs->Password = password;
+
+ CExtractOptions eo;
+ eo.OutputDir = outputFolderDefined ? outputFolder :
+ fullPath.Left(fileNamePartStartIndex);
+ eo.YesToAll = assumeYes;
+ eo.OverwriteMode = assumeYes ?
+ NExtract::NOverwriteMode::kWithoutPrompt :
+ NExtract::NOverwriteMode::kAskBefore;
+ eo.PathMode = NExtract::NPathMode::kFullPathnames;
+ eo.TestMode = false;
+
+ UStringVector v1, v2;
+ v1.Add(fullPath);
+ v2.Add(fullPath);
+ NWildcard::CCensorNode wildcardCensor;
+ wildcardCensor.AddItem(true, L"*", true, true, true);
+
+ HRESULT result = ExtractGUI(v1, v2,
+ wildcardCensor, eo, (assumeYes ? false: true), &openCallback, ecs);
+
+ /*
+ HRESULT result = ExtractArchive(NULL, path, assumeYes, !assumeYes,
+ outputFolderDefined ? outputFolder :
+ fullPath.Left(fileNamePartStartIndex));
+ */
+ if (result == S_FALSE)
+ MyMessageBox(L"Archive is not supported");
+ else if (result != S_OK && result != E_ABORT)
+ ShowErrorMessage(0, result);
+ return 0;
+}
diff --git a/CPP/7zip/Bundles/SFXWin/SFXWin.dsp b/CPP/7zip/Bundles/SFXWin/SFXWin.dsp
new file mode 100755
index 00000000..ead66bc6
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXWin/SFXWin.dsp
@@ -0,0 +1,847 @@
+# Microsoft Developer Studio Project File - Name="SFXWin" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=SFXWin - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "SFXWin.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "SFXWin.mak" CFG="SFXWin - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "SFXWin - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "SFXWin - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE "SFXWin - Win32 ReleaseD" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "SFXWin - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_PPMD" /D "_SFX" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7z.sfx" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "SFXWin - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_PPMD" /D "_SFX" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Util\7z.sfx" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "SFXWin - Win32 ReleaseD"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "SFXWin___Win32_ReleaseD"
+# PROP BASE Intermediate_Dir "SFXWin___Win32_ReleaseD"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "SFXWin___Win32_ReleaseD"
+# PROP Intermediate_Dir "SFXWin___Win32_ReleaseD"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_PPMD" /D "_SFX" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_PPMD" /D "_SFX" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7z.sfx" /opt:NOWIN98
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zD.sfx" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "SFXWin - Win32 Release"
+# Name "SFXWin - Win32 Debug"
+# Name "SFXWin - Win32 ReleaseD"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "7z"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zExtract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHeader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zMethodID.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zMethodID.h
+# End Source File
+# End Group
+# Begin Group "Archive Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2MT.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\FilterCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\FilterCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Group "LZMA"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMADecoder.cpp
+# End Source File
+# End Group
+# Begin Group "Branch"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86_2.cpp
+# End Source File
+# End Group
+# Begin Group "PPMD"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDContext.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDSubAlloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\PPMD\PPMDType.h
+# End Source File
+# End Group
+# 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 "Copy"
+
+# PROP Default_Filter ""
+# 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 Group
+# Begin Group "Crypto"
+
+# PROP Default_Filter ""
+# Begin Group "AES"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aes.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\AES_CBC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aescpp.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aescrypt.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aeskey.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aesopt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aestab.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\MyAES.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\MyAES.h
+# End Source File
+# End Group
+# Begin Group "7zAES"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAES\7zAES.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAES\7zAES.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAES\MySHA256.h
+# End Source File
+# End Group
+# Begin Group "Hash"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\RotateDefs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\Sha256.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\Hash\Sha256.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "Dialogs"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\MessagesDialog\MessagesDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\MessagesDialog\MessagesDialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\OverwriteDialog\OverwriteDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\OverwriteDialog\OverwriteDialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\PasswordDialog\PasswordDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\PasswordDialog\PasswordDialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\ProgressDialog\ProgressDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\ProgressDialog\ProgressDialog.h
+# End Source File
+# End Group
+# Begin Group "7zip Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\FilePathAutoRename.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilePathAutoRename.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# End Group
+# Begin Group "File Manager"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\FileManager\ExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\ExtractCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\FormatUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\FormatUtils.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Group "Control"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\Dialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\Dialog.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Error.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Error.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\ResourceString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\ResourceString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Shell.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Shell.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Window.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Window.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\Alloc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Alloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\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\Vector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Vector.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.h
+# End Source File
+# End Group
+# Begin Group "UI"
+
+# PROP Default_Filter ""
+# Begin Group "UI Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveExtractCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveOpenCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiverInfo.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiverInfo.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\DefaultName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\DefaultName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Extract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Extract.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ExtractingFilePath.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ExtractingFilePath.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\OpenArchive.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\OpenArchive.h
+# End Source File
+# End Group
+# Begin Group "GUI"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\GUI\ExtractDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\GUI\ExtractDialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\GUI\ExtractGUI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\GUI\ExtractGUI.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\GUI\OpenCallbackGUI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\GUI\OpenCallbackGUI.h
+# End Source File
+# End Group
+# Begin Group "Explorer"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\Explorer\MyMessages.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Explorer\MyMessages.h
+# End Source File
+# End Group
+# End Group
+# Begin Source File
+
+SOURCE=.\7z.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\7z1.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\Main.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/Bundles/SFXWin/SFXWin.dsw b/CPP/7zip/Bundles/SFXWin/SFXWin.dsw
new file mode 100755
index 00000000..a9926c71
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXWin/SFXWin.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "SFXWin"=.\SFXWin.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Bundles/SFXWin/StdAfx.cpp b/CPP/7zip/Bundles/SFXWin/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXWin/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Bundles/SFXWin/StdAfx.h b/CPP/7zip/Bundles/SFXWin/StdAfx.h
new file mode 100755
index 00000000..c5f7231f
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXWin/StdAfx.h
@@ -0,0 +1,12 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#include <commctrl.h>
+#include <ShlObj.h>
+
+#endif
diff --git a/CPP/7zip/Bundles/SFXWin/makefile b/CPP/7zip/Bundles/SFXWin/makefile
new file mode 100755
index 00000000..00d3ecc6
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXWin/makefile
@@ -0,0 +1,207 @@
+PROG = 7z.sfx
+LIBS = $(LIBS) user32.lib oleaut32.lib shell32.lib ole32.lib
+CFLAGS = $(CFLAGS) -I ../../../ \
+ -DEXCLUDE_COM \
+ -DNO_REGISTRY \
+ -DEXTRACT_ONLY \
+ -D_SFX \
+ -DFORMAT_7Z \
+ -DCOMPRESS_BCJ_X86 \
+ -DCOMPRESS_BCJ2 \
+ -DCOMPRESS_COPY \
+ -DCOMPRESS_LZMA \
+ -DCOMPRESS_PPMD \
+ -DCRYPTO_AES \
+ -DCRYPTO_7ZAES \
+
+
+SFX_WIN_OBJS = \
+ $O\Main.obj \
+
+GUI_OBJS = \
+ $O\ExtractDialog.obj \
+ $O\ExtractGUI.obj \
+ $O\OpenCallbackGUI.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\CommandLineParser.obj \
+ $O\CRC.obj \
+ $O\IntToString.obj \
+ $O\NewHandler.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\Vector.obj \
+ $O\Wildcard.obj \
+
+WIN_OBJS = \
+ $O\DLL.obj \
+ $O\Error.obj \
+ $O\FileDir.obj \
+ $O\FileFind.obj \
+ $O\FileIO.obj \
+ $O\FileName.obj \
+ $O\PropVariant.obj \
+ $O\PropVariantConversions.obj \
+ $O\ResourceString.obj \
+ $O\Shell.obj \
+ $O\Synchronization.obj \
+ $O\Window.obj \
+
+WIN_CTRL_OBJS = \
+ $O\Dialog.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\FilePathAutoRename.obj \
+ $O\FileStreams.obj \
+ $O\InBuffer.obj \
+ $O\LimitedStreams.obj \
+ $O\LockedStream.obj \
+ $O\OutBuffer.obj \
+ $O\ProgressUtils.obj \
+ $O\StreamBinder.obj \
+ $O\StreamObjects.obj \
+ $O\StreamUtils.obj \
+
+UI_COMMON_OBJS = \
+ $O\ArchiveExtractCallback.obj \
+ $O\ArchiveOpenCallback.obj \
+ $O\ArchiverInfo.obj \
+ $O\DefaultName.obj \
+ $O\Extract.obj \
+ $O\ExtractingFilePath.obj \
+ $O\OpenArchive.obj \
+
+FM_OBJS = \
+ $O\ExtractCallback.obj \
+ $O\FormatUtils.obj \
+
+AR_COMMON_OBJS = \
+ $O\CoderMixer2.obj \
+ $O\CoderMixer2MT.obj \
+ $O\CrossThreadProgress.obj \
+ $O\FilterCoder.obj \
+ $O\ItemNameUtils.obj \
+ $O\OutStreamWithCRC.obj \
+
+7Z_OBJS = \
+ $O\7zDecode.obj \
+ $O\7zExtract.obj \
+ $O\7zFolderOutStream.obj \
+ $O\7zHandler.obj \
+ $O\7zHeader.obj \
+ $O\7zIn.obj \
+ $O\7zMethodID.obj \
+
+BRANCH_OPT_OBJS = \
+ $O\BranchCoder.obj \
+ $O\x86.obj \
+ $O\x86_2.obj \
+
+LZ_OBJS = \
+ $O\LZOutWindow.obj \
+
+LZMA_OPT_OBJS = \
+ $O\LZMADecoder.obj \
+
+PPMD_OPT_OBJS = \
+ $O\PPMDDecoder.obj \
+
+7ZAES_OPT_OBJS = \
+ $O\7zAES.obj \
+
+AES_OPT_OBJS = \
+ $O\MyAES.obj \
+
+AES_ORIG_OBJS = \
+ $O\aescrypt.obj \
+ $O\aeskey.obj \
+ $O\aestab.obj \
+
+CRYPTO_HASH_OBJS = \
+ $O\Sha256.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(SFX_WIN_OBJS) \
+ $(GUI_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(WIN_CTRL_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(UI_COMMON_OBJS) \
+ $(FM_OBJS)\
+ $(AR_COMMON_OBJS) \
+ $(7Z_OBJS) \
+ $(BRANCH_OPT_OBJS) \
+ $(LZ_OBJS) \
+ $(LZMA_OPT_OBJS) \
+ $(PPMD_OPT_OBJS) \
+ $O\CopyCoder.obj \
+ $(CRYPTO_HASH_OBJS) \
+ $(7ZAES_OPT_OBJS) \
+ $(AES_OPT_OBJS) \
+ $(AES_ORIG_OBJS) \
+ $O\MyMessages.obj \
+ $O\MessagesDialog.obj \
+ $O\OverwriteDialog.obj \
+ $O\PasswordDialog.obj \
+ $O\ProgressDialog.obj \
+ $O\resource.res
+
+
+!include "../../../Build.mak"
+
+$(SFX_WIN_OBJS): $(*B).cpp
+ $(COMPL)
+
+$(GUI_OBJS): ../../UI/GUI/$(*B).cpp
+ $(COMPL)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(WIN_CTRL_OBJS): ../../../Windows/Control/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp
+ $(COMPL)
+$(FM_OBJS): ../../FileManager/$(*B).cpp
+ $(COMPL)
+$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
+ $(COMPL)
+
+$(7Z_OBJS): ../../Archive/7z/$(*B).cpp
+ $(COMPL)
+$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp
+ $(COMPL)
+$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp
+ $(COMPL)
+$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp
+ $(COMPL)
+$(PPMD_OPT_OBJS): ../../Compress/PPMD/$(*B).cpp
+ $(COMPL)
+
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
+
+$(CRYPTO_HASH_OBJS): ../../Crypto/Hash/$(*B).cpp
+ $(COMPL)
+$(7ZAES_OPT_OBJS): ../../Crypto/7zAES/$(*B).cpp
+ $(COMPL)
+$(AES_OPT_OBJS): ../../Crypto/AES/$(*B).cpp
+ $(COMPL)
+$(AES_ORIG_OBJS): ../../Crypto/AES/$(*B).c
+ $(COMPL_O1_W3)
+
+$O\MyMessages.obj: ../../UI/Explorer/MyMessages.cpp
+ $(COMPL)
+$O\MessagesDialog.obj: ../../FileManager/Resource/MessagesDialog/$(*B).cpp
+ $(COMPL)
+$O\OverwriteDialog.obj: ../../FileManager/Resource/OverwriteDialog./$(*B).cpp
+ $(COMPL)
+$O\PasswordDialog.obj: ../../FileManager/Resource/PasswordDialog/$(*B).cpp
+ $(COMPL)
+$O\ProgressDialog.obj: ../../FileManager/Resource/ProgressDialog/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/Bundles/SFXWin/resource.h b/CPP/7zip/Bundles/SFXWin/resource.h
new file mode 100755
index 00000000..0a460213
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXWin/resource.h
@@ -0,0 +1,7 @@
+#define IDD_DIALOG_EXTRACT 137
+
+#define IDI_ICON3 159
+
+#define IDC_STATIC_EXTRACT_EXTRACT_TO 1020
+#define IDC_EXTRACT_COMBO_PATH 1021
+#define IDC_EXTRACT_BUTTON_SET_PATH 1022
diff --git a/CPP/7zip/Bundles/SFXWin/resource.rc b/CPP/7zip/Bundles/SFXWin/resource.rc
new file mode 100755
index 00000000..60304803
--- /dev/null
+++ b/CPP/7zip/Bundles/SFXWin/resource.rc
@@ -0,0 +1,34 @@
+#include "../../MyVersionInfo.rc"
+#include "../../GuiCommon.rc"
+#include "resource.h"
+
+MY_VERSION_INFO_APP("7z SFX", "7z.sfx")
+
+#define xSize2 214
+#define ySize2 64
+
+#define xSize (xSize2 + marg + marg)
+#define ySize (ySize2 + marg + marg)
+
+#define bYPos (ySize - marg - bYSize)
+#define bXPos1 (xSize - marg - bXSize)
+#define bXPos2 (bXPos1 - 10 - bXSize)
+
+IDI_ICON3 ICON "7z.ico"
+
+IDD_DIALOG_EXTRACT DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE
+CAPTION "7-Zip self-extracting archive"
+MY_FONT
+BEGIN
+ LTEXT "E&xtract to:", IDC_STATIC_EXTRACT_EXTRACT_TO, marg, marg, xSize2, 8
+ EDITTEXT IDC_EXTRACT_COMBO_PATH, marg, 21, xSize2 - bDotsSize - 13, 14, ES_AUTOHSCROLL
+ PUSHBUTTON "...", IDC_EXTRACT_BUTTON_SET_PATH, xSize - marg - bDotsSize, 20, bDotsSize, bYSize, WS_GROUP
+ DEFPUSHBUTTON "Extract", IDOK, , bXPos2, bYPos, bXSize, bYSize, WS_GROUP
+ PUSHBUTTON "Cancel", IDCANCEL, bXPos1, bYPos, bXSize, bYSize
+END
+
+#include "../../FileManager/Resource/MessagesDialog/resource.rc"
+#include "../../FileManager/Resource/OverwriteDialog/resource.rc"
+#include "../../FileManager/Resource/PasswordDialog/resource.rc"
+#include "../../FileManager/Resource/ProgressDialog/resource.rc"
+#include "../../UI/Resource/Extract/resource.rc"
diff --git a/CPP/7zip/Bundles/makefile b/CPP/7zip/Bundles/makefile
new file mode 100755
index 00000000..7e7d7cdc
--- /dev/null
+++ b/CPP/7zip/Bundles/makefile
@@ -0,0 +1,15 @@
+DIRS = \
+ Alone\~ \
+ Alone7z\~ \
+ Format7z\~ \
+ Format7zR\~ \
+ Format7zExtract\~ \
+ Format7zExtractR\~ \
+ SFXCon\~ \
+ SFXSetup\~ \
+ SFXWin\~ \
+
+all: $(DIRS)
+
+$(DIRS):
+!include "../SubBuild.mak"
diff --git a/CPP/7zip/Common/FilePathAutoRename.cpp b/CPP/7zip/Common/FilePathAutoRename.cpp
new file mode 100755
index 00000000..3c5b910f
--- /dev/null
+++ b/CPP/7zip/Common/FilePathAutoRename.cpp
@@ -0,0 +1,57 @@
+// FilePathAutoRename.cpp
+
+#include "StdAfx.h"
+#include "FilePathAutoRename.h"
+
+#include "Common/Defs.h"
+#include "Common/IntToString.h"
+
+#include "Windows/FileName.h"
+#include "Windows/FileFind.h"
+
+using namespace NWindows;
+
+static bool MakeAutoName(const UString &name,
+ const UString &extension, int value, UString &path)
+{
+ wchar_t number[32];
+ ConvertUInt64ToString(value, number);
+ path = name;
+ path += number;
+ path += extension;
+ return NFile::NFind::DoesFileExist(path);
+}
+
+bool AutoRenamePath(UString &fullProcessedPath)
+{
+ UString path;
+ int dotPos = fullProcessedPath.ReverseFind(L'.');
+
+ int slashPos = fullProcessedPath.ReverseFind(L'/');
+ #ifdef _WIN32
+ int slash1Pos = fullProcessedPath.ReverseFind(L'\\');
+ slashPos = MyMax(slashPos, slash1Pos);
+ #endif
+
+ UString name, extension;
+ if (dotPos > slashPos && dotPos > 0)
+ {
+ name = fullProcessedPath.Left(dotPos);
+ extension = fullProcessedPath.Mid(dotPos);
+ }
+ else
+ name = fullProcessedPath;
+ name += L'_';
+ int indexLeft = 1, indexRight = (1 << 30);
+ while (indexLeft != indexRight)
+ {
+ int indexMid = (indexLeft + indexRight) / 2;
+ if (MakeAutoName(name, extension, indexMid, path))
+ indexLeft = indexMid + 1;
+ else
+ indexRight = indexMid;
+ }
+ if (MakeAutoName(name, extension, indexRight, fullProcessedPath))
+ return false;
+ return true;
+}
diff --git a/CPP/7zip/Common/FilePathAutoRename.h b/CPP/7zip/Common/FilePathAutoRename.h
new file mode 100755
index 00000000..99323094
--- /dev/null
+++ b/CPP/7zip/Common/FilePathAutoRename.h
@@ -0,0 +1,10 @@
+// Util/FilePathAutoRename.h
+
+#ifndef __FILEPATHAUTORENAME_H
+#define __FILEPATHAUTORENAME_H
+
+#include "Common/String.h"
+
+bool AutoRenamePath(UString &fullProcessedPath);
+
+#endif
diff --git a/CPP/7zip/Common/FileStreams.cpp b/CPP/7zip/Common/FileStreams.cpp
new file mode 100755
index 00000000..8a000e4e
--- /dev/null
+++ b/CPP/7zip/Common/FileStreams.cpp
@@ -0,0 +1,251 @@
+// FileStreams.cpp
+
+#include "StdAfx.h"
+
+#ifndef _WIN32
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#endif
+
+#include "FileStreams.h"
+
+static inline HRESULT ConvertBoolToHRESULT(bool result)
+{
+ // return result ? S_OK: E_FAIL;
+ #ifdef _WIN32
+ return result ? S_OK: (::GetLastError());
+ #else
+ return result ? S_OK: E_FAIL;
+ #endif
+}
+
+bool CInFileStream::Open(LPCTSTR fileName)
+{
+ return File.Open(fileName);
+}
+
+#ifdef _WIN32
+#ifndef _UNICODE
+bool CInFileStream::Open(LPCWSTR fileName)
+{
+ return File.Open(fileName);
+}
+#endif
+#endif
+
+STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ #ifdef _WIN32
+
+ UInt32 realProcessedSize;
+ bool result = File.ReadPart(data, size, realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return ConvertBoolToHRESULT(result);
+
+ #else
+
+ if(processedSize != NULL)
+ *processedSize = 0;
+ ssize_t res = File.Read(data, (size_t)size);
+ if (res == -1)
+ return E_FAIL;
+ if(processedSize != NULL)
+ *processedSize = (UInt32)res;
+ return S_OK;
+
+ #endif
+}
+
+#ifndef _WIN32_WCE
+STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ #ifdef _WIN32
+ UInt32 realProcessedSize;
+ BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE),
+ data, size, (DWORD *)&realProcessedSize, NULL);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE)
+ return S_OK;
+ return ConvertBoolToHRESULT(res != FALSE);
+
+ #else
+
+ if(processedSize != NULL)
+ *processedSize = 0;
+ ssize_t res;
+ do
+ {
+ res = read(0, data, (size_t)size);
+ }
+ while (res < 0 && (errno == EINTR));
+ if (res == -1)
+ return E_FAIL;
+ if(processedSize != NULL)
+ *processedSize = (UInt32)res;
+ return S_OK;
+
+ #endif
+}
+
+#endif
+
+STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin,
+ UInt64 *newPosition)
+{
+ if(seekOrigin >= 3)
+ return STG_E_INVALIDFUNCTION;
+
+ #ifdef _WIN32
+
+ UInt64 realNewPosition;
+ bool result = File.Seek(offset, seekOrigin, realNewPosition);
+ if(newPosition != NULL)
+ *newPosition = realNewPosition;
+ return ConvertBoolToHRESULT(result);
+
+ #else
+
+ off_t res = File.Seek(offset, seekOrigin);
+ if (res == -1)
+ return E_FAIL;
+ if(newPosition != NULL)
+ *newPosition = (UInt64)res;
+ return S_OK;
+
+ #endif
+}
+
+STDMETHODIMP CInFileStream::GetSize(UInt64 *size)
+{
+ return ConvertBoolToHRESULT(File.GetLength(*size));
+}
+
+
+//////////////////////////
+// COutFileStream
+
+bool COutFileStream::Create(LPCTSTR fileName, bool createAlways)
+{
+ return File.Create(fileName, createAlways);
+}
+
+#ifdef _WIN32
+#ifndef _UNICODE
+bool COutFileStream::Create(LPCWSTR fileName, bool createAlways)
+{
+ return File.Create(fileName, createAlways);
+}
+#endif
+#endif
+
+STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ #ifdef _WIN32
+
+ UInt32 realProcessedSize;
+ bool result = File.WritePart(data, size, realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return ConvertBoolToHRESULT(result);
+
+ #else
+
+ if(processedSize != NULL)
+ *processedSize = 0;
+ ssize_t res = File.Write(data, (size_t)size);
+ if (res == -1)
+ return E_FAIL;
+ if(processedSize != NULL)
+ *processedSize = (UInt32)res;
+ return S_OK;
+
+ #endif
+}
+
+STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin,
+ UInt64 *newPosition)
+{
+ if(seekOrigin >= 3)
+ return STG_E_INVALIDFUNCTION;
+ #ifdef _WIN32
+
+ UInt64 realNewPosition;
+ bool result = File.Seek(offset, seekOrigin, realNewPosition);
+ if(newPosition != NULL)
+ *newPosition = realNewPosition;
+ return ConvertBoolToHRESULT(result);
+
+ #else
+
+ off_t res = File.Seek(offset, seekOrigin);
+ if (res == -1)
+ return E_FAIL;
+ if(newPosition != NULL)
+ *newPosition = (UInt64)res;
+ return S_OK;
+
+ #endif
+}
+
+STDMETHODIMP COutFileStream::SetSize(Int64 newSize)
+{
+ #ifdef _WIN32
+ UInt64 currentPos;
+ if(!File.Seek(0, FILE_CURRENT, currentPos))
+ return E_FAIL;
+ bool result = File.SetLength(newSize);
+ UInt64 currentPos2;
+ result = result && File.Seek(currentPos, currentPos2);
+ return result ? S_OK : E_FAIL;
+ #else
+ return E_FAIL;
+ #endif
+}
+
+#ifndef _WIN32_WCE
+STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if(processedSize != NULL)
+ *processedSize = 0;
+
+ #ifdef _WIN32
+ UInt32 realProcessedSize;
+ BOOL res = TRUE;
+ if (size > 0)
+ {
+ // Seems that Windows doesn't like big amounts writing to stdout.
+ // So we limit portions by 32KB.
+ UInt32 sizeTemp = (1 << 15);
+ if (sizeTemp > size)
+ sizeTemp = size;
+ res = ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),
+ data, sizeTemp, (DWORD *)&realProcessedSize, NULL);
+ size -= realProcessedSize;
+ data = (const void *)((const Byte *)data + realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize += realProcessedSize;
+ }
+ return ConvertBoolToHRESULT(res != FALSE);
+
+ #else
+
+ ssize_t res;
+ do
+ {
+ res = write(1, data, (size_t)size);
+ }
+ while (res < 0 && (errno == EINTR));
+ if (res == -1)
+ return E_FAIL;
+ if(processedSize != NULL)
+ *processedSize = (UInt32)res;
+ return S_OK;
+
+ return S_OK;
+ #endif
+}
+
+#endif
diff --git a/CPP/7zip/Common/FileStreams.h b/CPP/7zip/Common/FileStreams.h
new file mode 100755
index 00000000..9326372a
--- /dev/null
+++ b/CPP/7zip/Common/FileStreams.h
@@ -0,0 +1,98 @@
+// FileStreams.h
+
+#ifndef __FILESTREAMS_H
+#define __FILESTREAMS_H
+
+#ifdef _WIN32
+#include "../../Windows/FileIO.h"
+#else
+#include "../../Common/C_FileIO.h"
+#endif
+
+#include "../IStream.h"
+#include "../../Common/MyCom.h"
+
+class CInFileStream:
+ public IInStream,
+ public IStreamGetSize,
+ public CMyUnknownImp
+{
+public:
+ #ifdef _WIN32
+ NWindows::NFile::NIO::CInFile File;
+ #else
+ NC::NFile::NIO::CInFile File;
+ #endif
+ CInFileStream() {}
+ virtual ~CInFileStream() {}
+
+ bool Open(LPCTSTR fileName);
+ #ifdef _WIN32
+ #ifndef _UNICODE
+ bool Open(LPCWSTR fileName);
+ #endif
+ #endif
+
+ MY_UNKNOWN_IMP2(IInStream, IStreamGetSize)
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+
+ STDMETHOD(GetSize)(UInt64 *size);
+};
+
+#ifndef _WIN32_WCE
+class CStdInFileStream:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+public:
+ // HANDLE File;
+ // CStdInFileStream() File(INVALID_HANDLE_VALUE): {}
+ // void Open() { File = GetStdHandle(STD_INPUT_HANDLE); };
+ MY_UNKNOWN_IMP
+
+ virtual ~CStdInFileStream() {}
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+#endif
+
+class COutFileStream:
+ public IOutStream,
+ public CMyUnknownImp
+{
+public:
+ #ifdef _WIN32
+ NWindows::NFile::NIO::COutFile File;
+ #else
+ NC::NFile::NIO::COutFile File;
+ #endif
+ virtual ~COutFileStream() {}
+ bool Create(LPCTSTR fileName, bool createAlways);
+ #ifdef _WIN32
+ #ifndef _UNICODE
+ bool Create(LPCWSTR fileName, bool createAlways);
+ #endif
+ #endif
+
+ MY_UNKNOWN_IMP1(IOutStream)
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+ STDMETHOD(SetSize)(Int64 newSize);
+};
+
+#ifndef _WIN32_WCE
+class CStdOutFileStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ virtual ~CStdOutFileStream() {}
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+#endif
+
+#endif
diff --git a/CPP/7zip/Common/InBuffer.cpp b/CPP/7zip/Common/InBuffer.cpp
new file mode 100755
index 00000000..02f2adfa
--- /dev/null
+++ b/CPP/7zip/Common/InBuffer.cpp
@@ -0,0 +1,80 @@
+// InBuffer.cpp
+
+#include "StdAfx.h"
+
+#include "InBuffer.h"
+
+#include "../../Common/Alloc.h"
+
+CInBuffer::CInBuffer():
+ _buffer(0),
+ _bufferLimit(0),
+ _bufferBase(0),
+ _stream(0),
+ _bufferSize(0)
+{}
+
+bool CInBuffer::Create(UInt32 bufferSize)
+{
+ const UInt32 kMinBlockSize = 1;
+ if (bufferSize < kMinBlockSize)
+ bufferSize = kMinBlockSize;
+ if (_bufferBase != 0 && _bufferSize == bufferSize)
+ return true;
+ Free();
+ _bufferSize = bufferSize;
+ _bufferBase = (Byte *)::MidAlloc(bufferSize);
+ return (_bufferBase != 0);
+}
+
+void CInBuffer::Free()
+{
+ ::MidFree(_bufferBase);
+ _bufferBase = 0;
+}
+
+void CInBuffer::SetStream(ISequentialInStream *stream)
+{
+ _stream = stream;
+}
+
+void CInBuffer::Init()
+{
+ _processedSize = 0;
+ _buffer = _bufferBase;
+ _bufferLimit = _buffer;
+ _wasFinished = false;
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = S_OK;
+ #endif
+}
+
+bool CInBuffer::ReadBlock()
+{
+ #ifdef _NO_EXCEPTIONS
+ if (ErrorCode != S_OK)
+ return false;
+ #endif
+ if (_wasFinished)
+ return false;
+ _processedSize += (_buffer - _bufferBase);
+ UInt32 numProcessedBytes;
+ HRESULT result = _stream->Read(_bufferBase, _bufferSize, &numProcessedBytes);
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = result;
+ #else
+ if (result != S_OK)
+ throw CInBufferException(result);
+ #endif
+ _buffer = _bufferBase;
+ _bufferLimit = _buffer + numProcessedBytes;
+ _wasFinished = (numProcessedBytes == 0);
+ return (!_wasFinished);
+}
+
+Byte CInBuffer::ReadBlock2()
+{
+ if(!ReadBlock())
+ return 0xFF;
+ return *_buffer++;
+}
diff --git a/CPP/7zip/Common/InBuffer.h b/CPP/7zip/Common/InBuffer.h
new file mode 100755
index 00000000..057caa16
--- /dev/null
+++ b/CPP/7zip/Common/InBuffer.h
@@ -0,0 +1,76 @@
+// InBuffer.h
+
+#ifndef __INBUFFER_H
+#define __INBUFFER_H
+
+#include "../IStream.h"
+#include "../../Common/MyCom.h"
+
+#ifndef _NO_EXCEPTIONS
+class CInBufferException
+{
+public:
+ HRESULT ErrorCode;
+ CInBufferException(HRESULT errorCode): ErrorCode(errorCode) {}
+};
+#endif
+
+class CInBuffer
+{
+ Byte *_buffer;
+ Byte *_bufferLimit;
+ Byte *_bufferBase;
+ CMyComPtr<ISequentialInStream> _stream;
+ UInt64 _processedSize;
+ UInt32 _bufferSize;
+ bool _wasFinished;
+
+ bool ReadBlock();
+ Byte ReadBlock2();
+
+public:
+ #ifdef _NO_EXCEPTIONS
+ HRESULT ErrorCode;
+ #endif
+
+ CInBuffer();
+ ~CInBuffer() { Free(); }
+
+ bool Create(UInt32 bufferSize);
+ void Free();
+
+ void SetStream(ISequentialInStream *stream);
+ void Init();
+ void ReleaseStream() { _stream.Release(); }
+
+ bool ReadByte(Byte &b)
+ {
+ if(_buffer >= _bufferLimit)
+ if(!ReadBlock())
+ return false;
+ b = *_buffer++;
+ return true;
+ }
+ Byte ReadByte()
+ {
+ if(_buffer >= _bufferLimit)
+ return ReadBlock2();
+ return *_buffer++;
+ }
+ void ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
+ {
+ for(processedSize = 0; processedSize < size; processedSize++)
+ if (!ReadByte(((Byte *)data)[processedSize]))
+ return;
+ }
+ bool ReadBytes(void *data, UInt32 size)
+ {
+ UInt32 processedSize;
+ ReadBytes(data, size, processedSize);
+ return (processedSize == size);
+ }
+ UInt64 GetProcessedSize() const { return _processedSize + (_buffer - _bufferBase); }
+ bool WasFinished() const { return _wasFinished; }
+};
+
+#endif
diff --git a/CPP/7zip/Common/InMemStream.cpp b/CPP/7zip/Common/InMemStream.cpp
new file mode 100755
index 00000000..036ef3bd
--- /dev/null
+++ b/CPP/7zip/Common/InMemStream.cpp
@@ -0,0 +1,222 @@
+// InMemStream.cpp
+
+#include "StdAfx.h"
+
+#include <stdio.h>
+
+#include "Windows/Thread.h"
+
+#include "InMemStream.h"
+#include "../../Common/Defs.h"
+
+void CStreamInfo::Free(IInMemStreamMtCallback *callback)
+{
+ for (int i = 0; i < Blocks.Size(); i++)
+ {
+ callback->FreeBlock(Blocks[i]);
+ Blocks[i] = 0;
+ }
+}
+
+bool CInMemStreamMt::Create(int numSubStreams, UInt64 subStreamSize)
+{
+ Free();
+ _subStreamSize = subStreamSize;
+ size_t blockSize = Callback->GetBlockSize();
+ for (int i = 0; i < numSubStreams; i++)
+ {
+ _streams.Add(CStreamInfo());
+ CStreamInfo &blocks = _streams.Back();
+ blocks.Create();
+ for (UInt64 j = 0; (UInt64)j * blockSize < _subStreamSize; j++)
+ blocks.Blocks.Add(0);
+ }
+ if (!_streamIndexAllocator.AllocateList(numSubStreams))
+ return false;
+ return true;
+}
+
+void CInMemStreamMt::Free()
+{
+ while(_streams.Size() > 0)
+ {
+ _streams.Back().Free(Callback);
+ _streams.DeleteBack();
+ }
+}
+
+HRESULT CInMemStreamMt::Read()
+{
+ for (;;)
+ {
+ // printf("\n_streamIndexAllocator.AllocateItem\n");
+ int index = _streamIndexAllocator.AllocateItem();
+ /*
+ if (_stopReading)
+ return E_ABORT;
+ */
+ // printf("\nread Index = %d\n", index);
+ CStreamInfo &blocks = _streams[index];
+ blocks.Init();
+ Callback->AddStreamIndexToQueue(index);
+
+ for (;;)
+ {
+ const Byte *p = (const Byte *)blocks.Blocks[blocks.LastBlockIndex];
+ if (p == 0)
+ {
+ void **pp = &blocks.Blocks[blocks.LastBlockIndex];
+ HRESULT res = Callback->AllocateBlock(pp);
+ p = (const Byte *)*pp;
+ RINOK(res);
+ if (p == 0)
+ return E_FAIL;
+ }
+ size_t blockSize = Callback->GetBlockSize();
+ UInt32 curSize = (UInt32)(blockSize - blocks.LastBlockPos);
+ UInt32 realProcessedSize;
+ UInt64 pos64 = (UInt64)blocks.LastBlockIndex * blockSize + blocks.LastBlockPos;
+ if (curSize > _subStreamSize - pos64)
+ curSize = (UInt32)(_subStreamSize - pos64);
+ RINOK(_stream->Read((void *)(p + blocks.LastBlockPos), curSize, &realProcessedSize));
+
+ blocks.Cs->Enter();
+ if (realProcessedSize == 0)
+ {
+ blocks.StreamWasFinished = true;
+ blocks.CanReadEvent->Set();
+ blocks.Cs->Leave();
+
+ Callback->AddStreamIndexToQueue(-1);
+ return S_OK;
+ }
+
+ blocks.LastBlockPos += realProcessedSize;
+ if (blocks.LastBlockPos == blockSize)
+ {
+ blocks.LastBlockPos = 0;
+ blocks.LastBlockIndex++;
+ }
+ pos64 += realProcessedSize;
+ if (pos64 >= _subStreamSize)
+ blocks.StreamWasFinished = true;
+ blocks.CanReadEvent->Set();
+ blocks.Cs->Leave();
+ if (pos64 >= _subStreamSize)
+ break;
+ }
+ }
+}
+
+static DWORD WINAPI CoderThread(void *threadCoderInfo)
+{
+ ((CInMemStreamMt *)threadCoderInfo)->ReadResult = ((CInMemStreamMt *)threadCoderInfo)->Read();
+ return 0;
+}
+
+bool CInMemStreamMt::StartReadThread()
+{
+ // _stopReading = false;
+ NWindows::CThread Thread;
+ return Thread.Create(CoderThread, this);
+}
+
+void CInMemStreamMt::FreeSubStream(int subStreamIndex)
+{
+ // printf("\nFreeSubStream\n");
+ _streams[subStreamIndex].Free(Callback);
+ _streamIndexAllocator.FreeItem(subStreamIndex);
+ // printf("\nFreeSubStream end\n");
+}
+
+HRESULT CInMemStreamMt::ReadSubStream(int subStreamIndex, void *data, UInt32 size, UInt32 *processedSize, bool keepData)
+{
+ if (processedSize != NULL)
+ *processedSize = 0;
+ CStreamInfo &blocks = _streams[subStreamIndex];
+ while (size > 0)
+ {
+ if (blocks.CurBlockPos == Callback->GetBlockSize())
+ {
+ blocks.CurBlockPos = 0;
+ blocks.CurBlockIndex++;
+ }
+ UInt32 curSize;
+ UInt32 curPos = blocks.CurBlockPos;
+
+ blocks.Cs->Enter();
+ if (blocks.CurBlockIndex == blocks.LastBlockIndex)
+ {
+ curSize = blocks.LastBlockPos - curPos;
+ if (curSize == 0)
+ {
+ if (blocks.StreamWasFinished)
+ {
+ blocks.Cs->Leave();
+ void *p = blocks.Blocks[blocks.CurBlockIndex];
+ if (p != 0 && !keepData)
+ {
+ Callback->FreeBlock(p);
+ blocks.Blocks[blocks.CurBlockIndex] = 0;
+ }
+ return S_OK;
+ }
+ blocks.CanReadEvent->Reset();
+ blocks.Cs->Leave();
+ // printf("\nBlock Lock\n");
+ blocks.CanReadEvent->Lock();
+ // printf("\nAfter Lock\n");
+ if (blocks.ExitResult != S_OK)
+ return blocks.ExitResult;
+ continue;
+ }
+ }
+ else
+ curSize = Callback->GetBlockSize() - curPos;
+ blocks.Cs->Leave();
+
+ if (curSize > size)
+ curSize = size;
+ void *p = blocks.Blocks[blocks.CurBlockIndex];
+ memmove(data, (const Byte *)p + curPos, curSize);
+ data = (void *)((Byte *)data + curSize);
+ size -= curSize;
+ if (processedSize != NULL)
+ *processedSize += curSize;
+ curPos += curSize;
+
+ bool needFree = false;
+ blocks.CurBlockPos = curPos;
+
+ if (curPos == Callback->GetBlockSize())
+ needFree = true;
+ blocks.Cs->Enter();
+ if (blocks.CurBlockIndex == blocks.LastBlockIndex &&
+ blocks.CurBlockPos == blocks.LastBlockPos &&
+ blocks.StreamWasFinished)
+ needFree = true;
+ blocks.Cs->Leave();
+
+ if (needFree && !keepData)
+ {
+ Callback->FreeBlock(p);
+ blocks.Blocks[blocks.CurBlockIndex] = 0;
+ }
+ return S_OK;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CInMemStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize;
+ HRESULT result = mtStream->ReadSubStream(Index, data, size, &realProcessedSize, _keepData);
+ if (processedSize != NULL)
+ *processedSize = realProcessedSize;
+ if (realProcessedSize != 0)
+ {
+ // printf("\ns = %d\n", Index);
+ }
+ _size += realProcessedSize;
+ return result;
+}
diff --git a/CPP/7zip/Common/InMemStream.h b/CPP/7zip/Common/InMemStream.h
new file mode 100755
index 00000000..fcd0092d
--- /dev/null
+++ b/CPP/7zip/Common/InMemStream.h
@@ -0,0 +1,282 @@
+// InMemStream.h
+
+#ifndef __INMEMSTREAM_H
+#define __INMEMSTREAM_H
+
+#include <stdio.h>
+
+#include "../../Common/MyCom.h"
+#include "MemBlocks.h"
+
+class CIntListCheck
+{
+protected:
+ int *_data;
+public:
+ CIntListCheck(): _data(0) {}
+ ~CIntListCheck() { FreeList(); }
+
+ bool AllocateList(int numItems)
+ {
+ FreeList();
+ if (numItems == 0)
+ return true;
+ _data = (int *)::MyAlloc(numItems * sizeof(int));
+ return (_data != 0);
+ }
+
+ void FreeList()
+ {
+ ::MyFree(_data);
+ _data = 0;
+ }
+};
+
+
+class CResourceList : public CIntListCheck
+{
+ int _headFree;
+public:
+ CResourceList(): _headFree(-1) {}
+
+ bool AllocateList(int numItems)
+ {
+ FreeList();
+ if (numItems == 0)
+ return true;
+ if (!CIntListCheck::AllocateList(numItems))
+ return false;
+ for (int i = 0; i < numItems; i++)
+ _data[i] = i + 1;
+ _data[numItems - 1] = -1;
+ _headFree = 0;
+ return true;
+ }
+
+ void FreeList()
+ {
+ CIntListCheck::FreeList();
+ _headFree = -1;
+ }
+
+ int AllocateItem()
+ {
+ int res = _headFree;
+ if (res >= 0)
+ _headFree = _data[res];
+ return res;
+ }
+
+ void FreeItem(int index)
+ {
+ if (index < 0)
+ return;
+ _data[index] = _headFree;
+ _headFree = index;
+ }
+};
+
+class CResourceListMt: public CResourceList
+{
+ NWindows::NSynchronization::CCriticalSection _criticalSection;
+public:
+ NWindows::NSynchronization::CSemaphore Semaphore;
+
+ bool AllocateList(int numItems)
+ {
+ if (!CResourceList::AllocateList(numItems))
+ return false;
+ return Semaphore.Create((LONG)numItems, (LONG)numItems);
+ }
+
+ int AllocateItem()
+ {
+ Semaphore.Lock();
+ _criticalSection.Enter();
+ int res = CResourceList::AllocateItem();
+ _criticalSection.Leave();
+ return res;
+ }
+
+ void FreeItem(int index)
+ {
+ if (index < 0)
+ return;
+ _criticalSection.Enter();
+ CResourceList::FreeItem(index);
+ _criticalSection.Leave();
+ Semaphore.Release();
+ }
+};
+
+class CIntQueueMt: public CIntListCheck
+{
+ int _numItems;
+ int _head;
+ int _cur;
+public:
+ CIntQueueMt(): _numItems(0), _head(0), _cur(0) {}
+ NWindows::NSynchronization::CSemaphore Semaphore;
+
+ bool AllocateList(int numItems)
+ {
+ FreeList();
+ if (numItems == 0)
+ return true;
+ if (!CIntListCheck::AllocateList(numItems))
+ return false;
+ _numItems = numItems;
+ return Semaphore.Create((LONG)0, (LONG)numItems);
+ }
+
+ void FreeList()
+ {
+ CIntListCheck::FreeList();
+ _numItems = 0;
+ _head = 0;
+ _cur = 0;
+ }
+
+ void AddItem(int value)
+ {
+ _data[_head++] = value;
+ if (_head == _numItems)
+ _head = 0;
+ LONG previousCount;
+ Semaphore.Release(1, &previousCount);
+ // printf("\nRelease prev = %d\n", previousCount);
+
+ }
+
+ int GetItem()
+ {
+ // Semaphore.Lock();
+ int res = _data[_cur++];
+ if (_cur == _numItems)
+ _cur = 0;
+ return res;
+ }
+};
+
+struct IInMemStreamMtCallback
+{
+ // must be same for all calls
+ virtual size_t GetBlockSize() = 0;
+
+ // Out:
+ // result != S_OK stops Reading
+ // if *p = 0, result must be != S_OK;
+ // Locking is allowed
+ virtual HRESULT AllocateBlock(void **p) = 0;
+
+ virtual void FreeBlock(void *p) = 0;
+
+ // It must allow to add at least numSubStreams + 1 ,
+ // where numSubStreams is value from CInMemStreamMt::Create
+ // value -1 means End of stream
+ // Locking is not allowed
+ virtual void AddStreamIndexToQueue(int index) = 0;
+};
+
+struct CStreamInfo
+{
+ CRecordVector<void *> Blocks;
+
+ int LastBlockIndex;
+ size_t LastBlockPos;
+ bool StreamWasFinished;
+
+ int CurBlockIndex;
+ size_t CurBlockPos;
+
+ NWindows::NSynchronization::CCriticalSection *Cs;
+ NWindows::NSynchronization::CManualResetEvent *CanReadEvent;
+
+ HRESULT ExitResult;
+
+ CStreamInfo(): Cs(0), CanReadEvent(0), StreamWasFinished(false) { }
+ ~CStreamInfo()
+ {
+ delete Cs;
+ delete CanReadEvent;
+ // Free();
+ }
+ void Create()
+ {
+ Cs = new NWindows::NSynchronization::CCriticalSection;
+ CanReadEvent = new NWindows::NSynchronization::CManualResetEvent;
+ }
+
+ void Free(IInMemStreamMtCallback *callback);
+ void Init()
+ {
+ LastBlockIndex = CurBlockIndex = 0;
+ CurBlockPos = LastBlockPos = 0;
+ StreamWasFinished = false;
+ ExitResult = S_OK;
+ }
+
+ // res must be != S_OK
+ void Exit(HRESULT res)
+ {
+ ExitResult = res;
+ CanReadEvent->Set();
+ }
+};
+
+
+class CInMemStreamMt
+{
+ CMyComPtr<ISequentialInStream> _stream;
+ NWindows::NSynchronization::CCriticalSection CS;
+ CObjectVector<CStreamInfo> _streams;
+ int _nextFreeStreamIndex;
+ int _currentStreamIndex;
+ UInt64 _subStreamSize;
+
+ CResourceListMt _streamIndexAllocator;
+
+ // bool _stopReading;
+
+public:
+ HRESULT Read();
+ HRESULT ReadResult;
+ IInMemStreamMtCallback *Callback;
+ void FreeSubStream(int subStreamIndex);
+ HRESULT ReadSubStream(int subStreamIndex, void *data, UInt32 size, UInt32 *processedSize, bool keepData);
+
+ // numSubStreams: min = 1, good min = numThreads
+ bool Create(int numSubStreams, UInt64 subStreamSize);
+ ~CInMemStreamMt() { Free(); }
+ void SetStream(ISequentialInStream *stream) { _stream = stream; }
+
+ // to stop reading you must implement
+ // returning Error in IInMemStreamMtCallback::AllocateBlock
+ // and then you must free at least one substream
+ bool StartReadThread();
+
+ void Free();
+
+ // you must free at least one substream after that function to unlock waiting.
+ // void StopReading() { _stopReading = true; }
+};
+
+class CInMemStream:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ UInt64 _size;
+ bool _keepData;
+public:
+ int Index;
+ CInMemStreamMt *mtStream;
+ void Init(bool keepData = false)
+ {
+ _size = 0; _keepData = keepData ;
+ }
+ MY_UNKNOWN_IMP
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ UInt64 GetSize() const { return _size; }
+};
+
+#endif
diff --git a/CPP/7zip/Common/InOutTempBuffer.cpp b/CPP/7zip/Common/InOutTempBuffer.cpp
new file mode 100755
index 00000000..ffaed32c
--- /dev/null
+++ b/CPP/7zip/Common/InOutTempBuffer.cpp
@@ -0,0 +1,122 @@
+// InOutTempBuffer.cpp
+
+#include "StdAfx.h"
+
+#include "InOutTempBuffer.h"
+#include "../../Common/Defs.h"
+// #include "Windows/Defs.h"
+
+#include "StreamUtils.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NDirectory;
+
+static UInt32 kTmpBufferMemorySize = (1 << 20);
+
+static LPCTSTR kTempFilePrefixString = TEXT("iot");
+
+CInOutTempBuffer::CInOutTempBuffer():
+ _buffer(NULL)
+{
+}
+
+void CInOutTempBuffer::Create()
+{
+ _buffer = new Byte[kTmpBufferMemorySize];
+}
+
+CInOutTempBuffer::~CInOutTempBuffer()
+{
+ delete []_buffer;
+}
+void CInOutTempBuffer::InitWriting()
+{
+ _bufferPosition = 0;
+ _tmpFileCreated = false;
+ _fileSize = 0;
+}
+
+bool CInOutTempBuffer::WriteToFile(const void *data, UInt32 size)
+{
+ if (size == 0)
+ return true;
+ if(!_tmpFileCreated)
+ {
+ CSysString tempDirPath;
+ if(!MyGetTempPath(tempDirPath))
+ return false;
+ if (_tempFile.Create(tempDirPath, kTempFilePrefixString, _tmpFileName) == 0)
+ return false;
+ // _outFile.SetOpenCreationDispositionCreateAlways();
+ if(!_outFile.Create(_tmpFileName, true))
+ return false;
+ _tmpFileCreated = true;
+ }
+ UInt32 processedSize;
+ if(!_outFile.Write(data, size, processedSize))
+ return false;
+ _fileSize += processedSize;
+ return (processedSize == size);
+}
+
+bool CInOutTempBuffer::FlushWrite()
+{
+ return _outFile.Close();
+}
+
+bool CInOutTempBuffer::Write(const void *data, UInt32 size)
+{
+ if(_bufferPosition < kTmpBufferMemorySize)
+ {
+ UInt32 curSize = MyMin(kTmpBufferMemorySize - _bufferPosition, size);
+ memmove(_buffer + _bufferPosition, (const Byte *)data, curSize);
+ _bufferPosition += curSize;
+ size -= curSize;
+ data = ((const Byte *)data) + curSize;
+ _fileSize += curSize;
+ }
+ return WriteToFile(data, size);
+}
+
+bool CInOutTempBuffer::InitReading()
+{
+ _currentPositionInBuffer = 0;
+ if(_tmpFileCreated)
+ return _inFile.Open(_tmpFileName);
+ return true;
+}
+
+HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream)
+{
+ if (_currentPositionInBuffer < _bufferPosition)
+ {
+ UInt32 sizeToWrite = _bufferPosition - _currentPositionInBuffer;
+ RINOK(WriteStream(stream, _buffer + _currentPositionInBuffer, sizeToWrite, NULL));
+ _currentPositionInBuffer += sizeToWrite;
+ }
+ if (!_tmpFileCreated)
+ return true;
+ for (;;)
+ {
+ UInt32 localProcessedSize;
+ if (!_inFile.ReadPart(_buffer, kTmpBufferMemorySize, localProcessedSize))
+ return E_FAIL;
+ if (localProcessedSize == 0)
+ return S_OK;
+ RINOK(WriteStream(stream, _buffer, localProcessedSize, NULL));
+ }
+}
+
+STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (!_buffer->Write(data, size))
+ {
+ if (processedSize != NULL)
+ *processedSize = 0;
+ return E_FAIL;
+ }
+ if (processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
diff --git a/CPP/7zip/Common/InOutTempBuffer.h b/CPP/7zip/Common/InOutTempBuffer.h
new file mode 100755
index 00000000..3abe76ec
--- /dev/null
+++ b/CPP/7zip/Common/InOutTempBuffer.h
@@ -0,0 +1,55 @@
+// Util/InOutTempBuffer.h
+
+#ifndef __IN_OUT_TEMP_BUFFER_H
+#define __IN_OUT_TEMP_BUFFER_H
+
+#include "../../Windows/FileIO.h"
+#include "../../Windows/FileDir.h"
+#include "../../Common/MyCom.h"
+
+#include "../IStream.h"
+
+class CInOutTempBuffer
+{
+ NWindows::NFile::NDirectory::CTempFile _tempFile;
+ NWindows::NFile::NIO::COutFile _outFile;
+ NWindows::NFile::NIO::CInFile _inFile;
+ Byte *_buffer;
+ UInt32 _bufferPosition;
+ UInt32 _currentPositionInBuffer;
+ CSysString _tmpFileName;
+ bool _tmpFileCreated;
+
+ UInt64 _fileSize;
+
+ bool WriteToFile(const void *data, UInt32 size);
+public:
+ CInOutTempBuffer();
+ ~CInOutTempBuffer();
+ void Create();
+
+ void InitWriting();
+ bool Write(const void *data, UInt32 size);
+ UInt64 GetDataSize() const { return _fileSize; }
+ bool FlushWrite();
+ bool InitReading();
+ HRESULT WriteToStream(ISequentialOutStream *stream);
+};
+
+class CSequentialOutTempBufferImp:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ CInOutTempBuffer *_buffer;
+public:
+ // CSequentialOutStreamImp(): _size(0) {}
+ // UInt32 _size;
+ void Init(CInOutTempBuffer *buffer) { _buffer = buffer; }
+ // UInt32 GetSize() const { return _size; }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+#endif
diff --git a/CPP/7zip/Common/LSBFDecoder.cpp b/CPP/7zip/Common/LSBFDecoder.cpp
new file mode 100755
index 00000000..76dd090f
--- /dev/null
+++ b/CPP/7zip/Common/LSBFDecoder.cpp
@@ -0,0 +1,27 @@
+// Stream/LSBFDecoder.cpp
+
+#include "StdAfx.h"
+
+#include "LSBFDecoder.h"
+
+namespace NStream {
+namespace NLSBF {
+
+Byte kInvertTable[256];
+
+class CInverterTableInitializer
+{
+public:
+ CInverterTableInitializer()
+ {
+ for (int i = 0; i < 256; i++)
+ {
+ int x = ((i & 0x55) << 1) | ((i & 0xAA) >> 1);
+ x = ((x & 0x33) << 2) | ((x & 0xCC) >> 2);
+ kInvertTable[i] = (Byte)(((x & 0x0F) << 4) | ((x & 0xF0) >> 4));
+ }
+ }
+} g_InverterTableInitializer;
+
+
+}}
diff --git a/CPP/7zip/Common/LSBFDecoder.h b/CPP/7zip/Common/LSBFDecoder.h
new file mode 100755
index 00000000..75458452
--- /dev/null
+++ b/CPP/7zip/Common/LSBFDecoder.h
@@ -0,0 +1,127 @@
+// LSBFDecoder.h
+
+#ifndef __STREAM_LSBFDECODER_H
+#define __STREAM_LSBFDECODER_H
+
+#include "../IStream.h"
+
+namespace NStream {
+namespace NLSBF {
+
+const int kNumBigValueBits = 8 * 4;
+
+const int kNumValueBytes = 3;
+const int kNumValueBits = 8 * kNumValueBytes;
+
+const UInt32 kMask = (1 << kNumValueBits) - 1;
+
+extern Byte kInvertTable[256];
+// the Least Significant Bit of byte is First
+
+template<class TInByte>
+class CBaseDecoder
+{
+protected:
+ int m_BitPos;
+ UInt32 m_Value;
+ TInByte m_Stream;
+public:
+ UInt32 NumExtraBytes;
+ bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }
+ void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream); }
+ void ReleaseStream() { m_Stream.ReleaseStream(); }
+ void Init()
+ {
+ m_Stream.Init();
+ m_BitPos = kNumBigValueBits;
+ m_Value = 0;
+ NumExtraBytes = 0;
+ }
+ UInt64 GetProcessedSize() const
+ { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; }
+ UInt64 GetProcessedBitsSize() const
+ { return (m_Stream.GetProcessedSize() << 3) - (kNumBigValueBits - m_BitPos); }
+ int GetBitPosition() const { return (m_BitPos & 7); }
+
+ void Normalize()
+ {
+ for (;m_BitPos >= 8; m_BitPos -= 8)
+ {
+ Byte b = 0;
+ if (!m_Stream.ReadByte(b))
+ {
+ b = 0xFF; // check it
+ NumExtraBytes++;
+ }
+ m_Value = (b << (kNumBigValueBits - m_BitPos)) | m_Value;
+ }
+ }
+
+ UInt32 ReadBits(int numBits)
+ {
+ Normalize();
+ UInt32 res = m_Value & ((1 << numBits) - 1);
+ m_BitPos += numBits;
+ m_Value >>= numBits;
+ return res;
+ }
+
+ bool ExtraBitsWereRead() const
+ {
+ if (NumExtraBytes == 0)
+ return false;
+ return ((UInt32)(kNumBigValueBits - m_BitPos) < (NumExtraBytes << 3));
+ }
+};
+
+template<class TInByte>
+class CDecoder: public CBaseDecoder<TInByte>
+{
+ UInt32 m_NormalValue;
+
+public:
+ void Init()
+ {
+ CBaseDecoder<TInByte>::Init();
+ m_NormalValue = 0;
+ }
+
+ void Normalize()
+ {
+ for (; this->m_BitPos >= 8; this->m_BitPos -= 8)
+ {
+ Byte b = 0;
+ if (!this->m_Stream.ReadByte(b))
+ {
+ b = 0xFF; // check it
+ this->NumExtraBytes++;
+ }
+ m_NormalValue = (b << (kNumBigValueBits - this->m_BitPos)) | m_NormalValue;
+ this->m_Value = (this->m_Value << 8) | kInvertTable[b];
+ }
+ }
+
+ UInt32 GetValue(int numBits)
+ {
+ Normalize();
+ return ((this->m_Value >> (8 - this->m_BitPos)) & kMask) >> (kNumValueBits - numBits);
+ }
+
+ void MovePos(int numBits)
+ {
+ this->m_BitPos += numBits;
+ m_NormalValue >>= numBits;
+ }
+
+ UInt32 ReadBits(int numBits)
+ {
+ Normalize();
+ UInt32 res = m_NormalValue & ( (1 << numBits) - 1);
+ MovePos(numBits);
+ return res;
+ }
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Common/LSBFEncoder.cpp b/CPP/7zip/Common/LSBFEncoder.cpp
new file mode 100755
index 00000000..6322cae3
--- /dev/null
+++ b/CPP/7zip/Common/LSBFEncoder.cpp
@@ -0,0 +1,29 @@
+// LSBFEncoder.cpp
+
+#include "StdAfx.h"
+
+#include "LSBFEncoder.h"
+#include "Common/Defs.h"
+
+namespace NStream {
+namespace NLSBF {
+
+void CEncoder::WriteBits(UInt32 value, int numBits)
+{
+ while(numBits > 0)
+ {
+ if (numBits < m_BitPos)
+ {
+ m_CurByte |= (value & ((1 << numBits) - 1)) << (8 - m_BitPos);
+ m_BitPos -= numBits;
+ return;
+ }
+ numBits -= m_BitPos;
+ m_Stream.WriteByte((Byte)(m_CurByte | (value << (8 - m_BitPos))));
+ value >>= m_BitPos;
+ m_BitPos = 8;
+ m_CurByte = 0;
+ }
+}
+
+}}
diff --git a/CPP/7zip/Common/LSBFEncoder.h b/CPP/7zip/Common/LSBFEncoder.h
new file mode 100755
index 00000000..72c84d9f
--- /dev/null
+++ b/CPP/7zip/Common/LSBFEncoder.h
@@ -0,0 +1,51 @@
+// Stream/LSBFEncoder.h
+
+#ifndef __STREAM_LSBFENCODER_H
+#define __STREAM_LSBFENCODER_H
+
+#include "../IStream.h"
+#include "OutBuffer.h"
+
+namespace NStream {
+namespace NLSBF {
+
+class CEncoder
+{
+ COutBuffer m_Stream;
+ int m_BitPos;
+ Byte m_CurByte;
+public:
+ bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }
+ void SetStream(ISequentialOutStream *outStream) { m_Stream.SetStream(outStream); }
+ void ReleaseStream() { m_Stream.ReleaseStream(); }
+ void Init()
+ {
+ m_Stream.Init();
+ m_BitPos = 8;
+ m_CurByte = 0;
+ }
+ HRESULT Flush()
+ {
+ FlushByte();
+ return m_Stream.Flush();
+ }
+
+ void FlushByte()
+ {
+ if(m_BitPos < 8)
+ m_Stream.WriteByte(m_CurByte);
+ m_BitPos = 8;
+ m_CurByte = 0;
+ }
+
+ void WriteBits(UInt32 value, int numBits);
+ UInt32 GetBitPosition() const { return (8 - m_BitPos); }
+ UInt64 GetProcessedSize() const {
+ return m_Stream.GetProcessedSize() + (8 - m_BitPos + 7) /8; }
+ void WriteByte(Byte b) { m_Stream.WriteByte(b);}
+};
+
+
+}}
+
+#endif
diff --git a/CPP/7zip/Common/LimitedStreams.cpp b/CPP/7zip/Common/LimitedStreams.cpp
new file mode 100755
index 00000000..af721146
--- /dev/null
+++ b/CPP/7zip/Common/LimitedStreams.cpp
@@ -0,0 +1,24 @@
+// LimitedStreams.cpp
+
+#include "StdAfx.h"
+
+#include "LimitedStreams.h"
+#include "../../Common/Defs.h"
+
+STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize = 0;
+ UInt32 sizeToRead = (UInt32)MyMin((_size - _pos), (UInt64)size);
+ HRESULT result = S_OK;
+ if (sizeToRead > 0)
+ {
+ result = _stream->Read(data, sizeToRead, &realProcessedSize);
+ _pos += realProcessedSize;
+ if (realProcessedSize == 0)
+ _wasFinished = true;
+ }
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return result;
+}
+
diff --git a/CPP/7zip/Common/LimitedStreams.h b/CPP/7zip/Common/LimitedStreams.h
new file mode 100755
index 00000000..ec4a3a70
--- /dev/null
+++ b/CPP/7zip/Common/LimitedStreams.h
@@ -0,0 +1,33 @@
+// LimitedStreams.h
+
+#ifndef __LIMITEDSTREAMS_H
+#define __LIMITEDSTREAMS_H
+
+#include "../../Common/MyCom.h"
+#include "../IStream.h"
+
+class CLimitedSequentialInStream:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ CMyComPtr<ISequentialInStream> _stream;
+ UInt64 _size;
+ UInt64 _pos;
+ bool _wasFinished;
+public:
+ void SetStream(ISequentialInStream *stream) { _stream = stream; }
+ void Init(UInt64 streamSize)
+ {
+ _size = streamSize;
+ _pos = 0;
+ _wasFinished = false;
+ }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ UInt64 GetSize() const { return _pos; }
+ bool WasFinished() const { return _wasFinished; }
+};
+
+#endif
diff --git a/CPP/7zip/Common/LockedStream.cpp b/CPP/7zip/Common/LockedStream.cpp
new file mode 100755
index 00000000..36be1ceb
--- /dev/null
+++ b/CPP/7zip/Common/LockedStream.cpp
@@ -0,0 +1,23 @@
+// LockedStream.cpp
+
+#include "StdAfx.h"
+
+#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);
+}
+
+STDMETHODIMP CLockedSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize = 0;
+ HRESULT result = _lockedInStream->Read(_pos, data, size, &realProcessedSize);
+ _pos += realProcessedSize;
+ if (processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return result;
+}
diff --git a/CPP/7zip/Common/LockedStream.h b/CPP/7zip/Common/LockedStream.h
new file mode 100755
index 00000000..1c1e1793
--- /dev/null
+++ b/CPP/7zip/Common/LockedStream.h
@@ -0,0 +1,38 @@
+// LockedStream.h
+
+#ifndef __LOCKEDSTREAM_H
+#define __LOCKEDSTREAM_H
+
+#include "../../Windows/Synchronization.h"
+#include "../../Common/MyCom.h"
+#include "../IStream.h"
+
+class CLockedInStream
+{
+ CMyComPtr<IInStream> _stream;
+ NWindows::NSynchronization::CCriticalSection _criticalSection;
+public:
+ void Init(IInStream *stream)
+ { _stream = stream; }
+ HRESULT Read(UInt64 startPos, void *data, UInt32 size, UInt32 *processedSize);
+};
+
+class CLockedSequentialInStreamImp:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ CLockedInStream *_lockedInStream;
+ UInt64 _pos;
+public:
+ void Init(CLockedInStream *lockedInStream, UInt64 startPos)
+ {
+ _lockedInStream = lockedInStream;
+ _pos = startPos;
+ }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+#endif
diff --git a/CPP/7zip/Common/MSBFDecoder.h b/CPP/7zip/Common/MSBFDecoder.h
new file mode 100755
index 00000000..dc80c0f7
--- /dev/null
+++ b/CPP/7zip/Common/MSBFDecoder.h
@@ -0,0 +1,69 @@
+// MSBFDecoder.h
+// the Most Significant Bit of byte is First
+
+#ifndef __STREAM_MSBFDECODER_H
+#define __STREAM_MSBFDECODER_H
+
+#include "../../Common/Types.h"
+#include "../IStream.h"
+
+namespace NStream {
+namespace NMSBF {
+
+const int kNumBigValueBits = 8 * 4;
+const int kNumValueBytes = 3;
+const int kNumValueBits = 8 * kNumValueBytes;
+
+const UInt32 kMask = (1 << kNumValueBits) - 1;
+
+template<class TInByte>
+class CDecoder
+{
+ 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();}
+
+ void Init()
+ {
+ m_Stream.Init();
+ m_BitPos = kNumBigValueBits;
+ Normalize();
+ }
+
+ UInt64 GetProcessedSize() const
+ { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; }
+ UInt32 GetBitPosition() const { return (m_BitPos & 7); }
+
+ void Normalize()
+ {
+ for (;m_BitPos >= 8; m_BitPos -= 8)
+ m_Value = (m_Value << 8) | m_Stream.ReadByte();
+ }
+
+ UInt32 GetValue(UInt32 numBits) const
+ {
+ // return (m_Value << m_BitPos) >> (kNumBigValueBits - numBits);
+ return ((m_Value >> (8 - m_BitPos)) & kMask) >> (kNumValueBits - numBits);
+ }
+
+ void MovePos(UInt32 numBits)
+ {
+ m_BitPos += numBits;
+ Normalize();
+ }
+
+ UInt32 ReadBits(UInt32 numBits)
+ {
+ UInt32 res = GetValue(numBits);
+ MovePos(numBits);
+ return res;
+ }
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Common/MSBFEncoder.h b/CPP/7zip/Common/MSBFEncoder.h
new file mode 100755
index 00000000..767a0e57
--- /dev/null
+++ b/CPP/7zip/Common/MSBFEncoder.h
@@ -0,0 +1,59 @@
+// Stream/MSBFEncoder.h
+
+#ifndef __STREAM_MSBFENCODER_H
+#define __STREAM_MSBFENCODER_H
+
+#include "Common/Defs.h"
+#include "../IStream.h"
+#include "OutBuffer.h"
+
+namespace NStream {
+namespace NMSBF {
+
+template<class TOutByte>
+class CEncoder
+{
+ TOutByte m_Stream;
+ int m_BitPos;
+ Byte m_CurByte;
+public:
+ bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }
+ void SetStream(ISequentialOutStream *outStream) { m_Stream.SetStream(outStream);}
+ void ReleaseStream() { m_Stream.ReleaseStream(); }
+ void Init()
+ {
+ m_Stream.Init();
+ m_BitPos = 8;
+ m_CurByte = 0;
+ }
+ HRESULT Flush()
+ {
+ if(m_BitPos < 8)
+ WriteBits(0, m_BitPos);
+ return m_Stream.Flush();
+ }
+
+ void WriteBits(UInt32 value, int numBits)
+ {
+ while(numBits > 0)
+ {
+ if (numBits < m_BitPos)
+ {
+ m_CurByte |= ((Byte)value << (m_BitPos -= numBits));
+ return;
+ }
+ numBits -= m_BitPos;
+ UInt32 newBits = (value >> numBits);
+ value -= (newBits << numBits);
+ m_Stream.WriteByte((Byte)(m_CurByte | newBits));
+ m_BitPos = 8;
+ m_CurByte = 0;
+ }
+ }
+ UInt64 GetProcessedSize() const {
+ return m_Stream.GetProcessedSize() + (8 - m_BitPos + 7) / 8; }
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Common/MemBlocks.cpp b/CPP/7zip/Common/MemBlocks.cpp
new file mode 100755
index 00000000..d2b79a70
--- /dev/null
+++ b/CPP/7zip/Common/MemBlocks.cpp
@@ -0,0 +1,184 @@
+// MemBlocks.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyCom.h"
+
+#include "StreamUtils.h"
+#include "MemBlocks.h"
+
+bool CMemBlockManager::AllocateSpace(size_t numBlocks)
+{
+ FreeSpace();
+ if (_blockSize < sizeof(void *) || numBlocks < 1)
+ return false;
+ size_t totalSize = numBlocks * _blockSize;
+ if (totalSize / _blockSize != numBlocks)
+ return false;
+ _data = ::MidAlloc(totalSize);
+ if (_data == 0)
+ return false;
+ Byte *p = (Byte *)_data;
+ for (size_t i = 0; i + 1 < numBlocks; i++, p += _blockSize)
+ *(Byte **)p = (p + _blockSize);
+ *(Byte **)p = 0;
+ _headFree = _data;
+ return true;
+}
+
+void CMemBlockManager::FreeSpace()
+{
+ ::MidFree(_data);
+ _data = 0;
+ _headFree= 0;
+}
+
+void *CMemBlockManager::AllocateBlock()
+{
+ if (_headFree == 0)
+ return 0;
+ void *p = _headFree;
+ _headFree = *(void **)_headFree;
+ return p;
+}
+
+void CMemBlockManager::FreeBlock(void *p)
+{
+ if (p == 0)
+ return;
+ *(void **)p = _headFree;
+ _headFree = p;
+}
+
+
+bool CMemBlockManagerMt::AllocateSpace(size_t numBlocks, size_t numNoLockBlocks)
+{
+ if (numNoLockBlocks > numBlocks)
+ return false;
+ if (!CMemBlockManager::AllocateSpace(numBlocks))
+ return false;
+ size_t numLockBlocks = numBlocks - numNoLockBlocks;
+ return Semaphore.Create((LONG)numLockBlocks, (LONG)numLockBlocks);
+}
+
+bool CMemBlockManagerMt::AllocateSpaceAlways(size_t desiredNumberOfBlocks, size_t numNoLockBlocks)
+{
+ if (numNoLockBlocks > desiredNumberOfBlocks)
+ return false;
+ for (;;)
+ {
+ if (AllocateSpace(desiredNumberOfBlocks, numNoLockBlocks))
+ return true;
+ if (desiredNumberOfBlocks == numNoLockBlocks)
+ return false;
+ desiredNumberOfBlocks = numNoLockBlocks + ((desiredNumberOfBlocks - numNoLockBlocks) >> 1);
+ }
+}
+
+void CMemBlockManagerMt::FreeSpace()
+{
+ Semaphore.Close();
+ CMemBlockManager::FreeSpace();
+}
+
+void *CMemBlockManagerMt::AllocateBlock()
+{
+ // Semaphore.Lock();
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ return CMemBlockManager::AllocateBlock();
+}
+
+void CMemBlockManagerMt::FreeBlock(void *p, bool lockMode)
+{
+ if (p == 0)
+ return;
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ CMemBlockManager::FreeBlock(p);
+ }
+ if (lockMode)
+ Semaphore.Release();
+}
+
+void CMemBlocks::Free(CMemBlockManagerMt *manager)
+{
+ while(Blocks.Size() > 0)
+ {
+ manager->FreeBlock(Blocks.Back());
+ Blocks.DeleteBack();
+ }
+ TotalSize = 0;
+}
+
+void CMemBlocks::FreeOpt(CMemBlockManagerMt *manager)
+{
+ Free(manager);
+ Blocks.Free(); // to reduce memory usage
+}
+
+HRESULT CMemBlocks::WriteToStream(size_t blockSize, ISequentialOutStream *outStream) const
+{
+ UInt64 totalSize = TotalSize;
+ for (int blockIndex = 0; totalSize > 0; blockIndex++)
+ {
+ UInt32 curSize = (UInt32)blockSize;
+ if (totalSize < curSize)
+ curSize = (UInt32)totalSize;
+ UInt32 processedSize;
+ if (blockIndex >= Blocks.Size())
+ return E_FAIL;
+ RINOK(WriteStream(outStream, Blocks[blockIndex], curSize, &processedSize));
+ if (processedSize != curSize)
+ return E_FAIL;
+ totalSize -= processedSize;
+ }
+ return S_OK;
+}
+
+
+void CMemLockBlocks::FreeBlock(int index, CMemBlockManagerMt *memManager)
+{
+ memManager->FreeBlock(Blocks[index], LockMode);
+ Blocks[index] = 0;
+}
+
+void CMemLockBlocks::Free(CMemBlockManagerMt *memManager)
+{
+ while (Blocks.Size() > 0)
+ {
+ FreeBlock(Blocks.Size() - 1, memManager);
+ Blocks.DeleteBack();
+ }
+ TotalSize = 0;
+}
+
+bool CMemLockBlocks::SwitchToNoLockMode(CMemBlockManagerMt *memManager)
+{
+ if (LockMode)
+ {
+ if (Blocks.Size() > 0)
+ if (!memManager->ReleaseLockedBlocks(Blocks.Size()))
+ return false;
+ LockMode = false;
+ }
+ return true;
+}
+
+void CMemLockBlocks::Detach(CMemLockBlocks &blocks, CMemBlockManagerMt *memManager)
+{
+ blocks.Free(memManager);
+ blocks.LockMode = LockMode;
+ UInt64 totalSize = 0;
+ size_t blockSize = memManager->GetBlockSize();
+ for (int i = 0; i < Blocks.Size(); i++)
+ {
+ if (totalSize < TotalSize)
+ blocks.Blocks.Add(Blocks[i]);
+ else
+ FreeBlock(i, memManager);
+ Blocks[i] = 0;
+ totalSize += blockSize;
+ }
+ blocks.TotalSize = TotalSize;
+ Free(memManager);
+}
diff --git a/CPP/7zip/Common/MemBlocks.h b/CPP/7zip/Common/MemBlocks.h
new file mode 100755
index 00000000..31cd3546
--- /dev/null
+++ b/CPP/7zip/Common/MemBlocks.h
@@ -0,0 +1,73 @@
+// MemBlocks.h
+
+#ifndef __MEMBLOCKS_H
+#define __MEMBLOCKS_H
+
+#include "Common/Alloc.h"
+#include "Common/Types.h"
+#include "Common/Vector.h"
+
+#include "Windows/Synchronization.h"
+
+#include "../IStream.h"
+
+class CMemBlockManager
+{
+ void *_data;
+ size_t _blockSize;
+ void *_headFree;
+public:
+ CMemBlockManager(size_t blockSize = (1 << 20)): _data(0), _blockSize(blockSize), _headFree(0) {}
+ ~CMemBlockManager() { FreeSpace(); }
+
+ bool AllocateSpace(size_t numBlocks);
+ void FreeSpace();
+ size_t GetBlockSize() const { return _blockSize; }
+ void *AllocateBlock();
+ void FreeBlock(void *p);
+};
+
+
+class CMemBlockManagerMt: public CMemBlockManager
+{
+ NWindows::NSynchronization::CCriticalSection _criticalSection;
+public:
+ NWindows::NSynchronization::CSemaphore Semaphore;
+
+ CMemBlockManagerMt(size_t blockSize = (1 << 20)): CMemBlockManager(blockSize) {}
+ ~CMemBlockManagerMt() { FreeSpace(); }
+
+ bool AllocateSpace(size_t numBlocks, size_t numNoLockBlocks = 0);
+ bool AllocateSpaceAlways(size_t desiredNumberOfBlocks, size_t numNoLockBlocks = 0);
+ void FreeSpace();
+ void *AllocateBlock();
+ void FreeBlock(void *p, bool lockMode = true);
+ bool ReleaseLockedBlocks(int number) { return Semaphore.Release(number); }
+};
+
+
+class CMemBlocks
+{
+ void Free(CMemBlockManagerMt *manager);
+public:
+ CRecordVector<void *> Blocks;
+ UInt64 TotalSize;
+
+ CMemBlocks(): TotalSize(0) {}
+
+ void FreeOpt(CMemBlockManagerMt *manager);
+ HRESULT WriteToStream(size_t blockSize, ISequentialOutStream *outStream) const;
+};
+
+struct CMemLockBlocks: public CMemBlocks
+{
+ bool LockMode;
+
+ CMemLockBlocks(): LockMode(true) {};
+ void Free(CMemBlockManagerMt *memManager);
+ void FreeBlock(int index, CMemBlockManagerMt *memManager);
+ bool SwitchToNoLockMode(CMemBlockManagerMt *memManager);
+ void Detach(CMemLockBlocks &blocks, CMemBlockManagerMt *memManager);
+};
+
+#endif
diff --git a/CPP/7zip/Common/OffsetStream.cpp b/CPP/7zip/Common/OffsetStream.cpp
new file mode 100755
index 00000000..997ccae2
--- /dev/null
+++ b/CPP/7zip/Common/OffsetStream.cpp
@@ -0,0 +1,35 @@
+// OffsetStream.cpp
+
+#include "StdAfx.h"
+
+#include "Common/Defs.h"
+#include "OffsetStream.h"
+
+HRESULT COffsetOutStream::Init(IOutStream *stream, UInt64 offset)
+{
+ _offset = offset;
+ _stream = stream;
+ return _stream->Seek(offset, STREAM_SEEK_SET, NULL);
+}
+
+STDMETHODIMP COffsetOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ return _stream->Write(data, size, processedSize);
+}
+
+STDMETHODIMP COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin,
+ UInt64 *newPosition)
+{
+ UInt64 absoluteNewPosition;
+ if (seekOrigin == STREAM_SEEK_SET)
+ offset += _offset;
+ HRESULT result = _stream->Seek(offset, seekOrigin, &absoluteNewPosition);
+ if (newPosition != NULL)
+ *newPosition = absoluteNewPosition - _offset;
+ return result;
+}
+
+STDMETHODIMP COffsetOutStream::SetSize(Int64 newSize)
+{
+ return _stream->SetSize(_offset + newSize);
+}
diff --git a/CPP/7zip/Common/OffsetStream.h b/CPP/7zip/Common/OffsetStream.h
new file mode 100755
index 00000000..57a055cc
--- /dev/null
+++ b/CPP/7zip/Common/OffsetStream.h
@@ -0,0 +1,25 @@
+// OffsetStream.h
+
+#ifndef __OFFSETSTREAM_H
+#define __OFFSETSTREAM_H
+
+#include "Common/MyCom.h"
+#include "../IStream.h"
+
+class COffsetOutStream:
+ public IOutStream,
+ public CMyUnknownImp
+{
+ UInt64 _offset;
+ CMyComPtr<IOutStream> _stream;
+public:
+ HRESULT Init(IOutStream *stream, UInt64 offset);
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+ STDMETHOD(SetSize)(Int64 newSize);
+};
+
+#endif
diff --git a/CPP/7zip/Common/OutBuffer.cpp b/CPP/7zip/Common/OutBuffer.cpp
new file mode 100755
index 00000000..a73fa7c5
--- /dev/null
+++ b/CPP/7zip/Common/OutBuffer.cpp
@@ -0,0 +1,116 @@
+// OutByte.cpp
+
+#include "StdAfx.h"
+
+#include "OutBuffer.h"
+
+#include "../../Common/Alloc.h"
+
+bool COutBuffer::Create(UInt32 bufferSize)
+{
+ const UInt32 kMinBlockSize = 1;
+ if (bufferSize < kMinBlockSize)
+ bufferSize = kMinBlockSize;
+ if (_buffer != 0 && _bufferSize == bufferSize)
+ return true;
+ Free();
+ _bufferSize = bufferSize;
+ _buffer = (Byte *)::MidAlloc(bufferSize);
+ return (_buffer != 0);
+}
+
+void COutBuffer::Free()
+{
+ ::MidFree(_buffer);
+ _buffer = 0;
+}
+
+void COutBuffer::SetStream(ISequentialOutStream *stream)
+{
+ _stream = stream;
+}
+
+void COutBuffer::Init()
+{
+ _streamPos = 0;
+ _limitPos = _bufferSize;
+ _pos = 0;
+ _processedSize = 0;
+ _overDict = false;
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = S_OK;
+ #endif
+}
+
+UInt64 COutBuffer::GetProcessedSize() const
+{
+ UInt64 res = _processedSize + _pos - _streamPos;
+ if (_streamPos > _pos)
+ res += _bufferSize;
+ return res;
+}
+
+
+HRESULT COutBuffer::FlushPart()
+{
+ // _streamPos < _bufferSize
+ UInt32 size = (_streamPos >= _pos) ? (_bufferSize - _streamPos) : (_pos - _streamPos);
+ HRESULT result = S_OK;
+ #ifdef _NO_EXCEPTIONS
+ result = ErrorCode;
+ #endif
+ 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;
+ if (_streamPos == _bufferSize)
+ _streamPos = 0;
+ if (_pos == _bufferSize)
+ {
+ _overDict = true;
+ _pos = 0;
+ }
+ _limitPos = (_streamPos > _pos) ? _streamPos : _bufferSize;
+ _processedSize += size;
+ return result;
+}
+
+HRESULT COutBuffer::Flush()
+{
+ #ifdef _NO_EXCEPTIONS
+ if (ErrorCode != S_OK)
+ return ErrorCode;
+ #endif
+
+ while(_streamPos != _pos)
+ {
+ HRESULT result = FlushPart();
+ if (result != S_OK)
+ return result;
+ }
+ return S_OK;
+}
+
+void COutBuffer::FlushWithCheck()
+{
+ HRESULT result = FlushPart();
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = result;
+ #else
+ if (result != S_OK)
+ throw COutBufferException(result);
+ #endif
+}
diff --git a/CPP/7zip/Common/OutBuffer.h b/CPP/7zip/Common/OutBuffer.h
new file mode 100755
index 00000000..0ce54e21
--- /dev/null
+++ b/CPP/7zip/Common/OutBuffer.h
@@ -0,0 +1,64 @@
+// OutBuffer.h
+
+#ifndef __OUTBUFFER_H
+#define __OUTBUFFER_H
+
+#include "../IStream.h"
+#include "../../Common/MyCom.h"
+
+#ifndef _NO_EXCEPTIONS
+struct COutBufferException
+{
+ HRESULT ErrorCode;
+ COutBufferException(HRESULT errorCode): ErrorCode(errorCode) {}
+};
+#endif
+
+class COutBuffer
+{
+protected:
+ Byte *_buffer;
+ UInt32 _pos;
+ UInt32 _limitPos;
+ UInt32 _streamPos;
+ UInt32 _bufferSize;
+ CMyComPtr<ISequentialOutStream> _stream;
+ UInt64 _processedSize;
+ Byte *_buffer2;
+ bool _overDict;
+
+ HRESULT FlushPart();
+ void FlushWithCheck();
+public:
+ #ifdef _NO_EXCEPTIONS
+ HRESULT ErrorCode;
+ #endif
+
+ 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 WriteByte(Byte b)
+ {
+ _buffer[_pos++] = b;
+ if(_pos == _limitPos)
+ FlushWithCheck();
+ }
+ void WriteBytes(const void *data, size_t size)
+ {
+ for (size_t i = 0; i < size; i++)
+ WriteByte(((const Byte *)data)[i]);
+ }
+
+ UInt64 GetProcessedSize() const;
+};
+
+#endif
diff --git a/CPP/7zip/Common/OutMemStream.cpp b/CPP/7zip/Common/OutMemStream.cpp
new file mode 100755
index 00000000..2953afd8
--- /dev/null
+++ b/CPP/7zip/Common/OutMemStream.cpp
@@ -0,0 +1,137 @@
+// OutMemStream.cpp
+
+#include "StdAfx.h"
+
+#include "OutMemStream.h"
+
+void COutMemStream::Free()
+{
+ Blocks.Free(_memManager);
+ Blocks.LockMode = true;
+}
+
+void COutMemStream::Init()
+{
+ WriteToRealStreamEvent.Reset();
+ _unlockEventWasSent = false;
+ _realStreamMode = false;
+ Free();
+ _curBlockPos = 0;
+ _curBlockIndex = 0;
+}
+
+void COutMemStream::DetachData(CMemLockBlocks &blocks)
+{
+ Blocks.Detach(blocks, _memManager);
+ Free();
+}
+
+
+HRESULT COutMemStream::WriteToRealStream()
+{
+ RINOK(Blocks.WriteToStream(_memManager->GetBlockSize(), OutSeqStream));
+ Blocks.Free(_memManager);
+ return S_OK;
+}
+
+STDMETHODIMP COutMemStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (_realStreamMode)
+ return OutSeqStream->Write(data, size, processedSize);
+ if (processedSize != 0)
+ *processedSize = 0;
+ while(size != 0)
+ {
+ if ((int)_curBlockIndex < Blocks.Blocks.Size())
+ {
+ Byte *p = (Byte *)Blocks.Blocks[(int)_curBlockIndex] + _curBlockPos;
+ size_t curSize = _memManager->GetBlockSize() - _curBlockPos;
+ if (size < curSize)
+ curSize = size;
+ memmove(p, data, curSize);
+ if (processedSize != 0)
+ *processedSize += (UInt32)curSize;
+ data = (const void *)((const Byte *)data + curSize);
+ size -= (UInt32)curSize;
+ _curBlockPos += curSize;
+
+ UInt64 pos64 = GetPos();
+ if (pos64 > Blocks.TotalSize)
+ Blocks.TotalSize = pos64;
+ if (_curBlockPos == _memManager->GetBlockSize())
+ {
+ _curBlockIndex++;
+ _curBlockPos = 0;
+ }
+ continue;
+ }
+ HANDLE events[4] = { StopWritingEvent, WriteToRealStreamEvent, NoLockEvent, _memManager->Semaphore };
+ DWORD waitResult = ::WaitForMultipleObjects((Blocks.LockMode ? 4 : 2), events, FALSE, INFINITE);
+ switch (waitResult)
+ {
+ case (WAIT_OBJECT_0 + 0):
+ return StopWriteResult;
+ case (WAIT_OBJECT_0 + 1):
+ {
+ _realStreamMode = true;
+ RINOK(WriteToRealStream());
+ UInt32 processedSize2;
+ HRESULT res = OutSeqStream->Write(data, size, &processedSize2);
+ if (processedSize != 0)
+ *processedSize += processedSize2;
+ return res;
+ }
+ case (WAIT_OBJECT_0 + 2):
+ {
+ if (!Blocks.SwitchToNoLockMode(_memManager))
+ return E_FAIL;
+ break;
+ }
+ case (WAIT_OBJECT_0 + 3):
+ break;
+ default:
+ return E_FAIL;
+ }
+ Blocks.Blocks.Add(_memManager->AllocateBlock());
+ }
+ return S_OK;
+}
+
+STDMETHODIMP COutMemStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+{
+ if (_realStreamMode)
+ {
+ if (!OutStream)
+ return E_FAIL;
+ return OutStream->Seek(offset, seekOrigin, newPosition);
+ }
+ if (seekOrigin == STREAM_SEEK_CUR)
+ {
+ if (offset != 0)
+ return E_NOTIMPL;
+ }
+ else if (seekOrigin == STREAM_SEEK_SET)
+ {
+ if (offset != 0)
+ return E_NOTIMPL;
+ _curBlockIndex = 0;
+ _curBlockPos = 0;
+ }
+ else
+ return E_NOTIMPL;
+ if (newPosition != 0)
+ *newPosition = GetPos();
+ return S_OK;
+}
+
+STDMETHODIMP COutMemStream::SetSize(Int64 newSize)
+{
+ if (_realStreamMode)
+ {
+ if (!OutStream)
+ return E_FAIL;
+ return OutStream->SetSize(newSize);
+ }
+ Blocks.TotalSize = newSize;
+ return S_OK;
+}
diff --git a/CPP/7zip/Common/OutMemStream.h b/CPP/7zip/Common/OutMemStream.h
new file mode 100755
index 00000000..ea98de17
--- /dev/null
+++ b/CPP/7zip/Common/OutMemStream.h
@@ -0,0 +1,88 @@
+// OutMemStream.h
+
+#ifndef __OUTMEMSTREAM_H
+#define __OUTMEMSTREAM_H
+
+#include "Common/MyCom.h"
+#include "MemBlocks.h"
+
+class COutMemStream:
+ public IOutStream,
+ public CMyUnknownImp
+{
+ CMemBlockManagerMt *_memManager;
+ size_t _curBlockIndex;
+ size_t _curBlockPos;
+ bool _realStreamMode;
+
+ bool _unlockEventWasSent;
+ NWindows::NSynchronization::CAutoResetEvent StopWritingEvent;
+ NWindows::NSynchronization::CAutoResetEvent WriteToRealStreamEvent;
+ NWindows::NSynchronization::CAutoResetEvent NoLockEvent;
+
+ HRESULT StopWriteResult;
+ CMemLockBlocks Blocks;
+
+ UInt64 GetPos() const { return (UInt64)_curBlockIndex * _memManager->GetBlockSize() + _curBlockPos; }
+
+ CMyComPtr<ISequentialOutStream> OutSeqStream;
+ CMyComPtr<IOutStream> OutStream;
+
+public:
+
+ void SetOutStream(IOutStream *outStream)
+ {
+ OutStream = outStream;
+ OutSeqStream = outStream;
+ }
+
+ void SetSeqOutStream(ISequentialOutStream *outStream)
+ {
+ OutStream = NULL;
+ OutSeqStream = outStream;
+ }
+
+ void ReleaseOutStream()
+ {
+ OutStream.Release();
+ OutSeqStream.Release();
+ }
+
+ COutMemStream(CMemBlockManagerMt *memManager): _memManager(memManager) { }
+
+ ~COutMemStream() { Free(); }
+ void Free();
+
+ void Init();
+ HRESULT WriteToRealStream();
+
+ void DetachData(CMemLockBlocks &blocks);
+
+ bool WasUnlockEventSent() const { return _unlockEventWasSent; }
+
+ void SetRealStreamMode()
+ {
+ _unlockEventWasSent = true;
+ WriteToRealStreamEvent.Set();
+ }
+
+ void SetNoLockMode()
+ {
+ _unlockEventWasSent = true;
+ NoLockEvent.Set();
+ }
+
+ void StopWriting(HRESULT res)
+ {
+ StopWriteResult = res;
+ StopWritingEvent.Set();
+ }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+ STDMETHOD(SetSize)(Int64 newSize);
+};
+
+#endif
diff --git a/CPP/7zip/Common/ProgressMt.cpp b/CPP/7zip/Common/ProgressMt.cpp
new file mode 100755
index 00000000..319bd241
--- /dev/null
+++ b/CPP/7zip/Common/ProgressMt.cpp
@@ -0,0 +1,53 @@
+// ProgressMt.h
+
+#include "StdAfx.h"
+
+#include "ProgressMt.h"
+
+void CMtCompressProgressMixer::Init(int numItems, ICompressProgressInfo *progress)
+{
+ NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection);
+ InSizes.Clear();
+ OutSizes.Clear();
+ for (int i = 0; i < numItems; i++)
+ {
+ InSizes.Add(0);
+ OutSizes.Add(0);
+ }
+ TotalInSize = 0;
+ TotalOutSize = 0;
+ _progress = progress;
+}
+
+void CMtCompressProgressMixer::Reinit(int index)
+{
+ NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection);
+ InSizes[index] = 0;
+ OutSizes[index] = 0;
+}
+
+HRESULT CMtCompressProgressMixer::SetRatioInfo(int index, const UInt64 *inSize, const UInt64 *outSize)
+{
+ NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection);
+ if (inSize != 0)
+ {
+ UInt64 diff = *inSize - InSizes[index];
+ InSizes[index] = *inSize;
+ TotalInSize += diff;
+ }
+ if (outSize != 0)
+ {
+ UInt64 diff = *outSize - OutSizes[index];
+ OutSizes[index] = *outSize;
+ TotalOutSize += diff;
+ }
+ if (_progress)
+ return _progress->SetRatioInfo(&TotalInSize, &TotalOutSize);
+ return S_OK;
+}
+
+
+STDMETHODIMP CMtCompressProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
+{
+ return _progress->SetRatioInfo(_index, inSize, outSize);
+}
diff --git a/CPP/7zip/Common/ProgressMt.h b/CPP/7zip/Common/ProgressMt.h
new file mode 100755
index 00000000..c0776944
--- /dev/null
+++ b/CPP/7zip/Common/ProgressMt.h
@@ -0,0 +1,47 @@
+// ProgressMt.h
+
+#ifndef __PROGRESSMT_H
+#define __PROGRESSMT_H
+
+#include "../../Common/MyCom.h"
+
+#include "../ICoder.h"
+#include "../IProgress.h"
+
+#include "Windows/Synchronization.h"
+#include "../../Common/Vector.h"
+
+class CMtCompressProgressMixer
+{
+ CMyComPtr<ICompressProgressInfo> _progress;
+ CRecordVector<UInt64> InSizes;
+ CRecordVector<UInt64> OutSizes;
+ UInt64 TotalInSize;
+ UInt64 TotalOutSize;
+public:
+ NWindows::NSynchronization::CCriticalSection CriticalSection;
+ void Init(int numItems, ICompressProgressInfo *progress);
+ void Reinit(int index);
+ HRESULT SetRatioInfo(int index, const UInt64 *inSize, const UInt64 *outSize);
+};
+
+class CMtCompressProgress:
+ public ICompressProgressInfo,
+ public CMyUnknownImp
+{
+ CMtCompressProgressMixer *_progress;
+ int _index;
+public:
+ void Init(CMtCompressProgressMixer *progress, int index)
+ {
+ _progress = progress;
+ _index = index;
+ }
+ void Reinit() { _progress->Reinit(_index); }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+};
+
+#endif
diff --git a/CPP/7zip/Common/ProgressUtils.cpp b/CPP/7zip/Common/ProgressUtils.cpp
new file mode 100755
index 00000000..40e13877
--- /dev/null
+++ b/CPP/7zip/Common/ProgressUtils.cpp
@@ -0,0 +1,55 @@
+// ProgressUtils.h
+
+#include "StdAfx.h"
+
+#include "ProgressUtils.h"
+
+void CLocalCompressProgressInfo::Init(ICompressProgressInfo *progress,
+ const UInt64 *inStartValue, const UInt64 *outStartValue)
+{
+ _progress = progress;
+ _inStartValueIsAssigned = (inStartValue != NULL);
+ if (_inStartValueIsAssigned)
+ _inStartValue = *inStartValue;
+ _outStartValueIsAssigned = (outStartValue != NULL);
+ if (_outStartValueIsAssigned)
+ _outStartValue = *outStartValue;
+}
+
+STDMETHODIMP CLocalCompressProgressInfo::SetRatioInfo(
+ const UInt64 *inSize, const UInt64 *outSize)
+{
+ UInt64 inSizeNew, outSizeNew;
+ const UInt64 *inSizeNewPointer;
+ const UInt64 *outSizeNewPointer;
+ if (_inStartValueIsAssigned && inSize != NULL)
+ {
+ inSizeNew = _inStartValue + (*inSize);
+ inSizeNewPointer = &inSizeNew;
+ }
+ else
+ inSizeNewPointer = NULL;
+
+ if (_outStartValueIsAssigned && outSize != NULL)
+ {
+ outSizeNew = _outStartValue + (*outSize);
+ outSizeNewPointer = &outSizeNew;
+ }
+ else
+ outSizeNewPointer = NULL;
+ return _progress->SetRatioInfo(inSizeNewPointer, outSizeNewPointer);
+}
+
+///////////////////////////////////
+
+void CLocalProgress::Init(IProgress *progress, bool inSizeIsMain)
+{
+ _progress = progress;
+ _inSizeIsMain = inSizeIsMain;
+}
+
+STDMETHODIMP CLocalProgress::SetRatioInfo(
+ const UInt64 *inSize, const UInt64 *outSize)
+{
+ return _progress->SetCompleted(_inSizeIsMain ? inSize : outSize);
+}
diff --git a/CPP/7zip/Common/ProgressUtils.h b/CPP/7zip/Common/ProgressUtils.h
new file mode 100755
index 00000000..f89839fa
--- /dev/null
+++ b/CPP/7zip/Common/ProgressUtils.h
@@ -0,0 +1,43 @@
+// ProgressUtils.h
+
+#ifndef __PROGRESSUTILS_H
+#define __PROGRESSUTILS_H
+
+#include "../../Common/MyCom.h"
+
+#include "../ICoder.h"
+#include "../IProgress.h"
+
+class CLocalCompressProgressInfo:
+ public ICompressProgressInfo,
+ public CMyUnknownImp
+{
+ CMyComPtr<ICompressProgressInfo> _progress;
+ bool _inStartValueIsAssigned;
+ bool _outStartValueIsAssigned;
+ UInt64 _inStartValue;
+ UInt64 _outStartValue;
+public:
+ void Init(ICompressProgressInfo *progress,
+ const UInt64 *inStartValue, const UInt64 *outStartValue);
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+};
+
+class CLocalProgress:
+ public ICompressProgressInfo,
+ public CMyUnknownImp
+{
+ CMyComPtr<IProgress> _progress;
+ bool _inSizeIsMain;
+public:
+ void Init(IProgress *progress, bool inSizeIsMain);
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+};
+
+#endif
diff --git a/CPP/7zip/Common/StdAfx.h b/CPP/7zip/Common/StdAfx.h
new file mode 100755
index 00000000..27a77b10
--- /dev/null
+++ b/CPP/7zip/Common/StdAfx.h
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../Common/MyWindows.h"
+#include "../../Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/Common/StreamBinder.cpp b/CPP/7zip/Common/StreamBinder.cpp
new file mode 100755
index 00000000..2984c2d9
--- /dev/null
+++ b/CPP/7zip/Common/StreamBinder.cpp
@@ -0,0 +1,162 @@
+// StreamBinder.cpp
+
+#include "StdAfx.h"
+
+#include "StreamBinder.h"
+#include "../../Common/Defs.h"
+#include "../../Common/MyCom.h"
+
+using namespace NWindows;
+using namespace NSynchronization;
+
+class CSequentialInStreamForBinder:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+private:
+ CStreamBinder *m_StreamBinder;
+public:
+ ~CSequentialInStreamForBinder() { m_StreamBinder->CloseRead(); }
+ void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; }
+};
+
+STDMETHODIMP CSequentialInStreamForBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
+ { return m_StreamBinder->Read(data, size, processedSize); }
+
+class CSequentialOutStreamForBinder:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+
+private:
+ CStreamBinder *m_StreamBinder;
+public:
+ ~CSequentialOutStreamForBinder() { m_StreamBinder->CloseWrite(); }
+ void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; }
+};
+
+STDMETHODIMP CSequentialOutStreamForBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)
+ { return m_StreamBinder->Write(data, size, processedSize); }
+
+
+//////////////////////////
+// CStreamBinder
+// (_thereAreBytesToReadEvent && _bufferSize == 0) means that stream is finished.
+
+void CStreamBinder::CreateEvents()
+{
+ _allBytesAreWritenEvent = new CManualResetEvent(true);
+ _thereAreBytesToReadEvent = new CManualResetEvent(false);
+ _readStreamIsClosedEvent = new CManualResetEvent(false);
+}
+
+void CStreamBinder::ReInit()
+{
+ _thereAreBytesToReadEvent->Reset();
+ _readStreamIsClosedEvent->Reset();
+ ProcessedSize = 0;
+}
+
+CStreamBinder::~CStreamBinder()
+{
+ if (_allBytesAreWritenEvent != NULL)
+ delete _allBytesAreWritenEvent;
+ if (_thereAreBytesToReadEvent != NULL)
+ delete _thereAreBytesToReadEvent;
+ if (_readStreamIsClosedEvent != NULL)
+ delete _readStreamIsClosedEvent;
+}
+
+
+
+
+void CStreamBinder::CreateStreams(ISequentialInStream **inStream,
+ ISequentialOutStream **outStream)
+{
+ CSequentialInStreamForBinder *inStreamSpec = new
+ CSequentialInStreamForBinder;
+ CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
+ inStreamSpec->SetBinder(this);
+ *inStream = inStreamLoc.Detach();
+
+ CSequentialOutStreamForBinder *outStreamSpec = new
+ CSequentialOutStreamForBinder;
+ CMyComPtr<ISequentialOutStream> outStreamLoc(outStreamSpec);
+ outStreamSpec->SetBinder(this);
+ *outStream = outStreamLoc.Detach();
+
+ _buffer = NULL;
+ _bufferSize= 0;
+ ProcessedSize = 0;
+}
+
+HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 sizeToRead = size;
+ if (size > 0)
+ {
+ if(!_thereAreBytesToReadEvent->Lock())
+ return E_FAIL;
+ sizeToRead = MyMin(_bufferSize, size);
+ if (_bufferSize > 0)
+ {
+ MoveMemory(data, _buffer, sizeToRead);
+ _buffer = ((const Byte *)_buffer) + sizeToRead;
+ _bufferSize -= sizeToRead;
+ if (_bufferSize == 0)
+ {
+ _thereAreBytesToReadEvent->Reset();
+ _allBytesAreWritenEvent->Set();
+ }
+ }
+ }
+ if (processedSize != NULL)
+ *processedSize = sizeToRead;
+ ProcessedSize += sizeToRead;
+ return S_OK;
+}
+
+void CStreamBinder::CloseRead()
+{
+ _readStreamIsClosedEvent->Set();
+}
+
+HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (size > 0)
+ {
+ _buffer = data;
+ _bufferSize = size;
+ _allBytesAreWritenEvent->Reset();
+ _thereAreBytesToReadEvent->Set();
+
+ HANDLE events[2];
+ events[0] = *_allBytesAreWritenEvent;
+ events[1] = *_readStreamIsClosedEvent;
+ DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
+ if (waitResult != WAIT_OBJECT_0 + 0)
+ {
+ // ReadingWasClosed = true;
+ return E_FAIL;
+ }
+ // if(!_allBytesAreWritenEvent.Lock())
+ // return E_FAIL;
+ }
+ if (processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
+
+void CStreamBinder::CloseWrite()
+{
+ // _bufferSize must be = 0
+ _thereAreBytesToReadEvent->Set();
+}
diff --git a/CPP/7zip/Common/StreamBinder.h b/CPP/7zip/Common/StreamBinder.h
new file mode 100755
index 00000000..a66c3acb
--- /dev/null
+++ b/CPP/7zip/Common/StreamBinder.h
@@ -0,0 +1,37 @@
+// StreamBinder.h
+
+#ifndef __STREAMBINDER_H
+#define __STREAMBINDER_H
+
+#include "../IStream.h"
+#include "../../Windows/Synchronization.h"
+
+class CStreamBinder
+{
+ NWindows::NSynchronization::CManualResetEvent *_allBytesAreWritenEvent;
+ NWindows::NSynchronization::CManualResetEvent *_thereAreBytesToReadEvent;
+ NWindows::NSynchronization::CManualResetEvent *_readStreamIsClosedEvent;
+ UInt32 _bufferSize;
+ const void *_buffer;
+public:
+ // bool ReadingWasClosed;
+ UInt64 ProcessedSize;
+ CStreamBinder():
+ _allBytesAreWritenEvent(NULL),
+ _thereAreBytesToReadEvent(NULL),
+ _readStreamIsClosedEvent(NULL)
+ {}
+ ~CStreamBinder();
+ void CreateEvents();
+
+ void CreateStreams(ISequentialInStream **inStream,
+ ISequentialOutStream **outStream);
+ HRESULT Read(void *data, UInt32 size, UInt32 *processedSize);
+ void CloseRead();
+
+ HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize);
+ void CloseWrite();
+ void ReInit();
+};
+
+#endif
diff --git a/CPP/7zip/Common/StreamObjects.cpp b/CPP/7zip/Common/StreamObjects.cpp
new file mode 100755
index 00000000..32f8f306
--- /dev/null
+++ b/CPP/7zip/Common/StreamObjects.cpp
@@ -0,0 +1,68 @@
+// StreamObjects.cpp
+
+#include "StdAfx.h"
+
+#include "StreamObjects.h"
+#include "../../Common/Defs.h"
+
+
+STDMETHODIMP CSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 numBytesToRead = (UInt32)(MyMin(_pos + size, _size) - _pos);
+ memmove(data, _dataPointer + _pos, numBytesToRead);
+ _pos += numBytesToRead;
+ if(processedSize != NULL)
+ *processedSize = numBytesToRead;
+ return S_OK;
+}
+
+
+void CWriteBuffer::Write(const void *data, size_t size)
+{
+ size_t newCapacity = _size + size;
+ _buffer.EnsureCapacity(newCapacity);
+ memmove(_buffer + _size, data, size);
+ _size += size;
+}
+
+STDMETHODIMP CSequentialOutStreamImp::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ _writeBuffer.Write(data, size);
+ if(processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
+
+STDMETHODIMP CSequentialOutStreamImp2::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 newSize = size;
+ if (_pos + size > _size)
+ newSize = (UInt32)(_size - _pos);
+ memmove(_buffer + _pos, data, newSize);
+ if(processedSize != NULL)
+ *processedSize = newSize;
+ _pos += newSize;
+ if (newSize != size)
+ return E_FAIL;
+ return S_OK;
+}
+
+STDMETHODIMP CSequentialInStreamSizeCount::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize;
+ HRESULT result = _stream->Read(data, size, &realProcessedSize);
+ _size += realProcessedSize;
+ if (processedSize != 0)
+ *processedSize = realProcessedSize;
+ return result;
+}
+
+STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 realProcessedSize;
+ HRESULT result = _stream->Write(data, size, &realProcessedSize);
+ _size += realProcessedSize;
+ if (processedSize != 0)
+ *processedSize = realProcessedSize;
+ return result;
+}
diff --git a/CPP/7zip/Common/StreamObjects.h b/CPP/7zip/Common/StreamObjects.h
new file mode 100755
index 00000000..6f670f59
--- /dev/null
+++ b/CPP/7zip/Common/StreamObjects.h
@@ -0,0 +1,117 @@
+// StreamObjects.h
+
+#ifndef __STREAMOBJECTS_H
+#define __STREAMOBJECTS_H
+
+#include "../../Common/DynamicBuffer.h"
+#include "../../Common/MyCom.h"
+#include "../IStream.h"
+
+class CSequentialInStreamImp:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ const Byte *_dataPointer;
+ size_t _size;
+ size_t _pos;
+
+public:
+ void Init(const Byte *dataPointer, size_t size)
+ {
+ _dataPointer = dataPointer;
+ _size = size;
+ _pos = 0;
+ }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+
+class CWriteBuffer
+{
+ CByteDynamicBuffer _buffer;
+ size_t _size;
+public:
+ CWriteBuffer(): _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; }
+};
+
+class CSequentialOutStreamImp:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ CWriteBuffer _writeBuffer;
+public:
+ 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);
+};
+
+class CSequentialOutStreamImp2:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ Byte *_buffer;
+ size_t _size;
+ size_t _pos;
+public:
+
+ void Init(Byte *buffer, size_t size)
+ {
+ _buffer = buffer;
+ _pos = 0;
+ _size = size;
+ }
+
+ size_t GetPos() const { return _pos; }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+class CSequentialInStreamSizeCount:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ CMyComPtr<ISequentialInStream> _stream;
+ UInt64 _size;
+public:
+ void Init(ISequentialInStream *stream)
+ {
+ _stream = stream;
+ _size = 0;
+ }
+ UInt64 GetSize() const { return _size; }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+class CSequentialOutStreamSizeCount:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ CMyComPtr<ISequentialOutStream> _stream;
+ UInt64 _size;
+public:
+ void SetStream(ISequentialOutStream *stream) { _stream = stream; }
+ void Init() { _size = 0; }
+ UInt64 GetSize() const { return _size; }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+#endif
diff --git a/CPP/7zip/Common/StreamUtils.cpp b/CPP/7zip/Common/StreamUtils.cpp
new file mode 100755
index 00000000..a5d9ac0e
--- /dev/null
+++ b/CPP/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/CPP/7zip/Common/StreamUtils.h b/CPP/7zip/Common/StreamUtils.h
new file mode 100755
index 00000000..59f88733
--- /dev/null
+++ b/CPP/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/CPP/7zip/Compress/Arj/ArjDecoder1.cpp b/CPP/7zip/Compress/Arj/ArjDecoder1.cpp
new file mode 100755
index 00000000..7f720807
--- /dev/null
+++ b/CPP/7zip/Compress/Arj/ArjDecoder1.cpp
@@ -0,0 +1,319 @@
+// Arj/Decoder.cpp
+
+#include "StdAfx.h"
+
+#include "ArjDecoder1.h"
+
+#include "Windows/Defs.h"
+
+namespace NCompress{
+namespace NArj {
+namespace NDecoder1 {
+
+static const UInt32 kHistorySize = 26624;
+static const UInt32 kMatchMaxLen = 256;
+static const UInt32 kMatchMinLen = 3;
+
+static const UInt32 kNC = 255 + kMatchMaxLen + 2 - kMatchMinLen;
+
+void CCoder::MakeTable(int nchar, Byte *bitlen, int tablebits,
+ UInt32 *table, int tablesize)
+{
+ UInt32 count[17], weight[17], start[18], *p;
+ UInt32 i, k, len, ch, jutbits, avail, nextcode, mask;
+
+ for (i = 1; i <= 16; i++)
+ count[i] = 0;
+ for (i = 0; (int)i < nchar; i++)
+ count[bitlen[i]]++;
+
+ start[1] = 0;
+ for (i = 1; i <= 16; i++)
+ start[i + 1] = start[i] + (count[i] << (16 - i));
+ if (start[17] != (UInt32) (1 << 16))
+ throw "Data error";
+
+ jutbits = 16 - tablebits;
+ for (i = 1; (int)i <= tablebits; i++)
+ {
+ start[i] >>= jutbits;
+ weight[i] = 1 << (tablebits - i);
+ }
+ while (i <= 16)
+ {
+ weight[i] = 1 << (16 - i);
+ i++;
+ }
+
+ i = start[tablebits + 1] >> jutbits;
+ if (i != (UInt32) (1 << 16))
+ {
+ k = 1 << tablebits;
+ while (i != k)
+ table[i++] = 0;
+ }
+
+ avail = nchar;
+ mask = 1 << (15 - tablebits);
+ for (ch = 0; (int)ch < nchar; ch++)
+ {
+ if ((len = bitlen[ch]) == 0)
+ continue;
+ k = start[len];
+ nextcode = k + weight[len];
+ if ((int)len <= tablebits)
+ {
+ if (nextcode > (UInt32)tablesize)
+ throw "Data error";
+ for (i = start[len]; i < nextcode; i++)
+ table[i] = ch;
+ }
+ else
+ {
+ p = &table[k >> jutbits];
+ i = len - tablebits;
+ while (i != 0)
+ {
+ if (*p == 0)
+ {
+ right[avail] = left[avail] = 0;
+ *p = avail++;
+ }
+ if (k & mask)
+ p = &right[*p];
+ else
+ p = &left[*p];
+ k <<= 1;
+ i--;
+ }
+ *p = ch;
+ }
+ start[len] = nextcode;
+ }
+}
+
+void CCoder::read_pt_len(int nn, int nbit, int i_special)
+{
+ UInt32 n = m_InBitStream.ReadBits(nbit);
+ if (n == 0)
+ {
+ UInt32 c = m_InBitStream.ReadBits(nbit);
+ int i;
+ for (i = 0; i < nn; i++)
+ pt_len[i] = 0;
+ for (i = 0; i < 256; i++)
+ pt_table[i] = c;
+ }
+ else
+ {
+ UInt32 i = 0;
+ while (i < n)
+ {
+ UInt32 bitBuf = m_InBitStream.GetValue(16);
+ int c = bitBuf >> 13;
+ if (c == 7)
+ {
+ UInt32 mask = 1 << (12);
+ while (mask & bitBuf)
+ {
+ mask >>= 1;
+ c++;
+ }
+ }
+ m_InBitStream.MovePos((c < 7) ? 3 : (int)(c - 3));
+ pt_len[i++] = (Byte)c;
+ if (i == (UInt32)i_special)
+ {
+ c = m_InBitStream.ReadBits(2);
+ while (--c >= 0)
+ pt_len[i++] = 0;
+ }
+ }
+ while (i < (UInt32)nn)
+ pt_len[i++] = 0;
+ MakeTable(nn, pt_len, 8, pt_table, PTABLESIZE);
+ }
+}
+
+void CCoder::read_c_len()
+{
+ int i, c, n;
+ UInt32 mask;
+
+ n = m_InBitStream.ReadBits(CBIT);
+ if (n == 0)
+ {
+ c = m_InBitStream.ReadBits(CBIT);
+ for (i = 0; i < NC; i++)
+ c_len[i] = 0;
+ for (i = 0; i < CTABLESIZE; i++)
+ c_table[i] = c;
+ }
+ else
+ {
+ i = 0;
+ while (i < n)
+ {
+ UInt32 bitBuf = m_InBitStream.GetValue(16);
+ c = pt_table[bitBuf >> (8)];
+ if (c >= NT)
+ {
+ mask = 1 << (7);
+ do
+ {
+ if (bitBuf & mask)
+ c = right[c];
+ else
+ c = left[c];
+ mask >>= 1;
+ } while (c >= NT);
+ }
+ m_InBitStream.MovePos((int)(pt_len[c]));
+ if (c <= 2)
+ {
+ if (c == 0)
+ c = 1;
+ else if (c == 1)
+ c = m_InBitStream.ReadBits(4) + 3;
+ else
+ c = m_InBitStream.ReadBits(CBIT) + 20;
+ while (--c >= 0)
+ c_len[i++] = 0;
+ }
+ else
+ c_len[i++] = (Byte)(c - 2);
+ }
+ while (i < NC)
+ c_len[i++] = 0;
+ MakeTable(NC, c_len, 12, c_table, CTABLESIZE);
+ }
+}
+
+UInt32 CCoder::decode_c()
+{
+ UInt32 j, mask;
+ UInt32 bitbuf = m_InBitStream.GetValue(16);
+ j = c_table[bitbuf >> 4];
+ if (j >= NC)
+ {
+ mask = 1 << (3);
+ do
+ {
+ if (bitbuf & mask)
+ j = right[j];
+ else
+ j = left[j];
+ mask >>= 1;
+ } while (j >= NC);
+ }
+ m_InBitStream.MovePos((int)(c_len[j]));
+ return j;
+}
+
+UInt32 CCoder::decode_p()
+{
+ UInt32 j, mask;
+ UInt32 bitbuf = m_InBitStream.GetValue(16);
+ j = pt_table[bitbuf >> (8)];
+ if (j >= NP)
+ {
+ mask = 1 << (7);
+ do
+ {
+ if (bitbuf & mask)
+ j = right[j];
+ else
+ j = left[j];
+ mask >>= 1;
+ } while (j >= NP);
+ }
+ m_InBitStream.MovePos((int)(pt_len[j]));
+ if (j != 0)
+ {
+ j--;
+ j = (1 << j) + m_InBitStream.ReadBits((int)j);
+ }
+ return j;
+}
+
+
+STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ if (outSize == NULL)
+ return E_INVALIDARG;
+
+ if (!m_OutWindowStream.Create(kHistorySize))
+ return E_OUTOFMEMORY;
+ if (!m_InBitStream.Create(1 << 20))
+ return E_OUTOFMEMORY;
+
+ int size1 = sizeof(c_table) / sizeof(c_table[0]);
+ for (int i = 0; i < size1; i++)
+ {
+ if (i % 100 == 0)
+ c_table[i] = 0;
+
+ c_table[i] = 0;
+ }
+
+
+ UInt64 pos = 0;
+ m_OutWindowStream.SetStream(outStream);
+ m_OutWindowStream.Init(false);
+ m_InBitStream.SetStream(inStream);
+ m_InBitStream.Init();
+
+ CCoderReleaser coderReleaser(this);
+
+ UInt32 blockSize = 0;
+
+ while(pos < *outSize)
+ {
+ if (blockSize == 0)
+ {
+ if (progress != NULL)
+ {
+ UInt64 packSize = m_InBitStream.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&packSize, &pos));
+ }
+ blockSize = m_InBitStream.ReadBits(16);
+ read_pt_len(NT, TBIT, 3);
+ read_c_len();
+ read_pt_len(NP, PBIT, -1);
+ }
+ blockSize--;
+
+ UInt32 number = decode_c();
+ if (number < 256)
+ {
+ m_OutWindowStream.PutByte((Byte)number);
+ pos++;
+ continue;
+ }
+ else
+ {
+ UInt32 len = number - 256 + kMatchMinLen;
+ UInt32 distance = decode_p();
+ if (distance >= pos)
+ throw "data error";
+ m_OutWindowStream.CopyBlock(distance, len);
+ pos += len;
+ }
+ }
+ coderReleaser.NeedFlush = false;
+ return m_OutWindowStream.Flush();
+}
+
+STDMETHODIMP CCoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ try { return CodeReal(inStream, outStream, inSize, outSize, progress);}
+ catch(const CInBufferException &e) { return e.ErrorCode; }
+ catch(const CLZOutWindowException &e) { return e.ErrorCode; }
+ catch(...) { return S_FALSE; }
+}
+
+}}}
diff --git a/CPP/7zip/Compress/Arj/ArjDecoder1.h b/CPP/7zip/Compress/Arj/ArjDecoder1.h
new file mode 100755
index 00000000..434a0a41
--- /dev/null
+++ b/CPP/7zip/Compress/Arj/ArjDecoder1.h
@@ -0,0 +1,105 @@
+// Arj/Decoder1.h
+
+#ifndef __COMPRESS_ARJ_DECODER1_H
+#define __COMPRESS_ARJ_DECODER1_H
+
+#include "../../../Common/MyCom.h"
+#include "../../ICoder.h"
+#include "../../Common/MSBFDecoder.h"
+#include "../../Common/InBuffer.h"
+#include "../LZ/LZOutWindow.h"
+
+/*
+// {23170F69-40C1-278B-0404-010000000000}
+DEFINE_GUID(CLSID_CCompressArjDecoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00);
+*/
+
+namespace NCompress {
+namespace NArj {
+namespace NDecoder1 {
+
+#define CODE_BIT 16
+
+#define THRESHOLD 3
+#define DDICSIZ 26624
+#define MAXDICBIT 16
+#define MATCHBIT 8
+#define MAXMATCH 256
+#define NC (0xFF + MAXMATCH + 2 - THRESHOLD)
+#define NP (MAXDICBIT + 1)
+#define CBIT 9
+#define NT (CODE_BIT + 3)
+#define PBIT 5
+#define TBIT 5
+
+#if NT > NP
+#define NPT NT
+#else
+#define NPT NP
+#endif
+
+#define CTABLESIZE 4096
+#define PTABLESIZE 256
+
+
+class CCoder :
+ public ICompressCoder,
+ public CMyUnknownImp
+{
+ CLZOutWindow m_OutWindowStream;
+ NStream::NMSBF::CDecoder<CInBuffer> m_InBitStream;
+
+ UInt32 left[2 * NC - 1];
+ UInt32 right[2 * NC - 1];
+ Byte c_len[NC];
+ Byte pt_len[NPT];
+
+ UInt32 c_table[CTABLESIZE];
+ UInt32 pt_table[PTABLESIZE];
+
+ void ReleaseStreams()
+ {
+ m_OutWindowStream.ReleaseStream();
+ m_InBitStream.ReleaseStream();
+ }
+
+ class CCoderReleaser
+ {
+ CCoder *m_Coder;
+ public:
+ bool NeedFlush;
+ CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {}
+ ~CCoderReleaser()
+ {
+ if (NeedFlush)
+ m_Coder->m_OutWindowStream.Flush();
+ m_Coder->ReleaseStreams();
+ }
+ };
+ friend class CCoderReleaser;
+
+ void MakeTable(int nchar, Byte *bitlen, int tablebits, UInt32 *table, int tablesize);
+
+ void read_c_len();
+ void read_pt_len(int nn, int nbit, int i_special);
+ UInt32 decode_c();
+ UInt32 decode_p();
+
+public:
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(CodeReal)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+};
+
+}}}
+
+#endif
diff --git a/CPP/7zip/Compress/Arj/ArjDecoder2.cpp b/CPP/7zip/Compress/Arj/ArjDecoder2.cpp
new file mode 100755
index 00000000..a734d1b4
--- /dev/null
+++ b/CPP/7zip/Compress/Arj/ArjDecoder2.cpp
@@ -0,0 +1,93 @@
+// Arj/Decoder2.cpp
+
+#include "StdAfx.h"
+
+#include "ArjDecoder2.h"
+
+namespace NCompress{
+namespace NArj {
+namespace NDecoder2 {
+
+static const UInt32 kHistorySize = 26624;
+static const UInt32 kMatchMaxLen = 256;
+static const UInt32 kMatchMinLen = 3;
+
+STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize,
+ ICompressProgressInfo * /* progress */)
+{
+ if (outSize == NULL)
+ return E_INVALIDARG;
+
+ if (!m_OutWindowStream.Create(kHistorySize))
+ return E_OUTOFMEMORY;
+ if (!m_InBitStream.Create(1 << 20))
+ return E_OUTOFMEMORY;
+
+ UInt64 pos = 0;
+ m_OutWindowStream.SetStream(outStream);
+ m_OutWindowStream.Init(false);
+ m_InBitStream.SetStream(inStream);
+ m_InBitStream.Init();
+ CCoderReleaser coderReleaser(this);
+
+ while(pos < *outSize)
+ {
+ const UInt32 kStartWidth = 0;
+ const UInt32 kStopWidth = 7;
+ UInt32 power = 1 << kStartWidth;
+ UInt32 width;
+ UInt32 len = 0;
+ for (width = kStartWidth; width < kStopWidth; width++)
+ {
+ if (m_InBitStream.ReadBits(1) == 0)
+ break;
+ len += power;
+ power <<= 1;
+ }
+ if (width != 0)
+ len += m_InBitStream.ReadBits(width);
+ if (len == 0)
+ {
+ m_OutWindowStream.PutByte((Byte)m_InBitStream.ReadBits(8));
+ pos++;
+ continue;
+ }
+ else
+ {
+ len = len - 1 + kMatchMinLen;
+ const UInt32 kStartWidth = 9;
+ const UInt32 kStopWidth = 13;
+ UInt32 power = 1 << kStartWidth;
+ UInt32 width;
+ UInt32 distance = 0;
+ for (width = kStartWidth; width < kStopWidth; width++)
+ {
+ if (m_InBitStream.ReadBits(1) == 0)
+ break;
+ distance += power;
+ power <<= 1;
+ }
+ if (width != 0)
+ distance += m_InBitStream.ReadBits(width);
+ if (distance >= pos)
+ throw "data error";
+ m_OutWindowStream.CopyBlock(distance, len);
+ pos += len;
+ }
+ }
+ coderReleaser.NeedFlush = false;
+ return m_OutWindowStream.Flush();
+}
+
+STDMETHODIMP CCoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ try { return CodeReal(inStream, outStream, inSize, outSize, progress);}
+ catch(const CInBufferException &e) { return e.ErrorCode; }
+ catch(const CLZOutWindowException &e) { return e.ErrorCode; }
+ catch(...) { return S_FALSE; }
+}
+
+}}}
diff --git a/CPP/7zip/Compress/Arj/ArjDecoder2.h b/CPP/7zip/Compress/Arj/ArjDecoder2.h
new file mode 100755
index 00000000..7a33f6bd
--- /dev/null
+++ b/CPP/7zip/Compress/Arj/ArjDecoder2.h
@@ -0,0 +1,65 @@
+// Arj/Decoder2.h
+
+#ifndef __COMPRESS_ARJ_DECODER2_H
+#define __COMPRESS_ARJ_DECODER2_H
+
+#include "../../../Common/MyCom.h"
+#include "../../ICoder.h"
+#include "../../Common/MSBFDecoder.h"
+#include "../../Common/InBuffer.h"
+#include "../LZ/LZOutWindow.h"
+
+/*
+// {23170F69-40C1-278B-0404-020000000000}
+DEFINE_GUID(CLSID_CCompressArj2Decoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
+*/
+
+namespace NCompress {
+namespace NArj {
+namespace NDecoder2 {
+
+class CCoder :
+ public ICompressCoder,
+ public CMyUnknownImp
+{
+ CLZOutWindow m_OutWindowStream;
+ NStream::NMSBF::CDecoder<CInBuffer> m_InBitStream;
+
+ void ReleaseStreams()
+ {
+ m_OutWindowStream.ReleaseStream();
+ m_InBitStream.ReleaseStream();
+ }
+
+ class CCoderReleaser
+ {
+ CCoder *m_Coder;
+ public:
+ bool NeedFlush;
+ CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {}
+ ~CCoderReleaser()
+ {
+ if (NeedFlush)
+ m_Coder->m_OutWindowStream.Flush();
+ m_Coder->ReleaseStreams();
+ }
+ };
+ friend class CCoderReleaser;
+
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(CodeReal)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+};
+
+}}}
+
+#endif
diff --git a/CPP/7zip/Compress/Arj/StdAfx.h b/CPP/7zip/Compress/Arj/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Compress/Arj/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Compress/BWT/BlockSort.cpp b/CPP/7zip/Compress/BWT/BlockSort.cpp
new file mode 100755
index 00000000..9e28c85f
--- /dev/null
+++ b/CPP/7zip/Compress/BWT/BlockSort.cpp
@@ -0,0 +1,487 @@
+// BlockSort.cpp
+
+#include "StdAfx.h"
+
+#include "BlockSort.h"
+
+extern "C"
+{
+ #include "../../../../C/Sort.h"
+}
+
+// use BLOCK_SORT_EXTERNAL_FLAGS if blockSize > 1M
+// #define BLOCK_SORT_USE_HEAP_SORT
+
+#if _MSC_VER >= 1300
+ #define NO_INLINE __declspec(noinline) __fastcall
+#else
+#ifdef _MSC_VER
+ #define NO_INLINE __fastcall
+#else
+ #define NO_INLINE
+#endif
+#endif
+
+// Don't change it !!
+static const int kNumHashBytes = 2;
+static const UInt32 kNumHashValues = 1 << (kNumHashBytes * 8);
+
+static const int kNumRefBitsMax = 12; // must be < (kNumHashBytes * 8) = 16
+static const UInt32 kNumRefsMax = (1 << kNumRefBitsMax);
+
+#define BS_TEMP_SIZE kNumHashValues
+
+#ifdef BLOCK_SORT_EXTERNAL_FLAGS
+
+static const int kNumFlagsBits = 5; // 32 Flags in UInt32 word
+static const UInt32 kNumFlagsInWord = (1 << kNumFlagsBits);
+static const UInt32 kFlagsMask = kNumFlagsInWord - 1;
+static const UInt32 kAllFlags = 0xFFFFFFFF;
+
+#else
+
+const int kNumBitsMax = 20;
+const UInt32 kIndexMask = (1 << kNumBitsMax) - 1;
+const int kNumExtraBits = 32 - kNumBitsMax;
+const int kNumExtra0Bits = kNumExtraBits - 2;
+const UInt32 kNumExtra0Mask = (1 << kNumExtra0Bits) - 1;
+
+#define SetFinishedGroupSize(p, size) \
+ { *(p) |= ((((size) - 1) & kNumExtra0Mask) << kNumBitsMax); \
+ if ((size) > (1 << kNumExtra0Bits)) { \
+ *(p) |= 0x40000000; *((p) + 1) |= ((((size) - 1)>> kNumExtra0Bits) << kNumBitsMax); } } \
+
+inline void SetGroupSize(UInt32 *p, UInt32 size)
+{
+ if (--size == 0)
+ return;
+ *p |= 0x80000000 | ((size & kNumExtra0Mask) << kNumBitsMax);
+ if (size >= (1 << kNumExtra0Bits))
+ {
+ *p |= 0x40000000;
+ p[1] |= ((size >> kNumExtra0Bits) << kNumBitsMax);
+ }
+}
+
+#endif
+
+// SortGroup - is recursive Range-Sort function with HeapSort optimization for small blocks
+// "range" is not real range. It's only for optimization.
+// returns: 1 - if there are groups, 0 - no more groups
+
+UInt32 NO_INLINE SortGroup(UInt32 BlockSize, UInt32 NumSortedBytes, UInt32 groupOffset, UInt32 groupSize, int NumRefBits, UInt32 *Indices
+ #ifndef BLOCK_SORT_USE_HEAP_SORT
+ , UInt32 left, UInt32 range
+ #endif
+ )
+{
+ UInt32 *ind2 = Indices + groupOffset;
+ if (groupSize <= 1)
+ {
+ /*
+ #ifndef BLOCK_SORT_EXTERNAL_FLAGS
+ SetFinishedGroupSize(ind2, 1);
+ #endif
+ */
+ return 0;
+ }
+ UInt32 *Groups = Indices + BlockSize + BS_TEMP_SIZE;
+ if (groupSize <= ((UInt32)1 << NumRefBits)
+ #ifndef BLOCK_SORT_USE_HEAP_SORT
+ && groupSize <= range
+ #endif
+ )
+ {
+ UInt32 *temp = Indices + BlockSize;
+ UInt32 j;
+ {
+ UInt32 gPrev;
+ UInt32 gRes = 0;
+ {
+ UInt32 sp = ind2[0] + NumSortedBytes;
+ if (sp >= BlockSize) sp -= BlockSize;
+ gPrev = Groups[sp];
+ temp[0] = (gPrev << NumRefBits);
+ }
+
+ for (j = 1; j < groupSize; j++)
+ {
+ UInt32 sp = ind2[j] + NumSortedBytes;
+ if (sp >= BlockSize) sp -= BlockSize;
+ UInt32 g = Groups[sp];
+ temp[j] = (g << NumRefBits) | j;
+ gRes |= (gPrev ^ g);
+ }
+ if (gRes == 0)
+ {
+ #ifndef BLOCK_SORT_EXTERNAL_FLAGS
+ SetGroupSize(ind2, groupSize);
+ #endif
+ return 1;
+ }
+ }
+
+ HeapSort(temp, groupSize);
+ const UInt32 mask = ((1 << NumRefBits) - 1);
+ UInt32 thereAreGroups = 0;
+
+ UInt32 group = groupOffset;
+ UInt32 cg = (temp[0] >> NumRefBits);
+ temp[0] = ind2[temp[0] & mask];
+
+ #ifdef BLOCK_SORT_EXTERNAL_FLAGS
+ UInt32 *Flags = Groups + BlockSize;
+ #else
+ UInt32 prevGroupStart = 0;
+ #endif
+
+ for (j = 1; j < groupSize; j++)
+ {
+ UInt32 val = temp[j];
+ UInt32 cgCur = (val >> NumRefBits);
+
+ if (cgCur != cg)
+ {
+ cg = cgCur;
+ group = groupOffset + j;
+
+ #ifdef BLOCK_SORT_EXTERNAL_FLAGS
+ UInt32 t = group - 1;
+ Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask));
+ #else
+ SetGroupSize(temp + prevGroupStart, j - prevGroupStart);
+ prevGroupStart = j;
+ #endif
+ }
+ else
+ thereAreGroups = 1;
+ UInt32 ind = ind2[val & mask];
+ temp[j] = ind;
+ Groups[ind] = group;
+ }
+
+ #ifndef BLOCK_SORT_EXTERNAL_FLAGS
+ SetGroupSize(temp + prevGroupStart, j - prevGroupStart);
+ #endif
+
+ for (j = 0; j < groupSize; j++)
+ ind2[j] = temp[j];
+ return thereAreGroups;
+ }
+
+ // Check that all strings are in one group (cannot sort)
+ {
+ UInt32 sp = ind2[0] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize;
+ UInt32 group = Groups[sp];
+ UInt32 j;
+ for (j = 1; j < groupSize; j++)
+ {
+ sp = ind2[j] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize;
+ if (Groups[sp] != group)
+ break;
+ }
+ if (j == groupSize)
+ {
+ #ifndef BLOCK_SORT_EXTERNAL_FLAGS
+ SetGroupSize(ind2, groupSize);
+ #endif
+ return 1;
+ }
+ }
+
+ #ifndef BLOCK_SORT_USE_HEAP_SORT
+ //--------------------------------------
+ // Range Sort
+ UInt32 i;
+ UInt32 mid;
+ for (;;)
+ {
+ if (range <= 1)
+ {
+ #ifndef BLOCK_SORT_EXTERNAL_FLAGS
+ SetGroupSize(ind2, groupSize);
+ #endif
+ return 1;
+ }
+ mid = left + ((range + 1) >> 1);
+ UInt32 j = groupSize;
+ i = 0;
+ do
+ {
+ UInt32 sp = ind2[i] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize;
+ if (Groups[sp] >= mid)
+ {
+ for (j--; j > i; j--)
+ {
+ sp = ind2[j] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize;
+ if (Groups[sp] < mid)
+ {
+ UInt32 temp = ind2[i]; ind2[i] = ind2[j]; ind2[j] = temp;
+ break;
+ }
+ }
+ if (i >= j)
+ break;
+ }
+ }
+ while(++i < j);
+ if (i == 0)
+ {
+ range = range - (mid - left);
+ left = mid;
+ }
+ else if (i == groupSize)
+ range = (mid - left);
+ else
+ break;
+ }
+
+ #ifdef BLOCK_SORT_EXTERNAL_FLAGS
+ {
+ UInt32 t = (groupOffset + i - 1);
+ UInt32 *Flags = Groups + BlockSize;
+ Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask));
+ }
+ #endif
+
+ for (UInt32 j = i; j < groupSize; j++)
+ Groups[ind2[j]] = groupOffset + i;
+
+ UInt32 res = SortGroup(BlockSize, NumSortedBytes, groupOffset, i, NumRefBits, Indices, left, mid - left);
+ return res | SortGroup(BlockSize, NumSortedBytes, groupOffset + i, groupSize - i, NumRefBits, Indices, mid, range - (mid - left));
+
+ #else
+
+ //--------------------------------------
+ // Heap Sort
+
+ {
+ UInt32 j;
+ for (j = 0; j < groupSize; j++)
+ {
+ UInt32 sp = ind2[j] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize;
+ ind2[j] = sp;
+ }
+
+ HeapSortRef(ind2, Groups, groupSize);
+
+ // Write Flags
+ UInt32 sp = ind2[0];
+ UInt32 group = Groups[sp];
+
+ #ifdef BLOCK_SORT_EXTERNAL_FLAGS
+ UInt32 *Flags = Groups + BlockSize;
+ #else
+ UInt32 prevGroupStart = 0;
+ #endif
+
+ for (j = 1; j < groupSize; j++)
+ {
+ sp = ind2[j];
+ if (Groups[sp] != group)
+ {
+ group = Groups[sp];
+ #ifdef BLOCK_SORT_EXTERNAL_FLAGS
+ UInt32 t = groupOffset + j - 1;
+ Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask));
+ #else
+ SetGroupSize(ind2 + prevGroupStart, j - prevGroupStart);
+ prevGroupStart = j;
+ #endif
+ }
+ }
+
+ #ifndef BLOCK_SORT_EXTERNAL_FLAGS
+ SetGroupSize(ind2 + prevGroupStart, j - prevGroupStart);
+ #endif
+
+ // Write new Groups values and Check that there are groups
+ UInt32 thereAreGroups = 0;
+ for (j = 0; j < groupSize; j++)
+ {
+ UInt32 group = groupOffset + j;
+ #ifndef BLOCK_SORT_EXTERNAL_FLAGS
+ UInt32 subGroupSize = ((ind2[j] & ~0xC0000000) >> kNumBitsMax);
+ if ((ind2[j] & 0x40000000) != 0)
+ subGroupSize += ((ind2[j + 1] >> kNumBitsMax) << kNumExtra0Bits);
+ subGroupSize++;
+ for (;;)
+ {
+ UInt32 original = ind2[j];
+ UInt32 sp = original & kIndexMask;
+ if (sp < NumSortedBytes) sp += BlockSize; sp -= NumSortedBytes;
+ ind2[j] = sp | (original & ~kIndexMask);
+ Groups[sp] = group;
+ if (--subGroupSize == 0)
+ break;
+ j++;
+ thereAreGroups = 1;
+ }
+ #else
+ for (;;)
+ {
+ UInt32 sp = ind2[j]; if (sp < NumSortedBytes) sp += BlockSize; sp -= NumSortedBytes;
+ ind2[j] = sp;
+ Groups[sp] = group;
+ if ((Flags[(groupOffset + j) >> kNumFlagsBits] & (1 << ((groupOffset + j) & kFlagsMask))) == 0)
+ break;
+ j++;
+ thereAreGroups = 1;
+ }
+ #endif
+ }
+ return thereAreGroups;
+ }
+ #endif
+}
+
+// conditions: blockSize > 0
+UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
+{
+ UInt32 *counters = Indices + blockSize;
+ UInt32 i;
+
+ // Radix-Sort for 2 bytes
+ for (i = 0; i < kNumHashValues; i++)
+ counters[i] = 0;
+ for (i = 0; i < blockSize - 1; i++)
+ counters[((UInt32)data[i] << 8) | data[i + 1]]++;
+ counters[((UInt32)data[i] << 8) | data[0]]++;
+
+ UInt32 *Groups = counters + BS_TEMP_SIZE;
+ #ifdef BLOCK_SORT_EXTERNAL_FLAGS
+ UInt32 *Flags = Groups + blockSize;
+ {
+ UInt32 numWords = (blockSize + kFlagsMask) >> kNumFlagsBits;
+ for (i = 0; i < numWords; i++)
+ Flags[i] = kAllFlags;
+ }
+ #endif
+
+ {
+ UInt32 sum = 0;
+ for (i = 0; i < kNumHashValues; i++)
+ {
+ UInt32 groupSize = counters[i];
+ if (groupSize > 0)
+ {
+ #ifdef BLOCK_SORT_EXTERNAL_FLAGS
+ UInt32 t = sum + groupSize - 1;
+ Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask));
+ #endif
+ sum += groupSize;
+ }
+ counters[i] = sum - groupSize;
+ }
+
+ for (i = 0; i < blockSize - 1; i++)
+ Groups[i] = counters[((UInt32)data[i] << 8) | data[i + 1]];
+ Groups[i] = counters[((UInt32)data[i] << 8) | data[0]];
+
+ for (i = 0; i < blockSize - 1; i++)
+ Indices[counters[((UInt32)data[i] << 8) | data[i + 1]]++] = i;
+ Indices[counters[((UInt32)data[i] << 8) | data[0]]++] = i;
+
+ #ifndef BLOCK_SORT_EXTERNAL_FLAGS
+ UInt32 prev = 0;
+ for (i = 0; i < kNumHashValues; i++)
+ {
+ UInt32 prevGroupSize = counters[i] - prev;
+ if (prevGroupSize == 0)
+ continue;
+ SetGroupSize(Indices + prev, prevGroupSize);
+ prev = counters[i];
+ }
+ #endif
+ }
+
+ int NumRefBits;
+ for (NumRefBits = 0; ((blockSize - 1) >> NumRefBits) != 0; NumRefBits++);
+ NumRefBits = 32 - NumRefBits;
+ if (NumRefBits > kNumRefBitsMax)
+ NumRefBits = kNumRefBitsMax;
+
+ for (UInt32 NumSortedBytes = kNumHashBytes; ; NumSortedBytes <<= 1)
+ {
+ #ifndef BLOCK_SORT_EXTERNAL_FLAGS
+ UInt32 finishedGroupSize = 0;
+ #endif
+ UInt32 newLimit = 0;
+ for (i = 0; i < blockSize;)
+ {
+ #ifdef BLOCK_SORT_EXTERNAL_FLAGS
+
+ if ((Flags[i >> kNumFlagsBits] & (1 << (i & kFlagsMask))) == 0)
+ {
+ i++;
+ continue;
+ }
+ UInt32 groupSize;
+ for(groupSize = 1;
+ (Flags[(i + groupSize) >> kNumFlagsBits] & (1 << ((i + groupSize) & kFlagsMask))) != 0;
+ groupSize++);
+
+ groupSize++;
+
+ #else
+
+ UInt32 groupSize = ((Indices[i] & ~0xC0000000) >> kNumBitsMax);
+ bool finishedGroup = ((Indices[i] & 0x80000000) == 0);
+ if ((Indices[i] & 0x40000000) != 0)
+ {
+ groupSize += ((Indices[i + 1] >> kNumBitsMax) << kNumExtra0Bits);
+ Indices[i + 1] &= kIndexMask;
+ }
+ Indices[i] &= kIndexMask;
+ groupSize++;
+ if (finishedGroup || groupSize == 1)
+ {
+ Indices[i - finishedGroupSize] &= kIndexMask;
+ if (finishedGroupSize > 1)
+ Indices[i - finishedGroupSize + 1] &= kIndexMask;
+ UInt32 newGroupSize = groupSize + finishedGroupSize;
+ SetFinishedGroupSize(Indices + i - finishedGroupSize, newGroupSize);
+ finishedGroupSize = newGroupSize;
+ i += groupSize;
+ continue;
+ }
+ finishedGroupSize = 0;
+
+ #endif
+
+ if (NumSortedBytes >= blockSize)
+ for (UInt32 j = 0; j < groupSize; j++)
+ {
+ UInt32 t = (i + j);
+ // Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask));
+ Groups[Indices[t]] = t;
+ }
+ else
+ if (SortGroup(blockSize, NumSortedBytes, i, groupSize, NumRefBits, Indices
+ #ifndef BLOCK_SORT_USE_HEAP_SORT
+ , 0, blockSize
+ #endif
+ ) != 0)
+ newLimit = i + groupSize;
+ i += groupSize;
+ }
+ if (newLimit == 0)
+ break;
+ }
+ #ifndef BLOCK_SORT_EXTERNAL_FLAGS
+ for (i = 0; i < blockSize;)
+ {
+ UInt32 groupSize = ((Indices[i] & ~0xC0000000) >> kNumBitsMax);
+ if ((Indices[i] & 0x40000000) != 0)
+ {
+ groupSize += ((Indices[i + 1] >> kNumBitsMax) << kNumExtra0Bits);
+ Indices[i + 1] &= kIndexMask;
+ }
+ Indices[i] &= kIndexMask;
+ groupSize++;
+ i += groupSize;
+ }
+ #endif
+ return Groups[0];
+}
+
diff --git a/CPP/7zip/Compress/BWT/BlockSort.h b/CPP/7zip/Compress/BWT/BlockSort.h
new file mode 100755
index 00000000..def48a96
--- /dev/null
+++ b/CPP/7zip/Compress/BWT/BlockSort.h
@@ -0,0 +1,21 @@
+// BlockSort.h
+
+#ifndef __BLOCKSORT_H
+#define __BLOCKSORT_H
+
+#include "Common/Types.h"
+
+// use BLOCK_SORT_EXTERNAL_FLAGS if blockSize can be > 1M
+// #define BLOCK_SORT_EXTERNAL_FLAGS
+
+#ifdef BLOCK_SORT_EXTERNAL_FLAGS
+#define BLOCK_SORT_EXTERNAL_SIZE(blockSize) ((((blockSize) + 31) >> 5))
+#else
+#define BLOCK_SORT_EXTERNAL_SIZE(blockSize) 0
+#endif
+
+#define BLOCK_SORT_BUF_SIZE(blockSize) ((blockSize) * 2 + BLOCK_SORT_EXTERNAL_SIZE(blockSize) + (1 << 16))
+
+UInt32 BlockSort(UInt32 *indices, const Byte *data, UInt32 blockSize);
+
+#endif
diff --git a/CPP/7zip/Compress/BWT/Mtf8.h b/CPP/7zip/Compress/BWT/Mtf8.h
new file mode 100755
index 00000000..92e4df20
--- /dev/null
+++ b/CPP/7zip/Compress/BWT/Mtf8.h
@@ -0,0 +1,195 @@
+// Mtf8.h
+
+#ifndef __MTF8_H
+#define __MTF8_H
+
+#include "Common/Types.h"
+
+namespace NCompress {
+
+class CMtf8Encoder
+{
+public:
+ Byte Buffer[256];
+ int FindAndMove(Byte v)
+ {
+ int pos;
+ for (pos = 0; Buffer[pos] != v; pos++);
+ int resPos = pos;
+ for (; pos >= 8; pos -= 8)
+ {
+ Buffer[pos] = Buffer[pos - 1];
+ Buffer[pos - 1] = Buffer[pos - 2];
+ Buffer[pos - 2] = Buffer[pos - 3];
+ Buffer[pos - 3] = Buffer[pos - 4];
+ Buffer[pos - 4] = Buffer[pos - 5];
+ Buffer[pos - 5] = Buffer[pos - 6];
+ Buffer[pos - 6] = Buffer[pos - 7];
+ Buffer[pos - 7] = Buffer[pos - 8];
+ }
+ for (; pos > 0; pos--)
+ Buffer[pos] = Buffer[pos - 1];
+ Buffer[0] = v;
+ return resPos;
+ }
+};
+
+/*
+class CMtf8Decoder
+{
+public:
+ Byte Buffer[256];
+ void Init(int) {};
+ Byte GetHead() const { return Buffer[0]; }
+ Byte GetAndMove(int pos)
+ {
+ Byte res = Buffer[pos];
+ for (; pos >= 8; pos -= 8)
+ {
+ Buffer[pos] = Buffer[pos - 1];
+ Buffer[pos - 1] = Buffer[pos - 2];
+ Buffer[pos - 2] = Buffer[pos - 3];
+ Buffer[pos - 3] = Buffer[pos - 4];
+ Buffer[pos - 4] = Buffer[pos - 5];
+ Buffer[pos - 5] = Buffer[pos - 6];
+ Buffer[pos - 6] = Buffer[pos - 7];
+ Buffer[pos - 7] = Buffer[pos - 8];
+ }
+ for (; pos > 0; pos--)
+ Buffer[pos] = Buffer[pos - 1];
+ Buffer[0] = res;
+ return res;
+ }
+};
+*/
+
+#ifdef _WIN64
+#define MODE_64BIT
+#endif
+
+#ifdef MODE_64BIT
+typedef UInt64 CMtfVar;
+#define MTF_MOVS 3
+#else
+typedef UInt32 CMtfVar;
+#define MTF_MOVS 2
+#endif
+
+#define MTF_MASK ((1 << MTF_MOVS) - 1)
+
+
+class CMtf8Decoder
+{
+public:
+ CMtfVar Buffer[256 >> MTF_MOVS];
+ void StartInit() { memset(Buffer, 0, sizeof(Buffer)); }
+ void Add(unsigned int pos, Byte val) { Buffer[pos >> MTF_MOVS] |= ((CMtfVar)val << ((pos & MTF_MASK) << 3)); }
+ Byte GetHead() const { return (Byte)Buffer[0]; }
+ Byte GetAndMove(unsigned int pos)
+ {
+ UInt32 lim = ((UInt32)pos >> MTF_MOVS);
+ pos = (pos & MTF_MASK) << 3;
+ CMtfVar prev = (Buffer[lim] >> pos) & 0xFF;
+
+ UInt32 i = 0;
+ if ((lim & 1) != 0)
+ {
+ CMtfVar next = Buffer[0];
+ Buffer[0] = (next << 8) | prev;
+ prev = (next >> (MTF_MASK << 3));
+ i = 1;
+ lim -= 1;
+ }
+ for (; i < lim; i += 2)
+ {
+ CMtfVar next = Buffer[i];
+ Buffer[i] = (next << 8) | prev;
+ prev = (next >> (MTF_MASK << 3));
+ next = Buffer[i + 1];
+ Buffer[i + 1] = (next << 8) | prev;
+ prev = (next >> (MTF_MASK << 3));
+ }
+ CMtfVar next = Buffer[i];
+ CMtfVar mask = (((CMtfVar)0x100 << pos) - 1);
+ Buffer[i] = (next & ~mask) | (((next << 8) | prev) & mask);
+ return (Byte)Buffer[0];
+ }
+};
+
+/*
+const int kSmallSize = 64;
+class CMtf8Decoder
+{
+ Byte SmallBuffer[kSmallSize];
+ int SmallSize;
+ Byte Counts[16];
+ int Size;
+public:
+ Byte Buffer[256];
+
+ Byte GetHead() const
+ {
+ if (SmallSize > 0)
+ return SmallBuffer[kSmallSize - SmallSize];
+ return Buffer[0];
+ }
+
+ void Init(int size)
+ {
+ Size = size;
+ SmallSize = 0;
+ for (int i = 0; i < 16; i++)
+ {
+ Counts[i] = ((size >= 16) ? 16 : size);
+ size -= Counts[i];
+ }
+ }
+
+ Byte GetAndMove(int pos)
+ {
+ if (pos < SmallSize)
+ {
+ Byte *p = SmallBuffer + kSmallSize - SmallSize;
+ Byte res = p[pos];
+ for (; pos > 0; pos--)
+ p[pos] = p[pos - 1];
+ SmallBuffer[kSmallSize - SmallSize] = res;
+ return res;
+ }
+ if (SmallSize == kSmallSize)
+ {
+ int i = Size - 1;
+ int g = 16;
+ do
+ {
+ g--;
+ int offset = (g << 4);
+ for (int t = Counts[g] - 1; t >= 0; t--, i--)
+ Buffer[i] = Buffer[offset + t];
+ }
+ while(g != 0);
+
+ for (i = kSmallSize - 1; i >= 0; i--)
+ Buffer[i] = SmallBuffer[i];
+ Init(Size);
+ }
+ pos -= SmallSize;
+ int g;
+ for (g = 0; pos >= Counts[g]; g++)
+ pos -= Counts[g];
+ int offset = (g << 4);
+ Byte res = Buffer[offset + pos];
+ for (pos; pos < 16 - 1; pos++)
+ Buffer[offset + pos] = Buffer[offset + pos + 1];
+
+ SmallSize++;
+ SmallBuffer[kSmallSize - SmallSize] = res;
+
+ Counts[g]--;
+ return res;
+ }
+};
+*/
+
+}
+#endif
diff --git a/CPP/7zip/Compress/BWT/StdAfx.h b/CPP/7zip/Compress/BWT/StdAfx.h
new file mode 100755
index 00000000..b637fd40
--- /dev/null
+++ b/CPP/7zip/Compress/BWT/StdAfx.h
@@ -0,0 +1,6 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#endif
diff --git a/CPP/7zip/Compress/BZip2/BZip2.dsp b/CPP/7zip/Compress/BZip2/BZip2.dsp
new file mode 100755
index 00000000..121602d8
--- /dev/null
+++ b/CPP/7zip/Compress/BZip2/BZip2.dsp
@@ -0,0 +1,303 @@
+# Microsoft Developer Studio Project File - Name="BZip2" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=BZip2 - 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 "BZip2.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 "BZip2.mak" CFG="BZip2 - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "BZip2 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "BZip2 - 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)" == "BZip2 - 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 "BZIP2_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "BZ_NO_STDIO" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /D "COMPRESS_BZIP2_MT" /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\BZip2.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "BZip2 - 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 "BZIP2_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /D "COMPRESS_BZIP2_MT" /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\BZip2.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "BZip2 - Win32 Release"
+# Name "BZip2 - 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 "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\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# End Group
+# Begin Group "Huffman"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Huffman\HuffmanDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Huffman\HuffmanEncode.c
+
+!IF "$(CFG)" == "BZip2 - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Huffman\HuffmanEncode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Sort.c
+
+!IF "$(CFG)" == "BZip2 - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Sort.h
+# End Source File
+# End Group
+# Begin Group "7-Zip 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\MSBFEncoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.h
+# End Source File
+# End Group
+# Begin Group "BWT"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\BWT\BlockSort.cpp
+
+!IF "$(CFG)" == "BZip2 - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\BWT\BlockSort.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\BWT\Mtf8.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Thread.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\BZip2Const.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\BZip2CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\BZip2CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\BZip2Decoder.cpp
+
+!IF "$(CFG)" == "BZip2 - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\BZip2Decoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\BZip2Encoder.cpp
+
+!IF "$(CFG)" == "BZip2 - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\BZip2Encoder.h
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/Compress/BZip2/BZip2.dsw b/CPP/7zip/Compress/BZip2/BZip2.dsw
new file mode 100755
index 00000000..697e5095
--- /dev/null
+++ b/CPP/7zip/Compress/BZip2/BZip2.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "BZip2"=.\BZip2.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Compress/BZip2/BZip2CRC.cpp b/CPP/7zip/Compress/BZip2/BZip2CRC.cpp
new file mode 100755
index 00000000..ba9ddb7e
--- /dev/null
+++ b/CPP/7zip/Compress/BZip2/BZip2CRC.cpp
@@ -0,0 +1,26 @@
+// BZip2CRC.cpp
+
+#include "StdAfx.h"
+
+#include "BZip2CRC.h"
+
+UInt32 CBZip2CRC::Table[256];
+
+static const UInt32 kBZip2CRCPoly = 0x04c11db7; /* AUTODIN II, Ethernet, & FDDI */
+
+void CBZip2CRC::InitTable()
+{
+ for (UInt32 i = 0; i < 256; i++)
+ {
+ UInt32 r = (i << 24);
+ for (int j = 8; j > 0; j--)
+ r = (r & 0x80000000) ? ((r << 1) ^ kBZip2CRCPoly) : (r << 1);
+ Table[i] = r;
+ }
+}
+
+class CBZip2CRCTableInit
+{
+public:
+ CBZip2CRCTableInit() { CBZip2CRC::InitTable(); }
+} g_BZip2CRCTableInit;
diff --git a/CPP/7zip/Compress/BZip2/BZip2CRC.h b/CPP/7zip/Compress/BZip2/BZip2CRC.h
new file mode 100755
index 00000000..8ac2a504
--- /dev/null
+++ b/CPP/7zip/Compress/BZip2/BZip2CRC.h
@@ -0,0 +1,31 @@
+// BZip2CRC.h
+
+#ifndef __BZIP2_CRC_H
+#define __BZIP2_CRC_H
+
+#include "Common/Types.h"
+
+class CBZip2CRC
+{
+ UInt32 _value;
+ static UInt32 Table[256];
+public:
+ static void InitTable();
+ CBZip2CRC(): _value(0xFFFFFFFF) {};
+ void Init() { _value = 0xFFFFFFFF; }
+ void UpdateByte(Byte b) { _value = Table[(_value >> 24) ^ b] ^ (_value << 8); }
+ void UpdateByte(unsigned int b) { _value = Table[(_value >> 24) ^ b] ^ (_value << 8); }
+ UInt32 GetDigest() const { return _value ^ 0xFFFFFFFF; }
+};
+
+class CBZip2CombinedCRC
+{
+ UInt32 _value;
+public:
+ CBZip2CombinedCRC(): _value(0){};
+ void Init() { _value = 0; }
+ void Update(UInt32 v) { _value = ((_value << 1) | (_value >> 31)) ^ v; }
+ UInt32 GetDigest() const { return _value ; }
+};
+
+#endif
diff --git a/CPP/7zip/Compress/BZip2/BZip2Const.h b/CPP/7zip/Compress/BZip2/BZip2Const.h
new file mode 100755
index 00000000..62427aa6
--- /dev/null
+++ b/CPP/7zip/Compress/BZip2/BZip2Const.h
@@ -0,0 +1,54 @@
+// Compress/BZip2Const.h
+
+#ifndef __COMPRESS_BZIP2_CONST_H
+#define __COMPRESS_BZIP2_CONST_H
+
+namespace NCompress {
+namespace NBZip2 {
+
+const Byte kArSig0 = 'B';
+const Byte kArSig1 = 'Z';
+const Byte kArSig2 = 'h';
+const Byte kArSig3 = '0';
+
+const Byte kFinSig0 = 0x17;
+const Byte kFinSig1 = 0x72;
+const Byte kFinSig2 = 0x45;
+const Byte kFinSig3 = 0x38;
+const Byte kFinSig4 = 0x50;
+const Byte kFinSig5 = 0x90;
+
+const Byte kBlockSig0 = 0x31;
+const Byte kBlockSig1 = 0x41;
+const Byte kBlockSig2 = 0x59;
+const Byte kBlockSig3 = 0x26;
+const Byte kBlockSig4 = 0x53;
+const Byte kBlockSig5 = 0x59;
+
+const int kNumOrigBits = 24;
+
+const int kNumTablesBits = 3;
+const int kNumTablesMin = 2;
+const int kNumTablesMax = 6;
+
+const int kNumLevelsBits = 5;
+
+const int kMaxHuffmanLen = 20; // Check it
+
+const int kMaxAlphaSize = 258;
+
+const int kGroupSize = 50;
+
+const int kBlockSizeMultMin = 1;
+const int kBlockSizeMultMax = 9;
+const UInt32 kBlockSizeStep = 100000;
+const UInt32 kBlockSizeMax = kBlockSizeMultMax * kBlockSizeStep;
+
+const int kNumSelectorsBits = 15;
+const UInt32 kNumSelectorsMax = (2 + (kBlockSizeMax / kGroupSize));
+
+const int kRleModeRepSize = 4;
+
+}}
+
+#endif
diff --git a/CPP/7zip/Compress/BZip2/BZip2Decoder.cpp b/CPP/7zip/Compress/BZip2/BZip2Decoder.cpp
new file mode 100755
index 00000000..a0b16b18
--- /dev/null
+++ b/CPP/7zip/Compress/BZip2/BZip2Decoder.cpp
@@ -0,0 +1,770 @@
+// BZip2Decoder.cpp
+
+#include "StdAfx.h"
+
+#include "BZip2Decoder.h"
+
+#include "../../../Common/Alloc.h"
+#include "../../../Common/Defs.h"
+#include "../BWT/Mtf8.h"
+#include "BZip2CRC.h"
+
+namespace NCompress {
+namespace NBZip2 {
+
+const UInt32 kNumThreadsMax = 4;
+
+static const UInt32 kBufferSize = (1 << 17);
+
+static Int16 kRandNums[512] = {
+ 619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
+ 985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
+ 733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
+ 419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
+ 878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
+ 862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
+ 150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
+ 170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
+ 73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
+ 909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
+ 641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
+ 161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
+ 382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
+ 98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
+ 227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
+ 469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
+ 184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
+ 715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
+ 951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
+ 652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
+ 645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
+ 609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
+ 653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
+ 411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
+ 170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
+ 857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
+ 669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
+ 944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
+ 344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
+ 897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
+ 433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
+ 686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
+ 946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
+ 978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
+ 680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
+ 707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
+ 297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
+ 134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
+ 343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
+ 140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
+ 170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
+ 369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
+ 804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
+ 896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
+ 661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
+ 768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
+ 61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
+ 372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
+ 780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
+ 920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
+ 645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
+ 936, 638
+};
+
+bool CState::Alloc()
+{
+ if (Counters == 0)
+ Counters = (UInt32 *)BigAlloc((256 + kBlockSizeMax) * sizeof(UInt32));
+ return (Counters != 0);
+}
+
+void CState::Free()
+{
+ ::BigFree(Counters);
+ Counters = 0;
+}
+
+UInt32 CDecoder::ReadBits(int numBits) { return m_InStream.ReadBits(numBits); }
+Byte CDecoder::ReadByte() {return (Byte)ReadBits(8); }
+bool CDecoder::ReadBit() { return ReadBits(1) != 0; }
+
+UInt32 CDecoder::ReadCRC()
+{
+ UInt32 crc = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ crc <<= 8;
+ crc |= ReadByte();
+ }
+ return crc;
+}
+
+UInt32 NO_INLINE ReadBits(NStream::NMSBF::CDecoder<CInBuffer> *m_InStream, int num)
+{
+ return m_InStream->ReadBits(num);
+}
+
+UInt32 NO_INLINE ReadBit(NStream::NMSBF::CDecoder<CInBuffer> *m_InStream)
+{
+ return m_InStream->ReadBits(1);
+}
+
+static HRESULT NO_INLINE ReadBlock(NStream::NMSBF::CDecoder<CInBuffer> *m_InStream,
+ UInt32 *CharCounters, UInt32 blockSizeMax, Byte *m_Selectors, CHuffmanDecoder *m_HuffmanDecoders,
+ UInt32 *blockSizeRes, UInt32 *origPtrRes, bool *randRes)
+{
+ *randRes = ReadBit(m_InStream) ? true : false;
+ *origPtrRes = ReadBits(m_InStream, kNumOrigBits);
+
+ // in original code it compares OrigPtr to (UInt32)(10 + blockSizeMax)) : why ?
+ if (*origPtrRes >= blockSizeMax)
+ return S_FALSE;
+
+ CMtf8Decoder mtf;
+ mtf.StartInit();
+
+ int numInUse = 0;
+ {
+ Byte inUse16[16];
+ int i;
+ for (i = 0; i < 16; i++)
+ inUse16[i] = (Byte)ReadBit(m_InStream);
+ for (i = 0; i < 256; i++)
+ if (inUse16[i >> 4])
+ {
+ if (ReadBit(m_InStream))
+ mtf.Add(numInUse++, (Byte)i);
+ }
+ if (numInUse == 0)
+ return S_FALSE;
+ // mtf.Init(numInUse);
+ }
+ int alphaSize = numInUse + 2;
+
+ int numTables = ReadBits(m_InStream, kNumTablesBits);
+ if (numTables < kNumTablesMin || numTables > kNumTablesMax)
+ return S_FALSE;
+
+ UInt32 numSelectors = ReadBits(m_InStream, kNumSelectorsBits);
+ if (numSelectors < 1 || numSelectors > kNumSelectorsMax)
+ return S_FALSE;
+
+ {
+ Byte mtfPos[kNumTablesMax];
+ int t = 0;
+ do
+ mtfPos[t] = (Byte)t;
+ while(++t < numTables);
+ UInt32 i = 0;
+ do
+ {
+ int j = 0;
+ while (ReadBit(m_InStream))
+ if (++j >= numTables)
+ return S_FALSE;
+ Byte tmp = mtfPos[j];
+ for (;j > 0; j--)
+ mtfPos[j] = mtfPos[j - 1];
+ m_Selectors[i] = mtfPos[0] = tmp;
+ }
+ while(++i < numSelectors);
+ }
+
+ int t = 0;
+ do
+ {
+ Byte lens[kMaxAlphaSize];
+ int len = (int)ReadBits(m_InStream, kNumLevelsBits);
+ int i;
+ for (i = 0; i < alphaSize; i++)
+ {
+ for (;;)
+ {
+ if (len < 1 || len > kMaxHuffmanLen)
+ return S_FALSE;
+ if (!ReadBit(m_InStream))
+ break;
+ len += 1 - (int)(ReadBit(m_InStream) << 1);
+ }
+ lens[i] = (Byte)len;
+ }
+ for (; i < kMaxAlphaSize; i++)
+ lens[i] = 0;
+ if(!m_HuffmanDecoders[t].SetCodeLengths(lens))
+ return S_FALSE;
+ }
+ while(++t < numTables);
+
+ {
+ for (int i = 0; i < 256; i++)
+ CharCounters[i] = 0;
+ }
+
+ UInt32 blockSize = 0;
+ {
+ UInt32 groupIndex = 0;
+ UInt32 groupSize = 0;
+ CHuffmanDecoder *huffmanDecoder = 0;
+ int runPower = 0;
+ UInt32 runCounter = 0;
+
+ for (;;)
+ {
+ if (groupSize == 0)
+ {
+ if (groupIndex >= numSelectors)
+ return S_FALSE;
+ groupSize = kGroupSize;
+ huffmanDecoder = &m_HuffmanDecoders[m_Selectors[groupIndex++]];
+ }
+ groupSize--;
+
+ UInt32 nextSym = huffmanDecoder->DecodeSymbol(m_InStream);
+
+ if (nextSym < 2)
+ {
+ runCounter += ((UInt32)(nextSym + 1) << runPower++);
+ if (blockSizeMax - blockSize < runCounter)
+ return S_FALSE;
+ continue;
+ }
+ if (runCounter != 0)
+ {
+ UInt32 b = (UInt32)mtf.GetHead();
+ CharCounters[b] += runCounter;
+ do
+ CharCounters[256 + blockSize++] = b;
+ while(--runCounter != 0);
+ runPower = 0;
+ }
+ if (nextSym <= (UInt32)numInUse)
+ {
+ UInt32 b = (UInt32)mtf.GetAndMove((int)nextSym - 1);
+ if (blockSize >= blockSizeMax)
+ return S_FALSE;
+ CharCounters[b]++;
+ CharCounters[256 + blockSize++] = b;
+ }
+ else if (nextSym == (UInt32)numInUse + 1)
+ break;
+ else
+ return S_FALSE;
+ }
+ }
+ *blockSizeRes = blockSize;
+ return (*origPtrRes < blockSize) ? S_OK : S_FALSE;
+}
+
+void NO_INLINE DecodeBlock1(UInt32 *charCounters, UInt32 blockSize)
+{
+ {
+ UInt32 sum = 0;
+ for (UInt32 i = 0; i < 256; i++)
+ {
+ sum += charCounters[i];
+ charCounters[i] = sum - charCounters[i];
+ }
+ }
+
+ UInt32 *tt = charCounters + 256;
+ // Compute the T^(-1) vector
+ UInt32 i = 0;
+ do
+ tt[charCounters[tt[i] & 0xFF]++] |= (i << 8);
+ while(++i < blockSize);
+}
+
+static UInt32 NO_INLINE DecodeBlock2(const UInt32 *tt, UInt32 blockSize, UInt32 OrigPtr, COutBuffer &m_OutStream)
+{
+ CBZip2CRC crc;
+
+ // it's for speed optimization: prefetch & prevByte_init;
+ UInt32 tPos = tt[tt[OrigPtr] >> 8];
+ unsigned int prevByte = (unsigned int)(tPos & 0xFF);
+
+ int numReps = 0;
+
+ do
+ {
+ unsigned int b = (unsigned int)(tPos & 0xFF);
+ tPos = tt[tPos >> 8];
+
+ if (numReps == kRleModeRepSize)
+ {
+ for (; b > 0; b--)
+ {
+ crc.UpdateByte(prevByte);
+ m_OutStream.WriteByte((Byte)prevByte);
+ }
+ numReps = 0;
+ continue;
+ }
+ if (b != prevByte)
+ numReps = 0;
+ numReps++;
+ prevByte = b;
+ crc.UpdateByte(b);
+ m_OutStream.WriteByte((Byte)b);
+
+ /*
+ prevByte = b;
+ crc.UpdateByte(b);
+ m_OutStream.WriteByte((Byte)b);
+ for (; --blockSize != 0;)
+ {
+ b = (unsigned int)(tPos & 0xFF);
+ tPos = tt[tPos >> 8];
+ crc.UpdateByte(b);
+ m_OutStream.WriteByte((Byte)b);
+ if (b != prevByte)
+ {
+ prevByte = b;
+ continue;
+ }
+ if (--blockSize == 0)
+ break;
+
+ b = (unsigned int)(tPos & 0xFF);
+ tPos = tt[tPos >> 8];
+ crc.UpdateByte(b);
+ m_OutStream.WriteByte((Byte)b);
+ if (b != prevByte)
+ {
+ prevByte = b;
+ continue;
+ }
+ if (--blockSize == 0)
+ break;
+
+ b = (unsigned int)(tPos & 0xFF);
+ tPos = tt[tPos >> 8];
+ crc.UpdateByte(b);
+ m_OutStream.WriteByte((Byte)b);
+ if (b != prevByte)
+ {
+ prevByte = b;
+ continue;
+ }
+ --blockSize;
+ break;
+ }
+ if (blockSize == 0)
+ break;
+
+ b = (unsigned int)(tPos & 0xFF);
+ tPos = tt[tPos >> 8];
+
+ for (; b > 0; b--)
+ {
+ crc.UpdateByte(prevByte);
+ m_OutStream.WriteByte((Byte)prevByte);
+ }
+ */
+ }
+ while(--blockSize != 0);
+ return crc.GetDigest();
+}
+
+static UInt32 NO_INLINE DecodeBlock2Rand(const UInt32 *tt, UInt32 blockSize, UInt32 OrigPtr, COutBuffer &m_OutStream)
+{
+ CBZip2CRC crc;
+
+ UInt32 randIndex = 1;
+ UInt32 randToGo = kRandNums[0] - 2;
+
+ int numReps = 0;
+
+ // it's for speed optimization: prefetch & prevByte_init;
+ UInt32 tPos = tt[tt[OrigPtr] >> 8];
+ unsigned int prevByte = (unsigned int)(tPos & 0xFF);
+
+ do
+ {
+ unsigned int b = (unsigned int)(tPos & 0xFF);
+ tPos = tt[tPos >> 8];
+
+ {
+ if (randToGo == 0)
+ {
+ b ^= 1;
+ randToGo = kRandNums[randIndex++];
+ randIndex &= 0x1FF;
+ }
+ randToGo--;
+ }
+
+ if (numReps == kRleModeRepSize)
+ {
+ for (; b > 0; b--)
+ {
+ crc.UpdateByte(prevByte);
+ m_OutStream.WriteByte((Byte)prevByte);
+ }
+ numReps = 0;
+ continue;
+ }
+ if (b != prevByte)
+ numReps = 0;
+ numReps++;
+ prevByte = b;
+ crc.UpdateByte(b);
+ m_OutStream.WriteByte((Byte)b);
+ }
+ while(--blockSize != 0);
+ return crc.GetDigest();
+}
+
+#ifdef COMPRESS_BZIP2_MT
+
+static DWORD WINAPI MFThread(void *p) { ((CState *)p)->ThreadFunc(); return 0; }
+
+CDecoder::CDecoder():
+ m_States(0)
+{
+ m_NumThreadsPrev = 0;
+ NumThreads = 1;
+ CS.Enter();
+}
+
+CDecoder::~CDecoder()
+{
+ Free();
+}
+
+bool CDecoder::Create()
+{
+ try
+ {
+ if (m_States != 0 && m_NumThreadsPrev == NumThreads)
+ return true;
+ Free();
+ MtMode = (NumThreads > 1);
+ m_NumThreadsPrev = NumThreads;
+ m_States = new CState[NumThreads];
+ if (m_States == 0)
+ return false;
+ #ifdef COMPRESS_BZIP2_MT
+ for (UInt32 t = 0; t < NumThreads; t++)
+ {
+ CState &ti = m_States[t];
+ ti.Decoder = this;
+ if (MtMode)
+ if (!ti.Thread.Create(MFThread, &ti))
+ {
+ NumThreads = t;
+ Free();
+ return false;
+ }
+ }
+ #endif
+ }
+ catch(...) { return false; }
+ return true;
+}
+
+void CDecoder::Free()
+{
+ if (!m_States)
+ return;
+ CloseThreads = true;
+ CS.Leave();
+ for (UInt32 t = 0; t < NumThreads; t++)
+ {
+ CState &s = m_States[t];
+ if (MtMode)
+ s.Thread.Wait();
+ s.Free();
+ }
+ delete []m_States;
+ m_States = 0;
+}
+#endif
+
+HRESULT CDecoder::ReadSignatures(bool &wasFinished, UInt32 &crc)
+{
+ wasFinished = false;
+ Byte s[6];
+ for (int i = 0; i < 6; i++)
+ s[i] = ReadByte();
+ crc = ReadCRC();
+ if (s[0] == kFinSig0)
+ {
+ if (s[1] != kFinSig1 ||
+ s[2] != kFinSig2 ||
+ s[3] != kFinSig3 ||
+ s[4] != kFinSig4 ||
+ s[5] != kFinSig5)
+ return S_FALSE;
+
+ wasFinished = true;
+ return (crc == CombinedCRC.GetDigest()) ? S_OK : S_FALSE;
+ }
+ if (s[0] != kBlockSig0 ||
+ s[1] != kBlockSig1 ||
+ s[2] != kBlockSig2 ||
+ s[3] != kBlockSig3 ||
+ s[4] != kBlockSig4 ||
+ s[5] != kBlockSig5)
+ return S_FALSE;
+ CombinedCRC.Update(crc);
+ return S_OK;
+}
+
+HRESULT CDecoder::DecodeFile(bool &isBZ, ICompressProgressInfo *progress)
+{
+ #ifdef COMPRESS_BZIP2_MT
+ Progress = progress;
+ if (!Create())
+ return E_FAIL;
+ for (UInt32 t = 0; t < NumThreads; t++)
+ {
+ CState &s = m_States[t];
+ if (!s.Alloc())
+ return E_OUTOFMEMORY;
+ s.StreamWasFinishedEvent.Reset();
+ s.WaitingWasStartedEvent.Reset();
+ s.CanWriteEvent.Reset();
+ }
+ #else
+ if (!m_States[0].Alloc())
+ return E_OUTOFMEMORY;
+ #endif
+
+ isBZ = false;
+ Byte s[6];
+ int i;
+ for (i = 0; i < 4; i++)
+ s[i] = ReadByte();
+ if (s[0] != kArSig0 ||
+ s[1] != kArSig1 ||
+ s[2] != kArSig2 ||
+ s[3] <= kArSig3 ||
+ s[3] > kArSig3 + kBlockSizeMultMax)
+ return S_OK;
+ isBZ = true;
+ UInt32 dicSize = (UInt32)(s[3] - kArSig3) * kBlockSizeStep;
+
+ CombinedCRC.Init();
+ #ifdef COMPRESS_BZIP2_MT
+ if (MtMode)
+ {
+ NextBlockIndex = 0;
+ StreamWasFinished1 = StreamWasFinished2 = false;
+ CloseThreads = false;
+ CanStartWaitingEvent.Reset();
+ m_States[0].CanWriteEvent.Set();
+ BlockSizeMax = dicSize;
+ Result1 = Result2 = S_OK;
+ CS.Leave();
+ UInt32 t;
+ for (t = 0; t < NumThreads; t++)
+ m_States[t].StreamWasFinishedEvent.Lock();
+ CS.Enter();
+ CanStartWaitingEvent.Set();
+ for (t = 0; t < NumThreads; t++)
+ m_States[t].WaitingWasStartedEvent.Lock();
+ CanStartWaitingEvent.Reset();
+ RINOK(Result2);
+ RINOK(Result1);
+ }
+ else
+ #endif
+ {
+ CState &state = m_States[0];
+ for (;;)
+ {
+ if (progress)
+ {
+ UInt64 packSize = m_InStream.GetProcessedSize();
+ UInt64 unpackSize = m_OutStream.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&packSize, &unpackSize));
+ }
+ bool wasFinished;
+ UInt32 crc;
+ RINOK(ReadSignatures(wasFinished, crc));
+ if (wasFinished)
+ return S_OK;
+
+ UInt32 blockSize, origPtr;
+ bool randMode;
+ RINOK(ReadBlock(&m_InStream, state.Counters, dicSize,
+ m_Selectors, m_HuffmanDecoders,
+ &blockSize, &origPtr, &randMode));
+ DecodeBlock1(state.Counters, blockSize);
+ if ((randMode ?
+ DecodeBlock2Rand(state.Counters + 256, blockSize, origPtr, m_OutStream) :
+ DecodeBlock2(state.Counters + 256, blockSize, origPtr, m_OutStream)) != crc)
+ return S_FALSE;
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CDecoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 * /* outSize */,
+ ICompressProgressInfo *progress)
+{
+ if (!m_InStream.Create(kBufferSize))
+ return E_OUTOFMEMORY;
+ if (!m_OutStream.Create(kBufferSize))
+ return E_OUTOFMEMORY;
+
+ m_InStream.SetStream(inStream);
+ m_InStream.Init();
+
+ m_OutStream.SetStream(outStream);
+ m_OutStream.Init();
+
+ CDecoderFlusher flusher(this);
+
+ bool isBZ;
+ RINOK(DecodeFile(isBZ, progress));
+ return isBZ ? S_OK: S_FALSE;
+}
+
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
+ catch(const CInBufferException &e) { return e.ErrorCode; }
+ catch(const COutBufferException &e) { return e.ErrorCode; }
+ catch(...) { return E_FAIL; }
+}
+
+STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
+{
+ if (value == NULL)
+ return E_INVALIDARG;
+ *value = m_InStream.GetProcessedSize();
+ return S_OK;
+}
+
+#ifdef COMPRESS_BZIP2_MT
+void CState::FinishStream()
+{
+ Decoder->StreamWasFinished1 = true;
+ StreamWasFinishedEvent.Set();
+ Decoder->CS.Leave();
+ Decoder->CanStartWaitingEvent.Lock();
+ WaitingWasStartedEvent.Set();
+}
+
+void CState::ThreadFunc()
+{
+ for (;;)
+ {
+ Decoder->CS.Enter();
+ if (Decoder->CloseThreads)
+ {
+ Decoder->CS.Leave();
+ return;
+ }
+ if (Decoder->StreamWasFinished1)
+ {
+ FinishStream();
+ continue;
+ }
+ HRESULT res = S_OK;
+
+ UInt32 blockIndex = Decoder->NextBlockIndex;
+ UInt32 nextBlockIndex = blockIndex + 1;
+ if (nextBlockIndex == Decoder->NumThreads)
+ nextBlockIndex = 0;
+ Decoder->NextBlockIndex = nextBlockIndex;
+ UInt32 crc;
+ UInt64 packSize;
+ UInt32 blockSize = 0, origPtr = 0;
+ bool randMode = false;
+
+ try
+ {
+ bool wasFinished;
+ res = Decoder->ReadSignatures(wasFinished, crc);
+ if (res != S_OK)
+ {
+ Decoder->Result1 = res;
+ FinishStream();
+ continue;
+ }
+ if (wasFinished)
+ {
+ Decoder->Result1 = res;
+ FinishStream();
+ continue;
+ }
+
+ res = ReadBlock(&Decoder->m_InStream, Counters, Decoder->BlockSizeMax,
+ Decoder->m_Selectors, Decoder->m_HuffmanDecoders,
+ &blockSize, &origPtr, &randMode);
+ if (res != S_OK)
+ {
+ Decoder->Result1 = res;
+ FinishStream();
+ continue;
+ }
+ packSize = Decoder->m_InStream.GetProcessedSize();
+ }
+ catch(const CInBufferException &e) { res = e.ErrorCode; if (res != S_OK) res = E_FAIL; }
+ catch(...) { res = E_FAIL; }
+ if (res != S_OK)
+ {
+ Decoder->Result1 = res;
+ FinishStream();
+ continue;
+ }
+
+ Decoder->CS.Leave();
+
+ DecodeBlock1(Counters, blockSize);
+
+ bool needFinish = true;
+ try
+ {
+ Decoder->m_States[blockIndex].CanWriteEvent.Lock();
+ needFinish = Decoder->StreamWasFinished2;
+ if (!needFinish)
+ {
+ if ((randMode ?
+ DecodeBlock2Rand(Counters + 256, blockSize, origPtr, Decoder->m_OutStream) :
+ DecodeBlock2(Counters + 256, blockSize, origPtr, Decoder->m_OutStream)) == crc)
+ {
+ if (Decoder->Progress)
+ {
+ UInt64 unpackSize = Decoder->m_OutStream.GetProcessedSize();
+ res = Decoder->Progress->SetRatioInfo(&packSize, &unpackSize);
+ }
+ }
+ else
+ res = S_FALSE;
+ }
+ }
+ catch(const COutBufferException &e) { res = e.ErrorCode; if (res != S_OK) res = E_FAIL; }
+ catch(...) { res = E_FAIL; }
+ if (res != S_OK)
+ {
+ Decoder->Result2 = res;
+ Decoder->StreamWasFinished2 = true;
+ }
+ Decoder->m_States[nextBlockIndex].CanWriteEvent.Set();
+ if (res != S_OK || needFinish)
+ {
+ StreamWasFinishedEvent.Set();
+ Decoder->CanStartWaitingEvent.Lock();
+ WaitingWasStartedEvent.Set();
+ }
+ }
+}
+
+STDMETHODIMP CDecoder::SetNumberOfThreads(UInt32 numThreads)
+{
+ NumThreads = numThreads;
+ if (NumThreads < 1)
+ NumThreads = 1;
+ if (NumThreads > kNumThreadsMax)
+ NumThreads = kNumThreadsMax;
+ return S_OK;
+}
+#endif
+
+}}
diff --git a/CPP/7zip/Compress/BZip2/BZip2Decoder.h b/CPP/7zip/Compress/BZip2/BZip2Decoder.h
new file mode 100755
index 00000000..2375b755
--- /dev/null
+++ b/CPP/7zip/Compress/BZip2/BZip2Decoder.h
@@ -0,0 +1,164 @@
+// Compress/BZip2/Decoder.h
+
+#ifndef __COMPRESS_BZIP2_DECODER_H
+#define __COMPRESS_BZIP2_DECODER_H
+
+#include "../../ICoder.h"
+#include "../../../Common/MyCom.h"
+#include "../../Common/MSBFDecoder.h"
+#include "../../Common/InBuffer.h"
+#include "../../Common/OutBuffer.h"
+#include "../Huffman/HuffmanDecoder.h"
+#include "BZip2Const.h"
+#include "BZip2CRC.h"
+
+#ifdef COMPRESS_BZIP2_MT
+#include "../../../Windows/Thread.h"
+#include "../../../Windows/Synchronization.h"
+#endif
+
+#if _MSC_VER >= 1300
+#define NO_INLINE __declspec(noinline) __fastcall
+#else
+#ifdef _MSC_VER
+#define NO_INLINE __fastcall
+#endif
+#endif
+
+namespace NCompress {
+namespace NBZip2 {
+
+typedef NCompress::NHuffman::CDecoder<kMaxHuffmanLen, kMaxAlphaSize> CHuffmanDecoder;
+
+class CDecoder;
+
+struct CState
+{
+ UInt32 *Counters;
+
+ #ifdef COMPRESS_BZIP2_MT
+
+ CDecoder *Decoder;
+ NWindows::CThread Thread;
+ bool m_OptimizeNumTables;
+
+ NWindows::NSynchronization::CAutoResetEvent StreamWasFinishedEvent;
+ NWindows::NSynchronization::CAutoResetEvent WaitingWasStartedEvent;
+
+ // it's not member of this thread. We just need one event per thread
+ NWindows::NSynchronization::CAutoResetEvent CanWriteEvent;
+
+ Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size.
+
+ void FinishStream();
+ void ThreadFunc();
+
+ #endif
+
+ CState(): Counters(0) {}
+ ~CState() { Free(); }
+ bool Alloc();
+ void Free();
+};
+
+class CDecoder :
+ public ICompressCoder,
+ #ifdef COMPRESS_BZIP2_MT
+ public ICompressSetCoderMt,
+ #endif
+ public ICompressGetInStreamProcessedSize,
+ public CMyUnknownImp
+{
+public:
+ COutBuffer m_OutStream;
+ Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size.
+ NStream::NMSBF::CDecoder<CInBuffer> m_InStream;
+ Byte m_Selectors[kNumSelectorsMax];
+ CHuffmanDecoder m_HuffmanDecoders[kNumTablesMax];
+private:
+
+ UInt32 m_NumThreadsPrev;
+
+ UInt32 ReadBits(int numBits);
+ Byte ReadByte();
+ bool ReadBit();
+ UInt32 ReadCRC();
+ HRESULT PrepareBlock(CState &state);
+ HRESULT DecodeFile(bool &isBZ, ICompressProgressInfo *progress);
+ HRESULT CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+ class CDecoderFlusher
+ {
+ CDecoder *_decoder;
+ public:
+ bool NeedFlush;
+ CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {}
+ ~CDecoderFlusher()
+ {
+ if (NeedFlush)
+ _decoder->Flush();
+ _decoder->ReleaseStreams();
+ }
+ };
+
+public:
+ CBZip2CombinedCRC CombinedCRC;
+
+ #ifdef COMPRESS_BZIP2_MT
+ ICompressProgressInfo *Progress;
+ CState *m_States;
+
+ NWindows::NSynchronization::CCriticalSection CS;
+ UInt32 NumThreads;
+ bool MtMode;
+ UInt32 NextBlockIndex;
+ bool CloseThreads;
+ bool StreamWasFinished1;
+ bool StreamWasFinished2;
+ NWindows::NSynchronization::CManualResetEvent CanStartWaitingEvent;
+
+ HRESULT Result1;
+ HRESULT Result2;
+
+ UInt32 BlockSizeMax;
+ CDecoder();
+ ~CDecoder();
+ bool Create();
+ void Free();
+
+ #else
+ CState m_States[1];
+ #endif
+
+ HRESULT ReadSignatures(bool &wasFinished, UInt32 &crc);
+
+
+ HRESULT Flush() { return m_OutStream.Flush(); }
+ void ReleaseStreams()
+ {
+ m_InStream.ReleaseStream();
+ m_OutStream.ReleaseStream();
+ }
+
+ #ifdef COMPRESS_BZIP2_MT
+ MY_UNKNOWN_IMP2(ICompressSetCoderMt, ICompressGetInStreamProcessedSize)
+ #else
+ MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
+ #endif
+
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
+
+ #ifdef COMPRESS_BZIP2_MT
+ STDMETHOD(SetNumberOfThreads)(UInt32 numThreads);
+ #endif
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Compress/BZip2/BZip2Encoder.cpp b/CPP/7zip/Compress/BZip2/BZip2Encoder.cpp
new file mode 100755
index 00000000..1542b07c
--- /dev/null
+++ b/CPP/7zip/Compress/BZip2/BZip2Encoder.cpp
@@ -0,0 +1,883 @@
+// BZip2Encoder.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/Alloc.h"
+
+#include "BZip2Encoder.h"
+
+#include "../BWT/BlockSort.h"
+#include "../BWT/Mtf8.h"
+#include "BZip2CRC.h"
+
+extern "C"
+{
+ #include "../../../../C/Compress/Huffman/HuffmanEncode.h"
+}
+
+namespace NCompress {
+namespace NBZip2 {
+
+const int kMaxHuffmanLenForEncoding = 16; // it must be < kMaxHuffmanLen = 20
+
+static const UInt32 kBufferSize = (1 << 17);
+static const int kNumHuffPasses = 4;
+
+bool CThreadInfo::Create()
+{
+ if (m_BlockSorterIndex != 0)
+ return true;
+ m_BlockSorterIndex = (UInt32 *)::BigAlloc(BLOCK_SORT_BUF_SIZE(kBlockSizeMax) * sizeof(UInt32));
+ if (m_BlockSorterIndex == 0)
+ return false;
+
+
+ if (m_Block == 0)
+ {
+ m_Block = (Byte *)::MidAlloc(kBlockSizeMax * 5 + kBlockSizeMax / 10 + (20 << 10));
+ if (m_Block == 0)
+ return false;
+ m_MtfArray = m_Block + kBlockSizeMax;
+ m_TempArray = m_MtfArray + kBlockSizeMax * 2 + 2;
+ }
+ return true;
+}
+
+void CThreadInfo::Free()
+{
+ ::BigFree(m_BlockSorterIndex);
+ m_BlockSorterIndex = 0;
+ ::MidFree(m_Block);
+ m_Block = 0;
+}
+
+#ifdef COMPRESS_BZIP2_MT
+void CThreadInfo::FinishStream(bool needLeave)
+{
+ Encoder->StreamWasFinished = true;
+ StreamWasFinishedEvent.Set();
+ if (needLeave)
+ Encoder->CS.Leave();
+ Encoder->CanStartWaitingEvent.Lock();
+ WaitingWasStartedEvent.Set();
+}
+
+DWORD CThreadInfo::ThreadFunc()
+{
+ for (;;)
+ {
+ Encoder->CS.Enter();
+ if (Encoder->CloseThreads)
+ {
+ Encoder->CS.Leave();
+ return 0;
+ }
+ if (Encoder->StreamWasFinished)
+ {
+ FinishStream(true);
+ continue;
+ }
+ HRESULT res = S_OK;
+ bool needLeave = true;
+ try
+ {
+ UInt32 blockSize = Encoder->ReadRleBlock(m_Block);
+ m_PackSize = Encoder->m_InStream.GetProcessedSize();
+ m_BlockIndex = Encoder->NextBlockIndex;
+ if (++Encoder->NextBlockIndex == Encoder->NumThreads)
+ Encoder->NextBlockIndex = 0;
+ if (blockSize == 0)
+ {
+ FinishStream(true);
+ continue;
+ }
+ Encoder->CS.Leave();
+ needLeave = false;
+ res = EncodeBlock3(blockSize);
+ }
+ catch(const CInBufferException &e) { res = e.ErrorCode; }
+ catch(const COutBufferException &e) { res = e.ErrorCode; }
+ catch(...) { res = E_FAIL; }
+ if (res != S_OK)
+ {
+ Encoder->Result = res;
+ FinishStream(needLeave);
+ continue;
+ }
+ }
+}
+
+static DWORD WINAPI MFThread(void *threadCoderInfo)
+{
+ return ((CThreadInfo *)threadCoderInfo)->ThreadFunc();
+}
+#endif
+
+CEncoder::CEncoder():
+ NumPasses(1),
+ m_OptimizeNumTables(false),
+ m_BlockSizeMult(kBlockSizeMultMax)
+{
+ #ifdef COMPRESS_BZIP2_MT
+ ThreadsInfo = 0;
+ m_NumThreadsPrev = 0;
+ NumThreads = 1;
+ CS.Enter();
+ #endif
+}
+
+#ifdef COMPRESS_BZIP2_MT
+CEncoder::~CEncoder()
+{
+ Free();
+}
+
+bool CEncoder::Create()
+{
+ try
+ {
+ if (ThreadsInfo != 0 && m_NumThreadsPrev == NumThreads)
+ return true;
+ Free();
+ MtMode = (NumThreads > 1);
+ m_NumThreadsPrev = NumThreads;
+ ThreadsInfo = new CThreadInfo[NumThreads];
+ if (ThreadsInfo == 0)
+ return false;
+ for (UInt32 t = 0; t < NumThreads; t++)
+ {
+ CThreadInfo &ti = ThreadsInfo[t];
+ ti.Encoder = this;
+ if (MtMode)
+ if (!ti.Thread.Create(MFThread, &ti))
+ {
+ NumThreads = t;
+ Free();
+ return false;
+ }
+ }
+ }
+ catch(...) { return false; }
+ return true;
+}
+
+void CEncoder::Free()
+{
+ if (!ThreadsInfo)
+ return;
+ CloseThreads = true;
+ CS.Leave();
+ for (UInt32 t = 0; t < NumThreads; t++)
+ {
+ CThreadInfo &ti = ThreadsInfo[t];
+ if (MtMode)
+ ti.Thread.Wait();
+ ti.Free();
+ }
+ delete []ThreadsInfo;
+ ThreadsInfo = 0;
+}
+#endif
+
+UInt32 CEncoder::ReadRleBlock(Byte *buffer)
+{
+ UInt32 i = 0;
+ Byte prevByte;
+ if (m_InStream.ReadByte(prevByte))
+ {
+ UInt32 blockSize = m_BlockSizeMult * kBlockSizeStep - 1;
+ int numReps = 1;
+ buffer[i++] = prevByte;
+ while (i < blockSize) // "- 1" to support RLE
+ {
+ Byte b;
+ if (!m_InStream.ReadByte(b))
+ break;
+ if (b != prevByte)
+ {
+ if (numReps >= kRleModeRepSize)
+ buffer[i++] = (Byte)(numReps - kRleModeRepSize);
+ buffer[i++] = b;
+ numReps = 1;
+ prevByte = b;
+ continue;
+ }
+ numReps++;
+ if (numReps <= kRleModeRepSize)
+ buffer[i++] = b;
+ else if (numReps == kRleModeRepSize + 255)
+ {
+ buffer[i++] = (Byte)(numReps - kRleModeRepSize);
+ numReps = 0;
+ }
+ }
+ // it's to support original BZip2 decoder
+ if (numReps >= kRleModeRepSize)
+ buffer[i++] = (Byte)(numReps - kRleModeRepSize);
+ }
+ return i;
+}
+
+void CThreadInfo::WriteBits2(UInt32 value, UInt32 numBits)
+ { m_OutStreamCurrent->WriteBits(value, numBits); }
+void CThreadInfo::WriteByte2(Byte b) { WriteBits2(b , 8); }
+void CThreadInfo::WriteBit2(bool v) { WriteBits2((v ? 1 : 0), 1); }
+void CThreadInfo::WriteCRC2(UInt32 v)
+{
+ for (int i = 0; i < 4; i++)
+ WriteByte2(((Byte)(v >> (24 - i * 8))));
+}
+
+void CEncoder::WriteBits(UInt32 value, UInt32 numBits)
+ { m_OutStream.WriteBits(value, numBits); }
+void CEncoder::WriteByte(Byte b) { WriteBits(b , 8); }
+void CEncoder::WriteBit(bool v) { WriteBits((v ? 1 : 0), 1); }
+void CEncoder::WriteCRC(UInt32 v)
+{
+ for (int i = 0; i < 4; i++)
+ WriteByte(((Byte)(v >> (24 - i * 8))));
+}
+
+
+// blockSize > 0
+void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize)
+{
+ WriteBit2(false); // Randomised = false
+
+ {
+ UInt32 origPtr = BlockSort(m_BlockSorterIndex, block, blockSize);
+ // if (m_BlockSorterIndex[origPtr] != 0) throw 1;
+ m_BlockSorterIndex[origPtr] = blockSize;
+ WriteBits2(origPtr, kNumOrigBits);
+ }
+
+ CMtf8Encoder mtf;
+ int numInUse = 0;
+ {
+ bool inUse[256];
+ bool inUse16[16];
+ UInt32 i;
+ for (i = 0; i < 256; i++)
+ inUse[i] = false;
+ for (i = 0; i < 16; i++)
+ inUse16[i] = false;
+ for (i = 0; i < blockSize; i++)
+ inUse[block[i]] = true;
+ for (i = 0; i < 256; i++)
+ if (inUse[i])
+ {
+ inUse16[i >> 4] = true;
+ mtf.Buffer[numInUse++] = (Byte)i;
+ }
+ for (i = 0; i < 16; i++)
+ WriteBit2(inUse16[i]);
+ for (i = 0; i < 256; i++)
+ if (inUse16[i >> 4])
+ WriteBit2(inUse[i]);
+ }
+ int alphaSize = numInUse + 2;
+
+ Byte *mtfs = m_MtfArray;
+ UInt32 mtfArraySize = 0;
+ UInt32 symbolCounts[kMaxAlphaSize];
+ {
+ for (int i = 0; i < kMaxAlphaSize; i++)
+ symbolCounts[i] = 0;
+ }
+
+ {
+ UInt32 rleSize = 0;
+ UInt32 i = 0;
+ const UInt32 *bsIndex = m_BlockSorterIndex;
+ block--;
+ do
+ {
+ int pos = mtf.FindAndMove(block[bsIndex[i]]);
+ if (pos == 0)
+ rleSize++;
+ else
+ {
+ while (rleSize != 0)
+ {
+ rleSize--;
+ mtfs[mtfArraySize++] = (Byte)(rleSize & 1);
+ symbolCounts[rleSize & 1]++;
+ rleSize >>= 1;
+ }
+ if (pos >= 0xFE)
+ {
+ mtfs[mtfArraySize++] = 0xFF;
+ mtfs[mtfArraySize++] = (Byte)(pos - 0xFE);
+ }
+ else
+ mtfs[mtfArraySize++] = (Byte)(pos + 1);
+ symbolCounts[pos + 1]++;
+ }
+ }
+ while (++i < blockSize);
+
+ while (rleSize != 0)
+ {
+ rleSize--;
+ mtfs[mtfArraySize++] = (Byte)(rleSize & 1);
+ symbolCounts[rleSize & 1]++;
+ rleSize >>= 1;
+ }
+
+ if (alphaSize < 256)
+ mtfs[mtfArraySize++] = (Byte)(alphaSize - 1);
+ else
+ {
+ mtfs[mtfArraySize++] = 0xFF;
+ mtfs[mtfArraySize++] = (Byte)(alphaSize - 256);
+ }
+ symbolCounts[alphaSize - 1]++;
+ }
+
+ UInt32 numSymbols = 0;
+ {
+ for (int i = 0; i < kMaxAlphaSize; i++)
+ numSymbols += symbolCounts[i];
+ }
+
+ int bestNumTables = kNumTablesMin;
+ UInt32 bestPrice = 0xFFFFFFFF;
+ UInt32 startPos = m_OutStreamCurrent->GetPos();
+ Byte startCurByte = m_OutStreamCurrent->GetCurByte();
+ for (int nt = kNumTablesMin; nt <= kNumTablesMax + 1; nt++)
+ {
+ int numTables;
+
+ if(m_OptimizeNumTables)
+ {
+ m_OutStreamCurrent->SetPos(startPos);
+ m_OutStreamCurrent->SetCurState((startPos & 7), startCurByte);
+ if (nt <= kNumTablesMax)
+ numTables = nt;
+ else
+ numTables = bestNumTables;
+ }
+ else
+ {
+ if (numSymbols < 200) numTables = 2;
+ else if (numSymbols < 600) numTables = 3;
+ else if (numSymbols < 1200) numTables = 4;
+ else if (numSymbols < 2400) numTables = 5;
+ else numTables = 6;
+ }
+
+ WriteBits2(numTables, kNumTablesBits);
+
+ UInt32 numSelectors = (numSymbols + kGroupSize - 1) / kGroupSize;
+ WriteBits2(numSelectors, kNumSelectorsBits);
+
+ {
+ UInt32 remFreq = numSymbols;
+ int gs = 0;
+ int t = numTables;
+ do
+ {
+ UInt32 tFreq = remFreq / t;
+ int ge = gs;
+ UInt32 aFreq = 0;
+ while (aFreq < tFreq) // && ge < alphaSize)
+ aFreq += symbolCounts[ge++];
+
+ if (ge - 1 > gs && t != numTables && t != 1 && (((numTables - t) & 1) == 1))
+ aFreq -= symbolCounts[--ge];
+
+ Byte *lens = Lens[t - 1];
+ int i = 0;
+ do
+ lens[i] = (i >= gs && i < ge) ? 0 : 1;
+ while (++i < alphaSize);
+ gs = ge;
+ remFreq -= aFreq;
+ }
+ while(--t != 0);
+ }
+
+
+ for (int pass = 0; pass < kNumHuffPasses; pass++)
+ {
+ {
+ int t = 0;
+ do
+ memset(Freqs[t], 0, sizeof(Freqs[t]));
+ while(++t < numTables);
+ }
+
+ {
+ UInt32 mtfPos = 0;
+ UInt32 g = 0;
+ do
+ {
+ UInt32 symbols[kGroupSize];
+ int i = 0;
+ do
+ {
+ UInt32 symbol = mtfs[mtfPos++];
+ if (symbol >= 0xFF)
+ symbol += mtfs[mtfPos++];
+ symbols[i] = symbol;
+ }
+ while (++i < kGroupSize && mtfPos < mtfArraySize);
+
+ UInt32 bestPrice = 0xFFFFFFFF;
+ int t = 0;
+ do
+ {
+ const Byte *lens = Lens[t];
+ UInt32 price = 0;
+ int j = 0;
+ do
+ price += lens[symbols[j]];
+ while (++j < i);
+ if (price < bestPrice)
+ {
+ m_Selectors[g] = (Byte)t;
+ bestPrice = price;
+ }
+ }
+ while(++t < numTables);
+ UInt32 *freqs = Freqs[m_Selectors[g++]];
+ int j = 0;
+ do
+ freqs[symbols[j]]++;
+ while (++j < i);
+ }
+ while (mtfPos < mtfArraySize);
+ }
+
+ int t = 0;
+ do
+ {
+ UInt32 *freqs = Freqs[t];
+ int i = 0;
+ do
+ if (freqs[i] == 0)
+ freqs[i] = 1;
+ while(++i < alphaSize);
+ Huffman_Generate(freqs, Codes[t], Lens[t], kMaxAlphaSize, kMaxHuffmanLenForEncoding);
+ }
+ while(++t < numTables);
+ }
+
+ {
+ Byte mtfSel[kNumTablesMax];
+ {
+ int t = 0;
+ do
+ mtfSel[t] = (Byte)t;
+ while(++t < numTables);
+ }
+
+ UInt32 i = 0;
+ do
+ {
+ Byte sel = m_Selectors[i];
+ int pos;
+ for (pos = 0; mtfSel[pos] != sel; pos++)
+ WriteBit2(true);
+ WriteBit2(false);
+ for (; pos > 0; pos--)
+ mtfSel[pos] = mtfSel[pos - 1];
+ mtfSel[0] = sel;
+ }
+ while(++i < numSelectors);
+ }
+
+ {
+ int t = 0;
+ do
+ {
+ const Byte *lens = Lens[t];
+ UInt32 len = lens[0];
+ WriteBits2(len, kNumLevelsBits);
+ int i = 0;
+ do
+ {
+ UInt32 level = lens[i];
+ while (len != level)
+ {
+ WriteBit2(true);
+ if (len < level)
+ {
+ WriteBit2(false);
+ len++;
+ }
+ else
+ {
+ WriteBit2(true);
+ len--;
+ }
+ }
+ WriteBit2(false);
+ }
+ while (++i < alphaSize);
+ }
+ while(++t < numTables);
+ }
+
+ {
+ UInt32 groupSize = 0;
+ UInt32 groupIndex = 0;
+ const Byte *lens = 0;
+ const UInt32 *codes = 0;
+ UInt32 mtfPos = 0;
+ do
+ {
+ UInt32 symbol = mtfs[mtfPos++];
+ if (symbol >= 0xFF)
+ symbol += mtfs[mtfPos++];
+ if (groupSize == 0)
+ {
+ groupSize = kGroupSize;
+ int t = m_Selectors[groupIndex++];
+ lens = Lens[t];
+ codes = Codes[t];
+ }
+ groupSize--;
+ m_OutStreamCurrent->WriteBits(codes[symbol], lens[symbol]);
+ }
+ while (mtfPos < mtfArraySize);
+ }
+
+ if (!m_OptimizeNumTables)
+ break;
+ UInt32 price = m_OutStreamCurrent->GetPos() - startPos;
+ if (price <= bestPrice)
+ {
+ if (nt == kNumTablesMax)
+ break;
+ bestPrice = price;
+ bestNumTables = nt;
+ }
+ }
+}
+
+// blockSize > 0
+UInt32 CThreadInfo::EncodeBlockWithHeaders(const Byte *block, UInt32 blockSize)
+{
+ WriteByte2(kBlockSig0);
+ WriteByte2(kBlockSig1);
+ WriteByte2(kBlockSig2);
+ WriteByte2(kBlockSig3);
+ WriteByte2(kBlockSig4);
+ WriteByte2(kBlockSig5);
+
+ CBZip2CRC crc;
+ int numReps = 0;
+ Byte prevByte = block[0];
+ UInt32 i = 0;
+ do
+ {
+ Byte b = block[i];
+ if (numReps == kRleModeRepSize)
+ {
+ for (; b > 0; b--)
+ crc.UpdateByte(prevByte);
+ numReps = 0;
+ continue;
+ }
+ if (prevByte == b)
+ numReps++;
+ else
+ {
+ numReps = 1;
+ prevByte = b;
+ }
+ crc.UpdateByte(b);
+ }
+ while (++i < blockSize);
+ UInt32 crcRes = crc.GetDigest();
+ WriteCRC2(crcRes);
+ EncodeBlock(block, blockSize);
+ return crcRes;
+}
+
+void CThreadInfo::EncodeBlock2(const Byte *block, UInt32 blockSize, UInt32 numPasses)
+{
+ UInt32 numCrcs = m_NumCrcs;
+ bool needCompare = false;
+
+ UInt32 startBytePos = m_OutStreamCurrent->GetBytePos();
+ UInt32 startPos = m_OutStreamCurrent->GetPos();
+ Byte startCurByte = m_OutStreamCurrent->GetCurByte();
+ Byte endCurByte = 0;
+ UInt32 endPos = 0;
+ if (numPasses > 1 && blockSize >= (1 << 10))
+ {
+ UInt32 blockSize0 = blockSize / 2;
+ for (;(block[blockSize0] == block[blockSize0 - 1] ||
+ block[blockSize0 - 1] == block[blockSize0 - 2]) &&
+ blockSize0 < blockSize; blockSize0++);
+ if (blockSize0 < blockSize)
+ {
+ EncodeBlock2(block, blockSize0, numPasses - 1);
+ EncodeBlock2(block + blockSize0, blockSize - blockSize0, numPasses - 1);
+ endPos = m_OutStreamCurrent->GetPos();
+ endCurByte = m_OutStreamCurrent->GetCurByte();
+ if ((endPos & 7) > 0)
+ WriteBits2(0, 8 - (endPos & 7));
+ m_OutStreamCurrent->SetCurState((startPos & 7), startCurByte);
+ needCompare = true;
+ }
+ }
+
+ UInt32 startBytePos2 = m_OutStreamCurrent->GetBytePos();
+ UInt32 startPos2 = m_OutStreamCurrent->GetPos();
+ UInt32 crcVal = EncodeBlockWithHeaders(block, blockSize);
+ UInt32 endPos2 = m_OutStreamCurrent->GetPos();
+
+ if (needCompare)
+ {
+ UInt32 size2 = endPos2 - startPos2;
+ if (size2 < endPos - startPos)
+ {
+ UInt32 numBytes = m_OutStreamCurrent->GetBytePos() - startBytePos2;
+ Byte *buffer = m_OutStreamCurrent->GetStream();
+ for (UInt32 i = 0; i < numBytes; i++)
+ buffer[startBytePos + i] = buffer[startBytePos2 + i];
+ m_OutStreamCurrent->SetPos(startPos + endPos2 - startPos2);
+ m_NumCrcs = numCrcs;
+ m_CRCs[m_NumCrcs++] = crcVal;
+ }
+ else
+ {
+ m_OutStreamCurrent->SetPos(endPos);
+ m_OutStreamCurrent->SetCurState((endPos & 7), endCurByte);
+ }
+ }
+ else
+ {
+ m_NumCrcs = numCrcs;
+ m_CRCs[m_NumCrcs++] = crcVal;
+ }
+}
+
+HRESULT CThreadInfo::EncodeBlock3(UInt32 blockSize)
+{
+ CMsbfEncoderTemp outStreamTemp;
+ outStreamTemp.SetStream(m_TempArray);
+ outStreamTemp.Init();
+ m_OutStreamCurrent = &outStreamTemp;
+
+ m_NumCrcs = 0;
+
+ EncodeBlock2(m_Block, blockSize, Encoder->NumPasses);
+
+ #ifdef COMPRESS_BZIP2_MT
+ if (Encoder->MtMode)
+ Encoder->ThreadsInfo[m_BlockIndex].CanWriteEvent.Lock();
+ #endif
+ for (UInt32 i = 0; i < m_NumCrcs; i++)
+ Encoder->CombinedCRC.Update(m_CRCs[i]);
+ Encoder->WriteBytes(m_TempArray, outStreamTemp.GetPos(), outStreamTemp.GetCurByte());
+ HRESULT res = S_OK;
+ #ifdef COMPRESS_BZIP2_MT
+ if (Encoder->MtMode)
+ {
+ UInt32 blockIndex = m_BlockIndex + 1;
+ if (blockIndex == Encoder->NumThreads)
+ blockIndex = 0;
+
+ if (Encoder->Progress)
+ {
+ UInt64 unpackSize = Encoder->m_OutStream.GetProcessedSize();
+ res = Encoder->Progress->SetRatioInfo(&m_PackSize, &unpackSize);
+ }
+
+ Encoder->ThreadsInfo[blockIndex].CanWriteEvent.Set();
+ }
+ #endif
+ return res;
+}
+
+void CEncoder::WriteBytes(const Byte *data, UInt32 sizeInBits, Byte lastByte)
+{
+ UInt32 bytesSize = (sizeInBits / 8);
+ for (UInt32 i = 0; i < bytesSize; i++)
+ m_OutStream.WriteBits(data[i], 8);
+ WriteBits(lastByte, (sizeInBits & 7));
+}
+
+
+HRESULT CEncoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 * /* outSize */,
+ ICompressProgressInfo *progress)
+{
+ #ifdef COMPRESS_BZIP2_MT
+ Progress = progress;
+ if (!Create())
+ return E_FAIL;
+ for (UInt32 t = 0; t < NumThreads; t++)
+ #endif
+ {
+ #ifdef COMPRESS_BZIP2_MT
+ CThreadInfo &ti = ThreadsInfo[t];
+ ti.StreamWasFinishedEvent.Reset();
+ ti.WaitingWasStartedEvent.Reset();
+ ti.CanWriteEvent.Reset();
+ #else
+ CThreadInfo &ti = ThreadsInfo;
+ ti.Encoder = this;
+ #endif
+
+ ti.m_OptimizeNumTables = m_OptimizeNumTables;
+
+ if (!ti.Create())
+ return E_OUTOFMEMORY;
+ }
+
+
+ if (!m_InStream.Create(kBufferSize))
+ return E_OUTOFMEMORY;
+ if (!m_OutStream.Create(kBufferSize))
+ return E_OUTOFMEMORY;
+
+
+ m_InStream.SetStream(inStream);
+ m_InStream.Init();
+
+ m_OutStream.SetStream(outStream);
+ m_OutStream.Init();
+
+ CFlusher flusher(this);
+
+ CombinedCRC.Init();
+ #ifdef COMPRESS_BZIP2_MT
+ NextBlockIndex = 0;
+ StreamWasFinished = false;
+ CloseThreads = false;
+ CanStartWaitingEvent.Reset();
+ #endif
+
+ WriteByte(kArSig0);
+ WriteByte(kArSig1);
+ WriteByte(kArSig2);
+ WriteByte((Byte)(kArSig3 + m_BlockSizeMult));
+
+ #ifdef COMPRESS_BZIP2_MT
+
+ if (MtMode)
+ {
+ ThreadsInfo[0].CanWriteEvent.Set();
+ Result = S_OK;
+ CS.Leave();
+ UInt32 t;
+ for (t = 0; t < NumThreads; t++)
+ ThreadsInfo[t].StreamWasFinishedEvent.Lock();
+ CS.Enter();
+ CanStartWaitingEvent.Set();
+ for (t = 0; t < NumThreads; t++)
+ ThreadsInfo[t].WaitingWasStartedEvent.Lock();
+ CanStartWaitingEvent.Reset();
+ RINOK(Result);
+ }
+ else
+ #endif
+ {
+ for (;;)
+ {
+ CThreadInfo &ti =
+ #ifdef COMPRESS_BZIP2_MT
+ ThreadsInfo[0];
+ #else
+ ThreadsInfo;
+ #endif
+ UInt32 blockSize = ReadRleBlock(ti.m_Block);
+ if (blockSize == 0)
+ break;
+ RINOK(ti.EncodeBlock3(blockSize));
+ if (progress)
+ {
+ UInt64 packSize = m_InStream.GetProcessedSize();
+ UInt64 unpackSize = m_OutStream.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&packSize, &unpackSize));
+ }
+ }
+ }
+ WriteByte(kFinSig0);
+ WriteByte(kFinSig1);
+ WriteByte(kFinSig2);
+ WriteByte(kFinSig3);
+ WriteByte(kFinSig4);
+ WriteByte(kFinSig5);
+
+ WriteCRC(CombinedCRC.GetDigest());
+ return S_OK;
+}
+
+STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
+ catch(const CInBufferException &e) { return e.ErrorCode; }
+ catch(const COutBufferException &e) { return e.ErrorCode; }
+ catch(...) { return S_FALSE; }
+}
+
+HRESULT CEncoder::SetCoderProperties(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties)
+{
+ for(UInt32 i = 0; i < numProperties; i++)
+ {
+ const PROPVARIANT &property = properties[i];
+ switch(propIDs[i])
+ {
+ case NCoderPropID::kNumPasses:
+ {
+ if (property.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 numPasses = property.ulVal;
+ if (numPasses == 0)
+ numPasses = 1;
+ if (numPasses > kNumPassesMax)
+ numPasses = kNumPassesMax;
+ NumPasses = numPasses;
+ m_OptimizeNumTables = (NumPasses > 1);
+ break;
+ }
+ case NCoderPropID::kDictionarySize:
+ {
+ if (property.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 dictionary = property.ulVal / kBlockSizeStep;
+ if (dictionary < kBlockSizeMultMin)
+ dictionary = kBlockSizeMultMin;
+ else if (dictionary > kBlockSizeMultMax)
+ dictionary = kBlockSizeMultMax;
+ m_BlockSizeMult = dictionary;
+ break;
+ }
+ case NCoderPropID::kNumThreads:
+ {
+ #ifdef COMPRESS_BZIP2_MT
+ if (property.vt != VT_UI4)
+ return E_INVALIDARG;
+ NumThreads = property.ulVal;
+ if (NumThreads < 1)
+ NumThreads = 1;
+ #endif
+ break;
+ }
+ default:
+ return E_INVALIDARG;
+ }
+ }
+ return S_OK;
+}
+
+#ifdef COMPRESS_BZIP2_MT
+STDMETHODIMP CEncoder::SetNumberOfThreads(UInt32 numThreads)
+{
+ NumThreads = numThreads;
+ if (NumThreads < 1)
+ NumThreads = 1;
+ return S_OK;
+}
+#endif
+
+}}
diff --git a/CPP/7zip/Compress/BZip2/BZip2Encoder.h b/CPP/7zip/Compress/BZip2/BZip2Encoder.h
new file mode 100755
index 00000000..62b255d4
--- /dev/null
+++ b/CPP/7zip/Compress/BZip2/BZip2Encoder.h
@@ -0,0 +1,246 @@
+// Compress/BZip2/Encoder.h
+
+#ifndef __COMPRESS_BZIP2_ENCODER_H
+#define __COMPRESS_BZIP2_ENCODER_H
+
+#include "../../ICoder.h"
+#include "../../../Common/MyCom.h"
+#include "../../Common/MSBFEncoder.h"
+#include "../../Common/InBuffer.h"
+#include "../../Common/OutBuffer.h"
+#include "BZip2Const.h"
+#include "BZip2CRC.h"
+
+#ifdef COMPRESS_BZIP2_MT
+#include "../../../Windows/Thread.h"
+#include "../../../Windows/Synchronization.h"
+#endif
+
+namespace NCompress {
+namespace NBZip2 {
+
+class CMsbfEncoderTemp
+{
+ UInt32 m_Pos;
+ int m_BitPos;
+ Byte m_CurByte;
+ Byte *Buffer;
+public:
+ void SetStream(Byte *buffer) { Buffer = buffer; }
+ Byte *GetStream() const { return Buffer; }
+
+ void Init()
+ {
+ m_Pos = 0;
+ m_BitPos = 8;
+ m_CurByte = 0;
+ }
+
+ void Flush()
+ {
+ if(m_BitPos < 8)
+ WriteBits(0, m_BitPos);
+ }
+
+ void WriteBits(UInt32 value, int numBits)
+ {
+ while(numBits > 0)
+ {
+ int numNewBits = MyMin(numBits, m_BitPos);
+ numBits -= numNewBits;
+
+ m_CurByte <<= numNewBits;
+ UInt32 newBits = value >> numBits;
+ m_CurByte |= Byte(newBits);
+ value -= (newBits << numBits);
+
+ m_BitPos -= numNewBits;
+
+ if (m_BitPos == 0)
+ {
+ Buffer[m_Pos++] = m_CurByte;
+ m_BitPos = 8;
+ }
+ }
+ }
+
+ UInt32 GetBytePos() const { return m_Pos ; }
+ UInt32 GetPos() const { return m_Pos * 8 + (8 - m_BitPos); }
+ Byte GetCurByte() const { return m_CurByte; }
+ void SetPos(UInt32 bitPos)
+ {
+ m_Pos = bitPos / 8;
+ m_BitPos = 8 - (bitPos & 7);
+ }
+ void SetCurState(UInt32 bitPos, Byte curByte)
+ {
+ m_BitPos = 8 - bitPos;
+ m_CurByte = curByte;
+ }
+};
+
+class CEncoder;
+
+const int kNumPassesMax = 10;
+
+class CThreadInfo
+{
+public:
+ Byte *m_Block;
+private:
+ Byte *m_MtfArray;
+ Byte *m_TempArray;
+ UInt32 *m_BlockSorterIndex;
+
+ CMsbfEncoderTemp *m_OutStreamCurrent;
+
+ Byte Lens[kNumTablesMax][kMaxAlphaSize];
+ UInt32 Freqs[kNumTablesMax][kMaxAlphaSize];
+ UInt32 Codes[kNumTablesMax][kMaxAlphaSize];
+
+ Byte m_Selectors[kNumSelectorsMax];
+
+ UInt32 m_CRCs[1 << kNumPassesMax];
+ UInt32 m_NumCrcs;
+
+ int m_BlockIndex;
+
+ void FinishStream(bool needLeave);
+
+ void WriteBits2(UInt32 value, UInt32 numBits);
+ void WriteByte2(Byte b);
+ void WriteBit2(bool v);
+ void WriteCRC2(UInt32 v);
+
+ void EncodeBlock(const Byte *block, UInt32 blockSize);
+ UInt32 EncodeBlockWithHeaders(const Byte *block, UInt32 blockSize);
+ void EncodeBlock2(const Byte *block, UInt32 blockSize, UInt32 numPasses);
+public:
+ bool m_OptimizeNumTables;
+ CEncoder *Encoder;
+ #ifdef COMPRESS_BZIP2_MT
+ NWindows::CThread Thread;
+
+ NWindows::NSynchronization::CAutoResetEvent StreamWasFinishedEvent;
+ NWindows::NSynchronization::CAutoResetEvent WaitingWasStartedEvent;
+
+ // it's not member of this thread. We just need one event per thread
+ NWindows::NSynchronization::CAutoResetEvent CanWriteEvent;
+
+ UInt64 m_PackSize;
+
+ Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size.
+ #endif
+
+ CThreadInfo(): m_BlockSorterIndex(0), m_Block(0) {}
+ ~CThreadInfo() { Free(); }
+ bool Create();
+ void Free();
+
+ HRESULT EncodeBlock3(UInt32 blockSize);
+ DWORD ThreadFunc();
+};
+
+class CEncoder :
+ public ICompressCoder,
+ public ICompressSetCoderProperties,
+ #ifdef COMPRESS_BZIP2_MT
+ public ICompressSetCoderMt,
+ #endif
+ public CMyUnknownImp
+{
+ UInt32 m_BlockSizeMult;
+ bool m_OptimizeNumTables;
+
+ UInt32 m_NumPassesPrev;
+
+ UInt32 m_NumThreadsPrev;
+public:
+ CInBuffer m_InStream;
+ Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size.
+ NStream::NMSBF::CEncoder<COutBuffer> m_OutStream;
+ UInt32 NumPasses;
+ CBZip2CombinedCRC CombinedCRC;
+
+ #ifdef COMPRESS_BZIP2_MT
+ CThreadInfo *ThreadsInfo;
+ NWindows::NSynchronization::CCriticalSection CS;
+ UInt32 NumThreads;
+ bool MtMode;
+ UInt32 NextBlockIndex;
+
+ bool CloseThreads;
+ bool StreamWasFinished;
+ NWindows::NSynchronization::CManualResetEvent CanStartWaitingEvent;
+
+ HRESULT Result;
+ ICompressProgressInfo *Progress;
+ #else
+ CThreadInfo ThreadsInfo;
+ #endif
+
+ UInt32 ReadRleBlock(Byte *buffer);
+ void WriteBytes(const Byte *data, UInt32 sizeInBits, Byte lastByte);
+
+ void WriteBits(UInt32 value, UInt32 numBits);
+ void WriteByte(Byte b);
+ void WriteBit(bool v);
+ void WriteCRC(UInt32 v);
+
+ #ifdef COMPRESS_BZIP2_MT
+ bool Create();
+ void Free();
+ #endif
+
+public:
+ CEncoder();
+ #ifdef COMPRESS_BZIP2_MT
+ ~CEncoder();
+ #endif
+
+ HRESULT Flush() { return m_OutStream.Flush(); }
+
+ void ReleaseStreams()
+ {
+ m_InStream.ReleaseStream();
+ m_OutStream.ReleaseStream();
+ }
+
+ class CFlusher
+ {
+ CEncoder *_coder;
+ public:
+ bool NeedFlush;
+ CFlusher(CEncoder *coder): _coder(coder), NeedFlush(true) {}
+ ~CFlusher()
+ {
+ if (NeedFlush)
+ _coder->Flush();
+ _coder->ReleaseStreams();
+ }
+ };
+
+ #ifdef COMPRESS_BZIP2_MT
+ MY_UNKNOWN_IMP2(ICompressSetCoderMt, ICompressSetCoderProperties)
+ #else
+ MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
+ #endif
+
+ HRESULT CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties);
+
+ #ifdef COMPRESS_BZIP2_MT
+ STDMETHOD(SetNumberOfThreads)(UInt32 numThreads);
+ #endif
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Compress/BZip2/DllExports.cpp b/CPP/7zip/Compress/BZip2/DllExports.cpp
new file mode 100755
index 00000000..57a3ae65
--- /dev/null
+++ b/CPP/7zip/Compress/BZip2/DllExports.cpp
@@ -0,0 +1,93 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#ifdef _WIN32
+#include "Common/Alloc.h"
+#endif
+
+#include "BZip2Encoder.h"
+#include "BZip2Decoder.h"
+
+// {23170F69-40C1-278B-0402-020000000000}
+DEFINE_GUID(CLSID_CCompressBZip2Decoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+// {23170F69-40C1-278B-0402-020000000100}
+DEFINE_GUID(CLSID_CCompressBZip2Encoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00);
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ #ifdef _WIN32
+ if (dwReason == DLL_PROCESS_ATTACH)
+ SetLargePageSize();
+ #endif
+ 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_CCompressBZip2Decoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder = (ICompressCoder *)new NCompress::NBZip2::CDecoder;
+ }
+ else if (*clsid == CLSID_CCompressBZip2Encoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder = (ICompressCoder *)new NCompress::NBZip2::CEncoder;
+ }
+ else
+ return CLASS_E_CLASSNOTAVAILABLE;
+ *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, 0x02, 0x02 };
+ if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NMethodPropID::kName:
+ if ((value->bstrVal = ::SysAllocString(L"BZip2")) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ case NMethodPropID::kDecoder:
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CCompressBZip2Decoder, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ case NMethodPropID::kEncoder:
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CCompressBZip2Encoder, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ return S_OK;
+}
diff --git a/CPP/7zip/Compress/BZip2/StdAfx.cpp b/CPP/7zip/Compress/BZip2/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Compress/BZip2/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Compress/BZip2/StdAfx.h b/CPP/7zip/Compress/BZip2/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Compress/BZip2/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Compress/BZip2/makefile b/CPP/7zip/Compress/BZip2/makefile
new file mode 100755
index 00000000..9e8cbdcb
--- /dev/null
+++ b/CPP/7zip/Compress/BZip2/makefile
@@ -0,0 +1,56 @@
+PROG = BZip2.dll
+DEF_FILE = ../Codec.def
+CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_BZIP2_MT
+LIBS = $(LIBS) oleaut32.lib
+
+BZIP2_OBJS = \
+ $O\DllExports.obj \
+ $O\BZip2CRC.obj \
+
+BZIP2_OPT_OBJS = \
+ $O\BZip2Decoder.obj \
+ $O\BZip2Encoder.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+
+WIN_OBJS = \
+ $O\Synchronization.obj
+
+7ZIP_COMMON_OBJS = \
+ $O\InBuffer.obj \
+ $O\OutBuffer.obj \
+
+C_OBJS = \
+ $O\Sort.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(BZIP2_OBJS) \
+ $(BZIP2_OPT_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $O\BlockSort.obj \
+ $(C_OBJS) \
+ $O\HuffmanEncode.obj \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(BZIP2_OBJS): $(*B).cpp
+ $(COMPL)
+$(BZIP2_OPT_OBJS): $(*B).cpp
+ $(COMPL_O2)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$O\BlockSort.obj: ../BWT/$(*B).cpp
+ $(COMPL_O2)
+$(C_OBJS): ../../../../C/$(*B).c
+ $(COMPL_O2)
+$O\HuffmanEncode.obj: ../../../../C/Compress/Huffman/$(*B).c
+ $(COMPL_O2)
diff --git a/CPP/7zip/Compress/BZip2/resource.rc b/CPP/7zip/Compress/BZip2/resource.rc
new file mode 100755
index 00000000..c5bea782
--- /dev/null
+++ b/CPP/7zip/Compress/BZip2/resource.rc
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("BZip2 Codec", "BZip2")
diff --git a/CPP/7zip/Compress/BZip2Original/BZip2Decoder.cpp b/CPP/7zip/Compress/BZip2Original/BZip2Decoder.cpp
new file mode 100755
index 00000000..5fb77d01
--- /dev/null
+++ b/CPP/7zip/Compress/BZip2Original/BZip2Decoder.cpp
@@ -0,0 +1,131 @@
+// BZip2Decoder.cpp
+
+#include "StdAfx.h"
+
+#include "BZip2Decoder.h"
+
+#include "../../../Common/Alloc.h"
+#include "Original/bzlib.h"
+
+namespace NCompress {
+namespace NBZip2 {
+
+static const UInt32 kBufferSize = (1 << 20);
+
+CDecoder::~CDecoder()
+{
+ BigFree(m_InBuffer);
+}
+
+struct CBZip2Decompressor: public bz_stream
+{
+ int Init(int verbosity, int small) { return BZ2_bzDecompressInit(this, verbosity, small); }
+ int Decompress() { return BZ2_bzDecompress(this); }
+ int End() { return BZ2_bzDecompressEnd(this); }
+ UInt64 GetTotalIn() const { return (UInt64(total_in_hi32) << 32) + total_in_lo32; }
+ UInt64 GetTotalOut() const { return (UInt64(total_out_hi32) << 32) + total_out_lo32; }
+};
+
+class CBZip2DecompressorReleaser
+{
+ CBZip2Decompressor *m_Decompressor;
+public:
+ CBZip2DecompressorReleaser(CBZip2Decompressor *decompressor): m_Decompressor(decompressor) {}
+ void Diable() { m_Decompressor = NULL; }
+ ~CBZip2DecompressorReleaser() { if (m_Decompressor != NULL) m_Decompressor->End(); }
+};
+
+STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ m_InSize = 0;
+ if (m_InBuffer == 0)
+ {
+ m_InBuffer = (Byte *)BigAlloc(kBufferSize * 2);
+ if (m_InBuffer == 0)
+ return E_OUTOFMEMORY;
+ }
+ Byte *outBuffer = m_InBuffer + kBufferSize;
+
+ CBZip2Decompressor bzStream;
+ bzStream.bzalloc = NULL;
+ bzStream.bzfree = NULL;
+ bzStream.opaque = NULL;
+
+ int result = bzStream.Init(0, 0);
+ switch(result)
+ {
+ case BZ_OK:
+ break;
+ case BZ_MEM_ERROR:
+ return E_OUTOFMEMORY;
+ default:
+ return E_FAIL;
+ }
+ CBZip2DecompressorReleaser releaser(&bzStream);
+ bzStream.avail_in = 0;
+ for (;;)
+ {
+ if (bzStream.avail_in == 0)
+ {
+ bzStream.next_in = (char *)m_InBuffer;
+ UInt32 processedSize;
+ RINOK(inStream->Read(m_InBuffer, kBufferSize, &processedSize));
+ bzStream.avail_in = processedSize;
+ }
+
+ bzStream.next_out = (char *)outBuffer;
+ bzStream.avail_out = kBufferSize;
+ result = bzStream.Decompress();
+ UInt32 numBytesToWrite = kBufferSize - bzStream.avail_out;
+ if (numBytesToWrite > 0)
+ {
+ UInt32 processedSize;
+ RINOK(outStream->Write(outBuffer, numBytesToWrite, &processedSize));
+ if (numBytesToWrite != processedSize)
+ return E_FAIL;
+ }
+
+ if (result == BZ_STREAM_END)
+ break;
+ switch(result)
+ {
+ case BZ_DATA_ERROR:
+ case BZ_DATA_ERROR_MAGIC:
+ return S_FALSE;
+ case BZ_OK:
+ break;
+ case BZ_MEM_ERROR:
+ return E_OUTOFMEMORY;
+ default:
+ return E_FAIL;
+ }
+ if (progress != NULL)
+ {
+ UInt64 totalIn = bzStream.GetTotalIn();
+ UInt64 totalOut = bzStream.GetTotalOut();
+ RINOK(progress->SetRatioInfo(&totalIn, &totalOut));
+ }
+ }
+ m_InSize = bzStream.GetTotalIn();
+ 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(...) { return S_FALSE; }
+}
+
+STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
+{
+ if (value == NULL)
+ return E_INVALIDARG;
+ *value = m_InSize;
+ return S_OK;
+}
+
+}}
diff --git a/CPP/7zip/Compress/BZip2Original/BZip2Decoder.h b/CPP/7zip/Compress/BZip2Original/BZip2Decoder.h
new file mode 100755
index 00000000..e41f730f
--- /dev/null
+++ b/CPP/7zip/Compress/BZip2Original/BZip2Decoder.h
@@ -0,0 +1,38 @@
+// Compress/BZip2/Decoder.h
+
+#ifndef __COMPRESS_BZIP2_DECODER_H
+#define __COMPRESS_BZIP2_DECODER_H
+
+#include "../../ICoder.h"
+#include "../../../Common/MyCom.h"
+
+namespace NCompress {
+namespace NBZip2 {
+
+class CDecoder :
+ public ICompressCoder,
+ public ICompressGetInStreamProcessedSize,
+ public CMyUnknownImp
+{
+ Byte *m_InBuffer;
+ UInt64 m_InSize;
+public:
+ CDecoder(): m_InBuffer(0), m_InSize(0) {};
+ ~CDecoder();
+
+ MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
+
+ 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(GetInStreamProcessedSize)(UInt64 *value);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Compress/BZip2Original/BZip2Encoder.cpp b/CPP/7zip/Compress/BZip2Original/BZip2Encoder.cpp
new file mode 100755
index 00000000..bcd7dec0
--- /dev/null
+++ b/CPP/7zip/Compress/BZip2Original/BZip2Encoder.cpp
@@ -0,0 +1,120 @@
+// BZip2Encoder.cpp
+
+#include "StdAfx.h"
+
+#include "BZip2Encoder.h"
+
+#include "../../../Common/Alloc.h"
+#include "Original/bzlib.h"
+
+namespace NCompress {
+namespace NBZip2 {
+
+static const UInt32 kBufferSize = (1 << 20);
+
+CEncoder::~CEncoder()
+{
+ BigFree(m_InBuffer);
+}
+
+struct CBZip2Compressor: public bz_stream
+{
+ int Init(int blockSize100k, int verbosity, int small)
+ { return BZ2_bzCompressInit(this, blockSize100k, verbosity, small); }
+ int Compress(int action ) { return BZ2_bzCompress(this, action ); }
+ int End() { return BZ2_bzCompressEnd(this); }
+ UInt64 GetTotalIn() const { return (UInt64(total_in_hi32) << 32) + total_in_lo32; }
+ UInt64 GetTotalOut() const { return (UInt64(total_out_hi32) << 32) + total_out_lo32; }
+};
+
+class CBZip2CompressorReleaser
+{
+ CBZip2Compressor *m_Compressor;
+public:
+ CBZip2CompressorReleaser(CBZip2Compressor *compressor): m_Compressor(compressor) {}
+ void Disable() { m_Compressor = NULL; }
+ ~CBZip2CompressorReleaser() { if (m_Compressor != NULL) m_Compressor->End(); }
+};
+
+
+STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ if (m_InBuffer == 0)
+ {
+ m_InBuffer = (Byte *)BigAlloc(kBufferSize * 2);
+ if (m_InBuffer == 0)
+ return E_OUTOFMEMORY;
+ }
+ Byte *outBuffer = m_InBuffer + kBufferSize;
+
+ CBZip2Compressor bzStream;
+ bzStream.bzalloc = NULL;
+ bzStream.bzfree = NULL;
+ bzStream.opaque = NULL;
+
+ int result = bzStream.Init(9, 0, 0);
+ switch(result)
+ {
+ case BZ_OK:
+ break;
+ case BZ_MEM_ERROR:
+ return E_OUTOFMEMORY;
+ default:
+ return E_FAIL;
+ }
+ CBZip2CompressorReleaser releaser(&bzStream);
+ bzStream.avail_in = 0;
+ for (;;)
+ {
+ if (bzStream.avail_in == 0)
+ {
+ bzStream.next_in = (char *)m_InBuffer;
+ UInt32 processedSize;
+ RINOK(inStream->Read(m_InBuffer, kBufferSize, &processedSize));
+ bzStream.avail_in = processedSize;
+ }
+
+ bzStream.next_out = (char *)outBuffer;
+ bzStream.avail_out = kBufferSize;
+ bool askFinish = (bzStream.avail_in == 0);
+ result = bzStream.Compress(askFinish ? BZ_FINISH : BZ_RUN);
+ UInt32 numBytesToWrite = kBufferSize - bzStream.avail_out;
+ if (numBytesToWrite > 0)
+ {
+ UInt32 processedSize;
+ RINOK(outStream->Write(outBuffer, numBytesToWrite, &processedSize));
+ if (numBytesToWrite != processedSize)
+ return E_FAIL;
+ }
+
+ if (result == BZ_STREAM_END)
+ break;
+ switch(result)
+ {
+ case BZ_RUN_OK:
+ if (!askFinish)
+ break;
+ return E_FAIL;
+ case BZ_FINISH_OK:
+ if (askFinish)
+ break;
+ return E_FAIL;
+ case BZ_MEM_ERROR:
+ return E_OUTOFMEMORY;
+ default:
+ return E_FAIL;
+ }
+ if (progress != NULL)
+ {
+ UInt64 totalIn = bzStream.GetTotalIn();
+ UInt64 totalOut = bzStream.GetTotalOut();
+ RINOK(progress->SetRatioInfo(&totalIn, &totalOut));
+ }
+ }
+ // result = bzStream.End();
+ return S_OK;
+}
+
+}}
diff --git a/CPP/7zip/Compress/BZip2Original/BZip2Encoder.h b/CPP/7zip/Compress/BZip2Original/BZip2Encoder.h
new file mode 100755
index 00000000..c451a08d
--- /dev/null
+++ b/CPP/7zip/Compress/BZip2Original/BZip2Encoder.h
@@ -0,0 +1,30 @@
+// Compress/BZip2/Encoder.h
+
+#ifndef __COMPRESS_BZIP2_ENCODER_H
+#define __COMPRESS_BZIP2_ENCODER_H
+
+#include "../../ICoder.h"
+#include "../../../Common/MyCom.h"
+
+namespace NCompress {
+namespace NBZip2 {
+
+class CEncoder :
+ public ICompressCoder,
+ public CMyUnknownImp
+{
+ Byte *m_InBuffer;
+public:
+ CEncoder(): m_InBuffer(0) {};
+ ~CEncoder();
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Compress/BZip2Original/BZip2Error.cpp b/CPP/7zip/Compress/BZip2Original/BZip2Error.cpp
new file mode 100755
index 00000000..c8a912dc
--- /dev/null
+++ b/CPP/7zip/Compress/BZip2Original/BZip2Error.cpp
@@ -0,0 +1,10 @@
+#include "StdAfx.h"
+
+#include "Original/bzlib.h"
+
+extern "C"
+
+void bz_internal_error (int errcode)
+{
+ throw "error";
+} \ No newline at end of file
diff --git a/CPP/7zip/Compress/BZip2Original/DllExports.cpp b/CPP/7zip/Compress/BZip2Original/DllExports.cpp
new file mode 100755
index 00000000..572d1fda
--- /dev/null
+++ b/CPP/7zip/Compress/BZip2Original/DllExports.cpp
@@ -0,0 +1,86 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+
+#include "BZip2Encoder.h"
+#include "BZip2Decoder.h"
+
+// {23170F69-40C1-278B-0402-020000000000}
+DEFINE_GUID(CLSID_CCompressBZip2Decoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+// {23170F69-40C1-278B-0402-020000000100}
+DEFINE_GUID(CLSID_CCompressBZip2Encoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 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_CCompressBZip2Decoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder = (ICompressCoder *)new NCompress::NBZip2::CDecoder;
+ }
+ else if (*clsid == CLSID_CCompressBZip2Encoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder = (ICompressCoder *)new NCompress::NBZip2::CEncoder;
+ }
+ else
+ return CLASS_E_CLASSNOTAVAILABLE;
+ *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, 0x02, 0x02 };
+ if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NMethodPropID::kName:
+ if ((value->bstrVal = ::SysAllocString(L"BZip2")) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ case NMethodPropID::kDecoder:
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CCompressBZip2Decoder, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ case NMethodPropID::kEncoder:
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CCompressBZip2Encoder, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ return S_OK;
+}
diff --git a/CPP/7zip/Compress/BZip2Original/StdAfx.cpp b/CPP/7zip/Compress/BZip2Original/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Compress/BZip2Original/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Compress/BZip2Original/StdAfx.h b/CPP/7zip/Compress/BZip2Original/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Compress/BZip2Original/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Compress/Branch/ARM.cpp b/CPP/7zip/Compress/Branch/ARM.cpp
new file mode 100755
index 00000000..0918cfb7
--- /dev/null
+++ b/CPP/7zip/Compress/Branch/ARM.cpp
@@ -0,0 +1,16 @@
+// ARM.cpp
+
+#include "StdAfx.h"
+#include "ARM.h"
+
+#include "../../../../C/Compress/Branch/BranchARM.c"
+
+UInt32 CBC_ARM_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::ARM_Convert(data, size, _bufferPos, 1);
+}
+
+UInt32 CBC_ARM_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::ARM_Convert(data, size, _bufferPos, 0);
+}
diff --git a/CPP/7zip/Compress/Branch/ARM.h b/CPP/7zip/Compress/Branch/ARM.h
new file mode 100755
index 00000000..5561299b
--- /dev/null
+++ b/CPP/7zip/Compress/Branch/ARM.h
@@ -0,0 +1,10 @@
+// ARM.h
+
+#ifndef __ARM_H
+#define __ARM_H
+
+#include "BranchCoder.h"
+
+MyClassA(BC_ARM, 0x05, 1)
+
+#endif
diff --git a/CPP/7zip/Compress/Branch/ARMThumb.cpp b/CPP/7zip/Compress/Branch/ARMThumb.cpp
new file mode 100755
index 00000000..50189adb
--- /dev/null
+++ b/CPP/7zip/Compress/Branch/ARMThumb.cpp
@@ -0,0 +1,16 @@
+// ARMThumb.cpp
+
+#include "StdAfx.h"
+#include "ARMThumb.h"
+
+#include "../../../../C/Compress/Branch/BranchARMThumb.c"
+
+UInt32 CBC_ARMThumb_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::ARMThumb_Convert(data, size, _bufferPos, 1);
+}
+
+UInt32 CBC_ARMThumb_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::ARMThumb_Convert(data, size, _bufferPos, 0);
+}
diff --git a/CPP/7zip/Compress/Branch/ARMThumb.h b/CPP/7zip/Compress/Branch/ARMThumb.h
new file mode 100755
index 00000000..601e40bf
--- /dev/null
+++ b/CPP/7zip/Compress/Branch/ARMThumb.h
@@ -0,0 +1,10 @@
+// ARMThumb.h
+
+#ifndef __ARMTHUMB_H
+#define __ARMTHUMB_H
+
+#include "BranchCoder.h"
+
+MyClassA(BC_ARMThumb, 0x07, 1)
+
+#endif
diff --git a/CPP/7zip/Compress/Branch/Branch.dsp b/CPP/7zip/Compress/Branch/Branch.dsp
new file mode 100755
index 00000000..220cb8ab
--- /dev/null
+++ b/CPP/7zip/Compress/Branch/Branch.dsp
@@ -0,0 +1,298 @@
+# Microsoft Developer Studio Project File - Name="Branch" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=Branch - 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 "Branch.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 "Branch.mak" CFG="Branch - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Branch - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Branch - 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)" == "Branch - 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 "BRANCH_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O2 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BRANCH_EXPORTS" /FD /c
+# SUBTRACT CPP /YX /Yc /Yu
+# 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\Branch.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Branch - 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 "BRANCH_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 "BRANCH_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\Codecs\Branch.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "Branch - Win32 Release"
+# Name "Branch - 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 "Methods"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\ARM.cpp
+
+!IF "$(CFG)" == "Branch - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Branch - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\ARM.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ARMThumb.cpp
+
+!IF "$(CFG)" == "Branch - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Branch - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\ARMThumb.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\BranchCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\BranchCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\BranchTypes.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\BranchX86.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\IA64.cpp
+
+!IF "$(CFG)" == "Branch - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Branch - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\IA64.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\PPC.cpp
+
+!IF "$(CFG)" == "Branch - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Branch - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\PPC.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\SPARC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\SPARC.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\x86.cpp
+
+!IF "$(CFG)" == "Branch - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Branch - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\x86.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\x86_2.cpp
+
+!IF "$(CFG)" == "Branch - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Branch - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\x86_2.h
+# End Source File
+# End Group
+# Begin Group "Stream"
+
+# 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\OutBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.h
+# End Source File
+# End Group
+# Begin Group "RangeCoder"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoderBit.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
+# End Target
+# End Project
diff --git a/CPP/7zip/Compress/Branch/Branch.dsw b/CPP/7zip/Compress/Branch/Branch.dsw
new file mode 100755
index 00000000..841c85a3
--- /dev/null
+++ b/CPP/7zip/Compress/Branch/Branch.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Branch"=.\Branch.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Compress/Branch/BranchCoder.cpp b/CPP/7zip/Compress/Branch/BranchCoder.cpp
new file mode 100755
index 00000000..8d25f0d5
--- /dev/null
+++ b/CPP/7zip/Compress/Branch/BranchCoder.cpp
@@ -0,0 +1,18 @@
+// BranchCoder.cpp
+
+#include "StdAfx.h"
+#include "BranchCoder.h"
+
+STDMETHODIMP CBranchConverter::Init()
+{
+ _bufferPos = 0;
+ SubInit();
+ return S_OK;
+}
+
+STDMETHODIMP_(UInt32) CBranchConverter::Filter(Byte *data, UInt32 size)
+{
+ UInt32 processedSize = SubFilter(data, size);
+ _bufferPos += processedSize;
+ return processedSize;
+}
diff --git a/CPP/7zip/Compress/Branch/BranchCoder.h b/CPP/7zip/Compress/Branch/BranchCoder.h
new file mode 100755
index 00000000..4b53b6cb
--- /dev/null
+++ b/CPP/7zip/Compress/Branch/BranchCoder.h
@@ -0,0 +1,54 @@
+// BranchCoder.h
+
+#ifndef __BRANCH_CODER_H
+#define __BRANCH_CODER_H
+
+#include "Common/MyCom.h"
+#include "Common/Types.h"
+#include "Common/Alloc.h"
+
+#include "../../ICoder.h"
+
+class CBranchConverter:
+ public ICompressFilter,
+ public CMyUnknownImp
+{
+protected:
+ UInt32 _bufferPos;
+ virtual void SubInit() {}
+ virtual UInt32 SubFilter(Byte *data, UInt32 size) = 0;
+public:
+ MY_UNKNOWN_IMP;
+ STDMETHOD(Init)();
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+};
+
+#define MyClassEncoderA(Name) class C ## Name: public CBranchConverter \
+ { public: UInt32 SubFilter(Byte *data, UInt32 size); };
+
+#define MyClassDecoderA(Name) class C ## Name: public CBranchConverter \
+ { public: UInt32 SubFilter(Byte *data, UInt32 size); };
+
+#define MyClassEncoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \
+ { public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT};
+
+#define MyClassDecoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \
+ { public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT};
+
+#define MyClass2b(Name, id, subId, encodingId) \
+DEFINE_GUID(CLSID_CCompressConvert ## Name, \
+0x23170F69, 0x40C1, 0x278B, 0x03, 0x03, id, subId, 0x00, 0x00, encodingId, 0x00);
+
+#define MyClassA(Name, id, subId) \
+MyClass2b(Name ## _Encoder, id, subId, 0x01) \
+MyClassEncoderA(Name ## _Encoder) \
+MyClass2b(Name ## _Decoder, id, subId, 0x00) \
+MyClassDecoderA(Name ## _Decoder)
+
+#define MyClassB(Name, id, subId, ADD_ITEMS, ADD_INIT) \
+MyClass2b(Name ## _Encoder, id, subId, 0x01) \
+MyClassEncoderB(Name ## _Encoder, ADD_ITEMS, ADD_INIT) \
+MyClass2b(Name ## _Decoder, id, subId, 0x00) \
+MyClassDecoderB(Name ## _Decoder, ADD_ITEMS, ADD_INIT)
+
+#endif
diff --git a/CPP/7zip/Compress/Branch/DllExports.cpp b/CPP/7zip/Compress/Branch/DllExports.cpp
new file mode 100755
index 00000000..e7928f75
--- /dev/null
+++ b/CPP/7zip/Compress/Branch/DllExports.cpp
@@ -0,0 +1,152 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+
+#include "x86.h"
+#include "PPC.h"
+#include "IA64.h"
+#include "ARM.h"
+#include "ARMThumb.h"
+#include "x86_2.h"
+#include "SPARC.h"
+
+#define MY_CreateClass0(n) \
+if (*clsid == CLSID_CCompressConvert ## n ## _Encoder) { \
+ if (!correctInterface) \
+ return E_NOINTERFACE; \
+ filter = (ICompressFilter *)new C ## n ## _Encoder(); \
+ } else if (*clsid == CLSID_CCompressConvert ## n ## _Decoder){ \
+ if (!correctInterface) \
+ return E_NOINTERFACE; \
+ filter = (ICompressFilter *)new C ## n ## _Decoder(); \
+ }
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /*lpReserved*/)
+{
+ return TRUE;
+}
+
+STDAPI CreateObject(
+ const GUID *clsid,
+ const GUID *interfaceID,
+ void **outObject)
+{
+ COM_TRY_BEGIN
+ *outObject = 0;
+ int correctInterface = (*interfaceID == IID_ICompressFilter);
+ CMyComPtr<ICompressFilter> filter;
+ MY_CreateClass0(BCJ_x86)
+ else
+ MY_CreateClass0(BC_ARM)
+ else
+ MY_CreateClass0(BC_PPC_B)
+ else
+ MY_CreateClass0(BC_IA64)
+ else
+ MY_CreateClass0(BC_ARMThumb)
+ else
+ MY_CreateClass0(BC_SPARC)
+ else
+ {
+ CMyComPtr<ICompressCoder2> coder2;
+ correctInterface = (*interfaceID == IID_ICompressCoder2);
+ if (*clsid == CLSID_CCompressConvertBCJ2_x86_Encoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder2 = (ICompressCoder2 *)new CBCJ2_x86_Encoder();
+ }
+ else if (*clsid == CLSID_CCompressConvertBCJ2_x86_Decoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder2 = (ICompressCoder2 *)new CBCJ2_x86_Decoder();
+ }
+ else
+ return CLASS_E_CLASSNOTAVAILABLE;
+ *outObject = coder2.Detach();
+ return S_OK;
+ }
+ *outObject = filter.Detach();
+ return S_OK;
+
+ COM_TRY_END
+}
+
+struct CBranchMethodItem
+{
+ char ID[4];
+ const wchar_t *UserName;
+ const GUID *Decoder;
+ const GUID *Encoder;
+ UINT32 NumInStreams;
+};
+
+#define METHOD_ITEM(Name, id, subId, UserName, NumInStreams) \
+ { { 0x03, 0x03, id, subId }, UserName, \
+ &CLSID_CCompressConvert ## Name ## _Decoder, \
+ &CLSID_CCompressConvert ## Name ## _Encoder, NumInStreams }
+
+
+static CBranchMethodItem g_Methods[] =
+{
+ METHOD_ITEM(BCJ_x86, 0x01, 0x03, L"BCJ", 1),
+ METHOD_ITEM(BCJ2_x86, 0x01, 0x1B, L"BCJ2", 4),
+ METHOD_ITEM(BC_PPC_B, 0x02, 0x05, L"BC_PPC_B", 1),
+ // METHOD_ITEM(BC_Alpha, 0x03, 1, L"BC_Alpha", 1),
+ METHOD_ITEM(BC_IA64, 0x04, 1, L"BC_IA64", 1),
+ METHOD_ITEM(BC_ARM, 0x05, 1, L"BC_ARM", 1),
+ // METHOD_ITEM(BC_M68_B, 0x06, 5, L"BC_M68_B", 1),
+ METHOD_ITEM(BC_ARMThumb, 0x07, 1, L"BC_ARMThumb", 1),
+ METHOD_ITEM(BC_SPARC, 0x08, 0x05, L"BC_SPARC", 1)
+};
+
+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 CBranchMethodItem &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;
+ case NMethodPropID::kEncoder:
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)method.Encoder, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ case NMethodPropID::kInStreams:
+ {
+ if (method.NumInStreams != 1)
+ {
+ value->vt = VT_UI4;
+ value->ulVal = method.NumInStreams;
+ }
+ return S_OK;
+ }
+ }
+ return S_OK;
+}
diff --git a/CPP/7zip/Compress/Branch/IA64.cpp b/CPP/7zip/Compress/Branch/IA64.cpp
new file mode 100755
index 00000000..4d57916c
--- /dev/null
+++ b/CPP/7zip/Compress/Branch/IA64.cpp
@@ -0,0 +1,16 @@
+// IA64.cpp
+
+#include "StdAfx.h"
+#include "IA64.h"
+
+#include "../../../../C/Compress/Branch/BranchIA64.c"
+
+UInt32 CBC_IA64_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::IA64_Convert(data, size, _bufferPos, 1);
+}
+
+UInt32 CBC_IA64_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::IA64_Convert(data, size, _bufferPos, 0);
+}
diff --git a/CPP/7zip/Compress/Branch/IA64.h b/CPP/7zip/Compress/Branch/IA64.h
new file mode 100755
index 00000000..7fe715ed
--- /dev/null
+++ b/CPP/7zip/Compress/Branch/IA64.h
@@ -0,0 +1,10 @@
+// IA64.h
+
+#ifndef __IA64_H
+#define __IA64_H
+
+#include "BranchCoder.h"
+
+MyClassA(BC_IA64, 0x04, 1)
+
+#endif
diff --git a/CPP/7zip/Compress/Branch/PPC.cpp b/CPP/7zip/Compress/Branch/PPC.cpp
new file mode 100755
index 00000000..08c436e1
--- /dev/null
+++ b/CPP/7zip/Compress/Branch/PPC.cpp
@@ -0,0 +1,17 @@
+// PPC.cpp
+
+#include "StdAfx.h"
+#include "PPC.h"
+
+#include "Windows/Defs.h"
+#include "../../../../C/Compress/Branch/BranchPPC.c"
+
+UInt32 CBC_PPC_B_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::PPC_B_Convert(data, size, _bufferPos, 1);
+}
+
+UInt32 CBC_PPC_B_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::PPC_B_Convert(data, size, _bufferPos, 0);
+}
diff --git a/CPP/7zip/Compress/Branch/PPC.h b/CPP/7zip/Compress/Branch/PPC.h
new file mode 100755
index 00000000..a0e33444
--- /dev/null
+++ b/CPP/7zip/Compress/Branch/PPC.h
@@ -0,0 +1,10 @@
+// PPC.h
+
+#ifndef __PPC_H
+#define __PPC_H
+
+#include "BranchCoder.h"
+
+MyClassA(BC_PPC_B, 0x02, 5)
+
+#endif
diff --git a/CPP/7zip/Compress/Branch/SPARC.cpp b/CPP/7zip/Compress/Branch/SPARC.cpp
new file mode 100755
index 00000000..7a218fe4
--- /dev/null
+++ b/CPP/7zip/Compress/Branch/SPARC.cpp
@@ -0,0 +1,17 @@
+// SPARC.cpp
+
+#include "StdAfx.h"
+#include "SPARC.h"
+
+#include "Windows/Defs.h"
+#include "../../../../C/Compress/Branch/BranchSPARC.c"
+
+UInt32 CBC_SPARC_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::SPARC_Convert(data, size, _bufferPos, 1);
+}
+
+UInt32 CBC_SPARC_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::SPARC_Convert(data, size, _bufferPos, 0);
+}
diff --git a/CPP/7zip/Compress/Branch/SPARC.h b/CPP/7zip/Compress/Branch/SPARC.h
new file mode 100755
index 00000000..e0a682ef
--- /dev/null
+++ b/CPP/7zip/Compress/Branch/SPARC.h
@@ -0,0 +1,10 @@
+// SPARC.h
+
+#ifndef __SPARC_H
+#define __SPARC_H
+
+#include "BranchCoder.h"
+
+MyClassA(BC_SPARC, 0x08, 5)
+
+#endif
diff --git a/CPP/7zip/Compress/Branch/StdAfx.cpp b/CPP/7zip/Compress/Branch/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Compress/Branch/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Compress/Branch/StdAfx.h b/CPP/7zip/Compress/Branch/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Compress/Branch/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Compress/Branch/makefile b/CPP/7zip/Compress/Branch/makefile
new file mode 100755
index 00000000..6857d39f
--- /dev/null
+++ b/CPP/7zip/Compress/Branch/makefile
@@ -0,0 +1,48 @@
+PROG = Branch.dll
+DEF_FILE = ../Codec.def
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib
+
+BRANCH_OBJS = \
+ $O\DllExports.obj \
+
+BRANCH_OPT_OBJS = \
+ $O\ARM.obj \
+ $O\ARMThumb.obj \
+ $O\BranchCoder.obj \
+ $O\IA64.obj \
+ $O\PPC.obj \
+ $O\SPARC.obj \
+ $O\x86.obj \
+ $O\x86_2.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\InBuffer.obj \
+ $O\OutBuffer.obj \
+
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(BRANCH_OBJS) \
+ $(BRANCH_OPT_OBJS) \
+ $(COMMON_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $O\RangeCoderBit.obj \
+ $O\resource.res
+
+
+!include "../../../Build.mak"
+
+$(BRANCH_OBJS): $(*B).cpp
+ $(COMPL)
+$(BRANCH_OPT_OBJS): $(*B).cpp
+ $(COMPL_O2)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$O\RangeCoderBit.obj: ../RangeCoder/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/Compress/Branch/resource.rc b/CPP/7zip/Compress/Branch/resource.rc
new file mode 100755
index 00000000..5476d4fa
--- /dev/null
+++ b/CPP/7zip/Compress/Branch/resource.rc
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("Branch Filter", "Branch")
diff --git a/CPP/7zip/Compress/Branch/x86.cpp b/CPP/7zip/Compress/Branch/x86.cpp
new file mode 100755
index 00000000..60640d29
--- /dev/null
+++ b/CPP/7zip/Compress/Branch/x86.cpp
@@ -0,0 +1,18 @@
+// x86.cpp
+
+#include "StdAfx.h"
+#include "x86.h"
+
+#include "Windows/Defs.h"
+
+#include "../../../../C/Compress/Branch/BranchX86.c"
+
+UInt32 CBCJ_x86_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::x86_Convert(data, size, _bufferPos, &_prevMask, &_prevPos, 1);
+}
+
+UInt32 CBCJ_x86_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+ return ::x86_Convert(data, size, _bufferPos, &_prevMask, &_prevPos, 0);
+}
diff --git a/CPP/7zip/Compress/Branch/x86.h b/CPP/7zip/Compress/Branch/x86.h
new file mode 100755
index 00000000..f795e778
--- /dev/null
+++ b/CPP/7zip/Compress/Branch/x86.h
@@ -0,0 +1,19 @@
+// x86.h
+
+#ifndef __X86_H
+#define __X86_H
+
+#include "BranchCoder.h"
+#include "../../../../C/Compress/Branch/BranchX86.h"
+
+struct CBranch86
+{
+ UInt32 _prevMask;
+ UInt32 _prevPos;
+ void x86Init() { x86_Convert_Init(_prevMask, _prevPos); }
+};
+
+MyClassB(BCJ_x86, 0x01, 3, CBranch86 ,
+ virtual void SubInit() { x86Init(); })
+
+#endif
diff --git a/CPP/7zip/Compress/Branch/x86_2.cpp b/CPP/7zip/Compress/Branch/x86_2.cpp
new file mode 100755
index 00000000..ca37ab83
--- /dev/null
+++ b/CPP/7zip/Compress/Branch/x86_2.cpp
@@ -0,0 +1,412 @@
+// x86_2.cpp
+
+#include "StdAfx.h"
+#include "x86_2.h"
+
+#include "../../../Common/Alloc.h"
+
+static const int kBufferSize = 1 << 17;
+
+inline bool IsJcc(Byte b0, Byte b1)
+{
+ return (b0 == 0x0F && (b1 & 0xF0) == 0x80);
+}
+
+#ifndef EXTRACT_ONLY
+
+static bool inline Test86MSByte(Byte b)
+{
+ return (b == 0 || b == 0xFF);
+}
+
+bool CBCJ2_x86_Encoder::Create()
+{
+ if (!_mainStream.Create(1 << 16))
+ return false;
+ if (!_callStream.Create(1 << 20))
+ return false;
+ if (!_jumpStream.Create(1 << 20))
+ return false;
+ if (!_rangeEncoder.Create(1 << 20))
+ return false;
+ if (_buffer == 0)
+ {
+ _buffer = (Byte *)MidAlloc(kBufferSize);
+ if (_buffer == 0)
+ return false;
+ }
+ return true;
+}
+
+CBCJ2_x86_Encoder::~CBCJ2_x86_Encoder()
+{
+ ::MidFree(_buffer);
+}
+
+HRESULT CBCJ2_x86_Encoder::Flush()
+{
+ RINOK(_mainStream.Flush());
+ RINOK(_callStream.Flush());
+ RINOK(_jumpStream.Flush());
+ _rangeEncoder.FlushData();
+ return _rangeEncoder.FlushStream();
+}
+
+const UInt32 kDefaultLimit = (1 << 24);
+
+HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 ** /* outSizes */,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress)
+{
+ if (numInStreams != 1 || numOutStreams != 4)
+ return E_INVALIDARG;
+
+ if (!Create())
+ return E_OUTOFMEMORY;
+
+ bool sizeIsDefined = false;
+ UInt64 inSize = 0;
+ if (inSizes != NULL)
+ if (inSizes[0] != NULL)
+ {
+ inSize = *inSizes[0];
+ if (inSize <= kDefaultLimit)
+ sizeIsDefined = true;
+ }
+
+ ISequentialInStream *inStream = inStreams[0];
+
+ _mainStream.SetStream(outStreams[0]);
+ _mainStream.Init();
+ _callStream.SetStream(outStreams[1]);
+ _callStream.Init();
+ _jumpStream.SetStream(outStreams[2]);
+ _jumpStream.Init();
+ _rangeEncoder.SetStream(outStreams[3]);
+ _rangeEncoder.Init();
+ for (int i = 0; i < 256; i++)
+ _statusE8Encoder[i].Init();
+ _statusE9Encoder.Init();
+ _statusJccEncoder.Init();
+ CCoderReleaser releaser(this);
+
+ CMyComPtr<ICompressGetSubStreamSize> getSubStreamSize;
+ {
+ inStream->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize);
+ }
+
+ UInt32 nowPos = 0;
+ UInt64 nowPos64 = 0;
+ UInt32 bufferPos = 0;
+
+ Byte prevByte = 0;
+
+ UInt64 subStreamIndex = 0;
+ UInt64 subStreamStartPos = 0;
+ UInt64 subStreamEndPos = 0;
+
+ for (;;)
+ {
+ UInt32 processedSize = 0;
+ for (;;)
+ {
+ 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)
+ {
+ // change it
+ for (bufferPos = 0; bufferPos < endPos; bufferPos++)
+ {
+ Byte b = _buffer[bufferPos];
+ _mainStream.WriteByte(b);
+ if (b == 0xE8)
+ _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0);
+ else if (b == 0xE9)
+ _statusE9Encoder.Encode(&_rangeEncoder, 0);
+ else if (IsJcc(prevByte, b))
+ _statusJccEncoder.Encode(&_rangeEncoder, 0);
+ prevByte = b;
+ }
+ return Flush();
+ }
+
+ bufferPos = 0;
+
+ UInt32 limit = endPos - 5;
+ while(bufferPos <= limit)
+ {
+ Byte b = _buffer[bufferPos];
+ _mainStream.WriteByte(b);
+ if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b))
+ {
+ bufferPos++;
+ prevByte = b;
+ continue;
+ }
+ Byte nextByte = _buffer[bufferPos + 4];
+ UInt32 src =
+ (UInt32(nextByte) << 24) |
+ (UInt32(_buffer[bufferPos + 3]) << 16) |
+ (UInt32(_buffer[bufferPos + 2]) << 8) |
+ (_buffer[bufferPos + 1]);
+ UInt32 dest = (nowPos + bufferPos + 5) + src;
+ // if (Test86MSByte(nextByte))
+ bool convert;
+ if (getSubStreamSize != NULL)
+ {
+ UInt64 currentPos = (nowPos64 + bufferPos);
+ while (subStreamEndPos < currentPos)
+ {
+ UInt64 subStreamSize;
+ HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize);
+ if (result == S_OK)
+ {
+ subStreamStartPos = subStreamEndPos;
+ subStreamEndPos += subStreamSize;
+ subStreamIndex++;
+ }
+ else if (result == S_FALSE || result == E_NOTIMPL)
+ {
+ getSubStreamSize.Release();
+ subStreamStartPos = 0;
+ subStreamEndPos = subStreamStartPos - 1;
+ }
+ else
+ return result;
+ }
+ if (getSubStreamSize == NULL)
+ {
+ if (sizeIsDefined)
+ convert = (dest < inSize);
+ else
+ convert = Test86MSByte(nextByte);
+ }
+ else if (subStreamEndPos - subStreamStartPos > kDefaultLimit)
+ convert = Test86MSByte(nextByte);
+ else
+ {
+ UInt64 dest64 = (currentPos + 5) + Int64(Int32(src));
+ convert = (dest64 >= subStreamStartPos && dest64 < subStreamEndPos);
+ }
+ }
+ else if (sizeIsDefined)
+ convert = (dest < inSize);
+ else
+ convert = Test86MSByte(nextByte);
+ if (convert)
+ {
+ if (b == 0xE8)
+ _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 1);
+ else if (b == 0xE9)
+ _statusE9Encoder.Encode(&_rangeEncoder, 1);
+ else
+ _statusJccEncoder.Encode(&_rangeEncoder, 1);
+
+ bufferPos += 5;
+ if (b == 0xE8)
+ {
+ _callStream.WriteByte((Byte)(dest >> 24));
+ _callStream.WriteByte((Byte)(dest >> 16));
+ _callStream.WriteByte((Byte)(dest >> 8));
+ _callStream.WriteByte((Byte)(dest));
+ }
+ else
+ {
+ _jumpStream.WriteByte((Byte)(dest >> 24));
+ _jumpStream.WriteByte((Byte)(dest >> 16));
+ _jumpStream.WriteByte((Byte)(dest >> 8));
+ _jumpStream.WriteByte((Byte)(dest));
+ }
+ prevByte = nextByte;
+ }
+ else
+ {
+ if (b == 0xE8)
+ _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0);
+ else if (b == 0xE9)
+ _statusE9Encoder.Encode(&_rangeEncoder, 0);
+ else
+ _statusJccEncoder.Encode(&_rangeEncoder, 0);
+ bufferPos++;
+ prevByte = b;
+ }
+ }
+ nowPos += bufferPos;
+ nowPos64 += bufferPos;
+
+ if (progress != NULL)
+ {
+ RINOK(progress->SetRatioInfo(&nowPos64, NULL));
+ }
+
+ UInt32 i = 0;
+ while(bufferPos < endPos)
+ _buffer[i++] = _buffer[bufferPos++];
+ bufferPos = i;
+ }
+}
+
+STDMETHODIMP CBCJ2_x86_Encoder::Code(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress)
+{
+ try
+ {
+ return CodeReal(inStreams, inSizes, numInStreams,
+ outStreams, outSizes,numOutStreams, progress);
+ }
+ catch(const COutBufferException &e) { return e.ErrorCode; }
+ catch(...) { return S_FALSE; }
+}
+
+#endif
+
+HRESULT CBCJ2_x86_Decoder::CodeReal(ISequentialInStream **inStreams,
+ const UInt64 ** /* inSizes */,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 ** /* outSizes */,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress)
+{
+ if (numInStreams != 4 || numOutStreams != 1)
+ return E_INVALIDARG;
+
+ if (!_mainInStream.Create(1 << 16))
+ return E_OUTOFMEMORY;
+ if (!_callStream.Create(1 << 20))
+ return E_OUTOFMEMORY;
+ if (!_jumpStream.Create(1 << 16))
+ return E_OUTOFMEMORY;
+ if (!_rangeDecoder.Create(1 << 20))
+ return E_OUTOFMEMORY;
+ if (!_outStream.Create(1 << 16))
+ return E_OUTOFMEMORY;
+
+ _mainInStream.SetStream(inStreams[0]);
+ _callStream.SetStream(inStreams[1]);
+ _jumpStream.SetStream(inStreams[2]);
+ _rangeDecoder.SetStream(inStreams[3]);
+ _outStream.SetStream(outStreams[0]);
+
+ _mainInStream.Init();
+ _callStream.Init();
+ _jumpStream.Init();
+ _rangeDecoder.Init();
+ _outStream.Init();
+
+ for (int i = 0; i < 256; i++)
+ _statusE8Decoder[i].Init();
+ _statusE9Decoder.Init();
+ _statusJccDecoder.Init();
+
+ CCoderReleaser releaser(this);
+
+ Byte prevByte = 0;
+ UInt32 processedBytes = 0;
+ for (;;)
+ {
+ if (processedBytes > (1 << 20) && progress != NULL)
+ {
+ UInt64 nowPos64 = _outStream.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(NULL, &nowPos64));
+ processedBytes = 0;
+ }
+ processedBytes++;
+ Byte b;
+ if (!_mainInStream.ReadByte(b))
+ return Flush();
+ _outStream.WriteByte(b);
+ if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b))
+ {
+ prevByte = b;
+ continue;
+ }
+ bool status;
+ if (b == 0xE8)
+ status = (_statusE8Decoder[prevByte].Decode(&_rangeDecoder) == 1);
+ else if (b == 0xE9)
+ status = (_statusE9Decoder.Decode(&_rangeDecoder) == 1);
+ else
+ status = (_statusJccDecoder.Decode(&_rangeDecoder) == 1);
+ if (status)
+ {
+ UInt32 src;
+ if (b == 0xE8)
+ {
+ Byte b0;
+ if(!_callStream.ReadByte(b0))
+ return S_FALSE;
+ src = ((UInt32)b0) << 24;
+ if(!_callStream.ReadByte(b0))
+ return S_FALSE;
+ src |= ((UInt32)b0) << 16;
+ if(!_callStream.ReadByte(b0))
+ return S_FALSE;
+ src |= ((UInt32)b0) << 8;
+ if(!_callStream.ReadByte(b0))
+ return S_FALSE;
+ src |= ((UInt32)b0);
+ }
+ else
+ {
+ Byte b0;
+ if(!_jumpStream.ReadByte(b0))
+ return S_FALSE;
+ src = ((UInt32)b0) << 24;
+ if(!_jumpStream.ReadByte(b0))
+ return S_FALSE;
+ src |= ((UInt32)b0) << 16;
+ if(!_jumpStream.ReadByte(b0))
+ return S_FALSE;
+ src |= ((UInt32)b0) << 8;
+ if(!_jumpStream.ReadByte(b0))
+ return S_FALSE;
+ src |= ((UInt32)b0);
+ }
+ UInt32 dest = src - (UInt32(_outStream.GetProcessedSize()) + 4) ;
+ _outStream.WriteByte((Byte)(dest));
+ _outStream.WriteByte((Byte)(dest >> 8));
+ _outStream.WriteByte((Byte)(dest >> 16));
+ _outStream.WriteByte((Byte)(dest >> 24));
+ prevByte = (Byte)(dest >> 24);
+ processedBytes += 4;
+ }
+ else
+ prevByte = b;
+ }
+}
+
+STDMETHODIMP CBCJ2_x86_Decoder::Code(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress)
+{
+ try
+ {
+ return CodeReal(inStreams, inSizes, numInStreams,
+ outStreams, outSizes,numOutStreams, progress);
+ }
+ catch(const COutBufferException &e) { return e.ErrorCode; }
+ catch(...) { return S_FALSE; }
+}
diff --git a/CPP/7zip/Compress/Branch/x86_2.h b/CPP/7zip/Compress/Branch/x86_2.h
new file mode 100755
index 00000000..3d34eb8d
--- /dev/null
+++ b/CPP/7zip/Compress/Branch/x86_2.h
@@ -0,0 +1,133 @@
+// x86_2.h
+
+#ifndef __BRANCH_X86_2_H
+#define __BRANCH_X86_2_H
+
+#include "../../../Common/MyCom.h"
+#include "../RangeCoder/RangeCoderBit.h"
+#include "../../ICoder.h"
+
+// {23170F69-40C1-278B-0303-010100000100}
+#define MyClass2_a(Name, id, subId, encodingId) \
+DEFINE_GUID(CLSID_CCompressConvert ## Name, \
+0x23170F69, 0x40C1, 0x278B, 0x03, 0x03, id, subId, 0x00, 0x00, encodingId, 0x00);
+
+#define MyClass_a(Name, id, subId) \
+MyClass2_a(Name ## _Encoder, id, subId, 0x01) \
+MyClass2_a(Name ## _Decoder, id, subId, 0x00)
+
+MyClass_a(BCJ2_x86, 0x01, 0x1B)
+
+const int kNumMoveBits = 5;
+
+#ifndef EXTRACT_ONLY
+
+class CBCJ2_x86_Encoder:
+ public ICompressCoder2,
+ public CMyUnknownImp
+{
+ Byte *_buffer;
+public:
+ CBCJ2_x86_Encoder(): _buffer(0) {};
+ ~CBCJ2_x86_Encoder();
+ bool Create();
+
+ COutBuffer _mainStream;
+ COutBuffer _callStream;
+ COutBuffer _jumpStream;
+ NCompress::NRangeCoder::CEncoder _rangeEncoder;
+ NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusE8Encoder[256];
+ NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusE9Encoder;
+ NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusJccEncoder;
+
+ HRESULT Flush();
+ void ReleaseStreams()
+ {
+ _mainStream.ReleaseStream();
+ _callStream.ReleaseStream();
+ _jumpStream.ReleaseStream();
+ _rangeEncoder.ReleaseStream();
+ }
+
+ class CCoderReleaser
+ {
+ CBCJ2_x86_Encoder *_coder;
+ public:
+ CCoderReleaser(CBCJ2_x86_Encoder *coder): _coder(coder) {}
+ ~CCoderReleaser() { _coder->ReleaseStreams(); }
+ };
+
+public:
+
+ MY_UNKNOWN_IMP
+
+ HRESULT CodeReal(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+ STDMETHOD(Code)(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+};
+
+#endif
+
+class CBCJ2_x86_Decoder:
+ public ICompressCoder2,
+ public CMyUnknownImp
+{
+public:
+ CInBuffer _mainInStream;
+ CInBuffer _callStream;
+ CInBuffer _jumpStream;
+ NCompress::NRangeCoder::CDecoder _rangeDecoder;
+ NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusE8Decoder[256];
+ NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusE9Decoder;
+ NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusJccDecoder;
+
+ COutBuffer _outStream;
+
+ void ReleaseStreams()
+ {
+ _mainInStream.ReleaseStream();
+ _callStream.ReleaseStream();
+ _jumpStream.ReleaseStream();
+ _rangeDecoder.ReleaseStream();
+ _outStream.ReleaseStream();
+ }
+
+ HRESULT Flush() { return _outStream.Flush(); }
+ class CCoderReleaser
+ {
+ CBCJ2_x86_Decoder *_coder;
+ public:
+ CCoderReleaser(CBCJ2_x86_Decoder *coder): _coder(coder) {}
+ ~CCoderReleaser() { _coder->ReleaseStreams(); }
+ };
+
+public:
+ MY_UNKNOWN_IMP
+ HRESULT CodeReal(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+ STDMETHOD(Code)(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress);
+};
+
+#endif
diff --git a/CPP/7zip/Compress/ByteSwap/ByteSwap.cpp b/CPP/7zip/Compress/ByteSwap/ByteSwap.cpp
new file mode 100755
index 00000000..3f252f2c
--- /dev/null
+++ b/CPP/7zip/Compress/ByteSwap/ByteSwap.cpp
@@ -0,0 +1,38 @@
+// ByteSwap.cpp
+
+#include "StdAfx.h"
+
+#include "ByteSwap.h"
+
+STDMETHODIMP CByteSwap2::Init() { return S_OK; }
+
+STDMETHODIMP_(UInt32) CByteSwap2::Filter(Byte *data, UInt32 size)
+{
+ const UInt32 kStep = 2;
+ UInt32 i;
+ for (i = 0; i + kStep <= size; i += kStep)
+ {
+ Byte b = data[i];
+ data[i] = data[i + 1];
+ data[i + 1] = b;
+ }
+ return i;
+}
+
+STDMETHODIMP CByteSwap4::Init() { return S_OK; }
+
+STDMETHODIMP_(UInt32) CByteSwap4::Filter(Byte *data, UInt32 size)
+{
+ const UInt32 kStep = 4;
+ UInt32 i;
+ for (i = 0; i + kStep <= size; i += kStep)
+ {
+ Byte b0 = data[i];
+ Byte b1 = data[i + 1];
+ data[i] = data[i + 3];
+ data[i + 1] = data[i + 2];
+ data[i + 2] = b1;
+ data[i + 3] = b0;
+ }
+ return i;
+}
diff --git a/CPP/7zip/Compress/ByteSwap/ByteSwap.dsp b/CPP/7zip/Compress/ByteSwap/ByteSwap.dsp
new file mode 100755
index 00000000..1a73d67f
--- /dev/null
+++ b/CPP/7zip/Compress/ByteSwap/ByteSwap.dsp
@@ -0,0 +1,125 @@
+# Microsoft Developer Studio Project File - Name="ByteSwap" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=ByteSwap - 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 "ByteSwap.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 "ByteSwap.mak" CFG="ByteSwap - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "ByteSwap - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "ByteSwap - 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)" == "ByteSwap - 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 "BYTESWAP_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BYTESWAP_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\Codecs\Swap.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "ByteSwap - 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 "BYTESWAP_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 "BYTESWAP_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\Codecs\Swap.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "ByteSwap - Win32 Release"
+# Name "ByteSwap - 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 Source File
+
+SOURCE=.\ByteSwap.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ByteSwap.h
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/Compress/ByteSwap/ByteSwap.dsw b/CPP/7zip/Compress/ByteSwap/ByteSwap.dsw
new file mode 100755
index 00000000..413d7e6e
--- /dev/null
+++ b/CPP/7zip/Compress/ByteSwap/ByteSwap.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "ByteSwap"=.\ByteSwap.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Compress/ByteSwap/ByteSwap.h b/CPP/7zip/Compress/ByteSwap/ByteSwap.h
new file mode 100755
index 00000000..00303063
--- /dev/null
+++ b/CPP/7zip/Compress/ByteSwap/ByteSwap.h
@@ -0,0 +1,37 @@
+// ByteSwap.h
+
+#ifndef __BYTESWAP_H
+#define __BYTESWAP_H
+
+#include "../../ICoder.h"
+#include "Common/MyCom.h"
+
+// {23170F69-40C1-278B-0203-020000000000}
+DEFINE_GUID(CLSID_CCompressConvertByteSwap2,
+0x23170F69, 0x40C1, 0x278B, 0x02, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+// {23170F69-40C1-278B-0203-040000000000}
+DEFINE_GUID(CLSID_CCompressConvertByteSwap4,
+0x23170F69, 0x40C1, 0x278B, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+class CByteSwap2:
+ public ICompressFilter,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+ STDMETHOD(Init)();
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+};
+
+class CByteSwap4:
+ public ICompressFilter,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+ STDMETHOD(Init)();
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+};
+
+#endif
diff --git a/CPP/7zip/Compress/ByteSwap/DllExports.cpp b/CPP/7zip/Compress/ByteSwap/DllExports.cpp
new file mode 100755
index 00000000..cc737590
--- /dev/null
+++ b/CPP/7zip/Compress/ByteSwap/DllExports.cpp
@@ -0,0 +1,91 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#include "ByteSwap.h"
+#include "../../ICoder.h"
+
+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_ICompressFilter);
+ CMyComPtr<ICompressFilter> coder;
+ if (*clsid == CLSID_CCompressConvertByteSwap2)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder = (ICompressFilter *)new CByteSwap2();
+ }
+ else if (*clsid == CLSID_CCompressConvertByteSwap4)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder = (ICompressFilter *)new CByteSwap4();
+ }
+ else
+ return CLASS_E_CLASSNOTAVAILABLE;
+ *outObject = coder.Detach();
+ COM_TRY_END
+ return S_OK;
+}
+
+struct CSwapMethodInfo
+{
+ char ID[3];
+ const wchar_t *Name;
+ const GUID *clsid;
+};
+
+static CSwapMethodInfo g_Methods[] =
+{
+ { { 0x2, 0x03, 0x02 }, L"Swap2", &CLSID_CCompressConvertByteSwap2 },
+ { { 0x2, 0x03, 0x04 }, L"Swap4", &CLSID_CCompressConvertByteSwap4 }
+};
+
+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 CSwapMethodInfo &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.Name)) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NMethodPropID::kDecoder:
+ case NMethodPropID::kEncoder:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)method.clsid, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ }
+ return S_OK;
+}
diff --git a/CPP/7zip/Compress/ByteSwap/StdAfx.cpp b/CPP/7zip/Compress/ByteSwap/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Compress/ByteSwap/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Compress/ByteSwap/StdAfx.h b/CPP/7zip/Compress/ByteSwap/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Compress/ByteSwap/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Compress/ByteSwap/makefile b/CPP/7zip/Compress/ByteSwap/makefile
new file mode 100755
index 00000000..f73a8079
--- /dev/null
+++ b/CPP/7zip/Compress/ByteSwap/makefile
@@ -0,0 +1,23 @@
+PROG = Swap.dll
+DEF_FILE = ../Codec.def
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib
+
+SWAP_OBJS = \
+ $O\DllExports.obj \
+
+SWAP_OPT_OBJS = \
+ $O\ByteSwap.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(SWAP_OBJS) \
+ $(SWAP_OPT_OBJS) \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(SWAP_OBJS): $(*B).cpp
+ $(COMPL)
+$(SWAP_OPT_OBJS): $(*B).cpp
+ $(COMPL_O2)
diff --git a/CPP/7zip/Compress/ByteSwap/resource.rc b/CPP/7zip/Compress/ByteSwap/resource.rc
new file mode 100755
index 00000000..21c0c505
--- /dev/null
+++ b/CPP/7zip/Compress/ByteSwap/resource.rc
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("SWAP filter Codec", "SWAP")
diff --git a/CPP/7zip/Compress/Codec.def b/CPP/7zip/Compress/Codec.def
new file mode 100755
index 00000000..ebf73a3b
--- /dev/null
+++ b/CPP/7zip/Compress/Codec.def
@@ -0,0 +1,4 @@
+EXPORTS
+ CreateObject PRIVATE
+ GetNumberOfMethods PRIVATE
+ GetMethodProperty PRIVATE
diff --git a/CPP/7zip/Compress/Copy/Copy.dsp b/CPP/7zip/Compress/Copy/Copy.dsp
new file mode 100755
index 00000000..099a433d
--- /dev/null
+++ b/CPP/7zip/Compress/Copy/Copy.dsp
@@ -0,0 +1,149 @@
+# Microsoft Developer Studio Project File - Name="Copy" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=Copy - 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 "Copy.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 "Copy.mak" CFG="Copy - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Copy - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Copy - 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)" == "Copy - 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 "COPY_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COPY_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 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-zip\Codecs\Copy.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Copy - 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 "COPY_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COPY_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 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-zip\Codecs\Copy.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "Copy - Win32 Release"
+# Name "Copy - 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 "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 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
+# End Source File
+# Begin Source File
+
+SOURCE=.\CopyCoder.h
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/Compress/Copy/Copy.dsw b/CPP/7zip/Compress/Copy/Copy.dsw
new file mode 100755
index 00000000..53ddf6cf
--- /dev/null
+++ b/CPP/7zip/Compress/Copy/Copy.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Copy"=".\Copy.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Compress/Copy/CopyCoder.cpp b/CPP/7zip/Compress/Copy/CopyCoder.cpp
new file mode 100755
index 00000000..ce1bde03
--- /dev/null
+++ b/CPP/7zip/Compress/Copy/CopyCoder.cpp
@@ -0,0 +1,52 @@
+// Compress/CopyCoder.cpp
+
+#include "StdAfx.h"
+
+#include "CopyCoder.h"
+#include "../../../Common/Alloc.h"
+#include "../../Common/StreamUtils.h"
+
+namespace NCompress {
+
+static const UInt32 kBufferSize = 1 << 17;
+
+CCopyCoder::~CCopyCoder()
+{
+ ::MidFree(_buffer);
+}
+
+STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 * /* inSize */, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ if (_buffer == 0)
+ {
+ _buffer = (Byte *)::MidAlloc(kBufferSize);
+ if (_buffer == 0)
+ return E_OUTOFMEMORY;
+ }
+
+ TotalSize = 0;
+ for (;;)
+ {
+ UInt32 realProcessedSize;
+ UInt32 size = kBufferSize;
+ if (outSize != 0)
+ if (size > *outSize - TotalSize)
+ size = (UInt32)(*outSize - TotalSize);
+ RINOK(inStream->Read(_buffer, size, &realProcessedSize));
+ if(realProcessedSize == 0)
+ break;
+ RINOK(WriteStream(outStream, _buffer, realProcessedSize, NULL));
+ TotalSize += realProcessedSize;
+ if (progress != NULL)
+ {
+ RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize));
+ }
+ }
+ return S_OK;
+}
+
+}
+
diff --git a/CPP/7zip/Compress/Copy/CopyCoder.h b/CPP/7zip/Compress/Copy/CopyCoder.h
new file mode 100755
index 00000000..d2a26a89
--- /dev/null
+++ b/CPP/7zip/Compress/Copy/CopyCoder.h
@@ -0,0 +1,31 @@
+// Compress/CopyCoder.h
+
+#ifndef __COMPRESS_COPYCODER_H
+#define __COMPRESS_COPYCODER_H
+
+#include "../../ICoder.h"
+#include "../../../Common/MyCom.h"
+
+namespace NCompress {
+
+class CCopyCoder:
+ public ICompressCoder,
+ public CMyUnknownImp
+{
+ Byte *_buffer;
+public:
+ UInt64 TotalSize;
+ CCopyCoder(): TotalSize(0) , _buffer(0) {};
+ ~CCopyCoder();
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+};
+
+}
+
+#endif
diff --git a/CPP/7zip/Compress/Copy/DllExports.cpp b/CPP/7zip/Compress/Copy/DllExports.cpp
new file mode 100755
index 00000000..756dcc9c
--- /dev/null
+++ b/CPP/7zip/Compress/Copy/DllExports.cpp
@@ -0,0 +1,70 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/MyInitGuid.h"
+#include "../../../Common/ComTry.h"
+
+#include "CopyCoder.h"
+
+// {23170F69-40C1-278B-0000-000000000000}
+DEFINE_GUID(CLSID_CCompressCopyCoder,
+0x23170F69, 0x40C1, 0x278B, 0x00, 0x00, 0x00, 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_CCompressCopyCoder)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ if (*iid != IID_ICompressCoder)
+ return E_NOINTERFACE;
+ CMyComPtr<ICompressCoder> coder = (ICompressCoder *)new NCompress::CCopyCoder();
+ *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[] = { 0x0 };
+ if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NMethodPropID::kName:
+ {
+ if ((value->bstrVal = ::SysAllocString(L"Copy")) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NMethodPropID::kDecoder:
+ case NMethodPropID::kEncoder:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CCompressCopyCoder, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ }
+ return S_OK;
+}
diff --git a/CPP/7zip/Compress/Copy/StdAfx.cpp b/CPP/7zip/Compress/Copy/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Compress/Copy/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Compress/Copy/StdAfx.h b/CPP/7zip/Compress/Copy/StdAfx.h
new file mode 100755
index 00000000..92239aeb
--- /dev/null
+++ b/CPP/7zip/Compress/Copy/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Compress/Copy/makefile b/CPP/7zip/Compress/Copy/makefile
new file mode 100755
index 00000000..8c108fbc
--- /dev/null
+++ b/CPP/7zip/Compress/Copy/makefile
@@ -0,0 +1,30 @@
+PROG = Copy.dll
+DEF_FILE = ../Codec.def
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib
+
+COPY_OBJS = \
+ $O\DllExports.obj \
+ $O\CopyCoder.obj \
+
+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"
+
+$(COPY_OBJS): $(*B).cpp
+ $(COMPL)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/Compress/Copy/resource.rc b/CPP/7zip/Compress/Copy/resource.rc
new file mode 100755
index 00000000..234c85bf
--- /dev/null
+++ b/CPP/7zip/Compress/Copy/resource.rc
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("Copy Codec", "Copy")
diff --git a/CPP/7zip/Compress/Deflate/Deflate.dsp b/CPP/7zip/Compress/Deflate/Deflate.dsp
new file mode 100755
index 00000000..a1baccad
--- /dev/null
+++ b/CPP/7zip/Compress/Deflate/Deflate.dsp
@@ -0,0 +1,341 @@
+# Microsoft Developer Studio Project File - Name="Deflate" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=Deflate - 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 "Deflate.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 "Deflate.mak" CFG="Deflate - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Deflate - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Deflate - 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)" == "Deflate - 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 "DEFLATE_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DEFLATE_EXPORTS" /D "_ST_MODE" /Yu"StdAfx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\Deflate.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Deflate - 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 "DEFLATE_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DEFLATE_EXPORTS" /D "_ST_MODE" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\Deflate.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "Deflate - Win32 Release"
+# Name "Deflate - 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 "Huffman"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Huffman\HuffmanDecoder.h
+# End Source File
+# End Group
+# Begin Group "Interface"
+
+# PROP Default_Filter ""
+# 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\LSBFDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFEncoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFEncoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.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\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# 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 "LZ_C"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrc.c
+
+!IF "$(CFG)" == "Deflate - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Deflate - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\LzHash.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.c
+
+!IF "$(CFG)" == "Deflate - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Deflate - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.h
+# End Source File
+# End Group
+# Begin Group "C Huffman"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Huffman\HuffmanEncode.c
+
+!IF "$(CFG)" == "Deflate - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Deflate - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Huffman\HuffmanEncode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Sort.c
+
+!IF "$(CFG)" == "Deflate - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Deflate - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Sort.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\DeflateConst.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\DeflateDecoder.cpp
+
+!IF "$(CFG)" == "Deflate - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Deflate - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\DeflateDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\DeflateEncoder.cpp
+
+!IF "$(CFG)" == "Deflate - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Deflate - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\DeflateEncoder.h
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/Compress/Deflate/Deflate.dsw b/CPP/7zip/Compress/Deflate/Deflate.dsw
new file mode 100755
index 00000000..f17203ed
--- /dev/null
+++ b/CPP/7zip/Compress/Deflate/Deflate.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Deflate"=.\Deflate.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Compress/Deflate/DeflateConst.h b/CPP/7zip/Compress/Deflate/DeflateConst.h
new file mode 100755
index 00000000..766b589a
--- /dev/null
+++ b/CPP/7zip/Compress/Deflate/DeflateConst.h
@@ -0,0 +1,134 @@
+// DeflateConst.h
+
+#ifndef __DEFLATE_CONST_H
+#define __DEFLATE_CONST_H
+
+namespace NCompress {
+namespace NDeflate {
+
+const int kNumHuffmanBits = 15;
+
+const UInt32 kHistorySize32 = (1 << 15);
+const UInt32 kHistorySize64 = (1 << 16);
+
+const UInt32 kDistTableSize32 = 30;
+const UInt32 kDistTableSize64 = 32;
+
+const UInt32 kNumLenSymbols32 = 256;
+const UInt32 kNumLenSymbols64 = 255; // don't change it. It must be <= 255.
+const UInt32 kNumLenSymbolsMax = kNumLenSymbols32;
+
+const UInt32 kNumLenSlots = 29;
+
+const UInt32 kFixedDistTableSize = 32;
+const UInt32 kFixedLenTableSize = 31;
+
+const UInt32 kSymbolEndOfBlock = 0x100;
+const UInt32 kSymbolMatch = kSymbolEndOfBlock + 1;
+
+const UInt32 kMainTableSize = kSymbolMatch + kNumLenSlots;
+const UInt32 kFixedMainTableSize = kSymbolMatch + kFixedLenTableSize;
+
+const UInt32 kLevelTableSize = 19;
+
+const UInt32 kTableDirectLevels = 16;
+const UInt32 kTableLevelRepNumber = kTableDirectLevels;
+const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1;
+const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1;
+
+const UInt32 kLevelMask = 0xF;
+
+const Byte kLenStart32[kFixedLenTableSize] =
+ {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 255, 0, 0};
+const Byte kLenStart64[kFixedLenTableSize] =
+ {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 0, 0, 0};
+
+const Byte kLenDirectBits32[kFixedLenTableSize] =
+ {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0};
+const Byte kLenDirectBits64[kFixedLenTableSize] =
+ {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 16, 0, 0};
+
+const UInt32 kDistStart[kDistTableSize64] =
+ {0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,
+ 1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768,49152};
+const Byte kDistDirectBits[kDistTableSize64] =
+ {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14};
+
+const Byte kLevelDirectBits[3] = {2, 3, 7};
+
+const Byte kCodeLengthAlphabetOrder[kLevelTableSize] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+const UInt32 kMatchMinLen = 3;
+const UInt32 kMatchMaxLen32 = kNumLenSymbols32 + kMatchMinLen - 1; //256 + 2
+const UInt32 kMatchMaxLen64 = kNumLenSymbols64 + kMatchMinLen - 1; //255 + 2
+const UInt32 kMatchMaxLen = kMatchMaxLen32;
+
+const int kFinalBlockFieldSize = 1;
+
+namespace NFinalBlockField
+{
+ enum
+ {
+ kNotFinalBlock = 0,
+ kFinalBlock = 1
+ };
+}
+
+const int kBlockTypeFieldSize = 2;
+
+namespace NBlockType
+{
+ enum
+ {
+ kStored = 0,
+ kFixedHuffman = 1,
+ kDynamicHuffman = 2
+ };
+}
+
+const int kNumLenCodesFieldSize = 5;
+const int kNumDistCodesFieldSize = 5;
+const int kNumLevelCodesFieldSize = 4;
+
+const UInt32 kNumLitLenCodesMin = 257;
+const UInt32 kNumDistCodesMin = 1;
+const UInt32 kNumLevelCodesMin = 4;
+
+const int kLevelFieldSize = 3;
+
+const int kStoredBlockLengthFieldSize = 16;
+
+struct CLevels
+{
+ Byte litLenLevels[kFixedMainTableSize];
+ Byte distLevels[kFixedDistTableSize];
+
+ void SubClear()
+ {
+ UInt32 i;
+ for(i = kNumLitLenCodesMin; i < kFixedMainTableSize; i++)
+ litLenLevels[i] = 0;
+ for(i = 0; i < kFixedDistTableSize; i++)
+ distLevels[i] = 0;
+ }
+
+ void SetFixedLevels()
+ {
+ 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++)
+ litLenLevels[i] = 8;
+ for (i = 0; i < kFixedDistTableSize; i++) // test it: InfoZip only uses kDistTableSize
+ distLevels[i] = 5;
+ }
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Compress/Deflate/DeflateDecoder.cpp b/CPP/7zip/Compress/Deflate/DeflateDecoder.cpp
new file mode 100755
index 00000000..0de5534b
--- /dev/null
+++ b/CPP/7zip/Compress/Deflate/DeflateDecoder.cpp
@@ -0,0 +1,339 @@
+// DeflateDecoder.cpp
+
+#include "StdAfx.h"
+
+#include "DeflateDecoder.h"
+
+namespace NCompress {
+namespace NDeflate {
+namespace NDecoder {
+
+static const int kLenIdFinished = -1;
+static const int kLenIdNeedInit = -2;
+
+CCoder::CCoder(bool deflate64Mode, bool deflateNSIS):
+ _deflate64Mode(deflate64Mode),
+ _deflateNSIS(deflateNSIS),
+ _keepHistory(false) {}
+
+UInt32 CCoder::ReadBits(int numBits)
+{
+ return m_InBitStream.ReadBits(numBits);
+}
+
+bool CCoder::DeCodeLevelTable(Byte *values, int numSymbols)
+{
+ int i = 0;
+ do
+ {
+ UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
+ if (number < kTableDirectLevels)
+ values[i++] = (Byte)number;
+ else if (number < kLevelTableSize)
+ {
+ if (number == kTableLevelRepNumber)
+ {
+ if (i == 0)
+ return false;
+ int num = ReadBits(2) + 3;
+ for (; num > 0 && i < numSymbols; num--, i++)
+ values[i] = values[i - 1];
+ }
+ else
+ {
+ int num;
+ if (number == kTableLevel0Number)
+ num = ReadBits(3) + 3;
+ else
+ num = ReadBits(7) + 11;
+ for (;num > 0 && i < numSymbols; num--)
+ values[i++] = 0;
+ }
+ }
+ else
+ return false;
+ }
+ while(i < numSymbols);
+ return true;
+}
+
+#define RIF(x) { if (!(x)) return false; }
+
+bool CCoder::ReadTables(void)
+{
+ m_FinalBlock = (ReadBits(kFinalBlockFieldSize) == NFinalBlockField::kFinalBlock);
+ UInt32 blockType = ReadBits(kBlockTypeFieldSize);
+ if (blockType > NBlockType::kDynamicHuffman)
+ return false;
+
+ if (blockType == NBlockType::kStored)
+ {
+ m_StoredMode = true;
+ UInt32 currentBitPosition = m_InBitStream.GetBitPosition();
+ int numBitsForAlign = (int)(currentBitPosition > 0 ? (8 - currentBitPosition): 0);
+ ReadBits(numBitsForAlign);
+ m_StoredBlockSize = ReadBits(kStoredBlockLengthFieldSize);
+ if (_deflateNSIS)
+ return true;
+ return (m_StoredBlockSize == (UInt16)~ReadBits(kStoredBlockLengthFieldSize));
+ }
+
+ m_StoredMode = false;
+
+ CLevels levels;
+ if (blockType == NBlockType::kFixedHuffman)
+ {
+ levels.SetFixedLevels();
+ _numDistLevels = _deflate64Mode ? kDistTableSize64 : kDistTableSize32;
+ }
+ else
+ {
+ int numLitLenLevels = ReadBits(kNumLenCodesFieldSize) + kNumLitLenCodesMin;
+ _numDistLevels = ReadBits(kNumDistCodesFieldSize) + kNumDistCodesMin;
+ int numLevelCodes = ReadBits(kNumLevelCodesFieldSize) + kNumLevelCodesMin;
+
+ if (!_deflate64Mode)
+ if (_numDistLevels > kDistTableSize32)
+ return false;
+
+ Byte levelLevels[kLevelTableSize];
+ for (int i = 0; i < kLevelTableSize; i++)
+ {
+ int position = kCodeLengthAlphabetOrder[i];
+ if(i < numLevelCodes)
+ levelLevels[position] = (Byte)ReadBits(kLevelFieldSize);
+ else
+ levelLevels[position] = 0;
+ }
+
+ RIF(m_LevelDecoder.SetCodeLengths(levelLevels));
+
+ Byte tmpLevels[kFixedMainTableSize + kFixedDistTableSize];
+ if (!DeCodeLevelTable(tmpLevels, numLitLenLevels + _numDistLevels))
+ return false;
+
+ levels.SubClear();
+ memcpy(levels.litLenLevels, tmpLevels, numLitLenLevels);
+ memcpy(levels.distLevels, tmpLevels + numLitLenLevels, _numDistLevels);
+ }
+ RIF(m_MainDecoder.SetCodeLengths(levels.litLenLevels));
+ return m_DistDecoder.SetCodeLengths(levels.distLevels);
+}
+
+HRESULT CCoder::CodeSpec(UInt32 curSize)
+{
+ 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;
+ }
+
+ if (curSize == 0)
+ return S_OK;
+
+ while(_remainLen > 0 && curSize > 0)
+ {
+ _remainLen--;
+ Byte b = m_OutWindowStream.GetByte(_rep0);
+ m_OutWindowStream.PutByte(b);
+ curSize--;
+ }
+
+ while(curSize > 0)
+ {
+ if (_needReadTable)
+ {
+ if (m_FinalBlock)
+ {
+ _remainLen = kLenIdFinished;
+ break;
+ }
+ if (!ReadTables())
+ return S_FALSE;
+ _needReadTable = false;
+ }
+
+ if(m_StoredMode)
+ {
+ for (; m_StoredBlockSize > 0 && curSize > 0; m_StoredBlockSize--, curSize--)
+ m_OutWindowStream.PutByte((Byte)m_InBitStream.ReadBits(8));
+ _needReadTable = (m_StoredBlockSize == 0);
+ continue;
+ }
+ while(curSize > 0)
+ {
+ if (m_InBitStream.NumExtraBytes > 4)
+ return S_FALSE;
+
+ UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
+ if (number < 0x100)
+ {
+ m_OutWindowStream.PutByte((Byte)number);
+ curSize--;
+ continue;
+ }
+ else if (number == kSymbolEndOfBlock)
+ {
+ _needReadTable = true;
+ break;
+ }
+ else if (number < kMainTableSize)
+ {
+ number -= kSymbolMatch;
+ UInt32 len;
+ {
+ 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 >= _numDistLevels)
+ return S_FALSE;
+ UInt32 distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]);
+ if (!m_OutWindowStream.CopyBlock(distance, locLen))
+ return S_FALSE;
+ curSize -= locLen;
+ len -= locLen;
+ if (len != 0)
+ {
+ _remainLen = (Int32)len;
+ _rep0 = distance;
+ break;
+ }
+ }
+ else
+ return S_FALSE;
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ SetInStream(inStream);
+ m_OutWindowStream.SetStream(outStream);
+ SetOutStreamSize(outSize);
+ CCoderReleaser flusher(this);
+
+ const UInt64 start = m_OutWindowStream.GetProcessedSize();
+ for (;;)
+ {
+ 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)
+ {
+ const UInt64 inSize = m_InBitStream.GetProcessedSize();
+ const 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
+}
+
+STDMETHODIMP CCoder::GetInStreamProcessedSize(UInt64 *value)
+{
+ if (value == NULL)
+ return E_INVALIDARG;
+ *value = m_InBitStream.GetProcessedSize();
+ return S_OK;
+}
+
+STDMETHODIMP CCoder::SetInStream(ISequentialInStream *inStream)
+{
+ m_InBitStream.SetStream(inStream);
+ return S_OK;
+}
+
+STDMETHODIMP CCoder::ReleaseInStream()
+{
+ m_InBitStream.ReleaseStream();
+ return S_OK;
+}
+
+STDMETHODIMP CCoder::SetOutStreamSize(const UInt64 * /* outSize */)
+{
+ _remainLen = kLenIdNeedInit;
+ m_OutWindowStream.Init(_keepHistory);
+ return S_OK;
+}
+
+#ifdef _ST_MODE
+
+STDMETHODIMP CCoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ 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/CPP/7zip/Compress/Deflate/DeflateDecoder.h b/CPP/7zip/Compress/Deflate/DeflateDecoder.h
new file mode 100755
index 00000000..99928b72
--- /dev/null
+++ b/CPP/7zip/Compress/Deflate/DeflateDecoder.h
@@ -0,0 +1,134 @@
+// DeflateDecoder.h
+
+#ifndef __DEFLATE_DECODER_H
+#define __DEFLATE_DECODER_H
+
+#include "../../../Common/MyCom.h"
+
+#include "../../ICoder.h"
+#include "../../Common/LSBFDecoder.h"
+#include "../../Common/InBuffer.h"
+#include "../LZ/LZOutWindow.h"
+#include "../Huffman/HuffmanDecoder.h"
+
+#include "DeflateConst.h"
+
+namespace NCompress {
+namespace NDeflate {
+namespace NDecoder {
+
+class CCoder:
+ public ICompressCoder,
+ public ICompressGetInStreamProcessedSize,
+ #ifdef _ST_MODE
+ public ICompressSetInStream,
+ public ICompressSetOutStreamSize,
+ public ISequentialInStream,
+ #endif
+ public CMyUnknownImp
+{
+ CLZOutWindow m_OutWindowStream;
+ NStream::NLSBF::CDecoder<CInBuffer> m_InBitStream;
+ NCompress::NHuffman::CDecoder<kNumHuffmanBits, kFixedMainTableSize> m_MainDecoder;
+ NCompress::NHuffman::CDecoder<kNumHuffmanBits, kFixedDistTableSize> m_DistDecoder;
+ NCompress::NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder;
+
+ UInt32 m_StoredBlockSize;
+
+ bool m_FinalBlock;
+ bool m_StoredMode;
+ UInt32 _numDistLevels;
+
+
+ bool _deflateNSIS;
+ bool _deflate64Mode;
+ bool _keepHistory;
+ Int32 _remainLen;
+ UInt32 _rep0;
+ bool _needReadTable;
+
+ UInt32 ReadBits(int numBits);
+
+ bool DeCodeLevelTable(Byte *values, int numSymbols);
+ bool ReadTables();
+
+ void ReleaseStreams()
+ {
+ m_OutWindowStream.ReleaseStream();
+ ReleaseInStream();
+ }
+
+ HRESULT Flush() { return m_OutWindowStream.Flush(); }
+ class CCoderReleaser
+ {
+ CCoder *m_Coder;
+ public:
+ bool NeedFlush;
+ CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {}
+ ~CCoderReleaser()
+ {
+ if (NeedFlush)
+ m_Coder->Flush();
+ m_Coder->ReleaseStreams();
+ }
+ };
+ friend class CCoderReleaser;
+
+ HRESULT CodeSpec(UInt32 curSize);
+public:
+ CCoder(bool deflate64Mode, bool deflateNSIS = false);
+ void SetKeepHistory(bool keepHistory) { _keepHistory = keepHistory; }
+
+ HRESULT CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ #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
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
+};
+
+class CCOMCoder : public CCoder
+{
+public:
+ CCOMCoder(): CCoder(false) {}
+};
+
+class CNsisCOMCoder : public CCoder
+{
+public:
+ CNsisCOMCoder(): CCoder(false, true) {}
+};
+
+class CCOMCoder64 : public CCoder
+{
+public:
+ CCOMCoder64(): CCoder(true) {}
+};
+
+}}}
+
+#endif
diff --git a/CPP/7zip/Compress/Deflate/DeflateEncoder.cpp b/CPP/7zip/Compress/Deflate/DeflateEncoder.cpp
new file mode 100755
index 00000000..4e9ffe6d
--- /dev/null
+++ b/CPP/7zip/Compress/Deflate/DeflateEncoder.cpp
@@ -0,0 +1,963 @@
+// DeflateEncoder.cpp
+
+#include "StdAfx.h"
+
+#include "DeflateEncoder.h"
+
+#include "Windows/Defs.h"
+#include "Common/ComTry.h"
+#include "../../../Common/Alloc.h"
+// #include "../LZ/BinTree/BinTree3Z.h"
+
+#if _MSC_VER >= 1300
+#define NO_INLINE __declspec(noinline)
+#else
+#define NO_INLINE
+#endif
+
+extern "C"
+{
+ #include "../../../../C/Compress/Huffman/HuffmanEncode.h"
+}
+
+namespace NCompress {
+namespace NDeflate {
+namespace NEncoder {
+
+const int kNumDivPassesMax = 10; // [0, 16); ratio/speed/ram tradeoff; use big value for better compression ratio.
+const UInt32 kNumTables = (1 << kNumDivPassesMax);
+
+static UInt32 kFixedHuffmanCodeBlockSizeMax = (1 << 8); // [0, (1 << 32)); ratio/speed tradeoff; use big value for better compression ratio.
+static UInt32 kDivideCodeBlockSizeMin = (1 << 6); // [1, (1 << 32)); ratio/speed tradeoff; use small value for better compression ratio.
+static UInt32 kDivideBlockSizeMin = (1 << 6); // [1, (1 << 32)); ratio/speed tradeoff; use small value for better compression ratio.
+
+static const UInt32 kMaxUncompressedBlockSize = ((1 << 16) - 1) * 1; // [1, (1 << 32))
+static const UInt32 kMatchArraySize = kMaxUncompressedBlockSize * 10; // [kMatchMaxLen * 2, (1 << 32))
+static const UInt32 kMatchArrayLimit = kMatchArraySize - kMatchMaxLen * 4 * sizeof(UInt16);
+static const UInt32 kBlockUncompressedSizeThreshold = kMaxUncompressedBlockSize -
+ kMatchMaxLen - kNumOpts;
+
+static const int kMaxCodeBitLength = 15;
+static const int kMaxLevelBitLength = 7;
+
+static Byte kNoLiteralStatPrice = 13;
+static Byte kNoLenStatPrice = 13;
+static Byte kNoPosStatPrice = 6;
+
+static Byte g_LenSlots[kNumLenSymbolsMax];
+static Byte g_FastPos[1 << 9];
+
+class CFastPosInit
+{
+public:
+ CFastPosInit()
+ {
+ int i;
+ for(i = 0; i < kNumLenSlots; i++)
+ {
+ int c = kLenStart32[i];
+ int j = 1 << kLenDirectBits32[i];
+ for(int k = 0; k < j; k++, c++)
+ g_LenSlots[c] = (Byte)i;
+ }
+
+ const int kFastSlots = 18;
+ int c = 0;
+ for (Byte slotFast = 0; slotFast < kFastSlots; slotFast++)
+ {
+ UInt32 k = (1 << kDistDirectBits[slotFast]);
+ for (UInt32 j = 0; j < k; j++, c++)
+ g_FastPos[c] = slotFast;
+ }
+ }
+};
+
+static CFastPosInit g_FastPosInit;
+
+
+inline UInt32 GetPosSlot(UInt32 pos)
+{
+ if (pos < 0x200)
+ return g_FastPos[pos];
+ return g_FastPos[pos >> 8] + 16;
+}
+
+void *SzAlloc(size_t size)
+{
+ if (size == 0)
+ return 0;
+ return malloc(size);
+}
+
+void SzFree(void *address)
+{
+ free(address);
+}
+
+ISzAlloc g_Alloc = { SzAlloc, SzFree };
+
+CCoder::CCoder(bool deflate64Mode):
+ m_Deflate64Mode(deflate64Mode),
+ m_NumPasses(1),
+ m_NumDivPasses(1),
+ m_NumFastBytes(32),
+ m_OnePosMatchesMemory(0),
+ m_DistanceMemory(0),
+ m_Created(false),
+ m_Values(0),
+ m_Tables(0),
+ m_MatchFinderCycles(0)
+ // m_SetMfPasses(0)
+{
+ m_MatchMaxLen = deflate64Mode ? kMatchMaxLen64 : kMatchMaxLen32;
+ m_NumLenCombinations = deflate64Mode ? kNumLenSymbols64 : kNumLenSymbols32;
+ m_LenStart = deflate64Mode ? kLenStart64 : kLenStart32;
+ m_LenDirectBits = deflate64Mode ? kLenDirectBits64 : kLenDirectBits32;
+ MatchFinder_Construct(&_lzInWindow);
+}
+
+HRESULT CCoder::Create()
+{
+ COM_TRY_BEGIN
+ if (m_Values == 0)
+ {
+ m_Values = (CCodeValue *)MyAlloc((kMaxUncompressedBlockSize) * sizeof(CCodeValue));
+ if (m_Values == 0)
+ return E_OUTOFMEMORY;
+ }
+ if (m_Tables == 0)
+ {
+ m_Tables = (CTables *)MyAlloc((kNumTables) * sizeof(CTables));
+ if (m_Tables == 0)
+ return E_OUTOFMEMORY;
+ }
+
+ if (m_IsMultiPass)
+ {
+ if (m_OnePosMatchesMemory == 0)
+ {
+ m_OnePosMatchesMemory = (UInt16 *)::MidAlloc(kMatchArraySize * sizeof(UInt16));
+ if (m_OnePosMatchesMemory == 0)
+ return E_OUTOFMEMORY;
+ }
+ }
+ else
+ {
+ if (m_DistanceMemory == 0)
+ {
+ m_DistanceMemory = (UInt16 *)MyAlloc((kMatchMaxLen + 2) * 2 * sizeof(UInt16));
+ if (m_DistanceMemory == 0)
+ return E_OUTOFMEMORY;
+ m_MatchDistances = m_DistanceMemory;
+ }
+ }
+
+ if (!m_Created)
+ {
+ _lzInWindow.btMode = 1;
+ _lzInWindow.numHashBytes = 3;
+ if (!MatchFinder_Create(&_lzInWindow,
+ m_Deflate64Mode ? kHistorySize64 : kHistorySize32,
+ kNumOpts + kMaxUncompressedBlockSize,
+ m_NumFastBytes, m_MatchMaxLen - m_NumFastBytes, &g_Alloc))
+ return E_OUTOFMEMORY;
+ if (!m_OutStream.Create(1 << 20))
+ return E_OUTOFMEMORY;
+ }
+ if (m_MatchFinderCycles != 0)
+ _lzInWindow.cutValue = m_MatchFinderCycles;
+ m_Created = true;
+ return S_OK;
+ COM_TRY_END
+}
+
+// ICompressSetEncoderProperties2
+HRESULT CCoder::BaseSetEncoderProperties2(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties)
+{
+ for(UInt32 i = 0; i < numProperties; i++)
+ {
+ const PROPVARIANT &prop = properties[i];
+ switch(propIDs[i])
+ {
+ case NCoderPropID::kNumPasses:
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ m_NumDivPasses = prop.ulVal;
+ if (m_NumDivPasses == 0)
+ m_NumDivPasses = 1;
+ if (m_NumDivPasses == 1)
+ m_NumPasses = 1;
+ else if (m_NumDivPasses <= kNumDivPassesMax)
+ m_NumPasses = 2;
+ else
+ {
+ m_NumPasses = 2 + (m_NumDivPasses - kNumDivPassesMax);
+ m_NumDivPasses = kNumDivPassesMax;
+ }
+ break;
+ case NCoderPropID::kNumFastBytes:
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ m_NumFastBytes = prop.ulVal;
+ if(m_NumFastBytes < kMatchMinLen || m_NumFastBytes > m_MatchMaxLen)
+ return E_INVALIDARG;
+ break;
+ case NCoderPropID::kMatchFinderCycles:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ m_MatchFinderCycles = prop.ulVal;
+ break;
+ }
+ default:
+ return E_INVALIDARG;
+ }
+ }
+ return S_OK;
+}
+
+void CCoder::Free()
+{
+ ::MidFree(m_OnePosMatchesMemory);
+ m_OnePosMatchesMemory = 0;
+ ::MyFree(m_DistanceMemory);
+ m_DistanceMemory = 0;
+ ::MyFree(m_Values);
+ m_Values = 0;
+ ::MyFree(m_Tables);
+ m_Tables = 0;
+}
+
+CCoder::~CCoder()
+{
+ Free();
+ MatchFinder_Free(&_lzInWindow, &g_Alloc);
+}
+
+void CCoder::GetMatches()
+{
+ if (m_IsMultiPass)
+ {
+ m_MatchDistances = m_OnePosMatchesMemory + m_Pos;
+ if (m_SecondPass)
+ {
+ m_Pos += *m_MatchDistances + 1;
+ return;
+ }
+ }
+
+ UInt32 distanceTmp[kMatchMaxLen * 2 + 3];
+
+ UInt32 numPairs = Bt3Zip_MatchFinder_GetMatches(&_lzInWindow, distanceTmp);
+ *m_MatchDistances = (UInt16)numPairs;
+
+ if (numPairs > 0)
+ {
+ UInt32 i;
+ for(i = 0; i < numPairs; i += 2)
+ {
+ m_MatchDistances[i + 1] = (UInt16)distanceTmp[i];
+ m_MatchDistances[i + 2] = (UInt16)distanceTmp[i + 1];
+ }
+ UInt32 len = distanceTmp[numPairs - 2];
+ if (len == m_NumFastBytes && m_NumFastBytes != m_MatchMaxLen)
+ {
+ UInt32 numAvail = Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) + 1;
+ const Byte *pby = Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow) - 1;
+ UInt32 distance = distanceTmp[numPairs - 1] + 1;
+ if (numAvail > m_MatchMaxLen)
+ numAvail = m_MatchMaxLen;
+ for (; len < numAvail && pby[len] == pby[(size_t)len - distance]; len++);
+ m_MatchDistances[i - 1] = (UInt16)len;
+ }
+ }
+ if (m_IsMultiPass)
+ m_Pos += numPairs + 1;
+ if (!m_SecondPass)
+ m_AdditionalOffset++;
+}
+
+void CCoder::MovePos(UInt32 num)
+{
+ if (!m_SecondPass && num > 0)
+ {
+ Bt3Zip_MatchFinder_Skip(&_lzInWindow, num);
+ m_AdditionalOffset += num;
+ }
+}
+
+static const UInt32 kIfinityPrice = 0xFFFFFFF;
+
+NO_INLINE UInt32 CCoder::Backward(UInt32 &backRes, UInt32 cur)
+{
+ m_OptimumEndIndex = cur;
+ UInt32 posMem = m_Optimum[cur].PosPrev;
+ UInt16 backMem = m_Optimum[cur].BackPrev;
+ do
+ {
+ UInt32 posPrev = posMem;
+ UInt16 backCur = backMem;
+ backMem = m_Optimum[posPrev].BackPrev;
+ posMem = m_Optimum[posPrev].PosPrev;
+ m_Optimum[posPrev].BackPrev = backCur;
+ m_Optimum[posPrev].PosPrev = (UInt16)cur;
+ cur = posPrev;
+ }
+ while(cur > 0);
+ backRes = m_Optimum[0].BackPrev;
+ m_OptimumCurrentIndex = m_Optimum[0].PosPrev;
+ return m_OptimumCurrentIndex;
+}
+
+NO_INLINE UInt32 CCoder::GetOptimal(UInt32 &backRes)
+{
+ if(m_OptimumEndIndex != m_OptimumCurrentIndex)
+ {
+ UInt32 len = m_Optimum[m_OptimumCurrentIndex].PosPrev - m_OptimumCurrentIndex;
+ backRes = m_Optimum[m_OptimumCurrentIndex].BackPrev;
+ m_OptimumCurrentIndex = m_Optimum[m_OptimumCurrentIndex].PosPrev;
+ return len;
+ }
+ m_OptimumCurrentIndex = m_OptimumEndIndex = 0;
+
+ GetMatches();
+
+ UInt32 numDistancePairs = m_MatchDistances[0];
+ if(numDistancePairs == 0)
+ return 1;
+
+ const UInt16 *matchDistances = m_MatchDistances + 1;
+ UInt32 lenMain = matchDistances[numDistancePairs - 2];
+
+ if(lenMain > m_NumFastBytes)
+ {
+ backRes = matchDistances[numDistancePairs - 1];
+ MovePos(lenMain - 1);
+ return lenMain;
+ }
+ m_Optimum[1].Price = m_LiteralPrices[Inline_MatchFinder_GetIndexByte(&_lzInWindow, 0 - m_AdditionalOffset)];
+ m_Optimum[1].PosPrev = 0;
+
+ m_Optimum[2].Price = kIfinityPrice;
+ m_Optimum[2].PosPrev = 1;
+
+
+ UInt32 offs = 0;
+ for(UInt32 i = kMatchMinLen; i <= lenMain; i++)
+ {
+ UInt32 distance = matchDistances[offs + 1];
+ m_Optimum[i].PosPrev = 0;
+ m_Optimum[i].BackPrev = (UInt16)distance;
+ m_Optimum[i].Price = m_LenPrices[i - kMatchMinLen] + m_PosPrices[GetPosSlot(distance)];
+ if (i == matchDistances[offs])
+ offs += 2;
+ }
+
+ UInt32 cur = 0;
+ UInt32 lenEnd = lenMain;
+ for (;;)
+ {
+ ++cur;
+ if(cur == lenEnd || cur == kNumOptsBase || m_Pos >= kMatchArrayLimit)
+ return Backward(backRes, cur);
+ GetMatches();
+ matchDistances = m_MatchDistances + 1;
+
+ UInt32 numDistancePairs = m_MatchDistances[0];
+ UInt32 newLen = 0;
+ if(numDistancePairs != 0)
+ {
+ newLen = matchDistances[numDistancePairs - 2];
+ if(newLen > m_NumFastBytes)
+ {
+ UInt32 len = Backward(backRes, cur);
+ m_Optimum[cur].BackPrev = matchDistances[numDistancePairs - 1];
+ m_OptimumEndIndex = cur + newLen;
+ m_Optimum[cur].PosPrev = (UInt16)m_OptimumEndIndex;
+ MovePos(newLen - 1);
+ return len;
+ }
+ }
+ UInt32 curPrice = m_Optimum[cur].Price;
+ UInt32 curAnd1Price = curPrice + m_LiteralPrices[Inline_MatchFinder_GetIndexByte(&_lzInWindow, cur - m_AdditionalOffset)];
+ COptimal &optimum = m_Optimum[cur + 1];
+ if (curAnd1Price < optimum.Price)
+ {
+ optimum.Price = curAnd1Price;
+ optimum.PosPrev = (UInt16)cur;
+ }
+ if(numDistancePairs == 0)
+ continue;
+ while(lenEnd < cur + newLen)
+ m_Optimum[++lenEnd].Price = kIfinityPrice;
+ offs = 0;
+ UInt32 distance = matchDistances[offs + 1];
+ curPrice += m_PosPrices[GetPosSlot(distance)];
+ for(UInt32 lenTest = kMatchMinLen; ; lenTest++)
+ {
+ UInt32 curAndLenPrice = curPrice + m_LenPrices[lenTest - kMatchMinLen];
+ COptimal &optimum = m_Optimum[cur + lenTest];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = (UInt16)cur;
+ optimum.BackPrev = (UInt16)distance;
+ }
+ if (lenTest == matchDistances[offs])
+ {
+ offs += 2;
+ if (offs == numDistancePairs)
+ break;
+ curPrice -= m_PosPrices[GetPosSlot(distance)];
+ distance = matchDistances[offs + 1];
+ curPrice += m_PosPrices[GetPosSlot(distance)];
+ }
+ }
+ }
+}
+
+void CTables::InitStructures()
+{
+ UInt32 i;
+ for(i = 0; i < 256; i++)
+ litLenLevels[i] = 8;
+ litLenLevels[i++] = 13;
+ for(;i < kFixedMainTableSize; i++)
+ litLenLevels[i] = 5;
+ for(i = 0; i < kFixedDistTableSize; i++)
+ distLevels[i] = 5;
+}
+
+NO_INLINE void CCoder::LevelTableDummy(const Byte *levels, int numLevels, UInt32 *freqs)
+{
+ int prevLen = 0xFF;
+ int nextLen = levels[0];
+ int count = 0;
+ int maxCount = 7;
+ int minCount = 4;
+ if (nextLen == 0)
+ {
+ maxCount = 138;
+ minCount = 3;
+ }
+ for (int n = 0; n < numLevels; n++)
+ {
+ int curLen = nextLen;
+ nextLen = (n < numLevels - 1) ? levels[n + 1] : 0xFF;
+ count++;
+ if (count < maxCount && curLen == nextLen)
+ continue;
+
+ if (count < minCount)
+ freqs[curLen] += (UInt32)count;
+ else if (curLen != 0)
+ {
+ if (curLen != prevLen)
+ {
+ freqs[curLen]++;
+ count--;
+ }
+ freqs[kTableLevelRepNumber]++;
+ }
+ else if (count <= 10)
+ freqs[kTableLevel0Number]++;
+ else
+ freqs[kTableLevel0Number2]++;
+
+ count = 0;
+ prevLen = curLen;
+
+ if (nextLen == 0)
+ {
+ maxCount = 138;
+ minCount = 3;
+ }
+ else if (curLen == nextLen)
+ {
+ maxCount = 6;
+ minCount = 3;
+ }
+ else
+ {
+ maxCount = 7;
+ minCount = 4;
+ }
+ }
+}
+
+#define WRITE_HF2(codes, lens, i) m_OutStream.WriteBits(codes[i], lens[i])
+#define WRITE_HF(i) m_OutStream.WriteBits(codes[i], lens[i])
+
+NO_INLINE void CCoder::LevelTableCode(const Byte *levels, int numLevels, const Byte *lens, const UInt32 *codes)
+{
+ int prevLen = 0xFF;
+ int nextLen = levels[0];
+ int count = 0;
+ int maxCount = 7;
+ int minCount = 4;
+ if (nextLen == 0)
+ {
+ maxCount = 138;
+ minCount = 3;
+ }
+ for (int n = 0; n < numLevels; n++)
+ {
+ int curLen = nextLen;
+ nextLen = (n < numLevels - 1) ? levels[n + 1] : 0xFF;
+ count++;
+ if (count < maxCount && curLen == nextLen)
+ continue;
+
+ if (count < minCount)
+ for(int i = 0; i < count; i++)
+ WRITE_HF(curLen);
+ else if (curLen != 0)
+ {
+ if (curLen != prevLen)
+ {
+ WRITE_HF(curLen);
+ count--;
+ }
+ WRITE_HF(kTableLevelRepNumber);
+ m_OutStream.WriteBits(count - 3, 2);
+ }
+ else if (count <= 10)
+ {
+ WRITE_HF(kTableLevel0Number);
+ m_OutStream.WriteBits(count - 3, 3);
+ }
+ else
+ {
+ WRITE_HF(kTableLevel0Number2);
+ m_OutStream.WriteBits(count - 11, 7);
+ }
+
+ count = 0;
+ prevLen = curLen;
+
+ if (nextLen == 0)
+ {
+ maxCount = 138;
+ minCount = 3;
+ }
+ else if (curLen == nextLen)
+ {
+ maxCount = 6;
+ minCount = 3;
+ }
+ else
+ {
+ maxCount = 7;
+ minCount = 4;
+ }
+ }
+}
+
+NO_INLINE void CCoder::MakeTables()
+{
+ Huffman_Generate(mainFreqs, mainCodes, m_NewLevels.litLenLevels, kFixedMainTableSize, kMaxCodeBitLength);
+ Huffman_Generate(distFreqs, distCodes, m_NewLevels.distLevels, kDistTableSize64, kMaxCodeBitLength);
+}
+
+NO_INLINE UInt32 Huffman_GetPrice(const UInt32 *freqs, const Byte *lens, UInt32 num)
+{
+ UInt32 price = 0;
+ UInt32 i;
+ for (i = 0; i < num; i++)
+ price += lens[i] * freqs[i];
+ return price;
+};
+
+NO_INLINE UInt32 Huffman_GetPrice_Spec(const UInt32 *freqs, const Byte *lens, UInt32 num, const Byte *extraBits, UInt32 extraBase)
+{
+ return Huffman_GetPrice(freqs, lens, num) +
+ Huffman_GetPrice(freqs + extraBase, extraBits, num - extraBase);
+}
+
+NO_INLINE UInt32 CCoder::GetLzBlockPrice() const
+{
+ return
+ Huffman_GetPrice_Spec(mainFreqs, m_NewLevels.litLenLevels, kFixedMainTableSize, m_LenDirectBits, kSymbolMatch) +
+ Huffman_GetPrice_Spec(distFreqs, m_NewLevels.distLevels, kDistTableSize64, kDistDirectBits, 0);
+}
+
+NO_INLINE void CCoder::TryBlock()
+{
+ memset(mainFreqs, 0, sizeof(mainFreqs));
+ memset(distFreqs, 0, sizeof(distFreqs));
+
+ m_ValueIndex = 0;
+ UInt32 blockSize = BlockSizeRes;
+ BlockSizeRes = 0;
+ for (;;)
+ {
+ if (m_OptimumCurrentIndex == m_OptimumEndIndex)
+ {
+ if (m_Pos >= kMatchArrayLimit || BlockSizeRes >= blockSize || !m_SecondPass &&
+ ((Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) == 0) || m_ValueIndex >= m_ValueBlockSize))
+ break;
+ }
+ UInt32 pos;
+ UInt32 len = GetOptimal(pos);
+ CCodeValue &codeValue = m_Values[m_ValueIndex++];
+ if (len >= kMatchMinLen)
+ {
+ UInt32 newLen = len - kMatchMinLen;
+ codeValue.Len = (UInt16)newLen;
+ mainFreqs[kSymbolMatch + g_LenSlots[newLen]]++;
+ codeValue.Pos = (UInt16)pos;
+ distFreqs[GetPosSlot(pos)]++;
+ }
+ else
+ {
+ Byte b = Inline_MatchFinder_GetIndexByte(&_lzInWindow, 0 - m_AdditionalOffset);
+ mainFreqs[b]++;
+ codeValue.SetAsLiteral();
+ codeValue.Pos = b;
+ }
+ m_AdditionalOffset -= len;
+ BlockSizeRes += len;
+ }
+ mainFreqs[kSymbolEndOfBlock]++;
+ m_AdditionalOffset += BlockSizeRes;
+ m_SecondPass = true;
+}
+
+NO_INLINE void CCoder::SetPrices(const CLevels &levels)
+{
+ UInt32 i;
+ for(i = 0; i < 256; i++)
+ {
+ Byte price = levels.litLenLevels[i];
+ m_LiteralPrices[i] = ((price != 0) ? price : kNoLiteralStatPrice);
+ }
+
+ for(i = 0; i < m_NumLenCombinations; i++)
+ {
+ UInt32 slot = g_LenSlots[i];
+ Byte price = levels.litLenLevels[kSymbolMatch + slot];
+ m_LenPrices[i] = (Byte)(((price != 0) ? price : kNoLenStatPrice) + m_LenDirectBits[slot]);
+ }
+
+ for(i = 0; i < kDistTableSize64; i++)
+ {
+ Byte price = levels.distLevels[i];
+ m_PosPrices[i] = (Byte)(((price != 0) ? price: kNoPosStatPrice) + kDistDirectBits[i]);
+ }
+}
+
+NO_INLINE void Huffman_ReverseBits(UInt32 *codes, const Byte *lens, UInt32 num)
+{
+ for (UInt32 i = 0; i < num; i++)
+ {
+ UInt32 x = codes[i];
+ x = ((x & 0x5555) << 1) | ((x & 0xAAAA) >> 1);
+ x = ((x & 0x3333) << 2) | ((x & 0xCCCC) >> 2);
+ x = ((x & 0x0F0F) << 4) | ((x & 0xF0F0) >> 4);
+ codes[i] = (((x & 0x00FF) << 8) | ((x & 0xFF00) >> 8)) >> (16 - lens[i]);
+ }
+}
+
+NO_INLINE void CCoder::WriteBlock()
+{
+ Huffman_ReverseBits(mainCodes, m_NewLevels.litLenLevels, kFixedMainTableSize);
+ Huffman_ReverseBits(distCodes, m_NewLevels.distLevels, kDistTableSize64);
+
+ for (UInt32 i = 0; i < m_ValueIndex; i++)
+ {
+ const CCodeValue &codeValue = m_Values[i];
+ if (codeValue.IsLiteral())
+ WRITE_HF2(mainCodes, m_NewLevels.litLenLevels, codeValue.Pos);
+ else
+ {
+ UInt32 len = codeValue.Len;
+ UInt32 lenSlot = g_LenSlots[len];
+ WRITE_HF2(mainCodes, m_NewLevels.litLenLevels, kSymbolMatch + lenSlot);
+ m_OutStream.WriteBits(len - m_LenStart[lenSlot], m_LenDirectBits[lenSlot]);
+ UInt32 dist = codeValue.Pos;
+ UInt32 posSlot = GetPosSlot(dist);
+ WRITE_HF2(distCodes, m_NewLevels.distLevels, posSlot);
+ m_OutStream.WriteBits(dist - kDistStart[posSlot], kDistDirectBits[posSlot]);
+ }
+ }
+ WRITE_HF2(mainCodes, m_NewLevels.litLenLevels, kSymbolEndOfBlock);
+}
+
+static UInt32 GetStorePrice(UInt32 blockSize, int bitPosition)
+{
+ UInt32 price = 0;
+ do
+ {
+ UInt32 nextBitPosition = (bitPosition + kFinalBlockFieldSize + kBlockTypeFieldSize) & 7;
+ int numBitsForAlign = nextBitPosition > 0 ? (8 - nextBitPosition): 0;
+ UInt32 curBlockSize = (blockSize < (1 << 16)) ? blockSize : (1 << 16) - 1;
+ price += kFinalBlockFieldSize + kBlockTypeFieldSize + numBitsForAlign + (2 + 2) * 8 + curBlockSize * 8;
+ bitPosition = 0;
+ blockSize -= curBlockSize;
+ }
+ while(blockSize != 0);
+ return price;
+}
+
+void CCoder::WriteStoreBlock(UInt32 blockSize, UInt32 additionalOffset, bool finalBlock)
+{
+ do
+ {
+ UInt32 curBlockSize = (blockSize < (1 << 16)) ? blockSize : (1 << 16) - 1;
+ blockSize -= curBlockSize;
+ m_OutStream.WriteBits((finalBlock && (blockSize == 0) ? NFinalBlockField::kFinalBlock: NFinalBlockField::kNotFinalBlock), kFinalBlockFieldSize);
+ m_OutStream.WriteBits(NBlockType::kStored, kBlockTypeFieldSize);
+ m_OutStream.FlushByte();
+ m_OutStream.WriteBits((UInt16)curBlockSize, kStoredBlockLengthFieldSize);
+ m_OutStream.WriteBits((UInt16)~curBlockSize, kStoredBlockLengthFieldSize);
+ const Byte *data = Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow)- additionalOffset;
+ for(UInt32 i = 0; i < curBlockSize; i++)
+ m_OutStream.WriteByte(data[i]);
+ additionalOffset -= curBlockSize;
+ }
+ while(blockSize != 0);
+}
+
+NO_INLINE UInt32 CCoder::TryDynBlock(int tableIndex, UInt32 numPasses)
+{
+ CTables &t = m_Tables[tableIndex];
+ BlockSizeRes = t.BlockSizeRes;
+ UInt32 posTemp = t.m_Pos;
+ SetPrices(t);
+
+ for (UInt32 p = 0; p < numPasses; p++)
+ {
+ m_Pos = posTemp;
+ TryBlock();
+ MakeTables();
+ SetPrices(m_NewLevels);
+ }
+
+ (CLevels &)t = m_NewLevels;
+
+ m_NumLitLenLevels = kMainTableSize;
+ while(m_NumLitLenLevels > kNumLitLenCodesMin && m_NewLevels.litLenLevels[m_NumLitLenLevels - 1] == 0)
+ m_NumLitLenLevels--;
+
+ m_NumDistLevels = kDistTableSize64;
+ while(m_NumDistLevels > kNumDistCodesMin && m_NewLevels.distLevels[m_NumDistLevels - 1] == 0)
+ m_NumDistLevels--;
+
+ UInt32 levelFreqs[kLevelTableSize];
+ memset(levelFreqs, 0, sizeof(levelFreqs));
+
+ LevelTableDummy(m_NewLevels.litLenLevels, m_NumLitLenLevels, levelFreqs);
+ LevelTableDummy(m_NewLevels.distLevels, m_NumDistLevels, levelFreqs);
+
+ Huffman_Generate(levelFreqs, levelCodes, levelLens, kLevelTableSize, kMaxLevelBitLength);
+
+ m_NumLevelCodes = kNumLevelCodesMin;
+ for (UInt32 i = 0; i < kLevelTableSize; i++)
+ {
+ Byte level = levelLens[kCodeLengthAlphabetOrder[i]];
+ if (level > 0 && i >= m_NumLevelCodes)
+ m_NumLevelCodes = i + 1;
+ m_LevelLevels[i] = level;
+ }
+
+ return GetLzBlockPrice() +
+ Huffman_GetPrice_Spec(levelFreqs, levelLens, kLevelTableSize, kLevelDirectBits, kTableDirectLevels) +
+ kNumLenCodesFieldSize + kNumDistCodesFieldSize + kNumLevelCodesFieldSize +
+ m_NumLevelCodes * kLevelFieldSize + kFinalBlockFieldSize + kBlockTypeFieldSize;
+}
+
+NO_INLINE UInt32 CCoder::TryFixedBlock(int tableIndex)
+{
+ CTables &t = m_Tables[tableIndex];
+ BlockSizeRes = t.BlockSizeRes;
+ m_Pos = t.m_Pos;
+ m_NewLevels.SetFixedLevels();
+ SetPrices(m_NewLevels);
+ TryBlock();
+ return kFinalBlockFieldSize + kBlockTypeFieldSize + GetLzBlockPrice();
+}
+
+NO_INLINE UInt32 CCoder::GetBlockPrice(int tableIndex, int numDivPasses)
+{
+ CTables &t = m_Tables[tableIndex];
+ t.StaticMode = false;
+ UInt32 price = TryDynBlock(tableIndex, m_NumPasses);
+ t.BlockSizeRes = BlockSizeRes;
+ UInt32 numValues = m_ValueIndex;
+ UInt32 posTemp = m_Pos;
+ UInt32 additionalOffsetEnd = m_AdditionalOffset;
+
+ if (m_CheckStatic && m_ValueIndex <= kFixedHuffmanCodeBlockSizeMax)
+ {
+ const UInt32 fixedPrice = TryFixedBlock(tableIndex);
+ t.StaticMode = (fixedPrice < price);
+ if (t.StaticMode)
+ price = fixedPrice;
+ }
+
+ const UInt32 storePrice = GetStorePrice(BlockSizeRes, 0); // bitPosition
+ t.StoreMode = (storePrice <= price);
+ if (t.StoreMode)
+ price = storePrice;
+
+ t.UseSubBlocks = false;
+
+ if (numDivPasses > 1 && numValues >= kDivideCodeBlockSizeMin)
+ {
+ CTables &t0 = m_Tables[(tableIndex << 1)];
+ (CLevels &)t0 = t;
+ t0.BlockSizeRes = t.BlockSizeRes >> 1;
+ t0.m_Pos = t.m_Pos;
+ UInt32 subPrice = GetBlockPrice((tableIndex << 1), numDivPasses - 1);
+
+ UInt32 blockSize2 = t.BlockSizeRes - t0.BlockSizeRes;
+ if (t0.BlockSizeRes >= kDivideBlockSizeMin && blockSize2 >= kDivideBlockSizeMin)
+ {
+ CTables &t1 = m_Tables[(tableIndex << 1) + 1];
+ (CLevels &)t1 = t;
+ t1.BlockSizeRes = blockSize2;
+ t1.m_Pos = m_Pos;
+ m_AdditionalOffset -= t0.BlockSizeRes;
+ subPrice += GetBlockPrice((tableIndex << 1) + 1, numDivPasses - 1);
+ t.UseSubBlocks = (subPrice < price);
+ if (t.UseSubBlocks)
+ price = subPrice;
+ }
+ }
+ m_AdditionalOffset = additionalOffsetEnd;
+ m_Pos = posTemp;
+ return price;
+}
+
+void CCoder::CodeBlock(int tableIndex, bool finalBlock)
+{
+ CTables &t = m_Tables[tableIndex];
+ if (t.UseSubBlocks)
+ {
+ CodeBlock((tableIndex << 1), false);
+ CodeBlock((tableIndex << 1) + 1, finalBlock);
+ }
+ else
+ {
+ if (t.StoreMode)
+ WriteStoreBlock(t.BlockSizeRes, m_AdditionalOffset, finalBlock);
+ else
+ {
+ m_OutStream.WriteBits((finalBlock ? NFinalBlockField::kFinalBlock: NFinalBlockField::kNotFinalBlock), kFinalBlockFieldSize);
+ if (t.StaticMode)
+ {
+ m_OutStream.WriteBits(NBlockType::kFixedHuffman, kBlockTypeFieldSize);
+ TryFixedBlock(tableIndex);
+ int i;
+ for (i = 0; i < kFixedMainTableSize; i++)
+ mainFreqs[i] = (UInt32)1 << (kNumHuffmanBits - m_NewLevels.litLenLevels[i]);
+ for (i = 0; i < kFixedDistTableSize; i++)
+ distFreqs[i] = (UInt32)1 << (kNumHuffmanBits - m_NewLevels.distLevels[i]);
+ MakeTables();
+ }
+ else
+ {
+ if (m_NumDivPasses > 1 || m_CheckStatic)
+ TryDynBlock(tableIndex, 1);
+ m_OutStream.WriteBits(NBlockType::kDynamicHuffman, kBlockTypeFieldSize);
+ m_OutStream.WriteBits(m_NumLitLenLevels - kNumLitLenCodesMin, kNumLenCodesFieldSize);
+ m_OutStream.WriteBits(m_NumDistLevels - kNumDistCodesMin, kNumDistCodesFieldSize);
+ m_OutStream.WriteBits(m_NumLevelCodes - kNumLevelCodesMin, kNumLevelCodesFieldSize);
+
+ for (UInt32 i = 0; i < m_NumLevelCodes; i++)
+ m_OutStream.WriteBits(m_LevelLevels[i], kLevelFieldSize);
+
+ Huffman_ReverseBits(levelCodes, levelLens, kLevelTableSize);
+ LevelTableCode(m_NewLevels.litLenLevels, m_NumLitLenLevels, levelLens, levelCodes);
+ LevelTableCode(m_NewLevels.distLevels, m_NumDistLevels, levelLens, levelCodes);
+ }
+ WriteBlock();
+ }
+ m_AdditionalOffset -= t.BlockSizeRes;
+ }
+}
+
+HRes Read(void *object, void *data, UInt32 size, UInt32 *processedSize)
+{
+ return (HRes)((CSeqInStream *)object)->RealStream->Read(data, size, processedSize);
+}
+
+HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 * /* inSize */ , const UInt64 * /* outSize */ ,
+ ICompressProgressInfo *progress)
+{
+ m_CheckStatic = (m_NumPasses != 1 || m_NumDivPasses != 1);
+ m_IsMultiPass = (m_CheckStatic || (m_NumPasses != 1 || m_NumDivPasses != 1));
+
+ RINOK(Create());
+
+ m_ValueBlockSize = (1 << 13) + (1 << 12) * m_NumDivPasses;
+
+ UInt64 nowPos = 0;
+
+ _seqInStream.RealStream = inStream;
+ _seqInStream.SeqInStream.Read = Read;
+ _lzInWindow.stream = &_seqInStream.SeqInStream;
+
+ MatchFinder_Init(&_lzInWindow);
+ m_OutStream.SetStream(outStream);
+ m_OutStream.Init();
+
+ CCoderReleaser coderReleaser(this);
+
+ m_OptimumEndIndex = m_OptimumCurrentIndex = 0;
+
+ CTables &t = m_Tables[1];
+ t.m_Pos = 0;
+ t.InitStructures();
+
+ m_AdditionalOffset = 0;
+ do
+ {
+ t.BlockSizeRes = kBlockUncompressedSizeThreshold;
+ m_SecondPass = false;
+ GetBlockPrice(1, m_NumDivPasses);
+ CodeBlock(1, Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) == 0);
+ nowPos += m_Tables[1].BlockSizeRes;
+ if (progress != NULL)
+ {
+ UInt64 packSize = m_OutStream.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&nowPos, &packSize));
+ }
+ }
+ while (Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) != 0);
+ if (_lzInWindow.result != SZ_OK)
+ return _lzInWindow.result;
+ return m_OutStream.Flush();
+}
+
+HRESULT CCoder::BaseCode(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
+ catch(const COutBufferException &e) { return e.ErrorCode; }
+ catch(...) { return E_FAIL; }
+}
+
+STDMETHODIMP CCOMCoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+ { return BaseCode(inStream, outStream, inSize, outSize, progress); }
+
+STDMETHODIMP CCOMCoder::SetCoderProperties(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties)
+ { return BaseSetEncoderProperties2(propIDs, properties, numProperties); }
+
+STDMETHODIMP CCOMCoder64::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+ { return BaseCode(inStream, outStream, inSize, outSize, progress); }
+
+STDMETHODIMP CCOMCoder64::SetCoderProperties(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties)
+ { return BaseSetEncoderProperties2(propIDs, properties, numProperties); }
+
+}}}
+
diff --git a/CPP/7zip/Compress/Deflate/DeflateEncoder.h b/CPP/7zip/Compress/Deflate/DeflateEncoder.h
new file mode 100755
index 00000000..86eede6f
--- /dev/null
+++ b/CPP/7zip/Compress/Deflate/DeflateEncoder.h
@@ -0,0 +1,221 @@
+// DeflateEncoder.h
+
+#ifndef __DEFLATE_ENCODER_H
+#define __DEFLATE_ENCODER_H
+
+#include "Common/MyCom.h"
+
+#include "../../ICoder.h"
+#include "../../Common/LSBFEncoder.h"
+
+#include "DeflateConst.h"
+
+extern "C"
+{
+ #include "../../../../C/Compress/Lz/MatchFinder.h"
+}
+
+namespace NCompress {
+namespace NDeflate {
+namespace NEncoder {
+
+struct CCodeValue
+{
+ UInt16 Len;
+ UInt16 Pos;
+ void SetAsLiteral() { Len = (1 << 15); }
+ bool IsLiteral() const { return ((Len & (1 << 15)) != 0); }
+};
+
+struct COptimal
+{
+ UInt32 Price;
+ UInt16 PosPrev;
+ UInt16 BackPrev;
+};
+
+const UInt32 kNumOptsBase = 1 << 12;
+const UInt32 kNumOpts = kNumOptsBase + kMatchMaxLen;
+
+class CCoder;
+
+struct CTables: public CLevels
+{
+ bool UseSubBlocks;
+ bool StoreMode;
+ bool StaticMode;
+ UInt32 BlockSizeRes;
+ UInt32 m_Pos;
+ void InitStructures();
+};
+
+typedef struct _CSeqInStream
+{
+ ISeqInStream SeqInStream;
+ CMyComPtr<ISequentialInStream> RealStream;
+} CSeqInStream;
+
+class CCoder
+{
+ CMatchFinder _lzInWindow;
+ NStream::NLSBF::CEncoder m_OutStream;
+
+ CSeqInStream _seqInStream;
+
+public:
+ CCodeValue *m_Values;
+
+ UInt16 *m_MatchDistances;
+ UInt32 m_NumFastBytes;
+
+ UInt16 *m_OnePosMatchesMemory;
+ UInt16 *m_DistanceMemory;
+
+ UInt32 m_Pos;
+
+ int m_NumPasses;
+ int m_NumDivPasses;
+ bool m_CheckStatic;
+ bool m_IsMultiPass;
+ UInt32 m_ValueBlockSize;
+
+ UInt32 m_NumLenCombinations;
+ UInt32 m_MatchMaxLen;
+ const Byte *m_LenStart;
+ const Byte *m_LenDirectBits;
+
+ bool m_Created;
+ bool m_Deflate64Mode;
+
+ Byte m_LevelLevels[kLevelTableSize];
+ int m_NumLitLenLevels;
+ int m_NumDistLevels;
+ UInt32 m_NumLevelCodes;
+ UInt32 m_ValueIndex;
+
+ bool m_SecondPass;
+ UInt32 m_AdditionalOffset;
+
+ UInt32 m_OptimumEndIndex;
+ UInt32 m_OptimumCurrentIndex;
+
+ Byte m_LiteralPrices[256];
+ Byte m_LenPrices[kNumLenSymbolsMax];
+ Byte m_PosPrices[kDistTableSize64];
+
+ CLevels m_NewLevels;
+ UInt32 mainFreqs[kFixedMainTableSize];
+ UInt32 distFreqs[kDistTableSize64];
+ UInt32 mainCodes[kFixedMainTableSize];
+ UInt32 distCodes[kDistTableSize64];
+ UInt32 levelCodes[kLevelTableSize];
+ Byte levelLens[kLevelTableSize];
+
+ UInt32 BlockSizeRes;
+
+ CTables *m_Tables;
+ COptimal m_Optimum[kNumOpts];
+
+ UInt32 m_MatchFinderCycles;
+ // IMatchFinderSetNumPasses *m_SetMfPasses;
+
+ void GetMatches();
+ void MovePos(UInt32 num);
+ UInt32 Backward(UInt32 &backRes, UInt32 cur);
+ UInt32 GetOptimal(UInt32 &backRes);
+
+ void LevelTableDummy(const Byte *levels, int numLevels, UInt32 *freqs);
+ void LevelTableCode(const Byte *levels, int numLevels, const Byte *lens, const UInt32 *codes);
+
+ void MakeTables();
+ UInt32 GetLzBlockPrice() const;
+ void TryBlock();
+ UInt32 TryDynBlock(int tableIndex, UInt32 numPasses);
+
+ UInt32 TryFixedBlock(int tableIndex);
+
+ void SetPrices(const CLevels &levels);
+ void WriteBlock();
+
+ HRESULT Create();
+ void Free();
+
+ void WriteStoreBlock(UInt32 blockSize, UInt32 additionalOffset, bool finalBlock);
+ void WriteTables(bool writeMode, bool finalBlock);
+
+ void WriteBlockData(bool writeMode, bool finalBlock);
+
+ void ReleaseStreams()
+ {
+ _seqInStream.RealStream.Release();
+ m_OutStream.ReleaseStream();
+ }
+ class CCoderReleaser
+ {
+ CCoder *m_Coder;
+ public:
+ CCoderReleaser(CCoder *coder): m_Coder(coder) {}
+ ~CCoderReleaser() { m_Coder->ReleaseStreams(); }
+ };
+ friend class CCoderReleaser;
+
+ UInt32 GetBlockPrice(int tableIndex, int numDivPasses);
+ void CodeBlock(int tableIndex, bool finalBlock);
+
+public:
+ CCoder(bool deflate64Mode = false);
+ ~CCoder();
+
+ HRESULT CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ HRESULT BaseCode(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ // ICompressSetCoderProperties
+ HRESULT BaseSetEncoderProperties2(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties);
+};
+
+///////////////////////////////////////////////////////////////
+
+class CCOMCoder :
+ public ICompressCoder,
+ public ICompressSetCoderProperties,
+ public CMyUnknownImp,
+ public CCoder
+{
+public:
+ MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
+ CCOMCoder(): CCoder(false) {};
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+ // ICompressSetCoderProperties
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties);
+};
+
+class CCOMCoder64 :
+ public ICompressCoder,
+ public ICompressSetCoderProperties,
+ public CMyUnknownImp,
+ public CCoder
+{
+public:
+ MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
+ CCOMCoder64(): CCoder(true) {};
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+ // ICompressSetCoderProperties
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties);
+};
+
+
+}}}
+
+#endif
diff --git a/CPP/7zip/Compress/Deflate/DllExports.cpp b/CPP/7zip/Compress/Deflate/DllExports.cpp
new file mode 100755
index 00000000..a0b23562
--- /dev/null
+++ b/CPP/7zip/Compress/Deflate/DllExports.cpp
@@ -0,0 +1,157 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+
+#include "DeflateEncoder.h"
+#include "DeflateDecoder.h"
+
+#ifdef CRC_GENERATE_TABLE
+extern "C"
+{
+ #include "../../../../C/7zCrc.h"
+}
+#endif
+
+// {23170F69-40C1-278B-0401-080000000000}
+DEFINE_GUID(CLSID_CCompressDeflateDecoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+// {23170F69-40C1-278B-0401-090000000000}
+DEFINE_GUID(CLSID_CCompressDeflate64Decoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+// {23170F69-40C1-278B-0401-080000000100}
+DEFINE_GUID(CLSID_CCompressDeflateEncoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00);
+
+// {23170F69-40C1-278B-0401-090000000100}
+DEFINE_GUID(CLSID_CCompressDeflate64Encoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00);
+
+
+// {23170F69-40C1-278B-0409-010000000000}
+DEFINE_GUID(CLSID_CCompressDeflateNsisDecoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ #ifdef CRC_GENERATE_TABLE
+ CrcGenerateTable();
+ #endif
+ }
+ 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_CCompressDeflateDecoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder = (ICompressCoder *)new NCompress::NDeflate::NDecoder::CCOMCoder();
+ }
+ else if (*clsid == CLSID_CCompressDeflateNsisDecoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder = (ICompressCoder *)new NCompress::NDeflate::NDecoder::CNsisCOMCoder();
+ }
+ else if (*clsid == CLSID_CCompressDeflateEncoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder = (ICompressCoder *)new NCompress::NDeflate::NEncoder::CCOMCoder();
+ }
+ else if (*clsid == CLSID_CCompressDeflate64Decoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder = (ICompressCoder *)new NCompress::NDeflate::NDecoder::CCOMCoder64();
+ }
+ else if (*clsid == CLSID_CCompressDeflate64Encoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder = (ICompressCoder *)new NCompress::NDeflate::NEncoder::CCOMCoder64();
+ }
+ else
+ return CLASS_E_CLASSNOTAVAILABLE;
+ *outObject = coder.Detach();
+ COM_TRY_END
+ return S_OK;
+}
+
+struct CDeflateMethodItem
+{
+ char ID[3];
+ const wchar_t *UserName;
+ const GUID *Decoder;
+ const GUID *Encoder;
+};
+
+#define METHOD_ITEM(Name, id, UserName) \
+ { { 0x04, 0x01, id }, UserName, \
+ &CLSID_CCompress ## Name ## Decoder, \
+ &CLSID_CCompress ## Name ## Encoder }
+
+#define METHOD_ITEM_DE(Name, id1, id2, UserName) \
+ { { 0x04, id1, id2 }, UserName, \
+ &CLSID_CCompress ## Name ## Decoder, NULL }
+
+
+static CDeflateMethodItem g_Methods[] =
+{
+ METHOD_ITEM(Deflate, 0x08, L"Deflate"),
+ METHOD_ITEM(Deflate64, 0x09, L"Deflate64"),
+ METHOD_ITEM_DE(DeflateNsis, 0x09, 0x01, L"DeflateNSIS")
+};
+
+STDAPI GetNumberOfMethods(UINT32 *numMethods)
+{
+ *numMethods = sizeof(g_Methods) / sizeof(g_Methods[0]);
+ return S_OK;
+}
+
+STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
+{
+ if (index > sizeof(g_Methods) / sizeof(g_Methods[0]))
+ return E_INVALIDARG;
+ VariantClear((tagVARIANT *)value);
+ const CDeflateMethodItem &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;
+ case NMethodPropID::kEncoder:
+ if (method.Encoder)
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)method.Encoder, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ }
+ return S_OK;
+ }
+ return S_OK;
+}
diff --git a/CPP/7zip/Compress/Deflate/StdAfx.cpp b/CPP/7zip/Compress/Deflate/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Compress/Deflate/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Compress/Deflate/StdAfx.h b/CPP/7zip/Compress/Deflate/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Compress/Deflate/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Compress/Deflate/makefile b/CPP/7zip/Compress/Deflate/makefile
new file mode 100755
index 00000000..c533d7cc
--- /dev/null
+++ b/CPP/7zip/Compress/Deflate/makefile
@@ -0,0 +1,63 @@
+PROG = Deflate.dll
+DEF_FILE = ../Codec.def
+CFLAGS = $(CFLAGS) -I ../../../ -D_ST_MODE
+LIBS = $(LIBS) oleaut32.lib
+
+DEFLATE_OBJS = \
+ $O\DllExports.obj \
+
+DEFLATE_OPT_OBJS = \
+ $O\DeflateDecoder.obj \
+ $O\DeflateEncoder.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\CRC.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\InBuffer.obj \
+ $O\OutBuffer.obj \
+ $O\LSBFDecoder.obj \
+ $O\LSBFEncoder.obj \
+
+LZ_OBJS = \
+ $O\LZOutWindow.obj \
+
+C_OBJS = \
+ $O\7zCrc.obj \
+ $O\Sort.obj \
+
+C_LZ_OBJS = \
+ $O\MatchFinder.obj \
+
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(DEFLATE_OBJS) \
+ $(DEFLATE_OPT_OBJS) \
+ $(COMMON_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(LZ_OBJS) \
+ $(C_OBJS) \
+ $(C_LZ_OBJS) \
+ $O\HuffmanEncode.obj \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(DEFLATE_OBJS): $(*B).cpp
+ $(COMPL)
+$(DEFLATE_OPT_OBJS): $(*B).cpp
+ $(COMPL_O2)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$(LZ_OBJS): ../LZ/$(*B).cpp
+ $(COMPL)
+$(C_OBJS): ../../../../C/$(*B).c
+ $(COMPL_O2)
+$(C_LZ_OBJS): ../../../../C/Compress/Lz/$(*B).c
+ $(COMPL_O2)
+$O\HuffmanEncode.obj: ../../../../C/Compress/Huffman/$(*B).c
+ $(COMPL_O2)
diff --git a/CPP/7zip/Compress/Deflate/resource.rc b/CPP/7zip/Compress/Deflate/resource.rc
new file mode 100755
index 00000000..910bc281
--- /dev/null
+++ b/CPP/7zip/Compress/Deflate/resource.rc
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("Deflate Codec", "Deflate")
diff --git a/CPP/7zip/Compress/Huffman/HuffmanDecoder.h b/CPP/7zip/Compress/Huffman/HuffmanDecoder.h
new file mode 100755
index 00000000..57115197
--- /dev/null
+++ b/CPP/7zip/Compress/Huffman/HuffmanDecoder.h
@@ -0,0 +1,88 @@
+// Compress/HuffmanDecoder.h
+
+#ifndef __COMPRESS_HUFFMANDECODER_H
+#define __COMPRESS_HUFFMANDECODER_H
+
+#include "../../../Common/Types.h"
+
+namespace NCompress {
+namespace NHuffman {
+
+const int kNumTableBits = 9;
+
+template <int kNumBitsMax, UInt32 m_NumSymbols>
+class CDecoder
+{
+ 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:
+
+ 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)
+ {
+ int numBits;
+ UInt32 value = bitStream->GetValue(kNumBitsMax);
+ if (value < m_Limits[kNumTableBits])
+ numBits = m_Lengths[value >> (kNumBitsMax - kNumTableBits)];
+ else
+ for (numBits = kNumTableBits + 1; value >= m_Limits[numBits]; numBits++);
+ bitStream->MovePos(numBits);
+ UInt32 index = m_Positions[numBits] +
+ ((value - m_Limits[numBits - 1]) >> (kNumBitsMax - numBits));
+ if (index >= m_NumSymbols)
+ // throw CDecoderException(); // test it
+ return 0xFFFFFFFF;
+ return m_Symbols[index];
+ }
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Compress/Huffman/StdAfx.h b/CPP/7zip/Compress/Huffman/StdAfx.h
new file mode 100755
index 00000000..b637fd40
--- /dev/null
+++ b/CPP/7zip/Compress/Huffman/StdAfx.h
@@ -0,0 +1,6 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#endif
diff --git a/CPP/7zip/Compress/Implode/DllExports.cpp b/CPP/7zip/Compress/Implode/DllExports.cpp
new file mode 100755
index 00000000..ff8cbe64
--- /dev/null
+++ b/CPP/7zip/Compress/Implode/DllExports.cpp
@@ -0,0 +1,65 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#include "ImplodeDecoder.h"
+
+// {23170F69-40C1-278B-0401-060000000000}
+DEFINE_GUID(CLSID_CCompressImplodeDecoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x06, 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_CCompressImplodeDecoder)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ if (*iid != IID_ICompressCoder)
+ return E_NOINTERFACE;
+ CMyComPtr<ICompressCoder> coder = (ICompressCoder *)new
+ NCompress::NImplode::NDecoder::CCoder;
+ *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, 0x01, 0x06 };
+ if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NMethodPropID::kName:
+ if ((value->bstrVal = ::SysAllocString(L"Implode")) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ case NMethodPropID::kDecoder:
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CCompressImplodeDecoder, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ return S_OK;
+}
diff --git a/CPP/7zip/Compress/Implode/ImplodeDecoder.cpp b/CPP/7zip/Compress/Implode/ImplodeDecoder.cpp
new file mode 100755
index 00000000..19634c5c
--- /dev/null
+++ b/CPP/7zip/Compress/Implode/ImplodeDecoder.cpp
@@ -0,0 +1,222 @@
+// Implode/Decoder.cpp
+
+#include "StdAfx.h"
+
+#include "ImplodeDecoder.h"
+#include "Common/Defs.h"
+
+namespace NCompress {
+namespace NImplode {
+namespace NDecoder {
+
+class CException
+{
+public:
+ enum ECauseType
+ {
+ kData
+ } m_Cause;
+ CException(ECauseType cause): m_Cause(cause) {}
+};
+
+static const int kNumDistanceLowDirectBitsForBigDict = 7;
+static const int kNumDistanceLowDirectBitsForSmallDict = 6;
+
+static const int kNumBitsInByte = 8;
+
+static const int kLevelStructuresNumberFieldSize = kNumBitsInByte;
+static const int kLevelStructuresNumberAdditionalValue = 1;
+
+static const int kNumLevelStructureLevelBits = 4;
+static const int kLevelStructureLevelAdditionalValue = 1;
+
+static const int kNumLevelStructureRepNumberBits = 4;
+static const int kLevelStructureRepNumberAdditionalValue = 1;
+
+
+static const int kLiteralTableSize = (1 << kNumBitsInByte);
+static const int kDistanceTableSize = 64;
+static const int kLengthTableSize = 64;
+
+static const UInt32 kHistorySize =
+ (1 << MyMax(kNumDistanceLowDirectBitsForBigDict,
+ kNumDistanceLowDirectBitsForSmallDict)) *
+ kDistanceTableSize; // = 8 KB;
+
+static const int kNumAdditionalLengthBits = 8;
+
+static const UInt32 kMatchMinLenWhenLiteralsOn = 3;
+static const UInt32 kMatchMinLenWhenLiteralsOff = 2;
+
+static const UInt32 kMatchMinLenMax = MyMax(kMatchMinLenWhenLiteralsOn,
+ kMatchMinLenWhenLiteralsOff); // 3
+
+static const UInt32 kMatchMaxLenMax = kMatchMinLenMax +
+ (kLengthTableSize - 1) + (1 << kNumAdditionalLengthBits) - 1; // or 2
+
+enum
+{
+ kMatchId = 0,
+ kLiteralId = 1
+};
+
+
+CCoder::CCoder():
+ m_LiteralDecoder(kLiteralTableSize),
+ m_LengthDecoder(kLengthTableSize),
+ m_DistanceDecoder(kDistanceTableSize)
+{
+}
+
+void CCoder::ReleaseStreams()
+{
+ m_OutWindowStream.ReleaseStream();
+ m_InBitStream.ReleaseStream();
+}
+
+bool CCoder::ReadLevelItems(NImplode::NHuffman::CDecoder &decoder,
+ Byte *levels, int numLevelItems)
+{
+ int numCodedStructures = m_InBitStream.ReadBits(kNumBitsInByte) +
+ kLevelStructuresNumberAdditionalValue;
+ int currentIndex = 0;
+ for(int i = 0; i < numCodedStructures; i++)
+ {
+ int level = m_InBitStream.ReadBits(kNumLevelStructureLevelBits) +
+ kLevelStructureLevelAdditionalValue;
+ int rep = m_InBitStream.ReadBits(kNumLevelStructureRepNumberBits) +
+ kLevelStructureRepNumberAdditionalValue;
+ if (currentIndex + rep > numLevelItems)
+ throw CException(CException::kData);
+ for(int j = 0; j < rep; j++)
+ levels[currentIndex++] = (Byte)level;
+ }
+ if (currentIndex != numLevelItems)
+ return false;
+ return decoder.SetCodeLengths(levels);
+}
+
+
+bool CCoder::ReadTables(void)
+{
+ if (m_LiteralsOn)
+ {
+ Byte literalLevels[kLiteralTableSize];
+ if (!ReadLevelItems(m_LiteralDecoder, literalLevels, kLiteralTableSize))
+ return false;
+ }
+
+ Byte lengthLevels[kLengthTableSize];
+ if (!ReadLevelItems(m_LengthDecoder, lengthLevels, kLengthTableSize))
+ return false;
+
+ Byte distanceLevels[kDistanceTableSize];
+ return ReadLevelItems(m_DistanceDecoder, distanceLevels, kDistanceTableSize);
+}
+
+class CCoderReleaser
+{
+ CCoder *m_Coder;
+public:
+ CCoderReleaser(CCoder *coder): m_Coder(coder) {}
+ ~CCoderReleaser() { m_Coder->ReleaseStreams(); }
+};
+
+STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ if (!m_InBitStream.Create(1 << 20))
+ return E_OUTOFMEMORY;
+ if (!m_OutWindowStream.Create(kHistorySize))
+ return E_OUTOFMEMORY;
+ if (outSize == NULL)
+ return E_INVALIDARG;
+ UInt64 pos = 0, unPackSize = *outSize;
+
+ m_OutWindowStream.SetStream(outStream);
+ m_OutWindowStream.Init(false);
+ m_InBitStream.SetStream(inStream);
+ m_InBitStream.Init();
+ CCoderReleaser coderReleaser(this);
+
+ if (!ReadTables())
+ return S_FALSE;
+
+ while(pos < unPackSize)
+ {
+ if (progress != NULL && pos % (1 << 16) == 0)
+ {
+ UInt64 packSize = m_InBitStream.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&packSize, &pos));
+ }
+ if(m_InBitStream.ReadBits(1) == kMatchId) // match
+ {
+ UInt32 lowDistBits = m_InBitStream.ReadBits(m_NumDistanceLowDirectBits);
+ UInt32 distance = m_DistanceDecoder.DecodeSymbol(&m_InBitStream);
+ if (distance >= kDistanceTableSize)
+ return S_FALSE;
+ distance = (distance << m_NumDistanceLowDirectBits) + lowDistBits;
+ UInt32 lengthSymbol = m_LengthDecoder.DecodeSymbol(&m_InBitStream);
+ if (lengthSymbol >= kLengthTableSize)
+ return S_FALSE;
+ UInt32 length = lengthSymbol + m_MinMatchLength;
+ if (lengthSymbol == kLengthTableSize - 1) // special symbol = 63
+ length += m_InBitStream.ReadBits(kNumAdditionalLengthBits);
+ while(distance >= pos && length > 0)
+ {
+ m_OutWindowStream.PutByte(0);
+ pos++;
+ length--;
+ }
+ if (length > 0)
+ m_OutWindowStream.CopyBlock(distance, length);
+ pos += length;
+ }
+ else
+ {
+ Byte b;
+ if (m_LiteralsOn)
+ {
+ UInt32 temp = m_LiteralDecoder.DecodeSymbol(&m_InBitStream);
+ if (temp >= kLiteralTableSize)
+ return S_FALSE;
+ b = (Byte)temp;
+ }
+ else
+ b = (Byte)m_InBitStream.ReadBits(kNumBitsInByte);
+ m_OutWindowStream.PutByte(b);
+ pos++;
+ }
+ }
+ if (pos > unPackSize)
+ throw CException(CException::kData);
+ return m_OutWindowStream.Flush();
+}
+
+STDMETHODIMP CCoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
+ catch(const CLZOutWindowException &e) { return e.ErrorCode; }
+ catch(...) { return S_FALSE; }
+}
+
+STDMETHODIMP CCoder::SetDecoderProperties2(const Byte *data, UInt32 size)
+{
+ if (size < 1)
+ return E_INVALIDARG;
+ Byte flag = data[0];
+ m_BigDictionaryOn = ((flag & 2) != 0);
+ m_NumDistanceLowDirectBits = m_BigDictionaryOn ?
+ kNumDistanceLowDirectBitsForBigDict:
+ kNumDistanceLowDirectBitsForSmallDict;
+ m_LiteralsOn = ((flag & 4) != 0);
+ m_MinMatchLength = m_LiteralsOn ?
+ kMatchMinLenWhenLiteralsOn :
+ kMatchMinLenWhenLiteralsOff;
+ return S_OK;
+}
+
+}}}
diff --git a/CPP/7zip/Compress/Implode/ImplodeDecoder.h b/CPP/7zip/Compress/Implode/ImplodeDecoder.h
new file mode 100755
index 00000000..627edba4
--- /dev/null
+++ b/CPP/7zip/Compress/Implode/ImplodeDecoder.h
@@ -0,0 +1,60 @@
+// ImplodeDecoder.h
+
+#ifndef __IMPLODE_DECODER_H
+#define __IMPLODE_DECODER_H
+
+#include "../../../Common/MyCom.h"
+
+#include "../../ICoder.h"
+#include "../LZ/LZOutWindow.h"
+
+#include "ImplodeHuffmanDecoder.h"
+
+namespace NCompress {
+namespace NImplode {
+namespace NDecoder {
+
+class CCoder :
+ public ICompressCoder,
+ public ICompressSetDecoderProperties2,
+ public CMyUnknownImp
+{
+ CLZOutWindow m_OutWindowStream;
+ NStream::NLSBF::CDecoder<CInBuffer> m_InBitStream;
+
+ NImplode::NHuffman::CDecoder m_LiteralDecoder;
+ NImplode::NHuffman::CDecoder m_LengthDecoder;
+ NImplode::NHuffman::CDecoder m_DistanceDecoder;
+
+ bool m_BigDictionaryOn;
+ bool m_LiteralsOn;
+
+ int m_NumDistanceLowDirectBits;
+ UInt32 m_MinMatchLength;
+
+ bool ReadLevelItems(NImplode::NHuffman::CDecoder &table, Byte *levels, int numLevelItems);
+ bool ReadTables();
+ void DeCodeLevelTable(Byte *newLevels, int numLevels);
+public:
+ CCoder();
+
+ MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)
+
+ void ReleaseStreams();
+ HRESULT (Flush)() { return m_OutWindowStream.Flush(); }
+
+ 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);
+
+ // ICompressSetDecoderProperties
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+};
+
+}}}
+
+#endif
diff --git a/CPP/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp b/CPP/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp
new file mode 100755
index 00000000..ad2061c3
--- /dev/null
+++ b/CPP/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp
@@ -0,0 +1,89 @@
+// ImplodeHuffmanDecoder.cpp
+
+#include "StdAfx.h"
+
+#include "ImplodeHuffmanDecoder.h"
+
+namespace NCompress {
+namespace NImplode {
+namespace NHuffman {
+
+CDecoder::CDecoder(UInt32 numSymbols):
+ m_NumSymbols(numSymbols)
+{
+ m_Symbols = new UInt32[m_NumSymbols];
+}
+
+CDecoder::~CDecoder()
+{
+ delete []m_Symbols;
+}
+
+bool CDecoder::SetCodeLengths(const Byte *codeLengths)
+{
+ // int lenCounts[kNumBitsInLongestCode + 1], tmpPositions[kNumBitsInLongestCode + 1];
+ int lenCounts[kNumBitsInLongestCode + 2], tmpPositions[kNumBitsInLongestCode + 1];
+ int i;
+ for(i = 0; i <= kNumBitsInLongestCode; i++)
+ lenCounts[i] = 0;
+ UInt32 symbolIndex;
+ for (symbolIndex = 0; symbolIndex < m_NumSymbols; symbolIndex++)
+ lenCounts[codeLengths[symbolIndex]]++;
+ // lenCounts[0] = 0;
+
+ // tmpPositions[0] = m_Positions[0] = m_Limitits[0] = 0;
+ m_Limitits[kNumBitsInLongestCode + 1] = 0;
+ m_Positions[kNumBitsInLongestCode + 1] = 0;
+ lenCounts[kNumBitsInLongestCode + 1] = 0;
+
+
+ UInt32 startPos = 0;
+ static const UInt32 kMaxValue = (1 << kNumBitsInLongestCode);
+
+ for (i = kNumBitsInLongestCode; i > 0; i--)
+ {
+ startPos += lenCounts[i] << (kNumBitsInLongestCode - i);
+ if (startPos > kMaxValue)
+ return false;
+ m_Limitits[i] = startPos;
+ m_Positions[i] = m_Positions[i + 1] + lenCounts[i + 1];
+ tmpPositions[i] = m_Positions[i] + lenCounts[i];
+
+ }
+
+ // if _ZIP_MODE do not throw exception for trees containing only one node
+ // #ifndef _ZIP_MODE
+ if (startPos != kMaxValue)
+ return false;
+ // #endif
+
+ for (symbolIndex = 0; symbolIndex < m_NumSymbols; symbolIndex++)
+ if (codeLengths[symbolIndex] != 0)
+ m_Symbols[--tmpPositions[codeLengths[symbolIndex]]] = symbolIndex;
+ return true;
+}
+
+UInt32 CDecoder::DecodeSymbol(CInBit *inStream)
+{
+ UInt32 numBits = 0;
+ UInt32 value = inStream->GetValue(kNumBitsInLongestCode);
+ int i;
+ for(i = kNumBitsInLongestCode; i > 0; i--)
+ {
+ if (value < m_Limitits[i])
+ {
+ numBits = i;
+ break;
+ }
+ }
+ if (i == 0)
+ return 0xFFFFFFFF;
+ inStream->MovePos(numBits);
+ UInt32 index = m_Positions[numBits] +
+ ((value - m_Limitits[numBits + 1]) >> (kNumBitsInLongestCode - numBits));
+ if (index >= m_NumSymbols)
+ return 0xFFFFFFFF;
+ return m_Symbols[index];
+}
+
+}}}
diff --git a/CPP/7zip/Compress/Implode/ImplodeHuffmanDecoder.h b/CPP/7zip/Compress/Implode/ImplodeHuffmanDecoder.h
new file mode 100755
index 00000000..9f7aeca1
--- /dev/null
+++ b/CPP/7zip/Compress/Implode/ImplodeHuffmanDecoder.h
@@ -0,0 +1,33 @@
+// ImplodeHuffmanDecoder.h
+
+#ifndef __IMPLODE_HUFFMAN_DECODER_H
+#define __IMPLODE_HUFFMAN_DECODER_H
+
+#include "../../Common/LSBFDecoder.h"
+#include "../../Common/InBuffer.h"
+
+namespace NCompress {
+namespace NImplode {
+namespace NHuffman {
+
+const int kNumBitsInLongestCode = 16;
+
+typedef NStream::NLSBF::CDecoder<CInBuffer> CInBit;
+
+class CDecoder
+{
+ UInt32 m_Limitits[kNumBitsInLongestCode + 2]; // m_Limitits[i] = value limit for symbols with length = i
+ UInt32 m_Positions[kNumBitsInLongestCode + 2]; // m_Positions[i] = index in m_Symbols[] of first symbol with length = i
+ UInt32 m_NumSymbols; // number of symbols in m_Symbols
+ UInt32 *m_Symbols; // symbols: at first with len=1 then 2, ... 15.
+public:
+ CDecoder(UInt32 numSymbols);
+ ~CDecoder();
+
+ bool SetCodeLengths(const Byte *codeLengths);
+ UInt32 DecodeSymbol(CInBit *inStream);
+};
+
+}}}
+
+#endif
diff --git a/CPP/7zip/Compress/Implode/StdAfx.cpp b/CPP/7zip/Compress/Implode/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Compress/Implode/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Compress/Implode/StdAfx.h b/CPP/7zip/Compress/Implode/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Compress/Implode/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Compress/LZ/LZOutWindow.cpp b/CPP/7zip/Compress/LZ/LZOutWindow.cpp
new file mode 100755
index 00000000..e2d6aba1
--- /dev/null
+++ b/CPP/7zip/Compress/LZ/LZOutWindow.cpp
@@ -0,0 +1,17 @@
+// LZOutWindow.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/Alloc.h"
+#include "LZOutWindow.h"
+
+void CLZOutWindow::Init(bool solid)
+{
+ if(!solid)
+ COutBuffer::Init();
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = S_OK;
+ #endif
+}
+
+
diff --git a/CPP/7zip/Compress/LZ/LZOutWindow.h b/CPP/7zip/Compress/LZ/LZOutWindow.h
new file mode 100755
index 00000000..3c50c6e7
--- /dev/null
+++ b/CPP/7zip/Compress/LZ/LZOutWindow.h
@@ -0,0 +1,56 @@
+// LZOutWindow.h
+
+#ifndef __LZ_OUT_WINDOW_H
+#define __LZ_OUT_WINDOW_H
+
+#include "../../IStream.h"
+#include "../../Common/OutBuffer.h"
+
+#ifndef _NO_EXCEPTIONS
+typedef COutBufferException CLZOutWindowException;
+#endif
+
+class CLZOutWindow: public COutBuffer
+{
+public:
+ void Init(bool solid = false);
+
+ // distance >= 0, len > 0,
+ bool CopyBlock(UInt32 distance, UInt32 len)
+ {
+ UInt32 pos = _pos - distance - 1;
+ if (distance >= _pos)
+ {
+ if (!_overDict || distance >= _bufferSize)
+ return false;
+ pos += _bufferSize;
+ }
+ do
+ {
+ if (pos == _bufferSize)
+ pos = 0;
+ _buffer[_pos++] = _buffer[pos++];
+ if (_pos == _limitPos)
+ FlushWithCheck();
+ }
+ while(--len != 0);
+ return true;
+ }
+
+ void PutByte(Byte b)
+ {
+ _buffer[_pos++] = b;
+ if (_pos == _limitPos)
+ FlushWithCheck();
+ }
+
+ Byte GetByte(UInt32 distance) const
+ {
+ UInt32 pos = _pos - distance - 1;
+ if (pos >= _bufferSize)
+ pos += _bufferSize;
+ return _buffer[pos];
+ }
+};
+
+#endif
diff --git a/CPP/7zip/Compress/LZ/StdAfx.h b/CPP/7zip/Compress/LZ/StdAfx.h
new file mode 100755
index 00000000..3ff6d8a2
--- /dev/null
+++ b/CPP/7zip/Compress/LZ/StdAfx.h
@@ -0,0 +1,6 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#endif
diff --git a/CPP/7zip/Compress/LZMA/DllExports.cpp b/CPP/7zip/Compress/LZMA/DllExports.cpp
new file mode 100755
index 00000000..1fc65b84
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA/DllExports.cpp
@@ -0,0 +1,109 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/MyInitGuid.h"
+#include "../../../Common/ComTry.h"
+#ifdef _WIN32
+#include "../../../Common/Alloc.h"
+#endif
+
+#include "LZMAEncoder.h"
+#include "LZMADecoder.h"
+
+#ifdef CRC_GENERATE_TABLE
+extern "C"
+{
+ #include "../../../../C/7zCrc.h"
+}
+#endif
+
+// {23170F69-40C1-278B-0301-010000000000}
+DEFINE_GUID(CLSID_CLZMADecoder,
+0x23170F69, 0x40C1, 0x278B, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+// {23170F69-40C1-278B-0301-010000000100}
+DEFINE_GUID(CLSID_CLZMAEncoder,
+0x23170F69, 0x40C1, 0x278B, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00);
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ // NCompress::NRangeCoder::g_PriceTables.Init();
+ #ifdef CRC_GENERATE_TABLE
+ CrcGenerateTable();
+ #endif
+ #ifdef _WIN32
+ SetLargePageSize();
+ #endif
+ }
+ return TRUE;
+}
+
+STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
+{
+ // NCompress::NRangeCoder::g_PriceTables.Init();
+ // CCRC::InitTable();
+ COM_TRY_BEGIN
+ *outObject = 0;
+ int correctInterface = (*iid == IID_ICompressCoder);
+ CMyComPtr<ICompressCoder> coder;
+ if (*clsid == CLSID_CLZMADecoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder = (ICompressCoder *)new NCompress::NLZMA::CDecoder();
+ }
+ else if (*clsid == CLSID_CLZMAEncoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder = (ICompressCoder *)new NCompress::NLZMA::CEncoder();
+ }
+ else
+ return CLASS_E_CLASSNOTAVAILABLE;
+ *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[] = { 0x03, 0x01, 0x01 };
+ if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NMethodPropID::kName:
+ if ((value->bstrVal = ::SysAllocString(L"LZMA")) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ case NMethodPropID::kDecoder:
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CLZMADecoder, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ case NMethodPropID::kEncoder:
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CLZMAEncoder, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ return S_OK;
+}
+
diff --git a/CPP/7zip/Compress/LZMA/LZMA.dsp b/CPP/7zip/Compress/LZMA/LZMA.dsp
new file mode 100755
index 00000000..3d51f1ff
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA/LZMA.dsp
@@ -0,0 +1,478 @@
+# Microsoft Developer Studio Project File - Name="LZMA" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=LZMA - 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 "LZMA.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 "LZMA.mak" CFG="LZMA - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "LZMA - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "LZMA - 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)" == "LZMA - 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 "LZMA_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMA_EXPORTS" /D "COMPRESS_MF_MT" /D "_ST_MODE" /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\LZMA.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none /debug
+
+!ELSEIF "$(CFG)" == "LZMA - 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 "LZMA_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 "LZMA_EXPORTS" /D "COMPRESS_MF_MT" /D "_ST_MODE" /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\LZMA.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "LZMA - Win32 Release"
+# Name "LZMA - 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 "7-zip 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\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 "RangeCoder"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoderBit.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoderBit.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoderBitTree.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoderOpt.h
+# End Source File
+# End Group
+# Begin Group "Interface"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\ICoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\MatchFinders\IMatchFinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IStream.h
+# End Source File
+# End Group
+# Begin Group "LZ"
+
+# PROP Default_Filter ""
+# Begin Group "BT"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\LZ\BinTree\BinTree.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\BinTree\BinTree2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\BinTree\BinTree3.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\BinTree\BinTree4.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\BinTree\BinTreeBase.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\BinTree\BinTreeD.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\BinTree\BinTreeD4.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\BinTree\BinTreeDMain.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\BinTree\BinTreeMain.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\BinTree\BinTreeR.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\BinTree\BinTreeR4.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\BinTree\BinTreeRMain.h
+# End Source File
+# End Group
+# Begin Group "HC"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\LZ\HashChain\HC4.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\HashChain\HCMain.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\LZ\IMatchFinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\LZInWindow.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\LZOutWindow.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\LZOutWindow.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\AlignedBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\AlignedBuffer.h
+# End Source File
+# 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\ComTry.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Defs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Exception.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyCom.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyUnknown.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyWindows.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Handle.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Thread.h
+# End Source File
+# End Group
+# Begin Group "C"
+
+# PROP Default_Filter ""
+# Begin Group "C_Lz"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\LzHash.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.c
+
+!IF "$(CFG)" == "LZMA - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "LZMA - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinderMt.c
+
+!IF "$(CFG)" == "LZMA - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "LZMA - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinderMt.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrc.c
+
+!IF "$(CFG)" == "LZMA - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "LZMA - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\IStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Threads.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Threads.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Types.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\LZMA.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LZMADecoder.cpp
+
+!IF "$(CFG)" == "LZMA - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "LZMA - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\LZMADecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LZMAEncoder.cpp
+
+!IF "$(CFG)" == "LZMA - Win32 Release"
+
+# ADD CPP /O2 /FAs
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "LZMA - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\LZMAEncoder.h
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/Compress/LZMA/LZMA.dsw b/CPP/7zip/Compress/LZMA/LZMA.dsw
new file mode 100755
index 00000000..f750e453
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA/LZMA.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "LZMA"=".\LZMA.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Compress/LZMA/LZMA.h b/CPP/7zip/Compress/LZMA/LZMA.h
new file mode 100755
index 00000000..7bc4c438
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA/LZMA.h
@@ -0,0 +1,82 @@
+// LZMA.h
+
+#ifndef __LZMA_H
+#define __LZMA_H
+
+namespace NCompress {
+namespace NLZMA {
+
+const UInt32 kNumRepDistances = 4;
+
+const int kNumStates = 12;
+
+const Byte kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
+const Byte kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
+const Byte kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
+const Byte kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
+
+class CState
+{
+public:
+ Byte Index;
+ void Init() { Index = 0; }
+ void UpdateChar() { Index = kLiteralNextStates[Index]; }
+ void UpdateMatch() { Index = kMatchNextStates[Index]; }
+ void UpdateRep() { Index = kRepNextStates[Index]; }
+ void UpdateShortRep() { Index = kShortRepNextStates[Index]; }
+ bool IsCharState() const { return Index < 7; }
+};
+
+const int kNumPosSlotBits = 6;
+const int kDicLogSizeMin = 0;
+const int kDicLogSizeMax = 32;
+const int kDistTableSizeMax = kDicLogSizeMax * 2;
+
+const UInt32 kNumLenToPosStates = 4;
+
+inline UInt32 GetLenToPosState(UInt32 len)
+{
+ len -= 2;
+ if (len < kNumLenToPosStates)
+ return len;
+ return kNumLenToPosStates - 1;
+}
+
+namespace NLength {
+
+const int kNumPosStatesBitsMax = 4;
+const UInt32 kNumPosStatesMax = (1 << kNumPosStatesBitsMax);
+
+const int kNumPosStatesBitsEncodingMax = 4;
+const UInt32 kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);
+
+const int kNumLowBits = 3;
+const int kNumMidBits = 3;
+const int kNumHighBits = 8;
+const UInt32 kNumLowSymbols = 1 << kNumLowBits;
+const UInt32 kNumMidSymbols = 1 << kNumMidBits;
+const UInt32 kNumSymbolsTotal = kNumLowSymbols + kNumMidSymbols + (1 << kNumHighBits);
+
+}
+
+const UInt32 kMatchMinLen = 2;
+const UInt32 kMatchMaxLen = kMatchMinLen + NLength::kNumSymbolsTotal - 1;
+
+const int kNumAlignBits = 4;
+const UInt32 kAlignTableSize = 1 << kNumAlignBits;
+const UInt32 kAlignMask = (kAlignTableSize - 1);
+
+const UInt32 kStartPosModelIndex = 4;
+const UInt32 kEndPosModelIndex = 14;
+const UInt32 kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
+
+const UInt32 kNumFullDistances = 1 << (kEndPosModelIndex / 2);
+
+const int kNumLitPosStatesBitsEncodingMax = 4;
+const int kNumLitContextBitsMax = 8;
+
+const int kNumMoveBits = 5;
+
+}}
+
+#endif
diff --git a/CPP/7zip/Compress/LZMA/LZMADecoder.cpp b/CPP/7zip/Compress/LZMA/LZMADecoder.cpp
new file mode 100755
index 00000000..75de2245
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA/LZMADecoder.cpp
@@ -0,0 +1,338 @@
+// LZMADecoder.cpp
+
+#include "StdAfx.h"
+
+#include "LZMADecoder.h"
+#include "../../../Common/Defs.h"
+
+namespace NCompress {
+namespace NLZMA {
+
+const int kLenIdFinished = -1;
+const int kLenIdNeedInit = -2;
+
+void CDecoder::Init()
+{
+ {
+ for(int i = 0; i < kNumStates; i++)
+ {
+ for (UInt32 j = 0; j <= _posStateMask; j++)
+ {
+ _isMatch[i][j].Init();
+ _isRep0Long[i][j].Init();
+ }
+ _isRep[i].Init();
+ _isRepG0[i].Init();
+ _isRepG1[i].Init();
+ _isRepG2[i].Init();
+ }
+ }
+ {
+ for (UInt32 i = 0; i < kNumLenToPosStates; i++)
+ _posSlotDecoder[i].Init();
+ }
+ {
+ for(UInt32 i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
+ _posDecoders[i].Init();
+ }
+ _posAlignDecoder.Init();
+ _lenDecoder.Init(_posStateMask + 1);
+ _repMatchLenDecoder.Init(_posStateMask + 1);
+ _literalDecoder.Init();
+
+ _state.Init();
+ _reps[0] = _reps[1] = _reps[2] = _reps[3] = 0;
+}
+
+HRESULT CDecoder::CodeSpec(UInt32 curSize)
+{
+ if (_outSizeDefined)
+ {
+ const UInt64 rem = _outSize - _outWindowStream.GetProcessedSize();
+ if (curSize > rem)
+ curSize = (UInt32)rem;
+ }
+
+ if (_remainLen == kLenIdFinished)
+ return S_OK;
+ if (_remainLen == kLenIdNeedInit)
+ {
+ _rangeDecoder.Init();
+ Init();
+ _remainLen = 0;
+ }
+ if (curSize == 0)
+ return S_OK;
+
+ UInt32 rep0 = _reps[0];
+ UInt32 rep1 = _reps[1];
+ UInt32 rep2 = _reps[2];
+ UInt32 rep3 = _reps[3];
+ CState state = _state;
+ Byte previousByte;
+
+ while(_remainLen > 0 && curSize > 0)
+ {
+ previousByte = _outWindowStream.GetByte(rep0);
+ _outWindowStream.PutByte(previousByte);
+ _remainLen--;
+ curSize--;
+ }
+ UInt64 nowPos64 = _outWindowStream.GetProcessedSize();
+ if (nowPos64 == 0)
+ previousByte = 0;
+ else
+ previousByte = _outWindowStream.GetByte(0);
+
+ while(curSize > 0)
+ {
+ {
+ #ifdef _NO_EXCEPTIONS
+ if (_rangeDecoder.Stream.ErrorCode != S_OK)
+ return _rangeDecoder.Stream.ErrorCode;
+ #endif
+ if (_rangeDecoder.Stream.WasFinished())
+ return S_FALSE;
+ UInt32 posState = UInt32(nowPos64) & _posStateMask;
+ if (_isMatch[state.Index][posState].Decode(&_rangeDecoder) == 0)
+ {
+ if(!state.IsCharState())
+ previousByte = _literalDecoder.DecodeWithMatchByte(&_rangeDecoder,
+ (UInt32)nowPos64, previousByte, _outWindowStream.GetByte(rep0));
+ else
+ previousByte = _literalDecoder.DecodeNormal(&_rangeDecoder,
+ (UInt32)nowPos64, previousByte);
+ _outWindowStream.PutByte(previousByte);
+ state.UpdateChar();
+ curSize--;
+ nowPos64++;
+ }
+ else
+ {
+ UInt32 len;
+ if(_isRep[state.Index].Decode(&_rangeDecoder) == 1)
+ {
+ len = 0;
+ if(_isRepG0[state.Index].Decode(&_rangeDecoder) == 0)
+ {
+ if(_isRep0Long[state.Index][posState].Decode(&_rangeDecoder) == 0)
+ {
+ state.UpdateShortRep();
+ len = 1;
+ }
+ }
+ else
+ {
+ UInt32 distance;
+ if(_isRepG1[state.Index].Decode(&_rangeDecoder) == 0)
+ distance = rep1;
+ else
+ {
+ if (_isRepG2[state.Index].Decode(&_rangeDecoder) == 0)
+ distance = rep2;
+ else
+ {
+ distance = rep3;
+ rep3 = rep2;
+ }
+ rep2 = rep1;
+ }
+ rep1 = rep0;
+ rep0 = distance;
+ }
+ if (len == 0)
+ {
+ len = _repMatchLenDecoder.Decode(&_rangeDecoder, posState) + kMatchMinLen;
+ state.UpdateRep();
+ }
+ }
+ else
+ {
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ len = kMatchMinLen + _lenDecoder.Decode(&_rangeDecoder, posState);
+ state.UpdateMatch();
+ UInt32 posSlot = _posSlotDecoder[GetLenToPosState(len)].Decode(&_rangeDecoder);
+ if (posSlot >= kStartPosModelIndex)
+ {
+ UInt32 numDirectBits = (posSlot >> 1) - 1;
+ rep0 = ((2 | (posSlot & 1)) << numDirectBits);
+
+ if (posSlot < kEndPosModelIndex)
+ rep0 += NRangeCoder::ReverseBitTreeDecode(_posDecoders +
+ rep0 - posSlot - 1, &_rangeDecoder, numDirectBits);
+ else
+ {
+ rep0 += (_rangeDecoder.DecodeDirectBits(
+ numDirectBits - kNumAlignBits) << kNumAlignBits);
+ rep0 += _posAlignDecoder.ReverseDecode(&_rangeDecoder);
+ if (rep0 == 0xFFFFFFFF)
+ {
+ _remainLen = kLenIdFinished;
+ return S_OK;
+ }
+ }
+ }
+ else
+ rep0 = posSlot;
+ }
+ UInt32 locLen = len;
+ if (len > curSize)
+ locLen = (UInt32)curSize;
+ if (!_outWindowStream.CopyBlock(rep0, locLen))
+ return S_FALSE;
+ previousByte = _outWindowStream.GetByte(0);
+ curSize -= locLen;
+ nowPos64 += locLen;
+ len -= locLen;
+ if (len != 0)
+ {
+ _remainLen = (Int32)len;
+ break;
+ }
+
+ #ifdef _NO_EXCEPTIONS
+ if (_outWindowStream.ErrorCode != S_OK)
+ return _outWindowStream.ErrorCode;
+ #endif
+ }
+ }
+ }
+ if (_rangeDecoder.Stream.WasFinished())
+ return S_FALSE;
+ _reps[0] = rep0;
+ _reps[1] = rep1;
+ _reps[2] = rep2;
+ _reps[3] = rep3;
+ _state = state;
+
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ SetInStream(inStream);
+ _outWindowStream.SetStream(outStream);
+ SetOutStreamSize(outSize);
+ CDecoderFlusher flusher(this);
+
+ for (;;)
+ {
+ UInt32 curSize = 1 << 18;
+ RINOK(CodeSpec(curSize));
+ if (_remainLen == kLenIdFinished)
+ break;
+ if (progress != NULL)
+ {
+ UInt64 inSize = _rangeDecoder.GetProcessedSize();
+ UInt64 nowPos64 = _outWindowStream.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&inSize, &nowPos64));
+ }
+ 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)
+{
+ LZMA_TRY_BEGIN
+ return CodeReal(inStream, outStream, inSize, outSize, progress);
+ LZMA_TRY_END
+}
+
+STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *properties, UInt32 size)
+{
+ if (size < 5)
+ return E_INVALIDARG;
+ int lc = properties[0] % 9;
+ Byte remainder = (Byte)(properties[0] / 9);
+ int lp = remainder % 5;
+ int pb = remainder / 5;
+ if (pb > NLength::kNumPosStatesBitsMax)
+ return E_INVALIDARG;
+ _posStateMask = (1 << pb) - 1;
+ UInt32 dictionarySize = 0;
+ for (int i = 0; i < 4; i++)
+ dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8);
+ if (!_outWindowStream.Create(dictionarySize))
+ return E_OUTOFMEMORY;
+ if (!_literalDecoder.Create(lp, lc))
+ return E_OUTOFMEMORY;
+ if (!_rangeDecoder.Create(1 << 20))
+ return E_OUTOFMEMORY;
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
+{
+ *value = _rangeDecoder.GetProcessedSize();
+ return S_OK;
+}
+
+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)
+{
+ _outSizeDefined = (outSize != NULL);
+ if (_outSizeDefined)
+ _outSize = *outSize;
+ _remainLen = kLenIdNeedInit;
+ _outWindowStream.Init();
+ return S_OK;
+}
+
+#ifdef _ST_MODE
+
+STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ LZMA_TRY_BEGIN
+ if (processedSize)
+ *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
+}
+
+#endif
+
+}}
diff --git a/CPP/7zip/Compress/LZMA/LZMADecoder.h b/CPP/7zip/Compress/LZMA/LZMADecoder.h
new file mode 100755
index 00000000..1c10409f
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA/LZMADecoder.h
@@ -0,0 +1,251 @@
+// LZMA/Decoder.h
+
+#ifndef __LZMA_DECODER_H
+#define __LZMA_DECODER_H
+
+#include "../../../Common/MyCom.h"
+#include "../../../Common/Alloc.h"
+#include "../../ICoder.h"
+#include "../LZ/LZOutWindow.h"
+#include "../RangeCoder/RangeCoderBitTree.h"
+
+#include "LZMA.h"
+
+namespace NCompress {
+namespace NLZMA {
+
+typedef NRangeCoder::CBitDecoder<kNumMoveBits> CMyBitDecoder;
+
+class CLiteralDecoder2
+{
+ CMyBitDecoder _decoders[0x300];
+public:
+ void Init()
+ {
+ for (int i = 0; i < 0x300; i++)
+ _decoders[i].Init();
+ }
+ Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder)
+ {
+ UInt32 symbol = 1;
+ RC_INIT_VAR
+ do
+ {
+ // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
+ RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol)
+ }
+ while (symbol < 0x100);
+ RC_FLUSH_VAR
+ return (Byte)symbol;
+ }
+ Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, Byte matchByte)
+ {
+ UInt32 symbol = 1;
+ RC_INIT_VAR
+ do
+ {
+ UInt32 matchBit = (matchByte >> 7) & 1;
+ matchByte <<= 1;
+ // UInt32 bit = _decoders[1 + matchBit][symbol].Decode(rangeDecoder);
+ // symbol = (symbol << 1) | bit;
+ UInt32 bit;
+ RC_GETBIT2(kNumMoveBits, _decoders[0x100 + (matchBit << 8) + symbol].Prob, symbol,
+ bit = 0, bit = 1)
+ if (matchBit != bit)
+ {
+ while (symbol < 0x100)
+ {
+ // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
+ RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol)
+ }
+ break;
+ }
+ }
+ while (symbol < 0x100);
+ RC_FLUSH_VAR
+ return (Byte)symbol;
+ }
+};
+
+class CLiteralDecoder
+{
+ CLiteralDecoder2 *_coders;
+ int _numPrevBits;
+ int _numPosBits;
+ UInt32 _posMask;
+public:
+ CLiteralDecoder(): _coders(0) {}
+ ~CLiteralDecoder() { Free(); }
+ void Free()
+ {
+ MyFree(_coders);
+ _coders = 0;
+ }
+ bool Create(int numPosBits, int numPrevBits)
+ {
+ if (_coders == 0 || (numPosBits + numPrevBits) !=
+ (_numPrevBits + _numPosBits) )
+ {
+ Free();
+ UInt32 numStates = 1 << (numPosBits + numPrevBits);
+ _coders = (CLiteralDecoder2 *)MyAlloc(numStates * sizeof(CLiteralDecoder2));
+ }
+ _numPosBits = numPosBits;
+ _posMask = (1 << numPosBits) - 1;
+ _numPrevBits = numPrevBits;
+ return (_coders != 0);
+ }
+ void Init()
+ {
+ UInt32 numStates = 1 << (_numPrevBits + _numPosBits);
+ for (UInt32 i = 0; i < numStates; i++)
+ _coders[i].Init();
+ }
+ UInt32 GetState(UInt32 pos, Byte prevByte) const
+ { return ((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits)); }
+ Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte)
+ { return _coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }
+ Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte, Byte matchByte)
+ { return _coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }
+};
+
+namespace NLength {
+
+class CDecoder
+{
+ CMyBitDecoder _choice;
+ CMyBitDecoder _choice2;
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumLowBits> _lowCoder[kNumPosStatesMax];
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesMax];
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumHighBits> _highCoder;
+public:
+ void Init(UInt32 numPosStates)
+ {
+ _choice.Init();
+ _choice2.Init();
+ for (UInt32 posState = 0; posState < numPosStates; posState++)
+ {
+ _lowCoder[posState].Init();
+ _midCoder[posState].Init();
+ }
+ _highCoder.Init();
+ }
+ UInt32 Decode(NRangeCoder::CDecoder *rangeDecoder, UInt32 posState)
+ {
+ if(_choice.Decode(rangeDecoder) == 0)
+ return _lowCoder[posState].Decode(rangeDecoder);
+ if(_choice2.Decode(rangeDecoder) == 0)
+ return kNumLowSymbols + _midCoder[posState].Decode(rangeDecoder);
+ return kNumLowSymbols + kNumMidSymbols + _highCoder.Decode(rangeDecoder);
+ }
+};
+
+}
+
+class CDecoder:
+ public ICompressCoder,
+ public ICompressSetDecoderProperties2,
+ public ICompressGetInStreamProcessedSize,
+ #ifdef _ST_MODE
+ public ICompressSetInStream,
+ public ICompressSetOutStreamSize,
+ public ISequentialInStream,
+ #endif
+ public CMyUnknownImp
+{
+ CLZOutWindow _outWindowStream;
+ NRangeCoder::CDecoder _rangeDecoder;
+
+ CMyBitDecoder _isMatch[kNumStates][NLength::kNumPosStatesMax];
+ CMyBitDecoder _isRep[kNumStates];
+ CMyBitDecoder _isRepG0[kNumStates];
+ CMyBitDecoder _isRepG1[kNumStates];
+ CMyBitDecoder _isRepG2[kNumStates];
+ CMyBitDecoder _isRep0Long[kNumStates][NLength::kNumPosStatesMax];
+
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumPosSlotBits> _posSlotDecoder[kNumLenToPosStates];
+
+ CMyBitDecoder _posDecoders[kNumFullDistances - kEndPosModelIndex];
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumAlignBits> _posAlignDecoder;
+
+ NLength::CDecoder _lenDecoder;
+ NLength::CDecoder _repMatchLenDecoder;
+
+ CLiteralDecoder _literalDecoder;
+
+ UInt32 _posStateMask;
+
+ ///////////////////
+ // State
+ UInt32 _reps[4];
+ CState _state;
+ Int32 _remainLen; // -1 means end of stream. // -2 means need Init
+ UInt64 _outSize;
+ bool _outSizeDefined;
+
+ void Init();
+ HRESULT CodeSpec(UInt32 size);
+public:
+
+ #ifdef _ST_MODE
+ MY_UNKNOWN_IMP5(
+ ICompressSetDecoderProperties2,
+ ICompressGetInStreamProcessedSize,
+ ICompressSetInStream,
+ ICompressSetOutStreamSize,
+ ISequentialInStream)
+ #else
+ MY_UNKNOWN_IMP2(
+ ICompressSetDecoderProperties2,
+ ICompressGetInStreamProcessedSize)
+ #endif
+
+ 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(); }
+
+ 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);
+
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
+
+ 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) {}
+ virtual ~CDecoder() {}
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Compress/LZMA/LZMAEncoder.cpp b/CPP/7zip/Compress/LZMA/LZMAEncoder.cpp
new file mode 100755
index 00000000..0589f8a1
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA/LZMAEncoder.cpp
@@ -0,0 +1,1530 @@
+// LZMA/Encoder.cpp
+
+#include "StdAfx.h"
+
+#include <stdio.h>
+
+#include "../../../Common/Defs.h"
+#include "../../Common/StreamUtils.h"
+
+#include "LZMAEncoder.h"
+
+// extern "C" { #include "../../../../C/7zCrc.h" }
+
+// #define SHOW_STAT
+
+
+namespace NCompress {
+namespace NLZMA {
+
+// struct CCrcInit { CCrcInit() { InitCrcTable(); } } g_CrcInit;
+
+const int kDefaultDictionaryLogSize = 22;
+const UInt32 kNumFastBytesDefault = 0x20;
+
+Byte g_FastPos[1 << 11];
+
+class CFastPosInit
+{
+public:
+ CFastPosInit() { Init(); }
+ void Init()
+ {
+ const Byte kFastSlots = 22;
+ int c = 2;
+ g_FastPos[0] = 0;
+ g_FastPos[1] = 1;
+
+ for (Byte slotFast = 2; slotFast < kFastSlots; slotFast++)
+ {
+ UInt32 k = (1 << ((slotFast >> 1) - 1));
+ for (UInt32 j = 0; j < k; j++, c++)
+ g_FastPos[c] = slotFast;
+ }
+ }
+} g_FastPosInit;
+
+void CLiteralEncoder2::Encode(NRangeCoder::CEncoder *rangeEncoder, Byte symbol)
+{
+ UInt32 context = 1;
+ int i = 8;
+ do
+ {
+ i--;
+ UInt32 bit = (symbol >> i) & 1;
+ _encoders[context].Encode(rangeEncoder, bit);
+ context = (context << 1) | bit;
+ }
+ while(i != 0);
+}
+
+void CLiteralEncoder2::EncodeMatched(NRangeCoder::CEncoder *rangeEncoder,
+ Byte matchByte, Byte symbol)
+{
+ UInt32 context = 1;
+ int i = 8;
+ do
+ {
+ i--;
+ UInt32 bit = (symbol >> i) & 1;
+ UInt32 matchBit = (matchByte >> i) & 1;
+ _encoders[0x100 + (matchBit << 8) + context].Encode(rangeEncoder, bit);
+ context = (context << 1) | bit;
+ if (matchBit != bit)
+ {
+ while(i != 0)
+ {
+ i--;
+ UInt32 bit = (symbol >> i) & 1;
+ _encoders[context].Encode(rangeEncoder, bit);
+ context = (context << 1) | bit;
+ }
+ break;
+ }
+ }
+ while(i != 0);
+}
+
+UInt32 CLiteralEncoder2::GetPrice(bool matchMode, Byte matchByte, Byte symbol) const
+{
+ UInt32 price = 0;
+ UInt32 context = 1;
+ int i = 8;
+ if (matchMode)
+ {
+ do
+ {
+ i--;
+ UInt32 matchBit = (matchByte >> i) & 1;
+ UInt32 bit = (symbol >> i) & 1;
+ price += _encoders[0x100 + (matchBit << 8) + context].GetPrice(bit);
+ context = (context << 1) | bit;
+ if (matchBit != bit)
+ break;
+ }
+ while (i != 0);
+ }
+ while(i != 0)
+ {
+ i--;
+ UInt32 bit = (symbol >> i) & 1;
+ price += _encoders[context].GetPrice(bit);
+ context = (context << 1) | bit;
+ }
+ return price;
+};
+
+
+namespace NLength {
+
+void CEncoder::Init(UInt32 numPosStates)
+{
+ _choice.Init();
+ _choice2.Init();
+ for (UInt32 posState = 0; posState < numPosStates; posState++)
+ {
+ _lowCoder[posState].Init();
+ _midCoder[posState].Init();
+ }
+ _highCoder.Init();
+}
+
+void CEncoder::Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState)
+{
+ if(symbol < kNumLowSymbols)
+ {
+ _choice.Encode(rangeEncoder, 0);
+ _lowCoder[posState].Encode(rangeEncoder, symbol);
+ }
+ else
+ {
+ _choice.Encode(rangeEncoder, 1);
+ if(symbol < kNumLowSymbols + kNumMidSymbols)
+ {
+ _choice2.Encode(rangeEncoder, 0);
+ _midCoder[posState].Encode(rangeEncoder, symbol - kNumLowSymbols);
+ }
+ else
+ {
+ _choice2.Encode(rangeEncoder, 1);
+ _highCoder.Encode(rangeEncoder, symbol - kNumLowSymbols - kNumMidSymbols);
+ }
+ }
+}
+
+void CEncoder::SetPrices(UInt32 posState, UInt32 numSymbols, UInt32 *prices) const
+{
+ UInt32 a0 = _choice.GetPrice0();
+ UInt32 a1 = _choice.GetPrice1();
+ UInt32 b0 = a1 + _choice2.GetPrice0();
+ UInt32 b1 = a1 + _choice2.GetPrice1();
+ UInt32 i = 0;
+ for (i = 0; i < kNumLowSymbols; i++)
+ {
+ if (i >= numSymbols)
+ return;
+ prices[i] = a0 + _lowCoder[posState].GetPrice(i);
+ }
+ for (; i < kNumLowSymbols + kNumMidSymbols; i++)
+ {
+ if (i >= numSymbols)
+ return;
+ prices[i] = b0 + _midCoder[posState].GetPrice(i - kNumLowSymbols);
+ }
+ for (; i < numSymbols; i++)
+ prices[i] = b1 + _highCoder.GetPrice(i - kNumLowSymbols - kNumMidSymbols);
+}
+
+}
+
+CEncoder::CEncoder():
+ _numFastBytes(kNumFastBytesDefault),
+ _distTableSize(kDefaultDictionaryLogSize * 2),
+ _posStateBits(2),
+ _posStateMask(4 - 1),
+ _numLiteralPosStateBits(0),
+ _numLiteralContextBits(3),
+ _dictionarySize(1 << kDefaultDictionaryLogSize),
+ _matchFinderCycles(0),
+ #ifdef COMPRESS_MF_MT
+ _multiThread(false),
+ #endif
+ _writeEndMark(false)
+{
+ MatchFinder_Construct(&_matchFinderBase);
+ // _maxMode = false;
+ _fastMode = false;
+ #ifdef COMPRESS_MF_MT
+ MatchFinderMt_Construct(&_matchFinderMt);
+ _matchFinderMt.MatchFinder = &_matchFinderBase;
+ #endif
+}
+
+
+static void *SzAlloc(size_t size) { return BigAlloc(size); }
+static void SzFree(void *address) { BigFree(address); }
+ISzAlloc g_Alloc = { SzAlloc, SzFree };
+
+CEncoder::~CEncoder()
+{
+ #ifdef COMPRESS_MF_MT
+ MatchFinderMt_Destruct(&_matchFinderMt, &g_Alloc);
+ #endif
+ MatchFinder_Free(&_matchFinderBase, &g_Alloc);
+}
+
+static const UInt32 kBigHashDicLimit = (UInt32)1 << 24;
+
+HRESULT CEncoder::Create()
+{
+ if (!_rangeEncoder.Create(1 << 20))
+ return E_OUTOFMEMORY;
+ bool btMode = (_matchFinderBase.btMode != 0);
+ #ifdef COMPRESS_MF_MT
+ _mtMode = (_multiThread && !_fastMode && btMode);
+ #endif
+
+ if (!_literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits))
+ return E_OUTOFMEMORY;
+
+ _matchFinderBase.bigHash = (_dictionarySize > kBigHashDicLimit);
+
+ UInt32 numCycles = 16 + (_numFastBytes >> 1);
+ if (!btMode)
+ numCycles >>= 1;
+ if (_matchFinderCycles != 0)
+ numCycles = _matchFinderCycles;
+ _matchFinderBase.cutValue = numCycles;
+ #ifdef COMPRESS_MF_MT
+ if (_mtMode)
+ {
+ RINOK(MatchFinderMt_Create(&_matchFinderMt, _dictionarySize, kNumOpts, _numFastBytes, kMatchMaxLen, &g_Alloc));
+ _matchFinderObj = &_matchFinderMt;
+ MatchFinderMt_CreateVTable(&_matchFinderMt, &_matchFinder);
+ }
+ else
+ #endif
+ {
+ if (!MatchFinder_Create(&_matchFinderBase, _dictionarySize, kNumOpts, _numFastBytes, kMatchMaxLen, &g_Alloc))
+ return E_OUTOFMEMORY;
+ _matchFinderObj = &_matchFinderBase;
+ MatchFinder_CreateVTable(&_matchFinderBase, &_matchFinder);
+ }
+ return S_OK;
+}
+
+inline wchar_t GetUpperChar(wchar_t c)
+{
+ if (c >= 'a' && c <= 'z')
+ c -= 0x20;
+ return c;
+}
+
+static int ParseMatchFinder(const wchar_t *s, int *btMode, UInt32 *numHashBytes /* , int *skipModeBits */)
+{
+ wchar_t c = GetUpperChar(*s++);
+ if (c == L'H')
+ {
+ if (GetUpperChar(*s++) != L'C')
+ return 0;
+ int numHashBytesLoc = (int)(*s++ - L'0');
+ if (numHashBytesLoc < 4 || numHashBytesLoc > 4)
+ return 0;
+ if (*s++ != 0)
+ return 0;
+ *btMode = 0;
+ *numHashBytes = numHashBytesLoc;
+ return 1;
+ }
+ if (c != L'B')
+ return 0;
+
+ if (GetUpperChar(*s++) != L'T')
+ return 0;
+ int numHashBytesLoc = (int)(*s++ - L'0');
+ if (numHashBytesLoc < 2 || numHashBytesLoc > 4)
+ return 0;
+ c = GetUpperChar(*s++);
+ /*
+ int skipModeBitsLoc = 0;
+ if (c == L'D')
+ {
+ skipModeBitsLoc = 2;
+ c = GetUpperChar(*s++);
+ }
+ */
+ if (c != L'\0')
+ return 0;
+ *btMode = 1;
+ *numHashBytes = numHashBytesLoc;
+ // *skipModeBits = skipModeBitsLoc;
+ return 1;
+}
+
+STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties)
+{
+ for (UInt32 i = 0; i < numProperties; i++)
+ {
+ const PROPVARIANT &prop = properties[i];
+ switch(propIDs[i])
+ {
+ case NCoderPropID::kNumFastBytes:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 numFastBytes = prop.ulVal;
+ if(numFastBytes < 5 || numFastBytes > kMatchMaxLen)
+ return E_INVALIDARG;
+ _numFastBytes = numFastBytes;
+ break;
+ }
+ case NCoderPropID::kMatchFinderCycles:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ _matchFinderCycles = prop.ulVal;
+ break;
+ }
+ case NCoderPropID::kAlgorithm:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 maximize = prop.ulVal;
+ _fastMode = (maximize == 0);
+ // _maxMode = (maximize >= 2);
+ break;
+ }
+ case NCoderPropID::kMatchFinder:
+ {
+ if (prop.vt != VT_BSTR)
+ return E_INVALIDARG;
+ if (!ParseMatchFinder(prop.bstrVal, &_matchFinderBase.btMode, &_matchFinderBase.numHashBytes /* , &_matchFinderBase.skipModeBits */))
+ return E_INVALIDARG;
+ break;
+ }
+ #ifdef COMPRESS_MF_MT
+ case NCoderPropID::kMultiThread:
+ {
+ if (prop.vt != VT_BOOL)
+ return E_INVALIDARG;
+ Bool newMultiThread = (prop.boolVal == VARIANT_TRUE);
+ if (newMultiThread != _multiThread)
+ {
+ ReleaseMatchFinder();
+ _multiThread = newMultiThread;
+ }
+ break;
+ }
+ case NCoderPropID::kNumThreads:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ Bool newMultiThread = (prop.ulVal > 1) ? True : False;
+ if (newMultiThread != _multiThread)
+ {
+ ReleaseMatchFinder();
+ _multiThread = newMultiThread;
+ }
+ break;
+ }
+ #endif
+ case NCoderPropID::kDictionarySize:
+ {
+ const int kDicLogSizeMaxCompress = 30;
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 dictionarySize = prop.ulVal;
+ if (dictionarySize < UInt32(1 << kDicLogSizeMin) ||
+ dictionarySize > UInt32(1 << kDicLogSizeMaxCompress))
+ return E_INVALIDARG;
+ _dictionarySize = dictionarySize;
+ UInt32 dicLogSize;
+ for(dicLogSize = 0; dicLogSize < (UInt32)kDicLogSizeMaxCompress; dicLogSize++)
+ if (dictionarySize <= (UInt32(1) << dicLogSize))
+ break;
+ _distTableSize = dicLogSize * 2;
+ break;
+ }
+ case NCoderPropID::kPosStateBits:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 value = prop.ulVal;
+ if (value > (UInt32)NLength::kNumPosStatesBitsEncodingMax)
+ return E_INVALIDARG;
+ _posStateBits = value;
+ _posStateMask = (1 << _posStateBits) - 1;
+ break;
+ }
+ case NCoderPropID::kLitPosBits:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 value = prop.ulVal;
+ if (value > (UInt32)kNumLitPosStatesBitsEncodingMax)
+ return E_INVALIDARG;
+ _numLiteralPosStateBits = value;
+ break;
+ }
+ case NCoderPropID::kLitContextBits:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 value = prop.ulVal;
+ if (value > (UInt32)kNumLitContextBitsMax)
+ return E_INVALIDARG;
+ _numLiteralContextBits = value;
+ break;
+ }
+ case NCoderPropID::kEndMarker:
+ {
+ if (prop.vt != VT_BOOL)
+ return E_INVALIDARG;
+ SetWriteEndMarkerMode(prop.boolVal == VARIANT_TRUE);
+ break;
+ }
+ default:
+ return E_INVALIDARG;
+ }
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{
+ const UInt32 kPropSize = 5;
+ Byte properties[kPropSize];
+ properties[0] = (Byte)((_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits);
+ for (int i = 0; i < 4; i++)
+ properties[1 + i] = Byte(_dictionarySize >> (8 * i));
+ return WriteStream(outStream, properties, kPropSize, NULL);
+}
+
+STDMETHODIMP CEncoder::SetOutStream(ISequentialOutStream *outStream)
+{
+ _rangeEncoder.SetStream(outStream);
+ return S_OK;
+}
+
+STDMETHODIMP CEncoder::ReleaseOutStream()
+{
+ _rangeEncoder.ReleaseStream();
+ return S_OK;
+}
+
+HRESULT CEncoder::Init()
+{
+ CBaseState::Init();
+
+ _rangeEncoder.Init();
+
+ for(int i = 0; i < kNumStates; i++)
+ {
+ for (UInt32 j = 0; j <= _posStateMask; j++)
+ {
+ _isMatch[i][j].Init();
+ _isRep0Long[i][j].Init();
+ }
+ _isRep[i].Init();
+ _isRepG0[i].Init();
+ _isRepG1[i].Init();
+ _isRepG2[i].Init();
+ }
+
+ _literalEncoder.Init();
+
+ {
+ for(UInt32 i = 0; i < kNumLenToPosStates; i++)
+ _posSlotEncoder[i].Init();
+ }
+ {
+ for(UInt32 i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
+ _posEncoders[i].Init();
+ }
+
+ _lenEncoder.Init(1 << _posStateBits);
+ _repMatchLenEncoder.Init(1 << _posStateBits);
+
+ _posAlignEncoder.Init();
+
+ _longestMatchWasFound = false;
+ _optimumEndIndex = 0;
+ _optimumCurrentIndex = 0;
+ _additionalOffset = 0;
+
+ return S_OK;
+}
+
+#ifdef SHOW_STAT
+static int ttt = 0;
+#endif
+
+void CEncoder::MovePos(UInt32 num)
+{
+ #ifdef SHOW_STAT
+ ttt += num;
+ printf("\n MovePos %d", num);
+ #endif
+ if (num != 0)
+ {
+ _additionalOffset += num;
+ _matchFinder.Skip(_matchFinderObj, num);
+ }
+}
+
+UInt32 CEncoder::Backward(UInt32 &backRes, UInt32 cur)
+{
+ _optimumEndIndex = cur;
+ UInt32 posMem = _optimum[cur].PosPrev;
+ UInt32 backMem = _optimum[cur].BackPrev;
+ do
+ {
+ if (_optimum[cur].Prev1IsChar)
+ {
+ _optimum[posMem].MakeAsChar();
+ _optimum[posMem].PosPrev = posMem - 1;
+ if (_optimum[cur].Prev2)
+ {
+ _optimum[posMem - 1].Prev1IsChar = false;
+ _optimum[posMem - 1].PosPrev = _optimum[cur].PosPrev2;
+ _optimum[posMem - 1].BackPrev = _optimum[cur].BackPrev2;
+ }
+ }
+ UInt32 posPrev = posMem;
+ UInt32 backCur = backMem;
+
+ backMem = _optimum[posPrev].BackPrev;
+ posMem = _optimum[posPrev].PosPrev;
+
+ _optimum[posPrev].BackPrev = backCur;
+ _optimum[posPrev].PosPrev = cur;
+ cur = posPrev;
+ }
+ while(cur != 0);
+ backRes = _optimum[0].BackPrev;
+ _optimumCurrentIndex = _optimum[0].PosPrev;
+ return _optimumCurrentIndex;
+}
+
+/*
+Out:
+ (lenRes == 1) && (backRes == 0xFFFFFFFF) means Literal
+*/
+
+UInt32 CEncoder::GetOptimum(UInt32 position, UInt32 &backRes)
+{
+ if(_optimumEndIndex != _optimumCurrentIndex)
+ {
+ const COptimal &optimum = _optimum[_optimumCurrentIndex];
+ UInt32 lenRes = optimum.PosPrev - _optimumCurrentIndex;
+ backRes = optimum.BackPrev;
+ _optimumCurrentIndex = optimum.PosPrev;
+ return lenRes;
+ }
+ _optimumCurrentIndex = _optimumEndIndex = 0;
+
+ UInt32 numAvailableBytes = _matchFinder.GetNumAvailableBytes(_matchFinderObj);
+
+ UInt32 lenMain, numDistancePairs;
+ if (!_longestMatchWasFound)
+ {
+ lenMain = ReadMatchDistances(numDistancePairs);
+ }
+ else
+ {
+ lenMain = _longestMatchLength;
+ numDistancePairs = _numDistancePairs;
+ _longestMatchWasFound = false;
+ }
+
+ const Byte *data = _matchFinder.GetPointerToCurrentPos(_matchFinderObj) - 1;
+ if (numAvailableBytes < 2)
+ {
+ backRes = (UInt32)(-1);
+ return 1;
+ }
+ if (numAvailableBytes > kMatchMaxLen)
+ numAvailableBytes = kMatchMaxLen;
+
+ UInt32 reps[kNumRepDistances];
+ UInt32 repLens[kNumRepDistances];
+ UInt32 repMaxIndex = 0;
+ UInt32 i;
+ for(i = 0; i < kNumRepDistances; i++)
+ {
+ reps[i] = _repDistances[i];
+ UInt32 backOffset = reps[i] + 1;
+ if (data[0] != data[(size_t)0 - backOffset] || data[1] != data[(size_t)1 - backOffset])
+ {
+ repLens[i] = 0;
+ continue;
+ }
+ UInt32 lenTest;
+ for (lenTest = 2; lenTest < numAvailableBytes &&
+ data[lenTest] == data[(size_t)lenTest - backOffset]; lenTest++);
+ repLens[i] = lenTest;
+ if (lenTest > repLens[repMaxIndex])
+ repMaxIndex = i;
+ }
+ if(repLens[repMaxIndex] >= _numFastBytes)
+ {
+ backRes = repMaxIndex;
+ UInt32 lenRes = repLens[repMaxIndex];
+ MovePos(lenRes - 1);
+ return lenRes;
+ }
+
+ UInt32 *matchDistances = _matchDistances;
+ if(lenMain >= _numFastBytes)
+ {
+ backRes = matchDistances[numDistancePairs - 1] + kNumRepDistances;
+ MovePos(lenMain - 1);
+ return lenMain;
+ }
+ Byte currentByte = *data;
+ Byte matchByte = data[(size_t)0 - reps[0] - 1];
+
+ if(lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2)
+ {
+ backRes = (UInt32)-1;
+ return 1;
+ }
+
+ _optimum[0].State = _state;
+
+ UInt32 posState = (position & _posStateMask);
+
+ _optimum[1].Price = _isMatch[_state.Index][posState].GetPrice0() +
+ _literalEncoder.GetSubCoder(position, _previousByte)->GetPrice(!_state.IsCharState(), matchByte, currentByte);
+ _optimum[1].MakeAsChar();
+
+ UInt32 matchPrice = _isMatch[_state.Index][posState].GetPrice1();
+ UInt32 repMatchPrice = matchPrice + _isRep[_state.Index].GetPrice1();
+
+ if(matchByte == currentByte)
+ {
+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState);
+ if(shortRepPrice < _optimum[1].Price)
+ {
+ _optimum[1].Price = shortRepPrice;
+ _optimum[1].MakeAsShortRep();
+ }
+ }
+ UInt32 lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]);
+
+ if(lenEnd < 2)
+ {
+ backRes = _optimum[1].BackPrev;
+ return 1;
+ }
+
+ _optimum[1].PosPrev = 0;
+ for (i = 0; i < kNumRepDistances; i++)
+ _optimum[0].Backs[i] = reps[i];
+
+ UInt32 len = lenEnd;
+ do
+ _optimum[len--].Price = kIfinityPrice;
+ while (len >= 2);
+
+ for(i = 0; i < kNumRepDistances; i++)
+ {
+ UInt32 repLen = repLens[i];
+ if (repLen < 2)
+ continue;
+ UInt32 price = repMatchPrice + GetPureRepPrice(i, _state, posState);
+ do
+ {
+ UInt32 curAndLenPrice = price + _repMatchLenEncoder.GetPrice(repLen - 2, posState);
+ COptimal &optimum = _optimum[repLen];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = 0;
+ optimum.BackPrev = i;
+ optimum.Prev1IsChar = false;
+ }
+ }
+ while(--repLen >= 2);
+ }
+
+ UInt32 normalMatchPrice = matchPrice + _isRep[_state.Index].GetPrice0();
+
+ len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
+ if (len <= lenMain)
+ {
+ UInt32 offs = 0;
+ while (len > matchDistances[offs])
+ offs += 2;
+ for(; ; len++)
+ {
+ UInt32 distance = matchDistances[offs + 1];
+ UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(distance, len, posState);
+ COptimal &optimum = _optimum[len];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = 0;
+ optimum.BackPrev = distance + kNumRepDistances;
+ optimum.Prev1IsChar = false;
+ }
+ if (len == matchDistances[offs])
+ {
+ offs += 2;
+ if (offs == numDistancePairs)
+ break;
+ }
+ }
+ }
+
+ UInt32 cur = 0;
+
+ for (;;)
+ {
+ cur++;
+ if(cur == lenEnd)
+ {
+ return Backward(backRes, cur);
+ }
+ UInt32 numAvailableBytesFull = _matchFinder.GetNumAvailableBytes(_matchFinderObj);
+ UInt32 newLen, numDistancePairs;
+ newLen = ReadMatchDistances(numDistancePairs);
+ if(newLen >= _numFastBytes)
+ {
+ _numDistancePairs = numDistancePairs;
+ _longestMatchLength = newLen;
+ _longestMatchWasFound = true;
+ return Backward(backRes, cur);
+ }
+ position++;
+ COptimal &curOptimum = _optimum[cur];
+ UInt32 posPrev = curOptimum.PosPrev;
+ CState state;
+ if (curOptimum.Prev1IsChar)
+ {
+ posPrev--;
+ if (curOptimum.Prev2)
+ {
+ state = _optimum[curOptimum.PosPrev2].State;
+ if (curOptimum.BackPrev2 < kNumRepDistances)
+ state.UpdateRep();
+ else
+ state.UpdateMatch();
+ }
+ else
+ state = _optimum[posPrev].State;
+ state.UpdateChar();
+ }
+ else
+ state = _optimum[posPrev].State;
+ if (posPrev == cur - 1)
+ {
+ if (curOptimum.IsShortRep())
+ state.UpdateShortRep();
+ else
+ state.UpdateChar();
+ }
+ else
+ {
+ UInt32 pos;
+ if (curOptimum.Prev1IsChar && curOptimum.Prev2)
+ {
+ posPrev = curOptimum.PosPrev2;
+ pos = curOptimum.BackPrev2;
+ state.UpdateRep();
+ }
+ else
+ {
+ pos = curOptimum.BackPrev;
+ if (pos < kNumRepDistances)
+ state.UpdateRep();
+ else
+ state.UpdateMatch();
+ }
+ const COptimal &prevOptimum = _optimum[posPrev];
+ if (pos < kNumRepDistances)
+ {
+ reps[0] = prevOptimum.Backs[pos];
+ UInt32 i;
+ for(i = 1; i <= pos; i++)
+ reps[i] = prevOptimum.Backs[i - 1];
+ for(; i < kNumRepDistances; i++)
+ reps[i] = prevOptimum.Backs[i];
+ }
+ else
+ {
+ reps[0] = (pos - kNumRepDistances);
+ for(UInt32 i = 1; i < kNumRepDistances; i++)
+ reps[i] = prevOptimum.Backs[i - 1];
+ }
+ }
+ curOptimum.State = state;
+ for(UInt32 i = 0; i < kNumRepDistances; i++)
+ curOptimum.Backs[i] = reps[i];
+ UInt32 curPrice = curOptimum.Price;
+ const Byte *data = _matchFinder.GetPointerToCurrentPos(_matchFinderObj) - 1;
+ const Byte currentByte = *data;
+ const Byte matchByte = data[(size_t)0 - reps[0] - 1];
+
+ UInt32 posState = (position & _posStateMask);
+
+ UInt32 curAnd1Price = curPrice +
+ _isMatch[state.Index][posState].GetPrice0() +
+ _literalEncoder.GetSubCoder(position, data[(size_t)0 - 1])->GetPrice(!state.IsCharState(), matchByte, currentByte);
+
+ COptimal &nextOptimum = _optimum[cur + 1];
+
+ bool nextIsChar = false;
+ if (curAnd1Price < nextOptimum.Price)
+ {
+ nextOptimum.Price = curAnd1Price;
+ nextOptimum.PosPrev = cur;
+ nextOptimum.MakeAsChar();
+ nextIsChar = true;
+ }
+
+ UInt32 matchPrice = curPrice + _isMatch[state.Index][posState].GetPrice1();
+ UInt32 repMatchPrice = matchPrice + _isRep[state.Index].GetPrice1();
+
+ if(matchByte == currentByte &&
+ !(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0))
+ {
+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState);
+ if(shortRepPrice <= nextOptimum.Price)
+ {
+ nextOptimum.Price = shortRepPrice;
+ nextOptimum.PosPrev = cur;
+ nextOptimum.MakeAsShortRep();
+ nextIsChar = true;
+ }
+ }
+ /*
+ if(newLen == 2 && matchDistances[2] >= kDistLimit2) // test it maybe set 2000 ?
+ continue;
+ */
+
+ numAvailableBytesFull = MyMin(kNumOpts - 1 - cur, numAvailableBytesFull);
+ UInt32 numAvailableBytes = numAvailableBytesFull;
+
+ if (numAvailableBytes < 2)
+ continue;
+ if (numAvailableBytes > _numFastBytes)
+ numAvailableBytes = _numFastBytes;
+ if (!nextIsChar && matchByte != currentByte) // speed optimization
+ {
+ // try Literal + rep0
+ UInt32 backOffset = reps[0] + 1;
+ UInt32 limit = MyMin(numAvailableBytesFull, _numFastBytes + 1);
+ UInt32 temp;
+ for (temp = 1; temp < limit &&
+ data[temp] == data[(size_t)temp - backOffset]; temp++);
+ UInt32 lenTest2 = temp - 1;
+ if (lenTest2 >= 2)
+ {
+ CState state2 = state;
+ state2.UpdateChar();
+ UInt32 posStateNext = (position + 1) & _posStateMask;
+ UInt32 nextRepMatchPrice = curAnd1Price +
+ _isMatch[state2.Index][posStateNext].GetPrice1() +
+ _isRep[state2.Index].GetPrice1();
+ // for (; lenTest2 >= 2; lenTest2--)
+ {
+ UInt32 offset = cur + 1 + lenTest2;
+ while(lenEnd < offset)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(
+ 0, lenTest2, state2, posStateNext);
+ COptimal &optimum = _optimum[offset];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur + 1;
+ optimum.BackPrev = 0;
+ optimum.Prev1IsChar = true;
+ optimum.Prev2 = false;
+ }
+ }
+ }
+ }
+
+ UInt32 startLen = 2; // speed optimization
+ for(UInt32 repIndex = 0; repIndex < kNumRepDistances; repIndex++)
+ {
+ // UInt32 repLen = _matchFinder.GetMatchLen(0 - 1, reps[repIndex], newLen); // test it;
+ UInt32 backOffset = reps[repIndex] + 1;
+ if (data[0] != data[(size_t)0 - backOffset] ||
+ data[1] != data[(size_t)1 - backOffset])
+ continue;
+ UInt32 lenTest;
+ for (lenTest = 2; lenTest < numAvailableBytes &&
+ data[lenTest] == data[(size_t)lenTest - backOffset]; lenTest++);
+ while(lenEnd < cur + lenTest)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ UInt32 lenTestTemp = lenTest;
+ UInt32 price = repMatchPrice + GetPureRepPrice(repIndex, state, posState);
+ do
+ {
+ UInt32 curAndLenPrice = price + _repMatchLenEncoder.GetPrice(lenTest - 2, posState);
+ COptimal &optimum = _optimum[cur + lenTest];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur;
+ optimum.BackPrev = repIndex;
+ optimum.Prev1IsChar = false;
+ }
+ }
+ while(--lenTest >= 2);
+ lenTest = lenTestTemp;
+
+ if (repIndex == 0)
+ startLen = lenTest + 1;
+
+ // if (_maxMode)
+ {
+ UInt32 lenTest2 = lenTest + 1;
+ UInt32 limit = MyMin(numAvailableBytesFull, lenTest2 + _numFastBytes);
+ for (; lenTest2 < limit &&
+ data[lenTest2] == data[(size_t)lenTest2 - backOffset]; lenTest2++);
+ lenTest2 -= lenTest + 1;
+ if (lenTest2 >= 2)
+ {
+ CState state2 = state;
+ state2.UpdateRep();
+ UInt32 posStateNext = (position + lenTest) & _posStateMask;
+ UInt32 curAndLenCharPrice =
+ price + _repMatchLenEncoder.GetPrice(lenTest - 2, posState) +
+ _isMatch[state2.Index][posStateNext].GetPrice0() +
+ _literalEncoder.GetSubCoder(position + lenTest, data[(size_t)lenTest - 1])->GetPrice(
+ true, data[(size_t)lenTest - backOffset], data[lenTest]);
+ state2.UpdateChar();
+ posStateNext = (position + lenTest + 1) & _posStateMask;
+ UInt32 nextRepMatchPrice = curAndLenCharPrice +
+ _isMatch[state2.Index][posStateNext].GetPrice1() +
+ _isRep[state2.Index].GetPrice1();
+
+ // for(; lenTest2 >= 2; lenTest2--)
+ {
+ UInt32 offset = cur + lenTest + 1 + lenTest2;
+ while(lenEnd < offset)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(
+ 0, lenTest2, state2, posStateNext);
+ COptimal &optimum = _optimum[offset];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur + lenTest + 1;
+ optimum.BackPrev = 0;
+ optimum.Prev1IsChar = true;
+ optimum.Prev2 = true;
+ optimum.PosPrev2 = cur;
+ optimum.BackPrev2 = repIndex;
+ }
+ }
+ }
+ }
+ }
+
+ // for(UInt32 lenTest = 2; lenTest <= newLen; lenTest++)
+ if (newLen > numAvailableBytes)
+ {
+ newLen = numAvailableBytes;
+ for (numDistancePairs = 0; newLen > matchDistances[numDistancePairs]; numDistancePairs += 2);
+ matchDistances[numDistancePairs] = newLen;
+ numDistancePairs += 2;
+ }
+ if (newLen >= startLen)
+ {
+ UInt32 normalMatchPrice = matchPrice + _isRep[state.Index].GetPrice0();
+ while(lenEnd < cur + newLen)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+
+ UInt32 offs = 0;
+ while(startLen > matchDistances[offs])
+ offs += 2;
+ UInt32 curBack = matchDistances[offs + 1];
+ UInt32 posSlot = GetPosSlot2(curBack);
+ for(UInt32 lenTest = /*2*/ startLen; ; lenTest++)
+ {
+ UInt32 curAndLenPrice = normalMatchPrice;
+ UInt32 lenToPosState = GetLenToPosState(lenTest);
+ if (curBack < kNumFullDistances)
+ curAndLenPrice += _distancesPrices[lenToPosState][curBack];
+ else
+ curAndLenPrice += _posSlotPrices[lenToPosState][posSlot] + _alignPrices[curBack & kAlignMask];
+
+ curAndLenPrice += _lenEncoder.GetPrice(lenTest - kMatchMinLen, posState);
+
+ COptimal &optimum = _optimum[cur + lenTest];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur;
+ optimum.BackPrev = curBack + kNumRepDistances;
+ optimum.Prev1IsChar = false;
+ }
+
+ if (/*_maxMode && */lenTest == matchDistances[offs])
+ {
+ // Try Match + Literal + Rep0
+ UInt32 backOffset = curBack + 1;
+ UInt32 lenTest2 = lenTest + 1;
+ UInt32 limit = MyMin(numAvailableBytesFull, lenTest2 + _numFastBytes);
+ for (; lenTest2 < limit &&
+ data[lenTest2] == data[(size_t)lenTest2 - backOffset]; lenTest2++);
+ lenTest2 -= lenTest + 1;
+ if (lenTest2 >= 2)
+ {
+ CState state2 = state;
+ state2.UpdateMatch();
+ UInt32 posStateNext = (position + lenTest) & _posStateMask;
+ UInt32 curAndLenCharPrice = curAndLenPrice +
+ _isMatch[state2.Index][posStateNext].GetPrice0() +
+ _literalEncoder.GetSubCoder(position + lenTest, data[(size_t)lenTest - 1])->GetPrice(
+ true, data[(size_t)lenTest - backOffset], data[lenTest]);
+ state2.UpdateChar();
+ posStateNext = (posStateNext + 1) & _posStateMask;
+ UInt32 nextRepMatchPrice = curAndLenCharPrice +
+ _isMatch[state2.Index][posStateNext].GetPrice1() +
+ _isRep[state2.Index].GetPrice1();
+
+ // for(; lenTest2 >= 2; lenTest2--)
+ {
+ UInt32 offset = cur + lenTest + 1 + lenTest2;
+ while(lenEnd < offset)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext);
+ COptimal &optimum = _optimum[offset];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur + lenTest + 1;
+ optimum.BackPrev = 0;
+ optimum.Prev1IsChar = true;
+ optimum.Prev2 = true;
+ optimum.PosPrev2 = cur;
+ optimum.BackPrev2 = curBack + kNumRepDistances;
+ }
+ }
+ }
+ offs += 2;
+ if (offs == numDistancePairs)
+ break;
+ curBack = matchDistances[offs + 1];
+ if (curBack >= kNumFullDistances)
+ posSlot = GetPosSlot2(curBack);
+ }
+ }
+ }
+ }
+}
+
+static inline bool ChangePair(UInt32 smallDist, UInt32 bigDist)
+{
+ return ((bigDist >> 7) > smallDist);
+}
+
+UInt32 CEncoder::ReadMatchDistances(UInt32 &numDistancePairs)
+{
+ UInt32 lenRes = 0;
+ numDistancePairs = _matchFinder.GetMatches(_matchFinderObj, _matchDistances);
+ #ifdef SHOW_STAT
+ printf("\n i = %d numPairs = %d ", ttt, numDistancePairs / 2);
+ if (ttt >= 61994)
+ ttt = ttt;
+
+ ttt++;
+ for (UInt32 i = 0; i < numDistancePairs; i += 2)
+ printf("%2d %6d | ", _matchDistances[i], _matchDistances[i + 1]);
+ #endif
+ if (numDistancePairs > 0)
+ {
+ lenRes = _matchDistances[numDistancePairs - 2];
+ if (lenRes == _numFastBytes)
+ {
+ UInt32 numAvail = _matchFinder.GetNumAvailableBytes(_matchFinderObj) + 1;
+ const Byte *pby = _matchFinder.GetPointerToCurrentPos(_matchFinderObj) - 1;
+ UInt32 distance = _matchDistances[numDistancePairs - 1] + 1;
+ if (numAvail > kMatchMaxLen)
+ numAvail = kMatchMaxLen;
+ for (; lenRes < numAvail && pby[lenRes] == pby[(size_t)lenRes - distance]; lenRes++);
+ }
+ }
+ _additionalOffset++;
+ return lenRes;
+}
+
+UInt32 CEncoder::GetOptimumFast(UInt32 &backRes)
+{
+ UInt32 numAvailableBytes = _matchFinder.GetNumAvailableBytes(_matchFinderObj);
+ UInt32 lenMain, numDistancePairs;
+ if (!_longestMatchWasFound)
+ {
+ lenMain = ReadMatchDistances(numDistancePairs);
+ }
+ else
+ {
+ lenMain = _longestMatchLength;
+ numDistancePairs = _numDistancePairs;
+ _longestMatchWasFound = false;
+ }
+
+ const Byte *data = _matchFinder.GetPointerToCurrentPos(_matchFinderObj) - 1;
+ if (numAvailableBytes > kMatchMaxLen)
+ numAvailableBytes = kMatchMaxLen;
+ if (numAvailableBytes < 2)
+ {
+ backRes = (UInt32)(-1);
+ return 1;
+ }
+
+ UInt32 repLens[kNumRepDistances];
+ UInt32 repMaxIndex = 0;
+
+ for(UInt32 i = 0; i < kNumRepDistances; i++)
+ {
+ UInt32 backOffset = _repDistances[i] + 1;
+ if (data[0] != data[(size_t)0 - backOffset] || data[1] != data[(size_t)1 - backOffset])
+ {
+ repLens[i] = 0;
+ continue;
+ }
+ UInt32 len;
+ for (len = 2; len < numAvailableBytes && data[len] == data[(size_t)len - backOffset]; len++);
+ if(len >= _numFastBytes)
+ {
+ backRes = i;
+ MovePos(len - 1);
+ return len;
+ }
+ repLens[i] = len;
+ if (len > repLens[repMaxIndex])
+ repMaxIndex = i;
+ }
+ UInt32 *matchDistances = _matchDistances;
+ if(lenMain >= _numFastBytes)
+ {
+ backRes = matchDistances[numDistancePairs - 1] + kNumRepDistances;
+ MovePos(lenMain - 1);
+ return lenMain;
+ }
+
+ UInt32 backMain = 0; // for GCC
+ if (lenMain >= 2)
+ {
+ backMain = matchDistances[numDistancePairs - 1];
+ while (numDistancePairs > 2 && lenMain == matchDistances[numDistancePairs - 4] + 1)
+ {
+ if (!ChangePair(matchDistances[numDistancePairs - 3], backMain))
+ break;
+ numDistancePairs -= 2;
+ lenMain = matchDistances[numDistancePairs - 2];
+ backMain = matchDistances[numDistancePairs - 1];
+ }
+ if (lenMain == 2 && backMain >= 0x80)
+ lenMain = 1;
+ }
+
+ if (repLens[repMaxIndex] >= 2)
+ {
+ if (repLens[repMaxIndex] + 1 >= lenMain ||
+ repLens[repMaxIndex] + 2 >= lenMain && (backMain > (1 << 9)) ||
+ repLens[repMaxIndex] + 3 >= lenMain && (backMain > (1 << 15)))
+ {
+ backRes = repMaxIndex;
+ UInt32 lenRes = repLens[repMaxIndex];
+ MovePos(lenRes - 1);
+ return lenRes;
+ }
+ }
+
+ if (lenMain >= 2 && numAvailableBytes > 2)
+ {
+ numAvailableBytes = _matchFinder.GetNumAvailableBytes(_matchFinderObj);
+ _longestMatchLength = ReadMatchDistances(_numDistancePairs);
+ if (_longestMatchLength >= 2)
+ {
+ UInt32 newDistance = matchDistances[_numDistancePairs - 1];
+ if (_longestMatchLength >= lenMain && newDistance < backMain ||
+ _longestMatchLength == lenMain + 1 && !ChangePair(backMain, newDistance) ||
+ _longestMatchLength > lenMain + 1 ||
+ _longestMatchLength + 1 >= lenMain && lenMain >= 3 && ChangePair(newDistance, backMain))
+ {
+ _longestMatchWasFound = true;
+ backRes = UInt32(-1);
+ return 1;
+ }
+ }
+ data = _matchFinder.GetPointerToCurrentPos(_matchFinderObj) - 1;
+ for(UInt32 i = 0; i < kNumRepDistances; i++)
+ {
+ UInt32 backOffset = _repDistances[i] + 1;
+ if (data[1] != data[(size_t)1 - backOffset] || data[2] != data[(size_t)2 - backOffset])
+ {
+ repLens[i] = 0;
+ continue;
+ }
+ UInt32 len;
+ for (len = 2; len < numAvailableBytes && data[len] == data[(size_t)len - backOffset]; len++);
+ if (len + 1 >= lenMain)
+ {
+ _longestMatchWasFound = true;
+ backRes = UInt32(-1);
+ return 1;
+ }
+ }
+ backRes = backMain + kNumRepDistances;
+ MovePos(lenMain - 2);
+ return lenMain;
+ }
+ backRes = UInt32(-1);
+ return 1;
+}
+
+HRESULT CEncoder::Flush(UInt32 nowPos)
+{
+ // ReleaseMFStream();
+ if (_matchFinderBase.result != SZ_OK)
+ return _matchFinderBase.result;
+ WriteEndMarker(nowPos & _posStateMask);
+ _rangeEncoder.FlushData();
+ return _rangeEncoder.FlushStream();
+}
+
+void CEncoder::WriteEndMarker(UInt32 posState)
+{
+ // This function for writing End Mark for stream version of LZMA.
+ // In current version this feature is not used.
+ if (!_writeEndMark)
+ return;
+
+ _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 1);
+ _isRep[_state.Index].Encode(&_rangeEncoder, 0);
+ _state.UpdateMatch();
+ UInt32 len = kMatchMinLen; // kMatchMaxLen;
+ _lenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState, !_fastMode);
+ UInt32 posSlot = (1 << kNumPosSlotBits) - 1;
+ UInt32 lenToPosState = GetLenToPosState(len);
+ _posSlotEncoder[lenToPosState].Encode(&_rangeEncoder, posSlot);
+ UInt32 footerBits = 30;
+ UInt32 posReduced = (UInt32(1) << footerBits) - 1;
+ _rangeEncoder.EncodeDirectBits(posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
+ _posAlignEncoder.ReverseEncode(&_rangeEncoder, posReduced & kAlignMask);
+}
+
+HRESULT CEncoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ // _needReleaseMFStream = false;
+ CCoderReleaser coderReleaser(this);
+ RINOK(SetStreams(inStream, outStream, inSize, outSize));
+ for (;;)
+ {
+ UInt64 processedInSize;
+ UInt64 processedOutSize;
+ Int32 finished;
+ RINOK(CodeOneBlock(&processedInSize, &processedOutSize, &finished));
+ if (finished != 0)
+ break;
+ if (progress != 0)
+ {
+ RINOK(progress->SetRatioInfo(&processedInSize, &processedOutSize));
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CEncoder::SetStreams(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 * /* inSize */, const UInt64 * /* outSize */)
+{
+ _inStream = inStream;
+ _finished = false;
+ RINOK(Create());
+ RINOK(SetOutStream(outStream));
+ RINOK(Init());
+
+ if (!_fastMode)
+ {
+ FillDistancesPrices();
+ FillAlignPrices();
+ }
+
+ _lenEncoder.SetTableSize(_numFastBytes + 1 - kMatchMinLen);
+ _lenEncoder.UpdateTables(1 << _posStateBits);
+ _repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - kMatchMinLen);
+ _repMatchLenEncoder.UpdateTables(1 << _posStateBits);
+
+ nowPos64 = 0;
+ return S_OK;
+}
+
+static HRes MyRead(void *object, void *data, UInt32 size, UInt32 *processedSize)
+{
+ return (HRes)((CSeqInStream *)object)->RealStream->Read(data, size, processedSize);
+}
+
+HRESULT CEncoder::CodeOneBlock(UInt64 *inSize, UInt64 *outSize, Int32 *finished)
+{
+ if (_inStream != 0)
+ {
+ _seqInStream.RealStream = _inStream;
+ _seqInStream.SeqInStream.Read = MyRead;
+ _matchFinderBase.stream = &_seqInStream.SeqInStream;
+ _matchFinder.Init(_matchFinderObj);
+ _needReleaseMFStream = true;
+ _inStream = 0;
+ }
+
+
+ *finished = 1;
+ if (_finished)
+ return _matchFinderBase.result;
+ _finished = true;
+
+ if (nowPos64 == 0)
+ {
+ if (_matchFinder.GetNumAvailableBytes(_matchFinderObj) == 0)
+ return Flush((UInt32)nowPos64);
+ UInt32 len, numDistancePairs;
+ len = ReadMatchDistances(numDistancePairs);
+ UInt32 posState = UInt32(nowPos64) & _posStateMask;
+ _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 0);
+ _state.UpdateChar();
+ Byte curByte = _matchFinder.GetIndexByte(_matchFinderObj, 0 - _additionalOffset);
+ _literalEncoder.GetSubCoder(UInt32(nowPos64), _previousByte)->Encode(&_rangeEncoder, curByte);
+ _previousByte = curByte;
+ _additionalOffset--;
+ nowPos64++;
+ }
+
+ UInt32 nowPos32 = (UInt32)nowPos64;
+ UInt32 progressPosValuePrev = nowPos32;
+
+ if (_matchFinder.GetNumAvailableBytes(_matchFinderObj) == 0)
+ return Flush(nowPos32);
+
+ for (;;)
+ {
+ #ifdef _NO_EXCEPTIONS
+ if (_rangeEncoder.Stream.ErrorCode != S_OK)
+ return _rangeEncoder.Stream.ErrorCode;
+ #endif
+ UInt32 pos, len;
+
+ if (_fastMode)
+ len = GetOptimumFast(pos);
+ else
+ len = GetOptimum(nowPos32, pos);
+
+ UInt32 posState = nowPos32 & _posStateMask;
+ if(len == 1 && pos == 0xFFFFFFFF)
+ {
+ _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 0);
+ Byte curByte = _matchFinder.GetIndexByte(_matchFinderObj, 0 - _additionalOffset);
+ CLiteralEncoder2 *subCoder = _literalEncoder.GetSubCoder(nowPos32, _previousByte);
+ if(_state.IsCharState())
+ subCoder->Encode(&_rangeEncoder, curByte);
+ else
+ {
+ Byte matchByte = _matchFinder.GetIndexByte(_matchFinderObj, 0 - _repDistances[0] - 1 - _additionalOffset);
+ subCoder->EncodeMatched(&_rangeEncoder, matchByte, curByte);
+ }
+ _state.UpdateChar();
+ _previousByte = curByte;
+ }
+ else
+ {
+ _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 1);
+ if(pos < kNumRepDistances)
+ {
+ _isRep[_state.Index].Encode(&_rangeEncoder, 1);
+ if(pos == 0)
+ {
+ _isRepG0[_state.Index].Encode(&_rangeEncoder, 0);
+ _isRep0Long[_state.Index][posState].Encode(&_rangeEncoder, ((len == 1) ? 0 : 1));
+ }
+ else
+ {
+ UInt32 distance = _repDistances[pos];
+ _isRepG0[_state.Index].Encode(&_rangeEncoder, 1);
+ if (pos == 1)
+ _isRepG1[_state.Index].Encode(&_rangeEncoder, 0);
+ else
+ {
+ _isRepG1[_state.Index].Encode(&_rangeEncoder, 1);
+ _isRepG2[_state.Index].Encode(&_rangeEncoder, pos - 2);
+ if (pos == 3)
+ _repDistances[3] = _repDistances[2];
+ _repDistances[2] = _repDistances[1];
+ }
+ _repDistances[1] = _repDistances[0];
+ _repDistances[0] = distance;
+ }
+ if (len == 1)
+ _state.UpdateShortRep();
+ else
+ {
+ _repMatchLenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState, !_fastMode);
+ _state.UpdateRep();
+ }
+ }
+ else
+ {
+ _isRep[_state.Index].Encode(&_rangeEncoder, 0);
+ _state.UpdateMatch();
+ _lenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState, !_fastMode);
+ pos -= kNumRepDistances;
+ UInt32 posSlot = GetPosSlot(pos);
+ _posSlotEncoder[GetLenToPosState(len)].Encode(&_rangeEncoder, posSlot);
+
+ if (posSlot >= kStartPosModelIndex)
+ {
+ UInt32 footerBits = ((posSlot >> 1) - 1);
+ UInt32 base = ((2 | (posSlot & 1)) << footerBits);
+ UInt32 posReduced = pos - base;
+
+ if (posSlot < kEndPosModelIndex)
+ NRangeCoder::ReverseBitTreeEncode(_posEncoders + base - posSlot - 1,
+ &_rangeEncoder, footerBits, posReduced);
+ else
+ {
+ _rangeEncoder.EncodeDirectBits(posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
+ _posAlignEncoder.ReverseEncode(&_rangeEncoder, posReduced & kAlignMask);
+ _alignPriceCount++;
+ }
+ }
+ _repDistances[3] = _repDistances[2];
+ _repDistances[2] = _repDistances[1];
+ _repDistances[1] = _repDistances[0];
+ _repDistances[0] = pos;
+ _matchPriceCount++;
+ }
+ _previousByte = _matchFinder.GetIndexByte(_matchFinderObj, len - 1 - _additionalOffset);
+ }
+ _additionalOffset -= len;
+ nowPos32 += len;
+ if (_additionalOffset == 0)
+ {
+ if (!_fastMode)
+ {
+ if (_matchPriceCount >= (1 << 7))
+ FillDistancesPrices();
+ if (_alignPriceCount >= kAlignTableSize)
+ FillAlignPrices();
+ }
+ if (_matchFinder.GetNumAvailableBytes(_matchFinderObj) == 0)
+ return Flush(nowPos32);
+ if (nowPos32 - progressPosValuePrev >= (1 << 14))
+ {
+ nowPos64 += nowPos32 - progressPosValuePrev;
+ *inSize = nowPos64;
+ *outSize = _rangeEncoder.GetProcessedSize();
+ _finished = false;
+ *finished = 0;
+ return _matchFinderBase.result;
+ }
+ }
+ }
+}
+
+STDMETHODIMP CEncoder::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 COutBufferException &e) { return e.ErrorCode; }
+ catch(...) { return E_FAIL; }
+ #endif
+}
+
+void CEncoder::FillDistancesPrices()
+{
+ UInt32 tempPrices[kNumFullDistances];
+ for (UInt32 i = kStartPosModelIndex; i < kNumFullDistances; i++)
+ {
+ UInt32 posSlot = GetPosSlot(i);
+ UInt32 footerBits = ((posSlot >> 1) - 1);
+ UInt32 base = ((2 | (posSlot & 1)) << footerBits);
+ tempPrices[i] = NRangeCoder::ReverseBitTreeGetPrice(_posEncoders +
+ base - posSlot - 1, footerBits, i - base);
+ }
+
+ for (UInt32 lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
+ {
+ UInt32 posSlot;
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumPosSlotBits> &encoder = _posSlotEncoder[lenToPosState];
+ UInt32 *posSlotPrices = _posSlotPrices[lenToPosState];
+ for (posSlot = 0; posSlot < _distTableSize; posSlot++)
+ posSlotPrices[posSlot] = encoder.GetPrice(posSlot);
+ for (posSlot = kEndPosModelIndex; posSlot < _distTableSize; posSlot++)
+ posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << NRangeCoder::kNumBitPriceShiftBits);
+
+ UInt32 *distancesPrices = _distancesPrices[lenToPosState];
+ UInt32 i;
+ for (i = 0; i < kStartPosModelIndex; i++)
+ distancesPrices[i] = posSlotPrices[i];
+ for (; i < kNumFullDistances; i++)
+ distancesPrices[i] = posSlotPrices[GetPosSlot(i)] + tempPrices[i];
+ }
+ _matchPriceCount = 0;
+}
+
+void CEncoder::FillAlignPrices()
+{
+ for (UInt32 i = 0; i < kAlignTableSize; i++)
+ _alignPrices[i] = _posAlignEncoder.ReverseGetPrice(i);
+ _alignPriceCount = 0;
+}
+
+}}
diff --git a/CPP/7zip/Compress/LZMA/LZMAEncoder.h b/CPP/7zip/Compress/LZMA/LZMAEncoder.h
new file mode 100755
index 00000000..c1dc7a69
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA/LZMAEncoder.h
@@ -0,0 +1,435 @@
+// LZMA/Encoder.h
+
+#ifndef __LZMA_ENCODER_H
+#define __LZMA_ENCODER_H
+
+#include "../../../Common/MyCom.h"
+#include "../../../Common/Alloc.h"
+#include "../../ICoder.h"
+
+extern "C"
+{
+ #include "../../../../C/Compress/Lz/MatchFinder.h"
+ #ifdef COMPRESS_MF_MT
+ #include "../../../../C/Compress/Lz/MatchFinderMt.h"
+ #endif
+}
+
+#include "../RangeCoder/RangeCoderBitTree.h"
+
+#include "LZMA.h"
+
+namespace NCompress {
+namespace NLZMA {
+
+typedef NRangeCoder::CBitEncoder<kNumMoveBits> CMyBitEncoder;
+
+class CBaseState
+{
+protected:
+ CState _state;
+ Byte _previousByte;
+ UInt32 _repDistances[kNumRepDistances];
+ void Init()
+ {
+ _state.Init();
+ _previousByte = 0;
+ for(UInt32 i = 0 ; i < kNumRepDistances; i++)
+ _repDistances[i] = 0;
+ }
+};
+
+struct COptimal
+{
+ CState State;
+
+ bool Prev1IsChar;
+ bool Prev2;
+
+ UInt32 PosPrev2;
+ UInt32 BackPrev2;
+
+ UInt32 Price;
+ UInt32 PosPrev; // posNext;
+ UInt32 BackPrev;
+ UInt32 Backs[kNumRepDistances];
+ void MakeAsChar() { BackPrev = UInt32(-1); Prev1IsChar = false; }
+ void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; }
+ bool IsShortRep() { return (BackPrev == 0); }
+};
+
+
+extern Byte g_FastPos[1 << 11];
+inline UInt32 GetPosSlot(UInt32 pos)
+{
+ if (pos < (1 << 11))
+ return g_FastPos[pos];
+ if (pos < (1 << 21))
+ return g_FastPos[pos >> 10] + 20;
+ return g_FastPos[pos >> 20] + 40;
+}
+
+inline UInt32 GetPosSlot2(UInt32 pos)
+{
+ if (pos < (1 << 17))
+ return g_FastPos[pos >> 6] + 12;
+ if (pos < (1 << 27))
+ return g_FastPos[pos >> 16] + 32;
+ return g_FastPos[pos >> 26] + 52;
+}
+
+const UInt32 kIfinityPrice = 0xFFFFFFF;
+
+const UInt32 kNumOpts = 1 << 12;
+
+
+class CLiteralEncoder2
+{
+ CMyBitEncoder _encoders[0x300];
+public:
+ void Init()
+ {
+ for (int i = 0; i < 0x300; i++)
+ _encoders[i].Init();
+ }
+ void Encode(NRangeCoder::CEncoder *rangeEncoder, Byte symbol);
+ void EncodeMatched(NRangeCoder::CEncoder *rangeEncoder, Byte matchByte, Byte symbol);
+ UInt32 GetPrice(bool matchMode, Byte matchByte, Byte symbol) const;
+};
+
+class CLiteralEncoder
+{
+ CLiteralEncoder2 *_coders;
+ int _numPrevBits;
+ int _numPosBits;
+ UInt32 _posMask;
+public:
+ CLiteralEncoder(): _coders(0) {}
+ ~CLiteralEncoder() { Free(); }
+ void Free()
+ {
+ MyFree(_coders);
+ _coders = 0;
+ }
+ bool Create(int numPosBits, int numPrevBits)
+ {
+ if (_coders == 0 || (numPosBits + numPrevBits) != (_numPrevBits + _numPosBits))
+ {
+ Free();
+ UInt32 numStates = 1 << (numPosBits + numPrevBits);
+ _coders = (CLiteralEncoder2 *)MyAlloc(numStates * sizeof(CLiteralEncoder2));
+ }
+ _numPosBits = numPosBits;
+ _posMask = (1 << numPosBits) - 1;
+ _numPrevBits = numPrevBits;
+ return (_coders != 0);
+ }
+ void Init()
+ {
+ UInt32 numStates = 1 << (_numPrevBits + _numPosBits);
+ for (UInt32 i = 0; i < numStates; i++)
+ _coders[i].Init();
+ }
+ CLiteralEncoder2 *GetSubCoder(UInt32 pos, Byte prevByte)
+ { return &_coders[((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits))]; }
+};
+
+namespace NLength {
+
+class CEncoder
+{
+ CMyBitEncoder _choice;
+ CMyBitEncoder _choice2;
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumLowBits> _lowCoder[kNumPosStatesEncodingMax];
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesEncodingMax];
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumHighBits> _highCoder;
+public:
+ void Init(UInt32 numPosStates);
+ void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState);
+ void SetPrices(UInt32 posState, UInt32 numSymbols, UInt32 *prices) const;
+};
+
+const UInt32 kNumSpecSymbols = kNumLowSymbols + kNumMidSymbols;
+
+class CPriceTableEncoder: public CEncoder
+{
+ UInt32 _prices[kNumPosStatesEncodingMax][kNumSymbolsTotal];
+ UInt32 _tableSize;
+ UInt32 _counters[kNumPosStatesEncodingMax];
+public:
+ void SetTableSize(UInt32 tableSize) { _tableSize = tableSize; }
+ UInt32 GetPrice(UInt32 symbol, UInt32 posState) const { return _prices[posState][symbol]; }
+ void UpdateTable(UInt32 posState)
+ {
+ SetPrices(posState, _tableSize, _prices[posState]);
+ _counters[posState] = _tableSize;
+ }
+ void UpdateTables(UInt32 numPosStates)
+ {
+ for (UInt32 posState = 0; posState < numPosStates; posState++)
+ UpdateTable(posState);
+ }
+ void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState, bool updatePrice)
+ {
+ CEncoder::Encode(rangeEncoder, symbol, posState);
+ if (updatePrice)
+ if (--_counters[posState] == 0)
+ UpdateTable(posState);
+ }
+};
+
+}
+
+typedef struct _CSeqInStream
+{
+ ISeqInStream SeqInStream;
+ CMyComPtr<ISequentialInStream> RealStream;
+} CSeqInStream;
+
+
+class CEncoder :
+ public ICompressCoder,
+ public ICompressSetOutStream,
+ public ICompressSetCoderProperties,
+ public ICompressWriteCoderProperties,
+ public CBaseState,
+ public CMyUnknownImp
+{
+ NRangeCoder::CEncoder _rangeEncoder;
+
+ IMatchFinder _matchFinder;
+ void *_matchFinderObj;
+
+ #ifdef COMPRESS_MF_MT
+ Bool _multiThread;
+ Bool _mtMode;
+ CMatchFinderMt _matchFinderMt;
+ #endif
+
+ CMatchFinder _matchFinderBase;
+ #ifdef COMPRESS_MF_MT
+ Byte _pad1[kMtCacheLineDummy];
+ #endif
+
+ COptimal _optimum[kNumOpts];
+
+ CMyBitEncoder _isMatch[kNumStates][NLength::kNumPosStatesEncodingMax];
+ CMyBitEncoder _isRep[kNumStates];
+ CMyBitEncoder _isRepG0[kNumStates];
+ CMyBitEncoder _isRepG1[kNumStates];
+ CMyBitEncoder _isRepG2[kNumStates];
+ CMyBitEncoder _isRep0Long[kNumStates][NLength::kNumPosStatesEncodingMax];
+
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumPosSlotBits> _posSlotEncoder[kNumLenToPosStates];
+
+ CMyBitEncoder _posEncoders[kNumFullDistances - kEndPosModelIndex];
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumAlignBits> _posAlignEncoder;
+
+ NLength::CPriceTableEncoder _lenEncoder;
+ NLength::CPriceTableEncoder _repMatchLenEncoder;
+
+ CLiteralEncoder _literalEncoder;
+
+ UInt32 _matchDistances[kMatchMaxLen * 2 + 2 + 1];
+
+ bool _fastMode;
+ // bool _maxMode;
+ UInt32 _numFastBytes;
+ UInt32 _longestMatchLength;
+ UInt32 _numDistancePairs;
+
+ UInt32 _additionalOffset;
+
+ UInt32 _optimumEndIndex;
+ UInt32 _optimumCurrentIndex;
+
+ bool _longestMatchWasFound;
+
+ UInt32 _posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
+
+ UInt32 _distancesPrices[kNumLenToPosStates][kNumFullDistances];
+
+ UInt32 _alignPrices[kAlignTableSize];
+ UInt32 _alignPriceCount;
+
+ UInt32 _distTableSize;
+
+ UInt32 _posStateBits;
+ UInt32 _posStateMask;
+ UInt32 _numLiteralPosStateBits;
+ UInt32 _numLiteralContextBits;
+
+ UInt32 _dictionarySize;
+
+ UInt32 _matchPriceCount;
+ UInt64 nowPos64;
+ bool _finished;
+ ISequentialInStream *_inStream;
+
+ CSeqInStream _seqInStream;
+
+ UInt32 _matchFinderCycles;
+ // int _numSkip
+
+ bool _writeEndMark;
+
+ bool _needReleaseMFStream;
+
+ void ReleaseMatchFinder()
+ {
+ _matchFinder.Init = 0;
+ _seqInStream.RealStream.Release();
+ }
+
+ void ReleaseMFStream()
+ {
+ if (_matchFinderObj && _needReleaseMFStream)
+ {
+ #ifdef COMPRESS_MF_MT
+ if (_mtMode)
+ MatchFinderMt_ReleaseStream(&_matchFinderMt);
+ #endif
+ _needReleaseMFStream = false;
+ }
+ _seqInStream.RealStream.Release();
+ }
+
+ UInt32 ReadMatchDistances(UInt32 &numDistancePairs);
+
+ void MovePos(UInt32 num);
+ UInt32 GetRepLen1Price(CState state, UInt32 posState) const
+ {
+ return _isRepG0[state.Index].GetPrice0() +
+ _isRep0Long[state.Index][posState].GetPrice0();
+ }
+
+ UInt32 GetPureRepPrice(UInt32 repIndex, CState state, UInt32 posState) const
+ {
+ UInt32 price;
+ if(repIndex == 0)
+ {
+ price = _isRepG0[state.Index].GetPrice0();
+ price += _isRep0Long[state.Index][posState].GetPrice1();
+ }
+ else
+ {
+ price = _isRepG0[state.Index].GetPrice1();
+ if (repIndex == 1)
+ price += _isRepG1[state.Index].GetPrice0();
+ else
+ {
+ price += _isRepG1[state.Index].GetPrice1();
+ price += _isRepG2[state.Index].GetPrice(repIndex - 2);
+ }
+ }
+ return price;
+ }
+ UInt32 GetRepPrice(UInt32 repIndex, UInt32 len, CState state, UInt32 posState) const
+ {
+ return _repMatchLenEncoder.GetPrice(len - kMatchMinLen, posState) +
+ GetPureRepPrice(repIndex, state, posState);
+ }
+ /*
+ UInt32 GetPosLen2Price(UInt32 pos, UInt32 posState) const
+ {
+ if (pos >= kNumFullDistances)
+ return kIfinityPrice;
+ return _distancesPrices[0][pos] + _lenEncoder.GetPrice(0, posState);
+ }
+ UInt32 GetPosLen3Price(UInt32 pos, UInt32 len, UInt32 posState) const
+ {
+ UInt32 price;
+ UInt32 lenToPosState = GetLenToPosState(len);
+ if (pos < kNumFullDistances)
+ price = _distancesPrices[lenToPosState][pos];
+ else
+ price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] +
+ _alignPrices[pos & kAlignMask];
+ return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState);
+ }
+ */
+ UInt32 GetPosLenPrice(UInt32 pos, UInt32 len, UInt32 posState) const
+ {
+ UInt32 price;
+ UInt32 lenToPosState = GetLenToPosState(len);
+ if (pos < kNumFullDistances)
+ price = _distancesPrices[lenToPosState][pos];
+ else
+ price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] +
+ _alignPrices[pos & kAlignMask];
+ return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState);
+ }
+
+ UInt32 Backward(UInt32 &backRes, UInt32 cur);
+ UInt32 GetOptimum(UInt32 position, UInt32 &backRes);
+ UInt32 GetOptimumFast(UInt32 &backRes);
+
+ void FillDistancesPrices();
+ void FillAlignPrices();
+
+ void ReleaseStreams()
+ {
+ ReleaseMFStream();
+ ReleaseOutStream();
+ }
+
+ HRESULT Flush(UInt32 nowPos);
+ class CCoderReleaser
+ {
+ CEncoder *_coder;
+ public:
+ CCoderReleaser(CEncoder *coder): _coder(coder) {}
+ ~CCoderReleaser() { _coder->ReleaseStreams(); }
+ };
+ friend class CCoderReleaser;
+
+ void WriteEndMarker(UInt32 posState);
+
+public:
+ CEncoder();
+ void SetWriteEndMarkerMode(bool writeEndMarker)
+ { _writeEndMark= writeEndMarker; }
+
+ HRESULT Create();
+
+ MY_UNKNOWN_IMP3(
+ ICompressSetOutStream,
+ ICompressSetCoderProperties,
+ ICompressWriteCoderProperties
+ )
+
+ HRESULT Init();
+
+ // ICompressCoder interface
+ HRESULT SetStreams(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize);
+ HRESULT CodeOneBlock(UInt64 *inSize, UInt64 *outSize, Int32 *finished);
+
+ HRESULT CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ // ICompressCoder interface
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ // ICompressSetCoderProperties2
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties);
+
+ // ICompressWriteCoderProperties
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+
+ STDMETHOD(SetOutStream)(ISequentialOutStream *outStream);
+ STDMETHOD(ReleaseOutStream)();
+
+ virtual ~CEncoder();
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Compress/LZMA/StdAfx.cpp b/CPP/7zip/Compress/LZMA/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Compress/LZMA/StdAfx.h b/CPP/7zip/Compress/LZMA/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Compress/LZMA/makefile b/CPP/7zip/Compress/LZMA/makefile
new file mode 100755
index 00000000..0b692541
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA/makefile
@@ -0,0 +1,69 @@
+PROG = LZMA.dll
+DEF_FILE = ../Codec.def
+CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_MF_MT -D_ST_MODE
+LIBS = $(LIBS) oleaut32.lib
+
+LZMA_OBJS = \
+ $O\DllExports.obj \
+
+LZMA_OPT_OBJS = \
+ $O\LZMADecoder.obj \
+ $O\LZMAEncoder.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\CRC.obj \
+
+WIN_OBJS = \
+ $O\Synchronization.obj
+
+7ZIP_COMMON_OBJS = \
+ $O\InBuffer.obj \
+ $O\OutBuffer.obj \
+ $O\StreamUtils.obj \
+
+LZ_OBJS = \
+ $O\LZOutWindow.obj \
+
+C_OBJS = \
+ $O\7zCrc.obj \
+ $O\Sort.obj \
+ $O\Threads.obj \
+
+C_LZ_OBJS = \
+ $O\MatchFinder.obj \
+ $O\MatchFinderMt.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(LZMA_OBJS) \
+ $(LZMA_OPT_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(LZ_OBJS) \
+ $(C_OBJS) \
+ $(C_LZ_OBJS) \
+ $O\RangeCoderBit.obj \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(LZMA_OBJS): $(*B).cpp
+ $(COMPL)
+$(LZMA_OPT_OBJS): $(*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
+ $(COMPL)
+$O\RangeCoderBit.obj: ../RangeCoder/$(*B).cpp
+ $(COMPL)
+$(C_OBJS): ../../../../C/$(*B).c
+ $(COMPL_O2)
+$(C_LZ_OBJS): ../../../../C/Compress/Lz/$(*B).c
+ $(COMPL_O2)
diff --git a/CPP/7zip/Compress/LZMA/resource.rc b/CPP/7zip/Compress/LZMA/resource.rc
new file mode 100755
index 00000000..1b2b6abb
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA/resource.rc
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("LZMA Codec", "LZMA")
diff --git a/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp b/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp
new file mode 100755
index 00000000..6401206c
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp
@@ -0,0 +1,449 @@
+# Microsoft Developer Studio Project File - Name="AloneLZMA" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=AloneLZMA - Win32 DebugU
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "AloneLZMA.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 "AloneLZMA.mak" CFG="AloneLZMA - Win32 DebugU"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "AloneLZMA - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "AloneLZMA - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "AloneLZMA - Win32 ReleaseU" (based on "Win32 (x86) Console Application")
+!MESSAGE "AloneLZMA - Win32 DebugU" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "AloneLZMA - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\lzma.exe" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "AloneLZMA - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\lzma.exe" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "AloneLZMA - Win32 ReleaseU"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ReleaseU"
+# PROP BASE Intermediate_Dir "ReleaseU"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ReleaseU"
+# PROP Intermediate_Dir "ReleaseU"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /Yu"StdAfx.h" /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7za2.exe" /opt:NOWIN98
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\lzma.exe" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "AloneLZMA - Win32 DebugU"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "DebugU"
+# PROP BASE Intermediate_Dir "DebugU"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "DebugU"
+# PROP Intermediate_Dir "DebugU"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7za2.exe" /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\lzma.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "AloneLZMA - Win32 Release"
+# Name "AloneLZMA - Win32 Debug"
+# Name "AloneLZMA - Win32 ReleaseU"
+# Name "AloneLZMA - Win32 DebugU"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Group "LZMA"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\LZMA\LZMA.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZMA\LZMADecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZMA\LZMADecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZMA\LZMAEncoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZMA\LZMAEncoder.h
+# End Source File
+# End Group
+# Begin Group "RangeCoder"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoderBit.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoderBit.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoderBitTree.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoderOpt.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
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# 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\CommandLineParser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Defs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Defs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyCom.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyWindows.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\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\StringToInt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringToInt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Types.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Vector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Vector.h
+# End Source File
+# End Group
+# Begin Group "7zip Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.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 "C"
+
+# PROP Default_Filter ""
+# Begin Group "C-Lz"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.h
+# End Source File
+# End Group
+# Begin Group "LZMA_C"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lzma\LzmaDecode.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lzma\LzmaDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lzma\LzmaTypes.h
+# End Source File
+# End Group
+# Begin Group "Branch"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchTypes.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchX86.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchX86.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrc.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrc.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\ICoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaAlone.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaBench.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaBench.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaRam.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaRam.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaRamDecode.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaRamDecode.h
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsw b/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsw
new file mode 100755
index 00000000..d7482d8a
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "AloneLZMA"=.\AloneLZMA.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp b/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp
new file mode 100755
index 00000000..f5ad65da
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp
@@ -0,0 +1,526 @@
+// LzmaAlone.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/MyInitGuid.h"
+
+#include <stdio.h>
+
+#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
+#include <fcntl.h>
+#include <io.h>
+#define MY_SET_BINARY_MODE(file) _setmode(_fileno(file), O_BINARY)
+#else
+#define MY_SET_BINARY_MODE(file)
+#endif
+
+#include "../../../Common/CommandLineParser.h"
+#include "../../../Common/StringConvert.h"
+#include "../../../Common/StringToInt.h"
+
+#include "../../Common/FileStreams.h"
+#include "../../Common/StreamUtils.h"
+
+#include "../LZMA/LZMADecoder.h"
+#include "../LZMA/LZMAEncoder.h"
+
+#include "LzmaBench.h"
+#include "LzmaRam.h"
+
+extern "C"
+{
+#include "LzmaRamDecode.h"
+}
+
+using namespace NCommandLineParser;
+
+#ifdef _WIN32
+bool g_IsNT = false;
+static inline bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+#endif
+
+static const char *kCantAllocate = "Can not allocate memory";
+static const char *kReadError = "Read error";
+static const char *kWriteError = "Write error";
+
+namespace NKey {
+enum Enum
+{
+ kHelp1 = 0,
+ kHelp2,
+ kMode,
+ kDictionary,
+ kFastBytes,
+ kMatchFinderCycles,
+ kLitContext,
+ kLitPos,
+ kPosBits,
+ kMatchFinder,
+ kEOS,
+ kStdIn,
+ kStdOut,
+ kFilter86
+};
+}
+
+static const CSwitchForm kSwitchForms[] =
+{
+ { L"?", NSwitchType::kSimple, false },
+ { L"H", NSwitchType::kSimple, false },
+ { L"A", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"D", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"FB", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"MC", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"LC", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"LP", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"PB", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"MF", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"EOS", NSwitchType::kSimple, false },
+ { L"SI", NSwitchType::kSimple, false },
+ { L"SO", NSwitchType::kSimple, false },
+ { L"F86", NSwitchType::kSimple, false }
+};
+
+static const int kNumSwitches = sizeof(kSwitchForms) / sizeof(kSwitchForms[0]);
+
+static void PrintHelp()
+{
+ fprintf(stderr, "\nUsage: LZMA <e|d> inputFile outputFile [<switches>...]\n"
+ " e: encode file\n"
+ " d: decode file\n"
+ " b: Benchmark\n"
+ "<Switches>\n"
+ " -a{N}: set compression mode - [0, 1], default: 1 (max)\n"
+ " -d{N}: set dictionary - [0,30], default: 23 (8MB)\n"
+ " -fb{N}: set number of fast bytes - [5, 273], default: 128\n"
+ " -mc{N}: set number of cycles for match finder\n"
+ " -lc{N}: set number of literal context bits - [0, 8], default: 3\n"
+ " -lp{N}: set number of literal pos bits - [0, 4], default: 0\n"
+ " -pb{N}: set number of pos bits - [0, 4], default: 2\n"
+ " -mf{MF_ID}: set Match Finder: [bt2, bt3, bt4, hc4], default: bt4\n"
+ " -eos: write End Of Stream marker\n"
+ " -si: read data from stdin\n"
+ " -so: write data to stdout\n"
+ );
+}
+
+static void PrintHelpAndExit(const char *s)
+{
+ fprintf(stderr, "\nError: %s\n\n", s);
+ PrintHelp();
+ throw -1;
+}
+
+static void IncorrectCommand()
+{
+ PrintHelpAndExit("Incorrect command");
+}
+
+static void WriteArgumentsToStringList(int numArguments, const char *arguments[],
+ UStringVector &strings)
+{
+ for(int i = 1; i < numArguments; i++)
+ strings.Add(MultiByteToUnicodeString(arguments[i]));
+}
+
+static bool GetNumber(const wchar_t *s, UInt32 &value)
+{
+ value = 0;
+ if (MyStringLen(s) == 0)
+ return false;
+ const wchar_t *end;
+ UInt64 res = ConvertStringToUInt64(s, &end);
+ if (*end != L'\0')
+ return false;
+ if (res > 0xFFFFFFFF)
+ return false;
+ value = UInt32(res);
+ return true;
+}
+
+int main2(int n, const char *args[])
+{
+ #ifdef _WIN32
+ g_IsNT = IsItWindowsNT();
+ #endif
+
+ fprintf(stderr, "\nLZMA 4.44 Copyright (c) 1999-2006 Igor Pavlov 2006-12-26\n");
+
+ if (n == 1)
+ {
+ PrintHelp();
+ return 0;
+ }
+
+ bool unsupportedTypes = (sizeof(Byte) != 1 || sizeof(UInt32) < 4 || sizeof(UInt64) < 4);
+ if (unsupportedTypes)
+ {
+ fprintf(stderr, "Unsupported base types. Edit Common/Types.h and recompile");
+ return 1;
+ }
+
+ UStringVector commandStrings;
+ WriteArgumentsToStringList(n, args, commandStrings);
+ CParser parser(kNumSwitches);
+ try
+ {
+ parser.ParseStrings(kSwitchForms, commandStrings);
+ }
+ catch(...)
+ {
+ IncorrectCommand();
+ }
+
+ if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
+ {
+ PrintHelp();
+ return 0;
+ }
+ const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
+
+ int paramIndex = 0;
+ if (paramIndex >= nonSwitchStrings.Size())
+ IncorrectCommand();
+ const UString &command = nonSwitchStrings[paramIndex++];
+
+ bool dictionaryIsDefined = false;
+ UInt32 dictionary = 1 << 21;
+ if(parser[NKey::kDictionary].ThereIs)
+ {
+ UInt32 dicLog;
+ if (!GetNumber(parser[NKey::kDictionary].PostStrings[0], dicLog))
+ IncorrectCommand();
+ dictionary = 1 << dicLog;
+ dictionaryIsDefined = true;
+ }
+ UString mf = L"BT4";
+ if (parser[NKey::kMatchFinder].ThereIs)
+ mf = parser[NKey::kMatchFinder].PostStrings[0];
+
+ if (command.CompareNoCase(L"b") == 0)
+ {
+ const UInt32 kNumDefaultItereations = 10;
+ UInt32 numIterations = kNumDefaultItereations;
+ {
+ if (paramIndex < nonSwitchStrings.Size())
+ if (!GetNumber(nonSwitchStrings[paramIndex++], numIterations))
+ numIterations = kNumDefaultItereations;
+ }
+ return LzmaBenchmark(stderr, numIterations, dictionary);
+ }
+
+ bool encodeMode = false;
+ if (command.CompareNoCase(L"e") == 0)
+ encodeMode = true;
+ else if (command.CompareNoCase(L"d") == 0)
+ encodeMode = false;
+ else
+ IncorrectCommand();
+
+ bool stdInMode = parser[NKey::kStdIn].ThereIs;
+ bool stdOutMode = parser[NKey::kStdOut].ThereIs;
+
+ CMyComPtr<ISequentialInStream> inStream;
+ CInFileStream *inStreamSpec = 0;
+ if (stdInMode)
+ {
+ inStream = new CStdInFileStream;
+ MY_SET_BINARY_MODE(stdin);
+ }
+ else
+ {
+ if (paramIndex >= nonSwitchStrings.Size())
+ IncorrectCommand();
+ const UString &inputName = nonSwitchStrings[paramIndex++];
+ inStreamSpec = new CInFileStream;
+ inStream = inStreamSpec;
+ if (!inStreamSpec->Open(GetSystemString(inputName)))
+ {
+ fprintf(stderr, "\nError: can not open input file %s\n",
+ (const char *)GetOemString(inputName));
+ return 1;
+ }
+ }
+
+ CMyComPtr<ISequentialOutStream> outStream;
+ if (stdOutMode)
+ {
+ outStream = new CStdOutFileStream;
+ MY_SET_BINARY_MODE(stdout);
+ }
+ else
+ {
+ if (paramIndex >= nonSwitchStrings.Size())
+ IncorrectCommand();
+ const UString &outputName = nonSwitchStrings[paramIndex++];
+ COutFileStream *outStreamSpec = new COutFileStream;
+ outStream = outStreamSpec;
+ if (!outStreamSpec->Create(GetSystemString(outputName), true))
+ {
+ fprintf(stderr, "\nError: can not open output file %s\n",
+ (const char *)GetOemString(outputName));
+ return 1;
+ }
+ }
+
+ if (parser[NKey::kFilter86].ThereIs)
+ {
+ // -f86 switch is for x86 filtered mode: BCJ + LZMA.
+ if (parser[NKey::kEOS].ThereIs || stdInMode)
+ throw "Can not use stdin in this mode";
+ UInt64 fileSize;
+ inStreamSpec->File.GetLength(fileSize);
+ if (fileSize > 0xF0000000)
+ throw "File is too big";
+ UInt32 inSize = (UInt32)fileSize;
+ Byte *inBuffer = 0;
+ if (inSize != 0)
+ {
+ inBuffer = (Byte *)MyAlloc((size_t)inSize);
+ if (inBuffer == 0)
+ throw kCantAllocate;
+ }
+
+ UInt32 processedSize;
+ if (ReadStream(inStream, inBuffer, (UInt32)inSize, &processedSize) != S_OK)
+ throw "Can not read";
+ if ((UInt32)inSize != processedSize)
+ throw "Read size error";
+
+ Byte *outBuffer = 0;
+ size_t outSizeProcessed;
+ if (encodeMode)
+ {
+ // we allocate 105% of original size for output buffer
+ size_t outSize = (size_t)fileSize / 20 * 21 + (1 << 16);
+ if (outSize != 0)
+ {
+ outBuffer = (Byte *)MyAlloc((size_t)outSize);
+ if (outBuffer == 0)
+ throw kCantAllocate;
+ }
+ if (!dictionaryIsDefined)
+ dictionary = 1 << 23;
+ int res = LzmaRamEncode(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed,
+ dictionary, SZ_FILTER_AUTO);
+ if (res != 0)
+ {
+ fprintf(stderr, "\nEncoder error = %d\n", (int)res);
+ return 1;
+ }
+ }
+ else
+ {
+ size_t outSize;
+ if (LzmaRamGetUncompressedSize(inBuffer, inSize, &outSize) != 0)
+ throw "data error";
+ if (outSize != 0)
+ {
+ outBuffer = (Byte *)MyAlloc(outSize);
+ if (outBuffer == 0)
+ throw kCantAllocate;
+ }
+ int res = LzmaRamDecompress(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed, malloc, free);
+ if (res != 0)
+ throw "LzmaDecoder error";
+ }
+ if (WriteStream(outStream, outBuffer, (UInt32)outSizeProcessed, &processedSize) != S_OK)
+ throw kWriteError;
+ MyFree(outBuffer);
+ MyFree(inBuffer);
+ return 0;
+ }
+
+
+ UInt64 fileSize;
+ if (encodeMode)
+ {
+ NCompress::NLZMA::CEncoder *encoderSpec =
+ new NCompress::NLZMA::CEncoder;
+ CMyComPtr<ICompressCoder> encoder = encoderSpec;
+
+ if (!dictionaryIsDefined)
+ dictionary = 1 << 23;
+
+ UInt32 posStateBits = 2;
+ UInt32 litContextBits = 3; // for normal files
+ // UInt32 litContextBits = 0; // for 32-bit data
+ UInt32 litPosBits = 0;
+ // UInt32 litPosBits = 2; // for 32-bit data
+ UInt32 algorithm = 1;
+ UInt32 numFastBytes = 128;
+ UInt32 matchFinderCycles = 16 + numFastBytes / 2;
+ bool matchFinderCyclesDefined = false;
+
+ bool eos = parser[NKey::kEOS].ThereIs || stdInMode;
+
+ if(parser[NKey::kMode].ThereIs)
+ if (!GetNumber(parser[NKey::kMode].PostStrings[0], algorithm))
+ IncorrectCommand();
+
+ if(parser[NKey::kFastBytes].ThereIs)
+ if (!GetNumber(parser[NKey::kFastBytes].PostStrings[0], numFastBytes))
+ IncorrectCommand();
+ matchFinderCyclesDefined = parser[NKey::kMatchFinderCycles].ThereIs;
+ if (matchFinderCyclesDefined)
+ if (!GetNumber(parser[NKey::kMatchFinderCycles].PostStrings[0], matchFinderCycles))
+ IncorrectCommand();
+ if(parser[NKey::kLitContext].ThereIs)
+ if (!GetNumber(parser[NKey::kLitContext].PostStrings[0], litContextBits))
+ IncorrectCommand();
+ if(parser[NKey::kLitPos].ThereIs)
+ if (!GetNumber(parser[NKey::kLitPos].PostStrings[0], litPosBits))
+ IncorrectCommand();
+ if(parser[NKey::kPosBits].ThereIs)
+ if (!GetNumber(parser[NKey::kPosBits].PostStrings[0], posStateBits))
+ IncorrectCommand();
+
+ PROPID propIDs[] =
+ {
+ NCoderPropID::kDictionarySize,
+ NCoderPropID::kPosStateBits,
+ NCoderPropID::kLitContextBits,
+ NCoderPropID::kLitPosBits,
+ NCoderPropID::kAlgorithm,
+ NCoderPropID::kNumFastBytes,
+ NCoderPropID::kMatchFinder,
+ NCoderPropID::kEndMarker,
+ NCoderPropID::kMatchFinderCycles
+ };
+ const int kNumPropsMax = sizeof(propIDs) / sizeof(propIDs[0]);
+ /*
+ NWindows::NCOM::CPropVariant properties[kNumProps];
+ properties[0] = UInt32(dictionary);
+ properties[1] = UInt32(posStateBits);
+ properties[2] = UInt32(litContextBits);
+
+ properties[3] = UInt32(litPosBits);
+ properties[4] = UInt32(algorithm);
+ properties[5] = UInt32(numFastBytes);
+ properties[6] = mf;
+ properties[7] = eos;
+ */
+ PROPVARIANT properties[kNumPropsMax];
+ for (int p = 0; p < 6; p++)
+ properties[p].vt = VT_UI4;
+
+ properties[0].ulVal = UInt32(dictionary);
+ properties[1].ulVal = UInt32(posStateBits);
+ properties[2].ulVal = UInt32(litContextBits);
+ properties[3].ulVal = UInt32(litPosBits);
+ properties[4].ulVal = UInt32(algorithm);
+ properties[5].ulVal = UInt32(numFastBytes);
+
+ properties[8].vt = VT_UI4;
+ properties[8].ulVal = UInt32(matchFinderCycles);
+
+ properties[6].vt = VT_BSTR;
+ properties[6].bstrVal = (BSTR)(const wchar_t *)mf;
+
+ properties[7].vt = VT_BOOL;
+ properties[7].boolVal = eos ? VARIANT_TRUE : VARIANT_FALSE;
+
+ int numProps = kNumPropsMax;
+ if (!matchFinderCyclesDefined)
+ numProps--;
+
+ if (encoderSpec->SetCoderProperties(propIDs, properties, numProps) != S_OK)
+ IncorrectCommand();
+ encoderSpec->WriteCoderProperties(outStream);
+
+ if (eos || stdInMode)
+ fileSize = (UInt64)(Int64)-1;
+ else
+ inStreamSpec->File.GetLength(fileSize);
+
+ for (int i = 0; i < 8; i++)
+ {
+ Byte b = Byte(fileSize >> (8 * i));
+ if (outStream->Write(&b, 1, 0) != S_OK)
+ {
+ fprintf(stderr, kWriteError);
+ return 1;
+ }
+ }
+ HRESULT result = encoder->Code(inStream, outStream, 0, 0, 0);
+ if (result == E_OUTOFMEMORY)
+ {
+ fprintf(stderr, "\nError: Can not allocate memory\n");
+ return 1;
+ }
+ else if (result != S_OK)
+ {
+ fprintf(stderr, "\nEncoder error = %X\n", (unsigned int)result);
+ return 1;
+ }
+ }
+ else
+ {
+ NCompress::NLZMA::CDecoder *decoderSpec =
+ new NCompress::NLZMA::CDecoder;
+ CMyComPtr<ICompressCoder> decoder = decoderSpec;
+ const UInt32 kPropertiesSize = 5;
+ Byte properties[kPropertiesSize];
+ UInt32 processedSize;
+ if (ReadStream(inStream, properties, kPropertiesSize, &processedSize) != S_OK)
+ {
+ fprintf(stderr, kReadError);
+ return 1;
+ }
+ if (processedSize != kPropertiesSize)
+ {
+ fprintf(stderr, kReadError);
+ return 1;
+ }
+ if (decoderSpec->SetDecoderProperties2(properties, kPropertiesSize) != S_OK)
+ {
+ fprintf(stderr, "SetDecoderProperties error");
+ return 1;
+ }
+ fileSize = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ Byte b;
+ if (inStream->Read(&b, 1, &processedSize) != S_OK)
+ {
+ fprintf(stderr, kReadError);
+ return 1;
+ }
+ if (processedSize != 1)
+ {
+ fprintf(stderr, kReadError);
+ return 1;
+ }
+ fileSize |= ((UInt64)b) << (8 * i);
+ }
+ if (decoder->Code(inStream, outStream, 0, &fileSize, 0) != S_OK)
+ {
+ fprintf(stderr, "Decoder error");
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int main(int n, const char *args[])
+{
+ try { return main2(n, args); }
+ catch(const char *s)
+ {
+ fprintf(stderr, "\nError: %s\n", s);
+ return 1;
+ }
+ catch(...)
+ {
+ fprintf(stderr, "\nError\n");
+ return 1;
+ }
+}
diff --git a/CPP/7zip/Compress/LZMA_Alone/LzmaBench.cpp b/CPP/7zip/Compress/LZMA_Alone/LzmaBench.cpp
new file mode 100755
index 00000000..f9924165
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA_Alone/LzmaBench.cpp
@@ -0,0 +1,506 @@
+// LzmaBench.cpp
+
+#include "StdAfx.h"
+
+#include "LzmaBench.h"
+
+#ifndef _WIN32
+#include <time.h>
+#endif
+
+#include "../../../Common/CRC.h"
+#include "../LZMA/LZMADecoder.h"
+#include "../LZMA/LZMAEncoder.h"
+
+static const UInt32 kAdditionalSize =
+#ifdef _WIN32_WCE
+(1 << 20);
+#else
+(6 << 20);
+#endif
+
+static const UInt32 kCompressedAdditionalSize = (1 << 10);
+static const UInt32 kMaxLzmaPropSize = 10;
+
+class CRandomGenerator
+{
+ UInt32 A1;
+ UInt32 A2;
+public:
+ CRandomGenerator() { Init(); }
+ void Init() { A1 = 362436069; A2 = 521288629;}
+ UInt32 GetRnd()
+ {
+ return
+ ((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) ^
+ ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) );
+ }
+};
+
+class CBitRandomGenerator
+{
+ CRandomGenerator RG;
+ UInt32 Value;
+ int NumBits;
+public:
+ void Init()
+ {
+ Value = 0;
+ NumBits = 0;
+ }
+ UInt32 GetRnd(int numBits)
+ {
+ if (NumBits > numBits)
+ {
+ UInt32 result = Value & ((1 << numBits) - 1);
+ Value >>= numBits;
+ NumBits -= numBits;
+ return result;
+ }
+ numBits -= NumBits;
+ UInt32 result = (Value << numBits);
+ Value = RG.GetRnd();
+ result |= Value & ((1 << numBits) - 1);
+ Value >>= numBits;
+ NumBits = 32 - numBits;
+ return result;
+ }
+};
+
+class CBenchRandomGenerator
+{
+ CBitRandomGenerator RG;
+ UInt32 Pos;
+ UInt32 Rep0;
+public:
+ UInt32 BufferSize;
+ Byte *Buffer;
+ CBenchRandomGenerator(): Buffer(0) {}
+ ~CBenchRandomGenerator() { Free(); }
+ void Free()
+ {
+ ::MidFree(Buffer);
+ Buffer = 0;
+ }
+ bool Alloc(UInt32 bufferSize)
+ {
+ if (Buffer != 0 && BufferSize == bufferSize)
+ return true;
+ Free();
+ Buffer = (Byte *)::MidAlloc(bufferSize);
+ Pos = 0;
+ BufferSize = bufferSize;
+ return (Buffer != 0);
+ }
+ UInt32 GetRndBit() { return RG.GetRnd(1); }
+ /*
+ UInt32 GetLogRand(int maxLen)
+ {
+ UInt32 len = GetRnd() % (maxLen + 1);
+ return GetRnd() & ((1 << len) - 1);
+ }
+ */
+ UInt32 GetLogRandBits(int numBits)
+ {
+ UInt32 len = RG.GetRnd(numBits);
+ return RG.GetRnd(len);
+ }
+ UInt32 GetOffset()
+ {
+ if (GetRndBit() == 0)
+ return GetLogRandBits(4);
+ return (GetLogRandBits(4) << 10) | RG.GetRnd(10);
+ }
+ UInt32 GetLen1() { return RG.GetRnd(1 + (int)RG.GetRnd(2)); }
+ UInt32 GetLen2() { return RG.GetRnd(2 + (int)RG.GetRnd(2)); }
+ void Generate()
+ {
+ RG.Init();
+ Rep0 = 1;
+ while(Pos < BufferSize)
+ {
+ if (GetRndBit() == 0 || Pos < 1)
+ Buffer[Pos++] = (Byte)RG.GetRnd(8);
+ else
+ {
+ UInt32 len;
+ if (RG.GetRnd(3) == 0)
+ len = 1 + GetLen1();
+ else
+ {
+ do
+ Rep0 = GetOffset();
+ while (Rep0 >= Pos);
+ Rep0++;
+ len = 2 + GetLen2();
+ }
+ for (UInt32 i = 0; i < len && Pos < BufferSize; i++, Pos++)
+ Buffer[Pos] = Buffer[Pos - Rep0];
+ }
+ }
+ }
+};
+
+class CBenchmarkInStream:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ const Byte *Data;
+ UInt32 Pos;
+ UInt32 Size;
+public:
+ MY_UNKNOWN_IMP
+ void Init(const Byte *data, UInt32 size)
+ {
+ Data = data;
+ Size = size;
+ Pos = 0;
+ }
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 remain = Size - Pos;
+ 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;
+}
+
+class CBenchmarkOutStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ UInt32 BufferSize;
+ FILE *_f;
+public:
+ UInt32 Pos;
+ Byte *Buffer;
+ CBenchmarkOutStream(): _f(0), Buffer(0) {}
+ virtual ~CBenchmarkOutStream() { delete []Buffer; }
+ void Init(FILE *f, UInt32 bufferSize)
+ {
+ delete []Buffer;
+ Buffer = 0;
+ Buffer = new Byte[bufferSize];
+ Pos = 0;
+ BufferSize = bufferSize;
+ _f = f;
+ }
+ MY_UNKNOWN_IMP
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 i;
+ for (i = 0; i < size && Pos < BufferSize; i++)
+ Buffer[Pos++] = ((const Byte *)data)[i];
+ if(processedSize != NULL)
+ *processedSize = i;
+ if (i != size)
+ {
+ fprintf(_f, "\nERROR: Buffer is full\n");
+ return E_FAIL;
+ }
+ return S_OK;
+}
+
+class CCrcOutStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ CCRC CRC;
+ MY_UNKNOWN_IMP
+ void Init() { CRC.Init(); }
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ CRC.Update(data, size);
+ if(processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
+
+static UInt64 GetTimeCount()
+{
+ #ifdef _WIN32
+ LARGE_INTEGER value;
+ if (::QueryPerformanceCounter(&value))
+ return value.QuadPart;
+ return GetTickCount();
+ #else
+ return clock();
+ #endif
+}
+
+static UInt64 GetFreq()
+{
+ #ifdef _WIN32
+ LARGE_INTEGER value;
+ if (::QueryPerformanceFrequency(&value))
+ return value.QuadPart;
+ return 1000;
+ #else
+ return CLOCKS_PER_SEC;
+ #endif
+}
+
+struct CProgressInfo:
+ public ICompressProgressInfo,
+ public CMyUnknownImp
+{
+ UInt64 ApprovedStart;
+ UInt64 InSize;
+ UInt64 Time;
+ void Init()
+ {
+ InSize = 0;
+ Time = 0;
+ }
+ MY_UNKNOWN_IMP
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+};
+
+STDMETHODIMP CProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)
+{
+ if (*inSize >= ApprovedStart && InSize == 0)
+ {
+ Time = ::GetTimeCount();
+ InSize = *inSize;
+ }
+ return S_OK;
+}
+
+static const int kSubBits = 8;
+
+static UInt32 GetLogSize(UInt32 size)
+{
+ for (int i = kSubBits; i < 32; i++)
+ for (UInt32 j = 0; j < (1 << kSubBits); j++)
+ if (size <= (((UInt32)1) << i) + (j << (i - kSubBits)))
+ return (i << kSubBits) + j;
+ return (32 << kSubBits);
+}
+
+static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime)
+{
+ UInt64 freq = GetFreq();
+ UInt64 elTime = elapsedTime;
+ while(freq > 1000000)
+ {
+ freq >>= 1;
+ elTime >>= 1;
+ }
+ if (elTime == 0)
+ elTime = 1;
+ return value * freq / elTime;
+}
+
+static UInt64 GetCompressRating(UInt32 dictionarySize, UInt64 elapsedTime, UInt64 size)
+{
+ UInt64 t = GetLogSize(dictionarySize) - (18 << kSubBits);
+ UInt64 numCommandsForOne = 1060 + ((t * t * 10) >> (2 * kSubBits));
+ UInt64 numCommands = (UInt64)(size) * numCommandsForOne;
+ return MyMultDiv64(numCommands, elapsedTime);
+}
+
+static UInt64 GetDecompressRating(UInt64 elapsedTime,
+ UInt64 outSize, UInt64 inSize)
+{
+ UInt64 numCommands = inSize * 220 + outSize * 20;
+ return MyMultDiv64(numCommands, elapsedTime);
+}
+
+/*
+static UInt64 GetTotalRating(
+ UInt32 dictionarySize,
+ bool isBT4,
+ UInt64 elapsedTimeEn, UInt64 sizeEn,
+ UInt64 elapsedTimeDe,
+ UInt64 inSizeDe, UInt64 outSizeDe)
+{
+ return (GetCompressRating(dictionarySize, isBT4, elapsedTimeEn, sizeEn) +
+ GetDecompressRating(elapsedTimeDe, inSizeDe, outSizeDe)) / 2;
+}
+*/
+
+static void PrintRating(FILE *f, UInt64 rating)
+{
+ fprintf(f, "%5d MIPS", (unsigned int)(rating / 1000000));
+}
+
+static void PrintResults(
+ FILE *f,
+ UInt32 dictionarySize,
+ UInt64 elapsedTime,
+ UInt64 size,
+ bool decompressMode, UInt64 secondSize)
+{
+ UInt64 speed = MyMultDiv64(size, elapsedTime);
+ fprintf(f, "%6d KB/s ", (unsigned int)(speed / 1024));
+ UInt64 rating;
+ if (decompressMode)
+ rating = GetDecompressRating(elapsedTime, size, secondSize);
+ else
+ rating = GetCompressRating(dictionarySize, elapsedTime, size);
+ PrintRating(f, rating);
+}
+
+static void ThrowError(FILE *f, HRESULT result, const char *s)
+{
+ fprintf(f, "\nError: ");
+ if (result == E_ABORT)
+ fprintf(f, "User break");
+ if (result == E_OUTOFMEMORY)
+ fprintf(f, "Can not allocate memory");
+ else
+ fprintf(f, s);
+ fprintf(f, "\n");
+}
+
+const wchar_t *bt2 = L"BT2";
+const wchar_t *bt4 = L"BT4";
+
+int LzmaBenchmark(FILE *f, UInt32 numIterations, UInt32 dictionarySize)
+{
+ if (numIterations == 0)
+ return 0;
+ if (dictionarySize < (1 << 18))
+ {
+ fprintf(f, "\nError: dictionary size for benchmark must be >= 19 (512 KB)\n");
+ return 1;
+ }
+ fprintf(f, "\n Compressing Decompressing\n\n");
+ NCompress::NLZMA::CEncoder *encoderSpec = new NCompress::NLZMA::CEncoder;
+ CMyComPtr<ICompressCoder> encoder = encoderSpec;
+
+ NCompress::NLZMA::CDecoder *decoderSpec = new NCompress::NLZMA::CDecoder;
+ CMyComPtr<ICompressCoder> decoder = decoderSpec;
+
+ CBenchmarkOutStream *propStreamSpec = new CBenchmarkOutStream;
+ CMyComPtr<ISequentialOutStream> propStream = propStreamSpec;
+ propStreamSpec->Init(f, kMaxLzmaPropSize);
+
+ PROPID propIDs[] =
+ {
+ NCoderPropID::kDictionarySize
+ };
+ const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);
+ PROPVARIANT properties[kNumProps];
+ properties[0].vt = VT_UI4;
+ properties[0].ulVal = UInt32(dictionarySize);
+
+ const UInt32 kBufferSize = dictionarySize + kAdditionalSize;
+ const UInt32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize;
+
+ if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK)
+ {
+ fprintf(f, "\nError: Incorrect command\n");
+ return 1;
+ }
+ encoderSpec->WriteCoderProperties(propStream);
+
+ CBenchRandomGenerator rg;
+ if (!rg.Alloc(kBufferSize))
+ {
+ fprintf(f, "\nError: Can't allocate memory\n");
+ return 1;
+ }
+
+ rg.Generate();
+ CCRC crc;
+ crc.Update(rg.Buffer, rg.BufferSize);
+
+ CProgressInfo *progressInfoSpec = new CProgressInfo;
+ CMyComPtr<ICompressProgressInfo> progressInfo = progressInfoSpec;
+
+ progressInfoSpec->ApprovedStart = dictionarySize;
+
+ UInt64 totalBenchSize = 0;
+ UInt64 totalEncodeTime = 0;
+ UInt64 totalDecodeTime = 0;
+ UInt64 totalCompressedSize = 0;
+
+ for (UInt32 i = 0; i < numIterations; i++)
+ {
+ progressInfoSpec->Init();
+ CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream;
+ inStreamSpec->Init(rg.Buffer, rg.BufferSize);
+ CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
+ CBenchmarkOutStream *outStreamSpec = new CBenchmarkOutStream;
+ outStreamSpec->Init(f, kCompressedBufferSize);
+ CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
+ HRESULT result = encoder->Code(inStream, outStream, 0, 0, progressInfo);
+ UInt64 encodeTime = ::GetTimeCount() - progressInfoSpec->Time;
+ UInt32 compressedSize = outStreamSpec->Pos;
+ if(result != S_OK)
+ {
+ ThrowError(f, result, "Encoder Error");
+ return 1;
+ }
+ if (progressInfoSpec->InSize == 0)
+ {
+ fprintf(f, "\nError: Internal ERROR 1282\n");
+ return 1;
+ }
+
+ ///////////////////////
+ // Decompressing
+
+ CCrcOutStream *crcOutStreamSpec = new CCrcOutStream;
+ CMyComPtr<ISequentialOutStream> crcOutStream = crcOutStreamSpec;
+
+ UInt64 decodeTime = 0;
+ for (int j = 0; j < 2; j++)
+ {
+ inStreamSpec->Init(outStreamSpec->Buffer, compressedSize);
+ crcOutStreamSpec->Init();
+
+ if (decoderSpec->SetDecoderProperties2(propStreamSpec->Buffer, propStreamSpec->Pos) != S_OK)
+ {
+ fprintf(f, "\nError: Set Decoder Properties Error\n");
+ return 1;
+ }
+ UInt64 outSize = kBufferSize;
+ UInt64 startTime = ::GetTimeCount();
+ result = decoder->Code(inStream, crcOutStream, 0, &outSize, 0);
+ decodeTime = ::GetTimeCount() - startTime;
+ if(result != S_OK)
+ {
+ ThrowError(f, result, "Decode Error");
+ return 1;
+ }
+ if (crcOutStreamSpec->CRC.GetDigest() != crc.GetDigest())
+ {
+ fprintf(f, "\nError: CRC Error\n");
+ return 1;
+ }
+ }
+ UInt64 benchSize = kBufferSize - progressInfoSpec->InSize;
+ PrintResults(f, dictionarySize, encodeTime, benchSize, false, 0);
+ fprintf(f, " ");
+ PrintResults(f, dictionarySize, decodeTime, kBufferSize, true, compressedSize);
+ fprintf(f, "\n");
+
+ totalBenchSize += benchSize;
+ totalEncodeTime += encodeTime;
+ totalDecodeTime += decodeTime;
+ totalCompressedSize += compressedSize;
+ }
+ fprintf(f, "---------------------------------------------------\n");
+ PrintResults(f, dictionarySize, totalEncodeTime, totalBenchSize, false, 0);
+ fprintf(f, " ");
+ PrintResults(f, dictionarySize, totalDecodeTime,
+ kBufferSize * numIterations, true, totalCompressedSize);
+ fprintf(f, " Average\n");
+ return 0;
+}
diff --git a/CPP/7zip/Compress/LZMA_Alone/LzmaBench.h b/CPP/7zip/Compress/LZMA_Alone/LzmaBench.h
new file mode 100755
index 00000000..a6a0e82e
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA_Alone/LzmaBench.h
@@ -0,0 +1,11 @@
+// LzmaBench.h
+
+#ifndef __LzmaBench_h
+#define __LzmaBench_h
+
+#include <stdio.h>
+#include "../../../Common/Types.h"
+
+int LzmaBenchmark(FILE *f, UInt32 numIterations, UInt32 dictionarySize);
+
+#endif
diff --git a/CPP/7zip/Compress/LZMA_Alone/LzmaRam.cpp b/CPP/7zip/Compress/LZMA_Alone/LzmaRam.cpp
new file mode 100755
index 00000000..31ca1c74
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA_Alone/LzmaRam.cpp
@@ -0,0 +1,227 @@
+// LzmaRam.cpp
+
+#include "StdAfx.h"
+#include "../../../Common/Types.h"
+#include "../LZMA/LZMADecoder.h"
+#include "../LZMA/LZMAEncoder.h"
+#include "LzmaRam.h"
+
+extern "C"
+{
+ #include "../../../../C/Compress/Branch/BranchX86.h"
+}
+
+class CInStreamRam:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ const Byte *Data;
+ size_t Size;
+ size_t Pos;
+public:
+ MY_UNKNOWN_IMP
+ void Init(const Byte *data, size_t size)
+ {
+ Data = data;
+ Size = size;
+ Pos = 0;
+ }
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP CInStreamRam::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (size > (Size - Pos))
+ size = (UInt32)(Size - Pos);
+ for (UInt32 i = 0; i < size; i++)
+ ((Byte *)data)[i] = Data[Pos + i];
+ Pos += size;
+ if(processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
+
+class COutStreamRam:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ size_t Size;
+public:
+ Byte *Data;
+ size_t Pos;
+ bool Overflow;
+ void Init(Byte *data, size_t size)
+ {
+ Data = data;
+ Size = size;
+ Pos = 0;
+ Overflow = false;
+ }
+ void SetPos(size_t pos)
+ {
+ Overflow = false;
+ Pos = pos;
+ }
+ MY_UNKNOWN_IMP
+ HRESULT WriteByte(Byte b)
+ {
+ if (Pos >= Size)
+ {
+ Overflow = true;
+ return E_FAIL;
+ }
+ Data[Pos++] = b;
+ return S_OK;
+ }
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP COutStreamRam::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 i;
+ for (i = 0; i < size && Pos < Size; i++)
+ Data[Pos++] = ((const Byte *)data)[i];
+ if(processedSize != NULL)
+ *processedSize = i;
+ if (i != size)
+ {
+ Overflow = true;
+ return E_FAIL;
+ }
+ return S_OK;
+}
+
+#define SZ_RAM_E_FAIL (1)
+#define SZ_RAM_E_OUTOFMEMORY (2)
+#define SZE_OUT_OVERFLOW (3)
+
+int LzmaRamEncode(
+ const Byte *inBuffer, size_t inSize,
+ Byte *outBuffer, size_t outSize, size_t *outSizeProcessed,
+ UInt32 dictionarySize, ESzFilterMode filterMode)
+{
+ #ifndef _NO_EXCEPTIONS
+ try {
+ #endif
+
+ *outSizeProcessed = 0;
+ const size_t kIdSize = 1;
+ const size_t kLzmaPropsSize = 5;
+ const size_t kMinDestSize = kIdSize + kLzmaPropsSize + 8;
+ if (outSize < kMinDestSize)
+ return SZE_OUT_OVERFLOW;
+ NCompress::NLZMA::CEncoder *encoderSpec = new NCompress::NLZMA::CEncoder;
+ CMyComPtr<ICompressCoder> encoder = encoderSpec;
+
+ PROPID propIDs[] =
+ {
+ NCoderPropID::kAlgorithm,
+ NCoderPropID::kDictionarySize,
+ NCoderPropID::kNumFastBytes,
+ };
+ const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);
+ PROPVARIANT properties[kNumProps];
+ properties[0].vt = VT_UI4;
+ properties[1].vt = VT_UI4;
+ properties[2].vt = VT_UI4;
+ properties[0].ulVal = (UInt32)2;
+ properties[1].ulVal = (UInt32)dictionarySize;
+ properties[2].ulVal = (UInt32)64;
+
+ if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK)
+ return 1;
+
+ COutStreamRam *outStreamSpec = new COutStreamRam;
+ if (outStreamSpec == 0)
+ return SZ_RAM_E_OUTOFMEMORY;
+ CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
+ CInStreamRam *inStreamSpec = new CInStreamRam;
+ if (inStreamSpec == 0)
+ return SZ_RAM_E_OUTOFMEMORY;
+ CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
+
+ outStreamSpec->Init(outBuffer, outSize);
+ if (outStreamSpec->WriteByte(0) != S_OK)
+ return SZE_OUT_OVERFLOW;
+
+ if (encoderSpec->WriteCoderProperties(outStream) != S_OK)
+ return SZE_OUT_OVERFLOW;
+ if (outStreamSpec->Pos != kIdSize + kLzmaPropsSize)
+ return 1;
+
+ int i;
+ for (i = 0; i < 8; i++)
+ {
+ UInt64 t = (UInt64)(inSize);
+ if (outStreamSpec->WriteByte((Byte)((t) >> (8 * i))) != S_OK)
+ return SZE_OUT_OVERFLOW;
+ }
+
+ Byte *filteredStream = 0;
+
+ bool useFilter = (filterMode != SZ_FILTER_NO);
+ if (useFilter)
+ {
+ if (inSize != 0)
+ {
+ filteredStream = (Byte *)MyAlloc(inSize);
+ if (filteredStream == 0)
+ return SZ_RAM_E_OUTOFMEMORY;
+ memmove(filteredStream, inBuffer, inSize);
+ }
+ UInt32 _prevMask;
+ UInt32 _prevPos;
+ x86_Convert_Init(_prevMask, _prevPos);
+ x86_Convert(filteredStream, (UInt32)inSize, 0, &_prevMask, &_prevPos, 1);
+ }
+
+ size_t minSize = 0;
+ int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1;
+ bool bestIsFiltered = false;
+ int mainResult = 0;
+ size_t startPos = outStreamSpec->Pos;
+ for (i = 0; i < numPasses; i++)
+ {
+ if (numPasses > 1 && i == numPasses - 1 && !bestIsFiltered)
+ break;
+ outStreamSpec->SetPos(startPos);
+ bool curModeIsFiltered = false;
+ if (useFilter && i == 0)
+ curModeIsFiltered = true;
+ if (numPasses > 1 && i == numPasses - 1)
+ curModeIsFiltered = true;
+
+ inStreamSpec->Init(curModeIsFiltered ? filteredStream : inBuffer, inSize);
+
+ HRESULT lzmaResult = encoder->Code(inStream, outStream, 0, 0, 0);
+
+ mainResult = 0;
+ if (lzmaResult == E_OUTOFMEMORY)
+ {
+ mainResult = SZ_RAM_E_OUTOFMEMORY;
+ break;
+ }
+ if (i == 0 || outStreamSpec->Pos <= minSize)
+ {
+ minSize = outStreamSpec->Pos;
+ bestIsFiltered = curModeIsFiltered;
+ }
+ if (outStreamSpec->Overflow)
+ mainResult = SZE_OUT_OVERFLOW;
+ else if (lzmaResult != S_OK)
+ {
+ mainResult = SZ_RAM_E_FAIL;
+ break;
+ }
+ }
+ *outSizeProcessed = outStreamSpec->Pos;
+ if (bestIsFiltered)
+ outBuffer[0] = 1;
+ if (useFilter)
+ MyFree(filteredStream);
+ return mainResult;
+
+ #ifndef _NO_EXCEPTIONS
+ } catch(...) { return SZ_RAM_E_OUTOFMEMORY; }
+ #endif
+}
diff --git a/CPP/7zip/Compress/LZMA_Alone/LzmaRam.h b/CPP/7zip/Compress/LZMA_Alone/LzmaRam.h
new file mode 100755
index 00000000..1244dc86
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA_Alone/LzmaRam.h
@@ -0,0 +1,46 @@
+// LzmaRam.h
+
+#ifndef __LzmaRam_h
+#define __LzmaRam_h
+
+#include <stdlib.h>
+#include "../../../Common/Types.h"
+
+/*
+LzmaRamEncode: BCJ + LZMA RAM->RAM compressing.
+It uses .lzma format, but it writes one additional byte to .lzma file:
+ 0: - no filter
+ 1: - x86(BCJ) filter.
+
+To provide best compression ratio dictionarySize mustbe >= inSize
+
+LzmaRamEncode allocates Data with MyAlloc/BigAlloc functions.
+RAM Requirements:
+ RamSize = dictionarySize * 9.5 + 6MB + FilterBlockSize
+ FilterBlockSize = 0, if useFilter == false
+ FilterBlockSize = inSize, if useFilter == true
+
+ Return code:
+ 0 - OK
+ 1 - Unspecified Error
+ 2 - Memory allocating error
+ 3 - Output buffer OVERFLOW
+
+If you use SZ_FILTER_AUTO mode, then encoder will use 2 or 3 passes:
+ 2 passes when FILTER_NO provides better compression.
+ 3 passes when FILTER_YES provides better compression.
+*/
+
+enum ESzFilterMode
+{
+ SZ_FILTER_NO,
+ SZ_FILTER_YES,
+ SZ_FILTER_AUTO
+};
+
+int LzmaRamEncode(
+ const Byte *inBuffer, size_t inSize,
+ Byte *outBuffer, size_t outSize, size_t *outSizeProcessed,
+ UInt32 dictionarySize, ESzFilterMode filterMode);
+
+#endif
diff --git a/CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.c b/CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.c
new file mode 100755
index 00000000..0767ba21
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.c
@@ -0,0 +1,79 @@
+/* LzmaRamDecode.c */
+
+#include "LzmaRamDecode.h"
+#ifdef _SZ_ONE_DIRECTORY
+#include "LzmaDecode.h"
+#include "BranchX86.h"
+#else
+#include "../../../../C/Compress/Lzma/LzmaDecode.h"
+#include "../../../../C/Compress/Branch/BranchX86.h"
+#endif
+
+#define LZMA_PROPS_SIZE 14
+#define LZMA_SIZE_OFFSET 6
+
+int LzmaRamGetUncompressedSize(
+ const unsigned char *inBuffer,
+ size_t inSize,
+ size_t *outSize)
+{
+ unsigned int i;
+ if (inSize < LZMA_PROPS_SIZE)
+ return 1;
+ *outSize = 0;
+ for(i = 0; i < sizeof(size_t); i++)
+ *outSize += ((size_t)inBuffer[LZMA_SIZE_OFFSET + i]) << (8 * i);
+ for(; i < 8; i++)
+ if (inBuffer[LZMA_SIZE_OFFSET + i] != 0)
+ return 1;
+ return 0;
+}
+
+#define SZE_DATA_ERROR (1)
+#define SZE_OUTOFMEMORY (2)
+
+int LzmaRamDecompress(
+ const unsigned char *inBuffer,
+ size_t inSize,
+ unsigned char *outBuffer,
+ size_t outSize,
+ size_t *outSizeProcessed,
+ void * (*allocFunc)(size_t size),
+ void (*freeFunc)(void *))
+{
+ CLzmaDecoderState state; /* it's about 24 bytes structure, if int is 32-bit */
+ int result;
+ SizeT outSizeProcessedLoc;
+ SizeT inProcessed;
+ int useFilter;
+
+ if (inSize < LZMA_PROPS_SIZE)
+ return 1;
+ useFilter = inBuffer[0];
+
+ *outSizeProcessed = 0;
+ if (useFilter > 1)
+ return 1;
+
+ if (LzmaDecodeProperties(&state.Properties, inBuffer + 1, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
+ return 1;
+ state.Probs = (CProb *)allocFunc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
+ if (state.Probs == 0)
+ return SZE_OUTOFMEMORY;
+
+ result = LzmaDecode(&state,
+ inBuffer + LZMA_PROPS_SIZE, (SizeT)inSize - LZMA_PROPS_SIZE, &inProcessed,
+ outBuffer, (SizeT)outSize, &outSizeProcessedLoc);
+ freeFunc(state.Probs);
+ if (result != LZMA_RESULT_OK)
+ return 1;
+ *outSizeProcessed = (size_t)outSizeProcessedLoc;
+ if (useFilter == 1)
+ {
+ UInt32 _prevMask;
+ UInt32 _prevPos;
+ x86_Convert_Init(_prevMask, _prevPos);
+ x86_Convert(outBuffer, (UInt32)outSizeProcessedLoc, 0, &_prevMask, &_prevPos, 0);
+ }
+ return 0;
+}
diff --git a/CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.h b/CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.h
new file mode 100755
index 00000000..7e641c55
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.h
@@ -0,0 +1,55 @@
+/* LzmaRamDecode.h */
+
+#ifndef __LzmaRamDecode_h
+#define __LzmaRamDecode_h
+
+#include <stdlib.h>
+
+/*
+LzmaRamGetUncompressedSize:
+ In:
+ inBuffer - input data
+ inSize - input data size
+ Out:
+ outSize - uncompressed size
+ Return code:
+ 0 - OK
+ 1 - Error in headers
+*/
+
+int LzmaRamGetUncompressedSize(
+ const unsigned char *inBuffer,
+ size_t inSize,
+ size_t *outSize);
+
+
+/*
+LzmaRamDecompress:
+ In:
+ inBuffer - input data
+ inSize - input data size
+ outBuffer - output data
+ outSize - output size
+ allocFunc - alloc function (can be malloc)
+ freeFunc - free function (can be free)
+ Out:
+ outSizeProcessed - processed size
+ Return code:
+ 0 - OK
+ 1 - Error in headers / data stream
+ 2 - Memory allocating error
+
+Memory requirements depend from properties of LZMA stream.
+With default lzma settings it's about 16 KB.
+*/
+
+int LzmaRamDecompress(
+ const unsigned char *inBuffer,
+ size_t inSize,
+ unsigned char *outBuffer,
+ size_t outSize,
+ size_t *outSizeProcessed,
+ void * (*allocFunc)(size_t size),
+ void (*freeFunc)(void *));
+
+#endif
diff --git a/CPP/7zip/Compress/LZMA_Alone/StdAfx.cpp b/CPP/7zip/Compress/LZMA_Alone/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA_Alone/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Compress/LZMA_Alone/StdAfx.h b/CPP/7zip/Compress/LZMA_Alone/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA_Alone/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Compress/LZMA_Alone/makefile b/CPP/7zip/Compress/LZMA_Alone/makefile
new file mode 100755
index 00000000..d3d80d88
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA_Alone/makefile
@@ -0,0 +1,124 @@
+PROG = lzma.exe
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib user32.lib
+
+!IFDEF CPU
+LIBS = $(LIBS) bufferoverflowU.lib
+CFLAGS = $(CFLAGS) -GS- -Zc:forScope -W4 -Wp64 -DUNICODE -D_UNICODE
+!ENDIF
+
+!IFNDEF O
+!IFDEF CPU
+O=$(CPU)
+!ELSE
+O=O
+!ENDIF
+!ENDIF
+
+!IFDEF MY_STATIC_LINK
+!IFNDEF MY_SINGLE_THREAD
+CFLAGS = $(CFLAGS) -MT
+!ENDIF
+!ELSE
+CFLAGS = $(CFLAGS) -MD
+!ENDIF
+
+
+CFLAGS = $(CFLAGS) -nologo -EHsc -c -Fo$O/ -WX
+CFLAGS_O1 = $(CFLAGS) -O1
+CFLAGS_O2 = $(CFLAGS) -O2
+
+LFLAGS = $(LFLAGS) -nologo -OPT:NOWIN98
+
+PROGPATH = $O\$(PROG)
+
+COMPL_O1 = $(CPP) $(CFLAGS_O1) $**
+COMPL_O2 = $(CPP) $(CFLAGS_O2) $**
+COMPL = $(CPP) $(CFLAGS_O1) $**
+
+
+LZMA_OBJS = \
+ $O\LzmaAlone.obj \
+ $O\LzmaBench.obj \
+ $O\LzmaRam.obj \
+
+LZMA_OPT_OBJS = \
+ $O\LZMADecoder.obj \
+ $O\LZMAEncoder.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\CRC.obj \
+ $O\CommandLineParser.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\Vector.obj
+
+7ZIP_COMMON_OBJS = \
+ $O\InBuffer.obj \
+ $O\OutBuffer.obj \
+ $O\StreamUtils.obj \
+
+LZ_OBJS = \
+ $O\LZOutWindow.obj \
+
+C_OBJS = \
+ $O\7zCrc.obj \
+
+C_LZ_OBJS = \
+ $O\MatchFinder.obj \
+
+OBJS = \
+ $(LZMA_OBJS) \
+ $(LZMA_OPT_OBJS) \
+ $(COMMON_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(LZ_OBJS) \
+ $(C_OBJS) \
+ $(C_LZ_OBJS) \
+ $O\LzmaRamDecode.obj \
+ $O\LzmaDecode.obj \
+ $O\FileStreams.obj \
+ $O\FileIO.obj \
+ $O\RangeCoderBit.obj \
+ $O\BranchX86.obj \
+
+all: $(PROGPATH)
+
+clean:
+ -del /Q $(PROGPATH) $O\*.exe $O\*.dll $O\*.obj $O\*.lib $O\*.exp $O\*.res $O\*.pch
+
+$O:
+ if not exist "$O" mkdir "$O"
+
+$(PROGPATH): $O $(OBJS)
+ link $(LFLAGS) -out:$(PROGPATH) $(OBJS) $(LIBS)
+
+
+$(LZMA_OBJS): $(*B).cpp
+ $(COMPL)
+$(LZMA_OPT_OBJS): ../LZMA/$(*B).cpp
+ $(COMPL_O2)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$(LZ_OBJS): ../LZ/$(*B).cpp
+ $(COMPL)
+$O\RangeCoderBit.obj: ../RangeCoder/$(*B).cpp
+ $(COMPL)
+$O\LzmaRamDecode.obj: LzmaRamDecode.c
+ $(COMPL_O1)
+$O\LzmaDecode.obj: ../../../../C/Compress/Lzma/LzmaDecode.c
+ $(COMPL_O2)
+$O\BranchX86.obj: ../../../../C/Compress/Branch/BranchX86.c
+ $(COMPL_O2)
+$O\FileStreams.obj: ../../Common/FileStreams.cpp
+ $(COMPL)
+$O\FileIO.obj: ../../../Windows/FileIO.cpp
+ $(COMPL)
+$(C_OBJS): ../../../../C/$(*B).c
+ $(COMPL_O2)
+$(C_LZ_OBJS): ../../../../C/Compress/Lz/$(*B).c
+ $(COMPL_O2)
diff --git a/CPP/7zip/Compress/LZMA_Alone/makefile.gcc b/CPP/7zip/Compress/LZMA_Alone/makefile.gcc
new file mode 100755
index 00000000..b83717a5
--- /dev/null
+++ b/CPP/7zip/Compress/LZMA_Alone/makefile.gcc
@@ -0,0 +1,117 @@
+PROG = lzma
+CXX = g++ -O2 -Wall
+CXX_C = gcc -O2 -Wall
+LIB = -lm
+RM = rm -f
+CFLAGS = -c -I ../../../
+
+OBJS = \
+ LzmaAlone.o \
+ LzmaBench.o \
+ LzmaRam.o \
+ LzmaRamDecode.o \
+ LzmaDecode.o \
+ BranchX86.o \
+ LZMADecoder.o \
+ LZMAEncoder.o \
+ 7zCrc.o \
+ MatchFinder.o \
+ LZOutWindow.o \
+ RangeCoderBit.o \
+ InBuffer.o \
+ OutBuffer.o \
+ FileStreams.o \
+ StreamUtils.o \
+ Alloc.o \
+ C_FileIO.o \
+ CommandLineParser.o \
+ CRC.o \
+ String.o \
+ StringConvert.o \
+ StringToInt.o \
+ Vector.o \
+
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB)
+
+LzmaAlone.o: LzmaAlone.cpp
+ $(CXX) $(CFLAGS) LzmaAlone.cpp
+
+LzmaBench.o: LzmaBench.cpp
+ $(CXX) $(CFLAGS) LzmaBench.cpp
+
+LzmaRam.o: LzmaRam.cpp
+ $(CXX) $(CFLAGS) LzmaRam.cpp
+
+LzmaRamDecode.o: LzmaRamDecode.c
+ $(CXX_C) $(CFLAGS) LzmaRamDecode.c
+
+LzmaDecode.o: ../../../../C/Compress/Lzma/LzmaDecode.c
+ $(CXX_C) $(CFLAGS) ../../../../C/Compress/Lzma/LzmaDecode.c
+
+BranchX86.o: ../../../../C/Compress/Branch/BranchX86.c
+ $(CXX_C) $(CFLAGS) ../../../../C/Compress/Branch/BranchX86.c
+
+LZMADecoder.o: ../LZMA/LZMADecoder.cpp
+ $(CXX) $(CFLAGS) ../LZMA/LZMADecoder.cpp
+
+LZMAEncoder.o: ../LZMA/LZMAEncoder.cpp
+ $(CXX) $(CFLAGS) ../LZMA/LZMAEncoder.cpp
+
+MatchFinder.o: ../../../../C/Compress/Lz/MatchFinder.c
+ $(CXX_C) $(CFLAGS) ../../../../C/Compress/Lz/MatchFinder.c
+
+7zCrc.o: ../../../../C/7zCrc.c
+ $(CXX_C) $(CFLAGS) ../../../../C/7zCrc.c
+
+LZOutWindow.o: ../LZ/LZOutWindow.cpp
+ $(CXX) $(CFLAGS) ../LZ/LZOutWindow.cpp
+
+RangeCoderBit.o: ../RangeCoder/RangeCoderBit.cpp
+ $(CXX) $(CFLAGS) ../RangeCoder/RangeCoderBit.cpp
+
+InBuffer.o: ../../Common/InBuffer.cpp
+ $(CXX) $(CFLAGS) ../../Common/InBuffer.cpp
+
+OutBuffer.o: ../../Common/OutBuffer.cpp
+ $(CXX) $(CFLAGS) ../../Common/OutBuffer.cpp
+
+FileStreams.o: ../../Common/FileStreams.cpp
+ $(CXX) $(CFLAGS) ../../Common/FileStreams.cpp
+
+StreamUtils.o: ../../Common/StreamUtils.cpp
+ $(CXX) $(CFLAGS) ../../Common/StreamUtils.cpp
+
+Alloc.o: ../../../Common/Alloc.cpp
+ $(CXX) $(CFLAGS) ../../../Common/Alloc.cpp
+
+C_FileIO.o: ../../../Common/C_FileIO.cpp
+ $(CXX) $(CFLAGS) ../../../Common/C_FileIO.cpp
+
+CommandLineParser.o: ../../../Common/CommandLineParser.cpp
+ $(CXX) $(CFLAGS) ../../../Common/CommandLineParser.cpp
+
+CRC.o: ../../../Common/CRC.cpp
+ $(CXX) $(CFLAGS) ../../../Common/CRC.cpp
+
+MyWindows.o: ../../../Common/MyWindows.cpp
+ $(CXX) $(CFLAGS) ../../../Common/MyWindows.cpp
+
+String.o: ../../../Common/String.cpp
+ $(CXX) $(CFLAGS) ../../../Common/String.cpp
+
+StringConvert.o: ../../../Common/StringConvert.cpp
+ $(CXX) $(CFLAGS) ../../../Common/StringConvert.cpp
+
+StringToInt.o: ../../../Common/StringToInt.cpp
+ $(CXX) $(CFLAGS) ../../../Common/StringToInt.cpp
+
+Vector.o: ../../../Common/Vector.cpp
+ $(CXX) $(CFLAGS) ../../../Common/Vector.cpp
+
+clean:
+ -$(RM) $(PROG) $(OBJS)
+
diff --git a/CPP/7zip/Compress/Lzh/LzhDecoder.cpp b/CPP/7zip/Compress/Lzh/LzhDecoder.cpp
new file mode 100755
index 00000000..5a661047
--- /dev/null
+++ b/CPP/7zip/Compress/Lzh/LzhDecoder.cpp
@@ -0,0 +1,216 @@
+// LzhDecoder.cpp
+
+#include "StdAfx.h"
+
+#include "LzhDecoder.h"
+
+#include "Windows/Defs.h"
+
+namespace NCompress{
+namespace NLzh {
+namespace NDecoder {
+
+static const UInt32 kHistorySize = (1 << 16);
+
+static const int kBlockSizeBits = 16;
+static const int kNumCBits = 9;
+static const int kNumLevelBits = 5; // smallest integer such that (1 << kNumLevelBits) > kNumLevelSymbols/
+
+UInt32 CCoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); }
+
+HRESULT CCoder::ReadLevelTable()
+{
+ int n = ReadBits(kNumLevelBits);
+ if (n == 0)
+ {
+ m_LevelHuffman.Symbol = ReadBits(kNumLevelBits);
+ if (m_LevelHuffman.Symbol >= kNumLevelSymbols)
+ return S_FALSE;
+ }
+ else
+ {
+ if (n > kNumLevelSymbols)
+ return S_FALSE;
+ m_LevelHuffman.Symbol = -1;
+ Byte lens[kNumLevelSymbols];
+ int i = 0;
+ while (i < n)
+ {
+ int c = m_InBitStream.ReadBits(3);
+ if (c == 7)
+ while (ReadBits(1))
+ if (c++ > kMaxHuffmanLen)
+ return S_FALSE;
+ lens[i++] = (Byte)c;
+ if (i == kNumSpecLevelSymbols)
+ {
+ c = ReadBits(2);
+ while (--c >= 0)
+ lens[i++] = 0;
+ }
+ }
+ while (i < kNumLevelSymbols)
+ lens[i++] = 0;
+ m_LevelHuffman.SetCodeLengths(lens);
+ }
+ return S_OK;
+}
+
+HRESULT CCoder::ReadPTable(int numBits)
+{
+ int n = ReadBits(numBits);
+ if (n == 0)
+ {
+ m_PHuffmanDecoder.Symbol = ReadBits(numBits);
+ if (m_PHuffmanDecoder.Symbol >= kNumDistanceSymbols)
+ return S_FALSE;
+ }
+ else
+ {
+ if (n > kNumDistanceSymbols)
+ return S_FALSE;
+ m_PHuffmanDecoder.Symbol = -1;
+ Byte lens[kNumDistanceSymbols];
+ int i = 0;
+ while (i < n)
+ {
+ int c = m_InBitStream.ReadBits(3);
+ if (c == 7)
+ while (ReadBits(1))
+ {
+ if (c > kMaxHuffmanLen)
+ return S_FALSE;
+ c++;
+ }
+ lens[i++] = (Byte)c;
+ }
+ while (i < kNumDistanceSymbols)
+ lens[i++] = 0;
+ m_PHuffmanDecoder.SetCodeLengths(lens);
+ }
+ return S_OK;
+}
+
+HRESULT CCoder::ReadCTable()
+{
+ int n = ReadBits(kNumCBits);
+ if (n == 0)
+ {
+ m_CHuffmanDecoder.Symbol = ReadBits(kNumCBits);
+ if (m_CHuffmanDecoder.Symbol >= kNumCSymbols)
+ return S_FALSE;
+ }
+ else
+ {
+ if (n > kNumCSymbols)
+ return S_FALSE;
+ m_CHuffmanDecoder.Symbol = -1;
+ Byte lens[kNumCSymbols];
+ int i = 0;
+ while (i < n)
+ {
+ int c = m_LevelHuffman.Decode(&m_InBitStream);
+ if (c < kNumSpecLevelSymbols)
+ {
+ if (c == 0)
+ c = 1;
+ else if (c == 1)
+ c = ReadBits(4) + 3;
+ else
+ c = ReadBits(kNumCBits) + 20;
+ while (--c >= 0)
+ {
+ if (i > kNumCSymbols)
+ return S_FALSE;
+ lens[i++] = 0;
+ }
+ }
+ else
+ lens[i++] = (Byte)(c - 2);
+ }
+ while (i < kNumCSymbols)
+ lens[i++] = 0;
+ m_CHuffmanDecoder.SetCodeLengths(lens);
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ if (outSize == NULL)
+ return E_INVALIDARG;
+
+ if (!m_OutWindowStream.Create(kHistorySize))
+ return E_OUTOFMEMORY;
+ if (!m_InBitStream.Create(1 << 20))
+ return E_OUTOFMEMORY;
+
+ UInt64 pos = 0;
+ m_OutWindowStream.SetStream(outStream);
+ m_OutWindowStream.Init(false);
+ m_InBitStream.SetStream(inStream);
+ m_InBitStream.Init();
+
+ CCoderReleaser coderReleaser(this);
+
+ int pbit;
+ if (m_NumDictBits <= 13)
+ pbit = 4;
+ else
+ pbit = 5;
+
+ UInt32 blockSize = 0;
+
+ while(pos < *outSize)
+ {
+ // for (i = 0; i < dictSize; i++) dtext[i] = 0x20;
+
+ if (blockSize == 0)
+ {
+ if (progress != NULL)
+ {
+ UInt64 packSize = m_InBitStream.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&packSize, &pos));
+ }
+ blockSize = ReadBits(kBlockSizeBits);
+ ReadLevelTable();
+ ReadCTable();
+ RINOK(ReadPTable(pbit));
+ }
+ blockSize--;
+ UInt32 c = m_CHuffmanDecoder.Decode(&m_InBitStream);
+ if (c < 256)
+ {
+ m_OutWindowStream.PutByte((Byte)c);
+ pos++;
+ }
+ else
+ {
+ // offset = (interface->method == LARC_METHOD_NUM) ? 0x100 - 2 : 0x100 - 3;
+ UInt32 len = c - 256 + kMinMatch;
+ UInt32 distance = m_PHuffmanDecoder.Decode(&m_InBitStream);
+ if (distance != 0)
+ distance = (1 << (distance - 1)) + ReadBits(distance - 1);
+ pos += len;
+ if (distance >= pos)
+ throw 1;
+ m_OutWindowStream.CopyBlock(distance, len);
+ }
+ }
+ coderReleaser.NeedFlush = false;
+ return m_OutWindowStream.Flush();
+}
+
+STDMETHODIMP CCoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ try { return CodeReal(inStream, outStream, inSize, outSize, progress);}
+ catch(const CInBufferException &e) { return e.ErrorCode; }
+ catch(const CLZOutWindowException &e) { return e.ErrorCode; }
+ catch(...) { return S_FALSE; }
+}
+
+}}}
diff --git a/CPP/7zip/Compress/Lzh/LzhDecoder.h b/CPP/7zip/Compress/Lzh/LzhDecoder.h
new file mode 100755
index 00000000..79f71b88
--- /dev/null
+++ b/CPP/7zip/Compress/Lzh/LzhDecoder.h
@@ -0,0 +1,103 @@
+// LzhDecoder.h
+
+#ifndef __COMPRESS_LZH_DECODER_H
+#define __COMPRESS_LZH_DECODER_H
+
+#include "../../../Common/MyCom.h"
+#include "../../ICoder.h"
+#include "../../Common/MSBFDecoder.h"
+#include "../../Common/InBuffer.h"
+#include "../Huffman/HuffmanDecoder.h"
+#include "../LZ/LZOutWindow.h"
+
+namespace NCompress {
+namespace NLzh {
+namespace NDecoder {
+
+const int kMaxHuffmanLen = 16; // Check it
+
+const int kNumSpecLevelSymbols = 3;
+const int kNumLevelSymbols = kNumSpecLevelSymbols + kMaxHuffmanLen;
+
+const int kDictBitsMax = 16;
+const int kNumDistanceSymbols = kDictBitsMax + 1;
+
+const int kMaxMatch = 256;
+const int kMinMatch = 3;
+const int kNumCSymbols = 256 + kMaxMatch + 2 - kMinMatch;
+
+template <UInt32 m_NumSymbols>
+class CHuffmanDecoder:public NCompress::NHuffman::CDecoder<kMaxHuffmanLen, m_NumSymbols>
+{
+public:
+ int Symbol;
+ template <class TBitDecoder>
+ UInt32 Decode(TBitDecoder *bitStream)
+ {
+ if (Symbol >= 0)
+ return (UInt32)Symbol;
+ return DecodeSymbol(bitStream);
+ }
+};
+
+class CCoder :
+ public ICompressCoder,
+ public CMyUnknownImp
+{
+ CLZOutWindow m_OutWindowStream;
+ NStream::NMSBF::CDecoder<CInBuffer> m_InBitStream;
+
+ int m_NumDictBits;
+
+ CHuffmanDecoder<kNumLevelSymbols> m_LevelHuffman;
+ CHuffmanDecoder<kNumDistanceSymbols> m_PHuffmanDecoder;
+ CHuffmanDecoder<kNumCSymbols> m_CHuffmanDecoder;
+
+ void ReleaseStreams()
+ {
+ m_OutWindowStream.ReleaseStream();
+ m_InBitStream.ReleaseStream();
+ }
+
+ class CCoderReleaser
+ {
+ CCoder *m_Coder;
+ public:
+ bool NeedFlush;
+ CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {}
+ ~CCoderReleaser()
+ {
+ if (NeedFlush)
+ m_Coder->m_OutWindowStream.Flush();
+ m_Coder->ReleaseStreams();
+ }
+ };
+ friend class CCoderReleaser;
+
+ void MakeTable(int nchar, Byte *bitlen, int tablebits,
+ UInt32 *table, int tablesize);
+
+ UInt32 ReadBits(int numBits);
+ HRESULT ReadLevelTable();
+ HRESULT ReadPTable(int numBits);
+ HRESULT ReadCTable();
+
+public:
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(CodeReal)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ void SetDictionary(int numDictBits) { m_NumDictBits = numDictBits; }
+ CCoder(): m_NumDictBits(0) {}
+};
+
+}}}
+
+#endif
diff --git a/CPP/7zip/Compress/Lzx/Lzx.h b/CPP/7zip/Compress/Lzx/Lzx.h
new file mode 100755
index 00000000..386a17c3
--- /dev/null
+++ b/CPP/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/CPP/7zip/Compress/Lzx/Lzx86Converter.cpp b/CPP/7zip/Compress/Lzx/Lzx86Converter.cpp
new file mode 100755
index 00000000..1265dba0
--- /dev/null
+++ b/CPP/7zip/Compress/Lzx/Lzx86Converter.cpp
@@ -0,0 +1,90 @@
+// Lzx86Converter.cpp
+
+#include "StdAfx.h"
+
+#include "Common/Defs.h"
+
+#include "Lzx86Converter.h"
+
+namespace NCompress {
+namespace NLzx {
+
+static const int kResidue = 6 + 4;
+
+void Cx86ConvertOutStream::MakeTranslation()
+{
+ if (m_Pos <= kResidue)
+ return;
+ UInt32 numBytes = m_Pos - kResidue;
+ Byte *buffer = m_Buffer;
+ for (UInt32 i = 0; i < numBytes;)
+ {
+ if (buffer[i++] == 0xE8)
+ {
+ Int32 absValue = 0;
+ int j;
+ for(j = 0; j < 4; j++)
+ absValue += (UInt32)buffer[i + j] << (j * 8);
+ Int32 pos = (Int32)(m_ProcessedSize + i - 1);
+ if (absValue >= -pos && absValue < (Int32)m_TranslationSize)
+ {
+ UInt32 offset = (absValue >= 0) ?
+ absValue - pos :
+ absValue + m_TranslationSize;
+ for(j = 0; j < 4; j++)
+ {
+ buffer[i + j] = (Byte)(offset & 0xFF);
+ offset >>= 8;
+ }
+ }
+ i += 4;
+ }
+ }
+}
+
+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);
+ memmove(m_Buffer + m_Pos, (const Byte *)data + realProcessedSize, writeSize);
+ m_Pos += writeSize;
+ realProcessedSize += writeSize;
+ if (m_Pos == kUncompressedBlockSize)
+ {
+ RINOK(Flush());
+ }
+ }
+ if (processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return S_OK;
+}
+
+HRESULT Cx86ConvertOutStream::Flush()
+{
+ if (m_Pos == 0)
+ return S_OK;
+ 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_TranslationMode && (m_ProcessedSize < (1 << 30)));
+ return S_OK;
+}
+
+}}
diff --git a/CPP/7zip/Compress/Lzx/Lzx86Converter.h b/CPP/7zip/Compress/Lzx/Lzx86Converter.h
new file mode 100755
index 00000000..b507a612
--- /dev/null
+++ b/CPP/7zip/Compress/Lzx/Lzx86Converter.h
@@ -0,0 +1,45 @@
+// Lzx/x86Converter.h
+
+#ifndef __LZX_X86CONVERTER_H
+#define __LZX_X86CONVERTER_H
+
+#include "Common/MyCom.h"
+#include "../../IStream.h"
+
+namespace NCompress {
+namespace NLzx {
+
+const int kUncompressedBlockSize = 1 << 15;
+
+class Cx86ConvertOutStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ CMyComPtr<ISequentialOutStream> m_Stream;
+ UInt32 m_ProcessedSize;
+ UInt32 m_Pos;
+ UInt32 m_TranslationSize;
+ bool m_TranslationMode;
+ Byte m_Buffer[kUncompressedBlockSize];
+
+ void MakeTranslation();
+public:
+ void SetStream(ISequentialOutStream *outStream) { m_Stream = outStream; }
+ void ReleaseStream() { m_Stream.Release(); }
+ void Init(bool translationMode, UInt32 translationSize)
+ {
+ m_TranslationMode = translationMode;
+ m_TranslationSize = translationSize;
+ m_ProcessedSize = 0;
+ m_Pos = 0;
+ }
+ HRESULT Flush();
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Compress/Lzx/LzxDecoder.cpp b/CPP/7zip/Compress/Lzx/LzxDecoder.cpp
new file mode 100755
index 00000000..e854af32
--- /dev/null
+++ b/CPP/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);
+
+ m_IsUncompressedBlock = (blockType == kBlockTypeUncompressed);
+ if (m_IsUncompressedBlock)
+ {
+ 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;
+ }
+ m_AlignIsUsed = (blockType == kBlockTypeAligned);
+ if (m_AlignIsUsed)
+ {
+ for(int i = 0; i < kAlignTableSize; i++)
+ newLevels[i] = (Byte)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 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;
+
+ RINOK(SetInStream(inStream));
+ m_x86ConvertOutStreamSpec->SetStream(outStream);
+ m_OutWindowStream.SetStream(m_x86ConvertOutStream);
+ RINOK(SetOutStreamSize(outSize));
+
+ CDecoderFlusher flusher(this);
+
+ const UInt64 start = m_OutWindowStream.GetProcessedSize();
+ for (;;)
+ {
+ 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/CPP/7zip/Compress/Lzx/LzxDecoder.h b/CPP/7zip/Compress/Lzx/LzxDecoder.h
new file mode 100755
index 00000000..a62662ec
--- /dev/null
+++ b/CPP/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/CPP/7zip/Compress/Lzx/StdAfx.h b/CPP/7zip/Compress/Lzx/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/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/CPP/7zip/Compress/PPMD/DllExports.cpp b/CPP/7zip/Compress/PPMD/DllExports.cpp
new file mode 100755
index 00000000..8159a2f8
--- /dev/null
+++ b/CPP/7zip/Compress/PPMD/DllExports.cpp
@@ -0,0 +1,93 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#ifdef _WIN32
+#include "Common/Alloc.h"
+#endif
+
+#include "PPMDEncoder.h"
+#include "PPMDDecoder.h"
+
+// {23170F69-40C1-278B-0304-010000000000}
+DEFINE_GUID(CLSID_CCompressPPMDDecoder,
+0x23170F69, 0x40C1, 0x278B, 0x03, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+// {23170F69-40C1-278B-0304-010000000100}
+DEFINE_GUID(CLSID_CCompressPPMDEncoder,
+0x23170F69, 0x40C1, 0x278B, 0x03, 0x04, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00);
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ #ifdef _WIN32
+ if (dwReason == DLL_PROCESS_ATTACH)
+ SetLargePageSize();
+ #endif
+ 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_CCompressPPMDDecoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder = (ICompressCoder *)new NCompress::NPPMD::CDecoder();
+ }
+ else if (*clsid == CLSID_CCompressPPMDEncoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder = (ICompressCoder *)new NCompress::NPPMD::CEncoder();
+ }
+ else
+ return CLASS_E_CLASSNOTAVAILABLE;
+ *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[] = { 0x03, 0x04, 0x01 };
+ if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NMethodPropID::kName:
+ if ((value->bstrVal = ::SysAllocString(L"PPMD")) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ case NMethodPropID::kDecoder:
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CCompressPPMDDecoder, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ case NMethodPropID::kEncoder:
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CCompressPPMDEncoder, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ return S_OK;
+}
diff --git a/CPP/7zip/Compress/PPMD/PPMD.dsp b/CPP/7zip/Compress/PPMD/PPMD.dsp
new file mode 100755
index 00000000..9e512f6c
--- /dev/null
+++ b/CPP/7zip/Compress/PPMD/PPMD.dsp
@@ -0,0 +1,229 @@
+# Microsoft Developer Studio Project File - Name="PPMD" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=PPMD - 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 "PPMD.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 "PPMD.mak" CFG="PPMD - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "PPMD - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "PPMD - 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)" == "PPMD - 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 "PPMD_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PPMD_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\Codecs\PPMd.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "PPMD - 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 "PPMD_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 "PPMD_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\Codecs\PPMd.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "PPMD - Win32 Release"
+# Name "PPMD - 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
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "PPMD"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\PPMDContext.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\PPMDDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\PPMDDecoder.cpp
+
+!IF "$(CFG)" == "PPMD - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "PPMD - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\PPMDDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\PPMDEncode.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\PPMDEncoder.cpp
+
+!IF "$(CFG)" == "PPMD - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "PPMD - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\PPMDEncoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\PPMDSubAlloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\PPMDType.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\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 "RangeCoder"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoder.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\Types.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/CPP/7zip/Compress/PPMD/PPMD.dsw b/CPP/7zip/Compress/PPMD/PPMD.dsw
new file mode 100755
index 00000000..8032f3db
--- /dev/null
+++ b/CPP/7zip/Compress/PPMD/PPMD.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "PPMD"=.\PPMD.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Compress/PPMD/PPMDContext.h b/CPP/7zip/Compress/PPMD/PPMDContext.h
new file mode 100755
index 00000000..a6a8dd60
--- /dev/null
+++ b/CPP/7zip/Compress/PPMD/PPMDContext.h
@@ -0,0 +1,489 @@
+// Compress/PPMD/Context.h
+// This code is based on Dmitry Shkarin's PPMdH code
+
+#ifndef __COMPRESS_PPMD_CONTEXT_H
+#define __COMPRESS_PPMD_CONTEXT_H
+
+#include "../../../Common/Types.h"
+
+#include "../RangeCoder/RangeCoder.h"
+#include "PPMDSubAlloc.h"
+
+namespace NCompress {
+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;
+
+struct SEE2_CONTEXT
+{
+ // SEE-contexts for PPM-contexts with masked symbols
+ UInt16 Summ;
+ Byte Shift, Count;
+ void init(int InitVal) { Summ = (UInt16)(InitVal << (Shift=PERIOD_BITS-4)); Count=4; }
+ unsigned int getMean()
+ {
+ unsigned int RetVal=(Summ >> Shift);
+ Summ = (UInt16)(Summ - RetVal);
+ return RetVal+(RetVal == 0);
+ }
+ void update()
+ {
+ if (Shift < PERIOD_BITS && --Count == 0)
+ {
+ Summ <<= 1;
+ Count = (Byte)(3 << Shift++);
+ }
+ }
+};
+
+struct PPM_CONTEXT
+{
+ 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)
+ {
+ PPM_CONTEXT* pc = (PPM_CONTEXT*) subAllocator.AllocContext();
+ if (pc)
+ {
+ pc->NumStats = 1;
+ pc->oneState() = FirstState;
+ pc->Suffix = subAllocator.GetOffset(this);
+ pStats->SetSuccessor(subAllocator.GetOffsetNoCheck(pc));
+ }
+ return pc;
+ }
+
+ STATE& oneState() const { return (STATE&) SummFreq; }
+};
+
+/////////////////////////////////
+
+const UInt16 InitBinEsc[] =
+ {0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051};
+
+struct CInfo
+{
+ CSubAllocator SubAllocator;
+ 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;
+ Byte CharMask[256], NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
+ Byte EscCount, PrintCount, PrevSuccess, HiBitsFlag;
+ UInt16 BinSumm[128][64]; // binary SEE-contexts
+
+ UInt16 &GetBinSumm(const PPM_CONTEXT::STATE &rs, int numStates)
+ {
+ HiBitsFlag = HB2Flag[FoundState->Symbol];
+ return BinSumm[rs.Freq - 1][
+ PrevSuccess + NS2BSIndx[numStates - 1] +
+ HiBitsFlag + 2 * HB2Flag[rs.Symbol] +
+ ((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;
+ memset(CharMask,0,sizeof(CharMask));
+ SubAllocator.InitSubAllocator();
+ InitRL = -((MaxOrder < 12) ? MaxOrder : 12) - 1;
+ MinContext = MaxContext = (PPM_CONTEXT*) SubAllocator.AllocContext();
+ MinContext->Suffix = 0;
+ OrderFall = MaxOrder;
+ MinContext->SummFreq = (UInt16)((MinContext->NumStats = 256) + 1);
+ FoundState = (PPM_CONTEXT::STATE*)SubAllocator.AllocUnits(256 / 2);
+ MinContext->Stats = SubAllocator.GetOffsetNoCheck(FoundState);
+ PrevSuccess = 0;
+ for (RunLength = InitRL, i = 0; i < 256; i++)
+ {
+ PPM_CONTEXT::STATE &state = FoundState[i];
+ state.Symbol = (Byte)i;
+ state.Freq = 1;
+ state.SetSuccessor(0);
+ }
+ for (i = 0; i < 128; i++)
+ for (k = 0; k < 8; k++)
+ for ( m=0; m < 64; m += 8)
+ BinSumm[i][k + m] = (UInt16)(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 StartModelRare(int MaxOrder)
+ {
+ int i, k, m ,Step;
+ EscCount=PrintCount=1;
+ if (MaxOrder < 2)
+ {
+ memset(CharMask,0,sizeof(CharMask));
+ OrderFall = this->MaxOrder;
+ MinContext = MaxContext;
+ while (MinContext->Suffix != 0)
+ {
+ MinContext = GetContextNoCheck(MinContext->Suffix);
+ OrderFall--;
+ }
+ FoundState = GetState(MinContext->Stats);
+ MinContext = MaxContext;
+ }
+ else
+ {
+ this->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] = (Byte)i;
+ for (m = i, k = Step = 1; i < 256; i++)
+ {
+ NS2Indx[i] = (Byte)m;
+ if ( !--k )
+ {
+ k = ++Step;
+ m++;
+ }
+ }
+ memset(HB2Flag, 0, 0x40);
+ memset(HB2Flag + 0x40, 0x08, 0x100 - 0x40);
+ DummySEE2Cont.Shift = PERIOD_BITS;
+ }
+ }
+
+ PPM_CONTEXT* CreateSuccessors(bool skip, PPM_CONTEXT::STATE* p1)
+ {
+ // static UpState declaration bypasses IntelC bug
+ // static PPM_CONTEXT::STATE UpState;
+ PPM_CONTEXT::STATE UpState;
+
+ PPM_CONTEXT *pc = MinContext;
+ PPM_CONTEXT *UpBranch = GetContext(FoundState->GetSuccessor());
+ PPM_CONTEXT::STATE * p, * ps[MAX_O], ** pps = ps;
+ if ( !skip )
+ {
+ *pps++ = FoundState;
+ if ( !pc->Suffix )
+ goto NO_LOOP;
+ }
+ if ( p1 )
+ {
+ p = p1;
+ pc = GetContext(pc->Suffix);
+ goto LOOP_ENTRY;
+ }
+ do
+ {
+ pc = GetContext(pc->Suffix);
+ if (pc->NumStats != 1)
+ {
+ if ((p = GetStateNoCheck(pc->Stats))->Symbol != FoundState->Symbol)
+ do { p++; } while (p->Symbol != FoundState->Symbol);
+ }
+ else
+ p = &(pc->oneState());
+LOOP_ENTRY:
+ if (GetContext(p->GetSuccessor()) != UpBranch)
+ {
+ pc = GetContext(p->GetSuccessor());
+ break;
+ }
+ *pps++ = p;
+ }
+ while ( pc->Suffix );
+NO_LOOP:
+ if (pps == ps)
+ return pc;
+ UpState.Symbol = *(Byte*) UpBranch;
+ UpState.SetSuccessor(SubAllocator.GetOffset(UpBranch) + 1);
+ if (pc->NumStats != 1)
+ {
+ 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;
+ UpState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) :
+ ((2 * cf + 3 * s0 - 1) / (2 * s0))));
+ }
+ else
+ UpState.Freq = pc->oneState().Freq;
+ do
+ {
+ pc = pc->createChild(SubAllocator, *--pps, UpState);
+ if ( !pc )
+ return NULL;
+ }
+ while (pps != ps);
+ return pc;
+ }
+
+ void UpdateModel()
+ {
+ PPM_CONTEXT::STATE fs = *FoundState, * p = NULL;
+ PPM_CONTEXT* pc, * Successor;
+ unsigned int ns1, ns, cf, sf, s0;
+ if (fs.Freq < MAX_FREQ / 4 && MinContext->Suffix != 0)
+ {
+ pc = GetContextNoCheck(MinContext->Suffix);
+
+ if (pc->NumStats != 1)
+ {
+ if ((p = GetStateNoCheck(pc->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->SummFreq += 2;
+ }
+ }
+ else
+ {
+ p = &(pc->oneState());
+ p->Freq = (Byte)(p->Freq + ((p->Freq < 32) ? 1 : 0));
+ }
+ }
+ if ( !OrderFall )
+ {
+ MinContext = MaxContext = CreateSuccessors(true, p);
+ FoundState->SetSuccessor(SubAllocator.GetOffset(MinContext));
+ if (MinContext == 0)
+ goto RESTART_MODEL;
+ return;
+ }
+ *SubAllocator.pText++ = fs.Symbol;
+ Successor = (PPM_CONTEXT*) SubAllocator.pText;
+ if (SubAllocator.pText >= SubAllocator.UnitsStart)
+ goto RESTART_MODEL;
+ if (fs.GetSuccessor() != 0)
+ {
+ 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 = GetContext(fs.GetSuccessor());
+ SubAllocator.pText -= (MaxContext != MinContext);
+ }
+ }
+ else
+ {
+ 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 = GetContext(pc->Suffix))
+ {
+ if ((ns1 = pc->NumStats) != 1)
+ {
+ if ((ns1 & 1) == 0)
+ {
+ void *ppp = SubAllocator.ExpandUnits(GetState(pc->Stats), ns1 >> 1);
+ pc->Stats = SubAllocator.GetOffset(ppp);
+ if (!ppp)
+ goto RESTART_MODEL;
+ }
+ pc->SummFreq = (UInt16)(pc->SummFreq + (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) &
+ (pc->SummFreq <= 8 * ns1)));
+ }
+ else
+ {
+ p = (PPM_CONTEXT::STATE*) SubAllocator.AllocUnits(1);
+ if ( !p )
+ goto RESTART_MODEL;
+ *p = pc->oneState();
+ pc->Stats = SubAllocator.GetOffsetNoCheck(p);
+ if (p->Freq < MAX_FREQ / 4 - 1)
+ p->Freq <<= 1;
+ else
+ p->Freq = MAX_FREQ - 4;
+ pc->SummFreq = (UInt16)(p->Freq + InitEsc + (ns > 3));
+ }
+ cf = 2 * fs.Freq * (pc->SummFreq+6);
+ sf = s0 + pc->SummFreq;
+ if (cf < 6 * sf)
+ {
+ cf = 1 + (cf > sf)+(cf >= 4 * sf);
+ pc->SummFreq += 3;
+ }
+ else
+ {
+ cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf);
+ pc->SummFreq = (UInt16)(pc->SummFreq + cf);
+ }
+ p = GetState(pc->Stats) + ns1;
+ p->SetSuccessor(SubAllocator.GetOffset(Successor));
+ p->Symbol = fs.Symbol;
+ p->Freq = (Byte)cf;
+ pc->NumStats = (UInt16)++ns1;
+ }
+ MaxContext = MinContext = GetContext(fs.GetSuccessor());
+ return;
+RESTART_MODEL:
+ RestartModelRare();
+ EscCount = 0;
+ PrintCount = 0xFF;
+ }
+
+ void ClearMask()
+ {
+ EscCount = 1;
+ memset(CharMask, 0, sizeof(CharMask));
+ // if (++PrintCount == 0)
+ // PrintInfo(DecodedFile,EncodedFile);
+ }
+
+ void update1(PPM_CONTEXT::STATE* p)
+ {
+ (FoundState = p)->Freq += 4;
+ MinContext->SummFreq += 4;
+ if (p[0].Freq > p[-1].Freq)
+ {
+ _PPMD_SWAP(p[0],p[-1]);
+ FoundState = --p;
+ if (p->Freq > MAX_FREQ)
+ rescale();
+ }
+ }
+
+
+ void update2(PPM_CONTEXT::STATE* p)
+ {
+ (FoundState = p)->Freq += 4;
+ MinContext->SummFreq += 4;
+ if (p->Freq > MAX_FREQ)
+ rescale();
+ EscCount++;
+ RunLength = InitRL;
+ }
+
+ SEE2_CONTEXT* makeEscFreq2(int Diff, UInt32 &scale)
+ {
+ SEE2_CONTEXT* psee2c;
+ if (MinContext->NumStats != 256)
+ {
+ 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
+ {
+ psee2c = &DummySEE2Cont;
+ scale = 1;
+ }
+ return psee2c;
+ }
+
+
+
+ void rescale()
+ {
+ int OldNS = MinContext->NumStats, i = MinContext->NumStats - 1, Adder, EscFreq;
+ PPM_CONTEXT::STATE* p1, * p;
+ PPM_CONTEXT::STATE *stats = GetStateNoCheck(MinContext->Stats);
+ for (p = FoundState; p != stats; p--)
+ _PPMD_SWAP(p[0], p[-1]);
+ stats->Freq += 4;
+ MinContext->SummFreq += 4;
+ EscFreq = MinContext->SummFreq - p->Freq;
+ Adder = (OrderFall != 0);
+ p->Freq = (Byte)((p->Freq + Adder) >> 1);
+ MinContext->SummFreq = p->Freq;
+ do
+ {
+ EscFreq -= (++p)->Freq;
+ p->Freq = (Byte)((p->Freq + Adder) >> 1);
+ MinContext->SummFreq = (UInt16)(MinContext->SummFreq + p->Freq);
+ if (p[0].Freq > p[-1].Freq)
+ {
+ PPM_CONTEXT::STATE tmp = *(p1 = p);
+ do
+ {
+ p1[0] = p1[-1];
+ }
+ while (--p1 != stats && tmp.Freq > p1[-1].Freq);
+ *p1 = tmp;
+ }
+ }
+ while ( --i );
+ if (p->Freq == 0)
+ {
+ do { i++; } while ((--p)->Freq == 0);
+ EscFreq += i;
+ MinContext->NumStats = (UInt16)(MinContext->NumStats - i);
+ if (MinContext->NumStats == 1)
+ {
+ PPM_CONTEXT::STATE tmp = *stats;
+ do { tmp.Freq = (Byte)(tmp.Freq - (tmp.Freq >> 1)); EscFreq >>= 1; } while (EscFreq > 1);
+ SubAllocator.FreeUnits(stats, (OldNS+1) >> 1);
+ *(FoundState = &MinContext->oneState()) = tmp; return;
+ }
+ }
+ EscFreq -= (EscFreq >> 1);
+ MinContext->SummFreq = (UInt16)(MinContext->SummFreq + EscFreq);
+ int n0 = (OldNS+1) >> 1, n1 = (MinContext->NumStats + 1) >> 1;
+ if (n0 != n1)
+ MinContext->Stats = SubAllocator.GetOffset(SubAllocator.ShrinkUnits(stats, n0, n1));
+ FoundState = GetState(MinContext->Stats);
+ }
+
+ void NextContext()
+ {
+ PPM_CONTEXT *c = GetContext(FoundState->GetSuccessor());
+ if (!OrderFall && (Byte *)c > SubAllocator.pText)
+ MinContext = MaxContext = c;
+ else
+ {
+ UpdateModel();
+ if (EscCount == 0)
+ ClearMask();
+ }
+ }
+};
+
+// Tabulated escapes for exponential symbol distribution
+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))
+
+}}
+
+#endif
diff --git a/CPP/7zip/Compress/PPMD/PPMDDecode.h b/CPP/7zip/Compress/PPMD/PPMDDecode.h
new file mode 100755
index 00000000..b05d8ee0
--- /dev/null
+++ b/CPP/7zip/Compress/PPMD/PPMDDecode.h
@@ -0,0 +1,154 @@
+// PPMDDecode.h
+// This code is based on Dmitry Shkarin's PPMdH code
+
+#ifndef __COMPRESS_PPMD_DECODE_H
+#define __COMPRESS_PPMD_DECODE_H
+
+#include "PPMDContext.h"
+
+namespace NCompress {
+namespace NPPMD {
+
+class CRangeDecoderVirt
+{
+public:
+ virtual UInt32 GetThreshold(UInt32 total) = 0;
+ virtual void Decode(UInt32 start, UInt32 size) = 0;
+ virtual UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) = 0;
+};
+
+typedef NRangeCoder::CDecoder CRangeDecoderMy;
+
+class CRangeDecoder:public CRangeDecoderVirt, public CRangeDecoderMy
+{
+ UInt32 GetThreshold(UInt32 total) { return CRangeDecoderMy::GetThreshold(total); }
+ void Decode(UInt32 start, UInt32 size) { CRangeDecoderMy::Decode(start, size); }
+ UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) { return CRangeDecoderMy::DecodeBit(size0, numTotalBits); }
+};
+
+struct CDecodeInfo: public CInfo
+{
+ void DecodeBinSymbol(CRangeDecoderVirt *rangeDecoder)
+ {
+ PPM_CONTEXT::STATE& rs = MinContext->oneState();
+ UInt16& bs = GetBinSumm(rs, GetContextNoCheck(MinContext->Suffix)->NumStats);
+ if (rangeDecoder->DecodeBit(bs, TOT_BITS) == 0)
+ {
+ FoundState = &rs;
+ rs.Freq = (Byte)(rs.Freq + (rs.Freq < 128 ? 1: 0));
+ bs = (UInt16)(bs + INTERVAL - GET_MEAN(bs, PERIOD_BITS, 2));
+ PrevSuccess = 1;
+ RunLength++;
+ }
+ else
+ {
+ bs = (UInt16)(bs - GET_MEAN(bs, PERIOD_BITS, 2));
+ InitEsc = ExpEscape[bs >> 10];
+ NumMasked = 1;
+ CharMask[rs.Symbol] = EscCount;
+ PrevSuccess = 0;
+ FoundState = NULL;
+ }
+ }
+
+ void DecodeSymbol1(CRangeDecoderVirt *rangeDecoder)
+ {
+ 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, p->Freq); // MinContext->SummFreq);
+ (FoundState = p)->Freq = (Byte)(hiCnt += 4);
+ MinContext->SummFreq += 4;
+ if (hiCnt > MAX_FREQ)
+ rescale();
+ return;
+ }
+ PrevSuccess = 0;
+ i = MinContext->NumStats - 1;
+ while ((hiCnt += (++p)->Freq) <= count)
+ if (--i == 0)
+ {
+ HiBitsFlag = HB2Flag[FoundState->Symbol];
+ rangeDecoder->Decode(hiCnt, MinContext->SummFreq - hiCnt); // , MinContext->SummFreq);
+ CharMask[p->Symbol] = EscCount;
+ i = (NumMasked = MinContext->NumStats)-1;
+ FoundState = NULL;
+ do { CharMask[(--p)->Symbol] = EscCount; } while ( --i );
+ return;
+ }
+ rangeDecoder->Decode(hiCnt - p->Freq, p->Freq); // , MinContext->SummFreq);
+ update1(p);
+ }
+
+
+ void DecodeSymbol2(CRangeDecoderVirt *rangeDecoder)
+ {
+ int count, hiCnt, i = MinContext->NumStats - NumMasked;
+ UInt32 freqSum;
+ SEE2_CONTEXT* psee2c = makeEscFreq2(i, freqSum);
+ PPM_CONTEXT::STATE* ps[256], ** pps = ps, * p = GetStateNoCheck(MinContext->Stats)-1;
+ hiCnt = 0;
+ do
+ {
+ do { p++; } while (CharMask[p->Symbol] == EscCount);
+ hiCnt += p->Freq;
+ *pps++ = p;
+ }
+ while ( --i );
+
+ freqSum += hiCnt;
+ count = rangeDecoder->GetThreshold(freqSum);
+
+ p = *(pps = ps);
+ if (count < hiCnt)
+ {
+ hiCnt = 0;
+ while ((hiCnt += p->Freq) <= count)
+ p=*++pps;
+ rangeDecoder->Decode(hiCnt - p->Freq, p->Freq); // , freqSum);
+
+ psee2c->update();
+ update2(p);
+ }
+ else
+ {
+ rangeDecoder->Decode(hiCnt, freqSum - hiCnt); // , freqSum);
+
+ i = MinContext->NumStats - NumMasked;
+ pps--;
+ do { CharMask[(*++pps)->Symbol] = EscCount; } while ( --i );
+ psee2c->Summ = (UInt16)(psee2c->Summ + freqSum);
+ NumMasked = MinContext->NumStats;
+ }
+ }
+
+ int DecodeSymbol(CRangeDecoderVirt *rangeDecoder)
+ {
+ if (MinContext->NumStats != 1)
+ DecodeSymbol1(rangeDecoder);
+ else
+ DecodeBinSymbol(rangeDecoder);
+ while ( !FoundState )
+ {
+ do
+ {
+ OrderFall++;
+ MinContext = GetContext(MinContext->Suffix);
+ if (MinContext == 0)
+ return -1;
+ }
+ while (MinContext->NumStats == NumMasked);
+ DecodeSymbol2(rangeDecoder);
+ }
+ Byte symbol = FoundState->Symbol;
+ NextContext();
+ return symbol;
+ }
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Compress/PPMD/PPMDDecoder.cpp b/CPP/7zip/Compress/PPMD/PPMDDecoder.cpp
new file mode 100755
index 00000000..2d0a2f52
--- /dev/null
+++ b/CPP/7zip/Compress/PPMD/PPMDDecoder.cpp
@@ -0,0 +1,184 @@
+// PPMDDecoder.cpp
+
+#include "StdAfx.h"
+
+#include "Common/Defs.h"
+#include "Windows/Defs.h"
+
+#include "PPMDDecoder.h"
+
+namespace NCompress {
+namespace NPPMD {
+
+const int kLenIdFinished = -1;
+const int kLenIdNeedInit = -2;
+
+STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *properties, UInt32 size)
+{
+ if (size < 5)
+ return E_INVALIDARG;
+ _order = properties[0];
+ _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;
+}
+
+class CDecoderFlusher
+{
+ CDecoder *_coder;
+public:
+ bool NeedFlush;
+ CDecoderFlusher(CDecoder *coder): _coder(coder), NeedFlush(true) {}
+ ~CDecoderFlusher()
+ {
+ if (NeedFlush)
+ _coder->Flush();
+ _coder->ReleaseStreams();
+ }
+};
+
+HRESULT CDecoder::CodeSpec(UInt32 size, Byte *memStream)
+{
+ if (_outSizeDefined)
+ {
+ const UInt64 rem = _outSize - _processedSize;
+ if (size > rem)
+ size = (UInt32)rem;
+ }
+ const UInt32 startSize = size;
+
+ 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++ = (Byte)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 (!_outStream.Create(1 << 20))
+ return E_OUTOFMEMORY;
+
+ SetInStream(inStream);
+ _outStream.SetStream(outStream);
+ SetOutStreamSize(outSize);
+ CDecoderFlusher flusher(this);
+
+ for (;;)
+ {
+ _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, &_processedSize));
+ }
+ if (_outSizeDefined)
+ if (_outStream.GetProcessedSize() >= _outSize)
+ break;
+ }
+ 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)
+{
+ 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)
+{
+ _outSizeDefined = (outSize != NULL);
+ if (_outSizeDefined)
+ _outSize = *outSize;
+ _processedSize = 0;
+ _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/CPP/7zip/Compress/PPMD/PPMDDecoder.h b/CPP/7zip/Compress/PPMD/PPMDDecoder.h
new file mode 100755
index 00000000..8e30c35c
--- /dev/null
+++ b/CPP/7zip/Compress/PPMD/PPMDDecoder.h
@@ -0,0 +1,89 @@
+// Compress/PPM/PPMDDecoder.h
+
+#ifndef __COMPRESS_PPMD_DECODER_H
+#define __COMPRESS_PPMD_DECODER_H
+
+#include "../../../Common/MyCom.h"
+
+#include "../../ICoder.h"
+#include "../../Common/OutBuffer.h"
+#include "../RangeCoder/RangeCoder.h"
+
+#include "PPMDDecode.h"
+
+namespace NCompress {
+namespace NPPMD {
+
+class CDecoder :
+ public ICompressCoder,
+ public ICompressSetDecoderProperties2,
+ #ifdef _ST_MODE
+ public ICompressSetInStream,
+ public ICompressSetOutStreamSize,
+ public ISequentialInStream,
+ #endif
+ public CMyUnknownImp
+{
+ CRangeDecoder _rangeDecoder;
+
+ COutBuffer _outStream;
+
+ CDecodeInfo _info;
+
+ Byte _order;
+ UInt32 _usedMemorySize;
+
+ int _remainLen;
+ UInt64 _outSize;
+ bool _outSizeDefined;
+ UInt64 _processedSize;
+
+ HRESULT CodeSpec(UInt32 num, Byte *memStream);
+public:
+
+ #ifdef _ST_MODE
+ MY_UNKNOWN_IMP4(
+ ICompressSetDecoderProperties2,
+ ICompressSetInStream,
+ ICompressSetOutStreamSize,
+ ISequentialInStream)
+ #else
+ MY_UNKNOWN_IMP1(
+ ICompressSetDecoderProperties2)
+ #endif
+
+ void ReleaseStreams()
+ {
+ ReleaseInStream();
+ _outStream.ReleaseStream();
+ }
+
+ HRESULT Flush() { return _outStream.Flush(); }
+
+ 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);
+
+ 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) {}
+
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Compress/PPMD/PPMDEncode.h b/CPP/7zip/Compress/PPMD/PPMDEncode.h
new file mode 100755
index 00000000..6a720cac
--- /dev/null
+++ b/CPP/7zip/Compress/PPMD/PPMDEncode.h
@@ -0,0 +1,142 @@
+// PPMDEncode.h
+// This code is based on Dmitry Shkarin's PPMdH code
+
+#ifndef __COMPRESS_PPMD_ENCODE_H
+#define __COMPRESS_PPMD_ENCODE_H
+
+#include "PPMDContext.h"
+
+namespace NCompress {
+namespace NPPMD {
+
+struct CEncodeInfo: public CInfo
+{
+
+ void EncodeBinSymbol(int symbol, NRangeCoder::CEncoder *rangeEncoder)
+ {
+ PPM_CONTEXT::STATE& rs = MinContext->oneState();
+ UInt16 &bs = GetBinSumm(rs, GetContextNoCheck(MinContext->Suffix)->NumStats);
+ if (rs.Symbol == symbol)
+ {
+ FoundState = &rs;
+ rs.Freq = (Byte)(rs.Freq + (rs.Freq < 128 ? 1: 0));
+ rangeEncoder->EncodeBit(bs, TOT_BITS, 0);
+ bs = (UInt16)(bs + INTERVAL - GET_MEAN(bs, PERIOD_BITS, 2));
+ PrevSuccess = 1;
+ RunLength++;
+ }
+ else
+ {
+ rangeEncoder->EncodeBit(bs, TOT_BITS, 1);
+ bs = (UInt16)(bs - GET_MEAN(bs, PERIOD_BITS, 2));
+ InitEsc = ExpEscape[bs >> 10];
+ NumMasked = 1;
+ CharMask[rs.Symbol] = EscCount;
+ PrevSuccess = 0;
+ FoundState = NULL;
+ }
+ }
+
+ void EncodeSymbol1(int symbol, NRangeCoder::CEncoder *rangeEncoder)
+ {
+ PPM_CONTEXT::STATE* p = GetStateNoCheck(MinContext->Stats);
+ if (p->Symbol == symbol)
+ {
+ PrevSuccess = (2 * (p->Freq) > MinContext->SummFreq);
+ RunLength += PrevSuccess;
+ rangeEncoder->Encode(0, p->Freq, MinContext->SummFreq);
+ (FoundState = p)->Freq += 4;
+ MinContext->SummFreq += 4;
+ if (p->Freq > MAX_FREQ)
+ rescale();
+ return;
+ }
+ PrevSuccess = 0;
+ int LoCnt = p->Freq, i = MinContext->NumStats - 1;
+ while ((++p)->Symbol != symbol)
+ {
+ LoCnt += p->Freq;
+ if (--i == 0)
+ {
+ HiBitsFlag = HB2Flag[FoundState->Symbol];
+ CharMask[p->Symbol] = EscCount;
+ i=(NumMasked = MinContext->NumStats)-1;
+ FoundState = NULL;
+ do { CharMask[(--p)->Symbol] = EscCount; } while ( --i );
+ rangeEncoder->Encode(LoCnt, MinContext->SummFreq - LoCnt, MinContext->SummFreq);
+ return;
+ }
+ }
+ rangeEncoder->Encode(LoCnt, p->Freq, MinContext->SummFreq);
+ update1(p);
+ }
+
+ void EncodeSymbol2(int symbol, NRangeCoder::CEncoder *rangeEncoder)
+ {
+ int hiCnt, i = MinContext->NumStats - NumMasked;
+ UInt32 scale;
+ SEE2_CONTEXT* psee2c = makeEscFreq2(i, scale);
+ PPM_CONTEXT::STATE* p = GetStateNoCheck(MinContext->Stats) - 1;
+ hiCnt = 0;
+ do
+ {
+ do { p++; } while (CharMask[p->Symbol] == EscCount);
+ hiCnt += p->Freq;
+ if (p->Symbol == symbol)
+ goto SYMBOL_FOUND;
+ CharMask[p->Symbol] = EscCount;
+ }
+ while ( --i );
+
+ rangeEncoder->Encode(hiCnt, scale, hiCnt + scale);
+ scale += hiCnt;
+
+ psee2c->Summ = (UInt16)(psee2c->Summ + scale);
+ NumMasked = MinContext->NumStats;
+ return;
+SYMBOL_FOUND:
+
+ UInt32 highCount = hiCnt;
+ UInt32 lowCount = highCount - p->Freq;
+ if ( --i )
+ {
+ PPM_CONTEXT::STATE* p1 = p;
+ do
+ {
+ do { p1++; } while (CharMask[p1->Symbol] == EscCount);
+ hiCnt += p1->Freq;
+ }
+ while ( --i );
+ }
+ // SubRange.scale += hiCnt;
+ scale += hiCnt;
+ rangeEncoder->Encode(lowCount, highCount - lowCount, scale);
+ psee2c->update();
+ update2(p);
+ }
+
+ void EncodeSymbol(int c, NRangeCoder::CEncoder *rangeEncoder)
+ {
+ if (MinContext->NumStats != 1)
+ EncodeSymbol1(c, rangeEncoder);
+ else
+ EncodeBinSymbol(c, rangeEncoder);
+ while ( !FoundState )
+ {
+ do
+ {
+ OrderFall++;
+ MinContext = GetContext(MinContext->Suffix);
+ if (MinContext == 0)
+ return; // S_OK;
+ }
+ while (MinContext->NumStats == NumMasked);
+ EncodeSymbol2(c, rangeEncoder);
+ }
+ NextContext();
+ }
+
+};
+}}
+
+#endif
diff --git a/CPP/7zip/Compress/PPMD/PPMDEncoder.cpp b/CPP/7zip/Compress/PPMD/PPMDEncoder.cpp
new file mode 100755
index 00000000..fe99ea5a
--- /dev/null
+++ b/CPP/7zip/Compress/PPMD/PPMDEncoder.cpp
@@ -0,0 +1,155 @@
+// Compress/Associative/Encoder.h
+
+#include "StdAfx.h"
+
+#include "Windows/Defs.h"
+
+// #include <fstream.h>
+// #include <iomanip.h>
+
+#include "Common/Defs.h"
+
+#include "../../Common/StreamUtils.h"
+
+#include "PPMDEncoder.h"
+
+namespace NCompress {
+namespace NPPMD {
+
+const UInt32 kMinMemSize = (1 << 11);
+const UInt32 kMinOrder = 2;
+
+/*
+UInt32 g_NumInner = 0;
+UInt32 g_InnerCycles = 0;
+
+UInt32 g_Encode2 = 0;
+UInt32 g_Encode2Cycles = 0;
+UInt32 g_Encode2Cycles2 = 0;
+
+class CCounter
+{
+public:
+ CCounter() {}
+ ~CCounter()
+ {
+ ofstream ofs("Res.dat");
+ ofs << "innerEncode1 = " << setw(10) << g_NumInner << endl;
+ ofs << "g_InnerCycles = " << setw(10) << g_InnerCycles << endl;
+ ofs << "g_Encode2 = " << setw(10) << g_Encode2 << endl;
+ ofs << "g_Encode2Cycles = " << setw(10) << g_Encode2Cycles << endl;
+ ofs << "g_Encode2Cycles2= " << setw(10) << g_Encode2Cycles2 << endl;
+
+ }
+};
+CCounter g_Counter;
+*/
+
+STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties)
+{
+ for (UInt32 i = 0; i < numProperties; i++)
+ {
+ const PROPVARIANT &prop = properties[i];
+ switch(propIDs[i])
+ {
+ case NCoderPropID::kUsedMemorySize:
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ if (prop.ulVal < kMinMemSize || prop.ulVal > kMaxMemBlockSize)
+ return E_INVALIDARG;
+ _usedMemorySize = (UInt32)prop.ulVal;
+ break;
+ case NCoderPropID::kOrder:
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ if (prop.ulVal < kMinOrder || prop.ulVal > kMaxOrderCompress)
+ return E_INVALIDARG;
+ _order = (Byte)prop.ulVal;
+ break;
+ default:
+ return E_INVALIDARG;
+ }
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{
+ const UInt32 kPropSize = 5;
+ Byte properties[kPropSize];
+ properties[0] = _order;
+ for (int i = 0; i < 4; i++)
+ properties[1 + i] = Byte(_usedMemorySize >> (8 * i));
+ return WriteStream(outStream, properties, kPropSize, NULL);
+}
+
+const UInt32 kUsedMemorySizeDefault = (1 << 24);
+const int kOrderDefault = 6;
+
+CEncoder::CEncoder():
+ _usedMemorySize(kUsedMemorySizeDefault),
+ _order(kOrderDefault)
+{
+}
+
+
+HRESULT CEncoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 * /* inSize */, const UInt64 * /* outSize */,
+ ICompressProgressInfo *progress)
+{
+ if (!_inStream.Create(1 << 20))
+ 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);
+
+ _info.MaxOrder = 0;
+ _info.StartModelRare(_order);
+
+ for (;;)
+ {
+ UInt32 size = (1 << 18);
+ do
+ {
+ 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);
+ }
+ while (--size != 0);
+ if (progress != NULL)
+ {
+ UInt64 inSize = _inStream.GetProcessedSize();
+ UInt64 outSize = _rangeEncoder.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&inSize, &outSize));
+ }
+ }
+}
+
+STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
+ catch(const COutBufferException &e) { return e.ErrorCode; }
+ catch(const CInBufferException &e) { return e.ErrorCode; }
+ catch(...) { return E_FAIL; }
+}
+
+}}
diff --git a/CPP/7zip/Compress/PPMD/PPMDEncoder.h b/CPP/7zip/Compress/PPMD/PPMDEncoder.h
new file mode 100755
index 00000000..915180b9
--- /dev/null
+++ b/CPP/7zip/Compress/PPMD/PPMDEncoder.h
@@ -0,0 +1,81 @@
+// Compress/PPMD/Encoder.h
+
+#ifndef __COMPRESS_PPMD_ENCODER_H
+#define __COMPRESS_PPMD_ENCODER_H
+
+#include "../../../Common/MyCom.h"
+
+#include "../../ICoder.h"
+#include "../../Common/InBuffer.h"
+#include "../RangeCoder/RangeCoder.h"
+
+#include "PPMDEncode.h"
+
+namespace NCompress {
+namespace NPPMD {
+
+class CEncoder :
+ public ICompressCoder,
+ public ICompressSetCoderProperties,
+ public ICompressWriteCoderProperties,
+ public CMyUnknownImp
+{
+public:
+ CInBuffer _inStream;
+
+ NRangeCoder::CEncoder _rangeEncoder;
+
+ CEncodeInfo _info;
+ UInt32 _usedMemorySize;
+ Byte _order;
+
+ HRESULT Flush()
+ {
+ _rangeEncoder.FlushData();
+ return _rangeEncoder.FlushStream();
+ }
+
+ void ReleaseStreams()
+ {
+ _inStream.ReleaseStream();
+ _rangeEncoder.ReleaseStream();
+ }
+
+ 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);
+
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties);
+
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+
+ CEncoder();
+
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Compress/PPMD/PPMDSubAlloc.h b/CPP/7zip/Compress/PPMD/PPMDSubAlloc.h
new file mode 100755
index 00000000..dce765d6
--- /dev/null
+++ b/CPP/7zip/Compress/PPMD/PPMDSubAlloc.h
@@ -0,0 +1,292 @@
+// PPMDSubAlloc.h
+// This code is based on Dmitry Shkarin's PPMdH code
+
+#ifndef __PPMD_SUBALLOC_H
+#define __PPMD_SUBALLOC_H
+
+#include "PPMDType.h"
+
+#include "../../../Common/Alloc.h"
+
+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;
+
+// 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;
+ UInt32 Next, Prev;
+ void InsertAt(Byte *Base, UInt32 p)
+ {
+ Prev = p;
+ MEM_BLK *pp = (MEM_BLK *)(Base + p);
+ Next = pp->Next;
+ pp->Next = ((MEM_BLK *)(Base + Next))->Prev = (UInt32)((Byte *)this - Base);
+ }
+ void Remove(Byte *Base)
+ {
+ ((MEM_BLK *)(Base + Prev))->Next = Next;
+ ((MEM_BLK *)(Base + Next))->Prev = Prev;
+ }
+};
+
+
+class CSubAllocator
+{
+ UInt32 SubAllocatorSize;
+ Byte Indx2Units[N_INDEXES], Units2Indx[128], GlueCount;
+ UInt32 FreeList[N_INDEXES];
+
+ Byte *Base;
+ Byte *HeapStart, *LoUnit, *HiUnit;
+public:
+ Byte *pText, *UnitsStart;
+ CSubAllocator():
+ SubAllocatorSize(0),
+ GlueCount(0),
+ LoUnit(0),
+ HiUnit(0),
+ pText(0),
+ UnitsStart(0)
+ {
+ memset(Indx2Units, 0, sizeof(Indx2Units));
+ memset(FreeList, 0, sizeof(FreeList));
+ }
+ ~CSubAllocator()
+ {
+ 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)
+ {
+ *(UInt32 *)p = FreeList[indx];
+ FreeList[indx] = GetOffsetNoCheck(p);
+ }
+
+ void* RemoveNode(int indx)
+ {
+ UInt32 offset = FreeList[indx];
+ UInt32 *p = GetNode(offset);
+ FreeList[indx] = *p;
+ return (void *)p;
+ }
+
+ UINT U2B(int NU) const { return (UINT)(NU) * UNIT_SIZE; }
+
+ void 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]);
+ }
+
+ UInt32 GetUsedMemory() const
+ {
+ 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);
+ }
+
+ UInt32 GetSubAllocatorSize() const { return SubAllocatorSize; }
+
+ void StopSubAllocator()
+ {
+ if (SubAllocatorSize != 0)
+ {
+ BigFree(Base);
+ SubAllocatorSize = 0;
+ Base = 0;
+ }
+ }
+
+ bool StartSubAllocator(UInt32 size)
+ {
+ if (SubAllocatorSize == size)
+ return true;
+ StopSubAllocator();
+ if (size == 0)
+ Base = 0;
+ else
+ {
+ if ((Base = (Byte *)::BigAlloc(size + kExtraSize)) == 0)
+ return false;
+ HeapStart = Base + UNIT_SIZE; // we need such code to support NULL;
+ }
+ SubAllocatorSize = size;
+ return true;
+ }
+
+ void InitSubAllocator()
+ {
+ int i, k;
+ memset(FreeList, 0, sizeof(FreeList));
+ HiUnit = (pText = HeapStart) + SubAllocatorSize;
+ UINT Diff = UNIT_SIZE * (SubAllocatorSize / 8 / UNIT_SIZE * 7);
+ LoUnit = UnitsStart = HiUnit - Diff;
+ for (i = 0, k=1; i < N1 ; i++, k += 1) Indx2Units[i] = (Byte)k;
+ for (k++; i < N1 + N2 ;i++, k += 2) Indx2Units[i] = (Byte)k;
+ for (k++; i < N1 + N2 + N3 ;i++,k += 3) Indx2Units[i] = (Byte)k;
+ for (k++; i < N1 + N2 + N3 + N4; i++, k += 4) Indx2Units[i] = (Byte)k;
+ GlueCount = 0;
+ for (k = i = 0; k < 128; k++)
+ {
+ i += (Indx2Units[i] < k+1);
+ Units2Indx[k] = (Byte)i;
+ }
+ }
+
+ void GlueFreeBlocks()
+ {
+ 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;
+ ps0->Next = ps0->Prev = s0;
+
+ for (i = 0; i < N_INDEXES; i++)
+ while (FreeList[i] != 0)
+ {
+ MEM_BLK *pp = (MEM_BLK *)RemoveNode(i);
+ pp->InsertAt(Base, s0);
+ pp->Stamp = 0xFFFF;
+ pp->NU = Indx2Units[i];
+ }
+ for (p = ps0->Next; p != s0; p = GetBlk(p)->Next)
+ {
+ for (;;)
+ {
+ 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 = (UInt16)(pp->NU + pp1->NU);
+ }
+ }
+ while ((p = ps0->Next) != s0)
+ {
+ 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)
+ {
+ int k = sz - Indx2Units[--i];
+ InsertNode(Base + p + (sz - k) * UNIT_SIZE, k - 1);
+ }
+ InsertNode(Base + p, i);
+ }
+ }
+ void* AllocUnitsRare(int indx)
+ {
+ if ( !GlueCount )
+ {
+ GlueCount = 255;
+ GlueFreeBlocks();
+ if (FreeList[indx] != 0)
+ return RemoveNode(indx);
+ }
+ int i = indx;
+ do
+ {
+ if (++i == N_INDEXES)
+ {
+ GlueCount--;
+ i = U2B(Indx2Units[indx]);
+ return (UnitsStart - pText > i) ? (UnitsStart -= i) : (NULL);
+ }
+ } while (FreeList[i] == 0);
+ void* RetVal = RemoveNode(i);
+ SplitBlock(RetVal, i, indx);
+ return RetVal;
+ }
+
+ void* AllocUnits(int NU)
+ {
+ int indx = Units2Indx[NU - 1];
+ if (FreeList[indx] != 0)
+ return RemoveNode(indx);
+ void* RetVal = LoUnit;
+ LoUnit += U2B(Indx2Units[indx]);
+ if (LoUnit <= HiUnit)
+ return RetVal;
+ LoUnit -= U2B(Indx2Units[indx]);
+ return AllocUnitsRare(indx);
+ }
+
+ void* AllocContext()
+ {
+ if (HiUnit != LoUnit)
+ return (HiUnit -= UNIT_SIZE);
+ if (FreeList[0] != 0)
+ return RemoveNode(0);
+ return AllocUnitsRare(0);
+ }
+
+ void* 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* ShrinkUnits(void* oldPtr, int oldNU, int newNU)
+ {
+ int i0 = Units2Indx[oldNU - 1], i1 = Units2Indx[newNU - 1];
+ if (i0 == i1)
+ return oldPtr;
+ if (FreeList[i1] != 0)
+ {
+ void* ptr = RemoveNode(i1);
+ memcpy(ptr, oldPtr, U2B(newNU));
+ InsertNode(oldPtr,i0);
+ return ptr;
+ }
+ else
+ {
+ SplitBlock(oldPtr, i0, i1);
+ return oldPtr;
+ }
+ }
+
+ void FreeUnits(void* ptr, int oldNU)
+ {
+ InsertNode(ptr, Units2Indx[oldNU - 1]);
+ }
+};
+
+#endif
diff --git a/CPP/7zip/Compress/PPMD/PPMDType.h b/CPP/7zip/Compress/PPMD/PPMDType.h
new file mode 100755
index 00000000..5200fa54
--- /dev/null
+++ b/CPP/7zip/Compress/PPMD/PPMDType.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ * This file is part of PPMd project *
+ * Written and distributed to public domain by Dmitry Shkarin 1997, *
+ * 1999-2001 *
+ * Contents: compilation parameters and miscelaneous definitions *
+ * Comments: system & compiler dependent file
+
+ * modified by Igor Pavlov (2004-08-29).
+ ****************************************************************************/
+#ifndef __PPMD_TYPE_H
+#define __PPMD_TYPE_H
+
+const int kMaxOrderCompress = 32;
+const int MAX_O = 255; /* maximum allowed model order */
+
+template <class T>
+inline void _PPMD_SWAP(T& t1,T& t2) { T tmp = t1; t1 = t2; t2 = tmp; }
+
+#endif
diff --git a/CPP/7zip/Compress/PPMD/StdAfx.cpp b/CPP/7zip/Compress/PPMD/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Compress/PPMD/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Compress/PPMD/StdAfx.h b/CPP/7zip/Compress/PPMD/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Compress/PPMD/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Compress/PPMD/makefile b/CPP/7zip/Compress/PPMD/makefile
new file mode 100755
index 00000000..2e687a70
--- /dev/null
+++ b/CPP/7zip/Compress/PPMD/makefile
@@ -0,0 +1,41 @@
+PROG = PPMd.dll
+DEF_FILE = ../Codec.def
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib
+
+PPMD_OBJS = \
+ $O\DllExports.obj \
+
+PPMD_OPT_OBJS = \
+ $O\PPMDDecoder.obj \
+ $O\PPMDEncoder.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\InBuffer.obj \
+ $O\OutBuffer.obj \
+ $O\StreamUtils.obj \
+
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(PPMD_OBJS) \
+ $(PPMD_OPT_OBJS) \
+ $(COMMON_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $O\resource.res
+
+
+!include "../../../Build.mak"
+
+$(PPMD_OBJS): $(*B).cpp
+ $(COMPL)
+$(PPMD_OPT_OBJS): $(*B).cpp
+ $(COMPL_O2)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+
diff --git a/CPP/7zip/Compress/PPMD/resource.rc b/CPP/7zip/Compress/PPMD/resource.rc
new file mode 100755
index 00000000..fed98e19
--- /dev/null
+++ b/CPP/7zip/Compress/PPMD/resource.rc
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("PPMd Codec", "PPMd")
diff --git a/CPP/7zip/Compress/Quantum/QuantumDecoder.cpp b/CPP/7zip/Compress/Quantum/QuantumDecoder.cpp
new file mode 100755
index 00000000..5cf863bb
--- /dev/null
+++ b/CPP/7zip/Compress/Quantum/QuantumDecoder.cpp
@@ -0,0 +1,173 @@
+// 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;
+
+ SetInStream(inStream);
+ _outWindowStream.SetStream(outStream);
+ SetOutStreamSize(outSize);
+ CDecoderFlusher flusher(this);
+
+ const UInt64 start = _outWindowStream.GetProcessedSize();
+ for (;;)
+ {
+ 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/CPP/7zip/Compress/Quantum/QuantumDecoder.h b/CPP/7zip/Compress/Quantum/QuantumDecoder.h
new file mode 100755
index 00000000..8b5aaaba
--- /dev/null
+++ b/CPP/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;
+ for (;;)
+ {
+ if ((Low & 0x8000) != (high & 0x8000))
+ {
+ if ((Low & 0x4000) == 0 || (high & 0x4000) != 0)
+ break;
+ Low &= 0x3FFF;
+ high |= 0x4000;
+ }
+ Low = (Low << 1) & 0xFFFF;
+ high = ((high << 1) | 1) & 0xFFFF;
+ Code = ((Code << 1) | Stream.ReadBit());
+ }
+ Range = high - Low + 1;
+ }
+};
+
+const 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] = (UInt16)(((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] = (UInt16)(Freqs[i] + Freqs[i + 1]);
+ while(i-- != 0);
+ }
+ else
+ {
+ i = NumItems - 1;
+ do
+ {
+ Freqs[i] >>= 1;
+ if (Freqs[i] <= Freqs[i + 1])
+ Freqs[i] = (UInt16)(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/CPP/7zip/Compress/RangeCoder/RangeCoder.h b/CPP/7zip/Compress/RangeCoder/RangeCoder.h
new file mode 100755
index 00000000..bbb2ba82
--- /dev/null
+++ b/CPP/7zip/Compress/RangeCoder/RangeCoder.h
@@ -0,0 +1,205 @@
+// Compress/RangeCoder/RangeCoder.h
+
+#ifndef __COMPRESS_RANGECODER_H
+#define __COMPRESS_RANGECODER_H
+
+#include "../../Common/InBuffer.h"
+#include "../../Common/OutBuffer.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+const int kNumTopBits = 24;
+const UInt32 kTopValue = (1 << kNumTopBits);
+
+class CEncoder
+{
+ UInt32 _cacheSize;
+ Byte _cache;
+public:
+ UInt64 Low;
+ UInt32 Range;
+ COutBuffer Stream;
+ bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
+
+ void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); }
+ void Init()
+ {
+ Stream.Init();
+ Low = 0;
+ Range = 0xFFFFFFFF;
+ _cacheSize = 1;
+ _cache = 0;
+ }
+
+ void FlushData()
+ {
+ // Low += 1;
+ for(int i = 0; i < 5; i++)
+ ShiftLow();
+ }
+
+ HRESULT FlushStream() { return Stream.Flush(); }
+
+ void ReleaseStream() { Stream.ReleaseStream(); }
+
+ void Encode(UInt32 start, UInt32 size, UInt32 total)
+ {
+ Low += start * (Range /= total);
+ Range *= size;
+ while (Range < kTopValue)
+ {
+ Range <<= 8;
+ ShiftLow();
+ }
+ }
+
+ void ShiftLow()
+ {
+ if ((UInt32)Low < (UInt32)0xFF000000 || (int)(Low >> 32) != 0)
+ {
+ Byte temp = _cache;
+ do
+ {
+ Stream.WriteByte((Byte)(temp + (Byte)(Low >> 32)));
+ temp = 0xFF;
+ }
+ while(--_cacheSize != 0);
+ _cache = (Byte)((UInt32)Low >> 24);
+ }
+ _cacheSize++;
+ Low = (UInt32)Low << 8;
+ }
+
+ void EncodeDirectBits(UInt32 value, int numTotalBits)
+ {
+ for (int i = numTotalBits - 1; i >= 0; i--)
+ {
+ Range >>= 1;
+ if (((value >> i) & 1) == 1)
+ Low += Range;
+ if (Range < kTopValue)
+ {
+ Range <<= 8;
+ ShiftLow();
+ }
+ }
+ }
+
+ void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol)
+ {
+ UInt32 newBound = (Range >> numTotalBits) * size0;
+ if (symbol == 0)
+ Range = newBound;
+ else
+ {
+ Low += newBound;
+ Range -= newBound;
+ }
+ while (Range < kTopValue)
+ {
+ Range <<= 8;
+ ShiftLow();
+ }
+ }
+
+ UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _cacheSize + 4; }
+};
+
+class CDecoder
+{
+public:
+ CInBuffer Stream;
+ UInt32 Range;
+ UInt32 Code;
+ bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
+
+ void Normalize()
+ {
+ while (Range < kTopValue)
+ {
+ Code = (Code << 8) | Stream.ReadByte();
+ Range <<= 8;
+ }
+ }
+
+ void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); }
+ void Init()
+ {
+ Stream.Init();
+ Code = 0;
+ Range = 0xFFFFFFFF;
+ for(int i = 0; i < 5; i++)
+ Code = (Code << 8) | Stream.ReadByte();
+ }
+
+ void ReleaseStream() { Stream.ReleaseStream(); }
+
+ UInt32 GetThreshold(UInt32 total)
+ {
+ return (Code) / ( Range /= total);
+ }
+
+ void Decode(UInt32 start, UInt32 size)
+ {
+ Code -= start * Range;
+ Range *= size;
+ Normalize();
+ }
+
+ UInt32 DecodeDirectBits(int numTotalBits)
+ {
+ UInt32 range = Range;
+ UInt32 code = Code;
+ UInt32 result = 0;
+ for (int i = numTotalBits; i != 0; i--)
+ {
+ range >>= 1;
+ /*
+ result <<= 1;
+ if (code >= range)
+ {
+ code -= range;
+ result |= 1;
+ }
+ */
+ UInt32 t = (code - range) >> 31;
+ code -= range & (t - 1);
+ result = (result << 1) | (1 - t);
+
+ if (range < kTopValue)
+ {
+ code = (code << 8) | Stream.ReadByte();
+ range <<= 8;
+ }
+ }
+ Range = range;
+ Code = code;
+ return result;
+ }
+
+ UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits)
+ {
+ UInt32 newBound = (Range >> numTotalBits) * size0;
+ UInt32 symbol;
+ if (Code < newBound)
+ {
+ symbol = 0;
+ Range = newBound;
+ }
+ else
+ {
+ symbol = 1;
+ Code -= newBound;
+ Range -= newBound;
+ }
+ Normalize();
+ return symbol;
+ }
+
+ UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); }
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Compress/RangeCoder/RangeCoderBit.cpp b/CPP/7zip/Compress/RangeCoder/RangeCoderBit.cpp
new file mode 100755
index 00000000..8e4c4d3a
--- /dev/null
+++ b/CPP/7zip/Compress/RangeCoder/RangeCoderBit.cpp
@@ -0,0 +1,80 @@
+// Compress/RangeCoder/RangeCoderBit.cpp
+
+#include "StdAfx.h"
+
+#include "RangeCoderBit.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+UInt32 CPriceTables::ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
+static CPriceTables g_PriceTables;
+
+CPriceTables::CPriceTables() { Init(); }
+
+void CPriceTables::Init()
+{
+ const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
+ for(int i = kNumBits - 1; i >= 0; i--)
+ {
+ UInt32 start = 1 << (kNumBits - i - 1);
+ UInt32 end = 1 << (kNumBits - i);
+ for (UInt32 j = start; j < end; j++)
+ ProbPrices[j] = (i << kNumBitPriceShiftBits) +
+ (((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1));
+ }
+
+ /*
+ // simplest: bad solution
+ for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
+ ProbPrices[i] = kBitPrice;
+ */
+
+ /*
+ const double kDummyMultMid = (1.0 / kBitPrice) / 2;
+ const double kDummyMultMid = 0;
+ // float solution
+ double ln2 = log(double(2));
+ double lnAll = log(double(kBitModelTotal >> kNumMoveReducingBits));
+ for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
+ ProbPrices[i] = UInt32((fabs(lnAll - log(double(i))) / ln2 + kDummyMultMid) * kBitPrice);
+ */
+
+ /*
+ // experimental, slow, solution:
+ for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
+ {
+ const int kCyclesBits = 5;
+ const UInt32 kCycles = (1 << kCyclesBits);
+
+ UInt32 range = UInt32(-1);
+ UInt32 bitCount = 0;
+ for (UInt32 j = 0; j < kCycles; j++)
+ {
+ range >>= (kNumBitModelTotalBits - kNumMoveReducingBits);
+ range *= i;
+ while(range < (1 << 31))
+ {
+ range <<= 1;
+ bitCount++;
+ }
+ }
+ bitCount <<= kNumBitPriceShiftBits;
+ range -= (1 << 31);
+ for (int k = kNumBitPriceShiftBits - 1; k >= 0; k--)
+ {
+ range <<= 1;
+ if (range > (1 << 31))
+ {
+ bitCount += (1 << k);
+ range -= (1 << 31);
+ }
+ }
+ ProbPrices[i] = (bitCount
+ // + (1 << (kCyclesBits - 1))
+ ) >> kCyclesBits;
+ }
+ */
+}
+
+}}
diff --git a/CPP/7zip/Compress/RangeCoder/RangeCoderBit.h b/CPP/7zip/Compress/RangeCoder/RangeCoderBit.h
new file mode 100755
index 00000000..624f887c
--- /dev/null
+++ b/CPP/7zip/Compress/RangeCoder/RangeCoderBit.h
@@ -0,0 +1,120 @@
+// Compress/RangeCoder/RangeCoderBit.h
+
+#ifndef __COMPRESS_RANGECODER_BIT_H
+#define __COMPRESS_RANGECODER_BIT_H
+
+#include "RangeCoder.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+const int kNumBitModelTotalBits = 11;
+const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits);
+
+const int kNumMoveReducingBits = 2;
+
+const int kNumBitPriceShiftBits = 6;
+const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits;
+
+class CPriceTables
+{
+public:
+ static UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
+ static void Init();
+ CPriceTables();
+};
+
+template <int numMoveBits>
+class CBitModel
+{
+public:
+ UInt32 Prob;
+ void UpdateModel(UInt32 symbol)
+ {
+ /*
+ Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits;
+ Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits);
+ */
+ if (symbol == 0)
+ Prob += (kBitModelTotal - Prob) >> numMoveBits;
+ else
+ Prob -= (Prob) >> numMoveBits;
+ }
+public:
+ void Init() { Prob = kBitModelTotal / 2; }
+};
+
+template <int numMoveBits>
+class CBitEncoder: public CBitModel<numMoveBits>
+{
+public:
+ void Encode(CEncoder *encoder, UInt32 symbol)
+ {
+ /*
+ encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol);
+ this->UpdateModel(symbol);
+ */
+ UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob;
+ if (symbol == 0)
+ {
+ encoder->Range = newBound;
+ this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
+ }
+ else
+ {
+ encoder->Low += newBound;
+ encoder->Range -= newBound;
+ this->Prob -= (this->Prob) >> numMoveBits;
+ }
+ if (encoder->Range < kTopValue)
+ {
+ encoder->Range <<= 8;
+ encoder->ShiftLow();
+ }
+ }
+ UInt32 GetPrice(UInt32 symbol) const
+ {
+ return CPriceTables::ProbPrices[
+ (((this->Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
+ }
+ UInt32 GetPrice0() const { return CPriceTables::ProbPrices[this->Prob >> kNumMoveReducingBits]; }
+ UInt32 GetPrice1() const { return CPriceTables::ProbPrices[(kBitModelTotal - this->Prob) >> kNumMoveReducingBits]; }
+};
+
+
+template <int numMoveBits>
+class CBitDecoder: public CBitModel<numMoveBits>
+{
+public:
+ UInt32 Decode(CDecoder *decoder)
+ {
+ UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob;
+ if (decoder->Code < newBound)
+ {
+ decoder->Range = newBound;
+ this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
+ if (decoder->Range < kTopValue)
+ {
+ decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
+ decoder->Range <<= 8;
+ }
+ return 0;
+ }
+ else
+ {
+ decoder->Range -= newBound;
+ decoder->Code -= newBound;
+ this->Prob -= (this->Prob) >> numMoveBits;
+ if (decoder->Range < kTopValue)
+ {
+ decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
+ decoder->Range <<= 8;
+ }
+ return 1;
+ }
+ }
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Compress/RangeCoder/RangeCoderBitTree.h b/CPP/7zip/Compress/RangeCoder/RangeCoderBitTree.h
new file mode 100755
index 00000000..4f0c78b4
--- /dev/null
+++ b/CPP/7zip/Compress/RangeCoder/RangeCoderBitTree.h
@@ -0,0 +1,161 @@
+// Compress/RangeCoder/RangeCoderBitTree.h
+
+#ifndef __COMPRESS_RANGECODER_BIT_TREE_H
+#define __COMPRESS_RANGECODER_BIT_TREE_H
+
+#include "RangeCoderBit.h"
+#include "RangeCoderOpt.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+template <int numMoveBits, int NumBitLevels>
+class CBitTreeEncoder
+{
+ CBitEncoder<numMoveBits> Models[1 << NumBitLevels];
+public:
+ void Init()
+ {
+ for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
+ Models[i].Init();
+ }
+ void Encode(CEncoder *rangeEncoder, UInt32 symbol)
+ {
+ UInt32 modelIndex = 1;
+ for (int bitIndex = NumBitLevels; bitIndex != 0 ;)
+ {
+ bitIndex--;
+ UInt32 bit = (symbol >> bitIndex) & 1;
+ Models[modelIndex].Encode(rangeEncoder, bit);
+ modelIndex = (modelIndex << 1) | bit;
+ }
+ };
+ void ReverseEncode(CEncoder *rangeEncoder, UInt32 symbol)
+ {
+ UInt32 modelIndex = 1;
+ for (int i = 0; i < NumBitLevels; i++)
+ {
+ UInt32 bit = symbol & 1;
+ Models[modelIndex].Encode(rangeEncoder, bit);
+ modelIndex = (modelIndex << 1) | bit;
+ symbol >>= 1;
+ }
+ }
+ UInt32 GetPrice(UInt32 symbol) const
+ {
+ symbol |= (1 << NumBitLevels);
+ UInt32 price = 0;
+ while (symbol != 1)
+ {
+ price += Models[symbol >> 1].GetPrice(symbol & 1);
+ symbol >>= 1;
+ }
+ return price;
+ }
+ UInt32 ReverseGetPrice(UInt32 symbol) const
+ {
+ UInt32 price = 0;
+ UInt32 modelIndex = 1;
+ for (int i = NumBitLevels; i != 0; i--)
+ {
+ UInt32 bit = symbol & 1;
+ symbol >>= 1;
+ price += Models[modelIndex].GetPrice(bit);
+ modelIndex = (modelIndex << 1) | bit;
+ }
+ return price;
+ }
+};
+
+template <int numMoveBits, int NumBitLevels>
+class CBitTreeDecoder
+{
+ CBitDecoder<numMoveBits> Models[1 << NumBitLevels];
+public:
+ void Init()
+ {
+ for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
+ Models[i].Init();
+ }
+ UInt32 Decode(CDecoder *rangeDecoder)
+ {
+ UInt32 modelIndex = 1;
+ RC_INIT_VAR
+ for(int bitIndex = NumBitLevels; bitIndex != 0; bitIndex--)
+ {
+ // modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder);
+ RC_GETBIT(numMoveBits, Models[modelIndex].Prob, modelIndex)
+ }
+ RC_FLUSH_VAR
+ return modelIndex - (1 << NumBitLevels);
+ };
+ UInt32 ReverseDecode(CDecoder *rangeDecoder)
+ {
+ UInt32 modelIndex = 1;
+ UInt32 symbol = 0;
+ RC_INIT_VAR
+ for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
+ {
+ // UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
+ // modelIndex <<= 1;
+ // modelIndex += bit;
+ // symbol |= (bit << bitIndex);
+ RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
+ }
+ RC_FLUSH_VAR
+ return symbol;
+ }
+};
+
+template <int numMoveBits>
+void ReverseBitTreeEncode(CBitEncoder<numMoveBits> *Models,
+ CEncoder *rangeEncoder, int NumBitLevels, UInt32 symbol)
+{
+ UInt32 modelIndex = 1;
+ for (int i = 0; i < NumBitLevels; i++)
+ {
+ UInt32 bit = symbol & 1;
+ Models[modelIndex].Encode(rangeEncoder, bit);
+ modelIndex = (modelIndex << 1) | bit;
+ symbol >>= 1;
+ }
+}
+
+template <int numMoveBits>
+UInt32 ReverseBitTreeGetPrice(CBitEncoder<numMoveBits> *Models,
+ UInt32 NumBitLevels, UInt32 symbol)
+{
+ UInt32 price = 0;
+ UInt32 modelIndex = 1;
+ for (int i = NumBitLevels; i != 0; i--)
+ {
+ UInt32 bit = symbol & 1;
+ symbol >>= 1;
+ price += Models[modelIndex].GetPrice(bit);
+ modelIndex = (modelIndex << 1) | bit;
+ }
+ return price;
+}
+
+template <int numMoveBits>
+UInt32 ReverseBitTreeDecode(CBitDecoder<numMoveBits> *Models,
+ CDecoder *rangeDecoder, int NumBitLevels)
+{
+ UInt32 modelIndex = 1;
+ UInt32 symbol = 0;
+ RC_INIT_VAR
+ for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
+ {
+ // UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
+ // modelIndex <<= 1;
+ // modelIndex += bit;
+ // symbol |= (bit << bitIndex);
+ RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
+ }
+ RC_FLUSH_VAR
+ return symbol;
+}
+
+}}
+
+#endif
diff --git a/CPP/7zip/Compress/RangeCoder/RangeCoderOpt.h b/CPP/7zip/Compress/RangeCoder/RangeCoderOpt.h
new file mode 100755
index 00000000..668b9a5b
--- /dev/null
+++ b/CPP/7zip/Compress/RangeCoder/RangeCoderOpt.h
@@ -0,0 +1,31 @@
+// Compress/RangeCoder/RangeCoderOpt.h
+
+#ifndef __COMPRESS_RANGECODER_OPT_H
+#define __COMPRESS_RANGECODER_OPT_H
+
+#define RC_INIT_VAR \
+ UInt32 range = rangeDecoder->Range; \
+ UInt32 code = rangeDecoder->Code;
+
+#define RC_FLUSH_VAR \
+ rangeDecoder->Range = range; \
+ rangeDecoder->Code = code;
+
+#define RC_NORMALIZE \
+ if (range < NCompress::NRangeCoder::kTopValue) \
+ { code = (code << 8) | rangeDecoder->Stream.ReadByte(); range <<= 8; }
+
+#define RC_GETBIT2(numMoveBits, prob, mi, A0, A1) \
+ { UInt32 bound = (range >> NCompress::NRangeCoder::kNumBitModelTotalBits) * prob; \
+ if (code < bound) \
+ { A0; range = bound; \
+ prob += (NCompress::NRangeCoder::kBitModelTotal - prob) >> numMoveBits; \
+ mi <<= 1; } \
+ else \
+ { A1; range -= bound; code -= bound; prob -= (prob) >> numMoveBits; \
+ mi = (mi + mi) + 1; }} \
+ RC_NORMALIZE
+
+#define RC_GETBIT(numMoveBits, prob, mi) RC_GETBIT2(numMoveBits, prob, mi, ; , ;)
+
+#endif
diff --git a/CPP/7zip/Compress/RangeCoder/StdAfx.h b/CPP/7zip/Compress/RangeCoder/StdAfx.h
new file mode 100755
index 00000000..b637fd40
--- /dev/null
+++ b/CPP/7zip/Compress/RangeCoder/StdAfx.h
@@ -0,0 +1,6 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#endif
diff --git a/CPP/7zip/Compress/Rar/DllExports.cpp b/CPP/7zip/Compress/Rar/DllExports.cpp
new file mode 100755
index 00000000..acc3068e
--- /dev/null
+++ b/CPP/7zip/Compress/Rar/DllExports.cpp
@@ -0,0 +1,91 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+
+#include "Rar1Decoder.h"
+#include "Rar2Decoder.h"
+#include "Rar3Decoder.h"
+// #include "Rar29Decoder.h"
+
+#define RarClassId(ver) CLSID_CCompressRar ## ver ## Decoder
+
+#define MyClassRar(ver) DEFINE_GUID(RarClassId(ver), \
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x03, ver, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+MyClassRar(1);
+MyClassRar(2);
+MyClassRar(3);
+
+#define CreateCoder(ver) if (*clsid == RarClassId(ver)) \
+{ if (!correctInterface) return E_NOINTERFACE; \
+coder = (ICompressCoder *)new NCompress::NRar ## ver::CDecoder; }
+
+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;
+ CreateCoder(1) else
+ CreateCoder(2) else
+ CreateCoder(3) 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", &RarClassId(1) },
+ { { 0x04, 0x03, 0x02 }, L"Rar20", &RarClassId(2) },
+ { { 0x04, 0x03, 0x03 }, L"Rar29", &RarClassId(3) }
+};
+
+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/CPP/7zip/Compress/Rar/Rar1Decoder.cpp b/CPP/7zip/Compress/Rar/Rar1Decoder.cpp
new file mode 100755
index 00000000..c30443de
--- /dev/null
+++ b/CPP/7zip/Compress/Rar/Rar1Decoder.cpp
@@ -0,0 +1,485 @@
+// Rar1Decoder.cpp
+// According to unRAR license,
+// this code may not be used to develop a
+// RAR (WinRAR) compatible archiver
+
+#include "StdAfx.h"
+
+#include "Rar1Decoder.h"
+
+namespace NCompress {
+namespace NRar1 {
+
+static UInt32 PosL1[]={0,0,0,2,3,5,7,11,16,20,24,32,32, 256};
+static UInt32 PosL2[]={0,0,0,0,5,7,9,13,18,22,26,34,36, 256};
+static UInt32 PosHf0[]={0,0,0,0,0,8,16,24,33,33,33,33,33, 257};
+static UInt32 PosHf1[]={0,0,0,0,0,0,4,44,60,76,80,80,127, 257};
+static UInt32 PosHf2[]={0,0,0,0,0,0,2,7,53,117,233, 257,0};
+static UInt32 PosHf3[]={0,0,0,0,0,0,0,2,16,218,251, 257,0};
+static UInt32 PosHf4[]={0,0,0,0,0,0,0,0,0,255, 257,0,0};
+
+static const UInt32 kHistorySize = (1 << 16);
+
+class CCoderReleaser
+{
+ CDecoder *m_Coder;
+public:
+ CCoderReleaser(CDecoder *coder): m_Coder(coder) {}
+ ~CCoderReleaser() { m_Coder->ReleaseStreams(); }
+};
+
+CDecoder::CDecoder(): m_IsSolid(false) { }
+
+void CDecoder::InitStructures()
+{
+ for(int i = 0; i < kNumRepDists; i++)
+ m_RepDists[i] = 0;
+ m_RepDistPtr = 0;
+ LastLength = 0;
+ LastDist = 0;
+}
+
+UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); }
+
+HRESULT CDecoder::CopyBlock(UInt32 distance, UInt32 len)
+{
+ m_UnpackSize -= len;
+ return m_OutWindowStream.CopyBlock(distance, len) ? S_OK : S_FALSE;
+}
+
+
+UInt32 CDecoder::DecodeNum(const UInt32 *posTab)
+{
+ UInt32 startPos = 2;
+ UInt32 num = m_InBitStream.GetValue(12);
+ for (;;)
+ {
+ UInt32 cur = (posTab[startPos + 1] - posTab[startPos]) << (12 - startPos);
+ if (num < cur)
+ break;
+ startPos++;
+ num -= cur;
+ }
+ m_InBitStream.MovePos(startPos);
+ return((num >> (12 - startPos)) + posTab[startPos]);
+}
+
+static Byte kShortLen1[] = {1,3,4,4,5,6,7,8,8,4,4,5,6,6 };
+static Byte kShortLen1a[] = {1,4,4,4,5,6,7,8,8,4,4,5,6,6,4 };
+static Byte kShortLen2[] = {2,3,3,3,4,4,5,6,6,4,4,5,6,6 };
+static Byte kShortLen2a[] = {2,3,3,4,4,4,5,6,6,4,4,5,6,6,4 };
+static UInt32 kShortXor1[] = {0,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xc0,0x80,0x90,0x98,0x9c,0xb0};
+static UInt32 kShortXor2[] = {0,0x40,0x60,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xc0,0x80,0x90,0x98,0x9c,0xb0};
+
+HRESULT CDecoder::ShortLZ()
+{
+ UInt32 len, saveLen, dist;
+ int distancePlace;
+ Byte *kShortLen;
+ const UInt32 *kShortXor;
+ NumHuf = 0;
+
+ if (LCount == 2)
+ {
+ if (ReadBits(1))
+ return CopyBlock(LastDist, LastLength);
+ LCount = 0;
+ }
+
+ UInt32 bitField = m_InBitStream.GetValue(8);
+
+ if (AvrLn1 < 37)
+ {
+ kShortLen = Buf60 ? kShortLen1a : kShortLen1;
+ kShortXor = kShortXor1;
+ }
+ else
+ {
+ kShortLen = Buf60 ? kShortLen2a : kShortLen2;
+ kShortXor = kShortXor2;
+ }
+
+ for (len = 0; ((bitField ^ kShortXor[len]) & (~(0xff >> kShortLen[len]))) != 0; len++);
+ m_InBitStream.MovePos(kShortLen[len]);
+
+ if (len >= 9)
+ {
+ if (len == 9)
+ {
+ LCount++;
+ return CopyBlock(LastDist, LastLength);
+ }
+ if (len == 14)
+ {
+ LCount = 0;
+ len = DecodeNum(PosL2) + 5;
+ dist = 0x8000 + ReadBits(15) - 1;
+ LastLength = len;
+ LastDist = dist;
+ return CopyBlock(dist, len);
+ }
+
+ LCount = 0;
+ saveLen = len;
+ dist = m_RepDists[(m_RepDistPtr - (len - 9)) & 3];
+ len = DecodeNum(PosL1) + 2;
+ if (len == 0x101 && saveLen == 10)
+ {
+ Buf60 ^= 1;
+ return S_OK;
+ }
+ if (dist >= 256)
+ len++;
+ if (dist >= MaxDist3 - 1)
+ len++;
+ }
+ else
+ {
+ LCount = 0;
+ AvrLn1 += len;
+ AvrLn1 -= AvrLn1 >> 4;
+
+ distancePlace = DecodeNum(PosHf2) & 0xff;
+ dist = ChSetA[distancePlace];
+ if (--distancePlace != -1)
+ {
+ PlaceA[dist]--;
+ UInt32 lastDistance = ChSetA[distancePlace];
+ PlaceA[lastDistance]++;
+ ChSetA[distancePlace + 1] = lastDistance;
+ ChSetA[distancePlace] = dist;
+ }
+ len += 2;
+ }
+ m_RepDists[m_RepDistPtr++] = dist;
+ m_RepDistPtr &= 3;
+ LastLength = len;
+ LastDist = dist;
+ return CopyBlock(dist, len);
+}
+
+
+HRESULT CDecoder::LongLZ()
+{
+ UInt32 len;
+ UInt32 dist;
+ UInt32 distancePlace, newDistancePlace;
+ UInt32 oldAvr2, oldAvr3;
+
+ NumHuf = 0;
+ Nlzb += 16;
+ if (Nlzb > 0xff)
+ {
+ Nlzb = 0x90;
+ Nhfb >>= 1;
+ }
+ oldAvr2=AvrLn2;
+
+ if (AvrLn2 >= 122)
+ len = DecodeNum(PosL2);
+ else if (AvrLn2 >= 64)
+ len = DecodeNum(PosL1);
+ else
+ {
+ UInt32 bitField = m_InBitStream.GetValue(16);
+ if (bitField < 0x100)
+ {
+ len = bitField;
+ m_InBitStream.MovePos(16);
+ }
+ else
+ {
+ for (len = 0; ((bitField << len) & 0x8000) == 0; len++)
+ ;
+ m_InBitStream.MovePos(len + 1);
+ }
+ }
+
+ AvrLn2 += len;
+ AvrLn2 -= AvrLn2 >> 5;
+
+ if (AvrPlcB > 0x28ff)
+ distancePlace = DecodeNum(PosHf2);
+ else if (AvrPlcB > 0x6ff)
+ distancePlace = DecodeNum(PosHf1);
+ else
+ distancePlace = DecodeNum(PosHf0);
+
+ AvrPlcB += distancePlace;
+ AvrPlcB -= AvrPlcB >> 8;
+ for (;;)
+ {
+ dist = ChSetB[distancePlace & 0xff];
+ newDistancePlace = NToPlB[dist++ & 0xff]++;
+ if (!(dist & 0xff))
+ CorrHuff(ChSetB,NToPlB);
+ else
+ break;
+ }
+
+ ChSetB[distancePlace] = ChSetB[newDistancePlace];
+ ChSetB[newDistancePlace] = dist;
+
+ dist = ((dist & 0xff00) >> 1) | ReadBits(7);
+
+ oldAvr3 = AvrLn3;
+ if (len != 1 && len != 4)
+ if (len == 0 && dist <= MaxDist3)
+ {
+ AvrLn3++;
+ AvrLn3 -= AvrLn3 >> 8;
+ }
+ else
+ if (AvrLn3 > 0)
+ AvrLn3--;
+ len += 3;
+ if (dist >= MaxDist3)
+ len++;
+ if (dist <= 256)
+ len += 8;
+ if (oldAvr3 > 0xb0 || AvrPlc >= 0x2a00 && oldAvr2 < 0x40)
+ MaxDist3 = 0x7f00;
+ else
+ MaxDist3 = 0x2001;
+ m_RepDists[m_RepDistPtr++] = --dist;
+ m_RepDistPtr &= 3;
+ LastLength = len;
+ LastDist = dist;
+ return CopyBlock(dist, len);
+}
+
+
+HRESULT CDecoder::HuffDecode()
+{
+ UInt32 curByte, newBytePlace;
+ UInt32 len;
+ UInt32 dist;
+ int bytePlace;
+
+ if (AvrPlc > 0x75ff) bytePlace = DecodeNum(PosHf4);
+ else if (AvrPlc > 0x5dff) bytePlace = DecodeNum(PosHf3);
+ else if (AvrPlc > 0x35ff) bytePlace = DecodeNum(PosHf2);
+ else if (AvrPlc > 0x0dff) bytePlace = DecodeNum(PosHf1);
+ else bytePlace = DecodeNum(PosHf0);
+ if (StMode)
+ {
+ if (--bytePlace == -1)
+ {
+ if (ReadBits(1))
+ {
+ NumHuf = StMode = 0;
+ return S_OK;
+ }
+ else
+ {
+ len = (ReadBits(1)) ? 4 : 3;
+ dist = DecodeNum(PosHf2);
+ dist = (dist << 5) | ReadBits(5);
+ return CopyBlock(dist - 1, len);
+ }
+ }
+ }
+ else if (NumHuf++ >= 16 && FlagsCnt == 0)
+ StMode = 1;
+ bytePlace &= 0xff;
+ AvrPlc += bytePlace;
+ AvrPlc -= AvrPlc >> 8;
+ Nhfb+=16;
+ if (Nhfb > 0xff)
+ {
+ Nhfb=0x90;
+ Nlzb >>= 1;
+ }
+
+ m_UnpackSize --;
+ m_OutWindowStream.PutByte((Byte)(ChSet[bytePlace] >> 8));
+
+ for (;;)
+ {
+ curByte = ChSet[bytePlace];
+ newBytePlace = NToPl[curByte++ & 0xff]++;
+ if ((curByte & 0xff) > 0xa1)
+ CorrHuff(ChSet, NToPl);
+ else
+ break;
+ }
+
+ ChSet[bytePlace] = ChSet[newBytePlace];
+ ChSet[newBytePlace] = curByte;
+ return S_OK;
+}
+
+
+void CDecoder::GetFlagsBuf()
+{
+ UInt32 flags, newFlagsPlace;
+ UInt32 flagsPlace = DecodeNum(PosHf2);
+
+ for (;;)
+ {
+ flags = ChSetC[flagsPlace];
+ FlagBuf = flags >> 8;
+ newFlagsPlace = NToPlC[flags++ & 0xff]++;
+ if ((flags & 0xff) != 0)
+ break;
+ CorrHuff(ChSetC, NToPlC);
+ }
+
+ ChSetC[flagsPlace] = ChSetC[newFlagsPlace];
+ ChSetC[newFlagsPlace] = flags;
+}
+
+void CDecoder::InitData()
+{
+ if (!m_IsSolid)
+ {
+ AvrPlcB = AvrLn1 = AvrLn2 = AvrLn3 = NumHuf = Buf60 = 0;
+ AvrPlc = 0x3500;
+ MaxDist3 = 0x2001;
+ Nhfb = Nlzb = 0x80;
+ }
+ FlagsCnt = 0;
+ FlagBuf = 0;
+ StMode = 0;
+ LCount = 0;
+}
+
+void CDecoder::CorrHuff(UInt32 *CharSet,UInt32 *NumToPlace)
+{
+ int i;
+ for (i = 7; i >= 0; i--)
+ for (int j = 0; j < 32; j++, CharSet++)
+ *CharSet = (*CharSet & ~0xff) | i;
+ memset(NumToPlace, 0, sizeof(NToPl));
+ for (i = 6; i >= 0; i--)
+ NumToPlace[i] = (7 - i) * 32;
+}
+
+void CDecoder::InitHuff()
+{
+ for (UInt32 i = 0; i < 256; i++)
+ {
+ Place[i] = PlaceA[i] = PlaceB[i] = i;
+ PlaceC[i] = (~i + 1) & 0xff;
+ ChSet[i] = ChSetB[i] = i << 8;
+ ChSetA[i] = i;
+ ChSetC[i] = ((~i + 1) & 0xff) << 8;
+ }
+ memset(NToPl, 0, sizeof(NToPl));
+ memset(NToPlB, 0, sizeof(NToPlB));
+ memset(NToPlC, 0, sizeof(NToPlC));
+ CorrHuff(ChSetB, NToPlB);
+}
+
+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_UnpackSize = (Int64)*outSize;
+ m_OutWindowStream.SetStream(outStream);
+ m_OutWindowStream.Init(m_IsSolid);
+ m_InBitStream.SetStream(inStream);
+ m_InBitStream.Init();
+
+ CCoderReleaser coderReleaser(this);
+ InitData();
+ if (!m_IsSolid)
+ {
+ InitStructures();
+ InitHuff();
+ }
+ if (m_UnpackSize > 0)
+ {
+ GetFlagsBuf();
+ FlagsCnt = 8;
+ }
+
+ while (m_UnpackSize > 0)
+ {
+ if (StMode)
+ {
+ RINOK(HuffDecode());
+ continue;
+ }
+
+ if (--FlagsCnt < 0)
+ {
+ GetFlagsBuf();
+ FlagsCnt=7;
+ }
+
+ if (FlagBuf & 0x80)
+ {
+ FlagBuf <<= 1;
+ if (Nlzb > Nhfb)
+ {
+ RINOK(LongLZ());
+ }
+ else
+ {
+ RINOK(HuffDecode());
+ }
+ }
+ else
+ {
+ FlagBuf <<= 1;
+ if (--FlagsCnt < 0)
+ {
+ GetFlagsBuf();
+ FlagsCnt = 7;
+ }
+ if (FlagBuf & 0x80)
+ {
+ FlagBuf <<= 1;
+ if (Nlzb > Nhfb)
+ {
+ RINOK(HuffDecode());
+ }
+ else
+ {
+ RINOK(LongLZ());
+ }
+ }
+ else
+ {
+ FlagBuf <<= 1;
+ RINOK(ShortLZ());
+ }
+ }
+ }
+ if (m_UnpackSize < 0)
+ return S_FALSE;
+ return m_OutWindowStream.Flush();
+}
+
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ try
+ {
+ HRESULT res = CodeReal(inStream, outStream, inSize, outSize, progress);
+ m_OutWindowStream.Flush();
+ return res;
+ }
+ catch(const CLZOutWindowException &e) { m_OutWindowStream.Flush(); return e.ErrorCode; }
+ catch(...) { m_OutWindowStream.Flush(); 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/CPP/7zip/Compress/Rar/Rar1Decoder.h b/CPP/7zip/Compress/Rar/Rar1Decoder.h
new file mode 100755
index 00000000..bdaf4d85
--- /dev/null
+++ b/CPP/7zip/Compress/Rar/Rar1Decoder.h
@@ -0,0 +1,90 @@
+// Rar15Decoder.h
+// According to unRAR license,
+// this code may not be used to develop a
+// RAR (WinRAR) compatible archiver
+
+#ifndef __RAR10_DECODER_H
+#define __RAR10_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"
+
+namespace NCompress {
+namespace NRar1 {
+
+const UInt32 kNumRepDists = 4;
+
+typedef NStream::NMSBF::CDecoder<CInBuffer> CBitDecoder;
+
+class CDecoder :
+ public ICompressCoder,
+ public ICompressSetDecoderProperties2,
+ public CMyUnknownImp
+{
+public:
+ CLZOutWindow m_OutWindowStream;
+ CBitDecoder m_InBitStream;
+
+ UInt32 m_RepDists[kNumRepDists];
+ UInt32 m_RepDistPtr;
+
+ UInt32 LastDist;
+ UInt32 LastLength;
+
+ Int64 m_UnpackSize;
+ bool m_IsSolid;
+
+ UInt32 ReadBits(int numBits);
+ HRESULT CopyBlock(UInt32 distance, UInt32 len);
+
+ UInt32 DecodeNum(const UInt32 *posTab);
+ HRESULT ShortLZ();
+ HRESULT LongLZ();
+ HRESULT HuffDecode();
+ void GetFlagsBuf();
+ void InitData();
+ void InitHuff();
+ void CorrHuff(UInt32 *CharSet, UInt32 *NumToPlace);
+ void OldUnpWriteBuf();
+
+ UInt32 ChSet[256],ChSetA[256],ChSetB[256],ChSetC[256];
+ UInt32 Place[256],PlaceA[256],PlaceB[256],PlaceC[256];
+ UInt32 NToPl[256],NToPlB[256],NToPlC[256];
+ UInt32 FlagBuf,AvrPlc,AvrPlcB,AvrLn1,AvrLn2,AvrLn3;
+ int Buf60,NumHuf,StMode,LCount,FlagsCnt;
+ UInt32 Nhfb,Nlzb,MaxDist3;
+
+ void InitStructures();
+
+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/CPP/7zip/Compress/Rar/Rar29.dsp b/CPP/7zip/Compress/Rar/Rar29.dsp
new file mode 100755
index 00000000..9a0b86bb
--- /dev/null
+++ b/CPP/7zip/Compress/Rar/Rar29.dsp
@@ -0,0 +1,297 @@
+# 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 "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
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.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 "Rar3"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\PPMD\PPMDContext.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\PPMD\PPMDDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\PPMD\PPMDSubAlloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\PPMD\PPMDType.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Rar1Decoder.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=.\Rar1Decoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Rar2Decoder.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=.\Rar2Decoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Rar3Decoder.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=.\Rar3Decoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Rar3Vm.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=.\Rar3Vm.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/CPP/7zip/Compress/Rar/Rar29.dsw b/CPP/7zip/Compress/Rar/Rar29.dsw
new file mode 100755
index 00000000..70172e1a
--- /dev/null
+++ b/CPP/7zip/Compress/Rar/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/CPP/7zip/Compress/Rar/Rar2Decoder.cpp b/CPP/7zip/Compress/Rar/Rar2Decoder.cpp
new file mode 100755
index 00000000..43473695
--- /dev/null
+++ b/CPP/7zip/Compress/Rar/Rar2Decoder.cpp
@@ -0,0 +1,401 @@
+// Rar2Decoder.cpp
+// According to unRAR license,
+// this code may not be used to develop a
+// RAR (WinRAR) compatible archiver
+
+#include "StdAfx.h"
+
+#include "Rar2Decoder.h"
+
+namespace NCompress {
+namespace NRar2 {
+
+namespace NMultimedia {
+
+Byte CFilter::Decode(int &channelDelta, Byte deltaByte)
+{
+ D4 = D3;
+ D3 = D2;
+ D2 = LastDelta - D1;
+ D1 = LastDelta;
+ int predictedValue = ((8 * LastChar + K1 * D1 + K2 * D2 + K3 * D3 + K4 * D4 + K5 * channelDelta) >> 3);
+
+ Byte realValue = (Byte)(predictedValue - deltaByte);
+ int i = ((int)(signed char)deltaByte) << 3;
+
+ Dif[0] += abs(i);
+ Dif[1] += abs(i - D1);
+ Dif[2] += abs(i + D1);
+ Dif[3] += abs(i - D2);
+ Dif[4] += abs(i + D2);
+ Dif[5] += abs(i - D3);
+ Dif[6] += abs(i + D3);
+ Dif[7] += abs(i - D4);
+ Dif[8] += abs(i + D4);
+ Dif[9] += abs(i - channelDelta);
+ Dif[10] += abs(i + channelDelta);
+
+ channelDelta = LastDelta = (signed char)(realValue - LastChar);
+ LastChar = realValue;
+
+ if (((++ByteCount) & 0x1F) == 0)
+ {
+ UInt32 minDif = Dif[0];
+ UInt32 numMinDif = 0;
+ Dif[0] = 0;
+ for (i = 1; i < sizeof(Dif) / sizeof(Dif[0]); i++)
+ {
+ if (Dif[i] < minDif)
+ {
+ minDif = Dif[i];
+ numMinDif = i;
+ }
+ Dif[i] = 0;
+ }
+ switch(numMinDif)
+ {
+ case 1: if (K1 >= -16) K1--; break;
+ case 2: if (K1 < 16) K1++; break;
+ case 3: if (K2 >= -16) K2--; break;
+ case 4: if (K2 < 16) K2++; break;
+ case 5: if (K3 >= -16) K3--; break;
+ case 6: if (K3 < 16) K3++; break;
+ case 7: if (K4 >= -16) K4--; break;
+ case 8: if (K4 < 16) K4++; break;
+ case 9: if (K5 >= -16) K5--; break;
+ case 10:if (K5 < 16) K5++; break;
+ }
+ }
+ return realValue;
+}
+}
+
+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_MmFilter.Init();
+ for(int i = 0; i < kNumRepDists; i++)
+ m_RepDists[i] = 0;
+ m_RepDistPtr = 0;
+ m_LastLength = 0;
+ memset(m_LastLevels, 0, kMaxTableSize);
+}
+
+UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); }
+
+#define RIF(x) { if (!(x)) return false; }
+
+bool CDecoder::ReadTables(void)
+{
+ Byte levelLevels[kLevelTableSize];
+ Byte newLevels[kMaxTableSize];
+ m_AudioMode = (ReadBits(1) == 1);
+
+ if (ReadBits(1) == 0)
+ memset(m_LastLevels, 0, kMaxTableSize);
+ int numLevels;
+ if (m_AudioMode)
+ {
+ m_NumChannels = ReadBits(2) + 1;
+ if (m_MmFilter.CurrentChannel >= m_NumChannels)
+ m_MmFilter.CurrentChannel = 0;
+ numLevels = m_NumChannels * kMMTableSize;
+ }
+ else
+ numLevels = kHeapTablesSizesSum;
+
+ int i;
+ for (i = 0; i < kLevelTableSize; i++)
+ levelLevels[i] = (Byte)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 = 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 = ReadBits(3) + 3;
+ else if (number == kTableLevel0Number2)
+ num = ReadBits(7) + 11;
+ else
+ return false;
+ for (;num > 0 && i < numLevels; num--)
+ newLevels[i++] = 0;
+ }
+ }
+ }
+ if (m_AudioMode)
+ for (i = 0; i < m_NumChannels; i++)
+ {
+ RIF(m_MMDecoders[i].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_MmFilter.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();
+ }
+};
+
+bool CDecoder::DecodeMm(UInt32 pos)
+{
+ while (pos-- > 0)
+ {
+ UInt32 symbol = m_MMDecoders[m_MmFilter.CurrentChannel].DecodeSymbol(&m_InBitStream);
+ if (symbol == 256)
+ return true;
+ if (symbol >= kMMTableSize)
+ return false;
+ /*
+ Byte byPredict = m_Predictor.Predict();
+ Byte byReal = (Byte)(byPredict - (Byte)symbol);
+ m_Predictor.Update(byReal, byPredict);
+ */
+ Byte byReal = m_MmFilter.Decode((Byte)symbol);
+ m_OutWindowStream.PutByte(byReal);
+ if (++m_MmFilter.CurrentChannel == m_NumChannels)
+ m_MmFilter.CurrentChannel = 0;
+ }
+ return true;
+}
+
+bool CDecoder::DecodeLz(Int32 pos)
+{
+ while (pos > 0)
+ {
+ UInt32 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 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 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)
+ return true;
+ else
+ return false;
+ m_RepDists[m_RepDistPtr++ & 3] = distance;
+ m_LastLength = length;
+ if (!m_OutWindowStream.CopyBlock(distance, length))
+ return false;
+ pos -= length;
+ }
+ return true;
+}
+
+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;
+ }
+
+ UInt64 startPos = m_OutWindowStream.GetProcessedSize();
+ while(pos < unPackSize)
+ {
+ UInt32 blockSize = 1 << 20;
+ if (blockSize > unPackSize - pos)
+ blockSize = (UInt32)(unPackSize - pos);
+ UInt64 blockStartPos = m_OutWindowStream.GetProcessedSize();
+ if (m_AudioMode)
+ {
+ if (!DecodeMm(blockSize))
+ return S_FALSE;
+ }
+ else
+ {
+ if (!DecodeLz((Int32)blockSize))
+ return S_FALSE;
+ }
+ UInt64 globalPos = m_OutWindowStream.GetProcessedSize();
+ pos = globalPos - blockStartPos;
+ if (pos < blockSize)
+ if (!ReadTables())
+ return S_FALSE;
+ pos = globalPos - startPos;
+ if (progress != 0)
+ {
+ UInt64 packSize = m_InBitStream.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&packSize, &pos));
+ }
+ }
+ if (pos > unPackSize)
+ 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/CPP/7zip/Compress/Rar/Rar2Decoder.h b/CPP/7zip/Compress/Rar/Rar2Decoder.h
new file mode 100755
index 00000000..dfd0f816
--- /dev/null
+++ b/CPP/7zip/Compress/Rar/Rar2Decoder.h
@@ -0,0 +1,176 @@
+// Rar2Decoder.h
+// According to unRAR license,
+// this code may not be used to develop a
+// RAR (WinRAR) compatible archiver
+
+#ifndef __RAR2DECODER_H
+#define __RAR2DECODER_H
+
+#include "../../../Common/MyCom.h"
+
+#include "../../ICoder.h"
+#include "../../Common/MSBFDecoder.h"
+#include "../../Common/InBuffer.h"
+
+#include "../LZ/LZOutWindow.h"
+#include "../Huffman/HuffmanDecoder.h"
+
+namespace NCompress {
+namespace NRar2 {
+
+const UInt32 kNumRepDists = 4;
+const UInt32 kDistTableSize = 48;
+
+const int kMMTableSize = 256 + 1;
+
+const UInt32 kMainTableSize = 298;
+const UInt32 kLenTableSize = 28;
+
+const UInt32 kDistTableStart = kMainTableSize;
+const UInt32 kLenTableStart = kDistTableStart + kDistTableSize;
+
+const UInt32 kHeapTablesSizesSum = kMainTableSize + kDistTableSize + kLenTableSize;
+
+const UInt32 kLevelTableSize = 19;
+
+const UInt32 kMMTablesSizesSum = kMMTableSize * 4;
+
+const UInt32 kMaxTableSize = kMMTablesSizesSum;
+
+const UInt32 kTableDirectLevels = 16;
+const UInt32 kTableLevelRepNumber = kTableDirectLevels;
+const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1;
+const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1;
+
+const UInt32 kLevelMask = 0xF;
+
+
+const UInt32 kRepBothNumber = 256;
+const UInt32 kRepNumber = kRepBothNumber + 1;
+const UInt32 kLen2Number = kRepNumber + 4;
+
+const UInt32 kLen2NumNumbers = 8;
+const UInt32 kReadTableNumber = kLen2Number + kLen2NumNumbers;
+const UInt32 kMatchNumber = kReadTableNumber + 1;
+
+const Byte kLenStart[kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224};
+const Byte kLenDirectBits[kLenTableSize] = {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5};
+
+const UInt32 kDistStart[kDistTableSize] = {0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768U,49152U,65536,98304,131072,196608,262144,327680,393216,458752,524288,589824,655360,720896,786432,851968,917504,983040};
+const Byte kDistDirectBits[kDistTableSize] = {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
+
+const Byte kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7};
+
+const Byte kLen2DistStarts[kLen2NumNumbers]={0,4,8,16,32,64,128,192};
+const Byte kLen2DistDirectBits[kLen2NumNumbers]={2,2,3, 4, 5, 6, 6, 6};
+
+const UInt32 kDistLimit2 = 0x101 - 1;
+const UInt32 kDistLimit3 = 0x2000 - 1;
+const UInt32 kDistLimit4 = 0x40000 - 1;
+
+const UInt32 kMatchMaxLen = 255 + 2;
+const UInt32 kMatchMaxLenMax = 255 + 5;
+const UInt32 kNormalMatchMinLen = 3;
+
+namespace NMultimedia {
+
+struct CFilter
+{
+ int K1,K2,K3,K4,K5;
+ int D1,D2,D3,D4;
+ int LastDelta;
+ UInt32 Dif[11];
+ UInt32 ByteCount;
+ int LastChar;
+
+ Byte Decode(int &channelDelta, Byte delta);
+
+ void Init() { memset(this, 0, sizeof(*this)); }
+
+};
+
+const int kNumChanelsMax = 4;
+
+class CFilter2
+{
+public:
+ CFilter m_Filters[kNumChanelsMax];
+ int m_ChannelDelta;
+ int CurrentChannel;
+
+ void Init() { memset(this, 0, sizeof(*this)); }
+ Byte Decode(Byte delta)
+ {
+ return m_Filters[CurrentChannel].Decode(m_ChannelDelta, delta);
+ }
+
+};
+
+}
+
+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::CFilter2 m_MmFilter;
+ 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();
+ UInt32 ReadBits(int numBits);
+ bool ReadTables();
+ bool ReadLastTables();
+
+ bool DecodeMm(UInt32 pos);
+ bool DecodeLz(Int32 pos);
+
+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/CPP/7zip/Compress/Rar/Rar3Decoder.cpp b/CPP/7zip/Compress/Rar/Rar3Decoder.cpp
new file mode 100755
index 00000000..478b6587
--- /dev/null
+++ b/CPP/7zip/Compress/Rar/Rar3Decoder.cpp
@@ -0,0 +1,832 @@
+// Rar3Decoder.cpp
+// According to unRAR license,
+// this code may not be used to develop a
+// RAR (WinRAR) compatible archiver
+
+#include "StdAfx.h"
+
+#include "Rar3Decoder.h"
+#include "../../Common/StreamUtils.h"
+
+namespace NCompress {
+namespace NRar3 {
+
+static const UInt32 kNumAlignReps = 15;
+
+static const UInt32 kSymbolReadTable = 256;
+static const UInt32 kSymbolRep = 259;
+static const UInt32 kSymbolLen2 = kSymbolRep + kNumReps;
+
+static const Byte kLenStart[kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224};
+static const Byte kLenDirectBits[kLenTableSize] = {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5};
+
+static const Byte kDistDirectBits[kDistTableSize] =
+ {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,
+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+ 18,18,18,18,18,18,18,18,18,18,18,18};
+
+static const Byte kLevelDirectBits[kLevelTableSize] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+static const Byte kLen2DistStarts[kNumLen2Symbols]={0,4,8,16,32,64,128,192};
+static const Byte kLen2DistDirectBits[kNumLen2Symbols]={2,2,3, 4, 5, 6, 6, 6};
+
+static const UInt32 kDistLimit3 = 0x2000 - 2;
+static const UInt32 kDistLimit4 = 0x40000 - 2;
+
+static const UInt32 kNormalMatchMinLen = 3;
+
+static const UInt32 kVmDataSizeMax = 1 << 16;
+static const UInt32 kVmCodeSizeMax = 1 << 16;
+
+CDecoder::CDecoder():
+ _window(0),
+ _winPos(0),
+ _wrPtr(0),
+ _lzSize(0),
+ _writtenFileSize(0),
+ _vmData(0),
+ _vmCode(0),
+ m_IsSolid(false)
+{
+}
+
+CDecoder::~CDecoder()
+{
+ InitFilters();
+ if (_vmData)
+ ::MidFree(_vmData);
+}
+
+HRESULT CDecoder::WriteDataToStream(const Byte *data, UInt32 size)
+{
+ UInt32 processedSize;
+ HRESULT res = WriteStream(_outStream, data, size, &processedSize);
+ if (res == S_OK && processedSize != size)
+ res = E_FAIL;
+ return res;
+}
+
+HRESULT CDecoder::WriteData(const Byte *data, UInt32 size)
+{
+ HRESULT res = S_OK;
+ if (_writtenFileSize < _unpackSize)
+ {
+ UInt32 curSize = size;
+ UInt64 remain = _unpackSize - _writtenFileSize;
+ if (remain < curSize)
+ curSize = (UInt32)remain;
+ res = WriteDataToStream(data, curSize);
+ }
+ _writtenFileSize += size;
+ return res;
+}
+
+HRESULT CDecoder::WriteArea(UInt32 startPtr, UInt32 endPtr)
+{
+ if (startPtr <= endPtr)
+ return WriteData(_window + startPtr, endPtr - startPtr);
+ RINOK(WriteData(_window + startPtr, kWindowSize - startPtr));
+ return WriteData(_window, endPtr);
+}
+
+void CDecoder::ExecuteFilter(int tempFilterIndex, NVm::CBlockRef &outBlockRef)
+{
+ CTempFilter *tempFilter = _tempFilters[tempFilterIndex];
+ tempFilter->InitR[6] = (UInt32)_writtenFileSize;
+ NVm::SetValue32(&tempFilter->GlobalData[0x24], (UInt32)_writtenFileSize);
+ NVm::SetValue32(&tempFilter->GlobalData[0x28], (UInt32)(_writtenFileSize >> 32));
+ CFilter *filter = _filters[tempFilter->FilterIndex];
+ _vm.Execute(filter, tempFilter, outBlockRef, filter->GlobalData);
+ delete tempFilter;
+ _tempFilters[tempFilterIndex] = 0;
+}
+
+HRESULT CDecoder::WriteBuf()
+{
+ UInt32 writtenBorder = _wrPtr;
+ UInt32 writeSize = (_winPos - writtenBorder) & kWindowMask;
+ for (int i = 0; i < _tempFilters.Size(); i++)
+ {
+ CTempFilter *filter = _tempFilters[i];
+ if (filter == NULL)
+ continue;
+ if (filter->NextWindow)
+ {
+ filter->NextWindow = false;
+ continue;
+ }
+ UInt32 blockStart = filter->BlockStart;
+ UInt32 blockSize = filter->BlockSize;
+ if (((blockStart - writtenBorder) & kWindowMask) < writeSize)
+ {
+ if (writtenBorder != blockStart)
+ {
+ RINOK(WriteArea(writtenBorder, blockStart));
+ writtenBorder = blockStart;
+ writeSize = (_winPos - writtenBorder) & kWindowMask;
+ }
+ if (blockSize <= writeSize)
+ {
+ UInt32 blockEnd = (blockStart + blockSize) & kWindowMask;
+ if (blockStart < blockEnd || blockEnd == 0)
+ _vm.SetMemory(0, _window + blockStart, blockSize);
+ else
+ {
+ UInt32 tailSize = kWindowSize - blockStart;
+ _vm.SetMemory(0, _window + blockStart, tailSize);
+ _vm.SetMemory(tailSize, _window, blockEnd);
+ }
+ NVm::CBlockRef outBlockRef;
+ ExecuteFilter(i, outBlockRef);
+ while (i + 1 < _tempFilters.Size())
+ {
+ CTempFilter *nextFilter = _tempFilters[i + 1];
+ if (nextFilter == NULL || nextFilter->BlockStart != blockStart ||
+ nextFilter->BlockSize != outBlockRef.Size || nextFilter->NextWindow)
+ break;
+ _vm.SetMemory(0, _vm.GetDataPointer(outBlockRef.Offset), outBlockRef.Size);
+ ExecuteFilter(++i, outBlockRef);
+ }
+ WriteDataToStream(_vm.GetDataPointer(outBlockRef.Offset), outBlockRef.Size);
+ _writtenFileSize += outBlockRef.Size;
+ writtenBorder = blockEnd;
+ writeSize = (_winPos - writtenBorder) & kWindowMask;
+ }
+ else
+ {
+ for (int j = i; j < _tempFilters.Size(); j++)
+ {
+ CTempFilter *filter = _tempFilters[j];
+ if (filter != NULL && filter->NextWindow)
+ filter->NextWindow = false;
+ }
+ _wrPtr = writtenBorder;
+ return S_OK; // check it
+ }
+ }
+ }
+
+ _wrPtr = _winPos;
+ return WriteArea(writtenBorder, _winPos);
+}
+
+void CDecoder::InitFilters()
+{
+ _lastFilter = 0;
+ int i;
+ for (i = 0; i < _tempFilters.Size(); i++)
+ delete _tempFilters[i];
+ _tempFilters.Clear();
+ for (i = 0; i < _filters.Size(); i++)
+ delete _filters[i];
+ _filters.Clear();
+}
+
+bool CDecoder::AddVmCode(UInt32 firstByte, UInt32 codeSize)
+{
+ CMemBitDecoder inp;
+ inp.Init(_vmData, codeSize);
+
+ UInt32 filterIndex;
+ if (firstByte & 0x80)
+ {
+ filterIndex = NVm::ReadEncodedUInt32(inp);
+ if (filterIndex == 0)
+ InitFilters();
+ else
+ filterIndex--;
+ }
+ else
+ filterIndex = _lastFilter;
+ if (filterIndex > (UInt32)_filters.Size())
+ return false;
+ _lastFilter = filterIndex;
+ bool newFilter = (filterIndex == (UInt32)_filters.Size());
+
+ CFilter *filter;
+ if (newFilter)
+ {
+ // check if too many filters
+ if (filterIndex > 1024)
+ return false;
+ filter = new CFilter;
+ _filters.Add(filter);
+ }
+ else
+ {
+ filter = _filters[filterIndex];
+ filter->ExecCount++;
+ }
+
+ int numEmptyItems = 0;
+ int i;
+ for (i = 0; i < _tempFilters.Size(); i++)
+ {
+ _tempFilters[i - numEmptyItems] = _tempFilters[i];
+ if (_tempFilters[i] == NULL)
+ numEmptyItems++;
+ if (numEmptyItems > 0)
+ _tempFilters[i] = NULL;
+ }
+ if (numEmptyItems == 0)
+ {
+ _tempFilters.Add(NULL);
+ numEmptyItems = 1;
+ }
+ CTempFilter *tempFilter = new CTempFilter;
+ _tempFilters[_tempFilters.Size() - numEmptyItems] = tempFilter;
+ tempFilter->FilterIndex = filterIndex;
+ tempFilter->ExecCount = filter->ExecCount;
+
+ UInt32 blockStart = NVm::ReadEncodedUInt32(inp);
+ if (firstByte & 0x40)
+ blockStart += 258;
+ tempFilter->BlockStart = (blockStart + _winPos) & kWindowMask;
+ if (firstByte & 0x20)
+ filter->BlockSize = NVm::ReadEncodedUInt32(inp);
+ tempFilter->BlockSize = filter->BlockSize;
+ tempFilter->NextWindow = _wrPtr != _winPos && ((_wrPtr - _winPos) & kWindowMask) <= blockStart;
+
+ memset(tempFilter->InitR, 0, sizeof(tempFilter->InitR));
+ tempFilter->InitR[3] = NVm::kGlobalOffset;
+ tempFilter->InitR[4] = tempFilter->BlockSize;
+ tempFilter->InitR[5] = tempFilter->ExecCount;
+ if (firstByte & 0x10)
+ {
+ UInt32 initMask = inp.ReadBits(NVm::kNumGpRegs);
+ for (int i = 0; i < NVm::kNumGpRegs; i++)
+ if (initMask & (1 << i))
+ tempFilter->InitR[i] = NVm::ReadEncodedUInt32(inp);
+ }
+ if (newFilter)
+ {
+ UInt32 vmCodeSize = NVm::ReadEncodedUInt32(inp);
+ if (vmCodeSize >= kVmCodeSizeMax || vmCodeSize == 0)
+ return false;
+ for (UInt32 i = 0; i < vmCodeSize; i++)
+ _vmCode[i] = (Byte)inp.ReadBits(8);
+ _vm.PrepareProgram(_vmCode, vmCodeSize, filter);
+ }
+
+ tempFilter->AllocateEmptyFixedGlobal();
+
+ Byte *globalData = &tempFilter->GlobalData[0];
+ for (i = 0; i < NVm::kNumGpRegs; i++)
+ NVm::SetValue32(&globalData[i * 4], tempFilter->InitR[i]);
+ NVm::SetValue32(&globalData[NVm::NGlobalOffset::kBlockSize], tempFilter->BlockSize);
+ NVm::SetValue32(&globalData[NVm::NGlobalOffset::kBlockPos], 0); // It was commented. why?
+ NVm::SetValue32(&globalData[NVm::NGlobalOffset::kExecCount], tempFilter->ExecCount);
+
+ if (firstByte & 8)
+ {
+ UInt32 dataSize = NVm::ReadEncodedUInt32(inp);
+ if (dataSize > NVm::kGlobalSize - NVm::kFixedGlobalSize)
+ return false;
+ CRecordVector<Byte> &globalData = tempFilter->GlobalData;
+ int requredSize = (int)(dataSize + NVm::kFixedGlobalSize);
+ if (globalData.Size() < requredSize)
+ {
+ globalData.Reserve(requredSize);
+ for (; globalData.Size() < requredSize; i++)
+ globalData.Add(0);
+ }
+ for (UInt32 i = 0; i < dataSize; i++)
+ globalData[NVm::kFixedGlobalSize + i] = (Byte)inp.ReadBits(8);
+ }
+ return true;
+}
+
+bool CDecoder::ReadVmCodeLZ()
+{
+ UInt32 firstByte = m_InBitStream.ReadBits(8);
+ UInt32 length = (firstByte & 7) + 1;
+ if (length == 7)
+ length = m_InBitStream.ReadBits(8) + 7;
+ else if (length == 8)
+ length = m_InBitStream.ReadBits(16);
+ if (length > kVmDataSizeMax)
+ return false;
+ for (UInt32 i = 0; i < length; i++)
+ _vmData[i] = (Byte)m_InBitStream.ReadBits(8);
+ return AddVmCode(firstByte, length);
+}
+
+bool CDecoder::ReadVmCodePPM()
+{
+ int firstByte = DecodePpmSymbol();
+ if (firstByte == -1)
+ return false;
+ UInt32 length = (firstByte & 7) + 1;
+ if (length == 7)
+ {
+ int b1 = DecodePpmSymbol();
+ if (b1 == -1)
+ return false;
+ length = b1 + 7;
+ }
+ else if (length == 8)
+ {
+ int b1 = DecodePpmSymbol();
+ if (b1 == -1)
+ return false;
+ int b2 = DecodePpmSymbol();
+ if (b2 == -1)
+ return false;
+ length = b1 * 256 + b2;
+ }
+ if (length > kVmDataSizeMax)
+ return false;
+ for (UInt32 i = 0; i < length; i++)
+ {
+ int b = DecodePpmSymbol();
+ if (b == -1)
+ return false;
+ _vmData[i] = (Byte)b;
+ }
+ return AddVmCode(firstByte, length);
+}
+
+#define RIF(x) { if (!(x)) return S_FALSE; }
+
+UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); }
+
+/////////////////////////////////////////////////
+// PPM
+
+HRESULT CDecoder::InitPPM()
+{
+ Byte maxOrder = (Byte)ReadBits(7);
+
+ bool reset = ((maxOrder & 0x20) != 0);
+ int maxMB = 0;
+ if (reset)
+ maxMB = (Byte)ReadBits(8);
+ else
+ {
+ if (_ppm.SubAllocator.GetSubAllocatorSize()== 0)
+ return S_FALSE;
+ }
+ if (maxOrder & 0x40)
+ PpmEscChar = (Byte)ReadBits(8);
+ m_InBitStream.InitRangeCoder();
+ /*
+ if (m_InBitStream.m_BitPos != 0)
+ return S_FALSE;
+ */
+ if (reset)
+ {
+ maxOrder = (maxOrder & 0x1F) + 1;
+ if (maxOrder > 16)
+ maxOrder = 16 + (maxOrder - 16) * 3;
+ if (maxOrder == 1)
+ {
+ // SubAlloc.StopSubAllocator();
+ _ppm.SubAllocator.StopSubAllocator();
+ return S_FALSE;
+ }
+ // SubAlloc.StartSubAllocator(MaxMB+1);
+ // StartModelRare(maxOrder);
+
+ if (!_ppm.SubAllocator.StartSubAllocator((maxMB + 1) << 20))
+ return E_OUTOFMEMORY;
+ _ppm.MaxOrder = 0;
+ _ppm.StartModelRare(maxOrder);
+
+ }
+ // return (minContext != NULL);
+
+ return S_OK;
+}
+
+int CDecoder::DecodePpmSymbol() { return _ppm.DecodeSymbol(&m_InBitStream); }
+
+HRESULT CDecoder::DecodePPM(Int32 num, bool &keepDecompressing)
+{
+ keepDecompressing = false;
+ do
+ {
+ if (((_wrPtr - _winPos) & kWindowMask) < 260 && _wrPtr != _winPos)
+ {
+ RINOK(WriteBuf());
+ if (_writtenFileSize > _unpackSize)
+ return S_OK;
+ }
+ int c = DecodePpmSymbol();
+ if (c == -1)
+ {
+ // Original code sets PPMError=true here and then it returns S_OK. Why ???
+ // return S_OK;
+ return S_FALSE;
+ }
+ if (c == PpmEscChar)
+ {
+ int nextCh = DecodePpmSymbol();
+ if (nextCh == 0)
+ return ReadTables(keepDecompressing);
+ if (nextCh == 2 || nextCh == -1)
+ return S_OK;
+ if (nextCh == 3)
+ {
+ if (!ReadVmCodePPM())
+ return S_FALSE;
+ continue;
+ }
+ if (nextCh == 4 || nextCh == 5)
+ {
+ UInt32 distance = 0;
+ UInt32 length = 4;
+ if (nextCh == 4)
+ {
+ for (int i = 0; i < 3; i++)
+ {
+ int c = DecodePpmSymbol();
+ if (c == -1)
+ return S_OK;
+ distance = (distance << 8) + (Byte)c;
+ }
+ distance++;
+ length += 28;
+ }
+ int c = DecodePpmSymbol();
+ if (c == -1)
+ return S_OK;
+ length += c;
+ if (distance >= _lzSize)
+ return S_FALSE;
+ CopyBlock(distance, length);
+ num -= (Int32)length;
+ continue;
+ }
+ }
+ PutByte((Byte)c);
+ num--;
+ }
+ while (num >= 0);
+ keepDecompressing = true;
+ return S_OK;
+}
+
+/////////////////////////////////////////////////
+// LZ
+
+HRESULT CDecoder::ReadTables(bool &keepDecompressing)
+{
+ keepDecompressing = true;
+ ReadBits((8 - m_InBitStream.GetBitPosition()) & 7);
+ if (ReadBits(1) != 0)
+ {
+ _lzMode = false;
+ return InitPPM();
+ }
+
+ _lzMode = true;
+ PrevAlignBits = 0;
+ PrevAlignCount = 0;
+
+ Byte levelLevels[kLevelTableSize];
+ Byte newLevels[kTablesSizesSum];
+
+ if (ReadBits(1) == 0)
+ memset(m_LastLevels, 0, kTablesSizesSum);
+
+ int i;
+ for (i = 0; i < kLevelTableSize; i++)
+ {
+ UInt32 length = ReadBits(4);
+ if (length == 15)
+ {
+ UInt32 zeroCount = ReadBits(4);
+ if (zeroCount != 0)
+ {
+ zeroCount += 2;
+ while (zeroCount-- > 0 && i < kLevelTableSize)
+ levelLevels[i++]=0;
+ i--;
+ continue;
+ }
+ }
+ levelLevels[i] = (Byte)length;
+ }
+ RIF(m_LevelDecoder.SetCodeLengths(levelLevels));
+ i = 0;
+ while (i < kTablesSizesSum)
+ {
+ UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
+ if (number < 16)
+ {
+ newLevels[i] = Byte((number + m_LastLevels[i]) & 15);
+ i++;
+ }
+ else if (number > kLevelTableSize)
+ return S_FALSE;
+ else
+ {
+ int num;
+ if (((number - 16) & 1) == 0)
+ num = ReadBits(3) + 3;
+ else
+ num = ReadBits(7) + 11;
+ if (number < 18)
+ {
+ if (i == 0)
+ return S_FALSE;
+ for (; num > 0 && i < kTablesSizesSum; num--, i++)
+ newLevels[i] = newLevels[i - 1];
+ }
+ else
+ {
+ for (; num > 0 && i < kTablesSizesSum; num--)
+ newLevels[i++] = 0;
+ }
+ }
+ }
+ TablesRead = true;
+
+ // original code has check here:
+ /*
+ if (InAddr > ReadTop)
+ {
+ keepDecompressing = false;
+ return true;
+ }
+ */
+
+ RIF(m_MainDecoder.SetCodeLengths(&newLevels[0]));
+ RIF(m_DistDecoder.SetCodeLengths(&newLevels[kMainTableSize]));
+ RIF(m_AlignDecoder.SetCodeLengths(&newLevels[kMainTableSize + kDistTableSize]));
+ RIF(m_LenDecoder.SetCodeLengths(&newLevels[kMainTableSize + kDistTableSize + kAlignTableSize]));
+
+ memcpy(m_LastLevels, newLevels, kTablesSizesSum);
+ return S_OK;
+}
+
+class CCoderReleaser
+{
+ CDecoder *m_Coder;
+public:
+ CCoderReleaser(CDecoder *coder): m_Coder(coder) {}
+ ~CCoderReleaser()
+ {
+ // m_Coder->m_OutWindowStream.Flush();
+ m_Coder->ReleaseStreams();
+ }
+};
+
+HRESULT CDecoder::ReadEndOfBlock(bool &keepDecompressing)
+{
+ if (ReadBits(1) != 0)
+ {
+ // old file
+ TablesRead = false;
+ return ReadTables(keepDecompressing);
+ }
+ // new file
+ keepDecompressing = false;
+ TablesRead = (ReadBits(1) == 0);
+ return S_OK;
+}
+
+UInt32 kDistStart[kDistTableSize];
+
+class CDistInit
+{
+public:
+ CDistInit() { Init(); }
+ void Init()
+ {
+ UInt32 start = 0;
+ for (UInt32 i = 0; i < kDistTableSize; i++)
+ {
+ kDistStart[i] = start;
+ start += (1 << kDistDirectBits[i]);
+ }
+ }
+} g_DistInit;
+
+HRESULT CDecoder::DecodeLZ(bool &keepDecompressing)
+{
+ UInt32 rep0 = _reps[0];
+ UInt32 rep1 = _reps[1];
+ UInt32 rep2 = _reps[2];
+ UInt32 rep3 = _reps[3];
+ UInt32 length = _lastLength;
+ for (;;)
+ {
+ if (((_wrPtr - _winPos) & kWindowMask) < 260 && _wrPtr != _winPos)
+ {
+ RINOK(WriteBuf());
+ if (_writtenFileSize > _unpackSize)
+ return S_OK;
+ }
+ UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
+ if (number < 256)
+ {
+ PutByte(Byte(number));
+
+ continue;
+ }
+ else if (number == kSymbolReadTable)
+ {
+ RINOK(ReadEndOfBlock(keepDecompressing));
+ break;
+ }
+ else if (number == 257)
+ {
+ if (!ReadVmCodeLZ())
+ return S_FALSE;
+ continue;
+ }
+ else if (number == 258)
+ {
+ }
+ else if (number < kSymbolRep + 4)
+ {
+ if (number != kSymbolRep)
+ {
+ UInt32 distance;
+ if (number == kSymbolRep + 1)
+ distance = rep1;
+ else
+ {
+ if (number == kSymbolRep + 2)
+ distance = rep2;
+ else
+ {
+ distance = rep3;
+ rep3 = rep2;
+ }
+ rep2 = rep1;
+ }
+ rep1 = rep0;
+ rep0 = distance;
+ }
+
+ UInt32 number = m_LenDecoder.DecodeSymbol(&m_InBitStream);
+ if (number >= kLenTableSize)
+ return S_FALSE;
+ length = 2 + kLenStart[number] + m_InBitStream.ReadBits(kLenDirectBits[number]);
+ }
+ else
+ {
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ if (number < 271)
+ {
+ number -= 263;
+ rep0 = kLen2DistStarts[number] + m_InBitStream.ReadBits(kLen2DistDirectBits[number]);
+ length = 2;
+ }
+ else if (number < 299)
+ {
+ number -= 271;
+ length = kNormalMatchMinLen + (UInt32)kLenStart[number] + m_InBitStream.ReadBits(kLenDirectBits[number]);
+ UInt32 number = m_DistDecoder.DecodeSymbol(&m_InBitStream);
+ if (number >= kDistTableSize)
+ return S_FALSE;
+ rep0 = kDistStart[number];
+ int numBits = kDistDirectBits[number];
+ if (number >= (kNumAlignBits * 2) + 2)
+ {
+ if (numBits > kNumAlignBits)
+ rep0 += (m_InBitStream.ReadBits(numBits - kNumAlignBits) << kNumAlignBits);
+ if (PrevAlignCount > 0)
+ {
+ PrevAlignCount--;
+ rep0 += PrevAlignBits;
+ }
+ else
+ {
+ UInt32 number = m_AlignDecoder.DecodeSymbol(&m_InBitStream);
+ if (number < (1 << kNumAlignBits))
+ {
+ rep0 += number;
+ PrevAlignBits = number;
+ }
+ else if (number == (1 << kNumAlignBits))
+ {
+ PrevAlignCount = kNumAlignReps;
+ rep0 += PrevAlignBits;
+ }
+ else
+ return S_FALSE;
+ }
+ }
+ else
+ rep0 += m_InBitStream.ReadBits(numBits);
+ length += ((kDistLimit4 - rep0) >> 31) + ((kDistLimit3 - rep0) >> 31);
+ }
+ else
+ return S_FALSE;
+ }
+ if (rep0 >= _lzSize)
+ return S_FALSE;
+ CopyBlock(rep0, length);
+ }
+ _reps[0] = rep0;
+ _reps[1] = rep1;
+ _reps[2] = rep2;
+ _reps[3] = rep3;
+ _lastLength = length;
+
+ return S_OK;
+}
+
+HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
+{
+ _writtenFileSize = 0;
+ if (!m_IsSolid)
+ {
+ _lzSize = 0;
+ _winPos = 0;
+ _wrPtr = 0;
+ for (int i = 0; i < kNumReps; i++)
+ _reps[i] = 0;
+ _lastLength = 0;
+ memset(m_LastLevels, 0, kTablesSizesSum);
+ TablesRead = false;
+ PpmEscChar = 2;
+ InitFilters();
+ }
+ if (!m_IsSolid || !TablesRead)
+ {
+ bool keepDecompressing;
+ RINOK(ReadTables(keepDecompressing));
+ if (!keepDecompressing)
+ return S_OK;
+ }
+
+ for(;;)
+ {
+ bool keepDecompressing;
+ if (_lzMode)
+ {
+ RINOK(DecodeLZ(keepDecompressing))
+ }
+ else
+ {
+ RINOK(DecodePPM(1 << 18, keepDecompressing))
+ }
+ UInt64 packSize = m_InBitStream.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize));
+ if (!keepDecompressing)
+ break;
+ }
+ RINOK(WriteBuf());
+ if (_writtenFileSize < _unpackSize)
+ return S_FALSE;
+ // return m_OutWindowStream.Flush();
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ try
+ {
+ if (inSize == NULL || outSize == NULL)
+ return E_INVALIDARG;
+
+ if (_vmData == 0)
+ {
+ _vmData = (Byte *)::MidAlloc(kVmDataSizeMax + kVmCodeSizeMax);
+ if (_vmData == 0)
+ return E_OUTOFMEMORY;
+ _vmCode = _vmData + kVmDataSizeMax;
+ }
+
+ if (_window == 0)
+ {
+ _window = (Byte *)::MidAlloc(kWindowSize);
+ if (_window == 0)
+ return E_OUTOFMEMORY;
+ }
+ if (!m_InBitStream.Create(1 << 20))
+ return E_OUTOFMEMORY;
+ if (!_vm.Create())
+ return E_OUTOFMEMORY;
+
+
+ m_InBitStream.SetStream(inStream);
+ m_InBitStream.Init();
+ _outStream = outStream;
+
+ CCoderReleaser coderReleaser(this);
+ _unpackSize = *outSize;
+ return CodeReal(progress);
+ }
+ catch(...) { return S_FALSE; }
+ // CNewException is possible here. But probably CNewException is caused
+ // by error in data stream.
+}
+
+STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
+{
+ if (size < 1)
+ return E_INVALIDARG;
+ m_IsSolid = (data[0] != 0);
+ return S_OK;
+}
+
+}}
diff --git a/CPP/7zip/Compress/Rar/Rar3Decoder.h b/CPP/7zip/Compress/Rar/Rar3Decoder.h
new file mode 100755
index 00000000..ec07a4d3
--- /dev/null
+++ b/CPP/7zip/Compress/Rar/Rar3Decoder.h
@@ -0,0 +1,294 @@
+// Rar3Decoder.h
+// According to unRAR license,
+// this code may not be used to develop a
+// RAR (WinRAR) compatible archiver
+
+#ifndef __RAR3DECODER_H
+#define __RAR3DECODER_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 "../PPMD/PPMDDecode.h"
+#include "Rar3Vm.h"
+
+namespace NCompress {
+namespace NRar3 {
+
+const UInt32 kWindowSize = 1 << 22;
+const UInt32 kWindowMask = (kWindowSize - 1);
+
+const UInt32 kNumReps = 4;
+const UInt32 kNumLen2Symbols = 8;
+const UInt32 kLenTableSize = 28;
+const UInt32 kMainTableSize = 256 + 1 + 1 + 1 + kNumReps + kNumLen2Symbols + kLenTableSize;
+const UInt32 kDistTableSize = 60;
+
+const int kNumAlignBits = 4;
+const UInt32 kAlignTableSize = (1 << kNumAlignBits) + 1;
+
+const UInt32 kLevelTableSize = 20;
+
+const UInt32 kTablesSizesSum = kMainTableSize + kDistTableSize + kAlignTableSize + kLenTableSize;
+
+template<class TInByte>
+class CBitDecoder2
+{
+ UInt32 m_Value;
+public:
+ UInt32 m_BitPos;
+ 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();}
+
+ void Init()
+ {
+ m_Stream.Init();
+ m_BitPos = 0;
+ m_Value = 0;
+ // m_BitPos = kNumBigValueBits;
+ // Normalize();
+ }
+
+ UInt64 GetProcessedSize() const
+ { return m_Stream.GetProcessedSize() - (m_BitPos) / 8; }
+ UInt32 GetBitPosition() const { return ((8 - m_BitPos) & 7); }
+
+ /*
+ void Normalize()
+ {
+ for (;m_BitPos >= 8; m_BitPos -= 8)
+ m_Value = (m_Value << 8) | m_Stream.ReadByte();
+ }
+ */
+
+ UInt32 GetValue(UInt32 numBits)
+ {
+ // return (m_Value << m_BitPos) >> (kNumBigValueBits - numBits);
+ // return ((m_Value >> (8 - m_BitPos)) & kMask) >> (kNumValueBits - numBits);
+ if (m_BitPos < numBits)
+ {
+ m_BitPos += 8;
+ m_Value = (m_Value << 8) | m_Stream.ReadByte();
+ if (m_BitPos < numBits)
+ {
+ m_BitPos += 8;
+ m_Value = (m_Value << 8) | m_Stream.ReadByte();
+ }
+ }
+ return m_Value >> (m_BitPos - numBits);
+ }
+
+ void MovePos(UInt32 numBits)
+ {
+ m_BitPos -= numBits;
+ m_Value = m_Value & ((1 << m_BitPos) - 1);
+ }
+
+ UInt32 ReadBits(UInt32 numBits)
+ {
+ UInt32 res = GetValue(numBits);
+ MovePos(numBits);
+ return res;
+ }
+};
+
+typedef CBitDecoder2<CInBuffer> CBitDecoder;
+
+const int kNumTopBits = 24;
+const UInt32 kTopValue = (1 << kNumTopBits);
+const UInt32 kBot = (1 << 15);
+
+class CRangeDecoder:public NPPMD::CRangeDecoderVirt, public CBitDecoder
+{
+public:
+ UInt32 Range;
+ UInt32 Low;
+ UInt32 Code;
+
+ void Normalize()
+ {
+ while ((Low ^ (Low + Range)) < kTopValue ||
+ Range < kBot && ((Range = (0 - Low) & (kBot - 1)), 1))
+ {
+ Code = (Code << 8) | m_Stream.ReadByte();
+ Range <<= 8;
+ Low <<= 8;
+ }
+ }
+
+ void InitRangeCoder()
+ {
+ Code = 0;
+ Low = 0;
+ Range = 0xFFFFFFFF;
+ for(int i = 0; i < 4; i++)
+ Code = (Code << 8) | ReadBits(8);
+ }
+
+ virtual UInt32 GetThreshold(UInt32 total)
+ {
+ return (Code - Low) / ( Range /= total);
+ }
+
+ virtual void Decode(UInt32 start, UInt32 size)
+ {
+ Low += start * Range;
+ Range *= size;
+ Normalize();
+ }
+
+ virtual UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits)
+ {
+ if (((Code - Low) / (Range >>= numTotalBits)) < size0)
+ {
+ Decode(0, size0);
+ return 0;
+ }
+ else
+ {
+ Decode(size0, (1 << numTotalBits) - size0);
+ return 1;
+ }
+ }
+
+ // UInt64 GetProcessedSizeRangeCoder() {return Stream.GetProcessedSize(); }
+};
+
+
+struct CFilter: public NVm::CProgram
+{
+ CRecordVector<Byte> GlobalData;
+ UInt32 BlockStart;
+ UInt32 BlockSize;
+ UInt32 ExecCount;
+ CFilter(): BlockStart(0), BlockSize(0), ExecCount(0) {}
+};
+
+struct CTempFilter: public NVm::CProgramInitState
+{
+ UInt32 BlockStart;
+ UInt32 BlockSize;
+ UInt32 ExecCount;
+ bool NextWindow;
+
+ UInt32 FilterIndex;
+};
+
+const int kNumHuffmanBits = 15;
+
+class CDecoder:
+ public ICompressCoder,
+ public ICompressSetDecoderProperties2,
+ public CMyUnknownImp
+{
+ CRangeDecoder m_InBitStream;
+ Byte *_window;
+ UInt32 _winPos;
+ UInt32 _wrPtr;
+ UInt64 _lzSize;
+ UInt64 _unpackSize;
+ UInt64 _writtenFileSize; // if it's > _unpackSize, then _unpackSize only written
+ CMyComPtr<ISequentialOutStream> _outStream;
+ NHuffman::CDecoder<kNumHuffmanBits, kMainTableSize> m_MainDecoder;
+ NHuffman::CDecoder<kNumHuffmanBits, kDistTableSize> m_DistDecoder;
+ NHuffman::CDecoder<kNumHuffmanBits, kAlignTableSize> m_AlignDecoder;
+ NHuffman::CDecoder<kNumHuffmanBits, kLenTableSize> m_LenDecoder;
+ NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder;
+
+ UInt32 _reps[kNumReps];
+ UInt32 _lastLength;
+
+ Byte m_LastLevels[kTablesSizesSum];
+
+ Byte *_vmData;
+ Byte *_vmCode;
+ NVm::CVm _vm;
+ CRecordVector<CFilter *> _filters;
+ CRecordVector<CTempFilter *> _tempFilters;
+ UInt32 _lastFilter;
+
+ bool m_IsSolid;
+
+ bool _lzMode;
+
+ UInt32 PrevAlignBits;
+ UInt32 PrevAlignCount;
+
+ bool TablesRead;
+
+ NPPMD::CDecodeInfo _ppm;
+ int PpmEscChar;
+
+ HRESULT WriteDataToStream(const Byte *data, UInt32 size);
+ HRESULT WriteData(const Byte *data, UInt32 size);
+ HRESULT WriteArea(UInt32 startPtr, UInt32 endPtr);
+ void ExecuteFilter(int tempFilterIndex, NVm::CBlockRef &outBlockRef);
+ HRESULT WriteBuf();
+
+ void InitFilters();
+ bool AddVmCode(UInt32 firstByte, UInt32 codeSize);
+ bool ReadVmCodeLZ();
+ bool ReadVmCodePPM();
+
+ UInt32 ReadBits(int numBits);
+
+ HRESULT InitPPM();
+ int DecodePpmSymbol();
+ HRESULT DecodePPM(Int32 num, bool &keepDecompressing);
+
+ HRESULT ReadTables(bool &keepDecompressing);
+ HRESULT ReadEndOfBlock(bool &keepDecompressing);
+ HRESULT DecodeLZ(bool &keepDecompressing);
+ HRESULT CodeReal(ICompressProgressInfo *progress);
+public:
+ CDecoder();
+ ~CDecoder();
+
+ MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)
+
+ void ReleaseStreams()
+ {
+ _outStream.Release();
+ m_InBitStream.ReleaseStream();
+ }
+
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+
+ void CopyBlock(UInt32 distance, UInt32 len)
+ {
+ _lzSize += len;
+ UInt32 pos = (_winPos - distance - 1) & kWindowMask;
+ do
+ {
+ _window[_winPos] = _window[pos];
+ _winPos = (_winPos + 1) & kWindowMask;
+ pos = (pos + 1) & kWindowMask;
+ }
+ while(--len != 0);
+ }
+
+ void PutByte(Byte b)
+ {
+ _window[_winPos] = b;
+ _winPos = (_winPos + 1) & kWindowMask;
+ _lzSize++;
+ }
+
+
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Compress/Rar/Rar3Vm.cpp b/CPP/7zip/Compress/Rar/Rar3Vm.cpp
new file mode 100755
index 00000000..69918d94
--- /dev/null
+++ b/CPP/7zip/Compress/Rar/Rar3Vm.cpp
@@ -0,0 +1,1089 @@
+// Rar3Vm.cpp
+// According to unRAR license,
+// this code may not be used to develop a
+// RAR (WinRAR) compatible archiver
+
+/*
+Note:
+ Due to performance considerations Rar VM may set Flags C incorrectly
+ for some operands (SHL x, 0, ... ).
+ Check implementation of concrete VM command
+ to see if it sets flags right.
+*/
+
+#include "StdAfx.h"
+
+#include "Rar3Vm.h"
+#include "Common/CRC.h"
+#include "Common/Alloc.h"
+
+namespace NCompress {
+namespace NRar3 {
+
+UInt32 CMemBitDecoder::ReadBits(int numBits)
+{
+ UInt32 res = 0;
+ for (;;)
+ {
+ Byte b = _bitPos < _bitSize ? _data[_bitPos >> 3] : 0;
+ int avail = (int)(8 - (_bitPos & 7));
+ if (numBits <= avail)
+ {
+ _bitPos += numBits;
+ return res | (b >> (avail - numBits)) & ((1 << numBits) - 1);
+ }
+ numBits -= avail;
+ res |= (UInt32)(b & ((1 << avail) - 1)) << numBits;
+ _bitPos += avail;
+ }
+}
+
+UInt32 CMemBitDecoder::ReadBit() { return ReadBits(1); }
+
+namespace NVm {
+
+const UInt32 kStackRegIndex = kNumRegs - 1;
+
+enum EFlags {FLAG_C = 1, FLAG_Z = 2, FLAG_S = 0x80000000};
+
+const Byte CF_OP0 = 0;
+const Byte CF_OP1 = 1;
+const Byte CF_OP2 = 2;
+const Byte CF_OPMASK = 3;
+const Byte CF_BYTEMODE = 4;
+const Byte CF_JUMP = 8;
+const Byte CF_PROC = 16;
+const Byte CF_USEFLAGS = 32;
+const Byte CF_CHFLAGS = 64;
+
+static Byte kCmdFlags[]=
+{
+ /* CMD_MOV */ CF_OP2 | CF_BYTEMODE,
+ /* CMD_CMP */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS,
+ /* CMD_ADD */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS,
+ /* CMD_SUB */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS,
+ /* CMD_JZ */ CF_OP1 | CF_JUMP | CF_USEFLAGS,
+ /* CMD_JNZ */ CF_OP1 | CF_JUMP | CF_USEFLAGS,
+ /* CMD_INC */ CF_OP1 | CF_BYTEMODE | CF_CHFLAGS,
+ /* CMD_DEC */ CF_OP1 | CF_BYTEMODE | CF_CHFLAGS,
+ /* CMD_JMP */ CF_OP1 | CF_JUMP,
+ /* CMD_XOR */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS,
+ /* CMD_AND */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS,
+ /* CMD_OR */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS,
+ /* CMD_TEST */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS,
+ /* CMD_JS */ CF_OP1 | CF_JUMP | CF_USEFLAGS,
+ /* CMD_JNS */ CF_OP1 | CF_JUMP | CF_USEFLAGS,
+ /* CMD_JB */ CF_OP1 | CF_JUMP | CF_USEFLAGS,
+ /* CMD_JBE */ CF_OP1 | CF_JUMP | CF_USEFLAGS,
+ /* CMD_JA */ CF_OP1 | CF_JUMP | CF_USEFLAGS,
+ /* CMD_JAE */ CF_OP1 | CF_JUMP | CF_USEFLAGS,
+ /* CMD_PUSH */ CF_OP1,
+ /* CMD_POP */ CF_OP1,
+ /* CMD_CALL */ CF_OP1 | CF_PROC,
+ /* CMD_RET */ CF_OP0 | CF_PROC,
+ /* CMD_NOT */ CF_OP1 | CF_BYTEMODE,
+ /* CMD_SHL */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS,
+ /* CMD_SHR */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS,
+ /* CMD_SAR */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS,
+ /* CMD_NEG */ CF_OP1 | CF_BYTEMODE | CF_CHFLAGS,
+ /* CMD_PUSHA */ CF_OP0,
+ /* CMD_POPA */ CF_OP0,
+ /* CMD_PUSHF */ CF_OP0 | CF_USEFLAGS,
+ /* CMD_POPF */ CF_OP0 | CF_CHFLAGS,
+ /* CMD_MOVZX */ CF_OP2,
+ /* CMD_MOVSX */ CF_OP2,
+ /* CMD_XCHG */ CF_OP2 | CF_BYTEMODE,
+ /* CMD_MUL */ CF_OP2 | CF_BYTEMODE,
+ /* CMD_DIV */ CF_OP2 | CF_BYTEMODE,
+ /* CMD_ADC */ CF_OP2 | CF_BYTEMODE | CF_USEFLAGS | CF_CHFLAGS ,
+ /* CMD_SBB */ CF_OP2 | CF_BYTEMODE | CF_USEFLAGS | CF_CHFLAGS ,
+ /* CMD_PRINT */ CF_OP0
+};
+
+CVm::CVm(): Mem(NULL) {}
+
+bool CVm::Create()
+{
+ if (Mem == NULL)
+ Mem = (Byte *)::MyAlloc(kSpaceSize + 4);
+ return (Mem != NULL);
+}
+
+CVm::~CVm()
+{
+ ::MyFree(Mem);
+}
+
+// CVm::Execute can change CProgram object: it clears progarm if VM returns error.
+
+bool CVm::Execute(CProgram *prg, const CProgramInitState *initState,
+ CBlockRef &outBlockRef, CRecordVector<Byte> &outGlobalData)
+{
+ memcpy(R, initState->InitR, sizeof(initState->InitR));
+ R[kStackRegIndex] = kSpaceSize;
+ R[kNumRegs] = 0;
+ Flags = 0;
+
+ UInt32 globalSize = MyMin((UInt32)initState->GlobalData.Size(), kGlobalSize);
+ if (globalSize != 0)
+ memcpy(Mem + kGlobalOffset, &initState->GlobalData[0], globalSize);
+ UInt32 staticSize = MyMin((UInt32)prg->StaticData.Size(), kGlobalSize - globalSize);
+ if (staticSize != 0)
+ memcpy(Mem + kGlobalOffset + globalSize, &prg->StaticData[0], staticSize);
+
+ bool res = true;
+ #ifdef RARVM_STANDARD_FILTERS
+ if (prg->StandardFilterIndex >= 0)
+ ExecuteStandardFilter(prg->StandardFilterIndex);
+ else
+ #endif
+ {
+ res = ExecuteCode(prg);
+ if (!res)
+ prg->Commands[0].OpCode = CMD_RET;
+ }
+ UInt32 newBlockPos = GetFixedGlobalValue32(NGlobalOffset::kBlockPos) & kSpaceMask;
+ UInt32 newBlockSize = GetFixedGlobalValue32(NGlobalOffset::kBlockSize) & kSpaceMask;
+ if (newBlockPos + newBlockSize >= kSpaceSize)
+ newBlockPos = newBlockSize = 0;
+ outBlockRef.Offset = newBlockPos;
+ outBlockRef.Size = newBlockSize;
+
+ outGlobalData.Clear();
+ UInt32 dataSize = GetFixedGlobalValue32(NGlobalOffset::kGlobalMemOutSize);
+ dataSize = MyMin(dataSize, kGlobalSize - kFixedGlobalSize);
+ if (dataSize != 0)
+ {
+ dataSize += kFixedGlobalSize;
+ outGlobalData.Reserve(dataSize);
+ for (UInt32 i = 0; i < dataSize; i++)
+ outGlobalData.Add(Mem[kGlobalOffset + i]);
+ }
+ return res;
+}
+
+
+#define SET_IP(IP) \
+ if ((IP) >= numCommands) return true; \
+ if (--maxOpCount <= 0) return false; \
+ cmd = commands + (IP);
+
+#define GET_FLAG_S_B(res) (((res) & 0x80) ? FLAG_S : 0)
+#define SET_IP_OP1 { UInt32 val = GetOperand32(&cmd->Op1); SET_IP(val); }
+#define FLAGS_UPDATE_SZ Flags = res == 0 ? FLAG_Z : res & FLAG_S
+#define FLAGS_UPDATE_SZ_B Flags = (res & 0xFF) == 0 ? FLAG_Z : GET_FLAG_S_B(res)
+
+UInt32 CVm::GetOperand32(const COperand *op) const
+{
+ switch(op->Type)
+ {
+ case OP_TYPE_REG: return R[op->Data];
+ case OP_TYPE_REGMEM: return GetValue32(&Mem[(op->Base + R[op->Data]) & kSpaceMask]);
+ default: return op->Data;
+ }
+}
+
+void CVm::SetOperand32(const COperand *op, UInt32 val)
+{
+ switch(op->Type)
+ {
+ case OP_TYPE_REG: R[op->Data] = val; return;
+ case OP_TYPE_REGMEM: SetValue32(&Mem[(op->Base + R[op->Data]) & kSpaceMask], val); return;
+ }
+}
+
+Byte CVm::GetOperand8(const COperand *op) const
+{
+ switch(op->Type)
+ {
+ case OP_TYPE_REG: return (Byte)R[op->Data];
+ case OP_TYPE_REGMEM: return Mem[(op->Base + R[op->Data]) & kSpaceMask];;
+ default: return (Byte)op->Data;
+ }
+}
+
+void CVm::SetOperand8(const COperand *op, Byte val)
+{
+ switch(op->Type)
+ {
+ case OP_TYPE_REG: R[op->Data] = (R[op->Data] & 0xFFFFFF00) | val; return;
+ case OP_TYPE_REGMEM: Mem[(op->Base + R[op->Data]) & kSpaceMask] = val; return;
+ }
+}
+
+UInt32 CVm::GetOperand(bool byteMode, const COperand *op) const
+{
+ if (byteMode)
+ return GetOperand8(op);
+ return GetOperand32(op);
+}
+
+void CVm::SetOperand(bool byteMode, const COperand *op, UInt32 val)
+{
+ if (byteMode)
+ SetOperand8(op, (Byte)(val & 0xFF));
+ else
+ SetOperand32(op, val);
+}
+
+bool CVm::ExecuteCode(const CProgram *prg)
+{
+ Int32 maxOpCount = 25000000;
+ const CCommand *commands = &prg->Commands[0];
+ const CCommand *cmd = commands;
+ UInt32 numCommands = prg->Commands.Size();
+ for (;;)
+ {
+ switch(cmd->OpCode)
+ {
+ #ifndef RARVM_NO_VM
+
+ case CMD_MOV:
+ SetOperand32(&cmd->Op1, GetOperand32(&cmd->Op2));
+ break;
+ case CMD_MOVB:
+ SetOperand8(&cmd->Op1, GetOperand8(&cmd->Op2));
+ break;
+ case CMD_CMP:
+ {
+ UInt32 v1 = GetOperand32(&cmd->Op1);
+ UInt32 res = v1 - GetOperand32(&cmd->Op2);
+ Flags = res == 0 ? FLAG_Z : (res > v1) | (res & FLAG_S);
+ }
+ break;
+ case CMD_CMPB:
+ {
+ Byte v1 = GetOperand8(&cmd->Op1);
+ Byte res = v1 - GetOperand8(&cmd->Op2);
+ res &= 0xFF;
+ Flags = res == 0 ? FLAG_Z : (res > v1) | GET_FLAG_S_B(res);
+ }
+ break;
+ case CMD_ADD:
+ {
+ UInt32 v1 = GetOperand32(&cmd->Op1);
+ UInt32 res = v1 + GetOperand32(&cmd->Op2);
+ SetOperand32(&cmd->Op1, res);
+ Flags = (res < v1) | (res == 0 ? FLAG_Z : (res & FLAG_S));
+ }
+ break;
+ case CMD_ADDB:
+ {
+ Byte v1 = GetOperand8(&cmd->Op1);
+ Byte res = v1 + GetOperand8(&cmd->Op2);
+ res &= 0xFF;
+ SetOperand8(&cmd->Op1, (Byte)res);
+ Flags = (res < v1) | (res == 0 ? FLAG_Z : GET_FLAG_S_B(res));
+ }
+ break;
+ case CMD_ADC:
+ {
+ UInt32 v1 = GetOperand(cmd->ByteMode, &cmd->Op1);
+ UInt32 FC = (Flags & FLAG_C);
+ UInt32 res = v1 + GetOperand(cmd->ByteMode, &cmd->Op2) + FC;
+ if (cmd->ByteMode)
+ res &= 0xFF;
+ SetOperand(cmd->ByteMode, &cmd->Op1, res);
+ Flags = (res < v1 || res == v1 && FC) | (res == 0 ? FLAG_Z : (res & FLAG_S));
+ }
+ break;
+ case CMD_SUB:
+ {
+ UInt32 v1 = GetOperand32(&cmd->Op1);
+ UInt32 res = v1 - GetOperand32(&cmd->Op2);
+ SetOperand32(&cmd->Op1, res);
+ Flags = res == 0 ? FLAG_Z : (res > v1) | (res & FLAG_S);
+ }
+ break;
+ case CMD_SUBB:
+ {
+ UInt32 v1 = GetOperand8(&cmd->Op1);
+ UInt32 res = v1 - GetOperand8(&cmd->Op2);
+ SetOperand8(&cmd->Op1, (Byte)res);
+ Flags = res == 0 ? FLAG_Z : (res > v1) | (res & FLAG_S);
+ }
+ break;
+ case CMD_SBB:
+ {
+ UInt32 v1 = GetOperand(cmd->ByteMode, &cmd->Op1);
+ UInt32 FC = (Flags & FLAG_C);
+ UInt32 res = v1 - GetOperand(cmd->ByteMode, &cmd->Op2) - FC;
+ // Flags = res == 0 ? FLAG_Z : (res > v1 || res == v1 && FC) | (res & FLAG_S);
+ if (cmd->ByteMode)
+ res &= 0xFF;
+ SetOperand(cmd->ByteMode, &cmd->Op1, res);
+ Flags = (res > v1 || res == v1 && FC) | (res == 0 ? FLAG_Z : (res & FLAG_S));
+ }
+ break;
+ case CMD_INC:
+ {
+ UInt32 res = GetOperand32(&cmd->Op1) + 1;
+ SetOperand32(&cmd->Op1, res);
+ FLAGS_UPDATE_SZ;
+ }
+ break;
+ case CMD_INCB:
+ {
+ Byte res = GetOperand8(&cmd->Op1) + 1;
+ SetOperand8(&cmd->Op1, res);;
+ FLAGS_UPDATE_SZ_B;
+ }
+ break;
+ case CMD_DEC:
+ {
+ UInt32 res = GetOperand32(&cmd->Op1) - 1;
+ SetOperand32(&cmd->Op1, res);
+ FLAGS_UPDATE_SZ;
+ }
+ break;
+ case CMD_DECB:
+ {
+ Byte res = GetOperand8(&cmd->Op1) - 1;
+ SetOperand8(&cmd->Op1, res);;
+ FLAGS_UPDATE_SZ_B;
+ }
+ break;
+ case CMD_XOR:
+ {
+ UInt32 res = GetOperand32(&cmd->Op1) ^ GetOperand32(&cmd->Op2);
+ SetOperand32(&cmd->Op1, res);
+ FLAGS_UPDATE_SZ;
+ }
+ break;
+ case CMD_XORB:
+ {
+ Byte res = GetOperand8(&cmd->Op1) ^ GetOperand8(&cmd->Op2);
+ SetOperand8(&cmd->Op1, res);
+ FLAGS_UPDATE_SZ_B;
+ }
+ break;
+ case CMD_AND:
+ {
+ UInt32 res = GetOperand32(&cmd->Op1) & GetOperand32(&cmd->Op2);
+ SetOperand32(&cmd->Op1, res);
+ FLAGS_UPDATE_SZ;
+ }
+ break;
+ case CMD_ANDB:
+ {
+ Byte res = GetOperand8(&cmd->Op1) & GetOperand8(&cmd->Op2);
+ SetOperand8(&cmd->Op1, res);
+ FLAGS_UPDATE_SZ_B;
+ }
+ break;
+ case CMD_OR:
+ {
+ UInt32 res = GetOperand32(&cmd->Op1) | GetOperand32(&cmd->Op2);
+ SetOperand32(&cmd->Op1, res);
+ FLAGS_UPDATE_SZ;
+ }
+ break;
+ case CMD_ORB:
+ {
+ Byte res = GetOperand8(&cmd->Op1) | GetOperand8(&cmd->Op2);
+ SetOperand8(&cmd->Op1, res);
+ FLAGS_UPDATE_SZ_B;
+ }
+ break;
+ case CMD_TEST:
+ {
+ UInt32 res = GetOperand32(&cmd->Op1) & GetOperand32(&cmd->Op2);
+ FLAGS_UPDATE_SZ;
+ }
+ break;
+ case CMD_TESTB:
+ {
+ Byte res = GetOperand8(&cmd->Op1) & GetOperand8(&cmd->Op2);
+ FLAGS_UPDATE_SZ_B;
+ }
+ break;
+ case CMD_NOT:
+ SetOperand(cmd->ByteMode, &cmd->Op1, ~GetOperand(cmd->ByteMode, &cmd->Op1));
+ break;
+ case CMD_NEG:
+ {
+ UInt32 res = 0 - GetOperand32(&cmd->Op1);
+ SetOperand32(&cmd->Op1, res);
+ Flags = res == 0 ? FLAG_Z : FLAG_C | (res & FLAG_S);
+ }
+ break;
+ case CMD_NEGB:
+ {
+ Byte res = (Byte)(0 - GetOperand8(&cmd->Op1));
+ SetOperand8(&cmd->Op1, res);
+ Flags = res == 0 ? FLAG_Z : FLAG_C | GET_FLAG_S_B(res);
+ }
+ break;
+
+ case CMD_SHL:
+ {
+ UInt32 v1 = GetOperand32(&cmd->Op1);
+ int v2 = (int)GetOperand32(&cmd->Op2);
+ UInt32 res = v1 << v2;
+ SetOperand32(&cmd->Op1, res);
+ Flags = (res == 0 ? FLAG_Z : (res & FLAG_S)) | ((v1 << (v2 - 1)) & 0x80000000 ? FLAG_C : 0);
+ }
+ break;
+ case CMD_SHLB:
+ {
+ Byte v1 = GetOperand8(&cmd->Op1);
+ int v2 = (int)GetOperand8(&cmd->Op2);
+ Byte res = (Byte)(v1 << v2);
+ SetOperand8(&cmd->Op1, res);
+ Flags = (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)) | ((v1 << (v2 - 1)) & 0x80 ? FLAG_C : 0);
+ }
+ break;
+ case CMD_SHR:
+ {
+ UInt32 v1 = GetOperand32(&cmd->Op1);
+ int v2 = (int)GetOperand32(&cmd->Op2);
+ UInt32 res = v1 >> v2;
+ SetOperand32(&cmd->Op1, res);
+ Flags = (res == 0 ? FLAG_Z : (res & FLAG_S)) | ((v1 >> (v2 - 1)) & FLAG_C);
+ }
+ break;
+ case CMD_SHRB:
+ {
+ Byte v1 = GetOperand8(&cmd->Op1);
+ int v2 = (int)GetOperand8(&cmd->Op2);
+ Byte res = (Byte)(v1 >> v2);
+ SetOperand8(&cmd->Op1, res);
+ Flags = (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)) | ((v1 >> (v2 - 1)) & FLAG_C);
+ }
+ break;
+ case CMD_SAR:
+ {
+ UInt32 v1 = GetOperand32(&cmd->Op1);
+ int v2 = (int)GetOperand32(&cmd->Op2);
+ UInt32 res = UInt32(((Int32)v1) >> v2);
+ SetOperand32(&cmd->Op1, res);
+ Flags= (res == 0 ? FLAG_Z : (res & FLAG_S)) | ((v1 >> (v2 - 1)) & FLAG_C);
+ }
+ break;
+ case CMD_SARB:
+ {
+ Byte v1 = GetOperand8(&cmd->Op1);
+ int v2 = (int)GetOperand8(&cmd->Op2);
+ Byte res = (Byte)(((signed char)v1) >> v2);
+ SetOperand8(&cmd->Op1, res);
+ Flags= (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)) | ((v1 >> (v2 - 1)) & FLAG_C);
+ }
+ break;
+
+ case CMD_JMP:
+ SET_IP_OP1;
+ continue;
+ case CMD_JZ:
+ if ((Flags & FLAG_Z) != 0)
+ {
+ SET_IP_OP1;
+ continue;
+ }
+ break;
+ case CMD_JNZ:
+ if ((Flags & FLAG_Z) == 0)
+ {
+ SET_IP_OP1;
+ continue;
+ }
+ break;
+ case CMD_JS:
+ if ((Flags & FLAG_S) != 0)
+ {
+ SET_IP_OP1;
+ continue;
+ }
+ break;
+ case CMD_JNS:
+ if ((Flags & FLAG_S) == 0)
+ {
+ SET_IP_OP1;
+ continue;
+ }
+ break;
+ case CMD_JB:
+ if ((Flags & FLAG_C) != 0)
+ {
+ SET_IP_OP1;
+ continue;
+ }
+ break;
+ case CMD_JBE:
+ if ((Flags & (FLAG_C | FLAG_Z)) != 0)
+ {
+ SET_IP_OP1;
+ continue;
+ }
+ break;
+ case CMD_JA:
+ if ((Flags & (FLAG_C | FLAG_Z)) == 0)
+ {
+ SET_IP_OP1;
+ continue;
+ }
+ break;
+ case CMD_JAE:
+ if ((Flags & FLAG_C) == 0)
+ {
+ SET_IP_OP1;
+ continue;
+ }
+ break;
+
+ case CMD_PUSH:
+ R[kStackRegIndex] -= 4;
+ SetValue32(&Mem[R[kStackRegIndex] & kSpaceMask], GetOperand32(&cmd->Op1));
+ break;
+ case CMD_POP:
+ SetOperand32(&cmd->Op1, GetValue32(&Mem[R[kStackRegIndex] & kSpaceMask]));
+ R[kStackRegIndex] += 4;
+ break;
+ case CMD_CALL:
+ R[kStackRegIndex] -= 4;
+ SetValue32(&Mem[R[kStackRegIndex] & kSpaceMask], (UInt32)(cmd - commands + 1));
+ SET_IP_OP1;
+ continue;
+
+ case CMD_PUSHA:
+ {
+ for (UInt32 i = 0, SP = R[kStackRegIndex] - 4; i < kNumRegs; i++, SP -= 4)
+ SetValue32(&Mem[SP & kSpaceMask], R[i]);
+ R[kStackRegIndex] -= kNumRegs * 4;
+ }
+ break;
+ case CMD_POPA:
+ {
+ for (UInt32 i = 0, SP = R[kStackRegIndex]; i < kNumRegs; i++, SP += 4)
+ R[kStackRegIndex - i] = GetValue32(&Mem[SP & kSpaceMask]);
+ }
+ break;
+ case CMD_PUSHF:
+ R[kStackRegIndex] -= 4;
+ SetValue32(&Mem[R[kStackRegIndex]&kSpaceMask], Flags);
+ break;
+ case CMD_POPF:
+ Flags = GetValue32(&Mem[R[kStackRegIndex] & kSpaceMask]);
+ R[kStackRegIndex] += 4;
+ break;
+
+ case CMD_MOVZX:
+ SetOperand32(&cmd->Op1, GetOperand8(&cmd->Op2));
+ break;
+ case CMD_MOVSX:
+ SetOperand32(&cmd->Op1, (UInt32)(Int32)(signed char)GetOperand8(&cmd->Op2));
+ break;
+ case CMD_XCHG:
+ {
+ UInt32 v1 = GetOperand(cmd->ByteMode, &cmd->Op1);
+ SetOperand(cmd->ByteMode, &cmd->Op1, GetOperand(cmd->ByteMode, &cmd->Op2));
+ SetOperand(cmd->ByteMode, &cmd->Op2, v1);
+ }
+ break;
+ case CMD_MUL:
+ {
+ UInt32 res = GetOperand32(&cmd->Op1) * GetOperand32(&cmd->Op2);
+ SetOperand32(&cmd->Op1, res);
+ }
+ break;
+ case CMD_MULB:
+ {
+ Byte res = GetOperand8(&cmd->Op1) * GetOperand8(&cmd->Op2);
+ SetOperand8(&cmd->Op1, res);
+ }
+ break;
+ case CMD_DIV:
+ {
+ UInt32 divider = GetOperand(cmd->ByteMode, &cmd->Op2);
+ if (divider != 0)
+ {
+ UInt32 res = GetOperand(cmd->ByteMode, &cmd->Op1) / divider;
+ SetOperand(cmd->ByteMode, &cmd->Op1, res);
+ }
+ }
+ break;
+
+ #endif
+
+ case CMD_RET:
+ {
+ if (R[kStackRegIndex] >= kSpaceSize)
+ return true;
+ UInt32 ip = GetValue32(&Mem[R[kStackRegIndex] & kSpaceMask]);
+ SET_IP(ip);
+ R[kStackRegIndex] += 4;
+ continue;
+ }
+ case CMD_PRINT:
+ break;
+ }
+ cmd++;
+ --maxOpCount;
+ }
+}
+
+
+//////////////////////////////////////////////////////
+// Read program
+
+UInt32 ReadEncodedUInt32(CMemBitDecoder &inp)
+{
+ switch(inp.ReadBits(2))
+ {
+ case 0:
+ return inp.ReadBits(4);
+ case 1:
+ {
+ UInt32 v = inp.ReadBits(4);
+ if (v == 0)
+ return 0xFFFFFF00 | inp.ReadBits(8);
+ else
+ return (v << 4) | inp.ReadBits(4);
+ }
+ case 2:
+ return inp.ReadBits(16);
+ default:
+ return inp.ReadBits(32);
+ }
+}
+
+void CVm::DecodeArg(CMemBitDecoder &inp, COperand &op, bool byteMode)
+{
+ if (inp.ReadBit())
+ {
+ op.Type = OP_TYPE_REG;
+ op.Data = inp.ReadBits(kNumRegBits);
+ }
+ else if (inp.ReadBit() == 0)
+ {
+ op.Type = OP_TYPE_INT;
+ if (byteMode)
+ op.Data = inp.ReadBits(8);
+ else
+ op.Data = ReadEncodedUInt32(inp);
+ }
+ else
+ {
+ op.Type = OP_TYPE_REGMEM;
+ if (inp.ReadBit() == 0)
+ {
+ op.Data = inp.ReadBits(kNumRegBits);
+ op.Base = 0;
+ }
+ else
+ {
+ if (inp.ReadBit() == 0)
+ op.Data = inp.ReadBits(kNumRegBits);
+ else
+ op.Data = kNumRegs;
+ op.Base = ReadEncodedUInt32(inp);
+ }
+ }
+}
+
+void CVm::ReadVmProgram(const Byte *code, UInt32 codeSize, CProgram *prg)
+{
+ CMemBitDecoder inp;
+ inp.Init(code, codeSize);
+
+ prg->StaticData.Clear();
+ if (inp.ReadBit())
+ {
+ UInt32 dataSize = ReadEncodedUInt32(inp) + 1;
+ for (UInt32 i = 0; inp.Avail() && i < dataSize; i++)
+ prg->StaticData.Add((Byte)inp.ReadBits(8));
+ }
+ while (inp.Avail())
+ {
+ prg->Commands.Add(CCommand());
+ CCommand *cmd = &prg->Commands.Back();
+ if (inp.ReadBit() == 0)
+ cmd->OpCode = (ECommand)inp.ReadBits(3);
+ else
+ cmd->OpCode = (ECommand)(8 + inp.ReadBits(5));
+ if (kCmdFlags[cmd->OpCode] & CF_BYTEMODE)
+ cmd->ByteMode = (inp.ReadBit()) ? true : false;
+ else
+ cmd->ByteMode = 0;
+ int opNum = (kCmdFlags[cmd->OpCode] & CF_OPMASK);
+ if (opNum > 0)
+ {
+ DecodeArg(inp, cmd->Op1, cmd->ByteMode);
+ if (opNum == 2)
+ DecodeArg(inp, cmd->Op2, cmd->ByteMode);
+ else
+ {
+ if (cmd->Op1.Type == OP_TYPE_INT && (kCmdFlags[cmd->OpCode] & (CF_JUMP | CF_PROC)))
+ {
+ int Distance = cmd->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->Commands.Size() - 1;
+ }
+ cmd->Op1.Data = Distance;
+ }
+ }
+ }
+ if (cmd->ByteMode)
+ {
+ switch (cmd->OpCode)
+ {
+ case CMD_MOV: cmd->OpCode = CMD_MOVB; break;
+ case CMD_CMP: cmd->OpCode = CMD_CMPB; break;
+ case CMD_ADD: cmd->OpCode = CMD_ADDB; break;
+ case CMD_SUB: cmd->OpCode = CMD_SUBB; break;
+ case CMD_INC: cmd->OpCode = CMD_INCB; break;
+ case CMD_DEC: cmd->OpCode = CMD_DECB; break;
+ case CMD_XOR: cmd->OpCode = CMD_XORB; break;
+ case CMD_AND: cmd->OpCode = CMD_ANDB; break;
+ case CMD_OR: cmd->OpCode = CMD_ORB; break;
+ case CMD_TEST: cmd->OpCode = CMD_TESTB; break;
+ case CMD_NEG: cmd->OpCode = CMD_NEGB; break;
+ case CMD_SHL: cmd->OpCode = CMD_SHLB; break;
+ case CMD_SHR: cmd->OpCode = CMD_SHRB; break;
+ case CMD_SAR: cmd->OpCode = CMD_SARB; break;
+ case CMD_MUL: cmd->OpCode = CMD_MULB; break;
+ }
+ }
+ }
+}
+
+#ifdef RARVM_STANDARD_FILTERS
+
+enum EStandardFilter
+{
+ SF_E8,
+ SF_E8E9,
+ SF_ITANIUM,
+ SF_RGB,
+ SF_AUDIO,
+ SF_DELTA,
+ SF_UPCASE
+};
+
+struct StandardFilterSignature
+{
+ UInt32 Length;
+ UInt32 CRC;
+ EStandardFilter Type;
+}
+kStdFilters[]=
+{
+ 53, 0xad576887, SF_E8,
+ 57, 0x3cd7e57e, SF_E8E9,
+ 120, 0x3769893f, SF_ITANIUM,
+ 29, 0x0e06077d, SF_DELTA,
+ 149, 0x1c2c5dc8, SF_RGB,
+ 216, 0xbc85e701, SF_AUDIO,
+ 40, 0x46b9c560, SF_UPCASE
+};
+
+static int FindStandardFilter(const Byte *code, UInt32 codeSize)
+{
+ UInt32 crc = CCRC::CalculateDigest(code, codeSize);
+ for (int i = 0; i < sizeof(kStdFilters) / sizeof(kStdFilters[0]); i++)
+ {
+ StandardFilterSignature &sfs = kStdFilters[i];
+ if (sfs.CRC == crc && sfs.Length == codeSize)
+ return i;
+ }
+ return -1;
+}
+
+#endif
+
+void CVm::PrepareProgram(const Byte *code, UInt32 codeSize, CProgram *prg)
+{
+ Byte xorSum = 0;
+ for (UInt32 i = 1; i < codeSize; i++)
+ xorSum ^= code[i];
+
+ prg->Commands.Clear();
+ #ifdef RARVM_STANDARD_FILTERS
+ prg->StandardFilterIndex = -1;
+ #endif
+
+ if (xorSum == code[0] && codeSize > 0)
+ {
+ #ifdef RARVM_STANDARD_FILTERS
+ prg->StandardFilterIndex = FindStandardFilter(code, codeSize);
+ if (prg->StandardFilterIndex >= 0)
+ return;
+ #endif
+ // 1 byte for checksum
+ ReadVmProgram(code + 1, codeSize - 1, prg);
+ }
+ prg->Commands.Add(CCommand());
+ CCommand *cmd = &prg->Commands.Back();
+ cmd->OpCode = CMD_RET;
+}
+
+void CVm::SetMemory(UInt32 pos, const Byte *data, UInt32 dataSize)
+{
+ if (pos < kSpaceSize && data != Mem + pos)
+ memmove(Mem + pos, data, MyMin(dataSize, kSpaceSize - pos));
+}
+
+#ifdef RARVM_STANDARD_FILTERS
+
+static void E8E9Decode(Byte *data, UInt32 dataSize, UInt32 fileOffset, bool e9)
+{
+ if (dataSize <= 4)
+ return;
+ dataSize -= 4;
+ const UInt32 kFileSize = 0x1000000;
+ Byte cmpByte2 = (e9 ? 0xE9 : 0xE8);
+ for (UInt32 curPos = 0; curPos < dataSize;)
+ {
+ Byte curByte = *(data++);
+ curPos++;
+ if (curByte == 0xE8 || curByte == cmpByte2)
+ {
+ UInt32 offset = curPos + fileOffset;
+ UInt32 addr = (Int32)GetValue32(data);
+ if (addr < kFileSize)
+ SetValue32(data, addr - offset);
+ else if ((Int32)addr < 0 && (Int32)(addr + offset) >= 0)
+ SetValue32(data, addr + kFileSize);
+ data += 4;
+ curPos += 4;
+ }
+ }
+}
+
+static inline UInt32 ItaniumGetOpType(const Byte *data, int bitPos)
+{
+ return (data[(unsigned int)bitPos >> 3] >> (bitPos & 7)) & 0xF;
+}
+
+
+static void ItaniumDecode(Byte *data, UInt32 dataSize, UInt32 fileOffset)
+{
+ UInt32 curPos = 0;
+ fileOffset >>= 4;
+ while (curPos < dataSize - 21)
+ {
+ int b = (data[0] & 0x1F) - 0x10;
+ if (b >= 0)
+ {
+ static Byte kCmdMasks[16] = {4,4,6,6,0,0,7,7,4,4,0,0,4,4,0,0};
+ Byte cmdMask = kCmdMasks[b];
+ if (cmdMask != 0)
+ for (int i = 0; i < 3; i++)
+ if (cmdMask & (1 << i))
+ {
+ int startPos = i * 41 + 18;
+ if (ItaniumGetOpType(data, startPos + 24) == 5)
+ {
+ const UInt32 kMask = 0xFFFFF;
+ Byte *p = data + ((unsigned int)startPos >> 3);
+ UInt32 bitField = ((UInt32)p[0]) | ((UInt32)p[1] << 8) | ((UInt32)p[2] << 16);
+ int inBit = (startPos & 7);
+ UInt32 offset = (bitField >> inBit) & kMask;
+ UInt32 andMask = ~(kMask << inBit);
+ bitField = ((offset - fileOffset) & kMask) << inBit;
+ for (int j = 0; j < 3; j++)
+ {
+ p[j] &= andMask;
+ p[j] |= bitField;
+ andMask >>= 8;
+ bitField >>= 8;
+ }
+ }
+ }
+ }
+ data += 16;
+ curPos += 16;
+ fileOffset++;
+ }
+}
+
+static void DeltaDecode(Byte *data, UInt32 dataSize, UInt32 numChannels)
+{
+ UInt32 srcPos = 0;
+ UInt32 border = dataSize * 2;
+ for (UInt32 curChannel = 0; curChannel < numChannels; curChannel++)
+ {
+ Byte prevByte = 0;
+ for (UInt32 destPos = dataSize + curChannel; destPos < border; destPos += numChannels)
+ data[destPos] = (prevByte = prevByte - data[srcPos++]);
+ }
+}
+
+static void RgbDecode(Byte *srcData, UInt32 dataSize, UInt32 width, UInt32 posR)
+{
+ Byte *destData = srcData + dataSize;
+ const UInt32 numChannels = 3;
+ for (UInt32 curChannel = 0; curChannel < numChannels; curChannel++)
+ {
+ Byte prevByte = 0;
+
+ for (UInt32 i = curChannel; i < dataSize; i+= numChannels)
+ {
+ unsigned int predicted;
+ if (i < width)
+ predicted = prevByte;
+ else
+ {
+ unsigned int upperLeftByte = destData[i - width];
+ unsigned int upperByte = destData[i - width + 3];
+ predicted = prevByte + upperByte - upperLeftByte;
+ int pa = abs((int)(predicted - prevByte));
+ int pb = abs((int)(predicted - upperByte));
+ int pc = abs((int)(predicted - upperLeftByte));
+ if (pa <= pb && pa <= pc)
+ predicted = prevByte;
+ else
+ if (pb <= pc)
+ predicted = upperByte;
+ else
+ predicted = upperLeftByte;
+ }
+ destData[i] = prevByte = (Byte)(predicted - *(srcData++));
+ }
+ }
+ if (dataSize < 3)
+ return;
+ for (UInt32 i = posR, border = dataSize - 2; i < border; i += 3)
+ {
+ Byte g = destData[i + 1];
+ destData[i] = destData[i] + g;
+ destData[i + 2] = destData[i + 2] + g;
+ }
+}
+
+static void AudioDecode(Byte *srcData, UInt32 dataSize, UInt32 numChannels)
+{
+ Byte *destData = srcData + dataSize;
+ for (UInt32 curChannel = 0; curChannel < numChannels; curChannel++)
+ {
+ UInt32 prevByte = 0, prevDelta = 0, dif[7];
+ Int32 D1 = 0, D2 = 0, D3;
+ Int32 K1 = 0, K2 = 0, K3 = 0;
+ memset(dif, 0, sizeof(dif));
+
+ for (UInt32 i = curChannel, byteCount = 0; i < dataSize; i += numChannels, byteCount++)
+ {
+ D3 = D2;
+ D2 = prevDelta - D1;
+ D1 = prevDelta;
+
+ UInt32 predicted = 8 * prevByte + K1 * D1 + K2 * D2 + K3 * D3;
+ predicted = (predicted >> 3) & 0xFF;
+
+ UInt32 curByte = *(srcData++);
+
+ predicted -= curByte;
+ destData[i] = (Byte)predicted;
+ prevDelta = (UInt32)(Int32)(signed char)(predicted - prevByte);
+ prevByte = predicted;
+
+ Int32 D = ((Int32)(signed char)curByte) << 3;
+
+ dif[0] += abs(D);
+ dif[1] += abs(D - D1);
+ dif[2] += abs(D + D1);
+ dif[3] += abs(D - D2);
+ dif[4] += abs(D + D2);
+ dif[5] += abs(D - D3);
+ dif[6] += abs(D + D3);
+
+ if ((byteCount & 0x1F) == 0)
+ {
+ UInt32 minDif = dif[0], numMinDif = 0;
+ dif[0] = 0;
+ for (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;
+ }
+ }
+ }
+ }
+}
+
+static UInt32 UpCaseDecode(Byte *data, UInt32 dataSize)
+{
+ UInt32 srcPos = 0, destPos = dataSize;
+ while (srcPos < dataSize)
+ {
+ Byte curByte = data[srcPos++];
+ if (curByte == 2 && (curByte = data[srcPos++]) != 2)
+ curByte -= 32;
+ data[destPos++] = curByte;
+ }
+ return destPos - dataSize;
+}
+
+void CVm::ExecuteStandardFilter(int filterIndex)
+{
+ UInt32 dataSize = R[4];
+ if (dataSize >= kGlobalOffset)
+ return;
+ EStandardFilter filterType = kStdFilters[filterIndex].Type;
+
+ switch (filterType)
+ {
+ case SF_E8:
+ case SF_E8E9:
+ E8E9Decode(Mem, dataSize, R[6], (filterType == SF_E8E9));
+ break;
+ case SF_ITANIUM:
+ ItaniumDecode(Mem, dataSize, R[6]);
+ break;
+ case SF_DELTA:
+ if (dataSize >= kGlobalOffset / 2)
+ break;
+ SetBlockPos(dataSize);
+ DeltaDecode(Mem, dataSize, R[0]);
+ break;
+ case SF_RGB:
+ if (dataSize >= kGlobalOffset / 2)
+ break;
+ {
+ UInt32 width = R[0];
+ if (width <= 3)
+ break;
+ SetBlockPos(dataSize);
+ RgbDecode(Mem, dataSize, width, R[1]);
+ }
+ break;
+ case SF_AUDIO:
+ if (dataSize >= kGlobalOffset / 2)
+ break;
+ SetBlockPos(dataSize);
+ AudioDecode(Mem, dataSize, R[0]);
+ break;
+ case SF_UPCASE:
+ if (dataSize >= kGlobalOffset / 2)
+ break;
+ UInt32 destSize = UpCaseDecode(Mem, dataSize);
+ SetBlockSize(destSize);
+ SetBlockPos(dataSize);
+ break;
+ }
+}
+
+#endif
+
+}}}
diff --git a/CPP/7zip/Compress/Rar/Rar3Vm.h b/CPP/7zip/Compress/Rar/Rar3Vm.h
new file mode 100755
index 00000000..d0a4f82c
--- /dev/null
+++ b/CPP/7zip/Compress/Rar/Rar3Vm.h
@@ -0,0 +1,219 @@
+// Rar3Vm.h
+// According to unRAR license,
+// this code may not be used to develop a
+// RAR (WinRAR) compatible archiver
+
+#ifndef __RAR3VM_H
+#define __RAR3VM_H
+
+#include "Common/Types.h"
+#include "Common/Vector.h"
+
+#define RARVM_STANDARD_FILTERS
+#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__) // || defined(_M_IA64) || defined(__ia64__)
+// Define RARVM_LITTLE_ENDIAN_UNALIGN, if CPU is LITTLE_ENDIAN and if it supports
+// unaligned 32-bit memory accesses.
+// It's for speed optimization, if you are not sure, just don't define it.
+#define RARVM_LITTLE_ENDIAN_UNALIGN
+#endif
+
+namespace NCompress {
+namespace NRar3 {
+
+class CMemBitDecoder
+{
+ const Byte *_data;
+ UInt32 _bitSize;
+ UInt32 _bitPos;
+public:
+ void Init(const Byte *data, UInt32 byteSize)
+ {
+ _data = data;
+ _bitSize = (byteSize << 3);
+ _bitPos = 0;
+ }
+ UInt32 ReadBits(int numBits);
+ UInt32 ReadBit();
+ bool Avail() const { return (_bitPos < _bitSize); }
+};
+
+namespace NVm {
+
+inline UInt32 GetValue32(const void *addr)
+{
+ #ifdef RARVM_LITTLE_ENDIAN_UNALIGN
+ return *(const UInt32 *)addr;
+ #else
+ const Byte *b = (const Byte *)addr;
+ return UInt32((UInt32)b[0]|((UInt32)b[1]<<8)|((UInt32)b[2]<<16)|((UInt32)b[3]<<24));
+ #endif
+}
+
+inline void SetValue32(void *addr, UInt32 value)
+{
+ #ifdef RARVM_LITTLE_ENDIAN_UNALIGN
+ *(UInt32 *)addr = value;
+ #else
+ ((Byte *)addr)[0] = (Byte)value;
+ ((Byte *)addr)[1] = (Byte)(value >> 8);
+ ((Byte *)addr)[2] = (Byte)(value >> 16);
+ ((Byte *)addr)[3] = (Byte)(value >> 24);
+ #endif
+}
+
+UInt32 ReadEncodedUInt32(CMemBitDecoder &inp);
+
+const int kNumRegBits = 3;
+const UInt32 kNumRegs = 1 << kNumRegBits;
+const UInt32 kNumGpRegs = kNumRegs - 1;
+
+const UInt32 kSpaceSize = 0x40000;
+const UInt32 kSpaceMask = kSpaceSize -1;
+const UInt32 kGlobalOffset = 0x3C000;
+const UInt32 kGlobalSize = 0x2000;
+const UInt32 kFixedGlobalSize = 64;
+
+namespace NGlobalOffset
+{
+ const UInt32 kBlockSize = 0x1C;
+ const UInt32 kBlockPos = 0x20;
+ const UInt32 kExecCount = 0x2C;
+ const UInt32 kGlobalMemOutSize = 0x30;
+};
+
+enum ECommand
+{
+ CMD_MOV, CMD_CMP, CMD_ADD, CMD_SUB, CMD_JZ, CMD_JNZ, CMD_INC, CMD_DEC,
+ CMD_JMP, CMD_XOR, CMD_AND, CMD_OR, CMD_TEST, CMD_JS, CMD_JNS, CMD_JB,
+ CMD_JBE, CMD_JA, CMD_JAE, CMD_PUSH, CMD_POP, CMD_CALL, CMD_RET, CMD_NOT,
+ CMD_SHL, CMD_SHR, CMD_SAR, CMD_NEG, CMD_PUSHA,CMD_POPA, CMD_PUSHF,CMD_POPF,
+ CMD_MOVZX,CMD_MOVSX,CMD_XCHG, CMD_MUL, CMD_DIV, CMD_ADC, CMD_SBB, CMD_PRINT,
+
+ CMD_MOVB, CMD_CMPB, CMD_ADDB, CMD_SUBB, CMD_INCB, CMD_DECB,
+ CMD_XORB, CMD_ANDB, CMD_ORB, CMD_TESTB,CMD_NEGB,
+ CMD_SHLB, CMD_SHRB, CMD_SARB, CMD_MULB
+};
+
+enum EOpType {OP_TYPE_REG, OP_TYPE_INT, OP_TYPE_REGMEM, OP_TYPE_NONE};
+
+// Addr in COperand object can link (point) to CVm object!!!
+
+struct COperand
+{
+ EOpType Type;
+ UInt32 Data;
+ UInt32 Base;
+ COperand(): Type(OP_TYPE_NONE), Data(0), Base(0) {}
+};
+
+struct CCommand
+{
+ ECommand OpCode;
+ bool ByteMode;
+ COperand Op1, Op2;
+};
+
+struct CBlockRef
+{
+ UInt32 Offset;
+ UInt32 Size;
+};
+
+struct CProgram
+{
+ CRecordVector<CCommand> Commands;
+ #ifdef RARVM_STANDARD_FILTERS
+ int StandardFilterIndex;
+ #endif
+ CRecordVector<Byte> StaticData;
+};
+
+struct CProgramInitState
+{
+ UInt32 InitR[kNumGpRegs];
+ CRecordVector<Byte> GlobalData;
+
+ void AllocateEmptyFixedGlobal()
+ {
+ GlobalData.Clear();
+ GlobalData.Reserve(NVm::kFixedGlobalSize);
+ for (UInt32 i = 0; i < NVm::kFixedGlobalSize; i++)
+ GlobalData.Add(0);
+ }
+};
+
+class CVm
+{
+ static UInt32 GetValue(bool byteMode, const void *addr)
+ {
+ if (byteMode)
+ return(*(const Byte *)addr);
+ else
+ {
+ #ifdef RARVM_LITTLE_ENDIAN_UNALIGN
+ return *(const UInt32 *)addr;
+ #else
+ const Byte *b = (const Byte *)addr;
+ return UInt32((UInt32)b[0]|((UInt32)b[1]<<8)|((UInt32)b[2]<<16)|((UInt32)b[3]<<24));
+ #endif
+ }
+ }
+
+ static void SetValue(bool byteMode, void *addr, UInt32 value)
+ {
+ if (byteMode)
+ *(Byte *)addr = (Byte)value;
+ else
+ {
+ #ifdef RARVM_LITTLE_ENDIAN_UNALIGN
+ *(UInt32 *)addr = value;
+ #else
+ ((Byte *)addr)[0] = (Byte)value;
+ ((Byte *)addr)[1] = (Byte)(value >> 8);
+ ((Byte *)addr)[2] = (Byte)(value >> 16);
+ ((Byte *)addr)[3] = (Byte)(value >> 24);
+ #endif
+ }
+ }
+
+ UInt32 GetFixedGlobalValue32(UInt32 globalOffset) { return GetValue(false, &Mem[kGlobalOffset + globalOffset]); }
+
+ void SetBlockSize(UInt32 v) { SetValue(&Mem[kGlobalOffset + NGlobalOffset::kBlockSize], v); }
+ void SetBlockPos(UInt32 v) { SetValue(&Mem[kGlobalOffset + NGlobalOffset::kBlockPos], v); }
+public:
+ static void SetValue(void *addr, UInt32 value) { SetValue(false, addr, value); }
+private:
+ UInt32 GetOperand32(const COperand *op) const;
+ void SetOperand32(const COperand *op, UInt32 val);
+ Byte GetOperand8(const COperand *op) const;
+ void SetOperand8(const COperand *op, Byte val);
+ UInt32 GetOperand(bool byteMode, const COperand *op) const;
+ void SetOperand(bool byteMode, const COperand *op, UInt32 val);
+
+ void DecodeArg(CMemBitDecoder &inp, COperand &op, bool byteMode);
+
+ bool ExecuteCode(const CProgram *prg);
+
+ #ifdef RARVM_STANDARD_FILTERS
+ void ExecuteStandardFilter(int filterIndex);
+ #endif
+
+ Byte *Mem;
+ UInt32 R[kNumRegs + 1]; // R[kNumRegs] = 0 always (speed optimization)
+ UInt32 Flags;
+ void ReadVmProgram(const Byte *code, UInt32 codeSize, CProgram *prg);
+public:
+ CVm();
+ ~CVm();
+ bool Create();
+ void PrepareProgram(const Byte *code, UInt32 codeSize, CProgram *prg);
+ void SetMemory(UInt32 pos, const Byte *data, UInt32 dataSize);
+ bool Execute(CProgram *prg, const CProgramInitState *initState,
+ CBlockRef &outBlockRef, CRecordVector<Byte> &outGlobalData);
+ const Byte *GetDataPointer(UInt32 offset) const { return Mem + offset; }
+
+};
+
+#endif
+
+}}}
diff --git a/CPP/7zip/Compress/Rar/StdAfx.cpp b/CPP/7zip/Compress/Rar/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Compress/Rar/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Compress/Rar/StdAfx.h b/CPP/7zip/Compress/Rar/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Compress/Rar/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Compress/Rar/makefile b/CPP/7zip/Compress/Rar/makefile
new file mode 100755
index 00000000..4d8d5304
--- /dev/null
+++ b/CPP/7zip/Compress/Rar/makefile
@@ -0,0 +1,49 @@
+PROG = Rar29.dll
+DEF_FILE = ../Codec.def
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib
+
+RAR29_OBJS = \
+ $O\DllExports.obj \
+
+RAR29_OPT_OBJS = \
+ $O\Rar1Decoder.obj \
+ $O\Rar2Decoder.obj \
+ $O\Rar3Decoder.obj \
+ $O\Rar3Vm.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\CRC.obj \
+ $O\Vector.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) \
+ $(COMMON_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(LZ_OBJS) \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(RAR29_OBJS): $(*B).cpp
+ $(COMPL)
+$(RAR29_OPT_OBJS): $(*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/CPP/7zip/Compress/Rar/resource.rc b/CPP/7zip/Compress/Rar/resource.rc
new file mode 100755
index 00000000..bb5e2ec9
--- /dev/null
+++ b/CPP/7zip/Compress/Rar/resource.rc
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("Rar29 Codec", "Rar29")
diff --git a/CPP/7zip/Compress/Shrink/DllExports.cpp b/CPP/7zip/Compress/Shrink/DllExports.cpp
new file mode 100755
index 00000000..61bd5e69
--- /dev/null
+++ b/CPP/7zip/Compress/Shrink/DllExports.cpp
@@ -0,0 +1,64 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#include "ShrinkDecoder.h"
+
+// {23170F69-40C1-278B-0401-010000000000}
+DEFINE_GUID(CLSID_CCompressShrinkDecoder,
+0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x01, 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_CCompressShrinkDecoder)
+ return CLASS_E_CLASSNOTAVAILABLE;
+ if (*iid != IID_ICompressCoder)
+ return E_NOINTERFACE;
+ CMyComPtr<ICompressCoder> coder = (ICompressCoder *)new NCompress::NShrink::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, 0x01, 0x01 };
+ if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NMethodPropID::kName:
+ if ((value->bstrVal = ::SysAllocString(L"Shrink")) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ case NMethodPropID::kDecoder:
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CCompressShrinkDecoder, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ return S_OK;
+}
diff --git a/CPP/7zip/Compress/Shrink/ShrinkDecoder.cpp b/CPP/7zip/Compress/Shrink/ShrinkDecoder.cpp
new file mode 100755
index 00000000..12d1b8d0
--- /dev/null
+++ b/CPP/7zip/Compress/Shrink/ShrinkDecoder.cpp
@@ -0,0 +1,149 @@
+// ShrinkDecoder.cpp
+
+#include "StdAfx.h"
+
+#include "ShrinkDecoder.h"
+
+#include "../../../Common/Alloc.h"
+#include "../../Common/InBuffer.h"
+#include "../../Common/OutBuffer.h"
+#include "../../Common/LSBFDecoder.h"
+
+namespace NCompress {
+namespace NShrink {
+
+static const UInt32 kBufferSize = (1 << 20);
+
+static const int kNumMinBits = 9;
+
+STDMETHODIMP CDecoder ::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 * /* outSize */,
+ ICompressProgressInfo *progress)
+{
+ NStream::NLSBF::CBaseDecoder<CInBuffer> inBuffer;
+ COutBuffer outBuffer;
+
+ if (!inBuffer.Create(kBufferSize))
+ return E_OUTOFMEMORY;
+ inBuffer.SetStream(inStream);
+ inBuffer.Init();
+
+ if (!outBuffer.Create(kBufferSize))
+ return E_OUTOFMEMORY;
+ outBuffer.SetStream(outStream);
+ outBuffer.Init();
+
+ UInt64 prevPos = 0;
+ int numBits = kNumMinBits;
+ UInt32 head = 257;
+
+ bool needPrev = false;
+
+ _parents[256] = 0; // virus protection
+ _suffixes[256] = 0;
+
+ int i;
+ for (i = 0; i < 257; i++)
+ _isFree[i] = false;
+ for (; i < kNumItems; i++)
+ _isFree[i] = true;
+
+ UInt32 lastSymbol = 0;
+ for (;;)
+ {
+ outBuffer.Flush();
+ UInt32 symbol = inBuffer.ReadBits(numBits);
+ if (inBuffer.ExtraBitsWereRead())
+ break;
+ if (_isFree[symbol])
+ return S_FALSE;
+ if (symbol == 256)
+ {
+ // fix it;
+ UInt32 symbol = inBuffer.ReadBits(numBits);
+ if (symbol == 1)
+ {
+ if (numBits < kNumMaxBits)
+ numBits++;
+ }
+ else if (symbol == 2)
+ {
+ /*
+ maybe need delete prev also ?
+ if (needPrev)
+ _isFree[head - 1] = true;
+ */
+ for (i = 257; i < kNumItems; i++)
+ _isParent[i] = false;
+ for (i = 257; i < kNumItems; i++)
+ if (!_isFree[i])
+ _isParent[_parents[i]] = true;
+ for (i = 257; i < kNumItems; i++)
+ if (!_isParent[i])
+ _isFree[i] = true;
+ head = 257;
+ while(head < ((UInt32)1 << numBits) && !_isFree[head])
+ head++;
+ if (head < ((UInt32)1 << numBits))
+ {
+ needPrev = true;
+ _isFree[head] = false;
+ _parents[head] = (UInt16)lastSymbol;
+ head++;
+ }
+ }
+ else
+ return S_FALSE;
+ continue;
+ }
+ UInt32 cur = symbol;
+ i = 0;
+ while (cur >= 256)
+ {
+ _stack[i++] = _suffixes[cur];
+ cur = _parents[cur];
+ }
+ _stack[i++] = (Byte)cur;
+ if (needPrev)
+ {
+ _suffixes[head - 1] = (Byte)cur;
+ if (symbol == head - 1)
+ _stack[0] = (Byte)cur;
+ }
+ while (i > 0)
+ outBuffer.WriteByte((_stack[--i]));
+ while(head < ((UInt32)1 << numBits) && !_isFree[head])
+ head++;
+ if (head < ((UInt32)1 << numBits))
+ {
+ needPrev = true;
+ _isFree[head] = false;
+ _parents[head] = (UInt16)symbol;
+ head++;
+ }
+ else
+ needPrev = false;
+ lastSymbol = symbol;
+
+ UInt64 nowPos = outBuffer.GetProcessedSize();
+ if (progress != NULL && nowPos - prevPos > (1 << 18))
+ {
+ prevPos = nowPos;
+ UInt64 packSize = inBuffer.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&packSize, &nowPos));
+ }
+ }
+ return outBuffer.Flush();
+}
+
+STDMETHODIMP CDecoder ::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
+ catch(const CInBufferException &e) { return e.ErrorCode; }
+ catch(const COutBufferException &e) { return e.ErrorCode; }
+ catch(...) { return S_FALSE; }
+}
+
+}}
diff --git a/CPP/7zip/Compress/Shrink/ShrinkDecoder.h b/CPP/7zip/Compress/Shrink/ShrinkDecoder.h
new file mode 100755
index 00000000..1c15ea8a
--- /dev/null
+++ b/CPP/7zip/Compress/Shrink/ShrinkDecoder.h
@@ -0,0 +1,39 @@
+// ShrinkDecoder.h
+
+#ifndef __SHRINK_DECODER_H
+#define __SHRINK_DECODER_H
+
+#include "../../../Common/MyCom.h"
+
+#include "../../ICoder.h"
+
+namespace NCompress {
+namespace NShrink {
+
+const int kNumMaxBits = 13;
+const UInt32 kNumItems = 1 << kNumMaxBits;
+
+class CDecoder :
+ public ICompressCoder,
+ public CMyUnknownImp
+{
+ UInt16 _parents[kNumItems];
+ Byte _suffixes[kNumItems];
+ Byte _stack[kNumItems];
+ bool _isFree[kNumItems];
+ bool _isParent[kNumItems];
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(CodeReal)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Compress/Shrink/StdAfx.cpp b/CPP/7zip/Compress/Shrink/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Compress/Shrink/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Compress/Shrink/StdAfx.h b/CPP/7zip/Compress/Shrink/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Compress/Shrink/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Compress/Z/StdAfx.cpp b/CPP/7zip/Compress/Z/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Compress/Z/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Compress/Z/StdAfx.h b/CPP/7zip/Compress/Z/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Compress/Z/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Compress/Z/ZDecoder.cpp b/CPP/7zip/Compress/Z/ZDecoder.cpp
new file mode 100755
index 00000000..2415efd8
--- /dev/null
+++ b/CPP/7zip/Compress/Z/ZDecoder.cpp
@@ -0,0 +1,172 @@
+// ZDecoder.cpp
+
+#include "StdAfx.h"
+
+#include "ZDecoder.h"
+
+#include "../../../Common/Alloc.h"
+#include "../../Common/InBuffer.h"
+#include "../../Common/OutBuffer.h"
+#include "../../Common/LSBFDecoder.h"
+
+namespace NCompress {
+namespace NZ {
+
+static const UInt32 kBufferSize = (1 << 20);
+static const Byte kNumBitsMask = 0x1F;
+static const Byte kBlockModeMask = 0x80;
+static const int kNumMinBits = 9;
+static const int kNumMaxBits = 16;
+
+void CDecoder::Free()
+{
+ MyFree(_parents);
+ _parents = 0;
+ MyFree(_suffixes);
+ _suffixes = 0;
+ MyFree(_stack);
+ _stack = 0;
+}
+
+bool CDecoder::Alloc(size_t numItems)
+{
+ Free();
+ _parents = (UInt16 *)MyAlloc(numItems * sizeof(UInt16));
+ if (_parents == 0)
+ return false;
+ _suffixes = (Byte *)MyAlloc(numItems * sizeof(Byte));
+ if (_suffixes == 0)
+ return false;
+ _stack = (Byte *)MyAlloc(numItems * sizeof(Byte));
+ return _stack != 0;
+}
+
+CDecoder::~CDecoder()
+{
+ Free();
+}
+
+STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 * /* outSize */,
+ ICompressProgressInfo *progress)
+{
+ NStream::NLSBF::CBaseDecoder<CInBuffer> inBuffer;
+ COutBuffer outBuffer;
+
+ if (!inBuffer.Create(kBufferSize))
+ return E_OUTOFMEMORY;
+ inBuffer.SetStream(inStream);
+ inBuffer.Init();
+
+ if (!outBuffer.Create(kBufferSize))
+ return E_OUTOFMEMORY;
+ outBuffer.SetStream(outStream);
+ outBuffer.Init();
+
+ int maxbits = _properties & kNumBitsMask;
+ if (maxbits < kNumMinBits || maxbits > kNumMaxBits)
+ return S_FALSE;
+ UInt32 numItems = 1 << maxbits;
+ bool blockMode = ((_properties & kBlockModeMask) != 0);
+ if (!blockMode)
+ return E_NOTIMPL;
+
+ if (maxbits != _numMaxBits || _parents == 0 || _suffixes == 0 || _stack == 0)
+ {
+ if (!Alloc(numItems))
+ return E_OUTOFMEMORY;
+ _numMaxBits = maxbits;
+ }
+
+ UInt64 prevPos = 0;
+ int numBits = kNumMinBits;
+ UInt32 head = blockMode ? 257 : 256;
+
+ bool needPrev = false;
+
+ int keepBits = 0;
+
+ _parents[256] = 0; // virus protection
+ _suffixes[256] = 0;
+
+ for (;;)
+ {
+ if (keepBits < numBits)
+ keepBits = numBits * 8;
+ UInt32 symbol = inBuffer.ReadBits(numBits);
+ if (inBuffer.ExtraBitsWereRead())
+ break;
+ keepBits -= numBits;
+ if (symbol >= head)
+ return S_FALSE;
+ if (blockMode && symbol == 256)
+ {
+ for (;keepBits > 0; keepBits--)
+ inBuffer.ReadBits(1);
+ numBits = kNumMinBits;
+ head = 257;
+ needPrev = false;
+ continue;
+ }
+ UInt32 cur = symbol;
+ int i = 0;
+ while (cur >= 256)
+ {
+ _stack[i++] = _suffixes[cur];
+ cur = _parents[cur];
+ }
+ _stack[i++] = (Byte)cur;
+ if (needPrev)
+ {
+ _suffixes[head - 1] = (Byte)cur;
+ if (symbol == head - 1)
+ _stack[0] = (Byte)cur;
+ }
+ while (i > 0)
+ outBuffer.WriteByte((_stack[--i]));
+ if (head < numItems)
+ {
+ needPrev = true;
+ _parents[head++] = (UInt16)symbol;
+ if (head > ((UInt32)1 << numBits))
+ {
+ if (numBits < maxbits)
+ {
+ numBits++;
+ keepBits = numBits * 8;
+ }
+ }
+ }
+ else
+ needPrev = false;
+
+ UInt64 nowPos = outBuffer.GetProcessedSize();
+ if (progress != NULL && nowPos - prevPos > (1 << 18))
+ {
+ prevPos = nowPos;
+ UInt64 packSize = inBuffer.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&packSize, &nowPos));
+ }
+ }
+ return outBuffer.Flush();
+}
+
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
+ catch(const CInBufferException &e) { return e.ErrorCode; }
+ catch(const COutBufferException &e) { return e.ErrorCode; }
+ catch(...) { return S_FALSE; }
+}
+
+STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
+{
+ if (size < 1)
+ return E_INVALIDARG;
+ _properties = data[0];
+ return S_OK;
+}
+
+}}
diff --git a/CPP/7zip/Compress/Z/ZDecoder.h b/CPP/7zip/Compress/Z/ZDecoder.h
new file mode 100755
index 00000000..1640c7f4
--- /dev/null
+++ b/CPP/7zip/Compress/Z/ZDecoder.h
@@ -0,0 +1,44 @@
+// ZDecoder.h
+
+#ifndef __COMPRESS_ZDECODER_H
+#define __COMPRESS_ZDECODER_H
+
+#include "../../../Common/MyCom.h"
+#include "../../ICoder.h"
+
+namespace NCompress {
+namespace NZ {
+
+class CDecoder :
+ public ICompressCoder,
+ public ICompressSetDecoderProperties2,
+ public CMyUnknownImp
+{
+ BYTE _properties;
+ int _numMaxBits;
+ UInt16 *_parents;
+ Byte *_suffixes;
+ Byte *_stack;
+
+public:
+ CDecoder(): _properties(0), _numMaxBits(0), _parents(0), _suffixes(0), _stack(0) {};
+ ~CDecoder();
+ void Free();
+ bool Alloc(size_t numItems);
+
+ MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)
+
+ 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/CPP/7zip/Compress/makefile b/CPP/7zip/Compress/makefile
new file mode 100755
index 00000000..7c1387c8
--- /dev/null
+++ b/CPP/7zip/Compress/makefile
@@ -0,0 +1,14 @@
+DIRS = \
+ Branch\~ \
+ ByteSwap\~ \
+ BZip2\~ \
+ Copy\~ \
+ Deflate\~ \
+ LZMA\~ \
+ PPMD\~ \
+ Rar\~ \
+
+all: $(DIRS)
+
+$(DIRS):
+!include "../SubBuild.mak"
diff --git a/CPP/7zip/Crypto/7zAES/7zAES.cpp b/CPP/7zip/Crypto/7zAES/7zAES.cpp
new file mode 100755
index 00000000..843d9027
--- /dev/null
+++ b/CPP/7zip/Crypto/7zAES/7zAES.cpp
@@ -0,0 +1,305 @@
+// 7z_AES.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/Defs.h"
+#include "Windows/Synchronization.h"
+#include "../../Common/StreamObjects.h"
+#include "../../Common/StreamUtils.h"
+
+#include "7zAES.h"
+// #include "../../Hash/Common/CryptoHashInterface.h"
+
+#ifdef CRYPTO_AES
+#include "../AES/MyAES.h"
+#endif
+
+#include "../Hash/Sha256.h"
+
+using namespace NWindows;
+
+#ifndef CRYPTO_AES
+extern HINSTANCE g_hInstance;
+#endif
+
+namespace NCrypto {
+namespace NSevenZ {
+
+bool CKeyInfo::IsEqualTo(const CKeyInfo &a) const
+{
+ if (SaltSize != a.SaltSize || NumCyclesPower != a.NumCyclesPower)
+ return false;
+ for (UInt32 i = 0; i < SaltSize; i++)
+ if (Salt[i] != a.Salt[i])
+ return false;
+ return (Password == a.Password);
+}
+
+void CKeyInfo::CalculateDigest()
+{
+ if (NumCyclesPower == 0x3F)
+ {
+ UInt32 pos;
+ for (pos = 0; pos < SaltSize; pos++)
+ Key[pos] = Salt[pos];
+ for (UInt32 i = 0; i < Password.GetCapacity() && pos < kKeySize; i++)
+ Key[pos++] = Password[i];
+ for (; pos < kKeySize; pos++)
+ Key[pos] = 0;
+ }
+ else
+ {
+ NCrypto::NSha256::CContext sha;
+ const UInt64 numRounds = UInt64(1) << (NumCyclesPower);
+ Byte temp[8] = { 0,0,0,0,0,0,0,0 };
+ for (UInt64 round = 0; round < numRounds; round++)
+ {
+ sha.Update(Salt, SaltSize);
+ sha.Update(Password, Password.GetCapacity());
+ sha.Update(temp, 8);
+ for (int i = 0; i < 8; i++)
+ if (++(temp[i]) != 0)
+ break;
+ }
+ sha.Final(Key);
+ }
+}
+
+bool CKeyInfoCache::Find(CKeyInfo &key)
+{
+ for (int i = 0; i < Keys.Size(); i++)
+ {
+ const CKeyInfo &cached = Keys[i];
+ if (key.IsEqualTo(cached))
+ {
+ for (int j = 0; j < kKeySize; j++)
+ key.Key[j] = cached.Key[j];
+ if (i != 0)
+ {
+ Keys.Insert(0, cached);
+ Keys.Delete(i+1);
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+void CKeyInfoCache::Add(CKeyInfo &key)
+{
+ if (Find(key))
+ return;
+ if (Keys.Size() >= Size)
+ Keys.DeleteBack();
+ Keys.Insert(0, key);
+}
+
+static CKeyInfoCache g_GlobalKeyCache(32);
+static NSynchronization::CCriticalSection g_GlobalKeyCacheCriticalSection;
+
+CBase::CBase():
+ _cachedKeys(16)
+{
+ for (int i = 0; i < sizeof(_iv); i++)
+ _iv[i] = 0;
+}
+
+void CBase::CalculateDigest()
+{
+ NSynchronization::CCriticalSectionLock lock(g_GlobalKeyCacheCriticalSection);
+ if (_cachedKeys.Find(_key))
+ g_GlobalKeyCache.Add(_key);
+ else
+ {
+ if (!g_GlobalKeyCache.Find(_key))
+ {
+ _key.CalculateDigest();
+ g_GlobalKeyCache.Add(_key);
+ }
+ _cachedKeys.Add(_key);
+ }
+}
+
+
+/*
+static void GetRandomData(Byte *data)
+{
+ // probably we don't need truly random.
+ // it's enough to prevent dictionary attack;
+ // but it gives some info about time when compressing
+ // was made.
+ UInt64 tempValue;
+ SYSTEMTIME systemTime;
+ FILETIME fileTime;
+ ::GetSystemTime(&systemTime);
+ ::SystemTimeToFileTime(&systemTime, &fileTime);
+ tempValue = *(const UInt64 *)&fileTime;
+ LARGE_INTEGER counter;
+ ::QueryPerformanceCounter(&counter);
+ tempValue += *(const UInt64 *)&counter;
+ tempValue += (UInt64)(GetTickCount()) << 32;
+ *(UInt64 *)data = tempValue;
+}
+*/
+
+STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{
+ _key.Init();
+ for (UInt32 i = 0; i < sizeof(_iv); i++)
+ _iv[i] = 0;
+
+ _key.SaltSize = 0;
+
+ // _key.SaltSize = 8;
+ // GetRandomData(_key.Salt);
+
+ int ivSize = 0;
+
+ // _key.NumCyclesPower = 0x3F;
+ _key.NumCyclesPower = 18;
+
+ Byte firstByte = (Byte)(_key.NumCyclesPower |
+ (((_key.SaltSize == 0) ? 0 : 1) << 7) |
+ (((ivSize == 0) ? 0 : 1) << 6));
+ RINOK(outStream->Write(&firstByte, 1, NULL));
+ if (_key.SaltSize == 0 && ivSize == 0)
+ return S_OK;
+ Byte saltSizeSpec = (Byte)((_key.SaltSize == 0) ? 0 : (_key.SaltSize - 1));
+ Byte ivSizeSpec = (Byte)((ivSize == 0) ? 0 : (ivSize - 1));
+ Byte secondByte = (Byte)(((saltSizeSpec) << 4) | ivSizeSpec);
+ RINOK(outStream->Write(&secondByte, 1, NULL));
+ if (_key.SaltSize > 0)
+ {
+ RINOK(WriteStream(outStream, _key.Salt, _key.SaltSize, NULL));
+ }
+ if (ivSize > 0)
+ {
+ RINOK(WriteStream(outStream, _iv, ivSize, NULL));
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
+{
+ _key.Init();
+ UInt32 i;
+ for (i = 0; i < sizeof(_iv); i++)
+ _iv[i] = 0;
+ if (size == 0)
+ return S_OK;
+ UInt32 pos = 0;
+ Byte firstByte = data[pos++];
+
+ _key.NumCyclesPower = firstByte & 0x3F;
+ if ((firstByte & 0xC0) == 0)
+ return S_OK;
+ _key.SaltSize = (firstByte >> 7) & 1;
+ UInt32 ivSize = (firstByte >> 6) & 1;
+
+ if (pos >= size)
+ return E_INVALIDARG;
+ Byte secondByte = data[pos++];
+
+ _key.SaltSize += (secondByte >> 4);
+ ivSize += (secondByte & 0x0F);
+
+ if (pos + _key.SaltSize + ivSize > size)
+ return E_INVALIDARG;
+ for (i = 0; i < _key.SaltSize; i++)
+ _key.Salt[i] = data[pos++];
+ for (i = 0; i < ivSize; i++)
+ _iv[i] = data[pos++];
+ return S_OK;
+}
+
+STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size)
+{
+ _key.Password.SetCapacity(size);
+ memcpy(_key.Password, data, size);
+ return S_OK;
+}
+
+/*
+static Byte *WideToRaw(const wchar_t *src, Byte *dest, int destSize=0x10000000)
+{
+ for (int i = 0; i < destSize; i++, src++)
+ {
+ dest[i * 2] = (Byte)*src;
+ dest[i * 2 + 1]= (Byte)(*src >> 8);
+ if (*src == 0)
+ break;
+ }
+ return(dest);
+}
+*/
+
+#ifndef CRYPTO_AES
+bool GetAESLibPath(TCHAR *path)
+{
+ TCHAR fullPath[MAX_PATH + 1];
+ if (::GetModuleFileName(g_hInstance, fullPath, MAX_PATH) == 0)
+ return false;
+ LPTSTR fileNamePointer;
+ DWORD needLength = ::GetFullPathName(fullPath, MAX_PATH + 1,
+ path, &fileNamePointer);
+ if (needLength == 0 || needLength >= MAX_PATH)
+ return false;
+ lstrcpy(fileNamePointer, TEXT("AES.dll"));
+ return true;
+}
+#endif
+
+STDMETHODIMP CBaseCoder::Init()
+{
+ CalculateDigest();
+ if (_aesFilter == 0)
+ {
+ RINOK(CreateFilter());
+ }
+ CMyComPtr<ICryptoProperties> cp;
+ RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp));
+ RINOK(cp->SetKey(_key.Key, sizeof(_key.Key)));
+ RINOK(cp->SetInitVector(_iv, sizeof(_iv)));
+ return S_OK;
+}
+
+STDMETHODIMP_(UInt32) CBaseCoder::Filter(Byte *data, UInt32 size)
+{
+ return _aesFilter->Filter(data, size);
+}
+
+#ifndef CRYPTO_AES
+HRESULT CBaseCoder::CreateFilterFromDLL(REFCLSID clsID)
+{
+ if (!_aesLibrary)
+ {
+ TCHAR filePath[MAX_PATH + 2];
+ if (!GetAESLibPath(filePath))
+ return ::GetLastError();
+ return _aesLibrary.LoadAndCreateFilter(filePath, clsID, &_aesFilter);
+ }
+ return S_OK;
+}
+#endif
+
+HRESULT CEncoder::CreateFilter()
+{
+ #ifdef CRYPTO_AES
+ _aesFilter = new CAES_CBC_Encoder;
+ return S_OK;
+ #else
+ return CreateFilterFromDLL(CLSID_CCrypto_AES_CBC_Encoder);
+ #endif
+}
+
+HRESULT CDecoder::CreateFilter()
+{
+ #ifdef CRYPTO_AES
+ _aesFilter = new CAES_CBC_Decoder;
+ return S_OK;
+ #else
+ return CreateFilterFromDLL(CLSID_CCrypto_AES_CBC_Decoder);
+ #endif
+}
+
+}}
diff --git a/CPP/7zip/Crypto/7zAES/7zAES.dsp b/CPP/7zip/Crypto/7zAES/7zAES.dsp
new file mode 100755
index 00000000..37cd7792
--- /dev/null
+++ b/CPP/7zip/Crypto/7zAES/7zAES.dsp
@@ -0,0 +1,245 @@
+# Microsoft Developer Studio Project File - Name="7zAES" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=7zAES - 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 "7zAES.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 "7zAES.mak" CFG="7zAES - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "7zAES - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "7zAES - 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)" == "7zAES - 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 "7zAES_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /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\7zAES.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "7zAES - 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 "7zAES_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" /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\7zAES.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "7zAES - Win32 Release"
+# Name "7zAES - 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 "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\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.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 "7-Zip Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.h
+# End Source File
+# End Group
+# Begin Group "Archive Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderLoader.h
+# End Source File
+# End Group
+# Begin Group "Hash"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Hash\RotateDefs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Hash\Sha256.cpp
+
+!IF "$(CFG)" == "7zAES - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7zAES - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\Hash\Sha256.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\7zAES.cpp
+
+!IF "$(CFG)" == "7zAES - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "7zAES - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zAES.h
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/Crypto/7zAES/7zAES.dsw b/CPP/7zip/Crypto/7zAES/7zAES.dsw
new file mode 100755
index 00000000..08efbad8
--- /dev/null
+++ b/CPP/7zip/Crypto/7zAES/7zAES.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "7zAES"=.\7zAES.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Crypto/7zAES/7zAES.h b/CPP/7zip/Crypto/7zAES/7zAES.h
new file mode 100755
index 00000000..f312f7e6
--- /dev/null
+++ b/CPP/7zip/Crypto/7zAES/7zAES.h
@@ -0,0 +1,122 @@
+// 7z_AES.h
+
+#ifndef __CRYPTO_7Z_AES_H
+#define __CRYPTO_7Z_AES_H
+
+#include "Common/MyCom.h"
+#include "Common/Types.h"
+#include "Common/Buffer.h"
+#include "Common/Vector.h"
+
+#include "../../ICoder.h"
+#include "../../IPassword.h"
+
+#ifndef CRYPTO_AES
+#include "../../Archive/Common/CoderLoader.h"
+#endif
+
+DEFINE_GUID(CLSID_CCrypto_AES_CBC_Encoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0xC1, 0x00, 0x00, 0x00, 0x01, 0x00);
+
+DEFINE_GUID(CLSID_CCrypto_AES_CBC_Decoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+namespace NCrypto {
+namespace NSevenZ {
+
+const int kKeySize = 32;
+
+class CKeyInfo
+{
+public:
+ int NumCyclesPower;
+ UInt32 SaltSize;
+ Byte Salt[16];
+ CByteBuffer Password;
+ Byte Key[kKeySize];
+
+ bool IsEqualTo(const CKeyInfo &a) const;
+ void CalculateDigest();
+
+ CKeyInfo() { Init(); }
+ void Init()
+ {
+ NumCyclesPower = 0;
+ SaltSize = 0;
+ for (int i = 0; i < sizeof(Salt); i++)
+ Salt[i] = 0;
+ }
+};
+
+class CKeyInfoCache
+{
+ int Size;
+ CObjectVector<CKeyInfo> Keys;
+public:
+ CKeyInfoCache(int size): Size(size) {}
+ bool Find(CKeyInfo &key);
+ // HRESULT Calculate(CKeyInfo &key);
+ void Add(CKeyInfo &key);
+};
+
+class CBase
+{
+ CKeyInfoCache _cachedKeys;
+protected:
+ CKeyInfo _key;
+ Byte _iv[16];
+ // int _ivSize;
+ void CalculateDigest();
+ CBase();
+};
+
+class CBaseCoder:
+ public ICompressFilter,
+ public ICryptoSetPassword,
+ public CMyUnknownImp,
+ public CBase
+{
+protected:
+ #ifndef CRYPTO_AES
+ CCoderLibrary _aesLibrary;
+ #endif
+ CMyComPtr<ICompressFilter> _aesFilter;
+
+ virtual HRESULT CreateFilter() = 0;
+ #ifndef CRYPTO_AES
+ HRESULT CreateFilterFromDLL(REFCLSID clsID);
+ #endif
+public:
+ STDMETHOD(Init)();
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+
+ STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
+};
+
+class CEncoder:
+ public CBaseCoder,
+ public ICompressWriteCoderProperties
+{
+ virtual HRESULT CreateFilter();
+public:
+ MY_UNKNOWN_IMP2(
+ ICryptoSetPassword,
+ ICompressWriteCoderProperties)
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+};
+
+class CDecoder:
+ public CBaseCoder,
+ public ICompressSetDecoderProperties2
+{
+ virtual HRESULT CreateFilter();
+public:
+ MY_UNKNOWN_IMP2(
+ ICryptoSetPassword,
+ ICompressSetDecoderProperties2)
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/7zAES/DllExports.cpp b/CPP/7zip/Crypto/7zAES/DllExports.cpp
new file mode 100755
index 00000000..8766ded4
--- /dev/null
+++ b/CPP/7zip/Crypto/7zAES/DllExports.cpp
@@ -0,0 +1,111 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#include "7zAES.h"
+
+/*
+// {23170F69-40C1-278B-0703-000000000000}
+DEFINE_GUID(CLSID_CCrypto_Hash_SHA256,
+0x23170F69, 0x40C1, 0x278B, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+*/
+
+// {23170F69-40C1-278B-06F1-070100000100}
+DEFINE_GUID(CLSID_CCrypto7zAESEncoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x07, 0x01, 0x00, 0x00, 0x01, 0x00);
+
+// {23170F69-40C1-278B-06F1-070100000000}
+DEFINE_GUID(CLSID_CCrypto7zAESDecoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00);
+
+HINSTANCE g_hInstance;
+#ifndef _UNICODE
+bool g_IsNT = false;
+static bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+#endif
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ g_hInstance = hInstance;
+ #ifndef _UNICODE
+ g_IsNT = IsItWindowsNT();
+ #endif
+ }
+ return TRUE;
+}
+
+STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
+{
+ COM_TRY_BEGIN
+ *outObject = 0;
+ int correctInterface = (*iid == IID_ICompressFilter);
+ CMyComPtr<ICompressFilter> filter;
+ if (*clsid == CLSID_CCrypto7zAESDecoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ filter = (ICompressFilter *)new NCrypto::NSevenZ::CDecoder();
+ }
+ else if (*clsid == CLSID_CCrypto7zAESEncoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ filter = (ICompressFilter *)new NCrypto::NSevenZ::CEncoder();
+ }
+ else
+ return CLASS_E_CLASSNOTAVAILABLE;
+ *outObject = filter.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[] = { 0x06, (char)(unsigned char)0xF1, 0x07, 0x01 };
+ if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NMethodPropID::kName:
+ if ((value->bstrVal = ::SysAllocString(L"7zAES")) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ case NMethodPropID::kDecoder:
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CCrypto7zAESDecoder, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ case NMethodPropID::kEncoder:
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CCrypto7zAESEncoder, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ return S_OK;
+}
+
diff --git a/CPP/7zip/Crypto/7zAES/StdAfx.cpp b/CPP/7zip/Crypto/7zAES/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Crypto/7zAES/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Crypto/7zAES/StdAfx.h b/CPP/7zip/Crypto/7zAES/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Crypto/7zAES/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Crypto/7zAES/makefile b/CPP/7zip/Crypto/7zAES/makefile
new file mode 100755
index 00000000..c3d9a51d
--- /dev/null
+++ b/CPP/7zip/Crypto/7zAES/makefile
@@ -0,0 +1,52 @@
+PROG = 7zAES.dll
+DEF_FILE = ../Codec.def
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib user32.lib
+
+7ZAES_OBJS = \
+ $O\DllExports.obj \
+
+7ZAES_OPT_OBJS = \
+ $O\7zAES.obj \
+
+CRYPTO_HASH_OBJS = \
+ $O\Sha256.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\NewHandler.obj \
+ $O\StringConvert.obj \
+ $O\Vector.obj \
+
+WIN_OBJS = \
+ $O\DLL.obj \
+ $O\Synchronization.obj
+
+7ZIP_COMMON_OBJS = \
+ $O\StreamObjects.obj \
+ $O\StreamUtils.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(7ZAES_OBJS) \
+ $(7ZAES_OPT_OBJS) \
+ $(CRYPTO_HASH_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(7ZAES_OBJS): $(*B).cpp
+ $(COMPL)
+$(7ZAES_OPT_OBJS): $(*B).cpp
+ $(COMPL)
+$(CRYPTO_HASH_OBJS): ../../Crypto/Hash/$(*B).cpp
+ $(COMPL_O2)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/Crypto/7zAES/resource.rc b/CPP/7zip/Crypto/7zAES/resource.rc
new file mode 100755
index 00000000..24d428de
--- /dev/null
+++ b/CPP/7zip/Crypto/7zAES/resource.rc
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("7zAES Codec", "7zAES")
diff --git a/CPP/7zip/Crypto/AES/AES.dsp b/CPP/7zip/Crypto/AES/AES.dsp
new file mode 100755
index 00000000..d039be77
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/AES.dsp
@@ -0,0 +1,203 @@
+# Microsoft Developer Studio Project File - Name="AES" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=AES - 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 "AES.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 "AES.mak" CFG="AES - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "AES - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "AES - 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)" == "AES - 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 "AES_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AES_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\Codecs\AES.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "AES - 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 "AES_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AES_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\Codecs\AES.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "AES - Win32 Release"
+# Name "AES - 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 "AES"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\aes.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\aescpp.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\aescrypt.c
+
+!IF "$(CFG)" == "AES - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "AES - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\aeskey.c
+
+!IF "$(CFG)" == "AES - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "AES - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\aesopt.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\aestab.c
+
+!IF "$(CFG)" == "AES - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "AES - Win32 Debug"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ENDIF
+
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\AES_CBC.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\MyAES.cpp
+
+!IF "$(CFG)" == "AES - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "AES - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\MyAES.h
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/Crypto/AES/AES.dsw b/CPP/7zip/Crypto/AES/AES.dsw
new file mode 100755
index 00000000..7fa9d07b
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/AES.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "AES"=.\AES.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/Crypto/AES/AES_CBC.h b/CPP/7zip/Crypto/AES/AES_CBC.h
new file mode 100755
index 00000000..fa3485a9
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/AES_CBC.h
@@ -0,0 +1,39 @@
+// AES_CBC.h
+
+#ifndef __AES_CBC_H
+#define __AES_CBC_H
+
+#include "aescpp.h"
+
+class CAES_CBC: public AESclass
+{
+protected:
+ Byte _prevBlock[16];
+public:
+ void Init(const Byte *iv)
+ {
+ for (int i = 0; i < 16; i++)
+ _prevBlock[i] = iv[i];
+ }
+ void Encode(const Byte *inBlock, Byte *outBlock)
+ {
+ int i;
+ for (i = 0; i < 16; i++)
+ _prevBlock[i] ^= inBlock[i];
+ enc_blk(_prevBlock, outBlock);
+ for (i = 0; i < 16; i++)
+ _prevBlock[i] = outBlock[i];
+ }
+
+ void Decode(const Byte *inBlock, Byte *outBlock)
+ {
+ dec_blk(inBlock, outBlock);
+ int i;
+ for (i = 0; i < 16; i++)
+ outBlock[i] ^= _prevBlock[i];
+ for (i = 0; i < 16; i++)
+ _prevBlock[i] = inBlock[i];
+ }
+};
+
+#endif
diff --git a/CPP/7zip/Crypto/AES/DllExports.cpp b/CPP/7zip/Crypto/AES/DllExports.cpp
new file mode 100755
index 00000000..7c21ac5c
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/DllExports.cpp
@@ -0,0 +1,100 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/ComTry.h"
+#include "MyAES.h"
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /* lpReserved */)
+{
+ return TRUE;
+}
+
+#define MY_CreateClass(n) \
+if (*clsid == CLSID_CCrypto_ ## n ## _Encoder) { \
+ if (!correctInterface) return E_NOINTERFACE; \
+ filter = (ICompressFilter *)new C ## n ## _Encoder(); \
+ } else if (*clsid == CLSID_CCrypto_ ## n ## _Decoder){ \
+ if (!correctInterface) return E_NOINTERFACE; \
+ filter = (ICompressFilter *)new C ## n ## _Decoder(); \
+ }
+
+STDAPI CreateObject(
+ const GUID *clsid,
+ const GUID *interfaceID,
+ void **outObject)
+{
+ COM_TRY_BEGIN
+ *outObject = 0;
+ int correctInterface = (*interfaceID == IID_ICompressFilter);
+ CMyComPtr<ICompressFilter> filter;
+
+ MY_CreateClass(AES_CBC)
+ else
+ MY_CreateClass(AES_ECB)
+ else
+ return CLASS_E_CLASSNOTAVAILABLE;
+ *outObject = filter.Detach();
+ return S_OK;
+ COM_TRY_END
+}
+
+struct CAESMethodItem
+{
+ char ID[3];
+ const wchar_t *UserName;
+ const GUID *Decoder;
+ const GUID *Encoder;
+};
+
+#define METHOD_ITEM(Name, id, UserName) \
+ { { 0x06, 0x01, id }, UserName, \
+ &CLSID_CCrypto_ ## Name ## _Decoder, \
+ &CLSID_CCrypto_ ## Name ## _Encoder }
+
+
+static CAESMethodItem g_Methods[] =
+{
+ METHOD_ITEM(AES_ECB, (char)(unsigned char)0xC0, L"AES-ECB"),
+ METHOD_ITEM(AES_CBC, (char)(unsigned char)0xC1, L"AES")
+};
+
+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 CAESMethodItem &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;
+ case NMethodPropID::kEncoder:
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)method.Encoder, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ return S_OK;
+}
+
diff --git a/CPP/7zip/Crypto/AES/MyAES.cpp b/CPP/7zip/Crypto/AES/MyAES.cpp
new file mode 100755
index 00000000..359caa25
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/MyAES.cpp
@@ -0,0 +1,94 @@
+// Crypto/AES/MyAES.cpp
+
+#include "StdAfx.h"
+
+#include "windows.h"
+
+#include "MyAES.h"
+#include "Windows/Defs.h"
+
+#include "AES_CBC.h"
+
+static const int kAESBlockSize = 16;
+
+extern "C"
+{
+#include "aesopt.h"
+}
+
+class CTabInit
+{
+public:
+ CTabInit() { gen_tabs();}
+} g_TabInit;
+
+STDMETHODIMP CAESFilter::Init() { return S_OK; }
+
+STDMETHODIMP_(UInt32) CAESFilter::Filter(Byte *data, UInt32 size)
+{
+ if (size > 0 && size < kAESBlockSize)
+ return kAESBlockSize;
+ UInt32 i;
+ for (i = 0; i + kAESBlockSize <= size; i += kAESBlockSize)
+ {
+ Byte outBlock[kAESBlockSize];
+ SubFilter(data + i, outBlock);
+ for (int j = 0; j < kAESBlockSize; j++)
+ data[i + j] = outBlock[j];
+ }
+ return i;
+}
+
+STDMETHODIMP CAESFilter::SetInitVector(const Byte *data, UInt32 size)
+{
+ if (size != 16)
+ return E_INVALIDARG;
+ AES.Init(data);
+ return S_OK;
+}
+
+STDMETHODIMP CAESEncoder::SetKey(const Byte *data, UInt32 size)
+ { return (AES.enc_key(data, size) == aes_good) ? S_OK: E_FAIL; }
+
+void CAESEncoder::SubFilter(const Byte *inBlock, Byte *outBlock)
+ { AES.Encode(inBlock, outBlock); }
+
+STDMETHODIMP CAESDecoder::SetKey(const Byte *data, UInt32 size)
+ { return (AES.dec_key(data, size) == aes_good) ? S_OK: E_FAIL; }
+
+void CAESDecoder::SubFilter(const Byte *inBlock, Byte *outBlock)
+ { AES.Decode(inBlock, outBlock); }
+
+////////////////////////////
+// ECB mode
+
+STDMETHODIMP CAesEcbFilter::Init() { return S_OK; }
+STDMETHODIMP CAesEcbFilter::SetInitVector(const Byte * /* data */, UInt32 size)
+ { return (size == 0) ? S_OK: E_INVALIDARG; }
+
+STDMETHODIMP_(UInt32) CAesEcbFilter::Filter(Byte *data, UInt32 size)
+{
+ if (size > 0 && size < kAESBlockSize)
+ return kAESBlockSize;
+ UInt32 i;
+ for (i = 0; i + kAESBlockSize <= size; i += kAESBlockSize)
+ {
+ Byte outBlock[kAESBlockSize];
+ SubFilter(data + i, outBlock);
+ for (int j = 0; j < kAESBlockSize; j++)
+ data[i + j] = outBlock[j];
+ }
+ return i;
+}
+
+STDMETHODIMP CAesEcbEncoder::SetKey(const Byte *data, UInt32 size)
+ { return (AES.enc_key(data, size) == aes_good) ? S_OK: E_FAIL; }
+
+void CAesEcbEncoder::SubFilter(const Byte *inBlock, Byte *outBlock)
+ { AES.enc_blk(inBlock, outBlock); }
+
+STDMETHODIMP CAesEcbDecoder::SetKey(const Byte *data, UInt32 size)
+ { return (AES.dec_key(data, size) == aes_good) ? S_OK: E_FAIL; }
+
+void CAesEcbDecoder::SubFilter(const Byte *inBlock, Byte *outBlock)
+ { AES.dec_blk(inBlock, outBlock); }
diff --git a/CPP/7zip/Crypto/AES/MyAES.h b/CPP/7zip/Crypto/AES/MyAES.h
new file mode 100755
index 00000000..f58913ae
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/MyAES.h
@@ -0,0 +1,106 @@
+// Crypto/AES/MyAES.h
+
+#ifndef __CIPHER_MYAES_H
+#define __CIPHER_MYAES_H
+
+#include "Common/Types.h"
+#include "Common/MyCom.h"
+
+#include "../../ICoder.h"
+#include "AES_CBC.h"
+
+class CAESFilter:
+ public ICompressFilter,
+ public ICryptoProperties,
+ public CMyUnknownImp
+{
+protected:
+ CAES_CBC AES;
+ // Byte Key[32];
+ // Byte IV[kAESBlockSize];
+public:
+ MY_UNKNOWN_IMP1(ICryptoProperties)
+ STDMETHOD(Init)();
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+ STDMETHOD(SetKey)(const Byte *data, UInt32 size) = 0;
+ STDMETHOD(SetInitVector)(const Byte *data, UInt32 size);
+ virtual void SubFilter(const Byte *inBlock, Byte *outBlock) = 0;
+};
+
+class CAESEncoder: public CAESFilter
+{
+public:
+ STDMETHOD(SetKey)(const Byte *data, UInt32 size);
+ virtual void SubFilter(const Byte *inBlock, Byte *outBlock);
+};
+
+class CAESDecoder: public CAESFilter
+{
+public:
+ STDMETHOD(SetKey)(const Byte *data, UInt32 size);
+ virtual void SubFilter(const Byte *inBlock, Byte *outBlock);
+};
+
+#define MyClassCrypto3E(Name) class C ## Name: public CAESEncoder { };
+#define MyClassCrypto3D(Name) class C ## Name: public CAESDecoder { };
+
+// {23170F69-40C1-278B-0601-000000000000}
+#define MyClassCrypto2(Name, id, encodingId) \
+DEFINE_GUID(CLSID_CCrypto_ ## Name, \
+0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, id, 0x00, 0x00, 0x00, encodingId, 0x00);
+
+#define MyClassCrypto(Name, id) \
+MyClassCrypto2(Name ## _Encoder, id, 0x01) \
+MyClassCrypto3E(Name ## _Encoder) \
+MyClassCrypto2(Name ## _Decoder, id, 0x00) \
+MyClassCrypto3D(Name ## _Decoder) \
+
+MyClassCrypto(AES_CBC, 0xC1)
+
+class CAesEcbFilter:
+ public ICompressFilter,
+ public ICryptoProperties,
+ public CMyUnknownImp
+{
+protected:
+ AESclass AES;
+public:
+ MY_UNKNOWN_IMP1(ICryptoProperties)
+ STDMETHOD(Init)();
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+ STDMETHOD(SetKey)(const Byte *data, UInt32 size) = 0;
+ STDMETHOD(SetInitVector)(const Byte *data, UInt32 size);
+ virtual void SubFilter(const Byte *inBlock, Byte *outBlock) = 0;
+};
+
+class CAesEcbEncoder: public CAesEcbFilter
+{
+public:
+ STDMETHOD(SetKey)(const Byte *data, UInt32 size);
+ virtual void SubFilter(const Byte *inBlock, Byte *outBlock);
+};
+
+class CAesEcbDecoder: public CAesEcbFilter
+{
+public:
+ STDMETHOD(SetKey)(const Byte *data, UInt32 size);
+ virtual void SubFilter(const Byte *inBlock, Byte *outBlock);
+};
+
+#define MyClassCrypto3E_Ecb(Name) class C ## Name: public CAesEcbEncoder { };
+#define MyClassCrypto3D_Ecb(Name) class C ## Name: public CAesEcbDecoder { };
+
+// {23170F69-40C1-278B-0601-000000000000}
+#define MyClassCrypto2_Ecb(Name, id, encodingId) \
+DEFINE_GUID(CLSID_CCrypto_ ## Name, \
+0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, id, 0x00, 0x00, 0x00, encodingId, 0x00);
+
+#define MyClassCrypto_Ecb(Name, id) \
+MyClassCrypto2_Ecb(Name ## _Encoder, id, 0x01) \
+MyClassCrypto3E_Ecb(Name ## _Encoder) \
+MyClassCrypto2_Ecb(Name ## _Decoder, id, 0x00) \
+MyClassCrypto3D_Ecb(Name ## _Decoder) \
+
+MyClassCrypto_Ecb(AES_ECB, 0xC0)
+
+#endif
diff --git a/CPP/7zip/Crypto/AES/StdAfx.cpp b/CPP/7zip/Crypto/AES/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Crypto/AES/StdAfx.h b/CPP/7zip/Crypto/AES/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Crypto/AES/aes.h b/CPP/7zip/Crypto/AES/aes.h
new file mode 100755
index 00000000..9aaba978
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/aes.h
@@ -0,0 +1,103 @@
+/*
+ -------------------------------------------------------------------------
+ Copyright (c) 2001, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+ 1. distributions of this source code include the above copyright
+ notice, this list of conditions and the following disclaimer;
+
+ 2. distributions in binary form include the above copyright
+ notice, this list of conditions and the following disclaimer
+ in the documentation and/or other associated materials;
+
+ 3. the copyright holder's name is not used to endorse products
+ built using this software without specific written permission.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and fitness for purpose.
+ -------------------------------------------------------------------------
+ Issue Date: 29/07/2002
+
+ This file contains the definitions required to use AES (Rijndael) in C.
+*/
+
+#ifndef _AES_H
+#define _AES_H
+
+/* This include is used only to find 8 and 32 bit unsigned integer types */
+
+#include "limits.h"
+
+#if UCHAR_MAX == 0xff /* an unsigned 8 bit type for internal AES use */
+ typedef unsigned char aes_08t;
+#else
+#error Please define an unsigned 8 bit type in aes.h
+#endif
+
+#if UINT_MAX == 0xffffffff /* an unsigned 32 bit type for internal AES use */
+ typedef unsigned int aes_32t;
+#elif ULONG_MAX == 0xffffffff
+ typedef unsigned long aes_32t;
+#else
+#error Please define an unsigned 32 bit type in aes.h
+#endif
+
+/* BLOCK_SIZE is in BYTES: 16, 24, 32 or undefined for aes.c and 16, 20,
+ 24, 28, 32 or undefined for aespp.c. When left undefined a slower
+ version that provides variable block length is compiled.
+*/
+
+#define BLOCK_SIZE 16
+
+/* key schedule length (in 32-bit words) */
+
+#if !defined(BLOCK_SIZE)
+#define KS_LENGTH 128
+#else
+#define KS_LENGTH 4 * BLOCK_SIZE
+#endif
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+typedef unsigned int aes_fret; /* type for function return value */
+#define aes_bad 0 /* bad function return value */
+#define aes_good 1 /* good function return value */
+#ifndef AES_DLL /* implement normal or DLL functions */
+#define aes_rval aes_fret
+#else
+#define aes_rval aes_fret __declspec(dllexport) _stdcall
+#endif
+
+
+typedef struct /* the AES context for encryption */
+{ aes_32t k_sch[KS_LENGTH]; /* the encryption key schedule */
+ aes_32t n_rnd; /* the number of cipher rounds */
+ aes_32t n_blk; /* the number of bytes in the state */
+} aes_ctx;
+
+#if !defined(BLOCK_SIZE)
+aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1]);
+#endif
+
+aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]);
+aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]);
+
+aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]);
+aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/CPP/7zip/Crypto/AES/aescpp.h b/CPP/7zip/Crypto/AES/aescpp.h
new file mode 100755
index 00000000..93e3c8b0
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/aescpp.h
@@ -0,0 +1,55 @@
+
+/*
+ -------------------------------------------------------------------------
+ Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
+ All rights reserved.
+
+ TERMS
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted subject to the following conditions:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. The copyright holder's name must not be used to endorse or promote
+ any products derived from this software without his specific prior
+ written permission.
+
+ This software is provided 'as is' with no express or implied warranties
+ of correctness or fitness for purpose.
+ -------------------------------------------------------------------------
+ Issue Date: 21/01/2002
+
+ This file contains the definitions required to use AES (Rijndael) in C++.
+*/
+
+#ifndef _AESCPP_H
+#define _AESCPP_H
+
+#include "aes.h"
+
+class AESclass
+{ aes_ctx cx[1];
+public:
+#if defined(BLOCK_SIZE)
+ AESclass() { cx->n_blk = BLOCK_SIZE; cx->n_rnd = 0; }
+#else
+ AESclass(unsigned int blen = 16) { cx->n_blk = blen; cx->n_rnd = 0; }
+ aes_rval blk_len(unsigned int blen) { return aes_blk_len(blen, cx); }
+#endif
+ aes_rval enc_key(const unsigned char in_key[], unsigned int klen)
+ { return aes_enc_key(in_key, klen, cx); }
+ aes_rval dec_key(const unsigned char in_key[], unsigned int klen)
+ { return aes_dec_key(in_key, klen, cx); }
+ aes_rval enc_blk(const unsigned char in_blk[], unsigned char out_blk[])
+ { return aes_enc_blk(in_blk, out_blk, cx); }
+ aes_rval dec_blk(const unsigned char in_blk[], unsigned char out_blk[])
+ { return aes_dec_blk(in_blk, out_blk, cx); }
+};
+
+#endif
diff --git a/CPP/7zip/Crypto/AES/aescrypt.c b/CPP/7zip/Crypto/AES/aescrypt.c
new file mode 100755
index 00000000..095a61c4
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/aescrypt.c
@@ -0,0 +1,421 @@
+/*
+ -------------------------------------------------------------------------
+ Copyright (c) 2001, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+ 1. distributions of this source code include the above copyright
+ notice, this list of conditions and the following disclaimer;
+
+ 2. distributions in binary form include the above copyright
+ notice, this list of conditions and the following disclaimer
+ in the documentation and/or other associated materials;
+
+ 3. the copyright holder's name is not used to endorse products
+ built using this software without specific written permission.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and fitness for purpose.
+ -------------------------------------------------------------------------
+ Issue Date: 29/07/2002
+
+ This file contains the code for implementing encryption and decryption
+ for AES (Rijndael) for block and key sizes of 16, 24 and 32 bytes. It
+ can optionally be replaced by code written in assembler using NASM.
+*/
+
+#include "aesopt.h"
+
+#if defined(BLOCK_SIZE) && (BLOCK_SIZE & 7)
+#error An illegal block size has been specified.
+#endif
+
+#define unused 77 /* Sunset Strip */
+
+#define si(y,x,k,c) s(y,c) = word_in(x + 4 * c) ^ k[c]
+#define so(y,x,c) word_out(y + 4 * c, s(x,c))
+
+#if BLOCK_SIZE == 16
+
+#if defined(ARRAYS)
+#define locals(y,x) x[4],y[4]
+#else
+#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
+ /*
+ the following defines prevent the compiler requiring the declaration
+ of generated but unused variables in the fwd_var and inv_var macros
+ */
+#define b04 unused
+#define b05 unused
+#define b06 unused
+#define b07 unused
+#define b14 unused
+#define b15 unused
+#define b16 unused
+#define b17 unused
+#endif
+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
+ s(y,2) = s(x,2); s(y,3) = s(x,3);
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
+
+#elif BLOCK_SIZE == 24
+
+#if defined(ARRAYS)
+#define locals(y,x) x[6],y[6]
+#else
+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \
+ y##0,y##1,y##2,y##3,y##4,y##5
+#define b06 unused
+#define b07 unused
+#define b16 unused
+#define b17 unused
+#endif
+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
+ s(y,4) = s(x,4); s(y,5) = s(x,5);
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
+ si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \
+ so(y,x,3); so(y,x,4); so(y,x,5)
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
+ rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
+#else
+
+#if defined(ARRAYS)
+#define locals(y,x) x[8],y[8]
+#else
+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
+ y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
+#endif
+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
+ s(y,4) = s(x,4); s(y,5) = s(x,5); \
+ s(y,6) = s(x,6); s(y,7) = s(x,7);
+
+#if BLOCK_SIZE == 32
+
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \
+ si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
+ so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \
+ rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
+#else
+
+#define state_in(y,x,k) \
+switch(nc) \
+{ case 8: si(y,x,k,7); si(y,x,k,6); \
+ case 6: si(y,x,k,5); si(y,x,k,4); \
+ case 4: si(y,x,k,3); si(y,x,k,2); \
+ si(y,x,k,1); si(y,x,k,0); \
+}
+
+#define state_out(y,x) \
+switch(nc) \
+{ case 8: so(y,x,7); so(y,x,6); \
+ case 6: so(y,x,5); so(y,x,4); \
+ case 4: so(y,x,3); so(y,x,2); \
+ so(y,x,1); so(y,x,0); \
+}
+
+#if defined(FAST_VARIABLE)
+
+#define round(rm,y,x,k) \
+switch(nc) \
+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
+ rm(y,x,k,5); rm(y,x,k,4); \
+ rm(y,x,k,3); rm(y,x,k,2); \
+ rm(y,x,k,1); rm(y,x,k,0); \
+ break; \
+ case 6: rm(y,x,k,5); rm(y,x,k,4); \
+ rm(y,x,k,3); rm(y,x,k,2); \
+ rm(y,x,k,1); rm(y,x,k,0); \
+ break; \
+ case 4: rm(y,x,k,3); rm(y,x,k,2); \
+ rm(y,x,k,1); rm(y,x,k,0); \
+ break; \
+}
+#else
+
+#define round(rm,y,x,k) \
+switch(nc) \
+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
+ case 6: rm(y,x,k,5); rm(y,x,k,4); \
+ case 4: rm(y,x,k,3); rm(y,x,k,2); \
+ rm(y,x,k,1); rm(y,x,k,0); \
+}
+
+#endif
+
+#endif
+#endif
+
+#if defined(ENCRYPTION)
+
+/* I am grateful to Frank Yellin for the following construction
+ (and that for decryption) which, given the column (c) of the
+ output state variable, gives the input state variables which
+ are needed in its computation for each row (r) of the state.
+
+ For the fixed block size options, compilers should be able to
+ reduce this complex expression (and the equivalent one for
+ decryption) to a static variable reference at compile time.
+ But for variable block size code, there will be some limbs on
+ which conditional clauses will be returned.
+*/
+
+/* y = output word, x = input word, r = row, c = column for r = 0,
+ 1, 2 and 3 = column accessed for row r.
+*/
+
+#define fwd_var(x,r,c)\
+ ( r == 0 ? \
+ ( c == 0 ? s(x,0) \
+ : c == 1 ? s(x,1) \
+ : c == 2 ? s(x,2) \
+ : c == 3 ? s(x,3) \
+ : c == 4 ? s(x,4) \
+ : c == 5 ? s(x,5) \
+ : c == 6 ? s(x,6) \
+ : s(x,7))\
+ : r == 1 ? \
+ ( c == 0 ? s(x,1) \
+ : c == 1 ? s(x,2) \
+ : c == 2 ? s(x,3) \
+ : c == 3 ? nc == 4 ? s(x,0) : s(x,4) \
+ : c == 4 ? s(x,5) \
+ : c == 5 ? nc == 8 ? s(x,6) : s(x,0) \
+ : c == 6 ? s(x,7) \
+ : s(x,0))\
+ : r == 2 ? \
+ ( c == 0 ? nc == 8 ? s(x,3) : s(x,2) \
+ : c == 1 ? nc == 8 ? s(x,4) : s(x,3) \
+ : c == 2 ? nc == 4 ? s(x,0) : nc == 8 ? s(x,5) : s(x,4) \
+ : c == 3 ? nc == 4 ? s(x,1) : nc == 8 ? s(x,6) : s(x,5) \
+ : c == 4 ? nc == 8 ? s(x,7) : s(x,0) \
+ : c == 5 ? nc == 8 ? s(x,0) : s(x,1) \
+ : c == 6 ? s(x,1) \
+ : s(x,2))\
+ : \
+ ( c == 0 ? nc == 8 ? s(x,4) : s(x,3) \
+ : c == 1 ? nc == 4 ? s(x,0) : nc == 8 ? s(x,5) : s(x,4) \
+ : c == 2 ? nc == 4 ? s(x,1) : nc == 8 ? s(x,6) : s(x,5) \
+ : c == 3 ? nc == 4 ? s(x,2) : nc == 8 ? s(x,7) : s(x,0) \
+ : c == 4 ? nc == 8 ? s(x,0) : s(x,1) \
+ : c == 5 ? nc == 8 ? s(x,1) : s(x,2) \
+ : c == 6 ? s(x,2) \
+ : s(x,3)))
+
+#if defined(FT4_SET)
+#undef dec_fmvars
+#define dec_fmvars
+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c)
+#elif defined(FT1_SET)
+#undef dec_fmvars
+#define dec_fmvars
+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c)
+#else
+#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c]
+#endif
+
+#if defined(FL4_SET)
+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c)
+#elif defined(FL1_SET)
+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c)
+#else
+#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c]
+#endif
+
+aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1])
+{ aes_32t locals(b0, b1);
+ const aes_32t *kp = cx->k_sch;
+ dec_fmvars /* declare variables for fwd_mcol() if needed */
+
+ if(!(cx->n_blk & 1)) return aes_bad;
+
+ state_in(b0, in_blk, kp);
+
+#if (ENC_UNROLL == FULL)
+
+ kp += (cx->n_rnd - 9) * nc;
+
+ switch(cx->n_rnd)
+ {
+ case 14: round(fwd_rnd, b1, b0, kp - 4 * nc);
+ round(fwd_rnd, b0, b1, kp - 3 * nc);
+ case 12: round(fwd_rnd, b1, b0, kp - 2 * nc);
+ round(fwd_rnd, b0, b1, kp - nc);
+ case 10: round(fwd_rnd, b1, b0, kp );
+ round(fwd_rnd, b0, b1, kp + nc);
+ round(fwd_rnd, b1, b0, kp + 2 * nc);
+ round(fwd_rnd, b0, b1, kp + 3 * nc);
+ round(fwd_rnd, b1, b0, kp + 4 * nc);
+ round(fwd_rnd, b0, b1, kp + 5 * nc);
+ round(fwd_rnd, b1, b0, kp + 6 * nc);
+ round(fwd_rnd, b0, b1, kp + 7 * nc);
+ round(fwd_rnd, b1, b0, kp + 8 * nc);
+ round(fwd_lrnd, b0, b1, kp + 9 * nc);
+ }
+#else
+
+#if (ENC_UNROLL == PARTIAL)
+ { aes_32t rnd;
+ for(rnd = 0; rnd < (cx->n_rnd >> 1) - 1; ++rnd)
+ {
+ kp += nc;
+ round(fwd_rnd, b1, b0, kp);
+ kp += nc;
+ round(fwd_rnd, b0, b1, kp);
+ }
+ kp += nc;
+ round(fwd_rnd, b1, b0, kp);
+#else
+ { aes_32t rnd, *p0 = b0, *p1 = b1, *pt;
+ for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd)
+ {
+ kp += nc;
+ round(fwd_rnd, p1, p0, kp);
+ pt = p0, p0 = p1, p1 = pt;
+ }
+#endif
+ kp += nc;
+ round(fwd_lrnd, b0, b1, kp);
+ }
+#endif
+
+ state_out(out_blk, b0);
+ return aes_good;
+}
+
+#endif
+
+#if defined(DECRYPTION)
+
+#define inv_var(x,r,c) \
+ ( r == 0 ? \
+ ( c == 0 ? s(x,0) \
+ : c == 1 ? s(x,1) \
+ : c == 2 ? s(x,2) \
+ : c == 3 ? s(x,3) \
+ : c == 4 ? s(x,4) \
+ : c == 5 ? s(x,5) \
+ : c == 6 ? s(x,6) \
+ : s(x,7))\
+ : r == 1 ? \
+ ( c == 0 ? nc == 4 ? s(x,3) : nc == 8 ? s(x,7) : s(x,5) \
+ : c == 1 ? s(x,0) \
+ : c == 2 ? s(x,1) \
+ : c == 3 ? s(x,2) \
+ : c == 4 ? s(x,3) \
+ : c == 5 ? s(x,4) \
+ : c == 6 ? s(x,5) \
+ : s(x,6))\
+ : r == 2 ? \
+ ( c == 0 ? nc == 4 ? s(x,2) : nc == 8 ? s(x,5) : s(x,4) \
+ : c == 1 ? nc == 4 ? s(x,3) : nc == 8 ? s(x,6) : s(x,5) \
+ : c == 2 ? nc == 8 ? s(x,7) : s(x,0) \
+ : c == 3 ? nc == 8 ? s(x,0) : s(x,1) \
+ : c == 4 ? nc == 8 ? s(x,1) : s(x,2) \
+ : c == 5 ? nc == 8 ? s(x,2) : s(x,3) \
+ : c == 6 ? s(x,3) \
+ : s(x,4))\
+ : \
+ ( c == 0 ? nc == 4 ? s(x,1) : nc == 8 ? s(x,4) : s(x,3) \
+ : c == 1 ? nc == 4 ? s(x,2) : nc == 8 ? s(x,5) : s(x,4) \
+ : c == 2 ? nc == 4 ? s(x,3) : nc == 8 ? s(x,6) : s(x,5) \
+ : c == 3 ? nc == 8 ? s(x,7) : s(x,0) \
+ : c == 4 ? nc == 8 ? s(x,0) : s(x,1) \
+ : c == 5 ? nc == 8 ? s(x,1) : s(x,2) \
+ : c == 6 ? s(x,2) \
+ : s(x,3)))
+
+#if defined(IT4_SET)
+#undef dec_imvars
+#define dec_imvars
+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c)
+#elif defined(IT1_SET)
+#undef dec_imvars
+#define dec_imvars
+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c)
+#else
+#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c])
+#endif
+
+#if defined(IL4_SET)
+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c)
+#elif defined(IL1_SET)
+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c)
+#else
+#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]
+#endif
+
+aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1])
+{ aes_32t locals(b0, b1);
+ const aes_32t *kp = cx->k_sch + nc * cx->n_rnd;
+ dec_imvars /* declare variables for inv_mcol() if needed */
+
+ if(!(cx->n_blk & 2)) return aes_bad;
+
+ state_in(b0, in_blk, kp);
+
+#if (DEC_UNROLL == FULL)
+
+ kp = cx->k_sch + 9 * nc;
+ switch(cx->n_rnd)
+ {
+ case 14: round(inv_rnd, b1, b0, kp + 4 * nc);
+ round(inv_rnd, b0, b1, kp + 3 * nc);
+ case 12: round(inv_rnd, b1, b0, kp + 2 * nc);
+ round(inv_rnd, b0, b1, kp + nc );
+ case 10: round(inv_rnd, b1, b0, kp );
+ round(inv_rnd, b0, b1, kp - nc);
+ round(inv_rnd, b1, b0, kp - 2 * nc);
+ round(inv_rnd, b0, b1, kp - 3 * nc);
+ round(inv_rnd, b1, b0, kp - 4 * nc);
+ round(inv_rnd, b0, b1, kp - 5 * nc);
+ round(inv_rnd, b1, b0, kp - 6 * nc);
+ round(inv_rnd, b0, b1, kp - 7 * nc);
+ round(inv_rnd, b1, b0, kp - 8 * nc);
+ round(inv_lrnd, b0, b1, kp - 9 * nc);
+ }
+#else
+
+#if (DEC_UNROLL == PARTIAL)
+ { aes_32t rnd;
+ for(rnd = 0; rnd < (cx->n_rnd >> 1) - 1; ++rnd)
+ {
+ kp -= nc;
+ round(inv_rnd, b1, b0, kp);
+ kp -= nc;
+ round(inv_rnd, b0, b1, kp);
+ }
+ kp -= nc;
+ round(inv_rnd, b1, b0, kp);
+#else
+ { aes_32t rnd, *p0 = b0, *p1 = b1, *pt;
+ for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd)
+ {
+ kp -= nc;
+ round(inv_rnd, p1, p0, kp);
+ pt = p0, p0 = p1, p1 = pt;
+ }
+#endif
+ kp -= nc;
+ round(inv_lrnd, b0, b1, kp);
+ }
+#endif
+
+ state_out(out_blk, b0);
+ return aes_good;
+}
+
+#endif
diff --git a/CPP/7zip/Crypto/AES/aeskey.c b/CPP/7zip/Crypto/AES/aeskey.c
new file mode 100755
index 00000000..d281e1a8
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/aeskey.c
@@ -0,0 +1,363 @@
+/*
+ -------------------------------------------------------------------------
+ Copyright (c) 2001, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+ 1. distributions of this source code include the above copyright
+ notice, this list of conditions and the following disclaimer;
+
+ 2. distributions in binary form include the above copyright
+ notice, this list of conditions and the following disclaimer
+ in the documentation and/or other associated materials;
+
+ 3. the copyright holder's name is not used to endorse products
+ built using this software without specific written permission.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and fitness for purpose.
+ -------------------------------------------------------------------------
+ Issue Date: 29/07/2002
+
+ This file contains the code for implementing the key schedule for AES
+ (Rijndael) for block and key sizes of 16, 24, and 32 bytes.
+*/
+
+#include "aesopt.h"
+
+#if defined(BLOCK_SIZE) && (BLOCK_SIZE & 7)
+#error An illegal block size has been specified.
+#endif
+
+/* Subroutine to set the block size (if variable) in bytes, legal
+ values being 16, 24 and 32.
+*/
+
+#if !defined(BLOCK_SIZE)
+
+aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1])
+{
+#if !defined(FIXED_TABLES)
+ if(!tab_init) gen_tabs();
+#endif
+
+ if((blen & 7) || blen < 16 || blen > 32)
+ {
+ cx->n_blk = 0; return aes_bad;
+ }
+
+ cx->n_blk = blen;
+ return aes_good;
+}
+
+#endif
+
+/* Initialise the key schedule from the user supplied key. The key
+ length is now specified in bytes - 16, 24 or 32 as appropriate.
+ This corresponds to bit lengths of 128, 192 and 256 bits, and
+ to Nk values of 4, 6 and 8 respectively.
+
+ The following macros implement a single cycle in the key
+ schedule generation process. The number of cycles needed
+ for each cx->n_col and nk value is:
+
+ nk = 4 5 6 7 8
+ ------------------------------
+ cx->n_col = 4 10 9 8 7 7
+ cx->n_col = 5 14 11 10 9 9
+ cx->n_col = 6 19 15 12 11 11
+ cx->n_col = 7 21 19 16 13 14
+ cx->n_col = 8 29 23 19 17 14
+*/
+
+#define ke4(k,i) \
+{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \
+ k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
+}
+#define kel4(k,i) \
+{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \
+ k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
+}
+
+#define ke6(k,i) \
+{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \
+ k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \
+ k[6*(i)+10] = ss[4] ^= ss[3]; k[6*(i)+11] = ss[5] ^= ss[4]; \
+}
+#define kel6(k,i) \
+{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \
+ k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \
+}
+
+#define ke8(k,i) \
+{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \
+ k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \
+ k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); k[8*(i)+13] = ss[5] ^= ss[4]; \
+ k[8*(i)+14] = ss[6] ^= ss[5]; k[8*(i)+15] = ss[7] ^= ss[6]; \
+}
+#define kel8(k,i) \
+{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \
+ k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \
+}
+
+#if defined(ENCRYPTION_KEY_SCHEDULE)
+
+aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1])
+{ aes_32t ss[8];
+
+#if !defined(FIXED_TABLES)
+ if(!tab_init) gen_tabs();
+#endif
+
+#if !defined(BLOCK_SIZE)
+ if(!cx->n_blk) cx->n_blk = 16;
+#else
+ cx->n_blk = BLOCK_SIZE;
+#endif
+
+ cx->n_blk = (cx->n_blk & ~3) | 1;
+
+ cx->k_sch[0] = ss[0] = word_in(in_key );
+ cx->k_sch[1] = ss[1] = word_in(in_key + 4);
+ cx->k_sch[2] = ss[2] = word_in(in_key + 8);
+ cx->k_sch[3] = ss[3] = word_in(in_key + 12);
+
+#if (BLOCK_SIZE == 16) && (ENC_UNROLL != NONE)
+
+ switch(klen)
+ {
+ case 16: ke4(cx->k_sch, 0); ke4(cx->k_sch, 1);
+ ke4(cx->k_sch, 2); ke4(cx->k_sch, 3);
+ ke4(cx->k_sch, 4); ke4(cx->k_sch, 5);
+ ke4(cx->k_sch, 6); ke4(cx->k_sch, 7);
+ ke4(cx->k_sch, 8); kel4(cx->k_sch, 9);
+ cx->n_rnd = 10; break;
+ case 24: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+ cx->k_sch[5] = ss[5] = word_in(in_key + 20);
+ ke6(cx->k_sch, 0); ke6(cx->k_sch, 1);
+ ke6(cx->k_sch, 2); ke6(cx->k_sch, 3);
+ ke6(cx->k_sch, 4); ke6(cx->k_sch, 5);
+ ke6(cx->k_sch, 6); kel6(cx->k_sch, 7);
+ cx->n_rnd = 12; break;
+ case 32: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+ cx->k_sch[5] = ss[5] = word_in(in_key + 20);
+ cx->k_sch[6] = ss[6] = word_in(in_key + 24);
+ cx->k_sch[7] = ss[7] = word_in(in_key + 28);
+ ke8(cx->k_sch, 0); ke8(cx->k_sch, 1);
+ ke8(cx->k_sch, 2); ke8(cx->k_sch, 3);
+ ke8(cx->k_sch, 4); ke8(cx->k_sch, 5);
+ kel8(cx->k_sch, 6);
+ cx->n_rnd = 14; break;
+ default: cx->n_rnd = 0; return aes_bad;
+ }
+#else
+ { aes_32t i, l;
+ cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
+ l = (nc * cx->n_rnd + nc - 1) / (klen >> 2);
+
+ switch(klen)
+ {
+ case 16: for(i = 0; i < l; ++i)
+ ke4(cx->k_sch, i);
+ break;
+ case 24: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+ cx->k_sch[5] = ss[5] = word_in(in_key + 20);
+ for(i = 0; i < l; ++i)
+ ke6(cx->k_sch, i);
+ break;
+ case 32: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+ cx->k_sch[5] = ss[5] = word_in(in_key + 20);
+ cx->k_sch[6] = ss[6] = word_in(in_key + 24);
+ cx->k_sch[7] = ss[7] = word_in(in_key + 28);
+ for(i = 0; i < l; ++i)
+ ke8(cx->k_sch, i);
+ break;
+ default: cx->n_rnd = 0; return aes_bad;
+ }
+ }
+#endif
+
+ return aes_good;
+}
+
+#endif
+
+#if defined(DECRYPTION_KEY_SCHEDULE)
+
+#if (DEC_ROUND != NO_TABLES)
+#define d_vars dec_imvars
+#define ff(x) inv_mcol(x)
+#else
+#define ff(x) (x)
+#define d_vars
+#endif
+
+#if 1
+#define kdf4(k,i) \
+{ ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; ss[1] = ss[1] ^ ss[3]; ss[2] = ss[2] ^ ss[3]; ss[3] = ss[3]; \
+ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; \
+ ss[4] ^= k[4*(i)]; k[4*(i)+4] = ff(ss[4]); ss[4] ^= k[4*(i)+1]; k[4*(i)+5] = ff(ss[4]); \
+ ss[4] ^= k[4*(i)+2]; k[4*(i)+6] = ff(ss[4]); ss[4] ^= k[4*(i)+3]; k[4*(i)+7] = ff(ss[4]); \
+}
+#define kd4(k,i) \
+{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
+ k[4*(i)+4] = ss[4] ^= k[4*(i)]; k[4*(i)+5] = ss[4] ^= k[4*(i)+1]; \
+ k[4*(i)+6] = ss[4] ^= k[4*(i)+2]; k[4*(i)+7] = ss[4] ^= k[4*(i)+3]; \
+}
+#define kdl4(k,i) \
+{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; \
+ k[4*(i)+4] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; k[4*(i)+5] = ss[1] ^ ss[3]; \
+ k[4*(i)+6] = ss[0]; k[4*(i)+7] = ss[1]; \
+}
+#else
+#define kdf4(k,i) \
+{ ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+ 4] = ff(ss[0]); ss[1] ^= ss[0]; k[4*(i)+ 5] = ff(ss[1]); \
+ ss[2] ^= ss[1]; k[4*(i)+ 6] = ff(ss[2]); ss[3] ^= ss[2]; k[4*(i)+ 7] = ff(ss[3]); \
+}
+#define kd4(k,i) \
+{ ss[4] = ls_box(ss[3],3) ^ rcon_tab[i]; \
+ ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[4*(i)+ 4] = ss[4] ^= k[4*(i)]; \
+ ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[4] ^= k[4*(i)+ 1]; \
+ ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[4] ^= k[4*(i)+ 2]; \
+ ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[4] ^= k[4*(i)+ 3]; \
+}
+#define kdl4(k,i) \
+{ ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+ 4] = ss[0]; ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[1]; \
+ ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[2]; ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[3]; \
+}
+#endif
+
+#define kdf6(k,i) \
+{ ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 6] = ff(ss[0]); ss[1] ^= ss[0]; k[6*(i)+ 7] = ff(ss[1]); \
+ ss[2] ^= ss[1]; k[6*(i)+ 8] = ff(ss[2]); ss[3] ^= ss[2]; k[6*(i)+ 9] = ff(ss[3]); \
+ ss[4] ^= ss[3]; k[6*(i)+10] = ff(ss[4]); ss[5] ^= ss[4]; k[6*(i)+11] = ff(ss[5]); \
+}
+#define kd6(k,i) \
+{ ss[6] = ls_box(ss[5],3) ^ rcon_tab[i]; \
+ ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[6*(i)+ 6] = ss[6] ^= k[6*(i)]; \
+ ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[6] ^= k[6*(i)+ 1]; \
+ ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[6] ^= k[6*(i)+ 2]; \
+ ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[6] ^= k[6*(i)+ 3]; \
+ ss[4] ^= ss[3]; k[6*(i)+10] = ss[6] ^= k[6*(i)+ 4]; \
+ ss[5] ^= ss[4]; k[6*(i)+11] = ss[6] ^= k[6*(i)+ 5]; \
+}
+#define kdl6(k,i) \
+{ ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 6] = ss[0]; ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[1]; \
+ ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[2]; ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[3]; \
+}
+
+#define kdf8(k,i) \
+{ ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 8] = ff(ss[0]); ss[1] ^= ss[0]; k[8*(i)+ 9] = ff(ss[1]); \
+ ss[2] ^= ss[1]; k[8*(i)+10] = ff(ss[2]); ss[3] ^= ss[2]; k[8*(i)+11] = ff(ss[3]); \
+ ss[4] ^= ls_box(ss[3],0); k[8*(i)+12] = ff(ss[4]); ss[5] ^= ss[4]; k[8*(i)+13] = ff(ss[5]); \
+ ss[6] ^= ss[5]; k[8*(i)+14] = ff(ss[6]); ss[7] ^= ss[6]; k[8*(i)+15] = ff(ss[7]); \
+}
+#define kd8(k,i) \
+{ aes_32t g = ls_box(ss[7],3) ^ rcon_tab[i]; \
+ ss[0] ^= g; g = ff(g); k[8*(i)+ 8] = g ^= k[8*(i)]; \
+ ss[1] ^= ss[0]; k[8*(i)+ 9] = g ^= k[8*(i)+ 1]; \
+ ss[2] ^= ss[1]; k[8*(i)+10] = g ^= k[8*(i)+ 2]; \
+ ss[3] ^= ss[2]; k[8*(i)+11] = g ^= k[8*(i)+ 3]; \
+ g = ls_box(ss[3],0); \
+ ss[4] ^= g; g = ff(g); k[8*(i)+12] = g ^= k[8*(i)+ 4]; \
+ ss[5] ^= ss[4]; k[8*(i)+13] = g ^= k[8*(i)+ 5]; \
+ ss[6] ^= ss[5]; k[8*(i)+14] = g ^= k[8*(i)+ 6]; \
+ ss[7] ^= ss[6]; k[8*(i)+15] = g ^= k[8*(i)+ 7]; \
+}
+#define kdl8(k,i) \
+{ ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 8] = ss[0]; ss[1] ^= ss[0]; k[8*(i)+ 9] = ss[1]; \
+ ss[2] ^= ss[1]; k[8*(i)+10] = ss[2]; ss[3] ^= ss[2]; k[8*(i)+11] = ss[3]; \
+}
+
+aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1])
+{ aes_32t ss[8];
+ d_vars
+
+#if !defined(FIXED_TABLES)
+ if(!tab_init) gen_tabs();
+#endif
+
+#if !defined(BLOCK_SIZE)
+ if(!cx->n_blk) cx->n_blk = 16;
+#else
+ cx->n_blk = BLOCK_SIZE;
+#endif
+
+ cx->n_blk = (cx->n_blk & ~3) | 2;
+
+ cx->k_sch[0] = ss[0] = word_in(in_key );
+ cx->k_sch[1] = ss[1] = word_in(in_key + 4);
+ cx->k_sch[2] = ss[2] = word_in(in_key + 8);
+ cx->k_sch[3] = ss[3] = word_in(in_key + 12);
+
+#if (BLOCK_SIZE == 16) && (DEC_UNROLL != NONE)
+
+ switch(klen)
+ {
+ case 16: kdf4(cx->k_sch, 0); kd4(cx->k_sch, 1);
+ kd4(cx->k_sch, 2); kd4(cx->k_sch, 3);
+ kd4(cx->k_sch, 4); kd4(cx->k_sch, 5);
+ kd4(cx->k_sch, 6); kd4(cx->k_sch, 7);
+ kd4(cx->k_sch, 8); kdl4(cx->k_sch, 9);
+ cx->n_rnd = 10; break;
+ case 24: cx->k_sch[4] = ff(ss[4] = word_in(in_key + 16));
+ cx->k_sch[5] = ff(ss[5] = word_in(in_key + 20));
+ kdf6(cx->k_sch, 0); kd6(cx->k_sch, 1);
+ kd6(cx->k_sch, 2); kd6(cx->k_sch, 3);
+ kd6(cx->k_sch, 4); kd6(cx->k_sch, 5);
+ kd6(cx->k_sch, 6); kdl6(cx->k_sch, 7);
+ cx->n_rnd = 12; break;
+ case 32: cx->k_sch[4] = ff(ss[4] = word_in(in_key + 16));
+ cx->k_sch[5] = ff(ss[5] = word_in(in_key + 20));
+ cx->k_sch[6] = ff(ss[6] = word_in(in_key + 24));
+ cx->k_sch[7] = ff(ss[7] = word_in(in_key + 28));
+ kdf8(cx->k_sch, 0); kd8(cx->k_sch, 1);
+ kd8(cx->k_sch, 2); kd8(cx->k_sch, 3);
+ kd8(cx->k_sch, 4); kd8(cx->k_sch, 5);
+ kdl8(cx->k_sch, 6);
+ cx->n_rnd = 14; break;
+ default: cx->n_rnd = 0; return aes_bad;
+ }
+#else
+ { aes_32t i, l;
+ cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
+ l = (nc * cx->n_rnd + nc - 1) / (klen >> 2);
+
+ switch(klen)
+ {
+ case 16:
+ for(i = 0; i < l; ++i)
+ ke4(cx->k_sch, i);
+ break;
+ case 24: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+ cx->k_sch[5] = ss[5] = word_in(in_key + 20);
+ for(i = 0; i < l; ++i)
+ ke6(cx->k_sch, i);
+ break;
+ case 32: cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+ cx->k_sch[5] = ss[5] = word_in(in_key + 20);
+ cx->k_sch[6] = ss[6] = word_in(in_key + 24);
+ cx->k_sch[7] = ss[7] = word_in(in_key + 28);
+ for(i = 0; i < l; ++i)
+ ke8(cx->k_sch, i);
+ break;
+ default: cx->n_rnd = 0; return aes_bad;
+ }
+#if (DEC_ROUND != NO_TABLES)
+ for(i = nc; i < nc * cx->n_rnd; ++i)
+ cx->k_sch[i] = inv_mcol(cx->k_sch[i]);
+#endif
+ }
+#endif
+
+ return aes_good;
+}
+
+#endif
diff --git a/CPP/7zip/Crypto/AES/aesopt.h b/CPP/7zip/Crypto/AES/aesopt.h
new file mode 100755
index 00000000..bcad345f
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/aesopt.h
@@ -0,0 +1,839 @@
+/*
+ -------------------------------------------------------------------------
+ Copyright (c) 2001, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+ 1. distributions of this source code include the above copyright
+ notice, this list of conditions and the following disclaimer;
+
+ 2. distributions in binary form include the above copyright
+ notice, this list of conditions and the following disclaimer
+ in the documentation and/or other associated materials;
+
+ 3. the copyright holder's name is not used to endorse products
+ built using this software without specific written permission.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and fitness for purpose.
+ -------------------------------------------------------------------------
+ Issue Date: 29/07/2002
+
+ This file contains the compilation options for AES (Rijndael) and code
+ that is common across encryption, key scheduling and table generation.
+
+ OPERATION
+
+ These source code files implement the AES algorithm Rijndael designed by
+ Joan Daemen and Vincent Rijmen. The version in aes.c is designed for
+ block and key sizes of 128, 192 and 256 bits (16, 24 and 32 bytes) while
+ that in aespp.c provides for block and keys sizes of 128, 160, 192, 224
+ and 256 bits (16, 20, 24, 28 and 32 bytes). This file is a common header
+ file for these two implementations and for aesref.c, which is a reference
+ implementation.
+
+ This version is designed for flexibility and speed using operations on
+ 32-bit words rather than operations on bytes. It provides aes_both fixed
+ and dynamic block and key lengths and can also run with either big or
+ little endian internal byte order (see aes.h). It inputs block and key
+ lengths in bytes with the legal values being 16, 24 and 32 for aes.c and
+ 16, 20, 24, 28 and 32 for aespp.c
+
+ THE CIPHER INTERFACE
+
+ aes_08t (an unsigned 8-bit type)
+ aes_32t (an unsigned 32-bit type)
+ aes_fret (a signed 16 bit type for function return values)
+ aes_good (value != 0, a good return)
+ aes_bad (value == 0, an error return)
+ struct aes_ctx (structure for the cipher encryption context)
+ struct aes_ctx (structure for the cipher decryption context)
+ aes_rval the function return type (aes_fret if not DLL)
+
+ C subroutine calls:
+
+ aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1]);
+ aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]);
+ aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]);
+
+ aes_rval aes_dec_len(unsigned int blen, aes_ctx cx[1]);
+ aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]);
+ aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]);
+
+ IMPORTANT NOTE: If you are using this C interface and your compiler does
+ not set the memory used for objects to zero before use, you will need to
+ ensure that cx.s_flg is set to zero before using these subroutine calls.
+
+ C++ aes class subroutines:
+
+ class AESclass for encryption
+ class AESclass for decryption
+
+ aes_rval len(unsigned int blen = 16);
+ aes_rval key(const unsigned char in_key[], unsigned int klen);
+ aes_rval blk(const unsigned char in_blk[], unsigned char out_blk[]);
+
+ aes_rval len(unsigned int blen = 16);
+ aes_rval key(const unsigned char in_key[], unsigned int klen);
+ aes_rval blk(const unsigned char in_blk[], unsigned char out_blk[]);
+
+ The block length inputs to set_block and set_key are in numbers of
+ BYTES, not bits. The calls to subroutines must be made in the above
+ order but multiple calls can be made without repeating earlier calls
+ if their parameters have not changed. If the cipher block length is
+ variable but set_blk has not been called before cipher operations a
+ value of 16 is assumed (that is, the AES block size). In contrast to
+ earlier versions the block and key length parameters are now checked
+ for correctness and the encryption and decryption routines check to
+ ensure that an appropriate key has been set before they are called.
+
+ COMPILATION
+
+ The files used to provide AES (Rijndael) are
+
+ a. aes.h for the definitions needed for use in C.
+ b. aescpp.h for the definitions needed for use in C++.
+ c. aesopt.h for setting compilation options (also includes common
+ code).
+ d. aescrypt.c for encryption and decrytpion, or
+ e. aescrypt.asm for encryption and decryption using assembler code.
+ f. aeskey.c for key scheduling.
+ g. aestab.c for table loading or generation.
+
+ The assembler code uses the NASM assembler. The above files provice
+ block and key lengths of 16, 24 and 32 bytes (128, 192 and 256 bits).
+ If aescrypp.c and aeskeypp.c are used instead of aescrypt.c and
+ aeskey.c respectively, the block and key lengths can then be 16, 20,
+ 24, 28 or 32 bytes. However this code has not been optimised to the
+ same extent and is hence slower (esepcially for the AES block size
+ of 16 bytes).
+
+ To compile AES (Rijndael) for use in C code use aes.h and exclude
+ the AES_DLL define in aes.h
+
+ To compile AES (Rijndael) for use in in C++ code use aescpp.h and
+ exclude the AES_DLL define in aes.h
+
+ To compile AES (Rijndael) in C as a Dynamic Link Library DLL) use
+ aes.h, include the AES_DLL define and compile the DLL. If using
+ the test files to test the DLL, exclude aes.c from the test build
+ project and compile it with the same defines as used for the DLL
+ (ensure that the DLL path is correct)
+
+ CONFIGURATION OPTIONS (here and in aes.h)
+
+ a. define BLOCK_SIZE in aes.h to set the cipher block size (16, 24
+ or 32 for the standard code, or 16, 20, 24, 28 or 32 for the
+ extended code) or leave this undefined for dynamically variable
+ block size (this will result in much slower code).
+ b. set AES_DLL in aes.h if AES (Rijndael) is to be compiled as a DLL
+ c. You may need to set PLATFORM_BYTE_ORDER to define the byte order.
+ d. If you want the code to run in a specific internal byte order, then
+ INTERNAL_BYTE_ORDER must be set accordingly.
+ e. set other configuration options decribed below.
+*/
+
+#ifndef _AESOPT_H
+#define _AESOPT_H
+
+/* START OF CONFIGURATION OPTIONS
+
+ USE OF DEFINES
+
+ Later in this section there are a number of defines that control the
+ operation of the code. In each section, the purpose of each define is
+ explained so that the relevant form can be included or excluded by
+ setting either 1's or 0's respectively on the branches of the related
+ #if clauses.
+*/
+
+/* 1. PLATFORM SPECIFIC INCLUDES */
+
+#if defined( __CRYPTLIB__ ) && !defined( INC_ALL ) && !defined( INC_CHILD )
+#include "crypt/aes.h"
+#else
+ #include "aes.h"
+#endif
+
+// 2003-09-16: Changed by Igor Pavlov. Check it.
+// #if defined(__GNUC__) || defined(__GNU_LIBRARY__)
+#if (defined(__GNUC__) || defined(__GNU_LIBRARY__)) && !defined(_WIN32)
+
+# include <endian.h>
+# include <byteswap.h>
+#elif defined(__CRYPTLIB__)
+# if defined( INC_ALL )
+# include "crypt.h"
+# elif defined( INC_CHILD )
+# include "../crypt.h"
+# else
+# include "crypt.h"
+# endif
+# if defined(DATA_LITTLEENDIAN)
+# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+# else
+# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+# endif
+#elif defined(_MSC_VER)
+# include <stdlib.h>
+#elif !defined(_WIN32)
+# include <stdlib.h>
+# if !defined (_ENDIAN_H)
+# include <sys/param.h>
+# else
+# include _ENDIAN_H
+# endif
+#endif
+
+/* 2. BYTE ORDER IN 32-BIT WORDS
+
+ To obtain the highest speed on processors with 32-bit words, this code
+ needs to determine the order in which bytes are packed into such words.
+ The following block of code is an attempt to capture the most obvious
+ ways in which various environemnts define byte order. It may well fail,
+ in which case the definitions will need to be set by editing at the
+ points marked **** EDIT HERE IF NECESSARY **** below.
+*/
+#define AES_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
+#define AES_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
+
+#if !defined(PLATFORM_BYTE_ORDER)
+#if defined(LITTLE_ENDIAN) || defined(BIG_ENDIAN)
+# if defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
+# if defined(BYTE_ORDER)
+# if (BYTE_ORDER == LITTLE_ENDIAN)
+# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+# elif (BYTE_ORDER == BIG_ENDIAN)
+# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+# endif
+# endif
+# elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
+# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+# elif !defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
+# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+# endif
+#elif defined(_LITTLE_ENDIAN) || defined(_BIG_ENDIAN)
+# if defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
+# if defined(_BYTE_ORDER)
+# if (_BYTE_ORDER == _LITTLE_ENDIAN)
+# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+# elif (_BYTE_ORDER == _BIG_ENDIAN)
+# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+# endif
+# endif
+# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
+# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+# elif !defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
+# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+# endif
+#elif 0 /* **** EDIT HERE IF NECESSARY **** */
+#define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#elif 0 /* **** EDIT HERE IF NECESSARY **** */
+#define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#elif (('1234' >> 24) == '1')
+# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#elif (('4321' >> 24) == '1')
+# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#endif
+#endif
+
+#if !defined(PLATFORM_BYTE_ORDER)
+# error Please set undetermined byte order (lines 233 or 235 of aesopt.h).
+#endif
+
+/* 3. ASSEMBLER SUPPORT
+
+ If the assembler code is used for encryption and decryption this file only
+ provides key scheduling so the following defines are used
+*/
+#ifdef AES_ASM
+#define ENCRYPTION_KEY_SCHEDULE
+#define DECRYPTION_KEY_SCHEDULE
+#else
+
+/* 4. FUNCTIONS REQUIRED
+
+ This implementation provides five main subroutines which provide for
+ setting block length, setting encryption and decryption keys and for
+ encryption and decryption. When the assembler code is not being used
+ the following definition blocks allow the selection of the routines
+ that are to be included in the compilation.
+*/
+#if 1
+#define ENCRYPTION_KEY_SCHEDULE
+#endif
+
+#if 1
+#define DECRYPTION_KEY_SCHEDULE
+#endif
+
+#if 1
+#define ENCRYPTION
+#endif
+
+#if 1
+#define DECRYPTION
+#endif
+
+#endif
+
+/* 5. BYTE ORDER WITHIN 32 BIT WORDS
+
+ The fundamental data processing units in Rijndael are 8-bit bytes. The
+ input, output and key input are all enumerated arrays of bytes in which
+ bytes are numbered starting at zero and increasing to one less than the
+ number of bytes in the array in question. This enumeration is only used
+ for naming bytes and does not imply any adjacency or order relationship
+ from one byte to another. When these inputs and outputs are considered
+ as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to
+ byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte.
+ In this implementation bits are numbered from 0 to 7 starting at the
+ numerically least significant end of each byte (bit n represents 2^n).
+
+ However, Rijndael can be implemented more efficiently using 32-bit
+ words by packing bytes into words so that bytes 4*n to 4*n+3 are placed
+ into word[n]. While in principle these bytes can be assembled into words
+ in any positions, this implementation only supports the two formats in
+ which bytes in adjacent positions within words also have adjacent byte
+ numbers. This order is called big-endian if the lowest numbered bytes
+ in words have the highest numeric significance and little-endian if the
+ opposite applies.
+
+ This code can work in either order irrespective of the order used by the
+ machine on which it runs. Normally the internal byte order will be set
+ to the order of the processor on which the code is to be run but this
+ define can be used to reverse this in special situations
+*/
+#if 1
+#define INTERNAL_BYTE_ORDER PLATFORM_BYTE_ORDER
+#elif defined(AES_LITTLE_ENDIAN)
+#define INTERNAL_BYTE_ORDER AES_LITTLE_ENDIAN
+#elif defined(AES_BIG_ENDIAN)
+#define INTERNAL_BYTE_ORDER AES_BIG_ENDIAN
+#endif
+
+/* 6. FAST INPUT/OUTPUT OPERATIONS.
+
+ On some machines it is possible to improve speed by transferring the
+ bytes in the input and output arrays to and from the internal 32-bit
+ variables by addressing these arrays as if they are arrays of 32-bit
+ words. On some machines this will always be possible but there may
+ be a large performance penalty if the byte arrays are not aligned on
+ the normal word boundaries. On other machines this technique will
+ lead to memory access errors when such 32-bit word accesses are not
+ properly aligned. The option SAFE_IO avoids such problems but will
+ often be slower on those machines that support misaligned access
+ (especially so if care is taken to align the input and output byte
+ arrays on 32-bit word boundaries). If SAFE_IO is not defined it is
+ assumed that access to byte arrays as if they are arrays of 32-bit
+ words will not cause problems when such accesses are misaligned.
+*/
+#if 1
+#define SAFE_IO
+#endif
+
+/* 7. LOOP UNROLLING
+
+ The code for encryption and decrytpion cycles through a number of rounds
+ that can be implemented either in a loop or by expanding the code into a
+ long sequence of instructions, the latter producing a larger program but
+ one that will often be much faster. The latter is called loop unrolling.
+ There are also potential speed advantages in expanding two iterations in
+ a loop with half the number of iterations, which is called partial loop
+ unrolling. The following options allow partial or full loop unrolling
+ to be set independently for encryption and decryption
+*/
+#if 1
+#define ENC_UNROLL FULL
+#elif 0
+#define ENC_UNROLL PARTIAL
+#else
+#define ENC_UNROLL NONE
+#endif
+
+// 7-Zip: Small size for SFX
+#ifdef _SFX
+#define DEC_UNROLL NONE
+#else
+
+#if 1
+#define DEC_UNROLL FULL
+#elif 0
+#define DEC_UNROLL PARTIAL
+#else
+#define DEC_UNROLL NONE
+#endif
+
+#endif
+
+/* 8. FIXED OR DYNAMIC TABLES
+
+ When this section is included the tables used by the code are comipled
+ statically into the binary file. Otherwise they are computed once when
+ the code is first used.
+*/
+#if 0
+#define FIXED_TABLES
+#endif
+
+/* 9. FAST FINITE FIELD OPERATIONS
+
+ If this section is included, tables are used to provide faster finite
+ field arithmetic (this has no effect if FIXED_TABLES is defined).
+*/
+#if 1
+#define FF_TABLES
+#endif
+
+/* 10. INTERNAL STATE VARIABLE FORMAT
+
+ The internal state of Rijndael is stored in a number of local 32-bit
+ word varaibles which can be defined either as an array or as individual
+ names variables. Include this section if you want to store these local
+ varaibles in arrays. Otherwise individual local variables will be used.
+*/
+#if 1
+#define ARRAYS
+#endif
+
+/* In this implementation the columns of the state array are each held in
+ 32-bit words. The state array can be held in various ways: in an array
+ of words, in a number of individual word variables or in a number of
+ processor registers. The following define maps a variable name x and
+ a column number c to the way the state array variable is to be held.
+ The first define below maps the state into an array x[c] whereas the
+ second form maps the state into a number of individual variables x0,
+ x1, etc. Another form could map individual state colums to machine
+ register names.
+*/
+
+#if defined(ARRAYS)
+#define s(x,c) x[c]
+#else
+#define s(x,c) x##c
+#endif
+
+/* 11. VARIABLE BLOCK SIZE SPEED
+
+ This section is only relevant if you wish to use the variable block
+ length feature of the code. Include this section if you place more
+ emphasis on speed rather than code size.
+*/
+#if 1
+#define FAST_VARIABLE
+#endif
+
+/* 12. INTERNAL TABLE CONFIGURATION
+
+ This cipher proceeds by repeating in a number of cycles known as 'rounds'
+ which are implemented by a round function which can optionally be speeded
+ up using tables. The basic tables are each 256 32-bit words, with either
+ one or four tables being required for each round function depending on
+ how much speed is required. The encryption and decryption round functions
+ are different and the last encryption and decrytpion round functions are
+ different again making four different round functions in all.
+
+ This means that:
+ 1. Normal encryption and decryption rounds can each use either 0, 1
+ or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
+ 2. The last encryption and decryption rounds can also use either 0, 1
+ or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
+
+ Include or exclude the appropriate definitions below to set the number
+ of tables used by this implementation.
+*/
+
+#if 1 /* set tables for the normal encryption round */
+#define ENC_ROUND FOUR_TABLES
+#elif 0
+#define ENC_ROUND ONE_TABLE
+#else
+#define ENC_ROUND NO_TABLES
+#endif
+
+#if 1 /* set tables for the last encryption round */
+#define LAST_ENC_ROUND FOUR_TABLES
+#elif 0
+#define LAST_ENC_ROUND ONE_TABLE
+#else
+#define LAST_ENC_ROUND NO_TABLES
+#endif
+
+#if 1 /* set tables for the normal decryption round */
+#define DEC_ROUND FOUR_TABLES
+#elif 0
+#define DEC_ROUND ONE_TABLE
+#else
+#define DEC_ROUND NO_TABLES
+#endif
+
+#if 1 /* set tables for the last decryption round */
+#define LAST_DEC_ROUND FOUR_TABLES
+#elif 0
+#define LAST_DEC_ROUND ONE_TABLE
+#else
+#define LAST_DEC_ROUND NO_TABLES
+#endif
+
+/* The decryption key schedule can be speeded up with tables in the same
+ way that the round functions can. Include or exclude the following
+ defines to set this requirement.
+*/
+#if 1
+#define KEY_SCHED FOUR_TABLES
+#elif 0
+#define KEY_SCHED ONE_TABLE
+#else
+#define KEY_SCHED NO_TABLES
+#endif
+
+/* END OF CONFIGURATION OPTIONS */
+
+#define NO_TABLES 0 /* DO NOT CHANGE */
+#define ONE_TABLE 1 /* DO NOT CHANGE */
+#define FOUR_TABLES 4 /* DO NOT CHANGE */
+#define NONE 0 /* DO NOT CHANGE */
+#define PARTIAL 1 /* DO NOT CHANGE */
+#define FULL 2 /* DO NOT CHANGE */
+
+#if defined(BLOCK_SIZE) && ((BLOCK_SIZE & 3) || BLOCK_SIZE < 16 || BLOCK_SIZE > 32)
+#error An illegal block size has been specified.
+#endif
+
+#if !defined(BLOCK_SIZE)
+#define RC_LENGTH 29
+#else
+#define RC_LENGTH 5 * BLOCK_SIZE / 4 - (BLOCK_SIZE == 16 ? 10 : 11)
+#endif
+
+/* Disable at least some poor combinations of options */
+
+#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES
+#undef LAST_ENC_ROUND
+#define LAST_ENC_ROUND NO_TABLES
+#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES
+#undef LAST_ENC_ROUND
+#define LAST_ENC_ROUND ONE_TABLE
+#endif
+
+#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE
+#undef ENC_UNROLL
+#define ENC_UNROLL NONE
+#endif
+
+#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES
+#undef LAST_DEC_ROUND
+#define LAST_DEC_ROUND NO_TABLES
+#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES
+#undef LAST_DEC_ROUND
+#define LAST_DEC_ROUND ONE_TABLE
+#endif
+
+#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE
+#undef DEC_UNROLL
+#define DEC_UNROLL NONE
+#endif
+
+/* upr(x,n): rotates bytes within words by n positions, moving bytes to
+ higher index positions with wrap around into low positions
+ ups(x,n): moves bytes by n positions to higher index positions in
+ words but without wrap around
+ bval(x,n): extracts a byte from a word
+
+ NOTE: The definitions given here are intended only for use with
+ unsigned variables and with shift counts that are compile
+ time constants
+*/
+
+#if (INTERNAL_BYTE_ORDER == AES_LITTLE_ENDIAN)
+#if defined(_MSC_VER)
+#define upr(x,n) _lrotl((aes_32t)(x), 8 * (n))
+#else
+#define upr(x,n) ((aes_32t)(x) << 8 * (n) | (aes_32t)(x) >> 32 - 8 * (n))
+#endif
+#define ups(x,n) ((aes_32t)(x) << 8 * (n))
+#define bval(x,n) ((aes_08t)((x) >> 8 * (n)))
+#define bytes2word(b0, b1, b2, b3) \
+ (((aes_32t)(b3) << 24) | ((aes_32t)(b2) << 16) | ((aes_32t)(b1) << 8) | (b0))
+#endif
+
+#if (INTERNAL_BYTE_ORDER == AES_BIG_ENDIAN)
+#define upr(x,n) ((aes_32t)(x) >> 8 * (n) | (aes_32t)(x) << 32 - 8 * (n))
+#define ups(x,n) ((aes_32t)(x) >> 8 * (n)))
+#define bval(x,n) ((aes_08t)((x) >> 24 - 8 * (n)))
+#define bytes2word(b0, b1, b2, b3) \
+ (((aes_32t)(b0) << 24) | ((aes_32t)(b1) << 16) | ((aes_32t)(b2) << 8) | (b3))
+#endif
+
+#if defined(SAFE_IO)
+
+#define word_in(x) bytes2word((x)[0], (x)[1], (x)[2], (x)[3])
+#define word_out(x,v) { (x)[0] = bval(v,0); (x)[1] = bval(v,1); \
+ (x)[2] = bval(v,2); (x)[3] = bval(v,3); }
+
+#elif (INTERNAL_BYTE_ORDER == PLATFORM_BYTE_ORDER)
+
+#define word_in(x) *(aes_32t*)(x)
+#define word_out(x,v) *(aes_32t*)(x) = (v)
+
+#else
+
+#if !defined(bswap_32)
+#if !defined(_MSC_VER)
+#define _lrotl(x,n) ((aes_32t)(x) << n | (aes_32t)(x) >> 32 - n)
+#endif
+#define bswap_32(x) ((_lrotl((x),8) & 0x00ff00ff) | (_lrotl((x),24) & 0xff00ff00))
+#endif
+
+#define word_in(x) bswap_32(*(aes_32t*)(x))
+#define word_out(x,v) *(aes_32t*)(x) = bswap_32(v)
+
+#endif
+
+/* the finite field modular polynomial and elements */
+
+#define WPOLY 0x011b
+#define BPOLY 0x1b
+
+/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */
+
+#define m1 0x80808080
+#define m2 0x7f7f7f7f
+#define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * BPOLY))
+
+/* The following defines provide alternative definitions of FFmulX that might
+ give improved performance if a fast 32-bit multiply is not available. Note
+ that a temporary variable u needs to be defined where FFmulX is used.
+
+#define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
+#define m4 (0x01010101 * BPOLY)
+#define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
+*/
+
+/* Work out which tables are needed for the different options */
+
+#ifdef AES_ASM
+#ifdef ENC_ROUND
+#undef ENC_ROUND
+#endif
+#define ENC_ROUND FOUR_TABLES
+#ifdef LAST_ENC_ROUND
+#undef LAST_ENC_ROUND
+#endif
+#define LAST_ENC_ROUND FOUR_TABLES
+#ifdef DEC_ROUND
+#undef DEC_ROUND
+#endif
+#define DEC_ROUND FOUR_TABLES
+#ifdef LAST_DEC_ROUND
+#undef LAST_DEC_ROUND
+#endif
+#define LAST_DEC_ROUND FOUR_TABLES
+#ifdef KEY_SCHED
+#undef KEY_SCHED
+#define KEY_SCHED FOUR_TABLES
+#endif
+#endif
+
+#if defined(ENCRYPTION) || defined(AES_ASM)
+#if ENC_ROUND == ONE_TABLE
+#define FT1_SET
+#elif ENC_ROUND == FOUR_TABLES
+#define FT4_SET
+#else
+#define SBX_SET
+#endif
+#if LAST_ENC_ROUND == ONE_TABLE
+#define FL1_SET
+#elif LAST_ENC_ROUND == FOUR_TABLES
+#define FL4_SET
+#elif !defined(SBX_SET)
+#define SBX_SET
+#endif
+#endif
+
+#if defined(DECRYPTION) || defined(AES_ASM)
+#if DEC_ROUND == ONE_TABLE
+#define IT1_SET
+#elif DEC_ROUND == FOUR_TABLES
+#define IT4_SET
+#else
+#define ISB_SET
+#endif
+#if LAST_DEC_ROUND == ONE_TABLE
+#define IL1_SET
+#elif LAST_DEC_ROUND == FOUR_TABLES
+#define IL4_SET
+#elif !defined(ISB_SET)
+#define ISB_SET
+#endif
+#endif
+
+#if defined(ENCRYPTION_KEY_SCHEDULE) || defined(DECRYPTION_KEY_SCHEDULE)
+#if KEY_SCHED == ONE_TABLE
+#define LS1_SET
+#define IM1_SET
+#elif KEY_SCHED == FOUR_TABLES
+#define LS4_SET
+#define IM4_SET
+#elif !defined(SBX_SET)
+#define SBX_SET
+#endif
+#endif
+
+#ifdef FIXED_TABLES
+#define prefx extern const
+#else
+#define prefx extern
+extern aes_08t tab_init;
+void gen_tabs(void);
+#endif
+
+prefx aes_32t rcon_tab[29];
+
+#ifdef SBX_SET
+prefx aes_08t s_box[256];
+#endif
+
+#ifdef ISB_SET
+prefx aes_08t inv_s_box[256];
+#endif
+
+#ifdef FT1_SET
+prefx aes_32t ft_tab[256];
+#endif
+
+#ifdef FT4_SET
+prefx aes_32t ft_tab[4][256];
+#endif
+
+#ifdef FL1_SET
+prefx aes_32t fl_tab[256];
+#endif
+
+#ifdef FL4_SET
+prefx aes_32t fl_tab[4][256];
+#endif
+
+#ifdef IT1_SET
+prefx aes_32t it_tab[256];
+#endif
+
+#ifdef IT4_SET
+prefx aes_32t it_tab[4][256];
+#endif
+
+#ifdef IL1_SET
+prefx aes_32t il_tab[256];
+#endif
+
+#ifdef IL4_SET
+prefx aes_32t il_tab[4][256];
+#endif
+
+#ifdef LS1_SET
+#ifdef FL1_SET
+#undef LS1_SET
+#else
+prefx aes_32t ls_tab[256];
+#endif
+#endif
+
+#ifdef LS4_SET
+#ifdef FL4_SET
+#undef LS4_SET
+#else
+prefx aes_32t ls_tab[4][256];
+#endif
+#endif
+
+#ifdef IM1_SET
+prefx aes_32t im_tab[256];
+#endif
+
+#ifdef IM4_SET
+prefx aes_32t im_tab[4][256];
+#endif
+
+/* Set the number of columns in nc. Note that it is important
+ that nc is a constant which is known at compile time if the
+ highest speed version of the code is needed.
+*/
+
+#if defined(BLOCK_SIZE)
+#define nc (BLOCK_SIZE >> 2)
+#else
+#define nc (cx->n_blk >> 2)
+#endif
+
+/* generic definitions of Rijndael macros that use tables */
+
+#define no_table(x,box,vf,rf,c) bytes2word( \
+ box[bval(vf(x,0,c),rf(0,c))], \
+ box[bval(vf(x,1,c),rf(1,c))], \
+ box[bval(vf(x,2,c),rf(2,c))], \
+ box[bval(vf(x,3,c),rf(3,c))])
+
+#define one_table(x,op,tab,vf,rf,c) \
+ ( tab[bval(vf(x,0,c),rf(0,c))] \
+ ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
+ ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
+ ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
+
+#define four_tables(x,tab,vf,rf,c) \
+ ( tab[0][bval(vf(x,0,c),rf(0,c))] \
+ ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
+ ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
+ ^ tab[3][bval(vf(x,3,c),rf(3,c))])
+
+#define vf1(x,r,c) (x)
+#define rf1(r,c) (r)
+#define rf2(r,c) ((r-c)&3)
+
+/* perform forward and inverse column mix operation on four bytes in long word x in */
+/* parallel. NOTE: x must be a simple variable, NOT an expression in these macros. */
+
+#define dec_fmvars
+#if defined(FM4_SET) /* not currently used */
+#define fwd_mcol(x) four_tables(x,fm_tab,vf1,rf1,0)
+#elif defined(FM1_SET) /* not currently used */
+#define fwd_mcol(x) one_table(x,upr,fm_tab,vf1,rf1,0)
+#else
+#undef dec_fmvars
+#define dec_fmvars aes_32t f1, f2;
+#define fwd_mcol(x) (f1 = (x), f2 = FFmulX(f1), f2 ^ upr(f1 ^ f2, 3) ^ upr(f1, 2) ^ upr(f1, 1))
+#endif
+
+#define dec_imvars
+#if defined(IM4_SET)
+#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0)
+#elif defined(IM1_SET)
+#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0)
+#else
+#undef dec_imvars
+#define dec_imvars aes_32t f2, f4, f8, f9;
+#define inv_mcol(x) \
+ (f9 = (x), f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \
+ f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1))
+#endif
+
+#if defined(FL4_SET)
+#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c)
+#elif defined(LS4_SET)
+#define ls_box(x,c) four_tables(x,ls_tab,vf1,rf2,c)
+#elif defined(FL1_SET)
+#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c)
+#elif defined(LS1_SET)
+#define ls_box(x,c) one_table(x,upr,ls_tab,vf1,rf2,c)
+#else
+#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c)
+#endif
+
+#endif
diff --git a/CPP/7zip/Crypto/AES/aestab.c b/CPP/7zip/Crypto/AES/aestab.c
new file mode 100755
index 00000000..de1d7eea
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/aestab.c
@@ -0,0 +1,494 @@
+/*
+ -------------------------------------------------------------------------
+ Copyright (c) 2001, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+ 1. distributions of this source code include the above copyright
+ notice, this list of conditions and the following disclaimer;
+
+ 2. distributions in binary form include the above copyright
+ notice, this list of conditions and the following disclaimer
+ in the documentation and/or other associated materials;
+
+ 3. the copyright holder's name is not used to endorse products
+ built using this software without specific written permission.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and fitness for purpose.
+ -------------------------------------------------------------------------
+ Issue Date: 29/07/2002
+*/
+
+#include "aesopt.h"
+
+#if defined(FIXED_TABLES) || !defined(FF_TABLES)
+
+/* finite field arithmetic operations */
+
+#define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY))
+#define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY))
+#define f8(x) ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \
+ ^ (((x>>5) & 4) * WPOLY))
+#define f3(x) (f2(x) ^ x)
+#define f9(x) (f8(x) ^ x)
+#define fb(x) (f8(x) ^ f2(x) ^ x)
+#define fd(x) (f8(x) ^ f4(x) ^ x)
+#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
+
+#endif
+
+#if defined(FIXED_TABLES)
+
+#define sb_data(w) \
+ w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
+ w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
+ w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\
+ w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\
+ w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\
+ w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\
+ w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\
+ w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\
+ w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\
+ w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\
+ w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\
+ w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\
+ w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\
+ w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\
+ w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\
+ w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\
+ w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\
+ w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\
+ w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\
+ w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\
+ w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\
+ w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\
+ w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\
+ w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\
+ w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\
+ w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\
+ w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\
+ w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\
+ w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\
+ w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\
+ w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\
+ w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16)
+
+#define isb_data(w) \
+ w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\
+ w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\
+ w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\
+ w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\
+ w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\
+ w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\
+ w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\
+ w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\
+ w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\
+ w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\
+ w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\
+ w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\
+ w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\
+ w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\
+ w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\
+ w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\
+ w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\
+ w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\
+ w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\
+ w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\
+ w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\
+ w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\
+ w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\
+ w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\
+ w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\
+ w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\
+ w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\
+ w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\
+ w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\
+ w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\
+ w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\
+ w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d),
+
+#define mm_data(w) \
+ w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\
+ w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\
+ w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\
+ w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\
+ w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\
+ w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\
+ w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\
+ w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\
+ w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\
+ w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\
+ w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\
+ w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\
+ w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\
+ w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\
+ w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\
+ w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\
+ w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\
+ w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\
+ w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\
+ w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\
+ w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\
+ w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\
+ w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\
+ w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\
+ w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\
+ w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\
+ w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\
+ w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\
+ w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\
+ w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\
+ w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\
+ w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff)
+
+#define h0(x) (x)
+
+/* These defines are used to ensure tables are generated in the
+ right format depending on the internal byte order required
+*/
+
+#define w0(p) bytes2word(p, 0, 0, 0)
+#define w1(p) bytes2word(0, p, 0, 0)
+#define w2(p) bytes2word(0, 0, p, 0)
+#define w3(p) bytes2word(0, 0, 0, p)
+
+/* Number of elements required in this table for different
+ block and key lengths is:
+
+ Rcon Table key length (bytes)
+ Length 16 20 24 28 32
+ ---------------------
+ block 16 | 10 9 8 7 7
+ length 20 | 14 11 10 9 9
+ (bytes) 24 | 19 15 12 11 11
+ 28 | 24 19 16 13 13
+ 32 | 29 23 19 17 14
+
+ this table can be a table of bytes if the key schedule
+ code is adjusted accordingly
+*/
+
+#define u0(p) bytes2word(f2(p), p, p, f3(p))
+#define u1(p) bytes2word(f3(p), f2(p), p, p)
+#define u2(p) bytes2word(p, f3(p), f2(p), p)
+#define u3(p) bytes2word(p, p, f3(p), f2(p))
+
+#define v0(p) bytes2word(fe(p), f9(p), fd(p), fb(p))
+#define v1(p) bytes2word(fb(p), fe(p), f9(p), fd(p))
+#define v2(p) bytes2word(fd(p), fb(p), fe(p), f9(p))
+#define v3(p) bytes2word(f9(p), fd(p), fb(p), fe(p))
+
+const aes_32t rcon_tab[29] =
+{
+ w0(0x01), w0(0x02), w0(0x04), w0(0x08),
+ w0(0x10), w0(0x20), w0(0x40), w0(0x80),
+ w0(0x1b), w0(0x36), w0(0x6c), w0(0xd8),
+ w0(0xab), w0(0x4d), w0(0x9a), w0(0x2f),
+ w0(0x5e), w0(0xbc), w0(0x63), w0(0xc6),
+ w0(0x97), w0(0x35), w0(0x6a), w0(0xd4),
+ w0(0xb3), w0(0x7d), w0(0xfa), w0(0xef),
+ w0(0xc5)
+};
+
+#ifdef SBX_SET
+const aes_08t s_box[256] = { sb_data(h0) };
+#endif
+#ifdef ISB_SET
+const aes_08t inv_s_box[256] = { isb_data(h0) };
+#endif
+
+#ifdef FT1_SET
+const aes_32t ft_tab[256] = { sb_data(u0) };
+#endif
+#ifdef FT4_SET
+const aes_32t ft_tab[4][256] =
+ { { sb_data(u0) }, { sb_data(u1) }, { sb_data(u2) }, { sb_data(u3) } };
+#endif
+
+#ifdef FL1_SET
+const aes_32t fl_tab[256] = { sb_data(w0) };
+#endif
+#ifdef FL4_SET
+const aes_32t fl_tab[4][256] =
+ { { sb_data(w0) }, { sb_data(w1) }, { sb_data(w2) }, { sb_data(w3) } };
+#endif
+
+#ifdef IT1_SET
+const aes_32t it_tab[256] = { isb_data(v0) };
+#endif
+#ifdef IT4_SET
+const aes_32t it_tab[4][256] =
+ { { isb_data(v0) }, { isb_data(v1) }, { isb_data(v2) }, { isb_data(v3) } };
+#endif
+
+#ifdef IL1_SET
+const aes_32t il_tab[256] = { isb_data(w0) };
+#endif
+#ifdef IL4_SET
+const aes_32t il_tab[4][256] =
+ { { isb_data(w0) }, { isb_data(w1) }, { isb_data(w2) }, { isb_data(w3) } };
+#endif
+
+#ifdef LS1_SET
+const aes_32t ls_tab[256] = { sb_data(w0) };
+#endif
+#ifdef LS4_SET
+const aes_32t ls_tab[4][256] =
+ { { sb_data(w0) }, { sb_data(w1) }, { sb_data(w2) }, { sb_data(w3) } };
+#endif
+
+#ifdef IM1_SET
+const aes_32t im_tab[256] = { mm_data(v0) };
+#endif
+#ifdef IM4_SET
+const aes_32t im_tab[4][256] =
+ { { mm_data(v0) }, { mm_data(v1) }, { mm_data(v2) }, { mm_data(v3) } };
+#endif
+
+#else /* dynamic table generation */
+
+aes_08t tab_init = 0;
+
+#define const
+
+aes_32t rcon_tab[29];
+
+#ifdef SBX_SET
+aes_08t s_box[256];
+#endif
+#ifdef ISB_SET
+aes_08t inv_s_box[256];
+#endif
+
+#ifdef FT1_SET
+aes_32t ft_tab[256];
+#endif
+#ifdef FT4_SET
+aes_32t ft_tab[4][256];
+#endif
+
+#ifdef FL1_SET
+aes_32t fl_tab[256];
+#endif
+#ifdef FL4_SET
+aes_32t fl_tab[4][256];
+#endif
+
+#ifdef IT1_SET
+aes_32t it_tab[256];
+#endif
+#ifdef IT4_SET
+aes_32t it_tab[4][256];
+#endif
+
+#ifdef IL1_SET
+aes_32t il_tab[256];
+#endif
+#ifdef IL4_SET
+aes_32t il_tab[4][256];
+#endif
+
+#ifdef LS1_SET
+aes_32t ls_tab[256];
+#endif
+#ifdef LS4_SET
+aes_32t ls_tab[4][256];
+#endif
+
+#ifdef IM1_SET
+aes_32t im_tab[256];
+#endif
+#ifdef IM4_SET
+aes_32t im_tab[4][256];
+#endif
+
+#if !defined(FF_TABLES)
+
+/* Generate the tables for the dynamic table option
+
+ It will generally be sensible to use tables to compute finite
+ field multiplies and inverses but where memory is scarse this
+ code might sometimes be better. But it only has effect during
+ initialisation so its pretty unimportant in overall terms.
+*/
+
+/* return 2 ^ (n - 1) where n is the bit number of the highest bit
+ set in x with x in the range 1 < x < 0x00000200. This form is
+ used so that locals within fi can be bytes rather than words
+*/
+
+static aes_08t hibit(const aes_32t x)
+{ aes_08t r = (aes_08t)((x >> 1) | (x >> 2));
+
+ r |= (r >> 2);
+ r |= (r >> 4);
+ return (r + 1) >> 1;
+}
+
+/* return the inverse of the finite field element x */
+
+static aes_08t fi(const aes_08t x)
+{ aes_08t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
+
+ if(x < 2) return x;
+
+ for(;;)
+ {
+ if(!n1) return v1;
+
+ while(n2 >= n1)
+ {
+ n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
+ }
+
+ if(!n2) return v2;
+
+ while(n1 >= n2)
+ {
+ n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
+ }
+ }
+}
+
+#else
+
+/* define the finite field multiplies required for Rijndael */
+
+#define f2(x) ((x) ? pow[log[x] + 0x19] : 0)
+#define f3(x) ((x) ? pow[log[x] + 0x01] : 0)
+#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0)
+#define fb(x) ((x) ? pow[log[x] + 0x68] : 0)
+#define fd(x) ((x) ? pow[log[x] + 0xee] : 0)
+#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0)
+#define fi(x) ((x) ? pow[255 - log[x]]: 0)
+
+#endif
+
+/* The forward and inverse affine transformations used in the S-box */
+
+#define fwd_affine(x) \
+ (w = (aes_32t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(aes_08t)(w^(w>>8)))
+
+#define inv_affine(x) \
+ (w = (aes_32t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(aes_08t)(w^(w>>8)))
+
+void gen_tabs(void)
+{ aes_32t i, w;
+
+#if defined(FF_TABLES)
+
+ aes_08t pow[512], log[256];
+
+ /* log and power tables for GF(2^8) finite field with
+ WPOLY as modular polynomial - the simplest primitive
+ root is 0x03, used here to generate the tables
+ */
+
+ i = 0; w = 1;
+ do
+ {
+ pow[i] = (aes_08t)w;
+ pow[i + 255] = (aes_08t)w;
+ log[w] = (aes_08t)i++;
+ w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0);
+ }
+ while (w != 1);
+
+#endif
+
+ for(i = 0, w = 1; i < RC_LENGTH; ++i)
+ {
+ rcon_tab[i] = bytes2word(w, 0, 0, 0);
+ w = f2(w);
+ }
+
+ for(i = 0; i < 256; ++i)
+ { aes_08t b;
+
+ b = fwd_affine(fi((aes_08t)i));
+ w = bytes2word(f2(b), b, b, f3(b));
+
+#ifdef SBX_SET
+ s_box[i] = b;
+#endif
+
+#ifdef FT1_SET /* tables for a normal encryption round */
+ ft_tab[i] = w;
+#endif
+#ifdef FT4_SET
+ ft_tab[0][i] = w;
+ ft_tab[1][i] = upr(w,1);
+ ft_tab[2][i] = upr(w,2);
+ ft_tab[3][i] = upr(w,3);
+#endif
+ w = bytes2word(b, 0, 0, 0);
+
+#ifdef FL1_SET /* tables for last encryption round (may also */
+ fl_tab[i] = w; /* be used in the key schedule) */
+#endif
+#ifdef FL4_SET
+ fl_tab[0][i] = w;
+ fl_tab[1][i] = upr(w,1);
+ fl_tab[2][i] = upr(w,2);
+ fl_tab[3][i] = upr(w,3);
+#endif
+
+#ifdef LS1_SET /* table for key schedule if fl_tab above is */
+ ls_tab[i] = w; /* not of the required form */
+#endif
+#ifdef LS4_SET
+ ls_tab[0][i] = w;
+ ls_tab[1][i] = upr(w,1);
+ ls_tab[2][i] = upr(w,2);
+ ls_tab[3][i] = upr(w,3);
+#endif
+
+ b = fi(inv_affine((aes_08t)i));
+ w = bytes2word(fe(b), f9(b), fd(b), fb(b));
+
+#ifdef IM1_SET /* tables for the inverse mix column operation */
+ im_tab[b] = w;
+#endif
+#ifdef IM4_SET
+ im_tab[0][b] = w;
+ im_tab[1][b] = upr(w,1);
+ im_tab[2][b] = upr(w,2);
+ im_tab[3][b] = upr(w,3);
+#endif
+
+#ifdef ISB_SET
+ inv_s_box[i] = b;
+#endif
+#ifdef IT1_SET /* tables for a normal decryption round */
+ it_tab[i] = w;
+#endif
+#ifdef IT4_SET
+ it_tab[0][i] = w;
+ it_tab[1][i] = upr(w,1);
+ it_tab[2][i] = upr(w,2);
+ it_tab[3][i] = upr(w,3);
+#endif
+ w = bytes2word(b, 0, 0, 0);
+#ifdef IL1_SET /* tables for last decryption round */
+ il_tab[i] = w;
+#endif
+#ifdef IL4_SET
+ il_tab[0][i] = w;
+ il_tab[1][i] = upr(w,1);
+ il_tab[2][i] = upr(w,2);
+ il_tab[3][i] = upr(w,3);
+#endif
+ }
+
+ tab_init = 1;
+}
+
+#endif
diff --git a/CPP/7zip/Crypto/AES/makefile b/CPP/7zip/Crypto/AES/makefile
new file mode 100755
index 00000000..28f99965
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/makefile
@@ -0,0 +1,31 @@
+PROG = AES.dll
+DEF_FILE = ../Codec.def
+CFLAGS = $(CFLAGS) -I ../../../
+LIBS = $(LIBS) oleaut32.lib
+
+AES_OBJS = \
+ $O\DllExports.obj \
+
+AES_OPT_OBJS = \
+ $O\MyAES.obj \
+
+AES_ORIG_OBJS = \
+ $O\aescrypt.obj \
+ $O\aeskey.obj \
+ $O\aestab.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(AES_OBJS) \
+ $(AES_OPT_OBJS) \
+ $(AES_ORIG_OBJS) \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(AES_OBJS): $(*B).cpp
+ $(COMPL)
+$(AES_OPT_OBJS): $(*B).cpp
+ $(COMPL_O2)
+$(AES_ORIG_OBJS): $(*B).c
+ $(COMPL_O2_W3)
diff --git a/CPP/7zip/Crypto/AES/resource.rc b/CPP/7zip/Crypto/AES/resource.rc
new file mode 100755
index 00000000..1ea1bfe7
--- /dev/null
+++ b/CPP/7zip/Crypto/AES/resource.rc
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("AES Codec", "AES")
diff --git a/CPP/7zip/Crypto/Codec.def b/CPP/7zip/Crypto/Codec.def
new file mode 100755
index 00000000..ebf73a3b
--- /dev/null
+++ b/CPP/7zip/Crypto/Codec.def
@@ -0,0 +1,4 @@
+EXPORTS
+ CreateObject PRIVATE
+ GetNumberOfMethods PRIVATE
+ GetMethodProperty PRIVATE
diff --git a/CPP/7zip/Crypto/Hash/HmacSha1.cpp b/CPP/7zip/Crypto/Hash/HmacSha1.cpp
new file mode 100755
index 00000000..a5c20a75
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/HmacSha1.cpp
@@ -0,0 +1,109 @@
+// HmacSha1.cpp
+
+#include "StdAfx.h"
+
+#include "HmacSha1.h"
+
+namespace NCrypto {
+namespace NSha1 {
+
+void CHmac::SetKey(const Byte *key, size_t keySize)
+{
+ Byte keyTemp[kBlockSize];
+ size_t i;
+ for (i = 0; i < kBlockSize; i++)
+ keyTemp[i] = 0;
+ if(keySize > kBlockSize)
+ {
+ _sha.Init();
+ _sha.Update(key, keySize);
+ _sha.Final(keyTemp);
+ keySize = kDigestSize;
+ }
+ else
+ for (i = 0; i < keySize; i++)
+ keyTemp[i] = key[i];
+ for (i = 0; i < kBlockSize; i++)
+ keyTemp[i] ^= 0x36;
+ _sha.Init();
+ _sha.Update(keyTemp, kBlockSize);
+ for (i = 0; i < kBlockSize; i++)
+ keyTemp[i] ^= 0x36 ^ 0x5C;
+ _sha2.Init();
+ _sha2.Update(keyTemp, kBlockSize);
+}
+
+void CHmac::Final(Byte *mac, size_t macSize)
+{
+ Byte digest[kDigestSize];
+ _sha.Final(digest);
+ _sha2.Update(digest, kDigestSize);
+ _sha2.Final(digest);
+ for(size_t i = 0; i < macSize; i++)
+ mac[i] = digest[i];
+}
+
+
+void CHmac32::SetKey(const Byte *key, size_t keySize)
+{
+ UInt32 keyTemp[kBlockSizeInWords];
+ size_t i;
+ for (i = 0; i < kBlockSizeInWords; i++)
+ keyTemp[i] = 0;
+ if(keySize > kBlockSize)
+ {
+ CContext sha;
+ sha.Init();
+ sha.Update(key, keySize);
+ Byte digest[kDigestSize];
+ sha.Final(digest);
+
+ for (int i = 0 ; i < kDigestSizeInWords; i++)
+ keyTemp[i] =
+ ((UInt32)(digest[i * 4 + 0]) << 24) |
+ ((UInt32)(digest[i * 4 + 1]) << 16) |
+ ((UInt32)(digest[i * 4 + 2]) << 8) |
+ ((UInt32)(digest[i * 4 + 3]));
+ keySize = kDigestSizeInWords;
+ }
+ else
+ for (size_t i = 0; i < keySize; i++)
+ keyTemp[i / 4] |= (key[i] << (24 - 8 * (i & 3)));
+ for (i = 0; i < kBlockSizeInWords; i++)
+ keyTemp[i] ^= 0x36363636;
+ _sha.Init();
+ _sha.Update(keyTemp, kBlockSizeInWords);
+ for (i = 0; i < kBlockSizeInWords; i++)
+ keyTemp[i] ^= 0x36363636 ^ 0x5C5C5C5C;
+ _sha2.Init();
+ _sha2.Update(keyTemp, kBlockSizeInWords);
+}
+
+void CHmac32::Final(UInt32 *mac, size_t macSize)
+{
+ UInt32 digest[kDigestSizeInWords];
+ _sha.Final(digest);
+ _sha2.Update(digest, kDigestSizeInWords);
+ _sha2.Final(digest);
+ for(size_t i = 0; i < macSize; i++)
+ mac[i] = digest[i];
+}
+
+void CHmac32::GetLoopXorDigest(UInt32 *mac, UInt32 numIteration)
+{
+ UInt32 block[kBlockSizeInWords];
+ UInt32 block2[kBlockSizeInWords];
+ _sha.PrepareBlock(block, kDigestSizeInWords);
+ _sha2.PrepareBlock(block2, kDigestSizeInWords);
+ for(unsigned int s = 0; s < kDigestSizeInWords; s++)
+ block[s] = mac[s];
+ for(UInt32 i = 0; i < numIteration; i++)
+ {
+ _sha.GetBlockDigest(block, block2);
+ _sha2.GetBlockDigest(block2, block);
+ for (unsigned int s = 0; s < kDigestSizeInWords; s++)
+ mac[s] ^= block[s];
+ }
+}
+
+}}
diff --git a/CPP/7zip/Crypto/Hash/HmacSha1.h b/CPP/7zip/Crypto/Hash/HmacSha1.h
new file mode 100755
index 00000000..bca5bcf8
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/HmacSha1.h
@@ -0,0 +1,39 @@
+// HmacSha1.h
+// Implements HMAC-SHA-1 (RFC2104, FIPS-198)
+
+#ifndef _HMAC_H
+#define _HMAC_H
+
+#include "Sha1.h"
+
+namespace NCrypto {
+namespace NSha1 {
+
+// Use: SetKey(key, keySize); for () Update(data, size); Final(mac, macSize);
+
+class CHmac
+{
+ CContext _sha;
+ CContext _sha2;
+public:
+ void SetKey(const Byte *key, size_t keySize);
+ void Update(const Byte *data, size_t dataSize) { _sha.Update(data, dataSize); }
+ void Final(Byte *mac, size_t macSize = kDigestSize);
+};
+
+class CHmac32
+{
+ CContext32 _sha;
+ CContext32 _sha2;
+public:
+ void SetKey(const Byte *key, size_t keySize);
+ void Update(const UInt32 *data, size_t dataSize) { _sha.Update(data, dataSize); }
+ void Final(UInt32 *mac, size_t macSize = kDigestSizeInWords);
+
+ // It'sa for hmac function. in,out: mac[kDigestSizeInWords].
+ void GetLoopXorDigest(UInt32 *mac, UInt32 numIteration);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.cpp b/CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.cpp
new file mode 100755
index 00000000..b11881b7
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.cpp
@@ -0,0 +1,83 @@
+// Pbkdf2HmacSha1.cpp
+
+#include "StdAfx.h"
+
+#include "HmacSha1.h"
+
+namespace NCrypto {
+namespace NSha1 {
+
+void Pbkdf2Hmac(const Byte *pwd, size_t pwdSize, const Byte *salt, size_t saltSize,
+ UInt32 numIterations, Byte *key, size_t keySize)
+{
+ CHmac baseCtx;
+ baseCtx.SetKey(pwd, pwdSize);
+ for (UInt32 i = 1; keySize > 0; i++)
+ {
+ CHmac ctx = baseCtx;
+ ctx.Update(salt, saltSize);
+ Byte u[kDigestSize] = { (Byte)(i >> 24), (Byte)(i >> 16), (Byte)(i >> 8), (Byte)(i) };
+ const unsigned int curSize = (keySize < kDigestSize) ? (unsigned int)keySize : kDigestSize;
+ ctx.Update(u, 4);
+ ctx.Final(u, kDigestSize);
+
+ unsigned int s;
+ for (s = 0; s < curSize; s++)
+ key[s] = u[s];
+
+ for (UInt32 j = numIterations; j > 1; j--)
+ {
+ ctx = baseCtx;
+ ctx.Update(u, kDigestSize);
+ ctx.Final(u, kDigestSize);
+ for (s = 0; s < curSize; s++)
+ key[s] ^= u[s];
+ }
+
+ key += curSize;
+ keySize -= curSize;
+ }
+}
+
+void Pbkdf2Hmac32(const Byte *pwd, size_t pwdSize, const UInt32 *salt, size_t saltSize,
+ UInt32 numIterations, UInt32 *key, size_t keySize)
+{
+ CHmac32 baseCtx;
+ baseCtx.SetKey(pwd, pwdSize);
+ for (UInt32 i = 1; keySize > 0; i++)
+ {
+ CHmac32 ctx = baseCtx;
+ ctx.Update(salt, saltSize);
+ UInt32 u[kDigestSizeInWords] = { i };
+ const unsigned int curSize = (keySize < kDigestSizeInWords) ? (unsigned int)keySize : kDigestSizeInWords;
+ ctx.Update(u, 1);
+ ctx.Final(u, kDigestSizeInWords);
+
+ // Speed-optimized code start
+ ctx = baseCtx;
+ ctx.GetLoopXorDigest(u, numIterations - 1);
+ // Speed-optimized code end
+
+ unsigned int s;
+ for (s = 0; s < curSize; s++)
+ key[s] = u[s];
+
+ /*
+ // Default code start
+ for (UInt32 j = numIterations; j > 1; j--)
+ {
+ ctx = baseCtx;
+ ctx.Update(u, kDigestSizeInWords);
+ ctx.Final(u, kDigestSizeInWords);
+ for (s = 0; s < curSize; s++)
+ key[s] ^= u[s];
+ }
+ // Default code end
+ */
+
+ key += curSize;
+ keySize -= curSize;
+ }
+}
+
+}}
diff --git a/CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.h b/CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.h
new file mode 100755
index 00000000..00a5e009
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.h
@@ -0,0 +1,21 @@
+// Pbkdf2HmacSha1.h
+// Password-Based Key Derivation Function (RFC 2898, PKCS #5) based on HMAC-SHA-1
+
+#ifndef __PBKDF2HMACSHA1_H
+#define __PBKDF2HMACSHA1_H
+
+#include <stddef.h>
+#include "../../../Common/Types.h"
+
+namespace NCrypto {
+namespace NSha1 {
+
+void Pbkdf2Hmac(const Byte *pwd, size_t pwdSize, const Byte *salt, size_t saltSize,
+ UInt32 numIterations, Byte *key, size_t keySize);
+
+void Pbkdf2Hmac32(const Byte *pwd, size_t pwdSize, const UInt32 *salt, size_t saltSize,
+ UInt32 numIterations, UInt32 *key, size_t keySize);
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/Hash/RandGen.cpp b/CPP/7zip/Crypto/Hash/RandGen.cpp
new file mode 100755
index 00000000..480e04ca
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/RandGen.cpp
@@ -0,0 +1,78 @@
+// RandGen.cpp
+
+#include "StdAfx.h"
+
+#include <stdio.h>
+
+#include "Windows/Synchronization.h"
+
+#include "RandGen.h"
+
+// This is not very good random number generator.
+// Please use it only for salt.
+// First genrated data block depends from timer.
+// Other genrated data blocks depend from previous state
+// Maybe it's possible to restore original timer vaue from generated value.
+
+void CRandomGenerator::Init()
+{
+ NCrypto::NSha1::CContext hash;
+ hash.Init();
+
+ #ifdef _WIN32
+ DWORD w = ::GetCurrentProcessId();
+ hash.Update((const Byte *)&w, sizeof(w));
+ w = ::GetCurrentThreadId();
+ hash.Update((const Byte *)&w, sizeof(w));
+ #endif
+
+ for (int i = 0; i < 1000; i++)
+ {
+ #ifdef _WIN32
+ LARGE_INTEGER v;
+ if (::QueryPerformanceCounter(&v))
+ hash.Update((const Byte *)&v.QuadPart, sizeof(v.QuadPart));
+ #endif
+
+ DWORD tickCount = ::GetTickCount();
+ hash.Update((const Byte *)&tickCount, sizeof(tickCount));
+
+ for (int j = 0; j < 100; j++)
+ {
+ hash.Final(_buff);
+ hash.Init();
+ hash.Update(_buff, NCrypto::NSha1::kDigestSize);
+ }
+ }
+ hash.Final(_buff);
+ _needInit = false;
+}
+
+static NWindows::NSynchronization::CCriticalSection g_CriticalSection;
+
+void CRandomGenerator::Generate(Byte *data, unsigned int size)
+{
+ g_CriticalSection.Enter();
+ if (_needInit)
+ Init();
+ while (size > 0)
+ {
+ NCrypto::NSha1::CContext hash;
+
+ hash.Init();
+ hash.Update(_buff, NCrypto::NSha1::kDigestSize);
+ hash.Final(_buff);
+
+ hash.Init();
+ UInt32 salt = 0xF672ABD1;
+ hash.Update((const Byte *)&salt, sizeof(salt));
+ hash.Update(_buff, NCrypto::NSha1::kDigestSize);
+ Byte buff[NCrypto::NSha1::kDigestSize];
+ hash.Final(buff);
+ for (unsigned int i = 0; i < NCrypto::NSha1::kDigestSize && size > 0; i++, size--)
+ *data++ = buff[i];
+ }
+ g_CriticalSection.Leave();
+}
+
+CRandomGenerator g_RandomGenerator;
diff --git a/CPP/7zip/Crypto/Hash/RandGen.h b/CPP/7zip/Crypto/Hash/RandGen.h
new file mode 100755
index 00000000..3b58a032
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/RandGen.h
@@ -0,0 +1,21 @@
+// RandGen.h
+
+#ifndef __RANDGEN_H
+#define __RANDGEN_H
+
+#include "Sha1.h"
+
+class CRandomGenerator
+{
+ Byte _buff[NCrypto::NSha1::kDigestSize];
+ bool _needInit;
+
+ void Init();
+public:
+ CRandomGenerator(): _needInit(true) {};
+ void Generate(Byte *data, unsigned int size);
+};
+
+extern CRandomGenerator g_RandomGenerator;
+
+#endif
diff --git a/CPP/7zip/Crypto/Hash/RotateDefs.h b/CPP/7zip/Crypto/Hash/RotateDefs.h
new file mode 100755
index 00000000..832e7357
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/RotateDefs.h
@@ -0,0 +1,19 @@
+// RotateDefs.h
+
+#ifndef __ROTATEDEFS_H
+#define __ROTATEDEFS_H
+
+#ifdef _MSC_VER
+
+#include <stddef.h>
+#define rotlFixed(x, n) _rotl((x), (n))
+#define rotrFixed(x, n) _rotr((x), (n))
+
+#else
+
+#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
+#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
+
+#endif
+
+#endif
diff --git a/CPP/7zip/Crypto/Hash/Sha1.cpp b/CPP/7zip/Crypto/Hash/Sha1.cpp
new file mode 100755
index 00000000..0e1d2ecf
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/Sha1.cpp
@@ -0,0 +1,210 @@
+// Sha1.cpp
+// This file is based on public domain
+// Steve Reid and Wei Dai's code from Crypto++
+
+#include "StdAfx.h"
+
+#include "Sha1.h"
+#include "RotateDefs.h"
+
+namespace NCrypto {
+namespace NSha1 {
+
+// define it for speed optimization
+// #define _SHA1_UNROLL
+
+static const unsigned int kNumW =
+ #ifdef _SHA1_UNROLL
+ 16;
+ #else
+ 80;
+ #endif
+
+
+#define w0(i) (W[(i)] = data[(i)])
+
+#ifdef _SHA1_UNROLL
+#define w1(i) (W[(i)&15] = rotlFixed(W[((i)-3)&15] ^ W[((i)-8)&15] ^ W[((i)-14)&15] ^ W[((i)-16)&15], 1))
+#else
+#define w1(i) (W[(i)] = rotlFixed(W[(i)-3] ^ W[(i)-8] ^ W[(i)-14] ^ W[(i)-16], 1))
+#endif
+
+#define f1(x,y,z) (z^(x&(y^z)))
+#define f2(x,y,z) (x^y^z)
+#define f3(x,y,z) ((x&y)|(z&(x|y)))
+#define f4(x,y,z) (x^y^z)
+
+#define RK1(a,b,c,d,e,i, f, w, k) e += f(b,c,d) + w(i) + k + rotlFixed(a,5); b = rotlFixed(b,30);
+
+#define R0(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f1, w0, 0x5A827999)
+#define R1(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f1, w1, 0x5A827999)
+#define R2(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f2, w1, 0x6ED9EBA1)
+#define R3(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f3, w1, 0x8F1BBCDC)
+#define R4(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f4, w1, 0xCA62C1D6)
+
+#define RX_1_4(rx1, rx4, i) rx1(a,b,c,d,e,i); rx4(e,a,b,c,d,i+1); rx4(d,e,a,b,c,i+2); rx4(c,d,e,a,b,i+3); rx4(b,c,d,e,a,i+4);
+#define RX_5(rx, i) RX_1_4(rx, rx, i);
+
+void CContextBase::Init()
+{
+ _state[0] = 0x67452301;
+ _state[1] = 0xEFCDAB89;
+ _state[2] = 0x98BADCFE;
+ _state[3] = 0x10325476;
+ _state[4] = 0xC3D2E1F0;
+ _count = 0;
+}
+
+void CContextBase::GetBlockDigest(UInt32 *data, UInt32 *destDigest, bool returnRes)
+{
+ UInt32 a, b, c, d, e;
+ UInt32 W[kNumW];
+
+ a = _state[0];
+ b = _state[1];
+ c = _state[2];
+ d = _state[3];
+ e = _state[4];
+ #ifdef _SHA1_UNROLL
+ RX_5(R0, 0); RX_5(R0, 5); RX_5(R0, 10);
+ #else
+ int i;
+ for (i = 0; i < 15; i += 5) { RX_5(R0, i); }
+ #endif
+
+ RX_1_4(R0, R1, 15);
+
+
+ #ifdef _SHA1_UNROLL
+ RX_5(R2, 20); RX_5(R2, 25); RX_5(R2, 30); RX_5(R2, 35);
+ RX_5(R3, 40); RX_5(R3, 45); RX_5(R3, 50); RX_5(R3, 55);
+ RX_5(R4, 60); RX_5(R4, 65); RX_5(R4, 70); RX_5(R4, 75);
+ #else
+ i = 20;
+ for (; i < 40; i += 5) { RX_5(R2, i); }
+ for (; i < 60; i += 5) { RX_5(R3, i); }
+ for (; i < 80; i += 5) { RX_5(R4, i); }
+ #endif
+
+ destDigest[0] = _state[0] + a;
+ destDigest[1] = _state[1] + b;
+ destDigest[2] = _state[2] + c;
+ destDigest[3] = _state[3] + d;
+ destDigest[4] = _state[4] + e;
+
+ if (returnRes)
+ for (int i = 0 ; i < 16; i++)
+ data[i] = W[kNumW - 16 + i];
+
+ // Wipe variables
+ // a = b = c = d = e = 0;
+}
+
+void CContextBase::PrepareBlock(UInt32 *block, unsigned int size) const
+{
+ unsigned int curBufferPos = size & 0xF;
+ block[curBufferPos++] = 0x80000000;
+ while (curBufferPos != (16 - 2))
+ block[curBufferPos++] = 0;
+ const UInt64 lenInBits = (_count << 9) + ((UInt64)size << 5);
+ block[curBufferPos++] = (UInt32)(lenInBits >> 32);
+ block[curBufferPos++] = (UInt32)(lenInBits);
+}
+
+void CContext::Update(Byte *data, size_t size, bool rar350Mode)
+{
+ bool returnRes = false;
+ unsigned int curBufferPos = _count2;
+ while (size-- > 0)
+ {
+ int pos = (int)(curBufferPos & 3);
+ if (pos == 0)
+ _buffer[curBufferPos >> 2] = 0;
+ _buffer[curBufferPos >> 2] |= ((UInt32)*data++) << (8 * (3 - pos));
+ if (++curBufferPos == kBlockSize)
+ {
+ curBufferPos = 0;
+ CContextBase::UpdateBlock(_buffer, returnRes);
+ if (returnRes)
+ for (int i = 0; i < kBlockSizeInWords; i++)
+ {
+ UInt32 d = _buffer[i];
+ data[i * 4 + 0 - kBlockSize] = (Byte)(d);
+ data[i * 4 + 1 - kBlockSize] = (Byte)(d >> 8);
+ data[i * 4 + 2 - kBlockSize] = (Byte)(d >> 16);
+ data[i * 4 + 3 - kBlockSize] = (Byte)(d >> 24);
+ }
+ returnRes = rar350Mode;
+ }
+ }
+ _count2 = curBufferPos;
+}
+
+void CContext::Final(Byte *digest)
+{
+ const UInt64 lenInBits = (_count << 9) + ((UInt64)_count2 << 3);
+ unsigned int curBufferPos = _count2;
+ int pos = (int)(curBufferPos & 3);
+ curBufferPos >>= 2;
+ if (pos == 0)
+ _buffer[curBufferPos] = 0;
+ _buffer[curBufferPos++] |= ((UInt32)0x80) << (8 * (3 - pos));
+
+ while (curBufferPos != (16 - 2))
+ {
+ curBufferPos &= 0xF;
+ if (curBufferPos == 0)
+ UpdateBlock();
+ _buffer[curBufferPos++] = 0;
+ }
+ _buffer[curBufferPos++] = (UInt32)(lenInBits >> 32);
+ _buffer[curBufferPos++] = (UInt32)(lenInBits);
+ UpdateBlock();
+
+ int i;
+ for (i = 0; i < kDigestSizeInWords; i++)
+ {
+ UInt32 state = _state[i] & 0xFFFFFFFF;
+ *digest++ = (Byte)(state >> 24);
+ *digest++ = (Byte)(state >> 16);
+ *digest++ = (Byte)(state >> 8);
+ *digest++ = (Byte)(state);
+ }
+ Init();
+}
+
+///////////////////////////
+// Words version
+
+void CContext32::Update(const UInt32 *data, size_t size)
+{
+ while (size-- > 0)
+ {
+ _buffer[_count2++] = *data++;
+ if (_count2 == kBlockSizeInWords)
+ {
+ _count2 = 0;
+ UpdateBlock();
+ }
+ }
+}
+
+void CContext32::Final(UInt32 *digest)
+{
+ const UInt64 lenInBits = (_count << 9) + ((UInt64)_count2 << 5);
+ unsigned int curBufferPos = _count2;
+ _buffer[curBufferPos++] = 0x80000000;
+ while (curBufferPos != (16 - 2))
+ {
+ curBufferPos &= 0xF;
+ if (curBufferPos == 0)
+ UpdateBlock();
+ _buffer[curBufferPos++] = 0;
+ }
+ _buffer[curBufferPos++] = (UInt32)(lenInBits >> 32);
+ _buffer[curBufferPos++] = (UInt32)(lenInBits);
+ GetBlockDigest(_buffer, digest);
+ Init();
+}
+
+}}
diff --git a/CPP/7zip/Crypto/Hash/Sha1.h b/CPP/7zip/Crypto/Hash/Sha1.h
new file mode 100755
index 00000000..ebb11142
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/Sha1.h
@@ -0,0 +1,68 @@
+// Sha1.h
+// This file is based on public domain
+// Steve Reid and Wei Dai's code from Crypto++
+
+#ifndef __SHA1_H
+#define __SHA1_H
+
+#include <stddef.h>
+#include "../../../Common/Types.h"
+
+// 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
+
+namespace NCrypto {
+namespace NSha1 {
+
+const unsigned int kBlockSize = 64;
+const unsigned int kDigestSize = 20;
+
+const unsigned int kBlockSizeInWords = (kBlockSize >> 2);
+const unsigned int kDigestSizeInWords = (kDigestSize >> 2);
+
+class CContextBase
+{
+protected:
+ UInt32 _state[5];
+ UInt64 _count;
+ void UpdateBlock(UInt32 *data, bool returnRes = false)
+ {
+ GetBlockDigest(data, _state, returnRes);
+ _count++;
+ }
+public:
+ void Init();
+ void GetBlockDigest(UInt32 *blockData, UInt32 *destDigest, bool returnRes = false);
+ // PrepareBlock can be used only when size <= 13. size in Words
+ void PrepareBlock(UInt32 *block, unsigned int size) const;
+};
+
+class CContextBase2: public CContextBase
+{
+protected:
+ unsigned int _count2;
+ UInt32 _buffer[kBlockSizeInWords];
+ void UpdateBlock() { CContextBase::UpdateBlock(_buffer); }
+public:
+ void Init() { CContextBase::Init(); _count2 = 0; }
+};
+
+class CContext: public CContextBase2
+{
+public:
+ void Update(Byte *data, size_t size, bool rar350Mode = false);
+ void Update(const Byte *data, size_t size) { Update((Byte *)data, size, false); }
+ void Final(Byte *digest);
+};
+
+class CContext32: public CContextBase2
+{
+public:
+ void Update(const UInt32 *data, size_t size);
+ void Final(UInt32 *digest);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/Hash/Sha256.cpp b/CPP/7zip/Crypto/Hash/Sha256.cpp
new file mode 100755
index 00000000..db236058
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/Sha256.cpp
@@ -0,0 +1,210 @@
+// Crypto/Sha256.cpp
+// This code is based on code from Wei Dai's Crypto++ library.
+
+#include "StdAfx.h"
+
+#include "Sha256.h"
+#include "RotateDefs.h"
+
+namespace NCrypto {
+namespace NSha256 {
+
+// define it for speed optimization
+// #define _SHA256_UNROLL
+// #define _SHA256_UNROLL2
+
+void CContext::Init()
+{
+ _state[0] = 0x6a09e667;
+ _state[1] = 0xbb67ae85;
+ _state[2] = 0x3c6ef372;
+ _state[3] = 0xa54ff53a;
+ _state[4] = 0x510e527f;
+ _state[5] = 0x9b05688c;
+ _state[6] = 0x1f83d9ab;
+ _state[7] = 0x5be0cd19;
+
+ _count = 0;
+}
+
+#define S0(x) (rotrFixed(x, 2) ^ rotrFixed(x,13) ^ rotrFixed(x, 22))
+#define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x, 25))
+#define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3))
+#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10))
+
+#define blk0(i) (W[i] = data[i])
+#define blk2(i) (W[i&15] += s1(W[(i-2)&15]) + W[(i-7)&15] + s0(W[(i-15)&15]))
+
+#define Ch(x,y,z) (z^(x&(y^z)))
+#define Maj(x,y,z) ((x&y)|(z&(x|y)))
+
+#define a(i) T[(0-(i))&7]
+#define b(i) T[(1-(i))&7]
+#define c(i) T[(2-(i))&7]
+#define d(i) T[(3-(i))&7]
+#define e(i) T[(4-(i))&7]
+#define f(i) T[(5-(i))&7]
+#define g(i) T[(6-(i))&7]
+#define h(i) T[(7-(i))&7]
+
+
+#ifdef _SHA256_UNROLL2
+
+#define R(a,b,c,d,e,f,g,h, i) h += S1(e) + Ch(e,f,g) + K[i+j] + (j?blk2(i):blk0(i));\
+ d += h; h += S0(a) + Maj(a, b, c)
+
+#define RX_8(i) \
+ R(a,b,c,d,e,f,g,h, i); \
+ R(h,a,b,c,d,e,f,g, i+1); \
+ R(g,h,a,b,c,d,e,f, i+2); \
+ R(f,g,h,a,b,c,d,e, i+3); \
+ R(e,f,g,h,a,b,c,d, i+4); \
+ R(d,e,f,g,h,a,b,c, i+5); \
+ R(c,d,e,f,g,h,a,b, i+6); \
+ R(b,c,d,e,f,g,h,a, i+7)
+
+#else
+
+#define R(i) h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[i+j] + (j?blk2(i):blk0(i));\
+ d(i) += h(i); h(i) += S0(a(i)) + Maj(a(i), b(i), c(i))
+
+#ifdef _SHA256_UNROLL
+
+#define RX_8(i) R(i+0); R(i+1); R(i+2); R(i+3); R(i+4); R(i+5); R(i+6); R(i+7);
+
+#endif
+
+#endif
+
+
+void CContext::Transform(UInt32 *state, const UInt32 *data)
+{
+ UInt32 W[16];
+
+ #ifdef _SHA256_UNROLL2
+ UInt32 a,b,c,d,e,f,g,h;
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+ f = state[5];
+ g = state[6];
+ h = state[7];
+ #else
+ UInt32 T[8];
+ for (int s = 0; s < 8; s++)
+ T[s] = state[s];
+ #endif
+
+ for (unsigned int j = 0; j < 64; j += 16)
+ {
+ #if defined(_SHA256_UNROLL) || defined(_SHA256_UNROLL2)
+ RX_8(0); RX_8(8);
+ #else
+ for (unsigned int i = 0; i < 16; i++) { R(i); }
+ #endif
+ }
+
+ #ifdef _SHA256_UNROLL2
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+ state[5] += f;
+ state[6] += g;
+ state[7] += h;
+ #else
+ for (int i = 0; i < 8; i++)
+ state[i] += T[i];
+ #endif
+
+ // Wipe variables
+ // memset(W, 0, sizeof(W));
+ // memset(T, 0, sizeof(T));
+}
+
+const UInt32 CContext::K[64] = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+#undef S0
+#undef S1
+#undef s0
+#undef s1
+
+void CContext::WriteByteBlock()
+{
+ UInt32 data32[16];
+ for (int i = 0; i < 16; i++)
+ {
+ data32[i] = (UInt32(_buffer[i * 4]) << 24) +
+ (UInt32(_buffer[i * 4 + 1]) << 16) +
+ (UInt32(_buffer[i * 4 + 2]) << 8) +
+ UInt32(_buffer[i * 4 + 3]);
+ }
+ Transform(_state, data32);
+}
+
+void CContext::Update(const Byte *data, size_t size)
+{
+ UInt32 curBufferPos = (UInt32)_count & 0x3F;
+ while (size > 0)
+ {
+ _buffer[curBufferPos++] = *data++;
+ _count++;
+ size--;
+ if (curBufferPos == 64)
+ {
+ curBufferPos = 0;
+ WriteByteBlock();
+ }
+ }
+}
+
+void CContext::Final(Byte *digest)
+{
+ UInt64 lenInBits = (_count << 3);
+ UInt32 curBufferPos = (UInt32)_count & 0x3F;
+ _buffer[curBufferPos++] = 0x80;
+ while (curBufferPos != (64 - 8))
+ {
+ curBufferPos &= 0x3F;
+ if (curBufferPos == 0)
+ WriteByteBlock();
+ _buffer[curBufferPos++] = 0;
+ }
+ for (int i = 0; i < 8; i++)
+ {
+ _buffer[curBufferPos++] = (Byte)(lenInBits >> 56);
+ lenInBits <<= 8;
+ }
+ WriteByteBlock();
+
+ for (int j = 0; j < 8; j++)
+ {
+ *digest++ = (Byte)(_state[j] >> 24);
+ *digest++ = (Byte)(_state[j] >> 16);
+ *digest++ = (Byte)(_state[j] >> 8);
+ *digest++ = (Byte)(_state[j]);
+ }
+ Init();
+}
+
+}}
diff --git a/CPP/7zip/Crypto/Hash/Sha256.h b/CPP/7zip/Crypto/Hash/Sha256.h
new file mode 100755
index 00000000..e4788f41
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/Sha256.h
@@ -0,0 +1,30 @@
+// Crypto/Sha256.h
+
+#ifndef __CRYPTO_SHA256_H
+#define __CRYPTO_SHA256_H
+
+#include "Common/Types.h"
+
+namespace NCrypto {
+namespace NSha256 {
+
+class CContext
+{
+ static const UInt32 K[64];
+
+ UInt32 _state[8];
+ UInt64 _count;
+ Byte _buffer[64];
+ static void Transform(UInt32 *digest, const UInt32 *data);
+ void WriteByteBlock();
+public:
+ enum {DIGESTSIZE = 32};
+ CContext() { Init(); } ;
+ void Init();
+ void Update(const Byte *data, size_t size);
+ void Final(Byte *digest);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/Hash/StdAfx.h b/CPP/7zip/Crypto/Hash/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Crypto/Rar20/Rar20Cipher.cpp b/CPP/7zip/Crypto/Rar20/Rar20Cipher.cpp
new file mode 100755
index 00000000..27ccc493
--- /dev/null
+++ b/CPP/7zip/Crypto/Rar20/Rar20Cipher.cpp
@@ -0,0 +1,76 @@
+// Crypto/Rar20Cipher.cpp
+
+#include "StdAfx.h"
+
+#include "Rar20Cipher.h"
+#include "Windows/Defs.h"
+
+namespace NCrypto {
+namespace NRar20 {
+
+static const int kBufferSize = 1 << 17;
+
+STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size)
+{
+ _coder.SetPassword(data, size);
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::Init()
+{
+ return S_OK;
+}
+
+STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size)
+{
+ const UInt16 kBlockSize = 16;
+ if (size > 0 && size < kBlockSize)
+ return kBlockSize;
+ UInt32 i;
+ for (i = 0; i + kBlockSize <= size; i += kBlockSize)
+ {
+ _coder.DecryptBlock(data + i);
+ }
+ return i;
+}
+
+/*
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ UInt64 nowPos = 0;
+ UInt32 bufferPos = 0;
+ UInt32 processedSize;
+ for (;;)
+ {
+ UInt32 size = kBufferSize - bufferPos;
+ RINOK(inStream->Read(_buffer + bufferPos, size, &processedSize));
+
+ UInt32 anEndPos = bufferPos + processedSize;
+ for (;bufferPos + 16 <= anEndPos; bufferPos += 16)
+ _coder.DecryptBlock(_buffer + bufferPos);
+
+ if (bufferPos == 0)
+ return S_OK;
+
+ if (outSize != NULL && nowPos + bufferPos > *outSize)
+ bufferPos = UInt32(*outSize - nowPos);
+
+ RINOK(outStream->Write(_buffer, bufferPos, &processedSize));
+ if (bufferPos != processedSize)
+ return E_FAIL;
+
+ nowPos += processedSize;
+ if (outSize != NULL && nowPos == *outSize)
+ return S_OK;
+
+ int i = 0;
+ while(bufferPos < anEndPos)
+ _buffer[i++] = _buffer[bufferPos++];
+ bufferPos = i;
+ }
+}
+*/
+
+}}
diff --git a/CPP/7zip/Crypto/Rar20/Rar20Cipher.h b/CPP/7zip/Crypto/Rar20/Rar20Cipher.h
new file mode 100755
index 00000000..e2091cda
--- /dev/null
+++ b/CPP/7zip/Crypto/Rar20/Rar20Cipher.h
@@ -0,0 +1,35 @@
+// Crypto/Rar20Cipher.h
+
+#ifndef __CRYPTO_RAR20_CIPHER_H
+#define __CRYPTO_RAR20_CIPHER_H
+
+#include "../../ICoder.h"
+#include "../../IPassword.h"
+#include "Common/MyCom.h"
+
+#include "Common/Types.h"
+#include "Rar20Crypto.h"
+
+namespace NCrypto {
+namespace NRar20 {
+
+class CDecoder:
+ public ICompressFilter,
+ public ICryptoSetPassword,
+ public CMyUnknownImp
+{
+public:
+ CData _coder;
+
+ MY_UNKNOWN_IMP1(ICryptoSetPassword)
+
+ STDMETHOD(Init)();
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+
+ STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
+
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/Rar20/Rar20Crypto.cpp b/CPP/7zip/Crypto/Rar20/Rar20Crypto.cpp
new file mode 100755
index 00000000..d8be2279
--- /dev/null
+++ b/CPP/7zip/Crypto/Rar20/Rar20Crypto.cpp
@@ -0,0 +1,124 @@
+// Crypto/Rar20/Crypto.cpp
+
+#include "StdAfx.h"
+
+#include "Rar20Crypto.h"
+#include "../../../Common/CRC.h"
+
+#define rol(x,n) (((x) << (n)) | ((x) >> (8 * sizeof(x) - (n))))
+#define ror(x,n) (((x) >> (n)) | ((x) << (8 * sizeof(x) - (n))))
+
+namespace NCrypto {
+namespace NRar20 {
+
+static const int kNumRounds = 32;
+
+static const Byte InitSubstTable[256] = {
+ 215, 19,149, 35, 73,197,192,205,249, 28, 16,119, 48,221, 2, 42,
+ 232, 1,177,233, 14, 88,219, 25,223,195,244, 90, 87,239,153,137,
+ 255,199,147, 70, 92, 66,246, 13,216, 40, 62, 29,217,230, 86, 6,
+ 71, 24,171,196,101,113,218,123, 93, 91,163,178,202, 67, 44,235,
+ 107,250, 75,234, 49,167,125,211, 83,114,157,144, 32,193,143, 36,
+ 158,124,247,187, 89,214,141, 47,121,228, 61,130,213,194,174,251,
+ 97,110, 54,229,115, 57,152, 94,105,243,212, 55,209,245, 63, 11,
+ 164,200, 31,156, 81,176,227, 21, 76, 99,139,188,127, 17,248, 51,
+ 207,120,189,210, 8,226, 41, 72,183,203,135,165,166, 60, 98, 7,
+ 122, 38,155,170, 69,172,252,238, 39,134, 59,128,236, 27,240, 80,
+ 131, 3, 85,206,145, 79,154,142,159,220,201,133, 74, 64, 20,129,
+ 224,185,138,103,173,182, 43, 34,254, 82,198,151,231,180, 58, 10,
+ 118, 26,102, 12, 50,132, 22,191,136,111,162,179, 45, 4,148,108,
+ 161, 56, 78,126,242,222, 15,175,146, 23, 33,241,181,190, 77,225,
+ 0, 46,169,186, 68, 95,237, 65, 53,208,253,168, 9, 18,100, 52,
+ 116,184,160, 96,109, 37, 30,106,140,104,150, 5,204,117,112, 84
+};
+
+void CData::UpdateKeys(const Byte *data)
+{
+ for (int i = 0; i < 16; i += 4)
+ for (int j = 0; j < 4; j++)
+ Keys[j] ^= CCRC::Table[data[i + j]];
+}
+
+static void Swap(Byte *b1, Byte *b2)
+{
+ Byte b = *b1;
+ *b1 = *b2;
+ *b2 = b;
+}
+
+void CData::SetPassword(const Byte *password, UInt32 passwordLength)
+{
+ // SetOldKeys(password);
+
+ Keys[0] = 0xD3A3B879L;
+ Keys[1] = 0x3F6D12F7L;
+ Keys[2] = 0x7515A235L;
+ Keys[3] = 0xA4E7F123L;
+
+ Byte psw[256];
+ memset(psw, 0, sizeof(psw));
+
+ memmove(psw, password, passwordLength);
+
+ memcpy(SubstTable, InitSubstTable, sizeof(SubstTable));
+ for (UInt32 j = 0; j < 256; j++)
+ for (UInt32 i = 0; i < passwordLength; i += 2)
+ {
+ UInt32 n2 = (Byte)CCRC::Table[(psw[i + 1] + j) & 0xFF];
+ UInt32 n1 = (Byte)CCRC::Table[(psw[i] - j) & 0xFF];
+ for (UInt32 k = 1; (n1 & 0xFF) != n2; n1++, k++)
+ Swap(&SubstTable[n1 & 0xFF], &SubstTable[(n1 + i + k) & 0xFF]);
+ }
+ for (UInt32 i = 0; i < passwordLength; i+= 16)
+ EncryptBlock(&psw[i]);
+}
+
+static inline UInt32 GetUInt32FromMemLE(const Byte *p)
+{
+ return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);
+}
+
+static inline void WriteUInt32ToMemLE(UInt32 v, Byte *p)
+{
+ p[0] = (Byte)v;
+ p[1] = (Byte)(v >> 8);
+ p[2] = (Byte)(v >> 16);
+ p[3] = (Byte)(v >> 24);
+}
+
+void CData::CryptBlock(Byte *buf, bool encrypt)
+{
+ Byte inBuf[16];
+ UInt32 A, B, C, D, T, TA, TB;
+
+ A = GetUInt32FromMemLE(buf + 0) ^ Keys[0];
+ B = GetUInt32FromMemLE(buf + 4) ^ Keys[1];
+ C = GetUInt32FromMemLE(buf + 8) ^ Keys[2];
+ D = GetUInt32FromMemLE(buf + 12) ^ Keys[3];
+
+ if (!encrypt)
+ memcpy(inBuf, buf, sizeof(inBuf));
+
+ for(int i = 0; i < kNumRounds; i++)
+ {
+ UInt32 key = Keys[(encrypt ? i : (kNumRounds - 1 - i)) & 3];
+ T = ((C + rol(D, 11)) ^ key);
+ TA = A ^ SubstLong(T);
+ T = ((D ^ rol(C, 17)) + key);
+ TB = B ^ SubstLong(T);
+ A = C;
+ B = D;
+ C = TA;
+ D = TB;
+ }
+
+ WriteUInt32ToMemLE(C ^ Keys[0], buf + 0);
+ WriteUInt32ToMemLE(D ^ Keys[1], buf + 4);
+ WriteUInt32ToMemLE(A ^ Keys[2], buf + 8);
+ WriteUInt32ToMemLE(B ^ Keys[3], buf + 12);
+
+ UpdateKeys(encrypt ? buf : inBuf);
+}
+
+
+}}
diff --git a/CPP/7zip/Crypto/Rar20/Rar20Crypto.h b/CPP/7zip/Crypto/Rar20/Rar20Crypto.h
new file mode 100755
index 00000000..071d01f1
--- /dev/null
+++ b/CPP/7zip/Crypto/Rar20/Rar20Crypto.h
@@ -0,0 +1,33 @@
+// Crypto/Rar20/Crypto.h
+
+#ifndef __CRYPTO_RAR20_CRYPTO_H
+#define __CRYPTO_RAR20_CRYPTO_H
+
+#include "../../../Common/Types.h"
+
+namespace NCrypto {
+namespace NRar20 {
+
+class CData
+{
+ Byte SubstTable[256];
+ UInt32 Keys[4];
+ UInt32 SubstLong(UInt32 t)
+ {
+ return (UInt32)SubstTable[(int)t & 255] |
+ ((UInt32)SubstTable[(int)(t >> 8) & 255] << 8) |
+ ((UInt32)SubstTable[(int)(t >> 16) & 255] << 16) |
+ ((UInt32)SubstTable[(int)(t >> 24) & 255] << 24);
+ }
+
+ void UpdateKeys(const Byte *data);
+ void CryptBlock(Byte *buf, bool encrypt);
+public:
+ void EncryptBlock(Byte *buf) { CryptBlock(buf, true); }
+ void DecryptBlock(Byte *buf) { CryptBlock(buf, false); }
+ void SetPassword(const Byte *password, UInt32 passwordLength);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/Rar20/StdAfx.h b/CPP/7zip/Crypto/Rar20/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Crypto/Rar20/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Crypto/RarAES/RarAES.cpp b/CPP/7zip/Crypto/RarAES/RarAES.cpp
new file mode 100755
index 00000000..ae22bb2a
--- /dev/null
+++ b/CPP/7zip/Crypto/RarAES/RarAES.cpp
@@ -0,0 +1,187 @@
+// Crypto/RarAES/RarAES.h
+// This code is based on UnRar sources
+
+#include "StdAfx.h"
+
+#include "RarAES.h"
+#include "../Hash/Sha1.h"
+
+extern void GetCryptoFolderPrefix(TCHAR *path);
+
+namespace NCrypto {
+namespace NRar29 {
+
+CDecoder::CDecoder():
+ _thereIsSalt(false),
+ _needCalculate(true),
+ _rar350Mode(false)
+{
+ for (int i = 0; i < sizeof(_salt); i++)
+ _salt[i] = 0;
+}
+
+STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
+{
+ bool thereIsSaltPrev = _thereIsSalt;
+ _thereIsSalt = false;
+ if (size == 0)
+ return S_OK;
+ if (size < 8)
+ return E_INVALIDARG;
+ _thereIsSalt = true;
+ bool same = false;
+ if (_thereIsSalt == thereIsSaltPrev)
+ {
+ same = true;
+ if (_thereIsSalt)
+ {
+ for (int i = 0; i < sizeof(_salt); i++)
+ if (_salt[i] != data[i])
+ {
+ same = false;
+ break;
+ }
+ }
+ }
+ for (int i = 0; i < sizeof(_salt); i++)
+ _salt[i] = data[i];
+ if (!_needCalculate && !same)
+ _needCalculate = true;
+ 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())
+ {
+ same = true;
+ for (UInt32 i = 0; i < size; i++)
+ if (data[i] != buffer[i])
+ {
+ same = false;
+ break;
+ }
+ }
+ if (!_needCalculate && !same)
+ _needCalculate = true;
+ buffer.SetCapacity(size);
+ memcpy(buffer, data, size);
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::Init()
+{
+ Calculate();
+ RINOK(CreateFilter());
+ CMyComPtr<ICryptoProperties> cp;
+ RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp));
+ RINOK(cp->SetKey(aesKey, 16));
+ RINOK(cp->SetInitVector(aesInit, 16));
+ _aesFilter->Init();
+ return S_OK;
+}
+
+HRESULT CDecoder::CreateFilter()
+{
+ if (_aesFilter)
+ return S_OK;
+ TCHAR aesLibPath[MAX_PATH + 64];
+ GetCryptoFolderPrefix(aesLibPath);
+ lstrcat(aesLibPath, TEXT("AES.dll"));
+ return _aesLib.LoadAndCreateFilter(aesLibPath, CLSID_CCrypto_AES_CBC_Decoder, &_aesFilter);
+}
+
+STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size)
+{
+ return _aesFilter->Filter(data, size);
+}
+
+void CDecoder::Calculate()
+{
+ if (_needCalculate)
+ {
+ const int kSaltSize = 8;
+
+ Byte rawPassword[kMaxPasswordLength + kSaltSize];
+
+ memcpy(rawPassword, buffer, buffer.GetCapacity());
+
+ size_t rawLength = buffer.GetCapacity();
+
+ if (_thereIsSalt)
+ {
+ memcpy(rawPassword + rawLength, _salt, kSaltSize);
+ rawLength += kSaltSize;
+ }
+
+ NSha1::CContext 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, _rar350Mode);
+ Byte pswNum[3] = { (Byte)i, (Byte)(i >> 8), (Byte)(i >> 16) };
+ sha.Update(pswNum, 3, _rar350Mode);
+ if (i % (hashRounds / 16) == 0)
+ {
+ NSha1::CContext shaTemp = sha;
+ Byte digest[NSha1::kDigestSize];
+ shaTemp.Final(digest);
+ aesInit[i / (hashRounds / 16)] = (Byte)digest[4 * 4 + 3];
+ }
+ }
+ /*
+ // it's test message for sha
+ const char *message = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
+ sha.Update((const Byte *)message, strlen(message));
+ */
+ Byte digest[20];
+ sha.Final(digest);
+ for (i = 0; i < 4; i++)
+ for (int j = 0; j < 4; j++)
+ aesKey[i * 4 + j] = (digest[i * 4 + 3 - j]);
+ }
+ _needCalculate = false;
+}
+
+
+
+/*
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, UInt64 const *inSize,
+ const UInt64 *outSize,ICompressProgressInfo *progress)
+{
+ Calculate();
+ TCHAR aesLibPath[MAX_PATH + 64];
+ GetCryptoFolderPrefix(aesLibPath);
+ lstrcat(aesLibPath, TEXT("AES.dll"));
+ CCoderLibrary aesLib;
+ CMyComPtr<ICompressCoder2> aesDecoder;
+ RINOK(aesLib.LoadAndCreateCoder2(aesLibPath, CLSID_CCrypto_AES128_Decoder, &aesDecoder));
+
+ CSequentialInStreamImp *ivStreamSpec = new CSequentialInStreamImp;
+ CMyComPtr<ISequentialInStream> ivStream(ivStreamSpec);
+ ivStreamSpec->Init(aesInit, 16);
+
+ CSequentialInStreamImp *keyStreamSpec = new CSequentialInStreamImp;
+ CMyComPtr<ISequentialInStream> keyStream(keyStreamSpec);
+ keyStreamSpec->Init(aesKey, 16);
+
+ ISequentialInStream *inStreams[3] = { inStream, ivStream, keyStream };
+ UInt64 ivSize = 16;
+ UInt64 keySize = 16;
+ const UInt64 *inSizes[3] = { inSize, &ivSize, &ivSize, };
+ return aesDecoder->Code(inStreams, inSizes, 3,
+ &outStream, &outSize, 1, progress);
+}
+*/
+
+}}
diff --git a/CPP/7zip/Crypto/RarAES/RarAES.h b/CPP/7zip/Crypto/RarAES/RarAES.h
new file mode 100755
index 00000000..4b435b5e
--- /dev/null
+++ b/CPP/7zip/Crypto/RarAES/RarAES.h
@@ -0,0 +1,61 @@
+// Crypto/CRarAES/RarAES.h
+
+#ifndef __CRYPTO_RARAES_H
+#define __CRYPTO_RARAES_H
+
+#include "Common/MyCom.h"
+#include "../../ICoder.h"
+#include "../../IPassword.h"
+#include "../../Archive/Common/CoderLoader.h"
+
+#include "Common/Types.h"
+#include "Common/Buffer.h"
+
+DEFINE_GUID(CLSID_CCrypto_AES_CBC_Decoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+namespace NCrypto {
+namespace NRar29 {
+
+class CDecoder:
+ public ICompressFilter,
+ public ICompressSetDecoderProperties2,
+ public ICryptoSetPassword,
+ public CMyUnknownImp
+{
+ Byte _salt[8];
+ bool _thereIsSalt;
+ CByteBuffer buffer;
+ Byte aesKey[16];
+ Byte aesInit[16];
+ bool _needCalculate;
+
+ CCoderLibrary _aesLib;
+ CMyComPtr<ICompressFilter> _aesFilter;
+
+ bool _rar350Mode;
+
+ void Calculate();
+ HRESULT CreateFilter();
+
+public:
+
+ MY_UNKNOWN_IMP2(
+ ICryptoSetPassword,
+ ICompressSetDecoderProperties2)
+
+ STDMETHOD(Init)();
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+
+ STDMETHOD(CryptoSetPassword)(const Byte *aData, UInt32 aSize);
+
+ // ICompressSetDecoderProperties
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+
+ CDecoder();
+ void SetRar350Mode(bool rar350Mode) { _rar350Mode = rar350Mode; }
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/RarAES/StdAfx.h b/CPP/7zip/Crypto/RarAES/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Crypto/RarAES/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Crypto/WzAES/StdAfx.cpp b/CPP/7zip/Crypto/WzAES/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/Crypto/WzAES/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/Crypto/WzAES/StdAfx.h b/CPP/7zip/Crypto/WzAES/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Crypto/WzAES/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Crypto/WzAES/WzAES.cpp b/CPP/7zip/Crypto/WzAES/WzAES.cpp
new file mode 100755
index 00000000..8bf53b43
--- /dev/null
+++ b/CPP/7zip/Crypto/WzAES/WzAES.cpp
@@ -0,0 +1,246 @@
+// WzAES.cpp
+/*
+This code implements Brian Gladman's scheme
+specified in password Based File Encryption Utility.
+*/
+
+#include "StdAfx.h"
+
+#include "Windows/Defs.h"
+#include "../../Common/StreamObjects.h"
+#include "../../Common/StreamUtils.h"
+#include "../Hash/Pbkdf2HmacSha1.h"
+#include "../Hash/RandGen.h"
+
+#include "WzAES.h"
+
+#ifdef CRYPTO_AES
+#include "../AES/MyAES.h"
+#else
+extern void GetCryptoFolderPrefix(TCHAR *path);
+#endif
+
+// define it if you don't want to use speed-optimized version of Pbkdf2HmacSha1
+// #define _NO_WZAES_OPTIMIZATIONS
+
+namespace NCrypto {
+namespace NWzAES {
+
+const unsigned int kAesKeySizeMax = 32;
+
+static const UInt32 kNumKeyGenIterations = 1000;
+
+STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size)
+{
+ if(size > kPasswordSizeMax)
+ return E_INVALIDARG;
+ _key.Password.SetCapacity(size);
+ memcpy(_key.Password, data, size);
+ return S_OK;
+}
+
+void CBaseCoder::EncryptData(Byte *data, UInt32 size)
+{
+ unsigned int pos = _blockPos;
+ for (; size > 0; size--)
+ {
+ if (pos == kAesBlockSize)
+ {
+ int j;
+ for (j = 0; j < 8 && ++_counter[j] == 0; j++);
+ for (j = 0; j < 8; j++)
+ _buffer[j] = _counter[j];
+ for (; j < kAesBlockSize; j++)
+ _buffer[j] = 0;
+ _aesFilter->Filter(_buffer, kAesBlockSize);
+ pos = 0;
+ }
+ *data++ ^= _buffer[pos++];
+ }
+ _blockPos = pos;
+}
+
+#ifndef _NO_WZAES_OPTIMIZATIONS
+
+static void BytesToBeUInt32s(const Byte *src, UInt32 *dest, int destSize)
+{
+ for (int i = 0 ; i < destSize; i++)
+ dest[i] =
+ ((UInt32)(src[i * 4 + 0]) << 24) |
+ ((UInt32)(src[i * 4 + 1]) << 16) |
+ ((UInt32)(src[i * 4 + 2]) << 8) |
+ ((UInt32)(src[i * 4 + 3]));
+}
+
+#endif
+
+STDMETHODIMP CBaseCoder::Init()
+{
+ UInt32 keySize = _key.GetKeySize();
+ UInt32 keysTotalSize = 2 * keySize + kPwdVerifCodeSize;
+ Byte buf[2 * kAesKeySizeMax + kPwdVerifCodeSize];
+
+ // for (int ii = 0; ii < 1000; ii++)
+ {
+ #ifdef _NO_WZAES_OPTIMIZATIONS
+
+ NSha1::Pbkdf2Hmac(
+ _key.Password, _key.Password.GetCapacity(),
+ _key.Salt, _key.GetSaltSize(),
+ kNumKeyGenIterations,
+ buf, keysTotalSize);
+
+ #else
+
+ UInt32 buf32[(2 * kAesKeySizeMax + kPwdVerifCodeSize + 3) / 4];
+ UInt32 key32SizeTotal = (keysTotalSize + 3) / 4;
+ UInt32 salt[kSaltSizeMax * 4];
+ UInt32 saltSizeInWords = _key.GetSaltSize() / 4;
+ BytesToBeUInt32s(_key.Salt, salt, saltSizeInWords);
+ NSha1::Pbkdf2Hmac32(
+ _key.Password, _key.Password.GetCapacity(),
+ salt, saltSizeInWords,
+ kNumKeyGenIterations,
+ buf32, key32SizeTotal);
+ for (UInt32 j = 0; j < keysTotalSize; j++)
+ buf[j] = (Byte)(buf32[j / 4] >> (24 - 8 * (j & 3)));
+
+ #endif
+ }
+
+ _hmac.SetKey(buf + keySize, keySize);
+ memcpy(_key.PwdVerifComputed, buf + 2 * keySize, kPwdVerifCodeSize);
+
+ _blockPos = kAesBlockSize;
+ for (int i = 0; i < 8; i++)
+ _counter[i] = 0;
+
+ RINOK(CreateFilters());
+ CMyComPtr<ICryptoProperties> cp;
+ RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp));
+ return cp->SetKey(buf, keySize);
+}
+
+static HRESULT SafeWrite(ISequentialOutStream *outStream, const Byte *data, UInt32 size)
+{
+ UInt32 processedSize;
+ RINOK(WriteStream(outStream, data, size, &processedSize));
+ return ((processedSize == size) ? S_OK : E_FAIL);
+}
+
+/*
+STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{
+ Byte keySizeMode = 3;
+ return outStream->Write(&keySizeMode, 1, NULL);
+}
+*/
+
+HRESULT CEncoder::WriteHeader(ISequentialOutStream *outStream)
+{
+ UInt32 saltSize = _key.GetSaltSize();
+ g_RandomGenerator.Generate(_key.Salt, saltSize);
+ Init();
+ RINOK(SafeWrite(outStream, _key.Salt, saltSize));
+ return SafeWrite(outStream, _key.PwdVerifComputed, kPwdVerifCodeSize);
+}
+
+HRESULT CEncoder::WriteFooter(ISequentialOutStream *outStream)
+{
+ Byte mac[kMacSize];
+ _hmac.Final(mac, kMacSize);
+ return SafeWrite(outStream, mac, kMacSize);
+}
+
+STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
+{
+ if (size != 1)
+ return E_INVALIDARG;
+ _key.Init();
+ Byte keySizeMode = data[0];
+ if (keySizeMode < 1 || keySizeMode > 3)
+ return E_INVALIDARG;
+ _key.KeySizeMode = keySizeMode;
+ return S_OK;
+}
+
+HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream)
+{
+ UInt32 saltSize = _key.GetSaltSize();
+ UInt32 extraSize = saltSize + kPwdVerifCodeSize;
+ Byte temp[kSaltSizeMax + kPwdVerifCodeSize];
+ UInt32 processedSize;
+ RINOK(ReadStream(inStream, temp, extraSize, &processedSize));
+ if (processedSize != extraSize)
+ return E_FAIL;
+ UInt32 i;
+ for (i = 0; i < saltSize; i++)
+ _key.Salt[i] = temp[i];
+ for (i = 0; i < kPwdVerifCodeSize; i++)
+ _pwdVerifFromArchive[i] = temp[saltSize + i];
+ return S_OK;
+}
+
+static bool CompareArrays(const Byte *p1, const Byte *p2, UInt32 size)
+{
+ for (UInt32 i = 0; i < size; i++)
+ if (p1[i] != p2[i])
+ return false;
+ return true;
+}
+
+bool CDecoder::CheckPasswordVerifyCode()
+{
+ return CompareArrays(_key.PwdVerifComputed, _pwdVerifFromArchive, kPwdVerifCodeSize);
+}
+
+HRESULT CDecoder::CheckMac(ISequentialInStream *inStream, bool &isOK)
+{
+ isOK = false;
+ UInt32 processedSize;
+ Byte mac1[kMacSize];
+ RINOK(ReadStream(inStream, mac1, kMacSize, &processedSize));
+ if (processedSize != kMacSize)
+ return E_FAIL;
+ Byte mac2[kMacSize];
+ _hmac.Final(mac2, kMacSize);
+ isOK = CompareArrays(mac1, mac2, kMacSize);
+ return S_OK;
+}
+
+STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size)
+{
+ EncryptData(data, size);
+ _hmac.Update(data, size);
+ return size;
+}
+
+STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size)
+{
+ _hmac.Update(data, size);
+ EncryptData(data, size);
+ return size;
+}
+
+
+HRESULT CBaseCoder::CreateFilters()
+{
+ if (!_aesFilter)
+ {
+ #ifdef CRYPTO_AES
+
+ _aesFilter = new CAES_ECB_Encoder;
+
+ #else
+
+ TCHAR aesLibPath[MAX_PATH + 64];
+ GetCryptoFolderPrefix(aesLibPath);
+ lstrcat(aesLibPath, TEXT("AES.dll"));
+ RINOK(_aesLibrary.LoadAndCreateFilter(aesLibPath, CLSID_CCrypto_AES_ECB_Encoder, &_aesFilter));
+
+ #endif
+ }
+ return S_OK;
+}
+
+}}
diff --git a/CPP/7zip/Crypto/WzAES/WzAES.h b/CPP/7zip/Crypto/WzAES/WzAES.h
new file mode 100755
index 00000000..c27bd326
--- /dev/null
+++ b/CPP/7zip/Crypto/WzAES/WzAES.h
@@ -0,0 +1,126 @@
+// WzAES.h
+/*
+This code implements Brian Gladman's scheme
+specified in password Based File Encryption Utility:
+ - AES encryption (128,192,256-bit) in Counter (CTR) mode.
+ - HMAC-SHA1 authentication for encrypted data (10 bytes)
+ - Keys are derived by PPKDF2(RFC2898)-HMAC-SHA1 from ASCII password and
+ Salt (saltSize = aesKeySize / 2).
+ - 2 bytes contain Password Verifier's Code
+*/
+
+#ifndef __CRYPTO_WZ_AES_H
+#define __CRYPTO_WZ_AES_H
+
+#include "../Hash/HmacSha1.h"
+
+#include "Common/MyCom.h"
+#include "Common/Buffer.h"
+#include "Common/Vector.h"
+
+#include "../../ICoder.h"
+#include "../../IPassword.h"
+
+#ifndef CRYPTO_AES
+#include "../../Archive/Common/CoderLoader.h"
+#endif
+
+DEFINE_GUID(CLSID_CCrypto_AES_ECB_Encoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0xC0, 0x00, 0x00, 0x00, 0x01, 0x00);
+
+namespace NCrypto {
+namespace NWzAES {
+
+const unsigned int kAesBlockSize = 16;
+const unsigned int kSaltSizeMax = 16;
+const unsigned int kMacSize = 10;
+
+const UInt32 kPasswordSizeMax = 99; // 128;
+
+// Password Verification Code Size
+const unsigned int kPwdVerifCodeSize = 2;
+
+class CKeyInfo
+{
+public:
+ Byte KeySizeMode; // 1 - 128-bit , 2 - 192-bit , 3 - 256-bit
+ Byte Salt[kSaltSizeMax];
+ Byte PwdVerifComputed[kPwdVerifCodeSize];
+
+ CByteBuffer Password;
+
+ UInt32 GetKeySize() const { return (8 * (KeySizeMode & 3) + 8); }
+ UInt32 GetSaltSize() const { return (4 * (KeySizeMode & 3) + 4); }
+
+ CKeyInfo() { Init(); }
+ void Init() { KeySizeMode = 3; }
+};
+
+class CBaseCoder:
+ public ICompressFilter,
+ public ICryptoSetPassword,
+ public CMyUnknownImp
+{
+protected:
+ CKeyInfo _key;
+ Byte _counter[8];
+ Byte _buffer[kAesBlockSize];
+ NSha1::CHmac _hmac;
+ unsigned int _blockPos;
+ Byte _pwdVerifFromArchive[kPwdVerifCodeSize];
+
+ void EncryptData(Byte *data, UInt32 size);
+
+ #ifndef CRYPTO_AES
+ CCoderLibrary _aesLibrary;
+ #endif
+ CMyComPtr<ICompressFilter> _aesFilter;
+
+ HRESULT CreateFilters();
+public:
+ STDMETHOD(Init)();
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) = 0;
+
+ STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
+
+ UInt32 GetHeaderSize() const { return _key.GetSaltSize() + kPwdVerifCodeSize; }
+};
+
+class CEncoder:
+ public CBaseCoder
+ // public ICompressWriteCoderProperties
+{
+public:
+ MY_UNKNOWN_IMP1(ICryptoSetPassword)
+ // ICompressWriteCoderProperties
+ // STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+ HRESULT WriteHeader(ISequentialOutStream *outStream);
+ HRESULT WriteFooter(ISequentialOutStream *outStream);
+ bool SetKeyMode(Byte mode)
+ {
+ if (mode < 1 || mode > 3)
+ return false;
+ _key.KeySizeMode = mode;
+ return true;
+ }
+};
+
+class CDecoder:
+ public CBaseCoder,
+ public ICompressSetDecoderProperties2
+{
+public:
+ MY_UNKNOWN_IMP2(
+ ICryptoSetPassword,
+ ICompressSetDecoderProperties2)
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+ HRESULT ReadHeader(ISequentialInStream *inStream);
+ bool CheckPasswordVerifyCode();
+ HRESULT CheckMac(ISequentialInStream *inStream, bool &isOK);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/Zip/StdAfx.h b/CPP/7zip/Crypto/Zip/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Crypto/Zip/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/CPP/7zip/Crypto/Zip/ZipCipher.cpp b/CPP/7zip/Crypto/Zip/ZipCipher.cpp
new file mode 100755
index 00000000..639776ce
--- /dev/null
+++ b/CPP/7zip/Crypto/Zip/ZipCipher.cpp
@@ -0,0 +1,85 @@
+// Crypto/ZipCipher.h
+
+#include "StdAfx.h"
+
+#include "ZipCipher.h"
+#include "Windows/Defs.h"
+
+#include "../../Common/StreamUtils.h"
+#include "../Hash/RandGen.h"
+
+namespace NCrypto {
+namespace NZip {
+
+STDMETHODIMP CEncoder::CryptoSetPassword(const Byte *data, UInt32 size)
+{
+ _cipher.SetPassword(data, size);
+ return S_OK;
+}
+
+STDMETHODIMP CEncoder::CryptoSetCRC(UInt32 crc)
+{
+ _crc = crc;
+ return S_OK;
+}
+
+STDMETHODIMP CEncoder::Init()
+{
+ return S_OK;
+}
+
+HRESULT CEncoder::WriteHeader(ISequentialOutStream *outStream)
+{
+ Byte header[kHeaderSize];
+ g_RandomGenerator.Generate(header, kHeaderSize - 2);
+
+ header[kHeaderSize - 1] = Byte(_crc >> 24);
+ header[kHeaderSize - 2] = Byte(_crc >> 16);
+
+ UInt32 processedSize;
+ _cipher.EncryptHeader(header);
+ RINOK(WriteStream(outStream, header, kHeaderSize, &processedSize));
+ if (processedSize != kHeaderSize)
+ return E_FAIL;
+ return S_OK;
+}
+
+STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size)
+{
+ UInt32 i;
+ for (i = 0; i < size; i++)
+ data[i] = _cipher.EncryptByte(data[i]);
+ return i;
+}
+
+STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size)
+{
+ _cipher.SetPassword(data, size);
+ return S_OK;
+}
+
+HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream)
+{
+ Byte header[kHeaderSize];
+ UInt32 processedSize;
+ RINOK(ReadStream(inStream, header, kHeaderSize, &processedSize));
+ if (processedSize != kHeaderSize)
+ return E_FAIL;
+ _cipher.DecryptHeader(header);
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::Init()
+{
+ return S_OK;
+}
+
+STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size)
+{
+ UInt32 i;
+ for (i = 0; i < size; i++)
+ data[i] = _cipher.DecryptByte(data[i]);
+ return i;
+}
+
+}}
diff --git a/CPP/7zip/Crypto/Zip/ZipCipher.h b/CPP/7zip/Crypto/Zip/ZipCipher.h
new file mode 100755
index 00000000..d750336c
--- /dev/null
+++ b/CPP/7zip/Crypto/Zip/ZipCipher.h
@@ -0,0 +1,59 @@
+// Crypto/ZipCipher.h
+
+#ifndef __CRYPTO_ZIPCIPHER_H
+#define __CRYPTO_ZIPCIPHER_H
+
+#include "Common/MyCom.h"
+#include "Common/Types.h"
+
+#include "../../ICoder.h"
+#include "../../IPassword.h"
+
+#include "ZipCrypto.h"
+
+namespace NCrypto {
+namespace NZip {
+
+class CEncoder :
+ public ICompressFilter,
+ public ICryptoSetPassword,
+ public ICryptoSetCRC,
+ public CMyUnknownImp
+{
+ CCipher _cipher;
+ UInt32 _crc;
+public:
+ MY_UNKNOWN_IMP2(
+ ICryptoSetPassword,
+ ICryptoSetCRC
+ )
+ STDMETHOD(Init)();
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+
+ STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
+ STDMETHOD(CryptoSetCRC)(UInt32 crc);
+ HRESULT WriteHeader(ISequentialOutStream *outStream);
+};
+
+
+class CDecoder:
+ public ICompressFilter,
+ public ICryptoSetPassword,
+ public CMyUnknownImp
+ // public CBuffer2
+{
+ CCipher _cipher;
+public:
+
+ MY_UNKNOWN_IMP1(ICryptoSetPassword)
+
+ STDMETHOD(Init)();
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+
+ HRESULT ReadHeader(ISequentialInStream *inStream);
+ STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/Zip/ZipCrypto.cpp b/CPP/7zip/Crypto/Zip/ZipCrypto.cpp
new file mode 100755
index 00000000..79f0953c
--- /dev/null
+++ b/CPP/7zip/Crypto/Zip/ZipCrypto.cpp
@@ -0,0 +1,65 @@
+// Crypto/ZipCrypto.cpp
+
+#include "StdAfx.h"
+
+#include "ZipCipher.h"
+#include "../../../Common/CRC.h"
+
+namespace NCrypto {
+namespace NZip {
+
+static inline UInt32 ZipCRC32(UInt32 c, Byte b)
+{
+ return CCRC::Table[(c ^ b) & 0xFF] ^ (c >> 8);
+}
+
+void CCipher::UpdateKeys(Byte b)
+{
+ Keys[0] = ZipCRC32(Keys[0], b);
+ Keys[1] += Keys[0] & 0xff;
+ Keys[1] = Keys[1] * 134775813L + 1;
+ Keys[2] = ZipCRC32(Keys[2], (Byte)(Keys[1] >> 24));
+}
+
+void CCipher::SetPassword(const Byte *password, UInt32 passwordLength)
+{
+ Keys[0] = 305419896L;
+ Keys[1] = 591751049L;
+ Keys[2] = 878082192L;
+ for (UInt32 i = 0; i < passwordLength; i++)
+ UpdateKeys(password[i]);
+}
+
+Byte CCipher::DecryptByteSpec()
+{
+ UInt32 temp = Keys[2] | 2;
+ return (Byte)((temp * (temp ^ 1)) >> 8);
+}
+
+Byte CCipher::DecryptByte(Byte encryptedByte)
+{
+ Byte c = (Byte)(encryptedByte ^ DecryptByteSpec());
+ UpdateKeys(c);
+ return c;
+}
+
+Byte CCipher::EncryptByte(Byte b)
+{
+ Byte c = (Byte)(b ^ DecryptByteSpec());
+ UpdateKeys(b);
+ return c;
+}
+
+void CCipher::DecryptHeader(Byte *buffer)
+{
+ for (int i = 0; i < 12; i++)
+ buffer[i] = DecryptByte(buffer[i]);
+}
+
+void CCipher::EncryptHeader(Byte *buffer)
+{
+ for (int i = 0; i < 12; i++)
+ buffer[i] = EncryptByte(buffer[i]);
+}
+
+}}
diff --git a/CPP/7zip/Crypto/Zip/ZipCrypto.h b/CPP/7zip/Crypto/Zip/ZipCrypto.h
new file mode 100755
index 00000000..6b4ecaaa
--- /dev/null
+++ b/CPP/7zip/Crypto/Zip/ZipCrypto.h
@@ -0,0 +1,26 @@
+// Crypto/ZipCrypto.h
+
+#ifndef __CRYPTO_ZIP_CRYPTO_H
+#define __CRYPTO_ZIP_CRYPTO_H
+
+namespace NCrypto {
+namespace NZip {
+
+const int kHeaderSize = 12;
+class CCipher
+{
+ UInt32 Keys[3];
+ void UpdateKeys(Byte b);
+ Byte DecryptByteSpec();
+public:
+ void SetPassword(const Byte *password, UInt32 passwordLength);
+ Byte DecryptByte(Byte encryptedByte);
+ Byte EncryptByte(Byte b);
+ void DecryptHeader(Byte *buffer);
+ void EncryptHeader(Byte *buffer);
+
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/makefile b/CPP/7zip/Crypto/makefile
new file mode 100755
index 00000000..61f59603
--- /dev/null
+++ b/CPP/7zip/Crypto/makefile
@@ -0,0 +1,8 @@
+DIRS = \
+ 7zAES\~ \
+ AES\~ \
+
+all: $(DIRS)
+
+$(DIRS):
+!include "../SubBuild.mak"
diff --git a/CPP/7zip/FileManager/7zFM.exe.manifest b/CPP/7zip/FileManager/7zFM.exe.manifest
new file mode 100755
index 00000000..06710e04
--- /dev/null
+++ b/CPP/7zip/FileManager/7zFM.exe.manifest
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"><assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="7-Zip.7-Zip.7zFM" type="win32"/><description>7-Zip File manager.</description><dependency> <dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/></dependentAssembly></dependency></assembly>
diff --git a/CPP/7zip/FileManager/7zipLogo.ico b/CPP/7zip/FileManager/7zipLogo.ico
new file mode 100755
index 00000000..973241c8
--- /dev/null
+++ b/CPP/7zip/FileManager/7zipLogo.ico
Binary files differ
diff --git a/CPP/7zip/FileManager/Add.bmp b/CPP/7zip/FileManager/Add.bmp
new file mode 100755
index 00000000..a8577fc7
--- /dev/null
+++ b/CPP/7zip/FileManager/Add.bmp
Binary files differ
diff --git a/CPP/7zip/FileManager/Add2.bmp b/CPP/7zip/FileManager/Add2.bmp
new file mode 100755
index 00000000..252fc253
--- /dev/null
+++ b/CPP/7zip/FileManager/Add2.bmp
Binary files differ
diff --git a/CPP/7zip/FileManager/App.cpp b/CPP/7zip/FileManager/App.cpp
new file mode 100755
index 00000000..28e2ff0f
--- /dev/null
+++ b/CPP/7zip/FileManager/App.cpp
@@ -0,0 +1,759 @@
+// App.cpp
+
+#include "StdAfx.h"
+
+#include "resource.h"
+
+#include "Common/StringConvert.h"
+#include "Windows/FileDir.h"
+#include "Windows/Error.h"
+#include "Windows/COM.h"
+#include "Windows/Thread.h"
+#include "IFolder.h"
+
+#include "App.h"
+
+#include "Resource/CopyDialog/CopyDialog.h"
+
+#include "ExtractCallback.h"
+#include "ViewSettings.h"
+#include "RegistryUtils.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NFind;
+
+extern DWORD g_ComCtl32Version;
+extern HINSTANCE g_hInstance;
+
+static LPCWSTR kTempDirPrefix = L"7zE";
+
+void CPanelCallbackImp::OnTab()
+{
+ if (g_App.NumPanels != 1)
+ _app->Panels[1 - _index].SetFocusToList();
+}
+
+void CPanelCallbackImp::SetFocusToPath(int index)
+{
+ int newPanelIndex = index;
+ if (g_App.NumPanels == 1)
+ newPanelIndex = g_App.LastFocusedPanel;
+ _app->Panels[newPanelIndex]._headerComboBox.SetFocus();
+}
+
+
+void CPanelCallbackImp::OnCopy(bool move, bool copyToSame)
+ { _app->OnCopy(move, copyToSame, _index); }
+
+void CPanelCallbackImp::OnSetSameFolder()
+ { _app->OnSetSameFolder(_index); }
+
+void CPanelCallbackImp::OnSetSubFolder()
+ { _app->OnSetSubFolder(_index); }
+
+void CPanelCallbackImp::PanelWasFocused()
+ { _app->SetFocusedPanel(_index); }
+
+void CPanelCallbackImp::DragBegin()
+ { _app->DragBegin(_index); }
+
+void CPanelCallbackImp::DragEnd()
+ { _app->DragEnd(); }
+
+void CApp::SetListSettings()
+{
+ bool showDots = ReadShowDots();
+ bool showRealFileIcons = ReadShowRealFileIcons();
+
+ DWORD extendedStyle = LVS_EX_HEADERDRAGDROP;
+ if (ReadFullRow())
+ extendedStyle |= LVS_EX_FULLROWSELECT;
+ if (ReadShowGrid())
+ extendedStyle |= LVS_EX_GRIDLINES;
+ bool mySelectionMode = ReadAlternativeSelection();
+
+ /*
+ if (ReadSingleClick())
+ {
+ extendedStyle |= LVS_EX_ONECLICKACTIVATE
+ | LVS_EX_TRACKSELECT;
+ if (ReadUnderline())
+ extendedStyle |= LVS_EX_UNDERLINEHOT;
+ }
+ */
+
+ for (int i = 0; i < kNumPanelsMax; i++)
+ {
+ CPanel &panel = Panels[i];
+ panel._mySelectMode = mySelectionMode;
+ panel._showDots = showDots;
+ panel._showRealFileIcons = showRealFileIcons;
+ panel._exStyle = extendedStyle;
+
+ DWORD style = (DWORD)panel._listView.GetStyle();
+ if (mySelectionMode)
+ style |= LVS_SINGLESEL;
+ else
+ style &= ~LVS_SINGLESEL;
+ panel._listView.SetStyle(style);
+ panel.SetExtendedStyle();
+ }
+}
+
+void CApp::SetShowSystemMenu()
+{
+ ShowSystemMenu = ReadShowSystemMenu();
+}
+
+void CApp::CreateOnePanel(int panelIndex, const UString &mainPath, bool &archiveIsOpened, bool &encrypted)
+{
+ if (PanelsCreated[panelIndex])
+ return;
+ m_PanelCallbackImp[panelIndex].Init(this, panelIndex);
+ UString path;
+ if (mainPath.IsEmpty())
+ {
+ if (!::ReadPanelPath(panelIndex, path))
+ path.Empty();
+ }
+ else
+ path = mainPath;
+ int id = 1000 + 100 * panelIndex;
+ Panels[panelIndex].Create(_window, _window,
+ id, path, &m_PanelCallbackImp[panelIndex], &AppState, archiveIsOpened, encrypted);
+ PanelsCreated[panelIndex] = true;
+}
+
+static void CreateToolbar(
+ HWND parent,
+ NWindows::NControl::CImageList &imageList,
+ NWindows::NControl::CToolBar &toolBar,
+ bool LargeButtons)
+{
+ toolBar.Attach(::CreateWindowEx(0,
+ TOOLBARCLASSNAME,
+ NULL, 0
+ | WS_VISIBLE
+ | TBSTYLE_FLAT
+ | TBSTYLE_TOOLTIPS
+ | WS_CHILD
+ | CCS_NOPARENTALIGN
+ | CCS_NORESIZE
+ | CCS_NODIVIDER
+ // | TBSTYLE_AUTOSIZE
+ // | CCS_ADJUSTABLE
+ ,0,0,0,0, parent, NULL, g_hInstance, NULL));
+
+ // TB_BUTTONSTRUCTSIZE message, which is required for
+ // backward compatibility.
+ toolBar.ButtonStructSize();
+
+ imageList.Create(
+ LargeButtons ? 48: 24,
+ LargeButtons ? 36: 24,
+ ILC_MASK, 0, 0);
+ toolBar.SetImageList(0, imageList);
+}
+
+struct CButtonInfo
+{
+ UINT commandID;
+ UINT BitmapResID;
+ UINT Bitmap2ResID;
+ UINT StringResID;
+ UINT32 LangID;
+ UString GetText()const { return LangString(StringResID, LangID); };
+};
+
+static CButtonInfo g_StandardButtons[] =
+{
+ { IDM_COPY_TO, IDB_COPY, IDB_COPY2, IDS_BUTTON_COPY, 0x03020420},
+ { IDM_MOVE_TO, IDB_MOVE, IDB_MOVE2, IDS_BUTTON_MOVE, 0x03020421},
+ { IDM_DELETE, IDB_DELETE, IDB_DELETE2, IDS_BUTTON_DELETE, 0x03020422} ,
+ { IDM_FILE_PROPERTIES, IDB_INFO, IDB_INFO2, IDS_BUTTON_INFO, 0x03020423}
+};
+
+static CButtonInfo g_ArchiveButtons[] =
+{
+ { kAddCommand, IDB_ADD, IDB_ADD2, IDS_ADD, 0x03020400},
+ { kExtractCommand, IDB_EXTRACT, IDB_EXTRACT2, IDS_EXTRACT, 0x03020401},
+ { kTestCommand , IDB_TEST, IDB_TEST2, IDS_TEST, 0x03020402}
+};
+
+bool SetButtonText(UINT32 commandID, CButtonInfo *buttons, int numButtons, UString &s)
+{
+ for (int i = 0; i < numButtons; i++)
+ {
+ const CButtonInfo &b = buttons[i];
+ if (b.commandID == commandID)
+ {
+ s = b.GetText();
+ return true;
+ }
+ }
+ return false;
+}
+
+void SetButtonText(UINT32 commandID, UString &s)
+{
+ if (SetButtonText(commandID, g_StandardButtons,
+ sizeof(g_StandardButtons) / sizeof(g_StandardButtons[0]), s))
+ return;
+ SetButtonText(commandID, g_ArchiveButtons,
+ sizeof(g_ArchiveButtons) / sizeof(g_ArchiveButtons[0]), s);
+}
+
+static void AddButton(
+ NControl::CImageList &imageList,
+ NControl::CToolBar &toolBar,
+ CButtonInfo &butInfo,
+ bool showText,
+ bool large)
+{
+ TBBUTTON but;
+ but.iBitmap = 0;
+ but.idCommand = butInfo.commandID;
+ but.fsState = TBSTATE_ENABLED;
+ but.fsStyle = BTNS_BUTTON
+ // | BTNS_AUTOSIZE
+ ;
+ but.dwData = 0;
+
+ UString s = butInfo.GetText();
+ but.iString = 0;
+ if (showText)
+ but.iString = (INT_PTR)(LPCWSTR)s;
+
+ but.iBitmap = imageList.GetImageCount();
+ HBITMAP b = ::LoadBitmap(g_hInstance,
+ large ?
+ MAKEINTRESOURCE(butInfo.BitmapResID):
+ MAKEINTRESOURCE(butInfo.Bitmap2ResID));
+ if (b != 0)
+ {
+ imageList.AddMasked(b, RGB(255, 0, 255));
+ ::DeleteObject(b);
+ }
+ #ifdef _UNICODE
+ toolBar.AddButton(1, &but);
+ #else
+ toolBar.AddButtonW(1, &but);
+ #endif
+}
+
+static void AddBand(NControl::CReBar &reBar, NControl::CToolBar &toolBar)
+{
+ SIZE size;
+ toolBar.GetMaxSize(&size);
+
+ RECT rect;
+ toolBar.GetWindowRect(&rect);
+
+ REBARBANDINFO rbBand;
+ rbBand.cbSize = sizeof(REBARBANDINFO); // Required
+ rbBand.fMask = RBBIM_STYLE
+ | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE;
+ rbBand.fStyle = RBBS_CHILDEDGE; // RBBS_NOGRIPPER;
+ rbBand.cxMinChild = size.cx; // rect.right - rect.left;
+ rbBand.cyMinChild = size.cy; // rect.bottom - rect.top;
+ rbBand.cyChild = rbBand.cyMinChild;
+ rbBand.cx = rbBand.cxMinChild;
+ rbBand.cxIdeal = rbBand.cxMinChild;
+ rbBand.hwndChild = toolBar;
+ reBar.InsertBand(-1, &rbBand);
+}
+
+void CApp::ReloadToolbars()
+{
+ if (!_rebar)
+ return;
+ HWND parent = _rebar;
+
+ while(_rebar.GetBandCount() > 0)
+ _rebar.DeleteBand(0);
+
+ _archiveToolBar.Destroy();
+ _archiveButtonsImageList.Destroy();
+
+ _standardButtonsImageList.Destroy();
+ _standardToolBar.Destroy();
+
+ if (ShowArchiveToolbar)
+ {
+ CreateToolbar(parent, _archiveButtonsImageList, _archiveToolBar, LargeButtons);
+ for (int i = 0; i < sizeof(g_ArchiveButtons) / sizeof(g_ArchiveButtons[0]); i++)
+ AddButton(_archiveButtonsImageList, _archiveToolBar, g_ArchiveButtons[i],
+ ShowButtonsLables, LargeButtons);
+ AddBand(_rebar, _archiveToolBar);
+ }
+
+ if (ShowStandardToolbar)
+ {
+ CreateToolbar(parent, _standardButtonsImageList, _standardToolBar, LargeButtons);
+ for (int i = 0; i < sizeof(g_StandardButtons) / sizeof(g_StandardButtons[0]); i++)
+ AddButton(_standardButtonsImageList, _standardToolBar, g_StandardButtons[i],
+ ShowButtonsLables, LargeButtons);
+ AddBand(_rebar, _standardToolBar);
+ }
+}
+
+void CApp::ReloadRebar(HWND hwnd)
+{
+ _rebar.Destroy();
+ if (!ShowArchiveToolbar && !ShowStandardToolbar)
+ return;
+ if (g_ComCtl32Version >= MAKELONG(71, 4))
+ {
+ INITCOMMONCONTROLSEX icex;
+ icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
+ icex.dwICC = ICC_COOL_CLASSES | ICC_BAR_CLASSES;
+ InitCommonControlsEx(&icex);
+
+ _rebar.Attach(::CreateWindowEx(WS_EX_TOOLWINDOW,
+ REBARCLASSNAME,
+ NULL,
+ WS_VISIBLE
+ | WS_BORDER
+ | WS_CHILD
+ | WS_CLIPCHILDREN
+ | WS_CLIPSIBLINGS
+ // | CCS_NODIVIDER
+ // | CCS_NOPARENTALIGN // it's bead for moveing of two bands
+ // | CCS_TOP
+ | RBS_VARHEIGHT
+ | RBS_BANDBORDERS
+ // | RBS_AUTOSIZE
+ ,0,0,0,0, hwnd, NULL, g_hInstance, NULL));
+ }
+ if (_rebar == 0)
+ return;
+ REBARINFO rbi;
+ rbi.cbSize = sizeof(REBARINFO); // Required when using this struct.
+ rbi.fMask = 0;
+ rbi.himl = (HIMAGELIST)NULL;
+ _rebar.SetBarInfo(&rbi);
+ ReloadToolbars();
+}
+
+void CApp::Create(HWND hwnd, const UString &mainPath, int xSizes[2], bool &archiveIsOpened, bool &encrypted)
+{
+ ReadToolbar();
+ ReloadRebar(hwnd);
+
+ int i;
+ for (i = 0; i < kNumPanelsMax; i++)
+ PanelsCreated[i] = false;
+
+ _window.Attach(hwnd);
+ AppState.Read();
+ SetListSettings();
+ SetShowSystemMenu();
+ if (LastFocusedPanel >= kNumPanelsMax)
+ LastFocusedPanel = 0;
+
+ CListMode listMode;
+ ReadListMode(listMode);
+ for (i = 0; i < kNumPanelsMax; i++)
+ {
+ Panels[i]._ListViewMode = listMode.Panels[i];
+ Panels[i]._xSize = xSizes[i];
+ }
+ for (i = 0; i < kNumPanelsMax; i++)
+ if (NumPanels > 1 || i == LastFocusedPanel)
+ {
+ if (NumPanels == 1)
+ Panels[i]._xSize = xSizes[0] + xSizes[1];
+ bool archiveIsOpened2 = false;
+ bool encrypted2 = false;
+ bool mainPanel = (i == LastFocusedPanel);
+ CreateOnePanel(i, mainPanel ? mainPath : L"", archiveIsOpened2, encrypted2);
+ if (mainPanel)
+ {
+ archiveIsOpened = archiveIsOpened2;
+ encrypted = encrypted2;
+ }
+ }
+ SetFocusedPanel(LastFocusedPanel);
+ Panels[LastFocusedPanel].SetFocusToList();
+}
+
+extern void MoveSubWindows(HWND hWnd);
+
+void CApp::SwitchOnOffOnePanel()
+{
+ if (NumPanels == 1)
+ {
+ NumPanels++;
+ bool archiveIsOpened, encrypted;
+ CreateOnePanel(1 - LastFocusedPanel, UString(), archiveIsOpened, encrypted);
+ Panels[1 - LastFocusedPanel].Enable(true);
+ Panels[1 - LastFocusedPanel].Show(SW_SHOWNORMAL);
+ }
+ else
+ {
+ NumPanels--;
+ Panels[1 - LastFocusedPanel].Enable(false);
+ Panels[1 - LastFocusedPanel].Show(SW_HIDE);
+ }
+ MoveSubWindows(_window);
+}
+
+void CApp::Save()
+{
+ AppState.Save();
+ CListMode listMode;
+ for (int i = 0; i < kNumPanelsMax; i++)
+ {
+ const CPanel &panel = Panels[i];
+ UString path;
+ if (panel._parentFolders.IsEmpty())
+ path = panel._currentFolderPrefix;
+ else
+ path = GetFolderPath(panel._parentFolders[0].ParentFolder);
+ SavePanelPath(i, path);
+ listMode.Panels[i] = panel.GetListViewMode();
+ }
+ SaveListMode(listMode);
+}
+
+void CApp::Release()
+{
+ // It's for unloading COM dll's: don't change it.
+ for (int i = 0; i < kNumPanelsMax; i++)
+ Panels[i].Release();
+}
+
+static bool IsThereFolderOfPath(const UString &path)
+{
+ CFileInfoW fileInfo;
+ if (!FindFile(path, fileInfo))
+ return false;
+ return fileInfo.IsDirectory();
+}
+
+// reduces path to part that exists on disk
+static void ReducePathToRealFileSystemPath(UString &path)
+{
+ while(!path.IsEmpty())
+ {
+ if (IsThereFolderOfPath(path))
+ {
+ NName::NormalizeDirPathPrefix(path);
+ break;
+ }
+ int pos = path.ReverseFind('\\');
+ if (pos < 0)
+ path.Empty();
+ else
+ {
+ path = path.Left(pos + 1);
+ if (path.Length() == 3 && path[1] == L':')
+ break;
+ path = path.Left(pos);
+ }
+ }
+}
+
+// return true for dir\, if dir exist
+static bool CheckFolderPath(const UString &path)
+{
+ UString pathReduced = path;
+ ReducePathToRealFileSystemPath(pathReduced);
+ return (pathReduced == path);
+}
+
+static bool IsPathAbsolute(const UString &path)
+{
+ if ((path.Length() >= 1 && path[0] == L'\\') ||
+ (path.Length() >= 3 && path[1] == L':' && path[2] == L'\\'))
+ return true;
+ return false;
+}
+
+void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
+{
+ int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex);
+ CPanel &srcPanel = Panels[srcPanelIndex];
+ CPanel &destPanel = Panels[destPanelIndex];
+
+ CPanel::CDisableTimerProcessing disableTimerProcessing1(destPanel);
+ CPanel::CDisableTimerProcessing disableTimerProcessing2(srcPanel);
+
+ if (!srcPanel.DoesItSupportOperations())
+ {
+ srcPanel.MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
+ return;
+ }
+
+ CRecordVector<UInt32> indices;
+ UString destPath;
+ bool useDestPanel = false;
+
+ {
+ if (copyToSame)
+ {
+ int focusedItem = srcPanel._listView.GetFocusedItem();
+ if (focusedItem < 0)
+ return;
+ int realIndex = srcPanel.GetRealItemIndex(focusedItem);
+ if (realIndex == kParentIndex)
+ return;
+ indices.Add(realIndex);
+ destPath = srcPanel.GetItemName(realIndex);
+ }
+ else
+ {
+ srcPanel.GetOperatedItemIndices(indices);
+ if (indices.Size() == 0)
+ return;
+ destPath = destPanel._currentFolderPrefix;
+ if (NumPanels == 1)
+ ReducePathToRealFileSystemPath(destPath);
+ }
+
+ CCopyDialog copyDialog;
+ UStringVector copyFolders;
+ ReadCopyHistory(copyFolders);
+
+ copyDialog.Strings = copyFolders;
+ copyDialog.Value = destPath;
+
+ copyDialog.Title = move ?
+ LangString(IDS_MOVE, 0x03020202):
+ LangString(IDS_COPY, 0x03020201);
+ copyDialog.Static = move ?
+ LangString(IDS_MOVE_TO, 0x03020204):
+ LangString(IDS_COPY_TO, 0x03020203);
+
+ if (copyDialog.Create(srcPanel.GetParent()) == IDCANCEL)
+ return;
+
+ destPath = copyDialog.Value;
+
+ if (!IsPathAbsolute(destPath))
+ {
+ if (!srcPanel.IsFSFolder())
+ {
+ srcPanel.MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
+ return;
+ }
+ destPath = srcPanel._currentFolderPrefix + destPath;
+ }
+
+ if (indices.Size() > 1 || (destPath.Length() > 0 && destPath.ReverseFind('\\') == destPath.Length() - 1) ||
+ IsThereFolderOfPath(destPath))
+ {
+ NDirectory::CreateComplexDirectory(destPath);
+ NName::NormalizeDirPathPrefix(destPath);
+ if (!CheckFolderPath(destPath))
+ {
+ if (NumPanels < 2 || destPath != destPanel._currentFolderPrefix || !destPanel.DoesItSupportOperations())
+ {
+ srcPanel.MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
+ return;
+ }
+ useDestPanel = true;
+ }
+ }
+ else
+ {
+ int pos = destPath.ReverseFind('\\');
+ if (pos >= 0)
+ {
+ UString prefix = destPath.Left(pos + 1);
+ NDirectory::CreateComplexDirectory(prefix);
+ if (!CheckFolderPath(prefix))
+ {
+ srcPanel.MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
+ return;
+ }
+ }
+ }
+
+ AddUniqueStringToHeadOfList(copyFolders, destPath);
+ while (copyFolders.Size() > 20)
+ copyFolders.DeleteBack();
+ SaveCopyHistory(copyFolders);
+ }
+
+ bool useSrcPanel = (!useDestPanel || !srcPanel.IsFSFolder() || destPanel.IsFSFolder());
+ bool useTemp = useSrcPanel && useDestPanel;
+ NFile::NDirectory::CTempDirectoryW tempDirectory;
+ UString tempDirPrefix;
+ if (useTemp)
+ {
+ tempDirectory.Create(kTempDirPrefix);
+ tempDirPrefix = tempDirectory.GetPath();
+ NFile::NName::NormalizeDirPathPrefix(tempDirPrefix);
+ }
+
+ CSelectedState srcSelState;
+ CSelectedState destSelState;
+ srcPanel.SaveSelectedState(srcSelState);
+ destPanel.SaveSelectedState(destSelState);
+
+ HRESULT result;
+ if (useSrcPanel)
+ {
+ UString folder = useTemp ? tempDirPrefix : destPath;
+ result = srcPanel.CopyTo(indices, folder, move, true, 0);
+ if (result != S_OK)
+ {
+ disableTimerProcessing1.Restore();
+ disableTimerProcessing2.Restore();
+ // For Password:
+ srcPanel.SetFocusToList();
+ if (result != E_ABORT)
+ srcPanel.MessageBoxError(result, L"Error");
+ return;
+ }
+ }
+
+ if (useDestPanel)
+ {
+ UStringVector filePaths;
+ UString folderPrefix;
+ if (useTemp)
+ folderPrefix = tempDirPrefix;
+ else
+ folderPrefix = srcPanel._currentFolderPrefix;
+ filePaths.Reserve(indices.Size());
+ for(int i = 0; i < indices.Size(); i++)
+ filePaths.Add(srcPanel.GetItemRelPath(indices[i]));
+
+ result = destPanel.CopyFrom(folderPrefix, filePaths, true, 0);
+
+ if (result != S_OK)
+ {
+ disableTimerProcessing1.Restore();
+ disableTimerProcessing2.Restore();
+ // For Password:
+ srcPanel.SetFocusToList();
+ if (result != E_ABORT)
+ srcPanel.MessageBoxError(result, L"Error");
+ return;
+ }
+ }
+
+ if (copyToSame || move)
+ {
+ srcPanel.RefreshListCtrl(srcSelState);
+ }
+ if (!copyToSame)
+ {
+ destPanel.RefreshListCtrl(destSelState);
+ srcPanel.KillSelection();
+ }
+ disableTimerProcessing1.Restore();
+ disableTimerProcessing2.Restore();
+ srcPanel.SetFocusToList();
+}
+
+void CApp::OnSetSameFolder(int srcPanelIndex)
+{
+ if (NumPanels <= 1)
+ return;
+ const CPanel &srcPanel = Panels[srcPanelIndex];
+ CPanel &destPanel = Panels[1 - srcPanelIndex];
+ destPanel.BindToPathAndRefresh(srcPanel._currentFolderPrefix);
+}
+
+void CApp::OnSetSubFolder(int srcPanelIndex)
+{
+ if (NumPanels <= 1)
+ return;
+ const CPanel &srcPanel = Panels[srcPanelIndex];
+ CPanel &destPanel = Panels[1 - srcPanelIndex];
+
+ int focusedItem = srcPanel._listView.GetFocusedItem();
+ if (focusedItem < 0)
+ return;
+ int realIndex = srcPanel.GetRealItemIndex(focusedItem);
+ if (!srcPanel.IsItemFolder(realIndex))
+ return;
+
+
+ /*
+ UString string = srcPanel._currentFolderPrefix +
+ srcPanel.GetItemName(realIndex) + L'\\';
+ destPanel.BindToFolder(string);
+ */
+ CMyComPtr<IFolderFolder> newFolder;
+ if (realIndex == kParentIndex)
+ {
+ if (srcPanel._folder->BindToParentFolder(&newFolder) != S_OK)
+ return;
+ }
+ else
+ {
+ if (srcPanel._folder->BindToFolder(realIndex, &newFolder) != S_OK)
+ return;
+ }
+ destPanel.CloseOpenFolders();
+ destPanel._folder = newFolder;
+ destPanel.RefreshListCtrl();
+}
+
+/*
+int CApp::GetFocusedPanelIndex() const
+{
+ return LastFocusedPanel;
+ HWND hwnd = ::GetFocus();
+ for (;;)
+ {
+ if (hwnd == 0)
+ return 0;
+ for (int i = 0; i < kNumPanelsMax; i++)
+ {
+ if (PanelsCreated[i] &&
+ ((HWND)Panels[i] == hwnd || Panels[i]._listView == hwnd))
+ return i;
+ }
+ hwnd = GetParent(hwnd);
+ }
+}
+ */
+
+static UString g_ToolTipBuffer;
+static CSysString g_ToolTipBufferSys;
+
+void CApp::OnNotify(int /* ctrlID */, LPNMHDR pnmh)
+{
+ if (pnmh->hwndFrom == _rebar)
+ {
+ switch(pnmh->code)
+ {
+ case RBN_HEIGHTCHANGE:
+ {
+ MoveSubWindows(g_HWND);
+ return;
+ }
+ }
+ return ;
+ }
+ else
+ {
+ if (pnmh->code == TTN_GETDISPINFO)
+ {
+ LPNMTTDISPINFO info = (LPNMTTDISPINFO)pnmh;
+ info->hinst = 0;
+ g_ToolTipBuffer.Empty();
+ SetButtonText((UINT32)info->hdr.idFrom, g_ToolTipBuffer);
+ g_ToolTipBufferSys = GetSystemString(g_ToolTipBuffer);
+ info->lpszText = (LPTSTR)(LPCTSTR)g_ToolTipBufferSys;
+ return;
+ }
+ #ifndef _UNICODE
+ if (pnmh->code == TTN_GETDISPINFOW)
+ {
+ LPNMTTDISPINFOW info = (LPNMTTDISPINFOW)pnmh;
+ info->hinst = 0;
+ g_ToolTipBuffer.Empty();
+ SetButtonText((UINT32)info->hdr.idFrom, g_ToolTipBuffer);
+ info->lpszText = (LPWSTR)(LPCWSTR)g_ToolTipBuffer;
+ return;
+ }
+ #endif
+ }
+}
diff --git a/CPP/7zip/FileManager/App.h b/CPP/7zip/FileManager/App.h
new file mode 100755
index 00000000..faa40afe
--- /dev/null
+++ b/CPP/7zip/FileManager/App.h
@@ -0,0 +1,332 @@
+// App.h
+
+#ifndef __APP_H
+#define __APP_H
+
+#include "Panel.h"
+#include "AppState.h"
+#include "Windows/Control/ImageList.h"
+
+class CApp;
+
+extern CApp g_App;
+extern HWND g_HWND;
+
+const int kNumPanelsMax = 2;
+
+extern void MoveSubWindows(HWND hWnd);
+
+enum
+{
+ kAddCommand = kToolbarStartID,
+ kExtractCommand,
+ kTestCommand
+};
+
+class CPanelCallbackImp: public CPanelCallback
+{
+ CApp *_app;
+ int _index;
+public:
+ void Init(CApp *app, int index)
+ {
+ _app = app;
+ _index = index;
+ }
+ virtual void OnTab();
+ virtual void SetFocusToPath(int index);
+ virtual void OnCopy(bool move, bool copyToSame);
+ virtual void OnSetSameFolder();
+ virtual void OnSetSubFolder();
+ virtual void PanelWasFocused();
+ virtual void DragBegin();
+ virtual void DragEnd();
+};
+
+class CApp;
+
+class CDropTarget:
+ public IDropTarget,
+ public CMyUnknownImp
+{
+ CMyComPtr<IDataObject> m_DataObject;
+ UStringVector m_SourcePaths;
+ int m_SelectionIndex;
+ bool m_DropIsAllowed; // = true, if data contain fillist
+ bool m_PanelDropIsAllowed; // = false, if current target_panel is source_panel.
+ // check it only if m_DropIsAllowed == true
+ int m_SubFolderIndex;
+ UString m_SubFolderName;
+
+ CPanel *m_Panel;
+ bool m_IsAppTarget; // true, if we want to drop to app window (not to panel).
+
+ bool m_SetPathIsOK;
+
+ bool IsItSameDrive() const;
+
+ void QueryGetData(IDataObject *dataObject);
+ bool IsFsFolderPath() const;
+ DWORD GetEffect(DWORD keyState, POINTL pt, DWORD allowedEffect);
+ void RemoveSelection();
+ void PositionCursor(POINTL ptl);
+ UString GetTargetPath() const;
+ bool SetPath(bool enablePath) const;
+ bool SetPath();
+
+public:
+ MY_UNKNOWN_IMP1_MT(IDropTarget)
+ STDMETHOD(DragEnter)(IDataObject * dataObject, DWORD keyState,
+ POINTL pt, DWORD *effect);
+ STDMETHOD(DragOver)(DWORD keyState, POINTL pt, DWORD * effect);
+ STDMETHOD(DragLeave)();
+ STDMETHOD(Drop)(IDataObject * dataObject, DWORD keyState,
+ POINTL pt, DWORD *effect);
+
+ CDropTarget():
+ TargetPanelIndex(-1),
+ SrcPanelIndex(-1),
+ m_IsAppTarget(false),
+ m_Panel(0),
+ App(0),
+ m_PanelDropIsAllowed(false),
+ m_DropIsAllowed(false),
+ m_SelectionIndex(-1),
+ m_SubFolderIndex(-1),
+ m_SetPathIsOK(false) {}
+
+ CApp *App;
+ int SrcPanelIndex; // index of D&D source_panel
+ int TargetPanelIndex; // what panel to use as target_panel of Application
+};
+
+class CApp
+{
+public:
+ NWindows::CWindow _window;
+ bool ShowSystemMenu;
+ int NumPanels;
+ int LastFocusedPanel;
+
+ bool ShowStandardToolbar;
+ bool ShowArchiveToolbar;
+ bool ShowButtonsLables;
+ bool LargeButtons;
+
+ CAppState AppState;
+ CPanelCallbackImp m_PanelCallbackImp[kNumPanelsMax];
+ CPanel Panels[kNumPanelsMax];
+ bool PanelsCreated[kNumPanelsMax];
+
+ NWindows::NControl::CImageList _archiveButtonsImageList;
+ NWindows::NControl::CImageList _standardButtonsImageList;
+
+ NWindows::NControl::CReBar _rebar;
+ NWindows::NControl::CToolBar _archiveToolBar;
+ NWindows::NControl::CToolBar _standardToolBar;
+
+ CDropTarget *_dropTargetSpec;
+ CMyComPtr<IDropTarget> _dropTarget;
+
+ void CreateDragTarget()
+ {
+ _dropTargetSpec = new CDropTarget();
+ _dropTarget = _dropTargetSpec;
+ _dropTargetSpec->App = (this);
+ }
+
+ void SetFocusedPanel(int index)
+ {
+ LastFocusedPanel = index;
+ _dropTargetSpec->TargetPanelIndex = LastFocusedPanel;
+ }
+
+ void DragBegin(int panelIndex)
+ {
+ _dropTargetSpec->TargetPanelIndex = (NumPanels > 1) ? 1 - panelIndex : panelIndex;
+ _dropTargetSpec->SrcPanelIndex = panelIndex;
+ }
+
+ void DragEnd()
+ {
+ _dropTargetSpec->TargetPanelIndex = LastFocusedPanel;
+ _dropTargetSpec->SrcPanelIndex = -1;
+ }
+
+
+ void OnCopy(bool move, bool copyToSame, int srcPanelIndex);
+ void OnSetSameFolder(int srcPanelIndex);
+ void OnSetSubFolder(int srcPanelIndex);
+
+ void CreateOnePanel(int panelIndex, const UString &mainPath, bool &archiveIsOpened, bool &encrypted);
+ void Create(HWND hwnd, const UString &mainPath, int xSizes[2], bool &archiveIsOpened, bool &encrypted);
+ void Read();
+ void Save();
+ void Release();
+
+
+ /*
+ void SetFocus(int panelIndex)
+ { Panels[panelIndex].SetFocusToList(); }
+ */
+ void SetFocusToLastItem()
+ { Panels[LastFocusedPanel].SetFocusToLastRememberedItem(); }
+
+ int GetFocusedPanelIndex() const { return LastFocusedPanel; }
+
+ bool IsPanelVisible(int index) const { return (NumPanels > 1 || index == LastFocusedPanel); }
+
+ /*
+ void SetCurrentIndex()
+ { CurrentPanel = GetFocusedPanelIndex(); }
+ */
+
+ CApp(): NumPanels(2), LastFocusedPanel(0) {}
+ CPanel &GetFocusedPanel()
+ { return Panels[GetFocusedPanelIndex()]; }
+
+ // File Menu
+ void OpenItem()
+ { GetFocusedPanel().OpenSelectedItems(true); }
+ void OpenItemInside()
+ { GetFocusedPanel().OpenFocusedItemAsInternal(); }
+ void OpenItemOutside()
+ { GetFocusedPanel().OpenSelectedItems(false); }
+ void EditItem()
+ { GetFocusedPanel().EditItem(); }
+ void Rename()
+ { GetFocusedPanel().RenameFile(); }
+ void CopyTo()
+ { OnCopy(false, false, GetFocusedPanelIndex()); }
+ void MoveTo()
+ { OnCopy(true, false, GetFocusedPanelIndex()); }
+ void Delete(bool toRecycleBin)
+ { GetFocusedPanel().DeleteItems(toRecycleBin); }
+ void CalculateCrc();
+ void Split();
+ void Combine();
+ void Properties()
+ { GetFocusedPanel().Properties(); }
+ void Comment()
+ { GetFocusedPanel().ChangeComment(); }
+
+ void CreateFolder()
+ { GetFocusedPanel().CreateFolder(); }
+ void CreateFile()
+ { GetFocusedPanel().CreateFile(); }
+
+ // Edit
+ void EditCopy()
+ { GetFocusedPanel().EditCopy(); }
+ void EditPaste()
+ { GetFocusedPanel().EditPaste(); }
+
+ void SelectAll(bool selectMode)
+ { GetFocusedPanel().SelectAll(selectMode); }
+ void InvertSelection()
+ { GetFocusedPanel().InvertSelection(); }
+ void SelectSpec(bool selectMode)
+ { GetFocusedPanel().SelectSpec(selectMode); }
+ void SelectByType(bool selectMode)
+ { GetFocusedPanel().SelectByType(selectMode); }
+
+ void RefreshStatusBar()
+ { GetFocusedPanel().RefreshStatusBar(); }
+
+ void SetListViewMode(UINT32 index)
+ { GetFocusedPanel().SetListViewMode(index); }
+ UINT32 GetListViewMode()
+ { return GetFocusedPanel().GetListViewMode(); }
+
+ void SortItemsWithPropID(PROPID propID)
+ { GetFocusedPanel().SortItemsWithPropID(propID); }
+
+ void OpenRootFolder()
+ { GetFocusedPanel().OpenDrivesFolder(); }
+ void OpenParentFolder()
+ { GetFocusedPanel().OpenParentFolder(); }
+ void FoldersHistory()
+ { GetFocusedPanel().FoldersHistory(); }
+ void RefreshView()
+ { GetFocusedPanel().OnReload(); }
+ void RefreshAllPanels()
+ {
+ for (int i = 0; i < NumPanels; i++)
+ {
+ int index = i;
+ if (NumPanels == 1)
+ index = LastFocusedPanel;
+ Panels[index].OnReload();
+ }
+ }
+ void SetListSettings();
+ void SetShowSystemMenu();
+ void SwitchOnOffOnePanel();
+ bool GetFlatMode() { return Panels[LastFocusedPanel].GetFlatMode(); }
+ void ChangeFlatMode() { Panels[LastFocusedPanel].ChangeFlatMode(); }
+
+ void OpenBookmark(int index)
+ { GetFocusedPanel().OpenBookmark(index); }
+ void SetBookmark(int index)
+ { GetFocusedPanel().SetBookmark(index); }
+
+ void ReloadRebar(HWND hwnd);
+ void ReloadToolbars();
+ void ReadToolbar()
+ {
+ UINT32 mask = ReadToolbarsMask();
+ ShowButtonsLables = ((mask & 1) != 0);
+ LargeButtons = ((mask & 2) != 0);
+ ShowStandardToolbar = ((mask & 4) != 0);
+ ShowArchiveToolbar = ((mask & 8) != 0);
+ }
+ void SaveToolbar()
+ {
+ UINT32 mask = 0;
+ if (ShowButtonsLables) mask |= 1;
+ if (LargeButtons) mask |= 2;
+ if (ShowStandardToolbar) mask |= 4;
+ if (ShowArchiveToolbar) mask |= 8;
+ SaveToolbarsMask(mask);
+ }
+ void SwitchStandardToolbar()
+ {
+ ShowStandardToolbar = !ShowStandardToolbar;
+ SaveToolbar();
+ ReloadRebar(g_HWND);
+ MoveSubWindows(_window);
+ }
+ void SwitchArchiveToolbar()
+ {
+ ShowArchiveToolbar = !ShowArchiveToolbar;
+ SaveToolbar();
+ ReloadRebar(g_HWND);
+ MoveSubWindows(_window);
+ }
+ void SwitchButtonsLables()
+ {
+ ShowButtonsLables = !ShowButtonsLables;
+ SaveToolbar();
+ ReloadRebar(g_HWND);
+ MoveSubWindows(_window);
+ }
+ void SwitchLargeButtons()
+ {
+ LargeButtons = !LargeButtons;
+ SaveToolbar();
+ ReloadRebar(g_HWND);
+ MoveSubWindows(_window);
+ }
+
+
+ void AddToArchive()
+ { GetFocusedPanel().AddToArchive(); }
+ void ExtractArchives()
+ { GetFocusedPanel().ExtractArchives(); }
+ void TestArchives()
+ { GetFocusedPanel().TestArchives(); }
+
+ void OnNotify(int ctrlID, LPNMHDR pnmh);
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/AppState.h b/CPP/7zip/FileManager/AppState.h
new file mode 100755
index 00000000..318c0258
--- /dev/null
+++ b/CPP/7zip/FileManager/AppState.h
@@ -0,0 +1,114 @@
+// AppState.h
+
+#ifndef __APPSTATE_H
+#define __APPSTATE_H
+
+#include "Windows/Synchronization.h"
+
+void inline AddUniqueStringToHead(UStringVector &list,
+ const UString &string)
+{
+ for(int i = 0; i < list.Size();)
+ if (string.CompareNoCase(list[i]) == 0)
+ list.Delete(i);
+ else
+ i++;
+ list.Insert(0, string);
+}
+
+class CFastFolders
+{
+ NWindows::NSynchronization::CCriticalSection _criticalSection;
+public:
+ UStringVector Strings;
+ void SetString(int index, const UString &string)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ while(Strings.Size() <= index)
+ Strings.Add(UString());
+ Strings[index] = string;
+ }
+ UString GetString(int index)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ if (index >= Strings.Size())
+ return UString();
+ return Strings[index];
+ }
+ void Save()
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ SaveFastFolders(Strings);
+ }
+ void Read()
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ ReadFastFolders(Strings);
+ }
+};
+
+class CFolderHistory
+{
+ NWindows::NSynchronization::CCriticalSection _criticalSection;
+ UStringVector Strings;
+public:
+
+ void GetList(UStringVector &foldersHistory)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ foldersHistory = Strings;
+ }
+
+ void Normalize()
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ const int kMaxSize = 100;
+ if (Strings.Size() > kMaxSize)
+ Strings.Delete(kMaxSize, Strings.Size() - kMaxSize);
+ }
+
+ void AddString(const UString &string)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ AddUniqueStringToHead(Strings, string);
+ Normalize();
+ }
+
+ void RemoveAll()
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ Strings.Clear();
+ }
+
+ void Save()
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ SaveFolderHistory(Strings);
+ }
+
+ void Read()
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ ReadFolderHistory(Strings);
+ Normalize();
+ }
+};
+
+struct CAppState
+{
+ CFastFolders FastFolders;
+ CFolderHistory FolderHistory;
+ void Save()
+ {
+ FastFolders.Save();
+ FolderHistory.Save();
+ }
+ void Read()
+ {
+ FastFolders.Read();
+ FolderHistory.Read();
+ }
+};
+
+
+#endif \ No newline at end of file
diff --git a/CPP/7zip/FileManager/ClassDefs.cpp b/CPP/7zip/FileManager/ClassDefs.cpp
new file mode 100755
index 00000000..ded9c8d8
--- /dev/null
+++ b/CPP/7zip/FileManager/ClassDefs.cpp
@@ -0,0 +1,15 @@
+// ClassDefs.cpp
+
+#include "StdAfx.h"
+
+#include <initguid.h>
+
+#include "IFolder.h"
+#include "../IPassword.h"
+#include "PluginInterface.h"
+#include "ExtractCallback.h"
+#include "../ICoder.h"
+
+// {23170F69-40C1-278A-1000-000100020000}
+DEFINE_GUID(CLSID_CZipContextMenu,
+0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00);
diff --git a/CPP/7zip/FileManager/Copy.bmp b/CPP/7zip/FileManager/Copy.bmp
new file mode 100755
index 00000000..0f28a324
--- /dev/null
+++ b/CPP/7zip/FileManager/Copy.bmp
Binary files differ
diff --git a/CPP/7zip/FileManager/Copy2.bmp b/CPP/7zip/FileManager/Copy2.bmp
new file mode 100755
index 00000000..ba88ded0
--- /dev/null
+++ b/CPP/7zip/FileManager/Copy2.bmp
Binary files differ
diff --git a/CPP/7zip/FileManager/Delete.bmp b/CPP/7zip/FileManager/Delete.bmp
new file mode 100755
index 00000000..d1004d82
--- /dev/null
+++ b/CPP/7zip/FileManager/Delete.bmp
Binary files differ
diff --git a/CPP/7zip/FileManager/Delete2.bmp b/CPP/7zip/FileManager/Delete2.bmp
new file mode 100755
index 00000000..60e08c6a
--- /dev/null
+++ b/CPP/7zip/FileManager/Delete2.bmp
Binary files differ
diff --git a/CPP/7zip/FileManager/EnumFormatEtc.cpp b/CPP/7zip/FileManager/EnumFormatEtc.cpp
new file mode 100755
index 00000000..ef9463fb
--- /dev/null
+++ b/CPP/7zip/FileManager/EnumFormatEtc.cpp
@@ -0,0 +1,108 @@
+// EnumFormatEtc.cpp
+
+#include "StdAfx.h"
+
+#include "EnumFormatEtc.h"
+#include "MyCom2.h"
+
+class CEnumFormatEtc :
+public IEnumFORMATETC,
+public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP1_MT(IEnumFORMATETC)
+
+ STDMETHOD(Next)(ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched);
+ STDMETHOD(Skip)(ULONG celt);
+ STDMETHOD(Reset)(void);
+ STDMETHOD(Clone)(IEnumFORMATETC **ppEnumFormatEtc);
+
+ CEnumFormatEtc(const FORMATETC *pFormatEtc, ULONG numFormats);
+ ~CEnumFormatEtc();
+
+private:
+ LONG m_RefCount;
+ ULONG m_NumFormats;
+ FORMATETC *m_Formats;
+ ULONG m_Index;
+};
+
+static void DeepCopyFormatEtc(FORMATETC *dest, const FORMATETC *src)
+{
+ *dest = *src;
+ if(src->ptd)
+ {
+ dest->ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(sizeof(DVTARGETDEVICE));
+ *(dest->ptd) = *(src->ptd);
+ }
+}
+
+CEnumFormatEtc::CEnumFormatEtc(const FORMATETC *pFormatEtc, ULONG numFormats)
+{
+ m_RefCount = 1;
+ m_Index = 0;
+ m_NumFormats = 0;
+ m_Formats = new FORMATETC[numFormats];
+ if(m_Formats)
+ {
+ m_NumFormats = numFormats;
+ for(ULONG i = 0; i < numFormats; i++)
+ DeepCopyFormatEtc(&m_Formats[i], &pFormatEtc[i]);
+ }
+}
+
+CEnumFormatEtc::~CEnumFormatEtc()
+{
+ if(m_Formats)
+ {
+ for(ULONG i = 0; i < m_NumFormats; i++)
+ if(m_Formats[i].ptd)
+ CoTaskMemFree(m_Formats[i].ptd);
+ delete[]m_Formats;
+ }
+}
+
+STDMETHODIMP CEnumFormatEtc::Next(ULONG celt, FORMATETC *pFormatEtc, ULONG *pceltFetched)
+{
+ ULONG copied = 0;
+ if(celt == 0 || pFormatEtc == 0)
+ return E_INVALIDARG;
+ while(m_Index < m_NumFormats && copied < celt)
+ {
+ DeepCopyFormatEtc(&pFormatEtc[copied], &m_Formats[m_Index]);
+ copied++;
+ m_Index++;
+ }
+ if(pceltFetched != 0)
+ *pceltFetched = copied;
+ return (copied == celt) ? S_OK : S_FALSE;
+}
+
+STDMETHODIMP CEnumFormatEtc::Skip(ULONG celt)
+{
+ m_Index += celt;
+ return (m_Index <= m_NumFormats) ? S_OK : S_FALSE;
+}
+
+STDMETHODIMP CEnumFormatEtc::Reset(void)
+{
+ m_Index = 0;
+ return S_OK;
+}
+
+STDMETHODIMP CEnumFormatEtc::Clone(IEnumFORMATETC ** ppEnumFormatEtc)
+{
+ HRESULT hResult = CreateEnumFormatEtc(m_NumFormats, m_Formats, ppEnumFormatEtc);
+ if(hResult == S_OK)
+ ((CEnumFormatEtc *)*ppEnumFormatEtc)->m_Index = m_Index;
+ return hResult;
+}
+
+// replacement for SHCreateStdEnumFmtEtc
+HRESULT CreateEnumFormatEtc(UINT numFormats, const FORMATETC *formats, IEnumFORMATETC **enumFormat)
+{
+ if(numFormats == 0 || formats == 0 || enumFormat == 0)
+ return E_INVALIDARG;
+ *enumFormat = new CEnumFormatEtc(formats, numFormats);
+ return (*enumFormat) ? S_OK : E_OUTOFMEMORY;
+}
diff --git a/CPP/7zip/FileManager/EnumFormatEtc.h b/CPP/7zip/FileManager/EnumFormatEtc.h
new file mode 100755
index 00000000..6c476f1a
--- /dev/null
+++ b/CPP/7zip/FileManager/EnumFormatEtc.h
@@ -0,0 +1,10 @@
+// EnumFormatEtc.h
+
+#ifndef __ENUMFORMATETC_H
+#define __ENUMFORMATETC_H
+
+#include <windows.h>
+
+HRESULT CreateEnumFormatEtc(UINT numFormats, const FORMATETC *formats, IEnumFORMATETC **enumFormat);
+
+#endif
diff --git a/CPP/7zip/FileManager/Extract.bmp b/CPP/7zip/FileManager/Extract.bmp
new file mode 100755
index 00000000..0aeba923
--- /dev/null
+++ b/CPP/7zip/FileManager/Extract.bmp
Binary files differ
diff --git a/CPP/7zip/FileManager/Extract2.bmp b/CPP/7zip/FileManager/Extract2.bmp
new file mode 100755
index 00000000..a7e57753
--- /dev/null
+++ b/CPP/7zip/FileManager/Extract2.bmp
Binary files differ
diff --git a/CPP/7zip/FileManager/ExtractCallback.cpp b/CPP/7zip/FileManager/ExtractCallback.cpp
new file mode 100755
index 00000000..d6ea8f8f
--- /dev/null
+++ b/CPP/7zip/FileManager/ExtractCallback.cpp
@@ -0,0 +1,382 @@
+// ExtractCallback.h
+
+#include "StdAfx.h"
+
+#include "ExtractCallback.h"
+
+#include "Windows/FileFind.h"
+#include "Windows/FileDir.h"
+#include "Windows/Error.h"
+
+#include "Resource/OverwriteDialog/OverwriteDialog.h"
+#ifndef _NO_CRYPTO
+#include "Resource/PasswordDialog/PasswordDialog.h"
+#endif
+#include "Resource/MessagesDialog/MessagesDialog.h"
+#include "../UI/Resource/Extract/resource.h"
+#include "../UI/GUI/resource.h"
+
+#include "Common/Wildcard.h"
+#include "Common/StringConvert.h"
+
+#include "FormatUtils.h"
+
+#include "../Common/FilePathAutoRename.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NFind;
+
+CExtractCallbackImp::~CExtractCallbackImp()
+{
+ if (ShowMessages && !Messages.IsEmpty())
+ {
+ CMessagesDialog messagesDialog;
+ messagesDialog.Messages = &Messages;
+ messagesDialog.Create(ParentWindow);
+ }
+}
+
+void CExtractCallbackImp::Init()
+{
+ Messages.Clear();
+ NumArchiveErrors = 0;
+}
+
+void CExtractCallbackImp::AddErrorMessage(LPCWSTR message)
+{
+ Messages.Add(message);
+}
+
+STDMETHODIMP CExtractCallbackImp::SetTotal(UInt64 total)
+{
+ ProgressDialog.ProgressSynch.SetProgress(total, 0);
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::SetCompleted(const UInt64 *completeValue)
+{
+ for (;;)
+ {
+ if(ProgressDialog.ProgressSynch.GetStopped())
+ return E_ABORT;
+ if(!ProgressDialog.ProgressSynch.GetPaused())
+ break;
+ ::Sleep(100);
+ }
+ if (completeValue != NULL)
+ ProgressDialog.ProgressSynch.SetPos(*completeValue);
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::AskOverwrite(
+ const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize,
+ const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize,
+ Int32 *answer)
+{
+ COverwriteDialog dialog;
+
+ dialog.OldFileInfo.Time = *existTime;
+ dialog.OldFileInfo.SizeIsDefined = (existSize != NULL);
+ if (dialog.OldFileInfo.SizeIsDefined)
+ dialog.OldFileInfo.Size = *existSize;
+ dialog.OldFileInfo.Name = existName;
+
+ if (newTime == 0)
+ dialog.NewFileInfo.TimeIsDefined = false;
+ else
+ {
+ dialog.NewFileInfo.TimeIsDefined = true;
+ dialog.NewFileInfo.Time = *newTime;
+ }
+
+ dialog.NewFileInfo.SizeIsDefined = (newSize != NULL);
+ if (dialog.NewFileInfo.SizeIsDefined)
+ dialog.NewFileInfo.Size = *newSize;
+ dialog.NewFileInfo.Name = newName;
+
+ /*
+ NOverwriteDialog::NResult::EEnum writeAnswer =
+ NOverwriteDialog::Execute(oldFileInfo, newFileInfo);
+ */
+ INT_PTR writeAnswer = dialog.Create(NULL); // ParentWindow doesn't work with 7z
+
+ switch(writeAnswer)
+ {
+ case IDCANCEL:
+ return E_ABORT;
+ // askResult = NAskOverwriteAnswer::kCancel;
+ // break;
+ case IDNO:
+ *answer = NOverwriteAnswer::kNo;
+ break;
+ case IDC_BUTTON_OVERWRITE_NO_TO_ALL:
+ *answer = NOverwriteAnswer::kNoToAll;
+ break;
+ case IDC_BUTTON_OVERWRITE_YES_TO_ALL:
+ *answer = NOverwriteAnswer::kYesToAll;
+ break;
+ case IDC_BUTTON_OVERWRITE_AUTO_RENAME:
+ *answer = NOverwriteAnswer::kAutoRename;
+ break;
+ case IDYES:
+ *answer = NOverwriteAnswer::kYes;
+ break;
+ default:
+ throw 20413;
+ }
+ return S_OK;
+}
+
+
+STDMETHODIMP CExtractCallbackImp::PrepareOperation(const wchar_t *name, Int32 /* askExtractMode */, const UInt64 * /* position */)
+{
+ return SetCurrentFilePath(name);
+}
+
+STDMETHODIMP CExtractCallbackImp::MessageError(const wchar_t *message)
+{
+ AddErrorMessage(message);
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::ShowMessage(const wchar_t *message)
+{
+ AddErrorMessage(message);
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 operationResult, bool encrypted)
+{
+ switch(operationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kOK:
+ break;
+ default:
+ {
+ UINT messageID;
+ UInt32 langID;
+ switch(operationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
+ messageID = IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_UNSUPPORTED_METHOD;
+ langID = 0x02000A91;
+ break;
+ case NArchive::NExtract::NOperationResult::kDataError:
+ messageID = encrypted ?
+ IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED:
+ IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_DATA_ERROR;
+ langID = encrypted ? 0x02000A94 : 0x02000A92;
+ break;
+ case NArchive::NExtract::NOperationResult::kCRCError:
+ messageID = encrypted ?
+ IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CRC_ENCRYPTED:
+ IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CRC;
+ langID = encrypted ? 0x02000A95 : 0x02000A93;
+ break;
+ default:
+ return E_FAIL;
+ }
+ if (_needWriteArchivePath)
+ {
+ AddErrorMessage(_currentArchivePath);
+ _needWriteArchivePath = false;
+ }
+ AddErrorMessage(
+ MyFormatNew(messageID,
+ #ifdef LANG
+ langID,
+ #endif
+ _currentFilePath));
+ }
+ }
+ return S_OK;
+}
+
+////////////////////////////////////////
+// IExtractCallbackUI
+
+HRESULT CExtractCallbackImp::BeforeOpen(const wchar_t *name)
+{
+ #ifndef _SFX
+ ProgressDialog.ProgressSynch.SetTitleFileName(name);
+ #endif
+ _currentArchivePath = name;
+ return S_OK;
+}
+
+HRESULT CExtractCallbackImp::SetCurrentFilePath(const wchar_t *path)
+{
+ _currentFilePath = path;
+ #ifndef _SFX
+ ProgressDialog.ProgressSynch.SetCurrentFileName(path);
+ #endif
+ return S_OK;
+}
+
+HRESULT CExtractCallbackImp::OpenResult(const wchar_t *name, HRESULT result, bool encrypted)
+{
+ if (result != S_OK)
+ {
+ MessageError(MyFormatNew(encrypted ? IDS_CANT_OPEN_ENCRYPTED_ARCHIVE : IDS_CANT_OPEN_ARCHIVE,
+ #ifdef LANG
+ (encrypted ? 0x0200060A : 0x02000609),
+ #endif
+ name));
+ NumArchiveErrors++;
+ }
+ _currentArchivePath = name;
+ _needWriteArchivePath = true;
+ return S_OK;
+}
+
+HRESULT CExtractCallbackImp::ThereAreNoFiles()
+{
+ return S_OK;
+}
+
+HRESULT CExtractCallbackImp::ExtractResult(HRESULT result)
+{
+ if (result == S_OK)
+ return result;
+ NumArchiveErrors++;
+ if (result == E_ABORT || result == ERROR_DISK_FULL)
+ return result;
+ MessageError(_currentFilePath);
+ MessageError(NError::MyFormatMessageW(result));
+ return S_OK;
+}
+
+HRESULT CExtractCallbackImp::SetPassword(const UString &password)
+{
+ PasswordIsDefined = true;
+ Password = password;
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::CryptoGetTextPassword(BSTR *password)
+{
+ if (!PasswordIsDefined)
+ {
+ CPasswordDialog dialog;
+
+ if (dialog.Create(ParentWindow) == IDCANCEL)
+ return E_ABORT;
+
+ Password = dialog.Password;
+ PasswordIsDefined = true;
+ }
+ CMyComBSTR tempName(Password);
+ *password = tempName.Detach();
+
+ return S_OK;
+}
+
+
+// IExtractCallBack3
+STDMETHODIMP CExtractCallbackImp::AskWrite(
+ const wchar_t *srcPath, Int32 srcIsFolder,
+ const FILETIME *srcTime, const UInt64 *srcSize,
+ const wchar_t *destPath,
+ BSTR *destPathResult,
+ Int32 *writeAnswer)
+{
+ UString destPathResultTemp = destPath;
+ /*
+ {
+ CMyComBSTR destPathResultBSTR = destPath;
+ *destPathResult = destPathResultBSTR.Detach();
+ }
+ */
+ *destPathResult = 0;
+ *writeAnswer = BoolToInt(false);
+
+ UString destPathSpec = destPath;
+ UString destPathSys = destPathSpec;
+ bool srcIsFolderSpec = IntToBool(srcIsFolder);
+ CFileInfoW destFileInfo;
+ if (FindFile(destPathSys, destFileInfo))
+ {
+ if (srcIsFolderSpec)
+ {
+ if (!destFileInfo.IsDirectory())
+ {
+ UString message = UString(L"can not replace file \'")
+ + destPathSpec +
+ UString(L"\' with folder with same name");
+ RINOK(MessageError(message));
+ return E_ABORT;
+ }
+ *writeAnswer = BoolToInt(false);
+ return S_OK;
+ }
+ if (destFileInfo.IsDirectory())
+ {
+ UString message = UString(L"can not replace folder \'")
+ + destPathSpec +
+ UString(L"\' with file with same name");
+ RINOK(MessageError(message));
+ return E_FAIL;
+ }
+
+ switch(OverwriteMode)
+ {
+ case NExtract::NOverwriteMode::kSkipExisting:
+ return S_OK;
+ case NExtract::NOverwriteMode::kAskBefore:
+ {
+ Int32 overwiteResult;
+ RINOK(AskOverwrite(
+ destPathSpec,
+ &destFileInfo.LastWriteTime, &destFileInfo.Size,
+ srcPath,
+ srcTime, srcSize,
+ &overwiteResult));
+ switch(overwiteResult)
+ {
+ case NOverwriteAnswer::kCancel:
+ return E_ABORT;
+ case NOverwriteAnswer::kNo:
+ return S_OK;
+ case NOverwriteAnswer::kNoToAll:
+ OverwriteMode = NExtract::NOverwriteMode::kSkipExisting;
+ return S_OK;
+ case NOverwriteAnswer::kYesToAll:
+ OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt;
+ break;
+ case NOverwriteAnswer::kYes:
+ break;
+ case NOverwriteAnswer::kAutoRename:
+ OverwriteMode = NExtract::NOverwriteMode::kAutoRename;
+ break;
+ default:
+ throw 20413;
+ }
+ }
+ }
+ if (OverwriteMode == NExtract::NOverwriteMode::kAutoRename)
+ {
+ if (!AutoRenamePath(destPathSys))
+ {
+ UString message = UString(L"can not create name of file ")
+ + destPathSys;
+ RINOK(MessageError(message));
+ return E_ABORT;
+ }
+ destPathResultTemp = destPathSys;
+ }
+ else
+ if (!NFile::NDirectory::DeleteFileAlways(destPathSys))
+ {
+ UString message = UString(L"can not delete output file ")
+ + destPathSys;
+ RINOK(MessageError(message));
+ return E_ABORT;
+ }
+ }
+ CMyComBSTR destPathResultBSTR = destPathResultTemp;
+ *destPathResult = destPathResultBSTR.Detach();
+ *writeAnswer = BoolToInt(true);
+ return S_OK;
+}
+
diff --git a/CPP/7zip/FileManager/ExtractCallback.h b/CPP/7zip/FileManager/ExtractCallback.h
new file mode 100755
index 00000000..7bf8864e
--- /dev/null
+++ b/CPP/7zip/FileManager/ExtractCallback.h
@@ -0,0 +1,124 @@
+// ExtractCallback.h
+
+#ifndef __EXTRACTCALLBACK_H
+#define __EXTRACTCALLBACK_H
+
+#include "../UI/Agent/IFolderArchive.h"
+#include "Common/String.h"
+
+#ifdef _SFX
+#include "Resource/ProgressDialog/ProgressDialog.h"
+#else
+#include "Resource/ProgressDialog2/ProgressDialog.h"
+#endif
+
+#include "Windows/ResourceString.h"
+
+#ifdef LANG
+#include "LangUtils.h"
+#endif
+
+#ifndef _NO_CRYPTO
+#include "../IPassword.h"
+#endif
+#include "Common/MyCom.h"
+#include "IFolder.h"
+
+class CExtractCallbackImp:
+ public IExtractCallbackUI,
+ public IFolderOperationsExtractCallback,
+ #ifndef _NO_CRYPTO
+ public ICryptoGetTextPassword,
+ #endif
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP3(
+ IFolderArchiveExtractCallback,
+ IFolderOperationsExtractCallback,
+ ICryptoGetTextPassword
+ )
+
+ // IProgress
+ STDMETHOD(SetTotal)(UInt64 total);
+ STDMETHOD(SetCompleted)(const UInt64 *completeValue);
+
+ // IFolderArchiveExtractCallback
+ STDMETHOD(AskOverwrite)(
+ const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize,
+ const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize,
+ Int32 *answer);
+ STDMETHOD (PrepareOperation)(const wchar_t *name, Int32 askExtractMode, const UInt64 *position);
+
+ STDMETHOD(MessageError)(const wchar_t *message);
+ STDMETHOD(SetOperationResult)(Int32 operationResult, bool encrypted);
+
+ // IExtractCallbackUI
+
+ HRESULT BeforeOpen(const wchar_t *name);
+ HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted);
+ HRESULT ThereAreNoFiles();
+ HRESULT ExtractResult(HRESULT result);
+
+ #ifndef _NO_CRYPTO
+ HRESULT SetPassword(const UString &password);
+ #endif
+
+ // IFolderOperationsExtractCallback
+ STDMETHOD(AskWrite)(
+ const wchar_t *srcPath,
+ Int32 srcIsFolder,
+ const FILETIME *srcTime,
+ const UInt64 *srcSize,
+ const wchar_t *destPathRequest,
+ BSTR *destPathResult,
+ Int32 *writeAnswer);
+ STDMETHOD(ShowMessage)(const wchar_t *message);
+ STDMETHOD(SetCurrentFilePath)(const wchar_t *filePath);
+
+ // ICryptoGetTextPassword
+ #ifndef _NO_CRYPTO
+ STDMETHOD(CryptoGetTextPassword)(BSTR *password);
+ #endif
+
+private:
+ // bool _extractMode;
+ UString _currentArchivePath;
+ bool _needWriteArchivePath;
+
+ UString _currentFilePath;
+
+ // void CreateComplexDirectory(const UStringVector &aDirPathParts);
+
+ void AddErrorMessage(LPCWSTR message);
+public:
+ CProgressDialog ProgressDialog;
+ UStringVector Messages;
+ bool ShowMessages;
+ HWND ParentWindow;
+ INT_PTR StartProgressDialog(const UString &title)
+ {
+ return ProgressDialog.Create(title, ParentWindow);
+ }
+ UInt32 NumArchiveErrors;
+ NExtract::NOverwriteMode::EEnum OverwriteMode;
+
+ #ifndef _NO_CRYPTO
+ bool PasswordIsDefined;
+ UString Password;
+ #endif
+
+ CExtractCallbackImp():
+ #ifndef _NO_CRYPTO
+ PasswordIsDefined(false),
+ #endif
+ OverwriteMode(NExtract::NOverwriteMode::kAskBefore),
+ ParentWindow(0),
+ ShowMessages(true)
+ {}
+
+ ~CExtractCallbackImp();
+ void Init();
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/FM.cpp b/CPP/7zip/FileManager/FM.cpp
new file mode 100755
index 00000000..c64f0b51
--- /dev/null
+++ b/CPP/7zip/FileManager/FM.cpp
@@ -0,0 +1,788 @@
+// FAM.cpp
+
+#include "StdAfx.h"
+
+#include "resource.h"
+#include "Panel.h"
+
+#include "Common/Defs.h"
+#include "Common/StringConvert.h"
+#include "Common/Alloc.h"
+// #include "Common/CommandLineParser.h"
+
+#include "Windows/Control/Toolbar.h"
+#include "Windows/Error.h"
+#include "Windows/COM.h"
+#include "Windows/DLL.h"
+#include "Windows/Security.h"
+#include "Windows/MemoryLock.h"
+
+#include "ViewSettings.h"
+#include "../UI/Resource/Extract/resource.h"
+
+#include "App.h"
+#include "StringUtils.h"
+
+#include "MyLoadMenu.h"
+#include "LangUtils.h"
+#include "FormatUtils.h"
+#include "RegistryUtils.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NFind;
+// using namespace NCommandLineParser;
+
+// NWindows::NCOM::CComInitializer aComInitializer;
+
+#define MAX_LOADSTRING 100
+
+#define MENU_HEIGHT 26
+
+#ifndef _UNICODE
+bool g_IsNT = false;
+#endif
+HINSTANCE g_hInstance;
+HWND g_HWND;
+bool g_OpenArchive = false;
+static UString g_MainPath;
+
+const int kNumDefaultPanels = 1;
+
+const int kSplitterWidth = 4;
+int kSplitterRateMax = 1 << 16;
+
+// bool OnMenuCommand(HWND hWnd, int id);
+
+static UString GetProgramPath()
+{
+ UString s;
+ NDLL::MyGetModuleFileName(g_hInstance, s);
+ return s;
+}
+
+UString GetProgramFolderPrefix()
+{
+ UString path = GetProgramPath();
+ int pos = path.ReverseFind(L'\\');
+ return path.Left(pos + 1);
+}
+
+
+class CSplitterPos
+{
+ int _ratio; // 10000 is max
+ int _pos;
+ int _fullWidth;
+ void SetRatioFromPos(HWND hWnd)
+ { _ratio = (_pos + kSplitterWidth / 2) * kSplitterRateMax /
+ MyMax(GetWidth(hWnd), 1); }
+public:
+ int GetPos() const
+ { return _pos; }
+ int GetWidth(HWND hWnd) const
+ {
+ RECT rect;
+ ::GetClientRect(hWnd, &rect);
+ return rect.right;
+ }
+ void SetRatio(HWND hWnd, int aRatio)
+ {
+ _ratio = aRatio;
+ SetPosFromRatio(hWnd);
+ }
+ void SetPosPure(HWND hWnd, int pos)
+ {
+ int posMax = GetWidth(hWnd) - kSplitterWidth;
+ if (pos > posMax)
+ pos = posMax;
+ if (pos < 0)
+ pos = 0;
+ _pos = pos;
+ }
+ void SetPos(HWND hWnd, int pos)
+ {
+ _fullWidth = GetWidth(hWnd);
+ SetPosPure(hWnd, pos);
+ SetRatioFromPos(hWnd);
+ }
+ void SetPosFromRatio(HWND hWnd)
+ {
+ int fullWidth = GetWidth(hWnd);
+ if (_fullWidth != fullWidth)
+ {
+ _fullWidth = fullWidth;
+ SetPosPure(hWnd, GetWidth(hWnd) * _ratio / kSplitterRateMax - kSplitterWidth / 2);
+ }
+ }
+};
+
+bool g_CanChangeSplitter = false;
+UINT32 g_SplitterPos = 0;
+CSplitterPos g_Splitter;
+bool g_PanelsInfoDefined = false;
+
+int g_StartCaptureMousePos;
+int g_StartCaptureSplitterPos;
+
+CApp g_App;
+
+void MoveSubWindows(HWND hWnd);
+void OnSize(HWND hWnd);
+
+LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
+
+const wchar_t *kWindowClass = L"FM";
+
+#ifndef _UNICODE
+static bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+#endif
+
+// FUNCTION: InitInstance(HANDLE, int)
+BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
+{
+ CWindow wnd;
+
+ g_hInstance = hInstance;
+
+ ReloadLangSmart();
+
+ // LoadString(hInstance, IDS_CLASS, windowClass, MAX_LOADSTRING);
+
+ // LoadString(hInstance, IDS_APP_TITLE, title, MAX_LOADSTRING);
+ UString title = LangString(IDS_APP_TITLE, 0x03000000);
+
+ /*
+ //If it is already running, then focus on the window
+ hWnd = FindWindow(windowClass, title);
+ if (hWnd)
+ {
+ SetForegroundWindow ((HWND) (((DWORD)hWnd) | 0x01));
+ return 0;
+ }
+ */
+
+ WNDCLASSW wc;
+
+ // wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.style = 0;
+ wc.lpfnWndProc = (WNDPROC) WndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = hInstance;
+ wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_FAM));
+
+ // wc.hCursor = LoadCursor (NULL, IDC_ARROW);
+ wc.hCursor = ::LoadCursor(0, IDC_SIZEWE);
+ // wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
+ wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
+
+ wc.lpszMenuName = MAKEINTRESOURCEW(IDM_MENU);
+ wc.lpszClassName = kWindowClass;
+
+ MyRegisterClass(&wc);
+
+ // RECT rect;
+ // GetClientRect(hWnd, &rect);
+
+ DWORD style = WS_OVERLAPPEDWINDOW;
+ // DWORD style = 0;
+
+ RECT rect;
+ bool maximized = false;
+ int x , y, xSize, ySize;
+ x = y = xSize = ySize = CW_USEDEFAULT;
+ bool windowPosIsRead = ReadWindowSize(rect, maximized);
+
+ if (windowPosIsRead)
+ {
+ // x = rect.left;
+ // y = rect.top;
+ xSize = rect.right - rect.left;
+ ySize = rect.bottom - rect.top;
+ }
+
+ UINT32 numPanels, currentPanel;
+ g_PanelsInfoDefined = ReadPanelsInfo(numPanels, currentPanel, g_SplitterPos);
+ if (g_PanelsInfoDefined)
+ {
+ if (numPanels < 1 || numPanels > 2)
+ numPanels = kNumDefaultPanels;
+ if (currentPanel >= 2)
+ currentPanel = 0;
+ }
+ else
+ {
+ numPanels = kNumDefaultPanels;
+ currentPanel = 0;
+ }
+ g_App.NumPanels = numPanels;
+ g_App.LastFocusedPanel = currentPanel;
+
+ if (!wnd.Create(kWindowClass, title, style,
+ x, y, xSize, ySize, NULL, NULL, hInstance, NULL))
+ return FALSE;
+ g_HWND = (HWND)wnd;
+
+ WINDOWPLACEMENT placement;
+ placement.length = sizeof(placement);
+ if (wnd.GetPlacement(&placement))
+ {
+ if (nCmdShow == SW_SHOWNORMAL || nCmdShow == SW_SHOW ||
+ nCmdShow == SW_SHOWDEFAULT)
+ {
+ if (maximized)
+ placement.showCmd = SW_SHOWMAXIMIZED;
+ else
+ placement.showCmd = SW_SHOWNORMAL;
+ }
+ else
+ placement.showCmd = nCmdShow;
+ if (windowPosIsRead)
+ placement.rcNormalPosition = rect;
+ wnd.SetPlacement(&placement);
+ // window.Show(nCmdShow);
+ }
+ else
+ wnd.Show(nCmdShow);
+ return TRUE;
+}
+
+/*
+static void GetCommands(const UString &aCommandLine, UString &aCommands)
+{
+ UString aProgramName;
+ aCommands.Empty();
+ bool aQuoteMode = false;
+ for (int i = 0; i < aCommandLine.Length(); i++)
+ {
+ wchar_t aChar = aCommandLine[i];
+ if (aChar == L'\"')
+ aQuoteMode = !aQuoteMode;
+ else if (aChar == L' ' && !aQuoteMode)
+ {
+ if (!aQuoteMode)
+ {
+ i++;
+ break;
+ }
+ }
+ else
+ aProgramName += aChar;
+ }
+ aCommands = aCommandLine.Mid(i);
+}
+*/
+
+DWORD GetDllVersion(LPCTSTR lpszDllName)
+{
+ HINSTANCE hinstDll;
+ DWORD dwVersion = 0;
+ hinstDll = LoadLibrary(lpszDllName);
+ if(hinstDll)
+ {
+ DLLGETVERSIONPROC pDllGetVersion;
+ pDllGetVersion = (DLLGETVERSIONPROC) GetProcAddress(hinstDll, "DllGetVersion");
+
+ /*Because some DLLs might not implement this function, you
+ must test for it explicitly. Depending on the particular
+ DLL, the lack of a DllGetVersion function can be a useful
+ indicator of the version.
+ */
+ if(pDllGetVersion)
+ {
+ DLLVERSIONINFO dvi;
+ HRESULT hr;
+
+ ZeroMemory(&dvi, sizeof(dvi));
+ dvi.cbSize = sizeof(dvi);
+
+ hr = (*pDllGetVersion)(&dvi);
+
+ if(SUCCEEDED(hr))
+ {
+ dwVersion = MAKELONG(dvi.dwMinorVersion, dvi.dwMajorVersion);
+ }
+ }
+ FreeLibrary(hinstDll);
+ }
+ return dwVersion;
+}
+
+DWORD g_ComCtl32Version;
+
+/*
+#ifndef _WIN64
+typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
+
+static bool IsWow64()
+{
+ LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(
+ GetModuleHandle("kernel32"), "IsWow64Process");
+ if (fnIsWow64Process == NULL)
+ return false;
+ BOOL isWow;
+ if (!fnIsWow64Process(GetCurrentProcess(),&isWow))
+ return false;
+ return isWow != FALSE;
+}
+#endif
+*/
+
+bool IsLargePageSupported()
+{
+ #ifdef _WIN64
+ return true;
+ #else
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ if (versionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || versionInfo.dwMajorVersion < 5)
+ return false;
+ if (versionInfo.dwMajorVersion > 5)
+ return true;
+ if (versionInfo.dwMinorVersion < 1)
+ return false;
+ if (versionInfo.dwMinorVersion > 1)
+ return true;
+ // return IsWow64();
+ return false;
+ #endif
+}
+
+static void SetMemoryLock()
+{
+ if (!IsLargePageSupported())
+ return;
+ // if (ReadLockMemoryAdd())
+ NSecurity::AddLockMemoryPrivilege();
+
+ if (ReadLockMemoryEnable())
+ NSecurity::EnableLockMemoryPrivilege();
+}
+
+/*
+static const int kNumSwitches = 1;
+
+namespace NKey {
+enum Enum
+{
+ kOpenArachive = 0,
+};
+
+}
+
+static const CSwitchForm kSwitchForms[kNumSwitches] =
+ {
+ { L"SOA", NSwitchType::kSimple, false },
+ };
+*/
+
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, LPSTR /* lpCmdLine */, int nCmdShow)
+{
+ #ifndef _UNICODE
+ g_IsNT = IsItWindowsNT();
+ #endif
+
+ #ifdef _WIN32
+ SetLargePageSize();
+ #endif
+
+ InitCommonControls();
+
+ g_ComCtl32Version = ::GetDllVersion(TEXT("comctl32.dll"));
+
+ // OleInitialize is required for drag and drop.
+ OleInitialize(NULL);
+ // Maybe needs CoInitializeEx also ?
+ // NCOM::CComInitializer comInitializer;
+
+ UString programString, commandsString;
+ // MessageBoxW(0, GetCommandLineW(), L"", 0);
+ SplitStringToTwoStrings(GetCommandLineW(), programString, commandsString);
+
+ commandsString.Trim();
+ UString paramString, tailString;
+ SplitStringToTwoStrings(commandsString, paramString, tailString);
+ paramString.Trim();
+
+ if (!paramString.IsEmpty())
+ {
+ g_MainPath = paramString;
+ // MessageBoxW(0, paramString, L"", 0);
+ }
+ /*
+ UStringVector commandStrings;
+ NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
+ NCommandLineParser::CParser parser(kNumSwitches);
+ try
+ {
+ parser.ParseStrings(kSwitchForms, commandStrings);
+ const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
+ if(nonSwitchStrings.Size() > 1)
+ {
+ g_MainPath = nonSwitchStrings[1];
+ // g_OpenArchive = parser[NKey::kOpenArachive].ThereIs;
+ CFileInfoW fileInfo;
+ if (FindFile(g_MainPath, fileInfo))
+ {
+ if (!fileInfo.IsDirectory())
+ g_OpenArchive = true;
+ }
+ }
+ }
+ catch(...) { }
+ */
+
+
+ SetMemoryLock();
+
+ MSG msg;
+ if (!InitInstance (hInstance, nCmdShow))
+ return FALSE;
+
+ MyLoadMenu(g_HWND);
+
+ #ifndef _UNICODE
+ if (g_IsNT)
+ {
+ HACCEL hAccels = LoadAcceleratorsW(hInstance, MAKEINTRESOURCEW(IDR_ACCELERATOR1));
+ while (GetMessageW(&msg, NULL, 0, 0))
+ {
+ if (TranslateAcceleratorW(g_HWND, hAccels, &msg) == 0)
+ {
+ TranslateMessage(&msg);
+ DispatchMessageW(&msg);
+ }
+ }
+ }
+ else
+ #endif
+ {
+ HACCEL hAccels = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1));
+ while (GetMessage(&msg, NULL, 0, 0))
+ {
+ if (TranslateAccelerator(g_HWND, hAccels, &msg) == 0)
+ {
+ // if (g_Hwnd != NULL || !IsDialogMessage(g_Hwnd, &msg))
+ // if (!IsDialogMessage(g_Hwnd, &msg))
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+ }
+
+ g_HWND = 0;
+ OleUninitialize();
+ return (int)msg.wParam;
+}
+
+static void SaveWindowInfo(HWND aWnd)
+{
+ /*
+ RECT rect;
+ if (!::GetWindowRect(aWnd, &rect))
+ return;
+ */
+ WINDOWPLACEMENT placement;
+ placement.length = sizeof(placement);
+ if (!::GetWindowPlacement(aWnd, &placement))
+ return;
+ SaveWindowSize(placement.rcNormalPosition,
+ BOOLToBool(::IsZoomed(aWnd)));
+ SavePanelsInfo(g_App.NumPanels, g_App.LastFocusedPanel,
+ g_Splitter.GetPos());
+}
+
+void ExecuteCommand(UINT commandID)
+{
+ switch (commandID)
+ {
+ case kAddCommand:
+ g_App.AddToArchive();
+ break;
+ case kExtractCommand:
+ g_App.ExtractArchives();
+ break;
+ case kTestCommand:
+ g_App.TestArchives();
+ break;
+ }
+}
+
+LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ int wmId, wmEvent;
+ switch (message)
+ {
+ case WM_COMMAND:
+ wmId = LOWORD(wParam);
+ wmEvent = HIWORD(wParam);
+ if ((HWND) lParam != NULL && wmEvent != 0)
+ break;
+ if (wmId >= kToolbarStartID)
+ {
+ ExecuteCommand(wmId);
+ return 0;
+ }
+ if (OnMenuCommand(hWnd, wmId))
+ return 0;
+ break;
+ case WM_INITMENUPOPUP:
+ OnMenuActivating(hWnd, HMENU(wParam), LOWORD(lParam));
+ break;
+
+ /*
+ It doesn't help
+ case WM_EXITMENULOOP:
+ {
+ OnMenuUnActivating(hWnd);
+ break;
+ }
+ case WM_UNINITMENUPOPUP:
+ OnMenuUnActivating(hWnd, HMENU(wParam), lParam);
+ break;
+ */
+
+ case WM_CREATE:
+ {
+
+ /*
+ INITCOMMONCONTROLSEX icex;
+ icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
+ icex.dwICC = ICC_BAR_CLASSES;
+ InitCommonControlsEx(&icex);
+
+ // Toolbar buttons used to create the first 4 buttons.
+ TBBUTTON tbb [ ] =
+ {
+ // {0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0},
+ // {VIEW_PARENTFOLDER, kParentFolderID, TBSTATE_ENABLED, BTNS_BUTTON, 0L, 0},
+ // {0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0},
+ {VIEW_NEWFOLDER, ID_FILE_CREATEFOLDER, TBSTATE_ENABLED, BTNS_BUTTON, 0L, 0},
+ };
+
+ int baseID = 100;
+ NWindows::NControl::CToolBar aToolBar;
+ aToolBar.Attach(::CreateToolbarEx (hWnd,
+ WS_CHILD | WS_BORDER | WS_VISIBLE | TBSTYLE_TOOLTIPS, // | TBSTYLE_FLAT
+ baseID + 2, 11,
+ (HINSTANCE)HINST_COMMCTRL, IDB_VIEW_SMALL_COLOR,
+ (LPCTBBUTTON)&tbb, sizeof(tbb) / sizeof(tbb[0]),
+ 0, 0, 100, 30, sizeof (TBBUTTON)));
+ */
+ // HCURSOR cursor = ::LoadCursor(0, IDC_SIZEWE);
+ // ::SetCursor(cursor);
+
+ if (g_PanelsInfoDefined)
+ g_Splitter.SetPos(hWnd, g_SplitterPos);
+ else
+ {
+ g_Splitter.SetRatio(hWnd, kSplitterRateMax / 2);
+ g_SplitterPos = g_Splitter.GetPos();
+ }
+
+ RECT rect;
+ ::GetClientRect(hWnd, &rect);
+ int xSize = rect.right;
+ int xSizes[2];
+ xSizes[0] = g_Splitter.GetPos();
+ xSizes[1] = xSize - kSplitterWidth - xSizes[0];
+ if (xSizes[1] < 0)
+ xSizes[1] = 0;
+
+ g_App.CreateDragTarget();
+ bool archiveIsOpened;
+ bool encrypted;
+ g_App.Create(hWnd, g_MainPath, xSizes, archiveIsOpened, encrypted);
+ if (!archiveIsOpened && g_OpenArchive)
+ {
+ UString message;
+ if (encrypted)
+ message = MyFormatNew(IDS_CANT_OPEN_ENCRYPTED_ARCHIVE, 0x0200060A, g_MainPath);
+ else
+ message = MyFormatNew(IDS_CANT_OPEN_ARCHIVE, 0x02000609, g_MainPath);
+ MessageBoxW(0, message, L"7-zip", MB_ICONERROR);
+ return -1;
+ }
+ // g_SplitterPos = 0;
+
+ // ::DragAcceptFiles(hWnd, TRUE);
+ RegisterDragDrop(hWnd, g_App._dropTarget);
+
+ break;
+ }
+ case WM_DESTROY:
+ {
+ // ::DragAcceptFiles(hWnd, FALSE);
+ RevokeDragDrop(hWnd);
+ g_App._dropTarget.Release();
+
+ g_App.Save();
+ g_App.Release();
+ SaveWindowInfo(hWnd);
+ PostQuitMessage(0);
+ break;
+ }
+ /*
+ case WM_MOVE:
+ {
+ break;
+ }
+ */
+ case WM_LBUTTONDOWN:
+ g_StartCaptureMousePos = LOWORD(lParam);
+ g_StartCaptureSplitterPos = g_Splitter.GetPos();
+ ::SetCapture(hWnd);
+ break;
+ case WM_LBUTTONUP:
+ {
+ ::ReleaseCapture();
+ break;
+ }
+ case WM_MOUSEMOVE:
+ {
+ if ((wParam & MK_LBUTTON) != 0 && ::GetCapture() == hWnd)
+ {
+ g_Splitter.SetPos(hWnd, g_StartCaptureSplitterPos +
+ (short)LOWORD(lParam) - g_StartCaptureMousePos);
+ MoveSubWindows(hWnd);
+ }
+ break;
+ }
+
+ case WM_SIZE:
+ {
+ if (g_CanChangeSplitter)
+ g_Splitter.SetPosFromRatio(hWnd);
+ else
+ {
+ g_Splitter.SetPos(hWnd, g_SplitterPos );
+ g_CanChangeSplitter = true;
+ }
+
+ OnSize(hWnd);
+ /*
+ int xSize = LOWORD(lParam);
+ int ySize = HIWORD(lParam);
+ // int xSplitter = 2;
+ int xWidth = g_SplitPos;
+ // int xSplitPos = xWidth;
+ g_Panel[0]._listView.MoveWindow(0, 0, xWidth, ySize);
+ g_Panel[1]._listView.MoveWindow(xSize - xWidth, 0, xWidth, ySize);
+ */
+ return 0;
+ break;
+ }
+ case WM_SETFOCUS:
+ // g_App.SetFocus(g_App.LastFocusedPanel);
+ g_App.SetFocusToLastItem();
+ break;
+ /*
+ case WM_ACTIVATE:
+ {
+ int fActive = LOWORD(wParam);
+ switch (fActive)
+ {
+ case WA_INACTIVE:
+ {
+ // g_FocusIndex = g_App.LastFocusedPanel;
+ // g_App.LastFocusedPanel = g_App.GetFocusedPanelIndex();
+ // return 0;
+ }
+ }
+ break;
+ }
+ */
+ /*
+ case kLangWasChangedMessage:
+ MyLoadMenu(g_HWND);
+ return 0;
+ */
+
+ /*
+ case WM_SETTINGCHANGE:
+ break;
+ */
+ case WM_NOTIFY:
+ {
+ g_App.OnNotify((int)wParam, (LPNMHDR)lParam);
+ break;
+ }
+ /*
+ case WM_DROPFILES:
+ {
+ g_App.GetFocusedPanel().CompressDropFiles((HDROP)wParam);
+ return 0 ;
+ }
+ */
+ }
+ #ifndef _UNICODE
+ if (g_IsNT)
+ return DefWindowProcW(hWnd, message, wParam, lParam);
+ else
+ #endif
+ return DefWindowProc(hWnd, message, wParam, lParam);
+
+}
+
+void OnSize(HWND hWnd)
+{
+ /*
+ if (g_App._rebar)
+ {
+ RECT rect;
+ ::GetClientRect(hWnd, &rect);
+ int xSize = rect.right;
+ int ySize = rect.bottom;
+ // rect.bottom = 0;
+ // g_App._rebar.SizeToRect(&rect);
+ // g_App._rebar.Move(0, 0, xSize, ySize);
+ }
+ */
+ MoveSubWindows(hWnd);
+}
+
+void MoveSubWindows(HWND hWnd)
+{
+ RECT rect;
+ ::GetClientRect(hWnd, &rect);
+ int xSize = rect.right;
+ int kHeaderSize = 0;
+ int ySize = MyMax(int(rect.bottom - kHeaderSize), 0);
+ if (g_App._rebar)
+ {
+ RECT barRect;
+ g_App._rebar.GetWindowRect(&barRect);
+ kHeaderSize = barRect.bottom - barRect.top;
+ ySize = MyMax(int(rect.bottom - kHeaderSize), 0);
+ }
+
+ // g_App._headerToolBar.Move(0, 2, xSize, kHeaderSize - 2);
+ RECT rect2 = rect;
+ rect2.bottom = 0;
+ // g_App._headerReBar.SizeToRect(&rect2);
+ if (g_App.NumPanels > 1)
+ {
+ g_App.Panels[0].Move(0, kHeaderSize, g_Splitter.GetPos(), ySize);
+ int xWidth1 = g_Splitter.GetPos() + kSplitterWidth;
+ g_App.Panels[1].Move(xWidth1, kHeaderSize, xSize - xWidth1, ySize);
+ }
+ else
+ {
+ /*
+ int otherPanel = 1 - g_App.LastFocusedPanel;
+ if (g_App.PanelsCreated[otherPanel])
+ g_App.Panels[otherPanel].Move(0, kHeaderSize, 0, ySize);
+ */
+ g_App.Panels[g_App.LastFocusedPanel].Move(0, kHeaderSize, xSize, ySize);
+ }
+}
diff --git a/CPP/7zip/FileManager/FM.dsp b/CPP/7zip/FileManager/FM.dsp
new file mode 100755
index 00000000..75c95ead
--- /dev/null
+++ b/CPP/7zip/FileManager/FM.dsp
@@ -0,0 +1,1251 @@
+# Microsoft Developer Studio Project File - Name="FM" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=FM - Win32 DebugU
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "FM.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "FM.mak" CFG="FM - Win32 DebugU"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "FM - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "FM - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE "FM - Win32 ReleaseU" (based on "Win32 (x86) Application")
+!MESSAGE "FM - Win32 DebugU" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "FM - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "WIN_LONG_PATH" /Yu"StdAfx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Program Files\7-ZIP\7zFM.exe" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "FM - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "WIN_LONG_PATH" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Program Files\7-ZIP\7zFM.exe" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "FM - Win32 ReleaseU"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ReleaseU"
+# PROP BASE Intermediate_Dir "ReleaseU"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ReleaseU"
+# PROP Intermediate_Dir "ReleaseU"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"StdAfx.h" /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "WIN_LONG_PATH" /Yu"StdAfx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Program Files\7-ZIP\7zFMn.exe" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "FM - Win32 DebugU"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "DebugU"
+# PROP BASE Intermediate_Dir "DebugU"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "DebugU"
+# PROP Intermediate_Dir "DebugU"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c
+# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "WIN_LONG_PATH" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Program Files\7-ZIP\7zFMn.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "FM - Win32 Release"
+# Name "FM - Win32 Debug"
+# Name "FM - Win32 ReleaseU"
+# Name "FM - Win32 DebugU"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\Resource\AboutDialog\7zipLogo.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\add.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ClassDefs.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Copy.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Delete.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Extract.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\FM.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\Move.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Parent.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Properties.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.rc
+# ADD BASE RSC /l 0x419
+# ADD RSC /l 0x409
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Test.bmp
+# End Source File
+# End Group
+# Begin Group "Archive Interfaces"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Archive\IArchive.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\UI\Agent\IFolderArchive.h
+# End Source File
+# End Group
+# Begin Group "Folders"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\FSDrives.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\FSDrives.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\FSFolder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\FSFolder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\FSFolderCopy.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\IFolder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NetFolder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NetFolder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\PhysDriveFolder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\PhysDriveFolder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\RootFolder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\RootFolder.h
+# End Source File
+# End Group
+# Begin Group "Registry"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\RegistryAssociations.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\RegistryAssociations.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\RegistryPlugins.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\RegistryPlugins.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\RegistryUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\RegistryUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ViewSettings.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ViewSettings.h
+# End Source File
+# End Group
+# Begin Group "Panel"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\App.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\App.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\AppState.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\EnumFormatEtc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\EnumFormatEtc.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\FileFolderPluginOpen.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\FileFolderPluginOpen.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Panel.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Panel.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\PanelCopy.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\PanelCrc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\PanelDrag.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\PanelFolderChange.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\PanelItemOpen.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\PanelItems.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\PanelKey.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\PanelListNotify.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\PanelMenu.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\PanelOperations.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\PanelSelect.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\PanelSort.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\PanelSplitFile.cpp
+# End Source File
+# End Group
+# Begin Group "Dialog"
+
+# PROP Default_Filter ""
+# Begin Group "Options"
+
+# PROP Default_Filter ""
+# Begin Group "Settings"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\Resource\SettingsPage\SettingsPage.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource\SettingsPage\SettingsPage.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\Resource\EditPage\EditPage.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource\EditPage\EditPage.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource\LangPage\LangPage.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource\LangPage\LangPage.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource\PluginsPage\PluginsPage.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource\PluginsPage\PluginsPage.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource\SystemPage\SystemPage.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource\SystemPage\SystemPage.h
+# End Source File
+# End Group
+# Begin Group "Password"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=Resource\PasswordDialog\PasswordDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=Resource\PasswordDialog\PasswordDialog.h
+# End Source File
+# End Group
+# Begin Group "Progress"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\Resource\ProgressDialog2\ProgressDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource\ProgressDialog2\ProgressDialog.h
+# End Source File
+# End Group
+# Begin Group "About"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\Resource\AboutDialog\AboutDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource\AboutDialog\AboutDialog.h
+# End Source File
+# End Group
+# Begin Group "Benchmark"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\Resource\BenchmarkDialog\BenchmarkDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource\BenchmarkDialog\BenchmarkDialog.h
+# End Source File
+# End Group
+# Begin Group "Split"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\Resource\SplitDialog\SplitDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource\SplitDialog\SplitDialog.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\Resource\ComboDialog\ComboDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource\ComboDialog\ComboDialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource\CopyDialog\CopyDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource\CopyDialog\CopyDialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource\ListViewDialog\ListViewDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource\ListViewDialog\ListViewDialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=Resource\MessagesDialog\MessagesDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=Resource\MessagesDialog\MessagesDialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=Resource\OverwriteDialog\OverwriteDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=Resource\OverwriteDialog\OverwriteDialog.h
+# End Source File
+# End Group
+# Begin Group "FM Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\ExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ExtractCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\FormatUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\FormatUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\HelpUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\HelpUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LangUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LangUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ProgramLocation.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ProgramLocation.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\UpdateCallback100.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\UpdateCallback100.h
+# End Source File
+# End Group
+# Begin Group "SDK"
+
+# PROP Default_Filter ""
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Group "Control"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Windows\Control\ComboBox.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Control\ComboBox.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Control\CommandBar.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Control\Dialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Control\Dialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Control\Edit.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Control\ImageList.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Control\ListView.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Control\ListView.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Control\ProgressBar.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Control\PropertyPage.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Control\PropertyPage.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Control\ReBar.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Control\Static.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Control\StatusBar.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Control\ToolBar.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Control\Trackbar.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Control\Window2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Control\Window2.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\Windows\CommonDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\CommonDialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Defs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Device.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Error.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Error.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\FileDevice.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\FileDevice.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\FileDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\FileDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\FileIO.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\FileName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\FileName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\FileSystem.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\FileSystem.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Handle.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Memory.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Memory.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\MemoryLock.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\MemoryLock.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Menu.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Menu.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Net.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Net.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Process.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\PropVariantConversions.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\PropVariantConversions.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Registry.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Registry.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\ResourceString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\ResourceString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Security.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Security.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Shell.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Shell.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Synchronization.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Thread.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Time.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Timer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Window.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Window.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\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\CommandLineParser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\CommandLineParser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ComTry.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\CRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\Defs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\DynamicBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\Exception.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\Lang.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\Lang.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MyCom.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\Random.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\Random.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StdInStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StdInStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StdOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StdOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\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\StringToInt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StringToInt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\TextConfig.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\TextConfig.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\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
+
+SOURCE=..\..\Common\Vector.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\Wildcard.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\Wildcard.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "UI Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\UI\Common\ArchiveName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\UI\Common\ArchiveName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\UI\Common\CompressCall.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\UI\Common\CompressCall.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\UI\Common\PropIDUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\UI\Common\PropIDUtils.h
+# End Source File
+# End Group
+# Begin Group "7-Zip Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Common\FilePathAutoRename.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\FilePathAutoRename.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\FileStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\FileStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\StreamObjects.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\StreamObjects.h
+# End Source File
+# End Group
+# Begin Group "C"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\C\Sort.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\C\Sort.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\7zFM.exe.manifest
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zipLogo.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\Add2.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Copy2.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Delete2.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Extract2.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\FilePlugins.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\FilePlugins.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\FM.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Info.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Info2.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Move2.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\MyCom2.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\MyLoadMenu.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\MyLoadMenu.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\OpenCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\OpenCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\OptionsDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\PluginInterface.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\PluginLoader.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\PropertyName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\PropertyName.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\SplitUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\SplitUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\SysIconUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\SysIconUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Test2.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\TextPairs.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\TextPairs.h
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/FileManager/FM.dsw b/CPP/7zip/FileManager/FM.dsw
new file mode 100755
index 00000000..1c955d95
--- /dev/null
+++ b/CPP/7zip/FileManager/FM.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "FM"=.\FM.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/FileManager/FM.ico b/CPP/7zip/FileManager/FM.ico
new file mode 100755
index 00000000..3a0a34da
--- /dev/null
+++ b/CPP/7zip/FileManager/FM.ico
Binary files differ
diff --git a/CPP/7zip/FileManager/FSDrives.cpp b/CPP/7zip/FileManager/FSDrives.cpp
new file mode 100755
index 00000000..447ff4dc
--- /dev/null
+++ b/CPP/7zip/FileManager/FSDrives.cpp
@@ -0,0 +1,240 @@
+// FSDrives.cpp
+
+#include "StdAfx.h"
+
+#include "resource.h"
+
+#include "FSDrives.h"
+
+#include "Common/StringConvert.h"
+#include "../PropID.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+#include "Windows/FileDir.h"
+#include "Windows/FileSystem.h"
+
+#include "SysIconUtils.h"
+#include "FSFolder.h"
+#include "PhysDriveFolder.h"
+#include "LangUtils.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NFind;
+
+static const STATPROPSTG kProperties[] =
+{
+ { NULL, kpidName, VT_BSTR},
+ // { NULL, kpidIsFolder, VT_BOOL},
+ { L"Total Size", kpidTotalSize, VT_UI8},
+ { L"Free Space", kpidFreeSpace, VT_UI8},
+ { NULL, kpidType, VT_BSTR},
+ { L"Label", kpidVolumeName, VT_BSTR},
+ { L"File system", kpidFileSystem, VT_BSTR},
+ { L"Cluster Size", kpidClusterSize, VT_UI8}
+};
+
+static const wchar_t *kDriveTypes[] =
+{
+ L"Unknown",
+ L"No Root Dir",
+ L"Removable",
+ L"Fixed",
+ L"Remote",
+ L"CD-ROM",
+ L"RAM disk"
+};
+
+STDMETHODIMP CFSDrives::LoadItems()
+{
+ _drives.Clear();
+
+ UStringVector driveStrings;
+ MyGetLogicalDriveStrings(driveStrings);
+ for (int i = 0; i < driveStrings.Size(); i++)
+ {
+ CDriveInfo driveInfo;
+
+ const UString &driveName = driveStrings[i];
+
+ driveInfo.FullSystemName = driveName;
+
+ driveInfo.Name = driveInfo.FullSystemName.Left(
+ driveInfo.FullSystemName.Length() - 1);
+ driveInfo.ClusterSize = 0;
+ driveInfo.DriveSize = 0;
+ driveInfo.FreeSpace = 0;
+ UINT driveType = NFile::NSystem::MyGetDriveType(driveName);
+ if (driveType < sizeof(kDriveTypes) / sizeof(kDriveTypes[0]))
+ {
+ driveInfo.Type = kDriveTypes[driveType];
+ }
+ bool needRead = true;
+ if (driveType == DRIVE_CDROM || driveType == DRIVE_REMOVABLE)
+ {
+ /*
+ DWORD dwSerialNumber;`
+ if (!::GetVolumeInformation(driveInfo.FullSystemName,
+ NULL, 0, &dwSerialNumber, NULL, NULL, NULL, 0))
+ */
+ driveInfo.KnownSizes = false;
+ {
+ needRead = false;
+ }
+ }
+ if (needRead)
+ {
+ UString volumeName, fileSystemName;
+ DWORD volumeSerialNumber, maximumComponentLength, fileSystemFlags;
+ NFile::NSystem::MyGetVolumeInformation(driveName,
+ volumeName,
+ &volumeSerialNumber, &maximumComponentLength, &fileSystemFlags,
+ fileSystemName);
+ driveInfo.VolumeName = volumeName;
+ driveInfo.FileSystemName = fileSystemName;
+
+ NFile::NSystem::MyGetDiskFreeSpace(driveName,
+ driveInfo.ClusterSize, driveInfo.DriveSize, driveInfo.FreeSpace);
+ driveInfo.KnownSizes = true;
+ }
+ _drives.Add(driveInfo);
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CFSDrives::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = _drives.Size();
+ return S_OK;
+}
+
+STDMETHODIMP CFSDrives::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value)
+{
+ if (itemIndex >= (UInt32)_drives.Size())
+ return E_INVALIDARG;
+ NCOM::CPropVariant propVariant;
+ const CDriveInfo &driveInfo = _drives[itemIndex];
+ switch(propID)
+ {
+ case kpidIsFolder:
+ propVariant = true;
+ break;
+ case kpidName:
+ propVariant = driveInfo.Name;
+ break;
+ case kpidTotalSize:
+ if (driveInfo.KnownSizes)
+ propVariant = driveInfo.DriveSize;
+ break;
+ case kpidFreeSpace:
+ if (driveInfo.KnownSizes)
+ propVariant = driveInfo.FreeSpace;
+ break;
+ case kpidClusterSize:
+ if (driveInfo.KnownSizes)
+ propVariant = driveInfo.ClusterSize;
+ break;
+ case kpidType:
+ propVariant = driveInfo.Type;
+ break;
+ case kpidVolumeName:
+ propVariant = driveInfo.VolumeName;
+ break;
+ case kpidFileSystem:
+ propVariant = driveInfo.FileSystemName;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
+
+HRESULT CFSDrives::BindToFolderSpec(const wchar_t *name, IFolderFolder **resultFolder)
+{
+ *resultFolder = 0;
+ CFSFolder *fsFolderSpec = new CFSFolder;
+ CMyComPtr<IFolderFolder> subFolder = fsFolderSpec;
+ RINOK(fsFolderSpec->Init(name, 0));
+ *resultFolder = subFolder.Detach();
+ return S_OK;
+}
+
+STDMETHODIMP CFSDrives::BindToFolder(UInt32 index, IFolderFolder **resultFolder)
+{
+ *resultFolder = 0;
+ if (index >= (UInt32)_drives.Size())
+ return E_INVALIDARG;
+ const CDriveInfo &driveInfo = _drives[index];
+ if (_volumeMode)
+ {
+ *resultFolder = 0;
+ CPhysDriveFolder *folderSpec = new CPhysDriveFolder;
+ CMyComPtr<IFolderFolder> subFolder = folderSpec;
+ RINOK(folderSpec->Init(driveInfo.Name));
+ *resultFolder = subFolder.Detach();
+ return S_OK;
+ }
+ return BindToFolderSpec(driveInfo.FullSystemName, resultFolder);
+}
+
+STDMETHODIMP CFSDrives::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder)
+{
+ return BindToFolderSpec(name, resultFolder);
+}
+
+STDMETHODIMP CFSDrives::BindToParentFolder(IFolderFolder **resultFolder)
+{
+ *resultFolder = 0;
+ return S_OK;
+}
+
+STDMETHODIMP CFSDrives::GetName(BSTR * /* name */)
+{
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP CFSDrives::GetNumberOfProperties(UInt32 *numProperties)
+{
+ *numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
+ return S_OK;
+}
+
+STDMETHODIMP CFSDrives::GetPropertyInfo(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType)
+{
+ if (index >= sizeof(kProperties) / sizeof(kProperties[0]))
+ return E_INVALIDARG;
+ const STATPROPSTG &prop = kProperties[index];
+ *propID = prop.propid;
+ *varType = prop.vt;
+ *name = 0;
+ return S_OK;
+}
+
+
+STDMETHODIMP CFSDrives::GetTypeID(BSTR *name)
+{
+ CMyComBSTR temp = L"FSDrives";
+ *name = temp.Detach();
+ return S_OK;
+}
+
+STDMETHODIMP CFSDrives::GetPath(BSTR *path)
+{
+ CMyComBSTR temp = LangString(IDS_COMPUTER, 0x03020300) + UString(L'\\');
+ *path = temp.Detach();
+ return S_OK;
+}
+
+STDMETHODIMP CFSDrives::GetSystemIconIndex(UInt32 index, INT32 *iconIndex)
+{
+ *iconIndex = 0;
+ const CDriveInfo &driveInfo = _drives[index];
+ int iconIndexTemp;
+ if (GetRealIconIndex(driveInfo.FullSystemName, 0, iconIndexTemp) != 0)
+ {
+ *iconIndex = iconIndexTemp;
+ return S_OK;
+ }
+ return GetLastError();
+}
+
diff --git a/CPP/7zip/FileManager/FSDrives.h b/CPP/7zip/FileManager/FSDrives.h
new file mode 100755
index 00000000..496e8fc1
--- /dev/null
+++ b/CPP/7zip/FileManager/FSDrives.h
@@ -0,0 +1,66 @@
+// FSDrives.h
+
+#ifndef __FSDRIVES_H
+#define __FSDRIVES_H
+
+#include "Common/String.h"
+#include "Common/Types.h"
+#include "Common/MyCom.h"
+#include "Windows/FileFind.h"
+#include "Windows/PropVariant.h"
+
+#include "IFolder.h"
+
+struct CDriveInfo
+{
+ UString Name;
+ UString FullSystemName;
+ bool KnownSizes;
+ UInt64 DriveSize;
+ UInt64 FreeSpace;
+ UInt64 ClusterSize;
+ UString Type;
+ UString VolumeName;
+ UString FileSystemName;
+};
+
+class CFSDrives:
+ public IFolderFolder,
+ public IEnumProperties,
+ public IFolderGetTypeID,
+ public IFolderGetPath,
+ public IFolderGetSystemIconIndex,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP4(
+ IEnumProperties,
+ IFolderGetTypeID,
+ IFolderGetPath,
+ IFolderGetSystemIconIndex
+ )
+
+ STDMETHOD(LoadItems)();
+ STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
+ STDMETHOD(GetProperty)(UInt32 itemIndex, PROPID propID, PROPVARIANT *value);
+ STDMETHOD(BindToFolder)(UInt32 index, IFolderFolder **resultFolder);
+ STDMETHOD(BindToFolder)(const wchar_t *name, IFolderFolder **resultFolder);
+ STDMETHOD(BindToParentFolder)(IFolderFolder **resultFolder);
+ STDMETHOD(GetName)(BSTR *name);
+
+ STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
+ STDMETHOD(GetPropertyInfo)(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType);
+ STDMETHOD(GetTypeID)(BSTR *name);
+ STDMETHOD(GetPath)(BSTR *path);
+ STDMETHOD(GetSystemIconIndex)(UInt32 index, INT32 *iconIndex);
+
+private:
+ HRESULT BindToFolderSpec(const wchar_t *name, IFolderFolder **resultFolder);
+ CObjectVector<CDriveInfo> _drives;
+ bool _volumeMode;
+public:
+ void Init() { _volumeMode = false;}
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/FSFolder.cpp b/CPP/7zip/FileManager/FSFolder.cpp
new file mode 100755
index 00000000..309128ae
--- /dev/null
+++ b/CPP/7zip/FileManager/FSFolder.cpp
@@ -0,0 +1,655 @@
+// FSFolder.cpp
+
+#include "StdAfx.h"
+
+#include "FSFolder.h"
+
+#include "Common/StringConvert.h"
+#include "Common/StdInStream.h"
+#include "Common/StdOutStream.h"
+#include "Common/UTFConvert.h"
+
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+#include "Windows/FileDir.h"
+#include "Windows/FileIO.h"
+
+#include "../PropID.h"
+
+#include "SysIconUtils.h"
+#include "FSDrives.h"
+#include "NetFolder.h"
+
+namespace NWindows {
+namespace NFile {
+
+bool GetLongPath(LPCWSTR path, UString &longPath);
+
+}}
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NFind;
+
+static STATPROPSTG kProperties[] =
+{
+ { NULL, kpidName, VT_BSTR},
+ // { NULL, kpidIsFolder, VT_BOOL},
+ { NULL, kpidSize, VT_UI8},
+ { NULL, kpidLastWriteTime, VT_FILETIME},
+ { NULL, kpidCreationTime, VT_FILETIME},
+ { NULL, kpidLastAccessTime, VT_FILETIME},
+ { NULL, kpidAttributes, VT_UI4},
+ { NULL, kpidPackedSize, VT_UI8},
+ { NULL, kpidComment, VT_BSTR},
+ { NULL, kpidPrefix, VT_BSTR}
+};
+
+HRESULT CFSFolder::Init(const UString &path, IFolderFolder *parentFolder)
+{
+ _parentFolder = parentFolder;
+ _path = path;
+
+ _findChangeNotification.FindFirst(_path, false,
+ FILE_NOTIFY_CHANGE_FILE_NAME |
+ FILE_NOTIFY_CHANGE_DIR_NAME |
+ FILE_NOTIFY_CHANGE_ATTRIBUTES |
+ FILE_NOTIFY_CHANGE_SIZE |
+ FILE_NOTIFY_CHANGE_LAST_WRITE /*|
+ FILE_NOTIFY_CHANGE_LAST_ACCESS |
+ FILE_NOTIFY_CHANGE_CREATION |
+ FILE_NOTIFY_CHANGE_SECURITY */);
+ if (!_findChangeNotification.IsHandleAllocated())
+ {
+ DWORD lastError = GetLastError();
+ CFindFile findFile;
+ CFileInfoW fileInfo;
+ if (!findFile.FindFirst(_path + UString(L"*"), fileInfo))
+ return lastError;
+ }
+ return S_OK;
+}
+
+static HRESULT GetFolderSize(const UString &path, UInt64 &size, IProgress *progress)
+{
+ RINOK(progress->SetCompleted(NULL));
+ size = 0;
+ CEnumeratorW enumerator(path + UString(L"\\*"));
+ CFileInfoW fileInfo;
+ while (enumerator.Next(fileInfo))
+ {
+ if (fileInfo.IsDirectory())
+ {
+ UInt64 subSize;
+ RINOK(GetFolderSize(path + UString(L"\\") + fileInfo.Name, subSize, progress));
+ size += subSize;
+ }
+ else
+ size += fileInfo.Size;
+ }
+ return S_OK;
+}
+
+HRESULT CFSFolder::LoadSubItems(CDirItem &dirItem, const UString &path)
+{
+ {
+ CEnumeratorW enumerator(path + L"*");
+ CDirItem fileInfo;
+ while (enumerator.Next(fileInfo))
+ {
+ fileInfo.CompressedSizeIsDefined = false;
+ /*
+ if (!GetCompressedFileSize(_path + fileInfo.Name,
+ fileInfo.CompressedSize))
+ fileInfo.CompressedSize = fileInfo.Size;
+ */
+ if (fileInfo.IsDirectory())
+ {
+ // fileInfo.Size = GetFolderSize(_path + fileInfo.Name);
+ fileInfo.Size = 0;
+ }
+ dirItem.Files.Add(fileInfo);
+ }
+ }
+ if (!_flatMode)
+ return S_OK;
+
+ for (int i = 0; i < dirItem.Files.Size(); i++)
+ {
+ CDirItem &item = dirItem.Files[i];
+ if (item.IsDirectory())
+ LoadSubItems(item, path + item.Name + L'\\');
+ }
+ return S_OK;
+}
+
+void CFSFolder::AddRefs(CDirItem &dirItem)
+{
+ int i;
+ for (i = 0; i < dirItem.Files.Size(); i++)
+ {
+ CDirItem &item = dirItem.Files[i];
+ item.Parent = &dirItem;
+ _refs.Add(&item);
+ }
+ if (!_flatMode)
+ return;
+ for (i = 0; i < dirItem.Files.Size(); i++)
+ {
+ CDirItem &item = dirItem.Files[i];
+ if (item.IsDirectory())
+ AddRefs(item);
+ }
+}
+
+STDMETHODIMP CFSFolder::LoadItems()
+{
+ // OutputDebugString(TEXT("Start\n"));
+ INT32 dummy;
+ WasChanged(&dummy);
+ Clear();
+ RINOK(LoadSubItems(_root, _path));
+ AddRefs(_root);
+
+ // OutputDebugString(TEXT("Finish\n"));
+ _commentsAreLoaded = false;
+ return S_OK;
+}
+
+static const wchar_t *kDescriptionFileName = L"descript.ion";
+
+bool CFSFolder::LoadComments()
+{
+ if (_commentsAreLoaded)
+ return true;
+ _comments.Clear();
+ _commentsAreLoaded = true;
+ NIO::CInFile file;
+ if (!file.Open(_path + kDescriptionFileName))
+ return false;
+ UInt64 length;
+ if (!file.GetLength(length))
+ return false;
+ if (length >= (1 << 28))
+ return false;
+ AString s;
+ char *p = s.GetBuffer((int)((size_t)length + 1));
+ UInt32 processedSize;
+ file.Read(p, (UInt32)length, processedSize);
+ p[length] = 0;
+ s.ReleaseBuffer();
+ s.Replace("\r\n", "\n");
+ if (processedSize != length)
+ return false;
+ file.Close();
+ UString unicodeString;
+ if (!ConvertUTF8ToUnicode(s, unicodeString))
+ return false;
+ return _comments.ReadFromString(unicodeString);
+}
+
+static bool IsAscii(const UString &testString)
+{
+ for (int i = 0; i < testString.Length(); i++)
+ if (testString[i] >= 0x80)
+ return false;
+ return true;
+}
+
+bool CFSFolder::SaveComments()
+{
+ NIO::COutFile file;
+ if (!file.Create(_path + kDescriptionFileName, true))
+ return false;
+ UString unicodeString;
+ _comments.SaveToString(unicodeString);
+ AString utfString;
+ ConvertUnicodeToUTF8(unicodeString, utfString);
+ UInt32 processedSize;
+ if (!IsAscii(unicodeString))
+ {
+ Byte bom [] = { 0xEF, 0xBB, 0xBF, 0x0D, 0x0A };
+ file.Write(bom , sizeof(bom), processedSize);
+ }
+ utfString.Replace("\n", "\r\n");
+ file.Write(utfString, utfString.Length(), processedSize);
+ _commentsAreLoaded = false;
+ return true;
+}
+
+STDMETHODIMP CFSFolder::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = _refs.Size();
+ return S_OK;
+}
+
+/*
+STDMETHODIMP CFSFolder::GetNumberOfSubFolders(UInt32 *numSubFolders)
+{
+ UInt32 numSubFoldersLoc = 0;
+ for (int i = 0; i < _files.Size(); i++)
+ if (_files[i].IsDirectory())
+ numSubFoldersLoc++;
+ *numSubFolders = numSubFoldersLoc;
+ return S_OK;
+}
+*/
+
+bool MyGetCompressedFileSizeW(LPCWSTR fileName, UInt64 &size)
+{
+ DWORD highPart;
+ DWORD lowPart = ::GetCompressedFileSizeW(fileName, &highPart);
+ if (lowPart == INVALID_FILE_SIZE && ::GetLastError() != NO_ERROR)
+ {
+ #ifdef WIN_LONG_PATH
+ {
+ UString longPath;
+ if (GetLongPath(fileName, longPath))
+ lowPart = ::GetCompressedFileSizeW(longPath, &highPart);
+ }
+ #endif
+ if (lowPart == INVALID_FILE_SIZE && ::GetLastError() != NO_ERROR)
+ return false;
+ }
+ size = (UInt64(highPart) << 32) | lowPart;
+ return true;
+}
+
+STDMETHODIMP CFSFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value)
+{
+ NCOM::CPropVariant propVariant;
+ if (itemIndex >= (UInt32)_refs.Size())
+ return E_INVALIDARG;
+ CDirItem &fileInfo = *_refs[itemIndex];
+ switch(propID)
+ {
+ case kpidIsFolder:
+ propVariant = fileInfo.IsDirectory();
+ break;
+ case kpidName:
+ propVariant = fileInfo.Name;
+ break;
+ case kpidSize:
+ propVariant = fileInfo.Size;
+ break;
+ case kpidPackedSize:
+ if (!fileInfo.CompressedSizeIsDefined)
+ {
+ fileInfo.CompressedSizeIsDefined = true;
+ if (fileInfo.IsDirectory () ||
+ !MyGetCompressedFileSizeW(_path + GetRelPath(fileInfo), fileInfo.CompressedSize))
+ fileInfo.CompressedSize = fileInfo.Size;
+ }
+ propVariant = fileInfo.CompressedSize;
+ break;
+ case kpidAttributes:
+ propVariant = (UInt32)fileInfo.Attributes;
+ break;
+ case kpidCreationTime:
+ propVariant = fileInfo.CreationTime;
+ break;
+ case kpidLastAccessTime:
+ propVariant = fileInfo.LastAccessTime;
+ break;
+ case kpidLastWriteTime:
+ propVariant = fileInfo.LastWriteTime;
+ break;
+ case kpidComment:
+ {
+ LoadComments();
+ UString comment;
+ if (_comments.GetValue(GetRelPath(fileInfo), comment))
+ propVariant = comment;
+ break;
+ }
+ case kpidPrefix:
+ {
+ if (_flatMode)
+ {
+ propVariant = GetPrefix(fileInfo);
+ }
+ break;
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
+
+HRESULT CFSFolder::BindToFolderSpec(const wchar_t *name, IFolderFolder **resultFolder)
+{
+ *resultFolder = 0;
+ CFSFolder *folderSpec = new CFSFolder;
+ CMyComPtr<IFolderFolder> subFolder = folderSpec;
+ RINOK(folderSpec->Init(_path + name + UString(L'\\'), 0));
+ *resultFolder = subFolder.Detach();
+ return S_OK;
+}
+
+UString CFSFolder::GetPrefix(const CDirItem &item) const
+{
+ UString path;
+ CDirItem *cur = item.Parent;
+ while (cur->Parent != 0)
+ {
+ path = cur->Name + UString('\\') + path;
+ cur = cur->Parent;
+ }
+ return path;
+}
+
+UString CFSFolder::GetRelPath(const CDirItem &item) const
+{
+ return GetPrefix(item) + item.Name;
+}
+
+STDMETHODIMP CFSFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder)
+{
+ *resultFolder = 0;
+ const CDirItem &fileInfo = *_refs[index];
+ if (!fileInfo.IsDirectory())
+ return E_INVALIDARG;
+ return BindToFolderSpec(GetRelPath(fileInfo), resultFolder);
+}
+
+STDMETHODIMP CFSFolder::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder)
+{
+ return BindToFolderSpec(name, resultFolder);
+}
+
+STDMETHODIMP CFSFolder::BindToParentFolder(IFolderFolder **resultFolder)
+{
+ *resultFolder = 0;
+ if (_parentFolder)
+ {
+ CMyComPtr<IFolderFolder> parentFolder = _parentFolder;
+ *resultFolder = parentFolder.Detach();
+ return S_OK;
+ }
+ if (_path.IsEmpty())
+ return E_INVALIDARG;
+ int pos = _path.ReverseFind(L'\\');
+ if (pos < 0 || pos != _path.Length() - 1)
+ return E_FAIL;
+ UString parentPath = _path.Left(pos);
+ pos = parentPath.ReverseFind(L'\\');
+ if (pos < 0)
+ {
+ parentPath.Empty();
+ CFSDrives *drivesFolderSpec = new CFSDrives;
+ CMyComPtr<IFolderFolder> drivesFolder = drivesFolderSpec;
+ drivesFolderSpec->Init();
+ *resultFolder = drivesFolder.Detach();
+ return S_OK;
+ }
+ UString parentPathReduced = parentPath.Left(pos);
+ parentPath = parentPath.Left(pos + 1);
+ pos = parentPathReduced.ReverseFind(L'\\');
+ if (pos == 1)
+ {
+ if (parentPath[0] != L'\\')
+ return E_FAIL;
+ CNetFolder *netFolderSpec = new CNetFolder;
+ CMyComPtr<IFolderFolder> netFolder = netFolderSpec;
+ netFolderSpec->Init(parentPath);
+ *resultFolder = netFolder.Detach();
+ return S_OK;
+ }
+ CFSFolder *parentFolderSpec = new CFSFolder;
+ CMyComPtr<IFolderFolder> parentFolder = parentFolderSpec;
+ RINOK(parentFolderSpec->Init(parentPath, 0));
+ *resultFolder = parentFolder.Detach();
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::GetName(BSTR * /* name */)
+{
+ return E_NOTIMPL;
+ /*
+ CMyComBSTR aBSTRName = m_ProxyFolderItem->m_Name;
+ *name = aBSTRName.Detach();
+ return S_OK;
+ */
+}
+
+STDMETHODIMP CFSFolder::GetNumberOfProperties(UInt32 *numProperties)
+{
+ *numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
+ if (!_flatMode)
+ (*numProperties)--;
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::GetPropertyInfo(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType)
+{
+ if (index >= sizeof(kProperties) / sizeof(kProperties[0]))
+ return E_INVALIDARG;
+ const STATPROPSTG &prop = kProperties[index];
+ *propID = prop.propid;
+ *varType = prop.vt;
+ *name = 0;
+ return S_OK;
+}
+
+
+STDMETHODIMP CFSFolder::GetTypeID(BSTR *name)
+{
+ CMyComBSTR temp = L"FSFolder";
+ *name = temp.Detach();
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::GetPath(BSTR *path)
+{
+ CMyComBSTR temp = _path;
+ *path = temp.Detach();
+ return S_OK;
+}
+
+
+STDMETHODIMP CFSFolder::WasChanged(INT32 *wasChanged)
+{
+ bool wasChangedMain = false;
+ for (;;)
+ {
+ if (!_findChangeNotification.IsHandleAllocated())
+ {
+ *wasChanged = BoolToInt(false);
+ return S_OK;
+ }
+
+ DWORD waitResult = ::WaitForSingleObject(_findChangeNotification, 0);
+ bool wasChangedLoc = (waitResult == WAIT_OBJECT_0);
+ if (wasChangedLoc)
+ {
+ _findChangeNotification.FindNext();
+ wasChangedMain = true;
+ }
+ else
+ break;
+ }
+ *wasChanged = BoolToInt(wasChangedMain);
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::Clone(IFolderFolder **resultFolder)
+{
+ CFSFolder *fsFolderSpec = new CFSFolder;
+ CMyComPtr<IFolderFolder> folderNew = fsFolderSpec;
+ fsFolderSpec->Init(_path, 0);
+ *resultFolder = folderNew.Detach();
+ return S_OK;
+}
+
+HRESULT CFSFolder::GetItemFullSize(int index, UInt64 &size, IProgress *progress)
+{
+ const CDirItem &fileInfo = *_refs[index];
+ if (fileInfo.IsDirectory())
+ {
+ /*
+ CMyComPtr<IFolderFolder> subFolder;
+ RINOK(BindToFolder(index, &subFolder));
+ CMyComPtr<IFolderReload> aFolderReload;
+ subFolder.QueryInterface(&aFolderReload);
+ aFolderReload->Reload();
+ UInt32 numItems;
+ RINOK(subFolder->GetNumberOfItems(&numItems));
+ CMyComPtr<IFolderGetItemFullSize> aGetItemFullSize;
+ subFolder.QueryInterface(&aGetItemFullSize);
+ for (UInt32 i = 0; i < numItems; i++)
+ {
+ UInt64 size;
+ RINOK(aGetItemFullSize->GetItemFullSize(i, &size));
+ *totalSize += size;
+ }
+ */
+ return GetFolderSize(_path + GetRelPath(fileInfo), size, progress);
+ }
+ size = fileInfo.Size;
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::GetItemFullSize(UInt32 index, PROPVARIANT *value, IProgress *progress)
+{
+ NCOM::CPropVariant propVariant;
+ if (index >= (UInt32)_refs.Size())
+ return E_INVALIDARG;
+ UInt64 size = 0;
+ HRESULT result = GetItemFullSize(index, size, progress);
+ propVariant = size;
+ propVariant.Detach(value);
+ return result;
+}
+
+HRESULT CFSFolder::GetComplexName(const wchar_t *name, UString &resultPath)
+{
+ UString newName = name;
+ resultPath = _path + newName;
+ if (newName.Length() < 1)
+ return S_OK;
+ if (newName[0] == L'\\')
+ {
+ resultPath = newName;
+ return S_OK;
+ }
+ if (newName.Length() < 2)
+ return S_OK;
+ if (newName[1] == L':')
+ resultPath = newName;
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::CreateFolder(const wchar_t *name, IProgress * /* progress */)
+{
+ UString processedName;
+ RINOK(GetComplexName(name, processedName));
+ if(NDirectory::MyCreateDirectory(processedName))
+ return S_OK;
+ if(::GetLastError() == ERROR_ALREADY_EXISTS)
+ return ::GetLastError();
+ if (!NDirectory::CreateComplexDirectory(processedName))
+ return ::GetLastError();
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::CreateFile(const wchar_t *name, IProgress * /* progress */)
+{
+ UString processedName;
+ RINOK(GetComplexName(name, processedName));
+ NIO::COutFile outFile;
+ if (!outFile.Create(processedName, false))
+ return ::GetLastError();
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::Rename(UInt32 index, const wchar_t *newName, IProgress * /* progress */)
+{
+ const CDirItem &fileInfo = *_refs[index];
+ const UString fullPrefix = _path + GetPrefix(fileInfo);
+ if (!NDirectory::MyMoveFile(fullPrefix + fileInfo.Name, fullPrefix + newName))
+ return GetLastError();
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::Delete(const UInt32 *indices, UInt32 numItems,IProgress *progress)
+{
+ RINOK(progress->SetTotal(numItems));
+ for (UInt32 i = 0; i < numItems; i++)
+ {
+ const CDirItem &fileInfo = *_refs[indices[i]];
+ const UString fullPath = _path + GetRelPath(fileInfo);
+ bool result;
+ if (fileInfo.IsDirectory())
+ result = NDirectory::RemoveDirectoryWithSubItems(fullPath);
+ else
+ result = NDirectory::DeleteFileAlways(fullPath);
+ if (!result)
+ return GetLastError();
+ UInt64 completed = i;
+ RINOK(progress->SetCompleted(&completed));
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::SetProperty(UInt32 index, PROPID propID,
+ const PROPVARIANT *value, IProgress * /* progress */)
+{
+ if (index >= (UInt32)_refs.Size())
+ return E_INVALIDARG;
+ CDirItem &fileInfo = *_refs[index];
+ if (fileInfo.Parent->Parent != 0)
+ return E_NOTIMPL;
+ switch(propID)
+ {
+ case kpidComment:
+ {
+ UString filename = fileInfo.Name;
+ filename.Trim();
+ if (value->vt == VT_EMPTY)
+ _comments.DeletePair(filename);
+ else if (value->vt == VT_BSTR)
+ {
+ CTextPair pair;
+ pair.ID = filename;
+ pair.ID.Trim();
+ pair.Value = value->bstrVal;
+ pair.Value.Trim();
+ if (pair.Value.IsEmpty())
+ _comments.DeletePair(filename);
+ else
+ _comments.AddPair(pair);
+ }
+ else
+ return E_INVALIDARG;
+ SaveComments();
+ break;
+ }
+ default:
+ return E_NOTIMPL;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::GetSystemIconIndex(UInt32 index, INT32 *iconIndex)
+{
+ if (index >= (UInt32)_refs.Size())
+ return E_INVALIDARG;
+ const CDirItem &fileInfo = *_refs[index];
+ *iconIndex = 0;
+ int iconIndexTemp;
+ if (GetRealIconIndex(_path + GetRelPath(fileInfo), fileInfo.Attributes, iconIndexTemp) != 0)
+ {
+ *iconIndex = iconIndexTemp;
+ return S_OK;
+ }
+ return GetLastError();
+}
+
+STDMETHODIMP CFSFolder::SetFlatMode(Int32 flatMode)
+{
+ _flatMode = IntToBool(flatMode);
+ return S_OK;
+}
+
+// static const LPCTSTR kInvalidFileChars = TEXT("\\/:*?\"<>|");
+
diff --git a/CPP/7zip/FileManager/FSFolder.h b/CPP/7zip/FileManager/FSFolder.h
new file mode 100755
index 00000000..4641c018
--- /dev/null
+++ b/CPP/7zip/FileManager/FSFolder.h
@@ -0,0 +1,141 @@
+// FSFolder.h
+
+#ifndef __FSFOLDER_H
+#define __FSFOLDER_H
+
+#include "Common/String.h"
+#include "Common/MyCom.h"
+#include "Windows/FileFind.h"
+#include "Windows/PropVariant.h"
+
+#include "IFolder.h"
+
+#include "TextPairs.h"
+
+class CFSFolder;
+
+struct CFileInfoEx: public NWindows::NFile::NFind::CFileInfoW
+{
+ bool CompressedSizeIsDefined;
+ UInt64 CompressedSize;
+};
+
+struct CDirItem;
+
+struct CDirItem: public CFileInfoEx
+{
+ CDirItem *Parent;
+ CObjectVector<CDirItem> Files;
+
+ CDirItem(): Parent(0) {}
+ void Clear()
+ {
+ Files.Clear();
+ Parent = 0;
+ }
+};
+
+class CFSFolder:
+ public IFolderFolder,
+ public IEnumProperties,
+ public IFolderGetTypeID,
+ public IFolderGetPath,
+ public IFolderWasChanged,
+ public IFolderOperations,
+ // public IFolderOperationsDeleteToRecycleBin,
+ public IFolderGetItemFullSize,
+ public IFolderClone,
+ public IFolderGetSystemIconIndex,
+ public IFolderSetFlatMode,
+ public CMyUnknownImp
+{
+ UInt64 GetSizeOfItem(int anIndex) const;
+public:
+ MY_QUERYINTERFACE_BEGIN
+ MY_QUERYINTERFACE_ENTRY(IEnumProperties)
+ 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)
+ MY_QUERYINTERFACE_ENTRY(IFolderGetSystemIconIndex)
+ MY_QUERYINTERFACE_ENTRY(IFolderSetFlatMode)
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
+
+
+ STDMETHOD(LoadItems)();
+ STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
+ STDMETHOD(GetProperty)(UInt32 itemIndex, PROPID propID, PROPVARIANT *value);
+ STDMETHOD(BindToFolder)(UInt32 index, IFolderFolder **resultFolder);
+ STDMETHOD(BindToFolder)(const wchar_t *name, IFolderFolder **resultFolder);
+ STDMETHOD(BindToParentFolder)(IFolderFolder **resultFolder);
+ STDMETHOD(GetName)(BSTR *name);
+
+ STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
+ STDMETHOD(GetPropertyInfo)(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType);
+ STDMETHOD(GetTypeID)(BSTR *name);
+ STDMETHOD(GetPath)(BSTR *path);
+ STDMETHOD(WasChanged)(INT32 *wasChanged);
+ STDMETHOD(Clone)(IFolderFolder **resultFolder);
+ STDMETHOD(GetItemFullSize)(UInt32 index, PROPVARIANT *value, IProgress *progress);
+
+ STDMETHOD(SetFlatMode)(Int32 flatMode);
+
+ // IFolderOperations
+
+ STDMETHOD(CreateFolder)(const wchar_t *name, IProgress *progress);
+ STDMETHOD(CreateFile)(const wchar_t *name, IProgress *progress);
+ STDMETHOD(Rename)(UInt32 index, const wchar_t *newName, IProgress *progress);
+ STDMETHOD(Delete)(const UInt32 *indices, UInt32 numItems, IProgress *progress);
+ STDMETHOD(CopyTo)(const UInt32 *indices, UInt32 numItems,
+ const wchar_t *path, IFolderOperationsExtractCallback *callback);
+ STDMETHOD(MoveTo)(const UInt32 *indices, UInt32 numItems,
+ const wchar_t *path, IFolderOperationsExtractCallback *callback);
+ STDMETHOD(CopyFrom)(const wchar_t *fromFolderPath,
+ const wchar_t **itemsPaths, UInt32 numItems, IProgress *progress);
+ STDMETHOD(SetProperty)(UInt32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress);
+ STDMETHOD(GetSystemIconIndex)(UInt32 index, INT32 *iconIndex);
+
+private:
+ UString _path;
+ CDirItem _root;
+ CRecordVector<CDirItem *> _refs;
+
+ CMyComPtr<IFolderFolder> _parentFolder;
+
+ bool _commentsAreLoaded;
+ CPairsStorage _comments;
+
+ bool _flatMode;
+
+ NWindows::NFile::NFind::CFindChangeNotification _findChangeNotification;
+
+ HRESULT GetItemFullSize(int index, UInt64 &size, IProgress *progress);
+ HRESULT GetComplexName(const wchar_t *name, UString &resultPath);
+ HRESULT BindToFolderSpec(const wchar_t *name, IFolderFolder **resultFolder);
+
+ bool LoadComments();
+ bool SaveComments();
+ HRESULT LoadSubItems(CDirItem &dirItem, const UString &path);
+ void AddRefs(CDirItem &dirItem);
+public:
+ HRESULT Init(const UString &path, IFolderFolder *parentFolder);
+
+ CFSFolder() : _flatMode(false) {}
+
+ UString GetPrefix(const CDirItem &item) const;
+ UString GetRelPath(const CDirItem &item) const;
+ UString GetRelPath(UInt32 index) const { return GetRelPath(*_refs[index]); }
+
+ void Clear()
+ {
+ _root.Clear();
+ _refs.Clear();
+ }
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/FSFolderCopy.cpp b/CPP/7zip/FileManager/FSFolderCopy.cpp
new file mode 100755
index 00000000..7566c8f2
--- /dev/null
+++ b/CPP/7zip/FileManager/FSFolderCopy.cpp
@@ -0,0 +1,490 @@
+// FSFolderCopy.cpp
+
+#include "StdAfx.h"
+
+#include <Winbase.h>
+
+#include "FSFolder.h"
+#include "Windows/FileDir.h"
+#include "Windows/Error.h"
+
+#include "Common/StringConvert.h"
+
+#include "../Common/FilePathAutoRename.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NFind;
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+/*
+static bool IsItWindows2000orHigher()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
+ (versionInfo.dwMajorVersion >= 5);
+}
+*/
+
+struct CProgressInfo
+{
+ UINT64 StartPos;
+ IProgress *Progress;
+};
+
+static DWORD CALLBACK CopyProgressRoutine(
+ LARGE_INTEGER /* TotalFileSize */, // file size
+ LARGE_INTEGER TotalBytesTransferred, // bytes transferred
+ LARGE_INTEGER /* StreamSize */, // bytes in stream
+ LARGE_INTEGER /* StreamBytesTransferred */, // bytes transferred for stream
+ DWORD /* dwStreamNumber */, // current stream
+ DWORD /* dwCallbackReason */, // callback reason
+ HANDLE /* hSourceFile */, // handle to source file
+ HANDLE /* hDestinationFile */, // handle to destination file
+ LPVOID lpData // from CopyFileEx
+)
+{
+ CProgressInfo &progressInfo = *(CProgressInfo *)lpData;
+ UINT64 completed = progressInfo.StartPos + TotalBytesTransferred.QuadPart;
+ if (progressInfo.Progress->SetCompleted(&completed) != S_OK)
+ return PROGRESS_CANCEL;
+ return PROGRESS_CONTINUE;
+}
+
+typedef BOOL (WINAPI * CopyFileExPointer)(
+ IN LPCSTR lpExistingFileName,
+ IN LPCSTR lpNewFileName,
+ IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL,
+ IN LPVOID lpData OPTIONAL,
+ IN LPBOOL pbCancel OPTIONAL,
+ IN DWORD dwCopyFlags
+ );
+
+typedef BOOL (WINAPI * CopyFileExPointerW)(
+ IN LPCWSTR lpExistingFileName,
+ IN LPCWSTR lpNewFileName,
+ IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL,
+ IN LPVOID lpData OPTIONAL,
+ IN LPBOOL pbCancel OPTIONAL,
+ IN DWORD dwCopyFlags
+ );
+
+#ifndef _UNICODE
+static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
+static CSysString GetSysPath(LPCWSTR sysPath)
+ { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); }
+#endif
+
+static bool MyCopyFile(LPCWSTR existingFile, LPCWSTR newFile,
+ IProgress *progress, UINT64 &completedSize)
+{
+ CProgressInfo progressInfo;
+ progressInfo.Progress = progress;
+ progressInfo.StartPos = completedSize;
+ BOOL CancelFlag = FALSE;
+ #ifndef _UNICODE
+ if (g_IsNT)
+ #endif
+ {
+ CopyFileExPointerW copyFunctionW = (CopyFileExPointerW)
+ ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"),
+ "CopyFileExW");
+ if (copyFunctionW == 0)
+ return false;
+ if (copyFunctionW(existingFile, newFile, CopyProgressRoutine,
+ &progressInfo, &CancelFlag, COPY_FILE_FAIL_IF_EXISTS))
+ return true;
+ #ifdef WIN_LONG_PATH
+ UString longPathExisting, longPathNew;
+ if (!NDirectory::GetLongPaths(existingFile, newFile, longPathExisting, longPathNew))
+ return false;
+ if (copyFunctionW(longPathExisting, longPathNew, CopyProgressRoutine,
+ &progressInfo, &CancelFlag, COPY_FILE_FAIL_IF_EXISTS))
+ return true;
+ #endif
+ return false;
+ }
+ #ifndef _UNICODE
+ else
+ {
+ CopyFileExPointer copyFunction = (CopyFileExPointer)
+ ::GetProcAddress(::GetModuleHandleA("kernel32.dll"),
+ "CopyFileExA");
+ if (copyFunction != 0)
+ {
+ if (copyFunction(GetSysPath(existingFile), GetSysPath(newFile),
+ CopyProgressRoutine,&progressInfo, &CancelFlag, COPY_FILE_FAIL_IF_EXISTS))
+ return true;
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return false;
+ }
+ return BOOLToBool(::CopyFile(GetSysPath(existingFile), GetSysPath(newFile), TRUE));
+ }
+ #endif
+}
+
+typedef BOOL (WINAPI * MoveFileWithProgressPointer)(
+ IN LPCWSTR lpExistingFileName,
+ IN LPCWSTR lpNewFileName,
+ IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL,
+ IN LPVOID lpData OPTIONAL,
+ IN DWORD dwFlags
+ );
+
+static bool MyMoveFile(LPCWSTR existingFile, LPCWSTR newFile,
+ IProgress *progress, UINT64 &completedSize)
+{
+ // if (IsItWindows2000orHigher())
+ // {
+ CProgressInfo progressInfo;
+ progressInfo.Progress = progress;
+ progressInfo.StartPos = completedSize;
+
+ MoveFileWithProgressPointer moveFunction = (MoveFileWithProgressPointer)
+ ::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")),
+ "MoveFileWithProgressW");
+ if (moveFunction != 0)
+ {
+ if (moveFunction(
+ existingFile, newFile, CopyProgressRoutine,
+ &progressInfo, MOVEFILE_COPY_ALLOWED))
+ return true;
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ {
+ #ifdef WIN_LONG_PATH
+ UString longPathExisting, longPathNew;
+ if (!NDirectory::GetLongPaths(existingFile, newFile, longPathExisting, longPathNew))
+ return false;
+ if (moveFunction(longPathExisting, longPathNew, CopyProgressRoutine,
+ &progressInfo, MOVEFILE_COPY_ALLOWED))
+ return true;
+ #endif
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return false;
+ }
+ }
+ // }
+ // else
+ return NDirectory::MyMoveFile(existingFile, newFile);
+}
+
+static HRESULT MyCopyFile(
+ const UString &srcPath,
+ const CFileInfoW &srcFileInfo,
+ const UString &destPathSpec,
+ IFolderOperationsExtractCallback *callback,
+ UINT64 &completedSize)
+{
+ UString destPath = destPathSpec;
+ if (destPath.CompareNoCase(srcPath) == 0)
+ {
+ UString message = UString(L"can not move file \'") + destPath + UString(L"\' onto itself");
+ RINOK(callback->ShowMessage(message));
+ return E_ABORT;
+ }
+
+ INT32 writeAskResult;
+ CMyComBSTR destPathResult;
+ RINOK(callback->AskWrite(
+ srcPath,
+ BoolToInt(false),
+ &srcFileInfo.LastWriteTime, &srcFileInfo.Size,
+ destPath,
+ &destPathResult,
+ &writeAskResult));
+ if (IntToBool(writeAskResult))
+ {
+ UString destPathNew = UString(destPathResult);
+ RINOK(callback->SetCurrentFilePath(srcPath));
+ if (!::MyCopyFile(srcPath, destPathNew, callback, completedSize))
+ {
+ UString message = NError::MyFormatMessageW(GetLastError()) +
+ UString(L" \'") +
+ UString(destPathNew) +
+ UString(L"\'");
+ RINOK(callback->ShowMessage(message));
+ return E_ABORT;
+ }
+ }
+ completedSize += srcFileInfo.Size;
+ return callback->SetCompleted(&completedSize);
+}
+
+static HRESULT CopyFolder(
+ const UString &srcPath,
+ const UString &destPathSpec,
+ IFolderOperationsExtractCallback *callback,
+ UINT64 &completedSize)
+{
+ RINOK(callback->SetCompleted(&completedSize));
+
+ UString destPath = destPathSpec;
+ int len = srcPath.Length();
+ if (destPath.Length() >= len && srcPath.CompareNoCase(destPath.Left(len)) == 0)
+ {
+ if (destPath.Length() == len || destPath[len] == L'\\')
+ {
+ UString message = UString(L"can not copy folder \'") +
+ destPath + UString(L"\' onto itself");
+ RINOK(callback->ShowMessage(message));
+ return E_ABORT;
+ }
+ }
+
+ if (!NDirectory::CreateComplexDirectory(destPath))
+ {
+ UString message = UString(L"can not create folder ") + destPath;
+ RINOK(callback->ShowMessage(message));
+ return E_ABORT;
+ }
+ CEnumeratorW enumerator(srcPath + UString(L"\\*"));
+ CFileInfoEx fileInfo;
+ while (enumerator.Next(fileInfo))
+ {
+ const UString srcPath2 = srcPath + UString(L"\\") + fileInfo.Name;
+ const UString destPath2 = destPath + UString(L"\\") + fileInfo.Name;
+ if (fileInfo.IsDirectory())
+ {
+ RINOK(CopyFolder(srcPath2, destPath2, callback, completedSize));
+ }
+ else
+ {
+ RINOK(MyCopyFile(srcPath2, fileInfo, destPath2, callback, completedSize));
+ }
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::CopyTo(const UInt32 *indices, UInt32 numItems,
+ const wchar_t *path, IFolderOperationsExtractCallback *callback)
+{
+ if (numItems == 0)
+ return S_OK;
+ UINT64 totalSize = 0;
+ UInt32 i;
+ for (i = 0; i < numItems; i++)
+ {
+ int index = indices[i];
+ if (index >= _refs.Size())
+ return E_INVALIDARG;
+ UINT64 size;
+ RINOK(GetItemFullSize(indices[i], size, callback));
+ totalSize += size;
+ }
+
+ callback->SetTotal(totalSize);
+ UString destPath = path;
+ if (destPath.IsEmpty())
+ return E_INVALIDARG;
+ bool directName = (destPath[destPath.Length() - 1] != L'\\');
+ if (directName)
+ {
+ if (numItems > 1)
+ return E_INVALIDARG;
+ }
+ /*
+ // doesn't work in network
+ else
+ if (!NDirectory::CreateComplexDirectory(destPath)))
+ {
+ DWORD lastError = ::GetLastError();
+ UString message = UString(L"can not create folder ") +
+ destPath;
+ RINOK(callback->ShowMessage(message));
+ return E_ABORT;
+ }
+ */
+
+ UINT64 completedSize = 0;
+ RINOK(callback->SetCompleted(&completedSize));
+ for (i = 0; i < numItems; i++)
+ {
+ const CDirItem &fileInfo = *_refs[indices[i]];
+ UString destPath2 = destPath;
+ if (!directName)
+ destPath2 += fileInfo.Name;
+ UString srcPath = _path + GetPrefix(fileInfo) + fileInfo.Name;
+ if (fileInfo.IsDirectory())
+ {
+ RINOK(CopyFolder(srcPath, destPath2, callback, completedSize));
+ }
+ else
+ {
+ RINOK(MyCopyFile(srcPath, fileInfo, destPath2, callback, completedSize));
+ }
+ }
+ return S_OK;
+}
+
+/////////////////////////////////////////////////
+// Move Operations
+
+HRESULT MyMoveFile(
+ const UString &srcPath,
+ const CFileInfoW &srcFileInfo,
+ const UString &destPathSpec,
+ IFolderOperationsExtractCallback *callback,
+ UINT64 &completedSize)
+{
+ UString destPath = destPathSpec;
+ if (destPath.CompareNoCase(srcPath) == 0)
+ {
+ UString message = UString(L"can not move file \'")
+ + destPath +
+ UString(L"\' onto itself");
+ RINOK(callback->ShowMessage(message));
+ return E_ABORT;
+ }
+
+ INT32 writeAskResult;
+ CMyComBSTR destPathResult;
+ RINOK(callback->AskWrite(
+ srcPath,
+ BoolToInt(false),
+ &srcFileInfo.LastWriteTime, &srcFileInfo.Size,
+ destPath,
+ &destPathResult,
+ &writeAskResult));
+ if (IntToBool(writeAskResult))
+ {
+ UString destPathNew = UString(destPathResult);
+ RINOK(callback->SetCurrentFilePath(srcPath));
+ if (!MyMoveFile(srcPath, destPathNew, callback, completedSize))
+ {
+ UString message = UString(L"can not move to file ") + destPathNew;
+ RINOK(callback->ShowMessage(message));
+ }
+ }
+ completedSize += srcFileInfo.Size;
+ RINOK(callback->SetCompleted(&completedSize));
+ return S_OK;
+}
+
+HRESULT MyMoveFolder(
+ const UString &srcPath,
+ const UString &destPathSpec,
+ IFolderOperationsExtractCallback *callback,
+ UINT64 &completedSize)
+{
+ UString destPath = destPathSpec;
+ int len = srcPath.Length();
+ if (destPath.Length() >= len && srcPath.CompareNoCase(destPath.Left(len)) == 0)
+ {
+ if (destPath.Length() == len || destPath[len] == L'\\')
+ {
+ UString message = UString(L"can not move folder \'") +
+ destPath + UString(L"\' onto itself");
+ RINOK(callback->ShowMessage(message));
+ return E_ABORT;
+ }
+ }
+
+ if (MyMoveFile(srcPath, destPath, callback, completedSize))
+ return S_OK;
+
+ if (!NDirectory::CreateComplexDirectory(destPath))
+ {
+ UString message = UString(L"can not create folder ") + destPath;
+ RINOK(callback->ShowMessage(message));
+ return E_ABORT;
+ }
+ {
+ CEnumeratorW enumerator(srcPath + UString(L"\\*"));
+ CFileInfoEx fileInfo;
+ while (enumerator.Next(fileInfo))
+ {
+ const UString srcPath2 = srcPath + UString(L"\\") + fileInfo.Name;
+ const UString destPath2 = destPath + UString(L"\\") + fileInfo.Name;
+ if (fileInfo.IsDirectory())
+ {
+ RINOK(MyMoveFolder(srcPath2, destPath2, callback, completedSize));
+ }
+ else
+ {
+ RINOK(MyMoveFile(srcPath2, fileInfo, destPath2, callback, completedSize));
+ }
+ }
+ }
+ if (!NDirectory::MyRemoveDirectory(srcPath))
+ {
+ UString message = UString(L"can not remove folder") + srcPath;
+ RINOK(callback->ShowMessage(message));
+ return E_ABORT;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::MoveTo(
+ const UInt32 *indices,
+ UInt32 numItems,
+ const wchar_t *path,
+ IFolderOperationsExtractCallback *callback)
+{
+ if (numItems == 0)
+ return S_OK;
+
+ UINT64 totalSize = 0;
+ UInt32 i;
+ for (i = 0; i < numItems; i++)
+ {
+ int index = indices[i];
+ if (index >= _refs.Size())
+ return E_INVALIDARG;
+ UINT64 size;
+ RINOK(GetItemFullSize(indices[i], size, callback));
+ totalSize += size;
+ }
+ callback->SetTotal(totalSize);
+
+ UString destPath = path;
+ if (destPath.IsEmpty())
+ return E_INVALIDARG;
+ bool directName = (destPath[destPath.Length() - 1] != L'\\');
+ if (directName)
+ {
+ if (numItems > 1)
+ return E_INVALIDARG;
+ }
+ else
+ if (!NDirectory::CreateComplexDirectory(destPath))
+ {
+ UString message = UString(L"can not create folder ") +
+ destPath;
+ RINOK(callback->ShowMessage(message));
+ return E_ABORT;
+ }
+
+ UINT64 completedSize = 0;
+ RINOK(callback->SetCompleted(&completedSize));
+ for (i = 0; i < numItems; i++)
+ {
+ const CDirItem &fileInfo = *_refs[indices[i]];
+ UString destPath2 = destPath;
+ if (!directName)
+ destPath2 += fileInfo.Name;
+ UString srcPath = _path + GetPrefix(fileInfo) + fileInfo.Name;
+ if (fileInfo.IsDirectory())
+ {
+ RINOK(MyMoveFolder(srcPath, destPath2, callback, completedSize));
+ }
+ else
+ {
+ RINOK(MyMoveFile(srcPath, fileInfo, destPath2, callback, completedSize));
+ }
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::CopyFrom(const wchar_t * /* fromFolderPath */,
+ const wchar_t ** /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */)
+{
+ return E_NOTIMPL;
+}
+
+
diff --git a/CPP/7zip/FileManager/FileFolderPluginOpen.cpp b/CPP/7zip/FileManager/FileFolderPluginOpen.cpp
new file mode 100755
index 00000000..3e3f40ba
--- /dev/null
+++ b/CPP/7zip/FileManager/FileFolderPluginOpen.cpp
@@ -0,0 +1,111 @@
+// FileFolderPluginOpen.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StringConvert.h"
+#include "Windows/Defs.h"
+#include "Windows/FileDir.h"
+#include "Windows/FileName.h"
+#include "Windows/DLL.h"
+
+#include "IFolder.h"
+#include "RegistryAssociations.h"
+#include "RegistryPlugins.h"
+
+#include "OpenCallback.h"
+#include "PluginLoader.h"
+
+using namespace NWindows;
+using namespace NRegistryAssociations;
+
+static int FindPlugin(const CObjectVector<CPluginInfo> &plugins,
+ const UString &pluginName)
+{
+ for (int i = 0; i < plugins.Size(); i++)
+ if (plugins[i].Name.CompareNoCase(pluginName) == 0)
+ return i;
+ return -1;
+}
+
+HRESULT OpenFileFolderPlugin(
+ const UString &path,
+ HMODULE *module,
+ IFolderFolder **resultFolder,
+ HWND parentWindow,
+ bool &encrypted)
+{
+ encrypted = false;
+ CObjectVector<CPluginInfo> plugins;
+ ReadFileFolderPluginInfoList(plugins);
+
+ UString extension;
+ UString name, pureName, dot;
+
+ if(!NFile::NDirectory::GetOnlyName(path, name))
+ return E_FAIL;
+ NFile::NName::SplitNameToPureNameAndExtension(name, pureName, dot, extension);
+
+
+ int slashPos = path.ReverseFind(L'\\');
+ UString dirPrefix;
+ UString fileName;
+ if (slashPos >= 0)
+ {
+ dirPrefix = path.Left(slashPos + 1);
+ fileName = path.Mid(slashPos + 1);
+ }
+ else
+ fileName = path;
+
+ if (!extension.IsEmpty())
+ {
+ CExtInfo extInfo;
+ if (ReadInternalAssociation(extension, extInfo))
+ {
+ for (int i = extInfo.Plugins.Size() - 1; i >= 0; i--)
+ {
+ int pluginIndex = FindPlugin(plugins, extInfo.Plugins[i]);
+ if (pluginIndex >= 0)
+ {
+ const CPluginInfo plugin = plugins[pluginIndex];
+ plugins.Delete(pluginIndex);
+ plugins.Insert(0, plugin);
+ }
+ }
+ }
+ }
+
+ for (int i = 0; i < plugins.Size(); i++)
+ {
+ const CPluginInfo &plugin = plugins[i];
+ CPluginLibrary library;
+ CMyComPtr<IFolderManager> folderManager;
+ CMyComPtr<IFolderFolder> folder;
+ HRESULT result = library.LoadAndCreateManager(
+ plugin.FilePath, plugin.ClassID, &folderManager);
+ if (result != S_OK)
+ continue;
+
+ COpenArchiveCallback *openCallbackSpec = new COpenArchiveCallback;
+ CMyComPtr<IProgress> openCallback = openCallbackSpec;
+ openCallbackSpec->PasswordIsDefined = false;
+ openCallbackSpec->ParentWindow = parentWindow;
+ openCallbackSpec->LoadFileInfo(dirPrefix, fileName);
+ result = folderManager->OpenFolderFile(path, &folder, openCallback);
+ if (openCallbackSpec->PasswordWasAsked)
+ encrypted = true;
+ if (result == S_OK)
+ {
+ *module = library.Detach();
+ *resultFolder = folder.Detach();
+ return S_OK;
+ }
+ continue;
+
+ /*
+ if (result != S_FALSE)
+ return result;
+ */
+ }
+ return S_FALSE;
+} \ No newline at end of file
diff --git a/CPP/7zip/FileManager/FileFolderPluginOpen.h b/CPP/7zip/FileManager/FileFolderPluginOpen.h
new file mode 100755
index 00000000..295048a9
--- /dev/null
+++ b/CPP/7zip/FileManager/FileFolderPluginOpen.h
@@ -0,0 +1,9 @@
+// FileFolderPluginOpen.h
+
+#ifndef __FILEFOLDERPLUGINOPEN_H
+#define __FILEFOLDERPLUGINOPEN_H
+
+HRESULT OpenFileFolderPlugin(const UString &path,
+ HMODULE *module, IFolderFolder **resultFolder, HWND parentWindow, bool &encrypted);
+
+#endif
diff --git a/CPP/7zip/FileManager/FilePlugins.cpp b/CPP/7zip/FileManager/FilePlugins.cpp
new file mode 100755
index 00000000..524b6aa7
--- /dev/null
+++ b/CPP/7zip/FileManager/FilePlugins.cpp
@@ -0,0 +1,113 @@
+// FilePlugins.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StringConvert.h"
+#include "Common/MyCom.h"
+
+#include "IFolder.h"
+#include "FilePlugins.h"
+#include "StringUtils.h"
+#include "PluginLoader.h"
+
+using namespace NRegistryAssociations;
+
+int CExtDatabase::FindExtInfoBig(const UString &ext)
+{
+ for (int i = 0; i < ExtBigItems.Size(); i++)
+ if (ExtBigItems[i].Ext.CompareNoCase(ext) == 0)
+ return i;
+ return -1;
+}
+
+int CExtDatabase::FindPlugin(const UString &plugin)
+{
+ for (int i = 0; i < Plugins.Size(); i++)
+ if (Plugins[i].Name.CompareNoCase(plugin) == 0)
+ return i;
+ return -1;
+}
+
+void CExtDatabase::Read()
+{
+ CObjectVector<CExtInfo> extItems;
+ ReadInternalAssociations(extItems);
+ ReadFileFolderPluginInfoList(Plugins);
+ for (int i = 0; i < extItems.Size(); i++)
+ {
+ const CExtInfo &extInfo = extItems[i];
+ CExtInfoBig extInfoBig;
+ extInfoBig.Ext = extInfo.Ext;
+ extInfoBig.Associated = false;
+ for (int p = 0; p < extInfo.Plugins.Size(); p++)
+ {
+ int pluginIndex = FindPlugin(extInfo.Plugins[p]);
+ if (pluginIndex >= 0)
+ extInfoBig.PluginsPairs.Add(CPluginEnabledPair(pluginIndex, true));
+ }
+ ExtBigItems.Add(extInfoBig);
+ }
+ for (int pluginIndex = 0; pluginIndex < Plugins.Size(); pluginIndex++)
+ {
+ const CPluginInfo &pluginInfo = Plugins[pluginIndex];
+ if (!pluginInfo.OptionsClassIDDefined)
+ continue;
+
+ CPluginLibrary pluginLibrary;
+ CMyComPtr<IFolderManager> folderManager;
+
+ if (pluginLibrary.LoadAndCreateManager(pluginInfo.FilePath,
+ pluginInfo.ClassID, &folderManager) != S_OK)
+ continue;
+ CMyComBSTR typesString;
+ if (folderManager->GetTypes(&typesString) != S_OK)
+ continue;
+ UStringVector types;
+ SplitString((const wchar_t *)typesString, types);
+ for (int typeIndex = 0; typeIndex < types.Size(); typeIndex++)
+ {
+ CMyComBSTR extTemp;
+ if (folderManager->GetExtension(types[typeIndex], &extTemp) != S_OK)
+ continue;
+ const UString ext = (const wchar_t *)extTemp;
+ int index = FindExtInfoBig(ext);
+ if (index < 0)
+ {
+ CExtInfoBig extInfo;
+ extInfo.PluginsPairs.Add(CPluginEnabledPair(pluginIndex, false));
+ extInfo.Associated = false;
+ extInfo.Ext = ext;
+ ExtBigItems.Add(extInfo);
+ }
+ else
+ {
+ CExtInfoBig &extInfo = ExtBigItems[index];
+ int pluginIndexIndex = extInfo.FindPlugin(pluginIndex);
+ if (pluginIndexIndex < 0)
+ extInfo.PluginsPairs.Add(CPluginEnabledPair(pluginIndex, false));
+ }
+ }
+ }
+}
+
+void CExtDatabase::Save()
+{
+ CObjectVector<CExtInfo> extItems;
+ for (int i = 0; i < ExtBigItems.Size(); i++)
+ {
+ const CExtInfoBig &extInfoBig = ExtBigItems[i];
+ CExtInfo extInfo;
+ // extInfo.Enabled = extInfoBig.Associated;
+ extInfo.Ext = extInfoBig.Ext;
+ for (int p = 0; p < extInfoBig.PluginsPairs.Size(); p++)
+ {
+ CPluginEnabledPair pluginPair = extInfoBig.PluginsPairs[p];
+ if (pluginPair.Enabled)
+ extInfo.Plugins.Add(Plugins[pluginPair.Index].Name);
+ }
+ extItems.Add(extInfo);
+ }
+ WriteInternalAssociations(extItems);
+}
+
+
diff --git a/CPP/7zip/FileManager/FilePlugins.h b/CPP/7zip/FileManager/FilePlugins.h
new file mode 100755
index 00000000..805cac2a
--- /dev/null
+++ b/CPP/7zip/FileManager/FilePlugins.h
@@ -0,0 +1,54 @@
+// FilePlugins.h
+
+#ifndef __FILEPLUGINS_H
+#define __FILEPLUGINS_H
+
+#include "RegistryPlugins.h"
+#include "RegistryAssociations.h"
+
+struct CPluginEnabledPair
+{
+ int Index;
+ bool Enabled;
+ CPluginEnabledPair(int index, bool enabled): Index(index),Enabled(enabled) {}
+};
+
+struct CExtInfoBig
+{
+ UString Ext;
+ bool Associated;
+ CRecordVector<CPluginEnabledPair> PluginsPairs;
+ int FindPlugin(int pluginIndex)
+ {
+ for (int i = 0; i < PluginsPairs.Size(); i++)
+ if (PluginsPairs[i].Index == pluginIndex)
+ return i;
+ return -1;
+ }
+};
+
+class CExtDatabase
+{
+public:
+ CObjectVector<CExtInfoBig> ExtBigItems;
+ CObjectVector<CPluginInfo> Plugins;
+ int FindExtInfoBig(const UString &ext);
+ int FindPlugin(const UString &plugin);
+
+ UString GetMainPluginNameForExtItem(int extIndex) const
+ {
+ const CExtInfoBig &extInfo = ExtBigItems[extIndex];
+ if (extInfo.PluginsPairs.IsEmpty())
+ return UString();
+ else
+ return Plugins[extInfo.PluginsPairs.Front().Index].Name;
+ }
+
+ void Read();
+ void Save();
+};
+
+
+#endif
+
+
diff --git a/CPP/7zip/FileManager/FormatUtils.cpp b/CPP/7zip/FileManager/FormatUtils.cpp
new file mode 100755
index 00000000..553d8bcd
--- /dev/null
+++ b/CPP/7zip/FileManager/FormatUtils.cpp
@@ -0,0 +1,40 @@
+// FormatUtils.cpp
+
+#include "StdAfx.h"
+
+#include "FormatUtils.h"
+#include "Common/IntToString.h"
+#include "Windows/ResourceString.h"
+
+#ifdef LANG
+#include "LangUtils.h"
+#endif
+
+UString NumberToString(UInt64 number)
+{
+ wchar_t numberString[32];
+ ConvertUInt64ToString(number, numberString);
+ return numberString;
+}
+
+UString MyFormatNew(const UString &format, const UString &argument)
+{
+ UString result = format;
+ result.Replace(L"{0}", argument);
+ return result;
+}
+
+UString MyFormatNew(UINT resourceID,
+ #ifdef LANG
+ UInt32 langID,
+ #endif
+ const UString &argument)
+{
+ return MyFormatNew(
+ #ifdef LANG
+ LangString(resourceID, langID),
+ #else
+ NWindows::MyLoadStringW(resourceID),
+ #endif
+ argument);
+}
diff --git a/CPP/7zip/FileManager/FormatUtils.h b/CPP/7zip/FileManager/FormatUtils.h
new file mode 100755
index 00000000..f7e9b193
--- /dev/null
+++ b/CPP/7zip/FileManager/FormatUtils.h
@@ -0,0 +1,18 @@
+// FormatUtils.h
+
+#ifndef __FORMATUTILS_H
+#define __FORMATUTILS_H
+
+#include "Common/Types.h"
+#include "Common/String.h"
+
+UString NumberToString(UInt64 number);
+
+UString MyFormatNew(const UString &format, const UString &argument);
+UString MyFormatNew(UINT resourceID,
+ #ifdef LANG
+ UInt32 langID,
+ #endif
+ const UString &argument);
+
+#endif
diff --git a/CPP/7zip/FileManager/HelpUtils.cpp b/CPP/7zip/FileManager/HelpUtils.cpp
new file mode 100755
index 00000000..c2bf49a5
--- /dev/null
+++ b/CPP/7zip/FileManager/HelpUtils.cpp
@@ -0,0 +1,23 @@
+// HelpUtils.cpp
+
+#include "StdAfx.h"
+
+#include <HtmlHelp.h>
+
+#include "Common/StringConvert.h"
+#include "HelpUtils.h"
+#include "ProgramLocation.h"
+
+static LPCWSTR kHelpFileName = L"7-zip.chm::/";
+
+void ShowHelpWindow(HWND hwnd, LPCWSTR topicFile)
+{
+ UString path;
+ if (!::GetProgramFolderPath(path))
+ return;
+ path += kHelpFileName;
+ path += topicFile;
+ HtmlHelp(hwnd, GetSystemString(path), HH_DISPLAY_TOPIC, NULL);
+}
+
+
diff --git a/CPP/7zip/FileManager/HelpUtils.h b/CPP/7zip/FileManager/HelpUtils.h
new file mode 100755
index 00000000..b993f09b
--- /dev/null
+++ b/CPP/7zip/FileManager/HelpUtils.h
@@ -0,0 +1,10 @@
+// HelpUtils.h
+
+#ifndef __HELPUTILS_H
+#define __HELPUTILS_H
+
+#include "Common/String.h"
+
+void ShowHelpWindow(HWND hwnd, LPCWSTR topicFile);
+
+#endif
diff --git a/CPP/7zip/FileManager/IFolder.h b/CPP/7zip/FileManager/IFolder.h
new file mode 100755
index 00000000..aa50a39d
--- /dev/null
+++ b/CPP/7zip/FileManager/IFolder.h
@@ -0,0 +1,190 @@
+// FolderInterface.h
+
+#ifndef __FOLDERINTERFACE_H
+#define __FOLDERINTERFACE_H
+
+#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
+ {
+ kName = 0,
+ kType,
+ kClassID,
+ kOptionsClassID
+ };
+}
+
+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) PURE;
+};
+
+FOLDER_INTERFACE(IFolderGetTypeID, 0x02)
+{
+ STDMETHOD(GetTypeID)(BSTR *name) PURE;
+};
+
+FOLDER_INTERFACE(IFolderGetPath, 0x03)
+{
+ STDMETHOD(GetPath)(BSTR *path) PURE;
+};
+
+FOLDER_INTERFACE(IFolderWasChanged, 0x04)
+{
+ STDMETHOD(WasChanged)(Int32 *wasChanged) PURE;
+};
+
+/*
+FOLDER_INTERFACE(IFolderReload, 0x05)
+{
+ STDMETHOD(Reload)() PURE;
+};
+*/
+
+FOLDER_INTERFACE_SUB(IFolderOperationsExtractCallback, IProgress, 0x06, 0x01)
+{
+ STDMETHOD(AskWrite)(
+ const wchar_t *srcPath,
+ Int32 srcIsFolder,
+ const FILETIME *srcTime,
+ const UInt64 *srcSize,
+ const wchar_t *destPathRequest,
+ BSTR *destPathResult,
+ Int32 *writeAnswer) PURE;
+ STDMETHOD(ShowMessage)(const wchar_t *message) PURE;
+ STDMETHOD(SetCurrentFilePath)(const wchar_t *filePath) PURE;
+};
+
+/*
+FOLDER_INTERFACE_SUB(IFolderOperationsUpdateCallback, IProgress, 0x06, 0x02)
+{
+ STDMETHOD(AskOverwrite)(
+ const wchar_t *srcPath,
+ Int32 destIsFolder,
+ const FILETIME *destTime,
+ const UInt64 *destSize,
+ const wchar_t *aDestPathRequest,
+ const wchar_t *aDestName,
+ BSTR *aDestPathResult,
+ Int32 *aResult);
+};
+*/
+
+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) PURE;
+ STDMETHOD(MoveTo)(const UInt32 *indices, UInt32 numItems,
+ const wchar_t *path, IFolderOperationsExtractCallback *callback) PURE;
+ STDMETHOD(CopyFrom)(const wchar_t *fromFolderPath,
+ const wchar_t **itemsPaths, UInt32 numItems, IProgress *progress) PURE;
+ STDMETHOD(SetProperty)(UInt32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress) PURE;
+};
+
+/*
+FOLDER_INTERFACE2(IFolderOperationsDeleteToRecycleBin, 0x06, 0x03)
+{
+ STDMETHOD(DeleteToRecycleBin)(const UInt32 *indices, UInt32 numItems, IProgress *progress) PURE;
+};
+*/
+
+FOLDER_INTERFACE(IFolderGetSystemIconIndex, 0x07)
+{
+ STDMETHOD(GetSystemIconIndex)(UInt32 index, Int32 *iconIndex) PURE;
+};
+
+FOLDER_INTERFACE(IFolderGetItemFullSize, 0x08)
+{
+ STDMETHOD(GetItemFullSize)(UInt32 index, PROPVARIANT *value, IProgress *progress) PURE;
+};
+
+FOLDER_INTERFACE(IFolderClone, 0x09)
+{
+ STDMETHOD(Clone)(IFolderFolder **resultFolder) PURE;
+};
+
+FOLDER_INTERFACE(IFolderSetFlatMode, 0x0A)
+{
+ STDMETHOD(SetFlatMode)(Int32 flatMode) PURE;
+};
+
+/*
+FOLDER_INTERFACE(IFolderOpen, 0x10)
+{
+ STDMETHOD(FolderOpen)(
+ const wchar_t *aFileName,
+ // IArchiveHandler100 **anArchiveHandler,
+ // NZipRootRegistry::CArchiverInfo &anArchiverInfoResult,
+ // UString &aDefaultName,
+ IOpenArchive2CallBack *anOpenArchive2CallBack) PURE;
+};
+*/
+
+#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) 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;
+};
+
+FOLDER_MANAGER_INTERFACE(IFolderManagerGetIconPath, 0x01)
+{
+ STDMETHOD(GetIconPath)(const wchar_t *type, BSTR *iconPath) PURE;
+};
+
+/*
+FOLDER_INTERFACE(IFolderExtract, 0x05, 0x0A);
+{
+ STDMETHOD(Clone)(IFolderFolder **aFolder) PURE;
+};
+
+FOLDER_INTERFACE(IFolderChangeNotify,0x05, 0x04, 0x00);
+IFolderChangeNotify: public IUnknown
+{
+ STDMETHOD(OnChanged)() PURE;
+};
+
+FOLDER_INTERFACE(IFolderSetChangeNotify, 0x05, 0x05);
+{
+ STDMETHOD(SetChangeNotify)(IFolderChangeNotify *aChangeNotify) PURE;
+};
+*/
+
+
+#endif
diff --git a/CPP/7zip/FileManager/Info.bmp b/CPP/7zip/FileManager/Info.bmp
new file mode 100755
index 00000000..d769a661
--- /dev/null
+++ b/CPP/7zip/FileManager/Info.bmp
Binary files differ
diff --git a/CPP/7zip/FileManager/Info2.bmp b/CPP/7zip/FileManager/Info2.bmp
new file mode 100755
index 00000000..af724d27
--- /dev/null
+++ b/CPP/7zip/FileManager/Info2.bmp
Binary files differ
diff --git a/CPP/7zip/FileManager/LangUtils.cpp b/CPP/7zip/FileManager/LangUtils.cpp
new file mode 100755
index 00000000..decff306
--- /dev/null
+++ b/CPP/7zip/FileManager/LangUtils.cpp
@@ -0,0 +1,185 @@
+// LangUtils.cpp
+
+#include "StdAfx.h"
+
+#include "LangUtils.h"
+#include "Common/StringConvert.h"
+#include "Common/StringToInt.h"
+#include "Windows/Synchronization.h"
+#include "Windows/Window.h"
+#include "Windows/FileFind.h"
+#include "RegistryUtils.h"
+#include "ProgramLocation.h"
+
+using namespace NWindows;
+
+static CLang g_Lang;
+UString g_LangID;
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+void ReloadLang()
+{
+ ReadRegLang(g_LangID);
+ g_Lang.Clear();
+ if (!g_LangID.IsEmpty() && g_LangID != L"-")
+ {
+ UString langPath = g_LangID;
+ if (langPath.Find('\\') < 0)
+ {
+ if (langPath.Find('.') < 0)
+ langPath += L".txt";
+ UString folderPath;
+ if (GetProgramFolderPath(folderPath))
+ langPath = folderPath + UString(L"Lang\\") + langPath;
+ }
+ g_Lang.Open(GetSystemString(langPath));
+ }
+}
+
+static bool g_Loaded = false;
+static NSynchronization::CCriticalSection g_CriticalSection;
+
+void LoadLangOneTime()
+{
+ NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
+ if (g_Loaded)
+ return;
+ g_Loaded = true;
+ ReloadLang();
+}
+
+void LangSetDlgItemsText(HWND dialogWindow, CIDLangPair *idLangPairs, int numItems)
+{
+ for (int i = 0; i < numItems; i++)
+ {
+ const CIDLangPair &idLangPair = idLangPairs[i];
+ UString message;
+ if (g_Lang.GetMessage(idLangPair.LangID, message))
+ {
+ NWindows::CWindow window(GetDlgItem(dialogWindow, idLangPair.ControlID));
+ window.SetText(message);
+ }
+ }
+}
+
+void LangSetWindowText(HWND window, UInt32 langID)
+{
+ UString message;
+ if (g_Lang.GetMessage(langID, message))
+ MySetWindowText(window, message);
+}
+
+UString LangString(UInt32 langID)
+{
+ UString message;
+ if (g_Lang.GetMessage(langID, message))
+ return message;
+ return UString();
+}
+
+UString LangString(UINT resourceID, UInt32 langID)
+{
+ UString message;
+ if (g_Lang.GetMessage(langID, message))
+ return message;
+ return NWindows::MyLoadStringW(resourceID);
+}
+
+void LoadLangs(CObjectVector<CLangEx> &langs)
+{
+ langs.Clear();
+ UString folderPath;
+ if (!::GetProgramFolderPath(folderPath))
+ return;
+ folderPath += L"Lang\\";
+ NWindows::NFile::NFind::CEnumeratorW enumerator(folderPath + L"*.txt");
+ NWindows::NFile::NFind::CFileInfoW fileInfo;
+ while (enumerator.Next(fileInfo))
+ {
+ if (fileInfo.IsDirectory())
+ continue;
+ CLangEx lang;
+ UString filePath = folderPath + fileInfo.Name;
+ const int kExtSize = 4;
+ if (fileInfo.Name.Right(kExtSize) != L".txt")
+ continue;
+ lang.ShortName = fileInfo.Name.Left(fileInfo.Name.Length() - kExtSize);
+ if (lang.Lang.Open(GetSystemString(filePath)))
+ langs.Add(lang);
+ }
+}
+
+bool SplidID(const UString &id, WORD &primID, WORD &subID)
+{
+ primID = 0;
+ subID = 0;
+ const wchar_t *start = id;
+ const wchar_t *end;
+ UInt64 value = ConvertStringToUInt64(start, &end);
+ if (start == end)
+ return false;
+ primID = (WORD)value;
+ if (*end == 0)
+ return true;
+ if (*end != L'-')
+ return false;
+ start = end + 1;
+ value = ConvertStringToUInt64(start, &end);
+ if (start == end)
+ return false;
+ subID = (WORD)value;
+ return (*end == 0);
+}
+
+void FindMatchLang(UString &shortName)
+{
+ shortName.Empty();
+ LANGID langID = GetUserDefaultLangID();
+ WORD primLang = (WORD)(PRIMARYLANGID(langID));
+ WORD subLang = (WORD)(SUBLANGID(langID));
+ CObjectVector<CLangEx> langs;
+ LoadLangs(langs);
+ for (int i = 0; i < langs.Size(); i++)
+ {
+ const CLangEx &lang = langs[i];
+ UString id;
+ if (lang.Lang.GetMessage(0x00000002, id))
+ {
+ WORD primID;
+ WORD subID;
+ if (SplidID(id, primID, subID))
+ if (primID == primLang)
+ {
+ if (subID == 0)
+ shortName = lang.ShortName;
+ if (subLang == subID)
+ {
+ shortName = lang.ShortName;
+ return;
+ }
+ }
+ }
+ }
+}
+
+void ReloadLangSmart()
+{
+ #ifndef _UNICODE
+ if (g_IsNT)
+ #endif
+ {
+ ReadRegLang(g_LangID);
+ if (g_LangID.IsEmpty())
+ {
+ UString shortName;
+ FindMatchLang(shortName);
+ if (shortName.IsEmpty())
+ shortName = L"-";
+ SaveRegLang(shortName);
+ }
+ }
+ ReloadLang();
+}
diff --git a/CPP/7zip/FileManager/LangUtils.h b/CPP/7zip/FileManager/LangUtils.h
new file mode 100755
index 00000000..40debdfe
--- /dev/null
+++ b/CPP/7zip/FileManager/LangUtils.h
@@ -0,0 +1,41 @@
+// LangUtils.h
+
+#ifndef __LANGUTILS_H
+#define __LANGUTILS_H
+
+#include "Common/Lang.h"
+#include "Windows/ResourceString.h"
+
+extern UString g_LangID;
+
+struct CIDLangPair
+{
+ int ControlID;
+ UInt32 LangID;
+};
+
+void ReloadLang();
+void LoadLangOneTime();
+void ReloadLangSmart();
+
+struct CLangEx
+{
+ CLang Lang;
+ UString ShortName;
+};
+
+void LoadLangs(CObjectVector<CLangEx> &langs);
+
+void LangSetDlgItemsText(HWND dialogWindow, CIDLangPair *idLangPairs, int numItems);
+void LangSetWindowText(HWND window, UInt32 langID);
+
+UString LangString(UInt32 langID);
+UString LangString(UINT resourceID, UInt32 langID);
+
+#ifdef LANG
+#define LangStringSpec(resourceID, langID) LangString(resourceID, langID)
+#else
+#define LangStringSpec(resourceID, langID) NWindows::MyLoadStringW(resourceID)
+#endif
+
+#endif
diff --git a/CPP/7zip/FileManager/Move.bmp b/CPP/7zip/FileManager/Move.bmp
new file mode 100755
index 00000000..eb5f20f9
--- /dev/null
+++ b/CPP/7zip/FileManager/Move.bmp
Binary files differ
diff --git a/CPP/7zip/FileManager/Move2.bmp b/CPP/7zip/FileManager/Move2.bmp
new file mode 100755
index 00000000..58679eff
--- /dev/null
+++ b/CPP/7zip/FileManager/Move2.bmp
Binary files differ
diff --git a/CPP/7zip/FileManager/MyCom2.h b/CPP/7zip/FileManager/MyCom2.h
new file mode 100755
index 00000000..756a8169
--- /dev/null
+++ b/CPP/7zip/FileManager/MyCom2.h
@@ -0,0 +1,48 @@
+// MyCom2.h
+
+#ifndef __MYCOM2_H
+#define __MYCOM2_H
+
+#include "Common/MyCom.h"
+
+#define MY_ADDREF_RELEASE_MT \
+STDMETHOD_(ULONG, AddRef)() { InterlockedIncrement((LONG *)&__m_RefCount); return __m_RefCount; } \
+STDMETHOD_(ULONG, Release)() { InterlockedDecrement((LONG *)&__m_RefCount); if (__m_RefCount != 0) \
+ return __m_RefCount; delete this; return 0; }
+
+#define MY_UNKNOWN_IMP_SPEC_MT(i) \
+ MY_QUERYINTERFACE_BEGIN \
+ MY_QUERYINTERFACE_ENTRY(IUnknown) \
+ i \
+ MY_QUERYINTERFACE_END \
+ MY_ADDREF_RELEASE_MT
+
+#define MY_UNKNOWN_IMP_SPEC_MT2(i1, i) \
+ MY_QUERYINTERFACE_BEGIN \
+ if (iid == IID_IUnknown) \
+ { *outObject = (void *)(IUnknown *)(i1 *)this; AddRef(); return S_OK; } i \
+ MY_QUERYINTERFACE_END \
+ MY_ADDREF_RELEASE_MT
+
+
+#define MY_UNKNOWN_IMP_MT MY_UNKNOWN_IMP_SPEC_MT(;)
+
+#define MY_UNKNOWN_IMP1_MT(i) MY_UNKNOWN_IMP_SPEC_MT2( \
+ i, \
+ MY_QUERYINTERFACE_ENTRY(i) \
+ )
+
+#define MY_UNKNOWN_IMP2_MT(i1, i2) MY_UNKNOWN_IMP_SPEC_MT2( \
+ i1, \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ )
+
+#define MY_UNKNOWN_IMP3_MT(i1, i2, i3) MY_UNKNOWN_IMP_SPEC_MT2( \
+ i1, \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ )
+
+#endif
diff --git a/CPP/7zip/FileManager/MyLoadMenu.cpp b/CPP/7zip/FileManager/MyLoadMenu.cpp
new file mode 100755
index 00000000..8be1e28f
--- /dev/null
+++ b/CPP/7zip/FileManager/MyLoadMenu.cpp
@@ -0,0 +1,694 @@
+// MyLoadMenu
+
+#include "StdAfx.h"
+
+#include "Common/StringConvert.h"
+
+#include "Windows/Menu.h"
+#include "Windows/Error.h"
+
+#include "../PropID.h"
+
+#include "resource.h"
+#include "App.h"
+#include "Resource/AboutDialog/AboutDialog.h"
+#include "Resource/BenchmarkDialog/BenchmarkDialog.h"
+
+#include "HelpUtils.h"
+#include "LangUtils.h"
+#include "PluginInterface.h"
+
+static const UINT kOpenBookmarkMenuID = 730;
+static const UINT kSetBookmarkMenuID = 740;
+
+extern HINSTANCE g_hInstance;
+
+static LPCWSTR kFMHelpTopic = L"FM/index.htm";
+
+extern void OptionsDialog(HWND hwndOwner, HINSTANCE hInstance);
+
+using namespace NWindows;
+
+static const int kFileMenuIndex = 0;
+static const int kViewMenuIndex = 2;
+static const int kBookmarksMenuIndex = kViewMenuIndex + 1;
+
+struct CStringLangPair
+{
+ wchar_t *String;
+ UINT32 LangID;
+};
+
+static CStringLangPair kStringLangPairs[] =
+{
+ { L"&File", 0x03000102 },
+ { L"&Edit", 0x03000103 },
+ { L"&View", 0x03000104 },
+ { L"&Bookmarks", 0x03000107 },
+ { L"&Tools", 0x03000105 },
+ { L"&Help", 0x03000106 },
+};
+
+UINT32 kAddToFavoritesLangID = 0x03000710;
+UINT32 kToolbarsLangID = 0x03000451;
+
+/*
+static int FindStringLangItem(const UString &anItem)
+{
+ for (int i = 0; i < sizeof(kStringLangPairs) /
+ sizeof(kStringLangPairs[0]); i++)
+ if (anItem.CompareNoCase(kStringLangPairs[i].String) == 0)
+ return i;
+ return -1;
+}
+*/
+
+static CIDLangPair kIDLangPairs[] =
+{
+ // File
+ { IDM_FILE_OPEN, 0x03000210 },
+ { IDM_FILE_OPEN_INSIDE, 0x03000211 },
+ { IDM_FILE_OPEN_OUTSIDE, 0x03000212 },
+ { IDM_FILE_VIEW, 0x03000220 },
+ { IDM_FILE_EDIT, 0x03000221 },
+ { IDM_RENAME, 0x03000230 },
+ { IDM_COPY_TO, 0x03000231 },
+ { IDM_MOVE_TO, 0x03000232 },
+ { IDM_DELETE, 0x03000233 },
+ { IDM_FILE_PROPERTIES, 0x03000240 },
+ { IDM_FILE_COMMENT, 0x03000241 },
+ { IDM_FILE_CRC, 0x03000242 },
+ { IDM_FILE_SPLIT, 0x03000270 },
+ { IDM_FILE_COMBINE, 0x03000271 },
+ { IDM_CREATE_FOLDER, 0x03000250 },
+ { IDM_CREATE_FILE, 0x03000251 },
+ { IDCLOSE, 0x03000260 },
+
+ // Edit
+ { IDM_EDIT_CUT, 0x03000320 },
+ { IDM_EDIT_COPY, 0x03000321 },
+ { IDM_EDIT_PASTE, 0x03000322 },
+
+ { IDM_SELECT_ALL, 0x03000330 },
+ { IDM_DESELECT_ALL, 0x03000331 },
+ { IDM_INVERT_SELECTION, 0x03000332 },
+ { IDM_SELECT, 0x03000333 },
+ { IDM_DESELECT, 0x03000334 },
+ { IDM_SELECT_BY_TYPE, 0x03000335 },
+ { IDM_DESELECT_BY_TYPE, 0x03000336 },
+
+ { IDM_VIEW_LARGE_ICONS, 0x03000410 },
+ { IDM_VIEW_SMALL_ICONS, 0x03000411 },
+ { IDM_VIEW_LIST, 0x03000412 },
+ { IDM_VIEW_DETAILS, 0x03000413 },
+
+ { IDM_VIEW_ARANGE_BY_NAME, 0x02000204 },
+ { IDM_VIEW_ARANGE_BY_TYPE, 0x02000214 },
+ { IDM_VIEW_ARANGE_BY_DATE, 0x0200020C },
+ { IDM_VIEW_ARANGE_BY_SIZE, 0x02000207 },
+ { IDM_VIEW_ARANGE_NO_SORT, 0x03000420 },
+
+ { IDM_OPEN_ROOT_FOLDER, 0x03000430 },
+ { IDM_OPEN_PARENT_FOLDER, 0x03000431 },
+ { IDM_FOLDERS_HISTORY, 0x03000432 },
+
+ { IDM_VIEW_REFRESH, 0x03000440 },
+
+ { IDM_VIEW_FLAT_VIEW, 0x03000449 },
+ { IDM_VIEW_TWO_PANELS, 0x03000450 },
+ { IDM_VIEW_ARCHIVE_TOOLBAR, 0x03000460 },
+ { IDM_VIEW_STANDARD_TOOLBAR, 0x03000461 },
+ { IDM_VIEW_TOOLBARS_LARGE_BUTTONS, 0x03000462 },
+ { IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT, 0x03000463 },
+
+ { IDM_OPTIONS, 0x03000510 },
+ { IDM_BENCHMARK, 0x03000511 },
+
+ { IDM_HELP_CONTENTS, 0x03000610 },
+ { IDM_ABOUT, 0x03000620 }
+};
+
+
+static int FindLangItem(int ControlID)
+{
+ for (int i = 0; i < sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]); i++)
+ if (kIDLangPairs[i].ControlID == ControlID)
+ return i;
+ return -1;
+}
+
+
+/*
+static bool g_IsNew_fMask = true;
+
+class CInit_fMask
+{
+public:
+ CInit_fMask()
+ {
+ g_IsNew_fMask = false;
+ OSVERSIONINFO vi;
+ vi.dwOSVersionInfoSize = sizeof(vi);
+ if (::GetVersionEx(&vi))
+ {
+ g_IsNew_fMask = (vi.dwMajorVersion > 4 ||
+ (vi.dwMajorVersion == 4 && vi.dwMinorVersion > 0));
+ }
+ g_IsNew_fMask = false;
+ }
+} g_Init_fMask;
+
+// it's hack for supporting Windows NT
+// constants are from WinUser.h
+
+#if(WINVER < 0x0500)
+#define MIIM_STRING 0x00000040
+#define MIIM_BITMAP 0x00000080
+#define MIIM_FTYPE 0x00000100
+#endif
+
+static UINT Get_fMaskForString()
+{
+ return g_IsNew_fMask ? MIIM_STRING : MIIM_TYPE;
+}
+
+static UINT Get_fMaskForFTypeAndString()
+{
+ return g_IsNew_fMask ? (MIIM_STRING | MIIM_FTYPE) : MIIM_TYPE;
+}
+*/
+
+static UINT Get_fMaskForString()
+{
+ return MIIM_TYPE;
+}
+
+static UINT Get_fMaskForFTypeAndString()
+{
+ return MIIM_TYPE;
+}
+
+
+
+static void MyChangeMenu(HMENU menuLoc, int level, int menuIndex)
+{
+ CMenu menu;
+ menu.Attach(menuLoc);
+ for (int i = 0; i < menu.GetItemCount(); i++)
+ {
+ CMenuItem item;
+ item.fMask = Get_fMaskForString() | MIIM_SUBMENU | MIIM_ID;
+ item.fType = MFT_STRING;
+ if (menu.GetItem(i, true, item))
+ {
+ UString newString;
+ if (item.hSubMenu)
+ {
+ if (level == 1 && menuIndex == kBookmarksMenuIndex)
+ newString = LangString(kAddToFavoritesLangID);
+ else
+ {
+ MyChangeMenu(item.hSubMenu, level + 1, i);
+ if (level == 1 && menuIndex == kViewMenuIndex)
+ {
+ newString = LangString(kToolbarsLangID);
+ }
+ else
+ {
+ if (level == 0 && i < sizeof(kStringLangPairs) /
+ sizeof(kStringLangPairs[0]))
+ newString = LangString(kStringLangPairs[i].LangID);
+ else
+ continue;
+ }
+ }
+ if (newString.IsEmpty())
+ continue;
+ }
+ else
+ {
+ int langPos = FindLangItem(item.wID);
+ if (langPos < 0)
+ continue;
+ newString = LangString(kIDLangPairs[langPos].LangID);
+ if (newString.IsEmpty())
+ continue;
+ UString shorcutString = item.StringValue;
+ int tabPos = shorcutString.ReverseFind(wchar_t('\t'));
+ if (tabPos >= 0)
+ newString += shorcutString.Mid(tabPos);
+ }
+ {
+ item.StringValue = newString;
+ item.fMask = Get_fMaskForString();
+ item.fType = MFT_STRING;
+ menu.SetItem(i, true, item);
+ }
+ }
+ }
+}
+
+CMenu g_FileMenu;
+
+class CFileMenuDestroyer
+{
+public:
+ ~CFileMenuDestroyer()
+ {
+ if ((HMENU)g_FileMenu != 0)
+ g_FileMenu.Destroy();
+ }
+} g_FileMenuDestroyer;
+
+
+void MyLoadMenu(HWND hWnd)
+{
+ if ((HMENU)g_FileMenu != 0)
+ g_FileMenu.Destroy();
+ HMENU oldMenu = ::GetMenu(hWnd);
+ HMENU baseMenu = ::LoadMenu(g_hInstance, MAKEINTRESOURCE(IDM_MENU));
+ ::SetMenu(hWnd, baseMenu);
+ ::DestroyMenu(oldMenu);
+ if (!g_LangID.IsEmpty())
+ {
+ HMENU menuOld = ::GetMenu(hWnd);
+ MyChangeMenu(menuOld, 0, 0);
+ }
+ ::DrawMenuBar(hWnd);
+}
+
+extern HWND g_HWND;
+void MyLoadMenu()
+{
+ MyLoadMenu(g_HWND);
+}
+
+static void CopyMenu(HMENU srcMenuSpec, HMENU destMenuSpec)
+{
+ CMenu srcMenu;
+ srcMenu.Attach(srcMenuSpec);
+ CMenu destMenu;
+ destMenu.Attach(destMenuSpec);
+ int startPos = 0;
+ for (int i = 0; i < srcMenu.GetItemCount(); i++)
+ {
+ CMenuItem item;
+ item.fMask = MIIM_STATE | MIIM_ID | Get_fMaskForFTypeAndString();
+ item.fType = MFT_STRING;
+ if (srcMenu.GetItem(i, true, item))
+ if (destMenu.InsertItem(startPos, true, item))
+ startPos++;
+ }
+}
+
+void OnMenuActivating(HWND /* hWnd */, HMENU hMenu, int position)
+{
+ if (::GetSubMenu(::GetMenu(g_HWND), position) != hMenu)
+ return;
+ if (position == kFileMenuIndex)
+ {
+ if ((HMENU)g_FileMenu == 0)
+ {
+ g_FileMenu.CreatePopup();
+ CopyMenu(hMenu, g_FileMenu);
+ }
+ CMenu menu;
+ menu.Attach(hMenu);
+ while (menu.GetItemCount() > 0)
+ {
+ if (!menu.RemoveItem(0, MF_BYPOSITION))
+ break;
+ }
+ // CopyMenu(g_FileMenu, hMenu);
+ g_App.GetFocusedPanel().CreateFileMenu(hMenu);
+
+ }
+ else if (position == kViewMenuIndex)
+ {
+ // View;
+ CMenu menu;
+ menu.Attach(hMenu);
+ menu.CheckRadioItem(IDM_VIEW_LARGE_ICONS, IDM_VIEW_DETAILS,
+ IDM_VIEW_LARGE_ICONS + g_App.GetListViewMode(), MF_BYCOMMAND);
+ menu.CheckItem(IDM_VIEW_TWO_PANELS, MF_BYCOMMAND |
+ ((g_App.NumPanels == 2) ? MF_CHECKED : MF_UNCHECKED));
+ menu.CheckItem(IDM_VIEW_FLAT_VIEW, MF_BYCOMMAND |
+ ((g_App.GetFlatMode()) ? MF_CHECKED : MF_UNCHECKED));
+ menu.CheckItem(IDM_VIEW_ARCHIVE_TOOLBAR, MF_BYCOMMAND |
+ (g_App.ShowArchiveToolbar ? MF_CHECKED : MF_UNCHECKED));
+ menu.CheckItem(IDM_VIEW_STANDARD_TOOLBAR, MF_BYCOMMAND |
+ (g_App.ShowStandardToolbar ? MF_CHECKED : MF_UNCHECKED));
+ menu.CheckItem(IDM_VIEW_TOOLBARS_LARGE_BUTTONS, MF_BYCOMMAND |
+ (g_App.LargeButtons ? MF_CHECKED : MF_UNCHECKED));
+ menu.CheckItem(IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT, MF_BYCOMMAND |
+ (g_App.ShowButtonsLables ? MF_CHECKED : MF_UNCHECKED));
+ }
+ else if (position == kBookmarksMenuIndex)
+ {
+ CMenu menu;
+ menu.Attach(hMenu);
+
+ CMenu subMenu;
+ subMenu.Attach(menu.GetSubMenu(0));
+ while (subMenu.GetItemCount() > 0)
+ subMenu.RemoveItem(subMenu.GetItemCount() - 1, MF_BYPOSITION);
+ int i;
+ for (i = 0; i < 10; i++)
+ {
+ UString s = LangString(IDS_BOOKMARK, 0x03000720);
+ s += L" ";
+ wchar_t c = (wchar_t)(L'0' + i);
+ s += c;
+ s += L"\tAlt+Shift+";
+ s += c;
+ subMenu.AppendItem(MF_STRING, kSetBookmarkMenuID + i, s);
+ }
+
+ while (menu.GetItemCount() > 2)
+ menu.RemoveItem(menu.GetItemCount() - 1, MF_BYPOSITION);
+
+ for (i = 0; i < 10; i++)
+ {
+ UString path = g_App.AppState.FastFolders.GetString(i);
+ const int kMaxSize = 100;
+ const int kFirstPartSize = kMaxSize / 2;
+ if (path.Length() > kMaxSize)
+ {
+ path = path.Left(kFirstPartSize) + UString(L" ... ") +
+ path.Right(kMaxSize - kFirstPartSize);
+ }
+ UString s = path;
+ if (s.IsEmpty())
+ s = L"-";
+ s += L"\tAlt+";
+ s += (wchar_t)(L'0' + i);
+ menu.AppendItem(MF_STRING, kOpenBookmarkMenuID + i, s);
+ }
+ }
+}
+
+/*
+It doesn't help
+void OnMenuUnActivating(HWND hWnd, HMENU hMenu, int id)
+{
+ if (::GetSubMenu(::GetMenu(g_HWND), 0) != hMenu)
+ return;
+ // g_App.GetFocusedPanel()._contextMenu.Release();
+}
+
+void OnMenuUnActivating(HWND hWnd)
+{
+}
+*/
+
+
+void LoadFileMenu(HMENU hMenu, int startPos, bool /* forFileMode */, bool programMenu)
+{
+ {
+ CMenu srcMenu;
+ srcMenu.Attach(::GetSubMenu(::GetMenu(g_HWND), 0));
+ if ((HMENU)g_FileMenu == 0)
+ {
+ g_FileMenu.CreatePopup();
+ CopyMenu(srcMenu, g_FileMenu);
+ }
+ }
+
+ CMenu destMenu;
+ destMenu.Attach(hMenu);
+
+ for (int i = 0; i < g_FileMenu.GetItemCount(); i++)
+ {
+ CMenuItem item;
+
+ item.fMask = MIIM_STATE | MIIM_ID | Get_fMaskForFTypeAndString();
+ item.fType = MFT_STRING;
+ if (g_FileMenu.GetItem(i, true, item))
+ {
+ if (!programMenu)
+ if (item.wID == IDCLOSE)
+ continue;
+ /*
+ bool createItem = (item.wID == IDM_CREATE_FOLDER || item.wID == IDM_CREATE_FILE);
+ if (forFileMode)
+ {
+ if (createItem)
+ continue;
+ }
+ else
+ {
+ if (!createItem)
+ continue;
+ }
+ */
+ if (destMenu.InsertItem(startPos, true, item))
+ startPos++;
+ }
+ }
+ while (destMenu.GetItemCount() > 0)
+ {
+ CMenuItem item;
+ item.fMask = MIIM_TYPE;
+ item.fType = 0;
+ // item.dwTypeData = 0;
+ int lastIndex = destMenu.GetItemCount() - 1;
+ if (!destMenu.GetItem(lastIndex, true, item))
+ break;
+ if(item.fType != MFT_SEPARATOR)
+ break;
+ if (!destMenu.RemoveItem(lastIndex, MF_BYPOSITION))
+ break;
+ }
+}
+
+bool ExecuteFileCommand(int id)
+{
+ if (id >= kPluginMenuStartID)
+ {
+ g_App.GetFocusedPanel().InvokePluginCommand(id);
+ g_App.GetFocusedPanel()._sevenZipContextMenu.Release();
+ g_App.GetFocusedPanel()._systemContextMenu.Release();
+ return true;
+ }
+
+ switch (id)
+ {
+ // File
+ case IDM_FILE_OPEN:
+ g_App.OpenItem();
+ break;
+ case IDM_FILE_OPEN_INSIDE:
+ g_App.OpenItemInside();
+ break;
+ case IDM_FILE_OPEN_OUTSIDE:
+ g_App.OpenItemOutside();
+ break;
+ case IDM_FILE_VIEW:
+ break;
+ case IDM_FILE_EDIT:
+ g_App.EditItem();
+ break;
+ case IDM_RENAME:
+ g_App.Rename();
+ break;
+ case IDM_COPY_TO:
+ g_App.CopyTo();
+ break;
+ case IDM_MOVE_TO:
+ g_App.MoveTo();
+ break;
+ case IDM_DELETE:
+ {
+ bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0;
+ g_App.Delete(!shift);
+ break;
+ }
+ case IDM_FILE_CRC:
+ g_App.CalculateCrc();
+ break;
+ case IDM_FILE_SPLIT:
+ g_App.Split();
+ break;
+ case IDM_FILE_COMBINE:
+ g_App.Combine();
+ break;
+ case IDM_FILE_PROPERTIES:
+ g_App.Properties();
+ break;
+ case IDM_FILE_COMMENT:
+ g_App.Comment();
+ break;
+
+ case IDM_CREATE_FOLDER:
+ g_App.CreateFolder();
+ break;
+ case IDM_CREATE_FILE:
+ g_App.CreateFile();
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+bool OnMenuCommand(HWND hWnd, int id)
+{
+ if (ExecuteFileCommand(id))
+ return true;
+
+ switch (id)
+ {
+ // File
+ case IDCLOSE:
+ SendMessage(hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)hWnd);
+ SendMessage (hWnd, WM_CLOSE, 0, 0);
+ break;
+
+ // Edit
+ case IDM_EDIT_COPY:
+ g_App.EditCopy();
+ break;
+ case IDM_EDIT_PASTE:
+ g_App.EditPaste();
+ break;
+ case IDM_SELECT_ALL:
+ g_App.SelectAll(true);
+ g_App.RefreshStatusBar();
+ break;
+ case IDM_DESELECT_ALL:
+ g_App.SelectAll(false);
+ g_App.RefreshStatusBar();
+ break;
+ case IDM_INVERT_SELECTION:
+ g_App.InvertSelection();
+ g_App.RefreshStatusBar();
+ break;
+ case IDM_SELECT:
+ g_App.SelectSpec(true);
+ g_App.RefreshStatusBar();
+ break;
+ case IDM_DESELECT:
+ g_App.SelectSpec(false);
+ g_App.RefreshStatusBar();
+ break;
+ case IDM_SELECT_BY_TYPE:
+ g_App.SelectByType(true);
+ g_App.RefreshStatusBar();
+ break;
+ case IDM_DESELECT_BY_TYPE:
+ g_App.SelectByType(false);
+ g_App.RefreshStatusBar();
+ break;
+
+ //View
+ case IDM_VIEW_LARGE_ICONS:
+ case IDM_VIEW_SMALL_ICONS:
+ case IDM_VIEW_LIST:
+ case IDM_VIEW_DETAILS:
+ {
+ UINT index = id - IDM_VIEW_LARGE_ICONS;
+ if (index < 4)
+ {
+ g_App.SetListViewMode(index);
+ /*
+ CMenu menu;
+ menu.Attach(::GetSubMenu(::GetMenu(hWnd), kViewMenuIndex));
+ menu.CheckRadioItem(IDM_VIEW_LARGE_ICONS, IDM_VIEW_DETAILS,
+ id, MF_BYCOMMAND);
+ */
+ }
+ break;
+ }
+ case IDM_VIEW_ARANGE_BY_NAME:
+ {
+ g_App.SortItemsWithPropID(kpidName);
+ break;
+ }
+ case IDM_VIEW_ARANGE_BY_TYPE:
+ {
+ g_App.SortItemsWithPropID(kpidExtension);
+ break;
+ }
+ case IDM_VIEW_ARANGE_BY_DATE:
+ {
+ g_App.SortItemsWithPropID(kpidLastWriteTime);
+ break;
+ }
+ case IDM_VIEW_ARANGE_BY_SIZE:
+ {
+ g_App.SortItemsWithPropID(kpidSize);
+ break;
+ }
+ case IDM_VIEW_ARANGE_NO_SORT:
+ {
+ g_App.SortItemsWithPropID(kpidNoProperty);
+ break;
+ }
+
+ case IDM_OPEN_ROOT_FOLDER:
+ g_App.OpenRootFolder();
+ break;
+ case IDM_OPEN_PARENT_FOLDER:
+ g_App.OpenParentFolder();
+ break;
+ case IDM_FOLDERS_HISTORY:
+ g_App.FoldersHistory();
+ break;
+ case IDM_VIEW_REFRESH:
+ g_App.RefreshView();
+ break;
+ case IDM_VIEW_FLAT_VIEW:
+ g_App.ChangeFlatMode();
+ break;
+ case IDM_VIEW_TWO_PANELS:
+ g_App.SwitchOnOffOnePanel();
+ break;
+ case IDM_VIEW_STANDARD_TOOLBAR:
+ g_App.SwitchStandardToolbar();
+ break;
+ case IDM_VIEW_ARCHIVE_TOOLBAR:
+ g_App.SwitchArchiveToolbar();
+ break;
+ case IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT:
+ g_App.SwitchButtonsLables();
+ break;
+ case IDM_VIEW_TOOLBARS_LARGE_BUTTONS:
+ g_App.SwitchLargeButtons();
+ break;
+
+ // Tools
+ case IDM_OPTIONS:
+ OptionsDialog(hWnd, g_hInstance);
+ break;
+
+ case IDM_BENCHMARK:
+ Benchmark(hWnd);
+ break;
+ // Help
+ case IDM_HELP_CONTENTS:
+ ShowHelpWindow(NULL, kFMHelpTopic);
+ break;
+ case IDM_ABOUT:
+ {
+ CAboutDialog dialog;
+ dialog.Create(hWnd);
+ break;
+ }
+ default:
+ {
+ if (id >= kOpenBookmarkMenuID && id <= kOpenBookmarkMenuID + 9)
+ {
+ g_App.OpenBookmark(id - kOpenBookmarkMenuID);
+ return true;
+ }
+ else if (id >= kSetBookmarkMenuID && id <= kSetBookmarkMenuID + 9)
+ {
+ g_App.SetBookmark(id - kSetBookmarkMenuID);
+ return true;
+ }
+ return false;
+ }
+ }
+ return true;
+}
+
diff --git a/CPP/7zip/FileManager/MyLoadMenu.h b/CPP/7zip/FileManager/MyLoadMenu.h
new file mode 100755
index 00000000..490dc6d8
--- /dev/null
+++ b/CPP/7zip/FileManager/MyLoadMenu.h
@@ -0,0 +1,16 @@
+// MyLoadMenu.h
+
+#ifndef __MYLOADMENU_H
+#define __MYLOADMENU_H
+
+void OnMenuActivating(HWND hWnd, HMENU hMenu, int position);
+// void OnMenuUnActivating(HWND hWnd, HMENU hMenu, int id);
+// void OnMenuUnActivating(HWND hWnd);
+
+void MyLoadMenu(HWND hWnd);
+bool OnMenuCommand(HWND hWnd, int id);
+void MyLoadMenu();
+void LoadFileMenu(HMENU hMenu, int startPos, bool forFileMode, bool programMenu);
+bool ExecuteFileCommand(int id);
+
+#endif
diff --git a/CPP/7zip/FileManager/NetFolder.cpp b/CPP/7zip/FileManager/NetFolder.cpp
new file mode 100755
index 00000000..a5cd379a
--- /dev/null
+++ b/CPP/7zip/FileManager/NetFolder.cpp
@@ -0,0 +1,315 @@
+// NetFolder.cpp
+
+#include "StdAfx.h"
+
+#include "NetFolder.h"
+
+#include "Common/StringConvert.h"
+#include "../PropID.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+#include "Windows/FileFind.h"
+
+#include "SysIconUtils.h"
+#include "FSFolder.h"
+
+using namespace NWindows;
+using namespace NNet;
+
+static const STATPROPSTG kProperties[] =
+{
+ { NULL, kpidName, VT_BSTR},
+ { NULL, kpidLocalName, VT_BSTR},
+ { NULL, kpidComment, VT_BSTR},
+ { NULL, kpidProvider, VT_BSTR}
+};
+
+void CNetFolder::Init(const UString &path)
+{
+ /*
+ if (path.Length() > 2)
+ {
+ if (path[0] == L'\\' && path[1] == L'\\')
+ {
+ CResource netResource;
+ netResource.RemoteName = GetSystemString(path.Left(path.Length() - 1));
+ netResource.Scope = RESOURCE_GLOBALNET;
+ netResource.Type = RESOURCETYPE_DISK;
+ netResource.DisplayType = RESOURCEDISPLAYTYPE_SERVER;
+ netResource.Usage = RESOURCEUSAGE_CONTAINER;
+ Init(&netResource, 0, path);
+ return;
+ }
+ }
+ Init(0, 0 , L"");
+ */
+ CResourceW resource;
+ resource.RemoteNameIsDefined = true;
+ resource.RemoteName = path.Left(path.Length() - 1);
+ resource.ProviderIsDefined = false;
+ resource.LocalNameIsDefined = false;
+ resource.CommentIsDefined = false;
+ resource.Type = RESOURCETYPE_DISK;
+ resource.Scope = RESOURCE_GLOBALNET;
+ resource.Usage = 0;
+ resource.DisplayType = 0;
+ CResourceW destResource;
+ UString systemPathPart;
+ DWORD result = GetResourceInformation(resource, destResource, systemPathPart);
+ if (result == NO_ERROR)
+ Init(&destResource, 0, path);
+ else
+ Init(0, 0 , L"");
+ return;
+}
+
+void CNetFolder::Init(const NWindows::NNet::CResourceW *netResource,
+ IFolderFolder *parentFolder, const UString &path)
+{
+ _path = path;
+ if (netResource == 0)
+ _netResourcePointer = 0;
+ else
+ {
+ _netResource = *netResource;
+ _netResourcePointer = &_netResource;
+
+ // if (_netResource.DisplayType == RESOURCEDISPLAYTYPE_SERVER)
+ _path = _netResource.RemoteName + L'\\';
+ }
+ _parentFolder = parentFolder;
+}
+
+STDMETHODIMP CNetFolder::LoadItems()
+{
+ _items.Clear();
+ CEnum enumerator;
+
+ for (;;)
+ {
+ DWORD result = enumerator.Open(
+ RESOURCE_GLOBALNET,
+ RESOURCETYPE_DISK,
+ 0, // enumerate all resources
+ _netResourcePointer
+ );
+ if (result == NO_ERROR)
+ break;
+ if (result != ERROR_ACCESS_DENIED)
+ return result;
+ if (_netResourcePointer != 0)
+ result = AddConnection2(_netResource,
+ 0, 0, CONNECT_INTERACTIVE);
+ if (result != NO_ERROR)
+ return result;
+ }
+
+ for (;;)
+ {
+ CResourceEx resource;
+ DWORD result = enumerator.Next(resource);
+ if (result == NO_ERROR)
+ {
+ if (!resource.RemoteNameIsDefined) // For Win 98, I don't know what's wrong
+ resource.RemoteName = resource.Comment;
+ resource.Name = resource.RemoteName;
+ int aPos = resource.Name.ReverseFind(L'\\');
+ if (aPos >= 0)
+ {
+ // _path = resource.Name.Left(aPos + 1);
+ resource.Name = resource.Name.Mid(aPos + 1);
+ }
+ _items.Add(resource);
+ }
+ else if (result == ERROR_NO_MORE_ITEMS)
+ break;
+ else
+ return result;
+ }
+
+ /*
+ It's too slow for some systems.
+ if (_netResourcePointer && _netResource.DisplayType == RESOURCEDISPLAYTYPE_SERVER)
+ {
+ for (char c = 'a'; c <= 'z'; c++)
+ {
+ CResourceEx resource;
+ resource.Name = UString(wchar_t(c)) + L'$';
+ resource.RemoteNameIsDefined = true;
+ resource.RemoteName = _path + resource.Name;
+
+ NFile::NFind::CFindFile findFile;
+ NFile::NFind::CFileInfoW fileInfo;
+ if (!findFile.FindFirst(resource.RemoteName + UString(L"\\*"), fileInfo))
+ continue;
+ resource.Usage = RESOURCEUSAGE_CONNECTABLE;
+ resource.LocalNameIsDefined = false;
+ resource.CommentIsDefined = false;
+ resource.ProviderIsDefined = false;
+ _items.Add(resource);
+ }
+ }
+ */
+ return S_OK;
+}
+
+
+STDMETHODIMP CNetFolder::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = _items.Size();
+ return S_OK;
+}
+
+STDMETHODIMP CNetFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value)
+{
+ NCOM::CPropVariant propVariant;
+ const CResourceEx &item = _items[itemIndex];
+ switch(propID)
+ {
+ case kpidIsFolder:
+ propVariant = true;
+ break;
+ case kpidName:
+ // if (item.RemoteNameIsDefined)
+ propVariant = item.Name;
+ break;
+ case kpidLocalName:
+ if (item.LocalNameIsDefined)
+ propVariant = item.LocalName;
+ break;
+ case kpidComment:
+ if (item.CommentIsDefined)
+ propVariant = item.Comment;
+ break;
+ case kpidProvider:
+ if (item.ProviderIsDefined)
+ propVariant = item.Provider;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
+
+STDMETHODIMP CNetFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder)
+{
+ *resultFolder = 0;
+ const CResourceEx &resource = _items[index];
+ if (resource.Usage == RESOURCEUSAGE_CONNECTABLE ||
+ resource.DisplayType == RESOURCEDISPLAYTYPE_SHARE)
+ {
+ CFSFolder *fsFolderSpec = new CFSFolder;
+ CMyComPtr<IFolderFolder> subFolder = fsFolderSpec;
+ RINOK(fsFolderSpec->Init(resource.RemoteName + L'\\', this));
+ *resultFolder = subFolder.Detach();
+ }
+ else
+ {
+ CNetFolder *netFolder = new CNetFolder;
+ CMyComPtr<IFolderFolder> subFolder = netFolder;
+ netFolder->Init(&resource, this, resource.Name + L'\\');
+ *resultFolder = subFolder.Detach();
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CNetFolder::BindToFolder(const wchar_t * /* name */, IFolderFolder ** /* resultFolder */)
+{
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP CNetFolder::BindToParentFolder(IFolderFolder **resultFolder)
+{
+ *resultFolder = 0;
+ if (_parentFolder)
+ {
+ CMyComPtr<IFolderFolder> parentFolder = _parentFolder;
+ *resultFolder = parentFolder.Detach();
+ return S_OK;
+ }
+ if (_netResourcePointer != 0)
+ {
+ CResourceW resourceParent;
+ DWORD result = GetResourceParent(_netResource, resourceParent);
+ if (result != NO_ERROR)
+ return result;
+ if (!_netResource.RemoteNameIsDefined)
+ return S_OK;
+
+ CNetFolder *netFolder = new CNetFolder;
+ CMyComPtr<IFolderFolder> subFolder = netFolder;
+ netFolder->Init(&resourceParent, 0, L'\\');
+ *resultFolder = subFolder.Detach();
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CNetFolder::GetName(BSTR *name)
+{
+ *name = 0;
+ return E_NOTIMPL;
+ /*
+ CMyComBSTR aBSTRName = m_ProxyFolderItem->m_Name;
+ *aName = aBSTRName.Detach();
+ return S_OK;
+ */
+}
+
+STDMETHODIMP CNetFolder::GetNumberOfProperties(UInt32 *numProperties)
+{
+ *numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
+ return S_OK;
+}
+
+STDMETHODIMP CNetFolder::GetPropertyInfo(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType)
+{
+ if (index >= sizeof(kProperties) / sizeof(kProperties[0]))
+ return E_INVALIDARG;
+ const STATPROPSTG &prop = kProperties[index];
+ *propID = prop.propid;
+ *varType = prop.vt;
+ *name = 0;
+ return S_OK;
+}
+
+STDMETHODIMP CNetFolder::GetTypeID(BSTR *name)
+{
+ CMyComBSTR aBSTRName = L"NetFolder";
+ *name = aBSTRName.Detach();
+ return S_OK;
+}
+
+STDMETHODIMP CNetFolder::GetPath(BSTR *path)
+{
+ CMyComBSTR aBSTRName = _path;
+ *path = aBSTRName.Detach();
+ return S_OK;
+}
+
+STDMETHODIMP CNetFolder::GetSystemIconIndex(UInt32 index, INT32 *iconIndex)
+{
+ if (index >= (UInt32)_items.Size())
+ return E_INVALIDARG;
+ *iconIndex = 0;
+ const CResourceW &resource = _items[index];
+ int iconIndexTemp;
+ if (resource.DisplayType == RESOURCEDISPLAYTYPE_SERVER ||
+ resource.Usage == RESOURCEUSAGE_CONNECTABLE)
+ {
+ if (GetRealIconIndex(resource.RemoteName, 0, iconIndexTemp))
+ {
+ *iconIndex = iconIndexTemp;
+ return S_OK;
+ }
+ }
+ else
+ {
+ if (GetRealIconIndex(TEXT(""), FILE_ATTRIBUTE_DIRECTORY, iconIndexTemp))
+ {
+ *iconIndex = iconIndexTemp;
+ return S_OK;
+ }
+ // *anIconIndex = GetRealIconIndex(0, L"\\\\HOME");
+ }
+ return GetLastError();
+}
diff --git a/CPP/7zip/FileManager/NetFolder.h b/CPP/7zip/FileManager/NetFolder.h
new file mode 100755
index 00000000..f23c7e4e
--- /dev/null
+++ b/CPP/7zip/FileManager/NetFolder.h
@@ -0,0 +1,66 @@
+// NetFolder.h
+
+#ifndef __NETFOLDER_H
+#define __NETFOLDER_H
+
+#include "Common/String.h"
+#include "Common/Buffer.h"
+#include "Common/MyCom.h"
+#include "Windows/PropVariant.h"
+#include "Windows/Net.h"
+
+#include "IFolder.h"
+
+struct CResourceEx: public NWindows::NNet::CResourceW
+{
+ UString Name;
+};
+
+class CNetFolder:
+ public IFolderFolder,
+ public IEnumProperties,
+ public IFolderGetTypeID,
+ public IFolderGetPath,
+ public IFolderGetSystemIconIndex,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP4(
+ IEnumProperties,
+ IFolderGetTypeID,
+ IFolderGetPath,
+ IFolderGetSystemIconIndex
+ )
+
+ STDMETHOD(LoadItems)();
+ STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
+ STDMETHOD(GetProperty)(UInt32 itemIndex, PROPID propID, PROPVARIANT *value);
+ STDMETHOD(BindToFolder)(UInt32 index, IFolderFolder **resultFolder);
+ STDMETHOD(BindToFolder)(const wchar_t *name, IFolderFolder **resultFolder);
+ STDMETHOD(BindToParentFolder)(IFolderFolder **resultFolder);
+ STDMETHOD(GetName)(BSTR *name);
+
+ STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
+ STDMETHOD(GetPropertyInfo)(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType);
+ STDMETHOD(GetTypeID)(BSTR *name);
+ STDMETHOD(GetPath)(BSTR *path);
+ STDMETHOD(GetSystemIconIndex)(UInt32 index, INT32 *iconIndex);
+
+private:
+ NWindows::NNet::CResourceW _netResource;
+ NWindows::NNet::CResourceW *_netResourcePointer;
+
+ CObjectVector<CResourceEx> _items;
+
+ CMyComPtr<IFolderFolder> _parentFolder;
+ UString _path;
+
+public:
+ void Init(const UString &path);
+ void Init(const NWindows::NNet::CResourceW *netResource,
+ IFolderFolder *parentFolder, const UString &path);
+ CNetFolder(): _netResourcePointer(0) {}
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/OpenCallback.cpp b/CPP/7zip/FileManager/OpenCallback.cpp
new file mode 100755
index 00000000..a69de62c
--- /dev/null
+++ b/CPP/7zip/FileManager/OpenCallback.cpp
@@ -0,0 +1,113 @@
+// OpenCallback.cpp
+
+#include "StdAfx.h"
+
+#include "OpenCallback.h"
+
+#include "Common/StringConvert.h"
+#include "Resource/PasswordDialog/PasswordDialog.h"
+#include "Windows/PropVariant.h"
+#include "../Common/FileStreams.h"
+
+STDMETHODIMP COpenArchiveCallback::SetTotal(const UINT64 * /* numFiles */, const UINT64 * /* numBytes */)
+{
+ return S_OK;
+}
+
+STDMETHODIMP COpenArchiveCallback::SetCompleted(const UINT64 * /* numFiles */, const UINT64 * /* numBytes */)
+{
+ return S_OK;
+}
+
+STDMETHODIMP COpenArchiveCallback::SetTotal(const UINT64 /* total */)
+{
+ return S_OK;
+}
+
+STDMETHODIMP COpenArchiveCallback::SetCompleted(const UINT64 * /* completed */)
+{
+ return S_OK;
+}
+
+STDMETHODIMP COpenArchiveCallback::GetProperty(PROPID propID, PROPVARIANT *value)
+{
+ NWindows::NCOM::CPropVariant propVariant;
+ if (_subArchiveMode)
+ {
+ switch(propID)
+ {
+ case kpidName:
+ propVariant = _subArchiveName;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ }
+ switch(propID)
+ {
+ case kpidName:
+ propVariant = _fileInfo.Name;
+ break;
+ case kpidIsFolder:
+ propVariant = _fileInfo.IsDirectory();
+ break;
+ case kpidSize:
+ propVariant = _fileInfo.Size;
+ break;
+ case kpidAttributes:
+ propVariant = (UINT32)_fileInfo.Attributes;
+ break;
+ case kpidLastAccessTime:
+ propVariant = _fileInfo.LastAccessTime;
+ break;
+ case kpidCreationTime:
+ propVariant = _fileInfo.CreationTime;
+ break;
+ case kpidLastWriteTime:
+ propVariant = _fileInfo.LastWriteTime;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
+
+STDMETHODIMP COpenArchiveCallback::GetStream(const wchar_t *name,
+ IInStream **inStream)
+{
+ *inStream = NULL;
+ if (_subArchiveMode)
+ return S_FALSE;
+
+ NWindows::NFile::NFind::CFileInfoW fileInfo;
+
+ UString fullPath = _folderPrefix + name;
+ if (!NWindows::NFile::NFind::FindFile(fullPath, fileInfo))
+ return S_FALSE;
+ _fileInfo = fileInfo;
+ if (_fileInfo.IsDirectory())
+ return S_FALSE;
+ CInFileStream *inFile = new CInFileStream;
+ CMyComPtr<IInStream> inStreamTemp = inFile;
+ if (!inFile->Open(fullPath))
+ return ::GetLastError();
+ *inStream = inStreamTemp.Detach();
+ return S_OK;
+}
+
+STDMETHODIMP COpenArchiveCallback::CryptoGetTextPassword(BSTR *password)
+{
+ PasswordWasAsked = true;
+ if (!PasswordIsDefined)
+ {
+ CPasswordDialog dialog;
+
+ if (dialog.Create(ParentWindow) == IDCANCEL)
+ return E_ABORT;
+
+ Password = dialog.Password;
+ PasswordIsDefined = true;
+ }
+ CMyComBSTR tempName(Password);
+ *password = tempName.Detach();
+ return S_OK;
+}
diff --git a/CPP/7zip/FileManager/OpenCallback.h b/CPP/7zip/FileManager/OpenCallback.h
new file mode 100755
index 00000000..853c0e44
--- /dev/null
+++ b/CPP/7zip/FileManager/OpenCallback.h
@@ -0,0 +1,85 @@
+// OpenCallback.h
+
+#ifndef __OPENCALLBACK_H
+#define __OPENCALLBACK_H
+
+#include "Common/String.h"
+#include "Common/MyCom.h"
+#include "Windows/FileFind.h"
+
+#include "../IPassword.h"
+
+#include "../Archive/IArchive.h"
+
+class COpenArchiveCallback:
+ public IArchiveOpenCallback,
+ public IArchiveOpenVolumeCallback,
+ public IArchiveOpenSetSubArchiveName,
+ public IProgress,
+ public ICryptoGetTextPassword,
+ public CMyUnknownImp
+{
+ UString _folderPrefix;
+ NWindows::NFile::NFind::CFileInfoW _fileInfo;
+public:
+ bool PasswordIsDefined;
+ UString Password;
+ bool PasswordWasAsked;
+ HWND ParentWindow;
+
+ bool _subArchiveMode;
+ UString _subArchiveName;
+
+public:
+ MY_UNKNOWN_IMP5(
+ IArchiveOpenCallback,
+ IArchiveOpenVolumeCallback,
+ IArchiveOpenSetSubArchiveName,
+ IProgress,
+ ICryptoGetTextPassword)
+
+ // IProgress
+ STDMETHOD(SetTotal)(UINT64 total);
+ STDMETHOD(SetCompleted)(const UINT64 *completeValue);
+
+ // IArchiveOpenCallback
+ STDMETHOD(SetTotal)(const UINT64 *numFiles, const UINT64 *numBytes);
+ STDMETHOD(SetCompleted)(const UINT64 *numFiles, const UINT64 *numBytes);
+
+ // IArchiveOpenVolumeCallback
+ STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value);
+ STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream);
+
+ // ICryptoGetTextPassword
+ STDMETHOD(CryptoGetTextPassword)(BSTR *password);
+
+ STDMETHOD(SetSubArchiveName(const wchar_t *name))
+ {
+ _subArchiveMode = true;
+ _subArchiveName = name;
+ return S_OK;
+ }
+
+ COpenArchiveCallback()
+ {
+ _subArchiveMode = false;
+ PasswordIsDefined = false;
+ PasswordWasAsked = false;
+ }
+ /*
+ void Init()
+ {
+ PasswordIsDefined = false;
+ _subArchiveMode = false;
+ }
+ */
+ void LoadFileInfo(const UString &folderPrefix, const UString &fileName)
+ {
+ _folderPrefix = folderPrefix;
+ if (!NWindows::NFile::NFind::FindFile(_folderPrefix + fileName, _fileInfo))
+ throw 1;
+ }
+ void ShowMessage(const UINT64 *completed);
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/OptionsDialog.cpp b/CPP/7zip/FileManager/OptionsDialog.cpp
new file mode 100755
index 00000000..7413bafc
--- /dev/null
+++ b/CPP/7zip/FileManager/OptionsDialog.cpp
@@ -0,0 +1,65 @@
+// OptionsDialog.cpp
+
+#include "StdAfx.h"
+
+#include "resource.h"
+
+#include "Common/StringConvert.h"
+
+#include "Windows/Control/PropertyPage.h"
+#include "Windows/Error.h"
+
+#include "Resource/LangPage/LangPage.h"
+#include "Resource/LangPage/resource.h"
+#include "Resource/PluginsPage/PluginsPage.h"
+#include "Resource/PluginsPage/resource.h"
+#include "Resource/SystemPage/SystemPage.h"
+#include "Resource/SystemPage/resource.h"
+#include "Resource/EditPage/EditPage.h"
+#include "Resource/EditPage/resource.h"
+#include "Resource/SettingsPage/SettingsPage.h"
+#include "Resource/SettingsPage/resource.h"
+
+#include "LangUtils.h"
+#include "MyLoadMenu.h"
+#include "App.h"
+
+using namespace NWindows;
+
+void OptionsDialog(HWND hwndOwner, HINSTANCE /* hInstance */)
+{
+ CSystemPage systemPage;
+ CPluginsPage pluginsPage;
+ CEditPage editPage;
+ CSettingsPage settingsPage;
+ CLangPage langPage;
+
+ CObjectVector<NControl::CPageInfo> pages;
+ UINT32 langIDs[] = { 0x03010300, 0x03010100, 0x03010200, 0x03010400, 0x01000400};
+ UINT pageIDs[] = { IDD_SYSTEM, IDD_PLUGINS, IDD_EDIT, IDD_SETTINGS, IDD_LANG};
+ NControl::CPropertyPage *pagePinters[] = { &systemPage, &pluginsPage, &editPage, &settingsPage, &langPage };
+ const int kNumPages = sizeof(langIDs) / sizeof(langIDs[0]);
+ for (int i = 0; i < kNumPages; i++)
+ {
+ NControl::CPageInfo page;
+ page.Title = LangString(langIDs[i]);
+ page.ID = pageIDs[i];
+ page.Page = pagePinters[i];
+ pages.Add(page);
+ }
+
+ INT_PTR res = NControl::MyPropertySheet(pages, hwndOwner, LangString(IDS_OPTIONS, 0x03010000));
+ if (res != -1 && res != 0)
+ {
+ if (langPage._langWasChanged)
+ {
+ g_App._window.SetText(LangString(IDS_APP_TITLE, 0x03000000));
+ MyLoadMenu();
+ }
+ g_App.SetListSettings();
+ g_App.SetShowSystemMenu();
+ g_App.RefreshAllPanels();
+ g_App.ReloadToolbars();
+ // ::PostMessage(hwndOwner, kLangWasChangedMessage, 0 , 0);
+ }
+}
diff --git a/CPP/7zip/FileManager/Panel.cpp b/CPP/7zip/FileManager/Panel.cpp
new file mode 100755
index 00000000..fcc33edf
--- /dev/null
+++ b/CPP/7zip/FileManager/Panel.cpp
@@ -0,0 +1,856 @@
+// Panel.cpp
+
+#include "StdAfx.h"
+
+#include <Windowsx.h>
+
+#include "Common/Defs.h"
+#include "Common/StringConvert.h"
+#include "Windows/Error.h"
+#include "Windows/PropVariant.h"
+
+#include "../PropID.h"
+
+#include "Panel.h"
+#include "RootFolder.h"
+#include "FSFolder.h"
+#include "FormatUtils.h"
+#include "App.h"
+
+#include "../UI/Common/CompressCall.h"
+#include "../UI/Common/ArchiveName.h"
+
+using namespace NWindows;
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+static const UINT_PTR kTimerID = 1;
+static const UINT kTimerElapse = 1000;
+
+static LPCWSTR kSelectOneFile = L"Select one file";
+static LPCWSTR kSelectFiles = L"Select files";
+
+static DWORD kStyles[4] = { LVS_ICON, LVS_SMALLICON, LVS_LIST, LVS_REPORT };
+
+// static const int kCreateFolderID = 101;
+// static const UINT kFileChangeNotifyMessage = WM_APP;
+
+extern HINSTANCE g_hInstance;
+extern DWORD g_ComCtl32Version;
+
+void CPanel::Release()
+{
+ // It's for unloading COM dll's: don't change it.
+ CloseOpenFolders();
+ _sevenZipContextMenu.Release();
+ _systemContextMenu.Release();
+}
+
+CPanel::~CPanel()
+{
+ CloseOpenFolders();
+}
+
+static LPCWSTR kClassName = L"7-Zip::Panel";
+
+
+LRESULT CPanel::Create(HWND mainWindow, HWND parentWindow, UINT id,
+ const UString &currentFolderPrefix, CPanelCallback *panelCallback, CAppState *appState,
+ bool &archiveIsOpened, bool &encrypted)
+{
+ _mainWindow = mainWindow;
+ _processTimer = true;
+ _processNotify = true;
+
+ _panelCallback = panelCallback;
+ _appState = appState;
+ // _index = index;
+ _baseID = id;
+ _comboBoxID = _baseID + 3;
+ _statusBarID = _comboBoxID + 1;
+
+ UString cfp = currentFolderPrefix;
+
+ if (!currentFolderPrefix.IsEmpty())
+ if (currentFolderPrefix[0] == L'.')
+ if (!NFile::NDirectory::MyGetFullPathName(currentFolderPrefix, cfp))
+ cfp = currentFolderPrefix;
+ BindToPath(cfp, archiveIsOpened, encrypted);
+
+ if (!CreateEx(0, kClassName, 0, WS_CHILD | WS_VISIBLE,
+ 0, 0, _xSize, 260,
+ parentWindow, (HMENU)(UINT_PTR)id, g_hInstance))
+ return E_FAIL;
+ return S_OK;
+}
+
+LRESULT CPanel::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch(message)
+ {
+ case kShiftSelectMessage:
+ OnShiftSelectMessage();
+ return 0;
+ case kReLoadMessage:
+ RefreshListCtrl(_selectedState);
+ return 0;
+ case kSetFocusToListView:
+ _listView.SetFocus();
+ return 0;
+ case kOpenItemChanged:
+ return OnOpenItemChanged(lParam);
+ case kRefreshStatusBar:
+ OnRefreshStatusBar();
+ return 0;
+ case WM_TIMER:
+ OnTimer();
+ return 0;
+ case WM_CONTEXTMENU:
+ if (OnContextMenu(HANDLE(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)))
+ return 0;
+ break;
+ /*
+ case WM_DROPFILES:
+ CompressDropFiles(HDROP(wParam));
+ return 0;
+ */
+ }
+ return CWindow2::OnMessage(message, wParam, lParam);
+}
+
+static LRESULT APIENTRY ListViewSubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ CWindow tempDialog(hwnd);
+ CMyListView *w = (CMyListView *)(tempDialog.GetUserDataLongPtr());
+ if (w == NULL)
+ return 0;
+ return w->OnMessage(message, wParam, lParam);
+}
+
+LRESULT CMyListView::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ if (message == WM_CHAR)
+ {
+ UINT scanCode = (UINT)((lParam >> 16) & 0xFF);
+ bool extended = ((lParam & 0x1000000) != 0);
+ UINT virtualKey = MapVirtualKey(scanCode, 1);
+ if (virtualKey == VK_MULTIPLY || virtualKey == VK_ADD ||
+ virtualKey == VK_SUBTRACT)
+ return 0;
+ if ((wParam == '/' && extended)
+ || wParam == '\\' || wParam == '/')
+ {
+ _panel->OpenDrivesFolder();
+ return 0;
+ }
+ }
+ else if (message == WM_SYSCHAR)
+ {
+ // For Alt+Enter Beep disabling
+ UINT scanCode = (UINT)(lParam >> 16) & 0xFF;
+ UINT virtualKey = MapVirtualKey(scanCode, 1);
+ if (virtualKey == VK_RETURN || virtualKey == VK_MULTIPLY ||
+ virtualKey == VK_ADD || virtualKey == VK_SUBTRACT)
+ return 0;
+ }
+ /*
+ else if (message == WM_SYSKEYDOWN)
+ {
+ // return 0;
+ }
+ */
+ else if (message == WM_KEYDOWN)
+ {
+ bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0;
+ bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0;
+ // bool leftCtrl = (::GetKeyState(VK_LCONTROL) & 0x8000) != 0;
+ // bool RightCtrl = (::GetKeyState(VK_RCONTROL) & 0x8000) != 0;
+ bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0;
+ switch(wParam)
+ {
+ case VK_RETURN:
+ {
+ if (shift && !alt && !ctrl)
+ {
+ _panel->OpenSelectedItems(false);
+ return 0;
+ }
+ break;
+ }
+ case VK_NEXT:
+ {
+ if (ctrl && !alt && !shift)
+ {
+ _panel->OpenFocusedItemAsInternal();
+ return 0;
+ }
+ break;
+ }
+ case VK_PRIOR:
+ if (ctrl && !alt && !shift)
+ {
+ _panel->OpenParentFolder();
+ return 0;
+ }
+ }
+ }
+ else if (message == WM_SETFOCUS)
+ {
+ _panel->_lastFocusedIsList = true;
+ _panel->_panelCallback->PanelWasFocused();
+ }
+ #ifndef _UNICODE
+ if (g_IsNT)
+ return CallWindowProcW(_origWindowProc, *this, message, wParam, lParam);
+ else
+ #endif
+ return CallWindowProc(_origWindowProc, *this, message, wParam, lParam);
+}
+
+/*
+static LRESULT APIENTRY ComboBoxSubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ CWindow tempDialog(hwnd);
+ CMyComboBox *w = (CMyComboBox *)(tempDialog.GetUserDataLongPtr());
+ if (w == NULL)
+ return 0;
+ return w->OnMessage(message, wParam, lParam);
+}
+
+LRESULT CMyComboBox::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ return CallWindowProc(_origWindowProc, *this, message, wParam, lParam);
+}
+*/
+static LRESULT APIENTRY ComboBoxEditSubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ CWindow tempDialog(hwnd);
+ CMyComboBoxEdit *w = (CMyComboBoxEdit *)(tempDialog.GetUserDataLongPtr());
+ if (w == NULL)
+ return 0;
+ return w->OnMessage(message, wParam, lParam);
+}
+
+LRESULT CMyComboBoxEdit::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ // See MSDN / Subclassing a Combo Box / Creating a Combo-box Toolbar
+ switch (message)
+ {
+ case WM_SYSKEYDOWN:
+ switch (wParam)
+ {
+ case VK_F1:
+ case VK_F2:
+ {
+ // check ALT
+ if ((lParam & (1<<29)) == 0)
+ break;
+ bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0;
+ bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0;
+ bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0;
+ if (alt && !ctrl && !shift)
+ {
+ _panel->_panelCallback->SetFocusToPath(wParam == VK_F1 ? 0 : 1);
+ return 0;
+ }
+ break;
+ }
+ }
+ break;
+ case WM_KEYDOWN:
+ switch (wParam)
+ {
+ case VK_TAB:
+ // SendMessage(hwndMain, WM_ENTER, 0, 0);
+ _panel->SetFocusToList();
+ return 0;
+ case VK_F9:
+ {
+ bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0;
+ bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0;
+ bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0;
+ if (!alt && !ctrl && !shift)
+ {
+ g_App.SwitchOnOffOnePanel();;
+ return 0;
+ }
+ break;
+ }
+ }
+ break;
+ case WM_CHAR:
+ switch (wParam)
+ {
+ case VK_TAB:
+ case VK_ESCAPE:
+ return 0;
+ }
+ }
+ #ifndef _UNICODE
+ if (g_IsNT)
+ return CallWindowProcW(_origWindowProc, *this, message, wParam, lParam);
+ else
+ #endif
+ return CallWindowProc(_origWindowProc, *this, message, wParam, lParam);
+}
+
+bool CPanel::OnCreate(CREATESTRUCT * /* createStruct */)
+{
+ // _virtualMode = false;
+ // _sortIndex = 0;
+ _sortID = kpidName;
+ _ascending = true;
+ _lastFocusedIsList = true;
+
+ DWORD style = WS_CHILD | WS_VISIBLE; // | WS_BORDER ; // | LVS_SHAREIMAGELISTS; // | LVS_SHOWSELALWAYS;;
+
+ style |= LVS_SHAREIMAGELISTS;
+ // style |= LVS_AUTOARRANGE;
+ style |= WS_CLIPCHILDREN;
+ style |= WS_CLIPSIBLINGS;
+
+ const UINT32 kNumListModes = sizeof(kStyles) / sizeof(kStyles[0]);
+ if (_ListViewMode >= kNumListModes)
+ _ListViewMode = kNumListModes - 1;
+
+ style |= kStyles[_ListViewMode]
+ | WS_TABSTOP
+ | LVS_EDITLABELS;
+ if (_mySelectMode)
+ style |= LVS_SINGLESEL;
+
+ /*
+ if (_virtualMode)
+ style |= LVS_OWNERDATA;
+ */
+
+ DWORD exStyle;
+ exStyle = WS_EX_CLIENTEDGE;
+
+ if (!_listView.CreateEx(exStyle, style, 0, 0, 116, 260,
+ HWND(*this), (HMENU)(UINT_PTR)(_baseID + 1), g_hInstance, NULL))
+ return false;
+
+ _listView.SetUnicodeFormat(true);
+
+ _listView.SetUserDataLongPtr(LONG_PTR(&_listView));
+ _listView._panel = this;
+
+ #ifndef _UNICODE
+ if(g_IsNT)
+ _listView._origWindowProc =
+ (WNDPROC)_listView.SetLongPtrW(GWLP_WNDPROC, LONG_PTR(ListViewSubclassProc));
+ else
+ #endif
+ _listView._origWindowProc =
+ (WNDPROC)_listView.SetLongPtr(GWLP_WNDPROC, LONG_PTR(ListViewSubclassProc));
+
+ SHFILEINFO shellInfo;
+ HIMAGELIST imageList = (HIMAGELIST)SHGetFileInfo(TEXT(""),
+ FILE_ATTRIBUTE_NORMAL |
+ FILE_ATTRIBUTE_DIRECTORY,
+ &shellInfo, sizeof(shellInfo),
+ SHGFI_USEFILEATTRIBUTES |
+ SHGFI_SYSICONINDEX |
+ SHGFI_SMALLICON
+ );
+ _listView.SetImageList(imageList, LVSIL_SMALL);
+ imageList = (HIMAGELIST)SHGetFileInfo(TEXT(""),
+ FILE_ATTRIBUTE_NORMAL |
+ FILE_ATTRIBUTE_DIRECTORY,
+ &shellInfo, sizeof(shellInfo),
+ SHGFI_USEFILEATTRIBUTES |
+ SHGFI_SYSICONINDEX |
+ SHGFI_ICON
+ );
+ _listView.SetImageList(imageList, LVSIL_NORMAL);
+
+ // _exStyle |= LVS_EX_HEADERDRAGDROP;
+ // DWORD extendedStyle = _listView.GetExtendedListViewStyle();
+ // extendedStyle |= _exStyle;
+ // _listView.SetExtendedListViewStyle(extendedStyle);
+ SetExtendedStyle();
+
+ _listView.Show(SW_SHOW);
+ _listView.InvalidateRect(NULL, true);
+ _listView.Update();
+
+ // Ensure that the common control DLL is loaded.
+ INITCOMMONCONTROLSEX icex;
+
+ icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
+ icex.dwICC = ICC_BAR_CLASSES;
+ InitCommonControlsEx(&icex);
+
+ TBBUTTON tbb [ ] =
+ {
+ // {0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0},
+ {VIEW_PARENTFOLDER, kParentFolderID, TBSTATE_ENABLED, BTNS_BUTTON, 0L, 0},
+ // {0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0},
+ // {VIEW_NEWFOLDER, kCreateFolderID, TBSTATE_ENABLED, BTNS_BUTTON, 0L, 0},
+ };
+
+ if (g_ComCtl32Version >= MAKELONG(71, 4))
+ {
+ icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
+ icex.dwICC = ICC_COOL_CLASSES | ICC_BAR_CLASSES;
+ InitCommonControlsEx(&icex);
+
+ _headerReBar.Attach(::CreateWindowEx(WS_EX_TOOLWINDOW,
+ REBARCLASSNAME,
+ NULL, WS_VISIBLE | WS_BORDER | WS_CHILD |
+ WS_CLIPCHILDREN | WS_CLIPSIBLINGS
+ | CCS_NODIVIDER
+ | CCS_NOPARENTALIGN
+ | CCS_TOP
+ | RBS_VARHEIGHT
+ | RBS_BANDBORDERS
+ ,0,0,0,0, HWND(*this), NULL, g_hInstance, NULL));
+ }
+
+ DWORD toolbarStyle = WS_CHILD | WS_VISIBLE ;
+ if (_headerReBar)
+ {
+ toolbarStyle |= 0
+ // | WS_CLIPCHILDREN
+ // | WS_CLIPSIBLINGS
+
+ | TBSTYLE_TOOLTIPS
+ | CCS_NODIVIDER
+ | CCS_NORESIZE
+ | TBSTYLE_FLAT
+ ;
+ }
+
+ _headerToolBar.Attach(::CreateToolbarEx ((*this), toolbarStyle,
+ _baseID + 2, 11,
+ (HINSTANCE)HINST_COMMCTRL,
+ IDB_VIEW_SMALL_COLOR,
+ (LPCTBBUTTON)&tbb, sizeof(tbb) / sizeof(tbb[0]),
+ 0, 0, 0, 0, sizeof (TBBUTTON)));
+
+ icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
+ icex.dwICC = ICC_USEREX_CLASSES;
+ InitCommonControlsEx(&icex);
+
+ _headerComboBox.CreateEx(0, WC_COMBOBOXEXW, NULL,
+ WS_BORDER | WS_VISIBLE |WS_CHILD | CBS_DROPDOWN | CBS_AUTOHSCROLL,
+ 0, 0, 100, 20,
+ ((_headerReBar == 0) ? HWND(*this) : _headerToolBar),
+ (HMENU)(UINT_PTR)(_comboBoxID),
+ g_hInstance, NULL);
+ // _headerComboBox.SendMessage(CBEM_SETUNICODEFORMAT, (WPARAM)(BOOL)TRUE, 0);
+
+
+ _headerComboBox.SetExtendedStyle(CBES_EX_PATHWORDBREAKPROC, CBES_EX_PATHWORDBREAKPROC);
+
+ /*
+ _headerComboBox.SetUserDataLongPtr(LONG_PTR(&_headerComboBox));
+ _headerComboBox._panel = this;
+ _headerComboBox._origWindowProc =
+ (WNDPROC)_headerComboBox.SetLongPtr(GWLP_WNDPROC,
+ LONG_PTR(ComboBoxSubclassProc));
+ */
+ _comboBoxEdit.Attach(_headerComboBox.GetEditControl());
+
+ // _comboBoxEdit.SendMessage(CCM_SETUNICODEFORMAT, (WPARAM)(BOOL)TRUE, 0);
+
+ _comboBoxEdit.SetUserDataLongPtr(LONG_PTR(&_comboBoxEdit));
+ _comboBoxEdit._panel = this;
+ #ifndef _UNICODE
+ if(g_IsNT)
+ _comboBoxEdit._origWindowProc =
+ (WNDPROC)_comboBoxEdit.SetLongPtrW(GWLP_WNDPROC, LONG_PTR(ComboBoxEditSubclassProc));
+ else
+ #endif
+ _comboBoxEdit._origWindowProc =
+ (WNDPROC)_comboBoxEdit.SetLongPtr(GWLP_WNDPROC, LONG_PTR(ComboBoxEditSubclassProc));
+
+
+
+ if (_headerReBar)
+ {
+ REBARINFO rbi;
+ rbi.cbSize = sizeof(REBARINFO); // Required when using this struct.
+ rbi.fMask = 0;
+ rbi.himl = (HIMAGELIST)NULL;
+ _headerReBar.SetBarInfo(&rbi);
+
+ // Send the TB_BUTTONSTRUCTSIZE message, which is required for
+ // backward compatibility.
+ // _headerToolBar.SendMessage(TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
+ SIZE size;
+ _headerToolBar.GetMaxSize(&size);
+
+ REBARBANDINFO rbBand;
+ rbBand.cbSize = sizeof(REBARBANDINFO); // Required
+ rbBand.fMask = RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE;
+ rbBand.fStyle = RBBS_NOGRIPPER;
+ rbBand.cxMinChild = size.cx;
+ rbBand.cyMinChild = size.cy;
+ rbBand.cyChild = size.cy;
+ rbBand.cx = size.cx;
+ rbBand.hwndChild = _headerToolBar;
+ _headerReBar.InsertBand(-1, &rbBand);
+
+ RECT rc;
+ ::GetWindowRect(_headerComboBox, &rc);
+ rbBand.cxMinChild = 30;
+ rbBand.cyMinChild = rc.bottom - rc.top;
+ rbBand.cx = 1000;
+ rbBand.hwndChild = _headerComboBox;
+ _headerReBar.InsertBand(-1, &rbBand);
+ // _headerReBar.MaximizeBand(1, false);
+ }
+
+ _statusBar.Create(WS_CHILD | WS_VISIBLE, L"Status", (*this), _statusBarID);
+ // _statusBar2.Create(WS_CHILD | WS_VISIBLE, L"Status", (*this), _statusBarID + 1);
+
+ int sizes[] = {150, 200, 250, -1};
+ _statusBar.SetParts(4, sizes);
+ // _statusBar2.SetParts(5, sizes);
+
+ /*
+ RECT rect;
+ GetClientRect(&rect);
+ OnSize(0, rect.right - rect.left, rect.top - rect.bottom);
+ */
+
+ SetTimer(kTimerID, kTimerElapse);
+
+ // InitListCtrl();
+ RefreshListCtrl();
+ RefreshStatusBar();
+
+ return true;
+}
+
+void CPanel::OnDestroy()
+{
+ SaveListViewInfo();
+ CWindow2::OnDestroy();
+}
+
+void CPanel::ChangeWindowSize(int xSize, int ySize)
+{
+ int kHeaderSize;
+ int kStatusBarSize;
+ // int kStatusBar2Size;
+ RECT rect;
+ if (_headerReBar)
+ _headerReBar.GetWindowRect(&rect);
+ else
+ _headerToolBar.GetWindowRect(&rect);
+
+ kHeaderSize = rect.bottom - rect.top;
+
+ _statusBar.GetWindowRect(&rect);
+ kStatusBarSize = rect.bottom - rect.top;
+
+ // _statusBar2.GetWindowRect(&rect);
+ // kStatusBar2Size = rect.bottom - rect.top;
+
+ int yListViewSize = MyMax(ySize - kHeaderSize - kStatusBarSize, 0);
+ const int kStartXPos = 32;
+ if (_headerReBar)
+ {
+ }
+ else
+ {
+ _headerToolBar.Move(0, 0, xSize, 0);
+ _headerComboBox.Move(kStartXPos, 2,
+ MyMax(xSize - kStartXPos - 10, kStartXPos), 0);
+ }
+ _listView.Move(0, kHeaderSize, xSize, yListViewSize);
+ _statusBar.Move(0, kHeaderSize + yListViewSize, xSize, kStatusBarSize);
+ // _statusBar2.MoveWindow(0, kHeaderSize + yListViewSize + kStatusBarSize, xSize, kStatusBar2Size);
+ // _statusBar.MoveWindow(0, 100, xSize, kStatusBarSize);
+ // _statusBar2.MoveWindow(0, 200, xSize, kStatusBar2Size);
+}
+
+bool CPanel::OnSize(WPARAM /* wParam */, int xSize, int ySize)
+{
+ if (_headerReBar)
+ _headerReBar.Move(0, 0, xSize, 0);
+ ChangeWindowSize(xSize, ySize);
+ return true;
+}
+
+bool CPanel::OnNotifyReBar(LPNMHDR header, LRESULT & /* result */)
+{
+ switch(header->code)
+ {
+ case RBN_HEIGHTCHANGE:
+ {
+ RECT rect;
+ GetWindowRect(&rect);
+ ChangeWindowSize(rect.right - rect.left, rect.bottom - rect.top);
+ return false;
+ }
+ }
+ return false;
+}
+
+bool CPanel::OnNotify(UINT /* controlID */, LPNMHDR header, LRESULT &result)
+{
+ if (!_processNotify)
+ return false;
+ if (header->hwndFrom == _headerComboBox)
+ return OnNotifyComboBox(header, result);
+ else if (header->hwndFrom == _headerReBar)
+ return OnNotifyReBar(header, result);
+ // if (header->hwndFrom == _listView)
+ else if (header->hwndFrom == _listView)
+ return OnNotifyList(header, result);
+ else if (::GetParent(header->hwndFrom) == _listView &&
+ header->code == NM_RCLICK)
+ return OnRightClick((LPNMITEMACTIVATE)header, result);
+ return false;
+}
+
+bool CPanel::OnCommand(int code, int itemID, LPARAM lParam, LRESULT &result)
+{
+ if (itemID == kParentFolderID)
+ {
+ OpenParentFolder();
+ result = 0;
+ return true;
+ }
+ /*
+ if (itemID == kCreateFolderID)
+ {
+ CreateFolder();
+ result = 0;
+ return true;
+ }
+ */
+ if (itemID == _comboBoxID)
+ {
+ OnComboBoxCommand(code, lParam);
+ }
+ return CWindow2::OnCommand(code, itemID, lParam, result);
+}
+
+void CPanel::MessageBoxInfo(LPCWSTR message, LPCWSTR caption)
+ { ::MessageBoxW(HWND(*this), message, caption, MB_OK); }
+void CPanel::MessageBox(LPCWSTR message, LPCWSTR caption)
+ { ::MessageBoxW(HWND(*this), message, caption, MB_OK | MB_ICONSTOP); }
+void CPanel::MessageBox(LPCWSTR message)
+ { MessageBox(message, L"7-Zip"); }
+void CPanel::MessageBoxMyError(LPCWSTR message)
+ { MessageBox(message, L"Error"); }
+void CPanel::MessageBoxError(HRESULT errorCode, LPCWSTR caption)
+ { MessageBox(NError::MyFormatMessageW(errorCode), caption); }
+void CPanel::MessageBoxError(HRESULT errorCode)
+ { MessageBoxError(errorCode, L"7-Zip"); }
+void CPanel::MessageBoxLastError(LPCWSTR caption)
+ { MessageBoxError(::GetLastError(), caption); }
+void CPanel::MessageBoxLastError()
+ { MessageBoxLastError(L"Error"); }
+
+void CPanel::SetFocusToList()
+{
+ _listView.SetFocus();
+ // SetCurrentPathText();
+}
+
+void CPanel::SetFocusToLastRememberedItem()
+{
+ if (_lastFocusedIsList)
+ SetFocusToList();
+ else
+ _headerComboBox.SetFocus();
+}
+
+UString CPanel::GetFolderTypeID() const
+{
+ CMyComPtr<IFolderGetTypeID> folderGetTypeID;
+ if(_folder.QueryInterface(IID_IFolderGetTypeID, &folderGetTypeID) != S_OK)
+ return L"";
+ CMyComBSTR typeID;
+ folderGetTypeID->GetTypeID(&typeID);
+ return (wchar_t *)typeID;
+}
+
+bool CPanel::IsRootFolder() const
+{
+ return (GetFolderTypeID() == L"RootFolder");
+}
+
+bool CPanel::IsFSFolder() const
+{
+ return (GetFolderTypeID() == L"FSFolder");
+}
+
+bool CPanel::IsFSDrivesFolder() const
+{
+ return (GetFolderTypeID() == L"FSDrives");
+}
+
+UString CPanel::GetFsPath() const
+{
+ if (IsFSDrivesFolder())
+ return UString();
+ return _currentFolderPrefix;
+}
+
+UString CPanel::GetDriveOrNetworkPrefix() const
+{
+ if (!IsFSFolder())
+ return UString();
+ UString drive = GetFsPath();
+ if (drive.Length() < 3)
+ return UString();
+ if (drive[0] == L'\\' && drive[1] == L'\\')
+ {
+ // if network
+ int pos = drive.Find(L'\\', 2);
+ if (pos < 0)
+ return UString();
+ pos = drive.Find(L'\\', pos + 1);
+ if (pos < 0)
+ return UString();
+ return drive.Left(pos + 1);
+ }
+ if (drive[1] != L':' || drive[2] != L'\\')
+ return UString();
+ return drive.Left(3);
+}
+
+bool CPanel::DoesItSupportOperations() const
+{
+ CMyComPtr<IFolderOperations> folderOperations;
+ return _folder.QueryInterface(IID_IFolderOperations, &folderOperations) == S_OK;
+}
+
+void CPanel::SetListViewMode(UINT32 index)
+{
+ if (index >= 4)
+ return;
+ _ListViewMode = index;
+ DWORD oldStyle = (DWORD)_listView.GetStyle();
+ DWORD newStyle = kStyles[index];
+ if ((oldStyle & LVS_TYPEMASK) != newStyle)
+ _listView.SetStyle((oldStyle & ~LVS_TYPEMASK) | newStyle);
+ // RefreshListCtrlSaveFocused();
+}
+
+void CPanel::ChangeFlatMode()
+{
+ _flatMode = !_flatMode;
+ RefreshListCtrlSaveFocused();
+}
+
+
+void CPanel::RefreshStatusBar()
+{
+ PostMessage(kRefreshStatusBar);
+}
+
+void CPanel::AddToArchive()
+{
+ CRecordVector<UINT32> indices;
+ GetOperatedItemIndices(indices);
+ if (!IsFSFolder())
+ {
+ MessageBox(L"Compress operation is not supported for that folder");
+ return;
+ }
+ if (indices.Size() == 0)
+ {
+ MessageBox(kSelectFiles);
+ return;
+ }
+ UStringVector names;
+ for (int i = 0; i < indices.Size(); i++)
+ {
+ int index = indices[i];
+ names.Add(_currentFolderPrefix + GetItemRelPath(index));
+ }
+ const UString archiveName = CreateArchiveName(
+ names.Front(), (names.Size() > 1), false);
+ HRESULT res = CompressFiles(_currentFolderPrefix, archiveName, L"", names, false, true, false);
+ if (res != S_OK)
+ {
+ if (_currentFolderPrefix.Length() >= MAX_PATH)
+ MessageBox(L"Can't call this operation for file with long path");
+ else
+ MessageBoxError(res, L"Error");
+ }
+ // KillSelection();
+}
+
+static UString GetSubFolderNameForExtract(const UString &archiveName)
+{
+ int slashPos = archiveName.ReverseFind(L'\\');
+ int dotPos = archiveName.ReverseFind(L'.');
+ if (dotPos < 0 || slashPos > dotPos)
+ return archiveName + UString(L"~");
+ UString res = archiveName.Left(dotPos);
+ res.TrimRight();
+ return res;
+}
+
+void CPanel::ExtractArchives()
+{
+ if (_parentFolders.Size() > 0)
+ {
+ _panelCallback->OnCopy(false, false);
+ return;
+ }
+ CRecordVector<UINT32> indices;
+ GetOperatedItemIndices(indices);
+ UStringVector paths;
+ if (indices.Size() == 0)
+ {
+ MessageBox(kSelectOneFile);
+ return;
+ }
+ for (int i = 0; i < indices.Size(); i++)
+ {
+ int index = indices[i];
+ if (IsItemFolder(index))
+ {
+ MessageBox(kSelectOneFile);
+ return;
+ }
+ paths.Add(_currentFolderPrefix + GetItemRelPath(index));
+ }
+ UString folderName;
+ if (indices.Size() == 1)
+ folderName = GetSubFolderNameForExtract(GetItemRelPath(indices[0]));
+ else
+ folderName = L"*";
+ ::ExtractArchives(paths, _currentFolderPrefix + folderName + UString(L"\\"), true);
+}
+
+void CPanel::TestArchives()
+{
+ CRecordVector<UINT32> indices;
+ GetOperatedItemIndices(indices);
+ if (!IsFSFolder())
+ {
+ MessageBox(L"Test archive operation is not supported for that folder");
+ return;
+ }
+ UStringVector paths;
+ if (indices.Size() == 0)
+ {
+ MessageBox(kSelectOneFile);
+ return;
+ }
+ for (int i = 0; i < indices.Size(); i++)
+ {
+ int index = indices[i];
+ if (IsItemFolder(index))
+ {
+ MessageBox(kSelectOneFile);
+ return;
+ }
+ paths.Add(_currentFolderPrefix + GetItemRelPath(index));
+ }
+ ::TestArchives(paths);
+}
+
diff --git a/CPP/7zip/FileManager/Panel.h b/CPP/7zip/FileManager/Panel.h
new file mode 100755
index 00000000..ba0e0884
--- /dev/null
+++ b/CPP/7zip/FileManager/Panel.h
@@ -0,0 +1,510 @@
+// Panel.h
+
+#ifndef __PANEL_H
+#define __PANEL_H
+
+#include "Common/MyCom.h"
+
+#include "Windows/DLL.h"
+#include "Windows/FileFind.h"
+#include "Windows/FileDir.h"
+#include "Windows/Synchronization.h"
+#include "Windows/Handle.h"
+
+#include "Windows/Control/ToolBar.h"
+#include "Windows/Control/ReBar.h"
+#include "Windows/Control/ListView.h"
+#include "Windows/Control/Static.h"
+#include "Windows/Control/Edit.h"
+#include "Windows/Control/ComboBox.h"
+#include "Windows/Control/Window2.h"
+#include "Windows/Control/StatusBar.h"
+
+#include "SysIconUtils.h"
+#include "IFolder.h"
+#include "ViewSettings.h"
+#include "AppState.h"
+#include "MyCom2.h"
+
+const int kParentFolderID = 100;
+const int kPluginMenuStartID = 1000;
+const int kToolbarStartID = 2000;
+
+const int kParentIndex = -1;
+
+class CPanelCallback
+{
+public:
+ virtual void OnTab() = 0;
+ virtual void SetFocusToPath(int index) = 0;
+ virtual void OnCopy(bool move, bool copyToSame) = 0;
+ virtual void OnSetSameFolder() = 0;
+ virtual void OnSetSubFolder() = 0;
+ virtual void PanelWasFocused() = 0;
+ virtual void DragBegin() = 0;
+ virtual void DragEnd() = 0;
+};
+
+void PanelCopyItems();
+
+struct CItemProperty
+{
+ UString Name;
+ PROPID ID;
+ VARTYPE Type;
+ int Order;
+ bool IsVisible;
+ UInt32 Width;
+};
+
+inline bool operator<(const CItemProperty &a1, const CItemProperty &a2)
+ { return (a1.Order < a2.Order); }
+
+inline bool operator==(const CItemProperty &a1, const CItemProperty &a2)
+ { return (a1.Order == a2.Order); }
+
+class CItemProperties: public CObjectVector<CItemProperty>
+{
+public:
+ int FindItemWithID(PROPID id)
+ {
+ for (int i = 0; i < Size(); i++)
+ if ((*this)[i].ID == id)
+ return i;
+ return -1;
+ }
+};
+
+struct CTempFileInfo
+{
+ UString ItemName;
+ UString FolderPath;
+ UString FilePath;
+ NWindows::NFile::NFind::CFileInfoW FileInfo;
+ void DeleteDirAndFile()
+ {
+ NWindows::NFile::NDirectory::DeleteFileAlways(FilePath);
+ NWindows::NFile::NDirectory::MyRemoveDirectory(FolderPath);
+ }
+};
+
+struct CFolderLink: public CTempFileInfo
+{
+ NWindows::NDLL::CLibrary Library;
+ CMyComPtr<IFolderFolder> ParentFolder;
+};
+
+enum MyMessages
+{
+ kShiftSelectMessage = WM_USER + 1,
+ kReLoadMessage,
+ kSetFocusToListView,
+ kOpenItemChanged,
+ kRefreshStatusBar
+};
+
+UString GetFolderPath(IFolderFolder * folder);
+
+class CPanel;
+
+class CMyListView: public NWindows::NControl::CListView
+{
+public:
+ WNDPROC _origWindowProc;
+ CPanel *_panel;
+ LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+};
+
+/*
+class CMyComboBox: public NWindows::NControl::CComboBoxEx
+{
+public:
+ WNDPROC _origWindowProc;
+ CPanel *_panel;
+ LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+};
+*/
+class CMyComboBoxEdit: public NWindows::NControl::CEdit
+{
+public:
+ WNDPROC _origWindowProc;
+ CPanel *_panel;
+ LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+};
+
+struct CSelectedState
+{
+ int FocusedItem;
+ UString FocusedName;
+ bool SelectFocused;
+ UStringVector SelectedNames;
+ CSelectedState(): FocusedItem(-1), SelectFocused(false) {}
+};
+
+class CPanel:public NWindows::NControl::CWindow2
+{
+ HWND _mainWindow;
+
+ CExtToIconMap _extToIconMap;
+ UINT _baseID;
+ int _comboBoxID;
+ UINT _statusBarID;
+
+ CAppState *_appState;
+
+ bool OnCommand(int code, int itemID, LPARAM lParam, LRESULT &result);
+ LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+ virtual bool OnCreate(CREATESTRUCT *createStruct);
+ virtual bool OnSize(WPARAM wParam, int xSize, int ySize);
+ virtual void OnDestroy();
+ virtual bool OnNotify(UINT controlID, LPNMHDR lParam, LRESULT &result);
+ void OnComboBoxCommand(UINT code, LPARAM &aParam);
+ bool OnNotifyComboBoxEndEdit(PNMCBEENDEDITW info, LRESULT &result);
+ #ifndef _UNICODE
+ bool OnNotifyComboBoxEndEdit(PNMCBEENDEDIT info, LRESULT &result);
+ #endif
+ bool OnNotifyReBar(LPNMHDR lParam, LRESULT &result);
+ bool OnNotifyComboBox(LPNMHDR lParam, LRESULT &result);
+ void OnItemChanged(NMLISTVIEW *item);
+ bool OnNotifyList(LPNMHDR lParam, LRESULT &result);
+ void OnDrag(LPNMLISTVIEW nmListView);
+ bool OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result);
+ BOOL OnBeginLabelEdit(LV_DISPINFOW * lpnmh);
+ BOOL OnEndLabelEdit(LV_DISPINFOW * lpnmh);
+ void OnColumnClick(LPNMLISTVIEW info);
+ bool OnCustomDraw(LPNMLVCUSTOMDRAW lplvcd, LRESULT &result);
+
+public:
+ CPanelCallback *_panelCallback;
+
+ void DeleteItems(bool toRecycleBin);
+ void DeleteItemsInternal(CRecordVector<UInt32> &indices);
+ void CreateFolder();
+ void CreateFile();
+
+private:
+
+ void ChangeWindowSize(int xSize, int ySize);
+
+ void InitColumns();
+ // void InitColumns2(PROPID sortID);
+ void InsertColumn(int index);
+
+ void SetFocusedSelectedItem(int index, bool select);
+ void RefreshListCtrl(const UString &focusedName, int focusedPos, bool selectFocused,
+ const UStringVector &selectedNames);
+
+ void OnShiftSelectMessage();
+ void OnArrowWithShift();
+
+ void OnInsert();
+ // void OnUpWithShift();
+ // void OnDownWithShift();
+public:
+ void UpdateSelection();
+ void SelectSpec(bool selectMode);
+ void SelectByType(bool selectMode);
+ void SelectAll(bool selectMode);
+ void InvertSelection();
+private:
+
+ // UString GetFileType(UInt32 index);
+ LRESULT SetItemText(LVITEMW &item);
+
+ // CRecordVector<PROPID> m_ColumnsPropIDs;
+
+public:
+ NWindows::NControl::CReBar _headerReBar;
+ NWindows::NControl::CToolBar _headerToolBar;
+ NWindows::NControl::CComboBoxEx _headerComboBox;
+ // CMyComboBox _headerComboBox;
+ CMyComboBoxEdit _comboBoxEdit;
+ CMyListView _listView;
+ NWindows::NControl::CStatusBar _statusBar;
+ bool _lastFocusedIsList;
+ // NWindows::NControl::CStatusBar _statusBar2;
+
+ DWORD _exStyle;
+ bool _showDots;
+ bool _showRealFileIcons;
+ // bool _virtualMode;
+ // CUIntVector _realIndices;
+ bool _enableItemChangeNotify;
+ bool _mySelectMode;
+ CBoolVector _selectedStatusVector;
+
+ CSelectedState _selectedState;
+
+ UInt32 GetRealIndex(const LVITEMW &item) const
+ {
+ /*
+ if (_virtualMode)
+ return _realIndices[item.iItem];
+ */
+ return (UInt32)item.lParam;
+ }
+ int GetRealItemIndex(int indexInListView) const
+ {
+ /*
+ if (_virtualMode)
+ return indexInListView;
+ */
+ LPARAM param;
+ if (!_listView.GetItemParam(indexInListView, param))
+ throw 1;
+ return (int)param;
+ }
+
+ UInt32 _ListViewMode;
+ int _xSize;
+
+ bool _flatMode;
+
+ bool _dontShowMode;
+
+
+ UString _currentFolderPrefix;
+
+ CObjectVector<CFolderLink> _parentFolders;
+ NWindows::NDLL::CLibrary _library;
+ CMyComPtr<IFolderFolder> _folder;
+ // CMyComPtr<IFolderGetSystemIconIndex> _folderGetSystemIconIndex;
+
+ UStringVector _fastFolders;
+
+ void GetSelectedNames(UStringVector &selectedNames);
+ void SaveSelectedState(CSelectedState &s);
+ void RefreshListCtrl(const CSelectedState &s);
+ void RefreshListCtrlSaveFocused();
+
+ UString GetItemName(int itemIndex) const;
+ UString GetItemPrefix(int itemIndex) const;
+ UString GetItemRelPath(int itemIndex) const;
+ bool IsItemFolder(int itemIndex) const;
+ UInt64 GetItemSize(int itemIndex) const;
+
+ ////////////////////////
+ // PanelFolderChange.cpp
+
+ void SetToRootFolder();
+ HRESULT BindToPath(const UString &fullPath, bool &archiveIsOpened, bool &encrypted); // can be prefix
+ HRESULT BindToPathAndRefresh(const UString &path);
+ void OpenDrivesFolder();
+
+ void SetBookmark(int index);
+ void OpenBookmark(int index);
+
+ void LoadFullPath();
+ void LoadFullPathAndShow();
+ void FoldersHistory();
+ void OpenParentFolder();
+ void CloseOpenFolders();
+ void OpenRootFolder();
+
+
+ LRESULT Create(HWND mainWindow, HWND parentWindow,
+ UINT id,
+ const UString &currentFolderPrefix,
+ CPanelCallback *panelCallback,
+ CAppState *appState, bool &archiveIsOpened, bool &encrypted);
+ void SetFocusToList();
+ void SetFocusToLastRememberedItem();
+
+
+ void ReadListViewInfo();
+ void SaveListViewInfo();
+
+ CPanel() :
+ // _virtualMode(flase),
+ _exStyle(0),
+ _showDots(false),
+ _showRealFileIcons(false),
+ _needSaveInfo(false),
+ _startGroupSelect(0),
+ _selectionIsDefined(false),
+ _ListViewMode(3),
+ _flatMode(false),
+ _xSize(300),
+ _mySelectMode(false),
+ _enableItemChangeNotify(true),
+ _dontShowMode(false)
+ {}
+
+ void SetExtendedStyle()
+ {
+ if (_listView != 0)
+ _listView.SetExtendedListViewStyle(_exStyle);
+ }
+
+
+ bool _needSaveInfo;
+ UString _typeIDString;
+ CListViewInfo _listViewInfo;
+ CItemProperties _properties;
+ CItemProperties _visibleProperties;
+
+ PROPID _sortID;
+ // int _sortIndex;
+ bool _ascending;
+
+ void Release();
+ ~CPanel();
+ void OnLeftClick(LPNMITEMACTIVATE itemActivate);
+ bool OnRightClick(LPNMITEMACTIVATE itemActivate, LRESULT &result);
+
+ void OnTimer();
+ void OnReload();
+ bool OnContextMenu(HANDLE windowHandle, int xPos, int yPos);
+
+ CMyComPtr<IContextMenu> _sevenZipContextMenu;
+ CMyComPtr<IContextMenu> _systemContextMenu;
+ HRESULT CreateShellContextMenu(
+ const CRecordVector<UInt32> &operatedIndices,
+ CMyComPtr<IContextMenu> &systemContextMenu);
+ void CreateSystemMenu(HMENU menu,
+ const CRecordVector<UInt32> &operatedIndices,
+ CMyComPtr<IContextMenu> &systemContextMenu);
+ void CreateSevenZipMenu(HMENU menu,
+ const CRecordVector<UInt32> &operatedIndices,
+ CMyComPtr<IContextMenu> &sevenZipContextMenu);
+ void CreateFileMenu(HMENU menu,
+ CMyComPtr<IContextMenu> &sevenZipContextMenu,
+ CMyComPtr<IContextMenu> &systemContextMenu,
+ bool programMenu);
+ void CreateFileMenu(HMENU menu);
+ bool InvokePluginCommand(int id);
+ bool InvokePluginCommand(int id, IContextMenu *sevenZipContextMenu,
+ IContextMenu *systemContextMenu);
+
+ void InvokeSystemCommand(const char *command);
+ void Properties();
+ void EditCopy();
+ void EditPaste();
+
+ int _startGroupSelect;
+
+ bool _selectionIsDefined;
+ bool _selectMark;
+ int _prevFocusedItem;
+
+
+ // void SortItems(int index);
+ void SortItemsWithPropID(PROPID propID);
+
+ void GetSelectedItemsIndices(CRecordVector<UInt32> &indices) const;
+ void GetOperatedItemIndices(CRecordVector<UInt32> &indices) const;
+ // void GetOperatedListViewIndices(CRecordVector<UInt32> &indices) const;
+ void KillSelection();
+
+ UString GetFolderTypeID() const;
+ bool IsRootFolder() const;
+ bool IsFSFolder() const;
+ bool IsFSDrivesFolder() const;
+
+ UString GetFsPath() const;
+ UString GetDriveOrNetworkPrefix() const;
+
+ bool DoesItSupportOperations() const;
+
+ bool _processTimer;
+ bool _processNotify;
+
+ class CDisableTimerProcessing
+ {
+ bool _processTimerMem;
+ bool _processNotifyMem;
+
+ CPanel &_panel;
+ public:
+
+ CDisableTimerProcessing(CPanel &panel): _panel(panel)
+ {
+ Disable();
+ }
+ void Disable()
+ {
+ _processTimerMem = _panel._processTimer;
+ _processNotifyMem = _panel._processNotify;
+ _panel._processTimer = false;
+ _panel._processNotify = false;
+ }
+ void Restore()
+ {
+ _panel._processTimer = _processTimerMem;
+ _panel._processNotify = _processNotifyMem;
+ }
+ ~CDisableTimerProcessing()
+ {
+ Restore();
+ }
+ CDisableTimerProcessing& operator=(const CDisableTimerProcessing &) {; }
+ };
+
+ // bool _passwordIsDefined;
+ // UString _password;
+
+ void RefreshListCtrl();
+
+ void MessageBoxInfo(LPCWSTR message, LPCWSTR caption);
+ void MessageBox(LPCWSTR message);
+ void MessageBox(LPCWSTR message, LPCWSTR caption);
+ void MessageBoxMyError(LPCWSTR message);
+ void MessageBoxError(HRESULT errorCode, LPCWSTR caption);
+ void MessageBoxError(HRESULT errorCode);
+ void MessageBoxLastError(LPCWSTR caption);
+ void MessageBoxLastError();
+
+
+ void OpenFocusedItemAsInternal();
+ void OpenSelectedItems(bool internal);
+
+ void OpenFolderExternal(int index);
+
+ void OpenFolder(int index);
+ HRESULT OpenParentArchiveFolder();
+ HRESULT OpenItemAsArchive(const UString &name,
+ const UString &folderPath,
+ const UString &filePath, bool &encrypted);
+ HRESULT OpenItemAsArchive(const UString &aName);
+ HRESULT OpenItemAsArchive(int index);
+ void OpenItemInArchive(int index, bool tryInternal, bool tryExternal,
+ bool editMode);
+ HRESULT OnOpenItemChanged(const UString &folderPath, const UString &itemName);
+ LRESULT OnOpenItemChanged(LPARAM lParam);
+
+ void OpenItem(int index, bool tryInternal, bool tryExternal);
+ void EditItem();
+ void EditItem(int index);
+
+ void RenameFile();
+ void ChangeComment();
+
+ void SetListViewMode(UInt32 index);
+ UInt32 GetListViewMode() const { return _ListViewMode; };
+
+ void ChangeFlatMode();
+ bool GetFlatMode() const { return _flatMode; };
+
+ void RefreshStatusBar();
+ void OnRefreshStatusBar();
+
+ void AddToArchive();
+ void ExtractArchives();
+ void TestArchives();
+
+ HRESULT CopyTo(const CRecordVector<UInt32> &indices, const UString &folder,
+ bool moveMode, bool showErrorMessages, UStringVector *messages);
+
+ HRESULT CopyFrom(const UString &folderPrefix, const UStringVector &filePaths,
+ bool showErrorMessages, UStringVector *messages);
+
+ void CopyFrom(const UStringVector &filePaths);
+
+ // empty folderPath means create new Archive to path of first fileName.
+ void DropObject(IDataObject * dataObject, const UString &folderPath);
+
+ // empty folderPath means create new Archive to path of first fileName.
+ void CompressDropFiles(const UStringVector &fileNames, const UString &folderPath);
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/PanelCopy.cpp b/CPP/7zip/FileManager/PanelCopy.cpp
new file mode 100755
index 00000000..4b62b878
--- /dev/null
+++ b/CPP/7zip/FileManager/PanelCopy.cpp
@@ -0,0 +1,208 @@
+// PanelExtract.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/COM.h"
+
+#include "Panel.h"
+#include "resource.h"
+#include "LangUtils.h"
+#include "ExtractCallback.h"
+#include "Windows/Thread.h"
+////////////////////////////////////////////////////////////////
+
+#include "UpdateCallback100.h"
+
+using namespace NWindows;
+
+struct CThreadExtractInArchive2
+{
+ CMyComPtr<IFolderOperations> FolderOperations;
+ CRecordVector<UInt32> Indices;
+ UString DestPath;
+ CExtractCallbackImp *ExtractCallbackSpec;
+ CMyComPtr<IFolderOperationsExtractCallback> ExtractCallback;
+ HRESULT Result;
+ bool MoveMode;
+
+ CThreadExtractInArchive2(): MoveMode(false) {}
+
+ DWORD Extract()
+ {
+ // NCOM::CComInitializer comInitializer;
+ ExtractCallbackSpec->ProgressDialog.WaitCreating();
+ if (MoveMode)
+ Result = FolderOperations->MoveTo(&Indices.Front(), Indices.Size(),
+ DestPath, ExtractCallback);
+ else
+ Result = FolderOperations->CopyTo(&Indices.Front(), Indices.Size(),
+ DestPath, ExtractCallback);
+ ExtractCallbackSpec->ProgressDialog.MyClose();
+ return 0;
+ }
+
+ static DWORD WINAPI MyThreadFunction(void *param)
+ {
+ return ((CThreadExtractInArchive2 *)param)->Extract();
+ }
+};
+
+HRESULT CPanel::CopyTo(const CRecordVector<UInt32> &indices, const UString &folder,
+ bool moveMode, bool showErrorMessages, UStringVector *messages)
+{
+ CMyComPtr<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ {
+ UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208);
+ if (showErrorMessages)
+ MessageBox(errorMessage);
+ else if (messages != 0)
+ messages->Add(errorMessage);
+ return E_FAIL;
+ }
+
+ CThreadExtractInArchive2 extracter;
+
+ extracter.ExtractCallbackSpec = new CExtractCallbackImp;
+ extracter.ExtractCallback = extracter.ExtractCallbackSpec;
+ extracter.ExtractCallbackSpec->ParentWindow = GetParent();
+ extracter.ExtractCallbackSpec->ShowMessages = showErrorMessages;
+
+ UString title = moveMode ?
+ LangString(IDS_MOVING, 0x03020206):
+ LangString(IDS_COPYING, 0x03020205);
+ UString progressWindowTitle = LangString(IDS_APP_TITLE, 0x03000000);
+
+ extracter.ExtractCallbackSpec->ProgressDialog.MainWindow = GetParent();
+ extracter.ExtractCallbackSpec->ProgressDialog.MainTitle = progressWindowTitle;
+ extracter.ExtractCallbackSpec->ProgressDialog.MainAddTitle = title + L" ";
+
+ extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kAskBefore;
+ extracter.ExtractCallbackSpec->Init();
+ extracter.Indices = indices;
+ extracter.DestPath = folder;
+ extracter.FolderOperations = folderOperations;
+ extracter.MoveMode = moveMode;
+
+ CThread extractThread;
+ if (!extractThread.Create(CThreadExtractInArchive2::MyThreadFunction, &extracter))
+ throw 271824;
+ extracter.ExtractCallbackSpec->StartProgressDialog(title);
+
+ if (messages != 0)
+ *messages = extracter.ExtractCallbackSpec->Messages;
+ return extracter.Result;
+}
+
+
+struct CThreadUpdate
+{
+ CMyComPtr<IFolderOperations> FolderOperations;
+ UString FolderPrefix;
+ UStringVector FileNames;
+ CRecordVector<const wchar_t *> FileNamePointers;
+ CMyComPtr<IFolderArchiveUpdateCallback> UpdateCallback;
+ CUpdateCallback100Imp *UpdateCallbackSpec;
+ HRESULT Result;
+
+ DWORD Process()
+ {
+ NCOM::CComInitializer comInitializer;
+ UpdateCallbackSpec->ProgressDialog.WaitCreating();
+ Result = FolderOperations->CopyFrom(
+ FolderPrefix,
+ &FileNamePointers.Front(),
+ FileNamePointers.Size(),
+ UpdateCallback);
+ UpdateCallbackSpec->ProgressDialog.MyClose();
+ return 0;
+ }
+
+ static DWORD WINAPI MyThreadFunction(void *param)
+ {
+ return ((CThreadUpdate *)param)->Process();
+ }
+};
+
+
+HRESULT CPanel::CopyFrom(const UString &folderPrefix, const UStringVector &filePaths,
+ bool showErrorMessages, UStringVector *messages)
+{
+ CMyComPtr<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ {
+ UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208);
+ if (showErrorMessages)
+ MessageBox(errorMessage);
+ else if (messages != 0)
+ messages->Add(errorMessage);
+ return E_FAIL;
+ }
+
+ CThreadUpdate updater;
+ updater.UpdateCallbackSpec = new CUpdateCallback100Imp;
+ updater.UpdateCallback = updater.UpdateCallbackSpec;
+
+ UString title = LangString(IDS_COPYING, 0x03020205);
+ UString progressWindowTitle = LangString(IDS_APP_TITLE, 0x03000000);
+
+ updater.UpdateCallbackSpec->ProgressDialog.MainWindow = GetParent();
+ updater.UpdateCallbackSpec->ProgressDialog.MainTitle = progressWindowTitle;
+ updater.UpdateCallbackSpec->ProgressDialog.MainAddTitle = title + UString(L" ");
+
+ updater.UpdateCallbackSpec->Init((HWND)*this, false, L"");
+ updater.FolderOperations = folderOperations;
+ updater.FolderPrefix = folderPrefix;
+ updater.FileNames.Reserve(filePaths.Size());
+ int i;
+ for(i = 0; i < filePaths.Size(); i++)
+ updater.FileNames.Add(filePaths[i]);
+ updater.FileNamePointers.Reserve(updater.FileNames.Size());
+ for(i = 0; i < updater.FileNames.Size(); i++)
+ updater.FileNamePointers.Add(updater.FileNames[i]);
+
+ CThread thread;
+ if (!thread.Create(CThreadUpdate::MyThreadFunction, &updater))
+ throw 271824;
+ updater.UpdateCallbackSpec->StartProgressDialog(title);
+
+ if (messages != 0)
+ *messages = updater.UpdateCallbackSpec->Messages;
+
+ return updater.Result;
+}
+
+void CPanel::CopyFrom(const UStringVector &filePaths)
+{
+ UString title = LangString(IDS_CONFIRM_FILE_COPY, 0x03020222);
+ UString message = LangString(IDS_WANT_TO_COPY_FILES, 0x03020223);
+ message += L"\n\'";
+ message += _currentFolderPrefix;
+ message += L"\' ?";
+ int res = ::MessageBoxW(*(this), message, title, MB_YESNOCANCEL | MB_ICONQUESTION | MB_SYSTEMMODAL);
+ if (res != IDYES)
+ return;
+
+ CDisableTimerProcessing disableTimerProcessing(*this);
+
+ CSelectedState srcSelState;
+ SaveSelectedState(srcSelState);
+
+ HRESULT result = CopyFrom(L"", filePaths, true, 0);
+
+ if (result != S_OK)
+ {
+ disableTimerProcessing.Restore();
+ // For Password:
+ SetFocusToList();
+ if (result != E_ABORT)
+ MessageBoxError(result);
+ return;
+ }
+
+ RefreshListCtrl(srcSelState);
+
+ disableTimerProcessing.Restore();
+ SetFocusToList();
+}
+
diff --git a/CPP/7zip/FileManager/PanelCrc.cpp b/CPP/7zip/FileManager/PanelCrc.cpp
new file mode 100755
index 00000000..12dcee55
--- /dev/null
+++ b/CPP/7zip/FileManager/PanelCrc.cpp
@@ -0,0 +1,361 @@
+// PanelSplitFile.cpp
+
+#include "StdAfx.h"
+
+#include "resource.h"
+
+#include "Common/Alloc.h"
+#include "Common/CRC.h"
+#include "Common/IntToString.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/FileIO.h"
+#include "Windows/FileFind.h"
+#include "Windows/FileName.h"
+#include "Windows/Thread.h"
+#include "Windows/Error.h"
+
+#include "Resource/ProgressDialog2/ProgressDialog.h"
+#include "Resource/OverwriteDialog/resource.h"
+
+#include "App.h"
+#include "FormatUtils.h"
+#include "LangUtils.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NName;
+
+static const UInt32 kBufSize = (1 << 15);
+
+struct CDirEnumerator
+{
+ bool FlatMode;
+ UString BasePrefix;
+ UStringVector FileNames;
+
+ CObjectVector<NFind::CEnumeratorW> Enumerators;
+ UStringVector Prefixes;
+ int Index;
+ bool GetNextFile(NFind::CFileInfoW &fileInfo, bool &filled, UString &fullPath, DWORD &errorCode);
+ void Init();
+
+ CDirEnumerator(): FlatMode(false) {};
+};
+
+void CDirEnumerator::Init()
+{
+ Enumerators.Clear();
+ Prefixes.Clear();
+ Index = 0;
+}
+
+bool CDirEnumerator::GetNextFile(NFind::CFileInfoW &fileInfo, bool &filled, UString &resPath, DWORD &errorCode)
+{
+ filled = false;
+ for (;;)
+ {
+ if (Enumerators.IsEmpty())
+ {
+ if (Index >= FileNames.Size())
+ return true;
+ const UString &path = FileNames[Index];
+ int pos = path.ReverseFind('\\');
+ resPath.Empty();
+ if (pos >= 0)
+ resPath = path.Left(pos + 1);
+ if (!NFind::FindFile(BasePrefix + path, fileInfo))
+ {
+ errorCode = ::GetLastError();
+ resPath = path;
+ return false;
+ }
+ Index++;
+ break;
+ }
+ bool found;
+ if (!Enumerators.Back().Next(fileInfo, found))
+ {
+ errorCode = ::GetLastError();
+ resPath = Prefixes.Back();
+ return false;
+ }
+ if (found)
+ {
+ resPath = Prefixes.Back();
+ break;
+ }
+ Enumerators.DeleteBack();
+ Prefixes.DeleteBack();
+ }
+ resPath += fileInfo.Name;
+ if (!FlatMode && fileInfo.IsDirectory())
+ {
+ UString prefix = resPath + (UString)(wchar_t)kDirDelimiter;
+ Enumerators.Add(NFind::CEnumeratorW(BasePrefix + prefix + (UString)(wchar_t)kAnyStringWildcard));
+ Prefixes.Add(prefix);
+ }
+ filled = true;
+ return true;
+}
+
+struct CThreadCrc
+{
+ class CMyBuffer
+ {
+ void *_data;
+ public:
+ CMyBuffer(): _data(0) {}
+ operator void *() { return _data; }
+ bool Allocate(size_t size)
+ {
+ if (_data != 0)
+ return false;
+ _data = ::MidAlloc(size);
+ return _data != 0;
+ }
+ ~CMyBuffer() { ::MidFree(_data); }
+ };
+
+ CProgressDialog *ProgressDialog;
+
+ CDirEnumerator DirEnumerator;
+
+ UInt64 NumFiles;
+ UInt64 NumFolders;
+ UInt64 DataSize;
+ UInt32 DataCrcSum;
+ UInt32 DataNameCrcSum;
+
+ HRESULT Result;
+ DWORD ErrorCode;
+ UString ErrorPath;
+ UString Error;
+ bool ThereIsError;
+
+ void Process2()
+ {
+ DataSize = NumFolders = NumFiles = DataCrcSum = DataNameCrcSum = 0;
+ ProgressDialog->WaitCreating();
+
+ CMyBuffer bufferObject;
+ if (!bufferObject.Allocate(kBufSize))
+ {
+ Error = L"Can not allocate memory";
+ ThereIsError = true;
+ return;
+ }
+ Byte *buffer = (Byte *)(void *)bufferObject;
+
+ UInt64 totalSize = 0;
+
+ DirEnumerator.Init();
+
+ UString scanningStr = LangString(IDS_SCANNING, 0x03020800);
+ scanningStr += L" ";
+
+ for (;;)
+ {
+ NFile::NFind::CFileInfoW fileInfo;
+ bool filled;
+ UString resPath;
+ if (!DirEnumerator.GetNextFile(fileInfo, filled, resPath, ErrorCode))
+ {
+ ThereIsError = true;
+ ErrorPath = resPath;
+ return;
+ }
+ if (!filled)
+ break;
+ if (!fileInfo.IsDirectory())
+ totalSize += fileInfo.Size;
+ ProgressDialog->ProgressSynch.SetCurrentFileName(scanningStr + resPath);
+ ProgressDialog->ProgressSynch.SetProgress(totalSize, 0);
+ Result = ProgressDialog->ProgressSynch.SetPosAndCheckPaused(0);
+ if (Result != S_OK)
+ return;
+ }
+
+ ProgressDialog->ProgressSynch.SetProgress(totalSize, 0);
+
+ DirEnumerator.Init();
+
+ for (;;)
+ {
+ NFile::NFind::CFileInfoW fileInfo;
+ bool filled;
+ UString resPath;
+ if (!DirEnumerator.GetNextFile(fileInfo, filled, resPath, ErrorCode))
+ {
+ ThereIsError = true;
+ ErrorPath = resPath;
+ return;
+ }
+ if (!filled)
+ break;
+
+ CCRC crc;
+ if (fileInfo.IsDirectory())
+ NumFolders++;
+ else
+ {
+ NFile::NIO::CInFile inFile;
+ if (!inFile.Open(DirEnumerator.BasePrefix + resPath))
+ {
+ ErrorCode = ::GetLastError();
+ ThereIsError = true;
+ ErrorPath = resPath;
+ return;
+ }
+ NumFiles++;
+ ProgressDialog->ProgressSynch.SetCurrentFileName(resPath);
+ for (;;)
+ {
+ UInt32 processedSize;
+ if (!inFile.Read(buffer, kBufSize, processedSize))
+ {
+ ErrorCode = ::GetLastError();
+ ThereIsError = true;
+ ErrorPath = resPath;
+ return;
+ }
+ if (processedSize == 0)
+ break;
+ crc.Update(buffer, processedSize);
+ DataSize += processedSize;
+ Result = ProgressDialog->ProgressSynch.SetPosAndCheckPaused(DataSize);
+ if (Result != S_OK)
+ return;
+ }
+ DataCrcSum += crc.GetDigest();
+ }
+ for (int i = 0; i < resPath.Length(); i++)
+ {
+ wchar_t c = resPath[i];
+ crc.UpdateByte((Byte)(c & 0xFF));
+ crc.UpdateByte((Byte)((c >> 8) & 0xFF));
+ }
+ DataNameCrcSum += crc.GetDigest();
+ Result = ProgressDialog->ProgressSynch.SetPosAndCheckPaused(DataSize);
+ if (Result != S_OK)
+ return;
+ }
+ }
+ DWORD Process()
+ {
+ try { Process2(); }
+ catch(...) { Error = L"Error"; ThereIsError = true;}
+ ProgressDialog->MyClose();
+ return 0;
+ }
+
+ static DWORD WINAPI MyThreadFunction(void *param)
+ {
+ return ((CThreadCrc *)param)->Process();
+ }
+};
+
+static void ConvertUInt32ToHex(UInt32 value, wchar_t *s)
+{
+ for (int i = 0; i < 8; i++)
+ {
+ int t = value & 0xF;
+ value >>= 4;
+ s[7 - i] = (wchar_t)((t < 10) ? (L'0' + t) : (L'A' + (t - 10)));
+ }
+ s[8] = L'\0';
+}
+
+void CApp::CalculateCrc()
+{
+ int srcPanelIndex = GetFocusedPanelIndex();
+ CPanel &srcPanel = Panels[srcPanelIndex];
+ if (!srcPanel.IsFSFolder())
+ {
+ srcPanel.MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
+ return;
+ }
+ CRecordVector<UInt32> indices;
+ srcPanel.GetOperatedItemIndices(indices);
+ if (indices.IsEmpty())
+ return;
+
+ CThreadCrc combiner;
+ for (int i = 0; i < indices.Size(); i++)
+ combiner.DirEnumerator.FileNames.Add(srcPanel.GetItemRelPath(indices[i]));
+ combiner.DirEnumerator.BasePrefix = srcPanel._currentFolderPrefix;
+ combiner.DirEnumerator.FlatMode = GetFlatMode();
+
+ CProgressDialog progressDialog;
+ combiner.ProgressDialog = &progressDialog;
+ combiner.ErrorCode = 0;
+ combiner.Result = S_OK;
+ combiner.ThereIsError = false;
+
+ UString progressWindowTitle = LangString(IDS_APP_TITLE, 0x03000000);
+ UString title = LangString(IDS_CHECKSUM_CALCULATING, 0x03020710);
+
+ progressDialog.MainWindow = _window;
+ progressDialog.MainTitle = progressWindowTitle;
+ progressDialog.MainAddTitle = title + UString(L" ");
+
+ CThread thread;
+ if (!thread.Create(CThreadCrc::MyThreadFunction, &combiner))
+ throw 271824;
+ progressDialog.Create(title, _window);
+
+ if (combiner.Result != S_OK)
+ {
+ if (combiner.Result != E_ABORT)
+ srcPanel.MessageBoxError(combiner.Result);
+ }
+ else if (combiner.ThereIsError)
+ {
+ if (combiner.Error.IsEmpty())
+ {
+ UString message = combiner.DirEnumerator.BasePrefix + combiner.ErrorPath;
+ message += L"\n";
+ message += NError::MyFormatMessageW(combiner.ErrorCode);
+ srcPanel.MessageBoxMyError(message);
+ }
+ else
+ srcPanel.MessageBoxMyError(combiner.Error);
+ }
+ else
+ {
+ UString s;
+ {
+ wchar_t sz[32];
+
+ s += LangString(IDS_FILES_COLON, 0x02000320);
+ s += L" ";
+ ConvertUInt64ToString(combiner.NumFiles, sz);
+ s += sz;
+ s += L"\n";
+
+ s += LangString(IDS_FOLDERS_COLON, 0x02000321);
+ s += L" ";
+ ConvertUInt64ToString(combiner.NumFolders, sz);
+ s += sz;
+ s += L"\n";
+
+ s += LangString(IDS_SIZE_COLON, 0x02000322);
+ s += L" ";
+ ConvertUInt64ToString(combiner.DataSize, sz);
+ s += MyFormatNew(IDS_FILE_SIZE, 0x02000982, sz);;
+ s += L"\n";
+
+ s += LangString(IDS_CHECKSUM_CRC_DATA, 0x03020721);
+ s += L" ";
+ ConvertUInt32ToHex(combiner.DataCrcSum, sz);
+ s += sz;
+ s += L"\n";
+
+ s += LangString(IDS_CHECKSUM_CRC_DATA_NAMES, 0x03020722);
+ s += L" ";
+ ConvertUInt32ToHex(combiner.DataNameCrcSum, sz);
+ s += sz;
+ }
+ srcPanel.MessageBoxInfo(s, LangString(IDS_CHECKSUM_INFORMATION, 0x03020720));
+ }
+}
diff --git a/CPP/7zip/FileManager/PanelDrag.cpp b/CPP/7zip/FileManager/PanelDrag.cpp
new file mode 100755
index 00000000..24f1def0
--- /dev/null
+++ b/CPP/7zip/FileManager/PanelDrag.cpp
@@ -0,0 +1,796 @@
+// PanelDrag.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StringConvert.h"
+
+#include "Windows/Memory.h"
+#include "Windows/FileDir.h"
+#include "Windows/Shell.h"
+
+#include "../UI/Common/ArchiveName.h"
+#include "../UI/Common/CompressCall.h"
+
+#include "Resource/MessagesDialog/MessagesDialog.h"
+
+#include "App.h"
+#include "EnumFormatEtc.h"
+
+using namespace NWindows;
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+static wchar_t *kTempDirPrefix = L"7zE";
+static LPCTSTR kSvenZipSetFolderFormat = TEXT("7-Zip::SetTargetFolder");
+
+////////////////////////////////////////////////////////
+
+class CDataObject:
+ public IDataObject,
+ public CMyUnknownImp
+{
+private:
+ FORMATETC m_Etc;
+ UINT m_SetFolderFormat;
+
+public:
+ MY_UNKNOWN_IMP1_MT(IDataObject)
+
+ STDMETHODIMP GetData(LPFORMATETC pformatetcIn, LPSTGMEDIUM medium);
+ STDMETHODIMP GetDataHere(LPFORMATETC pformatetc, LPSTGMEDIUM medium);
+ STDMETHODIMP QueryGetData(LPFORMATETC pformatetc );
+
+ STDMETHODIMP GetCanonicalFormatEtc ( LPFORMATETC /* pformatetc */, LPFORMATETC pformatetcOut)
+ { pformatetcOut->ptd = NULL; return ResultFromScode(E_NOTIMPL); }
+
+ STDMETHODIMP SetData(LPFORMATETC etc, STGMEDIUM *medium, BOOL release);
+ STDMETHODIMP EnumFormatEtc(DWORD drection, LPENUMFORMATETC *enumFormatEtc);
+
+ STDMETHODIMP DAdvise(FORMATETC * /* etc */, DWORD /* advf */, LPADVISESINK /* pAdvSink */, DWORD * /* pdwConnection */)
+ { return OLE_E_ADVISENOTSUPPORTED; }
+ STDMETHODIMP DUnadvise(DWORD /* dwConnection */) { return OLE_E_ADVISENOTSUPPORTED; }
+ STDMETHODIMP EnumDAdvise( LPENUMSTATDATA * /* ppenumAdvise */) { return OLE_E_ADVISENOTSUPPORTED; }
+
+ CDataObject();
+
+ NMemory::CGlobal hGlobal;
+ UString Path;
+};
+
+CDataObject::CDataObject()
+{
+ m_SetFolderFormat = RegisterClipboardFormat(kSvenZipSetFolderFormat);
+ m_Etc.cfFormat = CF_HDROP;
+ m_Etc.ptd = NULL;
+ m_Etc.dwAspect = DVASPECT_CONTENT;
+ m_Etc.lindex = -1;
+ m_Etc.tymed = TYMED_HGLOBAL;
+}
+
+STDMETHODIMP CDataObject::SetData(LPFORMATETC etc, STGMEDIUM *medium, BOOL /* release */)
+{
+ if (etc->cfFormat == m_SetFolderFormat && etc->tymed == TYMED_HGLOBAL &&
+ etc->dwAspect == DVASPECT_CONTENT && medium->tymed == TYMED_HGLOBAL)
+ {
+ Path.Empty();
+ if (medium->hGlobal == 0)
+ return S_OK;
+ size_t size = GlobalSize(medium->hGlobal) / sizeof(wchar_t);
+ const wchar_t *src = (const wchar_t *)GlobalLock(medium->hGlobal);
+ if (src != 0)
+ {
+ for (size_t i = 0; i < size; i++)
+ {
+ wchar_t c = src[i];
+ if (c == 0)
+ break;
+ Path += c;
+ }
+ GlobalUnlock(medium->hGlobal);
+ return S_OK;
+ }
+ }
+ return E_NOTIMPL;
+}
+
+static HGLOBAL DuplicateGlobalMem(HGLOBAL srcGlobal)
+{
+ SIZE_T size = GlobalSize(srcGlobal);
+ const void *src = GlobalLock(srcGlobal);
+ if (src == 0)
+ return 0;
+ HGLOBAL destGlobal = GlobalAlloc(GHND | GMEM_SHARE, size);
+ if (destGlobal != 0)
+ {
+ void *dest = GlobalLock(destGlobal);
+ if (dest == 0)
+ {
+ GlobalFree(destGlobal);
+ destGlobal = 0;
+ }
+ else
+ {
+ memcpy(dest, src, size);
+ GlobalUnlock(destGlobal);
+ }
+ }
+ GlobalUnlock(srcGlobal);
+ return destGlobal;
+}
+
+STDMETHODIMP CDataObject::GetData(LPFORMATETC etc, LPSTGMEDIUM medium)
+{
+ RINOK(QueryGetData(etc));
+ medium->tymed = m_Etc.tymed;
+ medium->pUnkForRelease = 0;
+ medium->hGlobal = DuplicateGlobalMem(hGlobal);
+ if (medium->hGlobal == 0)
+ return E_OUTOFMEMORY;
+ return S_OK;
+}
+
+STDMETHODIMP CDataObject::GetDataHere(LPFORMATETC /* etc */, LPSTGMEDIUM /* medium */)
+{
+ // Seems Windows doesn't call it, so we will not implement it.
+ return E_UNEXPECTED;
+}
+
+
+STDMETHODIMP CDataObject::QueryGetData(LPFORMATETC etc)
+{
+ if ((m_Etc.tymed & etc->tymed) &&
+ m_Etc.cfFormat == etc->cfFormat &&
+ m_Etc.dwAspect == etc->dwAspect)
+ return S_OK;
+ return DV_E_FORMATETC;
+}
+
+STDMETHODIMP CDataObject::EnumFormatEtc(DWORD direction, LPENUMFORMATETC FAR* enumFormatEtc)
+{
+ if(direction != DATADIR_GET)
+ return E_NOTIMPL;
+ return CreateEnumFormatEtc(1, &m_Etc, enumFormatEtc);
+}
+
+////////////////////////////////////////////////////////
+
+class CDropSource:
+ public IDropSource,
+ public CMyUnknownImp
+{
+ DWORD m_Effect;
+public:
+ MY_UNKNOWN_IMP1_MT(IDropSource)
+ STDMETHOD(QueryContinueDrag)(BOOL escapePressed, DWORD keyState);
+ STDMETHOD(GiveFeedback)(DWORD effect);
+
+
+ bool NeedExtract;
+ CPanel *Panel;
+ CRecordVector<UInt32> Indices;
+ UString Folder;
+ CDataObject *DataObjectSpec;
+ CMyComPtr<IDataObject> DataObject;
+
+ bool NeedPostCopy;
+ HRESULT Result;
+ UStringVector Messages;
+
+ CDropSource(): NeedPostCopy(false), Panel(0), Result(S_OK), m_Effect(DROPEFFECT_NONE) {}
+};
+
+STDMETHODIMP CDropSource::QueryContinueDrag(BOOL escapePressed, DWORD keyState)
+{
+ if(escapePressed == TRUE)
+ return DRAGDROP_S_CANCEL;
+ if((keyState & MK_LBUTTON) == 0)
+ {
+ if (m_Effect == DROPEFFECT_NONE)
+ return DRAGDROP_S_CANCEL;
+ Result = S_OK;
+ bool needExtract = NeedExtract;
+ // MoveMode = (((keyState & MK_SHIFT) != 0) && MoveIsAllowed);
+ if (!DataObjectSpec->Path.IsEmpty())
+ {
+ needExtract = false;
+ NeedPostCopy = true;
+ }
+ if (needExtract)
+ {
+ Result = Panel->CopyTo(Indices, Folder,
+ false, // moveMode,
+ false, // showMessages
+ &Messages);
+ if (Result != S_OK || !Messages.IsEmpty())
+ return DRAGDROP_S_CANCEL;
+ }
+ return DRAGDROP_S_DROP;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CDropSource::GiveFeedback(DWORD effect)
+{
+ m_Effect = effect;
+ return DRAGDROP_S_USEDEFAULTCURSORS;
+}
+
+static bool CopyNamesToHGlobal(NMemory::CGlobal &hgDrop, const UStringVector &names)
+{
+ size_t totalLength = 1;
+
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ AStringVector namesA;
+ int i;
+ for (i = 0; i < names.Size(); i++)
+ namesA.Add(GetSystemString(names[i]));
+ for (i = 0; i < names.Size(); i++)
+ totalLength += namesA[i].Length() + 1;
+
+ if (!hgDrop.Alloc(GHND | GMEM_SHARE, totalLength * sizeof(CHAR) + sizeof(DROPFILES)))
+ return false;
+
+ NMemory::CGlobalLock dropLock(hgDrop);
+ DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer();
+ if (dropFiles == 0)
+ return false;
+ dropFiles->fNC = FALSE;
+ dropFiles->pt.x = 0;
+ dropFiles->pt.y = 0;
+ dropFiles->pFiles = sizeof(DROPFILES);
+ dropFiles->fWide = FALSE;
+ CHAR *p = (CHAR *)((BYTE *)dropFiles + sizeof(DROPFILES));
+ for (i = 0; i < names.Size(); i++)
+ {
+ const AString &s = namesA[i];
+ int fullLength = s.Length() + 1;
+ MyStringCopy(p, (const char *)s);
+ p += fullLength;
+ totalLength -= fullLength;
+ }
+ *p = 0;
+ }
+ else
+ #endif
+ {
+ int i;
+ for (i = 0; i < names.Size(); i++)
+ totalLength += names[i].Length() + 1;
+
+ if (!hgDrop.Alloc(GHND | GMEM_SHARE, totalLength * sizeof(WCHAR) + sizeof(DROPFILES)))
+ return false;
+
+ NMemory::CGlobalLock dropLock(hgDrop);
+ DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer();
+ if (dropFiles == 0)
+ return false;
+ dropFiles->fNC = FALSE;
+ dropFiles->pt.x = 0;
+ dropFiles->pt.y = 0;
+ dropFiles->pFiles = sizeof(DROPFILES);
+ dropFiles->fWide = TRUE;
+ WCHAR *p = (WCHAR *)((BYTE *)dropFiles + sizeof(DROPFILES));
+ for (i = 0; i < names.Size(); i++)
+ {
+ const UString &s = names[i];
+ int fullLength = s.Length() + 1;
+ MyStringCopy(p, (const WCHAR *)s);
+ p += fullLength;
+ totalLength -= fullLength;
+ }
+ *p = 0;
+ }
+ return true;
+}
+
+void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
+{
+ CPanel::CDisableTimerProcessing disableTimerProcessing2(*this);
+ if (!DoesItSupportOperations())
+ return;
+ CRecordVector<UInt32> indices;
+ GetOperatedItemIndices(indices);
+ if (indices.Size() == 0)
+ return;
+
+ // CSelectedState selState;
+ // SaveSelectedState(selState);
+
+ UString dirPrefix;
+ NFile::NDirectory::CTempDirectoryW tempDirectory;
+
+ bool isFSFolder = IsFSFolder();
+ if (isFSFolder)
+ dirPrefix = _currentFolderPrefix;
+ else
+ {
+ tempDirectory.Create(kTempDirPrefix);
+ dirPrefix = tempDirectory.GetPath();
+ NFile::NName::NormalizeDirPathPrefix(dirPrefix);
+ }
+
+ CDataObject *dataObjectSpec = new CDataObject;
+ CMyComPtr<IDataObject> dataObject = dataObjectSpec;
+
+ {
+ UStringVector names;
+ for (int i = 0; i < indices.Size(); i++)
+ {
+ UInt32 index = indices[i];
+ UString s;
+ if (isFSFolder)
+ s = GetItemRelPath(index);
+ else
+ s = GetItemName(index);
+ names.Add(dirPrefix + s);
+ }
+ if (!CopyNamesToHGlobal(dataObjectSpec->hGlobal, names))
+ return;
+ }
+
+ CDropSource *dropSourceSpec = new CDropSource;
+ CMyComPtr<IDropSource> dropSource = dropSourceSpec;
+ dropSourceSpec->NeedExtract = !isFSFolder;
+ dropSourceSpec->Panel = this;
+ dropSourceSpec->Indices = indices;
+ dropSourceSpec->Folder = dirPrefix;
+ dropSourceSpec->DataObjectSpec = dataObjectSpec;
+ dropSourceSpec->DataObject = dataObjectSpec;
+
+ bool moveIsAllowed = isFSFolder;
+
+ DWORD effectsOK = DROPEFFECT_COPY;
+ if (moveIsAllowed)
+ effectsOK |= DROPEFFECT_MOVE;
+ DWORD effect;
+ _panelCallback->DragBegin();
+ HRESULT res = DoDragDrop(dataObject, dropSource, effectsOK, &effect);
+ _panelCallback->DragEnd();
+ bool canceled = (res == DRAGDROP_S_CANCEL);
+ if (res == DRAGDROP_S_DROP)
+ {
+ res = dropSourceSpec->Result;
+ if (dropSourceSpec->NeedPostCopy)
+ if (!dataObjectSpec->Path.IsEmpty())
+ {
+ NFile::NName::NormalizeDirPathPrefix(dataObjectSpec->Path);
+ res = CopyTo(indices, dataObjectSpec->Path,
+ (effect == DROPEFFECT_MOVE),// dropSourceSpec->MoveMode,
+ false, // showErrorMessages
+ &dropSourceSpec->Messages);
+ }
+ /*
+ if (effect == DROPEFFECT_MOVE)
+ RefreshListCtrl(selState);
+ */
+ }
+ else
+ {
+ if (res != DRAGDROP_S_CANCEL && res != S_OK)
+ MessageBoxError(res);
+ res = dropSourceSpec->Result;
+ }
+
+ if (!dropSourceSpec->Messages.IsEmpty())
+ {
+ CMessagesDialog messagesDialog;
+ messagesDialog.Messages = &dropSourceSpec->Messages;
+ messagesDialog.Create((*this));
+ }
+ if (res != S_OK && res != E_ABORT)
+ MessageBoxError(res);
+ if (res == S_OK && dropSourceSpec->Messages.IsEmpty() && !canceled)
+ KillSelection();
+}
+
+void CDropTarget::QueryGetData(IDataObject *dataObject)
+{
+ FORMATETC etc = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
+ m_DropIsAllowed = (dataObject->QueryGetData(&etc) == S_OK);
+
+}
+
+static void MySetDropHighlighted(HWND hWnd, int index, bool enable)
+{
+ LVITEM item;
+ item.mask = LVIF_STATE;
+ item.iItem = index;
+ item.iSubItem = 0;
+ item.state = enable ? LVIS_DROPHILITED : 0;
+ item.stateMask = LVIS_DROPHILITED;
+ item.pszText = 0;
+ ListView_SetItem(hWnd, &item);
+}
+
+void CDropTarget::RemoveSelection()
+{
+ if (m_SelectionIndex >= 0 && m_Panel != 0)
+ MySetDropHighlighted(m_Panel->_listView, m_SelectionIndex, false);
+ m_SelectionIndex = -1;
+}
+
+void CDropTarget::PositionCursor(POINTL ptl)
+{
+ m_SubFolderIndex = -1;
+ POINT pt;
+ pt.x = ptl.x;
+ pt.y = ptl.y;
+
+ RemoveSelection();
+ m_IsAppTarget = true;
+ m_Panel = NULL;
+
+ m_PanelDropIsAllowed = true;
+ if (!m_DropIsAllowed)
+ return;
+ {
+ POINT pt2 = pt;
+ App->_window.ScreenToClient(&pt2);
+ for (int i = 0; i < kNumPanelsMax; i++)
+ if (App->IsPanelVisible(i))
+ if (App->Panels[i].IsEnabled())
+ if (ChildWindowFromPointEx(App->_window, pt2,
+ CWP_SKIPINVISIBLE | CWP_SKIPDISABLED) == (HWND)App->Panels[i])
+ {
+ m_Panel = &App->Panels[i];
+ m_IsAppTarget = false;
+ if (i == SrcPanelIndex)
+ {
+ m_PanelDropIsAllowed = false;
+ return;
+ }
+ break;
+ }
+ if (m_IsAppTarget)
+ {
+ if (TargetPanelIndex >= 0)
+ m_Panel = &App->Panels[TargetPanelIndex];
+ return;
+ }
+ }
+
+ /*
+ m_PanelDropIsAllowed = m_Panel->DoesItSupportOperations();
+ if (!m_PanelDropIsAllowed)
+ return;
+ */
+
+ if (!m_Panel->IsFSFolder() && !m_Panel->IsFSDrivesFolder())
+ return;
+
+ if (WindowFromPoint(pt) != (HWND)m_Panel->_listView)
+ return;
+
+ LVHITTESTINFO info;
+ m_Panel->_listView.ScreenToClient(&pt);
+ info.pt = pt;
+ int index = ListView_HitTest(m_Panel->_listView, &info);
+ if (index < 0)
+ return;
+ int realIndex = m_Panel->GetRealItemIndex(index);
+ if (realIndex == kParentIndex)
+ return;
+ if (!m_Panel->IsItemFolder(realIndex))
+ return;
+ m_SubFolderIndex = realIndex;
+ m_SubFolderName = m_Panel->GetItemName(m_SubFolderIndex);
+ MySetDropHighlighted(m_Panel->_listView, index, true);
+ m_SelectionIndex = index;
+}
+
+bool CDropTarget::IsFsFolderPath() const
+{
+ if (!m_IsAppTarget && m_Panel != 0)
+ return (m_Panel->IsFSFolder() || (m_Panel->IsFSDrivesFolder() && m_SelectionIndex >= 0));
+ return false;
+}
+
+static void ReadUnicodeStrings(const wchar_t *p, size_t size, UStringVector &names)
+{
+ names.Clear();
+ UString name;
+ for (;size > 0; size--)
+ {
+ wchar_t c = *p++;
+ if (c == 0)
+ {
+ if (name.IsEmpty())
+ break;
+ names.Add(name);
+ name.Empty();
+ }
+ else
+ name += c;
+ }
+}
+
+static void ReadAnsiStrings(const char *p, size_t size, UStringVector &names)
+{
+ names.Clear();
+ AString name;
+ for (;size > 0; size--)
+ {
+ char c = *p++;
+ if (c == 0)
+ {
+ if (name.IsEmpty())
+ break;
+ names.Add(GetUnicodeString(name));
+ name.Empty();
+ }
+ else
+ name += c;
+ }
+}
+
+static void GetNamesFromDataObject(IDataObject *dataObject, UStringVector &names)
+{
+ names.Clear();
+ FORMATETC etc = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
+ STGMEDIUM medium;
+ HRESULT res = dataObject->GetData(&etc, &medium);
+ if (res != S_OK)
+ return;
+ if (medium.tymed != TYMED_HGLOBAL)
+ return;
+ {
+ NMemory::CGlobal global;
+ global.Attach(medium.hGlobal);
+ size_t blockSize = GlobalSize(medium.hGlobal);
+ NMemory::CGlobalLock dropLock(medium.hGlobal);
+ const DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer();
+ if (dropFiles == 0)
+ return;
+ if (blockSize < dropFiles->pFiles)
+ return;
+ size_t size = blockSize - dropFiles->pFiles;
+ const void *namesData = (const Byte *)dropFiles + dropFiles->pFiles;
+ if (dropFiles->fWide)
+ ReadUnicodeStrings((const wchar_t *)namesData, size / sizeof(wchar_t), names);
+ else
+ ReadAnsiStrings((const char *)namesData, size, names);
+ }
+}
+
+bool CDropTarget::IsItSameDrive() const
+{
+ if (m_Panel == 0)
+ return false;
+ if (!IsFsFolderPath())
+ return false;
+ UString drive;
+ if (m_Panel->IsFSFolder())
+ {
+ drive = m_Panel->GetDriveOrNetworkPrefix();
+ if (drive.IsEmpty())
+ return false;
+ }
+ else if (m_Panel->IsFSDrivesFolder() && m_SelectionIndex >= 0)
+ drive = m_SubFolderName + L'\\';
+ else
+ return false;
+
+ if (m_SourcePaths.Size() == 0)
+ return false;
+ for (int i = 0; i < m_SourcePaths.Size(); i++)
+ {
+ const UString &path = m_SourcePaths[i];
+ if (drive.CompareNoCase(path.Left(drive.Length())) != 0)
+ return false;
+ }
+ return true;
+
+}
+
+DWORD CDropTarget::GetEffect(DWORD keyState, POINTL /* pt */, DWORD allowedEffect)
+{
+ if (!m_DropIsAllowed || !m_PanelDropIsAllowed)
+ return DROPEFFECT_NONE;
+
+ if (!IsFsFolderPath())
+ allowedEffect &= ~DROPEFFECT_MOVE;
+
+ if (!m_SetPathIsOK)
+ allowedEffect &= ~DROPEFFECT_MOVE;
+
+ DWORD effect = 0;
+ if (keyState & MK_CONTROL)
+ effect = allowedEffect & DROPEFFECT_COPY;
+ else if (keyState & MK_SHIFT)
+ effect = allowedEffect & DROPEFFECT_MOVE;
+ if(effect == 0)
+ {
+ if(allowedEffect & DROPEFFECT_COPY)
+ effect = DROPEFFECT_COPY;
+ if(allowedEffect & DROPEFFECT_MOVE)
+ {
+ if (IsItSameDrive())
+ effect = DROPEFFECT_MOVE;
+ }
+ }
+ if(effect == 0)
+ return DROPEFFECT_NONE;
+ return effect;
+}
+
+UString CDropTarget::GetTargetPath() const
+{
+ if (!IsFsFolderPath())
+ return UString();
+ UString path = m_Panel->_currentFolderPrefix;
+ if (m_Panel->IsFSDrivesFolder())
+ path.Empty();
+ if (m_SubFolderIndex >= 0 && !m_SubFolderName.IsEmpty())
+ {
+ path += m_SubFolderName;
+ path += L"\\";
+ }
+ return path;
+}
+
+bool CDropTarget::SetPath(bool enablePath) const
+{
+ UINT setFolderFormat = RegisterClipboardFormat(kSvenZipSetFolderFormat);
+
+ FORMATETC etc = { (CLIPFORMAT)setFolderFormat, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
+ STGMEDIUM medium;
+ medium.tymed = etc.tymed;
+ medium.pUnkForRelease = 0;
+ UString path;
+ if (enablePath)
+ path = GetTargetPath();
+ size_t size = path.Length() + 1;
+ medium.hGlobal = GlobalAlloc(GHND | GMEM_SHARE, size * sizeof(wchar_t));
+ if (medium.hGlobal == 0)
+ return false;
+ wchar_t *dest = (wchar_t *)GlobalLock(medium.hGlobal);
+ if (dest == 0)
+ {
+ GlobalUnlock(medium.hGlobal);
+ return false;
+ }
+ MyStringCopy(dest, (const wchar_t *)path);
+ GlobalUnlock(medium.hGlobal);
+ bool res = m_DataObject->SetData(&etc, &medium, FALSE) == S_OK;
+ GlobalFree(medium.hGlobal);
+ return res;
+}
+
+bool CDropTarget::SetPath()
+{
+ m_SetPathIsOK = SetPath(m_DropIsAllowed && m_PanelDropIsAllowed && IsFsFolderPath());
+ return m_SetPathIsOK;
+}
+
+STDMETHODIMP CDropTarget::DragEnter(IDataObject * dataObject, DWORD keyState,
+ POINTL pt, DWORD *effect)
+{
+ GetNamesFromDataObject(dataObject, m_SourcePaths);
+ QueryGetData(dataObject);
+ m_DataObject = dataObject;
+ return DragOver(keyState, pt, effect);
+}
+
+
+STDMETHODIMP CDropTarget::DragOver(DWORD keyState, POINTL pt, DWORD *effect)
+{
+ PositionCursor(pt);
+ SetPath();
+ *effect = GetEffect(keyState, pt, *effect);
+ return S_OK;
+}
+
+
+STDMETHODIMP CDropTarget::DragLeave()
+{
+ RemoveSelection();
+ SetPath(false);
+ m_DataObject.Release();
+ return S_OK;
+}
+
+// We suppose that there was ::DragOver for same POINTL_pt before ::Drop
+// So SetPath() is same as in Drop.
+
+STDMETHODIMP CDropTarget::Drop(IDataObject *dataObject, DWORD keyState,
+ POINTL pt, DWORD * effect)
+{
+ QueryGetData(dataObject);
+ PositionCursor(pt);
+ m_DataObject = dataObject;
+ bool needDrop = true;
+ if(m_DropIsAllowed && m_PanelDropIsAllowed)
+ if (IsFsFolderPath())
+ needDrop = !SetPath();
+ *effect = GetEffect(keyState, pt, *effect);
+ if(m_DropIsAllowed && m_PanelDropIsAllowed)
+ {
+ if (needDrop)
+ {
+ UString path = GetTargetPath();
+ if (m_IsAppTarget && m_Panel)
+ if (m_Panel->IsFSFolder())
+ path = m_Panel->_currentFolderPrefix;
+ m_Panel->DropObject(dataObject, path);
+ }
+ }
+ RemoveSelection();
+ m_DataObject.Release();
+ return S_OK;
+}
+
+void CPanel::DropObject(IDataObject *dataObject, const UString &folderPath)
+{
+ UStringVector names;
+ GetNamesFromDataObject(dataObject, names);
+ CompressDropFiles(names, folderPath);
+}
+
+/*
+void CPanel::CompressDropFiles(HDROP dr)
+{
+ UStringVector fileNames;
+ {
+ NShell::CDrop drop(true);
+ drop.Attach(dr);
+ drop.QueryFileNames(fileNames);
+ }
+ CompressDropFiles(fileNamesUnicode);
+}
+*/
+
+static bool IsFolderInTemp(const UString &path)
+{
+ UString tempPath;
+ if (!NFile::NDirectory::MyGetTempPath(tempPath))
+ return false;
+ if (tempPath.IsEmpty())
+ return false;
+ return (tempPath.CompareNoCase(path.Left(tempPath.Length())) == 0);
+}
+
+static bool AreThereNamesFromTemp(const UStringVector &fileNames)
+{
+ UString tempPath;
+ if (!NFile::NDirectory::MyGetTempPath(tempPath))
+ return false;
+ if (tempPath.IsEmpty())
+ return false;
+ for (int i = 0; i < fileNames.Size(); i++)
+ if (tempPath.CompareNoCase(fileNames[i].Left(tempPath.Length())) == 0)
+ return true;
+ return false;
+}
+
+void CPanel::CompressDropFiles(const UStringVector &fileNames, const UString &folderPath)
+{
+ if (fileNames.Size() == 0)
+ return;
+ const UString archiveName = CreateArchiveName(fileNames.Front(),
+ (fileNames.Size() > 1), false);
+ bool createNewArchive = true;
+ if (!IsFSFolder())
+ createNewArchive = !DoesItSupportOperations();
+
+ if (createNewArchive)
+ {
+ UString folderPath2 = folderPath;
+ if (folderPath2.IsEmpty())
+ {
+ NFile::NDirectory::GetOnlyDirPrefix(fileNames.Front(), folderPath2);
+ if (IsFolderInTemp(folderPath2))
+ folderPath2 = L"C:\\"; // fix it
+ }
+ CompressFiles(folderPath2, archiveName, L"", fileNames,
+ false, // email
+ true, // showDialog
+ AreThereNamesFromTemp(fileNames) // waitFinish
+ );
+ }
+ else
+ CopyFrom(fileNames);
+}
diff --git a/CPP/7zip/FileManager/PanelFolderChange.cpp b/CPP/7zip/FileManager/PanelFolderChange.cpp
new file mode 100755
index 00000000..29841f54
--- /dev/null
+++ b/CPP/7zip/FileManager/PanelFolderChange.cpp
@@ -0,0 +1,414 @@
+// PanelFolderChange.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StringConvert.h"
+#include "Common/Wildcard.h"
+#include "Windows/FileDir.h"
+
+#include "Panel.h"
+#include "Resource/ListViewDialog/ListViewDialog.h"
+#include "RootFolder.h"
+#include "ViewSettings.h"
+#include "FSDrives.h"
+#include "LangUtils.h"
+#include "resource.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NFind;
+
+void CPanel::SetToRootFolder()
+{
+ _folder.Release();
+ _library.Free();
+ CRootFolder *rootFolderSpec = new CRootFolder;
+ _folder = rootFolderSpec;
+ rootFolderSpec->Init();
+}
+
+HRESULT CPanel::BindToPath(const UString &fullPath, bool &archiveIsOpened, bool &encrypted)
+{
+ archiveIsOpened = false;
+ encrypted = false;
+ CDisableTimerProcessing disableTimerProcessing1(*this);
+ CloseOpenFolders();
+ UString sysPath = fullPath;
+ CFileInfoW fileInfo;
+ UStringVector reducedParts;
+ while(!sysPath.IsEmpty())
+ {
+ if (FindFile(sysPath, fileInfo))
+ break;
+ int pos = sysPath.ReverseFind(L'\\');
+ if (pos < 0)
+ sysPath.Empty();
+ else
+ {
+ if (reducedParts.Size() > 0 || pos < sysPath.Length() - 1)
+ reducedParts.Add(sysPath.Mid(pos + 1));
+ sysPath = sysPath.Left(pos);
+ }
+ }
+ SetToRootFolder();
+ CMyComPtr<IFolderFolder> newFolder;
+ if (sysPath.IsEmpty())
+ {
+ if (_folder->BindToFolder(fullPath, &newFolder) == S_OK)
+ _folder = newFolder;
+ }
+ else if (fileInfo.IsDirectory())
+ {
+ NName::NormalizeDirPathPrefix(sysPath);
+ if (_folder->BindToFolder(sysPath, &newFolder) == S_OK)
+ _folder = newFolder;
+ }
+ else
+ {
+ UString dirPrefix;
+ if (!NDirectory::GetOnlyDirPrefix(sysPath, dirPrefix))
+ dirPrefix.Empty();
+ if (_folder->BindToFolder(dirPrefix, &newFolder) == S_OK)
+ {
+ _folder = newFolder;
+ LoadFullPath();
+ UString fileName;
+ if (NDirectory::GetOnlyName(sysPath, fileName))
+ {
+ if (OpenItemAsArchive(fileName, _currentFolderPrefix,
+ _currentFolderPrefix + fileName, encrypted) == S_OK)
+ {
+ archiveIsOpened = true;
+ for (int i = reducedParts.Size() - 1; i >= 0; i--)
+ {
+ CMyComPtr<IFolderFolder> newFolder;
+ _folder->BindToFolder(reducedParts[i], &newFolder);
+ if (!newFolder)
+ break;
+ _folder = newFolder;
+ }
+ }
+ }
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CPanel::BindToPathAndRefresh(const UString &path)
+{
+ CDisableTimerProcessing disableTimerProcessing1(*this);
+ bool archiveIsOpened, encrypted;
+ RINOK(BindToPath(path, archiveIsOpened, encrypted));
+ RefreshListCtrl(UString(), -1, true, UStringVector());
+ return S_OK;
+}
+
+void CPanel::SetBookmark(int index)
+{
+ _appState->FastFolders.SetString(index, _currentFolderPrefix);
+}
+
+void CPanel::OpenBookmark(int index)
+{
+ BindToPathAndRefresh(_appState->FastFolders.GetString(index));
+}
+
+UString GetFolderPath(IFolderFolder * folder)
+{
+ CMyComPtr<IFolderGetPath> folderGetPath;
+ if (folder->QueryInterface(IID_IFolderGetPath, (void **)&folderGetPath) == S_OK)
+ {
+ CMyComBSTR path;
+ if (folderGetPath->GetPath(&path) == S_OK)
+ return (const wchar_t *)path;
+ }
+ return UString();
+}
+
+void CPanel::LoadFullPath()
+{
+ _currentFolderPrefix.Empty();
+ for (int i = 0; i < _parentFolders.Size(); i++)
+ {
+ const CFolderLink &folderLink = _parentFolders[i];
+ _currentFolderPrefix += GetFolderPath(folderLink.ParentFolder);
+ _currentFolderPrefix += folderLink.ItemName;
+ _currentFolderPrefix += L'\\';
+ }
+ if (_folder)
+ _currentFolderPrefix += GetFolderPath(_folder);
+}
+
+void CPanel::LoadFullPathAndShow()
+{
+ LoadFullPath();
+ _appState->FolderHistory.AddString(_currentFolderPrefix);
+
+ // _headerComboBox.SendMessage(CB_RESETCONTENT, 0, 0);
+ _headerComboBox.SetText(_currentFolderPrefix);
+
+ /*
+ for (int i = 0; i < g_Folders.m_Strings.Size(); i++)
+ {
+ UString string = g_Folders.m_Strings[i];
+ COMBOBOXEXITEM item;
+ item.mask = CBEIF_TEXT;
+ item.iItem = i;
+ item.pszText = (LPTSTR)(LPCTSTR)string;
+ _headerComboBox.InsertItem(&item);
+ }
+ */
+}
+
+bool CPanel::OnNotifyComboBoxEndEdit(PNMCBEENDEDITW info, LRESULT &result)
+{
+ if (info->iWhy == CBENF_ESCAPE)
+ {
+ _headerComboBox.SetText(_currentFolderPrefix);
+ PostMessage(kSetFocusToListView);
+ result = FALSE;
+ return true;
+ }
+ if (info->iWhy == CBENF_DROPDOWN)
+ {
+ result = FALSE;
+ return true;
+ }
+
+ if (info->iWhy == CBENF_RETURN)
+ {
+ UString s;
+ _headerComboBox.GetText(s);
+ // length of NMCBEENDEDITW.szText is limited by MAX_PATH
+ // if (BindToPathAndRefresh(info->szText) != S_OK)
+ if (BindToPathAndRefresh(s) != S_OK)
+ {
+ result = TRUE;
+ return true;
+ }
+ result = FALSE;
+ PostMessage(kSetFocusToListView);
+ return true;
+ }
+ return false;
+}
+
+#ifndef _UNICODE
+bool CPanel::OnNotifyComboBoxEndEdit(PNMCBEENDEDIT info, LRESULT &result)
+{
+ if (info->iWhy == CBENF_ESCAPE)
+ {
+ _headerComboBox.SetText(_currentFolderPrefix);
+ PostMessage(kSetFocusToListView);
+ result = FALSE;
+ return true;
+ }
+ if (info->iWhy == CBENF_DROPDOWN)
+ {
+ result = FALSE;
+ return true;
+ }
+
+ if (info->iWhy == CBENF_RETURN)
+ {
+ if (BindToPathAndRefresh(GetUnicodeString(info->szText)) != S_OK)
+ {
+ result = TRUE;
+ return true;
+ }
+ result = FALSE;
+ PostMessage(kSetFocusToListView);
+ return true;
+ }
+ return false;
+}
+#endif
+
+void CPanel::OnComboBoxCommand(UINT /* code */, LPARAM & /* param */)
+{
+ /*
+ if (code == CBN_SELENDOK)
+ {
+ UString path;
+ if (!_headerComboBox.GetText(path))
+ return;
+ CRootFolder *rootFolderSpec = new CRootFolder;
+ CMyComPtr<IFolderFolder> rootFolder = rootFolderSpec;
+ rootFolderSpec->Init();
+ CMyComPtr<IFolderFolder> newFolder;
+ if (rootFolder->BindToFolder(path, &newFolder) != S_OK)
+ return;
+ _folder = newFolder;
+ SetCurrentPathText();
+ RefreshListCtrl(UString(), -1, UStringVector());
+ PostMessage(kSetFocusToListView);
+ }
+ */
+}
+
+bool CPanel::OnNotifyComboBox(LPNMHDR header, LRESULT &result)
+{
+ switch(header->code)
+ {
+ case CBEN_BEGINEDIT:
+ {
+ _lastFocusedIsList = false;
+ _panelCallback->PanelWasFocused();
+ }
+ #ifndef _UNICODE
+ case CBEN_ENDEDIT:
+ {
+ return OnNotifyComboBoxEndEdit((PNMCBEENDEDIT)header, result);
+ }
+ #endif
+ case CBEN_ENDEDITW:
+ {
+ return OnNotifyComboBoxEndEdit((PNMCBEENDEDITW)header, result);
+ }
+ }
+ return false;
+}
+
+
+void CPanel::FoldersHistory()
+{
+ CListViewDialog listViewDialog;
+ listViewDialog.DeleteIsAllowed = true;
+ listViewDialog.Title = LangString(IDS_FOLDERS_HISTORY, 0x03020260);
+ _appState->FolderHistory.GetList(listViewDialog.Strings);
+ if (listViewDialog.Create(GetParent()) == IDCANCEL)
+ return;
+ UString selectString;
+ if (listViewDialog.StringsWereChanged)
+ {
+ _appState->FolderHistory.RemoveAll();
+ for (int i = listViewDialog.Strings.Size() - 1; i >= 0; i--)
+ _appState->FolderHistory.AddString(listViewDialog.Strings[i]);
+ if (listViewDialog.FocusedItemIndex >= 0)
+ selectString = listViewDialog.Strings[listViewDialog.FocusedItemIndex];
+ }
+ else
+ {
+ if (listViewDialog.FocusedItemIndex >= 0)
+ selectString = listViewDialog.Strings[listViewDialog.FocusedItemIndex];
+ }
+ if (listViewDialog.FocusedItemIndex >= 0)
+ BindToPathAndRefresh(selectString);
+}
+
+void CPanel::OpenParentFolder()
+{
+ LoadFullPath(); // Maybe we don't need it ??
+ UString focucedName;
+ if (!_currentFolderPrefix.IsEmpty())
+ {
+ UString string = _currentFolderPrefix;
+ string.Delete(string.Length() - 1);
+ int pos = string.ReverseFind(L'\\');
+ if (pos < 0)
+ pos = 0;
+ else
+ pos++;
+ focucedName = string.Mid(pos);
+ }
+
+ CDisableTimerProcessing disableTimerProcessing1(*this);
+ CMyComPtr<IFolderFolder> newFolder;
+ _folder->BindToParentFolder(&newFolder);
+ if (newFolder)
+ _folder = newFolder;
+ else
+ {
+ if (_parentFolders.IsEmpty())
+ {
+ SetToRootFolder();
+ if (focucedName.IsEmpty())
+ focucedName = GetItemName(0);
+ }
+ else
+ {
+ _folder.Release();
+ _library.Free();
+ CFolderLink &link = _parentFolders.Back();
+ _folder = link.ParentFolder;
+ _library.Attach(link.Library.Detach());
+ focucedName = link.ItemName;
+ if (_parentFolders.Size () > 1)
+ OpenParentArchiveFolder();
+ _parentFolders.DeleteBack();
+ }
+ }
+
+ UStringVector selectedItems;
+ /*
+ if (!focucedName.IsEmpty())
+ selectedItems.Add(focucedName);
+ */
+ LoadFullPath();
+ // ::SetCurrentDirectory(::_currentFolderPrefix);
+ RefreshListCtrl(focucedName, -1, true, selectedItems);
+ _listView.EnsureVisible(_listView.GetFocusedItem(), false);
+ RefreshStatusBar();
+}
+
+void CPanel::CloseOpenFolders()
+{
+ while(_parentFolders.Size() > 0)
+ {
+ _folder.Release();
+ _library.Free();
+ _folder = _parentFolders.Back().ParentFolder;
+ _library.Attach(_parentFolders.Back().Library.Detach());
+ if (_parentFolders.Size () > 1)
+ OpenParentArchiveFolder();
+ _parentFolders.DeleteBack();
+ }
+ _folder.Release();
+ _library.Free();
+}
+
+void CPanel::OpenRootFolder()
+{
+ CDisableTimerProcessing disableTimerProcessing1(*this);
+ _parentFolders.Clear();
+ SetToRootFolder();
+ RefreshListCtrl(UString(), -1, true, UStringVector());
+ // ::SetCurrentDirectory(::_currentFolderPrefix);
+ /*
+ BeforeChangeFolder();
+ _currentFolderPrefix.Empty();
+ AfterChangeFolder();
+ SetCurrentPathText();
+ RefreshListCtrl(UString(), 0, UStringVector());
+ _listView.EnsureVisible(_listView.GetFocusedItem(), false);
+ */
+}
+
+void CPanel::OpenDrivesFolder()
+{
+ CloseOpenFolders();
+ CFSDrives *fsFolderSpec = new CFSDrives;
+ _folder = fsFolderSpec;
+ fsFolderSpec->Init();
+ RefreshListCtrl();
+}
+
+void CPanel::OpenFolder(int index)
+{
+ if (index == kParentIndex)
+ {
+ OpenParentFolder();
+ return;
+ }
+ CMyComPtr<IFolderFolder> newFolder;
+ _folder->BindToFolder(index, &newFolder);
+ if (!newFolder)
+ return;
+ _folder = newFolder;
+ LoadFullPath();
+ // ::SetCurrentDirectory(::_currentFolderPrefix);
+ RefreshListCtrl();
+ UINT state = LVIS_SELECTED;
+ _listView.SetItemState(_listView.GetFocusedItem(), state, state);
+ _listView.EnsureVisible(_listView.GetFocusedItem(), false);
+}
diff --git a/CPP/7zip/FileManager/PanelItemOpen.cpp b/CPP/7zip/FileManager/PanelItemOpen.cpp
new file mode 100755
index 00000000..be2d9024
--- /dev/null
+++ b/CPP/7zip/FileManager/PanelItemOpen.cpp
@@ -0,0 +1,546 @@
+// PanelItemOpen.cpp
+
+#include "StdAfx.h"
+
+#include "resource.h"
+
+#include "Common/StringConvert.h"
+#include "Common/Random.h"
+#include "Common/StringConvert.h"
+#include "Common/AutoPtr.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileFind.h"
+#include "Windows/Thread.h"
+#include "Windows/Synchronization.h"
+#include "Windows/Error.h"
+#include "Windows/COM.h"
+
+#include "ExtractCallback.h"
+#include "IFolder.h"
+#include "FileFolderPluginOpen.h"
+#include "FormatUtils.h"
+#include "Panel.h"
+#include "RegistryUtils.h"
+
+using namespace NWindows;
+using namespace NSynchronization;
+using namespace NFile;
+using namespace NDirectory;
+
+extern HWND g_HWND;
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+static wchar_t *kTempDirPrefix = L"7zO";
+
+static const wchar_t *virusMessage = L"File looks like virus (file name has long spaces in name). 7-Zip will not open it";
+
+static bool IsNameVirus(const UString &name)
+{
+ return (name.Find(L" ") >= 0);
+}
+
+struct CTmpProcessInfo: public CTempFileInfo
+{
+ HANDLE ProcessHandle;
+ HWND Window;
+ UString FullPathFolderPrefix;
+};
+
+class CTmpProcessInfoRelease
+{
+ CTmpProcessInfo *_tmpProcessInfo;
+public:
+ bool _needDelete;
+ CTmpProcessInfoRelease(CTmpProcessInfo &tmpProcessInfo):
+ _tmpProcessInfo(&tmpProcessInfo), _needDelete(true) {}
+ ~CTmpProcessInfoRelease()
+ {
+ if (_needDelete)
+ _tmpProcessInfo->DeleteDirAndFile();
+ }
+};
+
+HRESULT CPanel::OpenItemAsArchive(const UString &name,
+ const UString &folderPath, const UString &filePath, bool &encrypted)
+{
+ encrypted = false;
+ CFolderLink folderLink;
+ if (!NFile::NFind::FindFile(filePath, folderLink.FileInfo))
+ return E_FAIL;
+ if (folderLink.FileInfo.IsDirectory())
+ return S_FALSE;
+
+ folderLink.FilePath = filePath;
+ folderLink.FolderPath = folderPath;
+
+ CMyComPtr<IFolderFolder> newFolder;
+
+ // _passwordIsDefined = false;
+ // _password.Empty();
+
+ NDLL::CLibrary library;
+ RINOK(OpenFileFolderPlugin(filePath, &library, &newFolder, GetParent(), encrypted));
+
+ folderLink.ParentFolder = _folder;
+ folderLink.ItemName = name;
+ _parentFolders.Add(folderLink);
+ _parentFolders.Back().Library.Attach(_library.Detach());
+
+ _folder.Release();
+ _library.Free();
+ _folder = newFolder;
+ _library.Attach(library.Detach());
+
+ return S_OK;
+}
+
+HRESULT CPanel::OpenItemAsArchive(const UString &name)
+{
+ bool encrypted;
+ return OpenItemAsArchive(name, _currentFolderPrefix, _currentFolderPrefix + name, encrypted);
+}
+
+HRESULT CPanel::OpenItemAsArchive(int index)
+{
+ CDisableTimerProcessing disableTimerProcessing1(*this);
+ RINOK(OpenItemAsArchive(GetItemRelPath(index)));
+ RefreshListCtrl();
+ return S_OK;
+}
+
+HRESULT CPanel::OpenParentArchiveFolder()
+{
+ CDisableTimerProcessing disableTimerProcessing1(*this);
+ if (_parentFolders.Size() < 2)
+ return S_OK;
+ CFolderLink &folderLink = _parentFolders.Back();
+ NFind::CFileInfoW newFileInfo;
+ if (NFind::FindFile(folderLink.FilePath, newFileInfo))
+ {
+ if (newFileInfo.Size != folderLink.FileInfo.Size ||
+ CompareFileTime(&newFileInfo.LastWriteTime,
+ &folderLink.FileInfo.LastWriteTime) != 0)
+ {
+ UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE,
+ 0x03020280, folderLink.ItemName);
+ if (::MessageBoxW(HWND(*this), message, L"7-Zip", MB_OKCANCEL | MB_ICONQUESTION) == IDOK)
+ {
+ if (OnOpenItemChanged(folderLink.FolderPath, folderLink.ItemName) != S_OK)
+ {
+ ::MessageBoxW(HWND(*this), MyFormatNew(IDS_CANNOT_UPDATE_FILE,
+ 0x03020281, folderLink.FilePath), L"7-Zip", MB_OK | MB_ICONSTOP);
+ return S_OK;
+ }
+ }
+ }
+ }
+ folderLink.DeleteDirAndFile();
+ return S_OK;
+}
+
+static const wchar_t *kStartExtensions[] =
+{
+ L"exe",
+ L"bat",
+ L"com",
+ L"chm",
+ L"msi",
+ L"doc",
+ L"odt",
+ L"pdf",
+ L"xls"
+};
+
+static bool DoItemAlwaysStart(const UString &name)
+{
+ int extPos = name.ReverseFind('.');
+ if (extPos < 0)
+ return false;
+ UString ext = name.Mid(extPos + 1);
+ ext.MakeLower();
+ for (int i = 0; i < sizeof(kStartExtensions) / sizeof(kStartExtensions[0]); i++)
+ if (ext.Compare(kStartExtensions[i]) == 0)
+ return true;
+ return false;
+}
+
+static HANDLE StartEditApplication(const UString &path, HWND window)
+{
+ UString command;
+ ReadRegEditor(command);
+ if (command.IsEmpty())
+ {
+ if (!MyGetWindowsDirectory(command))
+ return 0;
+ NFile::NName::NormalizeDirPathPrefix(command);
+ command += L"notepad.exe";
+ }
+ command = UString(L"\"") + command + UString(L"\"");
+ command += L" \"";
+ command += UString(path);
+ command += L"\"";
+
+ PROCESS_INFORMATION processInformation;
+ BOOL result;
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ STARTUPINFOA startupInfo;
+ startupInfo.cb = sizeof(startupInfo);
+ startupInfo.lpReserved = 0;
+ startupInfo.lpDesktop = 0;
+ startupInfo.lpTitle = 0;
+ startupInfo.dwFlags = 0;
+ startupInfo.cbReserved2 = 0;
+ startupInfo.lpReserved2 = 0;
+
+ result = ::CreateProcessA(NULL, (CHAR *)(const CHAR *)GetSystemString(command),
+ NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation);
+ }
+ else
+ #endif
+ {
+ STARTUPINFOW startupInfo;
+ startupInfo.cb = sizeof(startupInfo);
+ startupInfo.lpReserved = 0;
+ startupInfo.lpDesktop = 0;
+ startupInfo.lpTitle = 0;
+ startupInfo.dwFlags = 0;
+ startupInfo.cbReserved2 = 0;
+ startupInfo.lpReserved2 = 0;
+
+ result = ::CreateProcessW(NULL, (WCHAR *)(const WCHAR *)command,
+ NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation);
+ }
+
+ if (result != FALSE)
+ {
+ ::CloseHandle(processInformation.hThread);
+ return processInformation.hProcess;
+ }
+ ::MessageBoxW(window, LangString(IDS_CANNOT_START_EDITOR, 0x03020282),
+ L"7-Zip", MB_OK | MB_ICONSTOP);
+ return 0;
+}
+
+#ifndef _UNICODE
+typedef BOOL (WINAPI * ShellExecuteExWP)(LPSHELLEXECUTEINFOW lpExecInfo);
+#endif
+
+static HANDLE StartApplication(const UString &path, HWND window)
+{
+ UINT32 result;
+ HANDLE hProcess;
+ #ifndef _UNICODE
+ if (g_IsNT)
+ {
+ SHELLEXECUTEINFOW execInfo;
+ execInfo.cbSize = sizeof(execInfo);
+ execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT;
+ execInfo.hwnd = NULL;
+ execInfo.lpVerb = NULL;
+ execInfo.lpFile = path;
+ execInfo.lpParameters = NULL;
+ execInfo.lpDirectory = NULL;
+ execInfo.nShow = SW_SHOWNORMAL;
+ execInfo.hProcess = 0;
+ ShellExecuteExWP shellExecuteExW = (ShellExecuteExWP)
+ ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "ShellExecuteExW");
+ if (shellExecuteExW == 0)
+ return 0;
+ shellExecuteExW(&execInfo);
+ result = (UINT32)(UINT_PTR)execInfo.hInstApp;
+ hProcess = execInfo.hProcess;
+ }
+ else
+ #endif
+ {
+ SHELLEXECUTEINFO execInfo;
+ execInfo.cbSize = sizeof(execInfo);
+ execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT;
+ execInfo.hwnd = NULL;
+ execInfo.lpVerb = NULL;
+ const CSysString sysPath = GetSystemString(path);
+ execInfo.lpFile = sysPath;
+ execInfo.lpParameters = NULL;
+ execInfo.lpDirectory = NULL;
+ execInfo.nShow = SW_SHOWNORMAL;
+ execInfo.hProcess = 0;
+ ::ShellExecuteEx(&execInfo);
+ result = (UINT32)(UINT_PTR)execInfo.hInstApp;
+ hProcess = execInfo.hProcess;
+ }
+ if(result <= 32)
+ {
+ switch(result)
+ {
+ case SE_ERR_NOASSOC:
+ ::MessageBoxW(window,
+ NError::MyFormatMessageW(::GetLastError()),
+ // L"There is no application associated with the given file name extension",
+ L"7-Zip", MB_OK | MB_ICONSTOP);
+ }
+ }
+ return hProcess;
+}
+
+void CPanel::EditItem(int index)
+{
+ if (!_parentFolders.IsEmpty())
+ {
+ OpenItemInArchive(index, false, true, true);
+ return;
+ }
+ HANDLE hProcess = StartEditApplication(_currentFolderPrefix + GetItemRelPath(index), (HWND)*this);
+ if (hProcess != 0)
+ ::CloseHandle(hProcess);
+}
+
+void CPanel::OpenFolderExternal(int index)
+{
+ HANDLE hProcess = StartApplication(GetFsPath() + GetItemRelPath(index), (HWND)*this);
+ if (hProcess != 0)
+ ::CloseHandle(hProcess);
+}
+
+void CPanel::OpenItem(int index, bool tryInternal, bool tryExternal)
+{
+ CDisableTimerProcessing disableTimerProcessing1(*this);
+ if (!_parentFolders.IsEmpty())
+ {
+ OpenItemInArchive(index, tryInternal, tryExternal, false);
+ return;
+ }
+ UString name = GetItemRelPath(index);
+ if (IsNameVirus(name))
+ {
+ MessageBoxMyError(virusMessage);
+ return;
+ }
+ UString fullPath = _currentFolderPrefix + name;
+ if (tryInternal)
+ if (!tryExternal || !DoItemAlwaysStart(name))
+ if (OpenItemAsArchive(index) == S_OK)
+ return;
+ if (tryExternal)
+ {
+ NDirectory::MySetCurrentDirectory(_currentFolderPrefix);
+ HANDLE hProcess = StartApplication(fullPath, (HWND)*this);
+ if (hProcess != 0)
+ ::CloseHandle(hProcess);
+ }
+}
+
+HRESULT CPanel::OnOpenItemChanged(const UString &folderPath, const UString &itemName)
+{
+ CMyComPtr<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ {
+ MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
+ return E_FAIL;
+ }
+ UStringVector fileNames;
+ CRecordVector<const wchar_t *> fileNamePointers;
+ fileNames.Add(itemName);
+ fileNamePointers.Add(fileNames[0]);
+
+ UString pathPrefix = folderPath;
+ NName::NormalizeDirPathPrefix(pathPrefix);
+ return folderOperations->CopyFrom(pathPrefix, &fileNamePointers.Front(),fileNamePointers.Size(), NULL);
+}
+
+LRESULT CPanel::OnOpenItemChanged(LPARAM lParam)
+{
+ CTmpProcessInfo &tmpProcessInfo = *(CTmpProcessInfo *)lParam;
+ // LoadCurrentPath()
+ if (tmpProcessInfo.FullPathFolderPrefix != _currentFolderPrefix)
+ return 0;
+
+ CSelectedState state;
+ SaveSelectedState(state);
+
+ HRESULT result = OnOpenItemChanged(tmpProcessInfo.FolderPath, tmpProcessInfo.ItemName);
+ if (result != S_OK)
+ return 0;
+ RefreshListCtrl(state);
+ return 1;
+}
+
+/*
+class CTmpProcessInfoList
+{
+public:
+ CObjectVector<CTmpProcessInfo> _items;
+} g_TmpProcessInfoList;
+*/
+
+class CExitEventLauncher
+{
+public:
+ CManualResetEvent _exitEvent;
+ CExitEventLauncher(): _exitEvent(false) {};
+ ~CExitEventLauncher() { _exitEvent.Set(); }
+} g_ExitEventLauncher;
+
+static DWORD WINAPI MyThreadFunction(void *param)
+{
+ CMyAutoPtr<CTmpProcessInfo> tmpProcessInfoPtr((CTmpProcessInfo *)param);
+ CTmpProcessInfo *tmpProcessInfo = tmpProcessInfoPtr.get();
+
+ HANDLE hProcess = tmpProcessInfo->ProcessHandle;
+ HANDLE events[2] = { g_ExitEventLauncher._exitEvent, hProcess};
+ DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
+ ::CloseHandle(hProcess);
+ if (waitResult == WAIT_OBJECT_0 + 0)
+ return 0;
+ if (waitResult != WAIT_OBJECT_0 + 1)
+ return 1;
+ Sleep(200);
+ NFind::CFileInfoW newFileInfo;
+ if (NFind::FindFile(tmpProcessInfo->FilePath, newFileInfo))
+ {
+ if (newFileInfo.Size != tmpProcessInfo->FileInfo.Size ||
+ CompareFileTime(&newFileInfo.LastWriteTime,
+ &tmpProcessInfo->FileInfo.LastWriteTime) != 0)
+ {
+ UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE,
+ 0x03020280, tmpProcessInfo->ItemName);
+ if (::MessageBoxW(g_HWND, message, L"7-Zip", MB_OKCANCEL | MB_ICONQUESTION) == IDOK)
+ {
+ if (SendMessage(tmpProcessInfo->Window, kOpenItemChanged, 0, (LONG_PTR)tmpProcessInfo) != 1)
+ {
+ ::MessageBoxW(g_HWND, MyFormatNew(IDS_CANNOT_UPDATE_FILE,
+ 0x03020281, tmpProcessInfo->FilePath), L"7-Zip", MB_OK | MB_ICONSTOP);
+ return 0;
+ }
+ }
+ }
+ }
+ tmpProcessInfo->DeleteDirAndFile();
+ return 0;
+}
+
+void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal,
+ bool editMode)
+{
+ const UString name = GetItemName(index);
+ if (IsNameVirus(name))
+ {
+ MessageBoxMyError(virusMessage);
+ return;
+ }
+
+ CMyComPtr<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ {
+ MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
+ return;
+ }
+
+ NFile::NDirectory::CTempDirectoryW tempDirectory;
+ tempDirectory.Create(kTempDirPrefix);
+ UString tempDir = tempDirectory.GetPath();
+ UString tempDirNorm = tempDir;
+ NFile::NName::NormalizeDirPathPrefix(tempDirNorm);
+
+ CRecordVector<UInt32> indices;
+ indices.Add(index);
+
+ UStringVector messages;
+ HRESULT result = CopyTo(indices, tempDirNorm, false, true, &messages);
+
+ if (!messages.IsEmpty())
+ return;
+ if (result != S_OK)
+ {
+ if (result != E_ABORT)
+ MessageBoxError(result);
+ return;
+ }
+
+ UString tempFilePath = tempDirNorm + name;
+
+ CMyAutoPtr<CTmpProcessInfo> tmpProcessInfoPtr(new CTmpProcessInfo());
+ CTmpProcessInfo *tmpProcessInfo = tmpProcessInfoPtr.get();
+ tmpProcessInfo->FolderPath = tempDir;
+ tmpProcessInfo->FilePath = tempFilePath;
+ if (!NFind::FindFile(tempFilePath, tmpProcessInfo->FileInfo))
+ return;
+
+ if (tryInternal)
+ {
+ if (!tryExternal || !DoItemAlwaysStart(name))
+ {
+ bool encrypted;
+ if (OpenItemAsArchive(name, tempDir, tempFilePath, encrypted) == S_OK)
+ {
+ RefreshListCtrl();
+ return;
+ }
+ }
+ }
+
+ CTmpProcessInfoRelease tmpProcessInfoRelease(*tmpProcessInfo);
+
+ if (!tryExternal)
+ return;
+
+ HANDLE hProcess;
+ if (editMode)
+ hProcess = StartEditApplication(tempFilePath, (HWND)*this);
+ else
+ hProcess = StartApplication(tempFilePath, (HWND)*this);
+
+ if (hProcess == 0)
+ return;
+
+ tmpProcessInfo->Window = (HWND)(*this);
+ tmpProcessInfo->FullPathFolderPrefix = _currentFolderPrefix;
+ tmpProcessInfo->ItemName = name;
+ tmpProcessInfo->ProcessHandle = hProcess;
+
+ CThread thread;
+ if (!thread.Create(MyThreadFunction, tmpProcessInfo))
+ throw 271824;
+ tempDirectory.DisableDeleting();
+ tmpProcessInfoPtr.release();
+ tmpProcessInfoRelease._needDelete = false;
+}
+
+/*
+static const UINT64 kTimeLimit = UINT64(10000000) * 3600 * 24;
+
+static bool CheckDeleteItem(UINT64 currentFileTime, UINT64 folderFileTime)
+{
+ return (currentFileTime - folderFileTime > kTimeLimit &&
+ folderFileTime - currentFileTime > kTimeLimit);
+}
+
+void DeleteOldTempFiles()
+{
+ UString tempPath;
+ if(!NFile::NDirectory::MyGetTempPath(tempPath))
+ throw 1;
+
+ SYSTEMTIME systemTime;
+ ::GetSystemTime(&systemTime);
+ UINT64 currentFileTime;
+ if(!::SystemTimeToFileTime(&systemTime, (FILETIME *)&currentFileTime))
+ throw 2;
+ UString searchWildCard = tempPath + kTempDirPrefix + L"*.tmp";
+ searchWildCard += WCHAR(NName::kAnyStringWildcard);
+ NFind::CEnumeratorW enumerator(searchWildCard);
+ NFind::CFileInfoW fileInfo;
+ while(enumerator.Next(fileInfo))
+ {
+ if (!fileInfo.IsDirectory())
+ continue;
+ const UINT64 &creationTime = *(const UINT64 *)(&fileInfo.CreationTime);
+ if(CheckDeleteItem(creationTime, currentFileTime))
+ RemoveDirectoryWithSubItems(tempPath + fileInfo.Name);
+ }
+}
+*/
diff --git a/CPP/7zip/FileManager/PanelItems.cpp b/CPP/7zip/FileManager/PanelItems.cpp
new file mode 100755
index 00000000..16c8d29a
--- /dev/null
+++ b/CPP/7zip/FileManager/PanelItems.cpp
@@ -0,0 +1,822 @@
+// PanelItems.cpp
+
+#include "StdAfx.h"
+
+#include "Common/String.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/PropVariant.h"
+#include "Windows/PropVariantConversions.h"
+#include "Windows/Menu.h"
+
+#include "../PropID.h"
+
+#include "Panel.h"
+#include "resource.h"
+
+#include "RootFolder.h"
+
+#include "PropertyName.h"
+#include "LangUtils.h"
+
+extern "C"
+{
+ #include "../../../C/Sort.h"
+}
+
+using namespace NWindows;
+
+static int GetColumnAlign(PROPID propID, VARTYPE varType)
+{
+ switch(propID)
+ {
+ case kpidCreationTime:
+ case kpidLastAccessTime:
+ case kpidLastWriteTime:
+ return LVCFMT_LEFT;
+ }
+ switch(varType)
+ {
+ case VT_UI1:
+ case VT_I2:
+ case VT_UI2:
+ case VT_I4:
+ case VT_INT:
+ case VT_UI4:
+ case VT_UINT:
+ case VT_I8:
+ case VT_UI8:
+ case VT_BOOL:
+ return LVCFMT_RIGHT;
+
+ case VT_EMPTY:
+ case VT_I1:
+ case VT_FILETIME:
+ case VT_BSTR:
+ return LVCFMT_LEFT;
+
+ default:
+ return LVCFMT_CENTER;
+ }
+}
+
+void CPanel::InitColumns()
+{
+ if (_needSaveInfo)
+ SaveListViewInfo();
+
+ _listView.DeleteAllItems();
+ _selectedStatusVector.Clear();
+
+ ReadListViewInfo();
+
+
+ PROPID sortID;
+ /*
+ if (_listViewInfo.SortIndex >= 0)
+ sortID = _listViewInfo.Columns[_listViewInfo.SortIndex].PropID;
+ */
+ sortID = _listViewInfo.SortID;
+
+ _ascending = _listViewInfo.Ascending;
+
+ _properties.Clear();
+
+ CMyComPtr<IEnumProperties> enumProperties;
+ // CMyComPtr<IEnumSTATPROPSTG> enumSTATPROPSTG;
+ /*
+ if (m_ArchiveHandler)
+ {
+ if (m_ArchiveHandler->EnumProperties(&enumSTATPROPSTG) != S_OK)
+ throw 1;
+ }
+ else
+ */
+ {
+ if (_folder.QueryInterface(IID_IEnumProperties, &enumProperties) != S_OK)
+ throw 1;
+ /*
+ if (enumProperties->EnumProperties(&enumSTATPROPSTG)!= S_OK)
+ throw 1;
+ */
+ }
+
+ _needSaveInfo = true;
+
+ UINT32 numProperties;
+ enumProperties->GetNumberOfProperties(&numProperties);
+ int i;
+ for (i = 0; i < (int)numProperties; i++)
+ {
+ CMyComBSTR name;
+ PROPID propID;
+ VARTYPE varType;
+
+ if (enumProperties->GetPropertyInfo(i, &name, &propID, &varType) != S_OK)
+ throw 1;
+
+ CItemProperty destProperty;
+ destProperty.Type = varType;
+ destProperty.ID = propID;
+ if (propID == kpidIsFolder)
+ continue;
+ {
+ if (name != NULL)
+ destProperty.Name = name;
+ else
+ destProperty.Name = L"Error";
+ }
+ UString propName = GetNameOfProperty(propID);
+ if (!propName.IsEmpty())
+ destProperty.Name = propName;
+ destProperty.Order = -1;
+ destProperty.IsVisible = true;
+ destProperty.Width = 100;
+ _properties.Add(destProperty);
+ }
+ // InitColumns2(sortID);
+
+ for (;;)
+ if (!_listView.DeleteColumn(0))
+ break;
+
+ int order = 0;
+ for(i = 0; i < _listViewInfo.Columns.Size(); i++)
+ {
+ const CColumnInfo &columnInfo = _listViewInfo.Columns[i];
+ int index = _properties.FindItemWithID(columnInfo.PropID);
+ if (index >= 0)
+ {
+ CItemProperty &item = _properties[index];
+ item.IsVisible = columnInfo.IsVisible;
+ item.Width = columnInfo.Width;
+ if (columnInfo.IsVisible)
+ item.Order = order++;
+ continue;
+ }
+ }
+ for(i = 0; i < _properties.Size(); i++)
+ {
+ CItemProperty &item = _properties[i];
+ if (item.Order < 0)
+ item.Order = order++;
+ }
+
+ _visibleProperties.Clear();
+ for (i = 0; i < _properties.Size(); i++)
+ {
+ const CItemProperty &property = _properties[i];
+ if (property.IsVisible)
+ _visibleProperties.Add(property);
+ }
+
+ // _sortIndex = 0;
+ _sortID = kpidName;
+ /*
+ if (_listViewInfo.SortIndex >= 0)
+ {
+ int sortIndex = _properties.FindItemWithID(sortID);
+ if (sortIndex >= 0)
+ _sortIndex = sortIndex;
+ }
+ */
+ _sortID = _listViewInfo.SortID;
+
+ for (i = 0; i < _visibleProperties.Size(); i++)
+ {
+ InsertColumn(i);
+ }
+}
+
+void CPanel::InsertColumn(int index)
+{
+ const CItemProperty &property = _visibleProperties[index];
+ LV_COLUMNW column;
+ column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM | LVCF_ORDER;
+ column.cx = property.Width;
+ column.fmt = GetColumnAlign(property.ID, property.Type);
+ column.iOrder = property.Order;
+ column.iSubItem = index;
+ UString propertyName = GetNameOfProperty(property.ID);
+ if (propertyName.IsEmpty())
+ propertyName = property.Name;
+ column.pszText = (wchar_t *)(const wchar_t *)propertyName;
+ _listView.InsertColumn(index, &column);
+}
+
+void CPanel::RefreshListCtrl()
+{
+ RefreshListCtrl(UString(), -1, true, UStringVector());
+}
+
+int CALLBACK CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData);
+
+
+void CPanel::GetSelectedNames(UStringVector &selectedNames)
+{
+ selectedNames.Clear();
+
+ CRecordVector<UINT32> indices;
+ GetSelectedItemsIndices(indices);
+ selectedNames.Reserve(indices.Size());
+ for (int i = 0; i < indices.Size(); i++)
+ selectedNames.Add(GetItemRelPath(indices[i]));
+
+ /*
+ for (int i = 0; i < _listView.GetItemCount(); i++)
+ {
+ const int kSize = 1024;
+ WCHAR name[kSize + 1];
+ LVITEMW item;
+ item.iItem = i;
+ item.pszText = name;
+ item.cchTextMax = kSize;
+ item.iSubItem = 0;
+ item.mask = LVIF_TEXT | LVIF_PARAM;
+ if (!_listView.GetItem(&item))
+ continue;
+ int realIndex = GetRealIndex(item);
+ if (realIndex == kParentIndex)
+ continue;
+ if (_selectedStatusVector[realIndex])
+ selectedNames.Add(item.pszText);
+ }
+ */
+ selectedNames.Sort();
+}
+
+void CPanel::SaveSelectedState(CSelectedState &s)
+{
+ s.FocusedName.Empty();
+ s.SelectedNames.Clear();
+ s.FocusedItem = _listView.GetFocusedItem();
+ {
+ if (s.FocusedItem >= 0)
+ {
+ int realIndex = GetRealItemIndex(s.FocusedItem);
+ if (realIndex != kParentIndex)
+ s.FocusedName = GetItemRelPath(realIndex);
+ /*
+ const int kSize = 1024;
+ WCHAR name[kSize + 1];
+ LVITEMW item;
+ item.iItem = focusedItem;
+ item.pszText = name;
+ item.cchTextMax = kSize;
+ item.iSubItem = 0;
+ item.mask = LVIF_TEXT;
+ if (_listView.GetItem(&item))
+ focusedName = item.pszText;
+ */
+ }
+ }
+ GetSelectedNames(s.SelectedNames);
+}
+
+void CPanel::RefreshListCtrl(const CSelectedState &s)
+{
+ bool selectFocused = s.SelectFocused;
+ if (_mySelectMode)
+ selectFocused = true;
+ RefreshListCtrl(s.FocusedName, s.FocusedItem, selectFocused, s.SelectedNames);
+}
+
+void CPanel::RefreshListCtrlSaveFocused()
+{
+ CSelectedState state;
+ SaveSelectedState(state);
+ RefreshListCtrl(state);
+}
+
+void CPanel::SetFocusedSelectedItem(int index, bool select)
+{
+ UINT state = LVIS_FOCUSED;
+ if (select)
+ state |= LVIS_SELECTED;
+ _listView.SetItemState(index, state, state);
+ if (!_mySelectMode && select)
+ {
+ int realIndex = GetRealItemIndex(index);
+ if (realIndex != kParentIndex)
+ _selectedStatusVector[realIndex] = true;
+ }
+}
+
+void CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool selectFocused,
+ const UStringVector &selectedNames)
+{
+ _dontShowMode = false;
+ LoadFullPathAndShow();
+ // OutputDebugStringA("=======\n");
+ // OutputDebugStringA("s1 \n");
+ CDisableTimerProcessing timerProcessing(*this);
+
+ if (focusedPos < 0)
+ focusedPos = 0;
+
+ _listView.SetRedraw(false);
+ // m_RedrawEnabled = false;
+
+ LVITEMW item;
+ ZeroMemory(&item, sizeof(item));
+
+ _listView.DeleteAllItems();
+ _selectedStatusVector.Clear();
+ // _realIndices.Clear();
+ _startGroupSelect = 0;
+
+ _selectionIsDefined = false;
+
+ // m_Files.Clear();
+ // _folder.Release();
+
+ if (!_folder)
+ {
+ // throw 1;
+ SetToRootFolder();
+ }
+
+ _headerToolBar.EnableButton(kParentFolderID, !IsRootFolder());
+
+ CMyComPtr<IFolderSetFlatMode> folderSetFlatMode;
+ _folder.QueryInterface(IID_IFolderSetFlatMode, &folderSetFlatMode);
+ if (folderSetFlatMode)
+ folderSetFlatMode->SetFlatMode(BoolToInt(_flatMode));
+
+ if (_folder->LoadItems() != S_OK)
+ return;
+
+ InitColumns();
+
+
+ // OutputDebugString(TEXT("Start Dir\n"));
+ UINT32 numItems;
+ _folder->GetNumberOfItems(&numItems);
+
+ bool showDots = _showDots && !IsRootFolder();
+
+ _listView.SetItemCount(numItems + (showDots ? 1 : 0));
+
+ _selectedStatusVector.Reserve(numItems);
+ int cursorIndex = -1;
+
+ CMyComPtr<IFolderGetSystemIconIndex> folderGetSystemIconIndex;
+ if (!IsFSFolder() || _showRealFileIcons)
+ _folder.QueryInterface(IID_IFolderGetSystemIconIndex, &folderGetSystemIconIndex);
+
+ if (showDots)
+ {
+ UString itemName = L"..";
+ item.iItem = _listView.GetItemCount();
+ if (itemName.CompareNoCase(focusedName) == 0)
+ cursorIndex = item.iItem;
+ item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
+ int subItem = 0;
+ item.iSubItem = subItem++;
+ item.lParam = kParentIndex;
+ item.pszText = (wchar_t *)(const wchar_t *)itemName;
+ UINT32 attributes = FILE_ATTRIBUTE_DIRECTORY;
+ item.iImage = _extToIconMap.GetIconIndex(attributes, itemName);
+ if (item.iImage < 0)
+ item.iImage = 0;
+ if(_listView.InsertItem(&item) == -1)
+ return;
+ }
+
+ // OutputDebugStringA("S1\n");
+
+ for(UInt32 i = 0; i < numItems; i++)
+ {
+ UString itemName = GetItemName(i);
+ const UString relPath = GetItemRelPath(i);
+ if (relPath.CompareNoCase(focusedName) == 0)
+ cursorIndex = _listView.GetItemCount();
+ bool selected = false;
+ if (selectedNames.FindInSorted(relPath) >= 0)
+ selected = true;
+ _selectedStatusVector.Add(selected);
+
+ item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
+
+ if (!_mySelectMode)
+ if (selected)
+ {
+ item.mask |= LVIF_STATE;
+ item.state = LVIS_SELECTED;
+ }
+
+ int subItem = 0;
+ item.iItem = _listView.GetItemCount();
+
+ item.iSubItem = subItem++;
+ item.lParam = i;
+
+ UString correctedName;
+ if (itemName.Find(L" ") >= 0)
+ {
+ int pos = 0;
+ for (;;)
+ {
+ int posNew = itemName.Find(L" ", pos);
+ if (posNew < 0)
+ {
+ correctedName += itemName.Mid(pos);
+ break;
+ }
+ correctedName += itemName.Mid(pos, posNew - pos);
+ correctedName += L" ... ";
+ pos = posNew;
+ while (itemName[++pos] == ' ');
+ }
+ item.pszText = (wchar_t *)(const wchar_t *)correctedName;
+ }
+ else
+ item.pszText = (wchar_t *)(const wchar_t *)itemName;
+
+ NCOM::CPropVariant propVariant;
+ _folder->GetProperty(i, kpidAttributes, &propVariant);
+ UINT32 attributes = 0;
+ if (propVariant.vt == VT_UI4)
+ attributes = propVariant.ulVal;
+ else
+ {
+ if (IsItemFolder(i))
+ attributes |= FILE_ATTRIBUTE_DIRECTORY;
+ }
+
+ bool defined = false;
+
+ if (folderGetSystemIconIndex)
+ {
+ folderGetSystemIconIndex->GetSystemIconIndex(i, &item.iImage);
+ defined = (item.iImage > 0);
+ }
+ if (!defined)
+ {
+ if (_currentFolderPrefix.IsEmpty())
+ {
+ int iconIndexTemp;
+ GetRealIconIndex(itemName + L"\\", attributes, iconIndexTemp);
+ item.iImage = iconIndexTemp;
+ }
+ else
+ {
+ item.iImage = _extToIconMap.GetIconIndex(attributes, itemName);
+ }
+ }
+ if (item.iImage < 0)
+ item.iImage = 0;
+
+ if(_listView.InsertItem(&item) == -1)
+ return; // error
+ }
+ // OutputDebugStringA("End2\n");
+
+ if(_listView.GetItemCount() > 0 && cursorIndex >= 0)
+ SetFocusedSelectedItem(cursorIndex, selectFocused);
+ _listView.SortItems(CompareItems, (LPARAM)this);
+ if (cursorIndex < 0 && _listView.GetItemCount() > 0)
+ {
+ if (focusedPos >= _listView.GetItemCount())
+ focusedPos = _listView.GetItemCount() - 1;
+ SetFocusedSelectedItem(focusedPos, true);
+ }
+ // m_RedrawEnabled = true;
+ _listView.EnsureVisible(_listView.GetFocusedItem(), false);
+ _listView.SetRedraw(true);
+ _listView.InvalidateRect(NULL, true);
+ // OutputDebugStringA("End1\n");
+ /*
+ _listView.UpdateWindow();
+ */
+}
+
+void CPanel::GetSelectedItemsIndices(CRecordVector<UINT32> &indices) const
+{
+ indices.Clear();
+ /*
+ int itemIndex = -1;
+ while ((itemIndex = _listView.GetNextItem(itemIndex, LVNI_SELECTED)) != -1)
+ {
+ LPARAM param;
+ if (_listView.GetItemParam(itemIndex, param))
+ indices.Add(param);
+ }
+ */
+ for (int i = 0; i < _selectedStatusVector.Size(); i++)
+ if (_selectedStatusVector[i])
+ indices.Add(i);
+ HeapSort(&indices.Front(), indices.Size());
+}
+
+void CPanel::GetOperatedItemIndices(CRecordVector<UINT32> &indices) const
+{
+ GetSelectedItemsIndices(indices);
+ if (!indices.IsEmpty())
+ return;
+ if (_listView.GetSelectedCount() == 0)
+ return;
+ int focusedItem = _listView.GetFocusedItem();
+ if (focusedItem >= 0)
+ {
+ if(_listView.GetItemState(focusedItem, LVIS_SELECTED) == LVIS_SELECTED)
+ {
+ int realIndex = GetRealItemIndex(focusedItem);
+ if (realIndex != kParentIndex)
+ indices.Add(realIndex);
+ }
+ }
+}
+
+/*
+void CPanel::GetOperatedListViewIndices(CRecordVector<UInt32> &indices) const
+{
+ indices.Clear();
+ int numItems = _listView.GetItemCount();
+ for (int i = 0; i < numItems; i++)
+ {
+ int realIndex = GetRealItemIndex(i);
+ if (realIndex >= 0)
+ if (_selectedStatusVector[realIndex])
+ indices.Add(i);
+ }
+ if (indices.IsEmpty())
+ {
+ int focusedItem = _listView.GetFocusedItem();
+ if (focusedItem >= 0)
+ indices.Add(focusedItem);
+ }
+}
+*/
+
+void CPanel::EditItem()
+{
+ int focusedItem = _listView.GetFocusedItem();
+ if (focusedItem < 0)
+ return;
+ int realIndex = GetRealItemIndex(focusedItem);
+ if (realIndex == kParentIndex)
+ return;
+ if (!IsItemFolder(realIndex))
+ EditItem(realIndex);
+}
+
+void CPanel::OpenFocusedItemAsInternal()
+{
+ int focusedItem = _listView.GetFocusedItem();
+ if (focusedItem < 0)
+ return;
+ int realIndex = GetRealItemIndex(focusedItem);
+ if (IsItemFolder(realIndex))
+ OpenFolder(realIndex);
+ else
+ OpenItem(realIndex, true, false);
+}
+
+void CPanel::OpenSelectedItems(bool tryInternal)
+{
+ CRecordVector<UINT32> indices;
+ GetOperatedItemIndices(indices);
+ if (indices.Size() > 20)
+ {
+ MessageBox(LangString(IDS_TOO_MANY_ITEMS, 0x02000606));
+ return;
+ }
+
+ int focusedItem = _listView.GetFocusedItem();
+ if (focusedItem >= 0)
+ {
+ int realIndex = GetRealItemIndex(focusedItem);
+ if (realIndex == kParentIndex && (tryInternal || indices.Size() == 0))
+ indices.Insert(0, realIndex);
+ }
+
+ bool dirIsStarted = false;
+ for(int i = 0; i < indices.Size(); i++)
+ {
+ UINT32 index = indices[i];
+ // CFileInfo &aFile = m_Files[index];
+ if (IsItemFolder(index))
+ {
+ if (!dirIsStarted)
+ {
+ if (tryInternal)
+ {
+ OpenFolder(index);
+ dirIsStarted = true;
+ break;
+ }
+ else
+ OpenFolderExternal(index);
+ }
+ }
+ else
+ OpenItem(index, (tryInternal && indices.Size() == 1), true);
+ }
+}
+
+UString CPanel::GetItemName(int itemIndex) const
+{
+ if (itemIndex == kParentIndex)
+ return L"..";
+ NCOM::CPropVariant propVariant;
+ if (_folder->GetProperty(itemIndex, kpidName, &propVariant) != S_OK)
+ throw 2723400;
+ if (propVariant.vt != VT_BSTR)
+ throw 2723401;
+ return (propVariant.bstrVal);
+}
+
+UString CPanel::GetItemPrefix(int itemIndex) const
+{
+ if (itemIndex == kParentIndex)
+ return UString();
+ NCOM::CPropVariant propVariant;
+ if (_folder->GetProperty(itemIndex, kpidPrefix, &propVariant) != S_OK)
+ throw 2723400;
+ UString prefix;
+ if (propVariant.vt == VT_BSTR)
+ prefix = propVariant.bstrVal;
+ return prefix;
+}
+
+UString CPanel::GetItemRelPath(int itemIndex) const
+{
+ return GetItemPrefix(itemIndex) + GetItemName(itemIndex);
+}
+
+
+bool CPanel::IsItemFolder(int itemIndex) const
+{
+ if (itemIndex == kParentIndex)
+ return true;
+ NCOM::CPropVariant propVariant;
+ if (_folder->GetProperty(itemIndex, kpidIsFolder, &propVariant) != S_OK)
+ throw 2723400;
+ if (propVariant.vt == VT_BOOL)
+ return VARIANT_BOOLToBool(propVariant.boolVal);
+ if (propVariant.vt == VT_EMPTY)
+ return false;
+ return false;
+}
+
+UINT64 CPanel::GetItemSize(int itemIndex) const
+{
+ if (itemIndex == kParentIndex)
+ return 0;
+ NCOM::CPropVariant propVariant;
+ if (_folder->GetProperty(itemIndex, kpidSize, &propVariant) != S_OK)
+ throw 2723400;
+ if (propVariant.vt == VT_EMPTY)
+ return 0;
+ return ConvertPropVariantToUInt64(propVariant);
+}
+
+void CPanel::ReadListViewInfo()
+{
+ CMyComPtr<IFolderGetTypeID> folderGetTypeID;
+ if(_folder.QueryInterface(IID_IFolderGetTypeID, &folderGetTypeID) != S_OK)
+ return;
+ CMyComBSTR typeID;
+ folderGetTypeID->GetTypeID(&typeID);
+ _typeIDString = typeID;
+ ::ReadListViewInfo(_typeIDString, _listViewInfo);
+}
+
+void CPanel::SaveListViewInfo()
+{
+ int i;
+ for(i = 0; i < _visibleProperties.Size(); i++)
+ {
+ CItemProperty &property = _visibleProperties[i];
+ LVCOLUMN winColumnInfo;
+ winColumnInfo.mask = LVCF_ORDER | LVCF_WIDTH;
+ if (!_listView.GetColumn(i, &winColumnInfo))
+ throw 1;
+ property.Order = winColumnInfo.iOrder;
+ property.Width = winColumnInfo.cx;
+ }
+
+ CListViewInfo viewInfo;
+
+ // PROPID sortPropID = _properties[_sortIndex].ID;
+ PROPID sortPropID = _sortID;
+
+ _visibleProperties.Sort();
+ for(i = 0; i < _visibleProperties.Size(); i++)
+ {
+ const CItemProperty &property = _visibleProperties[i];
+ CColumnInfo columnInfo;
+ columnInfo.IsVisible = property.IsVisible;
+ columnInfo.PropID = property.ID;
+ columnInfo.Width = property.Width;
+ viewInfo.Columns.Add(columnInfo);
+ }
+ for(i = 0; i < _properties.Size(); i++)
+ {
+ const CItemProperty &property = _properties[i];
+ if (!property.IsVisible)
+ {
+ CColumnInfo columnInfo;
+ columnInfo.IsVisible = property.IsVisible;
+ columnInfo.PropID = property.ID;
+ columnInfo.Width = property.Width;
+ viewInfo.Columns.Add(columnInfo);
+ }
+ }
+
+ // viewInfo.SortIndex = viewInfo.FindColumnWithID(sortPropID);
+ viewInfo.SortID = sortPropID;
+
+ viewInfo.Ascending = _ascending;
+ if (!_listViewInfo.IsEqual(viewInfo))
+ {
+ ::SaveListViewInfo(_typeIDString, viewInfo);
+ _listViewInfo = viewInfo;
+ }
+}
+
+bool CPanel::OnRightClick(LPNMITEMACTIVATE itemActiveate, LRESULT &result)
+{
+ if(itemActiveate->hdr.hwndFrom == HWND(_listView))
+ return false;
+
+ POINT point;
+ ::GetCursorPos(&point);
+
+ CMenu menu;
+ CMenuDestroyer menuDestroyer(menu);
+
+ menu.CreatePopup();
+
+ const int kCommandStart = 100;
+ for(int i = 0; i < _properties.Size(); i++)
+ {
+ const CItemProperty &property = _properties[i];
+ UINT flags = MF_STRING;
+ if (property.IsVisible)
+ flags |= MF_CHECKED;
+ if (i == 0)
+ flags |= MF_GRAYED;
+ menu.AppendItem(flags, kCommandStart + i, GetSystemString(property.Name));
+ }
+ int menuResult = menu.Track(TPM_LEFTALIGN | TPM_RETURNCMD | TPM_NONOTIFY,
+ point.x, point.y, _listView);
+ if (menuResult >= kCommandStart && menuResult <= kCommandStart + _properties.Size())
+ {
+ int index = menuResult - kCommandStart;
+ CItemProperty &property = _properties[index];
+ property.IsVisible = !property.IsVisible;
+
+ if (property.IsVisible)
+ {
+ int prevVisibleSize = _visibleProperties.Size();
+ property.Order = prevVisibleSize;
+ _visibleProperties.Add(property);
+ InsertColumn(prevVisibleSize);
+ }
+ else
+ {
+ int visibleIndex = _visibleProperties.FindItemWithID(property.ID);
+ _visibleProperties.Delete(visibleIndex);
+ /*
+ if (_sortIndex == index)
+ {
+ _sortIndex = 0;
+ _ascending = true;
+ }
+ */
+ if (_sortID == property.ID)
+ {
+ _sortID = kpidName;
+ _ascending = true;
+ }
+
+ _listView.DeleteColumn(visibleIndex);
+ }
+ }
+ result = TRUE;
+ return true;
+}
+
+void CPanel::OnReload()
+{
+ RefreshListCtrlSaveFocused();
+ OnRefreshStatusBar();
+}
+
+void CPanel::OnTimer()
+{
+ if (!_processTimer)
+ return;
+ CMyComPtr<IFolderWasChanged> folderWasChanged;
+ if (_folder.QueryInterface(IID_IFolderWasChanged, &folderWasChanged) != S_OK)
+ return;
+ INT32 wasChanged;
+ if (folderWasChanged->WasChanged(&wasChanged) != S_OK)
+ return;
+ if (wasChanged == 0)
+ return;
+ OnReload();
+}
+
diff --git a/CPP/7zip/FileManager/PanelKey.cpp b/CPP/7zip/FileManager/PanelKey.cpp
new file mode 100755
index 00000000..9c6ddac1
--- /dev/null
+++ b/CPP/7zip/FileManager/PanelKey.cpp
@@ -0,0 +1,297 @@
+// PanelKey.cpp
+
+#include "StdAfx.h"
+
+#include "Panel.h"
+#include "HelpUtils.h"
+
+#include "../PropID.h"
+#include "App.h"
+
+// static LPCWSTR kHelpTopic = L"FM/index.htm";
+
+struct CVKeyPropIDPair
+{
+ WORD VKey;
+ PROPID PropID;
+};
+
+static CVKeyPropIDPair g_VKeyPropIDPairs[] =
+{
+ { VK_F3, kpidName },
+ { VK_F4, kpidExtension },
+ { VK_F5, kpidLastWriteTime },
+ { VK_F6, kpidSize },
+ { VK_F7, kpidNoProperty }
+};
+
+static int FindVKeyPropIDPair(WORD vKey)
+{
+ for (int i = 0; i < sizeof(g_VKeyPropIDPairs) / sizeof(g_VKeyPropIDPairs[0]); i++)
+ if (g_VKeyPropIDPairs[i].VKey == vKey)
+ return i;
+ return -1;
+}
+
+
+bool CPanel::OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result)
+{
+ if (keyDownInfo->wVKey == VK_TAB && keyDownInfo->hdr.hwndFrom == _listView)
+ {
+ _panelCallback->OnTab();
+ return false;
+ }
+ bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0;
+ bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0;
+ // bool leftCtrl = (::GetKeyState(VK_LCONTROL) & 0x8000) != 0;
+ bool rightCtrl = (::GetKeyState(VK_RCONTROL) & 0x8000) != 0;
+ bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0;
+ result = 0;
+
+ if (keyDownInfo->wVKey >= '0' && keyDownInfo->wVKey <= '9' &&
+ (rightCtrl || alt))
+ {
+ int index = keyDownInfo->wVKey - '0';
+ if (shift)
+ {
+ SetBookmark(index);
+ return true;
+ }
+ else
+ {
+ OpenBookmark(index);
+ return true;
+ }
+ }
+
+ if ((keyDownInfo->wVKey == VK_F2 ||
+ keyDownInfo->wVKey == VK_F1) && alt && !ctrl && !shift)
+ {
+ _panelCallback->SetFocusToPath(keyDownInfo->wVKey == VK_F1 ? 0 : 1);
+ return true;
+ }
+
+ if ((keyDownInfo->wVKey == VK_F9) && !alt && !ctrl && !shift)
+ {
+ g_App.SwitchOnOffOnePanel();
+ }
+
+ if(keyDownInfo->wVKey >= VK_F3 && keyDownInfo->wVKey <= VK_F12 && ctrl)
+ {
+ int index = FindVKeyPropIDPair(keyDownInfo->wVKey);
+ if (index >= 0)
+ SortItemsWithPropID(g_VKeyPropIDPairs[index].PropID);
+ }
+
+ switch(keyDownInfo->wVKey)
+ {
+ case VK_SHIFT:
+ {
+ _selectionIsDefined = false;
+ _prevFocusedItem = _listView.GetFocusedItem();
+ break;
+ }
+ /*
+ case VK_F1:
+ {
+ // ShowHelpWindow(NULL, kHelpTopic);
+ break;
+ }
+ */
+ case VK_F2:
+ {
+ if (!alt && !ctrl &&!shift)
+ {
+ RenameFile();
+ return true;
+ }
+ break;
+ }
+ case VK_F4:
+ {
+ if (!alt && !ctrl && !shift)
+ {
+ EditItem();
+ return true;
+ }
+ if (!alt && !ctrl && shift)
+ {
+ CreateFile();
+ return true;
+ }
+ break;
+ }
+ case VK_F5:
+ {
+ if (!alt && !ctrl)
+ {
+ _panelCallback->OnCopy(false, shift);
+ return true;
+ }
+ break;
+ }
+ case VK_F6:
+ {
+ if (!alt && !ctrl)
+ {
+ _panelCallback->OnCopy(true, shift);
+ return true;
+ }
+ break;
+ }
+ /*
+ case VK_F7:
+ {
+ if (!alt && !ctrl && !shift)
+ {
+ CreateFolder();
+ return true;
+ }
+ break;
+ }
+ */
+ case VK_DELETE:
+ {
+ DeleteItems(!shift);
+ return true;
+ }
+ case VK_INSERT:
+ {
+ OnInsert();
+ return true;
+ }
+ case VK_DOWN:
+ {
+ if(shift)
+ OnArrowWithShift();
+ return false;
+ }
+ case VK_UP:
+ {
+ if (alt)
+ _panelCallback->OnSetSameFolder();
+ else if(shift)
+ OnArrowWithShift();
+ return false;
+ }
+ case VK_RIGHT:
+ {
+ if (alt)
+ _panelCallback->OnSetSubFolder();
+ else if(shift)
+ OnArrowWithShift();
+ return false;
+ }
+ case VK_LEFT:
+ {
+ if (alt)
+ _panelCallback->OnSetSubFolder();
+ else if(shift)
+ OnArrowWithShift();
+ return false;
+ }
+ case VK_NEXT:
+ {
+ if (ctrl && !alt && !shift)
+ {
+ // EnterToFocused();
+ return true;
+ }
+ break;
+ }
+ case VK_ADD:
+ {
+ if (alt)
+ SelectByType(true);
+ else if (shift)
+ SelectAll(true);
+ else if(!ctrl)
+ SelectSpec(true);
+ return true;
+ }
+ case VK_SUBTRACT:
+ {
+ if (alt)
+ SelectByType(false);
+ else if (shift)
+ SelectAll(false);
+ else
+ SelectSpec(false);
+ return true;
+ }
+ /*
+ case VK_DELETE:
+ CommandDelete();
+ return 0;
+ case VK_F1:
+ CommandHelp();
+ return 0;
+ */
+ case VK_BACK:
+ OpenParentFolder();
+ return true;
+ /*
+ case VK_DIVIDE:
+ case '\\':
+ case '/':
+ case VK_OEM_5:
+ {
+ // OpenRootFolder();
+ OpenDrivesFolder();
+
+ return true;
+ }
+ */
+ case 'A':
+ if(ctrl)
+ {
+ SelectAll(true);
+ return true;
+ }
+ return false;
+ case 'N':
+ if (ctrl)
+ {
+ CreateFile();
+ return true;
+ }
+ return false;
+ case 'R':
+ if(ctrl)
+ {
+ OnReload();
+ return true;
+ }
+ return false;
+ case 'Z':
+ if(ctrl)
+ {
+ ChangeComment();
+ return true;
+ }
+ return false;
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ if(ctrl)
+ {
+ int styleIndex = keyDownInfo->wVKey - '1';
+ SetListViewMode(styleIndex);
+ return true;
+ }
+ return false;
+ case VK_MULTIPLY:
+ {
+ InvertSelection();
+ return true;
+ }
+ case VK_F12:
+ if (alt && !ctrl && !shift)
+ {
+ FoldersHistory();
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/CPP/7zip/FileManager/PanelListNotify.cpp b/CPP/7zip/FileManager/PanelListNotify.cpp
new file mode 100755
index 00000000..44bb3e8b
--- /dev/null
+++ b/CPP/7zip/FileManager/PanelListNotify.cpp
@@ -0,0 +1,388 @@
+// PanelListNotify.cpp
+
+#include "StdAfx.h"
+
+#include "resource.h"
+
+#include "Common/IntToString.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/PropVariant.h"
+#include "Windows/PropVariantConversions.h"
+#include "Windows/COM.h"
+
+#include "../UI/Common/PropIDUtils.h"
+#include "../PropID.h"
+
+#include "Panel.h"
+#include "FormatUtils.h"
+
+using namespace NWindows;
+
+static UString ConvertSizeToString(UINT64 value)
+{
+ wchar_t s[64];
+ if (value < (UINT64(10000) << 0) /*&& ((value & 0x3FF) != 0 || value == 0)*/)
+ {
+ ConvertUInt64ToString(value, s);
+ return UString(s) + L" B";
+ }
+ if (value < (UINT64(10000) << 10))
+ {
+ ConvertUInt64ToString((value >> 10), s);
+ return UString(s) + L" K";
+ }
+ if (value < (UINT64(10000) << 20))
+ {
+ ConvertUInt64ToString((value >> 20), s);
+ return UString(s) + L" M";
+ }
+ ConvertUInt64ToString((value >> 30), s);
+ return UString(s) + L" G";
+}
+
+LRESULT CPanel::SetItemText(LVITEMW &item)
+{
+ if (_dontShowMode)
+ return 0;
+
+ UINT32 realIndex = GetRealIndex(item);
+ /*
+ if ((item.mask & LVIF_IMAGE) != 0)
+ {
+ bool defined = false;
+ CComPtr<IFolderGetSystemIconIndex> folderGetSystemIconIndex;
+ _folder.QueryInterface(&folderGetSystemIconIndex);
+ if (folderGetSystemIconIndex)
+ {
+ folderGetSystemIconIndex->GetSystemIconIndex(index, &item.iImage);
+ defined = (item.iImage > 0);
+ }
+ if (!defined)
+ {
+ NCOM::CPropVariant propVariant;
+ _folder->GetProperty(index, kpidAttributes, &propVariant);
+ UINT32 attributes = 0;
+ if (propVariant.vt == VT_UI4)
+ attributes = propVariant.ulVal;
+ else
+ {
+ if (IsItemFolder(index))
+ attributes |= FILE_ATTRIBUTE_DIRECTORY;
+ }
+ if (_currentFolderPrefix.IsEmpty())
+ {
+ throw 1;
+ }
+ else
+ item.iImage = _extToIconMap.GetIconIndex(attributes,
+ GetSystemString(GetItemName(index)));
+ }
+ // item.iImage = 1;
+ }
+ */
+
+ if ((item.mask & LVIF_TEXT) == 0)
+ return 0;
+
+ if (realIndex == kParentIndex)
+ return 0;
+ UString s;
+ UINT32 subItemIndex = item.iSubItem;
+ PROPID propID = _visibleProperties[subItemIndex].ID;
+ /*
+ {
+ NCOM::CPropVariant property;
+ if(propID == kpidType)
+ string = GetFileType(index);
+ else
+ {
+ HRESULT result = m_ArchiveFolder->GetProperty(index, propID, &property);
+ if (result != S_OK)
+ {
+ // PrintMessage("GetPropertyValue error");
+ return 0;
+ }
+ string = ConvertPropertyToString(property, propID, false);
+ }
+ }
+ */
+ // const NFind::CFileInfo &aFileInfo = m_Files[index];
+
+ NCOM::CPropVariant propVariant;
+ /*
+ bool needRead = true;
+ if (propID == kpidSize)
+ {
+ CComPtr<IFolderGetItemFullSize> getItemFullSize;
+ if (_folder.QueryInterface(&getItemFullSize) == S_OK)
+ {
+ if (getItemFullSize->GetItemFullSize(index, &propVariant) == S_OK)
+ needRead = false;
+ }
+ }
+ if (needRead)
+ */
+
+ if (_folder->GetProperty(realIndex, propID, &propVariant) != S_OK)
+ throw 2723407;
+
+ if ((propID == kpidSize || propID == kpidPackedSize ||
+ propID == kpidTotalSize || propID == kpidFreeSpace ||
+ propID == kpidClusterSize)
+ &&
+ (propVariant.vt == VT_UI8 || propVariant.vt == VT_UI4))
+ s = ConvertSizeToString(ConvertPropVariantToUInt64(propVariant));
+ else
+ s = ConvertPropertyToString(propVariant, propID, false);
+
+ int size = item.cchTextMax;
+ if(size > 0)
+ {
+ if(s.Length() + 1 > size)
+ s = s.Left(size - 1);
+ MyStringCopy(item.pszText, (const wchar_t *)s);
+ }
+ return 0;
+}
+
+extern DWORD g_ComCtl32Version;
+
+void CPanel::OnItemChanged(NMLISTVIEW *item)
+{
+ int index = (int)item->lParam;
+ if (index == kParentIndex)
+ return;
+ bool oldSelected = (item->uOldState & LVIS_SELECTED) != 0;
+ bool newSelected = (item->uNewState & LVIS_SELECTED) != 0;
+ // Don't change this code. It works only with such check
+ if(oldSelected != newSelected)
+ _selectedStatusVector[index] = newSelected;
+}
+
+bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result)
+{
+ // bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0;
+ // bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0;
+ // bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0;
+ switch(header->code)
+ {
+ case LVN_ITEMCHANGED:
+ {
+ if (_enableItemChangeNotify)
+ {
+ if (!_mySelectMode)
+ OnItemChanged((LPNMLISTVIEW)header);
+ RefreshStatusBar();
+ }
+ return false;
+ }
+ /*
+
+ case LVN_ODSTATECHANGED:
+ {
+ break;
+ }
+ */
+
+ case LVN_GETDISPINFOW:
+ {
+ LV_DISPINFOW *dispInfo = (LV_DISPINFOW *)header;
+
+ //is the sub-item information being requested?
+
+ if((dispInfo->item.mask & LVIF_TEXT) != 0 ||
+ (dispInfo->item.mask & LVIF_IMAGE) != 0)
+ SetItemText(dispInfo->item);
+ return false;
+ }
+ case LVN_KEYDOWN:
+ {
+ bool boolResult = OnKeyDown(LPNMLVKEYDOWN(header), result);
+ RefreshStatusBar();
+ return boolResult;
+ }
+
+ case LVN_COLUMNCLICK:
+ OnColumnClick(LPNMLISTVIEW(header));
+ return false;
+ /*
+ case LVN_ITEMACTIVATE:
+ RefreshStatusBar();
+ if (!alt && !ctrl && !shift)
+ OpenSelectedItems(true);
+ return false;
+ */
+
+ case NM_DBLCLK:
+ RefreshStatusBar();
+ OpenSelectedItems(true);
+ return false;
+ case NM_RETURN:
+ {
+ bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0;
+ bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0;
+ // bool leftCtrl = (::GetKeyState(VK_LCONTROL) & 0x8000) != 0;
+ // bool RightCtrl = (::GetKeyState(VK_RCONTROL) & 0x8000) != 0;
+ bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0;
+ if (!shift && alt && !ctrl)
+ {
+ Properties();
+ return false;
+ }
+ OpenSelectedItems(true);
+ return false;
+ }
+ case NM_RCLICK:
+ RefreshStatusBar();
+ break;
+
+ /*
+ return OnRightClick((LPNMITEMACTIVATE)header, result);
+ */
+ /*
+ case NM_CLICK:
+ SendRefreshStatusBarMessage();
+ return 0;
+
+ // TODO : Handler default action...
+ return 0;
+ case LVN_ITEMCHANGED:
+ {
+ NMLISTVIEW *pNMLV = (NMLISTVIEW *) lpnmh;
+ SelChange(pNMLV);
+ return TRUE;
+ }
+ case NM_SETFOCUS:
+ return onSetFocus(NULL);
+ case NM_KILLFOCUS:
+ return onKillFocus(NULL);
+ */
+ case NM_CLICK:
+ {
+ // we need SetFocusToList, if we drag-select items from other panel.
+ SetFocusToList();
+ RefreshStatusBar();
+ if(_mySelectMode)
+ if(g_ComCtl32Version >= MAKELONG(71, 4))
+ OnLeftClick((LPNMITEMACTIVATE)header);
+ return false;
+ }
+ case LVN_BEGINLABELEDITW:
+ result = OnBeginLabelEdit((LV_DISPINFOW *)header);
+ return true;
+ case LVN_ENDLABELEDITW:
+ result = OnEndLabelEdit((LV_DISPINFOW *)header);
+ return true;
+
+ case NM_CUSTOMDRAW:
+ {
+ if (_mySelectMode)
+ return OnCustomDraw((LPNMLVCUSTOMDRAW)header, result);
+ break;
+ }
+ case LVN_BEGINDRAG:
+ {
+ OnDrag((LPNMLISTVIEW)header);
+ RefreshStatusBar();
+ break;
+ }
+ // case LVN_BEGINRDRAG:
+ }
+ return false;
+}
+
+bool CPanel::OnCustomDraw(LPNMLVCUSTOMDRAW lplvcd, LRESULT &result)
+{
+ switch(lplvcd->nmcd.dwDrawStage)
+ {
+ case CDDS_PREPAINT :
+ result = CDRF_NOTIFYITEMDRAW;
+ return true;
+
+ case CDDS_ITEMPREPAINT:
+ /*
+ SelectObject(lplvcd->nmcd.hdc,
+ GetFontForItem(lplvcd->nmcd.dwItemSpec,
+ lplvcd->nmcd.lItemlParam) );
+ lplvcd->clrText = GetColorForItem(lplvcd->nmcd.dwItemSpec,
+ lplvcd->nmcd.lItemlParam);
+ lplvcd->clrTextBk = GetBkColorForItem(lplvcd->nmcd.dwItemSpec,
+ lplvcd->nmcd.lItemlParam);
+ */
+ int realIndex = (int)lplvcd->nmcd.lItemlParam;
+ bool selected = false;
+ if (realIndex != kParentIndex)
+ selected = _selectedStatusVector[realIndex];
+ if (selected)
+ lplvcd->clrTextBk = RGB(255, 192, 192);
+ // lplvcd->clrText = RGB(255, 0, 128);
+ else
+ lplvcd->clrTextBk = _listView.GetBkColor();
+ // lplvcd->clrText = RGB(0, 0, 0);
+ // result = CDRF_NEWFONT;
+ result = CDRF_NOTIFYITEMDRAW;
+ return true;
+
+ // return false;
+ // return true;
+ /*
+ case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
+ if (lplvcd->iSubItem == 0)
+ {
+ // lplvcd->clrText = RGB(255, 0, 0);
+ lplvcd->clrTextBk = RGB(192, 192, 192);
+ }
+ else
+ {
+ lplvcd->clrText = RGB(0, 0, 0);
+ lplvcd->clrTextBk = RGB(255, 255, 255);
+ }
+ return true;
+ */
+
+ /* At this point, you can change the background colors for the item
+ and any subitems and return CDRF_NEWFONT. If the list-view control
+ is in report mode, you can simply return CDRF_NOTIFYSUBITEMREDRAW
+ to customize the item's subitems individually */
+ }
+ return false;
+}
+
+void CPanel::OnRefreshStatusBar()
+{
+ CRecordVector<UINT32> indices;
+ GetOperatedItemIndices(indices);
+
+ _statusBar.SetText(0, MyFormatNew(IDS_N_SELECTED_ITEMS, 0x02000301, NumberToString(indices.Size())));
+
+ UString selectSizeString;
+
+ if (indices.Size() > 0)
+ {
+ UINT64 totalSize = 0;
+ for (int i = 0; i < indices.Size(); i++)
+ totalSize += GetItemSize(indices[i]);
+ selectSizeString = ConvertSizeToString(totalSize);
+ }
+ _statusBar.SetText(1, selectSizeString);
+
+ int focusedItem = _listView.GetFocusedItem();
+ UString sizeString;
+ UString dateString;
+ if (focusedItem >= 0 && _listView.GetSelectedCount() > 0)
+ {
+ int realIndex = GetRealItemIndex(focusedItem);
+ if (realIndex != kParentIndex)
+ {
+ sizeString = ConvertSizeToString(GetItemSize(realIndex));
+ NCOM::CPropVariant propVariant;
+ if (_folder->GetProperty(realIndex, kpidLastWriteTime, &propVariant) == S_OK)
+ dateString = ConvertPropertyToString(propVariant, kpidLastWriteTime, false);
+ }
+ }
+ _statusBar.SetText(2, sizeString);
+ _statusBar.SetText(3, dateString);
+ // _statusBar.SetText(4, nameString);
+ // _statusBar2.SetText(1, MyFormatNew(L"{0} bytes", NumberToStringW(totalSize)));
+}
diff --git a/CPP/7zip/FileManager/PanelMenu.cpp b/CPP/7zip/FileManager/PanelMenu.cpp
new file mode 100755
index 00000000..64db53ee
--- /dev/null
+++ b/CPP/7zip/FileManager/PanelMenu.cpp
@@ -0,0 +1,422 @@
+#include "StdAfx.h"
+
+#include "Common/StringConvert.h"
+#include "Windows/Menu.h"
+#include "Windows/COM.h"
+
+#include "Panel.h"
+#include "PluginInterface.h"
+#include "MyLoadMenu.h"
+#include "App.h"
+#include "LangUtils.h"
+#include "resource.h"
+
+using namespace NWindows;
+
+// {23170F69-40C1-278A-1000-000100020000}
+DEFINE_GUID(CLSID_CZipContextMenu,
+0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00);
+
+static const UINT kSevenZipStartMenuID = kPluginMenuStartID ;
+static const UINT kSystemStartMenuID = kPluginMenuStartID + 100;
+
+void CPanel::InvokeSystemCommand(const char *command)
+{
+ if (!IsFSFolder() && !IsFSDrivesFolder())
+ return;
+ CRecordVector<UINT32> operatedIndices;
+ GetOperatedItemIndices(operatedIndices);
+ if (operatedIndices.IsEmpty())
+ return;
+ CMyComPtr<IContextMenu> contextMenu;
+ if (CreateShellContextMenu(operatedIndices, contextMenu) != S_OK)
+ return;
+
+ CMINVOKECOMMANDINFO ci;
+ ZeroMemory(&ci, sizeof(ci));
+ ci.cbSize = sizeof(CMINVOKECOMMANDINFO);
+ ci.hwnd = GetParent();
+ ci.lpVerb = command;
+ contextMenu->InvokeCommand(&ci);
+}
+
+void CPanel::Properties()
+{
+ InvokeSystemCommand("properties");
+}
+
+// Copy and paste do not work, if you know why write me.
+
+void CPanel::EditCopy()
+{
+ NCOM::CComInitializer comInitializer;
+ InvokeSystemCommand("copy");
+}
+
+void CPanel::EditPaste()
+{
+ NCOM::CComInitializer comInitializer;
+ InvokeSystemCommand("paste");
+}
+
+HRESULT CPanel::CreateShellContextMenu(
+ const CRecordVector<UINT32> &operatedIndices,
+ CMyComPtr<IContextMenu> &systemContextMenu)
+{
+ systemContextMenu.Release();
+ UString folderPath = GetFsPath();
+
+ CMyComPtr<IShellFolder> desktopFolder;
+ RINOK(::SHGetDesktopFolder(&desktopFolder));
+ if (!desktopFolder)
+ {
+ // ShowMessage("Failed to get Desktop folder.");
+ return E_FAIL;
+ }
+
+ // Separate the file from the folder.
+
+
+ // Get a pidl for the folder the file
+ // is located in.
+ LPITEMIDLIST parentPidl;
+ DWORD eaten;
+ RINOK(desktopFolder->ParseDisplayName(
+ GetParent(), 0, (wchar_t *)(const wchar_t *)folderPath,
+ &eaten, &parentPidl, 0));
+
+ // Get an IShellFolder for the folder
+ // the file is located in.
+ CMyComPtr<IShellFolder> parentFolder;
+ RINOK(desktopFolder->BindToObject(parentPidl,
+ 0, IID_IShellFolder, (void**)&parentFolder));
+ if (!parentFolder)
+ {
+ // ShowMessage("Invalid file name.");
+ return E_FAIL;
+ }
+
+ // Get a pidl for the file itself.
+ CRecordVector<LPITEMIDLIST> pidls;
+ pidls.Reserve(operatedIndices.Size());
+ for (int i = 0; i < operatedIndices.Size(); i++)
+ {
+ LPITEMIDLIST pidl;
+ UString fileName = GetItemRelPath(operatedIndices[i]);
+ if (IsFSDrivesFolder())
+ fileName += L'\\';
+ RINOK(parentFolder->ParseDisplayName(GetParent(), 0,
+ (wchar_t *)(const wchar_t *)fileName, &eaten, &pidl, 0));
+ pidls.Add(pidl);
+ }
+
+ ITEMIDLIST temp;
+ if (pidls.Size() == 0)
+ {
+ temp.mkid.cb = 0;
+ /*
+ LPITEMIDLIST pidl;
+ HRESULT result = parentFolder->ParseDisplayName(GetParent(), 0,
+ L".\\", &eaten, &pidl, 0);
+ if (result != NOERROR)
+ return;
+ */
+ pidls.Add(&temp);
+ }
+
+ // Get the IContextMenu for the file.
+ CMyComPtr<IContextMenu> cm;
+ RINOK( parentFolder->GetUIObjectOf(GetParent(), pidls.Size(),
+ (LPCITEMIDLIST *)&pidls.Front(), IID_IContextMenu, 0, (void**)&cm));
+ if (!cm)
+ {
+ // ShowMessage("Unable to get context menu interface.");
+ return E_FAIL;
+ }
+ systemContextMenu = cm;
+ return S_OK;
+}
+
+void CPanel::CreateSystemMenu(HMENU menuSpec,
+ const CRecordVector<UINT32> &operatedIndices,
+ CMyComPtr<IContextMenu> &systemContextMenu)
+{
+ systemContextMenu.Release();
+
+ CreateShellContextMenu(operatedIndices, systemContextMenu);
+
+ if (systemContextMenu == 0)
+ return;
+
+ // Set up a CMINVOKECOMMANDINFO structure.
+ CMINVOKECOMMANDINFO ci;
+ ZeroMemory(&ci, sizeof(ci));
+ ci.cbSize = sizeof(CMINVOKECOMMANDINFO);
+ ci.hwnd = GetParent();
+
+ /*
+ if (Sender == GoBtn)
+ {
+ // Verbs that can be used are cut, paste,
+ // properties, delete, and so on.
+ String action;
+ if (CutRb->Checked)
+ action = "cut";
+ else if (CopyRb->Checked)
+ action = "copy";
+ else if (DeleteRb->Checked)
+ action = "delete";
+ else if (PropertiesRb->Checked)
+ action = "properties";
+
+ ci.lpVerb = action.c_str();
+ result = cm->InvokeCommand(&ci);
+ if (result)
+ ShowMessage(
+ "Error copying file to clipboard.");
+
+ }
+ else
+ */
+ {
+ // HMENU hMenu = CreatePopupMenu();
+ CMenu popupMenu;
+ // CMenuDestroyer menuDestroyer(popupMenu);
+ if(!popupMenu.CreatePopup())
+ throw 210503;
+
+ HMENU hMenu = popupMenu;
+
+ DWORD Flags = CMF_EXPLORE;
+ // Optionally the shell will show the extended
+ // context menu on some operating systems when
+ // the shift key is held down at the time the
+ // context menu is invoked. The following is
+ // commented out but you can uncommnent this
+ // line to show the extended context menu.
+ // Flags |= 0x00000080;
+ systemContextMenu->QueryContextMenu(hMenu, 0, kSystemStartMenuID, 0x7FFF, Flags);
+
+
+ {
+ CMenu menu;
+ menu.Attach(menuSpec);
+ CMenuItem menuItem;
+ menuItem.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID;
+ menuItem.fType = MFT_STRING;
+ menuItem.hSubMenu = popupMenu.Detach();
+ // menuDestroyer.Disable();
+ menuItem.StringValue = LangString(IDS_SYSTEM, 0x030202A0);
+ menu.InsertItem(0, true, menuItem);
+ }
+ /*
+ if (Cmd < 100 && Cmd != 0)
+ {
+ ci.lpVerb = MAKEINTRESOURCE(Cmd - 1);
+ ci.lpParameters = "";
+ ci.lpDirectory = "";
+ ci.nShow = SW_SHOWNORMAL;
+ cm->InvokeCommand(&ci);
+ }
+ // If Cmd is > 100 then it's one of our
+ // inserted menu items.
+ else
+ // Find the menu item.
+ for (int i = 0; i < popupMenu1->Items->Count; i++)
+ {
+ TMenuItem* menu = popupMenu1->Items->Items[i];
+ // Call its OnClick handler.
+ if (menu->Command == Cmd - 100)
+ menu->OnClick(this);
+ }
+ // Release the memory allocated for the menu.
+ DestroyMenu(hMenu);
+ */
+ }
+}
+
+void CPanel::CreateFileMenu(HMENU menuSpec)
+{
+ CreateFileMenu(menuSpec, _sevenZipContextMenu, _systemContextMenu, true);
+}
+
+void CPanel::CreateSevenZipMenu(HMENU menuSpec,
+ const CRecordVector<UINT32> &operatedIndices,
+ CMyComPtr<IContextMenu> &sevenZipContextMenu)
+{
+ sevenZipContextMenu.Release();
+
+ CMenu menu;
+ menu.Attach(menuSpec);
+ // CMenuDestroyer menuDestroyer(menu);
+ // menu.CreatePopup();
+
+ bool sevenZipMenuCreated = false;
+
+ CMyComPtr<IContextMenu> contextMenu;
+ if (contextMenu.CoCreateInstance(CLSID_CZipContextMenu, IID_IContextMenu) == S_OK)
+ {
+ CMyComPtr<IInitContextMenu> initContextMenu;
+ if (contextMenu.QueryInterface(IID_IInitContextMenu, &initContextMenu) != S_OK)
+ return;
+ UString currentFolderUnicode = _currentFolderPrefix;
+ UStringVector names;
+ int i;
+ for(i = 0; i < operatedIndices.Size(); i++)
+ names.Add(currentFolderUnicode + GetItemRelPath(operatedIndices[i]));
+ CRecordVector<const wchar_t *> namePointers;
+ for(i = 0; i < operatedIndices.Size(); i++)
+ namePointers.Add(names[i]);
+
+ // NFile::NDirectory::MySetCurrentDirectory(currentFolderUnicode);
+ if (initContextMenu->InitContextMenu(currentFolderUnicode, &namePointers.Front(),
+ operatedIndices.Size()) == S_OK)
+ {
+ HRESULT res = contextMenu->QueryContextMenu(menu, 0, kSevenZipStartMenuID,
+ kSystemStartMenuID - 1, 0);
+ sevenZipMenuCreated = (HRESULT_SEVERITY(res) == SEVERITY_SUCCESS);
+ if (sevenZipMenuCreated)
+ sevenZipContextMenu = contextMenu;
+ // int code = HRESULT_CODE(res);
+ // int nextItemID = code;
+ }
+ }
+}
+
+void CPanel::CreateFileMenu(HMENU menuSpec,
+ CMyComPtr<IContextMenu> &sevenZipContextMenu,
+ CMyComPtr<IContextMenu> &systemContextMenu,
+ bool programMenu)
+{
+ sevenZipContextMenu.Release();
+ systemContextMenu.Release();
+
+ CRecordVector<UINT32> operatedIndices;
+ GetOperatedItemIndices(operatedIndices);
+
+ CMenu menu;
+ menu.Attach(menuSpec);
+
+ CreateSevenZipMenu(menu, operatedIndices, sevenZipContextMenu);
+ if (g_App.ShowSystemMenu)
+ CreateSystemMenu(menu, operatedIndices, systemContextMenu);
+
+ if (menu.GetItemCount() > 0)
+ menu.AppendItem(MF_SEPARATOR, 0, (LPCTSTR)0);
+
+ LoadFileMenu(menu, menu.GetItemCount(), !operatedIndices.IsEmpty(), programMenu);
+}
+
+bool CPanel::InvokePluginCommand(int id)
+{
+ return InvokePluginCommand(id, _sevenZipContextMenu, _systemContextMenu);
+}
+
+bool CPanel::InvokePluginCommand(int id,
+ IContextMenu *sevenZipContextMenu, IContextMenu *systemContextMenu)
+{
+ UINT32 offset;
+ bool isSystemMenu = (id >= kSystemStartMenuID);
+ if (isSystemMenu)
+ offset = id - kSystemStartMenuID;
+ else
+ offset = id - kSevenZipStartMenuID;
+
+ CMINVOKECOMMANDINFOEX commandInfo;
+ commandInfo.cbSize = sizeof(commandInfo);
+ commandInfo.fMask = CMIC_MASK_UNICODE;
+ commandInfo.hwnd = GetParent();
+ commandInfo.lpVerb = (LPCSTR)(MAKEINTRESOURCE(offset));
+ commandInfo.lpParameters = NULL;
+ CSysString currentFolderSys = GetSystemString(_currentFolderPrefix);
+ commandInfo.lpDirectory = (LPCSTR)(LPCTSTR)(currentFolderSys);
+ commandInfo.nShow = SW_SHOW;
+ commandInfo.lpTitle = "";
+ commandInfo.lpVerbW = (LPCWSTR)(MAKEINTRESOURCEW(offset));
+ commandInfo.lpParameters = NULL;
+ UString currentFolderUnicode = _currentFolderPrefix;
+ commandInfo.lpDirectoryW = currentFolderUnicode;
+ commandInfo.lpTitleW = L"";
+ // commandInfo.ptInvoke.x = xPos;
+ // commandInfo.ptInvoke.y = yPos;
+ commandInfo.ptInvoke.x = 0;
+ commandInfo.ptInvoke.y = 0;
+ HRESULT result;
+ if (isSystemMenu)
+ result = systemContextMenu->InvokeCommand(LPCMINVOKECOMMANDINFO(&commandInfo));
+ else
+ result = sevenZipContextMenu->InvokeCommand(LPCMINVOKECOMMANDINFO(&commandInfo));
+ if (result == NOERROR)
+ {
+ KillSelection();
+ return true;
+ }
+ return false;
+}
+
+bool CPanel::OnContextMenu(HANDLE windowHandle, int xPos, int yPos)
+{
+ if (windowHandle != _listView)
+ return false;
+ /*
+ POINT point;
+ point.x = xPos;
+ point.y = yPos;
+ if (!_listView.ScreenToClient(&point))
+ return false;
+
+ LVHITTESTINFO info;
+ info.pt = point;
+ int index = _listView.HitTest(&info);
+ */
+
+ CRecordVector<UINT32> operatedIndices;
+ GetOperatedItemIndices(operatedIndices);
+
+ if (xPos < 0 || yPos < 0)
+ {
+ if (operatedIndices.Size() == 0)
+ {
+ xPos = 0;
+ yPos = 0;
+ }
+ else
+ {
+ int itemIndex = _listView.GetNextItem(-1, LVNI_FOCUSED);
+ if (itemIndex == -1)
+ return false;
+ RECT rect;
+ if (!_listView.GetItemRect(itemIndex, &rect, LVIR_ICON))
+ return false;
+ xPos = (rect.left + rect.right) / 2;
+ yPos = (rect.top + rect.bottom) / 2;
+ }
+ POINT point = {xPos, yPos};
+ _listView.ClientToScreen(&point);
+ xPos = point.x;
+ yPos = point.y;
+ }
+
+ CMenu menu;
+ CMenuDestroyer menuDestroyer(menu);
+ menu.CreatePopup();
+
+ CMyComPtr<IContextMenu> sevenZipContextMenu;
+ CMyComPtr<IContextMenu> systemContextMenu;
+ CreateFileMenu(menu, sevenZipContextMenu, systemContextMenu, false);
+
+ int result = menu.Track(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY,
+ xPos, yPos, _listView);
+
+ if (result == 0)
+ return true;
+
+ if (result >= kPluginMenuStartID)
+ {
+ InvokePluginCommand(result, sevenZipContextMenu, systemContextMenu);
+ return true;
+ }
+ if (ExecuteFileCommand(result))
+ return true;
+ return true;
+}
diff --git a/CPP/7zip/FileManager/PanelOperations.cpp b/CPP/7zip/FileManager/PanelOperations.cpp
new file mode 100755
index 00000000..66993f39
--- /dev/null
+++ b/CPP/7zip/FileManager/PanelOperations.cpp
@@ -0,0 +1,396 @@
+// PanelOperations.cpp
+
+#include "StdAfx.h"
+
+#include "resource.h"
+
+#include "Panel.h"
+
+#include "Common/StringConvert.h"
+#include "Common/DynamicBuffer.h"
+#include "Windows/FileDir.h"
+#include "Windows/ResourceString.h"
+#include "Windows/Thread.h"
+#include "Windows/COM.h"
+
+#include "Resource/ComboDialog/ComboDialog.h"
+
+#include "FSFolder.h"
+#include "LangUtils.h"
+#include "FormatUtils.h"
+
+#include "UpdateCallback100.h"
+
+using namespace NWindows;
+using namespace NFile;
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+struct CThreadDelete
+{
+ CMyComPtr<IFolderOperations> FolderOperations;
+ CRecordVector<UInt32> Indices;
+ CMyComPtr<IFolderArchiveUpdateCallback> UpdateCallback;
+ CUpdateCallback100Imp *UpdateCallbackSpec;
+ HRESULT Result;
+
+ DWORD Process()
+ {
+ NCOM::CComInitializer comInitializer;
+ UpdateCallbackSpec->ProgressDialog.WaitCreating();
+ Result = FolderOperations->Delete(&Indices.Front(), Indices.Size(), UpdateCallback);
+ UpdateCallbackSpec->ProgressDialog.MyClose();
+ return 0;
+ }
+
+ static DWORD WINAPI MyThreadFunction(void *param)
+ {
+ return ((CThreadDelete *)param)->Process();
+ }
+};
+
+#ifndef _UNICODE
+typedef int (WINAPI * SHFileOperationWP)(LPSHFILEOPSTRUCTW lpFileOp);
+#endif
+
+void CPanel::DeleteItems(bool toRecycleBin)
+{
+ CPanel::CDisableTimerProcessing disableTimerProcessing2(*this);
+ CRecordVector<UInt32> indices;
+ GetOperatedItemIndices(indices);
+ if (indices.IsEmpty())
+ return;
+ CSelectedState state;
+ SaveSelectedState(state);
+ bool useInternalDelete = false;
+ if (IsFSFolder() && toRecycleBin)
+ {
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ CDynamicBuffer<CHAR> buffer;
+ size_t size = 0;
+ for (int i = 0; i < indices.Size(); i++)
+ {
+ const AString path = GetSystemString(GetFsPath() + GetItemRelPath(indices[i]));
+ buffer.EnsureCapacity(size + path.Length() + 1);
+ memmove(((CHAR *)buffer) + size, (const CHAR *)path, (path.Length() + 1) * sizeof(CHAR));
+ size += path.Length() + 1;
+ }
+ buffer.EnsureCapacity(size + 1);
+ ((CHAR *)buffer)[size] = 0;
+ SHFILEOPSTRUCTA fo;
+ fo.hwnd = GetParent();
+ fo.wFunc = FO_DELETE;
+ fo.pFrom = (const CHAR *)buffer;
+ fo.pTo = 0;
+ fo.fFlags = 0;
+ if (toRecycleBin)
+ fo.fFlags |= FOF_ALLOWUNDO;
+ // fo.fFlags |= FOF_NOCONFIRMATION;
+ // fo.fFlags |= FOF_NOERRORUI;
+ // fo.fFlags |= FOF_SILENT;
+ // fo.fFlags |= FOF_WANTNUKEWARNING;
+ fo.fAnyOperationsAborted = FALSE;
+ fo.hNameMappings = 0;
+ fo.lpszProgressTitle = 0;
+ /* int res = */ ::SHFileOperationA(&fo);
+ }
+ else
+ #endif
+ {
+ CDynamicBuffer<WCHAR> buffer;
+ size_t size = 0;
+ int maxLen = 0;
+ for (int i = 0; i < indices.Size(); i++)
+ {
+ // L"\\\\?\\") doesn't work here.
+ const UString path = GetFsPath() + GetItemRelPath(indices[i]);
+ if (path.Length() > maxLen)
+ maxLen = path.Length();
+ buffer.EnsureCapacity(size + path.Length() + 1);
+ memmove(((WCHAR *)buffer) + size, (const WCHAR *)path, (path.Length() + 1) * sizeof(WCHAR));
+ size += path.Length() + 1;
+ }
+ buffer.EnsureCapacity(size + 1);
+ ((WCHAR *)buffer)[size] = 0;
+ if (maxLen >= MAX_PATH)
+ {
+ if (toRecycleBin)
+ {
+ MessageBoxMyError(L"You can't send file with long path to Recycle Bin");
+ return;
+ }
+ useInternalDelete = true;
+ }
+ else
+ {
+ SHFILEOPSTRUCTW fo;
+ fo.hwnd = GetParent();
+ fo.wFunc = FO_DELETE;
+ fo.pFrom = (const WCHAR *)buffer;
+ fo.pTo = 0;
+ fo.fFlags = 0;
+ if (toRecycleBin)
+ fo.fFlags |= FOF_ALLOWUNDO;
+ fo.fAnyOperationsAborted = FALSE;
+ fo.hNameMappings = 0;
+ fo.lpszProgressTitle = 0;
+ int res;
+ #ifdef _UNICODE
+ res = ::SHFileOperationW(&fo);
+ #else
+ SHFileOperationWP shFileOperationW = (SHFileOperationWP)
+ ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "SHFileOperationW");
+ if (shFileOperationW == 0)
+ return;
+ res = shFileOperationW(&fo);
+ #endif
+ }
+ }
+ /*
+ if (fo.fAnyOperationsAborted)
+ MessageBoxError(result, LangString(IDS_ERROR_DELETING, 0x03020217));
+ */
+ }
+ else
+ useInternalDelete = true;
+ if (useInternalDelete)
+ DeleteItemsInternal(indices);
+ RefreshListCtrl(state);
+}
+
+void CPanel::DeleteItemsInternal(CRecordVector<UInt32> &indices)
+{
+ CMyComPtr<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ {
+ MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
+ return;
+ }
+
+ UString title;
+ UString message;
+ if (indices.Size() == 1)
+ {
+ int index = indices[0];
+ const UString itemName = GetItemRelPath(index);
+ if (IsItemFolder(index))
+ {
+ title = LangString(IDS_CONFIRM_FOLDER_DELETE, 0x03020211);
+ message = MyFormatNew(IDS_WANT_TO_DELETE_FOLDER, 0x03020214, itemName);
+ }
+ else
+ {
+ title = LangString(IDS_CONFIRM_FILE_DELETE, 0x03020210);
+ message = MyFormatNew(IDS_WANT_TO_DELETE_FILE, 0x03020213, itemName);
+ }
+ }
+ else
+ {
+ title = LangString(IDS_CONFIRM_ITEMS_DELETE, 0x03020212);
+ message = MyFormatNew(IDS_WANT_TO_DELETE_ITEMS, 0x03020215,
+ NumberToString(indices.Size()));
+ }
+ if (::MessageBoxW(GetParent(), message, title, MB_OKCANCEL | MB_ICONQUESTION) != IDOK)
+ return;
+
+ CThreadDelete deleter;
+ deleter.UpdateCallbackSpec = new CUpdateCallback100Imp;
+ deleter.UpdateCallback = deleter.UpdateCallbackSpec;
+ deleter.UpdateCallbackSpec->Init(GetParent(), false, L"");
+
+ UString progressTitle = LangString(IDS_DELETING, 0x03020216);
+
+ deleter.UpdateCallbackSpec->ProgressDialog.MainWindow = _mainWindow;
+ deleter.UpdateCallbackSpec->ProgressDialog.MainTitle = LangString(IDS_APP_TITLE, 0x03000000);
+ deleter.UpdateCallbackSpec->ProgressDialog.MainAddTitle = progressTitle + UString(L" ");
+
+ deleter.FolderOperations = folderOperations;
+ deleter.Indices = indices;
+
+ CThread thread;
+ if (!thread.Create(CThreadDelete::MyThreadFunction, &deleter))
+ throw 271824;
+ deleter.UpdateCallbackSpec->StartProgressDialog(progressTitle);
+
+ HRESULT result = deleter.Result;
+ if (result != S_OK)
+ MessageBoxError(result, LangString(IDS_ERROR_DELETING, 0x03020217));
+}
+
+BOOL CPanel::OnBeginLabelEdit(LV_DISPINFOW * lpnmh)
+{
+ int realIndex = GetRealIndex(lpnmh->item);
+ if (realIndex == kParentIndex)
+ return TRUE;
+ CMyComPtr<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ return TRUE;
+ return FALSE;
+}
+
+BOOL CPanel::OnEndLabelEdit(LV_DISPINFOW * lpnmh)
+{
+ if (lpnmh->item.pszText == NULL)
+ return FALSE;
+ CMyComPtr<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ {
+ MessageBoxMyError(L"Renaming is not supported");
+ return FALSE;
+ }
+ const UString newName = lpnmh->item.pszText;
+ CPanel::CDisableTimerProcessing disableTimerProcessing2(*this);
+
+ SaveSelectedState(_selectedState);
+
+ int realIndex = GetRealIndex(lpnmh->item);
+ if (realIndex == kParentIndex)
+ return FALSE;
+ const UString prefix = GetItemPrefix(realIndex);
+ HRESULT result = folderOperations->Rename(realIndex, newName, 0);
+ if (result != S_OK)
+ {
+ MessageBoxError(result, LangString(IDS_ERROR_RENAMING, 0x03020221));
+ return FALSE;
+ }
+ // Can't use RefreshListCtrl here.
+ // RefreshListCtrlSaveFocused();
+ _selectedState.FocusedName = prefix + newName;
+ _selectedState.SelectFocused = true;
+
+ // We need clear all items to disable GetText before Reload:
+ // number of items can change.
+ // _listView.DeleteAllItems();
+ // But seems it can still call GetText (maybe for current item)
+ // so we can't delete items.
+
+ _dontShowMode = true;
+
+ PostMessage(kReLoadMessage);
+ return TRUE;
+}
+
+void CPanel::CreateFolder()
+{
+ CMyComPtr<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ {
+ MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
+ return;
+ }
+ CPanel::CDisableTimerProcessing disableTimerProcessing2(*this);
+ CSelectedState state;
+ SaveSelectedState(state);
+ CComboDialog comboDialog;
+ comboDialog.Title = LangString(IDS_CREATE_FOLDER, 0x03020230);
+ comboDialog.Static = LangString(IDS_CREATE_FOLDER_NAME, 0x03020231);
+ comboDialog.Value = LangString(IDS_CREATE_FOLDER_DEFAULT_NAME, /*0x03020232*/ (UInt32)-1);
+ if (comboDialog.Create(GetParent()) == IDCANCEL)
+ return;
+ UString newName = comboDialog.Value;
+ HRESULT result = folderOperations->CreateFolder(newName, 0);
+ if (result != S_OK)
+ {
+ MessageBoxError(result, LangString(IDS_CREATE_FOLDER_ERROR, 0x03020233));
+ return;
+ }
+ int pos = newName.Find(L'\\');
+ if (pos >= 0)
+ newName = newName.Left(pos);
+ if (!_mySelectMode)
+ state.SelectedNames.Clear();
+ state.FocusedName = newName;
+ state.SelectFocused = true;
+ RefreshListCtrl(state);
+}
+
+void CPanel::CreateFile()
+{
+ CMyComPtr<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ {
+ MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
+ return;
+ }
+ CPanel::CDisableTimerProcessing disableTimerProcessing2(*this);
+ CSelectedState state;
+ SaveSelectedState(state);
+ CComboDialog comboDialog;
+ comboDialog.Title = LangString(IDS_CREATE_FILE, 0x03020240);
+ comboDialog.Static = LangString(IDS_CREATE_FILE_NAME, 0x03020241);
+ comboDialog.Value = LangString(IDS_CREATE_FILE_DEFAULT_NAME, /*0x03020242*/ (UInt32)-1);
+ if (comboDialog.Create(GetParent()) == IDCANCEL)
+ return;
+ UString newName = comboDialog.Value;
+ HRESULT result = folderOperations->CreateFile(newName, 0);
+ if (result != S_OK)
+ {
+ MessageBoxError(result, LangString(IDS_CREATE_FILE_ERROR, 0x03020243));
+ return;
+ }
+ int pos = newName.Find(L'\\');
+ if (pos >= 0)
+ newName = newName.Left(pos);
+ if (!_mySelectMode)
+ state.SelectedNames.Clear();
+ state.FocusedName = newName;
+ state.SelectFocused = true;
+ RefreshListCtrl(state);
+}
+
+void CPanel::RenameFile()
+{
+ int index = _listView.GetFocusedItem();
+ if (index >= 0)
+ _listView.EditLabel(index);
+}
+
+void CPanel::ChangeComment()
+{
+ CPanel::CDisableTimerProcessing disableTimerProcessing2(*this);
+ int index = _listView.GetFocusedItem();
+ if (index < 0)
+ return;
+ int realIndex = GetRealItemIndex(index);
+ if (realIndex == kParentIndex)
+ return;
+ CSelectedState state;
+ SaveSelectedState(state);
+ CMyComPtr<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ {
+ MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
+ return;
+ }
+
+ UString comment;
+ {
+ NCOM::CPropVariant propVariant;
+ if (_folder->GetProperty(realIndex, kpidComment, &propVariant) != S_OK)
+ return;
+ if (propVariant.vt == VT_BSTR)
+ comment = propVariant.bstrVal;
+ else if (propVariant.vt != VT_EMPTY)
+ return;
+ }
+ UString name = GetItemRelPath(realIndex);
+ CComboDialog comboDialog;
+ comboDialog.Title = name + L" " + LangString(IDS_COMMENT, 0x03020290);
+ comboDialog.Value = comment;
+ comboDialog.Static = LangString(IDS_COMMENT2, 0x03020291);
+ if (comboDialog.Create(GetParent()) == IDCANCEL)
+ return;
+ NCOM::CPropVariant propVariant = comboDialog.Value;
+
+ HRESULT result = folderOperations->SetProperty(realIndex, kpidComment, &propVariant, NULL);
+ if (result != S_OK)
+ {
+ MessageBoxError(result, L"Set Comment Error");
+ }
+ RefreshListCtrl(state);
+}
+
diff --git a/CPP/7zip/FileManager/PanelSelect.cpp b/CPP/7zip/FileManager/PanelSelect.cpp
new file mode 100755
index 00000000..e769195f
--- /dev/null
+++ b/CPP/7zip/FileManager/PanelSelect.cpp
@@ -0,0 +1,297 @@
+// PanelSelect.cpp
+
+#include "StdAfx.h"
+
+#include "resource.h"
+
+#include "Common/StringConvert.h"
+#include "Common/Wildcard.h"
+
+#include "Panel.h"
+
+#include "Resource/ComboDialog/ComboDialog.h"
+
+#include "LangUtils.h"
+
+void CPanel::OnShiftSelectMessage()
+{
+ if (!_mySelectMode)
+ return;
+ int focusedItem = _listView.GetFocusedItem();
+ if (focusedItem < 0)
+ return;
+ if (!_selectionIsDefined)
+ return;
+ int startItem = MyMin(focusedItem, _prevFocusedItem);
+ int finishItem = MyMax(focusedItem, _prevFocusedItem);
+ for (int i = 0; i < _listView.GetItemCount(); i++)
+ {
+ int realIndex = GetRealItemIndex(i);
+ if (realIndex == kParentIndex)
+ continue;
+ if (i >= startItem && i <= finishItem)
+ if (_selectedStatusVector[realIndex] != _selectMark)
+ {
+ _selectedStatusVector[realIndex] = _selectMark;
+ _listView.RedrawItem(i);
+ }
+ }
+ _prevFocusedItem = focusedItem;
+}
+
+void CPanel::OnArrowWithShift()
+{
+ if (!_mySelectMode)
+ return;
+ int focusedItem = _listView.GetFocusedItem();
+ if (focusedItem < 0)
+ return;
+ int realIndex = GetRealItemIndex(focusedItem);
+ if (_selectionIsDefined)
+ {
+ if (realIndex != kParentIndex)
+ _selectedStatusVector[realIndex] = _selectMark;
+ }
+ else
+ {
+ if (realIndex == kParentIndex)
+ {
+ _selectionIsDefined = true;
+ _selectMark = true;
+ }
+ else
+ {
+ _selectionIsDefined = true;
+ _selectMark = !_selectedStatusVector[realIndex];
+ _selectedStatusVector[realIndex] = _selectMark;
+ }
+ }
+ _prevFocusedItem = focusedItem;
+ PostMessage(kShiftSelectMessage);
+ _listView.RedrawItem(focusedItem);
+}
+
+void CPanel::OnInsert()
+{
+ /*
+ const int kState = CDIS_MARKED; // LVIS_DROPHILITED;
+ UINT state = (_listView.GetItemState(focusedItem, LVIS_CUT) == 0) ?
+ LVIS_CUT : 0;
+ _listView.SetItemState(focusedItem, state, LVIS_CUT);
+ // _listView.SetItemState(focusedItem, LVIS_SELECTED, LVIS_SELECTED);
+
+ */
+ int focusedItem = _listView.GetFocusedItem();
+ if (focusedItem < 0)
+ return;
+ int realIndex = GetRealItemIndex(focusedItem);
+ bool isSelected = !_selectedStatusVector[realIndex];
+ if (realIndex != kParentIndex)
+ _selectedStatusVector[realIndex] = isSelected;
+
+ if (!_mySelectMode)
+ _listView.SetItemState(focusedItem, isSelected ? LVIS_SELECTED: 0, LVIS_SELECTED);
+
+ _listView.RedrawItem(focusedItem);
+
+ int nextIndex = focusedItem + 1;
+ if (nextIndex < _listView.GetItemCount())
+ {
+ _listView.SetItemState(nextIndex, LVIS_FOCUSED | LVIS_SELECTED,
+ LVIS_FOCUSED | LVIS_SELECTED);
+ _listView.EnsureVisible(nextIndex, false);
+ }
+}
+
+/*
+void CPanel::OnUpWithShift()
+{
+ int focusedItem = _listView.GetFocusedItem();
+ if (focusedItem < 0)
+ return;
+ int index = GetRealItemIndex(focusedItem);
+ _selectedStatusVector[index] = !_selectedStatusVector[index];
+ _listView.RedrawItem(index);
+}
+
+void CPanel::OnDownWithShift()
+{
+ int focusedItem = _listView.GetFocusedItem();
+ if (focusedItem < 0)
+ return;
+ int index = GetRealItemIndex(focusedItem);
+ _selectedStatusVector[index] = !_selectedStatusVector[index];
+ _listView.RedrawItem(index);
+}
+*/
+
+void CPanel::UpdateSelection()
+{
+ if (!_mySelectMode)
+ {
+ bool enableTemp = _enableItemChangeNotify;
+ _enableItemChangeNotify = false;
+ int numItems = _listView.GetItemCount();
+ for (int i = 0; i < numItems; i++)
+ {
+ int realIndex = GetRealItemIndex(i);
+ if (realIndex != kParentIndex)
+ {
+ UINT value = 0;
+ value = _selectedStatusVector[realIndex] ? LVIS_SELECTED: 0;
+ _listView.SetItemState(i, value, LVIS_SELECTED);
+ }
+ }
+ _enableItemChangeNotify = enableTemp;
+ }
+ _listView.RedrawAllItems();
+}
+
+
+void CPanel::SelectSpec(bool selectMode)
+{
+ CComboDialog comboDialog;
+ comboDialog.Title = selectMode ?
+ LangString(IDS_SELECT, 0x03020250):
+ LangString(IDS_DESELECT, 0x03020251);
+ comboDialog.Static = LangString(IDS_SELECT_MASK, 0x03020252);
+ comboDialog.Value = L"*";
+ if (comboDialog.Create(GetParent()) == IDCANCEL)
+ return;
+ const UString &mask = comboDialog.Value;
+ for (int i = 0; i < _selectedStatusVector.Size(); i++)
+ if (CompareWildCardWithName(mask, GetItemName(i)))
+ _selectedStatusVector[i] = selectMode;
+ UpdateSelection();
+}
+
+void CPanel::SelectByType(bool selectMode)
+{
+ int focusedItem = _listView.GetFocusedItem();
+ if (focusedItem < 0)
+ return;
+ int realIndex = GetRealItemIndex(focusedItem);
+ UString name = GetItemName(realIndex);
+ bool isItemFolder = IsItemFolder(realIndex);
+
+ /*
+ UINT32 numItems;
+ _folder->GetNumberOfItems(&numItems);
+ if ((UInt32)_selectedStatusVector.Size() != numItems)
+ throw 11111;
+ */
+
+ if (isItemFolder)
+ {
+ for (int i = 0; i < _selectedStatusVector.Size(); i++)
+ if (IsItemFolder(i) == isItemFolder)
+ _selectedStatusVector[i] = selectMode;
+ }
+ else
+ {
+ int pos = name.ReverseFind(L'.');
+ if (pos < 0)
+ {
+ for (int i = 0; i < _selectedStatusVector.Size(); i++)
+ if (IsItemFolder(i) == isItemFolder && GetItemName(i).ReverseFind(L'.') < 0)
+ _selectedStatusVector[i] = selectMode;
+ }
+ else
+ {
+ UString mask = UString(L'*') + name.Mid(pos);
+ for (int i = 0; i < _selectedStatusVector.Size(); i++)
+ if (IsItemFolder(i) == isItemFolder && CompareWildCardWithName(mask, GetItemName(i)))
+ _selectedStatusVector[i] = selectMode;
+ }
+ }
+ UpdateSelection();
+}
+
+void CPanel::SelectAll(bool selectMode)
+{
+ for (int i = 0; i < _selectedStatusVector.Size(); i++)
+ _selectedStatusVector[i] = selectMode;
+ UpdateSelection();
+}
+
+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();
+}
+
+void CPanel::KillSelection()
+{
+ SelectAll(false);
+ if (!_mySelectMode)
+ {
+ int focused = _listView.GetFocusedItem();
+ if (focused >= 0)
+ _listView.SetItemState(focused, LVIS_SELECTED, LVIS_SELECTED);
+ }
+}
+
+void CPanel::OnLeftClick(LPNMITEMACTIVATE itemActivate)
+{
+ if(itemActivate->hdr.hwndFrom != HWND(_listView))
+ return;
+ // It will be work only for Version 4.71 (IE 4);
+ int indexInList = itemActivate->iItem;
+ if (indexInList < 0)
+ return;
+ if ((itemActivate->uKeyFlags & LVKF_SHIFT) != 0)
+ {
+ // int focusedIndex = _listView.GetFocusedItem();
+ int focusedIndex = _startGroupSelect;
+ if (focusedIndex < 0)
+ return;
+ int startItem = MyMin(focusedIndex, indexInList);
+ int finishItem = MyMax(focusedIndex, indexInList);
+ for (int i = 0; i < _selectedStatusVector.Size(); i++)
+ {
+ int realIndex = GetRealItemIndex(i);
+ if (realIndex == kParentIndex)
+ continue;
+ bool selected = (i >= startItem && i <= finishItem);
+ if (_selectedStatusVector[realIndex] != selected)
+ {
+ _selectedStatusVector[realIndex] = selected;
+ _listView.RedrawItem(i);
+ }
+ }
+ }
+ else
+ {
+ _startGroupSelect = indexInList;
+ if ((itemActivate->uKeyFlags & LVKF_CONTROL) != 0)
+ {
+ int realIndex = GetRealItemIndex(indexInList);
+ if (realIndex != kParentIndex)
+ {
+ _selectedStatusVector[realIndex] = !_selectedStatusVector[realIndex];
+ _listView.RedrawItem(indexInList);
+ }
+ }
+ }
+ return;
+}
+
diff --git a/CPP/7zip/FileManager/PanelSort.cpp b/CPP/7zip/FileManager/PanelSort.cpp
new file mode 100755
index 00000000..fd9027b9
--- /dev/null
+++ b/CPP/7zip/FileManager/PanelSort.cpp
@@ -0,0 +1,163 @@
+// PanelSort.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/PropVariant.h"
+
+#include "../PropID.h"
+
+#include "Panel.h"
+
+using namespace NWindows;
+
+static UString GetExtension(const UString &name)
+{
+ int dotPos = name.ReverseFind(L'.');
+ if (dotPos < 0)
+ return UString();
+ return name.Mid(dotPos);
+}
+
+int CALLBACK CompareItems2(LPARAM lParam1, LPARAM lParam2, LPARAM lpData)
+{
+ if(lpData == NULL)
+ return 0;
+ CPanel *panel = (CPanel*)lpData;
+
+ switch(panel->_sortID)
+ {
+ // if (panel->_sortIndex == 0)
+ case kpidName:
+ {
+ const UString name1 = panel->GetItemName((int)lParam1);
+ const UString name2 = panel->GetItemName((int)lParam2);
+ int res = name1.CompareNoCase(name2);
+ /*
+ if (res != 0 || !panel->_flatMode)
+ return res;
+ const UString prefix1 = panel->GetItemPrefix(lParam1);
+ const UString prefix2 = panel->GetItemPrefix(lParam2);
+ return res = prefix1.CompareNoCase(prefix2);
+ */
+ return res;
+ }
+ case kpidNoProperty:
+ {
+ return MyCompare(lParam1, lParam2);
+ }
+ case kpidExtension:
+ {
+ const UString ext1 = GetExtension(panel->GetItemName((int)lParam1));
+ const UString ext2 = GetExtension(panel->GetItemName((int)lParam2));
+ return ext1.CompareNoCase(ext2);
+ }
+ }
+ /*
+ if (panel->_sortIndex == 1)
+ return MyCompare(file1.Size, file2.Size);
+ return ::CompareFileTime(&file1.LastWriteTime, &file2.LastWriteTime);
+ */
+
+ // PROPID propID = panel->_properties[panel->_sortIndex].ID;
+ PROPID propID = panel->_sortID;
+
+ NCOM::CPropVariant propVariant1, propVariant2;
+ // Name must be first property
+ panel->_folder->GetProperty((UINT32)lParam1, propID, &propVariant1);
+ panel->_folder->GetProperty((UINT32)lParam2, propID, &propVariant2);
+ if(propVariant1.vt != propVariant2.vt)
+ return 0; // It means some BUG
+ if (propVariant1.vt == VT_BSTR)
+ {
+ return _wcsicmp(propVariant1.bstrVal, propVariant2.bstrVal);
+ }
+ return propVariant1.Compare(propVariant2);
+ // return 0;
+}
+
+int CALLBACK CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData)
+{
+ if(lpData == NULL)
+ return 0;
+ if (lParam1 == kParentIndex)
+ return -1;
+ if (lParam2 == kParentIndex)
+ return 1;
+
+ CPanel *panel = (CPanel*)lpData;
+
+ bool isDirectory1 = panel->IsItemFolder((int)lParam1);
+ bool isDirectory2 = panel->IsItemFolder((int)lParam2);
+
+ if(isDirectory1 && (!isDirectory2))
+ return -1;
+ if((!isDirectory1) && isDirectory2)
+ return 1;
+
+ int result = CompareItems2(lParam1, lParam2, lpData);
+ return panel->_ascending ? result: (-result);
+}
+
+
+/*
+void CPanel::SortItems(int index)
+{
+ if(index == _sortIndex)
+ _ascending = !_ascending;
+ else
+ {
+ _sortIndex = index;
+ _ascending = true;
+ switch (_properties[_sortIndex].ID)
+ {
+ case kpidSize:
+ case kpidPackedSize:
+ case kpidCreationTime:
+ case kpidLastAccessTime:
+ case kpidLastWriteTime:
+ _ascending = false;
+ break;
+ }
+ }
+ _listView.SortItems(CompareItems, (LPARAM)this);
+ _listView.EnsureVisible(_listView.GetFocusedItem(), false);
+}
+void CPanel::SortItemsWithPropID(PROPID propID)
+{
+ int index = _properties.FindItemWithID(propID);
+ if (index >= 0)
+ SortItems(index);
+}
+*/
+void CPanel::SortItemsWithPropID(PROPID propID)
+{
+ if(propID == _sortID)
+ _ascending = !_ascending;
+ else
+ {
+ _sortID = propID;
+ _ascending = true;
+ switch (propID)
+ {
+ case kpidSize:
+ case kpidPackedSize:
+ case kpidCreationTime:
+ case kpidLastAccessTime:
+ case kpidLastWriteTime:
+ _ascending = false;
+ break;
+ }
+ }
+ _listView.SortItems(CompareItems, (LPARAM)this);
+ _listView.EnsureVisible(_listView.GetFocusedItem(), false);
+}
+
+
+void CPanel::OnColumnClick(LPNMLISTVIEW info)
+{
+ /*
+ int index = _properties.FindItemWithID(_visibleProperties[info->iSubItem].ID);
+ SortItems(index);
+ */
+ SortItemsWithPropID(_visibleProperties[info->iSubItem].ID);
+}
diff --git a/CPP/7zip/FileManager/PanelSplitFile.cpp b/CPP/7zip/FileManager/PanelSplitFile.cpp
new file mode 100755
index 00000000..8e095628
--- /dev/null
+++ b/CPP/7zip/FileManager/PanelSplitFile.cpp
@@ -0,0 +1,477 @@
+// PanelSplitFile.cpp
+
+#include "StdAfx.h"
+
+#include "resource.h"
+
+#include "Common/Alloc.h"
+#include "Common/Types.h"
+#include "Common/IntToString.h"
+
+#include "Windows/COM.h"
+#include "Windows/FileIO.h"
+#include "Windows/FileFind.h"
+#include "Windows/Thread.h"
+#include "Resource/ProgressDialog2/ProgressDialog.h"
+#include "Resource/SplitDialog/SplitDialog.h"
+#include "Resource/CopyDialog/CopyDialog.h"
+
+#include "../UI/Resource/Extract/resource.h"
+
+#include "SplitUtils.h"
+#include "App.h"
+#include "FormatUtils.h"
+#include "LangUtils.h"
+
+using namespace NWindows;
+
+class CMyBuffer
+{
+ void *_data;
+public:
+ CMyBuffer(): _data(0) {}
+ operator void *() { return _data; }
+ bool Allocate(size_t size)
+ {
+ if (_data != 0)
+ return false;
+ _data = ::MidAlloc(size);
+ return _data != 0;
+ }
+ ~CMyBuffer() { ::MidFree(_data); }
+};
+
+struct CVolSeqName
+{
+ UString UnchangedPart;
+ UString ChangedPart;
+ CVolSeqName(): ChangedPart(L"000") {};
+
+ bool ParseName(const UString &name)
+ {
+ if (name.Right(2) != L"01")
+ return false;
+ int numLetters = 2;
+ while (numLetters < name.Length())
+ {
+ if (name[name.Length() - numLetters - 1] != '0')
+ break;
+ numLetters++;
+ }
+ UnchangedPart = name.Left(name.Length() - numLetters);
+ ChangedPart = name.Right(numLetters);
+ return true;
+ }
+
+ UString GetNextName()
+ {
+ UString newName;
+ int i;
+ int numLetters = ChangedPart.Length();
+ for (i = numLetters - 1; i >= 0; i--)
+ {
+ wchar_t c = ChangedPart[i];
+ if (c == L'9')
+ {
+ c = L'0';
+ newName = c + newName;
+ if (i == 0)
+ newName = UString(L'1') + newName;
+ continue;
+ }
+ c++;
+ newName = c + newName;
+ i--;
+ for (; i >= 0; i--)
+ newName = ChangedPart[i] + newName;
+ break;
+ }
+ ChangedPart = newName;
+ return UnchangedPart + ChangedPart;
+ }
+};
+
+static const UInt32 kBufSize = (1 << 20);
+
+struct CThreadSplit
+{
+ // HRESULT Result;
+ // CPanel *Panel;
+ CProgressDialog *ProgressDialog;
+ UString FilePath;
+ UString VolBasePath;
+ CRecordVector<UInt64> VolumeSizes;
+ UString Error;
+
+ void Process2()
+ {
+ // NCOM::CComInitializer comInitializer;
+ ProgressDialog->WaitCreating();
+ NFile::NIO::CInFile inFile;
+ if (!inFile.Open(FilePath))
+ throw L"Can not open file";
+ NFile::NIO::COutFile outFile;
+ CMyBuffer bufferObject;
+ if (!bufferObject.Allocate(kBufSize))
+ throw L"Can not allocate buffer";
+ Byte *buffer = (Byte *)(void *)bufferObject;
+ UInt64 curVolSize = 0;
+ CVolSeqName seqName;
+ UInt64 length;
+ if (!inFile.GetLength(length))
+ throw "error";
+
+ ProgressDialog->ProgressSynch.SetProgress(length, 0);
+ UInt64 pos = 0;
+
+ int volIndex = 0;
+
+ for (;;)
+ {
+ UInt64 volSize;
+ if (volIndex < VolumeSizes.Size())
+ volSize = VolumeSizes[volIndex];
+ else
+ volSize = VolumeSizes.Back();
+
+ UInt32 needSize = (UInt32)(MyMin((UInt64)kBufSize, volSize - curVolSize));
+ UInt32 processedSize;
+ if (!inFile.Read(buffer, needSize, processedSize))
+ throw L"Can not read input file";
+ if (processedSize == 0)
+ break;
+ needSize = processedSize;
+ if (curVolSize == 0)
+ {
+ UString name = VolBasePath;
+ name += L".";
+ name += seqName.GetNextName();
+ if (!outFile.Create(name, false))
+ throw L"Can not create output file";
+ ProgressDialog->ProgressSynch.SetCurrentFileName(name);
+ }
+ if (!outFile.Write(buffer, needSize, processedSize))
+ throw L"Can not write output file";
+ if (needSize != processedSize)
+ throw L"Can not write output file";
+ curVolSize += processedSize;
+ if (curVolSize == volSize)
+ {
+ outFile.Close();
+ if (volIndex < VolumeSizes.Size())
+ volIndex++;
+ curVolSize = 0;
+ }
+ pos += processedSize;
+ HRESULT res = ProgressDialog->ProgressSynch.SetPosAndCheckPaused(pos);
+ if (res != S_OK)
+ return;
+ }
+ }
+ DWORD Process()
+ {
+ try { Process2(); }
+ catch(const wchar_t *s) { Error = s; }
+ catch(...) { Error = L"Error"; }
+ ProgressDialog->MyClose();
+ return 0;
+ }
+
+ static DWORD WINAPI MyThreadFunction(void *param)
+ {
+ return ((CThreadSplit *)param)->Process();
+ }
+};
+
+void CApp::Split()
+{
+ int srcPanelIndex = GetFocusedPanelIndex();
+ CPanel &srcPanel = Panels[srcPanelIndex];
+ if (!srcPanel.IsFSFolder())
+ {
+ srcPanel.MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
+ return;
+ }
+ CRecordVector<UInt32> indices;
+ srcPanel.GetOperatedItemIndices(indices);
+ if (indices.IsEmpty())
+ return;
+ if (indices.Size() != 1)
+ {
+ srcPanel.MessageBox(L"Select one file");
+ return;
+ }
+ int index = indices[0];
+ if (srcPanel.IsItemFolder(index))
+ {
+ srcPanel.MessageBox(L"Select one file");
+ return;
+ }
+ const UString itemName = srcPanel.GetItemName(index);
+
+ UString srcPath = srcPanel._currentFolderPrefix + srcPanel.GetItemPrefix(index);
+ UString path = srcPath;
+ int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex);
+ CPanel &destPanel = Panels[destPanelIndex];
+ if (NumPanels > 1)
+ if (destPanel.IsFSFolder())
+ path = destPanel._currentFolderPrefix;
+ CSplitDialog splitDialog;
+ splitDialog.FilePath = srcPanel.GetItemRelPath(index);
+ splitDialog.Path = path;
+ if (splitDialog.Create(srcPanel.GetParent()) == IDCANCEL)
+ return;
+
+ NFile::NFind::CFileInfoW fileInfo;
+ if (!NFile::NFind::FindFile(srcPath + itemName, fileInfo))
+ {
+ srcPanel.MessageBoxMyError(L"Can not find file");
+ return;
+ }
+ if (fileInfo.Size <= splitDialog.VolumeSizes.Front())
+ {
+ srcPanel.MessageBoxMyError(LangString(IDS_SPLIT_VOL_MUST_BE_SMALLER, 0x03020522));
+ return;
+ }
+ const UInt64 numVolumes = GetNumberOfVolumes(fileInfo.Size, splitDialog.VolumeSizes);
+ if (numVolumes >= 100)
+ {
+ wchar_t s[32];
+ ConvertUInt64ToString(numVolumes, s);
+ if (::MessageBoxW(srcPanel, MyFormatNew(IDS_SPLIT_CONFIRM_MESSAGE, 0x03020521, s),
+ LangString(IDS_SPLIT_CONFIRM_TITLE, 0x03020520),
+ MB_YESNOCANCEL | MB_ICONQUESTION | MB_TASKMODAL) != IDYES)
+ return;
+ }
+
+ path = splitDialog.Path;
+ NFile::NName::NormalizeDirPathPrefix(path);
+ if (!NFile::NDirectory::CreateComplexDirectory(path))
+ {
+ srcPanel.MessageBoxMyError(MyFormatNew(IDS_CANNOT_CREATE_FOLDER, 0x02000603, path));
+ return;
+ }
+
+ CThreadSplit spliter;
+ // spliter.Panel = this;
+
+ CProgressDialog progressDialog;
+ spliter.ProgressDialog = &progressDialog;
+
+ UString progressWindowTitle = LangString(IDS_APP_TITLE, 0x03000000);
+ UString title = LangString(IDS_SPLITTING, 0x03020510);
+
+ progressDialog.MainWindow = _window;
+ progressDialog.MainTitle = progressWindowTitle;
+ progressDialog.MainAddTitle = title + UString(L" ");
+ progressDialog.ProgressSynch.SetTitleFileName(itemName);
+
+
+ spliter.FilePath = srcPath + itemName;
+ spliter.VolBasePath = path + itemName;
+ spliter.VolumeSizes = splitDialog.VolumeSizes;
+
+ // if (splitDialog.VolumeSizes.Size() == 0) return;
+
+ // CPanel::CDisableTimerProcessing disableTimerProcessing1(srcPanel);
+ // CPanel::CDisableTimerProcessing disableTimerProcessing2(destPanel);
+
+ CThread thread;
+ if (!thread.Create(CThreadSplit::MyThreadFunction, &spliter))
+ throw 271824;
+ progressDialog.Create(title, _window);
+
+ if (!spliter.Error.IsEmpty())
+ srcPanel.MessageBoxMyError(spliter.Error);
+ // disableTimerProcessing1.Restore();
+ // disableTimerProcessing2.Restore();
+ // srcPanel.SetFocusToList();
+ // srcPanel.RefreshListCtrlSaveFocused();
+}
+
+
+struct CThreadCombine
+{
+ CProgressDialog *ProgressDialog;
+ UString InputDirPrefix;
+ UString FirstVolumeName;
+ UString OutputDirPrefix;
+ UString Error;
+
+ void Process2()
+ {
+ // NCOM::CComInitializer comInitializer;
+ ProgressDialog->WaitCreating();
+
+ CVolSeqName volSeqName;
+ if (!volSeqName.ParseName(FirstVolumeName))
+ throw L"Can not detect file as splitted file";
+
+ UString nextName = InputDirPrefix + FirstVolumeName;
+ UInt64 totalSize = 0;
+ for (;;)
+ {
+ NFile::NFind::CFileInfoW fileInfo;
+ if (!NFile::NFind::FindFile(nextName, fileInfo))
+ break;
+ if (fileInfo.IsDirectory())
+ break;
+ totalSize += fileInfo.Size;
+ nextName = InputDirPrefix + volSeqName.GetNextName();
+ }
+ if (totalSize == 0)
+ throw L"no data";
+ ProgressDialog->ProgressSynch.SetProgress(totalSize, 0);
+
+ if (!volSeqName.ParseName(FirstVolumeName))
+ throw L"Can not detect file as splitted file";
+
+ UString outName = volSeqName.UnchangedPart;
+ while(!outName.IsEmpty())
+ {
+ int lastIndex = outName.Length() - 1;
+ if (outName[lastIndex] != L'.')
+ break;
+ outName.Delete(lastIndex);
+ }
+ if (outName.IsEmpty())
+ outName = L"file";
+ NFile::NIO::COutFile outFile;
+ if (!outFile.Create(OutputDirPrefix + outName, false))
+ throw L"Can create open output file";
+
+ NFile::NIO::CInFile inFile;
+ CMyBuffer bufferObject;
+ if (!bufferObject.Allocate(kBufSize))
+ throw L"Can not allocate buffer";
+ Byte *buffer = (Byte *)(void *)bufferObject;
+ UInt64 pos = 0;
+ nextName = InputDirPrefix + FirstVolumeName;
+ bool needOpen = true;
+ for (;;)
+ {
+ if (needOpen)
+ {
+ NFile::NFind::CFileInfoW fileInfo;
+ if (!NFile::NFind::FindFile(nextName, fileInfo))
+ break;
+ if (fileInfo.IsDirectory())
+ break;
+ if (!inFile.Open(nextName))
+ throw L"Can not open file";
+ ProgressDialog->ProgressSynch.SetCurrentFileName(fileInfo.Name);
+ nextName = InputDirPrefix + volSeqName.GetNextName();
+ needOpen = false;
+ }
+ UInt32 processedSize;
+ if (!inFile.Read(buffer, kBufSize, processedSize))
+ throw L"Can not read input file";
+ if (processedSize == 0)
+ {
+ needOpen = true;
+ continue;
+ }
+ UInt32 needSize = processedSize;
+ if (!outFile.Write(buffer, needSize, processedSize))
+ throw L"Can not write output file";
+ if (needSize != processedSize)
+ throw L"Can not write output file";
+ pos += processedSize;
+ HRESULT res = ProgressDialog->ProgressSynch.SetPosAndCheckPaused(pos);
+ if (res != S_OK)
+ return;
+ }
+ }
+ DWORD Process()
+ {
+ try { Process2(); }
+ catch(const wchar_t *s) { Error = s; }
+ catch(...) { Error = L"Error";}
+ ProgressDialog->MyClose();
+ return 0;
+ }
+
+ static DWORD WINAPI MyThreadFunction(void *param)
+ {
+ return ((CThreadCombine *)param)->Process();
+ }
+};
+
+void CApp::Combine()
+{
+ int srcPanelIndex = GetFocusedPanelIndex();
+ CPanel &srcPanel = Panels[srcPanelIndex];
+ if (!srcPanel.IsFSFolder())
+ {
+ srcPanel.MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
+ return;
+ }
+ CRecordVector<UInt32> indices;
+ srcPanel.GetOperatedItemIndices(indices);
+ if (indices.IsEmpty())
+ return;
+ int index = indices[0];
+ if (indices.Size() != 1 || srcPanel.IsItemFolder(index))
+ {
+ srcPanel.MessageBox(LangString(IDS_COMBINE_SELECT_ONE_FILE, 0x03020620));
+ return;
+ }
+ const UString itemName = srcPanel.GetItemName(index);
+
+ UString srcPath = srcPanel._currentFolderPrefix + srcPanel.GetItemPrefix(index);
+ UString path = srcPath;
+ int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex);
+ CPanel &destPanel = Panels[destPanelIndex];
+ if (NumPanels > 1)
+ if (destPanel.IsFSFolder())
+ path = destPanel._currentFolderPrefix;
+ CCopyDialog copyDialog;
+ copyDialog.Value = path;
+ copyDialog.Title = LangString(IDS_COMBINE, 0x03020600);
+ copyDialog.Title += ' ';
+ copyDialog.Title += srcPanel.GetItemRelPath(index);
+
+ copyDialog.Static = LangString(IDS_COMBINE_TO, 0x03020601);;
+ if (copyDialog.Create(srcPanel.GetParent()) == IDCANCEL)
+ return;
+
+ CThreadCombine combiner;
+ // combiner.Panel = this;
+
+ CProgressDialog progressDialog;
+ combiner.ProgressDialog = &progressDialog;
+
+ UString progressWindowTitle = LangString(IDS_APP_TITLE, 0x03000000);
+ UString title = LangString(IDS_COMBINING, 0x03020610);
+
+ progressDialog.MainWindow = _window;
+ progressDialog.MainTitle = progressWindowTitle;
+ progressDialog.MainAddTitle = title + UString(L" ");
+
+ path = copyDialog.Value;
+ NFile::NName::NormalizeDirPathPrefix(path);
+ if (!NFile::NDirectory::CreateComplexDirectory(path))
+ {
+ srcPanel.MessageBoxMyError(MyFormatNew(IDS_CANNOT_CREATE_FOLDER, 0x02000603, path));
+ return;
+ }
+
+ combiner.InputDirPrefix = srcPath;
+ combiner.FirstVolumeName = itemName;
+ combiner.OutputDirPrefix = path;
+
+ // CPanel::CDisableTimerProcessing disableTimerProcessing1(srcPanel);
+ // CPanel::CDisableTimerProcessing disableTimerProcessing2(destPanel);
+
+ CThread thread;
+ if (!thread.Create(CThreadCombine::MyThreadFunction, &combiner))
+ throw 271824;
+ progressDialog.Create(title, _window);
+
+ if (!combiner.Error.IsEmpty())
+ srcPanel.MessageBoxMyError(combiner.Error);
+ // disableTimerProcessing1.Restore();
+ // disableTimerProcessing2.Restore();
+ // srcPanel.SetFocusToList();
+ // srcPanel.RefreshListCtrlSaveFocused();
+}
diff --git a/CPP/7zip/FileManager/PhysDriveFolder.cpp b/CPP/7zip/FileManager/PhysDriveFolder.cpp
new file mode 100755
index 00000000..b69d3cb3
--- /dev/null
+++ b/CPP/7zip/FileManager/PhysDriveFolder.cpp
@@ -0,0 +1,274 @@
+// PhysDriveFolder.cpp
+
+#include "StdAfx.h"
+
+#include "PhysDriveFolder.h"
+
+#include "Common/Alloc.h"
+
+#include "Windows/PropVariant.h"
+#include "Windows/FileDevice.h"
+#include "Windows/FileSystem.h"
+
+#include "../PropID.h"
+
+using namespace NWindows;
+
+static const UInt32 kBufferSize = (4 << 20);
+
+static STATPROPSTG kProperties[] =
+{
+ { NULL, kpidName, VT_BSTR},
+ { NULL, kpidSize, VT_UI8}
+};
+
+CPhysDriveFolder::~CPhysDriveFolder()
+{
+ if (_buffer != 0)
+ MyFree(_buffer);
+}
+
+HRESULT CPhysDriveFolder::Init(const UString &path)
+{
+ _prefix = L"\\\\.\\";
+ _path = path;
+ NFile::NDevice::CInFile inFile;
+ if (!inFile.Open(GetFullPath()))
+ return GetLastError();
+ return S_OK;
+}
+
+STDMETHODIMP CPhysDriveFolder::LoadItems()
+{
+ _driveType = NFile::NSystem::MyGetDriveType(_path + L"\\");
+ _name = _path.Left(1);
+ _name += L'.';
+ if (_driveType == DRIVE_CDROM)
+ _name += L"iso";
+ else
+ _name += L"img";
+ Int32 dummy;
+ WasChanged(&dummy);
+ return GetLength(_length);
+}
+
+STDMETHODIMP CPhysDriveFolder::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = 1;
+ return S_OK;
+}
+
+STDMETHODIMP CPhysDriveFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value)
+{
+ NCOM::CPropVariant propVariant;
+ if (itemIndex >= 1)
+ return E_INVALIDARG;
+ switch(propID)
+ {
+ case kpidIsFolder:
+ propVariant = false;
+ break;
+ case kpidName:
+ propVariant = _name;
+ break;
+ case kpidSize:
+ propVariant = _length;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
+
+STDMETHODIMP CPhysDriveFolder::BindToFolder(UInt32 /* index */, IFolderFolder ** /* resultFolder */)
+ { return E_NOTIMPL; }
+
+STDMETHODIMP CPhysDriveFolder::BindToFolder(const wchar_t * /* name */, IFolderFolder ** /* resultFolder */)
+ { return E_NOTIMPL; }
+
+STDMETHODIMP CPhysDriveFolder::BindToParentFolder(IFolderFolder **resultFolder)
+{
+ *resultFolder = 0;
+ return S_OK;
+}
+
+STDMETHODIMP CPhysDriveFolder::GetName(BSTR * /* name */)
+ { return E_NOTIMPL; }
+
+STDMETHODIMP CPhysDriveFolder::GetNumberOfProperties(UInt32 *numProperties)
+{
+ *numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
+ return S_OK;
+}
+
+STDMETHODIMP CPhysDriveFolder::GetPropertyInfo(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType)
+{
+ if (index >= sizeof(kProperties) / sizeof(kProperties[0]))
+ return E_INVALIDARG;
+ const STATPROPSTG &prop = kProperties[index];
+ *propID = prop.propid;
+ *varType = prop.vt;
+ *name = 0;
+ return S_OK;
+}
+
+
+STDMETHODIMP CPhysDriveFolder::GetTypeID(BSTR *name)
+{
+ CMyComBSTR temp = L"PhysDrive";
+ *name = temp.Detach();
+ return S_OK;
+}
+
+STDMETHODIMP CPhysDriveFolder::GetPath(BSTR *path)
+{
+ UString tempPath = GetFullPath() + L"\\";
+ CMyComBSTR temp = tempPath;
+ *path = temp.Detach();
+ return S_OK;
+}
+
+STDMETHODIMP CPhysDriveFolder::WasChanged(Int32 *wasChanged)
+{
+ bool wasChangedMain = false;
+ *wasChanged = BoolToInt(wasChangedMain);
+ return S_OK;
+}
+
+STDMETHODIMP CPhysDriveFolder::Clone(IFolderFolder **resultFolder)
+{
+ CPhysDriveFolder *folderSpec = new CPhysDriveFolder;
+ CMyComPtr<IFolderFolder> folderNew = folderSpec;
+ folderSpec->Init(_path);
+ *resultFolder = folderNew.Detach();
+ return S_OK;
+}
+
+STDMETHODIMP CPhysDriveFolder::GetItemFullSize(UInt32 index, PROPVARIANT *value, IProgress * /* progress */)
+{
+ NCOM::CPropVariant propVariant;
+ if (index >= 1)
+ return E_INVALIDARG;
+ UInt64 size = 0;
+ HRESULT result = GetLength(size);
+ propVariant = size;
+ propVariant.Detach(value);
+ return result;
+}
+
+STDMETHODIMP CPhysDriveFolder::CreateFolder(const wchar_t * /* name */, IProgress * /* progress */)
+ { return E_NOTIMPL; }
+
+STDMETHODIMP CPhysDriveFolder::CreateFile(const wchar_t * /* name */, IProgress * /* progress */)
+ { return E_NOTIMPL; }
+
+STDMETHODIMP CPhysDriveFolder::Rename(UInt32 /* index */, const wchar_t * /* newName */, IProgress * /* progress */)
+ { return E_NOTIMPL; }
+
+STDMETHODIMP CPhysDriveFolder::Delete(const UInt32 * /* indices */, UInt32 /* numItems */, IProgress * /* progress */)
+ { return E_NOTIMPL; }
+
+STDMETHODIMP CPhysDriveFolder::SetProperty(UInt32 index, PROPID /* propID */,
+ const PROPVARIANT * /* value */, IProgress * /* progress */)
+{
+ if (index >= 1)
+ return E_INVALIDARG;
+ return E_NOTIMPL;
+}
+
+HRESULT CPhysDriveFolder::GetLength(UInt64 &length) const
+{
+ NFile::NDevice::CInFile inFile;
+ if (!inFile.Open(GetFullPath()))
+ return GetLastError();
+ if (!inFile.GetLengthSmart(length))
+ return GetLastError();
+ return S_OK;
+}
+
+STDMETHODIMP CPhysDriveFolder::CopyTo(const UInt32 * /* indices */, UInt32 numItems,
+ const wchar_t *path, IFolderOperationsExtractCallback *callback)
+{
+ if (numItems == 0)
+ return S_OK;
+ UString destPath = path;
+ if (destPath.IsEmpty())
+ return E_INVALIDARG;
+ bool directName = (destPath[destPath.Length() - 1] != L'\\');
+ if (directName)
+ {
+ if (numItems > 1)
+ return E_INVALIDARG;
+ }
+ else
+ destPath += _name;
+
+ UInt64 fileSize;
+ if (GetLength(fileSize) == S_OK)
+ {
+ RINOK(callback->SetTotal(fileSize));
+ }
+
+ Int32 writeAskResult;
+ CMyComBSTR destPathResult;
+ RINOK(callback->AskWrite(GetFullPath(), BoolToInt(false), NULL, &fileSize,
+ destPath, &destPathResult, &writeAskResult));
+ if (!IntToBool(writeAskResult))
+ return S_OK;
+
+ RINOK(callback->SetCurrentFilePath(GetFullPathWithName()));
+
+ NFile::NDevice::CInFile inFile;
+ if (!inFile.Open(GetFullPath()))
+ return GetLastError();
+ NFile::NIO::COutFile outFile;
+ if (!outFile.Create(destPathResult, true))
+ return GetLastError();
+ if (_buffer == 0)
+ {
+ _buffer = MyAlloc(kBufferSize);
+ if (_buffer == 0)
+ return E_OUTOFMEMORY;
+ }
+ UInt64 pos = 0;
+ UInt32 bufferSize = kBufferSize;
+ if (_driveType == DRIVE_REMOVABLE)
+ bufferSize = (18 << 10) * 4;
+ pos = 0;
+ while(pos < fileSize)
+ {
+ RINOK(callback->SetCompleted(&pos));
+ UInt32 curSize = (UInt32)MyMin(fileSize - pos, (UInt64)bufferSize);
+ UInt32 processedSize;
+ if (!inFile.Read(_buffer, curSize, processedSize))
+ return GetLastError();
+ if (processedSize == 0)
+ break;
+ curSize = processedSize;
+ if (!outFile.Write(_buffer, curSize, processedSize))
+ return GetLastError();
+ if (curSize != processedSize)
+ return E_FAIL;
+ pos += curSize;
+ }
+ return S_OK;
+}
+
+/////////////////////////////////////////////////
+// Move Operations
+
+STDMETHODIMP CPhysDriveFolder::MoveTo(
+ const UInt32 * /* indices */,
+ UInt32 /* numItems */,
+ const wchar_t * /* path */,
+ IFolderOperationsExtractCallback * /* callback */)
+{
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP CPhysDriveFolder::CopyFrom(
+ const wchar_t * /* fromFolderPath */,
+ const wchar_t ** /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */)
+{
+ return E_NOTIMPL;
+}
diff --git a/CPP/7zip/FileManager/PhysDriveFolder.h b/CPP/7zip/FileManager/PhysDriveFolder.h
new file mode 100755
index 00000000..076b0718
--- /dev/null
+++ b/CPP/7zip/FileManager/PhysDriveFolder.h
@@ -0,0 +1,89 @@
+// PhysDriveFolder.h
+
+#ifndef __PHYSDRIVEFOLDER_H
+#define __PHYSDRIVEFOLDER_H
+
+#include "Common/String.h"
+#include "Common/MyCom.h"
+
+#include "IFolder.h"
+
+class CPhysDriveFolder:
+ public IFolderFolder,
+ public IEnumProperties,
+ public IFolderGetTypeID,
+ public IFolderGetPath,
+ public IFolderWasChanged,
+ public IFolderOperations,
+ public IFolderGetItemFullSize,
+ public IFolderClone,
+ // public IFolderGetSystemIconIndex,
+ public CMyUnknownImp
+{
+ UInt64 GetSizeOfItem(int anIndex) const;
+public:
+ MY_QUERYINTERFACE_BEGIN
+ MY_QUERYINTERFACE_ENTRY(IEnumProperties)
+ MY_QUERYINTERFACE_ENTRY(IFolderGetTypeID)
+ MY_QUERYINTERFACE_ENTRY(IFolderGetPath)
+ MY_QUERYINTERFACE_ENTRY(IFolderWasChanged)
+ MY_QUERYINTERFACE_ENTRY(IFolderOperations)
+ MY_QUERYINTERFACE_ENTRY(IFolderGetItemFullSize)
+ MY_QUERYINTERFACE_ENTRY(IFolderClone)
+ // MY_QUERYINTERFACE_ENTRY(IFolderGetSystemIconIndex)
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
+
+
+ STDMETHOD(LoadItems)();
+ STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
+ STDMETHOD(GetProperty)(UInt32 itemIndex, PROPID propID, PROPVARIANT *value);
+ STDMETHOD(BindToFolder)(UInt32 index, IFolderFolder **resultFolder);
+ STDMETHOD(BindToFolder)(const wchar_t *name, IFolderFolder **resultFolder);
+ STDMETHOD(BindToParentFolder)(IFolderFolder **resultFolder);
+ STDMETHOD(GetName)(BSTR *name);
+
+ STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
+ STDMETHOD(GetPropertyInfo)(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType);
+ STDMETHOD(GetTypeID)(BSTR *name);
+ STDMETHOD(GetPath)(BSTR *path);
+ STDMETHOD(WasChanged)(INT32 *wasChanged);
+ STDMETHOD(Clone)(IFolderFolder **resultFolder);
+ STDMETHOD(GetItemFullSize)(UInt32 index, PROPVARIANT *value, IProgress *progress);
+
+ // IFolderOperations
+ STDMETHOD(CreateFolder)(const wchar_t *name, IProgress *progress);
+ STDMETHOD(CreateFile)(const wchar_t *name, IProgress *progress);
+ STDMETHOD(Rename)(UInt32 index, const wchar_t *newName, IProgress *progress);
+ STDMETHOD(Delete)(const UInt32 *indices, UInt32 numItems, IProgress *progress);
+ STDMETHOD(CopyTo)(const UInt32 *indices, UInt32 numItems,
+ const wchar_t *path, IFolderOperationsExtractCallback *callback);
+ STDMETHOD(MoveTo)(const UInt32 *indices, UInt32 numItems,
+ const wchar_t *path, IFolderOperationsExtractCallback *callback);
+ STDMETHOD(CopyFrom)(const wchar_t *fromFolderPath,
+ const wchar_t **itemsPaths, UInt32 numItems, IProgress *progress);
+ STDMETHOD(SetProperty)(UInt32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress);
+ // STDMETHOD(GetSystemIconIndex)(UInt32 index, INT32 *iconIndex);
+
+private:
+ UString _name;
+ UString _prefix;
+ UString _path;
+ UString GetFullPath() const { return _prefix + _path; }
+ UString GetFullPathWithName() const { return GetFullPath() + L'\\' + _name; }
+ CMyComPtr<IFolderFolder> _parentFolder;
+ void *_buffer;
+
+ UINT _driveType;
+ DISK_GEOMETRY geom;
+ UInt64 _length;
+
+public:
+ HRESULT Init(const UString &path);
+ HRESULT GetLength(UInt64 &size) const;
+ CPhysDriveFolder(): _buffer(0) {}
+ ~CPhysDriveFolder();
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/PluginInterface.h b/CPP/7zip/FileManager/PluginInterface.h
new file mode 100755
index 00000000..249f5644
--- /dev/null
+++ b/CPP/7zip/FileManager/PluginInterface.h
@@ -0,0 +1,42 @@
+// PluginInterface.h
+
+#ifndef __PLUGININTERFACE_H
+#define __PLUGININTERFACE_H
+
+#include "Common/String.h"
+
+// {23170F69-40C1-278D-0000-000100010000}
+DEFINE_GUID(IID_IInitContextMenu,
+0x23170F69, 0x40C1, 0x278D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278D-0000-000100010000")
+IInitContextMenu: public IUnknown
+{
+public:
+ STDMETHOD(InitContextMenu)(const wchar_t *aFolder, const wchar_t **aNames, UINT32 aNumFiles) PURE;
+
+};
+
+// {23170F69-40C1-278D-0000-000100020100}
+DEFINE_GUID(IID_IPluginOptionsCallback,
+0x23170F69, 0x40C1, 0x278D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278D-0000-000100020000")
+IPluginOptionsCallback: public IUnknown
+{
+public:
+ STDMETHOD(GetProgramFolderPath)(BSTR *value) PURE;
+ STDMETHOD(GetProgramPath)(BSTR *value) PURE;
+ STDMETHOD(GetRegistryCUPath)(BSTR *value) PURE;
+};
+
+// {23170F69-40C1-278D-0000-000100020000}
+DEFINE_GUID(IID_IPluginOptions,
+0x23170F69, 0x40C1, 0x278D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278D-0000-000100020000")
+IPluginOptions: public IUnknown
+{
+public:
+ STDMETHOD(PluginOptions)(HWND hWnd, IPluginOptionsCallback *callback) PURE;
+ // STDMETHOD(GetFileExtensions)(BSTR *extensions) PURE;
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/PluginLoader.h b/CPP/7zip/FileManager/PluginLoader.h
new file mode 100755
index 00000000..598a874b
--- /dev/null
+++ b/CPP/7zip/FileManager/PluginLoader.h
@@ -0,0 +1,32 @@
+// PluginLoader.h
+
+#ifndef __PLUGINLOADER_H
+#define __PLUGINLOADER_H
+
+#include "Windows/DLL.h"
+
+typedef UINT32 (WINAPI * CreateObjectPointer)(
+ const GUID *clsID,
+ const GUID *interfaceID,
+ void **outObject);
+
+class CPluginLibrary: public NWindows::NDLL::CLibrary
+{
+public:
+ HRESULT CreateManager(REFGUID clsID, IFolderManager **manager)
+ {
+ CreateObjectPointer createObject = (CreateObjectPointer)
+ GetProcAddress("CreateObject");
+ if (createObject == NULL)
+ return GetLastError();
+ return createObject(&clsID, &IID_IFolderManager, (void **)manager);
+ }
+ HRESULT LoadAndCreateManager(LPCWSTR filePath, REFGUID clsID, IFolderManager **manager)
+ {
+ if (!Load(filePath))
+ return GetLastError();
+ return CreateManager(clsID, manager);
+ }
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/ProgramLocation.cpp b/CPP/7zip/FileManager/ProgramLocation.cpp
new file mode 100755
index 00000000..88c18d5e
--- /dev/null
+++ b/CPP/7zip/FileManager/ProgramLocation.cpp
@@ -0,0 +1,24 @@
+// ProgramLocation.h
+
+#include "StdAfx.h"
+
+#include "ProgramLocation.h"
+
+#include "Windows/FileName.h"
+#include "Windows/DLL.h"
+
+using namespace NWindows;
+
+extern HINSTANCE g_hInstance;
+
+bool GetProgramFolderPath(UString &folder)
+{
+ if (!NDLL::MyGetModuleFileName(g_hInstance, folder))
+ return false;
+ int pos = folder.ReverseFind(L'\\');
+ if (pos < 0)
+ return false;
+ folder = folder.Left(pos + 1);
+ return true;
+}
+
diff --git a/CPP/7zip/FileManager/ProgramLocation.h b/CPP/7zip/FileManager/ProgramLocation.h
new file mode 100755
index 00000000..8a8dcf7d
--- /dev/null
+++ b/CPP/7zip/FileManager/ProgramLocation.h
@@ -0,0 +1,10 @@
+// ProgramLocation.h
+
+#ifndef __PROGRAMLOCATION_H
+#define __PROGRAMLOCATION_H
+
+#include "Common/String.h"
+
+bool GetProgramFolderPath(UString &folder); // normalized
+
+#endif
diff --git a/CPP/7zip/FileManager/PropertyName.cpp b/CPP/7zip/FileManager/PropertyName.cpp
new file mode 100755
index 00000000..848a8855
--- /dev/null
+++ b/CPP/7zip/FileManager/PropertyName.cpp
@@ -0,0 +1,74 @@
+// PropertyName.cpp
+
+#include "StdAfx.h"
+
+#include "../PropID.h"
+#include "Windows/ResourceString.h"
+#include "resource.h"
+#include "PropertyName.h"
+#include "Resource/PropertyName/resource.h"
+#include "LangUtils.h"
+
+struct CPropertyIDNamePair
+{
+ PROPID PropID;
+ UINT ResourceID;
+ UINT LangID;
+};
+
+static CPropertyIDNamePair kPropertyIDNamePairs[] =
+{
+ { kpidPath, IDS_PROPERTY_PATH, 0x02000203 },
+ { kpidName, IDS_PROPERTY_NAME, 0x02000204 },
+ // { kpidExtension, L"Extension" },
+ { kpidIsFolder, IDS_PROPERTY_IS_FOLDER, 0x02000206},
+ { kpidSize, IDS_PROPERTY_SIZE, 0x02000207},
+ { kpidPackedSize, IDS_PROPERTY_PACKED_SIZE, 0x02000208 },
+ { kpidAttributes, IDS_PROPERTY_ATTRIBUTES, 0x02000209 },
+ { kpidCreationTime, IDS_PROPERTY_CREATION_TIME, 0x0200020A },
+ { kpidLastAccessTime, IDS_PROPERTY_LAST_ACCESS_TIME, 0x0200020B },
+ { kpidLastWriteTime, IDS_PROPERTY_LAST_WRITE_TIME, 0x0200020C },
+ { kpidSolid, IDS_PROPERTY_SOLID, 0x0200020D },
+ { kpidCommented, IDS_PROPERTY_C0MMENTED, 0x0200020E },
+ { kpidEncrypted, IDS_PROPERTY_ENCRYPTED, 0x0200020F },
+ { kpidSplitBefore, IDS_PROPERTY_SPLIT_BEFORE, 0x02000210 },
+ { kpidSplitAfter, IDS_PROPERTY_SPLIT_AFTER, 0x02000211 },
+ { kpidDictionarySize, IDS_PROPERTY_DICTIONARY_SIZE, 0x02000212 },
+ { kpidCRC, IDS_PROPERTY_CRC, 0x02000213 },
+ { kpidType, IDS_PROPERTY_FILE_TYPE, 0x02000214},
+ { kpidIsAnti, IDS_PROPERTY_ANTI, 0x02000215 },
+ { kpidMethod, IDS_PROPERTY_METHOD, 0x02000216 },
+ { kpidHostOS, IDS_PROPERTY_HOST_OS, 0x02000217 },
+ { kpidFileSystem, IDS_PROPERTY_FILE_SYSTEM, 0x02000218},
+ { kpidUser, IDS_PROPERTY_USER, 0x02000219},
+ { kpidGroup, IDS_PROPERTY_GROUP, 0x0200021A},
+ { kpidBlock, IDS_PROPERTY_BLOCK, 0x0200021B },
+ { kpidComment, IDS_PROPERTY_COMMENT, 0x0200021C },
+ { kpidPosition, IDS_PROPERTY_POSITION, 0x0200021D },
+ { kpidPrefix, IDS_PROPERTY_PREFIX, 0x0200021E },
+
+ { kpidTotalSize, IDS_PROPERTY_TOTAL_SIZE, 0x03031100 },
+ { kpidFreeSpace, IDS_PROPERTY_FREE_SPACE, 0x03031101 },
+ { kpidClusterSize, IDS_PROPERTY_CLUSTER_SIZE, 0x03031102},
+ { kpidVolumeName, IDS_PROPERTY_VOLUME_NAME, 0x03031103 },
+
+ { kpidLocalName, IDS_PROPERTY_LOCAL_NAME, 0x03031200 },
+ { kpidProvider, IDS_PROPERTY_PROVIDER, 0x03031201 }
+};
+
+int FindProperty(PROPID propID)
+{
+ for (int i = 0; i < sizeof(kPropertyIDNamePairs) / sizeof(kPropertyIDNamePairs[0]); i++)
+ if(kPropertyIDNamePairs[i].PropID == propID)
+ return i;
+ return -1;
+}
+
+UString GetNameOfProperty(PROPID propID)
+{
+ int index = FindProperty(propID);
+ if (index < 0)
+ return UString();
+ const CPropertyIDNamePair &pair = kPropertyIDNamePairs[index];
+ return LangString(pair.ResourceID, pair.LangID);
+}
diff --git a/CPP/7zip/FileManager/PropertyName.h b/CPP/7zip/FileManager/PropertyName.h
new file mode 100755
index 00000000..c99fe933
--- /dev/null
+++ b/CPP/7zip/FileManager/PropertyName.h
@@ -0,0 +1,10 @@
+// PropertyName.h
+
+#ifndef __PROPERTYNAME_H
+#define __PROPERTYNAME_H
+
+#include "Common/String.h"
+
+UString GetNameOfProperty(PROPID propID);
+
+#endif
diff --git a/CPP/7zip/FileManager/RegistryAssociations.cpp b/CPP/7zip/FileManager/RegistryAssociations.cpp
new file mode 100755
index 00000000..b4b35c67
--- /dev/null
+++ b/CPP/7zip/FileManager/RegistryAssociations.cpp
@@ -0,0 +1,270 @@
+// RegistryAssociations.cpp
+
+#include "StdAfx.h"
+
+#include "RegistryAssociations.h"
+
+#include "Common/StringConvert.h"
+
+#include "Windows/COM.h"
+#include "Windows/Synchronization.h"
+#include "Windows/Registry.h"
+
+#include "Windows/FileName.h"
+
+#include "StringUtils.h"
+
+using namespace NWindows;
+using namespace NCOM;
+using namespace NRegistry;
+
+
+namespace NRegistryAssociations {
+
+static NSynchronization::CCriticalSection g_CriticalSection;
+
+static const TCHAR *kCUKeyPath = TEXT("Software\\7-ZIP\\FM");
+static const TCHAR *kAssociations = TEXT("Associations");
+static const WCHAR *kExtPlugins = L"Plugins";
+static const TCHAR *kExtEnabled = TEXT("Enabled");
+
+static CSysString GetAssociationsPath()
+{
+ return CSysString(kCUKeyPath) + CSysString('\\') + CSysString(kAssociations);
+}
+
+bool ReadInternalAssociation(const wchar_t *ext, CExtInfo &extInfo)
+{
+ NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
+ CKey key;
+ if(key.Open(HKEY_CURRENT_USER, GetAssociationsPath() + CSysString('\\') +
+ CSysString(GetSystemString(ext)), KEY_READ) != ERROR_SUCCESS)
+ return false;
+ UString pluginsString;
+ key.QueryValue(kExtPlugins, pluginsString);
+ SplitString(pluginsString, extInfo.Plugins);
+ return true;
+}
+
+void ReadInternalAssociations(CObjectVector<CExtInfo> &items)
+{
+ items.Clear();
+ NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
+ CKey associationsKey;
+ if(associationsKey.Open(HKEY_CURRENT_USER, GetAssociationsPath(), KEY_READ) != ERROR_SUCCESS)
+ return;
+ CSysStringVector extNames;
+ associationsKey.EnumKeys(extNames);
+ for(int i = 0; i < extNames.Size(); i++)
+ {
+ const CSysString extName = extNames[i];
+ CExtInfo extInfo;
+ // extInfo.Enabled = false;
+ extInfo.Ext = GetUnicodeString(extName);
+ CKey key;
+ if(key.Open(associationsKey, extName, KEY_READ) != ERROR_SUCCESS)
+ return;
+ UString pluginsString;
+ key.QueryValue(kExtPlugins, pluginsString);
+ SplitString(pluginsString, extInfo.Plugins);
+ /*
+ if (key.QueryValue(kExtEnabled, extInfo.Enabled) != ERROR_SUCCESS)
+ extInfo.Enabled = false;
+ */
+ items.Add(extInfo);
+ }
+}
+
+void WriteInternalAssociations(const CObjectVector<CExtInfo> &items)
+{
+ NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
+ CKey mainKey;
+ mainKey.Create(HKEY_CURRENT_USER, kCUKeyPath);
+ mainKey.RecurseDeleteKey(kAssociations);
+ CKey associationsKey;
+ associationsKey.Create(mainKey, kAssociations);
+ for(int i = 0; i < items.Size(); i++)
+ {
+ const CExtInfo &extInfo = items[i];
+ CKey key;
+ key.Create(associationsKey, GetSystemString(extInfo.Ext));
+ key.SetValue(kExtPlugins, JoinStrings(extInfo.Plugins));
+ // key.SetValue(kExtEnabled, extInfo.Enabled);
+ }
+}
+
+///////////////////////////////////
+// External
+
+static const TCHAR *kShellNewKeyName = TEXT("ShellNew");
+static const TCHAR *kShellNewDataValueName = TEXT("Data");
+
+static const TCHAR *kDefaultIconKeyName = TEXT("DefaultIcon");
+static const TCHAR *kShellKeyName = TEXT("shell");
+static const TCHAR *kOpenKeyName = TEXT("open");
+static const TCHAR *kCommandKeyName = TEXT("command");
+
+static CSysString GetExtensionKeyName(const CSysString &extension)
+{
+ return CSysString(TEXT(".")) + extension;
+}
+
+static CSysString GetExtProgramKeyName(const CSysString &extension)
+{
+ return CSysString(TEXT("7-Zip.")) + extension;
+}
+
+static bool CheckShellExtensionInfo2(const CSysString &extension)
+{
+ NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
+ CKey extKey;
+ if (extKey.Open(HKEY_CLASSES_ROOT, GetExtensionKeyName(extension), KEY_READ) != ERROR_SUCCESS)
+ return false;
+ CSysString programNameValue;
+ if (extKey.QueryValue(NULL, programNameValue) != ERROR_SUCCESS)
+ return false;
+ CSysString extProgramKeyName = GetExtProgramKeyName(extension);
+ return (programNameValue.CompareNoCase(extProgramKeyName) == 0);
+}
+
+bool CheckShellExtensionInfo(const CSysString &extension)
+{
+ NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
+ if (!CheckShellExtensionInfo2(extension))
+ return false;
+ CKey extProgKey;
+ return (extProgKey.Open(HKEY_CLASSES_ROOT, GetExtProgramKeyName(extension), KEY_READ) == ERROR_SUCCESS);
+}
+
+static void DeleteShellExtensionKey(const CSysString &extension)
+{
+ NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
+ CKey rootKey;
+ rootKey.Attach(HKEY_CLASSES_ROOT);
+ rootKey.RecurseDeleteKey(GetExtensionKeyName(extension));
+ rootKey.Detach();
+}
+
+static void DeleteShellExtensionProgramKey(const CSysString &extension)
+{
+ NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
+ CKey rootKey;
+ rootKey.Attach(HKEY_CLASSES_ROOT);
+ rootKey.RecurseDeleteKey(GetExtProgramKeyName(extension));
+ rootKey.Detach();
+}
+
+void DeleteShellExtensionInfo(const CSysString &extension)
+{
+ if (CheckShellExtensionInfo2(extension))
+ DeleteShellExtensionKey(extension);
+ DeleteShellExtensionProgramKey(extension);
+}
+
+void AddShellExtensionInfo(const CSysString &extension,
+ const UString &programTitle,
+ const UString &programOpenCommand,
+ const UString &iconPath,
+ const void *shellNewData, int shellNewDataSize)
+{
+ DeleteShellExtensionKey(extension);
+ DeleteShellExtensionProgramKey(extension);
+ NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
+ CSysString programKeyName = GetExtProgramKeyName(extension);
+ {
+ CKey extKey;
+ extKey.Create(HKEY_CLASSES_ROOT, GetExtensionKeyName(extension));
+ extKey.SetValue(NULL, programKeyName);
+ if (shellNewData != NULL)
+ {
+ CKey shellNewKey;
+ shellNewKey.Create(extKey, kShellNewKeyName);
+ shellNewKey.SetValue(kShellNewDataValueName, shellNewData, shellNewDataSize);
+ }
+ }
+ CKey programKey;
+ programKey.Create(HKEY_CLASSES_ROOT, programKeyName);
+ programKey.SetValue(NULL, programTitle);
+ {
+ CKey iconKey;
+ iconKey.Create(programKey, kDefaultIconKeyName);
+ iconKey.SetValue(NULL, iconPath);
+ }
+
+ CKey shellKey;
+ shellKey.Create(programKey, kShellKeyName);
+ shellKey.SetValue(NULL, TEXT(""));
+
+ CKey openKey;
+ openKey.Create(shellKey, kOpenKeyName);
+ openKey.SetValue(NULL, TEXT(""));
+
+ CKey commandKey;
+ commandKey.Create(openKey, kCommandKeyName);
+
+ commandKey.SetValue(NULL, programOpenCommand);
+}
+
+///////////////////////////
+// ContextMenu
+/*
+
+static const TCHAR *kContextMenuKeyName = TEXT("\\shellex\\ContextMenuHandlers\\7-ZIP");
+static const TCHAR *kContextMenuHandlerCLASSIDValue =
+ TEXT("{23170F69-40C1-278A-1000-000100020000}");
+static const TCHAR *kRootKeyNameForFile = TEXT("*");
+static const TCHAR *kRootKeyNameForFolder = TEXT("Folder");
+
+static CSysString GetFullContextMenuKeyName(const CSysString &aKeyName)
+ { return (aKeyName + kContextMenuKeyName); }
+
+static bool CheckContextMenuHandlerCommon(const CSysString &aKeyName)
+{
+ NSynchronization::CCriticalSectionLock lock(&g_CriticalSection, true);
+ CKey aKey;
+ if (aKey.Open(HKEY_CLASSES_ROOT, GetFullContextMenuKeyName(aKeyName), KEY_READ)
+ != ERROR_SUCCESS)
+ return false;
+ CSysString aValue;
+ if (aKey.QueryValue(NULL, aValue) != ERROR_SUCCESS)
+ return false;
+ return (aValue.CompareNoCase(kContextMenuHandlerCLASSIDValue) == 0);
+}
+
+bool CheckContextMenuHandler()
+{
+ return CheckContextMenuHandlerCommon(kRootKeyNameForFile) &&
+ CheckContextMenuHandlerCommon(kRootKeyNameForFolder);
+}
+
+static void DeleteContextMenuHandlerCommon(const CSysString &aKeyName)
+{
+ CKey rootKey;
+ rootKey.Attach(HKEY_CLASSES_ROOT);
+ rootKey.RecurseDeleteKey(GetFullContextMenuKeyName(aKeyName));
+ rootKey.Detach();
+}
+
+void DeleteContextMenuHandler()
+{
+ DeleteContextMenuHandlerCommon(kRootKeyNameForFile);
+ DeleteContextMenuHandlerCommon(kRootKeyNameForFolder);
+}
+
+static void AddContextMenuHandlerCommon(const CSysString &aKeyName)
+{
+ DeleteContextMenuHandlerCommon(aKeyName);
+ NSynchronization::CCriticalSectionLock lock(&g_CriticalSection, true);
+ CKey aKey;
+ aKey.Create(HKEY_CLASSES_ROOT, GetFullContextMenuKeyName(aKeyName));
+ aKey.SetValue(NULL, kContextMenuHandlerCLASSIDValue);
+}
+
+void AddContextMenuHandler()
+{
+ AddContextMenuHandlerCommon(kRootKeyNameForFile);
+ AddContextMenuHandlerCommon(kRootKeyNameForFolder);
+}
+*/
+
+}
diff --git a/CPP/7zip/FileManager/RegistryAssociations.h b/CPP/7zip/FileManager/RegistryAssociations.h
new file mode 100755
index 00000000..c225aca4
--- /dev/null
+++ b/CPP/7zip/FileManager/RegistryAssociations.h
@@ -0,0 +1,45 @@
+// RegistryAssociations.h
+
+#ifndef __REGISTRYASSOCIATIONS_H
+#define __REGISTRYASSOCIATIONS_H
+
+#include "Common/String.h"
+#include "Common/Vector.h"
+
+namespace NRegistryAssociations {
+
+ struct CExtInfo
+ {
+ UString Ext;
+ UStringVector Plugins;
+ // bool Enabled;
+ };
+ bool ReadInternalAssociation(const wchar_t *ext, CExtInfo &extInfo);
+ void ReadInternalAssociations(CObjectVector<CExtInfo> &items);
+ void WriteInternalAssociations(const CObjectVector<CExtInfo> &items);
+
+ bool CheckShellExtensionInfo(const CSysString &extension);
+
+ // void ReadCompressionInfo(NZipSettings::NCompression::CInfo &anInfo,
+ void DeleteShellExtensionInfo(const CSysString &extension);
+
+ void AddShellExtensionInfo(const CSysString &extension,
+ const UString &programTitle,
+ const UString &programOpenCommand,
+ const UString &iconPath,
+ const void *shellNewData, int shellNewDataSize);
+
+
+ ///////////////////////////
+ // ContextMenu
+ /*
+ bool CheckContextMenuHandler();
+ void AddContextMenuHandler();
+ void DeleteContextMenuHandler();
+ */
+
+}
+
+// bool GetProgramDirPrefix(CSysString &aFolder);
+
+#endif
diff --git a/CPP/7zip/FileManager/RegistryPlugins.cpp b/CPP/7zip/FileManager/RegistryPlugins.cpp
new file mode 100755
index 00000000..cad3b43d
--- /dev/null
+++ b/CPP/7zip/FileManager/RegistryPlugins.cpp
@@ -0,0 +1,130 @@
+// RegistryPlugins.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StringConvert.h"
+// #include "Windows/Registry.h"
+// #include "Windows/Synchronization.h"
+// #include "Windows/COM.h"
+
+#include "Windows/DLL.h"
+#include "Windows/PropVariant.h"
+#include "Windows/FileFind.h"
+
+#include "RegistryPlugins.h"
+#include "IFolder.h"
+
+using namespace NWindows;
+using namespace NFile;
+// using namespace NRegistry;
+// using namespace NCOM;
+
+/*
+static const TCHAR *kLMBasePath = TEXT("Software\\7-Zip\\FM");
+
+static const TCHAR *kPluginsKeyName = TEXT("Plugins");
+static const TCHAR *kPluginsOpenClassIDValue = TEXT("CLSID");
+static const TCHAR *kPluginsOptionsClassIDValue = TEXT("Options");
+static const TCHAR *kPluginsTypeValue = TEXT("Type");
+
+static CSysString GetFileFolderPluginsKeyName()
+{
+ return CSysString(kLMBasePath) + CSysString(TEXT('\\')) +
+ CSysString(kPluginsKeyName);
+}
+
+static NSynchronization::CCriticalSection g_CriticalSection;
+*/
+typedef UINT32 (WINAPI * GetPluginPropertyFunc)(
+ PROPID propID, PROPVARIANT *value);
+
+static bool ReadPluginInfo(CPluginInfo &pluginInfo)
+{
+ {
+ NDLL::CLibrary library;
+ if (!library.LoadEx(pluginInfo.FilePath, LOAD_LIBRARY_AS_DATAFILE))
+ return false;
+ }
+ NDLL::CLibrary library;
+ if (!library.Load(pluginInfo.FilePath))
+ return false;
+ GetPluginPropertyFunc getPluginProperty = (GetPluginPropertyFunc)
+ library.GetProcAddress("GetPluginProperty");
+ if (getPluginProperty == NULL)
+ return false;
+
+ NCOM::CPropVariant propVariant;
+ if (getPluginProperty(NPlugin::kName, &propVariant) != S_OK)
+ return false;
+ if (propVariant.vt != VT_BSTR)
+ return false;
+ pluginInfo.Name = propVariant.bstrVal;
+ propVariant.Clear();
+
+ if (getPluginProperty(NPlugin::kClassID, &propVariant) != S_OK)
+ return false;
+ if (propVariant.vt != VT_BSTR)
+ return false;
+ pluginInfo.ClassID = *(const GUID *)propVariant.bstrVal;
+ propVariant.Clear();
+
+ if (getPluginProperty(NPlugin::kOptionsClassID, &propVariant) != S_OK)
+ return false;
+ if (propVariant.vt == VT_EMPTY)
+ pluginInfo.OptionsClassIDDefined = false;
+ else if (propVariant.vt != VT_BSTR)
+ return false;
+ else
+ {
+ pluginInfo.OptionsClassIDDefined = true;
+ pluginInfo.OptionsClassID = *(const GUID *)propVariant.bstrVal;
+ }
+ propVariant.Clear();
+
+ if (getPluginProperty(NPlugin::kType, &propVariant) != S_OK)
+ return false;
+ if (propVariant.vt == VT_EMPTY)
+ pluginInfo.Type = kPluginTypeFF;
+ else if (propVariant.vt == VT_UI4)
+ pluginInfo.Type = (EPluginType)propVariant.ulVal;
+ else
+ return false;
+ return true;
+}
+
+UString GetProgramFolderPrefix();
+
+void ReadPluginInfoList(CObjectVector<CPluginInfo> &plugins)
+{
+ plugins.Clear();
+
+ UString baseFolderPrefix = GetProgramFolderPrefix();
+ {
+ CPluginInfo pluginInfo;
+ pluginInfo.FilePath = baseFolderPrefix + L"7-zip.dll";
+ if (::ReadPluginInfo(pluginInfo))
+ plugins.Add(pluginInfo);
+ }
+ UString folderPath = baseFolderPrefix + L"Plugins\\";
+ NFind::CEnumeratorW enumerator(folderPath + L"*");
+ NFind::CFileInfoW fileInfo;
+ while (enumerator.Next(fileInfo))
+ {
+ if (fileInfo.IsDirectory())
+ continue;
+ CPluginInfo pluginInfo;
+ pluginInfo.FilePath = folderPath + fileInfo.Name;
+ if (::ReadPluginInfo(pluginInfo))
+ plugins.Add(pluginInfo);
+ }
+}
+
+void ReadFileFolderPluginInfoList(CObjectVector<CPluginInfo> &plugins)
+{
+ ReadPluginInfoList(plugins);
+ for (int i = 0; i < plugins.Size();)
+ if (plugins[i].Type != kPluginTypeFF)
+ plugins.Delete(i);
+ else
+ i++;
+}
diff --git a/CPP/7zip/FileManager/RegistryPlugins.h b/CPP/7zip/FileManager/RegistryPlugins.h
new file mode 100755
index 00000000..4a30857c
--- /dev/null
+++ b/CPP/7zip/FileManager/RegistryPlugins.h
@@ -0,0 +1,32 @@
+// RegistryPlugins.h
+
+#ifndef __REGISTRYPLUGINS_H
+#define __REGISTRYPLUGINS_H
+
+#include "Common/Vector.h"
+#include "Common/String.h"
+
+enum EPluginType
+{
+ kPluginTypeFF = 0
+};
+
+struct CPluginInfo
+{
+ UString FilePath;
+ EPluginType Type;
+ UString Name;
+ CLSID ClassID;
+ CLSID OptionsClassID;
+ bool OptionsClassIDDefined;
+
+ // CSysString Extension;
+ // CSysString AddExtension;
+ // bool UpdateEnabled;
+ // bool KeepName;
+};
+
+void ReadPluginInfoList(CObjectVector<CPluginInfo> &plugins);
+void ReadFileFolderPluginInfoList(CObjectVector<CPluginInfo> &plugins);
+
+#endif
diff --git a/CPP/7zip/FileManager/RegistryUtils.cpp b/CPP/7zip/FileManager/RegistryUtils.cpp
new file mode 100755
index 00000000..22869c46
--- /dev/null
+++ b/CPP/7zip/FileManager/RegistryUtils.cpp
@@ -0,0 +1,150 @@
+// RegistryUtils.cpp
+
+#include "StdAfx.h"
+
+#include "RegistryUtils.h"
+#include "Windows/Registry.h"
+
+using namespace NWindows;
+using namespace NRegistry;
+
+static const TCHAR *kCUBasePath = TEXT("Software\\7-ZIP");
+static const TCHAR *kCU_FMPath = TEXT("Software\\7-ZIP\\FM");
+static const TCHAR *kLM_Path = TEXT("Software\\7-ZIP\\FM");
+
+static const WCHAR *kLangValueName = L"Lang";
+static const WCHAR *kEditor = L"Editor";
+static const TCHAR *kShowDots = TEXT("ShowDots");
+static const TCHAR *kShowRealFileIcons = TEXT("ShowRealFileIcons");
+static const TCHAR *kShowSystemMenu = TEXT("ShowSystemMenu");
+
+static const TCHAR *kFullRow = TEXT("FullRow");
+static const TCHAR *kShowGrid = TEXT("ShowGrid");
+static const TCHAR *kAlternativeSelection = TEXT("AlternativeSelection");
+static const TCHAR *kLockMemoryAdd = TEXT("LockMemoryAdd");
+static const TCHAR *kLargePagesEnable = TEXT("LargePages");
+// static const TCHAR *kSingleClick = TEXT("SingleClick");
+// static const TCHAR *kUnderline = TEXT("Underline");
+
+void SaveRegLang(const UString &langFile)
+{
+ CKey key;
+ key.Create(HKEY_CURRENT_USER, kCUBasePath);
+ key.SetValue(kLangValueName, langFile);
+}
+
+void ReadRegLang(UString &langFile)
+{
+ langFile.Empty();
+ CKey key;
+ if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) == ERROR_SUCCESS)
+ key.QueryValue(kLangValueName, langFile);
+}
+
+void SaveRegEditor(const UString &editorPath)
+{
+ CKey key;
+ key.Create(HKEY_CURRENT_USER, kCU_FMPath);
+ key.SetValue(kEditor, editorPath);
+}
+
+void ReadRegEditor(UString &editorPath)
+{
+ editorPath.Empty();
+ CKey key;
+ if (key.Open(HKEY_CURRENT_USER, kCU_FMPath, KEY_READ) == ERROR_SUCCESS)
+ key.QueryValue(kEditor, editorPath);
+}
+
+static void Save7ZipOption(const TCHAR *value, bool enabled)
+{
+ CKey key;
+ key.Create(HKEY_CURRENT_USER, kCUBasePath);
+ key.SetValue(value, enabled);
+}
+
+static void SaveOption(const TCHAR *value, bool enabled)
+{
+ CKey key;
+ key.Create(HKEY_CURRENT_USER, kCU_FMPath);
+ key.SetValue(value, enabled);
+}
+
+static bool Read7ZipOption(const TCHAR *value, bool defaultValue)
+{
+ CKey key;
+ if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) == ERROR_SUCCESS)
+ {
+ bool enabled;
+ if (key.QueryValue(value, enabled) == ERROR_SUCCESS)
+ return enabled;
+ }
+ return defaultValue;
+}
+
+static bool ReadOption(const TCHAR *value, bool defaultValue)
+{
+ CKey key;
+ if (key.Open(HKEY_CURRENT_USER, kCU_FMPath, KEY_READ) == ERROR_SUCCESS)
+ {
+ bool enabled;
+ if (key.QueryValue(value, enabled) == ERROR_SUCCESS)
+ return enabled;
+ }
+ return defaultValue;
+}
+
+/*
+static void SaveLmOption(const TCHAR *value, bool enabled)
+{
+ CKey key;
+ key.Create(HKEY_LOCAL_MACHINE, kLM_Path);
+ key.SetValue(value, enabled);
+}
+
+static bool ReadLmOption(const TCHAR *value, bool defaultValue)
+{
+ CKey key;
+ if (key.Open(HKEY_LOCAL_MACHINE, kLM_Path, KEY_READ) == ERROR_SUCCESS)
+ {
+ bool enabled;
+ if (key.QueryValue(value, enabled) == ERROR_SUCCESS)
+ return enabled;
+ }
+ return defaultValue;
+}
+*/
+
+void SaveShowDots(bool showDots) { SaveOption(kShowDots, showDots); }
+bool ReadShowDots() { return ReadOption(kShowDots, false); }
+
+void SaveShowRealFileIcons(bool show) { SaveOption(kShowRealFileIcons, show); }
+bool ReadShowRealFileIcons() { return ReadOption(kShowRealFileIcons, false); }
+
+void SaveShowSystemMenu(bool show) { SaveOption(kShowSystemMenu, show); }
+bool ReadShowSystemMenu(){ return ReadOption(kShowSystemMenu, false); }
+
+void SaveFullRow(bool enable) { SaveOption(kFullRow, enable); }
+bool ReadFullRow() { return ReadOption(kFullRow, false); }
+
+void SaveShowGrid(bool enable) { SaveOption(kShowGrid, enable); }
+bool ReadShowGrid(){ return ReadOption(kShowGrid, false); }
+
+void SaveAlternativeSelection(bool enable) { SaveOption(kAlternativeSelection, enable); }
+bool ReadAlternativeSelection(){ return ReadOption(kAlternativeSelection, false); }
+
+/*
+void SaveSingleClick(bool enable) { SaveOption(kSingleClick, enable); }
+bool ReadSingleClick(){ return ReadOption(kSingleClick, false); }
+
+void SaveUnderline(bool enable) { SaveOption(kUnderline, enable); }
+bool ReadUnderline(){ return ReadOption(kUnderline, false); }
+*/
+
+// void SaveLockMemoryAdd(bool enable) { SaveLmOption(kLockMemoryAdd, enable); }
+// bool ReadLockMemoryAdd() { return ReadLmOption(kLockMemoryAdd, true); }
+
+void SaveLockMemoryEnable(bool enable) { Save7ZipOption(kLargePagesEnable, enable); }
+bool ReadLockMemoryEnable() { return Read7ZipOption(kLargePagesEnable, false); }
+
+
diff --git a/CPP/7zip/FileManager/RegistryUtils.h b/CPP/7zip/FileManager/RegistryUtils.h
new file mode 100755
index 00000000..0fec6f80
--- /dev/null
+++ b/CPP/7zip/FileManager/RegistryUtils.h
@@ -0,0 +1,46 @@
+// RegistryUtils.h
+
+#include "Common/StringConvert.h"
+
+#ifndef __REGISTRYUTILS_H
+#define __REGISTRYUTILS_H
+
+void SaveRegLang(const UString &langFile);
+void ReadRegLang(UString &langFile);
+
+void SaveRegEditor(const UString &editorPath);
+void ReadRegEditor(UString &editorPath);
+
+void SaveShowDots(bool showDots);
+bool ReadShowDots();
+
+void SaveShowRealFileIcons(bool show);
+bool ReadShowRealFileIcons();
+
+void SaveShowSystemMenu(bool showSystemMenu);
+bool ReadShowSystemMenu();
+
+void SaveFullRow(bool enable);
+bool ReadFullRow();
+
+void SaveShowGrid(bool enable);
+bool ReadShowGrid();
+
+void SaveAlternativeSelection(bool enable);
+bool ReadAlternativeSelection();
+
+// void SaveLockMemoryAdd(bool enable);
+// bool ReadLockMemoryAdd();
+
+bool ReadLockMemoryEnable();
+void SaveLockMemoryEnable(bool enable);
+
+/*
+void SaveSingleClick(bool enable);
+bool ReadSingleClick();
+
+void SaveUnderline(bool enable);
+bool ReadUnderline();
+*/
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/AboutDialog/7zipLogo.ico b/CPP/7zip/FileManager/Resource/AboutDialog/7zipLogo.ico
new file mode 100755
index 00000000..973241c8
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/AboutDialog/7zipLogo.ico
Binary files differ
diff --git a/CPP/7zip/FileManager/Resource/AboutDialog/AboutDialog.cpp b/CPP/7zip/FileManager/Resource/AboutDialog/AboutDialog.cpp
new file mode 100755
index 00000000..e4dd2313
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/AboutDialog/AboutDialog.cpp
@@ -0,0 +1,60 @@
+// AboutDialog.cpp
+
+#include "StdAfx.h"
+
+#include "resource.h"
+#include "AboutDialog.h"
+#include "../../HelpUtils.h"
+#include "../../LangUtils.h"
+
+static CIDLangPair kIDLangPairs[] =
+{
+ { IDC_ABOUT_STATIC_REGISTER_INFO, 0x01000103 },
+ { IDC_ABOUT_BUTTON_SUPPORT, 0x01000104 },
+ { IDC_ABOUT_BUTTON_REGISTER, 0x01000105 },
+ { IDOK, 0x02000702 }
+};
+
+#define MY_HOME_PAGE TEXT("http://www.7-zip.org/")
+
+static LPCTSTR kHomePageURL = MY_HOME_PAGE;
+static LPCTSTR kRegisterPageURL = MY_HOME_PAGE TEXT("register.html");
+static LPCTSTR kSupportPageURL = MY_HOME_PAGE TEXT("support.html");
+
+static LPCWSTR kHelpTopic = L"start.htm";
+
+bool CAboutDialog::OnInit()
+{
+ LangSetWindowText(HWND(*this), 0x01000100);
+ LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
+ return CModalDialog::OnInit();
+}
+
+void CAboutDialog::OnHelp()
+{
+ ShowHelpWindow(NULL, kHelpTopic);
+}
+
+static void MyShellExecute(LPCTSTR url)
+{
+ ::ShellExecute(NULL, NULL, url, NULL, NULL, SW_SHOWNORMAL);
+}
+
+bool CAboutDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch(buttonID)
+ {
+ case IDC_ABOUT_BUTTON_HOMEPAGE:
+ ::MyShellExecute(kHomePageURL);
+ break;
+ case IDC_ABOUT_BUTTON_REGISTER:
+ ::MyShellExecute(kRegisterPageURL);
+ break;
+ case IDC_ABOUT_BUTTON_SUPPORT:
+ ::MyShellExecute(kSupportPageURL);
+ break;
+ default:
+ return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
+ }
+ return true;
+}
diff --git a/CPP/7zip/FileManager/Resource/AboutDialog/AboutDialog.h b/CPP/7zip/FileManager/Resource/AboutDialog/AboutDialog.h
new file mode 100755
index 00000000..278d7c82
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/AboutDialog/AboutDialog.h
@@ -0,0 +1,18 @@
+// AboutDialog.h
+
+#ifndef __ABOUTDIALOG_H
+#define __ABOUTDIALOG_H
+
+#include "resource.h"
+#include "Windows/Control/Dialog.h"
+
+class CAboutDialog: public NWindows::NControl::CModalDialog
+{
+public:
+ virtual bool OnInit();
+ virtual void OnHelp();
+ virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
+ INT_PTR Create(HWND wndParent = 0) { return CModalDialog::Create(IDD_ABOUT, wndParent); }
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/AboutDialog/StdAfx.h b/CPP/7zip/FileManager/Resource/AboutDialog/StdAfx.h
new file mode 100755
index 00000000..a444ca31
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/AboutDialog/StdAfx.h
@@ -0,0 +1,16 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#define _WIN32_WINNT 0x0400
+
+// it's for Windows NT supporting (MENUITEMINFOW)
+#define WINVER 0x0400
+
+#include <windows.h>
+#include <commctrl.h>
+
+#include "Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/AboutDialog/resource.h b/CPP/7zip/FileManager/Resource/AboutDialog/resource.h
new file mode 100755
index 00000000..54475484
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/AboutDialog/resource.h
@@ -0,0 +1,6 @@
+#define IDD_ABOUT 100
+#define IDI_LOGO 138
+#define IDC_ABOUT_STATIC_REGISTER_INFO 1010
+#define IDC_ABOUT_BUTTON_HOMEPAGE 1020
+#define IDC_ABOUT_BUTTON_SUPPORT 1021
+#define IDC_ABOUT_BUTTON_REGISTER 1022
diff --git a/CPP/7zip/FileManager/Resource/AboutDialog/resource.rc b/CPP/7zip/FileManager/Resource/AboutDialog/resource.rc
new file mode 100755
index 00000000..b93fdd41
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/AboutDialog/resource.rc
@@ -0,0 +1,41 @@
+#include "resource.h"
+#include "../../../GuiCommon.rc"
+#include "../../../MyVersion.h"
+
+#define xSize2 224
+#define ySize2 158
+#define xSize (xSize2 + marg + marg)
+#define ySize (ySize2 + marg + marg)
+
+#define bXPos (xSize - marg - bXSize)
+#define bYPos (ySize - marg - bYSize)
+
+#undef b2XSize
+#undef b2XPos
+#undef infoYPos
+#undef infoYSize
+
+#define b2XSize 94
+#define b2XPos (xSize - marg - b2XSize)
+#define gSpace 2
+#define gSize (xSize2 - gSpace - b2XSize)
+
+#define infoYPos 91
+#define infoYSize (ySize2 - infoYPos - bYSize - 2)
+
+IDI_LOGO ICON "7zipLogo.ico"
+
+IDD_ABOUT DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE
+CAPTION "About 7-Zip"
+MY_FONT
+BEGIN
+ PUSHBUTTON "OK", IDOK, bXPos, bYPos, bXSize, bYSize
+ PUSHBUTTON "www.7-zip.org", IDC_ABOUT_BUTTON_HOMEPAGE, b2XPos, 7, b2XSize, bYSize
+ PUSHBUTTON "Support", IDC_ABOUT_BUTTON_SUPPORT, b2XPos, 30, b2XSize, bYSize
+ PUSHBUTTON "Register", IDC_ABOUT_BUTTON_REGISTER, b2XPos, 53, b2XSize, bYSize
+ ICON IDI_LOGO, -1, marg, marg, 20, 20, SS_REALSIZEIMAGE
+ LTEXT MY_7ZIP_VERSION, -1, marg, 54, gSize, 9
+ LTEXT MY_COPYRIGHT, -1, marg, 67, gSize, 17
+ LTEXT "7-Zip is free software. However, you can support development of 7-Zip by registering.",
+ IDC_ABOUT_STATIC_REGISTER_INFO, marg, infoYPos, xSize2, infoYSize
+END
diff --git a/CPP/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp b/CPP/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp
new file mode 100755
index 00000000..1083fc4c
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp
@@ -0,0 +1,976 @@
+// BenchmarkDialog.cpp
+
+#include "StdAfx.h"
+
+#include "Common/IntToString.h"
+#include "Common/StringToInt.h"
+#include "Common/Exception.h"
+#include "Common/Alloc.h"
+#include "Windows/Thread.h"
+#include "Windows/PropVariant.h"
+#include "Windows/Error.h"
+#include "Windows/DLL.h"
+#include "Windows/FileFind.h"
+#include "../../ProgramLocation.h"
+#include "../../HelpUtils.h"
+#include "../../../Common/StreamObjects.h"
+#include "resource.h"
+#include "BenchmarkDialog.h"
+#include "Common/CRC.h"
+
+using namespace NWindows;
+
+static LPCWSTR kHelpTopic = L"fm/benchmark.htm";
+
+static const UINT_PTR kTimerID = 4;
+static const UINT kTimerElapse = 1000;
+
+static const UInt32 kAdditionalSize = (6 << 20);
+static const UInt32 kCompressedAdditionalSize = (1 << 10);
+static const int kSubBits = 8;
+
+#ifdef LANG
+#include "../../LangUtils.h"
+#endif
+
+using namespace NWindows;
+
+#ifdef LANG
+static CIDLangPair kIDLangPairs[] =
+{
+ { IDC_BENCHMARK_DICTIONARY, 0x02000D0C },
+ { IDC_BENCHMARK_MEMORY, 0x03080001 },
+ { IDC_BENCHMARK_MULTITHREADING, 0x02000D09 },
+ { IDC_BENCHMARK_SPEED_LABEL, 0x03080004 },
+ { IDC_BENCHMARK_RATING_LABEL, 0x03080005 },
+ { IDC_BENCHMARK_COMPRESSING, 0x03080002 },
+ { IDC_BENCHMARK_DECOMPRESSING, 0x03080003 },
+ { IDC_BENCHMARK_CURRENT, 0x03080007 },
+ { IDC_BENCHMARK_RESULTING, 0x03080008 },
+ { IDC_BENCHMARK_CURRENT2, 0x03080007 },
+ { IDC_BENCHMARK_RESULTING2, 0x03080008 },
+ { IDC_BENCHMARK_TOTAL_RATING, 0x03080006 },
+ { IDC_BENCHMARK_ELAPSED, 0x02000C01 },
+ { IDC_BENCHMARK_SIZE, 0x02000C03 },
+ { IDC_BENCHMARK_PASSES, 0x03080009 },
+ { IDC_BENCHMARK_ERRORS, 0x0308000A },
+ { IDC_BUTTON_STOP, 0x02000714 },
+ { IDC_BUTTON_RESTART, 0x02000715 },
+ { IDHELP, 0x02000720 },
+ { IDCANCEL, 0x02000710 }
+};
+#endif
+
+static void MyMessageBoxError(HWND hwnd, LPCWSTR message)
+{
+ MessageBoxW(hwnd, message, L"7-Zip", MB_ICONERROR);
+}
+
+UInt64 GetTimeCount()
+{
+ return GetTickCount();
+ /*
+ LARGE_INTEGER value;
+ if (::QueryPerformanceCounter(&value))
+ return value.QuadPart;
+ return GetTickCount();
+ */
+}
+
+UInt64 GetFreq()
+{
+ return 1000;
+ /*
+ LARGE_INTEGER value;
+ if (::QueryPerformanceFrequency(&value))
+ return value.QuadPart;
+ return 1000;
+ */
+}
+
+class CRandomGenerator
+{
+ UInt32 A1;
+ UInt32 A2;
+public:
+ CRandomGenerator() { Init(); }
+ void Init() { A1 = 362436069; A2 = 521288629;}
+ UInt32 GetRnd()
+ {
+ return
+ ((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) ^
+ ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) );
+ }
+};
+
+class CBitRandomGenerator
+{
+ CRandomGenerator RG;
+ UInt32 Value;
+ int NumBits;
+public:
+ void Init()
+ {
+ Value = 0;
+ NumBits = 0;
+ }
+ UInt32 GetRnd(int numBits)
+ {
+ if (NumBits > numBits)
+ {
+ UInt32 result = Value & ((1 << numBits) - 1);
+ Value >>= numBits;
+ NumBits -= numBits;
+ return result;
+ }
+ numBits -= NumBits;
+ UInt32 result = (Value << numBits);
+ Value = RG.GetRnd();
+ result |= Value & ((1 << numBits) - 1);
+ Value >>= numBits;
+ NumBits = 32 - numBits;
+ return result;
+ }
+};
+
+class CBenchRandomGenerator
+{
+ CBitRandomGenerator RG;
+ UInt32 Pos;
+ UInt32 Rep0;
+public:
+ UInt32 BufferSize;
+ Byte *Buffer;
+ CBenchRandomGenerator(): Buffer(0) {}
+ ~CBenchRandomGenerator() { Free(); }
+ void Free()
+ {
+ ::MidFree(Buffer);
+ Buffer = 0;
+ }
+ bool Alloc(UInt32 bufferSize)
+ {
+ if (Buffer != 0 && BufferSize == bufferSize)
+ return true;
+ Free();
+ Buffer = (Byte *)::MidAlloc(bufferSize);
+ Pos = 0;
+ BufferSize = bufferSize;
+ return (Buffer != 0);
+ }
+ UInt32 GetRndBit() { return RG.GetRnd(1); }
+ /*
+ UInt32 GetLogRand(int maxLen)
+ {
+ UInt32 len = GetRnd() % (maxLen + 1);
+ return GetRnd() & ((1 << len) - 1);
+ }
+ */
+ UInt32 GetLogRandBits(int numBits)
+ {
+ UInt32 len = RG.GetRnd(numBits);
+ return RG.GetRnd(len);
+ }
+ UInt32 GetOffset()
+ {
+ if (GetRndBit() == 0)
+ return GetLogRandBits(4);
+ return (GetLogRandBits(4) << 10) | RG.GetRnd(10);
+ }
+ UInt32 GetLen1() { return RG.GetRnd(1 + RG.GetRnd(2)); }
+ UInt32 GetLen2() { return RG.GetRnd(2 + RG.GetRnd(2)); }
+ void Generate()
+ {
+ RG.Init();
+ Rep0 = 1;
+ while(Pos < BufferSize)
+ {
+ if (GetRndBit() == 0 || Pos < 1)
+ Buffer[Pos++] = Byte(RG.GetRnd(8));
+ else
+ {
+ UInt32 len;
+ if (RG.GetRnd(3) == 0)
+ len = 1 + GetLen1();
+ else
+ {
+ do
+ Rep0 = GetOffset();
+ while (Rep0 >= Pos);
+ Rep0++;
+ len = 2 + GetLen2();
+ }
+ for (UInt32 i = 0; i < len && Pos < BufferSize; i++, Pos++)
+ Buffer[Pos] = Buffer[Pos - Rep0];
+ }
+ }
+ }
+};
+
+const LPCTSTR kProcessingString = TEXT("...");
+const LPCTSTR kMB = TEXT(" MB");
+const LPCTSTR kMIPS = TEXT(" MIPS");
+const LPCTSTR kKBs = TEXT(" KB/s");
+
+bool CBenchmarkDialog::OnInit()
+{
+ #ifdef LANG
+ LangSetWindowText(HWND(*this), 0x03080000);
+ LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
+ #endif
+
+ m_Dictionary.Attach(GetItem(IDC_BENCHMARK_COMBO_DICTIONARY));
+ for (int i = kNumBenchDictionaryBitsStart; i <= 30; i++)
+ for (int j = 0; j < 2; j++)
+ {
+ UInt32 dictionary = (1 << i) + (j << (i - 1));
+ if(dictionary >
+ #ifdef _WIN64
+ (1 << 30)
+ #else
+ (1 << 27)
+ #endif
+ )
+ continue;
+ TCHAR s[40];
+ ConvertUInt64ToString((dictionary >> 20), s);
+ lstrcat(s, kMB);
+ int index = (int)m_Dictionary.AddString(s);
+ m_Dictionary.SetItemData(index, dictionary);
+ }
+ m_Dictionary.SetCurSel(0);
+ OnChangeSettings();
+
+ _syncInfo.Init();
+ _syncInfo.InitSettings();
+
+ _syncInfo._startEvent.Set();
+ _timer = SetTimer(kTimerID, kTimerElapse);
+ return CModalDialog::OnInit();
+}
+
+static UInt64 GetLZMAUsage(UInt32 dictionary)
+{
+ UInt32 hs = dictionary - 1;
+ hs |= (hs >> 1);
+ hs |= (hs >> 2);
+ hs |= (hs >> 4);
+ hs |= (hs >> 8);
+ hs >>= 1;
+ hs |= 0xFFFF;
+ if (hs > (1 << 24))
+ hs >>= 1;
+ hs++;
+ return ((hs + (1 << 16)) + (UInt64)dictionary * 2) * 4 + (UInt64)dictionary * 3 / 2 + (1 << 20);
+}
+
+static UInt64 GetMemoryUsage(UInt32 dictionary, bool mtMode)
+{
+ const UInt32 kBufferSize = dictionary + kAdditionalSize;
+ const UInt32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize;
+ return (mtMode ? (6 << 20) : 0 )+ kBufferSize + kCompressedBufferSize +
+ GetLZMAUsage(dictionary) + dictionary + (2 << 20);
+}
+
+UInt32 CBenchmarkDialog::OnChangeDictionary()
+{
+ UInt32 dictionary = (UInt32)m_Dictionary.GetItemData(m_Dictionary.GetCurSel());
+ UInt64 memUsage = GetMemoryUsage(dictionary, IsButtonCheckedBool(IDC_BENCHMARK_MULTITHREADING));
+ memUsage = (memUsage + (1 << 20) - 1) >> 20;
+ TCHAR s[40];
+ ConvertUInt64ToString(memUsage, s);
+ lstrcat(s, kMB);
+ SetItemText(IDC_BENCHMARK_MEMORY_VALUE, s);
+ return dictionary;
+}
+
+void CBenchmarkDialog::OnChangeSettings()
+{
+ EnableItem(IDC_BUTTON_STOP, true);
+ UInt32 dictionary = OnChangeDictionary();
+ SetItemText(IDC_BENCHMARK_COMPRESSING_SPEED, kProcessingString);
+ SetItemText(IDC_BENCHMARK_COMPRESSING_SPEED2, kProcessingString);
+ SetItemText(IDC_BENCHMARK_COMPRESSING_RATING, kProcessingString);
+ SetItemText(IDC_BENCHMARK_COMPRESSING_RATING2, kProcessingString);
+ SetItemText(IDC_BENCHMARK_DECOMPRESSING_SPEED, kProcessingString);
+ SetItemText(IDC_BENCHMARK_DECOMPRESSING_SPEED2, kProcessingString);
+ SetItemText(IDC_BENCHMARK_DECOMPRESSING_RATING, kProcessingString);
+ SetItemText(IDC_BENCHMARK_DECOMPRESSING_RATING2, kProcessingString);
+ SetItemText(IDC_BENCHMARK_TOTAL_RATING_VALUE, kProcessingString);
+ _startTime = GetTickCount();
+ PrintTime();
+ NWindows::NSynchronization::CCriticalSectionLock lock(_syncInfo.CS);
+ _syncInfo.Init();
+ _syncInfo.DictionarySize = dictionary;
+ _syncInfo.Changed = true;
+ _syncInfo.MultiThread = IsButtonCheckedBool(IDC_BENCHMARK_MULTITHREADING);
+}
+
+void CBenchmarkDialog::OnRestartButton()
+{
+ OnChangeSettings();
+}
+
+void CBenchmarkDialog::OnStopButton()
+{
+ EnableItem(IDC_BUTTON_STOP, false);
+ _syncInfo.Pause();
+}
+
+void CBenchmarkDialog::OnHelp()
+{
+ ShowHelpWindow(NULL, kHelpTopic);
+}
+
+void CBenchmarkDialog::OnCancel()
+{
+ _syncInfo.Stop();
+ KillTimer(_timer);
+ CModalDialog::OnCancel();
+}
+
+static void GetTimeString(UInt64 timeValue, TCHAR *s)
+{
+ wsprintf(s, TEXT("%02d:%02d:%02d"),
+ UInt32(timeValue / 3600),
+ UInt32((timeValue / 60) % 60),
+ UInt32(timeValue % 60));
+}
+
+void CBenchmarkDialog::PrintTime()
+{
+ UInt32 curTime = ::GetTickCount();
+ UInt32 elapsedTime = (curTime - _startTime);
+ UInt32 elapsedSec = elapsedTime / 1000;
+ TCHAR s[40];
+ GetTimeString(elapsedSec, s);
+ SetItemText(IDC_BENCHMARK_ELAPSED_VALUE, s);
+}
+
+static UInt32 GetLogSize(UInt32 size)
+{
+ for (int i = kSubBits; i < 32; i++)
+ for (UInt32 j = 0; j < (1 << kSubBits); j++)
+ if (size <= (((UInt32)1) << i) + (j << (i - kSubBits)))
+ return (i << kSubBits) + j;
+ return (32 << kSubBits);
+}
+
+static UInt64 GetCompressRating(UInt32 dictionarySize,
+ UInt64 elapsedTime, UInt64 size)
+{
+ if (elapsedTime == 0)
+ elapsedTime = 1;
+ UInt64 t = GetLogSize(dictionarySize) - (18 << kSubBits);
+ UInt64 numCommandsForOne = 1060 + ((t * t * 10) >> (2 * kSubBits));
+ UInt64 numCommands = (UInt64)(size) * numCommandsForOne;
+ return numCommands * GetFreq() / elapsedTime;
+}
+
+static UInt64 GetDecompressRating(UInt64 elapsedTime,
+ UInt64 outSize, UInt64 inSize)
+{
+ if (elapsedTime == 0)
+ elapsedTime = 1;
+ UInt64 numCommands = inSize * 220 + outSize * 20;
+ return numCommands * GetFreq() / elapsedTime;
+}
+
+static UInt64 GetTotalRating(
+ UInt32 dictionarySize,
+ UInt64 elapsedTimeEn, UInt64 sizeEn,
+ UInt64 elapsedTimeDe,
+ UInt64 inSizeDe, UInt64 outSizeDe)
+{
+ return (GetCompressRating(dictionarySize, elapsedTimeEn, sizeEn) +
+ GetDecompressRating(elapsedTimeDe, inSizeDe, outSizeDe)) / 2;
+}
+
+void CBenchmarkDialog::PrintRating(UInt64 rating, UINT controlID)
+{
+ TCHAR s[40];
+ ConvertUInt64ToString(rating / 1000000, s);
+ lstrcat(s, kMIPS);
+ SetItemText(controlID, s);
+}
+
+void CBenchmarkDialog::PrintResults(
+ UInt32 dictionarySize,
+ UInt64 elapsedTime,
+ UInt64 size, UINT speedID, UINT ratingID,
+ bool decompressMode, UInt64 secondSize)
+{
+ TCHAR s[40];
+ UInt64 speed = size * GetFreq() / elapsedTime;
+ ConvertUInt64ToString(speed / 1024, s);
+ lstrcat(s, kKBs);
+ SetItemText(speedID, s);
+ UInt64 rating;
+ if (decompressMode)
+ rating = GetDecompressRating(elapsedTime, size, secondSize);
+ else
+ rating = GetCompressRating(dictionarySize, elapsedTime, size);
+ PrintRating(rating, ratingID);
+}
+
+bool CBenchmarkDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */)
+{
+ PrintTime();
+ NWindows::NSynchronization::CCriticalSectionLock lock(_syncInfo.CS);
+
+ TCHAR s[40];
+ ConvertUInt64ToString((_syncInfo.ProcessedSize >> 20), s);
+ lstrcat(s, kMB);
+ SetItemText(IDC_BENCHMARK_SIZE_VALUE, s);
+
+ ConvertUInt64ToString(_syncInfo.NumPasses, s);
+ SetItemText(IDC_BENCHMARK_PASSES_VALUE, s);
+
+ ConvertUInt64ToString(_syncInfo.NumErrors, s);
+ SetItemText(IDC_BENCHMARK_ERRORS_VALUE, s);
+
+ UInt64 elapsedTime = _syncInfo.CompressingInfoTemp.Time;
+ if (elapsedTime >= 1)
+ {
+ UInt32 dicSizeTemp = (UInt32)MyMax(_syncInfo.ProcessedSize, UInt64(1) << 20);
+ dicSizeTemp = MyMin(dicSizeTemp, _syncInfo.DictionarySize),
+ PrintResults(dicSizeTemp, elapsedTime,
+ _syncInfo.CompressingInfoTemp.InSize,
+ IDC_BENCHMARK_COMPRESSING_SPEED,
+ IDC_BENCHMARK_COMPRESSING_RATING);
+ }
+
+ if (_syncInfo.CompressingInfo.Time >= 1)
+ {
+ PrintResults(
+ _syncInfo.DictionarySize,
+ _syncInfo.CompressingInfo.Time,
+ _syncInfo.CompressingInfo.InSize,
+ IDC_BENCHMARK_COMPRESSING_SPEED2,
+ IDC_BENCHMARK_COMPRESSING_RATING2);
+ }
+
+ if (_syncInfo.DecompressingInfoTemp.Time >= 1)
+ {
+ PrintResults(
+ _syncInfo.DictionarySize,
+ _syncInfo.DecompressingInfoTemp.Time,
+ _syncInfo.DecompressingInfoTemp.OutSize,
+ IDC_BENCHMARK_DECOMPRESSING_SPEED,
+ IDC_BENCHMARK_DECOMPRESSING_RATING,
+ true,
+ _syncInfo.DecompressingInfoTemp.InSize);
+ }
+ if (_syncInfo.DecompressingInfo.Time >= 1)
+ {
+ PrintResults(
+ _syncInfo.DictionarySize,
+ _syncInfo.DecompressingInfo.Time,
+ _syncInfo.DecompressingInfo.OutSize,
+ IDC_BENCHMARK_DECOMPRESSING_SPEED2,
+ IDC_BENCHMARK_DECOMPRESSING_RATING2,
+ true,
+ _syncInfo.DecompressingInfo.InSize);
+ if (_syncInfo.CompressingInfo.Time >= 1)
+ {
+ PrintRating(GetTotalRating(
+ _syncInfo.DictionarySize,
+ _syncInfo.CompressingInfo.Time,
+ _syncInfo.CompressingInfo.InSize,
+ _syncInfo.DecompressingInfo.Time,
+ _syncInfo.DecompressingInfo.OutSize,
+ _syncInfo.DecompressingInfo.InSize),
+ IDC_BENCHMARK_TOTAL_RATING_VALUE);
+ }
+ }
+ return true;
+}
+
+bool CBenchmarkDialog::OnCommand(int code, int itemID, LPARAM lParam)
+{
+ if (code == CBN_SELCHANGE && itemID == IDC_BENCHMARK_COMBO_DICTIONARY)
+ {
+ OnChangeSettings();
+ return true;
+ }
+ return CModalDialog::OnCommand(code, itemID, lParam);
+}
+
+bool CBenchmarkDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch(buttonID)
+ {
+ case IDC_BUTTON_RESTART:
+ OnRestartButton();
+ return true;
+ case IDC_BUTTON_STOP:
+ OnStopButton();
+ return true;
+ case IDC_BENCHMARK_MULTITHREADING:
+ OnChangeSettings();
+ return true;
+ }
+ return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
+}
+
+class CBenchmarkInStream:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ const Byte *Data;
+ UInt32 Pos;
+ UInt32 Size;
+public:
+ MY_UNKNOWN_IMP
+ void Init(const Byte *data, UInt32 size)
+ {
+ Data = data;
+ Size = size;
+ Pos = 0;
+ }
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 remain = Size - Pos;
+ 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;
+}
+
+class CBenchmarkOutStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ UInt32 BufferSize;
+public:
+ UInt32 Pos;
+ Byte *Buffer;
+ CBenchmarkOutStream(): Buffer(0) {}
+ ~CBenchmarkOutStream() { Free(); }
+ void Free()
+ {
+ ::MidFree(Buffer);
+ Buffer = 0;
+ }
+
+ bool Alloc(UInt32 bufferSize)
+ {
+ if (Buffer != 0 && BufferSize == bufferSize)
+ return true;
+ Free();
+ Buffer = (Byte *)::MidAlloc(bufferSize);
+ Init();
+ BufferSize = bufferSize;
+ return (Buffer != 0);
+ }
+
+ void Init()
+ {
+ Pos = 0;
+ }
+
+ MY_UNKNOWN_IMP
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 i;
+ for (i = 0; i < size && Pos < BufferSize; i++)
+ Buffer[Pos++] = ((const Byte *)data)[i];
+ if(processedSize != NULL)
+ *processedSize = i;
+ if (i != size)
+ {
+ MessageBoxW(0, L"Buffer is full", L"7-zip error", 0);
+ return E_FAIL;
+ }
+ return S_OK;
+}
+
+class CCompareOutStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ CCRC CRC;
+ MY_UNKNOWN_IMP
+ void Init() { CRC.Init(); }
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP CCompareOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ CRC.Update(data, size);
+ if(processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
+
+typedef UInt32 (WINAPI * CreateObjectPointer)(const GUID *clsID,
+ const GUID *interfaceID, void **outObject);
+
+struct CDecoderProgressInfo:
+ public ICompressProgressInfo,
+ public CMyUnknownImp
+{
+ CProgressSyncInfo *SyncInfo;
+ MY_UNKNOWN_IMP
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+};
+
+STDMETHODIMP CDecoderProgressInfo::SetRatioInfo(
+ const UInt64 * /* inSize */, const UInt64 * /* outSize */)
+{
+ NSynchronization::CCriticalSectionLock lock(SyncInfo->CS);
+ if (SyncInfo->Changed)
+ return E_ABORT;
+ return S_OK;
+}
+
+struct CThreadBenchmark:
+ public ICompressProgressInfo,
+ public CMyUnknownImp
+{
+ CProgressSyncInfo *SyncInfo;
+ UInt64 _startTime;
+ UInt64 _approvedStart;
+ NDLL::CLibrary Library;
+ CMyComPtr<ICompressCoder> Encoder;
+ CMyComPtr<ICompressCoder> Decoder;
+ HRESULT Process();
+ HRESULT Result;
+ static DWORD WINAPI MyThreadFunction(void *param)
+ {
+ ((CThreadBenchmark *)param)->Result = ((CThreadBenchmark *)param)->Process();
+ return 0;
+ }
+ MY_UNKNOWN_IMP
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+};
+
+HRESULT CThreadBenchmark::Process()
+{
+ try
+ {
+ SyncInfo->WaitCreating();
+ CBenchRandomGenerator randomGenerator;
+ CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
+ Encoder.QueryInterface(IID_ICompressWriteCoderProperties,
+ &writeCoderProperties);
+ CMyComPtr<ICompressSetDecoderProperties2> compressSetDecoderProperties;
+ Decoder.QueryInterface(
+ IID_ICompressSetDecoderProperties2, &compressSetDecoderProperties);
+ CSequentialOutStreamImp *propStreamSpec = 0;
+ CMyComPtr<ISequentialOutStream> propStream;
+ if (writeCoderProperties != NULL)
+ {
+ propStreamSpec = new CSequentialOutStreamImp;
+ propStream = propStreamSpec;
+ }
+
+ CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
+ Encoder.QueryInterface(IID_ICompressSetCoderProperties,
+ &setCoderProperties);
+
+ CDecoderProgressInfo *decoderProgressInfoSpec = new
+ CDecoderProgressInfo;
+ CMyComPtr<ICompressProgressInfo> decoderProgress = decoderProgressInfoSpec;
+ decoderProgressInfoSpec->SyncInfo = SyncInfo;
+
+ for (;;)
+ {
+ if (SyncInfo->WasStopped())
+ return 0;
+ if (SyncInfo->WasPaused())
+ {
+ Sleep(200);
+ continue;
+ }
+ UInt32 dictionarySize;
+ bool multiThread;
+ {
+ NSynchronization::CCriticalSectionLock lock(SyncInfo->CS);
+ dictionarySize = SyncInfo->DictionarySize;
+ multiThread = SyncInfo->MultiThread;
+ if (SyncInfo->Changed)
+ SyncInfo->Init();
+ }
+
+ const UInt32 kBufferSize = dictionarySize + kAdditionalSize;
+ const UInt32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize;
+
+ if (setCoderProperties)
+ {
+ PROPID propIDs[] =
+ {
+ NCoderPropID::kDictionarySize,
+ NCoderPropID::kMultiThread
+ };
+ const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);
+ NWindows::NCOM::CPropVariant properties[kNumProps];
+ properties[0] = UInt32(dictionarySize);
+ properties[1] = bool(multiThread);
+ HRESULT res = setCoderProperties->SetCoderProperties(propIDs,
+ properties, kNumProps);
+ if (res != S_OK)
+ {
+ // SyncInfo->Pause();
+ MessageBox(0, NError::MyFormatMessage(res), TEXT("7-Zip"), MB_ICONERROR);
+ return res;
+ }
+ }
+
+ if (propStream)
+ {
+ propStreamSpec->Init();
+ writeCoderProperties->WriteCoderProperties(propStream);
+ }
+
+ if (!randomGenerator.Alloc(kBufferSize))
+ return E_OUTOFMEMORY;
+
+ randomGenerator.Generate();
+ CCRC crc;
+
+ // randomGenerator.BufferSize
+ crc.Update(randomGenerator.Buffer, randomGenerator.BufferSize);
+
+ {
+ NSynchronization::CCriticalSectionLock lock(SyncInfo->CS);
+ if (SyncInfo->Changed)
+ continue;
+ }
+
+ CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream;
+ CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
+ CBenchmarkOutStream *outStreamSpec = new CBenchmarkOutStream;
+ CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
+ if (!outStreamSpec->Alloc(kCompressedBufferSize))
+ return E_OUTOFMEMORY;
+
+ {
+ // this code is for reducing time of memory allocationg
+ inStreamSpec->Init(randomGenerator.Buffer, MyMin((UInt32)1, randomGenerator.BufferSize));
+ outStreamSpec->Init();
+ /* HRESULT result = */ Encoder->Code(inStream, outStream, 0, 0, NULL);
+ }
+
+ inStreamSpec->Init(randomGenerator.Buffer, randomGenerator.BufferSize);
+ outStreamSpec->Init();
+
+ _approvedStart = dictionarySize;
+ _startTime = ::GetTimeCount();
+ HRESULT result = Encoder->Code(inStream, outStream, 0, 0, this);
+ UInt64 tickCount = ::GetTimeCount() - _startTime;
+ UInt32 compressedSize = outStreamSpec->Pos;
+ {
+ NSynchronization::CCriticalSectionLock lock(SyncInfo->CS);
+ if (result == S_OK)
+ {
+ if (SyncInfo->ApprovedInfo.InSize != 0)
+ {
+ SyncInfo->CompressingInfoTemp.InSize = kBufferSize - SyncInfo->ApprovedInfo.InSize;
+ SyncInfo->CompressingInfoTemp.OutSize = compressedSize - SyncInfo->ApprovedInfo.OutSize;
+ SyncInfo->CompressingInfoTemp.Time = tickCount - SyncInfo->ApprovedInfo.Time;
+ if (SyncInfo->CompressingInfo.Time == 0)
+ SyncInfo->CompressingInfo = SyncInfo->CompressingInfoTemp;
+ }
+ }
+ SyncInfo->ApprovedInfo.Init();
+ }
+ if(result != S_OK)
+ {
+ if (result != E_ABORT)
+ {
+ SyncInfo->Pause();
+ MessageBox(0, NError::MyFormatMessage(result), TEXT("7-Zip"), MB_ICONERROR);
+ }
+ continue;
+ }
+ {
+ NSynchronization::CCriticalSectionLock lock(SyncInfo->CS);
+ SyncInfo->NumPasses++;
+ }
+
+ ///////////////////////
+ // Decompressing
+
+
+ CCompareOutStream *outCompareStreamSpec = new CCompareOutStream;
+ CMyComPtr<ISequentialOutStream> outCompareStream = outCompareStreamSpec;
+
+ for (int i = 0; i < 2; i++)
+ {
+ inStreamSpec->Init(outStreamSpec->Buffer, compressedSize);
+ outCompareStreamSpec->Init();
+
+ if (compressSetDecoderProperties)
+ {
+ RINOK(compressSetDecoderProperties->SetDecoderProperties2(
+ propStreamSpec->GetBuffer(), (UInt32)propStreamSpec->GetSize()));
+ }
+
+ UInt64 outSize = kBufferSize;
+ UInt64 startTime = ::GetTimeCount();
+ result = Decoder->Code(inStream, outCompareStream, 0, &outSize, decoderProgress);
+ tickCount = ::GetTimeCount() - startTime;
+ {
+ NSynchronization::CCriticalSectionLock lock(SyncInfo->CS);
+ if (result == S_OK)
+ {
+ SyncInfo->DecompressingInfoTemp.InSize = compressedSize;
+ SyncInfo->DecompressingInfoTemp.OutSize = kBufferSize;
+ SyncInfo->DecompressingInfoTemp.Time = tickCount;
+ if (SyncInfo->DecompressingInfo.Time == 0 && i >= 1)
+ SyncInfo->DecompressingInfo = SyncInfo->DecompressingInfoTemp;
+ if (outCompareStreamSpec->CRC.GetDigest() != crc.GetDigest())
+ {
+ SyncInfo->NumErrors++;
+ break;
+ }
+ }
+ else
+ {
+ if(result != E_ABORT)
+ {
+ SyncInfo->NumErrors++;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ catch(CSystemException &e)
+ {
+ MessageBox(0, NError::MyFormatMessage(e.ErrorCode), TEXT("7-Zip"), MB_ICONERROR);
+ return E_FAIL;
+ }
+ catch(...)
+ {
+ MyMessageBoxError(0, L"Some error");
+ return E_FAIL;
+ }
+}
+
+STDMETHODIMP CThreadBenchmark::SetRatioInfo(
+ const UInt64 *inSize, const UInt64 *outSize)
+{
+ NSynchronization::CCriticalSectionLock lock(SyncInfo->CS);
+ if (SyncInfo->Changed || SyncInfo->WasPaused() || SyncInfo->WasStopped())
+ return E_ABORT;
+ CProgressInfo ci;
+ ci.InSize = *inSize;
+ ci.OutSize = *outSize;
+ ci.Time = ::GetTimeCount() - _startTime;
+ SyncInfo->ProcessedSize = *inSize;
+
+ UInt64 deltaTime = ci.Time - SyncInfo->CompressingInfoPrev.Time;
+ if (deltaTime >= GetFreq())
+ {
+ SyncInfo->CompressingInfoTemp.Time = deltaTime;
+ SyncInfo->CompressingInfoTemp.InSize = ci.InSize - SyncInfo->CompressingInfoPrev.InSize;
+ SyncInfo->CompressingInfoTemp.OutSize = ci.InSize - SyncInfo->CompressingInfoPrev.OutSize;
+ SyncInfo->CompressingInfoPrev = ci;
+ }
+ if (*inSize >= _approvedStart && SyncInfo->ApprovedInfo.InSize == 0)
+ SyncInfo->ApprovedInfo = ci;
+ return S_OK;
+}
+
+static bool GetCoderPath(UString &path)
+{
+ if (!GetProgramFolderPath(path))
+ return false;
+ path += L"Codecs\\LZMA.dll";
+ return true;
+}
+
+typedef UInt32 (WINAPI *GetMethodPropertyFunc)(
+ UInt32 index, PROPID propID, PROPVARIANT *value);
+
+static bool LoadCoder(
+ const UString &filePath,
+ NWindows::NDLL::CLibrary &library,
+ CLSID &encoder, CLSID &decoder)
+{
+ if (!library.Load(filePath))
+ return false;
+ GetMethodPropertyFunc getMethodProperty = (GetMethodPropertyFunc)
+ library.GetProcAddress("GetMethodProperty");
+ if (getMethodProperty == NULL)
+ return false;
+
+ NWindows::NCOM::CPropVariant propVariant;
+ if (getMethodProperty (0, NMethodPropID::kEncoder, &propVariant) != S_OK)
+ return false;
+ if (propVariant.vt != VT_BSTR)
+ return false;
+ encoder = *(const GUID *)propVariant.bstrVal;
+ propVariant.Clear();
+
+ if (getMethodProperty (0, NMethodPropID::kDecoder, &propVariant) != S_OK)
+ return false;
+ if (propVariant.vt != VT_BSTR)
+ return false;
+ decoder = *(const GUID *)propVariant.bstrVal;
+ propVariant.Clear();
+ return true;
+}
+
+void Benchmark(HWND hwnd)
+{
+ UString path;
+ if (!GetCoderPath(path))
+ {
+ MyMessageBoxError(hwnd, L"Can't find LZMA.dll");
+ return;
+ }
+ CLSID encoder;
+ CLSID decoder;
+ CThreadBenchmark benchmarker;
+ if (!LoadCoder(path, benchmarker.Library, encoder, decoder))
+ {
+ MyMessageBoxError(hwnd, L"Can't load LZMA.dll");
+ return;
+ }
+
+ CreateObjectPointer createObject = (CreateObjectPointer)
+ benchmarker.Library.GetProcAddress("CreateObject");
+ if (createObject == NULL)
+ {
+ MyMessageBoxError(hwnd, L"Incorrect LZMA.dll");
+ return;
+ }
+ if (createObject(&encoder, &IID_ICompressCoder, (void **)&benchmarker.Encoder) != S_OK)
+ {
+ MyMessageBoxError(hwnd, L"Can't create codec");
+ return;
+ }
+ if (createObject(&decoder, &IID_ICompressCoder, (void **)&benchmarker.Decoder) != S_OK)
+ {
+ MyMessageBoxError(hwnd, L"Can't create codec");
+ return;
+ }
+
+ CBenchmarkDialog benchmarkDialog;
+ benchmarker.SyncInfo = &benchmarkDialog._syncInfo;
+ CThread thread;
+ if (!thread.Create(CThreadBenchmark::MyThreadFunction, &benchmarker))
+ {
+ MyMessageBoxError(hwnd, L"error");
+ return;
+ }
+ benchmarkDialog.Create(hwnd);
+ WaitForSingleObject(thread, INFINITE);
+}
diff --git a/CPP/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.h b/CPP/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.h
new file mode 100755
index 00000000..244e7fe5
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.h
@@ -0,0 +1,136 @@
+// BenchmarkDialog.h
+
+#ifndef __BENCHMARKDIALOG_H
+#define __BENCHMARKDIALOG_H
+
+#include "resource.h"
+
+#include "Common/MyCom.h"
+#include "Windows/Control/Dialog.h"
+#include "Windows/Control/ComboBox.h"
+#include "Windows/Synchronization.h"
+#include "../../../ICoder.h"
+
+const int kNumBenchDictionaryBitsStart = 21;
+
+struct CProgressInfo
+{
+ UINT64 InSize;
+ UINT64 OutSize;
+ UINT64 Time;
+ void Init()
+ {
+ InSize = 0;
+ OutSize = 0;
+ Time = 0;
+ }
+};
+
+class CProgressSyncInfo
+{
+ bool Stopped;
+ bool Paused;
+public:
+ bool Changed;
+ UINT32 DictionarySize;
+ bool MultiThread;
+ UINT64 NumPasses;
+ UINT64 NumErrors;
+ NWindows::NSynchronization::CManualResetEvent _startEvent;
+ NWindows::NSynchronization::CCriticalSection CS;
+
+ CProgressInfo ApprovedInfo;
+ CProgressInfo CompressingInfoPrev;
+ CProgressInfo CompressingInfoTemp;
+ CProgressInfo CompressingInfo;
+ UINT64 ProcessedSize;
+
+ CProgressInfo DecompressingInfoTemp;
+ CProgressInfo DecompressingInfo;
+
+ void Init()
+ {
+ Changed = false;
+ ApprovedInfo.Init();
+ CompressingInfoPrev.Init();
+ CompressingInfoTemp.Init();
+ CompressingInfo.Init();
+ ProcessedSize = 0;
+
+ DecompressingInfoTemp.Init();
+ DecompressingInfo.Init();
+
+ Stopped = false;
+ Paused = false;
+ NumPasses = 0;
+ NumErrors = 0;
+ }
+ void InitSettings()
+ {
+ DictionarySize = (1 << kNumBenchDictionaryBitsStart);
+ MultiThread = false;
+ }
+ void Stop()
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(CS);
+ Stopped = true;
+ }
+ bool WasStopped()
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(CS);
+ return Stopped;
+ }
+ void Pause()
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(CS);
+ Paused = true;
+ }
+ void Start()
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(CS);
+ Paused = false;
+ }
+ bool WasPaused()
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(CS);
+ return Paused;
+ }
+ void WaitCreating() { _startEvent.Lock(); }
+};
+
+class CBenchmarkDialog:
+ public NWindows::NControl::CModalDialog
+{
+ NWindows::NControl::CComboBox m_Dictionary;
+ UINT_PTR _timer;
+ UINT32 _startTime;
+
+ bool OnTimer(WPARAM timerID, LPARAM callback);
+ virtual bool OnInit();
+ void OnRestartButton();
+ void OnStopButton();
+ void OnHelp();
+ virtual void OnCancel();
+ bool OnButtonClicked(int buttonID, HWND buttonHWND);
+ bool OnCommand(int code, int itemID, LPARAM lParam);
+
+ void PrintTime();
+ void PrintRating(UINT64 rating, UINT controlID);
+ void PrintResults(
+ UINT32 dictionarySize,
+ UINT64 elapsedTime,
+ UINT64 size, UINT speedID, UINT ratingID,
+ bool decompressMode = false, UINT64 secondSize = 0);
+
+ UINT32 OnChangeDictionary();
+ void OnChangeSettings();
+public:
+ CProgressSyncInfo _syncInfo;
+
+ CBenchmarkDialog(): _timer(0) {}
+ INT_PTR Create(HWND wndParent = 0) { return CModalDialog::Create(IDD_DIALOG_BENCHMARK, wndParent); }
+};
+
+void Benchmark(HWND hwnd);
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/BenchmarkDialog/StdAfx.h b/CPP/7zip/FileManager/Resource/BenchmarkDialog/StdAfx.h
new file mode 100755
index 00000000..a444ca31
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/BenchmarkDialog/StdAfx.h
@@ -0,0 +1,16 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#define _WIN32_WINNT 0x0400
+
+// it's for Windows NT supporting (MENUITEMINFOW)
+#define WINVER 0x0400
+
+#include <windows.h>
+#include <commctrl.h>
+
+#include "Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/BenchmarkDialog/resource.h b/CPP/7zip/FileManager/Resource/BenchmarkDialog/resource.h
new file mode 100755
index 00000000..d720058d
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/BenchmarkDialog/resource.h
@@ -0,0 +1,34 @@
+#define IDD_DIALOG_BENCHMARK 800
+#define IDC_BUTTON_STOP 1001
+#define IDC_BUTTON_RESTART 1002
+#define IDC_BENCHMARK_DICTIONARY 1010
+#define IDC_BENCHMARK_COMBO_DICTIONARY 1011
+#define IDC_BENCHMARK_MEMORY 1012
+#define IDC_BENCHMARK_MEMORY_VALUE 1013
+#define IDC_BENCHMARK_MULTITHREADING 1014
+#define IDC_BENCHMARK_SPEED_LABEL 1020
+#define IDC_BENCHMARK_RATING_LABEL 1021
+#define IDC_BENCHMARK_COMPRESSING 1022
+#define IDC_BENCHMARK_DECOMPRESSING 1023
+#define IDC_BENCHMARK_CURRENT 1024
+#define IDC_BENCHMARK_RESULTING 1025
+#define IDC_BENCHMARK_CURRENT2 1026
+#define IDC_BENCHMARK_RESULTING2 1027
+#define IDC_BENCHMARK_COMPRESSING_SPEED 1030
+#define IDC_BENCHMARK_COMPRESSING_SPEED2 1031
+#define IDC_BENCHMARK_COMPRESSING_RATING 1032
+#define IDC_BENCHMARK_COMPRESSING_RATING2 1033
+#define IDC_BENCHMARK_DECOMPRESSING_SPEED 1040
+#define IDC_BENCHMARK_DECOMPRESSING_SPEED2 1041
+#define IDC_BENCHMARK_DECOMPRESSING_RATING 1042
+#define IDC_BENCHMARK_DECOMPRESSING_RATING2 1043
+#define IDC_BENCHMARK_TOTAL_RATING 1050
+#define IDC_BENCHMARK_TOTAL_RATING_VALUE 1051
+#define IDC_BENCHMARK_ELAPSED 1060
+#define IDC_BENCHMARK_ELAPSED_VALUE 1061
+#define IDC_BENCHMARK_SIZE 1062
+#define IDC_BENCHMARK_SIZE_VALUE 1063
+#define IDC_BENCHMARK_ERRORS 1064
+#define IDC_BENCHMARK_ERRORS_VALUE 1065
+#define IDC_BENCHMARK_PASSES 1066
+#define IDC_BENCHMARK_PASSES_VALUE 1067
diff --git a/CPP/7zip/FileManager/Resource/BenchmarkDialog/resource.rc b/CPP/7zip/FileManager/Resource/BenchmarkDialog/resource.rc
new file mode 100755
index 00000000..5ab220e5
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/BenchmarkDialog/resource.rc
@@ -0,0 +1,87 @@
+#include "resource.h"
+#include "../../../GuiCommon.rc"
+
+#define xSize2 210
+#define ySize2 228
+
+#define xSize (xSize2 + marg + marg)
+#define ySize (ySize2 + marg + marg)
+
+#define bXPos1 (xSize - marg - bXSize)
+#define bXPos2 (bXPos1 - 10 - bXSize)
+
+#define bYPos (ySize - marg - bYSize)
+
+#define gSize 160
+#define gSpace 24
+
+#define g0XSize 75
+#define g1XSize 44
+#define g1XPos (marg + g0XSize)
+
+#define g10XPos (marg + marg)
+#define gRatingSize 51
+#define gSpeedSize 64
+#define gRatingPos (xSize - marg - marg - gRatingSize)
+#define gSpeedPos (gRatingPos - gSpeedSize)
+#define gLabelSize (gSpeedPos - g10XPos)
+#define gTotalRatingSize (gRatingSize + marg + marg)
+#define gTotalRatingPos (xSize - marg - gTotalRatingSize)
+
+#define g2XSize 58
+#define g3XSize 36
+#define g3XPos (marg + g2XSize)
+
+
+IDD_DIALOG_BENCHMARK DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE | WS_MINIMIZEBOX
+CAPTION "Benchmark"
+MY_FONT
+BEGIN
+ PUSHBUTTON "&Restart", IDC_BUTTON_RESTART, bXPos1, marg, bXSize, bYSize
+ PUSHBUTTON "&Stop", IDC_BUTTON_STOP, bXPos1, 27, bXSize, bYSize
+
+ PUSHBUTTON "&Help", IDHELP, bXPos2, bYPos, bXSize,bYSize
+ PUSHBUTTON "Cancel", IDCANCEL, bXPos1, bYPos, bXSize, bYSize
+
+ LTEXT "&Dictionary size:", IDC_BENCHMARK_DICTIONARY, marg, marg + 1, g0XSize, 8
+ COMBOBOX IDC_BENCHMARK_COMBO_DICTIONARY, g1XPos, marg, g1XSize, 140, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "Memory usage:", IDC_BENCHMARK_MEMORY, marg, 25, g0XSize, 8
+ LTEXT "0 MB", IDC_BENCHMARK_MEMORY_VALUE, g1XPos,25,g1XSize,8
+ CONTROL "Multi-threading", IDC_BENCHMARK_MULTITHREADING, "Button", BS_AUTOCHECKBOX | WS_TABSTOP,
+ marg, 41, g0XSize, 10
+
+ RTEXT "Speed", IDC_BENCHMARK_SPEED_LABEL, gSpeedPos, 53, gSpeedSize, 8
+ RTEXT "Rating", IDC_BENCHMARK_RATING_LABEL, gRatingPos, 53, gRatingSize, 8
+
+ GROUPBOX "Compressing", IDC_BENCHMARK_COMPRESSING, marg, 64, xSize2, 40
+
+ LTEXT "Current", IDC_BENCHMARK_CURRENT, g10XPos, 76, gLabelSize, 8
+ RTEXT "100 KB/s", IDC_BENCHMARK_COMPRESSING_SPEED, gSpeedPos, 76, gSpeedSize, 8
+ RTEXT "0", IDC_BENCHMARK_COMPRESSING_RATING, gRatingPos, 76, gRatingSize, 8
+
+ LTEXT "Resulting", IDC_BENCHMARK_RESULTING, g10XPos, 89, gLabelSize, 8
+ RTEXT "100 KB/s", IDC_BENCHMARK_COMPRESSING_SPEED2, gSpeedPos, 89, gSpeedSize, 8
+ RTEXT "0", IDC_BENCHMARK_COMPRESSING_RATING2, gRatingPos, 89, gRatingSize, 8
+
+ GROUPBOX "Decompressing", IDC_BENCHMARK_DECOMPRESSING, marg, 111, xSize2, 40
+
+ LTEXT "Current", IDC_BENCHMARK_CURRENT2, g10XPos, 123, gLabelSize, 8
+ RTEXT "100 KB/s", IDC_BENCHMARK_DECOMPRESSING_SPEED, gSpeedPos, 123, gSpeedSize, 8
+ RTEXT "0", IDC_BENCHMARK_DECOMPRESSING_RATING, gRatingPos, 123, gRatingSize, 8
+
+ LTEXT "Resulting", IDC_BENCHMARK_RESULTING2, g10XPos, 136, gLabelSize, 8
+ RTEXT "100 KB/s", IDC_BENCHMARK_DECOMPRESSING_SPEED2, gSpeedPos, 136, gSpeedSize, 8
+ RTEXT "0", IDC_BENCHMARK_DECOMPRESSING_RATING2, gRatingPos, 136, gRatingSize, 8
+
+ GROUPBOX "Total Rating", IDC_BENCHMARK_TOTAL_RATING, gTotalRatingPos, 163, gTotalRatingSize, 38
+ RTEXT "0", IDC_BENCHMARK_TOTAL_RATING_VALUE, gRatingPos, 181, gRatingSize, 8
+
+ LTEXT "Elapsed time:", IDC_BENCHMARK_ELAPSED, marg, 163, g2XSize, 8
+ LTEXT "Size:", IDC_BENCHMARK_SIZE, marg, 176, g2XSize, 8
+ LTEXT "Passes:", IDC_BENCHMARK_PASSES, marg, 189, g2XSize, 8
+ LTEXT "Errors:", IDC_BENCHMARK_ERRORS, marg, 202, g2XSize, 8
+ RTEXT "00:00:00", IDC_BENCHMARK_ELAPSED_VALUE, g3XPos, 163, g3XSize, 8
+ RTEXT "0", IDC_BENCHMARK_SIZE_VALUE, g3XPos, 176, g3XSize, 8
+ RTEXT "0", IDC_BENCHMARK_PASSES_VALUE, g3XPos, 189, g3XSize, 8
+ RTEXT "0", IDC_BENCHMARK_ERRORS_VALUE, g3XPos, 202, g3XSize, 8
+END
diff --git a/CPP/7zip/FileManager/Resource/ComboDialog/ComboDialog.cpp b/CPP/7zip/FileManager/Resource/ComboDialog/ComboDialog.cpp
new file mode 100755
index 00000000..2dc42ee0
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/ComboDialog/ComboDialog.cpp
@@ -0,0 +1,53 @@
+// ComboDialog.cpp
+
+#include "StdAfx.h"
+#include "ComboDialog.h"
+
+#include "Windows/Control/Static.h"
+
+#ifdef LANG
+#include "../../LangUtils.h"
+#endif
+
+using namespace NWindows;
+
+#ifdef LANG
+static CIDLangPair kIDLangPairs[] =
+{
+ { IDOK, 0x02000702 },
+ { IDCANCEL, 0x02000710 }
+};
+#endif
+
+bool CComboDialog::OnInit()
+{
+ #ifdef LANG
+ LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
+ #endif
+ _comboBox.Attach(GetItem(IDC_COMBO_COMBO));
+
+ /*
+ // why it doesn't work ?
+ DWORD style = _comboBox.GetStyle();
+ if (Sorted)
+ style |= CBS_SORT;
+ else
+ style &= ~CBS_SORT;
+ _comboBox.SetStyle(style);
+ */
+ SetText(Title);
+
+ NControl::CStatic staticContol;
+ staticContol.Attach(GetItem(IDC_COMBO_STATIC));
+ staticContol.SetText(Static);
+ _comboBox.SetText(Value);
+ for(int i = 0; i < Strings.Size(); i++)
+ _comboBox.AddString(Strings[i]);
+ return CModalDialog::OnInit();
+}
+
+void CComboDialog::OnOK()
+{
+ _comboBox.GetText(Value);
+ CModalDialog::OnOK();
+}
diff --git a/CPP/7zip/FileManager/Resource/ComboDialog/ComboDialog.h b/CPP/7zip/FileManager/Resource/ComboDialog/ComboDialog.h
new file mode 100755
index 00000000..1838783d
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/ComboDialog/ComboDialog.h
@@ -0,0 +1,25 @@
+// ComboDialog.h
+
+#ifndef __COMBODIALOG_H
+#define __COMBODIALOG_H
+
+#include "Windows/Control/Dialog.h"
+#include "Windows/Control/ComboBox.h"
+#include "resource.h"
+
+class CComboDialog: public NWindows::NControl::CModalDialog
+{
+ NWindows::NControl::CComboBox _comboBox;
+ virtual void OnOK();
+ virtual bool OnInit();
+public:
+ // bool Sorted;
+ UString Title;
+ UString Static;
+ UString Value;
+ UStringVector Strings;
+ // CComboDialog(): Sorted(false) {};
+ INT_PTR Create(HWND parentWindow = 0) { return CModalDialog::Create(IDD_DIALOG_COMBO, parentWindow); }
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/ComboDialog/StdAfx.h b/CPP/7zip/FileManager/Resource/ComboDialog/StdAfx.h
new file mode 100755
index 00000000..a444ca31
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/ComboDialog/StdAfx.h
@@ -0,0 +1,16 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#define _WIN32_WINNT 0x0400
+
+// it's for Windows NT supporting (MENUITEMINFOW)
+#define WINVER 0x0400
+
+#include <windows.h>
+#include <commctrl.h>
+
+#include "Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/ComboDialog/resource.h b/CPP/7zip/FileManager/Resource/ComboDialog/resource.h
new file mode 100755
index 00000000..b5111ddf
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/ComboDialog/resource.h
@@ -0,0 +1,4 @@
+#define IDD_DIALOG_COMBO 200
+
+#define IDC_COMBO_STATIC 1000
+#define IDC_COMBO_COMBO 1001
diff --git a/CPP/7zip/FileManager/Resource/ComboDialog/resource.rc b/CPP/7zip/FileManager/Resource/ComboDialog/resource.rc
new file mode 100755
index 00000000..7bf25365
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/ComboDialog/resource.rc
@@ -0,0 +1,24 @@
+#include "resource.h"
+#include "../../../GuiCommon.rc"
+
+#define xSize2 233
+#define ySize2 57
+
+#define xSize (xSize2 + marg + marg)
+#define ySize (ySize2 + marg + marg)
+
+#define bYPos (ySize - marg - bYSize)
+#define b1XPos (xSize - marg - bXSize)
+#define b2XPos (b1XPos - 10 - bXSize)
+
+
+IDD_DIALOG_COMBO DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE
+CAPTION "Combo"
+MY_FONT
+BEGIN
+ LTEXT "", IDC_COMBO_STATIC, marg, marg, xSize2, 8
+ COMBOBOX IDC_COMBO_COMBO, marg, 20, xSize2, 65, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+
+ DEFPUSHBUTTON "OK", IDOK, b2XPos, bYPos, bXSize, bYSize
+ PUSHBUTTON "Cancel", IDCANCEL, b1XPos, bYPos, bXSize, bYSize
+END
diff --git a/CPP/7zip/FileManager/Resource/CopyDialog/CopyDialog.cpp b/CPP/7zip/FileManager/Resource/CopyDialog/CopyDialog.cpp
new file mode 100755
index 00000000..c0bcf2bc
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/CopyDialog/CopyDialog.cpp
@@ -0,0 +1,81 @@
+// CopyDialog.cpp
+
+#include "StdAfx.h"
+#include "CopyDialog.h"
+
+#include "Common/StringConvert.h"
+
+#include "Windows/Control/Static.h"
+#include "Windows/Shell.h"
+#include "Windows/FileName.h"
+
+#ifdef LANG
+#include "../../LangUtils.h"
+#endif
+
+using namespace NWindows;
+
+#ifdef LANG
+static CIDLangPair kIDLangPairs[] =
+{
+ { IDOK, 0x02000702 },
+ { IDCANCEL, 0x02000710 }
+};
+#endif
+
+bool CCopyDialog::OnInit()
+{
+ #ifdef LANG
+ LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
+ #endif
+ _path.Attach(GetItem(IDC_COPY_COMBO));
+ SetText(Title);
+
+ NControl::CStatic staticContol;
+ staticContol.Attach(GetItem(IDC_COPY_STATIC));
+ staticContol.SetText(Static);
+ for(int i = 0; i < Strings.Size(); i++)
+ _path.AddString(Strings[i]);
+ _path.SetText(Value);
+ return CModalDialog::OnInit();
+}
+
+bool CCopyDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch(buttonID)
+ {
+ case IDC_COPY_SET_PATH:
+ OnButtonSetPath();
+ return true;
+ }
+ return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
+}
+
+void CCopyDialog::OnButtonSetPath()
+{
+ UString currentPath;
+ _path.GetText(currentPath);
+
+ /*
+ #ifdef LANG
+ UString title = LangLoadString(IDS_EXTRACT_SET_FOLDER, 0x02000881);
+ #else
+ UString title = MyLoadString(IDS_EXTRACT_SET_FOLDER);
+ #endif
+ */
+ UString title = LangStringSpec(IDS_SET_FOLDER, 0x03020209);
+ // UString title = L"Specify a location for output folder";
+
+ UString resultPath;
+ if (!NShell::BrowseForFolder(HWND(*this), title, currentPath, resultPath))
+ return;
+ NFile::NName::NormalizeDirPathPrefix(resultPath);
+ _path.SetCurSel(-1);
+ _path.SetText(resultPath);
+}
+
+void CCopyDialog::OnOK()
+{
+ _path.GetText(Value);
+ CModalDialog::OnOK();
+}
diff --git a/CPP/7zip/FileManager/Resource/CopyDialog/CopyDialog.h b/CPP/7zip/FileManager/Resource/CopyDialog/CopyDialog.h
new file mode 100755
index 00000000..353f6807
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/CopyDialog/CopyDialog.h
@@ -0,0 +1,26 @@
+// CopyDialog.h
+
+#ifndef __COPYDIALOG_H
+#define __COPYDIALOG_H
+
+#include "Windows/Control/Dialog.h"
+#include "Windows/Control/ComboBox.h"
+#include "resource.h"
+
+class CCopyDialog: public NWindows::NControl::CModalDialog
+{
+ NWindows::NControl::CComboBox _path;
+ virtual void OnOK();
+ virtual bool OnInit();
+ void OnButtonSetPath();
+ bool OnButtonClicked(int buttonID, HWND buttonHWND);
+public:
+ UString Title;
+ UString Static;
+ UString Value;
+ UStringVector Strings;
+
+ INT_PTR Create(HWND parentWindow = 0) { return CModalDialog::Create(IDD_DIALOG_COPY, parentWindow); }
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/CopyDialog/StdAfx.h b/CPP/7zip/FileManager/Resource/CopyDialog/StdAfx.h
new file mode 100755
index 00000000..a444ca31
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/CopyDialog/StdAfx.h
@@ -0,0 +1,16 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#define _WIN32_WINNT 0x0400
+
+// it's for Windows NT supporting (MENUITEMINFOW)
+#define WINVER 0x0400
+
+#include <windows.h>
+#include <commctrl.h>
+
+#include "Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/CopyDialog/resource.h b/CPP/7zip/FileManager/Resource/CopyDialog/resource.h
new file mode 100755
index 00000000..7ec6162a
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/CopyDialog/resource.h
@@ -0,0 +1,7 @@
+#define IDD_DIALOG_COPY 202
+
+#define IDC_COPY_STATIC 1000
+#define IDC_COPY_COMBO 1001
+#define IDC_COPY_SET_PATH 1002
+
+#define IDS_SET_FOLDER 210
diff --git a/CPP/7zip/FileManager/Resource/CopyDialog/resource.rc b/CPP/7zip/FileManager/Resource/CopyDialog/resource.rc
new file mode 100755
index 00000000..156b56cf
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/CopyDialog/resource.rc
@@ -0,0 +1,28 @@
+#include "resource.h"
+#include "../../../GuiCommon.rc"
+
+#define xSize2 346
+#define ySize2 57
+
+#define xSize (xSize2 + marg + marg)
+#define ySize (ySize2 + marg + marg)
+
+#define bYPos (ySize - marg - bYSize)
+#define b1XPos (xSize - marg - bXSize)
+#define b2XPos (b1XPos - 10 - bXSize)
+
+IDD_DIALOG_COPY DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE
+CAPTION "Copy"
+MY_FONT
+BEGIN
+ LTEXT "", IDC_COPY_STATIC, marg, marg, xSize2, 8
+ COMBOBOX IDC_COPY_COMBO, marg, 20, xSize2 - bDotsSize - 12, 65, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "...", IDC_COPY_SET_PATH, (xSize - marg - bDotsSize), 20, bDotsSize, 14, WS_GROUP
+ DEFPUSHBUTTON "OK", IDOK, b2XPos, bYPos, bXSize, bYSize
+ PUSHBUTTON "Cancel", IDCANCEL, b1XPos, bYPos, bXSize, bYSize
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_SET_FOLDER "Specify a location for output folder."
+END
diff --git a/CPP/7zip/FileManager/Resource/EditPage/EditPage.cpp b/CPP/7zip/FileManager/Resource/EditPage/EditPage.cpp
new file mode 100755
index 00000000..0e6e1d71
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/EditPage/EditPage.cpp
@@ -0,0 +1,91 @@
+// EditPage.cpp
+
+#include "StdAfx.h"
+#include "resource.h"
+#include "EditPage.h"
+
+#include "Common/StringConvert.h"
+
+#include "Windows/Defs.h"
+#include "Windows/CommonDialog.h"
+// #include "Windows/FileFind.h"
+// #include "Windows/FileDir.h"
+
+#include "../../RegistryUtils.h"
+#include "../../HelpUtils.h"
+#include "../../LangUtils.h"
+#include "../../ProgramLocation.h"
+
+using namespace NWindows;
+
+static CIDLangPair kIDLangPairs[] =
+{
+ { IDC_EDIT_STATIC_EDITOR, 0x03010201}
+};
+
+static LPCWSTR kEditTopic = L"FM/options.htm#editor";
+
+bool CEditPage::OnInit()
+{
+ LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
+
+ _editorEdit.Attach(GetItem(IDC_EDIT_EDIT_EDITOR));
+ UString editorPath;
+ ReadRegEditor(editorPath);
+ _editorEdit.SetText(editorPath);
+ return CPropertyPage::OnInit();
+}
+
+LONG CEditPage::OnApply()
+{
+ // int selectedIndex = _langCombo.GetCurSel();
+ // int pathIndex = _langCombo.GetItemData(selectedIndex);
+ // ReloadLang();
+ UString editorPath;
+ _editorEdit.GetText(editorPath);
+ SaveRegEditor(editorPath);
+ return PSNRET_NOERROR;
+}
+
+void CEditPage::OnNotifyHelp()
+{
+ ShowHelpWindow(NULL, kEditTopic); // change it
+}
+
+bool CEditPage::OnButtonClicked(int aButtonID, HWND aButtonHWND)
+{
+ switch(aButtonID)
+ {
+ case IDC_EDIT_BUTTON_SET:
+ {
+ OnSetEditorButton();
+ // if (!NShell::BrowseForFolder(HWND(*this), title, currentPath, aResultPath))
+ // return;
+ return true;
+ }
+ }
+ return CPropertyPage::OnButtonClicked(aButtonID, aButtonHWND);
+}
+
+void CEditPage::OnSetEditorButton()
+{
+ UString editorPath;
+ _editorEdit.GetText(editorPath);
+ UString resPath;
+ if(!MyGetOpenFileName(HWND(*this), 0, editorPath, L"*.exe", resPath))
+ return;
+ _editorEdit.SetText(resPath);
+ // Changed();
+}
+
+bool CEditPage::OnCommand(int code, int itemID, LPARAM param)
+{
+ if (code == EN_CHANGE && itemID == IDC_EDIT_EDIT_EDITOR)
+ {
+ Changed();
+ return true;
+ }
+ return CPropertyPage::OnCommand(code, itemID, param);
+}
+
+
diff --git a/CPP/7zip/FileManager/Resource/EditPage/EditPage.h b/CPP/7zip/FileManager/Resource/EditPage/EditPage.h
new file mode 100755
index 00000000..26999dcf
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/EditPage/EditPage.h
@@ -0,0 +1,21 @@
+// EditPage.h
+
+#ifndef __EDITPAGE_H
+#define __EDITPAGE_H
+
+#include "Windows/Control/PropertyPage.h"
+#include "Windows/Control/Edit.h"
+
+class CEditPage: public NWindows::NControl::CPropertyPage
+{
+ NWindows::NControl::CEdit _editorEdit;
+ void OnSetEditorButton();
+public:
+ virtual bool OnInit();
+ virtual void OnNotifyHelp();
+ virtual bool OnCommand(int code, int itemID, LPARAM param);
+ virtual LONG OnApply();
+ virtual bool OnButtonClicked(int aButtonID, HWND aButtonHWND);
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/EditPage/StdAfx.h b/CPP/7zip/FileManager/Resource/EditPage/StdAfx.h
new file mode 100755
index 00000000..a444ca31
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/EditPage/StdAfx.h
@@ -0,0 +1,16 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#define _WIN32_WINNT 0x0400
+
+// it's for Windows NT supporting (MENUITEMINFOW)
+#define WINVER 0x0400
+
+#include <windows.h>
+#include <commctrl.h>
+
+#include "Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/EditPage/resource.h b/CPP/7zip/FileManager/Resource/EditPage/resource.h
new file mode 100755
index 00000000..a2de1970
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/EditPage/resource.h
@@ -0,0 +1,4 @@
+#define IDD_EDIT 903
+#define IDC_EDIT_STATIC_EDITOR 1000
+#define IDC_EDIT_EDIT_EDITOR 1002
+#define IDC_EDIT_BUTTON_SET 1003
diff --git a/CPP/7zip/FileManager/Resource/EditPage/resource.rc b/CPP/7zip/FileManager/Resource/EditPage/resource.rc
new file mode 100755
index 00000000..d4d8b9cd
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/EditPage/resource.rc
@@ -0,0 +1,16 @@
+#include "resource.h"
+#include "../../../GuiCommon.rc"
+
+#define xSize2 196
+#define ySize2 140
+#define xSize (xSize2 + marg + marg)
+#define ySize (ySize2 + marg + marg)
+
+IDD_EDIT DIALOG 0, 0, xSize, ySize MY_PAGE_STYLE
+CAPTION "Editor"
+MY_FONT
+BEGIN
+ LTEXT "&Editor:", IDC_EDIT_STATIC_EDITOR, marg, marg, xSize2, 8
+ EDITTEXT IDC_EDIT_EDIT_EDITOR, marg, 20, xSize2 - 12 - bDotsSize, 14, ES_AUTOHSCROLL
+ PUSHBUTTON "...", IDC_EDIT_BUTTON_SET, (xSize - marg - bDotsSize), 20, bDotsSize, bYSize
+END
diff --git a/CPP/7zip/FileManager/Resource/LangPage/LangPage.cpp b/CPP/7zip/FileManager/Resource/LangPage/LangPage.cpp
new file mode 100755
index 00000000..9974759a
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/LangPage/LangPage.cpp
@@ -0,0 +1,90 @@
+// LangPage.cpp
+
+#include "StdAfx.h"
+#include "resource.h"
+#include "LangPage.h"
+
+#include "Common/StringConvert.h"
+
+#include "Windows/ResourceString.h"
+
+#include "../../RegistryUtils.h"
+#include "../../HelpUtils.h"
+#include "../../LangUtils.h"
+
+static CIDLangPair kIDLangPairs[] =
+{
+ { IDC_LANG_STATIC_LANG, 0x01000401}
+};
+
+static LPCWSTR kLangTopic = L"fm/options.htm#language";
+
+bool CLangPage::OnInit()
+{
+ _langWasChanged = false;
+ LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
+
+ _langCombo.Attach(GetItem(IDC_LANG_COMBO_LANG));
+
+ UString s = NWindows::MyLoadStringW(IDS_LANG_ENGLISH);
+ s += L" (";
+ s += NWindows::MyLoadStringW(IDS_LANG_NATIVE);
+ s += L")";
+ int index = (int)_langCombo.AddString(s);
+ _langCombo.SetItemData(index, _paths.Size());
+ _paths.Add(L"-");
+ _langCombo.SetCurSel(0);
+
+ CObjectVector<CLangEx> langs;
+ LoadLangs(langs);
+ for (int i = 0; i < langs.Size(); i++)
+ {
+ const CLangEx &lang = langs[i];
+ UString name;
+ UString englishName, nationalName;
+ if (lang.Lang.GetMessage(0x00000000, englishName))
+ name = englishName;
+ else
+ name = lang.ShortName;
+ if (lang.Lang.GetMessage(0x00000001, nationalName))
+ {
+ if (!nationalName.IsEmpty())
+ {
+ name += L" (";
+ name += nationalName;
+ name += L")";
+ }
+ }
+ index = (int)_langCombo.AddString(name);
+ _langCombo.SetItemData(index, _paths.Size());
+ _paths.Add(lang.ShortName);
+ if (g_LangID.CompareNoCase(lang.ShortName) == 0)
+ _langCombo.SetCurSel(index);
+ }
+ return CPropertyPage::OnInit();
+}
+
+LONG CLangPage::OnApply()
+{
+ int selectedIndex = _langCombo.GetCurSel();
+ int pathIndex = (int)_langCombo.GetItemData(selectedIndex);
+ SaveRegLang(_paths[pathIndex]);
+ ReloadLang();
+ _langWasChanged = true;
+ return PSNRET_NOERROR;
+}
+
+void CLangPage::OnNotifyHelp()
+{
+ ShowHelpWindow(NULL, kLangTopic); // change it
+}
+
+bool CLangPage::OnCommand(int code, int itemID, LPARAM param)
+{
+ if (code == CBN_SELCHANGE && itemID == IDC_LANG_COMBO_LANG)
+ {
+ Changed();
+ return true;
+ }
+ return CPropertyPage::OnCommand(code, itemID, param);
+}
diff --git a/CPP/7zip/FileManager/Resource/LangPage/LangPage.h b/CPP/7zip/FileManager/Resource/LangPage/LangPage.h
new file mode 100755
index 00000000..b28d6984
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/LangPage/LangPage.h
@@ -0,0 +1,21 @@
+// LangPage.h
+
+#ifndef __LANGPAGE_H
+#define __LANGPAGE_H
+
+#include "Windows/Control/PropertyPage.h"
+#include "Windows/Control/ComboBox.h"
+
+class CLangPage: public NWindows::NControl::CPropertyPage
+{
+ NWindows::NControl::CComboBox _langCombo;
+ UStringVector _paths;
+public:
+ bool _langWasChanged;
+ virtual bool OnInit();
+ virtual void OnNotifyHelp();
+ virtual bool OnCommand(int code, int itemID, LPARAM param);
+ virtual LONG OnApply();
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/LangPage/StdAfx.h b/CPP/7zip/FileManager/Resource/LangPage/StdAfx.h
new file mode 100755
index 00000000..a444ca31
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/LangPage/StdAfx.h
@@ -0,0 +1,16 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#define _WIN32_WINNT 0x0400
+
+// it's for Windows NT supporting (MENUITEMINFOW)
+#define WINVER 0x0400
+
+#include <windows.h>
+#include <commctrl.h>
+
+#include "Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/LangPage/resource.h b/CPP/7zip/FileManager/Resource/LangPage/resource.h
new file mode 100755
index 00000000..39571e53
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/LangPage/resource.h
@@ -0,0 +1,6 @@
+#define IDD_LANG 900
+#define IDS_LANG_ENGLISH 995
+#define IDS_LANG_NATIVE 996
+
+#define IDC_LANG_STATIC_LANG 1000
+#define IDC_LANG_COMBO_LANG 1001
diff --git a/CPP/7zip/FileManager/Resource/LangPage/resource.rc b/CPP/7zip/FileManager/Resource/LangPage/resource.rc
new file mode 100755
index 00000000..abaa9481
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/LangPage/resource.rc
@@ -0,0 +1,21 @@
+#include "resource.h"
+#include "../../../GuiCommon.rc"
+
+#define xSize2 238
+#define ySize2 204
+#define xSize (xSize2 + marg + marg)
+#define ySize (ySize2 + marg + marg)
+
+IDD_LANG DIALOG 0, 0, xSize, ySize MY_PAGE_STYLE
+CAPTION "Language"
+MY_FONT
+BEGIN
+ LTEXT "Language:", IDC_LANG_STATIC_LANG, marg, marg, xSize2, 8
+ COMBOBOX IDC_LANG_COMBO_LANG, marg, 20, 146, ySize2 - 12, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+END
+
+STRINGTABLE
+BEGIN
+ IDS_LANG_ENGLISH "English"
+ IDS_LANG_NATIVE "English"
+END
diff --git a/CPP/7zip/FileManager/Resource/ListBoxDialog/StdAfx.h b/CPP/7zip/FileManager/Resource/ListBoxDialog/StdAfx.h
new file mode 100755
index 00000000..a444ca31
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/ListBoxDialog/StdAfx.h
@@ -0,0 +1,16 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#define _WIN32_WINNT 0x0400
+
+// it's for Windows NT supporting (MENUITEMINFOW)
+#define WINVER 0x0400
+
+#include <windows.h>
+#include <commctrl.h>
+
+#include "Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/ListBoxDialog/resource.h b/CPP/7zip/FileManager/Resource/ListBoxDialog/resource.h
new file mode 100755
index 00000000..507e17bd
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/ListBoxDialog/resource.h
@@ -0,0 +1,3 @@
+#define IDD_DIALOG_LISTBOX 202
+
+#define IDC_LISTBOX_LIST 1000
diff --git a/CPP/7zip/FileManager/Resource/ListBoxDialog/resource.rc b/CPP/7zip/FileManager/Resource/ListBoxDialog/resource.rc
new file mode 100755
index 00000000..728aaa94
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/ListBoxDialog/resource.rc
@@ -0,0 +1,22 @@
+#include "resource.h"
+#include "../../../GuiCommon.rc"
+
+#define xSize2 223
+#define ySize2 177
+
+#define xSize (xSize2 + marg + marg)
+#define ySize (ySize2 + marg + marg)
+
+#define bYPos (ySize - marg - bYSize)
+#define b1XPos (xSize - marg - bXSize)
+#define b2XPos (b1XPos - 10 - bXSize)
+
+
+IDD_DIALOG_LISTBOX DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE
+CAPTION "List Box"
+MY_FONT
+BEGIN
+ LISTBOX IDC_LISTBOX_LIST, marg, marg, xSize2, 149, LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "OK", IDOK, b2XPos, bYPos, bXSize, bYSize
+ PUSHBUTTON "Cancel", IDCANCEL, b1XPos, bYPos, bXSize, bYSize
+END
diff --git a/CPP/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.cpp b/CPP/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.cpp
new file mode 100755
index 00000000..ca7b7935
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.cpp
@@ -0,0 +1,102 @@
+// ListViewDialog.cpp
+
+#include "StdAfx.h"
+#include "ListViewDialog.h"
+
+#include "Common/Vector.h"
+
+#ifdef LANG
+#include "../../LangUtils.h"
+static CIDLangPair kIDLangPairs[] =
+{
+ { IDOK, 0x02000702 },
+ { IDCANCEL, 0x02000710 }
+};
+#endif
+
+bool CListViewDialog::OnInit()
+{
+ #ifdef LANG
+ LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
+ #endif
+ _listView.Attach(GetItem(IDC_LISTVIEW_LIST));
+ SetText(Title);
+
+ LVCOLUMN columnInfo;
+ columnInfo.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM;
+ columnInfo.fmt = LVCFMT_LEFT;
+ columnInfo.iSubItem = 0;
+ columnInfo.cx = 1000;
+
+ _listView.InsertColumn(0, &columnInfo);
+
+ for(int i = 0; i < Strings.Size(); i++)
+ {
+ LVITEMW item;
+ item.mask = LVIF_TEXT;
+ item.iItem = i;
+ item.pszText = (LPWSTR)(LPCWSTR)Strings[i];
+ item.iSubItem = 0;
+ _listView.InsertItem(&item);
+ }
+ if (Strings.Size() > 0)
+ _listView.SetItemState(0, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
+ StringsWereChanged = false;
+ return CModalDialog::OnInit();
+}
+
+bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
+{
+ if (header->hwndFrom != _listView)
+ return false;
+ switch(header->code)
+ {
+ case LVN_KEYDOWN:
+ {
+ LPNMLVKEYDOWN keyDownInfo = LPNMLVKEYDOWN(header);
+ switch(keyDownInfo->wVKey)
+ {
+ case VK_DELETE:
+ {
+ if (!DeleteIsAllowed)
+ return false;
+ int focusedIndex = _listView.GetFocusedItem();
+ if (focusedIndex < 0)
+ focusedIndex = 0;
+ for (;;)
+ {
+ int index = _listView.GetNextSelectedItem(-1);
+ if (index < 0)
+ break;
+ StringsWereChanged = true;
+ _listView.DeleteItem(index);
+ Strings.Delete(index);
+ }
+ if (focusedIndex >= _listView.GetItemCount())
+ focusedIndex = _listView.GetItemCount() - 1;
+ if (focusedIndex >= 0)
+ _listView.SetItemState(focusedIndex, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
+ return true;
+ }
+ case 'A':
+ {
+ bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0;
+ if (ctrl)
+ {
+ int numItems = _listView.GetItemCount();
+ for (int i = 0; i < numItems; i++)
+ _listView.SetItemState(i, LVIS_SELECTED, LVIS_SELECTED);
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
+void CListViewDialog::OnOK()
+{
+ FocusedItemIndex = _listView.GetFocusedItem();
+ CModalDialog::OnOK();
+}
diff --git a/CPP/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.h b/CPP/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.h
new file mode 100755
index 00000000..ad107eba
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.h
@@ -0,0 +1,30 @@
+// ListViewDialog.h
+
+#ifndef __LISTVIEWDIALOG_H
+#define __LISTVIEWDIALOG_H
+
+#include "Windows/Control/Dialog.h"
+#include "Windows/Control/ListView.h"
+#include "resource.h"
+
+class CListViewDialog: public NWindows::NControl::CModalDialog
+{
+ NWindows::NControl::CListView _listView;
+ virtual void OnOK();
+ virtual bool OnInit();
+ virtual bool OnNotify(UINT controlID, LPNMHDR header);
+
+public:
+ UString Title;
+ bool DeleteIsAllowed;
+ UStringVector Strings;
+ bool StringsWereChanged;
+ int FocusedItemIndex;
+
+ INT_PTR Create(HWND wndParent = 0) { return CModalDialog::Create(IDD_DIALOG_LISTVIEW, wndParent); }
+
+ CListViewDialog(): DeleteIsAllowed(false) {}
+
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/ListViewDialog/StdAfx.h b/CPP/7zip/FileManager/Resource/ListViewDialog/StdAfx.h
new file mode 100755
index 00000000..a444ca31
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/ListViewDialog/StdAfx.h
@@ -0,0 +1,16 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#define _WIN32_WINNT 0x0400
+
+// it's for Windows NT supporting (MENUITEMINFOW)
+#define WINVER 0x0400
+
+#include <windows.h>
+#include <commctrl.h>
+
+#include "Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/ListViewDialog/resource.h b/CPP/7zip/FileManager/Resource/ListViewDialog/resource.h
new file mode 100755
index 00000000..440d14b0
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/ListViewDialog/resource.h
@@ -0,0 +1,3 @@
+#define IDD_DIALOG_LISTVIEW 201
+
+#define IDC_LISTVIEW_LIST 1000
diff --git a/CPP/7zip/FileManager/Resource/ListViewDialog/resource.rc b/CPP/7zip/FileManager/Resource/ListViewDialog/resource.rc
new file mode 100755
index 00000000..5c0bdbcd
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/ListViewDialog/resource.rc
@@ -0,0 +1,26 @@
+#include "resource.h"
+#include "../../../GuiCommon.rc"
+
+#define xSize2 342
+#define ySize2 220
+
+#define xSize (xSize2 + marg + marg)
+#define ySize (ySize2 + marg + marg)
+
+#define bYPos (ySize - marg - bYSize)
+#define b1XPos (xSize - marg - bXSize)
+#define b2XPos (b1XPos - 10 - bXSize)
+
+
+IDD_DIALOG_LISTVIEW DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE
+CAPTION "ListView"
+MY_FONT
+BEGIN
+ CONTROL "List1", IDC_LISTVIEW_LIST, "SysListView32", LVS_REPORT | LVS_SHOWSELALWAYS |
+ LVS_AUTOARRANGE | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP,
+ marg, marg, xSize2, ySize2 - bYSize - 10
+ DEFPUSHBUTTON "OK", IDOK, b2XPos, bYPos, bXSize, bYSize
+ PUSHBUTTON "Cancel", IDCANCEL, b1XPos, bYPos, bXSize, bYSize
+END
+
+
diff --git a/CPP/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.cpp b/CPP/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.cpp
new file mode 100755
index 00000000..d156f823
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.cpp
@@ -0,0 +1,100 @@
+// MessagesDialog.cpp
+
+#include "StdAfx.h"
+#include "MessagesDialog.h"
+#include "Common/StringConvert.h"
+#include "Common/IntToString.h"
+#include "Windows/ResourceString.h"
+
+#ifdef LANG
+#include "../../LangUtils.h"
+#endif
+
+using namespace NWindows;
+
+#ifdef LANG
+static CIDLangPair kIDLangPairs[] =
+{
+ { IDOK, 0x02000713 }
+};
+#endif
+
+void CMessagesDialog::AddMessageDirect(LPCWSTR message)
+{
+ int itemIndex = _messageList.GetItemCount();
+ LVITEMW item;
+ item.mask = LVIF_TEXT;
+ item.iItem = itemIndex;
+
+ wchar_t sz[32];
+ ConvertInt64ToString(itemIndex, sz);
+
+ item.pszText = sz;
+ item.iSubItem = 0;
+ _messageList.InsertItem(&item);
+
+ item.pszText = (LPWSTR)message;
+ item.iSubItem = 1;
+ _messageList.SetItem(&item);
+}
+
+void CMessagesDialog::AddMessage(LPCWSTR message)
+{
+ UString s = message;
+ while (!s.IsEmpty())
+ {
+ int pos = s.Find(L'\n');
+ if (pos < 0)
+ break;
+ AddMessageDirect(s.Left(pos));
+ s.Delete(0, pos + 1);
+ }
+ AddMessageDirect(s);
+}
+
+bool CMessagesDialog::OnInit()
+{
+ #ifdef LANG
+ LangSetWindowText(HWND(*this), 0x02000A00);
+ LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
+ #endif
+ _messageList.Attach(GetItem(IDC_MESSAGE_LIST));
+ _messageList.SetUnicodeFormat(true);
+
+ LVCOLUMNW columnInfo;
+ columnInfo.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
+ columnInfo.fmt = LVCFMT_LEFT;
+ columnInfo.pszText = L"#";
+ columnInfo.iSubItem = 0;
+ columnInfo.cx = 30;
+
+ _messageList.InsertColumn(0, &columnInfo);
+
+
+ columnInfo.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
+ columnInfo.fmt = LVCFMT_LEFT;
+ UString s =
+ #ifdef LANG
+ LangString(IDS_MESSAGES_DIALOG_MESSAGE_COLUMN, 0x02000A80);
+ #else
+ MyLoadStringW(IDS_MESSAGES_DIALOG_MESSAGE_COLUMN);
+ #endif
+
+ columnInfo.pszText = (LPWSTR)(LPCWSTR)s;
+ columnInfo.iSubItem = 1;
+ columnInfo.cx = 600;
+
+ _messageList.InsertColumn(1, &columnInfo);
+
+ for(int i = 0; i < Messages->Size(); i++)
+ AddMessage((*Messages)[i]);
+
+ /*
+ if(_messageList.GetItemCount() > 0)
+ {
+ UINT aState = LVIS_SELECTED | LVIS_FOCUSED;
+ _messageList.SetItemState(0, aState, aState);
+ }
+ */
+ return CModalDialog::OnInit();
+}
diff --git a/CPP/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.h b/CPP/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.h
new file mode 100755
index 00000000..2ec22d80
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.h
@@ -0,0 +1,22 @@
+// MessagesDialog.h
+
+#ifndef __MESSAGESDIALOG_H
+#define __MESSAGESDIALOG_H
+
+#include "resource.h"
+
+#include "Windows/Control/Dialog.h"
+#include "Windows/Control/ListView.h"
+
+class CMessagesDialog: public NWindows::NControl::CModalDialog
+{
+ NWindows::NControl::CListView _messageList;
+ void AddMessageDirect(LPCWSTR message);
+ void AddMessage(LPCWSTR message);
+ virtual bool OnInit();
+public:
+ const UStringVector *Messages;
+ INT_PTR Create(HWND parent = 0) { return CModalDialog::Create(IDD_DIALOG_MESSAGES, parent); }
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/MessagesDialog/StdAfx.h b/CPP/7zip/FileManager/Resource/MessagesDialog/StdAfx.h
new file mode 100755
index 00000000..a444ca31
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/MessagesDialog/StdAfx.h
@@ -0,0 +1,16 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#define _WIN32_WINNT 0x0400
+
+// it's for Windows NT supporting (MENUITEMINFOW)
+#define WINVER 0x0400
+
+#include <windows.h>
+#include <commctrl.h>
+
+#include "Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/MessagesDialog/resource.h b/CPP/7zip/FileManager/Resource/MessagesDialog/resource.h
new file mode 100755
index 00000000..39d49f57
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/MessagesDialog/resource.h
@@ -0,0 +1,3 @@
+#define IDS_MESSAGES_DIALOG_MESSAGE_COLUMN 503
+#define IDD_DIALOG_MESSAGES 503
+#define IDC_MESSAGE_LIST 1000
diff --git a/CPP/7zip/FileManager/Resource/MessagesDialog/resource.rc b/CPP/7zip/FileManager/Resource/MessagesDialog/resource.rc
new file mode 100755
index 00000000..eae00bf0
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/MessagesDialog/resource.rc
@@ -0,0 +1,25 @@
+#include "resource.h"
+#include "../../../GuiCommon.rc"
+
+#define xSize2 430
+#define ySize2 140
+#define xSize (xSize2 + marg + marg)
+#define ySize (ySize2 + marg + marg)
+#define bXPos (xSize - marg - bXSize)
+#define bYPos (ySize - marg - bYSize)
+
+
+IDD_DIALOG_MESSAGES DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE
+CAPTION "7-Zip: Diagnostic messages"
+MY_FONT
+BEGIN
+ DEFPUSHBUTTON "&Close", IDOK, bXPos, bYPos, bXSize, bYSize
+ CONTROL "List1",IDC_MESSAGE_LIST,"SysListView32",
+ LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,
+ marg, marg, xSize2, ySize2 - bYSize - 6
+END
+
+STRINGTABLE
+BEGIN
+ IDS_MESSAGES_DIALOG_MESSAGE_COLUMN "Message"
+END
diff --git a/CPP/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.cpp b/CPP/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.cpp
new file mode 100755
index 00000000..8f13a43a
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.cpp
@@ -0,0 +1,124 @@
+// OverwriteDialog.cpp
+
+#include "StdAfx.h"
+
+#include "OverwriteDialog.h"
+
+#include "Common/StringConvert.h"
+#include "Windows/FileName.h"
+#include "Windows/Defs.h"
+#include "Windows/ResourceString.h"
+#include "Windows/Control/Static.h"
+#include "Windows/PropVariantConversions.h"
+
+#include "../../FormatUtils.h"
+
+// #include "../resource.h"
+
+#ifdef LANG
+#include "../../LangUtils.h"
+#endif
+
+using namespace NWindows;
+
+#ifdef LANG
+static CIDLangPair kIDLangPairs[] =
+{
+ { IDC_STATIC_OVERWRITE_HEADER, 0x02000901},
+ { IDC_STATIC_OVERWRITE_QUESTION_BEGIN, 0x02000902 },
+ { IDC_STATIC_OVERWRITE_QUESTION_END, 0x02000903 },
+ { IDYES, 0x02000705 },
+ { IDC_BUTTON_OVERWRITE_YES_TO_ALL, 0x02000707 },
+ { IDNO, 0x02000709 },
+ { IDC_BUTTON_OVERWRITE_NO_TO_ALL,0x0200070B },
+ { IDC_BUTTON_OVERWRITE_AUTO_RENAME, 0x02000911 },
+ { IDCANCEL, 0x02000711 }
+};
+#endif
+
+void COverwriteDialog::SetFileInfoControl(int textID, int iconID,
+ const NOverwriteDialog::CFileInfo &fileInfo)
+{
+ UString sizeString;
+ if (fileInfo.SizeIsDefined)
+ sizeString = MyFormatNew(IDS_FILE_SIZE,
+ #ifdef LANG
+ 0x02000982,
+ #endif
+ NumberToString(fileInfo.Size));
+
+ UString reducedName;
+ const int kLineSize = 88;
+ for (int i = 0; i < fileInfo.Name.Length();)
+ {
+ reducedName += fileInfo.Name.Mid(i, kLineSize);
+ reducedName += L" ";
+ i += kLineSize;
+ }
+
+ UString fullString = reducedName;
+ fullString += L"\n";
+ fullString += sizeString;
+ fullString += L"\n";
+
+ if (fileInfo.TimeIsDefined)
+ {
+ UString timeString;
+ FILETIME localFileTime;
+ if (!FileTimeToLocalFileTime(&fileInfo.Time, &localFileTime))
+ throw 4190402;
+ timeString = ConvertFileTimeToString(localFileTime);
+
+ fullString +=
+ #ifdef LANG
+ LangString(IDS_FILE_MODIFIED, 0x02000983);
+ #else
+ MyLoadStringW(IDS_FILE_MODIFIED);
+ #endif
+
+ fullString += L" ";
+ fullString += timeString;
+ }
+
+ NWindows::NControl::CDialogChildControl control;
+ control.Init(*this, textID);
+ control.SetText(fullString);
+
+ SHFILEINFO shellFileInfo;
+ if (::SHGetFileInfo(
+ GetSystemString(fileInfo.Name), FILE_ATTRIBUTE_NORMAL, &shellFileInfo,
+ sizeof(shellFileInfo), SHGFI_ICON | SHGFI_USEFILEATTRIBUTES | SHGFI_LARGEICON))
+ {
+ NControl::CStatic staticContol;
+ staticContol.Attach(GetItem(iconID));
+ staticContol.SetIcon(shellFileInfo.hIcon);
+ }
+}
+
+bool COverwriteDialog::OnInit()
+{
+ #ifdef LANG
+ LangSetWindowText(HWND(*this), 0x02000900);
+ LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
+ #endif
+ SetFileInfoControl(IDC_STATIC_OVERWRITE_OLD_FILE_SIZE_TIME,
+ IDC_STATIC_OVERWRITE_OLD_FILE_ICON, OldFileInfo);
+ SetFileInfoControl(IDC_STATIC_OVERWRITE_NEW_FILE_SIZE_TIME,
+ IDC_STATIC_OVERWRITE_NEW_FILE_ICON, NewFileInfo);
+ return CModalDialog::OnInit();
+}
+
+bool COverwriteDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch(buttonID)
+ {
+ case IDYES:
+ case IDC_BUTTON_OVERWRITE_YES_TO_ALL:
+ case IDNO:
+ case IDC_BUTTON_OVERWRITE_NO_TO_ALL:
+ case IDC_BUTTON_OVERWRITE_AUTO_RENAME:
+ End(buttonID);
+ return true;
+ }
+ return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
+}
diff --git a/CPP/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.h b/CPP/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.h
new file mode 100755
index 00000000..193efb85
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.h
@@ -0,0 +1,34 @@
+// OverwriteDialog.h
+
+#ifndef __OVERWRITEDIALOG_H
+#define __OVERWRITEDIALOG_H
+
+#include "resource.h"
+#include "Windows/Control/Dialog.h"
+
+namespace NOverwriteDialog
+{
+ struct CFileInfo
+ {
+ bool SizeIsDefined;
+ UINT64 Size;
+ bool TimeIsDefined;
+ FILETIME Time;
+ UString Name;
+ };
+}
+
+class COverwriteDialog: public NWindows::NControl::CModalDialog
+{
+ void SetFileInfoControl(int textID, int iconID,
+ const NOverwriteDialog::CFileInfo &fileInfo);
+ virtual bool OnInit();
+ bool OnButtonClicked(int buttonID, HWND buttonHWND);
+public:
+ INT_PTR Create(HWND parent = 0) { return CModalDialog::Create(IDD_DIALOG_OVERWRITE, parent); }
+
+ NOverwriteDialog::CFileInfo OldFileInfo;
+ NOverwriteDialog::CFileInfo NewFileInfo;
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/OverwriteDialog/StdAfx.h b/CPP/7zip/FileManager/Resource/OverwriteDialog/StdAfx.h
new file mode 100755
index 00000000..a444ca31
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/OverwriteDialog/StdAfx.h
@@ -0,0 +1,16 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#define _WIN32_WINNT 0x0400
+
+// it's for Windows NT supporting (MENUITEMINFOW)
+#define WINVER 0x0400
+
+#include <windows.h>
+#include <commctrl.h>
+
+#include "Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/OverwriteDialog/resource.h b/CPP/7zip/FileManager/Resource/OverwriteDialog/resource.h
new file mode 100755
index 00000000..66710f84
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/OverwriteDialog/resource.h
@@ -0,0 +1,19 @@
+#define IDS_FILE_MODIFIED 600
+#define IDS_FILE_SIZE 601
+
+#define IDD_DIALOG_OVERWRITE 502
+
+#define IDC_STATIC_OVERWRITE_HEADER 1000
+
+#define IDC_STATIC_OVERWRITE_QUESTION_BEGIN 1001
+#define IDC_STATIC_OVERWRITE_QUESTION_END 1002
+
+#define IDC_STATIC_OVERWRITE_OLD_FILE_ICON 1003
+#define IDC_STATIC_OVERWRITE_NEW_FILE_ICON 1004
+
+#define IDC_STATIC_OVERWRITE_OLD_FILE_SIZE_TIME 1005
+#define IDC_STATIC_OVERWRITE_NEW_FILE_SIZE_TIME 1006
+
+#define IDC_BUTTON_OVERWRITE_YES_TO_ALL 1010
+#define IDC_BUTTON_OVERWRITE_NO_TO_ALL 1011
+#define IDC_BUTTON_OVERWRITE_AUTO_RENAME 1012
diff --git a/CPP/7zip/FileManager/Resource/OverwriteDialog/resource.rc b/CPP/7zip/FileManager/Resource/OverwriteDialog/resource.rc
new file mode 100755
index 00000000..1a907955
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/OverwriteDialog/resource.rc
@@ -0,0 +1,47 @@
+#include "resource.h"
+#include "../../../GuiCommon.rc"
+
+#define xSize2 357
+#define ySize2 204
+
+#define xSize (xSize2 + marg + marg)
+#define ySize (ySize2 + marg + marg)
+
+#undef iconSize
+#define iconSize 20
+
+#undef fiXPos
+#undef fiXSize
+#undef fiYSize
+#define fiXPos (iconSize + 12)
+#define fiXSize (xSize2 - fiXPos)
+#define fiYSize 50
+
+#define b1YPos (ySize - marg - bYSize)
+#define b2YPos (b1YPos - bYSize - 10)
+
+IDD_DIALOG_OVERWRITE DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE
+CAPTION "Confirm File Replace"
+MY_FONT
+BEGIN
+ LTEXT "Destination folder already contains processed file.", IDC_STATIC_OVERWRITE_HEADER, marg, 7, xSize2, 8
+ LTEXT "Would you like to replace the existing file", IDC_STATIC_OVERWRITE_QUESTION_BEGIN, marg, 28, xSize2, 8
+ ICON "", IDC_STATIC_OVERWRITE_OLD_FILE_ICON, marg, 44, iconSize, iconSize
+ LTEXT "", IDC_STATIC_OVERWRITE_OLD_FILE_SIZE_TIME, fiXPos, 44, fiXSize, fiYSize, SS_NOPREFIX
+ LTEXT "with this one?",IDC_STATIC_OVERWRITE_QUESTION_END, marg, 98, xSize2, 8
+ ICON "",IDC_STATIC_OVERWRITE_NEW_FILE_ICON, marg, 114, iconSize, iconSize
+ LTEXT "",IDC_STATIC_OVERWRITE_NEW_FILE_SIZE_TIME, fiXPos, 114, fiXSize, fiYSize, SS_NOPREFIX
+ PUSHBUTTON "&Yes", IDYES, 78, b2YPos, bXSize, bYSize
+ PUSHBUTTON "Yes to &All", IDC_BUTTON_OVERWRITE_YES_TO_ALL, 152, b2YPos, bXSize, bYSize
+ PUSHBUTTON "&No", IDNO, 226, b2YPos, bXSize, bYSize
+ PUSHBUTTON "No to A&ll", IDC_BUTTON_OVERWRITE_NO_TO_ALL, 300, b2YPos, bXSize, bYSize
+ PUSHBUTTON "A&uto Rename", IDC_BUTTON_OVERWRITE_AUTO_RENAME, 181, b1YPos, 109, bYSize
+ PUSHBUTTON "&Cancel", IDCANCEL, 300, b1YPos, bXSize, bYSize
+END
+
+
+STRINGTABLE
+BEGIN
+ IDS_FILE_MODIFIED "modified on"
+ IDS_FILE_SIZE "{0} bytes"
+END
diff --git a/CPP/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.cpp b/CPP/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.cpp
new file mode 100755
index 00000000..4f09f7f7
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.cpp
@@ -0,0 +1,50 @@
+// PasswordDialog.cpp
+
+#include "StdAfx.h"
+#include "PasswordDialog.h"
+
+#ifdef LANG
+#include "../../LangUtils.h"
+#endif
+
+#ifdef LANG
+static CIDLangPair kIDLangPairs[] =
+{
+ { IDC_STATIC_PASSWORD_HEADER, 0x02000B01 },
+ { IDC_CHECK_PASSWORD_SHOW, 0x02000B02 },
+
+};
+#endif
+
+
+bool CPasswordDialog::OnInit()
+{
+ #ifdef LANG
+ LangSetWindowText(HWND(*this), 0x02000B00);
+ LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
+ #endif
+ _passwordControl.Attach(GetItem(IDC_EDIT_PASSWORD));
+ _passwordControl.SetText(Password);
+ _passwordControl.SetPasswordChar(TEXT('*'));
+ return CModalDialog::OnInit();
+}
+
+bool CPasswordDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ if (buttonID == IDC_CHECK_PASSWORD_SHOW)
+ {
+ _passwordControl.SetPasswordChar((IsButtonChecked(
+ IDC_CHECK_PASSWORD_SHOW) == BST_CHECKED) ? 0: TEXT('*'));
+ UString password;
+ _passwordControl.GetText(password);
+ _passwordControl.SetText(password);
+ return true;
+ }
+ return CDialog::OnButtonClicked(buttonID, buttonHWND);
+}
+
+void CPasswordDialog::OnOK()
+{
+ _passwordControl.GetText(Password);
+ CModalDialog::OnOK();
+}
diff --git a/CPP/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.h b/CPP/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.h
new file mode 100755
index 00000000..f77cd2be
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.h
@@ -0,0 +1,21 @@
+// PasswordDialog.h
+
+#ifndef __PASSWORDDIALOG_H
+#define __PASSWORDDIALOG_H
+
+#include "Windows/Control/Dialog.h"
+#include "Windows/Control/Edit.h"
+#include "resource.h"
+
+class CPasswordDialog: public NWindows::NControl::CModalDialog
+{
+ NWindows::NControl::CEdit _passwordControl;
+ virtual void OnOK();
+ virtual bool OnInit();
+ virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
+public:
+ UString Password;
+ INT_PTR Create(HWND parentWindow = 0) { return CModalDialog::Create(IDD_DIALOG_PASSWORD, parentWindow); }
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/PasswordDialog/StdAfx.h b/CPP/7zip/FileManager/Resource/PasswordDialog/StdAfx.h
new file mode 100755
index 00000000..a444ca31
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/PasswordDialog/StdAfx.h
@@ -0,0 +1,16 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#define _WIN32_WINNT 0x0400
+
+// it's for Windows NT supporting (MENUITEMINFOW)
+#define WINVER 0x0400
+
+#include <windows.h>
+#include <commctrl.h>
+
+#include "Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/PasswordDialog/resource.h b/CPP/7zip/FileManager/Resource/PasswordDialog/resource.h
new file mode 100755
index 00000000..e0b42661
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/PasswordDialog/resource.h
@@ -0,0 +1,4 @@
+#define IDD_DIALOG_PASSWORD 501
+#define IDC_STATIC_PASSWORD_HEADER 1000
+#define IDC_EDIT_PASSWORD 1001
+#define IDC_CHECK_PASSWORD_SHOW 1002
diff --git a/CPP/7zip/FileManager/Resource/PasswordDialog/resource.rc b/CPP/7zip/FileManager/Resource/PasswordDialog/resource.rc
new file mode 100755
index 00000000..7e2658c7
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/PasswordDialog/resource.rc
@@ -0,0 +1,26 @@
+#include "resource.h"
+#include "../../../GuiCommon.rc"
+
+#define xSize2 172
+#define ySize2 68
+#define xSize (xSize2 + marg + marg)
+#define ySize (ySize2 + marg + marg)
+
+#define bYPos (ySize - marg - bYSize)
+#define b1XPos (xSize - marg - bXSize)
+#define b2XPos (b1XPos - 10 - bXSize)
+
+
+IDD_DIALOG_PASSWORD DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE
+CAPTION "Enter password"
+MY_FONT
+BEGIN
+ LTEXT "&Enter password:", IDC_STATIC_PASSWORD_HEADER, marg, marg, xSize2, 8
+ EDITTEXT IDC_EDIT_PASSWORD, marg , 19, xSize2, 14, ES_PASSWORD | ES_AUTOHSCROLL
+
+ CONTROL "&Show password", IDC_CHECK_PASSWORD_SHOW, "Button", BS_AUTOCHECKBOX | WS_TABSTOP,
+ marg, 41, xSize2, 10
+
+ DEFPUSHBUTTON "OK", IDOK, b2XPos, bYPos, bXSize, bYSize
+ PUSHBUTTON "Cancel", IDCANCEL, b1XPos, bYPos, bXSize, bYSize
+END
diff --git a/CPP/7zip/FileManager/Resource/PluginsPage/PluginsPage.cpp b/CPP/7zip/FileManager/Resource/PluginsPage/PluginsPage.cpp
new file mode 100755
index 00000000..0ccdf07e
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/PluginsPage/PluginsPage.cpp
@@ -0,0 +1,220 @@
+// PluginsPage.cpp
+
+#include "StdAfx.h"
+#include "resource.h"
+#include "PluginsPage.h"
+
+#include "Common/StringConvert.h"
+#include "Common/MyCom.h"
+
+#include "Windows/Defs.h"
+#include "Windows/DLL.h"
+#include "Windows/Control/ListView.h"
+#include "Windows/FileFind.h"
+
+#include "../../RegistryUtils.h"
+#include "../../HelpUtils.h"
+#include "../../LangUtils.h"
+#include "../../ProgramLocation.h"
+
+#include "../../PluginInterface.h"
+
+static CIDLangPair kIDLangPairs[] =
+{
+ { IDC_PLUGINS_STATIC_PLUGINS, 0x03010101},
+ { IDC_PLUGINS_BUTTON_OPTIONS, 0x03010110}
+};
+
+static LPCWSTR kPluginsTopic = L"FM/options.htm#plugins";
+
+bool CPluginsPage::OnInit()
+{
+ LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
+
+ _listView.Attach(GetItem(IDC_PLUGINS_LIST));
+
+ UINT32 newFlags = /*LVS_EX_CHECKBOXES | */ LVS_EX_FULLROWSELECT;
+ _listView.SetExtendedListViewStyle(newFlags, newFlags);
+
+ UString title = L"Plugins";
+ LVCOLUMNW column;
+ column.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_FMT | LVCF_SUBITEM;
+ column.cx = 160;
+ column.fmt = LVCFMT_LEFT;
+ column.pszText = (LPWSTR)(LPCWSTR)title;
+ column.iSubItem = 0;
+ _listView.InsertColumn(0, &column);
+
+ ReadFileFolderPluginInfoList(_plugins);
+
+ _listView.SetRedraw(false);
+ // _listView.DeleteAllItems();
+ for(int i = 0; i < _plugins.Size(); i++)
+ {
+ LVITEMW item;
+ item.iItem = i;
+ item.mask = LVIF_TEXT | LVIF_STATE;
+ UString pluginName = _plugins[i].Name;
+ item.pszText = (WCHAR *)(const WCHAR *)pluginName;
+ item.state = 0;
+ item.stateMask = UINT(-1);
+ item.iSubItem = 0;
+ _listView.InsertItem(&item);
+ _listView.SetCheckState(i, true);
+ }
+ _listView.SetRedraw(true);
+ if(_listView.GetItemCount() > 0)
+ {
+ UINT state = LVIS_SELECTED | LVIS_FOCUSED;
+ _listView.SetItemState(0, state, state);
+ }
+
+ return CPropertyPage::OnInit();
+}
+
+LONG CPluginsPage::OnApply()
+{
+ /*
+ int selectedIndex = m_Lang.GetCurSel();
+ int aPathIndex = m_Lang.GetItemData(selectedIndex);
+ SaveRegLang(m_Paths[aPathIndex]);
+ ReloadLang();
+ */
+ return PSNRET_NOERROR;
+}
+
+void CPluginsPage::OnNotifyHelp()
+{
+ ShowHelpWindow(NULL, kPluginsTopic);
+}
+
+bool CPluginsPage::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch(buttonID)
+ {
+ case IDC_PLUGINS_BUTTON_OPTIONS:
+ OnButtonOptions();
+ break;
+ default:
+ return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
+ }
+ return true;
+}
+
+class CPluginOptionsCallback:
+ public IPluginOptionsCallback,
+ public CMyUnknownImp
+{
+ UString _pluginName;
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(GetProgramFolderPath)(BSTR *value);
+ STDMETHOD(GetProgramPath)(BSTR *Value);
+ STDMETHOD(GetRegistryCUPath)(BSTR *Value);
+ void Init(const UString &pluginName)
+ { _pluginName = pluginName; }
+};
+
+STDMETHODIMP CPluginOptionsCallback::GetProgramFolderPath(BSTR *value)
+{
+ *value = 0;
+ UString folder;
+ if (!::GetProgramFolderPath(folder))
+ return E_FAIL;
+ CMyComBSTR valueTemp = folder;
+ *value = valueTemp.Detach();
+ return S_OK;
+}
+
+static UString GetDefaultProgramName()
+{
+ return L"7zFM.exe";
+}
+
+STDMETHODIMP CPluginOptionsCallback::GetProgramPath(BSTR *value)
+{
+ *value = 0;
+ UString folder;
+ if (!::GetProgramFolderPath(folder))
+ return E_FAIL;
+ CMyComBSTR valueTemp = folder + GetDefaultProgramName();
+ *value = valueTemp.Detach();
+ return S_OK;
+}
+
+STDMETHODIMP CPluginOptionsCallback::GetRegistryCUPath(BSTR *value)
+{
+ CMyComBSTR valueTemp = UString(L"Software\\7-Zip\\FM\\Plugins\\") + _pluginName;
+ *value = valueTemp.Detach();
+ return S_OK;
+}
+
+void CPluginsPage::OnButtonOptions()
+{
+ int index = _listView.GetSelectionMark();
+ if (index < 0)
+ return;
+
+ CPluginInfo pluginInfo = _plugins[index];
+ if (!pluginInfo.OptionsClassIDDefined)
+ {
+ MessageBoxW(HWND(*this), L"There are no options", L"7-Zip", 0);
+ return;
+ }
+ NWindows::NDLL::CLibrary library;
+ CMyComPtr<IPluginOptions> pluginOptions;
+ if (!library.Load(pluginInfo.FilePath))
+ {
+ MessageBoxW(HWND(*this), L"Can't load plugin", L"7-Zip", 0);
+ return;
+ }
+ typedef UINT32 (WINAPI * CreateObjectPointer)(
+ const GUID *clsID, const GUID *interfaceID, void **outObject);
+ CreateObjectPointer createObject = (CreateObjectPointer)
+ library.GetProcAddress("CreateObject");
+ if (createObject == NULL)
+ {
+ MessageBoxW(HWND(*this), L"Incorrect plugin", L"7-Zip", 0);
+ return;
+ }
+ if (createObject(&pluginInfo.OptionsClassID, &IID_IPluginOptions, (void **)&pluginOptions) != S_OK)
+ {
+ MessageBoxW(HWND(*this), L"There are no options", L"7-Zip", 0);
+ return;
+ }
+ CPluginOptionsCallback *callbackSpec = new CPluginOptionsCallback;
+ CMyComPtr<IPluginOptionsCallback> callback(callbackSpec);
+ callbackSpec->Init(pluginInfo.Name);
+ pluginOptions->PluginOptions(HWND(*this), callback);
+}
+
+bool CPluginsPage::OnNotify(UINT controlID, LPNMHDR lParam)
+{
+ if (lParam->hwndFrom == HWND(_listView) && lParam->code == LVN_ITEMCHANGED)
+ {
+ const NMLISTVIEW *aNMListView = (const NMLISTVIEW *)lParam;
+ if ((aNMListView->uChanged & LVIF_STATE) != 0)
+ {
+ UINT oldState = aNMListView->uOldState & LVIS_STATEIMAGEMASK;
+ UINT newState = aNMListView->uNewState & LVIS_STATEIMAGEMASK;
+ if (oldState != newState)
+ Changed();
+ }
+ return true;
+ }
+ return CPropertyPage::OnNotify(controlID, lParam);
+}
+
+/*
+bool CPluginsPage::OnCommand(int code, int itemID, LPARAM lParam)
+{
+ if (code == CBN_SELCHANGE && itemID == IDC_LANG_COMBO_LANG)
+ {
+ Changed();
+ return true;
+ }
+ return CPropertyPage::OnCommand(code, itemID, lParam);
+}
+
+*/ \ No newline at end of file
diff --git a/CPP/7zip/FileManager/Resource/PluginsPage/PluginsPage.h b/CPP/7zip/FileManager/Resource/PluginsPage/PluginsPage.h
new file mode 100755
index 00000000..78e81dbb
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/PluginsPage/PluginsPage.h
@@ -0,0 +1,26 @@
+// PluginsPage.h
+
+#include "Windows/Control/ListView.h"
+
+#ifndef __PLUGINSPAGE_H
+#define __PLUGINSPAGE_H
+
+#include "Windows/Control/PropertyPage.h"
+#include "Windows/Control/ComboBox.h"
+
+#include "../../RegistryPlugins.h"
+
+class CPluginsPage: public NWindows::NControl::CPropertyPage
+{
+ NWindows::NControl::CListView _listView;
+ CObjectVector<CPluginInfo> _plugins;
+public:
+ virtual bool OnInit();
+ virtual void OnNotifyHelp();
+ virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
+ virtual void OnButtonOptions();
+ virtual LONG OnApply();
+ virtual bool OnNotify(UINT controlID, LPNMHDR lParam);
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/PluginsPage/StdAfx.h b/CPP/7zip/FileManager/Resource/PluginsPage/StdAfx.h
new file mode 100755
index 00000000..a444ca31
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/PluginsPage/StdAfx.h
@@ -0,0 +1,16 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#define _WIN32_WINNT 0x0400
+
+// it's for Windows NT supporting (MENUITEMINFOW)
+#define WINVER 0x0400
+
+#include <windows.h>
+#include <commctrl.h>
+
+#include "Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/PluginsPage/resource.h b/CPP/7zip/FileManager/Resource/PluginsPage/resource.h
new file mode 100755
index 00000000..8fc923ee
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/PluginsPage/resource.h
@@ -0,0 +1,4 @@
+#define IDD_PLUGINS 901
+#define IDC_PLUGINS_STATIC_PLUGINS 1000
+#define IDC_PLUGINS_LIST 1001
+#define IDC_PLUGINS_BUTTON_OPTIONS 1002
diff --git a/CPP/7zip/FileManager/Resource/PluginsPage/resource.rc b/CPP/7zip/FileManager/Resource/PluginsPage/resource.rc
new file mode 100755
index 00000000..7b74107b
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/PluginsPage/resource.rc
@@ -0,0 +1,19 @@
+#include "resource.h"
+#include "../../../GuiCommon.rc"
+
+#define xSize2 196
+#define ySize2 140
+#define xSize (xSize2 + marg + marg)
+#define ySize (ySize2 + marg + marg)
+
+
+IDD_PLUGINS DIALOG 0, 0, xSize, ySize MY_PAGE_STYLE
+CAPTION "Plugins"
+MY_FONT
+BEGIN
+ LTEXT "&Plugins:", IDC_PLUGINS_STATIC_PLUGINS, marg, marg, xSize2, 8
+ CONTROL "List1", IDC_PLUGINS_LIST, "SysListView32", LVS_REPORT | LVS_SHOWSELALWAYS |
+ LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,
+ marg, 20, xSize2 - bXSize - 12, ySize2 - 12
+ PUSHBUTTON "Options...", IDC_PLUGINS_BUTTON_OPTIONS, (xSize - marg - bXSize), 20, bXSize, bYSize
+END
diff --git a/CPP/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.cpp b/CPP/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.cpp
new file mode 100755
index 00000000..ea0f6fd6
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.cpp
@@ -0,0 +1,175 @@
+// ProgressDialog.cpp
+
+#include "StdAfx.h"
+#include "resource.h"
+#include "ProgressDialog.h"
+#include "Common/IntToString.h"
+#include "Common/IntToString.h"
+
+using namespace NWindows;
+
+static const UINT_PTR kTimerID = 3;
+static const UINT kTimerElapse = 50;
+
+#ifdef LANG
+#include "../../LangUtils.h"
+#endif
+
+#ifdef LANG
+static CIDLangPair kIDLangPairs[] =
+{
+ { IDCANCEL, 0x02000711 }
+};
+#endif
+
+#ifndef _SFX
+CProgressDialog::~CProgressDialog()
+{
+ AddToTitle(TEXT(""));
+}
+void CProgressDialog::AddToTitle(LPCWSTR s)
+{
+ if (MainWindow != 0)
+ ::MySetWindowText(MainWindow, UString(s) + MainTitle);
+}
+#endif
+
+
+
+bool CProgressDialog::OnInit()
+{
+ _range = UINT64(-1);
+ _prevPercentValue = -1;
+
+ #ifdef LANG
+ // LangSetWindowText(HWND(*this), 0x02000C00);
+ LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
+ #endif
+
+ m_ProgressBar.Attach(GetItem(IDC_PROGRESS1));
+ _timer = SetTimer(kTimerID, kTimerElapse);
+ _dialogCreatedEvent.Set();
+ SetText(_title);
+ return CModalDialog::OnInit();
+}
+
+void CProgressDialog::OnCancel()
+{
+ ProgressSynch.SetStopped(true);
+}
+
+void CProgressDialog::SetRange(UINT64 range)
+{
+ _range = range;
+ _peviousPos = (UInt64)(Int64)-1;
+ _converter.Init(range);
+ m_ProgressBar.SetRange32(0 , _converter.Count(range)); // Test it for 100%
+}
+
+void CProgressDialog::SetPos(UINT64 pos)
+{
+ bool redraw = true;
+ if (pos < _range && pos > _peviousPos)
+ {
+ UINT64 posDelta = pos - _peviousPos;
+ if (posDelta < (_range >> 10))
+ redraw = false;
+ }
+ if(redraw)
+ {
+ m_ProgressBar.SetPos(_converter.Count(pos)); // Test it for 100%
+ _peviousPos = pos;
+ }
+}
+
+bool CProgressDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */)
+{
+ if (ProgressSynch.GetPaused())
+ return true;
+ UINT64 total, completed;
+ ProgressSynch.GetProgress(total, completed);
+ if (total != _range)
+ SetRange(total);
+ SetPos(completed);
+
+ if (total == 0)
+ total = 1;
+
+ int percentValue = (int)(completed * 100 / total);
+ if (percentValue != _prevPercentValue)
+ {
+ wchar_t s[64];
+ ConvertUInt64ToString(percentValue, s);
+ UString title = s;
+ title += L"% ";
+ SetText(title + _title);
+ #ifndef _SFX
+ AddToTitle(title + MainAddTitle);
+ #endif
+ _prevPercentValue = percentValue;
+ }
+ return true;
+}
+
+
+////////////////////
+// CU64ToI32Converter
+
+static const UINT64 kMaxIntValue = 0x7FFFFFFF;
+
+void CU64ToI32Converter::Init(UINT64 range)
+{
+ _numShiftBits = 0;
+ while(range > kMaxIntValue)
+ {
+ range >>= 1;
+ _numShiftBits++;
+ }
+}
+
+int CU64ToI32Converter::Count(UINT64 aValue)
+{
+ return int(aValue >> _numShiftBits);
+}
+
+const UINT CProgressDialog::kCloseMessage = WM_USER + 1;
+
+bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch(message)
+ {
+ case kCloseMessage:
+ {
+ KillTimer(_timer);
+ _timer = 0;
+ End(0);
+ return true;
+ }
+ case WM_SETTEXT:
+ {
+ if (_timer == 0)
+ return true;
+ }
+ }
+ return CModalDialog::OnMessage(message, wParam, lParam);
+}
+
+bool CProgressDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch(buttonID)
+ {
+ case IDCANCEL:
+ {
+ bool paused = ProgressSynch.GetPaused();;
+ ProgressSynch.SetPaused(true);
+ int res = ::MessageBoxW(HWND(*this),
+ L"Are you sure you want to cancel?",
+ _title, MB_YESNOCANCEL);
+ ProgressSynch.SetPaused(paused);
+ if (res == IDCANCEL || res == IDNO)
+ return true;
+ break;
+ }
+ }
+ return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
+}
diff --git a/CPP/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.h b/CPP/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.h
new file mode 100755
index 00000000..e11ffc51
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.h
@@ -0,0 +1,129 @@
+// ProgressDialog.h
+
+#ifndef __PROGRESSDIALOG_H
+#define __PROGRESSDIALOG_H
+
+#include "resource.h"
+
+#include "Windows/Control/Dialog.h"
+#include "Windows/Control/ProgressBar.h"
+#include "Windows/Synchronization.h"
+
+class CProgressSynch
+{
+ NWindows::NSynchronization::CCriticalSection _criticalSection;
+ bool _stopped;
+ bool _paused;
+ UINT64 _total;
+ UINT64 _completed;
+public:
+ CProgressSynch(): _stopped(false), _paused(false), _total(1), _completed(0) {}
+
+ bool GetStopped()
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ return _stopped;
+ }
+ void SetStopped(bool value)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ _stopped = value;
+ }
+ bool GetPaused()
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ return _paused;
+ }
+ void SetPaused(bool value)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ _paused = value;
+ }
+ void SetProgress(UINT64 total, UINT64 completed)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ _total = total;
+ _completed = completed;
+ }
+ void SetPos(UINT64 completed)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ _completed = completed;
+ }
+ void GetProgress(UINT64 &total, UINT64 &completed)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ total = _total;
+ completed = _completed;
+ }
+};
+
+class CU64ToI32Converter
+{
+ UINT64 _numShiftBits;
+public:
+ void Init(UINT64 _range);
+ int Count(UINT64 aValue);
+};
+
+// class CProgressDialog: public NWindows::NControl::CModelessDialog
+
+class CProgressDialog: public NWindows::NControl::CModalDialog
+{
+private:
+ UINT_PTR _timer;
+
+ UString _title;
+ CU64ToI32Converter _converter;
+ UINT64 _peviousPos;
+ UINT64 _range;
+ NWindows::NControl::CProgressBar m_ProgressBar;
+
+ int _prevPercentValue;
+
+ bool OnTimer(WPARAM timerID, LPARAM callback);
+ void SetRange(UINT64 range);
+ void SetPos(UINT64 pos);
+ virtual bool OnInit();
+ virtual void OnCancel();
+ NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent;
+ #ifndef _SFX
+ void AddToTitle(LPCWSTR string);
+ #endif
+ bool OnButtonClicked(int buttonID, HWND buttonHWND);
+public:
+ CProgressSynch ProgressSynch;
+
+ #ifndef _SFX
+ HWND MainWindow;
+ UString MainTitle;
+ UString MainAddTitle;
+ ~CProgressDialog();
+ #endif
+
+ CProgressDialog(): _timer(0)
+ #ifndef _SFX
+ ,MainWindow(0)
+ #endif
+ {}
+
+ void WaitCreating() { _dialogCreatedEvent.Lock(); }
+
+
+ INT_PTR Create(const UString &title, HWND wndParent = 0)
+ {
+ _title = title;
+ return CModalDialog::Create(IDD_DIALOG_PROGRESS, wndParent);
+ }
+
+ static const UINT kCloseMessage;
+
+ virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+
+ void MyClose()
+ {
+ PostMessage(kCloseMessage);
+ };
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/ProgressDialog/StdAfx.h b/CPP/7zip/FileManager/Resource/ProgressDialog/StdAfx.h
new file mode 100755
index 00000000..a444ca31
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/ProgressDialog/StdAfx.h
@@ -0,0 +1,16 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#define _WIN32_WINNT 0x0400
+
+// it's for Windows NT supporting (MENUITEMINFOW)
+#define WINVER 0x0400
+
+#include <windows.h>
+#include <commctrl.h>
+
+#include "Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/ProgressDialog/resource.h b/CPP/7zip/FileManager/Resource/ProgressDialog/resource.h
new file mode 100755
index 00000000..97e47228
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/ProgressDialog/resource.h
@@ -0,0 +1,3 @@
+#define IDD_DIALOG_PROGRESS 500
+
+#define IDC_PROGRESS1 1000
diff --git a/CPP/7zip/FileManager/Resource/ProgressDialog/resource.rc b/CPP/7zip/FileManager/Resource/ProgressDialog/resource.rc
new file mode 100755
index 00000000..a6b375ed
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/ProgressDialog/resource.rc
@@ -0,0 +1,20 @@
+#include "resource.h"
+#include "../../../GuiCommon.rc"
+
+#define xSize2 172
+#define ySize2 42
+#define xSize (xSize2 + marg + marg)
+#define ySize (ySize2 + marg + marg)
+
+#define bYPos (ySize - marg - bYSize)
+#define bXPos (xSize - marg - bXSize)
+
+
+IDD_DIALOG_PROGRESS DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE
+CAPTION "Progress"
+MY_FONT
+BEGIN
+ PUSHBUTTON "Cancel", IDCANCEL, bXPos, bYPos , bXSize, bYSize
+ CONTROL "Progress1", IDC_PROGRESS1,"msctls_progress32",PBS_SMOOTH | WS_BORDER,
+ marg,marg, xSize2, 14
+END
diff --git a/CPP/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.cpp b/CPP/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.cpp
new file mode 100755
index 00000000..e5a496bd
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.cpp
@@ -0,0 +1,432 @@
+// ProgressDialog.cpp
+
+#include "StdAfx.h"
+#include "resource.h"
+#include "ProgressDialog.h"
+#include "Common/IntToString.h"
+#include "Common/IntToString.h"
+
+using namespace NWindows;
+
+static const UINT_PTR kTimerID = 3;
+static const UINT kTimerElapse = 50;
+
+#ifdef LANG
+#include "../../LangUtils.h"
+#endif
+
+#ifdef LANG
+static CIDLangPair kIDLangPairs[] =
+{
+ { IDCANCEL, 0x02000C00 },
+ { IDC_PROGRESS_ELAPSED, 0x02000C01 },
+ { IDC_PROGRESS_REMAINING, 0x02000C02 },
+ { IDC_PROGRESS_TOTAL, 0x02000C03 },
+ { IDC_PROGRESS_SPEED, 0x02000C04 },
+ { IDC_BUTTON_PROGRESS_PRIORITY, 0x02000C10 },
+ { IDC_BUTTON_PAUSE, 0x02000C12 },
+ { IDCANCEL, 0x02000711 },
+};
+#endif
+
+HRESULT CProgressSynch::SetPosAndCheckPaused(UInt64 completed)
+{
+ for (;;)
+ {
+ if(GetStopped())
+ return E_ABORT;
+ if(!GetPaused())
+ break;
+ ::Sleep(100);
+ }
+ SetPos(completed);
+ return S_OK;
+}
+
+#ifndef _SFX
+CProgressDialog::~CProgressDialog()
+{
+ AddToTitle(L"");
+}
+void CProgressDialog::AddToTitle(LPCWSTR s)
+{
+ if (MainWindow != 0)
+ {
+ CWindow window(MainWindow);
+ window.SetText(s + UString(MainTitle));
+ }
+}
+
+static const int kTitleFileNameSizeLimit = 36;
+static const int kCurrentFileNameSizeLimit = 68;
+
+static void ReduceString(UString &s, int size)
+{
+ if (s.Length() > size)
+ s = s.Left(size / 2) + UString(L" ... ") + s.Right(size / 2);
+}
+#endif
+
+bool CProgressDialog::OnInit()
+{
+ _range = (UInt64)(Int64)(-1);
+ _prevPercentValue = UInt32(-1);
+ _prevElapsedSec = UInt32(-1);
+ _prevRemainingSec = UInt32(-1);
+ _prevSpeed = UInt32(-1);
+ _prevMode = kSpeedBytes;
+ _prevTime = ::GetTickCount();
+ _elapsedTime = 0;
+ _foreground = true;
+
+ #ifdef LANG
+ // LangSetWindowText(HWND(*this), 0x02000C00);
+ LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
+ #endif
+
+
+ CWindow window(GetItem(IDC_BUTTON_PROGRESS_PRIORITY));
+ window.GetText(backgroundString);
+ backgroundedString = backgroundString;
+ backgroundedString.Replace(L"&", L"");
+
+ window = GetItem(IDC_BUTTON_PAUSE);
+ window.GetText(pauseString);
+
+ foregroundString = LangString(IDS_PROGRESS_FOREGROUND, 0x02000C11);
+ continueString = LangString(IDS_PROGRESS_CONTINUE, 0x02000C13);
+ pausedString = LangString(IDS_PROGRESS_PAUSED, 0x02000C20);
+
+ m_ProgressBar.Attach(GetItem(IDC_PROGRESS1));
+ _timer = SetTimer(kTimerID, kTimerElapse);
+ _dialogCreatedEvent.Set();
+ SetText(_title);
+ SetPauseText();
+ SetPriorityText();
+ return CModalDialog::OnInit();
+}
+
+void CProgressDialog::OnCancel()
+{
+ ProgressSynch.SetStopped(true);
+}
+
+static void ConvertSizeToString(UInt64 value, wchar_t *s)
+{
+ const wchar_t *kModif = L" KMGTP";
+ for (int i = 0; ; i++)
+ if (i == 5 || value < (UInt64(10000) << (i * 10)))
+ {
+ ConvertUInt64ToString(value >> (i * 10), s);
+ s += wcslen(s);
+ *s++ = ' ';
+ if (i != 0)
+ *s++ = kModif[i];
+ *s++ = L'B';
+ *s++ = L'\0';
+ return;
+ }
+}
+
+void CProgressDialog::SetRange(UInt64 range)
+{
+ _range = range;
+ _previousPos = (UInt64)(Int64)-1;
+ _converter.Init(range);
+ m_ProgressBar.SetRange32(0 , _converter.Count(range)); // Test it for 100%
+
+ wchar_t s[32];
+ ConvertSizeToString(_range, s);
+ SetItemText(IDC_PROGRESS_SPEED_TOTAL_VALUE, s);
+}
+
+void CProgressDialog::SetPos(UInt64 pos)
+{
+ bool redraw = true;
+ if (pos < _range && pos > _previousPos)
+ {
+ if (pos - _previousPos < (_range >> 10))
+ redraw = false;
+ }
+ if(redraw)
+ {
+ m_ProgressBar.SetPos(_converter.Count(pos)); // Test it for 100%
+ _previousPos = pos;
+ }
+}
+
+static void GetTimeString(UInt64 timeValue, TCHAR *s)
+{
+ wsprintf(s, TEXT("%02d:%02d:%02d"),
+ UInt32(timeValue / 3600),
+ UInt32((timeValue / 60) % 60),
+ UInt32(timeValue % 60));
+}
+
+bool CProgressDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */)
+{
+ if (ProgressSynch.GetPaused())
+ return true;
+ UInt64 total, completed;
+ ProgressSynch.GetProgress(total, completed);
+
+ UInt32 curTime = ::GetTickCount();
+
+ if (total != _range)
+ SetRange(total);
+ if (total == (UInt64)(Int64)-1)
+ {
+ SetPos(0);
+ SetRange(completed);
+ }
+ else
+ SetPos(completed);
+
+ _elapsedTime += (curTime - _prevTime);
+ _prevTime = curTime;
+
+ UInt32 elapsedSec = _elapsedTime / 1000;
+
+ bool elapsedChanged = false;
+ if (elapsedSec != _prevElapsedSec)
+ {
+ TCHAR s[40];
+ GetTimeString(elapsedSec, s);
+ SetItemText(IDC_PROGRESS_ELAPSED_VALUE, s);
+ _prevElapsedSec = elapsedSec;
+ elapsedChanged = true;
+ }
+
+ if (completed != 0 && elapsedChanged)
+ {
+ if (total == (UInt64)(Int64)-1)
+ {
+ SetItemText(IDC_PROGRESS_REMAINING_VALUE, L"");
+ }
+ else
+ {
+ UInt64 remainingTime = 0;
+ if (completed < total)
+ remainingTime = _elapsedTime * (total - completed) / completed;
+ UInt64 remainingSec = remainingTime / 1000;
+ if (remainingSec != _prevRemainingSec)
+ {
+ TCHAR s[40];
+ GetTimeString(remainingSec, s);
+ SetItemText(IDC_PROGRESS_REMAINING_VALUE, s);
+ _prevRemainingSec = remainingSec;
+ }
+ }
+ // if (elapsedChanged)
+ {
+ UInt64 speedB = (completed * 1000) / _elapsedTime;
+ UInt64 speedKB = speedB / 1024;
+ UInt64 speedMB = speedKB / 1024;
+ const UInt32 kLimit1 = 10;
+ TCHAR s[40];
+ bool needRedraw = false;
+ if (speedMB >= kLimit1)
+ {
+ if (_prevMode != kSpeedMBytes || speedMB != _prevSpeed)
+ {
+ ConvertUInt64ToString(speedMB, s);
+ lstrcat(s, TEXT(" MB/s"));
+ _prevMode = kSpeedMBytes;
+ _prevSpeed = speedMB;
+ needRedraw = true;
+ }
+ }
+ else if (speedKB >= kLimit1)
+ {
+ if (_prevMode != kSpeedKBytes || speedKB != _prevSpeed)
+ {
+ ConvertUInt64ToString(speedKB, s);
+ lstrcat(s, TEXT(" KB/s"));
+ _prevMode = kSpeedKBytes;
+ _prevSpeed = speedKB;
+ needRedraw = true;
+ }
+ }
+ else
+ {
+ if (_prevMode != kSpeedBytes || speedB != _prevSpeed)
+ {
+ ConvertUInt64ToString(speedB, s);
+ lstrcat(s, TEXT(" B/s"));
+ _prevMode = kSpeedBytes;
+ _prevSpeed = speedB;
+ needRedraw = true;
+ }
+ }
+ if (needRedraw)
+ SetItemText(IDC_PROGRESS_SPEED_VALUE, s);
+ }
+ }
+
+ if (total == 0)
+ total = 1;
+ UInt32 percentValue = (UInt32)(completed * 100 / total);
+ UString titleName;
+ ProgressSynch.GetTitleFileName(titleName);
+ if (percentValue != _prevPercentValue || _prevTitleName != titleName)
+ {
+ _prevPercentValue = percentValue;
+ SetTitleText();
+ _prevTitleName = titleName;
+ }
+ UString fileName;
+ ProgressSynch.GetCurrentFileName(fileName);
+ if (_prevFileName != fileName)
+ {
+ ReduceString(fileName, kCurrentFileNameSizeLimit);
+ SetItemText(IDC_PROGRESS_FILE_NAME, fileName);
+ _prevFileName == fileName;
+ }
+
+ return true;
+}
+
+
+////////////////////
+// CU64ToI32Converter
+
+static const UInt64 kMaxIntValue = 0x7FFFFFFF;
+
+void CU64ToI32Converter::Init(UInt64 range)
+{
+ _numShiftBits = 0;
+ while(range > kMaxIntValue)
+ {
+ range >>= 1;
+ _numShiftBits++;
+ }
+}
+
+int CU64ToI32Converter::Count(UInt64 aValue)
+{
+ return int(aValue >> _numShiftBits);
+}
+
+const UINT CProgressDialog::kCloseMessage = WM_USER + 1;
+
+bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch(message)
+ {
+ case kCloseMessage:
+ {
+ KillTimer(_timer);
+ _timer = 0;
+ End(0);
+ return true;
+ }
+ case WM_SETTEXT:
+ {
+ if (_timer == 0)
+ return true;
+ }
+ }
+ return CModalDialog::OnMessage(message, wParam, lParam);
+}
+
+void CProgressDialog::SetTitleText()
+{
+ UString title;
+ if (ProgressSynch.GetPaused())
+ {
+ title = pausedString;
+ title += L" ";
+ }
+ if (_prevPercentValue != UInt32(-1))
+ {
+ wchar_t s[64];
+ ConvertUInt64ToString(_prevPercentValue, s);
+ title += s;
+ title += L"%";
+ }
+ if (!_foreground)
+ {
+ title += L" ";
+ title += backgroundedString;
+ }
+ title += L" ";
+ UString totalTitle = title + _title;
+ UString fileName;
+ ProgressSynch.GetTitleFileName(fileName);
+ if (!fileName.IsEmpty())
+ {
+ ReduceString(fileName, kTitleFileNameSizeLimit);
+ totalTitle += L" ";
+ totalTitle += fileName;
+ }
+ SetText(totalTitle);
+ #ifndef _SFX
+ AddToTitle(title + MainAddTitle);
+ #endif
+}
+
+void CProgressDialog::SetPauseText()
+{
+ SetItemText(IDC_BUTTON_PAUSE, ProgressSynch.GetPaused() ?
+ continueString : pauseString);
+ SetTitleText();
+}
+
+void CProgressDialog::OnPauseButton()
+{
+ bool paused = !ProgressSynch.GetPaused();
+ ProgressSynch.SetPaused(paused);
+ UInt32 curTime = ::GetTickCount();
+ if (paused)
+ _elapsedTime += (curTime - _prevTime);
+ _prevTime = curTime;
+ SetPauseText();
+}
+
+void CProgressDialog::SetPriorityText()
+{
+ SetItemText(IDC_BUTTON_PROGRESS_PRIORITY, _foreground ?
+ backgroundString :
+ foregroundString);
+ SetTitleText();
+}
+
+void CProgressDialog::OnPriorityButton()
+{
+ _foreground = !_foreground;
+ SetPriorityClass(GetCurrentProcess(), _foreground ?
+ NORMAL_PRIORITY_CLASS: IDLE_PRIORITY_CLASS);
+ SetPriorityText();
+}
+
+bool CProgressDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch(buttonID)
+ {
+ case IDCANCEL:
+ {
+ bool paused = ProgressSynch.GetPaused();;
+ // ProgressSynch.SetPaused(true);
+ if (!paused)
+ OnPauseButton();
+ int res = ::MessageBoxW(HWND(*this),
+ LangString(IDS_PROGRESS_ASK_CANCEL, 0x02000C30),
+ _title, MB_YESNOCANCEL);
+ // ProgressSynch.SetPaused(paused);
+ if (!paused)
+ OnPauseButton();
+ if (res == IDCANCEL || res == IDNO)
+ return true;
+ break;
+ }
+ case IDC_BUTTON_PAUSE:
+ OnPauseButton();
+ return true;
+ case IDC_BUTTON_PROGRESS_PRIORITY:
+ {
+ OnPriorityButton();
+ return true;
+ }
+ }
+ return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
+}
diff --git a/CPP/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.h b/CPP/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.h
new file mode 100755
index 00000000..0625eadd
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.h
@@ -0,0 +1,184 @@
+// ProgressDialog.h
+
+#ifndef __PROGRESSDIALOG_H
+#define __PROGRESSDIALOG_H
+
+#include "resource.h"
+
+#include "Common/Types.h"
+
+#include "Windows/Control/Dialog.h"
+#include "Windows/Control/ProgressBar.h"
+#include "Windows/Synchronization.h"
+
+class CProgressSynch
+{
+ NWindows::NSynchronization::CCriticalSection _criticalSection;
+ bool _stopped;
+ bool _paused;
+ UInt64 _total;
+ UInt64 _completed;
+ UString TitleFileName;
+ UString CurrentFileName;
+public:
+ CProgressSynch(): _stopped(false), _paused(false), _total((UInt64)(Int64)-1), _completed(0) {}
+
+ bool GetStopped()
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ return _stopped;
+ }
+ void SetStopped(bool value)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ _stopped = value;
+ }
+ bool GetPaused()
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ return _paused;
+ }
+ void SetPaused(bool value)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ _paused = value;
+ }
+ void SetProgress(UInt64 total, UInt64 completed)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ _total = total;
+ _completed = completed;
+ }
+ void SetPos(UInt64 completed)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ _completed = completed;
+ }
+ HRESULT SetPosAndCheckPaused(UInt64 completed);
+ void GetProgress(UInt64 &total, UInt64 &completed)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ total = _total;
+ completed = _completed;
+ }
+ void SetTitleFileName(const UString &fileName)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ TitleFileName = fileName;
+ }
+ void GetTitleFileName(UString &fileName)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ fileName = TitleFileName;
+ }
+ void SetCurrentFileName(const UString &fileName)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ CurrentFileName = fileName;
+ }
+ void GetCurrentFileName(UString &fileName)
+ {
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ fileName = CurrentFileName;
+ }
+};
+
+class CU64ToI32Converter
+{
+ UInt64 _numShiftBits;
+public:
+ void Init(UInt64 _range);
+ int Count(UInt64 aValue);
+};
+
+// class CProgressDialog: public NWindows::NControl::CModelessDialog
+
+enum ESpeedMode
+{
+ kSpeedBytes,
+ kSpeedKBytes,
+ kSpeedMBytes
+};
+
+class CProgressDialog: public NWindows::NControl::CModalDialog
+{
+ UString _prevFileName;
+ UString _prevTitleName;
+private:
+ UString backgroundString;
+ UString backgroundedString;
+ UString foregroundString;
+ UString pauseString;
+ UString continueString;
+ UString pausedString;
+
+
+
+ UINT_PTR _timer;
+
+ UString _title;
+ CU64ToI32Converter _converter;
+ UInt64 _previousPos;
+ UInt64 _range;
+ NWindows::NControl::CProgressBar m_ProgressBar;
+
+ UInt32 _prevPercentValue;
+ UInt32 _prevTime;
+ UInt32 _elapsedTime;
+ UInt32 _prevElapsedSec;
+ UInt64 _prevRemainingSec;
+ ESpeedMode _prevMode;
+ UInt64 _prevSpeed;
+
+ bool _foreground;
+
+ bool OnTimer(WPARAM timerID, LPARAM callback);
+ void SetRange(UInt64 range);
+ void SetPos(UInt64 pos);
+ virtual bool OnInit();
+ virtual void OnCancel();
+ NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent;
+ #ifndef _SFX
+ void AddToTitle(LPCWSTR string);
+ #endif
+
+ void SetPauseText();
+ void SetPriorityText();
+ void OnPauseButton();
+ void OnPriorityButton();
+ bool OnButtonClicked(int buttonID, HWND buttonHWND);
+
+ void SetTitleText();
+public:
+ CProgressSynch ProgressSynch;
+
+ #ifndef _SFX
+ HWND MainWindow;
+ UString MainTitle;
+ UString MainAddTitle;
+ ~CProgressDialog();
+ #endif
+
+ CProgressDialog(): _timer(0)
+ #ifndef _SFX
+ ,MainWindow(0)
+ #endif
+ {}
+
+ void WaitCreating() { _dialogCreatedEvent.Lock(); }
+
+
+ INT_PTR Create(const UString &title, HWND wndParent = 0)
+ {
+ _title = title;
+ return CModalDialog::Create(IDD_DIALOG_PROGRESS, wndParent);
+ }
+
+ static const UINT kCloseMessage;
+
+ virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+
+ void MyClose() { PostMessage(kCloseMessage); };
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/ProgressDialog2/StdAfx.h b/CPP/7zip/FileManager/Resource/ProgressDialog2/StdAfx.h
new file mode 100755
index 00000000..a444ca31
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/ProgressDialog2/StdAfx.h
@@ -0,0 +1,16 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#define _WIN32_WINNT 0x0400
+
+// it's for Windows NT supporting (MENUITEMINFOW)
+#define WINVER 0x0400
+
+#include <windows.h>
+#include <commctrl.h>
+
+#include "Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/ProgressDialog2/resource.h b/CPP/7zip/FileManager/Resource/ProgressDialog2/resource.h
new file mode 100755
index 00000000..be1da4ad
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/ProgressDialog2/resource.h
@@ -0,0 +1,17 @@
+#define IDC_BUTTON_PAUSE 3
+#define IDC_BUTTON_PROGRESS_PRIORITY 4
+#define IDD_DIALOG_PROGRESS 500
+#define IDS_PROGRESS_PAUSED 700
+#define IDS_PROGRESS_FOREGROUND 701
+#define IDS_PROGRESS_CONTINUE 702
+#define IDS_PROGRESS_ASK_CANCEL 703
+#define IDC_PROGRESS1 1000
+#define IDC_PROGRESS_ELAPSED 1002
+#define IDC_PROGRESS_ELAPSED_VALUE 1003
+#define IDC_PROGRESS_REMAINING 1004
+#define IDC_PROGRESS_REMAINING_VALUE 1005
+#define IDC_PROGRESS_SPEED 1006
+#define IDC_PROGRESS_SPEED_VALUE 1007
+#define IDC_PROGRESS_TOTAL 1008
+#define IDC_PROGRESS_SPEED_TOTAL_VALUE 1009
+#define IDC_PROGRESS_FILE_NAME 1010
diff --git a/CPP/7zip/FileManager/Resource/ProgressDialog2/resource.rc b/CPP/7zip/FileManager/Resource/ProgressDialog2/resource.rc
new file mode 100755
index 00000000..9f395bff
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/ProgressDialog2/resource.rc
@@ -0,0 +1,56 @@
+#include "resource.h"
+#include "../../../GuiCommon.rc"
+
+#define xSize2 290
+#define ySize2 76
+
+#define xSize (xSize2 + marg + marg)
+#define ySize (ySize2 + marg + marg)
+
+#define bYPos (ySize - marg - bYSize)
+
+#undef bXSize
+#define bXSize 72
+
+#define bXPos1 (xSize - marg - bXSize)
+#define bXPos2 (bXPos1 - 10 - bXSize)
+#define bXPos3 (bXPos2 - 10 - bXSize)
+
+#define valSize 42
+#define timeSize 91
+#define labelPos 178
+#define valPos1 (marg + timeSize)
+#define valPos2 (xSize - marg - valSize)
+#define labelSize (valPos2 - labelPos)
+
+#undef yPos
+#define yPos (marg + 11)
+
+
+IDD_DIALOG_PROGRESS DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE | WS_MINIMIZEBOX
+CAPTION "Progress"
+MY_FONT
+BEGIN
+ PUSHBUTTON "&Background", IDC_BUTTON_PROGRESS_PRIORITY, bXPos3, bYPos, bXSize, bYSize
+ PUSHBUTTON "&Pause", IDC_BUTTON_PAUSE, bXPos2, bYPos, bXSize, bYSize
+ PUSHBUTTON "Cancel", IDCANCEL, bXPos1, bYPos, bXSize, bYSize
+ LTEXT "Elapsed time:", IDC_PROGRESS_ELAPSED, marg, marg, timeSize, 8
+ LTEXT "Remaining time:", IDC_PROGRESS_REMAINING, marg, yPos, timeSize, 8
+ LTEXT "Size:", IDC_PROGRESS_TOTAL, labelPos, marg, labelSize, 8
+ LTEXT "Speed:", IDC_PROGRESS_SPEED, labelPos, yPos, labelSize, 8
+ RTEXT "00:00:00", IDC_PROGRESS_ELAPSED_VALUE, valPos1, marg, valSize, 8
+ RTEXT "", IDC_PROGRESS_REMAINING_VALUE, valPos1, yPos, valSize, 8
+ RTEXT "", IDC_PROGRESS_SPEED_TOTAL_VALUE, valPos2, marg, valSize, 8
+ RTEXT "", IDC_PROGRESS_SPEED_VALUE, valPos2, yPos, valSize, 8
+ LTEXT "", IDC_PROGRESS_FILE_NAME, marg, yPos + 16, xSize2, 8, SS_NOPREFIX
+ CONTROL "Progress1", IDC_PROGRESS1, "msctls_progress32", PBS_SMOOTH | WS_BORDER, marg, bYPos - 20, xSize2, 13
+END
+
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_PROGRESS_PAUSED "Paused"
+ IDS_PROGRESS_FOREGROUND "&Foreground"
+ IDS_PROGRESS_CONTINUE "&Continue"
+ IDS_PROGRESS_ASK_CANCEL "Are you sure you want to cancel?"
+END
diff --git a/CPP/7zip/FileManager/Resource/PropertyName/resource.h b/CPP/7zip/FileManager/Resource/PropertyName/resource.h
new file mode 100755
index 00000000..f3d56ef3
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/PropertyName/resource.h
@@ -0,0 +1,28 @@
+#define IDS_PROPERTY_PATH 3
+#define IDS_PROPERTY_NAME 4
+#define IDS_PROPERTY_EXTENSION 5
+#define IDS_PROPERTY_IS_FOLDER 6
+#define IDS_PROPERTY_SIZE 7
+#define IDS_PROPERTY_PACKED_SIZE 8
+#define IDS_PROPERTY_ATTRIBUTES 9
+#define IDS_PROPERTY_CREATION_TIME 10
+#define IDS_PROPERTY_LAST_ACCESS_TIME 11
+#define IDS_PROPERTY_LAST_WRITE_TIME 12
+#define IDS_PROPERTY_SOLID 13
+#define IDS_PROPERTY_C0MMENTED 14
+#define IDS_PROPERTY_ENCRYPTED 15
+#define IDS_PROPERTY_DICTIONARY_SIZE 16
+#define IDS_PROPERTY_SPLIT_BEFORE 17
+#define IDS_PROPERTY_SPLIT_AFTER 18
+#define IDS_PROPERTY_CRC 19
+#define IDS_PROPERTY_FILE_TYPE 20
+#define IDS_PROPERTY_ANTI 21
+#define IDS_PROPERTY_METHOD 22
+#define IDS_PROPERTY_HOST_OS 23
+#define IDS_PROPERTY_FILE_SYSTEM 24
+#define IDS_PROPERTY_USER 25
+#define IDS_PROPERTY_GROUP 26
+#define IDS_PROPERTY_BLOCK 27
+#define IDS_PROPERTY_COMMENT 28
+#define IDS_PROPERTY_POSITION 29
+#define IDS_PROPERTY_PREFIX 30
diff --git a/CPP/7zip/FileManager/Resource/PropertyName/resource.rc b/CPP/7zip/FileManager/Resource/PropertyName/resource.rc
new file mode 100755
index 00000000..3f517aff
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/PropertyName/resource.rc
@@ -0,0 +1,35 @@
+#include "resource.h"
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+STRINGTABLE
+BEGIN
+ IDS_PROPERTY_PATH "Path"
+ IDS_PROPERTY_NAME "Name"
+ IDS_PROPERTY_EXTENSION "Extension"
+ IDS_PROPERTY_IS_FOLDER "Folder"
+ IDS_PROPERTY_SIZE "Size"
+ IDS_PROPERTY_PACKED_SIZE "Packed Size"
+ IDS_PROPERTY_ATTRIBUTES "Attributes"
+ IDS_PROPERTY_CREATION_TIME "Created"
+ IDS_PROPERTY_LAST_ACCESS_TIME "Accessed"
+ IDS_PROPERTY_LAST_WRITE_TIME "Modified"
+ IDS_PROPERTY_SOLID "Solid"
+ IDS_PROPERTY_C0MMENTED "Commented"
+ IDS_PROPERTY_ENCRYPTED "Encrypted"
+ IDS_PROPERTY_DICTIONARY_SIZE "Dictionary Size"
+ IDS_PROPERTY_SPLIT_BEFORE "Split Before"
+ IDS_PROPERTY_SPLIT_AFTER "Split After"
+ IDS_PROPERTY_CRC "CRC"
+ IDS_PROPERTY_FILE_TYPE "Type"
+ IDS_PROPERTY_ANTI "Anti"
+ IDS_PROPERTY_METHOD "Method"
+ IDS_PROPERTY_HOST_OS "Host OS"
+ IDS_PROPERTY_FILE_SYSTEM "File System"
+ IDS_PROPERTY_USER "User"
+ IDS_PROPERTY_GROUP "Group"
+ IDS_PROPERTY_BLOCK "Block"
+ IDS_PROPERTY_COMMENT "Comment"
+ IDS_PROPERTY_POSITION "Position"
+ IDS_PROPERTY_PREFIX "Path Prefix"
+END
diff --git a/CPP/7zip/FileManager/Resource/SettingsPage/SettingsPage.cpp b/CPP/7zip/FileManager/Resource/SettingsPage/SettingsPage.cpp
new file mode 100755
index 00000000..6a681fbc
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/SettingsPage/SettingsPage.cpp
@@ -0,0 +1,113 @@
+// SettingsPage.cpp
+
+#include "StdAfx.h"
+#include "resource.h"
+#include "SettingsPage.h"
+
+#include "Common/StringConvert.h"
+
+#include "Windows/Defs.h"
+#include "Windows/MemoryLock.h"
+
+#include "../../RegistryUtils.h"
+#include "../../HelpUtils.h"
+#include "../../LangUtils.h"
+#include "../../ProgramLocation.h"
+
+using namespace NWindows;
+
+static CIDLangPair kIDLangPairs[] =
+{
+ { IDC_SETTINGS_SHOW_DOTS, 0x03010401},
+ { IDC_SETTINGS_SHOW_REAL_FILE_ICONS, 0x03010402},
+ { IDC_SETTINGS_SHOW_SYSTEM_MENU, 0x03010410},
+ { IDC_SETTINGS_FULL_ROW, 0x03010420},
+ { IDC_SETTINGS_SHOW_GRID, 0x03010421},
+ { IDC_SETTINGS_ALTERNATIVE_SELECTION, 0x03010430},
+ { IDC_SETTINGS_LARGE_PAGES, 0x03010440}
+ // { IDC_SETTINGS_SINGLE_CLICK, 0x03010422},
+ // { IDC_SETTINGS_UNDERLINE, 0x03010423}
+};
+
+static LPCWSTR kEditTopic = L"FM/options.htm#settings";
+
+extern bool IsLargePageSupported();
+
+bool CSettingsPage::OnInit()
+{
+ LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
+
+ CheckButton(IDC_SETTINGS_SHOW_DOTS, ReadShowDots());
+ CheckButton(IDC_SETTINGS_SHOW_SYSTEM_MENU, ReadShowSystemMenu());
+ CheckButton(IDC_SETTINGS_SHOW_REAL_FILE_ICONS, ReadShowRealFileIcons());
+
+ CheckButton(IDC_SETTINGS_FULL_ROW, ReadFullRow());
+ CheckButton(IDC_SETTINGS_SHOW_GRID, ReadShowGrid());
+ CheckButton(IDC_SETTINGS_ALTERNATIVE_SELECTION, ReadAlternativeSelection());
+ if (IsLargePageSupported())
+ CheckButton(IDC_SETTINGS_LARGE_PAGES, ReadLockMemoryEnable());
+ else
+ EnableItem(IDC_SETTINGS_LARGE_PAGES, false);
+ // CheckButton(IDC_SETTINGS_SINGLE_CLICK, ReadSingleClick());
+ // CheckButton(IDC_SETTINGS_UNDERLINE, ReadUnderline());
+
+ // EnableSubItems();
+
+ return CPropertyPage::OnInit();
+}
+
+/*
+void CSettingsPage::EnableSubItems()
+{
+ EnableItem(IDC_SETTINGS_UNDERLINE, IsButtonCheckedBool(IDC_SETTINGS_SINGLE_CLICK));
+}
+*/
+
+LONG CSettingsPage::OnApply()
+{
+ SaveShowDots(IsButtonCheckedBool(IDC_SETTINGS_SHOW_DOTS));
+ SaveShowSystemMenu(IsButtonCheckedBool(IDC_SETTINGS_SHOW_SYSTEM_MENU));
+ SaveShowRealFileIcons(IsButtonCheckedBool(IDC_SETTINGS_SHOW_REAL_FILE_ICONS));
+
+ SaveFullRow(IsButtonCheckedBool(IDC_SETTINGS_FULL_ROW));
+ SaveShowGrid(IsButtonCheckedBool(IDC_SETTINGS_SHOW_GRID));
+ SaveAlternativeSelection(IsButtonCheckedBool(IDC_SETTINGS_ALTERNATIVE_SELECTION));
+ if (IsLargePageSupported())
+ {
+ bool enable = IsButtonCheckedBool(IDC_SETTINGS_LARGE_PAGES);
+ NSecurity::EnableLockMemoryPrivilege(enable);
+ SaveLockMemoryEnable(enable);
+ }
+
+ // SaveSingleClick(IsButtonCheckedBool(IDC_SETTINGS_SINGLE_CLICK));
+ // SaveUnderline(IsButtonCheckedBool(IDC_SETTINGS_UNDERLINE));
+
+ return PSNRET_NOERROR;
+}
+
+void CSettingsPage::OnNotifyHelp()
+{
+ ShowHelpWindow(NULL, kEditTopic); // change it
+}
+
+bool CSettingsPage::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch(buttonID)
+ {
+ /*
+ case IDC_SETTINGS_SINGLE_CLICK:
+ EnableSubItems();
+ break;
+ */
+ case IDC_SETTINGS_SHOW_DOTS:
+ case IDC_SETTINGS_SHOW_SYSTEM_MENU:
+ case IDC_SETTINGS_SHOW_REAL_FILE_ICONS:
+ case IDC_SETTINGS_FULL_ROW:
+ case IDC_SETTINGS_SHOW_GRID:
+ case IDC_SETTINGS_ALTERNATIVE_SELECTION:
+ case IDC_SETTINGS_LARGE_PAGES:
+ Changed();
+ return true;
+ }
+ return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
+}
diff --git a/CPP/7zip/FileManager/Resource/SettingsPage/SettingsPage.h b/CPP/7zip/FileManager/Resource/SettingsPage/SettingsPage.h
new file mode 100755
index 00000000..e5fe6e67
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/SettingsPage/SettingsPage.h
@@ -0,0 +1,19 @@
+// SettingsPage.h
+
+#ifndef __SETTINGSPAGE_H
+#define __SETTINGSPAGE_H
+
+#include "Windows/Control/PropertyPage.h"
+#include "Windows/Control/Edit.h"
+
+class CSettingsPage: public NWindows::NControl::CPropertyPage
+{
+ // void EnableSubItems();
+ bool OnButtonClicked(int buttonID, HWND buttonHWND);
+public:
+ virtual bool OnInit();
+ virtual void OnNotifyHelp();
+ virtual LONG OnApply();
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/SettingsPage/StdAfx.h b/CPP/7zip/FileManager/Resource/SettingsPage/StdAfx.h
new file mode 100755
index 00000000..a444ca31
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/SettingsPage/StdAfx.h
@@ -0,0 +1,16 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#define _WIN32_WINNT 0x0400
+
+// it's for Windows NT supporting (MENUITEMINFOW)
+#define WINVER 0x0400
+
+#include <windows.h>
+#include <commctrl.h>
+
+#include "Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/SettingsPage/resource.h b/CPP/7zip/FileManager/Resource/SettingsPage/resource.h
new file mode 100755
index 00000000..8932dc0e
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/SettingsPage/resource.h
@@ -0,0 +1,11 @@
+#define IDD_SETTINGS 904
+#define IDC_SETTINGS_SHOW_DOTS 1000
+#define IDC_SETTINGS_SHOW_REAL_FILE_ICONS 1001
+
+#define IDC_SETTINGS_SHOW_SYSTEM_MENU 1010
+#define IDC_SETTINGS_FULL_ROW 1011
+#define IDC_SETTINGS_SHOW_GRID 1013
+#define IDC_SETTINGS_SINGLE_CLICK 1014
+#define IDC_SETTINGS_UNDERLINE 1015
+#define IDC_SETTINGS_ALTERNATIVE_SELECTION 1016
+#define IDC_SETTINGS_LARGE_PAGES 1017
diff --git a/CPP/7zip/FileManager/Resource/SettingsPage/resource.rc b/CPP/7zip/FileManager/Resource/SettingsPage/resource.rc
new file mode 100755
index 00000000..69afeba7
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/SettingsPage/resource.rc
@@ -0,0 +1,35 @@
+#include "resource.h"
+#include "../../../GuiCommon.rc"
+
+#define xSize2 196
+#define ySize2 140
+#define xSize (xSize2 + marg + marg)
+#define ySize (ySize2 + marg + marg)
+
+
+IDD_SETTINGS DIALOG 0, 0, xSize, ySize MY_PAGE_STYLE
+CAPTION "Settings"
+MY_FONT
+BEGIN
+ CONTROL "Show "".."" item", IDC_SETTINGS_SHOW_DOTS, "Button", BS_AUTOCHECKBOX | WS_TABSTOP,
+ marg, marg, xSize2, 10
+ CONTROL "Show real file &icons", IDC_SETTINGS_SHOW_REAL_FILE_ICONS, "Button", BS_AUTOCHECKBOX | WS_TABSTOP,
+ marg, 21, xSize2, 10
+ CONTROL "Show system &menu", IDC_SETTINGS_SHOW_SYSTEM_MENU, "Button", BS_AUTOCHECKBOX | WS_TABSTOP,
+ marg, 35, xSize2, 10
+ CONTROL "&Full row select", IDC_SETTINGS_FULL_ROW, "Button", BS_AUTOCHECKBOX | WS_TABSTOP,
+ marg, 63, xSize2, 10
+ CONTROL "Show &grid lines", IDC_SETTINGS_SHOW_GRID, "Button", BS_AUTOCHECKBOX | WS_TABSTOP,
+ marg, 77, xSize2, 10
+ CONTROL "&Single-click to open an item", IDC_SETTINGS_SINGLE_CLICK, "Button", BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,
+ marg, 91, xSize2, 10
+ CONTROL "&Underline current name", IDC_SETTINGS_UNDERLINE, "Button", BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,
+ marg + 12, 105, xSize2 - 12, 10
+
+ CONTROL "&Alternative selection mode", IDC_SETTINGS_ALTERNATIVE_SELECTION, "Button", BS_AUTOCHECKBOX | WS_TABSTOP,
+ marg, 122, xSize2, 10
+
+ CONTROL "Use &large memory pages", IDC_SETTINGS_LARGE_PAGES, "Button", BS_AUTOCHECKBOX | WS_TABSTOP,
+ marg, 142, xSize2, 10
+
+END
diff --git a/CPP/7zip/FileManager/Resource/SplitDialog/SplitDialog.cpp b/CPP/7zip/FileManager/Resource/SplitDialog/SplitDialog.cpp
new file mode 100755
index 00000000..383fa48a
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/SplitDialog/SplitDialog.cpp
@@ -0,0 +1,89 @@
+// SplitDialog.cpp
+
+#include "StdAfx.h"
+#include "SplitDialog.h"
+
+#include "Common/StringToInt.h"
+#include "Windows/Shell.h"
+#include "Windows/FileName.h"
+
+#include "../../SplitUtils.h"
+#ifdef LANG
+#include "../../LangUtils.h"
+#endif
+
+#include "../CopyDialog/resource.h"
+
+using namespace NWindows;
+
+#ifdef LANG
+static CIDLangPair kIDLangPairs[] =
+{
+ { IDC_STATIC_SPLIT_PATH, 0x03020501 },
+ { IDC_STATIC_SPLIT_VOLUME, 0x02000D40 },
+};
+#endif
+
+
+bool CSplitDialog::OnInit()
+{
+ #ifdef LANG
+ LangSetWindowText(HWND(*this), 0x03020500);
+ LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
+ #endif
+ _pathCombo.Attach(GetItem(IDC_COMBO_SPLIT_PATH));
+ _volumeCombo.Attach(GetItem(IDC_COMBO_SPLIT_VOLUME));
+
+ if (!FilePath.IsEmpty())
+ {
+ UString title;
+ GetText(title);
+ title += L' ';
+ title += FilePath;
+ SetText(title);
+ }
+ _pathCombo.SetText(Path);
+ AddVolumeItems(_volumeCombo);
+ _volumeCombo.SetCurSel(0);
+ return CModalDialog::OnInit();
+}
+
+bool CSplitDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch(buttonID)
+ {
+ case IDC_BUTTON_SPLIT_PATH:
+ OnButtonSetPath();
+ return true;
+ }
+ return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
+}
+
+void CSplitDialog::OnButtonSetPath()
+{
+ UString currentPath;
+ _pathCombo.GetText(currentPath);
+ // UString title = L"Specify a location for output folder";
+ UString title = LangStringSpec(IDS_SET_FOLDER, 0x03020209);
+
+ UString resultPath;
+ if (!NShell::BrowseForFolder(HWND(*this), title, currentPath, resultPath))
+ return;
+ NFile::NName::NormalizeDirPathPrefix(resultPath);
+ _pathCombo.SetCurSel(-1);
+ _pathCombo.SetText(resultPath);
+}
+
+void CSplitDialog::OnOK()
+{
+ _pathCombo.GetText(Path);
+ UString volumeString;
+ _volumeCombo.GetText(volumeString);
+ volumeString.Trim();
+ if (!ParseVolumeSizes(volumeString, VolumeSizes) || VolumeSizes.Size() == 0)
+ {
+ ::MessageBoxW(*this, LangString(IDS_COMPRESS_INCORRECT_VOLUME_SIZE, 0x02000D41), L"7-Zip", 0);
+ return;
+ }
+ CModalDialog::OnOK();
+}
diff --git a/CPP/7zip/FileManager/Resource/SplitDialog/SplitDialog.h b/CPP/7zip/FileManager/Resource/SplitDialog/SplitDialog.h
new file mode 100755
index 00000000..d73dcbca
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/SplitDialog/SplitDialog.h
@@ -0,0 +1,27 @@
+// SplitDialog.h
+
+#ifndef __SPLITDIALOG_H
+#define __SPLITDIALOG_H
+
+#include "Common/Types.h"
+#include "Windows/Control/Dialog.h"
+#include "Windows/Control/ComboBox.h"
+#include "resource.h"
+
+class CSplitDialog: public NWindows::NControl::CModalDialog
+{
+ NWindows::NControl::CComboBox _pathCombo;
+ NWindows::NControl::CComboBox _volumeCombo;
+ virtual void OnOK();
+ virtual bool OnInit();
+ virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
+ void OnButtonSetPath();
+public:
+ UString FilePath;
+ UString Path;
+ CRecordVector<UInt64> VolumeSizes;
+ INT_PTR Create(HWND parentWindow = 0)
+ { return CModalDialog::Create(IDD_DIALOG_SPLIT, parentWindow); }
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/SplitDialog/StdAfx.h b/CPP/7zip/FileManager/Resource/SplitDialog/StdAfx.h
new file mode 100755
index 00000000..eb2ba641
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/SplitDialog/StdAfx.h
@@ -0,0 +1,18 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#define _WIN32_WINNT 0x0400
+
+// it's for Windows NT supporting (MENUITEMINFOW)
+#define WINVER 0x0400
+
+#include <windows.h>
+#include <commctrl.h>
+
+// #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+
+#include "Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/SplitDialog/resource.h b/CPP/7zip/FileManager/Resource/SplitDialog/resource.h
new file mode 100755
index 00000000..019b7029
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/SplitDialog/resource.h
@@ -0,0 +1,8 @@
+#define IDD_DIALOG_SPLIT 504
+#define IDC_STATIC_SPLIT_PATH 1000
+#define IDC_COMBO_SPLIT_PATH 1001
+#define IDC_BUTTON_SPLIT_PATH 1002
+#define IDC_STATIC_SPLIT_VOLUME 1010
+#define IDC_COMBO_SPLIT_VOLUME 1011
+
+#define IDS_COMPRESS_INCORRECT_VOLUME_SIZE 95
diff --git a/CPP/7zip/FileManager/Resource/SplitDialog/resource.rc b/CPP/7zip/FileManager/Resource/SplitDialog/resource.rc
new file mode 100755
index 00000000..5282ee7d
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/SplitDialog/resource.rc
@@ -0,0 +1,32 @@
+#include "resource.h"
+#include "../../../GuiCommon.rc"
+
+#define xSize2 223
+#define ySize2 89
+
+#define xSize (xSize2 + marg + marg)
+#define ySize (ySize2 + marg + marg)
+
+#define bYPos (ySize - marg - bYSize)
+#define b1XPos (xSize - marg - bXSize)
+#define b2XPos (b1XPos - 10 - bXSize)
+
+
+
+IDD_DIALOG_SPLIT DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE
+CAPTION "Split File"
+MY_FONT
+BEGIN
+ LTEXT "&Split to:", IDC_STATIC_SPLIT_PATH, marg, marg, xSize2, 8
+ COMBOBOX IDC_COMBO_SPLIT_PATH, marg, 18, xSize2 - bDotsSize - 12, 126, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "...", IDC_BUTTON_SPLIT_PATH, xSize - marg - bDotsSize, 17, bDotsSize, bYSize, WS_GROUP
+ LTEXT "Split to &volumes, bytes:", IDC_STATIC_SPLIT_VOLUME, marg, 38, xSize2, 8
+ COMBOBOX IDC_COMBO_SPLIT_VOLUME, marg, 50, 120, 52, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "OK", IDOK, b2XPos, bYPos, bXSize, bYSize
+ PUSHBUTTON "Cancel", IDCANCEL, b1XPos, bYPos, bXSize, bYSize
+END
+
+STRINGTABLE
+BEGIN
+ IDS_COMPRESS_INCORRECT_VOLUME_SIZE "Incorrect volume size"
+END
diff --git a/CPP/7zip/FileManager/Resource/SystemPage/StdAfx.h b/CPP/7zip/FileManager/Resource/SystemPage/StdAfx.h
new file mode 100755
index 00000000..a444ca31
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/SystemPage/StdAfx.h
@@ -0,0 +1,16 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#define _WIN32_WINNT 0x0400
+
+// it's for Windows NT supporting (MENUITEMINFOW)
+#define WINVER 0x0400
+
+#include <windows.h>
+#include <commctrl.h>
+
+#include "Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/SystemPage/SystemPage.cpp b/CPP/7zip/FileManager/Resource/SystemPage/SystemPage.cpp
new file mode 100755
index 00000000..ca3b7432
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/SystemPage/SystemPage.cpp
@@ -0,0 +1,435 @@
+// SystemDialog.cpp
+
+#include "StdAfx.h"
+#include "resource.h"
+#include "SystemPage.h"
+
+#include "Common/StringConvert.h"
+#include "Common/MyCom.h"
+
+#include "Windows/Defs.h"
+#include "Windows/Control/ListView.h"
+
+#include "../../IFolder.h"
+#include "../../HelpUtils.h"
+#include "../../LangUtils.h"
+#include "../../PluginLoader.h"
+#include "../../ProgramLocation.h"
+#include "../../StringUtils.h"
+
+#include "../PropertyName/resource.h"
+
+using namespace NRegistryAssociations;
+
+const int kRefreshpluginsListMessage = WM_USER + 1;
+const int kUpdateDatabase = kRefreshpluginsListMessage + 1;
+
+static CIDLangPair kIDLangPairs[] =
+{
+ { IDC_SYSTEM_STATIC_ASSOCIATE, 0x03010302},
+ { IDC_SYSTEM_SELECT_ALL, 0x03000330}
+};
+
+static LPCWSTR kSystemTopic = L"FM/options.htm#system";
+
+
+bool CSystemPage::OnInit()
+{
+ _initMode = true;
+ LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
+
+ _listViewExt.Attach(GetItem(IDC_SYSTEM_LIST_ASSOCIATE));
+ _listViewPlugins.Attach(GetItem(IDC_SYSTEM_LIST_PLUGINS));
+
+ /*
+ CheckButton(IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU,
+ NRegistryAssociations::CheckContextMenuHandler());
+ */
+
+ UINT32 newFlags = LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT;
+ _listViewExt.SetExtendedListViewStyle(newFlags, newFlags);
+ _listViewPlugins.SetExtendedListViewStyle(newFlags, newFlags);
+
+ UString s = LangString(IDS_PROPERTY_EXTENSION, 0x02000205);
+ LVCOLUMNW column;
+ column.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_FMT | LVCF_SUBITEM;
+ column.cx = 70;
+ column.fmt = LVCFMT_LEFT;
+ column.pszText = (LPWSTR)(LPCWSTR)s;
+ column.iSubItem = 0;
+ _listViewExt.InsertColumn(0, &column);
+
+ s = LangString(IDS_PLUGIN, 0x03010310);
+ column.cx = 70;
+ column.pszText = (LPWSTR)(LPCWSTR)s;
+ column.iSubItem = 1;
+ _listViewExt.InsertColumn(1, &column);
+
+ s = LangString(IDS_PLUGIN, 0x03010310);
+ column.cx = 70;
+ column.pszText = (LPWSTR)(LPCWSTR)s;
+ column.iSubItem = 0;
+ _listViewPlugins.InsertColumn(0, &column);
+
+ _extDatabase.Read();
+
+ for (int i = 0; i < _extDatabase.ExtBigItems.Size(); i++)
+ {
+ CExtInfoBig &extInfo = _extDatabase.ExtBigItems[i];
+
+ LVITEMW item;
+ item.iItem = i;
+ item.mask = LVIF_TEXT | LVIF_PARAM;
+ item.lParam = i;
+ item.pszText = (LPWSTR)(LPCWSTR)extInfo.Ext;
+ item.iSubItem = 0;
+ int itemIndex = _listViewExt.InsertItem(&item);
+
+ extInfo.Associated = NRegistryAssociations::CheckShellExtensionInfo(GetSystemString(extInfo.Ext));
+ _listViewExt.SetCheckState(itemIndex, extInfo.Associated);
+
+ SetMainPluginText(itemIndex, i);
+ }
+ // _listViewExt.SortItems();
+
+ if(_listViewExt.GetItemCount() > 0)
+ {
+ UINT state = LVIS_SELECTED | LVIS_FOCUSED;
+ _listViewExt.SetItemState(0, state, state);
+ }
+ RefreshPluginsList(-1);
+ _initMode = false;
+
+ return CPropertyPage::OnInit();
+}
+
+void CSystemPage::SetMainPluginText(int itemIndex, int indexInDatabase)
+{
+ LVITEMW item;
+ item.iItem = itemIndex;
+ item.mask = LVIF_TEXT;
+ UString mainPlugin = _extDatabase.GetMainPluginNameForExtItem(indexInDatabase);
+ item.pszText = (WCHAR *)(const WCHAR *)mainPlugin;
+ item.iSubItem = 1;
+ _listViewExt.SetItem(&item);
+}
+
+static UString GetProgramCommand()
+{
+ UString path = L"\"";
+ UString folder;
+ if (GetProgramFolderPath(folder))
+ path += folder;
+ path += L"7zFM.exe\" \"%1\"";
+ return path;
+}
+
+static UString GetIconPath(const UString &filePath,
+ const CLSID &clsID, const UString &extension)
+{
+ CPluginLibrary library;
+ CMyComPtr<IFolderManager> folderManager;
+ CMyComPtr<IFolderFolder> folder;
+ if (library.LoadAndCreateManager(filePath, clsID, &folderManager) != S_OK)
+ return UString();
+ CMyComBSTR typesString;
+ if (folderManager->GetTypes(&typesString) != S_OK)
+ return UString();
+ UStringVector types;
+ SplitString((const wchar_t *)typesString, types);
+ for (int typeIndex = 0; typeIndex < types.Size(); typeIndex++)
+ {
+ const UString &type = types[typeIndex];
+ CMyComBSTR extTemp;
+ if (folderManager->GetExtension(type, &extTemp) != S_OK)
+ continue;
+ if (extension.CompareNoCase((const wchar_t *)extTemp) == 0)
+ {
+ CMyComPtr<IFolderManagerGetIconPath> getIconPath;
+ if (folderManager.QueryInterface(IID_IFolderManagerGetIconPath, &getIconPath) != S_OK)
+ break;
+ CMyComBSTR iconPathTemp;
+ if (getIconPath->GetIconPath(type, &iconPathTemp) != S_OK)
+ break;
+ return (const wchar_t *)iconPathTemp;
+ }
+ }
+ return UString();
+}
+
+LONG CSystemPage::OnApply()
+{
+ UpdateDatabase();
+ _extDatabase.Save();
+ UString command = GetProgramCommand();
+
+ for (int i = 0; i < _extDatabase.ExtBigItems.Size(); i++)
+ {
+ const CExtInfoBig &extInfo = _extDatabase.ExtBigItems[i];
+ if (extInfo.Associated)
+ {
+ UString title = extInfo.Ext + UString(L" Archive");
+ UString command = GetProgramCommand();
+ UString iconPath;
+ if (!extInfo.PluginsPairs.IsEmpty())
+ {
+ const CPluginInfo &plugin = _extDatabase.Plugins[extInfo.PluginsPairs[0].Index];
+ iconPath = GetIconPath(plugin.FilePath, plugin.ClassID, extInfo.Ext);
+ }
+ NRegistryAssociations::AddShellExtensionInfo(
+ GetSystemString(extInfo.Ext),
+ title,
+ command,
+ iconPath, NULL, 0);
+ }
+ else
+ NRegistryAssociations::DeleteShellExtensionInfo(GetSystemString(extInfo.Ext));
+ }
+ /*
+ if (IsButtonCheckedBool(IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU))
+ NRegistryAssociations::AddContextMenuHandler();
+ else
+ NRegistryAssociations::DeleteContextMenuHandler();
+ */
+ SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
+ return PSNRET_NOERROR;
+}
+
+void CSystemPage::OnNotifyHelp()
+{
+ ShowHelpWindow(NULL, kSystemTopic);
+}
+
+void CSystemPage::SelectAll()
+{
+ int count = _listViewExt.GetItemCount();
+ for (int i = 0; i < count; i++)
+ _listViewExt.SetCheckState(i, true);
+ UpdateDatabase();
+}
+
+bool CSystemPage::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch(buttonID)
+ {
+ case IDC_SYSTEM_SELECT_ALL:
+ {
+ SelectAll();
+ Changed();
+ return true;
+ }
+ }
+ return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
+}
+
+bool CSystemPage::OnNotify(UINT controlID, LPNMHDR lParam)
+{
+ if (lParam->hwndFrom == HWND(_listViewExt))
+ {
+ switch(lParam->code)
+ {
+ case (LVN_ITEMCHANGED):
+ return OnItemChanged((const NMLISTVIEW *)lParam);
+ case NM_RCLICK:
+ case NM_DBLCLK:
+ case LVN_KEYDOWN:
+ case NM_CLICK:
+ case LVN_BEGINRDRAG:
+ PostMessage(kRefreshpluginsListMessage, 0);
+ PostMessage(kUpdateDatabase, 0);
+ break;
+ }
+ }
+ else if (lParam->hwndFrom == HWND(_listViewPlugins))
+ {
+ switch(lParam->code)
+ {
+ case NM_RCLICK:
+ case NM_DBLCLK:
+ // case LVN_KEYDOWN:
+ case NM_CLICK:
+ case LVN_BEGINRDRAG:
+ PostMessage(kUpdateDatabase, 0);
+ break;
+
+ case (LVN_ITEMCHANGED):
+ {
+ OnItemChanged((const NMLISTVIEW *)lParam);
+ PostMessage(kUpdateDatabase, 0);
+ break;
+ }
+ case LVN_KEYDOWN:
+ {
+ OnPluginsKeyDown((LPNMLVKEYDOWN)lParam);
+ PostMessage(kUpdateDatabase, 0);
+ break;
+ }
+ }
+ }
+ return CPropertyPage::OnNotify(controlID, lParam);
+}
+
+bool CSystemPage::OnPluginsKeyDown(LPNMLVKEYDOWN keyDownInfo)
+{
+ bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0;
+ // bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0;
+ switch(keyDownInfo->wVKey)
+ {
+ case VK_UP:
+ {
+ if (alt)
+ MovePlugin(true);
+ return true;
+ }
+ case VK_DOWN:
+ {
+ if (alt)
+ MovePlugin(false);
+ return true;
+ }
+ }
+ return false;
+}
+
+void CSystemPage::MovePlugin(bool upDirection)
+{
+ int selectedPlugin = _listViewPlugins.GetSelectionMark();
+ if (selectedPlugin < 0)
+ return;
+ int newIndex = selectedPlugin + (upDirection ? -1: 1);
+ if (newIndex < 0 || newIndex >= _listViewPlugins.GetItemCount())
+ return;
+ int selectedExtIndex = GetSelectedExtIndex();
+ if (selectedExtIndex < 0)
+ return;
+ CExtInfoBig &extInfo = _extDatabase.ExtBigItems[selectedExtIndex];
+ CPluginEnabledPair pluginPairTemp = extInfo.PluginsPairs[newIndex];
+ extInfo.PluginsPairs[newIndex] = extInfo.PluginsPairs[selectedPlugin];
+ extInfo.PluginsPairs[selectedPlugin] = pluginPairTemp;
+
+ SetMainPluginText(_listViewExt.GetSelectionMark(), selectedExtIndex);
+ RefreshPluginsList(newIndex);
+
+ Changed();
+}
+
+bool CSystemPage::OnItemChanged(const NMLISTVIEW *info)
+{
+ if (_initMode)
+ return true;
+ if ((info->uChanged & LVIF_STATE) != 0)
+ {
+ UINT oldState = info->uOldState & LVIS_STATEIMAGEMASK;
+ UINT newState = info->uNewState & LVIS_STATEIMAGEMASK;
+ if (oldState != newState)
+ Changed();
+ }
+ // PostMessage(kRefreshpluginsListMessage, 0);
+ // RefreshPluginsList();
+ return true;
+}
+
+bool CSystemPage::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch(message)
+ {
+ case kRefreshpluginsListMessage:
+ RefreshPluginsList(-1);
+ return true;
+ case kUpdateDatabase:
+ UpdateDatabase();
+ return true;
+ }
+ return CPropertyPage::OnMessage(message, wParam, lParam);
+}
+
+void CSystemPage::UpdateDatabase()
+{
+ int i;
+ for (i = 0; i < _listViewExt.GetItemCount(); i++)
+ {
+ LPARAM param;
+ if (!_listViewExt.GetItemParam(i, param))
+ return;
+ CExtInfoBig &extInfo = _extDatabase.ExtBigItems[(int)param];
+ extInfo.Associated = _listViewExt.GetCheckState(i);
+ }
+
+ int selectedExtIndex = GetSelectedExtIndex();
+ if (selectedExtIndex < 0)
+ return;
+
+ CExtInfoBig &extInfo = _extDatabase.ExtBigItems[selectedExtIndex];
+ for (i = 0; i < _listViewPlugins.GetItemCount(); i++)
+ {
+ extInfo.PluginsPairs[i].Enabled = _listViewPlugins.GetCheckState(i);
+ }
+}
+
+
+
+int CSystemPage::GetSelectedExtIndex()
+{
+ int selectedIndex = _listViewExt.GetSelectionMark();
+ if (selectedIndex < 0)
+ return -1;
+ LPARAM param;
+ if (!_listViewExt.GetItemParam(selectedIndex, param))
+ return -1;
+ return (int)param;
+}
+
+
+void CSystemPage::RefreshPluginsList(int selectIndex)
+{
+ _listViewPlugins.DeleteAllItems();
+ int selectedExtIndex = GetSelectedExtIndex();
+ if (selectedExtIndex < 0)
+ return;
+ const CExtInfoBig &extInfo = _extDatabase.ExtBigItems[selectedExtIndex];
+
+ _initMode = true;
+ for (int i = 0; i < extInfo.PluginsPairs.Size(); i++)
+ {
+ CPluginEnabledPair pluginPair = extInfo.PluginsPairs[i];
+ UString pluginName = _extDatabase.Plugins[pluginPair.Index].Name;
+ LVITEMW item;
+ item.iItem = i;
+ item.mask = LVIF_TEXT | LVIF_PARAM;
+ item.lParam = i;
+ item.pszText = (LPWSTR)(LPCWSTR)pluginName;
+ item.iSubItem = 0;
+ int itemIndex = _listViewPlugins.InsertItem(&item);
+ _listViewPlugins.SetCheckState(itemIndex, pluginPair.Enabled);
+ }
+ if(_listViewPlugins.GetItemCount() > 0)
+ {
+ if (selectIndex < 0)
+ selectIndex = 0;
+ UINT state = LVIS_SELECTED | LVIS_FOCUSED;
+ _listViewPlugins.SetItemState(selectIndex, state, state);
+ }
+ _initMode = false;
+}
+
+
+
+/*
+static BYTE kZipShellNewData[] =
+ { 0x50-1, 0x4B, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0 };
+
+static BYTE kRarShellNewData[] =
+ { 0x52-1, 0x61, 0x72, 0x21, 0x1A, 7, 0, 0xCF, 0x90, 0x73, 0, 0, 0x0D, 0, 0, 0, 0, 0, 0, 0};
+
+class CSignatureMaker
+{
+public:
+ CSignatureMaker()
+ {
+ kZipShellNewData[0]++;
+ kRarShellNewData[0]++;
+ };
+};
+
+static CSignatureMaker g_SignatureMaker;
+*/
diff --git a/CPP/7zip/FileManager/Resource/SystemPage/SystemPage.h b/CPP/7zip/FileManager/Resource/SystemPage/SystemPage.h
new file mode 100755
index 00000000..3798f640
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/SystemPage/SystemPage.h
@@ -0,0 +1,40 @@
+// SystemPage.h
+
+#ifndef __SYSTEMPAGE_H
+#define __SYSTEMPAGE_H
+
+#include "Windows/Control/PropertyPage.h"
+#include "Windows/Control/ListView.h"
+
+#include "../../FilePlugins.h"
+
+class CSystemPage: public NWindows::NControl::CPropertyPage
+{
+ bool _initMode;
+ CExtDatabase _extDatabase;
+
+ // CObjectVector<NZipRootRegistry::CArchiverInfo> m_Archivers;
+ NWindows::NControl::CListView _listViewExt;
+ NWindows::NControl::CListView _listViewPlugins;
+
+ void SetMainPluginText(int itemIndex, int indexInDatabase);
+
+ int GetSelectedExtIndex();
+ void RefreshPluginsList(int selectIndex);
+ void MovePlugin(bool upDirection);
+ void UpdateDatabase();
+ void SelectAll();
+
+public:
+ virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+ virtual bool OnInit();
+ virtual void OnNotifyHelp();
+ virtual bool OnNotify(UINT controlID, LPNMHDR lParam);
+ virtual bool OnItemChanged(const NMLISTVIEW *info);
+
+ virtual LONG OnApply();
+ virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
+ bool OnPluginsKeyDown(LPNMLVKEYDOWN keyDownInfo);
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/Resource/SystemPage/resource.h b/CPP/7zip/FileManager/Resource/SystemPage/resource.h
new file mode 100755
index 00000000..8dce778b
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/SystemPage/resource.h
@@ -0,0 +1,7 @@
+#define IDD_SYSTEM 902
+#define IDS_PLUGIN 990
+// #define IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU 1010
+#define IDC_SYSTEM_STATIC_ASSOCIATE 1020
+#define IDC_SYSTEM_LIST_ASSOCIATE 1021
+#define IDC_SYSTEM_LIST_PLUGINS 1022
+#define IDC_SYSTEM_SELECT_ALL 1023
diff --git a/CPP/7zip/FileManager/Resource/SystemPage/resource.rc b/CPP/7zip/FileManager/Resource/SystemPage/resource.rc
new file mode 100755
index 00000000..cf19d11b
--- /dev/null
+++ b/CPP/7zip/FileManager/Resource/SystemPage/resource.rc
@@ -0,0 +1,31 @@
+#include "resource.h"
+#include "../../../GuiCommon.rc"
+
+#define xSize2 238
+#define ySize2 214
+#define xSize (xSize2 + marg + marg)
+#define ySize (ySize2 + marg + marg)
+#define gSpace 30
+#define g0Size 110
+#define gYSize (ySize2 - 20 - bYSize)
+
+
+IDD_SYSTEM DIALOG 0, 0, xSize, ySize MY_PAGE_STYLE
+CAPTION "System"
+MY_FONT
+BEGIN
+ LTEXT "Associate 7-Zip with:", IDC_SYSTEM_STATIC_ASSOCIATE, marg, marg, xSize2, 8
+ CONTROL "List1", IDC_SYSTEM_LIST_ASSOCIATE, "SysListView32",
+ LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP,
+ marg, 20, g0Size, gYSize
+ CONTROL "List1", IDC_SYSTEM_LIST_PLUGINS, "SysListView32",
+ LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | NOT WS_VISIBLE | WS_BORDER | WS_TABSTOP,
+ marg + g0Size + gSpace, 20, xSize2 - gSpace - g0Size, gYSize
+ PUSHBUTTON "Select all", IDC_SYSTEM_SELECT_ALL, marg, (ySize - marg - bYSize), 90, bYSize
+
+END
+
+STRINGTABLE
+BEGIN
+ IDS_PLUGIN "Plugin"
+END
diff --git a/CPP/7zip/FileManager/RootFolder.cpp b/CPP/7zip/FileManager/RootFolder.cpp
new file mode 100755
index 00000000..4ff0660b
--- /dev/null
+++ b/CPP/7zip/FileManager/RootFolder.cpp
@@ -0,0 +1,204 @@
+// RootFolder.cpp
+
+#include "StdAfx.h"
+
+#include "resource.h"
+
+#include "RootFolder.h"
+
+#include "Common/StringConvert.h"
+#include "../PropID.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+
+#include "FSDrives.h"
+#include "PhysDriveFolder.h"
+#include "NetFolder.h"
+#include "SysIconUtils.h"
+#include "LangUtils.h"
+
+using namespace NWindows;
+
+
+static const STATPROPSTG kProperties[] =
+{
+ { NULL, kpidName, VT_BSTR}
+};
+
+// static const wchar_t *kMyComputerTitle = L"Computer";
+// static const wchar_t *kMyNetworkTitle = L"Network";
+
+void CRootFolder::Init()
+{
+ _computerName = LangString(IDS_COMPUTER, 0x03020300);
+ _networkName = LangString(IDS_NETWORK, 0x03020301);
+};
+
+STDMETHODIMP CRootFolder::LoadItems()
+{
+ Init();
+ return S_OK;
+}
+
+STDMETHODIMP CRootFolder::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = 2;
+ return S_OK;
+}
+
+STDMETHODIMP CRootFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value)
+{
+ NCOM::CPropVariant propVariant;
+ switch(propID)
+ {
+ case kpidIsFolder:
+ propVariant = true;
+ break;
+ case kpidName:
+ if (itemIndex == 0)
+ propVariant = _computerName;
+ else if (itemIndex == 1)
+ propVariant = _networkName;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
+
+STDMETHODIMP CRootFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder)
+{
+ if (index == 0)
+ {
+ CFSDrives *fsDrivesSpec = new CFSDrives;
+ CMyComPtr<IFolderFolder> subFolder = fsDrivesSpec;
+ fsDrivesSpec->Init();
+ *resultFolder = subFolder.Detach();
+ }
+ else if (index == 1)
+ {
+ CNetFolder *netFolderSpec = new CNetFolder;
+ CMyComPtr<IFolderFolder> subFolder = netFolderSpec;
+ netFolderSpec->Init(0, 0, _networkName + L'\\');
+ *resultFolder = subFolder.Detach();
+ }
+ else
+ return E_INVALIDARG;
+ return S_OK;
+}
+
+STDMETHODIMP CRootFolder::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder)
+{
+ *resultFolder = 0;
+ UString name2 = name;
+ name2.Trim();
+ if (name2.IsEmpty())
+ {
+ CRootFolder *rootFolderSpec = new CRootFolder;
+ CMyComPtr<IFolderFolder> rootFolder = rootFolderSpec;
+ rootFolderSpec->Init();
+ *resultFolder = rootFolder.Detach();
+ return S_OK;
+ }
+ if (name2 == _computerName ||
+ name2 == (_computerName + UString(L'\\')))
+ return BindToFolder(UInt32(0), resultFolder);
+ if (name2 == _networkName ||
+ name2 == (_networkName + UString(L'\\')))
+ return BindToFolder(UInt32(1), resultFolder);
+ if (name2 == UString(L'\\'))
+ {
+ CMyComPtr<IFolderFolder> subFolder = this;
+ *resultFolder = subFolder.Detach();
+ return S_OK;
+ }
+
+ if (name2.Length () < 2)
+ return E_INVALIDARG;
+
+ CMyComPtr<IFolderFolder> subFolder;
+
+ if (name2.Left(4) == L"\\\\.\\")
+ {
+ CPhysDriveFolder *folderSpec = new CPhysDriveFolder;
+ subFolder = folderSpec;
+ RINOK(folderSpec->Init(name2.Mid(4, 2)));
+ }
+ else
+ {
+ if (name2[name2.Length () - 1] != L'\\')
+ name2 += L'\\';
+ CFSFolder *fsFolderSpec = new CFSFolder;
+ subFolder = fsFolderSpec;
+ if (fsFolderSpec->Init(name2, 0) != S_OK)
+ {
+ if (name2[0] == L'\\')
+ {
+ CNetFolder *netFolderSpec = new CNetFolder;
+ subFolder = netFolderSpec;
+ netFolderSpec->Init(name2);
+ }
+ else
+ return E_INVALIDARG;
+ }
+ }
+ *resultFolder = subFolder.Detach();
+ return S_OK;
+}
+
+STDMETHODIMP CRootFolder::BindToParentFolder(IFolderFolder **resultFolder)
+{
+ *resultFolder = 0;
+ return S_OK;
+}
+
+STDMETHODIMP CRootFolder::GetName(BSTR * /* name */)
+{
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP CRootFolder::GetNumberOfProperties(UInt32 *numProperties)
+{
+ *numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
+ return S_OK;
+}
+
+STDMETHODIMP CRootFolder::GetPropertyInfo(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType)
+{
+ if (index >= sizeof(kProperties) / sizeof(kProperties[0]))
+ return E_INVALIDARG;
+ const STATPROPSTG &prop = kProperties[index];
+ *propID = prop.propid;
+ *varType = prop.vt;
+ *name = 0;
+ return S_OK;
+}
+
+STDMETHODIMP CRootFolder::GetTypeID(BSTR *name)
+{
+ CMyComBSTR temp = L"RootFolder";
+ *name = temp.Detach();
+ return S_OK;
+}
+
+STDMETHODIMP CRootFolder::GetPath(BSTR *path)
+{
+ CMyComBSTR temp = L"";
+ *path = temp.Detach();
+ return S_OK;
+}
+
+STDMETHODIMP CRootFolder::GetSystemIconIndex(UInt32 index, INT32 *iconIndex)
+{
+ int aCSIDL;
+ if (index == 0)
+ aCSIDL = CSIDL_DRIVES;
+ else
+ aCSIDL = CSIDL_NETWORK;
+ *iconIndex = GetIconIndexForCSIDL(aCSIDL);
+ return S_OK;
+}
+
+
+
+
diff --git a/CPP/7zip/FileManager/RootFolder.h b/CPP/7zip/FileManager/RootFolder.h
new file mode 100755
index 00000000..16bac250
--- /dev/null
+++ b/CPP/7zip/FileManager/RootFolder.h
@@ -0,0 +1,49 @@
+// RootFolder.h
+
+#ifndef __ROOTFOLDER_H
+#define __ROOTFOLDER_H
+
+#include "Common/String.h"
+
+#include "Windows/PropVariant.h"
+
+#include "FSFolder.h"
+
+class CRootFolder:
+ public IFolderFolder,
+ public IEnumProperties,
+ public IFolderGetTypeID,
+ public IFolderGetPath,
+ public IFolderGetSystemIconIndex,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP4(
+ IEnumProperties,
+ IFolderGetTypeID,
+ IFolderGetPath,
+ IFolderGetSystemIconIndex
+ )
+
+ STDMETHOD(LoadItems)();
+ STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
+ STDMETHOD(GetProperty)(UInt32 itemIndex, PROPID propID, PROPVARIANT *value);
+ STDMETHOD(BindToFolder)(UInt32 index, IFolderFolder **resultFolder);
+ STDMETHOD(BindToFolder)(const wchar_t *name, IFolderFolder **resultFolder);
+ STDMETHOD(BindToParentFolder)(IFolderFolder **resultFolder);
+ STDMETHOD(GetName)(BSTR *name);
+
+ STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
+ STDMETHOD(GetPropertyInfo)(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType);
+ STDMETHOD(GetTypeID)(BSTR *name);
+ STDMETHOD(GetPath)(BSTR *path);
+ STDMETHOD(GetSystemIconIndex)(UInt32 index, INT32 *iconIndex);
+
+ void Init();
+private:
+ UString _computerName;
+ UString _networkName;
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/SplitUtils.cpp b/CPP/7zip/FileManager/SplitUtils.cpp
new file mode 100755
index 00000000..3a7635fa
--- /dev/null
+++ b/CPP/7zip/FileManager/SplitUtils.cpp
@@ -0,0 +1,85 @@
+// SplitUtils.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StringToInt.h"
+
+#include "SplitUtils.h"
+#include "StringUtils.h"
+
+bool ParseVolumeSizes(const UString &s, CRecordVector<UInt64> &values)
+{
+ values.Clear();
+ UStringVector destStrings;
+ SplitString(s, destStrings);
+ bool prevIsNumber = false;
+ for (int i = 0; i < destStrings.Size(); i++)
+ {
+ UString subString = destStrings[i];
+ subString.MakeUpper();
+ if (subString.IsEmpty())
+ return false;
+ if (subString == L"-")
+ return true;
+ if (prevIsNumber)
+ {
+ wchar_t c = subString[0];
+ UInt64 &value = values.Back();
+ prevIsNumber = false;
+ switch(c)
+ {
+ case L'B':
+ continue;
+ case L'K':
+ value <<= 10;
+ continue;
+ case L'M':
+ value <<= 20;
+ continue;
+ case L'G':
+ value <<= 30;
+ continue;
+ }
+ }
+ const wchar_t *start = subString;
+ const wchar_t *end;
+ UInt64 value = ConvertStringToUInt64(start, &end);
+ if (start == end)
+ return false;
+ if (value == 0)
+ return false;
+ values.Add(value);
+ prevIsNumber = true;
+ UString rem = subString.Mid((int)(end - start));
+ if (!rem.IsEmpty())
+ destStrings.Insert(i + 1, rem);
+ }
+ return true;
+}
+
+void AddVolumeItems(NWindows::NControl::CComboBox &volumeCombo)
+{
+ volumeCombo.AddString(TEXT("1457664 - 3.5\" floppy"));
+ volumeCombo.AddString(TEXT("650M - CD"));
+ volumeCombo.AddString(TEXT("700M - CD"));
+ volumeCombo.AddString(TEXT("4480M - DVD"));
+}
+
+UInt64 GetNumberOfVolumes(UInt64 size, CRecordVector<UInt64> &volSizes)
+{
+ if (size == 0 || volSizes.Size() == 0)
+ return 1;
+ UInt64 numVolumes = 0;
+ for (int i = 0; i < volSizes.Size(); i++)
+ {
+ UInt64 volSize = volSizes[i];
+ numVolumes++;
+ if (volSize >= size)
+ return numVolumes;
+ size -= volSize;
+ }
+ UInt64 volSize = volSizes.Back();
+ if (volSize == 0)
+ return (UInt64)(Int64)-1;
+ return numVolumes + (size - 1) / volSize + 1;
+}
diff --git a/CPP/7zip/FileManager/SplitUtils.h b/CPP/7zip/FileManager/SplitUtils.h
new file mode 100755
index 00000000..fe359f04
--- /dev/null
+++ b/CPP/7zip/FileManager/SplitUtils.h
@@ -0,0 +1,15 @@
+// SplitUtils.h
+
+#ifndef __SPLITUTILS_H
+#define __SPLITUTILS_H
+
+#include "Common/String.h"
+#include "Common/Types.h"
+#include "Windows/Control/ComboBox.h"
+
+bool ParseVolumeSizes(const UString &s, CRecordVector<UInt64> &values);
+void AddVolumeItems(NWindows::NControl::CComboBox &volumeCombo);
+
+UInt64 GetNumberOfVolumes(UInt64 size, CRecordVector<UInt64> &volSizes);
+
+#endif
diff --git a/CPP/7zip/FileManager/StdAfx.cpp b/CPP/7zip/FileManager/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/FileManager/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/FileManager/StdAfx.h b/CPP/7zip/FileManager/StdAfx.h
new file mode 100755
index 00000000..b09de592
--- /dev/null
+++ b/CPP/7zip/FileManager/StdAfx.h
@@ -0,0 +1,23 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#define _WIN32_WINNT 0x0400
+
+// it's for Windows NT supporting (MENUITEMINFOW)
+#define WINVER 0x0400
+
+#include <windows.h>
+#include <stdio.h>
+#include <commctrl.h>
+#include <ShlObj.h>
+#include <limits.h>
+#include <tchar.h>
+#include <shlwapi.h>
+
+// #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+
+#include "Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/FileManager/StringUtils.cpp b/CPP/7zip/FileManager/StringUtils.cpp
new file mode 100755
index 00000000..63eebdba
--- /dev/null
+++ b/CPP/7zip/FileManager/StringUtils.cpp
@@ -0,0 +1,68 @@
+// StringUtils.cpp
+
+#include "StdAfx.h"
+
+#include "StringUtils.h"
+
+void SplitStringToTwoStrings(const UString &src, UString &dest1, UString &dest2)
+{
+ dest1.Empty();
+ dest2.Empty();
+ bool quoteMode = false;
+ int i;
+ for (i = 0; i < src.Length(); i++)
+ {
+ wchar_t c = src[i];
+ if (c == L'\"')
+ quoteMode = !quoteMode;
+ else if (c == L' ' && !quoteMode)
+ {
+ if (!quoteMode)
+ {
+ i++;
+ break;
+ }
+ }
+ else
+ dest1 += c;
+ }
+ dest2 = src.Mid(i);
+}
+
+void SplitString(const UString &srcString, UStringVector &destStrings)
+{
+ destStrings.Clear();
+ UString string;
+ int len = srcString.Length();
+ if (len == 0)
+ return;
+ for (int i = 0; i < len; i++)
+ {
+ wchar_t c = srcString[i];
+ if (c == L' ')
+ {
+ if (!string.IsEmpty())
+ {
+ destStrings.Add(string);
+ string.Empty();
+ }
+ }
+ else
+ string += c;
+ }
+ if (!string.IsEmpty())
+ destStrings.Add(string);
+}
+
+UString JoinStrings(const UStringVector &srcStrings)
+{
+ UString destString;
+ for (int i = 0; i < srcStrings.Size(); i++)
+ {
+ if (i != 0)
+ destString += L' ';
+ destString += srcStrings[i];
+ }
+ return destString;
+}
+
diff --git a/CPP/7zip/FileManager/StringUtils.h b/CPP/7zip/FileManager/StringUtils.h
new file mode 100755
index 00000000..376a3024
--- /dev/null
+++ b/CPP/7zip/FileManager/StringUtils.h
@@ -0,0 +1,13 @@
+// StringUtils.h
+
+#ifndef __STRINGUTILS_H
+#define __STRINGUTILS_H
+
+#include "Common/String.h"
+
+void SplitStringToTwoStrings(const UString &src, UString &dest1, UString &dest2);
+
+void SplitString(const UString &srcString, UStringVector &destStrings);
+UString JoinStrings(const UStringVector &srcStrings);
+
+#endif
diff --git a/CPP/7zip/FileManager/SysIconUtils.cpp b/CPP/7zip/FileManager/SysIconUtils.cpp
new file mode 100755
index 00000000..0d337550
--- /dev/null
+++ b/CPP/7zip/FileManager/SysIconUtils.cpp
@@ -0,0 +1,157 @@
+// SysIconUtils.h
+
+#include "StdAfx.h"
+
+#include "SysIconUtils.h"
+#ifndef _UNICODE
+#include "Common/StringConvert.h"
+#endif
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+int GetIconIndexForCSIDL(int aCSIDL)
+{
+ LPITEMIDLIST pidlMyComputer = 0;
+ SHGetSpecialFolderLocation(NULL, aCSIDL, &pidlMyComputer);
+ if (pidlMyComputer)
+ {
+ SHFILEINFO shellInfo;
+ SHGetFileInfo(LPCTSTR(pidlMyComputer), FILE_ATTRIBUTE_NORMAL,
+ &shellInfo, sizeof(shellInfo),
+ SHGFI_PIDL | SHGFI_SYSICONINDEX);
+ IMalloc *pMalloc;
+ SHGetMalloc(&pMalloc);
+ if(pMalloc)
+ {
+ pMalloc->Free(pidlMyComputer);
+ pMalloc->Release();
+ }
+ return shellInfo.iIcon;
+ }
+ return 0;
+}
+
+DWORD_PTR GetRealIconIndex(LPCTSTR path, UINT32 attributes, int &iconIndex)
+{
+ SHFILEINFO shellInfo;
+ DWORD_PTR res = ::SHGetFileInfo(path, FILE_ATTRIBUTE_NORMAL | attributes, &shellInfo,
+ sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX);
+ iconIndex = shellInfo.iIcon;
+ return res;
+}
+
+
+#ifndef _UNICODE
+typedef int (WINAPI * SHGetFileInfoWP)(LPCWSTR pszPath, DWORD dwFileAttributes, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags);
+
+struct CSHGetFileInfoInit
+{
+ SHGetFileInfoWP shGetFileInfoW;
+ CSHGetFileInfoInit()
+ {
+ shGetFileInfoW = (SHGetFileInfoWP)
+ ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "SHGetFileInfoW");
+ }
+} g_SHGetFileInfoInit;
+#endif
+
+DWORD_PTR MySHGetFileInfoW(LPCWSTR pszPath, DWORD dwFileAttributes, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags)
+{
+ #ifdef _UNICODE
+ return SHGetFileInfoW(
+ #else
+ if (g_SHGetFileInfoInit.shGetFileInfoW == 0)
+ return 0;
+ return g_SHGetFileInfoInit.shGetFileInfoW(
+ #endif
+ pszPath, dwFileAttributes, psfi, cbFileInfo, uFlags);
+}
+
+#ifndef _UNICODE
+// static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
+DWORD_PTR GetRealIconIndex(LPCWSTR path, UINT32 attributes, int &iconIndex)
+{
+ if(g_IsNT)
+ {
+ SHFILEINFOW shellInfo;
+ DWORD_PTR res = ::MySHGetFileInfoW(path, FILE_ATTRIBUTE_NORMAL | attributes, &shellInfo,
+ sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX);
+ iconIndex = shellInfo.iIcon;
+ return res;
+ }
+ else
+ return GetRealIconIndex(UnicodeStringToMultiByte(path), attributes, iconIndex);
+}
+#endif
+
+DWORD_PTR GetRealIconIndex(const UString &fileName, UINT32 attributes,
+ int &iconIndex, UString &typeName)
+{
+ #ifndef _UNICODE
+ if(!g_IsNT)
+ {
+ SHFILEINFO shellInfo;
+ shellInfo.szTypeName[0] = 0;
+ DWORD_PTR res = ::SHGetFileInfoA(GetSystemString(fileName), FILE_ATTRIBUTE_NORMAL | attributes, &shellInfo,
+ sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX
+ | SHGFI_TYPENAME);
+ typeName = GetUnicodeString(shellInfo.szTypeName);
+ iconIndex = shellInfo.iIcon;
+ return res;
+ }
+ else
+ #endif
+ {
+ SHFILEINFOW shellInfo;
+ shellInfo.szTypeName[0] = 0;
+ DWORD_PTR res = ::MySHGetFileInfoW(fileName, FILE_ATTRIBUTE_NORMAL | attributes, &shellInfo,
+ sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX
+ | SHGFI_TYPENAME);
+ typeName = shellInfo.szTypeName;
+ iconIndex = shellInfo.iIcon;
+ return res;
+ }
+}
+
+int CExtToIconMap::GetIconIndex(UINT32 attributes, const UString &fileNameSpec, UString &typeName)
+{
+ UString fileName = fileNameSpec;
+ if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
+ {
+ fileName = L"__Fldr__";
+ if (_dirIconIndex < 0)
+ GetRealIconIndex(fileName, attributes, _dirIconIndex, _dirTypeName);
+ typeName = _dirTypeName;
+ return _dirIconIndex;
+ }
+ int dotPos = fileName.ReverseFind('.');
+ if (dotPos < 0)
+ {
+ fileName = L"__File__";
+ if (_noExtIconIndex < 0)
+ {
+ int iconIndexTemp;
+ GetRealIconIndex(fileName, attributes, iconIndexTemp, _noExtTypeName);
+ }
+ typeName = _noExtTypeName;
+ return _noExtIconIndex;
+ }
+ CExtIconPair extIconPair;
+ extIconPair.Ext = fileName.Mid(dotPos + 1);
+ int anIndex = _map.FindInSorted(extIconPair);
+ if (anIndex >= 0)
+ return _map[anIndex].IconIndex;
+ fileName = fileName.Mid(dotPos);
+ GetRealIconIndex(fileName, attributes, extIconPair.IconIndex, extIconPair.TypeName);
+ _map.AddToSorted(extIconPair);
+ typeName = extIconPair.TypeName;
+ return extIconPair.IconIndex;
+}
+
+int CExtToIconMap::GetIconIndex(UINT32 attributes, const UString &fileName)
+{
+ UString typeName;
+ return GetIconIndex(attributes, fileName, typeName);
+}
diff --git a/CPP/7zip/FileManager/SysIconUtils.h b/CPP/7zip/FileManager/SysIconUtils.h
new file mode 100755
index 00000000..51294751
--- /dev/null
+++ b/CPP/7zip/FileManager/SysIconUtils.h
@@ -0,0 +1,51 @@
+// SysIconUtils.h
+
+#ifndef __SYSICONUTILS_H
+#define __SYSICONUTILS_H
+
+#include "Common/String.h"
+
+struct CExtIconPair
+{
+ UString Ext;
+ int IconIndex;
+ UString TypeName;
+
+};
+
+inline bool operator==(const CExtIconPair &a1, const CExtIconPair &a2)
+{
+ return (a1.Ext == a2.Ext);
+}
+
+inline bool operator<(const CExtIconPair &a1, const CExtIconPair &a2)
+{
+ return (a1.Ext < a2.Ext);
+}
+
+class CExtToIconMap
+{
+ int _dirIconIndex;
+ UString _dirTypeName;
+ int _noExtIconIndex;
+ UString _noExtTypeName;
+ CObjectVector<CExtIconPair> _map;
+public:
+ CExtToIconMap(): _dirIconIndex(-1), _noExtIconIndex(-1) {}
+ void Clear()
+ {
+ _dirIconIndex = -1;
+ _noExtIconIndex = -1;
+ _map.Clear();
+ }
+ int GetIconIndex(UINT32 attributes, const UString &fileName, UString &typeName);
+ int GetIconIndex(UINT32 attributes, const UString &fileName);
+};
+
+DWORD_PTR GetRealIconIndex(LPCTSTR path, UINT32 attributes, int &iconIndex);
+#ifndef _UNICODE
+DWORD_PTR GetRealIconIndex(LPCWSTR path, UINT32 attributes, int &iconIndex);
+#endif
+int GetIconIndexForCSIDL(int aCSIDL);
+
+#endif
diff --git a/CPP/7zip/FileManager/Test.bmp b/CPP/7zip/FileManager/Test.bmp
new file mode 100755
index 00000000..ef85ba23
--- /dev/null
+++ b/CPP/7zip/FileManager/Test.bmp
Binary files differ
diff --git a/CPP/7zip/FileManager/Test2.bmp b/CPP/7zip/FileManager/Test2.bmp
new file mode 100755
index 00000000..99b7dbf0
--- /dev/null
+++ b/CPP/7zip/FileManager/Test2.bmp
Binary files differ
diff --git a/CPP/7zip/FileManager/TextPairs.cpp b/CPP/7zip/FileManager/TextPairs.cpp
new file mode 100755
index 00000000..76c97b8c
--- /dev/null
+++ b/CPP/7zip/FileManager/TextPairs.cpp
@@ -0,0 +1,216 @@
+// Common/TextPairs.cpp
+
+#include "StdAfx.h"
+
+#include "TextPairs.h"
+
+#include "Common/Defs.h"
+#include "Common/UTFConvert.h"
+
+static const wchar_t kNewLineChar = '\n';
+
+static const wchar_t kSpaceChar = ' ';
+static const wchar_t kTabChar = '\t';
+
+static const wchar_t kQuoteChar = '\"';
+static const wchar_t kEndOfLine = '\0';
+
+static const wchar_t kBOM = wchar_t(0xFEFF);
+
+static bool IsSeparatorChar(wchar_t c)
+{
+ return (c == kSpaceChar || c == kTabChar);
+}
+
+static UString GetIDString(const wchar_t *srcString, int &finishPos)
+{
+ UString result;
+ bool quotes = false;
+ for (finishPos = 0;;)
+ {
+ wchar_t c = srcString[finishPos];
+ if (c == kEndOfLine)
+ break;
+ finishPos++;
+ bool isSeparatorChar = IsSeparatorChar(c);
+ if (c == kNewLineChar || (isSeparatorChar && !quotes)
+ || (c == kQuoteChar && quotes))
+ break;
+ else if (c == kQuoteChar)
+ quotes = true;
+ else
+ result += c;
+ }
+ result.Trim();
+ return result;
+}
+
+static UString GetValueString(const wchar_t *srcString, int &finishPos)
+{
+ UString result;
+ for (finishPos = 0;;)
+ {
+ wchar_t c = srcString[finishPos];
+ if (c == kEndOfLine)
+ break;
+ finishPos++;
+ if (c == kNewLineChar)
+ break;
+ result += c;
+ }
+ result.Trim();
+ return result;
+}
+
+static bool GetTextPairs(const UString &srcString, CObjectVector<CTextPair> &pairs)
+{
+ pairs.Clear();
+ UString srcString2 = srcString;
+ srcString2.Replace(L"\x0D", L"");
+
+ pairs.Clear();
+ int pos = 0;
+
+ /////////////////////
+ // read strings
+
+ if (srcString2.Length() > 0)
+ {
+ if (srcString2[0] == kBOM)
+ pos++;
+ }
+ while (pos < srcString2.Length())
+ {
+ int finishPos;
+ UString id = GetIDString((const wchar_t *)srcString2 + pos, finishPos);
+ pos += finishPos;
+ if (id.IsEmpty())
+ continue;
+ UString value = GetValueString((const wchar_t *)srcString2 + pos, finishPos);
+ pos += finishPos;
+ if (!id.IsEmpty())
+ {
+ CTextPair pair;
+ pair.ID = id;
+ pair.Value = value;
+ pairs.Add(pair);
+ }
+ }
+ return true;
+}
+
+int FindItem(const CObjectVector<CTextPair> &pairs, const UString &id)
+{
+ for (int i = 0; i < pairs.Size(); i++)
+ if (pairs[i].ID.CompareNoCase(id) == 0)
+ return i;
+ return -1;
+}
+
+UString GetTextConfigValue(const CObjectVector<CTextPair> &pairs, const UString &id)
+{
+ int index = FindItem(pairs, id);
+ if (index < 0)
+ return UString();
+ return pairs[index].Value;
+}
+
+static int ComparePairIDs(const UString &s1, const UString &s2)
+ { return s1.CompareNoCase(s2); }
+static int ComparePairItems(const CTextPair &p1, const CTextPair &p2)
+ { return ComparePairIDs(p1.ID, p2.ID); }
+
+// 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()
+ { Pairs.Sort(ComparePairItems, 0); }
+
+int CPairsStorage::FindID(const UString &id, int &insertPos)
+{
+ int left = 0, right = Pairs.Size();
+ while (left != right)
+ {
+ UINT32 mid = (left + right) / 2;
+ int compResult = ComparePairIDs(id, Pairs[mid].ID);
+ if (compResult == 0)
+ return mid;
+ if (compResult < 0)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ insertPos = left;
+ return -1;
+}
+
+int CPairsStorage::FindID(const UString &id)
+{
+ int pos;
+ return FindID(id, pos);
+}
+
+void CPairsStorage::AddPair(const CTextPair &pair)
+{
+ int insertPos;
+ int pos = FindID(pair.ID, insertPos);
+ if (pos >= 0)
+ Pairs[pos] = pair;
+ else
+ Pairs.Insert(insertPos, pair);
+}
+
+void CPairsStorage::DeletePair(const UString &id)
+{
+ int pos = FindID(id);
+ if (pos >= 0)
+ Pairs.Delete(pos);
+}
+
+bool CPairsStorage::GetValue(const UString &id, UString &value)
+{
+ value.Empty();
+ int pos = FindID(id);
+ if (pos < 0)
+ return false;
+ value = Pairs[pos].Value;
+ return true;
+}
+
+UString CPairsStorage::GetValue(const UString &id)
+{
+ int pos = FindID(id);
+ if (pos < 0)
+ return UString();
+ return Pairs[pos].Value;
+}
+
+bool CPairsStorage::ReadFromString(const UString &text)
+{
+ bool result = ::GetTextPairs(text, Pairs);
+ if (result)
+ Sort();
+ else
+ Pairs.Clear();
+ return result;
+}
+
+void CPairsStorage::SaveToString(UString &text)
+{
+ for (int i = 0; i < Pairs.Size(); i++)
+ {
+ const CTextPair &pair = Pairs[i];
+ bool multiWord = (pair.ID.Find(L' ') >= 0);
+ if (multiWord)
+ text += L'\"';
+ text += pair.ID;
+ if (multiWord)
+ text += L'\"';
+ text += L' ';
+ text += pair.Value;
+ text += L'\n';
+ }
+}
diff --git a/CPP/7zip/FileManager/TextPairs.h b/CPP/7zip/FileManager/TextPairs.h
new file mode 100755
index 00000000..247a92d9
--- /dev/null
+++ b/CPP/7zip/FileManager/TextPairs.h
@@ -0,0 +1,32 @@
+// Common/TextPairs.h
+
+#ifndef __COMMON_TEXTPAIRS_H
+#define __COMMON_TEXTPAIRS_H
+
+#include "Common/Vector.h"
+#include "Common/String.h"
+
+struct CTextPair
+{
+ UString ID;
+ UString Value;
+};
+
+class CPairsStorage
+{
+ CObjectVector<CTextPair> Pairs;
+ int FindID(const UString &id, int &insertPos);
+ int FindID(const UString &id);
+ void Sort();
+public:
+ void Clear() { Pairs.Clear(); };
+ bool ReadFromString(const UString &text);
+ void SaveToString(UString &text);
+
+ bool GetValue(const UString &id, UString &value);
+ UString GetValue(const UString &id);
+ void AddPair(const CTextPair &pair);
+ void DeletePair(const UString &id);
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/UpdateCallback100.cpp b/CPP/7zip/FileManager/UpdateCallback100.cpp
new file mode 100755
index 00000000..ddd2e55d
--- /dev/null
+++ b/CPP/7zip/FileManager/UpdateCallback100.cpp
@@ -0,0 +1,92 @@
+// UpdateCallback.h
+
+#include "StdAfx.h"
+
+#include "Common/StringConvert.h"
+
+#include "UpdateCallback100.h"
+// #include "Windows/ProcessMessages.h"
+// #include "Resource/PasswordDialog/PasswordDialog.h"
+#include "Resource/MessagesDialog/MessagesDialog.h"
+
+#include "Common/Defs.h"
+
+using namespace NWindows;
+
+CUpdateCallback100Imp::~CUpdateCallback100Imp()
+{
+ if (ShowMessages && !Messages.IsEmpty())
+ {
+ CMessagesDialog messagesDialog;
+ messagesDialog.Messages = &Messages;
+ messagesDialog.Create(_parentWindow);
+ }
+}
+
+void CUpdateCallback100Imp::AddErrorMessage(LPCWSTR message)
+{
+ Messages.Add(message);
+}
+
+STDMETHODIMP CUpdateCallback100Imp::SetTotal(UINT64 size)
+{
+ ProgressDialog.ProgressSynch.SetProgress(size, 0);
+ return S_OK;
+}
+
+STDMETHODIMP CUpdateCallback100Imp::SetCompleted(const UINT64 *completeValue)
+{
+ for (;;)
+ {
+ if(ProgressDialog.ProgressSynch.GetStopped())
+ return E_ABORT;
+ if(!ProgressDialog.ProgressSynch.GetPaused())
+ break;
+ ::Sleep(100);
+ }
+ if (completeValue != NULL)
+ ProgressDialog.ProgressSynch.SetPos(*completeValue);
+ return S_OK;
+}
+
+STDMETHODIMP CUpdateCallback100Imp::CompressOperation(const wchar_t *name)
+{
+ ProgressDialog.ProgressSynch.SetCurrentFileName(name);
+ return S_OK;
+}
+
+STDMETHODIMP CUpdateCallback100Imp::DeleteOperation(const wchar_t * /* name */)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CUpdateCallback100Imp::OperationResult(INT32 /* operationResult */)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CUpdateCallback100Imp::UpdateErrorMessage(const wchar_t *message)
+{
+ AddErrorMessage(message);
+ return S_OK;
+}
+
+STDMETHODIMP CUpdateCallback100Imp::CryptoGetTextPassword2(INT32 *passwordIsDefined, BSTR *password)
+{
+ *passwordIsDefined = BoolToInt(_passwordIsDefined);
+ if (!_passwordIsDefined)
+ {
+ return S_OK;
+ /*
+ CPasswordDialog dialog;
+ if (dialog.Create(_parentWindow) == IDCANCEL)
+ return E_ABORT;
+ _password = dialog._password;
+ _passwordIsDefined = true;
+ */
+ }
+ *passwordIsDefined = BoolToInt(_passwordIsDefined);
+ CMyComBSTR tempName = _password;
+ *password = tempName.Detach();
+ return S_OK;
+}
diff --git a/CPP/7zip/FileManager/UpdateCallback100.h b/CPP/7zip/FileManager/UpdateCallback100.h
new file mode 100755
index 00000000..4cce5b52
--- /dev/null
+++ b/CPP/7zip/FileManager/UpdateCallback100.h
@@ -0,0 +1,67 @@
+// UpdateCallback100.h
+
+#ifndef __UPDATE_CALLBACK100_H
+#define __UPDATE_CALLBACK100_H
+
+#include "Common/MyCom.h"
+#include "Common/String.h"
+
+#include "../UI/Agent/IFolderArchive.h"
+#include "Resource/ProgressDialog2/ProgressDialog.h"
+#include "../IPassword.h"
+
+#ifdef LANG
+#include "LangUtils.h"
+#endif
+
+class CUpdateCallback100Imp:
+ public IFolderArchiveUpdateCallback,
+ public ICryptoGetTextPassword2,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP2(
+ IFolderArchiveUpdateCallback,
+ ICryptoGetTextPassword2)
+
+ // IProgress
+
+ STDMETHOD(SetTotal)(UINT64 size);
+ STDMETHOD(SetCompleted)(const UINT64 *completeValue);
+
+ // IUpdateCallBack
+ STDMETHOD(CompressOperation)(const wchar_t *name);
+ STDMETHOD(DeleteOperation)(const wchar_t *name);
+ STDMETHOD(OperationResult)(INT32 operationResult);
+ STDMETHOD(UpdateErrorMessage)(const wchar_t *message);
+
+ STDMETHOD(CryptoGetTextPassword2)(INT32 *passwordIsDefined, BSTR *password);
+private:
+ bool _passwordIsDefined;
+ UString _password;
+
+ void AddErrorMessage(LPCWSTR message);
+ bool ShowMessages;
+
+public:
+ CUpdateCallback100Imp(): ShowMessages(true) {}
+ ~CUpdateCallback100Imp();
+ CProgressDialog ProgressDialog;
+ HWND _parentWindow;
+ UStringVector Messages;
+
+ void Init(HWND parentWindow,
+ bool passwordIsDefined, const UString &password)
+ {
+ _passwordIsDefined = passwordIsDefined;
+ _password = password;
+ _parentWindow = parentWindow;
+ }
+ void StartProgressDialog(const UString &title)
+ {
+ ProgressDialog.Create(title, _parentWindow);
+ }
+
+};
+
+#endif
diff --git a/CPP/7zip/FileManager/ViewSettings.cpp b/CPP/7zip/FileManager/ViewSettings.cpp
new file mode 100755
index 00000000..9102cc4e
--- /dev/null
+++ b/CPP/7zip/FileManager/ViewSettings.cpp
@@ -0,0 +1,429 @@
+// ViewSettings.h
+
+#include "StdAfx.h"
+
+#include "Common/IntToString.h"
+#include "Common/StringConvert.h"
+
+#include "ViewSettings.h"
+#include "Windows/Registry.h"
+#include "Windows/Synchronization.h"
+
+using namespace NWindows;
+using namespace NRegistry;
+
+static const TCHAR *kCUBasePath = TEXT("Software\\7-Zip\\FM");
+
+static const TCHAR *kCulumnsKeyName = TEXT("Columns");
+
+static const TCHAR *kPositionValueName = TEXT("Position");
+static const TCHAR *kPanelsInfoValueName = TEXT("Panels");
+static const TCHAR *kToolbars = TEXT("Toolbars");
+
+static const WCHAR *kPanelPathValueName = L"PanelPath";
+static const TCHAR *kListMode = TEXT("ListMode");
+static const TCHAR *kFolderHistoryValueName = TEXT("FolderHistory");
+static const TCHAR *kFastFoldersValueName = TEXT("FolderShortcuts");
+static const TCHAR *kCopyHistoryValueName = TEXT("CopyHistory");
+
+/*
+class CColumnInfoSpec
+{
+ UInt32 PropID;
+ Byte IsVisible;
+ UInt32 Width;
+};
+
+struct CColumnHeader
+{
+ UInt32 Version;
+ UInt32 SortID;
+ Byte Ascending;
+};
+*/
+
+static const UInt32 kColumnInfoSpecHeader = 12;
+static const UInt32 kColumnHeaderSize = 12;
+
+static const UInt32 kColumnInfoVersion = 1;
+
+static NSynchronization::CCriticalSection g_RegistryOperationsCriticalSection;
+
+class CTempOutBufferSpec
+{
+ CByteBuffer Buffer;
+ UInt32 Size;
+ UInt32 Pos;
+public:
+ operator const Byte *() const { return (const Byte *)Buffer; }
+ void Init(UInt32 dataSize)
+ {
+ Buffer.SetCapacity(dataSize);
+ Size = dataSize;
+ Pos = 0;
+ }
+ void WriteByte(Byte value)
+ {
+ if (Pos >= Size)
+ throw "overflow";
+ ((Byte *)Buffer)[Pos++] = value;
+ }
+ void WriteUInt32(UInt32 value)
+ {
+ for (int i = 0; i < 4; i++)
+ {
+ WriteByte((Byte)value);
+ value >>= 8;
+ }
+ }
+ void WriteBool(bool value)
+ {
+ WriteUInt32(value ? 1 : 0);
+ }
+};
+
+class CTempInBufferSpec
+{
+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;
+ }
+ bool ReadBool()
+ {
+ return (ReadUInt32() != 0);
+ }
+};
+
+void SaveListViewInfo(const UString &id, const CListViewInfo &viewInfo)
+{
+ const CObjectVector<CColumnInfo> &columns = viewInfo.Columns;
+ CTempOutBufferSpec buffer;
+ UInt32 dataSize = kColumnHeaderSize + kColumnInfoSpecHeader * columns.Size();
+ buffer.Init(dataSize);
+
+ buffer.WriteUInt32(kColumnInfoVersion);
+ buffer.WriteUInt32(viewInfo.SortID);
+ buffer.WriteBool(viewInfo.Ascending);
+ for(int i = 0; i < columns.Size(); i++)
+ {
+ const CColumnInfo &column = columns[i];
+ buffer.WriteUInt32(column.PropID);
+ buffer.WriteBool(column.IsVisible);
+ buffer.WriteUInt32(column.Width);
+ }
+ {
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ CSysString keyName = kCUBasePath;
+ keyName += kKeyNameDelimiter;
+ keyName += kCulumnsKeyName;
+ CKey key;
+ key.Create(HKEY_CURRENT_USER, keyName);
+ key.SetValue(GetSystemString(id), (const Byte *)buffer, dataSize);
+ }
+}
+
+void ReadListViewInfo(const UString &id, CListViewInfo &viewInfo)
+{
+ viewInfo.Clear();
+ CObjectVector<CColumnInfo> &columns = viewInfo.Columns;
+ CByteBuffer buffer;
+ UInt32 size;
+ {
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ CSysString keyName = kCUBasePath;
+ keyName += kKeyNameDelimiter;
+ keyName += kCulumnsKeyName;
+ CKey key;
+ if(key.Open(HKEY_CURRENT_USER, keyName, KEY_READ) != ERROR_SUCCESS)
+ return;
+ if (key.QueryValue(GetSystemString(id), buffer, size) != ERROR_SUCCESS)
+ return;
+ }
+ if (size < kColumnHeaderSize)
+ return;
+ CTempInBufferSpec inBuffer;
+ inBuffer.Size = size;
+ inBuffer.Buffer = (Byte *)buffer;
+ inBuffer.Pos = 0;
+
+
+ UInt32 version = inBuffer.ReadUInt32();
+ if (version != kColumnInfoVersion)
+ return;
+ viewInfo.SortID = inBuffer.ReadUInt32();
+ viewInfo.Ascending = inBuffer.ReadBool();
+
+ size -= kColumnHeaderSize;
+ if (size % kColumnInfoSpecHeader != 0)
+ return;
+ int numItems = size / kColumnInfoSpecHeader;
+ columns.Reserve(numItems);
+ for(int i = 0; i < numItems; i++)
+ {
+ CColumnInfo columnInfo;
+ columnInfo.PropID = inBuffer.ReadUInt32();
+ columnInfo.IsVisible = inBuffer.ReadBool();
+ columnInfo.Width = inBuffer.ReadUInt32();
+ columns.Add(columnInfo);
+ }
+}
+
+static const UInt32 kWindowPositionHeaderSize = 5 * 4;
+static const UInt32 kPanelsInfoHeaderSize = 3 * 4;
+
+/*
+struct CWindowPosition
+{
+ RECT Rect;
+ UInt32 Maximized;
+};
+
+struct CPanelsInfo
+{
+ UInt32 NumPanels;
+ UInt32 CurrentPanel;
+ UInt32 SplitterPos;
+};
+*/
+
+void SaveWindowSize(const RECT &rect, bool maximized)
+{
+ CSysString keyName = kCUBasePath;
+ CKey key;
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ key.Create(HKEY_CURRENT_USER, keyName);
+ // CWindowPosition position;
+ CTempOutBufferSpec buffer;
+ buffer.Init(kWindowPositionHeaderSize);
+ buffer.WriteUInt32(rect.left);
+ buffer.WriteUInt32(rect.top);
+ buffer.WriteUInt32(rect.right);
+ buffer.WriteUInt32(rect.bottom);
+ buffer.WriteBool(maximized);
+ key.SetValue(kPositionValueName, (const Byte *)buffer, kWindowPositionHeaderSize);
+}
+
+bool ReadWindowSize(RECT &rect, bool &maximized)
+{
+ CSysString keyName = kCUBasePath;
+ CKey key;
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ if(key.Open(HKEY_CURRENT_USER, keyName, KEY_READ) != ERROR_SUCCESS)
+ return false;
+ CByteBuffer buffer;
+ UInt32 size;
+ if (key.QueryValue(kPositionValueName, buffer, size) != ERROR_SUCCESS)
+ return false;
+ if (size != kWindowPositionHeaderSize)
+ return false;
+ CTempInBufferSpec inBuffer;
+ inBuffer.Size = size;
+ inBuffer.Buffer = (Byte *)buffer;
+ inBuffer.Pos = 0;
+ rect.left = inBuffer.ReadUInt32();
+ rect.top = inBuffer.ReadUInt32();
+ rect.right = inBuffer.ReadUInt32();
+ rect.bottom = inBuffer.ReadUInt32();
+ maximized = inBuffer.ReadBool();
+ return true;
+}
+
+void SavePanelsInfo(UInt32 numPanels, UInt32 currentPanel, UInt32 splitterPos)
+{
+ CSysString keyName = kCUBasePath;
+ CKey key;
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ key.Create(HKEY_CURRENT_USER, keyName);
+
+ CTempOutBufferSpec buffer;
+ buffer.Init(kPanelsInfoHeaderSize);
+ buffer.WriteUInt32(numPanels);
+ buffer.WriteUInt32(currentPanel);
+ buffer.WriteUInt32(splitterPos);
+ key.SetValue(kPanelsInfoValueName, (const Byte *)buffer, kPanelsInfoHeaderSize);
+}
+
+bool ReadPanelsInfo(UInt32 &numPanels, UInt32 &currentPanel, UInt32 &splitterPos)
+{
+ CSysString keyName = kCUBasePath;
+ CKey key;
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ if(key.Open(HKEY_CURRENT_USER, keyName, KEY_READ) != ERROR_SUCCESS)
+ return false;
+ CByteBuffer buffer;
+ UInt32 size;
+ if (key.QueryValue(kPanelsInfoValueName, buffer, size) != ERROR_SUCCESS)
+ return false;
+ if (size != kPanelsInfoHeaderSize)
+ return false;
+ CTempInBufferSpec inBuffer;
+ inBuffer.Size = size;
+ inBuffer.Buffer = (Byte *)buffer;
+ inBuffer.Pos = 0;
+ numPanels = inBuffer.ReadUInt32();
+ currentPanel = inBuffer.ReadUInt32();
+ splitterPos = inBuffer.ReadUInt32();
+ return true;
+}
+
+void SaveToolbarsMask(UInt32 toolbarMask)
+{
+ CKey key;
+ key.Create(HKEY_CURRENT_USER, kCUBasePath);
+ key.SetValue(kToolbars, toolbarMask);
+}
+
+static const UInt32 kDefaultToolbarMask = 8 | 4 | 1;
+
+UInt32 ReadToolbarsMask()
+{
+ CKey key;
+ if(key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS)
+ return kDefaultToolbarMask;
+ UInt32 mask;
+ if (key.QueryValue(kToolbars, mask) != ERROR_SUCCESS)
+ return kDefaultToolbarMask;
+ return mask;
+}
+
+
+static UString GetPanelPathName(UInt32 panelIndex)
+{
+ WCHAR panelString[32];
+ ConvertUInt64ToString(panelIndex, panelString);
+ return UString(kPanelPathValueName) + panelString;
+}
+
+
+void SavePanelPath(UInt32 panel, const UString &path)
+{
+ CKey key;
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ key.Create(HKEY_CURRENT_USER, kCUBasePath);
+ key.SetValue(GetPanelPathName(panel), path);
+}
+
+bool ReadPanelPath(UInt32 panel, UString &path)
+{
+ CKey key;
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ if(key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS)
+ return false;
+ return (key.QueryValue(GetPanelPathName(panel), path) == ERROR_SUCCESS);
+}
+
+void SaveListMode(const CListMode &listMode)
+{
+ CKey key;
+ key.Create(HKEY_CURRENT_USER, kCUBasePath);
+ UInt32 t = 0;
+ for (int i = 0; i < 2; i++)
+ t |= ((listMode.Panels[i]) & 0xFF) << (i * 8);
+ key.SetValue(kListMode, t);
+}
+
+void ReadListMode(CListMode &listMode)
+{
+ CKey key;
+ listMode.Init();
+ if(key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS)
+ return;
+ UInt32 t;
+ if (key.QueryValue(kListMode, t) != ERROR_SUCCESS)
+ return;
+ for (int i = 0; i < 2; i++)
+ {
+ listMode.Panels[i] = (t & 0xFF);
+ t >>= 8;
+ }
+}
+
+
+void SaveStringList(LPCTSTR valueName, const UStringVector &folders)
+{
+ UInt32 sizeInChars = 0;
+ int i;
+ for (i = 0; i < folders.Size(); i++)
+ sizeInChars += folders[i].Length() + 1;
+ CBuffer<wchar_t> buffer;
+ buffer.SetCapacity(sizeInChars);
+ int pos = 0;
+ for (i = 0; i < folders.Size(); i++)
+ {
+ MyStringCopy((wchar_t *)buffer + pos, (const wchar_t *)folders[i]);
+ pos += folders[i].Length() + 1;
+ }
+ CKey key;
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ key.Create(HKEY_CURRENT_USER, kCUBasePath);
+ key.SetValue(valueName, buffer, sizeInChars * sizeof(wchar_t));
+}
+
+void ReadStringList(LPCTSTR valueName, UStringVector &folders)
+{
+ folders.Clear();
+ CKey key;
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ if(key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS)
+ return;
+ CByteBuffer buffer;
+ UInt32 dataSize;
+ if (key.QueryValue(valueName, buffer, dataSize) != ERROR_SUCCESS)
+ return;
+ if (dataSize % sizeof(wchar_t) != 0)
+ return;
+ const wchar_t *data = (const wchar_t *)(const Byte *)buffer;
+ int sizeInChars = dataSize / sizeof(wchar_t);
+ UString string;
+ for (int i = 0; i < sizeInChars; i++)
+ {
+ wchar_t c = data[i];
+ if (c == L'\0')
+ {
+ folders.Add(string);
+ string.Empty();
+ }
+ else
+ string += c;
+ }
+}
+
+void SaveFolderHistory(const UStringVector &folders)
+ { SaveStringList(kFolderHistoryValueName, folders); }
+void ReadFolderHistory(UStringVector &folders)
+ { ReadStringList(kFolderHistoryValueName, folders); }
+
+void SaveFastFolders(const UStringVector &folders)
+ { SaveStringList(kFastFoldersValueName, folders); }
+void ReadFastFolders(UStringVector &folders)
+ { ReadStringList(kFastFoldersValueName, folders); }
+
+void SaveCopyHistory(const UStringVector &folders)
+ { SaveStringList(kCopyHistoryValueName, folders); }
+void ReadCopyHistory(UStringVector &folders)
+ { ReadStringList(kCopyHistoryValueName, folders); }
+
+void AddUniqueStringToHeadOfList(UStringVector &list,
+ const UString &string)
+{
+ for(int i = 0; i < list.Size();)
+ if (string.CompareNoCase(list[i]) == 0)
+ list.Delete(i);
+ else
+ i++;
+ list.Insert(0, string);
+}
+
diff --git a/CPP/7zip/FileManager/ViewSettings.h b/CPP/7zip/FileManager/ViewSettings.h
new file mode 100755
index 00000000..4894a6f9
--- /dev/null
+++ b/CPP/7zip/FileManager/ViewSettings.h
@@ -0,0 +1,99 @@
+// ViewSettings.h
+
+#ifndef __VIEWSETTINGS_H
+#define __VIEWSETTINGS_H
+
+#include "Common/Vector.h"
+#include "Common/String.h"
+
+struct CColumnInfo
+{
+ PROPID PropID;
+ bool IsVisible;
+ UInt32 Width;
+};
+
+inline bool operator==(const CColumnInfo &a1, const CColumnInfo &a2)
+{
+ return (a1.PropID == a2.PropID) &&
+ (a1.IsVisible == a2.IsVisible) && (a1.Width == a2.Width);
+}
+
+inline bool operator!=(const CColumnInfo &a1, const CColumnInfo &a2)
+{
+ return !(a1 == a2);
+}
+
+struct CListViewInfo
+{
+ CObjectVector<CColumnInfo> Columns;
+ PROPID SortID;
+ bool Ascending;
+
+ void Clear()
+ {
+ SortID = 0;
+ Ascending = true;
+ Columns.Clear();
+ }
+
+ int FindColumnWithID(PROPID propID) const
+ {
+ for (int i = 0; i < Columns.Size(); i++)
+ if (Columns[i].PropID == propID)
+ return i;
+ return -1;
+ }
+
+ bool IsEqual(const CListViewInfo &aNewInfo) const
+ {
+ if (Columns.Size() != aNewInfo.Columns.Size() ||
+ // SortIndex != aNewInfo.SortIndex ||
+ SortID != aNewInfo.SortID ||
+ Ascending != aNewInfo.Ascending)
+ return false;
+ for (int i = 0; i < Columns.Size(); i++)
+ if (Columns[i] != aNewInfo.Columns[i])
+ return false;
+ return true;
+ }
+};
+
+void SaveListViewInfo(const UString &id, const CListViewInfo &viewInfo);
+void ReadListViewInfo(const UString &id, CListViewInfo &viewInfo);
+
+void SaveWindowSize(const RECT &rect, bool maximized);
+bool ReadWindowSize(RECT &rect, bool &maximized);
+
+void SavePanelsInfo(UInt32 numPanels, UInt32 currentPanel, UInt32 splitterPos);
+bool ReadPanelsInfo(UInt32 &numPanels, UInt32 &currentPanel, UInt32 &splitterPos);
+
+void SaveToolbarsMask(UInt32 toolbarMask);
+UInt32 ReadToolbarsMask();
+
+void SavePanelPath(UInt32 panel, const UString &path);
+bool ReadPanelPath(UInt32 panel, UString &path);
+
+struct CListMode
+{
+ UInt32 Panels[2];
+ void Init() { Panels[0] = Panels[1] = 3; }
+ CListMode() { Init(); }
+};
+
+void SaveListMode(const CListMode &listMode);
+void ReadListMode(CListMode &listMode);
+
+void SaveFolderHistory(const UStringVector &folders);
+void ReadFolderHistory(UStringVector &folders);
+
+void SaveFastFolders(const UStringVector &folders);
+void ReadFastFolders(UStringVector &folders);
+
+void SaveCopyHistory(const UStringVector &folders);
+void ReadCopyHistory(UStringVector &folders);
+
+void AddUniqueStringToHeadOfList(UStringVector &list,
+ const UString &string);
+
+#endif
diff --git a/CPP/7zip/FileManager/makefile b/CPP/7zip/FileManager/makefile
new file mode 100755
index 00000000..42619e0a
--- /dev/null
+++ b/CPP/7zip/FileManager/makefile
@@ -0,0 +1,187 @@
+PROG = 7zFM.exe
+LIBS = $(LIBS) user32.lib oleaut32.lib advapi32.lib shell32.lib ole32.lib comctl32.lib htmlhelp.lib Mpr.lib Gdi32.lib comdlg32.lib
+CFLAGS = $(CFLAGS) -I../../ -DLANG -DWIN_LONG_PATH
+
+FM_OBJS = \
+ $O\App.obj \
+ $O\ClassDefs.obj \
+ $O\EnumFormatEtc.obj \
+ $O\ExtractCallback.obj \
+ $O\FileFolderPluginOpen.obj \
+ $O\FilePlugins.obj \
+ $O\FM.obj \
+ $O\FormatUtils.obj \
+ $O\FSDrives.obj \
+ $O\FSFolder.obj \
+ $O\FSFolderCopy.obj \
+ $O\HelpUtils.obj \
+ $O\LangUtils.obj \
+ $O\MyLoadMenu.obj \
+ $O\NetFolder.obj \
+ $O\OpenCallback.obj \
+ $O\OptionsDialog.obj \
+ $O\Panel.obj \
+ $O\PanelCopy.obj \
+ $O\PanelCrc.obj \
+ $O\PanelDrag.obj \
+ $O\PanelFolderChange.obj \
+ $O\PanelItemOpen.obj \
+ $O\PanelItems.obj \
+ $O\PanelKey.obj \
+ $O\PanelListNotify.obj \
+ $O\PanelMenu.obj \
+ $O\PanelOperations.obj \
+ $O\PanelSelect.obj \
+ $O\PanelSort.obj \
+ $O\PanelSplitFile.obj \
+ $O\PhysDriveFolder.obj \
+ $O\ProgramLocation.obj \
+ $O\PropertyName.obj \
+ $O\RegistryAssociations.obj \
+ $O\RegistryPlugins.obj \
+ $O\RegistryUtils.obj \
+ $O\RootFolder.obj \
+ $O\SplitUtils.obj \
+ $O\StringUtils.obj \
+ $O\SysIconUtils.obj \
+ $O\TextPairs.obj \
+ $O\UpdateCallback100.obj \
+ $O\ViewSettings.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\CRC.obj \
+ $O\IntToString.obj \
+ $O\Lang.obj \
+ $O\ListFileUtils.obj \
+ $O\NewHandler.obj \
+ $O\Random.obj \
+ $O\StdInStream.obj \
+ $O\StdOutStream.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\TextConfig.obj \
+ $O\UTFConvert.obj \
+ $O\Vector.obj \
+ $O\Wildcard.obj \
+
+WIN_OBJS = \
+ $O\CommonDialog.obj \
+ $O\DLL.obj \
+ $O\Error.obj \
+ $O\FileDevice.obj \
+ $O\FileDir.obj \
+ $O\FileFind.obj \
+ $O\FileIO.obj \
+ $O\FileName.obj \
+ $O\FileSystem.obj \
+ $O\Memory.obj \
+ $O\MemoryLock.obj \
+ $O\Menu.obj \
+ $O\Net.obj \
+ $O\PropVariant.obj \
+ $O\PropVariantConversions.obj \
+ $O\Registry.obj \
+ $O\ResourceString.obj \
+ $O\Security.obj \
+ $O\Shell.obj \
+ $O\Synchronization.obj \
+ $O\Window.obj \
+
+WIN_CTRL_OBJS = \
+ $O\ComboBox.obj \
+ $O\Dialog.obj \
+ $O\ListView.obj \
+ $O\PropertyPage.obj \
+ $O\Window2.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\FilePathAutoRename.obj \
+ $O\FileStreams.obj \
+ $O\StreamObjects.obj \
+
+UI_COMMON_OBJS = \
+ $O\ArchiveName.obj \
+ $O\CompressCall.obj \
+ $O\PropIDUtils.obj \
+
+C_OBJS = \
+ $O\Sort.obj \
+
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(FM_OBJS)\
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(WIN_CTRL_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(UI_COMMON_OBJS) \
+ $O\AboutDialog.obj \
+ $O\BenchmarkDialog.obj \
+ $O\ComboDialog.obj \
+ $O\CopyDialog.obj \
+ $O\EditPage.obj \
+ $O\LangPage.obj \
+ $O\ListViewDialog.obj \
+ $O\MessagesDialog.obj \
+ $O\OverwriteDialog.obj \
+ $O\PasswordDialog.obj \
+ $O\PluginsPage.obj \
+ $O\ProgressDialog.obj \
+ $O\SettingsPage.obj \
+ $O\SplitDialog.obj \
+ $O\SystemPage.obj \
+ $O\resource.res \
+ $(C_OBJS) \
+
+!include "../../Build.mak"
+
+$(FM_OBJS): $(*B).cpp
+ $(COMPL)
+$(COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../Windows/$(*B).cpp
+ $(COMPL)
+$(WIN_CTRL_OBJS): ../../Windows/Control/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../Common/$(*B).cpp
+ $(COMPL)
+$(UI_COMMON_OBJS): ../UI/Common/$(*B).cpp
+ $(COMPL)
+
+$O\AboutDialog.obj: Resource/AboutDialog/AboutDialog.cpp
+ $(COMPL)
+$O\BenchmarkDialog.obj: Resource/BenchmarkDialog/BenchmarkDialog.cpp
+ $(COMPL)
+$O\ComboDialog.obj: Resource/ComboDialog/ComboDialog.cpp
+ $(COMPL)
+$O\CopyDialog.obj: Resource/CopyDialog/CopyDialog.cpp
+ $(COMPL)
+$O\EditPage.obj: Resource/EditPage/EditPage.cpp
+ $(COMPL)
+$O\LangPage.obj: Resource/LangPage/LangPage.cpp
+ $(COMPL)
+$O\ListViewDialog.obj: Resource/ListViewDialog/ListViewDialog.cpp
+ $(COMPL)
+$O\MessagesDialog.obj: Resource/MessagesDialog/MessagesDialog.cpp
+ $(COMPL)
+$O\OverwriteDialog.obj: Resource/OverwriteDialog/OverwriteDialog.cpp
+ $(COMPL)
+$O\PasswordDialog.obj: Resource/PasswordDialog/PasswordDialog.cpp
+ $(COMPL)
+$O\PluginsPage.obj: Resource/PluginsPage/PluginsPage.cpp
+ $(COMPL)
+$O\ProgressDialog.obj: Resource/ProgressDialog2/ProgressDialog.cpp
+ $(COMPL)
+$O\SettingsPage.obj: Resource/SettingsPage/SettingsPage.cpp
+ $(COMPL)
+$O\SplitDialog.obj: Resource/SplitDialog/SplitDialog.cpp
+ $(COMPL)
+$O\SystemPage.obj: Resource/SystemPage/SystemPage.cpp
+ $(COMPL)
+$(C_OBJS): ../../../C/$(*B).c
+ $(COMPL_O2)
+
+
diff --git a/CPP/7zip/FileManager/resource.h b/CPP/7zip/FileManager/resource.h
new file mode 100755
index 00000000..bc809306
--- /dev/null
+++ b/CPP/7zip/FileManager/resource.h
@@ -0,0 +1,154 @@
+#define IDI_FAM 101
+#define IDI_FM 101
+#define IDR_MENUBAR1 103
+#define IDM_MENU 103
+#define IDR_ACCELERATOR1 209
+#define IDM_FILE_OPEN 210
+#define IDM_FILE_OPEN_INSIDE 211
+#define IDM_FILE_OPEN_OUTSIDE 212
+#define IDM_FILE_VIEW 220
+#define IDM_FILE_EDIT 221
+#define IDM_RENAME 230
+#define IDM_COPY_TO 231
+#define IDM_MOVE_TO 232
+#define IDM_DELETE 233
+#define IDM_FILE_SPLIT 238
+#define IDM_FILE_COMBINE 239
+#define IDM_FILE_PROPERTIES 240
+#define IDM_FILE_COMMENT 241
+#define IDM_FILE_CRC 242
+#define IDM_CREATE_FOLDER 250
+#define IDM_CREATE_FILE 251
+#define IDM_EDIT_CUT 320
+#define IDM_EDIT_COPY 321
+#define IDM_EDIT_PASTE 322
+#define IDM_SELECT_ALL 330
+#define IDM_DESELECT_ALL 331
+#define IDM_INVERT_SELECTION 332
+#define IDM_SELECT 333
+#define IDM_DESELECT 334
+#define IDM_SELECT_BY_TYPE 335
+#define IDM_DESELECT_BY_TYPE 336
+#define IDM_VIEW_LARGE_ICONS 410
+#define IDM_VIEW_SMALL_ICONS 411
+#define IDM_VIEW_LIST 412
+#define IDM_VIEW_DETAILS 413
+#define IDM_VIEW_ARANGE_BY_NAME 420
+#define IDM_VIEW_ARANGE_BY_TYPE 421
+#define IDM_VIEW_ARANGE_BY_DATE 422
+#define IDM_VIEW_ARANGE_BY_SIZE 423
+#define IDM_VIEW_ARANGE_NO_SORT 424
+#define IDM_OPEN_ROOT_FOLDER 430
+#define IDM_OPEN_PARENT_FOLDER 431
+#define IDM_FOLDERS_HISTORY 432
+#define IDM_VIEW_REFRESH 440
+#define IDM_VIEW_FLAT_VIEW 449
+#define IDM_VIEW_TWO_PANELS 450
+#define IDM_VIEW_TOOLBARS 451
+#define IDM_VIEW_STANDARD_TOOLBAR 460
+#define IDM_VIEW_ARCHIVE_TOOLBAR 461
+#define IDM_VIEW_TOOLBARS_LARGE_BUTTONS 462
+#define IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT 463
+#define IDM_OPTIONS 510
+#define IDM_BENCHMARK 511
+#define IDM_HELP_CONTENTS 610
+#define IDM_ABOUT 620
+#define IDS_BOOKMARK 720
+#define IDB_ADD 2002
+#define IDB_EXTRACT 2003
+#define IDB_TEST 2004
+#define IDB_COPY 2010
+#define IDB_MOVE 2011
+#define IDB_DELETE 2012
+#define IDB_INFO 2013
+#define IDB_ADD2 2082
+#define IDB_EXTRACT2 2083
+#define IDB_TEST2 2084
+#define IDB_COPY2 2090
+#define IDB_MOVE2 2091
+#define IDB_DELETE2 2092
+#define IDB_INFO2 2093
+#define IDS_APP_TITLE 2200
+#define IDS_COPY 2201
+#define IDS_MOVE 2202
+#define IDS_COPY_TO 2203
+#define IDS_MOVE_TO 2204
+#define IDS_COPYING 2205
+#define IDS_MOVING 2206
+#define IDS_CANNOT_COPY 2207
+#define IDS_OPERATION_IS_NOT_SUPPORTED 2208
+
+#define IDS_CONFIRM_FILE_DELETE 2210
+#define IDS_CONFIRM_FOLDER_DELETE 2211
+#define IDS_CONFIRM_ITEMS_DELETE 2212
+#define IDS_WANT_TO_DELETE_FILE 2213
+#define IDS_WANT_TO_DELETE_FOLDER 2214
+#define IDS_WANT_TO_DELETE_ITEMS 2215
+#define IDS_DELETING 2216
+#define IDS_ERROR_DELETING 2217
+
+#define IDS_RENAMING 2220
+#define IDS_ERROR_RENAMING 2221
+#define IDS_CONFIRM_FILE_COPY 2222
+#define IDS_WANT_TO_COPY_FILES 2223
+
+
+#define IDS_CREATE_FOLDER 2230
+#define IDS_CREATE_FOLDER_NAME 2231
+#define IDS_CREATE_FOLDER_DEFAULT_NAME 2232
+#define IDS_CREATE_FOLDER_ERROR 2233
+#define IDS_CREATE_FILE 2240
+#define IDS_CREATE_FILE_NAME 2241
+#define IDS_CREATE_FOLDER_DEFAULT_FILE_NAME 2242
+#define IDS_CREATE_FILE_DEFAULT_NAME 2242
+#define IDS_CREATE_FILE_ERROR 2243
+#define IDS_SELECT 2250
+#define IDS_DESELECT 2251
+#define IDS_SELECT_MASK 2252
+#define IDS_FOLDERS_HISTORY 2260
+#define IDS_N_SELECTED_ITEMS 2270
+#define IDS_FILES_COLON 2274
+#define IDS_FOLDERS_COLON 2275
+#define IDS_SIZE_COLON 2276
+
+#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
+#define IDS_OPENNING 2283
+#define IDS_COMPUTER 2300
+#define IDS_NETWORK 2301
+#define IDS_ADD 2400
+#define IDS_EXTRACT 2401
+#define IDS_TEST 2402
+#define IDS_BUTTON_COPY 2420
+#define IDS_BUTTON_MOVE 2421
+#define IDS_BUTTON_DELETE 2422
+#define IDS_BUTTON_INFO 2423
+#define IDS_PROPERTY_TOTAL_SIZE 3100
+#define IDS_PROPERTY_FREE_SPACE 3101
+#define IDS_PROPERTY_CLUSTER_SIZE 3102
+#define IDS_PROPERTY_VOLUME_NAME 3103
+#define IDS_PROPERTY_LOCAL_NAME 3200
+#define IDS_PROPERTY_PROVIDER 3201
+#define IDS_OPTIONS 4000
+#define IDS_COMMENT 4001
+#define IDS_COMMENT2 4002
+#define IDS_SYSTEM 4010
+
+#define IDS_SPLITTING 4020
+#define IDS_SPLIT_CONFIRM_TITLE 4021
+#define IDS_SPLIT_CONFIRM_MESSAGE 4022
+#define IDS_SPLIT_VOL_MUST_BE_SMALLER 4023
+
+#define IDS_COMBINE 4030
+#define IDS_COMBINE_TO 4031
+#define IDS_COMBINING 4032
+#define IDS_COMBINE_SELECT_ONE_FILE 4033
+
+#define IDS_CHECKSUM_CALCULATING 4040
+#define IDS_CHECKSUM_INFORMATION 4041
+#define IDS_CHECKSUM_CRC_DATA 4042
+#define IDS_CHECKSUM_CRC_DATA_NAMES 4043
+
+#define IDS_SCANNING 4050
diff --git a/CPP/7zip/FileManager/resource.rc b/CPP/7zip/FileManager/resource.rc
new file mode 100755
index 00000000..ed56cd48
--- /dev/null
+++ b/CPP/7zip/FileManager/resource.rc
@@ -0,0 +1,232 @@
+#include "../MyVersionInfo.rc"
+#include "../GuiCommon.rc"
+#include "resource.h"
+
+MY_VERSION_INFO_APP("7-Zip File Manager", "7zFM")
+
+
+IDR_ACCELERATOR1 ACCELERATORS
+BEGIN
+ "N", IDM_CREATE_FILE, VIRTKEY, CONTROL, NOINVERT
+ VK_F1, IDM_HELP_CONTENTS, VIRTKEY, NOINVERT
+ VK_F12, IDM_FOLDERS_HISTORY, VIRTKEY, ALT, NOINVERT
+ VK_F7, IDM_CREATE_FOLDER, VIRTKEY, NOINVERT
+END
+
+
+IDM_MENU MENU
+BEGIN
+ POPUP "&File"
+ BEGIN
+ MENUITEM "&Open\tEnter", IDM_FILE_OPEN
+ MENUITEM "Open &Inside\tCtrl+PgDn", IDM_FILE_OPEN_INSIDE
+ MENUITEM "Open O&utside\tShift+Enter", IDM_FILE_OPEN_OUTSIDE
+ MENUITEM "&Edit\tF4", IDM_FILE_EDIT
+ MENUITEM SEPARATOR
+ MENUITEM "Rena&me\tF2", IDM_RENAME
+ MENUITEM "&Copy To...\tF5", IDM_COPY_TO
+ MENUITEM "&Move To...\tF6", IDM_MOVE_TO
+ MENUITEM "&Delete\tDel", IDM_DELETE
+ MENUITEM SEPARATOR
+ MENUITEM "&Split file...", IDM_FILE_SPLIT
+ MENUITEM "Com&bine files...", IDM_FILE_COMBINE
+ MENUITEM SEPARATOR
+ MENUITEM "P&roperties\tAlt+Enter", IDM_FILE_PROPERTIES
+ MENUITEM "Comme&nt\tCtrl+Z", IDM_FILE_COMMENT
+ MENUITEM "Calculate checksum", IDM_FILE_CRC
+ MENUITEM SEPARATOR
+ MENUITEM "Create Folder\tF7", IDM_CREATE_FOLDER
+ MENUITEM "Create File\tCtrl+N", IDM_CREATE_FILE
+ MENUITEM SEPARATOR
+ MENUITEM "E&xit\tAlt+F4", IDCLOSE
+ END
+ POPUP "&Edit"
+ BEGIN
+ MENUITEM "Cu&t\tCtrl+X", IDM_EDIT_CUT, GRAYED
+ MENUITEM "&Copy\tCtrl+C", IDM_EDIT_COPY, GRAYED
+ MENUITEM "&Paste\tCtrl+V", IDM_EDIT_PASTE, GRAYED
+ MENUITEM SEPARATOR
+ MENUITEM "Select &All\tShift+[Grey +]", IDM_SELECT_ALL
+ MENUITEM "Deselect All\tShift+[Grey -]", IDM_DESELECT_ALL
+ MENUITEM "&Invert Selection\tGrey *", IDM_INVERT_SELECTION
+ MENUITEM "Select...\tGrey +", IDM_SELECT
+ MENUITEM "Deselect...\tGrey -", IDM_DESELECT
+ MENUITEM "Select by Type\tAlt+[Grey+]", IDM_SELECT_BY_TYPE
+ MENUITEM "Deselect by Type\tAlt+[Grey -]", IDM_DESELECT_BY_TYPE
+ END
+ POPUP "&View"
+ BEGIN
+ MENUITEM "Lar&ge Icons\tCtrl+1", IDM_VIEW_LARGE_ICONS
+ MENUITEM "S&mall Icons\tCtrl+2", IDM_VIEW_SMALL_ICONS
+ MENUITEM "&List\tCtrl+3", IDM_VIEW_LIST
+ MENUITEM "&Details\tCtrl+4", IDM_VIEW_DETAILS, CHECKED
+ MENUITEM SEPARATOR
+ MENUITEM "Name\tCtrl+F3", IDM_VIEW_ARANGE_BY_NAME
+ MENUITEM "Type\tCtrl+F4", IDM_VIEW_ARANGE_BY_TYPE
+ MENUITEM "Date\tCtrl+F5", IDM_VIEW_ARANGE_BY_DATE
+ MENUITEM "Size\tCtrl+F6", IDM_VIEW_ARANGE_BY_SIZE
+ MENUITEM "Unsorted\tCtrl+F7", IDM_VIEW_ARANGE_NO_SORT
+ MENUITEM SEPARATOR
+ MENUITEM "Flat View", IDM_VIEW_FLAT_VIEW
+ MENUITEM "&2 Panels\tF9", IDM_VIEW_TWO_PANELS
+ POPUP "Toolbars"
+ BEGIN
+ MENUITEM "Archive Toolbar", IDM_VIEW_ARCHIVE_TOOLBAR
+ MENUITEM "Standard Toolbar", IDM_VIEW_STANDARD_TOOLBAR
+ MENUITEM SEPARATOR
+ MENUITEM "Large Buttons", IDM_VIEW_TOOLBARS_LARGE_BUTTONS
+ MENUITEM "Show Buttons Text", IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT
+ END
+ MENUITEM SEPARATOR
+ MENUITEM "Open Root Folder\t\\", IDM_OPEN_ROOT_FOLDER
+ MENUITEM "Up One Level\tBackspace", IDM_OPEN_PARENT_FOLDER
+ MENUITEM "Folders History...\tAlt+F12", IDM_FOLDERS_HISTORY
+ MENUITEM SEPARATOR
+ MENUITEM "&Refresh\tCtrl+R", IDM_VIEW_REFRESH
+ END
+ POPUP "F&avorites"
+ BEGIN
+ POPUP "&Add folder to Favorites as"
+ BEGIN
+ MENUITEM SEPARATOR
+ END
+ MENUITEM SEPARATOR
+ END
+ POPUP "&Tools"
+ BEGIN
+ MENUITEM "&Options...", IDM_OPTIONS
+ MENUITEM "&Benchmark", IDM_BENCHMARK
+ END
+ POPUP "&Help"
+ BEGIN
+ MENUITEM "&Contents...\tF1", IDM_HELP_CONTENTS
+ MENUITEM SEPARATOR
+ MENUITEM "&About 7-Zip...", IDM_ABOUT
+ END
+END
+
+
+IDI_FM ICON "FM.ico"
+
+1 24 MOVEABLE PURE "7zFM.exe.manifest"
+
+IDB_ADD BITMAP "Add.bmp"
+IDB_EXTRACT BITMAP "Extract.bmp"
+IDB_TEST BITMAP "Test.bmp"
+IDB_COPY BITMAP "Copy.bmp"
+IDB_MOVE BITMAP "Move.bmp"
+IDB_DELETE BITMAP "Delete.bmp"
+IDB_INFO BITMAP "Info.bmp"
+IDB_ADD2 BITMAP "Add2.bmp"
+IDB_EXTRACT2 BITMAP "Extract2.bmp"
+IDB_TEST2 BITMAP "Test2.bmp"
+IDB_COPY2 BITMAP "Copy2.bmp"
+IDB_MOVE2 BITMAP "Move2.bmp"
+IDB_DELETE2 BITMAP "Delete2.bmp"
+IDB_INFO2 BITMAP "Info2.bmp"
+
+
+STRINGTABLE
+BEGIN
+ IDS_APP_TITLE "7-Zip File Manager"
+ IDS_COPY "Copy"
+ IDS_MOVE "Move"
+ IDS_COPY_TO "Copy to:"
+ IDS_MOVE_TO "Move to:"
+ IDS_COPYING "Copying..."
+ IDS_MOVING "Moving..."
+ IDS_CANNOT_COPY "You cannot move or copy items for such folders."
+ IDS_SPLITTING "Splitting..."
+ IDS_SPLIT_CONFIRM_TITLE "Confirm Splitting"
+ IDS_SPLIT_CONFIRM_MESSAGE "Are you sure you want to split file into {0} volumes?"
+ IDS_SPLIT_VOL_MUST_BE_SMALLER "Volume size must be smaller than size of original file"
+
+ IDS_COMBINE "Combine Files"
+ IDS_COMBINE_TO "&Combine to:"
+ IDS_COMBINING "Combining..."
+ IDS_COMBINE_SELECT_ONE_FILE "Select only first file"
+
+ IDS_CHECKSUM_CALCULATING "Checksum calculating..."
+ IDS_CHECKSUM_INFORMATION "Checksum information"
+ IDS_CHECKSUM_CRC_DATA "CRC checksum for data:"
+ IDS_CHECKSUM_CRC_DATA_NAMES "CRC checksum for data and names:"
+
+ IDS_SCANNING "Scanning..."
+
+ IDS_OPERATION_IS_NOT_SUPPORTED "Operation is not supported."
+
+ IDS_CONFIRM_FILE_DELETE "Confirm File Delete"
+ IDS_CONFIRM_FOLDER_DELETE "Confirm Folder Delete"
+ IDS_CONFIRM_ITEMS_DELETE "Confirm Multiple File Delete"
+ IDS_WANT_TO_DELETE_FILE "Are you sure you want to delete '{0}'?"
+ IDS_WANT_TO_DELETE_FOLDER "Are you sure you want to delete the folder '{0}' and all its contents?"
+ IDS_WANT_TO_DELETE_ITEMS "Are you sure you want to delete these {0} items?"
+ IDS_DELETING "Deleting..."
+ IDS_ERROR_DELETING "Error Deleting File or Folder"
+ IDS_RENAMING "Renaming..."
+ IDS_ERROR_RENAMING "Error Renaming File or Folder"
+ IDS_CONFIRM_FILE_COPY "Confirm File Copy"
+ IDS_WANT_TO_COPY_FILES "Are you sure you want to copy files to archive"
+
+ IDS_CREATE_FOLDER "Create Folder"
+ IDS_CREATE_FOLDER_NAME "Folder name:"
+ IDS_CREATE_FOLDER_DEFAULT_NAME "New Folder"
+ IDS_CREATE_FOLDER_ERROR "Error Creating Folder"
+ IDS_CREATE_FILE "Create File"
+ IDS_CREATE_FILE_NAME "File Name:"
+ IDS_CREATE_FILE_DEFAULT_NAME "New File"
+ IDS_CREATE_FILE_ERROR "Error Creating File"
+ IDS_SELECT "Select"
+ IDS_DESELECT "Deselect"
+ IDS_SELECT_MASK "Mask:"
+ IDS_FOLDERS_HISTORY "Folders History"
+ IDS_N_SELECTED_ITEMS "{0} object(s) selected"
+ IDS_FILES_COLON "Files:"
+ IDS_FOLDERS_COLON "Folders:"
+ IDS_SIZE_COLON "Size:"
+
+ IDS_PROPERTY_TOTAL_SIZE "Total Size"
+ IDS_PROPERTY_FREE_SPACE "Free Space"
+ IDS_PROPERTY_CLUSTER_SIZE "Cluster Size"
+ IDS_PROPERTY_VOLUME_NAME "Label"
+ IDS_PROPERTY_LOCAL_NAME "Local Name"
+ IDS_PROPERTY_PROVIDER "Provider"
+ IDS_OPTIONS "Options"
+ 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."
+ IDS_OPENNING "Opening..."
+ IDS_ADD "Add"
+ IDS_EXTRACT "Extract"
+ IDS_TEST "Test"
+ IDS_BUTTON_COPY "Copy"
+ IDS_BUTTON_MOVE "Move"
+ IDS_BUTTON_DELETE "Delete"
+ IDS_BUTTON_INFO "Info"
+ IDS_BOOKMARK "Bookmark"
+ IDS_COMPUTER "Computer"
+ IDS_NETWORK "Network"
+END
+
+
+#include "Resource/ComboDialog/resource.rc"
+#include "Resource/CopyDialog/resource.rc"
+#include "Resource/ListViewDialog/resource.rc"
+#include "Resource/PropertyName/resource.rc"
+#include "Resource/MessagesDialog/resource.rc"
+#include "Resource/OverwriteDialog/resource.rc"
+#include "Resource/PasswordDialog/resource.rc"
+#include "Resource/SplitDialog/resource.rc"
+#include "Resource/ProgressDialog2/resource.rc"
+#include "Resource/BenchmarkDialog/resource.rc"
+#include "Resource/AboutDialog/resource.rc"
+#include "Resource/LangPage/resource.rc"
+#include "Resource/PluginsPage/resource.rc"
+#include "Resource/SystemPage/resource.rc"
+#include "Resource/EditPage/resource.rc"
+#include "Resource/SettingsPage/resource.rc"
+#include "../UI/Resource/Extract/resource.rc"
diff --git a/CPP/7zip/GuiCommon.rc b/CPP/7zip/GuiCommon.rc
new file mode 100755
index 00000000..66dc5ca6
--- /dev/null
+++ b/CPP/7zip/GuiCommon.rc
@@ -0,0 +1,37 @@
+#include <winnt.h>
+#include <WinUser.h>
+#include <CommCtrl.h>
+
+#define marg 7
+#undef bXSize
+#undef bYSize
+#define bXSize 64
+#define bYSize 14
+#define bDotsSize 20
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+#undef xSize2
+#undef ySize2
+#undef xSize
+#undef ySize
+#undef bXPos
+#undef bYPos
+#undef b1XPos
+#undef b1YPos
+#undef b2XPos
+#undef b2YPos
+#undef b3XPos
+#undef b3YPos
+#undef gPos
+#undef gPos2
+#undef gSpace
+#undef gSize
+#undef marg2
+#undef marg3
+
+
+#define MY_MODAL_DIALOG_STYLE STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+#define MY_PAGE_STYLE STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+
+#define MY_FONT FONT 8, "MS Shell Dlg"
diff --git a/CPP/7zip/Guid.txt b/CPP/7zip/Guid.txt
new file mode 100755
index 00000000..8fa5a291
--- /dev/null
+++ b/CPP/7zip/Guid.txt
@@ -0,0 +1,157 @@
+{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
+25 ICompressSetCoderMt
+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 IFolderSetFlatMode
+
+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
+09 Nsis
+0A Lzma
+
+E7 Iso
+E8 Bkf
+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/CPP/7zip/ICoder.h b/CPP/7zip/ICoder.h
new file mode 100755
index 00000000..d84575dc
--- /dev/null
+++ b/CPP/7zip/ICoder.h
@@ -0,0 +1,163 @@
+// ICoder.h
+
+#ifndef __ICODER_H
+#define __ICODER_H
+
+#include "IStream.h"
+
+// "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) PURE;
+};
+
+CODER_INTERFACE(ICompressCoder, 0x05)
+{
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize,
+ const UInt64 *outSize,
+ ICompressProgressInfo *progress) PURE;
+};
+
+CODER_INTERFACE(ICompressCoder2, 0x18)
+{
+ STDMETHOD(Code)(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress) PURE;
+};
+
+namespace NCoderPropID
+{
+ enum EEnum
+ {
+ kDictionarySize = 0x400,
+ kUsedMemorySize,
+ kOrder,
+ kPosStateBits = 0x440,
+ kLitContextBits,
+ kLitPosBits,
+ kNumFastBytes = 0x450,
+ kMatchFinder,
+ kMatchFinderCycles,
+ kNumPasses = 0x460,
+ kAlgorithm = 0x470,
+ kMultiThread = 0x480,
+ kNumThreads,
+ kEndMarker = 0x490
+ };
+}
+
+CODER_INTERFACE(ICompressSetCoderProperties, 0x20)
+{
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties) PURE;
+};
+
+/*
+CODER_INTERFACE(ICompressSetCoderProperties, 0x21)
+{
+ STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE;
+};
+*/
+
+CODER_INTERFACE(ICompressSetDecoderProperties2, 0x22)
+{
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size) PURE;
+};
+
+CODER_INTERFACE(ICompressWriteCoderProperties, 0x23)
+{
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStreams) PURE;
+};
+
+CODER_INTERFACE(ICompressGetInStreamProcessedSize, 0x24)
+{
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE;
+};
+
+CODER_INTERFACE(ICompressSetCoderMt, 0x25)
+{
+ STDMETHOD(SetNumberOfThreads)(UInt32 numThreads) PURE;
+};
+
+CODER_INTERFACE(ICompressGetSubStreamSize, 0x30)
+{
+ STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value) PURE;
+};
+
+CODER_INTERFACE(ICompressSetInStream, 0x31)
+{
+ STDMETHOD(SetInStream)(ISequentialInStream *inStream) PURE;
+ STDMETHOD(ReleaseInStream)() PURE;
+};
+
+CODER_INTERFACE(ICompressSetOutStream, 0x32)
+{
+ STDMETHOD(SetOutStream)(ISequentialOutStream *outStream) PURE;
+ STDMETHOD(ReleaseOutStream)() PURE;
+};
+
+CODER_INTERFACE(ICompressSetInStreamSize, 0x33)
+{
+ STDMETHOD(SetInStreamSize)(const UInt64 *inSize) PURE;
+};
+
+CODER_INTERFACE(ICompressSetOutStreamSize, 0x34)
+{
+ STDMETHOD(SetOutStreamSize)(const UInt64 *outSize) PURE;
+};
+
+CODER_INTERFACE(ICompressFilter, 0x40)
+{
+ STDMETHOD(Init)() PURE;
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) PURE;
+ // Filter return outSize (UInt32)
+ // if (outSize <= size): Filter have converted outSize bytes
+ // if (outSize > size): Filter have not converted anything.
+ // and it needs at least outSize bytes to convert one block
+ // (it's for crypto block algorithms).
+};
+
+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
+{
+ enum EEnum
+ {
+ kID,
+ kName,
+ kDecoder,
+ kEncoder,
+ kInStreams,
+ kOutStreams,
+ kDescription
+ };
+}
+
+#endif
diff --git a/CPP/7zip/IPassword.h b/CPP/7zip/IPassword.h
new file mode 100755
index 00000000..8f2adcca
--- /dev/null
+++ b/CPP/7zip/IPassword.h
@@ -0,0 +1,26 @@
+// IPassword.h
+
+#ifndef __IPASSWORD_H
+#define __IPASSWORD_H
+
+#include "../Common/MyUnknown.h"
+#include "../Common/Types.h"
+
+// 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
+
+PASSWORD_INTERFACE(ICryptoGetTextPassword, 0x10)
+{
+ STDMETHOD(CryptoGetTextPassword)(BSTR *password) PURE;
+};
+
+PASSWORD_INTERFACE(ICryptoGetTextPassword2, 0x11)
+{
+ STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password) PURE;
+};
+
+#endif
+
diff --git a/CPP/7zip/IProgress.h b/CPP/7zip/IProgress.h
new file mode 100755
index 00000000..aa3b64cc
--- /dev/null
+++ b/CPP/7zip/IProgress.h
@@ -0,0 +1,32 @@
+// Interface/IProgress.h
+
+#ifndef __IPROGRESS_H
+#define __IPROGRESS_H
+
+#include "../Common/MyUnknown.h"
+#include "../Common/Types.h"
+
+// {23170F69-40C1-278A-0000-000000050000}
+DEFINE_GUID(IID_IProgress,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000000050000")
+IProgress: public IUnknown
+{
+ STDMETHOD(SetTotal)(UInt64 total) PURE;
+ STDMETHOD(SetCompleted)(const UInt64 *completeValue) PURE;
+};
+
+/*
+// {23170F69-40C1-278A-0000-000000050002}
+DEFINE_GUID(IID_IProgress2,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000000050002")
+IProgress2: public IUnknown
+{
+public:
+ STDMETHOD(SetTotal)(const UInt64 *total) PURE;
+ STDMETHOD(SetCompleted)(const UInt64 *completeValue) PURE;
+};
+*/
+
+#endif
diff --git a/CPP/7zip/IStream.h b/CPP/7zip/IStream.h
new file mode 100755
index 00000000..bba21a31
--- /dev/null
+++ b/CPP/7zip/IStream.h
@@ -0,0 +1,62 @@
+// IStream.h
+
+#ifndef __ISTREAM_H
+#define __ISTREAM_H
+
+#include "../Common/MyUnknown.h"
+#include "../Common/Types.h"
+
+// "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)
+{
+ 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
+ */
+};
+
+STREAM_INTERFACE(ISequentialOutStream, 0x02)
+{
+ 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
+ */
+};
+
+STREAM_INTERFACE_SUB(IInStream, ISequentialInStream, 0x03)
+{
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;
+};
+
+STREAM_INTERFACE_SUB(IOutStream, ISequentialOutStream, 0x04)
+{
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;
+ STDMETHOD(SetSize)(Int64 newSize) PURE;
+};
+
+STREAM_INTERFACE(IStreamGetSize, 0x06)
+{
+ STDMETHOD(GetSize)(UInt64 *size) PURE;
+};
+
+STREAM_INTERFACE(IOutStreamFlush, 0x07)
+{
+ STDMETHOD(Flush)() PURE;
+};
+
+#endif
diff --git a/CPP/7zip/MyVersion.h b/CPP/7zip/MyVersion.h
new file mode 100755
index 00000000..7243563c
--- /dev/null
+++ b/CPP/7zip/MyVersion.h
@@ -0,0 +1,8 @@
+#define MY_VER_MAJOR 4
+#define MY_VER_MINOR 44
+#define MY_VER_BUILD 3
+#define MY_VERSION "4.44 beta"
+#define MY_7ZIP_VERSION "7-Zip 4.44 beta"
+#define MY_DATE "2007-01-20"
+#define MY_COPYRIGHT "Copyright (c) 1999-2007 Igor Pavlov"
+#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE
diff --git a/CPP/7zip/MyVersionInfo.rc b/CPP/7zip/MyVersionInfo.rc
new file mode 100755
index 00000000..fd52d6aa
--- /dev/null
+++ b/CPP/7zip/MyVersionInfo.rc
@@ -0,0 +1,41 @@
+#include <WinVer.h>
+#include "MyVersion.h"
+
+#define MY_VER MY_VER_MAJOR,MY_VER_MINOR,MY_VER_BUILD,0
+
+#ifdef DEBUG
+#define DBG_FL VS_FF_DEBUG
+#else
+#define DBG_FL 0
+#endif
+
+#define MY_VERSION_INFO(fileType, descr, intName, origName) \
+LANGUAGE 9, 1 \
+1 VERSIONINFO \
+ FILEVERSION MY_VER \
+ PRODUCTVERSION MY_VER \
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK \
+ FILEFLAGS DBG_FL \
+ FILEOS VOS_NT_WINDOWS32 \
+ FILETYPE fileType \
+ FILESUBTYPE 0x0L \
+BEGIN \
+ BLOCK "StringFileInfo" \
+ BEGIN \
+ BLOCK "040904b0" \
+ BEGIN \
+ VALUE "CompanyName", "Igor Pavlov" \
+ VALUE "FileDescription", descr \
+ VALUE "FileVersion", MY_VERSION \
+ VALUE "InternalName", intName \
+ VALUE "LegalCopyright", MY_COPYRIGHT \
+ VALUE "OriginalFilename", origName \
+ VALUE "ProductName", "7-Zip" \
+ VALUE "ProductVersion", MY_VERSION \
+ END \
+ END \
+END
+
+#define MY_VERSION_INFO_APP(descr, intName) MY_VERSION_INFO(VFT_APP, descr, intName, intName ".exe")
+
+#define MY_VERSION_INFO_DLL(descr, intName) MY_VERSION_INFO(VFT_DLL, descr, intName, intName ".dll")
diff --git a/CPP/7zip/PropID.h b/CPP/7zip/PropID.h
new file mode 100755
index 00000000..79f82452
--- /dev/null
+++ b/CPP/7zip/PropID.h
@@ -0,0 +1,51 @@
+// Interface/PropID.h
+
+#ifndef __INTERFACE_PROPID_H
+#define __INTERFACE_PROPID_H
+
+enum
+{
+ kpidNoProperty = 0,
+
+ kpidHandlerItemIndex = 2,
+ kpidPath,
+ kpidName,
+ kpidExtension,
+ kpidIsFolder,
+ kpidSize,
+ kpidPackedSize,
+ kpidAttributes,
+ kpidCreationTime,
+ kpidLastAccessTime,
+ kpidLastWriteTime,
+ kpidSolid,
+ kpidCommented,
+ kpidEncrypted,
+ kpidSplitBefore,
+ kpidSplitAfter,
+ kpidDictionarySize,
+ kpidCRC,
+ kpidType,
+ kpidIsAnti,
+ kpidMethod,
+ kpidHostOS,
+ kpidFileSystem,
+ kpidUser,
+ kpidGroup,
+ kpidBlock,
+ kpidComment,
+ kpidPosition,
+ kpidPrefix,
+
+ kpidTotalSize = 0x1100,
+ kpidFreeSpace,
+ kpidClusterSize,
+ kpidVolumeName,
+
+ kpidLocalName = 0x1200,
+ kpidProvider,
+
+ kpidUserDefined = 0x10000
+};
+
+#endif
diff --git a/CPP/7zip/SubBuild.mak b/CPP/7zip/SubBuild.mak
new file mode 100755
index 00000000..f86ce436
--- /dev/null
+++ b/CPP/7zip/SubBuild.mak
@@ -0,0 +1,3 @@
+ cd $(@D)
+ $(MAKE) -nologo $(TARGETS)
+ cd ..
diff --git a/CPP/7zip/UI/Agent/Agent.cpp b/CPP/7zip/UI/Agent/Agent.cpp
new file mode 100755
index 00000000..f983e2f9
--- /dev/null
+++ b/CPP/7zip/UI/Agent/Agent.cpp
@@ -0,0 +1,578 @@
+// Agent.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StringConvert.h"
+#include "Common/ComTry.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+#include "Windows/FileFind.h"
+
+#include "../Common/DefaultName.h"
+#include "../Common/ArchiveExtractCallback.h"
+
+#include "Agent.h"
+
+#ifdef FORMAT_7Z
+#include "../../Archive/7z/7zHandler.h"
+#endif
+
+extern "C"
+{
+ #include "../../../../C/Sort.h"
+}
+
+
+using namespace NWindows;
+
+STDMETHODIMP CAgentFolder::GetAgentFolder(CAgentFolder **agentFolder)
+{
+ *agentFolder = this;
+ return S_OK;
+}
+
+void CAgentFolder::LoadFolder(CProxyFolder *folder)
+{
+ int i;
+ CProxyItem item;
+ item.Folder = folder;
+ for (i = 0; i < folder->Folders.Size(); i++)
+ {
+ item.Index = i;
+ _items.Add(item);
+ LoadFolder(&folder->Folders[i]);
+ }
+ int start = folder->Folders.Size();
+ for (i = 0; i < folder->Files.Size(); i++)
+ {
+ item.Index = start + i;
+ _items.Add(item);
+ }
+}
+
+
+STDMETHODIMP CAgentFolder::LoadItems()
+{
+ _items.Clear();
+ if (_flatMode)
+ LoadFolder(_proxyFolderItem);
+ return S_OK;
+}
+
+STDMETHODIMP CAgentFolder::GetNumberOfItems(UINT32 *numItems)
+{
+ if (_flatMode)
+ *numItems = _items.Size();
+ else
+ *numItems = _proxyFolderItem->Folders.Size() +_proxyFolderItem->Files.Size();
+ return S_OK;
+}
+
+/*
+STDMETHODIMP CAgentFolder::GetNumberOfSubFolders(UINT32 *aNumSubFolders)
+{
+ *aNumSubFolders = _proxyFolderItem->Folders.Size();
+ return S_OK;
+}
+*/
+
+UString CAgentFolder::GetName(UInt32 index) const
+{
+ UInt32 realIndex;
+ const CProxyFolder *folder;
+ if (_flatMode)
+ {
+ const CProxyItem &item = _items[index];
+ folder = item.Folder;
+ realIndex = item.Index;
+ }
+ else
+ {
+ folder = _proxyFolderItem;
+ realIndex = index;
+ }
+
+ if (realIndex < (UINT32)folder->Folders.Size())
+ return folder->Folders[realIndex].Name;
+ return folder->Files[realIndex - folder->Folders.Size()].Name;
+}
+
+UString CAgentFolder::GetPrefix(UInt32 index) const
+{
+ if (!_flatMode)
+ return UString();
+ const CProxyItem &item = _items[index];
+ const CProxyFolder *folder = item.Folder;
+ UString path;
+ while(folder != _proxyFolderItem)
+ {
+ path = folder->Name + UString(L"\\") + path;
+ folder = folder->Parent;
+ }
+ return path;
+}
+
+UString CAgentFolder::GetFullPathPrefixPlusPrefix(UInt32 index) const
+{
+ return _proxyFolderItem->GetFullPathPrefix() + GetPrefix(index);
+}
+
+void CAgentFolder::GetPrefixIfAny(UInt32 index, NCOM::CPropVariant &propVariant) const
+{
+ if (!_flatMode)
+ return;
+ propVariant = GetPrefix(index);
+}
+
+
+STDMETHODIMP CAgentFolder::GetProperty(UINT32 itemIndex, PROPID propID, PROPVARIANT *value)
+{
+ NCOM::CPropVariant propVariant;
+ const CProxyFolder *folder;
+ UInt32 realIndex;
+ if (_flatMode)
+ {
+ const CProxyItem &item = _items[itemIndex];
+ folder = item.Folder;
+ realIndex = item.Index;
+ }
+ else
+ {
+ folder = _proxyFolderItem;
+ realIndex = itemIndex;
+ }
+
+ if (realIndex < (UINT32)folder->Folders.Size())
+ {
+ const CProxyFolder &item = folder->Folders[realIndex];
+ switch(propID)
+ {
+ case kpidIsFolder:
+ propVariant = true;
+ break;
+ case kpidName:
+ propVariant = item.Name;
+ break;
+ case kpidPrefix:
+ GetPrefixIfAny(itemIndex, propVariant);
+ break;
+ default:
+ if (item.IsLeaf)
+ return _agentSpec->GetArchive()->GetProperty(item.Index, propID, value);
+ }
+ }
+ else
+ {
+ realIndex -= folder->Folders.Size();
+ const CProxyFile &item = folder->Files[realIndex];
+ switch(propID)
+ {
+ case kpidIsFolder:
+ propVariant = false;
+ break;
+ case kpidName:
+ propVariant = item.Name;
+ break;
+ case kpidPrefix:
+ GetPrefixIfAny(itemIndex, propVariant);
+ break;
+ default:
+ return _agentSpec->GetArchive()->GetProperty(item.Index, propID, value);
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
+
+HRESULT CAgentFolder::BindToFolder(CProxyFolder *folder, IFolderFolder **resultFolder)
+{
+ CMyComPtr<IFolderFolder> parentFolder;
+ if (folder->Parent != _proxyFolderItem)
+ {
+ RINOK(BindToFolder(folder->Parent, &parentFolder));
+ }
+ else
+ parentFolder = this;
+ CAgentFolder *folderSpec = new CAgentFolder;
+ CMyComPtr<IFolderFolder> agentFolder = folderSpec;
+ folderSpec->Init(_proxyArchive, folder, parentFolder, _agentSpec);
+ *resultFolder = agentFolder.Detach();
+ return S_OK;
+}
+
+STDMETHODIMP CAgentFolder::BindToFolder(UINT32 index, IFolderFolder **resultFolder)
+{
+ COM_TRY_BEGIN
+
+ CProxyFolder *folder;
+ UInt32 realIndex;
+ if (_flatMode)
+ {
+ const CProxyItem &item = _items[index];
+ folder = item.Folder;
+ realIndex = item.Index;
+ }
+ else
+ {
+ folder = _proxyFolderItem;
+ realIndex = index;
+ }
+ if (realIndex >= (UINT32)folder->Folders.Size())
+ return E_INVALIDARG;
+ return BindToFolder(&folder->Folders[realIndex], resultFolder);
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgentFolder::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder)
+{
+ COM_TRY_BEGIN
+ int index = _proxyFolderItem->FindDirSubItemIndex(name);
+ if (index < 0)
+ return E_INVALIDARG;
+ return BindToFolder(index, resultFolder);
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgentFolder::BindToParentFolder(IFolderFolder **resultFolder)
+{
+ COM_TRY_BEGIN
+ CMyComPtr<IFolderFolder> parentFolder = _parentFolder;
+ *resultFolder = parentFolder.Detach();
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgentFolder::GetName(BSTR *name)
+{
+ CMyComBSTR temp = _proxyFolderItem->Name;
+ *name = temp.Detach();
+ return S_OK;
+}
+
+
+#ifdef NEW_FOLDER_INTERFACE
+
+struct CArchiveItemPropertyTemp
+{
+ UString Name;
+ PROPID ID;
+ VARTYPE Type;
+};
+
+STDMETHODIMP CAgentFolder::GetNumberOfProperties(UINT32 *numProperties)
+{
+ COM_TRY_BEGIN
+ RINOK(_agentSpec->GetArchive()->GetNumberOfProperties(numProperties));
+ if (_flatMode)
+ (*numProperties)++;
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgentFolder::GetPropertyInfo(UINT32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType)
+{
+ COM_TRY_BEGIN
+ UINT32 numProperties;
+ _agentSpec->GetArchive()->GetNumberOfProperties(&numProperties);
+ if (index < numProperties)
+ {
+ RINOK(_agentSpec->GetArchive()->GetPropertyInfo(index, name, propID, varType));
+ if (*propID == kpidPath)
+ *propID = kpidName;
+ }
+ else
+ {
+ *name = NULL;
+ *propID = kpidPrefix;
+ *varType = VT_BSTR;
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgentFolder::GetTypeID(BSTR *name)
+{
+ COM_TRY_BEGIN
+ UString temp = UString(L"7-Zip.") + _agentSpec->ArchiveType;
+ CMyComBSTR bstrTemp = temp;
+ *name = bstrTemp.Detach();
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgentFolder::GetPath(BSTR *path)
+{
+ COM_TRY_BEGIN
+ UStringVector pathParts;
+ pathParts.Clear();
+ CMyComPtr<IFolderFolder> currentFolder = this;
+ for (;;)
+ {
+ CMyComPtr<IFolderFolder> newFolder;
+ currentFolder->BindToParentFolder(&newFolder);
+ if (newFolder == NULL)
+ break;
+ CMyComBSTR aName;
+ currentFolder->GetName(&aName);
+ pathParts.Insert(0, (const wchar_t *)aName);
+ currentFolder = newFolder;
+ }
+
+ UString prefix;
+ for(int i = 0; i < pathParts.Size(); i++)
+ {
+ prefix += pathParts[i];
+ prefix += L'\\';
+ }
+
+ CMyComBSTR tempPath = prefix;
+ *path = tempPath.Detach();
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgentFolder::SetFlatMode(Int32 flatMode)
+{
+ _flatMode = IntToBool(flatMode);
+ return S_OK;
+}
+
+#endif
+
+void CAgentFolder::GetRealIndices(const UINT32 *indices, UINT32 numItems, CUIntVector &realIndices) const
+{
+ if (!_flatMode)
+ {
+ _proxyFolderItem->GetRealIndices(indices, numItems, realIndices);
+ return;
+ }
+ realIndices.Clear();
+ for(UINT32 i = 0; i < numItems; i++)
+ {
+ const CProxyItem &item = _items[indices[i]];
+ const CProxyFolder *folder = item.Folder;
+ UInt32 realIndex = item.Index;
+ if (realIndex < (UINT32)folder->Folders.Size())
+ continue;
+ realIndices.Add(folder->Files[realIndex - folder->Folders.Size()].Index);
+ }
+ HeapSort(&realIndices.Front(), realIndices.Size());
+}
+
+STDMETHODIMP CAgentFolder::Extract(const UINT32 *indices,
+ UINT32 numItems,
+ NExtract::NPathMode::EEnum pathMode,
+ NExtract::NOverwriteMode::EEnum overwriteMode,
+ const wchar_t *path,
+ INT32 testMode,
+ IFolderArchiveExtractCallback *extractCallback2)
+{
+ COM_TRY_BEGIN
+ CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
+ CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
+ UStringVector pathParts;
+ CProxyFolder *currentProxyFolder = _proxyFolderItem;
+ while (currentProxyFolder->Parent)
+ {
+ pathParts.Insert(0, currentProxyFolder->Name);
+ currentProxyFolder = currentProxyFolder->Parent;
+ }
+
+ /*
+ if (_flatMode)
+ pathMode = NExtract::NPathMode::kNoPathnames;
+ */
+
+ extractCallbackSpec->Init(_agentSpec->GetArchive(),
+ extractCallback2,
+ false,
+ path,
+ pathMode,
+ overwriteMode,
+ pathParts,
+ _agentSpec->DefaultName,
+ _agentSpec->DefaultTime,
+ _agentSpec->DefaultAttributes
+ // ,_agentSpec->_srcDirectoryPrefix
+ );
+ CUIntVector realIndices;
+ GetRealIndices(indices, numItems, realIndices);
+ return _agentSpec->GetArchive()->Extract(&realIndices.Front(),
+ realIndices.Size(), testMode, extractCallback);
+ COM_TRY_END
+}
+
+/////////////////////////////////////////
+// CAgent
+
+CAgent::CAgent():
+ _proxyArchive(NULL)
+{
+}
+
+CAgent::~CAgent()
+{
+ if (_proxyArchive != NULL)
+ delete _proxyArchive;
+}
+
+STDMETHODIMP CAgent::Open(
+ const wchar_t *filePath,
+ BSTR *archiveType,
+ // CLSID *clsIDResult,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ COM_TRY_BEGIN
+ _archiveFilePath = filePath;
+ NFile::NFind::CFileInfoW fileInfo;
+ if (!NFile::NFind::FindFile(_archiveFilePath, fileInfo))
+ return ::GetLastError();
+ if (fileInfo.IsDirectory())
+ return E_FAIL;
+ CArchiverInfo archiverInfo0, archiverInfo1;
+ HRESULT res = OpenArchive(_archiveFilePath, _archiveLink, openArchiveCallback);
+ // _archive = _archiveLink.GetArchive();
+ DefaultName = _archiveLink.GetDefaultItemName();
+ const CArchiverInfo &ai = _archiveLink.GetArchiverInfo();
+
+ RINOK(res);
+ DefaultTime = fileInfo.LastWriteTime;
+ DefaultAttributes = fileInfo.Attributes;
+ ArchiveType = ai.Name;
+ if (archiveType != 0)
+ {
+ CMyComBSTR name = ArchiveType;
+ *archiveType = name.Detach();
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgent::ReOpen(
+ // const wchar_t *filePath,
+ IArchiveOpenCallback * /* openArchiveCallback */)
+{
+ COM_TRY_BEGIN
+ if (_proxyArchive != NULL)
+ {
+ delete _proxyArchive;
+ _proxyArchive = NULL;
+ }
+ RINOK(ReOpenArchive(_archiveLink, _archiveFilePath));
+ return ReadItems();
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgent::Close()
+{
+ COM_TRY_BEGIN
+ RINOK(_archiveLink.Close());
+ if (_archiveLink.GetNumLevels() > 1)
+ {
+ // return S_OK;
+ }
+ // _archive->Close();
+ return S_OK;
+ COM_TRY_END
+}
+
+/*
+STDMETHODIMP CAgent::EnumProperties(IEnumSTATPROPSTG **EnumProperties)
+{
+ return _archive->EnumProperties(EnumProperties);
+}
+*/
+
+HRESULT CAgent::ReadItems()
+{
+ if (_proxyArchive != NULL)
+ return S_OK;
+ _proxyArchive = new CProxyArchive();
+ return _proxyArchive->Load(GetArchive(),
+ DefaultName,
+ // _defaultTime,
+ // _defaultAttributes,
+ NULL);
+}
+
+STDMETHODIMP CAgent::BindToRootFolder(IFolderFolder **resultFolder)
+{
+ COM_TRY_BEGIN
+ RINOK(ReadItems());
+ CAgentFolder *folderSpec = new CAgentFolder;
+ CMyComPtr<IFolderFolder> rootFolder = folderSpec;
+ folderSpec->Init(_proxyArchive, &_proxyArchive->RootFolder, NULL, this);
+ *resultFolder = rootFolder.Detach();
+ return S_OK;
+ COM_TRY_END
+}
+
+
+STDMETHODIMP CAgent::Extract(
+ NExtract::NPathMode::EEnum pathMode,
+ NExtract::NOverwriteMode::EEnum overwriteMode,
+ const wchar_t *path,
+ INT32 testMode,
+ IFolderArchiveExtractCallback *extractCallback2)
+{
+ COM_TRY_BEGIN
+ CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
+ CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
+ extractCallbackSpec->Init(GetArchive(),
+ extractCallback2,
+ false,
+ path,
+ pathMode,
+ overwriteMode,
+ UStringVector(),
+ DefaultName,
+ DefaultTime,
+ DefaultAttributes
+ // ,_srcDirectoryPrefix
+ );
+ return GetArchive()->Extract(0, (UInt32)(Int32)-1, testMode, extractCallback);
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgent::GetNumberOfProperties(UINT32 *numProperties)
+{
+ COM_TRY_BEGIN
+ return GetArchive()->GetNumberOfProperties(numProperties);
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgent::GetPropertyInfo(UINT32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType)
+{
+ COM_TRY_BEGIN
+ RINOK(GetArchive()->GetPropertyInfo(index, name, propID, varType));
+ if (*propID == kpidPath)
+ *propID = kpidName;
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgent::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ return GetArchive()->GetArchiveProperty(propID, value);
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgent::GetNumberOfArchiveProperties(UINT32 *numProperties)
+{
+ COM_TRY_BEGIN
+ return GetArchive()->GetNumberOfArchiveProperties(numProperties);
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgent::GetArchivePropertyInfo(UINT32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType)
+{
+ COM_TRY_BEGIN
+ return GetArchive()->GetArchivePropertyInfo(index,
+ name, propID, varType);
+ COM_TRY_END
+}
+
diff --git a/CPP/7zip/UI/Agent/Agent.h b/CPP/7zip/UI/Agent/Agent.h
new file mode 100755
index 00000000..41f80266
--- /dev/null
+++ b/CPP/7zip/UI/Agent/Agent.h
@@ -0,0 +1,314 @@
+// Agent/Agent.h
+
+#ifndef __AGENT_AGENT_H
+#define __AGENT_AGENT_H
+
+#include "Common/MyCom.h"
+#include "Windows/PropVariant.h"
+
+#include "../Common/UpdateAction.h"
+#include "../Common/ArchiverInfo.h"
+#include "../Common/OpenArchive.h"
+
+#include "IFolderArchive.h"
+#include "AgentProxy.h"
+
+#ifndef EXCLUDE_COM
+#include "Windows/DLL.h"
+#endif
+#ifdef NEW_FOLDER_INTERFACE
+#include "../../FileManager/IFolder.h"
+#endif
+
+class CAgentFolder;
+
+// {23170F69-40C1-278A-0000-000100050001}
+DEFINE_GUID(IID_IArchiveFolderInternal,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000100050001")
+IArchiveFolderInternal: public IUnknown
+{
+public:
+ STDMETHOD(GetAgentFolder)(CAgentFolder **agentFolder) PURE;
+};
+
+struct CProxyItem
+{
+ CProxyFolder *Folder;
+ UInt32 Index;
+};
+
+class CAgent;
+
+class CAgentFolder:
+ public IFolderFolder,
+ public IArchiveFolder,
+ public IArchiveFolderInternal,
+#ifdef NEW_FOLDER_INTERFACE
+ public IEnumProperties,
+ public IFolderGetTypeID,
+ public IFolderGetPath,
+ public IFolderOperations,
+ public IFolderSetFlatMode,
+#endif
+ public CMyUnknownImp
+{
+public:
+
+ MY_QUERYINTERFACE_BEGIN
+ MY_QUERYINTERFACE_ENTRY(IFolderFolder)
+ MY_QUERYINTERFACE_ENTRY(IArchiveFolder)
+ MY_QUERYINTERFACE_ENTRY(IArchiveFolderInternal)
+ #ifdef NEW_FOLDER_INTERFACE
+ MY_QUERYINTERFACE_ENTRY(IEnumProperties)
+ MY_QUERYINTERFACE_ENTRY(IFolderGetTypeID)
+ MY_QUERYINTERFACE_ENTRY(IFolderGetPath)
+ MY_QUERYINTERFACE_ENTRY(IFolderOperations)
+ MY_QUERYINTERFACE_ENTRY(IFolderSetFlatMode)
+ #endif
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
+
+ // IFolderFolder
+
+ void LoadFolder(CProxyFolder *folder);
+ HRESULT BindToFolder(CProxyFolder *folder, IFolderFolder **resultFolder);
+ void GetRealIndices(const UINT32 *indices, UINT32 numItems, CUIntVector &realIndices) const;
+
+ STDMETHOD(LoadItems)();
+ STDMETHOD(GetNumberOfItems)(UINT32 *numItems);
+ STDMETHOD(GetProperty)(UINT32 itemIndex, PROPID propID, PROPVARIANT *value);
+ STDMETHOD(BindToFolder)(UINT32 index, IFolderFolder **resultFolder);
+ STDMETHOD(BindToFolder)(const wchar_t *name, IFolderFolder **resultFolder);
+ STDMETHOD(BindToParentFolder)(IFolderFolder **resultFolder);
+ STDMETHOD(GetName)(BSTR *name);
+
+ // IArchiveFolder
+ STDMETHOD(Extract)(const UINT32 *indices, UINT32 numItems,
+ NExtract::NPathMode::EEnum pathMode,
+ NExtract::NOverwriteMode::EEnum overwriteMode,
+ const wchar_t *path,
+ INT32 testMode,
+ IFolderArchiveExtractCallback *extractCallback);
+
+ STDMETHOD(GetAgentFolder)(CAgentFolder **agentFolder);
+
+ #ifdef NEW_FOLDER_INTERFACE
+ STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties);
+ STDMETHOD(GetPropertyInfo)(UINT32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType);
+ STDMETHOD(GetTypeID)(BSTR *name);
+ STDMETHOD(GetPath)(BSTR *path);
+
+
+ // IFolderOperations
+ STDMETHOD(CreateFolder)(const wchar_t *name, IProgress *progress);
+ STDMETHOD(CreateFile)(const wchar_t *name, IProgress *progress);
+ STDMETHOD(Rename)(UINT32 index, const wchar_t *newName, IProgress *progress);
+ STDMETHOD(Delete)(const UINT32 *indices, UINT32 numItems, IProgress *progress);
+ STDMETHOD(CopyTo)(const UINT32 *indices, UINT32 numItems,
+ const wchar_t *path, IFolderOperationsExtractCallback *callback);
+ STDMETHOD(MoveTo)(const UINT32 *indices, UINT32 numItems,
+ const wchar_t *path, IFolderOperationsExtractCallback *callback);
+ STDMETHOD(CopyFrom)(const wchar_t *fromFolderPath,
+ const wchar_t **itemsPaths, UINT32 numItems, IProgress *progress);
+ STDMETHOD(SetProperty)(UINT32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress);
+
+ STDMETHOD(SetFlatMode)(Int32 flatMode);
+ #endif
+
+ CAgentFolder(): _proxyFolderItem(NULL), _flatMode(0) {}
+
+ void Init(CProxyArchive *proxyHandler,
+ CProxyFolder *proxyFolderItem,
+ IFolderFolder *parentFolder,
+ CAgent *agent)
+ {
+ _proxyArchive = proxyHandler;
+ _proxyFolderItem = proxyFolderItem;
+ _parentFolder = parentFolder;
+ _agent = (IInFolderArchive *)agent;
+ _agentSpec = agent;
+ }
+
+ void GetPathParts(UStringVector &pathParts);
+ HRESULT CommonUpdateOperation(
+ bool deleteOperation,
+ bool createFolderOperation,
+ bool renameOperation,
+ const wchar_t *newItemName,
+ const NUpdateArchive::CActionSet *actionSet,
+ const UINT32 *indices, UINT32 numItems,
+ IFolderArchiveUpdateCallback *updateCallback100);
+
+
+ UString GetPrefix(UInt32 index) const;
+ UString GetName(UInt32 index) const;
+ UString GetFullPathPrefixPlusPrefix(UInt32 index) const;
+ void GetPrefixIfAny(UInt32 index, NWindows::NCOM::CPropVariant &propVariant) const;
+
+public:
+ CProxyArchive *_proxyArchive;
+ CProxyFolder *_proxyFolderItem;
+ CMyComPtr<IFolderFolder> _parentFolder;
+ CMyComPtr<IInFolderArchive> _agent;
+ CAgent *_agentSpec;
+
+ CRecordVector<CProxyItem> _items;
+ bool _flatMode;
+private:
+};
+
+// {23170F69-40C1-278A-1000-000100030000}
+DEFINE_GUID(CLSID_CAgentArchiveHandler,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00);
+
+class CAgent:
+ public IInFolderArchive,
+ #ifndef EXTRACT_ONLY
+ public IOutFolderArchive,
+ public ISetProperties,
+ #endif
+ public CMyUnknownImp
+{
+public:
+
+ MY_QUERYINTERFACE_BEGIN
+ MY_QUERYINTERFACE_ENTRY(IInFolderArchive)
+ #ifndef EXTRACT_ONLY
+ MY_QUERYINTERFACE_ENTRY(IOutFolderArchive)
+ MY_QUERYINTERFACE_ENTRY(ISetProperties)
+ #endif
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
+
+ STDMETHOD(Open)(
+ const wchar_t *filePath,
+ // CLSID *clsIDResult,
+ BSTR *archiveType,
+ IArchiveOpenCallback *openArchiveCallback);
+
+ STDMETHOD(ReOpen)(
+ // const wchar_t *filePath,
+ IArchiveOpenCallback *openArchiveCallback);
+ /*
+ STDMETHOD(ReOpen)(IInStream *stream,
+ const wchar_t *defaultName,
+ const FILETIME *defaultTime,
+ UINT32 defaultAttributes,
+ const UINT64 *maxCheckStartPosition,
+ IArchiveOpenCallback *openArchiveCallback);
+ */
+ STDMETHOD(Close)();
+ 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);
+ STDMETHOD(BindToRootFolder)(IFolderFolder **resultFolder);
+ STDMETHOD(Extract)(
+ NExtract::NPathMode::EEnum pathMode,
+ NExtract::NOverwriteMode::EEnum overwriteMode,
+ const wchar_t *path,
+ INT32 testMode,
+ IFolderArchiveExtractCallback *extractCallback2);
+
+ #ifndef EXTRACT_ONLY
+ STDMETHOD(SetFolder)(IFolderFolder *folder);
+ STDMETHOD(SetFiles)(const wchar_t *folderPrefix, const wchar_t **names, UINT32 numNames);
+ STDMETHOD(DeleteItems)(const wchar_t *newArchiveName, const UINT32 *indices,
+ UINT32 numItems, IFolderArchiveUpdateCallback *updateCallback);
+ STDMETHOD(DoOperation)(
+ const wchar_t *filePath,
+ const CLSID *clsID,
+ const wchar_t *newArchiveName,
+ const Byte *stateActions,
+ const wchar_t *sfxModule,
+ IFolderArchiveUpdateCallback *updateCallback);
+
+ HRESULT CommonUpdate(
+ const wchar_t *newArchiveName,
+ int numUpdateItems,
+ IArchiveUpdateCallback *updateCallback);
+
+ HRESULT CreateFolder(
+ const wchar_t *newArchiveName,
+ const wchar_t *folderName,
+ IFolderArchiveUpdateCallback *updateCallback100);
+
+ HRESULT RenameItem(
+ const wchar_t *newArchiveName,
+ const UINT32 *indices, UINT32 numItems,
+ const wchar_t *newItemName,
+ IFolderArchiveUpdateCallback *updateCallback100);
+
+ // ISetProperties
+ STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, INT32 numProperties);
+ #endif
+
+ CAgent();
+ ~CAgent();
+private:
+ HRESULT ReadItems();
+public:
+ CProxyArchive *_proxyArchive;
+
+ CArchiveLink _archiveLink;
+ // IInArchive *_archive2;
+
+ // CLSID _CLSID;
+ // CMyComPtr<IArchiveFolder> m_RootFolder;
+
+ UString DefaultName;
+
+ FILETIME DefaultTime;
+ UINT32 DefaultAttributes;
+
+ UString ArchiveType;
+
+ UStringVector _names;
+ UString _folderPrefix;
+
+ UString _archiveNamePrefix;
+ CAgentFolder *_agentFolder;
+
+ UString _archiveFilePath;
+
+ #ifndef EXTRACT_ONLY
+ CObjectVector<UString> m_PropNames;
+ CObjectVector<NWindows::NCOM::CPropVariant> m_PropValues;
+ #endif
+
+ IInArchive *GetArchive() { return _archiveLink.GetArchive(); }
+ bool CanUpdate() const { return _archiveLink.GetNumLevels() <= 1; }
+};
+
+#ifdef NEW_FOLDER_INTERFACE
+class CArchiveFolderManager:
+ public IFolderManager,
+ public IFolderManagerGetIconPath,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP2(
+ IFolderManager,
+ IFolderManagerGetIconPath
+ )
+ // IFolderManager
+ STDMETHOD(OpenFolderFile)(const wchar_t *filePath, IFolderFolder **resultFolder, IProgress *progress);
+ STDMETHOD(GetTypes)(BSTR *types);
+ STDMETHOD(GetExtension)(const wchar_t *type, BSTR *extension);
+ STDMETHOD(CreateFolderFile)(const wchar_t *type, const wchar_t *filePath, IProgress *progress);
+ STDMETHOD(GetIconPath)(const wchar_t *type, BSTR *iconPath);
+ CArchiveFolderManager(): _formatsLoaded(false) {}
+private:
+ void LoadFormats();
+ int FindFormat(const UString &type);
+ bool _formatsLoaded;
+ CObjectVector<CArchiverInfo> _formats;
+};
+#endif
+
+#endif
diff --git a/CPP/7zip/UI/Agent/AgentOut.cpp b/CPP/7zip/UI/Agent/AgentOut.cpp
new file mode 100755
index 00000000..25d65bb2
--- /dev/null
+++ b/CPP/7zip/UI/Agent/AgentOut.cpp
@@ -0,0 +1,518 @@
+// AgentOut.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StringConvert.h"
+#include "Common/IntToString.h"
+
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+#include "Windows/PropVariantConversions.h"
+#include "Windows/FileDir.h"
+
+#include "../../Compress/Copy/CopyCoder.h"
+#include "../../Common/FileStreams.h"
+
+#include "../Common/UpdatePair.h"
+#include "../Common/EnumDirItems.h"
+#include "../Common/HandlerLoader.h"
+#include "../Common/UpdateCallback.h"
+#include "../Common/OpenArchive.h"
+
+#include "Agent.h"
+#include "UpdateCallbackAgent.h"
+
+using namespace NWindows;
+using namespace NCOM;
+
+static HRESULT CopyBlock(ISequentialInStream *inStream, ISequentialOutStream *outStream)
+{
+ CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
+ return copyCoder->Code(inStream, outStream, NULL, NULL, NULL);
+}
+
+STDMETHODIMP CAgent::SetFolder(IFolderFolder *folder)
+{
+ _archiveNamePrefix.Empty();
+ if (folder == NULL)
+ {
+ _agentFolder = NULL;
+ return S_OK;
+ }
+ else
+ {
+ CMyComPtr<IFolderFolder> archiveFolder = folder;
+ CMyComPtr<IArchiveFolderInternal> archiveFolderInternal;
+ RINOK(archiveFolder.QueryInterface(IID_IArchiveFolderInternal, &archiveFolderInternal));
+ RINOK(archiveFolderInternal->GetAgentFolder(&_agentFolder));
+ }
+
+ UStringVector pathParts;
+ pathParts.Clear();
+ CMyComPtr<IFolderFolder> folderItem = folder;
+ if (folderItem != NULL)
+ for (;;)
+ {
+ CMyComPtr<IFolderFolder> newFolder;
+ folderItem->BindToParentFolder(&newFolder);
+ if (newFolder == NULL)
+ break;
+ CMyComBSTR name;
+ folderItem->GetName(&name);
+ pathParts.Insert(0, (const wchar_t *)name);
+ folderItem = newFolder;
+ }
+
+ for(int i = 0; i < pathParts.Size(); i++)
+ {
+ _archiveNamePrefix += pathParts[i];
+ _archiveNamePrefix += L'\\';
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CAgent::SetFiles(const wchar_t *folderPrefix,
+ const wchar_t **names, UINT32 numNames)
+{
+ _folderPrefix = folderPrefix;
+ _names.Clear();
+ _names.Reserve(numNames);
+ for (UINT32 i = 0; i < numNames; i++)
+ _names.Add(names[i]);
+ return S_OK;
+}
+
+
+static HRESULT GetFileTime(CAgent *agent, UINT32 itemIndex, FILETIME &fileTime)
+{
+ CPropVariant property;
+ RINOK(agent->GetArchive()->GetProperty(itemIndex, kpidLastWriteTime, &property));
+ if (property.vt == VT_FILETIME)
+ fileTime = property.filetime;
+ else if (property.vt == VT_EMPTY)
+ fileTime = agent->DefaultTime;
+ else
+ throw 4190407;
+ return S_OK;
+}
+
+static HRESULT EnumerateArchiveItems(CAgent *agent,
+ const CProxyFolder &item,
+ const UString &prefix,
+ CObjectVector<CArchiveItem> &archiveItems)
+{
+ int i;
+ for(i = 0; i < item.Files.Size(); i++)
+ {
+ const CProxyFile &fileItem = item.Files[i];
+ CArchiveItem archiveItem;
+
+ RINOK(::GetFileTime(agent, fileItem.Index, archiveItem.LastWriteTime));
+
+ CPropVariant property;
+ agent->GetArchive()->GetProperty(fileItem.Index, kpidSize, &property);
+ archiveItem.SizeIsDefined = (property.vt != VT_EMPTY);
+ if (archiveItem.SizeIsDefined)
+ archiveItem.Size = ConvertPropVariantToUInt64(property);
+ archiveItem.IsDirectory = false;
+ archiveItem.Name = prefix + fileItem.Name;
+ archiveItem.Censored = true; // test it
+ archiveItem.IndexInServer = fileItem.Index;
+ archiveItems.Add(archiveItem);
+ }
+ for(i = 0; i < item.Folders.Size(); i++)
+ {
+ const CProxyFolder &dirItem = item.Folders[i];
+ UString fullName = prefix + dirItem.Name;
+ if(dirItem.IsLeaf)
+ {
+ CArchiveItem archiveItem;
+ RINOK(::GetFileTime(agent, dirItem.Index, archiveItem.LastWriteTime));
+ archiveItem.IsDirectory = true;
+ archiveItem.SizeIsDefined = false;
+ archiveItem.Name = fullName;
+ archiveItem.Censored = true; // test it
+ archiveItem.IndexInServer = dirItem.Index;
+ archiveItems.Add(archiveItem);
+ }
+ RINOK(EnumerateArchiveItems(agent, dirItem, fullName + UString(L'\\'), archiveItems));
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CAgent::DoOperation(
+ const wchar_t *filePath,
+ const CLSID *clsID,
+ const wchar_t *newArchiveName,
+ const Byte *stateActions,
+ const wchar_t *sfxModule,
+ IFolderArchiveUpdateCallback *updateCallback100)
+{
+ if (!CanUpdate())
+ return E_NOTIMPL;
+ NUpdateArchive::CActionSet actionSet;
+ int i;
+ for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
+ actionSet.StateActions[i] = (NUpdateArchive::NPairAction::EEnum)stateActions[i];
+
+ CObjectVector<CDirItem> dirItems;
+
+ UString folderPrefix = _folderPrefix;
+ NFile::NName::NormalizeDirPathPrefix(folderPrefix);
+ UStringVector errorPaths;
+ CRecordVector<DWORD> errorCodes;
+ ::EnumerateDirItems(folderPrefix, _names, _archiveNamePrefix, dirItems, errorPaths, errorCodes);
+ if (errorCodes.Size() > 0)
+ {
+ return errorCodes.Front();
+ }
+
+ NWindows::NDLL::CLibrary library;
+
+ CMyComPtr<IOutArchive> outArchive;
+ if (GetArchive())
+ {
+ RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive));
+ }
+ else
+ {
+ CHandlerLoader loader;
+ RINOK(loader.CreateHandler(filePath, *clsID, (void **)&outArchive, true));
+ library.Attach(loader.Detach());
+ }
+
+ NFileTimeType::EEnum fileTimeType;
+ UINT32 value;
+ RINOK(outArchive->GetFileTimeType(&value));
+
+ switch(value)
+ {
+ case NFileTimeType::kWindows:
+ case NFileTimeType::kDOS:
+ case NFileTimeType::kUnix:
+ fileTimeType = NFileTimeType::EEnum(value);
+ break;
+ default:
+ return E_FAIL;
+ }
+
+ CObjectVector<CUpdatePair> updatePairs;
+
+ CObjectVector<CArchiveItem> archiveItems;
+ if (GetArchive())
+ {
+ RINOK(ReadItems());
+ EnumerateArchiveItems(this, _proxyArchive->RootFolder, L"", archiveItems);
+ }
+
+ GetUpdatePairInfoList(dirItems, archiveItems, fileTimeType, updatePairs);
+
+ CObjectVector<CUpdatePair2> updatePairs2;
+ UpdateProduce(updatePairs, actionSet, updatePairs2);
+
+ CUpdateCallbackAgent updateCallbackAgent;
+ updateCallbackAgent.Callback = updateCallback100;
+ CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
+ CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec );
+
+ updateCallbackSpec->DirPrefix = folderPrefix;
+ updateCallbackSpec->DirItems = &dirItems;
+ updateCallbackSpec->ArchiveItems = &archiveItems;
+ updateCallbackSpec->UpdatePairs = &updatePairs2;
+ updateCallbackSpec->Archive = GetArchive();
+ updateCallbackSpec->Callback = &updateCallbackAgent;
+
+ COutFileStream *outStreamSpec = new COutFileStream;
+ CMyComPtr<IOutStream> outStream(outStreamSpec);
+ UString archiveName = newArchiveName;
+ {
+ UString resultPath;
+ int pos;
+ if(!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos))
+ throw 141716;
+ NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos));
+ }
+ if (!outStreamSpec->Create(archiveName, true))
+ {
+ // ShowLastErrorMessage();
+ return E_FAIL;
+ }
+
+ CMyComPtr<ISetProperties> setProperties;
+ if (outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties) == S_OK)
+ {
+ if (m_PropNames.Size() == 0)
+ {
+ RINOK(setProperties->SetProperties(0, 0, 0));
+ }
+ else
+ {
+ CRecordVector<const wchar_t *> names;
+ for(i = 0; i < m_PropNames.Size(); i++)
+ names.Add((const wchar_t *)m_PropNames[i]);
+
+ NWindows::NCOM::CPropVariant *propValues = new NWindows::NCOM::CPropVariant[m_PropValues.Size()];
+ try
+ {
+ for (int i = 0; i < m_PropValues.Size(); i++)
+ propValues[i] = m_PropValues[i];
+ RINOK(setProperties->SetProperties(&names.Front(), propValues, names.Size()));
+ }
+ catch(...)
+ {
+ delete []propValues;
+ throw;
+ }
+ delete []propValues;
+ }
+ }
+ m_PropNames.Clear();
+ m_PropValues.Clear();
+
+ if (sfxModule != NULL)
+ {
+ CInFileStream *sfxStreamSpec = new CInFileStream;
+ CMyComPtr<IInStream> sfxStream(sfxStreamSpec);
+ if (!sfxStreamSpec->Open(sfxModule))
+ throw "Can't open sfx module";
+ RINOK(CopyBlock(sfxStream, outStream));
+ }
+
+ return outArchive->UpdateItems(outStream, updatePairs2.Size(),updateCallback);
+}
+
+
+HRESULT CAgent::CommonUpdate(
+ const wchar_t *newArchiveName,
+ int numUpdateItems,
+ IArchiveUpdateCallback *updateCallback)
+{
+ if (!CanUpdate())
+ return E_NOTIMPL;
+ CMyComPtr<IOutArchive> outArchive;
+ RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive));
+
+ COutFileStream *outStreamSpec = new COutFileStream;
+ CMyComPtr<IOutStream> outStream(outStreamSpec);
+
+ UString archiveName = newArchiveName;
+ {
+ UString resultPath;
+ int pos;
+ if(!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos))
+ throw 141716;
+ NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos));
+ }
+
+ /*
+ bool isOK = false;
+ for (int i = 0; i < (1 << 16); i++)
+ {
+ resultName = newArchiveName;
+ if (i > 0)
+ {
+ wchar_t s[32];
+ ConvertUInt64ToString(i, s);
+ resultName += s;
+ }
+ if (outStreamSpec->Open(realPath))
+ {
+ isOK = true;
+ break;
+ }
+ if (::GetLastError() != ERROR_FILE_EXISTS)
+ return ::GetLastError();
+ }
+ if (!isOK)
+ return ::GetLastError();
+ */
+ if (!outStreamSpec->Create(archiveName, true))
+ {
+ // ShowLastErrorMessage();
+ return E_FAIL;
+ }
+
+ return outArchive->UpdateItems(outStream, numUpdateItems, updateCallback);
+}
+
+
+STDMETHODIMP CAgent::DeleteItems(
+ const wchar_t *newArchiveName,
+ const UINT32 *indices, UINT32 numItems,
+ IFolderArchiveUpdateCallback *updateCallback100)
+{
+ if (!CanUpdate())
+ return E_NOTIMPL;
+ CUpdateCallbackAgent updateCallbackAgent;
+ updateCallbackAgent.Callback = updateCallback100;
+ CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
+ CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
+
+ CUIntVector realIndices;
+ _agentFolder->GetRealIndices(indices, numItems, realIndices);
+ CObjectVector<CUpdatePair2> updatePairs;
+ int curIndex = 0;
+ UInt32 numItemsInArchive;
+ RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive));
+ for (UInt32 i = 0; i < numItemsInArchive; i++)
+ {
+ if (curIndex < realIndices.Size())
+ if (realIndices[curIndex] == i)
+ {
+ curIndex++;
+ continue;
+ }
+ CUpdatePair2 updatePair;
+ updatePair.NewData = updatePair.NewProperties = false;
+ updatePair.ExistInArchive = true;
+ updatePair.ExistOnDisk = false;
+ updatePair.IsAnti = false; // check it. Maybe it can be undefined
+ updatePair.ArchiveItemIndex = i;
+ updatePairs.Add(updatePair);
+ }
+ updateCallbackSpec->UpdatePairs = &updatePairs;
+ updateCallbackSpec->Archive = GetArchive();
+ updateCallbackSpec->Callback = &updateCallbackAgent;
+ return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback);
+}
+
+HRESULT CAgent::CreateFolder(
+ const wchar_t *newArchiveName,
+ const wchar_t *folderName,
+ IFolderArchiveUpdateCallback *updateCallback100)
+{
+ if (!CanUpdate())
+ return E_NOTIMPL;
+ CUpdateCallbackAgent updateCallbackAgent;
+ updateCallbackAgent.Callback = updateCallback100;
+ CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
+ CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
+
+ CObjectVector<CUpdatePair2> updatePairs;
+ UINT32 numItemsInArchive;
+ RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive));
+ for (UInt32 i = 0; i < numItemsInArchive; i++)
+ {
+ CUpdatePair2 updatePair;
+ updatePair.NewData = updatePair.NewProperties = false;
+ updatePair.ExistInArchive = true;
+ updatePair.ExistOnDisk = false;
+ updatePair.IsAnti = false; // check it.
+ updatePair.ArchiveItemIndex = i;
+ updatePairs.Add(updatePair);
+ }
+ CUpdatePair2 updatePair;
+ updatePair.NewData = updatePair.NewProperties = true;
+ updatePair.ExistInArchive = false;
+ updatePair.ExistOnDisk = true;
+ updatePair.IsAnti = false;
+ updatePair.ArchiveItemIndex = -1;
+ updatePair.DirItemIndex = 0;
+
+ updatePairs.Add(updatePair);
+
+ CObjectVector<CDirItem> dirItems;
+ CDirItem dirItem;
+
+ dirItem.Attributes = FILE_ATTRIBUTE_DIRECTORY;
+ dirItem.Size = 0;
+ dirItem.Name = _agentFolder->_proxyFolderItem->GetFullPathPrefix() + folderName;
+
+ SYSTEMTIME systemTime;
+ FILETIME fileTime;
+ ::GetSystemTime(&systemTime);
+ ::SystemTimeToFileTime(&systemTime, &fileTime);
+ dirItem.LastAccessTime = dirItem.LastWriteTime =
+ dirItem.CreationTime = fileTime;
+
+ dirItems.Add(dirItem);
+
+ updateCallbackSpec->Callback = &updateCallbackAgent;
+ updateCallbackSpec->DirItems = &dirItems;
+ updateCallbackSpec->UpdatePairs = &updatePairs;
+ updateCallbackSpec->Archive = GetArchive();
+ return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback);
+}
+
+
+HRESULT CAgent::RenameItem(
+ const wchar_t *newArchiveName,
+ const UINT32 *indices, UINT32 numItems,
+ const wchar_t *newItemName,
+ IFolderArchiveUpdateCallback *updateCallback100)
+{
+ if (!CanUpdate())
+ return E_NOTIMPL;
+ if (numItems != 1)
+ return E_INVALIDARG;
+ CUpdateCallbackAgent updateCallbackAgent;
+ updateCallbackAgent.Callback = updateCallback100;
+ CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
+ CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
+
+ CUIntVector realIndices;
+ _agentFolder->GetRealIndices(indices, numItems, realIndices);
+
+ UString fullPrefix = _agentFolder->GetFullPathPrefixPlusPrefix(indices[0]);
+ UString oldItemPath = fullPrefix + _agentFolder->GetName(indices[0]);
+ UString newItemPath = fullPrefix + newItemName;
+
+ CObjectVector<CUpdatePair2> updatePairs;
+ int curIndex = 0;
+ UINT32 numItemsInArchive;
+ RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive));
+ for (UInt32 i = 0; i < numItemsInArchive; i++)
+ {
+ if (curIndex < realIndices.Size())
+ if (realIndices[curIndex] == i)
+ {
+ CUpdatePair2 updatePair;
+ updatePair.NewData = false;
+ updatePair.NewProperties = true;
+ updatePair.ExistInArchive = true;
+ updatePair.ExistOnDisk = false;
+ RINOK(IsArchiveItemAnti(GetArchive(), i, updatePair.IsAnti));
+ updatePair.ArchiveItemIndex = i;
+ updatePair.NewNameIsDefined = true;
+
+ updatePair.NewName = newItemName;
+
+ UString oldFullPath;
+ RINOK(GetArchiveItemPath(GetArchive(), i, DefaultName, oldFullPath));
+
+ if (oldItemPath.CompareNoCase(oldFullPath.Left(oldItemPath.Length())) != 0)
+ return E_INVALIDARG;
+
+ updatePair.NewName = newItemPath + oldFullPath.Mid(oldItemPath.Length());
+ updatePairs.Add(updatePair);
+ curIndex++;
+ continue;
+ }
+ CUpdatePair2 updatePair;
+ updatePair.NewData = updatePair.NewProperties = false;
+ updatePair.ExistInArchive = true;
+ updatePair.ExistOnDisk = false;
+ updatePair.IsAnti = false;
+ updatePair.ArchiveItemIndex = i;
+ updatePairs.Add(updatePair);
+ }
+ updateCallbackSpec->Callback = &updateCallbackAgent;
+ updateCallbackSpec->UpdatePairs = &updatePairs;
+ updateCallbackSpec->Archive = GetArchive();
+ return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback);
+}
+
+STDMETHODIMP CAgent::SetProperties(const wchar_t **names,
+ const PROPVARIANT *values, INT32 numProperties)
+{
+ m_PropNames.Clear();
+ m_PropValues.Clear();
+ for (int i = 0; i < numProperties; i++)
+ {
+ m_PropNames.Add(names[i]);
+ m_PropValues.Add(values[i]);
+ }
+ return S_OK;
+}
+
+
diff --git a/CPP/7zip/UI/Agent/AgentProxy.cpp b/CPP/7zip/UI/Agent/AgentProxy.cpp
new file mode 100755
index 00000000..42063e67
--- /dev/null
+++ b/CPP/7zip/UI/Agent/AgentProxy.cpp
@@ -0,0 +1,203 @@
+// AgentProxy.cpp
+
+#include "StdAfx.h"
+
+#include "AgentProxy.h"
+
+#include "Common/MyCom.h"
+#include "Windows/PropVariant.h"
+#include "Windows/Defs.h"
+#include "../Common/OpenArchive.h"
+
+extern "C"
+{
+ #include "../../../../C/Sort.h"
+}
+
+using namespace NWindows;
+
+int CProxyFolder::FindDirSubItemIndex(const UString &name, int &insertPos) const
+{
+ int left = 0, right = Folders.Size();
+ for (;;)
+ {
+ if (left == right)
+ {
+ insertPos = left;
+ return -1;
+ }
+ int mid = (left + right) / 2;
+ int compare = name.CompareNoCase(Folders[mid].Name);
+ if (compare == 0)
+ return mid;
+ if (compare < 0)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+}
+
+int CProxyFolder::FindDirSubItemIndex(const UString &name) const
+{
+ int insertPos;
+ return FindDirSubItemIndex(name, insertPos);
+}
+
+void CProxyFolder::AddFileSubItem(UINT32 index, const UString &name)
+{
+ Files.Add(CProxyFile());
+ Files.Back().Name = name;
+ Files.Back().Index = index;
+}
+
+CProxyFolder* CProxyFolder::AddDirSubItem(UINT32 index, bool leaf,
+ const UString &name)
+{
+ int insertPos;
+ int folderIndex = FindDirSubItemIndex(name, insertPos);
+ if (folderIndex >= 0)
+ {
+ CProxyFolder *item = &Folders[folderIndex];
+ if(leaf)
+ {
+ item->Index = index;
+ item->IsLeaf = true;
+ }
+ return item;
+ }
+ Folders.Insert(insertPos, CProxyFolder());
+ CProxyFolder *item = &Folders[insertPos];
+ item->Name = name;
+ item->Index = index;
+ item->Parent = this;
+ item->IsLeaf = leaf;
+ return item;
+}
+
+void CProxyFolder::Clear()
+{
+ Folders.Clear();
+ Files.Clear();
+}
+
+UString CProxyFolder::GetFullPathPrefix() const
+{
+ UString result;
+ const CProxyFolder *current = this;
+ while (current->Parent != NULL)
+ {
+ result = current->Name + UString(L'\\') + result;
+ current = current->Parent;
+ }
+ return result;
+}
+
+UString CProxyFolder::GetItemName(UINT32 index) const
+{
+ if (index < (UINT32)Folders.Size())
+ return Folders[index].Name;
+ return Files[index - Folders.Size()].Name;
+}
+
+void CProxyFolder::AddRealIndices(CUIntVector &realIndices) const
+{
+ if (IsLeaf)
+ realIndices.Add(Index);
+ 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);
+}
+
+void CProxyFolder::GetRealIndices(const UINT32 *indices,
+ UINT32 numItems, CUIntVector &realIndices) const
+{
+ realIndices.Clear();
+ for(UINT32 i = 0; i < numItems; i++)
+ {
+ int index = indices[i];
+ int numDirItems = Folders.Size();
+ if (index < numDirItems)
+ Folders[index].AddRealIndices(realIndices);
+ else
+ realIndices.Add(Files[index - numDirItems].Index);
+ }
+ HeapSort(&realIndices.Front(), realIndices.Size());
+}
+
+///////////////////////////////////////////////
+// CProxyArchive
+
+HRESULT CProxyArchive::Reload(IInArchive *archive, IProgress *progress)
+{
+ RootFolder.Clear();
+ return ReadObjects(archive, progress);
+}
+
+HRESULT CProxyArchive::Load(IInArchive *archive,
+ const UString &defaultName,
+ // const FILETIME &defaultTime,
+ // UINT32 defaultAttributes,
+ IProgress *progress)
+{
+ DefaultName = defaultName;
+ // DefaultTime = defaultTime;
+ // DefaultAttributes = defaultAttributes;
+ return Reload(archive, progress);
+}
+
+
+HRESULT CProxyArchive::ReadObjects(IInArchive *archiveHandler, IProgress *progress)
+{
+ UINT32 numItems;
+ RINOK(archiveHandler->GetNumberOfItems(&numItems));
+ if (progress != NULL)
+ {
+ UINT64 totalItems = numItems;
+ RINOK(progress->SetTotal(totalItems));
+ }
+ for(UINT32 i = 0; i < numItems; i++)
+ {
+ if (progress != NULL)
+ {
+ UINT64 currentItemIndex = i;
+ RINOK(progress->SetCompleted(&currentItemIndex));
+ }
+ NCOM::CPropVariant propVariantPath;
+ RINOK(archiveHandler->GetProperty(i, kpidPath, &propVariantPath));
+ CProxyFolder *currentItem = &RootFolder;
+ UString fileName;
+ if(propVariantPath.vt == VT_EMPTY)
+ fileName = DefaultName;
+ else
+ {
+ if(propVariantPath.vt != VT_BSTR)
+ return E_FAIL;
+ UString filePath = propVariantPath.bstrVal;
+
+ int len = filePath.Length();
+ for (int i = 0; i < len; i++)
+ {
+ wchar_t c = filePath[i];
+ if (c == '\\' || c == '/')
+ {
+ currentItem = currentItem->AddDirSubItem((UInt32)(Int32)-1, false, fileName);
+ fileName.Empty();
+ }
+ else
+ fileName += c;
+ }
+ }
+
+ NCOM::CPropVariant propVariantIsFolder;
+ bool isFolder;
+ RINOK(IsArchiveItemFolder(archiveHandler, i, isFolder));
+ if(isFolder)
+ currentItem->AddDirSubItem(i, true, fileName);
+ else
+ currentItem->AddFileSubItem(i, fileName);
+ }
+ return S_OK;
+}
+
diff --git a/CPP/7zip/UI/Agent/AgentProxy.h b/CPP/7zip/UI/Agent/AgentProxy.h
new file mode 100755
index 00000000..9402cfdd
--- /dev/null
+++ b/CPP/7zip/UI/Agent/AgentProxy.h
@@ -0,0 +1,56 @@
+// AgentProxy.h
+
+#ifndef __AGENT_PROXY_H
+#define __AGENT_PROXY_H
+
+#include "Common/String.h"
+
+#include "../../Archive/IArchive.h"
+
+class CProxyFile
+{
+public:
+ UINT32 Index;
+ UString Name;
+};
+
+class CProxyFolder: public CProxyFile
+{
+public:
+ CProxyFolder *Parent;
+ CObjectVector<CProxyFolder> Folders;
+ CObjectVector<CProxyFile> Files;
+ bool IsLeaf;
+
+ CProxyFolder(): Parent(NULL) {};
+ int FindDirSubItemIndex(const UString &name, int &insertPos) const;
+ int FindDirSubItemIndex(const UString &name) const;
+ CProxyFolder* AddDirSubItem(UINT32 index,
+ bool leaf, const UString &name);
+ void AddFileSubItem(UINT32 index, const UString &name);
+ void Clear();
+
+ UString GetFullPathPrefix() const;
+ UString GetItemName(UINT32 index) const;
+ void AddRealIndices(CUIntVector &realIndices) const;
+ void GetRealIndices(const UINT32 *indices, UINT32 numItems,
+ CUIntVector &realIndices) const;
+};
+
+class CProxyArchive
+{
+ HRESULT ReadObjects(IInArchive *inArchive, IProgress *progress);
+public:
+ UString DefaultName;
+ // FILETIME DefaultTime;
+ // UINT32 DefaultAttributes;
+ CProxyFolder RootFolder;
+ HRESULT Reload(IInArchive *archive, IProgress *progress);
+ HRESULT Load(IInArchive *archive,
+ const UString &defaultName,
+ // const FILETIME &defaultTime,
+ // UINT32 defaultAttributes,
+ IProgress *progress);
+};
+
+#endif \ No newline at end of file
diff --git a/CPP/7zip/UI/Agent/ArchiveFolder.cpp b/CPP/7zip/UI/Agent/ArchiveFolder.cpp
new file mode 100755
index 00000000..0ce553dc
--- /dev/null
+++ b/CPP/7zip/UI/Agent/ArchiveFolder.cpp
@@ -0,0 +1,72 @@
+// Zip/ArchiveFolder.cpp
+
+#include "StdAfx.h"
+
+#include "Common/ComTry.h"
+#include "Common/StringConvert.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+#include "Windows/PropVariantConversions.h"
+#include "Windows/FileDir.h"
+
+#include "../../Common/FileStreams.h"
+
+#include "../Common/UpdatePair.h"
+#include "../Common/ArchiveExtractCallback.h"
+
+#include "Agent.h"
+
+using namespace NWindows;
+using namespace NCOM;
+
+STDMETHODIMP CAgentFolder::CopyTo(const UINT32 *indices, UINT32 numItems,
+ const wchar_t *path, IFolderOperationsExtractCallback *callback)
+{
+ COM_TRY_BEGIN
+ CArchiveExtractCallback *extractCallbackSpec = new
+ CArchiveExtractCallback;
+ CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
+ UStringVector pathParts;
+ CProxyFolder *currentProxyFolder = _proxyFolderItem;
+ while (currentProxyFolder->Parent)
+ {
+ pathParts.Insert(0, currentProxyFolder->Name);
+ currentProxyFolder = currentProxyFolder->Parent;
+ }
+
+ CMyComPtr<IFolderArchiveExtractCallback> extractCallback2;
+ {
+ CMyComPtr<IFolderOperationsExtractCallback> callbackWrap = callback;
+ RINOK(callbackWrap.QueryInterface(
+ IID_IFolderArchiveExtractCallback, &extractCallback2));
+ }
+
+ NExtract::NPathMode::EEnum pathMode = _flatMode ?
+ NExtract::NPathMode::kNoPathnames :
+ NExtract::NPathMode::kCurrentPathnames;
+
+ extractCallbackSpec->Init(_agentSpec->GetArchive(),
+ extractCallback2,
+ false,
+ path,
+ pathMode,
+ NExtract::NOverwriteMode::kAskBefore,
+ pathParts,
+ _agentSpec->DefaultName,
+ _agentSpec->DefaultTime,
+ _agentSpec->DefaultAttributes
+ // ,_agentSpec->_srcDirectoryPrefix
+ );
+ CUIntVector realIndices;
+ GetRealIndices(indices, numItems, realIndices);
+ return _agentSpec->GetArchive()->Extract(&realIndices.Front(),
+ realIndices.Size(), BoolToInt(false), extractCallback);
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgentFolder::MoveTo(const UINT32 * /* indices */, UINT32 /* numItems */,
+ const wchar_t * /* path */, IFolderOperationsExtractCallback * /* callback */)
+{
+ return E_NOTIMPL;
+}
+
diff --git a/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp b/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp
new file mode 100755
index 00000000..ce423941
--- /dev/null
+++ b/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp
@@ -0,0 +1,98 @@
+// Zip/ArchiveFolder.cpp
+
+#include "StdAfx.h"
+
+#include "Agent.h"
+
+#include "Common/StringConvert.h"
+
+#include "../Common/OpenArchive.h"
+
+static const UInt64 kMaxCheckStartPosition = 1 << 20;
+
+static inline UINT GetCurrentFileCodePage()
+ { return AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
+
+void CArchiveFolderManager::LoadFormats()
+{
+ if (!_formatsLoaded)
+ ReadArchiverInfoList(_formats);
+}
+
+int CArchiveFolderManager::FindFormat(const UString &type)
+{
+ // LoadFormats();
+ for (int i = 0; i < _formats.Size(); i++)
+ if (type.CompareNoCase(_formats[i].Name) == 0)
+ return i;
+ return -1;
+}
+
+STDMETHODIMP CArchiveFolderManager::OpenFolderFile(const wchar_t *filePath,
+ IFolderFolder **resultFolder, IProgress *progress)
+{
+ CMyComPtr<IArchiveOpenCallback> openArchiveCallback;
+ if (progress != 0)
+ {
+ CMyComPtr<IProgress> progressWrapper = progress;
+ progressWrapper.QueryInterface(IID_IArchiveOpenCallback, &openArchiveCallback);
+ }
+ CAgent *agent = new CAgent();
+ CMyComPtr<IInFolderArchive> archive = agent;
+ RINOK(agent->Open(filePath, NULL, openArchiveCallback));
+ return agent->BindToRootFolder(resultFolder);
+}
+
+/*
+HRESULT CAgent::FolderReOpen(
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ return ReOpenArchive(_archive, _archiveFilePath);
+}
+*/
+
+STDMETHODIMP CArchiveFolderManager::GetTypes(BSTR *types)
+{
+ LoadFormats();
+ 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 += ai.Name;
+ }
+ CMyComBSTR valueTemp = typesStrings;
+ *types = valueTemp.Detach();
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveFolderManager::GetExtension(const wchar_t *type, BSTR *extension)
+{
+ *extension = 0;
+ int formatIndex = FindFormat(type);
+ if (formatIndex < 0)
+ return E_INVALIDARG;
+ CMyComBSTR valueTemp = _formats[formatIndex].Extensions[0].Ext;
+ *extension = valueTemp.Detach();
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveFolderManager::GetIconPath(const wchar_t *type, BSTR *iconPath)
+{
+ *iconPath = 0;
+ int formatIndex = FindFormat(type);
+ if (formatIndex < 0)
+ return E_INVALIDARG;
+ CMyComBSTR iconPathTemp = _formats[formatIndex].FilePath;
+ *iconPath = iconPathTemp.Detach();
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveFolderManager::CreateFolderFile(const wchar_t * /* type */,
+ const wchar_t * /* filePath */, IProgress * /* progress */)
+{
+ return E_NOTIMPL;
+}
diff --git a/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp b/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp
new file mode 100755
index 00000000..4d66d86d
--- /dev/null
+++ b/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp
@@ -0,0 +1,215 @@
+// FolderOut.cpp
+
+#include "StdAfx.h"
+#include "Agent.h"
+
+#include "Common/StringConvert.h"
+#include "Common/ComTry.h"
+#include "Windows/FileDir.h"
+
+// #include "../Common/CompressEngineCommon.h"
+#include "../Common/ZipRegistry.h"
+#include "../Common/UpdateAction.h"
+#include "../Common/WorkDir.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NDirectory;
+
+static LPCWSTR kTempArcivePrefix = L"7zA";
+
+void CAgentFolder::GetPathParts(UStringVector &pathParts)
+{
+ pathParts.Clear();
+ CMyComPtr<IFolderFolder> folder = this;
+ for (;;)
+ {
+ CMyComPtr<IFolderFolder> newFolder;
+ folder->BindToParentFolder(&newFolder);
+ if (newFolder == NULL)
+ break;
+ CMyComBSTR name;
+ folder->GetName(&name);
+ pathParts.Insert(0, (const wchar_t *)name);
+ folder = newFolder;
+ }
+}
+
+HRESULT CAgentFolder::CommonUpdateOperation(
+ bool deleteOperation,
+ bool createFolderOperation,
+ bool renameOperation,
+ const wchar_t *newItemName,
+ const NUpdateArchive::CActionSet *actionSet,
+ const UINT32 *indices, UINT32 numItems,
+ IFolderArchiveUpdateCallback *updateCallback100)
+{
+ NWorkDir::CInfo workDirInfo;
+ ReadWorkDirInfo(workDirInfo);
+ UString archiveFilePath = _agentSpec->_archiveFilePath;
+ UString workDir = GetWorkDir(workDirInfo, archiveFilePath );
+ CreateComplexDirectory(workDir);
+
+ CTempFileW tempFile;
+ UString tempFileName;
+ if (tempFile.Create(workDir, kTempArcivePrefix, tempFileName) == 0)
+ return E_FAIL;
+
+ /*
+ if (SetOutProperties(anOutArchive, aCompressionInfo.Method) != S_OK)
+ return NFileOperationReturnCode::kError;
+ */
+
+ ////////////////////////////
+ // Save FolderItem;
+
+ UStringVector pathParts;
+ GetPathParts(pathParts);
+
+ HRESULT result;
+ if (deleteOperation)
+ result = _agentSpec->DeleteItems(tempFileName,
+ indices, numItems, updateCallback100);
+ else if (createFolderOperation)
+ {
+ result = _agentSpec->CreateFolder(tempFileName,
+ newItemName, updateCallback100);
+ }
+ else if (renameOperation)
+ {
+ result = _agentSpec->RenameItem(
+ tempFileName,
+ indices, numItems,
+ newItemName,
+ updateCallback100);
+ }
+ else
+ {
+ Byte actionSetByte[NUpdateArchive::NPairState::kNumValues];
+ for (int i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
+ actionSetByte[i] = (Byte)actionSet->StateActions[i];
+ result = _agentSpec->DoOperation(NULL, NULL,
+ tempFileName, actionSetByte, NULL, updateCallback100);
+ }
+
+ if (result != S_OK)
+ return result;
+
+ _agentSpec->Close();
+
+ // m_FolderItem = NULL;
+
+ if (!DeleteFileAlways(archiveFilePath ))
+ return GetLastError();
+
+ tempFile.DisableDeleting();
+ if (!MyMoveFile(tempFileName, archiveFilePath ))
+ return GetLastError();
+
+ RINOK(_agentSpec->ReOpen(NULL));
+
+ ////////////////////////////
+ // Restore FolderItem;
+
+ CMyComPtr<IFolderFolder> archiveFolder;
+ RINOK(_agentSpec->BindToRootFolder(&archiveFolder));
+ for (int i = 0; i < pathParts.Size(); i++)
+ {
+ CMyComPtr<IFolderFolder> newFolder;
+ archiveFolder->BindToFolder(pathParts[i], &newFolder);
+ if(!newFolder)
+ break;
+ archiveFolder = newFolder;
+ }
+
+ CMyComPtr<IArchiveFolderInternal> archiveFolderInternal;
+ RINOK(archiveFolder.QueryInterface(IID_IArchiveFolderInternal, &archiveFolderInternal));
+ CAgentFolder *agentFolder;
+ RINOK(archiveFolderInternal->GetAgentFolder(&agentFolder));
+ _proxyFolderItem = agentFolder->_proxyFolderItem;
+ _proxyArchive = agentFolder->_proxyArchive;
+ _parentFolder = agentFolder->_parentFolder;
+
+ return S_OK;
+}
+
+STDMETHODIMP CAgentFolder::CopyFrom(
+ const wchar_t *fromFolderPath, // test it
+ const wchar_t **itemsPaths,
+ UINT32 numItems,
+ IProgress *progress)
+{
+ COM_TRY_BEGIN
+ RINOK(_agentSpec->SetFiles(fromFolderPath, itemsPaths, numItems));
+ RINOK(_agentSpec->SetFolder(this));
+ CMyComPtr<IFolderArchiveUpdateCallback> updateCallback100;
+ if (progress != 0)
+ {
+ CMyComPtr<IProgress> progressWrapper = progress;
+ RINOK(progressWrapper.QueryInterface(
+ IID_IFolderArchiveUpdateCallback, &updateCallback100));
+ }
+ return CommonUpdateOperation(false, false, false, NULL,
+ &NUpdateArchive::kAddActionSet, 0, 0, updateCallback100);
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgentFolder::Delete(const UINT32 *indices, UINT32 numItems, IProgress *progress)
+{
+ COM_TRY_BEGIN
+ RINOK(_agentSpec->SetFolder(this));
+ CMyComPtr<IFolderArchiveUpdateCallback> updateCallback100;
+ if (progress != 0)
+ {
+ CMyComPtr<IProgress> progressWrapper = progress;
+ RINOK(progressWrapper.QueryInterface(
+ IID_IFolderArchiveUpdateCallback, &updateCallback100));
+ }
+ return CommonUpdateOperation(true, false, false, NULL,
+ &NUpdateArchive::kDeleteActionSet, indices, numItems, updateCallback100);
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgentFolder::CreateFolder(const wchar_t *name, IProgress *progress)
+{
+ COM_TRY_BEGIN
+ if (_proxyFolderItem->FindDirSubItemIndex(name) >= 0)
+ return ERROR_ALREADY_EXISTS;
+ RINOK(_agentSpec->SetFolder(this));
+ CMyComPtr<IFolderArchiveUpdateCallback> updateCallback100;
+ if (progress != 0)
+ {
+ CMyComPtr<IProgress> progressWrapper = progress;
+ RINOK(progressWrapper.QueryInterface(IID_IFolderArchiveUpdateCallback, &updateCallback100));
+ }
+ return CommonUpdateOperation(false, true, false, name, NULL, NULL, 0, updateCallback100);
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgentFolder::Rename(UINT32 index, const wchar_t *newName, IProgress *progress)
+{
+ COM_TRY_BEGIN
+ CUIntVector indices;
+ indices.Add(index);
+ RINOK(_agentSpec->SetFolder(this));
+ CMyComPtr<IFolderArchiveUpdateCallback> updateCallback100;
+ if (progress != 0)
+ {
+ CMyComPtr<IProgress> progressWrapper = progress;
+ RINOK(progressWrapper.QueryInterface(IID_IFolderArchiveUpdateCallback, &updateCallback100));
+ }
+ return CommonUpdateOperation(false, false, true, newName, NULL, &indices.Front(),
+ indices.Size(), updateCallback100);
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgentFolder::CreateFile(const wchar_t * /* name */, IProgress * /* progress */)
+{
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP CAgentFolder::SetProperty(UINT32 /* index */, PROPID /* propID */,
+ const PROPVARIANT * /* value */, IProgress * /* progress */)
+{
+ return E_NOTIMPL;
+}
diff --git a/CPP/7zip/UI/Agent/IFolderArchive.h b/CPP/7zip/UI/Agent/IFolderArchive.h
new file mode 100755
index 00000000..41d9eb22
--- /dev/null
+++ b/CPP/7zip/UI/Agent/IFolderArchive.h
@@ -0,0 +1,90 @@
+// IFolderArchive.h
+
+#ifndef __IFOLDER_ARCHIVE_H
+#define __IFOLDER_ARCHIVE_H
+
+#include "../../Archive/IArchive.h"
+// #include "../Format/Common/ArchiveInterface.h"
+#include "../../FileManager/IFolder.h"
+#include "../Common/IFileExtractCallback.h"
+#include "../Common/ExtractMode.h"
+
+// {23170F69-40C1-278A-0000-000100050000}
+DEFINE_GUID(IID_IArchiveFolder,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000100050000")
+IArchiveFolder: public IUnknown
+{
+public:
+ STDMETHOD(Extract)(const UINT32 *indices, UINT32 numItems,
+ NExtract::NPathMode::EEnum pathMode,
+ NExtract::NOverwriteMode::EEnum overwriteMode,
+ const wchar_t *path,
+ INT32 testMode,
+ IFolderArchiveExtractCallback *extractCallback2) PURE;
+};
+
+// {23170F69-40C1-278A-0000-000100060000}
+DEFINE_GUID(IID_IInFolderArchive,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000100060000")
+IInFolderArchive: public IUnknown
+{
+public:
+ STDMETHOD(Open)(const wchar_t *filePath,
+ // CLSID *clsIDResult,
+ BSTR *archiveType,
+ IArchiveOpenCallback *openArchiveCallback) PURE;
+ STDMETHOD(ReOpen)(
+ // const wchar_t *filePath,
+ IArchiveOpenCallback *openArchiveCallback) PURE;
+ STDMETHOD(Close)() PURE;
+ STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) PURE;
+ STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties) PURE;
+ STDMETHOD(GetPropertyInfo)(UINT32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType) PURE;
+ STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties) PURE;
+ STDMETHOD(GetArchivePropertyInfo)(UINT32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType) PURE;
+ STDMETHOD(BindToRootFolder)(IFolderFolder **resultFolder) PURE;
+ STDMETHOD(Extract)(
+ NExtract::NPathMode::EEnum pathMode,
+ NExtract::NOverwriteMode::EEnum overwriteMode,
+ const wchar_t *path,
+ INT32 testMode,
+ IFolderArchiveExtractCallback *extractCallback2) PURE;
+};
+
+// {23170F69-40C1-278A-0000-0001000B0000}
+DEFINE_GUID(IID_IFolderArchiveUpdateCallback,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-0001000B0000")
+IFolderArchiveUpdateCallback: public IProgress
+{
+public:
+ STDMETHOD(CompressOperation)(const wchar_t *name) PURE;
+ STDMETHOD(DeleteOperation)(const wchar_t *name) PURE;
+ STDMETHOD(OperationResult)(INT32 operationResult) PURE;
+ STDMETHOD(UpdateErrorMessage)(const wchar_t *message) PURE;
+};
+
+// {23170F69-40C1-278A-0000-0001000A0000}
+DEFINE_GUID(IID_IOutFolderArchive,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-0001000A0000")
+IOutFolderArchive: public IUnknown
+{
+ STDMETHOD(SetFolder)(IFolderFolder *folder) PURE;
+ STDMETHOD(SetFiles)(const wchar_t *folderPrefix, const wchar_t **names, UINT32 numNames) PURE;
+ STDMETHOD(DeleteItems)(const wchar_t *newArchiveName,
+ const UINT32 *indices, UINT32 numItems, IFolderArchiveUpdateCallback *updateCallback) PURE;
+ STDMETHOD(DoOperation)(
+ const wchar_t *filePath,
+ const CLSID *clsID,
+ const wchar_t *newArchiveName,
+ const Byte *stateActions,
+ const wchar_t *sfxModule,
+ IFolderArchiveUpdateCallback *updateCallback) PURE;
+};
+
+#endif
diff --git a/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp b/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp
new file mode 100755
index 00000000..0d57307c
--- /dev/null
+++ b/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp
@@ -0,0 +1,80 @@
+// UpdateCallbackAgent.h
+
+#include "StdAfx.h"
+
+#include "Windows/Error.h"
+
+#include "UpdateCallbackAgent.h"
+
+using namespace NWindows;
+
+HRESULT CUpdateCallbackAgent::SetTotal(UINT64 size)
+{
+ if (Callback)
+ return Callback->SetTotal(size);
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackAgent::SetCompleted(const UINT64 *completeValue)
+{
+ if (Callback)
+ return Callback->SetCompleted(completeValue);
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackAgent::CheckBreak()
+{
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackAgent::Finilize()
+{
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackAgent::OpenFileError(const wchar_t *name, DWORD systemError)
+{
+ // if (systemError == ERROR_SHARING_VIOLATION)
+ {
+ if (Callback)
+ {
+ RINOK(Callback->UpdateErrorMessage(
+ UString(L"WARNING: ") +
+ NError::MyFormatMessageW(systemError) +
+ UString(L": ") +
+ UString(name)));
+ return S_FALSE;
+ }
+ }
+ // FailedFiles.Add(name);
+ return systemError;
+}
+
+HRESULT CUpdateCallbackAgent::GetStream(const wchar_t *name, bool /* isAnti */)
+{
+ if (Callback)
+ return Callback->CompressOperation(name);
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackAgent::SetOperationResult(INT32 operationResult)
+{
+ if (Callback)
+ return Callback->OperationResult(operationResult);
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackAgent::CryptoGetTextPassword2(INT32 *passwordIsDefined, BSTR *password)
+{
+ *passwordIsDefined = BoolToInt(false);
+ if (!_cryptoGetTextPassword)
+ {
+ if (!Callback)
+ return S_OK;
+ HRESULT result = Callback.QueryInterface(
+ IID_ICryptoGetTextPassword2, &_cryptoGetTextPassword);
+ if (result != S_OK)
+ return S_OK;
+ }
+ return _cryptoGetTextPassword->CryptoGetTextPassword2(passwordIsDefined, password);
+}
diff --git a/CPP/7zip/UI/Agent/UpdateCallbackAgent.h b/CPP/7zip/UI/Agent/UpdateCallbackAgent.h
new file mode 100755
index 00000000..1cff501a
--- /dev/null
+++ b/CPP/7zip/UI/Agent/UpdateCallbackAgent.h
@@ -0,0 +1,24 @@
+// UpdateCallbackAgent.h
+
+#ifndef __UPDATECALLBACKAGENT_H
+#define __UPDATECALLBACKAGENT_H
+
+#include "../Common/UpdateCallback.h"
+#include "IFolderArchive.h"
+
+class CUpdateCallbackAgent: public IUpdateCallbackUI
+{
+ virtual HRESULT SetTotal(UINT64 size);
+ virtual HRESULT SetCompleted(const UINT64 *completeValue);
+ virtual HRESULT CheckBreak();
+ virtual HRESULT Finilize();
+ virtual HRESULT GetStream(const wchar_t *name, bool isAnti);
+ virtual HRESULT OpenFileError(const wchar_t *name, DWORD systemError);
+ virtual HRESULT SetOperationResult(INT32 operationResult);
+ virtual HRESULT CryptoGetTextPassword2(INT32 *passwordIsDefined, BSTR *password);
+ CMyComPtr<ICryptoGetTextPassword2> _cryptoGetTextPassword;
+public:
+ CMyComPtr<IFolderArchiveUpdateCallback> Callback;
+};
+
+#endif
diff --git a/CPP/7zip/UI/Client7z/Client7z.cpp b/CPP/7zip/UI/Client7z/Client7z.cpp
new file mode 100755
index 00000000..46bdb727
--- /dev/null
+++ b/CPP/7zip/UI/Client7z/Client7z.cpp
@@ -0,0 +1,850 @@
+// Client7z.cpp
+
+#include "StdAfx.h"
+
+#include <initguid.h>
+
+#include "Common/StringConvert.h"
+#include "Common/IntToString.h"
+#include "../../Common/FileStreams.h"
+#include "../../Archive/IArchive.h"
+#include "../../IPassword.h"
+
+#include "Windows/PropVariant.h"
+#include "Windows/PropVariantConversions.h"
+#include "Windows/DLL.h"
+#include "Windows/FileDir.h"
+#include "Windows/FileName.h"
+#include "Windows/FileFind.h"
+
+// {23170F69-40C1-278A-1000-000110070000}
+DEFINE_GUID(CLSID_CFormat7z,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);
+
+using namespace NWindows;
+
+static const char *kCopyrightString = "7-Zip 4.43 (7za.DLL client example) (c) 1999-2006 Igor Pavlov 2006-08-10\n";
+static const char *kHelpString =
+"Usage: Client7z.exe [a | l | x ] archive.7z [fileName ...]\n"
+"Examples:\n"
+" Client7z.exe a archive.7z f1.txt f2.txt : compress two files to archive.7z\n"
+" Client7z.exe l archive.7z : List contents of archive.7z\n"
+" Client7z.exe x archive.7z : eXtract files from archive.7z\n";
+
+
+typedef UINT32 (WINAPI * CreateObjectFunc)(
+ const GUID *clsID,
+ const GUID *interfaceID,
+ void **outObject);
+
+#ifndef _UNICODE
+bool g_IsNT = false;
+static inline bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+#endif
+
+void PrintString(const UString &s)
+{
+ printf("%s", (LPCSTR)GetOemString(s));
+}
+
+void PrintString(const AString &s)
+{
+ printf("%s", s);
+}
+
+void PrintNewLine()
+{
+ PrintString("\n");
+}
+
+void PrintStringLn(const AString &s)
+{
+ PrintString(s);
+ PrintNewLine();
+}
+
+static HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result)
+{
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetProperty(index, propID, &prop));
+ if(prop.vt == VT_BOOL)
+ result = VARIANT_BOOLToBool(prop.boolVal);
+ else if (prop.vt == VT_EMPTY)
+ result = false;
+ else
+ return E_FAIL;
+ return S_OK;
+}
+
+static HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result)
+{
+ return IsArchiveItemProp(archive, index, kpidIsFolder, result);
+}
+
+
+static const wchar_t *kEmptyFileAlias = L"[Content]";
+
+
+//////////////////////////////////////////////////////////////
+// Archive Open callback class
+
+
+class CArchiveOpenCallback:
+ public IArchiveOpenCallback,
+ public ICryptoGetTextPassword,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP1(ICryptoGetTextPassword)
+
+ STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes);
+ STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes);
+
+ STDMETHOD(CryptoGetTextPassword)(BSTR *password);
+
+ bool PasswordIsDefined;
+ UString Password;
+
+ CArchiveOpenCallback() : PasswordIsDefined(false) {}
+};
+
+STDMETHODIMP CArchiveOpenCallback::SetTotal(const UInt64 *files, const UInt64 *bytes)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveOpenCallback::SetCompleted(const UInt64 *files, const UInt64 *bytes)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveOpenCallback::CryptoGetTextPassword(BSTR *password)
+{
+ if (!PasswordIsDefined)
+ {
+ // You can ask real password here from user
+ // Password = GetPassword(OutStream);
+ // PasswordIsDefined = true;
+ PrintStringLn("Password is not defined");
+ return E_ABORT;
+ }
+ CMyComBSTR tempName(Password);
+ *password = tempName.Detach();
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////
+// Archive Extracting callback class
+
+static const wchar_t *kCantDeleteOutputFile = L"ERROR: Can not delete output file ";
+
+static const char *kTestingString = "Testing ";
+static const char *kExtractingString = "Extracting ";
+static const char *kSkippingString = "Skipping ";
+
+static const char *kUnsupportedMethod = "Unsupported Method";
+static const char *kCRCFailed = "CRC Failed";
+static const char *kDataError = "Data Error";
+static const char *kUnknownError = "Unknown Error";
+
+class CArchiveExtractCallback:
+ public IArchiveExtractCallback,
+ public ICryptoGetTextPassword,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP1(ICryptoGetTextPassword)
+
+ // IProgress
+ STDMETHOD(SetTotal)(UInt64 size);
+ STDMETHOD(SetCompleted)(const UInt64 *completeValue);
+
+ // IArchiveExtractCallback
+ STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode);
+ STDMETHOD(PrepareOperation)(Int32 askExtractMode);
+ STDMETHOD(SetOperationResult)(Int32 resultEOperationResult);
+
+ // ICryptoGetTextPassword
+ STDMETHOD(CryptoGetTextPassword)(BSTR *aPassword);
+
+private:
+ CMyComPtr<IInArchive> _archiveHandler;
+ UString _directoryPath; // Output directory
+ UString _filePath; // name inside arcvhive
+ UString _diskFilePath; // full path to file on disk
+ bool _extractMode;
+ struct CProcessedFileInfo
+ {
+ FILETIME UTCLastWriteTime;
+ UInt32 Attributes;
+ bool IsDirectory;
+ bool AttributesAreDefined;
+ bool UTCLastWriteTimeIsDefined;
+ } _processedFileInfo;
+
+ COutFileStream *_outFileStreamSpec;
+ CMyComPtr<ISequentialOutStream> _outFileStream;
+
+public:
+ void Init(IInArchive *archiveHandler, const UString &directoryPath);
+
+ UInt64 NumErrors;
+ bool PasswordIsDefined;
+ UString Password;
+
+ CArchiveExtractCallback() : PasswordIsDefined(false) {}
+};
+
+void CArchiveExtractCallback::Init(IInArchive *archiveHandler, const UString &directoryPath)
+{
+ NumErrors = 0;
+ _archiveHandler = archiveHandler;
+ _directoryPath = directoryPath;
+ NFile::NName::NormalizeDirPathPrefix(_directoryPath);
+}
+
+STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 size)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index,
+ ISequentialOutStream **outStream, Int32 askExtractMode)
+{
+ *outStream = 0;
+ _outFileStream.Release();
+
+ {
+ // Get Name
+ NCOM::CPropVariant propVariant;
+ RINOK(_archiveHandler->GetProperty(index, kpidPath, &propVariant));
+
+ UString fullPath;
+ if(propVariant.vt == VT_EMPTY)
+ fullPath = kEmptyFileAlias;
+ else
+ {
+ if(propVariant.vt != VT_BSTR)
+ return E_FAIL;
+ fullPath = propVariant.bstrVal;
+ }
+ _filePath = fullPath;
+ }
+
+ {
+ // Get Attributes
+ NCOM::CPropVariant propVariant;
+ RINOK(_archiveHandler->GetProperty(index, kpidAttributes, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ {
+ _processedFileInfo.Attributes = 0;
+ _processedFileInfo.AttributesAreDefined = false;
+ }
+ else
+ {
+ if (propVariant.vt != VT_UI4)
+ throw "incorrect item";
+ _processedFileInfo.Attributes = propVariant.ulVal;
+ _processedFileInfo.AttributesAreDefined = true;
+ }
+ }
+
+ RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.IsDirectory));
+
+ {
+ // Get Modified Time
+ NCOM::CPropVariant propVariant;
+ RINOK(_archiveHandler->GetProperty(index, kpidLastWriteTime, &propVariant));
+ _processedFileInfo.UTCLastWriteTimeIsDefined = false;
+ switch(propVariant.vt)
+ {
+ case VT_EMPTY:
+ // _processedFileInfo.UTCLastWriteTime = _utcLastWriteTimeDefault;
+ break;
+ case VT_FILETIME:
+ _processedFileInfo.UTCLastWriteTime = propVariant.filetime;
+ _processedFileInfo.UTCLastWriteTimeIsDefined = true;
+ break;
+ default:
+ return E_FAIL;
+ }
+
+ }
+ {
+ // Get Size
+ NCOM::CPropVariant propVariant;
+ RINOK(_archiveHandler->GetProperty(index, kpidSize, &propVariant));
+ bool newFileSizeDefined = (propVariant.vt != VT_EMPTY);
+ UInt64 newFileSize;
+ if (newFileSizeDefined)
+ newFileSize = ConvertPropVariantToUInt64(propVariant);
+ }
+
+
+ {
+ // Create folders for file
+ int slashPos = _filePath.ReverseFind(WCHAR_PATH_SEPARATOR);
+ if (slashPos >= 0)
+ NFile::NDirectory::CreateComplexDirectory(_directoryPath + _filePath.Left(slashPos));
+ }
+
+ UString fullProcessedPath = _directoryPath + _filePath;
+ _diskFilePath = fullProcessedPath;
+
+ if (_processedFileInfo.IsDirectory)
+ {
+ NFile::NDirectory::CreateComplexDirectory(fullProcessedPath);
+ }
+ else
+ {
+ NFile::NFind::CFileInfoW fileInfo;
+ if(NFile::NFind::FindFile(fullProcessedPath, fileInfo))
+ {
+ if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath))
+ {
+ PrintString(UString(kCantDeleteOutputFile) + fullProcessedPath);
+ return E_ABORT;
+ }
+ }
+
+ _outFileStreamSpec = new COutFileStream;
+ CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
+ if (!_outFileStreamSpec->File.Open(fullProcessedPath, CREATE_ALWAYS))
+ {
+ PrintString((UString)L"can not open output file " + fullProcessedPath);
+ return E_ABORT;
+ }
+ _outFileStream = outStreamLoc;
+ *outStream = outStreamLoc.Detach();
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
+{
+ _extractMode = false;
+ switch (askExtractMode)
+ {
+ case NArchive::NExtract::NAskMode::kExtract:
+ _extractMode = true;
+ };
+ switch (askExtractMode)
+ {
+ case NArchive::NExtract::NAskMode::kExtract:
+ PrintString(kExtractingString);
+ break;
+ case NArchive::NExtract::NAskMode::kTest:
+ PrintString(kTestingString);
+ break;
+ case NArchive::NExtract::NAskMode::kSkip:
+ PrintString(kSkippingString);
+ break;
+ };
+ PrintString(_filePath);
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
+{
+ switch(operationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kOK:
+ break;
+ default:
+ {
+ NumErrors++;
+ PrintString(" ");
+ switch(operationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
+ PrintString(kUnsupportedMethod);
+ break;
+ case NArchive::NExtract::NOperationResult::kCRCError:
+ PrintString(kCRCFailed);
+ break;
+ case NArchive::NExtract::NOperationResult::kDataError:
+ PrintString(kDataError);
+ break;
+ default:
+ PrintString(kUnknownError);
+ }
+ }
+ }
+
+ if(_outFileStream != NULL && _processedFileInfo.UTCLastWriteTimeIsDefined)
+ _outFileStreamSpec->File.SetLastWriteTime(&_processedFileInfo.UTCLastWriteTime);
+ _outFileStream.Release();
+ if (_extractMode && _processedFileInfo.AttributesAreDefined)
+ NFile::NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attributes);
+ PrintNewLine();
+ return S_OK;
+}
+
+
+STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)
+{
+ if (!PasswordIsDefined)
+ {
+ // You can ask real password here from user
+ // Password = GetPassword(OutStream);
+ // PasswordIsDefined = true;
+ PrintStringLn("Password is not defined");
+ return E_ABORT;
+ }
+ CMyComBSTR tempName(Password);
+ *password = tempName.Detach();
+ return S_OK;
+}
+
+
+
+//////////////////////////////////////////////////////////////
+// Archive Creating callback class
+
+struct CDirItem
+{
+ UInt32 Attributes;
+ FILETIME CreationTime;
+ FILETIME LastAccessTime;
+ FILETIME LastWriteTime;
+ UInt64 Size;
+ UString Name;
+ UString FullPath;
+ bool IsDirectory() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0 ; }
+};
+
+class CArchiveUpdateCallback:
+ public IArchiveUpdateCallback2,
+ public ICryptoGetTextPassword2,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP2(IArchiveUpdateCallback2, ICryptoGetTextPassword2)
+
+ // IProgress
+ STDMETHOD(SetTotal)(UInt64 size);
+ STDMETHOD(SetCompleted)(const UInt64 *completeValue);
+
+ // IUpdateCallback2
+ STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator);
+ STDMETHOD(GetUpdateItemInfo)(UInt32 index,
+ Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive);
+ STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream);
+ STDMETHOD(SetOperationResult)(Int32 operationResult);
+ STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size);
+ STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream);
+
+ STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password);
+
+public:
+ CRecordVector<UInt64> VolumesSizes;
+ UString VolName;
+ UString VolExt;
+
+ UString DirPrefix;
+ const CObjectVector<CDirItem> *DirItems;
+
+ bool PasswordIsDefined;
+ UString Password;
+ bool AskPassword;
+
+ bool m_NeedBeClosed;
+
+ UStringVector FailedFiles;
+ CRecordVector<HRESULT> FailedCodes;
+
+ CArchiveUpdateCallback(): PasswordIsDefined(false), AskPassword(false), DirItems(0) {};
+
+ ~CArchiveUpdateCallback() { Finilize(); }
+ HRESULT Finilize();
+
+ void Init(const CObjectVector<CDirItem> *dirItems)
+ {
+ DirItems = dirItems;
+ m_NeedBeClosed = false;
+ FailedFiles.Clear();
+ FailedCodes.Clear();
+ }
+};
+
+STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue)
+{
+ return S_OK;
+}
+
+
+STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **enumerator)
+{
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index,
+ Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive)
+{
+ if(newData != NULL)
+ *newData = BoolToInt(true);
+ if(newProperties != NULL)
+ *newProperties = BoolToInt(true);
+ if(indexInArchive != NULL)
+ *indexInArchive = UInt32(-1);
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ NWindows::NCOM::CPropVariant propVariant;
+
+ if (propID == kpidIsAnti)
+ {
+ propVariant = false;
+ propVariant.Detach(value);
+ return S_OK;
+ }
+
+ {
+ const CDirItem &dirItem = (*DirItems)[index];
+ switch(propID)
+ {
+ case kpidPath:
+ propVariant = dirItem.Name;
+ break;
+ case kpidIsFolder:
+ propVariant = dirItem.IsDirectory();
+ break;
+ case kpidSize:
+ propVariant = dirItem.Size;
+ break;
+ case kpidAttributes:
+ propVariant = dirItem.Attributes;
+ break;
+ case kpidLastAccessTime:
+ propVariant = dirItem.LastAccessTime;
+ break;
+ case kpidCreationTime:
+ propVariant = dirItem.CreationTime;
+ break;
+ case kpidLastWriteTime:
+ propVariant = dirItem.LastWriteTime;
+ break;
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
+
+HRESULT CArchiveUpdateCallback::Finilize()
+{
+ if (m_NeedBeClosed)
+ {
+ PrintNewLine();
+ m_NeedBeClosed = false;
+ }
+ return S_OK;
+}
+
+static void GetStream2(const wchar_t *name)
+{
+ PrintString("Compressing ");
+ if (name[0] == 0)
+ name = kEmptyFileAlias;
+ PrintString(name);
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
+{
+ RINOK(Finilize());
+
+ const CDirItem &dirItem = (*DirItems)[index];
+ GetStream2(dirItem.Name);
+
+ if(dirItem.IsDirectory())
+ return S_OK;
+
+ {
+ CInFileStream *inStreamSpec = new CInFileStream;
+ CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
+ UString path = DirPrefix + dirItem.FullPath;
+ if(!inStreamSpec->Open(path))
+ {
+ DWORD sysError = ::GetLastError();
+ FailedCodes.Add(sysError);
+ FailedFiles.Add(path);
+ // if (systemError == ERROR_SHARING_VIOLATION)
+ {
+ PrintNewLine();
+ PrintStringLn("WARNING: can't open file");
+ // PrintString(NError::MyFormatMessageW(systemError));
+ return S_FALSE;
+ }
+ // return sysError;
+ }
+ *inStream = inStreamLoc.Detach();
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 operationResult)
+{
+ m_NeedBeClosed = true;
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)
+{
+ if (VolumesSizes.Size() == 0)
+ return S_FALSE;
+ if (index >= (UInt32)VolumesSizes.Size())
+ index = VolumesSizes.Size() - 1;
+ *size = VolumesSizes[index];
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)
+{
+ wchar_t temp[32];
+ ConvertUInt64ToString(index + 1, temp);
+ UString res = temp;
+ while (res.Length() < 2)
+ res = UString(L'0') + res;
+ UString fileName = VolName;
+ fileName += L'.';
+ fileName += res;
+ fileName += VolExt;
+ COutFileStream *streamSpec = new COutFileStream;
+ CMyComPtr<ISequentialOutStream> streamLoc(streamSpec);
+ if(!streamSpec->Create(fileName, false))
+ return ::GetLastError();
+ *volumeStream = streamLoc.Detach();
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
+{
+ if (!PasswordIsDefined)
+ {
+ if (AskPassword)
+ {
+ // You can ask real password here from user
+ // Password = GetPassword(OutStream);
+ // PasswordIsDefined = true;
+ PrintStringLn("Password is not defined");
+ return E_ABORT;
+ }
+ }
+ *passwordIsDefined = BoolToInt(PasswordIsDefined);
+ CMyComBSTR tempName(Password);
+ *password = tempName.Detach();
+ return S_OK;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+// Main function
+
+int
+#ifdef _MSC_VER
+__cdecl
+#endif
+main(int argc, char* argv[])
+{
+ #ifndef _UNICODE
+ g_IsNT = IsItWindowsNT();
+ #endif
+
+ PrintStringLn(kCopyrightString);
+
+ if (argc < 3)
+ {
+ PrintStringLn(kHelpString);
+ return 1;
+ }
+ NWindows::NDLL::CLibrary library;
+ if (!library.Load(TEXT("7za.dll")))
+ {
+ PrintStringLn("Can not load library");
+ return 1;
+ }
+ CreateObjectFunc createObjectFunc = (CreateObjectFunc)library.GetProcAddress("CreateObject");
+ if (createObjectFunc == 0)
+ {
+ PrintStringLn("Can not get CreateObject");
+ return 1;
+ }
+
+ AString command = argv[1];
+ UString archiveName = GetUnicodeString(argv[2], CP_OEMCP);
+ if (command.CompareNoCase("a") == 0)
+ {
+ // create archive command
+ if (argc < 4)
+ {
+ PrintStringLn(kHelpString);
+ return 1;
+ }
+ CObjectVector<CDirItem> dirItems;
+ int i;
+ for (i = 3; i < argc; i++)
+ {
+ CDirItem item;
+ UString name = GetUnicodeString(argv[i], CP_OEMCP);
+
+ NFile::NFind::CFileInfoW fileInfo;
+ if (!NFile::NFind::FindFile(name, fileInfo))
+ {
+ PrintString(UString(L"Can't find file") + name);
+ return 1;
+ }
+
+ item.Attributes = fileInfo.Attributes;
+ item.Size = fileInfo.Size;
+ item.CreationTime = fileInfo.CreationTime;
+ item.LastAccessTime = fileInfo.LastAccessTime;
+ item.LastWriteTime = fileInfo.LastWriteTime;
+ item.Name = name;
+ item.FullPath = name;
+ dirItems.Add(item);
+ }
+ COutFileStream *outFileStreamSpec = new COutFileStream;
+ CMyComPtr<IOutStream> outFileStream = outFileStreamSpec;
+ if (!outFileStreamSpec->Create(archiveName, false))
+ {
+ PrintStringLn("can't create archive file");
+ return 1;
+ }
+
+ CMyComPtr<IOutArchive> outArchive;
+ if (createObjectFunc(&CLSID_CFormat7z, &IID_IOutArchive, (void **)&outArchive) != S_OK)
+ {
+ PrintStringLn("Can not get class object");
+ return 1;
+ }
+
+ CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
+ CMyComPtr<IArchiveUpdateCallback2> updateCallback(updateCallbackSpec);
+ updateCallbackSpec->Init(&dirItems);
+ // updateCallbackSpec->PasswordIsDefined = true;
+ // updateCallbackSpec->Password = L"1";
+
+ HRESULT result = outArchive->UpdateItems(outFileStream, dirItems.Size(), updateCallback);
+ updateCallbackSpec->Finilize();
+ if (result != S_OK)
+ {
+ PrintStringLn("Update Error");
+ return 1;
+ }
+ for (i = 0; i < updateCallbackSpec->FailedFiles.Size(); i++)
+ {
+ PrintNewLine();
+ PrintString((UString)L"Error for file: " + updateCallbackSpec->FailedFiles[i]);
+ }
+ if (updateCallbackSpec->FailedFiles.Size() != 0)
+ return 1;
+ }
+ else
+ {
+ if (argc != 3)
+ {
+ PrintStringLn(kHelpString);
+ return 1;
+ }
+
+ bool listCommand;
+ if (command.CompareNoCase("l") == 0)
+ listCommand = true;
+ else if (command.CompareNoCase("x") == 0)
+ listCommand = false;
+ else
+ {
+ PrintStringLn("incorrect command");
+ return 1;
+ }
+
+ CMyComPtr<IInArchive> archive;
+ if (createObjectFunc(&CLSID_CFormat7z, &IID_IInArchive, (void **)&archive) != S_OK)
+ {
+ PrintStringLn("Can not get class object");
+ return 1;
+ }
+
+ CInFileStream *fileSpec = new CInFileStream;
+ CMyComPtr<IInStream> file = fileSpec;
+
+ if (!fileSpec->Open(archiveName))
+ {
+ PrintStringLn("Can not open archive file");
+ return 1;
+ }
+
+ {
+ CArchiveOpenCallback *openCallbackSpec = new CArchiveOpenCallback;
+ CMyComPtr<IArchiveOpenCallback> openCallback(openCallbackSpec);
+ openCallbackSpec->PasswordIsDefined = false;
+ // openCallbackSpec->PasswordIsDefined = true;
+ // openCallbackSpec->Password = L"1";
+
+ if (archive->Open(file, 0, openCallback) != S_OK)
+ {
+ PrintStringLn("Can not open archive");
+ return 1;
+ }
+ }
+
+ if (listCommand)
+ {
+ // List command
+ UInt32 numItems = 0;
+ archive->GetNumberOfItems(&numItems);
+ for (UInt32 i = 0; i < numItems; i++)
+ {
+ {
+ // Get uncompressed size of file
+ NWindows::NCOM::CPropVariant propVariant;
+ archive->GetProperty(i, kpidSize, &propVariant);
+ UString s = ConvertPropVariantToString(propVariant);
+ PrintString(s);
+ PrintString(" ");
+ }
+ {
+ // Get name of file
+ NWindows::NCOM::CPropVariant propVariant;
+ archive->GetProperty(i, kpidPath, &propVariant);
+ UString s = ConvertPropVariantToString(propVariant);
+ PrintString(s);
+ }
+ PrintString("\n");
+ }
+ }
+ else
+ {
+ // Extract command
+ CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
+ CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);
+ extractCallbackSpec->Init(archive, L""); // second parameter is output folder path
+ extractCallbackSpec->PasswordIsDefined = false;
+ // extractCallbackSpec->PasswordIsDefined = true;
+ // extractCallbackSpec->Password = L"1";
+ archive->Extract(0, (UInt32)(Int32)(-1), false, extractCallback);
+ }
+ }
+ return 0;
+}
diff --git a/CPP/7zip/UI/Client7z/Client7z.dsp b/CPP/7zip/UI/Client7z/Client7z.dsp
new file mode 100755
index 00000000..b574bdb7
--- /dev/null
+++ b/CPP/7zip/UI/Client7z/Client7z.dsp
@@ -0,0 +1,226 @@
+# Microsoft Developer Studio Project File - Name="Client7z" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=Client7z - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "Client7z.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "Client7z.mak" CFG="Client7z - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Client7z - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "Client7z - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "Client7z - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "Client7z - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "Client7z - Win32 Release"
+# Name "Client7z - Win32 Debug"
+# Begin Group "Spec"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"stdafx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# 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\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.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\Vector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Vector.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.h
+# End Source File
+# End Group
+# Begin Group "7zip Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\Client7z.cpp
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/UI/Client7z/Client7z.dsw b/CPP/7zip/UI/Client7z/Client7z.dsw
new file mode 100755
index 00000000..598a6d3f
--- /dev/null
+++ b/CPP/7zip/UI/Client7z/Client7z.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Client7z"=.\Client7z.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/UI/Client7z/StdAfx.cpp b/CPP/7zip/UI/Client7z/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/UI/Client7z/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/UI/Client7z/StdAfx.h b/CPP/7zip/UI/Client7z/StdAfx.h
new file mode 100755
index 00000000..b23436e9
--- /dev/null
+++ b/CPP/7zip/UI/Client7z/StdAfx.h
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+#include <stdio.h>
+
+#endif
diff --git a/CPP/7zip/UI/Client7z/makefile b/CPP/7zip/UI/Client7z/makefile
new file mode 100755
index 00000000..c4ae0aaf
--- /dev/null
+++ b/CPP/7zip/UI/Client7z/makefile
@@ -0,0 +1,45 @@
+PROG = 7z.exe
+LIBS = $(LIBS) user32.lib oleaut32.lib advapi32.lib
+CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_MT
+
+CONSOLE_OBJS = \
+ $O\Client7z.obj \
+
+COMMON_OBJS = \
+ $O\IntToString.obj \
+ $O\NewHandler.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\Vector.obj \
+ $O\Wildcard.obj \
+
+WIN_OBJS = \
+ $O\DLL.obj \
+ $O\FileDir.obj \
+ $O\FileFind.obj \
+ $O\FileIO.obj \
+ $O\FileName.obj \
+ $O\PropVariant.obj \
+ $O\PropVariantConversions.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\FileStreams.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(CONSOLE_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+
+!include "../../../Build.mak"
+
+$(CONSOLE_OBJS): $(*B).cpp
+ $(COMPL_O1_W3)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
new file mode 100755
index 00000000..6f951a27
--- /dev/null
+++ b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
@@ -0,0 +1,985 @@
+// ArchiveCommandLine.cpp
+
+#include "StdAfx.h"
+
+#include <io.h>
+#include <stdio.h>
+
+#include "Common/ListFileUtils.h"
+#include "Common/StringConvert.h"
+#include "Common/StringToInt.h"
+
+#include "Windows/FileName.h"
+#include "Windows/FileDir.h"
+#ifdef _WIN32
+#include "Windows/FileMapping.h"
+#include "Windows/Synchronization.h"
+#endif
+
+#include "ArchiveCommandLine.h"
+#include "UpdateAction.h"
+#include "Update.h"
+#include "ArchiverInfo.h"
+#include "SortUtils.h"
+#include "EnumDirItems.h"
+
+using namespace NCommandLineParser;
+using namespace NWindows;
+using namespace NFile;
+
+static const int kNumSwitches = 28;
+
+namespace NKey {
+enum Enum
+{
+ kHelp1 = 0,
+ kHelp2,
+ kHelp3,
+ kDisableHeaders,
+ kDisablePercents,
+ kArchiveType,
+ kYes,
+ kPassword,
+ kProperty,
+ kOutputDir,
+ kWorkingDir,
+ kInclude,
+ kExclude,
+ kArInclude,
+ kArExclude,
+ kNoArName,
+ kUpdate,
+ kVolume,
+ kRecursed,
+ kSfx,
+ kStdIn,
+ kStdOut,
+ kOverwrite,
+ kEmail,
+ kShowDialog,
+ kLargePages,
+ kCharSet,
+ kTechMode
+};
+
+}
+
+
+static const wchar_t kRecursedIDChar = 'R';
+static const wchar_t *kRecursedPostCharSet = L"0-";
+
+static const wchar_t *kDefaultArchiveType = L"7z";
+static const wchar_t *kSFXExtension =
+ #ifdef _WIN32
+ L"exe";
+ #else
+ L"";
+ #endif
+
+namespace NRecursedPostCharIndex {
+ enum EEnum
+ {
+ kWildCardRecursionOnly = 0,
+ kNoRecursion = 1
+ };
+}
+
+static const char kImmediateNameID = '!';
+static const char kMapNameID = '#';
+static const char kFileListID = '@';
+
+static const char kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be
+static const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be
+
+static const wchar_t *kOverwritePostCharSet = L"asut";
+
+NExtract::NOverwriteMode::EEnum k_OverwriteModes[] =
+{
+ NExtract::NOverwriteMode::kWithoutPrompt,
+ NExtract::NOverwriteMode::kSkipExisting,
+ NExtract::NOverwriteMode::kAutoRename,
+ NExtract::NOverwriteMode::kAutoRenameExisting
+};
+
+static const CSwitchForm kSwitchForms[kNumSwitches] =
+ {
+ { L"?", NSwitchType::kSimple, false },
+ { L"H", NSwitchType::kSimple, false },
+ { L"-HELP", NSwitchType::kSimple, false },
+ { L"BA", NSwitchType::kSimple, false },
+ { L"BD", NSwitchType::kSimple, false },
+ { L"T", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"Y", NSwitchType::kSimple, false },
+ { L"P", NSwitchType::kUnLimitedPostString, false, 0 },
+ { L"M", NSwitchType::kUnLimitedPostString, true, 1 },
+ { L"O", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"W", NSwitchType::kUnLimitedPostString, false, 0 },
+ { L"I", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
+ { L"X", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
+ { L"AI", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
+ { L"AX", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
+ { L"AN", NSwitchType::kSimple, false },
+ { L"U", NSwitchType::kUnLimitedPostString, true, 1},
+ { L"V", NSwitchType::kUnLimitedPostString, true, 1},
+ { L"R", NSwitchType::kPostChar, false, 0, 0, kRecursedPostCharSet },
+ { L"SFX", NSwitchType::kUnLimitedPostString, false, 0 },
+ { L"SI", NSwitchType::kUnLimitedPostString, false, 0 },
+ { L"SO", NSwitchType::kSimple, false, 0 },
+ { L"AO", NSwitchType::kPostChar, false, 1, 1, kOverwritePostCharSet},
+ { L"SEML", NSwitchType::kUnLimitedPostString, false, 0},
+ { L"AD", NSwitchType::kSimple, false },
+ { L"SLP", NSwitchType::kUnLimitedPostString, false, 0},
+ { L"SCS", NSwitchType::kUnLimitedPostString, false, 0},
+ { L"SLT", NSwitchType::kSimple, false }
+ };
+
+static const int kNumCommandForms = 7;
+
+static const CCommandForm g_CommandForms[kNumCommandForms] =
+{
+ { L"A", false },
+ { L"U", false },
+ { L"D", false },
+ { L"T", false },
+ { L"E", false },
+ { L"X", false },
+ { L"L", false }
+};
+
+static const int kMaxCmdLineSize = 1000;
+static const wchar_t *kUniversalWildcard = L"*";
+static const int kMinNonSwitchWords = 1;
+static const int kCommandIndex = 0;
+
+// ---------------------------
+// exception messages
+
+static const char *kUserErrorMessage = "Incorrect command line";
+static const char *kIncorrectListFile = "Incorrect wildcard in listfile";
+static const char *kIncorrectWildCardInListFile = "Incorrect wildcard in listfile";
+static const char *kIncorrectWildCardInCommandLine = "Incorrect wildcard in command line";
+static const char *kTerminalOutError = "I won't write compressed data to a terminal";
+static const char *kSameTerminalError = "I won't write data and program's messages to same terminal";
+
+static void ThrowException(const char *errorMessage)
+{
+ throw CArchiveCommandLineException(errorMessage);
+};
+
+static void ThrowUserErrorException()
+{
+ ThrowException(kUserErrorMessage);
+};
+
+// ---------------------------
+
+bool CArchiveCommand::IsFromExtractGroup() const
+{
+ switch(CommandType)
+ {
+ case NCommandType::kTest:
+ case NCommandType::kExtract:
+ case NCommandType::kFullExtract:
+ return true;
+ default:
+ return false;
+ }
+}
+
+NExtract::NPathMode::EEnum CArchiveCommand::GetPathMode() const
+{
+ switch(CommandType)
+ {
+ case NCommandType::kTest:
+ case NCommandType::kFullExtract:
+ return NExtract::NPathMode::kFullPathnames;
+ default:
+ return NExtract::NPathMode::kNoPathnames;
+ }
+}
+
+bool CArchiveCommand::IsFromUpdateGroup() const
+{
+ return (CommandType == NCommandType::kAdd ||
+ CommandType == NCommandType::kUpdate ||
+ CommandType == NCommandType::kDelete);
+}
+
+static NRecursedType::EEnum GetRecursedTypeFromIndex(int index)
+{
+ switch (index)
+ {
+ case NRecursedPostCharIndex::kWildCardRecursionOnly:
+ return NRecursedType::kWildCardOnlyRecursed;
+ case NRecursedPostCharIndex::kNoRecursion:
+ return NRecursedType::kNonRecursed;
+ default:
+ return NRecursedType::kRecursed;
+ }
+}
+
+static bool ParseArchiveCommand(const UString &commandString, CArchiveCommand &command)
+{
+ UString commandStringUpper = commandString;
+ commandStringUpper.MakeUpper();
+ UString postString;
+ int commandIndex = ParseCommand(kNumCommandForms, g_CommandForms, commandStringUpper,
+ postString) ;
+ if (commandIndex < 0)
+ return false;
+ command.CommandType = (NCommandType::EEnum)commandIndex;
+ return true;
+}
+
+// ------------------------------------------------------------------
+// filenames functions
+
+static bool AddNameToCensor(NWildcard::CCensor &wildcardCensor,
+ const UString &name, bool include, NRecursedType::EEnum type)
+{
+ bool isWildCard = DoesNameContainWildCard(name);
+ bool recursed = false;
+
+ switch (type)
+ {
+ case NRecursedType::kWildCardOnlyRecursed:
+ recursed = isWildCard;
+ break;
+ case NRecursedType::kRecursed:
+ recursed = true;
+ break;
+ case NRecursedType::kNonRecursed:
+ recursed = false;
+ break;
+ }
+ wildcardCensor.AddItem(include, name, recursed);
+ return true;
+}
+
+static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
+
+static void AddToCensorFromListFile(NWildcard::CCensor &wildcardCensor,
+ LPCWSTR fileName, bool include, NRecursedType::EEnum type, UINT codePage)
+{
+ UStringVector names;
+ if (!ReadNamesFromListFile(GetSystemString(fileName, GetCurrentCodePage()), names, codePage))
+ throw kIncorrectListFile;
+ for (int i = 0; i < names.Size(); i++)
+ if (!AddNameToCensor(wildcardCensor, names[i], include, type))
+ throw kIncorrectWildCardInListFile;
+}
+
+static void AddCommandLineWildCardToCensr(NWildcard::CCensor &wildcardCensor,
+ const UString &name, bool include, NRecursedType::EEnum recursedType)
+{
+ if (!AddNameToCensor(wildcardCensor, name, include, recursedType))
+ throw kIncorrectWildCardInCommandLine;
+}
+
+static void AddToCensorFromNonSwitchesStrings(
+ int startIndex,
+ NWildcard::CCensor &wildcardCensor,
+ const UStringVector &nonSwitchStrings, NRecursedType::EEnum type,
+ bool thereAreSwitchIncludes, UINT codePage)
+{
+ if(nonSwitchStrings.Size() == startIndex && (!thereAreSwitchIncludes))
+ AddCommandLineWildCardToCensr(wildcardCensor, kUniversalWildcard, true, type);
+ for(int i = startIndex; i < nonSwitchStrings.Size(); i++)
+ {
+ const UString &s = nonSwitchStrings[i];
+ if (s[0] == kFileListID)
+ AddToCensorFromListFile(wildcardCensor, s.Mid(1), true, type, codePage);
+ else
+ AddCommandLineWildCardToCensr(wildcardCensor, s, true, type);
+ }
+}
+
+#ifdef _WIN32
+static void ParseMapWithPaths(NWildcard::CCensor &wildcardCensor,
+ const UString &switchParam, bool include,
+ NRecursedType::EEnum commonRecursedType)
+{
+ int splitPos = switchParam.Find(L':');
+ if (splitPos < 0)
+ ThrowUserErrorException();
+ UString mappingName = switchParam.Left(splitPos);
+
+ UString switchParam2 = switchParam.Mid(splitPos + 1);
+ splitPos = switchParam2.Find(L':');
+ if (splitPos < 0)
+ ThrowUserErrorException();
+
+ UString mappingSize = switchParam2.Left(splitPos);
+ UString eventName = switchParam2.Mid(splitPos + 1);
+
+ UInt64 dataSize64 = ConvertStringToUInt64(mappingSize, NULL);
+ UInt32 dataSize = (UInt32)dataSize64;
+ {
+ CFileMapping fileMapping;
+ if (!fileMapping.Open(FILE_MAP_READ, false, GetSystemString(mappingName)))
+ ThrowException("Can not open mapping");
+ LPVOID data = fileMapping.MapViewOfFile(FILE_MAP_READ, 0, dataSize);
+ if (data == NULL)
+ ThrowException("MapViewOfFile error");
+ try
+ {
+ const wchar_t *curData = (const wchar_t *)data;
+ if (*curData != 0)
+ ThrowException("Incorrect mapping data");
+ UInt32 numChars = dataSize / sizeof(wchar_t);
+ UString name;
+ for (UInt32 i = 1; i < numChars; i++)
+ {
+ wchar_t c = curData[i];
+ if (c == L'\0')
+ {
+ AddCommandLineWildCardToCensr(wildcardCensor,
+ name, include, commonRecursedType);
+ name.Empty();
+ }
+ else
+ name += c;
+ }
+ if (!name.IsEmpty())
+ ThrowException("data error");
+ }
+ catch(...)
+ {
+ UnmapViewOfFile(data);
+ throw;
+ }
+ UnmapViewOfFile(data);
+ }
+
+ {
+ NSynchronization::CEvent event;
+ event.Open(EVENT_MODIFY_STATE, false, GetSystemString(eventName));
+ event.Set();
+ }
+}
+#endif
+
+static void AddSwitchWildCardsToCensor(NWildcard::CCensor &wildcardCensor,
+ const UStringVector &strings, bool include,
+ NRecursedType::EEnum commonRecursedType, UINT codePage)
+{
+ for(int i = 0; i < strings.Size(); i++)
+ {
+ const UString &name = strings[i];
+ NRecursedType::EEnum recursedType;
+ int pos = 0;
+ if (name.Length() < kSomeCludePostStringMinSize)
+ ThrowUserErrorException();
+ if (::MyCharUpper(name[pos]) == kRecursedIDChar)
+ {
+ pos++;
+ int index = UString(kRecursedPostCharSet).Find(name[pos]);
+ recursedType = GetRecursedTypeFromIndex(index);
+ if (index >= 0)
+ pos++;
+ }
+ else
+ recursedType = commonRecursedType;
+ if (name.Length() < pos + kSomeCludeAfterRecursedPostStringMinSize)
+ ThrowUserErrorException();
+ UString tail = name.Mid(pos + 1);
+ if (name[pos] == kImmediateNameID)
+ AddCommandLineWildCardToCensr(wildcardCensor, tail, include, recursedType);
+ else if (name[pos] == kFileListID)
+ AddToCensorFromListFile(wildcardCensor, tail, include, recursedType, codePage);
+ #ifdef _WIN32
+ else if (name[pos] == kMapNameID)
+ ParseMapWithPaths(wildcardCensor, tail, include, recursedType);
+ #endif
+ else
+ ThrowUserErrorException();
+ }
+}
+
+#ifdef _WIN32
+
+// This code converts all short file names to long file names.
+
+static void ConvertToLongName(const UString &prefix, UString &name)
+{
+ if (name.IsEmpty() || DoesNameContainWildCard(name))
+ return;
+ NFind::CFileInfoW fileInfo;
+ if (NFind::FindFile(prefix + name, fileInfo))
+ name = fileInfo.Name;
+}
+
+static void ConvertToLongNames(const UString &prefix, CObjectVector<NWildcard::CItem> &items)
+{
+ for (int i = 0; i < items.Size(); i++)
+ {
+ NWildcard::CItem &item = items[i];
+ if (item.Recursive || item.PathParts.Size() != 1)
+ continue;
+ ConvertToLongName(prefix, item.PathParts.Front());
+ }
+}
+
+static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &node)
+{
+ ConvertToLongNames(prefix, node.IncludeItems);
+ ConvertToLongNames(prefix, node.ExcludeItems);
+ int i;
+ for (i = 0; i < node.SubNodes.Size(); i++)
+ ConvertToLongName(prefix, node.SubNodes[i].Name);
+ // mix folders with same name
+ for (i = 0; i < node.SubNodes.Size(); i++)
+ {
+ NWildcard::CCensorNode &nextNode1 = node.SubNodes[i];
+ for (int j = i + 1; j < node.SubNodes.Size();)
+ {
+ const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j];
+ if (nextNode1.Name.CompareNoCase(nextNode2.Name) == 0)
+ {
+ nextNode1.IncludeItems += nextNode2.IncludeItems;
+ nextNode1.ExcludeItems += nextNode2.ExcludeItems;
+ node.SubNodes.Delete(j);
+ }
+ else
+ j++;
+ }
+ }
+ for (i = 0; i < node.SubNodes.Size(); i++)
+ {
+ NWildcard::CCensorNode &nextNode = node.SubNodes[i];
+ ConvertToLongNames(prefix + nextNode.Name + wchar_t(NFile::NName::kDirDelimiter), nextNode);
+ }
+}
+
+static void ConvertToLongNames(NWildcard::CCensor &censor)
+{
+ for (int i = 0; i < censor.Pairs.Size(); i++)
+ {
+ NWildcard::CPair &pair = censor.Pairs[i];
+ ConvertToLongNames(pair.Prefix, pair.Head);
+ }
+}
+
+#endif
+
+static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i)
+{
+ switch(i)
+ {
+ case NUpdateArchive::NPairAction::kIgnore: return NUpdateArchive::NPairAction::kIgnore;
+ case NUpdateArchive::NPairAction::kCopy: return NUpdateArchive::NPairAction::kCopy;
+ case NUpdateArchive::NPairAction::kCompress: return NUpdateArchive::NPairAction::kCompress;
+ case NUpdateArchive::NPairAction::kCompressAsAnti: return NUpdateArchive::NPairAction::kCompressAsAnti;
+ }
+ throw 98111603;
+}
+
+const UString kUpdatePairStateIDSet = L"PQRXYZW";
+const int kUpdatePairStateNotSupportedActions[] = {2, 2, 1, -1, -1, -1, -1};
+
+const UString kUpdatePairActionIDSet = L"0123"; //Ignore, Copy, Compress, Create Anti
+
+const wchar_t *kUpdateIgnoreItselfPostStringID = L"-";
+const wchar_t kUpdateNewArchivePostCharID = '!';
+
+
+static bool ParseUpdateCommandString2(const UString &command,
+ NUpdateArchive::CActionSet &actionSet, UString &postString)
+{
+ for(int i = 0; i < command.Length();)
+ {
+ wchar_t c = MyCharUpper(command[i]);
+ int statePos = kUpdatePairStateIDSet.Find(c);
+ if (statePos < 0)
+ {
+ postString = command.Mid(i);
+ return true;
+ }
+ i++;
+ if (i >= command.Length())
+ return false;
+ int actionPos = kUpdatePairActionIDSet.Find(::MyCharUpper(command[i]));
+ if (actionPos < 0)
+ return false;
+ actionSet.StateActions[statePos] = GetUpdatePairActionType(actionPos);
+ if (kUpdatePairStateNotSupportedActions[statePos] == actionPos)
+ return false;
+ i++;
+ }
+ postString.Empty();
+ return true;
+}
+
+static void ParseUpdateCommandString(CUpdateOptions &options,
+ const UStringVector &updatePostStrings,
+ const NUpdateArchive::CActionSet &defaultActionSet)
+{
+ for(int i = 0; i < updatePostStrings.Size(); i++)
+ {
+ const UString &updateString = updatePostStrings[i];
+ if(updateString.CompareNoCase(kUpdateIgnoreItselfPostStringID) == 0)
+ {
+ if(options.UpdateArchiveItself)
+ {
+ options.UpdateArchiveItself = false;
+ options.Commands.Delete(0);
+ }
+ }
+ else
+ {
+ NUpdateArchive::CActionSet actionSet = defaultActionSet;
+
+ UString postString;
+ if (!ParseUpdateCommandString2(updateString, actionSet, postString))
+ ThrowUserErrorException();
+ if(postString.IsEmpty())
+ {
+ if(options.UpdateArchiveItself)
+ options.Commands[0].ActionSet = actionSet;
+ }
+ else
+ {
+ if(MyCharUpper(postString[0]) != kUpdateNewArchivePostCharID)
+ ThrowUserErrorException();
+ CUpdateArchiveCommand uc;
+ UString archivePath = postString.Mid(1);
+ if (archivePath.IsEmpty())
+ ThrowUserErrorException();
+ uc.ArchivePath.BaseExtension = options.ArchivePath.BaseExtension;
+ uc.ArchivePath.VolExtension = options.ArchivePath.VolExtension;
+ uc.ArchivePath.ParseFromPath(archivePath);
+ uc.ActionSet = actionSet;
+ options.Commands.Add(uc);
+ }
+ }
+ }
+}
+
+static const char kByteSymbol = 'B';
+static const char kKiloSymbol = 'K';
+static const char kMegaSymbol = 'M';
+static const char kGigaSymbol = 'G';
+
+static bool ParseComplexSize(const UString &src, UInt64 &result)
+{
+ UString s = src;
+ s.MakeUpper();
+
+ const wchar_t *start = s;
+ const wchar_t *end;
+ UInt64 number = ConvertStringToUInt64(start, &end);
+ int numDigits = (int)(end - start);
+ if (numDigits == 0 || s.Length() > numDigits + 1)
+ return false;
+ if (s.Length() == numDigits)
+ {
+ result = number;
+ return true;
+ }
+ int numBits;
+ switch (s[numDigits])
+ {
+ case kByteSymbol:
+ result = number;
+ return true;
+ case kKiloSymbol:
+ numBits = 10;
+ break;
+ case kMegaSymbol:
+ numBits = 20;
+ break;
+ case kGigaSymbol:
+ numBits = 30;
+ break;
+ default:
+ return false;
+ }
+ if (number >= ((UInt64)1 << (64 - numBits)))
+ return false;
+ result = number << numBits;
+ return true;
+}
+
+static void SetAddCommandOptions(
+ NCommandType::EEnum commandType,
+ const CParser &parser,
+ CUpdateOptions &options)
+{
+ NUpdateArchive::CActionSet defaultActionSet;
+ switch(commandType)
+ {
+ case NCommandType::kAdd:
+ defaultActionSet = NUpdateArchive::kAddActionSet;
+ break;
+ case NCommandType::kDelete:
+ defaultActionSet = NUpdateArchive::kDeleteActionSet;
+ break;
+ default:
+ defaultActionSet = NUpdateArchive::kUpdateActionSet;
+ }
+
+ options.UpdateArchiveItself = true;
+
+ options.Commands.Clear();
+ CUpdateArchiveCommand updateMainCommand;
+ updateMainCommand.ActionSet = defaultActionSet;
+ options.Commands.Add(updateMainCommand);
+ if(parser[NKey::kUpdate].ThereIs)
+ ParseUpdateCommandString(options, parser[NKey::kUpdate].PostStrings,
+ defaultActionSet);
+ if(parser[NKey::kWorkingDir].ThereIs)
+ {
+ const UString &postString = parser[NKey::kWorkingDir].PostStrings[0];
+ if (postString.IsEmpty())
+ NDirectory::MyGetTempPath(options.WorkingDir);
+ else
+ options.WorkingDir = postString;
+ }
+ options.SfxMode = parser[NKey::kSfx].ThereIs;
+ if (options.SfxMode)
+ options.SfxModule = parser[NKey::kSfx].PostStrings[0];
+
+ if (parser[NKey::kVolume].ThereIs)
+ {
+ const UStringVector &sv = parser[NKey::kVolume].PostStrings;
+ for (int i = 0; i < sv.Size(); i++)
+ {
+ UInt64 size;
+ if (!ParseComplexSize(sv[i], size))
+ ThrowException("Incorrect volume size");
+ options.VolumesSizes.Add(size);
+ }
+ }
+}
+
+static void SetMethodOptions(const CParser &parser, CObjectVector<CProperty> &properties)
+{
+ if (parser[NKey::kProperty].ThereIs)
+ {
+ // options.MethodMode.Properties.Clear();
+ for(int i = 0; i < parser[NKey::kProperty].PostStrings.Size(); i++)
+ {
+ CProperty property;
+ const UString &postString = parser[NKey::kProperty].PostStrings[i];
+ int index = postString.Find(L'=');
+ if (index < 0)
+ property.Name = postString;
+ else
+ {
+ property.Name = postString.Left(index);
+ property.Value = postString.Mid(index + 1);
+ }
+ properties.Add(property);
+ }
+ }
+}
+
+
+static void SetArchiveType(const UString &archiveType,
+#ifndef EXCLUDE_COM
+ UString &filePath, CLSID &classID,
+#else
+ UString &formatName,
+#endif
+ UString &archiveExtension)
+{
+ CObjectVector<CArchiverInfo> archiverInfoVector;
+ ReadArchiverInfoList(archiverInfoVector);
+ if (archiverInfoVector.Size() == 0)
+ ThrowException("There are no installed archive handlers");
+ if (archiveType.IsEmpty())
+ ThrowException("Incorrect archive type was assigned");
+ for (int i = 0; i < archiverInfoVector.Size(); i++)
+ {
+ const CArchiverInfo &archiverInfo = archiverInfoVector[i];
+ if (archiverInfo.Name.CompareNoCase(archiveType) == 0)
+ {
+ #ifndef EXCLUDE_COM
+ classID = archiverInfo.ClassID;
+ filePath = archiverInfo.FilePath;
+ #else
+ formatName = archiverInfo.Name;
+
+ #endif
+
+ archiveExtension = archiverInfo.GetMainExtension();
+ return;
+ }
+ }
+ ThrowException("Incorrect archive type was assigned");
+}
+
+
+CArchiveCommandLineParser::CArchiveCommandLineParser(): parser(kNumSwitches) {}
+
+void CArchiveCommandLineParser::Parse1(const UStringVector &commandStrings,
+ CArchiveCommandLineOptions &options)
+{
+ try
+ {
+ parser.ParseStrings(kSwitchForms, commandStrings);
+ }
+ catch(...)
+ {
+ ThrowUserErrorException();
+ }
+
+ options.IsInTerminal = (_isatty(_fileno(stdin)) != 0);
+ options.IsStdOutTerminal = (_isatty(_fileno(stdout)) != 0);
+ options.IsStdErrTerminal = (_isatty(_fileno(stderr)) != 0);
+ options.StdOutMode = parser[NKey::kStdOut].ThereIs;
+ options.EnableHeaders = !parser[NKey::kDisableHeaders].ThereIs;
+ options.HelpMode = parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs || parser[NKey::kHelp3].ThereIs;
+
+ #ifdef _WIN32
+ options.LargePages = false;
+ if (parser[NKey::kLargePages].ThereIs)
+ {
+ const UString &postString = parser[NKey::kLargePages].PostStrings.Front();
+ if (postString.IsEmpty())
+ options.LargePages = true;
+ }
+ #endif
+}
+
+struct CCodePagePair
+{
+ const wchar_t *Name;
+ UINT CodePage;
+};
+
+static CCodePagePair g_CodePagePairs[] =
+{
+ { L"UTF-8", CP_UTF8 },
+ { L"WIN", CP_ACP },
+ { L"DOS", CP_OEMCP }
+};
+
+static const int kNumCodePages = sizeof(g_CodePagePairs) / sizeof(g_CodePagePairs[0]);
+
+void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
+{
+ const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
+ int numNonSwitchStrings = nonSwitchStrings.Size();
+ if(numNonSwitchStrings < kMinNonSwitchWords)
+ ThrowUserErrorException();
+
+ if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], options.Command))
+ ThrowUserErrorException();
+
+ options.TechMode = parser[NKey::kTechMode].ThereIs;
+
+ NRecursedType::EEnum recursedType;
+ if (parser[NKey::kRecursed].ThereIs)
+ recursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex);
+ else
+ recursedType = NRecursedType::kNonRecursed;
+
+ UINT codePage = CP_UTF8;
+ if (parser[NKey::kCharSet].ThereIs)
+ {
+ UString name = parser[NKey::kCharSet].PostStrings.Front();
+ name.MakeUpper();
+ int i;
+ for (i = 0; i < kNumCodePages; i++)
+ {
+ const CCodePagePair &pair = g_CodePagePairs[i];
+ if (name.Compare(pair.Name) == 0)
+ {
+ codePage = pair.CodePage;
+ break;
+ }
+ }
+ if (i >= kNumCodePages)
+ ThrowUserErrorException();
+ }
+
+ bool thereAreSwitchIncludes = false;
+ if (parser[NKey::kInclude].ThereIs)
+ {
+ thereAreSwitchIncludes = true;
+ AddSwitchWildCardsToCensor(options.WildcardCensor,
+ parser[NKey::kInclude].PostStrings, true, recursedType, codePage);
+ }
+ if (parser[NKey::kExclude].ThereIs)
+ AddSwitchWildCardsToCensor(options.WildcardCensor,
+ parser[NKey::kExclude].PostStrings, false, recursedType, codePage);
+
+ int curCommandIndex = kCommandIndex + 1;
+ bool thereIsArchiveName = !parser[NKey::kNoArName].ThereIs;
+ if (thereIsArchiveName)
+ {
+ if(curCommandIndex >= numNonSwitchStrings)
+ ThrowUserErrorException();
+ options.ArchiveName = nonSwitchStrings[curCommandIndex++];
+ }
+
+ AddToCensorFromNonSwitchesStrings(
+ curCommandIndex, options.WildcardCensor,
+ nonSwitchStrings, recursedType, thereAreSwitchIncludes, codePage);
+
+ options.YesToAll = parser[NKey::kYes].ThereIs;
+
+ bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
+
+ options.PasswordEnabled = parser[NKey::kPassword].ThereIs;
+
+ if(options.PasswordEnabled)
+ options.Password = parser[NKey::kPassword].PostStrings[0];
+
+ options.StdInMode = parser[NKey::kStdIn].ThereIs;
+ options.ShowDialog = parser[NKey::kShowDialog].ThereIs;
+
+ if(isExtractGroupCommand || options.Command.CommandType == NCommandType::kList)
+ {
+ if (options.StdInMode)
+ ThrowException("Reading archives from stdin is not implemented");
+ if (!options.WildcardCensor.AllAreRelative())
+ ThrowException("Cannot use absolute pathnames for this command");
+
+ NWildcard::CCensor archiveWildcardCensor;
+
+ if (parser[NKey::kArInclude].ThereIs)
+ {
+ AddSwitchWildCardsToCensor(archiveWildcardCensor,
+ parser[NKey::kArInclude].PostStrings, true, NRecursedType::kNonRecursed, codePage);
+ }
+ if (parser[NKey::kArExclude].ThereIs)
+ AddSwitchWildCardsToCensor(archiveWildcardCensor,
+ parser[NKey::kArExclude].PostStrings, false, NRecursedType::kNonRecursed, codePage);
+
+ if (thereIsArchiveName)
+ AddCommandLineWildCardToCensr(archiveWildcardCensor, options.ArchiveName, true, NRecursedType::kNonRecursed);
+
+ #ifdef _WIN32
+ ConvertToLongNames(archiveWildcardCensor);
+ #endif
+
+ archiveWildcardCensor.ExtendExclude();
+
+ CObjectVector<CDirItem> dirItems;
+ {
+ UStringVector errorPaths;
+ CRecordVector<DWORD> errorCodes;
+ HRESULT res = EnumerateItems(archiveWildcardCensor, dirItems, NULL, errorPaths, errorCodes);
+ if (res != S_OK || errorPaths.Size() > 0)
+ throw "cannot find archive";
+ }
+ UStringVector archivePaths;
+ int i;
+ for (i = 0; i < dirItems.Size(); i++)
+ {
+ const CDirItem &dirItem = dirItems[i];
+ if (!dirItem.IsDirectory())
+ archivePaths.Add(dirItem.FullPath);
+ }
+
+ if (archivePaths.Size() == 0)
+ throw "there is no such archive";
+
+ UStringVector archivePathsFull;
+
+ for (i = 0; i < archivePaths.Size(); i++)
+ {
+ UString fullPath;
+ NFile::NDirectory::MyGetFullPathName(archivePaths[i], fullPath);
+ archivePathsFull.Add(fullPath);
+ }
+ CIntVector indices;
+ SortStringsToIndices(archivePathsFull, indices);
+ options.ArchivePathsSorted.Reserve(indices.Size());
+ options.ArchivePathsFullSorted.Reserve(indices.Size());
+ for (i = 0; i < indices.Size(); i++)
+ {
+ options.ArchivePathsSorted.Add(archivePaths[indices[i]]);
+ options.ArchivePathsFullSorted.Add(archivePathsFull[indices[i]]);
+ }
+
+ if (isExtractGroupCommand)
+ {
+ SetMethodOptions(parser, options.ExtractProperties);
+ if (options.StdOutMode && options.IsStdOutTerminal && options.IsStdErrTerminal)
+ throw kSameTerminalError;
+ if(parser[NKey::kOutputDir].ThereIs)
+ {
+ options.OutputDir = parser[NKey::kOutputDir].PostStrings[0];
+ NFile::NName::NormalizeDirPathPrefix(options.OutputDir);
+ }
+
+ options.OverwriteMode = NExtract::NOverwriteMode::kAskBefore;
+ if(parser[NKey::kOverwrite].ThereIs)
+ options.OverwriteMode =
+ k_OverwriteModes[parser[NKey::kOverwrite].PostCharIndex];
+ else if (options.YesToAll)
+ options.OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt;
+ }
+ }
+ else if(options.Command.IsFromUpdateGroup())
+ {
+ CUpdateOptions &updateOptions = options.UpdateOptions;
+
+ UString archiveType;
+ if(parser[NKey::kArchiveType].ThereIs)
+ archiveType = parser[NKey::kArchiveType].PostStrings[0];
+ else
+ archiveType = kDefaultArchiveType;
+
+ UString typeExtension;
+ if (!archiveType.IsEmpty())
+ {
+ #ifndef EXCLUDE_COM
+ SetArchiveType(archiveType, updateOptions.MethodMode.FilePath,
+ updateOptions.MethodMode.ClassID, typeExtension);
+ #else
+ SetArchiveType(archiveType, updateOptions.MethodMode.Name, typeExtension);
+ #endif
+ }
+ UString extension = typeExtension;
+ if(parser[NKey::kSfx].ThereIs)
+ extension = kSFXExtension;
+ updateOptions.ArchivePath.BaseExtension = extension;
+ updateOptions.ArchivePath.VolExtension = typeExtension;
+ updateOptions.ArchivePath.ParseFromPath(options.ArchiveName);
+ SetAddCommandOptions(options.Command.CommandType, parser, updateOptions);
+
+ SetMethodOptions(parser, updateOptions.MethodMode.Properties);
+
+ options.EnablePercents = !parser[NKey::kDisablePercents].ThereIs;
+
+ if (options.EnablePercents)
+ {
+ if ((options.StdOutMode && !options.IsStdErrTerminal) ||
+ (!options.StdOutMode && !options.IsStdOutTerminal))
+ options.EnablePercents = false;
+ }
+
+ updateOptions.EMailMode = parser[NKey::kEmail].ThereIs;
+ if (updateOptions.EMailMode)
+ {
+ updateOptions.EMailAddress = parser[NKey::kEmail].PostStrings.Front();
+ if (updateOptions.EMailAddress.Length() > 0)
+ if (updateOptions.EMailAddress[0] == L'.')
+ {
+ updateOptions.EMailRemoveAfter = true;
+ updateOptions.EMailAddress.Delete(0);
+ }
+ }
+
+ updateOptions.StdOutMode = options.StdOutMode;
+ updateOptions.StdInMode = options.StdInMode;
+
+ if (updateOptions.StdOutMode && updateOptions.EMailMode)
+ throw "stdout mode and email mode cannot be combined";
+ if (updateOptions.StdOutMode && options.IsStdOutTerminal)
+ throw kTerminalOutError;
+ if(updateOptions.StdInMode)
+ updateOptions.StdInFileName = parser[NKey::kStdIn].PostStrings.Front();
+
+ #ifdef _WIN32
+ ConvertToLongNames(options.WildcardCensor);
+ #endif
+ }
+ else
+ ThrowUserErrorException();
+ options.WildcardCensor.ExtendExclude();
+}
diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.h b/CPP/7zip/UI/Common/ArchiveCommandLine.h
new file mode 100755
index 00000000..daa66fb6
--- /dev/null
+++ b/CPP/7zip/UI/Common/ArchiveCommandLine.h
@@ -0,0 +1,95 @@
+// ArchiveCommandLine.h
+
+#ifndef __ARCHIVECOMMANDLINE_H
+#define __ARCHIVECOMMANDLINE_H
+
+#include "Common/Wildcard.h"
+#include "Common/CommandLineParser.h"
+
+#include "Extract.h"
+#include "Update.h"
+
+struct CArchiveCommandLineException: public AString
+{
+ CArchiveCommandLineException(const char *errorMessage): AString(errorMessage) {}
+};
+
+namespace NCommandType { enum EEnum
+{
+ kAdd = 0,
+ kUpdate,
+ kDelete,
+ kTest,
+ kExtract,
+ kFullExtract,
+ kList
+};}
+
+namespace NRecursedType { enum EEnum
+{
+ kRecursed,
+ kWildCardOnlyRecursed,
+ kNonRecursed,
+};}
+
+struct CArchiveCommand
+{
+ NCommandType::EEnum CommandType;
+ bool IsFromExtractGroup() const;
+ bool IsFromUpdateGroup() const;
+ bool IsTestMode() const { return CommandType == NCommandType::kTest; }
+ NExtract::NPathMode::EEnum GetPathMode() const;
+};
+
+struct CArchiveCommandLineOptions
+{
+ bool HelpMode;
+
+ #ifdef _WIN32
+ bool LargePages;
+ #endif
+
+ bool IsInTerminal;
+ bool IsStdOutTerminal;
+ bool IsStdErrTerminal;
+ bool StdInMode;
+ bool StdOutMode;
+ bool EnableHeaders;
+
+ bool YesToAll;
+ bool ShowDialog;
+ // NWildcard::CCensor ArchiveWildcardCensor;
+ NWildcard::CCensor WildcardCensor;
+
+ CArchiveCommand Command;
+ UString ArchiveName;
+
+ bool PasswordEnabled;
+ UString Password;
+
+ bool TechMode;
+ // Extract
+ bool AppendName;
+ UString OutputDir;
+ NExtract::NOverwriteMode::EEnum OverwriteMode;
+ UStringVector ArchivePathsSorted;
+ UStringVector ArchivePathsFullSorted;
+ CObjectVector<CProperty> ExtractProperties;
+
+ CUpdateOptions UpdateOptions;
+ bool EnablePercents;
+
+ CArchiveCommandLineOptions(): StdInMode(false), StdOutMode(false) {};
+
+};
+
+class CArchiveCommandLineParser
+{
+ NCommandLineParser::CParser parser;
+public:
+ CArchiveCommandLineParser();
+ void Parse1(const UStringVector &commandStrings, CArchiveCommandLineOptions &options);
+ void Parse2(CArchiveCommandLineOptions &options);
+};
+
+#endif
diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
new file mode 100755
index 00000000..05520fed
--- /dev/null
+++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
@@ -0,0 +1,448 @@
+// ArchiveExtractCallback.cpp
+
+#include "StdAfx.h"
+
+#include "ArchiveExtractCallback.h"
+
+#include "Common/Wildcard.h"
+#include "Common/StringConvert.h"
+#include "Common/ComTry.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileFind.h"
+#include "Windows/Time.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+
+#include "Windows/PropVariantConversions.h"
+
+#include "../../Common/FilePathAutoRename.h"
+
+#include "../Common/ExtractingFilePath.h"
+#include "OpenArchive.h"
+
+using namespace NWindows;
+
+static const wchar_t *kCantAutoRename = L"ERROR: Can not create file with auto name";
+static const wchar_t *kCantRenameFile = L"ERROR: Can not rename existing file ";
+static const wchar_t *kCantDeleteOutputFile = L"ERROR: Can not delete output file ";
+
+
+void CArchiveExtractCallback::Init(
+ IInArchive *archiveHandler,
+ IFolderArchiveExtractCallback *extractCallback2,
+ bool stdOutMode,
+ const UString &directoryPath,
+ NExtract::NPathMode::EEnum pathMode,
+ NExtract::NOverwriteMode::EEnum overwriteMode,
+ const UStringVector &removePathParts,
+ const UString &itemDefaultName,
+ const FILETIME &utcLastWriteTimeDefault,
+ UInt32 attributesDefault)
+{
+ _stdOutMode = stdOutMode;
+ _numErrors = 0;
+ _extractCallback2 = extractCallback2;
+ _itemDefaultName = itemDefaultName;
+ _utcLastWriteTimeDefault = utcLastWriteTimeDefault;
+ _attributesDefault = attributesDefault;
+ _removePathParts = removePathParts;
+ _pathMode = pathMode;
+ _overwriteMode = overwriteMode;
+ _archiveHandler = archiveHandler;
+ _directoryPath = directoryPath;
+ NFile::NName::NormalizeDirPathPrefix(_directoryPath);
+}
+
+STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 size)
+{
+ COM_TRY_BEGIN
+ return _extractCallback2->SetTotal(size);
+ COM_TRY_END
+}
+
+STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue)
+{
+ COM_TRY_BEGIN
+ return _extractCallback2->SetCompleted(completeValue);
+ COM_TRY_END
+}
+
+void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPathParts, UString &fullPath)
+{
+ fullPath = _directoryPath;
+ for(int i = 0; i < dirPathParts.Size(); i++)
+ {
+ if (i > 0)
+ fullPath += wchar_t(NFile::NName::kDirDelimiter);
+ fullPath += dirPathParts[i];
+ NFile::NDirectory::MyCreateDirectory(fullPath);
+ }
+}
+
+static UString MakePathNameFromParts(const UStringVector &parts)
+{
+ UString result;
+ for(int i = 0; i < parts.Size(); i++)
+ {
+ if(i != 0)
+ result += wchar_t(NFile::NName::kDirDelimiter);
+ result += parts[i];
+ }
+ return result;
+}
+
+
+HRESULT CArchiveExtractCallback::GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined)
+{
+ filetimeIsDefined = false;
+ NCOM::CPropVariant prop;
+ RINOK(_archiveHandler->GetProperty(index, propID, &prop));
+ if (prop.vt == VT_FILETIME)
+ {
+ filetime = prop.filetime;
+ filetimeIsDefined = true;
+ }
+ else if (prop.vt != VT_EMPTY)
+ return E_FAIL;
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode)
+{
+ COM_TRY_BEGIN
+ *outStream = 0;
+ _outFileStream.Release();
+
+ _encrypted = false;
+ _isSplit = false;
+
+ UString fullPath;
+ {
+ NCOM::CPropVariant prop;
+ RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop));
+
+ if(prop.vt == VT_EMPTY)
+ fullPath = _itemDefaultName;
+ else
+ {
+ if(prop.vt != VT_BSTR)
+ return E_FAIL;
+ fullPath = prop.bstrVal;
+ }
+ }
+
+ // UString fullPathCorrect = GetCorrectPath(fullPath);
+ _filePath = fullPath;
+
+ {
+ NCOM::CPropVariant prop;
+ RINOK(_archiveHandler->GetProperty(index, kpidPosition, &prop));
+ if (prop.vt != VT_EMPTY)
+ {
+ if (prop.vt != VT_UI8)
+ return E_FAIL;
+ _position = prop.uhVal.QuadPart;
+ _isSplit = true;
+ }
+ }
+
+ {
+ NCOM::CPropVariant prop;
+ RINOK(_archiveHandler->GetProperty(index, kpidEncrypted, &prop));
+ if (prop.vt == VT_BOOL)
+ _encrypted = VARIANT_BOOLToBool(prop.boolVal);
+ else if (prop.vt != VT_EMPTY)
+ return E_FAIL;
+ }
+
+ if(askExtractMode == NArchive::NExtract::NAskMode::kExtract)
+ {
+ if (_stdOutMode)
+ {
+ CMyComPtr<ISequentialOutStream> outStreamLoc = new CStdOutFileStream;
+ *outStream = outStreamLoc.Detach();
+ return S_OK;
+ }
+
+ {
+ NCOM::CPropVariant prop;
+ RINOK(_archiveHandler->GetProperty(index, kpidAttributes, &prop));
+ if (prop.vt == VT_EMPTY)
+ {
+ _processedFileInfo.Attributes = _attributesDefault;
+ _processedFileInfo.AttributesAreDefined = false;
+ }
+ else
+ {
+ if (prop.vt != VT_UI4)
+ throw "incorrect item";
+ _processedFileInfo.Attributes = prop.ulVal;
+ _processedFileInfo.AttributesAreDefined = true;
+ }
+ }
+
+ RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.IsDirectory));
+
+ RINOK(GetTime(index, kpidCreationTime, _processedFileInfo.CreationTime,
+ _processedFileInfo.IsCreationTimeDefined));
+ RINOK(GetTime(index, kpidLastWriteTime, _processedFileInfo.LastWriteTime,
+ _processedFileInfo.IsLastWriteTimeDefined));
+ RINOK(GetTime(index, kpidLastAccessTime, _processedFileInfo.LastAccessTime,
+ _processedFileInfo.IsLastAccessTimeDefined));
+
+ bool newFileSizeDefined;
+ UInt64 newFileSize;
+ {
+ NCOM::CPropVariant prop;
+ RINOK(_archiveHandler->GetProperty(index, kpidSize, &prop));
+ newFileSizeDefined = (prop.vt != VT_EMPTY);
+ if (newFileSizeDefined)
+ newFileSize = ConvertPropVariantToUInt64(prop);
+ }
+
+ bool isAnti = false;
+ {
+ NCOM::CPropVariant prop;
+ RINOK(_archiveHandler->GetProperty(index, kpidIsAnti, &prop));
+ if (prop.vt == VT_BOOL)
+ isAnti = VARIANT_BOOLToBool(prop.boolVal);
+ }
+
+ UStringVector pathParts;
+ SplitPathToParts(fullPath, pathParts);
+
+ if(pathParts.IsEmpty())
+ return E_FAIL;
+ UString processedPath;
+ switch(_pathMode)
+ {
+ case NExtract::NPathMode::kFullPathnames:
+ {
+ processedPath = fullPath;
+ break;
+ }
+ case NExtract::NPathMode::kCurrentPathnames:
+ {
+ // for incorrect paths: "/dir1/dir2/file"
+ int numRemovePathParts = _removePathParts.Size();
+ if(pathParts.Size() <= numRemovePathParts)
+ return E_FAIL;
+ for(int i = 0; i < numRemovePathParts; i++)
+ if(_removePathParts[i].CompareNoCase(pathParts[i]) != 0)
+ return E_FAIL;
+ pathParts.Delete(0, numRemovePathParts);
+ processedPath = MakePathNameFromParts(pathParts);
+ break;
+ }
+ case NExtract::NPathMode::kNoPathnames:
+ {
+ processedPath = pathParts.Back();
+ pathParts.Delete(0, pathParts.Size() - 1); // Test it!!
+ break;
+ }
+ }
+ processedPath = GetCorrectPath(processedPath);
+ if(!_processedFileInfo.IsDirectory)
+ pathParts.DeleteBack();
+
+ MakeCorrectPath(pathParts);
+
+ if (!isAnti)
+ {
+ if (!pathParts.IsEmpty())
+ {
+ UString fullPathNew;
+ CreateComplexDirectory(pathParts, fullPathNew);
+ if (_processedFileInfo.IsDirectory)
+ NFile::NDirectory::SetDirTime(fullPathNew,
+ (WriteCreated && _processedFileInfo.IsCreationTimeDefined) ? &_processedFileInfo.CreationTime : NULL,
+ (WriteAccessed && _processedFileInfo.IsLastAccessTimeDefined) ? &_processedFileInfo.LastAccessTime : NULL,
+ (WriteModified && _processedFileInfo.IsLastWriteTimeDefined) ? &_processedFileInfo.LastWriteTime : &_utcLastWriteTimeDefault);
+ }
+ }
+
+
+ UString fullProcessedPath = _directoryPath + processedPath;
+
+ if(_processedFileInfo.IsDirectory)
+ {
+ _diskFilePath = fullProcessedPath;
+ if (isAnti)
+ NFile::NDirectory::MyRemoveDirectory(_diskFilePath);
+ return S_OK;
+ }
+
+ if (!_isSplit)
+ {
+ NFile::NFind::CFileInfoW fileInfo;
+ if(NFile::NFind::FindFile(fullProcessedPath, fileInfo))
+ {
+ switch(_overwriteMode)
+ {
+ case NExtract::NOverwriteMode::kSkipExisting:
+ return S_OK;
+ case NExtract::NOverwriteMode::kAskBefore:
+ {
+ Int32 overwiteResult;
+ RINOK(_extractCallback2->AskOverwrite(
+ fullProcessedPath, &fileInfo.LastWriteTime, &fileInfo.Size, fullPath,
+ _processedFileInfo.IsLastWriteTimeDefined ? &_processedFileInfo.LastWriteTime : NULL,
+ newFileSizeDefined ? &newFileSize : NULL,
+ &overwiteResult))
+
+ switch(overwiteResult)
+ {
+ case NOverwriteAnswer::kCancel:
+ return E_ABORT;
+ case NOverwriteAnswer::kNo:
+ return S_OK;
+ case NOverwriteAnswer::kNoToAll:
+ _overwriteMode = NExtract::NOverwriteMode::kSkipExisting;
+ return S_OK;
+ case NOverwriteAnswer::kYesToAll:
+ _overwriteMode = NExtract::NOverwriteMode::kWithoutPrompt;
+ break;
+ case NOverwriteAnswer::kYes:
+ break;
+ case NOverwriteAnswer::kAutoRename:
+ _overwriteMode = NExtract::NOverwriteMode::kAutoRename;
+ break;
+ default:
+ throw 20413;
+ }
+ }
+ }
+ if (_overwriteMode == NExtract::NOverwriteMode::kAutoRename)
+ {
+ if (!AutoRenamePath(fullProcessedPath))
+ {
+ UString message = UString(kCantAutoRename) + fullProcessedPath;
+ RINOK(_extractCallback2->MessageError(message));
+ return E_FAIL;
+ }
+ }
+ else if (_overwriteMode == NExtract::NOverwriteMode::kAutoRenameExisting)
+ {
+ UString existPath = fullProcessedPath;
+ if (!AutoRenamePath(existPath))
+ {
+ UString message = kCantAutoRename + fullProcessedPath;
+ RINOK(_extractCallback2->MessageError(message));
+ return E_FAIL;
+ }
+ if(!NFile::NDirectory::MyMoveFile(fullProcessedPath, existPath))
+ {
+ UString message = UString(kCantRenameFile) + fullProcessedPath;
+ RINOK(_extractCallback2->MessageError(message));
+ return E_FAIL;
+ }
+ }
+ else
+ if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath))
+ {
+ UString message = UString(kCantDeleteOutputFile) +
+ fullProcessedPath;
+ RINOK(_extractCallback2->MessageError(message));
+ return E_FAIL;
+ }
+ }
+ }
+ if (!isAnti)
+ {
+ _outFileStreamSpec = new COutFileStream;
+ CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
+ if (!_outFileStreamSpec->File.Open(fullProcessedPath,
+ _isSplit ? OPEN_ALWAYS: CREATE_ALWAYS))
+ {
+ // if (::GetLastError() != ERROR_FILE_EXISTS || !isSplit)
+ {
+ UString message = L"can not open output file " + fullProcessedPath;
+ RINOK(_extractCallback2->MessageError(message));
+ return S_OK;
+ }
+ }
+ if (_isSplit)
+ {
+ RINOK(_outFileStreamSpec->Seek(_position, STREAM_SEEK_SET, NULL));
+ }
+ _outFileStream = outStreamLoc;
+ *outStream = outStreamLoc.Detach();
+ }
+ _diskFilePath = fullProcessedPath;
+ }
+ else
+ {
+ *outStream = NULL;
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
+{
+ COM_TRY_BEGIN
+ _extractMode = false;
+ switch (askExtractMode)
+ {
+ case NArchive::NExtract::NAskMode::kExtract:
+ _extractMode = true;
+ };
+ return _extractCallback2->PrepareOperation(_filePath, askExtractMode, _isSplit ? &_position: 0);
+ COM_TRY_END
+}
+
+STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
+{
+ COM_TRY_BEGIN
+ switch(operationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kOK:
+ case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
+ case NArchive::NExtract::NOperationResult::kCRCError:
+ case NArchive::NExtract::NOperationResult::kDataError:
+ break;
+ default:
+ _outFileStream.Release();
+ return E_FAIL;
+ }
+ if(_outFileStream != NULL)
+ _outFileStreamSpec->File.SetTime(
+ (WriteCreated && _processedFileInfo.IsCreationTimeDefined) ? &_processedFileInfo.CreationTime : NULL,
+ (WriteAccessed && _processedFileInfo.IsLastAccessTimeDefined) ? &_processedFileInfo.LastAccessTime : NULL,
+ (WriteModified && _processedFileInfo.IsLastWriteTimeDefined) ? &_processedFileInfo.LastWriteTime : &_utcLastWriteTimeDefault);
+ _outFileStream.Release();
+ if (_extractMode && _processedFileInfo.AttributesAreDefined)
+ NFile::NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attributes);
+ RINOK(_extractCallback2->SetOperationResult(operationResult, _encrypted));
+ return S_OK;
+ COM_TRY_END
+}
+
+/*
+STDMETHODIMP CArchiveExtractCallback::GetInStream(
+ const wchar_t *name, ISequentialInStream **inStream)
+{
+ COM_TRY_BEGIN
+ CInFileStream *inFile = new CInFileStream;
+ CMyComPtr<ISequentialInStream> inStreamTemp = inFile;
+ if (!inFile->Open(_srcDirectoryPrefix + name))
+ return ::GetLastError();
+ *inStream = inStreamTemp.Detach();
+ return S_OK;
+ COM_TRY_END
+}
+*/
+
+STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)
+{
+ COM_TRY_BEGIN
+ if (!_cryptoGetTextPassword)
+ {
+ RINOK(_extractCallback2.QueryInterface(IID_ICryptoGetTextPassword,
+ &_cryptoGetTextPassword));
+ }
+ return _cryptoGetTextPassword->CryptoGetTextPassword(password);
+ COM_TRY_END
+}
+
diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.h b/CPP/7zip/UI/Common/ArchiveExtractCallback.h
new file mode 100755
index 00000000..4fd63a53
--- /dev/null
+++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.h
@@ -0,0 +1,111 @@
+// ArchiveExtractCallback.h
+
+#ifndef __ARCHIVEEXTRACTCALLBACK_H
+#define __ARCHIVEEXTRACTCALLBACK_H
+
+#include "../../Archive/IArchive.h"
+#include "IFileExtractCallback.h"
+
+#include "Common/String.h"
+#include "Common/MyCom.h"
+
+#include "../../Common/FileStreams.h"
+#include "../../IPassword.h"
+
+#include "ExtractMode.h"
+
+class CArchiveExtractCallback:
+ public IArchiveExtractCallback,
+ // public IArchiveVolumeExtractCallback,
+ public ICryptoGetTextPassword,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP1(ICryptoGetTextPassword)
+ // COM_INTERFACE_ENTRY(IArchiveVolumeExtractCallback)
+
+ // IProgress
+ STDMETHOD(SetTotal)(UInt64 size);
+ STDMETHOD(SetCompleted)(const UInt64 *completeValue);
+
+ // IExtractCallBack
+ STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode);
+ STDMETHOD(PrepareOperation)(Int32 askExtractMode);
+ STDMETHOD(SetOperationResult)(Int32 resultEOperationResult);
+
+ // IArchiveVolumeExtractCallback
+ // STDMETHOD(GetInStream)(const wchar_t *name, ISequentialInStream **inStream);
+
+ // ICryptoGetTextPassword
+ STDMETHOD(CryptoGetTextPassword)(BSTR *aPassword);
+
+private:
+ CMyComPtr<IInArchive> _archiveHandler;
+ CMyComPtr<IFolderArchiveExtractCallback> _extractCallback2;
+ CMyComPtr<ICryptoGetTextPassword> _cryptoGetTextPassword;
+ UString _directoryPath;
+ NExtract::NPathMode::EEnum _pathMode;
+ NExtract::NOverwriteMode::EEnum _overwriteMode;
+
+ UString _filePath;
+ UInt64 _position;
+ bool _isSplit;
+
+ UString _diskFilePath;
+
+ bool _extractMode;
+
+ bool WriteModified;
+ bool WriteCreated;
+ bool WriteAccessed;
+
+ bool _encrypted;
+
+ struct CProcessedFileInfo
+ {
+ FILETIME CreationTime;
+ FILETIME LastWriteTime;
+ FILETIME LastAccessTime;
+ UInt32 Attributes;
+
+ bool IsCreationTimeDefined;
+ bool IsLastWriteTimeDefined;
+ bool IsLastAccessTimeDefined;
+
+ bool IsDirectory;
+ bool AttributesAreDefined;
+ } _processedFileInfo;
+
+ COutFileStream *_outFileStreamSpec;
+ CMyComPtr<ISequentialOutStream> _outFileStream;
+ UStringVector _removePathParts;
+
+ UString _itemDefaultName;
+ FILETIME _utcLastWriteTimeDefault;
+ UInt32 _attributesDefault;
+ bool _stdOutMode;
+
+ void CreateComplexDirectory(const UStringVector &dirPathParts, UString &fullPath);
+ HRESULT GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined);
+public:
+ CArchiveExtractCallback():
+ WriteModified(true),
+ WriteCreated(false),
+ WriteAccessed(false)
+ {}
+ void Init(
+ IInArchive *archiveHandler,
+ IFolderArchiveExtractCallback *extractCallback2,
+ bool stdOutMode,
+ const UString &directoryPath,
+ NExtract::NPathMode::EEnum pathMode,
+ NExtract::NOverwriteMode::EEnum overwriteMode,
+ const UStringVector &removePathParts,
+ const UString &itemDefaultName,
+ const FILETIME &utcLastWriteTimeDefault,
+ UInt32 attributesDefault);
+
+ UInt64 _numErrors;
+};
+
+#endif
diff --git a/CPP/7zip/UI/Common/ArchiveName.cpp b/CPP/7zip/UI/Common/ArchiveName.cpp
new file mode 100755
index 00000000..2d50ede1
--- /dev/null
+++ b/CPP/7zip/UI/Common/ArchiveName.cpp
@@ -0,0 +1,46 @@
+// ArchiveName.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/FileFind.h"
+#include "Windows/FileDir.h"
+
+using namespace NWindows;
+
+UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName)
+{
+ UString resultName = L"Archive";
+ if (fromPrev)
+ {
+ UString dirPrefix;
+ if (NFile::NDirectory::GetOnlyDirPrefix(srcName, dirPrefix))
+ {
+ if (dirPrefix.Length() > 0)
+ if (dirPrefix[dirPrefix.Length() - 1] == '\\')
+ {
+ dirPrefix.Delete(dirPrefix.Length() - 1);
+ NFile::NFind::CFileInfoW fileInfo;
+ if (NFile::NFind::FindFile(dirPrefix, fileInfo))
+ resultName = fileInfo.Name;
+ }
+ }
+ }
+ else
+ {
+ NFile::NFind::CFileInfoW fileInfo;
+ if (!NFile::NFind::FindFile(srcName, fileInfo))
+ return resultName;
+ resultName = fileInfo.Name;
+ if (!fileInfo.IsDirectory() && !keepName)
+ {
+ int dotPos = resultName.ReverseFind('.');
+ if (dotPos > 0)
+ {
+ UString archiveName2 = resultName.Left(dotPos);
+ if (archiveName2.ReverseFind('.') < 0)
+ resultName = archiveName2;
+ }
+ }
+ }
+ return resultName;
+}
diff --git a/CPP/7zip/UI/Common/ArchiveName.h b/CPP/7zip/UI/Common/ArchiveName.h
new file mode 100755
index 00000000..6b001a5a
--- /dev/null
+++ b/CPP/7zip/UI/Common/ArchiveName.h
@@ -0,0 +1,10 @@
+// ArchiveName.h
+
+#ifndef __ARCHIVENAME_H
+#define __ARCHIVENAME_H
+
+#include "Common/String.h"
+
+UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName);
+
+#endif
diff --git a/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp b/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
new file mode 100755
index 00000000..1d2944d8
--- /dev/null
+++ b/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
@@ -0,0 +1,127 @@
+// ArchiveOpenCallback.cpp
+
+#include "StdAfx.h"
+
+#include "ArchiveOpenCallback.h"
+
+#include "Common/StringConvert.h"
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+
+#include "../../Common/FileStreams.h"
+
+using namespace NWindows;
+
+STDMETHODIMP COpenCallbackImp::SetTotal(const UInt64 *files, const UInt64 *bytes)
+{
+ COM_TRY_BEGIN
+ return Callback->SetTotal(files, bytes);
+ COM_TRY_END
+}
+
+STDMETHODIMP COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *bytes)
+{
+ COM_TRY_BEGIN
+ return Callback->SetTotal(files, bytes);
+ COM_TRY_END
+}
+
+STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NCOM::CPropVariant propVariant;
+ if (_subArchiveMode)
+ {
+ switch(propID)
+ {
+ case kpidName:
+ propVariant = _subArchiveName;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ }
+ switch(propID)
+ {
+ case kpidName:
+ propVariant = _fileInfo.Name;
+ break;
+ case kpidIsFolder:
+ propVariant = _fileInfo.IsDirectory();
+ break;
+ case kpidSize:
+ propVariant = _fileInfo.Size;
+ break;
+ case kpidAttributes:
+ propVariant = (UInt32)_fileInfo.Attributes;
+ break;
+ case kpidLastAccessTime:
+ propVariant = _fileInfo.LastAccessTime;
+ break;
+ case kpidCreationTime:
+ propVariant = _fileInfo.CreationTime;
+ break;
+ case kpidLastWriteTime:
+ propVariant = _fileInfo.LastWriteTime;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+int COpenCallbackImp::FindName(const UString &name)
+{
+ for (int i = 0; i < FileNames.Size(); i++)
+ if (name.CompareNoCase(FileNames[i]) == 0)
+ return i;
+ return -1;
+}
+
+struct CInFileStreamVol: public CInFileStream
+{
+ UString Name;
+ COpenCallbackImp *OpenCallbackImp;
+ CMyComPtr<IArchiveOpenCallback> OpenCallbackRef;
+ ~CInFileStreamVol()
+ {
+ int index = OpenCallbackImp->FindName(Name);
+ if (index >= 0)
+ OpenCallbackImp->FileNames.Delete(index);
+ }
+};
+
+STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStream)
+{
+ COM_TRY_BEGIN
+ if (_subArchiveMode)
+ return S_FALSE;
+ RINOK(Callback->CheckBreak());
+ *inStream = NULL;
+ UString fullPath = _folderPrefix + name;
+ if (!NFile::NFind::FindFile(fullPath, _fileInfo))
+ return S_FALSE;
+ if (_fileInfo.IsDirectory())
+ return S_FALSE;
+ CInFileStreamVol *inFile = new CInFileStreamVol;
+ CMyComPtr<IInStream> inStreamTemp = inFile;
+ if (!inFile->Open(fullPath))
+ return ::GetLastError();
+ *inStream = inStreamTemp.Detach();
+ inFile->Name = name;
+ inFile->OpenCallbackImp = this;
+ inFile->OpenCallbackRef = this;
+ FileNames.Add(name);
+ return S_OK;
+ COM_TRY_END
+}
+
+#ifndef _NO_CRYPTO
+STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password)
+{
+ COM_TRY_BEGIN
+ return Callback->CryptoGetTextPassword(password);
+ COM_TRY_END
+}
+#endif
+
diff --git a/CPP/7zip/UI/Common/ArchiveOpenCallback.h b/CPP/7zip/UI/Common/ArchiveOpenCallback.h
new file mode 100755
index 00000000..454873ad
--- /dev/null
+++ b/CPP/7zip/UI/Common/ArchiveOpenCallback.h
@@ -0,0 +1,89 @@
+// ArchiveOpenCallback.h
+
+#ifndef __ARCHIVE_OPEN_CALLBACK_H
+#define __ARCHIVE_OPEN_CALLBACK_H
+
+#include "Common/String.h"
+#include "Common/MyCom.h"
+#include "Windows/FileFind.h"
+
+#ifndef _NO_CRYPTO
+#include "../../IPassword.h"
+#endif
+#include "../../Archive/IArchive.h"
+
+struct IOpenCallbackUI
+{
+ virtual HRESULT CheckBreak() = 0;
+ virtual HRESULT SetTotal(const UInt64 *files, const UInt64 *bytes) = 0;
+ virtual HRESULT SetCompleted(const UInt64 *files, const UInt64 *bytes) = 0;
+ #ifndef _NO_CRYPTO
+ virtual HRESULT CryptoGetTextPassword(BSTR *password) = 0;
+ virtual HRESULT GetPasswordIfAny(UString &password) = 0;
+ virtual bool WasPasswordAsked() = 0;
+ virtual void ClearPasswordWasAskedFlag() = 0;
+ #endif
+};
+
+class COpenCallbackImp:
+ public IArchiveOpenCallback,
+ public IArchiveOpenVolumeCallback,
+ public IArchiveOpenSetSubArchiveName,
+ #ifndef _NO_CRYPTO
+ public ICryptoGetTextPassword,
+ #endif
+ public CMyUnknownImp
+{
+public:
+ #ifndef _NO_CRYPTO
+ MY_UNKNOWN_IMP3(
+ IArchiveOpenVolumeCallback,
+ ICryptoGetTextPassword,
+ IArchiveOpenSetSubArchiveName
+ )
+ #else
+ MY_UNKNOWN_IMP2(
+ IArchiveOpenVolumeCallback,
+ IArchiveOpenSetSubArchiveName
+ )
+ #endif
+
+ STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes);
+ STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes);
+
+ // IArchiveOpenVolumeCallback
+ STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value);
+ STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream);
+
+ #ifndef _NO_CRYPTO
+ // ICryptoGetTextPassword
+ STDMETHOD(CryptoGetTextPassword)(BSTR *password);
+ #endif
+
+ STDMETHOD(SetSubArchiveName(const wchar_t *name))
+ {
+ _subArchiveMode = true;
+ _subArchiveName = name;
+ return S_OK;
+ }
+
+private:
+ UString _folderPrefix;
+ NWindows::NFile::NFind::CFileInfoW _fileInfo;
+ bool _subArchiveMode;
+ UString _subArchiveName;
+public:
+ UStringVector FileNames;
+ IOpenCallbackUI *Callback;
+ void Init(const UString &folderPrefix, const UString &fileName)
+ {
+ _folderPrefix = folderPrefix;
+ if (!NWindows::NFile::NFind::FindFile(_folderPrefix + fileName, _fileInfo))
+ throw 1;
+ FileNames.Clear();
+ _subArchiveMode = false;
+ }
+ int FindName(const UString &name);
+};
+
+#endif
diff --git a/CPP/7zip/UI/Common/ArchiverInfo.cpp b/CPP/7zip/UI/Common/ArchiverInfo.cpp
new file mode 100755
index 00000000..7833ed3c
--- /dev/null
+++ b/CPP/7zip/UI/Common/ArchiverInfo.cpp
@@ -0,0 +1,372 @@
+// ArchiverInfo.cpp
+
+#include "StdAfx.h"
+
+#include "ArchiverInfo.h"
+
+#ifndef EXCLUDE_COM
+
+#include "Common/StringConvert.h"
+#include "Windows/FileFind.h"
+#include "Windows/FileName.h"
+#include "Windows/DLL.h"
+#ifdef _WIN32
+#include "Windows/Registry.h"
+#endif
+#include "Windows/PropVariant.h"
+#include "../../Archive/IArchive.h"
+
+using namespace NWindows;
+using namespace NFile;
+
+#endif
+
+extern HINSTANCE g_hInstance;
+
+#ifndef EXCLUDE_COM
+
+static void SplitString(const UString &srcString, UStringVector &destStrings)
+{
+ destStrings.Clear();
+ UString string;
+ int len = srcString.Length();
+ if (len == 0)
+ return;
+ for (int i = 0; i < len; i++)
+ {
+ wchar_t c = srcString[i];
+ if (c == L' ')
+ {
+ if (!string.IsEmpty())
+ {
+ destStrings.Add(string);
+ string.Empty();
+ }
+ }
+ else
+ string += c;
+ }
+ if (!string.IsEmpty())
+ destStrings.Add(string);
+}
+
+typedef UInt32 (WINAPI * GetHandlerPropertyFunc)(
+ PROPID propID, PROPVARIANT *value);
+
+static UString GetModuleFolderPrefix()
+{
+ UString path;
+ NDLL::MyGetModuleFileName(g_hInstance, path);
+ int pos = path.ReverseFind(WCHAR_PATH_SEPARATOR);
+ return path.Left(pos + 1);
+}
+
+static wchar_t *kFormatFolderName = L"Formats";
+
+#ifdef _WIN32
+static LPCTSTR kRegistryPath = TEXT("Software\\7-zip");
+static LPCWSTR kProgramPathValue = L"Path";
+static bool ReadPathFromRegistry(HKEY baseKey, UString &path)
+{
+ NRegistry::CKey key;
+ if(key.Open(baseKey, kRegistryPath, KEY_READ) == ERROR_SUCCESS)
+ if (key.QueryValue(kProgramPathValue, path) == ERROR_SUCCESS)
+ {
+ NName::NormalizeDirPathPrefix(path);
+ return true;
+ }
+ return false;
+}
+#endif
+
+static UString GetBaseFolderPrefixFromRegistry()
+{
+ UString moduleFolderPrefix = GetModuleFolderPrefix();
+ NFind::CFileInfoW fileInfo;
+ if (NFind::FindFile(moduleFolderPrefix + kFormatFolderName, fileInfo))
+ if (fileInfo.IsDirectory())
+ return moduleFolderPrefix;
+ UString path;
+ #ifdef _WIN32
+ if(ReadPathFromRegistry(HKEY_CURRENT_USER, path))
+ return path;
+ if(ReadPathFromRegistry(HKEY_LOCAL_MACHINE, path))
+ return path;
+ #endif
+ return moduleFolderPrefix;
+}
+
+typedef UInt32 (WINAPI *CreateObjectPointer)(
+ const GUID *clsID,
+ const GUID *interfaceID,
+ void **outObject);
+
+#endif
+
+#ifndef _SFX
+static inline void SetBuffer(CByteBuffer &bb, const Byte *data, int size)
+{
+ bb.SetCapacity(size);
+ memmove((Byte *)bb, data, size);
+}
+#endif
+
+void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
+{
+ archivers.Clear();
+
+ #ifdef EXCLUDE_COM
+
+ #ifdef FORMAT_7Z
+ {
+ CArchiverInfo item;
+ item.UpdateEnabled = true;
+ item.Name = L"7z";
+ item.Extensions.Add(CArchiverExtInfo(L"7z"));
+ #ifndef _SFX
+ const unsigned char kSig[] = {'7' , 'z', 0xBC, 0xAF, 0x27, 0x1C};
+ SetBuffer(item.StartSignature, kSig, 6);
+ #endif
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_BZIP2
+ {
+ CArchiverInfo item;
+ item.UpdateEnabled = true;
+ item.KeepName = true;
+ item.Name = L"BZip2";
+ item.Extensions.Add(CArchiverExtInfo(L"bz2"));
+ item.Extensions.Add(CArchiverExtInfo(L"tbz2", L".tar"));
+ #ifndef _SFX
+ const unsigned char sig[] = {'B' , 'Z', 'h' };
+ SetBuffer(item.StartSignature, sig, 3);
+ #endif
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_CAB
+ {
+ CArchiverInfo item;
+ item.Name = L"Cab";
+ item.Extensions.Add(CArchiverExtInfo(L"cab"));
+ #ifndef _SFX
+ const unsigned char sig[] = { 0x4D, 0x53, 0x43, 0x46 };
+ SetBuffer(item.StartSignature, sig, 4);
+ #endif
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_GZIP
+ {
+ CArchiverInfo item;
+ item.UpdateEnabled = true;
+ item.Name = L"GZip";
+ item.Extensions.Add(CArchiverExtInfo(L"gz"));
+ item.Extensions.Add(CArchiverExtInfo(L"tgz", L".tar"));
+ #ifndef _SFX
+ const unsigned char sig[] = { 0x1F, 0x8B };
+ SetBuffer(item.StartSignature, sig, 2);
+ #endif
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_SPLIT
+ {
+ CArchiverInfo item;
+ item.UpdateEnabled = false;
+ item.KeepName = true;
+ item.Name = L"Split";
+ item.Extensions.Add(CArchiverExtInfo(L"001"));
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_TAR
+ {
+ CArchiverInfo item;
+ item.UpdateEnabled = true;
+ item.Name = L"Tar";
+ item.Extensions.Add(CArchiverExtInfo(L"tar"));
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_ZIP
+ {
+ CArchiverInfo item;
+ item.UpdateEnabled = true;
+ item.Name = L"Zip";
+ item.Extensions.Add(CArchiverExtInfo(L"zip"));
+ #ifndef _SFX
+ const unsigned char sig[] = { 0x50, 0x4B, 0x03, 0x04 };
+ SetBuffer(item.StartSignature, sig, 4);
+ #endif
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_CPIO
+ {
+ CArchiverInfo item;
+ item.Name = L"Cpio";
+ item.Extensions.Add(CArchiverExtInfo(L"cpio"));
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_RPM
+ {
+ CArchiverInfo item;
+ item.Name = L"Rpm";
+ item.Extensions.Add(CArchiverExtInfo(L"rpm", L".cpio.gz"));
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_ARJ
+ {
+ CArchiverInfo item;
+ item.Name = L"Arj";
+ item.Extensions.Add(CArchiverExtInfo(L"arj"));
+ #ifndef _SFX
+ const unsigned char sig[] = { 0x60, 0xEA };
+ SetBuffer(item.StartSignature, sig, 2);
+ #endif
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_Z
+ {
+ CArchiverInfo item;
+ item.Name = L"Z";
+ item.Extensions.Add(CArchiverExtInfo(L"Z"));
+ #ifndef _SFX
+ const unsigned char sig[] = { 0x1F, 0x9D };
+ SetBuffer(item.StartSignature, sig, 2);
+ #endif
+ archivers.Add(item);
+ }
+ #endif
+
+ #else
+
+ UString folderPath = GetBaseFolderPrefixFromRegistry() +
+ (UString)kFormatFolderName + (UString)WSTRING_PATH_SEPARATOR;
+ NFind::CEnumeratorW enumerator(folderPath + L"*");
+ NFind::CFileInfoW fileInfo;
+ while (enumerator.Next(fileInfo))
+ {
+ if (fileInfo.IsDirectory())
+ continue;
+ UString filePath = folderPath + fileInfo.Name;
+ {
+ NDLL::CLibrary library;
+ if (!library.LoadEx(filePath, LOAD_LIBRARY_AS_DATAFILE))
+ continue;
+ }
+
+ NDLL::CLibrary library;
+ if (!library.Load(filePath))
+ continue;
+ GetHandlerPropertyFunc getHandlerProperty = (GetHandlerPropertyFunc)
+ library.GetProcAddress("GetHandlerProperty");
+ if (getHandlerProperty == NULL)
+ continue;
+
+ CArchiverInfo item;
+ item.FilePath = filePath;
+
+ NWindows::NCOM::CPropVariant prop;
+ if (getHandlerProperty(NArchive::kName, &prop) != S_OK)
+ continue;
+ if (prop.vt != VT_BSTR)
+ continue;
+ item.Name = prop.bstrVal;
+ prop.Clear();
+
+ if (getHandlerProperty(NArchive::kClassID, &prop) != S_OK)
+ continue;
+ if (prop.vt != VT_BSTR)
+ continue;
+ item.ClassID = *(const GUID *)prop.bstrVal;
+ prop.Clear();
+
+ if (getHandlerProperty(NArchive::kExtension, &prop) != S_OK)
+ continue;
+ if (prop.vt != VT_BSTR)
+ continue;
+
+ UString ext = prop.bstrVal;
+ UString addExt;
+
+ prop.Clear();
+
+ if (getHandlerProperty(NArchive::kAddExtension, &prop) != S_OK)
+ continue;
+ if (prop.vt == VT_BSTR)
+ {
+ addExt = prop.bstrVal;
+ }
+ else if (prop.vt != VT_EMPTY)
+ continue;
+ prop.Clear();
+
+ UStringVector exts, addExts;
+ SplitString(ext, exts);
+ SplitString(addExt, addExts);
+
+ prop.Clear();
+ for (int i = 0; i < exts.Size(); i++)
+ {
+ CArchiverExtInfo extInfo;
+ extInfo.Ext = exts[i];
+ if (addExts.Size() > 0)
+ extInfo.AddExt = addExts[i];
+ if (extInfo.AddExt == L"*")
+ extInfo.AddExt.Empty();
+ item.Extensions.Add(extInfo);
+ }
+
+ if (getHandlerProperty(NArchive::kUpdate, &prop) == S_OK)
+ if (prop.vt == VT_BOOL)
+ item.UpdateEnabled = VARIANT_BOOLToBool(prop.boolVal);
+ prop.Clear();
+
+ if (item.UpdateEnabled)
+ {
+ if (getHandlerProperty(NArchive::kKeepName, &prop) == S_OK)
+ if (prop.vt == VT_BOOL)
+ item.KeepName = VARIANT_BOOLToBool(prop.boolVal);
+ prop.Clear();
+ }
+
+ if (getHandlerProperty(NArchive::kStartSignature, &prop) == S_OK)
+ {
+ if (prop.vt == VT_BSTR)
+ {
+ UINT len = ::SysStringByteLen(prop.bstrVal);
+ item.StartSignature.SetCapacity(len);
+ memmove(item.StartSignature, prop.bstrVal, len);
+ }
+ }
+ 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);
+ }
+
+ #endif
+}
+
+
diff --git a/CPP/7zip/UI/Common/ArchiverInfo.h b/CPP/7zip/UI/Common/ArchiverInfo.h
new file mode 100755
index 00000000..3b829518
--- /dev/null
+++ b/CPP/7zip/UI/Common/ArchiverInfo.h
@@ -0,0 +1,66 @@
+// ArchiverInfo.h
+
+#ifndef __ARCHIVERINFO_H
+#define __ARCHIVERINFO_H
+
+#include "Common/String.h"
+#include "Common/Types.h"
+#include "Common/Buffer.h"
+
+struct CArchiverExtInfo
+{
+ UString Ext;
+ UString AddExt;
+ CArchiverExtInfo() {}
+ CArchiverExtInfo(const UString &ext): Ext(ext) {}
+ CArchiverExtInfo(const UString &ext, const UString &addExt): Ext(ext), AddExt(addExt) {}
+};
+
+struct CArchiverInfo
+{
+ #ifndef EXCLUDE_COM
+ UString FilePath;
+ CLSID ClassID;
+ #endif
+ UString Name;
+ CObjectVector<CArchiverExtInfo> Extensions;
+ #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.CompareNoCase(Extensions[i].Ext) == 0)
+ return i;
+ return -1;
+ }
+ UString GetAllExtensions() const
+ {
+ UString s;
+ for (int i = 0; i < Extensions.Size(); i++)
+ {
+ if (i > 0)
+ s += ' ';
+ s += Extensions[i].Ext;
+ }
+ return s;
+ }
+ const UString &GetMainExtension() const
+ {
+ return Extensions[0].Ext;
+ }
+ bool UpdateEnabled;
+ bool KeepName;
+
+ CArchiverInfo(): UpdateEnabled(false), KeepName(false)
+ #ifndef _SFX
+ ,Associate(true)
+ #endif
+ {}
+};
+
+void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers);
+
+#endif
diff --git a/CPP/7zip/UI/Common/CompressCall.cpp b/CPP/7zip/UI/Common/CompressCall.cpp
new file mode 100755
index 00000000..86bdd297
--- /dev/null
+++ b/CPP/7zip/UI/Common/CompressCall.cpp
@@ -0,0 +1,367 @@
+// CompressCall.cpp
+
+#include "StdAfx.h"
+
+#include "CompressCall.h"
+
+#include "Common/Random.h"
+#include "Common/IntToString.h"
+#include "Common/MyCom.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/Synchronization.h"
+#include "Windows/FileMapping.h"
+#include "Windows/FileDir.h"
+
+#include "../../FileManager/ProgramLocation.h"
+#include "../../FileManager/RegistryUtils.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif _UNICODE
+
+using namespace NWindows;
+
+static LPCWSTR kShowDialogSwitch = L" -ad";
+static LPCWSTR kEmailSwitch = L" -seml.";
+static LPCWSTR kMapSwitch = L" -i#";
+static LPCWSTR kArchiveNoNameSwitch = L" -an";
+static LPCWSTR kArchiveTypeSwitch = L" -t";
+static LPCWSTR kArchiveMapSwitch = L" -ai#";
+static LPCWSTR kStopSwitchParsing = L" --";
+static LPCWSTR kLargePagesDisable = L" -slp-";
+
+static void AddLagePagesSwitch(UString &params)
+{
+ if (!ReadLockMemoryEnable())
+ params += kLargePagesDisable;
+}
+
+HRESULT MyCreateProcess(const UString &params,
+ LPCWSTR curDir, bool waitFinish,
+ NWindows::NSynchronization::CEvent *event)
+{
+ const UString params2 = params;
+ PROCESS_INFORMATION processInformation;
+ BOOL result;
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ STARTUPINFOA startupInfo;
+ startupInfo.cb = sizeof(startupInfo);
+ startupInfo.lpReserved = 0;
+ startupInfo.lpDesktop = 0;
+ startupInfo.lpTitle = 0;
+ startupInfo.dwFlags = 0;
+ startupInfo.cbReserved2 = 0;
+ startupInfo.lpReserved2 = 0;
+
+ CSysString curDirA;
+ if (curDir != 0)
+ curDirA = GetSystemString(curDir);
+ result = ::CreateProcessA(NULL, (LPSTR)(LPCSTR)GetSystemString(params),
+ NULL, NULL, FALSE, 0, NULL,
+ ((curDir != 0) ? (LPCSTR)curDirA: 0),
+ &startupInfo, &processInformation);
+ }
+ else
+ #endif
+ {
+ STARTUPINFOW startupInfo;
+ startupInfo.cb = sizeof(startupInfo);
+ startupInfo.lpReserved = 0;
+ startupInfo.lpDesktop = 0;
+ startupInfo.lpTitle = 0;
+ startupInfo.dwFlags = 0;
+ startupInfo.cbReserved2 = 0;
+ startupInfo.lpReserved2 = 0;
+
+ result = ::CreateProcessW(NULL, (LPWSTR)(LPCWSTR)params,
+ NULL, NULL, FALSE, 0, NULL,
+ curDir,
+ &startupInfo, &processInformation);
+ }
+ if (result == 0)
+ return ::GetLastError();
+ else
+ {
+ ::CloseHandle(processInformation.hThread);
+ if (waitFinish)
+ WaitForSingleObject(processInformation.hProcess, INFINITE);
+ else if (event != NULL)
+ {
+ HANDLE handles[] = {processInformation.hProcess, *event };
+ ::WaitForMultipleObjects(sizeof(handles) / sizeof(handles[0]),
+ handles, FALSE, INFINITE);
+ }
+ ::CloseHandle(processInformation.hProcess);
+ }
+ return S_OK;
+}
+
+static UString GetQuotedString(const UString &s)
+{
+ return UString(L"\"") + s + UString(L"\"");
+}
+
+static UString Get7zGuiPath()
+{
+ UString path;
+ UString folder;
+ if (GetProgramFolderPath(folder))
+ path += folder;
+ path += L"7zG.exe";
+ return GetQuotedString(path);
+}
+
+static HRESULT CreateMap(const UStringVector &names,
+ const UString &id,
+ CFileMapping &fileMapping, NSynchronization::CEvent &event,
+ UString &params)
+{
+ UInt32 extraSize = 2;
+ UInt32 dataSize = 0;
+ for (int i = 0; i < names.Size(); i++)
+ dataSize += (names[i].Length() + 1) * sizeof(wchar_t);
+ UInt32 totalSize = extraSize + dataSize;
+
+ UString mappingName;
+ UString eventName;
+
+ CRandom random;
+ random.Init(GetTickCount());
+ for (;;)
+ {
+ int number = random.Generate();
+ wchar_t temp[32];
+ ConvertUInt64ToString(UInt32(number), temp);
+ mappingName = id;
+ mappingName += L"Mapping";
+ mappingName += temp;
+ if (!fileMapping.Create(INVALID_HANDLE_VALUE, NULL,
+ PAGE_READWRITE, totalSize, GetSystemString(mappingName)))
+ return E_FAIL;
+ if (::GetLastError() != ERROR_ALREADY_EXISTS)
+ break;
+ fileMapping.Close();
+ }
+
+ for (;;)
+ {
+ int number = random.Generate();
+ wchar_t temp[32];
+ ConvertUInt64ToString(UInt32(number), temp);
+ eventName = id;
+ eventName += L"MappingEndEvent";
+ eventName += temp;
+ if (!event.Create(true, false, GetSystemString(eventName)))
+ return E_FAIL;
+ if (::GetLastError() != ERROR_ALREADY_EXISTS)
+ break;
+ event.Close();
+ }
+
+ params += mappingName;
+ params += L":";
+ wchar_t string[10];
+ ConvertUInt64ToString(totalSize, string);
+ params += string;
+
+ params += L":";
+ params += eventName;
+
+ LPVOID data = fileMapping.MapViewOfFile(FILE_MAP_WRITE, 0, totalSize);
+ if (data == NULL)
+ return E_FAIL;
+ {
+ wchar_t *curData = (wchar_t *)data;
+ *curData = 0;
+ curData++;
+ for (int i = 0; i < names.Size(); i++)
+ {
+ const UString &s = names[i];
+ memcpy(curData, (const wchar_t *)s, s.Length() * sizeof(wchar_t));
+ curData += s.Length();
+ *curData++ = L'\0';
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CompressFiles(
+ const UString &curDir,
+ const UString &archiveName,
+ const UString &archiveType,
+ const UStringVector &names,
+ // const UString &outFolder,
+ bool email,
+ bool showDialog,
+ bool waitFinish)
+{
+ /*
+ UString curDir;
+ if (names.Size() > 0)
+ {
+ NFile::NDirectory::GetOnlyDirPrefix(names[0], curDir);
+ }
+ */
+ UString params;
+ params = Get7zGuiPath();
+ params += L" a";
+ params += kMapSwitch;
+ // params += _fileNames[0];
+
+ UInt32 extraSize = 2;
+ UInt32 dataSize = 0;
+ for (int i = 0; i < names.Size(); i++)
+ dataSize += (names[i].Length() + 1) * sizeof(wchar_t);
+ UInt32 totalSize = extraSize + dataSize;
+
+ UString mappingName;
+ UString eventName;
+
+ CFileMapping fileMapping;
+ CRandom random;
+ random.Init(GetTickCount());
+ for (;;)
+ {
+ int number = random.Generate();
+ wchar_t temp[32];
+ ConvertUInt64ToString(UInt32(number), temp);
+ mappingName = L"7zCompressMapping";
+ mappingName += temp;
+ if (!fileMapping.Create(INVALID_HANDLE_VALUE, NULL,
+ PAGE_READWRITE, totalSize, GetSystemString(mappingName)))
+ {
+ // MyMessageBox(IDS_ERROR, 0x02000605);
+ return E_FAIL;
+ }
+ if (::GetLastError() != ERROR_ALREADY_EXISTS)
+ break;
+ fileMapping.Close();
+ }
+
+ NSynchronization::CEvent event;
+ for (;;)
+ {
+ int number = random.Generate();
+ wchar_t temp[32];
+ ConvertUInt64ToString(UInt32(number), temp);
+ eventName = L"7zCompressMappingEndEvent";
+ eventName += temp;
+ if (!event.Create(true, false, GetSystemString(eventName)))
+ {
+ // MyMessageBox(IDS_ERROR, 0x02000605);
+ return E_FAIL;
+ }
+ if (::GetLastError() != ERROR_ALREADY_EXISTS)
+ break;
+ event.Close();
+ }
+
+ params += mappingName;
+ params += L":";
+ wchar_t string[10];
+ ConvertUInt64ToString(totalSize, string);
+ params += string;
+
+ params += L":";
+ params += eventName;
+
+ if (!archiveType.IsEmpty())
+ {
+ params += kArchiveTypeSwitch;
+ params += archiveType;
+ }
+
+ if (email)
+ params += kEmailSwitch;
+
+ if (showDialog)
+ params += kShowDialogSwitch;
+
+ AddLagePagesSwitch(params);
+
+ params += kStopSwitchParsing;
+ params += L" ";
+
+ params += GetQuotedString(archiveName);
+
+ LPVOID data = fileMapping.MapViewOfFile(FILE_MAP_WRITE, 0, totalSize);
+ if (data == NULL)
+ {
+ // MyMessageBox(IDS_ERROR, 0x02000605);
+ return E_FAIL;
+ }
+ try
+ {
+ wchar_t *curData = (wchar_t *)data;
+ *curData = 0;
+ curData++;
+ for (int i = 0; i < names.Size(); i++)
+ {
+ const UString &unicodeString = names[i];
+ memcpy(curData, (const wchar_t *)unicodeString ,
+ unicodeString .Length() * sizeof(wchar_t));
+ curData += unicodeString.Length();
+ *curData++ = L'\0';
+ }
+ // MessageBox(0, params, 0, 0);
+ RINOK(MyCreateProcess(params,
+ (curDir.IsEmpty()? 0: (LPCWSTR)curDir),
+ waitFinish, &event));
+ }
+ catch(...)
+ {
+ UnmapViewOfFile(data);
+ throw;
+ }
+ UnmapViewOfFile(data);
+
+
+ /*
+ CThreadCompressMain *compressor = new CThreadCompressMain();;
+ compressor->FileNames = _fileNames;
+ CThread thread;
+ if (!thread.Create(CThreadCompressMain::MyThreadFunction, compressor))
+ throw 271824;
+ */
+ return S_OK;
+}
+
+static HRESULT ExtractGroupCommand(const UStringVector &archivePaths,
+ const UString &params)
+{
+ UString params2 = params;
+ AddLagePagesSwitch(params2);
+ params2 += kArchiveNoNameSwitch;
+ params2 += kArchiveMapSwitch;
+ CFileMapping fileMapping;
+ NSynchronization::CEvent event;
+ RINOK(CreateMap(archivePaths, L"7zExtract", fileMapping, event, params2));
+ return MyCreateProcess(params2, 0, false, &event);
+}
+
+HRESULT ExtractArchives(const UStringVector &archivePaths,
+ const UString &outFolder, bool showDialog)
+{
+ UString params;
+ params = Get7zGuiPath();
+ params += L" x";
+ if (!outFolder.IsEmpty())
+ {
+ params += L" -o";
+ params += GetQuotedString(outFolder);
+ }
+ if (showDialog)
+ params += kShowDialogSwitch;
+ return ExtractGroupCommand(archivePaths, params);
+}
+
+HRESULT TestArchives(const UStringVector &archivePaths)
+{
+ UString params;
+ params = Get7zGuiPath();
+ params += L" t";
+ return ExtractGroupCommand(archivePaths, params);
+}
diff --git a/CPP/7zip/UI/Common/CompressCall.h b/CPP/7zip/UI/Common/CompressCall.h
new file mode 100755
index 00000000..95be95c3
--- /dev/null
+++ b/CPP/7zip/UI/Common/CompressCall.h
@@ -0,0 +1,28 @@
+// CompressCall.h
+
+#ifndef __COMPRESSCALL_H
+#define __COMPRESSCALL_H
+
+#include "Common/String.h"
+#include "Windows/Synchronization.h"
+
+HRESULT MyCreateProcess(const UString &params,
+ LPCWSTR lpCurrentDirectory, bool waitFinish,
+ NWindows::NSynchronization::CEvent *event);
+
+HRESULT CompressFiles(
+ const UString &curDir,
+ const UString &archiveName,
+ const UString &archiveType,
+ const UStringVector &names,
+ // const UString &outFolder,
+ bool email, bool showDialog, bool waitFinish);
+
+HRESULT ExtractArchives(
+ const UStringVector &archivePaths,
+ const UString &outFolder, bool showDialog);
+
+HRESULT TestArchives(const UStringVector &archivePaths);
+
+#endif
+
diff --git a/CPP/7zip/UI/Common/DefaultName.cpp b/CPP/7zip/UI/Common/DefaultName.cpp
new file mode 100755
index 00000000..8ee7c048
--- /dev/null
+++ b/CPP/7zip/UI/Common/DefaultName.cpp
@@ -0,0 +1,26 @@
+// DefaultName.cpp
+
+#include "StdAfx.h"
+
+#include "DefaultName.h"
+
+static const wchar_t *kEmptyFileAlias = L"[Content]";
+
+UString GetDefaultName2(const UString &fileName,
+ const UString &extension, const UString &addSubExtension)
+{
+ int extLength = extension.Length();
+ int fileNameLength = fileName.Length();
+ if (fileNameLength > extLength + 1)
+ {
+ int dotPos = fileNameLength - (extLength + 1);
+ if (fileName[dotPos] == '.')
+ if (extension.CompareNoCase(fileName.Mid(dotPos + 1)) == 0)
+ return fileName.Left(dotPos) + addSubExtension;
+ }
+ int dotPos = fileName.ReverseFind(L'.');
+ if (dotPos > 0)
+ return fileName.Left(dotPos) + addSubExtension;
+ return kEmptyFileAlias;
+}
+
diff --git a/CPP/7zip/UI/Common/DefaultName.h b/CPP/7zip/UI/Common/DefaultName.h
new file mode 100755
index 00000000..ff6330fa
--- /dev/null
+++ b/CPP/7zip/UI/Common/DefaultName.h
@@ -0,0 +1,11 @@
+// DefaultName.h
+
+#ifndef __DEFAULTNAME_H
+#define __DEFAULTNAME_H
+
+#include "Common/String.h"
+
+UString GetDefaultName2(const UString &fileName,
+ const UString &extension, const UString &addSubExtension);
+
+#endif
diff --git a/CPP/7zip/UI/Common/DirItem.h b/CPP/7zip/UI/Common/DirItem.h
new file mode 100755
index 00000000..9537071c
--- /dev/null
+++ b/CPP/7zip/UI/Common/DirItem.h
@@ -0,0 +1,34 @@
+// DirItem.h
+
+#ifndef __DIR_ITEM_H
+#define __DIR_ITEM_H
+
+#include "Common/String.h"
+#include "Common/Types.h"
+
+struct CDirItem
+{
+ UInt32 Attributes;
+ FILETIME CreationTime;
+ FILETIME LastAccessTime;
+ FILETIME LastWriteTime;
+ UInt64 Size;
+ UString Name;
+ UString FullPath;
+ bool IsDirectory() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0 ; }
+};
+
+struct CArchiveItem
+{
+ bool IsDirectory;
+ // DWORD Attributes;
+ // NWindows::NCOM::CPropVariant LastWriteTime;
+ FILETIME LastWriteTime;
+ bool SizeIsDefined;
+ UInt64 Size;
+ UString Name;
+ bool Censored;
+ int IndexInServer;
+};
+
+#endif
diff --git a/CPP/7zip/UI/Common/EnumDirItems.cpp b/CPP/7zip/UI/Common/EnumDirItems.cpp
new file mode 100755
index 00000000..454092ec
--- /dev/null
+++ b/CPP/7zip/UI/Common/EnumDirItems.cpp
@@ -0,0 +1,281 @@
+// EnumDirItems.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StringConvert.h"
+#include "Common/Wildcard.h"
+#include "Common/MyCom.h"
+
+#include "EnumDirItems.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NName;
+
+void AddDirFileInfo(
+ const UString &prefix, // prefix for logical path
+ const UString &fullPathName, // path on disk: can be relative to some basePrefix
+ const NFind::CFileInfoW &fileInfo,
+ CObjectVector<CDirItem> &dirItems)
+{
+ CDirItem item;
+ item.Attributes = fileInfo.Attributes;
+ item.Size = fileInfo.Size;
+ item.CreationTime = fileInfo.CreationTime;
+ item.LastAccessTime = fileInfo.LastAccessTime;
+ item.LastWriteTime = fileInfo.LastWriteTime;
+ item.Name = prefix + fileInfo.Name;
+ item.FullPath = fullPathName;
+ dirItems.Add(item);
+}
+
+static void EnumerateDirectory(
+ const UString &baseFolderPrefix, // base (disk) prefix for scanning
+ const UString &directory, // additional disk prefix starting from baseFolderPrefix
+ const UString &prefix, // logical prefix
+ CObjectVector<CDirItem> &dirItems,
+ UStringVector &errorPaths,
+ CRecordVector<DWORD> &errorCodes)
+{
+ NFind::CEnumeratorW enumerator(baseFolderPrefix + directory + wchar_t(kAnyStringWildcard));
+ for (;;)
+ {
+ NFind::CFileInfoW fileInfo;
+ bool found;
+ if (!enumerator.Next(fileInfo, found))
+ {
+ errorCodes.Add(::GetLastError());
+ errorPaths.Add(baseFolderPrefix + directory);
+ return;
+ }
+ if (!found)
+ break;
+ AddDirFileInfo(prefix, directory + fileInfo.Name, fileInfo, dirItems);
+ if (fileInfo.IsDirectory())
+ {
+ EnumerateDirectory(baseFolderPrefix, directory + fileInfo.Name + wchar_t(kDirDelimiter),
+ prefix + fileInfo.Name + wchar_t(kDirDelimiter), dirItems, errorPaths, errorCodes);
+ }
+ }
+}
+
+void EnumerateDirItems(
+ const UString &baseFolderPrefix, // base (disk) prefix for scanning
+ const UStringVector &fileNames, // names relative to baseFolderPrefix
+ const UString &archiveNamePrefix,
+ CObjectVector<CDirItem> &dirItems,
+ UStringVector &errorPaths,
+ CRecordVector<DWORD> &errorCodes)
+{
+ for(int i = 0; i < fileNames.Size(); i++)
+ {
+ const UString &fileName = fileNames[i];
+ NFind::CFileInfoW fileInfo;
+ if (!NFind::FindFile(baseFolderPrefix + fileName, fileInfo))
+ {
+ errorCodes.Add(::GetLastError());
+ errorPaths.Add(baseFolderPrefix + fileName);
+ continue;
+ }
+ AddDirFileInfo(archiveNamePrefix, fileName, fileInfo, dirItems);
+ if (fileInfo.IsDirectory())
+ {
+ EnumerateDirectory(baseFolderPrefix, fileName + wchar_t(kDirDelimiter),
+ archiveNamePrefix + fileInfo.Name + wchar_t(kDirDelimiter),
+ dirItems, errorPaths, errorCodes);
+ }
+ }
+}
+
+static HRESULT EnumerateDirItems(
+ const NWildcard::CCensorNode &curNode,
+ const UString &diskPrefix, // full disk path prefix
+ const UString &archivePrefix, // prefix from root
+ const UStringVector &addArchivePrefix, // prefix from curNode
+ CObjectVector<CDirItem> &dirItems,
+ bool enterToSubFolders,
+ IEnumDirItemCallback *callback,
+ UStringVector &errorPaths,
+ CRecordVector<DWORD> &errorCodes)
+{
+ if (!enterToSubFolders)
+ if (curNode.NeedCheckSubDirs())
+ enterToSubFolders = true;
+ if (callback)
+ RINOK(callback->CheckBreak());
+
+ // try direct_names case at first
+ if (addArchivePrefix.IsEmpty() && !enterToSubFolders)
+ {
+ // check that all names are direct
+ int i;
+ for (i = 0; i < curNode.IncludeItems.Size(); i++)
+ {
+ const NWildcard::CItem &item = curNode.IncludeItems[i];
+ if (item.Recursive || item.PathParts.Size() != 1)
+ break;
+ const UString &name = item.PathParts.Front();
+ if (name.IsEmpty() || DoesNameContainWildCard(name))
+ break;
+ }
+ if (i == curNode.IncludeItems.Size())
+ {
+ // all names are direct (no wildcards)
+ // so we don't need file_system's dir enumerator
+ CRecordVector<bool> needEnterVector;
+ for (i = 0; i < curNode.IncludeItems.Size(); i++)
+ {
+ const NWildcard::CItem &item = curNode.IncludeItems[i];
+ const UString &name = item.PathParts.Front();
+ const UString fullPath = diskPrefix + name;
+ NFind::CFileInfoW fileInfo;
+ if (!NFind::FindFile(fullPath, fileInfo))
+ {
+ errorCodes.Add(::GetLastError());
+ errorPaths.Add(fullPath);
+ continue;
+ }
+ bool isDir = fileInfo.IsDirectory();
+ if (isDir && !item.ForDir || !isDir && !item.ForFile)
+ {
+ errorCodes.Add((DWORD)E_FAIL);
+ errorPaths.Add(fullPath);
+ continue;
+ }
+ const UString realName = fileInfo.Name;
+ const UString realDiskPath = diskPrefix + realName;
+ {
+ UStringVector pathParts;
+ pathParts.Add(fileInfo.Name);
+ if (curNode.CheckPathToRoot(false, pathParts, !isDir))
+ continue;
+ }
+ AddDirFileInfo(archivePrefix, realDiskPath, fileInfo, dirItems);
+ if (!isDir)
+ continue;
+
+ UStringVector addArchivePrefixNew;
+ const NWildcard::CCensorNode *nextNode = 0;
+ int index = curNode.FindSubNode(name);
+ if (index >= 0)
+ {
+ for (int t = needEnterVector.Size(); t <= index; t++)
+ needEnterVector.Add(true);
+ needEnterVector[index] = false;
+ nextNode = &curNode.SubNodes[index];
+ }
+ else
+ {
+ nextNode = &curNode;
+ addArchivePrefixNew.Add(name); // don't change it to realName. It's for shortnames support
+ }
+ RINOK(EnumerateDirItems(*nextNode,
+ realDiskPath + wchar_t(kDirDelimiter),
+ archivePrefix + realName + wchar_t(kDirDelimiter),
+ addArchivePrefixNew, dirItems, true, callback, errorPaths, errorCodes));
+ }
+ for (i = 0; i < curNode.SubNodes.Size(); i++)
+ {
+ if (i < needEnterVector.Size())
+ if (!needEnterVector[i])
+ continue;
+ const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i];
+ const UString fullPath = diskPrefix + nextNode.Name;
+ NFind::CFileInfoW fileInfo;
+ if (!NFind::FindFile(fullPath, fileInfo))
+ {
+ if (!nextNode.AreThereIncludeItems())
+ continue;
+ errorCodes.Add(::GetLastError());
+ errorPaths.Add(fullPath);
+ continue;
+ }
+ if (!fileInfo.IsDirectory())
+ {
+ errorCodes.Add((DWORD)E_FAIL);
+ errorPaths.Add(fullPath);
+ continue;
+ }
+ RINOK(EnumerateDirItems(nextNode,
+ diskPrefix + fileInfo.Name + wchar_t(kDirDelimiter),
+ archivePrefix + fileInfo.Name + wchar_t(kDirDelimiter),
+ UStringVector(), dirItems, false, callback, errorPaths, errorCodes));
+ }
+ return S_OK;
+ }
+ }
+
+
+ NFind::CEnumeratorW enumerator(diskPrefix + wchar_t(kAnyStringWildcard));
+ for (;;)
+ {
+ NFind::CFileInfoW fileInfo;
+ bool found;
+ if (!enumerator.Next(fileInfo, found))
+ {
+ errorCodes.Add(::GetLastError());
+ errorPaths.Add(diskPrefix);
+ break;
+ }
+ if (!found)
+ break;
+
+ if (callback)
+ RINOK(callback->CheckBreak());
+ const UString &name = fileInfo.Name;
+ bool enterToSubFolders2 = enterToSubFolders;
+ UStringVector addArchivePrefixNew = addArchivePrefix;
+ addArchivePrefixNew.Add(name);
+ {
+ UStringVector addArchivePrefixNewTemp(addArchivePrefixNew);
+ if (curNode.CheckPathToRoot(false, addArchivePrefixNewTemp, !fileInfo.IsDirectory()))
+ continue;
+ }
+ if (curNode.CheckPathToRoot(true, addArchivePrefixNew, !fileInfo.IsDirectory()))
+ {
+ AddDirFileInfo(archivePrefix, diskPrefix + name, fileInfo, dirItems);
+ if (fileInfo.IsDirectory())
+ enterToSubFolders2 = true;
+ }
+ if (!fileInfo.IsDirectory())
+ continue;
+
+ const NWildcard::CCensorNode *nextNode = 0;
+ if (addArchivePrefix.IsEmpty())
+ {
+ int index = curNode.FindSubNode(name);
+ if (index >= 0)
+ nextNode = &curNode.SubNodes[index];
+ }
+ if (!enterToSubFolders2 && nextNode == 0)
+ continue;
+
+ addArchivePrefixNew = addArchivePrefix;
+ if (nextNode == 0)
+ {
+ nextNode = &curNode;
+ addArchivePrefixNew.Add(name);
+ }
+ RINOK(EnumerateDirItems(*nextNode,
+ diskPrefix + name + wchar_t(kDirDelimiter),
+ archivePrefix + name + wchar_t(kDirDelimiter),
+ addArchivePrefixNew, dirItems, enterToSubFolders2, callback, errorPaths, errorCodes));
+ }
+ return S_OK;
+}
+
+HRESULT EnumerateItems(
+ const NWildcard::CCensor &censor,
+ CObjectVector<CDirItem> &dirItems,
+ IEnumDirItemCallback *callback,
+ UStringVector &errorPaths,
+ CRecordVector<DWORD> &errorCodes)
+{
+ for (int i = 0; i < censor.Pairs.Size(); i++)
+ {
+ const NWildcard::CPair &pair = censor.Pairs[i];
+ RINOK(EnumerateDirItems(pair.Head, pair.Prefix, L"", UStringVector(), dirItems, false,
+ callback, errorPaths, errorCodes));
+ }
+ return S_OK;
+}
diff --git a/CPP/7zip/UI/Common/EnumDirItems.h b/CPP/7zip/UI/Common/EnumDirItems.h
new file mode 100755
index 00000000..8d5495a8
--- /dev/null
+++ b/CPP/7zip/UI/Common/EnumDirItems.h
@@ -0,0 +1,39 @@
+// EnumDirItems.h
+
+#ifndef __ENUM_DIR_ITEMS_H
+#define __ENUM_DIR_ITEMS_H
+
+#include "Common/Wildcard.h"
+#include "DirItem.h"
+
+#include "Windows/FileFind.h"
+
+void AddDirFileInfo(
+ const UString &prefix,
+ const UString &fullPathName,
+ const NWindows::NFile::NFind::CFileInfoW &fileInfo,
+ CObjectVector<CDirItem> &dirItems);
+
+
+void EnumerateDirItems(
+ const UString &baseFolderPrefix,
+ const UStringVector &fileNames,
+ const UString &archiveNamePrefix,
+ CObjectVector<CDirItem> &dirItems,
+ UStringVector &errorPaths,
+ CRecordVector<DWORD> &errorCodes);
+
+struct IEnumDirItemCallback
+{
+ virtual HRESULT CheckBreak() { return S_OK; }
+};
+
+
+HRESULT EnumerateItems(
+ const NWildcard::CCensor &censor,
+ CObjectVector<CDirItem> &dirItems,
+ IEnumDirItemCallback *callback,
+ UStringVector &errorPaths,
+ CRecordVector<DWORD> &errorCodes);
+
+#endif
diff --git a/CPP/7zip/UI/Common/ExitCode.h b/CPP/7zip/UI/Common/ExitCode.h
new file mode 100755
index 00000000..0aac3695
--- /dev/null
+++ b/CPP/7zip/UI/Common/ExitCode.h
@@ -0,0 +1,27 @@
+// ExitCode.h
+
+#ifndef __EXIT_CODE_H
+#define __EXIT_CODE_H
+
+namespace NExitCode {
+
+enum EEnum {
+
+ kSuccess = 0, // Successful operation
+ kWarning = 1, // Non fatal error(s) occurred
+ kFatalError = 2, // A fatal error occurred
+ // kCRCError = 3, // A CRC error occurred when unpacking
+ // kLockedArchive = 4, // Attempt to modify an archive previously locked
+ // kWriteError = 5, // Write to disk error
+ // kOpenError = 6, // Open file error
+ kUserError = 7, // Command line option error
+ kMemoryError = 8, // Not enough memory for operation
+ // kCreateFileError = 9, // Create file error
+
+ kUserBreak = 255 // User stopped the process
+
+};
+
+}
+
+#endif
diff --git a/CPP/7zip/UI/Common/Extract.cpp b/CPP/7zip/UI/Common/Extract.cpp
new file mode 100755
index 00000000..34fb383b
--- /dev/null
+++ b/CPP/7zip/UI/Common/Extract.cpp
@@ -0,0 +1,152 @@
+// Extract.cpp
+
+#include "StdAfx.h"
+
+#include "Extract.h"
+
+#include "Windows/Defs.h"
+#include "Windows/FileDir.h"
+
+#include "OpenArchive.h"
+#include "SetProperties.h"
+
+#ifndef EXCLUDE_COM
+#include "Windows/DLL.h"
+#endif
+
+using namespace NWindows;
+
+HRESULT DecompressArchive(
+ IInArchive *archive,
+ const UString &defaultName,
+ const NWildcard::CCensorNode &wildcardCensor,
+ const CExtractOptions &options,
+ IExtractCallbackUI *callback,
+ UString &errorMessage)
+{
+ CRecordVector<UInt32> realIndices;
+ UInt32 numItems;
+ RINOK(archive->GetNumberOfItems(&numItems));
+
+ for(UInt32 i = 0; i < numItems; i++)
+ {
+ UString filePath;
+ RINOK(GetArchiveItemPath(archive, i, options.DefaultItemName, filePath));
+ bool isFolder;
+ RINOK(IsArchiveItemFolder(archive, i, isFolder));
+ if (!wildcardCensor.CheckPath(filePath, !isFolder))
+ continue;
+ realIndices.Add(i);
+ }
+ if (realIndices.Size() == 0)
+ {
+ callback->ThereAreNoFiles();
+ return S_OK;
+ }
+
+ CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
+ CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);
+
+ UStringVector removePathParts;
+
+ UString outDir = options.OutputDir;
+ outDir.Replace(L"*", defaultName);
+ if(!outDir.IsEmpty())
+ if(!NFile::NDirectory::CreateComplexDirectory(outDir))
+ {
+ HRESULT res = ::GetLastError();
+ if (res == S_OK)
+ res = E_FAIL;
+ errorMessage = ((UString)L"Can not create output directory ") + outDir;
+ return res;
+ }
+
+ extractCallbackSpec->Init(
+ archive,
+ callback,
+ options.StdOutMode,
+ outDir,
+ options.PathMode,
+ options.OverwriteMode,
+ removePathParts,
+ options.DefaultItemName,
+ options.ArchiveFileInfo.LastWriteTime,
+ options.ArchiveFileInfo.Attributes);
+
+ #ifdef COMPRESS_MT
+ RINOK(SetProperties(archive, options.Properties));
+ #endif
+
+ HRESULT result = archive->Extract(&realIndices.Front(),
+ realIndices.Size(), options.TestMode? 1: 0,
+ extractCallback);
+
+ return callback->ExtractResult(result);
+}
+
+HRESULT DecompressArchives(
+ UStringVector &archivePaths, UStringVector &archivePathsFull,
+ const NWildcard::CCensorNode &wildcardCensor,
+ const CExtractOptions &optionsSpec,
+ IOpenCallbackUI *openCallback,
+ IExtractCallbackUI *extractCallback,
+ UString &errorMessage)
+{
+ CExtractOptions options = optionsSpec;
+ for (int i = 0; i < archivePaths.Size(); i++)
+ {
+ const UString &archivePath = archivePaths[i];
+ NFile::NFind::CFileInfoW archiveFileInfo;
+ if (!NFile::NFind::FindFile(archivePath, archiveFileInfo))
+ throw "there is no such archive";
+
+ if (archiveFileInfo.IsDirectory())
+ throw "there is no such archive";
+
+ options.ArchiveFileInfo = archiveFileInfo;
+
+ #ifndef _NO_CRYPTO
+ openCallback->ClearPasswordWasAskedFlag();
+ #endif
+
+ RINOK(extractCallback->BeforeOpen(archivePath));
+ CArchiveLink archiveLink;
+ HRESULT result = MyOpenArchive(archivePath, archiveLink, openCallback);
+
+ bool crypted = false;
+ #ifndef _NO_CRYPTO
+ crypted = openCallback->WasPasswordAsked();
+ #endif
+
+ RINOK(extractCallback->OpenResult(archivePath, result, crypted));
+ if (result != S_OK)
+ continue;
+
+ for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
+ {
+ int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]);
+ if (index >= 0 && index > i)
+ {
+ archivePaths.Delete(index);
+ archivePathsFull.Delete(index);
+ }
+ }
+
+ #ifndef _NO_CRYPTO
+ UString password;
+ RINOK(openCallback->GetPasswordIfAny(password));
+ if (!password.IsEmpty())
+ {
+ RINOK(extractCallback->SetPassword(password));
+ }
+ #endif
+
+ options.DefaultItemName = archiveLink.GetDefaultItemName();
+ RINOK(DecompressArchive(
+ archiveLink.GetArchive(), archiveLink.GetDefaultItemName(),
+ wildcardCensor, options, extractCallback, errorMessage));
+ if (!errorMessage.IsEmpty())
+ return E_FAIL;
+ }
+ return S_OK;
+}
diff --git a/CPP/7zip/UI/Common/Extract.h b/CPP/7zip/UI/Common/Extract.h
new file mode 100755
index 00000000..c7b47c84
--- /dev/null
+++ b/CPP/7zip/UI/Common/Extract.h
@@ -0,0 +1,59 @@
+// Extract.h
+
+#ifndef __EXTRACT_H
+#define __EXTRACT_H
+
+#include "Common/Wildcard.h"
+#include "Windows/FileFind.h"
+
+#include "../../Archive/IArchive.h"
+
+#include "ArchiveExtractCallback.h"
+#include "ArchiveOpenCallback.h"
+#include "ExtractMode.h"
+#include "Property.h"
+
+class CExtractOptions
+{
+public:
+ bool StdOutMode;
+ bool TestMode;
+ NExtract::NPathMode::EEnum PathMode;
+
+ UString OutputDir;
+ bool YesToAll;
+ UString DefaultItemName;
+ NWindows::NFile::NFind::CFileInfoW ArchiveFileInfo;
+
+ // bool ShowDialog;
+ // bool PasswordEnabled;
+ // UString Password;
+ #ifdef COMPRESS_MT
+ CObjectVector<CProperty> Properties;
+ #endif
+
+ NExtract::NOverwriteMode::EEnum OverwriteMode;
+
+ CExtractOptions():
+ StdOutMode(false),
+ YesToAll(false),
+ TestMode(false),
+ PathMode(NExtract::NPathMode::kFullPathnames),
+ OverwriteMode(NExtract::NOverwriteMode::kAskBefore)
+ {}
+
+ /*
+ bool FullPathMode() const { return (ExtractMode == NExtractMode::kTest) ||
+ (ExtractMode == NExtractMode::kFullPath); }
+ */
+};
+
+HRESULT DecompressArchives(
+ UStringVector &archivePaths, UStringVector &archivePathsFull,
+ const NWildcard::CCensorNode &wildcardCensor,
+ const CExtractOptions &options,
+ IOpenCallbackUI *openCallback,
+ IExtractCallbackUI *extractCallback,
+ UString &errorMessage);
+
+#endif
diff --git a/CPP/7zip/UI/Common/ExtractMode.h b/CPP/7zip/UI/Common/ExtractMode.h
new file mode 100755
index 00000000..96b5a8cd
--- /dev/null
+++ b/CPP/7zip/UI/Common/ExtractMode.h
@@ -0,0 +1,31 @@
+// ExtractMode.h
+
+#ifndef __EXTRACT_MODE_H
+#define __EXTRACT_MODE_H
+
+namespace NExtract {
+
+ namespace NPathMode
+ {
+ enum EEnum
+ {
+ kFullPathnames,
+ kCurrentPathnames,
+ kNoPathnames
+ };
+ }
+
+ namespace NOverwriteMode
+ {
+ enum EEnum
+ {
+ kAskBefore,
+ kWithoutPrompt,
+ kSkipExisting,
+ kAutoRename,
+ kAutoRenameExisting
+ };
+ }
+}
+
+#endif
diff --git a/CPP/7zip/UI/Common/ExtractingFilePath.cpp b/CPP/7zip/UI/Common/ExtractingFilePath.cpp
new file mode 100755
index 00000000..a0b17282
--- /dev/null
+++ b/CPP/7zip/UI/Common/ExtractingFilePath.cpp
@@ -0,0 +1,75 @@
+// ExtractingFilePath.cpp
+
+#include "StdAfx.h"
+#include "ExtractingFilePath.h"
+
+static void ReplaceDisk(UString &s)
+{
+ int i;
+ for (i = 0; i < s.Length(); i++)
+ if (s[i] != ' ')
+ break;
+ if (s.Length() > i + 1)
+ {
+ if (s[i + 1] == L':')
+ {
+ s.Delete(i + 1);
+ // s.Insert(i + 1, L'_');
+ }
+ }
+}
+
+UString GetCorrectFileName(const UString &path)
+{
+ UString result = path;
+ {
+ UString test = path;
+ test.Trim();
+ if (test == L"..")
+ result.Replace(L"..", L"");
+ }
+ ReplaceDisk(result);
+ return result;
+}
+
+UString GetCorrectPath(const UString &path)
+{
+ UString result = path;
+ int first;
+ for (first = 0; first < result.Length(); first++)
+ if (result[first] != ' ')
+ break;
+ while(result.Length() > first)
+ {
+ if (
+ #ifdef _WIN32
+ result[first] == L'\\' ||
+ #endif
+ result[first] == L'/')
+ {
+ result.Delete(first);
+ continue;
+ }
+ break;
+ }
+ #ifdef _WIN32
+ result.Replace(L"..\\", L"");
+ #endif
+ result.Replace(L"../", L"");
+
+ ReplaceDisk(result);
+ return result;
+}
+
+void MakeCorrectPath(UStringVector &pathParts)
+{
+ for (int i = 0; i < pathParts.Size();)
+ {
+ UString &s = pathParts[i];
+ s = GetCorrectFileName(s);
+ if (s.IsEmpty())
+ pathParts.Delete(i);
+ else
+ i++;
+ }
+}
diff --git a/CPP/7zip/UI/Common/ExtractingFilePath.h b/CPP/7zip/UI/Common/ExtractingFilePath.h
new file mode 100755
index 00000000..0ae9e9b8
--- /dev/null
+++ b/CPP/7zip/UI/Common/ExtractingFilePath.h
@@ -0,0 +1,12 @@
+// ExtractingFilePath.h
+
+#ifndef __EXTRACTINGFILEPATH_H
+#define __EXTRACTINGFILEPATH_H
+
+#include "Common/String.h"
+
+UString GetCorrectFileName(const UString &path);
+UString GetCorrectPath(const UString &path);
+void MakeCorrectPath(UStringVector &pathParts);
+
+#endif
diff --git a/CPP/7zip/UI/Common/HandlerLoader.h b/CPP/7zip/UI/Common/HandlerLoader.h
new file mode 100755
index 00000000..2a878019
--- /dev/null
+++ b/CPP/7zip/UI/Common/HandlerLoader.h
@@ -0,0 +1,38 @@
+// HandlerLoader.h
+
+#ifndef __HANDLERLOADER_H
+#define __HANDLERLOADER_H
+
+#include "../../ICoder.h"
+#include "Windows/DLL.h"
+
+typedef UInt32 (WINAPI * CreateObjectFunc)(
+ const GUID *clsID,
+ const GUID *interfaceID,
+ void **outObject);
+
+class CHandlerLoader: public NWindows::NDLL::CLibrary
+{
+public:
+ HRESULT CreateHandler(LPCWSTR filepath, REFGUID clsID,
+ void **archive, bool outHandler)
+ {
+ if (!Load(filepath))
+ return GetLastError();
+ CreateObjectFunc createObject = (CreateObjectFunc)
+ GetProcAddress("CreateObject");
+ if (createObject == NULL)
+ {
+ HRESULT res = ::GetLastError();
+ Free();
+ return res;
+ }
+ HRESULT res = createObject(&clsID,
+ outHandler ? &IID_IOutArchive : &IID_IInArchive, (void **)archive);
+ if (res != 0)
+ Free();
+ return res;
+ }
+};
+
+#endif
diff --git a/CPP/7zip/UI/Common/IFileExtractCallback.h b/CPP/7zip/UI/Common/IFileExtractCallback.h
new file mode 100755
index 00000000..c70d7021
--- /dev/null
+++ b/CPP/7zip/UI/Common/IFileExtractCallback.h
@@ -0,0 +1,46 @@
+// IFileExtractCallback.h
+
+#ifndef __IFILEEXTRACTCALLBACK_H
+#define __IFILEEXTRACTCALLBACK_H
+
+#include "Common/String.h"
+
+namespace NOverwriteAnswer
+{
+ enum EEnum
+ {
+ kYes,
+ kYesToAll,
+ kNo,
+ kNoToAll,
+ kAutoRename,
+ kCancel,
+ };
+}
+
+// {23170F69-40C1-278A-0000-000100070000}
+DEFINE_GUID(IID_IFolderArchiveExtractCallback,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000100070000")
+IFolderArchiveExtractCallback: public IProgress
+{
+public:
+ STDMETHOD(AskOverwrite)(
+ const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize,
+ const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize,
+ Int32 *answer) PURE;
+ STDMETHOD(PrepareOperation)(const wchar_t *name, Int32 askExtractMode, const UInt64 *position) PURE;
+ STDMETHOD(MessageError)(const wchar_t *message) PURE;
+ STDMETHOD(SetOperationResult)(Int32 operationResult, bool encrypted) PURE;
+};
+
+struct IExtractCallbackUI: IFolderArchiveExtractCallback
+{
+ virtual HRESULT BeforeOpen(const wchar_t *name) = 0;
+ virtual HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted) = 0;
+ virtual HRESULT ThereAreNoFiles() = 0;
+ virtual HRESULT ExtractResult(HRESULT result) = 0;
+ virtual HRESULT SetPassword(const UString &password) = 0;
+};
+
+#endif
diff --git a/CPP/7zip/UI/Common/OpenArchive.cpp b/CPP/7zip/UI/Common/OpenArchive.cpp
new file mode 100755
index 00000000..ce1a6de3
--- /dev/null
+++ b/CPP/7zip/UI/Common/OpenArchive.cpp
@@ -0,0 +1,531 @@
+// OpenArchive.cpp
+
+#include "StdAfx.h"
+
+#include "OpenArchive.h"
+
+#include "Common/Wildcard.h"
+
+#include "Windows/FileName.h"
+#include "Windows/FileDir.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+
+#include "../../Common/FileStreams.h"
+#include "../../Common/StreamUtils.h"
+
+#include "Common/StringConvert.h"
+
+#ifdef FORMAT_7Z
+#include "../../Archive/7z/7zHandler.h"
+#endif
+
+#ifdef FORMAT_BZIP2
+#include "../../Archive/BZip2/BZip2Handler.h"
+#endif
+
+#ifdef FORMAT_CAB
+#include "../../Archive/Cab/CabHandler.h"
+#endif
+
+#ifdef FORMAT_GZIP
+#include "../../Archive/GZip/GZipHandler.h"
+#endif
+
+#ifdef FORMAT_SPLIT
+#include "../../Archive/Split/SplitHandler.h"
+#endif
+
+#ifdef FORMAT_TAR
+#include "../../Archive/Tar/TarHandler.h"
+#endif
+
+#ifdef FORMAT_ZIP
+#include "../../Archive/Zip/ZipHandler.h"
+#endif
+
+#ifdef FORMAT_Z
+#include "../../Archive/Z/ZHandler.h"
+#endif
+
+#ifndef EXCLUDE_COM
+#include "HandlerLoader.h"
+#endif
+
+#include "DefaultName.h"
+
+using namespace NWindows;
+
+HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, UString &result)
+{
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetProperty(index, kpidPath, &prop));
+ if(prop.vt == VT_BSTR)
+ result = prop.bstrVal;
+ else if (prop.vt == VT_EMPTY)
+ result.Empty();
+ else
+ return E_FAIL;
+ return S_OK;
+}
+
+HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, const UString &defaultName, UString &result)
+{
+ RINOK(GetArchiveItemPath(archive, index, result));
+ if (result.IsEmpty())
+ result = defaultName;
+ return S_OK;
+}
+
+HRESULT GetArchiveItemFileTime(IInArchive *archive, UInt32 index,
+ const FILETIME &defaultFileTime, FILETIME &fileTime)
+{
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetProperty(index, kpidLastWriteTime, &prop));
+ if (prop.vt == VT_FILETIME)
+ fileTime = prop.filetime;
+ else if (prop.vt == VT_EMPTY)
+ fileTime = defaultFileTime;
+ else
+ return E_FAIL;
+ return S_OK;
+}
+
+static HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result)
+{
+ NCOM::CPropVariant prop;
+ RINOK(archive->GetProperty(index, propID, &prop));
+ if(prop.vt == VT_BOOL)
+ result = VARIANT_BOOLToBool(prop.boolVal);
+ else if (prop.vt == VT_EMPTY)
+ result = false;
+ else
+ return E_FAIL;
+ return S_OK;
+}
+
+HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result)
+{
+ return IsArchiveItemProp(archive, index, kpidIsFolder, result);
+}
+
+HRESULT IsArchiveItemAnti(IInArchive *archive, UInt32 index, bool &result)
+{
+ return IsArchiveItemProp(archive, index, kpidIsAnti, result);
+}
+
+// Static-SFX (for Linux) can be big.
+const UInt64 kMaxCheckStartPosition = 1 << 22;
+
+HRESULT ReOpenArchive(IInArchive *archive, const UString &fileName)
+{
+ CInFileStream *inStreamSpec = new CInFileStream;
+ CMyComPtr<IInStream> inStream(inStreamSpec);
+ inStreamSpec->Open(fileName);
+ return archive->Open(inStream, &kMaxCheckStartPosition, NULL);
+}
+
+#ifndef _SFX
+static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size)
+{
+ for (size_t i = 0; i < size; i++)
+ if (p1[i] != p2[i])
+ return false;
+ return true;
+}
+#endif
+
+HRESULT OpenArchive(
+ IInStream *inStream,
+ const UString &fileName,
+ #ifndef EXCLUDE_COM
+ HMODULE *module,
+ #endif
+ IInArchive **archiveResult,
+ CArchiverInfo &archiverInfoResult,
+ UString &defaultItemName,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ *archiveResult = NULL;
+ CObjectVector<CArchiverInfo> archiverInfoList;
+ ReadArchiverInfoList(archiverInfoList);
+ UString extension;
+ {
+ int dotPos = fileName.ReverseFind(L'.');
+ if (dotPos >= 0)
+ extension = fileName.Mid(dotPos + 1);
+ }
+ CIntVector orderIndices;
+ int i;
+ bool finded = false;
+ for(i = 0; i < archiverInfoList.Size(); i++)
+ {
+ if (archiverInfoList[i].FindExtension(extension) >= 0)
+ {
+ orderIndices.Insert(0, i);
+ finded = true;
+ }
+ else
+ orderIndices.Add(i);
+ }
+
+ #ifndef _SFX
+ if (!finded)
+ {
+ CByteBuffer byteBuffer;
+ const UInt32 kBufferSize = (200 << 10);
+ byteBuffer.SetCapacity(kBufferSize);
+ Byte *buffer = byteBuffer;
+ RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
+ UInt32 processedSize;
+ RINOK(ReadStream(inStream, buffer, kBufferSize, &processedSize));
+ int numFinded = 0;
+ for (int pos = (int)processedSize; pos >= 0 ; pos--)
+ {
+ for(int i = numFinded; i < orderIndices.Size(); i++)
+ {
+ int index = orderIndices[i];
+ const CArchiverInfo &ai = archiverInfoList[index];
+ const CByteBuffer &sig = ai.StartSignature;
+ if (sig.GetCapacity() == 0)
+ continue;
+ if (pos + sig.GetCapacity() > processedSize)
+ continue;
+ if (TestSignature(buffer + pos, sig, sig.GetCapacity()))
+ {
+ orderIndices.Delete(i);
+ orderIndices.Insert(0, index);
+ numFinded++;
+ }
+ }
+ }
+ }
+ #endif
+
+ HRESULT badResult = S_OK;
+ for(i = 0; i < orderIndices.Size(); i++)
+ {
+ inStream->Seek(0, STREAM_SEEK_SET, NULL);
+ const CArchiverInfo &archiverInfo = archiverInfoList[orderIndices[i]];
+ #ifndef EXCLUDE_COM
+ CHandlerLoader loader;
+ #endif
+ CMyComPtr<IInArchive> archive;
+
+ #ifdef FORMAT_7Z
+ if (archiverInfo.Name.CompareNoCase(L"7z") == 0)
+ archive = new NArchive::N7z::CHandler;
+ #endif
+
+ #ifdef FORMAT_BZIP2
+ if (archiverInfo.Name.CompareNoCase(L"BZip2") == 0)
+ archive = new NArchive::NBZip2::CHandler;
+ #endif
+
+ #ifdef FORMAT_CAB
+ if (archiverInfo.Name.CompareNoCase(L"Cab") == 0)
+ archive = new NArchive::NCab::CHandler;
+ #endif
+
+ #ifdef FORMAT_GZIP
+ if (archiverInfo.Name.CompareNoCase(L"GZip") == 0)
+ archive = new NArchive::NGZip::CHandler;
+ #endif
+
+ #ifdef FORMAT_SPLIT
+ if (archiverInfo.Name.CompareNoCase(L"Split") == 0)
+ archive = new NArchive::NSplit::CHandler;
+ #endif
+
+ #ifdef FORMAT_TAR
+ if (archiverInfo.Name.CompareNoCase(L"Tar") == 0)
+ archive = new NArchive::NTar::CHandler;
+ #endif
+
+ #ifdef FORMAT_ZIP
+ if (archiverInfo.Name.CompareNoCase(L"Zip") == 0)
+ archive = new NArchive::NZip::CHandler;
+ #endif
+
+ #ifdef FORMAT_Z
+ if (archiverInfo.Name.CompareNoCase(L"Z") == 0)
+ archive = new NArchive::NZ::CHandler;
+ #endif
+
+
+ #ifndef EXCLUDE_COM
+ if (!archive)
+ {
+ HRESULT result = loader.CreateHandler(archiverInfo.FilePath,
+ archiverInfo.ClassID, (void **)&archive, false);
+ if (result != S_OK)
+ continue;
+ }
+ #endif
+
+ if (!archive)
+ return E_FAIL;
+
+ HRESULT result = archive->Open(inStream, &kMaxCheckStartPosition, openArchiveCallback);
+ if(result == S_FALSE)
+ continue;
+ if(result != S_OK)
+ {
+ badResult = result;
+ if(result == E_ABORT)
+ break;
+ continue;
+ }
+ *archiveResult = archive.Detach();
+ #ifndef EXCLUDE_COM
+ *module = loader.Detach();
+ #endif
+ archiverInfoResult = archiverInfo;
+ int subExtIndex = archiverInfo.FindExtension(extension);
+ if (subExtIndex < 0)
+ subExtIndex = 0;
+ defaultItemName = GetDefaultName2(fileName,
+ archiverInfo.Extensions[subExtIndex].Ext,
+ archiverInfo.Extensions[subExtIndex].AddExt);
+
+ return S_OK;
+ }
+ if (badResult != S_OK)
+ return badResult;
+ return S_FALSE;
+}
+
+HRESULT OpenArchive(const UString &filePath,
+ #ifndef EXCLUDE_COM
+ HMODULE *module,
+ #endif
+ IInArchive **archiveResult,
+ CArchiverInfo &archiverInfo,
+ UString &defaultItemName,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ CInFileStream *inStreamSpec = new CInFileStream;
+ CMyComPtr<IInStream> inStream(inStreamSpec);
+ if (!inStreamSpec->Open(filePath))
+ return GetLastError();
+ return OpenArchive(inStream, ExtractFileNameFromPath(filePath),
+ #ifndef EXCLUDE_COM
+ module,
+ #endif
+ archiveResult, archiverInfo,
+ defaultItemName, openArchiveCallback);
+}
+
+static void MakeDefaultName(UString &name)
+{
+ int dotPos = name.ReverseFind(L'.');
+ if (dotPos < 0)
+ return;
+ UString ext = name.Mid(dotPos + 1);
+ if (ext.IsEmpty())
+ return;
+ for (int pos = 0; pos < ext.Length(); pos++)
+ if (ext[pos] < L'0' || ext[pos] > L'9')
+ return;
+ name = name.Left(dotPos);
+}
+
+HRESULT OpenArchive(const UString &fileName,
+ #ifndef EXCLUDE_COM
+ HMODULE *module0,
+ HMODULE *module1,
+ #endif
+ IInArchive **archive0,
+ IInArchive **archive1,
+ CArchiverInfo &archiverInfo0,
+ CArchiverInfo &archiverInfo1,
+ UString &defaultItemName0,
+ UString &defaultItemName1,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ HRESULT result = OpenArchive(fileName,
+ #ifndef EXCLUDE_COM
+ module0,
+ #endif
+ archive0, archiverInfo0, defaultItemName0, openArchiveCallback);
+ RINOK(result);
+ CMyComPtr<IInArchiveGetStream> getStream;
+ result = (*archive0)->QueryInterface(IID_IInArchiveGetStream, (void **)&getStream);
+ if (result != S_OK || getStream == 0)
+ return S_OK;
+
+ CMyComPtr<ISequentialInStream> subSeqStream;
+ result = getStream->GetStream(0, &subSeqStream);
+ if (result != S_OK)
+ return S_OK;
+
+ CMyComPtr<IInStream> subStream;
+ if (subSeqStream.QueryInterface(IID_IInStream, &subStream) != S_OK)
+ return S_OK;
+ if (!subStream)
+ return S_OK;
+
+ UInt32 numItems;
+ RINOK((*archive0)->GetNumberOfItems(&numItems));
+ if (numItems < 1)
+ return S_OK;
+
+ UString subPath;
+ RINOK(GetArchiveItemPath(*archive0, 0, subPath))
+ if (subPath.IsEmpty())
+ {
+ MakeDefaultName(defaultItemName0);
+ subPath = defaultItemName0;
+ if (archiverInfo0.Name.CompareNoCase(L"7z") == 0)
+ {
+ if (subPath.Right(3).CompareNoCase(L".7z") != 0)
+ subPath += L".7z";
+ }
+ }
+ else
+ subPath = ExtractFileNameFromPath(subPath);
+
+ CMyComPtr<IArchiveOpenSetSubArchiveName> setSubArchiveName;
+ openArchiveCallback->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName);
+ if (setSubArchiveName)
+ setSubArchiveName->SetSubArchiveName(subPath);
+
+ result = OpenArchive(subStream, subPath,
+ #ifndef EXCLUDE_COM
+ module1,
+ #endif
+ archive1, archiverInfo1, defaultItemName1, openArchiveCallback);
+ return S_OK;
+}
+
+HRESULT MyOpenArchive(const UString &archiveName,
+ #ifndef EXCLUDE_COM
+ HMODULE *module,
+ #endif
+ IInArchive **archive,
+ UString &defaultItemName,
+ IOpenCallbackUI *openCallbackUI)
+{
+ COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
+ CMyComPtr<IArchiveOpenCallback> openCallback = openCallbackSpec;
+ openCallbackSpec->Callback = openCallbackUI;
+
+ UString fullName;
+ int fileNamePartStartIndex;
+ NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartIndex);
+ openCallbackSpec->Init(
+ fullName.Left(fileNamePartStartIndex),
+ fullName.Mid(fileNamePartStartIndex));
+
+ CArchiverInfo archiverInfo;
+ return OpenArchive(archiveName,
+ #ifndef EXCLUDE_COM
+ module,
+ #endif
+ archive,
+ archiverInfo,
+ defaultItemName,
+ openCallback);
+}
+
+HRESULT MyOpenArchive(const UString &archiveName,
+ #ifndef EXCLUDE_COM
+ HMODULE *module0,
+ HMODULE *module1,
+ #endif
+ IInArchive **archive0,
+ IInArchive **archive1,
+ UString &defaultItemName0,
+ UString &defaultItemName1,
+ UStringVector &volumePaths,
+ IOpenCallbackUI *openCallbackUI)
+{
+ COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
+ CMyComPtr<IArchiveOpenCallback> openCallback = openCallbackSpec;
+ openCallbackSpec->Callback = openCallbackUI;
+
+ UString fullName;
+ int fileNamePartStartIndex;
+ NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartIndex);
+ UString prefix = fullName.Left(fileNamePartStartIndex);
+ UString name = fullName.Mid(fileNamePartStartIndex);
+ openCallbackSpec->Init(prefix, name);
+
+ CArchiverInfo archiverInfo0, archiverInfo1;
+ HRESULT result = OpenArchive(archiveName,
+ #ifndef EXCLUDE_COM
+ module0,
+ module1,
+ #endif
+ archive0,
+ archive1,
+ archiverInfo0,
+ archiverInfo1,
+ defaultItemName0,
+ defaultItemName1,
+ openCallback);
+ RINOK(result);
+ volumePaths.Add(prefix + name);
+ for (int i = 0; i < openCallbackSpec->FileNames.Size(); i++)
+ volumePaths.Add(prefix + openCallbackSpec->FileNames[i]);
+ return S_OK;
+}
+
+HRESULT CArchiveLink::Close()
+{
+ if (Archive1 != 0)
+ RINOK(Archive1->Close());
+ if (Archive0 != 0)
+ RINOK(Archive0->Close());
+ return S_OK;
+}
+
+void CArchiveLink::Release()
+{
+ if (Archive1 != 0)
+ Archive1.Release();
+ if (Archive0 != 0)
+ Archive0.Release();
+ #ifndef EXCLUDE_COM
+ Library1.Free();
+ Library0.Free();
+ #endif
+}
+
+HRESULT OpenArchive(const UString &archiveName,
+ CArchiveLink &archiveLink,
+ IArchiveOpenCallback *openCallback)
+{
+ return OpenArchive(archiveName,
+ #ifndef EXCLUDE_COM
+ &archiveLink.Library0, &archiveLink.Library1,
+ #endif
+ &archiveLink.Archive0, &archiveLink.Archive1,
+ archiveLink.ArchiverInfo0, archiveLink.ArchiverInfo1,
+ archiveLink.DefaultItemName0, archiveLink.DefaultItemName1,
+ openCallback);
+}
+
+HRESULT MyOpenArchive(const UString &archiveName,
+ CArchiveLink &archiveLink,
+ IOpenCallbackUI *openCallbackUI)
+{
+ return MyOpenArchive(archiveName,
+ #ifndef EXCLUDE_COM
+ &archiveLink.Library0, &archiveLink.Library1,
+ #endif
+ &archiveLink.Archive0, &archiveLink.Archive1,
+ archiveLink.DefaultItemName0, archiveLink.DefaultItemName1,
+ archiveLink.VolumePaths,
+ openCallbackUI);
+}
+
+HRESULT ReOpenArchive(CArchiveLink &archiveLink,
+ const UString &fileName)
+{
+ if (archiveLink.GetNumLevels() > 1)
+ return E_NOTIMPL;
+ if (archiveLink.GetNumLevels() == 0)
+ return MyOpenArchive(fileName, archiveLink, 0);
+ return ReOpenArchive(archiveLink.GetArchive(), fileName);
+}
diff --git a/CPP/7zip/UI/Common/OpenArchive.h b/CPP/7zip/UI/Common/OpenArchive.h
new file mode 100755
index 00000000..f96b1ebf
--- /dev/null
+++ b/CPP/7zip/UI/Common/OpenArchive.h
@@ -0,0 +1,134 @@
+// OpenArchive.h
+
+#ifndef __OPENARCHIVE_H
+#define __OPENARCHIVE_H
+
+#include "Common/String.h"
+#include "Windows/FileFind.h"
+
+#include "../../Archive/IArchive.h"
+#include "ArchiverInfo.h"
+#include "ArchiveOpenCallback.h"
+
+#ifndef EXCLUDE_COM
+#include "Windows/DLL.h"
+#endif
+
+HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, UString &result);
+HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, const UString &defaultName, UString &result);
+HRESULT GetArchiveItemFileTime(IInArchive *archive, UInt32 index,
+ const FILETIME &defaultFileTime, FILETIME &fileTime);
+HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result);
+HRESULT IsArchiveItemAnti(IInArchive *archive, UInt32 index, bool &result);
+
+struct ISetSubArchiveName
+{
+ virtual void SetSubArchiveName(const wchar_t *name) = 0;
+};
+
+HRESULT OpenArchive(
+ IInStream *inStream,
+ const UString &fileName,
+ #ifndef EXCLUDE_COM
+ HMODULE *module,
+ #endif
+ IInArchive **archiveResult,
+ CArchiverInfo &archiverInfoResult,
+ UString &defaultItemName,
+ IArchiveOpenCallback *openArchiveCallback);
+
+HRESULT OpenArchive(const UString &filePath,
+ #ifndef EXCLUDE_COM
+ HMODULE *module,
+ #endif
+ IInArchive **archive,
+ CArchiverInfo &archiverInfo,
+ UString &defaultItemName,
+ IArchiveOpenCallback *openArchiveCallback);
+
+HRESULT OpenArchive(const UString &filePath,
+ #ifndef EXCLUDE_COM
+ HMODULE *module0,
+ HMODULE *module1,
+ #endif
+ IInArchive **archive0,
+ IInArchive **archive1,
+ CArchiverInfo &archiverInfo0,
+ CArchiverInfo &archiverInfo1,
+ UString &defaultItemName0,
+ UString &defaultItemName1,
+ IArchiveOpenCallback *openArchiveCallback);
+
+
+HRESULT ReOpenArchive(IInArchive *archive,
+ const UString &fileName);
+
+HRESULT MyOpenArchive(const UString &archiveName,
+ #ifndef EXCLUDE_COM
+ HMODULE *module,
+ #endif
+ IInArchive **archive,
+ UString &defaultItemName,
+ IOpenCallbackUI *openCallbackUI);
+
+HRESULT MyOpenArchive(const UString &archiveName,
+ #ifndef EXCLUDE_COM
+ HMODULE *module0,
+ HMODULE *module1,
+ #endif
+ IInArchive **archive0,
+ IInArchive **archive1,
+ UString &defaultItemName0,
+ UString &defaultItemName1,
+ UStringVector &volumePaths,
+ IOpenCallbackUI *openCallbackUI);
+
+struct CArchiveLink
+{
+ #ifndef EXCLUDE_COM
+ NWindows::NDLL::CLibrary Library0;
+ NWindows::NDLL::CLibrary Library1;
+ #endif
+ CMyComPtr<IInArchive> Archive0;
+ CMyComPtr<IInArchive> Archive1;
+ UString DefaultItemName0;
+ UString DefaultItemName1;
+
+ CArchiverInfo ArchiverInfo0;
+ CArchiverInfo ArchiverInfo1;
+
+ UStringVector VolumePaths;
+
+ int GetNumLevels() const
+ {
+ int result = 0;
+ if (Archive0)
+ {
+ result++;
+ if (Archive1)
+ result++;
+ }
+ return result;
+ }
+
+
+ IInArchive *GetArchive() { return Archive1 != 0 ? Archive1: Archive0; }
+ UString GetDefaultItemName() { return Archive1 != 0 ? DefaultItemName1: DefaultItemName0; }
+ const CArchiverInfo &GetArchiverInfo() { return Archive1 != 0 ? ArchiverInfo1: ArchiverInfo0; }
+ HRESULT Close();
+ void Release();
+};
+
+HRESULT OpenArchive(const UString &archiveName,
+ CArchiveLink &archiveLink,
+ IArchiveOpenCallback *openCallback);
+
+HRESULT MyOpenArchive(const UString &archiveName,
+ CArchiveLink &archiveLink,
+ IOpenCallbackUI *openCallbackUI);
+
+HRESULT ReOpenArchive(CArchiveLink &archiveLink,
+ const UString &fileName);
+
+#endif
+
diff --git a/CPP/7zip/UI/Common/PropIDUtils.cpp b/CPP/7zip/UI/Common/PropIDUtils.cpp
new file mode 100755
index 00000000..8869e565
--- /dev/null
+++ b/CPP/7zip/UI/Common/PropIDUtils.cpp
@@ -0,0 +1,90 @@
+// PropIDUtils.cpp
+
+#include "StdAfx.h"
+
+#include "PropIDUtils.h"
+
+#include "Common/IntToString.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/FileFind.h"
+#include "Windows/PropVariantConversions.h"
+
+#include "../../PropID.h"
+
+using namespace NWindows;
+
+static UString ConvertUInt32ToString(UInt32 value)
+{
+ wchar_t buffer[32];
+ ConvertUInt64ToString(value, buffer);
+ return buffer;
+}
+
+static void ConvertUInt32ToHex(UInt32 value, wchar_t *s)
+{
+ for (int i = 0; i < 8; i++)
+ {
+ int t = value & 0xF;
+ value >>= 4;
+ s[7 - i] = (wchar_t)((t < 10) ? (L'0' + t) : (L'A' + (t - 10)));
+ }
+ s[8] = L'\0';
+}
+
+UString ConvertPropertyToString(const PROPVARIANT &propVariant,
+ PROPID propID, bool full)
+{
+ switch(propID)
+ {
+ case kpidCreationTime:
+ case kpidLastWriteTime:
+ case kpidLastAccessTime:
+ {
+ if (propVariant.vt != VT_FILETIME)
+ return UString(); // It is error;
+ FILETIME localFileTime;
+ if (propVariant.filetime.dwHighDateTime == 0 &&
+ propVariant.filetime.dwLowDateTime == 0)
+ return UString();
+ if (!::FileTimeToLocalFileTime(&propVariant.filetime, &localFileTime))
+ return UString(); // It is error;
+ return ConvertFileTimeToString(localFileTime, true, full);
+ }
+ case kpidCRC:
+ {
+ if(propVariant.vt != VT_UI4)
+ break;
+ wchar_t temp[12];
+ ConvertUInt32ToHex(propVariant.ulVal, temp);
+ return temp;
+ }
+ case kpidAttributes:
+ {
+ if(propVariant.vt != VT_UI4)
+ break;
+ UString result;
+ UInt32 attributes = propVariant.ulVal;
+ if (NFile::NFind::NAttributes::IsReadOnly(attributes)) result += L'R';
+ if (NFile::NFind::NAttributes::IsHidden(attributes)) result += L'H';
+ if (NFile::NFind::NAttributes::IsSystem(attributes)) result += L'S';
+ if (NFile::NFind::NAttributes::IsDirectory(attributes)) result += L'D';
+ if (NFile::NFind::NAttributes::IsArchived(attributes)) result += L'A';
+ if (NFile::NFind::NAttributes::IsCompressed(attributes)) result += L'C';
+ if (NFile::NFind::NAttributes::IsEncrypted(attributes)) result += L'E';
+ return result;
+ }
+ case kpidDictionarySize:
+ {
+ if(propVariant.vt != VT_UI4)
+ break;
+ UInt32 size = propVariant.ulVal;
+ if (size % (1 << 20) == 0)
+ return ConvertUInt32ToString(size >> 20) + L"MB";
+ if (size % (1 << 10) == 0)
+ return ConvertUInt32ToString(size >> 10) + L"KB";
+ return ConvertUInt32ToString(size);
+ }
+ }
+ return ConvertPropVariantToString(propVariant);
+}
diff --git a/CPP/7zip/UI/Common/PropIDUtils.h b/CPP/7zip/UI/Common/PropIDUtils.h
new file mode 100755
index 00000000..aa540885
--- /dev/null
+++ b/CPP/7zip/UI/Common/PropIDUtils.h
@@ -0,0 +1,11 @@
+// PropIDUtils.h
+
+#ifndef __PROPIDUTILS_H
+#define __PROPIDUTILS_H
+
+#include "Common/String.h"
+
+UString ConvertPropertyToString(const PROPVARIANT &aPropVariant,
+ PROPID aPropID, bool aFull = true);
+
+#endif
diff --git a/CPP/7zip/UI/Common/Property.h b/CPP/7zip/UI/Common/Property.h
new file mode 100755
index 00000000..57e7b452
--- /dev/null
+++ b/CPP/7zip/UI/Common/Property.h
@@ -0,0 +1,14 @@
+// Property.h
+
+#ifndef __PROPERTY_H
+#define __PROPERTY_H
+
+#include "Common/String.h"
+
+struct CProperty
+{
+ UString Name;
+ UString Value;
+};
+
+#endif
diff --git a/CPP/7zip/UI/Common/SetProperties.cpp b/CPP/7zip/UI/Common/SetProperties.cpp
new file mode 100755
index 00000000..6c92a847
--- /dev/null
+++ b/CPP/7zip/UI/Common/SetProperties.cpp
@@ -0,0 +1,65 @@
+// SetProperties.cpp
+
+#include "StdAfx.h"
+
+#include "SetProperties.h"
+
+#include "Windows/PropVariant.h"
+#include "Common/String.h"
+#include "Common/StringToInt.h"
+#include "Common/MyCom.h"
+
+#include "../../Archive/IArchive.h"
+
+using namespace NWindows;
+using namespace NCOM;
+
+static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop)
+{
+ const wchar_t *endPtr;
+ UInt64 result = ConvertStringToUInt64(s, &endPtr);
+ if (endPtr - (const wchar_t *)s != s.Length())
+ prop = s;
+ else if (result <= 0xFFFFFFFF)
+ prop = (UInt32)result;
+ else
+ prop = result;
+}
+
+HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &properties)
+{
+ if (properties.IsEmpty())
+ return S_OK;
+ CMyComPtr<ISetProperties> setProperties;
+ unknown->QueryInterface(IID_ISetProperties, (void **)&setProperties);
+ if (!setProperties)
+ return S_OK;
+
+ UStringVector realNames;
+ CPropVariant *values = new CPropVariant[properties.Size()];
+ try
+ {
+ int i;
+ for(i = 0; i < properties.Size(); i++)
+ {
+ const CProperty &property = properties[i];
+ NCOM::CPropVariant propVariant;
+ if (!property.Value.IsEmpty())
+ ParseNumberString(property.Value, propVariant);
+ realNames.Add(property.Name);
+ values[i] = propVariant;
+ }
+ CRecordVector<const wchar_t *> names;
+ for(i = 0; i < realNames.Size(); i++)
+ names.Add((const wchar_t *)realNames[i]);
+
+ RINOK(setProperties->SetProperties(&names.Front(), values, names.Size()));
+ }
+ catch(...)
+ {
+ delete []values;
+ throw;
+ }
+ delete []values;
+ return S_OK;
+}
diff --git a/CPP/7zip/UI/Common/SetProperties.h b/CPP/7zip/UI/Common/SetProperties.h
new file mode 100755
index 00000000..892f1a21
--- /dev/null
+++ b/CPP/7zip/UI/Common/SetProperties.h
@@ -0,0 +1,10 @@
+// SetProperties.h
+
+#ifndef __SETPROPERTIES_H
+#define __SETPROPERTIES_H
+
+#include "Property.h"
+
+HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &properties);
+
+#endif
diff --git a/CPP/7zip/UI/Common/SortUtils.cpp b/CPP/7zip/UI/Common/SortUtils.cpp
new file mode 100755
index 00000000..c0111581
--- /dev/null
+++ b/CPP/7zip/UI/Common/SortUtils.cpp
@@ -0,0 +1,78 @@
+// SortUtils.cpp
+
+#include "StdAfx.h"
+
+#include "SortUtils.h"
+#include "Common/Types.h"
+
+/*
+template <class T>
+void TSortRefDown(T *p, UInt32 k, UInt32 size, int (*compare)(const T*, const T*, void *), void *param)
+{
+ T temp = p[k];
+ for (;;)
+ {
+ UInt32 s = (k << 1);
+ if (s > size)
+ break;
+ if (s < size && compare(p + s + 1, p + s, param) > 0)
+ s++;
+ if (compare(&temp, p + s, param) >= 0)
+ break;
+ p[k] = p[s];
+ k = s;
+ }
+ p[k] = temp;
+}
+
+template <class T>
+void TSort(T* p, UInt32 size, int (*compare)(const T*, const T*, void *), void *param)
+{
+ if (size <= 1)
+ return;
+ p--;
+ {
+ UInt32 i = size / 2;
+ do
+ TSortRefDown(p, i, size, compare, param);
+ while(--i != 0);
+ }
+ do
+ {
+ T temp = p[size];
+ p[size--] = p[1];
+ p[1] = temp;
+ TSortRefDown(p, 1, size, compare, param);
+ }
+ while (size > 1);
+}
+*/
+
+static int CompareStrings(const int *p1, const int *p2, void *param)
+{
+ 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();
+ int numItems = strings.Size();
+ indices.Reserve(numItems);
+ for(int i = 0; i < numItems; i++)
+ indices.Add(i);
+ indices.Sort(CompareStrings, (void *)&strings);
+ // TSort(&indices.Front(), indices.Size(), CompareStrings, (void *)&strings);
+}
+
+void SortStrings(const UStringVector &src, UStringVector &dest)
+{
+ CIntVector indices;
+ SortStringsToIndices(src, indices);
+ dest.Clear();
+ dest.Reserve(indices.Size());
+ for (int i = 0; i < indices.Size(); i++)
+ dest.Add(src[indices[i]]);
+}
diff --git a/CPP/7zip/UI/Common/SortUtils.h b/CPP/7zip/UI/Common/SortUtils.h
new file mode 100755
index 00000000..5b9af264
--- /dev/null
+++ b/CPP/7zip/UI/Common/SortUtils.h
@@ -0,0 +1,11 @@
+// SortUtils.h
+
+#ifndef __SORTUTLS_H
+#define __SORTUTLS_H
+
+#include "Common/String.h"
+
+void SortStringsToIndices(const UStringVector &strings, CIntVector &indices);
+void SortStrings(const UStringVector &src, UStringVector &dest);
+
+#endif
diff --git a/CPP/7zip/UI/Common/StdAfx.h b/CPP/7zip/UI/Common/StdAfx.h
new file mode 100755
index 00000000..100f4344
--- /dev/null
+++ b/CPP/7zip/UI/Common/StdAfx.h
@@ -0,0 +1,9 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/UI/Common/TempFiles.cpp b/CPP/7zip/UI/Common/TempFiles.cpp
new file mode 100755
index 00000000..3e604aea
--- /dev/null
+++ b/CPP/7zip/UI/Common/TempFiles.cpp
@@ -0,0 +1,22 @@
+// TempFiles.cpp
+
+#include "StdAfx.h"
+
+#include "TempFiles.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileIO.h"
+
+using namespace NWindows;
+using namespace NFile;
+
+void CTempFiles::Clear()
+{
+ while(!Paths.IsEmpty())
+ {
+ NDirectory::DeleteFileAlways(Paths.Back());
+ Paths.DeleteBack();
+ }
+}
+
+
diff --git a/CPP/7zip/UI/Common/TempFiles.h b/CPP/7zip/UI/Common/TempFiles.h
new file mode 100755
index 00000000..173713a0
--- /dev/null
+++ b/CPP/7zip/UI/Common/TempFiles.h
@@ -0,0 +1,16 @@
+// TempFiles.h
+
+#ifndef __TEMPFILES_H
+#define __TEMPFILES_H
+
+#include "Common/String.h"
+
+class CTempFiles
+{
+ void Clear();
+public:
+ UStringVector Paths;
+ ~CTempFiles() { Clear(); }
+};
+
+#endif
diff --git a/CPP/7zip/UI/Common/Update.cpp b/CPP/7zip/UI/Common/Update.cpp
new file mode 100755
index 00000000..cd7975d0
--- /dev/null
+++ b/CPP/7zip/UI/Common/Update.cpp
@@ -0,0 +1,818 @@
+// Update.cpp
+
+#include "StdAfx.h"
+
+#ifdef _WIN32
+#include <mapi.h>
+#endif
+
+#include "Update.h"
+
+#include "Common/IntToString.h"
+#include "Common/StringConvert.h"
+#include "Common/CommandLineParser.h"
+
+#ifdef _WIN32
+#include "Windows/DLL.h"
+#endif
+
+#include "Windows/Defs.h"
+#include "Windows/FileDir.h"
+#include "Windows/FileFind.h"
+#include "Windows/FileName.h"
+#include "Windows/PropVariant.h"
+#include "Windows/PropVariantConversions.h"
+// #include "Windows/Synchronization.h"
+
+#include "../../Common/FileStreams.h"
+#include "../../Compress/Copy/CopyCoder.h"
+
+#include "../Common/DirItem.h"
+#include "../Common/EnumDirItems.h"
+#include "../Common/UpdateProduce.h"
+#include "../Common/OpenArchive.h"
+
+#include "TempFiles.h"
+#include "UpdateCallback.h"
+#include "EnumDirItems.h"
+#include "SetProperties.h"
+
+#ifdef FORMAT_7Z
+#include "../../Archive/7z/7zHandler.h"
+#endif
+
+#ifdef FORMAT_BZIP2
+#include "../../Archive/BZip2/BZip2Handler.h"
+#endif
+
+#ifdef FORMAT_GZIP
+#include "../../Archive/GZip/GZipHandler.h"
+#endif
+
+#ifdef FORMAT_TAR
+#include "../../Archive/Tar/TarHandler.h"
+#endif
+
+#ifdef FORMAT_ZIP
+#include "../../Archive/Zip/ZipHandler.h"
+#endif
+
+#ifndef EXCLUDE_COM
+#include "../Common/HandlerLoader.h"
+#endif
+
+static const char *kUpdateIsNotSupoorted =
+ "update operations are not supported for this archive";
+
+using namespace NCommandLineParser;
+using namespace NWindows;
+using namespace NCOM;
+using namespace NFile;
+using namespace NName;
+
+static const wchar_t *kTempArchiveFilePrefixString = L"7zi";
+static const wchar_t *kTempFolderPrefix = L"7zE";
+
+static const char *kIllegalFileNameMessage = "Illegal file name for temp archive";
+
+using namespace NUpdateArchive;
+
+static HRESULT CopyBlock(ISequentialInStream *inStream, ISequentialOutStream *outStream)
+{
+ CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
+ return copyCoder->Code(inStream, outStream, NULL, NULL, NULL);
+}
+
+class COutMultiVolStream:
+ public IOutStream,
+ public CMyUnknownImp
+{
+ int _streamIndex; // required stream
+ UInt64 _offsetPos; // offset from start of _streamIndex index
+ UInt64 _absPos;
+ UInt64 _length;
+
+ struct CSubStreamInfo
+ {
+ CMyComPtr<IOutStream> Stream;
+ UString Name;
+ UInt64 Pos;
+ UInt64 RealSize;
+ };
+ CObjectVector<CSubStreamInfo> Streams;
+public:
+ // CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
+ CRecordVector<UInt64> Sizes;
+ UString Prefix;
+ CTempFiles *TempFiles;
+
+ void Init()
+ {
+ _streamIndex = 0;
+ _offsetPos = 0;
+ _absPos = 0;
+ _length = 0;
+ }
+
+ MY_UNKNOWN_IMP1(IOutStream)
+
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+ STDMETHOD(SetSize)(Int64 newSize);
+};
+
+// static NSynchronization::CCriticalSection g_TempPathsCS;
+
+STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if(processedSize != NULL)
+ *processedSize = 0;
+ while(size > 0)
+ {
+ if (_streamIndex >= Streams.Size())
+ {
+ CSubStreamInfo subStream;
+
+ wchar_t temp[32];
+ ConvertUInt64ToString(_streamIndex + 1, temp);
+ UString res = temp;
+ while (res.Length() < 3)
+ res = UString(L'0') + res;
+ UString name = Prefix + res;
+ COutFileStream *streamSpec = new COutFileStream;
+ subStream.Stream = streamSpec;
+ if(!streamSpec->Create(name, false))
+ return ::GetLastError();
+ {
+ // NSynchronization::CCriticalSectionLock lock(g_TempPathsCS);
+ TempFiles->Paths.Add(name);
+ }
+
+ subStream.Pos = 0;
+ subStream.RealSize = 0;
+ subStream.Name = name;
+ Streams.Add(subStream);
+ continue;
+ }
+ CSubStreamInfo &subStream = Streams[_streamIndex];
+
+ int index = _streamIndex;
+ if (index >= Sizes.Size())
+ index = Sizes.Size() - 1;
+ UInt64 volSize = Sizes[index];
+
+ if (_offsetPos >= volSize)
+ {
+ _offsetPos -= volSize;
+ _streamIndex++;
+ continue;
+ }
+ if (_offsetPos != subStream.Pos)
+ {
+ // CMyComPtr<IOutStream> outStream;
+ // RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream));
+ RINOK(subStream.Stream->Seek(_offsetPos, STREAM_SEEK_SET, NULL));
+ subStream.Pos = _offsetPos;
+ }
+
+ UInt32 curSize = (UInt32)MyMin((UInt64)size, volSize - subStream.Pos);
+ UInt32 realProcessed;
+ RINOK(subStream.Stream->Write(data, curSize, &realProcessed));
+ data = (void *)((Byte *)data + realProcessed);
+ size -= realProcessed;
+ subStream.Pos += realProcessed;
+ _offsetPos += realProcessed;
+ _absPos += realProcessed;
+ if (_absPos > _length)
+ _length = _absPos;
+ if (_offsetPos > subStream.RealSize)
+ subStream.RealSize = _offsetPos;
+ if(processedSize != NULL)
+ *processedSize += realProcessed;
+ if (subStream.Pos == volSize)
+ {
+ _streamIndex++;
+ _offsetPos = 0;
+ }
+ if (realProcessed == 0 && curSize != 0)
+ return E_FAIL;
+ break;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP COutMultiVolStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+{
+ if(seekOrigin >= 3)
+ return STG_E_INVALIDFUNCTION;
+ switch(seekOrigin)
+ {
+ case STREAM_SEEK_SET:
+ _absPos = offset;
+ break;
+ case STREAM_SEEK_CUR:
+ _absPos += offset;
+ break;
+ case STREAM_SEEK_END:
+ _absPos = _length + offset;
+ break;
+ }
+ _offsetPos = _absPos;
+ if (newPosition != NULL)
+ *newPosition = _absPos;
+ _streamIndex = 0;
+ return S_OK;
+}
+
+STDMETHODIMP COutMultiVolStream::SetSize(Int64 newSize)
+{
+ if (newSize < 0)
+ return E_INVALIDARG;
+ int i = 0;
+ while (i < Streams.Size())
+ {
+ CSubStreamInfo &subStream = Streams[i++];
+ if ((UInt64)newSize < subStream.RealSize)
+ {
+ RINOK(subStream.Stream->SetSize(newSize));
+ subStream.RealSize = newSize;
+ break;
+ }
+ newSize -= subStream.RealSize;
+ }
+ while (i < Streams.Size())
+ {
+ {
+ CSubStreamInfo &subStream = Streams.Back();
+ subStream.Stream.Release();
+ NDirectory::DeleteFileAlways(subStream.Name);
+ }
+ Streams.DeleteBack();
+ }
+ _offsetPos = _absPos;
+ _streamIndex = 0;
+ _length = newSize;
+ return S_OK;
+}
+
+
+static HRESULT Compress(
+ const CActionSet &actionSet,
+ IInArchive *archive,
+ const CCompressionMethodMode &compressionMethod,
+ CArchivePath &archivePath,
+ const CObjectVector<CArchiveItem> &archiveItems,
+ bool stdInMode,
+ /* const UString & stdInFileName, */
+ bool stdOutMode,
+ const CObjectVector<CDirItem> &dirItems,
+ bool sfxMode,
+ const UString &sfxModule,
+ const CRecordVector<UInt64> &volumesSizes,
+ CTempFiles &tempFiles,
+ CUpdateErrorInfo &errorInfo,
+ IUpdateCallbackUI *callback)
+{
+ #ifndef EXCLUDE_COM
+ CHandlerLoader loader;
+ #endif
+
+ CMyComPtr<IOutArchive> outArchive;
+ if(archive != NULL)
+ {
+ CMyComPtr<IInArchive> archive2 = archive;
+ HRESULT result = archive2.QueryInterface(IID_IOutArchive, &outArchive);
+ if(result != S_OK)
+ throw kUpdateIsNotSupoorted;
+ }
+ else
+ {
+ #ifndef EXCLUDE_COM
+
+ if (loader.CreateHandler(compressionMethod.FilePath,
+ compressionMethod.ClassID, (void **)&outArchive, true) != S_OK)
+ throw kUpdateIsNotSupoorted;
+ #endif
+
+ #ifdef FORMAT_7Z
+ if (compressionMethod.Name.CompareNoCase(L"7z") == 0)
+ outArchive = new NArchive::N7z::CHandler;
+ #endif
+
+ #ifdef FORMAT_BZIP2
+ if (compressionMethod.Name.CompareNoCase(L"BZip2") == 0)
+ outArchive = new NArchive::NBZip2::CHandler;
+ #endif
+
+ #ifdef FORMAT_GZIP
+ if (compressionMethod.Name.CompareNoCase(L"GZip") == 0)
+ outArchive = new NArchive::NGZip::CHandler;
+ #endif
+
+ #ifdef FORMAT_TAR
+ if (compressionMethod.Name.CompareNoCase(L"Tar") == 0)
+ outArchive = new NArchive::NTar::CHandler;
+ #endif
+
+ #ifdef FORMAT_ZIP
+ if (compressionMethod.Name.CompareNoCase(L"Zip") == 0)
+ outArchive = new NArchive::NZip::CHandler;
+ #endif
+
+ }
+ if (outArchive == 0)
+ throw kUpdateIsNotSupoorted;
+
+ NFileTimeType::EEnum fileTimeType;
+ UInt32 value;
+ RINOK(outArchive->GetFileTimeType(&value));
+
+ switch(value)
+ {
+ case NFileTimeType::kWindows:
+ case NFileTimeType::kDOS:
+ case NFileTimeType::kUnix:
+ fileTimeType = NFileTimeType::EEnum(value);
+ break;
+ default:
+ return E_FAIL;
+ }
+
+ CObjectVector<CUpdatePair> updatePairs;
+ GetUpdatePairInfoList(dirItems, archiveItems, fileTimeType, updatePairs); // must be done only once!!!
+
+ CObjectVector<CUpdatePair2> updatePairs2;
+ UpdateProduce(updatePairs, actionSet, updatePairs2);
+
+ CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
+ CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec );
+
+ updateCallbackSpec->StdInMode = stdInMode;
+ updateCallbackSpec->Callback = callback;
+ updateCallbackSpec->DirItems = &dirItems;
+ updateCallbackSpec->ArchiveItems = &archiveItems;
+ updateCallbackSpec->UpdatePairs = &updatePairs2;
+
+ CMyComPtr<ISequentialOutStream> outStream;
+
+ const UString &archiveName = archivePath.GetFinalPath();
+ if (!stdOutMode)
+ {
+ UString resultPath;
+ int pos;
+ if(!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos))
+ throw 1417161;
+ NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos));
+ }
+ if (volumesSizes.Size() == 0)
+ {
+ if (stdOutMode)
+ outStream = new CStdOutFileStream;
+ else
+ {
+ COutFileStream *outStreamSpec = new COutFileStream;
+ outStream = outStreamSpec;
+ bool isOK = false;
+ UString realPath;
+ for (int i = 0; i < (1 << 16); i++)
+ {
+ if (archivePath.Temp)
+ {
+ if (i > 0)
+ {
+ wchar_t s[32];
+ ConvertUInt64ToString(i, s);
+ archivePath.TempPostfix = s;
+ }
+ realPath = archivePath.GetTempPath();
+ }
+ else
+ realPath = archivePath.GetFinalPath();
+ if (outStreamSpec->Create(realPath, false))
+ {
+ tempFiles.Paths.Add(realPath);
+ isOK = true;
+ break;
+ }
+ if (::GetLastError() != ERROR_FILE_EXISTS)
+ break;
+ if (!archivePath.Temp)
+ break;
+ }
+ if (!isOK)
+ {
+ errorInfo.SystemError = ::GetLastError();
+ errorInfo.FileName = realPath;
+ errorInfo.Message = L"Can not open file";
+ return E_FAIL;
+ }
+ }
+ }
+ else
+ {
+ if (stdOutMode)
+ return E_FAIL;
+ COutMultiVolStream *volStreamSpec = new COutMultiVolStream;
+ outStream = volStreamSpec;
+ volStreamSpec->Sizes = volumesSizes;
+ volStreamSpec->Prefix = archivePath.GetFinalPath() + UString(L".");
+ volStreamSpec->TempFiles = &tempFiles;
+ volStreamSpec->Init();
+
+ /*
+ updateCallbackSpec->VolumesSizes = volumesSizes;
+ updateCallbackSpec->VolName = archivePath.Prefix + archivePath.Name;
+ if (!archivePath.VolExtension.IsEmpty())
+ updateCallbackSpec->VolExt = UString(L'.') + archivePath.VolExtension;
+ */
+ }
+
+ RINOK(SetProperties(outArchive, compressionMethod.Properties));
+
+ if (sfxMode)
+ {
+ CInFileStream *sfxStreamSpec = new CInFileStream;
+ CMyComPtr<IInStream> sfxStream(sfxStreamSpec);
+ if (!sfxStreamSpec->Open(sfxModule))
+ {
+ errorInfo.SystemError = ::GetLastError();
+ errorInfo.Message = L"Can't open sfx module";
+ errorInfo.FileName = sfxModule;
+ return E_FAIL;
+ }
+
+ CMyComPtr<ISequentialOutStream> sfxOutStream;
+ if (volumesSizes.Size() == 0)
+ sfxOutStream = outStream;
+ else
+ {
+ COutFileStream *outStreamSpec = new COutFileStream;
+ sfxOutStream = outStreamSpec;
+ UString realPath = archivePath.GetFinalPath();
+ if (!outStreamSpec->Create(realPath, false))
+ {
+ errorInfo.SystemError = ::GetLastError();
+ errorInfo.FileName = realPath;
+ errorInfo.Message = L"Can not open file";
+ return E_FAIL;
+ }
+ }
+ RINOK(CopyBlock(sfxStream, sfxOutStream));
+ }
+
+ HRESULT result = outArchive->UpdateItems(outStream, updatePairs2.Size(),
+ updateCallback);
+ callback->Finilize();
+ return result;
+}
+
+
+
+HRESULT EnumerateInArchiveItems(const NWildcard::CCensor &censor,
+ IInArchive *archive,
+ const UString &defaultItemName,
+ const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,
+ CObjectVector<CArchiveItem> &archiveItems)
+{
+ archiveItems.Clear();
+ UInt32 numItems;
+ RINOK(archive->GetNumberOfItems(&numItems));
+ archiveItems.Reserve(numItems);
+ for(UInt32 i = 0; i < numItems; i++)
+ {
+ CArchiveItem ai;
+
+ RINOK(GetArchiveItemPath(archive, i, ai.Name));
+ RINOK(IsArchiveItemFolder(archive, i, ai.IsDirectory));
+ ai.Censored = censor.CheckPath(ai.Name.IsEmpty() ? defaultItemName : ai.Name, !ai.IsDirectory);
+ RINOK(GetArchiveItemFileTime(archive, i,
+ archiveFileInfo.LastWriteTime, ai.LastWriteTime));
+
+ CPropVariant propertySize;
+ RINOK(archive->GetProperty(i, kpidSize, &propertySize));
+ ai.SizeIsDefined = (propertySize.vt != VT_EMPTY);
+ if (ai.SizeIsDefined)
+ ai.Size = ConvertPropVariantToUInt64(propertySize);
+
+ ai.IndexInServer = i;
+ archiveItems.Add(ai);
+ }
+ return S_OK;
+}
+
+
+static HRESULT UpdateWithItemLists(
+ CUpdateOptions &options,
+ IInArchive *archive,
+ const CObjectVector<CArchiveItem> &archiveItems,
+ const CObjectVector<CDirItem> &dirItems,
+ CTempFiles &tempFiles,
+ CUpdateErrorInfo &errorInfo,
+ IUpdateCallbackUI2 *callback)
+{
+ for(int i = 0; i < options.Commands.Size(); i++)
+ {
+ CUpdateArchiveCommand &command = options.Commands[i];
+ if (options.StdOutMode)
+ {
+ RINOK(callback->StartArchive(0, archive != 0));
+ }
+ else
+ {
+ RINOK(callback->StartArchive(command.ArchivePath.GetFinalPath(),
+ i == 0 && options.UpdateArchiveItself && archive != 0));
+ }
+
+ RINOK(Compress(command.ActionSet, archive,
+ options.MethodMode,
+ command.ArchivePath,
+ archiveItems,
+ options.StdInMode,
+ /* options.StdInFileName, */
+ options.StdOutMode,
+ dirItems,
+ options.SfxMode, options.SfxModule,
+ options.VolumesSizes,
+ tempFiles,
+ errorInfo, callback));
+
+ RINOK(callback->FinishArchive());
+ }
+ return S_OK;
+}
+
+#ifdef _WIN32
+class CCurrentDirRestorer
+{
+ UString m_CurrentDirectory;
+public:
+ CCurrentDirRestorer()
+ { NFile::NDirectory::MyGetCurrentDirectory(m_CurrentDirectory); }
+ ~CCurrentDirRestorer()
+ { RestoreDirectory();}
+ bool RestoreDirectory()
+ { return BOOLToBool(NFile::NDirectory::MySetCurrentDirectory(m_CurrentDirectory)); }
+};
+#endif
+
+struct CEnumDirItemUpdateCallback: public IEnumDirItemCallback
+{
+ IUpdateCallbackUI2 *Callback;
+ HRESULT CheckBreak() { return Callback->CheckBreak(); }
+};
+
+HRESULT UpdateArchive(const NWildcard::CCensor &censor,
+ CUpdateOptions &options,
+ CUpdateErrorInfo &errorInfo,
+ IOpenCallbackUI *openCallback,
+ IUpdateCallbackUI2 *callback)
+{
+ if (options.StdOutMode && options.EMailMode)
+ return E_FAIL;
+
+ if (options.VolumesSizes.Size() > 0 && (options.EMailMode || options.SfxMode))
+ return E_NOTIMPL;
+
+ if (options.SfxMode)
+ {
+ CProperty property;
+ property.Name = L"rsfx";
+ property.Value = L"on";
+ options.MethodMode.Properties.Add(property);
+ if (options.SfxModule.IsEmpty())
+ {
+ errorInfo.Message = L"sfx file is not specified";
+ return E_FAIL;
+ }
+ UString name = options.SfxModule;
+ if (!NDirectory::MySearchPath(NULL, name, NULL, options.SfxModule))
+ {
+ errorInfo.Message = L"can't find specified sfx module";
+ return E_FAIL;
+ }
+ }
+
+ const UString archiveName = options.ArchivePath.GetFinalPath();
+
+ UString defaultItemName;
+ NFind::CFileInfoW archiveFileInfo;
+
+ CArchiveLink archiveLink;
+ IInArchive *archive = 0;
+ if (NFind::FindFile(archiveName, archiveFileInfo))
+ {
+ if (archiveFileInfo.IsDirectory())
+ throw "there is no such archive";
+ if (options.VolumesSizes.Size() > 0)
+ return E_NOTIMPL;
+ HRESULT result = MyOpenArchive(archiveName, archiveLink, openCallback);
+ RINOK(callback->OpenResult(archiveName, result));
+ RINOK(result);
+ if (archiveLink.VolumePaths.Size() > 1)
+ {
+ errorInfo.SystemError = (DWORD)E_NOTIMPL;
+ errorInfo.Message = L"Updating for multivolume archives is not implemented";
+ return E_NOTIMPL;
+ }
+ archive = archiveLink.GetArchive();
+ defaultItemName = archiveLink.GetDefaultItemName();
+ }
+ else
+ {
+ /*
+ if (archiveType.IsEmpty())
+ throw "type of archive is not specified";
+ */
+ }
+
+ CObjectVector<CDirItem> dirItems;
+ if (options.StdInMode)
+ {
+ CDirItem item;
+ item.FullPath = item.Name = options.StdInFileName;
+ item.Size = (UInt64)(Int64)-1;
+ item.Attributes = 0;
+ SYSTEMTIME st;
+ FILETIME ft;
+ GetSystemTime(&st);
+ SystemTimeToFileTime(&st, &ft);
+ item.CreationTime = item.LastAccessTime = item.LastWriteTime = ft;
+ dirItems.Add(item);
+ }
+ else
+ {
+ bool needScanning = false;
+ for(int i = 0; i < options.Commands.Size(); i++)
+ if (options.Commands[i].ActionSet.NeedScanning())
+ needScanning = true;
+ if (needScanning)
+ {
+ CEnumDirItemUpdateCallback enumCallback;
+ enumCallback.Callback = callback;
+ RINOK(callback->StartScanning());
+ UStringVector errorPaths;
+ CRecordVector<DWORD> errorCodes;
+ HRESULT res = EnumerateItems(censor, dirItems, &enumCallback, errorPaths, errorCodes);
+ for (int i = 0; i < errorPaths.Size(); i++)
+ {
+ RINOK(callback->CanNotFindError(errorPaths[i], errorCodes[i]));
+ }
+ if(res != S_OK)
+ {
+ errorInfo.Message = L"Scanning error";
+ // errorInfo.FileName = errorPath;
+ return res;
+ }
+ RINOK(callback->FinishScanning());
+ }
+ }
+
+ UString tempDirPrefix;
+ bool usesTempDir = false;
+
+ #ifdef _WIN32
+ NDirectory::CTempDirectoryW tempDirectory;
+ if (options.EMailMode && options.EMailRemoveAfter)
+ {
+ tempDirectory.Create(kTempFolderPrefix);
+ tempDirPrefix = tempDirectory.GetPath();
+ NormalizeDirPathPrefix(tempDirPrefix);
+ usesTempDir = true;
+ }
+ #endif
+
+ CTempFiles tempFiles;
+
+ bool createTempFile = false;
+ if(!options.StdOutMode && options.UpdateArchiveItself)
+ {
+ CArchivePath &ap = options.Commands[0].ArchivePath;
+ ap = options.ArchivePath;
+ // if ((archive != 0 && !usesTempDir) || !options.WorkingDir.IsEmpty())
+ if ((archive != 0 || !options.WorkingDir.IsEmpty()) && !usesTempDir && options.VolumesSizes.Size() == 0)
+ {
+ createTempFile = true;
+ ap.Temp = true;
+ if (!options.WorkingDir.IsEmpty())
+ {
+ ap.TempPrefix = options.WorkingDir;
+ NormalizeDirPathPrefix(ap.TempPrefix);
+ }
+ }
+ }
+
+ for(int i = 0; i < options.Commands.Size(); i++)
+ {
+ CArchivePath &ap = options.Commands[i].ArchivePath;
+ if (usesTempDir)
+ {
+ // Check it
+ ap.Prefix = tempDirPrefix;
+ // ap.Temp = true;
+ // ap.TempPrefix = tempDirPrefix;
+ }
+ if (i > 0 || !createTempFile)
+ {
+ const UString &path = ap.GetFinalPath();
+ if (NFind::DoesFileExist(path))
+ {
+ errorInfo.SystemError = 0;
+ errorInfo.Message = L"File already exists";
+ errorInfo.FileName = path;
+ return E_FAIL;
+ }
+ }
+ }
+
+ CObjectVector<CArchiveItem> archiveItems;
+ if (archive != NULL)
+ {
+ RINOK(EnumerateInArchiveItems(censor,
+ archive, defaultItemName, archiveFileInfo, archiveItems));
+ }
+
+ RINOK(UpdateWithItemLists(options, archive, archiveItems, dirItems,
+ tempFiles, errorInfo, callback));
+
+ if (archive != NULL)
+ {
+ RINOK(archiveLink.Close());
+ archiveLink.Release();
+ }
+
+ tempFiles.Paths.Clear();
+ if(createTempFile)
+ {
+ try
+ {
+ CArchivePath &ap = options.Commands[0].ArchivePath;
+ const UString &tempPath = ap.GetTempPath();
+ if (archive != NULL)
+ if (!NDirectory::DeleteFileAlways(archiveName))
+ {
+ errorInfo.SystemError = ::GetLastError();
+ errorInfo.Message = L"delete file error";
+ errorInfo.FileName = archiveName;
+ return E_FAIL;
+ }
+ if (!NDirectory::MyMoveFile(tempPath, archiveName))
+ {
+ errorInfo.SystemError = ::GetLastError();
+ errorInfo.Message = L"move file error";
+ errorInfo.FileName = tempPath;
+ errorInfo.FileName2 = archiveName;
+ return E_FAIL;
+ }
+ }
+ catch(...)
+ {
+ throw;
+ }
+ }
+
+ #ifdef _WIN32
+ if (options.EMailMode)
+ {
+ NDLL::CLibrary mapiLib;
+ if (!mapiLib.Load(TEXT("Mapi32.dll")))
+ {
+ errorInfo.SystemError = ::GetLastError();
+ errorInfo.Message = L"can not load Mapi32.dll";
+ return E_FAIL;
+ }
+ LPMAPISENDDOCUMENTS fnSend = (LPMAPISENDDOCUMENTS)
+ mapiLib.GetProcAddress("MAPISendDocuments");
+ if (fnSend == 0)
+ {
+ errorInfo.SystemError = ::GetLastError();
+ errorInfo.Message = L"can not find MAPISendDocuments function";
+ return E_FAIL;
+ }
+ UStringVector fullPaths;
+ int i;
+ for(i = 0; i < options.Commands.Size(); i++)
+ {
+ CArchivePath &ap = options.Commands[i].ArchivePath;
+ UString arcPath;
+ if(!NFile::NDirectory::MyGetFullPathName(ap.GetFinalPath(), arcPath))
+ {
+ errorInfo.SystemError = ::GetLastError();
+ return E_FAIL;
+ }
+ fullPaths.Add(arcPath);
+ }
+ CCurrentDirRestorer curDirRestorer;
+ for(i = 0; i < fullPaths.Size(); i++)
+ {
+ UString arcPath = fullPaths[i];
+ UString fileName = ExtractFileNameFromPath(arcPath);
+ AString path = GetAnsiString(arcPath);
+ AString name = GetAnsiString(fileName);
+ // Warning!!! MAPISendDocuments function changes Current directory
+ fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0);
+ }
+ }
+ #endif
+ return S_OK;
+}
+
diff --git a/CPP/7zip/UI/Common/Update.h b/CPP/7zip/UI/Common/Update.h
new file mode 100755
index 00000000..465acc24
--- /dev/null
+++ b/CPP/7zip/UI/Common/Update.h
@@ -0,0 +1,158 @@
+// Update.h
+
+#ifndef __UPDATE_H
+#define __UPDATE_H
+
+#include "Common/Wildcard.h"
+#include "Windows/FileFind.h"
+#include "../../Archive/IArchive.h"
+
+#include "UpdateAction.h"
+#include "ArchiveOpenCallback.h"
+#include "UpdateCallback.h"
+#include "Property.h"
+
+struct CArchivePath
+{
+ UString Prefix; // path(folder) prefix including slash
+ UString Name; // base name
+ UString BaseExtension; // archive type extension or "exe" extension
+ UString VolExtension; // archive type extension for volumes
+
+ bool Temp;
+ UString TempPrefix; // path(folder) for temp location
+ UString TempPostfix;
+
+ CArchivePath(): Temp(false) {};
+
+ void ParseFromPath(const UString &path)
+ {
+ SplitPathToParts(path, Prefix, Name);
+ if (Name.IsEmpty())
+ return;
+ int dotPos = Name.ReverseFind(L'.');
+ if (dotPos <= 0)
+ return;
+ if (dotPos == Name.Length() - 1)
+ {
+ Name = Name.Left(dotPos);
+ BaseExtension.Empty();
+ return;
+ }
+ if (BaseExtension.CompareNoCase(Name.Mid(dotPos + 1)) == 0)
+ {
+ BaseExtension = Name.Mid(dotPos + 1);
+ Name = Name.Left(dotPos);
+ }
+ else
+ BaseExtension.Empty();
+ }
+
+ UString GetPathWithoutExt() const
+ {
+ return Prefix + Name;
+ }
+
+ UString GetFinalPath() const
+ {
+ UString path = GetPathWithoutExt();
+ if (!BaseExtension.IsEmpty())
+ path += UString(L'.') + BaseExtension;
+ return path;
+ }
+
+
+ UString GetTempPath() const
+ {
+ UString path = TempPrefix + Name;
+ if (!BaseExtension.IsEmpty())
+ path += UString(L'.') + BaseExtension;
+ path += L".tmp";
+ path += TempPostfix;
+ return path;
+ }
+};
+
+struct CUpdateArchiveCommand
+{
+ CArchivePath ArchivePath;
+ NUpdateArchive::CActionSet ActionSet;
+};
+
+struct CCompressionMethodMode
+{
+ #ifndef EXCLUDE_COM
+ UString FilePath;
+ CLSID ClassID;
+ #else
+ UString Name;
+ #endif
+ CObjectVector<CProperty> Properties;
+};
+
+struct CUpdateOptions
+{
+ CCompressionMethodMode MethodMode;
+
+ CObjectVector<CUpdateArchiveCommand> Commands;
+ bool UpdateArchiveItself;
+ CArchivePath ArchivePath;
+
+ bool SfxMode;
+ UString SfxModule;
+
+ bool StdInMode;
+ UString StdInFileName;
+ bool StdOutMode;
+
+ bool EMailMode;
+ bool EMailRemoveAfter;
+ UString EMailAddress;
+
+ UString WorkingDir;
+
+ CUpdateOptions():
+ UpdateArchiveItself(true),
+ SfxMode(false),
+ StdInMode(false),
+ StdOutMode(false),
+ EMailMode(false),
+ EMailRemoveAfter(false)
+ {};
+ CRecordVector<UInt64> VolumesSizes;
+};
+
+struct CErrorInfo
+{
+ DWORD SystemError;
+ UString FileName;
+ UString FileName2;
+ UString Message;
+ // UStringVector ErrorPaths;
+ // CRecordVector<DWORD> ErrorCodes;
+ CErrorInfo(): SystemError(0) {};
+};
+
+struct CUpdateErrorInfo: public CErrorInfo
+{
+};
+
+struct IUpdateCallbackUI2: public IUpdateCallbackUI
+{
+ virtual HRESULT OpenResult(const wchar_t *name, HRESULT result) = 0;
+
+ virtual HRESULT StartScanning() = 0;
+ virtual HRESULT CanNotFindError(const wchar_t *name, DWORD systemError) = 0;
+ virtual HRESULT FinishScanning() = 0;
+
+ virtual HRESULT StartArchive(const wchar_t *name, bool updating) = 0;
+ virtual HRESULT FinishArchive() = 0;
+};
+
+HRESULT UpdateArchive(const NWildcard::CCensor &censor,
+ CUpdateOptions &options,
+ CUpdateErrorInfo &errorInfo,
+ IOpenCallbackUI *openCallback,
+ IUpdateCallbackUI2 *callback);
+
+#endif
diff --git a/CPP/7zip/UI/Common/UpdateAction.cpp b/CPP/7zip/UI/Common/UpdateAction.cpp
new file mode 100755
index 00000000..5e3b5a10
--- /dev/null
+++ b/CPP/7zip/UI/Common/UpdateAction.cpp
@@ -0,0 +1,64 @@
+// UpdateAction.cpp
+
+#include "StdAfx.h"
+
+#include "UpdateAction.h"
+
+namespace NUpdateArchive {
+
+const CActionSet kAddActionSet =
+{
+ NPairAction::kCopy,
+ NPairAction::kCopy,
+ NPairAction::kCompress,
+ NPairAction::kCompress,
+ NPairAction::kCompress,
+ NPairAction::kCompress,
+ NPairAction::kCompress
+};
+
+const CActionSet kUpdateActionSet =
+{
+ NPairAction::kCopy,
+ NPairAction::kCopy,
+ NPairAction::kCompress,
+ NPairAction::kCopy,
+ NPairAction::kCompress,
+ NPairAction::kCopy,
+ NPairAction::kCompress
+};
+
+const CActionSet kFreshActionSet =
+{
+ NPairAction::kCopy,
+ NPairAction::kCopy,
+ NPairAction::kIgnore,
+ NPairAction::kCopy,
+ NPairAction::kCompress,
+ NPairAction::kCopy,
+ NPairAction::kCompress
+};
+
+const CActionSet kSynchronizeActionSet =
+{
+ NPairAction::kCopy,
+ NPairAction::kIgnore,
+ NPairAction::kCompress,
+ NPairAction::kCopy,
+ NPairAction::kCompress,
+ NPairAction::kCopy,
+ NPairAction::kCompress,
+};
+
+const CActionSet kDeleteActionSet =
+{
+ NPairAction::kCopy,
+ NPairAction::kIgnore,
+ NPairAction::kIgnore,
+ NPairAction::kIgnore,
+ NPairAction::kIgnore,
+ NPairAction::kIgnore,
+ NPairAction::kIgnore
+};
+
+}
diff --git a/CPP/7zip/UI/Common/UpdateAction.h b/CPP/7zip/UI/Common/UpdateAction.h
new file mode 100755
index 00000000..aa050975
--- /dev/null
+++ b/CPP/7zip/UI/Common/UpdateAction.h
@@ -0,0 +1,57 @@
+// UpdateAction.h
+
+#ifndef __UPDATE_ACTION_H
+#define __UPDATE_ACTION_H
+
+namespace NUpdateArchive {
+
+ namespace NPairState
+ {
+ const int kNumValues = 7;
+ enum EEnum
+ {
+ kNotMasked = 0,
+ kOnlyInArchive,
+ kOnlyOnDisk,
+ kNewInArchive,
+ kOldInArchive,
+ kSameFiles,
+ kUnknowNewerFiles
+ };
+ }
+ namespace NPairAction
+ {
+ enum EEnum
+ {
+ kIgnore = 0,
+ kCopy,
+ kCompress,
+ kCompressAsAnti
+ };
+ }
+ struct CActionSet
+ {
+ NPairAction::EEnum StateActions[NPairState::kNumValues];
+ bool NeedScanning() const
+ {
+ int i;
+ for (i = 0; i < NPairState::kNumValues; i++)
+ if (StateActions[i] == NPairAction::kCompress)
+ return true;
+ for (i = 1; i < NPairState::kNumValues; i++)
+ if (StateActions[i] != NPairAction::kIgnore)
+ return true;
+ return false;
+ }
+ };
+ extern const CActionSet kAddActionSet;
+ extern const CActionSet kUpdateActionSet;
+ extern const CActionSet kFreshActionSet;
+ extern const CActionSet kSynchronizeActionSet;
+ extern const CActionSet kDeleteActionSet;
+};
+
+
+#endif
+
+
diff --git a/CPP/7zip/UI/Common/UpdateCallback.cpp b/CPP/7zip/UI/Common/UpdateCallback.cpp
new file mode 100755
index 00000000..db3bf805
--- /dev/null
+++ b/CPP/7zip/UI/Common/UpdateCallback.cpp
@@ -0,0 +1,258 @@
+// UpdateCallback.cpp
+
+#include "StdAfx.h"
+
+#include "UpdateCallback.h"
+
+#include "Common/StringConvert.h"
+#include "Common/IntToString.h"
+#include "Common/Defs.h"
+#include "Common/ComTry.h"
+
+#include "Windows/PropVariant.h"
+
+#include "../../Common/FileStreams.h"
+
+using namespace NWindows;
+
+CArchiveUpdateCallback::CArchiveUpdateCallback():
+ Callback(0),
+ StdInMode(false),
+ DirItems(0),
+ ArchiveItems(0),
+ UpdatePairs(0)
+ {}
+
+
+STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size)
+{
+ COM_TRY_BEGIN
+ return Callback->SetTotal(size);
+ COM_TRY_END
+}
+
+STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue)
+{
+ COM_TRY_BEGIN
+ return Callback->SetCompleted(completeValue);
+ COM_TRY_END
+}
+
+/*
+STATPROPSTG kProperties[] =
+{
+ { NULL, kpidPath, VT_BSTR},
+ { NULL, kpidIsFolder, VT_BOOL},
+ { NULL, kpidSize, VT_UI8},
+ { NULL, kpidLastAccessTime, VT_FILETIME},
+ { NULL, kpidCreationTime, VT_FILETIME},
+ { NULL, kpidLastWriteTime, VT_FILETIME},
+ { NULL, kpidAttributes, VT_UI4},
+ { NULL, kpidIsAnti, VT_BOOL}
+};
+*/
+
+STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **)
+{
+ return E_NOTIMPL;
+ /*
+ return CStatPropEnumerator::CreateEnumerator(kProperties,
+ sizeof(kProperties) / sizeof(kProperties[0]), enumerator);
+ */
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index,
+ Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive)
+{
+ COM_TRY_BEGIN
+ RINOK(Callback->CheckBreak());
+ const CUpdatePair2 &updatePair = (*UpdatePairs)[index];
+ if(newData != NULL)
+ *newData = BoolToInt(updatePair.NewData);
+ if(newProperties != NULL)
+ *newProperties = BoolToInt(updatePair.NewProperties);
+ if(indexInArchive != NULL)
+ {
+ if (updatePair.ExistInArchive)
+ {
+ if (ArchiveItems == 0)
+ *indexInArchive = updatePair.ArchiveItemIndex;
+ else
+ *indexInArchive = (*ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer;
+ }
+ else
+ *indexInArchive = UInt32(-1);
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ const CUpdatePair2 &updatePair = (*UpdatePairs)[index];
+ NWindows::NCOM::CPropVariant propVariant;
+
+ if (propID == kpidIsAnti)
+ {
+ propVariant = updatePair.IsAnti;
+ propVariant.Detach(value);
+ return S_OK;
+ }
+
+ if (updatePair.IsAnti)
+ {
+ switch(propID)
+ {
+ case kpidIsFolder:
+ case kpidPath:
+ break;
+ case kpidSize:
+ propVariant = (UInt64)0;
+ propVariant.Detach(value);
+ return S_OK;
+ default:
+ propVariant.Detach(value);
+ return S_OK;
+ }
+ }
+
+ if(updatePair.ExistOnDisk)
+ {
+ const CDirItem &dirItem = (*DirItems)[updatePair.DirItemIndex];
+ switch(propID)
+ {
+ case kpidPath:
+ propVariant = dirItem.Name;
+ break;
+ case kpidIsFolder:
+ propVariant = dirItem.IsDirectory();
+ break;
+ case kpidSize:
+ propVariant = dirItem.Size;
+ break;
+ case kpidAttributes:
+ propVariant = dirItem.Attributes;
+ break;
+ case kpidLastAccessTime:
+ propVariant = dirItem.LastAccessTime;
+ break;
+ case kpidCreationTime:
+ propVariant = dirItem.CreationTime;
+ break;
+ case kpidLastWriteTime:
+ propVariant = dirItem.LastWriteTime;
+ break;
+ }
+ }
+ else
+ {
+ if (propID == kpidPath)
+ {
+ if (updatePair.NewNameIsDefined)
+ {
+ propVariant = updatePair.NewName;
+ propVariant.Detach(value);
+ return S_OK;
+ }
+ }
+ if (updatePair.ExistInArchive && Archive)
+ {
+ UInt32 indexInArchive;
+ if (ArchiveItems == 0)
+ indexInArchive = updatePair.ArchiveItemIndex;
+ else
+ indexInArchive = (*ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer;
+ return Archive->GetProperty(indexInArchive, propID, value);
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
+{
+ COM_TRY_BEGIN
+ const CUpdatePair2 &updatePair = (*UpdatePairs)[index];
+ if(!updatePair.NewData)
+ return E_FAIL;
+
+ RINOK(Callback->CheckBreak());
+ RINOK(Callback->Finilize());
+
+ if(updatePair.IsAnti)
+ {
+ return Callback->GetStream((*ArchiveItems)[updatePair.ArchiveItemIndex].Name, true);
+ }
+ const CDirItem &dirItem = (*DirItems)[updatePair.DirItemIndex];
+ RINOK(Callback->GetStream(dirItem.Name, false));
+
+ if(dirItem.IsDirectory())
+ return S_OK;
+
+ if (StdInMode)
+ {
+ CStdInFileStream *inStreamSpec = new CStdInFileStream;
+ CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
+ *inStream = inStreamLoc.Detach();
+ }
+ else
+ {
+ CInFileStream *inStreamSpec = new CInFileStream;
+ CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
+ UString path = DirPrefix + dirItem.FullPath;
+ if(!inStreamSpec->Open(path))
+ {
+ return Callback->OpenFileError(path, ::GetLastError());
+ }
+ *inStream = inStreamLoc.Detach();
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 operationResult)
+{
+ COM_TRY_BEGIN
+ return Callback->SetOperationResult(operationResult);
+ COM_TRY_END
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)
+{
+ if (VolumesSizes.Size() == 0)
+ return S_FALSE;
+ if (index >= (UInt32)VolumesSizes.Size())
+ index = VolumesSizes.Size() - 1;
+ *size = VolumesSizes[index];
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)
+{
+ COM_TRY_BEGIN
+ wchar_t temp[32];
+ ConvertUInt64ToString(index + 1, temp);
+ UString res = temp;
+ while (res.Length() < 2)
+ res = UString(L'0') + res;
+ UString fileName = VolName;
+ fileName += L'.';
+ fileName += res;
+ fileName += VolExt;
+ COutFileStream *streamSpec = new COutFileStream;
+ CMyComPtr<ISequentialOutStream> streamLoc(streamSpec);
+ if(!streamSpec->Create(fileName, false))
+ return ::GetLastError();
+ *volumeStream = streamLoc.Detach();
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
+{
+ COM_TRY_BEGIN
+ return Callback->CryptoGetTextPassword2(passwordIsDefined, password);
+ COM_TRY_END
+}
diff --git a/CPP/7zip/UI/Common/UpdateCallback.h b/CPP/7zip/UI/Common/UpdateCallback.h
new file mode 100755
index 00000000..8b14a9dc
--- /dev/null
+++ b/CPP/7zip/UI/Common/UpdateCallback.h
@@ -0,0 +1,70 @@
+// UpdateCallback.h
+
+#ifndef __UPDATECALLBACK_H
+#define __UPDATECALLBACK_H
+
+#include "Common/MyCom.h"
+#include "Common/String.h"
+
+#include "../../IPassword.h"
+
+#include "../Common/UpdatePair.h"
+#include "../Common/UpdateProduce.h"
+
+struct IUpdateCallbackUI
+{
+ virtual HRESULT SetTotal(UInt64 size) = 0;
+ virtual HRESULT SetCompleted(const UInt64 *completeValue) = 0;
+ virtual HRESULT CheckBreak() = 0;
+ virtual HRESULT Finilize() = 0;
+ virtual HRESULT GetStream(const wchar_t *name, bool isAnti) = 0;
+ virtual HRESULT OpenFileError(const wchar_t *name, DWORD systemError) = 0;
+ virtual HRESULT SetOperationResult(Int32 operationResult) = 0;
+ virtual HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) = 0;
+ virtual HRESULT CloseProgress() { return S_OK; };
+};
+
+class CArchiveUpdateCallback:
+ public IArchiveUpdateCallback2,
+ public ICryptoGetTextPassword2,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP2(IArchiveUpdateCallback2,
+ ICryptoGetTextPassword2)
+
+ // IProgress
+ STDMETHOD(SetTotal)(UInt64 size);
+ STDMETHOD(SetCompleted)(const UInt64 *completeValue);
+
+ // IUpdateCallback
+ STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator);
+ STDMETHOD(GetUpdateItemInfo)(UInt32 index,
+ Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive);
+ STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream);
+ STDMETHOD(SetOperationResult)(Int32 operationResult);
+
+ STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size);
+ STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream);
+
+ STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password);
+
+public:
+ CRecordVector<UInt64> VolumesSizes;
+ UString VolName;
+ UString VolExt;
+
+ IUpdateCallbackUI *Callback;
+
+ UString DirPrefix;
+ bool StdInMode;
+ const CObjectVector<CDirItem> *DirItems;
+ const CObjectVector<CArchiveItem> *ArchiveItems;
+ const CObjectVector<CUpdatePair2> *UpdatePairs;
+ CMyComPtr<IInArchive> Archive;
+
+ CArchiveUpdateCallback();
+};
+
+#endif
diff --git a/CPP/7zip/UI/Common/UpdatePair.cpp b/CPP/7zip/UI/Common/UpdatePair.cpp
new file mode 100755
index 00000000..dd51646f
--- /dev/null
+++ b/CPP/7zip/UI/Common/UpdatePair.cpp
@@ -0,0 +1,175 @@
+// UpdatePair.cpp
+
+#include "StdAfx.h"
+
+#include <time.h>
+
+#include "Common/Defs.h"
+#include "Windows/Time.h"
+
+#include "UpdatePair.h"
+#include "SortUtils.h"
+
+using namespace NWindows;
+using namespace NTime;
+
+static int MyCompareTime(NFileTimeType::EEnum fileTimeType,
+ const FILETIME &time1, const FILETIME &time2)
+{
+ switch(fileTimeType)
+ {
+ case NFileTimeType::kWindows:
+ return ::CompareFileTime(&time1, &time2);
+ case NFileTimeType::kUnix:
+ {
+ UInt32 unixTime1, unixTime2;
+ if (!FileTimeToUnixTime(time1, unixTime1))
+ {
+ unixTime1 = 0;
+ // throw 4191614;
+ }
+ if (!FileTimeToUnixTime(time2, unixTime2))
+ {
+ unixTime2 = 0;
+ // throw 4191615;
+ }
+ return MyCompare(unixTime1, unixTime2);
+ }
+ case NFileTimeType::kDOS:
+ {
+ UInt32 dosTime1, dosTime2;
+ FileTimeToDosTime(time1, dosTime1);
+ FileTimeToDosTime(time2, dosTime2);
+ /*
+ if (!FileTimeToDosTime(time1, dosTime1))
+ throw 4191616;
+ if (!FileTimeToDosTime(time2, dosTime2))
+ throw 4191617;
+ */
+ return MyCompare(dosTime1, dosTime2);
+ }
+ }
+ throw 4191618;
+}
+
+static const wchar_t *kDuplicateFileNameMessage = L"Duplicate filename:";
+
+/*
+static const char *kNotCensoredCollisionMessaged = "Internal file name collision:\n";
+static const char *kSameTimeChangedSizeCollisionMessaged =
+ "Collision between files with same date/time and different sizes:\n";
+*/
+
+static inline int MyFileNameCompare(const UString &s1, const UString &s2)
+{
+ return
+ #ifdef _WIN32
+ s1.CompareNoCase(s2);
+ #else
+ s1.Compare(s2);
+ #endif
+}
+
+static void TestDuplicateString(const UStringVector &strings, const CIntVector &indices)
+{
+ for(int i = 0; i + 1 < indices.Size(); i++)
+ if (MyFileNameCompare(strings[indices[i]], strings[indices[i + 1]]) == 0)
+ {
+ UString message = kDuplicateFileNameMessage;
+ message += L"\n";
+ message += strings[indices[i]];
+ message += L"\n";
+ message += strings[indices[i + 1]];
+ throw message;
+ }
+}
+
+void GetUpdatePairInfoList(
+ const CObjectVector<CDirItem> &dirItems,
+ const CObjectVector<CArchiveItem> &archiveItems,
+ NFileTimeType::EEnum fileTimeType,
+ CObjectVector<CUpdatePair> &updatePairs)
+{
+ CIntVector dirIndices, archiveIndices;
+ UStringVector dirNames, archiveNames;
+
+ int numDirItems = dirItems.Size();
+ int i;
+ for(i = 0; i < numDirItems; i++)
+ dirNames.Add(dirItems[i].Name);
+ SortStringsToIndices(dirNames, dirIndices);
+ TestDuplicateString(dirNames, dirIndices);
+
+ int numArchiveItems = archiveItems.Size();
+ for(i = 0; i < numArchiveItems; i++)
+ archiveNames.Add(archiveItems[i].Name);
+ SortStringsToIndices(archiveNames, archiveIndices);
+ TestDuplicateString(archiveNames, archiveIndices);
+
+ int dirItemIndex = 0, archiveItemIndex = 0;
+ CUpdatePair pair;
+ while(dirItemIndex < numDirItems && archiveItemIndex < numArchiveItems)
+ {
+ int dirItemIndex2 = dirIndices[dirItemIndex],
+ archiveItemIndex2 = archiveIndices[archiveItemIndex];
+ const CDirItem &dirItem = dirItems[dirItemIndex2];
+ const CArchiveItem &archiveItem = archiveItems[archiveItemIndex2];
+ int compareResult = MyFileNameCompare(dirItem.Name, archiveItem.Name);
+ if (compareResult < 0)
+ {
+ pair.State = NUpdateArchive::NPairState::kOnlyOnDisk;
+ pair.DirItemIndex = dirItemIndex2;
+ dirItemIndex++;
+ }
+ else if (compareResult > 0)
+ {
+ pair.State = archiveItem.Censored ?
+ NUpdateArchive::NPairState::kOnlyInArchive: NUpdateArchive::NPairState::kNotMasked;
+ pair.ArchiveItemIndex = archiveItemIndex2;
+ archiveItemIndex++;
+ }
+ else
+ {
+ if (!archiveItem.Censored)
+ throw 1082022;; // TTString(kNotCensoredCollisionMessaged + dirItem.Name);
+ pair.DirItemIndex = dirItemIndex2;
+ pair.ArchiveItemIndex = archiveItemIndex2;
+ switch (MyCompareTime(fileTimeType, dirItem.LastWriteTime, archiveItem.LastWriteTime))
+ {
+ case -1:
+ pair.State = NUpdateArchive::NPairState::kNewInArchive;
+ break;
+ case 1:
+ pair.State = NUpdateArchive::NPairState::kOldInArchive;
+ break;
+ default:
+ if (archiveItem.SizeIsDefined)
+ if (dirItem.Size != archiveItem.Size)
+ // throw 1082034; // kSameTimeChangedSizeCollisionMessaged;
+ pair.State = NUpdateArchive::NPairState::kUnknowNewerFiles;
+ else
+ pair.State = NUpdateArchive::NPairState::kSameFiles;
+ else
+ pair.State = NUpdateArchive::NPairState::kUnknowNewerFiles;
+ }
+ dirItemIndex++;
+ archiveItemIndex++;
+ }
+ updatePairs.Add(pair);
+ }
+ for(;dirItemIndex < numDirItems; dirItemIndex++)
+ {
+ pair.State = NUpdateArchive::NPairState::kOnlyOnDisk;
+ pair.DirItemIndex = dirIndices[dirItemIndex];
+ updatePairs.Add(pair);
+ }
+ for(;archiveItemIndex < numArchiveItems; archiveItemIndex++)
+ {
+ int archiveItemIndex2 = archiveIndices[archiveItemIndex];
+ const CArchiveItem &archiveItem = archiveItems[archiveItemIndex2];
+ pair.State = archiveItem.Censored ?
+ NUpdateArchive::NPairState::kOnlyInArchive: NUpdateArchive::NPairState::kNotMasked;
+ pair.ArchiveItemIndex = archiveItemIndex2;
+ updatePairs.Add(pair);
+ }
+}
diff --git a/CPP/7zip/UI/Common/UpdatePair.h b/CPP/7zip/UI/Common/UpdatePair.h
new file mode 100755
index 00000000..f50a23f8
--- /dev/null
+++ b/CPP/7zip/UI/Common/UpdatePair.h
@@ -0,0 +1,24 @@
+// UpdatePair.h
+
+#ifndef __UPDATE_PAIR_H
+#define __UPDATE_PAIR_H
+
+#include "DirItem.h"
+#include "UpdateAction.h"
+
+#include "../../Archive/IArchive.h"
+
+struct CUpdatePair
+{
+ NUpdateArchive::NPairState::EEnum State;
+ int ArchiveItemIndex;
+ int DirItemIndex;
+};
+
+void GetUpdatePairInfoList(
+ const CObjectVector<CDirItem> &dirItems,
+ const CObjectVector<CArchiveItem> &archiveItems,
+ NFileTimeType::EEnum fileTimeType,
+ CObjectVector<CUpdatePair> &updatePairs);
+
+#endif
diff --git a/CPP/7zip/UI/Common/UpdateProduce.cpp b/CPP/7zip/UI/Common/UpdateProduce.cpp
new file mode 100755
index 00000000..992bbeec
--- /dev/null
+++ b/CPP/7zip/UI/Common/UpdateProduce.cpp
@@ -0,0 +1,63 @@
+// UpdateProduce.cpp
+
+#include "StdAfx.h"
+
+#include "UpdateProduce.h"
+
+using namespace NUpdateArchive;
+
+static const char *kUpdateActionSetCollision =
+ "Internal collision in update action set";
+
+void UpdateProduce(
+ const CObjectVector<CUpdatePair> &updatePairs,
+ const NUpdateArchive::CActionSet &actionSet,
+ CObjectVector<CUpdatePair2> &operationChain)
+{
+ for(int i = 0; i < updatePairs.Size(); i++)
+ {
+ // CUpdateArchiveRange aRange;
+ const CUpdatePair &pair = updatePairs[i];
+
+ CUpdatePair2 pair2;
+ pair2.IsAnti = false;
+ pair2.ArchiveItemIndex = pair.ArchiveItemIndex;
+ pair2.DirItemIndex = pair.DirItemIndex;
+ pair2.ExistInArchive = (pair.State != NPairState::kOnlyOnDisk);
+ pair2.ExistOnDisk = (pair.State != NPairState::kOnlyInArchive);
+ switch(actionSet.StateActions[pair.State])
+ {
+ case NPairAction::kIgnore:
+ /*
+ if (pair.State != NPairState::kOnlyOnDisk)
+ IgnoreArchiveItem(m_ArchiveItems[pair.ArchiveItemIndex]);
+ // cout << "deleting";
+ */
+ break;
+ case NPairAction::kCopy:
+ {
+ if (pair.State == NPairState::kOnlyOnDisk)
+ throw kUpdateActionSetCollision;
+ pair2.NewData = pair2.NewProperties = false;
+ operationChain.Add(pair2);
+ break;
+ }
+ case NPairAction::kCompress:
+ {
+ if (pair.State == NPairState::kOnlyInArchive ||
+ pair.State == NPairState::kNotMasked)
+ throw kUpdateActionSetCollision;
+ pair2.NewData = pair2.NewProperties = true;
+ operationChain.Add(pair2);
+ break;
+ }
+ case NPairAction::kCompressAsAnti:
+ {
+ pair2.IsAnti = true;
+ pair2.NewData = pair2.NewProperties = true;
+ operationChain.Add(pair2);
+ break;
+ }
+ }
+ }
+}
diff --git a/CPP/7zip/UI/Common/UpdateProduce.h b/CPP/7zip/UI/Common/UpdateProduce.h
new file mode 100755
index 00000000..8f58dab9
--- /dev/null
+++ b/CPP/7zip/UI/Common/UpdateProduce.h
@@ -0,0 +1,31 @@
+// UpdateProduce.h
+
+#ifndef __UPDATE_PRODUCE_H
+#define __UPDATE_PRODUCE_H
+
+#include "UpdatePair.h"
+
+struct CUpdatePair2
+{
+ // bool OperationIsCompress;
+ bool NewData;
+ bool NewProperties;
+
+ bool ExistInArchive;
+ bool ExistOnDisk;
+ bool IsAnti;
+ int ArchiveItemIndex;
+ int DirItemIndex;
+
+ bool NewNameIsDefined;
+ UString NewName;
+
+ CUpdatePair2(): NewNameIsDefined(false) {}
+};
+
+void UpdateProduce(
+ const CObjectVector<CUpdatePair> &updatePairs,
+ const NUpdateArchive::CActionSet &actionSet,
+ CObjectVector<CUpdatePair2> &operationChain);
+
+#endif
diff --git a/CPP/7zip/UI/Common/WorkDir.cpp b/CPP/7zip/UI/Common/WorkDir.cpp
new file mode 100755
index 00000000..8db6f4f1
--- /dev/null
+++ b/CPP/7zip/UI/Common/WorkDir.cpp
@@ -0,0 +1,64 @@
+// WorkDir.cpp
+
+#include "StdAfx.h"
+
+#include "WorkDir.h"
+
+#include "Common/StringConvert.h"
+#include "Common/Wildcard.h"
+
+#include "Windows/FileName.h"
+#include "Windows/FileDir.h"
+
+static inline UINT GetCurrentCodePage()
+ { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NName;
+
+UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const UString &path)
+{
+ NWorkDir::NMode::EEnum mode = workDirInfo.Mode;
+ if (workDirInfo.ForRemovableOnly)
+ {
+ mode = NWorkDir::NMode::kCurrent;
+ UString prefix = path.Left(3);
+ if (prefix[1] == L':' && prefix[2] == L'\\')
+ {
+ UINT driveType = GetDriveType(GetSystemString(prefix, GetCurrentCodePage()));
+ if (driveType == DRIVE_CDROM || driveType == DRIVE_REMOVABLE)
+ mode = workDirInfo.Mode;
+ }
+ /*
+ CParsedPath parsedPath;
+ parsedPath.ParsePath(archiveName);
+ UINT driveType = GetDriveType(parsedPath.Prefix);
+ if ((driveType != DRIVE_CDROM) && (driveType != DRIVE_REMOVABLE))
+ mode = NZipSettings::NWorkDir::NMode::kCurrent;
+ */
+ }
+ switch(mode)
+ {
+ case NWorkDir::NMode::kCurrent:
+ {
+ return ExtractDirPrefixFromPath(path);
+ }
+ case NWorkDir::NMode::kSpecified:
+ {
+ UString tempDir = workDirInfo.Path;
+ NormalizeDirPathPrefix(tempDir);
+ return tempDir;
+ }
+ default:
+ {
+ UString tempDir;
+ if(!NFile::NDirectory::MyGetTempPath(tempDir))
+ throw 141717;
+ return tempDir;
+ }
+ }
+}
+
+
+
diff --git a/CPP/7zip/UI/Common/WorkDir.h b/CPP/7zip/UI/Common/WorkDir.h
new file mode 100755
index 00000000..0643d67a
--- /dev/null
+++ b/CPP/7zip/UI/Common/WorkDir.h
@@ -0,0 +1,10 @@
+// WorkDir.h
+
+#ifndef __WORKDIR_H
+#define __WORKDIR_H
+
+#include "ZipRegistry.h"
+
+UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const UString &path);
+
+#endif
diff --git a/CPP/7zip/UI/Common/ZipRegistry.cpp b/CPP/7zip/UI/Common/ZipRegistry.cpp
new file mode 100755
index 00000000..e449d6b4
--- /dev/null
+++ b/CPP/7zip/UI/Common/ZipRegistry.cpp
@@ -0,0 +1,420 @@
+// ZipRegistry.cpp
+
+#include "StdAfx.h"
+
+#include "ZipRegistry.h"
+
+#include "Common/IntToString.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/Synchronization.h"
+#include "Windows/Registry.h"
+
+#include "Windows/FileDir.h"
+
+using namespace NWindows;
+using namespace NRegistry;
+
+static const TCHAR *kCUBasePath = TEXT("Software\\7-ZIP");
+
+// static const TCHAR *kArchiversKeyName = TEXT("Archivers");
+
+static NSynchronization::CCriticalSection g_RegistryOperationsCriticalSection;
+
+//////////////////////
+// ExtractionInfo
+
+static const TCHAR *kExtractionKeyName = TEXT("Extraction");
+
+static const TCHAR *kExtractionPathHistoryKeyName = TEXT("PathHistory");
+static const TCHAR *kExtractionExtractModeValueName = TEXT("ExtarctMode");
+static const TCHAR *kExtractionOverwriteModeValueName = TEXT("OverwriteMode");
+static const TCHAR *kExtractionShowPasswordValueName = TEXT("ShowPassword");
+
+static CSysString GetKeyPath(const CSysString &path)
+{
+ return CSysString(kCUBasePath) + CSysString('\\') + CSysString(path);
+}
+
+void SaveExtractionInfo(const NExtract::CInfo &info)
+{
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ CKey extractionKey;
+ extractionKey.Create(HKEY_CURRENT_USER, GetKeyPath(kExtractionKeyName));
+ extractionKey.RecurseDeleteKey(kExtractionPathHistoryKeyName);
+ {
+ CKey pathHistoryKey;
+ pathHistoryKey.Create(extractionKey, kExtractionPathHistoryKeyName);
+ for(int i = 0; i < info.Paths.Size(); i++)
+ {
+ wchar_t numberString[16];
+ ConvertUInt64ToString(i, numberString);
+ pathHistoryKey.SetValue(numberString, info.Paths[i]);
+ }
+ }
+ extractionKey.SetValue(kExtractionExtractModeValueName, UInt32(info.PathMode));
+ extractionKey.SetValue(kExtractionOverwriteModeValueName, UInt32(info.OverwriteMode));
+ extractionKey.SetValue(kExtractionShowPasswordValueName, info.ShowPassword);
+}
+
+void ReadExtractionInfo(NExtract::CInfo &info)
+{
+ info.Paths.Clear();
+ info.PathMode = NExtract::NPathMode::kCurrentPathnames;
+ info.OverwriteMode = NExtract::NOverwriteMode::kAskBefore;
+ info.ShowPassword = false;
+
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ CKey extractionKey;
+ if(extractionKey.Open(HKEY_CURRENT_USER, GetKeyPath(kExtractionKeyName), KEY_READ) != ERROR_SUCCESS)
+ return;
+
+ {
+ CKey pathHistoryKey;
+ if(pathHistoryKey.Open(extractionKey, kExtractionPathHistoryKeyName, KEY_READ) ==
+ ERROR_SUCCESS)
+ {
+ for (;;)
+ {
+ wchar_t numberString[16];
+ ConvertUInt64ToString(info.Paths.Size(), numberString);
+ UString path;
+ if (pathHistoryKey.QueryValue(numberString, path) != ERROR_SUCCESS)
+ break;
+ info.Paths.Add(path);
+ }
+ }
+ }
+ UInt32 extractModeIndex;
+ if (extractionKey.QueryValue(kExtractionExtractModeValueName, extractModeIndex) == ERROR_SUCCESS)
+ {
+ switch (extractModeIndex)
+ {
+ case NExtract::NPathMode::kFullPathnames:
+ case NExtract::NPathMode::kCurrentPathnames:
+ case NExtract::NPathMode::kNoPathnames:
+ info.PathMode = NExtract::NPathMode::EEnum(extractModeIndex);
+ break;
+ }
+ }
+ UInt32 overwriteModeIndex;
+ if (extractionKey.QueryValue(kExtractionOverwriteModeValueName, overwriteModeIndex) == ERROR_SUCCESS)
+ {
+ switch (overwriteModeIndex)
+ {
+ case NExtract::NOverwriteMode::kAskBefore:
+ case NExtract::NOverwriteMode::kWithoutPrompt:
+ case NExtract::NOverwriteMode::kSkipExisting:
+ case NExtract::NOverwriteMode::kAutoRename:
+ case NExtract::NOverwriteMode::kAutoRenameExisting:
+ info.OverwriteMode = NExtract::NOverwriteMode::EEnum(overwriteModeIndex);
+ break;
+ }
+ }
+ if (extractionKey.QueryValue(kExtractionShowPasswordValueName,
+ info.ShowPassword) != ERROR_SUCCESS)
+ info.ShowPassword = false;
+}
+
+///////////////////////////////////
+// CompressionInfo
+
+static const TCHAR *kCompressionKeyName = TEXT("Compression");
+
+static const TCHAR *kCompressionHistoryArchivesKeyName = TEXT("ArcHistory");
+static const TCHAR *kCompressionLevelValueName = TEXT("Level");
+static const TCHAR *kCompressionLastFormatValueName = TEXT("Archiver");
+static const TCHAR *kCompressionShowPasswordValueName = TEXT("ShowPassword");
+static const TCHAR *kCompressionEncryptHeadersValueName = TEXT("EncryptHeaders");
+// static const TCHAR *kCompressionMaximizeValueName = TEXT("Maximize");
+
+static const TCHAR *kCompressionOptionsKeyName = TEXT("Options");
+static const TCHAR *kSolid = TEXT("Solid");
+static const TCHAR *kMultiThread = TEXT("Multithread");
+
+static const WCHAR *kCompressionOptions = L"Options";
+static const TCHAR *kCompressionLevel = TEXT("Level");
+static const WCHAR *kCompressionMethod = L"Method";
+static const WCHAR *kEncryptionMethod = L"EncryptionMethod";
+static const TCHAR *kCompressionDictionary = TEXT("Dictionary");
+static const TCHAR *kCompressionOrder = TEXT("Order");
+
+
+static void SetRegString(CKey &key, const WCHAR *name, const UString &value)
+{
+ if (value.IsEmpty())
+ key.DeleteValue(name);
+ else
+ key.SetValue(name, value);
+}
+
+static void SetRegUInt32(CKey &key, const TCHAR *name, UInt32 value)
+{
+ if (value == (UInt32)-1)
+ key.DeleteValue(name);
+ else
+ key.SetValue(name, value);
+}
+
+static void GetRegString(CKey &key, const WCHAR *name, UString &value)
+{
+ if (key.QueryValue(name, value) != ERROR_SUCCESS)
+ value.Empty();
+}
+
+static void GetRegUInt32(CKey &key, const TCHAR *name, UInt32 &value)
+{
+ if (key.QueryValue(name, value) != ERROR_SUCCESS)
+ value = UInt32(-1);
+}
+
+void SaveCompressionInfo(const NCompression::CInfo &info)
+{
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+
+ CKey compressionKey;
+ compressionKey.Create(HKEY_CURRENT_USER, GetKeyPath(kCompressionKeyName));
+ compressionKey.RecurseDeleteKey(kCompressionHistoryArchivesKeyName);
+ {
+ CKey historyArchivesKey;
+ historyArchivesKey.Create(compressionKey, kCompressionHistoryArchivesKeyName);
+ for(int i = 0; i < info.HistoryArchives.Size(); i++)
+ {
+ wchar_t numberString[16];
+ ConvertUInt64ToString(i, numberString);
+ historyArchivesKey.SetValue(numberString, info.HistoryArchives[i]);
+ }
+ }
+
+ compressionKey.SetValue(kSolid, info.Solid);
+ compressionKey.SetValue(kMultiThread, info.MultiThread);
+ compressionKey.RecurseDeleteKey(kCompressionOptionsKeyName);
+ {
+ CKey optionsKey;
+ optionsKey.Create(compressionKey, kCompressionOptionsKeyName);
+ for(int i = 0; i < info.FormatOptionsVector.Size(); i++)
+ {
+ const NCompression::CFormatOptions &fo = info.FormatOptionsVector[i];
+ CKey formatKey;
+ formatKey.Create(optionsKey, fo.FormatID);
+
+ SetRegString(formatKey, kCompressionOptions, fo.Options);
+ SetRegString(formatKey, kCompressionMethod, fo.Method);
+ SetRegString(formatKey, kEncryptionMethod, fo.EncryptionMethod);
+
+ SetRegUInt32(formatKey, kCompressionLevel, fo.Level);
+ SetRegUInt32(formatKey, kCompressionDictionary, fo.Dictionary);
+ SetRegUInt32(formatKey, kCompressionOrder, fo.Order);
+ }
+ }
+
+ compressionKey.SetValue(kCompressionLevelValueName, UInt32(info.Level));
+ compressionKey.SetValue(kCompressionLastFormatValueName,
+ GetSystemString(info.ArchiveType));
+
+ compressionKey.SetValue(kCompressionShowPasswordValueName, info.ShowPassword);
+ compressionKey.SetValue(kCompressionEncryptHeadersValueName, info.EncryptHeaders);
+ // compressionKey.SetValue(kCompressionMaximizeValueName, info.Maximize);
+}
+
+static bool IsMultiProcessor()
+{
+ SYSTEM_INFO systemInfo;
+ GetSystemInfo(&systemInfo);
+ return systemInfo.dwNumberOfProcessors > 1;
+}
+
+void ReadCompressionInfo(NCompression::CInfo &info)
+{
+ info.HistoryArchives.Clear();
+
+ info.Solid = true;
+ info.MultiThread = IsMultiProcessor();
+ info.FormatOptionsVector.Clear();
+
+ info.Level = 5;
+ info.ArchiveType = L"7z";
+ // definedStatus.Maximize = false;
+ info.ShowPassword = false;
+ info.EncryptHeaders = false;
+
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ CKey compressionKey;
+
+ if(compressionKey.Open(HKEY_CURRENT_USER,
+ GetKeyPath(kCompressionKeyName), KEY_READ) != ERROR_SUCCESS)
+ return;
+
+ {
+ CKey historyArchivesKey;
+ if(historyArchivesKey.Open(compressionKey, kCompressionHistoryArchivesKeyName, KEY_READ) ==
+ ERROR_SUCCESS)
+ {
+ for (;;)
+ {
+ wchar_t numberString[16];
+ ConvertUInt64ToString(info.HistoryArchives.Size(), numberString);
+ UString path;
+ if (historyArchivesKey.QueryValue(numberString, path) != ERROR_SUCCESS)
+ break;
+ info.HistoryArchives.Add(path);
+ }
+ }
+ }
+
+
+ bool solid = false;
+ if (compressionKey.QueryValue(kSolid, solid) == ERROR_SUCCESS)
+ info.Solid = solid;
+ bool multiThread = false;
+ if (compressionKey.QueryValue(kMultiThread, multiThread) == ERROR_SUCCESS)
+ info.MultiThread = multiThread;
+
+ {
+ CKey optionsKey;
+ if(optionsKey.Open(compressionKey, kCompressionOptionsKeyName, KEY_READ) ==
+ ERROR_SUCCESS)
+ {
+ CSysStringVector formatIDs;
+ optionsKey.EnumKeys(formatIDs);
+ for(int i = 0; i < formatIDs.Size(); i++)
+ {
+ CKey formatKey;
+ NCompression::CFormatOptions fo;
+ fo.FormatID = formatIDs[i];
+ if(formatKey.Open(optionsKey, fo.FormatID, KEY_READ) == ERROR_SUCCESS)
+ {
+ GetRegString(formatKey, kCompressionOptions, fo.Options);
+ GetRegString(formatKey, kCompressionMethod, fo.Method);
+ GetRegString(formatKey, kEncryptionMethod, fo.EncryptionMethod);
+
+ GetRegUInt32(formatKey, kCompressionLevel, fo.Level);
+ GetRegUInt32(formatKey, kCompressionDictionary, fo.Dictionary);
+ GetRegUInt32(formatKey, kCompressionOrder, fo.Order);
+
+ info.FormatOptionsVector.Add(fo);
+ }
+
+ }
+ }
+ }
+
+ UInt32 level;
+ if (compressionKey.QueryValue(kCompressionLevelValueName, level) == ERROR_SUCCESS)
+ info.Level = level;
+ CSysString archiveType;
+ if (compressionKey.QueryValue(kCompressionLastFormatValueName, archiveType) == ERROR_SUCCESS)
+ info.ArchiveType = GetUnicodeString(archiveType);
+ if (compressionKey.QueryValue(kCompressionShowPasswordValueName,
+ info.ShowPassword) != ERROR_SUCCESS)
+ info.ShowPassword = false;
+ if (compressionKey.QueryValue(kCompressionEncryptHeadersValueName,
+ info.EncryptHeaders) != ERROR_SUCCESS)
+ info.EncryptHeaders = false;
+ /*
+ if (compressionKey.QueryValue(kCompressionLevelValueName, info.Maximize) == ERROR_SUCCESS)
+ definedStatus.Maximize = true;
+ */
+}
+
+
+///////////////////////////////////
+// WorkDirInfo
+
+static const TCHAR *kOptionsInfoKeyName = TEXT("Options");
+
+static const TCHAR *kWorkDirTypeValueName = TEXT("WorkDirType");
+static const WCHAR *kWorkDirPathValueName = L"WorkDirPath";
+static const TCHAR *kTempRemovableOnlyValueName = TEXT("TempRemovableOnly");
+static const TCHAR *kCascadedMenuValueName = TEXT("CascadedMenu");
+static const TCHAR *kContextMenuValueName = TEXT("ContextMenu");
+
+void SaveWorkDirInfo(const NWorkDir::CInfo &info)
+{
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ CKey optionsKey;
+ optionsKey.Create(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName));
+ optionsKey.SetValue(kWorkDirTypeValueName, UInt32(info.Mode));
+ optionsKey.SetValue(kWorkDirPathValueName, info.Path);
+ optionsKey.SetValue(kTempRemovableOnlyValueName, info.ForRemovableOnly);
+}
+
+void ReadWorkDirInfo(NWorkDir::CInfo &info)
+{
+ info.SetDefault();
+
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ CKey optionsKey;
+ if(optionsKey.Open(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName), KEY_READ) != ERROR_SUCCESS)
+ return;
+
+ UInt32 dirType;
+ if (optionsKey.QueryValue(kWorkDirTypeValueName, dirType) != ERROR_SUCCESS)
+ return;
+ switch (dirType)
+ {
+ case NWorkDir::NMode::kSystem:
+ case NWorkDir::NMode::kCurrent:
+ case NWorkDir::NMode::kSpecified:
+ info.Mode = NWorkDir::NMode::EEnum(dirType);
+ }
+ UString sysWorkDir;
+ if (optionsKey.QueryValue(kWorkDirPathValueName, sysWorkDir) != ERROR_SUCCESS)
+ {
+ info.Path.Empty();
+ if (info.Mode == NWorkDir::NMode::kSpecified)
+ info.Mode = NWorkDir::NMode::kSystem;
+ }
+ info.Path = GetUnicodeString(sysWorkDir);
+ if (optionsKey.QueryValue(kTempRemovableOnlyValueName, info.ForRemovableOnly) != ERROR_SUCCESS)
+ info.SetForRemovableOnlyDefault();
+}
+
+static void SaveOption(const TCHAR *value, bool enabled)
+{
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ CKey optionsKey;
+ optionsKey.Create(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName));
+ optionsKey.SetValue(value, enabled);
+}
+
+static bool ReadOption(const TCHAR *value, bool defaultValue)
+{
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ CKey optionsKey;
+ if(optionsKey.Open(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName), KEY_READ) != ERROR_SUCCESS)
+ return defaultValue;
+ bool enabled;
+ if (optionsKey.QueryValue(value, enabled) != ERROR_SUCCESS)
+ return defaultValue;
+ return enabled;
+}
+
+void SaveCascadedMenu(bool show)
+ { SaveOption(kCascadedMenuValueName, show); }
+bool ReadCascadedMenu()
+ { return ReadOption(kCascadedMenuValueName, true); }
+
+
+static void SaveValue(const TCHAR *value, UInt32 valueToWrite)
+{
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ CKey optionsKey;
+ optionsKey.Create(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName));
+ optionsKey.SetValue(value, valueToWrite);
+}
+
+static bool ReadValue(const TCHAR *value, UInt32 &result)
+{
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ CKey optionsKey;
+ if(optionsKey.Open(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName), KEY_READ) != ERROR_SUCCESS)
+ return false;
+ return (optionsKey.QueryValue(value, result) == ERROR_SUCCESS);
+}
+
+void SaveContextMenuStatus(UInt32 value)
+ { SaveValue(kContextMenuValueName, value); }
+
+bool ReadContextMenuStatus(UInt32 &value)
+ { return ReadValue(kContextMenuValueName, value); }
diff --git a/CPP/7zip/UI/Common/ZipRegistry.h b/CPP/7zip/UI/Common/ZipRegistry.h
new file mode 100755
index 00000000..30e7ee44
--- /dev/null
+++ b/CPP/7zip/UI/Common/ZipRegistry.h
@@ -0,0 +1,99 @@
+// ZipRegistry.h
+
+#ifndef __ZIPREGISTRY_H
+#define __ZIPREGISTRY_H
+
+#include "Common/String.h"
+#include "Common/Types.h"
+#include "ExtractMode.h"
+
+namespace NExtract
+{
+ struct CInfo
+ {
+ NPathMode::EEnum PathMode;
+ NOverwriteMode::EEnum OverwriteMode;
+ UStringVector Paths;
+ bool ShowPassword;
+ };
+}
+
+namespace NCompression {
+
+ struct CFormatOptions
+ {
+ CSysString FormatID;
+ UString Options;
+ UString Method;
+ UString EncryptionMethod;
+ UInt32 Level;
+ UInt32 Dictionary;
+ UInt32 Order;
+ void ResetForLevelChange()
+ {
+ Level = Dictionary = Order = UInt32(-1);
+ Method.Empty();
+ // EncryptionMethod.Empty();
+ // Options.Empty();
+ }
+ CFormatOptions() { ResetForLevelChange(); }
+ };
+
+ struct CInfo
+ {
+ UStringVector HistoryArchives;
+ // bool LevelIsDefined;
+ UInt32 Level;
+ UString ArchiveType;
+
+ bool Solid;
+ bool MultiThread;
+ CObjectVector<CFormatOptions> FormatOptionsVector;
+
+ bool ShowPassword;
+ bool EncryptHeaders;
+ };
+}
+
+namespace NWorkDir{
+
+ namespace NMode
+ {
+ enum EEnum
+ {
+ kSystem,
+ kCurrent,
+ kSpecified
+ };
+ }
+ struct CInfo
+ {
+ NMode::EEnum Mode;
+ UString Path;
+ bool ForRemovableOnly;
+ void SetForRemovableOnlyDefault() { ForRemovableOnly = true; }
+ void SetDefault()
+ {
+ Mode = NMode::kSystem;
+ Path.Empty();
+ SetForRemovableOnlyDefault();
+ }
+ };
+}
+
+void SaveExtractionInfo(const NExtract::CInfo &info);
+void ReadExtractionInfo(NExtract::CInfo &info);
+
+void SaveCompressionInfo(const NCompression::CInfo &info);
+void ReadCompressionInfo(NCompression::CInfo &info);
+
+void SaveWorkDirInfo(const NWorkDir::CInfo &info);
+void ReadWorkDirInfo(NWorkDir::CInfo &info);
+
+void SaveCascadedMenu(bool enabled);
+bool ReadCascadedMenu();
+
+void SaveContextMenuStatus(UInt32 value);
+bool ReadContextMenuStatus(UInt32 &value);
+
+#endif
diff --git a/CPP/7zip/UI/Console/Console.dsp b/CPP/7zip/UI/Console/Console.dsp
new file mode 100755
index 00000000..e457008c
--- /dev/null
+++ b/CPP/7zip/UI/Console/Console.dsp
@@ -0,0 +1,667 @@
+# Microsoft Developer Studio Project File - Name="Console" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=Console - Win32 DebugU
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "Console.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "Console.mak" CFG="Console - Win32 DebugU"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Console - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "Console - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "Console - Win32 ReleaseU" (based on "Win32 (x86) Console Application")
+!MESSAGE "Console - Win32 DebugU" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "Console - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\UTIL\7z.exe" /OPT:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Console - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "../../../" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\UTIL\7z.exe" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "Console - Win32 ReleaseU"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Console___Win32_ReleaseU"
+# PROP BASE Intermediate_Dir "Console___Win32_ReleaseU"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ReleaseU"
+# PROP Intermediate_Dir "ReleaseU"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\UTIL\7z.exe"
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\UTIL\7zn.exe" /OPT:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Console - Win32 DebugU"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Console___Win32_DebugU"
+# PROP BASE Intermediate_Dir "Console___Win32_DebugU"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "DebugU"
+# PROP Intermediate_Dir "DebugU"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "../../../" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c
+# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "../../../" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\UTIL\7z.exe" /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\UTIL\7z.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "Console - Win32 Release"
+# Name "Console - Win32 Debug"
+# Name "Console - Win32 ReleaseU"
+# Name "Console - Win32 DebugU"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Console"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\ConsoleClose.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ConsoleClose.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ExtractCallbackConsole.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ExtractCallbackConsole.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\List.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\List.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Main.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\MainAr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\OpenCallbackConsole.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\OpenCallbackConsole.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\PercentPrinter.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\PercentPrinter.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\UpdateCallbackConsole.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\UpdateCallbackConsole.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\UserInputUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\UserInputUtils.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Error.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Error.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\MemoryLock.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\MemoryLock.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Registry.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Registry.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Time.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\CommandLineParser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\ComTry.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Defs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Exception.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\ListFileUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\ListFileUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyCom.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdInStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdInStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\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\StringToInt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringToInt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\UTFConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\UTFConvert.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Vector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Vector.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.h
+# End Source File
+# End Group
+# Begin Group "UI Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Common\ArchiveCommandLine.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiveCommandLine.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiveExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiveExtractCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiveOpenCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiveOpenCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiverInfo.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiverInfo.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CompressionMode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\DefaultName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\DefaultName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\DirItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\EnumDirItems.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\EnumDirItems.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ExitCode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\Extract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\Extract.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ExtractingFilePath.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ExtractingFilePath.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\HandlerLoader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\IFileExtractCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\OpenArchive.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\OpenArchive.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\Property.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\PropIDUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\PropIDUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\SetProperties.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\SetProperties.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\SortUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\SortUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\TempFiles.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\TempFiles.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\Update.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\Update.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdateAction.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdateAction.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdateCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdateCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdatePair.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdatePair.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdateProduce.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdateProduce.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\WorkDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\WorkDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ZipRegistry.h
+# End Source File
+# End Group
+# Begin Group "7-zip Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\FilePathAutoRename.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilePathAutoRename.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# 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/CPP/7zip/UI/Console/Console.dsw b/CPP/7zip/UI/Console/Console.dsw
new file mode 100755
index 00000000..0d93da2f
--- /dev/null
+++ b/CPP/7zip/UI/Console/Console.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Console"=".\Console.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/UI/Console/ConsoleClose.cpp b/CPP/7zip/UI/Console/ConsoleClose.cpp
new file mode 100755
index 00000000..a514c12a
--- /dev/null
+++ b/CPP/7zip/UI/Console/ConsoleClose.cpp
@@ -0,0 +1,65 @@
+// ConsoleClose.cpp
+
+#include "StdAfx.h"
+
+#include <stdio.h>
+
+#include "ConsoleClose.h"
+
+static int g_BreakCounter = 0;
+static const int kBreakAbortThreshold = 2;
+
+namespace NConsoleClose {
+
+static BOOL WINAPI HandlerRoutine(DWORD ctrlType)
+{
+ if (ctrlType == CTRL_LOGOFF_EVENT)
+ {
+ // printf("\nCTRL_LOGOFF_EVENT\n");
+ return TRUE;
+ }
+
+ g_BreakCounter++;
+ if (g_BreakCounter < kBreakAbortThreshold)
+ return TRUE;
+ return FALSE;
+ /*
+ switch(ctrlType)
+ {
+ case CTRL_C_EVENT:
+ case CTRL_BREAK_EVENT:
+ if (g_BreakCounter < kBreakAbortThreshold)
+ return TRUE;
+ }
+ return FALSE;
+ */
+}
+
+bool TestBreakSignal()
+{
+ /*
+ if (g_BreakCounter > 0)
+ return true;
+ */
+ return (g_BreakCounter > 0);
+}
+
+void CheckCtrlBreak()
+{
+ if (TestBreakSignal())
+ throw CCtrlBreakException();
+}
+
+CCtrlHandlerSetter::CCtrlHandlerSetter()
+{
+ if(!SetConsoleCtrlHandler(HandlerRoutine, TRUE))
+ throw "SetConsoleCtrlHandler fails";
+}
+
+CCtrlHandlerSetter::~CCtrlHandlerSetter()
+{
+ if(!SetConsoleCtrlHandler(HandlerRoutine, FALSE))
+ throw "SetConsoleCtrlHandler fails";
+}
+
+}
diff --git a/CPP/7zip/UI/Console/ConsoleClose.h b/CPP/7zip/UI/Console/ConsoleClose.h
new file mode 100755
index 00000000..3c5fd55d
--- /dev/null
+++ b/CPP/7zip/UI/Console/ConsoleClose.h
@@ -0,0 +1,24 @@
+// ConsoleCloseUtils.h
+
+#ifndef __CONSOLECLOSEUTILS_H
+#define __CONSOLECLOSEUTILS_H
+
+namespace NConsoleClose {
+
+bool TestBreakSignal();
+
+class CCtrlHandlerSetter
+{
+public:
+ CCtrlHandlerSetter();
+ virtual ~CCtrlHandlerSetter();
+};
+
+class CCtrlBreakException
+{};
+
+void CheckCtrlBreak();
+
+}
+
+#endif
diff --git a/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp b/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
new file mode 100755
index 00000000..9bd605ec
--- /dev/null
+++ b/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
@@ -0,0 +1,235 @@
+// ExtractCallbackConsole.h
+
+#include "StdAfx.h"
+
+#include "ExtractCallbackConsole.h"
+#include "UserInputUtils.h"
+#include "ConsoleClose.h"
+
+#include "Common/Wildcard.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileFind.h"
+#include "Windows/Time.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+#include "Windows/Error.h"
+#include "Windows/PropVariantConversions.h"
+
+#include "../../Common/FilePathAutoRename.h"
+
+#include "../Common/ExtractingFilePath.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NDirectory;
+
+static const char *kTestingString = "Testing ";
+static const char *kExtractingString = "Extracting ";
+static const char *kSkippingString = "Skipping ";
+
+static const char *kCantAutoRename = "can not create file with auto name\n";
+static const char *kCantRenameFile = "can not rename existing file\n";
+static const char *kCantDeleteOutputFile = "can not delete output file ";
+static const char *kError = "ERROR: ";
+static const char *kMemoryExceptionMessage = "Can't allocate required memory!";
+
+static const char *kProcessing = "Processing archive: ";
+static const char *kEverythingIsOk = "Everything is Ok";
+static const char *kNoFiles = "No files to process";
+
+static const char *kUnsupportedMethod = "Unsupported Method";
+static const char *kCrcFailed = "CRC Failed";
+static const char *kCrcFailedEncrypted = "CRC Failed in encrypted file. Wrong password?";
+static const char *kDataError = "Data Error";
+static const char *kDataErrorEncrypted = "Data Error in encrypted file. Wrong password?";
+static const char *kUnknownError = "Unknown Error";
+
+STDMETHODIMP CExtractCallbackConsole::SetTotal(UInt64)
+{
+ if (NConsoleClose::TestBreakSignal())
+ return E_ABORT;
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackConsole::SetCompleted(const UInt64 *)
+{
+ if (NConsoleClose::TestBreakSignal())
+ return E_ABORT;
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackConsole::AskOverwrite(
+ const wchar_t *existName, const FILETIME *, const UInt64 *,
+ const wchar_t *newName, const FILETIME *, const UInt64 *,
+ Int32 *answer)
+{
+ (*OutStream) << "file " << existName <<
+ "\nalready exists. Overwrite with " << endl;
+ (*OutStream) << newName;
+
+ NUserAnswerMode::EEnum overwriteAnswer = ScanUserYesNoAllQuit(OutStream);
+
+ switch(overwriteAnswer)
+ {
+ case NUserAnswerMode::kQuit:
+ return E_ABORT;
+ case NUserAnswerMode::kNo:
+ *answer = NOverwriteAnswer::kNo;
+ break;
+ case NUserAnswerMode::kNoAll:
+ *answer = NOverwriteAnswer::kNoToAll;
+ break;
+ case NUserAnswerMode::kYesAll:
+ *answer = NOverwriteAnswer::kYesToAll;
+ break;
+ case NUserAnswerMode::kYes:
+ *answer = NOverwriteAnswer::kYes;
+ break;
+ case NUserAnswerMode::kAutoRename:
+ *answer = NOverwriteAnswer::kAutoRename;
+ break;
+ default:
+ return E_FAIL;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int32 askExtractMode, const UInt64 *position)
+{
+ switch (askExtractMode)
+ {
+ case NArchive::NExtract::NAskMode::kExtract:
+ (*OutStream) << kExtractingString;
+ break;
+ case NArchive::NExtract::NAskMode::kTest:
+ (*OutStream) << kTestingString;
+ break;
+ case NArchive::NExtract::NAskMode::kSkip:
+ (*OutStream) << kSkippingString;
+ break;
+ };
+ (*OutStream) << name;
+ if (position != 0)
+ (*OutStream) << " <" << *position << ">";
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackConsole::MessageError(const wchar_t *message)
+{
+ (*OutStream) << message << endl;
+ NumFileErrorsInCurrentArchive++;
+ NumFileErrors++;
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 operationResult, bool encrypted)
+{
+ switch(operationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kOK:
+ break;
+ default:
+ {
+ NumFileErrorsInCurrentArchive++;
+ NumFileErrors++;
+ (*OutStream) << " ";
+ switch(operationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
+ (*OutStream) << kUnsupportedMethod;
+ break;
+ case NArchive::NExtract::NOperationResult::kCRCError:
+ (*OutStream) << (encrypted ? kCrcFailedEncrypted: kCrcFailed);
+ break;
+ case NArchive::NExtract::NOperationResult::kDataError:
+ (*OutStream) << (encrypted ? kDataErrorEncrypted : kDataError);
+ break;
+ default:
+ (*OutStream) << kUnknownError;
+ }
+ }
+ }
+ (*OutStream) << endl;
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackConsole::CryptoGetTextPassword(BSTR *password)
+{
+ if (!PasswordIsDefined)
+ {
+ Password = GetPassword(OutStream);
+ PasswordIsDefined = true;
+ }
+ CMyComBSTR tempName(Password);
+ *password = tempName.Detach();
+ return S_OK;
+}
+
+HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name)
+{
+ NumArchives++;
+ NumFileErrorsInCurrentArchive = 0;
+ (*OutStream) << endl << kProcessing << name << endl;
+ return S_OK;
+}
+
+HRESULT CExtractCallbackConsole::OpenResult(const wchar_t * /* name */, HRESULT result, bool encrypted)
+{
+ (*OutStream) << endl;
+ if (result != S_OK)
+ {
+ (*OutStream) << "Error: ";
+ if (encrypted)
+ (*OutStream) << "Can not open encrypted archive. Wrong password?";
+ else
+ (*OutStream) << "Can not open file as archive";
+ (*OutStream) << endl;
+ NumArchiveErrors++;
+ }
+ return S_OK;
+}
+
+HRESULT CExtractCallbackConsole::ThereAreNoFiles()
+{
+ (*OutStream) << endl << kNoFiles << endl;
+ return S_OK;
+}
+
+HRESULT CExtractCallbackConsole::ExtractResult(HRESULT result)
+{
+ if (result == S_OK)
+ {
+ (*OutStream) << endl;
+ if (NumFileErrorsInCurrentArchive == 0)
+ (*OutStream) << kEverythingIsOk << endl;
+ else
+ {
+ NumArchiveErrors++;
+ (*OutStream) << "Sub items Errors: " << NumFileErrorsInCurrentArchive << endl;
+ }
+ }
+ if (result == S_OK)
+ return result;
+ NumArchiveErrors++;
+ if (result == E_ABORT || result == ERROR_DISK_FULL)
+ return result;
+ (*OutStream) << endl << kError;
+ if (result == E_OUTOFMEMORY)
+ (*OutStream) << kMemoryExceptionMessage;
+ else
+ {
+ UString message;
+ NError::MyFormatMessage(result, message);
+ (*OutStream) << message;
+ }
+ (*OutStream) << endl;
+ return S_OK;
+}
+
+HRESULT CExtractCallbackConsole::SetPassword(const UString &password)
+{
+ PasswordIsDefined = true;
+ Password = password;
+ return S_OK;
+}
diff --git a/CPP/7zip/UI/Console/ExtractCallbackConsole.h b/CPP/7zip/UI/Console/ExtractCallbackConsole.h
new file mode 100755
index 00000000..5b45106a
--- /dev/null
+++ b/CPP/7zip/UI/Console/ExtractCallbackConsole.h
@@ -0,0 +1,65 @@
+// ExtractCallbackConsole.h
+
+#ifndef __EXTRACTCALLBACKCONSOLE_H
+#define __EXTRACTCALLBACKCONSOLE_H
+
+#include "Common/String.h"
+#include "Common/StdOutStream.h"
+#include "../../Common/FileStreams.h"
+#include "../../IPassword.h"
+#include "../../Archive/IArchive.h"
+#include "../Common/ArchiveExtractCallback.h"
+
+class CExtractCallbackConsole:
+ public IExtractCallbackUI,
+ public ICryptoGetTextPassword,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP2(IFolderArchiveExtractCallback, ICryptoGetTextPassword)
+
+ STDMETHOD(SetTotal)(UInt64 total);
+ STDMETHOD(SetCompleted)(const UInt64 *completeValue);
+
+ // IFolderArchiveExtractCallback
+ STDMETHOD(AskOverwrite)(
+ const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize,
+ const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize,
+ Int32 *answer);
+ STDMETHOD (PrepareOperation)(const wchar_t *name, Int32 askExtractMode, const UInt64 *position);
+
+ STDMETHOD(MessageError)(const wchar_t *message);
+ STDMETHOD(SetOperationResult)(Int32 operationResult, bool encrypted);
+
+ // ICryptoGetTextPassword
+ STDMETHOD(CryptoGetTextPassword)(BSTR *password);
+
+ HRESULT BeforeOpen(const wchar_t *name);
+ HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted);
+ HRESULT ThereAreNoFiles();
+ HRESULT ExtractResult(HRESULT result);
+
+ HRESULT SetPassword(const UString &password);
+
+public:
+ bool PasswordIsDefined;
+ UString Password;
+
+ UInt64 NumArchives;
+ UInt64 NumArchiveErrors;
+ UInt64 NumFileErrors;
+ UInt64 NumFileErrorsInCurrentArchive;
+
+ CStdOutStream *OutStream;
+
+ void Init()
+ {
+ NumArchives = 0;
+ NumArchiveErrors = 0;
+ NumFileErrors = 0;
+ NumFileErrorsInCurrentArchive = 0;
+ }
+
+};
+
+#endif
diff --git a/CPP/7zip/UI/Console/List.cpp b/CPP/7zip/UI/Console/List.cpp
new file mode 100755
index 00000000..6001e114
--- /dev/null
+++ b/CPP/7zip/UI/Console/List.cpp
@@ -0,0 +1,532 @@
+// List.cpp
+
+#include "StdAfx.h"
+
+#include "List.h"
+#include "ConsoleClose.h"
+
+#include "Common/StringConvert.h"
+#include "Common/StdOutStream.h"
+#include "Common/IntToString.h"
+#include "Common/MyCom.h"
+
+#include "Windows/PropVariant.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariantConversions.h"
+#include "Windows/FileDir.h"
+
+#include "../../Archive/IArchive.h"
+
+#include "../Common/PropIDUtils.h"
+#include "../Common/OpenArchive.h"
+
+#include "OpenCallbackConsole.h"
+
+using namespace NWindows;
+
+struct CPropIdToName
+{
+ PROPID PropID;
+ const wchar_t *Name;
+};
+
+static CPropIdToName kPropIdToName[] =
+{
+ { kpidPath, L"Path" },
+ { kpidName, L"Name" },
+ { kpidIsFolder, L"Folder" },
+ { kpidSize, L"Size" },
+ { kpidPackedSize, L"Packed Size" },
+ { kpidAttributes, L"Attributes" },
+ { kpidCreationTime, L"Created" },
+ { kpidLastAccessTime, L"Accessed" },
+ { kpidLastWriteTime, L"Modified" },
+ { kpidSolid, L"Solid" },
+ { kpidCommented, L"Commented" },
+ { kpidEncrypted, L"Encrypted" },
+ { kpidSplitBefore, L"Split Before" },
+ { kpidSplitAfter, L"Split After" },
+ { kpidDictionarySize, L"Dictionary Size" },
+ { kpidCRC, L"CRC" },
+ { kpidType, L"Type" },
+ { kpidIsAnti, L"Anti" },
+ { kpidMethod, L"Method" },
+ { kpidHostOS, L"Host OS" },
+ { kpidFileSystem, L"File System" },
+ { kpidUser, L"User" },
+ { kpidGroup, L"Group" },
+ { kpidBlock, L"Block" },
+ { kpidComment, L"Comment" },
+ { kpidPosition, L"Position" }
+};
+
+static const char kEmptyAttributeChar = '.';
+static const char kDirectoryAttributeChar = 'D';
+static const char kReadonlyAttributeChar = 'R';
+static const char kHiddenAttributeChar = 'H';
+static const char kSystemAttributeChar = 'S';
+static const char kArchiveAttributeChar = 'A';
+
+static const char *kListing = "Listing archive: ";
+static const wchar_t *kFilesMessage = L"files";
+
+static void GetAttributesString(DWORD wa, bool directory, char *s)
+{
+ s[0] = ((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || directory) ?
+ kDirectoryAttributeChar: kEmptyAttributeChar;
+ s[1] = ((wa & FILE_ATTRIBUTE_READONLY) != 0)?
+ kReadonlyAttributeChar: kEmptyAttributeChar;
+ s[2] = ((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ?
+ kHiddenAttributeChar: kEmptyAttributeChar;
+ s[3] = ((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ?
+ kSystemAttributeChar: kEmptyAttributeChar;
+ s[4] = ((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ?
+ kArchiveAttributeChar: kEmptyAttributeChar;
+ s[5] = '\0';
+}
+
+enum EAdjustment
+{
+ kLeft,
+ kCenter,
+ kRight
+};
+
+struct CFieldInfo
+{
+ PROPID PropID;
+ UString Name;
+ EAdjustment TitleAdjustment;
+ EAdjustment TextAdjustment;
+ int PrefixSpacesWidth;
+ int Width;
+};
+
+struct CFieldInfoInit
+{
+ PROPID PropID;
+ const wchar_t *Name;
+ EAdjustment TitleAdjustment;
+ EAdjustment TextAdjustment;
+ int PrefixSpacesWidth;
+ int Width;
+};
+
+CFieldInfoInit kStandardFieldTable[] =
+{
+ { kpidLastWriteTime, L" Date Time", kLeft, kLeft, 0, 19 },
+ { kpidAttributes, L"Attr", kRight, kCenter, 1, 5 },
+ { kpidSize, L"Size", kRight, kRight, 1, 12 },
+ { kpidPackedSize, L"Compressed", kRight, kRight, 1, 12 },
+ { kpidPath, L"Name", kLeft, kLeft, 2, 12 }
+};
+
+void PrintSpaces(int numSpaces)
+{
+ for (int i = 0; i < numSpaces; i++)
+ g_StdOut << ' ';
+}
+
+void PrintString(EAdjustment adjustment, int width, const UString &textString)
+{
+ const int numSpaces = width - textString.Length();
+ int numLeftSpaces = 0;
+ switch (adjustment)
+ {
+ case kLeft:
+ numLeftSpaces = 0;
+ break;
+ case kCenter:
+ numLeftSpaces = numSpaces / 2;
+ break;
+ case kRight:
+ numLeftSpaces = numSpaces;
+ break;
+ }
+ PrintSpaces(numLeftSpaces);
+ g_StdOut << textString;
+ PrintSpaces(numSpaces - numLeftSpaces);
+}
+
+class CFieldPrinter
+{
+ CObjectVector<CFieldInfo> _fields;
+public:
+ void Clear() { _fields.Clear(); }
+ void Init(const CFieldInfoInit *standardFieldTable, int numItems);
+ HRESULT Init(IInArchive *archive);
+ void PrintTitle();
+ void PrintTitleLines();
+ HRESULT PrintItemInfo(IInArchive *archive,
+ const UString &defaultItemName,
+ const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,
+ UInt32 index,
+ bool techMode);
+ HRESULT PrintSummaryInfo(UInt64 numFiles, const UInt64 *size,
+ const UInt64 *compressedSize);
+};
+
+void CFieldPrinter::Init(const CFieldInfoInit *standardFieldTable, int numItems)
+{
+ Clear();
+ for (int i = 0; i < numItems; i++)
+ {
+ CFieldInfo fieldInfo;
+ const CFieldInfoInit &fieldInfoInit = standardFieldTable[i];
+ fieldInfo.PropID = fieldInfoInit.PropID;
+ fieldInfo.Name = fieldInfoInit.Name;
+ fieldInfo.TitleAdjustment = fieldInfoInit.TitleAdjustment;
+ fieldInfo.TextAdjustment = fieldInfoInit.TextAdjustment;
+ fieldInfo.PrefixSpacesWidth = fieldInfoInit.PrefixSpacesWidth;
+ fieldInfo.Width = fieldInfoInit.Width;
+ _fields.Add(fieldInfo);
+ }
+}
+
+HRESULT CFieldPrinter::Init(IInArchive *archive)
+{
+ Clear();
+ UInt32 numProps;
+ RINOK(archive->GetNumberOfProperties(&numProps));
+ for (UInt32 i = 0; i < numProps; i++)
+ {
+ CMyComBSTR name;
+ PROPID propID;
+ VARTYPE vt;
+ RINOK(archive->GetPropertyInfo(i, &name, &propID, &vt));
+ CFieldInfo fieldInfo;
+ fieldInfo.PropID = propID;
+ if (name != NULL)
+ fieldInfo.Name = name;
+ else
+ {
+ fieldInfo.Name = L"Unknown";
+ for (int i = 0; i < sizeof(kPropIdToName) / sizeof(kPropIdToName[0]); i++)
+ {
+ const CPropIdToName &propIdToName = kPropIdToName[i];
+ if (propIdToName.PropID == propID)
+ {
+ fieldInfo.Name = propIdToName.Name;
+ break;
+ }
+ }
+ }
+ _fields.Add(fieldInfo);
+ }
+ return S_OK;
+}
+
+void CFieldPrinter::PrintTitle()
+{
+ for (int i = 0; i < _fields.Size(); i++)
+ {
+ const CFieldInfo &fieldInfo = _fields[i];
+ PrintSpaces(fieldInfo.PrefixSpacesWidth);
+ PrintString(fieldInfo.TitleAdjustment,
+ ((fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width), fieldInfo.Name);
+ }
+}
+
+void CFieldPrinter::PrintTitleLines()
+{
+ for (int i = 0; i < _fields.Size(); i++)
+ {
+ const CFieldInfo &fieldInfo = _fields[i];
+ PrintSpaces(fieldInfo.PrefixSpacesWidth);
+ for (int i = 0; i < fieldInfo.Width; i++)
+ g_StdOut << '-';
+ }
+}
+
+
+BOOL IsFileTimeZero(CONST FILETIME *lpFileTime)
+{
+ return (lpFileTime->dwLowDateTime == 0) && (lpFileTime->dwHighDateTime == 0);
+}
+
+static const char *kEmptyTimeString = " ";
+void PrintTime(const NCOM::CPropVariant &propVariant)
+{
+ if (propVariant.vt != VT_FILETIME)
+ throw "incorrect item";
+ if (IsFileTimeZero(&propVariant.filetime))
+ g_StdOut << kEmptyTimeString;
+ else
+ {
+ FILETIME localFileTime;
+ if (!FileTimeToLocalFileTime(&propVariant.filetime, &localFileTime))
+ throw "FileTimeToLocalFileTime error";
+ char s[32];
+ if (ConvertFileTimeToString(localFileTime, s, true, true))
+ g_StdOut << s;
+ else
+ g_StdOut << kEmptyTimeString;
+ }
+}
+
+HRESULT CFieldPrinter::PrintItemInfo(IInArchive *archive,
+ const UString &defaultItemName,
+ const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,
+ UInt32 index,
+ bool techMode)
+{
+ /*
+ if (techMode)
+ {
+ g_StdOut << "Index = ";
+ g_StdOut << (UInt64)index;
+ g_StdOut << endl;
+ }
+ */
+ for (int i = 0; i < _fields.Size(); i++)
+ {
+ const CFieldInfo &fieldInfo = _fields[i];
+ if (!techMode)
+ PrintSpaces(fieldInfo.PrefixSpacesWidth);
+
+ NCOM::CPropVariant propVariant;
+ RINOK(archive->GetProperty(index, fieldInfo.PropID, &propVariant));
+ if (techMode)
+ {
+ g_StdOut << fieldInfo.Name << " = ";
+ }
+ int width = (fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width;
+ if (propVariant.vt == VT_EMPTY)
+ {
+ switch(fieldInfo.PropID)
+ {
+ case kpidPath:
+ propVariant = defaultItemName;
+ break;
+ case kpidLastWriteTime:
+ propVariant = archiveFileInfo.LastWriteTime;
+ break;
+ default:
+ if (techMode)
+ g_StdOut << endl;
+ else
+ PrintSpaces(width);
+ continue;
+ }
+ }
+ if (fieldInfo.PropID == kpidLastWriteTime)
+ {
+ PrintTime(propVariant);
+ }
+ else if (fieldInfo.PropID == kpidAttributes)
+ {
+ if (propVariant.vt != VT_UI4)
+ throw "incorrect item";
+ UInt32 attributes = propVariant.ulVal;
+ bool isFolder;
+ RINOK(IsArchiveItemFolder(archive, index, isFolder));
+ char s[8];
+ GetAttributesString(attributes, isFolder, s);
+ g_StdOut << s;
+ }
+ else if (propVariant.vt == VT_BSTR)
+ {
+ if (techMode)
+ g_StdOut << propVariant.bstrVal;
+ else
+ PrintString(fieldInfo.TextAdjustment, width, propVariant.bstrVal);
+ }
+ else
+ {
+ UString s = ConvertPropertyToString(propVariant, fieldInfo.PropID);
+ if (techMode)
+ g_StdOut << s;
+ else
+ PrintString(fieldInfo.TextAdjustment, width, s);
+ }
+ if (techMode)
+ g_StdOut << endl;
+ }
+ return S_OK;
+}
+
+void PrintNumberString(EAdjustment adjustment, int width, const UInt64 *value)
+{
+ wchar_t textString[32] = { 0 };
+ if (value != NULL)
+ ConvertUInt64ToString(*value, textString);
+ PrintString(adjustment, width, textString);
+}
+
+
+HRESULT CFieldPrinter::PrintSummaryInfo(UInt64 numFiles,
+ const UInt64 *size, const UInt64 *compressedSize)
+{
+ for (int i = 0; i < _fields.Size(); i++)
+ {
+ const CFieldInfo &fieldInfo = _fields[i];
+ PrintSpaces(fieldInfo.PrefixSpacesWidth);
+ NCOM::CPropVariant propVariant;
+ if (fieldInfo.PropID == kpidSize)
+ PrintNumberString(fieldInfo.TextAdjustment, fieldInfo.Width, size);
+ else if (fieldInfo.PropID == kpidPackedSize)
+ PrintNumberString(fieldInfo.TextAdjustment, fieldInfo.Width, compressedSize);
+ else if (fieldInfo.PropID == kpidPath)
+ {
+ wchar_t textString[32];
+ ConvertUInt64ToString(numFiles, textString);
+ UString temp = textString;
+ temp += L" ";
+ temp += kFilesMessage;
+ PrintString(fieldInfo.TextAdjustment, 0, temp);
+ }
+ else
+ PrintString(fieldInfo.TextAdjustment, fieldInfo.Width, L"");
+ }
+ return S_OK;
+}
+
+bool GetUInt64Value(IInArchive *archive, UInt32 index, PROPID propID, UInt64 &value)
+{
+ NCOM::CPropVariant propVariant;
+ if (archive->GetProperty(index, propID, &propVariant) != S_OK)
+ throw "GetPropertyValue error";
+ if (propVariant.vt == VT_EMPTY)
+ return false;
+ value = ConvertPropVariantToUInt64(propVariant);
+ return true;
+}
+
+HRESULT ListArchives(UStringVector &archivePaths, UStringVector &archivePathsFull,
+ const NWildcard::CCensorNode &wildcardCensor,
+ bool enableHeaders, bool techMode, bool &passwordEnabled, UString &password)
+{
+ CFieldPrinter fieldPrinter;
+ if (!techMode)
+ fieldPrinter.Init(kStandardFieldTable, sizeof(kStandardFieldTable) / sizeof(kStandardFieldTable[0]));
+
+ UInt64 numFiles2 = 0, totalPackSize2 = 0, totalUnPackSize2 = 0;
+ UInt64 *totalPackSizePointer2 = 0, *totalUnPackSizePointer2 = 0;
+ int numErrors = 0;
+ for (int i = 0; i < archivePaths.Size(); i++)
+ {
+ const UString &archiveName = archivePaths[i];
+ NFile::NFind::CFileInfoW archiveFileInfo;
+ if (!NFile::NFind::FindFile(archiveName, archiveFileInfo) || archiveFileInfo.IsDirectory())
+ {
+ g_StdOut << endl << "Error: " << archiveName << " is not archive" << endl;
+ numErrors++;
+ continue;
+ }
+ if (archiveFileInfo.IsDirectory())
+ {
+ g_StdOut << endl << "Error: " << archiveName << " is not file" << endl;
+ numErrors++;
+ continue;
+ }
+
+ CArchiveLink archiveLink;
+
+ COpenCallbackConsole openCallback;
+ openCallback.OutStream = &g_StdOut;
+ openCallback.PasswordIsDefined = passwordEnabled;
+ openCallback.Password = password;
+
+ HRESULT result = MyOpenArchive(archiveName, archiveLink, &openCallback);
+ if (result != S_OK)
+ {
+ g_StdOut << endl << "Error: " << archiveName << " is not supported archive" << endl;
+ numErrors++;
+ continue;
+ }
+
+ for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
+ {
+ int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]);
+ if (index >= 0 && index > i)
+ {
+ archivePaths.Delete(index);
+ archivePathsFull.Delete(index);
+ }
+ }
+
+ IInArchive *archive = archiveLink.GetArchive();
+ const UString defaultItemName = archiveLink.GetDefaultItemName();
+
+ if (enableHeaders)
+ g_StdOut << endl << kListing << archiveName << endl << endl;
+
+ if (enableHeaders && !techMode)
+ {
+ fieldPrinter.PrintTitle();
+ g_StdOut << endl;
+ fieldPrinter.PrintTitleLines();
+ g_StdOut << endl;
+ }
+
+ if (techMode)
+ {
+ RINOK(fieldPrinter.Init(archive));
+ }
+ UInt64 numFiles = 0, totalPackSize = 0, totalUnPackSize = 0;
+ UInt64 *totalPackSizePointer = 0, *totalUnPackSizePointer = 0;
+ UInt32 numItems;
+ RINOK(archive->GetNumberOfItems(&numItems));
+ for(UInt32 i = 0; i < numItems; i++)
+ {
+ if (NConsoleClose::TestBreakSignal())
+ return E_ABORT;
+
+ UString filePath;
+ RINOK(GetArchiveItemPath(archive, i, defaultItemName, filePath));
+
+ bool isFolder;
+ RINOK(IsArchiveItemFolder(archive, i, isFolder));
+ if (!wildcardCensor.CheckPath(filePath, !isFolder))
+ continue;
+
+ fieldPrinter.PrintItemInfo(archive, defaultItemName, archiveFileInfo, i, techMode);
+
+ UInt64 packSize, unpackSize;
+ if (!GetUInt64Value(archive, i, kpidSize, unpackSize))
+ unpackSize = 0;
+ else
+ totalUnPackSizePointer = &totalUnPackSize;
+ if (!GetUInt64Value(archive, i, kpidPackedSize, packSize))
+ packSize = 0;
+ else
+ totalPackSizePointer = &totalPackSize;
+
+ g_StdOut << endl;
+
+ numFiles++;
+ totalPackSize += packSize;
+ totalUnPackSize += unpackSize;
+ }
+ if (enableHeaders && !techMode)
+ {
+ fieldPrinter.PrintTitleLines();
+ g_StdOut << endl;
+ fieldPrinter.PrintSummaryInfo(numFiles, totalUnPackSizePointer, totalPackSizePointer);
+ g_StdOut << endl;
+ }
+ if (totalPackSizePointer != 0)
+ {
+ totalPackSizePointer2 = &totalPackSize2;
+ totalPackSize2 += totalPackSize;
+ }
+ if (totalUnPackSizePointer != 0)
+ {
+ totalUnPackSizePointer2 = &totalUnPackSize2;
+ totalUnPackSize2 += totalUnPackSize;
+ }
+ numFiles2 += numFiles;
+ }
+ if (enableHeaders && !techMode && archivePaths.Size() > 1)
+ {
+ g_StdOut << endl;
+ fieldPrinter.PrintTitleLines();
+ g_StdOut << endl;
+ fieldPrinter.PrintSummaryInfo(numFiles2, totalUnPackSizePointer2, totalPackSizePointer2);
+ g_StdOut << endl;
+ g_StdOut << "Archives: " << archivePaths.Size() << endl;
+ }
+ if (numErrors > 0)
+ g_StdOut << endl << "Errors: " << numErrors;
+ return S_OK;
+}
diff --git a/CPP/7zip/UI/Console/List.h b/CPP/7zip/UI/Console/List.h
new file mode 100755
index 00000000..201a4128
--- /dev/null
+++ b/CPP/7zip/UI/Console/List.h
@@ -0,0 +1,13 @@
+// List.h
+
+#ifndef __LIST_H
+#define __LIST_H
+
+#include "Common/Wildcard.h"
+
+HRESULT ListArchives(UStringVector &archivePaths, UStringVector &archivePathsFull,
+ const NWildcard::CCensorNode &wildcardCensor,
+ bool enableHeaders, bool techMode, bool &passwordEnabled, UString &password);
+
+#endif
+
diff --git a/CPP/7zip/UI/Console/Main.cpp b/CPP/7zip/UI/Console/Main.cpp
new file mode 100755
index 00000000..387b8c2a
--- /dev/null
+++ b/CPP/7zip/UI/Console/Main.cpp
@@ -0,0 +1,382 @@
+// Main.cpp
+
+#include "StdAfx.h"
+
+#include <io.h>
+
+#include "Common/MyInitGuid.h"
+#include "Common/CommandLineParser.h"
+#include "Common/StdOutStream.h"
+#include "Common/Wildcard.h"
+#include "Common/ListFileUtils.h"
+#include "Common/StringConvert.h"
+#include "Common/StdInStream.h"
+#include "Common/StringToInt.h"
+#include "Common/Exception.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileName.h"
+#include "Windows/Defs.h"
+#include "Windows/Error.h"
+// #include "Windows/System.h"
+#ifdef _WIN32
+#include "Windows/MemoryLock.h"
+#endif
+
+#include "../../IPassword.h"
+#include "../../ICoder.h"
+#include "../Common/ArchiverInfo.h"
+#include "../Common/UpdateAction.h"
+#include "../Common/Update.h"
+#include "../Common/Extract.h"
+#include "../Common/ArchiveCommandLine.h"
+#include "../Common/ExitCode.h"
+
+#include "List.h"
+#include "OpenCallbackConsole.h"
+#include "ExtractCallbackConsole.h"
+#include "UpdateCallbackConsole.h"
+
+#include "../../MyVersion.h"
+
+#ifndef EXCLUDE_COM
+#include "Windows/DLL.h"
+#endif
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NCommandLineParser;
+
+HINSTANCE g_hInstance = 0;
+extern CStdOutStream *g_StdStream;
+
+static const char *kCopyrightString = "\n7-Zip"
+#ifdef EXCLUDE_COM
+" (A)"
+#endif
+
+#ifdef UNICODE
+" [NT]"
+#endif
+
+" " MY_VERSION_COPYRIGHT_DATE "\n";
+
+static const char *kHelpString =
+ "\nUsage: 7z"
+#ifdef _NO_CRYPTO
+ "r"
+#elif EXCLUDE_COM
+ "a"
+#endif
+ " <command> [<switches>...] <archive_name> [<file_names>...]\n"
+ " [<@listfiles...>]\n"
+ "\n"
+ "<Commands>\n"
+ " a: Add files to archive\n"
+ " d: Delete files from archive\n"
+ " e: Extract files from archive (without using directory names)\n"
+ " l: List contents of archive\n"
+// " l[a|t][f]: List contents of archive\n"
+// " a - with Additional fields\n"
+// " t - with all fields\n"
+// " f - with Full pathnames\n"
+ " t: Test integrity of archive\n"
+ " u: Update files to archive\n"
+ " x: eXtract files with full paths\n"
+ "<Switches>\n"
+ " -ai[r[-|0]]{@listfile|!wildcard}: Include archives\n"
+ " -ax[r[-|0]]{@listfile|!wildcard}: eXclude archives\n"
+ " -bd: Disable percentage indicator\n"
+ " -i[r[-|0]]{@listfile|!wildcard}: Include filenames\n"
+ " -m{Parameters}: set compression Method\n"
+ " -o{Directory}: set Output directory\n"
+ " -p{Password}: set Password\n"
+ " -r[-|0]: Recurse subdirectories\n"
+ " -scs{UTF-8 | WIN | DOS}: set charset for list files\n"
+ " -sfx[{name}]: Create SFX archive\n"
+ " -si[{name}]: read data from stdin\n"
+ " -slt: show technical information for l (List) command\n"
+ " -so: write data to stdout\n"
+ " -t{Type}: Set type of archive\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"
+ " -y: assume Yes on all queries\n";
+
+// ---------------------------
+// exception messages
+
+static const char *kProcessArchiveMessage = " archive: ";
+static const char *kEverythingIsOk = "Everything is Ok";
+static const char *kUserErrorMessage = "Incorrect command line"; // NExitCode::kUserError
+
+static const wchar_t *kDefaultSfxModule = L"7zCon.sfx";
+
+static void ShowMessageAndThrowException(CStdOutStream &s, LPCSTR message, NExitCode::EEnum code)
+{
+ s << message << endl;
+ throw code;
+}
+
+static void PrintHelpAndExit(CStdOutStream &s) // yyy
+{
+ s << kHelpString;
+ ShowMessageAndThrowException(s, kUserErrorMessage, NExitCode::kUserError);
+}
+
+#ifndef _WIN32
+static void GetArguments(int numArguments, const char *arguments[], UStringVector &parts)
+{
+ parts.Clear();
+ for(int i = 0; i < numArguments; i++)
+ {
+ UString s = MultiByteToUnicodeString(arguments[i]);
+ parts.Add(s);
+ }
+}
+#endif
+
+static void ShowCopyrightAndHelp(CStdOutStream &s, bool needHelp)
+{
+ s << kCopyrightString;
+ /*
+ UInt32 numCPUs = NWindows::NSystem::GetNumberOfProcessors();
+ s << "System configuration: " << (UInt64)numCPUs << " CPU";
+ if (numCPUs > 1)
+ s << "s";
+ s << "\n";
+ */
+ if (needHelp)
+ s << kHelpString;
+}
+
+int Main2(
+ #ifndef _WIN32
+ int numArguments, const char *arguments[]
+ #endif
+)
+{
+ #ifdef _WIN32
+ SetFileApisToOEM();
+ #endif
+
+ UStringVector commandStrings;
+ #ifdef _WIN32
+ NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
+ #else
+ GetArguments(numArguments, arguments, commandStrings);
+ #endif
+
+ if(commandStrings.Size() == 1)
+ {
+ ShowCopyrightAndHelp(g_StdOut, true);
+ return 0;
+ }
+ commandStrings.Delete(0);
+
+ CArchiveCommandLineOptions options;
+
+ CArchiveCommandLineParser parser;
+
+ parser.Parse1(commandStrings, options);
+
+ if(options.HelpMode)
+ {
+ ShowCopyrightAndHelp(g_StdOut, true);
+ return 0;
+ }
+
+ #ifdef _WIN32
+ if (options.LargePages)
+ NSecurity::EnableLockMemoryPrivilege();
+ #endif
+
+ CStdOutStream &stdStream = options.StdOutMode ? g_StdErr : g_StdOut;
+ g_StdStream = &stdStream;
+
+ if (options.EnableHeaders)
+ ShowCopyrightAndHelp(stdStream, false);
+
+ parser.Parse2(options);
+
+ bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
+ if(isExtractGroupCommand ||
+ options.Command.CommandType == NCommandType::kList)
+ {
+ if(isExtractGroupCommand)
+ {
+ CExtractCallbackConsole *ecs = new CExtractCallbackConsole;
+ CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
+
+ ecs->OutStream = &stdStream;
+ ecs->PasswordIsDefined = options.PasswordEnabled;
+ ecs->Password = options.Password;
+ ecs->Init();
+
+ COpenCallbackConsole openCallback;
+ openCallback.OutStream = &stdStream;
+ openCallback.PasswordIsDefined = options.PasswordEnabled;
+ openCallback.Password = options.Password;
+
+ CExtractOptions eo;
+ eo.StdOutMode = options.StdOutMode;
+ eo.PathMode = options.Command.GetPathMode();
+ eo.TestMode = options.Command.IsTestMode();
+ eo.OverwriteMode = options.OverwriteMode;
+ eo.OutputDir = options.OutputDir;
+ eo.YesToAll = options.YesToAll;
+ #ifdef COMPRESS_MT
+ eo.Properties = options.ExtractProperties;
+ #endif
+ UString errorMessage;
+ HRESULT result = DecompressArchives(
+ options.ArchivePathsSorted,
+ options.ArchivePathsFullSorted,
+ options.WildcardCensor.Pairs.Front().Head,
+ eo, &openCallback, ecs, errorMessage);
+ if (!errorMessage.IsEmpty())
+ {
+ stdStream << endl << "Error: " << errorMessage;
+ if (result == S_OK)
+ result = E_FAIL;
+ }
+
+ if (ecs->NumArchives > 1)
+ {
+ stdStream << endl << endl << "Total:" << endl;
+ stdStream << "Archives: " << ecs->NumArchives << endl;
+ }
+ if (ecs->NumArchiveErrors != 0 || ecs->NumFileErrors != 0)
+ {
+ if (ecs->NumArchives > 1)
+ {
+ if (ecs->NumArchiveErrors != 0)
+ stdStream << "Archive Errors: " << ecs->NumArchiveErrors << endl;
+ 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)
+ throw CSystemException(result);
+ }
+ else
+ {
+ HRESULT result = ListArchives(
+ options.ArchivePathsSorted,
+ options.ArchivePathsFullSorted,
+ options.WildcardCensor.Pairs.Front().Head,
+ options.EnableHeaders,
+ options.TechMode,
+ options.PasswordEnabled,
+ options.Password);
+ if (result != S_OK)
+ throw CSystemException(result);
+ }
+ }
+ else if(options.Command.IsFromUpdateGroup())
+ {
+ UString workingDir;
+
+ CUpdateOptions &uo = options.UpdateOptions;
+ if (uo.SfxMode && uo.SfxModule.IsEmpty())
+ uo.SfxModule = kDefaultSfxModule;
+
+ bool passwordIsDefined =
+ options.PasswordEnabled && !options.Password.IsEmpty();
+
+ COpenCallbackConsole openCallback;
+ openCallback.OutStream = &stdStream;
+ openCallback.PasswordIsDefined = passwordIsDefined;
+ openCallback.Password = options.Password;
+
+ CUpdateCallbackConsole callback;
+ callback.EnablePercents = options.EnablePercents;
+ callback.PasswordIsDefined = passwordIsDefined;
+ callback.AskPassword = options.PasswordEnabled && options.Password.IsEmpty();
+ callback.Password = options.Password;
+ callback.StdOutMode = uo.StdOutMode;
+ callback.Init(&stdStream);
+
+ CUpdateErrorInfo errorInfo;
+
+ HRESULT result = UpdateArchive(options.WildcardCensor, uo,
+ errorInfo, &openCallback, &callback);
+
+ int exitCode = NExitCode::kSuccess;
+ if (callback.CantFindFiles.Size() > 0)
+ {
+ stdStream << endl;
+ stdStream << "WARNINGS for files:" << endl << endl;
+ int numErrors = callback.CantFindFiles.Size();
+ for (int i = 0; i < numErrors; i++)
+ {
+ stdStream << callback.CantFindFiles[i] << " : ";
+ stdStream << NError::MyFormatMessageW(callback.CantFindCodes[i]) << endl;
+ }
+ stdStream << "----------------" << endl;
+ stdStream << "WARNING: Cannot find " << numErrors << " file";
+ if (numErrors > 1)
+ stdStream << "s";
+ stdStream << endl;
+ exitCode = NExitCode::kWarning;
+ }
+
+ if (result != S_OK)
+ {
+ UString message;
+ if (!errorInfo.Message.IsEmpty())
+ {
+ message += errorInfo.Message;
+ message += L"\n";
+ }
+ if (!errorInfo.FileName.IsEmpty())
+ {
+ message += errorInfo.FileName;
+ message += L"\n";
+ }
+ if (!errorInfo.FileName2.IsEmpty())
+ {
+ message += errorInfo.FileName2;
+ message += L"\n";
+ }
+ if (errorInfo.SystemError != 0)
+ {
+ message += NError::MyFormatMessageW(errorInfo.SystemError);
+ message += L"\n";
+ }
+ if (!message.IsEmpty())
+ stdStream << L"\nError:\n" << message;
+ throw CSystemException(result);
+ }
+ int numErrors = callback.FailedFiles.Size();
+ if (numErrors == 0)
+ {
+ if (callback.CantFindFiles.Size() == 0)
+ stdStream << kEverythingIsOk << endl;
+ }
+ else
+ {
+ stdStream << endl;
+ stdStream << "WARNINGS for files:" << endl << endl;
+ for (int i = 0; i < numErrors; i++)
+ {
+ stdStream << callback.FailedFiles[i] << " : ";
+ stdStream << NError::MyFormatMessageW(callback.FailedCodes[i]) << endl;
+ }
+ stdStream << "----------------" << endl;
+ stdStream << "WARNING: Cannot open " << numErrors << " file";
+ if (numErrors > 1)
+ stdStream << "s";
+ stdStream << endl;
+ exitCode = NExitCode::kWarning;
+ }
+ return exitCode;
+ }
+ else
+ PrintHelpAndExit(stdStream);
+ return 0;
+}
diff --git a/CPP/7zip/UI/Console/MainAr.cpp b/CPP/7zip/UI/Console/MainAr.cpp
new file mode 100755
index 00000000..4bdf813a
--- /dev/null
+++ b/CPP/7zip/UI/Console/MainAr.cpp
@@ -0,0 +1,169 @@
+// MainAr.cpp
+
+#include "StdAfx.h"
+
+// #include <locale.h>
+
+#include "Windows/Error.h"
+
+#include "Common/StdOutStream.h"
+#include "Common/NewHandler.h"
+#include "Common/Exception.h"
+#include "Common/StringConvert.h"
+#ifdef _WIN32
+#include "Common/Alloc.h"
+#endif
+
+#include "../Common/ExitCode.h"
+#include "../Common/ArchiveCommandLine.h"
+#include "ConsoleClose.h"
+
+#ifdef CRC_GENERATE_TABLE
+extern "C"
+{
+ #include "../../../../C/7zCrc.h"
+}
+#endif
+
+using namespace NWindows;
+
+CStdOutStream *g_StdStream = 0;
+
+#ifndef _UNICODE
+bool g_IsNT = false;
+#endif
+
+extern int Main2(
+ #ifndef _WIN32
+ int numArguments, const char *arguments[]
+ #endif
+);
+
+static const char *kExceptionErrorMessage = "\n\nError:\n";
+static const char *kUserBreak = "\nBreak signaled\n";
+
+static const char *kMemoryExceptionMessage = "\n\nERROR: Can't allocate required memory!\n";
+static const char *kUnknownExceptionMessage = "\n\nUnknown Error\n";
+static const char *kInternalExceptionMessage = "\n\nInternal Error #";
+
+static inline bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+
+int
+#ifdef _MSC_VER
+__cdecl
+#endif
+main
+(
+#ifndef _WIN32
+int numArguments, const char *arguments[]
+#endif
+)
+{
+ #ifdef CRC_GENERATE_TABLE
+ CrcGenerateTable();
+ #endif
+ g_StdStream = &g_StdOut;
+ #ifdef _UNICODE
+ if (!IsItWindowsNT())
+ {
+ (*g_StdStream) << "This program requires Windows NT/2000/XP/2003";
+ return NExitCode::kFatalError;
+ }
+ #else
+ g_IsNT = IsItWindowsNT();
+ #endif
+
+ #ifdef _WIN32
+ SetLargePageSize();
+ #endif
+
+ // setlocale(LC_COLLATE, ".OCP");
+ NConsoleClose::CCtrlHandlerSetter ctrlHandlerSetter;
+ int res = 0;
+ try
+ {
+ res = Main2(
+#ifndef _WIN32
+ numArguments, arguments
+#endif
+ );
+ }
+ catch(const CNewException &)
+ {
+ (*g_StdStream) << kMemoryExceptionMessage;
+ return (NExitCode::kMemoryError);
+ }
+ catch(const NConsoleClose::CCtrlBreakException &)
+ {
+ (*g_StdStream) << endl << kUserBreak;
+ return (NExitCode::kUserBreak);
+ }
+ catch(const CArchiveCommandLineException &e)
+ {
+ (*g_StdStream) << kExceptionErrorMessage << e << endl;
+ return (NExitCode::kUserError);
+ }
+ catch(const CSystemException &systemError)
+ {
+ if (systemError.ErrorCode == E_OUTOFMEMORY)
+ {
+ (*g_StdStream) << kMemoryExceptionMessage;
+ return (NExitCode::kMemoryError);
+ }
+ if (systemError.ErrorCode == E_ABORT)
+ {
+ (*g_StdStream) << endl << kUserBreak;
+ return (NExitCode::kUserBreak);
+ }
+ UString message;
+ NError::MyFormatMessage(systemError.ErrorCode, message);
+ (*g_StdStream) << endl << endl << "System error:" << endl <<
+ message << endl;
+ return (NExitCode::kFatalError);
+ }
+ catch(NExitCode::EEnum &exitCode)
+ {
+ (*g_StdStream) << kInternalExceptionMessage << exitCode << endl;
+ return (exitCode);
+ }
+ /*
+ catch(const NExitCode::CMultipleErrors &multipleErrors)
+ {
+ (*g_StdStream) << endl << multipleErrors.NumErrors << " errors" << endl;
+ return (NExitCode::kFatalError);
+ }
+ */
+ catch(const UString &s)
+ {
+ (*g_StdStream) << kExceptionErrorMessage << s << endl;
+ return (NExitCode::kFatalError);
+ }
+ catch(const AString &s)
+ {
+ (*g_StdStream) << kExceptionErrorMessage << s << endl;
+ return (NExitCode::kFatalError);
+ }
+ catch(const char *s)
+ {
+ (*g_StdStream) << kExceptionErrorMessage << s << endl;
+ return (NExitCode::kFatalError);
+ }
+ catch(int t)
+ {
+ (*g_StdStream) << kInternalExceptionMessage << t << endl;
+ return (NExitCode::kFatalError);
+ }
+ catch(...)
+ {
+ (*g_StdStream) << kUnknownExceptionMessage;
+ return (NExitCode::kFatalError);
+ }
+ return res;
+}
diff --git a/CPP/7zip/UI/Console/OpenCallbackConsole.cpp b/CPP/7zip/UI/Console/OpenCallbackConsole.cpp
new file mode 100755
index 00000000..06ff165f
--- /dev/null
+++ b/CPP/7zip/UI/Console/OpenCallbackConsole.cpp
@@ -0,0 +1,58 @@
+// OpenCallbackConsole.cpp
+
+#include "StdAfx.h"
+
+#include "OpenCallbackConsole.h"
+
+#include "ConsoleClose.h"
+#include "UserInputUtils.h"
+
+HRESULT COpenCallbackConsole::CheckBreak()
+{
+ if (NConsoleClose::TestBreakSignal())
+ return E_ABORT;
+ return S_OK;
+}
+
+HRESULT COpenCallbackConsole::SetTotal(const UInt64 *, const UInt64 *)
+{
+ return CheckBreak();
+}
+
+HRESULT COpenCallbackConsole::SetCompleted(const UInt64 *, const UInt64 *)
+{
+ return CheckBreak();
+}
+
+HRESULT COpenCallbackConsole::CryptoGetTextPassword(BSTR *password)
+{
+ PasswordWasAsked = true;
+ RINOK(CheckBreak());
+ if (!PasswordIsDefined)
+ {
+ Password = GetPassword(OutStream);
+ PasswordIsDefined = true;
+ }
+ CMyComBSTR temp(Password);
+ *password = temp.Detach();
+ return S_OK;
+}
+
+HRESULT COpenCallbackConsole::GetPasswordIfAny(UString &password)
+{
+ if (PasswordIsDefined)
+ password = Password;
+ return S_OK;
+}
+
+bool COpenCallbackConsole::WasPasswordAsked()
+{
+ return PasswordWasAsked;
+}
+
+void COpenCallbackConsole::ClearPasswordWasAskedFlag()
+{
+ PasswordWasAsked = false;
+}
+
+
diff --git a/CPP/7zip/UI/Console/OpenCallbackConsole.h b/CPP/7zip/UI/Console/OpenCallbackConsole.h
new file mode 100755
index 00000000..db0e9bd8
--- /dev/null
+++ b/CPP/7zip/UI/Console/OpenCallbackConsole.h
@@ -0,0 +1,27 @@
+// OpenCallbackConsole.h
+
+#ifndef __OPENCALLBACKCONSOLE_H
+#define __OPENCALLBACKCONSOLE_H
+
+#include "Common/StdOutStream.h"
+#include "../Common/ArchiveOpenCallback.h"
+
+class COpenCallbackConsole: public IOpenCallbackUI
+{
+public:
+ HRESULT CheckBreak();
+ HRESULT SetTotal(const UInt64 *files, const UInt64 *bytes);
+ HRESULT SetCompleted(const UInt64 *files, const UInt64 *bytes);
+ HRESULT CryptoGetTextPassword(BSTR *password);
+ HRESULT GetPasswordIfAny(UString &password);
+ bool WasPasswordAsked();
+ void ClearPasswordWasAskedFlag();
+
+ CStdOutStream *OutStream;
+ bool PasswordIsDefined;
+ UString Password;
+ bool PasswordWasAsked;
+ COpenCallbackConsole(): PasswordIsDefined(false), PasswordWasAsked(false) {}
+};
+
+#endif
diff --git a/CPP/7zip/UI/Console/PercentPrinter.cpp b/CPP/7zip/UI/Console/PercentPrinter.cpp
new file mode 100755
index 00000000..ec87b5d4
--- /dev/null
+++ b/CPP/7zip/UI/Console/PercentPrinter.cpp
@@ -0,0 +1,90 @@
+// PercentPrinter.cpp
+
+#include "StdAfx.h"
+
+#include "Common/IntToString.h"
+#include "Common/String.h"
+
+#include "PercentPrinter.h"
+
+const int kPaddingSize = 2;
+const int kPercentsSize = 4;
+const int kMaxExtraSize = kPaddingSize + 32 + kPercentsSize;
+
+static void ClearPrev(char *p, int num)
+{
+ int i;
+ for (i = 0; i < num; i++) *p++ = '\b';
+ for (i = 0; i < num; i++) *p++ = ' ';
+ for (i = 0; i < num; i++) *p++ = '\b';
+ *p = '\0';
+}
+
+void CPercentPrinter::ClosePrint()
+{
+ if (m_NumExtraChars == 0)
+ return;
+ char s[kMaxExtraSize * 3 + 1];
+ ClearPrev(s, m_NumExtraChars);
+ (*OutStream) << s;
+ m_NumExtraChars = 0;
+}
+
+void CPercentPrinter::PrintString(const char *s)
+{
+ ClosePrint();
+ (*OutStream) << s;
+}
+
+void CPercentPrinter::PrintString(const wchar_t *s)
+{
+ ClosePrint();
+ (*OutStream) << s;
+}
+
+void CPercentPrinter::PrintNewLine()
+{
+ ClosePrint();
+ (*OutStream) << "\n";
+}
+
+void CPercentPrinter::RePrintRatio()
+{
+ char s[32];
+ ConvertUInt64ToString(((m_Total == 0) ? 0 : (m_CurValue * 100 / m_Total)), s);
+ int size = (int)strlen(s);
+ s[size++] = '%';
+ s[size] = '\0';
+
+ int extraSize = kPaddingSize + MyMax(size, kPercentsSize);
+ if (extraSize < m_NumExtraChars)
+ extraSize = m_NumExtraChars;
+
+ char fullString[kMaxExtraSize * 3];
+ char *p = fullString;
+ int i;
+ if (m_NumExtraChars == 0)
+ {
+ for (i = 0; i < extraSize; i++)
+ *p++ = ' ';
+ m_NumExtraChars = extraSize;
+ }
+
+ for (i = 0; i < m_NumExtraChars; i++)
+ *p++ = '\b';
+ m_NumExtraChars = extraSize;
+ for (; size < m_NumExtraChars; size++)
+ *p++ = ' ';
+ strcpy(p, s);
+ (*OutStream) << fullString;
+ OutStream->Flush();
+ m_PrevValue = m_CurValue;
+}
+
+void CPercentPrinter::PrintRatio()
+{
+ if (m_CurValue < m_PrevValue + m_MinStepSize &&
+ m_CurValue + m_MinStepSize > m_PrevValue && m_NumExtraChars != 0)
+ return;
+ RePrintRatio();
+}
diff --git a/CPP/7zip/UI/Console/PercentPrinter.h b/CPP/7zip/UI/Console/PercentPrinter.h
new file mode 100755
index 00000000..e8b40916
--- /dev/null
+++ b/CPP/7zip/UI/Console/PercentPrinter.h
@@ -0,0 +1,31 @@
+// PercentPrinter.h
+
+#ifndef __PERCENTPRINTER_H
+#define __PERCENTPRINTER_H
+
+#include "Common/Types.h"
+#include "Common/StdOutStream.h"
+
+class CPercentPrinter
+{
+ UInt64 m_MinStepSize;
+ UInt64 m_PrevValue;
+ UInt64 m_CurValue;
+ UInt64 m_Total;
+ int m_NumExtraChars;
+public:
+ CStdOutStream *OutStream;
+
+ CPercentPrinter(UInt64 minStepSize = 1): m_MinStepSize(minStepSize),
+ m_PrevValue(0), m_CurValue(0), m_Total(1), m_NumExtraChars(0) {}
+ void SetTotal(UInt64 total) { m_Total = total; m_PrevValue = 0; }
+ void SetRatio(UInt64 doneValue) { m_CurValue = doneValue; }
+ void PrintString(const char *s);
+ void PrintString(const wchar_t *s);
+ void PrintNewLine();
+ void ClosePrint();
+ void RePrintRatio();
+ void PrintRatio();
+};
+
+#endif
diff --git a/CPP/7zip/UI/Console/StdAfx.cpp b/CPP/7zip/UI/Console/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/UI/Console/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/UI/Console/StdAfx.h b/CPP/7zip/UI/Console/StdAfx.h
new file mode 100755
index 00000000..8531cc9c
--- /dev/null
+++ b/CPP/7zip/UI/Console/StdAfx.h
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp b/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
new file mode 100755
index 00000000..5cbc11c0
--- /dev/null
+++ b/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
@@ -0,0 +1,196 @@
+// UpdateCallbackConsole.cpp
+
+#include "StdAfx.h"
+
+#include "UpdateCallbackConsole.h"
+
+#include "Windows/Error.h"
+#ifdef COMPRESS_MT
+#include "Windows/Synchronization.h"
+#endif
+
+#include "ConsoleClose.h"
+#include "UserInputUtils.h"
+
+using namespace NWindows;
+
+#ifdef COMPRESS_MT
+static NSynchronization::CCriticalSection g_CriticalSection;
+#define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
+#else
+#define MT_LOCK
+#endif
+
+static const wchar_t *kEmptyFileAlias = L"[Content]";
+
+static const char *kCreatingArchiveMessage = "Creating archive ";
+static const char *kUpdatingArchiveMessage = "Updating archive ";
+static const char *kScanningMessage = "Scanning";
+static const char *kNoFilesScannedMessage = "No files scanned";
+static const char *kTotalFilesAddedMessage = "Total files added to archive: ";
+
+
+HRESULT CUpdateCallbackConsole::OpenResult(const wchar_t *name, HRESULT result)
+{
+ (*OutStream) << endl;
+ if (result != S_OK)
+ (*OutStream) << "Error: " << name << " is not supported archive" << endl;
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::StartScanning()
+{
+ (*OutStream) << kScanningMessage;
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::CanNotFindError(const wchar_t *name, DWORD systemError)
+{
+ CantFindFiles.Add(name);
+ CantFindCodes.Add(systemError);
+ // m_PercentPrinter.ClosePrint();
+ if (!m_WarningsMode)
+ {
+ (*OutStream) << endl << endl;
+ m_PercentPrinter.PrintNewLine();
+ m_WarningsMode = true;
+ }
+ m_PercentPrinter.PrintString(name);
+ m_PercentPrinter.PrintString(": WARNING: ");
+ m_PercentPrinter.PrintString(NError::MyFormatMessageW(systemError));
+ m_PercentPrinter.PrintNewLine();
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::FinishScanning()
+{
+ (*OutStream) << endl << endl;
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::StartArchive(const wchar_t *name, bool updating)
+{
+ if(updating)
+ (*OutStream) << kUpdatingArchiveMessage;
+ else
+ (*OutStream) << kCreatingArchiveMessage;
+ if (name != 0)
+ (*OutStream) << name;
+ else
+ (*OutStream) << "StdOut";
+ (*OutStream) << endl << endl;
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::FinishArchive()
+{
+ (*OutStream) << endl;
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::CheckBreak()
+{
+ if (NConsoleClose::TestBreakSignal())
+ return E_ABORT;
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::Finilize()
+{
+ MT_LOCK
+ if (m_NeedBeClosed)
+ {
+ if (EnablePercents)
+ {
+ m_PercentPrinter.ClosePrint();
+ }
+ if (!StdOutMode && m_NeedNewLine)
+ {
+ m_PercentPrinter.PrintNewLine();
+ m_NeedNewLine = false;
+ }
+ m_NeedBeClosed = false;
+ }
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::SetTotal(UInt64 size)
+{
+ MT_LOCK
+ if (EnablePercents)
+ m_PercentPrinter.SetTotal(size);
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::SetCompleted(const UInt64 *completeValue)
+{
+ MT_LOCK
+ if (completeValue != NULL)
+ {
+ if (EnablePercents)
+ {
+ m_PercentPrinter.SetRatio(*completeValue);
+ m_PercentPrinter.PrintRatio();
+ m_NeedBeClosed = true;
+ }
+ }
+ if (NConsoleClose::TestBreakSignal())
+ return E_ABORT;
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool isAnti)
+{
+ MT_LOCK
+ if (StdOutMode)
+ return S_OK;
+ if(isAnti)
+ m_PercentPrinter.PrintString("Anti item ");
+ else
+ m_PercentPrinter.PrintString("Compressing ");
+ if (name[0] == 0)
+ name = kEmptyFileAlias;
+ m_PercentPrinter.PrintString(name);
+ if (EnablePercents)
+ m_PercentPrinter.RePrintRatio();
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::OpenFileError(const wchar_t *name, DWORD systemError)
+{
+ MT_LOCK
+ FailedCodes.Add(systemError);
+ FailedFiles.Add(name);
+ // if (systemError == ERROR_SHARING_VIOLATION)
+ {
+ m_PercentPrinter.ClosePrint();
+ m_PercentPrinter.PrintNewLine();
+ m_PercentPrinter.PrintString("WARNING: ");
+ m_PercentPrinter.PrintString(NError::MyFormatMessageW(systemError));
+ return S_FALSE;
+ }
+ // return systemError;
+}
+
+HRESULT CUpdateCallbackConsole::SetOperationResult(Int32 )
+{
+ m_NeedBeClosed = true;
+ m_NeedNewLine = true;
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
+{
+ if (!PasswordIsDefined)
+ {
+ if (AskPassword)
+ {
+ Password = GetPassword(OutStream);
+ PasswordIsDefined = true;
+ }
+ }
+ *passwordIsDefined = BoolToInt(PasswordIsDefined);
+ CMyComBSTR tempName(Password);
+ *password = tempName.Detach();
+ return S_OK;
+}
diff --git a/CPP/7zip/UI/Console/UpdateCallbackConsole.h b/CPP/7zip/UI/Console/UpdateCallbackConsole.h
new file mode 100755
index 00000000..2fcb891b
--- /dev/null
+++ b/CPP/7zip/UI/Console/UpdateCallbackConsole.h
@@ -0,0 +1,75 @@
+// UpdateCallbackConsole.h
+
+#ifndef __UPDATECALLBACKCONSOLE_H
+#define __UPDATECALLBACKCONSOLE_H
+
+#include "Common/String.h"
+#include "Common/StdOutStream.h"
+#include "PercentPrinter.h"
+#include "../Common/Update.h"
+
+class CUpdateCallbackConsole: public IUpdateCallbackUI2
+{
+ CPercentPrinter m_PercentPrinter;
+ bool m_NeedBeClosed;
+ bool m_NeedNewLine;
+
+ bool m_WarningsMode;
+
+ CStdOutStream *OutStream;
+public:
+ bool EnablePercents;
+ bool StdOutMode;
+
+ bool PasswordIsDefined;
+ UString Password;
+ bool AskPassword;
+
+
+ CUpdateCallbackConsole():
+ m_PercentPrinter(1 << 16),
+ PasswordIsDefined(false),
+ AskPassword(false),
+ StdOutMode(false),
+ EnablePercents(true),
+ m_WarningsMode(false)
+ {}
+
+ ~CUpdateCallbackConsole() { Finilize(); }
+ void Init(CStdOutStream *outStream)
+ {
+ m_NeedBeClosed = false;
+ m_NeedNewLine = false;
+ FailedFiles.Clear();
+ FailedCodes.Clear();
+ OutStream = outStream;
+ m_PercentPrinter.OutStream = outStream;
+ }
+
+ HRESULT OpenResult(const wchar_t *name, HRESULT result);
+
+ HRESULT StartScanning();
+ HRESULT CanNotFindError(const wchar_t *name, DWORD systemError);
+ HRESULT FinishScanning();
+
+ HRESULT StartArchive(const wchar_t *name, bool updating);
+ HRESULT FinishArchive();
+
+ HRESULT CheckBreak();
+ HRESULT Finilize();
+ HRESULT SetTotal(UInt64 size);
+ HRESULT SetCompleted(const UInt64 *completeValue);
+
+ HRESULT GetStream(const wchar_t *name, bool isAnti);
+ HRESULT OpenFileError(const wchar_t *name, DWORD systemError);
+ HRESULT SetOperationResult(Int32 operationResult);
+ HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password);
+
+ UStringVector FailedFiles;
+ CRecordVector<HRESULT> FailedCodes;
+
+ UStringVector CantFindFiles;
+ CRecordVector<HRESULT> CantFindCodes;
+};
+
+#endif
diff --git a/CPP/7zip/UI/Console/UserInputUtils.cpp b/CPP/7zip/UI/Console/UserInputUtils.cpp
new file mode 100755
index 00000000..164af99c
--- /dev/null
+++ b/CPP/7zip/UI/Console/UserInputUtils.cpp
@@ -0,0 +1,58 @@
+// UserInputUtils.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StdInStream.h"
+#include "Common/StringConvert.h"
+
+#include "UserInputUtils.h"
+
+static const char kYes = 'Y';
+static const char kNo = 'N';
+static const char kYesAll = 'A';
+static const char kNoAll = 'S';
+static const char kAutoRename = 'U';
+static const char kQuit = 'Q';
+
+static const char *kFirstQuestionMessage = "?\n";
+static const char *kHelpQuestionMessage =
+ "(Y)es / (N)o / (A)lways / (S)kip all / A(u)to rename / (Q)uit? ";
+
+// return true if pressed Quite;
+// in: anAll
+// out: anAll, anYes;
+
+NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream)
+{
+ (*outStream) << kFirstQuestionMessage;
+ for(;;)
+ {
+ (*outStream) << kHelpQuestionMessage;
+ AString scannedString = g_StdIn.ScanStringUntilNewLine();
+ scannedString.Trim();
+ if(!scannedString.IsEmpty())
+ switch(::MyCharUpper(scannedString[0]))
+ {
+ case kYes:
+ return NUserAnswerMode::kYes;
+ case kNo:
+ return NUserAnswerMode::kNo;
+ case kYesAll:
+ return NUserAnswerMode::kYesAll;
+ case kNoAll:
+ return NUserAnswerMode::kNoAll;
+ case kAutoRename:
+ return NUserAnswerMode::kAutoRename;
+ case kQuit:
+ return NUserAnswerMode::kQuit;
+ }
+ }
+}
+
+UString GetPassword(CStdOutStream *outStream)
+{
+ (*outStream) << "\nEnter password:";
+ outStream->Flush();
+ AString oemPassword = g_StdIn.ScanStringUntilNewLine();
+ return MultiByteToUnicodeString(oemPassword, CP_OEMCP);
+}
diff --git a/CPP/7zip/UI/Console/UserInputUtils.h b/CPP/7zip/UI/Console/UserInputUtils.h
new file mode 100755
index 00000000..75c85ee6
--- /dev/null
+++ b/CPP/7zip/UI/Console/UserInputUtils.h
@@ -0,0 +1,24 @@
+// UserInputUtils.h
+
+#ifndef __USERINPUTUTILS_H
+#define __USERINPUTUTILS_H
+
+#include "Common/StdOutStream.h"
+
+namespace NUserAnswerMode {
+
+enum EEnum
+{
+ kYes,
+ kNo,
+ kYesAll,
+ kNoAll,
+ kAutoRename,
+ kQuit,
+};
+}
+
+NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream);
+UString GetPassword(CStdOutStream *outStream);
+
+#endif
diff --git a/CPP/7zip/UI/Console/afxres.h b/CPP/7zip/UI/Console/afxres.h
new file mode 100755
index 00000000..c2fadd4a
--- /dev/null
+++ b/CPP/7zip/UI/Console/afxres.h
@@ -0,0 +1 @@
+#include <winresrc.h>
diff --git a/CPP/7zip/UI/Console/makefile b/CPP/7zip/UI/Console/makefile
new file mode 100755
index 00000000..54e83ea1
--- /dev/null
+++ b/CPP/7zip/UI/Console/makefile
@@ -0,0 +1,93 @@
+PROG = 7z.exe
+LIBS = $(LIBS) user32.lib oleaut32.lib advapi32.lib
+CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_MT -DWIN_LONG_PATH
+
+CONSOLE_OBJS = \
+ $O\ConsoleClose.obj \
+ $O\ExtractCallbackConsole.obj \
+ $O\List.obj \
+ $O\Main.obj \
+ $O\MainAr.obj \
+ $O\OpenCallbackConsole.obj \
+ $O\PercentPrinter.obj \
+ $O\UpdateCallbackConsole.obj \
+ $O\UserInputUtils.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\CommandLineParser.obj \
+ $O\IntToString.obj \
+ $O\ListFileUtils.obj \
+ $O\NewHandler.obj \
+ $O\StdInStream.obj \
+ $O\StdOutStream.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\UTFConvert.obj \
+ $O\Vector.obj \
+ $O\Wildcard.obj \
+
+WIN_OBJS = \
+ $O\DLL.obj \
+ $O\Error.obj \
+ $O\FileDir.obj \
+ $O\FileFind.obj \
+ $O\FileIO.obj \
+ $O\FileName.obj \
+ $O\MemoryLock.obj \
+ $O\PropVariant.obj \
+ $O\PropVariantConversions.obj \
+ $O\Registry.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\FilePathAutoRename.obj \
+ $O\FileStreams.obj \
+ $O\StreamUtils.obj \
+
+UI_COMMON_OBJS = \
+ $O\ArchiveCommandLine.obj \
+ $O\ArchiveExtractCallback.obj \
+ $O\ArchiveOpenCallback.obj \
+ $O\ArchiverInfo.obj \
+ $O\DefaultName.obj \
+ $O\EnumDirItems.obj \
+ $O\Extract.obj \
+ $O\ExtractingFilePath.obj \
+ $O\OpenArchive.obj \
+ $O\PropIDUtils.obj \
+ $O\SetProperties.obj \
+ $O\SortUtils.obj \
+ $O\TempFiles.obj \
+ $O\Update.obj \
+ $O\UpdateAction.obj \
+ $O\UpdateCallback.obj \
+ $O\UpdatePair.obj \
+ $O\UpdateProduce.obj \
+ $O\WorkDir.obj \
+
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(CONSOLE_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(UI_COMMON_OBJS) \
+ $O\CopyCoder.obj \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(CONSOLE_OBJS): $(*B).cpp
+ $(COMPL)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$(UI_COMMON_OBJS): ../Common/$(*B).cpp
+ $(COMPL)
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/UI/Console/resource.rc b/CPP/7zip/UI/Console/resource.rc
new file mode 100755
index 00000000..6e09bb96
--- /dev/null
+++ b/CPP/7zip/UI/Console/resource.rc
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_APP("7-Zip Console", "7z")
diff --git a/CPP/7zip/UI/Explorer/7-zip.dll.manifest b/CPP/7zip/UI/Explorer/7-zip.dll.manifest
new file mode 100755
index 00000000..cba1c5df
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/7-zip.dll.manifest
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"><assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="7-Zip.7-Zip.7-zip" type="win32"/><description>7-Zip Extension.</description><dependency> <dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/></dependentAssembly></dependency></assembly>
diff --git a/CPP/7zip/UI/Explorer/ContextMenu.cpp b/CPP/7zip/UI/Explorer/ContextMenu.cpp
new file mode 100755
index 00000000..fd40add5
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/ContextMenu.cpp
@@ -0,0 +1,682 @@
+// ContextMenu.cpp
+
+#include "StdAfx.h"
+
+#include "ContextMenu.h"
+
+#include "Common/StringConvert.h"
+#include "Common/MyCom.h"
+
+#include "Windows/Shell.h"
+#include "Windows/Memory.h"
+#include "Windows/COM.h"
+#include "Windows/FileFind.h"
+#include "Windows/FileDir.h"
+#include "Windows/FileName.h"
+#include "Windows/Thread.h"
+#include "Windows/Window.h"
+
+#include "Windows/Menu.h"
+#include "Windows/ResourceString.h"
+
+#include "../../FileManager/FormatUtils.h"
+#include "../../FileManager/ProgramLocation.h"
+
+#include "../Common/ZipRegistry.h"
+#include "../Common/ArchiveName.h"
+
+#ifdef LANG
+#include "../../FileManager/LangUtils.h"
+#endif
+
+#include "resource.h"
+#include "ContextMenuFlags.h"
+
+// #include "ExtractEngine.h"
+// #include "TestEngine.h"
+// #include "CompressEngine.h"
+#include "MyMessages.h"
+
+#include "../Resource/Extract/resource.h"
+#include "../Common/CompressCall.h"
+
+using namespace NWindows;
+
+static LPCTSTR kFileClassIDString = TEXT("SevenZip");
+
+///////////////////////////////
+// IShellExtInit
+
+extern LONG g_DllRefCount;
+
+CZipContextMenu::CZipContextMenu() { InterlockedIncrement(&g_DllRefCount); }
+CZipContextMenu::~CZipContextMenu() { InterlockedDecrement(&g_DllRefCount); }
+
+HRESULT CZipContextMenu::GetFileNames(LPDATAOBJECT dataObject, UStringVector &fileNames)
+{
+ fileNames.Clear();
+ if(dataObject == NULL)
+ return E_FAIL;
+ FORMATETC fmte = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
+ NCOM::CStgMedium stgMedium;
+ HRESULT result = dataObject->GetData(&fmte, &stgMedium);
+ if (result != S_OK)
+ return result;
+ stgMedium._mustBeReleased = true;
+
+ NShell::CDrop drop(false);
+ NMemory::CGlobalLock globalLock(stgMedium->hGlobal);
+ drop.Attach((HDROP)globalLock.GetPointer());
+ drop.QueryFileNames(fileNames);
+
+ return S_OK;
+}
+
+STDMETHODIMP CZipContextMenu::Initialize(LPCITEMIDLIST pidlFolder,
+ LPDATAOBJECT dataObject, HKEY /* hkeyProgID */)
+{
+ // OutputDebugString(TEXT("::Initialize\r\n"));
+ _dropMode = false;
+ _dropPath.Empty();
+ if (pidlFolder != 0)
+ {
+ if (NShell::GetPathFromIDList(pidlFolder, _dropPath))
+ {
+ // OutputDebugString(path);
+ // OutputDebugString(TEXT("\r\n"));
+ NFile::NName::NormalizeDirPathPrefix(_dropPath);
+ _dropMode = !_dropPath.IsEmpty();
+ }
+ else
+ _dropPath.Empty();
+ }
+
+ /*
+ m_IsFolder = false;
+ if (pidlFolder == 0)
+ */
+ // pidlFolder is NULL :(
+ return GetFileNames(dataObject, _fileNames);
+}
+
+STDMETHODIMP CZipContextMenu::InitContextMenu(const wchar_t * /* folder */,
+ const wchar_t **names, UINT32 numFiles)
+{
+ _fileNames.Clear();
+ for (UINT32 i = 0; i < numFiles; i++)
+ _fileNames.Add(names[i]);
+ _dropMode = false;
+ return S_OK;
+}
+
+
+/////////////////////////////
+// IContextMenu
+
+static LPCWSTR kMainVerb = L"SevenZip";
+
+/*
+static LPCTSTR kOpenVerb = TEXT("SevenOpen");
+static LPCTSTR kExtractVerb = TEXT("SevenExtract");
+static LPCTSTR kExtractHereVerb = TEXT("SevenExtractHere");
+static LPCTSTR kExtractToVerb = TEXT("SevenExtractTo");
+static LPCTSTR kTestVerb = TEXT("SevenTest");
+static LPCTSTR kCompressVerb = TEXT("SevenCompress");
+static LPCTSTR kCompressToVerb = TEXT("SevenCompressTo");
+static LPCTSTR kCompressEmailVerb = TEXT("SevenCompressEmail");
+static LPCTSTR kCompressToEmailVerb = TEXT("SevenCompressToEmail");
+*/
+
+struct CContextMenuCommand
+{
+ UINT32 flag;
+ CZipContextMenu::ECommandInternalID CommandInternalID;
+ LPCWSTR Verb;
+ UINT ResourceID;
+ UINT ResourceHelpID;
+ UINT32 LangID;
+};
+
+static CContextMenuCommand g_Commands[] =
+{
+ {
+ NContextMenuFlags::kOpen,
+ CZipContextMenu::kOpen,
+ L"Open",
+ IDS_CONTEXT_OPEN,
+ IDS_CONTEXT_OPEN_HELP,
+ 0x02000103
+ },
+ {
+ NContextMenuFlags::kExtract,
+ CZipContextMenu::kExtract,
+ L"Extract",
+ IDS_CONTEXT_EXTRACT,
+ IDS_CONTEXT_EXTRACT_HELP,
+ 0x02000105
+ },
+ {
+ NContextMenuFlags::kExtractHere,
+ CZipContextMenu::kExtractHere,
+ L"ExtractHere",
+ IDS_CONTEXT_EXTRACT_HERE,
+ IDS_CONTEXT_EXTRACT_HERE_HELP,
+ 0x0200010B
+ },
+ {
+ NContextMenuFlags::kExtractTo,
+ CZipContextMenu::kExtractTo,
+ L"ExtractTo",
+ IDS_CONTEXT_EXTRACT_TO,
+ IDS_CONTEXT_EXTRACT_TO_HELP,
+ 0x0200010D
+ },
+ {
+ NContextMenuFlags::kTest,
+ CZipContextMenu::kTest,
+ L"Test",
+ IDS_CONTEXT_TEST,
+ IDS_CONTEXT_TEST_HELP,
+ 0x02000109
+ },
+ {
+ NContextMenuFlags::kCompress,
+ CZipContextMenu::kCompress,
+ L"Compress",
+ IDS_CONTEXT_COMPRESS,
+ IDS_CONTEXT_COMPRESS_HELP,
+ 0x02000107,
+ },
+ {
+ NContextMenuFlags::kCompressEmail,
+ CZipContextMenu::kCompressEmail,
+ L"CompressEmail",
+ IDS_CONTEXT_COMPRESS_EMAIL,
+ IDS_CONTEXT_COMPRESS_EMAIL_HELP,
+ 0x02000111
+ },
+ {
+ NContextMenuFlags::kCompressTo7z,
+ CZipContextMenu::kCompressTo7z,
+ L"CompressTo7z",
+ IDS_CONTEXT_COMPRESS_TO,
+ IDS_CONTEXT_COMPRESS_TO_HELP,
+ 0x0200010F
+ },
+ {
+ NContextMenuFlags::kCompressTo7zEmail,
+ CZipContextMenu::kCompressTo7zEmail,
+ L"CompressTo7zEmail",
+ IDS_CONTEXT_COMPRESS_TO_EMAIL,
+ IDS_CONTEXT_COMPRESS_TO_EMAIL_HELP,
+ 0x02000113
+ },
+ {
+ NContextMenuFlags::kCompressToZip,
+ CZipContextMenu::kCompressToZip,
+ L"CompressToZip",
+ IDS_CONTEXT_COMPRESS_TO,
+ IDS_CONTEXT_COMPRESS_TO_HELP,
+ 0x0200010F
+ },
+ {
+ NContextMenuFlags::kCompressToZipEmail,
+ CZipContextMenu::kCompressToZipEmail,
+ L"CompressToZipEmail",
+ IDS_CONTEXT_COMPRESS_TO_EMAIL,
+ IDS_CONTEXT_COMPRESS_TO_EMAIL_HELP,
+ 0x02000113
+ }
+};
+
+int FindCommand(CZipContextMenu::ECommandInternalID &id)
+{
+ for (int i = 0; i < sizeof(g_Commands) / sizeof(g_Commands[0]); i++)
+ if (g_Commands[i].CommandInternalID == id)
+ return i;
+ return -1;
+}
+
+void CZipContextMenu::FillCommand(ECommandInternalID id,
+ UString &mainString, CCommandMapItem &commandMapItem)
+{
+ int i = FindCommand(id);
+ if (i < 0)
+ return;
+ const CContextMenuCommand &command = g_Commands[i];
+ commandMapItem.CommandInternalID = command.CommandInternalID;
+ commandMapItem.Verb = (UString)kMainVerb + (UString)command.Verb;
+ commandMapItem.HelpString = LangString(command.ResourceHelpID, command.LangID + 1);
+ mainString = LangString(command.ResourceID, command.LangID);
+}
+
+static bool MyInsertMenu(CMenu &menu, int pos, UINT id, const UString &s)
+{
+ CMenuItem menuItem;
+ menuItem.fType = MFT_STRING;
+ menuItem.fMask = MIIM_TYPE | MIIM_ID;
+ menuItem.wID = id;
+ menuItem.StringValue = s;
+ return menu.InsertItem(pos, true, menuItem);
+}
+
+static UString GetSubFolderNameForExtract(const UString &archiveName)
+{
+ int dotPos = archiveName.ReverseFind(L'.');
+ if (dotPos < 0)
+ return archiveName + UString(L"~");
+ UString res = archiveName.Left(dotPos);
+ res.TrimRight();
+ return res;
+}
+
+static UString GetReducedString(const UString &s)
+{
+ const int kMaxSize = 64;
+ if (s.Length() < kMaxSize)
+ return s;
+ const int kFirstPartSize = kMaxSize / 2;
+ return s.Left(kFirstPartSize) + UString(L" ... ") + s.Right(kMaxSize - kFirstPartSize);
+}
+
+STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
+ UINT commandIDFirst, UINT commandIDLast, UINT flags)
+{
+ LoadLangOneTime();
+ if(_fileNames.Size() == 0)
+ return E_FAIL;
+ UINT currentCommandID = commandIDFirst;
+ if ((flags & 0x000F) != CMF_NORMAL &&
+ (flags & CMF_VERBSONLY) == 0 &&
+ (flags & CMF_EXPLORE) == 0)
+ return MAKE_HRESULT(SEVERITY_SUCCESS, 0, currentCommandID);
+
+ _commandMap.Clear();
+
+ CMenu popupMenu;
+ CMenuDestroyer menuDestroyer;
+
+ bool cascadedMenu = ReadCascadedMenu();
+ MENUITEMINFO menuItem;
+ UINT subIndex = indexMenu;
+ if (cascadedMenu)
+ {
+ CCommandMapItem commandMapItem;
+ if(!popupMenu.CreatePopup())
+ throw 210503;
+ menuDestroyer.Attach(popupMenu);
+ commandMapItem.CommandInternalID = kCommandNULL;
+ commandMapItem.Verb = kMainVerb;
+ commandMapItem.HelpString = LangString(IDS_CONTEXT_CAPTION_HELP, 0x02000102);
+ _commandMap.Add(commandMapItem);
+
+ menuItem.wID = currentCommandID++;
+ subIndex = 0;
+ }
+ else
+ {
+ popupMenu.Attach(hMenu);
+ }
+
+ UINT32 contextMenuFlags;
+ if (!ReadContextMenuStatus(contextMenuFlags))
+ contextMenuFlags = NContextMenuFlags::GetDefaultFlags();
+
+ UString mainString;
+ if(_fileNames.Size() == 1 && currentCommandID + 6 <= commandIDLast)
+ {
+ const UString &fileName = _fileNames.Front();
+ UString folderPrefix;
+ NFile::NDirectory::GetOnlyDirPrefix(fileName, folderPrefix);
+
+ NFile::NFind::CFileInfoW fileInfo;
+ if (!NFile::NFind::FindFile(fileName, fileInfo))
+ return E_FAIL;
+ if (!fileInfo.IsDirectory())
+ {
+ // Open
+ if ((contextMenuFlags & NContextMenuFlags::kOpen) != 0)
+ {
+ CCommandMapItem commandMapItem;
+ FillCommand(kOpen, mainString, commandMapItem);
+ MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString);
+ _commandMap.Add(commandMapItem);
+ }
+ }
+ }
+
+ if(_fileNames.Size() > 0 && currentCommandID + 10 <= commandIDLast)
+ {
+ bool thereAreFolders = false;
+ for(int i = 0; i < _fileNames.Size(); i++)
+ {
+ NFile::NFind::CFileInfoW fileInfo;
+ if (!NFile::NFind::FindFile(_fileNames[i], fileInfo))
+ return E_FAIL;
+ if (fileInfo.IsDirectory())
+ thereAreFolders = true;
+ }
+ const UString &fileName = _fileNames.Front();
+ if (!thereAreFolders)
+ {
+ UString folderPrefix;
+ NFile::NDirectory::GetOnlyDirPrefix(fileName, folderPrefix);
+ NFile::NFind::CFileInfoW fileInfo;
+ if (!NFile::NFind::FindFile(fileName, fileInfo))
+ return E_FAIL;
+ // Extract
+ if ((contextMenuFlags & NContextMenuFlags::kExtract) != 0)
+ {
+ CCommandMapItem commandMapItem;
+ FillCommand(kExtract, mainString, commandMapItem);
+ if (_dropMode)
+ commandMapItem.Folder = _dropPath;
+ else
+ commandMapItem.Folder = folderPrefix;
+ commandMapItem.Folder += GetSubFolderNameForExtract(fileInfo.Name) + UString(L'\\');
+ MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString);
+ _commandMap.Add(commandMapItem);
+ }
+
+ // Extract Here
+ if ((contextMenuFlags & NContextMenuFlags::kExtractHere) != 0)
+ {
+ CCommandMapItem commandMapItem;
+ FillCommand(kExtractHere, mainString, commandMapItem);
+ MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString);
+ if (_dropMode)
+ commandMapItem.Folder = _dropPath;
+ else
+ commandMapItem.Folder = folderPrefix;
+ _commandMap.Add(commandMapItem);
+ }
+
+ // Extract To
+ if ((contextMenuFlags & NContextMenuFlags::kExtractTo) != 0)
+ {
+ CCommandMapItem commandMapItem;
+ UString s;
+ FillCommand(kExtractTo, s, commandMapItem);
+ UString folder;
+ if (_fileNames.Size() == 1)
+ folder = GetSubFolderNameForExtract(fileInfo.Name);
+ else
+ folder = L'*';
+ if (_dropMode)
+ commandMapItem.Folder = _dropPath;
+ else
+ commandMapItem.Folder = folderPrefix;
+ commandMapItem.Folder += folder;
+ s = MyFormatNew(s, GetReducedString(UString(L"\"") + folder + UString(L"\\\"")));
+ MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s);
+ _commandMap.Add(commandMapItem);
+ }
+ // Test
+ if ((contextMenuFlags & NContextMenuFlags::kTest) != 0)
+ {
+ CCommandMapItem commandMapItem;
+ FillCommand(kTest, mainString, commandMapItem);
+ MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString);
+ _commandMap.Add(commandMapItem);
+ }
+ }
+ UString archiveName = CreateArchiveName(fileName, _fileNames.Size() > 1, false);
+ UString archiveName7z = archiveName + L".7z";
+ UString archiveNameZip = archiveName + L".zip";
+ UString archivePathPrefix;
+ NFile::NDirectory::GetOnlyDirPrefix(fileName, archivePathPrefix);
+
+ // Compress
+ if ((contextMenuFlags & NContextMenuFlags::kCompress) != 0)
+ {
+ CCommandMapItem commandMapItem;
+ if (_dropMode)
+ commandMapItem.Folder = _dropPath;
+ else
+ commandMapItem.Folder = archivePathPrefix;
+ commandMapItem.Archive = archiveName;
+ FillCommand(kCompress, mainString, commandMapItem);
+ MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString);
+ _commandMap.Add(commandMapItem);
+ }
+
+
+ // CompressEmail
+ if ((contextMenuFlags & NContextMenuFlags::kCompressEmail) != 0 && !_dropMode)
+ {
+ CCommandMapItem commandMapItem;
+ commandMapItem.Archive = archiveName;
+ FillCommand(kCompressEmail, mainString, commandMapItem);
+ MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString);
+ _commandMap.Add(commandMapItem);
+ }
+
+ // CompressTo7z
+ if (contextMenuFlags & NContextMenuFlags::kCompressTo7z)
+ {
+ CCommandMapItem commandMapItem;
+ UString s;
+ FillCommand(kCompressTo7z, s, commandMapItem);
+ if (_dropMode)
+ commandMapItem.Folder = _dropPath;
+ else
+ commandMapItem.Folder = archivePathPrefix;
+ commandMapItem.Archive = archiveName7z;
+ commandMapItem.ArchiveType = L"7z";
+ UString t = UString(L"\"") + GetReducedString(archiveName7z) + UString(L"\"");
+ s = MyFormatNew(s, t);
+ MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s);
+ _commandMap.Add(commandMapItem);
+ }
+
+ // CompressTo7zEmail
+ if ((contextMenuFlags & NContextMenuFlags::kCompressTo7zEmail) != 0 && !_dropMode)
+ {
+ CCommandMapItem commandMapItem;
+ UString s;
+ FillCommand(kCompressTo7zEmail, s, commandMapItem);
+ commandMapItem.Archive = archiveName7z;
+ commandMapItem.ArchiveType = L"7z";
+ UString t = UString(L"\"") + GetReducedString(archiveName7z) + UString(L"\"");
+ s = MyFormatNew(s, t);
+ MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s);
+ _commandMap.Add(commandMapItem);
+ }
+
+ // CompressToZip
+ if (contextMenuFlags & NContextMenuFlags::kCompressToZip)
+ {
+ CCommandMapItem commandMapItem;
+ UString s;
+ FillCommand(kCompressToZip, s, commandMapItem);
+ if (_dropMode)
+ commandMapItem.Folder = _dropPath;
+ else
+ commandMapItem.Folder = archivePathPrefix;
+ commandMapItem.Archive = archiveNameZip;
+ commandMapItem.ArchiveType = L"zip";
+ UString t = UString(L"\"") + GetReducedString(archiveNameZip) + UString(L"\"");
+ s = MyFormatNew(s, t);
+ MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s);
+ _commandMap.Add(commandMapItem);
+ }
+
+ // CompressToZipEmail
+ if ((contextMenuFlags & NContextMenuFlags::kCompressToZipEmail) != 0 && !_dropMode)
+ {
+ CCommandMapItem commandMapItem;
+ UString s;
+ FillCommand(kCompressToZipEmail, s, commandMapItem);
+ commandMapItem.Archive = archiveNameZip;
+ commandMapItem.ArchiveType = L"zip";
+ UString t = UString(L"\"") + GetReducedString(archiveNameZip) + UString(L"\"");
+ s = MyFormatNew(s, t);
+ MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s);
+ _commandMap.Add(commandMapItem);
+ }
+ }
+
+
+ // don't use InsertMenu: See MSDN:
+ // PRB: Duplicate Menu Items In the File Menu For a Shell Context Menu Extension
+ // ID: Q214477
+
+ if (cascadedMenu)
+ {
+ CMenuItem menuItem;
+ menuItem.fType = MFT_STRING;
+ menuItem.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID;
+ menuItem.wID = currentCommandID++;
+ menuItem.hSubMenu = popupMenu.Detach();
+ menuDestroyer.Disable();
+ menuItem.StringValue = LangString(IDS_CONTEXT_POPUP_CAPTION, 0x02000101);
+ CMenu menu;
+ menu.Attach(hMenu);
+ menu.InsertItem(indexMenu++, true, menuItem);
+ }
+
+ return MAKE_HRESULT(SEVERITY_SUCCESS, 0, currentCommandID - commandIDFirst);
+}
+
+
+int CZipContextMenu::FindVerb(const UString &verb)
+{
+ for(int i = 0; i < _commandMap.Size(); i++)
+ if(_commandMap[i].Verb.Compare(verb) == 0)
+ return i;
+ return -1;
+}
+
+extern const char *kShellFolderClassIDString;
+
+
+static UString GetProgramCommand()
+{
+ UString path = L"\"";
+ UString folder;
+ if (GetProgramFolderPath(folder))
+ path += folder;
+ path += L"7zFM.exe\"";
+ return path;
+}
+
+STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
+{
+ // ::OutputDebugStringA("1");
+ int commandOffset;
+
+ // It's fix for bug: crashing in XP. See example in MSDN: "Creating Context Menu Handlers".
+
+ if (commandInfo->cbSize == sizeof(CMINVOKECOMMANDINFOEX) &&
+ (commandInfo->fMask & CMIC_MASK_UNICODE) != 0)
+ {
+ LPCMINVOKECOMMANDINFOEX commandInfoEx = (LPCMINVOKECOMMANDINFOEX)commandInfo;
+ if(HIWORD(commandInfoEx->lpVerbW) == 0)
+ commandOffset = LOWORD(commandInfo->lpVerb);
+ else
+ commandOffset = FindVerb(commandInfoEx->lpVerbW);
+ }
+ else
+ if(HIWORD(commandInfo->lpVerb) == 0)
+ commandOffset = LOWORD(commandInfo->lpVerb);
+ else
+ commandOffset = FindVerb(GetUnicodeString(commandInfo->lpVerb));
+
+ if(commandOffset < 0 || commandOffset >= _commandMap.Size())
+ return E_FAIL;
+
+ const CCommandMapItem commandMapItem = _commandMap[commandOffset];
+ ECommandInternalID commandInternalID = commandMapItem.CommandInternalID;
+
+ try
+ {
+ switch(commandInternalID)
+ {
+ case kOpen:
+ {
+ UString params;
+ params = GetProgramCommand();
+ params += L" \"";
+ params += _fileNames[0];
+ params += L"\"";
+ MyCreateProcess(params, 0, false, 0);
+ break;
+ }
+ case kExtract:
+ case kExtractHere:
+ case kExtractTo:
+ {
+ ExtractArchives(_fileNames, commandMapItem.Folder,
+ (commandInternalID == kExtract));
+ break;
+ }
+ case kTest:
+ {
+ TestArchives(_fileNames);
+ break;
+ }
+ case kCompress:
+ case kCompressEmail:
+ case kCompressTo7z:
+ case kCompressTo7zEmail:
+ case kCompressToZip:
+ case kCompressToZipEmail:
+ {
+ bool email =
+ (commandInternalID == kCompressEmail) ||
+ (commandInternalID == kCompressTo7zEmail) ||
+ (commandInternalID == kCompressToZipEmail);
+ bool showDialog =
+ (commandInternalID == kCompress) ||
+ (commandInternalID == kCompressEmail);
+ CompressFiles(commandMapItem.Folder,
+ commandMapItem.Archive, commandMapItem.ArchiveType,
+ _fileNames, email, showDialog, false);
+ break;
+ }
+ }
+ }
+ catch(...)
+ {
+ MyMessageBox(IDS_ERROR, 0x02000605);
+ }
+ return S_OK;
+}
+
+static void MyCopyString(void *dest, const wchar_t *src, bool writeInUnicode)
+{
+ if(writeInUnicode)
+ {
+ MyStringCopy((wchar_t *)dest, src);
+ }
+ else
+ lstrcpyA((char *)dest, GetAnsiString(src));
+}
+
+STDMETHODIMP CZipContextMenu::GetCommandString(UINT_PTR commandOffset, UINT uType,
+ UINT * /* pwReserved */ , LPSTR pszName, UINT /* cchMax */)
+{
+ int cmdOffset = (int)commandOffset;
+ switch(uType)
+ {
+ case GCS_VALIDATEA:
+ case GCS_VALIDATEW:
+ if(cmdOffset < 0 || cmdOffset >= _commandMap.Size())
+ return S_FALSE;
+ else
+ return S_OK;
+ }
+ if(cmdOffset < 0 || cmdOffset >= _commandMap.Size())
+ return E_FAIL;
+ if(uType == GCS_HELPTEXTA || uType == GCS_HELPTEXTW)
+ {
+ MyCopyString(pszName, _commandMap[cmdOffset].HelpString, uType == GCS_HELPTEXTW);
+ return NO_ERROR;
+ }
+ if(uType == GCS_VERBA || uType == GCS_VERBW)
+ {
+ MyCopyString(pszName, _commandMap[cmdOffset].Verb, uType == GCS_VERBW);
+ return NO_ERROR;
+ }
+ return E_FAIL;
+}
diff --git a/CPP/7zip/UI/Explorer/ContextMenu.h b/CPP/7zip/UI/Explorer/ContextMenu.h
new file mode 100755
index 00000000..60970a22
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/ContextMenu.h
@@ -0,0 +1,86 @@
+// ContextMenu.h
+
+#ifndef __CONTEXTMENU_H
+#define __CONTEXTMENU_H
+
+// {23170F69-40C1-278A-1000-000100020000}
+DEFINE_GUID(CLSID_CZipContextMenu,
+0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00);
+
+#include "Common/String.h"
+
+#include "../../FileManager/PluginInterface.h"
+#include "../../FileManager/MyCom2.h"
+
+
+class CZipContextMenu:
+ public IContextMenu,
+ public IShellExtInit,
+ public IInitContextMenu,
+ public CMyUnknownImp
+{
+
+public:
+
+ enum ECommandInternalID
+ {
+ kCommandNULL,
+ kOpen,
+ kExtract,
+ kExtractHere,
+ kExtractTo,
+ kTest,
+ kCompress,
+ kCompressEmail,
+ kCompressTo7z,
+ kCompressTo7zEmail,
+ kCompressToZip,
+ kCompressToZipEmail
+ };
+
+ struct CCommandMapItem
+ {
+ ECommandInternalID CommandInternalID;
+ UString Verb;
+ UString HelpString;
+ UString Folder;
+ UString Archive;
+ UString ArchiveType;
+ };
+
+ MY_UNKNOWN_IMP3_MT(IContextMenu, IShellExtInit, IInitContextMenu)
+
+ ///////////////////////////////
+ // IShellExtInit
+
+ STDMETHOD(Initialize)(LPCITEMIDLIST pidlFolder,
+ LPDATAOBJECT dataObject, HKEY hkeyProgID);
+
+ /////////////////////////////
+ // IContextMenu
+
+ STDMETHOD(QueryContextMenu)(HMENU hmenu, UINT indexMenu,
+ UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
+ STDMETHOD(InvokeCommand)(LPCMINVOKECOMMANDINFO lpici);
+ STDMETHOD(GetCommandString)(UINT_PTR idCmd, UINT uType, UINT *pwReserved,
+ LPSTR pszName, UINT cchMax);
+
+
+ // IInitContextMenu
+ STDMETHOD(InitContextMenu)(const wchar_t *folder, const wchar_t **names, UINT32 numFiles);
+private:
+ UStringVector _fileNames;
+ bool _dropMode;
+ UString _dropPath;
+ CObjectVector<CCommandMapItem> _commandMap;
+ HRESULT GetFileNames(LPDATAOBJECT dataObject, UStringVector &fileNames);
+ int FindVerb(const UString &verb);
+
+ void FillCommand(ECommandInternalID id, UString &mainString,
+ CCommandMapItem &commandMapItem);
+public:
+ CZipContextMenu();
+ ~CZipContextMenu();
+};
+
+#endif
diff --git a/CPP/7zip/UI/Explorer/ContextMenuFlags.h b/CPP/7zip/UI/Explorer/ContextMenuFlags.h
new file mode 100755
index 00000000..d138baf9
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/ContextMenuFlags.h
@@ -0,0 +1,34 @@
+// ContextMenuFlags.h
+
+#ifndef __SEVENZIP_CONTEXTMENUFLAGS_H
+#define __SEVENZIP_CONTEXTMENUFLAGS_H
+
+namespace NContextMenuFlags
+{
+ const UINT32 kExtract = 1 << 0;
+ const UINT32 kExtractHere = 1 << 1;
+ const UINT32 kExtractTo = 1 << 2;
+ // const UINT32 kExtractEach = 1 << 3;
+
+ const UINT32 kTest = 1 << 4;
+
+ const UINT32 kOpen = 1 << 5;
+
+ const UINT32 kCompress = 1 << 8;
+ const UINT32 kCompressTo7z = 1 << 9;
+ const UINT32 kCompressEmail = 1 << 10;
+ const UINT32 kCompressTo7zEmail = 1 << 11;
+
+ const UINT32 kCompressToZip = 1 << 12;
+ const UINT32 kCompressToZipEmail = 1 << 13;
+
+ inline UINT32 GetDefaultFlags() {
+ return
+ kOpen | kTest |
+ kExtract | kExtractHere | kExtractTo |
+ kCompress | kCompressEmail |
+ kCompressTo7z | kCompressTo7zEmail |
+ kCompressToZip | kCompressToZipEmail; }
+}
+
+#endif
diff --git a/CPP/7zip/UI/Explorer/DllExports.cpp b/CPP/7zip/UI/Explorer/DllExports.cpp
new file mode 100755
index 00000000..fb7daf04
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/DllExports.cpp
@@ -0,0 +1,315 @@
+// DLLExports.cpp
+//
+// Notes:
+// Win2000:
+// If I register at HKCR\Folder\ShellEx then DLL is locked.
+// otherwise it unloads after explorer closing.
+// but if I call menu for desktop items it's locked all the time
+
+#include "StdAfx.h"
+
+// #include <locale.h>
+
+#include <initguid.h>
+#include <windows.h>
+#include <ShlGuid.h>
+#include <OleCtl.h>
+
+#include "Common/ComTry.h"
+#include "Common/StringConvert.h"
+#include "Windows/DLL.h"
+#include "Windows/Registry.h"
+
+#include "../../IPassword.h"
+#include "../../FileManager/LangUtils.h"
+#include "../Agent/Agent.h"
+
+#include "ContextMenu.h"
+#include "OptionsDialog.h"
+
+using namespace NWindows;
+
+HINSTANCE g_hInstance;
+#ifndef _UNICODE
+bool g_IsNT = false;
+#endif
+
+LONG g_DllRefCount = 0; // Reference count of this DLL.
+
+static LPCWSTR kShellExtName = L"7-Zip Shell Extension";
+static LPCTSTR kClsidMask = TEXT("CLSID\\%s");
+static LPCTSTR kClsidInprocMask = TEXT("CLSID\\%s\\InprocServer32");
+static LPCTSTR kApprovedKeyPath = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved");
+
+// #define ODS(sz) OutputDebugString(L#sz)
+
+class CShellExtClassFactory:
+ public IClassFactory,
+ public CMyUnknownImp
+{
+public:
+ CShellExtClassFactory() { InterlockedIncrement(&g_DllRefCount); }
+ ~CShellExtClassFactory() { InterlockedDecrement(&g_DllRefCount); }
+
+
+ MY_UNKNOWN_IMP1_MT(IClassFactory)
+
+ STDMETHODIMP CreateInstance(LPUNKNOWN, REFIID, void**);
+ STDMETHODIMP LockServer(BOOL);
+};
+
+STDMETHODIMP CShellExtClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,
+ REFIID riid, void **ppvObj)
+{
+ // ODS("CShellExtClassFactory::CreateInstance()\r\n");
+ *ppvObj = NULL;
+ if (pUnkOuter)
+ return CLASS_E_NOAGGREGATION;
+
+ CZipContextMenu *shellExt;
+ try
+ {
+ shellExt = new CZipContextMenu();
+ }
+ catch(...) { return E_OUTOFMEMORY; }
+ if (shellExt == NULL)
+ return E_OUTOFMEMORY;
+
+ HRESULT res = shellExt->QueryInterface(riid, ppvObj);
+ if (res != S_OK)
+ delete shellExt;
+ return res;
+}
+
+
+STDMETHODIMP CShellExtClassFactory::LockServer(BOOL /* fLock */)
+{
+ return S_OK; // Check it
+}
+
+static bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID)
+{
+ // setlocale(LC_COLLATE, ".ACP");
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ g_hInstance = hInstance;
+ // ODS("In DLLMain, DLL_PROCESS_ATTACH\r\n");
+ #ifdef _UNICODE
+ if (!IsItWindowsNT())
+ return FALSE;
+ #else
+ g_IsNT = IsItWindowsNT();
+ #endif
+ }
+ else if (dwReason == DLL_PROCESS_DETACH)
+ {
+ // ODS("In DLLMain, DLL_PROCESS_DETACH\r\n");
+ }
+ return TRUE;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Used to determine whether the DLL can be unloaded by OLE
+
+STDAPI DllCanUnloadNow(void)
+{
+ // ODS("In DLLCanUnloadNow\r\n");
+ return (g_DllRefCount == 0 ? S_OK : S_FALSE);
+}
+
+STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
+{
+ // ODS("In DllGetClassObject\r\n");
+ *ppv = NULL;
+ if (IsEqualIID(rclsid, CLSID_CZipContextMenu))
+ {
+ CShellExtClassFactory *cf;
+ try
+ {
+ cf = new CShellExtClassFactory;
+ }
+ catch(...) { return E_OUTOFMEMORY; }
+ if (cf == 0)
+ return E_OUTOFMEMORY;
+ HRESULT res = cf->QueryInterface(riid, ppv);
+ if (res != S_OK)
+ delete cf;
+ return res;
+ }
+ return CLASS_E_CLASSNOTAVAILABLE;
+ // return _Module.GetClassObject(rclsid, riid, ppv);
+}
+
+static BOOL GetStringFromIID(CLSID clsid, LPTSTR s, int size)
+{
+ LPWSTR pwsz;
+ if (StringFromIID(clsid, &pwsz) != S_OK)
+ return FALSE;
+ if(!pwsz)
+ return FALSE;
+ #ifdef UNICODE
+ lstrcpyn(s, pwsz, size);
+ #else
+ WideCharToMultiByte(CP_ACP, 0, pwsz, -1, s, size, NULL, NULL);
+ #endif
+ CoTaskMemFree(pwsz);
+ s[size - 1] = 0;
+ return TRUE;
+}
+
+typedef struct
+{
+ HKEY hRootKey;
+ LPCTSTR SubKey;
+ LPCWSTR ValueName;
+ LPCWSTR Data;
+} CRegItem;
+
+static BOOL RegisterServer(CLSID clsid, LPCWSTR title)
+{
+ TCHAR clsidString[MAX_PATH];
+ if (!GetStringFromIID(clsid, clsidString, MAX_PATH))
+ return FALSE;
+
+ UString modulePath;
+ if (!NDLL::MyGetModuleFileName(g_hInstance, modulePath))
+ return FALSE;
+
+ CRegItem clsidEntries[] =
+ {
+ HKEY_CLASSES_ROOT, kClsidMask, NULL, title,
+ HKEY_CLASSES_ROOT, kClsidInprocMask, NULL, modulePath,
+ HKEY_CLASSES_ROOT, kClsidInprocMask, L"ThreadingModel", L"Apartment",
+ NULL, NULL, NULL, NULL
+ };
+
+ //register the CLSID entries
+ for(int i = 0; clsidEntries[i].hRootKey; i++)
+ {
+ TCHAR subKey[MAX_PATH];
+ wsprintf(subKey, clsidEntries[i].SubKey, clsidString);
+ NRegistry::CKey key;
+ if (key.Create(clsidEntries[i].hRootKey, subKey, NULL,
+ REG_OPTION_NON_VOLATILE, KEY_WRITE) != NOERROR)
+ return FALSE;
+ key.SetValue(clsidEntries[i].ValueName, clsidEntries[i].Data);
+ }
+
+ if(IsItWindowsNT())
+ {
+ NRegistry::CKey key;
+ if (key.Create(HKEY_LOCAL_MACHINE, kApprovedKeyPath, NULL,
+ REG_OPTION_NON_VOLATILE, KEY_WRITE) == NOERROR)
+ key.SetValue(GetUnicodeString(clsidString), title);
+ }
+ return TRUE;
+}
+
+STDAPI DllRegisterServer(void)
+{
+ return RegisterServer(CLSID_CZipContextMenu, kShellExtName) ? S_OK: SELFREG_E_CLASS;
+}
+
+static BOOL UnregisterServer(CLSID clsid)
+{
+ TCHAR clsidString[MAX_PATH];
+ if (!GetStringFromIID(clsid, clsidString, MAX_PATH))
+ return FALSE;
+
+ TCHAR subKey[MAX_PATH];
+ wsprintf(subKey, kClsidInprocMask, clsidString);
+ RegDeleteKey(HKEY_CLASSES_ROOT, subKey);
+
+ wsprintf (subKey, kClsidMask, clsidString);
+ RegDeleteKey(HKEY_CLASSES_ROOT, subKey);
+
+ if(IsItWindowsNT())
+ {
+ HKEY hKey;
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, kApprovedKeyPath, 0, KEY_SET_VALUE, &hKey) == NOERROR)
+ {
+ RegDeleteValue(hKey, clsidString);
+ RegCloseKey(hKey);
+ }
+ }
+ return TRUE;
+}
+
+STDAPI DllUnregisterServer(void)
+{
+ return UnregisterServer(CLSID_CZipContextMenu) ? S_OK: SELFREG_E_CLASS;
+}
+
+STDAPI CreateObject(
+ const GUID *classID,
+ const GUID *interfaceID,
+ void **outObject)
+{
+ LoadLangOneTime();
+ COM_TRY_BEGIN
+ *outObject = 0;
+ if (*classID == CLSID_CAgentArchiveHandler)
+ {
+ if (*interfaceID == IID_IFolderManager)
+ {
+ CMyComPtr<IFolderManager> manager = new CArchiveFolderManager;
+ *outObject = manager.Detach();
+ return S_OK;
+ }
+ return E_NOINTERFACE;
+ }
+ if (*classID == CLSID_CSevenZipOptions)
+ {
+ if (*interfaceID == IID_IPluginOptions)
+ {
+ CMyComPtr<IPluginOptions> options = new CSevenZipOptions;
+ *outObject = options.Detach();
+ return S_OK;
+ }
+ return E_NOINTERFACE;
+ }
+ return CLASS_E_CLASSNOTAVAILABLE;
+ COM_TRY_END
+}
+
+STDAPI GetPluginProperty(PROPID propID, PROPVARIANT *value)
+{
+ ::VariantClear((tagVARIANT *)value);
+ switch(propID)
+ {
+ case NPlugin::kName:
+ if ((value->bstrVal = ::SysAllocString(L"7-Zip")) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ case NPlugin::kClassID:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CAgentArchiveHandler, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ case NPlugin::kOptionsClassID:
+ {
+ if ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)&CLSID_CSevenZipOptions, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ /*
+ case NArchive::kType:
+ propVariant = UINT32(0);
+ break;
+ */
+ }
+ return S_OK;
+}
diff --git a/CPP/7zip/UI/Explorer/Explorer.def b/CPP/7zip/UI/Explorer/Explorer.def
new file mode 100755
index 00000000..752fbb7a
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/Explorer.def
@@ -0,0 +1,12 @@
+; 7-zip.def
+
+LIBRARY "7-zip"
+
+EXPORTS
+ DllCanUnloadNow PRIVATE
+ DllGetClassObject PRIVATE
+ DllRegisterServer PRIVATE
+ DllUnregisterServer PRIVATE
+
+ CreateObject PRIVATE
+ GetPluginProperty PRIVATE
diff --git a/CPP/7zip/UI/Explorer/Explorer.dsp b/CPP/7zip/UI/Explorer/Explorer.dsp
new file mode 100755
index 00000000..c395c6d2
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/Explorer.dsp
@@ -0,0 +1,818 @@
+# Microsoft Developer Studio Project File - Name="Explorer" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=Explorer - Win32 DebugU
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "Explorer.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "Explorer.mak" CFG="Explorer - Win32 DebugU"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Explorer - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Explorer - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Explorer - Win32 ReleaseU" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Explorer - Win32 DebugU" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "Explorer - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "LANG" /D "NEW_FOLDER_INTERFACE" /Yu"StdAfx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Explorer - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "LANG" /D "NEW_FOLDER_INTERFACE" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "Explorer - Win32 ReleaseU"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ReleaseU"
+# PROP BASE Intermediate_Dir "ReleaseU"
+# PROP BASE Ignore_Export_Lib 1
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ReleaseU"
+# PROP Intermediate_Dir "ReleaseU"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "LANG" /D "_MBCS" /Yu"StdAfx.h" /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "LANG" /D "NEW_FOLDER_INTERFACE" /Yu"StdAfx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /opt:NOWIN98
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zipn.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Explorer - Win32 DebugU"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "DebugU"
+# PROP BASE Intermediate_Dir "DebugU"
+# PROP BASE Ignore_Export_Lib 1
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "DebugU"
+# PROP Intermediate_Dir "DebugU"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "LANG" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c
+# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "LANG" /D "NEW_FOLDER_INTERFACE" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "Explorer - Win32 Release"
+# Name "Explorer - Win32 Debug"
+# Name "Explorer - Win32 ReleaseU"
+# Name "Explorer - Win32 DebugU"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\DllExports.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Explorer.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "UI Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Common\ArchiveExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiveExtractCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiveName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiveName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiveOpenCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiveOpenCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiverInfo.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiverInfo.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CompressCall.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CompressCall.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\DefaultName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\DefaultName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\EnumDirItems.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\EnumDirItems.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ExtractingFilePath.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ExtractingFilePath.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\HandlerLoader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\OpenArchive.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\OpenArchive.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\PropIDUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\PropIDUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\SortUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\SortUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdateAction.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdateAction.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdateCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdateCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdatePair.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdatePair.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdateProduce.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdateProduce.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\WorkDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\WorkDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ZipRegistry.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ZipRegistry.h
+# End Source File
+# End Group
+# Begin Group "Engine"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\ContextMenu.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ContextMenu.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\MyMessages.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\MyMessages.h
+# End Source File
+# End Group
+# Begin Group "Dialogs"
+
+# PROP Default_Filter ""
+# Begin Group "Options"
+
+# PROP Default_Filter ""
+# Begin Group "SystemPage"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\SystemPage\SystemPage.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\SystemPage\SystemPage.h
+# End Source File
+# End Group
+# Begin Group "FoldersPage"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\FoldersPage\FoldersPage.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\FoldersPage\FoldersPage.h
+# End Source File
+# End Group
+# End Group
+# End Group
+# Begin Group "Agent"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Agent\Agent.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\Agent.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\AgentOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\AgentProxy.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\AgentProxy.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\ArchiveFolder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\ArchiveFolderOpen.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\ArchiveFolderOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\IFileExtractCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\IFolderArchive.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\UpdateCallbackAgent.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\UpdateCallbackAgent.h
+# End Source File
+# End Group
+# Begin Group "FileManager"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\FileManager\FormatUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\FormatUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\HelpUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\HelpUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\IFolder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\LangUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\LangUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\ProgramLocation.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\ProgramLocation.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\RegistryUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\RegistryUtils.h
+# End Source File
+# End Group
+# Begin Group "SDK"
+
+# PROP Default_Filter ""
+# 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\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Lang.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Lang.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyCom.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Random.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Random.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdInStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdInStream.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\StringToInt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringToInt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\TextConfig.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\TextConfig.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\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
+
+SOURCE=..\..\..\Common\Vector.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Group "Control"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\Dialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\Dialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\PropertyPage.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\PropertyPage.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Error.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Error.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileMapping.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Memory.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Memory.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Menu.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Menu.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Registry.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Registry.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\ResourceString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\ResourceString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Shell.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Shell.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Window.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Window.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "7-zip common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\FilePathAutoRename.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilePathAutoRename.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.h
+# End Source File
+# End Group
+# Begin Group "C"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Sort.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Sort.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=".\7-zip.dll.manifest"
+# End Source File
+# Begin Source File
+
+SOURCE=.\ContextMenuFlags.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\OptionsDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\OptionsDialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\RegistryContextMenu.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\RegistryContextMenu.h
+# End Source File
+# End Target
+# End Project
diff --git a/CPP/7zip/UI/Explorer/Explorer.dsw b/CPP/7zip/UI/Explorer/Explorer.dsw
new file mode 100755
index 00000000..beb8df7b
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/Explorer.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Explorer"=".\Explorer.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.cpp b/CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.cpp
new file mode 100755
index 00000000..776813d8
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.cpp
@@ -0,0 +1,157 @@
+// FoldersPage.cpp
+
+#include "StdAfx.h"
+
+#include "resource.h"
+#include "FoldersPage.h"
+
+#include "Common/StringConvert.h"
+#include "Windows/Defs.h"
+#include "Windows/Shell.h"
+#include "Windows/ResourceString.h"
+
+#include "../../../FileManager/HelpUtils.h"
+#include "../../Common/ZipRegistry.h"
+
+#include "../../../FileManager/LangUtils.h"
+
+using namespace NWindows;
+
+static CIDLangPair kIDLangPairs[] =
+{
+ { IDC_FOLDERS_STATIC_WORKING_FOLDER, 0x01000210 },
+ { IDC_FOLDERS_WORK_RADIO_SYSTEM, 0x01000211 },
+ { IDC_FOLDERS_WORK_RADIO_CURRENT, 0x01000212 },
+ { IDC_FOLDERS_WORK_RADIO_SPECIFIED, 0x01000213 },
+ { IDC_FOLDERS_WORK_CHECK_FOR_REMOVABLE, 0x01000214 }
+};
+
+static const int kWorkModeButtons[] =
+{
+ IDC_FOLDERS_WORK_RADIO_SYSTEM,
+ IDC_FOLDERS_WORK_RADIO_CURRENT,
+ IDC_FOLDERS_WORK_RADIO_SPECIFIED
+};
+
+static const int kNumWorkModeButtons = sizeof(kWorkModeButtons) / sizeof(kWorkModeButtons[0]);
+
+bool CFoldersPage::OnInit()
+{
+ LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
+ ReadWorkDirInfo(m_WorkDirInfo);
+
+ CheckButton(IDC_FOLDERS_WORK_CHECK_FOR_REMOVABLE, m_WorkDirInfo.ForRemovableOnly);
+
+ CheckRadioButton(kWorkModeButtons[0], kWorkModeButtons[kNumWorkModeButtons - 1],
+ kWorkModeButtons[m_WorkDirInfo.Mode]);
+
+ m_WorkPath.Init(*this, IDC_FOLDERS_WORK_EDIT_PATH);
+ m_ButtonSetWorkPath.Init(*this, IDC_FOLDERS_WORK_BUTTON_PATH);
+
+ m_WorkPath.SetText(m_WorkDirInfo.Path);
+
+ MyEnableControls();
+
+ return CPropertyPage::OnInit();
+}
+
+int CFoldersPage::GetWorkMode() const
+{
+ for (int i = 0; i < kNumWorkModeButtons; i++)
+ if(IsButtonCheckedBool(kWorkModeButtons[i]))
+ return i;
+ throw 0;
+}
+
+void CFoldersPage::MyEnableControls()
+{
+ bool enablePath = (GetWorkMode() == NWorkDir::NMode::kSpecified);
+ m_WorkPath.Enable(enablePath);
+ m_ButtonSetWorkPath.Enable(enablePath);
+}
+
+void CFoldersPage::GetWorkDir(NWorkDir::CInfo &workDirInfo)
+{
+ m_WorkPath.GetText(workDirInfo.Path);
+ workDirInfo.ForRemovableOnly = IsButtonCheckedBool(IDC_FOLDERS_WORK_CHECK_FOR_REMOVABLE);
+ workDirInfo.Mode = NWorkDir::NMode::EEnum(GetWorkMode());
+}
+
+/*
+bool CFoldersPage::WasChanged()
+{
+ NWorkDir::CInfo workDirInfo;
+ GetWorkDir(workDirInfo);
+ return (workDirInfo.Mode != m_WorkDirInfo.Mode ||
+ workDirInfo.ForRemovableOnly != m_WorkDirInfo.ForRemovableOnly ||
+ workDirInfo.Path.Compare(m_WorkDirInfo.Path) != 0);
+}
+*/
+
+void CFoldersPage::ModifiedEvent()
+{
+ Changed();
+ /*
+ if (WasChanged())
+ Changed();
+ else
+ UnChanged();
+ */
+}
+
+bool CFoldersPage::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ for (int i = 0; i < kNumWorkModeButtons; i++)
+ if (buttonID == kWorkModeButtons[i])
+ {
+ MyEnableControls();
+ ModifiedEvent();
+ return true;
+ }
+ switch(buttonID)
+ {
+ case IDC_FOLDERS_WORK_BUTTON_PATH:
+ OnFoldersWorkButtonPath();
+ break;
+ case IDC_FOLDERS_WORK_CHECK_FOR_REMOVABLE:
+ break;
+ default:
+ return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
+ }
+ ModifiedEvent();
+ return true;
+}
+
+bool CFoldersPage::OnCommand(int code, int itemID, LPARAM lParam)
+{
+ if (code == EN_CHANGE && itemID == IDC_FOLDERS_WORK_EDIT_PATH)
+ {
+ ModifiedEvent();
+ return true;
+ }
+ return CPropertyPage::OnCommand(code, itemID, lParam);
+}
+
+void CFoldersPage::OnFoldersWorkButtonPath()
+{
+ UString currentPath;
+ m_WorkPath.GetText(currentPath);
+ UString title = LangString(IDS_FOLDERS_SET_WORK_PATH_TITLE, 0x01000281);
+ UString resultPath;
+ if (NShell::BrowseForFolder(HWND(*this), title, currentPath, resultPath))
+ m_WorkPath.SetText(resultPath);
+}
+
+LONG CFoldersPage::OnApply()
+{
+ GetWorkDir(m_WorkDirInfo);
+ SaveWorkDirInfo(m_WorkDirInfo);
+ return PSNRET_NOERROR;
+}
+
+static LPCWSTR kFoldersTopic = L"fm/plugins/7-zip/options.htm#folders";
+
+void CFoldersPage::OnNotifyHelp()
+{
+ ShowHelpWindow(NULL, kFoldersTopic);
+}
diff --git a/CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.h b/CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.h
new file mode 100755
index 00000000..97950fc6
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.h
@@ -0,0 +1,30 @@
+// FoldersPage.h
+
+#ifndef __FOLDERSPAGE_H
+#define __FOLDERSPAGE_H
+
+#include "Windows/Control/PropertyPage.h"
+
+#include "../../Common/ZipRegistry.h"
+
+class CFoldersPage : public NWindows::NControl::CPropertyPage
+{
+ NWorkDir::CInfo m_WorkDirInfo;
+
+ void MyEnableControls();
+ void ModifiedEvent();
+ NWindows::NControl::CDialogChildControl m_WorkPath;
+ NWindows::NControl::CDialogChildControl m_ButtonSetWorkPath;
+ void OnFoldersWorkButtonPath();
+ int GetWorkMode() const;
+ void GetWorkDir(NWorkDir::CInfo &workDirInfo);
+ // bool WasChanged();
+public:
+ virtual bool OnInit();
+ virtual bool OnCommand(int code, int itemID, LPARAM lParam);
+ virtual void OnNotifyHelp();
+ virtual LONG OnApply();
+ virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
+};
+
+#endif
diff --git a/CPP/7zip/UI/Explorer/FoldersPage/resource.h b/CPP/7zip/UI/Explorer/FoldersPage/resource.h
new file mode 100755
index 00000000..3052409b
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/FoldersPage/resource.h
@@ -0,0 +1,12 @@
+#define IDD_FOLDERS 900
+
+#define IDS_FOLDERS_SET_WORK_PATH_TITLE 103
+
+#define IDC_FOLDERS_STATIC_WORKING_FOLDER 1001
+
+#define IDC_FOLDERS_WORK_RADIO_SYSTEM 1011
+#define IDC_FOLDERS_WORK_RADIO_CURRENT 1012
+#define IDC_FOLDERS_WORK_RADIO_SPECIFIED 1013
+#define IDC_FOLDERS_WORK_EDIT_PATH 1014
+#define IDC_FOLDERS_WORK_BUTTON_PATH 1015
+#define IDC_FOLDERS_WORK_CHECK_FOR_REMOVABLE 1017
diff --git a/CPP/7zip/UI/Explorer/FoldersPage/resource.rc b/CPP/7zip/UI/Explorer/FoldersPage/resource.rc
new file mode 100755
index 00000000..96b2c9d3
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/FoldersPage/resource.rc
@@ -0,0 +1,36 @@
+#include "resource.h"
+#include "../../../GuiCommon.rc"
+
+#define xSize2 196
+#define ySize2 140
+#define xSize (xSize2 + marg + marg)
+#define ySize (ySize2 + marg + marg)
+
+#define marg2 marg
+#define marg3 10
+#define gPos (marg + marg2)
+#define gSize (xSize2 - marg2 - marg2)
+#define gPos2 (gPos + marg3)
+
+
+IDD_FOLDERS DIALOG 0, 0, xSize, ySize MY_PAGE_STYLE
+CAPTION "Folders"
+MY_FONT
+BEGIN
+ GROUPBOX "&Working folder", IDC_FOLDERS_STATIC_WORKING_FOLDER, marg, marg, xSize2, 98
+ CONTROL "&System temp folder", IDC_FOLDERS_WORK_RADIO_SYSTEM, "Button", BS_AUTORADIOBUTTON | WS_GROUP,
+ gPos, 20, gSize, 10
+ CONTROL "&Current", IDC_FOLDERS_WORK_RADIO_CURRENT, "Button", BS_AUTORADIOBUTTON,
+ gPos, 34, gSize, 10
+ CONTROL "Specified:", IDC_FOLDERS_WORK_RADIO_SPECIFIED, "Button", BS_AUTORADIOBUTTON,
+ gPos, 48, gSize, 10
+ EDITTEXT IDC_FOLDERS_WORK_EDIT_PATH, gPos2, 63, gSize - marg3 - bDotsSize - 10, 14, ES_AUTOHSCROLL
+ PUSHBUTTON "...", IDC_FOLDERS_WORK_BUTTON_PATH, xSize - marg - marg2 - bDotsSize, 63, bDotsSize, bYSize
+ CONTROL "Use for removable drives only", IDC_FOLDERS_WORK_CHECK_FOR_REMOVABLE, "Button", BS_AUTOCHECKBOX | WS_TABSTOP,
+ gPos, 87, gSize, 10
+END
+
+STRINGTABLE
+BEGIN
+ IDS_FOLDERS_SET_WORK_PATH_TITLE "Specify a location for temporary archive files."
+END
diff --git a/CPP/7zip/UI/Explorer/MyMessages.cpp b/CPP/7zip/UI/Explorer/MyMessages.cpp
new file mode 100755
index 00000000..61d2429d
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/MyMessages.cpp
@@ -0,0 +1,58 @@
+// MyMessages.cpp
+
+#include "StdAfx.h"
+
+#include "MyMessages.h"
+#include "Common/String.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/Error.h"
+#include "Windows/ResourceString.h"
+
+#ifdef LANG
+#include "../../FileManager/LangUtils.h"
+#endif
+
+using namespace NWindows;
+
+void MyMessageBox(HWND window, LPCWSTR message)
+{
+ ::MessageBoxW(window, message, L"7-Zip", 0);
+}
+
+void MyMessageBoxResource(HWND window, UINT32 id
+ #ifdef LANG
+ ,UINT32 langID
+ #endif
+ )
+{
+ #ifdef LANG
+ MyMessageBox(window, LangString(id, langID));
+ #else
+ MyMessageBox(window, MyLoadStringW(id));
+ #endif
+}
+
+void MyMessageBox(UINT32 id
+ #ifdef LANG
+ ,UINT32 langID
+ #endif
+ )
+{
+ MyMessageBoxResource(0, id
+ #ifdef LANG
+ , langID
+ #endif
+ );
+}
+
+void ShowErrorMessage(HWND window, DWORD message)
+{
+ MyMessageBox(window, NError::MyFormatMessageW(message));
+}
+
+void ShowLastErrorMessage(HWND window)
+{
+ ShowErrorMessage(window, ::GetLastError());
+}
+
diff --git a/CPP/7zip/UI/Explorer/MyMessages.h b/CPP/7zip/UI/Explorer/MyMessages.h
new file mode 100755
index 00000000..1a96f569
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/MyMessages.h
@@ -0,0 +1,30 @@
+// MyMessages.h
+
+#ifndef __MYMESSAGES_H
+#define __MYMESSAGES_H
+
+#include "Common/String.h"
+
+void MyMessageBox(HWND window, LPCWSTR message);
+
+inline void MyMessageBox(LPCWSTR message)
+ { MyMessageBox(0, message); }
+
+void MyMessageBoxResource(HWND window, UINT32 id
+ #ifdef LANG
+ ,UINT32 langID
+ #endif
+ );
+
+void MyMessageBox(UINT32 id
+ #ifdef LANG
+ ,UINT32 langID
+ #endif
+ );
+
+void ShowErrorMessage(HWND window, DWORD errorMessage);
+inline void ShowErrorMessage(DWORD errorMessage)
+ { ShowErrorMessage(0, errorMessage); }
+void ShowLastErrorMessage(HWND window = 0);
+
+#endif
diff --git a/CPP/7zip/UI/Explorer/OptionsDialog.cpp b/CPP/7zip/UI/Explorer/OptionsDialog.cpp
new file mode 100755
index 00000000..b7831afd
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/OptionsDialog.cpp
@@ -0,0 +1,71 @@
+// OptionsDialog.cpp
+
+#include "StdAfx.h"
+
+#include "resource.h"
+
+#include "OptionsDialog.h"
+
+#include "Common/StringConvert.h"
+#include "Windows/Control/PropertyPage.h"
+
+#include "../../FileManager/LangUtils.h"
+#include "FoldersPage/FoldersPage.h"
+#include "FoldersPage/resource.h"
+#include "SystemPage/SystemPage.h"
+#include "SystemPage/resource.h"
+
+using namespace NWindows;
+
+static INT_PTR OptionsDialog(HWND hwndOwner)
+{
+ CSystemPage systemPage;
+ CFoldersPage foldersPage;
+ UINT32 langIDs[] = { 0x01000300, 0x01000200};
+ UINT pageIDs[] = { IDD_SYSTEM, IDD_FOLDERS};
+ NControl::CPropertyPage *pagePinters[] = { &systemPage, &foldersPage };
+ CObjectVector<NControl::CPageInfo> pages;
+ const int kNumPages = sizeof(langIDs) / sizeof(langIDs[0]);
+ for (int i = 0; i < kNumPages; i++)
+ {
+ NControl::CPageInfo page;
+ page.Title = LangString(langIDs[i]);
+ page.ID = pageIDs[i];
+ page.Page = pagePinters[i];
+ pages.Add(page);
+ }
+ return NControl::MyPropertySheet(pages, hwndOwner,
+ LangString(IDS_CONFIG_DIALOG_CAPTION, 0x01000000));
+}
+
+STDMETHODIMP CSevenZipOptions::PluginOptions(HWND hWnd,
+ IPluginOptionsCallback * /* callback */)
+{
+ /*
+ CComBSTR programPath;
+ RETUEN_IF_NOT_S_OK(callback->GetProgramPath(programName)));
+ */
+ OptionsDialog(hWnd);
+ return S_OK;
+}
+
+STDMETHODIMP CSevenZipOptions::GetFileExtensions(BSTR * /* extensions */)
+{
+ /*
+ UString extStrings;
+ CObjectVector<NZipRootRegistry::CArchiverInfo> formats;
+ NZipRootRegistry::ReadArchiverInfoList(formats);
+ for(int i = 0; i < formats.Size(); i++)
+ {
+ if (i != 0)
+ extStrings += L' ';
+ extStrings += formats[i].Extension;
+ }
+ CComBSTR valueTemp = extStrings;
+ *extensions = valueTemp.Detach();
+ return S_OK;
+ */
+ return E_NOTIMPL;
+}
+
+
diff --git a/CPP/7zip/UI/Explorer/OptionsDialog.h b/CPP/7zip/UI/Explorer/OptionsDialog.h
new file mode 100755
index 00000000..7e85d357
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/OptionsDialog.h
@@ -0,0 +1,23 @@
+// OptionsDialog.h
+
+#ifndef __SEVENZIP_OPTIONSDIALOG_H
+#define __SEVENZIP_OPTIONSDIALOG_H
+
+#include "../../FileManager/PluginInterface.h"
+#include "Common/MyCom.h"
+
+// {23170F69-40C1-278D-1000-000100020000}
+DEFINE_GUID(CLSID_CSevenZipOptions,
+ 0x23170F69, 0x40C1, 0x278D, 0x10, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00);
+
+class CSevenZipOptions:
+ public IPluginOptions,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+ STDMETHOD(PluginOptions)(HWND hWnd, IPluginOptionsCallback *callback);
+ STDMETHOD(GetFileExtensions)(BSTR *extensions);
+};
+
+#endif
diff --git a/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp b/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp
new file mode 100755
index 00000000..73a8420e
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp
@@ -0,0 +1,128 @@
+// RegistryContextMenu.cpp
+
+#include "StdAfx.h"
+
+#include "RegistryContextMenu.h"
+#include "Windows/COM.h"
+#include "Windows/Synchronization.h"
+#include "Windows/Registry.h"
+#include "Windows/FileName.h"
+
+using namespace NWindows;
+using namespace NCOM;
+using namespace NRegistry;
+
+namespace NZipRootRegistry {
+
+static NSynchronization::CCriticalSection g_RegistryOperationsCriticalSection;
+
+///////////////////////////
+// ContextMenu
+
+static const TCHAR *kContextMenuKeyName = TEXT("\\shellex\\ContextMenuHandlers\\7-ZIP");
+static const TCHAR *kDragDropMenuKeyName = TEXT("\\shellex\\DragDropHandlers\\7-ZIP");
+
+static const TCHAR *kExtensionCLSID = TEXT("{23170F69-40C1-278A-1000-000100020000}");
+
+static const TCHAR *kRootKeyNameForFile = TEXT("*");
+static const TCHAR *kRootKeyNameForFolder = TEXT("Folder");
+static const TCHAR *kRootKeyNameForDirectory = TEXT("Directory");
+static const TCHAR *kRootKeyNameForDrive = TEXT("Drive");
+
+static CSysString GetFullContextMenuKeyName(const CSysString &keyName)
+ { return (keyName + kContextMenuKeyName); }
+
+static CSysString GetFullDragDropMenuKeyName(const CSysString &keyName)
+ { return (keyName + kDragDropMenuKeyName); }
+
+static bool CheckContextMenuHandlerCommon(const CSysString &keyName)
+{
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ CKey key;
+ if (key.Open(HKEY_CLASSES_ROOT, GetFullContextMenuKeyName(keyName), KEY_READ)
+ != ERROR_SUCCESS)
+ return false;
+ CSysString value;
+ if (key.QueryValue(NULL, value) != ERROR_SUCCESS)
+ return false;
+ return (value.CompareNoCase(kExtensionCLSID) == 0);
+}
+
+static bool CheckDragDropMenuHandlerCommon(const CSysString &keyName)
+{
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ CKey key;
+ if (key.Open(HKEY_CLASSES_ROOT, GetFullDragDropMenuKeyName(keyName), KEY_READ) != ERROR_SUCCESS)
+ return false;
+ CSysString value;
+ if (key.QueryValue(NULL, value) != ERROR_SUCCESS)
+ return false;
+ return (value.CompareNoCase(kExtensionCLSID) == 0);
+}
+
+bool CheckContextMenuHandler()
+{
+ return CheckContextMenuHandlerCommon(kRootKeyNameForFile) &&
+ // CheckContextMenuHandlerCommon(kRootKeyNameForFolder) &&
+ CheckContextMenuHandlerCommon(kRootKeyNameForDirectory) &&
+ CheckDragDropMenuHandlerCommon(kRootKeyNameForDirectory) &&
+ CheckDragDropMenuHandlerCommon(kRootKeyNameForDrive);
+}
+
+static void DeleteContextMenuHandlerCommon(const CSysString &keyName)
+{
+ CKey rootKey;
+ rootKey.Attach(HKEY_CLASSES_ROOT);
+ rootKey.RecurseDeleteKey(GetFullContextMenuKeyName(keyName));
+ rootKey.Detach();
+}
+
+static void DeleteDragDropMenuHandlerCommon(const CSysString &keyName)
+{
+ CKey rootKey;
+ rootKey.Attach(HKEY_CLASSES_ROOT);
+ rootKey.RecurseDeleteKey(GetFullDragDropMenuKeyName(keyName));
+ rootKey.Detach();
+}
+
+void DeleteContextMenuHandler()
+{
+ DeleteContextMenuHandlerCommon(kRootKeyNameForFile);
+ DeleteContextMenuHandlerCommon(kRootKeyNameForFolder);
+ DeleteContextMenuHandlerCommon(kRootKeyNameForDirectory);
+ DeleteContextMenuHandlerCommon(kRootKeyNameForDrive);
+ DeleteDragDropMenuHandlerCommon(kRootKeyNameForFile);
+ DeleteDragDropMenuHandlerCommon(kRootKeyNameForFolder);
+ DeleteDragDropMenuHandlerCommon(kRootKeyNameForDirectory);
+ DeleteDragDropMenuHandlerCommon(kRootKeyNameForDrive);
+}
+
+static void AddContextMenuHandlerCommon(const CSysString &keyName)
+{
+ DeleteContextMenuHandlerCommon(keyName);
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ CKey key;
+ key.Create(HKEY_CLASSES_ROOT, GetFullContextMenuKeyName(keyName));
+ key.SetValue(NULL, kExtensionCLSID);
+}
+
+static void AddDragDropMenuHandlerCommon(const CSysString &keyName)
+{
+ DeleteDragDropMenuHandlerCommon(keyName);
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ CKey key;
+ key.Create(HKEY_CLASSES_ROOT, GetFullDragDropMenuKeyName(keyName));
+ key.SetValue(NULL, kExtensionCLSID);
+}
+
+void AddContextMenuHandler()
+{
+ AddContextMenuHandlerCommon(kRootKeyNameForFile);
+ // AddContextMenuHandlerCommon(kRootKeyNameForFolder);
+ AddContextMenuHandlerCommon(kRootKeyNameForDirectory);
+
+ AddDragDropMenuHandlerCommon(kRootKeyNameForDirectory);
+ AddDragDropMenuHandlerCommon(kRootKeyNameForDrive);
+}
+
+}
diff --git a/CPP/7zip/UI/Explorer/RegistryContextMenu.h b/CPP/7zip/UI/Explorer/RegistryContextMenu.h
new file mode 100755
index 00000000..52b053da
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/RegistryContextMenu.h
@@ -0,0 +1,13 @@
+// RegistryContextMenu.h
+
+#ifndef __REGISTRYCONTEXTMENU_H
+#define __REGISTRYCONTEXTMENU_H
+
+namespace NZipRootRegistry {
+
+ bool CheckContextMenuHandler();
+ void AddContextMenuHandler();
+ void DeleteContextMenuHandler();
+}
+
+#endif
diff --git a/CPP/7zip/UI/Explorer/StdAfx.cpp b/CPP/7zip/UI/Explorer/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/CPP/7zip/UI/Explorer/StdAfx.h b/CPP/7zip/UI/Explorer/StdAfx.h
new file mode 100755
index 00000000..b9c0ee3a
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/StdAfx.h
@@ -0,0 +1,26 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#define _WIN32_WINNT 0x0400
+// it's hack for Windows NT supporting
+#define WINVER 0x0400
+
+// #define _WIN32_IE 0x0500
+#include <windows.h>
+#include <CommCtrl.h>
+#include <shlobj.h>
+#include <tchar.h>
+
+#include <stddef.h>
+#include <string.h>
+#include <mbstring.h>
+#include <wchar.h>
+
+#include <shlguid.h>
+#include <regstr.h>
+
+#include "Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/UI/Explorer/SystemPage/SystemPage.cpp b/CPP/7zip/UI/Explorer/SystemPage/SystemPage.cpp
new file mode 100755
index 00000000..cc2f974d
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/SystemPage/SystemPage.cpp
@@ -0,0 +1,212 @@
+// SystemPage.cpp
+
+#include "StdAfx.h"
+#include "resource.h"
+#include "../resource.h"
+
+#include "Common/StringConvert.h"
+#include "Windows/Defs.h"
+#include "Windows/Control/ListView.h"
+
+#include "SystemPage.h"
+
+#include "../../Common/ZipRegistry.h"
+#include "../RegistryContextMenu.h"
+#include "../ContextMenuFlags.h"
+
+#include "../../../FileManager/HelpUtils.h"
+#include "../../../FileManager/LangUtils.h"
+#include "../../../FileManager/FormatUtils.h"
+
+using namespace NContextMenuFlags;
+
+static CIDLangPair kIDLangPairs[] =
+{
+ { IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU, 0x01000301},
+ { IDC_SYSTEM_CASCADED_MENU, 0x01000302},
+ { IDC_SYSTEM_STATIC_CONTEXT_MENU_ITEMS, 0x01000310}
+};
+
+static LPCWSTR kSystemTopic = L"fm/plugins/7-zip/options.htm#system";
+
+struct CContextMenuItem
+{
+ int ControlID;
+ UINT32 LangID;
+ UINT32 Flag;
+};
+
+static CContextMenuItem kMenuItems[] =
+{
+ { IDS_CONTEXT_OPEN, 0x02000103, kOpen},
+ { IDS_CONTEXT_EXTRACT, 0x02000105, kExtract},
+ { IDS_CONTEXT_EXTRACT_HERE, 0x0200010B, kExtractHere },
+ { IDS_CONTEXT_EXTRACT_TO, 0x0200010D, kExtractTo },
+
+ { IDS_CONTEXT_TEST, 0x02000109, kTest},
+
+ { IDS_CONTEXT_COMPRESS, 0x02000107, kCompress },
+ { IDS_CONTEXT_COMPRESS_EMAIL, 0x02000111, kCompressEmail },
+ { IDS_CONTEXT_COMPRESS_TO, 0x0200010F, kCompressTo7z },
+ { IDS_CONTEXT_COMPRESS_TO_EMAIL, 0x02000113, kCompressTo7zEmail},
+ { IDS_CONTEXT_COMPRESS_TO, 0x0200010F, kCompressToZip },
+ { IDS_CONTEXT_COMPRESS_TO_EMAIL, 0x02000113, kCompressToZipEmail},
+};
+
+const int kNumMenuItems = sizeof(kMenuItems) / sizeof(kMenuItems[0]);
+
+bool CSystemPage::OnInit()
+{
+ _initMode = true;
+ LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
+
+ CheckButton(IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU,
+ NZipRootRegistry::CheckContextMenuHandler());
+
+ CheckButton(IDC_SYSTEM_CASCADED_MENU, ReadCascadedMenu());
+
+ UINT32 contextMenuFlags;
+ if (!ReadContextMenuStatus(contextMenuFlags))
+ contextMenuFlags = NContextMenuFlags::GetDefaultFlags();
+
+ m_ListView.Attach(GetItem(IDC_SYSTEM_OPTIONS_LIST));
+
+ /*
+ CheckButton(IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU,
+ NRegistryAssociations::CheckContextMenuHandler());
+ */
+
+ UINT32 newFlags = LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT;
+ m_ListView.SetExtendedListViewStyle(newFlags, newFlags);
+
+ UString s; // = TEXT("Items"); // LangLoadString(IDS_PROPERTY_EXTENSION, 0x02000205);
+ LVCOLUMNW column;
+ column.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_FMT | LVCF_SUBITEM;
+ column.cx = 270;
+ column.fmt = LVCFMT_LEFT;
+ column.pszText = (LPWSTR)(LPCWSTR)s;
+ column.iSubItem = 0;
+ m_ListView.InsertColumn(0, &column);
+
+ for (int i = 0; i < kNumMenuItems; i++)
+ {
+ CContextMenuItem &menuItem = kMenuItems[i];
+ LVITEMW item;
+ item.iItem = i;
+ item.mask = LVIF_TEXT | LVIF_PARAM;
+ item.lParam = i;
+
+ UString s = LangString(menuItem.ControlID, menuItem.LangID);
+
+ switch(menuItem.ControlID)
+ {
+ case IDS_CONTEXT_EXTRACT_TO:
+ {
+ s = MyFormatNew(s, LangString(IDS_CONTEXT_FOLDER, 0x02000140));
+ break;
+ }
+ case IDS_CONTEXT_COMPRESS_TO:
+ case IDS_CONTEXT_COMPRESS_TO_EMAIL:
+ {
+ UString s2 = LangString(IDS_CONTEXT_ARCHIVE, 0x02000141);
+ switch(menuItem.Flag)
+ {
+ case kCompressTo7z:
+ case kCompressTo7zEmail:
+ s2 += L".7z";
+ break;
+ case kCompressToZip:
+ case kCompressToZipEmail:
+ s2 += L".zip";
+ break;
+ }
+ s = MyFormatNew(s, s2);
+ break;
+ }
+ }
+
+ // UString MyFormatNew(const UString &format, const UString &argument);
+
+ item.pszText = (LPWSTR)(LPCWSTR)s;
+ item.iSubItem = 0;
+ int itemIndex = m_ListView.InsertItem(&item);
+ m_ListView.SetCheckState(itemIndex, ((contextMenuFlags & menuItem.Flag) != 0));
+ }
+
+ _initMode = false;
+ return CPropertyPage::OnInit();
+}
+
+STDAPI DllRegisterServer(void);
+STDAPI DllUnregisterServer(void);
+
+LONG CSystemPage::OnApply()
+{
+ if (IsButtonCheckedBool(IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU))
+ {
+ DllRegisterServer();
+ NZipRootRegistry::AddContextMenuHandler();
+ }
+ else
+ {
+ DllUnregisterServer();
+ NZipRootRegistry::DeleteContextMenuHandler();
+ }
+ SaveCascadedMenu(IsButtonCheckedBool(IDC_SYSTEM_CASCADED_MENU));
+
+ UINT32 flags = 0;
+ for (int i = 0; i < kNumMenuItems; i++)
+ if (m_ListView.GetCheckState(i))
+ flags |= kMenuItems[i].Flag;
+ SaveContextMenuStatus(flags);
+
+ return PSNRET_NOERROR;
+}
+
+void CSystemPage::OnNotifyHelp()
+{
+ ShowHelpWindow(NULL, kSystemTopic);
+}
+
+bool CSystemPage::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch(buttonID)
+ {
+ case IDC_SYSTEM_CASCADED_MENU:
+ case IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU:
+ Changed();
+ return true;
+ }
+ return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
+
+}
+
+bool CSystemPage::OnNotify(UINT aControlID, LPNMHDR lParam)
+{
+ if (lParam->hwndFrom == HWND(m_ListView))
+ {
+ switch(lParam->code)
+ {
+ case (LVN_ITEMCHANGED):
+ return OnItemChanged((const NMLISTVIEW *)lParam);
+ }
+ }
+ return CPropertyPage::OnNotify(aControlID, lParam);
+}
+
+
+bool CSystemPage::OnItemChanged(const NMLISTVIEW *info)
+{
+ if (_initMode)
+ return true;
+ if ((info->uChanged & LVIF_STATE) != 0)
+ {
+ UINT oldState = info->uOldState & LVIS_STATEIMAGEMASK;
+ UINT newState = info->uNewState & LVIS_STATEIMAGEMASK;
+ if (oldState != newState)
+ Changed();
+ }
+ // PostMessage(kRefreshpluginsListMessage, 0);
+ // RefreshPluginsList();
+ return true;
+}
diff --git a/CPP/7zip/UI/Explorer/SystemPage/SystemPage.h b/CPP/7zip/UI/Explorer/SystemPage/SystemPage.h
new file mode 100755
index 00000000..a7de7c79
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/SystemPage/SystemPage.h
@@ -0,0 +1,25 @@
+// SystemPage.h
+
+#ifndef __SYSTEMPAGE_H
+#define __SYSTEMPAGE_H
+
+#include "Windows/Control/PropertyPage.h"
+#include "Windows/Control/ListView.h"
+
+#include "../../Common/ArchiverInfo.h"
+
+class CSystemPage: public NWindows::NControl::CPropertyPage
+{
+ bool _initMode;
+ CObjectVector<CArchiverInfo> m_Archivers;
+ NWindows::NControl::CListView m_ListView;
+public:
+ virtual bool OnInit();
+ virtual void OnNotifyHelp();
+ virtual bool OnNotify(UINT aControlID, LPNMHDR lParam);
+ virtual bool OnItemChanged(const NMLISTVIEW *info);
+ virtual LONG OnApply();
+ virtual bool OnButtonClicked(int aButtonID, HWND aButtonHWND);
+};
+
+#endif
diff --git a/CPP/7zip/UI/Explorer/SystemPage/resource.h b/CPP/7zip/UI/Explorer/SystemPage/resource.h
new file mode 100755
index 00000000..b125849c
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/SystemPage/resource.h
@@ -0,0 +1,6 @@
+#define IDD_SYSTEM 102
+
+#define IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU 1010
+#define IDC_SYSTEM_CASCADED_MENU 1011
+#define IDC_SYSTEM_STATIC_CONTEXT_MENU_ITEMS 1020
+#define IDC_SYSTEM_OPTIONS_LIST 1022
diff --git a/CPP/7zip/UI/Explorer/SystemPage/resource.rc b/CPP/7zip/UI/Explorer/SystemPage/resource.rc
new file mode 100755
index 00000000..fdfed433
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/SystemPage/resource.rc
@@ -0,0 +1,24 @@
+#include "resource.h"
+#include "../../../GuiCommon.rc"
+
+#define xSize2 196
+#define ySize2 164
+#define xSize (xSize2 + marg + marg)
+#define ySize (ySize2 + marg + marg)
+
+IDD_SYSTEM DIALOG 0, 0, xSize, ySize MY_PAGE_STYLE
+CAPTION "System"
+MY_FONT
+BEGIN
+ CONTROL "Integrate 7-Zip to shell context menu", IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU,
+ "Button", BS_AUTOCHECKBOX | WS_TABSTOP,
+ marg, marg, xSize2, 10
+ CONTROL "Cascaded context menu", IDC_SYSTEM_CASCADED_MENU,
+ "Button", BS_AUTOCHECKBOX | WS_TABSTOP,
+ marg, 21, xSize2, 10
+ LTEXT "Context menu items:", IDC_SYSTEM_STATIC_CONTEXT_MENU_ITEMS,
+ marg, 37, xSize2, 8
+ CONTROL "List1", IDC_SYSTEM_OPTIONS_LIST, "SysListView32",
+ LVS_REPORT | LVS_SINGLESEL | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP,
+ marg, 50, xSize2, ySize - marg - 50
+END
diff --git a/CPP/7zip/UI/Explorer/makefile b/CPP/7zip/UI/Explorer/makefile
new file mode 100755
index 00000000..0fcc57e4
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/makefile
@@ -0,0 +1,137 @@
+PROG = 7-zip.dll
+DEF_FILE = Explorer.def
+LIBS = $(LIBS) user32.lib oleaut32.lib advapi32.lib htmlhelp.lib shell32.lib comctl32.lib ole32.lib comdlg32.lib
+CFLAGS = $(CFLAGS) -I ../../../ \
+ -DLANG \
+ -DNEW_FOLDER_INTERFACE \
+ -DWIN_LONG_PATH
+
+EXPLORER_OBJS = \
+ $O\DllExports.obj \
+ $O\ContextMenu.obj \
+ $O\MyMessages.obj \
+ $O\OptionsDialog.obj \
+ $O\RegistryContextMenu.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\IntToString.obj \
+ $O\Lang.obj \
+ $O\ListFileUtils.obj \
+ $O\NewHandler.obj \
+ $O\Random.obj \
+ $O\StdInStream.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\TextConfig.obj \
+ $O\UTFConvert.obj \
+ $O\Vector.obj \
+ $O\Wildcard.obj \
+
+WIN_OBJS = \
+ $O\DLL.obj \
+ $O\Error.obj \
+ $O\FileDir.obj \
+ $O\FileFind.obj \
+ $O\FileIO.obj \
+ $O\FileName.obj \
+ $O\Menu.obj \
+ $O\PropVariant.obj \
+ $O\PropVariantConversions.obj \
+ $O\Registry.obj \
+ $O\ResourceString.obj \
+ $O\Shell.obj \
+ $O\Synchronization.obj \
+ $O\Window.obj \
+
+WIN_CTRL_OBJS = \
+ $O\Dialog.obj \
+ $O\PropertyPage.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\FilePathAutoRename.obj \
+ $O\FileStreams.obj \
+ $O\StreamUtils.obj \
+
+UI_COMMON_OBJS = \
+ $O\ArchiveExtractCallback.obj \
+ $O\ArchiveName.obj \
+ $O\ArchiveOpenCallback.obj \
+ $O\ArchiverInfo.obj \
+ $O\CompressCall.obj \
+ $O\DefaultName.obj \
+ $O\EnumDirItems.obj \
+ $O\ExtractingFilePath.obj \
+ $O\OpenArchive.obj \
+ $O\PropIDUtils.obj \
+ $O\SortUtils.obj \
+ $O\UpdateAction.obj \
+ $O\UpdateCallback.obj \
+ $O\UpdatePair.obj \
+ $O\UpdateProduce.obj \
+ $O\WorkDir.obj \
+ $O\ZipRegistry.obj \
+
+AGENT_OBJS = \
+ $O\Agent.obj \
+ $O\AgentOut.obj \
+ $O\AgentProxy.obj \
+ $O\ArchiveFolder.obj \
+ $O\ArchiveFolderOpen.obj \
+ $O\ArchiveFolderOut.obj \
+ $O\UpdateCallbackAgent.obj \
+
+
+FM_COMMON_OBJS = \
+ $O\FormatUtils.obj \
+ $O\HelpUtils.obj \
+ $O\LangUtils.obj \
+ $O\ProgramLocation.obj \
+ $O\RegistryUtils.obj \
+
+C_OBJS = \
+ $O\Sort.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(EXPLORER_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(WIN_CTRL_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(UI_COMMON_OBJS) \
+ $(AGENT_OBJS) \
+ $(FM_COMMON_OBJS)\
+ $(C_OBJS) \
+ $O\SystemPage.obj \
+ $O\FoldersPage.obj \
+ $O\CopyCoder.obj \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(EXPLORER_OBJS): $(*B).cpp
+ $(COMPL)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(WIN_CTRL_OBJS): ../../../Windows/Control/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$(UI_COMMON_OBJS): ../Common/$(*B).cpp
+ $(COMPL)
+$(AGENT_OBJS): ../Agent/$(*B).cpp
+ $(COMPL)
+$(FM_COMMON_OBJS): ../../FileManager/$(*B).cpp
+ $(COMPL)
+$O\SystemPage.obj: SystemPage/$(*B).cpp
+ $(COMPL)
+$O\FoldersPage.obj: FoldersPage/$(*B).cpp
+ $(COMPL)
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
+$(C_OBJS): ../../../../C/$(*B).c
+ $(COMPL_O2)
diff --git a/CPP/7zip/UI/Explorer/resource.h b/CPP/7zip/UI/Explorer/resource.h
new file mode 100755
index 00000000..aec1e7cd
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/resource.h
@@ -0,0 +1,31 @@
+#define IDS_CONTEXT_EXTRACT 42
+#define IDS_CONTEXT_EXTRACT_HELP 43
+#define IDS_CONTEXT_COMPRESS 44
+#define IDS_CONTEXT_COMPRESS_HELP 45
+#define IDS_CONTEXT_OPEN 46
+#define IDS_CONTEXT_OPEN_HELP 47
+#define IDS_CONTEXT_TEST 48
+#define IDS_CONTEXT_TEST_HELP 49
+#define IDS_CONTEXT_CAPTION_HELP 50
+#define IDS_CONTEXT_POPUP_CAPTION 51
+
+#define IDS_CONTEXT_EXTRACT_HERE 52
+#define IDS_CONTEXT_EXTRACT_HERE_HELP 53
+
+#define IDS_CONTEXT_EXTRACT_TO 54
+#define IDS_CONTEXT_EXTRACT_TO_HELP 55
+
+#define IDS_CONTEXT_COMPRESS_TO 56
+#define IDS_CONTEXT_COMPRESS_TO_HELP 57
+
+#define IDS_CONTEXT_COMPRESS_EMAIL 58
+#define IDS_CONTEXT_COMPRESS_EMAIL_HELP 59
+
+#define IDS_CONTEXT_COMPRESS_TO_EMAIL 60
+#define IDS_CONTEXT_COMPRESS_TO_EMAIL_HELP 61
+
+#define IDS_CONTEXT_FOLDER 70
+#define IDS_CONTEXT_ARCHIVE 71
+
+#define IDS_ERROR 100
+#define IDS_CONFIG_DIALOG_CAPTION 102
diff --git a/CPP/7zip/UI/Explorer/resource.rc b/CPP/7zip/UI/Explorer/resource.rc
new file mode 100755
index 00000000..bf7601d9
--- /dev/null
+++ b/CPP/7zip/UI/Explorer/resource.rc
@@ -0,0 +1,38 @@
+#include "../../MyVersionInfo.rc"
+#include "resource.h"
+
+MY_VERSION_INFO_DLL("7-Zip Shell Extension", "7-zip")
+
+1 24 "7-zip.dll.manifest"
+
+STRINGTABLE
+BEGIN
+ IDS_CONTEXT_EXTRACT "Extract files..."
+ IDS_CONTEXT_EXTRACT_HELP "Extracts files from the selected archive."
+ IDS_CONTEXT_COMPRESS "Add to archive..."
+ IDS_CONTEXT_COMPRESS_HELP "Adds the selected items to archive."
+ IDS_CONTEXT_OPEN "Open archive"
+ IDS_CONTEXT_OPEN_HELP "Opens the selected archive."
+ IDS_CONTEXT_TEST "Test archive"
+ IDS_CONTEXT_TEST_HELP "Tests integrity of the selected archive."
+ IDS_CONTEXT_CAPTION_HELP "7-Zip commands"
+ IDS_CONTEXT_POPUP_CAPTION "7-Zip"
+ IDS_CONTEXT_EXTRACT_HERE "Extract Here"
+ IDS_CONTEXT_EXTRACT_HERE_HELP "Extracts files from the selected archive to current folder."
+ IDS_CONTEXT_EXTRACT_TO "Extract to {0}"
+ IDS_CONTEXT_EXTRACT_TO_HELP "Extracts files to subfolder."
+ IDS_CONTEXT_COMPRESS_TO "Add to {0}"
+ IDS_CONTEXT_COMPRESS_TO_HELP "Adds the selected items to archive."
+ IDS_CONTEXT_COMPRESS_EMAIL "Compress and email..."
+ IDS_CONTEXT_COMPRESS_EMAIL_HELP "Compresses the selected items to archive and sends archive via email."
+ IDS_CONTEXT_COMPRESS_TO_EMAIL "Compress to {0} and email"
+ IDS_CONTEXT_COMPRESS_TO_EMAIL_HELP "Compresses the selected items to archive and sends archive via email."
+ IDS_CONTEXT_FOLDER "<Folder>"
+ IDS_CONTEXT_ARCHIVE "<Archive>"
+ IDS_ERROR "Error"
+ IDS_CONFIG_DIALOG_CAPTION "7-Zip Options"
+END
+
+#include "FoldersPage/resource.rc"
+#include "SystemPage/resource.rc"
+
diff --git a/CPP/7zip/UI/Far/CLSIDConst.cpp b/CPP/7zip/UI/Far/CLSIDConst.cpp
new file mode 100755
index 00000000..a6cea92e
--- /dev/null
+++ b/CPP/7zip/UI/Far/CLSIDConst.cpp
@@ -0,0 +1,8 @@
+// CLSIDConst.cpp
+
+#include "StdAfx.h"
+
+#include <initguid.h>
+
+#include "../Agent/Agent.h"
+#include "../../IPassword.h"
diff --git a/CPP/7zip/UI/Far/ExtractEngine.cpp b/CPP/7zip/UI/Far/ExtractEngine.cpp
new file mode 100755
index 00000000..e85df5e1
--- /dev/null
+++ b/CPP/7zip/UI/Far/ExtractEngine.cpp
@@ -0,0 +1,168 @@
+// ExtractEngine.h
+
+#include "StdAfx.h"
+
+#include <stdio.h>
+
+#include "ExtractEngine.h"
+
+#include "Common/Wildcard.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/Defs.h"
+
+#include "FarUtils.h"
+#include "Messages.h"
+#include "OverwriteDialog.h"
+
+using namespace NWindows;
+using namespace NFar;
+
+extern void PrintMessage(const char *message);
+
+CExtractCallBackImp::~CExtractCallBackImp()
+{
+}
+
+void CExtractCallBackImp::Init(
+ UINT codePage,
+ CProgressBox *progressBox,
+ bool passwordIsDefined,
+ const UString &password)
+{
+ m_PasswordIsDefined = passwordIsDefined;
+ m_Password = password;
+ m_CodePage = codePage;
+ m_ProgressBox = progressBox;
+}
+
+STDMETHODIMP CExtractCallBackImp::SetTotal(UINT64 size)
+{
+ if (m_ProgressBox != 0)
+ {
+ m_ProgressBox->SetTotal(size);
+ m_ProgressBox->PrintCompeteValue(0);
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallBackImp::SetCompleted(const UINT64 *completeValue)
+{
+ if(WasEscPressed())
+ return E_ABORT;
+ if (m_ProgressBox != 0 && completeValue != NULL)
+ m_ProgressBox->PrintCompeteValue(*completeValue);
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallBackImp::AskOverwrite(
+ const wchar_t *existName, const FILETIME *existTime, const UINT64 *existSize,
+ const wchar_t *newName, const FILETIME *aNewTime, const UINT64 *newSize,
+ INT32 *answer)
+{
+ NOverwriteDialog::CFileInfo oldFileInfo, newFileInfo;
+ oldFileInfo.Time = *existTime;
+ oldFileInfo.SizeIsDefined = (existSize != NULL);
+ if (oldFileInfo.SizeIsDefined)
+ oldFileInfo.Size = *existSize;
+ oldFileInfo.Name = GetSystemString(existName, m_CodePage);
+
+
+ newFileInfo.Time = *aNewTime;
+
+ newFileInfo.SizeIsDefined = (newSize != NULL);
+ if (newFileInfo.SizeIsDefined)
+ newFileInfo.Size = *newSize;
+ newFileInfo.Name = GetSystemString(newName, m_CodePage);
+
+ NOverwriteDialog::NResult::EEnum result =
+ NOverwriteDialog::Execute(oldFileInfo, newFileInfo);
+
+ switch(result)
+ {
+ case NOverwriteDialog::NResult::kCancel:
+ // *answer = NOverwriteAnswer::kCancel;
+ // break;
+ return E_ABORT;
+ case NOverwriteDialog::NResult::kNo:
+ *answer = NOverwriteAnswer::kNo;
+ break;
+ case NOverwriteDialog::NResult::kNoToAll:
+ *answer = NOverwriteAnswer::kNoToAll;
+ break;
+ case NOverwriteDialog::NResult::kYesToAll:
+ *answer = NOverwriteAnswer::kYesToAll;
+ break;
+ case NOverwriteDialog::NResult::kYes:
+ *answer = NOverwriteAnswer::kYes;
+ break;
+ case NOverwriteDialog::NResult::kAutoRename:
+ *answer = NOverwriteAnswer::kAutoRename;
+ break;
+ default:
+ throw 20413;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallBackImp::PrepareOperation(const wchar_t *name, INT32 /* askExtractMode */, const UINT64 * /* position */)
+{
+ m_CurrentFilePath = name;
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallBackImp::MessageError(const wchar_t *message)
+{
+ AString s = UnicodeStringToMultiByte(message, CP_OEMCP);
+ if (g_StartupInfo.ShowMessage((const char *)s) == -1)
+ return E_ABORT;
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallBackImp::SetOperationResult(INT32 operationResult, bool encrypted)
+{
+ switch(operationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kOK:
+ break;
+ default:
+ {
+ UINT idMessage;
+ switch(operationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
+ idMessage = NMessageID::kExtractUnsupportedMethod;
+ break;
+ case NArchive::NExtract::NOperationResult::kCRCError:
+ idMessage = NMessageID::kExtractCRCFailed;
+ break;
+ case NArchive::NExtract::NOperationResult::kDataError:
+ idMessage = NMessageID::kExtractDataError;
+ break;
+ default:
+ return E_FAIL;
+ }
+ char buffer[512];
+ sprintf(buffer, g_StartupInfo.GetMsgString(idMessage),
+ GetSystemString(m_CurrentFilePath, m_CodePage));
+ if (g_StartupInfo.ShowMessage(buffer) == -1)
+ return E_ABORT;
+ }
+ }
+ return S_OK;
+}
+
+extern HRESULT GetPassword(UString &password);
+
+STDMETHODIMP CExtractCallBackImp::CryptoGetTextPassword(BSTR *password)
+{
+ if (!m_PasswordIsDefined)
+ {
+ RINOK(GetPassword(m_Password));
+ m_PasswordIsDefined = true;
+ }
+ CMyComBSTR tempName = m_Password;
+ *password = tempName.Detach();
+
+ return S_OK;
+}
diff --git a/CPP/7zip/UI/Far/ExtractEngine.h b/CPP/7zip/UI/Far/ExtractEngine.h
new file mode 100755
index 00000000..57c04f76
--- /dev/null
+++ b/CPP/7zip/UI/Far/ExtractEngine.h
@@ -0,0 +1,68 @@
+// ExtractEngine.h
+
+#ifndef __EXTRACTENGINE_H
+#define __EXTRACTENGINE_H
+
+#include "Common/MyCom.h"
+#include "Common/String.h"
+
+#include "../../IPassword.h"
+#include "../Agent/IFolderArchive.h"
+
+#include "ProgressBox.h"
+
+class CExtractCallBackImp:
+ public IFolderArchiveExtractCallback,
+ public ICryptoGetTextPassword,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP1(ICryptoGetTextPassword)
+
+ // IProgress
+ STDMETHOD(SetTotal)(UINT64 size);
+ STDMETHOD(SetCompleted)(const UINT64 *completeValue);
+
+ // IExtractCallBack
+ STDMETHOD(AskOverwrite)(
+ const wchar_t *existName, const FILETIME *existTime, const UINT64 *existSize,
+ const wchar_t *newName, const FILETIME *newTime, const UINT64 *newSize,
+ INT32 *result);
+ STDMETHOD (PrepareOperation)(const wchar_t *name, INT32 askExtractMode, const UINT64 *position);
+
+ STDMETHOD(MessageError)(const wchar_t *message);
+ STDMETHOD(SetOperationResult)(INT32 resultEOperationResult, bool encrypted);
+ // ICryptoGetTextPassword
+ STDMETHOD(CryptoGetTextPassword)(BSTR *password);
+
+private:
+ UString m_CurrentFilePath;
+
+ struct CProcessedFileInfo
+ {
+ FILETIME UTCLastWriteTime;
+ bool IsDirectory;
+ UINT32 Attributes;
+ } m_ProcessedFileInfo;
+
+ CProgressBox *m_ProgressBox;
+ UINT m_CodePage;
+
+ bool m_PasswordIsDefined;
+ UString m_Password;
+
+ void CreateComplexDirectory(const UStringVector &dirPathParts);
+ /*
+ void GetPropertyValue(LPITEMIDLIST anItemIDList, PROPID aPropId,
+ PROPVARIANT *aValue);
+ bool IsEncrypted(LPITEMIDLIST anItemIDList);
+ */
+ void AddErrorMessage(LPCTSTR message);
+public:
+ ~CExtractCallBackImp();
+ void Init(UINT codePage,
+ CProgressBox *progressBox,
+ bool passwordIsDefined, const UString &password);
+};
+
+#endif
diff --git a/CPP/7zip/UI/Far/Far.def b/CPP/7zip/UI/Far/Far.def
new file mode 100755
index 00000000..d96501e2
--- /dev/null
+++ b/CPP/7zip/UI/Far/Far.def
@@ -0,0 +1,20 @@
+; 7-ZipFar.def : Declares the module parameters for the DLL.
+
+LIBRARY "7-ZipFar"
+DESCRIPTION '7-ZipFar Windows Dynamic Link Library'
+
+EXPORTS
+ SetStartupInfo = _SetStartupInfo@4
+ OpenPlugin = _OpenPlugin@8
+ OpenFilePlugin = _OpenFilePlugin@12
+ ClosePlugin = _ClosePlugin@4
+ GetFindData = _GetFindData@16
+ FreeFindData = _FreeFindData@12
+ SetDirectory = _SetDirectory@12
+ GetPluginInfo = _GetPluginInfo@4
+ Configure = _Configure@4
+ GetOpenPluginInfo = _GetOpenPluginInfo@8
+ GetFiles = _GetFiles@24
+ PutFiles = _PutFiles@20
+ DeleteFiles = _DeleteFiles@16
+ ProcessKey = _ProcessKey@12
diff --git a/CPP/7zip/UI/Far/Far.dsp b/CPP/7zip/UI/Far/Far.dsp
new file mode 100755
index 00000000..47c44c69
--- /dev/null
+++ b/CPP/7zip/UI/Far/Far.dsp
@@ -0,0 +1,561 @@
+# Microsoft Developer Studio Project File - Name="Far" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=Far - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "Far.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "Far.mak" CFG="Far - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Far - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Far - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "Far - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAR_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAR_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\Far\Plugins\7-Zip\7-ZipFar.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Far - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAR_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAR_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\Far\Plugins\7-Zip\7-ZipFar.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "Far - Win32 Release"
+# Name "Far - Win32 Debug"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\CLSIDConst.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Far.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\Alloc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Alloc.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\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.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\Vector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Vector.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.h
+# End Source File
+# End Group
+# Begin Group "Plugin"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\ExtractEngine.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ExtractEngine.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Main.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Messages.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\OverwriteDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\OverwriteDialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Plugin.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Plugin.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\PluginDelete.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\PluginRead.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\PluginWrite.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\UpdateCallback100.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\UpdateCallback100.h
+# End Source File
+# End Group
+# Begin Group "Far"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\FarPlugin.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\FarUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\FarUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ProgressBox.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ProgressBox.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Defs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Error.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Error.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Registry.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Registry.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.h
+# End Source File
+# End Group
+# Begin Group "UI Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Common\ArchiveExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiveExtractCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiveOpenCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiveOpenCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiverInfo.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiverInfo.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\DefaultName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\DefaultName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\DirItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\EnumDirItems.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\EnumDirItems.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ExtractingFilePath.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ExtractingFilePath.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ExtractMode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\HandlerLoader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\OpenArchive.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\OpenArchive.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\PropIDUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\PropIDUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\SortUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\SortUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdateAction.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdateAction.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdateCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdateCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdatePair.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdatePair.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdateProduce.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdateProduce.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\WorkDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\WorkDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ZipRegistry.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ZipRegistry.h
+# End Source File
+# End Group
+# Begin Group "Agent"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Agent\Agent.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\Agent.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\AgentOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\AgentProxy.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\AgentProxy.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\IFolderArchive.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\UpdateCallbackAgent.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\UpdateCallbackAgent.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.h
+# End Source File
+# End Group
+# Begin Group "7-zip Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\FilePathAutoRename.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilePathAutoRename.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/CPP/7zip/UI/Far/Far.dsw b/CPP/7zip/UI/Far/Far.dsw
new file mode 100755
index 00000000..f4ef0801
--- /dev/null
+++ b/CPP/7zip/UI/Far/Far.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Far"=.\Far.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/UI/Far/FarPlugin.h b/CPP/7zip/UI/Far/FarPlugin.h
new file mode 100755
index 00000000..f61bbcb4
--- /dev/null
+++ b/CPP/7zip/UI/Far/FarPlugin.h
@@ -0,0 +1,577 @@
+// FarPlugin.h
+
+#ifndef __FARPLUGIN_H
+#define __FARPLUGIN_H
+
+#if defined(__BORLANDC__) && (__BORLANDC <= 0x520)
+ #pragma option -a1
+#elif defined(__GNUC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1100))
+ #pragma pack(1)
+#else
+ #pragma pack(push,1)
+ #if _MSC_VER
+ #define _export
+ #endif
+#endif
+
+#define NM 260
+
+struct FarFindData
+{
+ DWORD dwFileAttributes;
+ FILETIME ftCreationTime;
+ FILETIME ftLastAccessTime;
+ FILETIME ftLastWriteTime;
+ DWORD nFileSizeHigh;
+ DWORD nFileSizeLow;
+ DWORD dwReserved0;
+ DWORD dwReserved1;
+ char cFileName[ MAX_PATH ];
+ char cAlternateFileName[ 14 ];
+};
+
+struct PluginPanelItem
+{
+ FarFindData FindData;
+ DWORD PackSizeHigh;
+ DWORD PackSize;
+ DWORD Flags;
+ DWORD NumberOfLinks;
+ char *Description;
+ char *Owner;
+ char **CustomColumnData;
+ int CustomColumnNumber;
+ DWORD UserData;
+ DWORD Reserved[3];
+};
+
+#define PPIF_PROCESSDESCR 0x80000000
+#define PPIF_SELECTED 0x40000000
+#define PPIF_USERDATA 0x20000000
+
+enum {
+ FMENU_SHOWAMPERSAND=1,
+ FMENU_WRAPMODE=2,
+ FMENU_AUTOHIGHLIGHT=4,
+ FMENU_REVERSEAUTOHIGHLIGHT=8
+};
+
+
+typedef int (WINAPI *FARAPIMENU)(
+ int PluginNumber,
+ int X,
+ int Y,
+ int MaxHeight,
+ unsigned int Flags,
+ char *Title,
+ char *Bottom,
+ char *HelpTopic,
+ int *BreakKeys,
+ int *BreakCode,
+ struct FarMenuItem *Item,
+ int ItemsNumber
+);
+
+typedef int (WINAPI *FARAPIDIALOG)(
+ int PluginNumber,
+ int X1,
+ int Y1,
+ int X2,
+ int Y2,
+ char *HelpTopic,
+ struct FarDialogItem *Item,
+ int ItemsNumber
+);
+
+enum {
+ FMSG_WARNING=1,
+ FMSG_ERRORTYPE=2,
+ FMSG_KEEPBACKGROUND=4,
+ FMSG_DOWN=8,
+ FMSG_LEFTALIGN=16
+};
+
+typedef int (WINAPI *FARAPIMESSAGE)(
+ int PluginNumber,
+ unsigned int Flags,
+ char *HelpTopic,
+ char **Items,
+ int ItemsNumber,
+ int ButtonsNumber
+);
+
+typedef char* (WINAPI *FARAPIGETMSG)(
+ int PluginNumber,
+ int MsgId
+);
+
+
+enum DialogItemTypes {
+ DI_TEXT,
+ DI_VTEXT,
+ DI_SINGLEBOX,
+ DI_DOUBLEBOX,
+ DI_EDIT,
+ DI_PSWEDIT,
+ DI_FIXEDIT,
+ DI_BUTTON,
+ DI_CHECKBOX,
+ DI_RADIOBUTTON
+};
+
+enum FarDialogItemFlags {
+ DIF_COLORMASK = 0xff,
+ DIF_SETCOLOR = 0x100,
+ DIF_BOXCOLOR = 0x200,
+ DIF_GROUP = 0x400,
+ DIF_LEFTTEXT = 0x800,
+ DIF_MOVESELECT = 0x1000,
+ DIF_SHOWAMPERSAND = 0x2000,
+ DIF_CENTERGROUP = 0x4000,
+ DIF_NOBRACKETS = 0x8000,
+ DIF_SEPARATOR = 0x10000,
+ DIF_EDITOR = 0x20000,
+ DIF_HISTORY = 0x40000
+};
+
+struct FarDialogItem
+{
+ int Type;
+ int X1,Y1,X2,Y2;
+ int Focus;
+ union
+ {
+ int Selected;
+ const char *History;
+ const char *Mask;
+ struct FarList *ListItems;
+ int ListPos;
+ CHAR_INFO *VBuf;
+ };
+ unsigned int Flags;
+ int DefaultButton;
+ char Data[512];
+};
+
+
+struct FarMenuItem
+{
+ char Text[128];
+ int Selected;
+ int Checked;
+ int Separator;
+};
+
+
+enum {FCTL_CLOSEPLUGIN,FCTL_GETPANELINFO,FCTL_GETANOTHERPANELINFO,
+ FCTL_UPDATEPANEL,FCTL_UPDATEANOTHERPANEL,
+ FCTL_REDRAWPANEL,FCTL_REDRAWANOTHERPANEL,
+ FCTL_SETANOTHERPANELDIR,FCTL_GETCMDLINE,FCTL_SETCMDLINE,
+ FCTL_SETSELECTION,FCTL_SETANOTHERSELECTION,
+ FCTL_SETVIEWMODE,FCTL_SETANOTHERVIEWMODE,FCTL_INSERTCMDLINE,
+ FCTL_SETUSERSCREEN,FCTL_SETPANELDIR,FCTL_SETCMDLINEPOS,
+ FCTL_GETCMDLINEPOS
+};
+
+enum {PTYPE_FILEPANEL,PTYPE_TREEPANEL,PTYPE_QVIEWPANEL,PTYPE_INFOPANEL};
+
+struct PanelInfo
+{
+ int PanelType;
+ int Plugin;
+ RECT PanelRect;
+ struct PluginPanelItem *PanelItems;
+ int ItemsNumber;
+ struct PluginPanelItem *SelectedItems;
+ int SelectedItemsNumber;
+ int CurrentItem;
+ int TopPanelItem;
+ int Visible;
+ int Focus;
+ int ViewMode;
+ char ColumnTypes[80];
+ char ColumnWidths[80];
+ char CurDir[NM];
+ int ShortNames;
+ int SortMode;
+ DWORD Reserved[2];
+};
+
+
+struct PanelRedrawInfo
+{
+ int CurrentItem;
+ int TopPanelItem;
+};
+
+
+typedef int (WINAPI *FARAPICONTROL)(
+ HANDLE hPlugin,
+ int Command,
+ void *Param
+);
+
+typedef HANDLE (WINAPI *FARAPISAVESCREEN)(int X1,int Y1,int X2,int Y2);
+
+typedef void (WINAPI *FARAPIRESTORESCREEN)(HANDLE hScreen);
+
+typedef int (WINAPI *FARAPIGETDIRLIST)(
+ char *Dir,
+ struct PluginPanelItem **pPanelItem,
+ int *pItemsNumber
+);
+
+typedef int (WINAPI *FARAPIGETPLUGINDIRLIST)(
+ int PluginNumber,
+ HANDLE hPlugin,
+ char *Dir,
+ struct PluginPanelItem **pPanelItem,
+ int *pItemsNumber
+);
+
+typedef void (WINAPI *FARAPIFREEDIRLIST)(struct PluginPanelItem *PanelItem);
+
+enum VIEWER_FLAGS {
+ VF_NONMODAL=1,VF_DELETEONCLOSE=2
+};
+
+typedef int (WINAPI *FARAPIVIEWER)(
+ char *FileName,
+ char *Title,
+ int X1,
+ int Y1,
+ int X2,
+ int Y2,
+ DWORD Flags
+);
+
+typedef int (WINAPI *FARAPIEDITOR)(
+ char *FileName,
+ char *Title,
+ int X1,
+ int Y1,
+ int X2,
+ int Y2,
+ DWORD Flags,
+ int StartLine,
+ int StartChar
+);
+
+typedef int (WINAPI *FARAPICMPNAME)(
+ char *Pattern,
+ char *String,
+ int SkipPath
+);
+
+
+#define FCT_DETECT 0x40000000
+
+struct CharTableSet
+{
+ char DecodeTable[256];
+ char EncodeTable[256];
+ char UpperTable[256];
+ char LowerTable[256];
+ char TableName[128];
+};
+
+typedef int (WINAPI *FARAPICHARTABLE)(
+ int Command,
+ char *Buffer,
+ int BufferSize
+);
+
+typedef void (WINAPI *FARAPITEXT)(
+ int X,
+ int Y,
+ int Color,
+ char *Str
+);
+
+
+typedef int (WINAPI *FARAPIEDITORCONTROL)(
+ int Command,
+ void *Param
+);
+
+
+enum EDITOR_EVENTS {
+ EE_READ,EE_SAVE,EE_REDRAW,EE_CLOSE
+};
+
+enum EDITOR_CONTROL_COMMANDS {
+ ECTL_GETSTRING,ECTL_SETSTRING,ECTL_INSERTSTRING,ECTL_DELETESTRING,
+ ECTL_DELETECHAR,ECTL_INSERTTEXT,ECTL_GETINFO,ECTL_SETPOSITION,
+ ECTL_SELECT,ECTL_REDRAW,ECTL_EDITORTOOEM,ECTL_OEMTOEDITOR,
+ ECTL_TABTOREAL,ECTL_REALTOTAB,ECTL_EXPANDTABS,ECTL_SETTITLE,
+ ECTL_READINPUT,ECTL_PROCESSINPUT,ECTL_ADDCOLOR,ECTL_GETCOLOR
+};
+
+
+struct EditorGetString
+{
+ int StringNumber;
+ char *StringText;
+ char *StringEOL;
+ int StringLength;
+ int SelStart;
+ int SelEnd;
+};
+
+
+struct EditorSetString
+{
+ int StringNumber;
+ char *StringText;
+ char *StringEOL;
+ int StringLength;
+};
+
+
+enum EDITOR_OPTIONS {
+ EOPT_EXPANDTABS=1,EOPT_PERSISTENTBLOCKS=2,EOPT_DELREMOVESBLOCKS=4,
+ EOPT_AUTOINDENT=8,EOPT_SAVEFILEPOSITION=16,EOPT_AUTODETECTTABLE=32,
+ EOPT_CURSORBEYONDEOL=64
+};
+
+
+enum EDITOR_BLOCK_TYPES {
+ BTYPE_NONE,BTYPE_STREAM,BTYPE_COLUMN
+};
+
+
+struct EditorInfo
+{
+ int EditorID;
+ char *FileName;
+ int WindowSizeX;
+ int WindowSizeY;
+ int TotalLines;
+ int CurLine;
+ int CurPos;
+ int CurTabPos;
+ int TopScreenLine;
+ int LeftPos;
+ int Overtype;
+ int BlockType;
+ int BlockStartLine;
+ int AnsiMode;
+ int TableNum;
+ DWORD Options;
+ int TabSize;
+ DWORD Reserved[8];
+};
+
+
+struct EditorSetPosition
+{
+ int CurLine;
+ int CurPos;
+ int CurTabPos;
+ int TopScreenLine;
+ int LeftPos;
+ int Overtype;
+};
+
+
+struct EditorSelect
+{
+ int BlockType;
+ int BlockStartLine;
+ int BlockStartPos;
+ int BlockWidth;
+ int BlockHeight;
+};
+
+
+struct EditorConvertText
+{
+ char *Text;
+ int TextLength;
+};
+
+
+struct EditorConvertPos
+{
+ int StringNumber;
+ int SrcPos;
+ int DestPos;
+};
+
+
+struct EditorColor
+{
+ int StringNumber;
+ int ColorItem;
+ int StartPos;
+ int EndPos;
+ int Color;
+};
+
+
+struct PluginStartupInfo
+{
+ int StructSize;
+ char ModuleName[NM];
+ int ModuleNumber;
+ char *RootKey;
+ FARAPIMENU Menu;
+ FARAPIDIALOG Dialog;
+ FARAPIMESSAGE Message;
+ FARAPIGETMSG GetMsg;
+ FARAPICONTROL Control;
+ FARAPISAVESCREEN SaveScreen;
+ FARAPIRESTORESCREEN RestoreScreen;
+ FARAPIGETDIRLIST GetDirList;
+ FARAPIGETPLUGINDIRLIST GetPluginDirList;
+ FARAPIFREEDIRLIST FreeDirList;
+ FARAPIVIEWER Viewer;
+ FARAPIEDITOR Editor;
+ FARAPICMPNAME CmpName;
+ FARAPICHARTABLE CharTable;
+ FARAPITEXT Text;
+ FARAPIEDITORCONTROL EditorControl;
+};
+
+
+enum PLUGIN_FLAGS {
+ PF_PRELOAD = 0x0001,
+ PF_DISABLEPANELS = 0x0002,
+ PF_EDITOR = 0x0004,
+ PF_VIEWER = 0x0008
+};
+
+
+struct PluginInfo
+{
+ int StructSize;
+ DWORD Flags;
+ char **DiskMenuStrings;
+ int *DiskMenuNumbers;
+ int DiskMenuStringsNumber;
+ char **PluginMenuStrings;
+ int PluginMenuStringsNumber;
+ char **PluginConfigStrings;
+ int PluginConfigStringsNumber;
+ char *CommandPrefix;
+};
+
+
+struct InfoPanelLine
+{
+ char Text[80];
+ char Data[80];
+ int Separator;
+};
+
+
+struct PanelMode
+{
+ char *ColumnTypes;
+ char *ColumnWidths;
+ char **ColumnTitles;
+ int FullScreen;
+ int DetailedStatus;
+ int AlignExtensions;
+ int CaseConversion;
+ char *StatusColumnTypes;
+ char *StatusColumnWidths;
+ DWORD Reserved[2];
+};
+
+
+enum OPENPLUGININFO_FLAGS {
+ OPIF_USEFILTER = 0x0001,
+ OPIF_USESORTGROUPS = 0x0002,
+ OPIF_USEHIGHLIGHTING = 0x0004,
+ OPIF_ADDDOTS = 0x0008,
+ OPIF_RAWSELECTION = 0x0010,
+ OPIF_REALNAMES = 0x0020,
+ OPIF_SHOWNAMESONLY = 0x0040,
+ OPIF_SHOWRIGHTALIGNNAMES = 0x0080,
+ OPIF_SHOWPRESERVECASE = 0x0100,
+ OPIF_FINDFOLDERS = 0x0200,
+ OPIF_COMPAREFATTIME = 0x0400,
+ OPIF_EXTERNALGET = 0x0800,
+ OPIF_EXTERNALPUT = 0x1000,
+ OPIF_EXTERNALDELETE = 0x2000,
+ OPIF_EXTERNALMKDIR = 0x4000,
+ OPIF_USEATTRHIGHLIGHTING = 0x8000
+};
+
+
+enum OPENPLUGININFO_SORTMODES {
+ SM_DEFAULT,SM_UNSORTED,SM_NAME,SM_EXT,SM_MTIME,SM_CTIME,
+ SM_ATIME,SM_SIZE,SM_DESCR,SM_OWNER,SM_COMPRESSEDSIZE,SM_NUMLINKS
+};
+
+
+struct KeyBarTitles
+{
+ char *Titles[12];
+ char *CtrlTitles[12];
+ char *AltTitles[12];
+ char *ShiftTitles[12];
+};
+
+
+struct OpenPluginInfo
+{
+ int StructSize;
+ DWORD Flags;
+ char *HostFile;
+ char *CurDir;
+ char *Format;
+ char *PanelTitle;
+ struct InfoPanelLine *InfoLines;
+ int InfoLinesNumber;
+ char **DescrFiles;
+ int DescrFilesNumber;
+ struct PanelMode *PanelModesArray;
+ int PanelModesNumber;
+ int StartPanelMode;
+ int StartSortMode;
+ int StartSortOrder;
+ struct KeyBarTitles *KeyBar;
+ char *ShortcutData;
+};
+
+enum {
+ OPEN_DISKMENU,
+ OPEN_PLUGINSMENU,
+ OPEN_FINDLIST,
+ OPEN_SHORTCUT,
+ OPEN_COMMANDLINE,
+ OPEN_EDITOR,
+ OPEN_VIEWER
+};
+
+enum {PKF_CONTROL=1,PKF_ALT=2,PKF_SHIFT=4};
+
+enum FAR_EVENTS {
+ FE_CHANGEVIEWMODE,
+ FE_REDRAW,
+ FE_IDLE,
+ FE_CLOSE,
+ FE_BREAK,
+ FE_COMMAND
+};
+
+enum OPERATION_MODES {
+ OPM_SILENT=1,
+ OPM_FIND=2,
+ OPM_VIEW=4,
+ OPM_EDIT=8,
+ OPM_TOPLEVEL=16,
+ OPM_DESCR=32
+};
+
+#if defined(__BORLANDC__) && (__BORLANDC <= 0x520)
+ #pragma option -a.
+#elif defined(__GNUC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1100))
+ #pragma pack()
+#else
+ #pragma pack(pop)
+#endif
+
+#endif
diff --git a/CPP/7zip/UI/Far/FarUtils.cpp b/CPP/7zip/UI/Far/FarUtils.cpp
new file mode 100755
index 00000000..abbb6817
--- /dev/null
+++ b/CPP/7zip/UI/Far/FarUtils.cpp
@@ -0,0 +1,416 @@
+// FarUtils.cpp
+
+#include "StdAfx.h"
+
+#include "FarUtils.h"
+#include "Common/DynamicBuffer.h"
+#include "Common/StringConvert.h"
+#include "Windows/Defs.h"
+#include "Windows/Console.h"
+#include "Windows/Error.h"
+
+using namespace NWindows;
+
+namespace NFar {
+
+CStartupInfo g_StartupInfo;
+
+void CStartupInfo::Init(const PluginStartupInfo &pluginStartupInfo,
+ const CSysString &pliginNameForRegestry)
+{
+ m_Data = pluginStartupInfo;
+ m_RegistryPath = pluginStartupInfo.RootKey;
+ m_RegistryPath += '\\';
+ m_RegistryPath += pliginNameForRegestry;
+}
+
+const char *CStartupInfo::GetMsgString(int messageId)
+{
+ return (const char*)m_Data.GetMsg(m_Data.ModuleNumber, messageId);
+}
+
+int CStartupInfo::ShowMessage(unsigned int flags,
+ const char *helpTopic, const char **items, int numItems, int numButtons)
+{
+ return m_Data.Message(m_Data.ModuleNumber, flags, (char *)helpTopic,
+ (char **)items, numItems, numButtons);
+}
+
+namespace NMessageID
+{
+ enum
+ {
+ kOk,
+ kCancel,
+ kWarning,
+ kError
+ };
+}
+
+int CStartupInfo::ShowMessage(const char *message)
+{
+ const char *messagesItems[]= { GetMsgString(NMessageID::kError), message,
+ GetMsgString(NMessageID::kOk) };
+ return ShowMessage(FMSG_WARNING, NULL, messagesItems,
+ sizeof(messagesItems) / sizeof(messagesItems[0]), 1);
+}
+
+int CStartupInfo::ShowMessage(int messageId)
+{
+ return ShowMessage(GetMsgString(messageId));
+}
+
+int CStartupInfo::ShowDialog(int X1, int Y1, int X2, int Y2,
+ const char *helpTopic, struct FarDialogItem *items, int numItems)
+{
+ return m_Data.Dialog(m_Data.ModuleNumber, X1, Y1, X2, Y2, (char *)helpTopic,
+ items, numItems);
+}
+
+int CStartupInfo::ShowDialog(int sizeX, int sizeY,
+ const char *helpTopic, struct FarDialogItem *items, int numItems)
+{
+ return ShowDialog(-1, -1, sizeX, sizeY, helpTopic, items, numItems);
+}
+
+inline static BOOL GetBOOLValue(bool v) { return (v? TRUE: FALSE); }
+
+void CStartupInfo::InitDialogItems(const CInitDialogItem *srcItems,
+ FarDialogItem *destItems, int numItems)
+{
+ for (int i = 0; i < numItems; i++)
+ {
+ const CInitDialogItem &srcItem = srcItems[i];
+ FarDialogItem &destItem = destItems[i];
+
+ destItem.Type = srcItem.Type;
+ destItem.X1 = srcItem.X1;
+ destItem.Y1 = srcItem.Y1;
+ destItem.X2 = srcItem.X2;
+ destItem.Y2 = srcItem.Y2;
+ destItem.Focus = GetBOOLValue(srcItem.Focus);
+ if(srcItem.HistoryName != NULL)
+ destItem.History = srcItem.HistoryName;
+ else
+ destItem.Selected = GetBOOLValue(srcItem.Selected);
+ destItem.Flags = srcItem.Flags;
+ destItem.DefaultButton = GetBOOLValue(srcItem.DefaultButton);
+
+ if(srcItem.DataMessageId < 0)
+ MyStringCopy(destItem.Data, srcItem.DataString);
+ else
+ MyStringCopy(destItem.Data, GetMsgString(srcItem.DataMessageId));
+
+ /*
+ if ((unsigned int)Init[i].Data < 0xFFF)
+ MyStringCopy(destItem.Data, GetMsg((unsigned int)srcItem.Data));
+ else
+ MyStringCopy(destItem.Data,srcItem.Data);
+ */
+ }
+}
+
+// --------------------------------------------
+
+HANDLE CStartupInfo::SaveScreen(int X1, int Y1, int X2, int Y2)
+{
+ return m_Data.SaveScreen(X1, Y1, X2, Y2);
+}
+
+HANDLE CStartupInfo::SaveScreen()
+{
+ return SaveScreen(0, 0, -1, -1);
+}
+
+void CStartupInfo::RestoreScreen(HANDLE handle)
+{
+ m_Data.RestoreScreen(handle);
+}
+
+const char kRegestryKeyDelimiter = '\'';
+
+CSysString CStartupInfo::GetFullKeyName(const CSysString &keyName) const
+{
+ return (keyName.IsEmpty()) ? m_RegistryPath:
+ (m_RegistryPath + kRegestryKeyDelimiter + keyName);
+}
+
+
+LONG CStartupInfo::CreateRegKey(HKEY parentKey,
+ const CSysString &keyName, NRegistry::CKey &destKey) const
+{
+ return destKey.Create(parentKey, GetFullKeyName(keyName));
+}
+
+LONG CStartupInfo::OpenRegKey(HKEY parentKey,
+ const CSysString &keyName, NRegistry::CKey &destKey) const
+{
+ return destKey.Open(parentKey, GetFullKeyName(keyName));
+}
+
+void CStartupInfo::SetRegKeyValue(HKEY parentKey, const CSysString &keyName,
+ LPCTSTR valueName, LPCTSTR value) const
+{
+ NRegistry::CKey regKey;
+ CreateRegKey(parentKey, keyName, regKey);
+ regKey.SetValue(valueName, value);
+}
+
+void CStartupInfo::SetRegKeyValue(HKEY parentKey, const CSysString &keyName,
+ LPCTSTR valueName, UINT32 value) const
+{
+ NRegistry::CKey regKey;
+ CreateRegKey(parentKey, keyName, regKey);
+ regKey.SetValue(valueName, value);
+}
+
+void CStartupInfo::SetRegKeyValue(HKEY parentKey, const CSysString &keyName,
+ LPCTSTR valueName, bool value) const
+{
+ NRegistry::CKey regKey;
+ CreateRegKey(parentKey, keyName, regKey);
+ regKey.SetValue(valueName, value);
+}
+
+CSysString CStartupInfo::QueryRegKeyValue(HKEY parentKey, const CSysString &keyName,
+ LPCTSTR valueName, const CSysString &valueDefault) const
+{
+ NRegistry::CKey regKey;
+ if (OpenRegKey(parentKey, keyName, regKey) != ERROR_SUCCESS)
+ return valueDefault;
+
+ CSysString value;
+ if(regKey.QueryValue(valueName, value) != ERROR_SUCCESS)
+ return valueDefault;
+
+ return value;
+}
+
+UINT32 CStartupInfo::QueryRegKeyValue(HKEY parentKey, const CSysString &keyName,
+ LPCTSTR valueName, UINT32 valueDefault) const
+{
+ NRegistry::CKey regKey;
+ if (OpenRegKey(parentKey, keyName, regKey) != ERROR_SUCCESS)
+ return valueDefault;
+
+ UINT32 value;
+ if(regKey.QueryValue(valueName, value) != ERROR_SUCCESS)
+ return valueDefault;
+
+ return value;
+}
+
+bool CStartupInfo::QueryRegKeyValue(HKEY parentKey, const CSysString &keyName,
+ LPCTSTR valueName, bool valueDefault) const
+{
+ NRegistry::CKey regKey;
+ if (OpenRegKey(parentKey, keyName, regKey) != ERROR_SUCCESS)
+ return valueDefault;
+
+ bool value;
+ if(regKey.QueryValue(valueName, value) != ERROR_SUCCESS)
+ return valueDefault;
+
+ return value;
+}
+
+bool CStartupInfo::Control(HANDLE pluginHandle, int command, void *param)
+{
+ return BOOLToBool(m_Data.Control(pluginHandle, command, param));
+}
+
+bool CStartupInfo::ControlRequestActivePanel(int command, void *param)
+{
+ return Control(INVALID_HANDLE_VALUE, command, param);
+}
+
+bool CStartupInfo::ControlGetActivePanelInfo(PanelInfo &panelInfo)
+{
+ return ControlRequestActivePanel(FCTL_GETPANELINFO, &panelInfo);
+}
+
+bool CStartupInfo::ControlSetSelection(const PanelInfo &panelInfo)
+{
+ return ControlRequestActivePanel(FCTL_SETSELECTION, (void *)&panelInfo);
+}
+
+bool CStartupInfo::ControlGetActivePanelCurrentItemInfo(
+ PluginPanelItem &pluginPanelItem)
+{
+ PanelInfo panelInfo;
+ if(!ControlGetActivePanelInfo(panelInfo))
+ return false;
+ if(panelInfo.ItemsNumber <= 0)
+ throw "There are no items";
+ pluginPanelItem = panelInfo.PanelItems[panelInfo.CurrentItem];
+ return true;
+}
+
+bool CStartupInfo::ControlGetActivePanelSelectedOrCurrentItems(
+ CObjectVector<PluginPanelItem> &pluginPanelItems)
+{
+ pluginPanelItems.Clear();
+ PanelInfo panelInfo;
+ if(!ControlGetActivePanelInfo(panelInfo))
+ return false;
+ if(panelInfo.ItemsNumber <= 0)
+ throw "There are no items";
+ if (panelInfo.SelectedItemsNumber == 0)
+ pluginPanelItems.Add(panelInfo.PanelItems[panelInfo.CurrentItem]);
+ else
+ for (int i = 0; i < panelInfo.SelectedItemsNumber; i++)
+ pluginPanelItems.Add(panelInfo.SelectedItems[i]);
+ return true;
+}
+
+bool CStartupInfo::ControlClearPanelSelection()
+{
+ PanelInfo panelInfo;
+ if(!ControlGetActivePanelInfo(panelInfo))
+ return false;
+ for (int i = 0; i < panelInfo.ItemsNumber; i++)
+ panelInfo.PanelItems[i].Flags &= ~PPIF_SELECTED;
+ return ControlSetSelection(panelInfo);
+}
+
+////////////////////////////////////////////////
+// menu function
+
+int CStartupInfo::Menu(
+ int x,
+ int y,
+ int maxHeight,
+ unsigned int flags,
+ const char *title,
+ const char *aBottom,
+ const char *helpTopic,
+ int *breakKeys,
+ int *breakCode,
+ struct FarMenuItem *items,
+ int numItems)
+{
+ return m_Data.Menu(m_Data.ModuleNumber, x, y, maxHeight, flags, (char *)title,
+ (char *)aBottom, (char *)helpTopic, breakKeys, breakCode, items, numItems);
+}
+
+int CStartupInfo::Menu(
+ unsigned int flags,
+ const char *title,
+ const char *helpTopic,
+ struct FarMenuItem *items,
+ int numItems)
+{
+ return Menu(-1, -1, 0, flags, title, NULL, helpTopic, NULL,
+ NULL, items, numItems);
+}
+
+int CStartupInfo::Menu(
+ unsigned int flags,
+ const char *title,
+ const char *helpTopic,
+ const CSysStringVector &items,
+ int selectedItem)
+{
+ CRecordVector<FarMenuItem> farMenuItems;
+ for(int i = 0; i < items.Size(); i++)
+ {
+ FarMenuItem item;
+ item.Checked = 0;
+ item.Separator = 0;
+ item.Selected = (i == selectedItem);
+ AString reducedString = items[i].Left(sizeof(item.Text) / sizeof(item.Text[0]) - 1);
+ MyStringCopy(item.Text, (const char *)reducedString);
+ farMenuItems.Add(item);
+ }
+ return Menu(flags, title, helpTopic, &farMenuItems.Front(), farMenuItems.Size());
+}
+
+
+//////////////////////////////////
+// CScreenRestorer
+
+CScreenRestorer::~CScreenRestorer()
+{
+ Restore();
+}
+void CScreenRestorer::Save()
+{
+ if(m_Saved)
+ return;
+ m_HANDLE = g_StartupInfo.SaveScreen();
+ m_Saved = true;
+}
+
+void CScreenRestorer::Restore()
+{
+ if(m_Saved)
+ {
+ g_StartupInfo.RestoreScreen(m_HANDLE);
+ m_Saved = false;
+ }
+};
+
+static AString DWORDToString(DWORD number)
+{
+ char buffer[32];
+ ultoa(number, buffer, 10);
+ return buffer;
+}
+
+void PrintErrorMessage(const char *message, int code)
+{
+ CSysString tmp = message;
+ tmp += " #";
+ tmp += DWORDToString(code);
+ g_StartupInfo.ShowMessage(tmp);
+}
+
+void PrintErrorMessage(const char *message, const char *text)
+{
+ CSysString tmp = message;
+ tmp += ": ";
+ tmp += text;
+ g_StartupInfo.ShowMessage(tmp);
+}
+
+bool WasEscPressed()
+{
+ NConsole::CIn inConsole;
+ HANDLE handle = ::GetStdHandle(STD_INPUT_HANDLE);
+ if(handle == INVALID_HANDLE_VALUE)
+ return true;
+ inConsole.Attach(handle);
+ for (;;)
+ {
+ DWORD numEvents;
+ if(!inConsole.GetNumberOfEvents(numEvents))
+ return true;
+ if(numEvents == 0)
+ return false;
+
+ INPUT_RECORD event;
+ if(!inConsole.ReadEvent(event, numEvents))
+ return true;
+ if (event.EventType == KEY_EVENT &&
+ event.Event.KeyEvent.bKeyDown &&
+ event.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)
+ return true;
+ }
+}
+
+void ShowErrorMessage(DWORD errorCode)
+{
+ AString message;
+ NError::MyFormatMessage(errorCode, message);
+ message.Replace("\x0D", "");
+ message.Replace("\x0A", " ");
+ g_StartupInfo.ShowMessage(SystemStringToOemString(message));
+
+}
+
+void ShowLastErrorMessage()
+{
+ ShowErrorMessage(::GetLastError());
+}
+
+}
diff --git a/CPP/7zip/UI/Far/FarUtils.h b/CPP/7zip/UI/Far/FarUtils.h
new file mode 100755
index 00000000..4fba193d
--- /dev/null
+++ b/CPP/7zip/UI/Far/FarUtils.h
@@ -0,0 +1,185 @@
+// FarUtils.h
+
+#ifndef __FARUTILS_H
+#define __FARUTILS_H
+
+#include "FarPlugin.h"
+#include "Common/String.h"
+#include "Common/Vector.h"
+#include "Windows/Registry.h"
+
+namespace NFar {
+
+namespace NFileOperationReturnCode
+{
+ enum EEnum
+ {
+ kInterruptedByUser = -1,
+ kError = 0,
+ kSuccess = 1
+ };
+}
+
+namespace NEditorReturnCode
+{
+ enum EEnum
+ {
+ kOpenError = 0,
+ kFileWasChanged = 1,
+ kFileWasNotChanged = 2,
+ kInterruptedByUser = 3
+ };
+}
+
+struct CInitDialogItem
+{
+ DialogItemTypes Type;
+ int X1,Y1,X2,Y2;
+ bool Focus;
+ bool Selected;
+ unsigned int Flags; //FarDialogItemFlags Flags;
+ bool DefaultButton;
+ int DataMessageId;
+ const char *DataString;
+ const char *HistoryName;
+ // void InitToFarDialogItem(struct FarDialogItem &anItemDest);
+};
+
+class CStartupInfo
+{
+ PluginStartupInfo m_Data;
+ CSysString m_RegistryPath;
+
+ CSysString GetFullKeyName(const CSysString &keyName) const;
+ LONG CreateRegKey(HKEY parentKey,
+ const CSysString &keyName, NWindows::NRegistry::CKey &destKey) const;
+ LONG OpenRegKey(HKEY parentKey,
+ const CSysString &keyName, NWindows::NRegistry::CKey &destKey) const;
+
+public:
+ void Init(const PluginStartupInfo &pluginStartupInfo,
+ const CSysString &pliginNameForRegestry);
+ const char *GetMsgString(int messageId);
+ int ShowMessage(unsigned int flags, const char *helpTopic,
+ const char **items, int numItems, int numButtons);
+ int ShowMessage(const char *message);
+ int ShowMessage(int messageId);
+
+ int ShowDialog(int X1, int Y1, int X2, int Y2,
+ const char *helpTopic, struct FarDialogItem *items, int numItems);
+ int ShowDialog(int sizeX, int sizeY,
+ const char *helpTopic, struct FarDialogItem *items, int numItems);
+
+ void InitDialogItems(const CInitDialogItem *srcItems,
+ FarDialogItem *destItems, int numItems);
+
+ HANDLE SaveScreen(int X1, int Y1, int X2, int Y2);
+ HANDLE SaveScreen();
+ void RestoreScreen(HANDLE handle);
+
+ void SetRegKeyValue(HKEY parentKey, const CSysString &keyName,
+ const LPCTSTR valueName, LPCTSTR value) const;
+ void SetRegKeyValue(HKEY hRoot, const CSysString &keyName,
+ const LPCTSTR valueName, UINT32 value) const;
+ void SetRegKeyValue(HKEY hRoot, const CSysString &keyName,
+ const LPCTSTR valueName, bool value) const;
+
+ CSysString QueryRegKeyValue(HKEY parentKey, const CSysString &keyName,
+ LPCTSTR valueName, const CSysString &valueDefault) const;
+
+ UINT32 QueryRegKeyValue(HKEY parentKey, const CSysString &keyName,
+ LPCTSTR valueName, UINT32 valueDefault) const;
+
+ bool QueryRegKeyValue(HKEY parentKey, const CSysString &keyName,
+ LPCTSTR valueName, bool valueDefault) const;
+
+ bool Control(HANDLE plugin, int command, void *param);
+ bool ControlRequestActivePanel(int command, void *param);
+ bool ControlGetActivePanelInfo(PanelInfo &panelInfo);
+ bool ControlSetSelection(const PanelInfo &panelInfo);
+ bool ControlGetActivePanelCurrentItemInfo(PluginPanelItem &pluginPanelItem);
+ bool ControlGetActivePanelSelectedOrCurrentItems(
+ CObjectVector<PluginPanelItem> &pluginPanelItems);
+
+ bool ControlClearPanelSelection();
+
+ int Menu(
+ int x,
+ int y,
+ int maxHeight,
+ unsigned int flags,
+ const char *title,
+ const char *aBottom,
+ const char *helpTopic,
+ int *breakKeys,
+ int *breakCode,
+ FarMenuItem *items,
+ int numItems);
+ int Menu(
+ unsigned int flags,
+ const char *title,
+ const char *helpTopic,
+ FarMenuItem *items,
+ int numItems);
+
+ int Menu(
+ unsigned int flags,
+ const char *title,
+ const char *helpTopic,
+ const CSysStringVector &items,
+ int selectedItem);
+
+ int Editor(const char *fileName, const char *title,
+ int X1, int Y1, int X2, int Y2, DWORD flags, int startLine, int startChar)
+ { return m_Data.Editor((char *)fileName, (char *)title, X1, Y1, X2, Y2,
+ flags, startLine, startChar); }
+ int Editor(const char *fileName)
+ { return Editor(fileName, NULL, 0, 0, -1, -1, 0, -1, -1); }
+
+ int Viewer(const char *fileName, const char *title,
+ int X1, int Y1, int X2, int Y2, DWORD flags)
+ { return m_Data.Viewer((char *)fileName, (char *)title, X1, Y1, X2, Y2, flags); }
+ int Viewer(const char *fileName)
+ { return Viewer(fileName, NULL, 0, 0, -1, -1, VF_NONMODAL); }
+
+};
+
+class CScreenRestorer
+{
+ bool m_Saved;
+ HANDLE m_HANDLE;
+public:
+ CScreenRestorer(): m_Saved(false){};
+ ~CScreenRestorer();
+ void Save();
+ void Restore();
+};
+
+
+extern CStartupInfo g_StartupInfo;
+
+void PrintErrorMessage(const char *message, int code);
+void PrintErrorMessage(const char *message, const char *aText);
+
+#define MY_TRY_BEGIN try\
+ {
+
+#define MY_TRY_END1(x) }\
+ catch(int n) { PrintErrorMessage(x, n); return; }\
+ catch(const CSysString &s) { PrintErrorMessage(x, s); return; }\
+ catch(const char *s) { PrintErrorMessage(x, s); return; }\
+ catch(...) { g_StartupInfo.ShowMessage(x); return; }
+
+#define MY_TRY_END2(x, y) }\
+ catch(int n) { PrintErrorMessage(x, n); return y; }\
+ catch(const CSysString &s) { PrintErrorMessage(x, s); return y; }\
+ catch(const char *s) { PrintErrorMessage(x, s); return y; }\
+ catch(...) { g_StartupInfo.ShowMessage(x); return y; }
+
+bool WasEscPressed();
+void ShowErrorMessage(DWORD errorCode);
+void ShowLastErrorMessage();
+
+}
+
+#endif
diff --git a/CPP/7zip/UI/Far/Main.cpp b/CPP/7zip/UI/Far/Main.cpp
new file mode 100755
index 00000000..a7994b6d
--- /dev/null
+++ b/CPP/7zip/UI/Far/Main.cpp
@@ -0,0 +1,622 @@
+// Test Align for updating !!!!!!!!!!!!!!!!!!
+
+#include "StdAfx.h"
+
+// #include <locale.h>
+#include <initguid.h>
+
+#include "Plugin.h"
+
+#include "Common/Wildcard.h"
+#include "Common/DynamicBuffer.h"
+#include "Common/StringConvert.h"
+#include "Common/Defs.h"
+
+#include "Windows/FileFind.h"
+#include "Windows/FileIO.h"
+#include "Windows/FileDir.h"
+#include "Windows/Defs.h"
+
+#include "../../IPassword.h"
+#include "../../Common/FileStreams.h"
+
+#include "../Common/DefaultName.h"
+#include "../Common/OpenArchive.h"
+#include "../Agent/Agent.h"
+
+#include "ProgressBox.h"
+#include "FarUtils.h"
+#include "Messages.h"
+
+using namespace NWindows;
+using namespace NFar;
+
+static const char *kCommandPrefix = "7-zip";
+
+static const int kDescriptionMaxSize = 256;
+
+static const char *kRegisrtryMainKeyName = "";
+
+static const char *kRegisrtryValueNameEnabled = "UsedByDefault3";
+static bool kPluginEnabledDefault = true;
+
+static const char *kHelpTopicConfig = "Config";
+
+extern "C"
+{
+ void WINAPI SetStartupInfo(struct PluginStartupInfo *info);
+ HANDLE WINAPI OpenFilePlugin(char *name, const unsigned char *Data,
+ unsigned int DataSize);
+ HANDLE WINAPI OpenPlugin(int openFrom, int item);
+ void WINAPI ClosePlugin(HANDLE plugin);
+ int WINAPI GetFindData(HANDLE plugin, struct PluginPanelItem **panelItems,
+ int *itemsNumber, int OpMode);
+ void WINAPI FreeFindData(HANDLE plugin, struct PluginPanelItem *panelItems,
+ int itemsNumber);
+ int WINAPI GetFiles(HANDLE plugin, struct PluginPanelItem *panelItems,
+ int itemsNumber, int move, char *destPath, int opMode);
+ int WINAPI SetDirectory(HANDLE plugin, char *dir, int opMode);
+ void WINAPI GetPluginInfo(struct PluginInfo *info);
+ int WINAPI Configure(int itemNumber);
+ void WINAPI GetOpenPluginInfo(HANDLE plugin, struct OpenPluginInfo *info);
+ int WINAPI PutFiles(HANDLE plugin, struct PluginPanelItem *panelItems,
+ int itemsNumber, int move, int opMode);
+ int WINAPI DeleteFiles(HANDLE plugin, PluginPanelItem *panelItems,
+ int itemsNumber, int opMode);
+ int WINAPI ProcessKey(HANDLE plugin, int key, unsigned int controlState);
+};
+
+HINSTANCE g_hInstance;
+#ifndef _UNICODE
+bool g_IsNT = false;
+static bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+#endif
+
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ g_hInstance = hInstance;
+ #ifndef _UNICODE
+ g_IsNT = IsItWindowsNT();
+ #endif
+ }
+ return TRUE;
+}
+
+static struct COptions
+{
+ bool Enabled;
+} g_Options;
+
+static const char *kPliginNameForRegestry = "7-ZIP";
+
+// #define MY_TRY_BEGIN MY_TRY_BEGIN NCOM::CComInitializer aComInitializer;
+
+void WINAPI SetStartupInfo(struct PluginStartupInfo *info)
+{
+ MY_TRY_BEGIN;
+ g_StartupInfo.Init(*info, kPliginNameForRegestry);
+ g_Options.Enabled = g_StartupInfo.QueryRegKeyValue(
+ HKEY_CURRENT_USER, kRegisrtryMainKeyName,
+ kRegisrtryValueNameEnabled, kPluginEnabledDefault);
+ MY_TRY_END1("SetStartupInfo");
+}
+
+class COpenArchiveCallback:
+ public IArchiveOpenCallback,
+ public IArchiveOpenVolumeCallback,
+ public IProgress,
+ public ICryptoGetTextPassword,
+ public CMyUnknownImp
+{
+ DWORD m_StartTickValue;
+ bool m_MessageBoxIsShown;
+ CMessageBox *m_MessageBox;
+ UINT64 m_NumFiles;
+ UINT64 m_NumFilesMax;
+ UINT64 m_NumFilesPrev;
+ bool m_NumFilesDefined;
+ UINT64 m_NumBytes;
+ bool m_NumBytesDefined;
+ UINT32 m_PrevTickCount;
+
+ NWindows::NFile::NFind::CFileInfoW _fileInfo;
+public:
+ bool PasswordIsDefined;
+ UString Password;
+
+ UString _folderPrefix;
+
+public:
+ MY_UNKNOWN_IMP3(
+ IArchiveOpenVolumeCallback,
+ IProgress,
+ ICryptoGetTextPassword
+ )
+
+ // IProgress
+ STDMETHOD(SetTotal)(UINT64 total);
+ STDMETHOD(SetCompleted)(const UINT64 *aCompleteValue);
+
+ // IArchiveOpenCallback
+ STDMETHOD(SetTotal)(const UINT64 *numFiles, const UINT64 *numBytes);
+ STDMETHOD(SetCompleted)(const UINT64 *numFiles, const UINT64 *numBytes);
+
+ // IArchiveOpenVolumeCallback
+ STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value);
+ STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream);
+
+ // ICryptoGetTextPassword
+ STDMETHOD(CryptoGetTextPassword)(BSTR *password);
+
+ void Init(CMessageBox *messageBox)
+ {
+ PasswordIsDefined = false;
+
+ m_NumFilesMax = 0;
+ m_MessageBoxIsShown = false;
+ m_PrevTickCount = GetTickCount();
+ m_MessageBox = messageBox;
+ }
+ void ShowMessage(const UINT64 *completed);
+
+ void LoadFileInfo(const UString &folderPrefix,
+ const UString &fileName)
+ {
+ _folderPrefix = folderPrefix;
+ if (!NWindows::NFile::NFind::FindFile(_folderPrefix + fileName, _fileInfo))
+ throw 1;
+ }
+};
+
+void COpenArchiveCallback::ShowMessage(const UINT64 *completed)
+{
+ UINT32 currentTime = GetTickCount();
+ if (!m_MessageBoxIsShown)
+ {
+ if (currentTime - m_PrevTickCount < 400)
+ return;
+ m_MessageBox->Init(g_StartupInfo.GetMsgString(NMessageID::kWaitTitle),
+ g_StartupInfo.GetMsgString(NMessageID::kReading), 2, 30);
+ m_MessageBoxIsShown = true;
+ }
+ else
+ {
+ if (currentTime - m_PrevTickCount < 200)
+ return;
+ }
+ m_PrevTickCount = currentTime;
+ char aMessage[256];
+ sprintf(aMessage, "%5I64u", m_NumFilesMax);
+ char aMessage2[256];
+ aMessage2[0] = '\0';
+ if (completed != NULL)
+ sprintf(aMessage2, "%5I64u", *completed);
+ const char *aMessages[2] =
+ {aMessage, aMessage2 };
+ m_MessageBox->ShowProcessMessages(aMessages);
+}
+
+STDMETHODIMP COpenArchiveCallback::SetTotal(const UINT64 *numFiles, const UINT64 *numBytes)
+{
+ if (WasEscPressed())
+ return E_ABORT;
+ m_NumFilesDefined = (numFiles != NULL);
+ if (m_NumFilesDefined)
+ m_NumFiles = *numFiles;
+ m_NumBytesDefined = (numBytes != NULL);
+ if (m_NumBytesDefined)
+ m_NumBytes = *numBytes;
+ return S_OK;
+}
+
+STDMETHODIMP COpenArchiveCallback::SetCompleted(const UINT64 *numFiles, const UINT64 * /* numBytes */)
+{
+ if (WasEscPressed())
+ return E_ABORT;
+ if (numFiles == NULL)
+ return S_OK;
+ m_NumFilesMax = *numFiles;
+ // if (*numFiles % 100 != 0)
+ // return S_OK;
+ ShowMessage(NULL);
+ return S_OK;
+}
+
+
+STDMETHODIMP COpenArchiveCallback::SetTotal(const UINT64 /* total */)
+{
+ if (WasEscPressed())
+ return E_ABORT;
+ /*
+ aNumFilesDefined = (numFiles != NULL);
+ if (aNumFilesDefined)
+ aNumFiles = *numFiles;
+ aNumBytesDefined = (numBytes != NULL);
+ if (aNumBytesDefined)
+ aNumBytes = *numBytes;
+ */
+ return S_OK;
+}
+
+STDMETHODIMP COpenArchiveCallback::SetCompleted(const UINT64 *completed)
+{
+ if (WasEscPressed())
+ return E_ABORT;
+ if (completed == NULL)
+ return S_OK;
+ // if (*completed % 100 != 0)
+ // return S_OK;
+ ShowMessage(completed);
+ return S_OK;
+}
+
+STDMETHODIMP COpenArchiveCallback::GetStream(const wchar_t *name,
+ IInStream **inStream)
+{
+ if (WasEscPressed())
+ return E_ABORT;
+ *inStream = NULL;
+ UString fullPath = _folderPrefix + name;
+ if (!NWindows::NFile::NFind::FindFile(fullPath, _fileInfo))
+ return S_FALSE;
+ if (_fileInfo.IsDirectory())
+ return S_FALSE;
+ CInFileStream *inFile = new CInFileStream;
+ CMyComPtr<IInStream> inStreamTemp = inFile;
+ if (!inFile->Open(fullPath))
+ return ::GetLastError();
+ *inStream = inStreamTemp.Detach();
+ return S_OK;
+}
+
+
+STDMETHODIMP COpenArchiveCallback::GetProperty(PROPID propID, PROPVARIANT *value)
+{
+ NWindows::NCOM::CPropVariant propVariant;
+ switch(propID)
+ {
+ case kpidName:
+ propVariant = GetUnicodeString(_fileInfo.Name, CP_OEMCP);
+ break;
+ case kpidIsFolder:
+ propVariant = _fileInfo.IsDirectory();
+ break;
+ case kpidSize:
+ propVariant = _fileInfo.Size;
+ break;
+ case kpidAttributes:
+ propVariant = (UINT32)_fileInfo.Attributes;
+ break;
+ case kpidLastAccessTime:
+ propVariant = _fileInfo.LastAccessTime;
+ break;
+ case kpidCreationTime:
+ propVariant = _fileInfo.CreationTime;
+ break;
+ case kpidLastWriteTime:
+ propVariant = _fileInfo.LastWriteTime;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
+
+HRESULT GetPassword(UString &password)
+{
+ if (WasEscPressed())
+ return E_ABORT;
+ password.Empty();
+ CInitDialogItem initItems[]=
+ {
+ { DI_DOUBLEBOX, 3, 1, 72, 4, false, false, 0, false, NMessageID::kGetPasswordTitle, NULL, NULL },
+ { DI_TEXT, 5, 2, 0, 0, false, false, DIF_SHOWAMPERSAND, false, NMessageID::kEnterPasswordForFile, NULL, NULL },
+ { DI_PSWEDIT, 5, 3, 70, 3, true, false, 0, true, -1, "", NULL }
+ };
+
+ const int kNumItems = sizeof(initItems)/sizeof(initItems[0]);
+ FarDialogItem dialogItems[kNumItems];
+ g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumItems);
+
+ // sprintf(DialogItems[1].Data,GetMsg(MGetPasswordForFile),FileName);
+ if (g_StartupInfo.ShowDialog(76, 6, NULL, dialogItems, kNumItems) < 0)
+ return (E_ABORT);
+
+ AString oemPassword = dialogItems[2].Data;
+ password = MultiByteToUnicodeString(oemPassword, CP_OEMCP);
+ return S_OK;
+}
+
+STDMETHODIMP COpenArchiveCallback::CryptoGetTextPassword(BSTR *password)
+{
+ if (!PasswordIsDefined)
+ {
+ RINOK(GetPassword(Password));
+ PasswordIsDefined = true;
+ }
+ CMyComBSTR temp = Password;
+ *password = temp.Detach();
+ return S_OK;
+}
+
+/*
+HRESULT OpenArchive(const CSysString &fileName,
+ IInFolderArchive **archiveHandlerResult,
+ CArchiverInfo &archiverInfoResult,
+ UString &defaultName,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ HRESULT OpenArchive(const CSysString &fileName,
+ #ifndef EXCLUDE_COM
+ HMODULE *module,
+ #endif
+ IInArchive **archive,
+ CArchiverInfo &archiverInfoResult,
+ IArchiveOpenCallback *openArchiveCallback);
+}
+*/
+
+static HANDLE MyOpenFilePlugin(const char *name)
+{
+ UINT codePage = ::AreFileApisANSI() ? CP_ACP : CP_OEMCP;
+
+ UString normalizedName = GetUnicodeString(name, codePage);
+ normalizedName.Trim();
+ UString fullName;
+ int fileNamePartStartIndex;
+ NFile::NDirectory::MyGetFullPathName(normalizedName, fullName, fileNamePartStartIndex);
+ NFile::NFind::CFileInfoW fileInfo;
+ if (!NFile::NFind::FindFile(fullName, fileInfo))
+ return INVALID_HANDLE_VALUE;
+ if (fileInfo.IsDirectory())
+ return INVALID_HANDLE_VALUE;
+
+
+ CMyComPtr<IInFolderArchive> archiveHandler;
+
+ // CArchiverInfo archiverInfoResult;
+ // ::OutputDebugString("before OpenArchive\n");
+
+ COpenArchiveCallback *openArchiveCallbackSpec = new COpenArchiveCallback;
+
+ CMyComPtr<IArchiveOpenCallback> openArchiveCallback = openArchiveCallbackSpec;
+
+ // if ((opMode & OPM_SILENT) == 0 && (opMode & OPM_FIND ) == 0)
+ CScreenRestorer screenRestorer;
+ CMessageBox m_MessageBox;
+ {
+ screenRestorer.Save();
+ }
+ openArchiveCallbackSpec->Init(&m_MessageBox);
+ openArchiveCallbackSpec->LoadFileInfo(
+ fullName.Left(fileNamePartStartIndex),
+ fullName.Mid(fileNamePartStartIndex));
+
+ // ::OutputDebugString("before OpenArchive\n");
+
+ archiveHandler = new CAgent;
+ CMyComBSTR archiveType;
+ HRESULT result = archiveHandler->Open(
+ GetUnicodeString(fullName, CP_OEMCP), &archiveType, openArchiveCallback);
+ /*
+ HRESULT result = ::OpenArchive(fullName, &archiveHandler,
+ archiverInfoResult, defaultName, openArchiveCallback);
+ */
+ if (result != S_OK)
+ {
+ if (result == E_ABORT)
+ return (HANDLE)-2;
+ return INVALID_HANDLE_VALUE;
+ }
+
+ // ::OutputDebugString("after OpenArchive\n");
+
+ CPlugin *plugin = new CPlugin(
+ fullName,
+ // defaultName,
+ archiveHandler,
+ (const wchar_t *)archiveType
+ );
+ if (plugin == NULL)
+ return(INVALID_HANDLE_VALUE);
+ plugin->PasswordIsDefined = openArchiveCallbackSpec->PasswordIsDefined;
+ plugin->Password = openArchiveCallbackSpec->Password;
+
+ return (HANDLE)(plugin);
+}
+
+HANDLE WINAPI OpenFilePlugin(char *name,
+ const unsigned char * /* data */, unsigned int /* dataSize */)
+{
+ MY_TRY_BEGIN;
+ if (name == NULL || (!g_Options.Enabled))
+ {
+ // if (!Opt.ProcessShiftF1)
+ return(INVALID_HANDLE_VALUE);
+ }
+ return MyOpenFilePlugin(name);
+ MY_TRY_END2("OpenFilePlugin", INVALID_HANDLE_VALUE);
+}
+
+HANDLE WINAPI OpenPlugin(int openFrom, int item)
+{
+ MY_TRY_BEGIN;
+ if(openFrom == OPEN_COMMANDLINE)
+ {
+ CSysString fileName = (const char *)item;
+ if(fileName.IsEmpty())
+ return INVALID_HANDLE_VALUE;
+ if (fileName.Length() >= 2 &&
+ fileName[0] == '\"' && fileName[fileName.Length() - 1] == '\"')
+ fileName = fileName.Mid(1, fileName.Length() - 2);
+
+ return MyOpenFilePlugin(fileName);
+ }
+ if(openFrom == OPEN_PLUGINSMENU)
+ {
+ switch(item)
+ {
+ case 0:
+ {
+ PluginPanelItem pluginPanelItem;
+ if(!g_StartupInfo.ControlGetActivePanelCurrentItemInfo(pluginPanelItem))
+ throw 142134;
+ return MyOpenFilePlugin(pluginPanelItem.FindData.cFileName);
+ }
+ case 1:
+ {
+ CObjectVector<PluginPanelItem> pluginPanelItem;
+ if(!g_StartupInfo.ControlGetActivePanelSelectedOrCurrentItems(pluginPanelItem))
+ throw 142134;
+ if (CompressFiles(pluginPanelItem) == S_OK)
+ {
+ int t = g_StartupInfo.ControlClearPanelSelection();
+ g_StartupInfo.ControlRequestActivePanel(FCTL_UPDATEPANEL, NULL);
+ g_StartupInfo.ControlRequestActivePanel(FCTL_REDRAWPANEL, NULL);
+ g_StartupInfo.ControlRequestActivePanel(FCTL_UPDATEANOTHERPANEL, NULL);
+ g_StartupInfo.ControlRequestActivePanel(FCTL_REDRAWANOTHERPANEL, NULL);
+ }
+ return INVALID_HANDLE_VALUE;
+ }
+ default:
+ throw 4282215;
+ }
+ }
+ return INVALID_HANDLE_VALUE;
+ MY_TRY_END2("OpenPlugin", INVALID_HANDLE_VALUE);
+}
+
+void WINAPI ClosePlugin(HANDLE plugin)
+{
+ MY_TRY_BEGIN;
+ delete (CPlugin *)plugin;
+ MY_TRY_END1("ClosePlugin");
+}
+
+int WINAPI GetFindData(HANDLE plugin, struct PluginPanelItem **panelItems,
+ int *itemsNumber,int opMode)
+{
+ MY_TRY_BEGIN;
+ return(((CPlugin *)plugin)->GetFindData(panelItems, itemsNumber, opMode));
+ MY_TRY_END2("GetFindData", FALSE);
+}
+
+void WINAPI FreeFindData(HANDLE plugin, struct PluginPanelItem *panelItems,
+ int itemsNumber)
+{
+ MY_TRY_BEGIN;
+ ((CPlugin *)plugin)->FreeFindData(panelItems, itemsNumber);
+ MY_TRY_END1("FreeFindData");
+}
+
+int WINAPI GetFiles(HANDLE plugin, struct PluginPanelItem *panelItems,
+ int itemsNumber, int move, char *destPath, int opMode)
+{
+ MY_TRY_BEGIN;
+ return(((CPlugin *)plugin)->GetFiles(panelItems, itemsNumber, move, destPath, opMode));
+ MY_TRY_END2("GetFiles", NFileOperationReturnCode::kError);
+}
+
+int WINAPI SetDirectory(HANDLE plugin, char *dir, int opMode)
+{
+ MY_TRY_BEGIN;
+ return(((CPlugin *)plugin)->SetDirectory(dir, opMode));
+ MY_TRY_END2("SetDirectory", FALSE);
+}
+
+void WINAPI GetPluginInfo(struct PluginInfo *info)
+{
+ MY_TRY_BEGIN;
+
+ info->StructSize = sizeof(*info);
+ info->Flags = 0;
+ info->DiskMenuStrings = NULL;
+ info->DiskMenuNumbers = NULL;
+ info->DiskMenuStringsNumber = 0;
+ static const char *pluginMenuStrings[2];
+ pluginMenuStrings[0] = g_StartupInfo.GetMsgString(NMessageID::kOpenArchiveMenuString);
+ pluginMenuStrings[1] = g_StartupInfo.GetMsgString(NMessageID::kCreateArchiveMenuString);
+ info->PluginMenuStrings = (char **)pluginMenuStrings;
+ info->PluginMenuStringsNumber = 2;
+ static const char *pluginCfgStrings[1];
+ pluginCfgStrings[0] = g_StartupInfo.GetMsgString(NMessageID::kOpenArchiveMenuString);
+ info->PluginConfigStrings = (char **)pluginCfgStrings;
+ info->PluginConfigStringsNumber = sizeof(pluginCfgStrings) / sizeof(pluginCfgStrings[0]);
+ info->CommandPrefix = (char *)kCommandPrefix;
+ MY_TRY_END1("GetPluginInfo");
+}
+
+int WINAPI Configure(int itemNumber)
+{
+ MY_TRY_BEGIN;
+
+ const int kEnabledCheckBoxIndex = 1;
+
+ const int kYSize = 7;
+
+ struct CInitDialogItem initItems[]=
+ {
+ { DI_DOUBLEBOX, 3, 1, 72, kYSize - 2, false, false, 0, false, NMessageID::kConfigTitle, NULL, NULL },
+ { DI_CHECKBOX, 5, 2, 0, 0, true, g_Options.Enabled, 0, false, NMessageID::kConfigPluginEnabled, NULL, NULL },
+ { DI_TEXT, 5, 3, 0, 0, false, false, DIF_BOXCOLOR | DIF_SEPARATOR, false, -1, "", NULL },
+ { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, true, NMessageID::kOk, NULL, NULL },
+ { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kCancel, NULL, NULL },
+ };
+
+ const int kNumDialogItems = sizeof(initItems) / sizeof(initItems[0]);
+ const int kOkButtonIndex = kNumDialogItems - 2;
+
+ FarDialogItem dialogItems[kNumDialogItems];
+ g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems);
+
+ int askCode = g_StartupInfo.ShowDialog(76, kYSize,
+ kHelpTopicConfig, dialogItems, kNumDialogItems);
+
+ if (askCode != kOkButtonIndex)
+ return (FALSE);
+
+ g_Options.Enabled = BOOLToBool(dialogItems[kEnabledCheckBoxIndex].Selected);
+
+ g_StartupInfo.SetRegKeyValue(HKEY_CURRENT_USER, kRegisrtryMainKeyName,
+ kRegisrtryValueNameEnabled, g_Options.Enabled);
+ return(TRUE);
+ MY_TRY_END2("Configure", FALSE);
+}
+
+void WINAPI GetOpenPluginInfo(HANDLE plugin,struct OpenPluginInfo *info)
+{
+ MY_TRY_BEGIN;
+ ((CPlugin *)plugin)->GetOpenPluginInfo(info);
+ MY_TRY_END1("GetOpenPluginInfo");
+}
+
+int WINAPI PutFiles(HANDLE plugin, struct PluginPanelItem *panelItems,
+ int itemsNumber, int move, int opMode)
+{
+ MY_TRY_BEGIN;
+ return(((CPlugin *)plugin)->PutFiles(panelItems, itemsNumber, move, opMode));
+ MY_TRY_END2("PutFiles", NFileOperationReturnCode::kError);
+}
+
+int WINAPI DeleteFiles(HANDLE plugin, PluginPanelItem *panelItems,
+ int itemsNumber, int opMode)
+{
+ MY_TRY_BEGIN;
+ return(((CPlugin *)plugin)->DeleteFiles(panelItems, itemsNumber, opMode));
+ MY_TRY_END2("DeleteFiles", FALSE);
+}
+
+int WINAPI ProcessKey(HANDLE plugin, int key, unsigned int controlState)
+{
+ MY_TRY_BEGIN;
+ return (((CPlugin *)plugin)->ProcessKey(key, controlState));
+ MY_TRY_END2("ProcessKey", FALSE);
+}
diff --git a/CPP/7zip/UI/Far/Messages.h b/CPP/7zip/UI/Far/Messages.h
new file mode 100755
index 00000000..8b6e2a49
--- /dev/null
+++ b/CPP/7zip/UI/Far/Messages.h
@@ -0,0 +1,152 @@
+// SevenZip/ Messages.h
+
+#ifndef __SEVENZIP_MESSAGES_H
+#define __SEVENZIP_MESSAGES_H
+
+namespace NMessageID {
+
+enum EEnum
+{
+ kOk,
+ kCancel,
+
+ kWarning,
+ kError,
+
+ kArchiveType,
+
+ kProperties,
+
+ kYes,
+ kNo,
+
+ kName,
+ kExtension,
+ kIsFolder,
+ kSize,
+ kPackedSize,
+ kAttributes,
+ kCreationTime,
+ kLastAccessTime,
+ kLastWriteTime,
+ kSolid,
+ kCommented,
+ kEncrypted,
+ kSplitBefore,
+ kSplitAfter,
+ kDictionarySize,
+ kCRC,
+ kType,
+ kAnti,
+ kMethod,
+ kHostOS,
+ kFileSystem,
+ kUser,
+ kGroup,
+ kBlock,
+ kComment,
+ kPosition,
+
+ kGetPasswordTitle,
+ kEnterPasswordForFile,
+
+ kExtractTitle,
+ kExtractTo,
+
+ kExtractPathMode,
+ kExtractPathFull,
+ kExtractPathCurrent,
+ kExtractPathNo,
+
+ kExtractOwerwriteMode,
+ kExtractOwerwriteAsk,
+ kExtractOwerwritePrompt,
+ kExtractOwerwriteSkip,
+ kExtractOwerwriteAutoRename,
+ kExtractOwerwriteAutoRenameExisting,
+
+ kExtractFilesMode,
+ kExtractFilesSelected,
+ kExtractFilesAll,
+
+ kExtractPassword,
+
+ kExtractExtract,
+ kExtractCancel,
+
+ kExtractCanNotOpenOutputFile,
+
+ kExtractUnsupportedMethod,
+ kExtractCRCFailed,
+ kExtractDataError,
+
+ kOverwriteTitle,
+ kOverwriteMessage1,
+ kOverwriteMessageWouldYouLike,
+ kOverwriteMessageWithtTisOne,
+
+ kOverwriteBytes,
+ kOverwriteModifiedOn,
+
+ kOverwriteYes,
+ kOverwriteYesToAll,
+ kOverwriteNo,
+ kOverwriteNoToAll,
+ kOverwriteAutoRename,
+ kOverwriteCancel,
+
+ kUpdateNotSupportedForThisArchive,
+
+ kDeleteTitle,
+ kDeleteFile,
+ kDeleteFiles,
+ kDeleteNumberOfFiles,
+ kDeleteDelete,
+ kDeleteCancel,
+
+ kUpdateTitle,
+ kUpdateAddToArchive,
+
+ kUpdateMethod,
+ kUpdateMethodStore,
+ kUpdateMethodFastest,
+ kUpdateMethodFast,
+ kUpdateMethodNormal,
+ kUpdateMethodMaximum,
+ kUpdateMethodUltra,
+
+ kUpdateMode,
+ kUpdateModeAdd,
+ kUpdateModeUpdate,
+ kUpdateModeFreshen,
+ kUpdateModeSynchronize,
+
+ kUpdateAdd,
+ kUpdateSelectArchiver,
+
+ kUpdateSelectArchiverMenuTitle,
+
+ // kArcReadFiles,
+
+ kWaitTitle,
+
+ kReading,
+ kExtracting,
+ kDeleting,
+ kUpdating,
+
+ // kReadingList,
+
+ kMoveIsNotSupported,
+
+ kOpenArchiveMenuString,
+ kCreateArchiveMenuString,
+
+ kConfigTitle,
+
+ kConfigPluginEnabled
+};
+
+}
+
+#endif \ No newline at end of file
diff --git a/CPP/7zip/UI/Far/OverwriteDialog.cpp b/CPP/7zip/UI/Far/OverwriteDialog.cpp
new file mode 100755
index 00000000..028fff4e
--- /dev/null
+++ b/CPP/7zip/UI/Far/OverwriteDialog.cpp
@@ -0,0 +1,109 @@
+// OverwriteDialog.cpp
+
+#include "StdAfx.h"
+
+#include <stdio.h>
+
+#include "OverwriteDialog.h"
+
+#include "Common/String.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/FileName.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariantConversions.h"
+
+#include "FarUtils.h"
+#include "Messages.h"
+
+using namespace NWindows;
+using namespace NFar;
+
+namespace NOverwriteDialog {
+
+static const char *kHelpTopic = "OverwriteDialog";
+
+struct CFileInfoStrings
+{
+ CSysString Size;
+ CSysString Time;
+};
+
+void SetFileInfoStrings(const CFileInfo &fileInfo,
+ CFileInfoStrings &fileInfoStrings)
+{
+ char buffer[256];
+
+ if (fileInfo.SizeIsDefined)
+ {
+ sprintf(buffer, "%I64u ", fileInfo.Size);
+ fileInfoStrings.Size = buffer;
+ fileInfoStrings.Size += g_StartupInfo.GetMsgString(NMessageID::kOverwriteBytes);
+ }
+ else
+ {
+ fileInfoStrings.Size = "";
+ }
+
+ FILETIME localFileTime;
+ if (!FileTimeToLocalFileTime(&fileInfo.Time, &localFileTime))
+ throw 4190402;
+ UString timeString = ConvertFileTimeToString(localFileTime);
+
+ fileInfoStrings.Time = g_StartupInfo.GetMsgString(NMessageID::kOverwriteModifiedOn);
+ fileInfoStrings.Time += " ";
+ fileInfoStrings.Time += GetSystemString(timeString, CP_OEMCP);
+}
+
+NResult::EEnum Execute(const CFileInfo &oldFileInfo, const CFileInfo &newFileInfo)
+{
+ const int kYSize = 20;
+ const int kXSize = 76;
+
+ CFileInfoStrings oldFileInfoStrings;
+ CFileInfoStrings newFileInfoStrings;
+
+ SetFileInfoStrings(oldFileInfo, oldFileInfoStrings);
+ SetFileInfoStrings(newFileInfo, newFileInfoStrings);
+
+ struct CInitDialogItem anInitItems[]={
+ { DI_DOUBLEBOX, 3, 1, kXSize - 4, kYSize - 2, false, false, 0, false, NMessageID::kOverwriteTitle, NULL, NULL },
+ { DI_TEXT, 5, 2, 0, 0, false, false, 0, false, NMessageID::kOverwriteMessage1, NULL, NULL },
+
+ { DI_TEXT, 3, 3, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL },
+
+ { DI_TEXT, 5, 4, 0, 0, false, false, 0, false, NMessageID::kOverwriteMessageWouldYouLike, NULL, NULL },
+
+ { DI_TEXT, 7, 6, 0, 0, false, false, 0, false, -1, oldFileInfo.Name, NULL },
+ { DI_TEXT, 7, 7, 0, 0, false, false, 0, false, -1, oldFileInfoStrings.Size, NULL },
+ { DI_TEXT, 7, 8, 0, 0, false, false, 0, false, -1, oldFileInfoStrings.Time, NULL },
+
+ { DI_TEXT, 5, 10, 0, 0, false, false, 0, false, NMessageID::kOverwriteMessageWithtTisOne, NULL, NULL },
+
+ { DI_TEXT, 7, 12, 0, 0, false, false, 0, false, -1, newFileInfo.Name, NULL },
+ { DI_TEXT, 7, 13, 0, 0, false, false, 0, false, -1, newFileInfoStrings.Size, NULL },
+ { DI_TEXT, 7, 14, 0, 0, false, false, 0, false, -1, newFileInfoStrings.Time, NULL },
+
+ { DI_TEXT, 3, kYSize - 5, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL },
+
+ { DI_BUTTON, 0, kYSize - 4, 0, 0, true, false, DIF_CENTERGROUP, true, NMessageID::kOverwriteYes, NULL, NULL },
+ { DI_BUTTON, 0, kYSize - 4, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kOverwriteYesToAll, NULL, NULL },
+ { DI_BUTTON, 0, kYSize - 4, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kOverwriteNo, NULL, NULL },
+ { DI_BUTTON, 0, kYSize - 4, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kOverwriteNoToAll, NULL, NULL },
+ { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kOverwriteAutoRename, NULL, NULL },
+ { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kOverwriteCancel, NULL, NULL }
+ };
+
+ const int kNumDialogItems = sizeof(anInitItems) / sizeof(anInitItems[0]);
+ FarDialogItem aDialogItems[kNumDialogItems];
+ g_StartupInfo.InitDialogItems(anInitItems, aDialogItems, kNumDialogItems);
+ int anAskCode = g_StartupInfo.ShowDialog(kXSize, kYSize,
+ NULL, aDialogItems, kNumDialogItems);
+ const int kButtonStartPos = kNumDialogItems - 6;
+ if (anAskCode >= kButtonStartPos && anAskCode < kNumDialogItems)
+ return NResult::EEnum(anAskCode - kButtonStartPos);
+ return NResult::kCancel;
+}
+
+}
+
diff --git a/CPP/7zip/UI/Far/OverwriteDialog.h b/CPP/7zip/UI/Far/OverwriteDialog.h
new file mode 100755
index 00000000..ff1a480e
--- /dev/null
+++ b/CPP/7zip/UI/Far/OverwriteDialog.h
@@ -0,0 +1,33 @@
+// OverwriteDialog.h
+
+#ifndef OVERWRITEDIALOG_H
+#define OVERWRITEDIALOG_H
+
+#include "Common/String.h"
+
+namespace NOverwriteDialog {
+
+struct CFileInfo
+{
+ bool SizeIsDefined;
+ UINT64 Size;
+ FILETIME Time;
+ CSysString Name;
+};
+namespace NResult
+{
+ enum EEnum
+ {
+ kYes,
+ kYesToAll,
+ kNo,
+ kNoToAll,
+ kAutoRename,
+ kCancel,
+ };
+}
+NResult::EEnum Execute(const CFileInfo &anOldFileInfo, const CFileInfo &aNewFileInfo);
+
+}
+
+#endif
diff --git a/CPP/7zip/UI/Far/Plugin.cpp b/CPP/7zip/UI/Far/Plugin.cpp
new file mode 100755
index 00000000..0d4b150e
--- /dev/null
+++ b/CPP/7zip/UI/Far/Plugin.cpp
@@ -0,0 +1,693 @@
+// Plugin.cpp
+
+#include "StdAfx.h"
+
+#include "Plugin.h"
+
+#include "Common/StringConvert.h"
+#include "Common/Wildcard.h"
+
+#include "Windows/PropVariantConversions.h"
+#include "Windows/FileName.h"
+#include "Windows/FileDir.h"
+
+#include "../Common/PropIDUtils.h"
+
+#include "Messages.h"
+#include "FarUtils.h"
+
+using namespace NWindows;
+using namespace NFar;
+
+CSysString ConvertPropertyToString2(const PROPVARIANT &propVariant, PROPID propID)
+{
+ if (propVariant.vt == VT_BSTR)
+ return GetSystemString(propVariant.bstrVal, CP_OEMCP);
+ if (propVariant.vt != VT_BOOL)
+ return GetSystemString(ConvertPropertyToString(propVariant, propID), CP_OEMCP);
+ int messageID = VARIANT_BOOLToBool(propVariant.boolVal) ?
+ NMessageID::kYes : NMessageID::kNo;
+ return g_StartupInfo.GetMsgString(messageID);
+}
+
+CPlugin::CPlugin(const UString &fileName,
+ // const UString &defaultName,
+ IInFolderArchive *archiveHandler,
+ UString archiveTypeName
+ ):
+ m_ArchiveHandler(archiveHandler),
+ m_FileName(fileName),
+ _archiveTypeName(archiveTypeName)
+ // , m_DefaultName(defaultName)
+ // , m_ArchiverInfo(archiverInfo)
+{
+ if (!NFile::NFind::FindFile(m_FileName, m_FileInfo))
+ throw "error";
+ archiveHandler->BindToRootFolder(&_folder);
+}
+
+CPlugin::~CPlugin()
+{
+}
+
+static void MyGetFileTime(IFolderFolder *anArchiveFolder, UINT32 itemIndex,
+ PROPID propID, FILETIME &fileTime)
+{
+ NCOM::CPropVariant propVariant;
+ if (anArchiveFolder->GetProperty(itemIndex, propID, &propVariant) != S_OK)
+ throw 271932;
+ if (propVariant.vt == VT_EMPTY)
+ {
+ fileTime.dwHighDateTime = 0;
+ fileTime.dwLowDateTime = 0;
+ }
+ else
+ {
+ if (propVariant.vt != VT_FILETIME)
+ throw 4191730;
+ fileTime = propVariant.filetime;
+ }
+}
+
+void CPlugin::ReadPluginPanelItem(PluginPanelItem &panelItem, UINT32 itemIndex)
+{
+ NCOM::CPropVariant propVariant;
+ if (_folder->GetProperty(itemIndex, kpidName, &propVariant) != S_OK)
+ throw 271932;
+
+ if (propVariant.vt != VT_BSTR)
+ throw 272340;
+
+ CSysString oemString = UnicodeStringToMultiByte(propVariant.bstrVal, CP_OEMCP);
+ strcpy(panelItem.FindData.cFileName, oemString);
+ panelItem.FindData.cAlternateFileName[0] = 0;
+
+ if (_folder->GetProperty(itemIndex, kpidAttributes, &propVariant) != S_OK)
+ throw 271932;
+ if (propVariant.vt == VT_UI4)
+ panelItem.FindData.dwFileAttributes = propVariant.ulVal;
+ else if (propVariant.vt == VT_EMPTY)
+ panelItem.FindData.dwFileAttributes = m_FileInfo.Attributes;
+ else
+ throw 21631;
+
+ if (_folder->GetProperty(itemIndex, kpidIsFolder, &propVariant) != S_OK)
+ throw 271932;
+ if (propVariant.vt == VT_BOOL)
+ {
+ if (VARIANT_BOOLToBool(propVariant.boolVal))
+ panelItem.FindData.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
+ }
+ else if (propVariant.vt != VT_EMPTY)
+ throw 21632;
+
+ if (_folder->GetProperty(itemIndex, kpidSize, &propVariant) != S_OK)
+ throw 271932;
+ UINT64 length;
+ if (propVariant.vt == VT_EMPTY)
+ length = 0;
+ else
+ length = ::ConvertPropVariantToUInt64(propVariant);
+ panelItem.FindData.nFileSizeLow = UINT32(length);
+ panelItem.FindData.nFileSizeHigh = UINT32(length >> 32);
+
+ MyGetFileTime(_folder, itemIndex, kpidCreationTime, panelItem.FindData.ftCreationTime);
+ MyGetFileTime(_folder, itemIndex, kpidLastAccessTime, panelItem.FindData.ftLastAccessTime);
+ MyGetFileTime(_folder, itemIndex, kpidLastWriteTime, panelItem.FindData.ftLastWriteTime);
+
+ if (panelItem.FindData.ftLastWriteTime.dwHighDateTime == 0 &&
+ panelItem.FindData.ftLastWriteTime.dwLowDateTime == 0)
+ panelItem.FindData.ftLastWriteTime = m_FileInfo.LastWriteTime;
+
+ if (_folder->GetProperty(itemIndex, kpidPackedSize, &propVariant) != S_OK)
+ throw 271932;
+ if (propVariant.vt == VT_EMPTY)
+ length = 0;
+ else
+ length = ::ConvertPropVariantToUInt64(propVariant);
+ panelItem.PackSize = UINT32(length);
+ panelItem.PackSizeHigh = UINT32(length >> 32);
+
+ panelItem.Flags = 0;
+ panelItem.NumberOfLinks = 0;
+
+ panelItem.Description = NULL;
+ panelItem.Owner = NULL;
+ panelItem.CustomColumnData = NULL;
+ panelItem.CustomColumnNumber = 0;
+
+ panelItem.Reserved[0] = 0;
+ panelItem.Reserved[1] = 0;
+ panelItem.Reserved[2] = 0;
+
+
+}
+
+int CPlugin::GetFindData(PluginPanelItem **panelItems,
+ int *itemsNumber, int opMode)
+{
+ // CScreenRestorer screenRestorer;
+ if ((opMode & OPM_SILENT) == 0 && (opMode & OPM_FIND ) == 0)
+ {
+ /*
+ screenRestorer.Save();
+ const char *aMsgItems[]=
+ {
+ g_StartupInfo.GetMsgString(NMessageID::kWaitTitle),
+ g_StartupInfo.GetMsgString(NMessageID::kReadingList)
+ };
+ g_StartupInfo.ShowMessage(0, NULL, aMsgItems,
+ sizeof(aMsgItems) / sizeof(aMsgItems[0]), 0);
+ */
+ }
+
+ UINT32 numItems;
+ _folder->GetNumberOfItems(&numItems);
+ *panelItems = new PluginPanelItem[numItems];
+ try
+ {
+ for(UINT32 i = 0; i < numItems; i++)
+ {
+ PluginPanelItem &panelItem = (*panelItems)[i];
+ ReadPluginPanelItem(panelItem, i);
+ panelItem.UserData = i;
+ }
+ }
+ catch(...)
+ {
+ delete [](*panelItems);
+ throw;
+ }
+ *itemsNumber = numItems;
+ return(TRUE);
+}
+
+void CPlugin::FreeFindData(struct PluginPanelItem *panelItems,
+ int itemsNumber)
+{
+ for(int i = 0; i < itemsNumber; i++)
+ if(panelItems[i].Description != NULL)
+ delete []panelItems[i].Description;
+ delete []panelItems;
+}
+
+
+void CPlugin::EnterToDirectory(const UString &aDirName)
+{
+ CMyComPtr<IFolderFolder> newFolder;
+ _folder->BindToFolder(aDirName, &newFolder);
+ if(newFolder == NULL)
+ if (aDirName.IsEmpty())
+ return;
+ else
+ throw 40325;
+ _folder = newFolder;
+}
+
+int CPlugin::SetDirectory(const char *aszDir, int opMode)
+{
+ UString path = MultiByteToUnicodeString(aszDir, CP_OEMCP);
+ if (path == L"\\")
+ {
+ _folder.Release();
+ m_ArchiveHandler->BindToRootFolder(&_folder);
+ }
+ else if (path == L"..")
+ {
+ CMyComPtr<IFolderFolder> newFolder;
+ _folder->BindToParentFolder(&newFolder);
+ if (newFolder == NULL)
+ throw 40312;
+ _folder = newFolder;
+ }
+ else if (path.IsEmpty())
+ EnterToDirectory(path);
+ else
+ {
+ if (path[0] == L'\\')
+ {
+ _folder.Release();
+ m_ArchiveHandler->BindToRootFolder(&_folder);
+ path = path.Mid(1);
+ }
+ UStringVector pathParts;
+ SplitPathToParts(path, pathParts);
+ for(int i = 0; i < pathParts.Size(); i++)
+ EnterToDirectory(pathParts[i]);
+ }
+ GetCurrentDir();
+ return TRUE;
+}
+
+void CPlugin::GetPathParts(UStringVector &pathParts)
+{
+ pathParts.Clear();
+ CMyComPtr<IFolderFolder> folderItem = _folder;
+ for (;;)
+ {
+ CMyComPtr<IFolderFolder> newFolder;
+ folderItem->BindToParentFolder(&newFolder);
+ if (newFolder == NULL)
+ break;
+ CMyComBSTR name;
+ folderItem->GetName(&name);
+ pathParts.Insert(0, (const wchar_t *)name);
+ folderItem = newFolder;
+ }
+}
+
+void CPlugin::GetCurrentDir()
+{
+ m_CurrentDir.Empty();
+ UStringVector pathParts;
+ GetPathParts(pathParts);
+ for (int i = 0; i < pathParts.Size(); i++)
+ {
+ m_CurrentDir += L'\\';
+ m_CurrentDir += pathParts[i];
+ }
+}
+
+static char *kPluginFormatName = "7-ZIP";
+
+
+struct CPROPIDToName
+{
+ PROPID PropID;
+ int PluginID;
+};
+
+static CPROPIDToName kPROPIDToName[] =
+{
+ { kpidName, NMessageID::kName },
+ { kpidExtension, NMessageID::kExtension },
+ { kpidIsFolder, NMessageID::kIsFolder },
+ { kpidSize, NMessageID::kSize },
+ { kpidPackedSize, NMessageID::kPackedSize },
+ { kpidAttributes, NMessageID::kAttributes },
+ { kpidCreationTime, NMessageID::kCreationTime },
+ { kpidLastAccessTime, NMessageID::kLastAccessTime },
+ { kpidLastWriteTime, NMessageID::kLastWriteTime },
+ { kpidSolid, NMessageID::kSolid },
+ { kpidCommented, NMessageID::kCommented },
+ { kpidEncrypted, NMessageID::kEncrypted },
+ { kpidSplitBefore, NMessageID::kSplitBefore },
+ { kpidSplitAfter, NMessageID::kSplitAfter },
+ { kpidDictionarySize, NMessageID::kDictionarySize },
+ { kpidCRC, NMessageID::kCRC },
+ { kpidType, NMessageID::kType },
+ { kpidIsAnti, NMessageID::kAnti },
+ { kpidMethod, NMessageID::kMethod },
+ { kpidHostOS, NMessageID::kHostOS },
+ { kpidFileSystem, NMessageID::kFileSystem },
+ { kpidUser, NMessageID::kUser },
+ { kpidGroup, NMessageID::kGroup },
+ { kpidBlock, NMessageID::kBlock },
+ { kpidComment, NMessageID::kComment },
+ { kpidPosition, NMessageID::kPosition }
+
+};
+
+static const int kNumPROPIDToName = sizeof(kPROPIDToName) / sizeof(kPROPIDToName[0]);
+
+static int FindPropertyToName(PROPID propID)
+{
+ for(int i = 0; i < kNumPROPIDToName; i++)
+ if(kPROPIDToName[i].PropID == propID)
+ return i;
+ return -1;
+}
+
+/*
+struct CPropertyIDInfo
+{
+ PROPID PropID;
+ const char *FarID;
+ int Width;
+ // char CharID;
+};
+
+static CPropertyIDInfo kPropertyIDInfos[] =
+{
+ { kpidName, "N", 0},
+ { kpidSize, "S", 8},
+ { kpidPackedSize, "P", 8},
+ { kpidAttributes, "A", 0},
+ { kpidCreationTime, "DC", 14},
+ { kpidLastAccessTime, "DA", 14},
+ { kpidLastWriteTime, "DM", 14},
+
+ { kpidSolid, NULL, 0, 'S'},
+ { kpidEncrypted, NULL, 0, 'P'}
+
+ { kpidDictionarySize, IDS_PROPERTY_DICTIONARY_SIZE },
+ { kpidSplitBefore, NULL, 'B'},
+ { kpidSplitAfter, NULL, 'A'},
+ { kpidComment, , NULL, 'C'},
+ { kpidCRC, IDS_PROPERTY_CRC }
+ // { kpidType, L"Type" }
+};
+
+static const int kNumPropertyIDInfos = sizeof(kPropertyIDInfos) /
+ sizeof(kPropertyIDInfos[0]);
+
+static int FindPropertyInfo(PROPID propID)
+{
+ for(int i = 0; i < kNumPropertyIDInfos; i++)
+ if(kPropertyIDInfos[i].PropID == propID)
+ return i;
+ return -1;
+}
+*/
+
+// char *g_Titles[] = { "a", "f", "v" };
+static void SmartAddToString(AString &aDestString, const char *aSrcString)
+{
+ if (!aDestString.IsEmpty())
+ aDestString += ',';
+ aDestString += aSrcString;
+}
+
+/*
+void CPlugin::AddColumn(PROPID propID)
+{
+ int index = FindPropertyInfo(propID);
+ if (index >= 0)
+ {
+ for(int i = 0; i < m_ProxyHandler->m_InternalProperties.Size(); i++)
+ {
+ const CArchiveItemProperty &aHandlerProperty = m_ProxyHandler->m_InternalProperties[i];
+ if (aHandlerProperty.ID == propID)
+ break;
+ }
+ if (i == m_ProxyHandler->m_InternalProperties.Size())
+ return;
+
+ const CPropertyIDInfo &aPropertyIDInfo = kPropertyIDInfos[index];
+ SmartAddToString(PanelModeColumnTypes, aPropertyIDInfo.FarID);
+ char aTmp[32];
+ itoa(aPropertyIDInfo.Width, aTmp, 10);
+ SmartAddToString(PanelModeColumnWidths, aTmp);
+ return;
+ }
+}
+*/
+
+void CPlugin::GetOpenPluginInfo(struct OpenPluginInfo *info)
+{
+ info->StructSize = sizeof(*info);
+ info->Flags = OPIF_USEFILTER | OPIF_USESORTGROUPS| OPIF_USEHIGHLIGHTING|
+ OPIF_ADDDOTS | OPIF_COMPAREFATTIME;
+
+ UINT codePage = ::AreFileApisANSI() ? CP_ACP : CP_OEMCP;
+
+ strcpy(m_FileNameBuffer, UnicodeStringToMultiByte(m_FileName, codePage));
+ info->HostFile = m_FileNameBuffer; // test it it is not static
+
+ strcpy(m_CurrentDirBuffer, UnicodeStringToMultiByte(m_CurrentDir, CP_OEMCP));
+ info->CurDir = m_CurrentDirBuffer;
+
+ info->Format = kPluginFormatName;
+
+ UString name;
+ {
+ UString fullName;
+ int index;
+ NFile::NDirectory::MyGetFullPathName(m_FileName, fullName, index);
+ name = fullName.Mid(index);
+ }
+
+ m_PannelTitle =
+ UString(L' ') +
+ _archiveTypeName +
+ UString(L':') +
+ name +
+ UString(L' ');
+ if(!m_CurrentDir.IsEmpty())
+ {
+ // m_PannelTitle += '\\';
+ m_PannelTitle += m_CurrentDir;
+ }
+
+ strcpy(m_PannelTitleBuffer, UnicodeStringToMultiByte(m_PannelTitle, CP_OEMCP));
+ info->PanelTitle = m_PannelTitleBuffer;
+
+ memset(m_InfoLines,0,sizeof(m_InfoLines));
+ strcpy(m_InfoLines[0].Text,"");
+ m_InfoLines[0].Separator = TRUE;
+
+ strcpy(m_InfoLines[1].Text, g_StartupInfo.GetMsgString(NMessageID::kArchiveType));
+ strcpy(m_InfoLines[1].Data, UnicodeStringToMultiByte(_archiveTypeName, CP_OEMCP));
+
+ int numItems = 2;
+ UINT32 numProps;
+ if (m_ArchiveHandler->GetNumberOfArchiveProperties(&numProps) == S_OK)
+ {
+ for (UINT32 i = 0; i < numProps && numItems < 30; i++)
+ {
+ CMyComBSTR name;
+ PROPID propID;
+ VARTYPE vt;
+ if (m_ArchiveHandler->GetArchivePropertyInfo(i, &name, &propID, &vt) != S_OK)
+ continue;
+
+ InfoPanelLine &item = m_InfoLines[numItems];
+ int index = FindPropertyToName(propID);
+ if (index < 0)
+ {
+ if (name != 0)
+ strcpy(item.Text, UnicodeStringToMultiByte(
+ (const wchar_t *)name, CP_OEMCP));
+ else
+ strcpy(item.Text, "");
+ }
+ else
+ strcpy(item.Text, g_StartupInfo.GetMsgString(kPROPIDToName[index].PluginID));
+
+ NCOM::CPropVariant propVariant;
+ if (m_ArchiveHandler->GetArchiveProperty(propID, &propVariant) != S_OK)
+ continue;
+ CSysString s = ConvertPropertyToString2(propVariant, propID);
+ strcpy(item.Data, s);
+ numItems++;
+ }
+ }
+
+ //m_InfoLines[1].Separator = 0;
+
+ info->InfoLines = m_InfoLines;
+ info->InfoLinesNumber = numItems;
+
+
+ info->DescrFiles = NULL;
+ info->DescrFilesNumber = 0;
+
+ PanelModeColumnTypes.Empty();
+ PanelModeColumnWidths.Empty();
+
+ /*
+ AddColumn(kpidName);
+ AddColumn(kpidSize);
+ AddColumn(kpidPackedSize);
+ AddColumn(kpidLastWriteTime);
+ AddColumn(kpidCreationTime);
+ AddColumn(kpidLastAccessTime);
+ AddColumn(kpidAttributes);
+
+ PanelMode.ColumnTypes = (char *)(const char *)PanelModeColumnTypes;
+ PanelMode.ColumnWidths = (char *)(const char *)PanelModeColumnWidths;
+ PanelMode.ColumnTitles = NULL;
+ PanelMode.FullScreen = TRUE;
+ PanelMode.DetailedStatus = FALSE;
+ PanelMode.AlignExtensions = FALSE;
+ PanelMode.CaseConversion = FALSE;
+ PanelMode.StatusColumnTypes = "N";
+ PanelMode.StatusColumnWidths = "0";
+ PanelMode.Reserved[0] = 0;
+ PanelMode.Reserved[1] = 0;
+
+ info->PanelModesArray = &PanelMode;
+ info->PanelModesNumber = 1;
+ */
+
+ info->PanelModesArray = NULL;
+ info->PanelModesNumber = 0;
+
+ info->StartPanelMode = 0;
+ info->StartSortMode = 0;
+ info->KeyBar = NULL;
+ info->ShortcutData = NULL;
+}
+
+struct CArchiveItemProperty
+{
+ AString Name;
+ PROPID ID;
+ VARTYPE Type;
+};
+
+HRESULT CPlugin::ShowAttributesWindow()
+{
+ PluginPanelItem pluginPanelItem;
+ if (!g_StartupInfo.ControlGetActivePanelCurrentItemInfo(pluginPanelItem))
+ return S_FALSE;
+ if (strcmp(pluginPanelItem.FindData.cFileName, "..") == 0 &&
+ NFile::NFind::NAttributes::IsDirectory(pluginPanelItem.FindData.dwFileAttributes))
+ return S_FALSE;
+ int itemIndex = pluginPanelItem.UserData;
+
+ CObjectVector<CArchiveItemProperty> properties;
+ UINT32 numProps;
+ RINOK(m_ArchiveHandler->GetNumberOfProperties(&numProps));
+ int i;
+ for (i = 0; i < (int)numProps; i++)
+ {
+ CMyComBSTR name;
+ PROPID propID;
+ VARTYPE vt;
+ RINOK(m_ArchiveHandler->GetPropertyInfo(i, &name, &propID, &vt));
+ CArchiveItemProperty destProperty;
+ destProperty.Type = vt;
+ destProperty.ID = propID;
+ if (destProperty.ID == kpidPath)
+ destProperty.ID = kpidName;
+ AString propName;
+ {
+ if (name != NULL)
+ destProperty.Name = UnicodeStringToMultiByte(
+ (const wchar_t *)name, CP_OEMCP);
+ else
+ destProperty.Name = "Error";
+ }
+ properties.Add(destProperty);
+ }
+
+ /*
+ LPCITEMIDLIST aProperties;
+ if (index < m_FolderItem->m_DirSubItems.Size())
+ {
+ const CArchiveFolderItem &anItem = m_FolderItem->m_DirSubItems[index];
+ aProperties = anItem.m_Properties;
+ }
+ else
+ {
+ const CArchiveFolderFileItem &anItem =
+ m_FolderItem->m_FileSubItems[index - m_FolderItem->m_DirSubItems.Size()];
+ aProperties = anItem.m_Properties;
+ }
+ */
+
+ const int kPathIndex = 2;
+ const int kOkButtonIndex = 4;
+ int size = 2;
+ CRecordVector<CInitDialogItem> initDialogItems;
+
+ int xSize = 70;
+ CInitDialogItem initDialogItem =
+ { DI_DOUBLEBOX, 3, 1, xSize - 4, size - 2, false, false, 0, false, NMessageID::kProperties, NULL, NULL };
+ initDialogItems.Add(initDialogItem);
+ AStringVector aValues;
+
+ for (i = 0; i < properties.Size(); i++)
+ {
+ const CArchiveItemProperty &property = properties[i];
+
+ CInitDialogItem initDialogItem =
+ { DI_TEXT, 5, 3 + i, 0, 0, false, false, 0, false, 0, NULL, NULL };
+ int index = FindPropertyToName(property.ID);
+ if (index < 0)
+ {
+ initDialogItem.DataMessageId = -1;
+ initDialogItem.DataString = property.Name;
+ }
+ else
+ initDialogItem.DataMessageId = kPROPIDToName[index].PluginID;
+ initDialogItems.Add(initDialogItem);
+
+ NCOM::CPropVariant propVariant;
+ RINOK(_folder->GetProperty(itemIndex,
+ property.ID, &propVariant));
+ CSysString aString = ConvertPropertyToString2(propVariant, property.ID);
+ aValues.Add(aString);
+
+ {
+ CInitDialogItem initDialogItem =
+ { DI_TEXT, 30, 3 + i, 0, 0, false, false, 0, false, -1, NULL, NULL };
+ initDialogItems.Add(initDialogItem);
+ }
+ }
+
+ int numLines = aValues.Size();
+ for(i = 0; i < numLines; i++)
+ {
+ CInitDialogItem &initDialogItem = initDialogItems[1 + i * 2 + 1];
+ initDialogItem.DataString = aValues[i];
+ }
+
+ int numDialogItems = initDialogItems.Size();
+
+ CRecordVector<FarDialogItem> dialogItems;
+ dialogItems.Reserve(numDialogItems);
+ for(i = 0; i < numDialogItems; i++)
+ dialogItems.Add(FarDialogItem());
+ g_StartupInfo.InitDialogItems(&initDialogItems.Front(),
+ &dialogItems.Front(), numDialogItems);
+
+ int maxLen = 0;
+ for (i = 0; i < numLines; i++)
+ {
+ FarDialogItem &dialogItem = dialogItems[1 + i * 2];
+ int len = strlen(dialogItem.Data);
+ if (len > maxLen)
+ maxLen = len;
+ }
+ int maxLen2 = 0;
+ const int kSpace = 10;
+ for (i = 0; i < numLines; i++)
+ {
+ FarDialogItem &dialogItem = dialogItems[1 + i * 2 + 1];
+ int len = strlen(dialogItem.Data);
+ if (len > maxLen2)
+ maxLen2 = len;
+ dialogItem.X1 = maxLen + kSpace;
+ }
+ size = numLines + 6;
+ xSize = maxLen + kSpace + maxLen2 + 5;
+ FarDialogItem &aFirstDialogItem = dialogItems.Front();
+ aFirstDialogItem.Y2 = size - 2;
+ aFirstDialogItem.X2 = xSize - 4;
+
+ int askCode = g_StartupInfo.ShowDialog(xSize, size, NULL, &dialogItems.Front(), numDialogItems);
+ return S_OK;
+}
+
+int CPlugin::ProcessKey(int aKey, unsigned int controlState)
+{
+ if (controlState == PKF_CONTROL && aKey == 'A')
+ {
+ HRESULT result = ShowAttributesWindow();
+ if (result == S_OK)
+ return TRUE;
+ if (result == S_FALSE)
+ return FALSE;
+ throw "Error";
+ }
+ if ((controlState & PKF_ALT) != 0 && aKey == VK_F6)
+ {
+ UString folderPath;
+ if (!NFile::NDirectory::GetOnlyDirPrefix(m_FileName, folderPath))
+ return FALSE;
+ PanelInfo panelInfo;
+ g_StartupInfo.ControlGetActivePanelInfo(panelInfo);
+ GetFilesReal(panelInfo.SelectedItems,
+ panelInfo.SelectedItemsNumber, FALSE,
+ UnicodeStringToMultiByte(folderPath, CP_OEMCP), OPM_SILENT, true);
+ g_StartupInfo.Control(this, FCTL_UPDATEPANEL, NULL);
+ g_StartupInfo.Control(this, FCTL_REDRAWPANEL, NULL);
+ g_StartupInfo.Control(this, FCTL_UPDATEANOTHERPANEL, NULL);
+ g_StartupInfo.Control(this, FCTL_REDRAWANOTHERPANEL, NULL);
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/CPP/7zip/UI/Far/Plugin.h b/CPP/7zip/UI/Far/Plugin.h
new file mode 100755
index 00000000..0b617cfb
--- /dev/null
+++ b/CPP/7zip/UI/Far/Plugin.h
@@ -0,0 +1,99 @@
+// 7zip/Far/Plugin.h
+
+#ifndef __7ZIP_FAR_PLUGIN_H
+#define __7ZIP_FAR_PLUGIN_H
+
+#include "Common/MyCom.h"
+
+#include "Windows/COM.h"
+#include "Windows/FileFind.h"
+#include "Windows/PropVariant.h"
+
+#include "../Common/ArchiverInfo.h"
+#include "../Agent/IFolderArchive.h"
+
+#include "FarUtils.h"
+
+class CPlugin
+{
+ NWindows::NCOM::CComInitializer m_ComInitializer;
+ UString m_CurrentDir;
+
+ UString m_PannelTitle;
+
+ InfoPanelLine m_InfoLines[30]; // Change it;
+
+ char m_FileNameBuffer[1024];
+ char m_CurrentDirBuffer[1024];
+ char m_PannelTitleBuffer[1024];
+
+ AString PanelModeColumnTypes;
+ AString PanelModeColumnWidths;
+ PanelMode PanelMode;
+ void AddColumn(PROPID aPropID);
+
+
+ void EnterToDirectory(const UString &aDirName);
+
+ void GetPathParts(UStringVector &aPathParts);
+ void GetCurrentDir();
+public:
+ UString m_FileName;
+ // UString m_DefaultName;
+ NWindows::NFile::NFind::CFileInfoW m_FileInfo;
+
+ CMyComPtr<IInFolderArchive> m_ArchiveHandler;
+ CMyComPtr<IFolderFolder> _folder;
+
+ // CArchiverInfo m_ArchiverInfo;
+ UString _archiveTypeName;
+
+ bool PasswordIsDefined;
+ UString Password;
+
+
+ CPlugin(const UString &fileName,
+ // const UString &aDefaultName,
+ IInFolderArchive *archiveHandler,
+ UString archiveTypeName
+ );
+ ~CPlugin();
+
+ void ReadValueSafe(PROPID aPropID, NWindows::NCOM::CPropVariant aPropVariant);
+ void ReadPluginPanelItem(PluginPanelItem &aPanelItem, UINT32 anItemIndex);
+
+ int GetFindData(PluginPanelItem **pPanelItem,int *pItemsNumber,int OpMode);
+ void FreeFindData(PluginPanelItem *PanelItem,int ItemsNumber);
+ int SetDirectory(const char *aDir, int opMode);
+ void GetOpenPluginInfo(struct OpenPluginInfo *anInfo);
+
+ int DeleteFiles(PluginPanelItem *aPanelItems, int itemsNumber, int opMode);
+
+
+ HRESULT ExtractFiles(
+ bool decompressAllItems,
+ const UINT32 *indices,
+ UINT32 numIndices,
+ bool silent,
+ NExtract::NPathMode::EEnum pathMode,
+ NExtract::NOverwriteMode::EEnum overwriteMode,
+ const UString &destPath,
+ bool passwordIsDefined, const UString &password);
+
+ NFar::NFileOperationReturnCode::EEnum GetFiles(struct PluginPanelItem *aPanelItem, int itemsNumber,
+ int move, char *destPath, int opMode);
+
+ NFar::NFileOperationReturnCode::EEnum GetFilesReal(struct PluginPanelItem *aPanelItems,
+ int itemsNumber, int move, const char *_aDestPath, int opMode, bool aShowBox);
+
+ NFar::NFileOperationReturnCode::EEnum PutFiles(struct PluginPanelItem *aPanelItems, int itemsNumber,
+ int move, int opMode);
+
+ HRESULT ShowAttributesWindow();
+
+ int ProcessKey(int aKey, unsigned int aControlState);
+};
+
+HRESULT CompressFiles(const CObjectVector<PluginPanelItem> &aPluginPanelItems);
+
+#endif
diff --git a/CPP/7zip/UI/Far/PluginCommon.cpp b/CPP/7zip/UI/Far/PluginCommon.cpp
new file mode 100755
index 00000000..3e8e3cee
--- /dev/null
+++ b/CPP/7zip/UI/Far/PluginCommon.cpp
@@ -0,0 +1,50 @@
+// SevenZip/Plugin.cpp
+
+#include "StdAfx.h"
+
+#include "Plugin.h"
+
+/*
+void CPlugin::AddRealIndexOfFile(const CArchiveFolderItem &aFolder,
+ int anIndexInVector, vector<int> &aRealIndexes)
+{
+ const CArchiveFolderFileItem &anItem = aFolder.m_FileSubItems[anIndexInVector];
+ int aHandlerItemIndex = m_ProxyHandler->GetHandlerItemIndex(anItem.m_Properties);
+ if(aHandlerItemIndex < 0)
+ throw "error";
+ aRealIndexes.push_back(aHandlerItemIndex);
+}
+
+void CPlugin::AddRealIndexes(const CArchiveFolderItem &anItem,
+ vector<int> &aRealIndexes)
+{
+ int aHandlerItemIndex = m_ProxyHandler->GetHandlerItemIndex(anItem.m_Properties);
+ if(aHandlerItemIndex >= 0) // test -1 value
+ aRealIndexes.push_back(aHandlerItemIndex);
+ for(int i = 0; i < anItem.m_DirSubItems.Size(); i++)
+ AddRealIndexes(anItem.m_DirSubItems[i], aRealIndexes);
+ for(i = 0; i < anItem.m_FileSubItems.Size(); i++)
+ AddRealIndexOfFile(anItem, i , aRealIndexes);
+}
+
+
+void CPlugin::GetRealIndexes(PluginPanelItem *aPanelItems, int anItemsNumber,
+ vector<int> &aRealIndexes)
+{
+ aRealIndexes.clear();
+ for(int i = 0; i < anItemsNumber; i++)
+ {
+ int anIndex = aPanelItems[i].UserData;
+ if (anIndex < m_FolderItem->m_DirSubItems.Size())
+ {
+ const CArchiveFolderItem &anItem = m_FolderItem->m_DirSubItems[anIndex];
+ AddRealIndexes(anItem, aRealIndexes);
+ }
+ else
+ AddRealIndexOfFile(*m_FolderItem, anIndex - m_FolderItem->m_DirSubItems.Size(),
+ aRealIndexes);
+ }
+ sort(aRealIndexes.begin(), aRealIndexes.end());
+}
+
+*/
diff --git a/CPP/7zip/UI/Far/PluginDelete.cpp b/CPP/7zip/UI/Far/PluginDelete.cpp
new file mode 100755
index 00000000..6a969c15
--- /dev/null
+++ b/CPP/7zip/UI/Far/PluginDelete.cpp
@@ -0,0 +1,169 @@
+// PluginDelete.cpp
+
+#include "StdAfx.h"
+
+#include <stdio.h>
+
+#include "Plugin.h"
+#include "Messages.h"
+#include "UpdateCallback100.h"
+
+#include "Windows/FileDir.h"
+
+#include "../../Common/FileStreams.h"
+
+#include "Common/StringConvert.h"
+
+#include "../Common/ZipRegistry.h"
+#include "../Common/WorkDir.h"
+
+using namespace NFar;
+using namespace NWindows;
+using namespace NFile;
+using namespace NDirectory;
+
+static LPCWSTR kTempArchivePrefix = L"7zA";
+
+int CPlugin::DeleteFiles(PluginPanelItem *panelItems, int numItems,
+ int opMode)
+{
+ if (numItems == 0)
+ return FALSE;
+ /*
+ if (!m_ArchiverInfo.UpdateEnabled)
+ {
+ g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive);
+ return FALSE;
+ }
+ */
+ if ((opMode & OPM_SILENT) == 0)
+ {
+ const char *msgItems[]=
+ {
+ g_StartupInfo.GetMsgString(NMessageID::kDeleteTitle),
+ g_StartupInfo.GetMsgString(NMessageID::kDeleteFiles),
+ g_StartupInfo.GetMsgString(NMessageID::kDeleteDelete),
+ g_StartupInfo.GetMsgString(NMessageID::kDeleteCancel)
+ };
+ char msg[1024];
+ if (numItems == 1)
+ {
+ sprintf(msg, g_StartupInfo.GetMsgString(NMessageID::kDeleteFile),
+ panelItems[0].FindData.cFileName);
+ msgItems[1] = msg;
+ }
+ else if (numItems > 1)
+ {
+ sprintf(msg, g_StartupInfo.GetMsgString(NMessageID::kDeleteNumberOfFiles),
+ numItems);
+ msgItems[1] = msg;
+ }
+ if (g_StartupInfo.ShowMessage(FMSG_WARNING, NULL, msgItems,
+ sizeof(msgItems) / sizeof(msgItems[0]), 2) != 0)
+ return (FALSE);
+ }
+
+ CScreenRestorer screenRestorer;
+ CProgressBox progressBox;
+ CProgressBox *progressBoxPointer = NULL;
+ if ((opMode & OPM_SILENT) == 0 && (opMode & OPM_FIND ) == 0)
+ {
+ screenRestorer.Save();
+
+ progressBoxPointer = &progressBox;
+ progressBox.Init(g_StartupInfo.GetMsgString(NMessageID::kWaitTitle),
+ g_StartupInfo.GetMsgString(NMessageID::kDeleting), 1 << 17);
+ }
+
+ NWorkDir::CInfo workDirInfo;
+ ReadWorkDirInfo(workDirInfo);
+
+ UString workDir = GetWorkDir(workDirInfo, m_FileName);
+ CreateComplexDirectory(workDir);
+
+ CTempFileW tempFile;
+ UString tempFileName;
+ if (tempFile.Create(workDir, kTempArchivePrefix, tempFileName) == 0)
+ return FALSE;
+
+
+ CRecordVector<UINT32> indices;
+ indices.Reserve(numItems);
+ for(int i = 0; i < numItems; i++)
+ indices.Add(panelItems[i].UserData);
+
+ ////////////////////////////
+ // Save _folder;
+
+ UStringVector pathVector;
+ GetPathParts(pathVector);
+
+ CMyComPtr<IOutFolderArchive> outArchive;
+ HRESULT result = m_ArchiveHandler.QueryInterface(
+ IID_IOutFolderArchive, &outArchive);
+ if(result != S_OK)
+ {
+ g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive);
+ return FALSE;
+ }
+ outArchive->SetFolder(_folder);
+
+ CUpdateCallback100Imp *updateCallbackSpec = new CUpdateCallback100Imp;
+ CMyComPtr<IFolderArchiveUpdateCallback> updateCallback(updateCallbackSpec );
+
+ updateCallbackSpec->Init(m_ArchiveHandler, &progressBox);
+
+
+ result = outArchive->DeleteItems(
+ tempFileName,
+ &indices.Front(), indices.Size(),
+ updateCallback);
+ updateCallback.Release();
+ outArchive.Release();
+
+ if (result != S_OK)
+ {
+ ShowErrorMessage(result);
+ return FALSE;
+ }
+
+ _folder.Release();
+ m_ArchiveHandler->Close();
+
+ if (!DeleteFileAlways(m_FileName))
+ {
+ ShowLastErrorMessage();
+ return FALSE;
+ }
+
+ tempFile.DisableDeleting();
+ if (!MyMoveFile(tempFileName, m_FileName))
+ {
+ ShowLastErrorMessage();
+ return FALSE;
+ }
+
+ result = m_ArchiveHandler->ReOpen(NULL);
+ if (result != S_OK)
+ {
+ ShowErrorMessage(result);
+ return FALSE;
+ }
+
+
+ ////////////////////////////
+ // Restore _folder;
+
+ m_ArchiveHandler->BindToRootFolder(&_folder);
+ for (i = 0; i < pathVector.Size(); i++)
+ {
+ CMyComPtr<IFolderFolder> newFolder;
+ _folder->BindToFolder(pathVector[i], &newFolder);
+ if(!newFolder )
+ break;
+ _folder = newFolder;
+ }
+ GetCurrentDir();
+
+ return(TRUE);
+}
diff --git a/CPP/7zip/UI/Far/PluginRead.cpp b/CPP/7zip/UI/Far/PluginRead.cpp
new file mode 100755
index 00000000..503ff639
--- /dev/null
+++ b/CPP/7zip/UI/Far/PluginRead.cpp
@@ -0,0 +1,278 @@
+// PluginRead.cpp
+
+#include "StdAfx.h"
+
+#include "Plugin.h"
+
+#include "Messages.h"
+
+#include "Common/StringConvert.h"
+
+#include "Windows/FileName.h"
+#include "Windows/FileFind.h"
+#include "Windows/FileDir.h"
+#include "Windows/Defs.h"
+
+#include "../Common/ZipRegistry.h"
+
+#include "ExtractEngine.h"
+
+using namespace NFar;
+using namespace NWindows;
+
+static const char *kHelpTopicExtrFromSevenZip = "Extract";
+
+static const char kDirDelimiter = '\\';
+
+static const char *kExractPathHistoryName = "7-ZipExtractPath";
+
+HRESULT CPlugin::ExtractFiles(
+ bool decompressAllItems,
+ const UINT32 *indices,
+ UINT32 numIndices,
+ bool silent,
+ NExtract::NPathMode::EEnum pathMode,
+ NExtract::NOverwriteMode::EEnum overwriteMode,
+ const UString &destPath,
+ bool passwordIsDefined, const UString &password)
+{
+ CScreenRestorer screenRestorer;
+ CProgressBox progressBox;
+ CProgressBox *progressBoxPointer = NULL;
+ if (!silent)
+ {
+ screenRestorer.Save();
+
+ progressBoxPointer = &progressBox;
+ progressBox.Init(g_StartupInfo.GetMsgString(NMessageID::kWaitTitle),
+ g_StartupInfo.GetMsgString(NMessageID::kExtracting), 1 << 17);
+ }
+
+
+ CExtractCallBackImp *extractCallbackSpec = new CExtractCallBackImp;
+ CMyComPtr<IFolderArchiveExtractCallback> extractCallback(extractCallbackSpec);
+
+ extractCallbackSpec->Init(
+ CP_OEMCP,
+ progressBoxPointer,
+ /*
+ GetDefaultName(m_FileName, m_ArchiverInfo.Extension),
+ m_FileInfo.LastWriteTime, m_FileInfo.Attributes,
+ */
+ passwordIsDefined, password);
+
+ if (decompressAllItems)
+ return m_ArchiveHandler->Extract(pathMode, overwriteMode,
+ destPath, BoolToInt(false), extractCallback);
+ else
+ {
+ CMyComPtr<IArchiveFolder> archiveFolder;
+ _folder.QueryInterface(IID_IArchiveFolder, &archiveFolder);
+
+ return archiveFolder->Extract(indices, numIndices, pathMode, overwriteMode,
+ destPath, BoolToInt(false), extractCallback);
+ }
+}
+
+NFileOperationReturnCode::EEnum CPlugin::GetFiles(struct PluginPanelItem *panelItems,
+ int itemsNumber, int move, char *_aDestPath, int opMode)
+{
+ return GetFilesReal(panelItems, itemsNumber, move,
+ _aDestPath, opMode, (opMode & OPM_SILENT) == 0);
+}
+
+NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *panelItems,
+ int itemsNumber, int move, const char *_aDestPath, int opMode, bool showBox)
+{
+ if(move != 0)
+ {
+ g_StartupInfo.ShowMessage(NMessageID::kMoveIsNotSupported);
+ return NFileOperationReturnCode::kError;
+ }
+
+ CSysString destPath = _aDestPath;
+ NFile::NName::NormalizeDirPathPrefix(destPath);
+
+ bool extractSelectedFiles = true;
+
+ NExtract::CInfo extractionInfo;
+ extractionInfo.PathMode = NExtract::NPathMode::kCurrentPathnames;
+ extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt;
+
+ bool silent = (opMode & OPM_SILENT) != 0;
+ bool decompressAllItems = false;
+ UString password = Password;
+ bool passwordIsDefined = PasswordIsDefined;
+
+ if (!silent)
+ {
+ const int kPathIndex = 2;
+
+ ReadExtractionInfo(extractionInfo);
+
+ const int kPathModeRadioIndex = 4;
+ const int kOverwriteModeRadioIndex = kPathModeRadioIndex + 4;
+ const int kNumOverwriteOptions = 6;
+ const int kFilesModeIndex = kOverwriteModeRadioIndex + kNumOverwriteOptions;
+ const int kXSize = 76;
+ const int kYSize = 19;
+ const int kPasswordYPos = 12;
+
+ const int kXMid = kXSize / 2;
+
+ AString oemPassword = UnicodeStringToMultiByte(password, CP_OEMCP);
+
+ struct CInitDialogItem initItems[]={
+ { DI_DOUBLEBOX, 3, 1, kXSize - 4, kYSize - 2, false, false, 0, false, NMessageID::kExtractTitle, NULL, NULL },
+ { DI_TEXT, 5, 2, 0, 0, false, false, 0, false, NMessageID::kExtractTo, NULL, NULL },
+
+ { DI_EDIT, 5, 3, kXSize - 6, 3, true, false, DIF_HISTORY, false, -1, destPath, kExractPathHistoryName},
+ // { DI_EDIT, 5, 3, kXSize - 6, 3, true, false, 0, false, -1, destPath, NULL},
+
+ { DI_SINGLEBOX, 4, 5, kXMid - 2, 5 + 4, false, false, 0, false, NMessageID::kExtractPathMode, NULL, NULL },
+ { DI_RADIOBUTTON, 6, 6, 0, 0, false,
+ extractionInfo.PathMode == NExtract::NPathMode::kFullPathnames,
+ DIF_GROUP, false, NMessageID::kExtractPathFull, NULL, NULL },
+ { DI_RADIOBUTTON, 6, 7, 0, 0, false,
+ extractionInfo.PathMode == NExtract::NPathMode::kCurrentPathnames,
+ 0, false, NMessageID::kExtractPathCurrent, NULL, NULL },
+ { DI_RADIOBUTTON, 6, 8, 0, 0, false,
+ extractionInfo.PathMode == NExtract::NPathMode::kNoPathnames,
+ false, 0, NMessageID::kExtractPathNo, NULL, NULL },
+
+ { DI_SINGLEBOX, kXMid, 5, kXSize - 6, 5 + kNumOverwriteOptions, false, false, 0, false, NMessageID::kExtractOwerwriteMode, NULL, NULL },
+ { DI_RADIOBUTTON, kXMid + 2, 6, 0, 0, false,
+ extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kAskBefore,
+ DIF_GROUP, false, NMessageID::kExtractOwerwriteAsk, NULL, NULL },
+ { DI_RADIOBUTTON, kXMid + 2, 7, 0, 0, false,
+ extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kWithoutPrompt,
+ 0, false, NMessageID::kExtractOwerwritePrompt, NULL, NULL },
+ { DI_RADIOBUTTON, kXMid + 2, 8, 0, 0, false,
+ extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kSkipExisting,
+ 0, false, NMessageID::kExtractOwerwriteSkip, NULL, NULL },
+ { 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, kPasswordYPos, kXSize - 6, kPasswordYPos + 2, false, false, 0, false, NMessageID::kExtractPassword, NULL, NULL },
+ { DI_PSWEDIT, kXMid + 2, kPasswordYPos + 1, kXSize - 8, 12, false, false, 0, false, -1, oemPassword, NULL},
+
+ { DI_TEXT, 3, kYSize - 4, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL },
+
+
+ { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, true, NMessageID::kExtractExtract, NULL, NULL },
+ { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kExtractCancel, NULL, NULL }
+ };
+
+ const int kNumDialogItems = sizeof(initItems) / sizeof(initItems[0]);
+ const int kOkButtonIndex = kNumDialogItems - 2;
+ const int kPasswordIndex = kNumDialogItems - 4;
+
+ FarDialogItem dialogItems[kNumDialogItems];
+ g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems);
+ for (;;)
+ {
+ int askCode = g_StartupInfo.ShowDialog(kXSize, kYSize,
+ kHelpTopicExtrFromSevenZip, dialogItems, kNumDialogItems);
+ if (askCode != kOkButtonIndex)
+ return NFileOperationReturnCode::kInterruptedByUser;
+ destPath = dialogItems[kPathIndex].Data;
+ destPath.Trim();
+ if (destPath.IsEmpty())
+ {
+ if(!NFile::NDirectory::MyGetCurrentDirectory(destPath))
+ throw 318016;
+ NFile::NName::NormalizeDirPathPrefix(destPath);
+ break;
+ }
+ else
+ {
+ if(destPath[destPath.Length() - 1] == kDirDelimiter)
+ break;
+ }
+ g_StartupInfo.ShowMessage("You must specify directory path");
+ }
+
+ if (dialogItems[kPathModeRadioIndex].Selected)
+ extractionInfo.PathMode = NExtract::NPathMode::kFullPathnames;
+ else if (dialogItems[kPathModeRadioIndex + 1].Selected)
+ extractionInfo.PathMode = NExtract::NPathMode::kCurrentPathnames;
+ else if (dialogItems[kPathModeRadioIndex + 2].Selected)
+ extractionInfo.PathMode = NExtract::NPathMode::kNoPathnames;
+ else
+ throw 31806;
+
+ if (dialogItems[kOverwriteModeRadioIndex].Selected)
+ extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kAskBefore;
+ else if (dialogItems[kOverwriteModeRadioIndex + 1].Selected)
+ extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt;
+ else if (dialogItems[kOverwriteModeRadioIndex + 2].Selected)
+ 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;
+
+ if (dialogItems[kFilesModeIndex].Selected)
+ decompressAllItems = false;
+ else if (dialogItems[kFilesModeIndex + 1].Selected)
+ decompressAllItems = true;
+ else
+ throw 31806;
+
+ SaveExtractionInfo(extractionInfo);
+
+ if (dialogItems[kFilesModeIndex].Selected)
+ extractSelectedFiles = true;
+ else if (dialogItems[kFilesModeIndex + 1].Selected)
+ extractSelectedFiles = false;
+ else
+ throw 31806;
+
+ oemPassword = dialogItems[kPasswordIndex].Data;
+ password = MultiByteToUnicodeString(oemPassword, CP_OEMCP);
+ passwordIsDefined = !password.IsEmpty();
+ }
+
+ NFile::NDirectory::CreateComplexDirectory(destPath);
+
+ /*
+ vector<int> realIndices;
+ if (!decompressAllItems)
+ GetRealIndexes(panelItems, itemsNumber, realIndices);
+ */
+ CRecordVector<UINT32> indices;
+ indices.Reserve(itemsNumber);
+ for (int i = 0; i < itemsNumber; i++)
+ indices.Add(panelItems[i].UserData);
+
+ HRESULT result = ExtractFiles(decompressAllItems, &indices.Front(), itemsNumber,
+ !showBox, extractionInfo.PathMode, extractionInfo.OverwriteMode,
+ MultiByteToUnicodeString(destPath, CP_OEMCP),
+ passwordIsDefined, password);
+ // HRESULT result = ExtractFiles(decompressAllItems, realIndices, !showBox,
+ // extractionInfo, destPath, passwordIsDefined, password);
+ if (result != S_OK)
+ {
+ if (result == E_ABORT)
+ return NFileOperationReturnCode::kInterruptedByUser;
+ ShowErrorMessage(result);
+ return NFileOperationReturnCode::kError;
+ }
+
+ // if(move != 0)
+ // {
+ // if(DeleteFiles(panelItems, itemsNumber, opMode) == FALSE)
+ // return NFileOperationReturnCode::kError;
+ // }
+ return NFileOperationReturnCode::kSuccess;
+}
diff --git a/CPP/7zip/UI/Far/PluginWrite.cpp b/CPP/7zip/UI/Far/PluginWrite.cpp
new file mode 100755
index 00000000..d6730985
--- /dev/null
+++ b/CPP/7zip/UI/Far/PluginWrite.cpp
@@ -0,0 +1,696 @@
+// PluginWrite.cpp
+
+#include "StdAfx.h"
+
+#include "Plugin.h"
+
+#include "Common/StringConvert.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileName.h"
+#include "Windows/FileFind.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+
+#include "../Common/ZipRegistry.h"
+#include "../Common/WorkDir.h"
+#include "../Common/OpenArchive.h"
+
+#include "../Agent/Agent.h"
+
+#include "ProgressBox.h"
+#include "Messages.h"
+#include "UpdateCallback100.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NDirectory;
+using namespace NFar;
+
+using namespace NUpdateArchive;
+
+static const char *kHelpTopic = "Update";
+
+static LPCWSTR kTempArcivePrefix = L"7zA";
+
+static const char *kArchiveHistoryKeyName = "7-ZipArcName";
+
+static UINT32 g_MethodMap[] = { 0, 1, 3, 5, 7, 9 };
+
+static HRESULT SetOutProperties(IOutFolderArchive *outArchive, UINT32 method)
+{
+ CMyComPtr<ISetProperties> setProperties;
+ if (outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties) == S_OK)
+ {
+ UStringVector realNames;
+ realNames.Add(UString(L"x"));
+ NCOM::CPropVariant value = (UInt32)method;
+ CRecordVector<const wchar_t *> names;
+ for(int i = 0; i < realNames.Size(); i++)
+ names.Add(realNames[i]);
+ RINOK(setProperties->SetProperties(&names.Front(), &value, names.Size()));
+ }
+ return S_OK;
+}
+
+NFileOperationReturnCode::EEnum CPlugin::PutFiles(
+ struct PluginPanelItem *panelItems, int numItems,
+ int moveMode, int opMode)
+{
+ if(moveMode != 0)
+ {
+ g_StartupInfo.ShowMessage(NMessageID::kMoveIsNotSupported);
+ return NFileOperationReturnCode::kError;
+ }
+ if (numItems == 0)
+ return NFileOperationReturnCode::kError;
+
+ /*
+ if (!m_ArchiverInfo.UpdateEnabled)
+ {
+ g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive);
+ return NFileOperationReturnCode::kError;
+ }
+ */
+
+ const int kYSize = 14;
+ const int kXMid = 38;
+
+ NCompression::CInfo compressionInfo;
+ ReadCompressionInfo(compressionInfo);
+
+ int methodIndex = 0;
+ for (int i = sizeof(g_MethodMap) / sizeof(g_MethodMap[0]) - 1; i >= 0; i--)
+ if (compressionInfo.Level >= g_MethodMap[i])
+ {
+ methodIndex = i;
+ break;
+ }
+
+ const int kMethodRadioIndex = 2;
+ const int kModeRadioIndex = kMethodRadioIndex + 7;
+
+ struct CInitDialogItem initItems[]={
+ { DI_DOUBLEBOX, 3, 1, 72, kYSize - 2, false, false, 0, false, NMessageID::kUpdateTitle, NULL, NULL },
+ { DI_SINGLEBOX, 4, 2, kXMid - 2, 2 + 7, false, false, 0, false, NMessageID::kUpdateMethod, NULL, NULL },
+ { DI_RADIOBUTTON, 6, 3, 0, 0, methodIndex == 0, methodIndex == 0,
+ DIF_GROUP, false, NMessageID::kUpdateMethodStore, NULL, NULL },
+ { DI_RADIOBUTTON, 6, 4, 0, 0, methodIndex == 1, methodIndex == 1,
+ 0, false, NMessageID::kUpdateMethodFastest, NULL, NULL },
+ { DI_RADIOBUTTON, 6, 5, 0, 0, methodIndex == 2, methodIndex == 2,
+ 0, false, NMessageID::kUpdateMethodFast, NULL, NULL },
+ { DI_RADIOBUTTON, 6, 6, 0, 0, methodIndex == 3, methodIndex == 3,
+ 0, false, NMessageID::kUpdateMethodNormal, NULL, NULL },
+ { DI_RADIOBUTTON, 6, 7, 0, 0, methodIndex == 4, methodIndex == 4,
+ 0, false, NMessageID::kUpdateMethodMaximum, NULL, NULL },
+ { DI_RADIOBUTTON, 6, 8, 0, 0, methodIndex == 5, methodIndex == 5,
+ 0, false, NMessageID::kUpdateMethodUltra, NULL, NULL },
+
+ { DI_SINGLEBOX, kXMid, 2, 70, 2 + 5, false, false, 0, false, NMessageID::kUpdateMode, NULL, NULL },
+ { DI_RADIOBUTTON, kXMid + 2, 3, 0, 0, false, true,
+ DIF_GROUP, false, NMessageID::kUpdateModeAdd, NULL, NULL },
+ { DI_RADIOBUTTON, kXMid + 2, 4, 0, 0, false, false,
+ 0, false, NMessageID::kUpdateModeUpdate, NULL, NULL },
+ { DI_RADIOBUTTON, kXMid + 2, 5, 0, 0, false, false,
+ 0, false, NMessageID::kUpdateModeFreshen, NULL, NULL },
+ { DI_RADIOBUTTON, kXMid + 2, 6, 0, 0, false, false,
+ 0, false, NMessageID::kUpdateModeSynchronize, NULL, NULL },
+
+ { DI_TEXT, 3, kYSize - 4, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL },
+
+ { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, true, NMessageID::kUpdateAdd, NULL, NULL },
+ { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kCancel, NULL, NULL }
+ };
+
+ const int kNumDialogItems = sizeof(initItems) / sizeof(initItems[0]);
+ const int kOkButtonIndex = kNumDialogItems - 2;
+ FarDialogItem dialogItems[kNumDialogItems];
+ g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems);
+ int askCode = g_StartupInfo.ShowDialog(76, kYSize,
+ kHelpTopic, dialogItems, kNumDialogItems);
+ if (askCode != kOkButtonIndex)
+ return NFileOperationReturnCode::kInterruptedByUser;
+
+ compressionInfo.Level = g_MethodMap[0];
+ for (i = 0; i < sizeof(g_MethodMap)/ sizeof(g_MethodMap[0]); i++)
+ if (dialogItems[kMethodRadioIndex + i].Selected)
+ compressionInfo.Level = g_MethodMap[i];
+
+ const CActionSet *actionSet;
+
+ if (dialogItems[kModeRadioIndex].Selected)
+ actionSet = &kAddActionSet;
+ else if (dialogItems[kModeRadioIndex + 1].Selected)
+ actionSet = &kUpdateActionSet;
+ else if (dialogItems[kModeRadioIndex + 2].Selected)
+ actionSet = &kFreshActionSet;
+ else if (dialogItems[kModeRadioIndex + 3].Selected)
+ actionSet = &kSynchronizeActionSet;
+ else
+ throw 51751;
+
+ SaveCompressionInfo(compressionInfo);
+
+ NWorkDir::CInfo workDirInfo;
+ ReadWorkDirInfo(workDirInfo);
+ UString workDir = GetWorkDir(workDirInfo, m_FileName);
+ CreateComplexDirectory(workDir);
+
+ CTempFileW tempFile;
+ UString tempFileName;
+ if (tempFile.Create(workDir, kTempArcivePrefix, tempFileName) == 0)
+ return NFileOperationReturnCode::kError;
+
+
+ /*
+ CSysStringVector fileNames;
+ for(int i = 0; i < numItems; i++)
+ {
+ const PluginPanelItem &panelItem = panelItems[i];
+ CSysString fullName;
+ if (!MyGetFullPathName(panelItem.FindData.cFileName, fullName))
+ return NFileOperationReturnCode::kError;
+ fileNames.Add(fullName);
+ }
+ */
+
+ CScreenRestorer screenRestorer;
+ CProgressBox progressBox;
+ CProgressBox *progressBoxPointer = NULL;
+ if ((opMode & OPM_SILENT) == 0 && (opMode & OPM_FIND ) == 0)
+ {
+ screenRestorer.Save();
+
+ progressBoxPointer = &progressBox;
+ progressBox.Init(g_StartupInfo.GetMsgString(NMessageID::kWaitTitle),
+ g_StartupInfo.GetMsgString(NMessageID::kUpdating), 1 << 16);
+ }
+
+ ////////////////////////////
+ // Save FolderItem;
+ UStringVector aPathVector;
+ GetPathParts(aPathVector);
+
+ /*
+ UString anArchivePrefix;
+ for(i = aPathVector.Size() - 1; i >= 0; i--)
+ {
+ anArchivePrefix += aPathVector[i];
+ anArchivePrefix += wchar_t(NName::kDirDelimiter);
+ }
+ /////////////////////////////////
+ */
+
+ UStringVector fileNames;
+ fileNames.Reserve(numItems);
+ for(i = 0; i < numItems; i++)
+ fileNames.Add(MultiByteToUnicodeString(panelItems[i].FindData.cFileName, CP_OEMCP));
+ CRecordVector<const wchar_t *> fileNamePointers;
+ fileNamePointers.Reserve(numItems);
+ for(i = 0; i < numItems; i++)
+ fileNamePointers.Add(fileNames[i]);
+
+ CMyComPtr<IOutFolderArchive> outArchive;
+ HRESULT result = m_ArchiveHandler.QueryInterface(IID_IOutFolderArchive, &outArchive);
+ if(result != S_OK)
+ {
+ g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive);
+ return NFileOperationReturnCode::kError;
+ }
+ outArchive->SetFolder(_folder);
+
+ // CSysString aCurrentFolder;
+ // MyGetCurrentDirectory(aCurrentFolder);
+ // outArchive->SetFiles(MultiByteToUnicodeString(aCurrentFolder, CP_OEMCP),
+ outArchive->SetFiles(L"",
+ &fileNamePointers.Front(), fileNamePointers.Size());
+ BYTE actionSetByte[NUpdateArchive::NPairState::kNumValues];
+ for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
+ actionSetByte[i] = actionSet->StateActions[i];
+
+ CUpdateCallback100Imp *updateCallbackSpec = new CUpdateCallback100Imp;
+ CMyComPtr<IFolderArchiveUpdateCallback> updateCallback(updateCallbackSpec );
+
+ updateCallbackSpec->Init(m_ArchiveHandler, &progressBox);
+
+ if (SetOutProperties(outArchive, compressionInfo.Level) != S_OK)
+ return NFileOperationReturnCode::kError;
+
+ result = outArchive->DoOperation(NULL, NULL,
+ tempFileName, actionSetByte, NULL, updateCallback);
+ updateCallback.Release();
+ outArchive.Release();
+
+ /*
+ HRESULT result = Compress(fileNames, anArchivePrefix, *actionSet,
+ m_ProxyHandler.get(),
+ m_ArchiverInfo.ClassID, compressionInfo.Method == 0,
+ compressionInfo.Method == 2, tempFileName, progressBoxPointer);
+ */
+
+ if (result != S_OK)
+ {
+ ShowErrorMessage(result);
+ return NFileOperationReturnCode::kError;
+ }
+
+ _folder.Release();
+ m_ArchiveHandler->Close();
+
+ // m_FolderItem = NULL;
+
+ if (!DeleteFileAlways(m_FileName))
+ {
+ ShowLastErrorMessage();
+ return NFileOperationReturnCode::kError;
+ }
+
+ tempFile.DisableDeleting();
+ if (!MyMoveFile(tempFileName, m_FileName))
+ {
+ ShowLastErrorMessage();
+ return NFileOperationReturnCode::kError;
+ }
+
+ m_ArchiveHandler->ReOpen(NULL);
+ if (result != S_OK)
+ {
+ ShowErrorMessage(result);
+ return NFileOperationReturnCode::kError;
+ }
+
+ /*
+ if(m_ProxyHandler->ReInit(NULL) != S_OK)
+ return NFileOperationReturnCode::kError;
+ */
+
+ ////////////////////////////
+ // Restore FolderItem;
+
+ m_ArchiveHandler->BindToRootFolder(&_folder);
+ for (i = 0; i < aPathVector.Size(); i++)
+ {
+ CMyComPtr<IFolderFolder> newFolder;
+ _folder->BindToFolder(aPathVector[i], &newFolder);
+ if(!newFolder )
+ break;
+ _folder = newFolder;
+ }
+
+ /*
+ if(moveMode != 0)
+ {
+ for(int i = 0; i < numItems; i++)
+ {
+ const PluginPanelItem &aPluginPanelItem = panelItems[i];
+ bool result;
+ if(NFile::NFind::NAttributes::IsDirectory(aPluginPanelItem.FindData.dwFileAttributes))
+ result = NFile::NDirectory::RemoveDirectoryWithSubItems(
+ aPluginPanelItem.FindData.cFileName);
+ else
+ result = NFile::NDirectory::DeleteFileAlways(
+ aPluginPanelItem.FindData.cFileName);
+ if(!result)
+ return NFileOperationReturnCode::kError;
+ }
+ }
+ */
+ return NFileOperationReturnCode::kSuccess;
+}
+
+
+
+/*
+// {23170F69-40C1-278A-1000-000100030000}
+DEFINE_GUID(CLSID_CAgentArchiveHandler,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00);
+*/
+
+HRESULT CompressFiles(const CObjectVector<PluginPanelItem> &pluginPanelItems)
+{
+ if (pluginPanelItems.Size() == 0)
+ return E_FAIL;
+
+ UStringVector fileNames;
+ for(int i = 0; i < pluginPanelItems.Size(); i++)
+ {
+ const PluginPanelItem &panelItem = pluginPanelItems[i];
+ CSysString fullName;
+ if (strcmp(panelItem.FindData.cFileName, "..") == 0 &&
+ NFind::NAttributes::IsDirectory(panelItem.FindData.dwFileAttributes))
+ return E_FAIL;
+ if (strcmp(panelItem.FindData.cFileName, ".") == 0 &&
+ NFind::NAttributes::IsDirectory(panelItem.FindData.dwFileAttributes))
+ return E_FAIL;
+ if (!MyGetFullPathName(panelItem.FindData.cFileName, fullName))
+ return E_FAIL;
+ fileNames.Add(MultiByteToUnicodeString(fullName, CP_OEMCP));
+ }
+
+ NCompression::CInfo compressionInfo;
+ // CZipRegistryManager aZipRegistryManager;
+ ReadCompressionInfo(compressionInfo);
+
+ int archiverIndex = 0;
+
+ CObjectVector<CArchiverInfo> archiverInfoList;
+ {
+ CObjectVector<CArchiverInfo> fullArchiverInfoList;
+ ReadArchiverInfoList(fullArchiverInfoList);
+ for (int i = 0; i < fullArchiverInfoList.Size(); i++)
+ {
+ const CArchiverInfo &archiverInfo = fullArchiverInfoList[i];
+ if (archiverInfo.UpdateEnabled)
+ {
+ if (archiverInfo.Name.CompareNoCase(compressionInfo.ArchiveType) == 0)
+ archiverIndex = archiverInfoList.Size();
+ archiverInfoList.Add(archiverInfo);
+ }
+ }
+ }
+ if (archiverInfoList.IsEmpty())
+ throw "There is no update achivers";
+
+
+ UString resultPath;
+ {
+ NName::CParsedPath parsedPath;
+ parsedPath.ParsePath(fileNames.Front());
+ if(parsedPath.PathParts.Size() == 0)
+ return E_FAIL;
+ if (fileNames.Size() == 1 || parsedPath.PathParts.Size() == 1)
+ {
+ // CSysString pureName, dot, extension;
+ resultPath = parsedPath.PathParts.Back();
+ }
+ else
+ {
+ parsedPath.PathParts.DeleteBack();
+ resultPath = parsedPath.PathParts.Back();
+ }
+ }
+ UString archiveNameSrc = resultPath;
+ UString archiveName = archiveNameSrc;
+
+ const CArchiverInfo &archiverInfo = archiverInfoList[archiverIndex];
+ int prevFormat = archiverIndex;
+
+ if (!archiverInfo.KeepName)
+ {
+ int dotPos = archiveName.ReverseFind('.');
+ int slashPos = MyMax(archiveName.ReverseFind('\\'), archiveName.ReverseFind('/'));
+ if (dotPos > slashPos)
+ archiveName = archiveName.Left(dotPos);
+ }
+ archiveName += L'.';
+ archiveName += archiverInfo.GetMainExtension();
+
+ const CActionSet *actionSet = &kAddActionSet;
+
+ for (;;)
+ {
+ AString archiveNameA = UnicodeStringToMultiByte(archiveName, CP_OEMCP);
+ const int kYSize = 16;
+ const int kXMid = 38;
+
+ const int kArchiveNameIndex = 2;
+ const int kMethodRadioIndex = kArchiveNameIndex + 2;
+ const int kModeRadioIndex = kMethodRadioIndex + 7;
+
+ const CArchiverInfo &archiverInfo = archiverInfoList[archiverIndex];
+
+ char updateAddToArchiveString[512];
+ sprintf(updateAddToArchiveString,
+ g_StartupInfo.GetMsgString(NMessageID::kUpdateAddToArchive), GetSystemString(archiverInfo.Name), CP_OEMCP);
+
+ int methodIndex = 0;
+ for (int i = sizeof(g_MethodMap) / sizeof(g_MethodMap[0]) - 1; i >= 0; i--)
+ if (compressionInfo.Level >= g_MethodMap[i])
+ {
+ methodIndex = i;
+ break;
+ }
+
+ struct CInitDialogItem initItems[]=
+ {
+ { DI_DOUBLEBOX, 3, 1, 72, kYSize - 2, false, false, 0, false, NMessageID::kUpdateTitle, NULL, NULL },
+
+ { DI_TEXT, 5, 2, 0, 0, false, false, 0, false, -1, updateAddToArchiveString, NULL },
+
+ { DI_EDIT, 5, 3, 70, 3, true, false, DIF_HISTORY, false, -1, archiveNameA, kArchiveHistoryKeyName},
+ // { DI_EDIT, 5, 3, 70, 3, true, false, 0, false, -1, archiveName, NULL},
+
+ { DI_SINGLEBOX, 4, 4, kXMid - 2, 4 + 7, false, false, 0, false, NMessageID::kUpdateMethod, NULL, NULL },
+ { DI_RADIOBUTTON, 6, 5, 0, 0, false, methodIndex == 0,
+ DIF_GROUP, false, NMessageID::kUpdateMethodStore, NULL, NULL },
+ { DI_RADIOBUTTON, 6, 6, 0, 0, false, methodIndex == 1,
+ 0, false, NMessageID::kUpdateMethodFastest, NULL, NULL },
+ { DI_RADIOBUTTON, 6, 7, 0, 0, false, methodIndex == 2,
+ 0, false, NMessageID::kUpdateMethodFast, NULL, NULL },
+ { DI_RADIOBUTTON, 6, 8, 0, 0, false, methodIndex == 3,
+ 0, false, NMessageID::kUpdateMethodNormal, NULL, NULL },
+ { DI_RADIOBUTTON, 6, 9, 0, 0, false, methodIndex == 4,
+ false, 0, NMessageID::kUpdateMethodMaximum, NULL, NULL },
+ { DI_RADIOBUTTON, 6, 10, 0, 0, false, methodIndex == 5,
+ false, 0, NMessageID::kUpdateMethodUltra, NULL, NULL },
+
+ { DI_SINGLEBOX, kXMid, 4, 70, 4 + 5, false, false, 0, false, NMessageID::kUpdateMode, NULL, NULL },
+ { DI_RADIOBUTTON, kXMid + 2, 5, 0, 0, false,
+ actionSet == &kAddActionSet,
+ DIF_GROUP, false, NMessageID::kUpdateModeAdd, NULL, NULL },
+ { DI_RADIOBUTTON, kXMid + 2, 6, 0, 0, false,
+ actionSet == &kUpdateActionSet,
+ 0, false, NMessageID::kUpdateModeUpdate, NULL, NULL },
+ { DI_RADIOBUTTON, kXMid + 2, 7, 0, 0, false,
+ actionSet == &kFreshActionSet,
+ 0, false, NMessageID::kUpdateModeFreshen, NULL, NULL },
+ { DI_RADIOBUTTON, kXMid + 2, 8, 0, 0, false,
+ actionSet == &kSynchronizeActionSet,
+ 0, false, NMessageID::kUpdateModeSynchronize, NULL, NULL },
+
+ { DI_TEXT, 3, kYSize - 4, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL },
+
+ { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, true, NMessageID::kUpdateAdd, NULL, NULL },
+ { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kUpdateSelectArchiver, NULL, NULL },
+ { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kCancel, NULL, NULL }
+ };
+
+ const int kNumDialogItems = sizeof(initItems) / sizeof(initItems[0]);
+
+ const int kOkButtonIndex = kNumDialogItems - 3;
+ const int kSelectarchiverButtonIndex = kNumDialogItems - 2;
+
+ FarDialogItem dialogItems[kNumDialogItems];
+ g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems);
+ int askCode = g_StartupInfo.ShowDialog(76, kYSize,
+ kHelpTopic, dialogItems, kNumDialogItems);
+
+ archiveNameA = dialogItems[kArchiveNameIndex].Data;
+ archiveNameA.Trim();
+ archiveName = MultiByteToUnicodeString(archiveNameA, CP_OEMCP);
+
+ compressionInfo.Level = g_MethodMap[0];
+ for (i = 0; i < sizeof(g_MethodMap)/ sizeof(g_MethodMap[0]); i++)
+ if (dialogItems[kMethodRadioIndex + i].Selected)
+ compressionInfo.Level = g_MethodMap[i];
+
+ if (dialogItems[kModeRadioIndex].Selected)
+ actionSet = &kAddActionSet;
+ else if (dialogItems[kModeRadioIndex + 1].Selected)
+ actionSet = &kUpdateActionSet;
+ else if (dialogItems[kModeRadioIndex + 2].Selected)
+ actionSet = &kFreshActionSet;
+ else if (dialogItems[kModeRadioIndex + 3].Selected)
+ actionSet = &kSynchronizeActionSet;
+ else
+ throw 51751;
+
+ if (askCode == kSelectarchiverButtonIndex)
+ {
+ CSysStringVector archiverNames;
+ for(int i = 0; i < archiverInfoList.Size(); i++)
+ archiverNames.Add(GetSystemString(archiverInfoList[i].Name,
+ CP_OEMCP));
+
+ int index = g_StartupInfo.Menu(FMENU_AUTOHIGHLIGHT,
+ g_StartupInfo.GetMsgString(NMessageID::kUpdateSelectArchiverMenuTitle),
+ NULL, archiverNames, archiverIndex);
+ if(index >= 0)
+ {
+ const CArchiverInfo &prevArchiverInfo = archiverInfoList[prevFormat];
+ if (prevArchiverInfo.KeepName)
+ {
+ const UString &prevExtension = prevArchiverInfo.GetMainExtension();
+ const int prevExtensionLen = prevExtension.Length();
+ if (archiveName.Right(prevExtensionLen).CompareNoCase(prevExtension) == 0)
+ {
+ int pos = archiveName.Length() - prevExtensionLen;
+ UString temp = archiveName.Left(pos);
+ if (pos > 1)
+ {
+ int dotPos = archiveName.ReverseFind('.');
+ if (dotPos == pos - 1)
+ archiveName = archiveName.Left(dotPos);
+ }
+ }
+ }
+
+ archiverIndex = index;
+ const CArchiverInfo &archiverInfo =
+ archiverInfoList[archiverIndex];
+ prevFormat = archiverIndex;
+
+ if (archiverInfo.KeepName)
+ archiveName = archiveNameSrc;
+ else
+ {
+ int dotPos = archiveName.ReverseFind('.');
+ int slashPos = MyMax(archiveName.ReverseFind('\\'), archiveName.ReverseFind('/'));
+ if (dotPos > slashPos)
+ archiveName = archiveName.Left(dotPos);
+ }
+ archiveName += L'.';
+ archiveName += archiverInfo.GetMainExtension();
+ }
+ continue;
+ }
+
+ if (askCode != kOkButtonIndex)
+ return E_ABORT;
+
+ break;
+ }
+
+ const CArchiverInfo &archiverInfoFinal = archiverInfoList[archiverIndex];
+ compressionInfo.ArchiveType = archiverInfoFinal.Name;
+ SaveCompressionInfo(compressionInfo);
+
+ NWorkDir::CInfo workDirInfo;
+ ReadWorkDirInfo(workDirInfo);
+
+ UString fullArchiveName;
+ if (!MyGetFullPathName(archiveName, fullArchiveName))
+ return E_FAIL;
+
+ UString workDir = GetWorkDir(workDirInfo, fullArchiveName);
+ CreateComplexDirectory(workDir);
+
+ CTempFileW tempFile;
+ UString tempFileName;
+ if (tempFile.Create(workDir, kTempArcivePrefix, tempFileName) == 0)
+ return E_FAIL;
+
+
+ CScreenRestorer screenRestorer;
+ CProgressBox progressBox;
+ CProgressBox *progressBoxPointer = NULL;
+
+ screenRestorer.Save();
+
+ progressBoxPointer = &progressBox;
+ progressBox.Init(g_StartupInfo.GetMsgString(NMessageID::kWaitTitle),
+ g_StartupInfo.GetMsgString(NMessageID::kUpdating), 1 << 16);
+
+
+ NFind::CFileInfoW fileInfo;
+
+ CMyComPtr<IOutFolderArchive> outArchive;
+
+ CMyComPtr<IInFolderArchive> archiveHandler;
+ if(NFind::FindFile(fullArchiveName, fileInfo))
+ {
+ if (fileInfo.IsDirectory())
+ throw "There is Directory with such name";
+
+ CAgent *agentSpec = new CAgent;
+ archiveHandler = agentSpec;
+ // CLSID realClassID;
+ CMyComBSTR archiveType;
+ RINOK(agentSpec->Open(
+ GetUnicodeString(fullArchiveName, CP_OEMCP),
+ // &realClassID,
+ &archiveType,
+ NULL));
+
+ if (archiverInfoFinal.Name.CompareNoCase((const wchar_t *)archiveType) != 0)
+ throw "Type of existing archive differs from specified type";
+ HRESULT result = archiveHandler.QueryInterface(
+ IID_IOutFolderArchive, &outArchive);
+ if(result != S_OK)
+ {
+ g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive);
+ return E_FAIL;
+ }
+ }
+ else
+ {
+ // HRESULT result = outArchive.CoCreateInstance(classID);
+ CAgent *agentSpec = new CAgent;
+ outArchive = agentSpec;
+
+ /*
+ HRESULT result = outArchive.CoCreateInstance(CLSID_CAgentArchiveHandler);
+ if (result != S_OK)
+ {
+ g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive);
+ return E_FAIL;
+ }
+ */
+ }
+
+ CRecordVector<const wchar_t *> fileNamePointers;
+ fileNamePointers.Reserve(fileNames.Size());
+ for(i = 0; i < fileNames.Size(); i++)
+ fileNamePointers.Add(fileNames[i]);
+
+ outArchive->SetFolder(NULL);
+ // CSysString aCurrentFolder;
+ // MyGetCurrentDirectory(aCurrentFolder);
+ // outArchive->SetFiles(MultiByteToUnicodeString(aCurrentFolder, CP_OEMCP),
+ outArchive->SetFiles(L"",
+ &fileNamePointers.Front(), fileNamePointers.Size());
+ BYTE actionSetByte[NUpdateArchive::NPairState::kNumValues];
+ for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
+ actionSetByte[i] = actionSet->StateActions[i];
+
+ CUpdateCallback100Imp *updateCallbackSpec = new CUpdateCallback100Imp;
+ CMyComPtr<IFolderArchiveUpdateCallback> updateCallback(updateCallbackSpec );
+
+ updateCallbackSpec->Init(archiveHandler, &progressBox);
+
+
+ RINOK(SetOutProperties(outArchive, compressionInfo.Level));
+
+ HRESULT result = outArchive->DoOperation(
+ GetUnicodeString(archiverInfoFinal.FilePath, CP_OEMCP),
+ &archiverInfoFinal.ClassID,
+ tempFileName, actionSetByte,
+ NULL, updateCallback);
+ updateCallback.Release();
+ outArchive.Release();
+
+ if (result != S_OK)
+ {
+ ShowErrorMessage(result);
+ return result;
+ }
+
+ if(archiveHandler)
+ {
+ archiveHandler->Close();
+ if (!DeleteFileAlways(fullArchiveName))
+ {
+ ShowLastErrorMessage();
+ return NFileOperationReturnCode::kError;
+ }
+ }
+ tempFile.DisableDeleting();
+ if (!MyMoveFile(tempFileName, fullArchiveName))
+ {
+ ShowLastErrorMessage();
+ return E_FAIL;
+ }
+
+ return S_OK;
+}
+
diff --git a/CPP/7zip/UI/Far/ProgressBox.cpp b/CPP/7zip/UI/Far/ProgressBox.cpp
new file mode 100755
index 00000000..64e0e09d
--- /dev/null
+++ b/CPP/7zip/UI/Far/ProgressBox.cpp
@@ -0,0 +1,103 @@
+// ProgressBox.cpp
+
+#include "StdAfx.h"
+
+#include <stdio.h>
+
+#include "ProgressBox.h"
+
+#include "FarUtils.h"
+
+using namespace NFar;
+
+static void CopySpaces(char *destString, int numSpaces)
+{
+ for(int i = 0; i < numSpaces; i++)
+ destString[i] = ' ';
+ destString[i] = '\0';
+}
+
+/////////////////////////////////
+// CMessageBox
+
+const int kNumStringsMax = 10;
+
+void CMessageBox::Init(const CSysString &title, const CSysString &message,
+ int numStrings, int width)
+{
+ if (numStrings > kNumStringsMax)
+ throw 120620;
+ m_NumStrings = numStrings;
+ m_Width = width;
+
+ m_Title = title;
+ m_Message = message;
+}
+
+const int kNumStaticStrings = 2;
+
+void CMessageBox::ShowProcessMessages(const char *messages[])
+{
+ const char *msgItems[kNumStaticStrings + kNumStringsMax];
+ msgItems[0] = m_Title;
+ msgItems[1] = m_Message;
+
+ char formattedMessages[kNumStringsMax][256];
+
+ for (int i = 0; i < m_NumStrings; i++)
+ {
+ char *formattedMessage = formattedMessages[i];
+ int len = strlen(messages[i]);
+ int size = MyMax(m_Width, len);
+ int startPos = (size - len) / 2;
+ CopySpaces(formattedMessage, startPos);
+ strcpy(formattedMessage + startPos, messages[i]);
+ CopySpaces(formattedMessage + startPos + len, size - startPos - len);
+ msgItems[kNumStaticStrings + i] = formattedMessage;
+ }
+
+ g_StartupInfo.ShowMessage(0, NULL, msgItems, kNumStaticStrings + m_NumStrings, 0);
+}
+
+/////////////////////////////////
+// CProgressBox
+
+void CProgressBox::Init(const CSysString &title, const CSysString &message,
+ UInt64 step)
+{
+ CMessageBox::Init(title, message, 1, 22);
+ m_Step = step;
+ m_CompletedPrev = 0;
+ m_Total = 0;
+}
+
+
+void CProgressBox::ShowProcessMessage(const char *message)
+{
+ CMessageBox::ShowProcessMessages(&message);
+}
+
+void CProgressBox::PrintPercent(UInt64 percent)
+{
+ char valueBuffer[32];
+ sprintf(valueBuffer, "%I64u%%", percent);
+ ShowProcessMessage(valueBuffer);
+}
+
+void CProgressBox::SetTotal(UInt64 total)
+{
+ m_Total = total;
+}
+
+void CProgressBox::PrintCompeteValue(UInt64 completed)
+{
+ if (completed >= m_CompletedPrev + m_Step || completed < m_CompletedPrev ||
+ completed == 0)
+ {
+ if (m_Total == 0)
+ PrintPercent(0);
+ else
+ PrintPercent(completed * 100 / m_Total);
+ m_CompletedPrev = completed;
+ }
+}
diff --git a/CPP/7zip/UI/Far/ProgressBox.h b/CPP/7zip/UI/Far/ProgressBox.h
new file mode 100755
index 00000000..8721b456
--- /dev/null
+++ b/CPP/7zip/UI/Far/ProgressBox.h
@@ -0,0 +1,35 @@
+// ProgressBox.h
+
+#ifndef __PROGRESSBOX_H
+#define __PROGRESSBOX_H
+
+#include "Common/String.h"
+#include "Common/Types.h"
+
+class CMessageBox
+{
+ CSysString m_Title;
+ CSysString m_Message;
+ int m_NumStrings;
+ int m_Width;
+public:
+ void Init(const CSysString &title,
+ const CSysString &message, int numStrings, int width);
+ void ShowProcessMessages(const char *messages[]);
+};
+
+class CProgressBox: public CMessageBox
+{
+ UInt64 m_Total;
+ UInt64 m_CompletedPrev;
+ UInt64 m_Step;
+public:
+ void Init(const CSysString &title,
+ const CSysString &message, UInt64 step);
+ void ShowProcessMessage(const char *message);
+ void PrintPercent(UInt64 percent);
+ void PrintCompeteValue(UInt64 completed);
+ void SetTotal(UInt64 total);
+};
+
+#endif
diff --git a/CPP/7zip/UI/Far/StdAfx.cpp b/CPP/7zip/UI/Far/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/UI/Far/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/UI/Far/StdAfx.h b/CPP/7zip/UI/Far/StdAfx.h
new file mode 100755
index 00000000..0a7c347b
--- /dev/null
+++ b/CPP/7zip/UI/Far/StdAfx.h
@@ -0,0 +1,12 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+#include <stdio.h>
+
+#include "Common/NewHandler.h"
+
+#endif
+
diff --git a/CPP/7zip/UI/Far/UpdateCallback100.cpp b/CPP/7zip/UI/Far/UpdateCallback100.cpp
new file mode 100755
index 00000000..f1a2946e
--- /dev/null
+++ b/CPP/7zip/UI/Far/UpdateCallback100.cpp
@@ -0,0 +1,54 @@
+// UpdateCallback.h
+
+#include "StdAfx.h"
+
+#include "UpdateCallback100.h"
+
+#include "Common/Defs.h"
+#include "Common/StringConvert.h"
+#include "FarUtils.h"
+
+using namespace NFar;
+
+STDMETHODIMP CUpdateCallback100Imp::SetTotal(UINT64 aSize)
+{
+ if (m_ProgressBox != 0)
+ {
+ m_ProgressBox->SetTotal(aSize);
+ m_ProgressBox->PrintCompeteValue(0);
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CUpdateCallback100Imp::SetCompleted(const UINT64 *aCompleteValue)
+{
+ if(WasEscPressed())
+ return E_ABORT;
+ if (m_ProgressBox != 0 && aCompleteValue != NULL)
+ m_ProgressBox->PrintCompeteValue(*aCompleteValue);
+ return S_OK;
+}
+
+STDMETHODIMP CUpdateCallback100Imp::CompressOperation(const wchar_t *aName)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CUpdateCallback100Imp::DeleteOperation(const wchar_t *aName)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CUpdateCallback100Imp::OperationResult(INT32 aOperationResult)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CUpdateCallback100Imp::UpdateErrorMessage(const wchar_t *message)
+{
+ CSysString s = UnicodeStringToMultiByte(message, CP_OEMCP);
+ if (g_StartupInfo.ShowMessage(s) == -1)
+ return E_ABORT;
+ return S_OK;
+}
+
diff --git a/CPP/7zip/UI/Far/UpdateCallback100.h b/CPP/7zip/UI/Far/UpdateCallback100.h
new file mode 100755
index 00000000..d66137cc
--- /dev/null
+++ b/CPP/7zip/UI/Far/UpdateCallback100.h
@@ -0,0 +1,45 @@
+// UpdateCallback.h
+
+#ifndef __UPDATECALLBACK100_H
+#define __UPDATECALLBACK100_H
+
+#include "Common/String.h"
+#include "Common/MyCom.h"
+
+#include "../Agent/IFolderArchive.h"
+
+#include "ProgressBox.h"
+
+class CUpdateCallback100Imp:
+ public IFolderArchiveUpdateCallback,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ // IProfress
+
+ STDMETHOD(SetTotal)(UINT64 aSize);
+ STDMETHOD(SetCompleted)(const UINT64 *aCompleteValue);
+
+ // IUpdateCallBack
+ STDMETHOD(CompressOperation)(const wchar_t *aName);
+ STDMETHOD(DeleteOperation)(const wchar_t *aName);
+ STDMETHOD(OperationResult)(INT32 aOperationResult);
+ STDMETHOD(UpdateErrorMessage)(const wchar_t *message);
+
+private:
+ CMyComPtr<IInFolderArchive> m_ArchiveHandler;
+ CProgressBox *m_ProgressBox;
+public:
+ void Init(IInFolderArchive *anArchiveHandler,
+ CProgressBox *aProgressBox)
+ {
+ m_ArchiveHandler = anArchiveHandler;
+ m_ProgressBox = aProgressBox;
+ }
+};
+
+
+
+#endif
diff --git a/CPP/7zip/UI/Far/makefile b/CPP/7zip/UI/Far/makefile
new file mode 100755
index 00000000..4dbd1988
--- /dev/null
+++ b/CPP/7zip/UI/Far/makefile
@@ -0,0 +1,102 @@
+PROG = 7-ZipFar.dll
+DEF_FILE = Far.def
+LIBS = $(LIBS) user32.lib oleaut32.lib advapi32.lib ole32.lib
+CFLAGS = $(CFLAGS) -I ../../../ -DWIN_LONG_PATH
+
+FAR_OBJS = \
+ $O\CLSIDConst.obj \
+ $O\ExtractEngine.obj \
+ $O\FarUtils.obj \
+ $O\Main.obj \
+ $O\OverwriteDialog.obj \
+ $O\Plugin.obj \
+ $O\PluginCommon.obj \
+ $O\PluginDelete.obj \
+ $O\PluginRead.obj \
+ $O\PluginWrite.obj \
+ $O\ProgressBox.obj \
+ $O\UpdateCallback100.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\IntToString.obj \
+ $O\NewHandler.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\Vector.obj \
+ $O\Wildcard.obj \
+
+WIN_OBJS = \
+ $O\DLL.obj \
+ $O\Error.obj \
+ $O\FileDir.obj \
+ $O\FileFind.obj \
+ $O\FileIO.obj \
+ $O\FileName.obj \
+ $O\PropVariant.obj \
+ $O\PropVariantConversions.obj \
+ $O\Registry.obj \
+ $O\Synchronization.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\FilePathAutoRename.obj \
+ $O\FileStreams.obj \
+ $O\StreamUtils.obj \
+
+UI_COMMON_OBJS = \
+ $O\ArchiveExtractCallback.obj \
+ $O\ArchiveOpenCallback.obj \
+ $O\ArchiverInfo.obj \
+ $O\DefaultName.obj \
+ $O\EnumDirItems.obj \
+ $O\ExtractingFilePath.obj \
+ $O\OpenArchive.obj \
+ $O\PropIDUtils.obj \
+ $O\SortUtils.obj \
+ $O\UpdateAction.obj \
+ $O\UpdateCallback.obj \
+ $O\UpdatePair.obj \
+ $O\UpdateProduce.obj \
+ $O\WorkDir.obj \
+ $O\ZipRegistry.obj \
+
+AGENT_OBJS = \
+ $O\Agent.obj \
+ $O\AgentOut.obj \
+ $O\AgentProxy.obj \
+ $O\UpdateCallbackAgent.obj \
+
+C_OBJS = \
+ $O\Sort.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(FAR_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(UI_COMMON_OBJS) \
+ $(AGENT_OBJS) \
+ $(C_OBJS) \
+ $O\CopyCoder.obj \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(FAR_OBJS): $(*B).cpp
+ $(COMPL)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$(UI_COMMON_OBJS): ../Common/$(*B).cpp
+ $(COMPL)
+$(AGENT_OBJS): ../Agent/$(*B).cpp
+ $(COMPL)
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
+$(C_OBJS): ../../../../C/$(*B).c
+ $(COMPL_O2)
diff --git a/CPP/7zip/UI/Far/resource.rc b/CPP/7zip/UI/Far/resource.rc
new file mode 100755
index 00000000..a5c2e2f3
--- /dev/null
+++ b/CPP/7zip/UI/Far/resource.rc
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("7-Zip Plugin for FAR Manager", "7-ZipFar")
diff --git a/CPP/7zip/UI/GUI/7zG.exe.manifest b/CPP/7zip/UI/GUI/7zG.exe.manifest
new file mode 100755
index 00000000..c6ef90e8
--- /dev/null
+++ b/CPP/7zip/UI/GUI/7zG.exe.manifest
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"><assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="7-Zip.7-Zip.7zG" type="win32"/><description>7-Zip GUI.</description><dependency> <dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/></dependentAssembly></dependency></assembly>
diff --git a/CPP/7zip/UI/GUI/CompressDialog.cpp b/CPP/7zip/UI/GUI/CompressDialog.cpp
new file mode 100755
index 00000000..f49bb078
--- /dev/null
+++ b/CPP/7zip/UI/GUI/CompressDialog.cpp
@@ -0,0 +1,1373 @@
+// CompressDialog.cpp
+
+#include "StdAfx.h"
+
+#include "resource.h"
+#include "Common/Defs.h"
+#include "Common/StringConvert.h"
+#include "Common/IntToString.h"
+#include "Windows/CommonDialog.h"
+#include "Windows/FileDir.h"
+#include "Windows/FileName.h"
+#include "Windows/ResourceString.h"
+#include "Windows/System.h"
+
+#include "../../FileManager/HelpUtils.h"
+#include "../../FileManager/SplitUtils.h"
+#include "../../FileManager/FormatUtils.h"
+
+#include "../Explorer/MyMessages.h"
+
+#include "../Common/ZipRegistry.h"
+
+#include "CompressDialog.h"
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+#ifdef LANG
+#include "../../FileManager/LangUtils.h"
+#endif
+
+#include "../Resource/CompressDialog/resource.h"
+
+#define MY_SIZE_OF_ARRAY(x) (sizeof(x) / sizeof(x[0]))
+
+#ifdef LANG
+static CIDLangPair kIDLangPairs[] =
+{
+ { IDC_STATIC_COMPRESS_ARCHIVE, 0x02000D01 },
+ { IDC_STATIC_COMPRESS_FORMAT, 0x02000D03 },
+ { IDC_STATIC_COMPRESS_LEVEL, 0x02000D0B },
+ { IDC_STATIC_COMPRESS_METHOD, 0x02000D04 },
+ { IDC_STATIC_COMPRESS_DICTIONARY, 0x02000D0C },
+ { IDC_STATIC_COMPRESS_ORDER, 0x02000D0D },
+ { IDC_STATIC_COMPRESS_MEMORY, 0x02000D0E },
+ { IDC_STATIC_COMPRESS_MEMORY_DE, 0x02000D0F },
+ { IDC_COMPRESS_SOLID, 0x02000D05 },
+ { IDC_COMPRESS_MULTI_THREAD, 0x02000D09 },
+ { IDC_STATIC_COMPRESS_VOLUME, 0x02000D40 },
+ { IDC_STATIC_COMPRESS_PARAMETERS, 0x02000D06 },
+
+ { IDC_STATIC_COMPRESS_UPDATE_MODE, 0x02000D02 },
+ { IDC_STATIC_COMPRESS_OPTIONS, 0x02000D07 },
+ { IDC_COMPRESS_SFX, 0x02000D08 },
+
+ { IDC_COMPRESS_ENCRYPTION, 0x02000D10 },
+ { IDC_STATIC_COMPRESS_PASSWORD1, 0x02000B01 },
+ { IDC_STATIC_COMPRESS_PASSWORD2, 0x02000B03 },
+ { IDC_COMPRESS_CHECK_SHOW_PASSWORD, 0x02000B02 },
+ { IDC_STATIC_COMPRESS_ENCRYPTION_METHOD, 0x02000D11 },
+ { IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES, 0x02000D0A },
+
+ { IDOK, 0x02000702 },
+ { IDCANCEL, 0x02000710 },
+ { IDHELP, 0x02000720 }
+};
+#endif
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NName;
+using namespace NDirectory;
+
+static const int kHistorySize = 8;
+
+static LPCWSTR kExeExt = L".exe";
+static LPCWSTR k7zFormat = L"7z";
+
+struct CLevelInfo
+{
+ UInt32 ResourceID;
+ UInt32 LangID;
+};
+
+enum ELevel
+{
+ kStore = 0,
+ kFastest = 1,
+ kFast = 3,
+ kNormal = 5,
+ kMaximum = 7,
+ kUltra = 9
+};
+
+static const CLevelInfo g_Levels[] =
+{
+ { IDS_METHOD_STORE, 0x02000D81 },
+ { IDS_METHOD_FASTEST, 0x02000D85 },
+ { 0, 0 },
+ { IDS_METHOD_FAST, 0x02000D84 },
+ { 0, 0 },
+ { IDS_METHOD_NORMAL, 0x02000D82 },
+ { 0, 0 },
+ { IDS_METHOD_MAXIMUM, 0x02000D83 },
+ { 0, 0 },
+ { IDS_METHOD_ULTRA, 0x02000D86 }
+};
+
+enum EMethodID
+{
+ kCopy,
+ kLZMA,
+ kPPMd,
+ kBZip2,
+ kDeflate,
+ kDeflate64
+};
+
+static const LPCWSTR kMethodsNames[] =
+{
+ L"Copy",
+ L"LZMA",
+ L"PPMd",
+ L"BZip2",
+ L"Deflate",
+ L"Deflate64"
+};
+
+static const EMethodID g_7zMethods[] =
+{
+ kLZMA,
+ kPPMd,
+ kBZip2
+};
+
+static const EMethodID g_7zSfxMethods[] =
+{
+ kCopy,
+ kLZMA,
+ kPPMd
+};
+
+static EMethodID g_ZipMethods[] =
+{
+ kDeflate,
+ kDeflate64,
+ kBZip2
+};
+
+static EMethodID g_GZipMethods[] =
+{
+ kDeflate
+};
+
+static EMethodID g_BZip2Methods[] =
+{
+ kBZip2
+};
+
+struct CFormatInfo
+{
+ LPCWSTR Name;
+ UInt32 LevelsMask;
+ const EMethodID *MathodIDs;
+ int NumMethods;
+ bool Filter;
+ bool Solid;
+ bool MultiThread;
+ bool SFX;
+ bool Encrypt;
+ bool EncryptFileNames;
+};
+
+static const CFormatInfo g_Formats[] =
+{
+ {
+ L"",
+ (1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
+ 0, 0,
+ false, false, false, false, false, false
+ },
+ {
+ k7zFormat,
+ (1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
+ g_7zMethods, MY_SIZE_OF_ARRAY(g_7zMethods),
+ true, true, true, true, true, true
+ },
+ {
+ L"Zip",
+ (1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
+ g_ZipMethods, MY_SIZE_OF_ARRAY(g_ZipMethods) ,
+ false, false, true, false, true, false
+ },
+ {
+ L"GZip",
+ (1 << 5) | (1 << 7) | (1 << 9),
+ g_GZipMethods, MY_SIZE_OF_ARRAY(g_GZipMethods),
+ false, false, false, false, false, false
+ },
+ {
+ L"BZip2",
+ (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
+ g_BZip2Methods,
+ MY_SIZE_OF_ARRAY(g_BZip2Methods),
+ false, false, true, false, false
+ },
+ {
+ L"Tar",
+ (1 << 0),
+ 0, 0,
+ false, false, false, false, false, false
+ }
+};
+
+static bool IsMethodSupportedBySfx(int methodID)
+{
+ for (int i = 0; i < MY_SIZE_OF_ARRAY(g_7zSfxMethods); i++)
+ if (methodID == g_7zSfxMethods[i])
+ return true;
+ return false;
+};
+
+#ifndef _WIN64
+typedef BOOL (WINAPI *GlobalMemoryStatusExP)(LPMEMORYSTATUSEX lpBuffer);
+#endif
+
+static UInt64 GetPhysicalRamSize()
+{
+ MEMORYSTATUSEX stat;
+ stat.dwLength = sizeof(stat);
+ // return (128 << 20);
+ #ifdef _WIN64
+ if (!::GlobalMemoryStatusEx(&stat))
+ return 0;
+ return stat.ullTotalPhys;
+ #else
+ GlobalMemoryStatusExP globalMemoryStatusEx = (GlobalMemoryStatusExP)
+ ::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")),
+ "GlobalMemoryStatusEx");
+ if (globalMemoryStatusEx != 0)
+ if (globalMemoryStatusEx(&stat))
+ return stat.ullTotalPhys;
+ {
+ MEMORYSTATUS stat;
+ stat.dwLength = sizeof(stat);
+ GlobalMemoryStatus(&stat);
+ return stat.dwTotalPhys;
+ }
+ #endif
+}
+
+static UInt64 GetMaxRamSizeForProgram()
+{
+ UInt64 physSize = GetPhysicalRamSize();
+ const UInt64 kMinSysSize = (1 << 24);
+ if (physSize <= kMinSysSize)
+ physSize = 0;
+ else
+ physSize -= kMinSysSize;
+ const UInt64 kMinUseSize = (1 << 25);
+ if (physSize < kMinUseSize)
+ physSize = kMinUseSize;
+ return physSize;
+}
+
+bool CCompressDialog::OnInit()
+{
+ #ifdef LANG
+ LangSetWindowText(HWND(*this), 0x02000D00);
+ LangSetDlgItemsText(HWND(*this), kIDLangPairs, MY_SIZE_OF_ARRAY(kIDLangPairs) );
+ #endif
+ _password1Control.Attach(GetItem(IDC_COMPRESS_EDIT_PASSWORD1));
+ _password2Control.Attach(GetItem(IDC_COMPRESS_EDIT_PASSWORD2));
+ _password1Control.SetText(Info.Password);
+ _password2Control.SetText(Info.Password);
+ _encryptionMethod.Attach(GetItem(IDC_COMPRESS_COMBO_ENCRYPTION_METHOD));
+
+ m_ArchivePath.Attach(GetItem(IDC_COMPRESS_COMBO_ARCHIVE));
+ m_Format.Attach(GetItem(IDC_COMPRESS_COMBO_FORMAT));
+ m_Level.Attach(GetItem(IDC_COMPRESS_COMBO_LEVEL));
+ m_Method.Attach(GetItem(IDC_COMPRESS_COMBO_METHOD));
+ m_Dictionary.Attach(GetItem(IDC_COMPRESS_COMBO_DICTIONARY));
+ m_Order.Attach(GetItem(IDC_COMPRESS_COMBO_ORDER));
+
+ m_UpdateMode.Attach(GetItem(IDC_COMPRESS_COMBO_UPDATE_MODE));
+ m_Volume.Attach(GetItem(IDC_COMPRESS_COMBO_VOLUME));
+ m_Params.Attach(GetItem(IDC_COMPRESS_EDIT_PARAMETERS));
+
+ AddVolumeItems(m_Volume);
+
+ ReadCompressionInfo(m_RegistryInfo);
+ CheckButton(IDC_COMPRESS_CHECK_SHOW_PASSWORD, m_RegistryInfo.ShowPassword);
+ CheckButton(IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES, m_RegistryInfo.EncryptHeaders);
+
+ UpdatePasswordControl();
+
+ Info.ArchiverInfoIndex = 0;
+ int i;
+ for(i = 0; i < m_ArchiverInfoList.Size(); i++)
+ {
+ const CArchiverInfo &ai = m_ArchiverInfoList[i];
+ m_Format.AddString(ai.Name);
+ if (ai.Name.CompareNoCase(m_RegistryInfo.ArchiveType) == 0)
+ Info.ArchiverInfoIndex = i;
+ }
+ m_Format.SetCurSel(Info.ArchiverInfoIndex);
+
+ SetArchiveName(Info.ArchiveName);
+ SetLevel();
+ SetParams();
+
+ for(i = 0; i < m_RegistryInfo.HistoryArchives.Size() && i < kHistorySize; i++)
+ m_ArchivePath.AddString(m_RegistryInfo.HistoryArchives[i]);
+
+ m_UpdateMode.AddString(LangString(IDS_COMPRESS_UPDATE_MODE_ADD, 0x02000DA1));
+ m_UpdateMode.AddString(LangString(IDS_COMPRESS_UPDATE_MODE_UPDATE, 0x02000DA2));
+ m_UpdateMode.AddString(LangString(IDS_COMPRESS_UPDATE_MODE_FRESH, 0x02000DA3));
+ m_UpdateMode.AddString(LangString(IDS_COMPRESS_UPDATE_MODE_SYNCHRONIZE, 0x02000DA4));
+
+ m_UpdateMode.SetCurSel(0);
+
+ Info.Solid = m_RegistryInfo.Solid;
+ Info.MultiThread = m_RegistryInfo.MultiThread;
+
+ CheckButton(IDC_COMPRESS_SOLID, Info.Solid);
+ CheckButton(IDC_COMPRESS_MULTI_THREAD, Info.MultiThread);
+ CheckButton(IDC_COMPRESS_SFX, Info.SFXMode);
+
+ CheckControlsEnable();
+
+ OnButtonSFX();
+
+ SetEncryptionMethod();
+ return CModalDialog::OnInit();
+}
+
+namespace NCompressDialog
+{
+ bool CInfo::GetFullPathName(UString &result) const
+ {
+ NDirectory::MySetCurrentDirectory(CurrentDirPrefix);
+ return MyGetFullPathName(ArchiveName, result);
+ }
+}
+
+void CCompressDialog::UpdatePasswordControl()
+{
+ bool showPassword = IsShowPasswordChecked();
+ TCHAR c = showPassword ? 0: TEXT('*');
+ _password1Control.SetPasswordChar(c);
+ _password2Control.SetPasswordChar(c);
+ UString password;
+ _password1Control.GetText(password);
+ _password1Control.SetText(password);
+ _password2Control.GetText(password);
+ _password2Control.SetText(password);
+
+ int cmdShow = showPassword ? SW_HIDE : SW_SHOW;
+ ShowItem(IDC_STATIC_COMPRESS_PASSWORD2, cmdShow);
+ _password2Control.Show(cmdShow);
+}
+
+bool CCompressDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch(buttonID)
+ {
+ case IDC_COMPRESS_BUTTON_SET_ARCHIVE:
+ {
+ OnButtonSetArchive();
+ return true;
+ }
+ case IDC_COMPRESS_SFX:
+ {
+ OnButtonSFX();
+ return true;
+ }
+ case IDC_COMPRESS_CHECK_SHOW_PASSWORD:
+ {
+ UpdatePasswordControl();
+ return true;
+ }
+ case IDC_COMPRESS_MULTI_THREAD:
+ {
+ SetMemoryUsage();
+ return true;
+ }
+ }
+ return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
+}
+
+static bool IsMultiProcessor()
+{
+ return NSystem::GetNumberOfProcessors() > 1;
+}
+
+void CCompressDialog::CheckSFXControlsEnable()
+{
+ const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()];
+ bool enable = fi.SFX;
+ if (enable)
+ {
+ int methodID = GetMethodID();
+ enable = (methodID == -1 || IsMethodSupportedBySfx(methodID));
+ }
+ if (!enable)
+ CheckButton(IDC_COMPRESS_SFX, false);
+ EnableItem(IDC_COMPRESS_SFX, enable);
+}
+
+void CCompressDialog::CheckVolumeEnable()
+{
+ bool isSFX = IsSFX();
+ m_Volume.Enable(!isSFX);
+ if (isSFX)
+ m_Volume.SetText(TEXT(""));
+}
+
+void CCompressDialog::CheckControlsEnable()
+{
+ const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()];
+ Info.SolidIsAllowed = fi.Solid;
+ bool multiThreadEnable = fi.MultiThread & IsMultiProcessor();
+ Info.MultiThreadIsAllowed = multiThreadEnable;
+ Info.EncryptHeadersIsAllowed = fi.EncryptFileNames;
+
+ EnableItem(IDC_COMPRESS_SOLID, fi.Solid);
+ EnableItem(IDC_COMPRESS_MULTI_THREAD, multiThreadEnable);
+ CheckSFXControlsEnable();
+ CheckVolumeEnable();
+
+ EnableItem(IDC_COMPRESS_ENCRYPTION, fi.Encrypt);
+
+ EnableItem(IDC_STATIC_COMPRESS_PASSWORD1, fi.Encrypt);
+ EnableItem(IDC_STATIC_COMPRESS_PASSWORD2, fi.Encrypt);
+ EnableItem(IDC_COMPRESS_EDIT_PASSWORD1, fi.Encrypt);
+ EnableItem(IDC_COMPRESS_EDIT_PASSWORD2, fi.Encrypt);
+ EnableItem(IDC_COMPRESS_CHECK_SHOW_PASSWORD, fi.Encrypt);
+
+ EnableItem(IDC_STATIC_COMPRESS_ENCRYPTION_METHOD, fi.Encrypt);
+ EnableItem(IDC_COMPRESS_COMBO_ENCRYPTION_METHOD, fi.Encrypt);
+ EnableItem(IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES, fi.EncryptFileNames);
+}
+
+bool CCompressDialog::IsSFX()
+{
+ CWindow sfxButton = GetItem(IDC_COMPRESS_SFX);
+ return sfxButton.IsEnabled() && IsButtonCheckedBool(IDC_COMPRESS_SFX);
+}
+
+void CCompressDialog::OnButtonSFX()
+{
+ SetMethod();
+
+ UString fileName;
+ m_ArchivePath.GetText(fileName);
+ int dotPos = fileName.ReverseFind(L'.');
+ int slashPos = fileName.ReverseFind(L'\\');
+ if (dotPos < 0 || dotPos <= slashPos)
+ dotPos = -1;
+ bool isSFX = IsSFX();
+ if (isSFX)
+ {
+ if (dotPos >= 0)
+ fileName = fileName.Left(dotPos);
+ fileName += kExeExt;
+ m_ArchivePath.SetText(fileName);
+ }
+ else
+ {
+ if (dotPos >= 0)
+ {
+ UString ext = fileName.Mid(dotPos);
+ if (ext.CompareNoCase(kExeExt) == 0)
+ {
+ fileName = fileName.Left(dotPos);
+ m_ArchivePath.SetText(fileName);
+ }
+ }
+ SetArchiveName2(false); // it's for OnInit
+ }
+
+ CheckVolumeEnable();
+}
+
+void CCompressDialog::OnButtonSetArchive()
+{
+ UString fileName;
+ m_ArchivePath.GetText(fileName);
+ fileName.Trim();
+ Info.ArchiveName = fileName;
+ UString fullFileName;
+ if (!Info.GetFullPathName(fullFileName))
+ {
+ fullFileName = Info.ArchiveName;
+ return;
+ }
+ UString title = LangString(IDS_COMPRESS_SET_ARCHIVE_DIALOG_TITLE, 0x02000D90);
+ UString s = LangString(IDS_OPEN_TYPE_ALL_FILES, 0x02000DB1);
+ s += L" (*.*)";
+ UString resPath;
+ if (!MyGetOpenFileName(HWND(*this), title, fullFileName, s, resPath))
+ return;
+ m_ArchivePath.SetText(resPath);
+}
+
+// in ExtractDialog.cpp
+extern void AddUniqueString(UStringVector &strings, const UString &srcString);
+
+static bool IsAsciiString(const UString &s)
+{
+ for (int i = 0; i < s.Length(); i++)
+ {
+ wchar_t c = s[i];
+ if (c < 0x20 || c > 0x7F)
+ return false;
+ }
+ return true;
+}
+
+void CCompressDialog::OnOK()
+{
+ _password1Control.GetText(Info.Password);
+ if (IsZipFormat())
+ {
+ if (!IsAsciiString(Info.Password))
+ {
+ MyMessageBoxResource(*this, IDS_PASSWORD_USE_ASCII, 0x02000B11);
+ return;
+ }
+ UString method = GetEncryptionMethodSpec();
+ method.MakeUpper();
+ if (method.Find(L"AES") == 0)
+ {
+ if (Info.Password.Length() > 99)
+ {
+ MyMessageBoxResource(*this, IDS_PASSWORD_IS_TOO_LONG, 0x02000B12);
+ return;
+ }
+ }
+ }
+ if (!IsShowPasswordChecked())
+ {
+ UString password2;
+ _password2Control.GetText(password2);
+ if (password2 != Info.Password)
+ {
+ MyMessageBoxResource(*this, IDS_PASSWORD_PASSWORDS_DO_NOT_MATCH, 0x02000B10);
+ return;
+ }
+ }
+
+ SaveOptionsInMem();
+ UString s;
+ m_ArchivePath.GetText(s);
+ s.Trim();
+ m_RegistryInfo.HistoryArchives.Clear();
+ AddUniqueString(m_RegistryInfo.HistoryArchives, s);
+ Info.ArchiveName = s;
+ Info.UpdateMode = NCompressDialog::NUpdateMode::EEnum(m_UpdateMode.GetCurSel());
+
+ Info.Level = GetLevelSpec();
+ Info.Dictionary = GetDictionarySpec();
+ Info.Order = GetOrderSpec();
+ Info.OrderMode = GetOrderMode();
+ Info.Method = GetMethodSpec();
+ Info.EncryptionMethod = GetEncryptionMethodSpec();
+
+ Info.ArchiverInfoIndex = m_Format.GetCurSel();
+
+ Info.SFXMode = IsSFX();
+ m_RegistryInfo.Solid = Info.Solid = IsButtonCheckedBool(IDC_COMPRESS_SOLID);
+ m_RegistryInfo.MultiThread = Info.MultiThread = IsMultiThread();
+ m_RegistryInfo.EncryptHeaders = Info.EncryptHeaders = IsButtonCheckedBool(IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES);
+
+ m_Params.GetText(Info.Options);
+ UString volumeString;
+ m_Volume.GetText(volumeString);
+ volumeString.Trim();
+ Info.VolumeSizes.Clear();
+ if (!volumeString.IsEmpty())
+ {
+ if (!ParseVolumeSizes(volumeString, Info.VolumeSizes))
+ {
+ MyMessageBoxResource(*this, IDS_COMPRESS_INCORRECT_VOLUME_SIZE, 0x02000D41);
+ return;
+ }
+ if (!Info.VolumeSizes.IsEmpty())
+ {
+ const UInt64 volumeSize = Info.VolumeSizes.Back();
+ if (volumeSize < (100 << 10))
+ {
+ wchar_t s[32];
+ ConvertUInt64ToString(volumeSize, s);
+ if (::MessageBoxW(*this, MyFormatNew(IDS_COMPRESS_SPLIT_CONFIRM_MESSAGE, 0x02000D42, s),
+ L"7-Zip", MB_YESNOCANCEL | MB_ICONQUESTION | MB_TASKMODAL) != IDYES)
+ return;
+ }
+ }
+ }
+
+ for(int i = 0; i < m_ArchivePath.GetCount(); i++)
+ {
+ UString sTemp;
+ m_ArchivePath.GetLBText(i, sTemp);
+ sTemp.Trim();
+ AddUniqueString(m_RegistryInfo.HistoryArchives, sTemp);
+ }
+ if (m_RegistryInfo.HistoryArchives.Size() > kHistorySize)
+ m_RegistryInfo.HistoryArchives.DeleteBack();
+
+ ////////////////////
+ // Method
+
+ m_RegistryInfo.Level = Info.Level;
+ m_RegistryInfo.ArchiveType = m_ArchiverInfoList[Info.ArchiverInfoIndex].Name;
+
+ m_RegistryInfo.ShowPassword = IsShowPasswordChecked();
+
+ SaveCompressionInfo(m_RegistryInfo);
+
+ CModalDialog::OnOK();
+}
+
+static LPCWSTR kHelpTopic = L"fm/plugins/7-zip/add.htm";
+
+void CCompressDialog::OnHelp()
+{
+ ShowHelpWindow(NULL, kHelpTopic);
+}
+
+bool CCompressDialog::OnCommand(int code, int itemID, LPARAM lParam)
+{
+ if (code == CBN_SELCHANGE)
+ {
+ switch(itemID)
+ {
+ case IDC_COMPRESS_COMBO_FORMAT:
+ {
+ OnChangeFormat();
+ return true;
+ }
+ case IDC_COMPRESS_COMBO_LEVEL:
+ {
+ const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()];
+ int index = FindRegistryFormatAlways(ai.Name);
+ NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index];
+ fo.ResetForLevelChange();
+ SetMethod();
+ CheckSFXNameChange();
+ return true;
+ }
+ case IDC_COMPRESS_COMBO_METHOD:
+ {
+ SetDictionary();
+ SetOrder();
+ CheckSFXNameChange();
+ return true;
+ }
+ case IDC_COMPRESS_COMBO_DICTIONARY:
+ case IDC_COMPRESS_COMBO_ORDER:
+ {
+ SetMemoryUsage();
+ return true;
+ }
+ }
+ }
+ return CModalDialog::OnCommand(code, itemID, lParam);
+}
+
+void CCompressDialog::CheckSFXNameChange()
+{
+ bool isSFX = IsSFX();
+ CheckSFXControlsEnable();
+ if (isSFX != IsSFX())
+ SetArchiveName2(isSFX);
+}
+
+void CCompressDialog::SetArchiveName2(bool prevWasSFX)
+{
+ UString fileName;
+ m_ArchivePath.GetText(fileName);
+ const CArchiverInfo &prevArchiverInfo = m_ArchiverInfoList[m_PrevFormat];
+ if (prevArchiverInfo.KeepName || Info.KeepName)
+ {
+ UString prevExtension = prevArchiverInfo.GetMainExtension();
+ if (prevWasSFX)
+ prevExtension = kExeExt;
+ else
+ prevExtension = UString('.') + prevExtension;
+ const int prevExtensionLen = prevExtension.Length();
+ if (fileName.Length() >= prevExtensionLen)
+ if (fileName.Right(prevExtensionLen).CompareNoCase(prevExtension) == 0)
+ fileName = fileName.Left(fileName.Length() - prevExtensionLen);
+ }
+ SetArchiveName(fileName);
+}
+
+void CCompressDialog::OnChangeFormat()
+{
+ bool isSFX = IsSFX();
+ SaveOptionsInMem();
+ SetLevel();
+ SetParams();
+ CheckControlsEnable();
+ SetArchiveName2(isSFX);
+ SetEncryptionMethod();
+}
+
+// if type.KeepName then use OriginalFileName
+// else if !KeepName remove extension
+// add new extension
+
+void CCompressDialog::SetArchiveName(const UString &name)
+{
+ UString fileName = name;
+ Info.ArchiverInfoIndex = m_Format.GetCurSel();
+ const CArchiverInfo &ai = m_ArchiverInfoList[Info.ArchiverInfoIndex];
+ m_PrevFormat = Info.ArchiverInfoIndex;
+ if (ai.KeepName)
+ {
+ fileName = OriginalFileName;
+ }
+ else
+ {
+ if (!Info.KeepName)
+ {
+ int dotPos = fileName.ReverseFind('.');
+ int slashPos = MyMax(fileName.ReverseFind('\\'), fileName.ReverseFind('/'));
+ if (dotPos >= 0 && dotPos > slashPos + 1)
+ fileName = fileName.Left(dotPos);
+ }
+ }
+
+ if (IsSFX())
+ fileName += kExeExt;
+ else
+ {
+ fileName += L'.';
+ fileName += ai.GetMainExtension();
+ }
+ m_ArchivePath.SetText(fileName);
+}
+
+int CCompressDialog::FindRegistryFormat(const UString &name)
+{
+ for (int i = 0; i < m_RegistryInfo.FormatOptionsVector.Size(); i++)
+ {
+ const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[i];
+ if (GetUnicodeString(fo.FormatID) == name)
+ return i;
+ }
+ return -1;
+}
+
+int CCompressDialog::FindRegistryFormatAlways(const UString &name)
+{
+ int index = FindRegistryFormat(name);
+ if (index < 0)
+ {
+ NCompression::CFormatOptions fo;
+ fo.FormatID = GetSystemString(name);
+ index = m_RegistryInfo.FormatOptionsVector.Add(fo);
+ }
+ return index;
+}
+
+int CCompressDialog::GetStaticFormatIndex()
+{
+ int formatIndex = m_Format.GetCurSel();
+ const CArchiverInfo &ai = m_ArchiverInfoList[formatIndex];
+ for (int i = 0; i < MY_SIZE_OF_ARRAY(g_Formats); i++)
+ if (ai.Name.CompareNoCase(g_Formats[i].Name) == 0)
+ return i;
+ return 0; // -1;
+}
+
+void CCompressDialog::SetNearestSelectComboBox(
+ NControl::CComboBox &comboBox, UInt32 value)
+{
+ for (int i = comboBox.GetCount() - 1; i >= 0; i--)
+ if ((UInt32)comboBox.GetItemData(i) <= value)
+ {
+ comboBox.SetCurSel(i);
+ return;
+ }
+ if (comboBox.GetCount() > 0)
+ comboBox.SetCurSel(0);
+}
+
+void CCompressDialog::SetLevel()
+{
+ m_Level.ResetContent();
+ const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()];
+ const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()];
+ int index = FindRegistryFormat(ai.Name);
+ UInt32 level = kNormal;
+ if (index >= 0)
+ {
+ const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index];
+ if (fo.Level <= kUltra)
+ level = fo.Level;
+ else
+ level = kUltra;
+ }
+ int i;
+ for (i = 0; i <= kUltra; i++)
+ {
+ if ((fi.LevelsMask & (1 << i)) != 0)
+ {
+ const CLevelInfo &levelInfo = g_Levels[i];
+ int index = (int)m_Level.AddString(LangString(levelInfo.ResourceID, levelInfo.LangID));
+ m_Level.SetItemData(index, i);
+ }
+ }
+ SetNearestSelectComboBox(m_Level, level);
+ SetMethod();
+}
+
+int CCompressDialog::GetLevel()
+{
+ if (m_Level.GetCount() <= 0)
+ return -1;
+ return (int)m_Level.GetItemData(m_Level.GetCurSel());
+}
+
+int CCompressDialog::GetLevelSpec()
+{
+ if (m_Level.GetCount() <= 1)
+ return -1;
+ return GetLevel();
+}
+
+int CCompressDialog::GetLevel2()
+{
+ int level = GetLevel();
+ if (level < 0)
+ level = 5;
+ return level;
+}
+
+bool CCompressDialog::IsMultiThread()
+{
+ /*
+ const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()];
+ bool multiThreadEnable = fi.MultiThread & IsMultiProcessor();
+ if (!multiThreadEnable)
+ return false;
+ */
+ return IsButtonCheckedBool(IDC_COMPRESS_MULTI_THREAD);
+}
+
+void CCompressDialog::SetMethod()
+{
+ m_Method.ResetContent();
+ if (GetLevel() <= 0)
+ {
+ SetDictionary();
+ SetOrder();
+ return;
+ }
+ const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()];
+ const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()];
+ int index = FindRegistryFormat(ai.Name);
+ UString defaultMethod;
+ if (index >= 0)
+ {
+ const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index];
+ defaultMethod = fo.Method;
+ }
+ bool isSfx = IsSFX();
+ for(int m = 0; m < fi.NumMethods; m++)
+ {
+ EMethodID methodID = fi.MathodIDs[m];
+ if (isSfx)
+ if (!IsMethodSupportedBySfx(methodID))
+ continue;
+ const LPCWSTR method = kMethodsNames[methodID];
+ int itemIndex = (int)m_Method.AddString(GetSystemString(method));
+ if (defaultMethod.CompareNoCase(method) == 0 || m == 0)
+ m_Method.SetCurSel(itemIndex);
+ }
+ SetDictionary();
+ SetOrder();
+}
+
+bool CCompressDialog::IsZipFormat()
+{
+ const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()];
+ return (ai.Name.CompareNoCase(L"zip") == 0);
+}
+
+void CCompressDialog::SetEncryptionMethod()
+{
+ _encryptionMethod.ResetContent();
+ const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()];
+ if (ai.Name.CompareNoCase(L"7z") == 0)
+ {
+ _encryptionMethod.AddString(TEXT("AES-256"));
+ _encryptionMethod.SetCurSel(0);
+ }
+ else if (ai.Name.CompareNoCase(L"zip") == 0)
+ {
+ int index = FindRegistryFormat(ai.Name);
+ UString encryptionMethod;
+ if (index >= 0)
+ {
+ const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index];
+ encryptionMethod = fo.EncryptionMethod;
+ }
+ _encryptionMethod.AddString(TEXT("ZipCrypto"));
+ _encryptionMethod.AddString(TEXT("AES-256"));
+ _encryptionMethod.SetCurSel(encryptionMethod.Find(L"AES") == 0 ? 1 : 0);
+ }
+}
+
+int CCompressDialog::GetMethodID()
+{
+ UString methodName;
+ m_Method.GetText(methodName);
+ for (int i = 0; i < MY_SIZE_OF_ARRAY(kMethodsNames); i++)
+ if (methodName.CompareNoCase(kMethodsNames[i]) == 0)
+ return i;
+ return -1;
+}
+
+UString CCompressDialog::GetMethodSpec()
+{
+ if (m_Method.GetCount() <= 1)
+ return UString();
+ UString result;
+ m_Method.GetText(result);
+ return result;
+}
+
+UString CCompressDialog::GetEncryptionMethodSpec()
+{
+ if (m_Method.GetCount() <= 1)
+ return UString();
+ if (_encryptionMethod.GetCurSel() <= 0)
+ return UString();
+ UString result;
+ _encryptionMethod.GetText(result);
+ result.Replace(L"-", L"");
+ return result;
+}
+
+int CCompressDialog::AddDictionarySize(UInt32 size, bool kilo, bool maga)
+{
+ UInt32 sizePrint = size;
+ if (kilo)
+ sizePrint >>= 10;
+ else if (maga)
+ sizePrint >>= 20;
+ TCHAR s[40];
+ ConvertUInt64ToString(sizePrint, s);
+ if (kilo)
+ lstrcat(s, TEXT(" K"));
+ else if (maga)
+ lstrcat(s, TEXT(" M"));
+ else
+ lstrcat(s, TEXT(" "));
+ lstrcat(s, TEXT("B"));
+ int index = (int)m_Dictionary.AddString(s);
+ m_Dictionary.SetItemData(index, size);
+ return index;
+}
+
+int CCompressDialog::AddDictionarySize(UInt32 size)
+{
+ if (size > 0)
+ {
+ if ((size & 0xFFFFF) == 0)
+ return AddDictionarySize(size, false, true);
+ if ((size & 0x3FF) == 0)
+ return AddDictionarySize(size, true, false);
+ }
+ return AddDictionarySize(size, false, false);
+}
+
+void CCompressDialog::SetDictionary()
+{
+ m_Dictionary.ResetContent();
+ const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()];
+ int index = FindRegistryFormat(ai.Name);
+ UInt32 defaultDictionary = UInt32(-1);
+ if (index >= 0)
+ {
+ const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index];
+ if (fo.Method.CompareNoCase(GetMethodSpec()) == 0)
+ defaultDictionary = fo.Dictionary;
+ }
+ int methodID = GetMethodID();
+ int level = GetLevel2();
+ if (methodID < 0)
+ {
+ SetMemoryUsage();
+ return;
+ }
+ const UInt64 maxRamSize = GetMaxRamSizeForProgram();
+ switch (methodID)
+ {
+ case kLZMA:
+ {
+ static const UInt32 kMinDicSize = (1 << 16);
+ if (defaultDictionary == UInt32(-1))
+ {
+ if (level >= 9)
+ defaultDictionary = (1 << 26);
+ else if (level >= 7)
+ defaultDictionary = (1 << 24);
+ else if (level >= 5)
+ defaultDictionary = (1 << 22);
+ else if (level >= 3)
+ defaultDictionary = (1 << 20);
+ else
+ defaultDictionary = (kMinDicSize);
+ }
+ int i;
+ AddDictionarySize(kMinDicSize);
+ m_Dictionary.SetCurSel(0);
+ for (i = 20; i <= 30; i++)
+ for (int j = 0; j < 2; j++)
+ {
+ if (i == 20 && j > 0)
+ continue;
+ UInt32 dictionary = (1 << i) + (j << (i - 1));
+ if (dictionary >
+ #ifdef _WIN64
+ (1 << 30)
+ #else
+ (1 << 27)
+ #endif
+ )
+ continue;
+ AddDictionarySize(dictionary);
+ UInt64 decomprSize;
+ UInt64 requiredComprSize = GetMemoryUsage(dictionary, false, decomprSize);
+ if (dictionary <= defaultDictionary && requiredComprSize <= maxRamSize)
+ m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1);
+ }
+
+ // SetNearestSelectComboBox(m_Dictionary, defaultDictionary);
+ break;
+ }
+ case kPPMd:
+ {
+ if (defaultDictionary == UInt32(-1))
+ {
+ if (level >= 9)
+ defaultDictionary = (192 << 20);
+ else if (level >= 7)
+ defaultDictionary = (64 << 20);
+ else if (level >= 5)
+ defaultDictionary = (16 << 20);
+ else
+ defaultDictionary = (4 << 20);
+ }
+ int i;
+ for (i = 20; i < 31; i++)
+ for (int j = 0; j < 2; j++)
+ {
+ if (i == 20 && j > 0)
+ continue;
+ UInt32 dictionary = (1 << i) + (j << (i - 1));
+ if (dictionary >= (1 << 31))
+ continue;
+ AddDictionarySize(dictionary);
+ UInt64 decomprSize;
+ UInt64 requiredComprSize = GetMemoryUsage(dictionary, false, decomprSize);
+ if (dictionary <= defaultDictionary && requiredComprSize <= maxRamSize || m_Dictionary.GetCount() == 0)
+ m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1);
+ }
+ SetNearestSelectComboBox(m_Dictionary, defaultDictionary);
+ break;
+ }
+ case kDeflate:
+ {
+ AddDictionarySize(32 << 10);
+ m_Dictionary.SetCurSel(0);
+ break;
+ }
+ case kDeflate64:
+ {
+ AddDictionarySize(64 << 10);
+ m_Dictionary.SetCurSel(0);
+ break;
+ }
+ case kBZip2:
+ {
+ UInt32 defaultDictionary;
+ if (level >= 5)
+ defaultDictionary = (900 << 10);
+ else if (level >= 3)
+ defaultDictionary = (500 << 10);
+ else
+ defaultDictionary = (100 << 10);
+ for (int i = 1; i <= 9; i++)
+ {
+ UInt32 dictionary = (i * 100) << 10;
+ AddDictionarySize(dictionary);
+ if (dictionary <= defaultDictionary || m_Dictionary.GetCount() == 0)
+ m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1);
+ }
+ break;
+ }
+ }
+ SetMemoryUsage();
+}
+
+UInt32 CCompressDialog::GetDictionary()
+{
+ if (m_Dictionary.GetCount() <= 0)
+ return (UInt32)-1;
+ return (UInt32)m_Dictionary.GetItemData(m_Dictionary.GetCurSel());
+}
+
+UInt32 CCompressDialog::GetDictionarySpec()
+{
+ if (m_Dictionary.GetCount() <= 1)
+ return (UInt32)-1;
+ return GetDictionary();
+}
+
+int CCompressDialog::AddOrder(UInt32 size)
+{
+ TCHAR s[40];
+ ConvertUInt64ToString(size, s);
+ int index = (int)m_Order.AddString(s);
+ m_Order.SetItemData(index, size);
+ return index;
+}
+
+void CCompressDialog::SetOrder()
+{
+ m_Order.ResetContent();
+ const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()];
+ int index = FindRegistryFormat(ai.Name);
+ UInt32 defaultOrder = UInt32(-1);
+ if (index >= 0)
+ {
+ const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index];
+ if (fo.Method.CompareNoCase(GetMethodSpec()) == 0)
+ defaultOrder = fo.Order;
+ }
+ int methodID = GetMethodID();
+ int level = GetLevel2();
+ if (methodID < 0)
+ {
+ SetMemoryUsage();
+ return;
+ }
+ switch (methodID)
+ {
+ case kLZMA:
+ {
+ if (defaultOrder == UInt32(-1))
+ defaultOrder = (level >= 7) ? 64 : 32;
+ for (int i = 3; i <= 8; i++)
+ for (int j = 0; j < 2; j++)
+ {
+ UInt32 order = (1 << i) + (j << (i - 1));
+ if (order <= 256)
+ AddOrder(order);
+ }
+ AddOrder(273);
+ SetNearestSelectComboBox(m_Order, defaultOrder);
+ break;
+ }
+ case kPPMd:
+ {
+ if (defaultOrder == UInt32(-1))
+ {
+ if (level >= 9)
+ defaultOrder = 32;
+ else if (level >= 7)
+ defaultOrder = 16;
+ else if (level >= 5)
+ defaultOrder = 6;
+ else
+ defaultOrder = 4;
+ }
+ int i;
+ AddOrder(2);
+ AddOrder(3);
+ for (i = 2; i < 8; i++)
+ for (int j = 0; j < 4; j++)
+ {
+ UInt32 order = (1 << i) + (j << (i - 2));
+ if (order < 32)
+ AddOrder(order);
+ }
+ AddOrder(32);
+ SetNearestSelectComboBox(m_Order, defaultOrder);
+ break;
+ }
+ case kDeflate:
+ case kDeflate64:
+ {
+ if (defaultOrder == UInt32(-1))
+ {
+ if (level >= 9)
+ defaultOrder = 128;
+ else if (level >= 7)
+ defaultOrder = 64;
+ else
+ defaultOrder = 32;
+ }
+ int i;
+ for (i = 3; i <= 8; i++)
+ for (int j = 0; j < 2; j++)
+ {
+ UInt32 order = (1 << i) + (j << (i - 1));
+ if (order <= 256)
+ AddOrder(order);
+ }
+ AddOrder(methodID == kDeflate64 ? 257 : 258);
+ SetNearestSelectComboBox(m_Order, defaultOrder);
+ break;
+ }
+ case kBZip2:
+ {
+ break;
+ }
+ }
+ SetMemoryUsage();
+}
+
+bool CCompressDialog::GetOrderMode()
+{
+ switch (GetMethodID())
+ {
+ case kPPMd:
+ return true;
+ }
+ return false;
+}
+
+UInt32 CCompressDialog::GetOrder()
+{
+ if (m_Order.GetCount() <= 0)
+ return (UInt32)-1;
+ return (UInt32)m_Order.GetItemData(m_Order.GetCurSel());
+}
+
+UInt32 CCompressDialog::GetOrderSpec()
+{
+ if (m_Order.GetCount() <= 1)
+ return (UInt32)-1;
+ return GetOrder();
+}
+
+UInt64 CCompressDialog::GetMemoryUsage(UInt32 dictionary, bool isMultiThread, UInt64 &decompressMemory)
+{
+ decompressMemory = UInt64(Int64(-1));
+ int level = GetLevel2();
+ if (level == 0)
+ {
+ decompressMemory = (1 << 20);
+ return decompressMemory;
+ }
+ UInt64 size = 0;
+
+ const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()];
+ if (fi.Filter && level >= 9)
+ size += (12 << 20) * 2 + (5 << 20);
+ switch (GetMethodID())
+ {
+ case kLZMA:
+ {
+ UInt32 hs = dictionary - 1;
+ hs |= (hs >> 1);
+ hs |= (hs >> 2);
+ hs |= (hs >> 4);
+ hs |= (hs >> 8);
+ hs >>= 1;
+ hs |= 0xFFFF;
+ if (hs > (1 << 24))
+ hs >>= 1;
+ hs++;
+ size += hs * 4;
+ size += (UInt64)dictionary * 11 / 2;
+ if (level >= 5)
+ size += dictionary * 4;
+ size += (2 << 20);
+ if (isMultiThread && level >= 5)
+ size += (2 << 20) + (4 << 20);
+
+ decompressMemory = dictionary + (2 << 20);
+ return size;
+ }
+ case kPPMd:
+ {
+ decompressMemory = dictionary + (2 << 20);
+ return size + decompressMemory;
+ }
+ case kDeflate:
+ case kDeflate64:
+ {
+ UInt32 order = GetOrder();
+ if (order == UInt32(-1))
+ order = 32;
+ if (level >= 7)
+ size += (1 << 20);
+ size += 3 << 20;
+ decompressMemory = (2 << 20);
+ return size;
+ }
+ case kBZip2:
+ {
+ decompressMemory = (7 << 20);
+ UInt64 memForOneThread = (10 << 20);
+ if (isMultiThread)
+ memForOneThread *= NSystem::GetNumberOfProcessors();
+ return size + (10 << 20);
+ }
+ }
+ return UInt64(Int64(-1));
+}
+
+UInt64 CCompressDialog::GetMemoryUsage(UInt64 &decompressMemory)
+{
+ return GetMemoryUsage(GetDictionary(), IsMultiThread(), decompressMemory);
+}
+
+void CCompressDialog::PrintMemUsage(UINT res, UInt64 value)
+{
+ if (value == (UInt64)Int64(-1))
+ {
+ SetItemText(res, TEXT("?"));
+ return;
+ }
+ value = (value + (1 << 20) - 1) >> 20;
+ TCHAR s[40];
+ ConvertUInt64ToString(value, s);
+ lstrcat(s, TEXT(" MB"));
+ SetItemText(res, s);
+}
+
+void CCompressDialog::SetMemoryUsage()
+{
+ UInt64 decompressMem;
+ UInt64 memUsage = GetMemoryUsage(decompressMem);
+ PrintMemUsage(IDC_STATIC_COMPRESS_MEMORY_VALUE, memUsage);
+ PrintMemUsage(IDC_STATIC_COMPRESS_MEMORY_DE_VALUE, decompressMem);
+}
+
+void CCompressDialog::SetParams()
+{
+ const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()];
+ m_Params.SetText(TEXT(""));
+ int index = FindRegistryFormat(ai.Name);
+ if (index >= 0)
+ {
+ const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index];
+ m_Params.SetText(fo.Options);
+ }
+}
+
+void CCompressDialog::SaveOptionsInMem()
+{
+ const CArchiverInfo &ai = m_ArchiverInfoList[Info.ArchiverInfoIndex];
+ int index = FindRegistryFormatAlways(ai.Name);
+ m_Params.GetText(Info.Options);
+ Info.Options.Trim();
+ NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index];
+ fo.Options = Info.Options;
+ fo.Level = GetLevelSpec();
+ fo.Dictionary = GetDictionarySpec();
+ fo.Order = GetOrderSpec();
+ fo.Method = GetMethodSpec();
+ fo.EncryptionMethod = GetEncryptionMethodSpec();
+}
diff --git a/CPP/7zip/UI/GUI/CompressDialog.h b/CPP/7zip/UI/GUI/CompressDialog.h
new file mode 100755
index 00000000..87cf5d79
--- /dev/null
+++ b/CPP/7zip/UI/GUI/CompressDialog.h
@@ -0,0 +1,171 @@
+// CompressDialog.h
+
+#ifndef __COMPRESSDIALOG_H
+#define __COMPRESSDIALOG_H
+
+#include "../Common/ZipRegistry.h"
+#include "../Common/ArchiverInfo.h"
+#include "../Resource/CompressDialog/resource.h"
+
+#include "Windows/Control/Dialog.h"
+#include "Windows/Control/Edit.h"
+#include "Windows/Control/ComboBox.h"
+
+namespace NCompressDialog
+{
+ namespace NUpdateMode
+ {
+ enum EEnum
+ {
+ kAdd,
+ kUpdate,
+ kFresh,
+ kSynchronize,
+ };
+ }
+ struct CInfo
+ {
+ NUpdateMode::EEnum UpdateMode;
+ bool SolidIsAllowed;
+ bool Solid;
+
+ bool MultiThreadIsAllowed;
+ bool MultiThread;
+
+ CRecordVector<UInt64> VolumeSizes;
+
+ UInt32 Level;
+ UString Method;
+ UInt32 Dictionary;
+ bool OrderMode;
+ UInt32 Order;
+ UString Options;
+
+ UString EncryptionMethod;
+
+ bool SFXMode;
+
+ UString ArchiveName; // in: Relative for ; out: abs
+ UString CurrentDirPrefix;
+ bool KeepName;
+
+ bool GetFullPathName(UString &result) const;
+
+ int ArchiverInfoIndex;
+
+ UString Password;
+ bool EncryptHeadersIsAllowed;
+ bool EncryptHeaders;
+
+ void Init()
+ {
+ Level = Dictionary = Order = UInt32(-1);
+ OrderMode = false;
+ Method.Empty();
+ Options.Empty();
+ EncryptionMethod.Empty();
+ }
+ CInfo()
+ {
+ Init();
+ }
+ };
+}
+
+class CCompressDialog: public NWindows::NControl::CModalDialog
+{
+ NWindows::NControl::CComboBox m_ArchivePath;
+ NWindows::NControl::CComboBox m_Format;
+ NWindows::NControl::CComboBox m_Level;
+ NWindows::NControl::CComboBox m_Method;
+ NWindows::NControl::CComboBox m_Dictionary;
+ NWindows::NControl::CComboBox m_Order;
+ NWindows::NControl::CComboBox m_UpdateMode;
+ NWindows::NControl::CComboBox m_Volume;
+ NWindows::NControl::CDialogChildControl m_Params;
+
+ NWindows::NControl::CEdit _password1Control;
+ NWindows::NControl::CEdit _password2Control;
+ NWindows::NControl::CComboBox _encryptionMethod;
+
+ NCompression::CInfo m_RegistryInfo;
+
+ int m_PrevFormat;
+ void SetArchiveName(const UString &name);
+ int FindRegistryFormat(const UString &name);
+ int FindRegistryFormatAlways(const UString &name);
+
+ void OnChangeFormat();
+ void CheckSFXNameChange();
+ void SetArchiveName2(bool prevWasSFX);
+
+ int GetStaticFormatIndex();
+
+ void SetNearestSelectComboBox(NWindows::NControl::CComboBox &comboBox, UInt32 value);
+
+ void SetLevel();
+ int GetLevel();
+ int GetLevelSpec();
+ int GetLevel2();
+ bool IsMultiThread();
+
+ void SetMethod();
+ int GetMethodID();
+ UString GetMethodSpec();
+ UString GetEncryptionMethodSpec();
+
+ bool IsZipFormat();
+
+ void SetEncryptionMethod();
+
+ int AddDictionarySize(UInt32 size, bool kilo, bool maga);
+ int AddDictionarySize(UInt32 size);
+
+ void SetDictionary();
+ UInt32 GetDictionary();
+ UInt32 GetDictionarySpec();
+
+ int AddOrder(UInt32 size);
+ void SetOrder();
+ bool GetOrderMode();
+ UInt32 GetOrder();
+ UInt32 GetOrderSpec();
+
+ UInt64 GetMemoryUsage(UInt32 dictionary, bool isMultiThread, UInt64 &decompressMemory);
+ UInt64 GetMemoryUsage(UInt64 &decompressMemory);
+ void PrintMemUsage(UINT res, UInt64 value);
+ void SetMemoryUsage();
+ void SetParams();
+ void SaveOptionsInMem();
+
+ void UpdatePasswordControl();
+ bool IsShowPasswordChecked() const
+ { return IsButtonChecked(IDC_COMPRESS_CHECK_SHOW_PASSWORD) == BST_CHECKED; }
+public:
+ CObjectVector<CArchiverInfo> m_ArchiverInfoList;
+
+ NCompressDialog::CInfo Info;
+ UString OriginalFileName; // for bzip2, gzip2
+
+ INT_PTR Create(HWND wndParent = 0)
+ { return CModalDialog::Create(IDD_DIALOG_COMPRESS, wndParent); }
+
+protected:
+
+ void CheckSFXControlsEnable();
+ void CheckVolumeEnable();
+ void CheckControlsEnable();
+
+ void OnButtonSetArchive();
+ bool IsSFX();
+ void OnButtonSFX();
+
+ virtual bool OnInit();
+ virtual bool OnCommand(int code, int itemID, LPARAM lParam);
+ virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
+ virtual void OnOK();
+ virtual void OnHelp();
+
+};
+
+#endif
diff --git a/CPP/7zip/UI/GUI/ExtractDialog.cpp b/CPP/7zip/UI/GUI/ExtractDialog.cpp
new file mode 100755
index 00000000..55c871ad
--- /dev/null
+++ b/CPP/7zip/UI/GUI/ExtractDialog.cpp
@@ -0,0 +1,371 @@
+// ExtractDialog.cpp
+
+#include "StdAfx.h"
+
+// #include <HtmlHelp.h>
+
+#include "ExtractDialog.h"
+
+#include "Common/StringConvert.h"
+#include "Windows/Shell.h"
+#include "Windows/FileName.h"
+#include "Windows/FileDir.h"
+#include "Windows/ResourceString.h"
+
+#ifndef NO_REGISTRY
+#include "../../FileManager/HelpUtils.h"
+#endif
+
+#include "../Common/ZipRegistry.h"
+
+#include "../../FileManager/LangUtils.h"
+
+#include "../Resource/Extract/resource.h"
+#include "../Resource/ExtractDialog/resource.h"
+
+// #include "Help/Context/Extract.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NName;
+
+static const int kPathModeButtons[] =
+{
+ IDC_EXTRACT_RADIO_FULL_PATHNAMES,
+ IDC_EXTRACT_RADIO_CURRENT_PATHNAMES,
+ IDC_EXTRACT_RADIO_NO_PATHNAMES
+};
+
+static const NExtract::NPathMode::EEnum kPathModeButtonsVals[] =
+{
+ NExtract::NPathMode::kFullPathnames,
+ NExtract::NPathMode::kCurrentPathnames,
+ NExtract::NPathMode::kNoPathnames
+};
+
+static const int kNumPathnamesButtons = sizeof(kPathModeButtons) / sizeof(kPathModeButtons[0]);
+
+static const int kOverwriteButtons[] =
+{
+ IDC_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE,
+ IDC_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT,
+ IDC_EXTRACT_RADIO_SKIP_EXISTING_FILES,
+ IDC_EXTRACT_RADIO_AUTO_RENAME,
+ IDC_EXTRACT_RADIO_AUTO_RENAME_EXISTING,
+};
+
+static const NExtract::NOverwriteMode::EEnum kOverwriteButtonsVals[] =
+{
+ NExtract::NOverwriteMode::kAskBefore,
+ NExtract::NOverwriteMode::kWithoutPrompt,
+ NExtract::NOverwriteMode::kSkipExisting,
+ NExtract::NOverwriteMode::kAutoRename,
+ NExtract::NOverwriteMode::kAutoRenameExisting
+};
+
+static const int kNumOverwriteButtons = sizeof(kOverwriteButtons) / sizeof(kOverwriteButtons[0]);
+
+/*
+static const int kFilesButtons[] =
+{
+ IDC_EXTRACT_RADIO_SELECTED_FILES,
+ IDC_EXTRACT_RADIO_ALL_FILES
+};
+static const int kNumFilesButtons = sizeof(kFilesButtons) / sizeof(kFilesButtons[0]);
+*/
+
+#ifndef _SFX
+void CExtractDialog::GetPathMode()
+{
+ for (int i = 0; i < kNumPathnamesButtons; i++)
+ if(IsButtonCheckedBool(kPathModeButtons[i]))
+ {
+ PathMode = kPathModeButtonsVals[i];
+ return;
+ }
+ throw 1;
+}
+
+void CExtractDialog::SetPathMode()
+{
+ for (int j = 0; j < 2; j++)
+ {
+ for (int i = 0; i < kNumPathnamesButtons; i++)
+ if(PathMode == kPathModeButtonsVals[i])
+ {
+ CheckRadioButton(kPathModeButtons[0], kPathModeButtons[kNumPathnamesButtons - 1],
+ kPathModeButtons[i]);
+ return;
+ }
+ PathMode = kPathModeButtonsVals[0];
+ }
+ throw 1;
+}
+
+void CExtractDialog::GetOverwriteMode()
+{
+ for (int i = 0; i < kNumOverwriteButtons; i++)
+ if(IsButtonCheckedBool(kOverwriteButtons[i]))
+ {
+ OverwriteMode = kOverwriteButtonsVals[i];
+ return;
+ }
+ throw 0;
+}
+
+void CExtractDialog::SetOverwriteMode()
+{
+ for (int j = 0; j < 2; j++)
+ {
+ for (int i = 0; i < kNumOverwriteButtons; i++)
+ if(OverwriteMode == kOverwriteButtonsVals[i])
+ {
+ CheckRadioButton(kOverwriteButtons[0], kOverwriteButtons[kNumOverwriteButtons - 1],
+ kOverwriteButtons[i]);
+ return;
+ }
+ OverwriteMode = kOverwriteButtonsVals[0];
+ }
+ throw 1;
+}
+
+/*
+int CExtractDialog::GetFilesMode() const
+{
+ for (int i = 0; i < kNumFilesButtons; i++)
+ if(IsButtonCheckedBool(kFilesButtons[i]))
+ return i;
+ throw 0;
+}
+*/
+
+#endif
+
+#ifdef LANG
+static CIDLangPair kIDLangPairs[] =
+{
+ { IDC_STATIC_EXTRACT_EXTRACT_TO, 0x02000801 },
+ { IDC_EXTRACT_PATH_MODE, 0x02000810 },
+ { IDC_EXTRACT_RADIO_FULL_PATHNAMES, 0x02000811 },
+ { IDC_EXTRACT_RADIO_CURRENT_PATHNAMES, 0x02000812 },
+ { IDC_EXTRACT_RADIO_NO_PATHNAMES, 0x02000813 },
+ { IDC_EXTRACT_OVERWRITE_MODE, 0x02000820 },
+ { IDC_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE, 0x02000821 },
+ { IDC_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT, 0x02000822 },
+ { IDC_EXTRACT_RADIO_SKIP_EXISTING_FILES, 0x02000823 },
+ { IDC_EXTRACT_RADIO_AUTO_RENAME, 0x02000824 },
+ { IDC_EXTRACT_RADIO_AUTO_RENAME_EXISTING, 0x02000825 },
+ { IDC_EXTRACT_FILES, 0x02000830 },
+ { IDC_EXTRACT_RADIO_SELECTED_FILES, 0x02000831 },
+ { IDC_EXTRACT_RADIO_ALL_FILES, 0x02000832 },
+ { IDC_EXTRACT_PASSWORD, 0x02000802 },
+ { IDC_EXTRACT_CHECK_SHOW_PASSWORD, 0x02000B02 },
+ { IDOK, 0x02000702 },
+ { IDCANCEL, 0x02000710 },
+ { IDHELP, 0x02000720 }
+
+};
+#endif
+
+// static const int kWildcardsButtonIndex = 2;
+
+static const int kHistorySize = 8;
+
+bool CExtractDialog::OnInit()
+{
+ #ifdef LANG
+ LangSetWindowText(HWND(*this), 0x02000800);
+ LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
+ #endif
+ #ifndef _SFX
+ _passwordControl.Attach(GetItem(IDC_EXTRACT_EDIT_PASSWORD));
+ _passwordControl.SetText(Password);
+ _passwordControl.SetPasswordChar(TEXT('*'));
+ #endif
+
+ NExtract::CInfo extractionInfo;
+
+ #ifdef NO_REGISTRY
+ PathMode = NExtract::NPathMode::kFullPathnames;
+ OverwriteMode = NExtract::NOverwriteMode::kAskBefore;
+ // extractionInfo.Paths = NExtract::NPathMode::kFullPathnames;
+ #else
+ ReadExtractionInfo(extractionInfo);
+ CheckButton(IDC_EXTRACT_CHECK_SHOW_PASSWORD, extractionInfo.ShowPassword);
+ UpdatePasswordControl();
+ PathMode = extractionInfo.PathMode;
+ OverwriteMode = extractionInfo.OverwriteMode;
+ #endif
+
+ _path.Attach(GetItem(IDC_EXTRACT_COMBO_PATH));
+
+ _path.SetText(DirectoryPath);
+
+ #ifndef NO_REGISTRY
+ for(int i = 0; i < extractionInfo.Paths.Size() && i < kHistorySize; i++)
+ _path.AddString(extractionInfo.Paths[i]);
+ #endif
+
+ /*
+ if(extractionInfo.Paths.Size() > 0)
+ _path.SetCurSel(0);
+ else
+ _path.SetCurSel(-1);
+ */
+
+
+
+ #ifndef _SFX
+ SetPathMode();
+ SetOverwriteMode();
+
+ /*
+ CheckRadioButton(kFilesButtons[0], kFilesButtons[kNumFilesButtons - 1],
+ kFilesButtons[_filesMode]);
+ */
+
+ // CWindow selectedFilesWindow = GetItem(IDC_EXTRACT_RADIO_SELECTED_FILES);
+ // selectedFilesWindow.Enable(_enableSelectedFilesButton);
+
+
+ #endif
+
+
+ // CWindow filesWindow = GetItem(IDC_EXTRACT_RADIO_FILES);
+ // filesWindow.Enable(_enableFilesButton);
+
+ // UpdateWildCardState();
+ return CModalDialog::OnInit();
+}
+
+#ifndef _SFX
+void CExtractDialog::UpdatePasswordControl()
+{
+ _passwordControl.SetPasswordChar((IsButtonChecked(
+ IDC_EXTRACT_CHECK_SHOW_PASSWORD) == BST_CHECKED) ? 0: TEXT('*'));
+ UString password;
+ _passwordControl.GetText(password);
+ _passwordControl.SetText(password);
+}
+#endif
+
+bool CExtractDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ /*
+ for (int i = 0; i < kNumFilesButtons; i++)
+ if (buttonID == kFilesButtons[i])
+ {
+ UpdateWildCardState();
+ return true;
+ }
+ */
+ switch(buttonID)
+ {
+ case IDC_EXTRACT_BUTTON_SET_PATH:
+ OnButtonSetPath();
+ return true;
+ #ifndef _SFX
+ case IDC_EXTRACT_CHECK_SHOW_PASSWORD:
+ {
+ UpdatePasswordControl();
+ return true;
+ }
+ #endif
+ }
+ return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
+}
+
+void CExtractDialog::OnButtonSetPath()
+{
+ UString currentPath;
+ _path.GetText(currentPath);
+ UString title = LangStringSpec(IDS_EXTRACT_SET_FOLDER, 0x02000881);
+ UString resultPath;
+ if (!NShell::BrowseForFolder(HWND(*this), title, currentPath, resultPath))
+ return;
+ #ifndef NO_REGISTRY
+ _path.SetCurSel(-1);
+ #endif
+ _path.SetText(resultPath);
+}
+
+void AddUniqueString(UStringVector &list, const UString &s)
+{
+ for(int i = 0; i < list.Size(); i++)
+ if (s.CompareNoCase(list[i]) == 0)
+ return;
+ list.Add(s);
+}
+
+void CExtractDialog::OnOK()
+{
+ #ifndef _SFX
+ GetPathMode();
+ GetOverwriteMode();
+ // _filesMode = (NExtractionDialog::NFilesMode::EEnum)GetFilesMode();
+
+ _passwordControl.GetText(Password);
+ #endif
+
+ NExtract::CInfo extractionInfo;
+ extractionInfo.PathMode = PathMode;
+ extractionInfo.OverwriteMode = OverwriteMode;
+ extractionInfo.ShowPassword = (IsButtonChecked(
+ IDC_EXTRACT_CHECK_SHOW_PASSWORD) == BST_CHECKED);
+
+ UString s;
+
+ #ifdef NO_REGISTRY
+
+ _path.GetText(s);
+
+ #else
+
+ int currentItem = _path.GetCurSel();
+ if(currentItem == CB_ERR)
+ {
+ _path.GetText(s);
+ if(_path.GetCount() >= kHistorySize)
+ currentItem = _path.GetCount() - 1;
+ }
+ else
+ _path.GetLBText(currentItem, s);
+
+ #endif
+
+ s.Trim();
+ #ifndef _SFX
+ AddUniqueString(extractionInfo.Paths, s);
+ #endif
+ DirectoryPath = s;
+ #ifndef NO_REGISTRY
+ for(int i = 0; i < _path.GetCount(); i++)
+ if(i != currentItem)
+ {
+ UString sTemp;
+ _path.GetLBText(i, sTemp);
+ sTemp.Trim();
+ AddUniqueString(extractionInfo.Paths, sTemp);
+ }
+ SaveExtractionInfo(extractionInfo);
+ #endif
+ CModalDialog::OnOK();
+}
+
+/*
+void CExtractDialog::UpdateWildCardState()
+{
+ // UpdateData(TRUE);
+ // m_Wildcards.EnableWindow(BoolToBOOL(m_Files == kWildcardsButtonIndex));
+}
+*/
+
+#ifndef NO_REGISTRY
+static LPCWSTR kHelpTopic = L"fm/plugins/7-zip/extract.htm";
+void CExtractDialog::OnHelp()
+{
+ ShowHelpWindow(NULL, kHelpTopic);
+ CModalDialog::OnHelp();
+}
+#endif
+
diff --git a/CPP/7zip/UI/GUI/ExtractDialog.h b/CPP/7zip/UI/GUI/ExtractDialog.h
new file mode 100755
index 00000000..0020c693
--- /dev/null
+++ b/CPP/7zip/UI/GUI/ExtractDialog.h
@@ -0,0 +1,77 @@
+// ExtractDialog.h
+
+#ifndef __EXTRACTDIALOG_H
+#define __EXTRACTDIALOG_H
+
+#include "resource.h"
+
+#include "Windows/Control/Dialog.h"
+#include "Windows/Control/Edit.h"
+#include "Windows/Control/ComboBox.h"
+
+#ifndef NO_REGISTRY
+#include "../Common/ZipRegistry.h"
+#endif
+#include "../Common/ExtractMode.h"
+
+namespace NExtractionDialog
+{
+ /*
+ namespace NFilesMode
+ {
+ enum EEnum
+ {
+ kSelected,
+ kAll,
+ kSpecified
+ };
+ }
+ */
+}
+
+class CExtractDialog: public NWindows::NControl::CModalDialog
+{
+ #ifdef NO_REGISTRY
+ NWindows::NControl::CDialogChildControl _path;
+ #else
+ NWindows::NControl::CComboBox _path;
+ #endif
+
+ #ifndef _SFX
+ NWindows::NControl::CEdit _passwordControl;
+ #endif
+
+ #ifndef _SFX
+ void GetPathMode();
+ void SetPathMode();
+ void GetOverwriteMode();
+ void SetOverwriteMode();
+ // int GetFilesMode() const;
+ void UpdatePasswordControl();
+ #endif
+
+ void OnButtonSetPath();
+
+ virtual bool OnInit();
+ virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
+ virtual void OnOK();
+ #ifndef NO_REGISTRY
+ virtual void OnHelp();
+ #endif
+public:
+ // bool _enableSelectedFilesButton;
+ // bool _enableFilesButton;
+ // NExtractionDialog::NFilesMode::EEnum FilesMode;
+
+ UString DirectoryPath;
+ #ifndef _SFX
+ UString Password;
+ #endif
+ NExtract::NPathMode::EEnum PathMode;
+ NExtract::NOverwriteMode::EEnum OverwriteMode;
+
+ INT_PTR Create(HWND aWndParent = 0)
+ { return CModalDialog::Create(IDD_DIALOG_EXTRACT, aWndParent); }
+};
+
+#endif
diff --git a/CPP/7zip/UI/GUI/ExtractGUI.cpp b/CPP/7zip/UI/GUI/ExtractGUI.cpp
new file mode 100755
index 00000000..395df5a9
--- /dev/null
+++ b/CPP/7zip/UI/GUI/ExtractGUI.cpp
@@ -0,0 +1,172 @@
+// ExtractGUI.cpp
+
+#include "StdAfx.h"
+
+#include "ExtractGUI.h"
+
+#include "Common/StringConvert.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/Error.h"
+#include "Windows/FileFind.h"
+#include "Windows/Thread.h"
+
+#include "../../FileManager/FormatUtils.h"
+#include "../../FileManager/ExtractCallback.h"
+#include "../../FileManager/LangUtils.h"
+
+#include "../Common/ArchiveExtractCallback.h"
+#include "../Explorer/MyMessages.h"
+#include "../Resource/Extract/resource.h"
+
+#include "OpenCallbackGUI.h"
+#include "ExtractDialog.h"
+
+using namespace NWindows;
+
+static const wchar_t *kIncorrectOutDir = L"Incorrect output directory path";
+
+struct CThreadExtracting
+{
+ CExtractCallbackImp *ExtractCallbackSpec;
+
+ UStringVector *ArchivePaths;
+ UStringVector *ArchivePathsFull;
+ const NWildcard::CCensorNode *WildcardCensor;
+ const CExtractOptions *Options;
+ COpenCallbackGUI *OpenCallback;
+ CMyComPtr<IExtractCallbackUI> ExtractCallback;
+
+ UString ErrorMessage;
+ HRESULT Result;
+
+ DWORD Process()
+ {
+ ExtractCallbackSpec->ProgressDialog.WaitCreating();
+ try
+ {
+ Result = DecompressArchives(*ArchivePaths, *ArchivePathsFull,
+ *WildcardCensor, *Options, OpenCallback, ExtractCallback, ErrorMessage);
+ }
+ catch(const UString &s)
+ {
+ ErrorMessage = s;
+ Result = E_FAIL;
+ }
+ catch(const wchar_t *s)
+ {
+ ErrorMessage = s;
+ Result = E_FAIL;
+ }
+ catch(const char *s)
+ {
+ ErrorMessage = GetUnicodeString(s);
+ Result = E_FAIL;
+ }
+ catch(...)
+ {
+ Result = E_FAIL;
+ }
+ ExtractCallbackSpec->ProgressDialog.MyClose();
+ return 0;
+ }
+ static DWORD WINAPI MyThreadFunction(void *param)
+ {
+ return ((CThreadExtracting *)param)->Process();
+ }
+};
+
+HRESULT ExtractGUI(
+ UStringVector &archivePaths,
+ UStringVector &archivePathsFull,
+ const NWildcard::CCensorNode &wildcardCensor,
+ CExtractOptions &options,
+ bool showDialog,
+ COpenCallbackGUI *openCallback,
+ CExtractCallbackImp *extractCallback)
+{
+ CThreadExtracting extracter;
+
+ if (!options.TestMode)
+ {
+ UString outputDir = options.OutputDir;
+ if (outputDir.IsEmpty())
+ NFile::NDirectory::MyGetCurrentDirectory(outputDir);
+ if (showDialog)
+ {
+ CExtractDialog dialog;
+ if (!NFile::NDirectory::MyGetFullPathName(outputDir, dialog.DirectoryPath))
+ {
+ MyMessageBox(kIncorrectOutDir);
+ return E_FAIL;
+ }
+ NFile::NName::NormalizeDirPathPrefix(dialog.DirectoryPath);
+
+ // dialog.OverwriteMode = options.OverwriteMode;
+ // dialog.PathMode = options.PathMode;
+
+ if(dialog.Create(0) != IDOK)
+ return E_ABORT;
+ outputDir = dialog.DirectoryPath;
+ options.OverwriteMode = dialog.OverwriteMode;
+ options.PathMode = dialog.PathMode;
+ #ifndef _SFX
+ openCallback->Password = dialog.Password;
+ openCallback->PasswordIsDefined = !dialog.Password.IsEmpty();
+ #endif
+ }
+ if (!NFile::NDirectory::MyGetFullPathName(outputDir, options.OutputDir))
+ {
+ MyMessageBox(kIncorrectOutDir);
+ return E_FAIL;
+ }
+ NFile::NName::NormalizeDirPathPrefix(options.OutputDir);
+
+ /*
+ if(!NFile::NDirectory::CreateComplexDirectory(options.OutputDir))
+ {
+ UString s = GetUnicodeString(NError::MyFormatMessage(GetLastError()));
+ UString s2 = MyFormatNew(IDS_CANNOT_CREATE_FOLDER,
+ #ifdef LANG
+ 0x02000603,
+ #endif
+ options.OutputDir);
+ MyMessageBox(s2 + UString(L"\n") + s);
+ return E_FAIL;
+ }
+ */
+ }
+
+ UString title = LangStringSpec(options.TestMode ? IDS_PROGRESS_TESTING : IDS_PROGRESS_EXTRACTING,
+ options.TestMode ? 0x02000F90: 0x02000890);
+
+ extracter.ExtractCallbackSpec = extractCallback;
+ extracter.ExtractCallback = extractCallback;
+ extracter.ExtractCallbackSpec->Init();
+
+ extracter.ArchivePaths = &archivePaths;
+ extracter.ArchivePathsFull = &archivePathsFull;
+ extracter.WildcardCensor = &wildcardCensor;
+ extracter.Options = &options;
+ extracter.OpenCallback = openCallback;
+
+ CThread thread;
+ if (!thread.Create(CThreadExtracting::MyThreadFunction, &extracter))
+ throw 271824;
+ extracter.ExtractCallbackSpec->StartProgressDialog(title);
+ if (extracter.Result == S_OK && options.TestMode &&
+ extracter.ExtractCallbackSpec->Messages.IsEmpty() &&
+ extracter.ExtractCallbackSpec->NumArchiveErrors == 0)
+ {
+ #ifndef _SFX
+ MessageBoxW(0, LangString(IDS_MESSAGE_NO_ERRORS, 0x02000608),
+ LangString(IDS_PROGRESS_TESTING, 0x02000F90), 0);
+ #endif
+ }
+ if (extracter.Result != S_OK)
+ if (!extracter.ErrorMessage.IsEmpty())
+ throw extracter.ErrorMessage;
+ return extracter.Result;
+}
+
+
diff --git a/CPP/7zip/UI/GUI/ExtractGUI.h b/CPP/7zip/UI/GUI/ExtractGUI.h
new file mode 100755
index 00000000..5a0b157d
--- /dev/null
+++ b/CPP/7zip/UI/GUI/ExtractGUI.h
@@ -0,0 +1,20 @@
+// GUI/ExtractGUI.h
+
+#ifndef __EXTRACT_GUI_H
+#define __EXTRACT_GUI_H
+
+#include "../Common/Extract.h"
+#include "OpenCallbackGUI.h"
+
+#include "../../FileManager/ExtractCallback.h"
+
+HRESULT ExtractGUI(
+ UStringVector &archivePaths,
+ UStringVector &archivePathsFull,
+ const NWildcard::CCensorNode &wildcardCensor,
+ CExtractOptions &options,
+ bool showDialog,
+ COpenCallbackGUI *openCallback,
+ CExtractCallbackImp *extractCallback);
+
+#endif
diff --git a/CPP/7zip/UI/GUI/FM.ico b/CPP/7zip/UI/GUI/FM.ico
new file mode 100755
index 00000000..3a0a34da
--- /dev/null
+++ b/CPP/7zip/UI/GUI/FM.ico
Binary files differ
diff --git a/CPP/7zip/UI/GUI/GUI.cpp b/CPP/7zip/UI/GUI/GUI.cpp
new file mode 100755
index 00000000..fe956dbd
--- /dev/null
+++ b/CPP/7zip/UI/GUI/GUI.cpp
@@ -0,0 +1,260 @@
+// GUI.cpp
+
+#include "StdAfx.h"
+
+#include <initguid.h>
+
+#include "Common/NewHandler.h"
+#include "Common/StringConvert.h"
+#include "Common/CommandLineParser.h"
+#include "Common/Exception.h"
+
+#include "Windows/COM.h"
+#include "Windows/FileMapping.h"
+#include "Windows/FileDir.h"
+#include "Windows/Synchronization.h"
+#include "Windows/Error.h"
+#include "Windows/FileName.h"
+#ifdef _WIN32
+#include "Windows/MemoryLock.h"
+#include "Common/Alloc.h"
+#endif
+
+#include "../../IStream.h"
+#include "../../IPassword.h"
+
+#include "../../FileManager/StringUtils.h"
+
+#include "../Common/ExitCode.h"
+#include "../Common/ArchiveCommandLine.h"
+
+#include "../Resource/Extract/resource.h"
+#include "../Explorer/MyMessages.h"
+
+#include "ExtractGUI.h"
+#include "UpdateGUI.h"
+
+using namespace NWindows;
+
+HINSTANCE g_hInstance;
+#ifndef _UNICODE
+bool g_IsNT = false;
+#endif
+
+static const wchar_t *kExceptionErrorMessage = L"Error:";
+static const wchar_t *kUserBreak = L"Break signaled";
+
+static const wchar_t *kMemoryExceptionMessage = L"ERROR: Can't allocate required memory!";
+static const wchar_t *kUnknownExceptionMessage = L"Unknown Error";
+static const wchar_t *kInternalExceptionMessage = L"Internal Error #";
+
+static const wchar_t *kIncorrectCommandMessage = L"Incorrect command";
+
+static void ErrorMessage(const wchar_t *message)
+{
+ MessageBoxW(0, message, L"7-Zip GUI", MB_ICONERROR);
+}
+
+int Main2()
+{
+ /*
+ TCHAR t[512];
+ GetCurrentDirectory(512, t);
+ ErrorMessage(t);
+ return 0;
+ */
+
+ UStringVector commandStrings;
+ NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
+ if(commandStrings.Size() <= 1)
+ {
+ MessageBoxW(0, L"Specify command", L"7-Zip", 0);
+ return 0;
+ }
+ commandStrings.Delete(0);
+
+ CArchiveCommandLineOptions options;
+ CArchiveCommandLineParser parser;
+
+ parser.Parse1(commandStrings, options);
+ parser.Parse2(options);
+
+ #ifdef _WIN32
+ if (options.LargePages)
+ NSecurity::EnableLockMemoryPrivilege();
+ #endif
+
+ bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
+
+ if (isExtractGroupCommand)
+ {
+ CExtractCallbackImp *ecs = new CExtractCallbackImp;
+ CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
+ ecs->PasswordIsDefined = options.PasswordEnabled;
+ ecs->Password = options.Password;
+ ecs->Init();
+
+ COpenCallbackGUI openCallback;
+ openCallback.PasswordIsDefined = options.PasswordEnabled;
+ openCallback.Password = options.Password;
+
+ CExtractOptions eo;
+ eo.StdOutMode = options.StdOutMode;
+ eo.OutputDir = options.OutputDir;
+ eo.YesToAll = options.YesToAll;
+ eo.OverwriteMode = options.OverwriteMode;
+ eo.PathMode = options.Command.GetPathMode();
+ eo.TestMode = options.Command.IsTestMode();
+ #ifdef COMPRESS_MT
+ eo.Properties = options.ExtractProperties;
+ #endif
+
+ HRESULT result = ExtractGUI(
+ options.ArchivePathsSorted,
+ options.ArchivePathsFullSorted,
+ options.WildcardCensor.Pairs.Front().Head,
+ eo, options.ShowDialog, &openCallback, ecs);
+ if (result != S_OK)
+ throw CSystemException(result);
+ if (ecs->Messages.Size() > 0 || ecs->NumArchiveErrors != 0)
+ return NExitCode::kFatalError;
+ }
+ else if (options.Command.IsFromUpdateGroup())
+ {
+ bool passwordIsDefined =
+ options.PasswordEnabled && !options.Password.IsEmpty();
+
+ COpenCallbackGUI openCallback;
+ openCallback.PasswordIsDefined = passwordIsDefined;
+ openCallback.Password = options.Password;
+
+ CUpdateCallbackGUI callback;
+ // callback.EnablePercents = options.EnablePercents;
+ callback.PasswordIsDefined = passwordIsDefined;
+ callback.AskPassword = options.PasswordEnabled && options.Password.IsEmpty();
+ callback.Password = options.Password;
+ // callback.StdOutMode = options.UpdateOptions.StdOutMode;
+ callback.Init();
+
+ CUpdateErrorInfo errorInfo;
+
+ HRESULT result = UpdateGUI(
+ options.WildcardCensor, options.UpdateOptions,
+ options.ShowDialog,
+ errorInfo, &openCallback, &callback);
+
+ if (result != S_OK)
+ {
+ if (!errorInfo.Message.IsEmpty())
+ ErrorMessage(errorInfo.Message);
+ throw CSystemException(result);
+ }
+ if (callback.FailedFiles.Size() > 0)
+ return NExitCode::kWarning;
+ }
+ else
+ {
+ ErrorMessage(L"Use correct command");
+ return 0;
+ }
+ return 0;
+}
+
+static bool inline IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+
+int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, LPSTR /* lpCmdLine */, int /* nCmdShow */)
+{
+ g_hInstance = hInstance;
+ #ifdef _UNICODE
+ if (!IsItWindowsNT())
+ {
+ MyMessageBox(L"This program requires Windows NT/2000/XP/2003");
+ return NExitCode::kFatalError;
+ }
+ #else
+ g_IsNT = IsItWindowsNT();
+ #endif
+
+ #ifdef _WIN32
+ SetLargePageSize();
+ #endif
+
+ InitCommonControls();
+
+ ReloadLang();
+
+ // setlocale(LC_COLLATE, ".ACP");
+ try
+ {
+ return Main2();
+ }
+ catch(const CNewException &)
+ {
+ MyMessageBox(kMemoryExceptionMessage);
+ return (NExitCode::kMemoryError);
+ }
+ catch(const CArchiveCommandLineException &e)
+ {
+ MyMessageBox(GetUnicodeString(e));
+ return (NExitCode::kUserError);
+ }
+ catch(const CSystemException &systemError)
+ {
+ if (systemError.ErrorCode == E_OUTOFMEMORY)
+ {
+ MyMessageBox(kMemoryExceptionMessage);
+ return (NExitCode::kMemoryError);
+ }
+ if (systemError.ErrorCode == E_ABORT)
+ {
+ // MyMessageBox(kUserBreak);
+ return (NExitCode::kUserBreak);
+ }
+ UString message;
+ NError::MyFormatMessage(systemError.ErrorCode, message);
+ MyMessageBox(message);
+ return (NExitCode::kFatalError);
+ }
+ /*
+ catch(NExitCode::EEnum &exitCode)
+ {
+ g_StdErr << kInternalExceptionMessage << exitCode << endl;
+ return (exitCode);
+ }
+ */
+ catch(const UString &s)
+ {
+ MyMessageBox(s);
+ return (NExitCode::kFatalError);
+ }
+ catch(const AString &s)
+ {
+ MyMessageBox(GetUnicodeString(s));
+ return (NExitCode::kFatalError);
+ }
+ catch(const char *s)
+ {
+ MyMessageBox(GetUnicodeString(s));
+ return (NExitCode::kFatalError);
+ }
+ /*
+ catch(int t)
+ {
+ g_StdErr << kInternalExceptionMessage << t << endl;
+ return (NExitCode::kFatalError);
+ }
+ */
+ catch(...)
+ {
+ MyMessageBox(kUnknownExceptionMessage);
+ return (NExitCode::kFatalError);
+ }
+}
+
diff --git a/CPP/7zip/UI/GUI/GUI.dsp b/CPP/7zip/UI/GUI/GUI.dsp
new file mode 100755
index 00000000..dadb9648
--- /dev/null
+++ b/CPP/7zip/UI/GUI/GUI.dsp
@@ -0,0 +1,904 @@
+# Microsoft Developer Studio Project File - Name="GUI" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=GUI - Win32 DebugU
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "GUI.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "GUI.mak" CFG="GUI - Win32 DebugU"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "GUI - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "GUI - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE "GUI - Win32 ReleaseU" (based on "Win32 (x86) Application")
+!MESSAGE "GUI - Win32 DebugU" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "GUI - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "COMPRESS_MT" /D "WIN_LONG_PATH" /Yu"stdafx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Program Files\7-Zip\7zg.exe" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "GUI - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
+# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "COMPRESS_MT" /D "WIN_LONG_PATH" /Yu"stdafx.h" /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Program Files\7-Zip\7zg.exe" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "GUI - Win32 ReleaseU"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ReleaseU"
+# PROP BASE Intermediate_Dir "ReleaseU"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ReleaseU"
+# PROP Intermediate_Dir "ReleaseU"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "COMPRESS_MT" /D "WIN_LONG_PATH" /Yu"stdafx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\UTIL\7zg.exe"
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Program Files\7-Zip\7zgn.exe" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "GUI - Win32 DebugU"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "DebugU"
+# PROP BASE Intermediate_Dir "DebugU"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "DebugU"
+# PROP Intermediate_Dir "DebugU"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
+# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "COMPRESS_MT" /D "WIN_LONG_PATH" /Yu"stdafx.h" /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\UTIL\7zg.exe" /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Program Files\7-Zip\7zgn.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "GUI - Win32 Release"
+# Name "GUI - Win32 Debug"
+# Name "GUI - Win32 ReleaseU"
+# Name "GUI - Win32 DebugU"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\7zG.exe.manifest
+# End Source File
+# Begin Source File
+
+SOURCE=.\FM.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"stdafx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "SDK"
+
+# PROP Default_Filter ""
+# 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\CommandLineParser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Lang.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Lang.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\ListFileUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\ListFileUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdInStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdInStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\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\StringToInt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringToInt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\TextConfig.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\TextConfig.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\UTFConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\UTFConvert.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Vector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Vector.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Group "Control"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\ComboBox.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\ComboBox.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\Dialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\Dialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\Edit.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\ListView.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\ListView.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Control\ProgressBar.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\..\Windows\CommonDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\CommonDialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Error.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Error.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\MemoryLock.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\MemoryLock.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Registry.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Registry.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\ResourceString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\ResourceString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Shell.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Shell.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Window.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Window.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "UI Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Common\ArchiveCommandLine.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiveCommandLine.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiveExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiveExtractCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiveOpenCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiveOpenCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiverInfo.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiverInfo.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\DefaultName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\DefaultName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\DirItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\EnumDirItems.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\EnumDirItems.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ExitCode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\Extract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\Extract.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ExtractingFilePath.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ExtractingFilePath.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ExtractMode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\HandlerLoader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\IFileExtractCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\OpenArchive.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\OpenArchive.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\Property.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\PropIDUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\PropIDUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\SetProperties.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\SetProperties.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\SortUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\SortUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\TempFiles.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\TempFiles.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\Update.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\Update.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdateAction.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdateAction.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdateCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdateCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdatePair.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdatePair.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdateProduce.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\UpdateProduce.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\WorkDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\WorkDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ZipRegistry.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ZipRegistry.h
+# End Source File
+# End Group
+# Begin Group "Explorer"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Explorer\MyMessages.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Explorer\MyMessages.h
+# End Source File
+# End Group
+# Begin Group "Dialogs"
+
+# PROP Default_Filter ""
+# Begin Group "Progress"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\ProgressDialog2\ProgressDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\ProgressDialog2\ProgressDialog.h
+# End Source File
+# End Group
+# Begin Group "Messages"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\MessagesDialog\MessagesDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\MessagesDialog\MessagesDialog.h
+# End Source File
+# End Group
+# Begin Group "Overwtite"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\OverwriteDialog\OverwriteDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\OverwriteDialog\OverwriteDialog.h
+# End Source File
+# End Group
+# Begin Group "Password"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\PasswordDialog\PasswordDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\PasswordDialog\PasswordDialog.h
+# End Source File
+# End Group
+# Begin Group "Compress Dialog"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\CompressDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CompressDialog.h
+# End Source File
+# End Group
+# Begin Group "Extract Dialog"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\ExtractDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ExtractDialog.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "FM Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\FileManager\ExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\ExtractCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\FolderInterface.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\FormatUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\FormatUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\HelpUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\HelpUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\LangUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\LangUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\OpenCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\OpenCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\ProgramLocation.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\ProgramLocation.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\RegistryUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\RegistryUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\SplitUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\SplitUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\StringUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\StringUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\UpdateCallback100.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\UpdateCallback100.h
+# End Source File
+# End Group
+# Begin Group "Engine"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\ExtractGUI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ExtractGUI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\GUI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\OpenCallbackGUI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\OpenCallbackGUI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\UpdateCallbackGUI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\UpdateCallbackGUI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\UpdateGUI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\UpdateGUI.h
+# End Source File
+# End Group
+# Begin Group "7-zip Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\FilePathAutoRename.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilePathAutoRename.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# 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/CPP/7zip/UI/GUI/GUI.dsw b/CPP/7zip/UI/GUI/GUI.dsw
new file mode 100755
index 00000000..85d33484
--- /dev/null
+++ b/CPP/7zip/UI/GUI/GUI.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "GUI"=.\GUI.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/CPP/7zip/UI/GUI/OpenCallbackGUI.cpp b/CPP/7zip/UI/GUI/OpenCallbackGUI.cpp
new file mode 100755
index 00000000..bc6cf393
--- /dev/null
+++ b/CPP/7zip/UI/GUI/OpenCallbackGUI.cpp
@@ -0,0 +1,65 @@
+// OpenCallbackGUI.cpp
+
+#include "StdAfx.h"
+
+#include "OpenCallbackGUI.h"
+
+#include "Common/StdOutStream.h"
+#include "Common/StdInStream.h"
+#include "Common/StringConvert.h"
+
+#ifndef _NO_CRYPTO
+#include "../../FileManager/Resource/PasswordDialog/PasswordDialog.h"
+#endif
+
+HRESULT COpenCallbackGUI::CheckBreak()
+{
+ return S_OK;
+}
+
+HRESULT COpenCallbackGUI::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */)
+{
+ return S_OK;
+}
+
+HRESULT COpenCallbackGUI::SetCompleted(const UInt64 * /* files */, const UInt64 * /* bytes */)
+{
+ return S_OK;
+}
+
+#ifndef _NO_CRYPTO
+HRESULT COpenCallbackGUI::CryptoGetTextPassword(BSTR *password)
+{
+ PasswordWasAsked = true;
+ if (!PasswordIsDefined)
+ {
+ CPasswordDialog dialog;
+ if (dialog.Create(ParentWindow) == IDCANCEL)
+ return E_ABORT;
+ Password = dialog.Password;
+ PasswordIsDefined = true;
+ }
+ CMyComBSTR tempName(Password);
+ *password = tempName.Detach();
+ return S_OK;
+}
+
+HRESULT COpenCallbackGUI::GetPasswordIfAny(UString &password)
+{
+ if (PasswordIsDefined)
+ password = Password;
+ return S_OK;
+}
+
+bool COpenCallbackGUI::WasPasswordAsked()
+{
+ return PasswordWasAsked;
+}
+
+void COpenCallbackGUI::ClearPasswordWasAskedFlag()
+{
+ PasswordWasAsked = false;
+}
+
+#endif
+
diff --git a/CPP/7zip/UI/GUI/OpenCallbackGUI.h b/CPP/7zip/UI/GUI/OpenCallbackGUI.h
new file mode 100755
index 00000000..6b531d3c
--- /dev/null
+++ b/CPP/7zip/UI/GUI/OpenCallbackGUI.h
@@ -0,0 +1,35 @@
+// OpenCallbackGUI.h
+
+#ifndef __OPEN_CALLBACK_GUI_H
+#define __OPEN_CALLBACK_GUI_H
+
+#include "../Common/ArchiveOpenCallback.h"
+
+class COpenCallbackGUI: public IOpenCallbackUI
+{
+public:
+ HRESULT CheckBreak();
+ HRESULT SetTotal(const UInt64 *files, const UInt64 *bytes);
+ HRESULT SetCompleted(const UInt64 *files, const UInt64 *bytes);
+ #ifndef _NO_CRYPTO
+ HRESULT CryptoGetTextPassword(BSTR *password);
+ HRESULT GetPasswordIfAny(UString &password);
+ bool WasPasswordAsked();
+ void ClearPasswordWasAskedFlag();
+
+ bool PasswordIsDefined;
+ UString Password;
+ bool PasswordWasAsked;
+ #endif
+
+ HWND ParentWindow;
+
+ COpenCallbackGUI():
+ #ifndef _NO_CRYPTO
+ PasswordIsDefined(false),
+ PasswordWasAsked(false),
+ #endif
+ ParentWindow(0) {}
+};
+
+#endif
diff --git a/CPP/7zip/UI/GUI/StdAfx.cpp b/CPP/7zip/UI/GUI/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/CPP/7zip/UI/GUI/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/CPP/7zip/UI/GUI/StdAfx.h b/CPP/7zip/UI/GUI/StdAfx.h
new file mode 100755
index 00000000..46ea51cf
--- /dev/null
+++ b/CPP/7zip/UI/GUI/StdAfx.h
@@ -0,0 +1,13 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+#include <commctrl.h>
+#include <shlobj.h>
+#include <stdio.h>
+
+#include "Common/NewHandler.h"
+
+#endif
diff --git a/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp b/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp
new file mode 100755
index 00000000..eff29953
--- /dev/null
+++ b/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp
@@ -0,0 +1,167 @@
+// UpdateCallbackGUI.cpp
+
+#include "StdAfx.h"
+
+#include "UpdateCallbackGUI.h"
+
+#include "Common/StringConvert.h"
+#include "Common/IntToString.h"
+#include "Common/Defs.h"
+
+#include "Windows/PropVariant.h"
+#include "Windows/Error.h"
+#include "../../FileManager/Resource/MessagesDialog/MessagesDialog.h"
+#include "../../FileManager/Resource/PasswordDialog/PasswordDialog.h"
+
+using namespace NWindows;
+
+CUpdateCallbackGUI::~CUpdateCallbackGUI()
+{
+ if (!Messages.IsEmpty())
+ {
+ CMessagesDialog messagesDialog;
+ messagesDialog.Messages = &Messages;
+ messagesDialog.Create(ParentWindow);
+ }
+}
+
+void CUpdateCallbackGUI::Init()
+{
+ FailedFiles.Clear();
+ Messages.Clear();
+ NumArchiveErrors = 0;
+}
+
+void CUpdateCallbackGUI::AddErrorMessage(LPCWSTR message)
+{
+ Messages.Add(message);
+}
+
+void CUpdateCallbackGUI::AddErrorMessage(const wchar_t *name, DWORD systemError)
+{
+ AddErrorMessage(
+ UString(L"WARNING: ") +
+ NError::MyFormatMessageW(systemError) +
+ UString(L": ") +
+ UString(name));
+}
+
+HRESULT CUpdateCallbackGUI::OpenResult(const wchar_t *name, HRESULT result)
+{
+ if (result != S_OK)
+ {
+ AddErrorMessage (UString(L"Error: ") + name +
+ UString(L" is not supported archive"));
+ }
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackGUI::StartScanning()
+{
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackGUI::CanNotFindError(const wchar_t *name, DWORD systemError)
+{
+ FailedFiles.Add(name);
+ AddErrorMessage(name, systemError);
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackGUI::FinishScanning()
+{
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackGUI::StartArchive(const wchar_t *name, bool /* updating */)
+{
+ ProgressDialog.ProgressSynch.SetTitleFileName(name);
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackGUI::FinishArchive()
+{
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackGUI::CheckBreak()
+{
+ for (;;)
+ {
+ if(ProgressDialog.ProgressSynch.GetStopped())
+ return E_ABORT;
+ if(!ProgressDialog.ProgressSynch.GetPaused())
+ break;
+ ::Sleep(100);
+ }
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackGUI::Finilize()
+{
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackGUI::SetTotal(UInt64 total)
+{
+ ProgressDialog.ProgressSynch.SetProgress(total, 0);
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackGUI::SetCompleted(const UInt64 *completeValue)
+{
+ RINOK(CheckBreak());
+ if (completeValue != NULL)
+ ProgressDialog.ProgressSynch.SetPos(*completeValue);
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackGUI::GetStream(const wchar_t *name, bool /* isAnti */)
+{
+ ProgressDialog.ProgressSynch.SetCurrentFileName(name);
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackGUI::OpenFileError(const wchar_t *name, DWORD systemError)
+{
+ FailedFiles.Add(name);
+ // if (systemError == ERROR_SHARING_VIOLATION)
+ {
+ AddErrorMessage(name, systemError);
+ return S_FALSE;
+ }
+ // return systemError;
+}
+
+HRESULT CUpdateCallbackGUI::SetOperationResult(Int32 /* operationResult */)
+{
+ return S_OK;
+}
+
+HRESULT CUpdateCallbackGUI::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
+{
+ if (!PasswordIsDefined)
+ {
+ if (AskPassword)
+ {
+ CPasswordDialog dialog;
+ if (dialog.Create(ParentWindow) == IDCANCEL)
+ return E_ABORT;
+ Password = dialog.Password;
+ PasswordIsDefined = true;
+ }
+ }
+ *passwordIsDefined = BoolToInt(PasswordIsDefined);
+ CMyComBSTR tempName(Password);
+ *password = tempName.Detach();
+ return S_OK;
+}
+
+/*
+It doesn't work, since main stream waits Dialog
+HRESULT CUpdateCallbackGUI::CloseProgress()
+{
+ ProgressDialog.MyClose();
+ return S_OK;
+};
+*/ \ No newline at end of file
diff --git a/CPP/7zip/UI/GUI/UpdateCallbackGUI.h b/CPP/7zip/UI/GUI/UpdateCallbackGUI.h
new file mode 100755
index 00000000..16f0220c
--- /dev/null
+++ b/CPP/7zip/UI/GUI/UpdateCallbackGUI.h
@@ -0,0 +1,63 @@
+// UpdateCallbackGUI.h
+
+#ifndef __UPDATE_CALLBACK_GUI_H
+#define __UPDATE_CALLBACK_GUI_H
+
+#include "../Common/Update.h"
+#include "../../FileManager/Resource/ProgressDialog2/ProgressDialog.h"
+
+class CUpdateCallbackGUI: public IUpdateCallbackUI2
+{
+public:
+ // bool StdOutMode;
+ bool PasswordIsDefined;
+ UString Password;
+ bool AskPassword;
+
+ CUpdateCallbackGUI():
+ PasswordIsDefined(false),
+ AskPassword(false),
+ // StdOutMode(false)
+ ParentWindow(0)
+ {}
+
+ ~CUpdateCallbackGUI();
+ void Init();
+
+ HRESULT OpenResult(const wchar_t *name, HRESULT result);
+
+ HRESULT StartScanning();
+ HRESULT CanNotFindError(const wchar_t *name, DWORD systemError);
+ HRESULT FinishScanning();
+
+ HRESULT StartArchive(const wchar_t *name, bool updating);
+ HRESULT FinishArchive();
+
+ HRESULT CheckBreak();
+ HRESULT Finilize();
+ HRESULT SetTotal(UInt64 total);
+ HRESULT SetCompleted(const UInt64 *completeValue);
+
+ HRESULT GetStream(const wchar_t *name, bool isAnti);
+ HRESULT OpenFileError(const wchar_t *name, DWORD systemError);
+ HRESULT SetOperationResult(Int32 operationResult);
+ HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password);
+
+ // HRESULT CloseProgress();
+
+ UStringVector FailedFiles;
+
+ CProgressDialog ProgressDialog;
+ HWND ParentWindow;
+ void StartProgressDialog(const UString &title)
+ {
+ ProgressDialog.Create(title, ParentWindow);
+ }
+
+ UStringVector Messages;
+ int NumArchiveErrors;
+ void AddErrorMessage(LPCWSTR message);
+ void AddErrorMessage(const wchar_t *name, DWORD systemError);
+};
+
+#endif
diff --git a/CPP/7zip/UI/GUI/UpdateGUI.cpp b/CPP/7zip/UI/GUI/UpdateGUI.cpp
new file mode 100755
index 00000000..e39e7faf
--- /dev/null
+++ b/CPP/7zip/UI/GUI/UpdateGUI.cpp
@@ -0,0 +1,397 @@
+// UpdateGUI.cpp
+
+#include "StdAfx.h"
+
+#include "UpdateGUI.h"
+
+#include "resource.h"
+#include "Common/StringConvert.h"
+#include "Common/IntToString.h"
+#include "Common/StringToInt.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/Error.h"
+#include "Windows/FileFind.h"
+#include "Windows/Thread.h"
+
+#include "../../FileManager/FormatUtils.h"
+#include "../../FileManager/ExtractCallback.h"
+#include "../../FileManager/StringUtils.h"
+
+#include "../Common/ArchiveExtractCallback.h"
+#include "../Common/WorkDir.h"
+#include "../Explorer/MyMessages.h"
+#include "../Resource/Extract/resource.h"
+
+#include "OpenCallbackGUI.h"
+#include "CompressDialog.h"
+#include "UpdateGUI.h"
+
+using namespace NWindows;
+using namespace NFile;
+
+static const wchar_t *kIncorrectOutDir = L"Incorrect output directory path";
+static const wchar_t *kDefaultSfxModule = L"7z.sfx";
+static const wchar_t *kSFXExtension = L"exe";
+
+struct CThreadUpdating
+{
+ CUpdateCallbackGUI *UpdateCallbackGUI;
+
+ const NWildcard::CCensor *WildcardCensor;
+ CUpdateOptions *Options;
+ COpenCallbackGUI *OpenCallback;
+
+ CUpdateErrorInfo *ErrorInfo;
+ HRESULT Result;
+
+ DWORD Process()
+ {
+ UpdateCallbackGUI->ProgressDialog.WaitCreating();
+ try
+ {
+ Result = UpdateArchive(*WildcardCensor, *Options,
+ *ErrorInfo, OpenCallback, UpdateCallbackGUI);
+ }
+ catch(const UString &s)
+ {
+ ErrorInfo->Message = s;
+ Result = E_FAIL;
+ }
+ catch(const wchar_t *s)
+ {
+ ErrorInfo->Message = s;
+ Result = E_FAIL;
+ }
+ catch(const char *s)
+ {
+ ErrorInfo->Message = GetUnicodeString(s);
+ Result = E_FAIL;
+ }
+ catch(...)
+ {
+ Result = E_FAIL;
+ }
+ UpdateCallbackGUI->ProgressDialog.MyClose();
+ return 0;
+ }
+ static DWORD WINAPI MyThreadFunction(void *param)
+ {
+ return ((CThreadUpdating *)param)->Process();
+ }
+};
+
+static void AddProp(CObjectVector<CProperty> &properties,
+ const UString &name, const UString &value)
+{
+ CProperty prop;
+ prop.Name = name;
+ prop.Value = value;
+ properties.Add(prop);
+}
+
+static void AddProp(CObjectVector<CProperty> &properties,
+ const UString &name, UInt32 value)
+{
+ wchar_t tmp[32];
+ ConvertUInt64ToString(value, tmp);
+ AddProp(properties, name, tmp);
+}
+
+static void AddProp(CObjectVector<CProperty> &properties,
+ const UString &name, bool value)
+{
+ AddProp(properties, name, value ? UString(L"on"): UString(L"off"));
+}
+
+static bool IsThereMethodOverride(bool is7z, const UString &propertiesString)
+{
+ UStringVector strings;
+ SplitString(propertiesString, strings);
+ for (int i = 0; i < strings.Size(); i++)
+ {
+ const UString &s = strings[i];
+ if (is7z)
+ {
+ const wchar_t *end;
+ UInt64 n = ConvertStringToUInt64(s, &end);
+ if (n == 0 && *end == L'=')
+ return true;
+ }
+ else
+ {
+ if (s.Length() > 0)
+ if (s[0] == L'm' && s[1] == L'=')
+ return true;
+ }
+ }
+ return false;
+}
+
+static void ParseAndAddPropertires(CObjectVector<CProperty> &properties,
+ const UString &propertiesString)
+{
+ UStringVector strings;
+ SplitString(propertiesString, strings);
+ for (int i = 0; i < strings.Size(); i++)
+ {
+ const UString &s = strings[i];
+ CProperty property;
+ int index = s.Find(L'=');
+ if (index < 0)
+ property.Name = s;
+ else
+ {
+ property.Name = s.Left(index);
+ property.Value = s.Mid(index + 1);
+ }
+ properties.Add(property);
+ }
+}
+
+static void SetOutProperties(
+ CObjectVector<CProperty> &properties,
+ bool is7z,
+ UInt32 level,
+ bool setMethod,
+ const UString &method,
+ UInt32 dictionary,
+ bool orderMode,
+ UInt32 order,
+ bool solidModeIsAllowed, bool solidMode,
+ bool multiThreadIsAllowed, bool multiThread,
+ const UString &encryptionMethod,
+ bool encryptHeadersIsAllowed, bool encryptHeaders,
+ bool /* sfxMode */)
+{
+ if (level != (UInt32)(Int32)-1)
+ AddProp(properties, L"x", (UInt32)level);
+ if (setMethod)
+ {
+ if (!method.IsEmpty())
+ AddProp(properties, is7z ? L"0": L"m", method);
+ if (dictionary != (UInt32)(Int32)-1)
+ {
+ UString name;
+ if (is7z)
+ name = L"0";
+ if (orderMode)
+ name += L"mem";
+ else
+ name += L"d";
+ wchar_t s[32];
+ ConvertUInt64ToString(dictionary, s);
+ size_t len = wcslen(s);
+ s[len++] = L'B';
+ s[len] = L'\0';
+ AddProp(properties, name, UString(s));
+ }
+ if (order != (UInt32)(Int32)-1)
+ {
+ UString name;
+ if (is7z)
+ name = L"0";
+ if (orderMode)
+ name += L"o";
+ else
+ name += L"fb";
+ AddProp(properties, name, (UInt32)order);
+ }
+ }
+
+ if (!encryptionMethod.IsEmpty())
+ AddProp(properties, L"em", encryptionMethod);
+
+ if (encryptHeadersIsAllowed)
+ AddProp(properties, L"he", encryptHeaders);
+ if (solidModeIsAllowed)
+ AddProp(properties, L"s", solidMode);
+ if (multiThreadIsAllowed)
+ AddProp(properties, L"mt", multiThread);
+}
+
+static HRESULT ShowDialog(const NWildcard::CCensor &censor,
+ CUpdateOptions &options, CUpdateCallbackGUI *callback)
+{
+ if (options.Commands.Size() != 1)
+ throw "It must be one command";
+ CObjectVector<CArchiverInfo> archivers;
+ CArchiverInfo archiverInfo;
+ ReadArchiverInfoList(archivers);
+ UString currentDirPrefix;
+ {
+ if (!NDirectory::MyGetCurrentDirectory(currentDirPrefix))
+ return E_FAIL;
+ NName::NormalizeDirPathPrefix(currentDirPrefix);
+ }
+
+ bool oneFile = false;
+ NFind::CFileInfoW fileInfo;
+ if (censor.Pairs.Size() > 0)
+ {
+ const NWildcard::CPair &pair = censor.Pairs[0];
+ if (pair.Head.IncludeItems.Size() > 0)
+ {
+ const NWildcard::CItem &item = pair.Head.IncludeItems[0];
+ if (item.ForFile)
+ {
+ UString name = pair.Prefix;
+ for (int i = 0; i < item.PathParts.Size(); i++)
+ {
+ if (i > 0)
+ name += L'\\';
+ name += item.PathParts[i];
+ }
+ if (NFind::FindFile(name, fileInfo))
+ {
+ if (censor.Pairs.Size() == 1 && pair.Head.IncludeItems.Size() == 1)
+ oneFile = !fileInfo.IsDirectory();
+ }
+ }
+ }
+ }
+
+ CCompressDialog dialog;
+ NCompressDialog::CInfo &di = dialog.Info;
+ for(int i = 0; i < archivers.Size(); i++)
+ {
+ const CArchiverInfo &ai = archivers[i];
+ if (ai.UpdateEnabled && (oneFile || !ai.KeepName))
+ dialog.m_ArchiverInfoList.Add(ai);
+ }
+ if(dialog.m_ArchiverInfoList.Size() == 0)
+ {
+ MyMessageBox(L"No Update Engines");
+ return E_FAIL;
+ }
+
+ // di.ArchiveName = options.ArchivePath.GetFinalPath();
+ di.ArchiveName = options.ArchivePath.GetPathWithoutExt();
+ dialog.OriginalFileName = fileInfo.Name;
+
+ di.CurrentDirPrefix = currentDirPrefix;
+ di.SFXMode = options.SfxMode;
+
+ di.Solid = true;
+ di.MultiThread = false;
+
+ if (callback->PasswordIsDefined)
+ di.Password = callback->Password;
+
+ di.KeepName = !oneFile;
+
+ if(dialog.Create(0) != IDOK)
+ return E_ABORT;
+
+ options.VolumesSizes = di.VolumeSizes;
+ /*
+ if (di.VolumeSizeIsDefined)
+ {
+ MyMessageBox(L"Splitting to volumes is not supported");
+ return E_FAIL;
+ }
+ */
+
+ NUpdateArchive::CActionSet &actionSet = options.Commands.Front().ActionSet;
+
+ switch(di.UpdateMode)
+ {
+ case NCompressDialog::NUpdateMode::kAdd:
+ actionSet = NUpdateArchive::kAddActionSet;
+ break;
+ case NCompressDialog::NUpdateMode::kUpdate:
+ actionSet = NUpdateArchive::kUpdateActionSet;
+ break;
+ case NCompressDialog::NUpdateMode::kFresh:
+ actionSet = NUpdateArchive::kFreshActionSet;
+ break;
+ case NCompressDialog::NUpdateMode::kSynchronize:
+ actionSet = NUpdateArchive::kSynchronizeActionSet;
+ break;
+ default:
+ throw 1091756;
+ }
+ archiverInfo = dialog.m_ArchiverInfoList[di.ArchiverInfoIndex];
+ callback->PasswordIsDefined = (!di.Password.IsEmpty());
+ if (callback->PasswordIsDefined)
+ callback->Password = di.Password;
+
+ options.MethodMode.Properties.Clear();
+
+ bool is7z = archiverInfo.Name.CompareNoCase(L"7z") == 0;
+ bool methodOverride = IsThereMethodOverride(is7z, di.Options);
+
+ SetOutProperties(
+ options.MethodMode.Properties,
+ is7z,
+ di.Level,
+ !methodOverride,
+ di.Method,
+ di.Dictionary,
+ di.OrderMode, di.Order,
+ di.SolidIsAllowed, di.Solid,
+ di.MultiThreadIsAllowed, di.MultiThread,
+ di.EncryptionMethod,
+ di.EncryptHeadersIsAllowed, di.EncryptHeaders,
+ di.SFXMode);
+
+ ParseAndAddPropertires(options.MethodMode.Properties, di.Options);
+
+ if (di.SFXMode)
+ options.SfxMode = true;
+ options.MethodMode.FilePath = archiverInfo.FilePath;
+ options.MethodMode.ClassID = archiverInfo.ClassID;
+
+ options.ArchivePath.VolExtension = archiverInfo.GetMainExtension();
+ if(di.SFXMode)
+ options.ArchivePath.BaseExtension = kSFXExtension;
+ else
+ options.ArchivePath.BaseExtension = options.ArchivePath.VolExtension;
+ options.ArchivePath.ParseFromPath(di.ArchiveName);
+
+ NWorkDir::CInfo workDirInfo;
+ ReadWorkDirInfo(workDirInfo);
+ options.WorkingDir.Empty();
+ if (workDirInfo.Mode != NWorkDir::NMode::kCurrent)
+ {
+ UString fullPath;
+ NDirectory::MyGetFullPathName(di.ArchiveName, fullPath);
+ options.WorkingDir = GetWorkDir(workDirInfo, fullPath);
+ NFile::NDirectory::CreateComplexDirectory(options.WorkingDir);
+ }
+ return S_OK;
+}
+
+HRESULT UpdateGUI(
+ const NWildcard::CCensor &censor,
+ CUpdateOptions &options,
+ bool showDialog,
+ CUpdateErrorInfo &errorInfo,
+ COpenCallbackGUI *openCallback,
+ CUpdateCallbackGUI *callback)
+{
+ if (showDialog)
+ {
+ RINOK(ShowDialog(censor, options, callback));
+ }
+ if (options.SfxMode && options.SfxModule.IsEmpty())
+ options.SfxModule = kDefaultSfxModule;
+
+ CThreadUpdating tu;
+
+ tu.UpdateCallbackGUI = callback;
+ tu.UpdateCallbackGUI->Init();
+
+ tu.WildcardCensor = &censor;
+ tu.Options = &options;
+ tu.OpenCallback = openCallback;
+ tu.ErrorInfo = &errorInfo;
+
+ CThread thread;
+ if (!thread.Create(CThreadUpdating::MyThreadFunction, &tu))
+ throw 271824;
+ tu.UpdateCallbackGUI->StartProgressDialog(LangString(IDS_PROGRESS_COMPRESSING, 0x02000DC0));
+ return tu.Result;
+}
+
+
diff --git a/CPP/7zip/UI/GUI/UpdateGUI.h b/CPP/7zip/UI/GUI/UpdateGUI.h
new file mode 100755
index 00000000..c5061aca
--- /dev/null
+++ b/CPP/7zip/UI/GUI/UpdateGUI.h
@@ -0,0 +1,20 @@
+// GUI/UpdateGUI.h
+
+#ifndef __UPDATE_GUI_H
+#define __UPDATE_GUI_H
+
+#include "../Common/Update.h"
+#include "OpenCallbackGUI.h"
+#include "UpdateCallbackGUI.h"
+
+#include "../../FileManager/UpdateCallback100.h"
+
+HRESULT UpdateGUI(
+ const NWildcard::CCensor &censor,
+ CUpdateOptions &options,
+ bool showDialog,
+ CUpdateErrorInfo &errorInfo,
+ COpenCallbackGUI *openCallback,
+ CUpdateCallbackGUI *callback);
+
+#endif
diff --git a/CPP/7zip/UI/GUI/makefile b/CPP/7zip/UI/GUI/makefile
new file mode 100755
index 00000000..bc6af149
--- /dev/null
+++ b/CPP/7zip/UI/GUI/makefile
@@ -0,0 +1,135 @@
+PROG = 7zG.exe
+LIBS = $(LIBS) user32.lib advapi32.lib oleaut32.lib shell32.lib comctl32.lib htmlhelp.lib ole32.lib comdlg32.lib
+CFLAGS = $(CFLAGS) -I ../../../ -DLANG -DCOMPRESS_MT -DWIN_LONG_PATH
+
+GUI_OBJS = \
+ $O\CompressDialog.obj \
+ $O\ExtractDialog.obj \
+ $O\ExtractGUI.obj \
+ $O\GUI.obj \
+ $O\OpenCallbackGUI.obj \
+ $O\UpdateCallbackGUI.obj \
+ $O\UpdateGUI.obj \
+
+COMMON_OBJS = \
+ $O\Alloc.obj \
+ $O\CommandLineParser.obj \
+ $O\IntToString.obj \
+ $O\Lang.obj \
+ $O\ListFileUtils.obj \
+ $O\NewHandler.obj \
+ $O\StdInStream.obj \
+ $O\String.obj \
+ $O\StringConvert.obj \
+ $O\StringToInt.obj \
+ $O\TextConfig.obj \
+ $O\UTFConvert.obj \
+ $O\Vector.obj \
+ $O\Wildcard.obj \
+
+WIN_OBJS = \
+ $O\CommonDialog.obj \
+ $O\DLL.obj \
+ $O\Error.obj \
+ $O\FileDir.obj \
+ $O\FileFind.obj \
+ $O\FileIO.obj \
+ $O\FileName.obj \
+ $O\MemoryLock.obj \
+ $O\PropVariant.obj \
+ $O\PropVariantConversions.obj \
+ $O\Registry.obj \
+ $O\ResourceString.obj \
+ $O\Shell.obj \
+ $O\Synchronization.obj \
+ $O\Window.obj \
+
+WIN_CTRL_OBJS = \
+ $O\ComboBox.obj \
+ $O\Dialog.obj \
+ $O\ListView.obj \
+
+7ZIP_COMMON_OBJS = \
+ $O\FilePathAutoRename.obj \
+ $O\FileStreams.obj \
+ $O\StreamUtils.obj \
+
+UI_COMMON_OBJS = \
+ $O\ArchiveCommandLine.obj \
+ $O\ArchiveExtractCallback.obj \
+ $O\ArchiveOpenCallback.obj \
+ $O\ArchiverInfo.obj \
+ $O\DefaultName.obj \
+ $O\EnumDirItems.obj \
+ $O\Extract.obj \
+ $O\ExtractingFilePath.obj \
+ $O\OpenArchive.obj \
+ $O\PropIDUtils.obj \
+ $O\SetProperties.obj \
+ $O\SortUtils.obj \
+ $O\TempFiles.obj \
+ $O\Update.obj \
+ $O\UpdateAction.obj \
+ $O\UpdateCallback.obj \
+ $O\UpdatePair.obj \
+ $O\UpdateProduce.obj \
+ $O\WorkDir.obj \
+ $O\ZipRegistry.obj \
+
+FM_OBJS = \
+ $O\ExtractCallback.obj \
+ $O\FormatUtils.obj \
+ $O\HelpUtils.obj \
+ $O\LangUtils.obj \
+ $O\OpenCallback.obj \
+ $O\ProgramLocation.obj \
+ $O\RegistryUtils.obj \
+ $O\SplitUtils.obj \
+ $O\StringUtils.obj \
+ $O\UpdateCallback100.obj \
+
+OBJS = \
+ $O\StdAfx.obj \
+ $(GUI_OBJS) \
+ $(COMMON_OBJS) \
+ $(WIN_OBJS) \
+ $(WIN_CTRL_OBJS) \
+ $(7ZIP_COMMON_OBJS) \
+ $(UI_COMMON_OBJS) \
+ $(FM_OBJS)\
+ $O\MyMessages.obj \
+ $O\MessagesDialog.obj \
+ $O\OverwriteDialog.obj \
+ $O\PasswordDialog.obj \
+ $O\ProgressDialog.obj \
+ $O\CopyCoder.obj \
+ $O\resource.res
+
+!include "../../../Build.mak"
+
+$(GUI_OBJS): $(*B).cpp
+ $(COMPL)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+ $(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+ $(COMPL)
+$(WIN_CTRL_OBJS): ../../../Windows/Control/$(*B).cpp
+ $(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+ $(COMPL)
+$(UI_COMMON_OBJS): ../Common/$(*B).cpp
+ $(COMPL)
+$(FM_OBJS): ../../FileManager/$(*B).cpp
+ $(COMPL)
+$O\MyMessages.obj: ../Explorer/MyMessages.cpp
+ $(COMPL)
+$O\MessagesDialog.obj: ../../FileManager/Resource/MessagesDialog/$(*B).cpp
+ $(COMPL)
+$O\OverwriteDialog.obj: ../../FileManager/Resource/OverwriteDialog./$(*B).cpp
+ $(COMPL)
+$O\PasswordDialog.obj: ../../FileManager/Resource/PasswordDialog/$(*B).cpp
+ $(COMPL)
+$O\ProgressDialog.obj: ../../FileManager/Resource/ProgressDialog2/$(*B).cpp
+ $(COMPL)
+$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
+ $(COMPL)
diff --git a/CPP/7zip/UI/GUI/resource.h b/CPP/7zip/UI/GUI/resource.h
new file mode 100755
index 00000000..d88af787
--- /dev/null
+++ b/CPP/7zip/UI/GUI/resource.h
@@ -0,0 +1,45 @@
+#define IDS_CONTEXT_EXTRACT 42
+#define IDS_CONTEXT_EXTRACT_HELP 43
+#define IDS_CONTEXT_COMPRESS 44
+#define IDS_CONTEXT_COMPRESS_HELP 45
+#define IDS_CONTEXT_OPEN 46
+#define IDS_CONTEXT_OPEN_HELP 47
+#define IDS_CONTEXT_TEST 48
+#define IDS_CONTEXT_TEST_HELP 49
+#define IDS_CONTEXT_CAPTION_HELP 50
+#define IDS_CONTEXT_POPUP_CAPTION 51
+#define IDS_OPEN_TYPE_ALL_FILES 80
+
+#define IDS_METHOD_STORE 81
+#define IDS_METHOD_NORMAL 82
+#define IDS_METHOD_MAXIMUM 83
+#define IDS_METHOD_FAST 84
+#define IDS_METHOD_FASTEST 85
+#define IDS_METHOD_ULTRA 86
+
+#define IDS_COMPRESS_UPDATE_MODE_ADD 90
+#define IDS_COMPRESS_UPDATE_MODE_UPDATE 91
+#define IDS_COMPRESS_UPDATE_MODE_FRESH 92
+#define IDS_COMPRESS_UPDATE_MODE_SYNCHRONIZE 93
+
+#define IDS_COMPRESS_SPLIT_CONFIRM_MESSAGE 94
+#define IDS_COMPRESS_INCORRECT_VOLUME_SIZE 95
+
+#define IDS_COMPRESS_SET_ARCHIVE_DIALOG_TITLE 96
+#define IDS_CANT_UPDATE_ARCHIVE 97
+
+#define IDS_PROGRESS_COMPRESSING 98
+#define IDS_PROGRESS_TESTING 99
+#define IDS_ERROR 100
+#define IDS_MESSAGE_NO_ERRORS 101
+#define IDS_CONFIG_DIALOG_CAPTION 102
+
+#define IDS_PASSWORD_USE_ASCII 110
+#define IDS_PASSWORD_PASSWORDS_DO_NOT_MATCH 111
+#define IDS_PASSWORD_IS_TOO_LONG 112
+
+#define IDD_DIALOG_EXTRACT 137
+#define IDB_DELETE 149
+#define IDC_LIST1 1067
+#define IDC_COLUMN_EDIT_WIDTH 1068
+
diff --git a/CPP/7zip/UI/GUI/resource.rc b/CPP/7zip/UI/GUI/resource.rc
new file mode 100755
index 00000000..19f7e61b
--- /dev/null
+++ b/CPP/7zip/UI/GUI/resource.rc
@@ -0,0 +1,57 @@
+#include "../../MyVersionInfo.rc"
+#include <winnt.h>
+#include "resource.h"
+
+MY_VERSION_INFO_APP("7-Zip GUI", "7zg")
+
+IDI_ICON1 ICON "FM.ico"
+
+1 24 MOVEABLE PURE "7zG.exe.manifest"
+
+STRINGTABLE
+BEGIN
+ IDS_CONTEXT_EXTRACT "Extract files..."
+ IDS_CONTEXT_EXTRACT_HELP "Extracts files from the selected archive."
+ IDS_CONTEXT_COMPRESS "Add to archive..."
+ IDS_CONTEXT_COMPRESS_HELP "Adds the selected items to archive."
+ IDS_CONTEXT_OPEN "Open"
+ IDS_CONTEXT_OPEN_HELP "Opens the selected archive."
+ IDS_CONTEXT_TEST "Test archive"
+ IDS_CONTEXT_TEST_HELP "Tests integrity of the selected archive."
+ IDS_CONTEXT_CAPTION_HELP "7-Zip commands"
+ IDS_CONTEXT_POPUP_CAPTION "7-Zip"
+ IDS_OPEN_TYPE_ALL_FILES "All Files"
+ IDS_METHOD_STORE "Store"
+ IDS_METHOD_NORMAL "Normal"
+ IDS_METHOD_MAXIMUM "Maximum"
+ IDS_METHOD_FAST "Fast"
+ IDS_METHOD_FASTEST "Fastest"
+ IDS_METHOD_ULTRA "Ultra"
+ IDS_COMPRESS_UPDATE_MODE_ADD "Add and replace files"
+ IDS_COMPRESS_UPDATE_MODE_UPDATE "Update and add files"
+ IDS_COMPRESS_UPDATE_MODE_FRESH "Freshen existing files"
+ IDS_COMPRESS_UPDATE_MODE_SYNCHRONIZE "Synchronize files"
+ IDS_COMPRESS_SET_ARCHIVE_DIALOG_TITLE "Browse"
+ IDS_COMPRESS_INCORRECT_VOLUME_SIZE "Incorrect volume size"
+ IDS_COMPRESS_SPLIT_CONFIRM_MESSAGE "Specified volume size: {0} bytes.\nAre you sure you want to split archive into such volumes?"
+
+ IDS_PASSWORD_USE_ASCII "Use only English letters, numbers and special characters (!, #, $, ...) for password."
+ IDS_PASSWORD_PASSWORDS_DO_NOT_MATCH "Passwords do not match"
+ IDS_PASSWORD_IS_TOO_LONG "Password is too long"
+
+ IDS_CANT_UPDATE_ARCHIVE "Can not update archive '{0}'"
+ IDS_PROGRESS_COMPRESSING "Compressing"
+ IDS_PROGRESS_TESTING "Testing"
+ IDS_ERROR "Error"
+ IDS_MESSAGE_NO_ERRORS "There are no errors"
+ IDS_CONFIG_DIALOG_CAPTION "7-Zip Options"
+END
+
+#include "../../FileManager/Resource/PropertyName/resource.rc"
+#include "../../FileManager/Resource/OverwriteDialog/resource.rc"
+#include "../../FileManager/Resource/PasswordDialog/resource.rc"
+#include "../../FileManager/Resource/MessagesDialog/resource.rc"
+#include "../../FileManager/Resource/ProgressDialog2/resource.rc"
+#include "../Resource/Extract/resource.rc"
+#include "../Resource/ExtractDialog/resource.rc"
+#include "../Resource/CompressDialog/resource.rc"
diff --git a/CPP/7zip/UI/Resource/CompressDialog/resource.h b/CPP/7zip/UI/Resource/CompressDialog/resource.h
new file mode 100755
index 00000000..847bb3f9
--- /dev/null
+++ b/CPP/7zip/UI/Resource/CompressDialog/resource.h
@@ -0,0 +1,40 @@
+#define IDD_DIALOG_COMPRESS 152
+#define IDC_STATIC_COMPRESS_MEMORY 1022
+#define IDC_STATIC_COMPRESS_MEMORY_DE 1023
+#define IDC_STATIC_COMPRESS_MEMORY_VALUE 1027
+#define IDC_STATIC_COMPRESS_MEMORY_DE_VALUE 1028
+#define IDC_COMPRESS_COMBO_ARCHIVE 1072
+#define IDC_COMPRESS_BUTTON_SET_ARCHIVE 1073
+#define IDC_COMPRESS_COMBO_LEVEL 1074
+#define IDC_COMPRESS_COMBO_UPDATE_MODE 1075
+#define IDC_COMPRESS_COMBO_FORMAT 1076
+#define IDC_COMPRESS_COMBO_VOLUME 1077
+#define IDC_COMPRESS_COMBO_METHOD 1078
+#define IDC_COMPRESS_COMBO_DICTIONARY 1079
+#define IDC_COMPRESS_COMBO_ORDER 1080
+#define IDC_COMPRESS_SFX 1090
+#define IDC_COMPRESS_EDIT_PARAMETERS 1091
+#define IDC_COMPRESS_SOLID 1092
+#define IDC_COMPRESS_MULTI_THREAD 1093
+#define IDC_STATIC_COMPRESS_ARCHIVE 1097
+#define IDC_STATIC_COMPRESS_FORMAT 1098
+#define IDC_STATIC_COMPRESS_LEVEL 1099
+#define IDC_STATIC_COMPRESS_PARAMETERS 1100
+#define IDC_STATIC_COMPRESS_UPDATE_MODE 1101
+#define IDC_STATIC_COMPRESS_OPTIONS 1102
+#define IDC_STATIC_COMPRESS_VOLUME 1103
+#define IDC_STATIC_COMPRESS_METHOD 1104
+#define IDC_STATIC_COMPRESS_DICTIONARY 1105
+#define IDC_STATIC_COMPRESS_ORDER 1106
+
+#define IDC_COMPRESS_ENCRYPTION 1110
+#define IDC_STATIC_COMPRESS_PASSWORD1 1111
+#define IDC_COMPRESS_EDIT_PASSWORD1 1112
+#define IDC_STATIC_COMPRESS_PASSWORD2 1113
+#define IDC_COMPRESS_EDIT_PASSWORD2 1114
+#define IDC_COMPRESS_CHECK_SHOW_PASSWORD 1115
+
+#define IDC_STATIC_COMPRESS_ENCRYPTION_METHOD 1120
+#define IDC_COMPRESS_COMBO_ENCRYPTION_METHOD 1121
+
+#define IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES 1122
diff --git a/CPP/7zip/UI/Resource/CompressDialog/resource.rc b/CPP/7zip/UI/Resource/CompressDialog/resource.rc
new file mode 100755
index 00000000..9019a1af
--- /dev/null
+++ b/CPP/7zip/UI/Resource/CompressDialog/resource.rc
@@ -0,0 +1,117 @@
+#include "resource.h"
+#include "../../../GuiCommon.rc"
+
+#define xSize2 344
+#define ySize2 295
+
+#define xSize (xSize2 + marg + marg)
+#define ySize (ySize2 + marg + marg)
+
+#undef gSize
+#undef gSpace
+#undef g0XSize
+#undef g1XPos
+#undef g1XSize
+#undef g2XSize
+#undef g3XPos
+#undef g3XSize
+#undef g4XPos
+#undef g4XPos2
+#undef g4XSize
+#undef g4XSize2
+#undef bXPos1
+#undef bXPos2
+#undef bXPos3
+#undef bYPos
+
+#define gSize 160
+#define gSpace 24
+
+#define g0XSize 82
+#define g1XPos (marg + g0XSize)
+#define g1XSize (gSize - g0XSize)
+
+#define g2XSize 122
+#define g3XPos (marg + g2XSize)
+#define g3XSize (gSize - g2XSize)
+
+#define g4XPos (marg + gSize + gSpace)
+#define g4XPos2 (g4XPos + 7)
+#define g4XSize (xSize2 - gSize - gSpace)
+#define g4XSize2 (g4XSize - 14)
+
+#define bXPos1 (xSize - marg - bXSize)
+#define bXPos2 (bXPos1 - 10 - bXSize)
+#define bXPos3 (bXPos2 - 10 - bXSize)
+
+#define bYPos (ySize - marg - bYSize)
+
+IDD_DIALOG_COMPRESS DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE
+CAPTION "Add to Archive"
+MY_FONT
+BEGIN
+ LTEXT "&Archive:", IDC_STATIC_COMPRESS_ARCHIVE, marg, marg, xSize2, 8
+ COMBOBOX IDC_COMPRESS_COMBO_ARCHIVE, marg, 18, xSize2 - bDotsSize - 12, 126, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "...", IDC_COMPRESS_BUTTON_SET_ARCHIVE, xSize - marg - bDotsSize, 17, bDotsSize, bYSize, WS_GROUP
+
+ LTEXT "Archive &format:", IDC_STATIC_COMPRESS_FORMAT, marg, 41, g0XSize, 8
+ COMBOBOX IDC_COMPRESS_COMBO_FORMAT, g1XPos, 39, g1XSize , 80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+
+ LTEXT "Compression &level:",IDC_STATIC_COMPRESS_LEVEL, marg, 62, g0XSize, 8
+ COMBOBOX IDC_COMPRESS_COMBO_LEVEL, g1XPos, 60, g1XSize, 80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+
+ LTEXT "Compression &method:",IDC_STATIC_COMPRESS_METHOD, marg, 83, g0XSize, 8
+ COMBOBOX IDC_COMPRESS_COMBO_METHOD, g1XPos, 81, g1XSize, 80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+
+ LTEXT "&Dictionary size:",IDC_STATIC_COMPRESS_DICTIONARY, marg, 104, g0XSize, 8
+ COMBOBOX IDC_COMPRESS_COMBO_DICTIONARY, g1XPos, 102, g1XSize, 167, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+
+ LTEXT "&Word size:",IDC_STATIC_COMPRESS_ORDER, marg, 125, g0XSize, 8
+ COMBOBOX IDC_COMPRESS_COMBO_ORDER, g1XPos, 123, g1XSize, 141, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+
+
+ LTEXT "Memory usage for Compressing:", IDC_STATIC_COMPRESS_MEMORY, marg, 149, g2XSize, 8
+ RTEXT "0", IDC_STATIC_COMPRESS_MEMORY_VALUE, g3XPos, 149, g3XSize, 8
+
+ LTEXT "Memory usage for Decompressing:", IDC_STATIC_COMPRESS_MEMORY_DE, marg, 163, g2XSize, 8
+ RTEXT "0",IDC_STATIC_COMPRESS_MEMORY_DE_VALUE, g3XPos, 163, g3XSize, 8
+
+
+ CONTROL "Create &Solid archive", IDC_COMPRESS_SOLID,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,
+ marg, 181, gSize, 10
+ CONTROL "Multi-threading", IDC_COMPRESS_MULTI_THREAD, "Button", BS_AUTOCHECKBOX | WS_TABSTOP,
+ marg, 195, gSize, 10
+
+ LTEXT "Split to &volumes, bytes:", IDC_STATIC_COMPRESS_VOLUME, marg, 215, gSize, 8
+ COMBOBOX IDC_COMPRESS_COMBO_VOLUME, marg, 227, gSize, 73, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+
+ LTEXT "&Parameters:",IDC_STATIC_COMPRESS_PARAMETERS, marg, 250, xSize2, 8
+ EDITTEXT IDC_COMPRESS_EDIT_PARAMETERS, marg, 262, xSize2, 14, ES_AUTOHSCROLL
+
+ LTEXT "&Update mode:",IDC_STATIC_COMPRESS_UPDATE_MODE, g4XPos, 39, g4XSize, 8
+ COMBOBOX IDC_COMPRESS_COMBO_UPDATE_MODE, g4XPos, 51, g4XSize, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+
+ GROUPBOX "Options",IDC_STATIC_COMPRESS_OPTIONS, g4XPos, 73, g4XSize, 32
+ CONTROL "Create SF&X archive",IDC_COMPRESS_SFX, "Button", BS_AUTOCHECKBOX | WS_TABSTOP,
+ g4XPos2, 87, g4XSize2, 10
+
+ GROUPBOX "Encryption",IDC_COMPRESS_ENCRYPTION, g4XPos, 113, g4XSize, 127
+
+ LTEXT "Enter password:",IDC_STATIC_COMPRESS_PASSWORD1, g4XPos2, 127, g4XSize2, 8
+ EDITTEXT IDC_COMPRESS_EDIT_PASSWORD1, g4XPos2, 139, g4XSize2, 14, ES_PASSWORD | ES_AUTOHSCROLL
+ LTEXT "Reenter password:",IDC_STATIC_COMPRESS_PASSWORD2, g4XPos2, 159, g4XSize2, 8
+ EDITTEXT IDC_COMPRESS_EDIT_PASSWORD2, g4XPos2, 171, g4XSize2, 14, ES_PASSWORD | ES_AUTOHSCROLL
+
+ CONTROL "Show Password",IDC_COMPRESS_CHECK_SHOW_PASSWORD,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,
+ g4XPos2, 192, g4XSize2, 10
+
+ LTEXT "&Encryption method:",IDC_STATIC_COMPRESS_ENCRYPTION_METHOD, g4XPos2, 208, 80, 8
+ COMBOBOX IDC_COMPRESS_COMBO_ENCRYPTION_METHOD, g4XPos2 + 90, 206, g4XSize2 - 90, 198, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+
+ CONTROL "Encrypt file &names", IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES, "Button", BS_AUTOCHECKBOX | WS_TABSTOP,
+ g4XPos2, 224, g4XSize2, 10
+
+ DEFPUSHBUTTON "OK", IDOK, bXPos3, bYPos, bXSize, bYSize, WS_GROUP
+ PUSHBUTTON "Cancel", IDCANCEL, bXPos2, bYPos, bXSize, bYSize
+ PUSHBUTTON "Help", IDHELP, bXPos1, bYPos, bXSize, bYSize
+END
diff --git a/CPP/7zip/UI/Resource/Extract/resource.h b/CPP/7zip/UI/Resource/Extract/resource.h
new file mode 100755
index 00000000..917c0a34
--- /dev/null
+++ b/CPP/7zip/UI/Resource/Extract/resource.h
@@ -0,0 +1,15 @@
+#define IDS_CANNOT_CREATE_FOLDER 200
+#define IDS_OPEN_IS_NOT_SUPORTED_ARCHIVE 201
+
+#define IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CRC 202
+#define IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_DATA_ERROR 203
+#define IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_UNSUPPORTED_METHOD 204
+#define IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CRC_ENCRYPTED 205
+#define IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED 206
+
+#define IDS_EXTRACT_SET_FOLDER 207
+#define IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CANNOT_OPEN_FILE 208
+#define IDS_PROGRESS_EXTRACTING 209
+
+#define IDS_CANT_OPEN_ARCHIVE 103
+#define IDS_CANT_OPEN_ENCRYPTED_ARCHIVE 104
diff --git a/CPP/7zip/UI/Resource/Extract/resource.rc b/CPP/7zip/UI/Resource/Extract/resource.rc
new file mode 100755
index 00000000..d3fd1df9
--- /dev/null
+++ b/CPP/7zip/UI/Resource/Extract/resource.rc
@@ -0,0 +1,19 @@
+#include "resource.h"
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_CANNOT_CREATE_FOLDER "Cannot create folder '{0}'"
+ IDS_OPEN_IS_NOT_SUPORTED_ARCHIVE "File is not supported archive."
+ IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CRC "CRC failed in '{0}'. File is broken."
+ IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_DATA_ERROR "Data error in '{0}'. File is broken"
+ IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CRC_ENCRYPTED "CRC failed in encrypted file '{0}'. Wrong password?"
+ IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED "Data error in encrypted file '{0}'. Wrong password?"
+ IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_UNSUPPORTED_METHOD "Unsupported compression method for '{0}'."
+ IDS_EXTRACT_SET_FOLDER "Specify a location for extracted files."
+ IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CANNOT_OPEN_FILE "Can not open output file '{0}'."
+ IDS_PROGRESS_EXTRACTING "Extracting"
+ IDS_CANT_OPEN_ARCHIVE "Can not open file '{0}' as archive"
+ IDS_CANT_OPEN_ENCRYPTED_ARCHIVE "Can not open encrypted archive '{0}'. Wrong password?"
+END
diff --git a/CPP/7zip/UI/Resource/ExtractDialog/resource.h b/CPP/7zip/UI/Resource/ExtractDialog/resource.h
new file mode 100755
index 00000000..338a2561
--- /dev/null
+++ b/CPP/7zip/UI/Resource/ExtractDialog/resource.h
@@ -0,0 +1,26 @@
+#define IDC_STATIC_EXTRACT_EXTRACT_TO 1020
+#define IDC_EXTRACT_COMBO_PATH 1021
+#define IDC_EXTRACT_BUTTON_SET_PATH 1022
+
+
+#define IDC_EXTRACT_PATH_MODE 1040
+#define IDC_EXTRACT_RADIO_FULL_PATHNAMES 1041
+#define IDC_EXTRACT_RADIO_CURRENT_PATHNAMES 1042
+#define IDC_EXTRACT_RADIO_NO_PATHNAMES 1043
+
+#define IDC_EXTRACT_OVERWRITE_MODE 1050
+#define IDC_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE 1051
+#define IDC_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT 1052
+#define IDC_EXTRACT_RADIO_SKIP_EXISTING_FILES 1053
+#define IDC_EXTRACT_RADIO_SELECTED_FILES 1054
+#define IDC_EXTRACT_RADIO_ALL_FILES 1055
+#define IDC_EXTRACT_RADIO_AUTO_RENAME 1056
+#define IDC_EXTRACT_RADIO_AUTO_RENAME_EXISTING 1057
+
+
+#define IDC_EXTRACT_FILES 1060
+
+#define IDC_EXTRACT_PASSWORD 1100
+#define IDC_EXTRACT_EDIT_PASSWORD 1101
+#define IDC_EXTRACT_CHECK_SHOW_PASSWORD 1102
+
diff --git a/CPP/7zip/UI/Resource/ExtractDialog/resource.rc b/CPP/7zip/UI/Resource/ExtractDialog/resource.rc
new file mode 100755
index 00000000..05cf5ea6
--- /dev/null
+++ b/CPP/7zip/UI/Resource/ExtractDialog/resource.rc
@@ -0,0 +1,80 @@
+#include "resource.h"
+#include "../../../GuiCommon.rc"
+
+#define xSize2 285
+#define ySize2 204
+
+#define xSize (xSize2 + marg + marg)
+#define ySize (ySize2 + marg + marg)
+
+#undef g1XSize
+#undef g1XSize2
+#undef g1XPos2
+#undef g2XPos
+#undef g2XPos2
+#undef g2XSize
+#undef g2XSize2
+
+#define bYPos (ySize - marg - bYSize)
+
+#define g1XSize 127
+#define g1XSize2 (g1XSize - 13)
+#define g1XPos2 (marg + 7)
+
+#define gSpace 14
+#define g2XPos (marg + g1XSize + gSpace)
+#define g2XPos2 (g2XPos + 7)
+#define g2XSize (xSize2 - g1XSize - gSpace)
+#define g2XSize2 (g2XSize - 14)
+
+#define bXPos1 (xSize - marg - bXSize)
+#define bXPos2 (bXPos1 - 10 - bXSize)
+#define bXPos3 (bXPos2 - 10 - bXSize)
+
+IDD_DIALOG_EXTRACT DIALOG DISCARDABLE 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE
+CAPTION "Extract"
+MY_FONT
+BEGIN
+ LTEXT "E&xtract to:", IDC_STATIC_EXTRACT_EXTRACT_TO, marg, marg, xSize2, 8
+
+ COMBOBOX IDC_EXTRACT_COMBO_PATH, marg, 21, xSize2 - bDotsSize - 13, 126, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+
+ PUSHBUTTON "...", IDC_EXTRACT_BUTTON_SET_PATH, xSize - marg - bDotsSize, 20, bDotsSize, bYSize, WS_GROUP
+
+ GROUPBOX "Path mode",IDC_EXTRACT_PATH_MODE, marg, 44, g1XSize, 57
+ CONTROL "Full pathnames", IDC_EXTRACT_RADIO_FULL_PATHNAMES,"Button", BS_AUTORADIOBUTTON | WS_GROUP,
+ g1XPos2, 57, g1XSize2, 10
+ CONTROL "Current pathnames",IDC_EXTRACT_RADIO_CURRENT_PATHNAMES, "Button", BS_AUTORADIOBUTTON,
+ g1XPos2, 71, g1XSize2, 10
+ CONTROL "No pathnames", IDC_EXTRACT_RADIO_NO_PATHNAMES, "Button", BS_AUTORADIOBUTTON,
+ g1XPos2, 85, g1XSize2, 10
+
+ GROUPBOX "Overwrite mode",IDC_EXTRACT_OVERWRITE_MODE, g2XPos, 44, g2XSize, 88, WS_GROUP
+ CONTROL "Ask before overwrite", IDC_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE, "Button", BS_AUTORADIOBUTTON | WS_GROUP,
+ g2XPos2, 57, g2XSize2, 10
+ CONTROL "Overwrite without prompt", IDC_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT, "Button", BS_AUTORADIOBUTTON,
+ g2XPos2, 71, g2XSize2, 10
+ CONTROL "Skip existing files", IDC_EXTRACT_RADIO_SKIP_EXISTING_FILES, "Button", BS_AUTORADIOBUTTON,
+ g2XPos2, 85, g2XSize2, 10
+ CONTROL "Auto rename", IDC_EXTRACT_RADIO_AUTO_RENAME, "Button", BS_AUTORADIOBUTTON,
+ g2XPos2, 99, g2XSize2, 10
+ CONTROL "Auto rename existing files", IDC_EXTRACT_RADIO_AUTO_RENAME_EXISTING, "Button", BS_AUTORADIOBUTTON,
+ g2XPos2,113, g2XSize2, 10
+
+ GROUPBOX "Files",IDC_EXTRACT_FILES, marg, 140, 127, 48, NOT WS_VISIBLE | WS_DISABLED | WS_GROUP
+ CONTROL "&Selected files",IDC_EXTRACT_RADIO_SELECTED_FILES, "Button", BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_DISABLED | WS_GROUP,
+ g1XPos2, 153, g1XSize2, 10
+ CONTROL "&All files",IDC_EXTRACT_RADIO_ALL_FILES, "Button", BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_DISABLED,
+ g1XPos2, 166, g1XSize2, 10
+
+ GROUPBOX "Password",IDC_EXTRACT_PASSWORD, g2XPos, 142, g2XSize, 46
+ EDITTEXT IDC_EXTRACT_EDIT_PASSWORD,154,153,130,14, ES_PASSWORD | ES_AUTOHSCROLL
+ CONTROL "Show Password",IDC_EXTRACT_CHECK_SHOW_PASSWORD,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,
+ g2XPos2, 172, g2XSize2, 10
+
+ DEFPUSHBUTTON "OK", IDOK, bXPos3, bYPos, bXSize, bYSize, WS_GROUP
+ PUSHBUTTON "Cancel", IDCANCEL, bXPos2, bYPos, bXSize, bYSize
+ PUSHBUTTON "Help", IDHELP, bXPos1, bYPos, bXSize, bYSize
+END
+
+
diff --git a/CPP/7zip/UI/makefile b/CPP/7zip/UI/makefile
new file mode 100755
index 00000000..942beaa0
--- /dev/null
+++ b/CPP/7zip/UI/makefile
@@ -0,0 +1,10 @@
+DIRS = \
+ Client7z\~ \
+ Console\~ \
+ Explorer\~ \
+ GUI\~ \
+
+all: $(DIRS)
+
+$(DIRS):
+!include "../SubBuild.mak"
diff --git a/CPP/7zip/makefile b/CPP/7zip/makefile
new file mode 100755
index 00000000..1db4c9ad
--- /dev/null
+++ b/CPP/7zip/makefile
@@ -0,0 +1,16 @@
+DIRS = \
+ Compress\~ \
+ Crypto\~ \
+ Archive\~ \
+ UI\~ \
+ Bundles\~ \
+
+all: $(DIRS) FileManager\~
+
+$(DIRS):
+ cd $(@D)
+ $(MAKE) -nologo
+ cd ..
+
+FileManager\~:
+!include "SubBuild.mak"