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

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2003-12-11 03:00:00 +0300
committerKornel LesiƄski <kornel@geekhood.net>2016-05-28 02:15:41 +0300
commit8c1b5c7b7e74c45011ed0c4084ad6b37a35e5a03 (patch)
tree10732297ac552e35b40ac99f8f99ac142c1c0edf
3.133.13
-rwxr-xr-x7zip/Archive/7z/7z.def4
-rwxr-xr-x7zip/Archive/7z/7z.dsp533
-rwxr-xr-x7zip/Archive/7z/7z.dsw29
-rwxr-xr-x7zip/Archive/7z/7z.icobin0 -> 4710 bytes
-rwxr-xr-x7zip/Archive/7z/7zCompressionMode.cpp3
-rwxr-xr-x7zip/Archive/7z/7zCompressionMode.h60
-rwxr-xr-x7zip/Archive/7z/7zDecode.cpp377
-rwxr-xr-x7zip/Archive/7z/7zDecode.h54
-rwxr-xr-x7zip/Archive/7z/7zEncode.cpp570
-rwxr-xr-x7zip/Archive/7z/7zEncode.h56
-rwxr-xr-x7zip/Archive/7z/7zExtract.cpp204
-rwxr-xr-x7zip/Archive/7z/7zFolderInStream.cpp141
-rwxr-xr-x7zip/Archive/7z/7zFolderInStream.h68
-rwxr-xr-x7zip/Archive/7z/7zFolderOutStream.cpp165
-rwxr-xr-x7zip/Archive/7z/7zFolderOutStream.h58
-rwxr-xr-x7zip/Archive/7z/7zHandler.cpp442
-rwxr-xr-x7zip/Archive/7z/7zHandler.h208
-rwxr-xr-x7zip/Archive/7z/7zHandlerOut.cpp1160
-rwxr-xr-x7zip/Archive/7z/7zHeader.cpp18
-rwxr-xr-x7zip/Archive/7z/7zHeader.h85
-rwxr-xr-x7zip/Archive/7z/7zIn.cpp1158
-rwxr-xr-x7zip/Archive/7z/7zIn.h266
-rwxr-xr-x7zip/Archive/7z/7zItem.h195
-rwxr-xr-x7zip/Archive/7z/7zMethodID.cpp68
-rwxr-xr-x7zip/Archive/7z/7zMethodID.h38
-rwxr-xr-x7zip/Archive/7z/7zMethods.cpp174
-rwxr-xr-x7zip/Archive/7z/7zMethods.h36
-rwxr-xr-x7zip/Archive/7z/7zOut.cpp853
-rwxr-xr-x7zip/Archive/7z/7zOut.h154
-rwxr-xr-x7zip/Archive/7z/7zProperties.cpp157
-rwxr-xr-x7zip/Archive/7z/7zProperties.h51
-rwxr-xr-x7zip/Archive/7z/7zSpecStream.cpp34
-rwxr-xr-x7zip/Archive/7z/7zSpecStream.h38
-rwxr-xr-x7zip/Archive/7z/7zUpdate.cpp737
-rwxr-xr-x7zip/Archive/7z/7zUpdate.h72
-rwxr-xr-x7zip/Archive/7z/DllExports.cpp90
-rwxr-xr-x7zip/Archive/7z/StdAfx.cpp3
-rwxr-xr-x7zip/Archive/7z/StdAfx.h23
-rwxr-xr-x7zip/Archive/7z/resource.h16
-rwxr-xr-x7zip/Archive/7z/resource.rc130
-rwxr-xr-x7zip/Archive/Arj/Arj.def7
-rwxr-xr-x7zip/Archive/Arj/Arj.dsp309
-rwxr-xr-x7zip/Archive/Arj/Arj.dsw29
-rwxr-xr-x7zip/Archive/Arj/ArjHandler.cpp482
-rwxr-xr-x7zip/Archive/Arj/ArjHandler.h49
-rwxr-xr-x7zip/Archive/Arj/ArjHeader.h124
-rwxr-xr-x7zip/Archive/Arj/ArjIn.cpp221
-rwxr-xr-x7zip/Archive/Arj/ArjIn.h70
-rwxr-xr-x7zip/Archive/Arj/ArjItem.h77
-rwxr-xr-x7zip/Archive/Arj/DllExports.cpp69
-rwxr-xr-x7zip/Archive/Arj/StdAfx.cpp3
-rwxr-xr-x7zip/Archive/Arj/StdAfx.h9
-rwxr-xr-x7zip/Archive/Arj/arj.icobin0 -> 3638 bytes
-rwxr-xr-x7zip/Archive/Arj/resource.h16
-rwxr-xr-x7zip/Archive/Arj/resource.rc130
-rwxr-xr-x7zip/Archive/BZip2/BZip2.def8
-rwxr-xr-x7zip/Archive/BZip2/BZip2.dsp241
-rwxr-xr-x7zip/Archive/BZip2/BZip2.dsw29
-rwxr-xr-x7zip/Archive/BZip2/BZip2Handler.cpp215
-rwxr-xr-x7zip/Archive/BZip2/BZip2Handler.h61
-rwxr-xr-x7zip/Archive/BZip2/BZip2HandlerOut.cpp92
-rwxr-xr-x7zip/Archive/BZip2/BZip2Item.h22
-rwxr-xr-x7zip/Archive/BZip2/BZip2Update.cpp58
-rwxr-xr-x7zip/Archive/BZip2/BZip2Update.h23
-rwxr-xr-x7zip/Archive/BZip2/DllExports.cpp105
-rwxr-xr-x7zip/Archive/BZip2/StdAfx.cpp3
-rwxr-xr-x7zip/Archive/BZip2/StdAfx.h8
-rwxr-xr-x7zip/Archive/BZip2/bz2.icobin0 -> 3638 bytes
-rwxr-xr-x7zip/Archive/BZip2/resource.h16
-rwxr-xr-x7zip/Archive/BZip2/resource.rc130
-rwxr-xr-x7zip/Archive/Cab/Cab.def7
-rwxr-xr-x7zip/Archive/Cab/Cab.dsp325
-rwxr-xr-x7zip/Archive/Cab/Cab.dsw29
-rwxr-xr-x7zip/Archive/Cab/CabCopyDecoder.cpp67
-rwxr-xr-x7zip/Archive/Cab/CabCopyDecoder.h43
-rwxr-xr-x7zip/Archive/Cab/CabHandler.cpp636
-rwxr-xr-x7zip/Archive/Cab/CabHandler.h50
-rwxr-xr-x7zip/Archive/Cab/CabHeader.cpp19
-rwxr-xr-x7zip/Archive/Cab/CabHeader.h117
-rwxr-xr-x7zip/Archive/Cab/CabIn.cpp189
-rwxr-xr-x7zip/Archive/Cab/CabIn.h68
-rwxr-xr-x7zip/Archive/Cab/CabInBuffer.cpp153
-rwxr-xr-x7zip/Archive/Cab/CabInBuffer.h62
-rwxr-xr-x7zip/Archive/Cab/CabItem.h33
-rwxr-xr-x7zip/Archive/Cab/DllExports.cpp66
-rwxr-xr-x7zip/Archive/Cab/LZXBitDecoder.h112
-rwxr-xr-x7zip/Archive/Cab/LZXConst.h112
-rwxr-xr-x7zip/Archive/Cab/LZXDecoder.cpp311
-rwxr-xr-x7zip/Archive/Cab/LZXDecoder.h98
-rwxr-xr-x7zip/Archive/Cab/LZXExtConst.h31
-rwxr-xr-x7zip/Archive/Cab/LZXi86Converter.cpp124
-rwxr-xr-x7zip/Archive/Cab/LZXi86Converter.h46
-rwxr-xr-x7zip/Archive/Cab/MSZipConst.h94
-rwxr-xr-x7zip/Archive/Cab/MSZipDecoder.cpp269
-rwxr-xr-x7zip/Archive/Cab/MSZipDecoder.h88
-rwxr-xr-x7zip/Archive/Cab/MSZipExtConst.h22
-rwxr-xr-x7zip/Archive/Cab/StdAfx.cpp3
-rwxr-xr-x7zip/Archive/Cab/StdAfx.h9
-rwxr-xr-x7zip/Archive/Cab/cab.icobin0 -> 3638 bytes
-rwxr-xr-x7zip/Archive/Cab/resource.h16
-rwxr-xr-x7zip/Archive/Cab/resource.rc130
-rwxr-xr-x7zip/Archive/Common/CodecsPath.cpp34
-rwxr-xr-x7zip/Archive/Common/CodecsPath.h14
-rwxr-xr-x7zip/Archive/Common/CoderLoader.h108
-rwxr-xr-x7zip/Archive/Common/CoderMixer.cpp238
-rwxr-xr-x7zip/Archive/Common/CoderMixer.h87
-rwxr-xr-x7zip/Archive/Common/CoderMixer2.cpp448
-rwxr-xr-x7zip/Archive/Common/CoderMixer2.h254
-rwxr-xr-x7zip/Archive/Common/CoderPaths.cpp34
-rwxr-xr-x7zip/Archive/Common/CrossThreadProgress.cpp15
-rwxr-xr-x7zip/Archive/Common/CrossThreadProgress.h33
-rwxr-xr-x7zip/Archive/Common/DummyOutStream.cpp30
-rwxr-xr-x7zip/Archive/Common/DummyOutStream.h26
-rwxr-xr-x7zip/Archive/Common/InStreamWithCRC.cpp39
-rwxr-xr-x7zip/Archive/Common/InStreamWithCRC.h38
-rwxr-xr-x7zip/Archive/Common/ItemNameUtils.cpp37
-rwxr-xr-x7zip/Archive/Common/ItemNameUtils.h19
-rwxr-xr-x7zip/Archive/Common/OutStreamWithCRC.cpp41
-rwxr-xr-x7zip/Archive/Common/OutStreamWithCRC.h36
-rwxr-xr-x7zip/Archive/Common/StdAfx.h8
-rwxr-xr-x7zip/Archive/Deb/Deb.def8
-rwxr-xr-x7zip/Archive/Deb/Deb.dsp241
-rwxr-xr-x7zip/Archive/Deb/Deb.dsw29
-rwxr-xr-x7zip/Archive/Deb/DebHandler.cpp262
-rwxr-xr-x7zip/Archive/Deb/DebHandler.h49
-rwxr-xr-x7zip/Archive/Deb/DebHeader.cpp14
-rwxr-xr-x7zip/Archive/Deb/DebHeader.h44
-rwxr-xr-x7zip/Archive/Deb/DebIn.cpp136
-rwxr-xr-x7zip/Archive/Deb/DebIn.h31
-rwxr-xr-x7zip/Archive/Deb/DebItem.h34
-rwxr-xr-x7zip/Archive/Deb/DllExports.cpp73
-rwxr-xr-x7zip/Archive/Deb/StdAfx.cpp3
-rwxr-xr-x7zip/Archive/Deb/StdAfx.h10
-rwxr-xr-x7zip/Archive/Deb/deb.icobin0 -> 3638 bytes
-rwxr-xr-x7zip/Archive/Deb/resource.h16
-rwxr-xr-x7zip/Archive/Deb/resource.rc130
-rwxr-xr-x7zip/Archive/GZip/DllExports.cpp103
-rwxr-xr-x7zip/Archive/GZip/GZip.def8
-rwxr-xr-x7zip/Archive/GZip/GZip.dsp309
-rwxr-xr-x7zip/Archive/GZip/GZip.dsw29
-rwxr-xr-x7zip/Archive/GZip/GZipHandler.cpp361
-rwxr-xr-x7zip/Archive/GZip/GZipHandler.h77
-rwxr-xr-x7zip/Archive/GZip/GZipHandlerOut.cpp215
-rwxr-xr-x7zip/Archive/GZip/GZipHeader.cpp20
-rwxr-xr-x7zip/Archive/GZip/GZipHeader.h100
-rwxr-xr-x7zip/Archive/GZip/GZipIn.cpp132
-rwxr-xr-x7zip/Archive/GZip/GZipIn.h34
-rwxr-xr-x7zip/Archive/GZip/GZipItem.h65
-rwxr-xr-x7zip/Archive/GZip/GZipOut.cpp48
-rwxr-xr-x7zip/Archive/GZip/GZipOut.h28
-rwxr-xr-x7zip/Archive/GZip/GZipUpdate.cpp110
-rwxr-xr-x7zip/Archive/GZip/GZipUpdate.h32
-rwxr-xr-x7zip/Archive/GZip/StdAfx.cpp3
-rwxr-xr-x7zip/Archive/GZip/StdAfx.h10
-rwxr-xr-x7zip/Archive/GZip/gz.icobin0 -> 3638 bytes
-rwxr-xr-x7zip/Archive/GZip/resource.h16
-rwxr-xr-x7zip/Archive/GZip/resource.rc130
-rwxr-xr-x7zip/Archive/IArchive.h172
-rwxr-xr-x7zip/Archive/RPM/DllExports.cpp69
-rwxr-xr-x7zip/Archive/RPM/Rpm.def8
-rwxr-xr-x7zip/Archive/RPM/Rpm.dsp189
-rwxr-xr-x7zip/Archive/RPM/Rpm.dsw29
-rwxr-xr-x7zip/Archive/RPM/RpmHandler.cpp195
-rwxr-xr-x7zip/Archive/RPM/RpmHandler.h49
-rwxr-xr-x7zip/Archive/RPM/RpmHeader.h89
-rwxr-xr-x7zip/Archive/RPM/RpmIn.cpp70
-rwxr-xr-x7zip/Archive/RPM/RpmIn.h17
-rwxr-xr-x7zip/Archive/RPM/StdAfx.cpp3
-rwxr-xr-x7zip/Archive/RPM/StdAfx.h8
-rwxr-xr-x7zip/Archive/RPM/resource.h15
-rwxr-xr-x7zip/Archive/RPM/resource.rc130
-rwxr-xr-x7zip/Archive/RPM/rpm.icobin0 -> 3638 bytes
-rwxr-xr-x7zip/Archive/Rar/DllExports.cpp160
-rwxr-xr-x7zip/Archive/Rar/Rar.def7
-rwxr-xr-x7zip/Archive/Rar/Rar.dsp433
-rwxr-xr-x7zip/Archive/Rar/Rar.dsw29
-rwxr-xr-x7zip/Archive/Rar/RarHandler.cpp977
-rwxr-xr-x7zip/Archive/Rar/RarHandler.h65
-rwxr-xr-x7zip/Archive/Rar/RarHeader.cpp64
-rwxr-xr-x7zip/Archive/Rar/RarHeader.h214
-rwxr-xr-x7zip/Archive/Rar/RarIn.cpp407
-rwxr-xr-x7zip/Archive/Rar/RarIn.h96
-rwxr-xr-x7zip/Archive/Rar/RarItem.cpp108
-rwxr-xr-x7zip/Archive/Rar/RarItem.h92
-rwxr-xr-x7zip/Archive/Rar/RarItemEx.h19
-rwxr-xr-x7zip/Archive/Rar/RarVolumeInStream.cpp83
-rwxr-xr-x7zip/Archive/Rar/RarVolumeInStream.h53
-rwxr-xr-x7zip/Archive/Rar/StdAfx.cpp3
-rwxr-xr-x7zip/Archive/Rar/StdAfx.h9
-rwxr-xr-x7zip/Archive/Rar/rar.icobin0 -> 3638 bytes
-rwxr-xr-x7zip/Archive/Rar/resource.h16
-rwxr-xr-x7zip/Archive/Rar/resource.rc130
-rwxr-xr-x7zip/Archive/Split/DllExports.cpp63
-rwxr-xr-x7zip/Archive/Split/Split.def8
-rwxr-xr-x7zip/Archive/Split/Split.dsp217
-rwxr-xr-x7zip/Archive/Split/Split.dsw29
-rwxr-xr-x7zip/Archive/Split/Split.icobin0 -> 3638 bytes
-rwxr-xr-x7zip/Archive/Split/SplitHandler.cpp392
-rwxr-xr-x7zip/Archive/Split/SplitHandler.h60
-rwxr-xr-x7zip/Archive/Split/SplitHanlerOut.cpp93
-rwxr-xr-x7zip/Archive/Split/StdAfx.cpp3
-rwxr-xr-x7zip/Archive/Split/StdAfx.h8
-rwxr-xr-x7zip/Archive/Split/resource.h16
-rwxr-xr-x7zip/Archive/Split/resource.rc130
-rwxr-xr-x7zip/Archive/Tar/DllExports.cpp80
-rwxr-xr-x7zip/Archive/Tar/StdAfx.cpp3
-rwxr-xr-x7zip/Archive/Tar/StdAfx.h9
-rwxr-xr-x7zip/Archive/Tar/Tar.def7
-rwxr-xr-x7zip/Archive/Tar/Tar.dsp269
-rwxr-xr-x7zip/Archive/Tar/Tar.dsw29
-rwxr-xr-x7zip/Archive/Tar/TarHandler.cpp281
-rwxr-xr-x7zip/Archive/Tar/TarHandler.h58
-rwxr-xr-x7zip/Archive/Tar/TarHandlerOut.cpp122
-rwxr-xr-x7zip/Archive/Tar/TarHeader.cpp25
-rwxr-xr-x7zip/Archive/Tar/TarHeader.h107
-rwxr-xr-x7zip/Archive/Tar/TarIn.cpp191
-rwxr-xr-x7zip/Archive/Tar/TarIn.h32
-rwxr-xr-x7zip/Archive/Tar/TarItem.h67
-rwxr-xr-x7zip/Archive/Tar/TarOut.cpp155
-rwxr-xr-x7zip/Archive/Tar/TarOut.h30
-rwxr-xr-x7zip/Archive/Tar/TarUpdate.cpp156
-rwxr-xr-x7zip/Archive/Tar/TarUpdate.h38
-rwxr-xr-x7zip/Archive/Tar/resource.h16
-rwxr-xr-x7zip/Archive/Tar/resource.rc130
-rwxr-xr-x7zip/Archive/Tar/tar.icobin0 -> 3638 bytes
-rwxr-xr-x7zip/Archive/Zip/DllExports.cpp122
-rwxr-xr-x7zip/Archive/Zip/StdAfx.cpp3
-rwxr-xr-x7zip/Archive/Zip/StdAfx.h31
-rwxr-xr-x7zip/Archive/Zip/Zip.def7
-rwxr-xr-x7zip/Archive/Zip/Zip.dsp441
-rwxr-xr-x7zip/Archive/Zip/Zip.dsw29
-rwxr-xr-x7zip/Archive/Zip/ZipAddCommon.cpp270
-rwxr-xr-x7zip/Archive/Zip/ZipAddCommon.h56
-rwxr-xr-x7zip/Archive/Zip/ZipCompressionMode.h26
-rwxr-xr-x7zip/Archive/Zip/ZipHandler.cpp612
-rwxr-xr-x7zip/Archive/Zip/ZipHandler.h73
-rwxr-xr-x7zip/Archive/Zip/ZipHandlerOut.cpp284
-rwxr-xr-x7zip/Archive/Zip/ZipHeader.cpp32
-rwxr-xr-x7zip/Archive/Zip/ZipHeader.h227
-rwxr-xr-x7zip/Archive/Zip/ZipIn.cpp376
-rwxr-xr-x7zip/Archive/Zip/ZipIn.h84
-rwxr-xr-x7zip/Archive/Zip/ZipItem.cpp132
-rwxr-xr-x7zip/Archive/Zip/ZipItem.h72
-rwxr-xr-x7zip/Archive/Zip/ZipItemEx.h47
-rwxr-xr-x7zip/Archive/Zip/ZipOut.cpp134
-rwxr-xr-x7zip/Archive/Zip/ZipOut.h53
-rwxr-xr-x7zip/Archive/Zip/ZipUpdate.cpp357
-rwxr-xr-x7zip/Archive/Zip/ZipUpdate.h59
-rwxr-xr-x7zip/Archive/Zip/resource.h16
-rwxr-xr-x7zip/Archive/Zip/resource.rc130
-rwxr-xr-x7zip/Archive/Zip/zip.icobin0 -> 3638 bytes
-rwxr-xr-x7zip/Archive/cpio/CpioHandler.cpp287
-rwxr-xr-x7zip/Archive/cpio/CpioHandler.h49
-rwxr-xr-x7zip/Archive/cpio/CpioHeader.cpp22
-rwxr-xr-x7zip/Archive/cpio/CpioHeader.h69
-rwxr-xr-x7zip/Archive/cpio/CpioIn.cpp167
-rwxr-xr-x7zip/Archive/cpio/CpioIn.h31
-rwxr-xr-x7zip/Archive/cpio/CpioItem.h53
-rwxr-xr-x7zip/Archive/cpio/DllExports.cpp66
-rwxr-xr-x7zip/Archive/cpio/StdAfx.cpp3
-rwxr-xr-x7zip/Archive/cpio/StdAfx.h10
-rwxr-xr-x7zip/Archive/cpio/cpio.def8
-rwxr-xr-x7zip/Archive/cpio/cpio.dsp241
-rwxr-xr-x7zip/Archive/cpio/cpio.dsw29
-rwxr-xr-x7zip/Archive/cpio/cpio.icobin0 -> 3638 bytes
-rwxr-xr-x7zip/Archive/cpio/resource.h16
-rwxr-xr-x7zip/Archive/cpio/resource.rc130
-rwxr-xr-x7zip/Bundles/Alone/Alone.dsp2150
-rwxr-xr-x7zip/Bundles/Alone/Alone.dsw29
-rwxr-xr-x7zip/Bundles/Alone/StdAfx.cpp3
-rwxr-xr-x7zip/Bundles/Alone/StdAfx.h12
-rwxr-xr-x7zip/Bundles/Alone/afxres.h1
-rwxr-xr-x7zip/Bundles/Alone/resource.h15
-rwxr-xr-x7zip/Bundles/Alone/resource.rc121
-rwxr-xr-x7zip/Bundles/Format7z/Format7z.dsp905
-rwxr-xr-x7zip/Bundles/Format7z/Format7z.dsw29
-rwxr-xr-x7zip/Bundles/SFXCon/7z.icobin0 -> 1078 bytes
-rwxr-xr-x7zip/Bundles/SFXCon/Main.cpp459
-rwxr-xr-x7zip/Bundles/SFXCon/SFXCon.dsp675
-rwxr-xr-x7zip/Bundles/SFXCon/SFXCon.dsw29
-rwxr-xr-x7zip/Bundles/SFXCon/StdAfx.cpp3
-rwxr-xr-x7zip/Bundles/SFXCon/StdAfx.h11
-rwxr-xr-x7zip/Bundles/SFXCon/resource.h16
-rwxr-xr-x7zip/Bundles/SFXCon/resource.rc130
-rwxr-xr-x7zip/Bundles/SFXSetup/ExtractCallback.cpp266
-rwxr-xr-x7zip/Bundles/SFXSetup/ExtractCallback.h105
-rwxr-xr-x7zip/Bundles/SFXSetup/ExtractEngine.cpp150
-rwxr-xr-x7zip/Bundles/SFXSetup/ExtractEngine.h17
-rwxr-xr-x7zip/Bundles/SFXSetup/Main.cpp235
-rwxr-xr-x7zip/Bundles/SFXSetup/SFXSetup.dsp617
-rwxr-xr-x7zip/Bundles/SFXSetup/SFXSetup.dsw29
-rwxr-xr-x7zip/Bundles/SFXSetup/StdAfx.cpp3
-rwxr-xr-x7zip/Bundles/SFXSetup/StdAfx.h11
-rwxr-xr-x7zip/Bundles/SFXSetup/resource.h19
-rwxr-xr-x7zip/Bundles/SFXSetup/resource.rc148
-rwxr-xr-x7zip/Bundles/SFXSetup/setup.icobin0 -> 1078 bytes
-rwxr-xr-x7zip/Bundles/SFXWin/7z.icobin0 -> 1078 bytes
-rwxr-xr-x7zip/Bundles/SFXWin/Main.cpp66
-rwxr-xr-x7zip/Bundles/SFXWin/SFXWin.dsp788
-rwxr-xr-x7zip/Bundles/SFXWin/SFXWin.dsw29
-rwxr-xr-x7zip/Bundles/SFXWin/StdAfx.cpp3
-rwxr-xr-x7zip/Bundles/SFXWin/StdAfx.h14
-rwxr-xr-x7zip/Bundles/SFXWin/resource.h23
-rwxr-xr-x7zip/Bundles/SFXWin/resource.rc159
-rwxr-xr-x7zip/Common/FilePathAutoRename.cpp53
-rwxr-xr-x7zip/Common/FilePathAutoRename.h12
-rwxr-xr-x7zip/Common/FileStreams.cpp110
-rwxr-xr-x7zip/Common/FileStreams.h55
-rwxr-xr-x7zip/Common/InBuffer.cpp41
-rwxr-xr-x7zip/Common/InBuffer.h66
-rwxr-xr-x7zip/Common/InOutTempBuffer.cpp148
-rwxr-xr-x7zip/Common/InOutTempBuffer.h59
-rwxr-xr-x7zip/Common/LSBFDecoder.cpp34
-rwxr-xr-x7zip/Common/LSBFDecoder.h96
-rwxr-xr-x7zip/Common/LSBFEncoder.cpp46
-rwxr-xr-x7zip/Common/LSBFEncoder.h59
-rwxr-xr-x7zip/Common/LimitedStreams.cpp36
-rwxr-xr-x7zip/Common/LimitedStreams.h26
-rwxr-xr-x7zip/Common/MSBFDecoder.h73
-rwxr-xr-x7zip/Common/MSBFEncoder.h70
-rwxr-xr-x7zip/Common/MultiStream.cpp42
-rwxr-xr-x7zip/Common/MultiStream.h42
-rwxr-xr-x7zip/Common/OffsetStream.cpp41
-rwxr-xr-x7zip/Common/OffsetStream.h28
-rwxr-xr-x7zip/Common/OutBuffer.cpp53
-rwxr-xr-x7zip/Common/OutBuffer.h62
-rwxr-xr-x7zip/Common/ProgressUtils.cpp58
-rwxr-xr-x7zip/Common/ProgressUtils.h50
-rwxr-xr-x7zip/Common/StdAfx.h8
-rwxr-xr-x7zip/Common/StreamBinder.cpp197
-rwxr-xr-x7zip/Common/StreamBinder.h42
-rwxr-xr-x7zip/Common/StreamObjects.cpp146
-rwxr-xr-x7zip/Common/StreamObjects.h179
-rwxr-xr-x7zip/Compress/Arj/Decoder1.cpp317
-rwxr-xr-x7zip/Compress/Arj/Decoder1.h110
-rwxr-xr-x7zip/Compress/Arj/Decoder2.cpp95
-rwxr-xr-x7zip/Compress/Arj/Decoder2.h69
-rwxr-xr-x7zip/Compress/BZip2/BZip2.def9
-rwxr-xr-x7zip/Compress/BZip2/BZip2.dsp297
-rwxr-xr-x7zip/Compress/BZip2/BZip2.dsw29
-rwxr-xr-x7zip/Compress/BZip2/BZip2Decoder.cpp125
-rwxr-xr-x7zip/Compress/BZip2/BZip2Decoder.h41
-rwxr-xr-x7zip/Compress/BZip2/BZip2Encoder.cpp120
-rwxr-xr-x7zip/Compress/BZip2/BZip2Encoder.h36
-rwxr-xr-x7zip/Compress/BZip2/BZip2Error.cpp10
-rwxr-xr-x7zip/Compress/BZip2/DllExports.cpp86
-rwxr-xr-x7zip/Compress/BZip2/StdAfx.cpp3
-rwxr-xr-x7zip/Compress/BZip2/StdAfx.h8
-rwxr-xr-x7zip/Compress/BZip2/resource.h15
-rwxr-xr-x7zip/Compress/BZip2/resource.rc121
-rwxr-xr-x7zip/Compress/Branch/ARM.cpp69
-rwxr-xr-x7zip/Compress/Branch/ARM.h12
-rwxr-xr-x7zip/Compress/Branch/ARMThumb.cpp76
-rwxr-xr-x7zip/Compress/Branch/ARMThumb.h12
-rwxr-xr-x7zip/Compress/Branch/Alpha.cpp75
-rwxr-xr-x7zip/Compress/Branch/Alpha.h12
-rwxr-xr-x7zip/Compress/Branch/Branch.def9
-rwxr-xr-x7zip/Compress/Branch/Branch.dsp310
-rwxr-xr-x7zip/Compress/Branch/Branch.dsw29
-rwxr-xr-x7zip/Compress/Branch/Coder.h66
-rwxr-xr-x7zip/Compress/Branch/DllExports.cpp178
-rwxr-xr-x7zip/Compress/Branch/IA64.cpp103
-rwxr-xr-x7zip/Compress/Branch/IA64.h14
-rwxr-xr-x7zip/Compress/Branch/M68.cpp69
-rwxr-xr-x7zip/Compress/Branch/M68.h12
-rwxr-xr-x7zip/Compress/Branch/PPC.cpp76
-rwxr-xr-x7zip/Compress/Branch/PPC.h12
-rwxr-xr-x7zip/Compress/Branch/StdAfx.cpp3
-rwxr-xr-x7zip/Compress/Branch/StdAfx.h8
-rwxr-xr-x7zip/Compress/Branch/resource.h15
-rwxr-xr-x7zip/Compress/Branch/resource.rc121
-rwxr-xr-x7zip/Compress/Branch/x86.cpp124
-rwxr-xr-x7zip/Compress/Branch/x86.h13
-rwxr-xr-x7zip/Compress/Branch/x86_2.cpp331
-rwxr-xr-x7zip/Compress/Branch/x86_2.h147
-rwxr-xr-x7zip/Compress/ByteSwap/ByteSwap.cpp100
-rwxr-xr-x7zip/Compress/ByteSwap/ByteSwap.def9
-rwxr-xr-x7zip/Compress/ByteSwap/ByteSwap.dsp125
-rwxr-xr-x7zip/Compress/ByteSwap/ByteSwap.dsw29
-rwxr-xr-x7zip/Compress/ByteSwap/ByteSwap.h51
-rwxr-xr-x7zip/Compress/ByteSwap/DllExports.cpp92
-rwxr-xr-x7zip/Compress/ByteSwap/StdAfx.cpp3
-rwxr-xr-x7zip/Compress/ByteSwap/StdAfx.h8
-rwxr-xr-x7zip/Compress/ByteSwap/resource.h15
-rwxr-xr-x7zip/Compress/ByteSwap/resource.rc121
-rwxr-xr-x7zip/Compress/Copy/Copy.def4
-rwxr-xr-x7zip/Compress/Copy/Copy.dsp125
-rwxr-xr-x7zip/Compress/Copy/Copy.dsw29
-rwxr-xr-x7zip/Compress/Copy/CopyCoder.cpp45
-rwxr-xr-x7zip/Compress/Copy/CopyCoder.h34
-rwxr-xr-x7zip/Compress/Copy/DllExports.cpp70
-rwxr-xr-x7zip/Compress/Copy/StdAfx.cpp3
-rwxr-xr-x7zip/Compress/Copy/StdAfx.h8
-rwxr-xr-x7zip/Compress/Copy/resource.h15
-rwxr-xr-x7zip/Compress/Copy/resource.rc121
-rwxr-xr-x7zip/Compress/Deflate/Deflate.def8
-rwxr-xr-x7zip/Compress/Deflate/Deflate.dsp275
-rwxr-xr-x7zip/Compress/Deflate/Deflate.dsw29
-rwxr-xr-x7zip/Compress/Deflate/DeflateConst.h106
-rwxr-xr-x7zip/Compress/Deflate/DeflateDecoder.cpp291
-rwxr-xr-x7zip/Compress/Deflate/DeflateDecoder.h128
-rwxr-xr-x7zip/Compress/Deflate/DeflateEncoder.cpp785
-rwxr-xr-x7zip/Compress/Deflate/DeflateEncoder.h197
-rwxr-xr-x7zip/Compress/Deflate/DeflateExtConst.h27
-rwxr-xr-x7zip/Compress/Deflate/DllExports.cpp126
-rwxr-xr-x7zip/Compress/Deflate/StdAfx.cpp3
-rwxr-xr-x7zip/Compress/Deflate/StdAfx.h8
-rwxr-xr-x7zip/Compress/Deflate/resource.h15
-rwxr-xr-x7zip/Compress/Deflate/resource.rc121
-rwxr-xr-x7zip/Compress/Huffman/HuffmanDecoder.h113
-rwxr-xr-x7zip/Compress/Huffman/HuffmanEncoder.cpp296
-rwxr-xr-x7zip/Compress/Huffman/HuffmanEncoder.h66
-rwxr-xr-x7zip/Compress/Huffman/StdAfx.h6
-rwxr-xr-x7zip/Compress/Implode/DllExports.cpp66
-rwxr-xr-x7zip/Compress/Implode/Implode.def9
-rwxr-xr-x7zip/Compress/Implode/Implode.dsp181
-rwxr-xr-x7zip/Compress/Implode/Implode.dsw29
-rwxr-xr-x7zip/Compress/Implode/ImplodeDecoder.cpp210
-rwxr-xr-x7zip/Compress/Implode/ImplodeDecoder.h77
-rwxr-xr-x7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp88
-rwxr-xr-x7zip/Compress/Implode/ImplodeHuffmanDecoder.h36
-rwxr-xr-x7zip/Compress/Implode/StdAfx.cpp3
-rwxr-xr-x7zip/Compress/Implode/StdAfx.h8
-rwxr-xr-x7zip/Compress/Implode/resource.h15
-rwxr-xr-x7zip/Compress/Implode/resource.rc121
-rwxr-xr-x7zip/Compress/LZ/BinTree/BinTree.h116
-rwxr-xr-x7zip/Compress/LZ/BinTree/BinTree2.h18
-rwxr-xr-x7zip/Compress/LZ/BinTree/BinTree3.h22
-rwxr-xr-x7zip/Compress/LZ/BinTree/BinTree3Z.h19
-rwxr-xr-x7zip/Compress/LZ/BinTree/BinTree3ZMain.h18
-rwxr-xr-x7zip/Compress/LZ/BinTree/BinTree4.h24
-rwxr-xr-x7zip/Compress/LZ/BinTree/BinTree4b.h26
-rwxr-xr-x7zip/Compress/LZ/BinTree/BinTreeMF.h110
-rwxr-xr-x7zip/Compress/LZ/BinTree/BinTreeMFMain.h81
-rwxr-xr-x7zip/Compress/LZ/BinTree/BinTreeMain.h542
-rwxr-xr-x7zip/Compress/LZ/HashChain/HC.h108
-rwxr-xr-x7zip/Compress/LZ/HashChain/HC2.h18
-rwxr-xr-x7zip/Compress/LZ/HashChain/HC3.h22
-rwxr-xr-x7zip/Compress/LZ/HashChain/HC4.h24
-rwxr-xr-x7zip/Compress/LZ/HashChain/HC4b.h26
-rwxr-xr-x7zip/Compress/LZ/HashChain/HCMF.h111
-rwxr-xr-x7zip/Compress/LZ/HashChain/HCMFMain.h78
-rwxr-xr-x7zip/Compress/LZ/HashChain/HCMain.h436
-rwxr-xr-x7zip/Compress/LZ/IMatchFinder.h65
-rwxr-xr-x7zip/Compress/LZ/LZInWindow.cpp98
-rwxr-xr-x7zip/Compress/LZ/LZInWindow.h89
-rwxr-xr-x7zip/Compress/LZ/LZOutWindow.cpp83
-rwxr-xr-x7zip/Compress/LZ/LZOutWindow.h78
-rwxr-xr-x7zip/Compress/LZ/MT/MT.cpp317
-rwxr-xr-x7zip/Compress/LZ/MT/MT.h85
-rwxr-xr-x7zip/Compress/LZ/MT/StdAfx.h8
-rwxr-xr-x7zip/Compress/LZ/Patricia/Pat.h364
-rwxr-xr-x7zip/Compress/LZ/Patricia/Pat2.h24
-rwxr-xr-x7zip/Compress/LZ/Patricia/Pat2H.h26
-rwxr-xr-x7zip/Compress/LZ/Patricia/Pat2R.h22
-rwxr-xr-x7zip/Compress/LZ/Patricia/Pat3H.h26
-rwxr-xr-x7zip/Compress/LZ/Patricia/Pat4H.h26
-rwxr-xr-x7zip/Compress/LZ/Patricia/PatMain.h976
-rwxr-xr-x7zip/Compress/LZ/StdAfx.h8
-rwxr-xr-x7zip/Compress/LZMA/DllExports.cpp88
-rwxr-xr-x7zip/Compress/LZMA/LZMA.def7
-rwxr-xr-x7zip/Compress/LZMA/LZMA.dsp463
-rwxr-xr-x7zip/Compress/LZMA/LZMA.dsw29
-rwxr-xr-x7zip/Compress/LZMA/LZMA.h96
-rwxr-xr-x7zip/Compress/LZMA/LZMADecoder.cpp356
-rwxr-xr-x7zip/Compress/LZMA/LZMADecoder.h107
-rwxr-xr-x7zip/Compress/LZMA/LZMAEncoder.cpp1274
-rwxr-xr-x7zip/Compress/LZMA/LZMAEncoder.h294
-rwxr-xr-x7zip/Compress/LZMA/LZMALen.cpp74
-rwxr-xr-x7zip/Compress/LZMA/LZMALen.h114
-rwxr-xr-x7zip/Compress/LZMA/LZMALiteral.cpp69
-rwxr-xr-x7zip/Compress/LZMA/LZMALiteral.h166
-rwxr-xr-x7zip/Compress/LZMA/StdAfx.cpp3
-rwxr-xr-x7zip/Compress/LZMA/StdAfx.h8
-rwxr-xr-x7zip/Compress/LZMA/resource.h15
-rwxr-xr-x7zip/Compress/LZMA/resource.rc121
-rwxr-xr-x7zip/Compress/PPMD/DllExports.cpp87
-rwxr-xr-x7zip/Compress/PPMD/PPMD.def9
-rwxr-xr-x7zip/Compress/PPMD/PPMD.dsp205
-rwxr-xr-x7zip/Compress/PPMD/PPMD.dsw29
-rwxr-xr-x7zip/Compress/PPMD/PPMDContext.h447
-rwxr-xr-x7zip/Compress/PPMD/PPMDDecode.h139
-rwxr-xr-x7zip/Compress/PPMD/PPMDDecoder.cpp109
-rwxr-xr-x7zip/Compress/PPMD/PPMDDecoder.h67
-rwxr-xr-x7zip/Compress/PPMD/PPMDEncode.h144
-rwxr-xr-x7zip/Compress/PPMD/PPMDEncoder.cpp182
-rwxr-xr-x7zip/Compress/PPMD/PPMDEncoder.h68
-rwxr-xr-x7zip/Compress/PPMD/PPMDSubAlloc.h205
-rwxr-xr-x7zip/Compress/PPMD/PPMDType.h62
-rwxr-xr-x7zip/Compress/PPMD/StdAfx.cpp3
-rwxr-xr-x7zip/Compress/PPMD/StdAfx.h8
-rwxr-xr-x7zip/Compress/PPMD/resource.h15
-rwxr-xr-x7zip/Compress/PPMD/resource.rc121
-rwxr-xr-x7zip/Compress/RangeCoder/RangeCoder.h244
-rwxr-xr-x7zip/Compress/RangeCoder/RangeCoderBit.cpp77
-rwxr-xr-x7zip/Compress/RangeCoder/RangeCoderBit.h107
-rwxr-xr-x7zip/Compress/RangeCoder/RangeCoderBitTree.h303
-rwxr-xr-x7zip/Compress/RangeCoder/RangeCoderOpt.h43
-rwxr-xr-x7zip/Compress/RangeCoder/StdAfx.h8
-rwxr-xr-x7zip/Crypto/7zAES/7zAES.cpp355
-rwxr-xr-x7zip/Crypto/7zAES/7zAES.def8
-rwxr-xr-x7zip/Crypto/7zAES/7zAES.dsp209
-rwxr-xr-x7zip/Crypto/7zAES/7zAES.dsw29
-rwxr-xr-x7zip/Crypto/7zAES/7zAES.h139
-rwxr-xr-x7zip/Crypto/7zAES/DllExports.cpp96
-rwxr-xr-x7zip/Crypto/7zAES/SHA256.cpp189
-rwxr-xr-x7zip/Crypto/7zAES/SHA256.h30
-rwxr-xr-x7zip/Crypto/7zAES/StdAfx.cpp3
-rwxr-xr-x7zip/Crypto/7zAES/StdAfx.h8
-rwxr-xr-x7zip/Crypto/7zAES/resource.h15
-rwxr-xr-x7zip/Crypto/7zAES/resource.rc121
-rwxr-xr-x7zip/Crypto/AES/AES.def8
-rwxr-xr-x7zip/Crypto/AES/AES.dsp223
-rwxr-xr-x7zip/Crypto/AES/AES.dsw29
-rwxr-xr-x7zip/Crypto/AES/AES_CBC.h48
-rwxr-xr-x7zip/Crypto/AES/DllExports.cpp185
-rwxr-xr-x7zip/Crypto/AES/MyAES.cpp198
-rwxr-xr-x7zip/Crypto/AES/MyAES.h47
-rwxr-xr-x7zip/Crypto/AES/StdAfx.cpp3
-rwxr-xr-x7zip/Crypto/AES/StdAfx.h8
-rwxr-xr-x7zip/Crypto/AES/aes.h103
-rwxr-xr-x7zip/Crypto/AES/aescpp.h55
-rwxr-xr-x7zip/Crypto/AES/aescrypt.c421
-rwxr-xr-x7zip/Crypto/AES/aeskey.c363
-rwxr-xr-x7zip/Crypto/AES/aesopt.h839
-rwxr-xr-x7zip/Crypto/AES/aestab.c494
-rwxr-xr-x7zip/Crypto/AES/resource.h15
-rwxr-xr-x7zip/Crypto/AES/resource.rc121
-rwxr-xr-x7zip/Crypto/Rar20/Rar20Cipher.cpp67
-rwxr-xr-x7zip/Crypto/Rar20/Rar20Cipher.h40
-rwxr-xr-x7zip/Crypto/Rar20/Rar20Crypto.cpp144
-rwxr-xr-x7zip/Crypto/Rar20/Rar20Crypto.h32
-rwxr-xr-x7zip/Crypto/RarAES/RarAES.cpp157
-rwxr-xr-x7zip/Crypto/RarAES/RarAES.h48
-rwxr-xr-x7zip/Crypto/RarAES/sha1.cpp214
-rwxr-xr-x7zip/Crypto/RarAES/sha1.h19
-rwxr-xr-x7zip/Crypto/Zip/StdAfx.h8
-rwxr-xr-x7zip/Crypto/Zip/ZipCipher.cpp118
-rwxr-xr-x7zip/Crypto/Zip/ZipCipher.h72
-rwxr-xr-x7zip/Crypto/Zip/ZipCrypto.cpp65
-rwxr-xr-x7zip/Crypto/Zip/ZipCrypto.h28
-rwxr-xr-x7zip/FileManager/7zFM.exe.manifest1
-rwxr-xr-x7zip/FileManager/7zipLogo.icobin0 -> 9150 bytes
-rwxr-xr-x7zip/FileManager/Add.bmpbin0 -> 982 bytes
-rwxr-xr-x7zip/FileManager/Add2.bmpbin0 -> 406 bytes
-rwxr-xr-x7zip/FileManager/App.cpp786
-rwxr-xr-x7zip/FileManager/App.h239
-rwxr-xr-x7zip/FileManager/AppState.h116
-rwxr-xr-x7zip/FileManager/ClassDefs.cpp29
-rwxr-xr-x7zip/FileManager/Copy.bmpbin0 -> 982 bytes
-rwxr-xr-x7zip/FileManager/Copy2.bmpbin0 -> 406 bytes
-rwxr-xr-x7zip/FileManager/Delete.bmpbin0 -> 982 bytes
-rwxr-xr-x7zip/FileManager/Delete2.bmpbin0 -> 406 bytes
-rwxr-xr-x7zip/FileManager/Extract.bmpbin0 -> 982 bytes
-rwxr-xr-x7zip/FileManager/Extract2.bmpbin0 -> 406 bytes
-rwxr-xr-x7zip/FileManager/ExtractCallback.cpp312
-rwxr-xr-x7zip/FileManager/ExtractCallback.h96
-rwxr-xr-x7zip/FileManager/FM.cpp616
-rwxr-xr-x7zip/FileManager/FM.dsp1179
-rwxr-xr-x7zip/FileManager/FM.dsw29
-rwxr-xr-x7zip/FileManager/FM.icobin0 -> 4846 bytes
-rwxr-xr-x7zip/FileManager/FSDrives.cpp234
-rwxr-xr-x7zip/FileManager/FSDrives.h66
-rwxr-xr-x7zip/FileManager/FSFolder.cpp549
-rwxr-xr-x7zip/FileManager/FSFolder.h108
-rwxr-xr-x7zip/FileManager/FSFolderCopy.cpp495
-rwxr-xr-x7zip/FileManager/FileFolderPluginOpen.cpp108
-rwxr-xr-x7zip/FileManager/FileFolderPluginOpen.h11
-rwxr-xr-x7zip/FileManager/FilePlugins.cpp113
-rwxr-xr-x7zip/FileManager/FilePlugins.h56
-rwxr-xr-x7zip/FileManager/FormatUtils.cpp76
-rwxr-xr-x7zip/FileManager/FormatUtils.h23
-rwxr-xr-x7zip/FileManager/HelpUtils.cpp26
-rwxr-xr-x7zip/FileManager/HelpUtils.h12
-rwxr-xr-x7zip/FileManager/IFolder.h253
-rwxr-xr-x7zip/FileManager/Info.bmpbin0 -> 982 bytes
-rwxr-xr-x7zip/FileManager/Info2.bmpbin0 -> 406 bytes
-rwxr-xr-x7zip/FileManager/LangUtils.cpp74
-rwxr-xr-x7zip/FileManager/LangUtils.h32
-rwxr-xr-x7zip/FileManager/Move.bmpbin0 -> 982 bytes
-rwxr-xr-x7zip/FileManager/Move2.bmpbin0 -> 406 bytes
-rwxr-xr-x7zip/FileManager/MyLoadMenu.cpp730
-rwxr-xr-x7zip/FileManager/MyLoadMenu.h19
-rwxr-xr-x7zip/FileManager/NetFolder.cpp318
-rwxr-xr-x7zip/FileManager/NetFolder.h68
-rwxr-xr-x7zip/FileManager/OpenCallback.cpp99
-rwxr-xr-x7zip/FileManager/OpenCallback.h65
-rwxr-xr-x7zip/FileManager/OptionsDialog.cpp110
-rwxr-xr-x7zip/FileManager/Panel.cpp763
-rwxr-xr-x7zip/FileManager/Panel.h438
-rwxr-xr-x7zip/FileManager/PanelCopy.cpp10
-rwxr-xr-x7zip/FileManager/PanelFolderChange.cpp379
-rwxr-xr-x7zip/FileManager/PanelItemOpen.cpp494
-rwxr-xr-x7zip/FileManager/PanelItems.cpp734
-rwxr-xr-x7zip/FileManager/PanelKey.cpp298
-rwxr-xr-x7zip/FileManager/PanelListNotify.cpp365
-rwxr-xr-x7zip/FileManager/PanelMenu.cpp429
-rwxr-xr-x7zip/FileManager/PanelOperations.cpp269
-rwxr-xr-x7zip/FileManager/PanelSelect.cpp239
-rwxr-xr-x7zip/FileManager/PanelSort.cpp157
-rwxr-xr-x7zip/FileManager/PluginInterface.h44
-rwxr-xr-x7zip/FileManager/PluginLoader.h34
-rwxr-xr-x7zip/FileManager/ProgramLocation.cpp24
-rwxr-xr-x7zip/FileManager/ProgramLocation.h12
-rwxr-xr-x7zip/FileManager/PropertyName.cpp72
-rwxr-xr-x7zip/FileManager/PropertyName.h12
-rwxr-xr-x7zip/FileManager/RegistryAssociations.cpp276
-rwxr-xr-x7zip/FileManager/RegistryAssociations.h48
-rwxr-xr-x7zip/FileManager/RegistryPlugins.cpp144
-rwxr-xr-x7zip/FileManager/RegistryPlugins.h35
-rwxr-xr-x7zip/FileManager/RegistrySystem.cpp152
-rwxr-xr-x7zip/FileManager/RegistrySystem.h28
-rwxr-xr-x7zip/FileManager/RegistryUtils.cpp84
-rwxr-xr-x7zip/FileManager/RegistryUtils.h25
-rwxr-xr-x7zip/FileManager/Resource/AboutDialog/7zipLogo.icobin0 -> 9150 bytes
-rwxr-xr-x7zip/FileManager/Resource/AboutDialog/AboutDialog.cpp66
-rwxr-xr-x7zip/FileManager/Resource/AboutDialog/AboutDialog.h21
-rwxr-xr-x7zip/FileManager/Resource/AboutDialog/resource.h21
-rwxr-xr-x7zip/FileManager/Resource/AboutDialog/resource.rc117
-rwxr-xr-x7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp939
-rwxr-xr-x7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.h142
-rwxr-xr-x7zip/FileManager/Resource/BenchmarkDialog/resource.h49
-rwxr-xr-x7zip/FileManager/Resource/BenchmarkDialog/resource.rc149
-rwxr-xr-x7zip/FileManager/Resource/ComboDialog/ComboDialog.cpp53
-rwxr-xr-x7zip/FileManager/Resource/ComboDialog/ComboDialog.h29
-rwxr-xr-x7zip/FileManager/Resource/ComboDialog/resource.h21
-rwxr-xr-x7zip/FileManager/Resource/ComboDialog/resource.rc100
-rwxr-xr-x7zip/FileManager/Resource/CopyDialog/CopyDialog.cpp78
-rwxr-xr-x7zip/FileManager/Resource/CopyDialog/CopyDialog.h29
-rwxr-xr-x7zip/FileManager/Resource/CopyDialog/resource.h22
-rwxr-xr-x7zip/FileManager/Resource/CopyDialog/resource.rc101
-rwxr-xr-x7zip/FileManager/Resource/EditPage/EditPage.cpp161
-rwxr-xr-x7zip/FileManager/Resource/EditPage/EditPage.h23
-rwxr-xr-x7zip/FileManager/Resource/EditPage/resource.h19
-rwxr-xr-x7zip/FileManager/Resource/EditPage/resource.rc98
-rwxr-xr-x7zip/FileManager/Resource/LangPage/LangPage.cpp102
-rwxr-xr-x7zip/FileManager/Resource/LangPage/LangPage.h23
-rwxr-xr-x7zip/FileManager/Resource/LangPage/resource.h19
-rwxr-xr-x7zip/FileManager/Resource/LangPage/resource.rc99
-rwxr-xr-x7zip/FileManager/Resource/ListBoxDialog/resource.h20
-rwxr-xr-x7zip/FileManager/Resource/ListBoxDialog/resource.rc102
-rwxr-xr-x7zip/FileManager/Resource/ListViewDialog/ListViewDialog.cpp102
-rwxr-xr-x7zip/FileManager/Resource/ListViewDialog/ListViewDialog.h33
-rwxr-xr-x7zip/FileManager/Resource/ListViewDialog/resource.h20
-rwxr-xr-x7zip/FileManager/Resource/ListViewDialog/resource.rc101
-rwxr-xr-x7zip/FileManager/Resource/MessagesDialog/MessagesDialog.cpp87
-rwxr-xr-x7zip/FileManager/Resource/MessagesDialog/MessagesDialog.h24
-rwxr-xr-x7zip/FileManager/Resource/MessagesDialog/resource.h22
-rwxr-xr-x7zip/FileManager/Resource/MessagesDialog/resource.rc114
-rwxr-xr-x7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.cpp123
-rwxr-xr-x7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.h37
-rwxr-xr-x7zip/FileManager/Resource/OverwriteDialog/resource.h36
-rwxr-xr-x7zip/FileManager/Resource/OverwriteDialog/resource.rc132
-rwxr-xr-x7zip/FileManager/Resource/PasswordDialog/PasswordDialog.cpp50
-rwxr-xr-x7zip/FileManager/Resource/PasswordDialog/PasswordDialog.h24
-rwxr-xr-x7zip/FileManager/Resource/PasswordDialog/resource.h19
-rwxr-xr-x7zip/FileManager/Resource/PasswordDialog/resource.rc103
-rwxr-xr-x7zip/FileManager/Resource/PluginsPage/PluginsPage.cpp233
-rwxr-xr-x7zip/FileManager/Resource/PluginsPage/PluginsPage.h29
-rwxr-xr-x7zip/FileManager/Resource/PluginsPage/resource.h19
-rwxr-xr-x7zip/FileManager/Resource/PluginsPage/resource.rc100
-rwxr-xr-x7zip/FileManager/Resource/ProgressDialog/ProgressDialog.cpp175
-rwxr-xr-x7zip/FileManager/Resource/ProgressDialog/ProgressDialog.h131
-rwxr-xr-x7zip/FileManager/Resource/ProgressDialog/resource.h20
-rwxr-xr-x7zip/FileManager/Resource/ProgressDialog/resource.rc101
-rwxr-xr-x7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.cpp369
-rwxr-xr-x7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.h160
-rwxr-xr-x7zip/FileManager/Resource/ProgressDialog2/resource.h32
-rwxr-xr-x7zip/FileManager/Resource/ProgressDialog2/resource.rc127
-rwxr-xr-x7zip/FileManager/Resource/PropertyName/resource.h41
-rwxr-xr-x7zip/FileManager/Resource/PropertyName/resource.rc103
-rwxr-xr-x7zip/FileManager/Resource/SettingsPage/SettingsPage.cpp68
-rwxr-xr-x7zip/FileManager/Resource/SettingsPage/SettingsPage.h20
-rwxr-xr-x7zip/FileManager/Resource/SettingsPage/resource.h19
-rwxr-xr-x7zip/FileManager/Resource/SettingsPage/resource.rc101
-rwxr-xr-x7zip/FileManager/Resource/SystemPage/SystemPage.cpp441
-rwxr-xr-x7zip/FileManager/Resource/SystemPage/SystemPage.h41
-rwxr-xr-x7zip/FileManager/Resource/SystemPage/resource.h21
-rwxr-xr-x7zip/FileManager/Resource/SystemPage/resource.rc115
-rwxr-xr-x7zip/FileManager/RootFolder.cpp191
-rwxr-xr-x7zip/FileManager/RootFolder.h51
-rwxr-xr-x7zip/FileManager/StdAfx.cpp8
-rwxr-xr-x7zip/FileManager/StdAfx.h41
-rwxr-xr-x7zip/FileManager/StringUtils.cpp77
-rwxr-xr-x7zip/FileManager/StringUtils.h17
-rwxr-xr-x7zip/FileManager/SysIconUtils.cpp108
-rwxr-xr-x7zip/FileManager/SysIconUtils.h57
-rwxr-xr-x7zip/FileManager/Test.bmpbin0 -> 982 bytes
-rwxr-xr-x7zip/FileManager/Test2.bmpbin0 -> 406 bytes
-rwxr-xr-x7zip/FileManager/TextPairs.cpp220
-rwxr-xr-x7zip/FileManager/TextPairs.h36
-rwxr-xr-x7zip/FileManager/UpdateCallback100.cpp69
-rwxr-xr-x7zip/FileManager/UpdateCallback100.h64
-rwxr-xr-x7zip/FileManager/ViewSettings.cpp344
-rwxr-xr-x7zip/FileManager/ViewSettings.h95
-rwxr-xr-x7zip/FileManager/resource.h137
-rwxr-xr-x7zip/FileManager/resource.rc414
-rwxr-xr-x7zip/ICoder.h127
-rwxr-xr-x7zip/IMyUnknown.h71
-rwxr-xr-x7zip/IPassword.h47
-rwxr-xr-x7zip/IProgress.h32
-rwxr-xr-x7zip/IStream.h64
-rwxr-xr-x7zip/PropID.h51
-rwxr-xr-x7zip/UI/Agent/Agent.cpp407
-rwxr-xr-x7zip/UI/Agent/Agent.h292
-rwxr-xr-x7zip/UI/Agent/AgentOut.cpp469
-rwxr-xr-x7zip/UI/Agent/AgentProxy.cpp198
-rwxr-xr-x7zip/UI/Agent/AgentProxy.h58
-rwxr-xr-x7zip/UI/Agent/ArchiveExtractCallback.cpp358
-rwxr-xr-x7zip/UI/Agent/ArchiveExtractCallback.h107
-rwxr-xr-x7zip/UI/Agent/ArchiveFolder.cpp67
-rwxr-xr-x7zip/UI/Agent/ArchiveFolderOpen.cpp98
-rwxr-xr-x7zip/UI/Agent/ArchiveFolderOut.cpp219
-rwxr-xr-x7zip/UI/Agent/ArchiveUpdateCallback.cpp229
-rwxr-xr-x7zip/UI/Agent/ArchiveUpdateCallback.h71
-rwxr-xr-x7zip/UI/Agent/IFolderArchive.h141
-rwxr-xr-x7zip/UI/Client7z/Client7z.cpp72
-rwxr-xr-x7zip/UI/Client7z/Client7z.dsp190
-rwxr-xr-x7zip/UI/Client7z/Client7z.dsw29
-rwxr-xr-x7zip/UI/Client7z/StdAfx.cpp8
-rwxr-xr-x7zip/UI/Client7z/StdAfx.h12
-rwxr-xr-x7zip/UI/Common/ArchiveName.cpp46
-rwxr-xr-x7zip/UI/Common/ArchiveName.h12
-rwxr-xr-x7zip/UI/Common/ArchiverInfo.cpp308
-rwxr-xr-x7zip/UI/Common/ArchiverInfo.h58
-rwxr-xr-x7zip/UI/Common/CompressCall.cpp229
-rwxr-xr-x7zip/UI/Common/CompressCall.h22
-rwxr-xr-x7zip/UI/Common/DefaultName.cpp33
-rwxr-xr-x7zip/UI/Common/DefaultName.h13
-rwxr-xr-x7zip/UI/Common/DirItem.h37
-rwxr-xr-x7zip/UI/Common/EnumDirItems.cpp71
-rwxr-xr-x7zip/UI/Common/EnumDirItems.h33
-rwxr-xr-x7zip/UI/Common/ExtractingFilePath.cpp54
-rwxr-xr-x7zip/UI/Common/ExtractingFilePath.h13
-rwxr-xr-x7zip/UI/Common/HandlerLoader.h42
-rwxr-xr-x7zip/UI/Common/OpenArchive.cpp171
-rwxr-xr-x7zip/UI/Common/OpenArchive.h24
-rwxr-xr-x7zip/UI/Common/PropIDUtils.cpp79
-rwxr-xr-x7zip/UI/Common/PropIDUtils.h13
-rwxr-xr-x7zip/UI/Common/SortUtils.cpp30
-rwxr-xr-x7zip/UI/Common/SortUtils.h12
-rwxr-xr-x7zip/UI/Common/StdAfx.h8
-rwxr-xr-x7zip/UI/Common/UpdateAction.cpp64
-rwxr-xr-x7zip/UI/Common/UpdateAction.h48
-rwxr-xr-x7zip/UI/Common/UpdatePair.cpp157
-rwxr-xr-x7zip/UI/Common/UpdatePair.h26
-rwxr-xr-x7zip/UI/Common/UpdateProduce.cpp65
-rwxr-xr-x7zip/UI/Common/UpdateProduce.h35
-rwxr-xr-x7zip/UI/Common/WorkDir.cpp73
-rwxr-xr-x7zip/UI/Common/WorkDir.h14
-rwxr-xr-x7zip/UI/Common/ZipRegistry.cpp404
-rwxr-xr-x7zip/UI/Common/ZipRegistry.h119
-rwxr-xr-x7zip/UI/Console/ArError.h64
-rwxr-xr-x7zip/UI/Console/CompressionMode.h28
-rwxr-xr-x7zip/UI/Console/Console.dsp581
-rwxr-xr-x7zip/UI/Console/Console.dsw29
-rwxr-xr-x7zip/UI/Console/ConsoleClose.cpp57
-rwxr-xr-x7zip/UI/Console/ConsoleClose.h27
-rwxr-xr-x7zip/UI/Console/Extract.cpp94
-rwxr-xr-x7zip/UI/Console/Extract.h65
-rwxr-xr-x7zip/UI/Console/ExtractCallback.cpp405
-rwxr-xr-x7zip/UI/Console/ExtractCallback.h77
-rwxr-xr-x7zip/UI/Console/List.cpp381
-rwxr-xr-x7zip/UI/Console/List.h31
-rwxr-xr-x7zip/UI/Console/Main.cpp934
-rwxr-xr-x7zip/UI/Console/MainAr.cpp114
-rwxr-xr-x7zip/UI/Console/OpenCallback.cpp92
-rwxr-xr-x7zip/UI/Console/OpenCallback.h52
-rwxr-xr-x7zip/UI/Console/PercentPrinter.cpp86
-rwxr-xr-x7zip/UI/Console/PercentPrinter.h38
-rwxr-xr-x7zip/UI/Console/StdAfx.cpp3
-rwxr-xr-x7zip/UI/Console/StdAfx.h16
-rwxr-xr-x7zip/UI/Console/TempFiles.cpp39
-rwxr-xr-x7zip/UI/Console/TempFiles.h20
-rwxr-xr-x7zip/UI/Console/Update.cpp503
-rwxr-xr-x7zip/UI/Console/Update.h41
-rwxr-xr-x7zip/UI/Console/UpdateCallback.cpp259
-rwxr-xr-x7zip/UI/Console/UpdateCallback.h78
-rwxr-xr-x7zip/UI/Console/UserInputUtils.cpp51
-rwxr-xr-x7zip/UI/Console/UserInputUtils.h23
-rwxr-xr-x7zip/UI/Console/afxres.h1
-rwxr-xr-x7zip/UI/Console/resource.h15
-rwxr-xr-x7zip/UI/Console/resource.rc121
-rwxr-xr-x7zip/UI/Explorer/7-zip.dll.manifest1
-rwxr-xr-x7zip/UI/Explorer/ContextMenu.cpp686
-rwxr-xr-x7zip/UI/Explorer/ContextMenu.h92
-rwxr-xr-x7zip/UI/Explorer/ContextMenuFlags.h28
-rwxr-xr-x7zip/UI/Explorer/DllExports.cpp152
-rwxr-xr-x7zip/UI/Explorer/Explorer.def12
-rwxr-xr-x7zip/UI/Explorer/Explorer.dsp807
-rwxr-xr-x7zip/UI/Explorer/Explorer.dsw29
-rwxr-xr-x7zip/UI/Explorer/FoldersPage/FoldersPage.cpp161
-rwxr-xr-x7zip/UI/Explorer/FoldersPage/FoldersPage.h33
-rwxr-xr-x7zip/UI/Explorer/FoldersPage/resource.h27
-rwxr-xr-x7zip/UI/Explorer/FoldersPage/resource.rc109
-rwxr-xr-x7zip/UI/Explorer/MyMessages.cpp45
-rwxr-xr-x7zip/UI/Explorer/MyMessages.h26
-rwxr-xr-x7zip/UI/Explorer/OptionsDialog.cpp107
-rwxr-xr-x7zip/UI/Explorer/OptionsDialog.h25
-rwxr-xr-x7zip/UI/Explorer/RegistryContextMenu..cpp84
-rwxr-xr-x7zip/UI/Explorer/RegistryContextMenu.h18
-rwxr-xr-x7zip/UI/Explorer/StdAfx.cpp3
-rwxr-xr-x7zip/UI/Explorer/StdAfx.h40
-rwxr-xr-x7zip/UI/Explorer/SystemPage/SystemPage.cpp186
-rwxr-xr-x7zip/UI/Explorer/SystemPage/SystemPage.h27
-rwxr-xr-x7zip/UI/Explorer/SystemPage/resource.h20
-rwxr-xr-x7zip/UI/Explorer/SystemPage/resource.rc105
-rwxr-xr-x7zip/UI/Explorer/resource.h47
-rwxr-xr-x7zip/UI/Explorer/resource.rc181
-rwxr-xr-x7zip/UI/Far/CLSIDConst.cpp8
-rwxr-xr-x7zip/UI/Far/CompressEngine.cpp347
-rwxr-xr-x7zip/UI/Far/CompressEngine.h23
-rwxr-xr-x7zip/UI/Far/ExtractEngine.cpp165
-rwxr-xr-x7zip/UI/Far/ExtractEngine.h69
-rwxr-xr-x7zip/UI/Far/Far.def20
-rwxr-xr-x7zip/UI/Far/Far.dsp529
-rwxr-xr-x7zip/UI/Far/Far.dsw29
-rwxr-xr-x7zip/UI/Far/Far.rc121
-rwxr-xr-x7zip/UI/Far/Main.cpp615
-rwxr-xr-x7zip/UI/Far/Messages.h152
-rwxr-xr-x7zip/UI/Far/OverwriteDialog.cpp106
-rwxr-xr-x7zip/UI/Far/OverwriteDialog.h35
-rwxr-xr-x7zip/UI/Far/Plugin.cpp690
-rwxr-xr-x7zip/UI/Far/Plugin.h108
-rwxr-xr-x7zip/UI/Far/PluginCommon.cpp54
-rwxr-xr-x7zip/UI/Far/PluginDelete.cpp169
-rwxr-xr-x7zip/UI/Far/PluginRead.cpp304
-rwxr-xr-x7zip/UI/Far/PluginWrite.cpp712
-rwxr-xr-x7zip/UI/Far/StdAfx.cpp3
-rwxr-xr-x7zip/UI/Far/StdAfx.h28
-rwxr-xr-x7zip/UI/Far/UpdateCallback100.cpp44
-rwxr-xr-x7zip/UI/Far/UpdateCallback100.h46
-rwxr-xr-x7zip/UI/Far/resource.h15
-rwxr-xr-x7zip/UI/GUI/7zG.exe.manifest1
-rwxr-xr-x7zip/UI/GUI/Compress.cpp636
-rwxr-xr-x7zip/UI/GUI/Compress.h17
-rwxr-xr-x7zip/UI/GUI/CompressDialog.cpp1233
-rwxr-xr-x7zip/UI/GUI/CompressDialog.h161
-rwxr-xr-x7zip/UI/GUI/Extract.cpp225
-rwxr-xr-x7zip/UI/GUI/Extract.h12
-rwxr-xr-x7zip/UI/GUI/ExtractDialog.cpp371
-rwxr-xr-x7zip/UI/GUI/ExtractDialog.h99
-rwxr-xr-x7zip/UI/GUI/FM.icobin0 -> 4846 bytes
-rwxr-xr-x7zip/UI/GUI/GUI.cpp361
-rwxr-xr-x7zip/UI/GUI/GUI.dsp868
-rwxr-xr-x7zip/UI/GUI/GUI.dsw29
-rwxr-xr-x7zip/UI/GUI/StdAfx.cpp8
-rwxr-xr-x7zip/UI/GUI/StdAfx.h38
-rwxr-xr-x7zip/UI/GUI/Test.cpp122
-rwxr-xr-x7zip/UI/GUI/Test.h13
-rwxr-xr-x7zip/UI/GUI/resource.h53
-rwxr-xr-x7zip/UI/GUI/resource.rc203
-rwxr-xr-x7zip/UI/Resource/CompressDialog/resource.h47
-rwxr-xr-x7zip/UI/Resource/CompressDialog/resource.rc161
-rwxr-xr-x7zip/UI/Resource/Extract/resource.h26
-rwxr-xr-x7zip/UI/Resource/Extract/resource.rc113
-rwxr-xr-x7zip/UI/Resource/ExtractDialog/resource.h35
-rwxr-xr-x7zip/UI/Resource/ExtractDialog/resource.rc116
-rwxr-xr-xCommon/AlignedBuffer.cpp22
-rwxr-xr-xCommon/AlignedBuffer.h16
-rwxr-xr-xCommon/Buffer.h71
-rwxr-xr-xCommon/CRC.cpp110
-rwxr-xr-xCommon/CRC.h31
-rwxr-xr-xCommon/ComTry.h14
-rwxr-xr-xCommon/CommandLineParser.cpp248
-rwxr-xr-xCommon/CommandLineParser.h84
-rwxr-xr-xCommon/Defs.h22
-rwxr-xr-xCommon/DynamicBuffer.h49
-rwxr-xr-xCommon/Exception.h24
-rwxr-xr-xCommon/IntToString.cpp57
-rwxr-xr-xCommon/IntToString.h18
-rwxr-xr-xCommon/Lang.cpp144
-rwxr-xr-xCommon/Lang.h29
-rwxr-xr-xCommon/ListFileUtils.cpp55
-rwxr-xr-xCommon/ListFileUtils.h14
-rwxr-xr-xCommon/MyCom.h187
-rwxr-xr-xCommon/NewHandler.cpp105
-rwxr-xr-xCommon/NewHandler.h12
-rwxr-xr-xCommon/Random.cpp16
-rwxr-xr-xCommon/Random.h18
-rwxr-xr-xCommon/StdAfx.h8
-rwxr-xr-xCommon/StdInStream.cpp78
-rwxr-xr-xCommon/StdInStream.h33
-rwxr-xr-xCommon/StdOutStream.cpp80
-rwxr-xr-xCommon/StdOutStream.h36
-rwxr-xr-xCommon/String.cpp84
-rwxr-xr-xCommon/String.h672
-rwxr-xr-xCommon/StringConvert.cpp71
-rwxr-xr-xCommon/StringConvert.h72
-rwxr-xr-xCommon/StringToInt.cpp50
-rwxr-xr-xCommon/StringToInt.h15
-rwxr-xr-xCommon/TextConfig.cpp137
-rwxr-xr-xCommon/TextConfig.h24
-rwxr-xr-xCommon/Types.h19
-rwxr-xr-xCommon/UTFConvert.cpp70
-rwxr-xr-xCommon/UTFConvert.h13
-rwxr-xr-xCommon/Vector.cpp72
-rwxr-xr-xCommon/Vector.h177
-rwxr-xr-xCommon/Wildcard.cpp351
-rwxr-xr-xCommon/Wildcard.h60
-rwxr-xr-xCommon/WindowsTypes.h75
-rwxr-xr-xDOC/7zFormat.txt471
-rwxr-xr-xDOC/Methods.txt108
-rwxr-xr-xDOC/copying.txt504
-rwxr-xr-xDOC/history.txt213
-rwxr-xr-xDOC/readme.txt161
-rwxr-xr-xFar/FarPlugin.h564
-rwxr-xr-xFar/FarUtils.cpp421
-rwxr-xr-xFar/FarUtils.h220
-rwxr-xr-xFar/ProgressBox.cpp101
-rwxr-xr-xFar/ProgressBox.h36
-rwxr-xr-xWindows/COM.cpp37
-rwxr-xr-xWindows/COM.h59
-rwxr-xr-xWindows/Console.cpp10
-rwxr-xr-xWindows/Console.h54
-rwxr-xr-xWindows/Control/ComboBox.cpp23
-rwxr-xr-xWindows/Control/ComboBox.h55
-rwxr-xr-xWindows/Control/Dialog.cpp106
-rwxr-xr-xWindows/Control/Dialog.h137
-rwxr-xr-xWindows/Control/Edit.h23
-rwxr-xr-xWindows/Control/ImageList.cpp11
-rwxr-xr-xWindows/Control/ImageList.h88
-rwxr-xr-xWindows/Control/ListView.cpp58
-rwxr-xr-xWindows/Control/ListView.h121
-rwxr-xr-xWindows/Control/ProgressBar.h43
-rwxr-xr-xWindows/Control/PropertyPage.cpp59
-rwxr-xr-xWindows/Control/PropertyPage.h41
-rwxr-xr-xWindows/Control/ReBar.h37
-rwxr-xr-xWindows/Control/Static.h29
-rwxr-xr-xWindows/Control/StatusBar.h33
-rwxr-xr-xWindows/Control/ToolBar.h32
-rwxr-xr-xWindows/Control/Trackbar.h30
-rwxr-xr-xWindows/Control/Window2.cpp125
-rwxr-xr-xWindows/Control/Window2.h54
-rwxr-xr-xWindows/DLL.cpp113
-rwxr-xr-xWindows/DLL.h56
-rwxr-xr-xWindows/Defs.h23
-rwxr-xr-xWindows/Error.cpp59
-rwxr-xr-xWindows/Error.h35
-rwxr-xr-xWindows/FileDir.cpp713
-rwxr-xr-xWindows/FileDir.h189
-rwxr-xr-xWindows/FileFind.cpp312
-rwxr-xr-xWindows/FileFind.h174
-rwxr-xr-xWindows/FileIO.cpp219
-rwxr-xr-xWindows/FileIO.h98
-rwxr-xr-xWindows/FileMapping.cpp14
-rwxr-xr-xWindows/FileMapping.h52
-rwxr-xr-xWindows/FileName.cpp111
-rwxr-xr-xWindows/FileName.h45
-rwxr-xr-xWindows/FileSystem.cpp77
-rwxr-xr-xWindows/FileSystem.h28
-rwxr-xr-xWindows/Handle.h39
-rwxr-xr-xWindows/ItemIDListUtils.cpp166
-rwxr-xr-xWindows/ItemIDListUtils.h98
-rwxr-xr-xWindows/Memory.cpp59
-rwxr-xr-xWindows/Memory.h46
-rwxr-xr-xWindows/Menu.h108
-rwxr-xr-xWindows/NationalTime.cpp37
-rwxr-xr-xWindows/NationalTime.h22
-rwxr-xr-xWindows/Net.cpp158
-rwxr-xr-xWindows/Net.h54
-rwxr-xr-xWindows/ProcessMessages.cpp22
-rwxr-xr-xWindows/ProcessMessages.h16
-rwxr-xr-xWindows/PropVariant.cpp479
-rwxr-xr-xWindows/PropVariant.h60
-rwxr-xr-xWindows/PropVariantConversions.cpp143
-rwxr-xr-xWindows/PropVariantConversions.h17
-rwxr-xr-xWindows/Registry.cpp266
-rwxr-xr-xWindows/Registry.h65
-rwxr-xr-xWindows/ResourceString.cpp50
-rwxr-xr-xWindows/ResourceString.h22
-rwxr-xr-xWindows/Shell.cpp180
-rwxr-xr-xWindows/Shell.h82
-rwxr-xr-xWindows/StdAfx.h8
-rwxr-xr-xWindows/Synchronization.cpp17
-rwxr-xr-xWindows/Synchronization.h116
-rwxr-xr-xWindows/System.cpp15
-rwxr-xr-xWindows/System.h15
-rwxr-xr-xWindows/Thread.h45
-rwxr-xr-xWindows/Time.h58
-rwxr-xr-xWindows/Window.cpp80
-rwxr-xr-xWindows/Window.h176
982 files changed, 118799 insertions, 0 deletions
diff --git a/7zip/Archive/7z/7z.def b/7zip/Archive/7z/7z.def
new file mode 100755
index 00000000..d940a778
--- /dev/null
+++ b/7zip/Archive/7z/7z.def
@@ -0,0 +1,4 @@
+EXPORTS
+ CreateObject PRIVATE
+ GetHandlerProperty PRIVATE
+
diff --git a/7zip/Archive/7z/7z.dsp b/7zip/Archive/7z/7z.dsp
new file mode 100755
index 00000000..1199a0a1
--- /dev/null
+++ b/7zip/Archive/7z/7z.dsp
@@ -0,0 +1,533 @@
+# 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 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_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\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 /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_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\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=.\7z.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=..\..\ICoderProperties.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IMyUnknown.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IPassword.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IProgress.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\PropID.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\Buffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\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\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.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\CrossThreadProgress.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CrossThreadProgress.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
+# 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\MultiStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MultiStream.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
+# 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/7zip/Archive/7z/7z.dsw b/7zip/Archive/7z/7z.dsw
new file mode 100755
index 00000000..702a86c7
--- /dev/null
+++ b/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/7zip/Archive/7z/7z.ico b/7zip/Archive/7z/7z.ico
new file mode 100755
index 00000000..319753a1
--- /dev/null
+++ b/7zip/Archive/7z/7z.ico
Binary files differ
diff --git a/7zip/Archive/7z/7zCompressionMode.cpp b/7zip/Archive/7z/7zCompressionMode.cpp
new file mode 100755
index 00000000..6774fc48
--- /dev/null
+++ b/7zip/Archive/7z/7zCompressionMode.cpp
@@ -0,0 +1,3 @@
+// CompressionMethod.cpp
+
+#include "StdAfx.h"
diff --git a/7zip/Archive/7z/7zCompressionMode.h b/7zip/Archive/7z/7zCompressionMode.h
new file mode 100755
index 00000000..400344b8
--- /dev/null
+++ b/7zip/Archive/7z/7zCompressionMode.h
@@ -0,0 +1,60 @@
+// 7zCompressionMode.h
+
+#pragma once
+
+#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;
+ bool MultiThread;
+ bool PasswordIsDefined;
+ UString Password;
+
+ bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
+ CCompressionMethodMode(): PasswordIsDefined(false), MultiThread(false) {}
+};
+
+}}
+
+#endif
diff --git a/7zip/Archive/7z/7zDecode.cpp b/7zip/Archive/7z/7zDecode.cpp
new file mode 100755
index 00000000..13bcb444
--- /dev/null
+++ b/7zip/Archive/7z/7zDecode.cpp
@@ -0,0 +1,377 @@
+// Decode.cpp
+
+#include "StdAfx.h"
+
+#include "7zDecode.h"
+
+#include "../../Common/MultiStream.h"
+#include "../../Common/StreamObjects.h"
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/LimitedStreams.h"
+
+#include "7zMethods.h"
+
+#include "../../IPassword.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
+#include "../../Compress/Deflate/DeflateDecoder.h"
+static NArchive::N7z::CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
+#endif
+
+#ifdef COMPRESS_BZIP2
+#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.Coders.Clear();
+ bindInfo.CoderMethodIDs.Clear();
+ bindInfo.OutStreams.Clear();
+ bindInfo.InStreams.Clear();
+ bindInfo.BindPairs.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].Index);
+}
+
+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()
+{
+ _bindInfoExPrevIsDefinded = 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
+ )
+{
+ 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->Init(lockedStreamImp, packSizes[j]);
+ inStreams.Add(inStream);
+ }
+
+ int numCoders = folderInfo.Coders.Size();
+
+ CBindInfoEx bindInfo;
+ ConvertFolderItemInfoToBindInfo(folderInfo, bindInfo);
+ bool createNewCoders;
+ if (!_bindInfoExPrevIsDefinded)
+ createNewCoders = true;
+ else
+ createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev);
+ if (createNewCoders)
+ {
+ int i;
+ _decoders.Clear();
+ // _decoders2.Clear();
+
+ _mixerCoder.Release();
+
+ _mixerCoderSpec = new NCoderMixer2::CCoderMixer2;
+ _mixerCoder = _mixerCoderSpec;
+
+ _mixerCoderSpec->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;
+
+ #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)
+ decoder = new CBCJ_x86_Decoder;
+ #endif
+
+ #ifdef COMPRESS_DEFLATE
+ if (altCoderInfo.MethodID == k_Deflate)
+ decoder = new NCompress::NDeflate::NDecoder::CCOMCoder;
+ #endif
+
+ #ifdef COMPRESS_BZIP2
+ 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)
+ decoder = new NCrypto::NSevenZ::CDecoder;
+ #endif
+
+ #ifndef EXCLUDE_COM
+ if (decoder == 0)
+ {
+ RINOK(_libraries.CreateCoder(methodInfo.FilePath,
+ methodInfo.Decoder, &decoder));
+ }
+ #endif
+
+ if (decoder == 0)
+ return E_NOTIMPL;
+
+ _decoders.Add((IUnknown *)decoder);
+
+ _mixerCoderSpec->AddCoder(decoder);
+ }
+ 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);
+ _mixerCoderSpec->AddCoder2(decoder);
+ }
+ }
+ _bindInfoExPrev = bindInfo;
+ _bindInfoExPrevIsDefinded = true;
+ }
+ int i;
+ _mixerCoderSpec->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<ICompressSetDecoderProperties> compressSetDecoderProperties;
+ HRESULT result = _decoders[coderIndex].QueryInterface(
+ IID_ICompressSetDecoderProperties, &compressSetDecoderProperties);
+
+ if (result == S_OK)
+ {
+ const CByteBuffer &properties = altCoderInfo.Properties;
+ UINT32 size = properties.GetCapacity();
+ if (size > 0)
+ {
+ CSequentialInStreamImp *inStreamSpec = new CSequentialInStreamImp;
+ CMyComPtr<ISequentialInStream> inStream(inStreamSpec);
+ inStreamSpec->Init((const BYTE *)properties, size);
+ RINOK(compressSetDecoderProperties->SetDecoderProperties(inStream));
+ }
+ }
+ else if (result != E_NOINTERFACE)
+ return result;
+
+ #ifndef _NO_CRYPTO
+ CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
+ result = _decoders[coderIndex].QueryInterface(
+ IID_ICryptoSetPassword, &cryptoSetPassword);
+
+ if (result == S_OK)
+ {
+ if (getTextPassword == 0)
+ return E_FAIL;
+ CMyComBSTR password;
+ RINOK(getTextPassword->CryptoGetTextPassword(&password));
+ UString unicodePassword(password);
+ RINOK(cryptoSetPassword->CryptoSetPassword(
+ (const BYTE *)(const wchar_t *)unicodePassword,
+ unicodePassword.Length() * sizeof(wchar_t)));
+ }
+ else if (result != E_NOINTERFACE)
+ return result;
+ #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]);
+ }
+ }
+
+ _mixerCoderSpec->SetCoderInfo(i,
+ &packSizesPointers.Front(),
+ &unPackSizesPointers.Front());
+ }
+ UINT32 mainCoder, temp;
+ bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp);
+ _mixerCoderSpec->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 _mixerCoderSpec->Code(&inStreamPointers.Front(), NULL,
+ inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress);
+}
+
+}}
diff --git a/7zip/Archive/7z/7zDecode.h b/7zip/Archive/7z/7zDecode.h
new file mode 100755
index 00000000..f46eeb38
--- /dev/null
+++ b/7zip/Archive/7z/7zDecode.h
@@ -0,0 +1,54 @@
+// 7zDecode.h
+
+#pragma once
+
+#ifndef __7Z_DECODE_H
+#define __7Z_DECODE_H
+
+#include "../../IStream.h"
+#include "../../IPassword.h"
+
+#include "../Common/CoderMixer2.h"
+#ifndef EXCLUDE_COM
+#include "../Common/CoderLoader.h"
+#endif
+
+#include "7zItem.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CBindInfoEx: public NCoderMixer2::CBindInfo
+{
+ CRecordVector<CMethodID> CoderMethodIDs;
+};
+
+class CDecoder
+{
+ #ifndef EXCLUDE_COM
+ CCoderLibraries _libraries;
+ #endif
+
+ bool _bindInfoExPrevIsDefinded;
+ CBindInfoEx _bindInfoExPrev;
+ NCoderMixer2::CCoderMixer2 *_mixerCoderSpec;
+ CMyComPtr<ICompressCoder2> _mixerCoder;
+ CObjectVector<CMyComPtr<IUnknown> > _decoders;
+ // CObjectVector<CMyComPtr<ICompressCoder2> > _decoders2;
+public:
+ CDecoder();
+ HRESULT Decode(IInStream *inStream,
+ UINT64 startPos,
+ const UINT64 *packSizes,
+ const CFolder &folder,
+ ISequentialOutStream *outStream,
+ ICompressProgressInfo *compressProgress
+ #ifndef _NO_CRYPTO
+ , ICryptoGetTextPassword *getTextPasswordSpec
+ #endif
+ );
+};
+
+}}
+
+#endif
diff --git a/7zip/Archive/7z/7zEncode.cpp b/7zip/Archive/7z/7zEncode.cpp
new file mode 100755
index 00000000..ebec98ac
--- /dev/null
+++ b/7zip/Archive/7z/7zEncode.cpp
@@ -0,0 +1,570 @@
+// 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"
+
+#ifdef COMPRESS_COPY
+static NArchive::N7z::CMethodID k_Copy = { { 0x0 }, 1 };
+#include "../../Compress/Copy/CopyCoder.h"
+#endif
+
+#ifdef COMPRESS_LZMA
+#include "../../Compress/LZMA/LZMAEncoder.h"
+static NArchive::N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
+#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
+#include "../../Compress/Deflate/DeflateEncoder.h"
+static NArchive::N7z::CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
+#endif
+
+#ifdef COMPRESS_BZIP2
+#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++)
+ {
+ CPackStreamInfo packStreamInfo;
+ packStreamInfo.Index = bindInfo.InStreams[i];
+ folder.PackStreams.Add(packStreamInfo);
+ }
+}
+
+HRESULT CEncoder::CreateMixerCoder()
+{
+ _mixerCoderSpec = new NCoderMixer2::CCoderMixer2;
+ _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<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)
+ encoder = new CBCJ_x86_Encoder;
+ #endif
+
+ #ifdef COMPRESS_COPY
+ if (methodFull.MethodID == k_Copy)
+ encoder = new NCompress::CCopyCoder;
+ #endif
+
+ #ifdef COMPRESS_BZIP2
+ if (methodFull.MethodID == k_BZip2)
+ encoder = new NCompress::NBZip2::CEncoder;
+ #endif
+
+ #ifdef COMPRESS_DEFLATE
+ if (methodFull.MethodID == k_Deflate)
+ encoder = new NCompress::NDeflate::NEncoder::CCOMCoder;
+ #endif
+
+ #ifdef CRYPTO_7ZAES
+ if (methodFull.MethodID == k_AES)
+ encoder = new NCrypto::NSevenZ::CEncoder;
+ #endif
+
+ #ifndef EXCLUDE_COM
+ if (encoder == 0)
+ {
+ RINOK(_libraries.CreateCoder(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
+ }
+
+ if (methodFull.CoderProperties.Size() > 0)
+ {
+ std::vector<NWindows::NCOM::CPropVariant> properties;
+ std::vector<PROPID> propIDs;
+ INT32 numProperties = methodFull.CoderProperties.Size();
+ for (int i = 0; i < numProperties; i++)
+ {
+ const CProperty &property = methodFull.CoderProperties[i];
+ propIDs.push_back(property.PropID);
+ properties.push_back(property.Value);
+ }
+ CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
+ if (methodFull.IsSimpleCoder())
+ {
+ RINOK(encoder.QueryInterface(IID_ICompressSetCoderProperties,
+ &setCoderProperties));
+ }
+ else
+ {
+ RINOK(encoder2.QueryInterface(IID_ICompressSetCoderProperties,
+ &setCoderProperties));
+ }
+
+ RINOK(setCoderProperties->SetCoderProperties(&propIDs.front(),
+ &properties.front(), numProperties));
+ }
+
+ CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
+
+ if (methodFull.IsSimpleCoder())
+ {
+ encoder.QueryInterface(IID_ICompressWriteCoderProperties,
+ &writeCoderProperties);
+ }
+ else
+ {
+ encoder2.QueryInterface(IID_ICompressWriteCoderProperties,
+ &writeCoderProperties);
+ }
+
+ if (writeCoderProperties != NULL)
+ {
+ CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
+ CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
+ outStreamSpec->Init();
+ writeCoderProperties->WriteCoderProperties(outStream);
+
+ UINT32 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;
+ if (methodFull.IsSimpleCoder())
+ {
+ encoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
+ }
+ else
+ {
+ encoder2.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
+ }
+
+ if (cryptoSetPassword)
+ {
+ RINOK(cryptoSetPassword->CryptoSetPassword(
+ (const BYTE *)(const wchar_t *)_options.Password,
+ _options.Password.Length() * sizeof(wchar_t)));
+ }
+
+ // public ICompressWriteCoderProperties,
+ if (methodFull.IsSimpleCoder())
+ {
+ _mixerCoderSpec->AddCoder(encoder);
+ }
+ else
+ {
+ _mixerCoderSpec->AddCoder2(encoder2);
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CEncoder::Encode(ISequentialInStream *inStream,
+ const UINT64 *inStreamSize,
+ CFolder &folderItem,
+ ISequentialOutStream *outStream,
+ CRecordVector<UINT64> &packSizes,
+ ICompressProgressInfo *compressProgress)
+{
+ if (_mixerCoderSpec == NULL)
+ {
+ RINOK(CreateMixerCoder());
+ }
+ _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 (int 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->Init(outStream);
+
+ 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 < _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 (int 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 < numOutStreams; i++)
+ if (_bindInfo.FindBinderForOutStream(i) == -1)
+ _bindInfo.OutStreams.Add(i);
+ }
+
+ for (i = 0; i < 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];
+ while (true)
+ {
+ UINT32 coderIndex, coderStreamIndex;
+ _bindInfo.FindInStream(inIndex, coderIndex, coderStreamIndex);
+ UINT32 outIndex = _bindInfo.GetCoderStartOutStream(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/7zip/Archive/7z/7zEncode.h b/7zip/Archive/7z/7zEncode.h
new file mode 100755
index 00000000..ee523a14
--- /dev/null
+++ b/7zip/Archive/7z/7zEncode.h
@@ -0,0 +1,56 @@
+// 7zEncode.h
+
+#pragma once
+
+#ifndef __7Z_ENCODE_H
+#define __7Z_ENCODE_H
+
+// #include "../../Common/StreamObjects.h"
+
+#include "7zCompressionMode.h"
+
+#include "../Common/CoderMixer2.h"
+#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::CCoderMixer2 *_mixerCoderSpec;
+ CMyComPtr<ICompressCoder2> _mixerCoder;
+
+ CObjectVector<CCoderInfo> _codersInfo;
+
+ CCompressionMethodMode _options;
+ NCoderMixer2::CBindInfo _bindInfo;
+ NCoderMixer2::CBindInfo _decompressBindInfo;
+ NCoderMixer2::CBindReverseConverter *_bindReverseConverter;
+ CRecordVector<CMethodID> _decompressionMethods;
+
+ HRESULT CreateMixerCoder();
+
+public:
+ CEncoder(const CCompressionMethodMode &options);
+ ~CEncoder();
+ HRESULT Encode(ISequentialInStream *inStream,
+ const UINT64 *inStreamSize,
+ CFolder &folderItem,
+ ISequentialOutStream *outStream,
+ CRecordVector<UINT64> &packSizes,
+ ICompressProgressInfo *compressProgress);
+};
+
+}}
+
+#endif
diff --git a/7zip/Archive/7z/7zExtract.cpp b/7zip/Archive/7z/7zExtract.cpp
new file mode 100755
index 00000000..14347d29
--- /dev/null
+++ b/7zip/Archive/7z/7zExtract.cpp
@@ -0,0 +1,204 @@
+// 7zExtract.cpp
+
+#include "StdAfx.h"
+
+#include "7zHandler.h"
+#include "7zFolderOutStream.h"
+#include "7zMethods.h"
+#include "7zDecode.h"
+
+#include "../../../Common/ComTry.h"
+#include "../../Common/MultiStream.h"
+#include "../../Common/StreamObjects.h"
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/LimitedStreams.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CExtractFolderInfo
+{
+ int FileIndex;
+ int FolderIndex;
+ CBoolVector ExtractStatuses;
+ UINT64 UnPackSize;
+ CExtractFolderInfo(int fileIndex, int folderIndex):
+ FileIndex(fileIndex),
+ FolderIndex(folderIndex),
+ UnPackSize(0)
+ {
+ if (fileIndex >= 0)
+ {
+ 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;
+ UINT64 censoredTotalUnPacked = 0, censoredTotalPacked = 0;
+
+ bool allFilesMode = (numItems == UINT32(-1));
+ if (allFilesMode)
+ numItems = _database.Files.Size();
+
+ if(numItems == 0)
+ return S_OK;
+
+ CObjectVector<CExtractFolderInfo> extractFolderInfoVector;
+ for(UINT32 indexIndex = 0; indexIndex < numItems; indexIndex++)
+ {
+ int fileIndex = allFilesMode ? indexIndex : indices[indexIndex];
+ int folderIndex = _database.FileIndexToFolderIndexMap[fileIndex];
+ if (folderIndex < 0)
+ {
+ extractFolderInfoVector.Add(CExtractFolderInfo(fileIndex, -1));
+ continue;
+ }
+ if (extractFolderInfoVector.IsEmpty() ||
+ folderIndex != extractFolderInfoVector.Back().FolderIndex)
+ {
+ extractFolderInfoVector.Add(CExtractFolderInfo(-1, folderIndex));
+ const CFolder &folderInfo = _database.Folders[folderIndex];
+ // Count full_folder_size
+ UINT64 unPackSize = folderInfo.GetUnPackSize();
+ importantTotalUnPacked += unPackSize;
+ extractFolderInfoVector.Back().UnPackSize = unPackSize;
+ }
+
+ CExtractFolderInfo &extractFolderInfo = extractFolderInfoVector.Back();
+
+ // const CFolderInfo &folderInfo = m_dam_Folders[folderIndex];
+ UINT32 startIndex = (UINT32)_database.FolderStartFileIndex[folderIndex];
+ for (UINT32 index = extractFolderInfo.ExtractStatuses.Size();
+ index <= fileIndex - startIndex; index++)
+ {
+ UINT64 unPackSize = _database.Files[startIndex + index].UnPackSize;
+ // Count partial_folder_size
+ // extractFolderInfo.UnPackSize += unPackSize;
+ // importantTotalUnPacked += unPackSize;
+ extractFolderInfo.ExtractStatuses.Add(index == fileIndex - startIndex);
+ }
+ }
+
+ extractCallback->SetTotal(importantTotalUnPacked);
+
+ CDecoder decoder;
+
+ UINT64 currentImportantTotalUnPacked = 0;
+ UINT64 totalFolderUnPacked;
+
+ for(int i = 0; i < extractFolderInfoVector.Size(); i++,
+ currentImportantTotalUnPacked += totalFolderUnPacked)
+ {
+ CExtractFolderInfo &extractFolderInfo = extractFolderInfoVector[i];
+ totalFolderUnPacked = extractFolderInfo.UnPackSize;
+
+ RINOK(extractCallback->SetCompleted(&currentImportantTotalUnPacked));
+
+ CFolderOutStream *folderOutStream = new CFolderOutStream;
+ CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
+
+ UINT32 startIndex;
+ if (extractFolderInfo.FileIndex >= 0)
+ startIndex = extractFolderInfo.FileIndex;
+ else
+ startIndex = (UINT32)_database.FolderStartFileIndex[extractFolderInfo.FolderIndex];
+
+
+ RINOK(folderOutStream->Init(&_database, startIndex,
+ &extractFolderInfo.ExtractStatuses, extractCallback, testMode));
+
+ if (extractFolderInfo.FileIndex >= 0)
+ continue;
+
+ UINT32 folderIndex = extractFolderInfo.FolderIndex;
+ const CFolder &folderInfo = _database.Folders[folderIndex];
+
+ CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
+
+ CLockedInStream lockedInStream;
+ lockedInStream.Init(_inStream);
+
+
+ UINT64 folderStartPackStreamIndex = _database.FolderStartPackStreamIndex[folderIndex];
+
+ for (int j = 0; j < folderInfo.PackStreams.Size(); j++)
+ {
+ const CPackStreamInfo &packStreamInfo = folderInfo.PackStreams[j];
+ CLockedSequentialInStreamImp *lockedStreamImpSpec = new
+ CLockedSequentialInStreamImp;
+ CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec;
+ UINT64 streamStartPos = _database.GetFolderStreamPos(folderIndex, j);
+ lockedStreamImpSpec->Init(&lockedInStream, streamStartPos);
+
+ CLimitedSequentialInStream *streamSpec = new
+ CLimitedSequentialInStream;
+ CMyComPtr<ISequentialInStream> inStream = streamSpec;
+ streamSpec->Init(lockedStreamImp,
+ _database.PackSizes[(UINT32)folderStartPackStreamIndex + j]);
+ inStreams.Add(inStream);
+ }
+
+ 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);
+
+ UINT32 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(_inStream,
+ folderStartPackPos,
+ &_database.PackSizes[packStreamIndex],
+ folderInfo,
+ outStream,
+ compressProgress
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #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;
+ RINOK(folderOutStream->WasWritingFinished());
+ }
+ catch(...)
+ {
+ RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+}}
diff --git a/7zip/Archive/7z/7zFolderInStream.cpp b/7zip/Archive/7z/7zFolderInStream.cpp
new file mode 100755
index 00000000..a438c1bd
--- /dev/null
+++ b/7zip/Archive/7z/7zFolderInStream.cpp
@@ -0,0 +1,141 @@
+// 7zFolderInStream.cpp
+
+#include "StdAfx.h"
+
+#include "7zFolderInStream.h"
+
+namespace NArchive {
+namespace N7z {
+
+CFolderInStream::CFolderInStream()
+{
+ _inStreamWithHashSpec = new CInStreamWithCRC;
+ _inStreamWithHash = _inStreamWithHashSpec;
+}
+
+void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback,
+ const UINT32 *fileIndices, UINT32 numFiles)
+{
+ _updateCallback = updateCallback;
+ _numFiles = numFiles;
+ _fileIndex = 0;
+ _fileIndices = fileIndices;
+ CRCs.Clear();
+ Sizes.Clear();
+ _fileIsOpen = false;
+ _currentSizeIsDefined = false;
+}
+
+HRESULT CFolderInStream::OpenStream()
+{
+ _filePos = 0;
+ while (_fileIndex < _numFiles)
+ {
+ _currentSizeIsDefined = false;
+ CMyComPtr<IInStream> stream;
+ RINOK(_updateCallback->GetStream(_fileIndices[_fileIndex], &stream));
+ _fileIndex++;
+ _inStreamWithHashSpec->Init(stream);
+ if (!stream)
+ {
+ RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
+ Sizes.Add(0);
+ 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;
+ Sizes.Add(_filePos);
+ AddDigest();
+ return S_OK;
+}
+
+STDMETHODIMP CFolderInStream::ReadPart(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::Read(void *data, UINT32 size, UINT32 *processedSize)
+{
+ UINT32 realProcessedSize = 0;
+ while (size > 0)
+ {
+ UINT32 localProcessedSize;
+ RINOK(ReadPart(((BYTE *)data) + realProcessedSize, size, &localProcessedSize));
+ if (localProcessedSize == 0)
+ break;
+ size -= localProcessedSize;
+ realProcessedSize += localProcessedSize;
+ }
+ if (processedSize != 0)
+ *processedSize = realProcessedSize;
+ return S_OK;
+}
+
+
+STDMETHODIMP CFolderInStream::GetSubStreamSize(UINT64 subStream, UINT64 *value)
+{
+ *value = 0;
+ if (subStream < Sizes.Size())
+ {
+ *value= Sizes[subStream];
+ return S_OK;
+ }
+ if (subStream > Sizes.Size())
+ return E_FAIL;
+ if (!_currentSizeIsDefined)
+ return S_FALSE;
+ *value = _currentSize;
+ return S_OK;
+}
+
+}}
diff --git a/7zip/Archive/7z/7zFolderInStream.h b/7zip/Archive/7z/7zFolderInStream.h
new file mode 100755
index 00000000..265559a6
--- /dev/null
+++ b/7zip/Archive/7z/7zFolderInStream.h
@@ -0,0 +1,68 @@
+// 7z/FolderInStream.h
+
+#pragma once
+
+#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(ReadPart)(void *data, UINT32 size, UINT32 *processedSize);
+
+ STDMETHOD(GetSubStreamSize)(UINT64 subStream, UINT64 *value);
+private:
+ CInStreamWithCRC *_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<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/7zip/Archive/7z/7zFolderOutStream.cpp b/7zip/Archive/7z/7zFolderOutStream.cpp
new file mode 100755
index 00000000..12abafd5
--- /dev/null
+++ b/7zip/Archive/7z/7zFolderOutStream.cpp
@@ -0,0 +1,165 @@
+// 7zFolderOutStream.cpp
+
+#include "StdAfx.h"
+
+#include "7zFolderOutStream.h"
+
+namespace NArchive {
+namespace N7z {
+
+CFolderOutStream::CFolderOutStream()
+{
+ _outStreamWithHashSpec = new COutStreamWithCRC;
+ _outStreamWithHash = _outStreamWithHashSpec;
+}
+
+HRESULT CFolderOutStream::Init(
+ CArchiveDatabaseEx *archiveDatabase,
+ UINT32 startIndex,
+ const CBoolVector *extractStatuses,
+ IArchiveExtractCallback *extractCallback,
+ bool testMode)
+{
+ _archiveDatabase = archiveDatabase;
+ _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(index, &realOutStream, askMode));
+
+ _outStreamWithHashSpec->Init(realOutStream);
+ if (askMode == NArchive::NExtract::NAskMode::kExtract &&
+ (!realOutStream))
+ {
+ UINT32 index = _startIndex + _currentIndex;
+ 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.FileCRCIsDefined)
+ 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;
+}
+
+STDMETHODIMP CFolderOutStream::WritePart(const void *data,
+ UINT32 size, UINT32 *processedSize)
+{
+ return Write(data, size, processedSize);
+}
+
+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/7zip/Archive/7z/7zFolderOutStream.h b/7zip/Archive/7z/7zFolderOutStream.h
new file mode 100755
index 00000000..c5dcf157
--- /dev/null
+++ b/7zip/Archive/7z/7zFolderOutStream.h
@@ -0,0 +1,58 @@
+// 7zFolderOutStream.h
+
+#pragma once
+
+#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);
+ STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize);
+private:
+
+ COutStreamWithCRC *_outStreamWithHashSpec;
+ CMyComPtr<ISequentialOutStream> _outStreamWithHash;
+ CArchiveDatabaseEx *_archiveDatabase;
+ const CBoolVector *_extractStatuses;
+ UINT32 _startIndex;
+ int _currentIndex;
+ // UINT64 _currentDataPos;
+ CMyComPtr<IArchiveExtractCallback> _extractCallback;
+ bool _testMode;
+
+ bool _fileIsOpen;
+ UINT64 _filePos;
+
+ HRESULT OpenFile();
+ HRESULT WriteEmptyFiles();
+public:
+ HRESULT Init(
+ CArchiveDatabaseEx *archiveDatabase,
+ UINT32 startIndex,
+ const CBoolVector *extractStatuses,
+ IArchiveExtractCallback *extractCallback,
+ bool testMode);
+ HRESULT FlushCorrupted(INT32 resultEOperationResult);
+ HRESULT WasWritingFinished();
+};
+
+}}
+
+#endif
diff --git a/7zip/Archive/7z/7zHandler.cpp b/7zip/Archive/7z/7zHandler.cpp
new file mode 100755
index 00000000..5eaff836
--- /dev/null
+++ b/7zip/Archive/7z/7zHandler.cpp
@@ -0,0 +1,442 @@
+// 7z/Handler.cpp
+
+#include "StdAfx.h"
+
+#include "7zHandler.h"
+#include "7zProperties.h"
+
+#include "../../../Common/IntToString.h"
+// #include "../../../Common/StringConvert.h"
+#include "../../../Common/ComTry.h"
+
+#include "../../../Windows/Defs.h"
+
+#include "../Common/ItemNameUtils.h"
+
+// #include "7zMethods.h"
+
+namespace NArchive {
+namespace N7z {
+
+CHandler::CHandler()
+{
+ #ifndef EXTRACT_ONLY
+ Init();
+ #endif
+ #ifndef EXCLUDE_COM
+ LoadMethodMap();
+ #endif
+}
+
+/*
+STDMETHODIMP CHandler::EnumProperties(IEnumSTATPROPSTG **enumerator)
+{
+ #ifndef _SFX
+ COM_TRY_BEGIN
+ CComObjectNoLock<CEnumArchiveItemProperty> *enumeratorSpec =
+ new CComObjectNoLock<CEnumArchiveItemProperty>;
+ if (enumeratorSpec == NULL)
+ return E_OUTOFMEMORY;
+ CMyComPtr<IEnumSTATPROPSTG> tempEnumerator(enumeratorSpec);
+ enumeratorSpec->Init(_database.ArchiveInfo.FileInfoPopIDs);
+ *enumerator = tempEnumerator.Detach();
+ return S_OK;
+ // return tempEnumerator->QueryInterface(IID_IEnumSTATPROPSTG, (LPVOID*)enumerator);
+ COM_TRY_END
+ #else
+ return E_NOTIMPL;
+ #endif
+}
+*/
+
+STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems)
+{
+ COM_TRY_BEGIN
+ *numItems = _database.Files.Size();
+ return S_OK;
+ COM_TRY_END
+}
+
+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)
+{
+ // FILETIME fileTime;
+ if (timeDefined)
+ propVariant = unixTime;
+ // NTime::UnixTimeToFileTime((time_t)unixTime, fileTime);
+ else
+ {
+ return;
+ // fileTime.dwHighDateTime = fileTime.dwLowDateTime = 0;
+ }
+ // propVariant = fileTime;
+}
+
+/*
+inline static wchar_t GetHex(BYTE value)
+{
+ return (value < 10) ? ('0' + value) : ('A' + (value - 10));
+}
+
+static UString ConvertBytesToHexString(const BYTE *data, UINT32 size)
+{
+ UString result;
+ for (UINT32 i = 0; i < size; i++)
+ {
+ BYTE b = data[i];
+ result += GetHex(b >> 4);
+ result += GetHex(b & 0xF);
+ }
+ return result;
+}
+*/
+
+
+#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_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
+
+static inline char GetHex(BYTE value)
+{
+ return (value < 10) ? ('0' + value) : ('A' + (value - 10));
+}
+static inline UString GetHex2(BYTE value)
+{
+ UString result;
+ result += GetHex(value >> 4);
+ result += GetHex(value & 0xF);
+ return result;
+}
+
+#endif
+
+STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant propVariant;
+ const CFileItem &item = _database.Files[index];
+
+ switch(propID)
+ {
+ case kpidPath:
+ {
+ propVariant = NArchive::NItemName::GetOSName(item.Name);
+ break;
+ }
+ case kpidIsFolder:
+ propVariant = item.IsDirectory;
+ break;
+ case kpidSize:
+ propVariant = item.UnPackSize;
+ break;
+ case kpidPackedSize:
+ {
+ {
+ int folderIndex = _database.FileIndexToFolderIndexMap[index];
+ if (folderIndex >= 0)
+ {
+ const CFolder &folderInfo = _database.Folders[folderIndex];
+ if (_database.FolderStartFileIndex[folderIndex] == index)
+ 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.FileCRCIsDefined)
+ propVariant = item.FileCRC;
+ break;
+ #ifndef _SFX
+ case kpidMethod:
+ {
+ int folderIndex = _database.FileIndexToFolderIndexMap[index];
+ if (folderIndex >= 0)
+ {
+ 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_BZip2)
+ methodName = L"BZip2";
+ 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 = *(const UINT32 *)
+ ((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 = *(const UINT32 *)
+ ((const BYTE *)altCoderInfo.Properties + 1);
+ methodsString += GetStringForSizeValue(dicSize);
+ }
+ }
+ else
+ {
+ if (altCoderInfo.Properties.GetCapacity() > 0)
+ {
+ methodsString += L":[";
+ for (int bi = 0; bi < altCoderInfo.Properties.GetCapacity(); bi++)
+ {
+ if (bi > 2 && 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:
+ {
+ int folderIndex = _database.FileIndexToFolderIndexMap[index];
+ if (folderIndex >= 0)
+ propVariant = (UINT32)folderIndex;
+ }
+ break;
+ case kpidPackedSize0:
+ case kpidPackedSize1:
+ case kpidPackedSize2:
+ case kpidPackedSize3:
+ case kpidPackedSize4:
+ {
+ int folderIndex = _database.FileIndexToFolderIndexMap[index];
+ if (folderIndex >= 0)
+ {
+ const CFolder &folderInfo = _database.Folders[folderIndex];
+ if (_database.FolderStartFileIndex[folderIndex] == index &&
+ folderInfo.PackStreams.Size() > 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
+}
+
+STDMETHODIMP CHandler::Open(IInStream *stream,
+ const UINT64 *maxCheckStartPosition,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ COM_TRY_BEGIN
+ _inStream.Release();
+ _database.Clear();
+ #ifndef _SFX
+ _fileInfoPopIDs.Clear();
+ #endif
+ try
+ {
+ CInArchive archive;
+ RINOK(archive.Open(stream, maxCheckStartPosition));
+
+ #ifndef _NO_CRYPTO
+ CMyComPtr<ICryptoGetTextPassword> getTextPassword;
+ if (openArchiveCallback)
+ {
+ CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;
+ openArchiveCallbackTemp.QueryInterface(
+ IID_ICryptoGetTextPassword, &getTextPassword);
+ }
+ #endif
+
+ HRESULT result = archive.ReadDatabase(_database
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #endif
+ );
+ RINOK(result);
+ result = archive.CheckIntegrity();
+ if (result != S_OK)
+ return E_FAIL;
+ _database.FillFolderStartPackStream();
+ _database.FillStartPos();
+ _database.FillFolderStartFileIndex();
+ }
+ catch(...)
+ {
+ return S_FALSE;
+ }
+ _inStream = stream;
+ #ifndef _SFX
+ FillPopIDs();
+ #endif
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ COM_TRY_BEGIN
+ _inStream.Release();
+ return S_OK;
+ COM_TRY_END
+}
+
+}}
diff --git a/7zip/Archive/7z/7zHandler.h b/7zip/Archive/7z/7zHandler.h
new file mode 100755
index 00000000..a2c2e472
--- /dev/null
+++ b/7zip/Archive/7z/7zHandler.h
@@ -0,0 +1,208 @@
+// 7z/Handler.h
+
+#pragma once
+
+#ifndef __7Z_HANDLER_H
+#define __7Z_HANDLER_H
+
+#include "../IArchive.h"
+// #include "../../../Compress/Interface/CompressInterface.h"
+#include "7zIn.h"
+
+#include "7zCompressionMode.h"
+
+#ifndef _SFX
+#include "7zMethods.h"
+#endif
+
+namespace NArchive {
+namespace N7z {
+
+#ifndef EXTRACT_ONLY
+
+struct COneMethodInfo
+{
+ CObjectVector<CProperty> CoderProperties;
+ UString MethodName;
+};
+#endif
+
+// {23170F69-40C1-278A-1000-000110050000}
+DEFINE_GUID(CLSID_CFormat7z,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 0x00, 0x00);
+
+class CHandler:
+ public IInArchive,
+ #ifndef EXTRACT_ONLY
+ public IOutArchive,
+ public ISetProperties,
+ #endif
+ public CMyUnknownImp
+{
+public:
+ #ifdef EXTRACT_ONLY
+ MY_UNKNOWN_IMP
+ #else
+ MY_UNKNOWN_IMP3(
+ IInArchive,
+ IOutArchive,
+ ISetProperties
+ )
+ #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);
+
+
+ #ifndef EXTRACT_ONLY
+ // IOutArchiveHandler
+ STDMETHOD(UpdateItems)(IOutStream *outStream, UINT32 numItems,
+ IArchiveUpdateCallback *updateCallback);
+
+ STDMETHOD(GetFileTimeType)(UINT32 *type);
+
+ // ISetProperties
+ STDMETHOD(SetProperties)(const BSTR *names, const PROPVARIANT *values, INT32 numProperties);
+
+ HRESULT SetSolidSettings(const UString &s);
+ HRESULT SetSolidSettings(const PROPVARIANT &value);
+ #endif
+
+ CHandler();
+
+private:
+ CMyComPtr<IInStream> _inStream;
+
+ NArchive::N7z::CArchiveDatabaseEx _database;
+
+ #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 _copyMode;
+ UINT32 _defaultDicSize;
+ UINT32 _defaultAlgorithm;
+ UINT32 _defaultFastBytes;
+ UString _defaultMatchFinder;
+ bool _autoFilter;
+ bool _multiThread;
+ UINT32 _level;
+
+ 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,
+ bool multiThread);
+
+ HRESULT SetCompressionMethod(
+ CCompressionMethodMode &method,
+ CCompressionMethodMode &headerMethod);
+
+ #endif
+
+ #ifndef _SFX
+
+ CRecordVector<UINT64> _fileInfoPopIDs;
+ void FillPopIDs();
+
+ #endif
+
+ #ifndef EXTRACT_ONLY
+
+ UINT64 GetUINT64MAX() const
+ {
+ return
+ #if (__GNUC__)
+ 0xFFFFFFFFFFFFFFFFLL
+ #else
+ 0xFFFFFFFFFFFFFFFF
+ #endif
+ ;
+ }
+ void InitSolidFiles() { _numSolidFiles = GetUINT64MAX(); }
+ void InitSolidSize() { _numSolidBytes = GetUINT64MAX(); }
+ void InitSolid()
+ {
+ InitSolidFiles();
+ InitSolidSize();
+ _solidExtension = false;
+ _numSolidBytesDefined = false;
+ }
+ /*
+ void InitSolidPart()
+ {
+ if (_numSolidFiles <= 1)
+ InitSolidFiles();
+ }
+ */
+ void SetSolidBytesLimit()
+ {
+ _numSolidBytes = ((UINT64)_defaultDicSize) << 7;
+ const UINT64 kMinSize = (1<<24);
+ if (_numSolidBytes < kMinSize)
+ _numSolidBytes = kMinSize;
+ }
+ void CheckAndSetSolidBytesLimit()
+ {
+ if (!_numSolidBytesDefined)
+ {
+ if (_copyMode)
+ _numSolidBytes = 0;
+ else
+ SetSolidBytesLimit();
+ }
+ }
+
+ void Init()
+ {
+ _removeSfxBlock = false;
+ _compressHeaders = true;
+ _compressHeadersFull = true;
+ _encryptHeaders = false;
+ _multiThread = false;
+ _copyMode = false;
+ _defaultDicSize = (1 << 21);
+ _defaultAlgorithm = 1;
+ _defaultFastBytes = 32;
+ _defaultMatchFinder = L"BT4";
+ _level = 5;
+ _autoFilter = true;
+ InitSolid();
+ SetSolidBytesLimit();
+ }
+ #endif
+};
+
+}}
+
+#endif
diff --git a/7zip/Archive/7z/7zHandlerOut.cpp b/7zip/Archive/7z/7zHandlerOut.cpp
new file mode 100755
index 00000000..f29d9959
--- /dev/null
+++ b/7zip/Archive/7z/7zHandlerOut.cpp
@@ -0,0 +1,1160 @@
+// 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"
+
+using namespace NWindows;
+
+namespace NArchive {
+namespace N7z {
+
+#ifdef COMPRESS_LZMA
+static CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 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
+static CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
+#endif
+
+#ifdef COMPRESS_BZIP2
+static CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
+#endif
+
+const wchar_t *kCopyMethod = L"Copy";
+const wchar_t *kLZMAMethodName = L"LZMA";
+
+const UINT32 kAlgorithmForX7 = 2;
+const UINT32 kDicSizeForX7 = 1 << 23;
+const UINT32 kFastBytesForX7 = 64;
+
+const UINT32 kAlgorithmForX9 = 2;
+const UINT32 kDicSizeForX9 = 1 << 25;
+const UINT32 kFastBytesForX9 = 64;
+static const wchar_t *kMatchFinderForX9 = L"BT4b";
+
+const UINT32 kAlgorithmForFast = 0;
+const UINT32 kDicSizeForFast = 1 << 15;
+static const wchar_t *kMatchFinderForFast = L"HC3";
+
+const wchar_t *kDefaultMethodName = kLZMAMethodName;
+
+static const wchar_t *kMatchFinderForHeaders = L"BT2";
+static const UINT32 kDictionaryForHeaders = 1 << 20;
+static const UINT32 kNumFastBytesForHeaders = 254;
+
+static bool IsLZMAMethod(const UString &methodName)
+ { return (methodName.CompareNoCase(kLZMAMethodName) == 0); }
+static bool IsLZMethod(const UString &methodName)
+ { return IsLZMAMethod(methodName); }
+
+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));
+ if (methodMode.PasswordIsDefined = IntToBool(passwordIsDefined))
+ methodMode.Password = password;
+ }
+ else
+ methodMode.PasswordIsDefined = false;
+ return S_OK;
+}
+
+// it's work only for non-solid archives
+/*
+STDMETHODIMP CHandler::DeleteItems(IOutStream *outStream,
+ const UINT32* indices, UINT32 numItems, IUpdateCallback *updateCallback)
+{
+ COM_TRY_BEGIN
+ CRecordVector<bool> compressStatuses;
+ CRecordVector<UINT32> copyIndices;
+ int index = 0;
+ int i;
+ for(i = 0; i < _database.NumUnPackStreamsVector.Size(); i++)
+ {
+ if (_database.NumUnPackStreamsVector[i] != 1)
+ return E_NOTIMPL;
+ }
+ for(i = 0; i < _database.Files.Size(); i++)
+ {
+ // bool copyMode = true;
+ if(index < numItems && i == indices[index])
+ index++;
+ else
+ {
+ compressStatuses.Add(false);
+ copyIndices.Add(i);
+ }
+ }
+ CCompressionMethodMode methodMode, headerMethod;
+ RINOK(SetCompressionMethod(methodMode, headerMethod));
+ methodMode.MultiThread = _multiThread;
+ methodMode.MultiThreadMult = _multiThreadMult;
+
+ headerMethod.MultiThread = false;
+ bool useAdditionalHeaderStreams = true;
+ bool compressMainHeader = false;
+
+ // headerMethod.MultiThreadMult = _multiThreadMult;
+
+ return UpdateMain(_database, compressStatuses,
+ CObjectVector<CUpdateItem>(), copyIndices,
+ outStream, _inStream, &_database.ArchiveInfo,
+ NULL, (_compressHeaders ? &headerMethod: 0),
+ useAdditionalHeaderStreams, compressMainHeader,
+ updateCallback, false, _removeSfxBlock);
+ COM_TRY_END
+}
+*/
+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::kAlgorithm, VT_UI4, L"a" },
+ { NCoderPropID::kMatchFinder, VT_BSTR, L"mf" },
+ { NCoderPropID::kMultiThread, VT_BOOL, 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)
+{
+ RINOK(SetCompressionMethod(methodMode, _methods, _multiThread));
+ 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 = kMatchFinderForHeaders;
+ oneMethodInfo.CoderProperties.Add(property);
+ }
+ {
+ CProperty property;
+ property.PropID = NCoderPropID::kAlgorithm;
+ property.Value = kAlgorithmForX9;
+ 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);
+ RINOK(SetCompressionMethod(headerMethod, headerMethodInfoVector, false));
+ }
+ 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,
+ bool multiThread)
+{
+ #ifndef EXCLUDE_COM
+ /*
+ CObjectVector<CMethodInfo2> methodInfoVector;
+ if (!NRegistryInfo::EnumerateAllMethods(methodInfoVector))
+ return E_FAIL;
+ */
+ #endif
+
+
+ if (methodsInfo.IsEmpty())
+ {
+ COneMethodInfo oneMethodInfo;
+ oneMethodInfo.MethodName = _copyMode ? kCopyMethod : kDefaultMethodName;
+ methodsInfo.Add(oneMethodInfo);
+ }
+
+ for(int i = 0; i < methodsInfo.Size(); i++)
+ {
+ COneMethodInfo &oneMethodInfo = methodsInfo[i];
+ if (oneMethodInfo.MethodName.IsEmpty())
+ oneMethodInfo.MethodName = kDefaultMethodName;
+
+ if (IsLZMethod(oneMethodInfo.MethodName))
+ {
+ if (IsLZMAMethod(oneMethodInfo.MethodName))
+ {
+ SetOneMethodProp(oneMethodInfo,
+ NCoderPropID::kDictionarySize, _defaultDicSize);
+ SetOneMethodProp(oneMethodInfo,
+ NCoderPropID::kAlgorithm, _defaultAlgorithm);
+ SetOneMethodProp(oneMethodInfo,
+ NCoderPropID::kNumFastBytes, _defaultFastBytes);
+ SetOneMethodProp(oneMethodInfo,
+ NCoderPropID::kMatchFinder, (const wchar_t *)_defaultMatchFinder);
+ if (multiThread)
+ SetOneMethodProp(oneMethodInfo,
+ NCoderPropID::kMultiThread, true);
+ }
+ }
+ 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
+ if (oneMethodInfo.MethodName.CompareNoCase(L"Deflate") == 0)
+ {
+ defined = true;
+ methodFull.MethodID = k_Deflate;
+ }
+ #endif
+
+ #ifdef COMPRESS_BZIP2
+ 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
+
+ #ifdef EXCLUDE_COM
+
+ if (defined)
+ {
+
+ methodFull.CoderProperties = oneMethodInfo.CoderProperties;
+ methodMode.Methods.Add(methodFull);
+ continue;
+ }
+
+ #else
+
+ CMethodInfo2 methodInfo;
+ if (!GetMethodInfo(oneMethodInfo.MethodName, methodInfo))
+ return E_FAIL;
+ if (!methodInfo.EncoderIsAssigned)
+ return E_FAIL;
+
+ methodFull.MethodID = methodInfo.MethodID;
+ methodFull.NumInStreams = methodInfo.NumInStreams;
+ methodFull.NumOutStreams = methodInfo.NumOutStreams;
+
+ methodFull.EncoderClassID = methodInfo.Encoder;
+ methodFull.FilePath = methodInfo.FilePath;
+ methodFull.CoderProperties = oneMethodInfo.CoderProperties;
+ defined = true;
+
+ #endif
+ if (!defined)
+ return E_FAIL;
+
+ methodMode.Methods.Add(methodFull);
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems,
+ IArchiveUpdateCallback *updateCallback)
+{
+ COM_TRY_BEGIN
+
+ // CRecordVector<bool> compressStatuses;
+ CObjectVector<CUpdateItem> updateItems;
+ // CRecordVector<UINT32> copyIndices;
+
+ // CMyComPtr<IUpdateCallback2> updateCallback2;
+ // updateCallback->QueryInterface(&updateCallback2);
+
+ int index = 0;
+ for(int 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.LastWriteTime = fileItem.LastWriteTime;
+ updateItem.LastWriteTimeIsDefined = fileItem.IsLastWriteTimeDefined;
+ }
+
+ 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;
+ }
+ }
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(i, kpidCreationTime, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ updateItem.CreationTimeIsDefined = false;
+ else if (propVariant.vt != VT_FILETIME)
+ return E_INVALIDARG;
+ else
+ {
+ updateItem.CreationTime = propVariant.filetime;
+ updateItem.CreationTimeIsDefined = true;
+ }
+ }
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(updateCallback->GetProperty(i, kpidLastWriteTime, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ updateItem.LastWriteTimeIsDefined = false;
+ else if (propVariant.vt != VT_FILETIME)
+ return E_INVALIDARG;
+ else
+ {
+ updateItem.LastWriteTime = propVariant.filetime;
+ updateItem.LastWriteTimeIsDefined = true;
+ }
+ }
+ {
+ 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.CreationTimeIsDefined = false;
+ updateItem.LastWriteTimeIsDefined = 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 = *(const UINT64 *)(&propVariant.uhVal);
+ if (updateItem.Size != 0 && updateItem.IsAnti)
+ return E_INVALIDARG;
+ }
+ /*
+ else
+ thereIsCopyData = true;
+ */
+
+ updateItems.Add(updateItem);
+ }
+
+ /*
+ if (thereIsCopyData)
+ {
+ for(int i = 0; i < _database.NumUnPackStreamsVector.Size(); i++)
+ if (_database.NumUnPackStreamsVector[i] != 1)
+ return E_NOTIMPL;
+ if (!_solidIsSpecified)
+ _solid = false;
+ if (_solid)
+ return E_NOTIMPL;
+ }
+ */
+
+
+ CCompressionMethodMode methodMode, headerMethod;
+ RINOK(SetCompressionMethod(methodMode, headerMethod));
+ methodMode.MultiThread = _multiThread;
+ // methodMode.MultiThreadMult = _multiThreadMult;
+
+ headerMethod.MultiThread = false;
+ // headerMethod.MultiThreadMult = _multiThreadMult;
+
+ 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;
+
+ CInArchiveInfo *inArchiveInfo;
+ if (!_inStream)
+ inArchiveInfo = 0;
+ else
+ inArchiveInfo = &_database.ArchiveInfo;
+
+ return Update(_database,
+ // compressStatuses,
+ updateItems,
+ // copyIndices,
+ outStream, _inStream, inArchiveInfo,
+ methodMode,
+ (_compressHeaders ||
+ (methodMode.PasswordIsDefined && _encryptHeaders)) ?
+ &headerMethod : 0,
+ _level != 0 && _autoFilter, // useFilters
+ _level >= 8, // maxFilter
+ useAdditionalHeaderStreams, compressMainHeader,
+ updateCallback, _numSolidFiles, _numSolidBytes, _solidExtension,
+ _removeSfxBlock);
+ COM_TRY_END
+}
+
+static int ParseStringToUINT32(const UString &srcString, UINT32 &number)
+{
+ const wchar_t *start = srcString;
+ const wchar_t *end;
+ UINT64 number64 = ConvertStringToUINT64(start, &end);
+ if (number64 >= (UINT64(1) << 32))
+ {
+ number = 0;
+ return 0;
+ }
+ number = number64;
+ return end - start;
+}
+
+static const int kLogarithmicSizeLimit = 32;
+static const char kByteSymbol = 'B';
+static const char kKiloByteSymbol = 'K';
+static const char kMegaByteSymbol = 'M';
+
+HRESULT ParseDictionaryValues(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 = 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 << 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;
+}
+
+static inline UINT GetCurrentFileCodePage()
+{
+ return AreFileApisANSI() ? CP_ACP : CP_OEMCP;
+}
+
+static 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;
+}
+
+/*
+static HRESULT SetComplexProperty(bool &boolStatus, UINT32 &number,
+ const PROPVARIANT &value)
+{
+ switch(value.vt)
+ {
+ case VT_EMPTY:
+ case VT_BSTR:
+ {
+ RINOK(SetBoolProperty(boolStatus, value));
+ return S_OK;
+ }
+ case VT_UI4:
+ boolStatus = true;
+ number = (value.ulVal);
+ break;
+ default:
+ return E_INVALIDARG;
+ }
+ return S_OK;
+}
+*/
+
+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(ParseDictionaryValues(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 += 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 BSTR *names, const PROPVARIANT *values, INT32 numProperties)
+{
+ UINT codePage = GetCurrentFileCodePage();
+ COM_TRY_BEGIN
+ _methods.Clear();
+ _binds.Clear();
+ Init();
+ int 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;
+ if (value.vt == VT_UI4)
+ {
+ if (!name.IsEmpty())
+ return E_INVALIDARG;
+ _level = value.ulVal;
+ }
+ else if (value.vt == VT_EMPTY)
+ {
+ if(!name.IsEmpty())
+ {
+ int index = ParseStringToUINT32(name, _level);
+ if (index != name.Length())
+ return E_INVALIDARG;
+ }
+ }
+ else
+ return E_INVALIDARG;
+ if (_level == 0)
+ {
+ _copyMode = true;
+ }
+ else if (_level < 5)
+ {
+ _defaultAlgorithm = kAlgorithmForFast;
+ _defaultDicSize = kDicSizeForFast;
+ _defaultMatchFinder = kMatchFinderForFast;
+ }
+ else if (_level < 7)
+ {
+ // normal;
+ }
+ else if(_level < 9)
+ {
+ _defaultAlgorithm = kAlgorithmForX7;
+ _defaultDicSize = kDicSizeForX7;
+ _defaultFastBytes = kFastBytesForX7;
+ }
+ else
+ {
+ _defaultAlgorithm = kAlgorithmForX9;
+ _defaultDicSize = kDicSizeForX9;
+ _defaultFastBytes = kFastBytesForX9;
+ _defaultMatchFinder = kMatchFinderForX9;
+ }
+ 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.CompareNoCase(L"RSFX") == 0)
+ {
+ RINOK(SetBoolProperty(_removeSfxBlock, value));
+ continue;
+ }
+ 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"MT") == 0)
+ {
+ // _multiThreadMult = 200;
+ RINOK(SetBoolProperty(_multiThread, value));
+ // RINOK(SetComplexProperty(MultiThread, _multiThreadMult, value));
+ continue;
+ }
+ number = 0;
+ }
+ if (number > 100)
+ return E_FAIL;
+ if (number < minNumber)
+ {
+ return E_INVALIDARG;
+ }
+ number -= minNumber;
+ for(int j = _methods.Size(); j <= 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.CompareNoCase(L"D") == 0 || realName.CompareNoCase(L"MEM") == 0)
+ {
+ UINT32 dicSize;
+ if (value.vt == VT_UI4)
+ {
+ UINT32 logDicSize = value.ulVal;
+ if (logDicSize >= 32)
+ return E_INVALIDARG;
+ dicSize = (UINT32)1 << logDicSize;
+ }
+ else if (value.vt == VT_BSTR)
+ {
+ RINOK(ParseDictionaryValues(value.bstrVal, dicSize));
+ }
+ else
+ return E_FAIL;
+ if (realName.CompareNoCase(L"D") == 0)
+ property.PropID = NCoderPropID::kDictionarySize;
+ else
+ property.PropID = NCoderPropID::kUsedMemorySize;
+ property.Value = dicSize;
+ oneMethodInfo.CoderProperties.Add(property);
+ }
+ 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);
+ }
+ }
+ }
+ CheckAndSetSolidBytesLimit();
+
+ return S_OK;
+ COM_TRY_END
+}
+
+}}
diff --git a/7zip/Archive/7z/7zHeader.cpp b/7zip/Archive/7z/7zHeader.cpp
new file mode 100755
index 00000000..037e5c45
--- /dev/null
+++ b/7zip/Archive/7z/7zHeader.cpp
@@ -0,0 +1,18 @@
+// 7z/Header.cpp
+
+#include "StdAfx.h"
+#include "7zHeader.h"
+
+namespace NArchive {
+namespace N7z {
+
+BYTE kSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C};
+
+class SignatureInitializer
+{
+public:
+ SignatureInitializer() { kSignature[0]--; };
+} g_SignatureInitializer;
+
+}}
+
diff --git a/7zip/Archive/7z/7zHeader.h b/7zip/Archive/7z/7zHeader.h
new file mode 100755
index 00000000..7830cdc8
--- /dev/null
+++ b/7zip/Archive/7z/7zHeader.h
@@ -0,0 +1,85 @@
+// 7z/Header.h
+
+#pragma once
+
+#ifndef __7Z_HEADER_H
+#define __7Z_HEADER_H
+
+// #include "Common/Types.h"
+// #include "../../../Common/CRC.h"
+
+#include "7zMethodID.h"
+
+namespace NArchive {
+namespace N7z {
+
+#pragma pack( push, Pragma7zHeaders)
+#pragma pack( push, 1)
+
+const int kSignatureSize = 6;
+extern BYTE kSignature[kSignatureSize];
+
+struct CArchiveVersion
+{
+ BYTE Major;
+ BYTE Minor;
+};
+
+struct CStartHeader
+{
+ UINT64 NextHeaderOffset;
+ UINT64 NextHeaderSize;
+ UINT32 NextHeaderCRC;
+};
+
+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,
+ };
+}
+
+
+#pragma pack(pop)
+#pragma pack(pop, Pragma7zHeaders)
+
+const BYTE kMajorVersion = 0;
+
+}}
+
+
+#endif
diff --git a/7zip/Archive/7z/7zIn.cpp b/7zip/Archive/7z/7zIn.cpp
new file mode 100755
index 00000000..cb4690d9
--- /dev/null
+++ b/7zip/Archive/7z/7zIn.cpp
@@ -0,0 +1,1158 @@
+// 7zIn.cpp
+
+#include "StdAfx.h"
+
+#include "7zIn.h"
+#include "7zMethods.h"
+#include "7zDecode.h"
+#include "../../Common/StreamObjects.h"
+#include "../../../Common/CRC.h"
+
+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, UINT32 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, UINT32 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->SafeReadByte2(external));
+ if (external != 0)
+ {
+ UINT64 dataIndex;
+ RINOK(archive->ReadNumber(dataIndex));
+ Set(archive, (*dataVector)[(UINT32)dataIndex]);
+ }
+ return S_OK;
+}
+
+
+CInArchiveException::CInArchiveException(CCauseType cause):
+ Cause(cause)
+{}
+
+HRESULT CInArchive::ReadBytes(IInStream *stream, void *data, UINT32 size,
+ UINT32 *processedSize)
+{
+ UINT32 realProcessedSize;
+ HRESULT result = stream->Read(data, size, &realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ _position += realProcessedSize;
+ return result;
+}
+
+HRESULT CInArchive::ReadBytes(void *data, UINT32 size, UINT32 *processedSize)
+{
+ return ReadBytes(_stream, data, size, processedSize);
+}
+
+HRESULT CInArchive::SafeReadBytes(void *data, UINT32 size)
+{
+ UINT32 realProcessedSize;
+ RINOK(ReadBytes(data, size, &realProcessedSize));
+ if (realProcessedSize != size)
+ throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadNumber(UINT64 &value)
+{
+ BYTE firstByte;
+ RINOK(SafeReadByte2(firstByte));
+ BYTE mask = 0x80;
+ for (int i = 0; i < 8; i++)
+ {
+ if ((firstByte & mask) == 0)
+ {
+ value = 0;
+ RINOK(SafeReadBytes2(&value, i));
+ UINT64 highPart = firstByte & (mask - 1);
+ value += (highPart << (i * 8));
+ return S_OK;
+ }
+ mask >>= 1;
+ }
+ return SafeReadBytes2(&value, 8);
+}
+
+static inline bool TestSignatureCandidate(const void *testBytes)
+{
+ // return (memcmp(testBytes, kSignature, kSignatureSize) == 0);
+ for (UINT32 i = 0; i < kSignatureSize; i++)
+ if (((const BYTE *)testBytes)[i] != kSignature[i])
+ return false;
+ return true;
+}
+
+HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UINT64 *searchHeaderSizeLimit)
+{
+ _position = _arhiveBeginStreamPosition;
+ RINOK(stream->Seek(_arhiveBeginStreamPosition, STREAM_SEEK_SET, NULL));
+
+ BYTE signature[kSignatureSize];
+ UINT32 processedSize;
+ RINOK(ReadBytes(stream, signature, kSignatureSize, &processedSize));
+ if(processedSize != kSignatureSize)
+ return S_FALSE;
+ if (TestSignatureCandidate(signature))
+ return S_OK;
+
+ CByteBuffer byteBuffer;
+ static const UINT32 kSearchSignatureBufferSize = 0x10000;
+ byteBuffer.SetCapacity(kSearchSignatureBufferSize);
+ BYTE *buffer = byteBuffer;
+ UINT32 numBytesPrev = kSignatureSize - 1;
+ memmove(buffer, signature + 1, numBytesPrev);
+ UINT64 curTestPos = _arhiveBeginStreamPosition + 1;
+ while(true)
+ {
+ if (searchHeaderSizeLimit != NULL)
+ if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit)
+ return false;
+ UINT32 numReadBytes = kSearchSignatureBufferSize - numBytesPrev;
+ RINOK(ReadBytes(stream, buffer + numBytesPrev, numReadBytes, &processedSize));
+ UINT32 numBytesInBuffer = numBytesPrev + processedSize;
+ if (numBytesInBuffer < kSignatureSize)
+ return S_FALSE;
+ 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);
+ }
+ }
+ numBytesPrev = numBytesInBuffer - numTests;
+ memmove(buffer, buffer + numTests, numBytesPrev);
+ }
+}
+
+// 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;
+ RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit));
+ _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(SafeReadByte2(temp));
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::SkeepData()
+{
+ UINT64 size;
+ RINOK(ReadNumber(size));
+ return SkeepData(size);
+}
+
+HRESULT CInArchive::ReadArchiveProperties(CInArchiveInfo &archiveInfo)
+{
+ while(true)
+ {
+ UINT64 type;
+ RINOK(ReadID(type));
+ if (type == NID::kEnd)
+ break;
+ SkeepData();
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::GetNextFolderItem(CFolder &folder)
+{
+ UINT64 numCoders;
+ RINOK(ReadNumber(numCoders));
+
+ folder.Coders.Clear();
+ folder.Coders.Reserve((int)numCoders);
+ UINT32 numInStreams = 0;
+ UINT32 numOutStreams = 0;
+ UINT32 i;
+ for (i = 0; i < numCoders; i++)
+ {
+ folder.Coders.Add(CCoderInfo());
+ CCoderInfo &coderInfo = folder.Coders.Back();
+
+ while (true)
+ {
+ coderInfo.AltCoders.Add(CAltCoderInfo());
+ CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Back();
+ BYTE mainByte;
+ RINOK(SafeReadByte2(mainByte));
+ altCoderInfo.MethodID.IDSize = mainByte & 0xF;
+ bool isComplex = (mainByte & 0x10) != 0;
+ bool tereAreProperties = (mainByte & 0x20) != 0;
+ RINOK(SafeReadBytes2(&altCoderInfo.MethodID.ID[0],
+ altCoderInfo.MethodID.IDSize));
+ if (isComplex)
+ {
+ RINOK(ReadNumber(coderInfo.NumInStreams));
+ RINOK(ReadNumber(coderInfo.NumOutStreams));
+ }
+ else
+ {
+ coderInfo.NumInStreams = 1;
+ coderInfo.NumOutStreams = 1;
+ }
+ UINT64 propertiesSize = 0;
+ if (tereAreProperties)
+ {
+ RINOK(ReadNumber(propertiesSize));
+ }
+ altCoderInfo.Properties.SetCapacity((UINT32)propertiesSize);
+ RINOK(SafeReadBytes2((BYTE *)altCoderInfo.Properties,
+ (UINT32)propertiesSize));
+
+ // coderInfo.AltCoders.Add(coderInfo.AltCoders.Back());
+ if ((mainByte & 0x80) == 0)
+ break;
+ }
+ numInStreams += (UINT32)coderInfo.NumInStreams;
+ numOutStreams += (UINT32)coderInfo.NumOutStreams;
+ }
+
+ UINT64 numBindPairs;
+ // RINOK(ReadNumber(numBindPairs));
+ numBindPairs = numOutStreams - 1;
+ folder.BindPairs.Clear();
+ folder.BindPairs.Reserve((UINT32)numBindPairs);
+ for (i = 0; i < numBindPairs; i++)
+ {
+ CBindPair bindPair;
+ RINOK(ReadNumber(bindPair.InIndex));
+ RINOK(ReadNumber(bindPair.OutIndex));
+ folder.BindPairs.Add(bindPair);
+ }
+
+ UINT32 numPackedStreams = numInStreams - (UINT32)numBindPairs;
+ folder.PackStreams.Reserve(numPackedStreams);
+ if (numPackedStreams == 1)
+ {
+ for (UINT32 j = 0; j < numInStreams; j++)
+ if (folder.FindBindPairForInStream(j) < 0)
+ {
+ CPackStreamInfo packStreamInfo;
+ packStreamInfo.Index = j;
+ folder.PackStreams.Add(packStreamInfo);
+ break;
+ }
+ }
+ else
+ for(i = 0; i < numPackedStreams; i++)
+ {
+ CPackStreamInfo packStreamInfo;
+ RINOK(ReadNumber(packStreamInfo.Index));
+ folder.PackStreams.Add(packStreamInfo);
+ }
+
+ return S_OK;
+}
+
+HRESULT CInArchive::WaitAttribute(UINT64 attribute)
+{
+ while(true)
+ {
+ 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;
+ if (digestsDefined[i])
+ RINOK(SafeReadBytes2(&crc, sizeof(crc)));
+ digests.Add(crc);
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadPackInfo(
+ UINT64 &dataOffset,
+ CRecordVector<UINT64> &packSizes,
+ CRecordVector<bool> &packCRCsDefined,
+ CRecordVector<UINT32> &packCRCs)
+{
+ RINOK(ReadNumber(dataOffset));
+ UINT64 numPackStreams;
+ RINOK(ReadNumber(numPackStreams));
+
+ RINOK(WaitAttribute(NID::kSize));
+ packSizes.Clear();
+ packSizes.Reserve((UINT32)numPackStreams);
+ for(UINT64 i = 0; i < numPackStreams; i++)
+ {
+ UINT64 size;
+ RINOK(ReadNumber(size));
+ packSizes.Add(size);
+ }
+
+ UINT64 type;
+ while(true)
+ {
+ RINOK(ReadID(type));
+ if (type == NID::kEnd)
+ break;
+ if (type == NID::kCRC)
+ {
+ RINOK(ReadHashDigests(
+ (UINT32)numPackStreams, packCRCsDefined, packCRCs));
+ continue;
+ }
+ RINOK(SkeepData());
+ }
+ if (packCRCsDefined.IsEmpty())
+ {
+ packCRCsDefined.Reserve((UINT32)numPackStreams);
+ packCRCsDefined.Clear();
+ packCRCs.Reserve((UINT32)numPackStreams);
+ packCRCs.Clear();
+ for(UINT64 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));
+ UINT64 numFolders;
+ RINOK(ReadNumber(numFolders));
+
+ {
+ CStreamSwitch streamSwitch;
+ RINOK(streamSwitch.Set(this, dataVector));
+ folders.Clear();
+ folders.Reserve((UINT32)numFolders);
+ for(UINT64 i = 0; i < numFolders; i++)
+ {
+ folders.Add(CFolder());
+ RINOK(GetNextFolderItem(folders.Back()));
+ }
+ }
+
+ RINOK(WaitAttribute(NID::kCodersUnPackSize));
+
+ UINT32 i;
+ for(i = 0; i < numFolders; i++)
+ {
+ CFolder &folder = folders[i];
+ UINT32 numOutStreams = (UINT32)folder.GetNumOutStreams();
+ folder.UnPackSizes.Reserve(numOutStreams);
+ for(UINT32 j = 0; j < numOutStreams; j++)
+ {
+ UINT64 unPackSize;
+ RINOK(ReadNumber(unPackSize));
+ folder.UnPackSizes.Add(unPackSize);
+ }
+ }
+
+ while(true)
+ {
+ UINT64 type;
+ RINOK(ReadID(type));
+ if (type == NID::kEnd)
+ return S_OK;
+ if (type == NID::kCRC)
+ {
+ CRecordVector<bool> crcsDefined;
+ CRecordVector<UINT32> crcs;
+ RINOK(ReadHashDigests((UINT32)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<UINT64> &numUnPackStreamsInFolders,
+ CRecordVector<UINT64> &unPackSizes,
+ CRecordVector<bool> &digestsDefined,
+ CRecordVector<UINT32> &digests)
+{
+ numUnPackStreamsInFolders.Clear();
+ numUnPackStreamsInFolders.Reserve(folders.Size());
+ UINT64 type;
+ while(true)
+ {
+ RINOK(ReadID(type));
+ if (type == NID::kNumUnPackStream)
+ {
+ for(int i = 0; i < folders.Size(); i++)
+ {
+ UINT64 value;
+ RINOK(ReadNumber(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++)
+ {
+ UINT64 sum = 0;
+ for (UINT64 j = 1; j < numUnPackStreamsInFolders[i]; 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++)
+ {
+ UINT32 numSubstreams = (UINT32)numUnPackStreamsInFolders[i];
+ if (numSubstreams != 1 || !folders[i].UnPackCRCDefined)
+ numDigests += numSubstreams;
+ numDigestsTotal += numSubstreams;
+ }
+
+ while(true)
+ {
+ 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++)
+ {
+ int numSubstreams = (UINT32)numUnPackStreamsInFolders[i];
+ const CFolder &folder = folders[i];
+ if (numSubstreams == 1 && folder.UnPackCRCDefined)
+ {
+ digestsDefined.Add(true);
+ digests.Add(folder.UnPackCRC);
+ }
+ else
+ for (int 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<UINT64> &numUnPackStreamsInFolders,
+ CRecordVector<UINT64> &unPackSizes,
+ CRecordVector<bool> &digestsDefined,
+ CRecordVector<UINT32> &digests)
+{
+ while(true)
+ {
+ 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)
+{
+ // UINT32 pos = 0;
+ for(int i = 0; i < files.Size(); i++)
+ {
+ UString &name = files[i].Name;
+ name.Empty();
+ while (true)
+ {
+ // if (pos >= size)
+ // return S_FALSE;
+ wchar_t c;
+ RINOK(SafeReadWideCharLE(c));
+ // pos++;
+ if (c == '\0')
+ break;
+ name += c;
+ }
+ }
+ // if (pos != size)
+ // return S_FALSE;
+ return S_OK;
+}
+
+HRESULT CInArchive::CheckIntegrity()
+{
+ return S_OK;
+}
+
+
+HRESULT CInArchive::ReadBoolVector(UINT32 numItems, CBoolVector &vector)
+{
+ vector.Clear();
+ vector.Reserve(numItems);
+ BYTE b;
+ BYTE mask = 0;
+ for(UINT32 i = 0; i < numItems; i++)
+ {
+ if (mask == 0)
+ {
+ RINOK(SafeReadBytes2(&b, 1));
+ mask = 0x80;
+ }
+ vector.Add((b & mask) != 0);
+ mask >>= 1;
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadBoolVector2(UINT32 numItems, CBoolVector &vector)
+{
+ BYTE allAreDefinedFlag;
+ RINOK(SafeReadByte2(allAreDefinedFlag));
+ if (allAreDefinedFlag == 0)
+ return ReadBoolVector(numItems, vector);
+ vector.Clear();
+ vector.Reserve(numItems);
+ for (UINT32 j = 0; j < numItems; j++)
+ vector.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;
+ bool defined = boolVector[i];
+ if (defined)
+ {
+ RINOK(SafeReadBytes2(&fileTime, sizeof(fileTime)));
+ }
+ 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<UINT64> 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;
+
+ UINT32 packIndex = 0;
+ CDecoder decoder;
+ 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();
+ data.SetCapacity((UINT32)unPackSize);
+
+ CSequentialOutStreamImp2 *outStreamSpec = new CSequentialOutStreamImp2;
+ CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
+ outStreamSpec->Init(data, (UINT32)unPackSize);
+
+ HRESULT result = decoder.Decode(_stream, dataStartPos,
+ &packSizes[packIndex], folder, outStream, NULL
+ #ifndef _NO_CRYPTO
+ , getTextPassword
+ #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
+ )
+{
+ // database.Clear();
+
+ UINT64 type;
+ RINOK(ReadID(type));
+
+ if (type == NID::kArchiveProperties)
+ {
+ RINOK(ReadArchiveProperties(database.ArchiveInfo));
+ RINOK(ReadID(type));
+ }
+
+ CObjectVector<CByteBuffer> dataVector;
+
+ if (type == NID::kAdditionalStreamsInfo)
+ {
+ /*
+ CRecordVector<UINT64> packSizes;
+ CRecordVector<bool> packCRCsDefined;
+ CRecordVector<UINT32> packCRCs;
+ CObjectVector<CFolder> folders;
+
+ CRecordVector<UINT64> numUnPackStreamsInFolders;
+ CRecordVector<UINT64> unPackSizes;
+ CRecordVector<bool> digestsDefined;
+ CRecordVector<UINT32> digests;
+
+ RINOK(ReadStreamsInfo(NULL,
+ database.ArchiveInfo.DataStartPosition2,
+ packSizes,
+ packCRCsDefined,
+ packCRCs,
+ folders,
+ numUnPackStreamsInFolders,
+ unPackSizes,
+ digestsDefined,
+ digests));
+
+ database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader;
+
+ UINT32 packIndex = 0;
+ CDecoder decoder;
+ UINT64 dataStartPos = database.ArchiveInfo.DataStartPosition2;
+ for(int i = 0; i < folders.Size(); i++)
+ {
+ const CFolder &folder = folders[i];
+ dataVector.Add(CByteBuffer());
+ CByteBuffer &data = dataVector.Back();
+ UINT64 unPackSize = folder.GetUnPackSize();
+ data.SetCapacity(unPackSize);
+
+ CComObjectNoLock<CSequentialOutStreamImp2> *outStreamSpec =
+ new CComObjectNoLock<CSequentialOutStreamImp2>;
+ CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
+ outStreamSpec->Init(data, unPackSize);
+
+ RINOK(decoder.Decode(_stream, dataStartPos,
+ &packSizes[packIndex], folder, outStream, NULL, getTextPassword));
+
+ if (folder.UnPackCRCDefined)
+ if (!CCRC::VerifyDigest(folder.UnPackCRC, data, unPackSize))
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+ for (int j = 0; j < folder.PackStreams.Size(); j++)
+ dataStartPos += packSizes[packIndex++];
+ }
+ */
+ 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);
+ }
+ }
+
+ UINT64 numUnPackStreamsTotal = 0;
+
+ database.Files.Clear();
+
+ if (type == NID::kEnd)
+ return S_OK;
+ if (type != NID::kFilesInfo)
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+
+ UINT64 numFiles;
+ RINOK(ReadNumber(numFiles));
+ database.Files.Reserve((size_t)numFiles);
+ UINT64 i;
+ for(i = 0; i < numFiles; i++)
+ database.Files.Add(CFileItem());
+
+ // int sizePrev = -1;
+ // int posPrev = 0;
+
+ database.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize);
+ if (!database.PackSizes.IsEmpty())
+ database.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo);
+ if (numFiles > 0)
+ {
+ if (!digests.IsEmpty())
+ {
+ database.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC);
+ }
+ }
+
+ CBoolVector emptyStreamVector;
+ emptyStreamVector.Reserve((size_t)numFiles);
+ for(i = 0; i < numFiles; i++)
+ emptyStreamVector.Add(false);
+ CBoolVector emptyFileVector;
+ CBoolVector antiFileVector;
+ UINT32 numEmptyStreams = 0;
+
+ while(true)
+ {
+ /*
+ 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[(UINT32)i];
+ if (file.AreAttributesDefined = boolVector[(UINT32)i])
+ {
+ RINOK(SafeReadBytes2(&file.Attributes,
+ sizeof(file.Attributes)));
+ }
+ }
+ break;
+ }
+ case NID::kEmptyStream:
+ {
+ RINOK(ReadBoolVector((UINT32)numFiles, emptyStreamVector))
+ UINT32 i;
+ for (i = 0; i < (UINT32)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));
+ }
+ }
+ }
+
+ UINT32 emptyFileIndex = 0;
+ UINT32 sizeIndex = 0;
+ for(i = 0; i < numFiles; i++)
+ {
+ CFileItem &file = database.Files[(UINT32)i];
+ file.HasStream = !emptyStreamVector[(UINT32)i];
+ if(file.HasStream)
+ {
+ file.IsDirectory = false;
+ file.IsAnti = false;
+ file.UnPackSize = unPackSizes[sizeIndex];
+ file.FileCRC = digests[sizeIndex];
+ file.FileCRCIsDefined = digestsDefined[sizeIndex];
+ sizeIndex++;
+ }
+ else
+ {
+ file.IsDirectory = !emptyFileVector[emptyFileIndex];
+ file.IsAnti = antiFileVector[emptyFileIndex];
+ emptyFileIndex++;
+ file.UnPackSize = 0;
+ file.FileCRCIsDefined = false;
+ }
+ }
+ return S_OK;
+}
+
+
+void CArchiveDatabaseEx::FillFolderStartPackStream()
+{
+ FolderStartPackStreamIndex.Clear();
+ FolderStartPackStreamIndex.Reserve(Folders.Size());
+ UINT64 startPos = 0;
+ for(UINT64 i = 0; i < Folders.Size(); i++)
+ {
+ FolderStartPackStreamIndex.Add((UINT32)startPos);
+ startPos += Folders[(UINT32)i].PackStreams.Size();
+ }
+}
+
+void CArchiveDatabaseEx::FillStartPos()
+{
+ PackStreamStartPositions.Clear();
+ PackStreamStartPositions.Reserve(PackSizes.Size());
+ UINT64 startPos = 0;
+ for(UINT64 i = 0; i < PackSizes.Size(); i++)
+ {
+ PackStreamStartPositions.Add(startPos);
+ startPos += PackSizes[(UINT32)i];
+ }
+}
+
+void CArchiveDatabaseEx::FillFolderStartFileIndex()
+{
+ FolderStartFileIndex.Clear();
+ FolderStartFileIndex.Reserve(Folders.Size());
+ FileIndexToFolderIndexMap.Clear();
+ FileIndexToFolderIndexMap.Reserve(Files.Size());
+
+ int folderIndex = 0;
+ int 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(-1);
+ continue;
+ }
+ if (indexInFolder == 0)
+ {
+ if (folderIndex >= Folders.Size())
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+ FolderStartFileIndex.Add(i);
+ }
+ 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(SafeReadBytes(&database.ArchiveInfo.Version,
+ sizeof(database.ArchiveInfo.Version)));
+ if (database.ArchiveInfo.Version.Major != kMajorVersion)
+ throw CInArchiveException(CInArchiveException::kUnsupportedVersion);
+
+ UINT32 crcFromArchive;
+ RINOK(SafeReadBytes(&crcFromArchive, sizeof(crcFromArchive)));
+ CStartHeader startHeader;
+ RINOK(SafeReadBytes(&startHeader, sizeof(startHeader)));
+ if (!CCRC::VerifyDigest(crcFromArchive, &startHeader, sizeof(startHeader)))
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+
+ database.ArchiveInfo.StartPositionAfterHeader = _position;
+
+ if (startHeader.NextHeaderSize == 0)
+ return S_OK;
+
+ RINOK(_stream->Seek(startHeader.NextHeaderOffset, STREAM_SEEK_CUR, &_position));
+
+ CByteBuffer buffer2;
+ buffer2.SetCapacity((size_t)startHeader.NextHeaderSize);
+ RINOK(SafeReadBytes(buffer2, (UINT32)startHeader.NextHeaderSize));
+ if (!CCRC::VerifyDigest(startHeader.NextHeaderCRC, buffer2, (UINT32)startHeader.NextHeaderSize))
+ throw CInArchiveException(CInArchiveException::kIncorrectHeader);
+
+ CStreamSwitch streamSwitch;
+ streamSwitch.Set(this, buffer2);
+
+ CObjectVector<CByteBuffer> dataVector;
+
+ while (true)
+ {
+ 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/7zip/Archive/7z/7zIn.h b/7zip/Archive/7z/7zIn.h
new file mode 100755
index 00000000..0a835ac0
--- /dev/null
+++ b/7zip/Archive/7z/7zIn.h
@@ -0,0 +1,266 @@
+// 7zIn.h
+
+#pragma once
+
+#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<UINT32> FolderStartPackStreamIndex;
+ CRecordVector<UINT64> FolderStartFileIndex;
+ CRecordVector<int> FileIndexToFolderIndexMap;
+
+ void Clear()
+ {
+ CArchiveDatabase::Clear();
+ ArchiveInfo.Clear();
+ PackStreamStartPositions.Clear();
+ FolderStartPackStreamIndex.Clear();
+ FolderStartFileIndex.Clear();
+ FolderStartFileIndex.Clear();
+ }
+
+ void FillFolderStartPackStream();
+ void FillStartPos();
+ void FillFolderStartFileIndex();
+
+ UINT64 GetFolderStreamPos(int folderIndex, int indexInFolder) const
+ {
+ return ArchiveInfo.DataStartPosition +
+ PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] +
+ indexInFolder];
+ }
+
+ UINT64 GetFolderFullPackSize(int folderIndex) const
+ {
+ UINT32 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];
+ }
+};
+
+class CInByte2
+{
+ const BYTE *_buffer;
+ UINT32 _size;
+ UINT32 _pos;
+public:
+ void Init(const BYTE *buffer, UINT32 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, UINT32 size, UINT32 &processedSize)
+ {
+ for(processedSize = 0; processedSize < size && _pos < _size; processedSize++)
+ ((BYTE *)data)[processedSize] = _buffer[_pos++];
+ }
+
+ bool ReadBytes(void *data, UINT32 size)
+ {
+ UINT32 processedSize;
+ ReadBytes(data, size, processedSize);
+ return (processedSize == size);
+ }
+
+ UINT32 GetProcessedSize() const { return _pos; }
+};
+
+class CStreamSwitch;
+class CInArchive
+{
+ friend class CStreamSwitch;
+
+ CMyComPtr<IInStream> _stream;
+
+ CObjectVector<CInByte2> _inByteVector;
+ CInByte2 *_inByteBack;
+
+ UINT64 _arhiveBeginStreamPosition;
+ UINT64 _position;
+
+ void AddByteStream(const BYTE *buffer, UINT32 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
+
+ HRESULT ReadFileNames(CObjectVector<CFileItem> &files);
+
+ HRESULT ReadBytes(IInStream *stream, void *data, UINT32 size,
+ UINT32 *processedSize);
+ HRESULT ReadBytes(void *data, UINT32 size, UINT32 *processedSize);
+ HRESULT SafeReadBytes(void *data, UINT32 size);
+
+ HRESULT SafeReadBytes2(void *data, UINT32 size)
+ {
+ if (!_inByteBack->ReadBytes(data, size))
+ return E_FAIL;
+ return S_OK;
+ }
+
+ HRESULT SafeReadByte2(BYTE &b)
+ {
+ if (!_inByteBack->ReadByte(b))
+ return E_FAIL;
+ return S_OK;
+ }
+
+ HRESULT SafeReadWideCharLE(wchar_t &c)
+ {
+ BYTE b1;
+ if (!_inByteBack->ReadByte(b1))
+ return E_FAIL;
+ BYTE b2;
+ if (!_inByteBack->ReadByte(b2))
+ return E_FAIL;
+ c = (int(b2) << 8) + b1;
+ return S_OK;
+ }
+
+ HRESULT ReadNumber(UINT64 &value);
+
+ HRESULT ReadID(UINT64 &value)
+ {
+ return ReadNumber(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<UINT64> &numUnPackStreamsInFolders,
+ CRecordVector<UINT64> &unPackSizes,
+ CRecordVector<bool> &digestsDefined,
+ CRecordVector<UINT32> &digests);
+
+ HRESULT CInArchive::ReadStreamsInfo(
+ const CObjectVector<CByteBuffer> *dataVector,
+ UINT64 &dataOffset,
+ CRecordVector<UINT64> &packSizes,
+ CRecordVector<bool> &packCRCsDefined,
+ CRecordVector<UINT32> &packCRCs,
+ CObjectVector<CFolder> &folders,
+ CRecordVector<UINT64> &numUnPackStreamsInFolders,
+ CRecordVector<UINT64> &unPackSizes,
+ CRecordVector<bool> &digestsDefined,
+ CRecordVector<UINT32> &digests);
+
+
+
+ HRESULT GetNextFileItem(CFileItem &itemInfo);
+ HRESULT ReadBoolVector(UINT32 numItems, CBoolVector &vector);
+ HRESULT ReadBoolVector2(UINT32 numItems, CBoolVector &vector);
+ 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
+ );
+ HRESULT CheckIntegrity();
+};
+
+}}
+
+#endif
diff --git a/7zip/Archive/7z/7zItem.h b/7zip/Archive/7z/7zItem.h
new file mode 100755
index 00000000..da1eaefc
--- /dev/null
+++ b/7zip/Archive/7z/7zItem.h
@@ -0,0 +1,195 @@
+// 7zItem.h
+
+#pragma once
+
+#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;
+};
+
+struct CCoderInfo
+{
+ UINT64 NumInStreams;
+ UINT64 NumOutStreams;
+ CObjectVector<CAltCoderInfo> AltCoders;
+ bool IsSimpleCoder() const
+ { return (NumInStreams == 1) && (NumOutStreams == 1); }
+};
+
+struct CPackStreamInfo
+{
+ UINT64 Index;
+};
+
+struct CBindPair
+{
+ UINT64 InIndex;
+ UINT64 OutIndex;
+};
+
+struct CFolder
+{
+ CObjectVector<CCoderInfo> Coders;
+ CRecordVector<CBindPair> BindPairs;
+ CRecordVector<CPackStreamInfo> PackStreams;
+ CRecordVector<UINT64> UnPackSizes;
+ bool UnPackCRCDefined;
+ UINT32 UnPackCRC;
+
+ 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;
+ }
+ UINT64 GetNumOutStreams() const
+ {
+ UINT64 result = 0;
+ for (int i = 0; i < Coders.Size(); i++)
+ result += Coders[i].NumOutStreams;
+ return result;
+ }
+
+
+ int FindBindPairForInStream(int inStreamIndex) const
+ {
+ for(int i = 0; i < BindPairs.Size(); i++)
+ if (BindPairs[i].InIndex == inStreamIndex)
+ return i;
+ return -1;
+ }
+ int FindBindPairForOutStream(int outStreamIndex) const
+ {
+ for(int i = 0; i < BindPairs.Size(); i++)
+ if (BindPairs[i].OutIndex == outStreamIndex)
+ return i;
+ return -1;
+ }
+ int FindPackStreamArrayIndex(int inStreamIndex) const
+ {
+ for(int i = 0; i < PackStreams.Size(); i++)
+ if (PackStreams[i].Index == inStreamIndex)
+ return i;
+ return -1;
+ }
+};
+
+typedef FILETIME CArchiveFileTime;
+
+class CFileItem
+{
+public:
+ CArchiveFileTime CreationTime;
+ CArchiveFileTime LastWriteTime;
+ CArchiveFileTime LastAccessTime;
+ UINT64 UnPackSize;
+ 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 FileCRCIsDefined;
+ bool AreAttributesDefined;
+ bool IsCreationTimeDefined;
+ bool IsLastWriteTimeDefined;
+ bool IsLastAccessTimeDefined;
+
+ /*
+ const bool HasStream() const {
+ return !IsDirectory && !IsAnti && UnPackSize != 0; }
+ */
+ CFileItem():
+ AreAttributesDefined(false),
+ IsCreationTimeDefined(false),
+ IsLastWriteTimeDefined(false),
+ IsLastAccessTimeDefined(false),
+ IsDirectory(false),
+ FileCRCIsDefined(false),
+ IsAnti(false),
+ HasStream(true)
+ {}
+ void SetAttributes(UINT32 attributes)
+ {
+ AreAttributesDefined = true;
+ Attributes = attributes;
+ }
+ void SetCreationTime(CArchiveFileTime creationTime)
+ {
+ IsCreationTimeDefined = true;
+ CreationTime = creationTime;
+ }
+ void SetLastWriteTime(CArchiveFileTime lastWriteTime)
+ {
+ IsLastWriteTimeDefined = true;
+ LastWriteTime = lastWriteTime;
+ }
+ void SetLastAccessTime(CArchiveFileTime lastAccessTime)
+ {
+ IsLastAccessTimeDefined = true;
+ LastAccessTime = lastAccessTime;
+ }
+};
+
+struct CArchiveDatabase
+{
+ CRecordVector<UINT64> PackSizes;
+ CRecordVector<bool> PackCRCsDefined;
+ CRecordVector<UINT32> PackCRCs;
+ CObjectVector<CFolder> Folders;
+ CRecordVector<UINT64> 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());
+ }
+};
+
+struct CArchiveHeaderDatabase
+{
+ CRecordVector<UINT64> PackSizes;
+ CObjectVector<CFolder> Folders;
+ CRecordVector<UINT32> CRCs;
+ void Clear()
+ {
+ PackSizes.Clear();
+ Folders.Clear();
+ CRCs.Clear();
+ }
+};
+
+}}
+
+#endif
diff --git a/7zip/Archive/7z/7zMethodID.cpp b/7zip/Archive/7z/7zMethodID.cpp
new file mode 100755
index 00000000..f1ffc75f
--- /dev/null
+++ b/7zip/Archive/7z/7zMethodID.cpp
@@ -0,0 +1,68 @@
+// 7zMethodID.cpp
+
+#include "StdAfx.h"
+
+#include "7zMethodID.h"
+
+namespace NArchive {
+namespace N7z {
+
+static inline wchar_t GetHex(BYTE value)
+{
+ return (value < 10) ? ('0' + value) : ('A' + (value - 10));
+}
+
+static bool HexCharToInt(wchar_t value, BYTE &result)
+{
+ if (value >= '0' && value <= '9')
+ result = value - '0';
+ else if (value >= 'a' && value <= 'f')
+ result = 10 + value - 'a';
+ else if (value >= 'A' && value <= 'F')
+ result = 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 = (resultHigh << 4) + resultLow;
+ return true;
+}
+
+UString CMethodID::ConvertToString() const
+{
+ UString result;
+ for (int i = 0; i < IDSize; i++)
+ {
+ BYTE b = ID[i];
+ result += GetHex(b >> 4);
+ result += GetHex(b & 0xF);
+ }
+ return result;
+}
+
+bool CMethodID::ConvertFromString(const UString &srcString)
+{
+ int length = srcString.Length();
+ if ((length & 1) != 0)
+ return false;
+ IDSize = length / 2;
+ if (IDSize > kMethodIDSize)
+ return false;
+ UINT32 i;
+ for(i = 0; i < IDSize; i++)
+ if (!TwoHexCharsToInt(srcString[i * 2], srcString[i * 2 + 1], ID[i]))
+ return false;
+ for(i = IDSize; i < kMethodIDSize; i++)
+ ID[i] = 0;
+ return true;
+}
+
+}}
diff --git a/7zip/Archive/7z/7zMethodID.h b/7zip/Archive/7z/7zMethodID.h
new file mode 100755
index 00000000..9f30e665
--- /dev/null
+++ b/7zip/Archive/7z/7zMethodID.h
@@ -0,0 +1,38 @@
+// 7zMethodID.h
+
+#pragma once
+
+#ifndef __7Z_METHOD_ID_H
+#define __7Z_METHOD_ID_H
+
+#include "../../../Common/String.h"
+
+namespace NArchive {
+namespace N7z {
+
+const int kMethodIDSize = 16;
+
+struct CMethodID
+{
+ BYTE ID[kMethodIDSize];
+ UINT32 IDSize;
+ UString ConvertToString() const;
+ bool ConvertFromString(const UString &srcString);
+};
+
+inline 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;
+}
+
+inline bool operator!=(const CMethodID &a1, const CMethodID &a2)
+ { return !(a1 == a2); }
+
+}}
+
+#endif
diff --git a/7zip/Archive/7z/7zMethods.cpp b/7zip/Archive/7z/7zMethods.cpp
new file mode 100755
index 00000000..29531234
--- /dev/null
+++ b/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 = 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.CollateNoCase(name) == 0)
+ {
+ methodInfo = method;
+ return true;
+ }
+ }
+ return false;
+}
+
+}}
+
+
diff --git a/7zip/Archive/7z/7zMethods.h b/7zip/Archive/7z/7zMethods.h
new file mode 100755
index 00000000..64b67df8
--- /dev/null
+++ b/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/7zip/Archive/7z/7zOut.cpp b/7zip/Archive/7z/7zOut.cpp
new file mode 100755
index 00000000..45cd94fa
--- /dev/null
+++ b/7zip/Archive/7z/7zOut.cpp
@@ -0,0 +1,853 @@
+// 7zOut.cpp
+
+#include "StdAfx.h"
+
+#include "7zOut.h"
+#include "../../Common/StreamObjects.h"
+
+static HRESULT WriteBytes(IOutStream *stream, const void *data, UINT32 size)
+{
+ UINT32 processedSize;
+ RINOK(stream->Write(data, size, &processedSize));
+ if(processedSize != size)
+ return E_FAIL;
+ return S_OK;
+}
+
+namespace NArchive {
+namespace N7z {
+
+HRESULT COutArchive::Create(IOutStream *stream)
+{
+ Close();
+ RINOK(::WriteBytes(stream, kSignature, kSignatureSize));
+ CArchiveVersion archiveVersion;
+ archiveVersion.Major = kMajorVersion;
+ archiveVersion.Minor = 2;
+ RINOK(::WriteBytes(stream, &archiveVersion, sizeof(archiveVersion)));
+ RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_prefixHeaderPos));
+ Stream = stream;
+ return S_OK;
+}
+
+void COutArchive::Close()
+{
+ Stream.Release();
+}
+
+HRESULT COutArchive::SkeepPrefixArchiveHeader()
+{
+ return Stream->Seek(sizeof(CStartHeader) + sizeof(UINT32), STREAM_SEEK_CUR, NULL);
+}
+
+HRESULT COutArchive::WriteBytes(const void *data, UINT32 size)
+{
+ return ::WriteBytes(Stream, data, size);
+}
+
+
+HRESULT COutArchive::WriteBytes2(const void *data, UINT32 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::WriteBytes2(const CByteBuffer &data)
+{
+ return WriteBytes2(data, data.GetCapacity());
+}
+
+HRESULT COutArchive::WriteByte2(BYTE b)
+{
+ return WriteBytes2(&b, 1);
+}
+
+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(WriteByte2(firstByte));
+ return WriteBytes2(&value, i);
+}
+
+static UINT32 GetBigNumberSize(UINT64 value)
+{
+ int i;
+ for (i = 0; i < 8; i++)
+ if (value < ((UINT64(1) << ( 7 * (i + 1)))))
+ break;
+ return 1 + i;
+}
+
+HRESULT COutArchive::WriteFolderHeader(const CFolder &itemInfo)
+{
+ RINOK(WriteNumber(itemInfo.Coders.Size()));
+ int i;
+ for (i = 0; i < itemInfo.Coders.Size(); i++)
+ {
+ const CCoderInfo &coderInfo = itemInfo.Coders[i];
+ for (int j = 0; j < coderInfo.AltCoders.Size(); j++)
+ {
+ const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders[j];
+ UINT64 propertiesSize = altCoderInfo.Properties.GetCapacity();
+
+ BYTE b;
+ b = altCoderInfo.MethodID.IDSize & 0xF;
+ bool isComplex = (coderInfo.NumInStreams != 1) ||
+ (coderInfo.NumOutStreams != 1);
+ b |= (isComplex ? 0x10 : 0);
+ b |= ((propertiesSize != 0) ? 0x20 : 0 );
+ b |= ((j == coderInfo.AltCoders.Size() - 1) ? 0 : 0x80 );
+ RINOK(WriteByte2(b));
+ RINOK(WriteBytes2(&altCoderInfo.MethodID.ID[0],
+ altCoderInfo.MethodID.IDSize));
+ if (isComplex)
+ {
+ RINOK(WriteNumber(coderInfo.NumInStreams));
+ RINOK(WriteNumber(coderInfo.NumOutStreams));
+ }
+ if (propertiesSize == 0)
+ continue;
+ RINOK(WriteNumber(propertiesSize));
+ RINOK(WriteBytes2(altCoderInfo.Properties, (UINT32)propertiesSize));
+ }
+ }
+ // RINOK(WriteNumber(itemInfo.BindPairs.Size()));
+ for (i = 0; i < itemInfo.BindPairs.Size(); i++)
+ {
+ const CBindPair &bindPair = itemInfo.BindPairs[i];
+ RINOK(WriteNumber(bindPair.InIndex));
+ RINOK(WriteNumber(bindPair.OutIndex));
+ }
+ if (itemInfo.PackStreams.Size() > 1)
+ for (i = 0; i < itemInfo.PackStreams.Size(); i++)
+ {
+ const CPackStreamInfo &packStreamInfo = itemInfo.PackStreams[i];
+ RINOK(WriteNumber(packStreamInfo.Index));
+ }
+ 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(WriteBytes2(&b, 1));
+ mask = 0x80;
+ b = 0;
+ }
+ }
+ if (mask != 0x80)
+ {
+ RINOK(WriteBytes2(&b, 1));
+ }
+ 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(WriteByte2(NID::kCRC));
+ if (numDefined == digestsDefined.Size())
+ {
+ RINOK(WriteByte2(1));
+ }
+ else
+ {
+ RINOK(WriteByte2(0));
+ RINOK(WriteBoolVector(digestsDefined));
+ }
+ for(i = 0; i < digests.Size(); i++)
+ {
+ if(digestsDefined[i])
+ RINOK(WriteBytes2(&digests[i], sizeof(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(WriteByte2(NID::kPackInfo));
+ RINOK(WriteNumber(dataOffset));
+ RINOK(WriteNumber(packSizes.Size()));
+ RINOK(WriteByte2(NID::kSize));
+ for(int i = 0; i < packSizes.Size(); i++)
+ RINOK(WriteNumber(packSizes[i]));
+
+ RINOK(WriteHashDigests(packCRCsDefined, packCRCs));
+
+ return WriteByte2(NID::kEnd);
+}
+
+HRESULT COutArchive::WriteUnPackInfo(
+ bool externalFolders,
+ UINT64 externalFoldersStreamIndex,
+ const CObjectVector<CFolder> &folders)
+{
+ if (folders.IsEmpty())
+ return S_OK;
+
+ RINOK(WriteByte2(NID::kUnPackInfo));
+
+ RINOK(WriteByte2(NID::kFolder));
+ RINOK(WriteNumber(folders.Size()));
+ if (externalFolders)
+ {
+ RINOK(WriteByte2(1));
+ RINOK(WriteNumber(externalFoldersStreamIndex));
+ }
+ else
+ {
+ RINOK(WriteByte2(0));
+ for(int i = 0; i < folders.Size(); i++)
+ RINOK(WriteFolderHeader(folders[i]));
+ }
+
+ RINOK(WriteByte2(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 WriteByte2(NID::kEnd);
+}
+
+HRESULT COutArchive::WriteSubStreamsInfo(
+ const CObjectVector<CFolder> &folders,
+ const CRecordVector<UINT64> &numUnPackStreamsInFolders,
+ const CRecordVector<UINT64> &unPackSizes,
+ const CRecordVector<bool> &digestsDefined,
+ const CRecordVector<UINT32> &digests)
+{
+ RINOK(WriteByte2(NID::kSubStreamsInfo));
+
+ int i;
+ for(i = 0; i < numUnPackStreamsInFolders.Size(); i++)
+ {
+ if (numUnPackStreamsInFolders[i] != 1)
+ {
+ RINOK(WriteByte2(NID::kNumUnPackStream));
+ for(i = 0; i < numUnPackStreamsInFolders.Size(); i++)
+ RINOK(WriteNumber(numUnPackStreamsInFolders[i]));
+ break;
+ }
+ }
+
+
+ UINT32 needFlag = true;
+ UINT32 index = 0;
+ for(i = 0; i < numUnPackStreamsInFolders.Size(); i++)
+ for (UINT32 j = 0; j < numUnPackStreamsInFolders[i]; j++)
+ {
+ if (j + 1 != numUnPackStreamsInFolders[i])
+ {
+ if (needFlag)
+ RINOK(WriteByte2(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 WriteByte2(NID::kEnd);
+}
+
+HRESULT COutArchive::WriteTime(
+ const CObjectVector<CFileItem> &files, BYTE type,
+ bool isExternal, int 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(WriteByte2(type));
+ UINT32 dataSize = 1 + 1;
+ if (isExternal)
+ dataSize += GetBigNumberSize(externalDataIndex);
+ else
+ dataSize += files.Size() * sizeof(CArchiveFileTime);
+ if (allDefined)
+ {
+ RINOK(WriteNumber(dataSize));
+ WriteByte2(1);
+ }
+ else
+ {
+ RINOK(WriteNumber(1 + (boolVector.Size() + 7) / 8 + dataSize));
+ WriteByte2(0);
+ RINOK(WriteBoolVector(boolVector));
+ }
+ if (isExternal)
+ {
+ RINOK(WriteByte2(1));
+ RINOK(WriteNumber(externalDataIndex));
+ return S_OK;
+ }
+ RINOK(WriteByte2(0));
+ for(i = 0; i < files.Size(); i++)
+ {
+ if (boolVector[i])
+ {
+ const CFileItem &item = files[i];
+ CArchiveFileTime timeValue;
+ switch(type)
+ {
+ case NID::kCreationTime:
+ timeValue = item.CreationTime;
+ break;
+ case NID::kLastWriteTime:
+ timeValue = item.LastWriteTime;
+ break;
+ case NID::kLastAccessTime:
+ timeValue = item.LastAccessTime;
+ break;
+ }
+ RINOK(WriteBytes2(&timeValue, sizeof(timeValue)));
+ }
+ }
+ return S_OK;
+}
+
+HRESULT COutArchive::EncodeStream(CEncoder &encoder, const BYTE *data, UINT32 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);
+ RINOK(encoder.Encode(stream, NULL,
+ folderItem, Stream,
+ 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);
+}
+
+
+
+HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database,
+ const CCompressionMethodMode *options, UINT64 &headerOffset)
+{
+ CObjectVector<CFolder> folders;
+
+ bool compressHeaders = (options != NULL);
+ std::auto_ptr<CEncoder> encoder;
+ if (compressHeaders)
+ encoder = std::auto_ptr<CEncoder>(new CEncoder(*options));
+
+ CRecordVector<UINT64> packSizes;
+
+ UINT64 dataIndex = 0;
+
+ //////////////////////////
+ // Folders
+
+ UINT64 externalFoldersStreamIndex;
+ 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(WriteFolderHeader(database.Folders[i]));
+ }
+
+ _countMode = false;
+
+ CByteBuffer foldersData;
+ foldersData.SetCapacity(_countSize);
+ _outByte2.Init(foldersData, foldersData.GetCapacity());
+
+ for(i = 0; i < database.Folders.Size(); i++)
+ {
+ RINOK(WriteFolderHeader(database.Folders[i]));
+ }
+
+ {
+ externalFoldersStreamIndex = dataIndex++;
+ RINOK(EncodeStream(*encoder, foldersData, packSizes, folders));
+ }
+ }
+
+
+ /////////////////////////////////
+ // Names
+
+ CByteBuffer namesData;
+ UINT64 externalNamesStreamIndex;
+ bool externalNames = (compressHeaders && database.Files.Size() > 8);
+ {
+ UINT64 namesDataSize = 0;
+ int i;
+ for(i = 0; i < database.Files.Size(); i++)
+ namesDataSize += (database.Files[i].Name.Length() + 1) * sizeof(wchar_t);
+ namesData.SetCapacity(namesDataSize);
+ UINT32 pos = 0;
+ for(i = 0; i < database.Files.Size(); i++)
+ {
+ const UString &name = database.Files[i].Name;
+ int length = name.Length() * sizeof(wchar_t);
+ memmove(namesData + pos, name, length);
+ pos += length;
+ 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());
+ UINT32 numDefinedAttributes = 0;
+ int i;
+ for(i = 0; i < database.Files.Size(); i++)
+ {
+ bool defined = database.Files[i].AreAttributesDefined;
+ attributesBoolVector.Add(defined);
+ if (defined)
+ numDefinedAttributes++;
+ }
+
+ CByteBuffer attributesData;
+ UINT64 externalAttributesStreamIndex;
+ bool externalAttributes = (compressHeaders && numDefinedAttributes > 8);
+ if (numDefinedAttributes > 0)
+ {
+ attributesData.SetCapacity(numDefinedAttributes * sizeof(UINT32));
+ UINT32 pos = 0;
+ for(i = 0; i < database.Files.Size(); i++)
+ {
+ const CFileItem &file = database.Files[i];
+ if (file.AreAttributesDefined)
+ {
+ memmove(attributesData + pos, &database.Files[i].Attributes, sizeof(UINT32));
+ pos += sizeof(UINT32);
+ }
+ }
+ if (externalAttributes)
+ {
+ externalAttributesStreamIndex = dataIndex++;
+ RINOK(EncodeStream(*encoder, attributesData, packSizes, folders));
+ }
+ }
+
+ /////////////////////////////////
+ // Write Last Write Time
+ UINT64 externalLastWriteTimeStreamIndex;
+ bool externalLastWriteTime = false;
+ // /*
+ UINT32 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 * sizeof(CArchiveFileTime));
+ UINT32 pos = 0;
+ for(i = 0; i < database.Files.Size(); i++)
+ {
+ const CFileItem &file = database.Files[i];
+ if (file.IsLastWriteTimeDefined)
+ {
+ memmove(lastWriteTimeData + pos, &database.Files[i].LastWriteTime, sizeof(CArchiveFileTime));
+ pos += sizeof(CArchiveFileTime);
+ }
+ }
+ 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.Init(Stream);
+ _crc.Init();
+
+
+ RINOK(WriteByte2(NID::kHeader));
+
+ // Archive Properties
+
+ if (folders.Size() > 0)
+ {
+ RINOK(WriteByte2(NID::kAdditionalStreamsInfo));
+ RINOK(WritePackInfo(packedSize, packSizes,
+ CRecordVector<bool>(), CRecordVector<UINT32>()));
+ RINOK(WriteUnPackInfo(false, 0, folders));
+ RINOK(WriteByte2(NID::kEnd));
+ }
+
+ ////////////////////////////////////////////////////
+
+ if (database.Folders.Size() > 0)
+ {
+ RINOK(WriteByte2(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.FileCRCIsDefined);
+ digests.Add(file.FileCRC);
+ }
+
+ RINOK(WriteSubStreamsInfo(
+ database.Folders,
+ database.NumUnPackStreamsVector,
+ unPackSizes,
+ digestsDefined,
+ digests));
+ RINOK(WriteByte2(NID::kEnd));
+ }
+
+ if (database.Files.IsEmpty())
+ {
+ RINOK(WriteByte2(NID::kEnd));
+ return _outByte.Flush();
+ }
+
+ RINOK(WriteByte2(NID::kFilesInfo));
+ RINOK(WriteNumber(database.Files.Size()));
+
+ CBoolVector emptyStreamVector;
+ emptyStreamVector.Reserve(database.Files.Size());
+ UINT64 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(WriteByte2(NID::kEmptyStream));
+ RINOK(WriteNumber((emptyStreamVector.Size() + 7) / 8));
+ RINOK(WriteBoolVector(emptyStreamVector));
+
+ CBoolVector emptyFileVector, antiVector;
+ emptyFileVector.Reserve(numEmptyStreams);
+ antiVector.Reserve(numEmptyStreams);
+ UINT64 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(WriteByte2(NID::kEmptyFile));
+ RINOK(WriteNumber((emptyFileVector.Size() + 7) / 8));
+ RINOK(WriteBoolVector(emptyFileVector));
+ }
+
+ if (numAntiItems > 0)
+ {
+ RINOK(WriteByte2(NID::kAnti));
+ RINOK(WriteNumber((antiVector.Size() + 7) / 8));
+ RINOK(WriteBoolVector(antiVector));
+ }
+ }
+
+ {
+ /////////////////////////////////////////////////
+ RINOK(WriteByte2(NID::kName));
+ if (externalNames)
+ {
+ RINOK(WriteNumber(1 +
+ GetBigNumberSize(externalNamesStreamIndex)));
+ RINOK(WriteByte2(1));
+ RINOK(WriteNumber(externalNamesStreamIndex));
+ }
+ else
+ {
+ RINOK(WriteNumber(1 + namesData.GetCapacity()));
+ RINOK(WriteByte2(0));
+ RINOK(WriteBytes2(namesData));
+ }
+
+ }
+
+ RINOK(WriteTime(database.Files, NID::kCreationTime, false, 0));
+ RINOK(WriteTime(database.Files, NID::kLastAccessTime, false, 0));
+ RINOK(WriteTime(database.Files, NID::kLastWriteTime,
+ // false, 0));
+ externalLastWriteTime, externalLastWriteTimeStreamIndex));
+
+ if (numDefinedAttributes > 0)
+ {
+ /////////////////////////////////////////////////
+ RINOK(WriteByte2(NID::kWinAttributes));
+ UINT32 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(WriteByte2(1));
+ }
+ else
+ {
+ RINOK(WriteByte2(0));
+ RINOK(WriteBoolVector(attributesBoolVector));
+ }
+
+ if (externalAttributes)
+ {
+ RINOK(WriteByte2(1));
+ RINOK(WriteNumber(externalAttributesStreamIndex));
+ }
+ else
+ {
+ RINOK(WriteByte2(0));
+ RINOK(WriteBytes2(attributesData));
+ }
+ }
+
+ RINOK(WriteByte2(NID::kEnd)); // for files
+ RINOK(WriteByte2(NID::kEnd)); // for headers
+
+ return _outByte.Flush();
+}
+
+HRESULT COutArchive::WriteDatabase(const CArchiveDatabase &database,
+ const CCompressionMethodMode *options,
+ bool useAdditionalStreams, bool compressMainHeader)
+{
+ 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 (!useAdditionalStreams)
+ additionalStreamsOptions = 0;
+ /*
+ if (database.Files.Size() < 2)
+ compressMainHeader = false;
+ */
+ if (options != 0)
+ if (options->PasswordIsDefined || compressMainHeader)
+ _dynamicMode = true;
+ RINOK(WriteHeader(database, additionalStreamsOptions, headerOffset));
+
+ if (_dynamicMode)
+ {
+ CCompressionMethodMode encryptOptions;
+ encryptOptions.PasswordIsDefined = options->PasswordIsDefined;
+ encryptOptions.Password = options->Password;
+ CEncoder encoder(compressMainHeader ?
+ *options : encryptOptions);
+ CRecordVector<UINT64> packSizes;
+ CObjectVector<CFolder> folders;
+ RINOK(EncodeStream(encoder, _dynamicBuffer,
+ _dynamicBuffer.GetSize(), packSizes, folders));
+ _dynamicMode = false;
+ _mainMode = true;
+
+ _outByte.Init(Stream);
+ _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(WriteByte2(NID::kEnd));
+ for (int i = 0; i < packSizes.Size(); i++)
+ headerOffset += packSizes[i];
+ RINOK(_outByte.Flush());
+ }
+ headerCRC = _crc.GetDigest();
+ headerSize = _outByte.GetProcessedSize();
+ }
+ RINOK(Stream->Seek(_prefixHeaderPos, STREAM_SEEK_SET, NULL));
+
+ CStartHeader startHeader;
+ startHeader.NextHeaderOffset = headerOffset;
+ startHeader.NextHeaderSize = headerSize;
+ startHeader.NextHeaderCRC = headerCRC;
+
+ UINT32 crc = CCRC::CalculateDigest(&startHeader, sizeof(startHeader));
+ RINOK(WriteBytes(&crc, sizeof(crc)));
+ return WriteBytes(&startHeader, sizeof(startHeader));
+}
+
+}}
diff --git a/7zip/Archive/7z/7zOut.h b/7zip/Archive/7z/7zOut.h
new file mode 100755
index 00000000..1742dd41
--- /dev/null
+++ b/7zip/Archive/7z/7zOut.h
@@ -0,0 +1,154 @@
+// 7z/Out.h
+
+#pragma once
+
+#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;
+ UINT32 _size;
+ UINT32 _pos;
+public:
+ CWriteBufferLoc(): _size(0), _pos(0) {}
+ void Init(BYTE *data, UINT32 size)
+ {
+ _pos = 0;
+ _data = data;
+ _size = size;
+ }
+ HRESULT Write(const void *data, UINT32 size)
+ {
+ if (_pos + size > _size)
+ return E_FAIL;
+ memmove(_data + _pos, data, size);
+ _pos += size;
+ return S_OK;
+ }
+};
+
+class CWriteDynamicBuffer
+{
+ CByteDynamicBuffer _buffer;
+ UINT32 _pos;
+public:
+ CWriteDynamicBuffer(): _pos(0) {}
+ void Init()
+ {
+ _pos = 0;
+ }
+ void Write(const void *data, UINT32 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; };
+ UINT32 GetSize() const { return _pos; }
+};
+
+
+class COutArchive
+{
+ UINT64 _prefixHeaderPos;
+
+ HRESULT WriteBytes(const void *data, UINT32 size);
+ HRESULT WriteBytes2(const void *data, UINT32 size);
+ HRESULT WriteBytes2(const CByteBuffer &data);
+ HRESULT WriteByte2(BYTE b);
+ HRESULT WriteNumber(UINT64 value);
+ HRESULT WriteID(UINT64 value)
+ {
+ return WriteNumber(value);
+ }
+
+ HRESULT WriteFolderHeader(const CFolder &itemInfo);
+ 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,
+ UINT64 externalFoldersStreamIndex,
+ const CObjectVector<CFolder> &folders);
+
+ HRESULT WriteSubStreamsInfo(
+ const CObjectVector<CFolder> &folders,
+ const CRecordVector<UINT64> &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<UINT64> &numUnPackStreamsInFolders,
+ const CRecordVector<UINT64> &unPackSizes,
+ const CRecordVector<bool> &digestsDefined,
+ const CRecordVector<UINT32> &hashDigests);
+
+
+ HRESULT WriteTime(const CObjectVector<CFileItem> &files, BYTE type,
+ bool isExternal, int externalDataIndex);
+
+ HRESULT EncodeStream(CEncoder &encoder, const BYTE *data, UINT32 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,
+ UINT64 &headerOffset);
+
+ bool _mainMode;
+
+ bool _dynamicMode;
+
+ bool _countMode;
+ UINT32 _countSize;
+ COutBuffer _outByte;
+ CWriteBufferLoc _outByte2;
+ CWriteDynamicBuffer _dynamicBuffer;
+ CCRC _crc;
+
+public:
+ CMyComPtr<IOutStream> Stream;
+ HRESULT Create(IOutStream *stream);
+ void Close();
+ HRESULT SkeepPrefixArchiveHeader();
+ HRESULT WriteDatabase(const CArchiveDatabase &database,
+ const CCompressionMethodMode *options,
+ bool useAdditionalHeaderStreams,
+ bool compressMainHeader);
+};
+
+}}
+
+#endif
diff --git a/7zip/Archive/7z/7zProperties.cpp b/7zip/Archive/7z/7zProperties.cpp
new file mode 100755
index 00000000..84363b60
--- /dev/null
+++ b/7zip/Archive/7z/7zProperties.cpp
@@ -0,0 +1,157 @@
+// 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::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();
+ 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(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/7zip/Archive/7z/7zProperties.h b/7zip/Archive/7z/7zProperties.h
new file mode 100755
index 00000000..0b85b5e9
--- /dev/null
+++ b/7zip/Archive/7z/7zProperties.h
@@ -0,0 +1,51 @@
+// 7zProperties.h
+
+#pragma once
+
+#ifndef __7Z_PROPERTIES_H
+#define __7Z_PROPERTIES_H
+
+#include "../../PropID.h"
+
+namespace NArchive {
+namespace N7z {
+
+enum // PropID
+{
+ kpidPackedSize0 = kpidUserDefined,
+ kpidPackedSize1,
+ kpidPackedSize2,
+ kpidPackedSize3,
+ kpidPackedSize4,
+};
+
+/*
+class CEnumArchiveItemProperty:
+ public IEnumSTATPROPSTG,
+ public CComObjectRoot
+{
+ CRecordVector<UINT32> _fileInfoPopIDs;
+ int _index;
+public:
+
+ BEGIN_COM_MAP(CEnumArchiveItemProperty)
+ COM_INTERFACE_ENTRY(IEnumSTATPROPSTG)
+ END_COM_MAP()
+
+ DECLARE_NOT_AGGREGATABLE(CEnumArchiveItemProperty)
+
+ DECLARE_NO_REGISTRY()
+public:
+ CEnumArchiveItemProperty(): _index(0) {};
+ void Init(const CRecordVector<UINT32> &fileInfoPopIDs);
+
+ STDMETHOD(Next) (ULONG numItems, STATPROPSTG *items, ULONG *numFetched);
+ STDMETHOD(Skip) (ULONG numItems);
+ STDMETHOD(Reset) ();
+ STDMETHOD(Clone) (IEnumSTATPROPSTG **enumerator);
+};
+*/
+
+}}
+
+#endif
diff --git a/7zip/Archive/7z/7zSpecStream.cpp b/7zip/Archive/7z/7zSpecStream.cpp
new file mode 100755
index 00000000..4ff7b5c0
--- /dev/null
+++ b/7zip/Archive/7z/7zSpecStream.cpp
@@ -0,0 +1,34 @@
+// 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::ReadPart(void *data, UINT32 size, UINT32 *processedSize)
+{
+ UINT32 realProcessedSize;
+ HRESULT result = _stream->ReadPart(data, size, &realProcessedSize);
+ _size += realProcessedSize;
+ if (processedSize != 0)
+ *processedSize = realProcessedSize;
+ return result;
+}
+
+STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(
+ UINT64 subStream, UINT64 *value)
+{
+ if (_getSubStreamSize == NULL)
+ return E_NOTIMPL;
+ return _getSubStreamSize->GetSubStreamSize(subStream, value);
+}
+
diff --git a/7zip/Archive/7z/7zSpecStream.h b/7zip/Archive/7z/7zSpecStream.h
new file mode 100755
index 00000000..92019fff
--- /dev/null
+++ b/7zip/Archive/7z/7zSpecStream.h
@@ -0,0 +1,38 @@
+// 7zSpecStream.h
+
+#pragma once
+
+#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(ReadPart)(void *data, UINT32 size, UINT32 *processedSize);
+
+ STDMETHOD(GetSubStreamSize)(UINT64 subStream, UINT64 *value);
+};
+
+#endif
diff --git a/7zip/Archive/7z/7zUpdate.cpp b/7zip/Archive/7z/7zUpdate.cpp
new file mode 100755
index 00000000..6633f92f
--- /dev/null
+++ b/7zip/Archive/7z/7zUpdate.cpp
@@ -0,0 +1,737 @@
+// 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;
+const UINT32 kAlgorithmForBCJ2_LZMA = 2;
+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(IInStream *inStream,
+ ISequentialOutStream *outStream,
+ const CUpdateRange &range,
+ IProgress *progress,
+ UINT64 &currentComplexity)
+{
+ UINT64 position;
+ inStream->Seek(range.Position, STREAM_SEEK_SET, &position);
+
+ CLimitedSequentialInStream *streamSpec = new
+ CLimitedSequentialInStream;
+ CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);
+ streamSpec->Init(inStream, range.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 += range.Size;
+ return result;
+}
+
+int CUpdateItem::GetExtensionPos() const
+{
+ int slash1Pos = Name.ReverseFind(L'\\');
+ int slash2Pos = Name.ReverseFind(L'/');
+ int slashPos = MyMax(slash1Pos, slash2Pos);
+ 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)
+{
+ int c1 = a1.GetCapacity();
+ int c2 = a2.GetCapacity();
+ RINOZ(MyCompare(c1, c2));
+ for (int 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 MyStringCollateNoCase(f1.Name, f2.Name);
+}
+
+static int __cdecl CompareFolderRefs(const void *p1, const void *p2)
+{
+ const CFolderRef &a1 = *((const CFolderRef *)p1);
+ const CFolderRef &a2 = *((const CFolderRef *)p2);
+ const CArchiveDatabaseEx &d1 = *a1.Database;
+ const CArchiveDatabaseEx &d2 = *a2.Database;
+ RINOZ(CompareFolders(
+ d1.Folders[a1.FolderIndex],
+ d2.Folders[a2.FolderIndex]));
+ RINOZ(MyCompare(
+ d1.NumUnPackStreamsVector[a1.FolderIndex],
+ d2.NumUnPackStreamsVector[a2.FolderIndex]));
+ if (d1.NumUnPackStreamsVector[a1.FolderIndex] == 0)
+ return 0;
+ return CompareFiles(
+ d1.Files[d1.FolderStartFileIndex[a1.FolderIndex]],
+ d2.Files[d2.FolderStartFileIndex[a2.FolderIndex]]);
+}
+
+////////////////////////////////////////////////////////////
+
+static int __cdecl CompareEmptyItems(const void *p1, const void *p2)
+{
+ const CUpdateItem &u1 = **((CUpdateItem **)p1);
+ const CUpdateItem &u2 = **((CUpdateItem **)p2);
+ if (u1.IsDirectory != u2.IsDirectory)
+ {
+ if (u1.IsDirectory)
+ return u1.IsAnti ? 1: -1;
+ return u2.IsAnti ? -1: 1;
+ }
+ if (u1.IsDirectory)
+ {
+ if (u1.IsAnti != u2.IsAnti)
+ return (u1.IsAnti ? 1 : -1);
+ int n = MyStringCollateNoCase(u1.Name, u2.Name);
+ return (u1.IsAnti ? (-n) : n);
+ }
+ if (u1.IsAnti != u2.IsAnti)
+ return (u1.IsAnti ? 1 : -1);
+ return MyStringCollateNoCase(u1.Name, u2.Name);
+}
+
+struct CRefItem
+{
+ UINT32 Index;
+ const CUpdateItem *UpdateItem;
+ UINT32 ExtensionPos;
+ UINT32 NamePos;
+ bool SortByType;
+ CRefItem(UINT32 index, const CUpdateItem &updateItem, bool sortByType):
+ SortByType(sortByType),
+ Index(index),
+ UpdateItem(&updateItem),
+ ExtensionPos(0),
+ NamePos(0)
+ {
+ if (sortByType)
+ {
+ int slash1Pos = updateItem.Name.ReverseFind(L'\\');
+ int slash2Pos = updateItem.Name.ReverseFind(L'/');
+ int slashPos = MyMax(slash1Pos, slash2Pos);
+ if (slashPos >= 0)
+ NamePos = slashPos + 1;
+ else
+ NamePos = 0;
+ int dotPos = updateItem.Name.ReverseFind(L'.');
+ if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0))
+ ExtensionPos = updateItem.Name.Length();
+ else
+ ExtensionPos = dotPos + 1;
+ }
+ }
+};
+
+static int __cdecl CompareUpdateItems(const void *p1, const void *p2)
+{
+ const CRefItem &a1 = *((CRefItem *)p1);
+ const CRefItem &a2 = *((CRefItem *)p2);
+ const CUpdateItem &u1 = *a1.UpdateItem;
+ const CUpdateItem &u2 = *a2.UpdateItem;
+ int n;
+ if (u1.IsDirectory != u2.IsDirectory)
+ {
+ if (u1.IsDirectory)
+ return u1.IsAnti ? 1: -1;
+ return u2.IsAnti ? -1: 1;
+ }
+ if (u1.IsDirectory)
+ {
+ if (u1.IsAnti != u2.IsAnti)
+ return (u1.IsAnti ? 1 : -1);
+ n = MyStringCollateNoCase(u1.Name, u2.Name);
+ return (u1.IsAnti ? (-n) : n);
+ }
+ if (a1.SortByType)
+ {
+ RINOZ(MyStringCollateNoCase(u1.Name + a1.ExtensionPos, u2.Name + a2.ExtensionPos));
+ RINOZ(MyStringCollateNoCase(u1.Name + a1.NamePos, u2.Name + a2.NamePos));
+ if (u1.LastWriteTimeIsDefined && u2.LastWriteTimeIsDefined)
+ RINOZ(CompareFileTime(&u1.LastWriteTime, &u2.LastWriteTime));
+ RINOZ(MyCompare(u1.Size, u2.Size))
+ }
+ return MyStringCollateNoCase(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.CreationTimeIsDefined)
+ // file.SetCreationTime(updateItem.ItemInfo.CreationTime);
+
+ if (updateItem.LastWriteTimeIsDefined)
+ file.SetLastWriteTime(updateItem.LastWriteTime);
+
+ file.UnPackSize = updateItem.Size;
+ file.IsDirectory = updateItem.IsDirectory;
+ file.IsAnti = updateItem.IsAnti;
+ file.HasStream = updateItem.HasStream();
+}
+
+HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
+ CObjectVector<CUpdateItem> &updateItems,
+ IOutStream *outStream,
+ IInStream *inStream,
+ NArchive::N7z::CInArchiveInfo *inArchiveInfo,
+ const CCompressionMethodMode &method,
+ const CCompressionMethodMode *headerMethod,
+ bool useFilters,
+ bool maxFilter,
+ bool useAdditionalHeaderStreams,
+ bool compressMainHeader,
+ IArchiveUpdateCallback *updateCallback,
+ UINT64 numSolidFiles, UINT64 numSolidBytes, bool solidExtension,
+ bool removeSfxBlock)
+{
+ if (numSolidFiles == 0)
+ numSolidFiles = 1;
+
+ UINT64 startBlockSize = inArchiveInfo != 0 ?
+ inArchiveInfo->StartPosition: 0;
+ if (startBlockSize > 0 && !removeSfxBlock)
+ {
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+ CMyComPtr<ISequentialInStream> limitedStream(streamSpec);
+ RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
+ streamSpec->Init(inStream, startBlockSize);
+ RINOK(CopyBlock(limitedStream, outStream, NULL));
+ }
+
+ CRecordVector<int> fileIndexToUpdateIndexMap;
+ fileIndexToUpdateIndexMap.Reserve(database.Files.Size());
+ int i;
+ for (i = 0; i < database.Files.Size(); i++)
+ fileIndexToUpdateIndexMap.Add(-1);
+ for(i = 0; i < updateItems.Size(); i++)
+ {
+ int index = updateItems[i].IndexInArchive;
+ if (index != -1)
+ fileIndexToUpdateIndexMap[index] = i;
+ }
+
+ CRecordVector<CFolderRef> folderRefs;
+ for(i = 0; i < database.Folders.Size(); i++)
+ {
+ UINT64 indexInFolder = 0;
+ UINT64 numCopyItems = 0;
+ UINT64 numUnPackStreams = database.NumUnPackStreamsVector[i];
+ for (int 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)
+ {
+ CFolderRef folderRef;
+ folderRef.Database = &database;
+ folderRef.FolderIndex = i;
+ folderRefs.Add(folderRef);
+ }
+ }
+ qsort(&folderRefs.Front(), folderRefs.Size(), sizeof(folderRefs[0]),
+ CompareFolderRefs);
+
+ CArchiveDatabase newDatabase;
+
+ /////////////////////////////////////////
+ // Write Empty Files & Folders
+
+ CRecordVector<const CUpdateItem *> 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(&updateItem);
+ }
+ qsort(&emptyRefs.Front(), emptyRefs.Size(), sizeof(emptyRefs[0]),
+ CompareEmptyItems);
+ for(i = 0; i < emptyRefs.Size(); i++)
+ {
+ const CUpdateItem &updateItem = *emptyRefs[i];
+ CFileItem file;
+ if (updateItem.NewProperties)
+ FromUpdateItemToFileItem(updateItem, file);
+ else
+ file = database.Files[updateItem.IndexInArchive];
+ newDatabase.Files.Add(file);
+ }
+
+ ////////////////////////////
+
+ COutArchive archive;
+ archive.Create(outStream);
+ RINOK(archive.SkeepPrefixArchiveHeader());
+ UINT64 complexity = 0;
+ for(i = 0; i < folderRefs.Size(); i++)
+ complexity += database.GetFolderFullPackSize(folderRefs[i].FolderIndex);
+ for(i = 0; i < updateItems.Size(); i++)
+ {
+ const CUpdateItem &updateItem = updateItems[i];
+ if (updateItem.NewData)
+ complexity += 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].FolderIndex;
+
+ RINOK(WriteRange(inStream, archive.Stream,
+ CUpdateRange(database.GetFolderStreamPos(folderIndex, 0),
+ database.GetFolderFullPackSize(folderIndex)),
+ updateCallback, complexity));
+
+ const CFolder &folder = database.Folders[folderIndex];
+ UINT32 startIndex = database.FolderStartPackStreamIndex[folderIndex];
+ int j;
+ for (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);
+
+ UINT64 numUnPackStreams = database.NumUnPackStreamsVector[folderIndex];
+ newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
+
+ UINT64 indexInFolder = 0;
+ for (j = database.FolderStartFileIndex[folderIndex];
+ indexInFolder < numUnPackStreams; j++)
+ {
+ CFileItem file = database.Files[j];
+ if (file.HasStream)
+ {
+ indexInFolder++;
+ int updateIndex = fileIndexToUpdateIndexMap[j];
+ 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.FileCRCIsDefined = file.FileCRCIsDefined;
+ file2.HasStream = file.HasStream;
+ file = file2;
+ }
+ }
+ newDatabase.Files.Add(file);
+ }
+ }
+ }
+
+ /////////////////////////////////////////
+ // Compress New Files
+
+ CObjectVector<CSolidGroup> groups;
+ SplitFilesToGroups(method, useFilters, maxFilter, updateItems, groups);
+
+ 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);
+ for (i = 0; i < numFiles; i++)
+ refItems.Add(CRefItem(group.Indices[i],
+ updateItems[group.Indices[i]], numSolidFiles > 1));
+ qsort(&refItems.Front(), refItems.Size(), sizeof(refItems[0]), CompareUpdateItems);
+
+ CRecordVector<UINT32> indices;
+ indices.Reserve(numFiles);
+
+ int startFileIndexInDatabase = newDatabase.Files.Size();
+ 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 > numSolidBytes)
+ break;
+ if (solidExtension)
+ {
+ UString ext = updateItem.GetExtension();
+ if (numSubFiles == 0)
+ prevExtension = ext;
+ else
+ if (ext.CollateNoCase(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, folderItem,
+ archive.Stream, newDatabase.PackSizes, compressProgress));
+ // for()
+ // newDatabase.PackCRCsDefined.Add(false);
+ // newDatabase.PackCRCs.Add(0);
+
+ newDatabase.Folders.Add(folderItem);
+
+ UINT32 numUnPackStreams = 0;
+ for (int subIndex = 0; subIndex < numSubFiles; subIndex++)
+ {
+ CFileItem &file = newDatabase.Files[
+ startFileIndexInDatabase + i + subIndex];
+ file.FileCRC = inStreamSpec->CRCs[subIndex];
+ file.UnPackSize = inStreamSpec->Sizes[subIndex];
+ if (file.UnPackSize != 0)
+ {
+ file.FileCRCIsDefined = true;
+ file.HasStream = true;
+ numUnPackStreams++;
+ complexity += file.UnPackSize;
+ }
+ else
+ {
+ file.FileCRCIsDefined = false;
+ file.HasStream = false;
+ }
+ }
+ newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
+ i += numSubFiles;
+ }
+ }
+ if (newDatabase.Files.Size() != updateItems.Size())
+ return E_FAIL;
+
+ return archive.WriteDatabase(newDatabase, headerMethod,
+ useAdditionalHeaderStreams, compressMainHeader);
+}
+
+}}
diff --git a/7zip/Archive/7z/7zUpdate.h b/7zip/Archive/7z/7zUpdate.h
new file mode 100755
index 00000000..d4561559
--- /dev/null
+++ b/7zip/Archive/7z/7zUpdate.h
@@ -0,0 +1,72 @@
+// 7zUpdate.h
+
+#pragma once
+
+#ifndef __7Z_UPDATE_H
+#define __7Z_UPDATE_H
+
+#include "7zIn.h"
+#include "7zCompressionMode.h"
+
+#include "../IArchive.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CUpdateRange
+{
+ UINT64 Position;
+ UINT64 Size;
+ CUpdateRange() {};
+ CUpdateRange(UINT64 position, UINT64 size): Position(position), Size(size) {};
+};
+
+struct CUpdateItem
+{
+ bool NewData;
+ bool NewProperties;
+ int IndexInArchive;
+ int IndexInClient;
+
+ UINT32 Attributes;
+ FILETIME CreationTime;
+ FILETIME LastWriteTime;
+
+ UINT64 Size;
+ UString Name;
+
+ bool IsAnti;
+ bool IsDirectory;
+
+ bool CreationTimeIsDefined;
+ bool LastWriteTimeIsDefined;
+ bool AttributesAreDefined;
+
+ const bool HasStream() const
+ { return !IsDirectory && !IsAnti && Size != 0; }
+ CUpdateItem(): IsAnti(false) {}
+ void SetDirectoryStatusFromAttributes()
+ { IsDirectory = ((Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); };
+
+ int GetExtensionPos() const;
+ UString GetExtension() const;
+};
+
+HRESULT Update(const NArchive::N7z::CArchiveDatabaseEx &database,
+ CObjectVector<CUpdateItem> &updateItems,
+ IOutStream *outStream,
+ IInStream *inStream,
+ CInArchiveInfo *inArchiveInfo,
+ const CCompressionMethodMode &method,
+ const CCompressionMethodMode *headerMethod,
+ bool useFilters,
+ bool maxFilter,
+ bool useAdditionalHeaderStreams,
+ bool compressMainHeader,
+ IArchiveUpdateCallback *updateCallback,
+ UINT64 numSolidFiles, UINT64 numSolidBytes, bool solidExtension,
+ bool removeSfxBlock);
+
+}}
+
+#endif
diff --git a/7zip/Archive/7z/DllExports.cpp b/7zip/Archive/7z/DllExports.cpp
new file mode 100755
index 00000000..881443a9
--- /dev/null
+++ b/7zip/Archive/7z/DllExports.cpp
@@ -0,0 +1,90 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include <initguid.h>
+
+#include "7zHandler.h"
+#include "../../ICoder.h"
+#include "../../IPassword.h"
+#include "../../../Common/NewHandler.h"
+#include "../../../Common/ComTry.h"
+
+#ifndef EXCLUDE_COM
+// {23170F69-40C1-278B-06F1-070100000100}
+DEFINE_GUID(CLSID_CCrypto7zAESEncoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x07, 0x01, 0x00, 0x00, 0x01, 0x00);
+#else
+#include "../../Compress/LZ/IMatchFinder.h"
+#endif
+
+HINSTANCE g_hInstance;
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ g_hInstance = hInstance;
+ 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;
+ int needIn = *interfaceID == IID_IInArchive;
+ int needOut = *interfaceID == IID_IOutArchive;
+ if (needIn || needOut)
+ {
+ NArchive::N7z::CHandler *temp = new NArchive::N7z::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"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;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/7zip/Archive/7z/StdAfx.cpp b/7zip/Archive/7z/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Archive/7z/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Archive/7z/StdAfx.h b/7zip/Archive/7z/StdAfx.h
new file mode 100755
index 00000000..32888020
--- /dev/null
+++ b/7zip/Archive/7z/StdAfx.h
@@ -0,0 +1,23 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+/*
+#include <stdio.h>
+#include <tchar.h>
+#include <atlcom.h>
+#include <shlobj.h>
+#include <shlguid.h>
+
+#include <memory>
+#include <new.h>
+
+#include <time.h>
+*/
+#include <vector>
+#include <memory>
+
+#endif
diff --git a/7zip/Archive/7z/resource.h b/7zip/Archive/7z/resource.h
new file mode 100755
index 00000000..7b0dd8ff
--- /dev/null
+++ b/7zip/Archive/7z/resource.h
@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDI_ICON1 101
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Archive/7z/resource.rc b/7zip/Archive/7z/resource.rc
new file mode 100755
index 00000000..2317ad53
--- /dev/null
+++ b/7zip/Archive/7z/resource.rc
@@ -0,0 +1,130 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1 ICON DISCARDABLE "7z.ico"
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,12,0,0
+ PRODUCTVERSION 3,12,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "7z Plugin for 7-Zip\0"
+ VALUE "FileVersion", "3, 12, 0, 0\0"
+ VALUE "InternalName", "7z\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "7z.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 12, 0, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Archive/Arj/Arj.def b/7zip/Archive/Arj/Arj.def
new file mode 100755
index 00000000..e240b3f2
--- /dev/null
+++ b/7zip/Archive/Arj/Arj.def
@@ -0,0 +1,7 @@
+; Arj.def
+
+LIBRARY Arj.dll
+
+EXPORTS
+ CreateObject PRIVATE
+ GetHandlerProperty PRIVATE
diff --git a/7zip/Archive/Arj/Arj.dsp b/7zip/Archive/Arj/Arj.dsp
new file mode 100755
index 00000000..d6365185
--- /dev/null
+++ b/7zip/Archive/Arj/Arj.dsp
@@ -0,0 +1,309 @@
+# 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=.\arj.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\DllExports.cpp
+# 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
+# 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\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 "Compression"
+
+# PROP Default_Filter ""
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Group "Codecs"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Arj\Decoder1.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Arj\Decoder1.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Arj\Decoder2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Arj\Decoder2.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\ProgressUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.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/7zip/Archive/Arj/Arj.dsw b/7zip/Archive/Arj/Arj.dsw
new file mode 100755
index 00000000..7ce4bca5
--- /dev/null
+++ b/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/7zip/Archive/Arj/ArjHandler.cpp b/7zip/Archive/Arj/ArjHandler.cpp
new file mode 100755
index 00000000..2a5718b1
--- /dev/null
+++ b/7zip/Archive/Arj/ArjHandler.cpp
@@ -0,0 +1,482 @@
+// 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/Decoder1.h"
+#include "../../Compress/Arj/Decoder2.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
+{
+ 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
+ {
+ _items.Clear();
+ CInArchive archive;
+ if(!archive.Open(inStream, maxCheckStartPosition))
+ return S_FALSE;
+ if (openArchiveCallback != NULL)
+ {
+ RINOK(openArchiveCallback->SetTotal(NULL, NULL));
+ UINT64 numFiles = _items.Size();
+ RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
+ }
+ while(true)
+ {
+ 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 (openArchiveCallback != NULL)
+ {
+ UINT64 numFiles = _items.Size();
+ RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
+ }
+ }
+ _stream = inStream;
+ }
+ catch(...)
+ {
+ return S_FALSE;
+ }
+ COM_TRY_END
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ _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->Init(realOutStream);
+ realOutStream.Release();
+
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+ CMyComPtr<ISequentialInStream> inStream(streamSpec);
+
+ UINT64 pos;
+ _stream->Seek(itemInfo.DataPosition, STREAM_SEEK_SET, &pos);
+
+ streamSpec->Init(_stream, 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/7zip/Archive/Arj/ArjHandler.h b/7zip/Archive/Arj/ArjHandler.h
new file mode 100755
index 00000000..a449fd95
--- /dev/null
+++ b/7zip/Archive/Arj/ArjHandler.h
@@ -0,0 +1,49 @@
+// ArjHandler.h
+
+#pragma once
+
+#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 *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);
+
+ CHandler();
+private:
+ CObjectVector<CItemEx> _items;
+ CMyComPtr<IInStream> _stream;
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/7zip/Archive/Arj/ArjHeader.h b/7zip/Archive/Arj/ArjHeader.h
new file mode 100755
index 00000000..3537246c
--- /dev/null
+++ b/7zip/Archive/Arj/ArjHeader.h
@@ -0,0 +1,124 @@
+// Archive/Arj/Header.h
+
+#pragma once
+
+#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;
+}
+
+#pragma pack( push, Pragma_Arj_Headers)
+#pragma pack( push, 1)
+
+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
+ };
+ }
+}
+
+#pragma pack(pop)
+#pragma pack(pop, Pragma_Arj_Headers)
+
+}}
+
+#endif
diff --git a/7zip/Archive/Arj/ArjIn.cpp b/7zip/Archive/Arj/ArjIn.cpp
new file mode 100755
index 00000000..49a6b3f4
--- /dev/null
+++ b/7zip/Archive/Arj/ArjIn.cpp
@@ -0,0 +1,221 @@
+// Archive/arj/InEngine.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StringConvert.h"
+#include "Common/Buffer.h"
+#include "Common/CRC.h"
+
+#include "Windows/Defs.h"
+
+#include "ArjIn.h"
+
+namespace NArchive {
+namespace NArj {
+
+CInArchiveException::CInArchiveException(CCauseType cause):
+ Cause(cause)
+{}
+
+HRESULT CInArchive::ReadBytes(void *data, UINT32 size, UINT32 *processedSize)
+{
+ UINT32 realProcessedSize;
+ HRESULT result = _stream->Read(data, size, &realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ IncreasePositionValue(realProcessedSize);
+ return result;
+}
+
+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 = *((const UINT16 *)(block + 2));
+ if (maxSize < 2 + 2 + blockSize + 4)
+ return false;
+ block += 4;
+ if (blockSize == 0 || blockSize > 2600)
+ return false;
+ UINT32 crcFromFile = *(const UINT32 *)(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 + sizeof(UINT32);
+
+ CByteBuffer byteBuffer;
+ static const UINT32 kSearchMarkerBufferSize = 0x10000;
+ byteBuffer.SetCapacity(kSearchMarkerBufferSize);
+ BYTE *buffer = byteBuffer;
+
+ UINT32 processedSize;
+ ReadBytes(buffer, 2 + 2 + kMaxBlockSize + sizeof(UINT32), &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;
+ while(true)
+ {
+ 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);
+}
+
+bool CInArchive::ReadBlock()
+{
+ SafeReadBytes(&_blockSize, sizeof(_blockSize));
+ if (_blockSize == 0)
+ return false;
+ SafeReadBytes(_block, _blockSize);
+ UINT32 crcFromFile;
+ ReadBytesAndTestSize(&crcFromFile, sizeof(crcFromFile));
+ 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;
+ while(true)
+ if (!ReadBlock())
+ break;
+ return true;
+}
+
+void CInArchive::Close()
+{
+ _stream.Release();
+}
+
+void CInArchive::ThrowIncorrectArchiveException()
+{
+ throw CInArchiveException(CInArchiveException::kIncorrectArchive);
+}
+
+HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
+{
+ filled = false;
+ if (!ReadBlock2())
+ return S_OK;
+
+ const NFileHeader::CHeader &header = *(const NFileHeader::CHeader *)_block;
+
+ item.Version = header.Version;
+ item.ExtractVersion = header.ExtractVersion;
+ item.HostOS = header.HostOS;
+ item.Flags = header.Flags;
+ item.Method = header.Method;
+ item.FileType = header.FileType;
+ item.ModifiedTime = header.ModifiedTime;
+ item.PackSize = header.PackSize;
+ item.Size = header.Size;
+ item.FileCRC = header.FileCRC;
+ item.FileAccessMode = header.FileAccessMode;
+
+ /*
+ UINT32 extraData;
+ if ((header.Flags & NFileHeader::NFlags::kExtFile) != 0)
+ extraData = *(const UINT32 *)(_block + pos);
+ */
+ int pos = header.FirstHeaderSize;
+
+ for (; pos < _blockSize; pos++)
+ {
+ char aByte = _block[pos];
+ if (aByte == 0)
+ break;
+ item.Name += aByte;
+ }
+
+ while(true)
+ if (!ReadBlock())
+ break;
+
+ item.DataPosition = _position;
+
+ filled = true;
+ return S_OK;
+}
+
+}}
diff --git a/7zip/Archive/Arj/ArjIn.h b/7zip/Archive/Arj/ArjIn.h
new file mode 100755
index 00000000..cdf495e8
--- /dev/null
+++ b/7zip/Archive/Arj/ArjIn.h
@@ -0,0 +1,70 @@
+// Archive/ArjIn.h
+
+#pragma once
+
+#ifndef __ARCHIVE_ARJIN_H
+#define __ARCHIVE_ARJIN_H
+
+#include "Common/Exception.h"
+#include "Common/MyCom.h"
+#include "../../IStream.h"
+
+#include "Header.h"
+#include "ArjItem.h"
+
+namespace NArchive {
+namespace NArj {
+
+class CInArchiveException
+{
+public:
+ enum CCauseType
+ {
+ kUnexpectedEndOfArchive = 0,
+ kCRCError,
+ kIncorrectArchive,
+ kReadStreamError,
+ kSeekStreamError
+ }
+ Cause;
+ CInArchiveException(CCauseType cause);
+};
+
+class CProgressVirt
+{
+public:
+ STDMETHOD(SetCompleted)(const UINT64 *numFiles) PURE;
+};
+
+class CInArchive
+{
+ CMyComPtr<IInStream> _stream;
+ UINT64 _streamStartPosition;
+ UINT64 _position;
+ UINT16 _blockSize;
+ BYTE _block[kMaxBlockSize];
+
+ bool FindAndReadMarker(const UINT64 *searchHeaderSizeLimit);
+
+ bool ReadBlock();
+ bool ReadBlock2();
+
+ HRESULT ReadBytes(void *data, UINT32 size, UINT32 *processedSize);
+ bool ReadBytesAndTestSize(void *data, UINT32 size);
+ void SafeReadBytes(void *data, UINT32 size);
+
+ 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/7zip/Archive/Arj/ArjItem.h b/7zip/Archive/Arj/ArjItem.h
new file mode 100755
index 00000000..a1d0786c
--- /dev/null
+++ b/7zip/Archive/Arj/ArjItem.h
@@ -0,0 +1,77 @@
+// Archive/Arj/ItemInfo.h
+
+#pragma once
+
+#ifndef __ARCHIVE_ARJ_ITEMINFO_H
+#define __ARCHIVE_ARJ_ITEMINFO_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
+ {
+ DWORD 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/7zip/Archive/Arj/DllExports.cpp b/7zip/Archive/Arj/DllExports.cpp
new file mode 100755
index 00000000..8845ce06
--- /dev/null
+++ b/7zip/Archive/Arj/DllExports.cpp
@@ -0,0 +1,69 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include <initguid.h>
+
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+#include "../../ICoder.h"
+#include "ArjHandler.h"
+
+// {23170F69-40C1-278A-1000-0001100A0000}
+DEFINE_GUID(CLSID_CArjHandler,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x0A, 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::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/7zip/Archive/Arj/StdAfx.cpp b/7zip/Archive/Arj/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Archive/Arj/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Archive/Arj/StdAfx.h b/7zip/Archive/Arj/StdAfx.h
new file mode 100755
index 00000000..47001ee8
--- /dev/null
+++ b/7zip/Archive/Arj/StdAfx.h
@@ -0,0 +1,9 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+#include <limits.h>
+
+#endif
diff --git a/7zip/Archive/Arj/arj.ico b/7zip/Archive/Arj/arj.ico
new file mode 100755
index 00000000..c0f8b141
--- /dev/null
+++ b/7zip/Archive/Arj/arj.ico
Binary files differ
diff --git a/7zip/Archive/Arj/resource.h b/7zip/Archive/Arj/resource.h
new file mode 100755
index 00000000..7b0dd8ff
--- /dev/null
+++ b/7zip/Archive/Arj/resource.h
@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDI_ICON1 101
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Archive/Arj/resource.rc b/7zip/Archive/Arj/resource.rc
new file mode 100755
index 00000000..b90eaf91
--- /dev/null
+++ b/7zip/Archive/Arj/resource.rc
@@ -0,0 +1,130 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1 ICON DISCARDABLE "arj.ico"
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,9,2,0
+ PRODUCTVERSION 3,9,2,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "Arj Plugin for 7-Zip\0"
+ VALUE "FileVersion", "3, 9, 2, 0\0"
+ VALUE "InternalName", "arj\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "arj.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 9, 2, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Archive/BZip2/BZip2.def b/7zip/Archive/BZip2/BZip2.def
new file mode 100755
index 00000000..7bd6455e
--- /dev/null
+++ b/7zip/Archive/BZip2/BZip2.def
@@ -0,0 +1,8 @@
+; BZip2.def
+
+LIBRARY bz2.dll
+
+EXPORTS
+ CreateObject PRIVATE
+ GetHandlerProperty PRIVATE
+
diff --git a/7zip/Archive/BZip2/BZip2.dsp b/7zip/Archive/BZip2/BZip2.dsp
new file mode 100755
index 00000000..c56ce1d6
--- /dev/null
+++ b/7zip/Archive/BZip2/BZip2.dsp
@@ -0,0 +1,241 @@
+# 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 "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\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 "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\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=.\BZip2.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.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 "Common"
+
+# PROP Default_Filter ""
+# 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\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\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=.\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
+# End Group
+# Begin Source File
+
+SOURCE=.\bz2.ico
+# End Source File
+# End Target
+# End Project
diff --git a/7zip/Archive/BZip2/BZip2.dsw b/7zip/Archive/BZip2/BZip2.dsw
new file mode 100755
index 00000000..697e5095
--- /dev/null
+++ b/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/7zip/Archive/BZip2/BZip2Handler.cpp b/7zip/Archive/BZip2/BZip2Handler.cpp
new file mode 100755
index 00000000..455add19
--- /dev/null
+++ b/7zip/Archive/BZip2/BZip2Handler.cpp
@@ -0,0 +1,215 @@
+// BZip2Handler.cpp
+
+#include "StdAfx.h"
+
+#include "BZip2Handler.h"
+
+#include "Common/Defs.h"
+
+#include "../../Common/ProgressUtils.h"
+// #include "Interface/EnumStatProp.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(stream->Read(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;
+
+ 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, STREAM_SEEK_SET, NULL));
+
+ #ifndef COMPRESS_BZIP2
+ CCoderLibrary lib;
+ #endif
+ CMyComPtr<ICompressCoder> decoder;
+ #ifdef COMPRESS_BZIP2
+ decoder = new NCompress::NBZip2::CDecoder;
+ #else
+ RINOK(lib.LoadAndCreateCoder(
+ GetBZip2CodecPath(),
+ CLSID_CCompressBZip2Decoder, &decoder));
+ #endif
+
+ HRESULT result = decoder->Code(_stream, outStream, NULL, NULL, progress);
+ outStream.Release();
+ if (result == S_FALSE)
+ RINOK(extractCallback->SetOperationResult(
+ NArchive::NExtract::NOperationResult::kDataError))
+ else if (result == S_OK)
+ RINOK(extractCallback->SetOperationResult(
+ NArchive::NExtract::NOperationResult::kOK))
+ else
+ return result;
+
+ return S_OK;
+ COM_TRY_END
+}
+
+}}
diff --git a/7zip/Archive/BZip2/BZip2Handler.h b/7zip/Archive/BZip2/BZip2Handler.h
new file mode 100755
index 00000000..0859fd44
--- /dev/null
+++ b/7zip/Archive/BZip2/BZip2Handler.h
@@ -0,0 +1,61 @@
+// BZip2/Handler.h
+
+#pragma once
+
+#ifndef __BZIP2_HANDLER_H
+#define __BZIP2_HANDLER_H
+
+#include "Common/MyCom.h"
+#include "../IArchive.h"
+#include "BZip2Item.h"
+
+namespace NArchive {
+namespace NBZip2 {
+
+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);
+
+
+ // IOutArchiveHandler
+
+ STDMETHOD(UpdateItems)(IOutStream *outStream, UINT32 numItems,
+ IArchiveUpdateCallback *updateCallback);
+
+ STDMETHOD(GetFileTimeType)(UINT32 *type);
+
+private:
+ CMyComPtr<IInStream> _stream;
+ NArchive::NBZip2::CItem _item;
+ UINT64 _streamStartPosition;
+};
+
+}}
+
+#endif
diff --git a/7zip/Archive/BZip2/BZip2HandlerOut.cpp b/7zip/Archive/BZip2/BZip2HandlerOut.cpp
new file mode 100755
index 00000000..d1703e86
--- /dev/null
+++ b/7zip/Archive/BZip2/BZip2HandlerOut.cpp
@@ -0,0 +1,92 @@
+// BZip2/OutHandler.cpp
+
+#include "StdAfx.h"
+
+#include "BZip2Handler.h"
+#include "BZip2Update.h"
+
+#include "Windows/FileFind.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+
+#include "../../Compress/Copy/CopyCoder.h"
+
+using namespace NWindows;
+
+static const int kNumItemInArchive = 1;
+
+namespace NArchive {
+namespace NBZip2 {
+
+STDMETHODIMP CHandler::GetFileTimeType(UINT32 *type)
+{
+ *type = NFileTimeType::kUnix;
+ return S_OK;
+}
+
+static HRESULT CopyStreams(IInStream *inStream, IOutStream *outStream,
+ IArchiveUpdateCallback *updateCallback)
+{
+ CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
+ return copyCoder->Code(inStream, outStream, NULL, NULL, NULL);
+}
+
+STDMETHODIMP CHandler::UpdateItems(IOutStream *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, kpidAttributes, &propVariant));
+ if (propVariant.vt == VT_UI4)
+ {
+ if (NFile::NFind::NAttributes::IsDirectory(propVariant.ulVal))
+ return E_INVALIDARG;
+ }
+ else if (propVariant.vt != VT_EMPTY)
+ return E_INVALIDARG;
+ }
+ {
+ 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 = *(UINT64 *)(&propVariant.uhVal);
+ }
+ return UpdateArchive(size, outStream, 0, updateCallback);
+ }
+ if (indexInArchive != 0)
+ return E_INVALIDARG;
+ RINOK(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL));
+ return CopyStreams(_stream, outStream, updateCallback);
+}
+
+}}
diff --git a/7zip/Archive/BZip2/BZip2Item.h b/7zip/Archive/BZip2/BZip2Item.h
new file mode 100755
index 00000000..604adee8
--- /dev/null
+++ b/7zip/Archive/BZip2/BZip2Item.h
@@ -0,0 +1,22 @@
+// Archive/BZip2Item.h
+
+#pragma once
+
+#ifndef __ARCHIVE_BZIP2_ITEM_H
+#define __ARCHIVE_BZIP2_ITEM_H
+
+namespace NArchive {
+namespace NBZip2 {
+
+struct CItem
+{
+ UINT64 PackSize;
+ UINT64 UnPackSize;
+};
+
+}}
+
+#endif
+
+
+
diff --git a/7zip/Archive/BZip2/BZip2Update.cpp b/7zip/Archive/BZip2/BZip2Update.cpp
new file mode 100755
index 00000000..908140e5
--- /dev/null
+++ b/7zip/Archive/BZip2/BZip2Update.cpp
@@ -0,0 +1,58 @@
+// BZip2Update.cpp
+
+#include "StdAfx.h"
+
+#include "Common/Defs.h"
+#include "Windows/Defs.h"
+#include "../../Common/ProgressUtils.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,
+ IOutStream *outStream,
+ int indexInClient,
+ IArchiveUpdateCallback *updateCallback)
+{
+ RINOK(updateCallback->SetTotal(unpackSize));
+
+ UINT64 complexity = 0;
+ RINOK(updateCallback->SetCompleted(&complexity));
+
+ CMyComPtr<IInStream> 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
+
+ RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, localProgress));
+
+ return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
+}
+
+}}
diff --git a/7zip/Archive/BZip2/BZip2Update.h b/7zip/Archive/BZip2/BZip2Update.h
new file mode 100755
index 00000000..2ccdf492
--- /dev/null
+++ b/7zip/Archive/BZip2/BZip2Update.h
@@ -0,0 +1,23 @@
+// BZip2Update.h
+
+#pragma once
+
+#ifndef __BZIP2_UPDATE_H
+#define __BZIP2_UPDATE_H
+
+#include "Common/Types.h"
+
+#include "../IArchive.h"
+
+namespace NArchive {
+namespace NBZip2 {
+
+HRESULT UpdateArchive(
+ UINT64 unpackSize,
+ IOutStream *outStream,
+ int indexInClient,
+ IArchiveUpdateCallback *updateCallback);
+
+}}
+
+#endif
diff --git a/7zip/Archive/BZip2/DllExports.cpp b/7zip/Archive/BZip2/DllExports.cpp
new file mode 100755
index 00000000..7a63ddfb
--- /dev/null
+++ b/7zip/Archive/BZip2/DllExports.cpp
@@ -0,0 +1,105 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#define INITGUID
+
+#include "Common/ComTry.h"
+#include "Common/String.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-000110070000}
+DEFINE_GUID(CLSID_CBZip2Handler,
+0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);
+
+HINSTANCE g_hInstance;
+
+#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;
+ 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 tbz2";
+ break;
+ case NArchive::kAddExtension:
+ propVariant = L"* .tar";
+ break;
+ case NArchive::kUpdate:
+ propVariant = true;
+ break;
+ case NArchive::kKeepName:
+ propVariant = true;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/7zip/Archive/BZip2/StdAfx.cpp b/7zip/Archive/BZip2/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Archive/BZip2/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Archive/BZip2/StdAfx.h b/7zip/Archive/BZip2/StdAfx.h
new file mode 100755
index 00000000..a32fbed6
--- /dev/null
+++ b/7zip/Archive/BZip2/StdAfx.h
@@ -0,0 +1,8 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#endif
diff --git a/7zip/Archive/BZip2/bz2.ico b/7zip/Archive/BZip2/bz2.ico
new file mode 100755
index 00000000..614e3540
--- /dev/null
+++ b/7zip/Archive/BZip2/bz2.ico
Binary files differ
diff --git a/7zip/Archive/BZip2/resource.h b/7zip/Archive/BZip2/resource.h
new file mode 100755
index 00000000..7b0dd8ff
--- /dev/null
+++ b/7zip/Archive/BZip2/resource.h
@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDI_ICON1 101
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Archive/BZip2/resource.rc b/7zip/Archive/BZip2/resource.rc
new file mode 100755
index 00000000..3dba3fe0
--- /dev/null
+++ b/7zip/Archive/BZip2/resource.rc
@@ -0,0 +1,130 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1 ICON DISCARDABLE "bz2.ico"
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,12,0,0
+ PRODUCTVERSION 3,12,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "BZip2 Plugin for 7-Zip\0"
+ VALUE "FileVersion", "3, 12, 0, 0\0"
+ VALUE "InternalName", "bz2\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "bz.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 12, 0, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Archive/Cab/Cab.def b/7zip/Archive/Cab/Cab.def
new file mode 100755
index 00000000..77f97f92
--- /dev/null
+++ b/7zip/Archive/Cab/Cab.def
@@ -0,0 +1,7 @@
+; Cab.def
+
+LIBRARY cab.dll
+
+EXPORTS
+ CreateObject PRIVATE
+ GetHandlerProperty PRIVATE
diff --git a/7zip/Archive/Cab/Cab.dsp b/7zip/Archive/Cab/Cab.dsp
new file mode 100755
index 00000000..23ea022c
--- /dev/null
+++ b/7zip/Archive/Cab/Cab.dsp
@@ -0,0 +1,325 @@
+# 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" /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" /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=.\Cab.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\DllExports.cpp
+# 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
+# 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\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=.\CabCopyDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CabCopyDecoder.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=.\CabInBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CabInBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CabItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LZXBitDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LZXConst.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LZXDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LZXDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LZXExtConst.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LZXi86Converter.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LZXi86Converter.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\MSZipConst.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\MSZipDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\MSZipDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\MSZipExtConst.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\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
+# 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
+# End Group
+# Begin Source File
+
+SOURCE=.\cab.ico
+# End Source File
+# End Target
+# End Project
diff --git a/7zip/Archive/Cab/Cab.dsw b/7zip/Archive/Cab/Cab.dsw
new file mode 100755
index 00000000..470cb1b3
--- /dev/null
+++ b/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/7zip/Archive/Cab/CabCopyDecoder.cpp b/7zip/Archive/Cab/CabCopyDecoder.cpp
new file mode 100755
index 00000000..7e9c7ac8
--- /dev/null
+++ b/7zip/Archive/Cab/CabCopyDecoder.cpp
@@ -0,0 +1,67 @@
+// CabCopyDecoder.cpp
+
+#include "StdAfx.h"
+
+#include "CabCopyDecoder.h"
+#include "Common/Defs.h"
+#include "Windows/Defs.h"
+
+namespace NArchive {
+namespace NCab {
+
+static const UINT32 kBufferSize = 1 << 17;
+
+/*
+void CCopyDecoder::ReleaseStreams()
+{
+ m_InStream.ReleaseStream();
+ m_OutStream.ReleaseStream();
+}
+*/
+class CCopyDecoderFlusher
+{
+ CCopyDecoder *m_Decoder;
+public:
+ CCopyDecoderFlusher(CCopyDecoder *aDecoder): m_Decoder(aDecoder) {}
+ ~CCopyDecoderFlusher()
+ {
+ m_Decoder->Flush();
+ // m_Decoder->ReleaseStreams();
+ }
+};
+
+STDMETHODIMP CCopyDecoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ if (outSize == NULL)
+ return E_INVALIDARG;
+ UINT64 size = *outSize;
+
+ m_InStream.Init(inStream, m_ReservedSize, m_NumInDataBlocks);
+ m_OutStream.Init(outStream);
+ CCopyDecoderFlusher decoderFlusher(this);
+
+ UINT64 nowPos64 = 0;
+ while(nowPos64 < size)
+ {
+ UINT32 blockSize;
+ bool dataAreCorrect;
+ RINOK(m_InStream.ReadBlock(blockSize, dataAreCorrect));
+ if (!dataAreCorrect)
+ {
+ throw 123456;
+ }
+ for (UINT32 i = 0; i < blockSize; i++)
+ m_OutStream.WriteByte(m_InStream.ReadByte());
+ nowPos64 += blockSize;
+ if (progress != NULL)
+ {
+ RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
+ }
+ }
+ return S_OK;
+}
+
+}}
diff --git a/7zip/Archive/Cab/CabCopyDecoder.h b/7zip/Archive/Cab/CabCopyDecoder.h
new file mode 100755
index 00000000..d12cec95
--- /dev/null
+++ b/7zip/Archive/Cab/CabCopyDecoder.h
@@ -0,0 +1,43 @@
+// CabCopyDecoder.h
+
+#ifndef __ARCHIVE_CAB_COPY_DECODER_H
+#define __ARCHIVE_CAB_COPY_DECODER_H
+
+#pragma once
+
+#include "Common/MyCom.h"
+#include "../../ICoder.h"
+#include "../../Common/OutBuffer.h"
+#include "CabInBuffer.h"
+
+namespace NArchive {
+namespace NCab {
+
+class CCopyDecoder:
+ public ICompressCoder,
+ public CMyUnknownImp
+{
+ CInBuffer m_InStream;
+ COutBuffer m_OutStream;
+ BYTE m_ReservedSize;
+ UINT32 m_NumInDataBlocks;
+public:
+ MY_UNKNOWN_IMP
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress);
+
+ // void ReleaseStreams();
+ HRESULT Flush() { return m_OutStream.Flush(); }
+ void SetParams(BYTE reservedSize, UINT32 numInDataBlocks)
+ {
+ m_ReservedSize = reservedSize;
+ m_NumInDataBlocks = numInDataBlocks;
+ }
+
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/7zip/Archive/Cab/CabHandler.cpp b/7zip/Archive/Cab/CabHandler.cpp
new file mode 100755
index 00000000..038f108a
--- /dev/null
+++ b/7zip/Archive/Cab/CabHandler.cpp
@@ -0,0 +1,636 @@
+// Cab/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 "CabCopyDecoder.h"
+#include "LZXDecoder.h"
+#include "MSZIPDecoder.h"
+
+#include "CabHandler.h"
+
+#include "../../Common/ProgressUtils.h"
+
+using namespace NWindows;
+using namespace NTime;
+
+namespace NArchive {
+namespace NCab {
+
+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, kpidDictionarySize, VT_UI4},
+
+ { NULL, kpidBlock, VT_UI4}
+};
+
+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;
+ *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::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant propVariant;
+ const CItem &fileInfo = m_Files[index];
+ switch(propID)
+ {
+ case kpidPath:
+ if (fileInfo.IsNameUTF())
+ {
+ UString unicodeName;
+ if (!ConvertUTF8ToUnicode(fileInfo.Name, unicodeName))
+ propVariant = L"";
+ else
+ propVariant = unicodeName;
+ }
+ else
+ propVariant = MultiByteToUnicodeString(fileInfo.Name, CP_ACP);
+ break;
+ case kpidIsFolder:
+ propVariant = false;
+ break;
+ case kpidSize:
+ propVariant = fileInfo.UnPackSize;
+ break;
+ case kpidLastWriteTime:
+ {
+ FILETIME localFileTime, utcFileTime;
+ if (DosTimeToFileTime(fileInfo.Time, localFileTime))
+ {
+ if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
+ utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
+ }
+ else
+ utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
+ propVariant = utcFileTime;
+ break;
+ }
+ case kpidAttributes:
+ propVariant = fileInfo.GetWinAttributes();
+ break;
+
+ case kpidMethod:
+ {
+ UINT16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex(
+ m_Folders.Size(), fileInfo.FolderIndex);
+ const NHeader::CFolder &folder = m_Folders[realFolderIndex];
+ UString method;
+ int methodIndex = folder.GetCompressionMethod();
+ if (methodIndex < kNumMethods)
+ method = kMethods[methodIndex];
+ else
+ method = kUnknownMethod;
+ if (methodIndex == NHeader::NCompressionMethodMajor::kLZX)
+ {
+ method += L":";
+ wchar_t temp[32];
+ _itow (folder.CompressionTypeMinor, temp, 10);
+ method += temp;
+ }
+ propVariant = method;
+ break;
+ }
+ case kpidBlock:
+ propVariant = UINT32(fileInfo.FolderIndex);
+ break;
+ }
+ 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;
+ m_Files.Clear();
+ CPropgressImp progressImp;
+ progressImp.Init(openArchiveCallback);
+ RINOK(archive.Open(inStream, maxCheckStartPosition,
+ m_ArchiveInfo, m_Folders, m_Files, &progressImp));
+ m_Stream = inStream;
+ }
+ /*
+ catch(...)
+ {
+ return S_FALSE;
+ }
+ */
+ COM_TRY_END
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ m_Stream.Release();
+ return S_OK;
+}
+
+class CCabFolderOutStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize);
+ STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize);
+private:
+ const CObjectVector<NHeader::CFolder> *m_Folders;
+ const CObjectVector<CItem> *m_Files;
+ const CRecordVector<int> *m_FileIndexes;
+ const CRecordVector<bool> *m_ExtractStatuses;
+ int m_StartIndex;
+ int m_CurrentIndex;
+ int m_NumFiles;
+ UINT64 m_CurrentDataPos;
+ CMyComPtr<IArchiveExtractCallback> m_ExtractCallback;
+ bool m_TestMode;
+
+ bool m_FileIsOpen;
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ UINT64 m_FilePos;
+
+ HRESULT OpenFile(int indexIndex, ISequentialOutStream **realOutStream);
+ HRESULT WriteEmptyFiles();
+ UINT64 m_StartImportantTotalUnPacked;
+public:
+ void Init(
+ const CObjectVector<NHeader::CFolder> *folders,
+ const CObjectVector<CItem> *files,
+ const CRecordVector<int> *fileIndices,
+ const CRecordVector<bool> *extractStatuses,
+ int startIndex,
+ int numFiles,
+ IArchiveExtractCallback *extractCallback,
+ UINT64 startImportantTotalUnPacked,
+ bool testMode);
+ HRESULT FlushCorrupted();
+ HRESULT Unsupported();
+};
+
+void CCabFolderOutStream::Init(
+ const CObjectVector<NHeader::CFolder> *folders,
+ const CObjectVector<CItem> *files,
+ const CRecordVector<int> *fileIndices,
+ const CRecordVector<bool> *extractStatuses,
+ int startIndex,
+ int numFiles,
+ IArchiveExtractCallback *extractCallback,
+ UINT64 startImportantTotalUnPacked,
+ bool testMode)
+{
+ m_Folders = folders;
+ m_Files = files;
+ m_FileIndexes = fileIndices;
+ m_ExtractStatuses = extractStatuses;
+ m_StartIndex = startIndex;
+ m_NumFiles = numFiles;
+ m_ExtractCallback = extractCallback;
+ m_StartImportantTotalUnPacked = startImportantTotalUnPacked;
+ m_TestMode = testMode;
+
+ m_CurrentIndex = 0;
+ m_FileIsOpen = false;
+}
+
+HRESULT CCabFolderOutStream::OpenFile(int indexIndex, ISequentialOutStream **realOutStream)
+{
+ // RINOK(m_ExtractCallback->SetCompleted(&m_StartImportantTotalUnPacked));
+
+ int fullIndex = m_StartIndex + indexIndex;
+
+ INT32 askMode;
+ if((*m_ExtractStatuses)[fullIndex])
+ askMode = m_TestMode ?
+ NArchive::NExtract::NAskMode::kTest :
+ NArchive::NExtract::NAskMode::kExtract;
+ else
+ askMode = NArchive::NExtract::NAskMode::kSkip;
+
+ int index = (*m_FileIndexes)[fullIndex];
+ const CItem &fileInfo = (*m_Files)[index];
+ UINT16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex(
+ m_Folders->Size(), fileInfo.FolderIndex);
+
+ RINOK(m_ExtractCallback->GetStream(index, realOutStream, askMode));
+
+ UINT64 currentUnPackSize = fileInfo.UnPackSize;
+
+ bool mustBeProcessedAnywhere = (indexIndex < m_NumFiles - 1);
+
+ if (realOutStream || mustBeProcessedAnywhere)
+ {
+ if (!realOutStream && !m_TestMode)
+ askMode = NArchive::NExtract::NAskMode::kSkip;
+ RINOK(m_ExtractCallback->PrepareOperation(askMode));
+ return S_OK;
+ }
+ else
+ return S_FALSE;
+}
+
+
+HRESULT CCabFolderOutStream::WriteEmptyFiles()
+{
+ for(;m_CurrentIndex < m_NumFiles; m_CurrentIndex++)
+ {
+ int index = (*m_FileIndexes)[m_StartIndex + m_CurrentIndex];
+ const CItem &fileInfo = (*m_Files)[index];
+ if (fileInfo.UnPackSize != 0)
+ return S_OK;
+ realOutStream.Release();
+ HRESULT result = OpenFile(m_CurrentIndex, &realOutStream);
+ realOutStream.Release();
+ if (result == S_FALSE)
+ {
+ }
+ else if (result == S_OK)
+ {
+ RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ }
+ else
+ return result;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CCabFolderOutStream::Write(const void *data,
+ UINT32 size, UINT32 *processedSize)
+{
+ UINT32 processedSizeReal = 0;
+ while(m_CurrentIndex < m_NumFiles)
+ {
+ if (m_FileIsOpen)
+ {
+ int index = (*m_FileIndexes)[m_StartIndex + m_CurrentIndex];
+ const CItem &fileInfo = (*m_Files)[index];
+ UINT64 fileSize = fileInfo.UnPackSize;
+
+ UINT32 numBytesToWrite = (UINT32)MyMin(fileSize - m_FilePos,
+ UINT64(size - processedSizeReal));
+
+ UINT32 processedSizeLocal;
+ if (!realOutStream)
+ {
+ processedSizeLocal = numBytesToWrite;
+ }
+ else
+ {
+ RINOK(realOutStream->Write((const BYTE *)data + processedSizeReal, numBytesToWrite, &processedSizeLocal));
+ }
+ m_FilePos += processedSizeLocal;
+ processedSizeReal += processedSizeLocal;
+ if (m_FilePos == fileInfo.UnPackSize)
+ {
+ realOutStream.Release();
+ RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ m_FileIsOpen = false;
+ m_CurrentIndex++;
+ }
+ if (processedSizeReal == size)
+ {
+ RINOK(WriteEmptyFiles());
+ if (processedSize != NULL)
+ *processedSize = processedSizeReal;
+ return S_OK;
+ }
+ }
+ else
+ {
+ HRESULT result = OpenFile(m_CurrentIndex, &realOutStream);
+ if (result != S_FALSE && result != S_OK)
+ return result;
+ m_FileIsOpen = true;
+ m_FilePos = 0;
+ }
+ }
+ if (processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
+
+HRESULT CCabFolderOutStream::FlushCorrupted()
+{
+ // UINT32 processedSizeReal = 0;
+ while(m_CurrentIndex < m_NumFiles)
+ {
+ if (m_FileIsOpen)
+ {
+ int index = (*m_FileIndexes)[m_StartIndex + m_CurrentIndex];
+ const CItem &fileInfo = (*m_Files)[index];
+ UINT64 fileSize = fileInfo.UnPackSize;
+
+ realOutStream.Release();
+ RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError));
+ m_FileIsOpen = false;
+ m_CurrentIndex++;
+ }
+ else
+ {
+ HRESULT result = OpenFile(m_CurrentIndex, &realOutStream);
+ if (result != S_FALSE && result != S_OK)
+ return result;
+ m_FileIsOpen = true;
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CCabFolderOutStream::Unsupported()
+{
+ while(m_CurrentIndex < m_NumFiles)
+ {
+ HRESULT result = OpenFile(m_CurrentIndex, &realOutStream);
+ if (result != S_FALSE && result != S_OK)
+ return result;
+ realOutStream.Release();
+ RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+ m_CurrentIndex++;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CCabFolderOutStream::WritePart(const void *data,
+ UINT32 size, UINT32 *processedSize)
+{
+ return Write(data, size, processedSize);
+}
+
+
+STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
+ INT32 _aTestMode, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ bool allFilesMode = (numItems == UINT32(-1));
+ if (allFilesMode)
+ numItems = m_Files.Size();
+ if(numItems == 0)
+ return S_OK;
+ bool testMode = (_aTestMode != 0);
+ UINT64 censoredTotalUnPacked = 0, importantTotalUnPacked = 0;
+ int lastIndex = 0;
+ CRecordVector<int> folderIndexes;
+ CRecordVector<int> importantIndices;
+ CRecordVector<bool> extractStatuses;
+
+ UINT32 i;
+ for(i = 0; i < numItems; i++)
+ {
+ int index = allFilesMode ? i : indices[i];
+ const CItem &fileInfo = m_Files[index];
+ censoredTotalUnPacked += fileInfo.UnPackSize;
+
+ int folderIndex = fileInfo.FolderIndex;
+ if (folderIndexes.IsEmpty())
+ folderIndexes.Add(folderIndex);
+ else
+ {
+ if (folderIndex != folderIndexes.Back())
+ folderIndexes.Add(folderIndex);
+ }
+
+ for(int j = index - 1; j >= lastIndex; j--)
+ if(m_Files[j].FolderIndex != folderIndex)
+ break;
+ for(j++; j <= index; j++)
+ {
+ const CItem &fileInfo = m_Files[j];
+ importantTotalUnPacked += fileInfo.UnPackSize;
+ importantIndices.Add(j);
+ extractStatuses.Add(j == index);
+ }
+ lastIndex = index + 1;
+ }
+
+ extractCallback->SetTotal(importantTotalUnPacked);
+ UINT64 currentImportantTotalUnPacked = 0;
+ UINT64 currentImportantTotalPacked = 0;
+
+ CCopyDecoder *storeDecoderSpec = NULL;
+ CMyComPtr<ICompressCoder> storeDecoder;
+
+ NMSZip::CDecoder *msZipDecoderSpec = NULL;
+ CMyComPtr<ICompressCoder> msZipDecoder;
+
+ NLZX::CDecoder *lzxDecoderSpec = NULL;
+ CMyComPtr<ICompressCoder> lzxDecoder;
+
+
+ int curImportantIndexIndex = 0;
+ UINT64 totalFolderUnPacked;
+ for(i = 0; i < (UINT32)folderIndexes.Size(); i++, currentImportantTotalUnPacked += totalFolderUnPacked)
+ {
+ int folderIndex = folderIndexes[i];
+ UINT16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex(
+ m_Folders.Size(), folderIndex);
+
+ RINOK(extractCallback->SetCompleted(&currentImportantTotalUnPacked));
+ totalFolderUnPacked = 0;
+ for (int j = curImportantIndexIndex; j < importantIndices.Size(); j++)
+ {
+ const CItem &fileInfo = m_Files[importantIndices[j]];
+ if (fileInfo.FolderIndex != folderIndex)
+ break;
+ totalFolderUnPacked += fileInfo.UnPackSize;
+ }
+
+ CCabFolderOutStream *cabFolderOutStream = new CCabFolderOutStream;
+ CMyComPtr<ISequentialOutStream> outStream(cabFolderOutStream);
+
+ const NHeader::CFolder &folder = m_Folders[realFolderIndex];
+
+ cabFolderOutStream->Init(&m_Folders, &m_Files, &importantIndices,
+ &extractStatuses, curImportantIndexIndex, j - curImportantIndexIndex,
+ extractCallback, currentImportantTotalUnPacked,
+ folder.GetCompressionMethod() == NHeader::NCompressionMethodMajor::kQuantum?
+ true: testMode);
+
+ curImportantIndexIndex = j;
+
+ UINT64 pos = folder.DataStart; // test it (+ archiveStart)
+ RINOK(m_Stream->Seek(pos, STREAM_SEEK_SET, NULL));
+
+ CLocalProgress *localProgressSpec = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
+ localProgressSpec->Init(extractCallback, false);
+
+ CLocalCompressProgressInfo *localCompressProgressSpec =
+ new CLocalCompressProgressInfo;
+ CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
+ localCompressProgressSpec->Init(progress,
+ NULL, &currentImportantTotalUnPacked);
+
+ BYTE reservedSize = m_ArchiveInfo.ReserveBlockPresent() ?
+ m_ArchiveInfo.PerDataSizes.PerDatablockAreaSize : 0;
+
+ switch(folder.GetCompressionMethod())
+ {
+ case NHeader::NCompressionMethodMajor::kNone:
+ {
+ if(storeDecoderSpec == NULL)
+ {
+ storeDecoderSpec = new CCopyDecoder;
+ storeDecoder = storeDecoderSpec;
+ }
+ try
+ {
+ storeDecoderSpec->SetParams(reservedSize, folder.NumDataBlocks);
+ RINOK(storeDecoder->Code(m_Stream, outStream,
+ NULL, &totalFolderUnPacked, compressProgress));
+ }
+ catch(...)
+ {
+ RINOK(cabFolderOutStream->FlushCorrupted());
+ continue;
+ }
+ break;
+ }
+ case NHeader::NCompressionMethodMajor::kMSZip:
+ {
+ if(lzxDecoderSpec == NULL)
+ {
+ msZipDecoderSpec = new NMSZip::CDecoder;
+ msZipDecoder = msZipDecoderSpec;
+ }
+ try
+ {
+ msZipDecoderSpec->SetParams(reservedSize, folder.NumDataBlocks);
+ RINOK(msZipDecoder->Code(m_Stream, outStream,
+ NULL, &totalFolderUnPacked, compressProgress));
+ }
+ catch(...)
+ {
+ RINOK(cabFolderOutStream->FlushCorrupted());
+ continue;
+ }
+ break;
+ }
+ case NHeader::NCompressionMethodMajor::kLZX:
+ {
+ if(lzxDecoderSpec == NULL)
+ {
+ lzxDecoderSpec = new NLZX::CDecoder;
+ lzxDecoder = lzxDecoderSpec;
+ }
+ try
+ {
+ lzxDecoderSpec->SetParams(reservedSize, folder.NumDataBlocks,
+ folder.CompressionTypeMinor);
+ RINOK(lzxDecoder->Code(m_Stream, outStream,
+ NULL, &totalFolderUnPacked, compressProgress));
+ }
+ catch(...)
+ {
+ RINOK(cabFolderOutStream->FlushCorrupted());
+ continue;
+ }
+ break;
+ }
+ default:
+ RINOK(cabFolderOutStream->Unsupported());
+ // return E_FAIL;
+ }
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems)
+{
+ COM_TRY_BEGIN
+ *numItems = m_Files.Size();
+ return S_OK;
+ COM_TRY_END
+}
+
+}} \ No newline at end of file
diff --git a/7zip/Archive/Cab/CabHandler.h b/7zip/Archive/Cab/CabHandler.h
new file mode 100755
index 00000000..dad44eb4
--- /dev/null
+++ b/7zip/Archive/Cab/CabHandler.h
@@ -0,0 +1,50 @@
+// CabHandler.h
+
+#pragma once
+
+#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:
+ CObjectVector<NHeader::CFolder> m_Folders;
+ CObjectVector<CItem> m_Files;
+ CInArchiveInfo m_ArchiveInfo;
+ CMyComPtr<IInStream> m_Stream;
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/7zip/Archive/Cab/CabHeader.cpp b/7zip/Archive/Cab/CabHeader.cpp
new file mode 100755
index 00000000..01cdc9ee
--- /dev/null
+++ b/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;
+
+}
+
+}}} \ No newline at end of file
diff --git a/7zip/Archive/Cab/CabHeader.h b/7zip/Archive/Cab/CabHeader.h
new file mode 100755
index 00000000..f9904a0a
--- /dev/null
+++ b/7zip/Archive/Cab/CabHeader.h
@@ -0,0 +1,117 @@
+// Archive/Cab/Header.h
+
+#pragma once
+
+#ifndef __ARCHIVE_CAB_HEADER_H
+#define __ARCHIVE_CAB_HEADER_H
+
+#include "Common/Types.h"
+
+#pragma pack(push, PragmaCabHeaders)
+#pragma pack(push, 1)
+
+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;
+ }
+
+ struct CBlock
+ {
+ UINT32 Signature; /* cabinet file signature */
+ UINT32 Reserved1; /* reserved */
+ UINT32 Size; /* size of this cabinet file in bytes */
+ UINT32 Reserved2; /* reserved */
+ UINT32 FileOffset; /* offset of the first CFFILE entry */
+ UINT32 Reserved3; /* reserved */
+ BYTE VersionMinor; /* cabinet file format version, minor */
+ BYTE VersionMajor; /* cabinet file format version, major */
+ UINT16 NumFolders; /* number of CFFOLDER entries in this cabinet */
+ UINT16 NumFiles; /* number of CFFILE entries in this cabinet */
+ UINT16 Flags; /* cabinet file option indicators */
+ UINT16 SetID; /* must be the same for all cabinets in a set */
+ UINT16 CabinetNumber; /* number of this cabinet file in a set */
+ };
+
+ struct CPerDataSizes
+ {
+ UINT16 PerCabinetAreaSize; /* (optional) size of per-cabinet reserved area */
+ BYTE PerFolderAreaSize; /* (optional) size of per-folder reserved area */
+ BYTE PerDatablockAreaSize; /* (optional) size of per-datablock reserved area */
+ };
+
+ /*
+ BYTE abReserve[]; // (optional) per-cabinet reserved area
+ BYTE szCabinetPrev[]; // (optional) name of previous cabinet file
+ BYTE szDiskPrev[]; // (optional) name of previous disk
+ BYTE szCabinetNext[]; // (optional) name of next cabinet file
+ BYTE szDiskNext[]; // (optional) name of next disk
+ */
+}
+
+namespace NCompressionMethodMajor
+{
+ const BYTE kNone = 0;
+ const BYTE kMSZip = 1;
+ const BYTE kQuantum = 2;
+ const BYTE kLZX = 3;
+}
+
+struct CFolder
+{
+ UINT32 DataStart; // offset of the first CFDATA block in this folder
+ UINT16 NumDataBlocks; // number of CFDATA blocks in this folder
+ BYTE CompressionTypeMajor;
+ BYTE CompressionTypeMinor;
+ // BYTE abReserve[]; // (optional) per-folder reserved area
+ BYTE GetCompressionMethod() const { return CompressionTypeMajor & 0xF; }
+};
+
+const int kFileNameIsUTFAttributeMask = 0x80;
+
+namespace NFolderIndex
+{
+ const int kContinuedFromPrev = 0xFFFD;
+ const int kContinuedToNext = 0xFFFE;
+ const int kContinuedPrevAndNext = 0xFFFF;
+ inline UINT16 GetRealFolderIndex(UINT16 aNumFolders, UINT16 aFolderIndex)
+ {
+ switch(aFolderIndex)
+ {
+ case kContinuedFromPrev:
+ return 0;
+ case kContinuedToNext:
+ case kContinuedPrevAndNext:
+ return aNumFolders - 1;
+ default:
+ return aFolderIndex;
+ }
+ }
+}
+
+struct CFile
+{
+ UINT32 UnPackSize; /* uncompressed size of this file in bytes */
+ UINT32 UnPackOffset; /* uncompressed offset of this file in the folder */
+ UINT16 FolderIndex; /* index into the CFFOLDER area */
+ UINT16 PureDate;
+ UINT16 PureTime; /* Time */
+ UINT16 Attributes; /* attribute flags for this file */
+ //BYTE szName[]; /* name of this file */
+};
+
+}}}
+
+#pragma pack(pop)
+#pragma pack(pop, PragmaCabHeaders)
+
+#endif
diff --git a/7zip/Archive/Cab/CabIn.cpp b/7zip/Archive/Cab/CabIn.cpp
new file mode 100755
index 00000000..fcde9f4d
--- /dev/null
+++ b/7zip/Archive/Cab/CabIn.cpp
@@ -0,0 +1,189 @@
+// Archive/CabIn.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StringConvert.h"
+#include "Common/MyCom.h"
+#include "CabIn.h"
+#include "Windows/Defs.h"
+#include "../../Common/InBuffer.h"
+
+namespace NArchive{
+namespace NCab{
+
+static HRESULT ReadBytes(IInStream *inStream, void *data, UINT32 size)
+{
+ UINT32 realProcessedSize;
+ RINOK(inStream->Read(data, size, &realProcessedSize));
+ if(realProcessedSize != size)
+ return S_FALSE;
+ return S_OK;
+}
+
+static HRESULT SafeRead(IInStream *inStream, void *data, UINT32 size)
+{
+ UINT32 realProcessedSize;
+ RINOK(inStream->Read(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);
+}
+
+static void SafeReadName(CInBuffer &inBuffer, AString &name)
+{
+ name.Empty();
+ while(true)
+ {
+ BYTE b;
+ if (!inBuffer.ReadByte(b))
+ throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
+ if (b == 0)
+ return;
+ name += char(b);
+ }
+}
+
+HRESULT CInArchive::Open(IInStream *inStream,
+ const UINT64 *searchHeaderSizeLimit,
+ CInArchiveInfo &inArchiveInfo,
+ CObjectVector<NHeader::CFolder> &folders,
+ CObjectVector<CItem> &files,
+ CProgressVirt *progressVirt)
+{
+ UINT64 startPosition;
+ RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &startPosition));
+
+ NHeader::NArchive::CBlock archiveHeader;
+
+ {
+ CInBuffer inBuffer;
+ inBuffer.Init(inStream);
+ UINT64 value = 0;
+ const int kSignatureSize = sizeof(value);
+ UINT64 kSignature64 = NHeader::NArchive::kSignature;
+ while(true)
+ {
+ BYTE b;
+ if (!inBuffer.ReadByte(b))
+ return S_FALSE;
+ value >>= 8;
+ value |= ((UINT64)b) << ((kSignatureSize - 1) * 8);
+ if (inBuffer.GetProcessedSize() >= kSignatureSize)
+ {
+ if (value == kSignature64)
+ break;
+ if (searchHeaderSizeLimit != NULL)
+ if (inBuffer.GetProcessedSize() > (*searchHeaderSizeLimit))
+ return S_FALSE;
+ }
+ }
+ startPosition += inBuffer.GetProcessedSize() - kSignatureSize;
+ }
+ RINOK(inStream->Seek(startPosition, STREAM_SEEK_SET, NULL));
+ RINOK(ReadBytes(inStream, &archiveHeader, sizeof(archiveHeader)));
+ // if (archiveHeader.Signature != NHeader::NArchive::kSignature)
+ // return S_FALSE;
+
+ if (archiveHeader.Reserved1 != 0 ||
+ archiveHeader.Reserved2 != 0 ||
+ archiveHeader.Reserved3 != 0)
+ throw CInArchiveException(CInArchiveException::kUnsupported);
+
+ inArchiveInfo.VersionMinor = archiveHeader.VersionMinor;
+ inArchiveInfo.VersionMajor = archiveHeader.VersionMajor;
+ inArchiveInfo.NumFolders = archiveHeader.NumFolders;
+ inArchiveInfo.NumFiles = archiveHeader.NumFiles;
+ inArchiveInfo.Flags = archiveHeader.Flags;
+
+ if (inArchiveInfo.ReserveBlockPresent())
+ {
+ RINOK(SafeRead(inStream, &inArchiveInfo.PerDataSizes,
+ sizeof(inArchiveInfo.PerDataSizes)));
+ RINOK(inStream->Seek(inArchiveInfo.PerDataSizes.PerCabinetAreaSize,
+ STREAM_SEEK_CUR, NULL));
+ }
+
+ {
+ UINT64 foldersStartPosition;
+ RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &foldersStartPosition));
+ CInBuffer inBuffer;
+ inBuffer.Init(inStream);
+ if ((archiveHeader.Flags & NHeader::NArchive::NFlags::kPrevCabinet) != 0)
+ {
+ SafeReadName(inBuffer, inArchiveInfo.PreviousCabinetName);
+ SafeReadName(inBuffer, inArchiveInfo.PreviousDiskName);
+ }
+ if ((archiveHeader.Flags & NHeader::NArchive::NFlags::kNextCabinet) != 0)
+ {
+ SafeReadName(inBuffer, inArchiveInfo.NextCabinetName);
+ SafeReadName(inBuffer, inArchiveInfo.NextDiskName);
+ }
+ foldersStartPosition += inBuffer.GetProcessedSize();
+ RINOK(inStream->Seek(foldersStartPosition, STREAM_SEEK_SET, NULL));
+ }
+
+ if (progressVirt != NULL)
+ {
+ UINT64 numFiles = archiveHeader.NumFiles;
+ RINOK(progressVirt->SetTotal(&numFiles));
+ }
+ folders.Clear();
+ for(int i = 0; i < archiveHeader.NumFolders; i++)
+ {
+ if (progressVirt != NULL)
+ {
+ UINT64 numFiles = 0;
+ RINOK(progressVirt->SetCompleted(&numFiles));
+ }
+ NHeader::CFolder folder;
+ RINOK(SafeRead(inStream, &folder, sizeof(folder)));
+ if (inArchiveInfo.ReserveBlockPresent())
+ {
+ RINOK(inStream->Seek(
+ inArchiveInfo.PerDataSizes.PerFolderAreaSize, STREAM_SEEK_CUR, NULL));
+ }
+ folder.DataStart += (UINT32)startPosition;
+ folders.Add(folder);
+ }
+
+ RINOK(inStream->Seek(startPosition + archiveHeader.FileOffset,
+ STREAM_SEEK_SET, NULL));
+
+ CInBuffer inBuffer;
+ inBuffer.Init(inStream);
+ files.Clear();
+ if (progressVirt != NULL)
+ {
+ UINT64 numFiles = files.Size();
+ RINOK(progressVirt->SetCompleted(&numFiles));
+ }
+ for(i = 0; i < archiveHeader.NumFiles; i++)
+ {
+ NHeader::CFile fileHeader;
+ SafeInByteRead(inBuffer, &fileHeader, sizeof(fileHeader));
+ CItem item;
+ item.UnPackSize = fileHeader.UnPackSize;
+ item.UnPackOffset = fileHeader.UnPackOffset;
+ item.FolderIndex = fileHeader.FolderIndex;
+ item.Time = ((UINT32(fileHeader.PureDate) << 16)) | fileHeader.PureTime;
+ item.Attributes = fileHeader.Attributes;
+ SafeReadName(inBuffer, item.Name);
+ files.Add(item);
+ if (progressVirt != NULL)
+ {
+ UINT64 numFiles = files.Size();
+ RINOK(progressVirt->SetCompleted(&numFiles));
+ }
+ }
+ return S_OK;
+}
+
+}}
diff --git a/7zip/Archive/Cab/CabIn.h b/7zip/Archive/Cab/CabIn.h
new file mode 100755
index 00000000..4c6db9cb
--- /dev/null
+++ b/7zip/Archive/Cab/CabIn.h
@@ -0,0 +1,68 @@
+// Archive/CabIn.h
+
+#pragma once
+
+#ifndef __ARCHIVE_CAB_IN_H
+#define __ARCHIVE_CAB_IN_H
+
+#include "../../IStream.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) {}
+};
+
+class CInArchiveInfo
+{
+public:
+ UINT32 Size; /* size of this cabinet file in bytes */
+ BYTE VersionMinor; /* cabinet file format version, minor */
+ BYTE VersionMajor; /* cabinet file format version, major */
+ UINT16 NumFolders; /* number of CFFOLDER entries in this cabinet */
+ 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; }
+ NHeader::NArchive::CPerDataSizes PerDataSizes;
+
+ AString PreviousCabinetName;
+ AString PreviousDiskName;
+ AString NextCabinetName;
+ AString NextDiskName;
+};
+
+class CProgressVirt
+{
+public:
+ STDMETHOD(SetTotal)(const UINT64 *numFiles) PURE;
+ STDMETHOD(SetCompleted)(const UINT64 *numFiles) PURE;
+};
+
+class CInArchive
+{
+public:
+ HRESULT Open(IInStream *inStream,
+ const UINT64 *searchHeaderSizeLimit,
+ CInArchiveInfo &inArchiveInfo,
+ CObjectVector<NHeader::CFolder> &folders,
+ CObjectVector<CItem> &aFiles,
+ CProgressVirt *aProgressVirt);
+};
+
+}}
+
+#endif
diff --git a/7zip/Archive/Cab/CabInBuffer.cpp b/7zip/Archive/Cab/CabInBuffer.cpp
new file mode 100755
index 00000000..ba924115
--- /dev/null
+++ b/7zip/Archive/Cab/CabInBuffer.cpp
@@ -0,0 +1,153 @@
+// Archive/CabInBuffer.cpp
+
+#include "stdafx.h"
+
+#include "Common/Types.h"
+#include "Common/MyCom.h"
+#include "Windows/Defs.h"
+#include "CabInBuffer.h"
+
+namespace NArchive {
+namespace NCab {
+
+#pragma pack(push, PragmaCabDataHeader)
+#pragma pack(push, 1)
+
+struct CDataBlockHeader
+{
+ UINT32 CheckSum; /* checksum of this CFDATA entry */
+ UINT16 PackSize; /* number of compressed bytes in this block */
+ UINT16 UnPackSize; /* number of uncompressed bytes in this block */
+ // BYTE abReserve[]; /* (optional) per-datablock reserved area */
+ // BYTE ab[cbData]; /* compressed data bytes */
+};
+
+#pragma pack(pop)
+#pragma pack(pop, PragmaCabDataHeader)
+
+CInBuffer::CInBuffer(UINT32 bufferSize):
+ m_BufferSize(bufferSize),
+ m_Stream(0)
+{
+ m_Buffer = new BYTE[m_BufferSize];
+}
+
+CInBuffer::~CInBuffer()
+{
+ delete []m_Buffer;
+ // ReleaseStream();
+}
+
+void CInBuffer::Init(ISequentialInStream *inStream, BYTE reservedSize, UINT32 numBlocks)
+{
+ m_ReservedSize = reservedSize;
+ m_NumBlocks = numBlocks;
+ m_CurrentBlockIndex = 0;
+ // ReleaseStream();
+ m_Stream = inStream;
+ // m_Stream->AddRef();
+ m_ProcessedSize = 0;
+ m_Pos = 0;
+ m_NumReadBytesInBuffer = 0;
+}
+
+/*
+void CInBuffer::ReleaseStream()
+{
+ if(m_Stream != 0)
+ {
+ m_Stream->Release();
+ m_Stream = 0;
+ }
+}
+*/
+
+class CCheckSum
+{
+ UINT32 m_Value;
+public:
+ CCheckSum(): m_Value(0){};
+ void Init() { m_Value = 0; }
+ void Update(const void *data, UINT32 size);
+ UINT32 GetResult() const { return m_Value; }
+};
+
+void CCheckSum::Update(const void *data, UINT32 size)
+{
+ UINT32 checkSum = m_Value;
+ const BYTE *aDataPointer = (const BYTE *)data;
+ int numUINT32Words = size / 4; // Number of ULONGs
+
+ // dataPointer += numUINT32Words * 4;
+
+ UINT32 temp;
+ const UINT32 *aDataPointer32 = (const UINT32 *)data;
+ while (numUINT32Words-- > 0)
+ {
+ // temp ^= *aDataPointer32++;
+ temp = *aDataPointer++; // Get low-order byte
+ temp |= (((ULONG)(*aDataPointer++)) << 8); // Add 2nd byte
+ temp |= (((ULONG)(*aDataPointer++)) << 16); // Add 3nd byte
+ temp |= (((ULONG)(*aDataPointer++)) << 24); // Add 4th byte
+ checkSum ^= temp; // Update checksum
+ }
+
+ temp = 0;
+ switch (size % 4)
+ {
+ case 3:
+ temp |= (((ULONG)(*aDataPointer++)) << 16); // Add 3nd byte
+ case 2:
+ temp |= (((ULONG)(*aDataPointer++)) << 8); // Add 2nd byte
+ case 1:
+ temp |= *aDataPointer++; // Get low-order byte
+ default:
+ break;
+ }
+ checkSum ^= temp;
+ m_Value = checkSum;
+}
+HRESULT CInBuffer::ReadBlock(UINT32 &uncompressedSize, bool &dataAreCorrect)
+{
+ if (m_CurrentBlockIndex >= m_NumBlocks)
+ throw "there is no more data blocks";
+
+ m_ProcessedSize += m_NumReadBytesInBuffer;
+
+ CDataBlockHeader dataBlockHeader;
+ UINT32 numProcessedBytes;
+ RINOK(m_Stream->Read(&dataBlockHeader, sizeof(dataBlockHeader), &numProcessedBytes));
+ if (numProcessedBytes != sizeof(dataBlockHeader))
+ throw "bad block";
+
+ if (m_ReservedSize != 0)
+ {
+ BYTE reservedArea[256];
+ RINOK(m_Stream->Read(reservedArea, m_ReservedSize, &numProcessedBytes));
+ if (numProcessedBytes != m_ReservedSize)
+ throw "bad block";
+ }
+
+ RINOK(m_Stream->Read(m_Buffer, dataBlockHeader.PackSize, &m_NumReadBytesInBuffer));
+ if (m_NumReadBytesInBuffer != dataBlockHeader.PackSize)
+ throw "bad block";
+
+ if (dataBlockHeader.CheckSum == 0)
+ dataAreCorrect = true;
+ {
+ CCheckSum checkSum;
+ checkSum.Update(m_Buffer, dataBlockHeader.PackSize);
+ checkSum.Update(&dataBlockHeader.PackSize,
+ sizeof(dataBlockHeader) - sizeof(dataBlockHeader.CheckSum));
+ dataAreCorrect = (checkSum.GetResult() == dataBlockHeader.CheckSum);
+ }
+
+ m_Pos = 0;
+ uncompressedSize = dataBlockHeader.UnPackSize;
+
+ m_CurrentBlockIndex++;
+ return S_OK;
+}
+
+
+}}
diff --git a/7zip/Archive/Cab/CabInBuffer.h b/7zip/Archive/Cab/CabInBuffer.h
new file mode 100755
index 00000000..233a0f84
--- /dev/null
+++ b/7zip/Archive/Cab/CabInBuffer.h
@@ -0,0 +1,62 @@
+// Archive/CabInBuffer.h
+
+#pragma once
+
+#ifndef __ARCHIVE_CAB_INBUFFER_H
+#define __ARCHIVE_CAB_INBUFFER_H
+
+#include "../../IStream.h"
+
+namespace NArchive {
+namespace NCab {
+
+class CInBuffer
+{
+ UINT64 m_ProcessedSize;
+ UINT32 m_Pos;
+ UINT32 m_NumReadBytesInBuffer;
+ BYTE *m_Buffer;
+ ISequentialInStream *m_Stream;
+ UINT32 m_BufferSize;
+
+ UINT32 m_NumBlocks;
+ UINT32 m_CurrentBlockIndex;
+ UINT32 m_ReservedSize;
+
+public:
+ CInBuffer(UINT32 bufferSize = 0x20000);
+ ~CInBuffer();
+
+ void Init(ISequentialInStream *inStream, BYTE reservedSize, UINT32 numBlocks);
+ // void ReleaseStream();
+
+ bool ReadByte(BYTE &b)
+ {
+ if(m_Pos >= m_NumReadBytesInBuffer)
+ return false;
+ b = m_Buffer[m_Pos++];
+ return true;
+ }
+ BYTE ReadByte()
+ {
+ if(m_Pos >= m_NumReadBytesInBuffer)
+ return 0;
+ return m_Buffer[m_Pos++];
+ }
+ /*
+ void ReadBytes(void *data, UINT32 size, UINT32 &aProcessedSize)
+ {
+ BYTE *aDataPointer = (BYTE *)data;
+ for(int i = 0; i < size; i++)
+ if (!ReadByte(aDataPointer[i]))
+ break;
+ aProcessedSize = i;
+ }
+ */
+ HRESULT ReadBlock(UINT32 &uncompressedSize, bool &dataAreCorrect);
+ UINT64 GetProcessedSize() const { return m_ProcessedSize + m_Pos; }
+};
+
+}}
+
+#endif
diff --git a/7zip/Archive/Cab/CabItem.h b/7zip/Archive/Cab/CabItem.h
new file mode 100755
index 00000000..1b4add81
--- /dev/null
+++ b/7zip/Archive/Cab/CabItem.h
@@ -0,0 +1,33 @@
+// Archive/Cab/ItemInfo.h
+
+#pragma once
+
+#ifndef __ARCHIVE_RAR_ITEMINFO_H
+#define __ARCHIVE_RAR_ITEMINFO_H
+
+#include "Common/Types.h"
+#include "Common/String.h"
+#include "CabHeader.h"
+
+namespace NArchive {
+namespace NCab {
+
+class CItem
+{
+public:
+ UINT16 Flags;
+ UINT64 UnPackSize;
+ UINT32 UnPackOffset;
+ UINT16 FolderIndex;
+ UINT32 Time;
+ UINT16 Attributes;
+ UINT32 GetWinAttributes() const { return Attributes & (Attributes & ~NHeader::kFileNameIsUTFAttributeMask); }
+ bool IsNameUTF() const { return (Attributes & NHeader::kFileNameIsUTFAttributeMask) != 0; }
+ AString Name;
+};
+
+}}
+
+#endif
+
+
diff --git a/7zip/Archive/Cab/DllExports.cpp b/7zip/Archive/Cab/DllExports.cpp
new file mode 100755
index 00000000..8b345452
--- /dev/null
+++ b/7zip/Archive/Cab/DllExports.cpp
@@ -0,0 +1,66 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#define INITGUID
+
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+#include "CabHandler.h"
+#include "../../ICoder.h"
+
+// {23170F69-40C1-278A-1000-000110060000}
+DEFINE_GUID(CLSID_CCabHandler,
+ 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_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;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/7zip/Archive/Cab/LZXBitDecoder.h b/7zip/Archive/Cab/LZXBitDecoder.h
new file mode 100755
index 00000000..ec01ed87
--- /dev/null
+++ b/7zip/Archive/Cab/LZXBitDecoder.h
@@ -0,0 +1,112 @@
+// Archive/Cab/LZXBitDecoder.h
+
+#ifndef __ARCHIVE_CAB_LZXBITDECODER_H
+#define __ARCHIVE_CAB_LZXBITDECODER_H
+
+#include "CabInBuffer.h"
+
+namespace NArchive {
+namespace NCab {
+namespace NLZX {
+namespace NBitStream {
+
+const int kNumBigValueBits = 8 * 4;
+
+const int kNumValueBits = 17;
+const int kBitDecoderValueMask = (1 << kNumValueBits) - 1;
+
+class CDecoder
+{
+protected:
+ CInBuffer m_Stream;
+ UINT32 m_BitPos;
+ UINT32 m_Value;
+public:
+ void InitStream(ISequentialInStream *aStream, BYTE aReservedSize, UINT32 aNumBlocks)
+ {
+ m_Stream.Init(aStream, aReservedSize, aNumBlocks);
+ }
+ /*
+ void ReleaseStream()
+ { m_Stream.ReleaseStream(); }
+ */
+ UINT64 GetProcessedSize() const
+ { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; }
+ UINT32 GetBitPosition() const
+ { return UINT32(m_Stream.GetProcessedSize() * 8 - (kNumBigValueBits - m_BitPos)); }
+
+ void Init()
+ {
+ m_BitPos = kNumBigValueBits;
+ Normalize();
+ }
+
+ void Normalize()
+ {
+ for (;m_BitPos >= 16; m_BitPos -= 16)
+ {
+ BYTE aByte0 = m_Stream.ReadByte();
+ BYTE aByte1 = m_Stream.ReadByte();
+ m_Value = (m_Value << 8) | aByte1;
+ m_Value = (m_Value << 8) | aByte0;
+ }
+ }
+
+ UINT32 GetValue(UINT32 aNumBits)
+ {
+ return ((m_Value >> ((32 - kNumValueBits) - m_BitPos)) & kBitDecoderValueMask) >>
+ (kNumValueBits - aNumBits);
+ }
+
+ void MovePos(UINT32 aNumBits)
+ {
+ m_BitPos += aNumBits;
+ Normalize();
+ }
+
+ UINT32 ReadBits(UINT32 aNumBits)
+ {
+ UINT32 aRes = GetValue(aNumBits);
+ MovePos(aNumBits);
+ return aRes;
+ }
+ UINT32 ReadBitsBig(UINT32 aNumBits)
+ {
+ UINT32 aNumBits0 = aNumBits / 2;
+ UINT32 aNumBits1 = aNumBits - aNumBits0;
+ UINT32 aRes = ReadBits(aNumBits0) << aNumBits1;
+ return aRes + ReadBits(aNumBits1);
+ }
+
+ BYTE DirectReadByte()
+ {
+ if (m_BitPos == kNumBigValueBits)
+ return m_Stream.ReadByte();
+ BYTE aRes;
+ switch(m_BitPos)
+ {
+ case 0:
+ aRes = BYTE(m_Value >> 16);
+ break;
+ case 8:
+ aRes = BYTE(m_Value >> 24);
+ break;
+ case 16:
+ aRes = BYTE(m_Value);
+ break;
+ case 24:
+ aRes = BYTE(m_Value >> 8);
+ break;
+ }
+ m_BitPos += 8;
+ return aRes;
+ }
+
+ HRESULT ReadBlock(UINT32 &anUncompressedSize, bool &aDataAreCorrect)
+ { return m_Stream.ReadBlock(anUncompressedSize, aDataAreCorrect); }
+};
+
+
+}}}}
+
+#endif
diff --git a/7zip/Archive/Cab/LZXConst.h b/7zip/Archive/Cab/LZXConst.h
new file mode 100755
index 00000000..b996f904
--- /dev/null
+++ b/7zip/Archive/Cab/LZXConst.h
@@ -0,0 +1,112 @@
+// Archive/Cab/LZXConst.h
+
+#ifndef __ARCHIVE_CAB_LZXCONST_H
+#define __ARCHIVE_CAB_LZXCONST_H
+
+#include "LZXExtConst.h"
+
+namespace NArchive {
+namespace NCab {
+namespace NLZX {
+
+
+namespace NBlockType
+{
+ const int kNumBits = 3;
+ enum EEnum
+ {
+ kVerbatim = 1,
+ kAligned = 2,
+ kUncompressed = 3
+ };
+}
+
+const int kUncompressedBlockSizeNumBits = 24;
+
+const UINT32 kLevelTableSize = 20;
+
+const UINT32 kNumBitsForPreTreeLevel = 4;
+
+const int kLevelSymbolZeros = 17;
+const int kLevelSymbolZerosBig = 18;
+const int kLevelSymbolSame = 19;
+
+const int kLevelSymbolZerosStartValue = 4;
+const int kLevelSymbolZerosNumBits = 4;
+
+const int kLevelSymbolZerosBigStartValue = kLevelSymbolZerosStartValue +
+ (1 << kLevelSymbolZerosNumBits);
+const int kLevelSymbolZerosBigNumBits = 5;
+
+const int kNumBitsForAlignLevel = 3;
+
+const int kLevelSymbolSameNumBits = 1;
+const int kLevelSymbolSameStartValue = 4;
+
+// const UINT32 kMainTableSize = 256 + kNumPosLenSlots + 1;
+
+/*
+const UINT32 kLenTableSize = 28;
+
+const UINT32 kLenTableStart = kMainTableSize;
+const UINT32 kAlignTableStart = kLenTableStart + kLenTableSize;
+
+const UINT32 kHeapTablesSizesSum = kMainTableSize + kLenTableSize + kAlignTableSize;
+
+
+const UINT32 kMaxTableSize = kHeapTablesSizesSum;
+
+const UINT32 kTableDirectLevels = 16;
+const UINT32 kTableLevelRepNumber = kTableDirectLevels;
+const UINT32 kTableLevel0Number = kTableLevelRepNumber + 1;
+const UINT32 kTableLevel0Number2 = kTableLevel0Number + 1;
+
+const UINT32 kLevelMask = 0xF;
+
+const UINT32 kPosLenNumber = 256;
+const UINT32 kReadTableNumber = 256 + kNumPosLenSlots;
+
+//const UINT32 kMatchNumber = kReadTableNumber + 1;
+
+const BYTE kLenStart[kLenTableSize] =
+ {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224};
+const BYTE kLenDirectBits[kLenTableSize] =
+ {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5};
+*/
+
+const UINT32 kDistStart[] =
+{ 0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,
+ 1536,2048,3072,4096,6144,8192,12288,16384,24576,32768,49152,65536,98304,131072,196608,
+ 0x40000,
+ 0x60000,
+ 0x80000,
+ 0xA0000,
+ 0xC0000,
+ 0xE0000,
+
+ 0x100000,
+ 0x120000,
+ 0x140000,
+ 0x160000,
+ 0x180000,
+ 0x1A0000,
+ 0x1C0000,
+ 0x1E0000
+};
+const BYTE kDistDirectBits[] =
+{
+ 0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,
+ 17, 17, 17, 17, 17, 17,
+ 17, 17,17, 17, 17, 17, 17, 17
+};
+
+/*
+const BYTE kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7};
+
+const UINT32 kDistLimit2 = 0x101 - 1;
+*/
+
+
+}}}
+
+#endif \ No newline at end of file
diff --git a/7zip/Archive/Cab/LZXDecoder.cpp b/7zip/Archive/Cab/LZXDecoder.cpp
new file mode 100755
index 00000000..ffa7e1fc
--- /dev/null
+++ b/7zip/Archive/Cab/LZXDecoder.cpp
@@ -0,0 +1,311 @@
+// Archive/Cab/LZXDecoder.cpp
+
+#include "StdAfx.h"
+
+#include "LZXDecoder.h"
+
+#include "LZXConst.h"
+#include "Common/Defs.h"
+#include "Windows/Defs.h"
+
+namespace NArchive {
+namespace NCab {
+namespace NLZX {
+
+static const UINT32 kHistorySize = (1 << 21);
+
+const int kMainTableSize = 256 + kNumPosSlotLenSlotSymbols;
+
+CDecoder::CDecoder():
+ m_MainDecoder(kMainTableSize),
+ m_LenDecoder(kNumLenSymbols),
+ m_AlignDecoder(kAlignTableSize),
+ m_LevelDecoder(kLevelTableSize)
+{
+ m_OutWindowStream.Create(kHistorySize);
+ m_i86TranslationOutStreamSpec = new Ci86TranslationOutStream;
+ m_i86TranslationOutStream = m_i86TranslationOutStreamSpec;
+}
+
+void CDecoder::ReleaseStreams()
+{
+ // m_OutWindowStream.ReleaseStream();
+ // m_InBitStream.ReleaseStream();
+ m_i86TranslationOutStreamSpec->ReleaseStream();
+}
+
+STDMETHODIMP CDecoder::Flush()
+{
+ RINOK(m_OutWindowStream.Flush());
+ return m_i86TranslationOutStreamSpec->Flush();
+}
+
+void CDecoder::ReadTable(BYTE *lastLevels, BYTE *newLevels, UINT32 numSymbols)
+{
+ BYTE levelLevels[kLevelTableSize];
+ UINT32 i;
+ for (i = 0; i < kLevelTableSize; i++)
+ levelLevels[i] = BYTE(m_InBitStream.ReadBits(kNumBitsForPreTreeLevel));
+ m_LevelDecoder.SetCodeLengths(levelLevels);
+ for (i = 0; i < numSymbols;)
+ {
+ UINT32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
+ if (number <= kNumHuffmanBits)
+ newLevels[i++] = BYTE((17 + lastLevels[i] - number) % (kNumHuffmanBits + 1));
+ else if (number == kLevelSymbolZeros || number == kLevelSymbolZerosBig)
+ {
+ int num;
+ if (number == kLevelSymbolZeros)
+ num = kLevelSymbolZerosStartValue +
+ m_InBitStream.ReadBits(kLevelSymbolZerosNumBits);
+ else
+ num = kLevelSymbolZerosBigStartValue +
+ m_InBitStream.ReadBits(kLevelSymbolZerosBigNumBits);
+ for (;num > 0 && i < numSymbols; num--, i++)
+ newLevels[i] = 0;
+ }
+ else if (number == kLevelSymbolSame)
+ {
+ int num = kLevelSymbolSameStartValue + m_InBitStream.ReadBits(kLevelSymbolSameNumBits);
+ UINT32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
+ if (number > kNumHuffmanBits)
+ throw "bad data";
+ BYTE symbol = BYTE((17 + lastLevels[i] - number) % (kNumHuffmanBits + 1));
+ for (; num > 0 && i < numSymbols; num--, i++)
+ newLevels[i] = symbol;
+ }
+ else
+ throw "bad data";
+ }
+
+ memmove(lastLevels, newLevels, numSymbols);
+}
+
+void CDecoder::ReadTables(void)
+{
+ int blockType = m_InBitStream.ReadBits(NBlockType::kNumBits);
+
+ if (blockType != NBlockType::kVerbatim && blockType != NBlockType::kAligned &&
+ blockType != NBlockType::kUncompressed)
+ throw "bad data";
+
+ m_UnCompressedBlockSize = m_InBitStream.ReadBitsBig(kUncompressedBlockSizeNumBits);
+
+ if (blockType == NBlockType::kUncompressed)
+ {
+ m_UncompressedBlock = true;
+ UINT32 bitPos = m_InBitStream.GetBitPosition() % 16;
+ m_InBitStream.ReadBits(16 - bitPos);
+ for (int i = 0; i < kNumRepDistances; i++)
+ {
+ m_RepDistances[i] = 0;
+ for (int j = 0; j < 4; j++)
+ m_RepDistances[i] |= (m_InBitStream.DirectReadByte()) << (8 * j);
+ m_RepDistances[i]--;
+ }
+ return;
+ }
+
+ m_UncompressedBlock = false;
+
+ m_AlignIsUsed = (blockType == NBlockType::kAligned);
+
+ BYTE newLevels[kMaxTableSize];
+
+ if (m_AlignIsUsed)
+ {
+ for(int i = 0; i < kAlignTableSize; i++)
+ newLevels[i] = m_InBitStream.ReadBits(kNumBitsForAlignLevel);
+ m_AlignDecoder.SetCodeLengths(newLevels);
+ }
+
+ ReadTable(m_LastByteLevels, newLevels, 256);
+ ReadTable(m_LastPosLenLevels, newLevels + 256, m_NumPosLenSlots);
+ for (int i = m_NumPosLenSlots; i < kNumPosSlotLenSlotSymbols; i++)
+ newLevels[256 + i] = 0;
+ m_MainDecoder.SetCodeLengths(newLevels);
+
+ ReadTable(m_LastLenLevels, newLevels, kNumLenSymbols);
+ m_LenDecoder.SetCodeLengths(newLevels);
+
+}
+
+class CDecoderFlusher
+{
+ CDecoder *m_Decoder;
+public:
+ CDecoderFlusher(CDecoder *decoder): m_Decoder(decoder) {}
+ ~CDecoderFlusher()
+ {
+ m_Decoder->Flush();
+ m_Decoder->ReleaseStreams();
+ }
+};
+
+
+void CDecoder::ClearPrevLeveles()
+{
+ memset(m_LastByteLevels, 0, 256);
+ memset(m_LastPosLenLevels, 0, kNumPosSlotLenSlotSymbols);
+ memset(m_LastLenLevels, 0, kNumLenSymbols);
+};
+
+
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ if (outSize == NULL)
+ return E_INVALIDARG;
+ UINT64 size = *outSize;
+
+
+ m_OutWindowStream.Init(m_i86TranslationOutStream);
+ m_InBitStream.InitStream(inStream, m_ReservedSize, m_NumInDataBlocks);
+
+ CDecoderFlusher flusher(this);
+
+ UINT32 uncompressedCFDataBlockSize;
+ bool dataAreCorrect;
+ RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect));
+ if (!dataAreCorrect)
+ {
+ throw "Data Error";
+ }
+ UINT32 uncompressedCFDataCurrentValue = 0;
+ m_InBitStream.Init();
+
+ ClearPrevLeveles();
+
+ if (m_InBitStream.ReadBits(1) == 0)
+ m_i86TranslationOutStreamSpec->Init(outStream, false, 0);
+ else
+ {
+ UINT32 i86TranslationSize = m_InBitStream.ReadBits(16) << 16;
+ i86TranslationSize |= m_InBitStream.ReadBits(16);
+ m_i86TranslationOutStreamSpec->Init(outStream, true , i86TranslationSize);
+ }
+
+ for(int i = 0 ; i < kNumRepDistances; i++)
+ m_RepDistances[i] = 0;
+
+ UINT64 nowPos64 = 0;
+ while(nowPos64 < size)
+ {
+ if (uncompressedCFDataCurrentValue == uncompressedCFDataBlockSize)
+ {
+ bool dataAreCorrect;
+ RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect));
+ if (!dataAreCorrect)
+ {
+ throw "Data Error";
+ }
+ m_InBitStream.Init();
+ uncompressedCFDataCurrentValue = 0;
+ }
+ ReadTables();
+ UINT32 nowPos = 0;
+ UINT32 next = (UINT32)MyMin((UINT64)m_UnCompressedBlockSize, size - nowPos64);
+ if (m_UncompressedBlock)
+ {
+ while(nowPos < next)
+ {
+ m_OutWindowStream.PutOneByte(m_InBitStream.DirectReadByte());
+ nowPos++;
+ uncompressedCFDataCurrentValue++;
+ if (uncompressedCFDataCurrentValue == uncompressedCFDataBlockSize)
+ {
+ bool dataAreCorrect;
+ RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect));
+ if (!dataAreCorrect)
+ {
+ throw "Data Error";
+ }
+ // m_InBitStream.Init();
+ uncompressedCFDataCurrentValue = 0;
+ continue;
+ }
+ }
+ int bitPos = m_InBitStream.GetBitPosition() % 16;
+ if (bitPos == 8)
+ m_InBitStream.DirectReadByte();
+ m_InBitStream.Normalize();
+ }
+ else for (;nowPos < next;)
+ {
+ if (uncompressedCFDataCurrentValue == uncompressedCFDataBlockSize)
+ {
+ bool dataAreCorrect;
+ RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect));
+ if (!dataAreCorrect)
+ {
+ throw "Data Error";
+ }
+ m_InBitStream.Init();
+ uncompressedCFDataCurrentValue = 0;
+ }
+ UINT32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
+ if (number < 256)
+ {
+ m_OutWindowStream.PutOneByte(BYTE(number));
+ nowPos++;
+ uncompressedCFDataCurrentValue++;
+ // continue;
+ }
+ else if (number < 256 + m_NumPosLenSlots)
+ {
+ UINT32 posLenSlot = number - 256;
+ UINT32 posSlot = posLenSlot / kNumLenSlots;
+ UINT32 lenSlot = posLenSlot % kNumLenSlots;
+ UINT32 length = 2 + lenSlot;
+ if (lenSlot == kNumLenSlots - 1)
+ length += m_LenDecoder.DecodeSymbol(&m_InBitStream);
+
+ if (posSlot < kNumRepDistances)
+ {
+ UINT32 distance = m_RepDistances[posSlot];
+ m_OutWindowStream.CopyBackBlock(distance, length);
+ if (posSlot != 0)
+ {
+ m_RepDistances[posSlot] = m_RepDistances[0];
+ m_RepDistances[0] = distance;
+ }
+ }
+ else
+ {
+ UINT32 pos = kDistStart[posSlot];
+ UINT32 posDirectBits = kDistDirectBits[posSlot];
+ if (m_AlignIsUsed && posDirectBits >= kNumAlignBits)
+ {
+ pos += (m_InBitStream.ReadBits(posDirectBits - kNumAlignBits) << kNumAlignBits);
+ pos += m_AlignDecoder.DecodeSymbol(&m_InBitStream);
+ }
+ else
+ pos += m_InBitStream.ReadBits(posDirectBits);
+ UINT32 distance = pos - kNumRepDistances;
+ if (distance >= nowPos64 + nowPos)
+ throw 777123;
+ m_OutWindowStream.CopyBackBlock(distance, length);
+ m_RepDistances[2] = m_RepDistances[1];
+ m_RepDistances[1] = m_RepDistances[0];
+ m_RepDistances[0] = distance;
+ }
+ nowPos += length;
+ uncompressedCFDataCurrentValue += length;
+ }
+ else
+ throw 98112823;
+ }
+ if (progress != NULL)
+ {
+ UINT64 inSize = m_InBitStream.GetProcessedSize();
+ UINT64 outSize = nowPos64 + nowPos;
+ RINOK(progress->SetRatioInfo(&inSize, &outSize));
+ }
+ nowPos64 += nowPos;
+ }
+ return S_OK;
+}
+
+}}}
diff --git a/7zip/Archive/Cab/LZXDecoder.h b/7zip/Archive/Cab/LZXDecoder.h
new file mode 100755
index 00000000..00c2e9c4
--- /dev/null
+++ b/7zip/Archive/Cab/LZXDecoder.h
@@ -0,0 +1,98 @@
+// Archive/Cab/LZXDecoder.h
+
+#pragma once
+
+#ifndef __ARCHIVE_CAB_LZXDECODER_H
+#define __ARCHIVE_CAB_LZXDECODER_H
+
+#include "../../ICoder.h"
+
+#include "../../Compress/Huffman/HuffmanDecoder.h"
+#include "../../Compress/LZ/LZOutWindow.h"
+
+#include "LZXExtConst.h"
+#include "LZXBitDecoder.h"
+
+#include "LZXi86Converter.h"
+
+// #include "../../../Projects/CompressInterface/CompressInterface.h"
+
+namespace NArchive {
+namespace NCab {
+namespace NLZX {
+
+typedef NCompress::NHuffman::CDecoder<kNumHuffmanBits> CMSBFHuffmanDecoder;
+
+class CDecoder :
+ public ICompressCoder,
+ public CMyUnknownImp
+{
+ CLZOutWindow m_OutWindowStream;
+ NBitStream::CDecoder m_InBitStream;
+
+ CMSBFHuffmanDecoder m_MainDecoder;
+ CMSBFHuffmanDecoder m_LenDecoder; // for matches with repeated offsets
+ CMSBFHuffmanDecoder m_AlignDecoder; // for matches with repeated offsets
+ CMSBFHuffmanDecoder m_LevelDecoder; // table for decoding other tables;
+
+ UINT32 m_RepDistances[kNumRepDistances];
+
+ BYTE m_LastByteLevels[256];
+ BYTE m_LastPosLenLevels[kNumPosSlotLenSlotSymbols];
+ BYTE m_LastLenLevels[kNumLenSymbols];
+
+ UINT32 m_DictionarySizePowerOf2;
+ UINT32 m_NumPosSlots;
+ UINT32 m_NumPosLenSlots;
+
+ // bool m_i86PreprocessingUsed;
+ // UINT32 m_i86TranslationSize;
+
+ bool m_UncompressedBlock;
+ bool m_AlignIsUsed;
+
+ UINT32 m_UnCompressedBlockSize;
+
+ Ci86TranslationOutStream *m_i86TranslationOutStreamSpec;
+ CMyComPtr<ISequentialOutStream> m_i86TranslationOutStream;
+
+ BYTE m_ReservedSize;
+ UINT32 m_NumInDataBlocks;
+
+ void ReadTable(BYTE *lastLevels, BYTE *newLevels, UINT32 numSymbols);
+ void ReadTables();
+ void ClearPrevLeveles();
+
+public:
+ CDecoder();
+
+ MY_UNKNOWN_IMP
+
+ void ReleaseStreams();
+ STDMETHOD(Flush)();
+
+ // ICompressCoder interface
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress);
+
+ void SetParams(BYTE reservedSize, UINT32 numInDataBlocks,
+ UINT32 dictionarySizePowerOf2)
+ {
+ m_ReservedSize = reservedSize;
+ m_NumInDataBlocks = numInDataBlocks;
+ m_DictionarySizePowerOf2 = dictionarySizePowerOf2;
+ if (dictionarySizePowerOf2 < 20)
+ m_NumPosSlots = 30 + (dictionarySizePowerOf2 - 15) * 2;
+ else if (dictionarySizePowerOf2 == 20)
+ m_NumPosSlots = 42;
+ else
+ m_NumPosSlots = 50;
+ m_NumPosLenSlots = m_NumPosSlots * kNumLenSlots;
+ }
+};
+
+}}}
+
+#endif \ No newline at end of file
diff --git a/7zip/Archive/Cab/LZXExtConst.h b/7zip/Archive/Cab/LZXExtConst.h
new file mode 100755
index 00000000..c00dfbd9
--- /dev/null
+++ b/7zip/Archive/Cab/LZXExtConst.h
@@ -0,0 +1,31 @@
+// Archive/Cab/LZXExtConst.h
+
+#ifndef __ARCHIVE_CAB_LZXEXTCONST_H
+#define __ARCHIVE_CAB_LZXEXTCONST_H
+
+namespace NArchive {
+namespace NCab {
+namespace NLZX {
+
+const UINT32 kNumRepDistances = 3;
+
+const UINT32 kNumLenSlots = 8;
+const UINT32 kMatchMinLen = 2;
+const UINT32 kNumLenSymbols = 249;
+const UINT32 kMatchMaxLen = kMatchMinLen + (kNumLenSlots - 1) + kNumLenSymbols - 1;
+
+const BYTE kNumAlignBits = 3;
+const UINT32 kAlignTableSize = 1 << kNumAlignBits;
+
+const UINT32 kNumHuffmanBits = 16;
+
+const int kNumPosSlotSymbols = 50;
+const int kNumPosSlotLenSlotSymbols = kNumPosSlotSymbols * kNumLenSlots;
+
+const int kMaxTableSize = 256 + kNumPosSlotLenSlotSymbols;
+
+
+
+}}}
+
+#endif; \ No newline at end of file
diff --git a/7zip/Archive/Cab/LZXi86Converter.cpp b/7zip/Archive/Cab/LZXi86Converter.cpp
new file mode 100755
index 00000000..5e3e4809
--- /dev/null
+++ b/7zip/Archive/Cab/LZXi86Converter.cpp
@@ -0,0 +1,124 @@
+// Archive/Cab/LZXi86Converter.cpp
+
+#include "StdAfx.h"
+
+#include "Common/Defs.h"
+
+#include "LZXi86Converter.h"
+#include "Windows/Defs.h"
+
+namespace NArchive {
+namespace NCab {
+namespace NLZX {
+
+Ci86TranslationOutStream::Ci86TranslationOutStream():
+ m_Pos(0)
+{
+}
+
+Ci86TranslationOutStream::~Ci86TranslationOutStream()
+{
+ Flush();
+}
+
+void Ci86TranslationOutStream::Init(ISequentialOutStream *aStream,
+ bool aTranslationMode, UINT32 aTranslationSize)
+{
+ m_Stream = aStream;
+ m_TranslationMode = aTranslationMode;
+ m_TranslationSize = aTranslationSize;
+ m_ProcessedSize = 0;
+ m_Pos = 0;
+}
+
+void Ci86TranslationOutStream::ReleaseStream()
+{
+ m_Stream.Release();
+}
+
+inline INT32 Ci86TranslationOutStream::ConvertAbsoluteToOffset(INT32 aPos, INT32 anAbsoluteValue)
+{
+}
+
+static const int kResidue = 6 + 4;
+
+void Ci86TranslationOutStream::MakeTranslation()
+{
+ if (m_Pos <= kResidue)
+ return;
+ UINT32 aNumBytes = m_Pos - kResidue;
+ for (UINT32 i = 0; i < aNumBytes;)
+ {
+ if (m_Buffer[i] == 0xE8)
+ {
+ i++;
+ INT32 anAbsoluteValue = 0;
+ for(int j = 0; j < 4; j++)
+ anAbsoluteValue += UINT32(m_Buffer[i + j]) << (j * 8);
+
+ INT32 aPos = m_ProcessedSize + i - 1;
+ UINT32 anOffset;
+ if (anAbsoluteValue < -aPos || anAbsoluteValue >= INT32(m_TranslationSize))
+ {
+ }
+ else
+ {
+ anOffset = (anAbsoluteValue >= 0) ?
+ anAbsoluteValue - aPos :
+ anAbsoluteValue + m_TranslationSize;
+ for(j = 0; j < 4; j++)
+ {
+ m_Buffer[i + j] = BYTE(anOffset & 0xFF);
+ anOffset >>= 8;
+ }
+ }
+ i += 4;
+ }
+ else
+ i++;
+ }
+}
+
+STDMETHODIMP Ci86TranslationOutStream::Write(const void *aData, UINT32 aSize, UINT32 *aProcessedSize)
+{
+ if (!m_TranslationMode)
+ return m_Stream->Write(aData, aSize, aProcessedSize);
+
+ UINT32 aProcessedSizeReal = 0;
+
+ while (aProcessedSizeReal < aSize)
+ {
+ UINT32 aWriteSize = MyMin(aSize - aProcessedSizeReal, kUncompressedBlockSize - m_Pos);
+ memmove(m_Buffer + m_Pos, (const BYTE *)aData + aProcessedSizeReal, aWriteSize);
+ m_Pos += aWriteSize;
+ aProcessedSizeReal += aWriteSize;
+ if (m_Pos == kUncompressedBlockSize)
+ {
+ RINOK(Flush());
+ }
+ }
+ if (aProcessedSize != NULL)
+ *aProcessedSize = aProcessedSizeReal;
+ return S_OK;
+}
+
+STDMETHODIMP Ci86TranslationOutStream::WritePart(const void *aData, UINT32 aSize, UINT32 *aProcessedSize)
+{
+ return Write(aData, aSize, aProcessedSize);
+}
+
+HRESULT Ci86TranslationOutStream::Flush()
+{
+ if (m_Pos == 0)
+ return S_OK;
+ MakeTranslation();
+ RINOK(m_Stream->Write(m_Buffer, m_Pos, NULL));
+ m_ProcessedSize += m_Pos;
+ m_Pos = 0;
+ m_TranslationMode = (m_ProcessedSize < (1 << 30));
+ return S_OK;
+}
+
+
+}}}
+
diff --git a/7zip/Archive/Cab/LZXi86Converter.h b/7zip/Archive/Cab/LZXi86Converter.h
new file mode 100755
index 00000000..10507cdb
--- /dev/null
+++ b/7zip/Archive/Cab/LZXi86Converter.h
@@ -0,0 +1,46 @@
+// Archive/Cab/LZXi86Converter.h
+
+#pragma once
+
+#ifndef __ARCHIVE_CAB_LZXI86CONVERTER_H
+#define __ARCHIVE_CAB_LZXI86CONVERTER_H
+
+#include "Common/MyCom.h"
+#include "../../IStream.h"
+
+namespace NArchive {
+namespace NCab {
+namespace NLZX {
+
+const int kUncompressedBlockSize = 1 << 15;
+
+class Ci86TranslationOutStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ bool m_TranslationMode;
+ CMyComPtr<ISequentialOutStream> m_Stream;
+ UINT32 m_ProcessedSize;
+ BYTE m_Buffer[kUncompressedBlockSize];
+ UINT32 m_Pos;
+ UINT32 m_TranslationSize;
+
+ INT32 ConvertAbsoluteToOffset(INT32 aPos, INT32 anAbsoluteValue);
+ void MakeTranslation();
+public:
+ Ci86TranslationOutStream();
+ ~Ci86TranslationOutStream();
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *aData, UINT32 aSize, UINT32 *aProcessedSize);
+ STDMETHOD(WritePart)(const void *aData, UINT32 aSize, UINT32 *aProcessedSize);
+public:
+ void Init(ISequentialOutStream *aStream, bool aTranslationMode, UINT32 aTranslationSize);
+ HRESULT Flush();
+ void ReleaseStream();
+};
+
+}}}
+
+#endif \ No newline at end of file
diff --git a/7zip/Archive/Cab/MSZipConst.h b/7zip/Archive/Cab/MSZipConst.h
new file mode 100755
index 00000000..1a72cfe2
--- /dev/null
+++ b/7zip/Archive/Cab/MSZipConst.h
@@ -0,0 +1,94 @@
+// MSZipConst.h
+
+#pragma once
+
+#ifndef __MSZIP_CONST_H
+#define __MSZIP_CONST_H
+
+#include "MSZipExtConst.h"
+
+namespace NArchive {
+namespace NCab {
+namespace NMSZip {
+
+const UINT32 kLenTableSize = 29;
+
+const UINT32 kStaticDistTableSize = 32;
+const UINT32 kStaticLenTableSize = 31;
+
+const UINT32 kReadTableNumber = 0x100;
+const UINT32 kMatchNumber = kReadTableNumber + 1;
+
+const UINT32 kMainTableSize = kMatchNumber + kLenTableSize; //298;
+const UINT32 kStaticMainTableSize = kMatchNumber + kStaticLenTableSize; //298;
+
+const UINT32 kDistTableStart = kMainTableSize;
+
+const UINT32 kHeapTablesSizesSum = kMainTableSize + kDistTableSize;
+
+const UINT32 kLevelTableSize = 19;
+
+const UINT32 kMaxTableSize = kHeapTablesSizesSum; // test it
+const UINT32 kStaticMaxTableSize = kStaticMainTableSize + kStaticDistTableSize;
+
+const UINT32 kTableDirectLevels = 16;
+const UINT32 kTableLevelRepNumber = kTableDirectLevels;
+const UINT32 kTableLevel0Number = kTableLevelRepNumber + 1;
+const UINT32 kTableLevel0Number2 = kTableLevel0Number + 1;
+
+const UINT32 kLevelMask = 0xF;
+
+const BYTE kLenStart[kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 255};
+const BYTE kLenDirectBits[kLenTableSize] = {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
+
+
+const UINT32 kDistStart[kDistTableSize] = {0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576};
+const BYTE kDistDirectBits[kDistTableSize] = {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
+
+const BYTE kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7};
+
+const BYTE kCodeLengthAlphabetOrder[kLevelTableSize] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+const UINT32 kMatchMinLen = 3;
+const UINT32 kMatchMaxLen = kNumLenCombinations + kMatchMinLen - 1; //255 + 2; test it
+
+const int kFinalBlockFieldSize = 1;
+
+namespace NFinalBlockField
+{
+enum
+{
+ kNotFinalBlock = 0,
+ kFinalBlock = 1
+};
+}
+
+const int kBlockTypeFieldSize = 2;
+
+namespace NBlockType
+{
+ enum
+ {
+ kStored = 0,
+ kFixedHuffman = 1,
+ kDynamicHuffman = 2,
+ kReserved = 3
+ };
+}
+
+const UINT32 kDeflateNumberOfLengthCodesFieldSize = 5;
+const UINT32 kDeflateNumberOfDistanceCodesFieldSize = 5;
+const UINT32 kDeflateNumberOfLevelCodesFieldSize = 4;
+
+const UINT32 kDeflateNumberOfLitLenCodesMin = 257;
+
+const UINT32 kDeflateNumberOfDistanceCodesMin = 1;
+const UINT32 kDeflateNumberOfLevelCodesMin = 4;
+
+const UINT32 kDeflateLevelCodeFieldSize = 3;
+
+const UINT32 kDeflateStoredBlockLengthFieldSizeSize = 16;
+
+}}}
+
+#endif \ No newline at end of file
diff --git a/7zip/Archive/Cab/MSZipDecoder.cpp b/7zip/Archive/Cab/MSZipDecoder.cpp
new file mode 100755
index 00000000..92326e32
--- /dev/null
+++ b/7zip/Archive/Cab/MSZipDecoder.cpp
@@ -0,0 +1,269 @@
+// Archive/Cab/MSZipDecoder.cpp
+
+#include "StdAfx.h"
+
+#include "MSZipDecoder.h"
+#include "MSZipConst.h"
+
+#include "Windows/Defs.h"
+
+namespace NArchive {
+namespace NCab {
+namespace NMSZip {
+
+CDecoder::CDecoder():
+ m_MainDecoder(kStaticMainTableSize),
+ m_DistDecoder(kStaticDistTableSize),
+ m_LevelDecoder(kLevelTableSize)
+{
+ m_OutWindowStream.Create(kHistorySize);
+}
+
+HRESULT CDecoder::Flush()
+{
+ return m_OutWindowStream.Flush();
+}
+
+/*
+void CDecoder::ReleaseStreams()
+{
+ m_OutWindowStream.ReleaseStream();
+ m_InBitStream.ReleaseStream();
+}
+*/
+
+void CDecoder::DeCodeLevelTable(BYTE *newLevels, int numLevels)
+{
+ int i = 0;
+ while (i < numLevels)
+ {
+ UINT32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
+ if (number < kTableDirectLevels)
+ newLevels[i++] = BYTE(number);
+ else
+ {
+ if (number == kTableLevelRepNumber)
+ {
+ int t = m_InBitStream.ReadBits(2) + 3;
+ for (int reps = t; reps > 0 && i < numLevels ; reps--, i++)
+ newLevels[i] = newLevels[i - 1];
+ }
+ else
+ {
+ int num;
+ if (number == kTableLevel0Number)
+ num = m_InBitStream.ReadBits(3) + 3;
+ else
+ num = m_InBitStream.ReadBits(7) + 11;
+ for (;num > 0 && i < numLevels; num--)
+ newLevels[i++] = 0;
+ }
+ }
+ }
+}
+
+void CDecoder::ReadTables(void)
+{
+ if(m_FinalBlock) // test it
+ throw CDecoderException(CDecoderException::kData);
+
+ m_FinalBlock = (m_InBitStream.ReadBits(kFinalBlockFieldSize) == NFinalBlockField::kFinalBlock);
+
+ int blockType = m_InBitStream.ReadBits(kBlockTypeFieldSize);
+
+ switch(blockType)
+ {
+ case NBlockType::kStored:
+ {
+ m_StoredMode = true;
+ UINT32 currentBitPosition = m_InBitStream.GetBitPosition();
+ UINT32 numBitsForAlign = currentBitPosition > 0 ? (8 - currentBitPosition): 0;
+ if (numBitsForAlign > 0)
+ m_InBitStream.ReadBits(numBitsForAlign);
+ m_StoredBlockSize = m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize);
+ WORD onesComplementReverse = ~WORD(m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize));
+ if (m_StoredBlockSize != onesComplementReverse)
+ throw CDecoderException(CDecoderException::kData);
+ break;
+ }
+ case NBlockType::kFixedHuffman:
+ case NBlockType::kDynamicHuffman:
+ {
+ m_StoredMode = false;
+ BYTE litLenLevels[kStaticMainTableSize];
+ BYTE distLevels[kStaticDistTableSize];
+ if (blockType == NBlockType::kFixedHuffman)
+ {
+ int i;
+
+ // Leteral / length levels
+ for (i = 0; i < 144; i++)
+ litLenLevels[i] = 8;
+ for (; i < 256; i++)
+ litLenLevels[i] = 9;
+ for (; i < 280; i++)
+ litLenLevels[i] = 7;
+ for (; i < 288; i++) /* make a complete, but wrong code set */
+ litLenLevels[i] = 8;
+
+ // Distance levels
+ for (i = 0; i < kStaticDistTableSize; i++) // test it: infozip only use kDistTableSize
+ distLevels[i] = 5;
+ }
+ else // in case when (blockType == kDeflateBlockTypeFixedHuffman)
+ {
+ int numLitLenLevels = m_InBitStream.ReadBits(kDeflateNumberOfLengthCodesFieldSize) +
+ kDeflateNumberOfLitLenCodesMin;
+ int numDistLevels = m_InBitStream.ReadBits(kDeflateNumberOfDistanceCodesFieldSize) +
+ kDeflateNumberOfDistanceCodesMin;
+ int numLevelCodes = m_InBitStream.ReadBits(kDeflateNumberOfLevelCodesFieldSize) +
+ kDeflateNumberOfLevelCodesMin;
+
+ int numLevels;
+ numLevels = kHeapTablesSizesSum;
+
+ BYTE levelLevels[kLevelTableSize];
+ int i;
+ for (i = 0; i < kLevelTableSize; i++)
+ {
+ int position = kCodeLengthAlphabetOrder[i];
+ if(i < numLevelCodes)
+ levelLevels[position] = BYTE(m_InBitStream.ReadBits(kDeflateLevelCodeFieldSize));
+ else
+ levelLevels[position] = 0;
+ }
+
+ try
+ {
+ m_LevelDecoder.SetCodeLengths(levelLevels);
+ }
+ catch(...)
+ {
+ throw CDecoderException(CDecoderException::kData);
+ }
+
+ BYTE tmpLevels[kStaticMaxTableSize];
+ DeCodeLevelTable(tmpLevels, numLitLenLevels + numDistLevels);
+
+ memmove(litLenLevels, tmpLevels, numLitLenLevels);
+ memset(litLenLevels + numLitLenLevels, 0,
+ kStaticMainTableSize - numLitLenLevels);
+
+ memmove(distLevels, tmpLevels + numLitLenLevels, numDistLevels);
+ memset(distLevels + numDistLevels, 0, kStaticDistTableSize - numDistLevels);
+ }
+ try
+ {
+ m_MainDecoder.SetCodeLengths(litLenLevels);
+ m_DistDecoder.SetCodeLengths(distLevels);
+ }
+ catch(...)
+ {
+ throw CDecoderException(CDecoderException::kData);
+ }
+ break;
+ }
+ default:
+ throw CDecoderException(CDecoderException::kData);
+ }
+}
+
+class CCoderReleaser
+{
+ CDecoder *m_Coder;
+public:
+ CCoderReleaser(CDecoder *aCoder): m_Coder(aCoder) {}
+ ~CCoderReleaser()
+ {
+ m_Coder->Flush();
+ // m_Coder->ReleaseStreams();
+ }
+};
+
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ if (outSize == NULL)
+ return E_INVALIDARG;
+ UINT64 size = *outSize;
+
+ m_OutWindowStream.Init(outStream, false);
+ m_InBitStream.InitMain(inStream, m_ReservedSize, m_NumInDataBlocks);
+ CCoderReleaser coderReleaser(this);
+
+ UINT64 nowPos = 0;
+ while(nowPos < size)
+ {
+ if (progress != NULL)
+ {
+ UINT64 packSize = m_InBitStream.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&packSize, &nowPos));
+ }
+ UINT32 uncompressedCFDataBlockSize;
+ bool dataAreCorrect;
+ RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect));
+ if (!dataAreCorrect)
+ {
+ throw "Data Error";
+ }
+ m_InBitStream.Init();
+ if (m_InBitStream.ReadBits(8) != 0x43)
+ throw CDecoderException(CDecoderException::kData);
+ if (m_InBitStream.ReadBits(8) != 0x4B)
+ throw CDecoderException(CDecoderException::kData);
+ UINT32 uncompressedCFDataCurrentValue = 0;
+ m_FinalBlock = false;
+ while (uncompressedCFDataCurrentValue < uncompressedCFDataBlockSize)
+ {
+ ReadTables();
+ if(m_StoredMode)
+ {
+ for (UINT32 i = 0; i < m_StoredBlockSize; i++)
+ m_OutWindowStream.PutOneByte(BYTE(m_InBitStream.ReadBits(8)));
+ nowPos += m_StoredBlockSize;
+ uncompressedCFDataCurrentValue += m_StoredBlockSize;
+ continue;
+ }
+ while(true)
+ {
+ UINT32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
+
+ if (number < 256)
+ {
+ m_OutWindowStream.PutOneByte(BYTE(number));
+ nowPos++;
+ uncompressedCFDataCurrentValue++;
+ continue;
+ }
+ else if (number >= kMatchNumber)
+ {
+ number -= kMatchNumber;
+ UINT32 length = UINT32(kLenStart[number]) + kMatchMinLen;
+ UINT32 numBits;
+ if ((numBits = kLenDirectBits[number]) > 0)
+ length += m_InBitStream.ReadBits(numBits);
+
+ number = m_DistDecoder.DecodeSymbol(&m_InBitStream);
+ UINT32 distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]);
+ /*
+ if (distance >= nowPos)
+ throw "data error";
+ */
+ m_OutWindowStream.CopyBackBlock(distance, length);
+ nowPos += length;
+ uncompressedCFDataCurrentValue += length;
+ }
+ else if (number == kReadTableNumber)
+ {
+ break;
+ }
+ else
+ throw CDecoderException(CDecoderException::kData);
+ }
+ }
+ }
+ return S_OK;
+}
+
+}}}
diff --git a/7zip/Archive/Cab/MSZipDecoder.h b/7zip/Archive/Cab/MSZipDecoder.h
new file mode 100755
index 00000000..2fa40df0
--- /dev/null
+++ b/7zip/Archive/Cab/MSZipDecoder.h
@@ -0,0 +1,88 @@
+// Archive/Cab/MSZipDecoder.h
+
+#pragma once
+
+#ifndef __ARCHIVE_CAB_DECODER_H
+#define __ARCHIVE_CAB_DECODER_H
+
+#include "Common/MyCom.h"
+#include "../../ICoder.h"
+#include "../../Common/LSBFDecoder.h"
+#include "../../Compress/Huffman/HuffmanDecoder.h"
+#include "../../Compress/LZ/LZOutWindow.h"
+
+#include "CabInBuffer.h"
+#include "MSZipExtConst.h"
+
+namespace NArchive {
+namespace NCab {
+namespace NMSZip {
+
+class CDecoderException
+{
+public:
+ enum ECauseType
+ {
+ kData
+ } m_Cause;
+ CDecoderException(ECauseType aCause): m_Cause(aCause) {}
+};
+
+class CMSZipBitDecoder: public NStream::NLSBF::CDecoder<NCab::CInBuffer>
+{
+public:
+ void InitMain(ISequentialInStream *aStream, BYTE aReservedSize, UINT32 aNumBlocks)
+ {
+ m_Stream.Init(aStream, aReservedSize, aNumBlocks);
+ Init();
+ }
+ HRESULT ReadBlock(UINT32 &anUncompressedSize, bool &aDataAreCorrect)
+ {
+ return m_Stream.ReadBlock(anUncompressedSize, aDataAreCorrect);
+ }
+};
+
+typedef NCompress::NHuffman::CDecoder<kNumHuffmanBits> CHuffmanDecoder;
+
+class CDecoder :
+ public ICompressCoder,
+ public CMyUnknownImp
+{
+ CLZOutWindow m_OutWindowStream;
+ CMSZipBitDecoder m_InBitStream;
+ CHuffmanDecoder m_MainDecoder;
+ CHuffmanDecoder m_DistDecoder;
+ CHuffmanDecoder m_LevelDecoder; // table for decoding other tables;
+
+ bool m_FinalBlock;
+ bool m_StoredMode;
+ UINT32 m_StoredBlockSize;
+
+ BYTE m_ReservedSize;
+ UINT32 m_NumInDataBlocks;
+
+ void DeCodeLevelTable(BYTE *newLevels, int numLevels);
+ void ReadTables();
+public:
+ CDecoder();
+
+ MY_UNKNOWN_IMP
+
+ HRESULT Flush();
+ // void ReleaseStreams();
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress);
+
+ void SetParams(BYTE aReservedSize, UINT32 aNumInDataBlocks)
+ {
+ m_ReservedSize = aReservedSize;
+ m_NumInDataBlocks = aNumInDataBlocks;
+ }
+
+};
+
+}}}
+
+#endif \ No newline at end of file
diff --git a/7zip/Archive/Cab/MSZipExtConst.h b/7zip/Archive/Cab/MSZipExtConst.h
new file mode 100755
index 00000000..864d9eda
--- /dev/null
+++ b/7zip/Archive/Cab/MSZipExtConst.h
@@ -0,0 +1,22 @@
+// DeflateExtConst.h
+
+#pragma once
+
+#ifndef __DEFLATEEXTCONST_H
+#define __DEFLATEEXTCONST_H
+
+#include "Common/Types.h"
+
+namespace NArchive {
+namespace NCab {
+namespace NMSZip {
+
+ const UINT32 kDistTableSize = 30;
+ const UINT32 kHistorySize = 0x8000;
+ const UINT32 kNumLenCombinations = 256;
+
+ const UINT32 kNumHuffmanBits = 15;
+
+}}}
+
+#endif
diff --git a/7zip/Archive/Cab/StdAfx.cpp b/7zip/Archive/Cab/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Archive/Cab/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Archive/Cab/StdAfx.h b/7zip/Archive/Cab/StdAfx.h
new file mode 100755
index 00000000..6075e527
--- /dev/null
+++ b/7zip/Archive/Cab/StdAfx.h
@@ -0,0 +1,9 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+#include <time.h>
+
+#endif
diff --git a/7zip/Archive/Cab/cab.ico b/7zip/Archive/Cab/cab.ico
new file mode 100755
index 00000000..cc2007fc
--- /dev/null
+++ b/7zip/Archive/Cab/cab.ico
Binary files differ
diff --git a/7zip/Archive/Cab/resource.h b/7zip/Archive/Cab/resource.h
new file mode 100755
index 00000000..7b0dd8ff
--- /dev/null
+++ b/7zip/Archive/Cab/resource.h
@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDI_ICON1 101
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Archive/Cab/resource.rc b/7zip/Archive/Cab/resource.rc
new file mode 100755
index 00000000..872aa57d
--- /dev/null
+++ b/7zip/Archive/Cab/resource.rc
@@ -0,0 +1,130 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,12,0,0
+ PRODUCTVERSION 3,12,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov \0"
+ VALUE "FileDescription", "Cab Plugin for 7-Zip\0"
+ VALUE "FileVersion", "3, 12, 0, 0\0"
+ VALUE "InternalName", "cab\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "cab.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 12, 0, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1 ICON DISCARDABLE "cab.ico"
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Archive/Common/CodecsPath.cpp b/7zip/Archive/Common/CodecsPath.cpp
new file mode 100755
index 00000000..d2d27ed3
--- /dev/null
+++ b/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('\\'));
+ return path.Left(pos + 1);
+}
+
+CSysString GetBaseFolderPrefix()
+{
+ CSysString libPrefix = GetLibraryFolderPrefix();
+ CSysString temp = libPrefix;
+ temp.Delete(temp.Length() - 1);
+ int pos = temp.ReverseFind(TEXT('\\'));
+ return temp.Left(pos + 1);
+}
+
+CSysString GetCodecsFolderPrefix()
+{
+ return GetBaseFolderPrefix() + TEXT("Codecs\\");
+}
diff --git a/7zip/Archive/Common/CodecsPath.h b/7zip/Archive/Common/CodecsPath.h
new file mode 100755
index 00000000..d0fe7351
--- /dev/null
+++ b/7zip/Archive/Common/CodecsPath.h
@@ -0,0 +1,14 @@
+// CodecsPath.h
+
+#pragma once
+
+#ifndef __CODECSPATH_H
+#define __CODECSPATH_H
+
+#include "../../../Common/String.h"
+
+CSysString GetBaseFolderPrefix();
+CSysString GetCodecsFolderPrefix();
+
+#endif
+
diff --git a/7zip/Archive/Common/CoderLoader.h b/7zip/Archive/Common/CoderLoader.h
new file mode 100755
index 00000000..397c4798
--- /dev/null
+++ b/7zip/Archive/Common/CoderLoader.h
@@ -0,0 +1,108 @@
+// CoderLoader.h
+
+#pragma once
+
+#ifndef __CODERLOADER_H
+#define __CODERLOADER_H
+
+#include "../../../Common/String.h"
+#include "../../../Windows/DLL.h"
+// #include "../../../Windows/Defs.h"
+#include "../../ICoder.h"
+
+typedef UINT32 (WINAPI * CreateObjectPointer)(
+ const GUID *clsID,
+ const GUID *interfaceID,
+ void **outObject);
+
+class CCoderLibrary: public NWindows::NDLL::CLibrary
+{
+public:
+ HRESULT CreateCoder(REFGUID clsID, ICompressCoder **coder)
+ {
+ CreateObjectPointer createObject = (CreateObjectPointer)
+ GetProcAddress("CreateObject");
+ if (createObject == NULL)
+ return GetLastError();
+ return createObject(&clsID, &IID_ICompressCoder, (void **)coder);
+ }
+ 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 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.CollateNoCase(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 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/7zip/Archive/Common/CoderMixer.cpp b/7zip/Archive/Common/CoderMixer.cpp
new file mode 100755
index 00000000..f18feafd
--- /dev/null
+++ b/7zip/Archive/Common/CoderMixer.cpp
@@ -0,0 +1,238 @@
+// CoderMixer.cpp
+
+#include "StdAfx.h"
+
+#include "CoderMixer.h"
+#include "Common/Defs.h"
+#include "CrossThreadProgress.h"
+
+using namespace NWindows;
+using namespace NSynchronization;
+
+//////////////////////////
+// CThreadCoderInfo
+
+void CThreadCoderInfo::CreateEvents()
+{
+ CompressEvent = new CAutoResetEvent(false);
+ CompressionCompletedEvent = new CAutoResetEvent(false);
+}
+
+CThreadCoderInfo::~CThreadCoderInfo()
+{
+ if (CompressEvent != NULL)
+ delete CompressEvent;
+ if (CompressionCompletedEvent != NULL)
+ delete CompressionCompletedEvent;
+}
+
+class CCoderInfoFlusher
+{
+ CThreadCoderInfo *m_CoderInfo;
+public:
+ CCoderInfoFlusher(CThreadCoderInfo *coderInfo): m_CoderInfo(coderInfo) {}
+ ~CCoderInfoFlusher()
+ {
+ m_CoderInfo->InStream.Release();
+ m_CoderInfo->OutStream.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;
+
+ {
+ CCoderInfoFlusher coderInfoFlusher(this);
+ Result = Coder->Code(InStream, OutStream,
+ InSizeAssigned ? &InSizeValue : NULL,
+ OutSizeAssigned ? &OutSizeValue : NULL,
+ Progress);
+ }
+ return true;
+}
+
+
+DWORD WINAPI CoderThread(void *threadCoderInfo)
+{
+ while(true)
+ {
+ if (!((CThreadCoderInfo *)threadCoderInfo)->WaitAndCode())
+ return 0;
+ }
+}
+
+//////////////////////////
+// CCoderMixer
+
+static DWORD WINAPI MainCoderThread(void *threadCoderInfo)
+{
+ while(true)
+ {
+ if (!((CCoderMixer *)threadCoderInfo)->MyCode())
+ return 0;
+ }
+}
+
+CCoderMixer::CCoderMixer()
+{
+ if (!m_MainThread.Create(MainCoderThread, this))
+ throw 271825;
+}
+
+CCoderMixer::~CCoderMixer()
+{
+ ExitEvent.Set();
+ ::WaitForSingleObject(m_MainThread, INFINITE);
+ DWORD result = ::WaitForMultipleObjects(m_Threads.Size(),
+ &m_Threads.Front(), TRUE, INFINITE);
+ for(int i = 0; i < m_Threads.Size(); i++)
+ ::CloseHandle(m_Threads[i]);
+}
+
+
+void CCoderMixer::AddCoder(ICompressCoder *coder)
+{
+ CThreadCoderInfo threadCoderInfo;
+ threadCoderInfo.Coder = coder;
+ m_CoderInfoVector.Add(threadCoderInfo);
+ m_CoderInfoVector.Back().CreateEvents();
+ m_CoderInfoVector.Back().ExitEvent = ExitEvent;
+ m_CompressingCompletedEvents.Add(*m_CoderInfoVector.Back().CompressionCompletedEvent);
+}
+
+void CCoderMixer::FinishAddingCoders()
+{
+ for(int i = 0; i < m_CoderInfoVector.Size(); i++)
+ {
+ DWORD id;
+ HANDLE newThread = ::CreateThread(NULL, 0, CoderThread,
+ &m_CoderInfoVector[i], 0, &id);
+ if (newThread == 0)
+ throw 271824;
+ m_Threads.Add(newThread);
+ if (i >= 1)
+ {
+ CStreamBinder streamBinder;
+ m_StreamBinders.Add(streamBinder);
+ m_StreamBinders.Back().CreateEvents();
+ }
+ }
+}
+
+void CCoderMixer::ReInit()
+{
+ int i;
+ for(i = 0; i < m_CoderInfoVector.Size(); i++)
+ {
+ CThreadCoderInfo &coderInfo = m_CoderInfoVector[i];
+ coderInfo.InSizeAssigned = false;
+ coderInfo.OutSizeAssigned = false;
+ coderInfo.Progress = NULL;
+ }
+ for(i = 0; i < m_StreamBinders.Size(); i++)
+ {
+ m_StreamBinders[i].ReInit();
+ }
+}
+
+void CCoderMixer::SetCoderInfo(UINT32 coderIndex, const UINT64 *inSize,
+ const UINT64 *outSize)
+{
+ CThreadCoderInfo &coderInfo = m_CoderInfoVector[coderIndex];
+
+ coderInfo.InSizeAssigned = (inSize != NULL);
+ if (coderInfo.InSizeAssigned)
+ coderInfo.InSizeValue = *inSize;
+
+ coderInfo.OutSizeAssigned = (outSize != NULL);
+ if (coderInfo.OutSizeAssigned)
+ coderInfo.OutSizeValue = *outSize;
+
+ coderInfo.Progress = NULL;
+}
+
+STDMETHODIMP CCoderMixer::Init(ISequentialInStream *inStreamMain,
+ ISequentialOutStream *outStreamMain)
+{
+ m_CoderInfoVector.Front().InStream = inStreamMain;
+ for(int i = 0; i < m_StreamBinders.Size(); i++)
+ m_StreamBinders[i].CreateStreams(&m_CoderInfoVector[i+1].InStream,
+ &m_CoderInfoVector[i].OutStream);
+ m_CoderInfoVector.Back().OutStream = outStreamMain;
+
+ return S_OK;
+}
+
+bool CCoderMixer::MyCode()
+{
+ HANDLE events[2] = { ExitEvent, m_StartCompressingEvent };
+ DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
+ if (waitResult == WAIT_OBJECT_0 + 0)
+ return false;
+
+ for(int i = 0; i < m_CoderInfoVector.Size(); i++)
+ m_CoderInfoVector[i].CompressEvent->Set();
+ DWORD result = ::WaitForMultipleObjects(m_CompressingCompletedEvents.Size(),
+ &m_CompressingCompletedEvents.Front(), TRUE, INFINITE);
+
+ m_CompressingFinishedEvent.Set();
+
+ return true;
+}
+
+STDMETHODIMP CCoderMixer::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ Init(inStream, outStream);
+
+ m_CompressingFinishedEvent.Reset(); // ?
+
+ CCrossThreadProgress *progressSpec = new CCrossThreadProgress;
+ CMyComPtr<ICompressProgressInfo> crossProgress = progressSpec;
+ progressSpec->Init();
+ m_CoderInfoVector[m_ProgressCoderIndex].Progress = crossProgress;
+
+ m_StartCompressingEvent.Set();
+
+ while (true)
+ {
+ HANDLE events[2] = {m_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 < m_CoderInfoVector.Size(); i++)
+ {
+ HRESULT result = m_CoderInfoVector[i].Result;
+ if (result == S_FALSE)
+ return result;
+ }
+ for(i = 0; i < m_CoderInfoVector.Size(); i++)
+ {
+ HRESULT result = m_CoderInfoVector[i].Result;
+ if (result != S_OK)
+ return result;
+ }
+ return S_OK;
+}
+
+UINT64 CCoderMixer::GetWriteProcessedSize(UINT32 coderIndex)
+{
+ return m_StreamBinders[coderIndex].ProcessedSize;
+}
+
diff --git a/7zip/Archive/Common/CoderMixer.h b/7zip/Archive/Common/CoderMixer.h
new file mode 100755
index 00000000..7851206c
--- /dev/null
+++ b/7zip/Archive/Common/CoderMixer.h
@@ -0,0 +1,87 @@
+// CoderMixer.h
+
+#pragma once
+
+#ifndef __CODERMIXER_H
+#define __CODERMIXER_H
+
+#include "Common/Vector.h"
+#include "Common/MyCom.h"
+#include "Windows/Thread.h"
+#include "../../Common/StreamBinder.h"
+#include "../../ICoder.h"
+
+struct CThreadCoderInfo
+{
+ NWindows::NSynchronization::CAutoResetEvent *CompressEvent;
+ HANDLE ExitEvent;
+ NWindows::NSynchronization::CAutoResetEvent *CompressionCompletedEvent;
+
+ CMyComPtr<ICompressCoder> Coder;
+ CMyComPtr<ISequentialInStream> InStream;
+ CMyComPtr<ISequentialOutStream> OutStream;
+ UINT64 InSizeValue;
+ UINT64 OutSizeValue;
+ bool InSizeAssigned;
+ bool OutSizeAssigned;
+ ICompressProgressInfo *Progress;
+ HRESULT Result;
+
+ CThreadCoderInfo(): ExitEvent(NULL), CompressEvent(NULL),
+ CompressionCompletedEvent(NULL),
+ InSizeAssigned(false),
+ OutSizeAssigned(false), Progress(NULL){}
+ ~CThreadCoderInfo();
+ bool WaitAndCode();
+ void CreateEvents();
+};
+
+
+class CCoderMixer:
+ public ICompressCoder,
+ public CMyUnknownImp
+{
+ MY_UNKNOWN_IMP
+
+public:
+ STDMETHOD(Init)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream);
+ // STDMETHOD(ReleaseStreams)();
+ // STDMETHOD(Code)(UINT32 size, UINT32 &processedSize);
+ // STDMETHOD(Flush)();
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress);
+
+
+ CCoderMixer();
+ ~CCoderMixer();
+ void AddCoder(ICompressCoder *aCoder);
+ void FinishAddingCoders();
+
+ void ReInit();
+ void SetCoderInfo(UINT32 coderIndex,
+ const UINT64 *inSize, const UINT64 *outSize);
+ void SetProgressCoderIndex(UINT32 coderIndex)
+ { m_ProgressCoderIndex = coderIndex; }
+ UINT64 GetWriteProcessedSize(UINT32 coderIndex);
+
+ bool MyCode();
+private:
+ CObjectVector<CStreamBinder> m_StreamBinders;
+ CObjectVector<CThreadCoderInfo> m_CoderInfoVector;
+ CRecordVector<HANDLE> m_Threads;
+ NWindows::CThread m_MainThread;
+
+ NWindows::NSynchronization::CAutoResetEvent m_StartCompressingEvent;
+ CRecordVector<HANDLE> m_CompressingCompletedEvents;
+ NWindows::NSynchronization::CAutoResetEvent m_CompressingFinishedEvent;
+
+ NWindows::NSynchronization::CManualResetEvent ExitEvent;
+ UINT32 m_ProgressCoderIndex;
+};
+
+#endif
+
diff --git a/7zip/Archive/Common/CoderMixer2.cpp b/7zip/Archive/Common/CoderMixer2.cpp
new file mode 100755
index 00000000..6bd57375
--- /dev/null
+++ b/7zip/Archive/Common/CoderMixer2.cpp
@@ -0,0 +1,448 @@
+// CoderMixer2.cpp
+
+#include "StdAfx.h"
+
+#include "CoderMixer2.h"
+#include "CrossThreadProgress.h"
+
+using namespace NWindows;
+using namespace NSynchronization;
+
+//////////////////////////
+// CThreadCoderInfo2
+
+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]]);
+}
+
+
+CThreadCoderInfo2::CThreadCoderInfo2(UINT32 numInStreams, UINT32 numOutStreams):
+ ExitEvent(NULL),
+ CompressEvent(NULL),
+ CompressionCompletedEvent(NULL),
+ NumInStreams(numInStreams),
+ NumOutStreams(numOutStreams)
+{
+ InStreams.Reserve(NumInStreams);
+ InStreamPointers.Reserve(NumInStreams);
+ InSizes.Reserve(NumInStreams);
+ InSizePointers.Reserve(NumInStreams);
+ OutStreams.Reserve(NumOutStreams);
+ OutStreamPointers.Reserve(NumOutStreams);
+ OutSizes.Reserve(NumOutStreams);
+ OutSizePointers.Reserve(NumOutStreams);
+}
+
+void CThreadCoderInfo2::CreateEvents()
+{
+ CompressEvent = new CAutoResetEvent(false);
+ CompressionCompletedEvent = new CAutoResetEvent(false);
+}
+
+CThreadCoderInfo2::~CThreadCoderInfo2()
+{
+ if (CompressEvent != NULL)
+ delete CompressEvent;
+ if (CompressionCompletedEvent != NULL)
+ delete CompressionCompletedEvent;
+}
+
+class CCoderInfoFlusher2
+{
+ CThreadCoderInfo2 *m_CoderInfo;
+public:
+ CCoderInfoFlusher2(CThreadCoderInfo2 *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 CThreadCoderInfo2::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 (CompressorIsCoder2)
+ Result = Coder2->Code(&InStreamPointers.Front(),
+ &InSizePointers.Front(),
+ NumInStreams,
+ &OutStreamPointers.Front(),
+ &OutSizePointers.Front(),
+ NumOutStreams,
+ Progress);
+ else
+ Result = Coder->Code(InStreamPointers[0],
+ OutStreamPointers[0],
+ InSizePointers[0],
+ OutSizePointers[0],
+ Progress);
+ }
+ return true;
+}
+
+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 CThreadCoderInfo2::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)
+{
+ while(true)
+ {
+ if (!((CThreadCoderInfo2 *)threadCoderInfo)->WaitAndCode())
+ return 0;
+ }
+}
+
+//////////////////////////////////////
+// CCoderMixer2
+
+static DWORD WINAPI MainCoderThread(void *threadCoderInfo)
+{
+ while(true)
+ {
+ if (!((CCoderMixer2 *)threadCoderInfo)->MyCode())
+ return 0;
+ }
+}
+
+CCoderMixer2::CCoderMixer2()
+{
+ if (!_mainThread.Create(MainCoderThread, this))
+ throw 271825;
+}
+
+CCoderMixer2::~CCoderMixer2()
+{
+ _exitEvent.Set();
+
+ ::WaitForSingleObject(_mainThread, INFINITE);
+ DWORD result = ::WaitForMultipleObjects(_threads.Size(),
+ &_threads.Front(), TRUE, INFINITE);
+ for(int i = 0; i < _threads.Size(); i++)
+ ::CloseHandle(_threads[i]);
+}
+
+void CCoderMixer2::SetBindInfo(const CBindInfo &bindInfo)
+{
+ _bindInfo = bindInfo;
+ _streamBinders.Clear();
+ for(int i = 0; i < _bindInfo.BindPairs.Size(); i++)
+ {
+ _streamBinders.Add(CStreamBinder());
+ _streamBinders.Back().CreateEvents();
+ }
+}
+
+void CCoderMixer2::AddCoderCommon()
+{
+ int index = _coderInfoVector.Size();
+ const CCoderStreamsInfo &CoderStreamsInfo = _bindInfo.Coders[index];
+
+ CThreadCoderInfo2 threadCoderInfo(CoderStreamsInfo.NumInStreams,
+ CoderStreamsInfo.NumOutStreams);
+ _coderInfoVector.Add(threadCoderInfo);
+ _coderInfoVector.Back().CreateEvents();
+ _coderInfoVector.Back().ExitEvent = _exitEvent;
+ _compressingCompletedEvents.Add(*_coderInfoVector.Back().CompressionCompletedEvent);
+
+ DWORD id;
+ HANDLE newThread = ::CreateThread(NULL, 0, CoderThread,
+ &_coderInfoVector.Back(), 0, &id);
+ if (newThread == 0)
+ throw 271824;
+ _threads.Add(newThread);
+}
+
+void CCoderMixer2::AddCoder(ICompressCoder *coder)
+{
+ AddCoderCommon();
+ _coderInfoVector.Back().CompressorIsCoder2 = false;
+ _coderInfoVector.Back().Coder = coder;
+}
+
+void CCoderMixer2::AddCoder2(ICompressCoder2 *coder)
+{
+ AddCoderCommon();
+ _coderInfoVector.Back().CompressorIsCoder2 = true;
+ _coderInfoVector.Back().Coder2 = coder;
+}
+
+/*
+void CCoderMixer2::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 CCoderMixer2::ReInit()
+{
+ for(int i = 0; i < _streamBinders.Size(); i++)
+ _streamBinders[i].ReInit();
+}
+
+
+STDMETHODIMP CCoderMixer2::Init(ISequentialInStream **inStreams,
+ ISequentialOutStream **outStreams)
+{
+ if (_coderInfoVector.Size() != _bindInfo.Coders.Size())
+ throw 0;
+ UINT32 numInStreams = 0, numOutStreams = 0;
+ int i;
+ for(i = 0; i < _coderInfoVector.Size(); i++)
+ {
+ CThreadCoderInfo2 &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 CCoderMixer2::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 CCoderMixer2::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();
+
+
+ while (true)
+ {
+ 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 CCoderMixer2::GetWriteProcessedSize(UINT32 binderIndex) const
+{
+ return _streamBinders[binderIndex].ProcessedSize;
+}
+
+}
diff --git a/7zip/Archive/Common/CoderMixer2.h b/7zip/Archive/Common/CoderMixer2.h
new file mode 100755
index 00000000..ce1a0db7
--- /dev/null
+++ b/7zip/Archive/Common/CoderMixer2.h
@@ -0,0 +1,254 @@
+// CoderMixer2.h
+
+#pragma once
+
+#ifndef __CODERMIXER2_H
+#define __CODERMIXER2_H
+
+#include "../../../Common/Vector.h"
+#include "../../../Common/MyCom.h"
+#include "../../../Windows/Thread.h"
+#include "../../Common/StreamBinder.h"
+#include "../../ICoder.h"
+
+// #include "../../../Compress/Interface/CompressInterface.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;
+
+ 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;
+ const 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);
+};
+
+// CreateEvents();
+// {
+// SetCoderInfo()
+// Init Streams
+// set CompressEvent()
+// wait CompressionCompletedEvent
+// }
+
+struct CThreadCoderInfo2
+{
+ NWindows::NSynchronization::CAutoResetEvent *CompressEvent;
+ HANDLE ExitEvent;
+ NWindows::NSynchronization::CAutoResetEvent *CompressionCompletedEvent;
+
+ bool CompressorIsCoder2;
+ CMyComPtr<ICompressCoder> Coder;
+ CMyComPtr<ICompressCoder2> Coder2;
+ UINT32 NumInStreams;
+ UINT32 NumOutStreams;
+
+ CObjectVector< CMyComPtr<ISequentialInStream> > InStreams;
+ CObjectVector< CMyComPtr<ISequentialOutStream> > OutStreams;
+ CRecordVector<ISequentialInStream *> InStreamPointers;
+ CRecordVector<ISequentialOutStream *> OutStreamPointers;
+ CRecordVector<UINT64> InSizes;
+ CRecordVector<UINT64> OutSizes;
+ CRecordVector<const UINT64 *> InSizePointers;
+ CRecordVector<const UINT64 *> OutSizePointers;
+
+ CMyComPtr<ICompressProgressInfo> Progress; // CMyComPtr
+ HRESULT Result;
+
+ CThreadCoderInfo2(UINT32 numInStreams, UINT32 numOutStreams);
+ void SetCoderInfo(const UINT64 **inSizes,
+ const UINT64 **outSizes, ICompressProgressInfo *progress);
+ ~CThreadCoderInfo2();
+ bool WaitAndCode();
+ void CreateEvents();
+};
+
+
+// SetBindInfo()
+// for each coder
+// {
+// AddCoder[2]()
+// }
+//
+// for each file
+// {
+// ReInit()
+// for each coder
+// {
+// SetCoderInfo
+// }
+// SetProgressIndex(UINT32 coderIndex);
+// Code
+// }
+
+
+class CCoderMixer2:
+ public ICompressCoder2,
+ 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);
+
+
+ CCoderMixer2();
+ ~CCoderMixer2();
+ void AddCoderCommon();
+ void AddCoder(ICompressCoder *coder);
+ void AddCoder2(ICompressCoder2 *coder);
+
+ void ReInit();
+ void SetCoderInfo(UINT32 coderIndex, const UINT64 **anInSize, const UINT64 **outSize)
+ { _coderInfoVector[coderIndex].SetCoderInfo(anInSize, outSize, NULL); }
+ void SetProgressCoderIndex(UINT32 coderIndex)
+ { _progressCoderIndex = coderIndex; }
+
+
+ UINT64 GetWriteProcessedSize(UINT32 binderIndex) const;
+
+
+ bool MyCode();
+
+private:
+ CBindInfo _bindInfo;
+ CObjectVector<CStreamBinder> _streamBinders;
+ CObjectVector<CThreadCoderInfo2> _coderInfoVector;
+ CRecordVector<HANDLE> _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/7zip/Archive/Common/CoderPaths.cpp b/7zip/Archive/Common/CoderPaths.cpp
new file mode 100755
index 00000000..d2e75de6
--- /dev/null
+++ b/7zip/Archive/Common/CoderPaths.cpp
@@ -0,0 +1,34 @@
+// CodersPath.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('\\'));
+ return path.Left(pos + 1);
+}
+
+CSysString GetBaseFolderPrefix()
+{
+ CSysString libPrefix = GetLibraryFolderPrefix();
+ CSysString temp = libPrefix;
+ temp.Delete(temp.Length() - 1);
+ int pos = temp.ReverseFind(TEXT('\\'));
+ return temp.Left(pos + 1);
+}
+
+CSysString GetCodecsFolderPrefix()
+{
+ return GetBaseFolderPrefix() + TEXT("Compress\\");
+}
diff --git a/7zip/Archive/Common/CrossThreadProgress.cpp b/7zip/Archive/Common/CrossThreadProgress.cpp
new file mode 100755
index 00000000..ad4e8960
--- /dev/null
+++ b/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/7zip/Archive/Common/CrossThreadProgress.h b/7zip/Archive/Common/CrossThreadProgress.h
new file mode 100755
index 00000000..dcc2ce57
--- /dev/null
+++ b/7zip/Archive/Common/CrossThreadProgress.h
@@ -0,0 +1,33 @@
+// CrossThreadProgress.h
+
+#pragma once
+
+#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/7zip/Archive/Common/DummyOutStream.cpp b/7zip/Archive/Common/DummyOutStream.cpp
new file mode 100755
index 00000000..de1a5b19
--- /dev/null
+++ b/7zip/Archive/Common/DummyOutStream.cpp
@@ -0,0 +1,30 @@
+// 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;
+}
+
+STDMETHODIMP CDummyOutStream::WritePart(const void *data,
+ UINT32 size, UINT32 *processedSize)
+{
+ if(m_Stream)
+ return m_Stream->WritePart(data, size, processedSize);
+ if(processedSize != NULL)
+ *processedSize = size;
+ return S_OK;
+}
diff --git a/7zip/Archive/Common/DummyOutStream.h b/7zip/Archive/Common/DummyOutStream.h
new file mode 100755
index 00000000..85ff6dbf
--- /dev/null
+++ b/7zip/Archive/Common/DummyOutStream.h
@@ -0,0 +1,26 @@
+// DummyOutStream.h
+
+#pragma once
+
+#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);
+ STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize);
+private:
+ CMyComPtr<ISequentialOutStream> m_Stream;
+public:
+ void Init(ISequentialOutStream *outStream);
+};
+
+#endif
diff --git a/7zip/Archive/Common/InStreamWithCRC.cpp b/7zip/Archive/Common/InStreamWithCRC.cpp
new file mode 100755
index 00000000..40e950a8
--- /dev/null
+++ b/7zip/Archive/Common/InStreamWithCRC.cpp
@@ -0,0 +1,39 @@
+// InStreamWithCRC.cpp
+
+#include "StdAfx.h"
+
+#include "InStreamWithCRC.h"
+
+STDMETHODIMP CInStreamWithCRC::Read(void *data,
+ UINT32 size, UINT32 *processedSize)
+{
+ UINT32 realProcessedSize;
+ HRESULT result = _stream->Read(data, size, &realProcessedSize);
+ _size += realProcessedSize;
+ _crc.Update(data, realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return result;
+}
+
+STDMETHODIMP CInStreamWithCRC::ReadPart(void *data,
+ UINT32 size, UINT32 *processedSize)
+{
+ UINT32 realProcessedSize;
+ HRESULT result = _stream->ReadPart(data, size, &realProcessedSize);
+ _size += realProcessedSize;
+ _crc.Update(data, realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return result;
+}
+
+STDMETHODIMP CInStreamWithCRC::Seek(INT64 offset,
+ UINT32 seekOrigin, UINT64 *newPosition)
+{
+ if (seekOrigin != STREAM_SEEK_SET || offset != 0)
+ return E_FAIL;
+ _size = 0;
+ _crc.Init();
+ return _stream->Seek(offset, seekOrigin, newPosition);
+}
diff --git a/7zip/Archive/Common/InStreamWithCRC.h b/7zip/Archive/Common/InStreamWithCRC.h
new file mode 100755
index 00000000..6f1aa13e
--- /dev/null
+++ b/7zip/Archive/Common/InStreamWithCRC.h
@@ -0,0 +1,38 @@
+// InStreamWithCRC.h
+
+// #pragma once
+
+#ifndef __INSTREAMWITHCRC_H
+#define __INSTREAMWITHCRC_H
+
+#include "../../../Common/CRC.h"
+#include "../../../Common/MyCom.h"
+#include "../../IStream.h"
+
+class CInStreamWithCRC:
+ public IInStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize);
+ STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize);
+ STDMETHOD(Seek)(INT64 offset, UINT32 seekOrigin, UINT64 *newPosition);
+private:
+ CMyComPtr<IInStream> _stream;
+ UINT64 _size;
+ CCRC _crc;
+public:
+ void Init(IInStream *stream)
+ {
+ _stream = stream;
+ _size = 0;
+ _crc.Init();
+ }
+ void ReleaseStream() { _stream.Release(); }
+ UINT32 GetCRC() const { return _crc.GetDigest(); }
+ UINT64 GetSize() const { return _size; }
+};
+
+#endif
diff --git a/7zip/Archive/Common/ItemNameUtils.cpp b/7zip/Archive/Common/ItemNameUtils.cpp
new file mode 100755
index 00000000..b367b274
--- /dev/null
+++ b/7zip/Archive/Common/ItemNameUtils.cpp
@@ -0,0 +1,37 @@
+// Archive/Common/ItemNameUtils.cpp
+
+#include "StdAfx.h"
+
+#include "ItemNameUtils.h"
+
+namespace NArchive {
+namespace NItemName {
+
+static const wchar_t kOSDirDelimiter = '\\';
+static const wchar_t kDirDelimiter = '/';
+
+UString MakeLegalName(const UString &aName)
+{
+ UString aZipName = aName;
+ aZipName.Replace(kOSDirDelimiter, kDirDelimiter);
+ return aZipName;
+}
+
+UString GetOSName(const UString &aName)
+{
+ UString aNewName = aName;
+ aNewName.Replace(kDirDelimiter, kOSDirDelimiter);
+ return aNewName;
+}
+
+UString GetOSName2(const UString &aName)
+{
+ if (aName.IsEmpty())
+ return UString();
+ UString aNewName = GetOSName(aName);
+ if (aNewName[aNewName.Length() - 1] == kOSDirDelimiter)
+ aNewName.Delete(aNewName.Length() - 1);
+ return aNewName;
+}
+
+}}
diff --git a/7zip/Archive/Common/ItemNameUtils.h b/7zip/Archive/Common/ItemNameUtils.h
new file mode 100755
index 00000000..0e9badc6
--- /dev/null
+++ b/7zip/Archive/Common/ItemNameUtils.h
@@ -0,0 +1,19 @@
+// Archive/Common/ItemNameUtils.h
+
+#pragma once
+
+#ifndef __ARCHIVE_ITEMNAMEUTILS_H
+#define __ARCHIVE_ITEMNAMEUTILS_H
+
+#include "../../../Common/String.h"
+
+namespace NArchive {
+namespace NItemName {
+
+ UString MakeLegalName(const UString &aName);
+ UString GetOSName(const UString &aName);
+ UString GetOSName2(const UString &aName);
+
+}}
+
+#endif
diff --git a/7zip/Archive/Common/OutStreamWithCRC.cpp b/7zip/Archive/Common/OutStreamWithCRC.cpp
new file mode 100755
index 00000000..5899e753
--- /dev/null
+++ b/7zip/Archive/Common/OutStreamWithCRC.cpp
@@ -0,0 +1,41 @@
+// OutStreamWithCRC.cpp
+
+#include "StdAfx.h"
+
+#include "OutStreamWithCRC.h"
+
+STDMETHODIMP COutStreamWithCRC::Write(const void *data,
+ UINT32 size, UINT32 *processedSize)
+{
+ HRESULT result;
+ UINT32 realProcessedSize;
+ if(!_stream)
+ {
+ realProcessedSize = size;
+ result = S_OK;
+ }
+ else
+ result = _stream->Write(data, size, &realProcessedSize);
+ _crc.Update(data, realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return result;
+}
+
+STDMETHODIMP COutStreamWithCRC::WritePart(const void *data,
+ UINT32 size, UINT32 *processedSize)
+{
+ UINT32 realProcessedSize;
+ HRESULT result;
+ if(!_stream)
+ {
+ realProcessedSize = size;
+ result = S_OK;
+ }
+ else
+ result = _stream->WritePart(data, size, &realProcessedSize);
+ _crc.Update(data, realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return result;
+}
diff --git a/7zip/Archive/Common/OutStreamWithCRC.h b/7zip/Archive/Common/OutStreamWithCRC.h
new file mode 100755
index 00000000..b95abaf8
--- /dev/null
+++ b/7zip/Archive/Common/OutStreamWithCRC.h
@@ -0,0 +1,36 @@
+// OutStreamWithCRC.h
+
+// #pragma once
+
+#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);
+ STDMETHOD(WritePart)(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/7zip/Archive/Common/StdAfx.h b/7zip/Archive/Common/StdAfx.h
new file mode 100755
index 00000000..a32fbed6
--- /dev/null
+++ b/7zip/Archive/Common/StdAfx.h
@@ -0,0 +1,8 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#endif
diff --git a/7zip/Archive/Deb/Deb.def b/7zip/Archive/Deb/Deb.def
new file mode 100755
index 00000000..c281a9cf
--- /dev/null
+++ b/7zip/Archive/Deb/Deb.def
@@ -0,0 +1,8 @@
+; Deb.def
+
+LIBRARY deb.dll
+
+EXPORTS
+ CreateObject PRIVATE
+ GetHandlerProperty PRIVATE
+
diff --git a/7zip/Archive/Deb/Deb.dsp b/7zip/Archive/Deb/Deb.dsp
new file mode 100755
index 00000000..6c121a53
--- /dev/null
+++ b/7zip/Archive/Deb/Deb.dsp
@@ -0,0 +1,241 @@
+# 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=.\Deb.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.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 "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\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
+# End Group
+# End Target
+# End Project
diff --git a/7zip/Archive/Deb/Deb.dsw b/7zip/Archive/Deb/Deb.dsw
new file mode 100755
index 00000000..c7169534
--- /dev/null
+++ b/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/7zip/Archive/Deb/DebHandler.cpp b/7zip/Archive/Deb/DebHandler.cpp
new file mode 100755
index 00000000..389e5d15
--- /dev/null
+++ b/7zip/Archive/Deb/DebHandler.cpp
@@ -0,0 +1,262 @@
+// 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
+ bool mustBeClosed = true;
+ // 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));
+ }
+
+ while(true)
+ {
+ 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;
+ }
+ /*
+ catch(...)
+ {
+ return S_FALSE;
+ }
+ */
+ 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->Init(_inStream, 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/7zip/Archive/Deb/DebHandler.h b/7zip/Archive/Deb/DebHandler.h
new file mode 100755
index 00000000..2da70596
--- /dev/null
+++ b/7zip/Archive/Deb/DebHandler.h
@@ -0,0 +1,49 @@
+// DebHandler.h
+
+#pragma once
+
+#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 \ No newline at end of file
diff --git a/7zip/Archive/Deb/DebHeader.cpp b/7zip/Archive/Deb/DebHeader.cpp
new file mode 100755
index 00000000..b3c01119
--- /dev/null
+++ b/7zip/Archive/Deb/DebHeader.cpp
@@ -0,0 +1,14 @@
+// Archive/Deb/Header.h
+
+#include "StdAfx.h"
+
+#include "DebHeader.h"
+
+namespace NArchive {
+namespace NDeb {
+namespace NHeader {
+
+ const char *kSignature = "!<arch>\n";
+
+}}}
+
diff --git a/7zip/Archive/Deb/DebHeader.h b/7zip/Archive/Deb/DebHeader.h
new file mode 100755
index 00000000..5edda3d0
--- /dev/null
+++ b/7zip/Archive/Deb/DebHeader.h
@@ -0,0 +1,44 @@
+// Archive/Deb/Header.h
+
+#pragma once
+
+#ifndef __ARCHIVE_DEB_HEADER_H
+#define __ARCHIVE_DEB_HEADER_H
+
+#include "Common/Types.h"
+
+namespace NArchive {
+namespace NDeb {
+
+#pragma pack( push, PragmaDebHeaders)
+#pragma pack( push, 1)
+
+namespace NHeader
+{
+ 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 kSignatureLen = 8;
+ extern const char *kSignature;
+}
+
+#pragma pack(pop)
+#pragma pack(pop, PragmaDebHeaders)
+
+}}
+
+#endif
diff --git a/7zip/Archive/Deb/DebIn.cpp b/7zip/Archive/Deb/DebIn.cpp
new file mode 100755
index 00000000..d6c32b05
--- /dev/null
+++ b/7zip/Archive/Deb/DebIn.cpp
@@ -0,0 +1,136 @@
+// Archive/DebIn.cpp
+
+#include "StdAfx.h"
+
+#include "DebIn.h"
+#include "DebHeader.h"
+
+#include "Windows/Defs.h"
+
+namespace NArchive {
+namespace NDeb {
+
+using namespace NHeader;
+
+HRESULT CInArchive::ReadBytes(void *data, UINT32 size, UINT32 &processedSize)
+{
+ RINOK(m_Stream->Read(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(inStream->Read(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 bool CheckString(const char *srcString, int numChars, int radix)
+{
+ for(int i = 0; i < numChars; i++)
+ {
+ char c = srcString[i];
+ if (c == 0)
+ return true;
+ if (c >= '0' && c <= '0' + radix - 1)
+ continue;
+ if (c != ' ')
+ return false;
+ }
+ return true;
+}
+static bool CheckOctalString(const char *srcString, int numChars)
+ { return CheckString(srcString, numChars, 8); }
+static bool CheckDecimalString(const char *srcString, int numChars)
+ { return CheckString(srcString, numChars, 10); }
+
+#define ReturnIfBadOctal(x, y) { if (!CheckOctalString((x), (y))) return S_FALSE; }
+#define ReturnIfBadDecimal(x, y) { if (!CheckDecimalString((x), (y))) return S_FALSE; }
+
+static UINT32 StringToNumber(const char *srcString, int numChars, int radix)
+{
+ AString modString;
+ for (int i = 0; i < numChars; i++)
+ modString += srcString[i];
+ char *endPtr;
+ return strtoul(modString, &endPtr, radix);
+}
+static UINT32 OctalToNumber(const char *srcString, int numChars)
+ { return StringToNumber(srcString, numChars, 8); }
+static UINT32 DecimalToNumber(const char *srcString, int numChars)
+ { return StringToNumber(srcString, numChars, 10); }
+
+HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item)
+{
+ filled = false;
+
+ CHeader header;
+ UINT32 processedSize;
+ item.HeaderPosition = m_Position;
+ RINOK(ReadBytes(&header, sizeof(header), processedSize));
+ if (processedSize < sizeof(header))
+ return S_OK;
+
+ char tempString[kNameSize + 1];
+ strncpy(tempString, header.Name, 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;
+
+ ReturnIfBadDecimal(header.ModificationTime, kTimeSize);
+ ReturnIfBadOctal(header.Mode, kModeSize);
+ ReturnIfBadDecimal(header.Size, kSizeSize);
+
+ item.ModificationTime = DecimalToNumber(header.ModificationTime, kTimeSize);
+ item.Mode = OctalToNumber(header.Mode, kModeSize);
+ item.Size = DecimalToNumber(header.Size, kSizeSize);
+
+ filled = true;
+ return S_OK;
+}
+
+HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
+{
+ while(true)
+ {
+ 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);
+ }
+ 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::SkeepData(UINT64 dataSize)
+{
+ return Skeep((dataSize + 1) & 0xFFFFFFFFFFFFFFFE);
+}
+
+}}
diff --git a/7zip/Archive/Deb/DebIn.h b/7zip/Archive/Deb/DebIn.h
new file mode 100755
index 00000000..5089ab27
--- /dev/null
+++ b/7zip/Archive/Deb/DebIn.h
@@ -0,0 +1,31 @@
+// Archive/DebIn.h
+
+#pragma once
+
+#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/7zip/Archive/Deb/DebItem.h b/7zip/Archive/Deb/DebItem.h
new file mode 100755
index 00000000..58b493fa
--- /dev/null
+++ b/7zip/Archive/Deb/DebItem.h
@@ -0,0 +1,34 @@
+// Archive/Deb/ItemInfo.h
+
+#pragma once
+
+#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 + sizeof(NHeader::CHeader); };
+ // UINT64 GetFullSize() const { return NFileHeader::kRecordSize + Size; };
+};
+
+}}
+
+#endif
diff --git a/7zip/Archive/Deb/DllExports.cpp b/7zip/Archive/Deb/DllExports.cpp
new file mode 100755
index 00000000..d80af48e
--- /dev/null
+++ b/7zip/Archive/Deb/DllExports.cpp
@@ -0,0 +1,73 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#define INITGUID
+
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+
+#include "DebHandler.h"
+#include "../../ICoder.h"
+
+// {23170F69-40C1-278A-1000-0001100C0000}
+DEFINE_GUID(CLSID_CDebHandler,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x0C, 0x00, 0x00);
+
+// HINSTANCE g_hInstance;
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ /*
+ if (dwReason == DLL_PROCESS_ATTACH)
+ g_hInstance = hInstance;
+ */
+ 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;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/7zip/Archive/Deb/StdAfx.cpp b/7zip/Archive/Deb/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Archive/Deb/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Archive/Deb/StdAfx.h b/7zip/Archive/Deb/StdAfx.h
new file mode 100755
index 00000000..9f4df604
--- /dev/null
+++ b/7zip/Archive/Deb/StdAfx.h
@@ -0,0 +1,10 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#include <time.h>
+
+#endif
diff --git a/7zip/Archive/Deb/deb.ico b/7zip/Archive/Deb/deb.ico
new file mode 100755
index 00000000..97a08654
--- /dev/null
+++ b/7zip/Archive/Deb/deb.ico
Binary files differ
diff --git a/7zip/Archive/Deb/resource.h b/7zip/Archive/Deb/resource.h
new file mode 100755
index 00000000..7b0dd8ff
--- /dev/null
+++ b/7zip/Archive/Deb/resource.h
@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDI_ICON1 101
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Archive/Deb/resource.rc b/7zip/Archive/Deb/resource.rc
new file mode 100755
index 00000000..ad546918
--- /dev/null
+++ b/7zip/Archive/Deb/resource.rc
@@ -0,0 +1,130 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1 ICON DISCARDABLE "Deb.ico"
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,9,2,0
+ PRODUCTVERSION 3,9,2,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "Deb Plugin for 7-Zip\0"
+ VALUE "FileVersion", "3, 9, 2, 0\0"
+ VALUE "InternalName", "deb\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "deb.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 9, 2, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Archive/GZip/DllExports.cpp b/7zip/Archive/GZip/DllExports.cpp
new file mode 100755
index 00000000..6385b9fb
--- /dev/null
+++ b/7zip/Archive/GZip/DllExports.cpp
@@ -0,0 +1,103 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#define INITGUID
+
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+#include "../../ICoder.h"
+#include "GZipHandler.h"
+
+// {23170F69-40C1-278A-1000-000110030000}
+DEFINE_GUID(CLSID_CGZipHandler,
+0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x03, 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 COMPRESS_BZIP2
+#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;
+ 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 tgz";
+ break;
+ case NArchive::kAddExtension:
+ propVariant = L"* .tar";
+ break;
+ case NArchive::kUpdate:
+ propVariant = true;
+ break;
+ case NArchive::kKeepName:
+ propVariant = true;
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/7zip/Archive/GZip/GZip.def b/7zip/Archive/GZip/GZip.def
new file mode 100755
index 00000000..90971078
--- /dev/null
+++ b/7zip/Archive/GZip/GZip.def
@@ -0,0 +1,8 @@
+; GZip.def
+
+LIBRARY gz.dll
+
+EXPORTS
+ CreateObject PRIVATE
+ GetHandlerProperty PRIVATE
+
diff --git a/7zip/Archive/GZip/GZip.dsp b/7zip/Archive/GZip/GZip.dsp
new file mode 100755
index 00000000..5ba9663d
--- /dev/null
+++ b/7zip/Archive/GZip/GZip.dsp
@@ -0,0 +1,309 @@
+# 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=.\DllExports.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\GZip.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\GZip.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 "Common"
+
+# PROP Default_Filter ""
+# 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
+# End Group
+# Begin Group "Archive Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Common\ArchiveInterface.h
+# End Source File
+# 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
+# End Group
+# Begin Source File
+
+SOURCE=.\gz.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\gz1.ico
+# End Source File
+# End Target
+# End Project
diff --git a/7zip/Archive/GZip/GZip.dsw b/7zip/Archive/GZip/GZip.dsw
new file mode 100755
index 00000000..5ff50d2c
--- /dev/null
+++ b/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/7zip/Archive/GZip/GZipHandler.cpp b/7zip/Archive/GZip/GZipHandler.cpp
new file mode 100755
index 00000000..f839299d
--- /dev/null
+++ b/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, kpidLastWriteTime, VT_FILETIME},
+ { NULL, kpidSize, VT_UI8},
+ { NULL, kpidPackedSize, VT_UI8},
+
+ { 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)
+{
+ COM_TRY_BEGIN
+ *numItems = 1;
+ return S_OK;
+ COM_TRY_END
+}
+
+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(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_Item.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 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));
+ UINT64 newPosition;
+ RINOK(inStream->Seek(-8, STREAM_SEEK_END, &newPosition));
+ m_Item.PackSize = newPosition - archive.GetPosition();
+ UINT32 crc, unpackSize32;
+ if (archive.ReadPostInfo(inStream, crc, unpackSize32) != S_OK)
+ return S_FALSE;
+ m_Stream = inStream;
+ m_Item.UnPackSize32 = unpackSize32;
+ }
+ 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);
+ UINT64 totalUnPacked = 0, totalPacked = 0;
+
+ totalUnPacked += m_Item.UnPackSize32;
+ totalPacked += m_Item.PackSize;
+
+ extractCallback->SetTotal(totalUnPacked);
+
+ UINT64 currentTotalUnPacked = 0, currentTotalPacked = 0;
+
+ RINOK(extractCallback->SetCompleted(&currentTotalUnPacked));
+ 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->Init(realOutStream);
+ realOutStream.Release();
+
+ 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);
+
+ #ifndef COMPRESS_DEFLATE
+ CCoderLibrary lib;
+ #endif
+ CMyComPtr<ICompressCoder> deflateDecoder;
+ bool firstItem = true;
+ RINOK(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL));
+ while(true)
+ {
+ CInArchive archive;
+ CItemEx item;
+ HRESULT result = archive.ReadHeader(m_Stream, item);
+ if (result != S_OK)
+ {
+ if (firstItem)
+ return E_FAIL;
+ else
+ {
+ outStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK))
+ return S_OK;
+ }
+ }
+ firstItem = false;
+ RINOK(m_Stream->Seek(item.DataPosition, STREAM_SEEK_SET, NULL));
+
+ outStreamSpec->InitCRC();
+
+ switch(m_Item.CompressionMethod)
+ {
+ case NCompressionMethod::kDeflated:
+ {
+ 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));
+ RINOK(m_Stream->Seek(item.DataPosition + packSize, STREAM_SEEK_SET, NULL));
+
+ UINT32 crc, unpackSize32;
+ if (archive.ReadPostInfo(m_Stream, crc, unpackSize32) != S_OK)
+ return E_FAIL;
+
+ if((outStreamSpec->GetCRC() != crc))
+ {
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError))
+ return S_OK;
+ }
+ }
+ COM_TRY_END
+}
+
+}}
diff --git a/7zip/Archive/GZip/GZipHandler.h b/7zip/Archive/GZip/GZipHandler.h
new file mode 100755
index 00000000..037eb419
--- /dev/null
+++ b/7zip/Archive/GZip/GZipHandler.h
@@ -0,0 +1,77 @@
+// GZip/Handler.h
+
+#pragma once
+
+#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)(IOutStream *outStream, UINT32 numItems,
+ IArchiveUpdateCallback *updateCallback);
+
+ STDMETHOD(GetFileTimeType)(UINT32 *timeType);
+
+ // ISetProperties
+ STDMETHOD(SetProperties)(const BSTR *names, const PROPVARIANT *values, INT32 numProperties);
+
+public:
+ CHandler() { InitMethodProperties(); }
+
+private:
+ NArchive::NGZip::CItemEx m_Item;
+ UINT64 m_StreamStartPosition;
+ CMyComPtr<IInStream> m_Stream;
+ CCompressionMethodMode m_Method;
+ void InitMethodProperties()
+ {
+ m_Method.NumPasses = 1;
+ m_Method.NumFastBytes = 32;
+ }
+};
+
+}}
+
+#endif
diff --git a/7zip/Archive/GZip/GZipHandlerOut.cpp b/7zip/Archive/GZip/GZipHandlerOut.cpp
new file mode 100755
index 00000000..2d410554
--- /dev/null
+++ b/7zip/Archive/GZip/GZipHandlerOut.cpp
@@ -0,0 +1,215 @@
+// Zip/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"
+
+using namespace NWindows;
+using namespace NTime;
+
+namespace NArchive {
+namespace NGZip {
+
+STDMETHODIMP CHandler::GetFileTimeType(UINT32 *timeType)
+{
+ *timeType = NFileTimeType::kUnix;
+ return S_OK;
+}
+
+static HRESULT CopyStreams(IInStream *inStream, IOutStream *outStream,
+ IArchiveUpdateCallback *updateCallback)
+{
+ CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
+ return copyCoder->Code(inStream, outStream, NULL, NULL, NULL);
+}
+
+STDMETHODIMP CHandler::UpdateItems(IOutStream *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;
+ time_t unixTime;
+ if(!FileTimeToUnixTime(utcTime, unixTime))
+ return E_INVALIDARG;
+
+ newItem.Time = unixTime;
+ newItem.Name = UnicodeStringToMultiByte(name, CP_ACP);
+ int dirDelimiterPos = newItem.Name.ReverseFind('\\');
+ 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 = *(UINT64 *)(&propVariant.uhVal);
+ }
+ newItem.UnPackSize32 = (UINT32)size;
+ 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_Item.DataPosition, STREAM_SEEK_SET, NULL));
+ }
+ else
+ {
+ RINOK(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL));
+ }
+ return CopyStreams(m_Stream, outStream, updateCallback);
+}
+
+static const UINT32 kMatchFastLenNormal = 32;
+static const UINT32 kMatchFastLenMX = 64;
+
+static const UINT32 kNumPassesNormal = 1;
+static const UINT32 kNumPassesMX = 3;
+
+STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *values, INT32 numProperties)
+{
+ InitMethodProperties();
+ for (int i = 0; i < numProperties; i++)
+ {
+ UString name = UString(names[i]);
+ name.MakeUpper();
+ const PROPVARIANT &value = values[i];
+ if (name[0] == 'X')
+ {
+ name.Delete(0);
+ UINT32 level = 9;
+ if (value.vt == VT_UI4)
+ {
+ if (!name.IsEmpty())
+ return E_INVALIDARG;
+ level = value.ulVal;
+ }
+ else if (value.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;
+ level = (UINT32)v;
+ }
+ }
+ else
+ return E_INVALIDARG;
+ if (level < 7)
+ {
+ InitMethodProperties();
+ }
+ else
+ {
+ m_Method.NumPasses = kNumPassesMX;
+ m_Method.NumFastBytes = kMatchFastLenMX;
+ }
+ continue;
+ }
+ else if (name == L"PASS")
+ {
+ if (value.vt != VT_UI4)
+ return E_INVALIDARG;
+ m_Method.NumPasses = value.ulVal;
+ if (m_Method.NumPasses < 1 || m_Method.NumPasses > 4)
+ return E_INVALIDARG;
+ }
+ else if (name == L"FB")
+ {
+ if (value.vt != VT_UI4)
+ return E_INVALIDARG;
+ m_Method.NumFastBytes = value.ulVal;
+ if (m_Method.NumFastBytes < 3 || m_Method.NumFastBytes > 255)
+ return E_INVALIDARG;
+ }
+ else
+ return E_INVALIDARG;
+ }
+ return S_OK;
+}
+
+}}
diff --git a/7zip/Archive/GZip/GZipHeader.cpp b/7zip/Archive/GZip/GZipHeader.cpp
new file mode 100755
index 00000000..ec3f0ef7
--- /dev/null
+++ b/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/7zip/Archive/GZip/GZipHeader.h b/7zip/Archive/GZip/GZipHeader.h
new file mode 100755
index 00000000..34dd39c0
--- /dev/null
+++ b/7zip/Archive/GZip/GZipHeader.h
@@ -0,0 +1,100 @@
+// Archive/GZip/Header.h
+
+#pragma once
+
+#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;
+
+#pragma pack( push, PragmaGZipHeaders)
+#pragma pack( push, 1)
+
+namespace NCompressionMethod
+{
+ enum EType
+ {
+ kDeflated = 8,
+ };
+}
+
+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 kDefalate = 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;
+ }
+}
+
+#pragma pack(pop)
+#pragma pack(pop, PragmaGZipHeaders)
+
+}}
+
+#endif
diff --git a/7zip/Archive/GZip/GZipIn.cpp b/7zip/Archive/GZip/GZipIn.cpp
new file mode 100755
index 00000000..28bcd3d8
--- /dev/null
+++ b/7zip/Archive/GZip/GZipIn.cpp
@@ -0,0 +1,132 @@
+// Archive/GZipIn.cpp
+
+#include "StdAfx.h"
+
+#include "GZipIn.h"
+
+#include "Common/Defs.h"
+#include "Common/MyCom.h"
+#include "Windows/Defs.h"
+
+namespace NArchive {
+namespace NGZip {
+
+HRESULT CInArchive::ReadBytes(IInStream *inStream, void *data, UINT32 size)
+{
+ UINT32 realProcessedSize;
+ RINOK(inStream->Read(data, size, &realProcessedSize));
+ m_Position += realProcessedSize;
+ if(realProcessedSize != size)
+ return S_FALSE;
+ return S_OK;
+}
+
+HRESULT CInArchive::UpdateCRCBytes(IInStream *inStream,
+ UINT32 numBytesToSkeep, CCRC &crc)
+{
+ while (numBytesToSkeep > 0)
+ {
+ const UINT32 kBufferSize = (1 << 12);
+ BYTE buffer[kBufferSize];
+ UINT32 currentSize = MyMin(numBytesToSkeep, kBufferSize);
+ RINOK(ReadBytes(inStream, buffer, currentSize));
+ crc.Update(buffer, currentSize);
+ numBytesToSkeep -= currentSize;
+ }
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadZeroTerminatedString(IInStream *inStream, AString &resString)
+{
+ resString.Empty();
+ while(true)
+ {
+ char c;
+ RINOK(ReadBytes(inStream, &c, sizeof(c)));
+ if (c == 0)
+ return S_OK;
+ resString += c;
+ }
+}
+
+HRESULT CInArchive::ReadHeader(IInStream *inStream, CItemEx &item)
+{
+ RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition));
+
+ m_Position = m_StreamStartPosition;
+ NFileHeader::CBlock fileHeader;
+
+ RINOK(ReadBytes(inStream, &fileHeader, sizeof(fileHeader)));
+
+ if (fileHeader.Id != kSignature)
+ return S_FALSE;
+
+ item.CompressionMethod = fileHeader.CompressionMethod;
+ item.Flags = fileHeader.Flags;
+ item.Time = fileHeader.Time;
+ item.ExtraFlags = fileHeader.ExtraFlags;
+ item.HostOS = fileHeader.HostOS;
+
+ CCRC crc;
+ crc.Update(&fileHeader, sizeof(fileHeader));
+ if (item.ExtraFieldIsPresent())
+ {
+ item.ExtraPosition = m_Position;
+ RINOK(ReadBytes(inStream, &item.ExtraFieldSize,
+ sizeof(item.ExtraFieldSize)));
+ crc.Update(&item.ExtraFieldSize, sizeof(item.ExtraFieldSize));
+ RINOK(UpdateCRCBytes(inStream, item.ExtraFieldSize, crc));
+ }
+ item.Name.Empty();
+ if (item.NameIsPresent())
+ RINOK(ReadZeroTerminatedString(inStream, item.Name));
+ AString comment;
+ if (item.CommentIsPresent())
+ {
+ item.CommentPosition = m_Position;
+ RINOK(ReadZeroTerminatedString(inStream, comment));
+ item.CommentSize = comment.Length() + 1;
+ }
+ if (item.HeaderCRCIsPresent())
+ {
+ UINT16 headerCRC;
+ RINOK(ReadBytes(inStream, &headerCRC, sizeof(headerCRC)));
+ if (item.NameIsPresent())
+ {
+ crc.Update((const char *)item.Name, item.Name.Length());
+ BYTE zeroByte = 0;;
+ crc.Update(&zeroByte, sizeof(zeroByte));
+ }
+ if (item.CommentIsPresent())
+ {
+ crc.Update((const char *)comment, comment.Length());
+ BYTE zeroByte = 0;;
+ crc.Update(&zeroByte, sizeof(zeroByte));
+ }
+ if ((UINT16)crc.GetDigest() != headerCRC)
+ return S_FALSE;
+ }
+
+ item.DataPosition = m_Position;
+
+ item.UnPackSize32 = 0;
+ item.PackSize = 0;
+
+ /*
+ UINT64 newPosition;
+ RINOK(inStream->Seek(-8, STREAM_SEEK_END, &newPosition));
+ item.PackSize = newPosition - item.DataPosition;
+
+ RINOK(ReadBytes(inStream, &item.FileCRC, sizeof(item.FileCRC)));
+ RINOK(ReadBytes(inStream, &item.UnPackSize32, sizeof(item.UnPackSize32)));
+ */
+ return S_OK;
+}
+
+HRESULT CInArchive::ReadPostInfo(IInStream *inStream, UINT32 &crc, UINT32 &unpackSize32)
+{
+ RINOK(ReadBytes(inStream, &crc, sizeof(crc)));
+ return ReadBytes(inStream, &unpackSize32, sizeof(unpackSize32));
+}
+
+}}
diff --git a/7zip/Archive/GZip/GZipIn.h b/7zip/Archive/GZip/GZipIn.h
new file mode 100755
index 00000000..f0f72403
--- /dev/null
+++ b/7zip/Archive/GZip/GZipIn.h
@@ -0,0 +1,34 @@
+// Archive/GZipIn.h
+
+#pragma once
+
+#ifndef __ARCHIVE_GZIP_IN_H
+#define __ARCHIVE_GZIP_IN_H
+
+#include "GZipHeader.h"
+#include "GZipItem.h"
+#include "../../IStream.h"
+#include "Common/CRC.h"
+
+namespace NArchive {
+namespace NGZip {
+
+class CInArchive
+{
+ UINT64 m_StreamStartPosition;
+ UINT64 m_Position;
+
+ HRESULT ReadBytes(IInStream *inStream, void *data, UINT32 size);
+ HRESULT UpdateCRCBytes(IInStream *inStream, UINT32 numBytesToSkeep, CCRC &crc);
+
+ HRESULT ReadZeroTerminatedString(IInStream *inStream, AString &resString);
+
+public:
+ HRESULT ReadHeader(IInStream *inStream, CItemEx &item);
+ HRESULT ReadPostInfo(IInStream *inStream, UINT32 &crc, UINT32 &unpackSize32);
+ UINT64 GetPosition() const { return m_Position; }
+};
+
+}}
+
+#endif
diff --git a/7zip/Archive/GZip/GZipItem.h b/7zip/Archive/GZip/GZipItem.h
new file mode 100755
index 00000000..e47abadc
--- /dev/null
+++ b/7zip/Archive/GZip/GZipItem.h
@@ -0,0 +1,65 @@
+// Archive/GZipItem.h
+
+#pragma once
+
+#ifndef __ARCHIVE_GZIP_ITEM_H
+#define __ARCHIVE_GZIP_ITEM_H
+
+#include "Common/Types.h"
+#include "Common/String.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;
+ UINT64 PackSize;
+
+ AString Name;
+ UINT16 ExtraFieldSize;
+ UINT16 CommentSize;
+
+ 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);
+ }
+};
+
+class CItemEx: public CItem
+{
+public:
+ UINT64 DataPosition;
+ UINT64 CommentPosition;
+ UINT64 ExtraPosition;
+};
+
+
+}}
+
+#endif
+
+
diff --git a/7zip/Archive/GZip/GZipOut.cpp b/7zip/Archive/GZip/GZipOut.cpp
new file mode 100755
index 00000000..d1968385
--- /dev/null
+++ b/7zip/Archive/GZip/GZipOut.cpp
@@ -0,0 +1,48 @@
+// Archive/GZipOut.cpp
+
+#include "StdAfx.h"
+
+#include "GZipOut.h"
+#include "Common/CRC.h"
+#include "Windows/Defs.h"
+
+namespace NArchive {
+namespace NGZip {
+
+HRESULT COutArchive::WriteBytes(const void *buffer, UINT32 size)
+{
+ UINT32 processedSize;
+ RINOK(m_Stream->Write(buffer, size, &processedSize));
+ if(processedSize != size)
+ return E_FAIL;
+ return S_OK;
+}
+
+HRESULT COutArchive::WriteHeader(const CItem &item)
+{
+ NFileHeader::CBlock header;
+ header.Id = kSignature;
+ header.CompressionMethod = item.CompressionMethod;
+ header.Flags = item.Flags;
+ header.Flags &= NFileHeader::NFlags::kNameIsPresent;
+ header.Time = item.Time;
+ header.ExtraFlags = item.ExtraFlags;
+ header.HostOS = item.HostOS;
+ RINOK(WriteBytes(&header, sizeof(header)));
+ if (item.NameIsPresent())
+ {
+ RINOK(WriteBytes((LPCSTR)item.Name, item.Name.Length()));
+ BYTE zero = 0;
+ RINOK(WriteBytes(&zero, sizeof(zero)));
+ }
+ // check it
+ return S_OK;
+}
+
+HRESULT COutArchive::WritePostInfo(UINT32 crc, UINT32 unpackSize)
+{
+ RINOK(WriteBytes(&crc, sizeof(crc)));
+ return WriteBytes(&unpackSize, sizeof(unpackSize));
+}
+
+}}
diff --git a/7zip/Archive/GZip/GZipOut.h b/7zip/Archive/GZip/GZipOut.h
new file mode 100755
index 00000000..6cfd08e9
--- /dev/null
+++ b/7zip/Archive/GZip/GZipOut.h
@@ -0,0 +1,28 @@
+// Archive/GZipOut.h
+
+#pragma once
+
+#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<IOutStream> m_Stream;
+ HRESULT WriteBytes(const void *buffer, UINT32 size);
+public:
+ void Create(IOutStream *outStream) { m_Stream = outStream; }
+ HRESULT WriteHeader(const CItem &item);
+ HRESULT WritePostInfo(UINT32 crc, UINT32 anUnpackSize);
+};
+
+}}
+
+#endif
diff --git a/7zip/Archive/GZip/GZipUpdate.cpp b/7zip/Archive/GZip/GZipUpdate.cpp
new file mode 100755
index 00000000..ba31f69f
--- /dev/null
+++ b/7zip/Archive/GZip/GZipUpdate.cpp
@@ -0,0 +1,110 @@
+// 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);
+extern CSysString GetBaseFolderPrefix();
+#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,
+ IOutStream *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<IInStream> fileInStream;
+
+ RINOK(updateCallback->GetStream(indexInClient, &fileInStream));
+
+ CInStreamWithCRC *inStreamSpec = new CInStreamWithCRC;
+ CMyComPtr<ISequentialInStream> crcStream(inStreamSpec);
+ inStreamSpec->Init(fileInStream);
+
+ 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::kDefalate;
+ 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[2] =
+ { compressionMethod.NumPasses, compressionMethod.NumFastBytes };
+ PROPID propIDs[2] =
+ { NCoderPropID::kNumPasses, NCoderPropID::kNumFastBytes };
+ CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
+ RINOK(deflateEncoder.QueryInterface(
+ IID_ICompressSetCoderProperties, &setCoderProperties));
+ RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, 2));
+ }
+ RINOK(deflateEncoder->Code(crcStream, outStream, NULL, NULL, compressProgress));
+
+ RINOK(outArchive.WritePostInfo(inStreamSpec->GetCRC(),
+ (UINT32)inStreamSpec->GetSize()));
+ return updateCallback->SetOperationResult(
+ NArchive::NUpdate::NOperationResult::kOK);
+}
+
+}}
diff --git a/7zip/Archive/GZip/GZipUpdate.h b/7zip/Archive/GZip/GZipUpdate.h
new file mode 100755
index 00000000..a7df7ff9
--- /dev/null
+++ b/7zip/Archive/GZip/GZipUpdate.h
@@ -0,0 +1,32 @@
+// GZip/Update.h
+
+#pragma once
+
+#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;
+};
+
+HRESULT UpdateArchive(IInStream *inStream,
+ UINT64 unpackSize,
+ IOutStream *outStream,
+ const CItem &newItem,
+ const CCompressionMethodMode &compressionMethod,
+ int indexInClient,
+ IArchiveUpdateCallback *updateCallback);
+
+}}
+
+#endif
diff --git a/7zip/Archive/GZip/StdAfx.cpp b/7zip/Archive/GZip/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Archive/GZip/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Archive/GZip/StdAfx.h b/7zip/Archive/GZip/StdAfx.h
new file mode 100755
index 00000000..9f4df604
--- /dev/null
+++ b/7zip/Archive/GZip/StdAfx.h
@@ -0,0 +1,10 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#include <time.h>
+
+#endif
diff --git a/7zip/Archive/GZip/gz.ico b/7zip/Archive/GZip/gz.ico
new file mode 100755
index 00000000..f50d8c08
--- /dev/null
+++ b/7zip/Archive/GZip/gz.ico
Binary files differ
diff --git a/7zip/Archive/GZip/resource.h b/7zip/Archive/GZip/resource.h
new file mode 100755
index 00000000..7b0dd8ff
--- /dev/null
+++ b/7zip/Archive/GZip/resource.h
@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDI_ICON1 101
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Archive/GZip/resource.rc b/7zip/Archive/GZip/resource.rc
new file mode 100755
index 00000000..41565141
--- /dev/null
+++ b/7zip/Archive/GZip/resource.rc
@@ -0,0 +1,130 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1 ICON DISCARDABLE "gz.ico"
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,9,2,0
+ PRODUCTVERSION 3,9,2,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "GZip Plugin for 7-Zip\0"
+ VALUE "FileVersion", "3, 9, 2, 0\0"
+ VALUE "InternalName", "gz\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "gz.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 9, 2, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Archive/IArchive.h b/7zip/Archive/IArchive.h
new file mode 100755
index 00000000..541307cd
--- /dev/null
+++ b/7zip/Archive/IArchive.h
@@ -0,0 +1,172 @@
+// IArchive.h
+
+#ifndef __IARCHIVE_H
+#define __IARCHIVE_H
+
+#include "../IStream.h"
+#include "../IProgress.h"
+#include "../PropID.h"
+
+namespace NFileTimeType
+{
+ enum EEnum
+ {
+ kWindows,
+ kUnix,
+ kDOS
+ };
+}
+
+namespace NArchive
+{
+ enum
+ {
+ kName = 0,
+ kClassID,
+ kExtension,
+ kAddExtension,
+ kUpdate,
+ kKeepName,
+ };
+
+ 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,
+ };
+ }
+ }
+}
+
+// {23170F69-40C1-278A-0000-000100010000}
+DEFINE_GUID(IID_IArchiveOpenCallback,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000100010000")
+IArchiveOpenCallback: public IUnknown
+{
+public:
+ STDMETHOD(SetTotal)(const UINT64 *files, const UINT64 *bytes) PURE;
+ STDMETHOD(SetCompleted)(const UINT64 *files, const UINT64 *bytes) PURE;
+};
+
+// {23170F69-40C1-278A-0000-000100090000}
+DEFINE_GUID(IID_IArchiveExtractCallback,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000100090000")
+IArchiveExtractCallback: public IProgress
+{
+public:
+ STDMETHOD(GetStream)(UINT32 index, ISequentialOutStream **outStream,
+ INT32 askExtractMode) PURE;
+ STDMETHOD(PrepareOperation)(INT32 askExtractMode) PURE;
+ STDMETHOD(SetOperationResult)(INT32 resultEOperationResult) PURE;
+};
+
+
+// {23170F69-40C1-278A-0000-0001000D0000}
+DEFINE_GUID(IID_IArchiveOpenVolumeCallback,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0D, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-0001000D0000")
+IArchiveOpenVolumeCallback: public IUnknown
+{
+public:
+ STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) PURE;
+ STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) PURE;
+};
+
+
+// {23170F69-40C1-278A-0000-000100080000}
+DEFINE_GUID(IID_IInArchive,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000100080000")
+IInArchive: public IUnknown
+{
+public:
+ 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;
+
+ 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;
+};
+
+
+// {23170F69-40C1-278A-0000-000100040000}
+DEFINE_GUID(IID_IArchiveUpdateCallback,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000100040000")
+IArchiveUpdateCallback: public IProgress
+{
+public:
+ // STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator) PURE;
+ STDMETHOD(GetUpdateItemInfo)(UINT32 index,
+ INT32 *newData, // 1 - new data, 0 - old data
+ INT32 *newProperties, // 1 - new properties, 0 - old properties
+ 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, IInStream **inStream) PURE;
+ STDMETHOD(SetOperationResult)(INT32 operationResult) PURE;
+ // STDMETHOD(GetVolumeSize)(UINT32 index, UINT64 *size) PURE;
+ // STDMETHOD(GetVolumeStream)(UINT32 index, IOutStream **volumeStream) PURE;
+};
+
+// {23170F69-40C1-278A-0000-000100020000}
+DEFINE_GUID(IID_IOutArchive,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000100020000")
+IOutArchive: public IUnknown
+{
+ STDMETHOD(UpdateItems)(IOutStream *outStream, UINT32 numItems,
+ IArchiveUpdateCallback *updateCallback) PURE;
+ STDMETHOD(GetFileTimeType)(UINT32 *type) PURE;
+};
+
+// {23170F69-40C1-278A-0000-000100030000}
+DEFINE_GUID(IID_ISetProperties,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000100030000")
+ISetProperties: public IUnknown
+{
+ STDMETHOD(SetProperties)(const BSTR *names, const PROPVARIANT *values, INT32 numProperties) PURE;
+};
+
+
+#endif
diff --git a/7zip/Archive/RPM/DllExports.cpp b/7zip/Archive/RPM/DllExports.cpp
new file mode 100755
index 00000000..a529f03d
--- /dev/null
+++ b/7zip/Archive/RPM/DllExports.cpp
@@ -0,0 +1,69 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include <initguid.h>
+
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+#include "../../ICoder.h"
+#include "RpmHandler.h"
+
+// {23170F69-40C1-278A-1000-000110090000}
+DEFINE_GUID(CLSID_CRpmHandler,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x09, 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/7zip/Archive/RPM/Rpm.def b/7zip/Archive/RPM/Rpm.def
new file mode 100755
index 00000000..72d1968c
--- /dev/null
+++ b/7zip/Archive/RPM/Rpm.def
@@ -0,0 +1,8 @@
+; rpm.def
+
+LIBRARY rpm
+
+EXPORTS
+ CreateObject
+ GetHandlerProperty
+
diff --git a/7zip/Archive/RPM/Rpm.dsp b/7zip/Archive/RPM/Rpm.dsp
new file mode 100755
index 00000000..b10596ee
--- /dev/null
+++ b/7zip/Archive/RPM/Rpm.dsp
@@ -0,0 +1,189 @@
+# 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=.\DllExports.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\Rpm.def
+# 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
+# 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\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\Rpm.ico
+# End Source File
+# 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/7zip/Archive/RPM/Rpm.dsw b/7zip/Archive/RPM/Rpm.dsw
new file mode 100755
index 00000000..a67232ed
--- /dev/null
+++ b/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/7zip/Archive/RPM/RpmHandler.cpp b/7zip/Archive/RPM/RpmHandler.cpp
new file mode 100755
index 00000000..0a339196
--- /dev/null
+++ b/7zip/Archive/RPM/RpmHandler.cpp
@@ -0,0 +1,195 @@
+// 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 "Interface/EnumStatProp.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/7zip/Archive/RPM/RpmHandler.h b/7zip/Archive/RPM/RpmHandler.h
new file mode 100755
index 00000000..214d258d
--- /dev/null
+++ b/7zip/Archive/RPM/RpmHandler.h
@@ -0,0 +1,49 @@
+// RPM/Handler.h
+
+// #pragma once
+
+#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/7zip/Archive/RPM/RpmHeader.h b/7zip/Archive/RPM/RpmHeader.h
new file mode 100755
index 00000000..db68edd9
--- /dev/null
+++ b/7zip/Archive/RPM/RpmHeader.h
@@ -0,0 +1,89 @@
+// Archive/RpmHeader.h
+
+// #pragma once
+
+#ifndef __ARCHIVE_RPM_HEADER_H
+#define __ARCHIVE_RPM_HEADER_H
+
+#include "Common/Types.h"
+
+namespace NArchive {
+namespace NRpm {
+
+#pragma pack(push, PragmaRPMHeaders)
+#pragma pack(push, 1)
+
+/* 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 */
+
+struct CLead
+{
+ unsigned char Magic[4];
+ unsigned char Major; /* not supported ver1, only support 2,3 and lator */
+ unsigned char Minor;
+ short Type;
+ short ArchNum;
+ char Name[66];
+ short OSNum;
+ short 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; };
+ static short my_htons(short s)
+ {
+ const unsigned char *p = (const unsigned char*)&s;
+ return (short(p[0]) << 8) + (p[1]); }
+ ;
+ void hton()
+ {
+ Type = my_htons(Type);
+ ArchNum = my_htons(ArchNum);
+ OSNum = my_htons(OSNum);
+ SignatureType = my_htons(SignatureType);
+ };
+};
+
+
+struct CEntryInfo
+{
+ int Tag;
+ int Type;
+ int Offset; /* Offset from beginning of data segment, only defined on disk */
+ int Count;
+};
+
+/* case: SignatureType == RPMSIG_HEADERSIG */
+struct CSigHeaderSig
+{
+ unsigned char Magic[4];
+ int Reserved;
+ int IndexLen; /* count of index entries */
+ int DataLen; /* number of bytes */
+ int MagicCheck()
+ { return Magic[0] == 0x8e && Magic[1] == 0xad && Magic[2] == 0xe8 && Magic[3] == 0x01; };
+ int GetLostHeaderLen()
+ { return IndexLen * sizeof(CEntryInfo) + DataLen; };
+ long my_htonl(long s)
+ {
+ unsigned char *p = (unsigned char*)&s;
+ return (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3];
+ };
+ void hton()
+ {
+ IndexLen = my_htonl(IndexLen);
+ DataLen = my_htonl(DataLen);
+ };
+};
+
+#pragma pack(pop)
+#pragma pack(pop, PragmaRPMHeaders)
+
+}}
+
+#endif
diff --git a/7zip/Archive/RPM/RpmIn.cpp b/7zip/Archive/RPM/RpmIn.cpp
new file mode 100755
index 00000000..c26605ec
--- /dev/null
+++ b/7zip/Archive/RPM/RpmIn.cpp
@@ -0,0 +1,70 @@
+// Archive/RpmIn.cpp
+
+#include "StdAfx.h"
+
+#include "RpmIn.h"
+
+#include "RpmHeader.h"
+
+#include "Windows/Defs.h"
+#include "Common/MyCom.h"
+
+namespace NArchive {
+namespace NRpm {
+
+HRESULT OpenArchive(IInStream *inStream)
+{
+ UINT64 pos;
+ CLead lead;
+ UINT32 processedSize;
+ RINOK(inStream->Read(&lead, sizeof(lead), &processedSize));
+ if (sizeof(lead) != processedSize)
+ return S_FALSE;
+ if (!lead.MagicCheck() || lead.Major < 3)
+ return S_FALSE;
+ lead.hton();
+
+ 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(inStream->Read(&sigHeader, sizeof(sigHeader), &processedSize));
+ if (sizeof(sigHeader) != processedSize)
+ return S_FALSE;
+ if(!sigHeader.MagicCheck())
+ return S_FALSE;
+ sigHeader.hton();
+ int 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(inStream->Read(&header, sizeof(header), &processedSize));
+ if (sizeof(header) != processedSize)
+ return S_FALSE;
+ if(!header.MagicCheck())
+ return S_FALSE;
+ header.hton();
+ int headerLen = header.GetLostHeaderLen();
+ if(headerLen == -1)
+ return S_FALSE;
+ RINOK(inStream->Seek(headerLen, STREAM_SEEK_CUR, &pos));
+ return S_OK;
+}
+
+
+}}
diff --git a/7zip/Archive/RPM/RpmIn.h b/7zip/Archive/RPM/RpmIn.h
new file mode 100755
index 00000000..ff6ca1c6
--- /dev/null
+++ b/7zip/Archive/RPM/RpmIn.h
@@ -0,0 +1,17 @@
+// Archive/RpmIn.h
+
+// #pragma once
+
+#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/7zip/Archive/RPM/StdAfx.cpp b/7zip/Archive/RPM/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Archive/RPM/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Archive/RPM/StdAfx.h b/7zip/Archive/RPM/StdAfx.h
new file mode 100755
index 00000000..a32fbed6
--- /dev/null
+++ b/7zip/Archive/RPM/StdAfx.h
@@ -0,0 +1,8 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#endif
diff --git a/7zip/Archive/RPM/resource.h b/7zip/Archive/RPM/resource.h
new file mode 100755
index 00000000..612062a2
--- /dev/null
+++ b/7zip/Archive/RPM/resource.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Archive/RPM/resource.rc b/7zip/Archive/RPM/resource.rc
new file mode 100755
index 00000000..ae7fff20
--- /dev/null
+++ b/7zip/Archive/RPM/resource.rc
@@ -0,0 +1,130 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1 ICON DISCARDABLE "Rpm.ico"
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,9,2,0
+ PRODUCTVERSION 3,9,2,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "RPM Plugin for 7-Zip\0"
+ VALUE "FileVersion", "3, 9, 2, 0\0"
+ VALUE "InternalName", "rpm\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "rpm.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 9, 2, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Archive/RPM/rpm.ico b/7zip/Archive/RPM/rpm.ico
new file mode 100755
index 00000000..cdeb8d1b
--- /dev/null
+++ b/7zip/Archive/RPM/rpm.ico
Binary files differ
diff --git a/7zip/Archive/Rar/DllExports.cpp b/7zip/Archive/Rar/DllExports.cpp
new file mode 100755
index 00000000..6c1830a7
--- /dev/null
+++ b/7zip/Archive/Rar/DllExports.cpp
@@ -0,0 +1,160 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include <initguid.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;
+
+/*
+static bool GetBaseFolderPrefix(TCHAR *path)
+{
+ TCHAR fullPath[MAX_PATH + 1];
+ if (::GetModuleFileName(g_hInstance, fullPath, MAX_PATH) == 0)
+ return false;
+ // fullPath = "7-zip\Format\Rar.dll"
+ LPTSTR fileNamePointer;
+ TCHAR p[MAX_PATH + 1];
+ DWORD needLength = ::GetFullPathName(fullPath, MAX_PATH + 1,
+ p, &fileNamePointer);
+ if (needLength == 0 || needLength >= MAX_PATH)
+ return false;
+ *fileNamePointer = 0;
+ // p = "7-zip\Format\"
+ int len = lstrlen(p);
+ if (len == 0)
+ return false;
+ if (p[len - 1] != '\\')
+ return false;
+ p[len - 1] = 0;
+ // p = "7-zip\Format"
+ needLength = ::GetFullPathName(p, MAX_PATH + 1,
+ path, &fileNamePointer);
+ if (needLength == 0 || needLength >= MAX_PATH)
+ return false;
+ // fileNamePointer -> "7-zip\"+
+ *fileNamePointer = 0;
+ return true;
+}
+
+bool GetCompressFolderPrefix(TCHAR *path)
+{
+ if (!GetBaseFolderPrefix(path))
+ return false;
+ lstrcat(path, TEXT("Codecs\\"));
+ return true;
+}
+*/
+
+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-000110020000}
+DEFINE_GUID(CLSID_CRarHandler,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x02, 0x00, 0x00);
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ g_hInstance = hInstance;
+ 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;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/7zip/Archive/Rar/Rar.def b/7zip/Archive/Rar/Rar.def
new file mode 100755
index 00000000..6fd75ee2
--- /dev/null
+++ b/7zip/Archive/Rar/Rar.def
@@ -0,0 +1,7 @@
+; Rar.def
+
+LIBRARY Rar.dll
+
+EXPORTS
+ CreateObject PRIVATE
+ GetHandlerProperty PRIVATE
diff --git a/7zip/Archive/Rar/Rar.dsp b/7zip/Archive/Rar/Rar.dsp
new file mode 100755
index 00000000..07dfd729
--- /dev/null
+++ b/7zip/Archive/Rar/Rar.dsp
@@ -0,0 +1,433 @@
+# 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=.\DllExports.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Rar.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 "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\..\SDK\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=..\..\..\..\SDK\Common\DynamicBuffer.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\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\CoderMixer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CoderMixer.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\CrossThreadProgress.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CrossThreadProgress.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
+# Begin Source File
+
+SOURCE=..\..\Crypto\RarAES\sha1.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\RarAES\sha1.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
+# 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\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
+# End Group
+# Begin Group "7z"
+
+# PROP Default_Filter ""
+# 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/7zip/Archive/Rar/Rar.dsw b/7zip/Archive/Rar/Rar.dsw
new file mode 100755
index 00000000..3dab87aa
--- /dev/null
+++ b/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/7zip/Archive/Rar/RarHandler.cpp b/7zip/Archive/Rar/RarHandler.cpp
new file mode 100755
index 00000000..fb91479c
--- /dev/null
+++ b/7zip/Archive/Rar/RarHandler.cpp
@@ -0,0 +1,977 @@
+// RarHandler.cpp
+
+#include "StdAfx.h"
+
+#include "RarHandler.h"
+
+#include "Common/StringConvert.h"
+#include "Common/ComTry.h"
+
+#include "../../Common/StreamObjects.h"
+// #include "Interface/EnumStatProp.h"
+#include "../../Common//ProgressUtils.h"
+#include "../../IPassword.h"
+
+#include "Windows/PropVariant.h"
+#include "Windows/Time.h"
+
+#include "../../Compress/Copy/CopyCoder.h"
+
+#include "../Common/OutStreamWithCRC.h"
+#include "../Common/CoderMixer.h"
+#include "../Common/CoderLoader.h"
+#include "../Common/CodecsPath.h"
+#include "../7z/7zMethods.h"
+
+// #include "../../../Compress/Interface/CompressInterface.h"
+// #include "../../../Crypto/Cipher/Common/CipherInterface.h"
+#include "../../Crypto/Rar20/Rar20Cipher.h"
+#include "../../Crypto/RarAES/RarAES.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;
+ value += (int)rarTime.LowSecond * 10000000;
+ UINT64 subTime = ((UINT64)rarTime.SubTime[2] << 16) +
+ ((UINT64)rarTime.SubTime[1] << 8) +
+ ((UINT64)rarTime.SubTime[0]);
+ // value += (subTime * 10000000) >> 24;
+ value += subTime;
+ 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:
+ if (item.HasUnicodeName())
+ propVariant = item.UnicodeName;
+ else
+ propVariant = (const wchar_t *)MultiByteToUnicodeString(item.Name, CP_OEMCP);
+ 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];
+ _itow (item.Method - BYTE('0'), temp, 10);
+ method += temp;
+ if (!item.IsDirectory())
+ {
+ method += L":";
+ _itow (16 + item.GetDictSize(), temp, 10);
+ method += temp;
+ }
+ }
+ else
+ {
+ wchar_t temp[32];
+ _itow (item.Method, temp, 10);
+ 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;
+ 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;
+ }
+};
+
+STDMETHODIMP CHandler::Open(IInStream *stream,
+ const UINT64 *maxCheckStartPosition,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ COM_TRY_BEGIN
+ Close();
+ try
+ {
+ CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
+ 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));
+ }
+
+ while(true)
+ {
+ 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;
+ while(archive.GetNextItem(item))
+ {
+ 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;
+ for(int 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;
+
+ CMyComPtr<ICompressCoder> rar20CryptoDecoder;
+ CMyComPtr<ICompressCoder> 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->Init(realOutStream);
+ 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;
+
+ if (item.IsEncrypted())
+ {
+ CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
+ if (item.UnPackVersion >= 29)
+ {
+ if (!rar29CryptoDecoder)
+ {
+ rar29CryptoDecoder = new NCrypto::NRar29::CDecoder();
+ // RINOK(rar29CryptoDecoder.CoCreateInstance(CLSID_CCryptoRar29Decoder));
+ }
+ CMyComPtr<ICompressSetDecoderProperties> cryptoProperties;
+ RINOK(rar29CryptoDecoder.QueryInterface(IID_ICompressSetDecoderProperties,
+ &cryptoProperties));
+ CSequentialInStreamImp *inStreamSpec = new CSequentialInStreamImp;
+ CMyComPtr<ISequentialInStream> inStreamProperties(inStreamSpec);
+ inStreamSpec->Init(item.Salt, item.HasSalt() ? sizeof(item.Salt) : 0);
+ RINOK(cryptoProperties->SetDecoderProperties(inStreamProperties));
+ RINOK(rar29CryptoDecoder.QueryInterface(IID_ICryptoSetPassword,
+ &cryptoSetPassword));
+ }
+ else if (item.UnPackVersion >= 20)
+ {
+ if (!rar20CryptoDecoder)
+ {
+ rar20CryptoDecoder = new NCrypto::NRar20::CDecoder();
+ // RINOK(rar20CryptoDecoder.CoCreateInstance(CLSID_CCryptoRar20Decoder));
+ }
+ RINOK(rar20CryptoDecoder.QueryInterface(IID_ICryptoSetPassword,
+ &cryptoSetPassword));
+ }
+ else
+ {
+ outStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+ continue;
+ }
+
+ if (!getTextPassword)
+ extractCallback.QueryInterface(IID_ICryptoGetTextPassword,
+ &getTextPassword);
+ if (getTextPassword)
+ {
+ CMyComBSTR password;
+ RINOK(getTextPassword->CryptoGetTextPassword(&password));
+ if (item.UnPackVersion >= 29)
+ {
+ RINOK(cryptoSetPassword->CryptoSetPassword(
+ (const BYTE *)(const wchar_t *)password,
+ password.Length() * sizeof(wchar_t)));
+ }
+ 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));
+ }
+ }
+ switch(item.Method)
+ {
+ case '0':
+ {
+ if(copyCoderSpec == NULL)
+ {
+ copyCoderSpec = new NCompress::CCopyCoder;
+ copyCoder = copyCoderSpec;
+ }
+
+ if (item.IsEncrypted())
+ {
+ {
+ if (!mixerCoder || !mixerCoderStoreMethod ||
+ item.UnPackVersion != mixerCryptoVersion)
+ {
+ mixerCoder.Release();
+ mixerCoderSpec = new CCoderMixer;
+ mixerCoder = mixerCoderSpec;
+ if (item.UnPackVersion >= 29)
+ mixerCoderSpec->AddCoder(rar29CryptoDecoder);
+ else
+ mixerCoderSpec->AddCoder(rar20CryptoDecoder);
+ mixerCoderSpec->AddCoder(copyCoder);
+ mixerCoderSpec->FinishAddingCoders();
+ mixerCoderStoreMethod = true;
+ mixerCryptoVersion = item.UnPackVersion;
+ }
+ mixerCoderSpec->ReInit();
+ mixerCoderSpec->SetCoderInfo(0, &packSize, &item.UnPackSize);
+ mixerCoderSpec->SetCoderInfo(1, &item.UnPackSize, &item.UnPackSize);
+ mixerCoderSpec->SetProgressCoderIndex(1);
+
+ RINOK(mixerCoder->Code(folderInStream, outStream,
+ NULL, NULL, compressProgress));
+ }
+ }
+ else
+ {
+ RINOK(copyCoder->Code(folderInStream, outStream,
+ NULL, NULL, compressProgress));
+ }
+ 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<ICompressSetDecoderProperties> compressSetDecoderProperties;
+ RINOK(decoder.QueryInterface(IID_ICompressSetDecoderProperties,
+ &compressSetDecoderProperties));
+
+ BYTE isSolid = (
+ // item.IsSolid()
+ IsSolid(index)
+ ||
+ item.IsSplitBefore())
+ ? 1: 0;
+
+ CSequentialInStreamImp *inStreamSpec = new CSequentialInStreamImp;
+ CMyComPtr<ISequentialInStream> inStreamProperties(inStreamSpec);
+ inStreamSpec->Init(&isSolid, 1);
+ RINOK(compressSetDecoderProperties->SetDecoderProperties(inStreamProperties));
+
+ HRESULT result;
+ if (item.IsEncrypted())
+ {
+ if (!mixerCoder || mixerCoderStoreMethod)
+ {
+ mixerCoder.Release();
+ mixerCoderSpec = new CCoderMixer;
+ mixerCoder = mixerCoderSpec;
+ if (item.UnPackVersion >= 29)
+ mixerCoderSpec->AddCoder(rar29CryptoDecoder);
+ else
+ mixerCoderSpec->AddCoder(rar20CryptoDecoder);
+ mixerCoderSpec->AddCoder(decoder);
+ mixerCoderSpec->FinishAddingCoders();
+ mixerCoderStoreMethod = false;
+ }
+ mixerCoderSpec->ReInit();
+ mixerCoderSpec->SetCoderInfo(1, &packSize,
+ &item.UnPackSize);
+ mixerCoderSpec->SetProgressCoderIndex(1);
+ result = mixerCoder->Code(folderInStream, outStream,
+ NULL, NULL, compressProgress);
+ }
+ else
+ {
+ result = decoder->Code(folderInStream, outStream,
+ &packSize, &item.UnPackSize, compressProgress);
+ }
+ if (result == S_FALSE)
+ {
+ outStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
+ continue;
+ }
+ if (result != S_OK)
+ return result;
+ break;
+ }
+ default:
+ outStream.Release();
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+ continue;
+ }
+
+ /*
+ 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/7zip/Archive/Rar/RarHandler.h b/7zip/Archive/Rar/RarHandler.h
new file mode 100755
index 00000000..e75fcb86
--- /dev/null
+++ b/7zip/Archive/Rar/RarHandler.h
@@ -0,0 +1,65 @@
+// Rar/Handler.h
+
+#pragma once
+
+#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 \ No newline at end of file
diff --git a/7zip/Archive/Rar/RarHeader.cpp b/7zip/Archive/Rar/RarHeader.cpp
new file mode 100755
index 00000000..dd47f886
--- /dev/null
+++ b/7zip/Archive/Rar/RarHeader.cpp
@@ -0,0 +1,64 @@
+// Archive::Rar::Headers.cpp
+
+#include "StdAfx.h"
+
+#include "RarHeader.h"
+#include "Common/CRC.h"
+
+static void UpdateCRCBytesWithoutStartBytes(CCRC &crc, const void *data,
+ UINT32 size, UINT32 exludeSize)
+{
+ crc.Update(((const BYTE *)data) + exludeSize, size - exludeSize);
+}
+
+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 aMarkerInitializer;
+
+namespace NArchive
+{
+ UINT16 CBlock::GetRealCRC() const
+ {
+ CCRC crc;
+ UpdateCRCBytesWithoutStartBytes(crc, this,
+ sizeof(*this), sizeof(CRC));
+ return UINT16(crc.GetDigest());
+ }
+}
+
+namespace NFile
+{
+ /*
+ UINT16 CBlock32::GetRealCRC(const void *aName, UINT32 aNameSize,
+ bool anExtraDataDefined, BYTE *anExtraData) const
+ {
+ CCRC crc;
+ UpdateCRCBytesWithoutStartBytes(crc, this,
+ sizeof(*this), sizeof(HeadCRC));
+ crc.Update(aName, aNameSize);
+ if (anExtraDataDefined)
+ crc.Update(anExtraData, 8);
+ return UINT16(crc.GetDigest());
+ }
+ UINT16 CBlock64::GetRealCRC(const void *aName, UINT32 aNameSize) const
+ {
+ CCRC crc;
+ UpdateCRCBytesWithoutStartBytes(crc, this,
+ sizeof(*this), sizeof(HeadCRC));
+ crc.Update(aName, aNameSize);
+ return UINT16(crc.GetDigest());
+ }
+ */
+}
+
+}}} \ No newline at end of file
diff --git a/7zip/Archive/Rar/RarHeader.h b/7zip/Archive/Rar/RarHeader.h
new file mode 100755
index 00000000..642778ed
--- /dev/null
+++ b/7zip/Archive/Rar/RarHeader.h
@@ -0,0 +1,214 @@
+// Archive::Rar::Header.h
+
+#pragma once
+
+#ifndef __ARCHIVE_RAR_HEADER_H
+#define __ARCHIVE_RAR_HEADER_H
+
+#include "Common/Types.h"
+
+#pragma pack(push, PragmaRarHeaders)
+#pragma pack(push, 1)
+
+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)
+
+ struct CBlock
+ {
+ UINT16 CRC;
+ BYTE Type;
+ UINT16 Flags;
+ UINT16 Size;
+ UINT16 Reserved1;
+ UINT32 Reserved2;
+ UINT16 GetRealCRC() const;
+ };
+
+ const int kBlockHeadersAreEncrypted = 0x80;
+}
+
+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];
+};
+
+}}}
+
+#pragma pack(pop)
+#pragma pack(pop, PragmaRarHeaders)
+
+#endif
diff --git a/7zip/Archive/Rar/RarIn.cpp b/7zip/Archive/Rar/RarIn.cpp
new file mode 100755
index 00000000..f21eb588
--- /dev/null
+++ b/7zip/Archive/Rar/RarIn.cpp
@@ -0,0 +1,407 @@
+// Archive/RarIn.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StringConvert.h"
+#include "Common/CRC.h"
+
+#include "RarIn.h"
+#include "../../Common/LimitedStreams.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)
+{
+ 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)
+{
+ // return (memcmp(aTestBytes, NHeader::kMarker, NHeader::kMarkerSize) == 0);
+ 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;
+ while(true)
+ {
+ if (searchHeaderSizeLimit != NULL)
+ if (curTestPos - m_StreamStartPosition > *searchHeaderSizeLimit)
+ return false;
+ UINT32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev;
+ ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize);
+ UINT32 numBytesInBuffer = numBytesPrev + processedSize;
+ if (numBytesInBuffer < NHeader::kMarkerSize)
+ return false;
+ 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;
+}
+
+//bool boolIsItCorrectArchive;
+
+void CInArchive::ThrowUnexpectedEndOfArchiveException()
+{
+ ThrowExceptionWithCode(CInArchiveException::kUnexpectedEndOfArchive);
+}
+
+bool CInArchive::ReadBytesAndTestSize(void *data, UINT32 size)
+{
+ UINT32 processedSize;
+ m_Stream->Read(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 = m_Stream->Read(data, size, &realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ AddToSeekValue(realProcessedSize);
+ return result;
+}
+
+bool CInArchive::ReadMarkerAndArchiveHeader(const UINT64 *searchHeaderSizeLimit)
+{
+ if (!FindAndReadMarker(searchHeaderSizeLimit))
+ return false;
+
+ UINT32 processedSize;
+ ReadBytes(&m_ArchiveHeader, sizeof(m_ArchiveHeader), &processedSize);
+ if (processedSize != sizeof(m_ArchiveHeader))
+ return false;
+
+ if(m_ArchiveHeader.CRC != m_ArchiveHeader.GetRealCRC())
+ 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 - sizeof(m_ArchiveHeader));
+ m_SeekOnArchiveComment = false;
+}
+
+void CInArchive::GetArchiveInfo(CInArchiveInfo &archiveInfo) const
+{
+ archiveInfo.StartPosition = m_ArchiveStartPosition;
+ archiveInfo.Flags = m_ArchiveHeader.Flags;
+ archiveInfo.CommentPosition = m_ArchiveCommentPosition;
+ archiveInfo.CommentSize = m_ArchiveHeader.Size - sizeof(m_ArchiveHeader);
+}
+
+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++] = encName[encPos++] + (highByte << 8);
+ break;
+ case 2:
+ unicodeName[decPos++] = 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] = ((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(const BYTE *data, CItemEx &item, int nameSize)
+{
+ int sizeFileName = nameSize;
+ item.UnicodeName.Empty();
+ if (sizeFileName > 0)
+ {
+ m_NameBuffer.EnsureCapacity(sizeFileName + 1);
+ char *buffer = (char *)m_NameBuffer;
+
+ memmove(buffer, data, sizeFileName);
+
+ int mainLen;
+ for (mainLen = 0; mainLen < sizeFileName; mainLen++)
+ if (buffer[mainLen] == '\0')
+ break;
+ buffer[mainLen] = '\0';
+ item.Name = buffer;
+
+ int unicodeNameSizeMax = MyMin(sizeFileName, (0x400));
+ _unicodeNameBuffer.EnsureCapacity(unicodeNameSizeMax + 1);
+
+ if((m_BlockHeader.Flags & NHeader::NFile::kUnicodeName) != 0 &&
+ mainLen < sizeFileName)
+ {
+ DecodeUnicodeFileName(buffer, (const BYTE *)buffer + mainLen + 1,
+ sizeFileName - (mainLen + 1), _unicodeNameBuffer, unicodeNameSizeMax);
+ item.UnicodeName = _unicodeNameBuffer;
+ }
+ }
+ else
+ item.Name.Empty();
+}
+
+static const BYTE *ReadTime(const BYTE *data, BYTE mask, CRarTime &rarTime)
+{
+ rarTime.LowSecond = ((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] = *data++;
+ return data;
+}
+
+void CInArchive::ReadHeaderReal(const BYTE *data, CItemEx &item)
+{
+ const BYTE *dataStart = data;
+ const NHeader::NFile::CBlock &fileHeader =
+ *(const NHeader::NFile::CBlock *)data;
+ // UINT32 sizeFileName = fileHeader.NameSize;
+
+ item.Flags = m_BlockHeader.Flags;
+ item.PackSize = fileHeader.PackSize;
+ item.UnPackSize = fileHeader.UnPackSize;
+ item.HostOS = fileHeader.HostOS;
+ item.FileCRC = fileHeader.FileCRC;
+ item.LastWriteTime.DosTime = fileHeader.Time;
+ item.LastWriteTime.LowSecond = 0;
+ item.LastWriteTime.SubTime[0] =
+ item.LastWriteTime.SubTime[1] =
+ item.LastWriteTime.SubTime[2] = 0;
+
+
+ item.UnPackVersion = fileHeader.UnPackVersion;
+ item.Method = fileHeader.Method;
+ item.Attributes = fileHeader.Attributes;
+
+ data += sizeof(fileHeader);
+
+ if((item.Flags & NHeader::NFile::kSize64Bits) != 0)
+ {
+ item.PackSize |= (*((const UINT64 *)data)) << 32;
+ data += sizeof(UINT32);
+ item.UnPackSize |= (*((const UINT64 *)data)) << 32;
+ data += sizeof(UINT32);
+ }
+
+ ReadName(data, item, fileHeader.NameSize);
+ data += fileHeader.NameSize;
+
+ if (item.HasSalt())
+ {
+ memmove(item.Salt, data, sizeof(item.Salt));
+ data += sizeof(item.Salt);
+ }
+
+ if (item.HasExtTime())
+ {
+ BYTE access = (*data) >> 4;
+ data++;
+ BYTE modif = (*data) >> 4;
+ BYTE creat = (*data) & 0xF;
+ data++;
+ if ((modif & 8) != 0)
+ data = ReadTime(data, modif, item.LastWriteTime);
+ if (item.IsCreationTimeDefined = ((creat & 8) != 0))
+ {
+ item.CreationTime.DosTime = *(const UINT32 *)data;
+ data += sizeof(UINT32);
+ data = ReadTime(data, creat, item.CreationTime);
+ }
+ if (item.IsLastAccessTimeDefined = ((access & 8) != 0))
+ {
+ item.LastAccessTime.DosTime = *(const UINT32 *)data;
+ data += sizeof(UINT32);
+ data = ReadTime(data, access, item.LastAccessTime);
+ }
+ }
+
+ UINT16 fileHeaderWithNameSize =
+ sizeof(NHeader::NBlock::CBlock) + data - dataStart;
+
+ item.Position = m_Position;
+ item.MainPartSize = fileHeaderWithNameSize;
+ item.CommentSize = m_BlockHeader.HeadSize - fileHeaderWithNameSize;
+
+ AddToSeekValue(m_BlockHeader.HeadSize);
+}
+
+void CInArchive::AddToSeekValue(UINT64 addValue)
+{
+ m_Position += addValue;
+}
+
+bool CInArchive::GetNextItem(CItemEx &item)
+{
+ if ((m_ArchiveHeader.Flags &
+ NHeader::NArchive::kBlockHeadersAreEncrypted) != 0)
+ return false;
+ if (m_SeekOnArchiveComment)
+ SkipArchiveComment();
+ while (true)
+ {
+ if(!SeekInArchive(m_Position))
+ return false;
+ if(!ReadBytesAndTestSize(&m_BlockHeader, sizeof(m_BlockHeader)))
+ return false;
+
+ if (m_BlockHeader.HeadSize < 7)
+ ThrowExceptionWithCode(CInArchiveException::kIncorrectArchive);
+
+ if (m_BlockHeader.Type == NHeader::NBlockType::kFileHeader)
+ {
+ m_FileHeaderData.EnsureCapacity(m_BlockHeader.HeadSize);
+ UINT32 headerSize = m_BlockHeader.HeadSize - sizeof(m_BlockHeader);
+ ReadBytesAndTestResult(m_FileHeaderData, headerSize);
+ CCRC crc;
+ crc.Update(&m_BlockHeader.Type, sizeof(m_BlockHeader) -
+ sizeof(m_BlockHeader.CRC));
+
+ ReadHeaderReal(m_FileHeaderData, item);
+
+ crc.Update(m_FileHeaderData, headerSize - item.CommentSize);
+ if ((crc.GetDigest() & 0xFFFF) != m_BlockHeader.CRC)
+ ThrowExceptionWithCode(CInArchiveException::kFileHeaderCRCError);
+
+ SeekInArchive(m_Position); // Move Position to compressed Data;
+ AddToSeekValue(item.PackSize); // m_Position points Tto next header;
+ return true;
+ }
+ if ((m_BlockHeader.Flags & NHeader::NBlock::kLongBlock) != 0)
+ {
+ UINT32 dataSize;
+ ReadBytesAndTestResult(&dataSize, sizeof(dataSize)); // test it
+ AddToSeekValue(dataSize);
+ }
+ AddToSeekValue(m_BlockHeader.HeadSize);
+ }
+}
+
+
+void CInArchive::DirectGetBytes(void *data, UINT32 size)
+{
+ m_Stream->Read(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->Init(m_Stream, size);
+ return inStream.Detach();
+}
+
+}}
diff --git a/7zip/Archive/Rar/RarIn.h b/7zip/Archive/Rar/RarIn.h
new file mode 100755
index 00000000..242787c2
--- /dev/null
+++ b/7zip/Archive/Rar/RarIn.h
@@ -0,0 +1,96 @@
+// RarIn.h
+
+#pragma once
+
+#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 "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; }
+};
+
+class CInArchive
+{
+ CMyComPtr<IInStream> m_Stream;
+
+ UINT64 m_StreamStartPosition;
+ UINT64 m_Position;
+ UINT64 m_ArchiveStartPosition;
+
+ NHeader::NArchive::CBlock m_ArchiveHeader;
+ CDynamicBuffer<char> m_NameBuffer;
+ CDynamicBuffer<wchar_t> _unicodeNameBuffer;
+ bool m_SeekOnArchiveComment;
+ UINT64 m_ArchiveCommentPosition;
+
+ void ReadName(const BYTE *data, CItemEx &item, int nameSize);
+ void ReadHeaderReal(const BYTE *data, 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;
+
+ bool ReadMarkerAndArchiveHeader(const UINT64 *searchHeaderSizeLimit);
+public:
+ bool Open(IInStream *inStream, const UINT64 *searchHeaderSizeLimit);
+ void Close();
+ bool GetNextItem(CItemEx &item);
+
+ 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/7zip/Archive/Rar/RarItem.cpp b/7zip/Archive/Rar/RarItem.cpp
new file mode 100755
index 00000000..761f233e
--- /dev/null
+++ b/7zip/Archive/Rar/RarItem.cpp
@@ -0,0 +1,108 @@
+// 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
+{
+ return (GetDictSize() == NHeader::NFile::kDictDirectoryValue);
+}
+
+UINT32 CItem::GetWinAttributes() const
+{
+ UINT32 aWinAttributes;
+ switch(HostOS)
+ {
+ case NHeader::NFile::kHostMSDOS:
+ case NHeader::NFile::kHostOS2:
+ case NHeader::NFile::kHostWin32:
+ aWinAttributes = Attributes;
+ break;
+ default:
+ aWinAttributes = 0; // must be converted from unix value;;
+ }
+ if (IsDirectory()) // test it;
+ aWinAttributes |= NHeader::NFile::kWinFileDirectoryAttributeMask;
+ return aWinAttributes;
+}
+
+void CItem::ClearFlags()
+{ Flags = 0; }
+
+void CItem::SetFlagBits(int aStartBitNumber, int aNumBits, int aValue)
+{
+ UINT16 aMask = ((1 << aNumBits) - 1) << aStartBitNumber;
+ Flags &= ~aMask;
+ Flags |= aValue << aStartBitNumber;
+}
+
+void CItem::SetBitMask(int aBitMask, bool anEnable)
+{
+ if(anEnable)
+ Flags |= aBitMask;
+ else
+ Flags &= ~aBitMask;
+}
+
+void CItem::SetDictSize(UINT32 aSize)
+{
+ SetFlagBits(NHeader::NFile::kDictBitStart, NHeader::NFile::kNumDictBits, (aSize & NHeader::NFile::kDictMask));
+}
+
+void CItem::SetAsDirectory(bool aDirectory)
+{
+ if (aDirectory)
+ SetDictSize(NHeader::NFile::kDictDirectoryValue);
+}
+
+void CItem::SetEncrypted(bool anEncrypted)
+ { SetBitMask(NHeader::NFile::kEncrypted, anEncrypted); }
+void CItem::SetSolid(bool aSolid)
+ { SetBitMask(NHeader::NFile::kSolid, aSolid); }
+void CItem::SetCommented(bool aCommented)
+ { SetBitMask(NHeader::NFile::kComment, aCommented); }
+void CItem::SetSplitBefore(bool aSplitBefore)
+ { SetBitMask(NHeader::NFile::kSplitBefore, aSplitBefore); }
+void CItem::SetSplitAfter(bool aSplitAfter)
+ { SetBitMask(NHeader::NFile::kSplitAfter, aSplitAfter); }
+
+}}
diff --git a/7zip/Archive/Rar/RarItem.h b/7zip/Archive/Rar/RarItem.h
new file mode 100755
index 00000000..55c1086d
--- /dev/null
+++ b/7zip/Archive/Rar/RarItem.h
@@ -0,0 +1,92 @@
+// RarItem.h
+
+#pragma once
+
+#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 aStartBitNumber, int aNumBits, int aValue);
+ void SetBitMask(int aBitMask, bool anEnable);
+public:
+ void ClearFlags();
+ void SetDictSize(UINT32 aSize);
+ void SetAsDirectory(bool aDirectory);
+ void SetEncrypted(bool anEncrypted);
+ void SetSolid(bool aSolid);
+ void SetCommented(bool aCommented);
+ void SetSplitBefore(bool aSplitBefore);
+ void SetSplitAfter(bool aSplitAfter);
+};
+
+class CItemEx: public CItem
+{
+public:
+ UINT64 Position;
+ UINT16 MainPartSize;
+ UINT16 CommentSize;
+ UINT64 GetFullSize() const { return MainPartSize + CommentSize + PackSize; };
+ // DWORD GetHeaderWithCommentSize() const { return MainPartSize + CommentSize; };
+ UINT64 GetCommentPosition() const { return Position + MainPartSize; };
+ UINT64 GetDataPosition() const { return GetCommentPosition() + CommentSize; };
+};
+
+}}
+
+#endif
+
+
diff --git a/7zip/Archive/Rar/RarItemEx.h b/7zip/Archive/Rar/RarItemEx.h
new file mode 100755
index 00000000..509208dc
--- /dev/null
+++ b/7zip/Archive/Rar/RarItemEx.h
@@ -0,0 +1,19 @@
+// Archive::Rar::ItemInfoEx.h
+
+#pragma once
+
+#ifndef __ARCHIVE_RAR_ITEMINFOEX_H
+#define __ARCHIVE_RAR_ITEMINFOEX_H
+
+#include "Archive/Rar/ItemInfo.h"
+
+namespace NArchive{
+namespace NRar{
+
+
+}}
+
+#endif
+
+
+
diff --git a/7zip/Archive/Rar/RarVolumeInStream.cpp b/7zip/Archive/Rar/RarVolumeInStream.cpp
new file mode 100755
index 00000000..97efdb77
--- /dev/null
+++ b/7zip/Archive/Rar/RarVolumeInStream.cpp
@@ -0,0 +1,83 @@
+// 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;
+ }
+ else
+ {
+ RINOK(OpenStream());
+ }
+ }
+ if (processedSize != 0)
+ *processedSize = realProcessedSize;
+ return S_OK;
+}
+
+STDMETHODIMP CFolderInStream::ReadPart(void *data, UINT32 size, UINT32 *processedSize)
+{
+ return Read(data, size, processedSize);
+}
+
+}} \ No newline at end of file
diff --git a/7zip/Archive/Rar/RarVolumeInStream.h b/7zip/Archive/Rar/RarVolumeInStream.h
new file mode 100755
index 00000000..263d636c
--- /dev/null
+++ b/7zip/Archive/Rar/RarVolumeInStream.h
@@ -0,0 +1,53 @@
+// RarVolumeInStream.h
+
+#pragma once
+
+#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);
+ STDMETHOD(ReadPart)(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/7zip/Archive/Rar/StdAfx.cpp b/7zip/Archive/Rar/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Archive/Rar/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Archive/Rar/StdAfx.h b/7zip/Archive/Rar/StdAfx.h
new file mode 100755
index 00000000..97eb50d1
--- /dev/null
+++ b/7zip/Archive/Rar/StdAfx.h
@@ -0,0 +1,9 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+#include <time.h>
+
+#endif
diff --git a/7zip/Archive/Rar/rar.ico b/7zip/Archive/Rar/rar.ico
new file mode 100755
index 00000000..2918d294
--- /dev/null
+++ b/7zip/Archive/Rar/rar.ico
Binary files differ
diff --git a/7zip/Archive/Rar/resource.h b/7zip/Archive/Rar/resource.h
new file mode 100755
index 00000000..7b0dd8ff
--- /dev/null
+++ b/7zip/Archive/Rar/resource.h
@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDI_ICON1 101
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Archive/Rar/resource.rc b/7zip/Archive/Rar/resource.rc
new file mode 100755
index 00000000..731e0c29
--- /dev/null
+++ b/7zip/Archive/Rar/resource.rc
@@ -0,0 +1,130 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,12,0,0
+ PRODUCTVERSION 3,12,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov \0"
+ VALUE "FileDescription", "Rar Plugin for 7-Zip\0"
+ VALUE "FileVersion", "3, 12, 0, 0\0"
+ VALUE "InternalName", "rar\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "rar.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 12, 0, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1 ICON DISCARDABLE "Rar.ico"
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Archive/Split/DllExports.cpp b/7zip/Archive/Split/DllExports.cpp
new file mode 100755
index 00000000..11053845
--- /dev/null
+++ b/7zip/Archive/Split/DllExports.cpp
@@ -0,0 +1,63 @@
+// DLLExports.cpp : Implementation of DLL Exports.
+
+#include "StdAfx.h"
+
+#include <initguid.h>
+
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+#include "SplitHandler.h"
+#include "../../ICoder.h"
+
+// {23170F69-40C1-278A-1000-0001100B0000}
+DEFINE_GUID(CLSID_CSplitHandler,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x0B, 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;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/7zip/Archive/Split/Split.def b/7zip/Archive/Split/Split.def
new file mode 100755
index 00000000..8deaffce
--- /dev/null
+++ b/7zip/Archive/Split/Split.def
@@ -0,0 +1,8 @@
+; split.def
+
+LIBRARY split
+
+EXPORTS
+ CreateObject
+ GetHandlerProperty
+
diff --git a/7zip/Archive/Split/Split.dsp b/7zip/Archive/Split/Split.dsp
new file mode 100755
index 00000000..04a246af
--- /dev/null
+++ b/7zip/Archive/Split/Split.dsp
@@ -0,0 +1,217 @@
+# 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=.\DllExports.cpp
+# 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=.\Split.def
+# 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\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\ProgressUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.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=.\SplitHanlerOut.cpp
+# End Source File
+# End Target
+# End Project
diff --git a/7zip/Archive/Split/Split.dsw b/7zip/Archive/Split/Split.dsw
new file mode 100755
index 00000000..988ca30a
--- /dev/null
+++ b/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/7zip/Archive/Split/Split.ico b/7zip/Archive/Split/Split.ico
new file mode 100755
index 00000000..5cb93e84
--- /dev/null
+++ b/7zip/Archive/Split/Split.ico
Binary files differ
diff --git a/7zip/Archive/Split/SplitHandler.cpp b/7zip/Archive/Split/SplitHandler.cpp
new file mode 100755
index 00000000..0024804d
--- /dev/null
+++ b/7zip/Archive/Split/SplitHandler.cpp
@@ -0,0 +1,392 @@
+// 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"
+
+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;
+ bool mustBeClosed = true;
+ // 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 = *(UINT64 *)(&propVariant.uhVal);
+ }
+ _totalSize += size;
+
+ if (openArchiveCallback != NULL)
+ {
+ RINOK(openArchiveCallback->SetTotal(NULL, NULL));
+ UINT64 numFiles = _streams.Size();
+ RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
+ }
+
+ while (true)
+ {
+ 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 = *(UINT64 *)(&propVariant.uhVal);
+ }
+ _totalSize += 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()
+{
+ _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
+}
+
+}}
diff --git a/7zip/Archive/Split/SplitHandler.h b/7zip/Archive/Split/SplitHandler.h
new file mode 100755
index 00000000..149995fb
--- /dev/null
+++ b/7zip/Archive/Split/SplitHandler.h
@@ -0,0 +1,60 @@
+// Split/Handler.h
+
+#pragma once
+
+#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 IOutArchive,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP1(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);
+
+ /*
+ // IOutArchiveHandler
+ STDMETHOD(UpdateItems)(IOutStream *outStream, UINT32 numItems,
+ IArchiveUpdateCallback *updateCallback);
+
+ STDMETHOD(GetFileTimeType)(UINT32 *type);
+ */
+
+private:
+ UString _subName;
+ UString _name;
+ CObjectVector<CMyComPtr<IInStream> > _streams;
+
+ UINT64 _totalSize;
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/7zip/Archive/Split/SplitHanlerOut.cpp b/7zip/Archive/Split/SplitHanlerOut.cpp
new file mode 100755
index 00000000..a7eddb14
--- /dev/null
+++ b/7zip/Archive/Split/SplitHanlerOut.cpp
@@ -0,0 +1,93 @@
+// 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(IOutStream *outStream, UINT32 numItems,
+ IArchiveUpdateCallback *updateCallback)
+{
+ COM_TRY_BEGIN
+
+ if (numItems != 1)
+ return E_INVALIDARG;
+
+ UINT64 volumeSize;
+ RINOK(updateCallback->GetVolumeSize(0, &volumeSize));
+
+ INT32 newData;
+ INT32 newProperties;
+ UINT32 indexInArchive;
+ if (!updateCallback)
+ return E_FAIL;
+
+ UINT32 fileIndex;
+ 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 = *(const UINT64 *)(&propVariant.uhVal);
+ }
+ else
+ thereIsCopyData = true;
+
+ return S_OK;
+ COM_TRY_END
+}
+*/
+
+}}
diff --git a/7zip/Archive/Split/StdAfx.cpp b/7zip/Archive/Split/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Archive/Split/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Archive/Split/StdAfx.h b/7zip/Archive/Split/StdAfx.h
new file mode 100755
index 00000000..a32fbed6
--- /dev/null
+++ b/7zip/Archive/Split/StdAfx.h
@@ -0,0 +1,8 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#endif
diff --git a/7zip/Archive/Split/resource.h b/7zip/Archive/Split/resource.h
new file mode 100755
index 00000000..7b0dd8ff
--- /dev/null
+++ b/7zip/Archive/Split/resource.h
@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDI_ICON1 101
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Archive/Split/resource.rc b/7zip/Archive/Split/resource.rc
new file mode 100755
index 00000000..d1ab6f96
--- /dev/null
+++ b/7zip/Archive/Split/resource.rc
@@ -0,0 +1,130 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1 ICON DISCARDABLE "Split.ico"
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,9,2,0
+ PRODUCTVERSION 3,9,2,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "Split Plugin for 7-Zip\0"
+ VALUE "FileVersion", "3, 9, 2, 0\0"
+ VALUE "InternalName", "split\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "split.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 9, 2, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Archive/Tar/DllExports.cpp b/7zip/Archive/Tar/DllExports.cpp
new file mode 100755
index 00000000..ef4aa1b9
--- /dev/null
+++ b/7zip/Archive/Tar/DllExports.cpp
@@ -0,0 +1,80 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include <initguid.h>
+
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+#include "../../ICoder.h"
+#include "TarHandler.h"
+
+// {23170F69-40C1-278A-1000-000110040000}
+DEFINE_GUID(CLSID_CTarHandler,
+ 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_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;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/7zip/Archive/Tar/StdAfx.cpp b/7zip/Archive/Tar/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Archive/Tar/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Archive/Tar/StdAfx.h b/7zip/Archive/Tar/StdAfx.h
new file mode 100755
index 00000000..6075e527
--- /dev/null
+++ b/7zip/Archive/Tar/StdAfx.h
@@ -0,0 +1,9 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+#include <time.h>
+
+#endif
diff --git a/7zip/Archive/Tar/Tar.def b/7zip/Archive/Tar/Tar.def
new file mode 100755
index 00000000..248b0eaf
--- /dev/null
+++ b/7zip/Archive/Tar/Tar.def
@@ -0,0 +1,7 @@
+; Tar.def
+
+LIBRARY Tar.dll
+
+EXPORTS
+ CreateObject PRIVATE
+ GetHandlerProperty PRIVATE
diff --git a/7zip/Archive/Tar/Tar.dsp b/7zip/Archive/Tar/Tar.dsp
new file mode 100755
index 00000000..ec9f3cfa
--- /dev/null
+++ b/7zip/Archive/Tar/Tar.dsp
@@ -0,0 +1,269 @@
+# 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=.\DllExports.cpp
+# 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
+# Begin Source File
+
+SOURCE=.\Tar.def
+# 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\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=.\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
+# End Group
+# End Target
+# End Project
diff --git a/7zip/Archive/Tar/Tar.dsw b/7zip/Archive/Tar/Tar.dsw
new file mode 100755
index 00000000..318cce1c
--- /dev/null
+++ b/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/7zip/Archive/Tar/TarHandler.cpp b/7zip/Archive/Tar/TarHandler.cpp
new file mode 100755
index 00000000..480a1f44
--- /dev/null
+++ b/7zip/Archive/Tar/TarHandler.cpp
@@ -0,0 +1,281 @@
+// 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
+ bool mustBeClosed = true;
+ // 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));
+ }
+
+ while(true)
+ {
+ 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()
+{
+ _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(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->Init(_inStream, 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/7zip/Archive/Tar/TarHandler.h b/7zip/Archive/Tar/TarHandler.h
new file mode 100755
index 00000000..526fb233
--- /dev/null
+++ b/7zip/Archive/Tar/TarHandler.h
@@ -0,0 +1,58 @@
+// Tar/Handler.h
+
+#pragma once
+
+#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)(IOutStream *outStream, UINT32 numItems,
+ IArchiveUpdateCallback *updateCallback);
+ STDMETHOD(GetFileTimeType)(UINT32 *type);
+
+private:
+ CObjectVector<CItemEx> _items;
+ CMyComPtr<IInStream> _inStream;
+};
+
+}}
+
+#endif
diff --git a/7zip/Archive/Tar/TarHandlerOut.cpp b/7zip/Archive/Tar/TarHandlerOut.cpp
new file mode 100755
index 00000000..93ca7747
--- /dev/null
+++ b/7zip/Archive/Tar/TarHandlerOut.cpp
@@ -0,0 +1,122 @@
+// 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(IOutStream *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))
+ 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 = *(UINT64 *)(&propVariant.uhVal);
+ }
+ updateItem.Size = size;
+ }
+ updateItems.Add(updateItem);
+ }
+ return UpdateArchive(_inStream, outStream, _items, updateItems, updateCallback);
+ COM_TRY_END
+}
+
+}}
diff --git a/7zip/Archive/Tar/TarHeader.cpp b/7zip/Archive/Tar/TarHeader.cpp
new file mode 100755
index 00000000..7b954aa1
--- /dev/null
+++ b/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";
+
+ // The magic field is filled with this if uname and gname are valid.
+ namespace NMagic
+ {
+ const char *kUsTar = "ustar "; // 7 chars and a null
+ const char *kGNUTar = "GNUtar "; // 7 chars and a null
+ const char *kEmpty = "\0\0\0\0\0\0\0\0"; // 7 chars and a null
+ }
+
+}}}
+
diff --git a/7zip/Archive/Tar/TarHeader.h b/7zip/Archive/Tar/TarHeader.h
new file mode 100755
index 00000000..c7bc4785
--- /dev/null
+++ b/7zip/Archive/Tar/TarHeader.h
@@ -0,0 +1,107 @@
+// Archive/Tar/Header.h
+
+#pragma once
+
+#ifndef __ARCHIVE_TAR_HEADER_H
+#define __ARCHIVE_TAR_HEADER_H
+
+#include "Common/Types.h"
+
+namespace NArchive {
+namespace NTar {
+
+#pragma pack( push, PragmaTarHeaders)
+#pragma pack( push, 1)
+
+namespace NFileHeader
+{
+ const int kRecordSize = 512;
+ const int kNameSize = 100;
+ const int kUserNameSize = 32;
+ const int kGroupNameSize = 32;
+
+ 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];
+ /*
+ BYTE Padding[kRecordSize - (kNameSize + 8 + 8 + 12 + 12 + 8 + 1 + kNameSize + 8 +
+ kUserNameSize + kGroupNameSize + 8 + 8)];
+ */
+ };
+ 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";
+
+ // The magic field is filled with this if uname and gname are valid.
+ namespace NMagic
+ {
+ extern const char *kUsTar; // = "ustar "; // 7 chars and a null
+ extern const char *kGNUTar; // = "GNUtar "; // 7 chars and a null
+ extern const char *kEmpty; // = "GNUtar "; // 7 chars and a null
+ }
+
+}
+
+#pragma pack(pop)
+#pragma pack(pop, PragmaTarHeaders)
+
+}}
+
+#endif
diff --git a/7zip/Archive/Tar/TarIn.cpp b/7zip/Archive/Tar/TarIn.cpp
new file mode 100755
index 00000000..e5f31bb1
--- /dev/null
+++ b/7zip/Archive/Tar/TarIn.cpp
@@ -0,0 +1,191 @@
+// Archive/TarIn.cpp
+
+#include "StdAfx.h"
+
+#include "TarIn.h"
+#include "TarHeader.h"
+
+#include "Windows/Defs.h"
+
+namespace NArchive {
+namespace NTar {
+
+HRESULT CInArchive::ReadBytes(void *data, UINT32 size, UINT32 &processedSize)
+{
+ RINOK(m_Stream->Read(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 UINT32 OctalToNumber(const char *srcString)
+{
+ char *endPtr;
+ return(strtoul(srcString, &endPtr, 8));
+}
+
+static bool CheckOctalString(const char *srcString, int numChars)
+{
+ for(int i = 0; i < numChars; i++)
+ {
+ char c = srcString[i];
+ if (c == 0)
+ return true;
+ if (c >= '0' && c <= '7')
+ continue;
+ if (c != ' ')
+ return false;
+ }
+ return true;
+}
+
+#define ReturnIfBadOctal(x, y) { if (!CheckOctalString((x), (y))) return S_FALSE; }
+
+static bool IsRecordLast(const NFileHeader::CRecord &record)
+{
+ for (int i = 0; i < sizeof(record); i++)
+ if (record.Padding[i] != 0)
+ return false;
+ return true;
+}
+
+HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item)
+{
+ item.LongLinkSize = 0;
+ NFileHeader::CRecord record;
+ filled = false;
+
+ UINT32 processedSize;
+ item.HeaderPosition = m_Position;
+ RINOK(ReadBytes(&record, sizeof(record), processedSize));
+ if (processedSize == 0 ||
+ (processedSize == sizeof(record) && IsRecordLast(record)))
+ return S_OK;
+ if (processedSize < sizeof(record))
+ return S_FALSE;
+
+ NFileHeader::CHeader &header = record.Header;
+
+ char tempString[NFileHeader::kNameSize + 1];
+ strncpy(tempString, header.Name, NFileHeader::kNameSize);
+ tempString[NFileHeader::kNameSize] = '\0';
+ item.Name = tempString;
+
+ int i;
+ for (i = 0; i < item.Name.Length(); i++)
+ if (((BYTE)item.Name[i]) < 0x20)
+ return S_FALSE;
+ item.LinkFlag = header.LinkFlag;
+
+ BYTE linkFlag = item.LinkFlag;
+
+ ReturnIfBadOctal(header.Mode, 8);
+ ReturnIfBadOctal(header.UID, 8);
+ ReturnIfBadOctal(header.GID, 8);
+ ReturnIfBadOctal(header.Size, 12);
+ ReturnIfBadOctal(header.ModificationTime, 12);
+ ReturnIfBadOctal(header.CheckSum, 8);
+ ReturnIfBadOctal(header.DeviceMajor, 8);
+ ReturnIfBadOctal(header.DeviceMinor, 8);
+
+ item.Mode = OctalToNumber(header.Mode);
+ item.UID = OctalToNumber(header.UID);
+ item.GID = OctalToNumber(header.GID);
+
+ item.Size = OctalToNumber(header.Size);
+ if (item.LinkFlag == NFileHeader::NLinkFlag::kLink)
+ item.Size = 0;
+
+ item.ModificationTime = OctalToNumber(header.ModificationTime);
+
+
+ item.LinkName = header.LinkName;
+ memmove(item.Magic, header.Magic, 8);
+
+ item.UserName = header.UserName;
+ item.GroupName = header.GroupName;
+
+
+ item.DeviceMajorDefined = (header.DeviceMajor[0] != 0);
+ if (item.DeviceMajorDefined)
+ item.DeviceMajor = OctalToNumber(header.DeviceMajor);
+
+ item.DeviceMinorDefined = (header.DeviceMinor[0] != 0);
+ if (item.DeviceMinorDefined)
+ item.DeviceMinor = OctalToNumber(header.DeviceMinor);
+
+ UINT32 checkSum = OctalToNumber(header.CheckSum);
+
+ memmove(header.CheckSum, NFileHeader::kCheckSumBlanks, 8);
+
+ UINT32 checkSumReal = 0;
+ for(i = 0; i < NFileHeader::kRecordSize; i++)
+ checkSumReal += BYTE(record.Padding[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)
+ 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 > '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 + 511) &
+ #if ( __GNUC__)
+ 0xFFFFFFFFFFFFFE00LL
+ #else
+ 0xFFFFFFFFFFFFFE00
+ #endif
+ );
+}
+
+}}
diff --git a/7zip/Archive/Tar/TarIn.h b/7zip/Archive/Tar/TarIn.h
new file mode 100755
index 00000000..bac91aee
--- /dev/null
+++ b/7zip/Archive/Tar/TarIn.h
@@ -0,0 +1,32 @@
+// Archive/TarIn.h
+
+#pragma once
+
+#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/7zip/Archive/Tar/TarItem.h b/7zip/Archive/Tar/TarItem.h
new file mode 100755
index 00000000..a63ca6de
--- /dev/null
+++ b/7zip/Archive/Tar/TarItem.h
@@ -0,0 +1,67 @@
+// Archive/Tar/Item.h
+
+#pragma once
+
+#ifndef __ARCHIVE_TAR_ITEM_H
+#define __ARCHIVE_TAR_ITEM_H
+
+#include <time.h>
+
+#include "Common/Types.h"
+#include "Common/String.h"
+#include "TarHeader.h"
+
+namespace NArchive {
+namespace NTar {
+
+class CItem
+{
+public:
+ AString Name;
+ UINT32 Mode;
+ UINT32 UID;
+ UINT32 GID;
+ UINT64 Size;
+ time_t 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)
+ {
+ if (Name.IsEmpty())
+ return false;
+ #ifdef WIN32
+ return (*CharPrevExA(CP_OEMCP, Name, &Name[Name.Length()], 0) == '/');
+ #else
+ return (Name[Name.Length() - 1) == '/');
+ #endif
+ }
+ return false;
+ }
+};
+
+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/7zip/Archive/Tar/TarOut.cpp b/7zip/Archive/Tar/TarOut.cpp
new file mode 100755
index 00000000..ab05309a
--- /dev/null
+++ b/7zip/Archive/Tar/TarOut.cpp
@@ -0,0 +1,155 @@
+// Archive/TarOut.cpp
+
+#include "StdAfx.h"
+
+#include "TarOut.h"
+#include "TarHeader.h"
+
+#include "Windows/Defs.h"
+
+namespace NArchive {
+namespace NTar {
+
+HRESULT COutArchive::WriteBytes(const void *buffer, UINT32 size)
+{
+ UINT32 processedSize;
+ RINOK(m_Stream->Write(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];
+ _ui64toa(value, s, 8);
+ return AString(s) + ' ';
+}
+
+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] = ' ';
+ strcpy(s + numSpaces, 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;
+ strcpy(dest, src);
+ return true;
+}
+
+#define RETURN_IF_NOT_TRUE(x) { if (!(x)) return E_FAIL; }
+
+HRESULT COutArchive::WriteHeaderReal(const CItem &item)
+{
+ NFileHeader::CRecord record;
+ int i;
+ for (i = 0; i < NFileHeader::kRecordSize; i++)
+ record.Padding[i] = 0;
+
+ NFileHeader::CHeader &header = record.Header;
+
+ // RETURN_IF_NOT_TRUE(CopyString(header.Name, item.Name, NFileHeader::kNameSize));
+ if (item.Name.Length() > NFileHeader::kNameSize)
+ return E_FAIL;
+ strncpy(header.Name, item.Name, NFileHeader::kNameSize);
+
+ RETURN_IF_NOT_TRUE(CopyString(header.LinkName, item.LinkName, NFileHeader::kNameSize));
+ RETURN_IF_NOT_TRUE(CopyString(header.UserName, item.UserName, NFileHeader::kUserNameSize));
+ RETURN_IF_NOT_TRUE(CopyString(header.GroupName, item.GroupName, NFileHeader::kGroupNameSize));
+
+ RETURN_IF_NOT_TRUE(MakeOctalString8(header.Mode, item.Mode));
+ RETURN_IF_NOT_TRUE(MakeOctalString8(header.UID, item.UID));
+ RETURN_IF_NOT_TRUE(MakeOctalString8(header.GID, item.GID));
+
+ RETURN_IF_NOT_TRUE(MakeOctalString12(header.Size, item.Size));
+ RETURN_IF_NOT_TRUE(MakeOctalString12(header.ModificationTime, item.ModificationTime));
+ header.LinkFlag = item.LinkFlag;
+ memmove(header.Magic, item.Magic, 8);
+
+ if (item.DeviceMajorDefined)
+ RETURN_IF_NOT_TRUE(MakeOctalString8(header.DeviceMajor, item.DeviceMajor));
+ if (item.DeviceMinorDefined)
+ RETURN_IF_NOT_TRUE(MakeOctalString8(header.DeviceMinor, item.DeviceMinor));
+
+ memmove(header.CheckSum, NFileHeader::kCheckSumBlanks, 8);
+
+ UINT32 checkSumReal = 0;
+ for(i = 0; i < NFileHeader::kRecordSize; i++)
+ checkSumReal += BYTE(record.Padding[i]);
+
+ RETURN_IF_NOT_TRUE(MakeOctalString8(header.CheckSum, checkSumReal));
+
+ return WriteBytes(&record, sizeof(record));
+}
+
+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()
+{
+ NFileHeader::CRecord record;
+ for (int i = 0; i < NFileHeader::kRecordSize; i++)
+ record.Padding[i] = 0;
+ return WriteBytes(&record, sizeof(record));
+}
+
+}}
diff --git a/7zip/Archive/Tar/TarOut.h b/7zip/Archive/Tar/TarOut.h
new file mode 100755
index 00000000..73a50db9
--- /dev/null
+++ b/7zip/Archive/Tar/TarOut.h
@@ -0,0 +1,30 @@
+// Archive/TarOut.h
+
+#pragma once
+
+#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/7zip/Archive/Tar/TarUpdate.cpp b/7zip/Archive/Tar/TarUpdate.cpp
new file mode 100755
index 00000000..d84b0dab
--- /dev/null
+++ b/7zip/Archive/Tar/TarUpdate.cpp
@@ -0,0 +1,156 @@
+// 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;
+ }
+ else
+ {
+ const CItemEx &existItemInfo = inputItems[updateItem.IndexInArchive];
+ item.Size = existItemInfo.Size;
+ }
+ if (updateItem.NewData || updateItem.NewProperties)
+ {
+ RINOK(outArchive.WriteHeader(item));
+ }
+
+ if (updateItem.NewData)
+ {
+ CMyComPtr<IInStream> fileInStream;
+ RINOK(updateCallback->GetStream(updateItem.IndexInClient, &fileInStream));
+ 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(inStream->Seek(existItemInfo.GetDataPosition(),
+ STREAM_SEEK_SET, NULL));
+ streamSpec->Init(inStream, existItemInfo.Size);
+ }
+ else
+ {
+ RINOK(inStream->Seek(existItemInfo.HeaderPosition,
+ STREAM_SEEK_SET, NULL));
+ streamSpec->Init(inStream, existItemInfo.GetFullSize());
+ }
+ RINOK(CopyBlock(inStreamLimited, outStream, compressProgress));
+ RINOK(outArchive.FillDataResidual(existItemInfo.Size));
+ complexity += existItemInfo.GetFullSize();
+ }
+ complexity += kOneItemComplexity;
+ }
+ return outArchive.WriteFinishHeader();
+}
+
+}}
+
diff --git a/7zip/Archive/Tar/TarUpdate.h b/7zip/Archive/Tar/TarUpdate.h
new file mode 100755
index 00000000..cd84dae4
--- /dev/null
+++ b/7zip/Archive/Tar/TarUpdate.h
@@ -0,0 +1,38 @@
+// Tar/Update.h
+
+#pragma once
+
+#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;
+
+ time_t 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/7zip/Archive/Tar/resource.h b/7zip/Archive/Tar/resource.h
new file mode 100755
index 00000000..7b0dd8ff
--- /dev/null
+++ b/7zip/Archive/Tar/resource.h
@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDI_ICON1 101
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Archive/Tar/resource.rc b/7zip/Archive/Tar/resource.rc
new file mode 100755
index 00000000..8fb4e242
--- /dev/null
+++ b/7zip/Archive/Tar/resource.rc
@@ -0,0 +1,130 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1 ICON DISCARDABLE "Tar.ico"
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,9,2,0
+ PRODUCTVERSION 3,9,2,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "Tar Plugin for 7-Zip\0"
+ VALUE "FileVersion", "3, 9, 2, 0\0"
+ VALUE "InternalName", "tar\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "tar.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 9, 2, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Archive/Tar/tar.ico b/7zip/Archive/Tar/tar.ico
new file mode 100755
index 00000000..6835885b
--- /dev/null
+++ b/7zip/Archive/Tar/tar.ico
Binary files differ
diff --git a/7zip/Archive/Zip/DllExports.cpp b/7zip/Archive/Zip/DllExports.cpp
new file mode 100755
index 00000000..935f43f7
--- /dev/null
+++ b/7zip/Archive/Zip/DllExports.cpp
@@ -0,0 +1,122 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include <initguid.h>
+
+#include "Common/ComTry.h"
+#include "ZipHandler.h"
+#include "Windows/PropVariant.h"
+#include "../../ICoder.h"
+#include "../../IPassword.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;
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ g_hInstance = hInstance;
+ 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;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
diff --git a/7zip/Archive/Zip/StdAfx.cpp b/7zip/Archive/Zip/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Archive/Zip/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Archive/Zip/StdAfx.h b/7zip/Archive/Zip/StdAfx.h
new file mode 100755
index 00000000..8cd49d6c
--- /dev/null
+++ b/7zip/Archive/Zip/StdAfx.h
@@ -0,0 +1,31 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+#include <time.h>
+#include <limits.h>
+
+#include <memory>
+
+/*
+#define _ATL_APARTMENT_THREADED
+// #define _ATL_FREE_THREADED
+
+
+#define _ATL_NO_UUIDOF
+
+#include <atlbase.h>
+
+extern CComModule _Module;
+
+#include <atlcom.h>
+#include <shlobj.h>
+#include <shlguid.h>
+
+#include <new.h>
+
+*/
+
+#endif
diff --git a/7zip/Archive/Zip/Zip.def b/7zip/Archive/Zip/Zip.def
new file mode 100755
index 00000000..b0639b70
--- /dev/null
+++ b/7zip/Archive/Zip/Zip.def
@@ -0,0 +1,7 @@
+; Zip.def
+
+LIBRARY Zip.dll
+
+EXPORTS
+ CreateObject PRIVATE
+ GetHandlerProperty PRIVATE
diff --git a/7zip/Archive/Zip/Zip.dsp b/7zip/Archive/Zip/Zip.dsp
new file mode 100755
index 00000000..0d3efa5d
--- /dev/null
+++ b/7zip/Archive/Zip/Zip.dsp
@@ -0,0 +1,441 @@
+# 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 "CRYPTO_ZIP" /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 "CRYPTO_ZIP" /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=.\DllExports.cpp
+# 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
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Zip.def
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# 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\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
+# 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\CoderMixer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\CoderMixer.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\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
+# 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\OffsetStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OffsetStream.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
+# 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 "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 "Format Common"
+
+# PROP Default_Filter ""
+# End Group
+# Begin Group "Crypto"
+
+# PROP Default_Filter ""
+# 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\7zMethods.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\7z\7zMethods.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=".\7-zip.ico"
+# End Source File
+# Begin Source File
+
+SOURCE=.\zip.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\zip1.ico
+# End Source File
+# End Target
+# End Project
diff --git a/7zip/Archive/Zip/Zip.dsw b/7zip/Archive/Zip/Zip.dsw
new file mode 100755
index 00000000..0a355329
--- /dev/null
+++ b/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/7zip/Archive/Zip/ZipAddCommon.cpp b/7zip/Archive/Zip/ZipAddCommon.cpp
new file mode 100755
index 00000000..edbf7672
--- /dev/null
+++ b/7zip/Archive/Zip/ZipAddCommon.cpp
@@ -0,0 +1,270 @@
+// AddCommon.cpp
+
+#include "StdAfx.h"
+
+#include "Common/CRC.h"
+#include "Windows/PropVariant.h"
+#include "Windows/Defs.h"
+#include "../../ICoder.h"
+#include "../../IPassword.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 {
+
+static const BYTE kMethodIDForEmptyStream = NFileHeader::NCompressionMethod::kStored;
+static const BYTE kExtractVersionForEmptyStream = NFileHeader::NCompressionMethod::kStoreExtractVersion;
+
+CAddCommon::CAddCommon(const CCompressionMethodMode &options):
+ _options(options),
+ _copyCoderSpec(NULL),
+ _mixerCoderSpec(0)
+ {}
+
+static HRESULT GetStreamCRC(IInStream *inStream, UINT32 &resultCRC)
+{
+ CCRC crc;
+ crc.Init();
+ const UINT32 kBufferSize = (1 << 14);
+ BYTE buffer[kBufferSize];
+ while(true)
+ {
+ UINT32 realProcessedSize;
+ RINOK(inStream->Read(buffer, kBufferSize, &realProcessedSize));
+ if(realProcessedSize == 0)
+ {
+ resultCRC = crc.GetDigest();
+ return S_OK;
+ }
+ crc.Update(buffer, realProcessedSize);
+ }
+}
+
+HRESULT CAddCommon::Compress(IInStream *inStream, IOutStream *outStream,
+ UINT64 inSize, ICompressProgressInfo *progress, CCompressingResult &operationResult)
+{
+ /*
+ if(inSize == 0)
+ {
+ operationResult.PackSize = 0;
+ operationResult.Method = kMethodIDForEmptyStream;
+ operationResult.ExtractVersion = kExtractVersionForEmptyStream;
+ return S_OK;
+ }
+ */
+ int numTestMethods = _options.MethodSequence.Size();
+ BYTE method;
+ UINT64 resultSize = 0;
+ for(int i = 0; i < numTestMethods; i++)
+ {
+ if (_options.PasswordIsDefined)
+ {
+ if (!_cryptoEncoder)
+ {
+ #ifdef CRYPTO_ZIP
+ _cryptoEncoder = new NCrypto::NZip::CEncoder;
+ #else
+ // change it;
+ /*
+ RINOK(_cryptoLib.LoadAndCreateCoder(
+ GetBaseFolderPrefix() + TEXT("\\Crypto\\Zip.dll"),
+ CLSID_CCryptoZipEncoder, &_cryptoEncoder));
+ */
+ #endif
+ }
+ CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
+ RINOK(_cryptoEncoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword));
+ RINOK(cryptoSetPassword->CryptoSetPassword(
+ (const BYTE *)(const char *)_options.Password, _options.Password.Length()));
+ UINT32 crc;
+ RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
+ RINOK(GetStreamCRC(inStream, crc));
+ CMyComPtr<ICryptoSetCRC> cryptoSetCRC;
+ RINOK(_cryptoEncoder.QueryInterface(IID_ICryptoSetCRC, &cryptoSetCRC));
+ RINOK(cryptoSetCRC->CryptoSetCRC(crc));
+ }
+
+ RINOK(outStream->Seek(0, STREAM_SEEK_SET, NULL));
+ RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
+
+ method = _options.MethodSequence[i];
+ switch(method)
+ {
+ case NFileHeader::NCompressionMethod::kStored:
+ {
+ if(_copyCoderSpec == NULL)
+ {
+ _copyCoderSpec = new NCompress::CCopyCoder;
+ _copyCoder = _copyCoderSpec;
+ }
+ if (_options.PasswordIsDefined)
+ {
+ if (!_mixerCoder || _mixerCoderMethod != method)
+ {
+ _mixerCoder.Release();
+ _mixerCoderSpec = new CCoderMixer;
+ _mixerCoder = _mixerCoderSpec;
+ _mixerCoderSpec->AddCoder(_copyCoder);
+ _mixerCoderSpec->AddCoder(_cryptoEncoder);
+ _mixerCoderSpec->FinishAddingCoders();
+ _mixerCoderMethod = method;
+ }
+ _mixerCoderSpec->ReInit();
+ _mixerCoderSpec->SetCoderInfo(0, NULL, NULL);
+ _mixerCoderSpec->SetCoderInfo(1, NULL, NULL);
+ _mixerCoderSpec->SetProgressCoderIndex(0);
+ RINOK(_mixerCoder->Code(inStream, outStream,
+ NULL, NULL, progress));
+ }
+ else
+ {
+ RINOK(_copyCoder->Code(inStream, outStream,
+ 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[2] =
+ {
+ _options.NumPasses, _options.NumFastBytes
+ };
+ PROPID propIDs[2] =
+ {
+ NCoderPropID::kNumPasses,
+ NCoderPropID::kNumFastBytes
+ };
+ CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
+ RINOK(_compressEncoder.QueryInterface(
+ IID_ICompressSetCoderProperties, &setCoderProperties));
+ setCoderProperties->SetCoderProperties(propIDs, properties, 2);
+ }
+ }
+ if (_options.PasswordIsDefined)
+ {
+ if (!_mixerCoder || _mixerCoderMethod != method)
+ {
+ _mixerCoder.Release();
+ _mixerCoderSpec = new CCoderMixer;
+ _mixerCoder = _mixerCoderSpec;
+ _mixerCoderSpec->AddCoder(_compressEncoder);
+ _mixerCoderSpec->AddCoder(_cryptoEncoder);
+ _mixerCoderSpec->FinishAddingCoders();
+ _mixerCoderMethod = method;
+ }
+ _mixerCoderSpec->ReInit();
+ _mixerCoderSpec->SetCoderInfo(0, NULL, NULL);
+ _mixerCoderSpec->SetCoderInfo(1, NULL, NULL);
+ _mixerCoderSpec->SetProgressCoderIndex(0);
+ RINOK(_mixerCoder->Code(inStream, outStream,
+ NULL, NULL, progress));
+ }
+ else
+ {
+ RINOK(_compressEncoder->Code(inStream, outStream, NULL, NULL, progress));
+ }
+ operationResult.ExtractVersion = NFileHeader::NCompressionMethod::kDeflateExtractVersion;
+ break;
+ }
+ }
+ outStream->Seek(0, STREAM_SEEK_CUR, &resultSize);
+ if (_options.PasswordIsDefined)
+ {
+ if(resultSize < inSize + 12)
+ break;
+ }
+ else if(resultSize < inSize)
+ break;
+ }
+ outStream->SetSize(resultSize);
+ operationResult.PackSize = resultSize;
+ operationResult.Method = method;
+ return S_OK;
+}
+
+}}
diff --git a/7zip/Archive/Zip/ZipAddCommon.h b/7zip/Archive/Zip/ZipAddCommon.h
new file mode 100755
index 00000000..16de76b4
--- /dev/null
+++ b/7zip/Archive/Zip/ZipAddCommon.h
@@ -0,0 +1,56 @@
+// Zip/AddCommon.h
+
+#pragma once
+
+#ifndef __ZIP_ADDCOMMON_H
+#define __ZIP_ADDCOMMON_H
+
+#include "../../ICoder.h"
+#include "../../IProgress.h"
+#include "../../Compress/Copy/CopyCoder.h"
+#include "../Common/CoderMixer.h"
+#ifndef COMPRESS_DEFLATE
+#include "../Common/CoderLoader.h"
+#endif
+#include "ZipCompressionMode.h"
+
+namespace NArchive {
+namespace NZip {
+
+struct CCompressingResult
+{
+ BYTE Method;
+ UINT64 PackSize;
+ BYTE ExtractVersion;
+};
+
+class CAddCommon
+{
+ CCompressionMethodMode _options;
+ NCompress::CCopyCoder *_copyCoderSpec;
+ CMyComPtr<ICompressCoder> _copyCoder;
+
+ #ifndef COMPRESS_DEFLATE
+ CCoderLibrary _compressLib;
+ #endif
+ CMyComPtr<ICompressCoder> _compressEncoder;
+
+ #ifndef CRYPTO_ZIP
+ CCoderLibrary _cryptoLib;
+ #endif
+ CMyComPtr<ICompressCoder> _cryptoEncoder;
+ CCoderMixer *_mixerCoderSpec;
+ CMyComPtr<ICompressCoder> _mixerCoder;
+ BYTE _mixerCoderMethod;
+ // CMyComPtr<ICryptoGetTextPassword> getTextPassword;
+
+
+public:
+ CAddCommon(const CCompressionMethodMode &options);
+ HRESULT Compress(IInStream *inStream, IOutStream *outStream,
+ UINT64 inSize, ICompressProgressInfo *progress, CCompressingResult &operationResult);
+};
+
+}}
+
+#endif
diff --git a/7zip/Archive/Zip/ZipCompressionMode.h b/7zip/Archive/Zip/ZipCompressionMode.h
new file mode 100755
index 00000000..f153c179
--- /dev/null
+++ b/7zip/Archive/Zip/ZipCompressionMode.h
@@ -0,0 +1,26 @@
+// CompressionMode.h
+
+#pragma once
+
+#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 PasswordIsDefined;
+ AString Password;
+};
+
+}}
+
+#endif
diff --git a/7zip/Archive/Zip/ZipHandler.cpp b/7zip/Archive/Zip/ZipHandler.cpp
new file mode 100755
index 00000000..54c31d0a
--- /dev/null
+++ b/7zip/Archive/Zip/ZipHandler.cpp
@@ -0,0 +1,612 @@
+// Zip/Handler.cpp
+
+#include "StdAfx.h"
+
+#include "ZipHandler.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 "../../IPassword.h"
+// #include "../../../Compress/Interface/CompressInterface.h"
+
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/StreamObjects.h"
+// #include "Interface/EnumStatProp.h"
+#include "../../Common/StreamObjects.h"
+
+#include "../../Compress/Copy/CopyCoder.h"
+
+
+#include "../Common/ItemNameUtils.h"
+#include "../Common/OutStreamWithCRC.h"
+#include "../Common/CoderMixer.h"
+#include "../7z/7zMethods.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
+#include "../../Compress/Implode/ImplodeDecoder.h"
+#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
+
+#ifdef CRYPTO_ZIP
+#include "../../Crypto/Zip/ZipCipher.h"
+#else
+// {23170F69-40C1-278B-06F1-0101000000000}
+DEFINE_GUID(CLSID_CCryptoZipDecoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00);
+#endif
+
+#ifndef EXCLUDE_COM
+#include "../Common/CoderLoader.h"
+#endif
+
+// using namespace std;
+
+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, kpidCommented, VT_BOOL},
+
+ { 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"Shrunk",
+ 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";
+
+CHandler::CHandler():
+ m_ArchiveIsOpen(false)
+{
+ InitMethodProperties();
+ m_Method.MethodSequence.Add(NFileHeader::NCompressionMethod::kDeflated);
+ m_Method.MethodSequence.Add(NFileHeader::NCompressionMethod::kStored);
+}
+
+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;
+}
+
+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 kpidCommented:
+ propVariant = item.IsCommented();
+ break;
+ case kpidCRC:
+ propVariant = item.FileCRC;
+ break;
+ case kpidMethod:
+ {
+ UString method;
+ if (item.CompressionMethod < kNumMethods)
+ method = kMethods[item.CompressionMethod];
+ else
+ method = kUnknownMethod;
+ propVariant = method;
+ // propVariant = item.CompressionMethod;
+ 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_Archive.Close();
+ m_ArchiveIsOpen = false;
+ return S_OK;
+}
+
+//////////////////////////////////////
+// CHandler::DecompressItems
+
+struct CMethodItem
+{
+ BYTE ZipMethod;
+ 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 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;
+
+
+ #ifndef EXCLUDE_COM
+ N7z::LoadMethodMap();
+ CCoderLibraries libraries;
+ #endif
+ CObjectVector<CMethodItem> methodItems;
+ /*
+ CCoderLibraries _libraries;
+ #ifndef COMPRESS_IMPLODE
+ CCoderLibrary implodeLib;
+ #endif
+
+
+ CMyComPtr<ICompressCoder> implodeDecoder;
+ CMyComPtr<ICompressCoder> deflateDecoder;
+ CMyComPtr<ICompressCoder> deflate64Decoder;
+ CMyComPtr<ICompressCoder> bzip2Decoder;
+
+ #ifndef CRYPTO_ZIP
+ CCoderLibrary cryptoLib;
+ #endif
+ */
+
+ CMyComPtr<ICompressCoder> cryptoDecoder;
+ CCoderMixer *mixerCoderSpec;
+ CMyComPtr<ICompressCoder> mixerCoder;
+
+ UINT16 mixerCoderMethod;
+
+ 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 &item = m_Items[index];
+ RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
+
+ if(item.IsDirectory() || item.IgnoreItem())
+ {
+ // if (!testMode)
+ {
+ RINOK(extractCallback->PrepareOperation(askMode));
+ RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
+ }
+ continue;
+ }
+
+ if (!testMode && (!realOutStream))
+ continue;
+
+ RINOK(extractCallback->PrepareOperation(askMode));
+ currentItemUnPacked = item.UnPackSize;
+ currentItemPacked = item.PackSize;
+
+ {
+ COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
+ CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
+ outStreamSpec->Init(realOutStream);
+ realOutStream.Release();
+
+ CMyComPtr<ISequentialInStream> inStream;
+ inStream.Attach(m_Archive.CreateLimitedStream(item.GetDataPosition(),
+ item.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 (item.IsEncrypted())
+ {
+ if (!cryptoDecoder)
+ {
+ #ifdef CRYPTO_ZIP
+ cryptoDecoder = new NCrypto::NZip::CDecoder;
+ #else
+ RINOK(cryptoLib.LoadAndCreateCoder(
+ GetBaseFolderPrefix() + TEXT("\\Crypto\\Zip.dll"),
+ CLSID_CCryptoZipDecoder, &cryptoDecoder));
+ #endif
+ }
+ CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
+ RINOK(cryptoDecoder.QueryInterface(
+ IID_ICryptoSetPassword, &cryptoSetPassword));
+
+ if (!getTextPassword)
+ extractCallback.QueryInterface(
+ IID_ICryptoGetTextPassword, &getTextPassword);
+
+ if (getTextPassword)
+ {
+ CMyComBSTR password;
+ RINOK(getTextPassword->CryptoGetTextPassword(&password));
+ AString anOemPassword = UnicodeStringToMultiByte(
+ (const wchar_t *)password, CP_OEMCP);
+ RINOK(cryptoSetPassword->CryptoSetPassword(
+ (const BYTE *)(const char *)anOemPassword, anOemPassword.Length()));
+ }
+ else
+ {
+ RINOK(cryptoSetPassword->CryptoSetPassword(0, 0));
+ }
+ }
+
+ int m;
+ for (m = 0; m < methodItems.Size(); m++)
+ if (methodItems[m].ZipMethod == item.CompressionMethod)
+ break;
+ if (m == methodItems.Size())
+ {
+ CMethodItem mi;
+ mi.ZipMethod = item.CompressionMethod;
+ #ifdef EXCLUDE_COM
+ switch(item.CompressionMethod)
+ {
+ case NFileHeader::NCompressionMethod::kStored:
+ mi.Coder = new NCompress::CCopyCoder;
+ break;
+ case NFileHeader::NCompressionMethod::kImploded:
+ mi.Coder = new NCompress::NImplode::NDecoder::CCoder;
+ break;
+ 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:
+ RINOK(extractCallback->SetOperationResult(
+ NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+ continue;
+ }
+ #else
+ N7z::CMethodID methodID = { { 0x04, 0x01 } , 3 };
+ methodID.ID[2] = item.CompressionMethod;
+ if (item.CompressionMethod == NFileHeader::NCompressionMethod::kStored)
+ {
+ methodID.ID[0] = 0;
+ methodID.IDSize = 1;
+ }
+ else if (item.CompressionMethod == NFileHeader::NCompressionMethod::kBZip2)
+ {
+ methodID.ID[1] = 0x02;
+ methodID.ID[2] = 0x02;
+ }
+
+ 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));
+ #endif
+ m = methodItems.Add(mi);
+ }
+ ICompressCoder *coder = methodItems[m].Coder;
+
+ CMyComPtr<ICompressSetDecoderProperties> compressSetDecoderProperties;
+ if (coder->QueryInterface(IID_ICompressSetDecoderProperties, (void **)&compressSetDecoderProperties) == S_OK)
+ {
+ // BYTE properties = (item.Flags & 6);
+ BYTE properties = item.Flags;
+ CSequentialInStreamImp *inStreamSpec = new CSequentialInStreamImp;
+ CMyComPtr<ISequentialInStream> inStreamProperties(inStreamSpec);
+ inStreamSpec->Init(&properties, 1);
+ RINOK(compressSetDecoderProperties->SetDecoderProperties(inStreamProperties));
+ }
+
+ // case NFileHeader::NCompressionMethod::kImploded:
+ // switch(item.CompressionMethod)
+ try
+ {
+ HRESULT result;
+ if (item.IsEncrypted())
+ {
+ if (!mixerCoder || mixerCoderMethod != item.CompressionMethod)
+ {
+ mixerCoder.Release();
+ mixerCoderSpec = new CCoderMixer;
+ mixerCoder = mixerCoderSpec;
+ mixerCoderSpec->AddCoder(cryptoDecoder);
+ mixerCoderSpec->AddCoder(coder);
+ mixerCoderSpec->FinishAddingCoders();
+ mixerCoderMethod = item.CompressionMethod;
+ }
+ mixerCoderSpec->ReInit();
+
+ switch(item.CompressionMethod)
+ {
+ case NFileHeader::NCompressionMethod::kStored:
+ mixerCoderSpec->SetCoderInfo(0, &currentItemPacked,
+ &currentItemUnPacked);
+ mixerCoderSpec->SetCoderInfo(1, NULL, NULL);
+ break;
+ default:
+ mixerCoderSpec->SetCoderInfo(0, &currentItemPacked, NULL);
+ mixerCoderSpec->SetCoderInfo(1, NULL, &currentItemUnPacked);
+ break;
+ }
+
+ mixerCoderSpec->SetProgressCoderIndex(1);
+ result = mixerCoder->Code(inStream, outStream,
+ NULL, NULL, compressProgress);
+ }
+ else
+ {
+ result = coder->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;
+ }
+ bool crcOK = outStreamSpec->GetCRC() == item.FileCRC;
+ outStream.Release();
+ RINOK(extractCallback->SetOperationResult(crcOK ? NArchive::NExtract::NOperationResult::kOK :
+ NArchive::NExtract::NOperationResult::kCRCError))
+ }
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+}}
diff --git a/7zip/Archive/Zip/ZipHandler.h b/7zip/Archive/Zip/ZipHandler.h
new file mode 100755
index 00000000..93467715
--- /dev/null
+++ b/7zip/Archive/Zip/ZipHandler.h
@@ -0,0 +1,73 @@
+// Zip/Handler.h
+
+#pragma once
+
+#ifndef __ZIP_HANDLER_H
+#define __ZIP_HANDLER_H
+
+#include "Common/DynamicBuffer.h"
+#include "../../ICoder.h"
+#include "../IArchive.h"
+
+#include "ZipIn.h"
+#include "ZipCompressionMode.h"
+
+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)(IOutStream *outStream, UINT32 numItems,
+ IArchiveUpdateCallback *updateCallback);
+ STDMETHOD(GetFileTimeType)(UINT32 *timeType);
+
+ // ISetProperties
+ STDMETHOD(SetProperties)(const BSTR *names, const PROPVARIANT *values, INT32 numProperties);
+
+ CHandler();
+private:
+ CObjectVector<CItemEx> m_Items;
+ CInArchive m_Archive;
+ bool m_ArchiveIsOpen;
+ CCompressionMethodMode m_Method;
+ void InitMethodProperties()
+ {
+ m_Method.NumPasses = 1;
+ m_Method.NumFastBytes = 32;
+ }
+};
+
+}}
+
+#endif
diff --git a/7zip/Archive/Zip/ZipHandlerOut.cpp b/7zip/Archive/Zip/ZipHandlerOut.cpp
new file mode 100755
index 00000000..6bfd5f70
--- /dev/null
+++ b/7zip/Archive/Zip/ZipHandlerOut.cpp
@@ -0,0 +1,284 @@
+// 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"
+
+using namespace NWindows;
+using namespace NCOM;
+using namespace NTime;
+
+namespace NArchive {
+namespace NZip {
+
+STDMETHODIMP CHandler::GetFileTimeType(UINT32 *timeType)
+{
+ *timeType = NFileTimeType::kDOS;
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems,
+ IArchiveUpdateCallback *updateCallback)
+{
+ COM_TRY_BEGIN
+ CObjectVector<CUpdateItem> updateItems;
+ for(int 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;
+ updateItem.Name = UnicodeStringToMultiByte(
+ NItemName::MakeLegalName(name), CP_OEMCP);
+ if (!isDirectoryStatusDefined)
+ updateItem.IsDirectory = ((updateItem.Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
+ if (updateItem.IsDirectory)
+ updateItem.Name += '/';
+ 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 = *(UINT64 *)(&propVariant.uhVal);
+ }
+ if(size > 0xFFFFFFFF)
+ return E_NOTIMPL;
+ updateItem.Size = size;
+ }
+ updateItems.Add(updateItem);
+ }
+
+ 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));
+ if (m_Method.PasswordIsDefined = IntToBool(passwordIsDefined))
+ m_Method.Password = UnicodeStringToMultiByte(
+ (const wchar_t *)password, CP_OEMCP);
+ }
+ else
+ m_Method.PasswordIsDefined = false;
+
+ return Update(m_Items, updateItems, outStream,
+ m_ArchiveIsOpen ? &m_Archive : NULL, &m_Method, updateCallback);
+ COM_TRY_END
+}
+
+static const UINT32 kNumPassesNormal = 1;
+static const UINT32 kNumPassesMX = 3;
+
+static const UINT32 kMatchFastLenNormal = 32;
+static const UINT32 kMatchFastLenMX = 64;
+
+STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *values, INT32 numProperties)
+{
+ InitMethodProperties();
+ BYTE mainMethod = NFileHeader::NCompressionMethod::kDeflated;
+ for (int i = 0; i < numProperties; i++)
+ {
+ UString name = UString(names[i]);
+ name.MakeUpper();
+ const PROPVARIANT &value = values[i];
+
+ if (name[0] == 'X')
+ {
+ name.Delete(0);
+ UINT32 level = 9;
+ if (value.vt == VT_UI4)
+ {
+ if (!name.IsEmpty())
+ return E_INVALIDARG;
+ level = value.ulVal;
+ }
+ else if (value.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;
+ level = (UINT32)v;
+ }
+ }
+ else
+ return E_INVALIDARG;
+ if (level == 0)
+ {
+ mainMethod = NFileHeader::NCompressionMethod::kStored;
+ }
+ else if (level < 7)
+ {
+ InitMethodProperties();
+ if (mainMethod == NFileHeader::NCompressionMethod::kStored)
+ mainMethod = NFileHeader::NCompressionMethod::kDeflated;
+ }
+ else
+ {
+ m_Method.NumPasses = kNumPassesMX;
+ m_Method.NumFastBytes = kMatchFastLenMX;
+ if (mainMethod == NFileHeader::NCompressionMethod::kStored)
+ mainMethod = NFileHeader::NCompressionMethod::kDeflated;
+ }
+ continue;
+ }
+ else if (name == L"M")
+ {
+ if (value.vt == VT_BSTR)
+ {
+ UString valueString = value.bstrVal;
+ valueString.MakeUpper();
+ if (valueString == L"COPY")
+ mainMethod = NFileHeader::NCompressionMethod::kStored;
+ else if (valueString == L"DEFLATE")
+ mainMethod = NFileHeader::NCompressionMethod::kDeflated;
+ else if (valueString == L"DEFLATE64")
+ mainMethod = NFileHeader::NCompressionMethod::kDeflated64;
+ else if (valueString == L"BZIP2")
+ mainMethod = NFileHeader::NCompressionMethod::kBZip2;
+ else
+ return E_INVALIDARG;
+ }
+ else if (value.vt == VT_UI4)
+ {
+ switch(value.ulVal)
+ {
+ case NFileHeader::NCompressionMethod::kStored:
+ case NFileHeader::NCompressionMethod::kDeflated:
+ case NFileHeader::NCompressionMethod::kDeflated64:
+ case NFileHeader::NCompressionMethod::kBZip2:
+ mainMethod = value.ulVal;
+ break;
+ default:
+ return E_INVALIDARG;
+ }
+ }
+ else
+ return E_INVALIDARG;
+ }
+ else if (name == L"PASS")
+ {
+ if (value.vt != VT_UI4)
+ return E_INVALIDARG;
+ m_Method.NumPasses = value.ulVal;
+ if (m_Method.NumPasses < 1 || m_Method.NumPasses > 4)
+ return E_INVALIDARG;
+ }
+ else if (name == L"FB")
+ {
+ if (value.vt != VT_UI4)
+ return E_INVALIDARG;
+ m_Method.NumFastBytes = value.ulVal;
+ if (m_Method.NumFastBytes < 3 || m_Method.NumFastBytes > 255)
+ return E_INVALIDARG;
+ }
+ else
+ return E_INVALIDARG;
+ }
+ m_Method.MethodSequence.Clear();
+ if (mainMethod != NFileHeader::NCompressionMethod::kStored)
+ m_Method.MethodSequence.Add(mainMethod);
+ m_Method.MethodSequence.Add(NFileHeader::NCompressionMethod::kStored);
+ return S_OK;
+}
+
+}}
diff --git a/7zip/Archive/Zip/ZipHeader.cpp b/7zip/Archive/Zip/ZipHeader.cpp
new file mode 100755
index 00000000..fe32d4fd
--- /dev/null
+++ b/7zip/Archive/Zip/ZipHeader.cpp
@@ -0,0 +1,32 @@
+// 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;
+
+ class CMarkersInitializer
+ {
+ public:
+ CMarkersInitializer()
+ {
+ kLocalFileHeader--;
+ kDataDescriptor--;
+ kCentralFileHeader--;
+ kEndOfCentralDir--;
+ }
+ };
+ static CMarkersInitializer g_MarkerInitializer;
+}
+
+}}
+
diff --git a/7zip/Archive/Zip/ZipHeader.h b/7zip/Archive/Zip/ZipHeader.h
new file mode 100755
index 00000000..cc8e4ed7
--- /dev/null
+++ b/7zip/Archive/Zip/ZipHeader.h
@@ -0,0 +1,227 @@
+// Archive/Zip/Header.h
+
+#pragma once
+
+#ifndef __ARCHIVE_ZIP_HEADER_H
+#define __ARCHIVE_ZIP_HEADER_H
+
+#include "Common/Types.h"
+
+namespace NArchive {
+namespace NZip {
+
+#pragma pack( push, PragmaZipHeaders)
+#pragma pack( push, 1)
+
+namespace NSignature
+{
+ extern UINT32 kLocalFileHeader;
+ extern UINT32 kDataDescriptor;
+ extern UINT32 kCentralFileHeader;
+ extern UINT32 kEndOfCentralDir;
+
+ static const UINT32 kMarkerSize = 4;
+}
+
+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
+ };
+ const int kNumCompressionMethods = 11;
+ const BYTE kMadeByProgramVersion = 20;
+
+ const BYTE kDeflateExtractVersion = 20;
+ const BYTE kStoreExtractVersion = 10;
+
+ const BYTE kSupportedVersion = 20;
+ }
+
+ struct CLocalBlock
+ {
+ CVersion ExtractVersion;
+
+ UINT16 Flags;
+ UINT16 CompressionMethod;
+ UINT32 Time;
+ UINT32 FileCRC;
+ UINT32 PackSize;
+ UINT32 UnPackSize;
+ UINT16 NameSize;
+ UINT16 ExtraSize;
+ };
+
+ struct CDataDescriptor
+ {
+ UINT32 Signature;
+ UINT32 FileCRC;
+ UINT32 PackSize;
+ UINT32 UnPackSize;
+ };
+
+ struct CLocalBlockFull
+ {
+ UINT32 Signature;
+ CLocalBlock Header;
+ };
+
+ 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 */
+ }
+}
+
+#pragma pack(pop)
+#pragma pack(pop, PragmaZipHeaders)
+
+}}
+
+#endif
diff --git a/7zip/Archive/Zip/ZipIn.cpp b/7zip/Archive/Zip/ZipIn.cpp
new file mode 100755
index 00000000..6b23702b
--- /dev/null
+++ b/7zip/Archive/Zip/ZipIn.cpp
@@ -0,0 +1,376 @@
+// 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"
+
+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();
+}
+
+//////////////////////////////////////
+// Markers
+
+inline bool TestMarkerCandidate(const void *testBytes, UINT32 &value)
+{
+ value = *((const UINT32 *)(testBytes));
+ return (value == NSignature::kLocalFileHeader) ||
+ (value == NSignature::kEndOfCentralDir);
+}
+
+bool CInArchive::FindAndReadMarker(const UINT64 *searchHeaderSizeLimit)
+{
+ m_ArchiveInfo.StartPosition = 0;
+ m_Position = m_StreamStartPosition;
+ if(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL) != 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;
+ while(true)
+ {
+ if (searchHeaderSizeLimit != NULL)
+ if (curTestPos - m_StreamStartPosition > *searchHeaderSizeLimit)
+ return false;
+ UINT32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev;
+ ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize);
+ UINT32 numBytesInBuffer = numBytesPrev + processedSize;
+ if (numBytesInBuffer < NSignature::kMarkerSize)
+ return false;
+ 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_Position = curTestPos + NSignature::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);
+ }
+}
+
+//////////////////////////////////////
+// Read Operations
+
+HRESULT CInArchive::ReadBytes(void *data, UINT32 size, UINT32 *processedSize)
+{
+ UINT32 realProcessedSize;
+ HRESULT result = m_Stream->Read(data, size, &realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ IncreasePositionValue(realProcessedSize);
+ return result;
+}
+
+void CInArchive::IncreasePositionValue(UINT64 addValue)
+{
+ m_Position += addValue;
+}
+
+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);
+}
+
+
+//////////////////////////////////
+// Read headers
+
+bool CInArchive::ReadSignature(UINT32 &signature)
+{
+ return ReadBytesAndTestSize(&signature, sizeof(signature));
+}
+
+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);
+}
+
+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));
+ }
+ // FSeek -= sizeof(UINT32); // atention it's not real position
+
+ while(m_Signature == NSignature::kLocalFileHeader)
+ {
+ // FSeek points to next byte after signature
+ NFileHeader::CLocalBlock localHeader;
+ CItemEx itemInfo;
+ itemInfo.LocalHeaderPosition =
+ UINT32(m_Position - m_StreamStartPosition - sizeof(UINT32)); // points to signature;
+ SafeReadBytes(&localHeader, sizeof(localHeader));
+ UINT32 fileNameSize = localHeader.NameSize;
+ itemInfo.Name = ReadFileName(fileNameSize);
+ /*
+ if (!NItemName::IsNameLegal(itemInfo.Name))
+ ThrowIncorrectArchiveException();
+ */
+ itemInfo.ExtractVersion.Version = localHeader.ExtractVersion.Version;
+ itemInfo.ExtractVersion.HostOS = localHeader.ExtractVersion.HostOS;
+ itemInfo.Flags = localHeader.Flags & NFileHeader::NFlags::kUsedBitsMask;
+ itemInfo.CompressionMethod = localHeader.CompressionMethod;
+ itemInfo.Time = localHeader.Time;
+ itemInfo.FileCRC = localHeader.FileCRC;
+ itemInfo.PackSize = localHeader.PackSize;
+ itemInfo.UnPackSize = localHeader.UnPackSize;
+
+ itemInfo.LocalExtraSize = localHeader.ExtraSize;
+ itemInfo.FileHeaderWithNameSize = sizeof(UINT32) + sizeof(localHeader) + fileNameSize;
+
+ IncreaseRealPosition(localHeader.ExtraSize);
+
+ if (itemInfo.HasDescriptor())
+ {
+ const int kBufferSize = (1 << 12);
+ BYTE buffer[kBufferSize];
+ UINT32 numBytesInBuffer = 0;
+ UINT32 packedSize = 0;
+
+ bool descriptorWasFound = false;
+ while (true)
+ {
+ UINT32 processedSize;
+ RINOK(ReadBytes(buffer + numBytesInBuffer,
+ kBufferSize - numBytesInBuffer, &processedSize));
+ numBytesInBuffer += processedSize;
+ if (numBytesInBuffer < sizeof(NFileHeader::CDataDescriptor))
+ ThrowIncorrectArchiveException();
+ int i;
+ for (i = 0; i <= numBytesInBuffer -
+ sizeof(NFileHeader::CDataDescriptor); i++)
+ {
+ const NFileHeader::CDataDescriptor &descriptor =
+ *(NFileHeader::CDataDescriptor *)(buffer + i);
+ if (descriptor.Signature == NSignature::kDataDescriptor &&
+ descriptor.PackSize == packedSize + i)
+ {
+ descriptorWasFound = true;
+ itemInfo.FileCRC = descriptor.FileCRC;
+ itemInfo.PackSize = descriptor.PackSize;
+ itemInfo.UnPackSize = descriptor.UnPackSize;
+ IncreaseRealPosition(INT64(INT32(0 - (numBytesInBuffer - i -
+ sizeof(NFileHeader::CDataDescriptor)))));
+ break;
+ };
+ }
+ if (descriptorWasFound)
+ break;
+ packedSize += i;
+ int j;
+ for (j = 0; i < numBytesInBuffer; i++, j++)
+ buffer[j] = buffer[i];
+ numBytesInBuffer = j;
+ }
+ }
+ else
+ IncreaseRealPosition(localHeader.PackSize);
+
+ items.Add(itemInfo);
+ if (progress != 0)
+ {
+ UINT64 numItems = items.Size();
+ RINOK(progress->SetCompleted(&numItems));
+ }
+ if (!ReadSignature(m_Signature))
+ break;
+ }
+ UINT32 centralDirectorySize = 0;
+ UINT64 centralDirectoryStartOffset = m_Position - sizeof(UINT32);
+ for(int i = 0; i < items.Size(); i++)
+ {
+ if (progress != 0)
+ {
+ UINT64 numItems = items.Size();
+ RINOK(progress->SetCompleted(&numItems));
+ }
+ // if(m_Signature == NSignature::kEndOfCentralDir)
+ // break;
+ if(m_Signature != NSignature::kCentralFileHeader)
+ ThrowIncorrectArchiveException();
+
+ NFileHeader::CBlock header;
+ SafeReadBytes(&header, sizeof(header));
+ UINT32 localHeaderOffset = header.LocalHeaderOffset;
+ header.Flags &= NFileHeader::NFlags::kUsedBitsMask;
+
+ int index;
+ int left = 0, right = items.Size();
+ while(true)
+ {
+ if (left >= right)
+ ThrowIncorrectArchiveException();
+ index = (left + right) / 2;
+ UINT32 position = items[index].LocalHeaderPosition;
+ if (localHeaderOffset == position)
+ break;
+ if (localHeaderOffset < position)
+ right = index;
+ else
+ left = index + 1;
+ }
+ CItemEx &itemInfo = items[index];
+ itemInfo.MadeByVersion.Version = header.MadeByVersion.Version;
+ itemInfo.MadeByVersion.HostOS = header.MadeByVersion.HostOS;
+
+ CVersion centalHeaderExtractVersion;
+ centalHeaderExtractVersion.Version = header.ExtractVersion.Version;
+ centalHeaderExtractVersion.HostOS = header.ExtractVersion.HostOS;
+
+ if (
+ // itemInfo.ExtractVersion != centalHeaderExtractVersion ||
+ itemInfo.Flags != header.Flags ||
+ itemInfo.CompressionMethod != header.CompressionMethod ||
+ // itemInfo.Time != header.Time ||
+ itemInfo.FileCRC != header.FileCRC ||
+ itemInfo.PackSize != header.PackSize ||
+ itemInfo.UnPackSize != header.UnPackSize)
+ ThrowIncorrectArchiveException();
+
+ AString centralName = ReadFileName(header.NameSize);
+ if (itemInfo.Name.Length() != centralName.Length())
+ ThrowIncorrectArchiveException(); // test it maybe better compare names
+ itemInfo.Name = centralName;
+
+ itemInfo.CentralExtraPosition = m_Position;
+ itemInfo.CentralExtraSize = header.ExtraSize;
+ itemInfo.CommentSize = header.CommentSize;
+ if (header.DiskNumberStart != 0)
+ throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported);
+ itemInfo.InternalAttributes = header.InternalAttributes;
+ itemInfo.ExternalAttributes = header.ExternalAttributes;
+
+ // May be these strings must be deleted
+ if (itemInfo.IsDirectory())
+ {
+ // if (itemInfo.PackSize != 0 /* || itemInfo.UnPackSize != 0 */)
+ // ThrowIncorrectArchiveException();
+ itemInfo.UnPackSize = 0;
+ }
+
+ UINT32 currentRecordSize = sizeof(UINT32) + sizeof(header) +
+ header.NameSize + header.ExtraSize + header.CommentSize;
+
+ centralDirectorySize += currentRecordSize;
+ IncreaseRealPosition(header.ExtraSize + header.CommentSize);
+ if (!ReadSignature(m_Signature))
+ break;
+ }
+ if(m_Signature != NSignature::kEndOfCentralDir)
+ ThrowIncorrectArchiveException();
+ CEndOfCentralDirectoryRecord endOfCentralDirHeader;
+ SafeReadBytes(&endOfCentralDirHeader, sizeof(endOfCentralDirHeader));
+ if (endOfCentralDirHeader.ThisDiskNumber != 0 ||
+ endOfCentralDirHeader.StartCentralDirectoryDiskNumber != 0)
+ throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported);
+ if (endOfCentralDirHeader.NumEntriesInCentaralDirectoryOnThisDisk != ((UINT16)items.Size()) ||
+ endOfCentralDirHeader.NumEntriesInCentaralDirectory != ((UINT16)items.Size()) ||
+ endOfCentralDirHeader.CentralDirectorySize != centralDirectorySize ||
+ (endOfCentralDirHeader.CentralDirectoryStartOffset != centralDirectoryStartOffset &&
+ (!items.IsEmpty())))
+ ThrowIncorrectArchiveException();
+
+ m_ArchiveInfo.CommentPosition = m_Position;
+ m_ArchiveInfo.CommentSize = endOfCentralDirHeader.CommentSize;
+ return S_OK;
+}
+
+ISequentialInStream* CInArchive::CreateLimitedStream(UINT64 position, UINT64 size)
+{
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+ CMyComPtr<ISequentialInStream> inStream(streamSpec);
+ SeekInArchive(position);
+ streamSpec->Init(m_Stream, 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/7zip/Archive/Zip/ZipIn.h b/7zip/Archive/Zip/ZipIn.h
new file mode 100755
index 00000000..606653dd
--- /dev/null
+++ b/7zip/Archive/Zip/ZipIn.h
@@ -0,0 +1,84 @@
+// Archive/ZipIn.h
+
+#pragma once
+
+#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 CCauseType
+ {
+ kUnexpectedEndOfArchive = 0,
+ kArchiceHeaderCRCError,
+ kFileHeaderCRCError,
+ kIncorrectArchive,
+ kDataDescroptorsAreNotSupported,
+ kMultiVolumeArchiveAreNotSupported,
+ kReadStreamError,
+ kSeekStreamError
+ }
+ Cause;
+ CInArchiveException(CCauseType cause): Cause(cause) {}
+};
+
+class CInArchiveInfo
+{
+public:
+ UINT64 StartPosition;
+ UINT64 CommentPosition;
+ UINT16 CommentSize;
+ bool IsCommented() const { return (CommentSize != 0); };
+};
+
+class CProgressVirt
+{
+public:
+ STDMETHOD(SetCompleted)(const UINT64 *numFiles) PURE;
+};
+
+class CInArchive
+{
+ CMyComPtr<IInStream> m_Stream;
+ UINT32 m_Signature;
+ UINT64 m_StreamStartPosition;
+ UINT64 m_Position;
+ CInArchiveInfo m_ArchiveInfo;
+ AString m_NameBuffer;
+
+ bool FindAndReadMarker(const UINT64 *searchHeaderSizeLimit);
+ bool ReadSignature(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 IncreasePositionValue(UINT64 addValue);
+ void IncreaseRealPosition(UINT64 addValue);
+ void ThrowIncorrectArchiveException();
+
+public:
+ HRESULT ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *progress);
+ bool Open(IInStream *inStream, const UINT64 *searchHeaderSizeLimit);
+ void Close();
+ void GetArchiveInfo(CInArchiveInfo &archiveInfo) const;
+ void DirectGetBytes(void *data, UINT32 num);
+ bool SeekInArchive(UINT64 position);
+ ISequentialInStream *CreateLimitedStream(UINT64 position, UINT64 size);
+ IInStream* CreateStream();
+};
+
+}}
+
+#endif
diff --git a/7zip/Archive/Zip/ZipItem.cpp b/7zip/Archive/Zip/ZipItem.cpp
new file mode 100755
index 00000000..bb52624c
--- /dev/null
+++ b/7zip/Archive/Zip/ZipItem.cpp
@@ -0,0 +1,132 @@
+// Archive/ZipItem.cpp
+
+#include "StdAfx.h"
+
+#include "ZipHeader.h"
+#include "ZipItem.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 CItem::IsEncrypted() const
+{ return (Flags & NFileHeader::NFlags::kEncryptedMask) != 0; }
+bool CItem::HasDescriptor() const
+ { return (Flags & NFileHeader::NFlags::kDescriptorUsedMask) != 0; }
+
+bool CItem::IsImplodeBigDictionary() const
+{
+if (CompressionMethod != NFileHeader::NCompressionMethod::kImploded)
+ throw 12312212;
+ return (Flags & NFileHeader::NFlags::kImplodeDictionarySizeMask) != 0;
+}
+
+bool CItem::IsImplodeLiteralsOn() const
+{
+if (CompressionMethod != NFileHeader::NCompressionMethod::kImploded)
+ throw 12312213;
+ return (Flags & NFileHeader::NFlags::kImplodeLiteralsOnMask) != 0;
+}
+
+static const char *kUnknownAttributes = "Unknown file attributes";
+
+bool CItem::IsDirectory() const
+{
+ if (!Name.IsEmpty())
+ {
+ #ifdef WIN32
+ LPCSTR prev = CharPrevExA(GetCodePage(), Name, &Name[Name.Length()], 0);
+ if (*prev == '/')
+ return true;
+ #else
+ if (Name[Name.Length() - 1) == '/')
+ return true;
+ #endif
+ }
+ 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 CItem::GetWinAttributes() const
+{
+ DWORD winAttributes;
+ switch(MadeByVersion.HostOS)
+ {
+ case NFileHeader::NHostOS::kFAT:
+ case NFileHeader::NHostOS::kNTFS:
+ winAttributes = ExternalAttributes;
+ break;
+ default:
+ winAttributes = 0; // must be converted from unix value;;
+ }
+ if (IsDirectory()) // test it;
+ winAttributes |= FILE_ATTRIBUTE_DIRECTORY;
+ return winAttributes;
+}
+
+void CItem::ClearFlags()
+ { Flags = 0; }
+
+void CItem::SetFlagBits(int startBitNumber, int numBits, int value)
+{
+ WORD mask = ((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::SetEncrypted(bool encrypted)
+ { SetBitMask(NFileHeader::NFlags::kEncryptedMask, encrypted); }
+
+}}
diff --git a/7zip/Archive/Zip/ZipItem.h b/7zip/Archive/Zip/ZipItem.h
new file mode 100755
index 00000000..d1b21fb2
--- /dev/null
+++ b/7zip/Archive/Zip/ZipItem.h
@@ -0,0 +1,72 @@
+// Archive/ZipItem.h
+
+#pragma once
+
+#ifndef __ARCHIVE_ZIP_ITEM_H
+#define __ARCHIVE_ZIP_ITEM_H
+
+#include "Common/Types.h"
+#include "Common/String.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);
+
+class CItem
+{
+public:
+ CVersion MadeByVersion;
+ CVersion ExtractVersion;
+ UINT16 Flags;
+ UINT16 CompressionMethod;
+ UINT32 Time;
+ UINT32 FileCRC;
+ UINT32 PackSize;
+ UINT32 UnPackSize;
+ UINT16 InternalAttributes;
+ UINT32 ExternalAttributes;
+
+ AString Name;
+
+ UINT32 LocalHeaderPosition;
+ UINT16 LocalExtraSize;
+ UINT16 CentralExtraSize;
+ UINT16 CommentSize;
+
+ bool IsEncrypted() const;
+
+ bool IsImplodeBigDictionary() const;
+ bool IsImplodeLiteralsOn() const;
+
+ bool IsDirectory() const;
+ bool IgnoreItem() const { return false; }
+ UINT32 GetWinAttributes() const;
+
+ bool HasDescriptor() const;
+
+ #ifdef WIN32
+ WORD GetCodePage() const
+ { return (MadeByVersion.HostOS == NFileHeader::NHostOS::kFAT) ? CP_OEMCP : CP_ACP; }
+ #endif
+
+private:
+ void SetFlagBits(int startBitNumber, int numBits, int value);
+ void SetBitMask(int bitMask, bool enable);
+public:
+ void ClearFlags();
+ void SetEncrypted(bool encrypted);
+};
+
+}}
+
+#endif
+
+
diff --git a/7zip/Archive/Zip/ZipItemEx.h b/7zip/Archive/Zip/ZipItemEx.h
new file mode 100755
index 00000000..6d8e3ce1
--- /dev/null
+++ b/7zip/Archive/Zip/ZipItemEx.h
@@ -0,0 +1,47 @@
+// Archive/ZipItemEx.h
+
+#pragma once
+
+#ifndef __ARCHIVE_ZIP_ITEMEX_H
+#define __ARCHIVE_ZIP_ITEMEX_H
+
+#include "Common/Vector.h"
+
+#include "ZipHeader.h"
+#include "ZipItem.h"
+
+namespace NArchive {
+namespace NZip {
+
+class CItemEx: public CItem
+{
+public:
+ UINT16 FileHeaderWithNameSize;
+ UINT64 CentralExtraPosition;
+
+ UINT32 GetLocalFullSize() const
+ { return FileHeaderWithNameSize + LocalExtraSize + PackSize +
+ (HasDescriptor() ? sizeof(NFileHeader::CDataDescriptor) : 0); };
+
+ UINT32 GetCentralExtraPlusCommentSize() const
+ { return CentralExtraSize + CommentSize; };
+
+ UINT64 GetCommentPosition() const
+ { return CentralExtraPosition + CentralExtraSize; };
+
+ bool IsCommented() const
+ { return CommentSize != 0; };
+
+ UINT64 GetLocalExtraPosition() const
+ { return LocalHeaderPosition + FileHeaderWithNameSize; };
+
+ UINT64 GetDataPosition() const
+ { return GetLocalExtraPosition() + LocalExtraSize; };
+};
+
+}}
+
+#endif
+
+
+
diff --git a/7zip/Archive/Zip/ZipOut.cpp b/7zip/Archive/Zip/ZipOut.cpp
new file mode 100755
index 00000000..58da75d4
--- /dev/null
+++ b/7zip/Archive/Zip/ZipOut.cpp
@@ -0,0 +1,134 @@
+// ZipOut.cpp
+
+#include "StdAfx.h"
+
+#include "ZipOut.h"
+#include "Common/StringConvert.h"
+#include "Common/CRC.h"
+#include "../../Common/OffsetStream.h"
+
+namespace NArchive {
+namespace NZip {
+
+void COutArchive::Create(IOutStream *outStream)
+{
+ m_Stream = outStream;
+ m_BasePosition = 0;
+}
+
+void COutArchive::MoveBasePosition(UINT32 distanceToMove)
+{
+ m_BasePosition += distanceToMove; // test overflow
+}
+
+void COutArchive::PrepareWriteCompressedData(UINT16 fileNameLength)
+{
+ m_LocalFileHeaderSize = sizeof(NFileHeader::CLocalBlockFull) + fileNameLength;
+}
+
+void COutArchive::WriteBytes(const void *buffer, UINT32 size)
+{
+ UINT32 processedSize;
+ if(m_Stream->Write(buffer, size, &processedSize) != S_OK)
+ throw 0;
+ if(processedSize != size)
+ throw 0;
+ m_BasePosition += size;
+}
+
+void COutArchive::WriteLocalHeader(const CItem &item)
+{
+ NFileHeader::CLocalBlockFull fileHeader;
+ fileHeader.Signature = NSignature::kLocalFileHeader;
+ NFileHeader::CLocalBlock &header = fileHeader.Header;
+
+ header.ExtractVersion.HostOS = item.ExtractVersion.HostOS;
+ header.ExtractVersion.Version = item.ExtractVersion.Version;
+ header.Flags = item.Flags;
+ header.CompressionMethod = item.CompressionMethod;
+ header.Time = item.Time;
+ header.FileCRC = item.FileCRC;
+ header.PackSize = item.PackSize;
+ header.UnPackSize = item.UnPackSize;
+
+ header.NameSize = item.Name.Length();
+ header.ExtraSize = item.LocalExtraSize; // test it;
+
+ m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL);
+ WriteBytes(&fileHeader, sizeof(fileHeader));
+ WriteBytes((const char *)item.Name, header.NameSize);
+ MoveBasePosition(header.ExtraSize + header.PackSize);
+ m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL);
+}
+
+void COutArchive::WriteCentralHeader(const CItem &item)
+{
+ NFileHeader::CBlockFull fileHeader;
+ fileHeader.Signature = NSignature::kCentralFileHeader;
+ NFileHeader::CBlock &header = fileHeader.Header;
+
+ header.MadeByVersion.HostOS = item.MadeByVersion.HostOS;
+ header.MadeByVersion.Version = item.MadeByVersion.Version;
+ header.ExtractVersion.HostOS = item.ExtractVersion.HostOS;
+ header.ExtractVersion.Version = item.ExtractVersion.Version;
+ header.Flags = item.Flags;
+ header.CompressionMethod = item.CompressionMethod;
+ header.Time = item.Time;
+ header.FileCRC = item.FileCRC;
+ header.PackSize = item.PackSize;
+ header.UnPackSize = item.UnPackSize;
+
+ header.NameSize = item.Name.Length();
+
+ header.ExtraSize = item.CentralExtraSize; // test it;
+ header.CommentSize = item.CommentSize;
+ header.DiskNumberStart = 0;
+ header.InternalAttributes = item.InternalAttributes;
+ header.ExternalAttributes = item.ExternalAttributes;
+ header.LocalHeaderOffset = item.LocalHeaderPosition;
+
+ m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL);
+ WriteBytes(&fileHeader, sizeof(fileHeader));
+ WriteBytes((const char *)item.Name, header.NameSize);
+}
+
+void COutArchive::WriteEndOfCentralDir(const COutArchiveInfo &archiveInfo)
+{
+ CEndOfCentralDirectoryRecordFull fileHeader;
+ fileHeader.Signature = NSignature::kEndOfCentralDir;
+ CEndOfCentralDirectoryRecord &header = fileHeader.Header;
+
+ header.ThisDiskNumber = 0;
+ header.StartCentralDirectoryDiskNumber = 0;
+
+ header.NumEntriesInCentaralDirectoryOnThisDisk = archiveInfo.NumEntriesInCentaralDirectory;
+ header.NumEntriesInCentaralDirectory = archiveInfo.NumEntriesInCentaralDirectory;
+
+ header.CentralDirectorySize = archiveInfo.CentralDirectorySize;
+ header.CentralDirectoryStartOffset = archiveInfo.CentralDirectoryStartOffset;
+ header.CommentSize = archiveInfo.CommentSize;
+
+ m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL);
+ WriteBytes(&fileHeader, sizeof(fileHeader));
+}
+
+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/7zip/Archive/Zip/ZipOut.h b/7zip/Archive/Zip/ZipOut.h
new file mode 100755
index 00000000..8f9d98e5
--- /dev/null
+++ b/7zip/Archive/Zip/ZipOut.h
@@ -0,0 +1,53 @@
+// ZipOut.h
+
+#pragma once
+
+#ifndef __ZIP_OUT_H
+#define __ZIP_OUT_H
+
+#include "Common/MyCom.h"
+
+#include "../../IStream.h"
+
+#include "ZipHeader.h"
+#include "ZipItem.h"
+
+namespace NArchive {
+namespace NZip {
+
+class COutArchiveInfo
+{
+public:
+ UINT16 NumEntriesInCentaralDirectory;
+ UINT32 CentralDirectorySize;
+ UINT32 CentralDirectoryStartOffset;
+ UINT16 CommentSize;
+};
+
+class COutArchive
+{
+ CMyComPtr<IOutStream> m_Stream;
+
+ UINT32 m_BasePosition;
+ UINT32 m_LocalFileHeaderSize;
+
+ void WriteBytes(const void *buffer, UINT32 size);
+
+public:
+ void Create(IOutStream *outStream);
+ void MoveBasePosition(UINT32 distanceToMove);
+ UINT32 GetCurrentPosition() const { return m_BasePosition; };
+ void PrepareWriteCompressedData(UINT16 fileNameLength);
+ void WriteLocalHeader(const CItem &item);
+
+ void WriteCentralHeader(const CItem &item);
+ void WriteEndOfCentralDir(const COutArchiveInfo &archiveInfo);
+
+ void CreateStreamForCompressing(IOutStream **outStream);
+ void CreateStreamForCopying(ISequentialOutStream **outStream);
+ void SeekToPackedDataPosition();
+};
+
+}}
+
+#endif
diff --git a/7zip/Archive/Zip/ZipUpdate.cpp b/7zip/Archive/Zip/ZipUpdate.cpp
new file mode 100755
index 00000000..b9a5637b
--- /dev/null
+++ b/7zip/Archive/Zip/ZipUpdate.cpp
@@ -0,0 +1,357 @@
+// ZipUpdate.cpp
+
+#include "StdAfx.h"
+
+#include "ZipUpdate.h"
+#include "ZipAddCommon.h"
+#include "ZipOut.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 "../Common/InStreamWithCRC.h"
+
+using namespace std;
+
+namespace NArchive {
+namespace NZip {
+
+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 CopyBlock(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, ICompressProgressInfo *progress)
+{
+ CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
+ return copyCoder->Code(inStream, outStream, NULL, NULL, progress);
+}
+
+HRESULT CopyBlockToArchive(ISequentialInStream *inStream,
+ COutArchive &outArchive, ICompressProgressInfo *progress)
+{
+ CMyComPtr<ISequentialOutStream> outStream;
+ outArchive.CreateStreamForCopying(&outStream);
+ return CopyBlock(inStream, outStream, progress);
+}
+
+static HRESULT WriteRange(IInStream *inStream,
+ COutArchive &outArchive,
+ const CUpdateRange &range,
+ IProgress *progress,
+ UINT64 &currentComplexity)
+{
+ UINT64 position;
+ inStream->Seek(range.Position, STREAM_SEEK_SET, &position);
+
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+ CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);
+ streamSpec->Init(inStream, range.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 = CopyBlockToArchive(inStreamLimited, outArchive, compressProgress);
+ currentComplexity += range.Size;
+ return result;
+}
+
+
+static HRESULT UpdateOneFile(IInStream *inStream,
+ COutArchive &archive,
+ const CCompressionMethodMode &options,
+ CAddCommon &compressor,
+ const CUpdateItem &updateItem,
+ UINT64 &currentComplexity,
+ IArchiveUpdateCallback *updateCallback,
+ CItemEx &fileHeader)
+{
+ CMyComPtr<IInStream> fileInStream;
+ RINOK(updateCallback->GetStream(updateItem.IndexInClient, &fileInStream));
+
+ bool isDirectory;
+ UINT32 fileSize = updateItem.Size;
+ fileHeader.UnPackSize = fileSize;
+
+ if (updateItem.NewProperties)
+ {
+ isDirectory = updateItem.IsDirectory;
+ fileHeader.Name = updateItem.Name;
+ fileHeader.ExternalAttributes = updateItem.Attributes;
+ fileHeader.Time = updateItem.Time;
+ }
+ else
+ isDirectory = fileHeader.IsDirectory();
+
+ archive.PrepareWriteCompressedData(fileHeader.Name.Length());
+
+ fileHeader.LocalHeaderPosition = archive.GetCurrentPosition();
+ fileHeader.MadeByVersion.HostOS = kMadeByHostOS;
+ fileHeader.MadeByVersion.Version = NFileHeader::NCompressionMethod::kMadeByProgramVersion;
+
+ fileHeader.ExtractVersion.HostOS = kExtractHostOS;
+
+ fileHeader.InternalAttributes = 0; // test it
+ fileHeader.ClearFlags();
+ if(isDirectory)
+ {
+ fileHeader.ExtractVersion.Version = kExtractVersionForDirectory;
+ fileHeader.CompressionMethod = kMethodForDirectory;
+
+ fileHeader.PackSize = 0;
+ fileHeader.FileCRC = 0; // test it
+ }
+ else
+ {
+ {
+ CInStreamWithCRC *inStreamSpec = new CInStreamWithCRC;
+ CMyComPtr<IInStream> inStream(inStreamSpec);
+ inStreamSpec->Init(fileInStream);
+ CCompressingResult compressingResult;
+ CMyComPtr<IOutStream> outStream;
+ archive.CreateStreamForCompressing(&outStream);
+
+ CLocalProgress *localProgressSpec = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
+ localProgressSpec->Init(updateCallback, true);
+
+ CLocalCompressProgressInfo *localCompressProgressSpec =
+ new CLocalCompressProgressInfo;
+ CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
+
+ localCompressProgressSpec->Init(localProgress, &currentComplexity, NULL);
+
+ RINOK(compressor.Compress(inStream, outStream,
+ fileSize, compressProgress, compressingResult));
+
+ fileHeader.PackSize = (UINT32)compressingResult.PackSize;
+ fileHeader.CompressionMethod = compressingResult.Method;
+ fileHeader.ExtractVersion.Version = compressingResult.ExtractVersion;
+ fileHeader.FileCRC = inStreamSpec->GetCRC();
+ fileHeader.UnPackSize = (UINT32)inStreamSpec->GetSize();
+ }
+ }
+ fileHeader.SetEncrypted(options.PasswordIsDefined);
+ fileHeader.CommentSize = (updateItem.Commented) ?
+ WORD(updateItem.CommentRange.Size) : 0;
+
+ fileHeader.LocalExtraSize = 0;
+ fileHeader.CentralExtraSize = 0;
+
+ archive.WriteLocalHeader(fileHeader);
+ currentComplexity += fileSize;
+ return updateCallback->SetOperationResult(
+ NArchive::NUpdate::NOperationResult::kOK);
+}
+
+static HRESULT Update2(COutArchive &archive,
+ IInStream *inStream,
+ const CObjectVector<CItemEx> &inputItems,
+ const CObjectVector<CUpdateItem> &updateItems,
+ const CCompressionMethodMode *options,
+ bool commentRangeAssigned,
+ const CUpdateRange &commentRange,
+ IArchiveUpdateCallback *updateCallback)
+{
+ UINT64 complexity = 0;
+ UINT64 estimatedArchiveSize = (1<<20); // sfx part
+
+ int i;
+ for(i = 0; i < updateItems.Size(); i++)
+ {
+ const CUpdateItem &updateItem = updateItems[i];
+ if (updateItem.NewData)
+ {
+ complexity += updateItem.Size;
+ if (updateItem.Commented)
+ complexity += updateItem.CommentRange.Size;
+ estimatedArchiveSize += updateItem.Name.Length() * 2 + 100;
+ }
+ else
+ {
+ const CItemEx &inputItem = inputItems[updateItem.IndexInArchive];
+ complexity += inputItem.GetLocalFullSize();
+ complexity += inputItem.GetCentralExtraPlusCommentSize();
+ }
+ }
+
+ complexity += updateItems.Size();
+ complexity += updateItems.Size();
+
+ estimatedArchiveSize += complexity;
+ if (estimatedArchiveSize > 0xFFFFFFFF)
+ return E_NOTIMPL;
+
+ if (commentRangeAssigned)
+ complexity += commentRange.Size;
+
+ complexity++; // end of central
+
+ updateCallback->SetTotal(complexity);
+ auto_ptr<CAddCommon> compressor;
+
+ complexity = 0;
+
+ CObjectVector<CItemEx> items;
+
+ for(i = 0; i < updateItems.Size(); i++)
+ {
+ const CUpdateItem &updateItem = updateItems[i];
+ RINOK(updateCallback->SetCompleted(&complexity));
+
+ CItemEx item;
+ if (!updateItem.NewProperties || !updateItem.NewData)
+ item = inputItems[updateItem.IndexInArchive];
+
+ if (updateItem.NewData)
+ {
+ if(compressor.get() == NULL)
+ {
+ compressor = auto_ptr<CAddCommon>(new CAddCommon(*options));
+ }
+ RINOK(UpdateOneFile(inStream, archive, *options,
+ *compressor, updateItem, complexity, updateCallback, item));
+ }
+ else
+ {
+ // item = inputItems[copyIndices[copyIndexIndex++]];
+ 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.CentralExtraSize = 0;
+ item.LocalExtraSize = 0;
+
+ archive.PrepareWriteCompressedData(item.Name.Length());
+ item.LocalHeaderPosition = archive.GetCurrentPosition();
+ archive.SeekToPackedDataPosition();
+ RINOK(WriteRange(inStream, archive, range,
+ updateCallback, complexity));
+ archive.WriteLocalHeader(item);
+ }
+ else
+ {
+ CUpdateRange range(item.LocalHeaderPosition, item.GetLocalFullSize());
+
+ // set new header position
+ item.LocalHeaderPosition = archive.GetCurrentPosition();
+
+ RINOK(WriteRange(inStream, archive, range,
+ updateCallback, complexity));
+ archive.MoveBasePosition(range.Size);
+ }
+ }
+ items.Add(item);
+ complexity++;
+ }
+ DWORD centralDirStartPosition = archive.GetCurrentPosition();
+ for(i = 0; i < items.Size(); i++)
+ {
+ archive.WriteCentralHeader(items[i]);
+ const CUpdateItem &updateItem = updateItems[i];
+ if (updateItem.NewProperties)
+ {
+ if (updateItem.Commented)
+ {
+ const CUpdateRange range = updateItem.CommentRange;
+ RINOK(WriteRange(inStream, archive, range,
+ updateCallback, complexity));
+ archive.MoveBasePosition(range.Size);
+ }
+ }
+ else
+ {
+ const CItemEx item = items[i];
+ CUpdateRange range(item.CentralExtraPosition,
+ item.GetCentralExtraPlusCommentSize());
+ RINOK(WriteRange(inStream, archive, range,
+ updateCallback, complexity));
+ archive.MoveBasePosition(range.Size);
+ }
+ complexity++;
+ }
+ COutArchiveInfo archiveInfo;
+ archiveInfo.NumEntriesInCentaralDirectory = items.Size();
+ archiveInfo.CentralDirectorySize = archive.GetCurrentPosition() -
+ centralDirStartPosition;
+ archiveInfo.CentralDirectoryStartOffset = centralDirStartPosition;
+ archiveInfo.CommentSize = commentRangeAssigned ? WORD(commentRange.Size) : 0;
+ archive.WriteEndOfCentralDir(archiveInfo);
+ if (commentRangeAssigned)
+ RINOK(WriteRange(inStream, archive, commentRange,
+ updateCallback, complexity));
+ complexity++; // end of central
+ return S_OK;
+}
+
+HRESULT Update(
+ const CObjectVector<CItemEx> &inputItems,
+ const CObjectVector<CUpdateItem> &updateItems,
+ IOutStream *outStream,
+ CInArchive *inArchive,
+ CCompressionMethodMode *compressionMethodMode,
+ IArchiveUpdateCallback *updateCallback)
+{
+ DWORD startBlockSize;
+ bool commentRangeAssigned;
+ CUpdateRange commentRange;
+ if(inArchive != 0)
+ {
+ CInArchiveInfo archiveInfo;
+ inArchive->GetArchiveInfo(archiveInfo);
+ startBlockSize = archiveInfo.StartPosition;
+ commentRangeAssigned = archiveInfo.IsCommented();
+ if (commentRangeAssigned)
+ {
+ commentRange.Position = archiveInfo.CommentPosition;
+ commentRange.Size = archiveInfo.CommentSize;
+ }
+ }
+ else
+ {
+ startBlockSize = 0;
+ commentRangeAssigned = false;
+ }
+
+ COutArchive outArchive;
+ outArchive.Create(outStream);
+ if (startBlockSize > 0)
+ {
+ CMyComPtr<ISequentialInStream> inStream;
+ inStream.Attach(inArchive->CreateLimitedStream(0, startBlockSize));
+ RINOK(CopyBlockToArchive(inStream, outArchive, NULL));
+ outArchive.MoveBasePosition(startBlockSize);
+ }
+ CMyComPtr<IInStream> inStream;
+ if(inArchive != 0)
+ inStream.Attach(inArchive->CreateStream());
+
+ return Update2(outArchive, inStream,
+ inputItems, updateItems,
+ compressionMethodMode,
+ commentRangeAssigned, commentRange, updateCallback);
+}
+
+}}
diff --git a/7zip/Archive/Zip/ZipUpdate.h b/7zip/Archive/Zip/ZipUpdate.h
new file mode 100755
index 00000000..87a4e31e
--- /dev/null
+++ b/7zip/Archive/Zip/ZipUpdate.h
@@ -0,0 +1,59 @@
+// Zip/Update.h
+
+#pragma once
+
+#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
+{
+ UINT32 Position;
+ UINT32 Size;
+ CUpdateRange() {};
+ CUpdateRange(UINT32 position, UINT32 size):
+ Position(position), Size(size) {};
+};
+
+struct CUpdateItem
+{
+ bool NewData;
+ bool NewProperties;
+ bool IsDirectory;
+ int IndexInArchive;
+ int IndexInClient;
+ UINT32 Attributes;
+ UINT32 Time;
+ UINT32 Size;
+ AString Name;
+ // bool ExistInArchive;
+ bool Commented;
+ CUpdateRange CommentRange;
+ /*
+ bool IsDirectory() const
+ { return ((Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); };
+ */
+};
+
+HRESULT Update(
+ const CObjectVector<CItemEx> &inputItems,
+ const CObjectVector<CUpdateItem> &updateItems,
+ IOutStream *outStream,
+ CInArchive *inArchive,
+ CCompressionMethodMode *compressionMethodMode,
+ IArchiveUpdateCallback *updateCallback);
+
+}}
+
+#endif
diff --git a/7zip/Archive/Zip/resource.h b/7zip/Archive/Zip/resource.h
new file mode 100755
index 00000000..7b0dd8ff
--- /dev/null
+++ b/7zip/Archive/Zip/resource.h
@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDI_ICON1 101
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Archive/Zip/resource.rc b/7zip/Archive/Zip/resource.rc
new file mode 100755
index 00000000..afc35c0e
--- /dev/null
+++ b/7zip/Archive/Zip/resource.rc
@@ -0,0 +1,130 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1 ICON DISCARDABLE "zip.ico"
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,12,0,0
+ PRODUCTVERSION 3,12,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "Zip Plugin for 7-Zip\0"
+ VALUE "FileVersion", "3, 12, 0, 0\0"
+ VALUE "InternalName", "zip\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "zip.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 12, 0, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Archive/Zip/zip.ico b/7zip/Archive/Zip/zip.ico
new file mode 100755
index 00000000..2af46066
--- /dev/null
+++ b/7zip/Archive/Zip/zip.ico
Binary files differ
diff --git a/7zip/Archive/cpio/CpioHandler.cpp b/7zip/Archive/cpio/CpioHandler.cpp
new file mode 100755
index 00000000..3354e598
--- /dev/null
+++ b/7zip/Archive/cpio/CpioHandler.cpp
@@ -0,0 +1,287 @@
+// 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
+ bool mustBeClosed = true;
+ // 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));
+ }
+
+ while(true)
+ {
+ 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.OldHeader);
+ 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_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;
+ for(UINT32 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->Init(m_InStream, 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/7zip/Archive/cpio/CpioHandler.h b/7zip/Archive/cpio/CpioHandler.h
new file mode 100755
index 00000000..3e887992
--- /dev/null
+++ b/7zip/Archive/cpio/CpioHandler.h
@@ -0,0 +1,49 @@
+// Archive/cpio/Handler.h
+
+#pragma once
+
+#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 \ No newline at end of file
diff --git a/7zip/Archive/cpio/CpioHeader.cpp b/7zip/Archive/cpio/CpioHeader.cpp
new file mode 100755
index 00000000..06704db7
--- /dev/null
+++ b/7zip/Archive/cpio/CpioHeader.cpp
@@ -0,0 +1,22 @@
+// 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 *kEndName = "TRAILER!!!";
+
+ extern unsigned short kMagicForRecord2 = 0x71C7;
+ extern unsigned short kMagicForRecord2BE = 0xC771;
+ }
+
+}}}
+
diff --git a/7zip/Archive/cpio/CpioHeader.h b/7zip/Archive/cpio/CpioHeader.h
new file mode 100755
index 00000000..6943fc1d
--- /dev/null
+++ b/7zip/Archive/cpio/CpioHeader.h
@@ -0,0 +1,69 @@
+// Archive/cpio/Header.h
+
+#pragma once
+
+#ifndef __ARCHIVE_CPIO_HEADER_H
+#define __ARCHIVE_CPIO_HEADER_H
+
+#include "Common/Types.h"
+
+namespace NArchive {
+namespace NCpio {
+
+#pragma pack( push, PragmacpioHeaders)
+#pragma pack( push, 1)
+
+namespace NFileHeader
+{
+ namespace NMagic
+ {
+ extern const char *kMagic1;
+ extern const char *kMagic2;
+ extern const char *kEndName;
+ extern unsigned short kMagicForRecord2;
+ extern unsigned short kMagicForRecord2BE;
+ }
+
+ 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];
+ };
+
+ 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()
+ { return memcmp(Magic, NMagic::kMagic1, 6) == 0 ||
+ memcmp(Magic, NMagic::kMagic2, 6) == 0; };
+ };
+}
+
+#pragma pack(pop)
+#pragma pack(pop, PragmacpioHeaders)
+
+}}
+
+#endif
diff --git a/7zip/Archive/cpio/CpioIn.cpp b/7zip/Archive/cpio/CpioIn.cpp
new file mode 100755
index 00000000..a1c0cf58
--- /dev/null
+++ b/7zip/Archive/cpio/CpioIn.cpp
@@ -0,0 +1,167 @@
+// Archive/cpioIn.cpp
+
+#include "StdAfx.h"
+
+#include "CpioIn.h"
+
+#include "Windows/Defs.h"
+
+#include "CpioHeader.h"
+
+namespace NArchive {
+namespace NCpio {
+
+HRESULT CInArchive::ReadBytes(void *data, UINT32 size, UINT32 &processedSize)
+{
+ RINOK(m_Stream->Read(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 bool HexStringToNumber(const char *s, UINT32 &resultValue)
+{
+ resultValue = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ char c = s[i];
+ 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;
+}
+
+#define GetFromHex(x, y) { if (!HexStringToNumber((x), (y))) return E_FAIL; }
+
+static inline unsigned short ConvertValue(
+ unsigned short value, bool convert)
+{
+ if (!convert)
+ return value;
+ return (((unsigned short)(value & 0xFF)) << 8) | (value >> 8);
+}
+
+HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
+{
+ union
+ {
+ NFileHeader::CRecord record;
+ NFileHeader::CRecord2 record2;
+ };
+ filled = false;
+
+ UINT32 processedSize;
+ item.HeaderPosition = m_Position;
+
+ RINOK(ReadBytes(&record2, 2, processedSize));
+ if (processedSize != 2)
+ return S_FALSE;
+
+ UINT32 nameSize;
+
+ unsigned short signature = *(unsigned short *)&record;
+ bool oldBE = (signature == NFileHeader::NMagic::kMagicForRecord2BE);
+
+ if (signature == NFileHeader::NMagic::kMagicForRecord2 || oldBE)
+ {
+ RINOK(ReadBytes((BYTE *)(&record2) + 2,
+ sizeof(record2) - 2, processedSize));
+ if (processedSize != sizeof(record2) - 2)
+ return S_FALSE;
+
+ item.inode = ConvertValue(record2.c_ino, oldBE);
+ item.Mode = ConvertValue(record2.c_mode, oldBE);
+ item.UID = ConvertValue(record2.c_uid, oldBE);
+ item.GID = ConvertValue(record2.c_gid, oldBE);
+ item.Size =
+ (UINT32(ConvertValue(record2.c_filesizes[0], oldBE)) << 16)
+ + ConvertValue(record2.c_filesizes[1], oldBE);
+ item.ModificationTime =
+ (UINT32(ConvertValue(record2.c_mtimes[0], oldBE)) << 16) +
+ ConvertValue(record2.c_mtimes[1], oldBE);
+ item.NumLinks = ConvertValue(record2.c_nlink, oldBE);
+ item.DevMajor = 0;
+ item.DevMinor = ConvertValue(record2.c_dev, oldBE);
+ item.RDevMajor =0;
+ item.RDevMinor = ConvertValue(record2.c_rdev, oldBE);
+ item.ChkSum = 0;
+ nameSize = ConvertValue(record2.c_namesize, oldBE);
+ item.HeaderSize =
+ (((nameSize + sizeof(NFileHeader::CRecord2) - 1) / 2) + 1) * 2; /* 4 byte padding for ("new cpio header" + "filename") */
+ // nameSize + sizeof(NFileHeader::CRecord2);
+ nameSize = item.HeaderSize - sizeof(NFileHeader::CRecord2);
+ item.OldHeader = true;
+ }
+ else
+ {
+ RINOK(ReadBytes((BYTE *)(&record) + 2, sizeof(record) - 2, processedSize));
+ if (processedSize != sizeof(record) - 2)
+ return S_FALSE;
+
+ if (!record.CheckMagic())
+ return S_FALSE;
+
+ GetFromHex(record.inode, item.inode);
+ GetFromHex(record.Mode, item.Mode);
+ GetFromHex(record.UID, item.UID);
+ GetFromHex(record.GID, item.GID);
+ GetFromHex(record.nlink, item.NumLinks);
+ GetFromHex(record.mtime, *(UINT32 *)&item.ModificationTime);
+ GetFromHex(record.Size, item.Size);
+ GetFromHex(record.DevMajor, item.DevMajor);
+ GetFromHex(record.DevMinor, item.DevMinor);
+ GetFromHex(record.RDevMajor, item.RDevMajor);
+ GetFromHex(record.RDevMinor, item.RDevMinor);
+ GetFromHex(record.ChkSum, item.ChkSum);
+ GetFromHex(record.NameSize, nameSize)
+ item.HeaderSize =
+ (((nameSize + sizeof(NFileHeader::CRecord) - 1) / 4) + 1) * 4; /* 4 byte padding for ("new cpio header" + "filename") */
+ nameSize = item.HeaderSize - sizeof(NFileHeader::CRecord);
+ item.OldHeader = false;
+ }
+ 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 (item.Name == NFileHeader::NMagic::kEndName)
+ return S_OK;
+ filled = true;
+ return S_OK;
+}
+
+HRESULT CInArchive::Skeep(UINT64 aNumBytes)
+{
+ UINT64 aNewPostion;
+ RINOK(m_Stream->Seek(aNumBytes, STREAM_SEEK_CUR, &aNewPostion));
+ m_Position += aNumBytes;
+ if (m_Position != aNewPostion)
+ return E_FAIL;
+ return S_OK;
+}
+
+HRESULT CInArchive::SkeepDataRecords(UINT64 aDataSize, bool OldHeader)
+{
+ if (OldHeader)
+ return Skeep((aDataSize + 1) & 0xFFFFFFFFFFFFFFFE);
+ return Skeep((aDataSize + 3) & 0xFFFFFFFFFFFFFFFC);
+}
+
+}}
diff --git a/7zip/Archive/cpio/CpioIn.h b/7zip/Archive/cpio/CpioIn.h
new file mode 100755
index 00000000..8362aa9c
--- /dev/null
+++ b/7zip/Archive/cpio/CpioIn.h
@@ -0,0 +1,31 @@
+// CpioIn.h
+
+#pragma once
+
+#ifndef __ARCHIVE_CPIO_IN_H
+#define __ARCHIVE_CPIO_IN_H
+
+#include "Common/MyCom.h"
+#include "../../IStream.h"
+#include "CpioItem.h"
+
+namespace NArchive {
+namespace NCpio {
+
+class CInArchive
+{
+ CMyComPtr<IInStream> m_Stream;
+
+ UINT64 m_Position;
+
+ HRESULT ReadBytes(void *data, UINT32 size, UINT32 &aProcessedSize);
+public:
+ HRESULT Open(IInStream *inStream);
+ HRESULT GetNextItem(bool &filled, CItemEx &anItemInfo);
+ HRESULT Skeep(UINT64 aNumBytes);
+ HRESULT SkeepDataRecords(UINT64 aDataSize, bool OldHeader);
+};
+
+}}
+
+#endif
diff --git a/7zip/Archive/cpio/CpioItem.h b/7zip/Archive/cpio/CpioItem.h
new file mode 100755
index 00000000..465783c7
--- /dev/null
+++ b/7zip/Archive/cpio/CpioItem.h
@@ -0,0 +1,53 @@
+// Archive/cpio/ItemInfo.h
+
+#pragma once
+
+#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;
+ time_t ModificationTime;
+
+ // char LinkFlag;
+ // AString LinkName; ?????
+ char Magic[8];
+ UINT32 NumLinks;
+ UINT32 DevMajor;
+ UINT32 DevMinor;
+ UINT32 RDevMajor;
+ UINT32 RDevMinor;
+ UINT32 ChkSum;
+
+ bool OldHeader;
+
+ bool IsDirectory() const
+ { return (Mode & _S_IFMT) == _S_IFDIR; }
+};
+
+class CItemEx: public CItem
+{
+public:
+ UINT64 HeaderPosition;
+ UINT32 HeaderSize;
+ UINT64 GetDataPosition() const { return HeaderPosition + HeaderSize; };
+};
+
+}}
+
+#endif
diff --git a/7zip/Archive/cpio/DllExports.cpp b/7zip/Archive/cpio/DllExports.cpp
new file mode 100755
index 00000000..da6e3971
--- /dev/null
+++ b/7zip/Archive/cpio/DllExports.cpp
@@ -0,0 +1,66 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#define INITGUID
+
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+#include "CpioHandler.h"
+#include "../../ICoder.h"
+
+// {23170F69-40C1-278A-1000-000110080000}
+DEFINE_GUID(CLSID_CCpioHandler,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x08, 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/7zip/Archive/cpio/StdAfx.cpp b/7zip/Archive/cpio/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Archive/cpio/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Archive/cpio/StdAfx.h b/7zip/Archive/cpio/StdAfx.h
new file mode 100755
index 00000000..9f4df604
--- /dev/null
+++ b/7zip/Archive/cpio/StdAfx.h
@@ -0,0 +1,10 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#include <time.h>
+
+#endif
diff --git a/7zip/Archive/cpio/cpio.def b/7zip/Archive/cpio/cpio.def
new file mode 100755
index 00000000..a9522a82
--- /dev/null
+++ b/7zip/Archive/cpio/cpio.def
@@ -0,0 +1,8 @@
+; cpio.def
+
+LIBRARY cpio.dll
+
+EXPORTS
+ CreateObject PRIVATE
+ GetHandlerProperty PRIVATE
+
diff --git a/7zip/Archive/cpio/cpio.dsp b/7zip/Archive/cpio/cpio.dsp
new file mode 100755
index 00000000..da7ee1c6
--- /dev/null
+++ b/7zip/Archive/cpio/cpio.dsp
@@ -0,0 +1,241 @@
+# 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=.\cpio.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.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 "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\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
+# End Group
+# End Target
+# End Project
diff --git a/7zip/Archive/cpio/cpio.dsw b/7zip/Archive/cpio/cpio.dsw
new file mode 100755
index 00000000..b1b6d98f
--- /dev/null
+++ b/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/7zip/Archive/cpio/cpio.ico b/7zip/Archive/cpio/cpio.ico
new file mode 100755
index 00000000..9abaabc7
--- /dev/null
+++ b/7zip/Archive/cpio/cpio.ico
Binary files differ
diff --git a/7zip/Archive/cpio/resource.h b/7zip/Archive/cpio/resource.h
new file mode 100755
index 00000000..7b0dd8ff
--- /dev/null
+++ b/7zip/Archive/cpio/resource.h
@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDI_ICON1 101
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Archive/cpio/resource.rc b/7zip/Archive/cpio/resource.rc
new file mode 100755
index 00000000..1aa0520a
--- /dev/null
+++ b/7zip/Archive/cpio/resource.rc
@@ -0,0 +1,130 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1 ICON DISCARDABLE "cpio.ico"
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,9,2,0
+ PRODUCTVERSION 3,9,2,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "cpio Plugin for 7-Zip\0"
+ VALUE "FileVersion", "3, 9, 2, 0\0"
+ VALUE "InternalName", "cpio\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "cpio .dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 9, 2, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Bundles/Alone/Alone.dsp b/7zip/Bundles/Alone/Alone.dsp
new file mode 100755
index 00000000..6bd29f26
--- /dev/null
+++ b/7zip/Bundles/Alone/Alone.dsp
@@ -0,0 +1,2150 @@
+# 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 "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_MF_HC" /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" /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 /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 "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_MF_HC" /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" /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 "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_MF_HC" /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" /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 "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_MF_HC" /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" /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\Extract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\Extract.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ExtractCallback.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\OpenCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\OpenCallback.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\TempFiles.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\TempFiles.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\Update.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\Update.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\UpdateCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\UpdateCallback.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.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 "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\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\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\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\System.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\System.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Thread.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\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\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\MultiStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MultiStream.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
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Group "Branch"
+
+# PROP Default_Filter ""
+# 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 Group "Original BZip2"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\BZip2\Original\blocksort.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=..\..\Compress\BZip2\Original\bzlib.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=..\..\Compress\BZip2\Original\bzlib.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BZip2\Original\bzlib_private.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\BZip2\Original\compress.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=..\..\Compress\BZip2\Original\crctable.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=..\..\Compress\BZip2\Original\decompress.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=..\..\Compress\BZip2\Original\huffman.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=..\..\Compress\BZip2\Original\randtable.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
+# End Group
+# 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
+# Begin Source File
+
+SOURCE=..\..\Compress\BZip2\BZip2Error.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 "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
+# Begin Source File
+
+SOURCE=..\..\Compress\Huffman\HuffmanEncoder.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\Huffman\HuffmanEncoder.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 ""
+# 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
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\HashChain\HCMF.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\HashChain\HCMFMain.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
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMALen.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\LZMALen.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMALiteral.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\LZMALiteral.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
+# 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\CoderMixer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\DummyOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\DummyOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\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
+# End Group
+# End Group
+# Begin Group "UI Common"
+
+# PROP Default_Filter ""
+# 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\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\SortUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\SortUtils.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\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
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAES\MySHA256.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAES\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"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAES\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
+# End Target
+# End Project
diff --git a/7zip/Bundles/Alone/Alone.dsw b/7zip/Bundles/Alone/Alone.dsw
new file mode 100755
index 00000000..65eca43f
--- /dev/null
+++ b/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/7zip/Bundles/Alone/StdAfx.cpp b/7zip/Bundles/Alone/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Bundles/Alone/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Bundles/Alone/StdAfx.h b/7zip/Bundles/Alone/StdAfx.h
new file mode 100755
index 00000000..3bdedef1
--- /dev/null
+++ b/7zip/Bundles/Alone/StdAfx.h
@@ -0,0 +1,12 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+#include <stdio.h>
+#include <tchar.h>
+
+#include <vector>
+
+#endif
diff --git a/7zip/Bundles/Alone/afxres.h b/7zip/Bundles/Alone/afxres.h
new file mode 100755
index 00000000..c2fadd4a
--- /dev/null
+++ b/7zip/Bundles/Alone/afxres.h
@@ -0,0 +1 @@
+#include <winresrc.h>
diff --git a/7zip/Bundles/Alone/resource.h b/7zip/Bundles/Alone/resource.h
new file mode 100755
index 00000000..612062a2
--- /dev/null
+++ b/7zip/Bundles/Alone/resource.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Bundles/Alone/resource.rc b/7zip/Bundles/Alone/resource.rc
new file mode 100755
index 00000000..9fb6641a
--- /dev/null
+++ b/7zip/Bundles/Alone/resource.rc
@@ -0,0 +1,121 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,12,0,0
+ PRODUCTVERSION 3,12,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "7-Zip Standalone Console version\0"
+ VALUE "FileVersion", "3, 12, 0, 0\0"
+ VALUE "InternalName", "7za\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "7za.exe\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 12, 0, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Bundles/Format7z/Format7z.dsp b/7zip/Bundles/Format7z/Format7z.dsp
new file mode 100755
index 00000000..0ef0e8b8
--- /dev/null
+++ b/7zip/Bundles/Format7z/Format7z.dsp
@@ -0,0 +1,905 @@
+# 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_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_MF_HC" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /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 /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_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_MF_HC" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /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 /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.def
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7z.ico
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\DllExports.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\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\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\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
+# Begin Source File
+
+SOURCE=..\..\..\Windows\System.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\System.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\CrossThreadProgress.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.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
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Group "LZ"
+
+# PROP Default_Filter ""
+# Begin Group "MT"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\MT\MT.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\LZ\MT\MT.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\LZInWindow.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\LZInWindow.h
+# End Source File
+# 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\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
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMALen.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\LZMALen.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMALiteral.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\LZMALiteral.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
+# 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
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAES\MySHA256.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAES\SHA256.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\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\MultiStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MultiStream.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
+# End Group
+# End Target
+# End Project
diff --git a/7zip/Bundles/Format7z/Format7z.dsw b/7zip/Bundles/Format7z/Format7z.dsw
new file mode 100755
index 00000000..324dab1f
--- /dev/null
+++ b/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/7zip/Bundles/SFXCon/7z.ico b/7zip/Bundles/SFXCon/7z.ico
new file mode 100755
index 00000000..47ffb781
--- /dev/null
+++ b/7zip/Bundles/SFXCon/7z.ico
Binary files differ
diff --git a/7zip/Bundles/SFXCon/Main.cpp b/7zip/Bundles/SFXCon/Main.cpp
new file mode 100755
index 00000000..7ad3b0b3
--- /dev/null
+++ b/7zip/Bundles/SFXCon/Main.cpp
@@ -0,0 +1,459 @@
+// Main.cpp
+
+#include "StdAfx.h"
+
+#include <initguid.h>
+
+#include "Common/CommandLineParser.h"
+#include "Common/StdOutStream.h"
+#include "Common/Wildcard.h"
+#include "Common/StringConvert.h"
+#include "Common/MyCom.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/ZipRegistry.h"
+#include "../../UI/Common/DefaultName.h"
+
+#include "../../UI/Console/Extract.h"
+#include "../../UI/Console/ArError.h"
+#include "../../UI/Console/List.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NCommandLineParser;
+
+static const char *kCopyrightString =
+"\n7-Zip SFX 3.12 Copyright (c) 1999-2003 Igor Pavlov 2003-12-10\n";
+
+static const int kNumSwitches = 6;
+
+const wchar_t *defaultExt = L".exe";
+
+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 CSysString kExtractGroupProcessMessage = "Processing";
+static const CSysString kListingProcessMessage = "Listing";
+
+static const CSysString kDefaultWorkingDirectory = ""; // test it maybemust be "."
+
+struct CArchiveCommand
+{
+ NCommandType::EEnum CommandType;
+ // NListMode::EEnum ListMode;
+ // bool ListFullPathes;
+ NRecursedType::EEnum DefaultRecursedType() const;
+ bool IsFromExtractGroup(NExtractMode::EEnum &extractMode) const;
+};
+
+NRecursedType::EEnum CArchiveCommand::DefaultRecursedType() const
+{
+ return kCommandRecursedDefault[CommandType];
+}
+
+bool CArchiveCommand::IsFromExtractGroup(NExtractMode::EEnum &extractMode) const
+{
+ switch(CommandType)
+ {
+ case NCommandType::kTest:
+ extractMode = NExtractMode::kTest;
+ return true;
+ /*
+ case NCommandType::kExtract:
+ extractMode = NExtractMode::kExtractToOne;
+ return true;
+ */
+ case NCommandType::kFullExtract:
+ extractMode = NExtractMode::kFullPath;
+ return true;
+ default:
+ return false;
+ }
+}
+
+static NRecursedType::EEnum GetRecursedTypeFromIndex(int index)
+{
+ switch (index)
+ {
+ case NRecursedPostCharIndex::kWildCardRecursionOnly:
+ return NRecursedType::kWildCardOnlyRecursed;
+ case NRecursedPostCharIndex::kNoRecursion:
+ return NRecursedType::kNonRecursed;
+ default:
+ return NRecursedType::kRecursed;
+ }
+}
+
+void PrintHelp(void)
+{
+ g_StdOut << kHelpString;
+}
+
+static void ShowMessageAndThrowException(LPCTSTR message, NExitCode::EEnum code)
+{
+ g_StdOut << message << endl;
+ throw code;
+}
+
+static void PrintHelpAndExit() // yyy
+{
+ PrintHelp();
+ ShowMessageAndThrowException(kUserErrorMessage, NExitCode::kUserError);
+}
+
+static void PrintProcessTitle(const CSysString &processTitle, const UString &archiveName)
+{
+ g_StdOut << endl << processTitle << kProcessArchiveMessage <<
+ archiveName << endl << endl;
+}
+
+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;
+
+ switch (type)
+ {
+ case NRecursedType::kWildCardOnlyRecursed:
+ recursed = isWildCard;
+ break;
+ case NRecursedType::kRecursed:
+ recursed = true;
+ break;
+ case NRecursedType::kNonRecursed:
+ recursed = false;
+ break;
+ }
+ wildcardCensor.AddItem(name, include, recursed, isWildCard);
+ return true;
+}
+
+void AddCommandLineWildCardToCensr(NWildcard::CCensor &wildcardCensor,
+ const UString &name, bool include, NRecursedType::EEnum type)
+{
+ if (!AddNameToCensor(wildcardCensor, name, include, type))
+ ShowMessageAndThrowException(kIncorrectWildCardInCommandLine, NExitCode::kUserError);
+}
+
+static bool AreEqualNoCase(wchar_t c1, wchar_t c2)
+{
+ return ::MyCharUpper(c1) == ::MyCharUpper(c2);
+}
+
+void AddToCensorFromNonSwitchesStrings(NWildcard::CCensor &wildcardCensor,
+ const UStringVector &nonSwitchStrings, NRecursedType::EEnum type,
+ bool thereAreSwitchIncludeWildCards)
+{
+ AddCommandLineWildCardToCensr(wildcardCensor, kUniversalWildcard, true, type);
+}
+
+void AddSwitchWildCardsToCensor(NWildcard::CCensor &wildcardCensor,
+ const UStringVector &strings, bool include, NRecursedType::EEnum commonRecursedType)
+{
+ for(int i = 0; i < strings.Size(); i++)
+ {
+ const UString &string = strings[i];
+ NRecursedType::EEnum recursedType;
+ int pos = 0;
+ if (string.Length() < kSomeCludePostStringMinSize)
+ PrintHelpAndExit();
+ if (AreEqualNoCase(string[pos], kRecursedIDChar))
+ {
+ pos++;
+ int index = UString(kRecursedPostCharSet).Find(string[pos]);
+ recursedType = GetRecursedTypeFromIndex(index);
+ if (index >= 0)
+ pos++;
+ }
+ else
+ recursedType = commonRecursedType;
+ if (string.Length() < pos + kSomeCludeAfterRecursedPostStringMinSize)
+ PrintHelpAndExit();
+ UString tail = string.Mid(pos + 1);
+ if (AreEqualNoCase(string[pos], kImmediateNameID))
+ AddCommandLineWildCardToCensr(wildcardCensor,
+ tail, include, recursedType);
+ else
+ PrintHelpAndExit();
+ }
+}
+
+// ------------------------------------------------------------------
+static void ThrowPrintFileIsNotArchiveException(const CSysString &fileName)
+{
+ CSysString message;
+ message = kFileIsNotArchiveMessageBefore + fileName + kFileIsNotArchiveMessageAfter;
+ ShowMessageAndThrowException(message, NExitCode::kFileIsNotArchive);
+}
+
+void MyOpenArhive(const UString &archiveName,
+ const NFind::CFileInfoW &archiveFileInfo,
+ IInArchive **archiveHandler,
+ UString &defaultItemName)
+{
+ CArchiverInfo archiverInfo;
+ int subExtIndex;
+ HRESULT result = OpenArchive(archiveName, archiveHandler,
+ archiverInfo, subExtIndex, 0);
+ if (result == S_FALSE)
+ throw "file is not supported archive";
+ if (result != S_OK)
+ throw "error";
+ defaultItemName = GetDefaultName(archiveName,
+ archiverInfo.Extensions[subExtIndex].Extension,
+ archiverInfo.Extensions[subExtIndex].AddExtension);
+}
+
+// int Main2(int numArguments, const char *arguments[])
+int Main2()
+{
+ SetFileApisToOEM();
+
+ g_StdOut << kCopyrightString;
+
+ UStringVector commandStrings;
+ SplitCommandLine(GetCommandLineW(), commandStrings);
+
+ 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;
+
+ if (archiveName.Right(4).CompareNoCase(defaultExt) != 0)
+ archiveName += defaultExt;
+
+
+ NExtractMode::EEnum extractMode;
+ bool isExtractGroupCommand = command.IsFromExtractGroup(extractMode);
+
+ bool passwordEnabled = parser[NKey::kPassword].ThereIs;
+
+ UString password;
+ if(passwordEnabled)
+ password = parser[NKey::kPassword].PostStrings[0];
+
+ if(isExtractGroupCommand || command.CommandType == NCommandType::kList)
+ {
+ NFind::CFileInfoW archiveFileInfo;
+ if (!NFind::FindFile(archiveName, archiveFileInfo) || archiveFileInfo.IsDirectory())
+ throw "there is no such archive";
+
+ if (archiveFileInfo.IsDirectory())
+ throw "there is no such archive";
+
+ UString defaultItemName;
+ CMyComPtr<IInArchive> archiveHandler;
+ CArchiverInfo archiverInfo;
+ MyOpenArhive(archiveName, archiveFileInfo, &archiveHandler, defaultItemName);
+ if(isExtractGroupCommand)
+ {
+ PrintProcessTitle(kExtractGroupProcessMessage, archiveName);
+ UString outputDir;
+ if(parser[NKey::kOutputDir].ThereIs)
+ {
+ outputDir = parser[NKey::kOutputDir].PostStrings[0];
+ NName::NormalizeDirPathPrefix(outputDir);
+ }
+ NExtraction::NOverwriteMode::EEnum overwriteMode =
+ NExtraction::NOverwriteMode::kAskBefore;
+ CExtractOptions options(extractMode, outputDir, yesToAll,
+ passwordEnabled, password, overwriteMode);
+ options.DefaultItemName = defaultItemName;
+ options.ArchiveFileInfo = archiveFileInfo;
+ // options.ArchiveFileInfo = archiveFileInfo;
+ HRESULT result = DeCompressArchiveSTD(archiveHandler, wildcardCensor, options);
+ if (result != S_OK)
+ {
+ return NExitCode::kErrorsDuringDecompression;
+ }
+ }
+ else
+ {
+ PrintProcessTitle(kListingProcessMessage, archiveName);
+ ListArchive(archiveHandler, defaultItemName, archiveFileInfo,
+ wildcardCensor/*, command.ListFullPathes, command.ListMode*/);
+ }
+ }
+ else
+ PrintHelpAndExit();
+ return 0;
+}
diff --git a/7zip/Bundles/SFXCon/SFXCon.dsp b/7zip/Bundles/SFXCon/SFXCon.dsp
new file mode 100755
index 00000000..592c8cfb
--- /dev/null
+++ b/7zip/Bundles/SFXCon/SFXCon.dsp
@@ -0,0 +1,675 @@
+# 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 /MT /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\7zSfxCon.exe" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "SFXCon - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /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\7zSfxCon.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "SFXCon - Win32 Release"
+# Name "SFXCon - Win32 Debug"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Archive Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.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 Archiver"
+
+# 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\Extract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\Extract.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ExtractCallback.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\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
+# 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\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
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAES\MySHA256.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAES\SHA256.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAES\SHA256.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
+# 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
+# Begin Source File
+
+SOURCE=..\..\..\Windows\System.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\System.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\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\MultiStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MultiStream.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
+# End Group
+# Begin Group "UI"
+
+# PROP Default_Filter ""
+# Begin Group "UI Common"
+
+# PROP Default_Filter ""
+# 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\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
+# 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/7zip/Bundles/SFXCon/SFXCon.dsw b/7zip/Bundles/SFXCon/SFXCon.dsw
new file mode 100755
index 00000000..27bf7e6d
--- /dev/null
+++ b/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/7zip/Bundles/SFXCon/StdAfx.cpp b/7zip/Bundles/SFXCon/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Bundles/SFXCon/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Bundles/SFXCon/StdAfx.h b/7zip/Bundles/SFXCon/StdAfx.h
new file mode 100755
index 00000000..77b5124c
--- /dev/null
+++ b/7zip/Bundles/SFXCon/StdAfx.h
@@ -0,0 +1,11 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+#include <stdio.h>
+// #include <time.h>
+#include <tchar.h>
+
+#endif
diff --git a/7zip/Bundles/SFXCon/resource.h b/7zip/Bundles/SFXCon/resource.h
new file mode 100755
index 00000000..7b0dd8ff
--- /dev/null
+++ b/7zip/Bundles/SFXCon/resource.h
@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDI_ICON1 101
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Bundles/SFXCon/resource.rc b/7zip/Bundles/SFXCon/resource.rc
new file mode 100755
index 00000000..f0444133
--- /dev/null
+++ b/7zip/Bundles/SFXCon/resource.rc
@@ -0,0 +1,130 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1 ICON DISCARDABLE "7z.ico"
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,12,0,0
+ PRODUCTVERSION 3,12,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "7z SFX (Console version)\0"
+ VALUE "FileVersion", "3, 12, 0, 0\0"
+ VALUE "InternalName", "7zCon.sfx\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "7zCon.sfx\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 12, 0, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Bundles/SFXSetup/ExtractCallback.cpp b/7zip/Bundles/SFXSetup/ExtractCallback.cpp
new file mode 100755
index 00000000..893817d6
--- /dev/null
+++ b/7zip/Bundles/SFXSetup/ExtractCallback.cpp
@@ -0,0 +1,266 @@
+// 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 LPCTSTR kUnknownError = TEXT("Unknown Error");
+
+void CExtractCallbackImp::Init(IInArchive *archiveHandler,
+ const UString &directoryPath,
+ const UString &itemDefaultName,
+ const FILETIME &utcLastWriteTimeDefault,
+ UINT32 attributesDefault)
+{
+ _numErrors = 0;
+ _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
+ while(true)
+ {
+ 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))
+ {
+ #ifdef _SILENT
+ _message = kCantDeleteFile;
+ #else
+ MessageBoxW(0, kCantDeleteFile, kErrorTitle, 0);
+ #endif
+ // g_StdOut << GetOemString(fullProcessedPath);
+ // return E_ABORT;
+ return E_ABORT;
+ }
+ }
+
+ if (!isAnti)
+ {
+ _outFileStreamSpec = new COutFileStream;
+ CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
+ if (!_outFileStreamSpec->Open(fullProcessedPath))
+ {
+ #ifdef _SILENT
+ _message = kCantOpenFile;
+ #else
+ MessageBoxW(0, kCantOpenFile, kErrorTitle, 0);
+ #endif
+ return E_ABORT;
+ }
+ _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:
+ {
+ _numErrors++;
+ UString errorMessage;
+ _outFileStream.Release();
+ switch(resultEOperationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
+ errorMessage = kUnsupportedMethod;
+ break;
+ case NArchive::NExtract::NOperationResult::kCRCError:
+ errorMessage = kCRCFailed;
+ break;
+ case NArchive::NExtract::NOperationResult::kDataError:
+ errorMessage = kDataError;
+ break;
+ /*
+ default:
+ errorMessage = kUnknownError;
+ */
+ }
+ #ifdef _SILENT
+ _message = errorMessage;
+ #else
+ MessageBoxW(0, errorMessage, kErrorTitle, 0);
+ #endif
+ 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/7zip/Bundles/SFXSetup/ExtractCallback.h b/7zip/Bundles/SFXSetup/ExtractCallback.h
new file mode 100755
index 00000000..b5b72a24
--- /dev/null
+++ b/7zip/Bundles/SFXSetup/ExtractCallback.h
@@ -0,0 +1,105 @@
+// ExtractCallback.h
+
+#pragma once
+
+#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 "../../Common/ZipSettings.h"
+#include "../../ICoder.h"
+
+#ifndef _NO_PROGRESS
+#include "../../FileManager/Resource/ProgressDialog/ProgressDialog.h"
+#endif
+
+// #include "../../Explorer/MyMessages.h"
+
+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
+
+ #ifdef _SILENT
+ UString _message;
+ #endif
+
+ void Init(IInArchive *archiveHandler,
+ const UString &directoryPath,
+ const UString &itemDefaultName,
+ const FILETIME &utcLastWriteTimeDefault,
+ UINT32 attributesDefault);
+
+ UINT64 _numErrors;
+
+ #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);
+ // _progressDialog.Start(m_ParentWindow, PROGDLG_MODAL | PROGDLG_AUTOTIME);
+ return S_OK;
+ }
+ ~CExtractCallbackImp() { ProgressDialog.Destroy(); }
+ #endif
+
+};
+
+#endif
diff --git a/7zip/Bundles/SFXSetup/ExtractEngine.cpp b/7zip/Bundles/SFXSetup/ExtractEngine.cpp
new file mode 100755
index 00000000..dd45f53e
--- /dev/null
+++ b/7zip/Bundles/SFXSetup/ExtractEngine.cpp
@@ -0,0 +1,150 @@
+// ExtractEngine.h
+
+#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
+{
+ CMyComPtr<IInArchive> ArchiveHandler;
+ CExtractCallbackImp *ExtractCallbackSpec;
+ CMyComPtr<IArchiveExtractCallback> ExtractCallback;
+
+ #ifndef _NO_PROGRESS
+ HRESULT Result;
+
+ DWORD Process()
+ {
+ ExtractCallbackSpec->ProgressDialog.WaitCreating();
+ Result = ArchiveHandler->Extract(0, (UINT32)-1 , BoolToInt(false),
+ ExtractCallback);
+ ExtractCallbackSpec->ProgressDialog.MyClose();
+ return 0;
+ }
+ static DWORD WINAPI MyThreadFunction(void *param)
+ {
+ return ((CThreadExtracting *)param)->Process();
+ }
+ #endif
+};
+
+static const LPCTSTR kCantFindArchive = TEXT("Can not find archive file");
+static const LPCTSTR kCantOpenArchive = TEXT("File is not correct archive");
+
+HRESULT ExtractArchive(
+ const UString &fileName,
+ const UString &folderName
+ #ifdef _SILENT
+ , UString &resultMessage
+ #endif
+ )
+{
+ NFile::NFind::CFileInfoW archiveFileInfo;
+ if (!NFile::NFind::FindFile(fileName, archiveFileInfo))
+ {
+ #ifndef _SILENT
+ MessageBox(0, kCantFindArchive, TEXT("7-Zip"), 0);
+ #else
+ resultMessage = kCantFindArchive;
+ #endif
+ return E_FAIL;
+ }
+
+ CThreadExtracting extracter;
+
+ CArchiverInfo archiverInfoResult;
+ int subExtIndex;
+ HRESULT result = OpenArchive(fileName, &extracter.ArchiveHandler,
+ archiverInfoResult, subExtIndex, NULL);
+ if (result != S_OK)
+ {
+ #ifdef _SILENT
+ resultMessage = kCantOpenArchive;
+ #endif
+ return E_FAIL;
+ }
+
+ UString directoryPath = folderName;
+ NFile::NName::NormalizeDirPathPrefix(directoryPath);
+
+ /*
+ UString directoryPath;
+ {
+ UString aFullPath;
+ int aFileNamePartStartIndex;
+ if (!NWindows::NFile::NDirectory::MyGetFullPathName(fileName, aFullPath, aFileNamePartStartIndex))
+ {
+ MessageBox(NULL, "Error 1329484", "7-Zip", 0);
+ return E_FAIL;
+ }
+ directoryPath = aFullPath.Left(aFileNamePartStartIndex);
+ }
+ */
+
+ if(!NFile::NDirectory::CreateComplexDirectory(directoryPath))
+ {
+ #ifndef _SILENT
+ MyMessageBox(MyFormatNew(IDS_CANNOT_CREATE_FOLDER,
+ #ifdef LANG
+ 0x02000603,
+ #endif
+ directoryPath));
+ #else
+ resultMessage = TEXT("Can not create output folder");
+ #endif
+ return E_FAIL;
+ }
+
+ extracter.ExtractCallbackSpec = new CExtractCallbackImp;
+ extracter.ExtractCallback = extracter.ExtractCallbackSpec;
+
+ // anExtractCallBackSpec->StartProgressDialog();
+
+ // anExtractCallBackSpec->m_ProgressDialog.ShowWindow(SW_SHOWNORMAL);
+
+ extracter.ExtractCallbackSpec->Init(extracter.ArchiveHandler,
+ directoryPath, L"Default", archiveFileInfo.LastWriteTime, 0);
+
+ #ifndef _NO_PROGRESS
+
+ 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);
+ return extracter.Result;
+
+ #else
+
+ result = extracter.ArchiveHandler->Extract(0, (UINT32)-1,
+ BoolToInt(false), extracter.ExtractCallback);
+ #ifdef _SILENT
+ resultMessage = extracter.ExtractCallbackSpec->_message;
+ #endif
+ return result;
+ #endif
+}
+
+
+
diff --git a/7zip/Bundles/SFXSetup/ExtractEngine.h b/7zip/Bundles/SFXSetup/ExtractEngine.h
new file mode 100755
index 00000000..331ac7fa
--- /dev/null
+++ b/7zip/Bundles/SFXSetup/ExtractEngine.h
@@ -0,0 +1,17 @@
+// ExtractEngine.h
+
+#ifndef __EXTRACTENGINE_H
+#define __EXTRACTENGINE_H
+
+#include "Common/String.h"
+
+HRESULT ExtractArchive(
+ const UString &fileName,
+ const UString &folderName
+ #ifdef _SILENT
+ , UString &resultMessage
+ #endif
+ );
+
+#endif
+
diff --git a/7zip/Bundles/SFXSetup/Main.cpp b/7zip/Bundles/SFXSetup/Main.cpp
new file mode 100755
index 00000000..b132522a
--- /dev/null
+++ b/7zip/Bundles/SFXSetup/Main.cpp
@@ -0,0 +1,235 @@
+// 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 "../../IPassword.h"
+#include "../../ICoder.h"
+#include "../../Archive/IArchive.h"
+#include "../../UI/Explorer/MyMessages.h"
+
+#include "ExtractEngine.h"
+
+HINSTANCE g_hInstance;
+
+using namespace NWindows;
+
+static LPCTSTR kTempDirPrefix = TEXT("7zS");
+
+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;
+ while(true)
+ {
+ 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;
+ while (true)
+ {
+ 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)); }
+};
+
+int APIENTRY WinMain(
+ HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine,
+ int nCmdShow)
+{
+ InitCommonControls();
+ g_hInstance = (HINSTANCE)hInstance;
+ UString archiveName, switches;
+ NCommandLineParser::SplitCommandLine(GetCommandLineW(), archiveName, switches);
+
+ UString fullPath;
+ NDLL::MyGetModuleFileName(g_hInstance, fullPath);
+
+ AString config;
+ if (!ReadDataString(fullPath, kStartID, kEndID, config))
+ {
+ MyMessageBox(L"Can't load config info");
+ return 1;
+ }
+ switches.Trim();
+ bool assumeYes = false;
+ if (switches.Left(2).CompareNoCase(UString(L"-y")) == 0)
+ {
+ assumeYes = true;
+ switches = switches.Mid(2);
+ switches.Trim();
+ }
+
+ UString appLaunched;
+ if (!config.IsEmpty())
+ {
+ CObjectVector<CTextConfigPair> pairs;
+ if (!GetTextConfig(config, pairs))
+ {
+ MyMessageBox(L"Config failed");
+ return 1;
+ }
+ UString friendlyName = GetTextConfigValue(pairs, L"Title");
+ UString installPrompt = GetTextConfigValue(pairs, L"BeginPrompt");
+
+ if (!installPrompt.IsEmpty() && !assumeYes)
+ {
+ if (MessageBoxW(0, installPrompt, friendlyName, MB_YESNO |
+ MB_ICONQUESTION) != IDYES)
+ return 0;
+ }
+ appLaunched = GetTextConfigValue(pairs, L"RunProgram");
+ }
+
+ NFile::NDirectory::CTempDirectory tempDir;
+ if (!tempDir.Create(kTempDirPrefix))
+ {
+ MyMessageBox(L"Can not create temp folder archive");
+ return 1;
+ }
+
+ HRESULT result = ExtractArchive(fullPath, GetUnicodeString(tempDir.GetPath()));
+ if (result != S_OK)
+ {
+ if (result == S_FALSE)
+ MyMessageBox(L"Can not open archive");
+ else if (result != E_ABORT)
+ ShowErrorMessage(result);
+ return 1;
+ }
+
+ CCurrentDirRestorer currentDirRestorer;
+
+ if (!SetCurrentDirectory(tempDir.GetPath()))
+ return 1;
+
+
+ if (appLaunched.IsEmpty())
+ {
+ appLaunched = L"Setup.exe";
+ if (!NFile::NFind::DoesFileExist(GetSystemString(appLaunched)))
+ return 1;
+ }
+ 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 shortPath;
+ if (!NFile::NDirectory::MyGetShortPathName(tempDir.GetPath(), shortPath))
+ return 1;
+
+ UString appLaunchedSysU = appLaunched;
+ appLaunchedSysU.Replace(TEXT(L"%%T"), GetUnicodeString(shortPath));
+
+ appLaunchedSysU += L' ';
+ appLaunchedSysU += switches;
+
+ CSysString tempDirPathNormalized = shortPath;
+ NFile::NName::NormalizeDirPathPrefix(shortPath);
+ // CSysString appLaunchedSys = shortPath + GetSystemString(appLaunchedSysU);
+ CSysString appLaunchedSys = CSysString(TEXT(".\\")) + GetSystemString(appLaunchedSysU);
+
+ BOOL createResult = CreateProcess(NULL, (LPTSTR)(LPCTSTR)appLaunchedSys,
+ NULL, NULL, FALSE, 0, NULL, NULL /*tempDir.GetPath() */,
+ &startupInfo, &processInformation);
+ if (createResult == 0)
+ {
+ ShowLastErrorMessage();
+ return 1;
+ }
+ WaitForSingleObject(processInformation.hProcess, INFINITE);
+ ::CloseHandle(processInformation.hThread);
+ ::CloseHandle(processInformation.hProcess);
+ return 0;
+}
diff --git a/7zip/Bundles/SFXSetup/SFXSetup.dsp b/7zip/Bundles/SFXSetup/SFXSetup.dsp
new file mode 100755
index 00000000..38b10955
--- /dev/null
+++ b/7zip/Bundles/SFXSetup/SFXSetup.dsp
@@ -0,0 +1,617 @@
+# 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\7zSfxS.exe" /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\7zSfxSD.exe" /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
+# 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\CrossThreadProgress.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.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\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\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\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\MultiStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MultiStream.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
+# 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\ArchiverInfo.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiverInfo.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\OpenArchive.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\OpenArchive.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "File Manager"
+
+# PROP Default_Filter ""
+# Begin 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
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\ProgressDialog\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\ProgressDialog\resource.rc
+# PROP Exclude_From_Build 1
+# 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/7zip/Bundles/SFXSetup/SFXSetup.dsw b/7zip/Bundles/SFXSetup/SFXSetup.dsw
new file mode 100755
index 00000000..f563b21f
--- /dev/null
+++ b/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/7zip/Bundles/SFXSetup/StdAfx.cpp b/7zip/Bundles/SFXSetup/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Bundles/SFXSetup/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Bundles/SFXSetup/StdAfx.h b/7zip/Bundles/SFXSetup/StdAfx.h
new file mode 100755
index 00000000..fe98539c
--- /dev/null
+++ b/7zip/Bundles/SFXSetup/StdAfx.h
@@ -0,0 +1,11 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+#include <commctrl.h>
+#include <limits.h>
+// #include <time.h>
+
+#endif
diff --git a/7zip/Bundles/SFXSetup/resource.h b/7zip/Bundles/SFXSetup/resource.h
new file mode 100755
index 00000000..a0dc7925
--- /dev/null
+++ b/7zip/Bundles/SFXSetup/resource.h
@@ -0,0 +1,19 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDI_ICON3 159
+
+#define IDS_CANNOT_CREATE_FOLDER 9
+#define IDS_PROGRESS_EXTRACTING 69
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 160
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1091
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Bundles/SFXSetup/resource.rc b/7zip/Bundles/SFXSetup/resource.rc
new file mode 100755
index 00000000..9ff820c2
--- /dev/null
+++ b/7zip/Bundles/SFXSetup/resource.rc
@@ -0,0 +1,148 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""..\\..\\FileManager\\Resource\\ProgressDialog\\resource.rc""\r\n"
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON3 ICON DISCARDABLE "setup.ico"
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,12,0,0
+ PRODUCTVERSION 3,12,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "7z Self-Extract Setup\0"
+ VALUE "FileVersion", "3, 12, 0, 0\0"
+ VALUE "InternalName", "7zS.sfx\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "7zS.sfx\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 12, 0, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_CANNOT_CREATE_FOLDER "Cannot create folder '{0}'"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_PROGRESS_EXTRACTING "Extracting"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "..\..\FileManager\Resource\ProgressDialog\resource.rc"
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Bundles/SFXSetup/setup.ico b/7zip/Bundles/SFXSetup/setup.ico
new file mode 100755
index 00000000..bb455be1
--- /dev/null
+++ b/7zip/Bundles/SFXSetup/setup.ico
Binary files differ
diff --git a/7zip/Bundles/SFXWin/7z.ico b/7zip/Bundles/SFXWin/7z.ico
new file mode 100755
index 00000000..47ffb781
--- /dev/null
+++ b/7zip/Bundles/SFXWin/7z.ico
Binary files differ
diff --git a/7zip/Bundles/SFXWin/Main.cpp b/7zip/Bundles/SFXWin/Main.cpp
new file mode 100755
index 00000000..ec7e5fd0
--- /dev/null
+++ b/7zip/Bundles/SFXWin/Main.cpp
@@ -0,0 +1,66 @@
+// 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/Agent/Agent.h"
+#include "../../UI/GUI/Extract.h"
+#include "../../UI/Explorer/MyMessages.h"
+
+HINSTANCE g_hInstance;
+
+int APIENTRY WinMain(
+ HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine,
+ int nCmdShow)
+{
+ g_hInstance = (HINSTANCE)hInstance;
+ 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();
+ }
+ }
+
+ 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;
+ }
+ 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/7zip/Bundles/SFXWin/SFXWin.dsp b/7zip/Bundles/SFXWin/SFXWin.dsp
new file mode 100755
index 00000000..89b3eee4
--- /dev/null
+++ b/7zip/Bundles/SFXWin/SFXWin.dsp
@@ -0,0 +1,788 @@
+# 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
+
+# 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 /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 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\7zSfx.exe" /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\7zSfx.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "SFXWin - Win32 Release"
+# Name "SFXWin - Win32 Debug"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "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
+# 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\CrossThreadProgress.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.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\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 "Agent"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\Agent\Agent.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Agent\Agent.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Agent\AgentProxy.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Agent\AgentProxy.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Agent\ArchiveExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Agent\ArchiveExtractCallback.h
+# End Source File
+# 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)" == "SFXWin - Win32 Release"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "SFXWin - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\AES\aeskey.c
+
+!IF "$(CFG)" == "SFXWin - Win32 Release"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "SFXWin - Win32 Debug"
+
+!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)" == "SFXWin - Win32 Release"
+
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "SFXWin - Win32 Debug"
+
+!ENDIF
+
+# 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
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAES\SHA256.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Crypto\7zAES\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\MultiStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MultiStream.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
+# 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
+# Begin Source File
+
+SOURCE=..\..\FileManager\OpenCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\OpenCallback.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\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\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\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\Extract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\GUI\Extract.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\GUI\ExtractDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\GUI\ExtractDialog.h
+# End Source File
+# 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/7zip/Bundles/SFXWin/SFXWin.dsw b/7zip/Bundles/SFXWin/SFXWin.dsw
new file mode 100755
index 00000000..a9926c71
--- /dev/null
+++ b/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/7zip/Bundles/SFXWin/StdAfx.cpp b/7zip/Bundles/SFXWin/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Bundles/SFXWin/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Bundles/SFXWin/StdAfx.h b/7zip/Bundles/SFXWin/StdAfx.h
new file mode 100755
index 00000000..a6b81337
--- /dev/null
+++ b/7zip/Bundles/SFXWin/StdAfx.h
@@ -0,0 +1,14 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+#include <commctrl.h>
+#include <ShlObj.h>
+#include <tchar.h>
+#include <limits.h>
+
+// #include <vector>
+
+#endif
diff --git a/7zip/Bundles/SFXWin/resource.h b/7zip/Bundles/SFXWin/resource.h
new file mode 100755
index 00000000..e6ff17a6
--- /dev/null
+++ b/7zip/Bundles/SFXWin/resource.h
@@ -0,0 +1,23 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+
+#define IDD_DIALOG_EXTRACT 137
+
+#define IDI_ICON3 159
+
+#define IDC_EXTRACT_COMBO_PATH 1044
+#define IDC_EXTRACT_BUTTON_SET_PATH 1045
+#define IDC_STATIC_EXTRACT_EXTRACT_TO 1092
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 160
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1093
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Bundles/SFXWin/resource.rc b/7zip/Bundles/SFXWin/resource.rc
new file mode 100755
index 00000000..cacc2257
--- /dev/null
+++ b/7zip/Bundles/SFXWin/resource.rc
@@ -0,0 +1,159 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""..\\..\\FileManager\\Resource\\OverwriteDialog\\resource.rc""\r\n"
+ "#include ""..\\..\\FileManager\\Resource\\PasswordDialog\\resource.rc""\r\n"
+ "#include ""..\\..\\FileManager\\Resource\\MessagesDialog\\resource.rc""\r\n"
+ "#include ""..\\..\\FileManager\\Resource\\ProgressDialog\\resource.rc""\r\n"
+ "#include ""..\\..\\UI\\Resource\\Extract\\resource.rc""\r\n"
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON3 ICON DISCARDABLE "7z.ico"
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,12,0,0
+ PRODUCTVERSION 3,12,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "7z SFX\0"
+ VALUE "FileVersion", "3, 12, 0, 0\0"
+ VALUE "InternalName", "7zWin.sfx\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "7zWin.sfx\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 12, 0, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALOG_EXTRACT DIALOG DISCARDABLE 0, 0, 228, 78
+STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "7-Zip self-extracting archive"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "E&xtract to:",IDC_STATIC_EXTRACT_EXTRACT_TO,7,7,33,8
+ EDITTEXT IDC_EXTRACT_COMBO_PATH,7,21,184,14,ES_AUTOHSCROLL
+ PUSHBUTTON "...",IDC_EXTRACT_BUTTON_SET_PATH,203,20,18,14,WS_GROUP
+ DEFPUSHBUTTON "Extract",IDOK,111,57,50,14,WS_GROUP
+ PUSHBUTTON "Cancel",IDCANCEL,171,57,50,14
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "..\..\FileManager\Resource\OverwriteDialog\resource.rc"
+#include "..\..\FileManager\Resource\PasswordDialog\resource.rc"
+#include "..\..\FileManager\Resource\MessagesDialog\resource.rc"
+#include "..\..\FileManager\Resource\ProgressDialog\resource.rc"
+#include "..\..\UI\Resource\Extract\resource.rc"
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Common/FilePathAutoRename.cpp b/7zip/Common/FilePathAutoRename.cpp
new file mode 100755
index 00000000..ddeb7366
--- /dev/null
+++ b/7zip/Common/FilePathAutoRename.cpp
@@ -0,0 +1,53 @@
+// 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 slashDot1 = fullProcessedPath.ReverseFind(L'\\');
+ int slashDot2 = fullProcessedPath.ReverseFind(L'/');
+ int slashDot = MyMin(slashDot1, slashDot2);
+ UString name, extension;
+ if (dotPos > slashDot && 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/7zip/Common/FilePathAutoRename.h b/7zip/Common/FilePathAutoRename.h
new file mode 100755
index 00000000..931c6566
--- /dev/null
+++ b/7zip/Common/FilePathAutoRename.h
@@ -0,0 +1,12 @@
+// Util/FilePathAutoRename.h
+
+#pragma once
+
+#ifndef __FILEPATHAUTORENAME_H
+#define __FILEPATHAUTORENAME_H
+
+#include "Common/String.h"
+
+bool AutoRenamePath(UString &fullProcessedPath);
+
+#endif
diff --git a/7zip/Common/FileStreams.cpp b/7zip/Common/FileStreams.cpp
new file mode 100755
index 00000000..7a1f22b2
--- /dev/null
+++ b/7zip/Common/FileStreams.cpp
@@ -0,0 +1,110 @@
+// FileStreams.cpp
+
+#include "StdAfx.h"
+#include "FileStreams.h"
+
+static inline HRESULT ConvertBoolToHRESULT(bool result)
+{
+ // return result ? S_OK: E_FAIL;
+ return result ? S_OK: (::GetLastError());
+}
+
+bool CInFileStream::Open(LPCTSTR fileName)
+{
+ return File.Open(fileName);
+}
+
+#ifndef _UNICODE
+bool CInFileStream::Open(LPCWSTR fileName)
+{
+ return File.Open(fileName);
+}
+#endif
+
+STDMETHODIMP CInFileStream::Read(void *data, UINT32 size, UINT32 *processedSize)
+{
+ UINT32 realProcessedSize;
+ bool result = File.Read(data, size, realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return ConvertBoolToHRESULT(result);
+}
+
+STDMETHODIMP CInFileStream::ReadPart(void *data, UINT32 size, UINT32 *processedSize)
+{
+ return Read(data, size, processedSize);
+}
+
+
+STDMETHODIMP CInFileStream::Seek(INT64 offset, UINT32 seekOrigin,
+ UINT64 *newPosition)
+{
+ if(seekOrigin >= 3)
+ return STG_E_INVALIDFUNCTION;
+ UINT64 realNewPosition;
+ bool result = File.Seek(offset, seekOrigin, realNewPosition);
+ if(newPosition != NULL)
+ *newPosition = realNewPosition;
+ return ConvertBoolToHRESULT(result);
+}
+
+STDMETHODIMP CInFileStream::GetSize(UINT64 *size)
+{
+ return ConvertBoolToHRESULT(File.GetLength(*size));
+}
+
+
+//////////////////////////
+// COutFileStream
+
+bool COutFileStream::Open(LPCTSTR fileName)
+{
+ File.SetOpenCreationDispositionCreateAlways();
+ return File.Open(fileName);
+}
+
+#ifndef _UNICODE
+bool COutFileStream::Open(LPCWSTR fileName)
+{
+ File.SetOpenCreationDispositionCreateAlways();
+ return File.Open(fileName);
+}
+#endif
+
+STDMETHODIMP COutFileStream::Write(const void *data, UINT32 size, UINT32 *processedSize)
+{
+ UINT32 realProcessedSize;
+ bool result = File.Write(data, size, realProcessedSize);
+ if(processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return ConvertBoolToHRESULT(result);
+}
+
+STDMETHODIMP COutFileStream::WritePart(const void *data, UINT32 size, UINT32 *processedSize)
+{
+ return Write(data, size, processedSize);
+}
+
+
+STDMETHODIMP COutFileStream::Seek(INT64 offset, UINT32 seekOrigin,
+ UINT64 *newPosition)
+{
+ if(seekOrigin >= 3)
+ return STG_E_INVALIDFUNCTION;
+ UINT64 realNewPosition;
+ bool result = File.Seek(offset, seekOrigin, realNewPosition);
+ if(newPosition != NULL)
+ *newPosition = realNewPosition;
+ return ConvertBoolToHRESULT(result);
+}
+
+STDMETHODIMP COutFileStream::SetSize(INT64 newSize)
+{
+ 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;
+}
diff --git a/7zip/Common/FileStreams.h b/7zip/Common/FileStreams.h
new file mode 100755
index 00000000..f3295323
--- /dev/null
+++ b/7zip/Common/FileStreams.h
@@ -0,0 +1,55 @@
+// FileStreams.h
+
+#pragma once
+
+#ifndef __FILESTREAMS_H
+#define __FILESTREAMS_H
+
+#include "Windows/FileIO.h"
+
+#include "../IStream.h"
+#include "Common/MyCom.h"
+
+class CInFileStream:
+ public IInStream,
+ public IStreamGetSize,
+ public CMyUnknownImp
+{
+public:
+ NWindows::NFile::NIO::CInFile File;
+ CInFileStream() {}
+ bool Open(LPCTSTR fileName);
+ #ifndef _UNICODE
+ bool Open(LPCWSTR fileName);
+ #endif
+
+ MY_UNKNOWN_IMP1(IStreamGetSize)
+
+ STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize);
+ STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize);
+ STDMETHOD(Seek)(INT64 offset, UINT32 seekOrigin, UINT64 *newPosition);
+
+ STDMETHOD(GetSize)(UINT64 *size);
+};
+
+class COutFileStream:
+ public IOutStream,
+ public CMyUnknownImp
+{
+public:
+ NWindows::NFile::NIO::COutFile File;
+ COutFileStream() {}
+ bool Open(LPCTSTR fileName);
+ #ifndef _UNICODE
+ bool Open(LPCWSTR fileName);
+ #endif
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize);
+ STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize);
+ STDMETHOD(Seek)(INT64 offset, UINT32 seekOrigin, UINT64 *newPosition);
+ STDMETHOD(SetSize)(INT64 newSize);
+};
+
+#endif
diff --git a/7zip/Common/InBuffer.cpp b/7zip/Common/InBuffer.cpp
new file mode 100755
index 00000000..2d56e44d
--- /dev/null
+++ b/7zip/Common/InBuffer.cpp
@@ -0,0 +1,41 @@
+// InBuffer.cpp
+
+#include "stdafx.h"
+
+#include "InBuffer.h"
+
+CInBuffer::CInBuffer(UINT32 bufferSize):
+ _bufferSize(bufferSize),
+ _bufferBase(0)
+{
+ _bufferBase = new BYTE[_bufferSize];
+}
+
+CInBuffer::~CInBuffer()
+{
+ delete []_bufferBase;
+}
+
+void CInBuffer::Init(ISequentialInStream *stream)
+{
+ _stream = stream;
+ _processedSize = 0;
+ _buffer = _bufferBase;
+ _bufferLimit = _buffer;
+ _streamWasExhausted = false;
+}
+
+bool CInBuffer::ReadBlock()
+{
+ if (_streamWasExhausted)
+ return false;
+ _processedSize += (_buffer - _bufferBase);
+ UINT32 numProcessedBytes;
+ HRESULT result = _stream->ReadPart(_bufferBase, _bufferSize, &numProcessedBytes);
+ if (result != S_OK)
+ throw CInBufferException(result);
+ _buffer = _bufferBase;
+ _bufferLimit = _buffer + numProcessedBytes;
+ _streamWasExhausted = (numProcessedBytes == 0);
+ return (!_streamWasExhausted);
+}
diff --git a/7zip/Common/InBuffer.h b/7zip/Common/InBuffer.h
new file mode 100755
index 00000000..604a6658
--- /dev/null
+++ b/7zip/Common/InBuffer.h
@@ -0,0 +1,66 @@
+// InBuffer.h
+
+// #pragma once
+
+#ifndef __INBUFFER_H
+#define __INBUFFER_H
+
+#include "../IStream.h"
+
+class CInBufferException
+{
+public:
+ HRESULT ErrorCode;
+ CInBufferException(HRESULT errorCode): ErrorCode(errorCode) {}
+};
+
+class CInBuffer
+{
+ UINT64 _processedSize;
+ BYTE *_bufferBase;
+ UINT32 _bufferSize;
+ BYTE *_buffer;
+ BYTE *_bufferLimit;
+ ISequentialInStream *_stream;
+ bool _streamWasExhausted;
+
+ bool ReadBlock();
+
+public:
+ CInBuffer(UINT32 bufferSize = 0x100000);
+ ~CInBuffer();
+
+ void Init(ISequentialInStream *stream);
+ // void ReleaseStream() { _stream.Release(); }
+
+ bool ReadByte(BYTE &b)
+ {
+ if(_buffer >= _bufferLimit)
+ if(!ReadBlock())
+ return false;
+ b = *_buffer++;
+ return true;
+ }
+ BYTE ReadByte()
+ {
+ if(_buffer >= _bufferLimit)
+ if(!ReadBlock())
+ return 0x0;
+ 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); }
+};
+
+#endif
diff --git a/7zip/Common/InOutTempBuffer.cpp b/7zip/Common/InOutTempBuffer.cpp
new file mode 100755
index 00000000..cc956869
--- /dev/null
+++ b/7zip/Common/InOutTempBuffer.cpp
@@ -0,0 +1,148 @@
+// InOutTempBuffer.cpp
+
+#include "StdAfx.h"
+
+#include "InOutTempBuffer.h"
+#include "../../Common/Defs.h"
+// #include "Windows/Defs.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.Open(_tmpFileName))
+ 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)
+{
+ UINT32 numBytes = 0;
+ 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;
+}
+
+/*
+bool CInOutTempBuffer::Read(void *data, UINT32 maxSize, UINT32 &processedSize)
+{
+ processedSize = 0;
+ if (_currentPositionInBuffer < _bufferPosition)
+ {
+ UINT32 sizeToRead = MyMin(_bufferPosition - _currentPositionInBuffer, maxSize);
+ memmove(data, _buffer + _currentPositionInBuffer, sizeToRead);
+ data = ((BYTE *)data) + sizeToRead;
+ _currentPositionInBuffer += sizeToRead;
+ processedSize += sizeToRead;
+ maxSize -= sizeToRead;
+ }
+ if (maxSize == 0 || !_tmpFileCreated)
+ return true;
+ UINT32 localProcessedSize;
+ bool result = _inFile.Read(data, maxSize, localProcessedSize);
+ processedSize += localProcessedSize;
+ return result;
+}
+*/
+
+HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream)
+{
+ if (_currentPositionInBuffer < _bufferPosition)
+ {
+ UINT32 sizeToWrite = _bufferPosition - _currentPositionInBuffer;
+ RINOK(stream->Write(_buffer + _currentPositionInBuffer, sizeToWrite, NULL));
+ _currentPositionInBuffer += sizeToWrite;
+ }
+ if (!_tmpFileCreated)
+ return true;
+ while(true)
+ {
+ UINT32 localProcessedSize;
+ if (!_inFile.Read(_buffer, kTmpBufferMemorySize, localProcessedSize))
+ return E_FAIL;
+ if (localProcessedSize == 0)
+ return S_OK;
+ RINOK(stream->Write(_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;
+}
+
+STDMETHODIMP CSequentialOutTempBufferImp::WritePart(const void *data, UINT32 size, UINT32 *processedSize)
+{
+ return Write(data, size, processedSize);
+}
diff --git a/7zip/Common/InOutTempBuffer.h b/7zip/Common/InOutTempBuffer.h
new file mode 100755
index 00000000..c1762b40
--- /dev/null
+++ b/7zip/Common/InOutTempBuffer.h
@@ -0,0 +1,59 @@
+// Util/InOutTempBuffer.h
+
+#pragma once
+
+#ifndef __INOUTTEMPBUFFER_H
+#define __INOUTTEMPBUFFER_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();
+ // bool Read(void *data, UINT32 maxSize, UINT32 &processedSize);
+ 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);
+ STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize);
+};
+
+#endif
diff --git a/7zip/Common/LSBFDecoder.cpp b/7zip/Common/LSBFDecoder.cpp
new file mode 100755
index 00000000..59df1acd
--- /dev/null
+++ b/7zip/Common/LSBFDecoder.cpp
@@ -0,0 +1,34 @@
+// 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++)
+ {
+ BYTE b = BYTE(i);
+ BYTE bInvert = 0;
+ for(int j = 0; j < 8; j++)
+ {
+ bInvert <<= 1;
+ if (b & 1)
+ bInvert |= 1;
+ b >>= 1;
+ }
+ kInvertTable[i] = bInvert;
+ }
+ }
+} g_InverterTableInitializer;
+
+
+}}
diff --git a/7zip/Common/LSBFDecoder.h b/7zip/Common/LSBFDecoder.h
new file mode 100755
index 00000000..db6bf514
--- /dev/null
+++ b/7zip/Common/LSBFDecoder.h
@@ -0,0 +1,96 @@
+// Stream/LSBFDecoder.h
+
+#pragma once
+
+#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 CDecoder
+{
+ UINT32 m_BitPos;
+ UINT32 m_Value;
+ UINT32 m_NormalValue;
+protected:
+ TInByte m_Stream;
+public:
+ UINT32 NumExtraBytes;
+ void Init(ISequentialInStream *inStream)
+ {
+ m_Stream.Init(inStream);
+ Init();
+ }
+ void Init()
+ {
+ m_BitPos = kNumBigValueBits;
+ m_NormalValue = 0;
+ NumExtraBytes = 0;
+ }
+ /*
+ void ReleaseStream()
+ {
+ m_Stream.ReleaseStream();
+ }
+ */
+ UINT64 GetProcessedSize() const
+ { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; }
+ UINT64 GetProcessedBitsSize() const
+ { return (m_Stream.GetProcessedSize() << 3) - (kNumBigValueBits - m_BitPos); }
+
+ void Normalize()
+ {
+ for (;m_BitPos >= 8; m_BitPos -= 8)
+ {
+ BYTE b;
+ if (!m_Stream.ReadByte(b))
+ NumExtraBytes++;
+ m_NormalValue = (b << (kNumBigValueBits - m_BitPos)) | m_NormalValue;
+ m_Value = (m_Value << 8) | kInvertTable[b];
+ }
+ }
+
+ UINT32 GetValue(UINT32 numBits)
+ {
+ Normalize();
+ return ((m_Value >> (8 - m_BitPos)) & kMask) >> (kNumValueBits - numBits);
+ }
+
+ void MovePos(UINT32 numBits)
+ {
+ m_BitPos += numBits;
+ m_NormalValue >>= numBits;
+ }
+
+ UINT32 ReadBits(UINT32 numBits)
+ {
+ Normalize();
+ UINT32 res = m_NormalValue & ( (1 << numBits) - 1);
+ MovePos(numBits);
+ return res;
+ }
+
+ UINT32 GetBitPosition() const
+ {
+ return (m_BitPos & 7);
+ }
+
+};
+
+}}
+
+#endif
diff --git a/7zip/Common/LSBFEncoder.cpp b/7zip/Common/LSBFEncoder.cpp
new file mode 100755
index 00000000..5c0f9a18
--- /dev/null
+++ b/7zip/Common/LSBFEncoder.cpp
@@ -0,0 +1,46 @@
+// LSBFEncoder.cpp
+
+#include "StdAfx.h"
+
+#include "LSBFEncoder.h"
+#include "Common/Defs.h"
+
+namespace NStream {
+namespace NLSBF {
+
+void CEncoder::WriteBits(UINT32 aValue, UINT32 aNumBits)
+{
+ while(aNumBits > 0)
+ {
+ UINT32 aNumNewBits = MyMin(aNumBits, m_BitPos);
+ aNumBits -= aNumNewBits;
+
+ UINT32 aMask = (1 << aNumNewBits) - 1;
+ m_CurByte |= (aValue & aMask) << (8 - m_BitPos);
+ aValue >>= aNumNewBits;
+
+ m_BitPos -= aNumNewBits;
+
+ if (m_BitPos == 0)
+ {
+ m_Stream.WriteByte(m_CurByte);
+ m_BitPos = 8;
+ m_CurByte = 0;
+ }
+ }
+}
+
+
+void CReverseEncoder::WriteBits(UINT32 aValue, UINT32 aNumBits)
+{
+ UINT32 aReverseValue = 0;
+ for(UINT32 i = 0; i < aNumBits; i++)
+ {
+ aReverseValue <<= 1;
+ aReverseValue |= aValue & 1;
+ aValue >>= 1;
+ }
+ m_Encoder->WriteBits(aReverseValue, aNumBits);
+}
+
+}}
diff --git a/7zip/Common/LSBFEncoder.h b/7zip/Common/LSBFEncoder.h
new file mode 100755
index 00000000..f9786dcb
--- /dev/null
+++ b/7zip/Common/LSBFEncoder.h
@@ -0,0 +1,59 @@
+// Stream/LSBFEncoder.h
+
+#pragma once
+
+#ifndef __STREAM_LSBFENCODER_H
+#define __STREAM_LSBFENCODER_H
+
+#include "../IStream.h"
+#include "OutBuffer.h"
+
+namespace NStream {
+namespace NLSBF {
+
+class CEncoder
+{
+ COutBuffer m_Stream;
+ UINT32 m_BitPos;
+ BYTE m_CurByte;
+public:
+ void Init(ISequentialOutStream *aStream)
+ {
+ m_Stream.Init(aStream);
+ m_BitPos = 8;
+ m_CurByte = 0;
+ }
+ HRESULT Flush()
+ {
+ if(m_BitPos < 8)
+ WriteBits(0, m_BitPos);
+ return m_Stream.Flush();
+ }
+ /*
+ void ReleaseStream()
+ {
+ m_Stream.ReleaseStream();
+ }
+ */
+
+ void WriteBits(UINT32 aValue, UINT32 aNumBits);
+
+ UINT32 GetBitPosition() const
+ { return (8 - m_BitPos); }
+
+ UINT64 GetProcessedSize() const {
+ return m_Stream.GetProcessedSize() + (8 - m_BitPos + 7) /8; }
+};
+
+class CReverseEncoder
+{
+ CEncoder *m_Encoder;
+public:
+ void Init(CEncoder *anEncoder)
+ { m_Encoder = anEncoder; }
+ void WriteBits(UINT32 aValue, UINT32 aNumBits);
+};
+
+}}
+
+#endif
diff --git a/7zip/Common/LimitedStreams.cpp b/7zip/Common/LimitedStreams.cpp
new file mode 100755
index 00000000..49e8554c
--- /dev/null
+++ b/7zip/Common/LimitedStreams.cpp
@@ -0,0 +1,36 @@
+// LimitedStreams.cpp
+
+#include "StdAfx.h"
+
+#include "LimitedStreams.h"
+#include "../../Common/Defs.h"
+
+void CLimitedSequentialInStream::Init(ISequentialInStream *stream, UINT64 streamSize)
+{
+ _stream = stream;
+ _size = streamSize;
+}
+
+STDMETHODIMP CLimitedSequentialInStream::Read(void *data,
+ UINT32 size, UINT32 *processedSize)
+{
+ UINT32 processedSizeReal;
+ UINT32 sizeToRead = UINT32(MyMin(_size, UINT64(size)));
+ HRESULT result = _stream->Read(data, sizeToRead, &processedSizeReal);
+ _size -= processedSizeReal;
+ if(processedSize != NULL)
+ *processedSize = processedSizeReal;
+ return result;
+}
+
+STDMETHODIMP CLimitedSequentialInStream::ReadPart(void *data, UINT32 size, UINT32 *processedSize)
+{
+ UINT32 processedSizeReal;
+ UINT32 sizeToRead = UINT32(MyMin(_size, UINT64(size)));
+ HRESULT result = _stream->ReadPart(data, sizeToRead, &processedSizeReal);
+ _size -= processedSizeReal;
+ if(processedSize != NULL)
+ *processedSize = processedSizeReal;
+ return result;
+}
+
diff --git a/7zip/Common/LimitedStreams.h b/7zip/Common/LimitedStreams.h
new file mode 100755
index 00000000..b5c9be55
--- /dev/null
+++ b/7zip/Common/LimitedStreams.h
@@ -0,0 +1,26 @@
+// LimitedStreams.h
+
+#pragma once
+
+#ifndef __LIMITEDSTREAMS_H
+#define __LIMITEDSTREAMS_H
+
+#include "../../Common/MyCom.h"
+#include "../IStream.h"
+
+class CLimitedSequentialInStream:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ UINT64 _size;
+ CMyComPtr<ISequentialInStream> _stream;
+public:
+ void Init(ISequentialInStream *stream, UINT64 streamSize);
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize);
+ STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize);
+};
+
+#endif
diff --git a/7zip/Common/MSBFDecoder.h b/7zip/Common/MSBFDecoder.h
new file mode 100755
index 00000000..53accff6
--- /dev/null
+++ b/7zip/Common/MSBFDecoder.h
@@ -0,0 +1,73 @@
+// Stream/MSBFDecoder.h
+// the Most Significant Bit of byte is First
+
+#pragma once
+
+#ifndef __STREAM_MSBFDECODER_H
+#define __STREAM_MSBFDECODER_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
+{
+ TInByte m_Stream;
+ UINT32 m_BitPos;
+ UINT32 m_Value;
+
+public:
+
+ void Init(ISequentialInStream *aStream)
+ {
+ m_Stream.Init(aStream);
+ m_BitPos = kNumBigValueBits;
+ Normalize();
+ }
+
+ /*
+ void ReleaseStream()
+ {
+ m_Stream.ReleaseStream();
+ }
+ */
+
+ UINT64 GetProcessedSize() const
+ { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; }
+
+ void Normalize()
+ {
+ for (;m_BitPos >= 8; m_BitPos -= 8)
+ m_Value = (m_Value << 8) | m_Stream.ReadByte();
+ }
+
+ UINT32 GetValue(UINT32 aNumBits) const
+ {
+ // return (m_Value << m_BitPos) >> (kNumBigValueBits - aNumBits);
+ return ((m_Value >> (8 - m_BitPos)) & kMask) >> (kNumValueBits - aNumBits);
+ }
+
+ void MovePos(UINT32 aNumBits)
+ {
+ m_BitPos += aNumBits;
+ Normalize();
+ }
+
+ UINT32 ReadBits(UINT32 aNumBits)
+ {
+ UINT32 aRes = GetValue(aNumBits);
+ MovePos(aNumBits);
+ return aRes;
+ }
+};
+
+}}
+
+#endif
diff --git a/7zip/Common/MSBFEncoder.h b/7zip/Common/MSBFEncoder.h
new file mode 100755
index 00000000..b87bdea3
--- /dev/null
+++ b/7zip/Common/MSBFEncoder.h
@@ -0,0 +1,70 @@
+// Stream/MSBFEncoder.h
+// the Most Significant Bit of byte is First
+
+#pragma once
+
+#ifndef __STREAM_MSBFENCODER_H
+#define __STREAM_MSBFENCODER_H
+
+#include "Common/Defs.h"
+#include "Interface/IInOutStreams.h"
+
+namespace NStream {
+namespace NMSBF {
+
+template<class TOutByte>
+class CEncoder
+{
+ TOutByte m_Stream;
+ UINT32 m_BitPos;
+ BYTE m_CurByte;
+public:
+ void Init(ISequentialOutStream *aStream)
+ {
+ m_Stream.Init(aStream);
+ m_BitPos = 8;
+ m_CurByte = 0;
+ }
+ HRESULT Flush()
+ {
+ if(m_BitPos < 8)
+ WriteBits(0, m_BitPos);
+ return m_Stream.Flush();
+ }
+
+ void ReleaseStream()
+ {
+ m_Stream.ReleaseStream();
+ }
+
+ void WriteBits(UINT32 aValue, UINT32 aNumBits)
+ {
+ while(aNumBits > 0)
+ {
+ UINT32 aNumNewBits = MyMin(aNumBits, m_BitPos);
+ aNumBits -= aNumNewBits;
+
+
+ m_CurByte <<= aNumNewBits;
+ UINT32 aNewBits = aValue >> aNumBits;
+ m_CurByte |= BYTE(aNewBits);
+ aValue -= (aNewBits << aNumBits);
+
+
+ m_BitPos -= aNumNewBits;
+
+ if (m_BitPos == 0)
+ {
+ m_Stream.WriteByte(m_CurByte);
+ m_BitPos = 8;
+ }
+ }
+ }
+ UINT64 GetProcessedSize() const {
+ return m_Stream.GetProcessedSize() + (8 - m_BitPos + 7) /8; }
+};
+
+}}
+
+#endif
+
diff --git a/7zip/Common/MultiStream.cpp b/7zip/Common/MultiStream.cpp
new file mode 100755
index 00000000..d1141b09
--- /dev/null
+++ b/7zip/Common/MultiStream.cpp
@@ -0,0 +1,42 @@
+// MultiStream.cpp
+
+#include "StdAfx.h"
+
+#include "MultiStream.h"
+
+HRESULT CLockedInStream::Read(UINT64 startPos, void *data, UINT32 size,
+ UINT32 *processedSize)
+{
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ RINOK(_stream->Seek(startPos, STREAM_SEEK_SET, NULL));
+ return _stream->Read(data, size, processedSize);
+}
+
+HRESULT CLockedInStream::ReadPart(UINT64 startPos, void *data, UINT32 size,
+ UINT32 *processedSize)
+{
+ NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+ RINOK(_stream->Seek(startPos, STREAM_SEEK_SET, NULL));
+ return _stream->ReadPart(data, size, processedSize);
+}
+
+
+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;
+}
+
+STDMETHODIMP CLockedSequentialInStreamImp::ReadPart(void *data, UINT32 size, UINT32 *processedSize)
+{
+ UINT32 realProcessedSize = 0;
+ HRESULT result = _lockedInStream->ReadPart(_pos, data, size, &realProcessedSize);
+ _pos += realProcessedSize;
+ if (processedSize != NULL)
+ *processedSize = realProcessedSize;
+ return result;
+}
diff --git a/7zip/Common/MultiStream.h b/7zip/Common/MultiStream.h
new file mode 100755
index 00000000..6736a51d
--- /dev/null
+++ b/7zip/Common/MultiStream.h
@@ -0,0 +1,42 @@
+// MultiStream.h
+
+#pragma once
+
+#ifndef __MULTISTREAM_H
+#define __MULTISTREAM_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);
+ HRESULT ReadPart(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);
+ STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize);
+};
+
+#endif
diff --git a/7zip/Common/OffsetStream.cpp b/7zip/Common/OffsetStream.cpp
new file mode 100755
index 00000000..81347e4f
--- /dev/null
+++ b/7zip/Common/OffsetStream.cpp
@@ -0,0 +1,41 @@
+// 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::WritePart(const void *data, UINT32 size, UINT32 *processedSize)
+{
+ return _stream->WritePart(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/7zip/Common/OffsetStream.h b/7zip/Common/OffsetStream.h
new file mode 100755
index 00000000..d98277c2
--- /dev/null
+++ b/7zip/Common/OffsetStream.h
@@ -0,0 +1,28 @@
+// OffsetStream.h
+
+#pragma once
+
+#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(WritePart)(const void *data, UINT32 size, UINT32 *processedSize);
+ STDMETHOD(Seek)(INT64 offset, UINT32 seekOrigin, UINT64 *newPosition);
+ STDMETHOD(SetSize)(INT64 newSize);
+};
+
+#endif
diff --git a/7zip/Common/OutBuffer.cpp b/7zip/Common/OutBuffer.cpp
new file mode 100755
index 00000000..a5fc005d
--- /dev/null
+++ b/7zip/Common/OutBuffer.cpp
@@ -0,0 +1,53 @@
+// Stream/OutByte.cpp
+
+#include "StdAfx.h"
+
+#include "OutBuffer.h"
+
+COutBuffer::COutBuffer(UINT32 bufferSize):
+ _bufferSize(bufferSize)
+{
+ _buffer = new BYTE[_bufferSize];
+}
+
+COutBuffer::~COutBuffer()
+{
+ delete []_buffer;
+}
+
+void COutBuffer::Init(ISequentialOutStream *stream)
+{
+ _stream = stream;
+ _processedSize = 0;
+ _pos = 0;
+}
+
+/*
+void COutBuffer::ReleaseStream()
+{
+ _stream.Release();
+}
+*/
+
+
+HRESULT COutBuffer::Flush()
+{
+ if (_pos == 0)
+ return S_OK;
+ UINT32 processedSize;
+ HRESULT result = _stream->Write(_buffer, _pos, &processedSize);
+ if (result != S_OK)
+ return result;
+ if (_pos != processedSize)
+ return E_FAIL;
+ _processedSize += processedSize;
+ _pos = 0;
+ return S_OK;
+}
+
+void COutBuffer::WriteBlock()
+{
+ HRESULT result = Flush();
+ if (result != S_OK)
+ throw COutBufferException(result);
+}
diff --git a/7zip/Common/OutBuffer.h b/7zip/Common/OutBuffer.h
new file mode 100755
index 00000000..777c5538
--- /dev/null
+++ b/7zip/Common/OutBuffer.h
@@ -0,0 +1,62 @@
+// OutBuffer.h
+
+// #pragma once
+
+#ifndef __OUTBUFFER_H
+#define __OUTBUFFER_H
+
+#include "../IStream.h"
+
+class COutBufferException
+{
+public:
+ HRESULT ErrorCode;
+ COutBufferException(HRESULT errorCode): ErrorCode(errorCode) {}
+};
+
+class COutBuffer
+{
+ BYTE *_buffer;
+ UINT32 _pos;
+ UINT32 _bufferSize;
+ ISequentialOutStream *_stream;
+ UINT64 _processedSize;
+
+ void WriteBlock();
+public:
+ COutBuffer(UINT32 bufferSize = (1 << 20));
+ ~COutBuffer();
+
+ void Init(ISequentialOutStream *stream);
+ HRESULT Flush();
+ // void ReleaseStream();
+
+ void *GetBuffer(UINT32 &sizeAvail)
+ {
+ sizeAvail = _bufferSize - _pos;
+ return _buffer + _pos;
+ }
+ void MovePos(UINT32 num)
+ {
+ _pos += num;
+ if(_pos >= _bufferSize)
+ WriteBlock();
+ }
+
+
+ void WriteByte(BYTE b)
+ {
+ _buffer[_pos++] = b;
+ if(_pos >= _bufferSize)
+ WriteBlock();
+ }
+ void WriteBytes(const void *data, UINT32 size)
+ {
+ for (UINT32 i = 0; i < size; i++)
+ WriteByte(((const BYTE *)data)[i]);
+ }
+
+ UINT64 GetProcessedSize() const { return _processedSize + _pos; }
+};
+
+#endif
diff --git a/7zip/Common/ProgressUtils.cpp b/7zip/Common/ProgressUtils.cpp
new file mode 100755
index 00000000..7e337263
--- /dev/null
+++ b/7zip/Common/ProgressUtils.cpp
@@ -0,0 +1,58 @@
+// 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/7zip/Common/ProgressUtils.h b/7zip/Common/ProgressUtils.h
new file mode 100755
index 00000000..d634d685
--- /dev/null
+++ b/7zip/Common/ProgressUtils.h
@@ -0,0 +1,50 @@
+// ProgressUtils.h
+
+// #pragma once
+
+#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);
+};
+
+
+///////////////////////////////////////////
+// CLocalProgress
+
+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/7zip/Common/StdAfx.h b/7zip/Common/StdAfx.h
new file mode 100755
index 00000000..a32fbed6
--- /dev/null
+++ b/7zip/Common/StdAfx.h
@@ -0,0 +1,8 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#endif
diff --git a/7zip/Common/StreamBinder.cpp b/7zip/Common/StreamBinder.cpp
new file mode 100755
index 00000000..f4050ff1
--- /dev/null
+++ b/7zip/Common/StreamBinder.cpp
@@ -0,0 +1,197 @@
+// 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);
+ STDMETHOD(ReadPart)(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); }
+
+STDMETHODIMP CSequentialInStreamForBinder::ReadPart(void *data, UINT32 size, UINT32 *processedSize)
+ { return m_StreamBinder->ReadPart(data, size, processedSize); }
+
+class CSequentialOutStreamForBinder:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize);
+ STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize);
+
+private:
+ CStreamBinder *m_StreamBinder;
+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); }
+
+STDMETHODIMP CSequentialOutStreamForBinder::WritePart(const void *data, UINT32 size, UINT32 *processedSize)
+ { return m_StreamBinder->WritePart(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;
+}
+
+STDMETHODIMP CStreamBinder::ReadPart(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;
+}
+
+STDMETHODIMP CStreamBinder::Read(void *data, UINT32 size, UINT32 *processedSize)
+{
+ UINT32 fullProcessedSize = 0;
+ UINT32 realProcessedSize;
+ HRESULT result = S_OK;
+ while(size > 0)
+ {
+ result = ReadPart(data, size, &realProcessedSize);
+ size -= realProcessedSize;
+ data = (void *)((BYTE *)data + realProcessedSize);
+ fullProcessedSize += realProcessedSize;
+ if (result != S_OK)
+ break;
+ if (realProcessedSize == 0)
+ break;
+ }
+ if (processedSize != NULL)
+ *processedSize = fullProcessedSize;
+ return result;
+}
+
+void CStreamBinder::CloseRead()
+{
+ _readStreamIsClosedEvent->Set();
+}
+
+STDMETHODIMP CStreamBinder::Write(const void *data, UINT32 size, UINT32 *processedSize)
+{
+ 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;
+}
+
+STDMETHODIMP CStreamBinder::WritePart(const void *data, UINT32 size, UINT32 *processedSize)
+{
+ return Write(data, size, processedSize);
+}
+
+void CStreamBinder::CloseWrite()
+{
+ // _bufferSize must be = 0
+ _thereAreBytesToReadEvent->Set();
+}
+
diff --git a/7zip/Common/StreamBinder.h b/7zip/Common/StreamBinder.h
new file mode 100755
index 00000000..dc656c02
--- /dev/null
+++ b/7zip/Common/StreamBinder.h
@@ -0,0 +1,42 @@
+// StreamBinder.h
+
+#pragma once
+
+#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);
+ STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize);
+ STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize);
+ void CloseRead();
+
+ STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize);
+ STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize);
+ void CloseWrite();
+ void ReInit();
+};
+
+#endif
+
diff --git a/7zip/Common/StreamObjects.cpp b/7zip/Common/StreamObjects.cpp
new file mode 100755
index 00000000..5f696655
--- /dev/null
+++ b/7zip/Common/StreamObjects.cpp
@@ -0,0 +1,146 @@
+// StreamObjects.cpp
+
+#include "StdAfx.h"
+
+#include "StreamObjects.h"
+#include "../../Common/Defs.h"
+
+STDMETHODIMP COutStreamImp::Read(void *data, ULONG size, ULONG *processedSize)
+ { return E_NOTIMPL; }
+
+STDMETHODIMP COutStreamImp::Write(void const *data, ULONG size, ULONG *processedSize)
+{
+ size_t newCapacity = _size + size;
+ _buffer.EnsureCapacity(newCapacity);
+ memmove(_buffer + _size, data, size);
+ if(processedSize != NULL)
+ *processedSize = size;
+ _size += size;
+ return S_OK;
+}
+
+void CInStreamImp::Init(BYTE *dataPointer, UINT32 size)
+{
+ _dataPointer = dataPointer;
+ _size = size;
+ _pos = 0;
+}
+
+STDMETHODIMP CInStreamImp::Read(void *data, ULONG size, ULONG *processedSize)
+{
+ UINT32 numBytesToRead = MyMin(_pos + (UINT32)size, _size) - _pos;
+ if(processedSize != NULL)
+ *processedSize = numBytesToRead;
+ memmove(data, _dataPointer + _pos, numBytesToRead);
+ _pos += numBytesToRead;
+ if(numBytesToRead == size)
+ return S_OK;
+ else
+ return S_FALSE;
+}
+
+STDMETHODIMP CInStreamImp::Write(void const *data, ULONG size, ULONG *processedSize)
+ { return E_NOTIMPL; }
+
+
+
+STDMETHODIMP CSequentialInStreamImp::Read(void *data, UINT32 size, UINT32 *processedSize)
+{
+ UINT32 numBytesToRead = MyMin(_pos + size, _size) - _pos;
+ memmove(data, _dataPointer + _pos, numBytesToRead);
+ _pos += numBytesToRead;
+ if(processedSize != NULL)
+ *processedSize = numBytesToRead;
+ return S_OK;
+}
+
+STDMETHODIMP CSequentialInStreamImp::ReadPart(void *data, UINT32 size, UINT32 *processedSize)
+{
+ return Read(data, size, processedSize);
+}
+
+////////////////////
+
+
+void CWriteBuffer::Write(const void *data, UINT32 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 CSequentialOutStreamImp::WritePart(const void *data, UINT32 size, UINT32 *processedSize)
+{
+ return Write(data, size, processedSize);
+}
+
+STDMETHODIMP CSequentialOutStreamImp2::Write(const void *data, UINT32 size, UINT32 *processedSize)
+{
+ UINT32 newSize = size;
+ if (_pos + size > _size)
+ newSize = _size - _pos;
+ memmove(_buffer + _pos, data, newSize);
+ if(processedSize != NULL)
+ *processedSize = newSize;
+ _pos += newSize;
+ if (newSize != size)
+ return E_FAIL;
+ return S_OK;
+}
+
+STDMETHODIMP CSequentialOutStreamImp2::WritePart(const void *data, UINT32 size, UINT32 *processedSize)
+{
+ return Write(data, size, processedSize);
+}
+
+
+
+STDMETHODIMP CSequentialInStreamSizeCount::Read(void *data, UINT32 size, UINT32 *processedSize)
+{
+ UINT32 realProcessedSize;
+ HRESULT result = _stream->Read(data, size, &realProcessedSize);
+ _size += realProcessedSize;
+ if (processedSize != 0)
+ *processedSize = realProcessedSize;
+ return result;
+}
+
+STDMETHODIMP CSequentialInStreamSizeCount::ReadPart(void *data, UINT32 size, UINT32 *processedSize)
+{
+ UINT32 realProcessedSize;
+ HRESULT result = _stream->ReadPart(data, size, &realProcessedSize);
+ _size += realProcessedSize;
+ if (processedSize != 0)
+ *processedSize = realProcessedSize;
+ return result;
+}
+
+
+STDMETHODIMP 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;
+}
+
+STDMETHODIMP CSequentialOutStreamSizeCount::WritePart(const void *data, UINT32 size, UINT32 *processedSize)
+{
+ UINT32 realProcessedSize;
+ HRESULT result = _stream->WritePart(data, size, &realProcessedSize);
+ _size += realProcessedSize;
+ if (processedSize != 0)
+ *processedSize = realProcessedSize;
+ return result;
+}
diff --git a/7zip/Common/StreamObjects.h b/7zip/Common/StreamObjects.h
new file mode 100755
index 00000000..4c8139f1
--- /dev/null
+++ b/7zip/Common/StreamObjects.h
@@ -0,0 +1,179 @@
+// StreamObjects.h
+
+#pragma once
+
+#ifndef __STREAMOBJECTS_H
+#define __STREAMOBJECTS_H
+
+#include "../../Common/DynamicBuffer.h"
+#include "../../Common/MyCom.h"
+#include "../IStream.h"
+
+class COutStreamImp:
+ public ISequentialStream,
+ public CMyUnknownImp
+{
+ CByteDynamicBuffer _buffer;
+ UINT32 _size;
+public:
+ COutStreamImp(): _size(0) {}
+ void Init(){ _size = 0; }
+ UINT32 GetSize() const { return _size; }
+ const CByteDynamicBuffer& GetBuffer() const { return _buffer; }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHODIMP Read(void *data, ULONG size, ULONG *processedSize);
+ STDMETHODIMP Write(void const *data, ULONG size, ULONG *processedSize);
+};
+
+class CInStreamImp:
+ public ISequentialStream,
+ public CMyUnknownImp
+{
+ BYTE *_dataPointer;
+ UINT32 _size;
+ UINT32 _pos;
+
+public:
+ CInStreamImp(): _size(0xFFFFFFFF), _pos(0), _dataPointer(NULL) {}
+ void Init(BYTE *dataPointer, UINT32 size);
+
+ MY_UNKNOWN_IMP
+
+ STDMETHODIMP Read(void *data, ULONG size, ULONG *processedSize);
+ STDMETHODIMP Write(void const *data, ULONG size, ULONG *processedSize);
+};
+
+class CSequentialInStreamImp:
+ public ISequentialInStream,
+ public CMyUnknownImp
+{
+ const BYTE *_dataPointer;
+ UINT32 _size;
+ UINT32 _pos;
+
+public:
+ void Init(const BYTE *dataPointer, UINT32 size)
+ {
+ _dataPointer = dataPointer;
+ _size = size;
+ _pos = 0;
+ }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize);
+ STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize);
+};
+
+
+class CWriteBuffer
+{
+ CByteDynamicBuffer _buffer;
+ UINT32 _size;
+public:
+ CWriteBuffer(): _size(0) {}
+ // void Init(UINT32 size = 0)
+ void Init()
+ {
+ /*
+ if (size > 0)
+ _buffer.EnsureCapacity(size);
+ */
+ _size = 0;
+ }
+ void Write(const void *data, UINT32 size);
+ UINT32 GetSize() const { return _size; }
+ const CByteDynamicBuffer& GetBuffer() const { return _buffer; }
+};
+
+class CSequentialOutStreamImp:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ CWriteBuffer _writeBuffer;
+public:
+ void Init()
+ {
+ _writeBuffer.Init();
+ }
+
+ /*
+ void Init(UINT32 size = 0)
+ {
+ _writeBuffer.Init(size);
+ }
+ */
+ UINT32 GetSize() const { return _writeBuffer.GetSize(); }
+ const CByteDynamicBuffer& GetBuffer() const { return _writeBuffer.GetBuffer(); }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize);
+ STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize);
+};
+
+class CSequentialOutStreamImp2:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ BYTE *_buffer;
+public:
+ UINT32 _size;
+ UINT32 _pos;
+
+ void Init(BYTE *buffer, UINT32 size)
+ {
+ _buffer = buffer;
+ _pos = 0;
+ _size = size;
+ }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize);
+ STDMETHOD(WritePart)(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);
+ STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize);
+};
+
+class CSequentialOutStreamSizeCount:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ CMyComPtr<ISequentialOutStream> _stream;
+ UINT64 _size;
+public:
+ void Init(ISequentialOutStream *stream)
+ {
+ _stream = stream;
+ _size = 0;
+ }
+ UINT64 GetSize() const { return _size; }
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize);
+ STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize);
+};
+
+#endif
diff --git a/7zip/Compress/Arj/Decoder1.cpp b/7zip/Compress/Arj/Decoder1.cpp
new file mode 100755
index 00000000..b43a408d
--- /dev/null
+++ b/7zip/Compress/Arj/Decoder1.cpp
@@ -0,0 +1,317 @@
+// Arj/Decoder.cpp
+
+#include "StdAfx.h"
+
+#include "Decoder1.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;
+
+CCoder::CCoder()
+{}
+
+void CCoder::make_table(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;
+ make_table(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;
+ make_table(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)
+{
+ 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;
+ }
+
+ if (outSize == NULL)
+ return E_INVALIDARG;
+
+ if (!m_OutWindowStream.IsCreated())
+ {
+ try { m_OutWindowStream.Create(kHistorySize); }
+ catch(...) { return E_OUTOFMEMORY; }
+ }
+ UINT64 pos = 0;
+ m_OutWindowStream.Init(outStream, false);
+ m_InBitStream.Init(inStream);
+ 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.PutOneByte(number);
+ pos++;
+ continue;
+ }
+ else
+ {
+ UINT32 len = number - 256 + kMatchMinLen;
+ UINT32 distance = decode_p();
+ if (distance >= pos)
+ throw "data error";
+ m_OutWindowStream.CopyBackBlock(distance, len);
+ pos += len;
+ }
+ }
+ 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/7zip/Compress/Arj/Decoder1.h b/7zip/Compress/Arj/Decoder1.h
new file mode 100755
index 00000000..6caa18e5
--- /dev/null
+++ b/7zip/Compress/Arj/Decoder1.h
@@ -0,0 +1,110 @@
+// Arj/Decoder1.h
+
+#pragma once
+
+#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 (UCHAR_MAX + 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 CCoder::ReleaseStreams()
+ {
+ m_OutWindowStream.ReleaseStream();
+ m_InBitStream.ReleaseStream();
+ }
+ */
+ class CCoderReleaser
+ {
+ CCoder *m_Coder;
+ public:
+ CCoderReleaser(CCoder *aCoder): m_Coder(aCoder) {}
+ ~CCoderReleaser()
+ {
+ m_Coder->m_OutWindowStream.Flush();
+ // m_Coder->ReleaseStreams();
+ }
+ };
+ friend class CCoderReleaser;
+
+ void make_table(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:
+ CCoder();
+
+ 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/7zip/Compress/Arj/Decoder2.cpp b/7zip/Compress/Arj/Decoder2.cpp
new file mode 100755
index 00000000..87c3b4cb
--- /dev/null
+++ b/7zip/Compress/Arj/Decoder2.cpp
@@ -0,0 +1,95 @@
+// Arj/Decoder2.cpp
+
+#include "StdAfx.h"
+
+#include "Decoder2.h"
+
+#include "Windows/Defs.h"
+
+namespace NCompress{
+namespace NArj {
+namespace NDecoder2 {
+
+static const UINT32 kHistorySize = 26624;
+static const UINT32 kMatchMaxLen = 256;
+static const UINT32 kMatchMinLen = 3;
+
+CCoder::CCoder()
+{}
+
+STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ if (outSize == NULL)
+ return E_INVALIDARG;
+
+ if (!m_OutWindowStream.IsCreated())
+ {
+ try { m_OutWindowStream.Create(kHistorySize); }
+ catch(...) { return E_OUTOFMEMORY; }
+ }
+ UINT64 pos = 0;
+ m_OutWindowStream.Init(outStream, false);
+ m_InBitStream.Init(inStream);
+ 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.PutOneByte(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.CopyBackBlock(distance, len);
+ pos += len;
+ }
+ }
+ 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/7zip/Compress/Arj/Decoder2.h b/7zip/Compress/Arj/Decoder2.h
new file mode 100755
index 00000000..0fa993c6
--- /dev/null
+++ b/7zip/Compress/Arj/Decoder2.h
@@ -0,0 +1,69 @@
+// Arj/Decoder2.h
+
+#pragma once
+
+#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 CCoder::ReleaseStreams()
+ {
+ m_OutWindowStream.ReleaseStream();
+ m_InBitStream.ReleaseStream();
+ }
+ */
+
+ class CCoderReleaser
+ {
+ CCoder *m_Coder;
+ public:
+ CCoderReleaser(CCoder *aCoder): m_Coder(aCoder) {}
+ ~CCoderReleaser()
+ {
+ m_Coder->m_OutWindowStream.Flush();
+ // m_Coder->ReleaseStreams();
+ }
+ };
+ friend class CCoderReleaser;
+
+public:
+ CCoder();
+
+ 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 \ No newline at end of file
diff --git a/7zip/Compress/BZip2/BZip2.def b/7zip/Compress/BZip2/BZip2.def
new file mode 100755
index 00000000..c7169268
--- /dev/null
+++ b/7zip/Compress/BZip2/BZip2.def
@@ -0,0 +1,9 @@
+; BZip2.def
+
+LIBRARY BZip2.dll
+
+EXPORTS
+ CreateObject PRIVATE
+ GetNumberOfMethods PRIVATE
+ GetMethodProperty PRIVATE
+
diff --git a/7zip/Compress/BZip2/BZip2.dsp b/7zip/Compress/BZip2/BZip2.dsp
new file mode 100755
index 00000000..e7d38571
--- /dev/null
+++ b/7zip/Compress/BZip2/BZip2.dsp
@@ -0,0 +1,297 @@
+# 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 "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /D "BZ_NO_STDIO" /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 "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\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=.\BZip2.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\DllExports.cpp
+# 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 "Origianl"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\Original\blocksort.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=.\Original\bzlib.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=.\Original\bzlib.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Original\bzlib_private.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Original\compress.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=.\Original\crctable.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=.\Original\decompress.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=.\Original\huffman.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=.\Original\randtable.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
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# 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=.\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
+# Begin Source File
+
+SOURCE=.\BZip2Error.cpp
+# End Source File
+# End Target
+# End Project
diff --git a/7zip/Compress/BZip2/BZip2.dsw b/7zip/Compress/BZip2/BZip2.dsw
new file mode 100755
index 00000000..697e5095
--- /dev/null
+++ b/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/7zip/Compress/BZip2/BZip2Decoder.cpp b/7zip/Compress/BZip2/BZip2Decoder.cpp
new file mode 100755
index 00000000..86e6480a
--- /dev/null
+++ b/7zip/Compress/BZip2/BZip2Decoder.cpp
@@ -0,0 +1,125 @@
+// BZip2Decoder.cpp
+
+#include "StdAfx.h"
+
+#include "BZip2Decoder.h"
+
+#include "Windows/Defs.h"
+#include "Original/bzlib.h"
+
+namespace NCompress {
+namespace NBZip2 {
+
+static const UINT32 kBufferSize = (1 << 20);
+
+CDecoder::CDecoder()
+{
+ m_InBuffer = new BYTE[kBufferSize];
+ m_OutBuffer = new BYTE[kBufferSize];
+}
+
+CDecoder::~CDecoder()
+{
+ delete []m_OutBuffer;
+ delete []m_InBuffer;
+}
+
+struct CBZip2Decompressor: public bz_stream
+{
+ // bz_stream m_Object;
+public:
+ 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 *aDecompressor): m_Decompressor(aDecompressor) {}
+ 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)
+{
+ 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;
+ while (true)
+ {
+ 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 *)m_OutBuffer;
+ bzStream.avail_out = kBufferSize;
+ result = bzStream.Decompress();
+ UINT32 numBytesToWrite = kBufferSize - bzStream.avail_out;
+ if (numBytesToWrite > 0)
+ {
+ UINT32 processedSize;
+ RINOK(outStream->Write(m_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));
+ }
+ }
+ // result = bzStream.End();
+
+ 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; }
+}
+
+}}
diff --git a/7zip/Compress/BZip2/BZip2Decoder.h b/7zip/Compress/BZip2/BZip2Decoder.h
new file mode 100755
index 00000000..962da55e
--- /dev/null
+++ b/7zip/Compress/BZip2/BZip2Decoder.h
@@ -0,0 +1,41 @@
+// Compress/BZip2/Decoder.h
+
+#pragma once
+
+#ifndef __COMPRESS_BZIP2_DECODER_H
+#define __COMPRESS_BZIP2_DECODER_H
+
+#include "../../ICoder.h"
+// #include "../../Interface/CompressInterface.h"
+#include "Common/MyCom.h"
+
+namespace NCompress {
+namespace NBZip2 {
+
+class CDecoder :
+ public ICompressCoder,
+ public CMyUnknownImp
+{
+ BYTE *m_InBuffer;
+ BYTE *m_OutBuffer;
+public:
+ CDecoder();
+ ~CDecoder();
+
+ MY_UNKNOWN_IMP
+
+ HRESULT Flush();
+ // void (ReleaseStreams)();
+
+ STDMETHOD(CodeReal)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress);
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress);
+};
+
+}}
+
+#endif
diff --git a/7zip/Compress/BZip2/BZip2Encoder.cpp b/7zip/Compress/BZip2/BZip2Encoder.cpp
new file mode 100755
index 00000000..b3525fe7
--- /dev/null
+++ b/7zip/Compress/BZip2/BZip2Encoder.cpp
@@ -0,0 +1,120 @@
+// BZip2Encoder.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/Defs.h"
+#include "BZip2Encoder.h"
+#include "Original/bzlib.h"
+
+namespace NCompress {
+namespace NBZip2 {
+
+static const UINT32 kBufferSize = (1 << 20);
+
+CEncoder::CEncoder()
+{
+ m_InBuffer = new BYTE[kBufferSize];
+ m_OutBuffer = new BYTE[kBufferSize];
+}
+
+CEncoder::~CEncoder()
+{
+ delete []m_OutBuffer;
+ delete []m_InBuffer;
+}
+
+struct CBZip2Compressor: public bz_stream
+{
+public:
+ 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)
+{
+ 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;
+ while (true)
+ {
+ 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 *)m_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(m_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/7zip/Compress/BZip2/BZip2Encoder.h b/7zip/Compress/BZip2/BZip2Encoder.h
new file mode 100755
index 00000000..c3617e3f
--- /dev/null
+++ b/7zip/Compress/BZip2/BZip2Encoder.h
@@ -0,0 +1,36 @@
+// Compress/BZip2/Encoder.h
+
+#pragma once
+
+#ifndef __COMPRESS_BZIP2_ENCODER_H
+#define __COMPRESS_BZIP2_ENCODER_H
+
+#include "Common/MyCom.h"
+#include "../../ICoder.h"
+
+namespace NCompress {
+namespace NBZip2 {
+
+class CEncoder :
+ public ICompressCoder,
+ public CMyUnknownImp
+{
+ BYTE *m_InBuffer;
+ BYTE *m_OutBuffer;
+
+public:
+ CEncoder();
+ ~CEncoder();
+
+ MY_UNKNOWN_IMP
+
+ // STDMETHOD(ReleaseStreams)();
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress);
+};
+
+}}
+
+#endif
diff --git a/7zip/Compress/BZip2/BZip2Error.cpp b/7zip/Compress/BZip2/BZip2Error.cpp
new file mode 100755
index 00000000..c8a912dc
--- /dev/null
+++ b/7zip/Compress/BZip2/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/7zip/Compress/BZip2/DllExports.cpp b/7zip/Compress/BZip2/DllExports.cpp
new file mode 100755
index 00000000..65e47107
--- /dev/null
+++ b/7zip/Compress/BZip2/DllExports.cpp
@@ -0,0 +1,86 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#define INITGUID
+
+#include "BZip2Encoder.h"
+#include "BZip2Decoder.h"
+#include "Common/ComTry.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/7zip/Compress/BZip2/StdAfx.cpp b/7zip/Compress/BZip2/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Compress/BZip2/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Compress/BZip2/StdAfx.h b/7zip/Compress/BZip2/StdAfx.h
new file mode 100755
index 00000000..a32fbed6
--- /dev/null
+++ b/7zip/Compress/BZip2/StdAfx.h
@@ -0,0 +1,8 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#endif
diff --git a/7zip/Compress/BZip2/resource.h b/7zip/Compress/BZip2/resource.h
new file mode 100755
index 00000000..612062a2
--- /dev/null
+++ b/7zip/Compress/BZip2/resource.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Compress/BZip2/resource.rc b/7zip/Compress/BZip2/resource.rc
new file mode 100755
index 00000000..602aa511
--- /dev/null
+++ b/7zip/Compress/BZip2/resource.rc
@@ -0,0 +1,121 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,8,1,0
+ PRODUCTVERSION 3,8,1,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", " \0"
+ VALUE "FileDescription", "BZip2 Coder\0"
+ VALUE "FileVersion", "3, 8, 1, 0\0"
+ VALUE "InternalName", "BZip2\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "BZip2.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 8, 1, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Compress/Branch/ARM.cpp b/7zip/Compress/Branch/ARM.cpp
new file mode 100755
index 00000000..309c355f
--- /dev/null
+++ b/7zip/Compress/Branch/ARM.cpp
@@ -0,0 +1,69 @@
+// ARM.cpp
+
+#include "StdAfx.h"
+#include "ARM.h"
+
+#include "Windows/Defs.h"
+
+static HRESULT BC_ARM_Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress, BYTE *buffer, bool encoding)
+{
+ UINT32 nowPos = 0;
+ UINT64 nowPos64 = 0;
+ UINT32 bufferPos = 0;
+ while(true)
+ {
+ UINT32 processedSize;
+ UINT32 size = kBufferSize - bufferPos;
+ RINOK(inStream->Read(buffer + bufferPos, size, &processedSize));
+ UINT32 endPos = bufferPos + processedSize;
+ if (endPos < 4)
+ {
+ if (endPos > 0)
+ {
+ RINOK(outStream->Write(buffer, endPos, &processedSize));
+ if (endPos != processedSize)
+ return E_FAIL;
+ }
+ return S_OK;
+ }
+ for (bufferPos = 0; bufferPos <= endPos - 4; bufferPos += 4)
+ {
+ if (buffer[bufferPos + 3] == 0xeb)
+ {
+ UINT32 src =
+ (buffer[bufferPos + 2] << 16) |
+ (buffer[bufferPos + 1] << 8) |
+ (buffer[bufferPos + 0]);
+
+ src <<= 2;
+ UINT32 dest;
+ if (encoding)
+ dest = nowPos + bufferPos + 8 + src;
+ else
+ dest = src - (nowPos + bufferPos + 8);
+ dest >>= 2;
+ buffer[bufferPos + 2] = (dest >> 16);
+ buffer[bufferPos + 1] = (dest >> 8);
+ buffer[bufferPos + 0] = dest;
+ }
+ }
+ nowPos += bufferPos;
+ nowPos64 += bufferPos;
+ RINOK(outStream->Write(buffer, bufferPos, &processedSize));
+ if (bufferPos != processedSize)
+ return E_FAIL;
+ if (progress != NULL)
+ {
+ RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
+ }
+
+ UINT32 i = 0;
+ while(bufferPos < endPos)
+ buffer[i++] = buffer[bufferPos++];
+ bufferPos = i;
+ }
+}
+
+MyClassImp(BC_ARM)
diff --git a/7zip/Compress/Branch/ARM.h b/7zip/Compress/Branch/ARM.h
new file mode 100755
index 00000000..cdd3c0dc
--- /dev/null
+++ b/7zip/Compress/Branch/ARM.h
@@ -0,0 +1,12 @@
+// ARM.h
+
+#pragma once
+
+#ifndef __ARM_H
+#define __ARM_H
+
+#include "Coder.h"
+
+MyClass(BC_ARM, 0x05, 1)
+
+#endif
diff --git a/7zip/Compress/Branch/ARMThumb.cpp b/7zip/Compress/Branch/ARMThumb.cpp
new file mode 100755
index 00000000..69605885
--- /dev/null
+++ b/7zip/Compress/Branch/ARMThumb.cpp
@@ -0,0 +1,76 @@
+// ARMThumb.cpp
+
+#include "StdAfx.h"
+#include "ARMThumb.h"
+
+#include "Windows/Defs.h"
+
+static HRESULT BC_ARMThumb_Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress, BYTE *buffer, bool encoding)
+{
+ UINT32 nowPos = 0;
+ UINT64 nowPos64 = 0;
+ UINT32 bufferPos = 0;
+ while(true)
+ {
+ UINT32 processedSize;
+ UINT32 size = kBufferSize - bufferPos;
+ RINOK(inStream->Read(buffer + bufferPos, size, &processedSize));
+ UINT32 endPos = bufferPos + processedSize;
+ if (endPos < 4)
+ {
+ if (endPos > 0)
+ {
+ RINOK(outStream->Write(buffer, endPos, &processedSize));
+ if (endPos != processedSize)
+ return E_FAIL;
+ }
+ return S_OK;
+ }
+ for (bufferPos = 0; bufferPos <= endPos - 4; bufferPos += 2)
+ {
+ if ((buffer[bufferPos + 1] & 0xF8) == 0xF0 &&
+ (buffer[bufferPos + 3] & 0xF8) == 0xF8)
+ {
+ UINT32 src =
+ ((buffer[bufferPos + 1] & 0x7) << 19) |
+ (buffer[bufferPos + 0] << 11) |
+ ((buffer[bufferPos + 3] & 0x7) << 8) |
+ (buffer[bufferPos + 2]);
+
+ src <<= 1;
+ UINT32 dest;
+ if (encoding)
+ dest = nowPos + bufferPos + 4 + src;
+ else
+ dest = src - (nowPos + bufferPos + 4);
+ dest >>= 1;
+
+ buffer[bufferPos + 1] = 0xF0 | ((dest >> 19) & 0x7);
+ buffer[bufferPos + 0] = (dest >> 11);
+ buffer[bufferPos + 3] = 0xF8 | ((dest >> 8) & 0x7);
+ buffer[bufferPos + 2] = (dest);
+ bufferPos += 2;
+ }
+ }
+ nowPos += bufferPos;
+ nowPos64 += bufferPos;
+ RINOK(outStream->Write(buffer, bufferPos, &processedSize));
+ if (bufferPos != processedSize)
+ return E_FAIL;
+ if (progress != NULL)
+ {
+ RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
+ }
+
+ UINT32 i = 0;
+ while(bufferPos < endPos)
+ buffer[i++] = buffer[bufferPos++];
+ bufferPos = i;
+ }
+}
+
+MyClassImp(BC_ARMThumb)
+
+
diff --git a/7zip/Compress/Branch/ARMThumb.h b/7zip/Compress/Branch/ARMThumb.h
new file mode 100755
index 00000000..5e3bf3d5
--- /dev/null
+++ b/7zip/Compress/Branch/ARMThumb.h
@@ -0,0 +1,12 @@
+// ARMThumb.h
+
+#pragma once
+
+#ifndef __ARMTHUMB_H
+#define __ARMTHUMB_H
+
+#include "Coder.h"
+
+MyClass(BC_ARMThumb, 0x07, 1)
+
+#endif
diff --git a/7zip/Compress/Branch/Alpha.cpp b/7zip/Compress/Branch/Alpha.cpp
new file mode 100755
index 00000000..aa70d3a3
--- /dev/null
+++ b/7zip/Compress/Branch/Alpha.cpp
@@ -0,0 +1,75 @@
+// Alpha.cpp
+
+#include "StdAfx.h"
+#include "Alpha.h"
+
+#include "Windows/Defs.h"
+
+static HRESULT BC_Alpha_Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress, BYTE *buffer, bool encoding)
+{
+ UINT32 nowPos = 0;
+ UINT64 nowPos64 = 0;
+ UINT32 bufferPos = 0;
+ while(true)
+ {
+ UINT32 processedSize;
+ UINT32 size = kBufferSize - bufferPos;
+ RINOK(inStream->Read(buffer + bufferPos, size, &processedSize));
+ UINT32 endPos = bufferPos + processedSize;
+ if (endPos < 4)
+ {
+ if (endPos > 0)
+ {
+ RINOK(outStream->Write(buffer, endPos, &processedSize));
+ if (endPos != processedSize)
+ return E_FAIL;
+ }
+ return S_OK;
+ }
+ for (bufferPos = 0; bufferPos <= endPos - 4; bufferPos += 4)
+ {
+ // if (buffer[bufferPos + 3] == 0xc3 && (buffer[bufferPos + 2] >> 5) == 7) // its jump
+ // if (buffer[bufferPos + 3] == 0xd3 && (buffer[bufferPos + 2] >> 5) == 2)
+ // if (buffer[bufferPos + 3] == 0xd3)
+ if ((buffer[bufferPos + 3] >> 2) == 0x34)
+ {
+ UINT32 src =
+ ((buffer[bufferPos + 2] & 0x1F) << 16) |
+ (buffer[bufferPos + 1] << 8) |
+ (buffer[bufferPos + 0]);
+
+ src <<= 2;
+
+ UINT32 dest;
+ if (encoding)
+ dest = (nowPos + bufferPos + 4) + src;
+ else
+ dest = src - (nowPos + bufferPos + 4);
+ dest >>= 2;
+ dest &= 0x1FFFFF;
+ buffer[bufferPos + 2] &= (~0x1F);
+ buffer[bufferPos + 2] |= (dest >> 16);
+ buffer[bufferPos + 1] = (dest >> 8);
+ buffer[bufferPos + 0] = dest;
+ }
+ }
+ nowPos += bufferPos;
+ nowPos64 += bufferPos;
+ RINOK(outStream->Write(buffer, bufferPos, &processedSize));
+ if (bufferPos != processedSize)
+ return E_FAIL;
+ if (progress != NULL)
+ {
+ RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
+ }
+
+ UINT32 i = 0;
+ while(bufferPos < endPos)
+ buffer[i++] = buffer[bufferPos++];
+ bufferPos = i;
+ }
+}
+
+MyClassImp(BC_Alpha)
diff --git a/7zip/Compress/Branch/Alpha.h b/7zip/Compress/Branch/Alpha.h
new file mode 100755
index 00000000..7d4fdab3
--- /dev/null
+++ b/7zip/Compress/Branch/Alpha.h
@@ -0,0 +1,12 @@
+// Alpha.h
+
+#pragma once
+
+#ifndef __ALPHA_H
+#define __ALPHA_H
+
+#include "Coder.h"
+
+MyClass(BC_Alpha, 0x03, 1)
+
+#endif
diff --git a/7zip/Compress/Branch/Branch.def b/7zip/Compress/Branch/Branch.def
new file mode 100755
index 00000000..abc26775
--- /dev/null
+++ b/7zip/Compress/Branch/Branch.def
@@ -0,0 +1,9 @@
+; Branch.def
+
+LIBRARY Branch.dll
+
+EXPORTS
+ CreateObject PRIVATE
+ GetNumberOfMethods PRIVATE
+ GetMethodProperty PRIVATE
+
diff --git a/7zip/Compress/Branch/Branch.dsp b/7zip/Compress/Branch/Branch.dsp
new file mode 100755
index 00000000..c43391e6
--- /dev/null
+++ b/7zip/Compress/Branch/Branch.dsp
@@ -0,0 +1,310 @@
+# 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=.\Branch.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\DllExports.cpp
+# 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 "Methods"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\Alpha.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=.\Alpha.h
+# End Source File
+# 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=.\Coder.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=.\M68.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=.\M68.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=.\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 ""
+# End Group
+# End Target
+# End Project
diff --git a/7zip/Compress/Branch/Branch.dsw b/7zip/Compress/Branch/Branch.dsw
new file mode 100755
index 00000000..841c85a3
--- /dev/null
+++ b/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/7zip/Compress/Branch/Coder.h b/7zip/Compress/Branch/Coder.h
new file mode 100755
index 00000000..3f37c1e4
--- /dev/null
+++ b/7zip/Compress/Branch/Coder.h
@@ -0,0 +1,66 @@
+// Branch/Coder.h
+
+#pragma once
+
+#ifndef __CallPowerPC_CODER_H
+#define __CallPowerPC_CODER_H
+
+#include "Common/MyCom.h"
+#include "Common/Types.h"
+
+#include "../../ICoder.h"
+
+const int kBufferSize = 1 << 17;
+
+class CDataBuffer
+{
+protected:
+ BYTE *_buffer;
+public:
+ CDataBuffer()
+ { _buffer = new BYTE[kBufferSize]; }
+ ~CDataBuffer()
+ { delete []_buffer; }
+};
+
+#define MyClass3(Name) \
+class C ## Name: \
+ public ICompressCoder, \
+ public CDataBuffer, \
+ public CMyUnknownImp \
+ { \
+public: \
+ MY_UNKNOWN_IMP \
+ STDMETHOD(Code)(ISequentialInStream *inStream, \
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, \
+ ICompressProgressInfo *progress); \
+};
+
+// {23170F69-40C1-278B-0303-010100000100}
+#define MyClass2(Name, id, subId, encodingId) \
+DEFINE_GUID(CLSID_CCompressConvert ## Name, \
+0x23170F69, 0x40C1, 0x278B, 0x03, 0x03, id, subId, 0x00, 0x00, encodingId, 0x00); \
+MyClass3(Name) \
+
+
+#define MyClass(Name, id, subId) \
+MyClass2(Name ## _Encoder, id, subId, 0x01) \
+MyClass2(Name ## _Decoder, id, subId, 0x00)
+
+#define MyClassImp(Name) \
+STDMETHODIMP C ## Name ## _Encoder::Code(ISequentialInStream *inStream, \
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, \
+ ICompressProgressInfo *progress) \
+{ \
+ return Name ## _Code(inStream, outStream, inSize, outSize, \
+ progress, _buffer, true); \
+} \
+STDMETHODIMP C ## Name ## _Decoder::Code(ISequentialInStream *inStream, \
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, \
+ ICompressProgressInfo *progress) \
+{ \
+ return Name ## _Code(inStream, outStream, inSize, outSize, \
+ progress, _buffer, false); \
+}
+
+#endif
diff --git a/7zip/Compress/Branch/DllExports.cpp b/7zip/Compress/Branch/DllExports.cpp
new file mode 100755
index 00000000..520a364c
--- /dev/null
+++ b/7zip/Compress/Branch/DllExports.cpp
@@ -0,0 +1,178 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#define INITGUID
+
+#include "Common/ComTry.h"
+
+#include "Coder.h"
+#include "x86.h"
+#include "PPC.h"
+#include "Alpha.h"
+#include "IA64.h"
+#include "ARM.h"
+#include "ARMThumb.h"
+#include "M68.h"
+#include "x86_2.h"
+
+#include "../../ICoder.h"
+
+
+#define MY_CreateClass(n) \
+if (*clsid == CLSID_CCompressConvert ## n ## _Encoder) { \
+ if (!correctInterface) \
+ return E_NOINTERFACE; \
+ coder = (ICompressCoder *)new C ## n ## _Encoder(); \
+ } else if (*clsid == CLSID_CCompressConvert ## n ## _Decoder){ \
+ if (!correctInterface) \
+ return E_NOINTERFACE; \
+ coder = (ICompressCoder *)new C ## n ## _Decoder(); \
+ }
+
+/*
+#define MyOBJECT_ENTRY(Name) \
+ OBJECT_ENTRY(CLSID_CCompressConvert ## Name ## _Encoder, C ## Name ## _Encoder) \
+ OBJECT_ENTRY(CLSID_CCompressConvert ## Name ## _Decoder, C ## Name ## _Decoder) \
+
+
+BEGIN_OBJECT_MAP(ObjectMap)
+ MyOBJECT_ENTRY(BCJ_x86)
+ MyOBJECT_ENTRY(BCJ2_x86)
+ MyOBJECT_ENTRY(BC_PPC_B)
+ MyOBJECT_ENTRY(BC_Alpha)
+ MyOBJECT_ENTRY(BC_IA64)
+ MyOBJECT_ENTRY(BC_ARM)
+ MyOBJECT_ENTRY(BC_ARMThumb)
+ MyOBJECT_ENTRY(BC_M68_B)
+END_OBJECT_MAP()
+*/
+
+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_ICompressCoder);
+ CMyComPtr<ICompressCoder> coder;
+
+ MY_CreateClass(BCJ_x86)
+ else
+ MY_CreateClass(BC_PPC_B)
+ else
+ MY_CreateClass(BC_Alpha)
+ else
+ MY_CreateClass(BC_IA64)
+ else
+ MY_CreateClass(BC_ARM)
+ else
+ MY_CreateClass(BC_ARMThumb)
+ else
+ MY_CreateClass(BC_M68_B)
+ 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 = coder.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)
+};
+
+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/7zip/Compress/Branch/IA64.cpp b/7zip/Compress/Branch/IA64.cpp
new file mode 100755
index 00000000..76614c22
--- /dev/null
+++ b/7zip/Compress/Branch/IA64.cpp
@@ -0,0 +1,103 @@
+// IA64.cpp
+
+#include "StdAfx.h"
+#include "IA64.h"
+
+#include "Windows/Defs.h"
+
+const BYTE kBranchTable[32] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 4, 4, 6, 6, 0, 0, 7, 7,
+ 4, 4, 0, 0, 4, 4, 0, 0
+};
+
+
+static HRESULT BC_IA64_Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress, BYTE *buffer, bool encoding)
+{
+ UINT32 nowPos = 0;
+ UINT64 nowPos64 = 0;
+ UINT32 bufferPos = 0;
+ while(true)
+ {
+ UINT32 processedSize;
+ UINT32 size = kBufferSize - bufferPos;
+ RINOK(inStream->Read(buffer + bufferPos, size, &processedSize));
+ UINT32 endPos = bufferPos + processedSize;
+ if (endPos < 16)
+ {
+ if (endPos > 0)
+ {
+ RINOK(outStream->Write(buffer, endPos, &processedSize));
+ if (endPos != processedSize)
+ return E_FAIL;
+ }
+ return S_OK;
+ }
+ for (bufferPos = 0; bufferPos <= endPos - 16; bufferPos += 16)
+ {
+ UINT32 instrTemplate = buffer[bufferPos] & 0x1F;
+ // ofs << hex << setw(4) << instrTemplate << endl;
+ UINT32 mask = kBranchTable[instrTemplate];
+ UINT32 bitPos = 5;
+ for (int slot = 0; slot < 3; slot++, bitPos += 41)
+ {
+ if (((mask >> slot) & 1) == 0)
+ continue;
+ UINT32 bytePos = (bitPos >> 3);
+ UINT32 bitRes = bitPos & 0x7;
+ UINT64 instruction = *(UINT64 *)(buffer + bufferPos + bytePos);
+ UINT64 instNorm = instruction >> bitRes;
+ if (((instNorm >> 37) & 0xF) == 0x5
+ && ((instNorm >> 9) & 0x7) == 0
+ // && (instNorm & 0x3F)== 0
+ )
+ {
+ UINT32 src = UINT32((instNorm >> 13) & 0xFFFFF);
+ src |= ((instNorm >> 36) & 1) << 20;
+
+ src <<= 4;
+
+ UINT32 dest;
+ if (encoding)
+ dest = nowPos + bufferPos + src;
+ else
+ dest = src - (nowPos + bufferPos);
+
+ dest >>= 4;
+
+ UINT64 instNorm2 = instNorm;
+
+ instNorm &= ~(UINT64(0x8FFFFF) << 13);
+ instNorm |= (UINT64(dest & 0xFFFFF) << 13);
+ instNorm |= (UINT64(dest & 0x100000) << (36 - 20));
+
+ instruction &= (1 << bitRes) - 1;
+ instruction |= (instNorm << bitRes);
+ *(UINT64 *)(buffer + bufferPos + bytePos) = instruction;
+ }
+ }
+ }
+ nowPos += bufferPos;
+ nowPos64 += bufferPos;
+ RINOK(outStream->Write(buffer, bufferPos, &processedSize));
+ if (bufferPos != processedSize)
+ return E_FAIL;
+ if (progress != NULL)
+ {
+ RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
+ }
+
+ UINT32 i = 0;
+ while(bufferPos < endPos)
+ buffer[i++] = buffer[bufferPos++];
+ bufferPos = i;
+ }
+}
+
+MyClassImp(BC_IA64)
+
+
diff --git a/7zip/Compress/Branch/IA64.h b/7zip/Compress/Branch/IA64.h
new file mode 100755
index 00000000..d1840964
--- /dev/null
+++ b/7zip/Compress/Branch/IA64.h
@@ -0,0 +1,14 @@
+// IA64.h
+
+#pragma once
+
+#ifndef __IA64_H
+#define __IA64_H
+
+#include "Coder.h"
+
+MyClass(BC_IA64, 0x04, 1)
+
+// MyClass(IA64_Parse, 0x08, 1)
+
+#endif
diff --git a/7zip/Compress/Branch/M68.cpp b/7zip/Compress/Branch/M68.cpp
new file mode 100755
index 00000000..5340ed1f
--- /dev/null
+++ b/7zip/Compress/Branch/M68.cpp
@@ -0,0 +1,69 @@
+// M68.cpp
+
+#include "StdAfx.h"
+#include "M68.h"
+
+#include "Windows/Defs.h"
+
+static HRESULT BC_M68_B_Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress, BYTE *buffer, bool encoding)
+{
+ UINT32 nowPos = 0;
+ UINT64 nowPos64 = 0;
+ UINT32 bufferPos = 0;
+ while(true)
+ {
+ UINT32 processedSize;
+ UINT32 size = kBufferSize - bufferPos;
+ RINOK(inStream->Read(buffer + bufferPos, size, &processedSize));
+ UINT32 endPos = bufferPos + processedSize;
+ if (endPos < 4)
+ {
+ if (endPos > 0)
+ {
+ RINOK(outStream->Write(buffer, endPos, &processedSize));
+ if (endPos != processedSize)
+ return E_FAIL;
+ }
+ return S_OK;
+ }
+ for (bufferPos = 0; bufferPos <= endPos - 4;)
+ {
+ if (buffer[bufferPos] == 0x61 && buffer[bufferPos + 1] == 0x00)
+ {
+ UINT32 src =
+ (buffer[bufferPos + 2] << 8) |
+ (buffer[bufferPos + 3]);
+
+ UINT32 dest;
+ if (encoding)
+ dest = nowPos + bufferPos + 2 + src;
+ else
+ dest = src - (nowPos + bufferPos + 2);
+ buffer[bufferPos + 2] = (dest >> 8);
+ buffer[bufferPos + 3] = dest;
+ bufferPos += 4;
+ }
+ else
+ bufferPos += 2;
+ }
+ nowPos += bufferPos;
+ nowPos64 += bufferPos;
+ RINOK(outStream->Write(buffer, bufferPos, &processedSize));
+ if (bufferPos != processedSize)
+ return E_FAIL;
+ if (progress != NULL)
+ {
+ RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
+ }
+
+ UINT32 i = 0;
+ while(bufferPos < endPos)
+ buffer[i++] = buffer[bufferPos++];
+ bufferPos = i;
+ }
+}
+
+MyClassImp(BC_M68_B)
+
diff --git a/7zip/Compress/Branch/M68.h b/7zip/Compress/Branch/M68.h
new file mode 100755
index 00000000..0acdede4
--- /dev/null
+++ b/7zip/Compress/Branch/M68.h
@@ -0,0 +1,12 @@
+// M68.h
+
+#pragma once
+
+#ifndef __M68_H
+#define __M68_H
+
+#include "Coder.h"
+
+MyClass(BC_M68_B, 0x06, 5)
+
+#endif
diff --git a/7zip/Compress/Branch/PPC.cpp b/7zip/Compress/Branch/PPC.cpp
new file mode 100755
index 00000000..9ecdc4c3
--- /dev/null
+++ b/7zip/Compress/Branch/PPC.cpp
@@ -0,0 +1,76 @@
+// PPC.cpp
+
+#include "StdAfx.h"
+#include "PPC.h"
+
+#include "Windows/Defs.h"
+
+static HRESULT BC_PPC_B_Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress, BYTE *buffer, bool encoding)
+{
+ UINT32 nowPos = 0;
+ UINT64 nowPos64 = 0;
+ UINT32 bufferPos = 0;
+ while(true)
+ {
+ UINT32 processedSize;
+ UINT32 size = kBufferSize - bufferPos;
+ RINOK(inStream->Read(buffer + bufferPos, size, &processedSize));
+ UINT32 endPos = bufferPos + processedSize;
+ if (endPos < 4)
+ {
+ if (endPos > 0)
+ {
+ RINOK(outStream->Write(buffer, endPos, &processedSize));
+ if (endPos != processedSize)
+ return E_FAIL;
+ }
+ return S_OK;
+ }
+ for (bufferPos = 0; bufferPos <= endPos - 4; bufferPos += 4)
+ {
+ // PowerPC branch 6(48) 24(Offset) 1(Abs) 1(Link)
+ if ((buffer[bufferPos] >> 2) == 0x12 &&
+ (
+ (buffer[bufferPos + 3] & 3) == 1
+ // || (buffer[bufferPos+3] & 3) == 3
+ )
+ )
+ {
+ UINT32 src = ((buffer[bufferPos + 0] & 3) << 24) |
+ (buffer[bufferPos + 1] << 16) |
+ (buffer[bufferPos + 2] << 8) |
+ (buffer[bufferPos + 3] & (~3));
+
+ UINT32 dest;
+ if (encoding)
+ dest = nowPos + bufferPos + src;
+ else
+ dest = src - (nowPos + bufferPos);
+ buffer[bufferPos + 0] = 0x48 | ((dest >> 24) & 0x3);
+ buffer[bufferPos + 1] = (dest >> 16);
+ buffer[bufferPos + 2] = (dest >> 8);
+ buffer[bufferPos + 3] &= 0x3;
+ buffer[bufferPos + 3] |= dest;
+ }
+ }
+ nowPos += bufferPos;
+ nowPos64 += bufferPos;
+ RINOK(outStream->Write(buffer, bufferPos, &processedSize));
+ if (bufferPos != processedSize)
+ return E_FAIL;
+ if (progress != NULL)
+ {
+ RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
+ }
+
+ UINT32 i = 0;
+ while(bufferPos < endPos)
+ buffer[i++] = buffer[bufferPos++];
+ bufferPos = i;
+ }
+}
+
+MyClassImp(BC_PPC_B)
+
diff --git a/7zip/Compress/Branch/PPC.h b/7zip/Compress/Branch/PPC.h
new file mode 100755
index 00000000..aad9d0b8
--- /dev/null
+++ b/7zip/Compress/Branch/PPC.h
@@ -0,0 +1,12 @@
+// PPC.h
+
+#pragma once
+
+#ifndef __PPC_H
+#define __PPC_H
+
+#include "Coder.h"
+
+MyClass(BC_PPC_B, 0x02, 5)
+
+#endif
diff --git a/7zip/Compress/Branch/StdAfx.cpp b/7zip/Compress/Branch/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Compress/Branch/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Compress/Branch/StdAfx.h b/7zip/Compress/Branch/StdAfx.h
new file mode 100755
index 00000000..a32fbed6
--- /dev/null
+++ b/7zip/Compress/Branch/StdAfx.h
@@ -0,0 +1,8 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#endif
diff --git a/7zip/Compress/Branch/resource.h b/7zip/Compress/Branch/resource.h
new file mode 100755
index 00000000..612062a2
--- /dev/null
+++ b/7zip/Compress/Branch/resource.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Compress/Branch/resource.rc b/7zip/Compress/Branch/resource.rc
new file mode 100755
index 00000000..65a91cd3
--- /dev/null
+++ b/7zip/Compress/Branch/resource.rc
@@ -0,0 +1,121 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,9,2,0
+ PRODUCTVERSION 3,9,2,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "Branch converter\0"
+ VALUE "FileVersion", "3, 9, 2, 0\0"
+ VALUE "InternalName", "Branch\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "Branch.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 9, 2, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Compress/Branch/x86.cpp b/7zip/Compress/Branch/x86.cpp
new file mode 100755
index 00000000..3f46a659
--- /dev/null
+++ b/7zip/Compress/Branch/x86.cpp
@@ -0,0 +1,124 @@
+// x86.h
+
+#include "StdAfx.h"
+#include "x86.h"
+
+#include "Windows/Defs.h"
+
+static bool inline Test86MSByte(BYTE b)
+{
+ return (b == 0 || b == 0xFF);
+}
+
+const bool kMaskToAllowedStatus[8] = {true, true, true, false, true, false, false, false};
+const BYTE kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
+
+static HRESULT BCJ_x86_Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress, BYTE *buffer, bool encoding)
+{
+ UINT64 nowPos64 = 0;
+ UINT32 nowPos = 0;
+ UINT32 bufferPos = 0;
+ UINT32 prevMask = 0;
+ UINT32 prevPos = (- 5);
+
+ while(true)
+ {
+ UINT32 processedSize;
+ UINT32 size = kBufferSize - bufferPos;
+ RINOK(inStream->Read(buffer + bufferPos, size, &processedSize));
+ UINT32 endPos = bufferPos + processedSize;
+ if (endPos < 5)
+ {
+ if (endPos > 0)
+ {
+ RINOK(outStream->Write(buffer, endPos, &processedSize));
+ if (endPos != processedSize)
+ return E_FAIL;
+ }
+ return S_OK;
+ }
+ bufferPos = 0;
+ if (nowPos - prevPos > 5)
+ prevPos = nowPos - 5;
+
+ UINT32 limit = endPos - 5;
+ while(bufferPos <= limit)
+ {
+ if (buffer[bufferPos] != 0xE8 && buffer[bufferPos] != 0xE9)
+ {
+ bufferPos++;
+ continue;
+ }
+ UINT32 offset = (nowPos + bufferPos - prevPos);
+ prevPos = (nowPos + bufferPos);
+ if (offset > 5)
+ prevMask = 0;
+ else
+ {
+ for (UINT32 i = 0; i < offset; i++)
+ {
+ prevMask &= 0x77;
+ prevMask <<= 1;
+ }
+ }
+ BYTE &nextByte = buffer[bufferPos + 4];
+ if (Test86MSByte(nextByte) && kMaskToAllowedStatus[(prevMask >> 1) & 0x7] &&
+ (prevMask >> 1) < 0x10)
+ {
+ UINT32 src =
+ (UINT32(nextByte) << 24) |
+ (UINT32(buffer[bufferPos + 3]) << 16) |
+ (UINT32(buffer[bufferPos + 2]) << 8) |
+ (buffer[bufferPos + 1]);
+
+ UINT32 dest;
+ while(true)
+ {
+ if (encoding)
+ dest = (nowPos + bufferPos + 5) + src;
+ else
+ dest = src - (nowPos + bufferPos + 5);
+ if (prevMask == 0)
+ break;
+ UINT32 index = kMaskToBitNumber[prevMask >> 1];
+ if (!Test86MSByte(dest >> (24 - index * 8)))
+ break;
+ src = dest ^ ((1 << (32 - index * 8)) - 1);
+ // src = dest;
+ }
+ nextByte = ~(((dest >> 24) & 1) - 1);
+ buffer[bufferPos + 3] = (dest >> 16);
+ buffer[bufferPos + 2] = (dest >> 8);
+ buffer[bufferPos + 1] = dest;
+ bufferPos += 5;
+ prevMask = 0;
+ }
+ else
+ {
+ bufferPos++;
+ prevMask |= 1;
+ if (Test86MSByte(nextByte))
+ prevMask |= 0x10;
+ }
+ }
+ nowPos += bufferPos;
+ nowPos64 += bufferPos;
+ RINOK(outStream->Write(buffer, bufferPos, &processedSize));
+ if (bufferPos != processedSize)
+ return E_FAIL;
+ if (progress != NULL)
+ {
+ RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
+ }
+
+ UINT32 i = 0;
+ while(bufferPos < endPos)
+ buffer[i++] = buffer[bufferPos++];
+ bufferPos = i;
+ }
+}
+
+
+MyClassImp(BCJ_x86)
diff --git a/7zip/Compress/Branch/x86.h b/7zip/Compress/Branch/x86.h
new file mode 100755
index 00000000..cbe402a6
--- /dev/null
+++ b/7zip/Compress/Branch/x86.h
@@ -0,0 +1,13 @@
+// x86.h
+
+#pragma once
+
+#ifndef __X86_H
+#define __X86_H
+
+#include "Coder.h"
+
+MyClass(BCJ_x86, 0x01, 3)
+// MyClass(x86_J, 0x01, 2)
+
+#endif
diff --git a/7zip/Compress/Branch/x86_2.cpp b/7zip/Compress/Branch/x86_2.cpp
new file mode 100755
index 00000000..88d7f750
--- /dev/null
+++ b/7zip/Compress/Branch/x86_2.cpp
@@ -0,0 +1,331 @@
+// x86_2.cpp
+
+#include "StdAfx.h"
+#include "x86_2.h"
+
+#include "Windows/Defs.h"
+#include "../../ICoder.h"
+
+inline UINT32 Swap4(UINT32 value)
+{
+ return (value << 24) | (value >> 24) |
+ ( (value >> 8) & 0xFF00) | ( (value << 8) & 0xFF0000);
+}
+
+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);
+}
+
+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;
+
+ bool sizeIsDefined = false;
+ UINT64 inSize;
+ if (inSizes != NULL)
+ if (inSizes[0] != NULL)
+ {
+ inSize = *inSizes[0];
+ if (inSize <= kDefaultLimit)
+ sizeIsDefined = true;
+ }
+
+
+ ISequentialInStream *inStream = inStreams[0];
+
+ _mainStream.Init(outStreams[0]);
+ _callStream.Init(outStreams[1]);
+ _jumpStream.Init(outStreams[2]);
+ _rangeEncoder.Init(outStreams[3]);
+ 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;
+ UINT32 processedSize;
+
+ BYTE prevByte = 0;
+
+ UINT64 subStreamIndex = 0;
+ UINT64 subStreamStartPos = 0;
+ UINT64 subStreamEndPos = 0;
+
+ while(true)
+ {
+ UINT32 size = kBufferSize - bufferPos;
+ RINOK(inStream->Read(_buffer + bufferPos, size, &processedSize));
+ 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);
+
+ dest = Swap4(dest);
+
+ bufferPos += 5;
+ if (b == 0xE8)
+ _callStream.WriteBytes(&dest, sizeof(dest));
+ else
+ _jumpStream.WriteBytes(&dest, sizeof(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;
+
+ _mainInStream.Init(inStreams[0]);
+ _callStream.Init(inStreams[1]);
+ _jumpStream.Init(inStreams[2]);
+ _rangeDecoder.Init(inStreams[3]);
+ for (int i = 0; i < 256; i++)
+ _statusE8Decoder[i].Init();
+ _statusE9Decoder.Init();
+ _statusJccDecoder.Init();
+
+ _outStream.Init(outStreams[0]);
+
+ // CCoderReleaser releaser(this);
+
+ BYTE prevByte = 0;
+ UINT32 processedBytes = 0;
+ while(true)
+ {
+ 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)
+ {
+ if (!_callStream.ReadBytes(&src, sizeof(src)))
+ return S_FALSE;
+ }
+ else
+ {
+ if (!_jumpStream.ReadBytes(&src, sizeof(src)))
+ return S_FALSE;
+ }
+ src = Swap4(src);
+ UINT32 dest = src - (UINT32(_outStream.GetProcessedSize()) + 4) ;
+ _outStream.WriteBytes(&dest, sizeof(dest));
+ prevByte = (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/7zip/Compress/Branch/x86_2.h b/7zip/Compress/Branch/x86_2.h
new file mode 100755
index 00000000..6d7aa958
--- /dev/null
+++ b/7zip/Compress/Branch/x86_2.h
@@ -0,0 +1,147 @@
+// x86_2.h
+
+#pragma once
+
+#ifndef __X86_2_H
+#define __X86_2_H
+
+#include "Common/MyCom.h"
+#include "Coder.h"
+#include "../RangeCoder/RangeCoderBit.h"
+// #include "../../Common/InBuffer.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 CDataBuffer,
+ public CMyUnknownImp
+{
+public:
+ CBCJ2_x86_Encoder(): _mainStream(1 << 16) {}
+
+ 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 *aCoder): _coder(aCoder) {}
+ ~CCoderReleaser()
+ {
+ _coder->ReleaseStreams();
+ }
+ };
+ friend class CCoderReleaser;
+ */
+
+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:
+ CBCJ2_x86_Decoder(): _outStream(1 << 16), _mainInStream(1 << 16) {}
+
+ 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 *aCoder): _coder(aCoder) {}
+ ~CCoderReleaser() { _coder->ReleaseStreams(); }
+ };
+ friend class CCoderReleaser;
+ */
+
+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/7zip/Compress/ByteSwap/ByteSwap.cpp b/7zip/Compress/ByteSwap/ByteSwap.cpp
new file mode 100755
index 00000000..2db1a284
--- /dev/null
+++ b/7zip/Compress/ByteSwap/ByteSwap.cpp
@@ -0,0 +1,100 @@
+// Coder.cpp
+
+#include "StdAfx.h"
+
+#include "ByteSwap.h"
+#include "Windows/Defs.h"
+
+const int kBufferSize = 1 << 17;
+
+CBuffer::CBuffer():
+ _buffer(0)
+{
+ _buffer = new BYTE[kBufferSize];
+}
+
+CBuffer::~CBuffer()
+{
+ delete []_buffer;
+}
+
+STDMETHODIMP CByteSwap2::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ const UINT32 kStep = 2;
+ UINT32 bufferPos = 0;
+ UINT64 nowPos64 = 0;
+ while(true)
+ {
+ UINT32 processedSize;
+ UINT32 size = kBufferSize - bufferPos;
+ RINOK(inStream->Read(_buffer + bufferPos, size, &processedSize));
+ if (processedSize == 0)
+ return outStream->Write(_buffer, bufferPos, NULL);
+
+ UINT32 endPos = bufferPos + processedSize;
+ for (UINT32 curPos = 0; curPos + kStep <= endPos; curPos += kStep)
+ {
+ BYTE data[kStep];
+ data[0] = _buffer[curPos + 0];
+ data[1] = _buffer[curPos + 1];
+ _buffer[curPos + 0] = data[1];
+ _buffer[curPos + 1] = data[0];
+ }
+ RINOK(outStream->Write(_buffer, curPos, &processedSize));
+ if (curPos != processedSize)
+ return E_FAIL;
+ nowPos64 += curPos;
+ if (progress != NULL)
+ {
+ RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
+ }
+ bufferPos = 0;
+ while(curPos < endPos)
+ _buffer[bufferPos++] = _buffer[curPos++];
+ }
+}
+
+STDMETHODIMP CByteSwap4::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ const UINT32 kStep = 4;
+ UINT32 bufferPos = 0;
+ UINT64 nowPos64 = 0;
+ while(true)
+ {
+ UINT32 processedSize;
+ UINT32 size = kBufferSize - bufferPos;
+ RINOK(inStream->Read(_buffer + bufferPos, size, &processedSize));
+ if (processedSize == 0)
+ return outStream->Write(_buffer, bufferPos, NULL);
+
+ UINT32 endPos = bufferPos + processedSize;
+ for (UINT32 curPos = 0; curPos + kStep <= endPos; curPos += kStep)
+ {
+ BYTE data[kStep];
+ data[0] = _buffer[curPos + 0];
+ data[1] = _buffer[curPos + 1];
+ data[2] = _buffer[curPos + 2];
+ data[3] = _buffer[curPos + 3];
+ _buffer[curPos + 0] = data[3];
+ _buffer[curPos + 1] = data[2];
+ _buffer[curPos + 2] = data[1];
+ _buffer[curPos + 3] = data[0];
+ }
+ RINOK(outStream->Write(_buffer, curPos, &processedSize));
+ if (curPos != processedSize)
+ return E_FAIL;
+ nowPos64 += curPos;
+ if (progress != NULL)
+ {
+ RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
+ }
+ bufferPos = 0;
+ while(curPos < endPos)
+ _buffer[bufferPos++] = _buffer[curPos++];
+ }
+}
+
diff --git a/7zip/Compress/ByteSwap/ByteSwap.def b/7zip/Compress/ByteSwap/ByteSwap.def
new file mode 100755
index 00000000..3bed0888
--- /dev/null
+++ b/7zip/Compress/ByteSwap/ByteSwap.def
@@ -0,0 +1,9 @@
+; Swap.def
+
+LIBRARY Swap.dll
+
+EXPORTS
+ CreateObject PRIVATE
+ GetNumberOfMethods PRIVATE
+ GetMethodProperty PRIVATE
+
diff --git a/7zip/Compress/ByteSwap/ByteSwap.dsp b/7zip/Compress/ByteSwap/ByteSwap.dsp
new file mode 100755
index 00000000..49f5cc32
--- /dev/null
+++ b/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=.\ByteSwap.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/7zip/Compress/ByteSwap/ByteSwap.dsw b/7zip/Compress/ByteSwap/ByteSwap.dsw
new file mode 100755
index 00000000..413d7e6e
--- /dev/null
+++ b/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/7zip/Compress/ByteSwap/ByteSwap.h b/7zip/Compress/ByteSwap/ByteSwap.h
new file mode 100755
index 00000000..d8eff960
--- /dev/null
+++ b/7zip/Compress/ByteSwap/ByteSwap.h
@@ -0,0 +1,51 @@
+// 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 CBuffer
+{
+protected:
+ BYTE *_buffer;
+public:
+ CBuffer();
+ ~CBuffer();
+};
+
+class CByteSwap2 :
+ public ICompressCoder,
+ public CBuffer,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress);
+};
+
+class CByteSwap4 :
+ public ICompressCoder,
+ public CBuffer,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress);
+};
+
+
+#endif \ No newline at end of file
diff --git a/7zip/Compress/ByteSwap/DllExports.cpp b/7zip/Compress/ByteSwap/DllExports.cpp
new file mode 100755
index 00000000..4ce2a428
--- /dev/null
+++ b/7zip/Compress/ByteSwap/DllExports.cpp
@@ -0,0 +1,92 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#define INITGUID
+
+#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_ICompressCoder);
+ CMyComPtr<ICompressCoder> coder;
+ if (*clsid == CLSID_CCompressConvertByteSwap2)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder = (ICompressCoder *)new CByteSwap2();
+ }
+ else if (*clsid == CLSID_CCompressConvertByteSwap4)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder = (ICompressCoder *)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/7zip/Compress/ByteSwap/StdAfx.cpp b/7zip/Compress/ByteSwap/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Compress/ByteSwap/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Compress/ByteSwap/StdAfx.h b/7zip/Compress/ByteSwap/StdAfx.h
new file mode 100755
index 00000000..a32fbed6
--- /dev/null
+++ b/7zip/Compress/ByteSwap/StdAfx.h
@@ -0,0 +1,8 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#endif
diff --git a/7zip/Compress/ByteSwap/resource.h b/7zip/Compress/ByteSwap/resource.h
new file mode 100755
index 00000000..612062a2
--- /dev/null
+++ b/7zip/Compress/ByteSwap/resource.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Compress/ByteSwap/resource.rc b/7zip/Compress/ByteSwap/resource.rc
new file mode 100755
index 00000000..c7e1c8e1
--- /dev/null
+++ b/7zip/Compress/ByteSwap/resource.rc
@@ -0,0 +1,121 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,9,2,0
+ PRODUCTVERSION 3,9,2,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "Byte Swap converter \0"
+ VALUE "FileVersion", "3, 9, 2, 0\0"
+ VALUE "InternalName", "Swap\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "Swap.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 9, 2, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Compress/Copy/Copy.def b/7zip/Compress/Copy/Copy.def
new file mode 100755
index 00000000..ebf73a3b
--- /dev/null
+++ b/7zip/Compress/Copy/Copy.def
@@ -0,0 +1,4 @@
+EXPORTS
+ CreateObject PRIVATE
+ GetNumberOfMethods PRIVATE
+ GetMethodProperty PRIVATE
diff --git a/7zip/Compress/Copy/Copy.dsp b/7zip/Compress/Copy/Copy.dsp
new file mode 100755
index 00000000..02552719
--- /dev/null
+++ b/7zip/Compress/Copy/Copy.dsp
@@ -0,0 +1,125 @@
+# 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=.\Copy.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=.\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CopyCoder.h
+# End Source File
+# End Target
+# End Project
diff --git a/7zip/Compress/Copy/Copy.dsw b/7zip/Compress/Copy/Copy.dsw
new file mode 100755
index 00000000..53ddf6cf
--- /dev/null
+++ b/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/7zip/Compress/Copy/CopyCoder.cpp b/7zip/Compress/Copy/CopyCoder.cpp
new file mode 100755
index 00000000..23e40a75
--- /dev/null
+++ b/7zip/Compress/Copy/CopyCoder.cpp
@@ -0,0 +1,45 @@
+// Compress/CopyCoder.cpp
+
+#include "StdAfx.h"
+
+#include "CopyCoder.h"
+
+namespace NCompress {
+
+static const UINT32 kBufferSize = 1 << 17;
+
+CCopyCoder::CCopyCoder():
+ TotalSize(0)
+{
+ _buffer = new BYTE[kBufferSize];
+}
+
+CCopyCoder::~CCopyCoder()
+{
+ delete []_buffer;
+}
+
+STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ TotalSize = 0;
+ while(true)
+ {
+ UINT32 realProcessedSize;
+ RINOK(inStream->ReadPart(_buffer, kBufferSize, &realProcessedSize));
+ if(realProcessedSize == 0)
+ break;
+ RINOK(outStream->Write(_buffer, realProcessedSize, NULL));
+ TotalSize += realProcessedSize;
+ if (progress != NULL)
+ {
+ RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize));
+ }
+ }
+ return S_OK;
+}
+
+}
+
diff --git a/7zip/Compress/Copy/CopyCoder.h b/7zip/Compress/Copy/CopyCoder.h
new file mode 100755
index 00000000..02447ad1
--- /dev/null
+++ b/7zip/Compress/Copy/CopyCoder.h
@@ -0,0 +1,34 @@
+// Compress/CopyCoder.h
+
+// #pragma once
+
+#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();
+ ~CCopyCoder();
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress);
+};
+
+}
+
+#endif
diff --git a/7zip/Compress/Copy/DllExports.cpp b/7zip/Compress/Copy/DllExports.cpp
new file mode 100755
index 00000000..47de3fd2
--- /dev/null
+++ b/7zip/Compress/Copy/DllExports.cpp
@@ -0,0 +1,70 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include <initguid.h>
+
+#include "CopyCoder.h"
+#include "../../../Common/ComTry.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/7zip/Compress/Copy/StdAfx.cpp b/7zip/Compress/Copy/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Compress/Copy/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Compress/Copy/StdAfx.h b/7zip/Compress/Copy/StdAfx.h
new file mode 100755
index 00000000..a32fbed6
--- /dev/null
+++ b/7zip/Compress/Copy/StdAfx.h
@@ -0,0 +1,8 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#endif
diff --git a/7zip/Compress/Copy/resource.h b/7zip/Compress/Copy/resource.h
new file mode 100755
index 00000000..612062a2
--- /dev/null
+++ b/7zip/Compress/Copy/resource.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Compress/Copy/resource.rc b/7zip/Compress/Copy/resource.rc
new file mode 100755
index 00000000..d3700ba7
--- /dev/null
+++ b/7zip/Compress/Copy/resource.rc
@@ -0,0 +1,121 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,8,1,0
+ PRODUCTVERSION 3,8,1,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "Copy Coder\0"
+ VALUE "FileVersion", "3, 8, 1, 0\0"
+ VALUE "InternalName", "Copy\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "Copy.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 8, 1, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Compress/Deflate/Deflate.def b/7zip/Compress/Deflate/Deflate.def
new file mode 100755
index 00000000..ac9fd5e5
--- /dev/null
+++ b/7zip/Compress/Deflate/Deflate.def
@@ -0,0 +1,8 @@
+; Deflate.def
+
+LIBRARY Deflate.dll
+
+EXPORTS
+ CreateObject PRIVATE
+ GetNumberOfMethods PRIVATE
+ GetMethodProperty PRIVATE
diff --git a/7zip/Compress/Deflate/Deflate.dsp b/7zip/Compress/Deflate/Deflate.dsp
new file mode 100755
index 00000000..cd7a98f7
--- /dev/null
+++ b/7zip/Compress/Deflate/Deflate.dsp
@@ -0,0 +1,275 @@
+# 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" /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" /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=.\Deflate.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\DllExports.cpp
+# 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 "Huffman"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Huffman\HuffmanDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Huffman\HuffmanEncoder.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=..\Huffman\HuffmanEncoder.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\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\LZInWindow.cpp
+# 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 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
+# Begin Source File
+
+SOURCE=.\DeflateExtConst.h
+# End Source File
+# End Target
+# End Project
diff --git a/7zip/Compress/Deflate/Deflate.dsw b/7zip/Compress/Deflate/Deflate.dsw
new file mode 100755
index 00000000..f17203ed
--- /dev/null
+++ b/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/7zip/Compress/Deflate/DeflateConst.h b/7zip/Compress/Deflate/DeflateConst.h
new file mode 100755
index 00000000..7a19a9a2
--- /dev/null
+++ b/7zip/Compress/Deflate/DeflateConst.h
@@ -0,0 +1,106 @@
+// DeflateConst.h
+
+#pragma once
+
+#ifndef __DEFLATE_CONST_H
+#define __DEFLATE_CONST_H
+
+#include "DeflateExtConst.h"
+
+namespace NCompress {
+namespace NDeflate {
+
+const UINT32 kLenTableSize = 29;
+
+const UINT32 kStaticDistTableSize = 32;
+const UINT32 kStaticLenTableSize = 31;
+
+const UINT32 kReadTableNumber = 0x100;
+const UINT32 kMatchNumber = kReadTableNumber + 1;
+
+const UINT32 kMainTableSize = kMatchNumber + kLenTableSize; //298;
+const UINT32 kStaticMainTableSize = kMatchNumber + kStaticLenTableSize; //298;
+
+const UINT32 kDistTableStart = kMainTableSize;
+
+const UINT32 kHeapTablesSizesSum32 = kMainTableSize + kDistTableSize32;
+const UINT32 kHeapTablesSizesSum64 = kMainTableSize + kDistTableSize64;
+
+const UINT32 kLevelTableSize = 19;
+
+const UINT32 kMaxTableSize32 = kHeapTablesSizesSum32; // test it
+const UINT32 kMaxTableSize64 = kHeapTablesSizesSum64; // test it
+
+const UINT32 kStaticMaxTableSize = kStaticMainTableSize + kStaticDistTableSize;
+
+const UINT32 kTableDirectLevels = 16;
+const UINT32 kTableLevelRepNumber = kTableDirectLevels;
+const UINT32 kTableLevel0Number = kTableLevelRepNumber + 1;
+const UINT32 kTableLevel0Number2 = kTableLevel0Number + 1;
+
+const UINT32 kLevelMask = 0xF;
+
+const BYTE kLenStart32[kLenTableSize] =
+ {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 255};
+const BYTE kLenStart64[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, 0};
+
+const BYTE kLenDirectBits32[kLenTableSize] =
+ {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
+const BYTE kLenDirectBits64[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, 16};
+
+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[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7};
+
+const BYTE kCodeLengthAlphabetOrder[kLevelTableSize] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+const UINT32 kMatchMinLen = 3;
+const UINT32 kMatchMaxLen32 = kNumLenCombinations32 + kMatchMinLen - 1; //256 + 2; test it
+const UINT32 kMatchMaxLen64 = kNumLenCombinations64 + kMatchMinLen - 1; //255 + 2; test it
+
+const int kFinalBlockFieldSize = 1;
+
+namespace NFinalBlockField
+{
+enum
+{
+ kNotFinalBlock = 0,
+ kFinalBlock = 1
+};
+}
+
+const int kBlockTypeFieldSize = 2;
+
+namespace NBlockType
+{
+ enum
+ {
+ kStored = 0,
+ kFixedHuffman = 1,
+ kDynamicHuffman = 2,
+ kReserved = 3
+ };
+}
+
+const UINT32 kDeflateNumberOfLengthCodesFieldSize = 5;
+const UINT32 kDeflateNumberOfDistanceCodesFieldSize = 5;
+const UINT32 kDeflateNumberOfLevelCodesFieldSize = 4;
+
+const UINT32 kDeflateNumberOfLitLenCodesMin = 257;
+
+const UINT32 kDeflateNumberOfDistanceCodesMin = 1;
+const UINT32 kDeflateNumberOfLevelCodesMin = 4;
+
+const UINT32 kDeflateLevelCodeFieldSize = 3;
+
+const UINT32 kDeflateStoredBlockLengthFieldSizeSize = 16;
+
+}}
+
+#endif
diff --git a/7zip/Compress/Deflate/DeflateDecoder.cpp b/7zip/Compress/Deflate/DeflateDecoder.cpp
new file mode 100755
index 00000000..25e638f1
--- /dev/null
+++ b/7zip/Compress/Deflate/DeflateDecoder.cpp
@@ -0,0 +1,291 @@
+// DeflateDecoder.cpp
+
+#include "StdAfx.h"
+
+#include "DeflateDecoder.h"
+#include "DeflateConst.h"
+
+#include "Windows/Defs.h"
+
+namespace NCompress {
+namespace NDeflate {
+namespace NDecoder {
+
+CCoder::CCoder(bool deflate64Mode):
+ m_MainDecoder(kStaticMainTableSize),
+ m_DistDecoder(kStaticDistTableSize),
+ m_LevelDecoder(kLevelTableSize),
+ _deflate64Mode(deflate64Mode)
+{}
+
+void CCoder::DeCodeLevelTable(BYTE *newLevels, int numLevels)
+{
+ int i = 0;
+ while (i < numLevels)
+ {
+ UINT32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
+ if (number < kTableDirectLevels)
+ newLevels[i++] = BYTE(number);
+ else
+ {
+ if (number == kTableLevelRepNumber)
+ {
+ int t = m_InBitStream.ReadBits(2) + 3;
+ for (int reps = t; reps > 0 && i < numLevels ; reps--, i++)
+ newLevels[i] = newLevels[i - 1];
+ }
+ else
+ {
+ int num;
+ if (number == kTableLevel0Number)
+ num = m_InBitStream.ReadBits(3) + 3;
+ else
+ num = m_InBitStream.ReadBits(7) + 11;
+ for (;num > 0 && i < numLevels; num--)
+ newLevels[i++] = 0;
+ }
+ }
+ }
+}
+
+void CCoder::ReadTables(void)
+{
+ if(m_FinalBlock) // test it
+ throw CException(CException::kData);
+
+ m_FinalBlock = (m_InBitStream.ReadBits(kFinalBlockFieldSize) == NFinalBlockField::kFinalBlock);
+
+ int blockType = m_InBitStream.ReadBits(kBlockTypeFieldSize);
+
+ switch(blockType)
+ {
+ case NBlockType::kStored:
+ {
+ m_StoredMode = true;
+ UINT32 currentBitPosition = m_InBitStream.GetBitPosition();
+ UINT32 numBitsForAlign = currentBitPosition > 0 ? (8 - currentBitPosition): 0;
+ if (numBitsForAlign > 0)
+ m_InBitStream.ReadBits(numBitsForAlign);
+ m_StoredBlockSize = m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize);
+ WORD onesComplementReverse = ~WORD(m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize));
+ if (m_StoredBlockSize != onesComplementReverse)
+ throw CException(CException::kData);
+ break;
+ }
+ case NBlockType::kFixedHuffman:
+ case NBlockType::kDynamicHuffman:
+ {
+ m_StoredMode = false;
+ BYTE litLenLevels[kStaticMainTableSize];
+ BYTE distLevels[kStaticDistTableSize];
+ if (blockType == NBlockType::kFixedHuffman)
+ {
+ int i;
+
+ // Leteral / length levels
+ for (i = 0; i < 144; i++)
+ litLenLevels[i] = 8;
+ for (; i < 256; i++)
+ litLenLevels[i] = 9;
+ for (; i < 280; i++)
+ litLenLevels[i] = 7;
+ for (; i < 288; i++) /* make a complete, but wrong code set */
+ litLenLevels[i] = 8;
+
+ // Distance levels
+ for (i = 0; i < kStaticDistTableSize; i++) // test it: infozip only use kDistTableSize
+ distLevels[i] = 5;
+ }
+ else // in case when (blockType == kDeflateBlockTypeFixedHuffman)
+ {
+ int numLitLenLevels = m_InBitStream.ReadBits(kDeflateNumberOfLengthCodesFieldSize) +
+ kDeflateNumberOfLitLenCodesMin;
+ int numDistLevels = m_InBitStream.ReadBits(kDeflateNumberOfDistanceCodesFieldSize) +
+ kDeflateNumberOfDistanceCodesMin;
+ int numLevelCodes = m_InBitStream.ReadBits(kDeflateNumberOfLevelCodesFieldSize) +
+ kDeflateNumberOfLevelCodesMin;
+
+ int numLevels = _deflate64Mode ? kHeapTablesSizesSum64 :
+ kHeapTablesSizesSum32;
+
+ BYTE levelLevels[kLevelTableSize];
+ int i;
+ for (i = 0; i < kLevelTableSize; i++)
+ {
+ int position = kCodeLengthAlphabetOrder[i];
+ if(i < numLevelCodes)
+ levelLevels[position] = BYTE(m_InBitStream.ReadBits(kDeflateLevelCodeFieldSize));
+ else
+ levelLevels[position] = 0;
+ }
+
+ try
+ {
+ m_LevelDecoder.SetCodeLengths(levelLevels);
+ }
+ catch(...)
+ {
+ throw CException(CException::kData);
+ }
+
+ BYTE tmpLevels[kStaticMaxTableSize];
+ DeCodeLevelTable(tmpLevels, numLitLenLevels + numDistLevels);
+
+ memmove(litLenLevels, tmpLevels, numLitLenLevels);
+ memset(litLenLevels + numLitLenLevels, 0,
+ kStaticMainTableSize - numLitLenLevels);
+
+ memmove(distLevels, tmpLevels + numLitLenLevels, numDistLevels);
+ memset(distLevels + numDistLevels, 0, kStaticDistTableSize - numDistLevels);
+ }
+ try
+ {
+ m_MainDecoder.SetCodeLengths(litLenLevels);
+ m_DistDecoder.SetCodeLengths(distLevels);
+ }
+ catch(...)
+ {
+ throw CException(CException::kData);
+ }
+ break;
+ }
+ default:
+ throw CException(CException::kData);
+ }
+}
+
+HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ {
+ try
+ {
+ m_OutWindowStream.Create(_deflate64Mode ? kHistorySize64: kHistorySize32 /* , kMatchMaxLen */);
+ }
+ catch(...)
+ {
+ return E_OUTOFMEMORY;
+ }
+ }
+ UINT64 pos = 0;
+ m_OutWindowStream.Init(outStream, false);
+ m_InBitStream.Init(inStream);
+ // CCoderReleaser coderReleaser(this);
+
+ m_FinalBlock = false;
+
+ while(!m_FinalBlock)
+ {
+ if (progress != NULL)
+ {
+ UINT64 packSize = m_InBitStream.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&packSize, &pos));
+ }
+ ReadTables();
+ if(m_StoredMode)
+ {
+ for (UINT32 i = 0; i < m_StoredBlockSize; i++)
+ m_OutWindowStream.PutOneByte(BYTE(m_InBitStream.ReadBits(8)));
+ pos += m_StoredBlockSize;
+ continue;
+ }
+ while(true)
+ {
+ if (m_InBitStream.NumExtraBytes > 4)
+ throw CException(CException::kData);
+
+ UINT32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
+ if (number < 256)
+ {
+ if (outSize != NULL)
+ if (pos >= *outSize)
+ throw CException(CException::kData);
+ m_OutWindowStream.PutOneByte(BYTE(number));
+ pos++;
+ continue;
+ }
+ else if (number >= kMatchNumber)
+ {
+ if (outSize != NULL)
+ if (pos >= *outSize)
+ throw CException(CException::kData);
+ number -= kMatchNumber;
+
+ UINT32 length;
+ if (_deflate64Mode)
+ {
+ length = UINT32(kLenStart64[number]) + kMatchMinLen;
+ UINT32 numBits = kLenDirectBits64[number];
+ if (numBits > 0)
+ length += m_InBitStream.ReadBits(numBits);
+ }
+ else
+ {
+ length = UINT32(kLenStart32[number]) + kMatchMinLen;
+ UINT32 numBits = kLenDirectBits32[number];
+ if (numBits > 0)
+ length += m_InBitStream.ReadBits(numBits);
+ }
+
+
+ number = m_DistDecoder.DecodeSymbol(&m_InBitStream);
+ UINT32 distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]);
+ if (distance >= pos)
+ throw "data error";
+ m_OutWindowStream.CopyBackBlock(distance, length);
+ pos += length;
+ }
+ else if (number == kReadTableNumber)
+ break;
+ else
+ throw CException(CException::kData);
+ }
+ }
+ return m_OutWindowStream.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 CInBufferException &e) { return e.ErrorCode; }
+ catch(const CLZOutWindowException &e) { return e.ErrorCode; }
+ catch(...) { return S_FALSE; }
+}
+
+HRESULT CCoder::BaseGetInStreamProcessedSize(UINT64 *value)
+{
+ if (value == NULL)
+ return E_INVALIDARG;
+ *value = m_InBitStream.GetProcessedSize();
+ return S_OK;
+}
+
+STDMETHODIMP CCOMCoder::GetInStreamProcessedSize(UINT64 *value)
+{
+ return BaseGetInStreamProcessedSize(value);
+}
+
+HRESULT CCOMCoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ return BaseCode(inStream, outStream, inSize, outSize, progress);
+}
+
+STDMETHODIMP CCOMCoder64::GetInStreamProcessedSize(UINT64 *value)
+{
+ return BaseGetInStreamProcessedSize(value);
+}
+
+HRESULT CCOMCoder64::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ return BaseCode(inStream, outStream, inSize, outSize, progress);
+}
+
+
+}}}
diff --git a/7zip/Compress/Deflate/DeflateDecoder.h b/7zip/Compress/Deflate/DeflateDecoder.h
new file mode 100755
index 00000000..446e2eb9
--- /dev/null
+++ b/7zip/Compress/Deflate/DeflateDecoder.h
@@ -0,0 +1,128 @@
+// DeflateDecoder.h
+
+#pragma once
+
+#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 "DeflateExtConst.h"
+
+namespace NCompress {
+namespace NDeflate {
+namespace NDecoder {
+
+class CException
+{
+public:
+ enum ECauseType
+ {
+ kData
+ } m_Cause;
+ CException(ECauseType aCause): m_Cause(aCause) {}
+};
+
+typedef NStream::NLSBF::CDecoder<CInBuffer> CInBit;
+typedef NCompress::NHuffman::CDecoder<kNumHuffmanBits> CHuffmanDecoder;
+
+class CCoder
+{
+ CLZOutWindow m_OutWindowStream;
+ CInBit m_InBitStream;
+ CHuffmanDecoder m_MainDecoder;
+ CHuffmanDecoder m_DistDecoder;
+ CHuffmanDecoder m_LevelDecoder; // table for decoding other tables;
+
+ bool m_FinalBlock;
+ bool m_StoredMode;
+ UINT32 m_StoredBlockSize;
+
+ bool _deflate64Mode;
+
+ void DeCodeLevelTable(BYTE *newLevels, int numLevels);
+ void ReadTables();
+
+ /*
+ void CCoder::ReleaseStreams()
+ {
+ m_OutWindowStream.ReleaseStream();
+ m_InBitStream.ReleaseStream();
+ }
+ class CCoderReleaser
+ {
+ CCoder *m_Coder;
+ public:
+ CCoderReleaser(CCoder *coder): m_Coder(coder) {}
+ ~CCoderReleaser()
+ {
+ m_Coder->m_OutWindowStream.Flush();
+ m_Coder->ReleaseStreams();
+ }
+ };
+ friend class CCoderReleaser;
+ */
+
+public:
+ CCoder(bool deflate64Mode = false);
+
+ 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);
+
+ // IGetInStreamProcessedSize
+ HRESULT BaseGetInStreamProcessedSize(UINT64 *aValue);
+};
+
+class CCOMCoder :
+ public ICompressCoder,
+ public ICompressGetInStreamProcessedSize,
+ public CMyUnknownImp,
+ public CCoder
+{
+public:
+
+ MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress);
+
+ // IGetInStreamProcessedSize
+ STDMETHOD(GetInStreamProcessedSize)(UINT64 *aValue);
+
+ CCOMCoder(): CCoder(false) {}
+};
+
+class CCOMCoder64 :
+ public ICompressCoder,
+ public ICompressGetInStreamProcessedSize,
+ public CMyUnknownImp,
+ public CCoder
+{
+public:
+ MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress);
+
+ // IGetInStreamProcessedSize
+ STDMETHOD(GetInStreamProcessedSize)(UINT64 *aValue);
+
+ CCOMCoder64(): CCoder(true) {}
+};
+
+}}}
+
+#endif
diff --git a/7zip/Compress/Deflate/DeflateEncoder.cpp b/7zip/Compress/Deflate/DeflateEncoder.cpp
new file mode 100755
index 00000000..07fa3a9f
--- /dev/null
+++ b/7zip/Compress/Deflate/DeflateEncoder.cpp
@@ -0,0 +1,785 @@
+// DeflateEncoder.cpp
+
+#include "StdAfx.h"
+
+#include "DeflateEncoder.h"
+#include "DeflateConst.h"
+
+#include "Windows/Defs.h"
+#include "Common/ComTry.h"
+#include "../LZ/BinTree/BinTree3ZMain.h"
+
+namespace NCompress {
+namespace NDeflate {
+namespace NEncoder {
+
+class CMatchFinderException
+{
+public:
+ HRESULT m_Result;
+ CMatchFinderException(HRESULT result): m_Result (result) {}
+};
+
+static const int kValueBlockSize = 0x2000;
+
+static const int kMaxCodeBitLength = 15;
+static const int kMaxLevelBitLength = 7;
+
+static const BYTE kFlagImm = 0;
+static const BYTE kFlagLenPos = 4;
+
+static const UINT32 kMaxUncompressedBlockSize = 0xFFFF; // test it !!!
+
+static const UINT32 kBlockUncompressedSizeThreshold =
+ kMaxUncompressedBlockSize - kMatchMaxLen32 - kNumOpts;
+
+static const int kNumGoodBacks = 0x10000;
+
+static BYTE kNoLiteralDummy = 13;
+static BYTE kNoLenDummy = 13;
+static BYTE kNoPosDummy = 6;
+
+static BYTE g_LenSlots[kNumLenCombinations32];
+static BYTE g_FastPos[1 << 9];
+
+class CFastPosInit
+{
+public:
+ CFastPosInit()
+ {
+ int i;
+ for(i = 0; i < kLenTableSize; i++)
+ {
+ int c = kLenStart32[i];
+ int j = 1 << kLenDirectBits32[i];
+ for(int k = 0; k < j; k++, c++)
+ g_LenSlots[c] = 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)
+{
+ // for (UINT32 i = 1; pos >= kDistStart[i]; i++);
+ // return i - 1;
+ if (pos < 0x200)
+ return g_FastPos[pos];
+ return g_FastPos[pos >> 8] + 16;
+}
+
+CCoder::CCoder(bool deflate64Mode):
+ _deflate64Mode(deflate64Mode),
+ m_MainCoder(kMainTableSize,
+ deflate64Mode ? kLenDirectBits64 : kLenDirectBits32,
+ kMatchNumber, kMaxCodeBitLength),
+ m_DistCoder(deflate64Mode ? kDistTableSize64 : kDistTableSize32, kDistDirectBits, 0, kMaxCodeBitLength),
+ m_LevelCoder(kLevelTableSize, kLevelDirectBits, 0, kMaxLevelBitLength),
+ m_NumPasses(1),
+ m_NumFastBytes(32),
+ m_OnePosMatchesMemory(0),
+ m_OnePosMatchesArray(0),
+ m_MatchDistances(0),
+ m_Created(false),
+ m_Values(0)
+{
+ m_MatchMaxLen = deflate64Mode ? kMatchMaxLen64 : kMatchMaxLen32;
+ m_NumLenCombinations = deflate64Mode ? kNumLenCombinations64 :
+ kNumLenCombinations32;
+ m_LenStart = deflate64Mode ? kLenStart64 : kLenStart32;
+ m_LenDirectBits = deflate64Mode ? kLenDirectBits64 : kLenDirectBits32;
+
+ m_Values = new CCodeValue[kValueBlockSize + kNumOpts];
+}
+
+HRESULT CCoder::Create()
+{
+ COM_TRY_BEGIN
+ m_MatchFinder.Create(
+ _deflate64Mode ? kHistorySize64 : kHistorySize32,
+ kNumOpts + kNumGoodBacks, m_NumFastBytes,
+ m_MatchMaxLen - m_NumFastBytes);
+ m_MatchLengthEdge = m_NumFastBytes + 1;
+
+ if (m_NumPasses > 1)
+ {
+ m_OnePosMatchesMemory = new UINT16[kNumGoodBacks * (m_NumFastBytes + 1)];
+ try
+ {
+ m_OnePosMatchesArray = new COnePosMatches[kNumGoodBacks];
+ }
+ catch(...)
+ {
+ delete []m_OnePosMatchesMemory;
+ m_OnePosMatchesMemory = 0;
+ throw;
+ }
+ UINT16 *goodBacksWordsCurrent = m_OnePosMatchesMemory;
+ for(int i = 0; i < kNumGoodBacks; i++, goodBacksWordsCurrent += (m_NumFastBytes + 1))
+ m_OnePosMatchesArray[i].Init(goodBacksWordsCurrent);
+ }
+ else
+ m_MatchDistances = new UINT16[m_NumFastBytes + 1];
+ 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 &property = properties[i];
+ switch(propIDs[i])
+ {
+ case NCoderPropID::kNumPasses:
+ if (property.vt != VT_UI4)
+ return E_INVALIDARG;
+ m_NumPasses = property.ulVal;
+ if(m_NumPasses == 0 || m_NumPasses > 255)
+ return E_INVALIDARG;
+ break;
+ case NCoderPropID::kNumFastBytes:
+ if (property.vt != VT_UI4)
+ return E_INVALIDARG;
+ m_NumFastBytes = property.ulVal;
+ if(m_NumFastBytes < 3 || m_NumFastBytes > m_MatchMaxLen)
+ return E_INVALIDARG;
+ break;
+ default:
+ return E_INVALIDARG;
+ }
+ }
+ return S_OK;
+}
+
+void CCoder::Free()
+{
+ if(m_NumPasses > 0)
+ {
+ if (m_NumPasses > 1)
+ {
+ delete []m_OnePosMatchesMemory;
+ delete []m_OnePosMatchesArray;
+ }
+ else
+ delete []m_MatchDistances;
+ }
+}
+
+CCoder::~CCoder()
+{
+ Free();
+ delete []m_Values;
+}
+
+void CCoder::ReadGoodBacks()
+{
+ UINT32 goodIndex;
+ if (m_NumPasses > 1)
+ {
+ goodIndex = m_FinderPos % kNumGoodBacks;
+ m_MatchDistances = m_OnePosMatchesArray[goodIndex].MatchDistances;
+ }
+ UINT32 distanceTmp[kMatchMaxLen32 + 1];
+ UINT32 len = m_MatchFinder.GetLongestMatch(distanceTmp);
+ for(UINT32 i = kMatchMinLen; i <= len; i++)
+ m_MatchDistances[i] = distanceTmp[i];
+
+ m_LongestMatchDistance = m_MatchDistances[len];
+ if (len == m_NumFastBytes && m_NumFastBytes != m_MatchMaxLen)
+ m_LongestMatchLength = len + m_MatchFinder.GetMatchLen(len,
+ m_LongestMatchDistance, m_MatchMaxLen - len);
+ else
+ m_LongestMatchLength = len;
+ if (m_NumPasses > 1)
+ {
+ m_OnePosMatchesArray[goodIndex].LongestMatchDistance = UINT16(m_LongestMatchDistance);
+ m_OnePosMatchesArray[goodIndex].LongestMatchLength = UINT16(m_LongestMatchLength);
+ }
+ HRESULT result = m_MatchFinder.MovePos();
+ if (result != S_OK)
+ throw CMatchFinderException(result);
+ m_FinderPos++;
+ m_AdditionalOffset++;
+}
+
+void CCoder::GetBacks(UINT32 pos)
+{
+ if(pos == m_FinderPos)
+ ReadGoodBacks();
+ else
+ {
+ if (m_NumPasses == 1)
+ {
+ if(pos + 1 == m_FinderPos)
+ return;
+ throw 1932;
+ }
+ else
+ {
+ UINT32 goodIndex = pos % kNumGoodBacks;
+ m_MatchDistances = m_OnePosMatchesArray[goodIndex].MatchDistances;
+ m_LongestMatchDistance = m_OnePosMatchesArray[goodIndex].LongestMatchDistance;
+ m_LongestMatchLength = m_OnePosMatchesArray[goodIndex].LongestMatchLength;
+ }
+ }
+}
+
+
+void CCoder::MovePos(UINT32 num)
+{
+ if (m_NumPasses > 1)
+ {
+ for(UINT32 i = 0; i < num; i++)
+ GetBacks(UINT32(m_BlockStartPostion + m_CurrentBlockUncompressedSize + i + 1));
+ }
+ else
+ {
+ for (;num > 0; num--)
+ {
+ m_MatchFinder.DummyLongestMatch();
+ HRESULT result = m_MatchFinder.MovePos();
+ if (result != S_OK)
+ throw CMatchFinderException(result);
+ m_FinderPos++;
+ m_AdditionalOffset++;
+ }
+ }
+}
+
+static const UINT32 kIfinityPrice = 0xFFFFFFF;
+
+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 = cur;
+ cur = posPrev;
+ }
+ while(cur > 0);
+ backRes = m_Optimum[0].BackPrev;
+ m_OptimumCurrentIndex = m_Optimum[0].PosPrev;
+ return m_OptimumCurrentIndex;
+}
+
+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 = 0;
+ m_OptimumEndIndex = 0;
+
+ GetBacks(UINT32(m_BlockStartPostion + m_CurrentBlockUncompressedSize));
+
+ UINT32 lenMain = m_LongestMatchLength;
+ UINT32 backMain = m_LongestMatchDistance;
+
+ if(lenMain < kMatchMinLen)
+ return 1;
+ if(lenMain >= m_MatchLengthEdge)
+ {
+ backRes = backMain;
+ MovePos(lenMain - 1);
+ return lenMain;
+ }
+ m_Optimum[1].Price = m_LiteralPrices[m_MatchFinder.GetIndexByte(0 - m_AdditionalOffset)];
+ m_Optimum[1].PosPrev = 0;
+
+ m_Optimum[2].Price = kIfinityPrice;
+ m_Optimum[2].PosPrev = 1;
+
+ for(UINT32 i = kMatchMinLen; i <= lenMain; i++)
+ {
+ m_Optimum[i].PosPrev = 0;
+ m_Optimum[i].BackPrev = m_MatchDistances[i];
+ m_Optimum[i].Price = m_LenPrices[i - kMatchMinLen] + m_PosPrices[GetPosSlot(m_MatchDistances[i])];
+ }
+
+
+ UINT32 cur = 0;
+ UINT32 lenEnd = lenMain;
+ while(true)
+ {
+ cur++;
+ if(cur == lenEnd)
+ return Backward(backRes, cur);
+ GetBacks(UINT32(m_BlockStartPostion + m_CurrentBlockUncompressedSize + cur));
+ UINT32 newLen = m_LongestMatchLength;
+ if(newLen >= m_MatchLengthEdge)
+ return Backward(backRes, cur);
+
+ UINT32 curPrice = m_Optimum[cur].Price;
+ UINT32 curAnd1Price = curPrice +
+ m_LiteralPrices[m_MatchFinder.GetIndexByte(cur - m_AdditionalOffset)];
+ COptimal &optimum = m_Optimum[cur + 1];
+ if (curAnd1Price < optimum.Price)
+ {
+ optimum.Price = curAnd1Price;
+ optimum.PosPrev = cur;
+ }
+ if (newLen < kMatchMinLen)
+ continue;
+ if(cur + newLen > lenEnd)
+ {
+ if (cur + newLen > kNumOpts - 1)
+ newLen = kNumOpts - 1 - cur;
+ UINT32 lenEndNew = cur + newLen;
+ if (lenEnd < lenEndNew)
+ {
+ for(UINT32 i = lenEnd + 1; i <= lenEndNew; i++)
+ m_Optimum[i].Price = kIfinityPrice;
+ lenEnd = lenEndNew;
+ }
+ }
+ for(UINT32 lenTest = kMatchMinLen; lenTest <= newLen; lenTest++)
+ {
+ UINT16 curBack = m_MatchDistances[lenTest];
+ UINT32 curAndLenPrice = curPrice +
+ m_LenPrices[lenTest - kMatchMinLen] + m_PosPrices[GetPosSlot(curBack)];
+ COptimal &optimum = m_Optimum[cur + lenTest];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur;
+ optimum.BackPrev = curBack;
+ }
+ }
+ }
+}
+
+
+void CCoder::InitStructures()
+{
+ memset(m_LastLevels, 0, kMaxTableSize64);
+
+ m_ValueIndex = 0;
+ m_OptimumEndIndex = 0;
+ m_OptimumCurrentIndex = 0;
+ m_AdditionalOffset = 0;
+
+ m_BlockStartPostion = 0;
+ m_CurrentBlockUncompressedSize = 0;
+
+ m_MainCoder.StartNewBlock();
+ m_DistCoder.StartNewBlock();
+
+ UINT32 i;
+ for(i = 0; i < 256; i++)
+ m_LiteralPrices[i] = 8;
+ for(i = 0; i < m_NumLenCombinations; i++)
+ m_LenPrices[i] = 5 + m_LenDirectBits[g_LenSlots[i]]; // test it
+ for(i = 0; i < kDistTableSize64; i++)
+ m_PosPrices[i] = 5 + kDistDirectBits[i];
+}
+
+void CCoder::WriteBlockData(bool writeMode, bool finalBlock)
+{
+ m_MainCoder.AddSymbol(kReadTableNumber);
+ int method = WriteTables(writeMode, finalBlock);
+
+ if (writeMode)
+ {
+ if(method == NBlockType::kStored)
+ {
+ for(UINT32 i = 0; i < m_CurrentBlockUncompressedSize; i++)
+ {
+ BYTE b = m_MatchFinder.GetIndexByte(i - m_AdditionalOffset -
+ m_CurrentBlockUncompressedSize);
+ m_OutStream.WriteBits(b, 8);
+ }
+ }
+ else
+ {
+ for (UINT32 i = 0; i < m_ValueIndex; i++)
+ {
+ if (m_Values[i].Flag == kFlagImm)
+ m_MainCoder.CodeOneValue(&m_ReverseOutStream, m_Values[i].Imm);
+ else if (m_Values[i].Flag == kFlagLenPos)
+ {
+ UINT32 len = m_Values[i].Len;
+ UINT32 lenSlot = g_LenSlots[len];
+ m_MainCoder.CodeOneValue(&m_ReverseOutStream, kMatchNumber + lenSlot);
+ m_OutStream.WriteBits(len - m_LenStart[lenSlot], m_LenDirectBits[lenSlot]);
+ UINT32 dist = m_Values[i].Pos;
+ UINT32 posSlot = GetPosSlot(dist);
+ m_DistCoder.CodeOneValue(&m_ReverseOutStream, posSlot);
+ m_OutStream.WriteBits(dist - kDistStart[posSlot], kDistDirectBits[posSlot]);
+ }
+ }
+ m_MainCoder.CodeOneValue(&m_ReverseOutStream, kReadTableNumber);
+ }
+ }
+ m_MainCoder.StartNewBlock();
+ m_DistCoder.StartNewBlock();
+ m_ValueIndex = 0;
+ UINT32 i;
+ for(i = 0; i < 256; i++)
+ if(m_LastLevels[i] != 0)
+ m_LiteralPrices[i] = m_LastLevels[i];
+ else
+ m_LiteralPrices[i] = kNoLiteralDummy;
+
+ // -------------- Normal match -----------------------------
+
+ for(i = 0; i < m_NumLenCombinations; i++)
+ {
+ UINT32 slot = g_LenSlots[i];
+ BYTE dummy = m_LastLevels[kMatchNumber + slot];
+ if (dummy != 0)
+ m_LenPrices[i] = dummy;
+ else
+ m_LenPrices[i] = kNoLenDummy;
+ m_LenPrices[i] += m_LenDirectBits[slot];
+ }
+ for(i = 0; i < kDistTableSize64; i++)
+ {
+ BYTE dummy = m_LastLevels[kDistTableStart + i];
+ if (dummy != 0)
+ m_PosPrices[i] = dummy;
+ else
+ m_PosPrices[i] = kNoPosDummy;
+ m_PosPrices[i] += kDistDirectBits[i];
+ }
+}
+
+void CCoder::CodeLevelTable(BYTE *newLevels, int numLevels, bool codeMode)
+{
+ int prevLen = 0xFF; // last emitted length
+ int nextLen = newLevels[0]; // length of next code
+ int count = 0; // repeat count of the current code
+ int maxCount = 7; // max repeat count
+ int minCount = 4; // min repeat count
+ if (nextLen == 0)
+ {
+ maxCount = 138;
+ minCount = 3;
+ }
+ BYTE oldValueInGuardElement = newLevels[numLevels]; // push guard value
+ try
+ {
+ newLevels[numLevels] = 0xFF; // guard already set
+ for (int n = 0; n < numLevels; n++)
+ {
+ int curLen = nextLen;
+ nextLen = newLevels[n + 1];
+ count++;
+ if (count < maxCount && curLen == nextLen)
+ continue;
+ else if (count < minCount)
+ for(int i = 0; i < count; i++)
+ {
+ int codeLen = curLen;
+ if (codeMode)
+ m_LevelCoder.CodeOneValue(&m_ReverseOutStream, codeLen);
+ else
+ m_LevelCoder.AddSymbol(codeLen);
+ }
+ else if (curLen != 0)
+ {
+ if (curLen != prevLen)
+ {
+ int codeLen = curLen;
+ if (codeMode)
+ m_LevelCoder.CodeOneValue(&m_ReverseOutStream, codeLen);
+ else
+ m_LevelCoder.AddSymbol(codeLen);
+ count--;
+ }
+ if (codeMode)
+ {
+ m_LevelCoder.CodeOneValue(&m_ReverseOutStream, kTableLevelRepNumber);
+ m_OutStream.WriteBits(count - 3, 2);
+ }
+ else
+ m_LevelCoder.AddSymbol(kTableLevelRepNumber);
+ }
+ else if (count <= 10)
+ {
+ if (codeMode)
+ {
+ m_LevelCoder.CodeOneValue(&m_ReverseOutStream, kTableLevel0Number);
+ m_OutStream.WriteBits(count - 3, 3);
+ }
+ else
+ m_LevelCoder.AddSymbol(kTableLevel0Number);
+ }
+ else
+ {
+ if (codeMode)
+ {
+ m_LevelCoder.CodeOneValue(&m_ReverseOutStream, kTableLevel0Number2);
+ m_OutStream.WriteBits(count - 11, 7);
+ }
+ else
+ m_LevelCoder.AddSymbol(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;
+ }
+ }
+ }
+ catch(...)
+ {
+ newLevels[numLevels] = oldValueInGuardElement; // old guard
+ throw;
+ }
+ newLevels[numLevels] = oldValueInGuardElement; // old guard
+}
+
+int CCoder::WriteTables(bool writeMode, bool finalBlock)
+{
+ BYTE newLevels[kMaxTableSize64 + 1]; // (+ 1) for guard
+
+ m_MainCoder.BuildTree(&newLevels[0]);
+ m_DistCoder.BuildTree(&newLevels[kDistTableStart]);
+
+
+ memset(m_LastLevels, 0, kMaxTableSize64);
+
+ if (writeMode)
+ {
+ if(finalBlock)
+ m_OutStream.WriteBits(NFinalBlockField::kFinalBlock, kFinalBlockFieldSize);
+ else
+ m_OutStream.WriteBits(NFinalBlockField::kNotFinalBlock, kFinalBlockFieldSize);
+
+ m_LevelCoder.StartNewBlock();
+
+ int numLitLenLevels = kMainTableSize;
+ while(numLitLenLevels > kDeflateNumberOfLitLenCodesMin && newLevels[numLitLenLevels - 1] == 0)
+ numLitLenLevels--;
+
+ int numDistLevels = _deflate64Mode ? kDistTableSize64 : kDistTableSize32;
+ while(numDistLevels > kDeflateNumberOfDistanceCodesMin &&
+ newLevels[kDistTableStart + numDistLevels - 1] == 0)
+ numDistLevels--;
+
+
+ /////////////////////////
+ // First Pass
+
+ CodeLevelTable(newLevels, numLitLenLevels, false);
+ CodeLevelTable(&newLevels[kDistTableStart], numDistLevels, false);
+
+ memcpy(m_LastLevels, newLevels, kMaxTableSize64);
+
+
+ BYTE levelLevels[kLevelTableSize];
+ m_LevelCoder.BuildTree(levelLevels);
+
+ BYTE levelLevelsStream[kLevelTableSize];
+ int numLevelCodes = kDeflateNumberOfLevelCodesMin;
+ int i;
+ for (i = 0; i < kLevelTableSize; i++)
+ {
+ int streamPos = kCodeLengthAlphabetOrder[i];
+ int level = levelLevels[streamPos];
+ if (level > 0 && i >= numLevelCodes)
+ numLevelCodes = i + 1;
+ levelLevelsStream[i] = level;
+ }
+
+ UINT32 numLZHuffmanBits = m_MainCoder.GetBlockBitLength();
+ numLZHuffmanBits += m_DistCoder.GetBlockBitLength();
+ numLZHuffmanBits += m_LevelCoder.GetBlockBitLength();
+ numLZHuffmanBits += kDeflateNumberOfLengthCodesFieldSize +
+ kDeflateNumberOfDistanceCodesFieldSize +
+ kDeflateNumberOfLevelCodesFieldSize;
+ numLZHuffmanBits += numLevelCodes * kDeflateLevelCodeFieldSize;
+
+ UINT32 nextBitPosition =
+ (m_OutStream.GetBitPosition() + kBlockTypeFieldSize) % 8;
+ UINT32 numBitsForAlign = nextBitPosition > 0 ? (8 - nextBitPosition): 0;
+
+ UINT32 numStoreBits = numBitsForAlign + (2 * sizeof(UINT16)) * 8;
+ numStoreBits += m_CurrentBlockUncompressedSize * 8;
+ if(numStoreBits < numLZHuffmanBits)
+ {
+ m_OutStream.WriteBits(NBlockType::kStored, kBlockTypeFieldSize); // test it
+ m_OutStream.WriteBits(0, numBitsForAlign); // test it
+ UINT16 currentBlockUncompressedSize = UINT16(m_CurrentBlockUncompressedSize);
+ UINT16 currentBlockUncompressedSizeNot = ~currentBlockUncompressedSize;
+ m_OutStream.WriteBits(currentBlockUncompressedSize, kDeflateStoredBlockLengthFieldSizeSize);
+ m_OutStream.WriteBits(currentBlockUncompressedSizeNot, kDeflateStoredBlockLengthFieldSizeSize);
+ return NBlockType::kStored;
+ }
+ else
+ {
+ m_OutStream.WriteBits(NBlockType::kDynamicHuffman, kBlockTypeFieldSize);
+ m_OutStream.WriteBits(numLitLenLevels - kDeflateNumberOfLitLenCodesMin, kDeflateNumberOfLengthCodesFieldSize);
+ m_OutStream.WriteBits(numDistLevels - kDeflateNumberOfDistanceCodesMin,
+ kDeflateNumberOfDistanceCodesFieldSize);
+ m_OutStream.WriteBits(numLevelCodes - kDeflateNumberOfLevelCodesMin,
+ kDeflateNumberOfLevelCodesFieldSize);
+
+ for (i = 0; i < numLevelCodes; i++)
+ m_OutStream.WriteBits(levelLevelsStream[i], kDeflateLevelCodeFieldSize);
+
+ /////////////////////////
+ // Second Pass
+
+ CodeLevelTable(newLevels, numLitLenLevels, true);
+ CodeLevelTable(&newLevels[kDistTableStart], numDistLevels, true);
+ return NBlockType::kDynamicHuffman;
+ }
+ }
+ else
+ memcpy(m_LastLevels, newLevels, kMaxTableSize64);
+ return -1;
+}
+
+HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ if (!m_Created)
+ {
+ RINOK(Create());
+ m_Created = true;
+ }
+
+ UINT64 nowPos = 0;
+ m_FinderPos = 0;
+
+ RINOK(m_MatchFinder.Init(inStream));
+ m_OutStream.Init(outStream);
+ m_ReverseOutStream.Init(&m_OutStream);
+
+ // CCoderReleaser coderReleaser(this);
+ InitStructures();
+
+ while(true)
+ {
+ int currentPassIndex = 0;
+ bool noMoreBytes;
+ while (true)
+ {
+ while(true)
+ {
+ noMoreBytes = (m_AdditionalOffset == 0 && m_MatchFinder.GetNumAvailableBytes() == 0);
+
+ if (((m_CurrentBlockUncompressedSize >= kBlockUncompressedSizeThreshold ||
+ m_ValueIndex >= kValueBlockSize) &&
+ (m_OptimumEndIndex == m_OptimumCurrentIndex))
+ || noMoreBytes)
+ break;
+ UINT32 pos;
+ UINT32 len = GetOptimal(pos);
+ if (len >= kMatchMinLen)
+ {
+ UINT32 newLen = len - kMatchMinLen;
+ m_Values[m_ValueIndex].Flag = kFlagLenPos;
+ m_Values[m_ValueIndex].Len = BYTE(newLen);
+ UINT32 lenSlot = g_LenSlots[newLen];
+ m_MainCoder.AddSymbol(kMatchNumber + lenSlot);
+ m_Values[m_ValueIndex].Pos = UINT16(pos);
+ UINT32 posSlot = GetPosSlot(pos);
+ m_DistCoder.AddSymbol(posSlot);
+ }
+ else if (len == 1)
+ {
+ BYTE b = m_MatchFinder.GetIndexByte(0 - m_AdditionalOffset);
+ len = 1;
+ m_MainCoder.AddSymbol(b);
+ m_Values[m_ValueIndex].Flag = kFlagImm;
+ m_Values[m_ValueIndex].Imm = b;
+ }
+ else
+ throw 12112342;
+ m_ValueIndex++;
+ m_AdditionalOffset -= len;
+ nowPos += len;
+ m_CurrentBlockUncompressedSize += len;
+
+ }
+ currentPassIndex++;
+ bool writeMode = (currentPassIndex == m_NumPasses);
+ WriteBlockData(writeMode, noMoreBytes);
+ if (writeMode)
+ break;
+ nowPos = m_BlockStartPostion;
+ m_AdditionalOffset = UINT32(m_FinderPos - m_BlockStartPostion);
+ m_CurrentBlockUncompressedSize = 0;
+ }
+ m_BlockStartPostion += m_CurrentBlockUncompressedSize;
+ m_CurrentBlockUncompressedSize = 0;
+ if (progress != NULL)
+ {
+ UINT64 packSize = m_OutStream.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&nowPos, &packSize));
+ }
+ if (noMoreBytes)
+ break;
+ }
+ 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(CMatchFinderException &e) { return e.m_Result; }
+ 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/7zip/Compress/Deflate/DeflateEncoder.h b/7zip/Compress/Deflate/DeflateEncoder.h
new file mode 100755
index 00000000..8ee38daf
--- /dev/null
+++ b/7zip/Compress/Deflate/DeflateEncoder.h
@@ -0,0 +1,197 @@
+// DeflateEncoder.h
+
+#pragma once
+
+#ifndef __DEFLATE_ENCODER_H
+#define __DEFLATE_ENCODER_H
+
+#include "Common/MyCom.h"
+
+#include "../../ICoder.h"
+#include "../../Common/LSBFEncoder.h"
+#include "../LZ/BinTree/BinTree3Z.h"
+#include "../Huffman/HuffmanEncoder.h"
+
+#include "DeflateConst.h"
+
+namespace NCompress {
+namespace NDeflate {
+namespace NEncoder {
+
+struct CCodeValue
+{
+ BYTE Flag;
+ union
+ {
+ BYTE Imm;
+ BYTE Len;
+ };
+ UINT16 Pos;
+};
+
+class COnePosMatches
+{
+public:
+ UINT16 *MatchDistances;
+ UINT16 LongestMatchLength;
+ UINT16 LongestMatchDistance;
+ void Init(UINT16 *matchDistances)
+ {
+ MatchDistances = matchDistances;
+ };
+};
+
+struct COptimal
+{
+ UINT32 Price;
+ UINT16 PosPrev;
+ UINT16 BackPrev;
+};
+
+const int kNumOpts = 0x1000;
+
+class CCoder
+{
+ UINT32 m_FinderPos;
+
+ COptimal m_Optimum[kNumOpts];
+
+ // CComPtr<IInWindowStreamMatch> m_MatchFinder;
+ NBT3Z::CInTree m_MatchFinder;
+
+ NStream::NLSBF::CEncoder m_OutStream;
+ NStream::NLSBF::CReverseEncoder m_ReverseOutStream;
+
+ NCompression::NHuffman::CEncoder m_MainCoder;
+ NCompression::NHuffman::CEncoder m_DistCoder;
+ NCompression::NHuffman::CEncoder m_LevelCoder;
+
+ BYTE m_LastLevels[kMaxTableSize64];
+
+ UINT32 m_ValueIndex;
+ CCodeValue *m_Values;
+
+ UINT32 m_OptimumEndIndex;
+ UINT32 m_OptimumCurrentIndex;
+ UINT32 m_AdditionalOffset;
+
+ UINT32 m_LongestMatchLength;
+ UINT32 m_LongestMatchDistance;
+ UINT16 *m_MatchDistances;
+
+ UINT32 m_NumFastBytes;
+ UINT32 m_MatchLengthEdge;
+
+ BYTE m_LiteralPrices[256];
+
+ BYTE m_LenPrices[kNumLenCombinations32];
+ BYTE m_PosPrices[kDistTableSize64];
+
+ UINT32 m_CurrentBlockUncompressedSize;
+
+ COnePosMatches *m_OnePosMatchesArray;
+ UINT16 *m_OnePosMatchesMemory;
+
+ UINT64 m_BlockStartPostion;
+ int m_NumPasses;
+
+ bool m_Created;
+
+ bool _deflate64Mode;
+ UINT32 m_NumLenCombinations;
+ UINT32 m_MatchMaxLen;
+ const BYTE *m_LenStart;
+ const BYTE *m_LenDirectBits;
+
+ HRESULT Create();
+ void Free();
+
+ void GetBacks(UINT32 aPos);
+
+ void ReadGoodBacks();
+ void MovePos(UINT32 num);
+ UINT32 Backward(UINT32 &backRes, UINT32 cur);
+ UINT32 GetOptimal(UINT32 &backRes);
+
+ void InitStructures();
+ void CodeLevelTable(BYTE *newLevels, int numLevels, bool codeMode);
+ int WriteTables(bool writeMode, bool finalBlock);
+ void CopyBackBlockOp(UINT32 distance, UINT32 length);
+ void WriteBlockData(bool writeMode, bool finalBlock);
+
+ /*
+ void CCoder::ReleaseStreams()
+ {
+ m_MatchFinder.ReleaseStream();
+ m_OutStream.ReleaseStream();
+ }
+ class CCoderReleaser
+ {
+ CCoder *m_Coder;
+ public:
+ CCoderReleaser(CCoder *aCoder): m_Coder(aCoder) {}
+ ~CCoderReleaser()
+ {
+ m_Coder->ReleaseStreams();
+ }
+ };
+ friend class CCoderReleaser;
+ */
+
+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/7zip/Compress/Deflate/DeflateExtConst.h b/7zip/Compress/Deflate/DeflateExtConst.h
new file mode 100755
index 00000000..7a58c856
--- /dev/null
+++ b/7zip/Compress/Deflate/DeflateExtConst.h
@@ -0,0 +1,27 @@
+// DeflateExtConst.h
+
+#pragma once
+
+#ifndef __DEFLATE_EXTCONST_H
+#define __DEFLATE_EXTCONST_H
+
+#include "Common/Types.h"
+
+namespace NCompress {
+namespace NDeflate {
+
+ // const UINT32 kDistTableSize = 30;
+ const UINT32 kDistTableSize32 = 30;
+ const UINT32 kDistTableSize64 = 32;
+
+ const UINT32 kHistorySize32 = 0x8000;
+ const UINT32 kHistorySize64 = 0x10000;
+ const UINT32 kNumLenCombinations32 = 256;
+ const UINT32 kNumLenCombinations64 = 255;
+ // don't change kNumLenCombinations64. It must be less than 255.
+
+ const UINT32 kNumHuffmanBits = 15;
+
+}}
+
+#endif
diff --git a/7zip/Compress/Deflate/DllExports.cpp b/7zip/Compress/Deflate/DllExports.cpp
new file mode 100755
index 00000000..9fdd6341
--- /dev/null
+++ b/7zip/Compress/Deflate/DllExports.cpp
@@ -0,0 +1,126 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#define INITGUID
+
+#include "DeflateEncoder.h"
+#include "DeflateDecoder.h"
+#include "Common/ComTry.h"
+
+
+// {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);
+
+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_CCompressDeflateDecoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder = (ICompressCoder *)new NCompress::NDeflate::NDecoder::CCOMCoder();
+ }
+ 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 }
+
+
+static CDeflateMethodItem g_Methods[] =
+{
+ METHOD_ITEM(Deflate, 0x08, L"Deflate"),
+ METHOD_ITEM(Deflate64, 0x09, L"Deflate64")
+};
+
+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 ((value->bstrVal = ::SysAllocStringByteLen(
+ (const char *)method.Encoder, sizeof(GUID))) != 0)
+ value->vt = VT_BSTR;
+ return S_OK;
+ }
+ return S_OK;
+}
diff --git a/7zip/Compress/Deflate/StdAfx.cpp b/7zip/Compress/Deflate/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Compress/Deflate/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Compress/Deflate/StdAfx.h b/7zip/Compress/Deflate/StdAfx.h
new file mode 100755
index 00000000..a32fbed6
--- /dev/null
+++ b/7zip/Compress/Deflate/StdAfx.h
@@ -0,0 +1,8 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#endif
diff --git a/7zip/Compress/Deflate/resource.h b/7zip/Compress/Deflate/resource.h
new file mode 100755
index 00000000..612062a2
--- /dev/null
+++ b/7zip/Compress/Deflate/resource.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Compress/Deflate/resource.rc b/7zip/Compress/Deflate/resource.rc
new file mode 100755
index 00000000..fb37c0ee
--- /dev/null
+++ b/7zip/Compress/Deflate/resource.rc
@@ -0,0 +1,121 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,9,2,0
+ PRODUCTVERSION 3,9,2,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", " \0"
+ VALUE "FileDescription", "Deflate Coder\0"
+ VALUE "FileVersion", "3, 9, 2, 0\0"
+ VALUE "InternalName", "Deflate\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "Deflate.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 9, 2, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Compress/Huffman/HuffmanDecoder.h b/7zip/Compress/Huffman/HuffmanDecoder.h
new file mode 100755
index 00000000..930e5367
--- /dev/null
+++ b/7zip/Compress/Huffman/HuffmanDecoder.h
@@ -0,0 +1,113 @@
+// Compress/HuffmanDecoder.h
+
+#pragma once
+
+#ifndef __COMPRESS_HUFFMANDECODER_H
+#define __COMPRESS_HUFFMANDECODER_H
+
+namespace NCompress {
+namespace NHuffman {
+
+class CDecoderException{};
+
+const UINT32 kValueTableBits = 8;
+
+template <int kNumBitsInLongestCode>
+class CDecoder
+{
+ UINT32 m_Limitits[kNumBitsInLongestCode + 1]; // m_Limitits[i] = value limit for symbols with length = i
+ UINT32 m_Positions[kNumBitsInLongestCode + 1]; // m_Positions[i] = index in m_Symbols[] of first symbol with length = i
+ UINT32 m_NumSymbols;
+ UINT32 *m_Symbols; // symbols: at first with len = 1 then 2, ... 15.
+ BYTE m_Lengths[1 << kValueTableBits];
+public:
+ CDecoder(UINT32 numSymbols):
+ m_NumSymbols(numSymbols)
+ { m_Symbols = new UINT32[m_NumSymbols]; }
+
+ ~CDecoder()
+ { delete []m_Symbols; }
+
+ void SetNumSymbols(UINT32 numSymbols)
+ { m_NumSymbols = numSymbols; }
+ void SetCodeLengths(const BYTE *codeLengths);
+ template <class TBitDecoder>
+ UINT32 DecodeSymbol(TBitDecoder *bitStream)
+ {
+ UINT32 numBits;
+
+ UINT32 value = bitStream->GetValue(kNumBitsInLongestCode);
+
+ if (value < m_Limitits[kValueTableBits])
+ numBits = m_Lengths[value >> (kNumBitsInLongestCode - kValueTableBits)];
+ else if (value < m_Limitits[10])
+ if (value < m_Limitits[9])
+ numBits = 9;
+ else
+ numBits = 10;
+ else if (value < m_Limitits[11])
+ numBits = 11;
+ else if (value < m_Limitits[12])
+ numBits = 12;
+ else
+ for (numBits = 13; numBits < kNumBitsInLongestCode; numBits++)
+ if (value < m_Limitits[numBits])
+ break;
+ bitStream->MovePos(numBits);
+ UINT32 index = m_Positions[numBits] +
+ ((value - m_Limitits[numBits - 1]) >> (kNumBitsInLongestCode - numBits));
+ if (index >= m_NumSymbols)
+ throw CDecoderException(); // test it
+ return m_Symbols[index];
+ }
+};
+
+
+template <int kNumBitsInLongestCode>
+void CDecoder<kNumBitsInLongestCode>::SetCodeLengths(const BYTE *codeLengths)
+{
+ int lenCounts[kNumBitsInLongestCode + 1], tmpPositions[kNumBitsInLongestCode + 1];
+ int i;
+ for(i = 1; i <= kNumBitsInLongestCode; i++)
+ lenCounts[i] = 0;
+ UINT32 symbol;
+ for (symbol = 0; symbol < m_NumSymbols; symbol++)
+ {
+ BYTE codeLength = codeLengths[symbol];
+ if (codeLength > kNumBitsInLongestCode)
+ throw CDecoderException();
+ lenCounts[codeLength]++;
+ }
+ lenCounts[0] = 0;
+ tmpPositions[0] = m_Positions[0] = m_Limitits[0] = 0;
+ UINT32 startPos = 0;
+ UINT32 index = 0;
+ const UINT32 kMaxValue = (1 << kNumBitsInLongestCode);
+ for (i = 1; i <= kNumBitsInLongestCode; i++)
+ {
+ startPos += lenCounts[i] << (kNumBitsInLongestCode - i);
+ if (startPos > kMaxValue)
+ throw CDecoderException();
+ m_Limitits[i] = startPos;
+ m_Positions[i] = m_Positions[i - 1] + lenCounts[i - 1];
+ tmpPositions[i] = m_Positions[i];
+
+ if(i <= kValueTableBits)
+ {
+ UINT32 limit = (m_Limitits[i] >> (kNumBitsInLongestCode - kValueTableBits)); // change it
+ memset(m_Lengths + index, BYTE(i), limit - index);
+ index = limit;
+ }
+ }
+
+ // if (startPos != kMaxValue)
+ // throw CDecoderException();
+
+ for (symbol = 0; symbol < m_NumSymbols; symbol++)
+ if (codeLengths[symbol] != 0)
+ m_Symbols[tmpPositions[codeLengths[symbol]]++] = symbol;
+}
+
+}}
+
+#endif
diff --git a/7zip/Compress/Huffman/HuffmanEncoder.cpp b/7zip/Compress/Huffman/HuffmanEncoder.cpp
new file mode 100755
index 00000000..a9e7e8e0
--- /dev/null
+++ b/7zip/Compress/Huffman/HuffmanEncoder.cpp
@@ -0,0 +1,296 @@
+// Compression/HuffmanEncoder.cpp
+
+#include "StdAfx.h"
+
+#include "HuffmanEncoder.h"
+#include "Common/Defs.h"
+
+namespace NCompression {
+namespace NHuffman {
+
+static const char *kIncorrectBitLenCountsMessage = "Incorrect bit len counts";
+
+CEncoder::CEncoder(UINT32 numSymbols,
+ const BYTE *extraBits, UINT32 extraBase, UINT32 maxLength):
+ m_NumSymbols(numSymbols),
+ m_ExtraBits(extraBits),
+ m_ExtraBase(extraBase),
+ m_MaxLength(maxLength),
+ m_HeapSize(numSymbols * 2+ 1)
+{
+ m_Items = new CItem[m_HeapSize];
+ m_Heap = new UINT32[m_HeapSize];
+ m_Depth = new BYTE[m_HeapSize];
+}
+
+CEncoder::~CEncoder()
+{
+ delete []m_Depth;
+ delete []m_Heap;
+ delete []m_Items;
+}
+
+void CEncoder::StartNewBlock()
+{
+ for (UINT32 i = 0; i < m_NumSymbols; i++)
+ m_Items[i].Freq = 0;
+}
+
+void CEncoder::SetFreqs(const UINT32 *freqs)
+{
+ for (UINT32 i = 0; i < m_NumSymbols; i++)
+ m_Items[i].Freq = freqs[i];
+}
+
+static const int kSmallest = 1;
+
+// ===========================================================================
+// Remove the smallest element from the heap and recreate the heap with
+// one less element. Updates heap and m_HeapLength.
+
+UINT32 CEncoder::RemoveSmallest()
+{
+ UINT32 top = m_Heap[kSmallest];
+ m_Heap[kSmallest] = m_Heap[m_HeapLength--];
+ DownHeap(kSmallest);
+ return top;
+}
+
+// ===========================================================================
+// Compares to subtrees, using the tree m_Depth as tie breaker when
+// the subtrees have equal frequency. This minimizes the worst case length.
+
+bool CEncoder::Smaller(int n, int m)
+{
+ return (m_Items[n].Freq < m_Items[m].Freq ||
+ (m_Items[n].Freq == m_Items[m].Freq && m_Depth[n] <= m_Depth[m]));
+}
+
+// ===========================================================================
+// Restore the m_Heap property by moving down the tree starting at node k,
+// exchanging a node with the smallest of its two sons if necessary, stopping
+// when the m_Heap property is re-established (each father CompareFreqs than its
+// two sons).
+
+void CEncoder::DownHeap(UINT32 k)
+{
+ UINT32 symbol = m_Heap[k];
+ for (UINT32 j = k << 1; j <= m_HeapLength;) // j: left son of k
+ {
+ // Set j to the smallest of the two sons:
+ if (j < m_HeapLength && Smaller(m_Heap[j+1], m_Heap[j]))
+ j++;
+ UINT32 htemp = m_Heap[j]; // htemp required because of bug in SASC compiler
+ if (Smaller(symbol, htemp)) // Exit if v is smaller than both sons
+ break;
+ m_Heap[k] = htemp; // Exchange v with the smallest son
+ k = j;
+ j <<= 1; // And continue down the tree, setting j to the left son of k
+ }
+ m_Heap[k] = symbol;
+}
+
+// ===========================================================================
+// Compute the optimal bit lengths for a tree and update the total bit length
+// for the current block.
+// IN assertion: the fields freq and dad are set, heap[heapMax] and
+// above are the tree nodes sorted by increasing frequency.
+// OUT assertions: the field len is set to the optimal bit length, the
+// array m_BitLenCounters contains the frequencies for each bit length.
+// The length m_BlockBitLength is updated; static_len is also updated if stree is
+// not null.
+
+void CEncoder::GenerateBitLen(UINT32 maxCode, UINT32 heapMax)
+{
+ int overflow = 0; // number of elements with bit length too large
+
+ for (UINT32 i = 0; i <= kNumBitsInLongestCode; i++)
+ m_BitLenCounters[i] = 0;
+
+ /* In a first pass, compute the optimal bit lengths (which may
+ * overflow in the case of the bit length tree).
+ */
+ m_Items[m_Heap[heapMax]].Len = 0; /* root of the heap */
+ UINT32 h; /* heap index */
+ for (h = heapMax+1; h < m_HeapSize; h++)
+ {
+ UINT32 symbol = m_Heap[h];
+ UINT32 len = m_Items[m_Items[symbol].Dad].Len + 1;
+ if (len > m_MaxLength)
+ {
+ len = m_MaxLength;
+ overflow++;
+ }
+ m_Items[symbol].Len = len; // We overwrite m_Items[symbol].Dad which is no longer needed
+ if (symbol > maxCode)
+ continue; // not a leaf node
+ m_BitLenCounters[len]++;
+ UINT32 extraBits;
+ if (m_ExtraBits != 0 && symbol >= m_ExtraBase)
+ extraBits = m_ExtraBits[symbol - m_ExtraBase];
+ else
+ extraBits = 0;
+ m_BlockBitLength += (m_Items[symbol].Freq * (len + extraBits));
+ }
+ if (overflow == 0)
+ return;
+
+ // This happens for example on obj2 and pic of the Calgary corpus
+ // Find the first bit length which could increase:
+ do
+ {
+ UINT32 bits = m_MaxLength-1;
+ while (m_BitLenCounters[bits] == 0)
+ bits--;
+ m_BitLenCounters[bits]--; // move one leaf down the m_Items
+ m_BitLenCounters[bits + 1] += 2; // move one overflow item as its brother
+ m_BitLenCounters[m_MaxLength]--;
+ // The brother of the overflow item also moves one step up,
+ // but this does not affect m_BitLenCounters[m_MaxLength]
+ overflow -= 2;
+ }
+ while (overflow > 0);
+
+ // Now recompute all bit lengths, scanning in increasing frequency.
+ // h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+ // lengths instead of fixing only the wrong ones. This idea is taken
+ // from 'ar' written by Haruhiko Okumura.)
+ for (UINT32 bits = m_MaxLength; bits != 0; bits--)
+ {
+ UINT32 numNodes = m_BitLenCounters[bits];
+ while (numNodes != 0)
+ {
+ UINT32 m = m_Heap[--h];
+ if (m > maxCode)
+ continue;
+ if (m_Items[m].Len != (unsigned) bits)
+ {
+ m_BlockBitLength += ((long)bits - (long)m_Items[m].Len) * (long)m_Items[m].Freq;
+ m_Items[m].Len = bits;
+ }
+ numNodes--;
+ }
+ }
+}
+
+
+// ===========================================================================
+// Generate the codes for a given tree and bit counts (which need not be
+// optimal).
+// IN assertion: the array m_BitLenCounters contains the bit length statistics for
+// the given tree and the field len is set for all tree elements.
+// OUT assertion: the field code is set for all tree elements of non
+// zero code length.
+
+// UINT32 maxCode = largest code with non zero frequency
+
+
+void CEncoder::GenerateCodes(UINT32 maxCode)
+{
+ UINT32 nextCodes[kNumBitsInLongestCode + 1]; // next code value for each bit length
+ UINT32 code = 0; // running code value
+ // The distribution counts are first used to generate the code values
+ // without bit reversal.
+ for (UINT32 bits = 1; bits <= kNumBitsInLongestCode; bits++)
+ nextCodes[bits] = code = (code + m_BitLenCounters[bits - 1]) << 1;
+ // Check that the bit counts in m_BitLenCounters are consistent. The last code
+ // must be all ones.
+ if (code + m_BitLenCounters[kNumBitsInLongestCode] - 1 != (1 << kNumBitsInLongestCode) - 1)
+ throw kIncorrectBitLenCountsMessage;
+ for (UINT32 n = 0; n <= maxCode; n++)
+ {
+ int len = m_Items[n].Len;
+ if (len == 0)
+ continue;
+ m_Items[n].Code = nextCodes[len]++;
+ }
+}
+
+
+// ===========================================================================
+// Construct one Huffman tree and assigns the code bit strings and lengths.
+// Update the total bit length for the current block.
+// IN assertion: the field freq is set for all tree elements.
+// OUT assertions: the fields len and code are set to the optimal bit length
+// and corresponding code. The length m_BlockBitLength is updated; static_len is
+// also updated if stree is not null. The field max_code is set.
+
+void CEncoder::BuildTree(BYTE *levels)
+{
+ m_BlockBitLength = 0;
+ int maxCode = -1; // WAS = -1; largest code with non zero frequency */
+
+ // Construct the initial m_Heap, with least frequent element in
+ // m_Heap[kSmallest]. The sons of m_Heap[n] are m_Heap[2*n] and m_Heap[2*n+1].
+ // m_Heap[0] is not used.
+ //
+
+ m_HeapLength = 0;
+ UINT32 n; // iterate over m_Heap elements
+ for (n = 0; n < m_NumSymbols; n++)
+ {
+ if (m_Items[n].Freq != 0)
+ {
+ m_Heap[++m_HeapLength] = maxCode = n;
+ m_Depth[n] = 0;
+ }
+ else
+ m_Items[n].Len = 0;
+ }
+
+ // The pkzip format requires that at least one distance code exists,
+ // and that at least one bit should be sent even if there is only one
+ // possible code. So to avoid special checks later on we force at least
+ // two codes of non zero frequency.
+ while (m_HeapLength < 2)
+ {
+ int aNewNode = m_Heap[++m_HeapLength] = (maxCode < 2 ? ++maxCode : 0);
+ m_Items[aNewNode].Freq = 1;
+ m_Depth[aNewNode] = 0;
+ m_BlockBitLength--;
+ // if (stree) static_len -= stree[aNewNode].Len;
+ // aNewNode is 0 or 1 so it does not have m_ExtraBits bits
+ }
+
+ // The elements m_Heap[m_HeapLength/2+1 .. m_HeapLength] are leaves of the m_Items,
+ // establish sub-heaps of increasing lengths:
+ for (n = m_HeapLength / 2; n >= 1; n--)
+ DownHeap(n);
+
+ // Construct the Huffman tree by repeatedly combining the least two
+ // frequent nodes.
+ int node = m_NumSymbols; // next internal node of the tree
+ UINT32 heapMax = m_NumSymbols * 2+ 1;
+ do
+ {
+ n = RemoveSmallest(); /* n = node of least frequency */
+ UINT32 m = m_Heap[kSmallest]; /* m = node of next least frequency */
+
+ m_Heap[--heapMax] = n; /* keep the nodes sorted by frequency */
+ m_Heap[--heapMax] = m;
+
+ // Create a new node father of n and m
+ m_Items[node].Freq = m_Items[n].Freq + m_Items[m].Freq;
+ m_Depth[node] = (BYTE) (MyMax(m_Depth[n], m_Depth[m]) + 1);
+ m_Items[n].Dad = m_Items[m].Dad = node;
+ // and insert the new node in the m_Heap
+ m_Heap[kSmallest] = node++;
+ DownHeap(kSmallest);
+
+ }
+ while (m_HeapLength >= 2);
+
+ m_Heap[--heapMax] = m_Heap[kSmallest];
+
+ // At this point, the fields freq and dad are set. We can now
+ // generate the bit lengths.
+ GenerateBitLen(maxCode, heapMax);
+
+ // The field len is now set, we can generate the bit codes
+ GenerateCodes (maxCode);
+
+ for (n = 0; n < m_NumSymbols; n++)
+ levels[n] = BYTE(m_Items[n].Len);
+}
+
+}}
diff --git a/7zip/Compress/Huffman/HuffmanEncoder.h b/7zip/Compress/Huffman/HuffmanEncoder.h
new file mode 100755
index 00000000..1af89be6
--- /dev/null
+++ b/7zip/Compress/Huffman/HuffmanEncoder.h
@@ -0,0 +1,66 @@
+// Compression/HuffmanEncoder.h
+
+#pragma once
+
+#ifndef __COMPRESSION_HUFFMANENCODER_H
+#define __COMPRESSION_HUFFMANENCODER_H
+
+#include "../../../Common/Types.h"
+
+namespace NCompression {
+namespace NHuffman {
+
+const int kNumBitsInLongestCode = 15;
+
+struct CItem
+{
+ UINT32 Freq;
+ UINT32 Code;
+ UINT32 Dad;
+ UINT32 Len;
+};
+
+class CEncoder
+{
+ UINT32 m_NumSymbols; // number of symbols in adwSymbol
+
+ CItem *m_Items;
+ UINT32 *m_Heap;
+ UINT32 m_HeapSize;
+ BYTE *m_Depth;
+ const BYTE *m_ExtraBits;
+ UINT32 m_ExtraBase;
+ UINT32 m_MaxLength;
+
+ UINT32 m_HeapLength;
+ UINT32 m_BitLenCounters[kNumBitsInLongestCode + 1];
+
+ UINT32 RemoveSmallest();
+ bool Smaller(int n, int m);
+ void DownHeap(UINT32 k);
+ void GenerateBitLen(UINT32 maxCode, UINT32 heapMax);
+ void GenerateCodes(UINT32 maxCode);
+
+ UINT32 m_BlockBitLength;
+public:
+
+ CEncoder(UINT32 numSymbols, const BYTE *extraBits,
+ UINT32 extraBase, UINT32 maxLength);
+ ~CEncoder();
+ void StartNewBlock();
+
+ void AddSymbol(UINT32 symbol)
+ { m_Items[symbol].Freq++; }
+
+ void SetFreqs(const UINT32 *freqs);
+ void BuildTree(BYTE *levels);
+ UINT32 GetBlockBitLength() const { return m_BlockBitLength; }
+
+ template <class TBitEncoder>
+ void CodeOneValue(TBitEncoder *bitEncoder, UINT32 symbol)
+ { bitEncoder->WriteBits(m_Items[symbol].Code, m_Items[symbol].Len); }
+};
+
+}}
+
+#endif
diff --git a/7zip/Compress/Huffman/StdAfx.h b/7zip/Compress/Huffman/StdAfx.h
new file mode 100755
index 00000000..2b5a157a
--- /dev/null
+++ b/7zip/Compress/Huffman/StdAfx.h
@@ -0,0 +1,6 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#endif
diff --git a/7zip/Compress/Implode/DllExports.cpp b/7zip/Compress/Implode/DllExports.cpp
new file mode 100755
index 00000000..3f817a09
--- /dev/null
+++ b/7zip/Compress/Implode/DllExports.cpp
@@ -0,0 +1,66 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#define INITGUID
+
+#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/7zip/Compress/Implode/Implode.def b/7zip/Compress/Implode/Implode.def
new file mode 100755
index 00000000..5364eb65
--- /dev/null
+++ b/7zip/Compress/Implode/Implode.def
@@ -0,0 +1,9 @@
+; Implode.def
+
+LIBRARY Implode.dll
+
+EXPORTS
+ CreateObject PRIVATE
+ GetNumberOfMethods PRIVATE
+ GetMethodProperty PRIVATE
+
diff --git a/7zip/Compress/Implode/Implode.dsp b/7zip/Compress/Implode/Implode.dsp
new file mode 100755
index 00000000..832d3c88
--- /dev/null
+++ b/7zip/Compress/Implode/Implode.dsp
@@ -0,0 +1,181 @@
+# Microsoft Developer Studio Project File - Name="Implode" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=Implode - 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 "Implode.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 "Implode.mak" CFG="Implode - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Implode - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Implode - 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)" == "Implode - 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 "IMPLODE_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IMPLODE_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\Implode.dll" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "Implode - 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 "IMPLODE_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 "IMPLODE_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\Implode.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "Implode - Win32 Release"
+# Name "Implode - Win32 Debug"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\DllExports.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Implode.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 "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
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.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 Source File
+
+SOURCE=.\ImplodeDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ImplodeDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ImplodeHuffmanDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ImplodeHuffmanDecoder.h
+# End Source File
+# End Target
+# End Project
diff --git a/7zip/Compress/Implode/Implode.dsw b/7zip/Compress/Implode/Implode.dsw
new file mode 100755
index 00000000..d3dd6c44
--- /dev/null
+++ b/7zip/Compress/Implode/Implode.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Implode"=.\Implode.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/7zip/Compress/Implode/ImplodeDecoder.cpp b/7zip/Compress/Implode/ImplodeDecoder.cpp
new file mode 100755
index 00000000..fccd1dd9
--- /dev/null
+++ b/7zip/Compress/Implode/ImplodeDecoder.cpp
@@ -0,0 +1,210 @@
+// Implode/Decoder.cpp
+
+#include "StdAfx.h"
+
+#include "ImplodeDecoder.h"
+#include "Common/Defs.h"
+
+#include "Windows/Defs.h"
+
+namespace NCompress {
+namespace NImplode {
+namespace NDecoder {
+
+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)
+{
+ m_OutWindowStream.Create(kHistorySize/*, kMatchMaxLenMax*/);
+}
+
+/*
+STDMETHODIMP CCoder::ReleaseStreams()
+{
+ m_OutWindowStream.ReleaseStream();
+ m_InBitStream.ReleaseStream();
+ return S_OK;
+}
+*/
+
+void 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++] = level;
+ }
+ if (currentIndex != numLevelItems)
+ throw CException(CException::kData);
+ try
+ {
+ decoder.SetCodeLengths(levels);
+ }
+ catch(const NImplode::NHuffman::CDecoderException &)
+ {
+ throw CException(CException::kData);
+ }
+}
+
+
+void CCoder::ReadTables(void)
+{
+ if (m_LiteralsOn)
+ {
+ BYTE literalLevels[kLiteralTableSize];
+ ReadLevelItems(m_LiteralDecoder, literalLevels, kLiteralTableSize);
+ }
+
+ BYTE lengthLevels[kLengthTableSize];
+ ReadLevelItems(m_LengthDecoder, lengthLevels, kLengthTableSize);
+
+ BYTE distanceLevels[kDistanceTableSize];
+ 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 (outSize == NULL)
+ return E_INVALIDARG;
+ UINT64 pos = 0, unPackSize = *outSize;
+
+ m_OutWindowStream.Init(outStream, false);
+ m_InBitStream.Init(inStream);
+ // CCoderReleaser coderReleaser(this);
+
+ ReadTables();
+
+ 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) <<
+ m_NumDistanceLowDirectBits) + lowDistBits;
+
+ UINT32 lengthSymbol = m_LengthDecoder.DecodeSymbol(&m_InBitStream);
+ UINT32 length = lengthSymbol + m_MinMatchLength;
+ if (lengthSymbol == kLengthTableSize - 1) // special symbol = 63
+ length += m_InBitStream.ReadBits(kNumAdditionalLengthBits);
+ while(distance >= pos && length > 0)
+ {
+ m_OutWindowStream.PutOneByte(0);
+ pos++;
+ length--;
+ }
+ if (length > 0)
+ m_OutWindowStream.CopyBackBlock(distance, length);
+ pos += length;
+ }
+ else
+ {
+ BYTE b = BYTE(m_LiteralsOn ? m_LiteralDecoder.DecodeSymbol(&m_InBitStream) :
+ m_InBitStream.ReadBits(kNumBitsInByte));
+ m_OutWindowStream.PutOneByte(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::SetDecoderProperties(ISequentialInStream *inStream)
+{
+ BYTE flag;
+ UINT32 processedSize;
+ RINOK(inStream->Read(&flag, sizeof(flag), &processedSize));
+ if (processedSize != sizeof(flag))
+ return E_INVALIDARG;
+ 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/7zip/Compress/Implode/ImplodeDecoder.h b/7zip/Compress/Implode/ImplodeDecoder.h
new file mode 100755
index 00000000..aa90f75c
--- /dev/null
+++ b/7zip/Compress/Implode/ImplodeDecoder.h
@@ -0,0 +1,77 @@
+// ImplodeDecoder.h
+
+#ifndef __IMPLODE_DECODER_H
+#define __IMPLODE_DECODER_H
+
+#pragma once
+
+#include "Common/MyCom.h"
+
+#include "../../ICoder.h"
+#include "../LZ/LZOutWindow.h"
+
+#include "ImplodeHuffmanDecoder.h"
+
+namespace NCompress {
+namespace NImplode {
+namespace NDecoder {
+
+class CException
+{
+public:
+ enum ECauseType
+ {
+ kData
+ } m_Cause;
+ CException(ECauseType cause): m_Cause(cause) {}
+};
+
+class CCoder :
+ public ICompressCoder,
+ public ICompressSetDecoderProperties,
+ 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;
+
+ void ReadLevelItems(NImplode::NHuffman::CDecoder &table,
+ BYTE *levels, int numLevelItems);
+ void ReadTables();
+ void DeCodeLevelTable(BYTE *newLevels, int numLevels);
+public:
+ CCoder();
+
+ MY_UNKNOWN_IMP1(ICompressSetDecoderProperties)
+
+ // STDMETHOD(ReleaseStreams)();
+ // STDMETHOD(Code)(UINT32 aSize, UINT32 &aProcessedSize);
+ 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(SetCoderProperties)(PROPVARIANT *aProperties, UINT32 aNumProperties);
+ STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream);
+};
+
+}}}
+
+#endif
diff --git a/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp b/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp
new file mode 100755
index 00000000..1006d5c8
--- /dev/null
+++ b/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp
@@ -0,0 +1,88 @@
+// 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;
+}
+
+void 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)
+ throw CDecoderException();
+ 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)
+ throw CDecoderException();
+ // #endif
+
+ for (symbolIndex = 0; symbolIndex < m_NumSymbols; symbolIndex++)
+ if (codeLengths[symbolIndex] != 0)
+ m_Symbols[--tmpPositions[codeLengths[symbolIndex]]] = symbolIndex;
+}
+
+UINT32 CDecoder::DecodeSymbol(CInBit *inStream)
+{
+ UINT32 numBits;
+ UINT32 value = inStream->GetValue(kNumBitsInLongestCode);
+ int i;
+ for(i = kNumBitsInLongestCode; i > 0; i--)
+ {
+ if (value < m_Limitits[i])
+ {
+ numBits = i;
+ break;
+ }
+ }
+ if (i == 0)
+ throw CDecoderException();
+ inStream->MovePos(numBits);
+ UINT32 index = m_Positions[numBits] +
+ ((value - m_Limitits[numBits + 1]) >> (kNumBitsInLongestCode - numBits));
+ if (index >= m_NumSymbols)
+ throw CDecoderException(); // test it
+ return m_Symbols[index];
+}
+
+}}}
diff --git a/7zip/Compress/Implode/ImplodeHuffmanDecoder.h b/7zip/Compress/Implode/ImplodeHuffmanDecoder.h
new file mode 100755
index 00000000..189f7c4c
--- /dev/null
+++ b/7zip/Compress/Implode/ImplodeHuffmanDecoder.h
@@ -0,0 +1,36 @@
+// ImplodeHuffmanDecoder.h
+
+#pragma once
+
+#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;
+class CDecoderException{};
+
+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();
+
+ void SetCodeLengths(const BYTE *codeLengths);
+ UINT32 DecodeSymbol(CInBit *inStream);
+};
+
+}}}
+
+#endif
diff --git a/7zip/Compress/Implode/StdAfx.cpp b/7zip/Compress/Implode/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Compress/Implode/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Compress/Implode/StdAfx.h b/7zip/Compress/Implode/StdAfx.h
new file mode 100755
index 00000000..a32fbed6
--- /dev/null
+++ b/7zip/Compress/Implode/StdAfx.h
@@ -0,0 +1,8 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#endif
diff --git a/7zip/Compress/Implode/resource.h b/7zip/Compress/Implode/resource.h
new file mode 100755
index 00000000..612062a2
--- /dev/null
+++ b/7zip/Compress/Implode/resource.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Compress/Implode/resource.rc b/7zip/Compress/Implode/resource.rc
new file mode 100755
index 00000000..be30a871
--- /dev/null
+++ b/7zip/Compress/Implode/resource.rc
@@ -0,0 +1,121 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,9,2,0
+ PRODUCTVERSION 3,9,2,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "Implode Decoder\0"
+ VALUE "FileVersion", "3, 9, 2, 0\0"
+ VALUE "InternalName", "Implode\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "Implode.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 9, 2, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Compress/LZ/BinTree/BinTree.h b/7zip/Compress/LZ/BinTree/BinTree.h
new file mode 100755
index 00000000..9096fe70
--- /dev/null
+++ b/7zip/Compress/LZ/BinTree/BinTree.h
@@ -0,0 +1,116 @@
+// BinTree.h
+
+// #pragma once
+
+// #ifndef __BINTREE_H
+// #define __BINTREE_H
+
+#include "../LZInWindow.h"
+// #include "Common/Types.h"
+// #include "Windows/Defs.h"
+
+namespace BT_NAMESPACE {
+
+// #define __USE_3_BYTES
+
+#ifdef __USE_3_BYTES
+
+#pragma pack(push, PragmaBinTree, 1)
+
+struct CIndex
+{
+ BYTE Data[3];
+ CIndex(){}
+ CIndex(UINT32 value)
+ {
+ Data[0] = value & 0xFF;
+ Data[1] = (value >> 8) & 0xFF;
+ Data[2] = (value >> 16) & 0xFF;
+ }
+ operator UINT32() const { return (*((const UINT32 *)Data)) & 0xFFFFFF; }
+};
+const UINT32 kMaxValForNormalize = CIndex(-1);
+
+#pragma pack(pop, PragmaBinTree)
+
+#else
+
+typedef UINT32 CIndex;
+const UINT32 kMaxValForNormalize = (UINT32(1) << 31) - 1;
+
+#endif
+
+
+
+// #define HASH_ARRAY_2
+
+// #ifdef HASH_ARRAY_2
+
+// #define HASH_ARRAY_3
+
+// #else
+
+// #define HASH_ZIP
+
+// #endif
+
+#pragma pack(push, PragmaBinTreePair, 1)
+// #pragma pack(push, 1)
+
+struct CPair
+{
+ CIndex Left;
+ CIndex Right;
+};
+
+// #pragma pack(pop)
+#pragma pack(pop, PragmaBinTreePair)
+
+class CInTree: public CLZInWindow
+{
+ UINT32 _cyclicBufferPos;
+ UINT32 _cyclicBufferSize;
+ UINT32 _historySize;
+ UINT32 _matchMaxLen;
+
+ CIndex *_hash;
+
+ #ifdef HASH_ARRAY_2
+ CIndex *_hash2;
+ #ifdef HASH_ARRAY_3
+ CIndex *_hash3;
+ #endif
+ #endif
+
+ CPair *_son;
+
+ UINT32 _cutValue;
+
+ void NormalizeLinks(CIndex *array, UINT32 numItems, UINT32 subValue);
+ void Normalize();
+ void FreeMemory();
+
+public:
+ CInTree();
+ ~CInTree();
+ HRESULT Create(UINT32 sizeHistory, UINT32 keepAddBufferBefore, UINT32 matchMaxLen,
+ UINT32 keepAddBufferAfter, UINT32 sizeReserv = (1<<17));
+ HRESULT Init(ISequentialInStream *stream);
+ void SetCutValue(UINT32 cutValue) { _cutValue = cutValue; }
+ UINT32 GetLongestMatch(UINT32 *distances);
+ void DummyLongestMatch();
+ HRESULT MovePos()
+ {
+ _cyclicBufferPos++;
+ if (_cyclicBufferPos >= _cyclicBufferSize)
+ _cyclicBufferPos = 0;
+ RINOK(CLZInWindow::MovePos());
+ if (_pos == kMaxValForNormalize)
+ Normalize();
+ return S_OK;
+ }
+};
+
+}
+
+// #endif
diff --git a/7zip/Compress/LZ/BinTree/BinTree2.h b/7zip/Compress/LZ/BinTree/BinTree2.h
new file mode 100755
index 00000000..2a93e8b2
--- /dev/null
+++ b/7zip/Compress/LZ/BinTree/BinTree2.h
@@ -0,0 +1,18 @@
+// BinTree2.h
+
+// #pragma once
+
+#ifndef __BINTREE2__H
+#define __BINTREE2__H
+
+#undef BT_CLSID
+#define BT_CLSID CLSID_CMatchFinderBT2
+
+#undef BT_NAMESPACE
+#define BT_NAMESPACE NBT2
+
+#include "BinTreeMF.h"
+#include "BinTreeMFMain.h"
+
+#endif
+
diff --git a/7zip/Compress/LZ/BinTree/BinTree3.h b/7zip/Compress/LZ/BinTree/BinTree3.h
new file mode 100755
index 00000000..69bb8711
--- /dev/null
+++ b/7zip/Compress/LZ/BinTree/BinTree3.h
@@ -0,0 +1,22 @@
+// BinTree3.h
+
+// #pragma once
+
+#ifndef __BINTREE3__H
+#define __BINTREE3__H
+
+#undef BT_CLSID
+#define BT_CLSID CLSID_CMatchFinderBT3
+
+#undef BT_NAMESPACE
+#define BT_NAMESPACE NBT3
+
+#define HASH_ARRAY_2
+
+#include "BinTreeMF.h"
+#include "BinTreeMFMain.h"
+
+#undef HASH_ARRAY_2
+
+#endif
+
diff --git a/7zip/Compress/LZ/BinTree/BinTree3Z.h b/7zip/Compress/LZ/BinTree/BinTree3Z.h
new file mode 100755
index 00000000..9217d9fe
--- /dev/null
+++ b/7zip/Compress/LZ/BinTree/BinTree3Z.h
@@ -0,0 +1,19 @@
+// BinTree3Z.h
+
+// #pragma once
+
+#ifndef __BINTREE3Z__H
+#define __BINTREE3Z__H
+
+#undef BT_NAMESPACE
+#define BT_NAMESPACE NBT3Z
+
+#define HASH_ZIP
+
+#include "BinTree.h"
+// #include "BinTreeMain.h"
+
+#undef HASH_ZIP
+
+#endif
+
diff --git a/7zip/Compress/LZ/BinTree/BinTree3ZMain.h b/7zip/Compress/LZ/BinTree/BinTree3ZMain.h
new file mode 100755
index 00000000..ded819f1
--- /dev/null
+++ b/7zip/Compress/LZ/BinTree/BinTree3ZMain.h
@@ -0,0 +1,18 @@
+// BinTree3ZMain.h
+
+// #pragma once
+
+#ifndef __BINTREE3ZMAIN__H
+#define __BINTREE3ZMAIN__H
+
+#undef BT_NAMESPACE
+#define BT_NAMESPACE NBT3Z
+
+#define HASH_ZIP
+
+#include "BinTreeMain.h"
+
+#undef HASH_ZIP
+
+#endif
+
diff --git a/7zip/Compress/LZ/BinTree/BinTree4.h b/7zip/Compress/LZ/BinTree/BinTree4.h
new file mode 100755
index 00000000..c5cc2a76
--- /dev/null
+++ b/7zip/Compress/LZ/BinTree/BinTree4.h
@@ -0,0 +1,24 @@
+// BinTree4.h
+
+// #pragma once
+
+#ifndef __BINTREE4__H
+#define __BINTREE4__H
+
+#undef BT_CLSID
+#define BT_CLSID CLSID_CMatchFinderBT4
+
+#undef BT_NAMESPACE
+#define BT_NAMESPACE NBT4
+
+#define HASH_ARRAY_2
+#define HASH_ARRAY_3
+
+#include "BinTreeMF.h"
+#include "BinTreeMFMain.h"
+
+#undef HASH_ARRAY_2
+#undef HASH_ARRAY_3
+
+#endif
+
diff --git a/7zip/Compress/LZ/BinTree/BinTree4b.h b/7zip/Compress/LZ/BinTree/BinTree4b.h
new file mode 100755
index 00000000..0128f32c
--- /dev/null
+++ b/7zip/Compress/LZ/BinTree/BinTree4b.h
@@ -0,0 +1,26 @@
+// BinTree4b.h
+
+// #pragma once
+
+#ifndef __BINTREE4B__H
+#define __BINTREE4B__H
+
+#undef BT_CLSID
+#define BT_CLSID CLSID_CMatchFinderBT4b
+
+#undef BT_NAMESPACE
+#define BT_NAMESPACE NBT4B
+
+#define HASH_ARRAY_2
+#define HASH_ARRAY_3
+#define HASH_BIG
+
+#include "BinTreeMF.h"
+#include "BinTreeMFMain.h"
+
+#undef HASH_ARRAY_2
+#undef HASH_ARRAY_3
+#undef HASH_BIG
+
+#endif
+
diff --git a/7zip/Compress/LZ/BinTree/BinTreeMF.h b/7zip/Compress/LZ/BinTree/BinTreeMF.h
new file mode 100755
index 00000000..9903db4f
--- /dev/null
+++ b/7zip/Compress/LZ/BinTree/BinTreeMF.h
@@ -0,0 +1,110 @@
+// BinTreeMF.h
+
+// #pragma once
+
+// #ifndef __BINTREEMF_H
+// #define __BINTREEMF_H
+
+#include "../../../ICoder.h"
+#include "BinTree.h"
+
+namespace BT_NAMESPACE {
+
+#undef kIDByte
+#undef kIDString
+
+#ifdef HASH_ARRAY_2
+ #ifdef HASH_ARRAY_3
+ #ifdef HASH_BIG
+ #define kIDByte 0x4
+ #define kIDString TEXT("4b")
+ #else
+ #define kIDByte 0x3
+ #define kIDString TEXT("4")
+ #endif
+ #else
+ #define kIDByte 0x2
+ #define kIDString TEXT("3")
+ #endif
+#else
+ #ifdef HASH_ZIP
+ #define kIDByte 0x0
+ #define kIDString TEXT("3Z")
+ #else
+ #define kIDByte 0x1
+ #define kIDString TEXT("2")
+ #endif
+#endif
+
+#undef kIDUse3BytesByte
+#undef kIDUse3BytesString
+
+#ifdef __USE_3_BYTES
+ #define kIDUse3BytesByte 0x80
+ #define kIDUse3BytesString TEXT("T")
+#else
+ #define kIDUse3BytesByte 0x00
+ #define kIDUse3BytesString TEXT("")
+#endif
+
+// #undef kIDStringFull
+
+// #define kIDStringFull TEXT("Compress.MatchFinderBT") kIDString kIDUse3BytesString
+
+// {23170F69-40C1-278C-02XX-0000000000}
+DEFINE_GUID(BT_CLSID,
+0x23170F69, 0x40C1, 0x278C, 0x02, kIDByte | kIDUse3BytesByte,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+class CInTree2: public CInTree
+{
+ CMyComPtr<IMatchFinderCallback> _callback;
+ virtual void BeforeMoveBlock();
+ virtual void AfterMoveBlock();
+public:
+ void SetCallback(IMatchFinderCallback *callback)
+ {
+ _callback = callback;
+ }
+};
+
+class CMatchFinderBinTree:
+ public IMatchFinder,
+ public IMatchFinderSetCallback,
+ public CMyUnknownImp
+{
+ MY_UNKNOWN_IMP1(IMatchFinderSetCallback)
+
+ STDMETHOD(Init)(ISequentialInStream *stream);
+ STDMETHOD_(void, ReleaseStream)();
+ STDMETHOD(MovePos)();
+ STDMETHOD_(BYTE, GetIndexByte)(UINT32 index);
+ STDMETHOD_(UINT32, GetMatchLen)(UINT32 index, UINT32 back, UINT32 limit);
+ STDMETHOD_(UINT32, GetNumAvailableBytes)();
+ STDMETHOD_(const BYTE *, GetPointerToCurrentPos)();
+ STDMETHOD(Create)(UINT32 sizeHistory,
+ UINT32 keepAddBufferBefore, UINT32 matchMaxLen,
+ UINT32 keepAddBufferAfter);
+ STDMETHOD_(UINT32, GetLongestMatch)(UINT32 *distances);
+ STDMETHOD_(void, DummyLongestMatch)();
+
+ // IMatchFinderSetCallback
+ STDMETHOD(SetCallback)(IMatchFinderCallback *callback);
+
+private:
+ // UINT32 m_WindowReservSize;
+ CInTree2 _matchFinder;
+public:
+ // CMatchFinderBinTree(): m_WindowReservSize((1 << 19) + 256) {};
+ void SetCutValue(UINT32 cutValue)
+ { _matchFinder.SetCutValue(cutValue); }
+ /*
+ void SetWindowReservSize(UINT32 reservWindowSize)
+ { m_WindowReservSize = reservWindowSize; }
+ */
+};
+
+}
+
+// #endif
+
diff --git a/7zip/Compress/LZ/BinTree/BinTreeMFMain.h b/7zip/Compress/LZ/BinTree/BinTreeMFMain.h
new file mode 100755
index 00000000..499686ba
--- /dev/null
+++ b/7zip/Compress/LZ/BinTree/BinTreeMFMain.h
@@ -0,0 +1,81 @@
+// BinTreeMFMain.h
+
+// #include "StdAfx.h"
+
+// #include "BinTreeMF.h"
+#include "BinTreeMain.h"
+
+namespace BT_NAMESPACE {
+
+void CInTree2::BeforeMoveBlock()
+{
+ if (_callback)
+ _callback->BeforeChangingBufferPos();
+ CInTree::BeforeMoveBlock();
+}
+
+void CInTree2::AfterMoveBlock()
+{
+ CInTree::AfterMoveBlock();
+ if (_callback)
+ _callback->AfterChangingBufferPos();
+}
+
+STDMETHODIMP CMatchFinderBinTree::Init(ISequentialInStream *stream)
+ { return _matchFinder.Init(stream); }
+
+STDMETHODIMP_(void) CMatchFinderBinTree::ReleaseStream()
+{
+ // _matchFinder.ReleaseStream();
+}
+
+STDMETHODIMP CMatchFinderBinTree::MovePos()
+ { return _matchFinder.MovePos(); }
+
+STDMETHODIMP_(BYTE) CMatchFinderBinTree::GetIndexByte(UINT32 index)
+ { return _matchFinder.GetIndexByte(index); }
+
+STDMETHODIMP_(UINT32) CMatchFinderBinTree::GetMatchLen(UINT32 index,
+ UINT32 back, UINT32 limit)
+ { return _matchFinder.GetMatchLen(index, back, limit); }
+
+STDMETHODIMP_(UINT32) CMatchFinderBinTree::GetNumAvailableBytes()
+ { return _matchFinder.GetNumAvailableBytes(); }
+
+STDMETHODIMP CMatchFinderBinTree::Create(UINT32 sizeHistory,
+ UINT32 keepAddBufferBefore, UINT32 matchMaxLen,
+ UINT32 keepAddBufferAfter)
+{
+ UINT32 windowReservSize = (sizeHistory + keepAddBufferBefore +
+ matchMaxLen + keepAddBufferAfter) / 2 + 256;
+ try
+ {
+ return _matchFinder.Create(sizeHistory, keepAddBufferBefore,
+ matchMaxLen, keepAddBufferAfter, windowReservSize);
+ }
+ catch(...)
+ {
+ return E_OUTOFMEMORY;
+ }
+}
+
+STDMETHODIMP_(UINT32) CMatchFinderBinTree::GetLongestMatch(UINT32 *distances)
+ { return _matchFinder.GetLongestMatch(distances); }
+
+STDMETHODIMP_(void) CMatchFinderBinTree::DummyLongestMatch()
+ { _matchFinder.DummyLongestMatch(); }
+
+STDMETHODIMP_(const BYTE *) CMatchFinderBinTree::GetPointerToCurrentPos()
+{
+ return _matchFinder.GetPointerToCurrentPos();
+}
+
+// IMatchFinderSetCallback
+STDMETHODIMP CMatchFinderBinTree::SetCallback(IMatchFinderCallback *callback)
+{
+ _matchFinder.SetCallback(callback);
+ return S_OK;
+}
+
+
+}
diff --git a/7zip/Compress/LZ/BinTree/BinTreeMain.h b/7zip/Compress/LZ/BinTree/BinTreeMain.h
new file mode 100755
index 00000000..6657d07d
--- /dev/null
+++ b/7zip/Compress/LZ/BinTree/BinTreeMain.h
@@ -0,0 +1,542 @@
+// BinTreemain.h
+
+// #include "StdAfx.h"
+
+// #include "BinTree.h"
+// #include "Common/NewHandler.h"
+
+#include "../../../../Common/Defs.h"
+#include "../../../../Common/CRC.h"
+
+namespace BT_NAMESPACE {
+
+#ifdef HASH_ARRAY_2
+ static const UINT32 kHash2Size = 1 << 10;
+ #ifdef HASH_ARRAY_3
+ static const UINT32 kNumHashDirectBytes = 0;
+ static const UINT32 kNumHashBytes = 4;
+ static const UINT32 kHash3Size = 1 << 18;
+ #ifdef HASH_BIG
+ static const UINT32 kHashSize = 1 << 23;
+ #else
+ static const UINT32 kHashSize = 1 << 20;
+ #endif
+ #else
+ static const UINT32 kNumHashDirectBytes = 3;
+ static const UINT32 kNumHashBytes = 3;
+ static const UINT32 kHashSize = 1 << (8 * kNumHashBytes);
+ #endif
+#else
+ #ifdef HASH_ZIP
+ static const UINT32 kNumHashDirectBytes = 0;
+ static const UINT32 kNumHashBytes = 3;
+ static const UINT32 kHashSize = 1 << 16;
+ #else
+ static const UINT32 kNumHashDirectBytes = 2;
+ static const UINT32 kNumHashBytes = 2;
+ static const UINT32 kHashSize = 1 << (8 * kNumHashBytes);
+ #endif
+#endif
+
+
+CInTree::CInTree():
+ #ifdef HASH_ARRAY_2
+ _hash2(0),
+ #ifdef HASH_ARRAY_3
+ _hash3(0),
+ #endif
+ #endif
+ _hash(0),
+ _son(0),
+ _cutValue(0xFF)
+{
+}
+
+void CInTree::FreeMemory()
+{
+ #ifdef WIN32
+ if (_son != 0)
+ VirtualFree(_son, 0, MEM_RELEASE);
+ if (_hash != 0)
+ VirtualFree(_hash, 0, MEM_RELEASE);
+ #else
+ delete []_son;
+ delete []_hash;
+ #endif
+ _son = 0;
+ _hash = 0;
+ CLZInWindow::Free();
+}
+
+CInTree::~CInTree()
+{
+ FreeMemory();
+}
+
+HRESULT CInTree::Create(UINT32 sizeHistory, UINT32 keepAddBufferBefore,
+ UINT32 matchMaxLen, UINT32 keepAddBufferAfter, UINT32 sizeReserv)
+{
+ FreeMemory();
+ try
+ {
+ CLZInWindow::Create(sizeHistory + keepAddBufferBefore,
+ matchMaxLen + keepAddBufferAfter, sizeReserv);
+
+ if (_blockSize + 256 > kMaxValForNormalize)
+ return E_INVALIDARG;
+
+ _historySize = sizeHistory;
+ _matchMaxLen = matchMaxLen;
+
+ _cyclicBufferSize = sizeHistory + 1;
+
+
+ UINT32 size = kHashSize;
+ #ifdef HASH_ARRAY_2
+ size += kHash2Size;
+ #ifdef HASH_ARRAY_3
+ size += kHash3Size;
+ #endif
+ #endif
+
+ #ifdef WIN32
+ _son = (CPair *)::VirtualAlloc(0, (_cyclicBufferSize + 1) * sizeof(CPair), MEM_COMMIT, PAGE_READWRITE);
+ if (_son == 0)
+ throw 1; // CNewException();
+ _hash = (CIndex *)::VirtualAlloc(0, (size + 1) * sizeof(CIndex), MEM_COMMIT, PAGE_READWRITE);
+ if (_hash == 0)
+ throw 1; // CNewException();
+ #else
+ _son = new CPair[_cyclicBufferSize + 1];
+ _hash = new CIndex[size + 1];
+ #endif
+
+ // m_RightBase = &m_LeftBase[_blockSize];
+
+ // _hash = &m_RightBase[_blockSize];
+ #ifdef HASH_ARRAY_2
+ _hash2 = &_hash[kHashSize];
+ #ifdef HASH_ARRAY_3
+ _hash3 = &_hash2[kHash2Size];
+ #endif
+ #endif
+ return S_OK;
+ }
+ catch(...)
+ {
+ FreeMemory();
+ return E_OUTOFMEMORY;
+ }
+}
+
+static const UINT32 kEmptyHashValue = 0;
+
+HRESULT CInTree::Init(ISequentialInStream *stream)
+{
+ RINOK(CLZInWindow::Init(stream));
+ int i;
+ for(i = 0; i < kHashSize; i++)
+ _hash[i] = kEmptyHashValue;
+
+ #ifdef HASH_ARRAY_2
+ for(i = 0; i < kHash2Size; i++)
+ _hash2[i] = kEmptyHashValue;
+ #ifdef HASH_ARRAY_3
+ for(i = 0; i < kHash3Size; i++)
+ _hash3[i] = kEmptyHashValue;
+ #endif
+ #endif
+
+ _cyclicBufferPos = 0;
+
+ ReduceOffsets(0 - 1);
+ return S_OK;
+}
+
+
+#ifdef HASH_ARRAY_2
+#ifdef HASH_ARRAY_3
+inline UINT32 Hash(const BYTE *pointer, UINT32 &hash2Value, UINT32 &hash3Value)
+{
+ UINT32 temp = CCRC::Table[pointer[0]] ^ pointer[1];
+ hash2Value = temp & (kHash2Size - 1);
+ hash3Value = (temp ^ (UINT32(pointer[2]) << 8)) & (kHash3Size - 1);
+ return (temp ^ (UINT32(pointer[2]) << 8) ^ (CCRC::Table[pointer[3]] << 5)) &
+ (kHashSize - 1);
+}
+#else // no HASH_ARRAY_3
+inline UINT32 Hash(const BYTE *pointer, UINT32 &hash2Value)
+{
+ hash2Value = (CCRC::Table[pointer[0]] ^ pointer[1]) & (kHash2Size - 1);
+ return (*((const UINT32 *)pointer)) & 0xFFFFFF;
+}
+#endif // HASH_ARRAY_3
+#else // no HASH_ARRAY_2
+#ifdef HASH_ZIP
+inline UINT32 Hash(const BYTE *pointer)
+{
+ return ((UINT32(pointer[0]) << 8) ^
+ CCRC::Table[pointer[1]] ^ pointer[2]) & (kHashSize - 1);
+}
+#else // no HASH_ZIP
+inline UINT32 Hash(const BYTE *pointer)
+{
+ return pointer[0] ^ (UINT32(pointer[1]) << 8);
+}
+#endif // HASH_ZIP
+#endif // HASH_ARRAY_2
+
+UINT32 CInTree::GetLongestMatch(UINT32 *distances)
+{
+ UINT32 currentLimit;
+ if (_pos + _matchMaxLen <= _streamPos)
+ currentLimit = _matchMaxLen;
+ else
+ {
+ currentLimit = _streamPos - _pos;
+ if(currentLimit < kNumHashBytes)
+ return 0;
+ }
+
+ UINT32 matchMinPos = (_pos > _historySize) ? (_pos - _historySize) : 1;
+ BYTE *cur = _buffer + _pos;
+
+ UINT32 matchHashLenMax = 0;
+
+ #ifdef HASH_ARRAY_2
+ UINT32 hash2Value;
+ #ifdef HASH_ARRAY_3
+ UINT32 hash3Value;
+ UINT32 hashValue = Hash(cur, hash2Value, hash3Value);
+ #else
+ UINT32 hashValue = Hash(cur, hash2Value);
+ #endif
+ #else
+ UINT32 hashValue = Hash(cur);
+ #endif
+
+ UINT32 curMatch = _hash[hashValue];
+ #ifdef HASH_ARRAY_2
+ UINT32 curMatch2 = _hash2[hash2Value];
+ #ifdef HASH_ARRAY_3
+ UINT32 curMatch3 = _hash3[hash3Value];
+ #endif
+ _hash2[hash2Value] = _pos;
+ bool matchLen2Exist = false;
+ UINT32 len2Distance = 0;
+ if(curMatch2 >= matchMinPos)
+ {
+ if (_buffer[curMatch2] == cur[0])
+ {
+ len2Distance = _pos - curMatch2 - 1;
+ matchHashLenMax = 2;
+ matchLen2Exist = true;
+ }
+ }
+
+ #ifdef HASH_ARRAY_3
+ _hash3[hash3Value] = _pos;
+ UINT32 matchLen3Exist = false;
+ UINT32 len3Distance = 0;
+ if(curMatch3 >= matchMinPos)
+ {
+ if (_buffer[curMatch3] == cur[0])
+ {
+ len3Distance = _pos - curMatch3 - 1;
+ matchHashLenMax = 3;
+ matchLen3Exist = true;
+ if (matchLen2Exist)
+ {
+ if (len3Distance < len2Distance)
+ len2Distance = len3Distance;
+ }
+ else
+ {
+ len2Distance = len3Distance;
+ matchLen2Exist = true;
+ }
+ }
+ }
+ #endif
+ #endif
+
+ _hash[hashValue] = _pos;
+
+ if(curMatch < matchMinPos)
+ {
+ _son[_cyclicBufferPos].Left = kEmptyHashValue;
+ _son[_cyclicBufferPos].Right = kEmptyHashValue;
+
+ #ifdef HASH_ARRAY_2
+ distances[2] = len2Distance;
+ #ifdef HASH_ARRAY_3
+ distances[3] = len3Distance;
+ #endif
+ #endif
+
+ return matchHashLenMax;
+ }
+ CIndex *ptrLeft = &_son[_cyclicBufferPos].Right;
+ CIndex *ptrRight = &_son[_cyclicBufferPos].Left;
+
+ UINT32 maxLen, minSameLeft, minSameRight, minSame;
+ maxLen = minSameLeft = minSameRight = minSame = kNumHashDirectBytes;
+
+ #ifdef HASH_ARRAY_2
+ #ifndef HASH_ARRAY_3
+ if (matchLen2Exist)
+ distances[2] = len2Distance;
+ else
+ if (kNumHashDirectBytes >= 2)
+ distances[2] = _pos - curMatch - 1;
+ #endif
+ #endif
+
+ distances[maxLen] = _pos - curMatch - 1;
+
+ for(UINT32 count = _cutValue; count > 0; count--)
+ {
+ BYTE *pby1 = _buffer + curMatch;
+ // CIndex left = _son[curMatch].Left; // it's prefetch
+ UINT32 currentLen;
+ for(currentLen = minSame; currentLen < currentLimit; currentLen++/*, dwComps++*/)
+ if (pby1[currentLen] != cur[currentLen])
+ break;
+ while (currentLen > maxLen)
+ distances[++maxLen] = _pos - curMatch - 1;
+
+ UINT32 delta = _pos - curMatch;
+ UINT32 cyclicPos = (delta <= _cyclicBufferPos) ?
+ (_cyclicBufferPos - delta):
+ (_cyclicBufferPos - delta + _cyclicBufferSize);
+
+ if (currentLen != currentLimit)
+ {
+ if (pby1[currentLen] < cur[currentLen])
+ {
+ *ptrRight = curMatch;
+ ptrRight = &_son[cyclicPos].Right;
+ curMatch = _son[cyclicPos].Right;
+ if(currentLen > minSameLeft)
+ {
+ minSameLeft = currentLen;
+ minSame = MyMin(minSameLeft, minSameRight);
+ }
+ }
+ else
+ {
+ *ptrLeft = curMatch;
+ ptrLeft = &_son[cyclicPos].Left;
+ // curMatch = left;
+ curMatch = _son[cyclicPos].Left;
+ if(currentLen > minSameRight)
+ {
+ minSameRight = currentLen;
+ minSame = MyMin(minSameLeft, minSameRight);
+ }
+ }
+ }
+ else
+ {
+ if(currentLen < _matchMaxLen)
+ {
+ *ptrLeft = curMatch;
+ ptrLeft = &_son[cyclicPos].Left;
+ curMatch = _son[cyclicPos].Left;
+ if(currentLen > minSameRight)
+ {
+ minSameRight = currentLen;
+ minSame = MyMin(minSameLeft, minSameRight);
+ }
+ }
+ else
+ {
+ *ptrLeft = _son[cyclicPos].Right;
+ *ptrRight = _son[cyclicPos].Left;
+
+ #ifdef HASH_ARRAY_2
+ if (matchLen2Exist && len2Distance < distances[2])
+ distances[2] = len2Distance;
+ #ifdef HASH_ARRAY_3
+ if (matchLen3Exist && len3Distance < distances[3])
+ distances[3] = len3Distance;
+ #endif
+ #endif
+
+ return maxLen;
+ }
+ }
+ if(curMatch < matchMinPos)
+ break;
+ }
+ *ptrLeft = kEmptyHashValue;
+ *ptrRight = kEmptyHashValue;
+ #ifdef HASH_ARRAY_2
+ if (matchLen2Exist)
+ {
+ if (maxLen < 2)
+ {
+ distances[2] = len2Distance;
+ maxLen = 2;
+ }
+ else if (len2Distance < distances[2])
+ distances[2] = len2Distance;
+ }
+ #ifdef HASH_ARRAY_3
+ if (matchLen3Exist)
+ {
+ if (maxLen < 3)
+ {
+ distances[3] = len3Distance;
+ maxLen = 3;
+ }
+ else if (len3Distance < distances[3])
+ distances[3] = len3Distance;
+ }
+ #endif
+ #endif
+ return maxLen;
+}
+
+void CInTree::DummyLongestMatch()
+{
+ UINT32 currentLimit;
+ if (_pos + _matchMaxLen <= _streamPos)
+ currentLimit = _matchMaxLen;
+ else
+ {
+ currentLimit = _streamPos - _pos;
+ if(currentLimit < kNumHashBytes)
+ return;
+ }
+ UINT32 matchMinPos = (_pos > _historySize) ? (_pos - _historySize) : 1;
+ BYTE *cur = _buffer + _pos;
+
+ #ifdef HASH_ARRAY_2
+ UINT32 hash2Value;
+ #ifdef HASH_ARRAY_3
+ UINT32 hash3Value;
+ UINT32 hashValue = Hash(cur, hash2Value, hash3Value);
+ _hash3[hash3Value] = _pos;
+ #else
+ UINT32 hashValue = Hash(cur, hash2Value);
+ #endif
+ _hash2[hash2Value] = _pos;
+ #else
+ UINT32 hashValue = Hash(cur);
+ #endif
+
+ UINT32 curMatch = _hash[hashValue];
+ _hash[hashValue] = _pos;
+
+ if(curMatch < matchMinPos)
+ {
+ _son[_cyclicBufferPos].Left = kEmptyHashValue;
+ _son[_cyclicBufferPos].Right = kEmptyHashValue;
+ return;
+ }
+ CIndex *ptrLeft = &_son[_cyclicBufferPos].Right;
+ CIndex *ptrRight = &_son[_cyclicBufferPos].Left;
+
+ UINT32 maxLen, minSameLeft, minSameRight, minSame;
+ maxLen = minSameLeft = minSameRight = minSame = kNumHashDirectBytes;
+ for(UINT32 count = _cutValue; count > 0; count--)
+ {
+ BYTE *pby1 = _buffer + curMatch;
+ // CIndex left = _son[curMatch].Left; // it's prefetch
+ UINT32 currentLen;
+ for(currentLen = minSame; currentLen < currentLimit; currentLen++/*, dwComps++*/)
+ if (pby1[currentLen] != cur[currentLen])
+ break;
+
+ UINT32 delta = _pos - curMatch;
+ UINT32 cyclicPos = (delta <= _cyclicBufferPos) ?
+ (_cyclicBufferPos - delta):
+ (_cyclicBufferPos - delta + _cyclicBufferSize);
+
+ if (currentLen != currentLimit)
+ {
+ if (pby1[currentLen] < cur[currentLen])
+ {
+ *ptrRight = curMatch;
+ ptrRight = &_son[cyclicPos].Right;
+ curMatch = _son[cyclicPos].Right;
+ if(currentLen > minSameLeft)
+ {
+ minSameLeft = currentLen;
+ minSame = MyMin(minSameLeft, minSameRight);
+ }
+ }
+ else
+ {
+ *ptrLeft = curMatch;
+ ptrLeft = &_son[cyclicPos].Left;
+ curMatch = _son[cyclicPos].Left;
+ // curMatch = left;
+ if(currentLen > minSameRight)
+ {
+ minSameRight = currentLen;
+ minSame = MyMin(minSameLeft, minSameRight);
+ }
+ }
+ }
+ else
+ {
+ if(currentLen < _matchMaxLen)
+ {
+ *ptrLeft = curMatch;
+ ptrLeft = &_son[cyclicPos].Left;
+ curMatch = _son[cyclicPos].Left;
+ if(currentLen > minSameRight)
+ {
+ minSameRight = currentLen;
+ minSame = MyMin(minSameLeft, minSameRight);
+ }
+ }
+ else
+ {
+ *ptrLeft = _son[cyclicPos].Right;
+ *ptrRight = _son[cyclicPos].Left;
+ return;
+ }
+ }
+ if(curMatch < matchMinPos)
+ break;
+ }
+ *ptrLeft = kEmptyHashValue;
+ *ptrRight = kEmptyHashValue;
+}
+
+void CInTree::NormalizeLinks(CIndex *array, UINT32 numItems, UINT32 subValue)
+{
+ for (UINT32 i = 0; i < numItems; i++)
+ {
+ UINT32 value = array[i];
+ if (value <= subValue)
+ value = kEmptyHashValue;
+ else
+ value -= subValue;
+ array[i] = value;
+ }
+}
+
+void CInTree::Normalize()
+{
+ UINT32 startItem = _pos - _historySize;
+ UINT32 subValue = startItem - 1;
+ // NormalizeLinks((CIndex *)(_son + startItem), _historySize * 2, subValue);
+ NormalizeLinks((CIndex *)_son, _cyclicBufferSize * 2, subValue);
+
+ NormalizeLinks(_hash, kHashSize, subValue);
+
+ #ifdef HASH_ARRAY_2
+ NormalizeLinks(_hash2, kHash2Size, subValue);
+ #ifdef HASH_ARRAY_3
+ NormalizeLinks(_hash3, kHash3Size, subValue);
+ #endif
+ #endif
+
+ ReduceOffsets(subValue);
+}
+
+}
diff --git a/7zip/Compress/LZ/HashChain/HC.h b/7zip/Compress/LZ/HashChain/HC.h
new file mode 100755
index 00000000..0928c747
--- /dev/null
+++ b/7zip/Compress/LZ/HashChain/HC.h
@@ -0,0 +1,108 @@
+// HC.h
+
+// #pragma once
+
+// #ifndef __HC_H
+// #define __HC_H
+
+#include "../LZInWindow.h"
+#include "Common/Types.h"
+#include "Windows/Defs.h"
+
+namespace HC_NAMESPACE {
+
+
+// #define __USE_3_BYTES
+
+#ifdef __USE_3_BYTES
+
+#pragma pack(push, PragmaBinTree)
+#pragma pack(push, 1)
+
+struct CIndex
+{
+ BYTE Data[3];
+ CIndex(){}
+ CIndex(UINT32 aValue)
+ {
+ Data[0] = aValue & 0xFF;
+ Data[1] = (aValue >> 8) & 0xFF;
+ Data[2] = (aValue >> 16) & 0xFF;
+ }
+ operator UINT32() const { return (*((const UINT32 *)Data)) & 0xFFFFFF; }
+};
+const UINT32 kMaxValForNormalize = CIndex(-1);
+
+#pragma pack(pop)
+#pragma pack(pop, PragmaBinTree)
+
+#else
+
+typedef UINT32 CIndex;
+const UINT32 kMaxValForNormalize = (UINT32(1) << 31) - 1;
+
+#endif
+
+
+
+// #define HASH_ARRAY_2
+
+// #ifdef HASH_ARRAY_2
+
+// #define HASH_ARRAY_3
+
+// #else
+
+// #define HASH_ZIP
+
+// #endif
+
+class CInTree: public CLZInWindow
+{
+ UINT32 _cyclicBufferPos;
+ UINT32 _cyclicBufferSize;
+
+ UINT32 _historySize;
+ UINT32 _matchMaxLen;
+
+ CIndex *_hash;
+
+ #ifdef HASH_ARRAY_2
+ CIndex *_hash2;
+ #ifdef HASH_ARRAY_3
+ CIndex *_hash3;
+ #endif
+ #endif
+
+ CIndex *_chain;
+
+ UINT32 _cutValue;
+
+ void NormalizeLinks(CIndex *anArray, UINT32 aNumItems, UINT32 aSubValue);
+ void Normalize();
+ void FreeMemory();
+
+public:
+ CInTree();
+ ~CInTree();
+ HRESULT Create(UINT32 aSizeHistory, UINT32 aKeepAddBufferBefore, UINT32 aMatchMaxLen,
+ UINT32 aKeepAddBufferAfter, UINT32 _dwSizeReserv = (1<<17));
+ HRESULT Init(ISequentialInStream *aStream);
+ void SetCutValue(UINT32 aCutValue) { _cutValue = aCutValue; }
+ UINT32 GetLongestMatch(UINT32 *aDistances);
+ void DummyLongestMatch();
+ HRESULT MovePos()
+ {
+ _cyclicBufferPos++;
+ if (_cyclicBufferPos >= _cyclicBufferSize)
+ _cyclicBufferPos = 0;
+ RINOK(CLZInWindow::MovePos());
+ if (_pos == kMaxValForNormalize)
+ Normalize();
+ return S_OK;
+ }
+};
+
+}
+
+// #endif
diff --git a/7zip/Compress/LZ/HashChain/HC2.h b/7zip/Compress/LZ/HashChain/HC2.h
new file mode 100755
index 00000000..c2582cee
--- /dev/null
+++ b/7zip/Compress/LZ/HashChain/HC2.h
@@ -0,0 +1,18 @@
+// HC2.h
+
+#pragma once
+
+#ifndef __HC2__H
+#define __HC2__H
+
+#undef HC_CLSID
+#define HC_CLSID CLSID_CMatchFinderHC2
+
+#undef HC_NAMESPACE
+#define HC_NAMESPACE NHC2
+
+#include "HCMF.h"
+#include "HCMFMain.h"
+
+#endif
+
diff --git a/7zip/Compress/LZ/HashChain/HC3.h b/7zip/Compress/LZ/HashChain/HC3.h
new file mode 100755
index 00000000..1edca882
--- /dev/null
+++ b/7zip/Compress/LZ/HashChain/HC3.h
@@ -0,0 +1,22 @@
+// HC3.h
+
+#pragma once
+
+#ifndef __HC3__H
+#define __HC3__H
+
+#undef HC_CLSID
+#define HC_CLSID CLSID_CMatchFinderHC3
+
+#undef HC_NAMESPACE
+#define HC_NAMESPACE NHC3
+
+#define HASH_ARRAY_2
+
+#include "HCMF.h"
+#include "HCMFMain.h"
+
+#undef HASH_ARRAY_2
+
+#endif
+
diff --git a/7zip/Compress/LZ/HashChain/HC4.h b/7zip/Compress/LZ/HashChain/HC4.h
new file mode 100755
index 00000000..fb0a39df
--- /dev/null
+++ b/7zip/Compress/LZ/HashChain/HC4.h
@@ -0,0 +1,24 @@
+// HC4.h
+
+#pragma once
+
+#ifndef __HC4__H
+#define __HC4__H
+
+#undef HC_CLSID
+#define HC_CLSID CLSID_CMatchFinderHC4
+
+#undef HC_NAMESPACE
+#define HC_NAMESPACE NHC4
+
+#define HASH_ARRAY_2
+#define HASH_ARRAY_3
+
+#include "HCMF.h"
+#include "HCMFMain.h"
+
+#undef HASH_ARRAY_2
+#undef HASH_ARRAY_3
+
+#endif
+
diff --git a/7zip/Compress/LZ/HashChain/HC4b.h b/7zip/Compress/LZ/HashChain/HC4b.h
new file mode 100755
index 00000000..6f8949d8
--- /dev/null
+++ b/7zip/Compress/LZ/HashChain/HC4b.h
@@ -0,0 +1,26 @@
+// HC4b.h
+
+#pragma once
+
+#ifndef __HC4B__H
+#define __HC4B__H
+
+#undef HC_CLSID
+#define HC_CLSID CLSID_CMatchFinderHC4b
+
+#undef HC_NAMESPACE
+#define HC_NAMESPACE NHC4b
+
+#define HASH_ARRAY_2
+#define HASH_ARRAY_3
+#define HASH_BIG
+
+#include "HCMF.h"
+#include "HCMFMain.h"
+
+#undef HASH_ARRAY_2
+#undef HASH_ARRAY_3
+#undef HASH_BIG
+
+#endif
+
diff --git a/7zip/Compress/LZ/HashChain/HCMF.h b/7zip/Compress/LZ/HashChain/HCMF.h
new file mode 100755
index 00000000..94f42f6b
--- /dev/null
+++ b/7zip/Compress/LZ/HashChain/HCMF.h
@@ -0,0 +1,111 @@
+// HCMF.h
+
+// #pragma once
+
+// #ifndef __HCMF_H
+// #define __HCMF_H
+
+#include "Common/MyCom.h"
+// #include "../../../Interface/CompressInterface.h"
+#include "HC.h"
+
+namespace HC_NAMESPACE {
+
+#undef kIDByte
+#undef kIDString
+
+#ifdef HASH_ARRAY_2
+ #ifdef HASH_ARRAY_3
+ #ifdef HASH_BIG
+ #define kIDByte 0x4
+ #define kIDString TEXT("4b")
+ #else
+ #define kIDByte 0x3
+ #define kIDString TEXT("4")
+ #endif
+ #else
+ #define kIDByte 0x2
+ #define kIDString TEXT("3")
+ #endif
+#else
+ #ifdef HASH_ZIP
+ #define kIDByte 0x0
+ #define kIDString TEXT("3Z")
+ #else
+ #define kIDByte 0x1
+ #define kIDString TEXT("2")
+ #endif
+#endif
+
+#undef kIDUse3BytesByte
+#undef kIDUse3BytesString
+
+#ifdef __USE_3_BYTES
+ #define kIDUse3BytesByte 0x80
+ #define kIDUse3BytesString TEXT("T")
+#else
+ #define kIDUse3BytesByte 0x00
+ #define kIDUse3BytesString TEXT("")
+#endif
+
+// #undef kIDStringFull
+
+// #define kIDStringFull TEXT("Compress.MatchFinderHC") kIDString kIDUse3BytesString
+
+// {23170F69-40C1-278C-03XX-0000000000}
+DEFINE_GUID(HC_CLSID,
+0x23170F69, 0x40C1, 0x278C, 0x03, kIDByte | kIDUse3BytesByte,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+class CInTree2: public CInTree
+{
+ CMyComPtr<IMatchFinderCallback> m_Callback;
+ virtual void BeforeMoveBlock();
+ virtual void AfterMoveBlock();
+public:
+ void SetCallback(IMatchFinderCallback *aCallback)
+ {
+ m_Callback = aCallback;
+ }
+};
+
+class CMatchFinderHC:
+ public IMatchFinder,
+ public IMatchFinderSetCallback,
+ public CMyUnknownImp
+{
+ MY_UNKNOWN_IMP1(IMatchFinderSetCallback)
+
+ STDMETHOD(Init)(ISequentialInStream *aStream);
+ STDMETHOD_(void, ReleaseStream)();
+ STDMETHOD(MovePos)();
+ STDMETHOD_(BYTE, GetIndexByte)(UINT32 anIndex);
+ STDMETHOD_(UINT32, GetMatchLen)(UINT32 aIndex, UINT32 aBack, UINT32 aLimit);
+ STDMETHOD_(UINT32, GetNumAvailableBytes)();
+ STDMETHOD_(const BYTE *, GetPointerToCurrentPos)();
+ STDMETHOD(Create)(UINT32 aSizeHistory,
+ UINT32 aKeepAddBufferBefore, UINT32 aMatchMaxLen,
+ UINT32 aKeepAddBufferAfter);
+ STDMETHOD_(UINT32, GetLongestMatch)(UINT32 *aDistances);
+ STDMETHOD_(void, DummyLongestMatch)();
+
+ // IMatchFinderSetCallback
+ STDMETHOD(SetCallback)(IMatchFinderCallback *aCallback);
+
+private:
+ // UINT32 m_WindowReservSize;
+ CInTree2 m_MatchFinder;
+public:
+ // CMatchFinderHC(): m_WindowReservSize((1 << 19) + 256) {};
+ void SetCutValue(UINT32 aCutValue)
+ { m_MatchFinder.SetCutValue(aCutValue); }
+ /*
+ void SetWindowReservSize(UINT32 aReservWindowSize)
+ { m_WindowReservSize = aReservWindowSize; }
+ */
+};
+
+}
+
+// #endif
+
diff --git a/7zip/Compress/LZ/HashChain/HCMFMain.h b/7zip/Compress/LZ/HashChain/HCMFMain.h
new file mode 100755
index 00000000..dd428488
--- /dev/null
+++ b/7zip/Compress/LZ/HashChain/HCMFMain.h
@@ -0,0 +1,78 @@
+// HCMFMain.h
+
+#include "HCMain.h"
+
+namespace HC_NAMESPACE {
+
+void CInTree2::BeforeMoveBlock()
+{
+ if (m_Callback)
+ m_Callback->BeforeChangingBufferPos();
+ CInTree::BeforeMoveBlock();
+}
+
+void CInTree2::AfterMoveBlock()
+{
+ if (m_Callback)
+ m_Callback->AfterChangingBufferPos();
+ CInTree::AfterMoveBlock();
+}
+
+STDMETHODIMP CMatchFinderHC::Init(ISequentialInStream *aStream)
+ { return m_MatchFinder.Init(aStream); }
+
+STDMETHODIMP_(void) CMatchFinderHC::ReleaseStream()
+{
+ // m_MatchFinder.ReleaseStream();
+}
+
+STDMETHODIMP CMatchFinderHC::MovePos()
+ { return m_MatchFinder.MovePos(); }
+
+STDMETHODIMP_(BYTE) CMatchFinderHC::GetIndexByte(UINT32 anIndex)
+ { return m_MatchFinder.GetIndexByte(anIndex); }
+
+STDMETHODIMP_(UINT32) CMatchFinderHC::GetMatchLen(UINT32 aIndex,
+ UINT32 aBack, UINT32 aLimit)
+ { return m_MatchFinder.GetMatchLen(aIndex, aBack, aLimit); }
+
+STDMETHODIMP_(UINT32) CMatchFinderHC::GetNumAvailableBytes()
+ { return m_MatchFinder.GetNumAvailableBytes(); }
+
+STDMETHODIMP CMatchFinderHC::Create(UINT32 aSizeHistory,
+ UINT32 aKeepAddBufferBefore, UINT32 aMatchMaxLen,
+ UINT32 aKeepAddBufferAfter)
+{
+ UINT32 aWindowReservSize = (aSizeHistory + aKeepAddBufferBefore +
+ aMatchMaxLen + aKeepAddBufferAfter) / 2 + 256;
+ try
+ {
+ return m_MatchFinder.Create(aSizeHistory, aKeepAddBufferBefore, aMatchMaxLen,
+ aKeepAddBufferAfter, aWindowReservSize);
+ }
+ catch(...)
+ {
+ return E_OUTOFMEMORY;
+ }
+}
+
+STDMETHODIMP_(UINT32) CMatchFinderHC::GetLongestMatch(UINT32 *aDistances)
+ { return m_MatchFinder.GetLongestMatch(aDistances); }
+
+STDMETHODIMP_(void) CMatchFinderHC::DummyLongestMatch()
+ { m_MatchFinder.DummyLongestMatch(); }
+
+STDMETHODIMP_(const BYTE *) CMatchFinderHC::GetPointerToCurrentPos()
+{
+ return m_MatchFinder.GetPointerToCurrentPos();
+}
+
+// IMatchFinderSetCallback
+STDMETHODIMP CMatchFinderHC::SetCallback(IMatchFinderCallback *aCallback)
+{
+ m_MatchFinder.SetCallback(aCallback);
+ return S_OK;
+}
+
+
+}
diff --git a/7zip/Compress/LZ/HashChain/HCMain.h b/7zip/Compress/LZ/HashChain/HCMain.h
new file mode 100755
index 00000000..fbe6cb13
--- /dev/null
+++ b/7zip/Compress/LZ/HashChain/HCMain.h
@@ -0,0 +1,436 @@
+// HC.h
+
+// #include "StdAfx.h"
+
+// #include "BinTree.h"
+#include "Common/NewHandler.h"
+
+#include "Common/Defs.h"
+#include "Common/CRC.h"
+
+namespace HC_NAMESPACE {
+
+#ifdef HASH_ARRAY_2
+ static const UINT32 kHash2Size = 1 << 10;
+ #ifdef HASH_ARRAY_3
+ static const UINT32 kNumHashDirectBytes = 0;
+ static const UINT32 kNumHashBytes = 4;
+ static const UINT32 kHash3Size = 1 << 18;
+ #ifdef HASH_BIG
+ static const UINT32 kHashSize = 1 << 23;
+ #else
+ static const UINT32 kHashSize = 1 << 20;
+ #endif
+ #else
+ static const UINT32 kNumHashBytes = 3;
+ // static const UINT32 kNumHashDirectBytes = 3;
+ // static const UINT32 kHashSize = 1 << (8 * kNumHashBytes);
+ static const UINT32 kNumHashDirectBytes = 0;
+ static const UINT32 kHashSize = 1 << (16);
+ #endif
+#else
+ #ifdef HASH_ZIP
+ static const UINT32 kNumHashDirectBytes = 0;
+ static const UINT32 kNumHashBytes = 3;
+ static const UINT32 kHashSize = 1 << 16;
+ #else
+ static const UINT32 kNumHashDirectBytes = 2;
+ static const UINT32 kNumHashBytes = 2;
+ static const UINT32 kHashSize = 1 << (8 * kNumHashBytes);
+ #endif
+#endif
+
+
+CInTree::CInTree():
+ #ifdef HASH_ARRAY_2
+ _hash2(0),
+ #ifdef HASH_ARRAY_3
+ _hash3(0),
+ #endif
+ #endif
+ _hash(0),
+ _chain(0),
+ _cutValue(16)
+{
+}
+
+void CInTree::FreeMemory()
+{
+ #ifdef WIN32
+ if (_chain != 0)
+ VirtualFree(_chain, 0, MEM_RELEASE);
+ if (_hash != 0)
+ VirtualFree(_hash, 0, MEM_RELEASE);
+ #else
+ delete []_chain;
+ delete []_hash;
+ #endif
+ _chain = 0;
+ _hash = 0;
+ CLZInWindow::Free();
+}
+
+CInTree::~CInTree()
+{
+ FreeMemory();
+}
+
+HRESULT CInTree::Create(UINT32 aSizeHistory, UINT32 aKeepAddBufferBefore,
+ UINT32 aMatchMaxLen, UINT32 aKeepAddBufferAfter, UINT32 aSizeReserv)
+{
+ FreeMemory();
+ try
+ {
+ CLZInWindow::Create(aSizeHistory + aKeepAddBufferBefore,
+ aMatchMaxLen + aKeepAddBufferAfter, aSizeReserv);
+
+ if (_blockSize + 256 > kMaxValForNormalize)
+ return E_INVALIDARG;
+
+ _historySize = aSizeHistory;
+ _matchMaxLen = aMatchMaxLen;
+ _cyclicBufferSize = aSizeHistory + 1;
+
+
+ UINT32 aSize = kHashSize;
+ #ifdef HASH_ARRAY_2
+ aSize += kHash2Size;
+ #ifdef HASH_ARRAY_3
+ aSize += kHash3Size;
+ #endif
+ #endif
+
+ #ifdef WIN32
+ _chain = (CIndex *)::VirtualAlloc(0, (_cyclicBufferSize + 1) * sizeof(CIndex), MEM_COMMIT, PAGE_READWRITE);
+ if (_chain == 0)
+ throw CNewException();
+ _hash = (CIndex *)::VirtualAlloc(0, (aSize + 1) * sizeof(CIndex), MEM_COMMIT, PAGE_READWRITE);
+ if (_hash == 0)
+ throw CNewException();
+ #else
+ _chain = new CIndex[_cyclicBufferSize + 1];
+ _hash = new CIndex[aSize + 1];
+ #endif
+
+ // m_RightBase = &m_LeftBase[_blockSize];
+
+ // _hash = &m_RightBase[_blockSize];
+ #ifdef HASH_ARRAY_2
+ _hash2 = &_hash[kHashSize];
+ #ifdef HASH_ARRAY_3
+ _hash3 = &_hash2[kHash2Size];
+ #endif
+ #endif
+ return S_OK;
+ }
+ catch(...)
+ {
+ FreeMemory();
+ return E_OUTOFMEMORY;
+ }
+}
+
+static const UINT32 kEmptyHashValue = 0;
+
+HRESULT CInTree::Init(ISequentialInStream *aStream)
+{
+ RINOK(CLZInWindow::Init(aStream));
+ int i;
+ for(i = 0; i < kHashSize; i++)
+ _hash[i] = kEmptyHashValue;
+
+ #ifdef HASH_ARRAY_2
+ for(i = 0; i < kHash2Size; i++)
+ _hash2[i] = kEmptyHashValue;
+ #ifdef HASH_ARRAY_3
+ for(i = 0; i < kHash3Size; i++)
+ _hash3[i] = kEmptyHashValue;
+ #endif
+ #endif
+
+ _cyclicBufferPos = 0;
+
+ ReduceOffsets(0 - 1);
+ return S_OK;
+}
+
+
+#ifdef HASH_ARRAY_2
+#ifdef HASH_ARRAY_3
+inline UINT32 Hash(const BYTE *pointer, UINT32 &hash2Value, UINT32 &aHash3Value)
+{
+ UINT32 temp = CCRC::Table[pointer[0]] ^ pointer[1];
+ hash2Value = temp & (kHash2Size - 1);
+ aHash3Value = (temp ^ (UINT32(pointer[2]) << 8)) & (kHash3Size - 1);
+ return (temp ^ (UINT32(pointer[2]) << 8) ^ (CCRC::Table[pointer[3]] << 5)) &
+ (kHashSize - 1);
+}
+#else // no HASH_ARRAY_3
+inline UINT32 Hash(const BYTE *pointer, UINT32 &hash2Value)
+{
+ UINT32 temp = CCRC::Table[pointer[0]] ^ pointer[1];
+ hash2Value = temp & (kHash2Size - 1);
+ return (temp ^ (UINT32(pointer[2]) << 8)) & (kHashSize - 1);;
+}
+#endif // HASH_ARRAY_3
+#else // no HASH_ARRAY_2
+#ifdef HASH_ZIP
+inline UINT32 Hash(const BYTE *pointer)
+{
+ return ((UINT32(pointer[0]) << 8) ^
+ CCRC::Table[pointer[1]] ^ pointer[2]) & (kHashSize - 1);
+}
+#else // no HASH_ZIP
+inline UINT32 Hash(const BYTE *pointer)
+{
+ return pointer[0] ^ (UINT32(pointer[1]) << 8);
+}
+#endif // HASH_ZIP
+#endif // HASH_ARRAY_2
+
+
+UINT32 CInTree::GetLongestMatch(UINT32 *aDistances)
+{
+ UINT32 aCurrentLimit;
+ if (_pos + _matchMaxLen <= _streamPos)
+ aCurrentLimit = _matchMaxLen;
+ else
+ {
+ aCurrentLimit = _streamPos - _pos;
+ if(aCurrentLimit < kNumHashBytes)
+ return 0;
+ }
+
+ UINT32 aMatchMinPos = (_pos > _historySize) ? (_pos - _historySize) : 1;
+ BYTE *aCur = _buffer + _pos;
+
+ UINT32 aMatchHashLenMax = 0;
+
+ #ifdef HASH_ARRAY_2
+
+ UINT32 hash2Value;
+
+ #ifdef HASH_ARRAY_3
+
+ UINT32 aHash3Value;
+ UINT32 hashValue = Hash(aCur, hash2Value, aHash3Value);
+
+ #else // no HASH_ARRAY_3
+
+ UINT32 hashValue = Hash(aCur, hash2Value);
+
+ #endif // HASH_ARRAY_3
+
+ #else // no HASH_ARRAY_2
+
+ UINT32 hashValue = Hash(aCur);
+
+ #endif
+
+ #ifdef HASH_ARRAY_2
+
+ UINT32 aCurMatch2 = _hash2[hash2Value];
+ _hash2[hash2Value] = _pos;
+ bool aMatchLen2Exist = false;
+ UINT32 aLen2Distance = 0;
+ if(aCurMatch2 >= aMatchMinPos)
+ {
+ if (_buffer[aCurMatch2] == aCur[0])
+ {
+ aLen2Distance = _pos - aCurMatch2 - 1;
+ aMatchHashLenMax = 2;
+ aMatchLen2Exist = true;
+ }
+ }
+
+ #ifdef HASH_ARRAY_3
+
+ UINT32 aCurMatch3 = _hash3[aHash3Value];
+ _hash3[aHash3Value] = _pos;
+ UINT32 aMatchLen3Exist = false;
+ UINT32 aLen3Distance = 0;
+ if(aCurMatch3 >= aMatchMinPos)
+ {
+ if (_buffer[aCurMatch3] == aCur[0])
+ {
+ aLen3Distance = _pos - aCurMatch3 - 1;
+ aMatchHashLenMax = 3;
+ aMatchLen3Exist = true;
+ if (aMatchLen2Exist)
+ {
+ if (aLen3Distance < aLen2Distance)
+ aLen2Distance = aLen3Distance;
+ }
+ else
+ {
+ aLen2Distance = aLen3Distance;
+ aMatchLen2Exist = true;
+ }
+ }
+ }
+
+ #endif
+ #endif
+
+ UINT32 aCurMatch = _hash[hashValue];
+ _hash[hashValue] = _pos;
+ if(aCurMatch < aMatchMinPos)
+ {
+ _chain[_cyclicBufferPos] = kEmptyHashValue;
+
+ #ifdef HASH_ARRAY_2
+ aDistances[2] = aLen2Distance;
+ #ifdef HASH_ARRAY_3
+ aDistances[3] = aLen3Distance;
+ #endif
+ #endif
+
+ return aMatchHashLenMax;
+ }
+ _chain[_cyclicBufferPos] = aCurMatch;
+
+
+ #ifdef HASH_ARRAY_2
+ #ifndef HASH_ARRAY_3
+ if (aMatchLen2Exist)
+ aDistances[2] = aLen2Distance;
+ else
+ if (kNumHashDirectBytes >= 2)
+ aDistances[2] = _pos - aCurMatch - 1;
+ #endif
+ #endif
+
+ UINT32 aMax, aMinSame;
+
+ aMax = aMinSame = kNumHashDirectBytes;
+
+ aDistances[aMax] = _pos - aCurMatch - 1;
+
+ for(UINT32 aCount = _cutValue; aCount > 0; aCount--)
+ {
+ BYTE *pby1 = _buffer + aCurMatch;
+ UINT32 aCurrentLen;
+ for(aCurrentLen = aMinSame; aCurrentLen < aCurrentLimit; aCurrentLen++/*, dwComps++*/)
+ if (pby1[aCurrentLen] != aCur[aCurrentLen])
+ break;
+ if (aCurrentLen > aMax)
+ {
+ UINT32 dwBack = _pos - aCurMatch - 1;
+ for(UINT32 dwLen = aMax + 1; dwLen <= aCurrentLen; dwLen++)
+ aDistances[dwLen] = dwBack;
+ aMax = aCurrentLen;
+ }
+ if(aCurrentLen == aCurrentLimit)
+ break;
+
+ UINT32 aDelta = _pos - aCurMatch;
+ UINT32 aCyclicPos = (aDelta <= _cyclicBufferPos) ?
+ (_cyclicBufferPos - aDelta):
+ (_cyclicBufferPos - aDelta + _cyclicBufferSize);
+
+ aCurMatch = _chain[aCyclicPos];
+ if(aCurMatch < aMatchMinPos)
+ break;
+ }
+ #ifdef HASH_ARRAY_2
+ if (aMatchLen2Exist)
+ {
+ if (aMax < 2)
+ {
+ aDistances[2] = aLen2Distance;
+ aMax = 2;
+ }
+ else if (aLen2Distance < aDistances[2])
+ aDistances[2] = aLen2Distance;
+ }
+ #ifdef HASH_ARRAY_3
+ if (aMatchLen3Exist)
+ {
+ if (aMax < 3)
+ {
+ aDistances[3] = aLen3Distance;
+ aMax = 3;
+ }
+ else if (aLen3Distance < aDistances[3])
+ aDistances[3] = aLen3Distance;
+ }
+ #endif
+ #endif
+ return aMax;
+}
+
+void CInTree::DummyLongestMatch()
+{
+ UINT32 aCurrentLimit;
+ if (_pos + _matchMaxLen <= _streamPos)
+ aCurrentLimit = _matchMaxLen;
+ else
+ {
+ aCurrentLimit = _streamPos - _pos;
+ if(aCurrentLimit < kNumHashBytes)
+ return;
+ }
+ UINT32 aMatchMinPos = (_pos > _historySize) ? (_pos - _historySize) : 1;
+ BYTE *aCur = _buffer + _pos;
+
+
+ #ifdef HASH_ARRAY_2
+ UINT32 hash2Value;
+ #ifdef HASH_ARRAY_3
+ UINT32 aHash3Value;
+ UINT32 hashValue = Hash(aCur, hash2Value, aHash3Value);
+ _hash3[aHash3Value] = _pos;
+ #else
+ UINT32 hashValue = Hash(aCur, hash2Value);
+ #endif
+ _hash2[hash2Value] = _pos;
+
+
+ #else // no hash
+ UINT32 hashValue = Hash(aCur);
+ #endif
+
+ UINT32 aCurMatch = _hash[hashValue];
+ _hash[hashValue] = _pos;
+ if(aCurMatch < aMatchMinPos)
+ {
+ _chain[_cyclicBufferPos] = kEmptyHashValue;
+ return;
+ }
+ _chain[_cyclicBufferPos] = aCurMatch;
+}
+
+void CInTree::NormalizeLinks(CIndex *anArray, UINT32 aNumItems, UINT32 aSubValue)
+{
+ for (UINT32 i = 0; i < aNumItems; i++)
+ {
+ UINT32 aValue = anArray[i];
+ if (aValue <= aSubValue)
+ aValue = kEmptyHashValue;
+ else
+ aValue -= aSubValue;
+ anArray[i] = aValue;
+ }
+}
+
+void CInTree::Normalize()
+{
+ UINT32 aStartItem = _pos - _historySize;
+ UINT32 aSubValue = aStartItem - 1;
+
+ // NormalizeLinks(_chain + aStartItem, _historySize, aSubValue);
+ NormalizeLinks(_chain, _cyclicBufferSize, aSubValue);
+
+ NormalizeLinks(_hash, kHashSize, aSubValue);
+
+ #ifdef HASH_ARRAY_2
+ NormalizeLinks(_hash2, kHash2Size, aSubValue);
+ #ifdef HASH_ARRAY_3
+ NormalizeLinks(_hash3, kHash3Size, aSubValue);
+ #endif
+ #endif
+
+ ReduceOffsets(aSubValue);
+}
+
+}
diff --git a/7zip/Compress/LZ/IMatchFinder.h b/7zip/Compress/LZ/IMatchFinder.h
new file mode 100755
index 00000000..6efa8941
--- /dev/null
+++ b/7zip/Compress/LZ/IMatchFinder.h
@@ -0,0 +1,65 @@
+// MatchFinders/IMatchFinder.h
+
+// #pragma once
+
+#ifndef __IMATCHFINDER_H
+#define __IMATCHFINDER_H
+
+// {23170F69-40C1-278A-0000-000200010000}
+DEFINE_GUID(IID_IInWindowStream,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000200010000")
+IInWindowStream: public IUnknown
+{
+ STDMETHOD(Init)(ISequentialInStream *inStream) PURE;
+ STDMETHOD_(void, ReleaseStream)() PURE;
+ STDMETHOD(MovePos)() PURE;
+ STDMETHOD_(BYTE, GetIndexByte)(UINT32 index) PURE;
+ STDMETHOD_(UINT32, GetMatchLen)(UINT32 index, UINT32 distance, UINT32 limit) PURE;
+ STDMETHOD_(UINT32, GetNumAvailableBytes)() PURE;
+ STDMETHOD_(const BYTE *, GetPointerToCurrentPos)() PURE;
+};
+
+// {23170F69-40C1-278A-0000-000200020000}
+DEFINE_GUID(IID_IMatchFinder,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000200020000")
+IMatchFinder: public IInWindowStream
+{
+ STDMETHOD(Create)(UINT32 historySize, UINT32 keepAddBufferBefore,
+ UINT32 matchMaxLen, UINT32 keepAddBufferAfter) PURE;
+ STDMETHOD_(UINT32, GetLongestMatch)(UINT32 *distances) PURE;
+ STDMETHOD_(void, DummyLongestMatch)() PURE;
+};
+
+// {23170F69-40C1-278A-0000-000200020100}
+DEFINE_GUID(IID_IMatchFinderCallback,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x01, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000200020100")
+IMatchFinderCallback: public IUnknown
+{
+ STDMETHOD(BeforeChangingBufferPos)() PURE;
+ STDMETHOD(AfterChangingBufferPos)() PURE;
+};
+
+// {23170F69-40C1-278A-0000-000200020200}
+DEFINE_GUID(IID_IMatchFinderSetCallback,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x02, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000200020200")
+IMatchFinderSetCallback: public IUnknown
+{
+ STDMETHOD(SetCallback)(IMatchFinderCallback *callback) PURE;
+};
+
+/*
+// {23170F69-40C1-278A-0000-000200030000}
+DEFINE_GUID(IID_IInitMatchFinder,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000200030000")
+IMatchFinderInit: public IUnknown
+{
+ STDMETHOD(InitMatchFinder)(IMatchFinder *matchFinder) PURE;
+};
+*/
+
+#endif
diff --git a/7zip/Compress/LZ/LZInWindow.cpp b/7zip/Compress/LZ/LZInWindow.cpp
new file mode 100755
index 00000000..817ef800
--- /dev/null
+++ b/7zip/Compress/LZ/LZInWindow.cpp
@@ -0,0 +1,98 @@
+// LZInWindow.cpp
+
+#include "StdAfx.h"
+
+#include "LZInWindow.h"
+#include "../../../Common/MyCom.h"
+
+CLZInWindow::~CLZInWindow()
+{
+ Free();
+}
+
+void CLZInWindow::Free()
+{
+ delete []_bufferBase;
+ _bufferBase = 0;
+}
+
+void CLZInWindow::Create(UINT32 keepSizeBefore, UINT32 keepSizeAfter, UINT32 keepSizeReserv)
+{
+ _keepSizeBefore = keepSizeBefore;
+ _keepSizeAfter = keepSizeAfter;
+ _keepSizeReserv = keepSizeReserv;
+ _blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
+ Free();
+ _bufferBase = new BYTE[_blockSize];
+ _pointerToLastSafePosition = _bufferBase + _blockSize - keepSizeAfter;
+}
+
+
+HRESULT CLZInWindow::Init(ISequentialInStream *stream)
+{
+ _stream = stream;
+ _buffer = _bufferBase;
+ _pos = 0;
+ _streamPos = 0;
+ _streamEndWasReached = false;
+ return ReadBlock();
+}
+
+/*
+void CLZInWindow::ReleaseStream()
+{
+ _stream.Release();
+}
+*/
+
+///////////////////////////////////////////
+// ReadBlock
+
+// In State:
+// (_buffer + _streamPos) <= (_bufferBase + _blockSize)
+// Out State:
+// _posLimit <= _blockSize - _keepSizeAfter;
+// if(_streamEndWasReached == false):
+// _streamPos >= _pos + _keepSizeAfter
+// _posLimit = _streamPos - _keepSizeAfter;
+// else
+//
+
+HRESULT CLZInWindow::ReadBlock()
+{
+ if(_streamEndWasReached)
+ return S_OK;
+ while(true)
+ {
+ UINT32 size = (_bufferBase + _blockSize) - (_buffer + _streamPos);
+ if(size == 0)
+ return S_OK;
+ UINT32 numReadBytes;
+ RINOK(_stream->ReadPart(_buffer + _streamPos, size, &numReadBytes));
+ if(numReadBytes == 0)
+ {
+ _posLimit = _streamPos;
+ const BYTE *pointerToPostion = _buffer + _posLimit;
+ if(pointerToPostion > _pointerToLastSafePosition)
+ _posLimit = _pointerToLastSafePosition - _buffer;
+ _streamEndWasReached = true;
+ return S_OK;
+ }
+ _streamPos += numReadBytes;
+ if(_streamPos >= _pos + _keepSizeAfter)
+ {
+ _posLimit = _streamPos - _keepSizeAfter;
+ return S_OK;
+ }
+ }
+}
+
+void CLZInWindow::MoveBlock()
+{
+ BeforeMoveBlock();
+ UINT32 offset = (_buffer + _pos - _keepSizeBefore) - _bufferBase;
+ UINT32 numBytes = (_buffer + _streamPos) - (_bufferBase + offset);
+ memmove(_bufferBase, _bufferBase + offset, numBytes);
+ _buffer -= offset;
+ AfterMoveBlock();
+}
diff --git a/7zip/Compress/LZ/LZInWindow.h b/7zip/Compress/LZ/LZInWindow.h
new file mode 100755
index 00000000..6ae2da16
--- /dev/null
+++ b/7zip/Compress/LZ/LZInWindow.h
@@ -0,0 +1,89 @@
+// LZInWindow.h
+
+// #pragma once
+
+#ifndef __LZ_IN_WINDOW_H
+#define __LZ_IN_WINDOW_H
+
+#include "../../IStream.h"
+
+class CLZInWindow
+{
+ BYTE *_bufferBase; // pointer to buffer with data
+ ISequentialInStream *_stream;
+ UINT32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done
+ bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream
+ const BYTE *_pointerToLastSafePosition;
+protected:
+ BYTE *_buffer; // Pointer to virtual Buffer begin
+ UINT32 _blockSize; // Size of Allocated memory block
+ UINT32 _pos; // offset (from _buffer) of curent byte
+ UINT32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos
+ UINT32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos
+ UINT32 _keepSizeReserv; // how many BYTEs must be kept as reserv
+ UINT32 _streamPos; // offset (from _buffer) of first not read byte from Stream
+
+ virtual void BeforeMoveBlock() {};
+ virtual void AfterMoveBlock() {};
+ void MoveBlock();
+ virtual HRESULT ReadBlock();
+ void Free();
+public:
+ CLZInWindow(): _bufferBase(0) {}
+ ~CLZInWindow();
+ void Create(UINT32 keepSizeBefore, UINT32 keepSizeAfter,
+ UINT32 keepSizeReserv = (1<<17));
+
+ HRESULT Init(ISequentialInStream *stream);
+ // void ReleaseStream();
+
+ BYTE *GetBuffer() const { return _buffer; }
+
+ const BYTE *GetPointerToCurrentPos() const { return _buffer + _pos; }
+
+ HRESULT MovePos()
+ {
+ _pos++;
+ if (_pos > _posLimit)
+ {
+ const BYTE *pointerToPostion = _buffer + _pos;
+ if(pointerToPostion > _pointerToLastSafePosition)
+ MoveBlock();
+ return ReadBlock();
+ }
+ else
+ return S_OK;
+ }
+ // BYTE GetCurrentByte()const;
+ BYTE GetIndexByte(UINT32 index)const
+ { return _buffer[_pos + index]; }
+
+ // UINT32 GetCurPos()const { return _pos;};
+ // BYTE *GetBufferBeg()const { return _buffer;};
+
+ // index + limit have not to exceed _keepSizeAfter;
+ UINT32 GetMatchLen(UINT32 index, UINT32 back, UINT32 limit) const
+ {
+ if(_streamEndWasReached)
+ if ((_pos + index) + limit > _streamPos)
+ limit = _streamPos - (_pos + index);
+ back++;
+ BYTE *pby = _buffer + _pos + index;
+ UINT32 i;
+ for(i = 0; i < limit && pby[i] == pby[i - back]; i++);
+ return i;
+ }
+
+ UINT32 GetNumAvailableBytes() const { return _streamPos - _pos; }
+
+ void ReduceOffsets(UINT32 subValue)
+ {
+ _buffer += subValue;
+ _posLimit -= subValue;
+ _pos -= subValue;
+ _streamPos -= subValue;
+ }
+
+};
+
+#endif
diff --git a/7zip/Compress/LZ/LZOutWindow.cpp b/7zip/Compress/LZ/LZOutWindow.cpp
new file mode 100755
index 00000000..22fb4c04
--- /dev/null
+++ b/7zip/Compress/LZ/LZOutWindow.cpp
@@ -0,0 +1,83 @@
+// LZOutWindow.cpp
+
+#include "StdAfx.h"
+
+#include "LZOutWindow.h"
+
+void CLZOutWindow::Create(UINT32 windowSize)
+{
+ _pos = 0;
+ _streamPos = 0;
+ UINT32 newBlockSize = windowSize;
+ const UINT32 kMinBlockSize = 1;
+ if (newBlockSize < kMinBlockSize)
+ newBlockSize = kMinBlockSize;
+ if (_buffer != 0 && _windowSize == newBlockSize)
+ return;
+ delete []_buffer;
+ _buffer = 0;
+ _windowSize = newBlockSize;
+ _buffer = new BYTE[_windowSize];
+}
+
+CLZOutWindow::~CLZOutWindow()
+{
+ // ReleaseStream();
+ delete []_buffer;
+}
+
+/*
+void CLZOutWindow::SetWindowSize(UINT32 windowSize)
+{
+ _windowSize = windowSize;
+}
+*/
+
+void CLZOutWindow::Init(ISequentialOutStream *stream, bool solid)
+{
+ // ReleaseStream();
+ _stream = stream;
+ // _stream->AddRef();
+
+ if(!solid)
+ {
+ _streamPos = 0;
+ _pos = 0;
+ }
+}
+
+/*
+void CLZOutWindow::ReleaseStream()
+{
+ if(_stream != 0)
+ {
+ // Flush(); // Test it
+ _stream->Release();
+ _stream = 0;
+ }
+}
+*/
+
+void CLZOutWindow::FlushWithCheck()
+{
+ HRESULT result = Flush();
+ if (result != S_OK)
+ throw CLZOutWindowException(result);
+}
+
+HRESULT CLZOutWindow::Flush()
+{
+ UINT32 size = _pos - _streamPos;
+ if(size == 0)
+ return S_OK;
+ UINT32 processedSize;
+ HRESULT result = _stream->Write(_buffer + _streamPos, size, &processedSize);
+ if (result != S_OK)
+ return result;
+ if (size != processedSize)
+ return E_FAIL;
+ if (_pos >= _windowSize)
+ _pos = 0;
+ _streamPos = _pos;
+ return S_OK;
+}
diff --git a/7zip/Compress/LZ/LZOutWindow.h b/7zip/Compress/LZ/LZOutWindow.h
new file mode 100755
index 00000000..d0b392c3
--- /dev/null
+++ b/7zip/Compress/LZ/LZOutWindow.h
@@ -0,0 +1,78 @@
+// LZOutWindow.h
+
+// #pragma once
+
+#ifndef __LZ_OUT_WINDOW_H
+#define __LZ_OUT_WINDOW_H
+
+#include "../../IStream.h"
+
+// m_KeepSizeBefore: how mach BYTEs must be in buffer before _pos;
+// m_KeepSizeAfter: how mach BYTEs must be in buffer after _pos;
+// m_KeepSizeReserv: how mach BYTEs must be in buffer for Moving Reserv;
+// must be >= aKeepSizeAfter; // test it
+
+class CLZOutWindowException
+{
+public:
+ HRESULT ErrorCode;
+ CLZOutWindowException(HRESULT errorCode): ErrorCode(errorCode) {}
+};
+
+class CLZOutWindow
+{
+ BYTE *_buffer;
+ UINT32 _pos;
+ UINT32 _windowSize;
+ UINT32 _streamPos;
+ ISequentialOutStream *_stream;
+ void FlushWithCheck();
+
+public:
+ CLZOutWindow(): _buffer(0), _stream(0) {}
+ ~CLZOutWindow();
+ void Create(UINT32 windowSize);
+ bool IsCreated() const { return _buffer != 0; }
+
+ void Init(ISequentialOutStream *stream, bool solid = false);
+ HRESULT Flush();
+ // void ReleaseStream();
+
+ // UINT32 GetCurPos() const { return _pos; }
+ // const BYTE *GetPointerToCurrentPos() const { return _buffer + _pos;};
+
+ void CopyBackBlock(UINT32 distance, UINT32 len)
+ {
+ UINT32 pos = _pos - distance - 1;
+ if (pos >= _windowSize)
+ pos += _windowSize;
+ for(; len > 0; len--)
+ {
+ if (pos >= _windowSize)
+ pos = 0;
+ _buffer[_pos++] = _buffer[pos++];
+ if (_pos >= _windowSize)
+ FlushWithCheck();
+ // PutOneByte(GetOneByte(0 - distance));
+ }
+ }
+
+ void PutOneByte(BYTE b)
+ {
+ _buffer[_pos++] = b;
+ if (_pos >= _windowSize)
+ FlushWithCheck();
+ }
+
+ BYTE GetOneByte(UINT32 index) const
+ {
+ UINT32 pos = _pos + index;
+ if (pos >= _windowSize)
+ pos += _windowSize;
+ return _buffer[pos];
+ }
+
+ // BYTE *GetBuffer() const { return _buffer; }
+};
+
+#endif
diff --git a/7zip/Compress/LZ/MT/MT.cpp b/7zip/Compress/LZ/MT/MT.cpp
new file mode 100755
index 00000000..5fb76738
--- /dev/null
+++ b/7zip/Compress/LZ/MT/MT.cpp
@@ -0,0 +1,317 @@
+// MT_MF.cpp
+
+#include "StdAfx.h"
+
+#include "MT.h"
+
+class CMatchFinderCallback:
+ public IMatchFinderCallback,
+ public CMyUnknownImp
+{
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(BeforeChangingBufferPos)();
+ STDMETHOD(AfterChangingBufferPos)();
+public:
+ CMatchFinderMT *m_MatchFinderMT;
+ const BYTE *m_BufferPosBefore;
+};
+
+STDMETHODIMP CMatchFinderCallback::BeforeChangingBufferPos()
+{
+ m_MatchFinderMT->m_AskChangeBufferPos.Set();
+ m_MatchFinderMT->m_CanChangeBufferPos.Lock();
+ m_BufferPosBefore = m_MatchFinderMT->m_MatchFinder->GetPointerToCurrentPos();
+ return S_OK;
+}
+
+STDMETHODIMP CMatchFinderCallback::AfterChangingBufferPos()
+{
+ m_MatchFinderMT->m_DataCurrentPos +=
+ m_MatchFinderMT->m_MatchFinder->GetPointerToCurrentPos() - m_BufferPosBefore;
+ m_MatchFinderMT->m_BufferPosWasChanged.Set();
+ return S_OK;
+}
+
+HRESULT CMatchFinderMT::SetMatchFinder(IMatchFinder *aMatchFinder,
+ UINT32 multiThreadMult)
+{
+ _multiThreadMult = multiThreadMult;
+ m_MatchFinder = aMatchFinder;
+ CMyComPtr<IMatchFinderSetCallback> matchFinderSetCallback;
+ if (m_MatchFinder.QueryInterface(IID_IMatchFinderSetCallback,
+ &matchFinderSetCallback) == S_OK)
+ {
+ CMatchFinderCallback *matchFinderCallbackSpec =
+ new CMatchFinderCallback;
+ CMyComPtr<IMatchFinderCallback> matchFinderCallback = matchFinderCallbackSpec;
+ matchFinderCallbackSpec->m_MatchFinderMT = this;
+ matchFinderSetCallback->SetCallback(matchFinderCallback);
+ return S_OK;
+ }
+ else
+ return E_FAIL;
+}
+
+
+STDMETHODIMP CMatchFinderMT::Init(ISequentialInStream *aStream)
+{
+ // OutputDebugString("Init\n");
+ m_AskChangeBufferPos.Reset();
+ m_CanChangeBufferPos.Reset();
+ m_BufferPosWasChanged.Reset();
+ m_StopWriting.Reset();
+ m_WritingWasStopped.Reset();
+ m_NeedStart = true;
+ HRESULT aResult = m_MatchFinder->Init(aStream);
+ if (aResult == S_OK)
+ m_DataCurrentPos = m_MatchFinder->GetPointerToCurrentPos();
+ return aResult;
+}
+
+STDMETHODIMP_(void) CMatchFinderMT::ReleaseStream()
+{
+ // OutputDebugString("ReleaseStream\n");
+ m_StopWriting.Set();
+ m_WritingWasStopped.Lock();
+ // OutputDebugString("m_WritingWasStopped\n");
+ m_MatchFinder->ReleaseStream();
+}
+
+STDMETHODIMP CMatchFinderMT::MovePos()
+{
+ m_NumAvailableBytesCurrent--;
+ m_DataCurrentPos++;
+ return S_OK;
+}
+
+STDMETHODIMP_(BYTE) CMatchFinderMT::GetIndexByte(UINT32 anIndex)
+{
+ return m_DataCurrentPos[anIndex];
+}
+
+STDMETHODIMP_(UINT32) CMatchFinderMT::GetMatchLen(UINT32 aIndex,
+ UINT32 aBack, UINT32 aLimit)
+{
+ if (int(aIndex + aLimit) > m_NumAvailableBytesCurrent)
+ aLimit = m_NumAvailableBytesCurrent - (aIndex);
+ aBack++;
+ const BYTE *pby = m_DataCurrentPos + aIndex;
+ UINT32 i;
+ for(i = 0; i < aLimit && pby[i] == pby[i - aBack]; i++);
+ /*
+
+ char aSz[100];
+ sprintf(aSz, "GetMatchLen = %d", i);
+ OutputDebugString(aSz);
+ OutputDebugString("\n");
+ */
+ return i;
+ // return m_MatchFinder->GetMatchLen(aIndex, aBack, aLimit); }
+}
+
+STDMETHODIMP_(const BYTE *) CMatchFinderMT::GetPointerToCurrentPos()
+{
+ return m_DataCurrentPos;
+}
+
+
+STDMETHODIMP_(UINT32) CMatchFinderMT::GetNumAvailableBytes()
+{
+ if (m_NeedStart)
+ return m_MatchFinder->GetNumAvailableBytes();
+ else
+ return m_NumAvailableBytesCurrent;
+}
+
+void CMatchFinderMT::FreeMem()
+{
+ delete []m_Buffer;
+}
+
+STDMETHODIMP CMatchFinderMT::Create(UINT32 aSizeHistory,
+ UINT32 aKeepAddBufferBefore, UINT32 matchMaxLen,
+ UINT32 aKeepAddBufferAfter)
+{
+ FreeMem();
+ m_MatchMaxLen = matchMaxLen;
+
+ m_BlockSize = (matchMaxLen + 1) * _multiThreadMult;
+ UINT32 aBufferSize = m_BlockSize * kNumMTBlocks;
+ m_Buffer = new UINT32[aBufferSize];
+ for (int i = 0; i < kNumMTBlocks; i++)
+ m_Buffers[i] = &m_Buffer[i * m_BlockSize];
+
+ m_NeedStart = true;
+
+ aKeepAddBufferBefore += aBufferSize;
+
+ return m_MatchFinder->Create(aSizeHistory,
+ aKeepAddBufferBefore, matchMaxLen,
+ aKeepAddBufferAfter);
+}
+
+static DWORD WINAPI MFThread(void *aThreadCoderInfo)
+{
+ CMatchFinderMT &aMT = *(CMatchFinderMT *)aThreadCoderInfo;
+ while (true)
+ {
+ HANDLE anEvents[3] = { aMT.m_ExitEvent, aMT.m_StopWriting, aMT.m_CanWriteEvents[aMT.m_WriteBufferIndex] } ;
+ DWORD anWaitResult = ::WaitForMultipleObjects(3, anEvents, FALSE, INFINITE);
+ if (anWaitResult == WAIT_OBJECT_0 + 0)
+ return 0;
+ if (anWaitResult == WAIT_OBJECT_0 + 1)
+ {
+ // OutputDebugString("m_StopWriting\n");
+ aMT.m_WriteBufferIndex = 0;
+ for (int i = 0; i < kNumMTBlocks; i++)
+ aMT.m_CanWriteEvents[i].Reset();
+ aMT.m_WritingWasStopped.Set();
+ continue;
+ }
+ // OutputDebugString("m_CanWriteEvents\n");
+ UINT32 *aBuffer = aMT.m_Buffers[aMT.m_WriteBufferIndex];
+ UINT32 aCurPos = 0;
+ UINT32 aNumBytes = 0;
+ while (aCurPos + aMT.m_MatchMaxLen + 1 <= aMT.m_BlockSize)
+ {
+ if (aMT.m_MatchFinder->GetNumAvailableBytes() == 0)
+ break;
+ UINT32 aLen = aMT.m_MatchFinder->GetLongestMatch(aBuffer + aCurPos);
+ /*
+ if (aLen == 1)
+ aLen = 0;
+ */
+ aBuffer[aCurPos] = aLen;
+ aCurPos += aLen + 1;
+ HRESULT aResult = aMT.m_MatchFinder->MovePos();
+ if (aResult != S_OK)
+ throw 124459;
+ aNumBytes++;
+ }
+ aMT.m_LimitPos[aMT.m_WriteBufferIndex] = aCurPos;
+ aMT.m_NumAvailableBytes[aMT.m_WriteBufferIndex] =
+ aNumBytes + aMT.m_MatchFinder->GetNumAvailableBytes();
+ // char aSz[100];
+ // sprintf(aSz, "x = %d", aMT.m_WriteBufferIndex);
+ // OutputDebugString(aSz);
+ // OutputDebugString("aMT.m_CanReadEvents\n");
+ aMT.m_CanReadEvents[aMT.m_WriteBufferIndex].Set();
+ aMT.m_WriteBufferIndex++;
+ if (aMT.m_WriteBufferIndex == kNumMTBlocks)
+ aMT.m_WriteBufferIndex = 0;
+ }
+
+ /*
+ while(true)
+ {
+ if (!((CCoderMixer2 *)aThreadCoderInfo)->MyCode())
+ return 0;
+ }
+ */
+}
+
+CMatchFinderMT::CMatchFinderMT():
+ m_Buffer(0),
+ _multiThreadMult(100)
+{
+ for (int i = 0; i < kNumMTBlocks; i++)
+ {
+ m_CanReadEvents[i].Reset();
+ m_CanWriteEvents[i].Reset();
+ }
+ m_ReadBufferIndex = 0;
+ m_WriteBufferIndex = 0;
+
+ m_ExitEvent.Reset();
+ if (!m_Thread.Create(MFThread, this))
+ throw 271826;
+}
+CMatchFinderMT::~CMatchFinderMT()
+{
+ m_ExitEvent.Set();
+ if (HANDLE(m_Thread) != 0)
+ ::WaitForSingleObject(m_Thread, INFINITE);
+ FreeMem();
+}
+
+void CMatchFinderMT::Start()
+{
+ // OutputDebugString("Start\n");
+ m_AskChangeBufferPos.Reset();
+ m_CanChangeBufferPos.Reset();
+ m_BufferPosWasChanged.Reset();
+
+ m_WriteBufferIndex = 0;
+ m_ReadBufferIndex = 0;
+ m_NeedStart = false;
+ m_CurrentPos = 0;
+ m_CurrentLimitPos = 0;
+ int i;
+ for (i = 0; i < kNumMTBlocks; i++)
+ m_CanReadEvents[i].Reset();
+ for (i = kNumMTBlocks - 1; i >= 0; i--)
+ m_CanWriteEvents[i].Set();
+}
+
+STDMETHODIMP_(UINT32) CMatchFinderMT::GetLongestMatch(UINT32 *aDistances)
+{
+ // OutputDebugString("GetLongestMatch\n");
+ if (m_NeedStart)
+ Start();
+ /*
+ if (m_CurrentPos > m_CurrentLimitPos)
+ throw 1123324;
+ */
+ if (m_CurrentPos == m_CurrentLimitPos)
+ {
+ // OutputDebugString("m_CurrentPos == m_CurrentLimitPos\n");
+ while (true)
+ {
+ /*
+ char aSz[100];
+ sprintf(aSz, "m_CanReadEvents[m_ReadBufferIndex] = %d\n", m_ReadBufferIndex);
+ OutputDebugString(aSz);
+ OutputDebugString("\n");
+ */
+ HANDLE anEvents[2] = { m_AskChangeBufferPos, m_CanReadEvents[m_ReadBufferIndex] } ;
+ DWORD anWaitResult = ::WaitForMultipleObjects(2, anEvents, FALSE, INFINITE);
+ if (anWaitResult == WAIT_OBJECT_0 + 1)
+ break;
+ m_BufferPosWasChanged.Reset();
+ m_CanChangeBufferPos.Set();
+ m_BufferPosWasChanged.Lock();
+ }
+
+ m_CurrentLimitPos = m_LimitPos[m_ReadBufferIndex];
+ m_NumAvailableBytesCurrent = m_NumAvailableBytes[m_ReadBufferIndex];
+ m_CurrentPos = 0;
+ }
+ if (m_CurrentPos >= m_CurrentLimitPos)
+ throw 1123324;
+ const UINT32 *aBuffer = m_Buffers[m_ReadBufferIndex];
+ UINT32 aLen = aBuffer[m_CurrentPos++];
+ for (UINT32 i = 1; i <= aLen; i++)
+ aDistances[i] = aBuffer[m_CurrentPos++];
+ if (m_CurrentPos == m_CurrentLimitPos)
+ {
+ m_CanWriteEvents[m_ReadBufferIndex].Set();
+ m_ReadBufferIndex++;
+ if (m_ReadBufferIndex == kNumMTBlocks)
+ m_ReadBufferIndex = 0;
+ }
+ // char aSz[100];
+ // sprintf(aSz, "m_NumAvailableBytesCurrent = %d", m_NumAvailableBytesCurrent);
+ // OutputDebugString(aSz);
+ // OutputDebugString("\n");
+ return aLen;
+}
+
+STDMETHODIMP_(void) CMatchFinderMT::DummyLongestMatch()
+{
+ UINT32 aBuffer[512];
+ GetLongestMatch(aBuffer);
+ // m_MatchFinder->DummyLongestMatch();
+}
+
+
diff --git a/7zip/Compress/LZ/MT/MT.h b/7zip/Compress/LZ/MT/MT.h
new file mode 100755
index 00000000..40b140ff
--- /dev/null
+++ b/7zip/Compress/LZ/MT/MT.h
@@ -0,0 +1,85 @@
+// MT_MF.h
+
+#pragma once
+
+#ifndef __MT_MF_H
+#define __MT_MF_H
+
+#include "Common/MyCom.h"
+
+#include "Windows/Thread.h"
+#include "Windows/Synchronization.h"
+
+#include "../../../ICoder.h"
+#include "../IMatchFinder.h"
+
+const int kNumMTBlocks = 3;
+
+class CMatchFinderMT:
+ public IMatchFinder,
+ public CMyUnknownImp
+{
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(Init)(ISequentialInStream *aStream);
+ STDMETHOD_(void, ReleaseStream)();
+ STDMETHOD(MovePos)();
+ STDMETHOD_(BYTE, GetIndexByte)(UINT32 anIndex);
+ STDMETHOD_(UINT32, GetMatchLen)(UINT32 aIndex, UINT32 aBack, UINT32 aLimit);
+ STDMETHOD_(UINT32, GetNumAvailableBytes)();
+ STDMETHOD_(const BYTE *, GetPointerToCurrentPos)();
+ STDMETHOD(Create)(UINT32 aSizeHistory,
+ UINT32 aKeepAddBufferBefore, UINT32 aMatchMaxLen,
+ UINT32 aKeepAddBufferAfter);
+ STDMETHOD_(UINT32, GetLongestMatch)(UINT32 *aDistances);
+ STDMETHOD_(void, DummyLongestMatch)();
+
+private:
+public:
+ CMyComPtr<IMatchFinder> m_MatchFinder;
+ UINT32 m_MatchMaxLen;
+
+ UINT32 m_BlockSize;
+ // UINT32 m_BufferSize;
+ UINT32 *m_Buffer;
+ UINT32 *m_Buffers[kNumMTBlocks];
+
+ bool m_NeedStart;
+ UINT32 m_WriteBufferIndex;
+ UINT32 m_ReadBufferIndex;
+
+ NWindows::NSynchronization::CAutoResetEvent m_StopWriting;
+ NWindows::NSynchronization::CAutoResetEvent m_WritingWasStopped;
+
+ NWindows::NSynchronization::CAutoResetEvent m_AskChangeBufferPos;
+ NWindows::NSynchronization::CAutoResetEvent m_CanChangeBufferPos;
+ NWindows::NSynchronization::CAutoResetEvent m_BufferPosWasChanged;
+
+ NWindows::NSynchronization::CManualResetEvent m_ExitEvent;
+ // NWindows::NSynchronization::CManualResetEvent m_NewStart;
+ NWindows::NSynchronization::CAutoResetEvent m_CanReadEvents[kNumMTBlocks];
+ NWindows::NSynchronization::CAutoResetEvent m_CanWriteEvents[kNumMTBlocks];
+ UINT32 m_LimitPos[kNumMTBlocks];
+ UINT32 m_NumAvailableBytes[kNumMTBlocks];
+
+ UINT32 m_NumAvailableBytesCurrent;
+ const BYTE *m_DataCurrentPos;
+
+ UINT32 m_CurrentLimitPos;
+ UINT32 m_CurrentPos;
+
+ NWindows::CThread m_Thread;
+ // bool m_WriteWasClosed;
+ UINT32 _multiThreadMult;
+public:
+ CMatchFinderMT();
+ ~CMatchFinderMT();
+ void Start();
+ void FreeMem();
+ HRESULT SetMatchFinder(IMatchFinder *aMatchFinder,
+ UINT32 multiThreadMult = 200);
+};
+
+
+#endif
+
diff --git a/7zip/Compress/LZ/MT/StdAfx.h b/7zip/Compress/LZ/MT/StdAfx.h
new file mode 100755
index 00000000..a32fbed6
--- /dev/null
+++ b/7zip/Compress/LZ/MT/StdAfx.h
@@ -0,0 +1,8 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#endif
diff --git a/7zip/Compress/LZ/Patricia/Pat.h b/7zip/Compress/LZ/Patricia/Pat.h
new file mode 100755
index 00000000..50acb686
--- /dev/null
+++ b/7zip/Compress/LZ/Patricia/Pat.h
@@ -0,0 +1,364 @@
+// Pat.h
+
+// #pragma once
+
+// #ifndef __PATRICIA__H
+// #define __PATRICIA__H
+
+#include "../../../../Common/AlignedBuffer.h"
+#include "../../../../Common/MyCom.h"
+#include "../LZInWindow.h"
+
+namespace PAT_NAMESPACE {
+
+struct CNode;
+
+typedef CNode *CNodePointer;
+
+#pragma pack(push, PragmaPatrTree)
+#pragma pack(push, 1)
+
+// #define __AUTO_REMOVE
+
+// #define __USE_3_BYTES
+
+// #define __NODE_4_BITS
+// #define __NODE_3_BITS
+// #define __NODE_2_BITS
+// #define __NODE_2_BITS_PADDING
+
+// #define __HASH_3
+
+
+#ifdef __USE_3_BYTES
+struct CIndex
+{
+ BYTE Data[3];
+ operator =(UINT32 aValue)
+ {
+ Data[0] = aValue & 0xFF;
+ Data[1] = (aValue >> 8) & 0xFF;
+ Data[2] = (aValue >> 16) & 0xFF;
+ }
+ operator UINT32() const { return (*((const UINT32 *)Data)) & 0xFFFFFF; }
+};
+#else
+ typedef UINT32 CIndex;
+#endif
+
+
+#pragma pack(pop)
+#pragma pack(pop, PragmaPatrTree)
+
+#ifdef __NODE_4_BITS
+ typedef UINT32 CIndex2;
+ typedef UINT32 CSameBitsType;
+#else
+#ifdef __NODE_3_BITS
+ typedef UINT32 CIndex2;
+ typedef UINT32 CSameBitsType;
+#else
+
+ #ifdef __USE_3_BYTES
+ typedef BYTE CSameBitsType;
+ #else
+ typedef UINT32 CIndex;
+ typedef UINT32 CSameBitsType;
+ #endif
+
+ typedef CIndex CIndex2;
+#endif
+#endif
+
+const UINT32 kNumBitsInIndex = sizeof(CIndex) * 8;
+const UINT32 kMatchStartValue = UINT32(1) << (kNumBitsInIndex - 1);
+
+typedef CIndex CMatchPointer;
+
+const UINT32 kDescendantEmptyValue = kMatchStartValue - 1;
+
+#pragma pack(push, PragmaPatrTree2)
+#pragma pack(push, 1)
+
+union CDescendant
+{
+ CIndex NodePointer;
+ CMatchPointer MatchPointer;
+ bool IsEmpty() const { return NodePointer == kDescendantEmptyValue; }
+ bool IsNode() const { return NodePointer < kDescendantEmptyValue; }
+ bool IsMatch() const { return NodePointer > kDescendantEmptyValue; }
+ void MakeEmpty() { NodePointer = kDescendantEmptyValue; }
+};
+
+#pragma pack(pop)
+#pragma pack(pop, PragmaPatrTree2)
+
+#pragma pack( push, PragmaBackNode)
+#pragma pack( push, 1)
+
+#undef MY_BYTE_SIZE
+
+#ifdef __NODE_4_BITS
+ #define MY_BYTE_SIZE 8
+ const UINT32 kNumSubBits = 4;
+#else
+#ifdef __NODE_3_BITS
+ #define MY_BYTE_SIZE 9
+ const UINT32 kNumSubBits = 3;
+#else
+ #define MY_BYTE_SIZE 8
+ #ifdef __NODE_2_BITS
+ const UINT32 kNumSubBits = 2;
+ #else
+ const UINT32 kNumSubBits = 1;
+ #endif
+#endif
+#endif
+
+const UINT32 kNumSubNodes = 1 << kNumSubBits;
+const UINT32 kSubNodesMask = kNumSubNodes - 1;
+
+struct CNode
+{
+ CIndex2 LastMatch;
+ CSameBitsType NumSameBits;
+ union
+ {
+ CDescendant Descendants[kNumSubNodes];
+ UINT32 NextFreeNode;
+ };
+ #ifdef __NODE_2_BITS
+ #ifdef __NODE_2_BITS_PADDING
+ UINT32 Padding[2];
+ #endif
+ #endif
+};
+
+#pragma pack(pop)
+#pragma pack(pop, PragmaBackNode)
+
+#undef kIDNumBitsByte
+#undef kIDNumBitsString
+
+#ifdef __NODE_4_BITS
+ #define kIDNumBitsByte 0x30
+ #define kIDNumBitsString TEXT("4")
+#else
+#ifdef __NODE_3_BITS
+ #define kIDNumBitsByte 0x20
+ #define kIDNumBitsString TEXT("3")
+#else
+#ifdef __NODE_2_BITS
+ #define kIDNumBitsByte 0x10
+ #define kIDNumBitsString TEXT("2")
+#else
+ #define kIDNumBitsByte 0x00
+ #define kIDNumBitsString TEXT("1")
+#endif
+#endif
+#endif
+
+#undef kIDManualRemoveByte
+#undef kIDManualRemoveString
+
+#ifdef __AUTO_REMOVE
+ #define kIDManualRemoveByte 0x00
+ #define kIDManualRemoveString TEXT("")
+#else
+ #define kIDManualRemoveByte 0x08
+ #define kIDManualRemoveString TEXT("R")
+#endif
+
+#undef kIDHash3Byte
+#undef kIDHash3String
+
+#ifdef __HASH_3
+ #define kIDHash3Byte 0x04
+ #define kIDHash3String TEXT("H")
+#else
+ #define kIDHash3Byte 0x00
+ #define kIDHash3String TEXT("")
+#endif
+
+#undef kIDUse3BytesByte
+#undef kIDUse3BytesString
+
+#ifdef __USE_3_BYTES
+ #define kIDUse3BytesByte 0x02
+ #define kIDUse3BytesString TEXT("T")
+#else
+ #define kIDUse3BytesByte 0x00
+ #define kIDUse3BytesString TEXT("")
+#endif
+
+#undef kIDPaddingByte
+#undef kIDPaddingString
+
+#ifdef __NODE_2_BITS_PADDING
+ #define kIDPaddingByte 0x01
+ #define kIDPaddingString TEXT("P")
+#else
+ #define kIDPaddingByte 0x00
+ #define kIDPaddingString TEXT("")
+#endif
+
+
+// #undef kIDString
+// #define kIDString TEXT("Compress.MatchFinderPat") kIDNumBitsString kIDManualRemoveString kIDUse3BytesString kIDPaddingString kIDHash3String
+
+// {23170F69-40C1-278C-01XX-0000000000}
+
+DEFINE_GUID(PAT_CLSID,
+0x23170F69, 0x40C1, 0x278C, 0x01,
+kIDNumBitsByte |
+kIDManualRemoveByte | kIDHash3Byte | kIDUse3BytesByte | kIDPaddingByte,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+// III(PAT_NAMESPACE)
+
+class CPatricia:
+ public IMatchFinder,
+ public IMatchFinderSetCallback,
+ public CMyUnknownImp,
+ CLZInWindow
+{
+ MY_UNKNOWN_IMP1(IMatchFinderSetCallback)
+
+ STDMETHOD(Init)(ISequentialInStream *aStream);
+ STDMETHOD_(void, ReleaseStream)();
+ STDMETHOD(MovePos)();
+ STDMETHOD_(BYTE, GetIndexByte)(UINT32 anIndex);
+ STDMETHOD_(UINT32, GetMatchLen)(UINT32 aIndex, UINT32 aBack, UINT32 aLimit);
+ STDMETHOD_(UINT32, GetNumAvailableBytes)();
+ STDMETHOD(Create)(UINT32 aSizeHistory,
+ UINT32 aKeepAddBufferBefore, UINT32 aMatchMaxLen,
+ UINT32 aKeepAddBufferAfter);
+ STDMETHOD_(UINT32, GetLongestMatch)(UINT32 *aDistances);
+ STDMETHOD_(void, DummyLongestMatch)();
+ STDMETHOD_(const BYTE *, GetPointerToCurrentPos)();
+
+ void FreeMemory();
+public:
+ CPatricia();
+ ~CPatricia();
+
+ UINT32 _sizeHistory;
+ UINT32 _matchMaxLen;
+
+ CDescendant *m_HashDescendants;
+ #ifdef __HASH_3
+ CDescendant *m_Hash2Descendants;
+ #endif
+
+ CNode *m_Nodes;
+
+ UINT32 m_FreeNode;
+ UINT32 m_FreeNodeMax;
+
+ #ifdef __AUTO_REMOVE
+ UINT32 m_NumUsedNodes;
+ UINT32 m_NumNodes;
+ #else
+ bool m_SpecialRemoveMode;
+ #endif
+
+ bool m_SpecialMode;
+ UINT32 m_NumNotChangedCycles;
+ UINT32 *m_TmpBacks;
+
+ CAlignedBuffer m_AlignBuffer;
+
+ CMyComPtr<IMatchFinderCallback> m_Callback;
+
+ virtual void BeforeMoveBlock();
+ virtual void AfterMoveBlock();
+
+ // IMatchFinderSetCallback
+ STDMETHOD(SetCallback)(IMatchFinderCallback *aCallback);
+
+ void ChangeLastMatch(UINT32 aHashValue);
+
+ #ifdef __AUTO_REMOVE
+ void TestRemoveDescendant(CDescendant &aDescendant, UINT32 aLimitPos);
+ void TestRemoveNodes();
+ void RemoveNode(UINT32 anIndex);
+ void TestRemoveAndNormalizeDescendant(CDescendant &aDescendant,
+ UINT32 aLimitPos, UINT32 aSubValue);
+ void TestRemoveNodesAndNormalize();
+ #else
+ void NormalizeDescendant(CDescendant &aDescendant, UINT32 aSubValue);
+ void Normalize();
+ void RemoveMatch();
+ #endif
+private:
+ void AddInternalNode(CNodePointer aNode, CIndex *aNodePointerPointer,
+ BYTE aByte, BYTE aByteXOR, UINT32 aNumSameBits, UINT32 aPos)
+ {
+ while((aByteXOR & kSubNodesMask) == 0)
+ {
+ aByteXOR >>= kNumSubBits;
+ aByte >>= kNumSubBits;
+ aNumSameBits -= kNumSubBits;
+ }
+ // Insert New Node
+ CNodePointer aNewNode = &m_Nodes[m_FreeNode];
+ UINT32 aNodeIndex = *aNodePointerPointer;
+ *aNodePointerPointer = m_FreeNode;
+ m_FreeNode = aNewNode->NextFreeNode;
+ #ifdef __AUTO_REMOVE
+ m_NumUsedNodes++;
+ #endif
+ if (m_FreeNode > m_FreeNodeMax)
+ {
+ m_FreeNodeMax = m_FreeNode;
+ m_Nodes[m_FreeNode].NextFreeNode = m_FreeNode + 1;
+ }
+
+ UINT32 aBitsNew = aByte & kSubNodesMask;
+ UINT32 aBitsOld = (aByte ^ aByteXOR) & kSubNodesMask;
+ for (UINT32 i = 0; i < kNumSubNodes; i++)
+ aNewNode->Descendants[i].NodePointer = kDescendantEmptyValue;
+ aNewNode->Descendants[aBitsNew].MatchPointer = aPos + kMatchStartValue;
+ aNewNode->Descendants[aBitsOld].NodePointer = aNodeIndex;
+ aNewNode->NumSameBits = CSameBitsType(aNode->NumSameBits - aNumSameBits);
+ aNewNode->LastMatch = aPos;
+
+ aNode->NumSameBits = CSameBitsType(aNumSameBits - kNumSubBits);
+ }
+
+ void AddLeafNode(CNodePointer aNode, BYTE aByte, BYTE aByteXOR,
+ UINT32 aNumSameBits, UINT32 aPos, UINT32 aDescendantIndex)
+ {
+ for(;(aByteXOR & kSubNodesMask) == 0; aNumSameBits += kNumSubBits)
+ {
+ aByte >>= kNumSubBits;
+ aByteXOR >>= kNumSubBits;
+ }
+ UINT32 aNewNodeIndex = m_FreeNode;
+ CNodePointer aNewNode = &m_Nodes[m_FreeNode];
+ m_FreeNode = aNewNode->NextFreeNode;
+ #ifdef __AUTO_REMOVE
+ m_NumUsedNodes++;
+ #endif
+ if (m_FreeNode > m_FreeNodeMax)
+ {
+ m_FreeNodeMax = m_FreeNode;
+ m_Nodes[m_FreeNode].NextFreeNode = m_FreeNode + 1;
+ }
+
+ UINT32 aBitsNew = (aByte & kSubNodesMask);
+ UINT32 aBitsOld = (aByte ^ aByteXOR) & kSubNodesMask;
+ for (UINT32 i = 0; i < kNumSubNodes; i++)
+ aNewNode->Descendants[i].NodePointer = kDescendantEmptyValue;
+ aNewNode->Descendants[aBitsNew].MatchPointer = aPos + kMatchStartValue;
+ aNewNode->Descendants[aBitsOld].MatchPointer =
+ aNode->Descendants[aDescendantIndex].MatchPointer;
+ aNewNode->NumSameBits = CSameBitsType(aNumSameBits);
+ aNewNode->LastMatch = aPos;
+ aNode->Descendants[aDescendantIndex].NodePointer = aNewNodeIndex;
+ }
+};
+
+}
+
+// #endif
diff --git a/7zip/Compress/LZ/Patricia/Pat2.h b/7zip/Compress/LZ/Patricia/Pat2.h
new file mode 100755
index 00000000..df25f0c7
--- /dev/null
+++ b/7zip/Compress/LZ/Patricia/Pat2.h
@@ -0,0 +1,24 @@
+// Pat2.h
+
+#pragma once
+
+#ifndef __PAT2__H
+#define __PAT2__H
+
+#undef PAT_CLSID
+#define PAT_CLSID CLSID_CMatchFinderPat2
+
+#undef PAT_NAMESPACE
+#define PAT_NAMESPACE NPat2
+
+#define __AUTO_REMOVE
+#define __NODE_2_BITS
+
+#include "Pat.h"
+#include "PatMain.h"
+
+#undef __AUTO_REMOVE
+#undef __NODE_2_BITS
+
+#endif
+
diff --git a/7zip/Compress/LZ/Patricia/Pat2H.h b/7zip/Compress/LZ/Patricia/Pat2H.h
new file mode 100755
index 00000000..51f5180f
--- /dev/null
+++ b/7zip/Compress/LZ/Patricia/Pat2H.h
@@ -0,0 +1,26 @@
+// Pat2H.h
+
+#pragma once
+
+#ifndef __PAT2H__H
+#define __PAT2H__H
+
+#undef PAT_CLSID
+#define PAT_CLSID CLSID_CMatchFinderPat2H
+
+#undef PAT_NAMESPACE
+#define PAT_NAMESPACE NPat2H
+
+#define __AUTO_REMOVE
+#define __NODE_2_BITS
+#define __HASH_3
+
+#include "Pat.h"
+#include "PatMain.h"
+
+#undef __AUTO_REMOVE
+#undef __NODE_2_BITS
+#undef __HASH_3
+
+#endif
+
diff --git a/7zip/Compress/LZ/Patricia/Pat2R.h b/7zip/Compress/LZ/Patricia/Pat2R.h
new file mode 100755
index 00000000..f6af9191
--- /dev/null
+++ b/7zip/Compress/LZ/Patricia/Pat2R.h
@@ -0,0 +1,22 @@
+// Pat2R.h
+
+#pragma once
+
+#ifndef __PAT2R__H
+#define __PAT2R__H
+
+#undef PAT_CLSID
+#define PAT_CLSID CLSID_CMatchFinderPat2R
+
+#undef PAT_NAMESPACE
+#define PAT_NAMESPACE NPat2R
+
+#define __NODE_2_BITS
+
+#include "Pat.h"
+#include "PatMain.h"
+
+#undef __NODE_2_BITS
+
+#endif
+
diff --git a/7zip/Compress/LZ/Patricia/Pat3H.h b/7zip/Compress/LZ/Patricia/Pat3H.h
new file mode 100755
index 00000000..170ebf6b
--- /dev/null
+++ b/7zip/Compress/LZ/Patricia/Pat3H.h
@@ -0,0 +1,26 @@
+// Pat3H.h
+
+#pragma once
+
+#ifndef __PAT3H__H
+#define __PAT3H__H
+
+#undef PAT_CLSID
+#define PAT_CLSID CLSID_CMatchFinderPat3H
+
+#undef PAT_NAMESPACE
+#define PAT_NAMESPACE NPat3H
+
+#define __AUTO_REMOVE
+#define __NODE_3_BITS
+#define __HASH_3
+
+#include "Pat.h"
+#include "PatMain.h"
+
+#undef __AUTO_REMOVE
+#undef __NODE_3_BITS
+#undef __HASH_3
+
+#endif
+
diff --git a/7zip/Compress/LZ/Patricia/Pat4H.h b/7zip/Compress/LZ/Patricia/Pat4H.h
new file mode 100755
index 00000000..15fa2bc2
--- /dev/null
+++ b/7zip/Compress/LZ/Patricia/Pat4H.h
@@ -0,0 +1,26 @@
+// Pat4H.h
+
+#pragma once
+
+#ifndef __PAT4H__H
+#define __PAT4H__H
+
+#undef PAT_CLSID
+#define PAT_CLSID CLSID_CMatchFinderPat4H
+
+#undef PAT_NAMESPACE
+#define PAT_NAMESPACE NPat4H
+
+#define __AUTO_REMOVE
+#define __NODE_4_BITS
+#define __HASH_3
+
+#include "Pat.h"
+#include "PatMain.h"
+
+#undef __AUTO_REMOVE
+#undef __NODE_4_BITS
+#undef __HASH_3
+
+#endif
+
diff --git a/7zip/Compress/LZ/Patricia/PatMain.h b/7zip/Compress/LZ/Patricia/PatMain.h
new file mode 100755
index 00000000..2b75341e
--- /dev/null
+++ b/7zip/Compress/LZ/Patricia/PatMain.h
@@ -0,0 +1,976 @@
+// PatMain.h
+
+#include "../../../../Common/Defs.h"
+#include "../../../../Common/NewHandler.h"
+
+namespace PAT_NAMESPACE {
+
+STDMETHODIMP CPatricia::SetCallback(IMatchFinderCallback *aCallback)
+{
+ m_Callback = aCallback;
+ return S_OK;
+}
+
+void CPatricia::BeforeMoveBlock()
+{
+ if (m_Callback)
+ m_Callback->BeforeChangingBufferPos();
+ CLZInWindow::BeforeMoveBlock();
+}
+
+void CPatricia::AfterMoveBlock()
+{
+ if (m_Callback)
+ m_Callback->AfterChangingBufferPos();
+ CLZInWindow::AfterMoveBlock();
+}
+
+const UINT32 kMatchStartValue2 = 2;
+const UINT32 kDescendantEmptyValue2 = kMatchStartValue2 - 1;
+const UINT32 kDescendantsNotInitilized2 = kDescendantEmptyValue2 - 1;
+
+#ifdef __HASH_3
+
+static const UINT32 kNumHashBytes = 3;
+static const UINT32 kHashSize = 1 << (8 * kNumHashBytes);
+
+static const UINT32 kNumHash2Bytes = 2;
+static const UINT32 kHash2Size = 1 << (8 * kNumHash2Bytes);
+static const UINT32 kPrevHashSize = kNumHash2Bytes;
+
+#else
+
+static const UINT32 kNumHashBytes = 2;
+static const UINT32 kHashSize = 1 << (8 * kNumHashBytes);
+static const UINT32 kPrevHashSize = 0;
+
+#endif
+
+
+CPatricia::CPatricia():
+ m_HashDescendants(0),
+ #ifdef __HASH_3
+ m_Hash2Descendants(0),
+ #endif
+ m_TmpBacks(0),
+ m_Nodes(0)
+{
+}
+
+CPatricia::~CPatricia()
+{
+ FreeMemory();
+}
+
+void CPatricia::FreeMemory()
+{
+ delete []m_TmpBacks;
+ m_TmpBacks = 0;
+
+ #ifdef WIN32
+ if (m_Nodes != 0)
+ VirtualFree(m_Nodes, 0, MEM_RELEASE);
+ m_Nodes = 0;
+ #else
+ m_AlignBuffer.Free();
+ #endif
+
+ delete []m_HashDescendants;
+ m_HashDescendants = 0;
+
+ #ifdef __HASH_3
+
+ delete []m_Hash2Descendants;
+ m_Hash2Descendants = 0;
+
+ #endif
+}
+
+STDMETHODIMP CPatricia::Create(UINT32 aSizeHistory, UINT32 aKeepAddBufferBefore,
+ UINT32 aMatchMaxLen, UINT32 aKeepAddBufferAfter)
+{
+ FreeMemory();
+ const int kNumBitsInNumSameBits = sizeof(CSameBitsType) * 8;
+ if (kNumBitsInNumSameBits < 32 && ((aMatchMaxLen * MY_BYTE_SIZE) > (1 << kNumBitsInNumSameBits)))
+ return E_INVALIDARG;
+
+ const UINT32 kAlignMask = (1 << 16) - 1;
+ UINT32 aWindowReservSize = aSizeHistory;
+ aWindowReservSize += kAlignMask;
+ aWindowReservSize &= ~(kAlignMask);
+
+ const UINT32 kMinReservSize = (1 << 19);
+ if (aWindowReservSize < kMinReservSize)
+ aWindowReservSize = kMinReservSize;
+ aWindowReservSize += 256;
+
+ try
+ {
+ CLZInWindow::Create(aSizeHistory + aKeepAddBufferBefore,
+ aMatchMaxLen + aKeepAddBufferAfter, aWindowReservSize);
+ _sizeHistory = aSizeHistory;
+ _matchMaxLen = aMatchMaxLen;
+ m_HashDescendants = new CDescendant[kHashSize + 1];
+ #ifdef __HASH_3
+ m_Hash2Descendants = new CDescendant[kHash2Size + 1];
+ #endif
+
+ #ifdef __AUTO_REMOVE
+
+ #ifdef __HASH_3
+ m_NumNodes = aSizeHistory + _sizeHistory * 4 / 8 + (1 << 19);
+ #else
+ m_NumNodes = aSizeHistory + _sizeHistory * 4 / 8 + (1 << 10);
+ #endif
+
+ #else
+
+ UINT32 m_NumNodes = aSizeHistory;
+
+ #endif
+
+ const UINT32 kMaxNumNodes = UINT32(1) << (sizeof(CIndex) * 8 - 1);
+ if (m_NumNodes + 32 > kMaxNumNodes)
+ return E_INVALIDARG;
+
+ #ifdef WIN32
+ m_Nodes = (CNode *)::VirtualAlloc(0, (m_NumNodes + 2) * sizeof(CNode), MEM_COMMIT, PAGE_READWRITE);
+ if (m_Nodes == 0)
+ throw CNewException();
+ #else
+ m_Nodes = (CNode *)m_AlignBuffer.Allocate(m_NumNodes + 2, sizeof(CNode), 0x40);
+ #endif
+
+ m_TmpBacks = new UINT32[_matchMaxLen + 1];
+ return S_OK;
+ }
+ catch(...)
+ {
+ FreeMemory();
+ return E_OUTOFMEMORY;
+ }
+}
+
+STDMETHODIMP CPatricia::Init(ISequentialInStream *aStream)
+{
+ RINOK(CLZInWindow::Init(aStream));
+
+ // memset(m_HashDescendants, 0xFF, kHashSize * sizeof(m_HashDescendants[0]));
+
+ #ifdef __HASH_3
+ for (UINT32 i = 0; i < kHash2Size; i++)
+ m_Hash2Descendants[i].MatchPointer = kDescendantsNotInitilized2;
+ #else
+ for (UINT32 i = 0; i < kHashSize; i++)
+ m_HashDescendants[i].MakeEmpty();
+ #endif
+
+ m_Nodes[0].NextFreeNode = 1;
+ m_FreeNode = 0;
+ m_FreeNodeMax = 0;
+ #ifdef __AUTO_REMOVE
+ m_NumUsedNodes = 0;
+ #else
+ m_SpecialRemoveMode = false;
+ #endif
+ m_SpecialMode = false;
+ return S_OK;
+}
+
+STDMETHODIMP_(void) CPatricia::ReleaseStream()
+{
+ // CLZInWindow::ReleaseStream();
+}
+
+// pos = _pos + kNumHashBytes
+// aFullCurrentLimit = aCurrentLimit + kNumHashBytes
+// aFullMatchLen = aMatchLen + kNumHashBytes
+
+void CPatricia::ChangeLastMatch(UINT32 aHashValue)
+{
+ UINT32 pos = _pos + kNumHashBytes - 1;
+ UINT32 descendantIndex;
+ const BYTE *aCurrentBytePointer = _buffer + pos;
+ UINT32 aNumLoadedBits = 0;
+ BYTE aByte;
+ CNodePointer aNode = &m_Nodes[m_HashDescendants[aHashValue].NodePointer];
+
+ while(true)
+ {
+ UINT32 aNumSameBits = aNode->NumSameBits;
+ if(aNumSameBits > 0)
+ {
+ if (aNumLoadedBits < aNumSameBits)
+ {
+ aNumSameBits -= aNumLoadedBits;
+ aCurrentBytePointer += (aNumSameBits / MY_BYTE_SIZE);
+ aNumSameBits %= MY_BYTE_SIZE;
+ aByte = *aCurrentBytePointer++;
+ aNumLoadedBits = MY_BYTE_SIZE;
+ }
+ aByte >>= aNumSameBits;
+ aNumLoadedBits -= aNumSameBits;
+ }
+ if(aNumLoadedBits == 0)
+ {
+ aByte = *aCurrentBytePointer++;
+ aNumLoadedBits = MY_BYTE_SIZE;
+ }
+ descendantIndex = (aByte & kSubNodesMask);
+ aNode->LastMatch = pos;
+ aNumLoadedBits -= kNumSubBits;
+ aByte >>= kNumSubBits;
+ if(aNode->Descendants[descendantIndex].IsNode())
+ aNode = &m_Nodes[aNode->Descendants[descendantIndex].NodePointer];
+ else
+ break;
+ }
+ aNode->Descendants[descendantIndex].MatchPointer = pos + kMatchStartValue;
+}
+
+UINT32 CPatricia::GetLongestMatch(UINT32 *aBacks)
+{
+ UINT32 aFullCurrentLimit;
+ if (_pos + _matchMaxLen <= _streamPos)
+ aFullCurrentLimit = _matchMaxLen;
+ else
+ {
+ aFullCurrentLimit = _streamPos - _pos;
+ if(aFullCurrentLimit < kNumHashBytes)
+ return 0;
+ }
+ UINT32 pos = _pos + kNumHashBytes;
+
+ #ifdef __HASH_3
+ UINT32 aHashValueTemp = (*((UINT32 *)(_buffer + _pos)));
+ UINT32 aHashValue = ((aHashValueTemp << 8) |
+ ((aHashValueTemp & 0xFFFFFF)>> 16)) & 0xFFFFFF;
+ CDescendant &aHashDescendant = m_HashDescendants[aHashValue];
+ CDescendant &aHash2Descendant = m_Hash2Descendants[aHashValueTemp & 0xFFFF];
+ if(aHash2Descendant.MatchPointer <= kDescendantEmptyValue2)
+ {
+ if(aHash2Descendant.MatchPointer == kDescendantsNotInitilized2)
+ {
+ UINT32 aBase = aHashValue & 0xFFFF00;
+ for (UINT32 i = 0; i < 0x100; i++)
+ m_HashDescendants[aBase + i].MakeEmpty();
+ }
+ aHash2Descendant.MatchPointer = pos + kMatchStartValue2;
+ aHashDescendant.MatchPointer = pos + kMatchStartValue;
+ return 0;
+ }
+
+ aBacks[kNumHash2Bytes] = pos - (aHash2Descendant.MatchPointer - kMatchStartValue2) - 1;
+ aHash2Descendant.MatchPointer = pos + kMatchStartValue2;
+ #ifdef __AUTO_REMOVE
+ if (aBacks[kNumHash2Bytes] >= _sizeHistory)
+ {
+ if (aHashDescendant.IsNode())
+ RemoveNode(aHashDescendant.NodePointer);
+ aHashDescendant.MatchPointer = pos + kMatchStartValue;
+ return 0;
+ }
+ #endif
+ if (aFullCurrentLimit == kNumHash2Bytes)
+ return kNumHash2Bytes;
+
+ #else
+ UINT32 aHashValue = UINT32(GetIndexByte(1)) | (UINT32(GetIndexByte(0)) << 8);
+ CDescendant &aHashDescendant = m_HashDescendants[aHashValue];
+ #endif
+
+
+ if(m_SpecialMode)
+ {
+ if(aHashDescendant.IsMatch())
+ m_NumNotChangedCycles = 0;
+ if(m_NumNotChangedCycles >= _sizeHistory - 1)
+ {
+ ChangeLastMatch(aHashValue);
+ m_NumNotChangedCycles = 0;
+ }
+ if(GetIndexByte(aFullCurrentLimit - 1) == GetIndexByte(aFullCurrentLimit - 2))
+ {
+ if(aHashDescendant.IsMatch())
+ aHashDescendant.MatchPointer = pos + kMatchStartValue;
+ else
+ m_NumNotChangedCycles++;
+ for(UINT32 i = kNumHashBytes; i <= aFullCurrentLimit; i++)
+ aBacks[i] = 0;
+ return aFullCurrentLimit;
+ }
+ else if(m_NumNotChangedCycles > 0)
+ ChangeLastMatch(aHashValue);
+ m_SpecialMode = false;
+ }
+
+ if(aHashDescendant.IsEmpty())
+ {
+ aHashDescendant.MatchPointer = pos + kMatchStartValue;
+ return kPrevHashSize;
+ }
+
+ UINT32 aCurrentLimit = aFullCurrentLimit - kNumHashBytes;
+
+ if(aHashDescendant.IsMatch())
+ {
+ CMatchPointer aMatchPointer = aHashDescendant.MatchPointer;
+ UINT32 aBackReal = pos - (aMatchPointer - kMatchStartValue);
+ UINT32 aBack = aBackReal - 1;
+ #ifdef __AUTO_REMOVE
+ if (aBack >= _sizeHistory)
+ {
+ aHashDescendant.MatchPointer = pos + kMatchStartValue;
+ return kPrevHashSize;
+ }
+ #endif
+
+ UINT32 aMatchLen;
+ aBacks += kNumHashBytes;
+ BYTE *aBuffer = _buffer + pos;
+ for(aMatchLen = 0; true; aMatchLen++)
+ {
+ *aBacks++ = aBack;
+ if (aMatchLen == aCurrentLimit)
+ {
+ aHashDescendant.MatchPointer = pos + kMatchStartValue;
+ return kNumHashBytes + aMatchLen;
+ }
+ if (aBuffer[aMatchLen] != aBuffer[aMatchLen - aBackReal])
+ break;
+ }
+
+ // UINT32 aMatchLen = GetMatchLen(kNumHashBytes, aBack, aCurrentLimit);
+
+ UINT32 aFullMatchLen = aMatchLen + kNumHashBytes;
+ aHashDescendant.NodePointer = m_FreeNode;
+ CNodePointer aNode = &m_Nodes[m_FreeNode];
+ m_FreeNode = aNode->NextFreeNode;
+ #ifdef __AUTO_REMOVE
+ m_NumUsedNodes++;
+ #endif
+ if (m_FreeNode > m_FreeNodeMax)
+ {
+ m_FreeNodeMax = m_FreeNode;
+ m_Nodes[m_FreeNode].NextFreeNode = m_FreeNode + 1;
+ }
+
+ for (UINT32 i = 0; i < kNumSubNodes; i++)
+ aNode->Descendants[i].NodePointer = kDescendantEmptyValue;
+ aNode->LastMatch = pos;
+
+ BYTE aByteNew = GetIndexByte(aFullMatchLen);
+ BYTE aByteOld = GetIndexByte(aFullMatchLen - aBackReal);
+ BYTE aBitsNew, aBitsOld;
+ UINT32 aNumSameBits = aMatchLen * MY_BYTE_SIZE;
+ while (true)
+ {
+ aBitsNew = (aByteNew & kSubNodesMask);
+ aBitsOld = (aByteOld & kSubNodesMask);
+ if(aBitsNew != aBitsOld)
+ break;
+ aByteNew >>= kNumSubBits;
+ aByteOld >>= kNumSubBits;
+ aNumSameBits += kNumSubBits;
+ }
+ aNode->NumSameBits = CSameBitsType(aNumSameBits);
+ aNode->Descendants[aBitsNew].MatchPointer = pos + kMatchStartValue;
+ aNode->Descendants[aBitsOld].MatchPointer = aMatchPointer;
+ return aFullMatchLen;
+ }
+ const BYTE *aBaseCurrentBytePointer = _buffer + pos;
+ const BYTE *aCurrentBytePointer = aBaseCurrentBytePointer;
+ UINT32 aNumLoadedBits = 0;
+ BYTE aByte = 0;
+ CIndex *aNodePointerPointer = &aHashDescendant.NodePointer;
+ CNodePointer aNode = &m_Nodes[*aNodePointerPointer];
+ aBacks += kNumHashBytes;
+ const BYTE *aBytePointerLimit = aBaseCurrentBytePointer + aCurrentLimit;
+ const BYTE *aCurrentAddingOffset = _buffer;
+
+ #ifdef __AUTO_REMOVE
+ UINT32 aLowPos;
+ if (pos > _sizeHistory)
+ aLowPos = pos - _sizeHistory;
+ else
+ aLowPos = 0;
+ #endif
+
+ while(true)
+ {
+ #ifdef __AUTO_REMOVE
+ if (aNode->LastMatch < aLowPos)
+ {
+ RemoveNode(*aNodePointerPointer);
+ *aNodePointerPointer = pos + kMatchStartValue;
+ if (aCurrentBytePointer == aBaseCurrentBytePointer)
+ return kPrevHashSize;
+ return kNumHashBytes + (aCurrentBytePointer - aBaseCurrentBytePointer - 1);
+ }
+ #endif
+ if(aNumLoadedBits == 0)
+ {
+ *aBacks++ = pos - aNode->LastMatch - 1;
+ if(aCurrentBytePointer >= aBytePointerLimit)
+ {
+ for (UINT32 i = 0; i < kNumSubNodes; i++)
+ aNode->Descendants[i].MatchPointer = pos + kMatchStartValue;
+ aNode->LastMatch = pos;
+ aNode->NumSameBits = 0;
+ return aFullCurrentLimit;
+ }
+ aByte = (*aCurrentBytePointer++);
+ aCurrentAddingOffset++;
+ aNumLoadedBits = MY_BYTE_SIZE;
+ }
+ UINT32 aNumSameBits = aNode->NumSameBits;
+ if(aNumSameBits > 0)
+ {
+ BYTE aByteXOR = ((*(aCurrentAddingOffset + aNode->LastMatch -1)) >>
+ (MY_BYTE_SIZE - aNumLoadedBits)) ^ aByte;
+ while(aNumLoadedBits <= aNumSameBits)
+ {
+ if(aByteXOR != 0)
+ {
+ AddInternalNode(aNode, aNodePointerPointer, aByte, aByteXOR,
+ aNumSameBits, pos);
+ return kNumHashBytes + (aCurrentBytePointer - aBaseCurrentBytePointer - 1);
+ }
+ *aBacks++ = pos - aNode->LastMatch - 1;
+ aNumSameBits -= aNumLoadedBits;
+ if(aCurrentBytePointer >= aBytePointerLimit)
+ {
+ for (UINT32 i = 0; i < kNumSubNodes; i++)
+ aNode->Descendants[i].MatchPointer = pos + kMatchStartValue;
+ aNode->LastMatch = pos;
+ aNode->NumSameBits = CSameBitsType(aNode->NumSameBits - aNumSameBits);
+ return aFullCurrentLimit;
+ }
+ aNumLoadedBits = MY_BYTE_SIZE;
+ aByte = (*aCurrentBytePointer++);
+ aByteXOR = aByte ^ (*(aCurrentAddingOffset + aNode->LastMatch));
+ aCurrentAddingOffset++;
+ }
+ if((aByteXOR & ((1 << aNumSameBits) - 1)) != 0)
+ {
+ AddInternalNode(aNode, aNodePointerPointer, aByte, aByteXOR,
+ aNumSameBits, pos);
+ return kNumHashBytes + (aCurrentBytePointer - aBaseCurrentBytePointer - 1);
+ }
+ aByte >>= aNumSameBits;
+ aNumLoadedBits -= aNumSameBits;
+ }
+ UINT32 descendantIndex = (aByte & kSubNodesMask);
+ aNumLoadedBits -= kNumSubBits;
+ aNodePointerPointer = &aNode->Descendants[descendantIndex].NodePointer;
+ UINT32 aNextNodeIndex = *aNodePointerPointer;
+ aNode->LastMatch = pos;
+ if (aNextNodeIndex < kDescendantEmptyValue)
+ {
+ aByte >>= kNumSubBits;
+ aNode = &m_Nodes[aNextNodeIndex];
+ }
+ else if (aNextNodeIndex == kDescendantEmptyValue)
+ {
+ aNode->Descendants[descendantIndex].MatchPointer = pos + kMatchStartValue;
+ return kNumHashBytes + (aCurrentBytePointer - aBaseCurrentBytePointer - 1);
+ }
+ else
+ break;
+ }
+
+ UINT32 descendantIndex = (aByte & kSubNodesMask);
+ aByte >>= kNumSubBits;
+ CMatchPointer aMatchPointer = aNode->Descendants[descendantIndex].MatchPointer;
+ CMatchPointer aRealMatchPointer;
+ aRealMatchPointer = aMatchPointer - kMatchStartValue;
+
+ #ifdef __AUTO_REMOVE
+ if (aRealMatchPointer < aLowPos)
+ {
+ aNode->Descendants[descendantIndex].MatchPointer = pos + kMatchStartValue;
+ return kNumHashBytes + (aCurrentBytePointer - aBaseCurrentBytePointer - 1);
+ }
+ #endif
+
+ BYTE aByteXOR;
+ UINT32 aNumSameBits = 0;
+ if(aNumLoadedBits != 0)
+ {
+ BYTE aMatchByte = *(aCurrentAddingOffset + aRealMatchPointer -1);
+ aMatchByte >>= (MY_BYTE_SIZE - aNumLoadedBits);
+ aByteXOR = aMatchByte ^ aByte;
+ if(aByteXOR != 0)
+ {
+ AddLeafNode(aNode, aByte, aByteXOR, aNumSameBits, pos, descendantIndex);
+ return kNumHashBytes + (aCurrentBytePointer - aBaseCurrentBytePointer - 1);
+ }
+ aNumSameBits += aNumLoadedBits;
+ }
+
+ const BYTE *aMatchBytePointer = _buffer + aRealMatchPointer +
+ (aCurrentBytePointer - aBaseCurrentBytePointer);
+ for(; aCurrentBytePointer < aBytePointerLimit; aNumSameBits += MY_BYTE_SIZE)
+ {
+ aByte = (*aCurrentBytePointer++);
+ *aBacks++ = pos - aRealMatchPointer - 1;
+ aByteXOR = aByte ^ (*aMatchBytePointer++);
+ if(aByteXOR != 0)
+ {
+ AddLeafNode(aNode, aByte, aByteXOR, aNumSameBits, pos, descendantIndex);
+ return kNumHashBytes + (aCurrentBytePointer - aBaseCurrentBytePointer - 1);
+ }
+ }
+ *aBacks = pos - aRealMatchPointer - 1;
+ aNode->Descendants[descendantIndex].MatchPointer = pos + kMatchStartValue;
+
+ if(*aBacks == 0)
+ {
+ m_SpecialMode = true;
+ m_NumNotChangedCycles = 0;
+ }
+ return aFullCurrentLimit;
+}
+
+STDMETHODIMP_(void) CPatricia::DummyLongestMatch()
+{
+ GetLongestMatch(m_TmpBacks);
+}
+
+
+// ------------------------------------
+// Remove Match
+
+typedef BYTE CRemoveDataWord;
+
+static const int kSizeRemoveDataWordInBits = MY_BYTE_SIZE * sizeof(CRemoveDataWord);
+
+#ifndef __AUTO_REMOVE
+
+void CPatricia::RemoveMatch()
+{
+ if(m_SpecialRemoveMode)
+ {
+ if(GetIndexByte(_matchMaxLen - 1 - _sizeHistory) ==
+ GetIndexByte(_matchMaxLen - _sizeHistory))
+ return;
+ m_SpecialRemoveMode = false;
+ }
+ UINT32 pos = _pos + kNumHashBytes - _sizeHistory;
+
+ #ifdef __HASH_3
+ // UINT32 aHashValue = (*((UINT32 *)(_buffer + _pos - _sizeHistory))) & 0xFFFFFF;
+ UINT32 aHashValueTemp = *((UINT32 *)(_buffer + _pos - _sizeHistory));
+ UINT32 aHashValue = ((aHashValueTemp << 8) |
+ ((aHashValueTemp & 0xFFFFFF)>> 16)) & 0xFFFFFF;
+
+ CDescendant &aHashDescendant = m_HashDescendants[aHashValue];
+ CDescendant &aHash2Descendant = m_Hash2Descendants[aHashValueTemp & 0xFFFF];
+ if (aHash2Descendant >= kMatchStartValue2)
+ if(aHash2Descendant.MatchPointer == pos + kMatchStartValue2)
+ aHash2Descendant.MatchPointer = kDescendantEmptyValue2;
+ #else
+ UINT32 aHashValue = UINT32(GetIndexByte(1 - _sizeHistory)) |
+ (UINT32(GetIndexByte(0 - _sizeHistory)) << 8);
+ CDescendant &aHashDescendant = m_HashDescendants[aHashValue];
+ #endif
+
+ if(aHashDescendant.IsEmpty())
+ return;
+ if(aHashDescendant.IsMatch())
+ {
+ if(aHashDescendant.MatchPointer == pos + kMatchStartValue)
+ aHashDescendant.MakeEmpty();
+ return;
+ }
+
+ UINT32 descendantIndex;
+ const CRemoveDataWord *aCurrentPointer = (const CRemoveDataWord *)(_buffer + pos);
+ UINT32 aNumLoadedBits = 0;
+ CRemoveDataWord aWord;
+
+ CIndex *aNodePointerPointer = &aHashDescendant.NodePointer;
+
+ CNodePointer aNode = &m_Nodes[aHashDescendant.NodePointer];
+
+ while(true)
+ {
+ if(aNumLoadedBits == 0)
+ {
+ aWord = *aCurrentPointer++;
+ aNumLoadedBits = kSizeRemoveDataWordInBits;
+ }
+ UINT32 aNumSameBits = aNode->NumSameBits;
+ if(aNumSameBits > 0)
+ {
+ if (aNumLoadedBits <= aNumSameBits)
+ {
+ aNumSameBits -= aNumLoadedBits;
+ aCurrentPointer += (aNumSameBits / kSizeRemoveDataWordInBits);
+ aNumSameBits %= kSizeRemoveDataWordInBits;
+ aWord = *aCurrentPointer++;
+ aNumLoadedBits = kSizeRemoveDataWordInBits;
+ }
+ aWord >>= aNumSameBits;
+ aNumLoadedBits -= aNumSameBits;
+ }
+ descendantIndex = (aWord & kSubNodesMask);
+ aNumLoadedBits -= kNumSubBits;
+ aWord >>= kNumSubBits;
+ UINT32 aNextNodeIndex = aNode->Descendants[descendantIndex].NodePointer;
+ if (aNextNodeIndex < kDescendantEmptyValue)
+ {
+ aNodePointerPointer = &aNode->Descendants[descendantIndex].NodePointer;
+ aNode = &m_Nodes[aNextNodeIndex];
+ }
+ else
+ break;
+ }
+ if (aNode->Descendants[descendantIndex].MatchPointer != pos + kMatchStartValue)
+ {
+ const BYTE *aCurrentBytePointer = _buffer + _pos - _sizeHistory;
+ const BYTE *aCurrentBytePointerLimit = aCurrentBytePointer + _matchMaxLen;
+ for(;aCurrentBytePointer < aCurrentBytePointerLimit; aCurrentBytePointer++)
+ if(*aCurrentBytePointer != *(aCurrentBytePointer+1))
+ return;
+ m_SpecialRemoveMode = true;
+ return;
+ }
+
+ UINT32 aNumNodes = 0, aNumMatches = 0;
+
+ UINT32 i;
+ for (i = 0; i < kNumSubNodes; i++)
+ {
+ UINT32 aNodeIndex = aNode->Descendants[i].NodePointer;
+ if (aNodeIndex < kDescendantEmptyValue)
+ aNumNodes++;
+ else if (aNodeIndex > kDescendantEmptyValue)
+ aNumMatches++;
+ }
+ aNumMatches -= 1;
+ if (aNumNodes + aNumMatches > 1)
+ {
+ aNode->Descendants[descendantIndex].MakeEmpty();
+ return;
+ }
+ if(aNumNodes == 1)
+ {
+ UINT32 i;
+ for (i = 0; i < kNumSubNodes; i++)
+ if (aNode->Descendants[i].IsNode())
+ break;
+ UINT32 aNextNodeIndex = aNode->Descendants[i].NodePointer;
+ CNodePointer aNextNode = &m_Nodes[aNextNodeIndex];
+ aNextNode->NumSameBits += aNode->NumSameBits + kNumSubBits;
+ *aNode = *aNextNode;
+
+ aNextNode->NextFreeNode = m_FreeNode;
+ m_FreeNode = aNextNodeIndex;
+ return;
+ }
+ UINT32 aMatchPointer;
+ for (i = 0; i < kNumSubNodes; i++)
+ if (aNode->Descendants[i].IsMatch() && i != descendantIndex)
+ {
+ aMatchPointer = aNode->Descendants[i].MatchPointer;
+ break;
+ }
+ aNode->NextFreeNode = m_FreeNode;
+ m_FreeNode = *aNodePointerPointer;
+ *aNodePointerPointer = aMatchPointer;
+}
+#endif
+
+const UINT32 kNormalizeStartPos = (UINT32(1) << (kNumBitsInIndex)) -
+ kMatchStartValue - kNumHashBytes - 1;
+
+STDMETHODIMP CPatricia::MovePos()
+{
+ #ifndef __AUTO_REMOVE
+ if(_pos >= _sizeHistory)
+ RemoveMatch();
+ #endif
+ RINOK(CLZInWindow::MovePos());
+ #ifdef __AUTO_REMOVE
+ if (m_NumUsedNodes >= m_NumNodes)
+ TestRemoveNodes();
+ #endif
+ if (_pos >= kNormalizeStartPos)
+ {
+ #ifdef __AUTO_REMOVE
+ TestRemoveNodesAndNormalize();
+ #else
+ Normalize();
+ #endif
+ }
+ return S_OK;
+}
+
+#ifndef __AUTO_REMOVE
+
+void CPatricia::NormalizeDescendant(CDescendant &aDescendant, UINT32 aSubValue)
+{
+ if (aDescendant.IsEmpty())
+ return;
+ if (aDescendant.IsMatch())
+ aDescendant.MatchPointer = aDescendant.MatchPointer - aSubValue;
+ else
+ {
+ CNode &aNode = m_Nodes[aDescendant.NodePointer];
+ aNode.LastMatch = aNode.LastMatch - aSubValue;
+ for (UINT32 i = 0; i < kNumSubNodes; i++)
+ NormalizeDescendant(aNode.Descendants[i], aSubValue);
+ }
+}
+
+void CPatricia::Normalize()
+{
+ UINT32 aSubValue = _pos - _sizeHistory;
+ CLZInWindow::ReduceOffsets(aSubValue);
+
+ #ifdef __HASH_3
+
+ for(UINT32 aHash = 0; aHash < kHash2Size; aHash++)
+ {
+ CDescendant &aDescendant = m_Hash2Descendants[aHash];
+ if (aDescendant.MatchPointer != kDescendantsNotInitilized2)
+ {
+ UINT32 aBase = aHash << 8;
+ for (UINT32 i = 0; i < 0x100; i++)
+ NormalizeDescendant(m_HashDescendants[aBase + i], aSubValue);
+ }
+ if (aDescendant.MatchPointer < kMatchStartValue2)
+ continue;
+ aDescendant.MatchPointer = aDescendant.MatchPointer - aSubValue;
+ }
+
+ #else
+
+ for(UINT32 aHash = 0; aHash < kHashSize; aHash++)
+ NormalizeDescendant(m_HashDescendants[aHash], aSubValue);
+
+ #endif
+
+}
+
+#else
+
+void CPatricia::TestRemoveDescendant(CDescendant &aDescendant, UINT32 aLimitPos)
+{
+ CNode &aNode = m_Nodes[aDescendant.NodePointer];
+ UINT32 aNumChilds = 0;
+ UINT32 aChildIndex;
+ for (UINT32 i = 0; i < kNumSubNodes; i++)
+ {
+ CDescendant &aDescendant2 = aNode.Descendants[i];
+ if (aDescendant2.IsEmpty())
+ continue;
+ if (aDescendant2.IsMatch())
+ {
+ if (aDescendant2.MatchPointer < aLimitPos)
+ aDescendant2.MakeEmpty();
+ else
+ {
+ aNumChilds++;
+ aChildIndex = i;
+ }
+ }
+ else
+ {
+ TestRemoveDescendant(aDescendant2, aLimitPos);
+ if (!aDescendant2.IsEmpty())
+ {
+ aNumChilds++;
+ aChildIndex = i;
+ }
+ }
+ }
+ if (aNumChilds > 1)
+ return;
+
+ CIndex aNodePointerTemp = aDescendant.NodePointer;
+ if (aNumChilds == 1)
+ {
+ const CDescendant &aDescendant2 = aNode.Descendants[aChildIndex];
+ if (aDescendant2.IsNode())
+ m_Nodes[aDescendant2.NodePointer].NumSameBits += aNode.NumSameBits + kNumSubBits;
+ aDescendant = aDescendant2;
+ }
+ else
+ aDescendant.MakeEmpty();
+ aNode.NextFreeNode = m_FreeNode;
+ m_FreeNode = aNodePointerTemp;
+ m_NumUsedNodes--;
+}
+
+void CPatricia::RemoveNode(UINT32 anIndex)
+{
+ CNode &aNode = m_Nodes[anIndex];
+ for (UINT32 i = 0; i < kNumSubNodes; i++)
+ {
+ CDescendant &aDescendant2 = aNode.Descendants[i];
+ if (aDescendant2.IsNode())
+ RemoveNode(aDescendant2.NodePointer);
+ }
+ aNode.NextFreeNode = m_FreeNode;
+ m_FreeNode = anIndex;
+ m_NumUsedNodes--;
+}
+
+void CPatricia::TestRemoveNodes()
+{
+ UINT32 aLimitPos = kMatchStartValue + _pos - _sizeHistory + kNumHashBytes;
+
+ #ifdef __HASH_3
+
+ UINT32 aLimitPos2 = kMatchStartValue2 + _pos - _sizeHistory + kNumHashBytes;
+ for(UINT32 aHash = 0; aHash < kHash2Size; aHash++)
+ {
+ CDescendant &aDescendant = m_Hash2Descendants[aHash];
+ if (aDescendant.MatchPointer != kDescendantsNotInitilized2)
+ {
+ UINT32 aBase = aHash << 8;
+ for (UINT32 i = 0; i < 0x100; i++)
+ {
+ CDescendant &aDescendant = m_HashDescendants[aBase + i];
+ if (aDescendant.IsEmpty())
+ continue;
+ if (aDescendant.IsMatch())
+ {
+ if (aDescendant.MatchPointer < aLimitPos)
+ aDescendant.MakeEmpty();
+ }
+ else
+ TestRemoveDescendant(aDescendant, aLimitPos);
+ }
+ }
+ if (aDescendant.MatchPointer < kMatchStartValue2)
+ continue;
+ if (aDescendant.MatchPointer < aLimitPos2)
+ aDescendant.MatchPointer = kDescendantEmptyValue2;
+ }
+
+ #else
+
+ for(UINT32 aHash = 0; aHash < kHashSize; aHash++)
+ {
+ CDescendant &aDescendant = m_HashDescendants[aHash];
+ if (aDescendant.IsEmpty())
+ continue;
+ if (aDescendant.IsMatch())
+ {
+ if (aDescendant.MatchPointer < aLimitPos)
+ aDescendant.MakeEmpty();
+ }
+ else
+ TestRemoveDescendant(aDescendant, aLimitPos);
+ }
+
+ #endif
+}
+
+void CPatricia::TestRemoveAndNormalizeDescendant(CDescendant &aDescendant,
+ UINT32 aLimitPos, UINT32 aSubValue)
+{
+ if (aDescendant.IsEmpty())
+ return;
+ if (aDescendant.IsMatch())
+ {
+ if (aDescendant.MatchPointer < aLimitPos)
+ aDescendant.MakeEmpty();
+ else
+ aDescendant.MatchPointer = aDescendant.MatchPointer - aSubValue;
+ return;
+ }
+ CNode &aNode = m_Nodes[aDescendant.NodePointer];
+ UINT32 aNumChilds = 0;
+ UINT32 aChildIndex;
+ for (UINT32 i = 0; i < kNumSubNodes; i++)
+ {
+ CDescendant &aDescendant2 = aNode.Descendants[i];
+ TestRemoveAndNormalizeDescendant(aDescendant2, aLimitPos, aSubValue);
+ if (!aDescendant2.IsEmpty())
+ {
+ aNumChilds++;
+ aChildIndex = i;
+ }
+ }
+ if (aNumChilds > 1)
+ {
+ aNode.LastMatch = aNode.LastMatch - aSubValue;
+ return;
+ }
+
+ CIndex aNodePointerTemp = aDescendant.NodePointer;
+ if (aNumChilds == 1)
+ {
+ const CDescendant &aDescendant2 = aNode.Descendants[aChildIndex];
+ if (aDescendant2.IsNode())
+ m_Nodes[aDescendant2.NodePointer].NumSameBits += aNode.NumSameBits + kNumSubBits;
+ aDescendant = aDescendant2;
+ }
+ else
+ aDescendant.MakeEmpty();
+ aNode.NextFreeNode = m_FreeNode;
+ m_FreeNode = aNodePointerTemp;
+ m_NumUsedNodes--;
+}
+
+void CPatricia::TestRemoveNodesAndNormalize()
+{
+ UINT32 aSubValue = _pos - _sizeHistory;
+ UINT32 aLimitPos = kMatchStartValue + _pos - _sizeHistory + kNumHashBytes;
+ CLZInWindow::ReduceOffsets(aSubValue);
+
+ #ifdef __HASH_3
+
+ UINT32 aLimitPos2 = kMatchStartValue2 + _pos - _sizeHistory + kNumHashBytes;
+ for(UINT32 aHash = 0; aHash < kHash2Size; aHash++)
+ {
+ CDescendant &aDescendant = m_Hash2Descendants[aHash];
+ if (aDescendant.MatchPointer != kDescendantsNotInitilized2)
+ {
+ UINT32 aBase = aHash << 8;
+ for (UINT32 i = 0; i < 0x100; i++)
+ TestRemoveAndNormalizeDescendant(m_HashDescendants[aBase + i], aLimitPos, aSubValue);
+ }
+ if (aDescendant.MatchPointer < kMatchStartValue2)
+ continue;
+ if (aDescendant.MatchPointer < aLimitPos2)
+ aDescendant.MatchPointer = kDescendantEmptyValue2;
+ else
+ aDescendant.MatchPointer = aDescendant.MatchPointer - aSubValue;
+ }
+
+ #else
+
+ for(UINT32 aHash = 0; aHash < kHashSize; aHash++)
+ TestRemoveAndNormalizeDescendant(m_HashDescendants[aHash], aLimitPos, aSubValue);
+
+ #endif
+}
+
+#endif
+
+STDMETHODIMP_(BYTE) CPatricia::GetIndexByte(UINT32 anIndex)
+{
+ return CLZInWindow::GetIndexByte(anIndex);
+}
+
+STDMETHODIMP_(UINT32) CPatricia::GetMatchLen(UINT32 aIndex, UINT32 aBack, UINT32 aLimit)
+{
+ return CLZInWindow::GetMatchLen(aIndex, aBack, aLimit);
+}
+
+STDMETHODIMP_(UINT32) CPatricia::GetNumAvailableBytes()
+{
+ return CLZInWindow::GetNumAvailableBytes();
+}
+
+STDMETHODIMP_(const BYTE *) CPatricia::GetPointerToCurrentPos()
+{
+ return CLZInWindow::GetPointerToCurrentPos();
+}
+
+}
diff --git a/7zip/Compress/LZ/StdAfx.h b/7zip/Compress/LZ/StdAfx.h
new file mode 100755
index 00000000..a32fbed6
--- /dev/null
+++ b/7zip/Compress/LZ/StdAfx.h
@@ -0,0 +1,8 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#endif
diff --git a/7zip/Compress/LZMA/DllExports.cpp b/7zip/Compress/LZMA/DllExports.cpp
new file mode 100755
index 00000000..043e2e93
--- /dev/null
+++ b/7zip/Compress/LZMA/DllExports.cpp
@@ -0,0 +1,88 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+// #include <initguid.h>
+#define INITGUID
+
+#include "LZMAEncoder.h"
+#include "LZMADecoder.h"
+#include "../../../Common/ComTry.h"
+
+// {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*/)
+{
+ 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_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/7zip/Compress/LZMA/LZMA.def b/7zip/Compress/LZMA/LZMA.def
new file mode 100755
index 00000000..c2f3e24f
--- /dev/null
+++ b/7zip/Compress/LZMA/LZMA.def
@@ -0,0 +1,7 @@
+LIBRARY LZMA
+
+EXPORTS
+ CreateObject
+ GetNumberOfMethods
+ GetMethodProperty
+
diff --git a/7zip/Compress/LZMA/LZMA.dsp b/7zip/Compress/LZMA/LZMA.dsp
new file mode 100755
index 00000000..d52308ec
--- /dev/null
+++ b/7zip/Compress/LZMA/LZMA.dsp
@@ -0,0 +1,463 @@
+# 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_BT" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_HC" /D "COMPRESS_MF_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\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_BT" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_HC" /D "COMPRESS_MF_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\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=.\DllExports.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LZMA.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 "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
+# 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=..\..\IMyUnknown.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IStream.h
+# End Source File
+# End Group
+# Begin Group "LZ"
+
+# PROP Default_Filter ""
+# Begin Group "MT"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\LZ\MT\MT.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=..\LZ\MT\MT.h
+# End Source File
+# End Group
+# Begin Group "Pat"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\LZ\Patricia\Pat.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\Patricia\Pat2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\Patricia\Pat2H.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\Patricia\Pat2R.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\Patricia\Pat3H.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\Patricia\Pat4H.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\Patricia\PatMain.h
+# End Source File
+# End Group
+# 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\BinTree4b.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\BinTree\BinTreeMain.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\BinTree\BinTreeMF.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\BinTree\BinTreeMFMain.h
+# End Source File
+# End Group
+# Begin Group "HC"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\LZ\HashChain\HC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\HashChain\HC2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\HashChain\HC3.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\HashChain\HC4.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\HashChain\HC4b.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\HashChain\HCMain.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\HashChain\HCMF.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\HashChain\HCMFMain.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\LZ\IMatchFinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\LZInWindow.cpp
+# 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\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\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\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.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
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF "$(CFG)" == "LZMA - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\LZMAEncoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LZMALen.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=.\LZMALen.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LZMALiteral.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=.\LZMALiteral.h
+# End Source File
+# End Target
+# End Project
diff --git a/7zip/Compress/LZMA/LZMA.dsw b/7zip/Compress/LZMA/LZMA.dsw
new file mode 100755
index 00000000..f750e453
--- /dev/null
+++ b/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/7zip/Compress/LZMA/LZMA.h b/7zip/Compress/LZMA/LZMA.h
new file mode 100755
index 00000000..f6e2d8d3
--- /dev/null
+++ b/7zip/Compress/LZMA/LZMA.h
@@ -0,0 +1,96 @@
+// LZMA.h
+
+// #pragma once
+
+#include "LZMALen.h"
+
+#ifndef __LZMA_H
+#define __LZMA_H
+
+namespace NCompress {
+namespace NLZMA {
+
+const UINT32 kNumRepDistances = 4;
+
+const BYTE 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]; }
+};
+
+class CBaseCoder
+{
+protected:
+ CState _state;
+ BYTE _previousByte;
+ bool _peviousIsMatch;
+ UINT32 _repDistances[kNumRepDistances];
+ void Init()
+ {
+ _state.Init();
+ _previousByte = 0;
+ _peviousIsMatch = false;
+ for(int i = 0 ; i < kNumRepDistances; i++)
+ _repDistances[i] = 0;
+ }
+};
+
+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;
+}
+
+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 UINT32 kMainChoiceLiteralIndex = 0;
+const UINT32 kMainChoiceMatchIndex = 1;
+
+const UINT32 kMatchChoiceDistanceIndex= 0;
+const UINT32 kMatchChoiceRepetitionIndex = 1;
+
+const int kNumMoveBits = 5;
+
+const int kNumLitPosStatesBitsEncodingMax = 4;
+const int kNumLitContextBitsMax = 8;
+
+}}
+
+#endif
diff --git a/7zip/Compress/LZMA/LZMADecoder.cpp b/7zip/Compress/LZMA/LZMADecoder.cpp
new file mode 100755
index 00000000..18374db7
--- /dev/null
+++ b/7zip/Compress/LZMA/LZMADecoder.cpp
@@ -0,0 +1,356 @@
+// LZMADecoder.cpp
+
+#include "StdAfx.h"
+
+#include "LZMADecoder.h"
+#include "../../../Common/Defs.h"
+#include "../../../Common/ComTry.h"
+
+/*
+#include "fstream.h"
+#include "iomanip.h"
+
+ofstream ofs("res.dat");
+
+const int kNumCounters = 3;
+UINT32 g_Counter[kNumCounters];
+class C1
+{
+public:
+ ~C1()
+ {
+ for (int i = 0; i < kNumCounters; i++)
+ ofs << setw(10) << g_Counter[i] << endl;
+ }
+} g_C1;
+*/
+
+/*
+const UINT32 kLenTableMax = 20;
+const UINT32 kNumDists = NCompress::NLZMA::kDistTableSizeMax / 2;
+UINT32 g_Counts[kLenTableMax][kNumDists];
+class C1
+{
+public:
+ ~C1 ()
+ {
+ UINT32 sums[kLenTableMax];
+ for (int len = 2; len < kLenTableMax; len++)
+ {
+ sums[len] = 0;
+ for (int dist = 0; dist < kNumDists; dist++)
+ sums[len] += g_Counts[len][dist];
+ if (sums[len] == 0)
+ sums[len] = 1;
+ }
+ for (int dist = 0; dist < kNumDists; dist++)
+ {
+ ofs << setw(4) << dist << " ";
+ for (int len = 2; len < kLenTableMax; len++)
+ {
+ ofs << setw(4) << g_Counts[len][dist] * 1000 / sums[len];
+ }
+ ofs << endl;
+ }
+ }
+} g_Class;
+
+void UpdateStat(UINT32 len, UINT32 dist)
+{
+ if (len >= kLenTableMax)
+ len = kLenTableMax - 1;
+ g_Counts[len][dist / 2]++;
+}
+*/
+
+namespace NCompress {
+namespace NLZMA {
+
+HRESULT CDecoder::SetDictionarySize(UINT32 dictionarySize)
+{
+ if (_dictionarySize != dictionarySize)
+ {
+ _dictionarySize = dictionarySize;
+ _dictionarySizeCheck = MyMax(_dictionarySize, UINT32(1));
+ UINT32 blockSize = MyMax(_dictionarySizeCheck, UINT32(1 << 12));
+ try
+ {
+ _outWindowStream.Create(blockSize /*, kMatchMaxLen */);
+ }
+ catch(...)
+ {
+ return E_OUTOFMEMORY;
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CDecoder::SetLiteralProperties(
+ UINT32 numLiteralPosStateBits, UINT32 numLiteralContextBits)
+{
+ if (numLiteralPosStateBits > 8)
+ return E_INVALIDARG;
+ if (numLiteralContextBits > 8)
+ return E_INVALIDARG;
+ _literalDecoder.Create(numLiteralPosStateBits, numLiteralContextBits);
+ return S_OK;
+}
+
+HRESULT CDecoder::SetPosBitsProperties(UINT32 numPosStateBits)
+{
+ if (numPosStateBits > NLength::kNumPosStatesBitsMax)
+ return E_INVALIDARG;
+ UINT32 numPosStates = 1 << numPosStateBits;
+ _lenDecoder.Create(numPosStates);
+ _repMatchLenDecoder.Create(numPosStates);
+ _posStateMask = numPosStates - 1;
+ return S_OK;
+}
+
+CDecoder::CDecoder():
+ _dictionarySize((UINT32)-1)
+{
+ Create();
+}
+
+HRESULT CDecoder::Create()
+{
+ COM_TRY_BEGIN
+ for(int i = 0; i < kNumPosModels; i++)
+ _posDecoders[i].Create(((kStartPosModelIndex + i) >> 1) - 1);
+ COM_TRY_END
+ return S_OK;
+}
+
+
+HRESULT CDecoder::Init(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream)
+{
+ _rangeDecoder.Init(inStream);
+
+ _outWindowStream.Init(outStream);
+
+ int i;
+ for(i = 0; i < kNumStates; i++)
+ {
+ for (UINT32 j = 0; j <= _posStateMask; j++)
+ {
+ _mainChoiceDecoders[i][j].Init();
+ _matchRepShortChoiceDecoders[i][j].Init();
+ }
+ _matchChoiceDecoders[i].Init();
+ _matchRepChoiceDecoders[i].Init();
+ _matchRep1ChoiceDecoders[i].Init();
+ _matchRep2ChoiceDecoders[i].Init();
+ }
+
+ _literalDecoder.Init();
+
+ // _repMatchLenDecoder.Init();
+
+ for (i = 0; i < kNumLenToPosStates; i++)
+ _posSlotDecoder[i].Init();
+
+ for(i = 0; i < kNumPosModels; i++)
+ _posDecoders[i].Init();
+
+ _lenDecoder.Init();
+ _repMatchLenDecoder.Init();
+
+ _posAlignDecoder.Init();
+ return S_OK;
+
+}
+
+
+
+STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ /*
+ if (outSize == NULL)
+ return E_INVALIDARG;
+ */
+
+ Init(inStream, outStream);
+ CDecoderFlusher flusher(this);
+
+ CState state;
+ state.Init();
+ bool peviousIsMatch = false;
+ BYTE previousByte = 0;
+ UINT32 repDistances[kNumRepDistances];
+ for(int i = 0 ; i < kNumRepDistances; i++)
+ repDistances[i] = 0;
+
+ UINT64 nowPos64 = 0;
+ UINT64 size = (outSize == NULL) ? (UINT64)(INT64)(-1) : *outSize;
+ while(nowPos64 < size)
+ {
+ UINT64 nextPos = MyMin(nowPos64 + (1 << 18), size);
+ while(nowPos64 < nextPos)
+ {
+ UINT32 posState = UINT32(nowPos64) & _posStateMask;
+ if (_mainChoiceDecoders[state.Index][posState].Decode(&_rangeDecoder) == kMainChoiceLiteralIndex)
+ {
+ state.UpdateChar();
+ if(peviousIsMatch)
+ {
+ BYTE matchByte = _outWindowStream.GetOneByte(0 - repDistances[0] - 1);
+ previousByte = _literalDecoder.DecodeWithMatchByte(&_rangeDecoder,
+ UINT32(nowPos64), previousByte, matchByte);
+ peviousIsMatch = false;
+ }
+ else
+ previousByte = _literalDecoder.DecodeNormal(&_rangeDecoder,
+ UINT32(nowPos64), previousByte);
+ _outWindowStream.PutOneByte(previousByte);
+ nowPos64++;
+ }
+ else
+ {
+ peviousIsMatch = true;
+ UINT32 distance, len;
+ if(_matchChoiceDecoders[state.Index].Decode(&_rangeDecoder) ==
+ kMatchChoiceRepetitionIndex)
+ {
+ if(_matchRepChoiceDecoders[state.Index].Decode(&_rangeDecoder) == 0)
+ {
+ if(_matchRepShortChoiceDecoders[state.Index][posState].Decode(&_rangeDecoder) == 0)
+ {
+ state.UpdateShortRep();
+ previousByte = _outWindowStream.GetOneByte(0 - repDistances[0] - 1);
+ _outWindowStream.PutOneByte(previousByte);
+ nowPos64++;
+ continue;
+ }
+ distance = repDistances[0];
+ }
+ else
+ {
+ if(_matchRep1ChoiceDecoders[state.Index].Decode(&_rangeDecoder) == 0)
+ distance = repDistances[1];
+ else
+ {
+ if (_matchRep2ChoiceDecoders[state.Index].Decode(&_rangeDecoder) == 0)
+ distance = repDistances[2];
+ else
+ {
+ distance = repDistances[3];
+ repDistances[3] = repDistances[2];
+ }
+ repDistances[2] = repDistances[1];
+ }
+ repDistances[1] = repDistances[0];
+ repDistances[0] = distance;
+ }
+ len = _repMatchLenDecoder.Decode(&_rangeDecoder, posState) + kMatchMinLen;
+ state.UpdateRep();
+ }
+ else
+ {
+ len = kMatchMinLen + _lenDecoder.Decode(&_rangeDecoder, posState);
+ state.UpdateMatch();
+ UINT32 posSlot = _posSlotDecoder[GetLenToPosState(len)].Decode(&_rangeDecoder);
+ if (posSlot >= kStartPosModelIndex)
+ {
+ UINT32 numDirectBits = (posSlot >> 1) - 1;
+ distance = ((2 | (posSlot & 1)) << numDirectBits);
+
+ if (posSlot < kEndPosModelIndex)
+ distance += _posDecoders[posSlot - kStartPosModelIndex].Decode(&_rangeDecoder);
+ else
+ {
+ distance += (_rangeDecoder.DecodeDirectBits(
+ numDirectBits - kNumAlignBits) << kNumAlignBits);
+ distance += _posAlignDecoder.Decode(&_rangeDecoder);
+ }
+ }
+ else
+ distance = posSlot;
+
+ repDistances[3] = repDistances[2];
+ repDistances[2] = repDistances[1];
+ repDistances[1] = repDistances[0];
+ repDistances[0] = distance;
+ // UpdateStat(len, posSlot);
+ }
+ if (distance >= nowPos64 || distance >= _dictionarySizeCheck)
+ {
+ if (distance == (UINT32)(-1) && size == (UINT64)(INT64)(-1))
+ {
+ flusher.NeedFlush = false;
+ return Flush();
+ }
+ throw "data error";
+ }
+ _outWindowStream.CopyBackBlock(distance, len);
+ nowPos64 += len;
+ previousByte = _outWindowStream.GetOneByte(0 - 1);
+ }
+ }
+ if (progress != NULL)
+ {
+ UINT64 inSize = _rangeDecoder.GetProcessedSize();
+ 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; }
+}
+
+
+static HRESULT DecodeProperties(ISequentialInStream *inStream,
+ UINT32 &numPosStateBits,
+ UINT32 &numLiteralPosStateBits,
+ UINT32 &numLiteralContextBits,
+ UINT32 &dictionarySize)
+{
+ UINT32 processesedSize;
+
+ BYTE firstByte;
+ RINOK(inStream->Read(&firstByte, sizeof(firstByte), &processesedSize));
+ if (processesedSize != sizeof(firstByte))
+ return E_INVALIDARG;
+
+ numLiteralContextBits = firstByte % 9;
+ BYTE remainder = firstByte / 9;
+ numLiteralPosStateBits = remainder % 5;
+ numPosStateBits = remainder / 5;
+
+ RINOK(inStream->Read(&dictionarySize, sizeof(dictionarySize), &processesedSize));
+ if (processesedSize != sizeof(dictionarySize))
+ return E_INVALIDARG;
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::SetDecoderProperties(ISequentialInStream *inStream)
+{
+ UINT32 numPosStateBits;
+ UINT32 numLiteralPosStateBits;
+ UINT32 numLiteralContextBits;
+ UINT32 dictionarySize;
+ RINOK(DecodeProperties(inStream,
+ numPosStateBits,
+ numLiteralPosStateBits,
+ numLiteralContextBits,
+ dictionarySize));
+ RINOK(SetDictionarySize(dictionarySize));
+ RINOK(SetLiteralProperties(numLiteralPosStateBits, numLiteralContextBits));
+ RINOK(SetPosBitsProperties(numPosStateBits));
+ return S_OK;
+}
+
+}}
diff --git a/7zip/Compress/LZMA/LZMADecoder.h b/7zip/Compress/LZMA/LZMADecoder.h
new file mode 100755
index 00000000..28350963
--- /dev/null
+++ b/7zip/Compress/LZMA/LZMADecoder.h
@@ -0,0 +1,107 @@
+// LZMA/Decoder.h
+
+// #pragma once
+
+#ifndef __LZMA_DECODER_H
+#define __LZMA_DECODER_H
+
+#include "../../ICoder.h"
+#include "../../../Common/MyCom.h"
+#include "../LZ/LZOutWindow.h"
+
+#include "LZMA.h"
+#include "LZMALen.h"
+#include "LZMALiteral.h"
+
+namespace NCompress {
+namespace NLZMA {
+
+typedef NRangeCoder::CBitDecoder<kNumMoveBits> CMyBitDecoder;
+
+class CDecoder:
+ public ICompressCoder,
+ public ICompressSetDecoderProperties,
+ public CMyUnknownImp
+{
+ CLZOutWindow _outWindowStream;
+ NRangeCoder::CDecoder _rangeDecoder;
+
+ CMyBitDecoder _mainChoiceDecoders[kNumStates][NLength::kNumPosStatesMax];
+ CMyBitDecoder _matchChoiceDecoders[kNumStates];
+ CMyBitDecoder _matchRepChoiceDecoders[kNumStates];
+ CMyBitDecoder _matchRep1ChoiceDecoders[kNumStates];
+ CMyBitDecoder _matchRep2ChoiceDecoders[kNumStates];
+ CMyBitDecoder _matchRepShortChoiceDecoders[kNumStates][NLength::kNumPosStatesMax];
+
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumPosSlotBits> _posSlotDecoder[kNumLenToPosStates];
+
+ NRangeCoder::CReverseBitTreeDecoder2<kNumMoveBits> _posDecoders[kNumPosModels];
+ NRangeCoder::CReverseBitTreeDecoder<kNumMoveBits, kNumAlignBits> _posAlignDecoder;
+
+ NLength::CDecoder _lenDecoder;
+ NLength::CDecoder _repMatchLenDecoder;
+
+ NLiteral::CDecoder _literalDecoder;
+
+ UINT32 _dictionarySize;
+ UINT32 _dictionarySizeCheck;
+
+ UINT32 _posStateMask;
+
+public:
+
+ MY_UNKNOWN_IMP1(ICompressSetDecoderProperties)
+
+ CDecoder();
+ HRESULT Create();
+
+
+ HRESULT Init(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream);
+ /*
+ void ReleaseStreams()
+ {
+ _outWindowStream.ReleaseStream();
+ _rangeDecoder.ReleaseStream();
+ }
+ */
+
+ 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(); }
+
+ // ICompressCoder interface
+ 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(SetDecoderProperties)(ISequentialInStream *inStream);
+
+ HRESULT SetDictionarySize(UINT32 dictionarySize);
+ HRESULT SetLiteralProperties(UINT32 numLiteralPosStateBits,
+ UINT32 numLiteralContextBits);
+ HRESULT SetPosBitsProperties(UINT32 numPosStateBits);
+};
+
+}}
+
+#endif
diff --git a/7zip/Compress/LZMA/LZMAEncoder.cpp b/7zip/Compress/LZMA/LZMAEncoder.cpp
new file mode 100755
index 00000000..aae4515b
--- /dev/null
+++ b/7zip/Compress/LZMA/LZMAEncoder.cpp
@@ -0,0 +1,1274 @@
+// LZMA/Encoder.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/Defs.h"
+
+#include "LZMAEncoder.h"
+
+#ifdef COMPRESS_MF_BT
+#include "../LZ/BinTree/BinTree2.h"
+#include "../LZ/BinTree/BinTree3.h"
+#include "../LZ/BinTree/BinTree4.h"
+#include "../LZ/BinTree/BinTree4b.h"
+#endif
+
+#ifdef COMPRESS_MF_PAT
+#include "../LZ/Patricia/Pat2.h"
+#include "../LZ/Patricia/Pat2H.h"
+#include "../LZ/Patricia/Pat3H.h"
+#include "../LZ/Patricia/Pat4H.h"
+#include "../LZ/Patricia/Pat2R.h"
+#endif
+
+#ifdef COMPRESS_MF_HC
+#include "../LZ/HashChain/HC3.h"
+#include "../LZ/HashChain/HC4.h"
+#endif
+
+#ifdef COMPRESS_MF_MT
+#include "../LZ/MT/MT.h"
+#endif
+
+namespace NCompress {
+namespace NLZMA {
+
+enum
+{
+ kBT2,
+ kBT3,
+ kBT4,
+ kBT4B,
+ kPat2,
+ kPat2H,
+ kPat3H,
+ kPat4H,
+ kPat2R,
+ kHC3,
+ kHC4
+};
+
+static const wchar_t *kMatchFinderIDs[] =
+{
+ L"BT2",
+ L"BT3",
+ L"BT4",
+ L"BT4B",
+ L"PAT2",
+ L"PAT2H",
+ L"PAT3H",
+ L"PAT4H",
+ L"PAT2R",
+ L"HC3",
+ L"HC4"
+};
+
+BYTE g_FastPos[1024];
+
+class CFastPosInit
+{
+public:
+ CFastPosInit()
+ {
+ const BYTE kFastSlots = 20;
+ 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;
+
+const int kDefaultDictionaryLogSize = 20;
+const UINT32 kNumFastBytesDefault = 0x20;
+
+CEncoder::CEncoder():
+ _dictionarySize(1 << kDefaultDictionaryLogSize),
+ _dictionarySizePrev(UINT32(-1)),
+ _numFastBytes(kNumFastBytesDefault),
+ _numFastBytesPrev(UINT32(-1)),
+ _distTableSize(kDefaultDictionaryLogSize * 2),
+ _posStateBits(2),
+ _posStateMask(4 - 1),
+ _numLiteralPosStateBits(0),
+ _numLiteralContextBits(3),
+ #ifdef COMPRESS_MF_MT
+ _multiThread(false),
+ #endif
+ _matchFinderIndex(kBT4),
+ _writeEndMark(false)
+{
+ _maxMode = false;
+ _fastMode = false;
+ _posAlignEncoder.Create(kNumAlignBits);
+ for(int i = 0; i < kNumPosModels; i++)
+ _posEncoders[i].Create(((kStartPosModelIndex + i) >> 1) - 1);
+}
+
+HRESULT CEncoder::Create()
+{
+ if (!_matchFinder)
+ {
+ switch(_matchFinderIndex)
+ {
+ #ifdef COMPRESS_MF_BT
+ case kBT2:
+ _matchFinder = new NBT2::CMatchFinderBinTree;
+ break;
+ case kBT3:
+ _matchFinder = new NBT3::CMatchFinderBinTree;
+ break;
+ case kBT4:
+ _matchFinder = new NBT4::CMatchFinderBinTree;
+ break;
+ case kBT4B:
+ _matchFinder = new NBT4B::CMatchFinderBinTree;
+ break;
+ #endif
+
+ #ifdef COMPRESS_MF_PAT
+ case kPat2:
+ _matchFinder = new NPat2::CPatricia;
+ break;
+ case kPat2H:
+ _matchFinder = new NPat2H::CPatricia;
+ break;
+ case kPat3H:
+ _matchFinder = new NPat3H::CPatricia;
+ break;
+ case kPat4H:
+ _matchFinder = new NPat4H::CPatricia;
+ break;
+ case kPat2R:
+ _matchFinder = new NPat2R::CPatricia;
+ break;
+ #endif
+
+ #ifdef COMPRESS_MF_HC
+ case kHC3:
+ _matchFinder = new NHC3::CMatchFinderHC;
+ break;
+ case kHC4:
+ _matchFinder = new NHC4::CMatchFinderHC;
+ break;
+ #endif
+ }
+ #ifdef COMPRESS_MF_MT
+ if (_multiThread)
+ {
+ CMatchFinderMT *mfSpec = new CMatchFinderMT;
+ CMyComPtr<IMatchFinder> mf = mfSpec;
+ RINOK(mfSpec->SetMatchFinder(_matchFinder));
+ _matchFinder.Release();
+ _matchFinder = mf;
+ }
+ #endif
+ }
+ if (_dictionarySize == _dictionarySizePrev && _numFastBytesPrev == _numFastBytes)
+ return S_OK;
+ RINOK(_matchFinder->Create(_dictionarySize, kNumOpts, _numFastBytes,
+ kMatchMaxLen - _numFastBytes));
+ _dictionarySizePrev = _dictionarySize;
+ _numFastBytesPrev = _numFastBytes;
+ _literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits);
+ _lenEncoder.Create(1 << _posStateBits);
+ _repMatchLenEncoder.Create(1 << _posStateBits);
+ return S_OK;
+}
+
+static inline bool AreStringsEqual(const wchar_t *s, const wchar_t *testString)
+{
+ while (true)
+ {
+ wchar_t c = *testString;
+ if (c >= 'a' && c <= 'z')
+ c -= 0x20;
+ if (*s != c)
+ return false;
+ if (c == 0)
+ return true;
+ s++;
+ testString++;
+ }
+}
+
+// ICompressSetEncoderProperties2
+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 < 2 || numFastBytes > kMatchMaxLen)
+ return E_INVALIDARG;
+ _numFastBytes = numFastBytes;
+ 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;
+ int matchFinderIndexPrev = _matchFinderIndex;
+ _matchFinderIndex = 0;
+ const int kNumMFs = sizeof(kMatchFinderIDs) / sizeof(kMatchFinderIDs[0]);
+ int m;
+ for (m = 0; m < kNumMFs; m++)
+ {
+ if (AreStringsEqual(kMatchFinderIDs[m], prop.bstrVal))
+ {
+ _matchFinderIndex = m;
+ break;
+ }
+ }
+ if (m == kNumMFs)
+ return E_INVALIDARG;
+ if (!_matchFinder && matchFinderIndexPrev != _matchFinderIndex)
+ {
+ _dictionarySizePrev = UINT32(-1);
+ _matchFinder.Release();
+ }
+ break;
+ }
+ #ifdef COMPRESS_MF_MT
+ case NCoderPropID::kMultiThread:
+ {
+ if (prop.vt != VT_BOOL)
+ return E_INVALIDARG;
+ bool newMultiThread = (prop.boolVal != VARIANT_FALSE);
+ if (newMultiThread != _multiThread)
+ {
+ _dictionarySizePrev = UINT32(-1);
+ _matchFinder.Release();
+ }
+ _multiThread = newMultiThread;
+ break;
+ }
+ #endif
+ case NCoderPropID::kDictionarySize:
+ {
+ const int kDicLogSizeMaxCompress = 28;
+ 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 < 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 > 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 > kNumLitPosStatesBitsEncodingMax)
+ return E_INVALIDARG;
+ _numLiteralPosStateBits = value;
+ break;
+ }
+ case NCoderPropID::kLitContextBits:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UINT32 value = prop.ulVal;
+ if (value > kNumLitContextBitsMax)
+ return E_INVALIDARG;
+ _numLiteralContextBits = value;
+ break;
+ }
+ default:
+ return E_INVALIDARG;
+ }
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{
+ BYTE firstByte = (_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits;
+ RINOK(outStream->Write(&firstByte, sizeof(firstByte), NULL));
+ return outStream->Write(&_dictionarySize, sizeof(_dictionarySize), NULL);
+}
+
+STDMETHODIMP CEncoder::Init(
+ ISequentialOutStream *outStream)
+{
+ CBaseCoder::Init();
+
+ // RINOK(_matchFinder->Init(inStream));
+ _rangeEncoder.Init(outStream);
+
+ int i;
+ for(i = 0; i < kNumStates; i++)
+ {
+ for (UINT32 j = 0; j <= _posStateMask; j++)
+ {
+ _mainChoiceEncoders[i][j].Init();
+ _matchRepShortChoiceEncoders[i][j].Init();
+ }
+ _matchChoiceEncoders[i].Init();
+ _matchRepChoiceEncoders[i].Init();
+ _matchRep1ChoiceEncoders[i].Init();
+ _matchRep2ChoiceEncoders[i].Init();
+ }
+
+ _literalEncoder.Init();
+
+ // _repMatchLenEncoder.Init();
+
+ for(i = 0; i < kNumLenToPosStates; i++)
+ _posSlotEncoder[i].Init();
+
+ for(i = 0; i < kNumPosModels; i++)
+ _posEncoders[i].Init();
+
+ _lenEncoder.Init();
+ _repMatchLenEncoder.Init();
+
+ _posAlignEncoder.Init();
+
+ _longestMatchWasFound = false;
+ _optimumEndIndex = 0;
+ _optimumCurrentIndex = 0;
+ _additionalOffset = 0;
+
+ return S_OK;
+}
+
+void CEncoder::MovePos(UINT32 num)
+{
+ for (;num > 0; num--)
+ {
+ _matchFinder->DummyLongestMatch();
+ HRESULT result = _matchFinder->MovePos();
+ if (result != S_OK)
+ throw CMatchFinderException(result);
+ _additionalOffset++;
+ }
+}
+
+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;
+}
+
+/*
+inline UINT32 GetMatchLen(const BYTE *data, UINT32 back, UINT32 limit)
+{
+ back++;
+ for(UINT32 i = 0; i < limit && data[i] == data[i - back]; i++);
+ return i;
+}
+*/
+
+UINT32 CEncoder::GetOptimum(UINT32 &backRes, UINT32 position)
+{
+ if(_optimumEndIndex != _optimumCurrentIndex)
+ {
+ UINT32 len = _optimum[_optimumCurrentIndex].PosPrev - _optimumCurrentIndex;
+ backRes = _optimum[_optimumCurrentIndex].BackPrev;
+ _optimumCurrentIndex = _optimum[_optimumCurrentIndex].PosPrev;
+ return len;
+ }
+ _optimumCurrentIndex = 0;
+ _optimumEndIndex = 0; // test it;
+
+ UINT32 lenMain;
+ if (!_longestMatchWasFound)
+ lenMain = ReadMatchDistances();
+ else
+ {
+ lenMain = _longestMatchLength;
+ _longestMatchWasFound = false;
+ }
+
+
+ UINT32 reps[kNumRepDistances];
+ UINT32 repLens[kNumRepDistances];
+ UINT32 repMaxIndex = 0;
+ int i;
+ for(i = 0; i < kNumRepDistances; i++)
+ {
+ reps[i] = _repDistances[i];
+ repLens[i] = _matchFinder->GetMatchLen(0 - 1, reps[i], kMatchMaxLen);
+ if (i == 0 || repLens[i] > repLens[repMaxIndex])
+ repMaxIndex = i;
+ }
+ if(repLens[repMaxIndex] > _numFastBytes)
+ {
+ backRes = repMaxIndex;
+ MovePos(repLens[repMaxIndex] - 1);
+ return repLens[repMaxIndex];
+ }
+
+ if(lenMain > _numFastBytes)
+ {
+ UINT32 backMain = (lenMain < _numFastBytes) ? _matchDistances[lenMain] :
+ _matchDistances[_numFastBytes];
+ backRes = backMain + kNumRepDistances;
+ MovePos(lenMain - 1);
+ return lenMain;
+ }
+ BYTE currentByte = _matchFinder->GetIndexByte(0 - 1);
+
+ _optimum[0].State = _state;
+
+ BYTE matchByte;
+
+ matchByte = _matchFinder->GetIndexByte(0 - _repDistances[0] - 1 - 1);
+
+ UINT32 posState = (position & _posStateMask);
+
+ _optimum[1].Price = _mainChoiceEncoders[_state.Index][posState].GetPrice(kMainChoiceLiteralIndex) +
+ _literalEncoder.GetPrice(position, _previousByte, _peviousIsMatch, matchByte, currentByte);
+ _optimum[1].MakeAsChar();
+
+ _optimum[1].PosPrev = 0;
+
+ for (i = 0; i < kNumRepDistances; i++)
+ _optimum[0].Backs[i] = reps[i];
+
+ UINT32 matchPrice = _mainChoiceEncoders[_state.Index][posState].GetPrice(kMainChoiceMatchIndex);
+ UINT32 repMatchPrice = matchPrice +
+ _matchChoiceEncoders[_state.Index].GetPrice(kMatchChoiceRepetitionIndex);
+
+ if(matchByte == currentByte)
+ {
+ UINT32 shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState);
+ if(shortRepPrice < _optimum[1].Price)
+ {
+ _optimum[1].Price = shortRepPrice;
+ _optimum[1].MakeAsShortRep();
+ }
+ }
+ if(lenMain < 2)
+ {
+ backRes = _optimum[1].BackPrev;
+ return 1;
+ }
+
+
+ UINT32 normalMatchPrice = matchPrice +
+ _matchChoiceEncoders[_state.Index].GetPrice(kMatchChoiceDistanceIndex);
+
+ if (lenMain <= repLens[repMaxIndex])
+ lenMain = 0;
+
+ UINT32 len;
+ for(len = 2; len <= lenMain; len++)
+ {
+ _optimum[len].PosPrev = 0;
+ _optimum[len].BackPrev = _matchDistances[len] + kNumRepDistances;
+ _optimum[len].Price = normalMatchPrice +
+ GetPosLenPrice(_matchDistances[len], len, posState);
+ _optimum[len].Prev1IsChar = false;
+ }
+
+ if (lenMain < repLens[repMaxIndex])
+ lenMain = repLens[repMaxIndex];
+
+ for (; len <= lenMain; len++)
+ _optimum[len].Price = kIfinityPrice;
+
+ for(i = 0; i < kNumRepDistances; i++)
+ {
+ UINT repLen = repLens[i];
+ for(UINT32 lenTest = 2; lenTest <= repLen; lenTest++)
+ {
+ UINT32 curAndLenPrice = repMatchPrice + GetRepPrice(i, lenTest, _state, posState);
+ COptimal &optimum = _optimum[lenTest];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = 0;
+ optimum.BackPrev = i;
+ optimum.Prev1IsChar = false;
+ }
+ }
+ }
+
+ UINT32 cur = 0;
+ UINT32 lenEnd = lenMain;
+
+ while(true)
+ {
+ cur++;
+ if(cur == lenEnd)
+ return Backward(backRes, cur);
+ position++;
+ UINT32 posPrev = _optimum[cur].PosPrev;
+ CState state;
+ if (_optimum[cur].Prev1IsChar)
+ {
+ posPrev--;
+ if (_optimum[cur].Prev2)
+ {
+ state = _optimum[_optimum[cur].PosPrev2].State;
+ if (_optimum[cur].BackPrev2 < kNumRepDistances)
+ state.UpdateRep();
+ else
+ state.UpdateMatch();
+ }
+ else
+ state = _optimum[posPrev].State;
+ state.UpdateChar();
+ }
+ else
+ state = _optimum[posPrev].State;
+ bool prevWasMatch;
+ if (posPrev == cur - 1)
+ {
+ if (_optimum[cur].IsShortRep())
+ {
+ prevWasMatch = true;
+ state.UpdateShortRep();
+ }
+ else
+ {
+ prevWasMatch = false;
+ state.UpdateChar();
+ }
+ /*
+ if (_optimum[cur].Prev1IsChar)
+ for(int i = 0; i < kNumRepDistances; i++)
+ reps[i] = _optimum[posPrev].Backs[i];
+ */
+ }
+ else
+ {
+ prevWasMatch = true;
+ UINT32 pos;
+ if (_optimum[cur].Prev1IsChar && _optimum[cur].Prev2)
+ {
+ posPrev = _optimum[cur].PosPrev2;
+ pos = _optimum[cur].BackPrev2;
+ state.UpdateRep();
+ }
+ else
+ {
+ pos = _optimum[cur].BackPrev;
+ if (pos < kNumRepDistances)
+ state.UpdateRep();
+ else
+ state.UpdateMatch();
+ }
+ if (pos < kNumRepDistances)
+ {
+ reps[0] = _optimum[posPrev].Backs[pos];
+ UINT32 i;
+ for(i = 1; i <= pos; i++)
+ reps[i] = _optimum[posPrev].Backs[i - 1];
+ for(; i < kNumRepDistances; i++)
+ reps[i] = _optimum[posPrev].Backs[i];
+ }
+ else
+ {
+ reps[0] = (pos - kNumRepDistances);
+ for(UINT32 i = 1; i < kNumRepDistances; i++)
+ reps[i] = _optimum[posPrev].Backs[i - 1];
+ }
+ }
+ _optimum[cur].State = state;
+ for(UINT32 i = 0; i < kNumRepDistances; i++)
+ _optimum[cur].Backs[i] = reps[i];
+ UINT32 newLen = ReadMatchDistances();
+ if(newLen > _numFastBytes)
+ {
+ _longestMatchLength = newLen;
+ _longestMatchWasFound = true;
+ return Backward(backRes, cur);
+ }
+ UINT32 curPrice = _optimum[cur].Price;
+ // BYTE currentByte = _matchFinder->GetIndexByte(0 - 1);
+ // BYTE matchByte = _matchFinder->GetIndexByte(0 - reps[0] - 1 - 1);
+ const BYTE *data = _matchFinder->GetPointerToCurrentPos() - 1;
+ BYTE currentByte = *data;
+ BYTE matchByte = data[0 - reps[0] - 1];
+
+ UINT32 posState = (position & _posStateMask);
+
+ UINT32 curAnd1Price = curPrice +
+ _mainChoiceEncoders[state.Index][posState].GetPrice(kMainChoiceLiteralIndex) +
+ _literalEncoder.GetPrice(position, data[-1], prevWasMatch, 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 + _mainChoiceEncoders[state.Index][posState].GetPrice(kMainChoiceMatchIndex);
+ UINT32 repMatchPrice = matchPrice + _matchChoiceEncoders[state.Index].GetPrice(kMatchChoiceRepetitionIndex);
+
+ 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 = false;
+ }
+ }
+ /*
+ if(newLen == 2 && _matchDistances[2] >= kDistLimit2) // test it maybe set 2000 ?
+ continue;
+ */
+
+ UINT32 numAvailableBytes = _matchFinder->GetNumAvailableBytes() + 1;
+ numAvailableBytes = MyMin(kNumOpts - 1 - cur, numAvailableBytes);
+
+ if (numAvailableBytes < 2)
+ continue;
+ if (numAvailableBytes > _numFastBytes)
+ numAvailableBytes = _numFastBytes;
+ if (numAvailableBytes >= 3 && !nextIsChar)
+ {
+ UINT32 backOffset = reps[0] + 1;
+ UINT32 temp;
+ for (temp = 1; temp < numAvailableBytes; temp++)
+ if (data[temp] != data[temp - backOffset])
+ break;
+ UINT32 lenTest2 = temp - 1;
+ if (lenTest2 >= 2)
+ {
+ CState state2 = state;
+ state2.UpdateChar();
+ UINT32 posStateNext = (position + 1) & _posStateMask;
+ UINT32 nextRepMatchPrice = curAnd1Price +
+ _mainChoiceEncoders[state2.Index][posStateNext].GetPrice(kMainChoiceMatchIndex) +
+ _matchChoiceEncoders[state2.Index].GetPrice(kMatchChoiceRepetitionIndex);
+ // for (; lenTest2 >= 2; lenTest2--)
+ {
+ while(lenEnd < cur + 1 + lenTest2)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ UINT32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(
+ 0, lenTest2, state2, posStateNext);
+ COptimal &optimum = _optimum[cur + 1 + lenTest2];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur + 1;
+ optimum.BackPrev = 0;
+ optimum.Prev1IsChar = true;
+ optimum.Prev2 = false;
+ }
+ }
+ }
+ }
+ for(UINT32 repIndex = 0; repIndex < kNumRepDistances; repIndex++)
+ {
+ // UINT32 repLen = _matchFinder->GetMatchLen(0 - 1, reps[repIndex], newLen); // test it;
+ UINT32 backOffset = reps[repIndex] + 1;
+ UINT32 lenTest;
+ for (lenTest = 0; lenTest < numAvailableBytes; lenTest++)
+ if (data[lenTest] != data[lenTest - backOffset])
+ break;
+ for(; lenTest >= 2; lenTest--)
+ {
+ while(lenEnd < cur + lenTest)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ UINT32 curAndLenPrice = repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState);
+ COptimal &optimum = _optimum[cur + lenTest];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur;
+ optimum.BackPrev = repIndex;
+ optimum.Prev1IsChar = false;
+ }
+
+ /*
+ if (_maxMode)
+ {
+ UINT32 temp;
+ for (temp = lenTest + 1; temp < numAvailableBytes; temp++)
+ if (data[temp] != data[temp - backOffset])
+ break;
+ UINT32 lenTest2 = temp - (lenTest + 1);
+ if (lenTest2 >= 2)
+ {
+ CState state2 = state;
+ state2.UpdateRep();
+ UINT32 posStateNext = (position + lenTest) & _posStateMask;
+ UINT32 curAndLenCharPrice = curAndLenPrice +
+ _mainChoiceEncoders[state2.Index][posStateNext].GetPrice(kMainChoiceLiteralIndex) +
+ _literalEncoder.GetPrice(position + lenTest, data[lenTest - 1],
+ true, data[lenTest - backOffset], data[lenTest]);
+ state2.UpdateChar();
+ posStateNext = (position + lenTest + 1) & _posStateMask;
+ UINT32 nextMatchPrice = curAndLenCharPrice + _mainChoiceEncoders[state2.Index][posStateNext].GetPrice(kMainChoiceMatchIndex);
+ UINT32 nextRepMatchPrice = nextMatchPrice + _matchChoiceEncoders[state2.Index].GetPrice(kMatchChoiceRepetitionIndex);
+
+ // for(; lenTest2 >= 2; lenTest2--)
+ {
+ UINT32 offset = lenTest + 1 + lenTest2;
+ while(lenEnd < cur + offset)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ UINT32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(
+ 0, lenTest2, state2, posStateNext);
+ COptimal &optimum = _optimum[cur + 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;
+ if (newLen >= 2)
+ {
+ if (newLen == 2 && _matchDistances[2] >= 0x80)
+ continue;
+ UINT32 normalMatchPrice = matchPrice +
+ _matchChoiceEncoders[state.Index].GetPrice(kMatchChoiceDistanceIndex);
+ while(lenEnd < cur + newLen)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+
+ for(UINT32 lenTest = newLen; lenTest >= 2; lenTest--)
+ {
+ UINT32 curBack = _matchDistances[lenTest];
+ UINT32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(curBack, lenTest, 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)
+ {
+ UINT32 backOffset = curBack + 1;
+ UINT32 temp;
+ for (temp = lenTest + 1; temp < numAvailableBytes; temp++)
+ if (data[temp] != data[temp - backOffset])
+ break;
+ UINT32 lenTest2 = temp - (lenTest + 1);
+ if (lenTest2 >= 2)
+ {
+ CState state2 = state;
+ state2.UpdateMatch();
+ UINT32 posStateNext = (position + lenTest) & _posStateMask;
+ UINT32 curAndLenCharPrice = curAndLenPrice +
+ _mainChoiceEncoders[state2.Index][posStateNext].GetPrice(kMainChoiceLiteralIndex) +
+ _literalEncoder.GetPrice(position + lenTest, data[lenTest - 1],
+ true, data[lenTest - backOffset], data[lenTest]);
+ state2.UpdateChar();
+ posStateNext = (position + lenTest + 1) & _posStateMask;
+ UINT32 nextMatchPrice = curAndLenCharPrice + _mainChoiceEncoders[state2.Index][posStateNext].GetPrice(kMainChoiceMatchIndex);
+ UINT32 nextRepMatchPrice = nextMatchPrice + _matchChoiceEncoders[state2.Index].GetPrice(kMatchChoiceRepetitionIndex);
+
+ // for(; lenTest2 >= 2; lenTest2--)
+ {
+ UINT32 offset = lenTest + 1 + lenTest2;
+ while(lenEnd < cur + offset)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ UINT32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(
+ 0, lenTest2, state2, posStateNext);
+ COptimal &optimum = _optimum[cur + 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;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+static inline bool ChangePair(UINT32 smallDist, UINT32 bigDist)
+{
+ const int kDif = 7;
+ return (smallDist < (UINT32(1) << (32-kDif)) && bigDist >= (smallDist << kDif));
+}
+
+
+UINT32 CEncoder::GetOptimumFast(UINT32 &backRes, UINT32 position)
+{
+ UINT32 lenMain;
+ if (!_longestMatchWasFound)
+ lenMain = ReadMatchDistances();
+ else
+ {
+ lenMain = _longestMatchLength;
+ _longestMatchWasFound = false;
+ }
+ UINT32 repLens[kNumRepDistances];
+ UINT32 repMaxIndex = 0;
+ for(int i = 0; i < kNumRepDistances; i++)
+ {
+ repLens[i] = _matchFinder->GetMatchLen(0 - 1, _repDistances[i], kMatchMaxLen);
+ if (i == 0 || repLens[i] > repLens[repMaxIndex])
+ repMaxIndex = i;
+ }
+ if(repLens[repMaxIndex] >= _numFastBytes)
+ {
+ backRes = repMaxIndex;
+ MovePos(repLens[repMaxIndex] - 1);
+ return repLens[repMaxIndex];
+ }
+ if(lenMain >= _numFastBytes)
+ {
+ backRes = _matchDistances[_numFastBytes] + kNumRepDistances;
+ MovePos(lenMain - 1);
+ return lenMain;
+ }
+ while (lenMain > 2)
+ {
+ if (!ChangePair(_matchDistances[lenMain - 1], _matchDistances[lenMain]))
+ break;
+ lenMain--;
+ }
+ if (lenMain == 2 && _matchDistances[2] >= 0x80)
+ lenMain = 1;
+
+ UINT32 backMain = _matchDistances[lenMain];
+ if (repLens[repMaxIndex] >= 2)
+ {
+ if (repLens[repMaxIndex] + 1 >= lenMain ||
+ repLens[repMaxIndex] + 2 >= lenMain && (backMain > (1<<12)))
+ {
+ backRes = repMaxIndex;
+ MovePos(repLens[repMaxIndex] - 1);
+ return repLens[repMaxIndex];
+ }
+ }
+
+
+ if (lenMain >= 2)
+ {
+ _longestMatchLength = ReadMatchDistances();
+ if (_longestMatchLength >= 2 &&
+ (
+ (_longestMatchLength >= lenMain &&
+ _matchDistances[lenMain] < backMain) ||
+ _longestMatchLength == lenMain + 1 &&
+ !ChangePair(backMain, _matchDistances[_longestMatchLength]) ||
+ _longestMatchLength > lenMain + 1 ||
+ _longestMatchLength + 1 >= lenMain &&
+ ChangePair(_matchDistances[lenMain - 1], backMain)
+ )
+ )
+ {
+ _longestMatchWasFound = true;
+ backRes = UINT32(-1);
+ return 1;
+ }
+ for(int i = 0; i < kNumRepDistances; i++)
+ {
+ UINT32 repLen = _matchFinder->GetMatchLen(0 - 1, _repDistances[i], kMatchMaxLen);
+ if (repLen >= 2 && repLen + 1 >= lenMain)
+ {
+ _longestMatchWasFound = true;
+ backRes = UINT32(-1);
+ return 1;
+ }
+ }
+ backRes = backMain + kNumRepDistances;
+ MovePos(lenMain - 2);
+ return lenMain;
+ }
+ backRes = UINT32(-1);
+ return 1;
+}
+
+STDMETHODIMP CEncoder::InitMatchFinder(IMatchFinder *matchFinder)
+{
+ _matchFinder = matchFinder;
+ return S_OK;
+}
+
+HRESULT CEncoder::Flush()
+{
+ _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;
+
+ _mainChoiceEncoders[_state.Index][posState].Encode(&_rangeEncoder, kMainChoiceMatchIndex);
+ _matchChoiceEncoders[_state.Index].Encode(&_rangeEncoder, kMatchChoiceDistanceIndex);
+ _state.UpdateMatch();
+ UINT32 len = kMatchMinLen; // kMatchMaxLen;
+ _lenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState);
+ 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.Encode(&_rangeEncoder, posReduced & kAlignMask);
+}
+
+HRESULT CEncoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ RINOK(SetStreams(inStream, outStream, inSize, outSize));
+ while(true)
+ {
+ UINT64 processedInSize;
+ UINT64 processedOutSize;
+ INT32 finished;
+ RINOK(CodeOneBlock(&processedInSize, &processedOutSize, &finished));
+ if (finished != 0)
+ return S_OK;
+ if (progress != 0)
+ {
+ RINOK(progress->SetRatioInfo(&processedInSize, &processedOutSize));
+ }
+ }
+}
+
+HRESULT CEncoder::SetStreams(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UINT64 *inSize, const UINT64 *outSize)
+{
+ _inStream = inStream;
+ _finished = false;
+ RINOK(Create());
+ RINOK(Init(outStream));
+
+ // CCoderReleaser releaser(this);
+
+ /*
+ if (_matchFinder->GetNumAvailableBytes() == 0)
+ return Flush();
+ */
+
+ if (!_fastMode)
+ {
+ FillPosSlotPrices();
+ FillDistancesPrices();
+ FillAlignPrices();
+ }
+
+ _lenEncoder.SetTableSize(_numFastBytes);
+ _lenEncoder.UpdateTables();
+ _repMatchLenEncoder.SetTableSize(_numFastBytes);
+ _repMatchLenEncoder.UpdateTables();
+
+ lastPosSlotFillingPos = 0;
+ nowPos64 = 0;
+ return S_OK;
+}
+
+HRESULT CEncoder::CodeOneBlock(UINT64 *inSize, UINT64 *outSize, INT32 *finished)
+{
+ if (_inStream != 0)
+ {
+ RINOK(_matchFinder->Init(_inStream));
+ _inStream = 0;
+ }
+
+
+ *finished = 1;
+ if (_finished)
+ return S_OK;
+ _finished = true;
+
+
+ UINT64 progressPosValuePrev = nowPos64;
+ if (nowPos64 == 0)
+ {
+ if (_matchFinder->GetNumAvailableBytes() == 0)
+ {
+ _matchFinder->ReleaseStream();
+ WriteEndMarker(UINT32(nowPos64) & _posStateMask);
+ return Flush();
+ }
+ ReadMatchDistances();
+ UINT32 posState = UINT32(nowPos64) & _posStateMask;
+ _mainChoiceEncoders[_state.Index][posState].Encode(&_rangeEncoder, kMainChoiceLiteralIndex);
+ _state.UpdateChar();
+ BYTE curByte = _matchFinder->GetIndexByte(0 - _additionalOffset);
+ _literalEncoder.Encode(&_rangeEncoder, UINT32(nowPos64), _previousByte,
+ false, 0, curByte);
+ _previousByte = curByte;
+ _additionalOffset--;
+ nowPos64++;
+ }
+ if (_matchFinder->GetNumAvailableBytes() == 0)
+ {
+ _matchFinder->ReleaseStream();
+ WriteEndMarker(UINT32(nowPos64) & _posStateMask);
+ return Flush();
+ }
+ while(true)
+ {
+ UINT32 pos;
+ UINT32 posState = UINT32(nowPos64) & _posStateMask;
+
+ UINT32 len;
+ if (_fastMode)
+ len = GetOptimumFast(pos, UINT32(nowPos64));
+ else
+ len = GetOptimum(pos, UINT32(nowPos64));
+
+ if(len == 1 && pos == (-1))
+ {
+ _mainChoiceEncoders[_state.Index][posState].Encode(&_rangeEncoder, kMainChoiceLiteralIndex);
+ _state.UpdateChar();
+ BYTE matchByte;
+ if(_peviousIsMatch)
+ matchByte = _matchFinder->GetIndexByte(0 - _repDistances[0] - 1 - _additionalOffset);
+ BYTE curByte = _matchFinder->GetIndexByte(0 - _additionalOffset);
+ _literalEncoder.Encode(&_rangeEncoder, UINT32(nowPos64), _previousByte, _peviousIsMatch,
+ matchByte, curByte);
+ _previousByte = curByte;
+ _peviousIsMatch = false;
+ }
+ else
+ {
+ _peviousIsMatch = true;
+ _mainChoiceEncoders[_state.Index][posState].Encode(&_rangeEncoder, kMainChoiceMatchIndex);
+ if(pos < kNumRepDistances)
+ {
+ _matchChoiceEncoders[_state.Index].Encode(&_rangeEncoder, kMatchChoiceRepetitionIndex);
+ if(pos == 0)
+ {
+ _matchRepChoiceEncoders[_state.Index].Encode(&_rangeEncoder, 0);
+ if(len == 1)
+ _matchRepShortChoiceEncoders[_state.Index][posState].Encode(&_rangeEncoder, 0);
+ else
+ _matchRepShortChoiceEncoders[_state.Index][posState].Encode(&_rangeEncoder, 1);
+ }
+ else
+ {
+ _matchRepChoiceEncoders[_state.Index].Encode(&_rangeEncoder, 1);
+ if (pos == 1)
+ _matchRep1ChoiceEncoders[_state.Index].Encode(&_rangeEncoder, 0);
+ else
+ {
+ _matchRep1ChoiceEncoders[_state.Index].Encode(&_rangeEncoder, 1);
+ _matchRep2ChoiceEncoders[_state.Index].Encode(&_rangeEncoder, pos - 2);
+ }
+ }
+ if (len == 1)
+ _state.UpdateShortRep();
+ else
+ {
+ _repMatchLenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState);
+ _state.UpdateRep();
+ }
+
+
+ UINT32 distance = _repDistances[pos];
+ if (pos != 0)
+ {
+ for(UINT32 i = pos; i >= 1; i--)
+ _repDistances[i] = _repDistances[i - 1];
+ _repDistances[0] = distance;
+ }
+ }
+ else
+ {
+ _matchChoiceEncoders[_state.Index].Encode(&_rangeEncoder, kMatchChoiceDistanceIndex);
+ _state.UpdateMatch();
+ _lenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState);
+ pos -= kNumRepDistances;
+ UINT32 posSlot = GetPosSlot(pos);
+ UINT32 lenToPosState = GetLenToPosState(len);
+ _posSlotEncoder[lenToPosState].Encode(&_rangeEncoder, posSlot);
+
+ if (posSlot >= kStartPosModelIndex)
+ {
+ UINT32 footerBits = ((posSlot >> 1) - 1);
+ UINT32 posReduced = pos - ((2 | (posSlot & 1)) << footerBits);
+
+ if (posSlot < kEndPosModelIndex)
+ _posEncoders[posSlot - kStartPosModelIndex].Encode(&_rangeEncoder, posReduced);
+ else
+ {
+ _rangeEncoder.EncodeDirectBits(posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
+ _posAlignEncoder.Encode(&_rangeEncoder, posReduced & kAlignMask);
+ if (!_fastMode)
+ if (--_alignPriceCount == 0)
+ FillAlignPrices();
+ }
+ }
+ UINT32 distance = pos;
+ for(UINT32 i = kNumRepDistances - 1; i >= 1; i--)
+ _repDistances[i] = _repDistances[i - 1];
+ _repDistances[0] = distance;
+ }
+ _previousByte = _matchFinder->GetIndexByte(len - 1 - _additionalOffset);
+ }
+ _additionalOffset -= len;
+ nowPos64 += len;
+ if (!_fastMode)
+ if (nowPos64 - lastPosSlotFillingPos >= (1 << 9))
+ {
+ FillPosSlotPrices();
+ FillDistancesPrices();
+ lastPosSlotFillingPos = nowPos64;
+ }
+ if (_additionalOffset == 0)
+ {
+ *inSize = nowPos64;
+ *outSize = _rangeEncoder.GetProcessedSize();
+ if (_matchFinder->GetNumAvailableBytes() == 0)
+ {
+ _matchFinder->ReleaseStream();
+ WriteEndMarker(UINT32(nowPos64) & _posStateMask);
+ return Flush();
+ }
+ if (nowPos64 - progressPosValuePrev >= (1 << 12))
+ {
+ _finished = false;
+ *finished = 0;
+ 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(CMatchFinderException &e) { return e.ErrorCode; }
+ catch(const COutBufferException &e) { return e.ErrorCode; }
+ catch(...) { return E_FAIL; }
+}
+
+void CEncoder::FillPosSlotPrices()
+{
+ for (int lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
+ {
+ UINT32 posSlot;
+ for (posSlot = 0; posSlot < kEndPosModelIndex && posSlot < _distTableSize; posSlot++)
+ _posSlotPrices[lenToPosState][posSlot] = _posSlotEncoder[lenToPosState].GetPrice(posSlot);
+ for (; posSlot < _distTableSize; posSlot++)
+ _posSlotPrices[lenToPosState][posSlot] = _posSlotEncoder[lenToPosState].GetPrice(posSlot) +
+ ((((posSlot >> 1) - 1) - kNumAlignBits) << NRangeCoder::kNumBitPriceShiftBits);
+ }
+}
+
+void CEncoder::FillDistancesPrices()
+{
+ for (int lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
+ {
+ UINT32 i;
+ for (i = 0; i < kStartPosModelIndex; i++)
+ _distancesPrices[lenToPosState][i] = _posSlotPrices[lenToPosState][i];
+ for (; i < kNumFullDistances; i++)
+ {
+ UINT32 posSlot = GetPosSlot(i);
+ _distancesPrices[lenToPosState][i] = _posSlotPrices[lenToPosState][posSlot] +
+ _posEncoders[posSlot - kStartPosModelIndex].GetPrice(i -
+ ((2 | (posSlot & 1)) << (((posSlot >> 1) - 1))));
+ }
+ }
+}
+
+void CEncoder::FillAlignPrices()
+{
+ for (int i = 0; i < kAlignTableSize; i++)
+ _alignPrices[i] = _posAlignEncoder.GetPrice(i);
+ _alignPriceCount = kAlignTableSize;
+}
+
+}}
diff --git a/7zip/Compress/LZMA/LZMAEncoder.h b/7zip/Compress/LZMA/LZMAEncoder.h
new file mode 100755
index 00000000..7e29ee51
--- /dev/null
+++ b/7zip/Compress/LZMA/LZMAEncoder.h
@@ -0,0 +1,294 @@
+// LZMA/Encoder.h
+
+// #pragma once
+
+#ifndef __LZMA_ENCODER_H
+#define __LZMA_ENCODER_H
+
+#include "../../ICoder.h"
+#include "../../../Common/MyCom.h"
+#include "../LZ/IMatchFinder.h"
+
+#include "LZMA.h"
+#include "LZMALen.h"
+#include "LZMALiteral.h"
+
+namespace NCompress {
+namespace NLZMA {
+
+class CMatchFinderException
+{
+public:
+ HRESULT ErrorCode;
+ CMatchFinderException(HRESULT errorCode): ErrorCode(errorCode) {}
+};
+
+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[1024];
+inline UINT32 GetPosSlot(UINT32 pos)
+{
+ if (pos < (1 << 10))
+ return g_FastPos[pos];
+ if (pos < (1 << 19))
+ return g_FastPos[pos >> 9] + 18;
+ return g_FastPos[pos >> 18] + 36;
+}
+
+inline UINT32 GetPosSlot2(UINT32 pos)
+{
+ if (pos < (1 << 16))
+ return g_FastPos[pos >> 6] + 12;
+ if (pos < (1 << 25))
+ return g_FastPos[pos >> 15] + 30;
+ return g_FastPos[pos >> 24] + 48;
+}
+
+const UINT32 kIfinityPrice = 0xFFFFFFF;
+
+typedef NRangeCoder::CBitEncoder<kNumMoveBits> CMyBitEncoder;
+
+const UINT32 kNumOpts = 1 << 12;
+
+class CEncoder :
+ public ICompressCoder,
+ // public IInitMatchFinder,
+ public ICompressSetCoderProperties,
+ public ICompressWriteCoderProperties,
+ public CBaseCoder,
+ public CMyUnknownImp
+{
+ COptimal _optimum[kNumOpts];
+public:
+ CMyComPtr<IMatchFinder> _matchFinder; // test it
+ NRangeCoder::CEncoder _rangeEncoder;
+private:
+
+ CMyBitEncoder _mainChoiceEncoders[kNumStates][NLength::kNumPosStatesEncodingMax];
+ CMyBitEncoder _matchChoiceEncoders[kNumStates];
+ CMyBitEncoder _matchRepChoiceEncoders[kNumStates];
+ CMyBitEncoder _matchRep1ChoiceEncoders[kNumStates];
+ CMyBitEncoder _matchRep2ChoiceEncoders[kNumStates];
+ CMyBitEncoder _matchRepShortChoiceEncoders[kNumStates][NLength::kNumPosStatesEncodingMax];
+
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumPosSlotBits> _posSlotEncoder[kNumLenToPosStates];
+
+ NRangeCoder::CReverseBitTreeEncoder2<kNumMoveBits> _posEncoders[kNumPosModels];
+ NRangeCoder::CReverseBitTreeEncoder2<kNumMoveBits> _posAlignEncoder;
+
+ NLength::CPriceTableEncoder _lenEncoder;
+ NLength::CPriceTableEncoder _repMatchLenEncoder;
+
+ NLiteral::CEncoder _literalEncoder;
+
+ UINT32 _matchDistances[kMatchMaxLen + 1];
+
+ bool _fastMode;
+ bool _maxMode;
+ UINT32 _numFastBytes;
+ UINT32 _longestMatchLength;
+
+ 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 _dictionarySizePrev;
+ UINT32 _numFastBytesPrev;
+
+ UINT64 lastPosSlotFillingPos;
+ UINT64 nowPos64;
+ bool _finished;
+ ISequentialInStream *_inStream;
+
+ int _matchFinderIndex;
+ #ifdef COMPRESS_MF_MT
+ bool _multiThread;
+ #endif
+
+ bool _writeEndMark;
+
+ UINT32 ReadMatchDistances()
+ {
+ UINT32 len = _matchFinder->GetLongestMatch(_matchDistances);
+ if (len == _numFastBytes)
+ len += _matchFinder->GetMatchLen(len, _matchDistances[len],
+ kMatchMaxLen - len);
+ _additionalOffset++;
+ HRESULT result = _matchFinder->MovePos();
+ if (result != S_OK)
+ throw CMatchFinderException(result);
+ return len;
+ }
+
+ void MovePos(UINT32 num);
+ UINT32 GetRepLen1Price(CState state, UINT32 posState) const
+ {
+ return _matchRepChoiceEncoders[state.Index].GetPrice(0) +
+ _matchRepShortChoiceEncoders[state.Index][posState].GetPrice(0);
+ }
+ UINT32 GetRepPrice(UINT32 repIndex, UINT32 len, CState state, UINT32 posState) const
+ {
+ UINT32 price = _repMatchLenEncoder.GetPrice(len - kMatchMinLen, posState);
+ if(repIndex == 0)
+ {
+ price += _matchRepChoiceEncoders[state.Index].GetPrice(0);
+ price += _matchRepShortChoiceEncoders[state.Index][posState].GetPrice(1);
+ }
+ else
+ {
+ price += _matchRepChoiceEncoders[state.Index].GetPrice(1);
+ if (repIndex == 1)
+ price += _matchRep1ChoiceEncoders[state.Index].GetPrice(0);
+ else
+ {
+ price += _matchRep1ChoiceEncoders[state.Index].GetPrice(1);
+ price += _matchRep2ChoiceEncoders[state.Index].GetPrice(repIndex - 2);
+ }
+ }
+ return price;
+ }
+ /*
+ 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
+ {
+ if (len == 2 && pos >= 0x80)
+ return kIfinityPrice;
+ 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 &backRes, UINT32 position);
+ UINT32 GetOptimumFast(UINT32 &backRes, UINT32 position);
+
+ void FillPosSlotPrices();
+ void FillDistancesPrices();
+ void FillAlignPrices();
+
+ void ReleaseStreams()
+ {
+ _matchFinder->ReleaseStream();
+ // _rangeEncoder.ReleaseStream();
+ }
+
+ HRESULT Flush();
+ 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_IMP2(
+ ICompressSetCoderProperties,
+ ICompressWriteCoderProperties
+ )
+
+ STDMETHOD(Init)(
+ ISequentialOutStream *outStream);
+
+ // 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);
+
+ // IInitMatchFinder interface
+ STDMETHOD(InitMatchFinder)(IMatchFinder *matchFinder);
+
+ // ICompressSetCoderProperties2
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
+ const PROPVARIANT *properties, UINT32 numProperties);
+
+ // ICompressWriteCoderProperties
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+};
+
+}}
+
+#endif
diff --git a/7zip/Compress/LZMA/LZMALen.cpp b/7zip/Compress/LZMA/LZMALen.cpp
new file mode 100755
index 00000000..0a422605
--- /dev/null
+++ b/7zip/Compress/LZMA/LZMALen.cpp
@@ -0,0 +1,74 @@
+// LZMALen.cpp
+
+#include "StdAfx.h"
+
+#include "LZMALen.h"
+
+namespace NCompress {
+namespace NLZMA {
+namespace NLength {
+
+void CEncoder::Init()
+{
+ _choice.Init();
+ for (UINT32 posState = 0; posState < _numPosStates; posState++)
+ {
+ _lowCoder[posState].Init();
+ _midCoder[posState].Init();
+ }
+ _choice2.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
+ {
+ symbol -= kNumLowSymbols;
+ _choice.Encode(rangeEncoder, 1);
+ if(symbol < kNumMidSymbols)
+ {
+ _choice2.Encode(rangeEncoder, 0);
+ _midCoder[posState].Encode(rangeEncoder, symbol);
+ }
+ else
+ {
+ _choice2.Encode(rangeEncoder, 1);
+ _highCoder.Encode(rangeEncoder, symbol - kNumMidSymbols);
+ }
+ }
+}
+
+UINT32 CEncoder::GetPrice(UINT32 symbol, UINT32 posState) const
+{
+ UINT32 price = 0;
+ if(symbol < kNumLowSymbols)
+ {
+ price += _choice.GetPrice(0);
+ price += _lowCoder[posState].GetPrice(symbol);
+ }
+ else
+ {
+ symbol -= kNumLowSymbols;
+ price += _choice.GetPrice(1);
+ if(symbol < kNumMidSymbols)
+ {
+ price += _choice2.GetPrice(0);
+ price += _midCoder[posState].GetPrice(symbol);
+ }
+ else
+ {
+ price += _choice2.GetPrice(1);
+ price += _highCoder.GetPrice(symbol - kNumMidSymbols);
+ }
+ }
+ return price;
+}
+
+}}}
+
diff --git a/7zip/Compress/LZMA/LZMALen.h b/7zip/Compress/LZMA/LZMALen.h
new file mode 100755
index 00000000..c8b61f3d
--- /dev/null
+++ b/7zip/Compress/LZMA/LZMALen.h
@@ -0,0 +1,114 @@
+// LenCoder.h
+
+// #pragma once
+
+#ifndef __LENCODER_H
+#define __LENCODER_H
+
+#include "../RangeCoder/RangeCoderBitTree.h"
+
+namespace NCompress {
+namespace NLZMA {
+namespace NLength {
+
+const int kNumMoveBits = 5;
+
+const int kNumPosStatesBitsMax = 4;
+const UINT32 kNumPosStatesMax = (1 << kNumPosStatesBitsMax);
+
+const int kNumPosStatesBitsEncodingMax = 4;
+const UINT32 kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);
+
+const int kNumLenBits = 3;
+const UINT32 kNumLowSymbols = 1 << kNumLenBits;
+const int kNumMidBits = 3;
+const UINT32 kNumMidSymbols = 1 << kNumMidBits;
+
+const int kNumHighBits = 8;
+
+const UINT32 kNumSymbolsTotal = kNumLowSymbols + kNumMidSymbols + (1 << kNumHighBits);
+
+class CEncoder
+{
+ NRangeCoder::CBitEncoder<kNumMoveBits> _choice;
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumLenBits> _lowCoder[kNumPosStatesEncodingMax];
+ NRangeCoder::CBitEncoder<kNumMoveBits> _choice2;
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesEncodingMax];
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumHighBits> _highCoder;
+protected:
+ UINT32 _numPosStates;
+public:
+ void Create(UINT32 numPosStates)
+ { _numPosStates = numPosStates; }
+ void Init();
+ void Encode(NRangeCoder::CEncoder *rangeEncoder, UINT32 symbol, UINT32 posState);
+ UINT32 GetPrice(UINT32 symbol, UINT32 posState) const;
+};
+
+const UINT32 kNumSpecSymbols = kNumLowSymbols + kNumMidSymbols;
+
+class CPriceTableEncoder: public CEncoder
+{
+ UINT32 _prices[kNumSymbolsTotal][kNumPosStatesEncodingMax];
+ UINT32 _tableSize;
+ UINT32 _counters[kNumPosStatesEncodingMax];
+public:
+ void SetTableSize(UINT32 tableSize)
+ { _tableSize = tableSize; }
+ UINT32 GetPrice(UINT32 symbol, UINT32 posState) const
+ { return _prices[symbol][posState]; }
+ void UpdateTable(UINT32 posState)
+ {
+ for (UINT32 len = 0; len < _tableSize; len++)
+ _prices[len][posState] = CEncoder::GetPrice(len , posState);
+ _counters[posState] = _tableSize;
+ }
+ void UpdateTables()
+ {
+ for (UINT32 posState = 0; posState < _numPosStates; posState++)
+ UpdateTable(posState);
+ }
+ void Encode(NRangeCoder::CEncoder *rangeEncoder, UINT32 symbol, UINT32 posState)
+ {
+ CEncoder::Encode(rangeEncoder, symbol, posState);
+ if (--_counters[posState] == 0)
+ UpdateTable(posState);
+ }
+};
+
+
+class CDecoder
+{
+ NRangeCoder::CBitDecoder<kNumMoveBits> _choice;
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumLenBits> _lowCoder[kNumPosStatesMax];
+ NRangeCoder::CBitDecoder<kNumMoveBits> _choice2;
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesMax];
+ NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumHighBits> _highCoder;
+ UINT32 _numPosStates;
+public:
+ void Create(UINT32 numPosStates)
+ { _numPosStates = numPosStates; }
+ void Init()
+ {
+ _choice.Init();
+ for (UINT32 posState = 0; posState < _numPosStates; posState++)
+ {
+ _lowCoder[posState].Init();
+ _midCoder[posState].Init();
+ }
+ _choice2.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);
+ }
+};
+
+}}}
+
+#endif
diff --git a/7zip/Compress/LZMA/LZMALiteral.cpp b/7zip/Compress/LZMA/LZMALiteral.cpp
new file mode 100755
index 00000000..e35bdba2
--- /dev/null
+++ b/7zip/Compress/LZMA/LZMALiteral.cpp
@@ -0,0 +1,69 @@
+// LZMALiteral.cpp
+
+#include "StdAfx.h"
+
+#include "LZMALiteral.h"
+
+namespace NCompress {
+namespace NLZMA {
+namespace NLiteral {
+
+void CEncoder2::Init()
+{
+ for (int i = 0; i < 3; i++)
+ for (int j = 1; j < (1 << 8); j++)
+ _encoders[i][j].Init();
+}
+
+void CEncoder2::Encode(NRangeCoder::CEncoder *rangeEncoder,
+ bool matchMode, BYTE matchByte, BYTE symbol)
+{
+ UINT32 context = 1;
+ bool same = true;
+ for (int i = 7; i >= 0; i--)
+ {
+ UINT32 bit = (symbol >> i) & 1;
+ UINT state;
+ if (matchMode && same)
+ {
+ UINT32 matchBit = (matchByte >> i) & 1;
+ state = 1 + matchBit;
+ same = (matchBit == bit);
+ }
+ else
+ state = 0;
+ _encoders[state][context].Encode(rangeEncoder, bit);
+ context = (context << 1) | bit;
+ }
+}
+
+UINT32 CEncoder2::GetPrice(bool matchMode, BYTE matchByte, BYTE symbol) const
+{
+ UINT32 price = 0;
+ UINT32 context = 1;
+ int i = 7;
+ if (matchMode)
+ {
+ for (; i >= 0; i--)
+ {
+ UINT32 matchBit = (matchByte >> i) & 1;
+ UINT32 bit = (symbol >> i) & 1;
+ price += _encoders[1 + matchBit][context].GetPrice(bit);
+ context = (context << 1) | bit;
+ if (matchBit != bit)
+ {
+ i--;
+ break;
+ }
+ }
+ }
+ for (; i >= 0; i--)
+ {
+ UINT32 bit = (symbol >> i) & 1;
+ price += _encoders[0][context].GetPrice(bit);
+ context = (context << 1) | bit;
+ }
+ return price;
+};
+
+}}}
diff --git a/7zip/Compress/LZMA/LZMALiteral.h b/7zip/Compress/LZMA/LZMALiteral.h
new file mode 100755
index 00000000..09cf0c36
--- /dev/null
+++ b/7zip/Compress/LZMA/LZMALiteral.h
@@ -0,0 +1,166 @@
+// LiteralCoder.h
+
+// #pragma once
+
+#ifndef __LITERALCODER_H
+#define __LITERALCODER_H
+
+#include "../RangeCoder/RangeCoderBit.h"
+#include "../RangeCoder/RangeCoderOpt.h"
+
+namespace NCompress {
+namespace NLZMA {
+namespace NLiteral {
+
+const int kNumMoveBits = 5;
+
+class CEncoder2
+{
+ NRangeCoder::CBitEncoder<kNumMoveBits> _encoders[3][1 << 8];
+public:
+ void Init();
+ void Encode(NRangeCoder::CEncoder *rangeEncoder, bool matchMode, BYTE matchByte, BYTE symbol);
+ UINT32 GetPrice(bool matchMode, BYTE matchByte, BYTE symbol) const;
+};
+
+class CDecoder2
+{
+ NRangeCoder::CBitDecoder<kNumMoveBits> _decoders[3][1 << 8];
+public:
+ void Init()
+ {
+ for (int i = 0; i < 3; i++)
+ for (int j = 1; j < (1 << 8); j++)
+ _decoders[i][j].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[0][symbol].Probability, symbol)
+ }
+ while (symbol < 0x100);
+ RC_FLUSH_VAR
+ return 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[1 + matchBit][symbol].Probability, symbol,
+ bit = 0, bit = 1)
+ if (matchBit != bit)
+ {
+ while (symbol < 0x100)
+ {
+ // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
+ RC_GETBIT(kNumMoveBits, _decoders[0][symbol].Probability, symbol)
+ }
+ break;
+ }
+ }
+ while (symbol < 0x100);
+ RC_FLUSH_VAR
+ return symbol;
+ }
+};
+
+/*
+const UINT32 kNumPrevByteBits = 1;
+const UINT32 kNumPrevByteStates = (1 << kNumPrevByteBits);
+
+inline UINT32 GetLiteralState(BYTE prevByte)
+ { return (prevByte >> (8 - kNumPrevByteBits)); }
+*/
+
+class CEncoder
+{
+ CEncoder2 *_coders;
+ UINT32 _numPrevBits;
+ UINT32 _numPosBits;
+ UINT32 _posMask;
+public:
+ CEncoder(): _coders(0) {}
+ ~CEncoder() { Free(); }
+ void Free()
+ {
+ delete []_coders;
+ _coders = 0;
+ }
+ void Create(UINT32 numPosBits, UINT32 numPrevBits)
+ {
+ Free();
+ _numPosBits = numPosBits;
+ _posMask = (1 << numPosBits) - 1;
+ _numPrevBits = numPrevBits;
+ UINT32 numStates = 1 << (_numPrevBits + _numPosBits);
+ _coders = new CEncoder2[numStates];
+ }
+ 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)); }
+ void Encode(NRangeCoder::CEncoder *rangeEncoder, UINT32 pos, BYTE prevByte,
+ bool matchMode, BYTE matchByte, BYTE symbol)
+ { _coders[GetState(pos, prevByte)].Encode(rangeEncoder, matchMode,
+ matchByte, symbol); }
+ UINT32 GetPrice(UINT32 pos, BYTE prevByte, bool matchMode, BYTE matchByte, BYTE symbol) const
+ { return _coders[GetState(pos, prevByte)].GetPrice(matchMode, matchByte, symbol); }
+};
+
+class CDecoder
+{
+ CDecoder2 *_coders;
+ UINT32 _numPrevBits;
+ UINT32 _numPosBits;
+ UINT32 _posMask;
+public:
+ CDecoder(): _coders(0) {}
+ ~CDecoder() { Free(); }
+ void Free()
+ {
+ delete []_coders;
+ _coders = 0;
+ }
+ void Create(UINT32 numPosBits, UINT32 numPrevBits)
+ {
+ Free();
+ _numPosBits = numPosBits;
+ _posMask = (1 << numPosBits) - 1;
+ _numPrevBits = numPrevBits;
+ UINT32 numStates = 1 << (_numPrevBits + _numPosBits);
+ _coders = new CDecoder2[numStates];
+ }
+ 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); }
+};
+
+}}}
+
+#endif
diff --git a/7zip/Compress/LZMA/StdAfx.cpp b/7zip/Compress/LZMA/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Compress/LZMA/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Compress/LZMA/StdAfx.h b/7zip/Compress/LZMA/StdAfx.h
new file mode 100755
index 00000000..a32fbed6
--- /dev/null
+++ b/7zip/Compress/LZMA/StdAfx.h
@@ -0,0 +1,8 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#endif
diff --git a/7zip/Compress/LZMA/resource.h b/7zip/Compress/LZMA/resource.h
new file mode 100755
index 00000000..612062a2
--- /dev/null
+++ b/7zip/Compress/LZMA/resource.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Compress/LZMA/resource.rc b/7zip/Compress/LZMA/resource.rc
new file mode 100755
index 00000000..e6e906e6
--- /dev/null
+++ b/7zip/Compress/LZMA/resource.rc
@@ -0,0 +1,121 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,12,0,0
+ PRODUCTVERSION 3,12,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "LZMA Codec\0"
+ VALUE "FileVersion", "3, 12, 0, 0\0"
+ VALUE "InternalName", "LZMA\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "LZMA.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 12, 0, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Compress/PPMD/DllExports.cpp b/7zip/Compress/PPMD/DllExports.cpp
new file mode 100755
index 00000000..3d7406aa
--- /dev/null
+++ b/7zip/Compress/PPMD/DllExports.cpp
@@ -0,0 +1,87 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#define INITGUID
+
+#include "Common/ComTry.h"
+
+#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*/)
+{
+ 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/7zip/Compress/PPMD/PPMD.def b/7zip/Compress/PPMD/PPMD.def
new file mode 100755
index 00000000..bec83a03
--- /dev/null
+++ b/7zip/Compress/PPMD/PPMD.def
@@ -0,0 +1,9 @@
+; PPMD.def
+
+LIBRARY PPMD.dll
+
+EXPORTS
+ CreateObject PRIVATE
+ GetNumberOfMethods PRIVATE
+ GetMethodProperty PRIVATE
+
diff --git a/7zip/Compress/PPMD/PPMD.dsp b/7zip/Compress/PPMD/PPMD.dsp
new file mode 100755
index 00000000..78e8bb13
--- /dev/null
+++ b/7zip/Compress/PPMD/PPMD.dsp
@@ -0,0 +1,205 @@
+# 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=.\DllExports.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\PPMD.def
+# 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
+# End Group
+# Begin Group "RangeCoder"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoder.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# End Target
+# End Project
diff --git a/7zip/Compress/PPMD/PPMD.dsw b/7zip/Compress/PPMD/PPMD.dsw
new file mode 100755
index 00000000..8032f3db
--- /dev/null
+++ b/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/7zip/Compress/PPMD/PPMDContext.h b/7zip/Compress/PPMD/PPMDContext.h
new file mode 100755
index 00000000..6a2b7025
--- /dev/null
+++ b/7zip/Compress/PPMD/PPMDContext.h
@@ -0,0 +1,447 @@
+// Compress/PPM/PPMD/Context.h
+// This code is based on Dmitry Shkarin's PPMdH code
+
+#pragma once
+
+#ifndef __COMPRESS_PPM_PPMD_CONTEXT_H
+#define __COMPRESS_PPM_PPMD_CONTEXT_H
+
+#include "Common/Types.h"
+
+#include "PPMDSubAlloc.h"
+#include "../RangeCoder/RangeCoder.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;
+
+#pragma pack(1)
+struct SEE2_CONTEXT
+{ // SEE-contexts for PPM-contexts with masked symbols
+ WORD Summ;
+ BYTE Shift, Count;
+ void init(int InitVal) { Summ=InitVal << (Shift=PERIOD_BITS-4); Count=4; }
+ UINT getMean()
+ {
+ UINT RetVal=(Summ >> Shift);
+ Summ -= RetVal;
+ return RetVal+(RetVal == 0);
+ }
+ void update()
+ {
+ if (Shift < PERIOD_BITS && --Count == 0)
+ {
+ Summ += Summ;
+ Count = 3 << Shift++;
+ }
+ }
+};
+
+struct PPM_CONTEXT
+{
+ WORD NumStats,SummFreq; // sizeof(WORD) > sizeof(BYTE)
+ struct STATE { BYTE Symbol, Freq; PPM_CONTEXT* Successor; } _PACK_ATTR * Stats;
+ PPM_CONTEXT* Suffix;
+
+ PPM_CONTEXT* createChild(CSubAllocator &aSubAllocator, STATE* pStats, STATE& FirstState)
+ {
+ PPM_CONTEXT* pc = (PPM_CONTEXT*) aSubAllocator.AllocContext();
+ if ( pc )
+ {
+ pc->NumStats = 1;
+ pc->oneState() = FirstState;
+ pc->Suffix = this;
+ pStats->Successor = pc;
+ }
+ return pc;
+ }
+
+ STATE& oneState() const { return (STATE&) SummFreq; }
+};
+#pragma pack()
+
+/////////////////////////////////
+
+const WORD InitBinEsc[] =
+ {0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051};
+
+struct CInfo
+{
+ CSubAllocator SubAllocator;
+ SEE2_CONTEXT _PACK_ATTR SEE2Cont[25][16], DummySEE2Cont;
+ PPM_CONTEXT _PACK_ATTR * 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;
+ WORD BinSumm[128][64]; // binary SEE-contexts
+
+ WORD &GetBinSumm(const PPM_CONTEXT::STATE &rs, int aNumStates)
+ {
+ HiBitsFlag = HB2Flag[FoundState->Symbol];
+ return BinSumm[rs.Freq - 1][
+ PrevSuccess + NS2BSIndx[aNumStates - 1] +
+ HiBitsFlag + 2 * HB2Flag[rs.Symbol] +
+ ((RunLength >> 26) & 0x20)];
+ }
+
+ 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 = NULL;
+ OrderFall = MaxOrder;
+ MinContext->SummFreq = (MinContext->NumStats = 256) + 1;
+ FoundState = MinContext->Stats = (PPM_CONTEXT::STATE*) SubAllocator.AllocUnits(256 / 2);
+ for (RunLength = InitRL, PrevSuccess = i = 0; i < 256; i++)
+ {
+ MinContext->Stats[i].Symbol = i;
+ MinContext->Stats[i].Freq = 1;
+ MinContext->Stats[i].Successor = NULL;
+ }
+ for (i = 0; i < 128; i++)
+ for (k = 0; k < 8; k++)
+ for ( m=0; m < 64; m += 8)
+ BinSumm[i][k + m] = BIN_SCALE - InitBinEsc[k] / (i + 2);
+ for (i = 0; i < 25; i++)
+ for (k = 0; k < 16; k++)
+ SEE2Cont[i][k].init(5*i+10);
+ }
+
+ void _FASTCALL 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 != NULL)
+ {
+ MinContext = MinContext->Suffix;
+ OrderFall--;
+ }
+ FoundState = 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] = i;
+ for (m = i, k = Step = 1; i < 256; i++)
+ {
+ NS2Indx[i] =m;
+ if ( !--k )
+ {
+ k = ++Step;
+ m++;
+ }
+ }
+ memset(HB2Flag, 0, 0x40);
+ memset(HB2Flag + 0x40, 0x08, 0x100 - 0x40);
+ DummySEE2Cont.Shift = PERIOD_BITS;
+ }
+ }
+
+ 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, * UpBranch = FoundState->Successor;
+ PPM_CONTEXT::STATE * p, * ps[MAX_O], ** pps = ps;
+ if ( !Skip )
+ {
+ *pps++ = FoundState;
+ if ( !pc->Suffix )
+ goto NO_LOOP;
+ }
+ if ( p1 )
+ {
+ p = p1;
+ pc = pc->Suffix;
+ goto LOOP_ENTRY;
+ }
+ do
+ {
+ pc = pc->Suffix;
+ if (pc->NumStats != 1)
+ {
+ if ((p = pc->Stats)->Symbol != FoundState->Symbol)
+ do { p++; } while (p->Symbol != FoundState->Symbol);
+ }
+ else
+ p = &(pc->oneState());
+LOOP_ENTRY:
+ if (p->Successor != UpBranch)
+ {
+ pc = p->Successor;
+ break;
+ }
+ *pps++ = p;
+ }
+ while ( pc->Suffix );
+NO_LOOP:
+ if (pps == ps)
+ return pc;
+ UpState.Symbol = *(BYTE*) UpBranch;
+ UpState.Successor = (PPM_CONTEXT*) (((BYTE*) UpBranch)+1);
+ if (pc->NumStats != 1)
+ {
+ if ((p = pc->Stats)->Symbol != UpState.Symbol)
+ do { p++; } while (p->Symbol != UpState.Symbol);
+ UINT cf = p->Freq-1;
+ UINT s0 = pc->SummFreq - pc->NumStats - cf;
+ UpState.Freq = 1 + ((2 * cf <= s0) ? (5 * cf > s0) :
+ ((2 * cf + 3 * s0 - 1) / (2 * s0)));
+ }
+ else
+ UpState.Freq = pc->oneState().Freq;
+ do
+ {
+ pc = pc->createChild(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;
+ UINT ns1, ns, cf, sf, s0;
+ if (fs.Freq < MAX_FREQ/4 && (pc=MinContext->Suffix) != NULL)
+ {
+ if (pc->NumStats != 1)
+ {
+ if ((p = 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 += (p->Freq < 32);
+ }
+ }
+ if ( !OrderFall )
+ {
+ MinContext = MaxContext = FoundState->Successor = CreateSuccessors(TRUE, p);
+ if ( !MinContext )
+ goto RESTART_MODEL;
+ return;
+ }
+ *SubAllocator.pText++ = fs.Symbol;
+ Successor = (PPM_CONTEXT*) SubAllocator.pText;
+ if (SubAllocator.pText >= SubAllocator.UnitsStart)
+ goto RESTART_MODEL;
+ if ( fs.Successor )
+ {
+ if ((BYTE*) fs.Successor <= SubAllocator.pText &&
+ (fs.Successor=CreateSuccessors(FALSE,p)) == NULL)
+ goto RESTART_MODEL;
+ if ( !--OrderFall )
+ {
+ Successor = fs.Successor;
+ SubAllocator.pText -= (MaxContext != MinContext);
+ }
+ }
+ else
+ {
+ FoundState->Successor = Successor;
+ fs.Successor = MinContext;
+ }
+ s0 = MinContext->SummFreq - (ns = MinContext->NumStats) - (fs.Freq - 1);
+ for (pc = MaxContext; pc != MinContext; pc = pc->Suffix)
+ {
+ if ((ns1 = pc->NumStats) != 1)
+ {
+ if ((ns1 & 1) == 0)
+ {
+ pc->Stats = (PPM_CONTEXT::STATE*) SubAllocator.ExpandUnits(pc->Stats, ns1 >> 1);
+ if ( !pc->Stats )
+ goto RESTART_MODEL;
+ }
+ 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 = p;
+ if (p->Freq < MAX_FREQ / 4 - 1)
+ p->Freq += p->Freq;
+ else
+ p->Freq = MAX_FREQ - 4;
+ pc->SummFreq = 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 += cf;
+ }
+ p = pc->Stats + ns1;
+ p->Successor = Successor;
+ p->Symbol = fs.Symbol;
+ p->Freq = cf;
+ pc->NumStats = ++ns1;
+ }
+ MaxContext = MinContext = fs.Successor;
+ return;
+RESTART_MODEL:
+ RestartModelRare();
+ EscCount = 0;
+ 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 &aScale)
+ {
+ SEE2_CONTEXT* psee2c;
+ if (MinContext->NumStats != 256)
+ {
+ psee2c = SEE2Cont[NS2Indx[Diff-1]] + (Diff < MinContext->Suffix->NumStats - MinContext->NumStats)+
+ 2 * (MinContext->SummFreq < 11 * MinContext->NumStats) + 4 * (NumMasked > Diff) + HiBitsFlag;
+ aScale = psee2c->getMean();
+ }
+ else
+ {
+ psee2c = &DummySEE2Cont;
+ aScale = 1;
+ }
+ return psee2c;
+ }
+
+
+
+ void rescale()
+ {
+ int OldNS = MinContext->NumStats, i = MinContext->NumStats - 1, Adder, EscFreq;
+ PPM_CONTEXT::STATE* p1, * p;
+ for (p = FoundState; p != MinContext->Stats; p--)
+ _PPMD_SWAP(p[0], p[-1]);
+ MinContext->Stats->Freq += 4;
+ MinContext->SummFreq += 4;
+ EscFreq = MinContext->SummFreq - p->Freq;
+ Adder = (OrderFall != 0);
+ MinContext->SummFreq = (p->Freq = (p->Freq + Adder) >> 1);
+ do
+ {
+ EscFreq -= (++p)->Freq;
+ MinContext->SummFreq += (p->Freq = (p->Freq + Adder) >> 1);
+ if (p[0].Freq > p[-1].Freq)
+ {
+ PPM_CONTEXT::STATE tmp = *(p1 = p);
+ do { p1[0] = p1[-1]; } while (--p1 != MinContext->Stats && tmp.Freq > p1[-1].Freq);
+ *p1 = tmp;
+ }
+ }
+ while ( --i );
+ if (p->Freq == 0)
+ {
+ do { i++; } while ((--p)->Freq == 0);
+ EscFreq += i;
+ if ((MinContext->NumStats -= i) == 1)
+ {
+ PPM_CONTEXT::STATE tmp = *MinContext->Stats;
+ do { tmp.Freq -= (tmp.Freq >> 1); EscFreq >>= 1; } while (EscFreq > 1);
+ SubAllocator.FreeUnits(MinContext->Stats, (OldNS+1) >> 1);
+ *(FoundState = &MinContext->oneState()) = tmp; return;
+ }
+ }
+ MinContext->SummFreq += (EscFreq -= (EscFreq >> 1));
+ int n0 = (OldNS+1) >> 1, n1 = (MinContext->NumStats + 1) >> 1;
+ if (n0 != n1)
+ MinContext->Stats =
+ (PPM_CONTEXT::STATE*) SubAllocator.ShrinkUnits(MinContext->Stats, n0, n1);
+ FoundState = MinContext->Stats;
+ }
+
+ void NextContext()
+ {
+ if (!OrderFall && (BYTE*) FoundState->Successor > SubAllocator.pText)
+ MinContext = MaxContext = FoundState->Successor;
+ 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/7zip/Compress/PPMD/PPMDDecode.h b/7zip/Compress/PPMD/PPMDDecode.h
new file mode 100755
index 00000000..04888825
--- /dev/null
+++ b/7zip/Compress/PPMD/PPMDDecode.h
@@ -0,0 +1,139 @@
+// Decode.h
+// This code is based on Dmitry Shkarin's PPMdH code
+
+#pragma once
+
+#ifndef __COMPRESS_PPM_PPMD_DECODE_H
+#define __COMPRESS_PPM_PPMD_DECODE_H
+
+#include "PPMDContext.h"
+
+namespace NCompress {
+namespace NPPMD {
+
+struct CDecodeInfo: public CInfo
+{
+ void DecodeBinSymbol(NRangeCoder::CDecoder *rangeDecoder)
+ {
+ PPM_CONTEXT::STATE& rs = MinContext->oneState();
+ WORD& bs = GetBinSumm(rs, MinContext->Suffix->NumStats);
+ if (rangeDecoder->DecodeBit(bs, TOT_BITS) == 0)
+ {
+ FoundState = &rs;
+ rs.Freq += (rs.Freq < 128);
+ bs += UINT16(INTERVAL-GET_MEAN(bs,PERIOD_BITS,2));
+ PrevSuccess = 1;
+ RunLength++;
+ }
+ else
+ {
+ bs -= UINT16(GET_MEAN(bs,PERIOD_BITS,2));
+ InitEsc = ExpEscape[bs >> 10];
+ NumMasked = 1;
+ CharMask[rs.Symbol] = EscCount;
+ PrevSuccess = 0;
+ FoundState = NULL;
+ }
+ }
+
+ void DecodeSymbol1(NRangeCoder::CDecoder *rangeDecoder)
+ {
+ PPM_CONTEXT::STATE* p = MinContext->Stats;
+ int i, count, hiCnt;
+ if ((count = rangeDecoder->GetThreshold(MinContext->SummFreq)) < (hiCnt = p->Freq))
+ {
+ PrevSuccess = (2 * hiCnt > MinContext->SummFreq);
+ RunLength += PrevSuccess;
+ rangeDecoder->Decode(0, MinContext->Stats->Freq, MinContext->SummFreq);
+ (FoundState = p)->Freq=(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(NRangeCoder::CDecoder *rangeDecoder)
+ {
+ int count, hiCnt, i = MinContext->NumStats - NumMasked;
+ UINT32 freqSum;
+ SEE2_CONTEXT* psee2c = makeEscFreq2(i, freqSum);
+ PPM_CONTEXT::STATE* ps[256], ** pps = ps, * p = MinContext->Stats-1;
+ 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 += freqSum;
+ NumMasked = MinContext->NumStats;
+ }
+ }
+
+ int DecodeSymbol(NRangeCoder::CDecoder *rangeDecoder)
+ {
+ if (MinContext->NumStats != 1)
+ DecodeSymbol1(rangeDecoder);
+ else
+ DecodeBinSymbol(rangeDecoder);
+ while ( !FoundState )
+ {
+ do
+ {
+ OrderFall++;
+ MinContext = MinContext->Suffix;
+ if ( !MinContext )
+ return -1;
+ }
+ while (MinContext->NumStats == NumMasked);
+ DecodeSymbol2(rangeDecoder);
+ }
+ BYTE symbol = FoundState->Symbol;
+ NextContext();
+ return symbol;
+ }
+};
+
+}}
+
+#endif
diff --git a/7zip/Compress/PPMD/PPMDDecoder.cpp b/7zip/Compress/PPMD/PPMDDecoder.cpp
new file mode 100755
index 00000000..aa2a98af
--- /dev/null
+++ b/7zip/Compress/PPMD/PPMDDecoder.cpp
@@ -0,0 +1,109 @@
+// PPMDDecoder.cpp
+
+#include "StdAfx.h"
+
+#include "Common/Defs.h"
+#include "Windows/Defs.h"
+
+#include "PPMDDecoder.h"
+
+namespace NCompress {
+namespace NPPMD {
+
+STDMETHODIMP CDecoder::SetDecoderProperties(ISequentialInStream *inStream)
+{
+ UINT32 processedSize;
+ RINOK(inStream->Read(&_order,
+ sizeof(_order), &processedSize));
+ if (processedSize != sizeof(_order))
+ return E_FAIL;
+ RINOK(inStream->Read(&_usedMemorySize,
+ sizeof(_usedMemorySize), &processedSize));
+ if (processedSize != sizeof(_usedMemorySize))
+ return E_FAIL;
+ return S_OK;
+}
+
+class CDecoderFlusher
+{
+ CDecoder *_coder;
+public:
+ CDecoderFlusher(CDecoder *coder): _coder(coder) {}
+ ~CDecoderFlusher()
+ {
+ _coder->Flush();
+ // _coder->ReleaseStreams();
+ }
+};
+
+UINT32 GetMatchLen(const BYTE *pointer1, const BYTE *pointer2,
+ UINT32 limit)
+{
+ UINT32 i;
+ for(i = 0; i < limit && *pointer1 == *pointer2;
+ pointer1++, pointer2++, i++);
+ return i;
+}
+
+STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ _rangeDecoder.Init(inStream);
+ _outStream.Init(outStream);
+
+ CDecoderFlusher flusher(this);
+
+ /*
+ if (outSize == NULL)
+ return E_INVALIDARG;
+ */
+
+ UINT64 progressPosValuePrev = 0, pos = 0;
+
+ try
+ {
+ if (!_info.SubAllocator.StartSubAllocator(_usedMemorySize))
+ return E_OUTOFMEMORY;
+ }
+ catch(...)
+ {
+ return E_OUTOFMEMORY;
+ }
+
+ // _info.Init();
+ // _info.MaxOrder = _order;
+ _info.MaxOrder = 0;
+ _info.StartModelRare(_order);
+
+ UINT64 size = (outSize == NULL) ? (UINT64)(INT64)(-1) : *outSize;
+
+ while(pos < size)
+ {
+ pos++;
+ int symbol = _info.DecodeSymbol(&_rangeDecoder);
+ if (symbol < 0)
+ return S_OK;
+ _outStream.WriteByte(symbol);
+ if (pos - progressPosValuePrev >= (1 << 18) && progress != NULL)
+ {
+ UINT64 inSize = _rangeDecoder.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&inSize, &pos));
+ progressPosValuePrev = pos;
+ }
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
+ catch(const COutBufferException &e) { return e.ErrorCode; }
+ catch(const CInBufferException &e) { return e.ErrorCode; }
+ catch(...) { return E_FAIL; }
+}
+
+
+}}
diff --git a/7zip/Compress/PPMD/PPMDDecoder.h b/7zip/Compress/PPMD/PPMDDecoder.h
new file mode 100755
index 00000000..83a0c5e0
--- /dev/null
+++ b/7zip/Compress/PPMD/PPMDDecoder.h
@@ -0,0 +1,67 @@
+// Compress/PPM/PPMDDecoder.h
+
+#pragma once
+
+#ifndef __COMPRESS_PPM_PPMD_DECODER_H
+#define __COMPRESS_PPM_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 ICompressSetDecoderProperties,
+ public CMyUnknownImp
+{
+ NRangeCoder::CDecoder _rangeDecoder;
+
+ COutBuffer _outStream;
+
+ CDecodeInfo _info;
+
+ BYTE _order;
+ UINT32 _usedMemorySize;
+
+public:
+
+ MY_UNKNOWN_IMP1(ICompressSetDecoderProperties)
+
+ /*
+ void ReleaseStreams()
+ {
+ _rangeDecoder.ReleaseStream();
+ _outStream.ReleaseStream();
+ }
+ */
+
+ // STDMETHOD(Code)(UINT32 aNumBytes, UINT32 &aProcessedBytes);
+ 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);
+
+
+ // ICompressSetDecoderProperties
+ STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream);
+
+};
+
+}}
+
+#endif
diff --git a/7zip/Compress/PPMD/PPMDEncode.h b/7zip/Compress/PPMD/PPMDEncode.h
new file mode 100755
index 00000000..f86fc4af
--- /dev/null
+++ b/7zip/Compress/PPMD/PPMDEncode.h
@@ -0,0 +1,144 @@
+// PPMDEncode.h
+// This code is based on Dmitry Shkarin's PPMdH code
+
+#pragma once
+
+#ifndef __COMPRESS_PPM_PPMD_ENCODE_H
+#define __COMPRESS_PPM_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();
+ WORD &bs = GetBinSumm(rs, MinContext->Suffix->NumStats);
+ if (rs.Symbol == symbol)
+ {
+ FoundState = &rs;
+ rs.Freq += (rs.Freq < 128);
+ rangeEncoder->EncodeBit(bs, TOT_BITS, 0);
+ bs += UINT16(INTERVAL-GET_MEAN(bs,PERIOD_BITS, 2));
+ PrevSuccess = 1;
+ RunLength++;
+ }
+ else
+ {
+ rangeEncoder->EncodeBit(bs, TOT_BITS, 1);
+ bs -= UINT16(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 = MinContext->Stats;
+ if (p->Symbol == symbol)
+ {
+ PrevSuccess = (2 * (p->Freq) > MinContext->SummFreq);
+ RunLength += PrevSuccess;
+ rangeEncoder->Encode(0, MinContext->Stats->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 = 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 += 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 = MinContext->Suffix;
+ if ( !MinContext )
+ return; // S_OK;
+ }
+ while (MinContext->NumStats == NumMasked);
+ EncodeSymbol2(c, rangeEncoder);
+ }
+ NextContext();
+ }
+
+};
+}}
+
+#endif
diff --git a/7zip/Compress/PPMD/PPMDEncoder.cpp b/7zip/Compress/PPMD/PPMDEncoder.cpp
new file mode 100755
index 00000000..0675cdb1
--- /dev/null
+++ b/7zip/Compress/PPMD/PPMDEncoder.cpp
@@ -0,0 +1,182 @@
+// Compress/Associative/Encoder.h
+
+#include "StdAfx.h"
+
+#include "Windows/Defs.h"
+
+// #include <fstream.h>
+// #include <iomanip.h>
+
+#include "Common/Defs.h"
+
+#include "PPMDEncoder.h"
+
+namespace NCompress {
+namespace NPPMD {
+
+/*
+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;
+
+
+/*
+// ISetRangeEncoder
+STDMETHODIMP CEncoder::SetRangeEncoder(CRangeEncoder *aRangeEncoder)
+{
+ _rangeEncoder = aRangeEncoder;
+ RINOK(_rangeEncoder.QueryInterface(&m_InitOutCoder));
+
+ return S_OK;
+}
+*/
+
+STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
+ const PROPVARIANT *properties, UINT32 numProperties)
+{
+ for (UINT32 i = 0; i < numProperties; i++)
+ {
+ const PROPVARIANT &aProperty = properties[i];
+ switch(propIDs[i])
+ {
+ case NCoderPropID::kUsedMemorySize:
+ if (aProperty.vt != VT_UI4)
+ return E_INVALIDARG;
+ if (aProperty.ulVal < kMinMemSize)
+ return E_INVALIDARG;
+ _usedMemorySize = aProperty.ulVal;
+ break;
+ case NCoderPropID::kOrder:
+ if (aProperty.vt != VT_UI4)
+ return E_INVALIDARG;
+ if (aProperty.ulVal < kMinOrder || aProperty.ulVal > kMaxOrderCompress)
+ return E_INVALIDARG;
+ _order = BYTE(aProperty.ulVal);
+ break;
+ default:
+ return E_INVALIDARG;
+ }
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{
+ RINOK(outStream->Write(&_order, sizeof(_order), NULL));
+ return outStream->Write(&_usedMemorySize, sizeof(_usedMemorySize), NULL);
+}
+
+const UINT32 kUsedMemorySizeDefault = (1 << 24);
+const int kOrderDefault = 6;
+
+CEncoder::CEncoder():
+ _usedMemorySize(kUsedMemorySizeDefault),
+ _order(kOrderDefault)
+{
+ // SubAllocator.StartSubAllocator(kSubAllocator);
+}
+
+
+HRESULT CEncoder::Flush()
+{
+ _rangeEncoder.FlushData();
+ return _rangeEncoder.FlushStream();
+}
+
+class CEncoderFlusher
+{
+ CEncoder *_encoder;
+public:
+ CEncoderFlusher(CEncoder *encoder): _encoder(encoder) {}
+ ~CEncoderFlusher()
+ {
+ _encoder->Flush();
+ // _encoder->ReleaseStreams();
+ }
+};
+
+
+
+HRESULT CEncoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ _inStream.Init(inStream);
+ _rangeEncoder.Init(outStream);
+
+ CEncoderFlusher aFlusher(this);
+
+ UINT64 pos = 0;
+ UINT64 prevProgressPos = 0;
+
+ try
+ {
+ if ( !_info.SubAllocator.StartSubAllocator(_usedMemorySize) )
+ return E_OUTOFMEMORY;
+ }
+ catch(...)
+ {
+ return E_OUTOFMEMORY;
+ }
+
+
+ _info.MaxOrder = 0;
+ _info.StartModelRare(_order);
+
+
+ while (true)
+ {
+ 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);
+ pos++;
+ if (pos - prevProgressPos >= (1 << 18) && progress != NULL)
+ {
+ UINT64 outSize = _rangeEncoder.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&pos, &outSize));
+ prevProgressPos = pos;
+ }
+ }
+}
+
+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/7zip/Compress/PPMD/PPMDEncoder.h b/7zip/Compress/PPMD/PPMDEncoder.h
new file mode 100755
index 00000000..434a727c
--- /dev/null
+++ b/7zip/Compress/PPMD/PPMDEncoder.h
@@ -0,0 +1,68 @@
+// Compress/PPMD/Encoder.h
+
+#pragma once
+
+#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;
+
+public:
+
+ MY_UNKNOWN_IMP2(
+ ICompressSetCoderProperties,
+ ICompressWriteCoderProperties)
+
+ // ICoder interface
+ HRESULT Flush();
+ /*
+ void ReleaseStreams()
+ {
+ _inStream.ReleaseStream();
+ _rangeEncoder.ReleaseStream();
+ }
+ */
+
+ 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);
+
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+
+ CEncoder();
+
+};
+
+}}
+
+#endif
diff --git a/7zip/Compress/PPMD/PPMDSubAlloc.h b/7zip/Compress/PPMD/PPMDSubAlloc.h
new file mode 100755
index 00000000..b2733e26
--- /dev/null
+++ b/7zip/Compress/PPMD/PPMDSubAlloc.h
@@ -0,0 +1,205 @@
+// SubAlloc.h
+// This code is based on Dmitry Shkarin's PPMdH code
+
+#pragma once
+
+#ifndef __SubAlloc_H
+#define __SubAlloc_H
+
+#include "PPMdType.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;
+
+#pragma pack(1)
+struct MEM_BLK {
+ WORD Stamp, NU;
+ MEM_BLK* next, * prev;
+ void insertAt(MEM_BLK* p) {
+ next=(prev=p)->next; p->next=next->prev=this;
+ }
+ void remove() { prev->next=next; next->prev=prev; }
+} _PACK_ATTR;
+#pragma pack()
+
+
+class CSubAllocator
+{
+ DWORD SubAllocatorSize;
+ BYTE Indx2Units[N_INDEXES], Units2Indx[128], GlueCount;
+ struct NODE { NODE* next; } FreeList[N_INDEXES];
+public:
+ BYTE* HeapStart, * pText, * UnitsStart, * LoUnit, * HiUnit;
+ CSubAllocator():
+ SubAllocatorSize(0),
+ GlueCount(0),
+ pText(0),
+ UnitsStart(0),
+ LoUnit(0),
+ HiUnit(0)
+ {
+ memset(Indx2Units, 0, sizeof(Indx2Units));
+ memset(FreeList, 0, sizeof(FreeList));
+ }
+ ~CSubAllocator()
+ {
+ StopSubAllocator();
+ };
+
+
+inline void InsertNode(void* p,int indx) {
+ ((NODE*) p)->next=FreeList[indx].next; FreeList[indx].next=(NODE*) p;
+}
+inline void* RemoveNode(int indx) {
+ NODE* RetVal=FreeList[indx].next; FreeList[indx].next=RetVal->next;
+ return RetVal;
+}
+inline UINT U2B(int NU) { return 8*NU+4*NU; }
+inline 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]);
+}
+
+DWORD _STDCALL GetUsedMemory()
+{
+ DWORD i, k, RetVal=SubAllocatorSize-(HiUnit-LoUnit)-(UnitsStart-pText);
+ for (k=i=0;i < N_INDEXES;i++, k=0) {
+ for (NODE* pn=FreeList+i;(pn=pn->next) != NULL;k++)
+ ;
+ RetVal -= UNIT_SIZE*Indx2Units[i]*k;
+ }
+ return (RetVal >> 2);
+}
+
+ void _STDCALL StopSubAllocator()
+ {
+ if ( SubAllocatorSize )
+ {
+ #ifdef WIN32
+ VirtualFree(HeapStart, 0, MEM_RELEASE);
+ #else
+ delete[] HeapStart;
+ #endif
+ SubAllocatorSize = 0;
+ HeapStart = 0;
+ }
+ }
+
+ bool _STDCALL StartSubAllocator(UINT32 aSize)
+ {
+ if (SubAllocatorSize == aSize)
+ return true;
+ StopSubAllocator();
+ #ifdef WIN32
+ if ((HeapStart = (BYTE *)::VirtualAlloc(0, aSize, MEM_COMMIT, PAGE_READWRITE)) == 0)
+ return false;
+ #else
+ if ((HeapStart = new BYTE[aSize]) == NULL)
+ return false;
+ #endif
+ SubAllocatorSize = aSize;
+ return true;
+ }
+
+inline 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]=k;
+ for (k++;i < N1+N2 ;i++,k += 2) Indx2Units[i]=k;
+ for (k++;i < N1+N2+N3 ;i++,k += 3) Indx2Units[i]=k;
+ for (k++;i < N1+N2+N3+N4;i++,k += 4) Indx2Units[i]=k;
+ for (GlueCount=k=i=0;k < 128;k++) {
+ i += (Indx2Units[i] < k+1); Units2Indx[k]=i;
+ }
+}
+inline void GlueFreeBlocks()
+{
+ MEM_BLK s0, * p, * p1;
+ int i, k, sz;
+ if (LoUnit != HiUnit) *LoUnit=0;
+ for (i=0, s0.next=s0.prev=&s0;i < N_INDEXES;i++)
+ while ( FreeList[i].next ) {
+ p=(MEM_BLK*) RemoveNode(i); p->insertAt(&s0);
+ p->Stamp=0xFFFF; p->NU=Indx2Units[i];
+ }
+ for (p=s0.next;p != &s0;p=p->next)
+ while ((p1=p+p->NU)->Stamp == 0xFFFF && int(p->NU)+p1->NU < 0x10000) {
+ p1->remove(); p->NU += p1->NU;
+ }
+ while ((p=s0.next) != &s0) {
+ for (p->remove(), sz=p->NU;sz > 128;sz -= 128, p += 128)
+ InsertNode(p,N_INDEXES-1);
+ if (Indx2Units[i=Units2Indx[sz-1]] != sz) {
+ k=sz-Indx2Units[--i]; InsertNode(p+(sz-k),k-1);
+ }
+ InsertNode(p,i);
+ }
+}
+void* AllocUnitsRare(int indx)
+{
+ if ( !GlueCount ) {
+ GlueCount = 255; GlueFreeBlocks();
+ if ( FreeList[indx].next ) return RemoveNode(indx);
+ }
+ int i=indx;
+ do {
+ if (++i == N_INDEXES) {
+ GlueCount--; i=U2B(Indx2Units[indx]);
+ return (UnitsStart-pText > i)?(UnitsStart -= i):(NULL);
+ }
+ } while ( !FreeList[i].next );
+ void* RetVal=RemoveNode(i); SplitBlock(RetVal,i,indx);
+ return RetVal;
+}
+inline void* AllocUnits(int NU)
+{
+ int indx=Units2Indx[NU-1];
+ if ( FreeList[indx].next ) return RemoveNode(indx);
+ void* RetVal=LoUnit; LoUnit += U2B(Indx2Units[indx]);
+ if (LoUnit <= HiUnit) return RetVal;
+ LoUnit -= U2B(Indx2Units[indx]); return AllocUnitsRare(indx);
+}
+inline void* AllocContext()
+{
+ if (HiUnit != LoUnit) return (HiUnit -= UNIT_SIZE);
+ if ( FreeList->next ) return RemoveNode(0);
+ return AllocUnitsRare(0);
+}
+inline 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;
+}
+inline 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].next ) {
+ void* ptr=RemoveNode(i1); memcpy(ptr,OldPtr,U2B(NewNU));
+ InsertNode(OldPtr,i0); return ptr;
+ } else {
+ SplitBlock(OldPtr,i0,i1); return OldPtr;
+ }
+}
+inline void FreeUnits(void* ptr,int OldNU)
+{
+ InsertNode(ptr,Units2Indx[OldNU-1]);
+}
+};
+
+#endif
diff --git a/7zip/Compress/PPMD/PPMDType.h b/7zip/Compress/PPMD/PPMDType.h
new file mode 100755
index 00000000..563d6d04
--- /dev/null
+++ b/7zip/Compress/PPMD/PPMDType.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+ * 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 *
+ ****************************************************************************/
+#if !defined(_PPMDTYPE_H_)
+#define _PPMDTYPE_H_
+
+#include <stdio.h>
+
+const UINT32 kMinMemSize = (1 << 11);
+const UINT32 kMinOrder = 2;
+const int kMaxOrderCompress = 32;
+const int MAX_O=255; /* maximum allowed model order */
+
+#define _WIN32_ENVIRONMENT_
+//#define _DOS32_ENVIRONMENT_
+//#define _POSIX_ENVIRONMENT_
+//#define _UNKNOWN_ENVIRONMENT_
+#if defined(_WIN32_ENVIRONMENT_)+defined(_DOS32_ENVIRONMENT_)+defined(_POSIX_ENVIRONMENT_)+defined(_UNKNOWN_ENVIRONMENT_) != 1
+#error Only one environment must be defined
+#endif /* defined(_WIN32_ENVIRONMENT_)+defined(_DOS32_ENVIRONMENT_)+defined(_POSIX_ENVIRONMENT_)+defined(_UNKNOWN_ENVIRONMENT_) != 1 */
+
+#if defined(_WIN32_ENVIRONMENT_)
+#include <wtypes.h>
+#else /* _DOS32_ENVIRONMENT_ || _POSIX_ENVIRONMENT_ || _UNKNOWN_ENVIRONMENT_ */
+typedef int BOOL;
+#define FALSE 0
+#define TRUE 1
+typedef unsigned char BYTE;
+typedef unsigned short WORD;
+typedef unsigned long DWORD;
+typedef unsigned int UINT;
+#endif /* defined(_WIN32_ENVIRONMENT_) */
+
+#if !defined(_UNKNOWN_ENVIRONMENT_) && !defined(__GNUC__)
+#define _FASTCALL __fastcall
+#define _STDCALL __stdcall
+#else
+#define _FASTCALL
+#define _STDCALL
+#endif /* !defined(_UNKNOWN_ENVIRONMENT_) && !defined(__GNUC__) */
+
+#if defined(__GNUC__)
+#define _PACK_ATTR __attribute__ ((packed))
+#else
+#define _PACK_ATTR
+#endif /* defined(__GNUC__) */
+
+// PPMd module works with file streams via ...GETC/...PUTC macros only
+typedef FILE _PPMD_FILE;
+#define _PPMD_E_GETC(fp) getc(fp)
+#define _PPMD_E_PUTC(c,fp) putc((c),fp)
+#define _PPMD_D_GETC(fp) getc(fp)
+#define _PPMD_D_PUTC(c,fp) putc((c),fp)
+
+template <class T>
+inline void _PPMD_SWAP(T& t1,T& t2) { T tmp=t1; t1=t2; t2=tmp; }
+
+#endif /* !defined(_PPMDTYPE_H_) */
diff --git a/7zip/Compress/PPMD/StdAfx.cpp b/7zip/Compress/PPMD/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Compress/PPMD/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Compress/PPMD/StdAfx.h b/7zip/Compress/PPMD/StdAfx.h
new file mode 100755
index 00000000..99ff6f25
--- /dev/null
+++ b/7zip/Compress/PPMD/StdAfx.h
@@ -0,0 +1,8 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#endif
diff --git a/7zip/Compress/PPMD/resource.h b/7zip/Compress/PPMD/resource.h
new file mode 100755
index 00000000..612062a2
--- /dev/null
+++ b/7zip/Compress/PPMD/resource.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Compress/PPMD/resource.rc b/7zip/Compress/PPMD/resource.rc
new file mode 100755
index 00000000..ca4ce99c
--- /dev/null
+++ b/7zip/Compress/PPMD/resource.rc
@@ -0,0 +1,121 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,9,2,0
+ PRODUCTVERSION 3,9,2,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "PPMd Coder\0"
+ VALUE "FileVersion", "3, 9, 2, 0\0"
+ VALUE "InternalName", "PPMd\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "PPMd.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 9, 2, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Compress/RangeCoder/RangeCoder.h b/7zip/Compress/RangeCoder/RangeCoder.h
new file mode 100755
index 00000000..cb0292f9
--- /dev/null
+++ b/7zip/Compress/RangeCoder/RangeCoder.h
@@ -0,0 +1,244 @@
+// Compress/RangeCoder.h
+// This code is based on Eugene Shelwien's Rangecoder code
+
+// #pragma once
+
+#ifndef __COMPRESS_RANGECODER_H
+#define __COMPRESS_RANGECODER_H
+
+#include "../../Common/InBuffer.h"
+#include "../../Common/OutBuffer.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+const UINT32 kNumTopBits = 24;
+const UINT32 kTopValue = (1 << kNumTopBits);
+
+class CEncoder
+{
+ COutBuffer Stream;
+ UINT64 Low;
+ UINT32 Range;
+ UINT32 _ffNum;
+ BYTE _cache;
+
+public:
+ void Init(ISequentialOutStream *stream)
+ {
+ Stream.Init(stream);
+ Low = 0;
+ Range = UINT32(-1);
+ _ffNum = 0;
+ _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 EncodeDirectBitsDiv(UINT32 value, UINT32 numTotalBits)
+ {
+ Low += value * (Range >>= numTotalBits);
+ Normalize();
+ }
+
+ void EncodeDirectBitsDiv2(UINT32 value, UINT32 numTotalBits)
+ {
+ if (numTotalBits <= kNumBottomBits)
+ EncodeDirectBitsDiv(value, numTotalBits);
+ else
+ {
+ EncodeDirectBitsDiv(value >> kNumBottomBits, (numTotalBits - kNumBottomBits));
+ EncodeDirectBitsDiv(value & ((1 << kBottomValueBits) - 1), kNumBottomBits);
+ }
+ }
+ */
+ void ShiftLow()
+ {
+ if (Low < (UINT32)0xFF000000 || UINT32(Low >> 32) == 1)
+ {
+ Stream.WriteByte(_cache + BYTE(Low >> 32));
+ for (;_ffNum != 0; _ffNum--)
+ Stream.WriteByte(0xFF + BYTE(Low >> 32));
+ _cache = BYTE(UINT32(Low) >> 24);
+ }
+ else
+ _ffNum++;
+ Low = UINT32(Low) << 8;
+ }
+
+ void EncodeDirectBits(UINT32 value, UINT32 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() + _ffNum; }
+};
+
+class CDecoder
+{
+public:
+ CInBuffer Stream;
+ UINT32 Range;
+ UINT32 Code;
+ // UINT32 m_Word;
+ void Normalize()
+ {
+ while (Range < kTopValue)
+ {
+ Code = (Code << 8) | Stream.ReadByte();
+ Range <<= 8;
+ }
+ }
+
+ void Init(ISequentialInStream *stream)
+ {
+ Stream.Init(stream);
+ Code = 0;
+ Range = UINT32(-1);
+ 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, UINT32 total)
+ {
+ Code -= start * Range;
+ Range *= size;
+ Normalize();
+ }
+
+ /*
+ UINT32 DecodeDirectBitsDiv(UINT32 numTotalBits)
+ {
+ Range >>= numTotalBits;
+ UINT32 threshold = Code / Range;
+ Code -= threshold * Range;
+
+ Normalize();
+ return threshold;
+ }
+
+ UINT32 DecodeDirectBitsDiv2(UINT32 numTotalBits)
+ {
+ if (numTotalBits <= kNumBottomBits)
+ return DecodeDirectBitsDiv(numTotalBits);
+ UINT32 result = DecodeDirectBitsDiv(numTotalBits - kNumBottomBits) << kNumBottomBits;
+ return (result | DecodeDirectBitsDiv(kNumBottomBits));
+ }
+ */
+
+ UINT32 DecodeDirectBits(UINT32 numTotalBits)
+ {
+ UINT32 range = Range;
+ UINT32 code = Code;
+ UINT32 result = 0;
+ for (UINT32 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);
+ // range = rangeTmp + ((range & 1) & (1 - t));
+ 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/7zip/Compress/RangeCoder/RangeCoderBit.cpp b/7zip/Compress/RangeCoder/RangeCoderBit.cpp
new file mode 100755
index 00000000..c8acf3cd
--- /dev/null
+++ b/7zip/Compress/RangeCoder/RangeCoderBit.cpp
@@ -0,0 +1,77 @@
+// Compress/RangeCoder/RangeCoderBit.cpp
+
+#include "StdAfx.h"
+
+#include "RangeCoderBit.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+CPriceTables::CPriceTables()
+{
+ /*
+ // simplest: bad solution
+ for(UINT32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
+ StatePrices[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++)
+ StatePrices[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);
+ }
+ }
+ StatePrices[i] = (bitCount
+ // + (1 << (kCyclesBits - 1))
+ ) >> kCyclesBits;
+ }
+ */
+
+ 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++)
+ StatePrices[j] = (i << kNumBitPriceShiftBits) +
+ (((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1));
+ }
+}
+
+CPriceTables g_PriceTables;
+
+}}
diff --git a/7zip/Compress/RangeCoder/RangeCoderBit.h b/7zip/Compress/RangeCoder/RangeCoderBit.h
new file mode 100755
index 00000000..2e49b304
--- /dev/null
+++ b/7zip/Compress/RangeCoder/RangeCoderBit.h
@@ -0,0 +1,107 @@
+// Compress/RangeCoder/RangeCoderBit.h
+
+// #pragma once
+
+#ifndef __COMPRESS_RANGECODER_BIT_TREE_H
+#define __COMPRESS_RANGECODER_BIT_TREE_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:
+ UINT32 StatePrices[kBitModelTotal >> kNumMoveReducingBits];
+ CPriceTables();
+};
+
+extern CPriceTables g_PriceTables;
+
+
+/////////////////////////////
+// CBitModel
+
+template <int aNumMoveBits>
+class CBitModel
+{
+public:
+ UINT32 Probability;
+ void UpdateModel(UINT32 symbol)
+ {
+ /*
+ Probability -= (Probability + ((symbol - 1) & ((1 << aNumMoveBits) - 1))) >> aNumMoveBits;
+ Probability += (1 - symbol) << (kNumBitModelTotalBits - aNumMoveBits);
+ */
+ if (symbol == 0)
+ Probability += (kBitModelTotal - Probability) >> aNumMoveBits;
+ else
+ Probability -= (Probability) >> aNumMoveBits;
+ }
+public:
+ void Init() { Probability = kBitModelTotal / 2; }
+};
+
+template <int aNumMoveBits>
+class CBitEncoder: public CBitModel<aNumMoveBits>
+{
+public:
+ void Encode(CEncoder *encoder, UINT32 symbol)
+ {
+ encoder->EncodeBit(Probability, kNumBitModelTotalBits, symbol);
+ UpdateModel(symbol);
+ }
+ UINT32 GetPrice(UINT32 symbol) const
+ {
+ return g_PriceTables.StatePrices[
+ (((Probability - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
+ }
+};
+
+
+template <int aNumMoveBits>
+class CBitDecoder: public CBitModel<aNumMoveBits>
+{
+public:
+ UINT32 Decode(CDecoder *decoder)
+ {
+ UINT32 newBound = (decoder->Range >> kNumBitModelTotalBits) * Probability;
+ if (decoder->Code < newBound)
+ {
+ decoder->Range = newBound;
+ Probability += (kBitModelTotal - Probability) >> aNumMoveBits;
+ if (decoder->Range < kTopValue)
+ {
+ decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
+ decoder->Range <<= 8;
+ }
+ return 0;
+ }
+ else
+ {
+ decoder->Range -= newBound;
+ decoder->Code -= newBound;
+ Probability -= (Probability) >> aNumMoveBits;
+ if (decoder->Range < kTopValue)
+ {
+ decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
+ decoder->Range <<= 8;
+ }
+ return 1;
+ }
+ }
+};
+
+}}
+
+
+#endif
diff --git a/7zip/Compress/RangeCoder/RangeCoderBitTree.h b/7zip/Compress/RangeCoder/RangeCoderBitTree.h
new file mode 100755
index 00000000..02c74cdb
--- /dev/null
+++ b/7zip/Compress/RangeCoder/RangeCoderBitTree.h
@@ -0,0 +1,303 @@
+// Compress/RangeCoder/RangeCoderBitTree.h
+
+// #pragma once
+
+#ifndef __COMPRESS_RANGECODER_BIT_H
+#define __COMPRESS_RANGECODER_BIT_H
+
+#include "RangeCoderBit.h"
+#include "RangeCoderOpt.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+/*
+template <int numMoveBits> class CMyBitEncoder:
+ public NCompression::NArithmetic::CBitEncoder<numMoveBits> {};
+template <int numMoveBits> class CMyBitDecoder:
+ public NCompression::NArithmetic::CBitDecoder<numMoveBits> {};
+*/
+
+//////////////////////////
+// CBitTreeEncoder
+
+template <int numMoveBits, UINT32 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 (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;)
+ {
+ bitIndex--;
+ UINT32 bit = (symbol >> bitIndex ) & 1;
+ Models[modelIndex].Encode(rangeEncoder, bit);
+ modelIndex = (modelIndex << 1) | bit;
+ }
+ };
+ UINT32 GetPrice(UINT32 symbol) const
+ {
+ UINT32 price = 0;
+ UINT32 modelIndex = 1;
+ for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;)
+ {
+ bitIndex--;
+ UINT32 bit = (symbol >> bitIndex ) & 1;
+ price += Models[modelIndex].GetPrice(bit);
+ modelIndex = (modelIndex << 1) + bit;
+ }
+ return price;
+ }
+};
+
+//////////////////////////
+// CBitTreeDecoder
+
+template <int numMoveBits, UINT32 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(UINT32 bitIndex = NumBitLevels; bitIndex > 0; bitIndex--)
+ {
+ // modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder);
+ RC_GETBIT(numMoveBits, Models[modelIndex].Probability, modelIndex)
+ }
+ RC_FLUSH_VAR
+ return modelIndex - (1 << NumBitLevels);
+ };
+};
+
+////////////////////////////////
+// CReverseBitTreeEncoder
+
+template <int numMoveBits>
+class CReverseBitTreeEncoder2
+{
+ CBitEncoder<numMoveBits> *Models;
+ UINT32 NumBitLevels;
+public:
+ CReverseBitTreeEncoder2(): Models(0) { }
+ ~CReverseBitTreeEncoder2() { delete []Models; }
+ void Create(UINT32 numBitLevels)
+ {
+ NumBitLevels = numBitLevels;
+ Models = new CBitEncoder<numMoveBits>[1 << numBitLevels];
+ // return (Models != 0);
+ }
+ void Init()
+ {
+ UINT32 numModels = 1 << NumBitLevels;
+ for(UINT32 i = 1; i < numModels; i++)
+ Models[i].Init();
+ }
+ void Encode(CEncoder *rangeEncoder, UINT32 symbol)
+ {
+ UINT32 modelIndex = 1;
+ for (UINT32 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
+ {
+ UINT32 price = 0;
+ UINT32 modelIndex = 1;
+ for (UINT32 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 CReverseBitTreeEncoder: public CReverseBitTreeEncoder2<numMoveBits>
+{
+public:
+ CReverseBitTreeEncoder()
+ { Create(numBitLevels); }
+};
+*/
+////////////////////////////////
+// CReverseBitTreeDecoder
+
+template <int numMoveBits>
+class CReverseBitTreeDecoder2
+{
+ CBitDecoder<numMoveBits> *Models;
+ UINT32 NumBitLevels;
+public:
+ CReverseBitTreeDecoder2(): Models(0) { }
+ ~CReverseBitTreeDecoder2() { delete []Models; }
+ void Create(UINT32 numBitLevels)
+ {
+ NumBitLevels = numBitLevels;
+ Models = new CBitDecoder<numMoveBits>[1 << numBitLevels];
+ // return (Models != 0);
+ }
+ void Init()
+ {
+ UINT32 numModels = 1 << NumBitLevels;
+ for(UINT32 i = 1; i < numModels; i++)
+ Models[i].Init();
+ }
+ UINT32 Decode(CDecoder *rangeDecoder)
+ {
+ UINT32 modelIndex = 1;
+ UINT32 symbol = 0;
+ RC_INIT_VAR
+ for(UINT32 bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
+ {
+ // UINT32 bit = Models[modelIndex].Decode(rangeDecoder);
+ // modelIndex <<= 1;
+ // modelIndex += bit;
+ // symbol |= (bit << bitIndex);
+ RC_GETBIT2(numMoveBits, Models[modelIndex].Probability, modelIndex, ; , symbol |= (1 << bitIndex))
+ }
+ RC_FLUSH_VAR
+ return symbol;
+ };
+};
+////////////////////////////
+// CReverseBitTreeDecoder2
+
+template <int numMoveBits, UINT32 NumBitLevels>
+class CReverseBitTreeDecoder
+{
+ 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;
+ UINT32 symbol = 0;
+ RC_INIT_VAR
+ for(UINT32 bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
+ {
+ // UINT32 bit = Models[modelIndex].Decode(rangeDecoder);
+ // modelIndex <<= 1;
+ // modelIndex += bit;
+ // symbol |= (bit << bitIndex);
+ RC_GETBIT2(numMoveBits, Models[modelIndex].Probability, modelIndex, ; , symbol |= (1 << bitIndex))
+ }
+ RC_FLUSH_VAR
+ return symbol;
+ }
+};
+
+/*
+//////////////////////////
+// CBitTreeEncoder2
+
+template <int numMoveBits>
+class CBitTreeEncoder2
+{
+ NCompression::NArithmetic::CBitEncoder<numMoveBits> *Models;
+ UINT32 NumBitLevels;
+public:
+ bool Create(UINT32 numBitLevels)
+ {
+ NumBitLevels = numBitLevels;
+ Models = new NCompression::NArithmetic::CBitEncoder<numMoveBits>[1 << numBitLevels];
+ return (Models != 0);
+ }
+ void Init()
+ {
+ UINT32 numModels = 1 << NumBitLevels;
+ for(UINT32 i = 1; i < numModels; i++)
+ Models[i].Init();
+ }
+ void Encode(CMyRangeEncoder *rangeEncoder, UINT32 symbol)
+ {
+ UINT32 modelIndex = 1;
+ for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;)
+ {
+ bitIndex--;
+ UINT32 bit = (symbol >> bitIndex ) & 1;
+ Models[modelIndex].Encode(rangeEncoder, bit);
+ modelIndex = (modelIndex << 1) | bit;
+ }
+ }
+ UINT32 GetPrice(UINT32 symbol) const
+ {
+ UINT32 price = 0;
+ UINT32 modelIndex = 1;
+ for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;)
+ {
+ bitIndex--;
+ UINT32 bit = (symbol >> bitIndex ) & 1;
+ price += Models[modelIndex].GetPrice(bit);
+ modelIndex = (modelIndex << 1) + bit;
+ }
+ return price;
+ }
+};
+
+
+//////////////////////////
+// CBitTreeDecoder2
+
+template <int numMoveBits>
+class CBitTreeDecoder2
+{
+ NCompression::NArithmetic::CBitDecoder<numMoveBits> *Models;
+ UINT32 NumBitLevels;
+public:
+ bool Create(UINT32 numBitLevels)
+ {
+ NumBitLevels = numBitLevels;
+ Models = new NCompression::NArithmetic::CBitDecoder<numMoveBits>[1 << numBitLevels];
+ return (Models != 0);
+ }
+ void Init()
+ {
+ UINT32 numModels = 1 << NumBitLevels;
+ for(UINT32 i = 1; i < numModels; i++)
+ Models[i].Init();
+ }
+ UINT32 Decode(CMyRangeDecoder *rangeDecoder)
+ {
+ UINT32 modelIndex = 1;
+ RC_INIT_VAR
+ for(UINT32 bitIndex = NumBitLevels; bitIndex > 0; bitIndex--)
+ {
+ // modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder);
+ RC_GETBIT(numMoveBits, Models[modelIndex].Probability, modelIndex)
+ }
+ RC_FLUSH_VAR
+ return modelIndex - (1 << NumBitLevels);
+ }
+};
+*/
+
+}}
+
+#endif
diff --git a/7zip/Compress/RangeCoder/RangeCoderOpt.h b/7zip/Compress/RangeCoder/RangeCoderOpt.h
new file mode 100755
index 00000000..f251caa8
--- /dev/null
+++ b/7zip/Compress/RangeCoder/RangeCoderOpt.h
@@ -0,0 +1,43 @@
+// Compress/RangeCoder/RangeCoderOpt.h
+
+// #pragma once
+
+#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, modelIndex, Action0, Action1) \
+ {UINT32 newBound = (range >> NCompress::NRangeCoder::kNumBitModelTotalBits) * prob; \
+ if (code < newBound) \
+ { \
+ Action0; \
+ range = newBound; \
+ prob += (NCompress::NRangeCoder::kBitModelTotal - prob) >> numMoveBits; \
+ modelIndex <<= 1; \
+ } \
+ else \
+ { \
+ Action1; \
+ range -= newBound; \
+ code -= newBound; \
+ prob -= (prob) >> numMoveBits; \
+ modelIndex = (modelIndex << 1) + 1; \
+ }} \
+ RC_NORMALIZE
+
+#define RC_GETBIT(numMoveBits, prob, modelIndex) RC_GETBIT2(numMoveBits, prob, modelIndex, ; , ;)
+
+#endif
diff --git a/7zip/Compress/RangeCoder/StdAfx.h b/7zip/Compress/RangeCoder/StdAfx.h
new file mode 100755
index 00000000..a32fbed6
--- /dev/null
+++ b/7zip/Compress/RangeCoder/StdAfx.h
@@ -0,0 +1,8 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#endif
diff --git a/7zip/Crypto/7zAES/7zAES.cpp b/7zip/Crypto/7zAES/7zAES.cpp
new file mode 100755
index 00000000..d98d6642
--- /dev/null
+++ b/7zip/Crypto/7zAES/7zAES.cpp
@@ -0,0 +1,355 @@
+// 7z_AES.h
+
+#include "StdAfx.h"
+
+#include "Windows/Defs.h"
+#include "Windows/Synchronization.h"
+#include "../../Common/StreamObjects.h"
+
+#include "7zAES.h"
+// #include "../../Hash/Common/CryptoHashInterface.h"
+
+#ifdef CRYPTO_AES
+#include "../AES/MyAES.h"
+#endif
+
+#include "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
+ {
+ /*
+ CMyComPtr<ICryptoHash> sha;
+ RINOK(sha.CoCreateInstance(CLSID_CCrypto_Hash_SHA256));
+ RINOK(sha->Init());
+ */
+
+ NCrypto::NSHA256::SHA256 sha;
+ const UINT64 numRounds = UINT64(1) << (NumCyclesPower);
+ for (UINT64 round = 0; round < numRounds; round++)
+ {
+ /*
+ RINOK(sha->Update(Salt, SaltSize));
+ RINOK(sha->Update(Password, Password.GetCapacity()));
+ // change it if big endian;
+ RINOK(sha->Update(&round, sizeof(round)));
+ */
+
+ // sha.Update(Salt, sizeof(Salt));
+ sha.Update(Salt, SaltSize);
+ sha.Update(Password, Password.GetCapacity());
+ // change it if big endian;
+ sha.Update((const BYTE *)&round, sizeof(round));
+ }
+ // return sha->GetDigest(Key);
+ 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 = _key.NumCyclesPower |
+ (((_key.SaltSize == 0) ? 0 : 1) << 7) |
+ (((ivSize == 0) ? 0 : 1) << 6);
+ RINOK(outStream->Write(&firstByte, sizeof(firstByte), NULL));
+ if (_key.SaltSize == 0 && ivSize == 0)
+ return S_OK;
+ BYTE saltSizeSpec = (_key.SaltSize == 0) ? 0 : (_key.SaltSize - 1);
+ BYTE ivSizeSpec = (ivSize == 0) ? 0 : (ivSize - 1);
+ BYTE secondByte = ((saltSizeSpec) << 4) | ivSizeSpec;
+ RINOK(outStream->Write(&secondByte, sizeof(secondByte), NULL));
+ if (_key.SaltSize > 0)
+ {
+ RINOK(outStream->Write(_key.Salt, _key.SaltSize, NULL));
+ }
+ if (ivSize > 0)
+ {
+ RINOK(outStream->Write(_iv, ivSize, NULL));
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CEncoder::SetDecoderProperties(ISequentialInStream *inStream)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::SetDecoderProperties(ISequentialInStream *inStream)
+{
+ _key.Init();
+ for (int i = 0; i < sizeof(_iv); i++)
+ _iv[i] = 0;
+ UINT32 processedSize;
+ BYTE firstByte;
+ RINOK(inStream->Read(&firstByte, sizeof(firstByte), &processedSize));
+ if (processedSize == 0)
+ return S_OK;
+
+ _key.NumCyclesPower = firstByte & 0x3F;
+ if ((firstByte & 0xC0) == 0)
+ return S_OK;
+ _key.SaltSize = (firstByte >> 7) & 1;
+ UINT32 ivSize = (firstByte >> 6) & 1;
+
+ BYTE secondByte;
+ RINOK(inStream->Read(&secondByte, sizeof(secondByte), &processedSize));
+ if (processedSize == 0)
+ return E_INVALIDARG;
+
+ _key.SaltSize += (secondByte >> 4);
+ ivSize += (secondByte & 0x0F);
+
+ RINOK(inStream->Read(_key.Salt,
+ _key.SaltSize, &processedSize));
+ if (processedSize != _key.SaltSize)
+ return E_INVALIDARG;
+
+ RINOK(inStream->Read(_iv, ivSize, &processedSize));
+ if (processedSize != ivSize)
+ return E_INVALIDARG;
+
+ return S_OK;
+}
+
+STDMETHODIMP CEncoder::CryptoSetPassword(const BYTE *data, UINT32 size)
+{
+ _key.Password.SetCapacity(size);
+ memcpy(_key.Password, data, size);
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::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 CEncoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, UINT64 const *inSize,
+ const UINT64 *outSize,ICompressProgressInfo *progress)
+{
+ CalculateDigest();
+
+ if (_aesEncoder == 0)
+ {
+ #ifdef CRYPTO_AES
+ _aesEncoder = new CAES256_CBC_Encoder;
+ #else
+ if ((HMODULE)_aesEncoderLibrary == 0)
+ {
+ TCHAR filePath[MAX_PATH + 2];
+ if (!GetAESLibPath(filePath))
+ return ::GetLastError();
+ RINOK(_aesEncoderLibrary.LoadAndCreateCoder2(filePath,
+ CLSID_CCrypto_AES256_Encoder, &_aesEncoder));
+ }
+ #endif
+ }
+
+ CSequentialInStreamImp *ivStreamSpec = new CSequentialInStreamImp;
+ CMyComPtr<ISequentialInStream> ivStream(ivStreamSpec);
+ ivStreamSpec->Init(_iv, sizeof(_iv));
+
+ CSequentialInStreamImp *keyStreamSpec = new CSequentialInStreamImp;
+ CMyComPtr<ISequentialInStream> keyStream(keyStreamSpec);
+ keyStreamSpec->Init(_key.Key, sizeof(_key.Key));
+
+ ISequentialInStream *inStreams[3] = { inStream, ivStream, keyStream };
+ UINT64 ivSize = sizeof(_iv);
+ UINT64 keySize = sizeof(_key.Key);
+ const UINT64 *inSizes[3] = { inSize, &ivSize, &ivSize, };
+ return _aesEncoder->Code(inStreams, inSizes, 3,
+ &outStream, &outSize, 1, progress);
+}
+
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, UINT64 const *inSize,
+ const UINT64 *outSize,ICompressProgressInfo *progress)
+{
+ CalculateDigest();
+
+ if (_aesDecoder == 0)
+ {
+ #ifdef CRYPTO_AES
+ _aesDecoder = new CAES256_CBC_Decoder;
+ #else
+ if ((HMODULE)_aesDecoderLibrary == 0)
+ {
+ TCHAR filePath[MAX_PATH + 2];
+ if (!GetAESLibPath(filePath))
+ return ::GetLastError();
+ RINOK(_aesDecoderLibrary.LoadAndCreateCoder2(filePath,
+ CLSID_CCrypto_AES256_Decoder, &_aesDecoder));
+ }
+ #endif
+ }
+
+ CSequentialInStreamImp *ivStreamSpec = new CSequentialInStreamImp;
+ CMyComPtr<ISequentialInStream> ivStream(ivStreamSpec);
+ ivStreamSpec->Init(_iv, sizeof(_iv));
+
+ CSequentialInStreamImp *keyStreamSpec = new CSequentialInStreamImp;
+ CMyComPtr<ISequentialInStream> keyStream(keyStreamSpec);
+ keyStreamSpec->Init(_key.Key, sizeof(_key.Key));
+
+ ISequentialInStream *inStreams[3] = { inStream, ivStream, keyStream };
+ UINT64 ivSize = sizeof(_iv);
+ UINT64 keySize = sizeof(_key.Key);
+ const UINT64 *inSizes[3] = { inSize, &ivSize, &ivSize, };
+ return _aesDecoder->Code(inStreams, inSizes, 3,
+ &outStream, &outSize, 1, progress);
+}
+
+}}
diff --git a/7zip/Crypto/7zAES/7zAES.def b/7zip/Crypto/7zAES/7zAES.def
new file mode 100755
index 00000000..078b2085
--- /dev/null
+++ b/7zip/Crypto/7zAES/7zAES.def
@@ -0,0 +1,8 @@
+; 7zAES.def
+
+LIBRARY 7zAES.dll
+
+EXPORTS
+ CreateObject PRIVATE
+ GetNumberOfMethods PRIVATE
+ GetMethodProperty PRIVATE
diff --git a/7zip/Crypto/7zAES/7zAES.dsp b/7zip/Crypto/7zAES/7zAES.dsp
new file mode 100755
index 00000000..002aee9b
--- /dev/null
+++ b/7zip/Crypto/7zAES/7zAES.dsp
@@ -0,0 +1,209 @@
+# 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=.\7zAES.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\DllExports.cpp
+# 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 "Common"
+
+# PROP Default_Filter ""
+# 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
+# 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 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
+# Begin Source File
+
+SOURCE=.\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=.\SHA256.h
+# End Source File
+# End Target
+# End Project
diff --git a/7zip/Crypto/7zAES/7zAES.dsw b/7zip/Crypto/7zAES/7zAES.dsw
new file mode 100755
index 00000000..08efbad8
--- /dev/null
+++ b/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/7zip/Crypto/7zAES/7zAES.h b/7zip/Crypto/7zAES/7zAES.h
new file mode 100755
index 00000000..0c0e2cdc
--- /dev/null
+++ b/7zip/Crypto/7zAES/7zAES.h
@@ -0,0 +1,139 @@
+// 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
+
+// {23170F69-40C1-278B-0601-810000000100}
+DEFINE_GUID(CLSID_CCrypto_AES256_Encoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0x81, 0x00, 0x00, 0x00, 0x01, 0x00);
+
+// {23170F69-40C1-278B-0601-810000000000}
+DEFINE_GUID(CLSID_CCrypto_AES256_Decoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0x81, 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 CEncoder:
+ public ICompressCoder,
+ public ICompressSetDecoderProperties,
+ public ICryptoSetPassword,
+ public ICompressWriteCoderProperties,
+ public CMyUnknownImp,
+ public CBase
+{
+ MY_UNKNOWN_IMP3(
+ ICryptoSetPassword,
+ ICompressSetDecoderProperties,
+ ICompressWriteCoderProperties
+ )
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, UINT64 const *inSize,
+ const UINT64 *outSize,ICompressProgressInfo *progress);
+
+ STDMETHOD(CryptoSetPassword)(const BYTE *aData, UINT32 aSize);
+
+ // ICompressSetDecoderProperties
+ STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream);
+
+ // ICompressWriteCoderProperties
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+
+ #ifndef CRYPTO_AES
+ CCoderLibrary _aesEncoderLibrary;
+ #endif
+ CMyComPtr<ICompressCoder2> _aesEncoder;
+};
+
+class CDecoder:
+ public ICompressCoder,
+ public ICompressSetDecoderProperties,
+ public ICryptoSetPassword,
+ public CMyUnknownImp,
+ public CBase
+{
+ MY_UNKNOWN_IMP2(
+ ICryptoSetPassword,
+ ICompressSetDecoderProperties
+ )
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, UINT64 const *inSize,
+ const UINT64 *outSize,ICompressProgressInfo *progress);
+
+ STDMETHOD(CryptoSetPassword)(const BYTE *aData, UINT32 aSize);
+ // ICompressSetDecoderProperties
+
+ STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream);
+
+ #ifndef CRYPTO_AES
+ CCoderLibrary _aesDecoderLibrary;
+ #endif
+ CMyComPtr<ICompressCoder2> _aesDecoder;
+};
+
+}}
+
+#endif
diff --git a/7zip/Crypto/7zAES/DllExports.cpp b/7zip/Crypto/7zAES/DllExports.cpp
new file mode 100755
index 00000000..75998f95
--- /dev/null
+++ b/7zip/Crypto/7zAES/DllExports.cpp
@@ -0,0 +1,96 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#define INITGUID
+
+#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;
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ g_hInstance = hInstance;
+ 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_CCrypto7zAESDecoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder = (ICompressCoder *)new NCrypto::NSevenZ::CDecoder();
+ }
+ else if (*clsid == CLSID_CCrypto7zAESEncoder)
+ {
+ if (!correctInterface)
+ return E_NOINTERFACE;
+ coder = (ICompressCoder *)new NCrypto::NSevenZ::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[] = { 0x06, (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/7zip/Crypto/7zAES/SHA256.cpp b/7zip/Crypto/7zAES/SHA256.cpp
new file mode 100755
index 00000000..21c12fa2
--- /dev/null
+++ b/7zip/Crypto/7zAES/SHA256.cpp
@@ -0,0 +1,189 @@
+// Crypto/HASH/SHA256/SHA256.cpp
+// This code is based on code from Wei Dai's Crypto++ library.
+
+#include "StdAfx.h"
+
+#include "SHA256.h"
+#include "Windows/Defs.h"
+
+const int kBufferSize = 1 << 17;
+
+namespace NCrypto {
+namespace NSHA256 {
+
+
+template <class T> static inline T rotrFixed(T x, unsigned int y)
+{
+ // assert(y < sizeof(T)*8);
+ return (x>>y) | (x<<(sizeof(T)*8-y));
+}
+
+#define blk0(i) (W[i] = data[i])
+
+
+void SHA256::Init()
+{
+ m_digest[0] = 0x6a09e667;
+ m_digest[1] = 0xbb67ae85;
+ m_digest[2] = 0x3c6ef372;
+ m_digest[3] = 0xa54ff53a;
+ m_digest[4] = 0x510e527f;
+ m_digest[5] = 0x9b05688c;
+ m_digest[6] = 0x1f83d9ab;
+ m_digest[7] = 0x5be0cd19;
+
+ m_count = 0;
+}
+
+#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]
+
+#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))
+
+// for SHA256
+#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))
+
+void SHA256::Transform(UINT32 *state, const UINT32 *data)
+{
+ UINT32 W[16];
+ UINT32 T[8];
+ /* Copy context->state[] to working vars */
+ // memcpy(T, state, sizeof(T));
+ for (int s = 0; s < 8; s++)
+ T[s] = state[s];
+
+
+ /* 64 operations, partially loop unrolled */
+ for (unsigned int j = 0; j < 64; j += 16)
+ {
+ for (unsigned int i = 0; i < 16; i++)
+ {
+ R(i);
+ }
+ /*
+ R( 0); R( 1); R( 2); R( 3);
+ R( 4); R( 5); R( 6); R( 7);
+ R( 8); R( 9); R(10); R(11);
+ R(12); R(13); R(14); R(15);
+ */
+ }
+ /* Add the working vars back into context.state[] */
+ /*
+ state[0] += a(0);
+ state[1] += b(0);
+ state[2] += c(0);
+ state[3] += d(0);
+ state[4] += e(0);
+ state[5] += f(0);
+ state[6] += g(0);
+ state[7] += h(0);
+ */
+ for (int i = 0; i < 8; i++)
+ state[i] += T[i];
+
+ /* Wipe variables */
+ // memset(W, 0, sizeof(W));
+ // memset(T, 0, sizeof(T));
+}
+
+const UINT32 SHA256::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 SHA256::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(m_digest, data32);
+}
+
+void SHA256::Update(const BYTE *data, UINT32 size)
+{
+ UINT32 curBufferPos = UINT32(m_count) & 0x3F;
+ while (size > 0)
+ {
+ while(curBufferPos < 64 && size > 0)
+ {
+ _buffer[curBufferPos++] = *data++;
+ m_count++;
+ size--;
+ }
+ if (curBufferPos == 64)
+ {
+ curBufferPos = 0;
+ WriteByteBlock();
+ }
+ }
+}
+
+void SHA256::Final(BYTE *digest)
+{
+ UINT64 lenInBits = (m_count << 3);
+ UINT32 curBufferPos = UINT32(m_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++ = m_digest[j] >> 24;
+ *digest++ = m_digest[j] >> 16;
+ *digest++ = m_digest[j] >> 8;
+ *digest++ = m_digest[j];
+ }
+ Init();
+}
+
+}}
diff --git a/7zip/Crypto/7zAES/SHA256.h b/7zip/Crypto/7zAES/SHA256.h
new file mode 100755
index 00000000..59024435
--- /dev/null
+++ b/7zip/Crypto/7zAES/SHA256.h
@@ -0,0 +1,30 @@
+// Crypto/SHA/SHA256.h
+
+#ifndef __CRYPTO_SHA256_H
+#define __CRYPTO_SHA256_H
+
+#include "Common/Types.h"
+
+namespace NCrypto {
+namespace NSHA256 {
+
+class SHA256
+{
+ static const UINT32 K[64];
+
+ UINT32 m_digest[8];
+ UINT64 m_count;
+ BYTE _buffer[64];
+ static void Transform(UINT32 *digest, const UINT32 *data);
+ void WriteByteBlock();
+public:
+ enum {DIGESTSIZE = 32};
+ SHA256() { Init(); } ;
+ void Init();
+ void Update(const BYTE *data, UINT32 size);
+ void Final(BYTE *digest);
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/7zip/Crypto/7zAES/StdAfx.cpp b/7zip/Crypto/7zAES/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Crypto/7zAES/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Crypto/7zAES/StdAfx.h b/7zip/Crypto/7zAES/StdAfx.h
new file mode 100755
index 00000000..99ff6f25
--- /dev/null
+++ b/7zip/Crypto/7zAES/StdAfx.h
@@ -0,0 +1,8 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#endif
diff --git a/7zip/Crypto/7zAES/resource.h b/7zip/Crypto/7zAES/resource.h
new file mode 100755
index 00000000..612062a2
--- /dev/null
+++ b/7zip/Crypto/7zAES/resource.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Crypto/7zAES/resource.rc b/7zip/Crypto/7zAES/resource.rc
new file mode 100755
index 00000000..15641858
--- /dev/null
+++ b/7zip/Crypto/7zAES/resource.rc
@@ -0,0 +1,121 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,9,2,0
+ PRODUCTVERSION 3,9,2,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "7z-AES Crypto\0"
+ VALUE "FileVersion", "3, 9, 2, 0\0"
+ VALUE "InternalName", "7zAES\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "7zAES.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 9, 2, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Crypto/AES/AES.def b/7zip/Crypto/AES/AES.def
new file mode 100755
index 00000000..392f21a3
--- /dev/null
+++ b/7zip/Crypto/AES/AES.def
@@ -0,0 +1,8 @@
+; AES.def
+
+LIBRARY AES.dll
+
+EXPORTS
+ CreateObject PRIVATE
+ GetNumberOfMethods PRIVATE
+ GetMethodProperty PRIVATE
diff --git a/7zip/Crypto/AES/AES.dsp b/7zip/Crypto/AES/AES.dsp
new file mode 100755
index 00000000..1e132956
--- /dev/null
+++ b/7zip/Crypto/AES/AES.dsp
@@ -0,0 +1,223 @@
+# 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=.\AES.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\DllExports.cpp
+# 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\OutBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.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
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# End Target
+# End Project
diff --git a/7zip/Crypto/AES/AES.dsw b/7zip/Crypto/AES/AES.dsw
new file mode 100755
index 00000000..7fa9d07b
--- /dev/null
+++ b/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/7zip/Crypto/AES/AES_CBC.h b/7zip/Crypto/AES/AES_CBC.h
new file mode 100755
index 00000000..67780a9d
--- /dev/null
+++ b/7zip/Crypto/AES/AES_CBC.h
@@ -0,0 +1,48 @@
+// AES_CBC.h
+
+#ifndef __AES_CBC_H
+#define __AES_CBC_H
+
+#include "aescpp.h"
+
+class CAES_CBCEncoder: public AESclass
+{
+ BYTE _prevBlock[16];
+public:
+ void Init(const BYTE *iv)
+ {
+ for (int i = 0; i < 16; i++)
+ _prevBlock[i] = iv[i];
+ }
+ void ProcessData(BYTE *outBlock, const BYTE *inBlock)
+ {
+ 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];
+ }
+};
+
+class CAES_CBCCBCDecoder: public AESclass
+{
+ BYTE _prevBlock[16];
+public:
+ void Init(const BYTE *iv)
+ {
+ for (int i = 0; i < 16; i++)
+ _prevBlock[i] = iv[i];
+ }
+ void ProcessData(BYTE *outBlock, const BYTE *inBlock)
+ {
+ 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/7zip/Crypto/AES/DllExports.cpp b/7zip/Crypto/AES/DllExports.cpp
new file mode 100755
index 00000000..124a40a5
--- /dev/null
+++ b/7zip/Crypto/AES/DllExports.cpp
@@ -0,0 +1,185 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#define INITGUID
+
+#include "Common/ComTry.h"
+#include "../../ICoder.h"
+#include "MyAES.h"
+
+/*
+// {23170F69-40C1-278B-0601-000000000100}
+DEFINE_GUID(CLSID_CCrypto_AES_Encoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00);
+
+// {23170F69-40C1-278B-0601-000000000000}
+DEFINE_GUID(CLSID_CCrypto_AES_Decoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+*/
+
+/*
+#include "Interface/ICoder.h"
+
+#include "Alien/Crypto/CryptoPP/crc.h"
+#include "Alien/Crypto/CryptoPP/sha.h"
+#include "Alien/Crypto/CryptoPP/md2.h"
+#include "Alien/Crypto/CryptoPP/md5.h"
+#include "Alien/Crypto/CryptoPP/ripemd.h"
+#include "Alien/Crypto/CryptoPP/haval.h"
+// #include "Alien/Crypto/CryptoPP/tiger.h"
+
+
+using namespace CryptoPP;
+
+#define CLSIDName(Name) CLSID_CCryptoHash ## Name
+#define ClassName(Name) aClass ## Name
+
+// {23170F69-40C1-278B-17??-000000000000}
+#define MyClassID(Name, anID) DEFINE_GUID(CLSIDName(Name), \
+ 0x23170F69, 0x40C1, 0x278B, 0x17, anID, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+#define Pair(Name, anID) MyClassID(Name, anID)\
+typedef CHash<Name, &CLSIDName(Name)> ClassName(Name);
+
+Pair(CRC32, 1)
+Pair(SHA1, 2)
+Pair(SHA256, 3)
+Pair(SHA384, 4)
+Pair(SHA512, 5)
+Pair(MD2, 6)
+Pair(MD5, 7)
+Pair(RIPEMD160, 8)
+Pair(HAVAL, 9)
+// Pair(Tiger, 18)
+
+#define My_OBJECT_ENTRY(ID) OBJECT_ENTRY(CLSIDName(ID), ClassName(ID))
+
+BEGIN_OBJECT_MAP(ObjectMap)
+ My_OBJECT_ENTRY(CRC32)
+ My_OBJECT_ENTRY(SHA1)
+ My_OBJECT_ENTRY(SHA256)
+ My_OBJECT_ENTRY(SHA384)
+ My_OBJECT_ENTRY(SHA512)
+ My_OBJECT_ENTRY(MD2)
+ My_OBJECT_ENTRY(MD5)
+ My_OBJECT_ENTRY(RIPEMD160)
+ My_OBJECT_ENTRY(HAVAL)
+// My_OBJECT_ENTRY(Tiger)
+END_OBJECT_MAP()
+*/
+
+/*
+#define MyOBJECT_ENTRY(Name) \
+ OBJECT_ENTRY(CLSID_CCrypto ## Name ## _Encoder, C ## Name ## _Encoder) \
+ OBJECT_ENTRY(CLSID_CCrypto ## Name ## _Decoder, C ## Name ## _Decoder) \
+
+BEGIN_OBJECT_MAP(ObjectMap)
+ MyOBJECT_ENTRY(_AES128_CBC)
+ MyOBJECT_ENTRY(_AES256_CBC)
+END_OBJECT_MAP()
+*/
+
+/////////////////////////////////////////////////////////////////////////////
+// DLL Entry Point
+
+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; \
+ coder = (ICompressCoder2 *)new C ## n ## _Encoder(); \
+ } else if (*clsid == CLSID_CCrypto_ ## n ## _Decoder){ \
+ if (!correctInterface) \
+ return E_NOINTERFACE; \
+ coder = (ICompressCoder2 *)new C ## n ## _Decoder(); \
+ }
+
+STDAPI CreateObject(
+ const GUID *clsid,
+ const GUID *interfaceID,
+ void **outObject)
+{
+ COM_TRY_BEGIN
+ *outObject = 0;
+ int correctInterface = (*interfaceID == IID_ICompressCoder2);
+ CMyComPtr<ICompressCoder2> coder;
+
+ MY_CreateClass(AES128_CBC)
+ else
+ MY_CreateClass(AES256_CBC)
+ else
+ return CLASS_E_CLASSNOTAVAILABLE;
+ *outObject = coder.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(AES128_CBC, 0x01, L"AES128"),
+ METHOD_ITEM(AES256_CBC, char(0x81), L"AES256")
+};
+
+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;
+ case NMethodPropID::kInStreams:
+ {
+ value->vt = VT_UI4;
+ value->ulVal = 3;
+ return S_OK;
+ }
+ }
+ return S_OK;
+}
+
diff --git a/7zip/Crypto/AES/MyAES.cpp b/7zip/Crypto/AES/MyAES.cpp
new file mode 100755
index 00000000..e97af86b
--- /dev/null
+++ b/7zip/Crypto/AES/MyAES.cpp
@@ -0,0 +1,198 @@
+// Crypto/Rar20/Encoder.h
+
+#include "StdAfx.h"
+
+#include "windows.h"
+
+#include "MyAES.h"
+#include "Windows/Defs.h"
+#include "Common/Defs.h"
+
+#include "AES_CBC.h"
+
+extern "C"
+{
+#include "aesopt.h"
+}
+class CTabInit
+{
+public:
+ CTabInit()
+ {
+ gen_tabs();
+ }
+} g_TabInit;
+
+const int kBlockSize = 16;
+
+static HRESULT Encode(
+ CInBuffer &inBuffer,
+ COutBuffer &outBuffer,
+ ISequentialInStream **inStreams,
+ const UINT64 **inSizes,
+ UINT32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UINT64 **outSizes,
+ UINT32 numOutStreams,
+ ICompressProgressInfo *progress,
+ UINT32 keySize)
+{
+ try
+ {
+ if (numInStreams != 3 || numOutStreams != 1)
+ return E_INVALIDARG;
+
+ BYTE key[32];
+ BYTE iv[kBlockSize];
+
+ /*
+ int i;
+ for (i = 0; i < kBlockSize; i++)
+ iv[i] = 1;
+ for (i = 0; i < keySize; i++)
+ key[i] = 2;
+
+ RINOK(outStreams[1]->Write(iv, kBlockSize, NULL));
+ RINOK(outStreams[2]->Write(key, keySize, NULL));
+ */
+ UINT32 processedSize;
+ RINOK(inStreams[1]->Read(iv, kBlockSize, &processedSize));
+ if (processedSize != kBlockSize)
+ return E_FAIL;
+
+ RINOK(inStreams[2]->Read(key, keySize, &processedSize));
+ if (processedSize != keySize)
+ return E_FAIL;
+
+ CAES_CBCEncoder encoder;
+ encoder.enc_key(key, keySize);
+ encoder.Init(iv);
+
+ inBuffer.Init(inStreams[0]);
+ outBuffer.Init(outStreams[0]);
+
+ UINT64 nowPos = 0, posPrev = 0;
+ while(true)
+ {
+ BYTE inBlock[kBlockSize], outBlock[kBlockSize];
+ UINT32 numBytes;
+ inBuffer.ReadBytes(inBlock, kBlockSize, numBytes);
+ for (int i = numBytes; i < kBlockSize; i++)
+ inBlock[i] = 0;
+ encoder.ProcessData(outBlock, inBlock);
+ outBuffer.WriteBytes(outBlock, kBlockSize);
+
+ nowPos += numBytes;
+ if (progress != NULL && (nowPos - posPrev) > (1 << 18))
+ {
+ UINT64 outSize = nowPos - numBytes + kBlockSize;
+ RINOK(progress->SetRatioInfo(&nowPos, &outSize));
+ posPrev = nowPos;
+ }
+ if (numBytes < kBlockSize)
+ break;
+ }
+ return outBuffer.Flush();
+ // inBuffer.ReleaseStream();
+ // outBuffer.ReleaseStream();
+ // return S_OK;
+ }
+ catch(const CInBufferException &e) { return e.ErrorCode; }
+ catch(const COutBufferException &e) { return e.ErrorCode; }
+ catch(...) { return E_FAIL; }
+}
+
+static HRESULT Decode(
+ CInBuffer &inBuffer,
+ COutBuffer &outBuffer,
+ ISequentialInStream **inStreams,
+ const UINT64 **inSizes,
+ UINT32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UINT64 **outSizes,
+ UINT32 numOutStreams,
+ ICompressProgressInfo *progress,
+ UINT32 keySize)
+{
+ try
+ {
+ if (numInStreams != 3 || numOutStreams != 1)
+ return E_INVALIDARG;
+ BYTE key[32];
+ BYTE iv[kBlockSize];
+ UINT32 processedSize;
+ RINOK(inStreams[1]->Read(iv, kBlockSize, &processedSize));
+ if (processedSize != kBlockSize)
+ return E_FAIL;
+
+ RINOK(inStreams[2]->Read(key, keySize, &processedSize));
+ if (processedSize != keySize)
+ return E_FAIL;
+
+ CAES_CBCCBCDecoder decoder;
+ decoder.dec_key(key, keySize);
+ decoder.Init(iv);
+
+ inBuffer.Init(inStreams[0]);
+ outBuffer.Init(outStreams[0]);
+
+ const UINT64 *outSize = outSizes[0];
+ UINT64 nowPos = 0;
+ UINT64 posPrev = 0;
+ while(true)
+ {
+ BYTE inBlock[kBlockSize], outBlock[kBlockSize];
+ UINT32 numBytes;
+ inBuffer.ReadBytes(inBlock, kBlockSize, numBytes);
+ if (numBytes == 0)
+ break;
+ decoder.ProcessData(outBlock, inBlock);
+ UINT32 numBytesToWrite = kBlockSize;
+ if (outSize != 0)
+ numBytesToWrite = (UINT32)MyMin((*outSize - nowPos), UINT64(numBytesToWrite));
+ outBuffer.WriteBytes(outBlock, numBytesToWrite);
+ nowPos += numBytesToWrite;
+
+ if (progress != NULL && (nowPos - posPrev) > (1 << 18))
+ {
+ UINT64 inSize = inBuffer.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&inSize, &nowPos));
+ posPrev = nowPos;
+ }
+
+ if (outSize != 0)
+ if (nowPos >= *outSize)
+ break;
+ }
+ return outBuffer.Flush();
+ // inBuffer.ReleaseStream();
+ // outBuffer.ReleaseStream();
+ // return S_OK;
+ }
+ catch(const CInBufferException &e) { return e.ErrorCode; }
+ catch(const COutBufferException &e) { return e.ErrorCode; }
+ catch(...) { return E_FAIL; }
+}
+
+
+#define MyClassCryptoImp(Name, keySize) \
+STDMETHODIMP C ## Name ## _Encoder::Code( \
+ ISequentialInStream **inStreams, const UINT64 **inSizes, UINT32 numInStreams, \
+ ISequentialOutStream **outStreams, const UINT64 **outSizes, UINT32 numOutStreams, \
+ ICompressProgressInfo *progress) \
+{ \
+ return Encode(_inByte, _outByte, inStreams, inSizes, numInStreams, \
+ outStreams, outSizes, numOutStreams, progress, keySize); \
+} \
+STDMETHODIMP C ## Name ## _Decoder::Code( \
+ ISequentialInStream **inStreams, const UINT64 **inSizes, UINT32 numInStreams, \
+ ISequentialOutStream **outStreams, const UINT64 **outSizes, UINT32 numOutStreams, \
+ ICompressProgressInfo *progress) \
+{ \
+ return Decode(_inByte, _outByte, inStreams, inSizes, numInStreams, \
+ outStreams, outSizes, numOutStreams, progress, keySize); \
+}
+
+MyClassCryptoImp(AES128_CBC, 16)
+MyClassCryptoImp(AES256_CBC, 32)
+
diff --git a/7zip/Crypto/AES/MyAES.h b/7zip/Crypto/AES/MyAES.h
new file mode 100755
index 00000000..3da6b041
--- /dev/null
+++ b/7zip/Crypto/AES/MyAES.h
@@ -0,0 +1,47 @@
+// Cipher/AES/MyAES.h
+
+#pragma once
+
+#ifndef __CIPHER_MYAES_H
+#define __CIPHER_MYAES_H
+
+#include "Common/Types.h"
+#include "Common/MyCom.h"
+
+#include "../../ICoder.h"
+#include "../../IPassword.h"
+#include "../../Common/InBuffer.h"
+#include "../../Common/OutBuffer.h"
+
+// #include "Alien/Crypto/CryptoPP/algparam.h"
+// #include "Alien/Crypto/CryptoPP/modes.h"
+// #include "Alien/Crypto/CryptoPP/aes.h"
+
+#define MyClassCrypto3(Name) \
+class C ## Name: \
+ public ICompressCoder2, \
+ public CMyUnknownImp { \
+ CInBuffer _inByte; \
+ COutBuffer _outByte; \
+public: \
+ MY_UNKNOWN_IMP \
+ STDMETHOD(Code)( \
+ ISequentialInStream **inStreams, const UINT64 **inSizes, UINT32 numInStreams, \
+ ISequentialOutStream **outStreams, const UINT64 **outSizes, UINT32 numOutStreams, \
+ ICompressProgressInfo *progress); \
+};
+
+// {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); \
+MyClassCrypto3(Name) \
+
+#define MyClassCrypto(Name, id) \
+MyClassCrypto2(Name ## _Encoder, id, 0x01) \
+MyClassCrypto2(Name ## _Decoder, id, 0x00)
+
+MyClassCrypto(AES128_CBC, 0x01)
+MyClassCrypto(AES256_CBC, 0x81)
+
+#endif \ No newline at end of file
diff --git a/7zip/Crypto/AES/StdAfx.cpp b/7zip/Crypto/AES/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/Crypto/AES/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/Crypto/AES/StdAfx.h b/7zip/Crypto/AES/StdAfx.h
new file mode 100755
index 00000000..a32fbed6
--- /dev/null
+++ b/7zip/Crypto/AES/StdAfx.h
@@ -0,0 +1,8 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#endif
diff --git a/7zip/Crypto/AES/aes.h b/7zip/Crypto/AES/aes.h
new file mode 100755
index 00000000..9aaba978
--- /dev/null
+++ b/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/7zip/Crypto/AES/aescpp.h b/7zip/Crypto/AES/aescpp.h
new file mode 100755
index 00000000..93e3c8b0
--- /dev/null
+++ b/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/7zip/Crypto/AES/aescrypt.c b/7zip/Crypto/AES/aescrypt.c
new file mode 100755
index 00000000..095a61c4
--- /dev/null
+++ b/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/7zip/Crypto/AES/aeskey.c b/7zip/Crypto/AES/aeskey.c
new file mode 100755
index 00000000..d281e1a8
--- /dev/null
+++ b/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/7zip/Crypto/AES/aesopt.h b/7zip/Crypto/AES/aesopt.h
new file mode 100755
index 00000000..040089c6
--- /dev/null
+++ b/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/7zip/Crypto/AES/aestab.c b/7zip/Crypto/AES/aestab.c
new file mode 100755
index 00000000..de1d7eea
--- /dev/null
+++ b/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/7zip/Crypto/AES/resource.h b/7zip/Crypto/AES/resource.h
new file mode 100755
index 00000000..612062a2
--- /dev/null
+++ b/7zip/Crypto/AES/resource.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/Crypto/AES/resource.rc b/7zip/Crypto/AES/resource.rc
new file mode 100755
index 00000000..57a99b6b
--- /dev/null
+++ b/7zip/Crypto/AES/resource.rc
@@ -0,0 +1,121 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,9,2,0
+ PRODUCTVERSION 3,9,2,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "AES Crypto\0"
+ VALUE "FileVersion", "3, 9, 2, 0\0"
+ VALUE "InternalName", "AES\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "AES.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 9, 2, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/Crypto/Rar20/Rar20Cipher.cpp b/7zip/Crypto/Rar20/Rar20Cipher.cpp
new file mode 100755
index 00000000..c2423482
--- /dev/null
+++ b/7zip/Crypto/Rar20/Rar20Cipher.cpp
@@ -0,0 +1,67 @@
+// Crypto/Rar20Cipher.cpp
+
+#include "StdAfx.h"
+
+#include "Rar20Cipher.h"
+#include "Windows/Defs.h"
+
+namespace NCrypto {
+namespace NRar20 {
+
+static const int kBufferSize = 1 << 17;
+
+CDecoder::CDecoder():
+ _buffer(0)
+{
+ _buffer = new BYTE[kBufferSize];
+}
+
+CDecoder::~CDecoder()
+{
+ delete []_buffer;
+}
+
+STDMETHODIMP CDecoder::CryptoSetPassword(const BYTE *data, UINT32 size)
+{
+ _coder.SetPassword(data, size);
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ UINT64 nowPos = 0;
+ UINT32 bufferPos = 0;
+ UINT32 processedSize;
+ while(true)
+ {
+ 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/7zip/Crypto/Rar20/Rar20Cipher.h b/7zip/Crypto/Rar20/Rar20Cipher.h
new file mode 100755
index 00000000..f4cc49d2
--- /dev/null
+++ b/7zip/Crypto/Rar20/Rar20Cipher.h
@@ -0,0 +1,40 @@
+// 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 ICompressCoder,
+ public ICryptoSetPassword,
+ public CMyUnknownImp
+{
+ BYTE *_buffer;
+public:
+ CData _coder;
+
+ CDecoder();
+ ~CDecoder();
+
+ MY_UNKNOWN_IMP1(ICryptoSetPassword)
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, UINT64 const *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress);
+
+ STDMETHOD(CryptoSetPassword)(const BYTE *data, UINT32 size);
+
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/7zip/Crypto/Rar20/Rar20Crypto.cpp b/7zip/Crypto/Rar20/Rar20Crypto.cpp
new file mode 100755
index 00000000..ae95655a
--- /dev/null
+++ b/7zip/Crypto/Rar20/Rar20Crypto.cpp
@@ -0,0 +1,144 @@
+// 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 *Ch1, BYTE *Ch2)
+{
+ BYTE Ch = *Ch1;
+ *Ch1 = *Ch2;
+ *Ch2 = Ch;
+}
+
+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]);
+}
+
+void CData::EncryptBlock(BYTE *Buf)
+{
+ UINT32 A, B, C, D, T, TA, TB;
+
+ UINT32 *BufPtr;
+ BufPtr = (UINT32 *)Buf;
+
+ A = BufPtr[0] ^ Keys[0];
+ B = BufPtr[1] ^ Keys[1];
+ C = BufPtr[2] ^ Keys[2];
+ D = BufPtr[3] ^ Keys[3];
+
+ for(int i = 0; i < kNumRounds; i++)
+ {
+ T = ((C + rol(D, 11)) ^ Keys[i & 3]);
+ TA = A ^ SubstLong(T);
+ T=((D ^ rol(C, 17)) + Keys[i & 3]);
+ TB = B ^ SubstLong(T);
+ A = C;
+ B = D;
+ C = TA;
+ D = TB;
+ }
+
+ BufPtr[0] = C ^ Keys[0];
+ BufPtr[1] = D ^ Keys[1];
+ BufPtr[2] = A ^ Keys[2];
+ BufPtr[3] = B ^ Keys[3];
+
+ UpdateKeys(Buf);
+}
+
+void CData::DecryptBlock(BYTE *Buf)
+{
+ BYTE InBuf[16];
+ UINT32 A, B, C, D, T, TA, TB;
+
+ UINT32 *BufPtr;
+ BufPtr = (UINT32 *)Buf;
+
+ A = BufPtr[0] ^ Keys[0];
+ B = BufPtr[1] ^ Keys[1];
+ C = BufPtr[2] ^ Keys[2];
+ D = BufPtr[3] ^ Keys[3];
+
+ memcpy(InBuf, Buf, sizeof(InBuf));
+
+ for(int i = kNumRounds - 1; i >= 0; i--)
+ {
+ T = ((C + rol(D, 11)) ^ Keys[i & 3]);
+ TA = A ^ SubstLong(T);
+ T = ((D ^ rol(C, 17)) + Keys[i & 3]);
+ TB = B ^ SubstLong(T);
+ A = C;
+ B = D;
+ C = TA;
+ D = TB;
+ }
+
+ BufPtr[0] = C ^ Keys[0];
+ BufPtr[1] = D ^ Keys[1];
+ BufPtr[2] = A ^ Keys[2];
+ BufPtr[3] = B ^ Keys[3];
+
+ UpdateKeys(InBuf);
+}
+
+}}
diff --git a/7zip/Crypto/Rar20/Rar20Crypto.h b/7zip/Crypto/Rar20/Rar20Crypto.h
new file mode 100755
index 00000000..589adae5
--- /dev/null
+++ b/7zip/Crypto/Rar20/Rar20Crypto.h
@@ -0,0 +1,32 @@
+// Crypto/Rar20/Crypto.h
+
+#pragma once
+
+#ifndef __CRYPTO_RAR20_CRYPTO_H
+#define __CRYPTO_RAR20_CRYPTO_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);
+public:
+ void EncryptBlock(BYTE *Buf);
+ void DecryptBlock(BYTE *Buf);
+ void SetPassword(const BYTE *password, UINT32 passwordLength);
+};
+
+}}
+
+#endif
diff --git a/7zip/Crypto/RarAES/RarAES.cpp b/7zip/Crypto/RarAES/RarAES.cpp
new file mode 100755
index 00000000..2a13e13b
--- /dev/null
+++ b/7zip/Crypto/RarAES/RarAES.cpp
@@ -0,0 +1,157 @@
+// Crypto/RarAES/RarAES.h
+// This code is based on UnRar sources
+
+#include "StdAfx.h"
+
+#include "../../Common/StreamObjects.h"
+#include "../../Archive/Common/CoderLoader.h"
+
+#include "Windows/Defs.h"
+
+#include "RarAES.h"
+#include "sha1.h"
+
+extern void GetCryptoFolderPrefix(TCHAR *path);
+
+// {23170F69-40C1-278B-0601-010000000000}
+DEFINE_GUID(CLSID_CCrypto_AES128_Decoder,
+0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+namespace NCrypto {
+namespace NRar29 {
+
+CDecoder::CDecoder():
+ _thereIsSalt(false),
+ _needCalculate(true)
+{
+ for (int i = 0; i < sizeof(_salt); i++)
+ _salt[i] = 0;
+}
+
+STDMETHODIMP CDecoder::SetDecoderProperties(ISequentialInStream *inStream)
+{
+ bool thereIsSaltPrev = _thereIsSalt;
+ _thereIsSalt = false;
+ UINT32 processedSize;
+ BYTE salt[8];
+ RINOK(inStream->Read(salt, sizeof(salt), &processedSize));
+ if (processedSize == 0)
+ _thereIsSalt = false;
+ if (processedSize != sizeof(salt))
+ 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] != salt[i])
+ {
+ same = false;
+ break;
+ }
+ }
+ }
+ for (int i = 0; i < sizeof(_salt); i++)
+ _salt[i] = salt[i];
+ if (!_needCalculate && !same)
+ _needCalculate = true;
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::CryptoSetPassword(const BYTE *data, UINT32 size)
+{
+ 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::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, UINT64 const *inSize,
+ const UINT64 *outSize,ICompressProgressInfo *progress)
+{
+ if (_needCalculate)
+ {
+ const MAXPASSWORD = 128;
+ const SALT_SIZE = 8;
+
+ BYTE rawPassword[2 * MAXPASSWORD+ SALT_SIZE];
+
+ memcpy(rawPassword, buffer, buffer.GetCapacity());
+
+ int rawLength = buffer.GetCapacity();
+
+ if (_thereIsSalt)
+ {
+ memcpy(rawPassword + rawLength, _salt, SALT_SIZE);
+ rawLength += SALT_SIZE;
+ }
+
+ hash_context c;
+ hash_initial(&c);
+
+ const int hashRounds = 0x40000;
+ int i;
+ for (i = 0; i < hashRounds; i++)
+ {
+ hash_process(&c, rawPassword, rawLength);
+ BYTE pswNum[3];
+ pswNum[0] = (BYTE)i;
+ pswNum[1] = (BYTE)(i >> 8);
+ pswNum[2] = (BYTE)(i >> 16);
+ hash_process(&c, pswNum, 3);
+ if (i % (hashRounds / 16) == 0)
+ {
+ hash_context tempc = c;
+ UINT32 digest[5];
+ hash_final(&tempc, digest);
+ aesInit[i / (hashRounds / 16)] = (BYTE)digest[4];
+ }
+ }
+ UINT32 digest[5];
+ hash_final(&c, digest);
+ for (i = 0; i < 4; i++)
+ for (int j = 0; j < 4; j++)
+ aesKey[i * 4 + j] = (BYTE)(digest[i] >> (j * 8));
+ }
+ _needCalculate = false;
+
+ 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/7zip/Crypto/RarAES/RarAES.h b/7zip/Crypto/RarAES/RarAES.h
new file mode 100755
index 00000000..480c3b06
--- /dev/null
+++ b/7zip/Crypto/RarAES/RarAES.h
@@ -0,0 +1,48 @@
+// Crypto/CRarAES/RarAES.h
+
+#ifndef __CRYPTO_RARAES_H
+#define __CRYPTO_RARAES_H
+
+#include "Common/MyCom.h"
+#include "../../ICoder.h"
+#include "../../IPassword.h"
+
+#include "Common/Types.h"
+#include "Common/Buffer.h"
+
+namespace NCrypto {
+namespace NRar29 {
+
+class CDecoder:
+ public ICompressCoder,
+ public ICompressSetDecoderProperties,
+ public ICryptoSetPassword,
+ public CMyUnknownImp
+{
+ BYTE _salt[8];
+ bool _thereIsSalt;
+ CByteBuffer buffer;
+ BYTE aesKey[16];
+ BYTE aesInit[16];
+ bool _needCalculate;
+public:
+
+ MY_UNKNOWN_IMP2(
+ ICryptoSetPassword,
+ ICompressSetDecoderProperties)
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, UINT64 const *inSize,
+ const UINT64 *outSize,ICompressProgressInfo *progress);
+
+ STDMETHOD(CryptoSetPassword)(const BYTE *aData, UINT32 aSize);
+
+ // ICompressSetDecoderProperties
+ STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream);
+
+ CDecoder();
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/7zip/Crypto/RarAES/sha1.cpp b/7zip/Crypto/RarAES/sha1.cpp
new file mode 100755
index 00000000..a0944177
--- /dev/null
+++ b/7zip/Crypto/RarAES/sha1.cpp
@@ -0,0 +1,214 @@
+// sha1.cpp
+// This file from UnRar sources
+
+#include "StdAfx.h"
+
+#include "sha1.h"
+
+/*
+SHA-1 in C
+By Steve Reid <steve@edmweb.com>
+100% Public Domain
+
+ Test Vectors (from FIPS PUB 180-1)
+ "abc"
+ A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+ A million repetitions of "a"
+ 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+*/
+
+#if !defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
+#if defined(_M_IX86) || defined(_M_I86) || defined(__alpha)
+#define LITTLE_ENDIAN
+#else
+#error "LITTLE_ENDIAN or BIG_ENDIAN must be defined"
+#endif
+#endif
+
+/* #define SHA1HANDSOFF * Copies data before messing with it. */
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/* blk0() and blk() perform the initial expand. */
+/* I got the idea of expanding during the round function from SSLeay */
+#ifdef LITTLE_ENDIAN
+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
+|(rol(block->l[i],8)&0x00FF00FF))
+#else
+#define blk0(i) block->l[i]
+#endif
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
+^block->l[(i+2)&15]^block->l[i&15],1))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) {z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);}
+#define R1(v,w,x,y,z,i) {z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);}
+#define R2(v,w,x,y,z,i) {z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);}
+#define R3(v,w,x,y,z,i) {z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);}
+#define R4(v,w,x,y,z,i) {z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);}
+
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+
+void SHA1Transform(UINT32 state[5], unsigned char buffer[64])
+{
+ UINT32 a, b, c, d, e;
+ typedef union {
+ unsigned char c[64];
+ UINT32 l[16];
+ } CHAR64LONG16;
+ CHAR64LONG16* block;
+#ifdef SHA1HANDSOFF
+ static unsigned char workspace[64];
+ block = (CHAR64LONG16*)workspace;
+ memcpy(block, buffer, 64);
+#else
+ block = (CHAR64LONG16*)buffer;
+#endif
+#ifdef SFX_MODULE
+ static int pos[80][5];
+ static bool pinit=false;
+ if (!pinit)
+ {
+ for (int I=0,P=0;I<80;I++,P=(P ? P-1:4))
+ {
+ pos[I][0]=P;
+ pos[I][1]=(P+1)%5;
+ pos[I][2]=(P+2)%5;
+ pos[I][3]=(P+3)%5;
+ pos[I][4]=(P+4)%5;
+ }
+ pinit=true;
+ }
+ UINT32 s[5];
+ for (int I=0;I<sizeof(s)/sizeof(s[0]);I++)
+ s[I]=state[I];
+
+ for (int I=0;I<16;I++)
+ R0(s[pos[I][0]],s[pos[I][1]],s[pos[I][2]],s[pos[I][3]],s[pos[I][4]],I);
+ for (int I=16;I<20;I++)
+ R1(s[pos[I][0]],s[pos[I][1]],s[pos[I][2]],s[pos[I][3]],s[pos[I][4]],I);
+ for (int I=20;I<40;I++)
+ R2(s[pos[I][0]],s[pos[I][1]],s[pos[I][2]],s[pos[I][3]],s[pos[I][4]],I);
+ for (int I=40;I<60;I++)
+ R3(s[pos[I][0]],s[pos[I][1]],s[pos[I][2]],s[pos[I][3]],s[pos[I][4]],I);
+ for (int I=60;I<80;I++)
+ R4(s[pos[I][0]],s[pos[I][1]],s[pos[I][2]],s[pos[I][3]],s[pos[I][4]],I);
+
+ for (int I=0;I<sizeof(s)/sizeof(s[0]);I++)
+ state[I]+=s[I];
+#else
+ /* Copy context->state[] to working vars */
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+ /* 4 rounds of 20 operations each. Loop unrolled. */
+ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+ /* Add the working vars back into context.state[] */
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+
+ /* Wipe variables */
+ a = b = c = d = e = 0;
+ memset(&a,0,sizeof(a));
+#endif
+}
+
+
+/* Initialize new context */
+
+void hash_initial(hash_context* context)
+{
+ /* SHA1 initialization constants */
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xEFCDAB89;
+ context->state[2] = 0x98BADCFE;
+ context->state[3] = 0x10325476;
+ context->state[4] = 0xC3D2E1F0;
+ context->count[0] = context->count[1] = 0;
+}
+
+
+/* Run your data through this. */
+void hash_process( hash_context * context, unsigned char * data, unsigned len )
+{
+ unsigned int i, j;
+ UINT32 blen = ((UINT32)len)<<3;
+
+ j = (context->count[0] >> 3) & 63;
+ if ((context->count[0] += blen) < blen ) context->count[1]++;
+ context->count[1] += (len >> 29);
+ if ((j + len) > 63) {
+ memcpy(&context->buffer[j], data, (i = 64-j));
+ SHA1Transform(context->state, context->buffer);
+ for ( ; i + 63 < len; i += 64) {
+ SHA1Transform(context->state, &data[i]);
+ }
+ j = 0;
+ }
+ else i = 0;
+ if (len > i)
+ memcpy(&context->buffer[j], &data[i], len - i);
+}
+
+
+/* Add padding and return the message digest. */
+
+void hash_final( hash_context* context, UINT32 digest[5] )
+{
+ UINT32 i, j;
+ unsigned char finalcount[8];
+
+ for (i = 0; i < 8; i++) {
+ finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
+ >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
+ }
+ unsigned char ch='\200';
+ hash_process(context, &ch, 1);
+ while ((context->count[0] & 504) != 448) {
+ ch=0;
+ hash_process(context, &ch, 1);
+ }
+ hash_process(context, finalcount, 8); /* Should cause a SHA1Transform() */
+ for (i = 0; i < 5; i++) {
+ digest[i] = context->state[i] & 0xffffffff;
+ }
+ /* Wipe variables */
+ memset(&i,0,sizeof(i));
+ memset(&j,0,sizeof(j));
+ memset(context->buffer, 0, 64);
+ memset(context->state, 0, 20);
+ memset(context->count, 0, 8);
+ memset(&finalcount, 0, 8);
+#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
+ SHA1Transform(context->state, context->buffer);
+#endif
+}
+
+
diff --git a/7zip/Crypto/RarAES/sha1.h b/7zip/Crypto/RarAES/sha1.h
new file mode 100755
index 00000000..1177bb5c
--- /dev/null
+++ b/7zip/Crypto/RarAES/sha1.h
@@ -0,0 +1,19 @@
+// sha1.h
+// This file from UnRar sources
+
+#ifndef _RAR_SHA1_
+#define _RAR_SHA1_
+
+#define HW 5
+
+typedef struct {
+ UINT32 state[5];
+ UINT32 count[2];
+ unsigned char buffer[64];
+} hash_context;
+
+void hash_initial( hash_context * c );
+void hash_process( hash_context * c, unsigned char * data, unsigned len );
+void hash_final( hash_context * c, UINT32[HW] );
+
+#endif
diff --git a/7zip/Crypto/Zip/StdAfx.h b/7zip/Crypto/Zip/StdAfx.h
new file mode 100755
index 00000000..a32fbed6
--- /dev/null
+++ b/7zip/Crypto/Zip/StdAfx.h
@@ -0,0 +1,8 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#endif
diff --git a/7zip/Crypto/Zip/ZipCipher.cpp b/7zip/Crypto/Zip/ZipCipher.cpp
new file mode 100755
index 00000000..50263267
--- /dev/null
+++ b/7zip/Crypto/Zip/ZipCipher.cpp
@@ -0,0 +1,118 @@
+// Crypto/ZipCipher.h
+
+#include "StdAfx.h"
+
+#include "ZipCipher.h"
+#include "Windows/Defs.h"
+
+namespace NCrypto {
+namespace NZip {
+
+const int kBufferSize = 1 << 17;
+
+CBuffer2::CBuffer2():
+ _buffer(0)
+{
+ _buffer = new BYTE[kBufferSize];
+}
+
+CBuffer2::~CBuffer2()
+{
+ delete []_buffer;
+}
+
+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::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ CRandom random;
+ random.Init(::GetTickCount());
+
+ UINT64 nowPos = 0;
+ BYTE header[kHeaderSize];
+ for (int i = 0; i < kHeaderSize - 2; i++)
+ {
+ header[i] = BYTE(random.Generate());
+ }
+ header[kHeaderSize - 1] = BYTE(_crc >> 24);
+ header[kHeaderSize - 2] = BYTE(_crc >> 16);
+
+ UINT32 processedSize;
+ _cipher.EncryptHeader(header);
+ RINOK(outStream->Write(header, kHeaderSize, &processedSize));
+ if (processedSize != kHeaderSize)
+ return E_FAIL;
+
+ while(true)
+ {
+ if (outSize != NULL && nowPos == *outSize)
+ return S_OK;
+ RINOK(inStream->Read(_buffer, kBufferSize, &processedSize));
+ if (processedSize == 0)
+ return S_OK;
+ for (UINT32 i = 0; i < processedSize; i++)
+ _buffer[i] = _cipher.EncryptByte(_buffer[i]);
+ UINT32 size = processedSize;
+ if (outSize != NULL && nowPos + size > *outSize)
+ size = UINT32(*outSize - nowPos);
+ RINOK(outStream->Write(_buffer, size, &processedSize));
+ if (size != processedSize)
+ return E_FAIL;
+ nowPos += processedSize;
+ }
+}
+
+STDMETHODIMP CDecoder::CryptoSetPassword(const BYTE *data, UINT32 size)
+{
+ _cipher.SetPassword(data, size);
+ return S_OK;
+}
+
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ UINT64 nowPos = 0;
+
+ if (inSize != NULL && *inSize == 0)
+ return S_OK;
+
+ BYTE header[kHeaderSize];
+ UINT32 processedSize;
+ RINOK(inStream->Read(header, kHeaderSize, &processedSize));
+ if (processedSize != kHeaderSize)
+ return E_FAIL;
+ _cipher.DecryptHeader(header);
+
+ while(true)
+ {
+ if (outSize != NULL && nowPos == *outSize)
+ return S_OK;
+ RINOK(inStream->Read(_buffer, kBufferSize, &processedSize));
+ if (processedSize == 0)
+ return S_OK;
+ for (UINT32 i = 0; i < processedSize; i++)
+ _buffer[i] = _cipher.DecryptByte(_buffer[i]);
+ UINT32 size = processedSize;
+ if (outSize != NULL && nowPos + size > *outSize)
+ size = UINT32(*outSize - nowPos);
+ RINOK(outStream->Write(_buffer, size, &processedSize));
+ if (size != processedSize)
+ return E_FAIL;
+ nowPos += processedSize;
+ }
+}
+
+}}
diff --git a/7zip/Crypto/Zip/ZipCipher.h b/7zip/Crypto/Zip/ZipCipher.h
new file mode 100755
index 00000000..95ba5167
--- /dev/null
+++ b/7zip/Crypto/Zip/ZipCipher.h
@@ -0,0 +1,72 @@
+// Crypto/ZipCipher.h
+
+#ifndef __CRYPTO_ZIPCIPHER_H
+#define __CRYPTO_ZIPCIPHER_H
+
+#include "Common/MyCom.h"
+#include "Common/Random.h"
+#include "Common/Types.h"
+
+#include "../../ICoder.h"
+#include "../../IPassword.h"
+
+#include "ZipCrypto.h"
+
+namespace NCrypto {
+namespace NZip {
+
+class CBuffer2
+{
+protected:
+ BYTE *_buffer;
+public:
+ CBuffer2();
+ ~CBuffer2();
+};
+
+class CEncoder :
+ public ICompressCoder,
+ public ICryptoSetPassword,
+ public ICryptoSetCRC,
+ public CMyUnknownImp,
+ public CBuffer2
+{
+ CCipher _cipher;
+ UINT32 _crc;
+public:
+ MY_UNKNOWN_IMP2(
+ ICryptoSetPassword,
+ ICryptoSetCRC
+ )
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress);
+
+ STDMETHOD(CryptoSetPassword)(const BYTE *data, UINT32 size);
+ STDMETHOD(CryptoSetCRC)(UINT32 crc);
+};
+
+
+class CDecoder:
+ public ICompressCoder,
+ public ICryptoSetPassword,
+ public CMyUnknownImp,
+ public CBuffer2
+{
+ CCipher _cipher;
+public:
+
+ MY_UNKNOWN_IMP1(ICryptoSetPassword)
+
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, UINT64 const *inSize,
+ const UINT64 *outSize,
+ ICompressProgressInfo *progress);
+
+ STDMETHOD(CryptoSetPassword)(const BYTE *data, UINT32 size);
+};
+
+}}
+
+#endif
diff --git a/7zip/Crypto/Zip/ZipCrypto.cpp b/7zip/Crypto/Zip/ZipCrypto.cpp
new file mode 100755
index 00000000..966cec78
--- /dev/null
+++ b/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 {
+
+inline UINT32 CRC32(UINT32 c, BYTE b)
+{
+ return CCRC::Table[(c ^ b) & 0xFF] ^ (c >> 8);
+}
+
+void CCipher::UpdateKeys(BYTE b)
+{
+ Keys[0] = CRC32(Keys[0], b);
+ Keys[1] += Keys[0] & 0xff;
+ Keys[1] = Keys[1] * 134775813L + 1;
+ Keys[2] = CRC32(Keys[2], 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 (temp * (temp ^ 1)) >> 8;
+}
+
+BYTE CCipher::DecryptByte(BYTE encryptedByte)
+{
+ BYTE c = encryptedByte ^ DecryptByteSpec();
+ UpdateKeys(c);
+ return c;
+}
+
+BYTE CCipher::EncryptByte(BYTE b)
+{
+ BYTE c = 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/7zip/Crypto/Zip/ZipCrypto.h b/7zip/Crypto/Zip/ZipCrypto.h
new file mode 100755
index 00000000..051a2556
--- /dev/null
+++ b/7zip/Crypto/Zip/ZipCrypto.h
@@ -0,0 +1,28 @@
+// Crypto/ZipCrypto.h
+
+#pragma once
+
+#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/7zip/FileManager/7zFM.exe.manifest b/7zip/FileManager/7zFM.exe.manifest
new file mode 100755
index 00000000..7b2c3378
--- /dev/null
+++ b/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="X86" 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="X86" publicKeyToken="6595b64144ccf1df" language="*"/></dependentAssembly></dependency></assembly>
diff --git a/7zip/FileManager/7zipLogo.ico b/7zip/FileManager/7zipLogo.ico
new file mode 100755
index 00000000..973241c8
--- /dev/null
+++ b/7zip/FileManager/7zipLogo.ico
Binary files differ
diff --git a/7zip/FileManager/Add.bmp b/7zip/FileManager/Add.bmp
new file mode 100755
index 00000000..a8577fc7
--- /dev/null
+++ b/7zip/FileManager/Add.bmp
Binary files differ
diff --git a/7zip/FileManager/Add2.bmp b/7zip/FileManager/Add2.bmp
new file mode 100755
index 00000000..252fc253
--- /dev/null
+++ b/7zip/FileManager/Add2.bmp
Binary files differ
diff --git a/7zip/FileManager/App.cpp b/7zip/FileManager/App.cpp
new file mode 100755
index 00000000..90e7f6a3
--- /dev/null
+++ b/7zip/FileManager/App.cpp
@@ -0,0 +1,786 @@
+// 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 "UpdateCallback100.h"
+#include "ViewSettings.h"
+#include "RegistryUtils.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NFind;
+
+extern DWORD g_ComCtl32Version;
+extern HINSTANCE g_hInstance;
+
+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(UStringVector &externalNames, bool move, bool copyToSame)
+ { _app->OnCopy(externalNames, move, copyToSame, _index); }
+
+void CPanelCallbackImp::OnSetSameFolder()
+ { _app->OnSetSameFolder(_index); }
+
+void CPanelCallbackImp::OnSetSubFolder()
+ { _app->OnSetSubFolder(_index); }
+
+void CPanelCallbackImp::PanelWasFocused()
+{
+ _app->LastFocusedPanel = _index;
+}
+
+void CApp::SetListSettings()
+{
+ bool showDots = ReadShowDots();
+ bool showRealFileIcons = ReadShowRealFileIcons();
+ for (int i = 0; i < kNumPanelsMax; i++)
+ {
+ Panels[i]._showDots = showDots;
+ Panels[i]._showRealFileIcons = showRealFileIcons;
+ }
+}
+
+void CApp::SetShowSystemMenu()
+{
+ ShowSystemMenu = ReadShowSystemMenu();
+}
+
+void CApp::CreateOnePanel(int panelIndex, const UString &mainPath)
+{
+ if (PanelsCreated[panelIndex])
+ return;
+ m_PanelCallbackImp[panelIndex].Init(this, panelIndex);
+ UString path;
+ if (mainPath.IsEmpty())
+ {
+ CSysString sysPath;
+ if (!::ReadPanelPath(panelIndex, sysPath))
+ sysPath.Empty();
+ path = GetUnicodeString(sysPath);
+ }
+ else
+ path = mainPath;
+ int id = 1000 + 100 * panelIndex;
+ Panels[panelIndex].Create(_window, _window,
+ id, 0, path, &m_PanelCallbackImp[panelIndex], &AppState);
+ 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;
+ CSysString GetText()const
+ { return LangLoadString(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, CSysString &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, CSysString &s)
+{
+ if (SetButtonText(commandID, g_StandardButtons, sizeof(g_StandardButtons) /
+ sizeof(g_StandardButtons[0]), s))
+ return;
+ SetButtonText(commandID, g_ArchiveButtons, sizeof(g_StandardButtons) /
+ 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;
+
+ CSysString s = butInfo.GetText();
+ but.iString = 0;
+ if (showText)
+ but.iString = (INT_PTR )(LPCTSTR)s;
+
+ but.iBitmap = imageList.GetImageCount();
+ HBITMAP b = ::LoadBitmap(g_hInstance,
+ large ?
+ (LPCTSTR)butInfo.BitmapResID:
+ (LPCTSTR)butInfo.Bitmap2ResID);
+ if (b != 0)
+ {
+ imageList.AddMasked(b, RGB(255, 0, 255));
+ ::DeleteObject(b);
+ }
+ toolBar.AddButton(1, &but);
+}
+
+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)
+{
+ ReadToolbar();
+ ReloadRebar(hwnd);
+
+ for (int i = 0; i < kNumPanelsMax; i++)
+ PanelsCreated[i] = false;
+
+ _window.Attach(hwnd);
+ AppState.Read();
+ SetListSettings();
+ SetShowSystemMenu();
+ UString mainPathSpec = mainPath;
+ if (LastFocusedPanel >= kNumPanelsMax)
+ LastFocusedPanel = 0;
+ for (i = 0; i < kNumPanelsMax; i++)
+ if (NumPanels > 1 || i == LastFocusedPanel)
+ CreateOnePanel(i, (i == LastFocusedPanel) ? mainPath : L"");
+ Panels[LastFocusedPanel].SetFocusToList();
+}
+
+extern void MoveSubWindows(HWND hWnd);
+
+void CApp::SwitchOnOffOnePanel()
+{
+ if (NumPanels == 1)
+ {
+ NumPanels++;
+ CreateOnePanel(1 - LastFocusedPanel, UString());
+ 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();
+ 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, GetSystemString(path));
+ }
+}
+
+void CApp::Release()
+{
+ // It's for unloading COM dll's: don't change it.
+ for (int i = 0; i < kNumPanelsMax; i++)
+ Panels[i].Release();
+}
+
+class CWindowDisable
+{
+ bool _wasEnabled;
+ CWindow _window;
+public:
+ CWindowDisable(HWND window): _window(window)
+ {
+ _wasEnabled = _window.IsEnabled();
+ if (_wasEnabled)
+ _window.Enable(false);
+ }
+ ~CWindowDisable()
+ {
+ if (_wasEnabled)
+ _window.Enable(true);
+ }
+};
+
+struct CThreadExtract
+{
+ bool Move;
+ CMyComPtr<IFolderOperations> FolderOperations;
+ CRecordVector<UINT32> Indices;
+ UString DestPath;
+ CExtractCallbackImp *ExtractCallbackSpec;
+ CMyComPtr<IFolderOperationsExtractCallback> ExtractCallback;
+ HRESULT Result;
+
+ DWORD Extract()
+ {
+ NCOM::CComInitializer comInitializer;
+ ExtractCallbackSpec->ProgressDialog.WaitCreating();
+ if (Move)
+ {
+ Result = FolderOperations->MoveTo(
+ &Indices.Front(), Indices.Size(),
+ DestPath, ExtractCallback);
+ // ExtractCallbackSpec->DestroyWindows();
+ }
+ else
+ {
+ Result = FolderOperations->CopyTo(
+ &Indices.Front(), Indices.Size(),
+ DestPath, ExtractCallback);
+ // ExtractCallbackSpec->DestroyWindows();
+ }
+ ExtractCallbackSpec->ProgressDialog.MyClose();
+ return 0;
+ }
+
+ static DWORD WINAPI MyThreadFunction(void *param)
+ {
+ return ((CThreadExtract *)param)->Extract();
+ }
+};
+
+struct CThreadUpdate
+{
+ bool Move;
+ CMyComPtr<IFolderOperations> FolderOperations;
+ UString SrcFolderPrefix;
+ UStringVector FileNames;
+ CRecordVector<const wchar_t *> FileNamePointers;
+ CMyComPtr<IFolderArchiveUpdateCallback> UpdateCallback;
+ CUpdateCallback100Imp *UpdateCallbackSpec;
+ HRESULT Result;
+
+ DWORD Process()
+ {
+ NCOM::CComInitializer comInitializer;
+ UpdateCallbackSpec->ProgressDialog.WaitCreating();
+ if (Move)
+ {
+ {
+ throw 1;
+ // srcPanel.MessageBoxMyError(L"Move is not supported");
+ return 0;
+ }
+ }
+ else
+ {
+ Result = FolderOperations->CopyFrom(
+ SrcFolderPrefix,
+ &FileNamePointers.Front(),
+ FileNamePointers.Size(),
+ UpdateCallback);
+ }
+ UpdateCallbackSpec->ProgressDialog.MyClose();
+ return 0;
+ }
+
+ static DWORD WINAPI MyThreadFunction(void *param)
+ {
+ return ((CThreadUpdate *)param)->Process();
+ }
+};
+
+
+
+void CApp::OnCopy(UStringVector &externalNames, bool move, bool copyToSame, int srcPanelIndex)
+{
+ bool external = (externalNames.Size() > 0);
+ if (external)
+ copyToSame = true;
+
+ int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex);
+ CPanel &srcPanel = Panels[srcPanelIndex];
+ CPanel &destPanel = Panels[destPanelIndex];
+ bool useSrcPanel = true;
+ if (!external)
+ if (NumPanels != 1)
+ {
+ if (!srcPanel.IsFSFolder() && !destPanel.IsFSFolder())
+ {
+ srcPanel.MessageBox(LangLoadStringW(IDS_CANNOT_COPY, 0x03020207));
+ return;
+ }
+ useSrcPanel = copyToSame || destPanel.IsFSFolder();
+ if (move && !useSrcPanel)
+ {
+ srcPanel.MessageBoxMyError(L"Move is not supported");
+ return;
+ }
+ }
+
+ CPanel &panel = useSrcPanel ? srcPanel : destPanel;
+
+ CMyComPtr<IFolderOperations> folderOperations;
+
+ // if (move)
+ if (panel._folder.QueryInterface(IID_IFolderOperations,
+ &folderOperations) != S_OK)
+ {
+ panel.MessageBox(LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
+ return;
+ }
+
+ CRecordVector<UINT32> indices;
+ UString destPath;
+
+ if (external)
+ {
+ UString message = L"Are you sure you want to copy files to archive \'";
+ message += srcPanel._currentFolderPrefix;
+ message += L"\'?";
+ int res = MessageBoxW(_window, message, L"Confirm File Copy",
+ MB_YESNOCANCEL | MB_ICONQUESTION | MB_TASKMODAL);
+ if (res != IDYES)
+ return;
+ }
+ else
+ {
+ CCopyDialog copyDialog;
+
+ UStringVector copyFolders;
+ ReadCopyHistory(copyFolders);
+
+ int i;
+ for (i = 0; i < copyFolders.Size(); i++)
+ copyDialog.Strings.Add(GetSystemString(copyFolders[i]));
+
+ if (copyToSame)
+ {
+ int focusedItem = srcPanel._listView.GetFocusedItem();
+ if (focusedItem < 0)
+ return;
+ int realIndex = srcPanel.GetRealItemIndex(focusedItem);
+ if (realIndex == -1)
+ return;
+ indices.Add(realIndex);
+ copyDialog.Value = srcPanel.GetItemName(realIndex);
+ }
+ else
+ {
+ srcPanel.GetOperatedItemIndices(indices);
+ if (indices.Size() == 0)
+ return;
+ UString destPath = destPanel._currentFolderPrefix;
+ if (NumPanels == 1)
+ {
+ while(!destPath.IsEmpty())
+ {
+ CFileInfoW fileInfo;
+ if (FindFile(destPath, fileInfo))
+ {
+ if (fileInfo.IsDirectory())
+ {
+ destPath += TEXT('\\');
+ break;
+ }
+ }
+ int pos = destPath.ReverseFind('\\');
+ if (pos < 0)
+ destPath.Empty();
+ else
+ destPath = destPath.Left(pos);
+ }
+ }
+ copyDialog.Value = destPath;
+ }
+ copyDialog.Title = move ?
+ LangLoadStringW(IDS_MOVE, 0x03020202):
+ LangLoadStringW(IDS_COPY, 0x03020201);
+ copyDialog.Static = move ?
+ LangLoadStringW(IDS_MOVE_TO, 0x03020204):
+ LangLoadStringW(IDS_COPY_TO, 0x03020203);
+ if (copyDialog.Create(srcPanel.GetParent()) == IDCANCEL)
+ return;
+
+ AddUniqueStringToHeadOfList(copyFolders, GetUnicodeString(
+ copyDialog.Value));
+ while (copyFolders.Size() > 20)
+ copyFolders.DeleteBack();
+
+ SaveCopyHistory(copyFolders);
+
+ /// ?????
+ SetCurrentDirectory(GetSystemString(srcPanel._currentFolderPrefix));
+
+ if (!NDirectory::MyGetFullPathName(copyDialog.Value, destPath))
+ {
+ srcPanel.MessageBoxLastError();
+ return;
+ }
+
+ if (destPath.Length() > 0 && destPath.ReverseFind('\\') == destPath.Length() - 1)
+ NDirectory::CreateComplexDirectory(destPath);
+ }
+
+ UString title = move ?
+ LangLoadStringW(IDS_MOVING, 0x03020206):
+ LangLoadStringW(IDS_COPYING, 0x03020205);
+ UString progressWindowTitle = LangLoadStringW(IDS_APP_TITLE, 0x03000000);
+
+ CPanel::CDisableTimerProcessing disableTimerProcessing1(destPanel);
+ CPanel::CDisableTimerProcessing disableTimerProcessing2(srcPanel);
+
+ HRESULT result;
+ if (useSrcPanel && !external)
+ {
+ CThreadExtract extracter;
+ extracter.ExtractCallbackSpec = new CExtractCallbackImp;
+ extracter.ExtractCallback = extracter.ExtractCallbackSpec;
+ extracter.ExtractCallbackSpec->_parentWindow = _window;
+
+ extracter.ExtractCallbackSpec->ProgressDialog.MainWindow = _window;
+ extracter.ExtractCallbackSpec->ProgressDialog.MainTitle = progressWindowTitle;
+ extracter.ExtractCallbackSpec->ProgressDialog.MainAddTitle = title + L" ";
+
+ extracter.ExtractCallbackSpec->Init(NExtractionMode::NOverwrite::kAskBefore, false, L"");
+ extracter.Move = move;
+ extracter.FolderOperations = folderOperations;
+ extracter.Indices = indices;;
+ extracter.DestPath = GetUnicodeString(destPath);
+ CThread thread;
+ if (!thread.Create(CThreadExtract::MyThreadFunction, &extracter))
+ throw 271824;
+ extracter.ExtractCallbackSpec->StartProgressDialog(title);
+ result = extracter.Result;
+ }
+ else
+ {
+ CThreadUpdate updater;
+ updater.UpdateCallbackSpec = new CUpdateCallback100Imp;
+ updater.UpdateCallback = updater.UpdateCallbackSpec;
+
+ updater.UpdateCallbackSpec->ProgressDialog.MainWindow = _window;
+ updater.UpdateCallbackSpec->ProgressDialog.MainTitle = progressWindowTitle;
+ updater.UpdateCallbackSpec->ProgressDialog.MainAddTitle = title + UString(L" ");
+
+ updater.UpdateCallbackSpec->Init(_window, false, L"");
+ updater.Move = move;
+ updater.FolderOperations = folderOperations;
+ if (external)
+ {
+ updater.FileNames.Reserve(externalNames.Size());
+ for(int i = 0; i < externalNames.Size(); i++)
+ updater.FileNames.Add(externalNames[i]);
+ }
+ else
+ {
+ updater.SrcFolderPrefix = srcPanel._currentFolderPrefix;
+ updater.FileNames.Reserve(indices.Size());
+ for(int i = 0; i < indices.Size(); i++)
+ updater.FileNames.Add(srcPanel.GetItemName(indices[i]));
+ }
+ updater.FileNamePointers.Reserve(updater.FileNames.Size());
+ int i;
+ 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);
+ result = updater.Result;
+ }
+
+ /*
+ if (useSrcPanel)
+ extractCallbackSpec->DestroyWindows();
+ */
+
+ 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.RefreshListCtrlSaveFocused();
+ }
+ if (!copyToSame)
+ {
+ destPanel.RefreshListCtrlSaveFocused();
+ 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 == -1)
+ {
+ if (srcPanel._folder->BindToParentFolder(&newFolder) != S_OK)
+ return;
+ }
+ else
+ {
+ if (srcPanel._folder->BindToFolder(realIndex, &newFolder) != S_OK)
+ return;
+ }
+ destPanel._folder = newFolder;
+ destPanel.RefreshListCtrl();
+}
+
+int CApp::GetFocusedPanelIndex()
+{
+ return LastFocusedPanel;
+ /*
+ HWND hwnd = ::GetFocus();
+ while(true)
+ {
+ 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 CSysString g_ToolTipBuffer;
+
+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(info->hdr.idFrom, g_ToolTipBuffer);
+ info->lpszText = (LPTSTR)(LPCTSTR)g_ToolTipBuffer;
+ return;
+ }
+ }
+}
diff --git a/7zip/FileManager/App.h b/7zip/FileManager/App.h
new file mode 100755
index 00000000..374e8dc5
--- /dev/null
+++ b/7zip/FileManager/App.h
@@ -0,0 +1,239 @@
+// App.h
+
+#pragma once
+
+#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(UStringVector &externalNames, bool move, bool copyToSame);
+ virtual void OnSetSameFolder();
+ virtual void OnSetSubFolder();
+ virtual void PanelWasFocused();
+};
+
+class CApp
+{
+ NWindows::CWindow _window;
+public:
+ 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;
+
+ void OnCopy(UStringVector &externalNames,
+ bool move, bool copyToSame, int srcPanelIndex);
+ void OnSetSameFolder(int srcPanelIndex);
+ void OnSetSubFolder(int srcPanelIndex);
+
+ void CreateOnePanel(int panelIndex, const UString &mainPath);
+ void Create(HWND hwnd, const UString &mainPath);
+ void Read();
+ void Save();
+ void Release();
+
+
+ /*
+ void SetFocus(int panelIndex)
+ { Panels[panelIndex].SetFocusToList(); }
+ */
+ void SetFocusToLastItem()
+ { Panels[LastFocusedPanel].SetFocusToLastRememberedItem(); }
+
+ int GetFocusedPanelIndex();
+ /*
+ 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(UStringVector(), false, false, GetFocusedPanelIndex()); }
+ void MoveTo()
+ { OnCopy(UStringVector(), true, false, GetFocusedPanelIndex()); }
+ void Delete()
+ { GetFocusedPanel().DeleteItems(); }
+ 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();
+
+ 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 ExtractArchive()
+ { GetFocusedPanel().ExtractArchive(); }
+ void TestArchive()
+ { GetFocusedPanel().TestArchive(); }
+
+ void OnNotify(int ctrlID, LPNMHDR pnmh);
+};
+
+#endif
diff --git a/7zip/FileManager/AppState.h b/7zip/FileManager/AppState.h
new file mode 100755
index 00000000..49739f6e
--- /dev/null
+++ b/7zip/FileManager/AppState.h
@@ -0,0 +1,116 @@
+// AppState.h
+
+#pragma once
+
+#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.CollateNoCase(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/7zip/FileManager/ClassDefs.cpp b/7zip/FileManager/ClassDefs.cpp
new file mode 100755
index 00000000..d48932ef
--- /dev/null
+++ b/7zip/FileManager/ClassDefs.cpp
@@ -0,0 +1,29 @@
+// ClassDefs.cpp
+
+#include "StdAfx.h"
+
+// #define INITGUID
+#include <initguid.h>
+
+#include "IFolder.h"
+#include "../IPassword.h"
+// #include "../Archiver/Format/Common/ArchiveInterface.h"
+#include "PluginInterface.h"
+#include "ExtractCallback.h"
+#include "../ICoder.h"
+
+/*
+// {23170F69-40C1-278A-1000-000100030000}
+DEFINE_GUID(CLSID_CAgentArchiveHandler,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00);
+*/
+
+// {23170F69-40C1-278A-1000-000100020000}
+DEFINE_GUID(CLSID_CZipContextMenu,
+0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00);
+
+/*
+// {23170F69-40C1-278F-1000-000110050000}
+DEFINE_GUID(CLSID_CTest,
+ 0x23170F69, 0x40C1, 0x278F, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 0x00, 0x00);
+*/
diff --git a/7zip/FileManager/Copy.bmp b/7zip/FileManager/Copy.bmp
new file mode 100755
index 00000000..0f28a324
--- /dev/null
+++ b/7zip/FileManager/Copy.bmp
Binary files differ
diff --git a/7zip/FileManager/Copy2.bmp b/7zip/FileManager/Copy2.bmp
new file mode 100755
index 00000000..ba88ded0
--- /dev/null
+++ b/7zip/FileManager/Copy2.bmp
Binary files differ
diff --git a/7zip/FileManager/Delete.bmp b/7zip/FileManager/Delete.bmp
new file mode 100755
index 00000000..d1004d82
--- /dev/null
+++ b/7zip/FileManager/Delete.bmp
Binary files differ
diff --git a/7zip/FileManager/Delete2.bmp b/7zip/FileManager/Delete2.bmp
new file mode 100755
index 00000000..60e08c6a
--- /dev/null
+++ b/7zip/FileManager/Delete2.bmp
Binary files differ
diff --git a/7zip/FileManager/Extract.bmp b/7zip/FileManager/Extract.bmp
new file mode 100755
index 00000000..0aeba923
--- /dev/null
+++ b/7zip/FileManager/Extract.bmp
Binary files differ
diff --git a/7zip/FileManager/Extract2.bmp b/7zip/FileManager/Extract2.bmp
new file mode 100755
index 00000000..a7e57753
--- /dev/null
+++ b/7zip/FileManager/Extract2.bmp
Binary files differ
diff --git a/7zip/FileManager/ExtractCallback.cpp b/7zip/FileManager/ExtractCallback.cpp
new file mode 100755
index 00000000..8fabd7c7
--- /dev/null
+++ b/7zip/FileManager/ExtractCallback.cpp
@@ -0,0 +1,312 @@
+// ExtractCallback.h
+
+#include "StdAfx.h"
+
+#include "ExtractCallback.h"
+
+#include "Windows/FileFind.h"
+#include "Windows/FileDir.h"
+
+#include "Resource/OverwriteDialog/OverwriteDialog.h"
+#include "Resource/PasswordDialog/PasswordDialog.h"
+#include "Resource/MessagesDialog/MessagesDialog.h"
+#include "../UI/Resource/Extract/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 (!_messages.IsEmpty())
+ {
+ CMessagesDialog messagesDialog;
+ messagesDialog._messages = &_messages;
+ messagesDialog.Create(_parentWindow);
+ }
+}
+
+void CExtractCallbackImp::Init(
+ NExtractionMode::NOverwrite::EEnum overwriteMode,
+ bool passwordIsDefined,
+ const UString &password)
+{
+ _overwriteMode = overwriteMode;
+ _passwordIsDefined = passwordIsDefined;
+ _password = password;
+ _messages.Clear();
+}
+
+void CExtractCallbackImp::AddErrorMessage(LPCTSTR message)
+{
+ _messages.Add(message);
+}
+
+STDMETHODIMP CExtractCallbackImp::SetTotal(UINT64 total)
+{
+ ProgressDialog.ProgressSynch.SetProgress(total, 0);
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::SetCompleted(const UINT64 *completeValue)
+{
+ while(true)
+ {
+ 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;
+ if (dialog.OldFileInfo.SizeIsDefined = (existSize != NULL))
+ dialog.OldFileInfo.Size = *existSize;
+ dialog.OldFileInfo.Name = existName;
+
+ if (newTime == 0)
+ dialog.NewFileInfo.TimeIsDefined = false;
+ else
+ {
+ dialog.NewFileInfo.TimeIsDefined = true;
+ dialog.NewFileInfo.Time = *newTime;
+ }
+
+ if (dialog.NewFileInfo.SizeIsDefined = (newSize != NULL))
+ dialog.NewFileInfo.Size = *newSize;
+ dialog.NewFileInfo.Name = newName;
+
+ /*
+ NOverwriteDialog::NResult::EEnum writeAnswer =
+ NOverwriteDialog::Execute(oldFileInfo, newFileInfo);
+ */
+ int 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)
+{
+ _currentFilePath = name;
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::MessageError(const wchar_t *message)
+{
+ AddErrorMessage(GetSystemString(message));
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::ShowMessage(const wchar_t *message)
+{
+ AddErrorMessage(GetSystemString(message));
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::SetOperationResult(INT32 operationResult)
+{
+ 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 = IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_DATA_ERROR;
+ langID = 0x02000A92;
+ break;
+ case NArchive::NExtract::NOperationResult::kCRCError:
+ messageID = IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CRC;
+ langID = 0x02000A93;
+ break;
+ default:
+ return E_FAIL;
+ }
+ AddErrorMessage(
+ GetSystemString(MyFormatNew(messageID,
+ #ifdef LANG
+ langID,
+ #endif
+ _currentFilePath)));
+ }
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::CryptoGetTextPassword(BSTR *password)
+{
+ if (!_passwordIsDefined)
+ {
+ CPasswordDialog dialog;
+
+ if (dialog.Create(_parentWindow) == IDCANCEL)
+ return E_ABORT;
+
+ _password = GetUnicodeString((LPCTSTR)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 NExtractionMode::NOverwrite::kSkipExisting:
+ return S_OK;
+ case NExtractionMode::NOverwrite::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 = NExtractionMode::NOverwrite::kSkipExisting;
+ return S_OK;
+ case NOverwriteAnswer::kYesToAll:
+ _overwriteMode = NExtractionMode::NOverwrite::kWithoutPrompt;
+ break;
+ case NOverwriteAnswer::kYes:
+ break;
+ case NOverwriteAnswer::kAutoRename:
+ _overwriteMode = NExtractionMode::NOverwrite::kAutoRename;
+ break;
+ default:
+ throw 20413;
+ }
+ }
+ }
+ if (_overwriteMode == NExtractionMode::NOverwrite::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/7zip/FileManager/ExtractCallback.h b/7zip/FileManager/ExtractCallback.h
new file mode 100755
index 00000000..2ac07fa8
--- /dev/null
+++ b/7zip/FileManager/ExtractCallback.h
@@ -0,0 +1,96 @@
+// ExtractCallback.h
+
+#pragma once
+
+#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
+
+#include "../IPassword.h"
+#include "Common/MyCom.h"
+#include "IFolder.h"
+
+class CExtractCallbackImp:
+ public IFolderArchiveExtractCallback,
+ public IFolderOperationsExtractCallback,
+ public ICryptoGetTextPassword,
+ 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);
+
+ STDMETHOD(MessageError)(const wchar_t *message);
+ STDMETHOD(SetOperationResult)(INT32 operationResult);
+
+ // 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);
+
+ // ICryptoGetTextPassword
+ STDMETHOD(CryptoGetTextPassword)(BSTR *password);
+
+private:
+ // CSysString _directoryPath;
+ // CSysString m_DiskFilePath;
+ // bool _extractMode;
+
+ UString _currentFilePath;
+ NExtractionMode::NOverwrite::EEnum _overwriteMode;
+
+ bool _passwordIsDefined;
+ UString _password;
+
+ // void CreateComplexDirectory(const UStringVector &aDirPathParts);
+
+ void AddErrorMessage(LPCTSTR message);
+public:
+ CProgressDialog ProgressDialog;
+ CSysStringVector _messages;
+ HWND _parentWindow;
+ INT_PTR StartProgressDialog(const UString &title)
+ {
+ return ProgressDialog.Create(title, _parentWindow);
+ }
+
+ ~CExtractCallbackImp();
+ void Init(NExtractionMode::NOverwrite::EEnum overwriteMode,
+ bool passwordIsDefined, const UString &password);
+};
+
+#endif
diff --git a/7zip/FileManager/FM.cpp b/7zip/FileManager/FM.cpp
new file mode 100755
index 00000000..5cfeb784
--- /dev/null
+++ b/7zip/FileManager/FM.cpp
@@ -0,0 +1,616 @@
+// FAM.cpp
+
+#include "stdafx.h"
+
+#include "resource.h"
+#include "Panel.h"
+
+#include "Common/Defs.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/Control/Toolbar.h"
+#include "Windows/Error.h"
+#include "Windows/COM.h"
+
+#include "ViewSettings.h"
+
+#include "App.h"
+#include "StringUtils.h"
+
+#include "MyLoadMenu.h"
+#include "LangUtils.h"
+
+using namespace NWindows;
+
+// NWindows::NCOM::CComInitializer aComInitializer;
+
+#define MAX_LOADSTRING 100
+
+#define MENU_HEIGHT 26
+
+HINSTANCE g_hInstance;
+HWND g_HWND;
+
+
+static UString g_MainPath;
+
+const int kNumDefaultPanels = 1;
+
+const int kSplitterWidth = 4;
+int kSplitterRateMax = 1 << 16;
+
+// bool OnMenuCommand(HWND hWnd, int id);
+
+static CSysString GetProgramPath()
+{
+ TCHAR fullPath[MAX_PATH + 1];
+ ::GetModuleFileName(g_hInstance, fullPath, MAX_PATH);
+ return fullPath;
+}
+
+CSysString GetProgramFolderPrefix()
+{
+ CSysString path = GetProgramPath();
+ int pos = path.ReverseFind(TEXT('\\'));
+ 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;
+int g_SplitterPos = 0;
+CSplitterPos g_Splitter;
+
+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);
+
+// FUNCTION: InitInstance(HANDLE, int)
+BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
+{
+ HWND hWnd = NULL;
+ TCHAR windowClass[MAX_LOADSTRING]; // The window class name
+ lstrcpy(windowClass, TEXT("FM"));
+
+ g_hInstance = hInstance; // Store instance handle in our global variable
+
+ // LoadString(hInstance, IDS_CLASS, windowClass, MAX_LOADSTRING);
+
+ // LoadString(hInstance, IDS_APP_TITLE, title, MAX_LOADSTRING);
+ UString title = LangLoadStringW(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;
+ }
+ */
+
+ WNDCLASS 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 = MAKEINTRESOURCE(IDM_MENU);
+ wc.lpszClassName = windowClass;
+
+ RegisterClass(&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;
+ UINT32 splitterPos;
+ bool panelsInfoDefined = ReadPanelsInfo(numPanels, currentPanel, splitterPos);
+ if (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;
+
+ hWnd = CreateWindow(windowClass, GetSystemString(title), style,
+ x, y, xSize, ySize, NULL, NULL, hInstance, NULL);
+ if (!hWnd)
+ return FALSE;
+ g_HWND = hWnd;
+
+ if (panelsInfoDefined)
+ {
+ g_SplitterPos = splitterPos;
+ g_Splitter.SetPos(hWnd, splitterPos);
+ }
+ else
+ {
+ g_Splitter.SetRatio(hWnd, kSplitterRateMax / 2);
+ g_SplitterPos = g_Splitter.GetPos();
+ }
+
+ CWindow window(hWnd);
+
+ WINDOWPLACEMENT placement;
+ placement.length = sizeof(placement);
+ if (window.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;
+ window.SetPlacement(&placement);
+ // window.Show(nCmdShow);
+ }
+ else
+ window.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;
+
+int WINAPI WinMain( HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine,
+ int nCmdShow)
+{
+ InitCommonControls();
+
+ g_ComCtl32Version = ::GetDllVersion(TEXT("comctl32.dll"));
+
+ 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);
+ }
+
+
+ MSG msg;
+ if (!InitInstance (hInstance, nCmdShow))
+ return FALSE;
+
+ MyLoadMenu(g_HWND);
+
+ HACCEL hAccels = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1));
+ while (GetMessage(&msg, NULL, 0, 0))
+ {
+ if (!TranslateAccelerator(g_HWND, hAccels, &msg))
+ {
+ // if (g_Hwnd != NULL || !IsDialogMessage(g_Hwnd, &msg))
+ // if (!IsDialogMessage(g_Hwnd, &msg))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+ }
+
+ g_HWND = 0;
+ return 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.ExtractArchive();
+ break;
+ case kTestCommand:
+ g_App.TestArchive();
+ 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);
+
+ g_App.Create(hWnd, g_MainPath);
+ // g_SplitterPos = 0;
+
+ DragAcceptFiles(hWnd, TRUE);
+ break;
+ }
+ case WM_DESTROY:
+ {
+ ::DragAcceptFiles(hWnd, FALSE);
+ 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(wParam, (LPNMHDR)lParam);
+ break;
+ }
+ case WM_DROPFILES:
+ {
+ g_App.GetFocusedPanel().CompressDropFiles((HDROP)wParam);
+ return 0 ;
+ }
+ }
+ 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/7zip/FileManager/FM.dsp b/7zip/FileManager/FM.dsp
new file mode 100755
index 00000000..2cd69412
--- /dev/null
+++ b/7zip/FileManager/FM.dsp
@@ -0,0 +1,1179 @@
+# 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" /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 /W3 /Gm /GX /ZI /Od /I "..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "LANG" /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 "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "LANG" /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 "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "LANG" /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=.\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=.\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=.\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
+# 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\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource\SettingsPage\resource.rc
+# PROP Exclude_From_Build 1
+# End Source File
+# 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
+# Begin Source File
+
+SOURCE=.\Resource\PasswordDialog\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource\PasswordDialog\resource.rc
+# PROP Exclude_From_Build 1
+# 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
+# Begin Source File
+
+SOURCE=.\Resource\ProgressDialog2\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource\ProgressDialog2\resource.rc
+# PROP Exclude_From_Build 1
+# 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
+# Begin Source File
+
+SOURCE=.\Resource\AboutDialog\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource\AboutDialog\resource.rc
+# PROP Exclude_From_Build 1
+# 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
+# Begin Source File
+
+SOURCE=.\Resource\BenchmarkDialog\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource\BenchmarkDialog\resource.rc
+# PROP Exclude_From_Build 1
+# 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\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\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\ItemIDListUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\ItemIDListUtils.h
+# 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\Shell.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Shell.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Synchronization.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\System.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\System.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\Thread.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Windows\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\Buffer.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 Source File
+
+SOURCE=.\7zFM.exe.manifest
+# 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=.\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=.\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/7zip/FileManager/FM.dsw b/7zip/FileManager/FM.dsw
new file mode 100755
index 00000000..1c955d95
--- /dev/null
+++ b/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/7zip/FileManager/FM.ico b/7zip/FileManager/FM.ico
new file mode 100755
index 00000000..3a0a34da
--- /dev/null
+++ b/7zip/FileManager/FM.ico
Binary files differ
diff --git a/7zip/FileManager/FSDrives.cpp b/7zip/FileManager/FSDrives.cpp
new file mode 100755
index 00000000..4804a331
--- /dev/null
+++ b/7zip/FileManager/FSDrives.cpp
@@ -0,0 +1,234 @@
+// 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 "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"
+};
+
+static inline UINT GetCurrentFileCodePage()
+ { return AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
+
+STDMETHODIMP CFSDrives::LoadItems()
+{
+ UINT fileCodePage = GetCurrentFileCodePage();
+ _drives.Clear();
+
+ CSysStringVector driveStrings;
+ MyGetLogicalDriveStrings(driveStrings);
+ for (int i = 0; i < driveStrings.Size(); i++)
+ {
+ CDriveInfo driveInfo;
+
+ const CSysString &driveName = driveStrings[i];
+
+ driveInfo.FullSystemName = GetUnicodeString(driveName, fileCodePage);
+
+ driveInfo.Name = driveInfo.FullSystemName.Left(
+ driveInfo.FullSystemName.Length() - 1);
+ driveInfo.ClusterSize = 0;
+ driveInfo.DriveSize = 0;
+ driveInfo.FreeSpace = 0;
+ UINT driveType = ::GetDriveType(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)
+ {
+ CSysString volumeName, fileSystemName;
+ DWORD volumeSerialNumber, maximumComponentLength, fileSystemFlags;
+ NFile::NSystem::MyGetVolumeInformation(driveName,
+ volumeName,
+ &volumeSerialNumber, &maximumComponentLength, &fileSystemFlags,
+ fileSystemName);
+ driveInfo.VolumeName = GetUnicodeString(volumeName, fileCodePage);
+ driveInfo.FileSystemName = GetUnicodeString(fileSystemName, fileCodePage);
+
+ 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;
+ return BindToFolderSpec(_drives[index].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 = (LangLoadStringW(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(GetSystemString(driveInfo.FullSystemName), 0, iconIndexTemp) != 0)
+ {
+ *iconIndex = iconIndexTemp;
+ return S_OK;
+ }
+ return GetLastError();
+}
+
diff --git a/7zip/FileManager/FSDrives.h b/7zip/FileManager/FSDrives.h
new file mode 100755
index 00000000..45c4ff88
--- /dev/null
+++ b/7zip/FileManager/FSDrives.h
@@ -0,0 +1,66 @@
+// FSDrives.h
+
+#pragma once
+
+#ifndef __FSDRIVES_H
+#define __FSDRIVES_H
+
+#include "Common/String.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;
+public:
+ void Init() {}
+};
+
+#endif
diff --git a/7zip/FileManager/FSFolder.cpp b/7zip/FileManager/FSFolder.cpp
new file mode 100755
index 00000000..c0c20745
--- /dev/null
+++ b/7zip/FileManager/FSFolder.cpp
@@ -0,0 +1,549 @@
+// 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"
+
+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}
+};
+
+static inline UINT GetCurrentFileCodePage()
+ { return AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
+
+HRESULT CFSFolder::Init(const UString &path, IFolderFolder *parentFolder)
+{
+ _parentFolder = parentFolder;
+ _path = path;
+ _fileCodePage = GetCurrentFileCodePage();
+
+ if (_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 */) == INVALID_HANDLE_VALUE)
+ {
+ DWORD lastError = GetLastError();
+ // return GetLastError();
+ CFindFile findFile;
+ CFileInfoW fileInfo;
+ if (!findFile.FindFirst(_path + UString(L"*"), fileInfo))
+ return lastError;
+ _findChangeNotificationDefined = false;
+ }
+ else
+ _findChangeNotificationDefined = true;
+
+ 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;
+}
+
+STDMETHODIMP CFSFolder::LoadItems()
+{
+ // OutputDebugString(TEXT("Start\n"));
+ INT32 dummy;
+ WasChanged(&dummy);
+ _files.Clear();
+ CEnumeratorW enumerator(_path + L"*");
+ CFileInfoEx 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;
+ }
+ _files.Add(fileInfo);
+ }
+ // OutputDebugString(TEXT("Finish\n"));
+ _commentsAreLoaded = false;
+ return S_OK;
+}
+
+bool CFSFolder::LoadComments()
+{
+ if (_commentsAreLoaded)
+ return true;
+ _comments.Clear();
+ _commentsAreLoaded = true;
+ CStdInStream file;
+ if (!file.Open(GetSystemString(_path + L"descript.ion", _fileCodePage)))
+ return false;
+ AString string;
+ file.ReadToString(string);
+ file.Close();
+ UString unicodeString;
+ if (!ConvertUTF8ToUnicode(string, 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()
+{
+ CStdOutStream file;
+ if (!file.Open(GetSystemString(_path + L"descript.ion", _fileCodePage)))
+ return false;
+ UString unicodeString;
+ _comments.SaveToString(unicodeString);
+ AString utfString;
+ ConvertUnicodeToUTF8(unicodeString, utfString);
+ if (!IsAscii(unicodeString))
+ {
+ file << char(0xEF) << char(0xBB) << char(0xBF) << char('\n');
+ }
+ file << utfString;
+ file.Close();
+ _commentsAreLoaded = false;
+ return true;
+}
+
+STDMETHODIMP CFSFolder::GetNumberOfItems(UINT32 *numItems)
+{
+ *numItems = _files.Size();
+ return S_OK;
+}
+
+/*
+STDMETHODIMP CFSFolder::GetNumberOfSubFolders(UINT32 *aNumSubFolders)
+{
+ UINT32 aNumSubFoldersLoc = 0;
+ for (int i = 0; i < _files.Size(); i++)
+ if (_files[i].IsDirectory())
+ aNumSubFoldersLoc++;
+ *aNumSubFolders = aNumSubFoldersLoc;
+ return S_OK;
+}
+*/
+
+STDMETHODIMP CFSFolder::GetProperty(UINT32 itemIndex, PROPID propID, PROPVARIANT *value)
+{
+ NCOM::CPropVariant propVariant;
+ if (itemIndex >= (UINT32)_files.Size())
+ return E_INVALIDARG;
+ CFileInfoEx &fileInfo = _files[itemIndex];
+ switch(propID)
+ {
+ case kpidIsFolder:
+ propVariant = fileInfo.IsDirectory();
+ break;
+ case kpidName:
+ propVariant = GetUnicodeString(fileInfo.Name);
+ break;
+ case kpidSize:
+ propVariant = fileInfo.Size;
+ break;
+ case kpidPackedSize:
+ if (!fileInfo.CompressedSizeIsDefined)
+ {
+ fileInfo.CompressedSizeIsDefined = true;
+ if (fileInfo.IsDirectory () ||
+ !MyGetCompressedFileSizeW(_path + fileInfo.Name,
+ 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(GetUnicodeString(fileInfo.Name), comment))
+ propVariant = comment;
+ 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;
+}
+
+
+STDMETHODIMP CFSFolder::BindToFolder(UINT32 index, IFolderFolder **resultFolder)
+{
+ *resultFolder = 0;
+ const NFind::CFileInfoW &fileInfo = _files[index];
+ if (!fileInfo.IsDirectory())
+ return E_INVALIDARG;
+ return BindToFolderSpec(fileInfo.Name, 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(TEXT('\\'));
+ if (pos < 0 || pos != _path.Length() - 1)
+ return E_FAIL;
+ UString parentPath = _path.Left(pos);
+ pos = parentPath.ReverseFind(TEXT('\\'));
+ 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(TEXT('\\'));
+ if (pos == 1)
+ {
+ if (parentPath[0] != TEXT('\\'))
+ return E_FAIL;
+ CNetFolder *netFolderSpec = new CNetFolder;
+ CMyComPtr<IFolderFolder> netFolder = netFolderSpec;
+ netFolderSpec->Init(GetUnicodeString(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]);
+ 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 = GetUnicodeString(_path, _fileCodePage);
+ *path = temp.Detach();
+ return S_OK;
+}
+
+
+STDMETHODIMP CFSFolder::WasChanged(INT32 *wasChanged)
+{
+ bool wasChangedMain = false;
+ while (true)
+ {
+ if (!_findChangeNotificationDefined)
+ {
+ *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 CFileInfoW &fileInfo = _files[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 + fileInfo.Name, size, progress);
+ }
+ size = fileInfo.Size;
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::GetItemFullSize(UINT32 index, PROPVARIANT *value, IProgress *progress)
+{
+ NCOM::CPropVariant propVariant;
+ if (index >= (UINT32)_files.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.Open(processedName))
+ return ::GetLastError();
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::Rename(UINT32 index, const wchar_t *newName, IProgress *progress)
+{
+ const CFileInfoW &fileInfo = _files[index];
+ if (!NDirectory::MyMoveFile(_path + fileInfo.Name, _path + 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++)
+ {
+ int index = indices[i];
+ const CFileInfoW &fileInfo = _files[indices[i]];
+ const UString fullPath = _path + fileInfo.Name;
+ 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)_files.Size())
+ return E_INVALIDARG;
+ CFileInfoEx &fileInfo = _files[index];
+ switch(propID)
+ {
+ case kpidComment:
+ {
+ UString filename = GetUnicodeString(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)_files.Size())
+ return E_INVALIDARG;
+ const CFileInfoEx &fileInfo = _files[index];
+ *iconIndex = 0;
+ int iconIndexTemp;
+ if (GetRealIconIndex(GetSystemString(_path + fileInfo.Name),
+ fileInfo.Attributes, iconIndexTemp) != 0)
+ {
+ *iconIndex = iconIndexTemp;
+ return S_OK;
+ }
+ return GetLastError();
+}
+
+// static const LPCTSTR kInvalidFileChars = TEXT("\\/:*?\"<>|");
+
diff --git a/7zip/FileManager/FSFolder.h b/7zip/FileManager/FSFolder.h
new file mode 100755
index 00000000..d1262cbd
--- /dev/null
+++ b/7zip/FileManager/FSFolder.h
@@ -0,0 +1,108 @@
+// FSFolder.h
+
+#pragma once
+
+#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;
+};
+
+
+class CFSFolder:
+ 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:
+ UINT _fileCodePage;
+ UString _path;
+ CObjectVector<CFileInfoEx> _files;
+ CMyComPtr<IFolderFolder> _parentFolder;
+
+ bool _findChangeNotificationDefined;
+
+ bool _commentsAreLoaded;
+ CPairsStorage _comments;
+
+ 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();
+public:
+ HRESULT Init(const UString &path, IFolderFolder *parentFolder);
+};
+
+#endif
diff --git a/7zip/FileManager/FSFolderCopy.cpp b/7zip/FileManager/FSFolderCopy.cpp
new file mode 100755
index 00000000..776567fd
--- /dev/null
+++ b/7zip/FileManager/FSFolderCopy.cpp
@@ -0,0 +1,495 @@
+// 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;
+
+static inline UINT GetCurrentCodePage()
+ { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
+
+static bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+
+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
+ );
+
+static bool MyCopyFile(LPCWSTR existingFile, LPCWSTR newFile,
+ IProgress *progress, UINT64 &completedSize)
+{
+ // if (IsItWindowsNT())
+ // {
+ CProgressInfo progressInfo;
+ progressInfo.Progress = progress;
+ progressInfo.StartPos = completedSize;
+ BOOL CancelFlag = FALSE;
+ CopyFileExPointerW copyFunctionW = (CopyFileExPointerW)
+ ::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")),
+ "CopyFileExW");
+ if (copyFunctionW != 0)
+ {
+ if (copyFunctionW(existingFile, newFile, CopyProgressRoutine,
+ &progressInfo, &CancelFlag, COPY_FILE_FAIL_IF_EXISTS))
+ return true;
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return false;
+ }
+
+ CopyFileExPointer copyFunction = (CopyFileExPointer)
+ ::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")),
+ "CopyFileExA");
+ UINT codePage = GetCurrentCodePage();
+ if (copyFunction != 0)
+ {
+ if (copyFunction(
+ UnicodeStringToMultiByte(existingFile, codePage),
+ UnicodeStringToMultiByte(newFile, codePage),
+ CopyProgressRoutine,
+ &progressInfo, &CancelFlag, COPY_FILE_FAIL_IF_EXISTS))
+ return true;
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return false;
+ }
+ // }
+ return BOOLToBool(::CopyFile(
+ GetSystemString(existingFile, codePage),
+ GetSystemString(newFile, codePage),
+ TRUE));
+}
+
+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;
+ BOOL CancelFlag = FALSE;
+
+ 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)
+ return false;
+ }
+
+
+
+ // }
+ // else
+ return NDirectory::MyMoveFile(existingFile, newFile);
+}
+
+static HRESULT MyCopyFile(
+ const UString &srcPath,
+ const CFileInfoW &srcFileInfo,
+ const UString &destPathSpec,
+ IFolderOperationsExtractCallback *callback,
+ UINT fileCodePage,
+ UINT64 &completedSize)
+{
+ UString destPath = destPathSpec;
+ if (destPath.CollateNoCase(srcPath) == 0)
+ {
+ UString message = UString(L"can not move file \'") +
+ GetUnicodeString(destPath, fileCodePage) + UString(L"\' onto itself");
+ RINOK(callback->ShowMessage(message));
+ return E_ABORT;
+ }
+
+ INT32 writeAskResult;
+ CMyComBSTR destPathResult;
+ RINOK(callback->AskWrite(
+ GetUnicodeString(srcPath, fileCodePage),
+ BoolToInt(false),
+ &srcFileInfo.LastWriteTime, &srcFileInfo.Size,
+ GetUnicodeString(destPath, fileCodePage),
+ &destPathResult,
+ &writeAskResult));
+ if (IntToBool(writeAskResult))
+ {
+ UString destPathNew = UString(destPathResult);
+ if (!::MyCopyFile(srcPath, destPathNew, callback, completedSize))
+ {
+ UString message = GetUnicodeString(NError::MyFormatMessage(GetLastError())) +
+ UString(L" \'") +
+ GetUnicodeString(destPathNew, fileCodePage)+
+ 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,
+ UINT fileCodePage,
+ UINT64 &completedSize)
+{
+ RINOK(callback->SetCompleted(&completedSize));
+
+ UString destPath = destPathSpec;
+ int len = srcPath.Length();
+ if (destPath.Length() >= len && srcPath.CollateNoCase(destPath.Left(len)) == 0)
+ {
+ if (destPath.Length() == len || destPath[len] == L'\\')
+ {
+ UString message = UString(L"can not copy folder \'") +
+ GetUnicodeString(destPath, fileCodePage) + UString(L"\' onto itself");
+ RINOK(callback->ShowMessage(message));
+ return E_ABORT;
+ }
+ }
+
+ if (!NDirectory::CreateComplexDirectory(destPath))
+ {
+ UString message = UString(L"can not create folder ") +
+ GetUnicodeString(destPath, fileCodePage);
+ 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, fileCodePage, completedSize));
+ }
+ else
+ {
+ RINOK(MyCopyFile(srcPath2, fileInfo, destPath2,
+ callback, fileCodePage, 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 >= _files.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(GetSystemString(destPath, _fileCodePage)))
+ {
+ 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 CFileInfoW &fileInfo = _files[indices[i]];
+ UString destPath2 = destPath;
+ if (!directName)
+ destPath2 += fileInfo.Name;
+ UString srcPath = _path + fileInfo.Name;
+ if (fileInfo.IsDirectory())
+ {
+ RINOK(CopyFolder(srcPath, destPath2, callback,
+ _fileCodePage, completedSize));
+ }
+ else
+ {
+ RINOK(MyCopyFile(srcPath, fileInfo, destPath2,
+ callback, _fileCodePage, completedSize));
+ }
+ }
+ return S_OK;
+}
+
+/////////////////////////////////////////////////
+// Move Operations
+
+HRESULT MyMoveFile(
+ const UString &srcPath,
+ const CFileInfoW &srcFileInfo,
+ const UString &destPathSpec,
+ IFolderOperationsExtractCallback *callback,
+ UINT fileCodePage,
+ UINT64 &completedSize)
+{
+ UString destPath = destPathSpec;
+ if (destPath.CollateNoCase(srcPath) == 0)
+ {
+ UString message = UString(L"can not move file \'")
+ + GetUnicodeString(destPath, fileCodePage) +
+ UString(L"\' onto itself");
+ RINOK(callback->ShowMessage(message));
+ return E_ABORT;
+ }
+
+ INT32 writeAskResult;
+ CMyComBSTR destPathResult;
+ RINOK(callback->AskWrite(
+ GetUnicodeString(srcPath, fileCodePage),
+ BoolToInt(false),
+ &srcFileInfo.LastWriteTime, &srcFileInfo.Size,
+ GetUnicodeString(destPath, fileCodePage),
+ &destPathResult,
+ &writeAskResult));
+ if (IntToBool(writeAskResult))
+ {
+ UString destPathNew = UString(destPathResult);
+ if (!MyMoveFile(srcPath, destPathNew, callback, completedSize))
+ {
+ UString message = UString(L"can not move to file ") +
+ GetUnicodeString(destPathNew, fileCodePage);
+ RINOK(callback->ShowMessage(message));
+ }
+ }
+ completedSize += srcFileInfo.Size;
+ RINOK(callback->SetCompleted(&completedSize));
+ return S_OK;
+}
+
+HRESULT MyMoveFolder(
+ const UString &srcPath,
+ const UString &destPathSpec,
+ IFolderOperationsExtractCallback *callback,
+ UINT fileCodePage,
+ UINT64 &completedSize)
+{
+ UString destPath = destPathSpec;
+ int len = srcPath.Length();
+ if (destPath.Length() >= len && srcPath.CollateNoCase(destPath.Left(len)) == 0)
+ {
+ if (destPath.Length() == len || destPath[len] == L'\\')
+ {
+ UString message = UString(L"can not move folder \'")
+ + GetUnicodeString(destPath, fileCodePage) +
+ 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 ") +
+ GetUnicodeString(destPath, fileCodePage);
+ 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, fileCodePage, completedSize));
+ }
+ else
+ {
+ RINOK(MyMoveFile(srcPath2, fileInfo, destPath2,
+ callback, fileCodePage, completedSize));
+ }
+ }
+ }
+ if (!NDirectory::MyRemoveDirectory(srcPath))
+ {
+ UString message = UString(L"can not remove folder") +
+ GetUnicodeString(srcPath, fileCodePage);
+ 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 >= _files.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(GetSystemString(destPath, _fileCodePage)))
+ {
+ 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 CFileInfoW &fileInfo = _files[indices[i]];
+ UString destPath2 = destPath;
+ if (!directName)
+ destPath2 += fileInfo.Name;
+ UString srcPath = _path + fileInfo.Name;
+ if (fileInfo.IsDirectory())
+ {
+ RINOK(MyMoveFolder(srcPath, destPath2, callback,
+ _fileCodePage, completedSize));
+ }
+ else
+ {
+ RINOK(MyMoveFile(srcPath, fileInfo, destPath2,
+ callback, _fileCodePage, 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/7zip/FileManager/FileFolderPluginOpen.cpp b/7zip/FileManager/FileFolderPluginOpen.cpp
new file mode 100755
index 00000000..70754e83
--- /dev/null
+++ b/7zip/FileManager/FileFolderPluginOpen.cpp
@@ -0,0 +1,108 @@
+// 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)
+{
+ 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 (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/7zip/FileManager/FileFolderPluginOpen.h b/7zip/FileManager/FileFolderPluginOpen.h
new file mode 100755
index 00000000..3614484d
--- /dev/null
+++ b/7zip/FileManager/FileFolderPluginOpen.h
@@ -0,0 +1,11 @@
+// FileFolderPluginOpen.h
+
+#pragma once
+
+#ifndef __FILEFOLDERPLUGINOPEN_H
+#define __FILEFOLDERPLUGINOPEN_H
+
+HRESULT OpenFileFolderPlugin(const UString &path,
+ HMODULE *module, IFolderFolder **resultFolder, HWND parentWindow);
+
+#endif
diff --git a/7zip/FileManager/FilePlugins.cpp b/7zip/FileManager/FilePlugins.cpp
new file mode 100755
index 00000000..524b6aa7
--- /dev/null
+++ b/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/7zip/FileManager/FilePlugins.h b/7zip/FileManager/FilePlugins.h
new file mode 100755
index 00000000..6abe0537
--- /dev/null
+++ b/7zip/FileManager/FilePlugins.h
@@ -0,0 +1,56 @@
+// FilePlugins.h
+
+#pragma once
+
+#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/7zip/FileManager/FormatUtils.cpp b/7zip/FileManager/FormatUtils.cpp
new file mode 100755
index 00000000..5515cd79
--- /dev/null
+++ b/7zip/FileManager/FormatUtils.cpp
@@ -0,0 +1,76 @@
+// FormatUtils.cpp
+
+#include "StdAfx.h"
+
+#include "FormatUtils.h"
+#include "Windows/ResourceString.h"
+#include "Common/IntToString.h"
+#include "Common/StringConvert.h"
+
+#ifdef LANG
+#include "LangUtils.h"
+#endif
+
+/*
+CSysString MyFormat(const CSysString &format, const CSysString &argument)
+{
+ CSysString result;
+ _stprintf(result.GetBuffer(format.Length() + argument.Length() + 2),
+ format, argument);
+ result.ReleaseBuffer();
+ return result;
+}
+
+CSysString MyFormat(UINT32 resourceID,
+ #ifdef LANG
+ UINT32 aLangID,
+ #endif
+ const CSysString &argument)
+{
+ return MyFormat(
+ #ifdef LANG
+ LangLoadString(resourceID, aLangID),
+ #else
+ NWindows::MyLoadString(resourceID),
+ #endif
+
+ argument);
+}
+*/
+
+CSysString NumberToString(UINT64 number)
+{
+ TCHAR temp[32];
+ ConvertUINT64ToString(number, temp);
+ return temp;
+}
+
+UString NumberToStringW(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(UINT32 resourceID,
+ #ifdef LANG
+ UINT32 aLangID,
+ #endif
+ const UString &argument)
+{
+ return MyFormatNew(
+ #ifdef LANG
+ LangLoadStringW(resourceID, aLangID),
+ #else
+ NWindows::MyLoadStringW(resourceID),
+ #endif
+ argument);
+}
diff --git a/7zip/FileManager/FormatUtils.h b/7zip/FileManager/FormatUtils.h
new file mode 100755
index 00000000..2d2333db
--- /dev/null
+++ b/7zip/FileManager/FormatUtils.h
@@ -0,0 +1,23 @@
+// FormatUtils.h
+
+#pragma once
+
+#ifndef __FORMATUTILS_H
+#define __FORMATUTILS_H
+
+#include "Common/String.h"
+
+// CSysString MyFormat(const CSysString &format, const CSysString &argument);
+
+// CSysString NumberToString(UINT64 number);
+
+UString NumberToStringW(UINT64 number);
+
+UString MyFormatNew(const UString &format, const UString &argument);
+UString MyFormatNew(UINT32 resourceID,
+ #ifdef LANG
+ UINT32 aLangID,
+ #endif
+ const UString &argument);
+
+#endif
diff --git a/7zip/FileManager/HelpUtils.cpp b/7zip/FileManager/HelpUtils.cpp
new file mode 100755
index 00000000..93203449
--- /dev/null
+++ b/7zip/FileManager/HelpUtils.cpp
@@ -0,0 +1,26 @@
+// 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))
+ {
+ // AfxMessageBox(TEXT("App Path Registry Item not found"));
+ return;
+ }
+ path += kHelpFileName;
+ path += topicFile;
+ HtmlHelp(hwnd, GetSystemString(path), HH_DISPLAY_TOPIC, NULL);
+}
+
+
diff --git a/7zip/FileManager/HelpUtils.h b/7zip/FileManager/HelpUtils.h
new file mode 100755
index 00000000..7210bd20
--- /dev/null
+++ b/7zip/FileManager/HelpUtils.h
@@ -0,0 +1,12 @@
+// HelpUtils.h
+
+#ifndef __HELPUTILS_H
+#define __HELPUTILS_H
+
+#pragma once
+
+#include "Common/String.h"
+
+void ShowHelpWindow(HWND hwnd, LPCWSTR topicFile);
+
+#endif \ No newline at end of file
diff --git a/7zip/FileManager/IFolder.h b/7zip/FileManager/IFolder.h
new file mode 100755
index 00000000..d2f6d5c7
--- /dev/null
+++ b/7zip/FileManager/IFolder.h
@@ -0,0 +1,253 @@
+// FolderInterface.h
+
+#pragma once
+
+#ifndef __FOLDERINTERFACE_H
+#define __FOLDERINTERFACE_H
+
+#include "../IProgress.h"
+
+namespace NPlugin
+{
+ enum
+ {
+ kName = 0,
+ kType,
+ kClassID,
+ kOptionsClassID
+ };
+}
+
+// {23170F69-40C1-278A-0000-000800000000}
+DEFINE_GUID(IID_IFolderFolder,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000800000000")
+IFolderFolder: public IUnknown
+{
+public:
+ STDMETHOD(LoadItems)() = 0;
+ STDMETHOD(GetNumberOfItems)(UINT32 *numItems) = 0;
+ // STDMETHOD(GetNumberOfSubFolders)(UINT32 *numSubFolders) = 0;
+ STDMETHOD(GetProperty)(UINT32 itemIndex, PROPID propID, PROPVARIANT *value) = 0;
+ STDMETHOD(BindToFolder)(UINT32 index, IFolderFolder **resultFolder) = 0;
+ STDMETHOD(BindToFolder)(const wchar_t *name, IFolderFolder **resultFolder) = 0;
+ STDMETHOD(BindToParentFolder)(IFolderFolder **resultFolder) = 0;
+ STDMETHOD(GetName)(BSTR *name) = 0;
+};
+
+// {23170F69-40C1-278A-0000-000800010000}
+DEFINE_GUID(IID_IEnumProperties,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000800010000")
+IEnumProperties: public IUnknown
+{
+public:
+ // STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator) = 0;
+ STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties) = 0;
+ STDMETHOD(GetPropertyInfo)(UINT32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType) = 0;
+};
+
+// {23170F69-40C1-278A-0000-000800020000}
+DEFINE_GUID(IID_IFolderGetTypeID,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000800020000")
+IFolderGetTypeID: public IUnknown
+{
+public:
+ STDMETHOD(GetTypeID)(BSTR *name) = 0;
+};
+
+// {23170F69-40C1-278A-0000-000800030000}
+DEFINE_GUID(IID_IFolderGetPath,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000800030000")
+IFolderGetPath: public IUnknown
+{
+public:
+ STDMETHOD(GetPath)(BSTR *path) = 0;
+};
+
+// {23170F69-40C1-278A-0000-000800040000}
+DEFINE_GUID(IID_IFolderWasChanged,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000800040000")
+IFolderWasChanged: public IUnknown
+{
+public:
+ STDMETHOD(WasChanged)(INT32 *wasChanged) = 0;
+};
+
+/*
+// {23170F69-40C1-278A-0000-000800050000}
+DEFINE_GUID(IID_IFolderReload,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000800050000")
+IFolderReload: public IUnknown
+{
+public:
+ STDMETHOD(Reload)() = 0;
+};
+*/
+
+// {23170F69-40C1-278A-0000-000800060100}
+DEFINE_GUID(IID_IFolderOperationsExtractCallback,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x06, 0x01, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000800060100")
+IFolderOperationsExtractCallback: public IProgress
+{
+public:
+ STDMETHOD(AskWrite)(
+ const wchar_t *srcPath,
+ INT32 srcIsFolder,
+ const FILETIME *srcTime,
+ const UINT64 *srcSize,
+ const wchar_t *destPathRequest,
+ BSTR *destPathResult,
+ INT32 *writeAnswer) = 0;
+ STDMETHOD(ShowMessage)(const wchar_t *message) = 0;
+};
+
+/*
+// {23170F69-40C1-278A-0000-000800060200}
+DEFINE_GUID(IID_IFolderOperationsUpdateCallback,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x06, 0x02, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000800060200")
+IFolderOperationsUpdateCallback: public IProgress
+{
+public:
+ 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);
+};
+*/
+
+// {23170F69-40C1-278A-0000-000800060000}
+DEFINE_GUID(IID_IFolderOperations,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000800060000")
+IFolderOperations: public IUnknown
+{
+public:
+ STDMETHOD(CreateFolder)(const wchar_t *name, IProgress *progress) = 0;
+ STDMETHOD(CreateFile)(const wchar_t *name, IProgress *progress) = 0;
+ STDMETHOD(Rename)(UINT32 index, const wchar_t *newName, IProgress *progress) = 0;
+ STDMETHOD(Delete)(const UINT32 *indices, UINT32 numItems, IProgress *progress) = 0;
+ STDMETHOD(CopyTo)(const UINT32 *indices, UINT32 numItems,
+ const wchar_t *path, IFolderOperationsExtractCallback *callback) = 0;
+ STDMETHOD(MoveTo)(const UINT32 *indices, UINT32 numItems,
+ const wchar_t *path, IFolderOperationsExtractCallback *callback) = 0;
+ STDMETHOD(CopyFrom)(const wchar_t *fromFolderPath,
+ const wchar_t **itemsPaths, UINT32 numItems, IProgress *progress) = 0;
+ STDMETHOD(SetProperty)(UINT32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress) = 0;
+};
+
+// {23170F69-40C1-278A-0000-000800070000}
+DEFINE_GUID(IID_IFolderGetSystemIconIndex,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x07, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000800070000")
+IFolderGetSystemIconIndex: public IUnknown
+{
+public:
+ STDMETHOD(GetSystemIconIndex)(UINT32 index, INT32 *iconIndex) = 0;
+};
+
+// {23170F69-40C1-278A-0000-000800080000}
+DEFINE_GUID(IID_IFolderGetItemFullSize,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000800080000")
+IFolderGetItemFullSize: public IUnknown
+{
+public:
+ STDMETHOD(GetItemFullSize)(UINT32 index, PROPVARIANT *value, IProgress *progress) = 0;
+};
+
+// {23170F69-40C1-278A-0000-000800090000}
+DEFINE_GUID(IID_IFolderClone,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x09, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000800090000")
+IFolderClone: public IUnknown
+{
+public:
+ STDMETHOD(Clone)(IFolderFolder **resultFolder) = 0;
+};
+
+/*
+// {23170F69-40C1-278A-0000-0008000A0000}
+DEFINE_GUID(IID_IFolderOpen,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0A, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-0008000A0000")
+IFolderOpen: public IUnknown
+{
+ STDMETHOD(FolderOpen)(
+ const wchar_t *aFileName,
+ // IArchiveHandler100 **anArchiveHandler,
+ // NZipRootRegistry::CArchiverInfo &anArchiverInfoResult,
+ // UString &aDefaultName,
+ IOpenArchive2CallBack *anOpenArchive2CallBack) = 0;
+};
+*/
+
+// {23170F69-40C1-278A-0000-000900000000}
+DEFINE_GUID(IID_IFolderManager,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000900000000")
+IFolderManager: public IUnknown
+{
+ STDMETHOD(OpenFolderFile)(const wchar_t *filePath, IFolderFolder **resultFolder, IProgress *progress) = 0;
+ STDMETHOD(GetTypes)(BSTR *types);
+ STDMETHOD(GetExtension)(const wchar_t *type, BSTR *extension);
+ STDMETHOD(CreateFolderFile)(const wchar_t *type, const wchar_t *filePath, IProgress *progress) = 0;
+};
+
+// {23170F69-40C1-278A-0000-000900010000}
+DEFINE_GUID(IID_IFolderManagerGetIconPath,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000900010000")
+IFolderManagerGetIconPath: public IUnknown
+{
+ STDMETHOD(GetIconPath)(const wchar_t *type, BSTR *iconPath) = 0;
+};
+
+/*
+// {23170F69-40C1-278A-0000-000800050A00}
+DEFINE_GUID(IID_IFolderExtract,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x0A, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000800050A00")
+IFolderExtract: public IUnknown
+{
+public:
+ STDMETHOD(Clone)(IFolderFolder **aFolder) = 0;
+};
+*/
+
+/*
+// {23170F69-40C1-278A-0000-000800050400}
+DEFINE_GUID(IID_IFolderChangeNotify,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x04, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000800050400")
+IFolderChangeNotify: public IUnknown
+{
+public:
+ STDMETHOD(OnChanged)() = 0;
+};
+
+// {23170F69-40C1-278A-0000-000800050500}
+DEFINE_GUID(IID_IFolderSetChangeNotify,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x05, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000800050500")
+IFolderSetChangeNotify: public IUnknown
+{
+public:
+ STDMETHOD(SetChangeNotify)(IFolderChangeNotify *aChangeNotify) = 0;
+};
+*/
+
+
+#endif
diff --git a/7zip/FileManager/Info.bmp b/7zip/FileManager/Info.bmp
new file mode 100755
index 00000000..d769a661
--- /dev/null
+++ b/7zip/FileManager/Info.bmp
Binary files differ
diff --git a/7zip/FileManager/Info2.bmp b/7zip/FileManager/Info2.bmp
new file mode 100755
index 00000000..af724d27
--- /dev/null
+++ b/7zip/FileManager/Info2.bmp
Binary files differ
diff --git a/7zip/FileManager/LangUtils.cpp b/7zip/FileManager/LangUtils.cpp
new file mode 100755
index 00000000..c12bbf79
--- /dev/null
+++ b/7zip/FileManager/LangUtils.cpp
@@ -0,0 +1,74 @@
+// LangUtils.cpp
+
+#include "StdAfx.h"
+
+#include "LangUtils.h"
+#include "Common/StringConvert.h"
+#include "Windows/ResourceString.h"
+#include "Windows/Window.h"
+#include "RegistryUtils.h"
+
+CLang g_Lang;
+CSysString g_LangPath;
+
+void ReloadLang()
+{
+ ReadRegLang(g_LangPath);
+ g_Lang.Clear();
+ if (!g_LangPath.IsEmpty())
+ g_Lang.Open(g_LangPath);
+}
+
+class CLangLoader
+{
+public:
+ CLangLoader()
+ {
+ ReloadLang();
+ }
+} g_LangLoader;
+
+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))
+ SetWindowText(window, GetSystemString(message));
+}
+
+UString LangLoadString(UINT32 langID)
+{
+ UString message;
+ if (g_Lang.GetMessage(langID, message))
+ return message;
+ return UString();
+}
+
+CSysString LangLoadString(UINT resourceID, UINT32 langID)
+{
+ UString message;
+ if (g_Lang.GetMessage(langID, message))
+ return GetSystemString(message);
+ return NWindows::MyLoadString(resourceID);
+}
+
+UString LangLoadStringW(UINT resourceID, UINT32 langID)
+{
+ UString message;
+ if (g_Lang.GetMessage(langID, message))
+ return message;
+ return NWindows::MyLoadStringW(resourceID);
+}
diff --git a/7zip/FileManager/LangUtils.h b/7zip/FileManager/LangUtils.h
new file mode 100755
index 00000000..546fabd1
--- /dev/null
+++ b/7zip/FileManager/LangUtils.h
@@ -0,0 +1,32 @@
+// LangUtils.h
+
+#pragma once
+
+#ifndef __LANGUTILS_H
+#define __LANGUTILS_H
+
+#include "Common/Lang.h"
+
+// extern CLang g_Lang;
+extern CSysString g_LangPath;
+
+struct CIDLangPair
+{
+ int ControlID;
+ UINT32 LangID;
+};
+
+void ReloadLang();
+
+void LangSetDlgItemsText(HWND dialogWindow, CIDLangPair *idLangPairs, int numItems);
+void LangSetWindowText(HWND window, UINT32 langID);
+
+UString LangLoadString(UINT32 langID);
+CSysString LangLoadString(UINT resourceID, UINT32 langID);
+UString LangLoadStringW(UINT resourceID, UINT32 langID);
+
+
+#endif
+
+
+
diff --git a/7zip/FileManager/Move.bmp b/7zip/FileManager/Move.bmp
new file mode 100755
index 00000000..eb5f20f9
--- /dev/null
+++ b/7zip/FileManager/Move.bmp
Binary files differ
diff --git a/7zip/FileManager/Move2.bmp b/7zip/FileManager/Move2.bmp
new file mode 100755
index 00000000..58679eff
--- /dev/null
+++ b/7zip/FileManager/Move2.bmp
Binary files differ
diff --git a/7zip/FileManager/MyLoadMenu.cpp b/7zip/FileManager/MyLoadMenu.cpp
new file mode 100755
index 00000000..cc906161
--- /dev/null
+++ b/7zip/FileManager/MyLoadMenu.cpp
@@ -0,0 +1,730 @@
+// 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_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_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;
+}
+
+/*
+void MyChangeMenu(HMENU menuLoc, int baseIndex = -1)
+{
+ CMenu menu;
+ menu.Attach(menuLoc);
+ for (int i = 0; i < menu.GetItemCount(); i++)
+ {
+ HMENU subMenu = menu.GetSubMenu(i);
+ CSysString menuString;
+ menu.GetMenuString(i, MF_BYPOSITION, menuString);
+
+ // if (menu.GetItemInfo(i, true, &menuInfo))
+ {
+ CSysString newString;
+ if (subMenu)
+ {
+ MyChangeMenu(subMenu);
+ if (baseIndex >= 0 && baseIndex < sizeof(kStringLangPairs) /
+ sizeof(kStringLangPairs[0]))
+ newString = LangLoadString(kStringLangPairs[baseIndex++].LangID);
+ else
+ continue;
+ if (newString.IsEmpty())
+ continue;
+
+ // int langPos = FindStringLangItem(GetUnicodeString(menuInfo.dwTypeData));
+ // if (langPos >= 0)
+ // newString = LangLoadString(kStringLangPairs[langPos].LangID);
+ // else
+ // newString = menuInfo.dwTypeData;
+ }
+ else
+ {
+ UINT id = menu.GetItemID(i);
+ int langPos = FindLangItem(id);
+ if (langPos < 0)
+ continue;
+ newString = LangLoadString(kIDLangPairs[langPos].LangID);
+ if (newString.IsEmpty())
+ continue;
+ int tabPos = menuString.ReverseFind(wchar_t('\t'));
+ if (tabPos >= 0)
+ newString += menuString.Mid(tabPos);
+ }
+ MENUITEMINFO menuInfo;
+ menuInfo.cbSize = sizeof(menuInfo);
+ menuInfo.fType = MFT_STRING;
+ menuInfo.fMask = MIIM_TYPE;
+ menuInfo.dwTypeData = (LPTSTR)(LPCTSTR)newString;
+ menu.SetItemInfo(i, true, &menuInfo);
+ // HMENU subMenu = menu.GetSubMenu(i);
+ }
+ }
+}
+*/
+
+static void MyChangeMenu(HMENU menuLoc, int level, int menuIndex)
+{
+ CMenu menu;
+ menu.Attach(menuLoc);
+ for (int i = 0; i < menu.GetItemCount(); i++)
+ {
+ MENUITEMINFO menuInfo;
+ ZeroMemory(&menuInfo, sizeof(menuInfo));
+ menuInfo.cbSize = sizeof(menuInfo);
+ menuInfo.fMask = MIIM_STRING | MIIM_SUBMENU | MIIM_ID;
+ menuInfo.fType = MFT_STRING;
+ const int kBufferSize = 1024;
+ TCHAR buffer[kBufferSize + 1];
+ menuInfo.dwTypeData = buffer;
+ menuInfo.cch = kBufferSize;
+ if (menu.GetItemInfo(i, true, &menuInfo))
+ {
+ CSysString newString;
+ if (menuInfo.hSubMenu)
+ {
+ if (level == 1 && menuIndex == kBookmarksMenuIndex)
+ newString = GetSystemString(LangLoadString(kAddToFavoritesLangID));
+ else
+ {
+ MyChangeMenu(menuInfo.hSubMenu, level + 1, i);
+ if (level == 1 && menuIndex == kViewMenuIndex)
+ {
+ newString = GetSystemString(LangLoadString(kToolbarsLangID));
+ }
+ else
+ {
+ if (level == 0 && i < sizeof(kStringLangPairs) /
+ sizeof(kStringLangPairs[0]))
+ newString = GetSystemString(LangLoadString(kStringLangPairs[i].LangID));
+ else
+ continue;
+ }
+ }
+ if (newString.IsEmpty())
+ continue;
+
+ // int langPos = FindStringLangItem(GetUnicodeString(menuInfo.dwTypeData));
+ // if (langPos >= 0)
+ // newString = LangLoadString(kStringLangPairs[langPos].LangID);
+ // else
+ // newString = menuInfo.dwTypeData;
+ }
+ else
+ {
+ int langPos = FindLangItem(menuInfo.wID);
+ if (langPos < 0)
+ continue;
+ newString = GetSystemString(LangLoadString(kIDLangPairs[langPos].LangID));
+ if (newString.IsEmpty())
+ continue;
+ CSysString shorcutString = menuInfo.dwTypeData;
+ int tabPos = shorcutString.ReverseFind(wchar_t('\t'));
+ if (tabPos >= 0)
+ newString += shorcutString.Mid(tabPos);
+ }
+ menuInfo.dwTypeData = (LPTSTR)(LPCTSTR)newString;
+ menuInfo.fMask = MIIM_STRING;
+ menu.SetItemInfo(i, true, &menuInfo);
+ // HMENU subMenu = menu.GetSubMenu(i);
+ }
+ }
+}
+
+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_LangPath.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++)
+ {
+ MENUITEMINFO menuInfo;
+ ZeroMemory(&menuInfo, sizeof(menuInfo));
+ menuInfo.cbSize = sizeof(menuInfo);
+ menuInfo.fMask = MIIM_STATE | MIIM_ID | MIIM_FTYPE | MIIM_STRING;
+ menuInfo.fType = MFT_STRING;
+ const int kBufferSize = 1024;
+ TCHAR buffer[kBufferSize + 1];
+ menuInfo.dwTypeData = buffer;
+ menuInfo.cch = kBufferSize;
+ if (srcMenu.GetItemInfo(i, true, &menuInfo))
+ {
+ if (destMenu.InsertItem(startPos, true, &menuInfo))
+ 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_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 = LangLoadStringW(IDS_BOOKMARK, 0x03000720);
+ s += L" ";
+ wchar_t c = L'0' + i;
+ s += c;
+ s += L"\tAlt+Shift+";
+ s += c;
+ subMenu.AppendItem(MF_STRING, kSetBookmarkMenuID + i,
+ GetSystemString(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);
+ }
+ CSysString s = GetSystemString(path);
+ if (s.IsEmpty())
+ s = TEXT("-");
+ s += TEXT("\tAlt+");
+ s += ('0' + i);
+ menu.AppendItem(MF_STRING, kOpenBookmarkMenuID + i, s);
+ }
+
+ // menu.AppendItem(MF_STRING, 100, TEXT("Test2\tAlt+2"));
+ }
+}
+
+/*
+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++)
+ {
+ MENUITEMINFO menuInfo;
+ ZeroMemory(&menuInfo, sizeof(menuInfo));
+ menuInfo.cbSize = sizeof(menuInfo);
+
+ /*
+ menuInfo.fMask = MIIM_STATE | MIIM_ID | MIIM_TYPE;
+ menuInfo.fType = MFT_STRING;
+
+ if (!srcMenu.GetItemInfo(i, true, &menuInfo))
+ {
+ // MessageBox(0, NError::MyFormatMessage(GetLastError()), "Error", 0);
+ continue;
+ }
+ // menuInfo.wID = srcMenu.GetItemID(i);
+ // menuInfo.fState = srcMenu.GetItemState(i, MF_BYPOSITION);
+
+ // menuInfo.hSubMenu = srcMenu.GetSubMenu(i);
+ CSysString menuString;
+ if (menuInfo.fType == MFT_STRING)
+ {
+ srcMenu.GetMenuString(i, MF_BYPOSITION, menuString);
+ menuInfo.dwTypeData = (LPTSTR)(LPCTSTR)menuString;
+ }
+ menuInfo.dwTypeData = (LPTSTR)(LPCTSTR)menuString;
+ */
+
+ menuInfo.fMask = MIIM_STATE | MIIM_ID | MIIM_FTYPE | MIIM_STRING;
+ menuInfo.fType = MFT_STRING;
+ const int kBufferSize = 1024;
+ TCHAR buffer[kBufferSize + 1];
+ menuInfo.dwTypeData = buffer;
+ menuInfo.cch = kBufferSize;
+
+ if (g_FileMenu.GetItemInfo(i, true, &menuInfo))
+ {
+ if (!programMenu)
+ if (menuInfo.wID == IDCLOSE)
+ continue;
+ bool createItem = (menuInfo.wID == IDM_CREATE_FOLDER ||
+ menuInfo.wID == IDM_CREATE_FILE);
+ /*
+ if (forFileMode)
+ {
+ if (createItem)
+ continue;
+ }
+ else
+ {
+ if (!createItem)
+ continue;
+ }
+ */
+ if (destMenu.InsertItem(startPos, true, &menuInfo))
+ startPos++;
+ }
+ }
+ while (destMenu.GetItemCount() > 0)
+ {
+ MENUITEMINFO menuInfo;
+ ZeroMemory(&menuInfo, sizeof(menuInfo));
+ menuInfo.cbSize = sizeof(menuInfo);
+ menuInfo.fMask = MIIM_TYPE;
+ menuInfo.dwTypeData = 0;
+ int lastIndex = destMenu.GetItemCount() - 1;
+ if (!destMenu.GetItemInfo(lastIndex, true, &menuInfo))
+ break;
+ if(menuInfo.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:
+ g_App.Delete();
+ 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_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/7zip/FileManager/MyLoadMenu.h b/7zip/FileManager/MyLoadMenu.h
new file mode 100755
index 00000000..869cfd11
--- /dev/null
+++ b/7zip/FileManager/MyLoadMenu.h
@@ -0,0 +1,19 @@
+// MyLoadMenu.h
+
+#pragma once
+
+#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/7zip/FileManager/NetFolder.cpp b/7zip/FileManager/NetFolder.cpp
new file mode 100755
index 00000000..78911e64
--- /dev/null
+++ b/7zip/FileManager/NetFolder.cpp
@@ -0,0 +1,318 @@
+// 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"");
+ */
+ CResource resource;
+ resource.RemoteNameIsDefined = true;
+ resource.RemoteName = GetSystemString(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;
+ CResource aDestResource;
+ CSysString aSystemPathPart;
+ DWORD result = GetResourceInformation(resource, aDestResource,
+ aSystemPathPart);
+ if (result == NO_ERROR)
+ Init(&aDestResource, 0, path);
+ else
+ Init(0, 0 , L"");
+ return;
+}
+
+void CNetFolder::Init(const NWindows::NNet::CResource *netResource,
+ IFolderFolder *parentFolder, const UString &path)
+{
+ _path = path;
+ if (netResource == 0)
+ _netResourcePointer = 0;
+ else
+ {
+ _netResource = *netResource;
+ _netResourcePointer = &_netResource;
+
+ // if (_netResource.DisplayType == RESOURCEDISPLAYTYPE_SERVER)
+ _path = GetUnicodeString(_netResource.RemoteName) + L'\\';
+ }
+ _parentFolder = parentFolder;
+}
+
+STDMETHODIMP CNetFolder::LoadItems()
+{
+ _items.Clear();
+ CEnum enumerator;
+
+ while(true)
+ {
+ 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;
+ }
+
+ while(true)
+ {
+ 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 = GetUnicodeString(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;
+ }
+
+ 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 = GetSystemString(_path + resource.Name);
+
+ NFile::NFind::CFindFile aFindFile;
+ NFile::NFind::CFileInfo aFileInfo;
+ if (!aFindFile.FindFirst(resource.RemoteName + CSysString(TEXT("\\*")), aFileInfo))
+ 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 = GetUnicodeString(item.LocalName);
+ break;
+ case kpidComment:
+ if (item.CommentIsDefined)
+ propVariant = GetUnicodeString(item.Comment);
+ break;
+ case kpidProvider:
+ if (item.ProviderIsDefined)
+ propVariant = GetUnicodeString(item.Provider);
+ break;
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
+
+static inline UINT GetCurrentCodePage()
+ { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
+
+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(
+ GetUnicodeString(resource.RemoteName, GetCurrentCodePage())
+ + L'\\', this));
+ *resultFolder = subFolder.Detach();
+ }
+ else
+ {
+ CNetFolder *netFolder = new CNetFolder;
+ CMyComPtr<IFolderFolder> subFolder = netFolder;
+ netFolder->Init(&resource, this, GetUnicodeString(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)
+ {
+ CResource 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 CResource &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/7zip/FileManager/NetFolder.h b/7zip/FileManager/NetFolder.h
new file mode 100755
index 00000000..4671f516
--- /dev/null
+++ b/7zip/FileManager/NetFolder.h
@@ -0,0 +1,68 @@
+// NetFolder.h
+
+#pragma once
+
+#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::CResource
+{
+ 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::CResource _netResource;
+ NWindows::NNet::CResource *_netResourcePointer;
+
+ CObjectVector<CResourceEx> _items;
+
+ CMyComPtr<IFolderFolder> _parentFolder;
+ UString _path;
+
+public:
+ void Init(const UString &path);
+ void Init(const NWindows::NNet::CResource *netResource,
+ IFolderFolder *parentFolder, const UString &path);
+ CNetFolder(): _netResourcePointer(0) {}
+};
+
+#endif
diff --git a/7zip/FileManager/OpenCallback.cpp b/7zip/FileManager/OpenCallback.cpp
new file mode 100755
index 00000000..60003cfc
--- /dev/null
+++ b/7zip/FileManager/OpenCallback.cpp
@@ -0,0 +1,99 @@
+// 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;
+ switch(propID)
+ {
+ case kpidName:
+ propVariant = GetUnicodeString(_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;
+ 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)
+{
+ if (!_passwordIsDefined)
+ {
+ CPasswordDialog dialog;
+
+ if (dialog.Create(_parentWindow) == IDCANCEL)
+ return E_ABORT;
+
+ _password = GetUnicodeString((LPCTSTR)dialog._password);
+ _passwordIsDefined = true;
+ }
+ CMyComBSTR tempName = _password;
+ *password = tempName.Detach();
+
+ return S_OK;
+}
diff --git a/7zip/FileManager/OpenCallback.h b/7zip/FileManager/OpenCallback.h
new file mode 100755
index 00000000..37effc57
--- /dev/null
+++ b/7zip/FileManager/OpenCallback.h
@@ -0,0 +1,65 @@
+// OpenCallback.h
+
+#pragma once
+
+#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 IProgress,
+ public ICryptoGetTextPassword,
+ public CMyUnknownImp
+{
+ UString _folderPrefix;
+ NWindows::NFile::NFind::CFileInfoW _fileInfo;
+public:
+ bool _passwordIsDefined;
+ UString _password;
+ HWND _parentWindow;
+
+public:
+ MY_UNKNOWN_IMP4(
+ IArchiveOpenCallback,
+ IArchiveOpenVolumeCallback,
+ 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);
+
+ void Init()
+ {
+ _passwordIsDefined = 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/7zip/FileManager/OptionsDialog.cpp b/7zip/FileManager/OptionsDialog.cpp
new file mode 100755
index 00000000..fc94a153
--- /dev/null
+++ b/7zip/FileManager/OptionsDialog.cpp
@@ -0,0 +1,110 @@
+// 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"
+
+void FillInPropertyPage(PROPSHEETPAGE* page, HINSTANCE instance, int dialogID,
+ NWindows::NControl::CPropertyPage *propertyPage, const CSysString &title)
+{
+ page->dwSize = sizeof(PROPSHEETPAGE);
+ // page->dwSize = sizeof(PROPSHEETPAGEW_V1_SIZE);
+
+ page->dwFlags = PSP_HASHELP;
+ page->hInstance = instance;
+ page->pszTemplate = MAKEINTRESOURCE(dialogID);
+ page->pszIcon = NULL;
+ page->pfnDlgProc = NWindows::NControl::ProperyPageProcedure;
+
+ if (title.IsEmpty())
+ page->pszTitle = NULL;
+ else
+ {
+ page->dwFlags |= PSP_USETITLE;
+ page->pszTitle = title;
+ }
+
+ page->lParam = LPARAM(propertyPage);
+ page->pfnCallback = NULL;
+
+ // page->dwFlags = 0;
+ // page->pszTitle = NULL;
+ // page->lParam = 0;
+}
+
+void OptionsDialog(HWND hwndOwner, HINSTANCE hInstance)
+{
+ CSystemPage systemPage;
+ CPluginsPage pluginsPage;
+ CEditPage editPage;
+ CSettingsPage settingsPage;
+ CLangPage langPage;
+
+ CSysStringVector titles;
+ UINT32 langIDs[] = { 0x03010300, 0x03010100, 0x03010200, 0x03010400, 0x01000400};
+ const int kNumPages = sizeof(langIDs) / sizeof(langIDs[0]);
+ for (int i = 0; i < kNumPages; i++)
+ titles.Add(GetSystemString(LangLoadString(langIDs[i])));
+
+ PROPSHEETPAGE pages[kNumPages];
+
+ FillInPropertyPage(&pages[0], hInstance, IDD_SYSTEM, &systemPage, titles[0]);
+ FillInPropertyPage(&pages[1], hInstance, IDD_PLUGINS, &pluginsPage, titles[1]);
+ FillInPropertyPage(&pages[2], hInstance, IDD_EDIT, &editPage, titles[2]);
+ FillInPropertyPage(&pages[3], hInstance, IDD_SETTINGS, &settingsPage, titles[3]);
+ FillInPropertyPage(&pages[4], hInstance, IDD_LANG, &langPage, titles[4]);
+
+ PROPSHEETHEADER sheet;
+
+ // sheet.dwSize = sizeof(PROPSHEETHEADER_V1_SIZE);
+
+ sheet.dwSize = sizeof(PROPSHEETHEADER);
+ sheet.dwFlags = PSH_PROPSHEETPAGE;
+ sheet.hwndParent = hwndOwner;
+ sheet.hInstance = hInstance;
+
+ CSysString title = LangLoadString(IDS_OPTIONS, 0x03010000);
+
+ sheet.pszCaption = title;
+ sheet.nPages = sizeof(pages) / sizeof(PROPSHEETPAGE);
+ sheet.nStartPage = 0;
+ sheet.ppsp = pages;
+ sheet.pfnCallback = NULL;
+
+ if (::PropertySheet(&sheet) != -1)
+ {
+ if (langPage._langWasChanged)
+ MyLoadMenu();
+ g_App.SetListSettings();
+ g_App.SetShowSystemMenu();
+ g_App.RefreshAllPanels();
+ g_App.ReloadToolbars();
+ // ::PostMessage(hwndOwner, kLangWasChangedMessage, 0 , 0);
+ }
+ /*
+ else
+ MessageBox(0, NWindows::NError::MyFormatMessage(GetLastError()), TEXT("PropertySheet"), 0);
+ */
+
+}
+
diff --git a/7zip/FileManager/Panel.cpp b/7zip/FileManager/Panel.cpp
new file mode 100755
index 00000000..7268db40
--- /dev/null
+++ b/7zip/FileManager/Panel.cpp
@@ -0,0 +1,763 @@
+// 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 "Windows/Shell.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;
+
+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 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 LPCTSTR kClassName = TEXT("7-Zip::Panel");
+
+
+LRESULT CPanel::Create(HWND mainWindow, HWND parentWindow, UINT id, int xPos,
+ const UString &currentFolderPrefix, CPanelCallback *panelCallback, CAppState *appState)
+{
+ _mainWindow = mainWindow;
+ _processTimer = true;
+ _processNotify = true;
+
+ _panelCallback = panelCallback;
+ _appState = appState;
+ // _index = index;
+ _baseID = id;
+ _comboBoxID = _baseID + 3;
+ _statusBarID = _comboBoxID + 1;
+ _ListViewMode = 0;
+
+ BindToPath(currentFolderPrefix);
+
+ if (!CreateEx(0, kClassName, 0, WS_CHILD | WS_VISIBLE,
+ xPos, 0, 116, 260,
+ parentWindow, (HMENU)id, g_hInstance))
+ return E_FAIL;
+ return S_OK;
+}
+
+LRESULT CPanel::OnMessage(UINT message, UINT wParam, LPARAM lParam)
+{
+ switch(message)
+ {
+ case kShiftSelectMessage:
+ OnShiftSelectMessage();
+ return 0;
+ case kReLoadMessage:
+ OnReload();
+ 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 = (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 = (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();
+ }
+ 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;
+ }
+ }
+ 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;
+ style |= WS_TABSTOP | LVS_REPORT | LVS_EDITLABELS | 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)_baseID + 1, g_hInstance, NULL))
+ return false;
+ SetListViewMode(3);
+
+ _listView.SetUserDataLongPtr(LONG_PTR(&_listView));
+ _listView._panel = this;
+ _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);
+
+ DWORD extendedStyle = _listView.GetExtendedListViewStyle();
+ extendedStyle |= LVS_EX_HEADERDRAGDROP; // Version 4.70
+ _listView.SetExtendedListViewStyle(extendedStyle);
+
+ _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_COMBOBOXEX, NULL,
+ WS_BORDER | WS_VISIBLE |WS_CHILD | CBS_DROPDOWN | CBS_AUTOHSCROLL,
+ 0, 0, 100, 20,
+ ((_headerReBar == 0) ? HWND(*this) : _headerToolBar),
+ (HMENU)(_comboBoxID),
+ g_hInstance, NULL);
+ _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.SetUserDataLongPtr(LONG_PTR(&_comboBoxEdit));
+ _comboBoxEdit._panel = this;
+ _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, TEXT("Statuys"), (*this), _statusBarID);
+ // _statusBar2.Create(WS_CHILD | WS_VISIBLE, TEXT("Statuys"), (*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();
+ ::DragAcceptFiles(HWND(*this), TRUE);
+ return true;
+}
+
+void CPanel::OnDestroy()
+{
+ ::DragAcceptFiles(HWND(*this), FALSE);
+ 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::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(GetUnicodeString(NError::MyFormatMessage(errorCode)), caption); }
+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();
+}
+
+CSysString CPanel::GetFileType(UINT32 index)
+{
+ return TEXT("Test type");
+}
+
+UString CPanel::GetFolderTypeID() const
+{
+ CMyComPtr<IFolderGetTypeID> folderGetTypeID;
+ if(_folder.QueryInterface(IID_IFolderGetTypeID, &folderGetTypeID) != S_OK)
+ return L"";
+ CMyComBSTR typeID;
+ folderGetTypeID->GetTypeID(&typeID);
+ return typeID;
+}
+
+bool CPanel::IsRootFolder() const
+{
+ return (GetFolderTypeID() == L"RootFolder");
+}
+
+bool CPanel::IsFSFolder() const
+{
+ return (GetFolderTypeID() == L"FSFolder");
+}
+
+static DWORD kStyles[4] = { LVS_ICON, LVS_SMALLICON, LVS_LIST, LVS_REPORT };
+
+void CPanel::SetListViewMode(UINT32 index)
+{
+ if (index >= 4)
+ return;
+ _ListViewMode = index;
+ DWORD oldStyle = _listView.GetStyle();
+ DWORD newStyle = kStyles[index];
+ if ((oldStyle & LVS_TYPEMASK) != newStyle)
+ _listView.SetStyle((oldStyle & ~LVS_TYPEMASK) | newStyle);
+ // RefreshListCtrlSaveFocused();
+}
+
+void CPanel::RefreshStatusBar()
+{
+ PostMessage(kRefreshStatusBar);
+}
+
+void CPanel::CompressDropFiles(HDROP dr)
+{
+ NShell::CDrop drop(true);
+ drop.Attach(dr);
+ CSysStringVector fileNames;
+ drop.QueryFileNames(fileNames);
+ if (fileNames.Size() == 0)
+ return;
+ UStringVector fileNamesUnicode;
+ for (int i = 0; i < fileNames.Size(); i++)
+ fileNamesUnicode.Add(GetUnicodeString(fileNames[i]));
+ const UString archiveName = CreateArchiveName(
+ fileNamesUnicode.Front(), (fileNamesUnicode.Size() > 1), false);
+ UString currentDirectory;
+ if (IsFSFolder())
+ {
+ CompressFiles(_currentFolderPrefix + archiveName, fileNamesUnicode,
+ false, // email
+ true // showDialog
+ );
+ }
+ else
+ {
+ _panelCallback->OnCopy(fileNamesUnicode, false, true);
+ /*
+ if (!NFile::NDirectory::GetOnlyDirPrefix(fileNames.Front(), currentDirectory))
+ return;
+ */
+ }
+}
+
+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 + GetItemName(index));
+ }
+ const UString archiveName = CreateArchiveName(
+ names.Front(), (names.Size() > 1), false);
+ CompressFiles(_currentFolderPrefix + archiveName, names, false, true);
+ KillSelection();
+}
+
+void CPanel::ExtractArchive()
+{
+ if (_parentFolders.Size() > 0)
+ {
+ _panelCallback->OnCopy(UStringVector(), false, false);
+ return;
+ }
+ CRecordVector<UINT32> indices;
+ GetOperatedItemIndices(indices);
+ if (indices.Size() != 1)
+ {
+ MessageBox(kSelectOneFile);
+ return;
+ }
+ int index = indices[0];
+ if (IsItemFolder(index))
+ {
+ MessageBox(kSelectOneFile);
+ return;
+ }
+ UString fullPath = _currentFolderPrefix + GetItemName(index);
+ ::ExtractArchive(fullPath, _currentFolderPrefix, true);
+}
+
+void CPanel::TestArchive()
+{
+ CRecordVector<UINT32> indices;
+ GetOperatedItemIndices(indices);
+ if (!IsFSFolder())
+ {
+ MessageBox(L"Test archive operation is not supported for that folder");
+ return;
+ }
+ if (indices.Size() != 1)
+ {
+ MessageBox(kSelectOneFile);
+ return;
+ }
+ int index = indices[0];
+ if (IsItemFolder(index))
+ {
+ MessageBox(kSelectOneFile);
+ return;
+ }
+ UString fullPath = _currentFolderPrefix + GetItemName(index);
+ ::TestArchive(fullPath);
+}
+
diff --git a/7zip/FileManager/Panel.h b/7zip/FileManager/Panel.h
new file mode 100755
index 00000000..11f73e30
--- /dev/null
+++ b/7zip/FileManager/Panel.h
@@ -0,0 +1,438 @@
+// Panel.h
+
+#pragma once
+
+#ifndef __PANEL_H
+#define __PANEL_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 "Windows/DLL.h"
+#include "Windows/FileFind.h"
+#include "Windows/FileDir.h"
+#include "Windows/Synchronization.h"
+#include "Windows/Handle.h"
+
+#include "Common/MyCom.h"
+
+#include "SysIconUtils.h"
+
+#include "IFolder.h"
+
+#include "ViewSettings.h"
+
+#include "AppState.h"
+
+const int kParentFolderID = 100;
+const int kPluginMenuStartID = 1000;
+const int kToolbarStartID = 2000;
+
+class CPanelCallback
+{
+public:
+ virtual void OnTab() = 0;
+ virtual void SetFocusToPath(int index) = 0;
+ virtual void OnCopy(UStringVector &externalNames, bool move, bool copyToSame) = 0;
+ virtual void OnSetSameFolder() = 0;
+ virtual void OnSetSubFolder() = 0;
+ virtual void PanelWasFocused() = 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;
+ CSysString FolderPath;
+ CSysString FilePath;
+ NWindows::NFile::NFind::CFileInfo FileInfo;
+ void DeleteDirAndFile()
+ {
+ NWindows::NFile::NDirectory::DeleteFileAlways(FilePath);
+ ::RemoveDirectory(FolderPath);
+ }
+};
+
+struct CFolderLink: public CTempFileInfo
+{
+ NWindows::NDLL::CLibrary Library;
+ CMyComPtr<IFolderFolder> ParentFolder;
+ // CSysString RealPath;
+};
+
+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);
+};
+
+class CPanel:public NWindows::NControl::CWindow2
+{
+ HWND _mainWindow;
+
+ CExtToIconMap _extToIconMap;
+ // int _index;
+ UINT _baseID;
+ int _comboBoxID;
+ UINT _statusBarID;
+
+ CAppState *_appState;
+
+ bool OnCommand(int code, int itemID, LPARAM lParam, LRESULT &result);
+ LRESULT OnMessage(UINT message, UINT 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(PNMCBEENDEDIT info, LRESULT &result);
+ bool OnNotifyReBar(LPNMHDR lParam, LRESULT &result);
+ bool OnNotifyComboBox(LPNMHDR lParam, LRESULT &result);
+ bool OnNotifyList(LPNMHDR lParam, LRESULT &result);
+ // void OnDrag(LPNMLISTVIEW nmListView);
+ bool OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result);
+ BOOL OnBeginLabelEdit(LV_DISPINFO * lpnmh);
+ BOOL OnEndLabelEdit(LV_DISPINFO * lpnmh);
+ void OnColumnClick(LPNMLISTVIEW info);
+ bool OnCustomDraw(LPNMLVCUSTOMDRAW lplvcd, LRESULT &result);
+
+public:
+ CPanelCallback *_panelCallback;
+
+ void DeleteItems();
+ void CreateFolder();
+ void CreateFile();
+
+private:
+
+ void ChangeWindowSize(int xSize, int ySize);
+
+ void InitColumns();
+ // void InitColumns2(PROPID sortID);
+ void InsertColumn(int index);
+
+ void RefreshListCtrl(const UString &focusedName, int focusedPos,
+ const UStringVector &selectedNames);
+
+ void OnShiftSelectMessage();
+ void OnArrowWithShift();
+
+ void OnInsert();
+ // void OnUpWithShift();
+ // void OnDownWithShift();
+public:
+ void SelectSpec(bool selectMode);
+ void SelectByType(bool selectMode);
+ void SelectAll(bool selectMode);
+ void InvertSelection();
+private:
+
+ CSysString GetFileType(UINT32 index);
+ LRESULT SetItemText(LVITEM &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;
+
+ bool _showDots;
+ bool _showRealFileIcons;
+ // bool _virtualMode;
+ CBoolVector _selectedStatusVector;
+ CUIntVector _realIndices;
+
+ UINT32 GetRealIndex(const LVITEM &item) const
+ {
+ /*
+ if (_virtualMode)
+ return _realIndices[item.iItem];
+ */
+ return item.lParam;
+ }
+ int GetRealItemIndex(int indexInListView) const
+ {
+ /*
+ if (_virtualMode)
+ return indexInListView;
+ */
+ LPARAM param;
+ if (!_listView.GetItemParam(indexInListView, param))
+ throw 1;
+ return param;
+ }
+
+ UINT32 _ListViewMode;
+
+ UString _currentFolderPrefix;
+
+ CObjectVector<CFolderLink> _parentFolders;
+ NWindows::NDLL::CLibrary _library;
+ CMyComPtr<IFolderFolder> _folder;
+ // CMyComPtr<IFolderGetSystemIconIndex> _folderGetSystemIconIndex;
+
+ UStringVector _fastFolders;
+
+ void GetSelectedNames(UStringVector &selectedNames);
+ void RefreshListCtrlSaveFocused();
+
+ UString GetItemName(int itemIndex) const;
+ bool IsItemFolder(int itemIndex) const;
+ UINT64 GetItemSize(int itemIndex) const;
+
+ ////////////////////////
+ // PanelFolderChange.cpp
+
+ void SetToRootFolder();
+ HRESULT BindToPath(const UString &fullPath); // 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, int xPos,
+ const UString &currentFolderPrefix,
+ CPanelCallback *panelCallback,
+ CAppState *appState);
+ void SetFocusToList();
+ void SetFocusToLastRememberedItem();
+
+
+ void ReadListViewInfo();
+ void SaveListViewInfo();
+
+ CPanel() :
+ // _virtualMode(flase),
+ _showDots(false),
+ _showRealFileIcons(false),
+ _needSaveInfo(false),
+ _startGroupSelect(0),
+ _selectionIsDefined(false)
+ {}
+
+ bool _needSaveInfo;
+ CSysString _typeIDString;
+ CListViewInfo _listViewInfo;
+ CItemProperties _properties;
+ CItemProperties _visibleProperties;
+
+ int _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;
+ void 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 KillSelection();
+
+ UString GetFolderTypeID() const;
+ bool IsRootFolder() const;
+ bool IsFSFolder() const;
+
+ bool _processTimer;
+ bool _processNotify;
+
+ class CDisableTimerProcessing
+ {
+ bool _processTimerMem;
+ bool _processNotifyMem;
+
+ CPanel &_panel;
+ public:
+ CDisableTimerProcessing(CPanel &panel): _panel(panel)
+ {
+ _processTimerMem = _panel._processTimer;
+ _processNotifyMem = _panel._processNotify;
+ _panel._processTimer = false;
+ _panel._processNotify = false;
+ }
+ void Restore()
+ {
+ _panel._processTimer = _processTimerMem;
+ _panel._processNotify = _processNotifyMem;
+ }
+ ~CDisableTimerProcessing()
+ {
+ Restore();
+ }
+ };
+
+ // bool _passwordIsDefined;
+ // UString _password;
+
+ void RefreshListCtrl();
+
+ void MessageBox(LPCWSTR message);
+ void MessageBox(LPCWSTR message, LPCWSTR caption);
+ void MessageBoxMyError(LPCWSTR message);
+ void MessageBoxError(HRESULT errorCode, LPCWSTR caption);
+ 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 CSysString &folderPath,
+ const CSysString &filePath);
+ HRESULT OpenItemAsArchive(const UString &aName);
+ HRESULT OpenItemAsArchive(int index);
+ // void OpenItem(int index, CSysString realPath);
+ void OpenItemInArchive(int index, bool tryInternal, bool tryExternal,
+ bool editMode);
+ LRESULT OnOpenItemChanged(const CSysString &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() { return _ListViewMode; };
+
+ void RefreshStatusBar();
+ void OnRefreshStatusBar();
+
+ void CompressDropFiles(HDROP dr);
+
+ void AddToArchive();
+ void ExtractArchive();
+ void TestArchive();
+};
+
+#endif
diff --git a/7zip/FileManager/PanelCopy.cpp b/7zip/FileManager/PanelCopy.cpp
new file mode 100755
index 00000000..c0ed38e1
--- /dev/null
+++ b/7zip/FileManager/PanelCopy.cpp
@@ -0,0 +1,10 @@
+// PanelCopy.cpp
+
+#include "StdAfx.h"
+
+#include "App.h"
+
+void CApp::PanelCopyItems()
+{
+ return;
+} \ No newline at end of file
diff --git a/7zip/FileManager/PanelFolderChange.cpp b/7zip/FileManager/PanelFolderChange.cpp
new file mode 100755
index 00000000..43cfb17e
--- /dev/null
+++ b/7zip/FileManager/PanelFolderChange.cpp
@@ -0,0 +1,379 @@
+// 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)
+{
+ CDisableTimerProcessing disableTimerProcessing1(*this);
+ CloseOpenFolders();
+ CSysString sysPath = GetSystemString(fullPath);
+ CFileInfo fileInfo;
+ UStringVector reducedParts;
+ while(!sysPath.IsEmpty())
+ {
+ if (FindFile(sysPath, fileInfo))
+ break;
+ int pos = sysPath.ReverseFind('\\');
+ if (pos < 0)
+ sysPath.Empty();
+ else
+ {
+ if (reducedParts.Size() > 0 || pos < sysPath.Length() - 1)
+ reducedParts.Add(GetUnicodeString(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(GetUnicodeString(sysPath), &newFolder) == S_OK)
+ _folder = newFolder;
+ }
+ else
+ {
+ CSysString dirPrefix;
+ if (!NDirectory::GetOnlyDirPrefix(sysPath, dirPrefix))
+ dirPrefix.Empty();
+ if (_folder->BindToFolder(GetUnicodeString(dirPrefix), &newFolder) == S_OK)
+ {
+ _folder = newFolder;
+ LoadFullPath();
+ CSysString fileName;
+ if (NDirectory::GetOnlyName(sysPath, fileName))
+ {
+ if (OpenItemAsArchive(GetUnicodeString(fileName),
+ GetSystemString(_currentFolderPrefix),
+ GetSystemString(_currentFolderPrefix) + fileName) == S_OK)
+ {
+ 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);
+ RINOK(BindToPath(path));
+ RefreshListCtrl(UString(), -1, 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(&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(GetSystemString(_currentFolderPrefix));
+
+ /*
+ for (int i = 0; i < g_Folders.m_Strings.Size(); i++)
+ {
+ CSysString string = GetSystemString(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(PNMCBEENDEDIT info, LRESULT &result)
+{
+ if (info->iWhy == CBENF_ESCAPE)
+ {
+ _headerComboBox.SetText(GetSystemString(_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)
+ {
+ // MessageBeep((UINT)-1);
+ result = TRUE;
+ return true;
+ }
+ result = FALSE;
+ PostMessage(kSetFocusToListView);
+ return true;
+ }
+ return false;
+}
+
+void CPanel::OnComboBoxCommand(UINT code, LPARAM &param)
+{
+ /*
+ if (code == CBN_SELENDOK)
+ {
+ CSysString path;
+ if (!_headerComboBox.GetText(path))
+ return;
+ CRootFolder *rootFolderSpec = new CRootFolder;
+ CMyComPtr<IFolderFolder> rootFolder = rootFolderSpec;
+ rootFolderSpec->Init();
+ CMyComPtr<IFolderFolder> newFolder;
+ if (rootFolder->BindToFolder(GetUnicodeString(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();
+ }
+ case CBEN_ENDEDIT:
+ {
+ return OnNotifyComboBoxEndEdit((PNMCBEENDEDIT)header, result);
+ }
+ }
+ return false;
+}
+
+
+void CPanel::FoldersHistory()
+{
+ CListViewDialog listViewDialog;
+ listViewDialog.DeleteIsAllowed = true;
+ // listViewDialog.m_Value = TEXT("*");
+ listViewDialog.Title = LangLoadStringW(IDS_FOLDERS_HISTORY, 0x03020260);
+ UStringVector strings;
+ _appState->FolderHistory.GetList(strings);
+ int i;
+ for(i = 0; i < strings.Size(); i++)
+ listViewDialog.Strings.Add(GetSystemString(strings[i]));
+ if (listViewDialog.Create(GetParent()) == IDCANCEL)
+ return;
+ UString selectString;
+ if (listViewDialog.StringsWereChanged)
+ {
+ _appState->FolderHistory.RemoveAll();
+ for (i = listViewDialog.Strings.Size() - 1; i >= 0; i--)
+ _appState->FolderHistory.AddString(GetUnicodeString(listViewDialog.Strings[i]));
+ if (listViewDialog.FocusedItemIndex >= 0)
+ selectString = GetUnicodeString(listViewDialog.Strings[listViewDialog.FocusedItemIndex]);
+ }
+ else
+ {
+ if (listViewDialog.FocusedItemIndex >= 0)
+ selectString = 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 = GetUnicodeString(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(::GetSystemString(_currentFolderPrefix));
+ RefreshListCtrl(focucedName, -1, 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(), 0, UStringVector());
+ // ::SetCurrentDirectory(::GetSystemString(_currentFolderPrefix));
+ /*
+ BeforeChangeFolder();
+ _currentFolderPrefix.Empty();
+ AfterChangeFolder();
+ SetCurrentPathText();
+ RefreshListCtrl(CSysString(), 0, CSysStringVector());
+ _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 == -1)
+ {
+ OpenParentFolder();
+ return;
+ }
+ CMyComPtr<IFolderFolder> newFolder;
+ _folder->BindToFolder(index, &newFolder);
+ if (!newFolder)
+ return;
+ _folder = newFolder;
+ LoadFullPath();
+ ::SetCurrentDirectory(::GetSystemString(_currentFolderPrefix));
+ RefreshListCtrl();
+ UINT state = LVIS_SELECTED;
+ _listView.SetItemState(_listView.GetFocusedItem(), state, state);
+ _listView.EnsureVisible(_listView.GetFocusedItem(), false);
+}
diff --git a/7zip/FileManager/PanelItemOpen.cpp b/7zip/FileManager/PanelItemOpen.cpp
new file mode 100755
index 00000000..b6a03a48
--- /dev/null
+++ b/7zip/FileManager/PanelItemOpen.cpp
@@ -0,0 +1,494 @@
+// PanelItemOpen.cpp
+
+#include "StdAfx.h"
+
+#include "resource.h"
+
+#include "Common/StringConvert.h"
+#include "Common/Random.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileFind.h"
+#include "Windows/Thread.h"
+#include "Windows/Synchronization.h"
+#include "Windows/System.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;
+
+static inline UINT GetCurrentFileCodePage()
+ { return AreFileApisANSI() ? CP_ACP : CP_OEMCP;}
+
+static LPCTSTR kTempDirPrefix = TEXT("7zO");
+
+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 CSysString &folderPath,
+ const CSysString &filePath)
+{
+ 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(GetUnicodeString(filePath),
+ &library, &newFolder, GetParent()));
+
+ 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)
+{
+ return OpenItemAsArchive(name, GetSystemString(_currentFolderPrefix),
+ GetSystemString(_currentFolderPrefix + name));
+}
+
+HRESULT CPanel::OpenItemAsArchive(int index)
+{
+ CDisableTimerProcessing disableTimerProcessing1(*this);
+ RINOK(OpenItemAsArchive(GetItemName(index)));
+ RefreshListCtrl();
+ return S_OK;
+}
+
+HRESULT CPanel::OpenParentArchiveFolder()
+{
+ CDisableTimerProcessing disableTimerProcessing1(*this);
+ if (_parentFolders.Size() < 2)
+ return S_OK;
+ CFolderLink &folderLink = _parentFolders.Back();
+ NFind::CFileInfo 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, GetUnicodeString(folderLink.FilePath)), L"7-Zip", MB_OK | MB_ICONSTOP);
+ return S_OK;
+ }
+ }
+ }
+ }
+ folderLink.DeleteDirAndFile();
+ return S_OK;
+}
+
+static bool DoItemAlwaysStart(const UString &name)
+{
+ int extPos = name.ReverseFind('.');
+ if (extPos < 0)
+ return false;
+ const UString ext = name.Mid(extPos + 1);
+ return (ext == UString(L"exe") || ext == UString(L"bat") || ext == UString(L"com"));
+}
+
+static HANDLE StartEditApplication(CSysString &path, HWND window)
+{
+ CSysString command;
+ ReadRegEditor(command);
+ if (command.IsEmpty())
+ {
+ if (!MyGetWindowsDirectory(command))
+ return 0;
+ NFile::NName::NormalizeDirPathPrefix(command);
+ command += TEXT("notepad.exe");
+ }
+ command = CSysString(TEXT("\"")) + command + CSysString(TEXT("\""));
+ command += TEXT(" \"");
+ command += path;
+ command += TEXT("\"");
+
+ 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;
+ BOOL result = ::CreateProcess(NULL, (TCHAR *)(const TCHAR *)command,
+ NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation);
+ if (result != FALSE)
+ {
+ ::CloseHandle(processInformation.hThread);
+ return processInformation.hProcess;
+ }
+ ::MessageBoxW(window, LangLoadStringW(IDS_CANNOT_START_EDITOR, 0x03020282),
+ L"7-Zip", MB_OK | MB_ICONSTOP);
+ return 0;
+}
+
+static HANDLE StartApplication(CSysString &path, HWND window)
+{
+ SHELLEXECUTEINFO execInfo;
+ execInfo.cbSize = sizeof(execInfo);
+ execInfo.fMask = SEE_MASK_NOCLOSEPROCESS; //
+ execInfo.hwnd = NULL;
+ execInfo.lpVerb = NULL;
+ execInfo.lpFile = path;
+ execInfo.lpParameters = NULL;
+ execInfo.lpDirectory = NULL;
+ execInfo.nShow = SW_SHOWNORMAL;
+ execInfo.hProcess = 0;
+ bool success = BOOLToBool(::ShellExecuteEx(&execInfo));
+ UINT32 result = (UINT32)execInfo.hInstApp;
+ if(result <= 32)
+ {
+ switch(result)
+ {
+ case SE_ERR_NOASSOC:
+ ::MessageBox(window,
+ NError::MyFormatMessage(::GetLastError()),
+ // TEXT("There is no application associated with the given file name extension"),
+ TEXT("7-Zip"), MB_OK | MB_ICONSTOP);
+ }
+ }
+ return execInfo.hProcess;
+}
+
+void CPanel::EditItem(int index)
+{
+ if (!_parentFolders.IsEmpty())
+ {
+ OpenItemInArchive(index, false, true, true);
+ return;
+ }
+ CSysString fullPath = GetSystemString((_currentFolderPrefix +
+ GetItemName(index)), GetCurrentFileCodePage());
+ HANDLE hProcess = StartEditApplication(fullPath, (HWND)*this);
+ if (hProcess != 0)
+ ::CloseHandle(hProcess);
+}
+
+void CPanel::OpenFolderExternal(int index)
+{
+ CSysString fullPath = GetSystemString((_currentFolderPrefix +
+ GetItemName(index)), GetCurrentFileCodePage());
+ StartApplication(fullPath, (HWND)*this);
+}
+
+void CPanel::OpenItem(int index, bool tryInternal, bool tryExternal)
+{
+ CDisableTimerProcessing disableTimerProcessing1(*this);
+ if (!_parentFolders.IsEmpty())
+ {
+ OpenItemInArchive(index, tryInternal, tryExternal, false);
+ return;
+ }
+ CSysString fullPath = GetSystemString((_currentFolderPrefix +
+ GetItemName(index)), GetCurrentFileCodePage());
+ if (tryInternal)
+ if (!tryExternal || !DoItemAlwaysStart(GetItemName(index)))
+ if (OpenItemAsArchive(index) == S_OK)
+ return;
+ if (tryExternal)
+ {
+ ::SetCurrentDirectory(GetSystemString(_currentFolderPrefix));
+ HANDLE hProcess = StartApplication(fullPath, (HWND)*this);
+ if (hProcess != 0)
+ ::CloseHandle(hProcess);
+ }
+}
+
+HRESULT CPanel::OnOpenItemChanged(const CSysString &folderPath, const UString &itemName)
+{
+ CMyComPtr<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ {
+ MessageBox(LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
+ return E_FAIL;
+ }
+ UStringVector fileNames;
+ CRecordVector<const wchar_t *> fileNamePointers;
+ fileNames.Add(itemName);
+ fileNamePointers.Add(fileNames[0]);
+
+ // SetCurrentDirectory(tmpProcessInfo.FolderPath);
+ CSysString pathPrefix = folderPath;
+ NName::NormalizeDirPathPrefix(pathPrefix);
+ return folderOperations->CopyFrom(
+ GetUnicodeString(pathPrefix),
+ &fileNamePointers.Front(),
+ fileNamePointers.Size(),
+ NULL);
+}
+
+LRESULT CPanel::OnOpenItemChanged(LPARAM lParam)
+{
+ CTmpProcessInfo &tmpProcessInfo = *(CTmpProcessInfo *)lParam;
+ // LoadCurrentPath()
+ if (tmpProcessInfo.FullPathFolderPrefix != _currentFolderPrefix)
+ return 0;
+ HRESULT result = OnOpenItemChanged(tmpProcessInfo.FolderPath, tmpProcessInfo.ItemName);
+ if (result != S_OK)
+ return 0;
+ RefreshListCtrlSaveFocused();
+ 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)
+{
+ // CTmpProcessInfo *tmpProcessInfo = (CTmpProcessInfo *)param;
+ std::auto_ptr<CTmpProcessInfo> tmpProcessInfo((CTmpProcessInfo *)param);
+ 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::CFileInfo 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.get()) != 1)
+ {
+ ::MessageBoxW(g_HWND, MyFormatNew(IDS_CANNOT_UPDATE_FILE,
+ 0x03020281, GetUnicodeString(tmpProcessInfo->FilePath)), L"7-Zip", MB_OK | MB_ICONSTOP);
+ return 0;
+ }
+ }
+ }
+ }
+ tmpProcessInfo->DeleteDirAndFile();
+ return 0;
+}
+
+static CCriticalSection g_CriticalSection;
+
+struct CThreadExtractInArchive
+{
+ CMyComPtr<IFolderOperations> FolderOperations;
+ CRecordVector<UINT32> Indices;
+ UString DestPath;
+ CExtractCallbackImp *ExtractCallbackSpec;
+ CMyComPtr<IFolderOperationsExtractCallback> ExtractCallback;
+ HRESULT Result;
+
+ DWORD Extract()
+ {
+ NCOM::CComInitializer comInitializer;
+ ExtractCallbackSpec->ProgressDialog.WaitCreating();
+ Result = FolderOperations->CopyTo(
+ &Indices.Front(), Indices.Size(),
+ DestPath, ExtractCallback);
+ // ExtractCallbackSpec->DestroyWindows();
+ ExtractCallbackSpec->ProgressDialog.MyClose();
+ return 0;
+ }
+
+ static DWORD WINAPI MyThreadFunction(void *param)
+ {
+ return ((CThreadExtractInArchive *)param)->Extract();
+ }
+};
+
+void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal,
+ bool editMode)
+{
+ CMyComPtr<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ {
+ MessageBox(LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
+ return;
+ }
+
+ CSysString tempDir;
+ if (!CreateTempDirectory(kTempDirPrefix, tempDir))
+ return;
+
+ CThreadExtractInArchive extracter;
+
+ extracter.ExtractCallbackSpec = new CExtractCallbackImp;
+ extracter.ExtractCallback = extracter.ExtractCallbackSpec;
+ extracter.ExtractCallbackSpec->_parentWindow = GetParent();
+
+ // extracter.ExtractCallbackSpec->_appTitle.Window = extracter.ExtractCallbackSpec->_parentWindow;
+ // extracter.ExtractCallbackSpec->_appTitle.Title = progressWindowTitle;
+ // extracter.ExtractCallbackSpec->_appTitle.AddTitle = title + CSysString(TEXT(" "));
+
+ extracter.ExtractCallbackSpec->Init(NExtractionMode::NOverwrite::kWithoutPrompt, false, L"");
+ extracter.Indices.Add(index);
+ extracter.DestPath = GetUnicodeString(tempDir + NFile::NName::kDirDelimiter);
+ extracter.FolderOperations = folderOperations;
+
+ CThread extractThread;
+ if (!extractThread.Create(CThreadExtractInArchive::MyThreadFunction, &extracter))
+ throw 271824;
+ extracter.ExtractCallbackSpec->StartProgressDialog(LangLoadStringW(IDS_OPENNING, 0x03020283));
+
+ if (extracter.Result != S_OK)
+ {
+ // MessageBox(TEXT("Can not extract item"));
+ return;
+ }
+
+ UString name = GetItemName(index);
+ CSysString tempFileName = tempDir + NFile::NName::kDirDelimiter +
+ GetSystemString(name);
+
+ std::auto_ptr<CTmpProcessInfo> tmpProcessInfo(new CTmpProcessInfo());
+ tmpProcessInfo->FolderPath = tempDir;
+ tmpProcessInfo->FilePath = tempFileName;
+ if (!NFind::FindFile(tempFileName, tmpProcessInfo->FileInfo))
+ return;
+
+ if (tryInternal)
+ {
+ if (!tryExternal || !DoItemAlwaysStart(name))
+ if (OpenItemAsArchive(name, tempDir, tempFileName) == S_OK)
+ {
+ RefreshListCtrl();
+ return;
+ }
+ }
+
+ CTmpProcessInfoRelease tmpProcessInfoRelease(*tmpProcessInfo);
+
+ if (!tryExternal)
+ return;
+
+ HANDLE hProcess;
+ if (editMode)
+ hProcess = StartEditApplication(tempFileName, (HWND)*this);
+ else
+ hProcess = StartApplication(tempFileName, (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.get()))
+ throw 271824;
+ tmpProcessInfo.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()
+{
+ CSysString tempPath;
+ if(!NFile::NDirectory::MyGetTempPath(tempPath))
+ throw 1;
+
+ SYSTEMTIME systemTime;
+ ::GetSystemTime(&systemTime);
+ UINT64 currentFileTime;
+ if(!::SystemTimeToFileTime(&systemTime, (FILETIME *)&currentFileTime))
+ throw 2;
+ CSysString searchWildCard = tempPath + kTempDirPrefix + TEXT("*.tmp");
+ searchWildCard += TCHAR(NName::kAnyStringWildcard);
+ NFind::CEnumerator enumerator(searchWildCard);
+ NFind::CFileInfo 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/7zip/FileManager/PanelItems.cpp b/7zip/FileManager/PanelItems.cpp
new file mode 100755
index 00000000..4a083982
--- /dev/null
+++ b/7zip/FileManager/PanelItems.cpp
@@ -0,0 +1,734 @@
+// 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 "RootFolder.h"
+
+#include "PropertyName.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);
+ UINT32 i;
+ for (i = 0; i < 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);
+
+ while(true)
+ 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_COLUMN column;
+ column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM | LVCF_ORDER;
+ TCHAR string[1024];
+ column.pszText = string;
+ 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;
+ lstrcpy(string, GetSystemString(propertyName));
+ _listView.InsertColumn(index, &column);
+}
+
+
+void CPanel::RefreshListCtrl()
+{
+ RefreshListCtrl(UString(), 0, UStringVector());
+}
+
+int CALLBACK CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData);
+
+
+void CPanel::GetSelectedNames(UStringVector &selectedNames)
+{
+ selectedNames.Clear();
+ /*
+ CRecordVector<UINT32> indices;
+ GetSelectedItemsIndexes(indices);
+ selectedNames.Reserve(indices.Size());
+ for (int i = 0; i < indices.Size(); i++)
+ selectedNames.Add(GetItemName(indices[i]));
+ */
+ for (int i = 0; i < _listView.GetItemCount(); i++)
+ {
+ const int kSize = 1024;
+ TCHAR name[kSize + 1];
+ LVITEM 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 == -1)
+ continue;
+ if (_selectedStatusVector[realIndex])
+ selectedNames.Add(GetUnicodeString(item.pszText));
+ }
+ selectedNames.Sort();
+}
+
+void CPanel::RefreshListCtrlSaveFocused()
+{
+ int focusedItem = _listView.GetFocusedItem();
+ UString focusedName;
+ if (focusedItem >= 0)
+ {
+ /*
+ LPARAM param;
+ if (_listView.GetItemParam(focusedItem, param))
+ // focusedName = m_Files[param].Name;
+ focusedName = GetItemName(param);
+ */
+ const int kSize = 1024;
+ TCHAR name[kSize + 1];
+ LVITEM item;
+ item.iItem = focusedItem;
+ item.pszText = name;
+ item.cchTextMax = kSize;
+ item.iSubItem = 0;
+ item.mask = LVIF_TEXT;
+ if (_listView.GetItem(&item))
+ focusedName = GetUnicodeString(item.pszText);
+ }
+ UStringVector selectedNames;
+ GetSelectedNames(selectedNames);
+ RefreshListCtrl(focusedName, focusedItem, selectedNames);
+}
+
+void CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos,
+ const UStringVector &selectedNames)
+{
+ LoadFullPathAndShow();
+ // OutputDebugStringA("=======\n");
+ // OutputDebugStringA("s1 \n");
+ CDisableTimerProcessing timerProcessing(*this);
+
+ if (focusedPos < 0)
+ focusedPos = 0;
+
+ _listView.SetRedraw(false);
+ // m_RedrawEnabled = false;
+
+ LVITEM 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();
+ }
+
+ bool isRoot = IsRootFolder();
+ _headerToolBar.EnableButton(kParentFolderID, !IsRootFolder());
+
+ 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 = -1;
+ const int kMaxNameSize = MAX_PATH * 2;
+ TCHAR string[kMaxNameSize];
+ lstrcpyn(string, GetSystemString(itemName), kMaxNameSize);
+ item.pszText = string;
+ UINT32 attributes = FILE_ATTRIBUTE_DIRECTORY;
+ item.iImage = _extToIconMap.GetIconIndex(attributes,
+ GetSystemString(itemName));
+ if (item.iImage < 0)
+ item.iImage = 0;
+ if(_listView.InsertItem(&item) == -1)
+ return;
+ }
+
+ // OutputDebugStringA("S1\n");
+
+ for(int i = 0; i < numItems; i++)
+ {
+ UString itemName = GetItemName(i);
+ if (itemName.CompareNoCase(focusedName) == 0)
+ cursorIndex = _listView.GetItemCount();
+ bool selected = false;
+ if (selectedNames.FindInSorted(itemName) >= 0)
+ selected = true;
+ _selectedStatusVector.Add(selected);
+ /*
+ if (_virtualMode)
+ {
+ _realIndices.Add(i);
+ }
+ else
+ */
+ {
+
+ item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
+ // item.mask = LVIF_TEXT | LVIF_PARAM;
+
+
+ int subItem = 0;
+ item.iItem = _listView.GetItemCount();
+
+ item.iSubItem = subItem++;
+ item.lParam = i;
+
+ const int kMaxNameSize = MAX_PATH * 2;
+ TCHAR string[kMaxNameSize];
+ lstrcpyn(string, GetSystemString(itemName), kMaxNameSize);
+ item.pszText = string;
+
+ 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(GetSystemString(itemName + L"\\"), attributes, iconIndexTemp);
+ item.iImage = iconIndexTemp;
+ }
+ else
+ {
+ item.iImage = _extToIconMap.GetIconIndex(attributes,
+ GetSystemString(itemName));
+ }
+ }
+ if (item.iImage < 0)
+ item.iImage = 0;
+
+ if(_listView.InsertItem(&item) == -1)
+ return; // error
+ }
+ }
+ // OutputDebugStringA("End2\n");
+
+ if(_listView.GetItemCount() > 0 && cursorIndex >= 0)
+ {
+ UINT state = LVIS_FOCUSED | LVIS_SELECTED;
+ _listView.SetItemState(cursorIndex, state, state);
+ }
+ _listView.SortItems(CompareItems, (LPARAM)this);
+ if (cursorIndex < 0 && _listView.GetItemCount() > 0)
+ {
+ if (focusedPos >= _listView.GetItemCount())
+ focusedPos = _listView.GetItemCount() - 1;
+ UINT state = LVIS_FOCUSED | LVIS_SELECTED;
+ _listView.SetItemState(focusedPos, state, state);
+ }
+ // 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);
+ indices.Sort();
+}
+
+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)
+ {
+ int realIndex = GetRealItemIndex(focusedItem);
+ if (realIndex != -1)
+ indices.Add(realIndex);
+ }
+}
+
+void CPanel::EditItem()
+{
+ int focusedItem = _listView.GetFocusedItem();
+ if (focusedItem < 0)
+ return;
+ int realIndex = GetRealItemIndex(focusedItem);
+ if (realIndex == -1)
+ 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(L"Too much items");
+ return;
+ }
+
+ int focusedItem = _listView.GetFocusedItem();
+ if (focusedItem >= 0)
+ {
+ int realIndex = GetRealItemIndex(focusedItem);
+ if (realIndex == -1 && (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 == -1)
+ 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);
+}
+
+
+bool CPanel::IsItemFolder(int itemIndex) const
+{
+ if (itemIndex == -1)
+ 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;
+ throw 21632;
+}
+
+UINT64 CPanel::GetItemSize(int itemIndex) const
+{
+ if (itemIndex == -1)
+ 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 = GetSystemString((const wchar_t *)typeID);
+ ::ReadListViewInfo(_typeIDString, _listViewInfo);
+}
+
+void CPanel::SaveListViewInfo()
+{
+ for(int 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/7zip/FileManager/PanelKey.cpp b/7zip/FileManager/PanelKey.cpp
new file mode 100755
index 00000000..796ab209
--- /dev/null
+++ b/7zip/FileManager/PanelKey.cpp
@@ -0,0 +1,298 @@
+// PanelKey.cpp
+
+#include "StdAfx.h"
+
+#include "Panel.h"
+#include "HelpUtils.h"
+
+#include "../PropID.h"
+#include "App.h"
+
+// static LPCTSTR kHelpTopic = _T("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(UStringVector(), false, shift);
+ return true;
+ }
+ break;
+ }
+ case VK_F6:
+ {
+ if (!alt && !ctrl)
+ {
+ _panelCallback->OnCopy(UStringVector(), true, shift);
+ return true;
+ }
+ break;
+ }
+ /*
+ case VK_F7:
+ {
+ if (!alt && !ctrl && !shift)
+ {
+ CreateFolder();
+ return true;
+ }
+ break;
+ }
+ */
+ case VK_DELETE:
+ {
+ // if (shift)
+ DeleteItems();
+ 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/7zip/FileManager/PanelListNotify.cpp b/7zip/FileManager/PanelListNotify.cpp
new file mode 100755
index 00000000..ec449c68
--- /dev/null
+++ b/7zip/FileManager/PanelListNotify.cpp
@@ -0,0 +1,365 @@
+// 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(LVITEM &item)
+{
+ 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 == (UINT32)-1)
+ return 0;
+ UString string;
+ 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))
+ {
+ string = ConvertSizeToString(ConvertPropVariantToUINT64(propVariant));
+ }
+ else
+ {
+ string = ConvertPropertyToString(propVariant, propID, false);
+ }
+
+ int size = item.cchTextMax;
+ if(size > 0)
+ {
+ if(string.Length() + 1 > size)
+ string = string.Left(size - 1);
+ lstrcpy(item.pszText, GetSystemString(string));
+ }
+ return 0;
+}
+
+extern DWORD g_ComCtl32Version;
+
+bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result)
+{
+ switch(header->code)
+ {
+ /*
+ case LVN_ITEMCHANGED:
+ case LVN_ODSTATECHANGED:
+ {
+ break;
+ }
+ */
+
+ case LVN_GETDISPINFO:
+ {
+ LV_DISPINFO *dispInfo = (LV_DISPINFO *)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 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_BEGINDRAG:
+ case LVN_BEGINRDRAG:
+ {
+ SendRefreshStatusBarMessage();
+ 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:
+ {
+ RefreshStatusBar();
+ if(g_ComCtl32Version >= MAKELONG(71, 4))
+ {
+ OnLeftClick((LPNMITEMACTIVATE)header);
+ }
+ return false;
+ }
+ case LVN_BEGINLABELEDIT:
+ result = OnBeginLabelEdit((LV_DISPINFO *)header);
+ return true;
+ case LVN_ENDLABELEDIT:
+ result = OnEndLabelEdit((LV_DISPINFO *)header);
+ return true;
+
+ case NM_CUSTOMDRAW:
+ return OnCustomDraw((LPNMLVCUSTOMDRAW)header, result);
+ case LVN_BEGINDRAG:
+ case LVN_BEGINRDRAG:
+ {
+ // OnDrag((LPNMLISTVIEW)header);
+ RefreshStatusBar();
+ break;
+ }
+ }
+ 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 = lplvcd->nmcd.lItemlParam;
+ bool selected = false;
+ if (realIndex != -1)
+ 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, GetSystemString(MyFormatNew(IDS_N_SELECTED_ITEMS,
+ 0x02000301, NumberToStringW(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, GetSystemString(selectSizeString));
+
+ int focusedItem = _listView.GetFocusedItem();
+ UString sizeString;
+ UString dateString;
+ // CSysString nameString;
+ if (focusedItem >= 0 && _listView.GetSelectedCount() > 0)
+ {
+ int realIndex = GetRealItemIndex(focusedItem);
+ if (realIndex != -1)
+ {
+ sizeString = ConvertSizeToString(GetItemSize(realIndex));
+ NCOM::CPropVariant propVariant;
+ if (_folder->GetProperty(realIndex, kpidLastWriteTime, &propVariant) == S_OK)
+ dateString = ConvertPropertyToString(propVariant, kpidLastWriteTime, false);
+ }
+ // nameString = GetSystemString(GetItemName(realIndex));
+ }
+ _statusBar.SetText(2, GetSystemString(sizeString));
+ _statusBar.SetText(3, GetSystemString(dateString));
+ // _statusBar.SetText(4, nameString);
+
+
+ /*
+ _statusBar2.SetText(1, GetSystemString(MyFormatNew(L"{0} bytes",
+ NumberToStringW(totalSize))));
+ */
+ // _statusBar.SetText(L"yyy"));
+}
diff --git a/7zip/FileManager/PanelMenu.cpp b/7zip/FileManager/PanelMenu.cpp
new file mode 100755
index 00000000..c7919188
--- /dev/null
+++ b/7zip/FileManager/PanelMenu.cpp
@@ -0,0 +1,429 @@
+#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())
+ return;
+ CRecordVector<UINT32> operatedIndices;
+ GetOperatedItemIndices(operatedIndices);
+ if (operatedIndices.IsEmpty())
+ return;
+ CMyComPtr<IContextMenu> contextMenu;
+ CreateShellContextMenu(operatedIndices, contextMenu);
+
+ 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");
+}
+
+void CPanel::CreateShellContextMenu(
+ const CRecordVector<UINT32> &operatedIndices,
+ CMyComPtr<IContextMenu> &systemContextMenu)
+{
+ systemContextMenu.Release();
+ UString folderPath = GetUnicodeString(_currentFolderPrefix);
+
+ CMyComPtr<IShellFolder> desktopFolder;
+ ::SHGetDesktopFolder(&desktopFolder);
+ if (!desktopFolder)
+ {
+ // ShowMessage("Failed to get Desktop folder.");
+ return;
+ }
+
+ // Separate the file from the folder.
+
+
+ // Get a pidl for the folder the file
+ // is located in.
+ LPITEMIDLIST parentPidl;
+ DWORD eaten;
+ DWORD result = desktopFolder->ParseDisplayName(
+ GetParent(), 0, (wchar_t *)(const wchar_t *)folderPath,
+ &eaten, &parentPidl, 0);
+ if (result != NOERROR)
+ {
+ // ShowMessage("Invalid file name.");
+ return;
+ }
+
+ // Get an IShellFolder for the folder
+ // the file is located in.
+ CMyComPtr<IShellFolder> parentFolder;
+ result = desktopFolder->BindToObject(parentPidl,
+ 0, IID_IShellFolder, (void**)&parentFolder);
+ if (!parentFolder)
+ {
+ // ShowMessage("Invalid file name.");
+ return;
+ }
+
+ // 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 = GetItemName(operatedIndices[i]);
+ HRESULT result = parentFolder->ParseDisplayName(GetParent(), 0,
+ (wchar_t *)(const wchar_t *)fileName, &eaten, &pidl, 0);
+ if (result != NOERROR)
+ return;
+ 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;
+ result = parentFolder->GetUIObjectOf(GetParent(), pidls.Size(),
+ (LPCITEMIDLIST *)&pidls.Front(), IID_IContextMenu, 0, (void**)&cm);
+ if (!cm)
+ {
+ // ShowMessage("Unable to get context menu interface.");
+ return;
+ }
+ systemContextMenu = cm;
+}
+
+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);
+
+
+ MENUITEMINFO menuItem;
+ menuItem.cbSize = sizeof(menuItem);
+ menuItem.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID;
+ menuItem.fType = MFT_STRING;
+ menuItem.hSubMenu = popupMenu.Detach();
+ // menuDestroyer.Disable();
+ CSysString popupMenuCaption = LangLoadString(IDS_SYSTEM, 0x030202A0);
+ menuItem.dwTypeData = (LPTSTR)(LPCTSTR)popupMenuCaption;
+
+ InsertMenuItem(menuSpec, 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;
+ UString currentFolderUnicode;
+ UString folder = GetUnicodeString(_currentFolderPrefix);
+ CSysString currentFolderSys = GetSystemString(_currentFolderPrefix);
+
+ CMyComPtr<IContextMenu> contextMenu;
+ if (contextMenu.CoCreateInstance(CLSID_CZipContextMenu, IID_IContextMenu) == S_OK)
+ {
+ CMyComPtr<IInitContextMenu> initContextMenu;
+ if (contextMenu.QueryInterface(IID_IInitContextMenu,
+ &initContextMenu) != S_OK)
+ return;
+ currentFolderUnicode = GetUnicodeString(_currentFolderPrefix);;
+ UStringVector names;
+ for(int i = 0; i < operatedIndices.Size(); i++)
+ names.Add(currentFolderUnicode + GetItemName(operatedIndices[i]));
+ CRecordVector<const wchar_t *> namePointers;
+ for(i = 0; i < operatedIndices.Size(); i++)
+ namePointers.Add(names[i]);
+
+ ::SetCurrentDirectory(::GetSystemString(_currentFolderPrefix));
+ if (initContextMenu->InitContextMenu(folder, &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, 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(offset);
+ commandInfo.lpParameters = NULL;
+ CSysString currentFolderSys = GetSystemString(_currentFolderPrefix);
+ commandInfo.lpDirectory = (LPCSTR)(LPCTSTR)(currentFolderSys);
+ commandInfo.nShow = SW_SHOW;
+ commandInfo.lpTitle = "";
+ commandInfo.lpVerbW = LPCWSTR(offset);
+ commandInfo.lpParameters = NULL;
+ UString currentFolderUnicode = GetUnicodeString(_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/7zip/FileManager/PanelOperations.cpp b/7zip/FileManager/PanelOperations.cpp
new file mode 100755
index 00000000..51c65cc4
--- /dev/null
+++ b/7zip/FileManager/PanelOperations.cpp
@@ -0,0 +1,269 @@
+// PanelOperations.cpp
+
+#include "StdAfx.h"
+
+#include "resource.h"
+
+#include "Panel.h"
+
+#include "Common/StringConvert.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 "FormatUtils.h"
+
+#include "UpdateCallback100.h"
+
+using namespace NWindows;
+using namespace NFile;
+
+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();
+ }
+};
+
+
+void CPanel::DeleteItems()
+{
+ CMyComPtr<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ {
+ MessageBox(LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
+ return;
+ }
+
+ CRecordVector<UINT32> indices;
+ GetOperatedItemIndices(indices);
+ if (indices.IsEmpty())
+ return;
+ UString title;
+ UString message;
+ if (indices.Size() == 1)
+ {
+ int index = indices[0];
+ const UString itemName = GetItemName(index);
+ if (IsItemFolder(index))
+ {
+ title = LangLoadStringW(IDS_CONFIRM_FOLDER_DELETE, 0x03020211);
+ message = MyFormatNew(IDS_WANT_TO_DELETE_FOLDER, 0x03020214, itemName);
+ }
+ else
+ {
+ title = LangLoadStringW(IDS_CONFIRM_FILE_DELETE, 0x03020210);
+ message = MyFormatNew(IDS_WANT_TO_DELETE_FILE, 0x03020213, itemName);
+ }
+ }
+ else
+ {
+ title = LangLoadStringW(IDS_CONFIRM_ITEMS_DELETE, 0x03020212);
+ message = MyFormatNew(IDS_WANT_TO_DELETE_ITEMS, 0x03020215,
+ NumberToStringW(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 = LangLoadStringW(IDS_DELETING, 0x03020216);
+
+ deleter.UpdateCallbackSpec->ProgressDialog.MainWindow = _mainWindow;
+ deleter.UpdateCallbackSpec->ProgressDialog.MainTitle = LangLoadStringW(IDS_APP_TITLE, 0x03000000);
+ deleter.UpdateCallbackSpec->ProgressDialog.MainAddTitle = progressTitle + UString(L" ");
+
+ deleter.FolderOperations = folderOperations;
+ deleter.Indices = indices;
+
+ CPanel::CDisableTimerProcessing disableTimerProcessing2(*this);
+
+ CThread thread;
+ if (!thread.Create(CThreadDelete::MyThreadFunction, &deleter))
+ throw 271824;
+ deleter.UpdateCallbackSpec->StartProgressDialog(progressTitle);
+
+ HRESULT result = deleter.Result;
+ if (result != S_OK)
+ MessageBoxError(result, LangLoadStringW(IDS_ERROR_DELETING, 0x03020217));
+
+ RefreshListCtrlSaveFocused();
+}
+
+BOOL CPanel::OnBeginLabelEdit(LV_DISPINFO * lpnmh)
+{
+ int realIndex = GetRealIndex(lpnmh->item);
+ if (realIndex == -1)
+ return TRUE;
+ CMyComPtr<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ return TRUE;
+ return FALSE;
+}
+
+BOOL CPanel::OnEndLabelEdit(LV_DISPINFO * 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;
+ }
+ UString newName = GetUnicodeString(lpnmh->item.pszText);
+ CPanel::CDisableTimerProcessing disableTimerProcessing2(*this);
+
+ int realIndex = GetRealIndex(lpnmh->item);
+ if (realIndex == -1)
+ return FALSE;
+ HRESULT result = folderOperations->Rename(realIndex, newName, 0);
+ if (result != S_OK)
+ {
+ MessageBoxError(result, LangLoadStringW(IDS_ERROR_RENAMING, 0x03020221));
+ return FALSE;
+ }
+ // Can't use RefreshListCtrl here.
+ // UStringVector selectedItems;
+ // selectedItems.Add(newName);
+ // RefreshListCtrl(newName, -1, selectedItems);
+ // RefreshListCtrl();
+ PostMessage(kReLoadMessage);
+ return TRUE;
+}
+
+void CPanel::CreateFolder()
+{
+ CMyComPtr<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ {
+ MessageBox(LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
+ return;
+ }
+ CComboDialog comboDialog;
+ comboDialog.Title = LangLoadStringW(IDS_CREATE_FOLDER, 0x03020230);
+ comboDialog.Static = LangLoadStringW(IDS_CREATE_FOLDER_NAME, 0x03020231);
+ comboDialog.Value = LangLoadStringW(IDS_CREATE_FOLDER_DEFAULT_NAME, /*0x03020232*/ (UINT32)-1);
+ if (comboDialog.Create(GetParent()) == IDCANCEL)
+ return;
+ UString newName = GetUnicodeString(comboDialog.Value);
+ CPanel::CDisableTimerProcessing disableTimerProcessing2(*this);
+ HRESULT result = folderOperations->CreateFolder(newName, 0);
+ if (result != S_OK)
+ {
+ MessageBoxError(result, LangLoadStringW(IDS_CREATE_FOLDER_ERROR, 0x03020233));
+ return;
+ }
+ UStringVector selectedNames;
+ GetSelectedNames(selectedNames);
+ int pos = newName.Find(TEXT('\\'));
+ if (pos >= 0)
+ newName = newName.Left(pos);
+ // SetFocus();
+ RefreshListCtrl(newName, _listView.GetFocusedItem(), selectedNames);
+}
+
+void CPanel::CreateFile()
+{
+ CMyComPtr<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ {
+ MessageBox(LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
+ return;
+ }
+ CComboDialog comboDialog;
+ comboDialog.Title = LangLoadStringW(IDS_CREATE_FILE, 0x03020240);
+ comboDialog.Static = LangLoadStringW(IDS_CREATE_FILE_NAME, 0x03020241);
+ comboDialog.Value = LangLoadStringW(IDS_CREATE_FILE_DEFAULT_NAME, /*0x03020242*/ (UINT32)-1);
+ if (comboDialog.Create(GetParent()) == IDCANCEL)
+ return;
+ UString newName = GetUnicodeString(comboDialog.Value);
+ CPanel::CDisableTimerProcessing disableTimerProcessing2(*this);
+ HRESULT result = folderOperations->CreateFile(newName, 0);
+ if (result != S_OK)
+ {
+ MessageBoxError(result, LangLoadStringW(IDS_CREATE_FILE_ERROR, 0x03020243));
+ return;
+ }
+ UStringVector selectedNames;
+ GetSelectedNames(selectedNames);
+ int pos = newName.Find(TEXT('\\'));
+ if (pos >= 0)
+ newName = newName.Left(pos);
+ RefreshListCtrl(newName, _listView.GetFocusedItem(),
+ selectedNames);
+}
+
+void CPanel::RenameFile()
+{
+ int index = _listView.GetFocusedItem();
+ if (index >= 0)
+ _listView.EditLabel(index);
+}
+
+void CPanel::ChangeComment()
+{
+ int index = _listView.GetFocusedItem();
+ if (index < 0)
+ return;
+ int realIndex = GetRealItemIndex(index);
+ if (realIndex == -1)
+ return;
+ CMyComPtr<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ {
+ MessageBox(LangLoadStringW(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 = GetItemName(realIndex);
+ CComboDialog comboDialog;
+ comboDialog.Title = name + L" " + LangLoadStringW(IDS_COMMENT, 0x03020290);
+ comboDialog.Value = comment;
+ comboDialog.Static = LangLoadStringW(IDS_COMMENT2, 0x03020291);
+ if (comboDialog.Create(GetParent()) == IDCANCEL)
+ return;
+ NCOM::CPropVariant propVariant = GetUnicodeString(comboDialog.Value);
+ HRESULT result = folderOperations->SetProperty(realIndex, kpidComment, &propVariant, NULL);
+ if (result != S_OK)
+ {
+ MessageBoxError(result, L"Set Comment Error");
+ }
+ RefreshListCtrlSaveFocused();
+}
+
diff --git a/7zip/FileManager/PanelSelect.cpp b/7zip/FileManager/PanelSelect.cpp
new file mode 100755
index 00000000..5c7024e3
--- /dev/null
+++ b/7zip/FileManager/PanelSelect.cpp
@@ -0,0 +1,239 @@
+// 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()
+{
+ 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 == -1)
+ continue;
+ if (i >= startItem && i <= finishItem)
+ if (_selectedStatusVector[realIndex] != _selectMark)
+ {
+ _selectedStatusVector[realIndex] = _selectMark;
+ _listView.RedrawItem(i);
+ }
+ }
+ _prevFocusedItem = focusedItem;
+}
+
+void CPanel::OnArrowWithShift()
+{
+ int focusedItem = _listView.GetFocusedItem();
+ if (focusedItem < 0)
+ return;
+ int realIndex = GetRealItemIndex(focusedItem);
+ if (_selectionIsDefined)
+ {
+ if (realIndex != -1)
+ _selectedStatusVector[realIndex] = _selectMark;
+ }
+ else
+ {
+ if (realIndex == -1)
+ {
+ _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);
+ if (realIndex != -1)
+ _selectedStatusVector[realIndex] = !_selectedStatusVector[realIndex];
+ _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::SelectSpec(bool selectMode)
+{
+ CComboDialog comboDialog;
+ comboDialog.Title = selectMode ?
+ LangLoadStringW(IDS_SELECT, 0x03020250):
+ LangLoadStringW(IDS_DESELECT, 0x03020251);
+ comboDialog.Static = LangLoadStringW(IDS_SELECT_MASK, 0x03020252);
+ comboDialog.Value = L"*";
+ if (comboDialog.Create(GetParent()) == IDCANCEL)
+ return;
+ UString mask = GetUnicodeString(comboDialog.Value);
+ for (int i = 0; i < _selectedStatusVector.Size(); i++)
+ if (CompareWildCardWithName(mask, GetItemName(i)))
+ _selectedStatusVector[i] = selectMode;
+ _listView.RedrawAllItems();
+}
+
+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 (_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;
+ }
+ }
+ _listView.RedrawAllItems();
+}
+
+void CPanel::SelectAll(bool selectMode)
+{
+ for (int i = 0; i < _selectedStatusVector.Size(); i++)
+ _selectedStatusVector[i] = selectMode;
+ _listView.RedrawAllItems();
+}
+
+void CPanel::InvertSelection()
+{
+ for (int i = 0; i < _selectedStatusVector.Size(); i++)
+ _selectedStatusVector[i] = !_selectedStatusVector[i];
+ _listView.RedrawAllItems();
+}
+
+void CPanel::KillSelection()
+{
+ SelectAll(false);
+}
+
+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 == -1)
+ 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 != -1)
+ {
+ _selectedStatusVector[realIndex] = !_selectedStatusVector[realIndex];
+ _listView.RedrawItem(indexInList);
+ }
+ }
+ }
+ return;
+}
+
diff --git a/7zip/FileManager/PanelSort.cpp b/7zip/FileManager/PanelSort.cpp
new file mode 100755
index 00000000..e2f07df2
--- /dev/null
+++ b/7zip/FileManager/PanelSort.cpp
@@ -0,0 +1,157 @@
+// 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:
+ {
+ UString &name1 = panel->GetItemName(lParam1);
+ UString &name2 = panel->GetItemName(lParam2);
+ return name1.CompareNoCase(name2);
+ }
+ case kpidNoProperty:
+ {
+ return MyCompare(lParam1, lParam2);
+ }
+ case kpidExtension:
+ {
+ UString &ext1 = GetExtension(panel->GetItemName(lParam1));
+ UString &ext2 = GetExtension(panel->GetItemName(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(lParam1, propID, &propVariant1);
+ panel->_folder->GetProperty(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 == -1)
+ return -1;
+ if (lParam2 == -1)
+ return 1;
+
+ CPanel *panel = (CPanel*)lpData;
+
+ bool isDirectory1 = panel->IsItemFolder(lParam1);
+ bool isDirectory2 = panel->IsItemFolder(lParam2);
+
+ if(isDirectory1 && (!isDirectory2))
+ return -1;
+ if((!isDirectory1) && isDirectory2)
+ return 1;
+
+ int result = CompareItems2(lParam1, lParam2, lpData);
+ if(lpData == NULL)
+ return 0;
+ 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/7zip/FileManager/PluginInterface.h b/7zip/FileManager/PluginInterface.h
new file mode 100755
index 00000000..6f781340
--- /dev/null
+++ b/7zip/FileManager/PluginInterface.h
@@ -0,0 +1,44 @@
+// PluginInterface.h
+
+#pragma once
+
+#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/7zip/FileManager/PluginLoader.h b/7zip/FileManager/PluginLoader.h
new file mode 100755
index 00000000..b13edb37
--- /dev/null
+++ b/7zip/FileManager/PluginLoader.h
@@ -0,0 +1,34 @@
+// PluginLoader.h
+
+#pragma once
+
+#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(LPCTSTR filePath, REFGUID clsID, IFolderManager **manager)
+ {
+ if (!Load(filePath))
+ return GetLastError();
+ return CreateManager(clsID, manager);
+ }
+};
+
+#endif \ No newline at end of file
diff --git a/7zip/FileManager/ProgramLocation.cpp b/7zip/FileManager/ProgramLocation.cpp
new file mode 100755
index 00000000..88c18d5e
--- /dev/null
+++ b/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/7zip/FileManager/ProgramLocation.h b/7zip/FileManager/ProgramLocation.h
new file mode 100755
index 00000000..aacda0fa
--- /dev/null
+++ b/7zip/FileManager/ProgramLocation.h
@@ -0,0 +1,12 @@
+// ProgramLocation.h
+
+#pragma once
+
+#ifndef __PROGRAMLOCATION_H
+#define __PROGRAMLOCATION_H
+
+#include "Common/String.h"
+
+bool GetProgramFolderPath(UString &folder); // normalized
+
+#endif
diff --git a/7zip/FileManager/PropertyName.cpp b/7zip/FileManager/PropertyName.cpp
new file mode 100755
index 00000000..96f4d018
--- /dev/null
+++ b/7zip/FileManager/PropertyName.cpp
@@ -0,0 +1,72 @@
+// 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 },
+
+ { 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 LangLoadStringW(pair.ResourceID, pair.LangID);
+}
diff --git a/7zip/FileManager/PropertyName.h b/7zip/FileManager/PropertyName.h
new file mode 100755
index 00000000..d1cee697
--- /dev/null
+++ b/7zip/FileManager/PropertyName.h
@@ -0,0 +1,12 @@
+// PropertyName.h
+
+#pragma once
+
+#ifndef __PROPERTYNAME_H
+#define __PROPERTYNAME_H
+
+#include "Common/String.h"
+
+UString GetNameOfProperty(PROPID propID);
+
+#endif \ No newline at end of file
diff --git a/7zip/FileManager/RegistryAssociations.cpp b/7zip/FileManager/RegistryAssociations.cpp
new file mode 100755
index 00000000..89fb0414
--- /dev/null
+++ b/7zip/FileManager/RegistryAssociations.cpp
@@ -0,0 +1,276 @@
+// 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/System.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 TCHAR *kExtPlugins = TEXT("Plugins");
+static const TCHAR *kExtEnabled = TEXT("Enabled");
+
+bool ReadInternalAssociation(const wchar_t *ext, CExtInfo &extInfo)
+{
+ NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
+ CKey key;
+ if(key.Open(HKEY_CURRENT_USER, CSysString(kCUKeyPath)
+ + CSysString('\\') + CSysString(kAssociations)
+ + CSysString('\\') + CSysString(GetSystemString(ext)),
+ KEY_READ) != ERROR_SUCCESS)
+ return false;
+ CSysString pluginsString;
+ key.QueryValue(kExtPlugins, pluginsString);
+ SplitString(GetUnicodeString(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, CSysString(kCUKeyPath)
+ + CSysString('\\') + CSysString(kAssociations), 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;
+ CSysString pluginsString;
+ key.QueryValue(kExtPlugins, pluginsString);
+ SplitString(GetUnicodeString(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, GetSystemString(JoinStrings(extInfo.Plugins)));
+ // key.SetValue(kExtEnabled, extInfo.Enabled);
+ }
+}
+
+///////////////////////////////////
+// External
+
+static const TCHAR *kShellNewKeyName = TEXT("ShellNew");
+static const TCHAR *kShellNewDataValueName = TEXT("Data");
+
+static const TCHAR *kDefaultIconKeyName = TEXT("DefaultIcon");
+static const TCHAR *kShellKeyName = TEXT("shell");
+static const TCHAR *kOpenKeyName = TEXT("open");
+static const TCHAR *kCommandKeyName = TEXT("command");
+
+static const TCHAR *kOpenCommandValue = TEXT("7zFMn.exe \"%1\"");
+
+static CSysString GetExtensionKeyName(const CSysString &extension)
+{
+ return CSysString(TEXT(".")) + extension;
+}
+
+static CSysString GetExtProgramKeyName(const CSysString &extension)
+{
+ return CSysString(TEXT("7-Zip.")) + extension;
+}
+
+bool CheckShellExtensionInfo(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);
+ if (programNameValue.CollateNoCase(extProgramKeyName) != 0)
+ return false;
+ CKey extProgKey;
+ return (extProgKey.Open(HKEY_CLASSES_ROOT, extProgramKeyName, 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 (CheckShellExtensionInfo(extension))
+ DeleteShellExtensionKey(extension);
+ DeleteShellExtensionProgramKey(extension);
+}
+
+void AddShellExtensionInfo(const CSysString &extension,
+ const CSysString &programTitle,
+ const CSysString &programOpenCommand,
+ const CSysString &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);
+
+ CSysString params;
+ /*
+ if (!NSystem::MyGetWindowsDirectory(aParams))
+ {
+ aParams.Empty();
+ // return;
+ }
+ else
+ NFile::NName::NormalizeDirPathPrefix(aParams);
+ */
+ // aParams += kOpenCommandValue;
+ HRESULT result = 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.CollateNoCase(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/7zip/FileManager/RegistryAssociations.h b/7zip/FileManager/RegistryAssociations.h
new file mode 100755
index 00000000..a55c36d6
--- /dev/null
+++ b/7zip/FileManager/RegistryAssociations.h
@@ -0,0 +1,48 @@
+// RegistryAssociations.h
+
+#pragma once
+
+#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 CSysString &programTitle,
+ const CSysString &programOpenCommand,
+ const CSysString &iconPath,
+ const void *shellNewData, int shellNewDataSize);
+
+
+ ///////////////////////////
+ // ContextMenu
+ /*
+ bool CheckContextMenuHandler();
+ void AddContextMenuHandler();
+ void DeleteContextMenuHandler();
+ */
+
+}
+
+// bool GetProgramDirPrefix(CSysString &aFolder);
+
+
+#endif \ No newline at end of file
diff --git a/7zip/FileManager/RegistryPlugins.cpp b/7zip/FileManager/RegistryPlugins.cpp
new file mode 100755
index 00000000..b491876a
--- /dev/null
+++ b/7zip/FileManager/RegistryPlugins.cpp
@@ -0,0 +1,144 @@
+// 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;
+}
+
+CSysString GetProgramFolderPrefix();
+
+static bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+
+void ReadPluginInfoList(CObjectVector<CPluginInfo> &plugins)
+{
+ plugins.Clear();
+
+ CSysString baseFolderPrefix = GetProgramFolderPrefix();
+ {
+ CSysString path = baseFolderPrefix + TEXT("7-zip");
+ if (IsItWindowsNT())
+ path += TEXT("n");
+ path += TEXT(".dll");
+ CPluginInfo pluginInfo;
+ pluginInfo.FilePath = path;
+
+ if (::ReadPluginInfo(pluginInfo))
+ plugins.Add(pluginInfo);
+ }
+ CSysString folderPath = baseFolderPrefix + TEXT("Plugins\\");
+ NFind::CEnumerator enumerator(folderPath + TEXT("*"));
+ NFind::CFileInfo 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/7zip/FileManager/RegistryPlugins.h b/7zip/FileManager/RegistryPlugins.h
new file mode 100755
index 00000000..9f19b3bf
--- /dev/null
+++ b/7zip/FileManager/RegistryPlugins.h
@@ -0,0 +1,35 @@
+// RegistryPlugins.h
+
+#pragma once
+
+#ifndef __REGISTRYPLUGINS_H
+#define __REGISTRYPLUGINS_H
+
+#include "Common/Vector.h"
+#include "Common/String.h"
+
+enum EPluginType
+{
+ kPluginTypeFF = 0
+};
+
+struct CPluginInfo
+{
+ CSysString 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/7zip/FileManager/RegistrySystem.cpp b/7zip/FileManager/RegistrySystem.cpp
new file mode 100755
index 00000000..1d1cc940
--- /dev/null
+++ b/7zip/FileManager/RegistrySystem.cpp
@@ -0,0 +1,152 @@
+// ZipRegistryMain.cpp
+
+#include "StdAfx.h"
+
+#include "ZipRegistryMain.h"
+
+#ifndef NO_REGISTRY
+
+#include "Windows/COM.h"
+#include "Windows/Synchronization.h"
+#include "Windows/Registry.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileName.h"
+
+using namespace NZipSettings;
+
+using namespace NWindows;
+using namespace NCOM;
+using namespace NRegistry;
+
+#endif
+
+namespace NZipRootRegistry {
+
+#ifndef NO_REGISTRY
+//////////////////////////////////
+static const TCHAR *kLMBasePath = _T("Software\\7-ZIP");
+// m_LMKey.Create(HKEY_LOCAL_MACHINE, kLMBasePath);
+
+static const TCHAR *kArchiversKeyName = _T("Archivers");
+
+namespace NArchiveType
+{
+ static const TCHAR *kExtension = _T("Extension");
+ static const TCHAR *kAddExtension = _T("AddExtension");
+ static const TCHAR *kUpdate = _T("Update");
+ static const TCHAR *kKeepName = _T("KeepName");
+}
+
+static NSynchronization::CCriticalSection g_RegistryOperationsCriticalSection;
+
+static CSysString GetArchiversKeyName()
+{
+ return CSysString(kLMBasePath) + CSysString(kKeyNameDelimiter) +
+ CSysString(kArchiversKeyName);
+}
+#endif
+
+void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &anInfoList)
+{
+ anInfoList.Clear();
+
+ #ifdef NO_REGISTRY
+
+ CArchiverInfo anItemInfo;
+ #ifdef FORMAT_7Z
+ anItemInfo.UpdateEnabled = true;
+ anItemInfo.KeepName = false;
+ anItemInfo.Name = TEXT("7z");
+ anItemInfo.Extension = TEXT("7z");
+ anInfoList.Add(anItemInfo);
+ #endif
+
+ #ifdef FORMAT_BZIP2
+ anItemInfo.UpdateEnabled = true;
+ anItemInfo.KeepName = true;
+ anItemInfo.Name = TEXT("BZip2");
+ anItemInfo.Extension = TEXT("bz2");
+ anInfoList.Add(anItemInfo);
+ #endif
+
+ #ifdef FORMAT_GZIP
+ anItemInfo.UpdateEnabled = true;
+ anItemInfo.KeepName = false;
+ anItemInfo.Name = TEXT("GZip");
+ anItemInfo.Extension = TEXT("gz");
+ anInfoList.Add(anItemInfo);
+ #endif
+
+ #ifdef FORMAT_TAR
+ anItemInfo.UpdateEnabled = true;
+ anItemInfo.KeepName = false;
+ anItemInfo.Name = TEXT("Tar");
+ anItemInfo.Extension = TEXT("tar");
+ anInfoList.Add(anItemInfo);
+ #endif
+
+ #ifdef FORMAT_ZIP
+ anItemInfo.UpdateEnabled = true;
+ anItemInfo.KeepName = false;
+ anItemInfo.Name = TEXT("Zip");
+ anItemInfo.Extension = TEXT("zip");
+ anInfoList.Add(anItemInfo);
+ #endif
+
+ #ifdef FORMAT_CPIO
+ anItemInfo.UpdateEnabled = false;
+ anItemInfo.Name = TEXT("cpio");
+ anItemInfo.Extension = TEXT("cpio");
+ anInfoList.Add(anItemInfo);
+ #endif
+
+ #ifdef FORMAT_RPM
+ anItemInfo.UpdateEnabled = false;
+ anItemInfo.Name = TEXT("RPM");
+ anItemInfo.Extension = TEXT("rpm");
+ anItemInfo.AddExtension = TEXT(".cpio.gz");
+ anInfoList.Add(anItemInfo);
+ #endif
+
+ #ifdef FORMAT_ARJ
+ anItemInfo.UpdateEnabled = false;
+ anItemInfo.Name = TEXT("arj");
+ anItemInfo.Extension = TEXT("arj");
+ anInfoList.Add(anItemInfo);
+ #endif
+
+ #else
+
+ NSynchronization::CSingleLock aLock(&g_RegistryOperationsCriticalSection, true);
+
+ CKey anArchiversKey;
+ if(anArchiversKey.Open(HKEY_LOCAL_MACHINE, GetArchiversKeyName(), KEY_READ) != ERROR_SUCCESS)
+ return;
+
+ CSysStringVector aClassIDs;
+ anArchiversKey.EnumKeys(aClassIDs);
+ for(int i = 0; i < aClassIDs.Size(); i++)
+ {
+ const CSysString aClassIDString = aClassIDs[i];
+ CArchiverInfo anItemInfo;
+ anItemInfo.UpdateEnabled = false;
+ anItemInfo.KeepName = false;
+ CKey aClassIDKey;
+ if(aClassIDKey.Open(anArchiversKey, aClassIDString, KEY_READ) != ERROR_SUCCESS)
+ return;
+
+ if(StringToGUID(aClassIDString, anItemInfo.ClassID) != NOERROR)
+ return; // test it maybe creation;
+ aClassIDKey.QueryValue(NULL, anItemInfo.Name);
+ aClassIDKey.QueryValue(NArchiveType::kExtension, anItemInfo.Extension);
+ aClassIDKey.QueryValue(NArchiveType::kAddExtension, anItemInfo.AddExtension);
+ aClassIDKey.QueryValue(NArchiveType::kUpdate, anItemInfo.UpdateEnabled);
+ aClassIDKey.QueryValue(NArchiveType::kKeepName, anItemInfo.KeepName);
+ anInfoList.Add(anItemInfo);
+ }
+ #endif
+}
+
+}
+
diff --git a/7zip/FileManager/RegistrySystem.h b/7zip/FileManager/RegistrySystem.h
new file mode 100755
index 00000000..2a59e6e0
--- /dev/null
+++ b/7zip/FileManager/RegistrySystem.h
@@ -0,0 +1,28 @@
+// ZipRegistryMain.h
+
+#pragma once
+
+#ifndef __ZIPREGISTRYMAIN_H
+#define __ZIPREGISTRYMAIN_H
+
+#include "ZipSettings.h"
+
+namespace NZipRootRegistry {
+
+ struct CArchiverInfo
+ {
+ #ifndef NO_REGISTRY
+ CLSID ClassID;
+ #endif
+ CSysString Name;
+ CSysString Extension;
+ CSysString AddExtension;
+ bool UpdateEnabled;
+ bool KeepName;
+ };
+
+ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &anInfoList);
+}
+
+
+#endif \ No newline at end of file
diff --git a/7zip/FileManager/RegistryUtils.cpp b/7zip/FileManager/RegistryUtils.cpp
new file mode 100755
index 00000000..470d3eb5
--- /dev/null
+++ b/7zip/FileManager/RegistryUtils.cpp
@@ -0,0 +1,84 @@
+// 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 *kLangValueName = TEXT("Lang");
+static const TCHAR *kEditorValueName = TEXT("Editor");
+static const TCHAR *kShowDotsValueName = TEXT("ShowDots");
+static const TCHAR *kShowRealFileIconsValueName = TEXT("ShowRealFileIcons");
+static const TCHAR *kShowSystemMenuValueName = TEXT("ShowSystemMenu");
+
+void SaveRegLang(const CSysString &langFile)
+{
+ CKey cuKey;
+ cuKey.Create(HKEY_CURRENT_USER, kCUBasePath);
+ cuKey.SetValue(kLangValueName, langFile);
+}
+
+void ReadRegLang(CSysString &langFile)
+{
+ langFile.Empty();
+ CKey cuKey;
+ cuKey.Create(HKEY_CURRENT_USER, kCUBasePath);
+ cuKey.QueryValue(kLangValueName, langFile);
+}
+
+void SaveRegEditor(const CSysString &editorPath)
+{
+ CKey cuKey;
+ cuKey.Create(HKEY_CURRENT_USER, kCU_FMPath);
+ cuKey.SetValue(kEditorValueName, editorPath);
+}
+
+void ReadRegEditor(CSysString &editorPath)
+{
+ editorPath.Empty();
+ CKey cuKey;
+ cuKey.Create(HKEY_CURRENT_USER, kCU_FMPath);
+ cuKey.QueryValue(kEditorValueName, editorPath);
+ /*
+ if (editorPath.IsEmpty())
+ editorPath = TEXT("notepad.exe");
+ */
+}
+
+static void SaveOption(const TCHAR *value, bool enabled)
+{
+ CKey cuKey;
+ cuKey.Create(HKEY_CURRENT_USER, kCU_FMPath);
+ cuKey.SetValue(value, enabled);
+}
+
+static bool ReadOption(const TCHAR *value, bool defaultValue)
+{
+ CKey cuKey;
+ cuKey.Create(HKEY_CURRENT_USER, kCU_FMPath);
+ bool enabled;
+ if (cuKey.QueryValue(value, enabled) != ERROR_SUCCESS)
+ return defaultValue;
+ return enabled;
+}
+
+void SaveShowDots(bool showDots)
+ { SaveOption(kShowDotsValueName, showDots); }
+bool ReadShowDots()
+ { return ReadOption(kShowDotsValueName, false); }
+
+void SaveShowRealFileIcons(bool show)
+ { SaveOption(kShowRealFileIconsValueName, show); }
+bool ReadShowRealFileIcons()
+ { return ReadOption(kShowRealFileIconsValueName, false); }
+
+void SaveShowSystemMenu(bool show)
+ { SaveOption(kShowSystemMenuValueName, show); }
+bool ReadShowSystemMenu()
+ { return ReadOption(kShowSystemMenuValueName, false); }
diff --git a/7zip/FileManager/RegistryUtils.h b/7zip/FileManager/RegistryUtils.h
new file mode 100755
index 00000000..dade674b
--- /dev/null
+++ b/7zip/FileManager/RegistryUtils.h
@@ -0,0 +1,25 @@
+// RegistryUtils.h
+
+#pragma once
+
+#include "Common/StringConvert.h"
+
+#ifndef __REGISTRYUTILS_H
+#define __REGISTRYUTILS_H
+
+void SaveRegLang(const CSysString &langFile);
+void ReadRegLang(CSysString &langFile);
+
+void SaveRegEditor(const CSysString &langFile);
+void ReadRegEditor(CSysString &langFile);
+
+void SaveShowDots(bool showDots);
+bool ReadShowDots();
+
+void SaveShowRealFileIcons(bool show);
+bool ReadShowRealFileIcons();
+
+void SaveShowSystemMenu(bool showSystemMenu);
+bool ReadShowSystemMenu();
+
+#endif \ No newline at end of file
diff --git a/7zip/FileManager/Resource/AboutDialog/7zipLogo.ico b/7zip/FileManager/Resource/AboutDialog/7zipLogo.ico
new file mode 100755
index 00000000..973241c8
--- /dev/null
+++ b/7zip/FileManager/Resource/AboutDialog/7zipLogo.ico
Binary files differ
diff --git a/7zip/FileManager/Resource/AboutDialog/AboutDialog.cpp b/7zip/FileManager/Resource/AboutDialog/AboutDialog.cpp
new file mode 100755
index 00000000..7631f9fe
--- /dev/null
+++ b/7zip/FileManager/Resource/AboutDialog/AboutDialog.cpp
@@ -0,0 +1,66 @@
+// AboutDialog.cpp
+
+#include "StdAfx.h"
+
+#include "resource.h"
+#include "AboutDialog.h"
+#include "Common/String.h"
+#include "../../HelpUtils.h"
+#include "../../LangUtils.h"
+
+static CIDLangPair kIDLangPairs[] =
+{
+ { IDC_ABOUT_STATIC_REGISTER_INFO, 0x01000103 },
+ { IDC_ABOUT_BUTTON_REGISTER, 0x01000105 },
+ { IDOK, 0x02000702 }
+};
+
+static LPCTSTR kHomePageURL = TEXT("http://www.7-zip.org/");
+// static LPCTSTR kRegisterRegNowURL = TEXT("https://secure.shareit.com/shareit/checkout.html?PRODUCT[104808]=1&languageid=1");
+static LPCTSTR kRegisterRegNowURL = TEXT("https://www.regnow.com/softsell/nph-softsell.cgi?item=2521-1&vreferrer=program");
+
+static LPCTSTR kEmailAction =
+ TEXT("mailto:support@7-zip.org?subject=7-Zip");
+
+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);
+}
+
+bool CAboutDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch(buttonID)
+ {
+ case IDC_ABOUT_BUTTON_HOMEPAGE:
+ ::ShellExecute(NULL, NULL, kHomePageURL, NULL, NULL, SW_SHOWNORMAL);
+ break;
+ case IDC_ABOUT_BUTTON_REGISTER:
+ {
+ LPCTSTR registerURL = kRegisterRegNowURL;
+ /*
+ LCID aLCID = ::GetUserDefaultLCID();
+ if (aLCID == 0x0419 || aLCID == 0x422 || aLCID == 0x0423)
+ registerURL = TEXT("http://www.7-zip.org/ru/donate.html");
+ */
+ ::ShellExecute(NULL, NULL, registerURL, NULL, NULL, SW_SHOWNORMAL);
+ break;
+ }
+ case IDC_ABOUT_BUTTON_EMAIL:
+ {
+ ::ShellExecute(NULL, NULL, kEmailAction, NULL, NULL, SW_SHOWNORMAL);
+ break;
+ }
+ default:
+ return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
+ }
+ return true;
+}
diff --git a/7zip/FileManager/Resource/AboutDialog/AboutDialog.h b/7zip/FileManager/Resource/AboutDialog/AboutDialog.h
new file mode 100755
index 00000000..e1ff98ee
--- /dev/null
+++ b/7zip/FileManager/Resource/AboutDialog/AboutDialog.h
@@ -0,0 +1,21 @@
+// AboutDialog.h
+
+#pragma once
+
+#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 aWndParent = 0)
+ { return CModalDialog::Create(MAKEINTRESOURCE(IDD_ABOUT), aWndParent); }
+};
+
+#endif
diff --git a/7zip/FileManager/Resource/AboutDialog/resource.h b/7zip/FileManager/Resource/AboutDialog/resource.h
new file mode 100755
index 00000000..23539a37
--- /dev/null
+++ b/7zip/FileManager/Resource/AboutDialog/resource.h
@@ -0,0 +1,21 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#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_EMAIL 1021
+#define IDC_ABOUT_BUTTON_REGISTER 1022
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 139
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1023
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/FileManager/Resource/AboutDialog/resource.rc b/7zip/FileManager/Resource/AboutDialog/resource.rc
new file mode 100755
index 00000000..600fc863
--- /dev/null
+++ b/7zip/FileManager/Resource/AboutDialog/resource.rc
@@ -0,0 +1,117 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_LOGO ICON DISCARDABLE "7zipLogo.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUT DIALOG DISCARDABLE 0, 0, 237, 172
+STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "About 7-Zip"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ PUSHBUTTON "OK",IDOK,180,151,50,14
+ PUSHBUTTON "www.7-zip.org",IDC_ABOUT_BUTTON_HOMEPAGE,136,7,94,14
+ PUSHBUTTON "support@7-zip.org",IDC_ABOUT_BUTTON_EMAIL,136,30,94,14
+ PUSHBUTTON "Register",IDC_ABOUT_BUTTON_REGISTER,136,53,94,14
+ ICON IDI_LOGO,IDC_STATIC,7,7,20,20,SS_REALSIZEIMAGE
+ LTEXT "7-Zip 3.13",IDC_STATIC,7,54,119,9
+ LTEXT "Copyright (c) 1999-2003 Igor Pavlov",IDC_STATIC,7,67,
+ 119,17
+ LTEXT "7-Zip is free software. However, you can support development of 7-Zip by registering. As registered user, you will be able to get technical support.",
+ IDC_ABOUT_STATIC_REGISTER_INFO,7,91,223,54
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_ABOUT, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 230
+ VERTGUIDE, 126
+ VERTGUIDE, 136
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 165
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp b/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp
new file mode 100755
index 00000000..a0eb020b
--- /dev/null
+++ b/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp
@@ -0,0 +1,939 @@
+// BenchmarkDialog.cpp
+
+#include "StdAfx.h"
+
+#include "Common/IntToString.h"
+#include "Common/StringToInt.h"
+#include "Common/Exception.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;
+public:
+ UINT32 BufferSize;
+ BYTE *Buffer;
+ CBenchRandomGenerator(): Buffer(0) {}
+ ~CBenchRandomGenerator() { delete []Buffer; }
+ void Init() { RG.Init(); }
+ void Set(UINT32 bufferSize)
+ {
+ delete []Buffer;
+ Buffer = 0;
+ Buffer = new BYTE[bufferSize];
+ Pos = 0;
+ BufferSize = bufferSize;
+ }
+ 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 GetLen()
+ {
+ if (GetRndBit() == 0)
+ return RG.GetRnd(2);
+ if (GetRndBit() == 0)
+ return 4 + RG.GetRnd(3);
+ return 12 + RG.GetRnd(4);
+ }
+ void Generate()
+ {
+ while(Pos < BufferSize)
+ {
+ if (GetRndBit() == 0 || Pos < 1)
+ Buffer[Pos++] = BYTE(RG.GetRnd(8));
+ else
+ {
+ UINT32 offset = GetOffset();
+ while (offset >= Pos)
+ offset >>= 1;
+ offset += 1;
+ UINT32 len = 2 + GetLen();
+ for (UINT32 i = 0; i < len && Pos < BufferSize; i++, Pos++)
+ Buffer[Pos] = Buffer[Pos - offset];
+ }
+ }
+ }
+};
+
+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 < 28; i++)
+ for (int j = 0; j < 2; j++)
+ {
+ UINT32 dictionary = (1 << i) + (j << (i - 1));
+ TCHAR s[40];
+ ConvertUINT64ToString((dictionary >> 20), s);
+ lstrcat(s, kMB);
+ int index = 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)
+ { return ((UINT64)dictionary * 19 / 2) + (8 << 20); }
+
+static UINT64 GetMemoryUsage(UINT32 dictionary)
+{
+ const UINT32 kBufferSize = dictionary + kAdditionalSize;
+ const UINT32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize;
+ return kBufferSize + kCompressedBufferSize +
+ GetLZMAUsage(dictionary) + dictionary + (1 << 20);
+}
+
+UINT32 CBenchmarkDialog::OnChangeDictionary()
+{
+ UINT64 dictionary = m_Dictionary.GetItemData(m_Dictionary.GetCurSel());
+ UINT64 memUsage = GetMemoryUsage(dictionary);
+ 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) - (19 << kSubBits);
+ UINT64 numCommandsForOne = 2000 + ((t * t * 68) >> (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 * 250 + 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);
+ STDMETHOD(ReadPart)(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;
+}
+
+STDMETHODIMP CBenchmarkInStream::ReadPart(void *data, UINT32 size, UINT32 *processedSize)
+{
+ return Read(data, size, processedSize);
+}
+
+class CBenchmarkOutStream:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ UINT32 BufferSize;
+public:
+ UINT32 Pos;
+ BYTE *Buffer;
+ CBenchmarkOutStream(): Buffer(0) {}
+ ~CBenchmarkOutStream() { delete []Buffer; }
+ void Init(UINT32 bufferSize)
+ {
+ delete []Buffer;
+ Buffer = 0;
+ Buffer = new BYTE[bufferSize];
+ Pos = 0;
+ BufferSize = bufferSize;
+ }
+ MY_UNKNOWN_IMP
+ STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize);
+ STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize);
+};
+
+STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UINT32 size, UINT32 *processedSize)
+{
+ 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;
+}
+
+STDMETHODIMP CBenchmarkOutStream::WritePart(const void *data, UINT32 size, UINT32 *processedSize)
+{
+ return Write(data, size, processedSize);
+}
+
+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);
+ STDMETHOD(WritePart)(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;
+}
+
+STDMETHODIMP CCompareOutStream::WritePart(const void *data, UINT32 size, UINT32 *processedSize)
+{
+ return Write(data, size, processedSize);
+}
+
+typedef UINT32 (WINAPI * CreateObjectPointer)(const GUID *clsID,
+ const GUID *interfaceID, void **outObject);
+
+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;
+ DWORD Process();
+ static DWORD WINAPI MyThreadFunction(void *param)
+ {
+ return ((CThreadBenchmark *)param)->Process();
+ }
+ MY_UNKNOWN_IMP
+ STDMETHOD(SetRatioInfo)(const UINT64 *inSize, const UINT64 *outSize);
+};
+
+DWORD CThreadBenchmark::Process()
+{
+ try
+ {
+ SyncInfo->WaitCreating();
+ CBenchRandomGenerator randomGenerator;
+ randomGenerator.Init();
+ CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
+ Encoder.QueryInterface(IID_ICompressWriteCoderProperties,
+ &writeCoderProperties);
+ CMyComPtr<ICompressSetDecoderProperties> compressSetDecoderProperties;
+ Decoder.QueryInterface(
+ IID_ICompressSetDecoderProperties, &compressSetDecoderProperties);
+ CSequentialOutStreamImp *propStreamSpec = 0;
+ CMyComPtr<ISequentialOutStream> propStream;
+ if (writeCoderProperties != NULL)
+ {
+ propStreamSpec = new CSequentialOutStreamImp;
+ propStream = propStreamSpec;
+ }
+
+ CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
+ Encoder.QueryInterface(IID_ICompressSetCoderProperties,
+ &setCoderProperties);
+
+ CBenchmarkInStream *propDecoderStreamSpec = 0;
+ CMyComPtr<ISequentialInStream> propDecoderStream;
+ if (compressSetDecoderProperties)
+ {
+ propDecoderStreamSpec = new CBenchmarkInStream;
+ propDecoderStream = propDecoderStreamSpec;
+ }
+
+ CDecoderProgressInfo *decoderProgressInfoSpec = new
+ CDecoderProgressInfo;
+ CMyComPtr<ICompressProgressInfo> decoderProgress = decoderProgressInfoSpec;
+ decoderProgressInfoSpec->SyncInfo = SyncInfo;
+
+ while(true)
+ {
+ 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);
+ RINOK(setCoderProperties->SetCoderProperties(propIDs,
+ properties, kNumProps));
+ }
+
+ if (propStream)
+ {
+ propStreamSpec->Init();
+ writeCoderProperties->WriteCoderProperties(propStream);
+ }
+
+ randomGenerator.Set(kBufferSize);
+ 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;
+ inStreamSpec->Init(randomGenerator.Buffer, randomGenerator.BufferSize);
+ CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
+ CBenchmarkOutStream *outStreamSpec = new CBenchmarkOutStream;
+ outStreamSpec->Init(kCompressedBufferSize);
+ CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
+ _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)
+ {
+ propDecoderStreamSpec->Init(
+ propStreamSpec->GetBuffer(), propStreamSpec->GetSize());
+ RINOK(compressSetDecoderProperties->SetDecoderProperties(propDecoderStream));
+ }
+
+ 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/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.h b/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.h
new file mode 100755
index 00000000..a70fd621
--- /dev/null
+++ b/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.h
@@ -0,0 +1,142 @@
+// BenchmarkDialog.h
+
+#pragma once
+
+#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(MAKEINTRESOURCE(IDD_DIALOG_BENCHMARK), wndParent);
+ }
+};
+
+void Benchmark(HWND hwnd);
+
+#endif
diff --git a/7zip/FileManager/Resource/BenchmarkDialog/resource.h b/7zip/FileManager/Resource/BenchmarkDialog/resource.h
new file mode 100755
index 00000000..e7aadde9
--- /dev/null
+++ b/7zip/FileManager/Resource/BenchmarkDialog/resource.h
@@ -0,0 +1,49 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#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
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 157
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1070
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/FileManager/Resource/BenchmarkDialog/resource.rc b/7zip/FileManager/Resource/BenchmarkDialog/resource.rc
new file mode 100755
index 00000000..745a0823
--- /dev/null
+++ b/7zip/FileManager/Resource/BenchmarkDialog/resource.rc
@@ -0,0 +1,149 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALOG_BENCHMARK DIALOG DISCARDABLE 0, 0, 219, 242
+STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP |
+ WS_CAPTION | WS_SYSMENU
+CAPTION "Benchmark"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ PUSHBUTTON "&Restart",IDC_BUTTON_RESTART,151,7,62,14
+ PUSHBUTTON "&Stop",IDC_BUTTON_STOP,151,27,62,14
+ PUSHBUTTON "&Help",IDHELP,82,221,62,14
+ PUSHBUTTON "Cancel",IDCANCEL,151,221,62,14
+ LTEXT "&Dictionary size:",IDC_BENCHMARK_DICTIONARY,7,8,75,8
+ COMBOBOX IDC_BENCHMARK_COMBO_DICTIONARY,88,7,44,140,
+ CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "Memory usage:",IDC_BENCHMARK_MEMORY,7,25,75,8
+ LTEXT "0 MB",IDC_BENCHMARK_MEMORY_VALUE,88,25,44,8
+ CONTROL "Multi-threading",IDC_BENCHMARK_MULTITHREADING,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,7,41,75,10
+ RTEXT "Speed",IDC_BENCHMARK_SPEED_LABEL,82,53,64,8
+ RTEXT "Rating",IDC_BENCHMARK_RATING_LABEL,151,53,51,8
+ GROUPBOX "Compressing",IDC_BENCHMARK_COMPRESSING,7,64,205,40
+ LTEXT "Current",IDC_BENCHMARK_CURRENT,17,76,65,8
+ RTEXT "100 KB/s",IDC_BENCHMARK_COMPRESSING_SPEED,82,76,64,8
+ RTEXT "0",IDC_BENCHMARK_COMPRESSING_RATING,151,76,51,8
+ LTEXT "Resulting",IDC_BENCHMARK_RESULTING,17,89,65,8
+ RTEXT "100 KB/s",IDC_BENCHMARK_COMPRESSING_SPEED2,82,89,64,8
+ RTEXT "0",IDC_BENCHMARK_COMPRESSING_RATING2,151,89,51,8
+ GROUPBOX "Decompressing",IDC_BENCHMARK_DECOMPRESSING,7,111,205,40
+ LTEXT "Current",IDC_BENCHMARK_CURRENT2,17,123,65,8
+ RTEXT "100 KB/s",IDC_BENCHMARK_DECOMPRESSING_SPEED,82,123,64,8
+ RTEXT "0",IDC_BENCHMARK_DECOMPRESSING_RATING,151,123,51,8
+ LTEXT "Resulting",IDC_BENCHMARK_RESULTING2,17,136,65,8
+ RTEXT "100 KB/s",IDC_BENCHMARK_DECOMPRESSING_SPEED2,82,136,64,
+ 8
+ RTEXT "0",IDC_BENCHMARK_DECOMPRESSING_RATING2,151,136,51,8
+ GROUPBOX "Total Rating",IDC_BENCHMARK_TOTAL_RATING,137,162,75,38
+ RTEXT "0",IDC_BENCHMARK_TOTAL_RATING_VALUE,146,180,56,8
+ LTEXT "Elapsed time:",IDC_BENCHMARK_ELAPSED,7,163,58,8
+ RTEXT "00:00:00",IDC_BENCHMARK_ELAPSED_VALUE,65,163,36,8
+ LTEXT "Size:",IDC_BENCHMARK_SIZE,7,176,58,8
+ RTEXT "0",IDC_BENCHMARK_SIZE_VALUE,65,176,36,8
+ LTEXT "Passes:",IDC_BENCHMARK_PASSES,7,189,58,8
+ RTEXT "0",IDC_BENCHMARK_PASSES_VALUE,65,189,36,8
+ LTEXT "Errors:",IDC_BENCHMARK_ERRORS,7,202,58,8
+ RTEXT "0",IDC_BENCHMARK_ERRORS_VALUE,65,202,36,8
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_DIALOG_BENCHMARK, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 212
+ VERTGUIDE, 17
+ VERTGUIDE, 65
+ VERTGUIDE, 82
+ VERTGUIDE, 88
+ VERTGUIDE, 101
+ VERTGUIDE, 132
+ VERTGUIDE, 146
+ VERTGUIDE, 151
+ VERTGUIDE, 202
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 235
+ HORZGUIDE, 24
+ HORZGUIDE, 53
+ HORZGUIDE, 76
+ HORZGUIDE, 89
+ HORZGUIDE, 123
+ HORZGUIDE, 136
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/7zip/FileManager/Resource/ComboDialog/ComboDialog.cpp b/7zip/FileManager/Resource/ComboDialog/ComboDialog.cpp
new file mode 100755
index 00000000..2dc42ee0
--- /dev/null
+++ b/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/7zip/FileManager/Resource/ComboDialog/ComboDialog.h b/7zip/FileManager/Resource/ComboDialog/ComboDialog.h
new file mode 100755
index 00000000..29cc789c
--- /dev/null
+++ b/7zip/FileManager/Resource/ComboDialog/ComboDialog.h
@@ -0,0 +1,29 @@
+// ComboDialog.h
+
+#pragma once
+
+#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;
+ CSysStringVector Strings;
+
+ // CComboDialog(): Sorted(false) {};
+ INT_PTR Create(HWND parentWindow = 0)
+ { return CModalDialog::Create(MAKEINTRESOURCE(IDD_DIALOG_COMBO), parentWindow); }
+};
+
+#endif
diff --git a/7zip/FileManager/Resource/ComboDialog/resource.h b/7zip/FileManager/Resource/ComboDialog/resource.h
new file mode 100755
index 00000000..8c120fe1
--- /dev/null
+++ b/7zip/FileManager/Resource/ComboDialog/resource.h
@@ -0,0 +1,21 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+
+#define IDD_DIALOG_COMBO 200
+
+#define IDC_COMBO_STATIC 1000
+#define IDC_COMBO_COMBO 1001
+
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 157
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1002
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/FileManager/Resource/ComboDialog/resource.rc b/7zip/FileManager/Resource/ComboDialog/resource.rc
new file mode 100755
index 00000000..8f749912
--- /dev/null
+++ b/7zip/FileManager/Resource/ComboDialog/resource.rc
@@ -0,0 +1,100 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALOG_COMBO DIALOG DISCARDABLE 0, 0, 247, 71
+STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Combo"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ COMBOBOX IDC_COMBO_COMBO,7,20,233,65,CBS_DROPDOWN |
+ CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "OK",IDOK,127,50,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,190,50,50,14
+ LTEXT "",IDC_COMBO_STATIC,7,7,233,8
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_DIALOG_COMBO, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 240
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 64
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/7zip/FileManager/Resource/CopyDialog/CopyDialog.cpp b/7zip/FileManager/Resource/CopyDialog/CopyDialog.cpp
new file mode 100755
index 00000000..b36ba93a
--- /dev/null
+++ b/7zip/FileManager/Resource/CopyDialog/CopyDialog.cpp
@@ -0,0 +1,78 @@
+// CopyDialog.cpp
+
+#include "StdAfx.h"
+#include "CopyDialog.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 aButtonID, HWND buttonHWND)
+{
+ switch(aButtonID)
+ {
+ case IDC_COPY_SET_PATH:
+ OnButtonSetPath();
+ return true;
+ }
+ return CModalDialog::OnButtonClicked(aButtonID, buttonHWND);
+}
+
+void CCopyDialog::OnButtonSetPath()
+{
+ CSysString currentPath;
+ _path.GetText(currentPath);
+
+ /*
+ #ifdef LANG
+ CSysString title = LangLoadString(IDS_EXTRACT_SET_FOLDER, 0x02000881);
+ #else
+ CSysString title = MyLoadString(IDS_EXTRACT_SET_FOLDER);
+ #endif
+ */
+ CSysString title = TEXT("Specify a location for output folder");
+
+ CSysString 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/7zip/FileManager/Resource/CopyDialog/CopyDialog.h b/7zip/FileManager/Resource/CopyDialog/CopyDialog.h
new file mode 100755
index 00000000..1db2f87b
--- /dev/null
+++ b/7zip/FileManager/Resource/CopyDialog/CopyDialog.h
@@ -0,0 +1,29 @@
+// CopyDialog.h
+
+#pragma once
+
+#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;
+ CSysStringVector Strings;
+
+ INT_PTR Create(HWND parentWindow = 0)
+ { return CModalDialog::Create(MAKEINTRESOURCE(IDD_DIALOG_COPY), parentWindow); }
+};
+
+#endif
diff --git a/7zip/FileManager/Resource/CopyDialog/resource.h b/7zip/FileManager/Resource/CopyDialog/resource.h
new file mode 100755
index 00000000..efef1bd3
--- /dev/null
+++ b/7zip/FileManager/Resource/CopyDialog/resource.h
@@ -0,0 +1,22 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+
+#define IDD_DIALOG_COPY 202
+
+#define IDC_COPY_STATIC 1000
+#define IDC_COPY_COMBO 1001
+#define IDC_COPY_SET_PATH 1002
+
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 157
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1003
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/FileManager/Resource/CopyDialog/resource.rc b/7zip/FileManager/Resource/CopyDialog/resource.rc
new file mode 100755
index 00000000..b32ee270
--- /dev/null
+++ b/7zip/FileManager/Resource/CopyDialog/resource.rc
@@ -0,0 +1,101 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALOG_COPY DIALOG DISCARDABLE 0, 0, 360, 71
+STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Copy"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "",IDC_COPY_STATIC,7,7,346,8
+ COMBOBOX IDC_COPY_COMBO,7,20,317,65,CBS_DROPDOWN |
+ CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "...",IDC_COPY_SET_PATH,333,20,20,14,WS_GROUP
+ DEFPUSHBUTTON "OK",IDOK,240,50,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,303,50,50,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_DIALOG_COPY, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 353
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 64
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/7zip/FileManager/Resource/EditPage/EditPage.cpp b/7zip/FileManager/Resource/EditPage/EditPage.cpp
new file mode 100755
index 00000000..812515f2
--- /dev/null
+++ b/7zip/FileManager/Resource/EditPage/EditPage.cpp
@@ -0,0 +1,161 @@
+// EditPage.cpp
+
+#include "StdAfx.h"
+#include "resource.h"
+#include "EditPage.h"
+
+#include "Common/StringConvert.h"
+
+#include "Windows/Defs.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));
+ CSysString editorPath;
+ ReadRegEditor(editorPath);
+ _editorEdit.SetText(editorPath);
+ return CPropertyPage::OnInit();
+}
+
+LONG CEditPage::OnApply()
+{
+ // int selectedIndex = _langCombo.GetCurSel();
+ // int pathIndex = _langCombo.GetItemData(selectedIndex);
+ // ReloadLang();
+ CSysString 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);
+}
+
+class CDoubleZeroStringList
+{
+ CRecordVector<int> _indexes;
+ CSysString _string;
+public:
+ void Add(LPCTSTR string);
+ void SetForBuffer(LPTSTR buffer);
+};
+
+const TCHAR kDelimiterSymbol = TEXT(' ');
+void CDoubleZeroStringList::Add(LPCTSTR string)
+{
+ _string += string;
+ _indexes.Add(_string.Length());
+ _string += kDelimiterSymbol;
+}
+
+void CDoubleZeroStringList::SetForBuffer(LPTSTR buffer)
+{
+ lstrcpy(buffer, _string);
+ for (int i = 0; i < _indexes.Size(); i++)
+ buffer[_indexes[i]] = TEXT('\0');
+}
+
+void CEditPage::OnSetEditorButton()
+{
+ OPENFILENAME info;
+ info.lStructSize = sizeof(info);
+ info.hwndOwner = HWND(*this);
+ info.hInstance = 0;
+
+ const int kBufferSize = MAX_PATH * 2;
+ TCHAR buffer[kBufferSize + 1];
+ CSysString editorPath;
+ _editorEdit.GetText(editorPath);
+
+ lstrcpy(buffer, editorPath);
+
+ const int kFilterBufferSize = MAX_PATH;
+ TCHAR filterBuffer[kFilterBufferSize];
+ CDoubleZeroStringList doubleZeroStringList;
+ CSysString string = TEXT("*.exe");
+ doubleZeroStringList.Add(string);
+ doubleZeroStringList.Add(string);
+ doubleZeroStringList.SetForBuffer(filterBuffer);
+ info.lpstrFilter = filterBuffer;
+
+ info.lpstrCustomFilter = NULL;
+ info.nMaxCustFilter = 0;
+ info.nFilterIndex = 0;
+
+ info.lpstrFile = buffer;
+ info.nMaxFile = kBufferSize;
+
+ info.lpstrFileTitle = NULL;
+ info.nMaxFileTitle = 0;
+
+ info.lpstrInitialDir= NULL;
+
+ /*
+ CSysString title = "Open";
+ LangLoadString(IDS_COMPRESS_SET_ARCHIVE_DIALOG_TITLE, 0x02000D90);
+ info.lpstrTitle = title;
+ */
+ info.lpstrTitle = 0;
+
+
+ info.Flags = OFN_EXPLORER | OFN_HIDEREADONLY;
+ info.nFileOffset = 0;
+ info.nFileExtension = 0;
+ info.lpstrDefExt = NULL;
+
+ info.lCustData = 0;
+ info.lpfnHook = NULL;
+ info.lpTemplateName = NULL;
+
+ if(!GetOpenFileName(&info))
+ return;
+ _editorEdit.SetText(buffer);
+ // 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/7zip/FileManager/Resource/EditPage/EditPage.h b/7zip/FileManager/Resource/EditPage/EditPage.h
new file mode 100755
index 00000000..fb8e1ab9
--- /dev/null
+++ b/7zip/FileManager/Resource/EditPage/EditPage.h
@@ -0,0 +1,23 @@
+// EditPage.h
+
+#pragma once
+
+#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/7zip/FileManager/Resource/EditPage/resource.h b/7zip/FileManager/Resource/EditPage/resource.h
new file mode 100755
index 00000000..05324746
--- /dev/null
+++ b/7zip/FileManager/Resource/EditPage/resource.h
@@ -0,0 +1,19 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDD_EDIT 903
+#define IDC_EDIT_STATIC_EDITOR 1000
+#define IDC_EDIT_EDIT_EDITOR 1002
+#define IDC_EDIT_BUTTON_SET 1003
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 135
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1004
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/FileManager/Resource/EditPage/resource.rc b/7zip/FileManager/Resource/EditPage/resource.rc
new file mode 100755
index 00000000..3578173f
--- /dev/null
+++ b/7zip/FileManager/Resource/EditPage/resource.rc
@@ -0,0 +1,98 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_EDIT DIALOG DISCARDABLE 0, 0, 210, 154
+STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Editor"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "&Editor:",IDC_EDIT_STATIC_EDITOR,7,7,196,8
+ EDITTEXT IDC_EDIT_EDIT_EDITOR,7,20,160,14,ES_AUTOHSCROLL
+ PUSHBUTTON "...",IDC_EDIT_BUTTON_SET,182,20,21,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_EDIT, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 203
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 147
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/7zip/FileManager/Resource/LangPage/LangPage.cpp b/7zip/FileManager/Resource/LangPage/LangPage.cpp
new file mode 100755
index 00000000..3563a02d
--- /dev/null
+++ b/7zip/FileManager/Resource/LangPage/LangPage.cpp
@@ -0,0 +1,102 @@
+// LangPage.cpp
+
+#include "StdAfx.h"
+#include "resource.h"
+#include "LangPage.h"
+
+#include "Common/StringConvert.h"
+
+#include "Windows/Defs.h"
+#include "Windows/FileFind.h"
+
+#include "../../RegistryUtils.h"
+#include "../../HelpUtils.h"
+#include "../../LangUtils.h"
+#include "../../ProgramLocation.h"
+
+#include "../../MyLoadMenu.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));
+
+ int index = _langCombo.AddString(TEXT("English (English)"));
+ _langCombo.SetItemData(index, _paths.Size());
+ _paths.Add(TEXT(""));
+ _langCombo.SetCurSel(0);
+
+ UString folderPath;
+ if (::GetProgramFolderPath(folderPath))
+ {
+ folderPath += L"Lang\\";
+ NWindows::NFile::NFind::CEnumeratorW enumerator(folderPath + L"*.txt");
+ NWindows::NFile::NFind::CFileInfoW fileInfo;
+ while (enumerator.Next(fileInfo))
+ {
+ if (fileInfo.IsDirectory())
+ continue;
+ CLang lang;
+ UString filePath = folderPath + fileInfo.Name;
+ if (lang.Open(GetSystemString(filePath)))
+ {
+ UString name;
+ UString englishName, nationalName;
+ if (lang.GetMessage(0x00000000, englishName))
+ name += englishName;
+ if (lang.GetMessage(0x00000001, nationalName))
+ {
+ if (!nationalName.IsEmpty())
+ {
+ name += L" (";
+ name += nationalName;
+ name += L")";
+ }
+ }
+ if (name.IsEmpty())
+ name = fileInfo.Name;
+ index = _langCombo.AddString(GetSystemString(name));
+ _langCombo.SetItemData(index, _paths.Size());
+ _paths.Add(GetSystemString(filePath));
+ if (g_LangPath.CollateNoCase(GetSystemString(filePath)) == 0)
+ _langCombo.SetCurSel(index);
+ }
+ }
+ }
+ return CPropertyPage::OnInit();
+}
+
+LONG CLangPage::OnApply()
+{
+ int selectedIndex = _langCombo.GetCurSel();
+ int pathIndex = _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/7zip/FileManager/Resource/LangPage/LangPage.h b/7zip/FileManager/Resource/LangPage/LangPage.h
new file mode 100755
index 00000000..4838e429
--- /dev/null
+++ b/7zip/FileManager/Resource/LangPage/LangPage.h
@@ -0,0 +1,23 @@
+// LangPage.h
+
+#pragma once
+
+#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;
+ CSysStringVector _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/7zip/FileManager/Resource/LangPage/resource.h b/7zip/FileManager/Resource/LangPage/resource.h
new file mode 100755
index 00000000..323fe7c7
--- /dev/null
+++ b/7zip/FileManager/Resource/LangPage/resource.h
@@ -0,0 +1,19 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDD_LANG 900
+
+#define IDC_LANG_STATIC_LANG 1000
+#define IDC_LANG_COMBO_LANG 1001
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 135
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1002
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/FileManager/Resource/LangPage/resource.rc b/7zip/FileManager/Resource/LangPage/resource.rc
new file mode 100755
index 00000000..d98d6d6e
--- /dev/null
+++ b/7zip/FileManager/Resource/LangPage/resource.rc
@@ -0,0 +1,99 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_LANG DIALOG DISCARDABLE 0, 0, 210, 154
+STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Language"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "Language:",IDC_LANG_STATIC_LANG,7,7,196,8
+ COMBOBOX IDC_LANG_COMBO_LANG,7,20,146,124,CBS_DROPDOWNLIST |
+ CBS_SORT | WS_VSCROLL | WS_TABSTOP
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_LANG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 203
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 147
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/7zip/FileManager/Resource/ListBoxDialog/resource.h b/7zip/FileManager/Resource/ListBoxDialog/resource.h
new file mode 100755
index 00000000..4e137513
--- /dev/null
+++ b/7zip/FileManager/Resource/ListBoxDialog/resource.h
@@ -0,0 +1,20 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+
+#define IDD_DIALOG_LISTBOX 202
+
+#define IDC_LISTBOX_LIST 1000
+
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 157
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1002
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/FileManager/Resource/ListBoxDialog/resource.rc b/7zip/FileManager/Resource/ListBoxDialog/resource.rc
new file mode 100755
index 00000000..7b30063f
--- /dev/null
+++ b/7zip/FileManager/Resource/ListBoxDialog/resource.rc
@@ -0,0 +1,102 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALOG_LISTBOX DIALOG DISCARDABLE 0, 0, 237, 191
+STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Dialog"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,64,170,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,123,170,50,14
+ LISTBOX IDC_LISTBOX_LIST,7,7,223,149,LBS_SORT |
+ LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_DIALOG_LISTBOX, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 230
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 184
+ HORZGUIDE, 156
+ END
+
+END
+#endif // APSTUDIO_INVOKED
+
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.cpp b/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.cpp
new file mode 100755
index 00000000..a43f2626
--- /dev/null
+++ b/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++)
+ {
+ LVITEM item;
+ item.mask = LVIF_TEXT;
+ item.iItem = i;
+ item.pszText = (LPTSTR)(LPCTSTR)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;
+ while(true)
+ {
+ 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/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.h b/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.h
new file mode 100755
index 00000000..dda9ea42
--- /dev/null
+++ b/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.h
@@ -0,0 +1,33 @@
+// ListViewDialog.h
+
+#pragma once
+
+#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;
+ CSysStringVector Strings;
+ bool StringsWereChanged;
+ int FocusedItemIndex;
+
+ INT_PTR Create(HWND wndParent = 0)
+ { return CModalDialog::Create(MAKEINTRESOURCE(IDD_DIALOG_LISTVIEW), wndParent); }
+
+ CListViewDialog(): DeleteIsAllowed(false) {}
+
+};
+
+#endif
diff --git a/7zip/FileManager/Resource/ListViewDialog/resource.h b/7zip/FileManager/Resource/ListViewDialog/resource.h
new file mode 100755
index 00000000..25117958
--- /dev/null
+++ b/7zip/FileManager/Resource/ListViewDialog/resource.h
@@ -0,0 +1,20 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+
+#define IDD_DIALOG_LISTVIEW 201
+
+#define IDC_LISTVIEW_LIST 1000
+
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 157
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1002
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/FileManager/Resource/ListViewDialog/resource.rc b/7zip/FileManager/Resource/ListViewDialog/resource.rc
new file mode 100755
index 00000000..76546af9
--- /dev/null
+++ b/7zip/FileManager/Resource/ListViewDialog/resource.rc
@@ -0,0 +1,101 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALOG_LISTVIEW DIALOG DISCARDABLE 0, 0, 356, 234
+STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Dialog"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ CONTROL "List1",IDC_LISTVIEW_LIST,"SysListView32",LVS_REPORT |
+ LVS_SHOWSELALWAYS | LVS_AUTOARRANGE | LVS_NOCOLUMNHEADER |
+ WS_BORDER | WS_TABSTOP,7,7,342,196
+ DEFPUSHBUTTON "OK",IDOK,238,213,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,299,213,50,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_DIALOG_LISTVIEW, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 349
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 227
+ HORZGUIDE, 203
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.cpp b/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.cpp
new file mode 100755
index 00000000..f8bc20ef
--- /dev/null
+++ b/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.cpp
@@ -0,0 +1,87 @@
+// MessagesDialog.cpp
+
+#include "StdAfx.h"
+#include "MessagesDialog.h"
+#include "Windows/ResourceString.h"
+
+// #include "../resource.h"
+
+#ifdef LANG
+#include "../../LangUtils.h"
+#endif
+
+using namespace NWindows;
+
+#ifdef LANG
+static CIDLangPair kIDLangPairs[] =
+{
+ { IDOK, 0x02000713 }
+};
+#endif
+
+void CMessagesDialog::AddMessage(LPCTSTR aMessage)
+{
+ int itemIndex = _messageList.GetItemCount();
+ LVITEM item;
+ item.mask = LVIF_TEXT;
+ item.iItem = itemIndex;
+
+ CSysString stringNumber;
+ TCHAR sz[32];
+ wsprintf(sz, TEXT("%d"), itemIndex);
+ stringNumber = sz;
+
+ item.pszText = (LPTSTR)(LPCTSTR)stringNumber;
+ item.iSubItem = 0;
+ _messageList.InsertItem(&item);
+
+ item.mask = LVIF_TEXT;
+ item.pszText = (LPTSTR)aMessage;
+ item.iSubItem = 1;
+ _messageList.SetItem(&item);
+}
+
+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));
+
+ LVCOLUMN columnInfo;
+ columnInfo.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
+ columnInfo.fmt = LVCFMT_LEFT;
+ columnInfo.pszText = TEXT("#");
+ columnInfo.iSubItem = 0;
+ columnInfo.cx = 30;
+
+ _messageList.InsertColumn(0, &columnInfo);
+
+
+ columnInfo.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
+ columnInfo.fmt = LVCFMT_LEFT;
+ #ifdef LANG
+ CSysString s = LangLoadString(IDS_MESSAGES_DIALOG_MESSAGE_COLUMN, 0x02000A80);
+ #else
+ CSysString s = MyLoadString(IDS_MESSAGES_DIALOG_MESSAGE_COLUMN);
+ #endif
+
+ columnInfo.pszText = (LPTSTR)(LPCTSTR)s;
+ columnInfo.iSubItem = 1;
+ columnInfo.cx = 450;
+
+ _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/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.h b/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.h
new file mode 100755
index 00000000..81b0fcbb
--- /dev/null
+++ b/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.h
@@ -0,0 +1,24 @@
+// MessagesDialog.h
+
+#pragma once
+
+#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 AddMessage(LPCTSTR string);
+ virtual bool OnInit();
+public:
+ const CSysStringVector *_messages;
+ INT_PTR Create(HWND parentWindow = 0)
+ { return CModalDialog::Create(MAKEINTRESOURCE(IDD_DIALOG_MESSAGES), parentWindow); }
+};
+
+#endif
diff --git a/7zip/FileManager/Resource/MessagesDialog/resource.h b/7zip/FileManager/Resource/MessagesDialog/resource.h
new file mode 100755
index 00000000..4f23ac83
--- /dev/null
+++ b/7zip/FileManager/Resource/MessagesDialog/resource.h
@@ -0,0 +1,22 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+
+#define IDS_MESSAGES_DIALOG_MESSAGE_COLUMN 11
+
+#define IDD_DIALOG_MESSAGES 503
+
+#define IDC_MESSAGE_LIST 1000
+
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 157
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1002
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/FileManager/Resource/MessagesDialog/resource.rc b/7zip/FileManager/Resource/MessagesDialog/resource.rc
new file mode 100755
index 00000000..ff35395e
--- /dev/null
+++ b/7zip/FileManager/Resource/MessagesDialog/resource.rc
@@ -0,0 +1,114 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALOG_MESSAGES DIALOG DISCARDABLE 0, 0, 349, 135
+STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "7-Zip: Diagnostic messages"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ DEFPUSHBUTTON "&Close",IDOK,143,114,64,14
+ CONTROL "List1",IDC_MESSAGE_LIST,"SysListView32",LVS_REPORT |
+ LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER |
+ WS_TABSTOP,7,7,335,101
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+
+ IDD_DIALOG_MESSAGES, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 342
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 128
+ END
+
+END
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_MESSAGES_DIALOG_MESSAGE_COLUMN "Message"
+END
+
+
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.cpp b/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.cpp
new file mode 100755
index 00000000..8ebeeb01
--- /dev/null
+++ b/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.cpp
@@ -0,0 +1,123 @@
+// 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
+ NumberToStringW(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 = ConvertFileTimeToString2(localFileTime);
+
+ fullString +=
+ #ifdef LANG
+ LangLoadStringW(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/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.h b/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.h
new file mode 100755
index 00000000..de5f0f18
--- /dev/null
+++ b/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.h
@@ -0,0 +1,37 @@
+// OverwriteDialog.h
+
+#pragma once
+
+#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(MAKEINTRESOURCE(IDD_DIALOG_OVERWRITE), parent); }
+
+ NOverwriteDialog::CFileInfo OldFileInfo;
+ NOverwriteDialog::CFileInfo NewFileInfo;
+};
+
+#endif
diff --git a/7zip/FileManager/Resource/OverwriteDialog/resource.h b/7zip/FileManager/Resource/OverwriteDialog/resource.h
new file mode 100755
index 00000000..deefd58d
--- /dev/null
+++ b/7zip/FileManager/Resource/OverwriteDialog/resource.h
@@ -0,0 +1,36 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#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
+
+
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1013
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/FileManager/Resource/OverwriteDialog/resource.rc b/7zip/FileManager/Resource/OverwriteDialog/resource.rc
new file mode 100755
index 00000000..2e5cf828
--- /dev/null
+++ b/7zip/FileManager/Resource/OverwriteDialog/resource.rc
@@ -0,0 +1,132 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALOG_OVERWRITE DIALOG DISCARDABLE 0, 0, 371, 218
+STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Confirm File Replace"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "Destination folder already contains processed file.",
+ IDC_STATIC_OVERWRITE_HEADER,6,7,358,8
+ LTEXT "Would you like to replace the existing file",
+ IDC_STATIC_OVERWRITE_QUESTION_BEGIN,7,28,357,8
+ ICON "",IDC_STATIC_OVERWRITE_OLD_FILE_ICON,7,44,20,20
+ LTEXT "",IDC_STATIC_OVERWRITE_OLD_FILE_SIZE_TIME,39,44,325,50
+ LTEXT "with this one?",IDC_STATIC_OVERWRITE_QUESTION_END,7,98,
+ 357,8
+ ICON "",IDC_STATIC_OVERWRITE_NEW_FILE_ICON,7,114,20,20
+ LTEXT "",IDC_STATIC_OVERWRITE_NEW_FILE_SIZE_TIME,39,114,325,50
+ PUSHBUTTON "&Yes",IDYES,78,173,64,14
+ PUSHBUTTON "Yes to &All",IDC_BUTTON_OVERWRITE_YES_TO_ALL,152,173,64,
+ 14
+ PUSHBUTTON "&No",IDNO,226,172,64,14
+ PUSHBUTTON "No to A&ll",IDC_BUTTON_OVERWRITE_NO_TO_ALL,300,172,64,
+ 14
+ PUSHBUTTON "A&uto Rename",IDC_BUTTON_OVERWRITE_AUTO_RENAME,181,197,
+ 109,14
+ PUSHBUTTON "&Cancel",IDCANCEL,300,197,64,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_DIALOG_OVERWRITE, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 364
+ VERTGUIDE, 39
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 211
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_FILE_MODIFIED "modified on"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_FILE_SIZE "{0} bytes"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.cpp b/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.cpp
new file mode 100755
index 00000000..b2f9536c
--- /dev/null
+++ b/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('*'));
+ CSysString 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/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.h b/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.h
new file mode 100755
index 00000000..e890aefa
--- /dev/null
+++ b/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.h
@@ -0,0 +1,24 @@
+// PasswordDialog.h
+
+#pragma once
+
+#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:
+ CSysString _password;
+ INT_PTR Create(HWND parentWindow = 0)
+ { return CModalDialog::Create(MAKEINTRESOURCE(IDD_DIALOG_PASSWORD), parentWindow); }
+};
+
+#endif
diff --git a/7zip/FileManager/Resource/PasswordDialog/resource.h b/7zip/FileManager/Resource/PasswordDialog/resource.h
new file mode 100755
index 00000000..a092053c
--- /dev/null
+++ b/7zip/FileManager/Resource/PasswordDialog/resource.h
@@ -0,0 +1,19 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDD_DIALOG_PASSWORD 501
+#define IDC_STATIC_PASSWORD_HEADER 1000
+#define IDC_EDIT_PASSWORD 1001
+#define IDC_CHECK_PASSWORD_SHOW 1002
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 157
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1003
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/FileManager/Resource/PasswordDialog/resource.rc b/7zip/FileManager/Resource/PasswordDialog/resource.rc
new file mode 100755
index 00000000..33583245
--- /dev/null
+++ b/7zip/FileManager/Resource/PasswordDialog/resource.rc
@@ -0,0 +1,103 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALOG_PASSWORD DIALOG DISCARDABLE 0, 0, 186, 82
+STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Enter password"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "&Enter password:",IDC_STATIC_PASSWORD_HEADER,7,7,172,8
+ EDITTEXT IDC_EDIT_PASSWORD,7,19,172,14,ES_PASSWORD |
+ ES_AUTOHSCROLL
+ CONTROL "&Show password",IDC_CHECK_PASSWORD_SHOW,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,7,41,172,10
+ DEFPUSHBUTTON "OK",IDOK,41,61,64,14
+ PUSHBUTTON "Cancel",IDCANCEL,115,61,64,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_DIALOG_PASSWORD, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 179
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 75
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/7zip/FileManager/Resource/PluginsPage/PluginsPage.cpp b/7zip/FileManager/Resource/PluginsPage/PluginsPage.cpp
new file mode 100755
index 00000000..57f21c54
--- /dev/null
+++ b/7zip/FileManager/Resource/PluginsPage/PluginsPage.cpp
@@ -0,0 +1,233 @@
+// 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 aNewFlags = /*LVS_EX_CHECKBOXES | */ LVS_EX_FULLROWSELECT;
+ _listView.SetExtendedListViewStyle(aNewFlags, aNewFlags);
+
+ // CSysString aString = LangLoadString(IDS_COLUMN_TITLE, 0x02000E81);
+ CSysString aString = TEXT("Plugins");
+ LVCOLUMN aColumn;
+ aColumn.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_FMT | LVCF_SUBITEM;
+ aColumn.cx = 160;
+ aColumn.fmt = LVCFMT_LEFT;
+ aColumn.pszText = (LPTSTR)(LPCTSTR)aString;
+ aColumn.iSubItem = 0;
+ _listView.InsertColumn(0, &aColumn);
+
+ ReadFileFolderPluginInfoList(_plugins);
+
+ _listView.SetRedraw(false);
+ // _listView.DeleteAllItems();
+ for(int i = 0; i < _plugins.Size(); i++)
+ {
+ LVITEM anItem;
+ anItem.iItem = i;
+ anItem.mask = LVIF_TEXT | LVIF_STATE;
+ CSysString pluginName = GetSystemString(_plugins[i].Name);
+ anItem.pszText = (TCHAR *)(const TCHAR *)pluginName;
+ anItem.state = 0;
+ anItem.stateMask = UINT(-1);
+ anItem.iSubItem = 0;
+ _listView.InsertItem(&anItem);
+ _listView.SetCheckState(i, true);
+ }
+ _listView.SetRedraw(true);
+ if(_listView.GetItemCount() > 0)
+ {
+ UINT aState = LVIS_SELECTED | LVIS_FOCUSED;
+ _listView.SetItemState(0, aState, aState);
+ }
+
+ return CPropertyPage::OnInit();
+}
+
+LONG CPluginsPage::OnApply()
+{
+ /*
+ int aSelectedIndex = m_Lang.GetCurSel();
+ int aPathIndex = m_Lang.GetItemData(aSelectedIndex);
+ 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 = GetUnicodeString(folder);
+ *value = valueTemp.Detach();
+ return S_OK;
+}
+
+static bool IsItWindowsNT()
+{
+ OSVERSIONINFO aVersionInfo;
+ aVersionInfo.dwOSVersionInfoSize = sizeof(aVersionInfo);
+ if (!::GetVersionEx(&aVersionInfo))
+ return false;
+ return (aVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+
+static UString GetDefaultProgramName()
+{
+ if (IsItWindowsNT())
+ return L"7zFMn.exe";
+ else
+ 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 anOldState = aNMListView->uOldState & LVIS_STATEIMAGEMASK;
+ UINT aNewState = aNMListView->uNewState & LVIS_STATEIMAGEMASK;
+ if (anOldState != aNewState)
+ Changed();
+ }
+ return true;
+ }
+ return CPropertyPage::OnNotify(controlID, lParam);
+}
+
+/*
+bool CPluginsPage::OnCommand(int aCode, int anItemID, LPARAM lParam)
+{
+ if (aCode == CBN_SELCHANGE && anItemID == IDC_LANG_COMBO_LANG)
+ {
+ Changed();
+ return true;
+ }
+ return CPropertyPage::OnCommand(aCode, anItemID, lParam);
+}
+
+*/ \ No newline at end of file
diff --git a/7zip/FileManager/Resource/PluginsPage/PluginsPage.h b/7zip/FileManager/Resource/PluginsPage/PluginsPage.h
new file mode 100755
index 00000000..ec4cecb2
--- /dev/null
+++ b/7zip/FileManager/Resource/PluginsPage/PluginsPage.h
@@ -0,0 +1,29 @@
+// PluginsPage.h
+
+#pragma once
+
+#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 OnCommand(int aCode, int anItemID, LPARAM lParam);
+ virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
+ virtual void OnButtonOptions();
+ virtual LONG OnApply();
+ virtual bool OnNotify(UINT controlID, LPNMHDR lParam);
+};
+
+#endif
diff --git a/7zip/FileManager/Resource/PluginsPage/resource.h b/7zip/FileManager/Resource/PluginsPage/resource.h
new file mode 100755
index 00000000..c0463eae
--- /dev/null
+++ b/7zip/FileManager/Resource/PluginsPage/resource.h
@@ -0,0 +1,19 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDD_PLUGINS 901
+#define IDC_PLUGINS_STATIC_PLUGINS 1000
+#define IDC_PLUGINS_LIST 1001
+#define IDC_PLUGINS_BUTTON_OPTIONS 1002
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 135
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 103
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/FileManager/Resource/PluginsPage/resource.rc b/7zip/FileManager/Resource/PluginsPage/resource.rc
new file mode 100755
index 00000000..b47c7996
--- /dev/null
+++ b/7zip/FileManager/Resource/PluginsPage/resource.rc
@@ -0,0 +1,100 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_PLUGINS DIALOG DISCARDABLE 0, 0, 210, 154
+STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Plugins"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "&Plugins:",IDC_PLUGINS_STATIC_PLUGINS,7,7,196,8
+ CONTROL "List1",IDC_PLUGINS_LIST,"SysListView32",LVS_REPORT |
+ LVS_SHOWSELALWAYS | LVS_NOCOLUMNHEADER |
+ LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,20,135,127
+ PUSHBUTTON "Options...",IDC_PLUGINS_BUTTON_OPTIONS,153,20,50,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_PLUGINS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 203
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 147
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.cpp b/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.cpp
new file mode 100755
index 00000000..16a59cf5
--- /dev/null
+++ b/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(LPCTSTR s)
+{
+ if (MainWindow != 0)
+ ::SetWindowText(MainWindow, s + UString(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 = _UI64_MAX;
+ _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/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.h b/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.h
new file mode 100755
index 00000000..e56b3b67
--- /dev/null
+++ b/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.h
@@ -0,0 +1,131 @@
+// ProgressDialog.h
+
+#pragma once
+
+#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(LPCTSTR 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 aWndParent = 0)
+ {
+ _title = title;
+ return CModalDialog::Create(MAKEINTRESOURCE(IDD_DIALOG_PROGRESS), aWndParent);
+ }
+
+ static const UINT kCloseMessage;
+
+ virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+
+ void MyClose()
+ {
+ PostMessage(kCloseMessage);
+ };
+};
+
+#endif
diff --git a/7zip/FileManager/Resource/ProgressDialog/resource.h b/7zip/FileManager/Resource/ProgressDialog/resource.h
new file mode 100755
index 00000000..fc03e42c
--- /dev/null
+++ b/7zip/FileManager/Resource/ProgressDialog/resource.h
@@ -0,0 +1,20 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+
+#define IDD_DIALOG_PROGRESS 500
+
+#define IDC_PROGRESS1 1000
+
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 157
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1002
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/FileManager/Resource/ProgressDialog/resource.rc b/7zip/FileManager/Resource/ProgressDialog/resource.rc
new file mode 100755
index 00000000..8d4c76cc
--- /dev/null
+++ b/7zip/FileManager/Resource/ProgressDialog/resource.rc
@@ -0,0 +1,101 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALOG_PROGRESS DIALOG DISCARDABLE 0, 0, 186, 55
+STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Progress"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ PUSHBUTTON "Cancel",IDCANCEL,61,34,64,14
+ CONTROL "Progress1",IDC_PROGRESS1,"msctls_progress32",PBS_SMOOTH |
+ WS_BORDER,7,7,172,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+
+ IDD_DIALOG_PROGRESS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 179
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 48
+ END
+
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.cpp b/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.cpp
new file mode 100755
index 00000000..678db72a
--- /dev/null
+++ b/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.cpp
@@ -0,0 +1,369 @@
+// 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
+
+#ifndef _SFX
+CProgressDialog::~CProgressDialog()
+{
+ AddToTitle(L"");
+}
+void CProgressDialog::AddToTitle(LPCWSTR s)
+{
+ if (MainWindow != 0)
+ {
+ CWindow window(MainWindow);
+ window.SetText(s + UString(MainTitle));
+ }
+}
+#endif
+
+bool CProgressDialog::OnInit()
+{
+ _range = UINT64(-1);
+ _prevPercentValue = UINT32(-1);
+ _prevElapsedSec = UINT32(-1);
+ _prevRemainingSec = UINT32(-1);
+ _prevSpeed = UINT32(-1);
+ _prevMode = kSpeedBytes;
+ _pevTime = ::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 = LangLoadStringW(IDS_PROGRESS_FOREGROUND, 0x02000C11);
+ continueString = LangLoadStringW(IDS_PROGRESS_CONTINUE, 0x02000C13);
+ pausedString = LangLoadStringW(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)
+{
+ if (value < (UINT64(10000) << 0))
+ {
+ ConvertUINT64ToString(value, s);
+ lstrcatW(s, L" B");
+ return;
+ }
+ if (value < (UINT64(10000) << 10))
+ {
+ ConvertUINT64ToString((value >> 10), s);
+ lstrcatW(s, L" KB");
+ return;
+ }
+ if (value < (UINT64(10000) << 20))
+ {
+ ConvertUINT64ToString((value >> 20), s);
+ lstrcatW(s, L" MB");
+ return;
+ }
+ ConvertUINT64ToString((value >> 30), s);
+ lstrcatW(s, L" GB");
+ return;
+}
+
+void CProgressDialog::SetRange(UINT64 range)
+{
+ _range = range;
+ _previousPos = _UI64_MAX;
+ _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);
+ SetPos(completed);
+
+ _elapsedTime += (curTime - _pevTime);
+ _pevTime = 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)
+ {
+ 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);
+ if (percentValue != _prevPercentValue)
+ {
+ wchar_t s[64];
+ ConvertUINT64ToString(percentValue, s);
+ UString title = s;
+ title += L"% ";
+ if (!_foreground)
+ {
+ title += backgroundedString;
+ 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);
+}
+
+void CProgressDialog::SetPauseText()
+{
+ SetItemText(IDC_BUTTON_PAUSE, ProgressSynch.GetPaused() ?
+ continueString : pauseString);
+
+ SetText(LangLoadStringW(IDS_PROGRESS_PAUSED, 0x02000C20) +
+ UString(L" ") + _title);
+}
+
+void CProgressDialog::OnPauseButton()
+{
+ bool paused = !ProgressSynch.GetPaused();
+ ProgressSynch.SetPaused(paused);
+ UINT32 curTime = ::GetTickCount();
+ if (paused)
+ _elapsedTime += (curTime - _pevTime);
+ _pevTime = curTime;
+ SetPauseText();
+}
+
+void CProgressDialog::SetPriorityText()
+{
+ SetItemText(IDC_BUTTON_PROGRESS_PRIORITY, _foreground ?
+ backgroundString :
+ foregroundString);
+}
+
+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),
+ LangLoadStringW(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/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.h b/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.h
new file mode 100755
index 00000000..40806296
--- /dev/null
+++ b/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.h
@@ -0,0 +1,160 @@
+// ProgressDialog.h
+
+#pragma once
+
+#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
+
+enum ESpeedMode
+{
+ kSpeedBytes,
+ kSpeedKBytes,
+ kSpeedMBytes
+};
+
+class CProgressDialog: public NWindows::NControl::CModalDialog
+{
+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 _pevTime;
+ 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);
+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 aWndParent = 0)
+ {
+ _title = title;
+ return CModalDialog::Create(MAKEINTRESOURCE(IDD_DIALOG_PROGRESS), aWndParent);
+ }
+
+ static const UINT kCloseMessage;
+
+ virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+
+ void MyClose()
+ {
+ PostMessage(kCloseMessage);
+ };
+};
+
+#endif
diff --git a/7zip/FileManager/Resource/ProgressDialog2/resource.h b/7zip/FileManager/Resource/ProgressDialog2/resource.h
new file mode 100755
index 00000000..f13a7c2b
--- /dev/null
+++ b/7zip/FileManager/Resource/ProgressDialog2/resource.h
@@ -0,0 +1,32 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDC_BUTTON_PAUSE 3
+#define IDC_BUTTON_PROGRESS_PRIORITY 4
+#define IDD_DIALOG_PROGRESS 500
+#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 IDS_PROGRESS_PAUSED 700
+#define IDS_PROGRESS_FOREGROUND 701
+#define IDS_PROGRESS_CONTINUE 702
+#define IDS_PROGRESS_ASK_CANCEL 703
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 157
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1006
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/FileManager/Resource/ProgressDialog2/resource.rc b/7zip/FileManager/Resource/ProgressDialog2/resource.rc
new file mode 100755
index 00000000..5540e88b
--- /dev/null
+++ b/7zip/FileManager/Resource/ProgressDialog2/resource.rc
@@ -0,0 +1,127 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALOG_PROGRESS DIALOG DISCARDABLE 0, 0, 246, 78
+STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP |
+ WS_CAPTION | WS_SYSMENU
+CAPTION "Progress"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ PUSHBUTTON "&Background",IDC_BUTTON_PROGRESS_PRIORITY,7,57,72,14
+ PUSHBUTTON "&Pause",IDC_BUTTON_PAUSE,92,57,72,14
+ PUSHBUTTON "Cancel",IDCANCEL,175,57,64,14
+ LTEXT "Elapsed time:",IDC_PROGRESS_ELAPSED,7,7,71,8
+ RTEXT "00:00:00",IDC_PROGRESS_ELAPSED_VALUE,78,7,42,8
+ LTEXT "Remaining time:",IDC_PROGRESS_REMAINING,7,18,71,8
+ RTEXT "",IDC_PROGRESS_REMAINING_VALUE,78,18,42,8
+ LTEXT "Size:",IDC_PROGRESS_TOTAL,149,7,48,8
+ RTEXT "",IDC_PROGRESS_SPEED_TOTAL_VALUE,197,7,42,8
+ LTEXT "Speed:",IDC_PROGRESS_SPEED,149,18,48,8
+ RTEXT "",IDC_PROGRESS_SPEED_VALUE,197,18,42,8
+ CONTROL "Progress1",IDC_PROGRESS1,"msctls_progress32",PBS_SMOOTH |
+ WS_BORDER,7,34,232,13
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_DIALOG_PROGRESS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 239
+ VERTGUIDE, 78
+ VERTGUIDE, 120
+ VERTGUIDE, 149
+ VERTGUIDE, 197
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 71
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+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
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/7zip/FileManager/Resource/PropertyName/resource.h b/7zip/FileManager/Resource/PropertyName/resource.h
new file mode 100755
index 00000000..40f298cd
--- /dev/null
+++ b/7zip/FileManager/Resource/PropertyName/resource.h
@@ -0,0 +1,41 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#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
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 157
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1002
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/FileManager/Resource/PropertyName/resource.rc b/7zip/FileManager/Resource/PropertyName/resource.rc
new file mode 100755
index 00000000..6bdce925
--- /dev/null
+++ b/7zip/FileManager/Resource/PropertyName/resource.rc
@@ -0,0 +1,103 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+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"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ 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"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/7zip/FileManager/Resource/SettingsPage/SettingsPage.cpp b/7zip/FileManager/Resource/SettingsPage/SettingsPage.cpp
new file mode 100755
index 00000000..c476c97a
--- /dev/null
+++ b/7zip/FileManager/Resource/SettingsPage/SettingsPage.cpp
@@ -0,0 +1,68 @@
+// SettingsPage.cpp
+
+#include "StdAfx.h"
+#include "resource.h"
+#include "SettingsPage.h"
+
+#include "Common/StringConvert.h"
+
+#include "Windows/Defs.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}
+};
+
+static LPCWSTR kEditTopic = L"FM/options.htm#settings";
+
+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());
+ return CPropertyPage::OnInit();
+}
+
+LONG CSettingsPage::OnApply()
+{
+ SaveShowDots(IsButtonCheckedBool(IDC_SETTINGS_SHOW_DOTS));
+ SaveShowSystemMenu(IsButtonCheckedBool(IDC_SETTINGS_SHOW_SYSTEM_MENU));
+ SaveShowRealFileIcons(IsButtonCheckedBool(IDC_SETTINGS_SHOW_REAL_FILE_ICONS));
+
+ return PSNRET_NOERROR;
+}
+
+void CSettingsPage::OnNotifyHelp()
+{
+ ShowHelpWindow(NULL, kEditTopic); // change it
+}
+
+
+bool CSettingsPage::OnCommand(int code, int itemID, LPARAM param)
+{
+ if (code == EN_CHANGE &&
+ (
+ itemID == IDC_SETTINGS_SHOW_DOTS ||
+ itemID == IDC_SETTINGS_SHOW_SYSTEM_MENU ||
+ itemID == IDC_SETTINGS_SHOW_REAL_FILE_ICONS
+ )
+ )
+ {
+ Changed();
+ return true;
+ }
+ return CPropertyPage::OnCommand(code, itemID, param);
+}
+
+
diff --git a/7zip/FileManager/Resource/SettingsPage/SettingsPage.h b/7zip/FileManager/Resource/SettingsPage/SettingsPage.h
new file mode 100755
index 00000000..f8bd5de3
--- /dev/null
+++ b/7zip/FileManager/Resource/SettingsPage/SettingsPage.h
@@ -0,0 +1,20 @@
+// SettingsPage.h
+
+#pragma once
+
+#ifndef __SETTINGSPAGE_H
+#define __SETTINGSPAGE_H
+
+#include "Windows/Control/PropertyPage.h"
+#include "Windows/Control/Edit.h"
+
+class CSettingsPage: public NWindows::NControl::CPropertyPage
+{
+public:
+ virtual bool OnInit();
+ virtual void OnNotifyHelp();
+ virtual bool OnCommand(int code, int itemID, LPARAM param);
+ virtual LONG OnApply();
+};
+
+#endif
diff --git a/7zip/FileManager/Resource/SettingsPage/resource.h b/7zip/FileManager/Resource/SettingsPage/resource.h
new file mode 100755
index 00000000..762ca83f
--- /dev/null
+++ b/7zip/FileManager/Resource/SettingsPage/resource.h
@@ -0,0 +1,19 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#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
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 135
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1011
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/FileManager/Resource/SettingsPage/resource.rc b/7zip/FileManager/Resource/SettingsPage/resource.rc
new file mode 100755
index 00000000..d9c4f4af
--- /dev/null
+++ b/7zip/FileManager/Resource/SettingsPage/resource.rc
@@ -0,0 +1,101 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_SETTINGS DIALOG DISCARDABLE 0, 0, 210, 154
+STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Settings"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ CONTROL "Show "".."" item",IDC_SETTINGS_SHOW_DOTS,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,7,7,196,10
+ CONTROL "Show real file icons",IDC_SETTINGS_SHOW_REAL_FILE_ICONS,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,21,196,10
+ CONTROL "Show system menu",IDC_SETTINGS_SHOW_SYSTEM_MENU,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,7,35,196,10
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_SETTINGS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 203
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 147
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/7zip/FileManager/Resource/SystemPage/SystemPage.cpp b/7zip/FileManager/Resource/SystemPage/SystemPage.cpp
new file mode 100755
index 00000000..6860d942
--- /dev/null
+++ b/7zip/FileManager/Resource/SystemPage/SystemPage.cpp
@@ -0,0 +1,441 @@
+// 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}
+};
+
+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);
+
+ CSysString s = LangLoadString(IDS_PROPERTY_EXTENSION, 0x02000205);
+ LVCOLUMN column;
+ column.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_FMT | LVCF_SUBITEM;
+ column.cx = 70;
+ column.fmt = LVCFMT_LEFT;
+ column.pszText = (LPTSTR)(LPCTSTR)s;
+ column.iSubItem = 0;
+ _listViewExt.InsertColumn(0, &column);
+
+ s = LangLoadString(IDS_PLUGIN, 0x03010310);
+ column.cx = 70;
+ column.pszText = (LPTSTR)(LPCTSTR)s;
+ column.iSubItem = 1;
+ _listViewExt.InsertColumn(1, &column);
+
+ s = LangLoadString(IDS_PLUGIN, 0x03010310);
+ column.cx = 70;
+ column.pszText = (LPTSTR)(LPCTSTR)s;
+ column.iSubItem = 0;
+ _listViewPlugins.InsertColumn(0, &column);
+
+ _extDatabase.Read();
+
+ for (int i = 0; i < _extDatabase.ExtBigItems.Size(); i++)
+ {
+ CExtInfoBig &extInfo = _extDatabase.ExtBigItems[i];
+
+ LVITEM item;
+ item.iItem = i;
+ item.mask = LVIF_TEXT | LVIF_PARAM;
+ item.lParam = i;
+ CSysString ext = GetSystemString(extInfo.Ext);
+ item.pszText = (LPTSTR)(LPCTSTR)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)
+{
+ LVITEM item;
+ item.iItem = itemIndex;
+ item.mask = LVIF_TEXT;
+ CSysString mainPlugin = GetSystemString(
+ _extDatabase.GetMainPluginNameForExtItem(indexInDatabase));
+ item.pszText = (TCHAR *)(const TCHAR *)mainPlugin;
+ item.iSubItem = 1;
+ _listViewExt.SetItem(&item);
+}
+
+static bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+
+static UString GetProgramCommand()
+{
+ UString path = L"\"";
+ UString folder;
+ if (GetProgramFolderPath(folder))
+ path += folder;
+ if (IsItWindowsNT())
+ path += L"7zFMn.exe";
+ else
+ path += L"7zFM.exe";
+ path += L"\" \"%1\"";
+ return path;
+}
+
+static CSysString GetIconPath(const CSysString &filePath,
+ const CLSID &clsID, const UString &extension)
+{
+ CPluginLibrary library;
+ CMyComPtr<IFolderManager> folderManager;
+ CMyComPtr<IFolderFolder> folder;
+ if (library.LoadAndCreateManager(filePath, clsID, &folderManager) != S_OK)
+ return CSysString();
+ CMyComBSTR typesString;
+ if (folderManager->GetTypes(&typesString) != S_OK)
+ return CSysString();
+ 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)
+ return CSysString();
+ CMyComBSTR iconPathTemp;
+ if (getIconPath->GetIconPath(type, &iconPathTemp) != S_OK)
+ return CSysString();
+ return GetSystemString((const wchar_t *)iconPathTemp);
+ }
+ }
+ return CSysString();
+}
+
+LONG CSystemPage::OnApply()
+{
+ _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();
+ CSysString 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),
+ GetSystemString(title),
+ GetSystemString(command),
+ iconPath, NULL, 0);
+ }
+ else
+ NRegistryAssociations::DeleteShellExtensionInfo(GetSystemString(extInfo.Ext));
+ }
+ /*
+ if (IsButtonCheckedBool(IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU))
+ NRegistryAssociations::AddContextMenuHandler();
+ else
+ NRegistryAssociations::DeleteContextMenuHandler();
+ */
+
+ return PSNRET_NOERROR;
+}
+
+void CSystemPage::OnNotifyHelp()
+{
+ ShowHelpWindow(NULL, kSystemTopic);
+}
+
+bool CSystemPage::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch(buttonID)
+ {
+ case IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU:
+ 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, UINT 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[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 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];
+ CSysString pluginName = GetSystemString(_extDatabase.Plugins[pluginPair.Index].Name);
+ LVITEM item;
+ item.iItem = i;
+ item.mask = LVIF_TEXT | LVIF_PARAM;
+ item.lParam = i;
+ item.pszText = (LPTSTR)(LPCTSTR)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 LPCTSTR kZIPExtension = TEXT("zip");
+static LPCTSTR kRARExtension = TEXT("rar");
+
+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/7zip/FileManager/Resource/SystemPage/SystemPage.h b/7zip/FileManager/Resource/SystemPage/SystemPage.h
new file mode 100755
index 00000000..3a2052e8
--- /dev/null
+++ b/7zip/FileManager/Resource/SystemPage/SystemPage.h
@@ -0,0 +1,41 @@
+// SystemPage.h
+
+#pragma once
+
+#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();
+
+public:
+ virtual bool OnMessage(UINT message, UINT 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/7zip/FileManager/Resource/SystemPage/resource.h b/7zip/FileManager/Resource/SystemPage/resource.h
new file mode 100755
index 00000000..e2606899
--- /dev/null
+++ b/7zip/FileManager/Resource/SystemPage/resource.h
@@ -0,0 +1,21 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#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
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 135
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1022
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/FileManager/Resource/SystemPage/resource.rc b/7zip/FileManager/Resource/SystemPage/resource.rc
new file mode 100755
index 00000000..9158e701
--- /dev/null
+++ b/7zip/FileManager/Resource/SystemPage/resource.rc
@@ -0,0 +1,115 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_SYSTEM DIALOG DISCARDABLE 0, 0, 252, 218
+STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "System"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "Associate 7-Zip with:",IDC_SYSTEM_STATIC_ASSOCIATE,7,7,
+ 238,8
+ CONTROL "List1",IDC_SYSTEM_LIST_ASSOCIATE,"SysListView32",
+ LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SORTASCENDING |
+ WS_BORDER | WS_TABSTOP,7,20,105,186
+ CONTROL "List1",IDC_SYSTEM_LIST_PLUGINS,"SysListView32",
+ LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | NOT
+ WS_VISIBLE | WS_BORDER | WS_TABSTOP,143,20,102,186
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_SYSTEM, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 245
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 211
+ HORZGUIDE, 25
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_PLUGIN "Plugin"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/7zip/FileManager/RootFolder.cpp b/7zip/FileManager/RootFolder.cpp
new file mode 100755
index 00000000..ebff83c4
--- /dev/null
+++ b/7zip/FileManager/RootFolder.cpp
@@ -0,0 +1,191 @@
+// 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 "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 = LangLoadStringW(IDS_COMPUTER, 0x03020300);
+ _networkName = LangLoadStringW(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
+ 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
+ {
+ CNetFolder *netFolderSpec = new CNetFolder;
+ CMyComPtr<IFolderFolder> subFolder = netFolderSpec;
+ netFolderSpec->Init(0, 0, _networkName + L'\\');
+ *resultFolder = subFolder.Detach();
+ }
+ 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;
+
+ if (name2[name2.Length () - 1] != L'\\')
+ name2 += L'\\';
+ CFSFolder *fsFolderSpec = new CFSFolder;
+ CMyComPtr<IFolderFolder> subFolder = fsFolderSpec;
+ if (fsFolderSpec->Init(name2, 0) == S_OK)
+ {
+ *resultFolder = subFolder.Detach();
+ return S_OK;
+ }
+ if (name2[0] == L'\\')
+ {
+ CNetFolder *netFolderSpec = new CNetFolder;
+ CMyComPtr<IFolderFolder> subFolder = netFolderSpec;
+ netFolderSpec->Init(name2);
+ *resultFolder = subFolder.Detach();
+ return S_OK;
+ }
+ return E_INVALIDARG;
+}
+
+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/7zip/FileManager/RootFolder.h b/7zip/FileManager/RootFolder.h
new file mode 100755
index 00000000..97e28c85
--- /dev/null
+++ b/7zip/FileManager/RootFolder.h
@@ -0,0 +1,51 @@
+// RootFolder.h
+
+#pragma once
+
+#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/7zip/FileManager/StdAfx.cpp b/7zip/FileManager/StdAfx.cpp
new file mode 100755
index 00000000..4cdd30e1
--- /dev/null
+++ b/7zip/FileManager/StdAfx.cpp
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// FAM.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/7zip/FileManager/StdAfx.h b/7zip/FileManager/StdAfx.h
new file mode 100755
index 00000000..4e8dc51d
--- /dev/null
+++ b/7zip/FileManager/StdAfx.h
@@ -0,0 +1,41 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#pragma once
+
+#define _WIN32_WINNT 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 <atlbase.h>
+
+extern CComModule _Module;
+
+#include <atlcom.h>
+
+#include <ComDef.h>
+#include <stdio.h>
+#include <windows.h>
+#include <Commctrl.h>
+#include <shellapi.h>
+#include <mbstring.h>
+#include <new.h>
+#include <regstr.h>
+
+*/
+#include <memory>
+
+
+#endif
diff --git a/7zip/FileManager/StringUtils.cpp b/7zip/FileManager/StringUtils.cpp
new file mode 100755
index 00000000..8a4e48ae
--- /dev/null
+++ b/7zip/FileManager/StringUtils.cpp
@@ -0,0 +1,77 @@
+// StringUtils.cpp
+
+#include "StdAfx.h"
+
+#include "StringUtils.h"
+
+void SplitStringToTwoStrings(const UString &src, UString &dest1, UString &dest2)
+{
+ dest1.Empty();
+ dest2.Empty();
+ bool aQuoteMode = false;
+ for (int i = 0; i < src.Length(); i++)
+ {
+ wchar_t aChar = src[i];
+ if (aChar == L'\"')
+ aQuoteMode = !aQuoteMode;
+ else if (aChar == L' ' && !aQuoteMode)
+ {
+ if (!aQuoteMode)
+ {
+ i++;
+ break;
+ }
+ }
+ else
+ dest1 += aChar;
+ }
+ dest2 = src.Mid(i);
+}
+
+void SplitString(const UString &srcString, UStringVector &destStrings)
+{
+ destStrings.Clear();
+ UString string;
+ int aLen = srcString.Length();
+ if (aLen == 0)
+ return;
+ for (int i = 0; i < aLen; 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;
+}
+
+/*
+void SplitString(const CSysString &srcString, CSysStringVector &destStrings)
+{
+ destStrings.Clear();
+ UStringVector destStringsTemp;
+ SplitString(GetUnicodeString(srcString), destStringsTemp);
+ for (int i = 0; i < destStringsTemp.Size(); i++);
+ destStrings.Add(GetSysUnicodeString
+}
+*/
diff --git a/7zip/FileManager/StringUtils.h b/7zip/FileManager/StringUtils.h
new file mode 100755
index 00000000..6a17da9b
--- /dev/null
+++ b/7zip/FileManager/StringUtils.h
@@ -0,0 +1,17 @@
+// StringUtils.h
+
+#pragma once
+
+#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 \ No newline at end of file
diff --git a/7zip/FileManager/SysIconUtils.cpp b/7zip/FileManager/SysIconUtils.cpp
new file mode 100755
index 00000000..e2577b45
--- /dev/null
+++ b/7zip/FileManager/SysIconUtils.cpp
@@ -0,0 +1,108 @@
+// SysIconUtils.h
+
+#include "StdAfx.h"
+
+#include "SysIconUtils.h"
+#ifndef _UNICODE
+#include "Common/StringConvert.h"
+#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
+static inline UINT GetCurrentCodePage()
+ { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
+DWORD_PTR GetRealIconIndex(LPCWSTR path, UINT32 attributes, int &iconIndex)
+{
+ SHFILEINFOW shellInfo;
+ DWORD_PTR res = ::SHGetFileInfoW(path, FILE_ATTRIBUTE_NORMAL | attributes, &shellInfo,
+ sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX);
+ if (res == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+ return GetRealIconIndex(UnicodeStringToMultiByte(path, GetCurrentCodePage()), attributes, iconIndex);
+ iconIndex = shellInfo.iIcon;
+ return res;
+}
+#endif
+
+DWORD_PTR GetRealIconIndex(const CSysString &fileName, UINT32 attributes,
+ int &iconIndex, CSysString &typeName)
+{
+ SHFILEINFO shellInfo;
+ DWORD_PTR res = ::SHGetFileInfo(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 CSysString &fileNameSpec,
+ CSysString &typeName)
+{
+ CSysString fileName = fileNameSpec;
+ if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
+ {
+ fileName = TEXT("__Fldr__");
+ if (_dirIconIndex < 0)
+ GetRealIconIndex(fileName, attributes, _dirIconIndex, _dirTypeName);
+ typeName = _dirTypeName;
+ return _dirIconIndex;
+ }
+ int dotPos = fileName.ReverseFind('.');
+ if (dotPos < 0)
+ {
+ fileName = TEXT("__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 CSysString &fileName)
+{
+ CSysString typeName;
+ return GetIconIndex(attributes, fileName, typeName);
+}
diff --git a/7zip/FileManager/SysIconUtils.h b/7zip/FileManager/SysIconUtils.h
new file mode 100755
index 00000000..186a1549
--- /dev/null
+++ b/7zip/FileManager/SysIconUtils.h
@@ -0,0 +1,57 @@
+// SysIconUtils.h
+
+#pragma once
+
+#ifndef __SYSICONUTILS_H
+#define __SYSICONUTILS_H
+
+#include "Common/String.h"
+
+struct CExtIconPair
+{
+ CSysString Ext;
+ int IconIndex;
+ CSysString 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;
+ CSysString _dirTypeName;
+ int _noExtIconIndex;
+ CSysString _noExtTypeName;
+ CObjectVector<CExtIconPair> _map;
+public:
+ CExtToIconMap(): _dirIconIndex(-1), _noExtIconIndex(-1) {}
+ void Clear()
+ {
+ _dirIconIndex = -1;
+ _noExtIconIndex = -1;
+ _map.Clear();
+ }
+ int GetIconIndex(UINT32 attributes, const CSysString &fileName,
+ CSysString &typeName);
+ int GetIconIndex(UINT32 attributes, const CSysString &fileName);
+};
+
+DWORD_PTR GetRealIconIndex(LPCTSTR path, UINT32 attributes, int &iconIndex);
+#ifndef _UNICODE
+// DWORD_PTR GetRealIconIndex(LPCWSTR path, UINT32 attributes, int &iconIndex);
+#endif
+DWORD_PTR GetRealIconIndex(const CSysString &fileName, UINT32 attributes, int &iconIndex, CSysString &typeName);
+int GetIconIndexForCSIDL(int aCSIDL);
+
+
+#endif
+
diff --git a/7zip/FileManager/Test.bmp b/7zip/FileManager/Test.bmp
new file mode 100755
index 00000000..ef85ba23
--- /dev/null
+++ b/7zip/FileManager/Test.bmp
Binary files differ
diff --git a/7zip/FileManager/Test2.bmp b/7zip/FileManager/Test2.bmp
new file mode 100755
index 00000000..99b7dbf0
--- /dev/null
+++ b/7zip/FileManager/Test2.bmp
Binary files differ
diff --git a/7zip/FileManager/TextPairs.cpp b/7zip/FileManager/TextPairs.cpp
new file mode 100755
index 00000000..6ccc6bf7
--- /dev/null
+++ b/7zip/FileManager/TextPairs.cpp
@@ -0,0 +1,220 @@
+// 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.CollateNoCase(s2); }
+static int ComparePairItems(const CTextPair &p1, const CTextPair &p2)
+ { return ComparePairIDs(p1.ID, p2.ID); }
+static int __cdecl ComparePairItems(const void *a1, const void *a2)
+{
+ return ComparePairItems(
+ *(*((const CTextPair **)a1)),
+ *(*((const CTextPair **)a2)));
+}
+
+void CPairsStorage::Sort()
+{
+ CPointerVector &pointerVector = Pairs;
+ qsort(&pointerVector[0], Pairs.Size(), sizeof(void *),
+ ComparePairItems);
+}
+
+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/7zip/FileManager/TextPairs.h b/7zip/FileManager/TextPairs.h
new file mode 100755
index 00000000..bce4755c
--- /dev/null
+++ b/7zip/FileManager/TextPairs.h
@@ -0,0 +1,36 @@
+// Common/TextPairs.h
+
+#pragma once
+
+#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/7zip/FileManager/UpdateCallback100.cpp b/7zip/FileManager/UpdateCallback100.cpp
new file mode 100755
index 00000000..05f50887
--- /dev/null
+++ b/7zip/FileManager/UpdateCallback100.cpp
@@ -0,0 +1,69 @@
+// UpdateCallback.h
+
+#include "StdAfx.h"
+
+#include "Common/StringConvert.h"
+
+#include "UpdateCallback100.h"
+// #include "Windows/ProcessMessages.h"
+// #include "Resource/PasswordDialog/PasswordDialog.h"
+
+#include "Common/Defs.h"
+
+using namespace NWindows;
+
+STDMETHODIMP CUpdateCallback100Imp::SetTotal(UINT64 size)
+{
+ ProgressDialog.ProgressSynch.SetProgress(size, 0);
+ return S_OK;
+}
+
+STDMETHODIMP CUpdateCallback100Imp::SetCompleted(const UINT64 *completeValue)
+{
+ while(true)
+ {
+ 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)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CUpdateCallback100Imp::DeleteOperation(const wchar_t *name)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CUpdateCallback100Imp::OperationResult(INT32 operationResult)
+{
+ 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 = GetUnicodeString((LPCTSTR)dialog._password);
+ _passwordIsDefined = true;
+ */
+ }
+ *passwordIsDefined = BoolToInt(_passwordIsDefined);
+ CMyComBSTR tempName = _password;
+ *password = tempName.Detach();
+ return S_OK;
+}
diff --git a/7zip/FileManager/UpdateCallback100.h b/7zip/FileManager/UpdateCallback100.h
new file mode 100755
index 00000000..ca1c50b2
--- /dev/null
+++ b/7zip/FileManager/UpdateCallback100.h
@@ -0,0 +1,64 @@
+// UpdateCallback.h
+
+#pragma once
+
+#ifndef __UPDATECALLBACK100_H
+#define __UPDATECALLBACK100_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(CryptoGetTextPassword2)(INT32 *passwordIsDefined, BSTR *password);
+private:
+ bool _passwordIsDefined;
+ UString _password;
+
+public:
+ CProgressDialog ProgressDialog;
+ HWND _parentWindow;
+ 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/7zip/FileManager/ViewSettings.cpp b/7zip/FileManager/ViewSettings.cpp
new file mode 100755
index 00000000..5955bf10
--- /dev/null
+++ b/7zip/FileManager/ViewSettings.cpp
@@ -0,0 +1,344 @@
+// ViewSettings.h
+
+#include "StdAfx.h"
+
+#include "Common/IntToString.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 TCHAR *kPanelPathValueName = TEXT("PanelPath");
+static const TCHAR *kFolderHistoryValueName = TEXT("FolderHistory");
+static const TCHAR *kFastFoldersValueName = TEXT("FolderShortcuts");
+static const TCHAR *kCopyHistoryValueName = TEXT("CopyHistory");
+
+
+#pragma pack( push, PragmaColumnInfoSpec)
+#pragma pack( push, 1)
+
+class CColumnInfoSpec
+{
+ UINT32 PropID;
+ BYTE IsVisible;
+ UINT32 Width;
+public:
+ void GetFromColumnInfo(const CColumnInfo &aSrc)
+ {
+ PropID = aSrc.PropID;
+ IsVisible = aSrc.IsVisible ? 1: 0;
+ Width = aSrc.Width;
+ }
+ void PutColumnInfo(CColumnInfo &aDest)
+ {
+ aDest.PropID = PropID;
+ aDest.IsVisible = (IsVisible != 0);
+ aDest.Width = Width;
+ }
+};
+
+struct CColumnHeader
+{
+ UINT32 Version;
+ // UINT32 SortIndex;
+ UINT32 SortID;
+ BYTE Ascending;
+};
+
+#pragma pack(pop)
+#pragma pack(pop, PragmaColumnInfoSpec)
+
+static const UINT32 kColumnInfoVersion = 0;
+
+static NSynchronization::CCriticalSection g_RegistryOperationsCriticalSection;
+
+void SaveListViewInfo(const CSysString &id, const CListViewInfo &viewInfo)
+{
+ const CObjectVector<CColumnInfo> &columns = viewInfo.Columns;
+ CByteBuffer buffer;
+ UINT32 dataSize = sizeof(CColumnHeader) + sizeof(CColumnInfoSpec) * columns.Size();
+ buffer.SetCapacity(dataSize);
+ BYTE *dataPointer = (BYTE *)buffer;
+ CColumnHeader &columnHeader = *(CColumnHeader *)dataPointer;
+ columnHeader.Version = kColumnInfoVersion;
+
+ // columnHeader.SortIndex = viewInfo.SortIndex;
+ columnHeader.SortID = viewInfo.SortID;
+
+ columnHeader.Ascending = viewInfo.Ascending ? 1 : 0;
+ CColumnInfoSpec *destItems = (CColumnInfoSpec *)(dataPointer + sizeof(CColumnHeader));
+ for(int i = 0; i < columns.Size(); i++)
+ {
+ CColumnInfoSpec &columnInfoSpec = destItems[i];
+ columnInfoSpec.GetFromColumnInfo(columns[i]);
+ }
+ {
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ CSysString keyName = kCUBasePath;
+ keyName += kKeyNameDelimiter;
+ keyName += kCulumnsKeyName;
+ CKey key;
+ key.Create(HKEY_CURRENT_USER, keyName);
+ key.SetValue(id, dataPointer, dataSize);
+ }
+}
+
+void ReadListViewInfo(const CSysString &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(id, buffer, size) != ERROR_SUCCESS)
+ return;
+ }
+ if (size < sizeof(CColumnHeader))
+ return;
+ BYTE *dataPointer = (BYTE *)buffer;
+ const CColumnHeader &columnHeader = *(CColumnHeader*)dataPointer;
+ if (columnHeader.Version != kColumnInfoVersion)
+ return;
+ viewInfo.Ascending = (columnHeader.Ascending != 0);
+
+ // viewInfo.SortIndex = columnHeader.SortIndex;
+ viewInfo.SortID = columnHeader.SortID;
+
+ size -= sizeof(CColumnHeader);
+ if (size % sizeof(CColumnHeader) != 0)
+ return;
+ int numItems = size / sizeof(CColumnInfoSpec);
+ CColumnInfoSpec *specItems = (CColumnInfoSpec *)(dataPointer + sizeof(CColumnHeader));;
+ columns.Reserve(numItems);
+ for(int i = 0; i < numItems; i++)
+ {
+ CColumnInfo columnInfo;
+ specItems[i].PutColumnInfo(columnInfo);
+ columns.Add(columnInfo);
+ }
+}
+
+#pragma pack( push, PragmaWindowPosition)
+#pragma pack( push, 1)
+
+struct CWindowPosition
+{
+ RECT Rect;
+ UINT32 Maximized;
+};
+
+struct CPanelsInfo
+{
+ UINT32 NumPanels;
+ UINT32 CurrentPanel;
+ UINT32 SplitterPos;
+};
+
+#pragma pack(pop)
+#pragma pack(pop, PragmaWindowPosition)
+
+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;
+ position.Rect = rect;
+ position.Maximized = maximized ? 1: 0;
+ key.SetValue(kPositionValueName, &position, sizeof(position));
+}
+
+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 != sizeof(CWindowPosition))
+ return false;
+ const CWindowPosition &position = *(const CWindowPosition *)(const BYTE *)buffer;
+ rect = position.Rect;
+ maximized = (position.Maximized != 0);
+ 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);
+ CPanelsInfo block;
+ block.NumPanels = numPanels;
+ block.CurrentPanel = currentPanel;
+ block.SplitterPos = splitterPos;
+ key.SetValue(kPanelsInfoValueName, &block, sizeof(block));
+}
+
+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 != sizeof(CPanelsInfo))
+ return false;
+ const CPanelsInfo &block = *(const CPanelsInfo *)(const BYTE *)buffer;
+ numPanels = block.NumPanels;
+ currentPanel = block.CurrentPanel;
+ splitterPos = block.SplitterPos;
+ return true;
+}
+
+void SaveToolbarsMask(UINT32 toolbarMask)
+{
+ CKey key;
+ key.Create(HKEY_CURRENT_USER, kCUBasePath);
+ key.SetValue(kToolbars, toolbarMask);
+}
+
+static const 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 CSysString GetPanelPathName(UINT32 panelIndex)
+{
+ TCHAR panelString[32];
+ ConvertUINT64ToString(panelIndex, panelString);
+ return CSysString(kPanelPathValueName) + panelString;
+}
+
+
+void SavePanelPath(UINT32 panel, const CSysString &path)
+{
+ CSysString keyName = kCUBasePath;
+ CKey key;
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ key.Create(HKEY_CURRENT_USER, keyName);
+ key.SetValue(GetPanelPathName(panel), path);
+}
+
+bool ReadPanelPath(UINT32 panel, CSysString &path)
+{
+ CSysString keyName = kCUBasePath;
+ CKey key;
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ if(key.Open(HKEY_CURRENT_USER, keyName, KEY_READ) != ERROR_SUCCESS)
+ return false;
+ return (key.QueryValue(GetPanelPathName(panel), path) == ERROR_SUCCESS);
+}
+
+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 aPos = 0;
+ for (i = 0; i < folders.Size(); i++)
+ {
+ wcscpy(buffer + aPos, folders[i]);
+ aPos += 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.CollateNoCase(list[i]) == 0)
+ list.Delete(i);
+ else
+ i++;
+ list.Insert(0, string);
+}
+
diff --git a/7zip/FileManager/ViewSettings.h b/7zip/FileManager/ViewSettings.h
new file mode 100755
index 00000000..5d2f509d
--- /dev/null
+++ b/7zip/FileManager/ViewSettings.h
@@ -0,0 +1,95 @@
+// ViewSettings.h
+
+#pragma once
+
+#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;
+ // int SortIndex;
+ PROPID SortID;
+ bool Ascending;
+
+ void Clear()
+ {
+ // SortIndex = -1;
+ 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 OrderItems();
+};
+
+void SaveListViewInfo(const CSysString &anID, const CListViewInfo &viewInfo);
+void ReadListViewInfo(const CSysString &anID, 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 CSysString &path);
+bool ReadPanelPath(UINT32 panel, CSysString &path);
+
+void SaveFolderHistory(const UStringVector &folders);
+void ReadFolderHistory(UStringVector &folders);
+
+void SaveFastFolders(const UStringVector &folders);
+void ReadFastFolders(UStringVector &folders);
+
+void SaveCopyHistory(const UStringVector &folders);
+void ReadCopyHistory(UStringVector &folders);
+
+void AddUniqueStringToHeadOfList(UStringVector &list,
+ const UString &string);
+
+#endif
diff --git a/7zip/FileManager/resource.h b/7zip/FileManager/resource.h
new file mode 100755
index 00000000..e8d2b612
--- /dev/null
+++ b/7zip/FileManager/resource.h
@@ -0,0 +1,137 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#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_PROPERTIES 240
+#define IDM_FILE_COMMENT 241
+#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_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_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_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
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 4020
+#define _APS_NEXT_COMMAND_VALUE 40078
+#define _APS_NEXT_CONTROL_VALUE 3000
+#define _APS_NEXT_SYMED_VALUE 4010
+#endif
+#endif
diff --git a/7zip/FileManager/resource.rc b/7zip/FileManager/resource.rc
new file mode 100755
index 00000000..293559b4
--- /dev/null
+++ b/7zip/FileManager/resource.rc
@@ -0,0 +1,414 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""Resource\\ComboDialog\\resource.rc""\r\n"
+ "#include ""Resource\\CopyDialog\\resource.rc""\r\n"
+ "#include ""Resource\\ListViewDialog\\resource.rc""\r\n"
+ "#include ""Resource\\PropertyName\\resource.rc""\r\n"
+ "#include ""Resource\\MessagesDialog\\resource.rc""\r\n"
+ "#include ""Resource\\OverwriteDialog\\resource.rc""\r\n"
+ "#include ""Resource\\PasswordDialog\\resource.rc""\r\n"
+ "#include ""Resource\\ProgressDialog2\\resource.rc""\r\n"
+ "#include ""Resource\\BenchmarkDialog\\resource.rc""\r\n"
+ "#include ""Resource\\AboutDialog\\resource.rc""\r\n"
+ "#include ""Resource\\LangPage\\resource.rc""\r\n"
+ "#include ""Resource\\PluginsPage\\resource.rc""\r\n"
+ "#include ""Resource\\SystemPage\\resource.rc""\r\n"
+ "#include ""Resource\\EditPage\\resource.rc""\r\n"
+ "#include ""Resource\\SettingsPage\\resource.rc""\r\n"
+ "#include ""..\\UI\\Resource\\Extract\\resource.rc""\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,13,0,0
+ PRODUCTVERSION 3,13,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "7-Zip File Manager\0"
+ VALUE "FileVersion", "3, 13, 0, 0\0"
+ VALUE "InternalName", "7zFM\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "7zFM.exe\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 13, 0, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+IDR_ACCELERATOR1 ACCELERATORS DISCARDABLE
+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
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDM_MENU MENU DISCARDABLE
+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 "&View\tF3", IDM_FILE_VIEW, GRAYED
+ 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 "P&roperties\tAlt+Enter", IDM_FILE_PROPERTIES
+ MENUITEM "Comme&nt\tCtrl+Z", IDM_FILE_COMMENT
+ 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 "&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
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_FM ICON DISCARDABLE "FM.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// 24
+//
+
+1 24 MOVEABLE PURE "7zFM.exe.manifest"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDB_ADD BITMAP DISCARDABLE "Add.bmp"
+IDB_EXTRACT BITMAP DISCARDABLE "Extract.bmp"
+IDB_TEST BITMAP DISCARDABLE "Test.bmp"
+IDB_COPY BITMAP DISCARDABLE "Copy.bmp"
+IDB_MOVE BITMAP DISCARDABLE "Move.bmp"
+IDB_DELETE BITMAP DISCARDABLE "Delete.bmp"
+IDB_INFO BITMAP DISCARDABLE "Info.bmp"
+IDB_ADD2 BITMAP DISCARDABLE "Add2.bmp"
+IDB_EXTRACT2 BITMAP DISCARDABLE "Extract2.bmp"
+IDB_TEST2 BITMAP DISCARDABLE "Test2.bmp"
+IDB_COPY2 BITMAP DISCARDABLE "Copy2.bmp"
+IDB_MOVE2 BITMAP DISCARDABLE "Move2.bmp"
+IDB_DELETE2 BITMAP DISCARDABLE "Delete2.bmp"
+IDB_INFO2 BITMAP DISCARDABLE "Info2.bmp"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+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."
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ 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"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ 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"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ 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:"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_FOLDERS_HISTORY "Folders History"
+ IDS_N_SELECTED_ITEMS "{0} object(s) selected"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_PROPERTY_TOTAL_SIZE "Total Size"
+ IDS_PROPERTY_FREE_SPACE "Free Space"
+ IDS_PROPERTY_CLUSTER_SIZE "Cluster Size"
+ IDS_PROPERTY_VOLUME_NAME "Label"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_PROPERTY_LOCAL_NAME "Local Name"
+ IDS_PROPERTY_PROVIDER "Provider"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_OPTIONS "Options"
+ IDS_COMMENT "Comment"
+ IDS_COMMENT2 "&Comment:"
+ IDS_SYSTEM "System"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ 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..."
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_ADD "Add"
+ IDS_EXTRACT "Extract"
+ IDS_TEST "Test"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_BUTTON_COPY "Copy"
+ IDS_BUTTON_MOVE "Move"
+ IDS_BUTTON_DELETE "Delete"
+ IDS_BUTTON_INFO "Info"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_BOOKMARK "Bookmark"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_COMPUTER "Computer"
+ IDS_NETWORK "Network"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#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\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"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/ICoder.h b/7zip/ICoder.h
new file mode 100755
index 00000000..0068bef0
--- /dev/null
+++ b/7zip/ICoder.h
@@ -0,0 +1,127 @@
+// ICoder.h
+
+// #pragma once
+
+#ifndef __ICODER_H
+#define __ICODER_H
+
+#include "IStream.h"
+
+// {23170F69-40C1-278A-0000-000200040000}
+DEFINE_GUID(IID_ICompressProgressInfo,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000200040000")
+ICompressProgressInfo: public IUnknown
+{
+ STDMETHOD(SetRatioInfo)(const UINT64 *inSize, const UINT64 *outSize) = 0;
+};
+
+// {23170F69-40C1-278A-0000-000200050000}
+DEFINE_GUID(IID_ICompressCoder,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000200050000")
+ICompressCoder: public IUnknown
+{
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UINT64 *inSize,
+ const UINT64 *outSize,
+ ICompressProgressInfo *progress) = 0;
+};
+
+// {23170F69-40C1-278A-0000-000200180000}
+DEFINE_GUID(IID_ICompressCoder2,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x18, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000200180000")
+ICompressCoder2: public IUnknown
+{
+ 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,
+ kNumPasses = 0x460,
+ kAlgorithm = 0x470,
+ kMultiThread = 0x480
+ };
+}
+
+// {23170F69-40C1-278A-0000-000200200000}
+DEFINE_GUID(IID_ICompressSetCoderProperties,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x20, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000200200000")
+ICompressSetCoderProperties: public IUnknown
+{
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
+ const PROPVARIANT *properties, UINT32 numProperties) PURE;
+};
+
+// {23170F69-40C1-278A-0000-000200210000}
+DEFINE_GUID(IID_ICompressSetDecoderProperties,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x21, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000200210000")
+ICompressSetDecoderProperties: public IUnknown
+{
+ STDMETHOD(SetDecoderProperties)(ISequentialInStream *anInStream) PURE;
+};
+
+// {23170F69-40C1-278A-0000-000200230000}
+DEFINE_GUID(IID_ICompressWriteCoderProperties,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x23, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000200230000")
+ICompressWriteCoderProperties: public IUnknown
+{
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStreams) PURE;
+};
+
+// {23170F69-40C1-278A-0000-000200240000}
+DEFINE_GUID(IID_ICompressGetInStreamProcessedSize,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x24, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000200240000")
+ICompressGetInStreamProcessedSize: public IUnknown
+{
+ STDMETHOD(GetInStreamProcessedSize)(UINT64 *value) PURE;
+};
+
+// {23170F69-40C1-278A-0000-000200250000}
+DEFINE_GUID(IID_ICompressGetSubStreamSize,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x25, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000200250000")
+ICompressGetSubStreamSize: public IUnknown
+{
+ STDMETHOD(GetSubStreamSize)(UINT64 subStream, UINT64 *value) PURE;
+};
+
+//////////////////////
+// It's for DLL file
+namespace NMethodPropID
+{
+ enum EEnum
+ {
+ kID,
+ kName,
+ kDecoder,
+ kEncoder,
+ kInStreams,
+ kOutStreams,
+ kDescription,
+ };
+}
+
+#endif
diff --git a/7zip/IMyUnknown.h b/7zip/IMyUnknown.h
new file mode 100755
index 00000000..d614d99a
--- /dev/null
+++ b/7zip/IMyUnknown.h
@@ -0,0 +1,71 @@
+// IMyUnknown.h
+
+// #pragma once
+
+#ifndef __MYUNKNOWN_H
+#define __MYUNKNOWN_H
+
+#ifdef WIN32
+
+// #include <guiddef.h>
+#include <basetyps.h>
+
+#else
+
+#define HRESULT LONG
+#define STDMETHODCALLTYPE __stdcall
+#define STDMETHOD_(t, f) virtual t STDMETHODCALLTYPE f
+#define STDMETHOD(f) STDMETHOD_(HRESULT, f)
+#define STDMETHODIMP_(type) type STDMETHODCALLTYPE
+#define STDMETHODIMP STDMETHODIMP_(HRESULT)
+
+#define PURE = 0;
+
+typedef struct {
+ unsigned long Data1;
+ unsigned short Data2;
+ unsigned short Data3;
+ unsigned char Data4[8];
+} GUID;
+
+#ifdef __cplusplus
+ #define MY_EXTERN_C extern "C"
+#else
+ #define MY_EXTERN_C extern
+#endif
+
+#ifdef INITGUID
+ #define MY_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+ MY_EXTERN_C const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
+#else
+ #define MY_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+ MY_EXTERN_C const GUID name
+#endif
+
+#ifdef __cplusplus
+#define REFGUID const GUID &
+#else
+#define REFGUID const GUID * __MIDL_CONST
+#endif
+
+#define MIDL_INTERFACE(x) struct
+inline int operator==(REFGUID g1, REFGUID g2)
+{
+ for (int i = 0; i < sizeof(g1); i++)
+ if (((unsigned char *)&g1)[i] != ((unsigned char *)&g2)[i])
+ return false;
+ return true;
+}
+inline int operator!=(REFGUID &g1, REFGUID &g2)
+ { return !(g1 == g2); }
+
+struct IUnknown
+{
+ STDMETHOD(QueryInterface) (const GUID *iid, void **outObject) PURE;
+ STDMETHOD_(ULONG, AddRef)() PURE;
+ STDMETHOD_(ULONG, Release)() PURE;
+};
+
+#endif
+
+#endif
diff --git a/7zip/IPassword.h b/7zip/IPassword.h
new file mode 100755
index 00000000..301031ae
--- /dev/null
+++ b/7zip/IPassword.h
@@ -0,0 +1,47 @@
+// IPassword.h
+
+// #pragma once
+
+#ifndef __IPASSWORD_H
+#define __IPASSWORD_H
+
+// #include "Common/Types.h"
+
+// {23170F69-40C1-278A-0000-000200250000}
+DEFINE_GUID(IID_ICryptoSetPassword,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x25, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000200250000")
+ICryptoSetPassword: public IUnknown
+{
+ STDMETHOD(CryptoSetPassword)(const BYTE *data, UINT32 size) PURE;
+};
+
+// {23170F69-40C1-278A-0000-000200251000}
+DEFINE_GUID(IID_ICryptoSetCRC,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x25, 0x10, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000200251000")
+ICryptoSetCRC: public IUnknown
+{
+ STDMETHOD(CryptoSetCRC)(UINT32 crc) PURE;
+};
+
+// {23170F69-40C1-278A-0000-000200270000}
+DEFINE_GUID(IID_ICryptoGetTextPassword,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000200270000")
+ICryptoGetTextPassword: public IUnknown
+{
+ STDMETHOD(CryptoGetTextPassword)(BSTR *password) PURE;
+};
+
+// {23170F69-40C1-278A-0000-000200270200}
+DEFINE_GUID(IID_ICryptoGetTextPassword2,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, 0x02, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000200270200")
+ICryptoGetTextPassword2: public IUnknown
+{
+ STDMETHOD(CryptoGetTextPassword2)(INT32 *passwordIsDefined, BSTR *password) PURE;
+};
+
+#endif
+
diff --git a/7zip/IProgress.h b/7zip/IProgress.h
new file mode 100755
index 00000000..db14b051
--- /dev/null
+++ b/7zip/IProgress.h
@@ -0,0 +1,32 @@
+// Interface/IProgress.h
+
+// #pragma once
+
+#ifndef __IPROGRESS_H
+#define __IPROGRESS_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
+{
+public:
+ 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/7zip/IStream.h b/7zip/IStream.h
new file mode 100755
index 00000000..147be411
--- /dev/null
+++ b/7zip/IStream.h
@@ -0,0 +1,64 @@
+// IStream.h
+
+// #pragma once
+
+#ifndef __ISTREAMS_H
+#define __ISTREAMS_H
+
+#include "IMyUnknown.h"
+
+// {23170F69-40C1-278A-0000-000000010000}
+DEFINE_GUID(IID_ISequentialInStream,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000000010000")
+ISequentialInStream : public IUnknown
+{
+public:
+ // out: if (processedSize == 0) then there are no more bytes
+ STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize) = 0;
+ STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize) = 0;
+};
+
+// {23170F69-40C1-278A-0000-000000020000}
+DEFINE_GUID(IID_ISequentialOutStream,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000000020000")
+ISequentialOutStream : public IUnknown
+{
+public:
+ STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize) = 0;
+ STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize) = 0;
+};
+
+// {23170F69-40C1-278A-0000-000000030000}
+DEFINE_GUID(IID_IInStream,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000000030000")
+IInStream : public ISequentialInStream
+{
+public:
+ STDMETHOD(Seek)(INT64 offset, UINT32 seekOrigin, UINT64 *newPosition) = 0;
+};
+
+// {23170F69-40C1-278A-0000-000000040000}
+DEFINE_GUID(IID_IOutStream,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000000040000")
+IOutStream : public ISequentialOutStream
+{
+public:
+ STDMETHOD(Seek)(INT64 offset, UINT32 seekOrigin, UINT64 *newPosition) = 0;
+ STDMETHOD(SetSize)(INT64 aNewSize) = 0;
+};
+
+// {23170F69-40C1-278A-0000-000000060000}
+DEFINE_GUID(IID_IStreamGetSize,
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000000060000")
+IStreamGetSize : public IUnknown
+{
+public:
+ STDMETHOD(GetSize)(UINT64 *size) = 0;
+};
+
+#endif
diff --git a/7zip/PropID.h b/7zip/PropID.h
new file mode 100755
index 00000000..d0e8e86e
--- /dev/null
+++ b/7zip/PropID.h
@@ -0,0 +1,51 @@
+// Interface/PropID.h
+
+// #pragma once
+
+#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,
+
+ kpidTotalSize = 0x1100,
+ kpidFreeSpace,
+ kpidClusterSize,
+ kpidVolumeName,
+
+ kpidLocalName = 0x1200,
+ kpidProvider,
+
+ kpidUserDefined = 0x10000
+};
+
+#endif
diff --git a/7zip/UI/Agent/Agent.cpp b/7zip/UI/Agent/Agent.cpp
new file mode 100755
index 00000000..2e59769a
--- /dev/null
+++ b/7zip/UI/Agent/Agent.cpp
@@ -0,0 +1,407 @@
+// 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/OpenArchive.h"
+#include "../Common/DefaultName.h"
+
+#include "Agent.h"
+#include "ArchiveExtractCallback.h"
+
+#ifdef FORMAT_7Z
+#include "../../Archive/7z/7zHandler.h"
+#endif
+
+using namespace NWindows;
+
+STDMETHODIMP CAgentFolder::GetAgentFolder(CAgentFolder **agentFolder)
+{
+ *agentFolder = this;
+ return S_OK;
+}
+
+STDMETHODIMP CAgentFolder::LoadItems()
+{
+ return S_OK;
+}
+
+STDMETHODIMP CAgentFolder::GetNumberOfItems(UINT32 *numItems)
+{
+ *numItems = _proxyFolderItem->Folders.Size() +
+ _proxyFolderItem->Files.Size();
+ return S_OK;
+}
+
+/*
+STDMETHODIMP CAgentFolder::GetNumberOfSubFolders(UINT32 *aNumSubFolders)
+{
+ *aNumSubFolders = _proxyFolderItem->Folders.Size();
+ return S_OK;
+}
+*/
+
+STDMETHODIMP CAgentFolder::GetProperty(UINT32 itemIndex, PROPID propID, PROPVARIANT *value)
+{
+ NCOM::CPropVariant propVariant;
+ if (itemIndex < (UINT32)_proxyFolderItem->Folders.Size())
+ {
+ const CProxyFolder &item = _proxyFolderItem->Folders[itemIndex];
+ switch(propID)
+ {
+ case kpidIsFolder:
+ propVariant = true;
+ break;
+ case kpidName:
+ propVariant = item.Name;
+ break;
+ default:
+ if (item.IsLeaf)
+ return _agentSpec->_archive->GetProperty(item.Index,
+ propID, value);
+ }
+ }
+ else
+ {
+ itemIndex -= _proxyFolderItem->Folders.Size();
+ const CProxyFile &item = _proxyFolderItem->Files[itemIndex];
+ switch(propID)
+ {
+ case kpidIsFolder:
+ propVariant = false;
+ break;
+ case kpidName:
+ propVariant = item.Name;
+ break;
+ default:
+ return _agentSpec->_archive->GetProperty(item.Index,
+ propID, value);
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
+
+STDMETHODIMP CAgentFolder::BindToFolder(UINT32 index, IFolderFolder **resultFolder)
+{
+ COM_TRY_BEGIN
+ if (index >= (UINT32)_proxyFolderItem->Folders.Size())
+ return E_INVALIDARG;
+ CAgentFolder *folderSpec = new CAgentFolder;
+ CMyComPtr<IFolderFolder> agentFolder = folderSpec;
+ folderSpec->Init(_proxyArchive, &_proxyFolderItem->Folders[index],
+ this, _agentSpec);
+ *resultFolder = agentFolder.Detach();
+ return S_OK;
+ 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
+ return _agentSpec->_archive->GetNumberOfProperties(numProperties);
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgentFolder::GetPropertyInfo(UINT32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType)
+{
+ COM_TRY_BEGIN
+ RINOK(_agentSpec->_archive->GetPropertyInfo(index, name, propID, varType));
+ if (*propID == kpidPath)
+ *propID = kpidName;
+ 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;
+ while (true)
+ {
+ 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
+}
+#endif
+
+
+STDMETHODIMP CAgentFolder::Extract(const UINT32 *indices,
+ UINT32 numItems,
+ NExtractionMode::NPath::EEnum pathMode,
+ NExtractionMode::NOverwrite::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;
+ }
+ extractCallbackSpec->Init(_agentSpec->_archive,
+ extractCallback2,
+ path,
+ pathMode,
+ overwriteMode,
+ pathParts,
+ _agentSpec->DefaultName,
+ _agentSpec->DefaultTime,
+ _agentSpec->DefaultAttributes
+ // ,_agentSpec->_srcDirectoryPrefix
+ );
+ CUIntVector realIndices;
+ _proxyFolderItem->GetRealIndices(indices, numItems, realIndices);
+ return _agentSpec->_archive->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 archiverInfo;
+ int subExtIndex;
+ HRESULT res = OpenArchive(_archiveFilePath,
+ #ifndef EXCLUDE_COM
+ &_library,
+ #endif
+ &_archive, archiverInfo, subExtIndex, openArchiveCallback);
+ RINOK(res);
+ DefaultName = GetDefaultName(_archiveFilePath,
+ archiverInfo.Extensions[subExtIndex].Extension,
+ archiverInfo.Extensions[subExtIndex].AddExtension);
+ DefaultTime = fileInfo.LastWriteTime;
+ DefaultAttributes = fileInfo.Attributes;
+ ArchiveType = archiverInfo.Name;
+ if (archiveType != 0)
+ {
+ CMyComBSTR name = archiverInfo.Name;
+ *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(_archive, _archiveFilePath));
+ return ReadItems();
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgent::Close()
+{
+ COM_TRY_BEGIN
+ return _archive->Close();
+ 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(_archive,
+ 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(
+ NExtractionMode::NPath::EEnum pathMode,
+ NExtractionMode::NOverwrite::EEnum overwriteMode,
+ const wchar_t *path,
+ INT32 testMode,
+ IFolderArchiveExtractCallback *extractCallback2)
+{
+ COM_TRY_BEGIN
+ CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
+ CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
+ extractCallbackSpec->Init(_archive,
+ extractCallback2,
+ path,
+ pathMode,
+ overwriteMode,
+ UStringVector(),
+ DefaultName,
+ DefaultTime,
+ DefaultAttributes
+ // ,_srcDirectoryPrefix
+ );
+ return _archive->Extract(0, -1, testMode, extractCallback);
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgent::GetNumberOfProperties(UINT32 *numProperties)
+{
+ COM_TRY_BEGIN
+ return _archive->GetNumberOfProperties(numProperties);
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgent::GetPropertyInfo(UINT32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType)
+{
+ COM_TRY_BEGIN
+ RINOK(_archive->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 _archive->GetArchiveProperty(propID, value);
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgent::GetNumberOfArchiveProperties(UINT32 *numProperties)
+{
+ COM_TRY_BEGIN
+ return _archive->GetNumberOfArchiveProperties(numProperties);
+ COM_TRY_END
+}
+
+STDMETHODIMP CAgent::GetArchivePropertyInfo(UINT32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType)
+{
+ COM_TRY_BEGIN
+ return _archive->GetArchivePropertyInfo(index,
+ name, propID, varType);
+ COM_TRY_END
+}
+
diff --git a/7zip/UI/Agent/Agent.h b/7zip/UI/Agent/Agent.h
new file mode 100755
index 00000000..b3c73a5c
--- /dev/null
+++ b/7zip/UI/Agent/Agent.h
@@ -0,0 +1,292 @@
+// Agent/Agent.h
+
+#pragma once
+
+#ifndef __AGENT_AGENT_H
+#define __AGENT_AGENT_H
+
+#include "Windows/PropVariant.h"
+#include "Common/MyCom.h"
+
+#include "../Common/UpdateAction.h"
+#include "../Common/ArchiverInfo.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;
+};
+
+class CAgent;
+
+class CAgentFolder:
+ public IFolderFolder,
+ public IArchiveFolder,
+ public IArchiveFolderInternal,
+#ifdef NEW_FOLDER_INTERFACE
+ public IEnumProperties,
+ public IFolderGetTypeID,
+ public IFolderGetPath,
+ public IFolderOperations,
+#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)
+ #endif
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
+
+ // IFolderFolder
+
+ 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,
+ NExtractionMode::NPath::EEnum pathMode,
+ NExtractionMode::NOverwrite::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);
+
+
+#endif
+
+ CAgentFolder(): _proxyFolderItem(NULL) {}
+
+ 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);
+
+
+public:
+ CProxyArchive *_proxyArchive;
+ CProxyFolder *_proxyFolderItem;
+ CMyComPtr<IFolderFolder> _parentFolder;
+ CMyComPtr<IInFolderArchive> _agent;
+ CAgent *_agentSpec;
+};
+
+// {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)(
+ NExtractionMode::NPath::EEnum pathMode,
+ NExtractionMode::NOverwrite::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 BSTR *names, const PROPVARIANT *values, INT32 numProperties);
+ #endif
+
+ CAgent();
+ ~CAgent();
+private:
+ HRESULT ReadItems();
+public:
+ CProxyArchive *_proxyArchive;
+
+ #ifndef EXCLUDE_COM
+ NWindows::NDLL::CLibrary _library;
+ #endif
+
+ CMyComPtr<IInArchive> _archive;
+
+ // CLSID _CLSID;
+ // CMyComPtr<IArchiveFolder> m_RootFolder;
+
+ UString DefaultName;
+ FILETIME DefaultTime;
+ UINT32 DefaultAttributes;
+
+ UString ArchiveType;
+
+ UStringVector _names;
+ UString _folderPrefix;
+
+ UString _archiveNamePrefix;
+ CProxyFolder *_archiveFolderItem;
+
+ UString _archiveFilePath;
+
+ #ifndef EXTRACT_ONLY
+ CObjectVector<CMyComBSTR> m_PropNames;
+ std::vector<NWindows::NCOM::CPropVariant> m_PropValues;
+ #endif
+};
+
+#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/7zip/UI/Agent/AgentOut.cpp b/7zip/UI/Agent/AgentOut.cpp
new file mode 100755
index 00000000..7f1f8e77
--- /dev/null
+++ b/7zip/UI/Agent/AgentOut.cpp
@@ -0,0 +1,469 @@
+// Zip/Handler.cpp
+
+#include "StdAfx.h"
+
+#include "../Common/UpdatePair.h"
+#include "../Common/EnumDirItems.h"
+#include "../Common/HandlerLoader.h"
+// #include "../Common/UpdatePairAction.h"
+// #include "../Common/CompressEngineCommon.h"
+// #include "../Common/UpdateProducer.h"
+#include "../../Compress/Copy/CopyCoder.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 "Agent.h"
+#include "ArchiveUpdateCallback.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)
+ {
+ _archiveFolderItem = NULL;
+ return S_OK;
+ // folder = m_RootFolder;
+ }
+ else
+ {
+ CMyComPtr<IFolderFolder> archiveFolder = folder;
+ CMyComPtr<IArchiveFolderInternal> archiveFolderInternal;
+ RINOK(archiveFolder.QueryInterface(
+ IID_IArchiveFolderInternal, &archiveFolderInternal));
+ CAgentFolder *agentFolder;
+ RINOK(archiveFolderInternal->GetAgentFolder(&agentFolder));
+ _archiveFolderItem = agentFolder->_proxyFolderItem;
+ }
+
+ UStringVector pathParts;
+ pathParts.Clear();
+ CMyComPtr<IFolderFolder> folderItem = folder;
+ if (_archiveFolderItem != NULL)
+ while (true)
+ {
+ 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 (int 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->_archive->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->_archive->GetProperty(fileItem.Index, kpidSize, &property);
+ if (archiveItem.SizeIsDefined = (property.vt != VT_EMPTY))
+ 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)
+{
+ NUpdateArchive::CActionSet actionSet;
+ for (int 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);
+ ::EnumerateDirItems(folderPrefix, _names, _archiveNamePrefix, dirItems);
+
+ CMyComPtr<IOutArchive> outArchive;
+ if (_archive)
+ {
+ RINOK(_archive.QueryInterface(IID_IOutArchive, &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 (_archive)
+ {
+ RINOK(ReadItems());
+ EnumerateArchiveItems(this, _proxyArchive->RootFolder, L"", archiveItems);
+ }
+
+ GetUpdatePairInfoList(dirItems, archiveItems, fileTimeType, updatePairs);
+
+ CObjectVector<CUpdatePair2> operationChain;
+ UpdateProduce(dirItems, archiveItems, updatePairs, actionSet,
+ operationChain);
+
+ CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
+ CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec );
+
+ updateCallbackSpec->Init(folderPrefix,&dirItems, &archiveItems,
+ &operationChain, NULL, updateCallback100);
+
+ 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->Open(archiveName))
+ {
+ // ShowLastErrorMessage();
+ return E_FAIL;
+ }
+
+ CMyComPtr<ISetProperties> setProperties;
+ if (outArchive->QueryInterface(&setProperties) == S_OK)
+ {
+ if (m_PropNames.Size() == 0)
+ {
+ RINOK(setProperties->SetProperties(0, 0, 0));
+ }
+ else
+ {
+ std::vector<BSTR> names;
+ for(i = 0; i < m_PropNames.Size(); i++)
+ names.push_back(m_PropNames[i]);
+ RINOK(setProperties->SetProperties(&names.front(),
+ &m_PropValues.front(), names.size()));
+ }
+ }
+ 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, operationChain.Size(),
+ updateCallback);
+}
+
+
+HRESULT CAgent::CommonUpdate(const wchar_t *newArchiveName,
+ int numUpdateItems,
+ IArchiveUpdateCallback *updateCallback)
+{
+ CMyComPtr<IOutArchive> outArchive;
+ RINOK(_archive.QueryInterface(IID_IOutArchive, &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));
+ }
+ if (!outStreamSpec->Open(archiveName))
+ {
+ // ShowLastErrorMessage();
+ return E_FAIL;
+ }
+
+ return outArchive->UpdateItems(outStream, numUpdateItems, updateCallback);
+}
+
+
+STDMETHODIMP CAgent::DeleteItems(
+ const wchar_t *newArchiveName,
+ const UINT32 *indices, UINT32 numItems,
+ IFolderArchiveUpdateCallback *updateCallback100)
+{
+ CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
+ CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
+
+ CUIntVector realIndices;
+ _archiveFolderItem->GetRealIndices(indices, numItems, realIndices);
+ CObjectVector<CUpdatePair2> updatePairs;
+ int curIndex = 0;
+ UINT32 numItemsInArchive;
+ RINOK(_archive->GetNumberOfItems(&numItemsInArchive));
+ for (int 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;
+ updatePair.ArchiveItemIndex = i;
+ updatePairs.Add(updatePair);
+ }
+ updateCallbackSpec->Init(L"", NULL, NULL, &updatePairs, NULL, updateCallback100);
+ return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback);
+}
+
+HRESULT CAgent::CreateFolder(
+ const wchar_t *newArchiveName,
+ const wchar_t *folderName,
+ IFolderArchiveUpdateCallback *updateCallback100)
+{
+ CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
+ CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
+
+ CObjectVector<CUpdatePair2> updatePairs;
+ UINT32 numItemsInArchive;
+ RINOK(_archive->GetNumberOfItems(&numItemsInArchive));
+ for (int i = 0; i < numItemsInArchive; i++)
+ {
+ CUpdatePair2 updatePair;
+ updatePair.NewData = updatePair.NewProperties = false;
+ updatePair.ExistInArchive = true;
+ updatePair.ExistOnDisk = false;
+ updatePair.IsAnti = false;
+ 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 = _archiveFolderItem->GetFullPathPrefix() + folderName;
+
+ SYSTEMTIME systemTime;
+ FILETIME fileTime;
+ ::GetSystemTime(&systemTime);
+ ::SystemTimeToFileTime(&systemTime, &fileTime);
+ dirItem.LastAccessTime = dirItem.LastWriteTime =
+ dirItem.CreationTime = fileTime;
+
+ dirItems.Add(dirItem);
+
+ updateCallbackSpec->Init(L"", &dirItems, NULL, &updatePairs, NULL, updateCallback100);
+ 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 (numItems != 1)
+ return E_INVALIDARG;
+ CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
+ CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
+
+ CUIntVector realIndices;
+ _archiveFolderItem->GetRealIndices(indices, numItems, realIndices);
+
+ UString fullPrefix = _archiveFolderItem->GetFullPathPrefix();
+ UString oldItemPath = fullPrefix +
+ _archiveFolderItem->GetItemName(indices[0]);
+ UString newItemPath = fullPrefix + newItemName;
+
+ CObjectVector<CUpdatePair2> updatePairs;
+ int curIndex = 0;
+ UINT32 numItemsInArchive;
+ RINOK(_archive->GetNumberOfItems(&numItemsInArchive));
+ for (int 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;
+ updatePair.IsAnti = false; // ?
+ updatePair.ArchiveItemIndex = i;
+ updatePair.NewNameIsDefined = true;
+
+ updatePair.NewName = newItemName;
+
+ UString oldFullPath;
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(_archive->GetProperty(
+ updatePair.ArchiveItemIndex, kpidPath, &propVariant));
+ if (propVariant.vt != VT_BSTR)
+ return E_INVALIDARG;
+ oldFullPath = propVariant.bstrVal;
+ }
+ if (oldItemPath.CollateNoCase(oldFullPath.Left(oldItemPath.Length())) != 0)
+ return E_INVALIDARG;
+
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(_archive->GetProperty(i, kpidIsAnti, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ updatePair.IsAnti = false;
+ else if (propVariant.vt != VT_BOOL)
+ return E_INVALIDARG;
+ else
+ updatePair.IsAnti = (propVariant.boolVal != VARIANT_FALSE);
+ }
+
+ 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->Init(L"", NULL, NULL, &updatePairs, _archive, updateCallback100);
+ return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback);
+}
+
+
+
+STDMETHODIMP CAgent::SetProperties(const BSTR *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.push_back(values[i]);
+ }
+ return S_OK;
+}
+
+
diff --git a/7zip/UI/Agent/AgentProxy.cpp b/7zip/UI/Agent/AgentProxy.cpp
new file mode 100755
index 00000000..f2627e6d
--- /dev/null
+++ b/7zip/UI/Agent/AgentProxy.cpp
@@ -0,0 +1,198 @@
+// AgentProxy.cpp
+
+#include "StdAfx.h"
+
+#include "AgentProxy.h"
+
+#include "Common/MyCom.h"
+#include "Windows/PropVariant.h"
+#include "Windows/Defs.h"
+
+using namespace NWindows;
+
+int CProxyFolder::FindDirSubItemIndex(const UString &name, int &insertPos) const
+{
+ int left = 0, right = Folders.Size();
+ while(true)
+ {
+ if (left == right)
+ {
+ insertPos = left;
+ return -1;
+ }
+ int mid = (left + right) / 2;
+ int compare = name.CollateNoCase(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);
+ for(int 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);
+ }
+ realIndices.Sort();
+}
+
+///////////////////////////////////////////////
+// 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(-1, false, fileName);
+ fileName.Empty();
+ }
+ else
+ fileName += c;
+ }
+ }
+
+ NCOM::CPropVariant propVariantIsFolder;
+ RINOK(archiveHandler->GetProperty(i,
+ kpidIsFolder, &propVariantIsFolder));
+ if(propVariantIsFolder.vt != VT_BOOL)
+ return E_FAIL;
+ if(VARIANT_BOOLToBool(propVariantIsFolder.boolVal))
+ currentItem->AddDirSubItem(i, true, fileName);
+ else
+ currentItem->AddFileSubItem(i, fileName);
+ }
+ return S_OK;
+}
+
diff --git a/7zip/UI/Agent/AgentProxy.h b/7zip/UI/Agent/AgentProxy.h
new file mode 100755
index 00000000..d07b8a10
--- /dev/null
+++ b/7zip/UI/Agent/AgentProxy.h
@@ -0,0 +1,58 @@
+// AgentProxy.h
+
+#pragma once
+
+#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/7zip/UI/Agent/ArchiveExtractCallback.cpp b/7zip/UI/Agent/ArchiveExtractCallback.cpp
new file mode 100755
index 00000000..90b390c2
--- /dev/null
+++ b/7zip/UI/Agent/ArchiveExtractCallback.cpp
@@ -0,0 +1,358 @@
+// ExtractCallback.cpp
+
+#include "StdAfx.h"
+
+#include "ArchiveExtractCallback.h"
+
+#include "Common/Wildcard.h"
+#include "Common/StringConvert.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"
+
+using namespace NWindows;
+
+void CArchiveExtractCallback::Init(
+ IInArchive *archiveHandler,
+ IFolderArchiveExtractCallback *extractCallback2,
+ const UString &directoryPath,
+ NExtractionMode::NPath::EEnum pathMode,
+ NExtractionMode::NOverwrite::EEnum overwriteMode,
+ const UStringVector &removePathParts,
+ const UString &itemDefaultName,
+ const FILETIME &utcLastWriteTimeDefault,
+ UINT32 attributesDefault)
+ // bool passwordIsDefined, const UString &password
+ // UString srcDirectoryPrefix)
+{
+ _extractCallback2 = extractCallback2;
+ // m_PasswordIsDefined = passwordIsDefined;
+ // m_Password = password;
+ _numErrors = 0;
+
+ _itemDefaultName = itemDefaultName;
+ _utcLastWriteTimeDefault = utcLastWriteTimeDefault;
+ _attributesDefault = attributesDefault;
+
+ _removePathParts = removePathParts;
+
+ _pathMode = pathMode;
+ _overwriteMode = overwriteMode;
+
+ _archiveHandler = archiveHandler;
+ _directoryPath = directoryPath;
+ NFile::NName::NormalizeDirPathPrefix(_directoryPath);
+
+ // _srcDirectoryPrefix = srcDirectoryPrefix;
+}
+
+STDMETHODIMP CArchiveExtractCallback::SetTotal(UINT64 size)
+{
+ return _extractCallback2->SetTotal(size);
+}
+
+STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UINT64 *completeValue)
+{
+ return _extractCallback2->SetCompleted(completeValue);
+}
+
+void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPathParts)
+{
+ UString fullPath = _directoryPath;
+ for(int i = 0; i < dirPathParts.Size(); i++)
+ {
+ fullPath += dirPathParts[i];
+ NFile::NDirectory::MyCreateDirectory(fullPath);
+ fullPath += wchar_t(NFile::NName::kDirDelimiter);
+ }
+}
+
+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;
+}
+
+
+STDMETHODIMP CArchiveExtractCallback::GetStream(UINT32 index,
+ ISequentialOutStream **outStream, INT32 askExtractMode)
+{
+ *outStream = 0;
+ _outFileStream.Release();
+ NCOM::CPropVariant propVariant;
+ RINOK(_archiveHandler->GetProperty(index, kpidPath, &propVariant));
+
+ UString fullPath;
+ if(propVariant.vt == VT_EMPTY)
+ {
+ fullPath = _itemDefaultName;
+ }
+ else
+ {
+ if(propVariant.vt != VT_BSTR)
+ return E_FAIL;
+ fullPath = propVariant.bstrVal;
+ }
+
+ // UString fullPathCorrect = GetCorrectPath(fullPath);
+ _filePath = fullPath;
+
+ if(askExtractMode == NArchive::NExtract::NAskMode::kExtract)
+ {
+ RINOK(_archiveHandler->GetProperty(index, kpidAttributes, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ {
+ _processedFileInfo.Attributes = _attributesDefault;
+ _processedFileInfo.AttributesAreDefined = false;
+ }
+ else
+ {
+ if (propVariant.vt != VT_UI4)
+ throw "incorrect item";
+ _processedFileInfo.Attributes = propVariant.ulVal;
+ _processedFileInfo.AttributesAreDefined = true;
+ }
+
+ RINOK(_archiveHandler->GetProperty(index, kpidIsFolder, &propVariant));
+ _processedFileInfo.IsDirectory = VARIANT_BOOLToBool(propVariant.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;
+ }
+
+ RINOK(_archiveHandler->GetProperty(index, kpidSize, &propVariant));
+ bool newFileSizeDefined = (propVariant.vt != VT_EMPTY);
+ UINT64 newFileSize;
+ if (newFileSizeDefined)
+ newFileSize = ConvertPropVariantToUINT64(propVariant);
+
+ bool isAnti = false;
+ {
+ NCOM::CPropVariant propVariantTemp;
+ RINOK(_archiveHandler->GetProperty(index, kpidIsAnti,
+ &propVariantTemp));
+ if (propVariantTemp.vt == VT_BOOL)
+ isAnti = VARIANT_BOOLToBool(propVariantTemp.boolVal);
+ }
+
+ UStringVector pathParts;
+
+ // SplitPathToParts(fullPathCorrect, pathParts);
+ SplitPathToParts(fullPath, pathParts);
+
+ if(pathParts.IsEmpty())
+ return E_FAIL;
+ UString processedPath;
+ switch(_pathMode)
+ {
+ case NExtractionMode::NPath::kFullPathnames:
+ {
+ // processedPath = fullPathCorrect;
+ processedPath = GetCorrectPath(fullPath);
+ break;
+ }
+ case NExtractionMode::NPath::kCurrentPathnames:
+ {
+ int numRemovePathParts = _removePathParts.Size();
+ if(pathParts.Size() <= numRemovePathParts)
+ return E_FAIL;
+ for(int i = 0; i < numRemovePathParts; i++)
+ if(_removePathParts[i].CollateNoCase(pathParts[i]) != 0)
+ return E_FAIL;
+ pathParts.Delete(0, numRemovePathParts);
+ processedPath = MakePathNameFromParts(pathParts);
+ processedPath = GetCorrectPath(processedPath);
+ break;
+ }
+ case NExtractionMode::NPath::kNoPathnames:
+ {
+ processedPath = pathParts.Back();
+ pathParts.Delete(0, pathParts.Size() - 1); // Test it!!
+ break;
+ }
+ }
+ if(!_processedFileInfo.IsDirectory)
+ pathParts.DeleteBack();
+
+ for(int i = 0; i < pathParts.Size(); i++)
+ pathParts[i] = GetCorrectFileName(pathParts[i]);
+
+ if (!isAnti)
+ if (!pathParts.IsEmpty())
+ CreateComplexDirectory(pathParts);
+
+
+ const UString fullProcessedPathUnicode = _directoryPath + processedPath;
+ UString fullProcessedPath = _directoryPath + processedPath;
+
+ if(_processedFileInfo.IsDirectory)
+ {
+ _diskFilePath = fullProcessedPath;
+ if (isAnti)
+ NFile::NDirectory::MyRemoveDirectory(_diskFilePath);
+ return S_OK;
+ }
+
+ NFile::NFind::CFileInfoW fileInfo;
+ if(NFile::NFind::FindFile(fullProcessedPath, fileInfo))
+ {
+ switch(_overwriteMode)
+ {
+ case NExtractionMode::NOverwrite::kSkipExisting:
+ return S_OK;
+ case NExtractionMode::NOverwrite::kAskBefore:
+ {
+ INT32 overwiteResult;
+ RINOK(_extractCallback2->AskOverwrite(
+ fullProcessedPathUnicode, &fileInfo.LastWriteTime, &fileInfo.Size,
+ fullPath, &_processedFileInfo.UTCLastWriteTime, newFileSizeDefined?
+ &newFileSize : NULL, &overwiteResult))
+
+ switch(overwiteResult)
+ {
+ case NOverwriteAnswer::kCancel:
+ return E_ABORT;
+ case NOverwriteAnswer::kNo:
+ return S_OK;
+ case NOverwriteAnswer::kNoToAll:
+ _overwriteMode = NExtractionMode::NOverwrite::kSkipExisting;
+ return S_OK;
+ case NOverwriteAnswer::kYesToAll:
+ _overwriteMode = NExtractionMode::NOverwrite::kWithoutPrompt;
+ break;
+ case NOverwriteAnswer::kYes:
+ break;
+ case NOverwriteAnswer::kAutoRename:
+ _overwriteMode = NExtractionMode::NOverwrite::kAutoRename;
+ break;
+ default:
+ throw 20413;
+ }
+ }
+ }
+ if (_overwriteMode == NExtractionMode::NOverwrite::kAutoRename)
+ {
+ if (!AutoRenamePath(fullProcessedPath))
+ {
+ UString message = UString(L"can not create name of file ") +
+ fullProcessedPathUnicode;
+ RINOK(_extractCallback2->MessageError(message));
+ return E_ABORT;
+ }
+ }
+ else
+ if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath))
+ {
+ UString message = UString(L"can not delete output file ") +
+ fullProcessedPathUnicode;
+ RINOK(_extractCallback2->MessageError(message));
+ return E_ABORT;
+ }
+ }
+ if (!isAnti)
+ {
+ _outFileStreamSpec = new COutFileStream;
+ CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
+ if (!_outFileStreamSpec->Open(fullProcessedPath))
+ {
+ UString message = L"can not open output file " + fullProcessedPathUnicode;
+ RINOK(_extractCallback2->MessageError(message));
+ return S_OK;
+ }
+ _outFileStream = outStreamLoc;
+ *outStream = outStreamLoc.Detach();
+ }
+ _diskFilePath = fullProcessedPath;
+ }
+ else
+ {
+ *outStream = NULL;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveExtractCallback::PrepareOperation(INT32 askExtractMode)
+{
+ _extractMode = false;
+ switch (askExtractMode)
+ {
+ case NArchive::NExtract::NAskMode::kExtract:
+ _extractMode = true;
+ };
+ return _extractCallback2->PrepareOperation(_filePath, askExtractMode);
+}
+
+void CArchiveExtractCallback::AddErrorMessage(LPCTSTR message)
+{
+ _messages.Add(message);
+}
+
+STDMETHODIMP CArchiveExtractCallback::SetOperationResult(INT32 operationResult)
+{
+ 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.SetLastWriteTime(&_processedFileInfo.UTCLastWriteTime);
+ _outFileStream.Release();
+ if (_extractMode && _processedFileInfo.AttributesAreDefined)
+ NFile::NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attributes);
+ RINOK(_extractCallback2->SetOperationResult(operationResult));
+ return S_OK;
+}
+
+/*
+STDMETHODIMP CArchiveExtractCallback::GetInStream(
+ const wchar_t *name, ISequentialInStream **inStream)
+{
+ CInFileStream *inFile = new CInFileStream;
+ CMyComPtr<ISequentialInStream> inStreamTemp = inFile;
+ if (!inFile->Open(_srcDirectoryPrefix + name))
+ return ::GetLastError();
+ *inStream = inStreamTemp.Detach();
+ return S_OK;
+}
+*/
+
+STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)
+{
+ if (!_cryptoGetTextPassword)
+ {
+ RINOK(_extractCallback2.QueryInterface(IID_ICryptoGetTextPassword,
+ &_cryptoGetTextPassword));
+ }
+ return _cryptoGetTextPassword->CryptoGetTextPassword(password);
+}
+
diff --git a/7zip/UI/Agent/ArchiveExtractCallback.h b/7zip/UI/Agent/ArchiveExtractCallback.h
new file mode 100755
index 00000000..bf0388ac
--- /dev/null
+++ b/7zip/UI/Agent/ArchiveExtractCallback.h
@@ -0,0 +1,107 @@
+// ArchiveExtractCallback.h
+
+#pragma once
+
+#ifndef __ARCHIVEEXTRACTCALLBACK_H
+#define __ARCHIVEEXTRACTCALLBACK_H
+
+#include "../../Archive/IArchive.h"
+#include "IFolderArchive.h"
+
+#include "Common/String.h"
+#include "Common/MyCom.h"
+
+#include "../../Common/FileStreams.h"
+#include "../../IPassword.h"
+
+class CArchiveExtractCallback:
+ public IArchiveExtractCallback,
+ // public IArchiveVolumeExtractCallback,
+ public ICryptoGetTextPassword,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP1(ICryptoGetTextPassword)
+ // COM_INTERFACE_ENTRY(IArchiveVolumeExtractCallback)
+
+ // IProgress
+ STDMETHOD(SetTotal)(UINT64 aize);
+ STDMETHOD(SetCompleted)(const UINT64 *completeValue);
+
+ // IExtractCallBack
+ STDMETHOD(GetStream)(UINT32 anIndex, 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;
+ NExtractionMode::NPath::EEnum _pathMode;
+ NExtractionMode::NOverwrite::EEnum _overwriteMode;
+
+ UString _filePath;
+
+ UString _diskFilePath;
+
+ CSysStringVector _messages;
+
+ bool _extractMode;
+ struct CProcessedFileInfo
+ {
+ FILETIME UTCLastWriteTime;
+ bool IsDirectory;
+ bool AttributesAreDefined;
+ UINT32 Attributes;
+ } _processedFileInfo;
+
+
+ COutFileStream *_outFileStreamSpec;
+ CMyComPtr<ISequentialOutStream> _outFileStream;
+ UStringVector _removePathParts;
+
+ UString _itemDefaultName;
+ FILETIME _utcLastWriteTimeDefault;
+ UINT32 _attributesDefault;
+
+ // bool m_PasswordIsDefined;
+ // UString m_Password;
+
+
+ // UString _srcDirectoryPrefix;
+
+ void CreateComplexDirectory(const UStringVector &dirPathParts);
+ /*
+ void GetPropertyValue(LPITEMIDLIST anItemIDList, PROPID aPropId,
+ PROPVARIANT *aValue);
+ bool IsEncrypted(LPITEMIDLIST anItemIDList);
+ */
+ void AddErrorMessage(LPCTSTR message);
+public:
+ // CProgressDialog m_ProcessDialog;
+ void Init(
+ IInArchive *archiveHandler,
+ IFolderArchiveExtractCallback *extractCallback2,
+ const UString &directoryPath,
+ NExtractionMode::NPath::EEnum pathMode,
+ NExtractionMode::NOverwrite::EEnum overwriteMode,
+ const UStringVector &removePathParts,
+ const UString &itemDefaultName,
+ const FILETIME &utcLastWriteTimeDefault,
+ UINT32 anAttributesDefault
+ // bool passwordIsDefined, const UString &password
+ // UString srcDirectoryPrefix
+ );
+
+ UINT64 _numErrors;
+};
+
+#endif
diff --git a/7zip/UI/Agent/ArchiveFolder.cpp b/7zip/UI/Agent/ArchiveFolder.cpp
new file mode 100755
index 00000000..4701653d
--- /dev/null
+++ b/7zip/UI/Agent/ArchiveFolder.cpp
@@ -0,0 +1,67 @@
+// 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 "Agent.h"
+#include "ArchiveExtractCallback.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));
+ }
+
+ extractCallbackSpec->Init(_agentSpec->_archive,
+ extractCallback2,
+ path,
+ NExtractionMode::NPath::kCurrentPathnames,
+ NExtractionMode::NOverwrite::kAskBefore,
+ pathParts,
+ _agentSpec->DefaultName,
+ _agentSpec->DefaultTime,
+ _agentSpec->DefaultAttributes
+ // ,_agentSpec->_srcDirectoryPrefix
+ );
+ CUIntVector realIndices;
+ _proxyFolderItem->GetRealIndices(indices, numItems, realIndices);
+ return _agentSpec->_archive->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/7zip/UI/Agent/ArchiveFolderOpen.cpp b/7zip/UI/Agent/ArchiveFolderOpen.cpp
new file mode 100755
index 00000000..2e6defc7
--- /dev/null
+++ b/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();
+ CComPtr<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++)
+ {
+ if (i != 0)
+ typesStrings += L' ';
+ typesStrings += _formats[i].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].GetAllExtensions();
+ CMyComBSTR valueTemp = _formats[formatIndex].Extensions[0].Extension;
+ *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/7zip/UI/Agent/ArchiveFolderOut.cpp b/7zip/UI/Agent/ArchiveFolderOut.cpp
new file mode 100755
index 00000000..fed01b78
--- /dev/null
+++ b/7zip/UI/Agent/ArchiveFolderOut.cpp
@@ -0,0 +1,219 @@
+// 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;
+ while (true)
+ {
+ 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] = 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 realIndices;
+ 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/7zip/UI/Agent/ArchiveUpdateCallback.cpp b/7zip/UI/Agent/ArchiveUpdateCallback.cpp
new file mode 100755
index 00000000..fd0c136e
--- /dev/null
+++ b/7zip/UI/Agent/ArchiveUpdateCallback.cpp
@@ -0,0 +1,229 @@
+// ArchiveUpdateCallback.h
+
+#include "StdAfx.h"
+
+#include "ArchiveUpdateCallback.h"
+
+#include "Common/StringConvert.h"
+#include "Common/Defs.h"
+
+#include "Windows/FileName.h"
+#include "Windows/PropVariant.h"
+
+#include "../../Common/FileStreams.h"
+
+#include "Windows/Defs.h"
+
+using namespace NWindows;
+
+void CArchiveUpdateCallback::Init(const UString &baseFolderPrefix,
+ const CObjectVector<CDirItem> *dirItems,
+ const CObjectVector<CArchiveItem> *archiveItems, // test CItemInfoExList
+ CObjectVector<CUpdatePair2> *updatePairs,
+ IInArchive *inArchive,
+ IFolderArchiveUpdateCallback *updateCallback)
+{
+ m_BaseFolderPrefix = baseFolderPrefix;
+ NFile::NName::NormalizeDirPathPrefix(m_BaseFolderPrefix);
+ m_DirItems = dirItems;
+ m_ArchiveItems = archiveItems;
+ m_UpdatePairs = updatePairs;
+ m_UpdateCallback = updateCallback;
+ m_CodePage = ::AreFileApisANSI() ? CP_ACP : CP_OEMCP;
+ _inArchive = inArchive;;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::SetTotal(UINT64 size)
+{
+ if (m_UpdateCallback)
+ return m_UpdateCallback->SetTotal(size);
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UINT64 *completeValue)
+{
+ if (m_UpdateCallback)
+ return m_UpdateCallback->SetCompleted(completeValue);
+ return S_OK;
+}
+
+/*
+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 **enumerator)
+{
+ return CStatPropEnumerator::CreateEnumerator(kProperties,
+ sizeof(kProperties) / sizeof(kProperties[0]), enumerator);
+}
+*/
+
+STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UINT32 index,
+ INT32 *newData, INT32 *newProperties, UINT32 *indexInArchive)
+{
+ const CUpdatePair2 &updatePair = (*m_UpdatePairs)[index];
+ if(newData != NULL)
+ *newData = BoolToInt(updatePair.NewData);
+ if(newProperties != NULL)
+ *newProperties = BoolToInt(updatePair.NewProperties);
+ if(indexInArchive != NULL)
+ {
+ if (updatePair.ExistInArchive)
+ {
+ if (m_ArchiveItems == 0)
+ *indexInArchive = updatePair.ArchiveItemIndex;
+ else
+ *indexInArchive = (*m_ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer;
+ }
+ else
+ *indexInArchive = UINT32(-1);
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
+{
+ const CUpdatePair2 &updatePair = (*m_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 = (*m_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 && _inArchive)
+ {
+ UINT32 indexInArchive;
+ if (m_ArchiveItems == 0)
+ indexInArchive = updatePair.ArchiveItemIndex;
+ else
+ indexInArchive = (*m_ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer;
+ return _inArchive->GetProperty(indexInArchive, propID, value);
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetStream(UINT32 index,
+ IInStream **inStream)
+{
+ const CUpdatePair2 &updatePair = (*m_UpdatePairs)[index];
+ if(!updatePair.NewData)
+ return E_FAIL;
+ const CDirItem &dirItem = (*m_DirItems)[updatePair.DirItemIndex];
+
+ /*
+ m_PercentPrinter.PrintString("Compressing ");
+ m_PercentCanBePrint = true;
+ m_PercentPrinter.PrintString(UnicodeStringToMultiByte(dirItem.Name, CP_OEMCP));
+ m_PercentPrinter.PreparePrint();
+ m_PercentPrinter.RePrintRatio();
+ */
+
+ if (m_UpdateCallback)
+ {
+ RINOK(m_UpdateCallback->CompressOperation(
+ GetUnicodeString(dirItem.FullPath, m_CodePage)));
+ }
+
+ if(dirItem.IsDirectory())
+ return S_OK;
+
+ CInFileStream *inStreamSpec = new CInFileStream;
+ CMyComPtr<IInStream> inStreamLoc(inStreamSpec);
+ if(!inStreamSpec->Open(m_BaseFolderPrefix + dirItem.FullPath))
+ return ::GetLastError();
+
+ *inStream = inStreamLoc.Detach();
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(INT32 operationResult)
+{
+ if (m_UpdateCallback)
+ return m_UpdateCallback->OperationResult(operationResult);
+ return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(INT32 *passwordIsDefined, BSTR *password)
+{
+ *passwordIsDefined = BoolToInt(false);
+ if (!_cryptoGetTextPassword)
+ {
+ if (!m_UpdateCallback)
+ return S_OK;
+ HRESULT result = m_UpdateCallback.QueryInterface(
+ IID_ICryptoGetTextPassword2, &_cryptoGetTextPassword);
+ if (result != S_OK)
+ return S_OK;
+ }
+ return _cryptoGetTextPassword->CryptoGetTextPassword2(passwordIsDefined, password);
+}
diff --git a/7zip/UI/Agent/ArchiveUpdateCallback.h b/7zip/UI/Agent/ArchiveUpdateCallback.h
new file mode 100755
index 00000000..bef5dbc3
--- /dev/null
+++ b/7zip/UI/Agent/ArchiveUpdateCallback.h
@@ -0,0 +1,71 @@
+// ArchiveUpdateCallback.h
+
+#pragma once
+
+#ifndef __ARCHIVEUPDATECALLBACK_H
+#define __ARCHIVEUPDATECALLBACK_H
+
+#include "../../Archive/IArchive.h"
+#include "../../IPassword.h"
+#include "IFolderArchive.h"
+
+#include "Common/String.h"
+#include "Common/MyCom.h"
+
+#include "../Common/UpdateProduce.h"
+// #include "Interface/CryptoInterface.h"
+// #include "Interface/MyCom.h"
+
+class CArchiveUpdateCallback:
+ public IArchiveUpdateCallback,
+ public ICryptoGetTextPassword2,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP1(ICryptoGetTextPassword2)
+
+
+ // IProgress
+
+ STDMETHOD(SetTotal)(UINT64 size);
+ STDMETHOD(SetCompleted)(const UINT64 *completeValue);
+
+ // IArchiveUpdateCallback
+ // STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator);
+ STDMETHOD(GetUpdateItemInfo)(UINT32 index,
+ INT32 *newData, // 1 - new data, 0 - old data
+ INT32 *newProperties, // 1 - new properties, 0 - old properties
+ UINT32 *indexInArchive// set if existInArchive == true
+ );
+
+ STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value);
+
+ STDMETHOD(GetStream)(UINT32 index, IInStream **anInStream);
+ STDMETHOD(SetOperationResult)(INT32 operationResult);
+ STDMETHOD(CryptoGetTextPassword2)(INT32 *passwordIsDefined, BSTR *password);
+
+private:
+ UString m_BaseFolderPrefix;
+ const CObjectVector<CDirItem> *m_DirItems;
+ const CObjectVector<CArchiveItem> *m_ArchiveItems;
+ const CObjectVector<CUpdatePair2> *m_UpdatePairs;
+ CMyComPtr<IFolderArchiveUpdateCallback> m_UpdateCallback;
+ CMyComPtr<ICryptoGetTextPassword2> _cryptoGetTextPassword;
+ UINT m_CodePage;
+
+ CMyComPtr<IInArchive> _inArchive;
+
+public:
+ void Init(const UString &baseFolderPrefix,
+ const CObjectVector<CDirItem> *dirItems,
+ const CObjectVector<CArchiveItem> *archiveItems, // test CItemInfoExList
+ CObjectVector<CUpdatePair2> *updatePairs,
+ // UINT codePage,
+ IInArchive *inArchive,
+ IFolderArchiveUpdateCallback *updateCallback);
+};
+
+
+
+
+#endif
diff --git a/7zip/UI/Agent/IFolderArchive.h b/7zip/UI/Agent/IFolderArchive.h
new file mode 100755
index 00000000..3f101e85
--- /dev/null
+++ b/7zip/UI/Agent/IFolderArchive.h
@@ -0,0 +1,141 @@
+// IFolderArchive.h
+
+#pragma once
+
+#ifndef __IFOLDERARCHIVE_H
+#define __IFOLDERARCHIVE_H
+
+#include "../../Archive/IArchive.h"
+// #include "../Format/Common/ArchiveInterface.h"
+#include "../../FileManager/IFolder.h"
+
+namespace NExtractionMode {
+ namespace NPath
+ {
+ enum EEnum
+ {
+ kFullPathnames,
+ kCurrentPathnames,
+ kNoPathnames
+ };
+ }
+ namespace NOverwrite
+ {
+ enum EEnum
+ {
+ kAskBefore,
+ kWithoutPrompt,
+ kSkipExisting,
+ kAutoRename
+ };
+ }
+}
+
+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);
+ STDMETHOD(PrepareOperation)(const wchar_t *name, INT32 askExtractMode) PURE;
+ STDMETHOD(MessageError)(const wchar_t *message) PURE;
+ STDMETHOD(SetOperationResult)(INT32 operationResult) PURE;
+};
+
+// {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,
+ NExtractionMode::NPath::EEnum pathMode,
+ NExtractionMode::NOverwrite::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)(
+ NExtractionMode::NPath::EEnum pathMode,
+ NExtractionMode::NOverwrite::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;
+};
+
+// {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/7zip/UI/Client7z/Client7z.cpp b/7zip/UI/Client7z/Client7z.cpp
new file mode 100755
index 00000000..32211dca
--- /dev/null
+++ b/7zip/UI/Client7z/Client7z.cpp
@@ -0,0 +1,72 @@
+// Client7z.cpp : Defines the entry point for the console application.
+
+#include "stdafx.h"
+
+#include <initguid.h>
+
+#include "Common/StringConvert.h"
+#include "../../Common/FileStreams.h"
+#include "../../Archive/IArchive.h"
+#include "Windows/PropVariant.h"
+#include "Windows/PropVariantConversions.h"
+#include "Windows/DLL.h"
+
+// {23170F69-40C1-278A-1000-000110050000}
+DEFINE_GUID(CLSID_CFormat7z,
+ 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 0x00, 0x00);
+
+typedef UINT32 (WINAPI * CreateObjectFunc)(
+ const GUID *clsID,
+ const GUID *interfaceID,
+ void **outObject);
+
+int main(int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ printf("Use Client7z.exe file.7z");
+ return 1;
+ }
+ NWindows::NDLL::CLibrary library;
+ if (!library.Load("7za.dll"))
+ {
+ printf("Can not load library");
+ return 1;
+ }
+ CreateObjectFunc
+ createObjectFunc =
+ (CreateObjectFunc)library.GetProcAddress("CreateObject");
+ if (createObjectFunc == 0)
+ {
+ printf("Can not get CreateObject");
+ return 1;
+ }
+ CMyComPtr<IInArchive> archive;
+ if (createObjectFunc(&CLSID_CFormat7z,
+ &IID_IInArchive, (void **)&archive) != S_OK)
+ {
+ printf("Can not get class object");
+ return 1;
+ }
+
+ CInFileStream *fileSpec = new CInFileStream;
+ CMyComPtr<IInStream> file = fileSpec;
+
+ if (!fileSpec->Open(argv[1]))
+ {
+ printf("Can not open");
+ return 1;
+ }
+ if (archive->Open(file, 0, 0) != S_OK)
+ return 0;
+ UINT32 numItems = 0;
+ archive->GetNumberOfItems(&numItems);
+ for (UINT32 i = 0; i < numItems; i++)
+ {
+ NWindows::NCOM::CPropVariant propVariant;
+ archive->GetProperty(i, kpidPath, &propVariant);
+ UString s = ConvertPropVariantToString(propVariant);
+ printf("%s\n", (LPCSTR)GetOemString(s));
+ }
+ return 0;
+}
diff --git a/7zip/UI/Client7z/Client7z.dsp b/7zip/UI/Client7z/Client7z.dsp
new file mode 100755
index 00000000..612a2078
--- /dev/null
+++ b/7zip/UI/Client7z/Client7z.dsp
@@ -0,0 +1,190 @@
+# 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 "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\Client7z.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"stdafx.h"
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# Begin Group "SDK"
+
+# PROP Default_Filter ""
+# 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\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\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\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
+# 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
+# End Target
+# End Project
diff --git a/7zip/UI/Client7z/Client7z.dsw b/7zip/UI/Client7z/Client7z.dsw
new file mode 100755
index 00000000..598a6d3f
--- /dev/null
+++ b/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/7zip/UI/Client7z/StdAfx.cpp b/7zip/UI/Client7z/StdAfx.cpp
new file mode 100755
index 00000000..710de2fb
--- /dev/null
+++ b/7zip/UI/Client7z/StdAfx.cpp
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// Client7z.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/7zip/UI/Client7z/StdAfx.h b/7zip/UI/Client7z/StdAfx.h
new file mode 100755
index 00000000..40ea3552
--- /dev/null
+++ b/7zip/UI/Client7z/StdAfx.h
@@ -0,0 +1,12 @@
+// stdafx.h
+
+#pragma once
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+#include <stdio.h>
+
+#endif
+
diff --git a/7zip/UI/Common/ArchiveName.cpp b/7zip/UI/Common/ArchiveName.cpp
new file mode 100755
index 00000000..91ce0a9f
--- /dev/null
+++ b/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 ::GetLastError();
+ 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/7zip/UI/Common/ArchiveName.h b/7zip/UI/Common/ArchiveName.h
new file mode 100755
index 00000000..605d0a70
--- /dev/null
+++ b/7zip/UI/Common/ArchiveName.h
@@ -0,0 +1,12 @@
+// ArchiveName.h
+
+#pragma once
+
+#ifndef __ARCHIVENAME_H
+#define __ARCHIVENAME_H
+
+#include "Common/String.h"
+
+UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName);
+
+#endif \ No newline at end of file
diff --git a/7zip/UI/Common/ArchiverInfo.cpp b/7zip/UI/Common/ArchiverInfo.cpp
new file mode 100755
index 00000000..0ff7bae2
--- /dev/null
+++ b/7zip/UI/Common/ArchiverInfo.cpp
@@ -0,0 +1,308 @@
+// 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"
+#include "Windows/Registry.h"
+#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);
+
+/*
+UString GetCurrentModulePath()
+{
+ TCHAR fullPath[MAX_PATH + 1];
+ ::GetModuleFileName(g_hInstance, fullPath, MAX_PATH);
+ return fullPath;
+}
+*/
+
+static UString GetModuleFolderPrefix()
+{
+ UString path;
+ NDLL::MyGetModuleFileName(g_hInstance, path);
+ int pos = path.ReverseFind(L'\\');
+ return path.Left(pos + 1);
+}
+
+static wchar_t *kFormatFolderName = L"Formats";
+static LPCTSTR kRegistryPath = TEXT("Software\\7-zip");
+static LPCTSTR kProgramPathValue = TEXT("Path");
+
+UString GetBaseFolderPrefix()
+{
+ UString moduleFolderPrefix = GetModuleFolderPrefix();
+ NFind::CFileInfoW fileInfo;
+ if (NFind::FindFile(moduleFolderPrefix + kFormatFolderName, fileInfo))
+ if (fileInfo.IsDirectory())
+ return moduleFolderPrefix;
+ CSysString pathSys;
+ {
+ NRegistry::CKey key;
+ if(key.Open(HKEY_CURRENT_USER, kRegistryPath, KEY_READ) == ERROR_SUCCESS)
+ if (key.QueryValue(kProgramPathValue, pathSys) == ERROR_SUCCESS)
+ {
+ UString path = GetUnicodeString(pathSys);
+ NName::NormalizeDirPathPrefix(path);
+ return path;
+ }
+ }
+ {
+ NRegistry::CKey key;
+ if(key.Open(HKEY_LOCAL_MACHINE, kRegistryPath, KEY_READ) == ERROR_SUCCESS)
+ if (key.QueryValue(kProgramPathValue, pathSys) == ERROR_SUCCESS)
+ {
+ UString path = GetUnicodeString(pathSys);
+ NName::NormalizeDirPathPrefix(path);
+ return path;
+ }
+ }
+ return moduleFolderPrefix;
+}
+
+typedef UINT32 (WINAPI *CreateObjectPointer)(
+ const GUID *clsID,
+ const GUID *interfaceID,
+ void **outObject);
+
+#endif
+
+void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
+{
+ archivers.Clear();
+
+ #ifdef EXCLUDE_COM
+
+ #ifdef FORMAT_7Z
+ {
+ CArchiverInfo item;
+ item.UpdateEnabled = true;
+ item.KeepName = false;
+ item.Name = L"7z";
+ item.Extensions.Add(CArchiverExtInfo(L"7z"));
+ 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"));
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_GZIP
+ {
+ CArchiverInfo item;
+ item.UpdateEnabled = true;
+ item.KeepName = false;
+ item.Name = L"GZip";
+ item.Extensions.Add(CArchiverExtInfo(L"gz"));
+ item.Extensions.Add(CArchiverExtInfo(L"tgz", L".tar"));
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_TAR
+ {
+ CArchiverInfo item;
+ item.UpdateEnabled = true;
+ item.KeepName = false;
+ item.Name = L"Tar";
+ item.Extensions.Add(CArchiverExtInfo(L"tar"));
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_ZIP
+ {
+ CArchiverInfo item;
+ item.UpdateEnabled = true;
+ item.KeepName = false;
+ item.Name = L"Zip";
+ item.Extensions.Add(CArchiverExtInfo(L"zip"));
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_CPIO
+ {
+ CArchiverInfo item;
+ item.UpdateEnabled = false;
+ item.Name = L"Cpio";
+ item.Extensions.Add(CArchiverExtInfo(L"cpio"));
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_RPM
+ {
+ CArchiverInfo item;
+ item.UpdateEnabled = false;
+ item.Name = L"Rpm";
+ item.Extensions.Add(CArchiverExtInfo(L"rpm", L".cpio.gz"));
+ archivers.Add(item);
+ }
+ #endif
+
+ #ifdef FORMAT_ARJ
+ {
+ CArchiverInfo item;
+ item.UpdateEnabled = false;
+ item.Name = L"Arj";
+ item.Extensions.Add(CArchiverExtInfo(L"arj"));
+ archivers.Add(item);
+ }
+ #endif
+
+ #else
+
+ UString folderPath = GetBaseFolderPrefix() +
+ kFormatFolderName + L"\\";
+ 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;
+ // item.Extension = prop.bstrVal;
+
+ UString addExt;
+
+ 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.Extension = exts[i];
+ if (addExts.Size() > 0)
+ extInfo.AddExtension = addExts[i];
+ if (extInfo.AddExtension == L"*")
+ extInfo.AddExtension.Empty();
+ item.Extensions.Add(extInfo);
+ }
+
+ if (getHandlerProperty(NArchive::kUpdate, &prop) != S_OK)
+ continue;
+ if (prop.vt != VT_BOOL)
+ continue;
+ item.UpdateEnabled = VARIANT_BOOLToBool(prop.boolVal);
+ prop.Clear();
+
+ if (item.UpdateEnabled)
+ {
+ if (getHandlerProperty(NArchive::kKeepName, &prop) != S_OK)
+ continue;
+ if (prop.vt != VT_BOOL)
+ continue;
+ item.KeepName = VARIANT_BOOLToBool(prop.boolVal);
+ prop.Clear();
+ }
+
+ archivers.Add(item);
+ }
+
+ #endif
+}
+
+
diff --git a/7zip/UI/Common/ArchiverInfo.h b/7zip/UI/Common/ArchiverInfo.h
new file mode 100755
index 00000000..8a21266e
--- /dev/null
+++ b/7zip/UI/Common/ArchiverInfo.h
@@ -0,0 +1,58 @@
+// ArchiverInfo.h
+
+#pragma once
+
+#ifndef __ARCHIVERINFO_H
+#define __ARCHIVERINFO_H
+
+#include "Common/String.h"
+#include "Common/Types.h"
+
+struct CArchiverExtInfo
+{
+ UString Extension;
+ UString AddExtension;
+ CArchiverExtInfo() {}
+ CArchiverExtInfo(const UString &extension):
+ Extension(extension) {}
+ CArchiverExtInfo(const UString &extension, const UString &addExtension):
+ Extension(extension), AddExtension(addExtension) {}
+};
+
+struct CArchiverInfo
+{
+ #ifndef EXCLUDE_COM
+ UString FilePath;
+ CLSID ClassID;
+ #endif
+ UString Name;
+ CObjectVector<CArchiverExtInfo> Extensions;
+ int FindExtension(const UString &ext) const
+ {
+ for (int i = 0; i < Extensions.Size(); i++)
+ if (ext.CollateNoCase(Extensions[i].Extension) == 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].Extension;
+ }
+ return s;
+ }
+ const UString &GetMainExtension() const
+ {
+ return Extensions[0].Extension;
+ }
+ bool UpdateEnabled;
+ bool KeepName;
+};
+
+void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers);
+
+#endif
diff --git a/7zip/UI/Common/CompressCall.cpp b/7zip/UI/Common/CompressCall.cpp
new file mode 100755
index 00000000..d6cdf57e
--- /dev/null
+++ b/7zip/UI/Common/CompressCall.cpp
@@ -0,0 +1,229 @@
+// 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 "../../FileManager/ProgramLocation.h"
+
+using namespace NWindows;
+
+static LPCWSTR kShowDialogSwitch = L" -ad";
+static LPCWSTR kEmailSwitch = L" -seml";
+static LPCWSTR kMapSwitch = L" -i#";
+
+
+static bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+
+HRESULT MyCreateProcess(const UString &params,
+ NWindows::NSynchronization::CEvent *event)
+{
+ 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;
+ BOOL result = ::CreateProcess(NULL, (TCHAR *)(const TCHAR *)
+ GetSystemString(params),
+ NULL, NULL, FALSE, 0, NULL, NULL,
+ &startupInfo, &processInformation);
+ if (result == 0)
+ return ::GetLastError();
+ else
+ {
+ if (event != NULL)
+ {
+ HANDLE handles[] = {processInformation.hProcess, *event };
+ ::WaitForMultipleObjects(sizeof(handles) / sizeof(handles[0]),
+ handles, FALSE, INFINITE);
+ }
+ ::CloseHandle(processInformation.hThread);
+ ::CloseHandle(processInformation.hProcess);
+ }
+ return S_OK;
+}
+
+static UString GetQuotedString(const UString &s)
+{
+ return UString(L"\"") + s + UString(L"\"");
+}
+
+static UString Get7zGuiPath()
+{
+ UString path = L"\"";
+ UString folder;
+ if (GetProgramFolderPath(folder))
+ path += folder;
+ if (IsItWindowsNT())
+ path += L"7zgn.exe";
+ else
+ path += L"7zg.exe";
+ path += L"\"";
+ return path;
+}
+
+HRESULT CompressFiles(
+ const UString &archiveName,
+ const UStringVector &names,
+ // const UString &outFolder,
+ bool email,
+ bool showDialog)
+{
+ 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());
+ while(true)
+ {
+ 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;
+ while(true)
+ {
+ 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 (email)
+ params += kEmailSwitch;
+
+ if (showDialog)
+ params += kShowDialogSwitch;
+
+ 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, &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;
+}
+
+HRESULT ExtractArchive(const UString &archiveName,
+ const UString &outFolder, bool showDialog)
+{
+ UString params;
+ params = Get7zGuiPath();
+ params += L" x ";
+ params += GetQuotedString(archiveName);
+ if (!outFolder.IsEmpty())
+ {
+ params += L" -o";
+ params += GetQuotedString(outFolder);
+ }
+ if (showDialog)
+ params += kShowDialogSwitch;
+ return MyCreateProcess(params);
+}
+
+HRESULT TestArchive(const UString &archiveName)
+{
+ UString params;
+ params = Get7zGuiPath();
+ params += L" t ";
+ params += GetQuotedString(archiveName);
+ return MyCreateProcess(params);
+}
diff --git a/7zip/UI/Common/CompressCall.h b/7zip/UI/Common/CompressCall.h
new file mode 100755
index 00000000..73d93984
--- /dev/null
+++ b/7zip/UI/Common/CompressCall.h
@@ -0,0 +1,22 @@
+// CompressCall.h
+
+#ifndef __COMPRESSCALL_H
+#define __COMPRESSCALL_H
+
+#include "Common/String.h"
+#include "Windows/Synchronization.h"
+
+HRESULT MyCreateProcess(const UString &params,
+ NWindows::NSynchronization::CEvent *event = NULL);
+HRESULT CompressFiles(const UString &archiveName,
+ const UStringVector &names,
+ // const UString &outFolder,
+ bool email, bool showDialog);
+
+HRESULT ExtractArchive(const UString &archiveName,
+ const UString &outFolder, bool showDialog);
+
+HRESULT TestArchive(const UString &archiveName);
+
+#endif
+
diff --git a/7zip/UI/Common/DefaultName.cpp b/7zip/UI/Common/DefaultName.cpp
new file mode 100755
index 00000000..73ba2274
--- /dev/null
+++ b/7zip/UI/Common/DefaultName.cpp
@@ -0,0 +1,33 @@
+// DefaultName.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/FileDir.h"
+
+#include "Common/StringConvert.h"
+#include "DefaultName.h"
+
+const wchar_t *kEmptyFileAlias = L"[Content]";
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NDirectory;
+
+UString GetDefaultName(const UString &fullFileName,
+ const UString &extension, const UString &addSubExtension)
+{
+ UString fileName;
+ if (!GetOnlyName(fullFileName, fileName))
+ throw 5011749;
+ int extLength = extension.Length();
+ int fileNameLength = fileName.Length();
+ if (fileNameLength <= extLength + 1)
+ return kEmptyFileAlias;
+ int dotPos = fileNameLength - (extLength + 1);
+ if (fileName[dotPos] != '.')
+ return kEmptyFileAlias;
+ if (extension.CollateNoCase(fileName.Mid(dotPos + 1)) == 0)
+ return fileName.Left(dotPos) + addSubExtension;
+ return kEmptyFileAlias;
+}
+
diff --git a/7zip/UI/Common/DefaultName.h b/7zip/UI/Common/DefaultName.h
new file mode 100755
index 00000000..57e64cec
--- /dev/null
+++ b/7zip/UI/Common/DefaultName.h
@@ -0,0 +1,13 @@
+// DefaultName.h
+
+#pragma once
+
+#ifndef __DEFAULTNAME_H
+#define __DEFAULTNAME_H
+
+#include "Common/String.h"
+
+UString GetDefaultName(const UString &fullFileName,
+ const UString &extension, const UString &addSubExtension);
+
+#endif
diff --git a/7zip/UI/Common/DirItem.h b/7zip/UI/Common/DirItem.h
new file mode 100755
index 00000000..7fe882bc
--- /dev/null
+++ b/7zip/UI/Common/DirItem.h
@@ -0,0 +1,37 @@
+// DirItem.h
+
+#pragma once
+
+#ifndef __DIR_ITEM_H
+#define __DIR_ITEM_H
+
+// #include "Common/Types.h"
+#include "Common/String.h"
+// #include "Windows/PropVariant.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/7zip/UI/Common/EnumDirItems.cpp b/7zip/UI/Common/EnumDirItems.cpp
new file mode 100755
index 00000000..50fc2a28
--- /dev/null
+++ b/7zip/UI/Common/EnumDirItems.cpp
@@ -0,0 +1,71 @@
+// EnumDirItems.cpp
+
+#include "StdAfx.h"
+
+#include "EnumDirItems.h"
+#include "Common/StringConvert.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NName;
+
+// using namespace NUpdateArchive;
+
+void AddDirFileInfo(
+ const UString &prefix,
+ const UString &fullPathName,
+ 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,
+ const UString &directory,
+ const UString &prefix,
+ CObjectVector<CDirItem> &dirItems)
+{
+ NFind::CEnumeratorW enumerator(baseFolderPrefix + directory + wchar_t(kAnyStringWildcard));
+ NFind::CFileInfoW fileInfo;
+ while (enumerator.Next(fileInfo))
+ {
+ 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);
+ }
+ }
+}
+
+void EnumerateDirItems(
+ const UString &baseFolderPrefix,
+ const UStringVector &fileNames,
+ const UString &archiveNamePrefix,
+ CObjectVector<CDirItem> &dirItems)
+{
+ for(int i = 0; i < fileNames.Size(); i++)
+ {
+ const UString &fileName = fileNames[i];
+ NFind::CFileInfoW fileInfo;
+ if (!NFind::FindFile(baseFolderPrefix + fileName, fileInfo))
+ throw 1081736;
+ AddDirFileInfo(archiveNamePrefix, fileName, fileInfo, dirItems);
+ if (fileInfo.IsDirectory())
+ {
+ EnumerateDirectory(baseFolderPrefix, fileName + wchar_t(kDirDelimiter),
+ archiveNamePrefix + fileInfo.Name + wchar_t(kDirDelimiter),
+ dirItems);
+ }
+ }
+}
diff --git a/7zip/UI/Common/EnumDirItems.h b/7zip/UI/Common/EnumDirItems.h
new file mode 100755
index 00000000..4d2d4386
--- /dev/null
+++ b/7zip/UI/Common/EnumDirItems.h
@@ -0,0 +1,33 @@
+// EnumDirItems.h
+
+#pragma once
+
+#ifndef __ENUM_DIR_ITEMS_H
+#define __ENUM_DIR_ITEMS_H
+
+#include "Common/String.h"
+#include "Common/Vector.h"
+#include "DirItem.h"
+// #include "UpdatePairBasic.h"
+
+#include "Windows/FileFind.h"
+
+void AddDirFileInfo(
+ const UString &prefix,
+ const UString &fullPathName,
+ NWindows::NFile::NFind::CFileInfoW &fileInfo,
+ CObjectVector<CDirItem> &dirItems);
+
+void EnumerateDirItems(
+ const UString &baseFolderPrefix,
+ const UStringVector &fileNames,
+ const UString &archiveNamePrefix,
+ CObjectVector<CDirItem> &dirItems);
+
+/*
+void EnumerateItems(const CSysStringVector &filePaths,
+ const UString &archiveNamePrefix,
+ CArchiveStyleDirItemInfoVector &dirFileInfoVector, UINT codePage);
+*/
+
+#endif
diff --git a/7zip/UI/Common/ExtractingFilePath.cpp b/7zip/UI/Common/ExtractingFilePath.cpp
new file mode 100755
index 00000000..d1797f64
--- /dev/null
+++ b/7zip/UI/Common/ExtractingFilePath.cpp
@@ -0,0 +1,54 @@
+// ExtractingFilePath.cpp
+
+#include "StdAfx.h"
+#include "ExtractingFilePath.h"
+
+UString GetCorrectFileName(const UString &path)
+{
+ UString result = path;
+ result.Trim();
+ result.Replace(L"..\\", L"");
+ result.Replace(L"../", L"");
+ if (result.Length() > 1)
+ {
+ if (result[1] == L':')
+ {
+ result.Delete(1);
+ // result.Insert(first + 1, L'_');
+ }
+ }
+ 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 (result[first] == L'\\' || result[first] == L'/')
+ {
+ result.Delete(first);
+ continue;
+ }
+ break;
+ }
+ result.Replace(L"..\\", L"");
+ result.Replace(L"../", L"");
+
+ if (result.Length() > 1)
+ {
+ if (result[first + 1] == L':')
+ {
+ result.Delete(first + 1);
+ // result.Insert(first + 1, L'_');
+ }
+ }
+ return result;
+
+}
+
diff --git a/7zip/UI/Common/ExtractingFilePath.h b/7zip/UI/Common/ExtractingFilePath.h
new file mode 100755
index 00000000..0b8f08bb
--- /dev/null
+++ b/7zip/UI/Common/ExtractingFilePath.h
@@ -0,0 +1,13 @@
+// ExtractingFilePath.h
+
+#pragma once
+
+#ifndef __EXTRACTINGFILEPATH_H
+#define __EXTRACTINGFILEPATH_H
+
+#include "Common/String.h"
+
+UString GetCorrectFileName(const UString &path);
+UString GetCorrectPath(const UString &path);
+
+#endif
diff --git a/7zip/UI/Common/HandlerLoader.h b/7zip/UI/Common/HandlerLoader.h
new file mode 100755
index 00000000..ec81b5c7
--- /dev/null
+++ b/7zip/UI/Common/HandlerLoader.h
@@ -0,0 +1,42 @@
+// HandlerLoader.h
+
+#pragma once
+
+#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/7zip/UI/Common/OpenArchive.cpp b/7zip/UI/Common/OpenArchive.cpp
new file mode 100755
index 00000000..d64f436f
--- /dev/null
+++ b/7zip/UI/Common/OpenArchive.cpp
@@ -0,0 +1,171 @@
+// OpenArchive.cpp
+
+#include "StdAfx.h"
+
+#include "OpenArchive.h"
+
+#include "Windows/FileName.h"
+#include "Windows/FileDir.h"
+#include "Windows/Defs.h"
+
+#include "../../Common/FileStreams.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_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 "HandlerLoader.h"
+#endif
+
+
+using namespace NWindows;
+
+const UINT64 kMaxCheckStartPosition = 1 << 20;
+
+HRESULT ReOpenArchive(IInArchive *archive,
+ const UString &fileName)
+{
+ CInFileStream *inStreamSpec = new CInFileStream;
+ CMyComPtr<IInStream> inStream(inStreamSpec);
+ inStreamSpec->Open(fileName);
+ return archive->Open(inStream, &kMaxCheckStartPosition, NULL);
+}
+
+HRESULT OpenArchive(const UString &fileName,
+ #ifndef EXCLUDE_COM
+ HMODULE *module,
+ #endif
+ IInArchive **archiveResult,
+ CArchiverInfo &archiverInfoResult,
+ int &subExtIndex,
+ IArchiveOpenCallback *openArchiveCallback)
+{
+ CInFileStream *inStreamSpec = new CInFileStream;
+ CMyComPtr<IInStream> inStream(inStreamSpec);
+ if (!inStreamSpec->Open(fileName))
+ return GetLastError();
+
+ *archiveResult = NULL;
+ CObjectVector<CArchiverInfo> archiverInfoList;
+ ReadArchiverInfoList(archiverInfoList);
+ UString extension;
+ {
+ UString name, pureName, dot;
+ if(!NFile::NDirectory::GetOnlyName(fileName, name))
+ return E_FAIL;
+ NFile::NName::SplitNameToPureNameAndExtension(name, pureName, dot, extension);
+ }
+ CIntVector orderIndices;
+ int firstArchiverIndex;
+ for(firstArchiverIndex = 0;
+ firstArchiverIndex < archiverInfoList.Size(); firstArchiverIndex++)
+ {
+ int subIndex = archiverInfoList[firstArchiverIndex].FindExtension(extension);
+ if (subIndex >= 0)
+ break;
+ }
+ if(firstArchiverIndex < archiverInfoList.Size())
+ orderIndices.Add(firstArchiverIndex);
+ for(int j = 0; j < archiverInfoList.Size(); j++)
+ if(j != firstArchiverIndex)
+ orderIndices.Add(j);
+
+ HRESULT badResult = S_OK;
+ for(int i = 0; i < orderIndices.Size(); i++)
+ {
+ inStreamSpec->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_GZIP
+ if (archiverInfo.Name.CompareNoCase(L"GZip") == 0)
+ archive = new NArchive::NGZip::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
+
+
+ #ifndef EXCLUDE_COM
+ if (!archive)
+ {
+ HRESULT result = loader.CreateHandler(archiverInfo.FilePath,
+ archiverInfo.ClassID, (void **)&archive, false);
+ if (result != S_OK)
+ continue;
+ }
+ #endif EXCLUDE_COM
+
+ if (!archive)
+ return E_FAIL;
+
+ HRESULT result = archive->Open(inStream, &kMaxCheckStartPosition, openArchiveCallback);
+ if(result == S_FALSE)
+ continue;
+ if(result != S_OK)
+ {
+ badResult = result;
+ continue;
+ // return result;
+ }
+ *archiveResult = archive.Detach();
+ #ifndef EXCLUDE_COM
+ *module = loader.Detach();
+ #endif
+ archiverInfoResult = archiverInfo;
+ subExtIndex = archiverInfo.FindExtension(extension);
+ if (subExtIndex < 0)
+ subExtIndex = 0;
+ return S_OK;
+ }
+ if (badResult != S_OK)
+ return badResult;
+ return S_FALSE;
+
+ /*
+ #else
+ return S_FALSE;
+ #endif
+
+ #endif
+ */
+}
diff --git a/7zip/UI/Common/OpenArchive.h b/7zip/UI/Common/OpenArchive.h
new file mode 100755
index 00000000..7c4128dc
--- /dev/null
+++ b/7zip/UI/Common/OpenArchive.h
@@ -0,0 +1,24 @@
+// OpenArchive.h
+
+#ifndef __OPENARCHIVE_H
+#define __OPENARCHIVE_H
+
+#include "Common/String.h"
+
+#include "../../Archive/IArchive.h"
+#include "ArchiverInfo.h"
+
+HRESULT OpenArchive(const UString &fileName,
+ #ifndef EXCLUDE_COM
+ HMODULE *module,
+ #endif
+ IInArchive **archive,
+ CArchiverInfo &archiverInfoResult,
+ int &subExtIndex,
+ IArchiveOpenCallback *openArchiveCallback);
+
+HRESULT ReOpenArchive(IInArchive *archive,
+ const UString &fileName);
+
+
+#endif
diff --git a/7zip/UI/Common/PropIDUtils.cpp b/7zip/UI/Common/PropIDUtils.cpp
new file mode 100755
index 00000000..bd836fff
--- /dev/null
+++ b/7zip/UI/Common/PropIDUtils.cpp
@@ -0,0 +1,79 @@
+// 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;
+}
+
+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 ConvertFileTimeToString2(localFileTime, true, full);
+ }
+ case kpidCRC:
+ {
+ if(propVariant.vt != VT_UI4)
+ break;
+ TCHAR temp[17];
+ wsprintf(temp, TEXT("%08X"), propVariant.ulVal);
+ return GetUnicodeString(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/7zip/UI/Common/PropIDUtils.h b/7zip/UI/Common/PropIDUtils.h
new file mode 100755
index 00000000..82ee249a
--- /dev/null
+++ b/7zip/UI/Common/PropIDUtils.h
@@ -0,0 +1,13 @@
+// PropIDUtils.h
+
+#pragma once
+
+#ifndef __PROPIDUTILS_H
+#define __PROPIDUTILS_H
+
+#include "Common/String.h"
+
+UString ConvertPropertyToString(const PROPVARIANT &aPropVariant,
+ PROPID aPropID, bool aFull = true);
+
+#endif
diff --git a/7zip/UI/Common/SortUtils.cpp b/7zip/UI/Common/SortUtils.cpp
new file mode 100755
index 00000000..881aec0b
--- /dev/null
+++ b/7zip/UI/Common/SortUtils.cpp
@@ -0,0 +1,30 @@
+// SortUtils.cpp
+
+#include "StdAfx.h"
+
+#include "SortUtils.h"
+
+static int __cdecl CompareStrings(const void *a1, const void *a2)
+{
+ const UString &s1 = *(*(*((const UString ***)a1)));
+ const UString &s2 = *(*(*((const UString ***)a2)));
+ return s1.CompareNoCase(s2);
+}
+
+void SortStringsToIndices(UStringVector &strings, CIntVector &indices)
+{
+ indices.Clear();
+ if (strings.IsEmpty())
+ return;
+ int numItems = strings.Size();
+ CPointerVector pointers;
+ pointers.Reserve(numItems);
+ indices.Reserve(numItems);
+ int i;
+ for(i = 0; i < numItems; i++)
+ pointers.Add(&strings.CPointerVector::operator[](i));
+ void **stringsBase = (void **)pointers[0];
+ qsort(&pointers[0], numItems, sizeof(void *), CompareStrings);
+ for(i = 0; i < numItems; i++)
+ indices.Add((void **)pointers[i] - stringsBase);
+}
diff --git a/7zip/UI/Common/SortUtils.h b/7zip/UI/Common/SortUtils.h
new file mode 100755
index 00000000..36eda0b9
--- /dev/null
+++ b/7zip/UI/Common/SortUtils.h
@@ -0,0 +1,12 @@
+// SortUtils.h
+
+#pragma once
+
+#ifndef __SORTUTLS_H
+#define __SORTUTLS_H
+
+#include "Common/String.h"
+
+void SortStringsToIndices(UStringVector &strings, CIntVector &indices);
+
+#endif
diff --git a/7zip/UI/Common/StdAfx.h b/7zip/UI/Common/StdAfx.h
new file mode 100755
index 00000000..a32fbed6
--- /dev/null
+++ b/7zip/UI/Common/StdAfx.h
@@ -0,0 +1,8 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#endif
diff --git a/7zip/UI/Common/UpdateAction.cpp b/7zip/UI/Common/UpdateAction.cpp
new file mode 100755
index 00000000..8805ce64
--- /dev/null
+++ b/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
+};
+
+} \ No newline at end of file
diff --git a/7zip/UI/Common/UpdateAction.h b/7zip/UI/Common/UpdateAction.h
new file mode 100755
index 00000000..1cd2fd69
--- /dev/null
+++ b/7zip/UI/Common/UpdateAction.h
@@ -0,0 +1,48 @@
+// UpdateAction.h
+
+#pragma once
+
+#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];
+ };
+ extern const CActionSet kAddActionSet;
+ extern const CActionSet kUpdateActionSet;
+ extern const CActionSet kFreshActionSet;
+ extern const CActionSet kSynchronizeActionSet;
+ extern const CActionSet kDeleteActionSet;
+};
+
+
+#endif
+
+
diff --git a/7zip/UI/Common/UpdatePair.cpp b/7zip/UI/Common/UpdatePair.cpp
new file mode 100755
index 00000000..ce33812e
--- /dev/null
+++ b/7zip/UI/Common/UpdatePair.cpp
@@ -0,0 +1,157 @@
+// 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 NCOM;
+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:
+ {
+ time_t unixTime1, unixTime2;
+ if (!FileTimeToUnixTime(time1, unixTime1))
+ throw 4191614;
+ if (!FileTimeToUnixTime(time2, unixTime2))
+ throw 4191615;
+ return MyCompare(unixTime1, unixTime2);
+ }
+ case NFileTimeType::kDOS:
+ {
+ UINT32 dosTime1, 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 void TestDuplicateString(const UStringVector &strings,
+ const CIntVector &indices)
+{
+ for(int i = 0; i + 1 < indices.Size(); i++)
+ if (strings[indices[i]].CollateNoCase(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 = dirItem.Name.CollateNoCase(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/7zip/UI/Common/UpdatePair.h b/7zip/UI/Common/UpdatePair.h
new file mode 100755
index 00000000..41a9b09b
--- /dev/null
+++ b/7zip/UI/Common/UpdatePair.h
@@ -0,0 +1,26 @@
+// UpdatePair.h
+
+#pragma once
+
+#ifndef __UPDATEPAIR_H
+#define __UPDATEPAIR_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/7zip/UI/Common/UpdateProduce.cpp b/7zip/UI/Common/UpdateProduce.cpp
new file mode 100755
index 00000000..0d50a8ce
--- /dev/null
+++ b/7zip/UI/Common/UpdateProduce.cpp
@@ -0,0 +1,65 @@
+// 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<CDirItem> &dirItems,
+ const CObjectVector<CArchiveItem> &archiveItems,
+ 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/7zip/UI/Common/UpdateProduce.h b/7zip/UI/Common/UpdateProduce.h
new file mode 100755
index 00000000..d09a0fba
--- /dev/null
+++ b/7zip/UI/Common/UpdateProduce.h
@@ -0,0 +1,35 @@
+// UpdateProduce.h
+
+#pragma once
+
+#ifndef __UPDATEPRODUCE_H
+#define __UPDATEPRODUCE_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<CDirItem> &dirItems,
+ const CObjectVector<CArchiveItem> &archiveItems,
+ const CObjectVector<CUpdatePair> &updatePairs,
+ const NUpdateArchive::CActionSet &actionSet,
+ CObjectVector<CUpdatePair2> &operationChain);
+
+#endif
diff --git a/7zip/UI/Common/WorkDir.cpp b/7zip/UI/Common/WorkDir.cpp
new file mode 100755
index 00000000..75147245
--- /dev/null
+++ b/7zip/UI/Common/WorkDir.cpp
@@ -0,0 +1,73 @@
+// WorkDir.cpp
+
+#include "StdAfx.h"
+
+#include "WorkDir.h"
+
+#include "Common/StringConvert.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;
+
+static UString GetContainingDir(const UString &path)
+{
+ UString resultPath;
+ int pos;
+ if(!NFile::NDirectory::MyGetFullPathName(path, resultPath, pos))
+ throw 141716;
+ return resultPath.Left(pos);
+}
+
+UString GetWorkDir(const NWorkDir::CInfo &workDirInfo,
+ const UString &archiveName)
+{
+ NWorkDir::NMode::EEnum mode = workDirInfo.Mode;
+ if (workDirInfo.ForRemovableOnly)
+ {
+ mode = NWorkDir::NMode::kCurrent;
+ UString prefix = archiveName.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 GetContainingDir(archiveName);
+ }
+ case NWorkDir::NMode::kSpecified:
+ {
+ UString tempDir = workDirInfo.Path;
+ NormalizeDirPathPrefix(tempDir);
+ return tempDir;
+ }
+ default: // NZipSettings::NWorkDir::NMode::kSystem:
+ {
+ UString tempDir;
+ if(!NFile::NDirectory::MyGetTempPath(tempDir))
+ throw 141717;
+ return tempDir;
+ }
+ }
+}
+
+
+
diff --git a/7zip/UI/Common/WorkDir.h b/7zip/UI/Common/WorkDir.h
new file mode 100755
index 00000000..16720ae6
--- /dev/null
+++ b/7zip/UI/Common/WorkDir.h
@@ -0,0 +1,14 @@
+// WorkDir.h
+
+#pragma once
+
+#ifndef __WORKDIR_H
+#define __WORKDIR_H
+
+#include "../Common/ZipRegistry.h"
+
+UString GetWorkDir(const NWorkDir::CInfo &workDirInfo,
+ const UString &archiveName);
+
+#endif
+
diff --git a/7zip/UI/Common/ZipRegistry.cpp b/7zip/UI/Common/ZipRegistry.cpp
new file mode 100755
index 00000000..16c3a808
--- /dev/null
+++ b/7zip/UI/Common/ZipRegistry.cpp
@@ -0,0 +1,404 @@
+// 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 NExtraction::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++)
+ {
+ TCHAR 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(NExtraction::CInfo &info)
+{
+ info.Paths.Clear();
+ info.PathMode = NExtraction::NPathMode::kFullPathnames;
+ info.OverwriteMode = NExtraction::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)
+ {
+ while(true)
+ {
+ TCHAR numberString[16];
+ ConvertUINT64ToString(info.Paths.Size(), numberString);
+ CSysString 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 NExtraction::NPathMode::kFullPathnames:
+ case NExtraction::NPathMode::kCurrentPathnames:
+ case NExtraction::NPathMode::kNoPathnames:
+ info.PathMode = NExtraction::NPathMode::EEnum(extractModeIndex);
+ break;
+ }
+ }
+ UINT32 overwriteModeIndex;
+ if (extractionKey.QueryValue(kExtractionOverwriteModeValueName, overwriteModeIndex) == ERROR_SUCCESS)
+ {
+ switch (overwriteModeIndex)
+ {
+ case NExtraction::NOverwriteMode::kAskBefore:
+ case NExtraction::NOverwriteMode::kWithoutPrompt:
+ case NExtraction::NOverwriteMode::kSkipExisting:
+ case NExtraction::NOverwriteMode::kAutoRename:
+ case NExtraction::NOverwriteMode::kAutoRenameExisting:
+ info.OverwriteMode = NExtraction::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 TCHAR *kCompressionOptions = TEXT("Options");
+static const TCHAR *kCompressionLevel = TEXT("Level");
+static const TCHAR *kCompressionMethod = TEXT("Method");
+static const TCHAR *kCompressionDictionary = TEXT("Dictionary");
+static const TCHAR *kCompressionOrder = TEXT("Order");
+
+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++)
+ {
+ TCHAR 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);
+ if (fo.Options.IsEmpty())
+ formatKey.DeleteValue(kCompressionOptions);
+ else
+ formatKey.SetValue(kCompressionOptions, fo.Options);
+ if (fo.Level == UINT32(-1))
+ formatKey.DeleteValue(kCompressionLevel);
+ else
+ formatKey.SetValue(kCompressionLevel, fo.Level);
+ if (fo.Method.IsEmpty())
+ formatKey.DeleteValue(kCompressionMethod);
+ else
+ formatKey.SetValue(kCompressionMethod, fo.Method);
+ if (fo.Dictionary == UINT32(-1))
+ formatKey.DeleteValue(kCompressionDictionary);
+ else
+ formatKey.SetValue(kCompressionDictionary, fo.Dictionary);
+ if (fo.Order == UINT32(-1))
+ formatKey.DeleteValue(kCompressionOrder);
+ else
+ formatKey.SetValue(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)
+ {
+ while(true)
+ {
+ TCHAR numberString[16];
+ ConvertUINT64ToString(info.HistoryArchives.Size(), numberString);
+ CSysString 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)
+ {
+ if (formatKey.QueryValue(kCompressionOptions, fo.Options) != ERROR_SUCCESS)
+ fo.Options.Empty();
+ if (formatKey.QueryValue(kCompressionLevel, fo.Level) != ERROR_SUCCESS)
+ fo.Level = UINT32(-1);
+ if (formatKey.QueryValue(kCompressionMethod, fo.Method) != ERROR_SUCCESS)
+ fo.Method.Empty();;
+ if (formatKey.QueryValue(kCompressionDictionary, fo.Dictionary) != ERROR_SUCCESS)
+ fo.Dictionary = UINT32(-1);
+ if (formatKey.QueryValue(kCompressionOrder, fo.Order) != ERROR_SUCCESS)
+ fo.Order = UINT32(-1);
+ 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 TCHAR *kWorkDirPathValueName = TEXT("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, GetSystemString(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);
+ }
+ CSysString 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, false); }
+
+
+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/7zip/UI/Common/ZipRegistry.h b/7zip/UI/Common/ZipRegistry.h
new file mode 100755
index 00000000..7bf56b46
--- /dev/null
+++ b/7zip/UI/Common/ZipRegistry.h
@@ -0,0 +1,119 @@
+// ZipRegistry.h
+
+#pragma once
+
+#ifndef __ZIPREGISTRY_H
+#define __ZIPREGISTRY_H
+
+#include "Common/String.h"
+
+namespace NExtraction {
+
+ namespace NPathMode
+ {
+ enum EEnum
+ {
+ kFullPathnames,
+ kCurrentPathnames,
+ kNoPathnames
+ };
+ }
+
+ namespace NOverwriteMode
+ {
+ enum EEnum
+ {
+ kAskBefore,
+ kWithoutPrompt,
+ kSkipExisting,
+ kAutoRename,
+ kAutoRenameExisting
+ };
+ }
+
+ struct CInfo
+ {
+ NPathMode::EEnum PathMode;
+ NOverwriteMode::EEnum OverwriteMode;
+ CSysStringVector Paths;
+ bool ShowPassword;
+ };
+}
+
+namespace NCompression {
+
+ struct CFormatOptions
+ {
+ CSysString FormatID;
+ CSysString Options;
+ UINT32 Level;
+ CSysString Method;
+ UINT32 Dictionary;
+ UINT32 Order;
+ void Init()
+ {
+ Level = Dictionary = Order = UINT32(-1);
+ Method.Empty();
+ // Options.Empty();
+ }
+ CFormatOptions() { Init(); }
+ };
+
+ struct CInfo
+ {
+ CSysStringVector 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 NExtraction::CInfo &info);
+void ReadExtractionInfo(NExtraction::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/7zip/UI/Console/ArError.h b/7zip/UI/Console/ArError.h
new file mode 100755
index 00000000..70f1d5b0
--- /dev/null
+++ b/7zip/UI/Console/ArError.h
@@ -0,0 +1,64 @@
+// ArError.h
+
+#pragma once
+
+#ifndef __ARERROR_H
+#define __ARERROR_H
+
+namespace NExitCode {
+
+struct CSystemError
+{
+ UINT32 ErrorValue;
+ CSystemError(UINT32 anErrorValue): ErrorValue(anErrorValue) {}
+};
+
+struct CMultipleErrors
+{
+ UINT64 NumErrors;
+ CMultipleErrors(UINT64 aNumErrors): NumErrors(aNumErrors) {}
+};
+
+
+enum EEnum {
+
+ kSuccess = 0, // Successful operation (User exit)
+ 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
+
+
+ kNotSupported = 102, // format of file doesn't supported
+ kFileError = 103, //
+
+ kVerError = 110, // Version doesn't supported
+ kMethodError = 111, // Unsupported method
+
+ kUserQuit = 120, // Unsupported method
+
+ kFileIsNotArchive = 130, // File Is Not Archive
+
+ kCommonError = 150,
+
+ kInputArchiveException = 160, // archive file does not exist
+
+ kErrorsDuringDecompression = 170, // Errors during decompression
+
+
+ kDirFileWith64BitSize = 171,
+ kFileTimeWinToDosConvertError = 172,
+
+ kFileChangedDuringOperation = 180,
+
+ kUserBreak = 255 // User stopped the process
+
+};
+
+}
+
+#endif
diff --git a/7zip/UI/Console/CompressionMode.h b/7zip/UI/Console/CompressionMode.h
new file mode 100755
index 00000000..e20c4f3b
--- /dev/null
+++ b/7zip/UI/Console/CompressionMode.h
@@ -0,0 +1,28 @@
+// CompressionMethodUtils.h
+
+#pragma once
+
+#ifndef __COMPRESSIONMETHODUTILS_H
+#define __COMPRESSIONMETHODUTILS_H
+
+struct CProperty
+{
+ UString Name;
+ UString Value;
+};
+
+struct CCompressionMethodMode
+{
+ #ifndef EXCLUDE_COM
+ UString FilePath;
+ CLSID ClassID1;
+ #else
+ UString Name;
+ #endif
+ CObjectVector<CProperty> Properties;
+ bool PasswordIsDefined;
+ bool AskPassword;
+ UString Password;
+};
+
+#endif
diff --git a/7zip/UI/Console/Console.dsp b/7zip/UI/Console/Console.dsp
new file mode 100755
index 00000000..762975e4
--- /dev/null
+++ b/7zip/UI/Console/Console.dsp
@@ -0,0 +1,581 @@
+# 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 "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\UTIL\7z.exe"
+
+!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 "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"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 "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /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"
+
+!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 "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /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=.\ArError.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CompressionMode.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ConsoleClose.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ConsoleClose.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Extract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Extract.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ExtractCallback.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=.\OpenCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\OpenCallback.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=.\TempFiles.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\TempFiles.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Update.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Update.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\UpdateCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\UpdateCallback.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\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\System.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\System.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\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\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\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\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\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
+# 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
+# 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/7zip/UI/Console/Console.dsw b/7zip/UI/Console/Console.dsw
new file mode 100755
index 00000000..0d93da2f
--- /dev/null
+++ b/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/7zip/UI/Console/ConsoleClose.cpp b/7zip/UI/Console/ConsoleClose.cpp
new file mode 100755
index 00000000..5527ef6b
--- /dev/null
+++ b/7zip/UI/Console/ConsoleClose.cpp
@@ -0,0 +1,57 @@
+// ConsoleClose.cpp
+
+#include "StdAfx.h"
+
+#include "ConsoleClose.h"
+
+static int g_BreakCounter = 0;
+static const int kBreakAbortThreshold = 2;
+
+namespace NConsoleClose {
+
+static BOOL WINAPI HandlerRoutine(DWORD aCtrlType)
+{
+ g_BreakCounter++;
+ if (g_BreakCounter < kBreakAbortThreshold)
+ return TRUE;
+ return FALSE;
+ /*
+ switch(aCtrlType)
+ {
+ 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/7zip/UI/Console/ConsoleClose.h b/7zip/UI/Console/ConsoleClose.h
new file mode 100755
index 00000000..9a0fc792
--- /dev/null
+++ b/7zip/UI/Console/ConsoleClose.h
@@ -0,0 +1,27 @@
+// ConsoleCloseUtils.h
+
+#pragma once
+
+#ifndef __CONSOLECLOSEUTILS_H
+#define __CONSOLECLOSEUTILS_H
+
+namespace NConsoleClose {
+
+bool TestBreakSignal();
+
+class CCtrlHandlerSetter
+{
+public:
+ CCtrlHandlerSetter();
+ virtual ~CCtrlHandlerSetter();
+};
+
+class CCtrlBreakException
+{};
+
+void CheckCtrlBreak();
+
+}
+
+#endif
+
diff --git a/7zip/UI/Console/Extract.cpp b/7zip/UI/Console/Extract.cpp
new file mode 100755
index 00000000..1230ece0
--- /dev/null
+++ b/7zip/UI/Console/Extract.cpp
@@ -0,0 +1,94 @@
+// Extract.cpp
+
+#include "StdAfx.h"
+
+#include "Extract.h"
+#include "ExtractCallback.h"
+#include "ArError.h"
+
+#include "Common/StdOutStream.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+#include "Windows/FileDir.h"
+
+using namespace NWindows;
+
+static const char *kEverythingIsOk = "Everything is Ok";
+
+HRESULT DeCompressArchiveSTD(
+ IInArchive *archive,
+ const NWildcard::CCensor &wildcardCensor,
+ const CExtractOptions &options)
+{
+ CRecordVector<UINT32> realIndices;
+ UINT32 numItems;
+ RINOK(archive->GetNumberOfItems(&numItems));
+
+ for(UINT32 i = 0; i < numItems; i++)
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(archive->GetProperty(i, kpidPath, &propVariant));
+ UString filePath;
+ if(propVariant.vt == VT_EMPTY)
+ filePath = options.DefaultItemName;
+ else
+ {
+ if(propVariant.vt != VT_BSTR)
+ return E_FAIL;
+ filePath = propVariant.bstrVal;
+ }
+ if (!wildcardCensor.CheckName(filePath))
+ continue;
+ realIndices.Add(i);
+ }
+ if (realIndices.Size() == 0)
+ {
+ g_StdOut << endl << "No files to process" << endl;
+ return S_OK;
+ }
+
+ CExtractCallbackImp *extractCallbackSpec = new CExtractCallbackImp;
+ CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);
+
+ UStringVector removePathParts;
+
+ NExtraction::CInfo extractionInfo;
+ extractionInfo.PathMode = options.FullPathMode() ? NExtraction::NPathMode::kFullPathnames:
+ NExtraction::NPathMode::kNoPathnames;
+
+ if (options.YesToAll)
+ extractionInfo.OverwriteMode = NExtraction::NOverwriteMode::kWithoutPrompt;
+ else
+ {
+ extractionInfo.OverwriteMode = options.OverwriteMode;
+ }
+
+ if(!options.OutputBaseDir.IsEmpty())
+ if(!NFile::NDirectory::CreateComplexDirectory(options.OutputBaseDir))
+ {
+ throw "Can not create output directory";
+ }
+
+ extractCallbackSpec->Init(archive,
+ options.OutputBaseDir,
+ extractionInfo, removePathParts,
+ options.DefaultItemName,
+ options.ArchiveFileInfo.LastWriteTime,
+ options.ArchiveFileInfo.Attributes,
+ options.PasswordEnabled,
+ options.Password);
+
+ HRESULT result = archive->Extract(&realIndices.Front(),
+ realIndices.Size(), options.ExtractMode == NExtractMode::kTest,
+ extractCallback);
+
+ if (extractCallbackSpec->m_NumErrors != 0)
+ throw NExitCode::CMultipleErrors(extractCallbackSpec->m_NumErrors);
+
+ if (result != S_OK)
+ throw NExitCode::CSystemError(result);
+
+ g_StdOut << endl << kEverythingIsOk << endl;
+
+ return S_OK;
+}
diff --git a/7zip/UI/Console/Extract.h b/7zip/UI/Console/Extract.h
new file mode 100755
index 00000000..8e2b4cb8
--- /dev/null
+++ b/7zip/UI/Console/Extract.h
@@ -0,0 +1,65 @@
+// Extract.h
+
+#pragma once
+
+#ifndef __EXTRACT_H
+#define __EXTRACT_H
+
+#include "Common/Wildcard.h"
+#include "Windows/FileFind.h"
+
+#include "../../Archive/IArchive.h"
+#include "../Common/ZipRegistry.h"
+
+namespace NExtractMode {
+
+enum EEnum
+{
+ kTest,
+ kFullPath,
+ kExtractToOne
+};
+
+
+}
+
+class CExtractOptions
+{
+public:
+ NExtractMode::EEnum ExtractMode;
+ UString OutputBaseDir;
+ bool YesToAll;
+ UString DefaultItemName;
+ NWindows::NFile::NFind::CFileInfoW ArchiveFileInfo;
+ bool PasswordEnabled;
+ UString Password;
+
+ NExtraction::NOverwriteMode::EEnum OverwriteMode;
+
+
+ CExtractOptions(NExtractMode::EEnum extractMode, const UString &outputBaseDir,
+ bool yesToAll, bool passwordEnabled, const UString &password,
+ NExtraction::NOverwriteMode::EEnum overwriteMode):
+ ExtractMode(extractMode),
+ OutputBaseDir(outputBaseDir),
+ YesToAll(yesToAll),
+ PasswordEnabled(passwordEnabled),
+ Password(password),
+ OverwriteMode(overwriteMode)
+ {}
+
+ bool TestMode() const { return (ExtractMode == NExtractMode::kTest); }
+ bool FullPathMode() const { return (ExtractMode == NExtractMode::kTest) ||
+ (ExtractMode == NExtractMode::kFullPath); }
+};
+
+HRESULT DeCompressArchiveSTD(IInArchive *archive,
+ const NWildcard::CCensor &wildcardCensor,
+ const CExtractOptions &options);
+
+/*
+bool DeCompressArchiveSTD(TTWildCardInputArchive &anArchive,
+ const TTExtractOptions &anOptions);
+*/
+
+#endif
diff --git a/7zip/UI/Console/ExtractCallback.cpp b/7zip/UI/Console/ExtractCallback.cpp
new file mode 100755
index 00000000..c3f0d498
--- /dev/null
+++ b/7zip/UI/Console/ExtractCallback.cpp
@@ -0,0 +1,405 @@
+// ExtractCallback.h
+
+#include "StdAfx.h"
+
+#include "ExtractCallback.h"
+#include "UserInputUtils.h"
+
+#include "ConsoleClose.h"
+#include "Common/StdOutStream.h"
+#include "Common/StdInStream.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"
+
+#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 ";
+void CExtractCallbackImp::Init(IInArchive *archive,
+ const UString &directoryPath,
+ const NExtraction::CInfo &extractModeInfo,
+ const UStringVector &removePathParts,
+ const UString &itemDefaultName,
+ const FILETIME &utcLastWriteTimeDefault,
+ UINT32 attributesDefault,
+ bool passwordIsDefined,
+ const UString &password)
+{
+ m_PasswordIsDefined = passwordIsDefined;
+ m_Password = password;
+ m_NumErrors = 0;
+
+ m_ItemDefaultName = itemDefaultName;
+ m_UTCLastWriteTimeDefault = utcLastWriteTimeDefault;
+ m_AttributesDefault = attributesDefault;
+
+ m_RemovePathParts = removePathParts;
+ m_ExtractModeInfo = extractModeInfo;
+ m_ArchiveHandler = archive;
+ m_DirectoryPath = directoryPath;
+ NFile::NName::NormalizeDirPathPrefix(m_DirectoryPath);
+}
+
+bool CExtractCallbackImp::IsEncrypted(UINT32 index)
+{
+ NCOM::CPropVariant propVariant;
+ if(m_ArchiveHandler->GetProperty(index, kpidEncrypted, &propVariant) != S_OK)
+ return false;
+ if (propVariant.vt != VT_BOOL)
+ return false;
+ return VARIANT_BOOLToBool(propVariant.boolVal);
+}
+
+STDMETHODIMP CExtractCallbackImp::SetTotal(UINT64 size)
+{
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::SetCompleted(const UINT64 *completeValue)
+{
+ if (NConsoleClose::TestBreakSignal())
+ return E_ABORT;
+ return S_OK;
+}
+
+void CExtractCallbackImp::CreateComplexDirectory(const UStringVector &dirPathParts)
+{
+ UString fullPath = m_DirectoryPath;
+ for(int i = 0; i < dirPathParts.Size(); i++)
+ {
+ fullPath += dirPathParts[i];
+ MyCreateDirectory(fullPath);
+ fullPath += (wchar_t)NFile::NName::kDirDelimiter;
+ }
+}
+
+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;
+}
+
+STDMETHODIMP CExtractCallbackImp::GetStream(UINT32 index,
+ ISequentialOutStream **outStream, INT32 askExtractMode)
+{
+ *outStream = NULL;
+ if (NConsoleClose::TestBreakSignal())
+ return E_ABORT;
+ m_OutFileStream.Release();
+ NCOM::CPropVariant propVariantName;
+ RINOK(m_ArchiveHandler->GetProperty(index, kpidPath, &propVariantName));
+ UString fullPath;
+ if(propVariantName.vt == VT_EMPTY)
+ fullPath = m_ItemDefaultName;
+ else
+ {
+ if(propVariantName.vt != VT_BSTR)
+ return E_FAIL;
+ fullPath = propVariantName.bstrVal;
+ }
+
+ m_FilePath = fullPath;
+
+ UString fullPathCorrect = GetCorrectPath(fullPath);
+
+ if(askExtractMode == NArchive::NExtract::NAskMode::kExtract)
+ {
+ NCOM::CPropVariant propVariant;
+ RINOK(m_ArchiveHandler->GetProperty(index, kpidAttributes, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ {
+ m_ProcessedFileInfo.Attributes = m_AttributesDefault;
+ m_ProcessedFileInfo.AttributesAreDefined = false;
+ }
+ else
+ {
+ if (propVariant.vt != VT_UI4)
+ throw "incorrect item";
+ m_ProcessedFileInfo.Attributes = propVariant.ulVal;
+ m_ProcessedFileInfo.AttributesAreDefined = true;
+ }
+
+ RINOK(m_ArchiveHandler->GetProperty(index, kpidIsFolder, &propVariant));
+ m_ProcessedFileInfo.IsDirectory = VARIANT_BOOLToBool(propVariant.boolVal);
+
+ bool isAnti = false;
+ {
+ NCOM::CPropVariant propVariantTemp;
+ RINOK(m_ArchiveHandler->GetProperty(index, kpidIsAnti,
+ &propVariantTemp));
+ if (propVariantTemp.vt == VT_BOOL)
+ isAnti = VARIANT_BOOLToBool(propVariantTemp.boolVal);
+ }
+
+ RINOK(m_ArchiveHandler->GetProperty(index, kpidLastWriteTime, &propVariant));
+ switch(propVariant.vt)
+ {
+ case VT_EMPTY:
+ m_ProcessedFileInfo.UTCLastWriteTime = m_UTCLastWriteTimeDefault;
+ break;
+ case VT_FILETIME:
+ m_ProcessedFileInfo.UTCLastWriteTime = propVariant.filetime;
+ break;
+ default:
+ return E_FAIL;
+ }
+
+ // GetPropertyValue(anItemIDList, kpidSize, &propVariant);
+ // UINT64 newFileSize = ConvertPropVariantToUINT64(propVariant);
+
+ UStringVector pathParts;
+ SplitPathToParts(fullPathCorrect, pathParts);
+ if(pathParts.IsEmpty())
+ return E_FAIL;
+ UString processedPath;
+ switch(m_ExtractModeInfo.PathMode)
+ {
+ case NExtraction::NPathMode::kFullPathnames:
+ {
+ processedPath = fullPathCorrect;
+ break;
+ }
+ case NExtraction::NPathMode::kCurrentPathnames:
+ {
+ int numRemovePathParts = m_RemovePathParts.Size();
+ if(pathParts.Size() <= numRemovePathParts)
+ return E_FAIL;
+ for(int i = 0; i < numRemovePathParts; i++)
+ if(m_RemovePathParts[i].CollateNoCase(pathParts[i]) != 0)
+ return E_FAIL;
+ pathParts.Delete(0, numRemovePathParts);
+ processedPath = MakePathNameFromParts(pathParts);
+ break;
+ }
+ case NExtraction::NPathMode::kNoPathnames:
+ {
+ processedPath = pathParts.Back();
+ pathParts.Delete(0, pathParts.Size() - 1); // Test it!!
+ break;
+ }
+ }
+ if(!m_ProcessedFileInfo.IsDirectory)
+ pathParts.DeleteBack();
+ if (!pathParts.IsEmpty())
+ {
+ if (!isAnti)
+ CreateComplexDirectory(pathParts);
+ }
+
+ UString fullProcessedPath = m_DirectoryPath + GetCorrectPath(processedPath);
+
+ if(m_ProcessedFileInfo.IsDirectory)
+ {
+ m_DiskFilePath = fullProcessedPath;
+
+ if (isAnti)
+ MyRemoveDirectory(m_DiskFilePath);
+ return S_OK;
+ }
+
+ NFile::NFind::CFileInfoW fileInfo;
+ if(NFile::NFind::FindFile(fullProcessedPath, fileInfo))
+ {
+ switch(m_ExtractModeInfo.OverwriteMode)
+ {
+ case NExtraction::NOverwriteMode::kSkipExisting:
+ return S_OK;
+ case NExtraction::NOverwriteMode::kAskBefore:
+ {
+ /*
+ NOverwriteDialog::CFileInfo oldFileInfo, newFileInfo;
+ oldFileInfo.Time = fileInfo.LastWriteTime;
+ oldFileInfo.Size = fileInfo.Size;
+ oldFileInfo.Name = fullProcessedPath;
+
+ newFileInfo.Time = m_ProcessedFileInfo.UTCLastWriteTime;
+ newFileInfo.Size = newFileSize;
+ newFileInfo.Name = fullPath;
+
+ NOverwriteDialog::NResult::EEnum result =
+ NOverwriteDialog::Execute(oldFileInfo, newFileInfo);
+ */
+
+ g_StdOut << "file " << fullProcessedPath <<
+ "\nalready exists. Overwrite with " << endl;
+ g_StdOut << fullPathCorrect;
+
+ NUserAnswerMode::EEnum overwriteAnswer = ScanUserYesNoAllQuit();
+
+ switch(overwriteAnswer)
+ {
+ case NUserAnswerMode::kQuit:
+ return E_ABORT;
+ case NUserAnswerMode::kNo:
+ return S_OK;
+ case NUserAnswerMode::kNoAll:
+ m_ExtractModeInfo.OverwriteMode = NExtraction::NOverwriteMode::kSkipExisting;
+ return S_OK;
+ case NUserAnswerMode::kYesAll:
+ m_ExtractModeInfo.OverwriteMode = NExtraction::NOverwriteMode::kWithoutPrompt;
+ break;
+ case NUserAnswerMode::kYes:
+ break;
+ case NUserAnswerMode::kAutoRename:
+ m_ExtractModeInfo.OverwriteMode = NExtraction::NOverwriteMode::kAutoRename;
+ break;
+ default:
+ throw 20413;
+ }
+ break;
+ }
+ }
+ if (m_ExtractModeInfo.OverwriteMode == NExtraction::NOverwriteMode::kAutoRename)
+ {
+ if (!AutoRenamePath(fullProcessedPath))
+ {
+ g_StdOut << kCantAutoRename;
+ g_StdOut << fullProcessedPath;
+ return E_ABORT;
+ }
+ }
+ else if (m_ExtractModeInfo.OverwriteMode == NExtraction::NOverwriteMode::kAutoRenameExisting)
+ {
+ UString existPath = fullProcessedPath;
+ if (!AutoRenamePath(existPath))
+ {
+ g_StdOut << kCantAutoRename;
+ g_StdOut << fullProcessedPath;
+ return E_ABORT;
+ }
+ if(!MyMoveFile(fullProcessedPath, existPath))
+ {
+ g_StdOut << kCantRenameFile;
+ return E_ABORT;
+ }
+ }
+ else
+ if (!DeleteFileAlways(fullProcessedPath))
+ {
+ g_StdOut << kCantDeleteOutputFile << endl;
+ g_StdOut << fullProcessedPath;
+ return E_ABORT;
+ }
+ }
+
+ if (!isAnti)
+ {
+ m_OutFileStreamSpec = new COutFileStream;
+ CMyComPtr<ISequentialOutStream> outStreamLoc(m_OutFileStreamSpec);
+ if (!m_OutFileStreamSpec->Open(fullProcessedPath))
+ {
+ m_NumErrors++;
+ g_StdOut << "Can not open output file " << endl;
+ g_StdOut << fullProcessedPath << endl;
+ return S_OK;
+ }
+ m_OutFileStream = outStreamLoc;
+ *outStream = outStreamLoc.Detach();
+ }
+ m_DiskFilePath = fullProcessedPath;
+ }
+ else
+ {
+ *outStream = NULL;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::PrepareOperation(INT32 askExtractMode)
+{
+ m_ExtractMode = false;
+ switch (askExtractMode)
+ {
+ case NArchive::NExtract::NAskMode::kExtract:
+ m_ExtractMode = true;
+ g_StdOut << kExtractingString;
+ break;
+ case NArchive::NExtract::NAskMode::kTest:
+ g_StdOut << kTestingString;
+ break;
+ case NArchive::NExtract::NAskMode::kSkip:
+ g_StdOut << kSkippingString;
+ break;
+ };
+ g_StdOut << m_FilePath;
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::SetOperationResult(INT32 resultEOperationResult)
+{
+ switch(resultEOperationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kOK:
+ {
+ break;
+ }
+ default:
+ {
+ m_NumErrors++;
+ switch(resultEOperationResult)
+ {
+ case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
+ g_StdOut << " Unsupported Method";
+ break;
+ case NArchive::NExtract::NOperationResult::kCRCError:
+ g_StdOut << " CRC Failed";
+ break;
+ case NArchive::NExtract::NOperationResult::kDataError:
+ g_StdOut << " Data Error";
+ break;
+ default:
+ g_StdOut << " Unknown Error";
+ // m_OutFileStream.Release();
+ // return E_FAIL;
+ }
+ }
+ }
+ if(m_OutFileStream != NULL)
+ m_OutFileStreamSpec->File.SetLastWriteTime(&m_ProcessedFileInfo.UTCLastWriteTime);
+ m_OutFileStream.Release();
+ if (m_ExtractMode && m_ProcessedFileInfo.AttributesAreDefined)
+ MySetFileAttributes(m_DiskFilePath, m_ProcessedFileInfo.Attributes);
+ g_StdOut << endl;
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackImp::CryptoGetTextPassword(BSTR *password)
+{
+ if (!m_PasswordIsDefined)
+ {
+ g_StdOut << "\nEnter password:";
+ AString oemPassword = g_StdIn.ScanStringUntilNewLine();
+ m_Password = MultiByteToUnicodeString(oemPassword, CP_OEMCP);
+ m_PasswordIsDefined = true;
+ }
+ CMyComBSTR tempName(m_Password);
+ *password = tempName.Detach();
+ return S_OK;
+}
+
diff --git a/7zip/UI/Console/ExtractCallback.h b/7zip/UI/Console/ExtractCallback.h
new file mode 100755
index 00000000..762d82cc
--- /dev/null
+++ b/7zip/UI/Console/ExtractCallback.h
@@ -0,0 +1,77 @@
+// ExtractCallback.h
+
+#pragma once
+
+#ifndef __EXTRACTCALLBACK_H
+#define __EXTRACTCALLBACK_H
+
+#include "Common/String.h"
+#include "../../Common/FileStreams.h"
+#include "../../IPassword.h"
+#include "../../Archive/IArchive.h"
+#include "../Common/ZipRegistry.h"
+
+class CExtractCallbackImp:
+ public IArchiveExtractCallback,
+ public ICryptoGetTextPassword,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP1(ICryptoGetTextPassword)
+
+ // IProgress
+ STDMETHOD(SetTotal)(UINT64 size);
+ STDMETHOD(SetCompleted)(const UINT64 *completeValue);
+
+ // IExtractCallback200
+ STDMETHOD(GetStream)(UINT32 index, ISequentialOutStream **outStream,
+ INT32 askExtractMode);
+ STDMETHOD(PrepareOperation)(INT32 askExtractMode);
+ STDMETHOD(SetOperationResult)(INT32 resultEOperationResult);
+
+ // ICryptoGetTextPassword
+ STDMETHOD(CryptoGetTextPassword)(BSTR *password);
+
+private:
+ CMyComPtr<IInArchive> m_ArchiveHandler;
+ UString m_DirectoryPath;
+ NExtraction::CInfo m_ExtractModeInfo;
+
+ UString m_FilePath;
+
+ UString m_DiskFilePath;
+
+ bool m_ExtractMode;
+ struct CProcessedFileInfo
+ {
+ FILETIME UTCLastWriteTime;
+ bool IsDirectory;
+ bool AttributesAreDefined;
+ UINT32 Attributes;
+ } m_ProcessedFileInfo;
+
+ COutFileStream *m_OutFileStreamSpec;
+ CMyComPtr<ISequentialOutStream> m_OutFileStream;
+ UStringVector m_RemovePathParts;
+
+ UString m_ItemDefaultName;
+ FILETIME m_UTCLastWriteTimeDefault;
+ UINT32 m_AttributesDefault;
+
+ bool m_PasswordIsDefined;
+ UString m_Password;
+
+ void CreateComplexDirectory(const UStringVector &dirPathParts);
+ bool IsEncrypted(UINT32 index);
+public:
+ void Init(IInArchive *archive, const UString &directoryPath,
+ const NExtraction::CInfo &anExtractModeInfo,
+ const UStringVector &removePathParts,
+ const UString &itemDefaultName,
+ const FILETIME &utcLastWriteTimeDefault, UINT32 attributesDefault,
+ bool passwordIsDefined, const UString &password);
+
+ UINT64 m_NumErrors;
+};
+
+#endif
diff --git a/7zip/UI/Console/List.cpp b/7zip/UI/Console/List.cpp
new file mode 100755
index 00000000..3676e5a9
--- /dev/null
+++ b/7zip/UI/Console/List.cpp
@@ -0,0 +1,381 @@
+// 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 "../Common/PropIDUtils.h"
+
+using namespace NWindows;
+
+/*
+static const char kEmptyFlag = '.';
+
+static const char kPasswordFlag = '*';
+static const char kSolidFlag = 'S';
+static const char kSplitBeforeFlag = 'B';
+static const char kSplitAfterFlag = 'A';
+static const char kCommentedFlag = 'C';
+*/
+
+static const char kEmptyAttributeChar = '.';
+//static const char kVolumeAttributeChar = 'V';
+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 AString GetAttributesString(DWORD winAttributes, bool directory)
+{
+ AString s;
+ // s = ((winAttributes & kLabelFileAttribute) != 0) ?
+ // kVolumeAttributeChar: kEmptyAttributeChar;
+ s += ((winAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 || directory) ?
+ kDirectoryAttributeChar: kEmptyAttributeChar;
+ s += ((winAttributes & FILE_ATTRIBUTE_READONLY) != 0)?
+ kReadonlyAttributeChar: kEmptyAttributeChar;
+ s += ((winAttributes & FILE_ATTRIBUTE_HIDDEN) != 0) ?
+ kHiddenAttributeChar: kEmptyAttributeChar;
+ s += ((winAttributes & FILE_ATTRIBUTE_SYSTEM) != 0) ?
+ kSystemAttributeChar: kEmptyAttributeChar;
+ s += ((winAttributes & FILE_ATTRIBUTE_ARCHIVE) != 0) ?
+ kArchiveAttributeChar: kEmptyAttributeChar;
+ return s;
+}
+
+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;
+ 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 Init(const CFieldInfoInit *standardFieldTable, int numItems);
+ void PrintTitle();
+ void PrintTitleLines();
+ HRESULT PrintItemInfo(IInArchive *archive,
+ const UString &defaultItemName,
+ const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,
+ UINT32 index);
+ HRESULT PrintSummaryInfo(UINT64 numFiles, const UINT64 *size,
+ const UINT64 *compressedSize);
+};
+
+void CFieldPrinter::Init(const CFieldInfoInit *standardFieldTable, int numItems)
+{
+ 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);
+ }
+}
+
+
+void CFieldPrinter::PrintTitle()
+{
+ for (int i = 0; i < _fields.Size(); i++)
+ {
+ const CFieldInfo &fieldInfo = _fields[i];
+ PrintSpaces(fieldInfo.PrefixSpacesWidth);
+ PrintString(fieldInfo.TitleAdjustment, 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);
+}
+
+
+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";
+ SYSTEMTIME st;
+ if (FileTimeToSystemTime(&localFileTime, &st))
+ {
+ char s[32];
+ wsprintfA(s, "%04u-%02u-%02u %02u:%02u:%02u",
+ st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
+ g_StdOut << s;
+ }
+ else
+ g_StdOut << kEmptyTimeString;
+ }
+}
+
+HRESULT CFieldPrinter::PrintItemInfo(IInArchive *archive,
+ const UString &defaultItemName,
+ const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,
+ UINT32 index)
+{
+ for (int i = 0; i < _fields.Size(); i++)
+ {
+ const CFieldInfo &fieldInfo = _fields[i];
+ PrintSpaces(fieldInfo.PrefixSpacesWidth);
+
+ NCOM::CPropVariant propVariant;
+ RINOK(archive->GetProperty(index,
+ fieldInfo.PropID, &propVariant));
+ if (propVariant.vt == VT_EMPTY)
+ {
+ switch(fieldInfo.PropID)
+ {
+ case kpidPath:
+ propVariant = defaultItemName;
+ break;
+ case kpidLastWriteTime:
+ propVariant = archiveFileInfo.LastWriteTime;
+ break;
+ default:
+ PrintSpaces(fieldInfo.Width);
+ continue;
+ }
+ }
+
+ if (fieldInfo.PropID == kpidLastWriteTime)
+ {
+ PrintTime(propVariant);
+ continue;
+ }
+ if (fieldInfo.PropID == kpidAttributes)
+ {
+ if (propVariant.vt != VT_UI4)
+ throw "incorrect item";
+ UINT32 attributes = propVariant.ulVal;
+ NCOM::CPropVariant propVariantIsFolder;
+ RINOK(archive->GetProperty(index,
+ kpidIsFolder, &propVariantIsFolder));
+ if(propVariantIsFolder.vt != VT_BOOL)
+ return E_FAIL;
+ g_StdOut << GetAttributesString(attributes, VARIANT_BOOLToBool(propVariantIsFolder.boolVal));
+ continue;
+ }
+
+ if (propVariant.vt == VT_BSTR)
+ {
+ PrintString(fieldInfo.TextAdjustment, fieldInfo.Width, propVariant.bstrVal);
+ continue;
+ }
+ PrintString(fieldInfo.TextAdjustment, fieldInfo.Width,
+ ConvertPropertyToString(propVariant, fieldInfo.PropID));
+ }
+ 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);
+}
+
+static const wchar_t *kFilesMessage = L"files";
+
+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, fieldInfo.Width, 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 ListArchive(IInArchive *archive,
+ const UString &defaultItemName,
+ const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,
+ const NWildcard::CCensor &wildcardCensor/*, bool fullPathMode,
+ NListMode::EEnum mode*/)
+{
+ CFieldPrinter fieldPrinter;
+ fieldPrinter.Init(kStandardFieldTable, sizeof(kStandardFieldTable) / sizeof(kStandardFieldTable[0]));
+ fieldPrinter.PrintTitle();
+ g_StdOut << endl;
+ fieldPrinter.PrintTitleLines();
+ g_StdOut << endl;
+
+ // bool nameFirst = (fullPathMode && (mode != NListMode::kDefault)) || (mode == NListMode::kAll);
+
+ 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;
+ NCOM::CPropVariant propVariant;
+ RINOK(archive->GetProperty(i, kpidPath, &propVariant));
+ UString filePath;
+ if(propVariant.vt == VT_EMPTY)
+ filePath = defaultItemName;
+ else
+ {
+ if(propVariant.vt != VT_BSTR)
+ return E_FAIL;
+ filePath = propVariant.bstrVal;
+ }
+ if (!wildcardCensor.CheckName(filePath))
+ continue;
+
+ fieldPrinter.PrintItemInfo(archive, defaultItemName, archiveFileInfo, i);
+
+ 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;
+ }
+ fieldPrinter.PrintTitleLines();
+ g_StdOut << endl;
+ /*
+ if(numFiles == 0)
+ g_StdOut << kNoFilesMessage);
+ else
+ */
+ fieldPrinter.PrintSummaryInfo(numFiles, totalUnPackSizePointer, totalPackSizePointer);
+ g_StdOut << endl;
+ return S_OK;
+}
+
+
+
diff --git a/7zip/UI/Console/List.h b/7zip/UI/Console/List.h
new file mode 100755
index 00000000..e8c16164
--- /dev/null
+++ b/7zip/UI/Console/List.h
@@ -0,0 +1,31 @@
+// List.h
+
+#pragma once
+
+#ifndef __LIST_H
+#define __LIST_H
+
+#include "../../Archive/IArchive.h"
+#include "Common/Wildcard.h"
+#include "Windows/FileFind.h"
+
+/*
+namespace NListMode
+{
+ enum EEnum
+ {
+ kDefault,
+ kAdd,
+ kAll
+ };
+}
+*/
+
+HRESULT ListArchive(IInArchive *archive,
+ const UString &defaultItemName,
+ const NWindows::NFile::NFind::CFileInfoW &srchiveFileInfo,
+ const NWildcard::CCensor &wildcardCensor/*, bool fullPathMode,
+ NListMode::EEnum mode*/);
+
+#endif
+
diff --git a/7zip/UI/Console/Main.cpp b/7zip/UI/Console/Main.cpp
new file mode 100755
index 00000000..8e01ae8d
--- /dev/null
+++ b/7zip/UI/Console/Main.cpp
@@ -0,0 +1,934 @@
+// Main.cpp
+
+#include "StdAfx.h"
+
+#include <initguid.h>
+#include <io.h>
+
+
+#include "Common/CommandLineParser.h"
+#include "Common/StdOutStream.h"
+#include "Common/Wildcard.h"
+#include "Common/ListFileUtils.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileName.h"
+#include "Windows/Defs.h"
+
+#include "../../IPassword.h"
+#include "../../ICoder.h"
+#include "../../Compress/LZ/IMatchFinder.h"
+#include "../Common/DefaultName.h"
+#include "../Common/OpenArchive.h"
+#include "../Common/ArchiverInfo.h"
+#include "../Common/UpdateAction.h"
+
+#include "List.h"
+#include "Extract.h"
+#include "Update.h"
+#include "ArError.h"
+#include "OpenCallback.h"
+
+#ifndef EXCLUDE_COM
+#include "Windows/DLL.h"
+#endif
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NCommandLineParser;
+
+HINSTANCE g_hInstance = 0;
+
+static const char *kCopyrightString = "\n7-Zip"
+#ifdef EXCLUDE_COM
+" (A)"
+#endif
+
+#ifdef UNICODE
+" [NT]"
+#endif
+
+" 3.12 Copyright (c) 1999-2003 Igor Pavlov 2003-12-10\n";
+
+const wchar_t *kDefaultArchiveType = L"7z";
+const wchar_t *kDefaultSfxModule = L"7zCon.sfx";
+const wchar_t *kSFXExtension = L"exe";
+
+static const int kNumSwitches = 15;
+
+namespace NKey {
+enum Enum
+{
+ kHelp1 = 0,
+ kHelp2,
+ kDisablePercents,
+ kArchiveType,
+ kYes,
+ kPassword,
+ kProperty,
+ kOutputDir,
+ kWorkingDir,
+ kInclude,
+ kExclude,
+ kUpdate,
+ kRecursed,
+ kSfx,
+ kOverwrite
+};
+
+}
+
+namespace NRecursedType {
+enum EEnum
+{
+ kRecursed,
+ kWildCardOnlyRecursed,
+ kNonRecursed,
+};
+}
+
+static const wchar_t 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 wchar_t *kOverwritePostCharSet = L"asut";
+
+NExtraction::NOverwriteMode::EEnum k_OverwriteModes[] =
+{
+ NExtraction::NOverwriteMode::kWithoutPrompt,
+ NExtraction::NOverwriteMode::kSkipExisting,
+ NExtraction::NOverwriteMode::kAutoRename,
+ NExtraction::NOverwriteMode::kAutoRenameExisting
+};
+
+
+static const CSwitchForm kSwitchForms[kNumSwitches] =
+ {
+ { L"?", NSwitchType::kSimple, false },
+ { L"H", 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"U", NSwitchType::kUnLimitedPostString, true, 1},
+ { L"R", NSwitchType::kPostChar, false, 0, 0, kRecursedPostCharSet },
+ { L"SFX", NSwitchType::kUnLimitedPostString, false, 0 },
+ { L"AO", NSwitchType::kPostChar, false, 1, 1, kOverwritePostCharSet}
+ };
+
+static const int kNumCommandForms = 7;
+
+namespace NCommandType {
+enum EEnum
+{
+ kAdd = 0,
+ kUpdate,
+ kDelete,
+ kTest,
+ kExtract,
+ kFullExtract,
+ kList
+};
+
+}
+
+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 }
+ // { "L", true }
+};
+
+static const NRecursedType::EEnum kCommandRecursedDefault[kNumCommandForms] =
+{
+ NRecursedType::kNonRecursed,
+ NRecursedType::kNonRecursed,
+ NRecursedType::kNonRecursed,
+ NRecursedType::kRecursed,
+ NRecursedType::kRecursed,
+ NRecursedType::kRecursed,
+ NRecursedType::kRecursed
+};
+
+
+// -------------------------------------------------
+// Update area
+
+const UString kUpdatePairStateIDSet = L"PQRXYZW";
+const int kUpdatePairStateNotSupportedActions[] = {2, 2, 1, -1, -1, -1, -1};
+
+const UString kUpdatePairActionIDSet = L"0123"; //Ignore, Copy, Compress
+
+const wchar_t *kUpdateIgnoreItselfPostStringID = L"-";
+const wchar_t kUpdateNewArchivePostCharID = '!';
+
+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 = 2;
+static const int kCommandIndex = 0;
+static const int kArchiveNameIndex = kCommandIndex + 1;
+static const int kFirstFileNameIndex = kArchiveNameIndex + 1;
+
+static const char *kHelpString =
+ "\nUsage: 7z <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\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 pathname\n"
+ "<Switches>\n"
+ " -bd Disable percentage indicator\n"
+ " -i[r[-|0]]{@listfile|!wildcard}: Include filenames\n"
+ " -m{Parameters}: set compression Method\n"
+// " -m0: store (no compression)\n"
+// " -md<#>[b|k|m]: set Dictionary Size\n"
+// " -mx: maXimize compression\n"
+ " -o{Directory}: set Output directory\n"
+ " -p{Password}: set Password\n"
+ " -r[-|0]: Recurse subdirectories\n"
+ " -sfx[{name}]: Create SFX archive\n"
+ " -t{Type}: Set type of archive\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 *kUserErrorMessage = "Incorrect command line"; // NExitCode::kUserError
+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 *kProcessArchiveMessage = " archive: ";
+
+// ---------------------------
+
+static const AString kExtractGroupProcessMessage = "Processing";
+static const AString kListingProcessMessage = "Listing";
+
+static const AString kDefaultWorkingDirectory = ""; // test it maybemust be "."
+
+struct CArchiveCommand
+{
+ NCommandType::EEnum CommandType;
+ NRecursedType::EEnum DefaultRecursedType() const;
+ bool IsFromExtractGroup(NExtractMode::EEnum &extractMode) const;
+ bool IsFromUpdateGroup() const;
+};
+
+NRecursedType::EEnum CArchiveCommand::DefaultRecursedType() const
+{
+ return kCommandRecursedDefault[CommandType];
+}
+
+bool CArchiveCommand::IsFromExtractGroup(NExtractMode::EEnum &extractMode) const
+{
+ switch(CommandType)
+ {
+ case NCommandType::kTest:
+ extractMode = NExtractMode::kTest;
+ return true;
+ case NCommandType::kExtract:
+ extractMode = NExtractMode::kExtractToOne;
+ return true;
+ case NCommandType::kFullExtract:
+ extractMode = NExtractMode::kFullPath;
+ return true;
+ default:
+ return false;
+ }
+}
+
+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;
+ }
+}
+
+void PrintHelp(void)
+{
+ g_StdOut << kHelpString;
+}
+
+static void ShowMessageAndThrowException(LPCSTR message, NExitCode::EEnum code)
+{
+ g_StdOut << message << endl;
+ throw code;
+}
+
+static void PrintHelpAndExit() // yyy
+{
+ PrintHelp();
+ ShowMessageAndThrowException(kUserErrorMessage, NExitCode::kUserError);
+}
+
+static void PrintProcessTitle(const AString &processTitle, const UString &archiveName)
+{
+ g_StdOut << endl << processTitle <<
+ kProcessArchiveMessage << archiveName << endl << endl;
+}
+
+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 TestIsPathLegal(const UString &name)
+{
+ if (name.Length() == 0)
+ return false;
+ if (name[0] == L'\\' || name[0] == L'/')
+ return false;
+ if (name.Length() < 3)
+ return true;
+ if (name[1] == L':' && name[2] == L'\\')
+ return false;
+ return true;
+}
+
+static bool AddNameToCensor(NWildcard::CCensor &wildcardCensor,
+ const UString &name, bool include, NRecursedType::EEnum type)
+{
+ if (!TestIsPathLegal(name))
+ throw "Can't use absolute paths";
+ bool isWildCard = DoesNameContainWildCard(name);
+ bool recursed;
+
+ switch (type)
+ {
+ case NRecursedType::kWildCardOnlyRecursed:
+ recursed = isWildCard;
+ break;
+ case NRecursedType::kRecursed:
+ recursed = true;
+ break;
+ case NRecursedType::kNonRecursed:
+ recursed = false;
+ break;
+ }
+ wildcardCensor.AddItem(name, include, recursed, isWildCard);
+ return true;
+}
+
+static inline UINT GetCurrentCodePage()
+ { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
+
+void AddToCensorFromListFile(NWildcard::CCensor &wildcardCensor,
+ LPCWSTR fileName, bool include, NRecursedType::EEnum type)
+{
+ UStringVector names;
+ if (!ReadNamesFromListFile(GetSystemString(fileName,
+ GetCurrentCodePage()), names))
+ ShowMessageAndThrowException(kIncorrectListFile, NExitCode::kUserError);
+ for (int i = 0; i < names.Size(); i++)
+ if (!AddNameToCensor(wildcardCensor, names[i], include, type))
+ ShowMessageAndThrowException(kIncorrectWildCardInListFile, NExitCode::kUserError);
+}
+
+void AddCommandLineWildCardToCensr(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)
+{
+ int numNonSwitchStrings = nonSwitchStrings.Size();
+ if(numNonSwitchStrings == kMinNonSwitchWords && (!thereAreSwitchIncludeWildCards))
+ AddCommandLineWildCardToCensr(wildcardCensor, kUniversalWildcard, true, type);
+ for(int i = kFirstFileNameIndex; i < numNonSwitchStrings; i++)
+ {
+ const UString &s = nonSwitchStrings[i];
+ if (s[0] == kFileListID)
+ AddToCensorFromListFile(wildcardCensor, s.Mid(1), true, type);
+ else
+ AddCommandLineWildCardToCensr(wildcardCensor, s, true, type);
+ }
+}
+
+void AddSwitchWildCardsToCensor(NWildcard::CCensor &wildcardCensor,
+ const UStringVector &strings, bool include,
+ NRecursedType::EEnum commonRecursedType)
+{
+ for(int i = 0; i < strings.Size(); i++)
+ {
+ const UString &name = strings[i];
+ NRecursedType::EEnum recursedType;
+ int pos = 0;
+ if (name.Length() < kSomeCludePostStringMinSize)
+ PrintHelpAndExit();
+ 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)
+ PrintHelpAndExit();
+ 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);
+ else
+ PrintHelpAndExit();
+ }
+}
+
+// ------------------------------------------------------
+// AddCommand functions
+
+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;
+}
+
+bool ParseUpdateCommandString2(const UString &command,
+ NUpdateArchive::CActionSet &actionSet, UString &postString)
+{
+ for(int i = 0; i < command.Length();)
+ {
+ char 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;
+}
+
+UString MakeFullArchiveName(const UString &name, const UString &extension)
+{
+ if (extension.IsEmpty())
+ return name;
+ if (name.IsEmpty())
+ return name;
+ if (name[name.Length() - 1] == L'.')
+ return name.Left(name.Length() - 1);
+ int slash1Pos = name.ReverseFind(L'\\');
+ int slash2Pos = name.ReverseFind(L'/');
+ int slashPos = MyMax(slash1Pos, slash2Pos);
+ int dotPos = name.ReverseFind(L'.');
+ if (dotPos >= 0 && (dotPos > slashPos || slashPos < 0))
+ return name;
+ return name + L'.' + extension;
+}
+
+void ParseUpdateCommandString(CUpdateArchiveOptions &options,
+ const UStringVector &updatePostStrings,
+ const NUpdateArchive::CActionSet &defaultActionSet,
+ const UString &extension)
+{
+ 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))
+ PrintHelpAndExit();
+ if(postString.IsEmpty())
+ {
+ if(options.UpdateArchiveItself)
+ {
+ options.Commands[0].ActionSet = actionSet;
+ }
+ }
+ else
+ {
+ if(MyCharUpper(postString[0]) != kUpdateNewArchivePostCharID)
+ PrintHelpAndExit();
+ CUpdateArchiveCommand updateCommand;
+
+ UString archivePath = postString.Mid(1);
+
+ if (archivePath.IsEmpty())
+ PrintHelpAndExit();
+ updateCommand.ArchivePath = MakeFullArchiveName(archivePath, extension);
+ updateCommand.ActionSet = actionSet;
+ options.Commands.Add(updateCommand);
+ }
+ }
+ }
+}
+
+static void SetAddCommandOptions(NCommandType::EEnum commandType,
+ const CParser &parser,
+ const UString &archivePath,
+ CUpdateArchiveOptions &options, UString &workingDir,
+ const UString &extension)
+{
+ NUpdateArchive::CActionSet defaultActionSet;
+ switch(commandType)
+ {
+ case NCommandType::kAdd:
+ defaultActionSet = NUpdateArchive::kAddActionSet;
+ break;
+ case NCommandType::kDelete:
+ defaultActionSet = NUpdateArchive::kDeleteActionSet;
+ break;
+ default:
+ defaultActionSet = NUpdateArchive::kUpdateActionSet;
+ }
+
+ options.ArchivePath = archivePath;
+ options.UpdateArchiveItself = true;
+
+ options.Commands.Clear();
+ CUpdateArchiveCommand updateMainCommand;
+ updateMainCommand.ActionSet = defaultActionSet;
+ options.Commands.Add(updateMainCommand);
+ // options.ItselfActionSet = defaultActionSet;
+ if(parser[NKey::kUpdate].ThereIs)
+ ParseUpdateCommandString(options, parser[NKey::kUpdate].PostStrings,
+ defaultActionSet, extension);
+ if(parser[NKey::kWorkingDir].ThereIs)
+ {
+ const UString &postString = parser[NKey::kWorkingDir].PostStrings[0];
+ if (postString.IsEmpty())
+ NDirectory::MyGetTempPath(workingDir);
+ else
+ workingDir = postString;
+ }
+ else
+ {
+ if (!NDirectory::GetOnlyDirPrefix(archivePath, workingDir))
+ throw "bad archive name";
+ if (workingDir.IsEmpty())
+ workingDir = L".\\";
+ }
+ if(options.SfxMode = parser[NKey::kSfx].ThereIs)
+ {
+ UString moduleName = parser[NKey::kSfx].PostStrings[0];
+ if (moduleName.IsEmpty())
+ moduleName = kDefaultSfxModule;
+ if (!NDirectory::MySearchPath(NULL, moduleName, NULL, options.SfxModule))
+ throw "can't find specified sfx module";
+ }
+}
+
+static const char kByteSymbol = 'B';
+static const char kKiloByteSymbol = 'K';
+static const char kMegaByteSymbol = 'M';
+
+static void SetMethodOptions(const CParser &parser,
+ CUpdateArchiveOptions &options)
+{
+ 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);
+ }
+ options.MethodMode.Properties.Add(property);
+ }
+ }
+}
+
+static void MyOpenArhive(const UString &archiveName,
+ const NFind::CFileInfoW &archiveFileInfo,
+ #ifndef EXCLUDE_COM
+ HMODULE *module,
+ #endif
+ IInArchive **archiveHandler,
+ UString &defaultItemName,
+ bool &passwordEnabled,
+ UString &password)
+{
+ COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
+ CMyComPtr<IArchiveOpenCallback> openCallback = openCallbackSpec;
+ if (passwordEnabled)
+ {
+ openCallbackSpec->PasswordIsDefined = passwordEnabled;
+ openCallbackSpec->Password = password;
+ }
+
+ UString fullName;
+ int fileNamePartStartIndex;
+ NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartIndex);
+ openCallbackSpec->LoadFileInfo(
+ fullName.Left(fileNamePartStartIndex),
+ fullName.Mid(fileNamePartStartIndex));
+
+ CArchiverInfo archiverInfo;
+ int subExtIndex;
+ HRESULT result = OpenArchive(archiveName,
+ #ifndef EXCLUDE_COM
+ module,
+ #endif
+ archiveHandler,
+ archiverInfo,
+ subExtIndex,
+ openCallback);
+ if (result == S_FALSE)
+ throw "file is not supported archive";
+ if (result != S_OK)
+ throw "error";
+ defaultItemName = GetDefaultName(archiveName,
+ archiverInfo.Extensions[subExtIndex].Extension,
+ archiverInfo.Extensions[subExtIndex].AddExtension);
+ passwordEnabled = openCallbackSpec->PasswordIsDefined;
+ password = openCallbackSpec->Password;
+}
+
+#ifndef EXCLUDE_COM
+void SetArchiveType(const UString &archiveType,
+ UString &filePath, CLSID &classID, UString &archiveExtension)
+#else
+void SetArchiveType(const UString &archiveType,
+ UString &formatName, UString &archiveExtension)
+#endif
+{
+ CObjectVector<CArchiverInfo> archiverInfoVector;
+ ReadArchiverInfoList(archiverInfoVector);
+ if (archiverInfoVector.Size() == 0)
+ throw "There are no installed archive handlers";
+ if (archiveType.IsEmpty())
+ throw "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;
+ }
+ }
+ throw "Incorrect archive type was assigned";
+}
+
+// int Main2(int numArguments, const char *arguments[])
+int Main2()
+{
+ SetFileApisToOEM();
+
+ g_StdOut << kCopyrightString;
+
+ UStringVector commandStrings;
+ NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
+
+ if(commandStrings.Size() == 1)
+ {
+ PrintHelp();
+ return 0;
+ }
+ commandStrings.Delete(0);
+
+ 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();
+ if(numNonSwitchStrings < kMinNonSwitchWords)
+ PrintHelpAndExit();
+ CArchiveCommand command;
+ if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], command))
+ PrintHelpAndExit();
+
+ NRecursedType::EEnum recursedType;
+ if (parser[NKey::kRecursed].ThereIs)
+ recursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex);
+ else
+ recursedType = command.DefaultRecursedType();
+
+ NWildcard::CCensor wildcardCensor;
+
+ bool thereAreSwitchIncludeWildCards;
+ if (parser[NKey::kInclude].ThereIs)
+ {
+ thereAreSwitchIncludeWildCards = true;
+ AddSwitchWildCardsToCensor(wildcardCensor, parser[NKey::kInclude].PostStrings,
+ true, recursedType);
+ }
+ else
+ thereAreSwitchIncludeWildCards = false;
+ if (parser[NKey::kExclude].ThereIs)
+ AddSwitchWildCardsToCensor(wildcardCensor, parser[NKey::kExclude].PostStrings,
+ false, recursedType);
+
+ AddToCensorFromNonSwitchesStrings(wildcardCensor, nonSwitchStrings, recursedType,
+ thereAreSwitchIncludeWildCards);
+
+
+ bool yesToAll = parser[NKey::kYes].ThereIs;
+
+ UString archiveName;
+ archiveName = nonSwitchStrings[kArchiveNameIndex];
+
+ NExtractMode::EEnum extractMode;
+ bool isExtractGroupCommand = command.IsFromExtractGroup(extractMode);
+
+ bool passwordEnabled = parser[NKey::kPassword].ThereIs;
+
+ UString password;
+ if(passwordEnabled)
+ password = parser[NKey::kPassword].PostStrings[0];
+
+ if(isExtractGroupCommand || command.CommandType == NCommandType::kList)
+ {
+ NFind::CFileInfoW archiveFileInfo;
+ if (!NFind::FindFile(archiveName, archiveFileInfo) || archiveFileInfo.IsDirectory())
+ throw "there is no such archive";
+
+ if (archiveFileInfo.IsDirectory())
+ throw "there is no such archive";
+
+ UString defaultItemName;
+
+ #ifndef EXCLUDE_COM
+ NDLL::CLibrary library;
+ #endif
+ CMyComPtr<IInArchive> archiveHandler;
+ CArchiverInfo archiverInfo;
+
+ MyOpenArhive(archiveName, archiveFileInfo,
+ #ifndef EXCLUDE_COM
+ &library,
+ #endif
+ &archiveHandler,
+ defaultItemName, passwordEnabled, password);
+
+ if(isExtractGroupCommand)
+ {
+ PrintProcessTitle(kExtractGroupProcessMessage, archiveName);
+ UString outputDir;
+ if(parser[NKey::kOutputDir].ThereIs)
+ {
+ outputDir = parser[NKey::kOutputDir].PostStrings[0]; // test this DirPath
+ NName::NormalizeDirPathPrefix(outputDir);
+ }
+
+ NExtraction::NOverwriteMode::EEnum overwriteMode =
+ NExtraction::NOverwriteMode::kAskBefore;
+ if(parser[NKey::kOverwrite].ThereIs)
+ overwriteMode = k_OverwriteModes[parser[NKey::kOverwrite].PostCharIndex];
+
+
+ CExtractOptions options(extractMode, outputDir, yesToAll,
+ passwordEnabled, password, overwriteMode);
+ options.DefaultItemName = defaultItemName;
+ options.ArchiveFileInfo = archiveFileInfo;
+ // options.ArchiveFileInfo = archiveFileInfo;
+ HRESULT result = DeCompressArchiveSTD(archiveHandler, wildcardCensor, options);
+ if (result != S_OK)
+ {
+ return NExitCode::kErrorsDuringDecompression;
+ }
+ }
+ else
+ {
+ PrintProcessTitle(kListingProcessMessage, archiveName);
+ ListArchive(archiveHandler, defaultItemName, archiveFileInfo,
+ wildcardCensor/*, command.ListFullPathes, command.ListMode*/);
+ }
+ }
+ else if(command.IsFromUpdateGroup())
+ {
+ CUpdateArchiveOptions options;
+
+ options.MethodMode.PasswordIsDefined = passwordEnabled && !password.IsEmpty();
+ options.MethodMode.AskPassword = passwordEnabled && password.IsEmpty();
+ options.MethodMode.Password = password;
+
+ UString workingDir;
+
+ UString archiveType;
+ if(parser[NKey::kArchiveType].ThereIs)
+ archiveType = parser[NKey::kArchiveType].PostStrings[0];
+ else
+ archiveType = kDefaultArchiveType;
+
+ UString extension;
+ if (!archiveType.IsEmpty())
+ {
+ #ifndef EXCLUDE_COM
+ SetArchiveType(archiveType, options.MethodMode.FilePath,
+ options.MethodMode.ClassID1, extension);
+ #else
+ SetArchiveType(archiveType, options.MethodMode.Name, extension);
+ #endif
+ }
+ if(parser[NKey::kSfx].ThereIs)
+ extension = kSFXExtension;
+ archiveName = MakeFullArchiveName(archiveName, extension);
+
+ SetAddCommandOptions(command.CommandType, parser, archiveName, options,
+ workingDir, extension);
+
+ SetMethodOptions(parser, options);
+
+ if (options.SfxMode)
+ {
+ CProperty property;
+ property.Name = L"rsfx";
+ property.Value = L"on";
+ options.MethodMode.Properties.Add(property);
+ }
+
+ NFind::CFileInfoW archiveFileInfo;
+ #ifndef EXCLUDE_COM
+ NDLL::CLibrary library;
+ #endif
+ CMyComPtr<IInArchive> archive;
+
+ UString defaultItemName;
+ if (NFind::FindFile(archiveName, archiveFileInfo))
+ {
+ if (archiveFileInfo.IsDirectory())
+ throw "there is no such archive";
+ MyOpenArhive(archiveName, archiveFileInfo,
+ #ifndef EXCLUDE_COM
+ &library,
+ #endif
+ &archive,
+ defaultItemName, passwordEnabled, password);
+ }
+ else
+ if (archiveType.IsEmpty())
+ throw "type of archive is not specified";
+ bool enableParcents = !parser[NKey::kDisablePercents].ThereIs;
+ if (enableParcents)
+ {
+ if (!isatty(fileno(stdout)))
+ enableParcents = false;
+ }
+ HRESULT result = UpdateArchiveStdMain(wildcardCensor, options, workingDir,
+ archive, &defaultItemName, &archiveFileInfo, enableParcents);
+ if (result != S_OK)
+ throw NExitCode::CSystemError(result);
+ }
+ else
+ PrintHelpAndExit();
+ return 0;
+}
diff --git a/7zip/UI/Console/MainAr.cpp b/7zip/UI/Console/MainAr.cpp
new file mode 100755
index 00000000..8c612bd4
--- /dev/null
+++ b/7zip/UI/Console/MainAr.cpp
@@ -0,0 +1,114 @@
+// MainAr.cpp
+
+#include "StdAfx.h"
+
+// #include <locale.h>
+
+#include "Windows/COM.h"
+#include "Windows/Error.h"
+
+#include "Common/StdOutStream.h"
+#include "Common/NewHandler.h"
+#include "Common/StringConvert.h"
+
+#include "ConsoleClose.h"
+#include "ArError.h"
+
+using namespace NWindows;
+
+// extern int Main2(int numArguments, const char *arguments[]);
+extern int Main2();
+
+static const char *kExceptionErrorMessage = "\n\nError:\n";
+static const char *kUserBreak = "\nBreak signaled\n";
+
+static const char *kMemoryExceptionMessage = "\n\nMemory Error! Can't allocate!\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 __cdecl main()
+// int __cdecl main(int numArguments, const char *arguments[])
+{
+ #ifdef UNICODE
+ if (!IsItWindowsNT())
+ {
+ g_StdOut << "This program requires Windows NT/2000/XP";
+ return NExitCode::kFatalError;
+ }
+ #endif
+ // setlocale(LC_COLLATE, ".OCP");
+ int result=1;
+ NCOM::CComInitializer comInitializer;
+ try
+ {
+ NConsoleClose::CCtrlHandlerSetter aCtrlHandlerSetter;
+ try
+ {
+ // result = Main2(numArguments, arguments);
+ result = Main2();
+ }
+ catch(const NConsoleClose::CCtrlBreakException &)
+ {
+ g_StdOut << endl << kUserBreak;
+ return (NExitCode::kUserBreak);
+ }
+ }
+ catch(const CNewException)
+ {
+ g_StdOut << kMemoryExceptionMessage;
+ return (NExitCode::kMemoryError);
+ }
+ catch(const CSystemException &e)
+ {
+ g_StdOut << "System Error: " << (UINT64)(e.ErrorCode);
+ return (NExitCode::kFatalError);
+ }
+ catch(NExitCode::EEnum &aExitCode)
+ {
+ g_StdOut << kInternalExceptionMessage << aExitCode << endl;
+ return (aExitCode);
+ }
+ catch(const NExitCode::CSystemError &systemError)
+ {
+ UString message;
+ NError::MyFormatMessage(systemError.ErrorValue, message);
+ g_StdOut << endl << endl << "System error:" << endl <<
+ message << endl;
+ return (NExitCode::kFatalError);
+ }
+ catch(const NExitCode::CMultipleErrors &multipleErrors)
+ {
+ g_StdOut << endl << multipleErrors.NumErrors << " errors" << endl;
+ return (NExitCode::kFatalError);
+ }
+ catch(const UString &s)
+ {
+ g_StdOut << kExceptionErrorMessage << s << endl;
+ return (NExitCode::kFatalError);
+ }
+ catch(const char *s)
+ {
+ g_StdOut << kExceptionErrorMessage << s << endl;
+ return (NExitCode::kFatalError);
+ }
+ catch(int t)
+ {
+ g_StdOut << kInternalExceptionMessage << t << endl;
+ return (NExitCode::kFatalError);
+ }
+ catch(...)
+ {
+ g_StdOut << kUnknownExceptionMessage;
+ return (NExitCode::kFatalError);
+ }
+ return result;
+}
diff --git a/7zip/UI/Console/OpenCallback.cpp b/7zip/UI/Console/OpenCallback.cpp
new file mode 100755
index 00000000..beefe38f
--- /dev/null
+++ b/7zip/UI/Console/OpenCallback.cpp
@@ -0,0 +1,92 @@
+// OpenCallback.cpp
+
+#include "StdAfx.h"
+
+#include "OpenCallback.h"
+
+#include "Common/StdOutStream.h"
+#include "Common/StdInStream.h"
+#include "Common/StringConvert.h"
+
+#include "../../Common/FileStreams.h"
+
+#include "Windows/PropVariant.h"
+
+#include "ConsoleClose.h"
+
+STDMETHODIMP COpenCallbackImp::SetTotal(const UINT64 *files, const UINT64 *bytes)
+{
+ if (NConsoleClose::TestBreakSignal())
+ return E_ABORT;
+ return S_OK;
+}
+
+STDMETHODIMP COpenCallbackImp::SetCompleted(const UINT64 *files, const UINT64 *bytes)
+{
+ if (NConsoleClose::TestBreakSignal())
+ return E_ABORT;
+ return S_OK;
+}
+
+STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
+{
+ NWindows::NCOM::CPropVariant propVariant;
+ 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 COpenCallbackImp::GetStream(const wchar_t *name,
+ IInStream **inStream)
+{
+ *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 COpenCallbackImp::CryptoGetTextPassword(BSTR *password)
+{
+ if (!PasswordIsDefined)
+ {
+ g_StdOut << "\nEnter password:";
+ AString oemPassword = g_StdIn.ScanStringUntilNewLine();
+ Password = MultiByteToUnicodeString(oemPassword, CP_OEMCP);
+ PasswordIsDefined = true;
+ }
+ CMyComBSTR temp(Password);
+ *password = temp.Detach();
+ return S_OK;
+}
+
diff --git a/7zip/UI/Console/OpenCallback.h b/7zip/UI/Console/OpenCallback.h
new file mode 100755
index 00000000..a0064414
--- /dev/null
+++ b/7zip/UI/Console/OpenCallback.h
@@ -0,0 +1,52 @@
+// OpenCallback.h
+
+#pragma once
+
+#ifndef __OPENCALLBACK_H
+#define __OPENCALLBACK_H
+
+#include "Common/String.h"
+#include "Common/MyCom.h"
+#include "Windows/FileFind.h"
+
+#include "../../Archive/IArchive.h"
+#include "../../IPassword.h"
+
+class COpenCallbackImp:
+ public IArchiveOpenCallback,
+ public IArchiveOpenVolumeCallback,
+ public ICryptoGetTextPassword,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP2(
+ IArchiveOpenVolumeCallback,
+ ICryptoGetTextPassword
+ )
+
+ 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);
+
+ // ICryptoGetTextPassword
+ STDMETHOD(CryptoGetTextPassword)(BSTR *password);
+
+private:
+ UString _folderPrefix;
+ NWindows::NFile::NFind::CFileInfoW _fileInfo;
+public:
+ bool PasswordIsDefined;
+ UString Password;
+ COpenCallbackImp(): PasswordIsDefined(false) {}
+ void LoadFileInfo(const UString &folderPrefix, const UString &fileName)
+ {
+ _folderPrefix = folderPrefix;
+ if (!NWindows::NFile::NFind::FindFile(_folderPrefix + fileName, _fileInfo))
+ throw 1;
+ }
+};
+
+#endif
diff --git a/7zip/UI/Console/PercentPrinter.cpp b/7zip/UI/Console/PercentPrinter.cpp
new file mode 100755
index 00000000..5e88ecbb
--- /dev/null
+++ b/7zip/UI/Console/PercentPrinter.cpp
@@ -0,0 +1,86 @@
+// PercentPrinter.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StdOutStream.h"
+#include "Common/IntToString.h"
+#include "Common/String.h"
+
+#include "PercentPrinter.h"
+
+static const char *kPrepareString = " ";
+static const char *kCloseString = "\b\b\b\b \b\b\b\b";
+// static const char *kPercentFormatString = "\b\b\b\b%3I64u%%";
+static const char *kPercentFormatString1 = "\b\b\b\b";
+static const int kNumDigits = 3;
+
+CPercentPrinter::CPercentPrinter(UINT64 minStepSize):
+ m_MinStepSize(minStepSize),
+ m_ScreenPos(0),
+ m_StringIsPrinted(false)
+{
+ for (int i = 0; i < kNumPercentSpaces; i++)
+ m_Spaces[i] = ' ';
+ m_Spaces[kNumPercentSpaces] = '\0';
+}
+
+void CPercentPrinter::PreparePrint()
+{
+ if (m_ScreenPos < kNumPercentSpaces)
+ g_StdOut << (m_Spaces + m_ScreenPos);
+ m_ScreenPos = kNumPercentSpaces;
+ g_StdOut << kPrepareString;
+}
+
+void CPercentPrinter::ClosePrint()
+{
+ g_StdOut << kCloseString;
+ m_StringIsPrinted = false;
+}
+
+void CPercentPrinter::PrintString(const char *s)
+{
+ m_ScreenPos += MyStringLen(s);
+ g_StdOut << s;
+}
+
+void CPercentPrinter::PrintString(const wchar_t *s)
+{
+ m_ScreenPos += MyStringLen(s);
+ g_StdOut << s;
+}
+
+void CPercentPrinter::PrintNewLine()
+{
+ m_ScreenPos = 0;
+ g_StdOut << "\n";
+ m_StringIsPrinted = false;
+}
+
+void CPercentPrinter::SetRatio(UINT64 doneValue)
+ { m_CurValue = doneValue; }
+
+void CPercentPrinter::RePrintRatio()
+{
+ if (m_Total == 0)
+ return;
+ UINT64 ratio = m_CurValue * 100 / m_Total;
+ // char temp[32];
+ // sprintf(temp, kPercentFormatString, ratio);
+ char temp[32 + kNumDigits] = " "; // for 4 digits;
+ ConvertUINT64ToString(ratio, temp + kNumDigits);
+ int len = lstrlenA(temp + kNumDigits);
+ lstrcatA(temp, "%");
+ int pos = (len > kNumDigits)? kNumDigits : len;
+ g_StdOut << kPercentFormatString1;
+ g_StdOut << (temp + pos);
+ m_PrevValue = m_CurValue;
+ m_StringIsPrinted = true;
+}
+
+void CPercentPrinter::PrintRatio()
+{
+ if (m_CurValue < m_PrevValue + m_MinStepSize || !m_StringIsPrinted)
+ return;
+ RePrintRatio();
+}
diff --git a/7zip/UI/Console/PercentPrinter.h b/7zip/UI/Console/PercentPrinter.h
new file mode 100755
index 00000000..15713fa9
--- /dev/null
+++ b/7zip/UI/Console/PercentPrinter.h
@@ -0,0 +1,38 @@
+// PercentPrinter.h
+
+#pragma once
+
+#ifndef __PERCENTPRINTER_H
+#define __PERCENTPRINTER_H
+
+#include "Common/Defs.h"
+
+const int kNumPercentSpaces = 70;
+class CPercentPrinter
+{
+ UINT64 m_MinStepSize;
+ UINT64 m_PrevValue;
+ UINT64 m_CurValue;
+ UINT64 m_Total;
+ UINT32 m_ScreenPos;
+ char m_Spaces[kNumPercentSpaces + 1];
+ bool m_StringIsPrinted;
+public:
+ CPercentPrinter(UINT64 minStepSize = 1);
+ void SetTotal(UINT64 total)
+ {
+ m_Total = total;
+ m_PrevValue = 0;
+ m_StringIsPrinted = false;
+ }
+ void PrintString(const char *s);
+ void PrintString(const wchar_t *s);
+ void PrintNewLine();
+ void PreparePrint();
+ void ClosePrint();
+ void SetRatio(UINT64 doneValue);
+ void RePrintRatio();
+ void PrintRatio();
+};
+
+#endif
diff --git a/7zip/UI/Console/StdAfx.cpp b/7zip/UI/Console/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/UI/Console/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/UI/Console/StdAfx.h b/7zip/UI/Console/StdAfx.h
new file mode 100755
index 00000000..f2d39704
--- /dev/null
+++ b/7zip/UI/Console/StdAfx.h
@@ -0,0 +1,16 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#ifdef WIN32
+#include <windows.h>
+#include <tchar.h>
+#endif
+
+#include <stdio.h>
+#include <time.h>
+
+#include <vector>
+
+#endif
diff --git a/7zip/UI/Console/TempFiles.cpp b/7zip/UI/Console/TempFiles.cpp
new file mode 100755
index 00000000..19793c08
--- /dev/null
+++ b/7zip/UI/Console/TempFiles.cpp
@@ -0,0 +1,39 @@
+// TempFiles.cpp
+
+#include "StdAfx.h"
+
+#include "TempFiles.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileIO.h"
+
+using namespace NWindows;
+using namespace NFile;
+
+void CFileVectorBundle::DisableDeleting(int index)
+{
+ m_FileNames.Delete(index);
+}
+
+bool CFileVectorBundle::Add(const UString &filePath, bool tryToOpen)
+{
+ if (tryToOpen)
+ {
+ NIO::COutFile file;
+ if (!file.Open(filePath))
+ return false;
+ }
+ m_FileNames.Add(filePath);
+ return true;
+}
+
+void CFileVectorBundle::Clear()
+{
+ while(!m_FileNames.IsEmpty())
+ {
+ NDirectory::DeleteFileAlways(m_FileNames.Back());
+ m_FileNames.DeleteBack();
+ }
+}
+
+
diff --git a/7zip/UI/Console/TempFiles.h b/7zip/UI/Console/TempFiles.h
new file mode 100755
index 00000000..b51276fd
--- /dev/null
+++ b/7zip/UI/Console/TempFiles.h
@@ -0,0 +1,20 @@
+// FileCreationUtils.h
+
+#pragma once
+
+#ifndef __FILECREATIONUTILS_H
+#define __FILECREATIONUTILS_H
+
+#include "Common/String.h"
+
+class CFileVectorBundle
+{
+ UStringVector m_FileNames;
+public:
+ ~CFileVectorBundle() { Clear(); }
+ bool Add(const UString &filePath, bool tryToOpen = true);
+ void DisableDeleting(int index);
+ void Clear();
+};
+
+#endif
diff --git a/7zip/UI/Console/Update.cpp b/7zip/UI/Console/Update.cpp
new file mode 100755
index 00000000..4831e005
--- /dev/null
+++ b/7zip/UI/Console/Update.cpp
@@ -0,0 +1,503 @@
+// Update.cpp
+
+#include "StdAfx.h"
+
+#include "Update.h"
+
+#include "Common/StdOutStream.h"
+#include "Common/StringConvert.h"
+#include "Common/MyCom.h"
+
+#include "Windows/Defs.h"
+#include "Windows/Error.h"
+#include "Windows/FileDir.h"
+#include "Windows/FileFind.h"
+#include "Windows/FileName.h"
+#include "Windows/PropVariant.h"
+#include "Windows/PropVariantConversions.h"
+#include "Windows/Error.h"
+
+#include "../../Common/FileStreams.h"
+#include "../../Compress/Copy/CopyCoder.h"
+
+#include "../Common/DirItem.h"
+#include "../Common/EnumDirItems.h"
+#include "../Common/UpdateProduce.h"
+
+#include "TempFiles.h"
+#include "ConsoleClose.h"
+#include "UpdateCallback.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 *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: ";
+
+using namespace NWindows;
+using namespace NCOM;
+using namespace NFile;
+using namespace NName;
+
+static wchar_t *kTempArchiveFilePrefixString = L"7zi";
+static const char *kEverythingIsOk = "Everything is Ok";
+
+static const char *kIllegalFileNameMessage = "Illegal file name for temp archive";
+
+using namespace NUpdateArchive;
+
+static bool ParseNumberString(const UString &srcString, UINT32 &number)
+{
+ wchar_t *anEndPtr;
+ number = wcstoul(srcString, &anEndPtr, 10);
+ return (anEndPtr - srcString == srcString.Length());
+}
+
+
+static HRESULT CopyBlock(ISequentialInStream *inStream, ISequentialOutStream *outStream)
+{
+ CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
+ return copyCoder->Code(inStream, outStream, NULL, NULL, NULL);
+}
+
+HRESULT Compress(
+ const CActionSet &actionSet,
+ IInArchive *archive,
+ const CCompressionMethodMode &compressionMethod,
+ const UString &archiveName,
+ const CObjectVector<CArchiveItem> &archiveItems,
+ const CObjectVector<CDirItem> &dirItems,
+ bool enablePercents,
+ bool sfxMode,
+ const UString &sfxModule)
+{
+ #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 "update operations are not supported for this archive";
+ }
+ }
+ else
+ {
+ #ifndef EXCLUDE_COM
+
+ HRESULT result = loader.CreateHandler(compressionMethod.FilePath,
+ compressionMethod.ClassID1, (void **)&outArchive, true);
+
+ if (result != S_OK)
+ {
+ throw "update operations are not supported for this archive";
+ return E_FAIL;
+ }
+ #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 "update operations are not supported for this archive";
+ return E_FAIL;
+ }
+ }
+
+ 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> operationChain;
+ UpdateProduce(dirItems, archiveItems, updatePairs, actionSet,
+ operationChain);
+
+ CUpdateCallbackImp *updateCallbackSpec = new CUpdateCallbackImp;
+ CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec );
+
+ updateCallbackSpec->Init(&dirItems, &archiveItems, &operationChain, enablePercents,
+ compressionMethod.PasswordIsDefined, compressionMethod.Password,
+ compressionMethod.AskPassword);
+
+ COutFileStream *outStreamSpec = new COutFileStream;
+ CMyComPtr<IOutStream> outStream(outStreamSpec);
+
+ {
+ UString resultPath;
+ int pos;
+ if(! NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos))
+ throw 141716;
+ NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos));
+ }
+ if (!outStreamSpec->Open(archiveName))
+ {
+ UString message;
+ NError::MyFormatMessage(::GetLastError(), message);
+ g_StdOut << message << endl;
+ return E_FAIL;
+ }
+
+ CMyComPtr<ISetProperties> setProperties;
+ if (outArchive.QueryInterface(IID_ISetProperties, &setProperties) == S_OK)
+ {
+ CObjectVector<CMyComBSTR> realNames;
+ std::vector<CPropVariant> values;
+ int i;
+ for(i = 0; i < compressionMethod.Properties.Size(); i++)
+ {
+ const CProperty &property = compressionMethod.Properties[i];
+ NCOM::CPropVariant propVariant;
+ UINT32 number;
+ if (!property.Value.IsEmpty())
+ {
+ if (ParseNumberString(property.Value, number))
+ propVariant = number;
+ else
+ propVariant = property.Value;
+ }
+ CMyComBSTR comBSTR(property.Name);
+ realNames.Add(comBSTR);
+ values.push_back(propVariant);
+ }
+ std::vector<BSTR> names;
+ for(i = 0; i < realNames.Size(); i++)
+ names.push_back(realNames[i]);
+
+ RINOK(setProperties->SetProperties(&names.front(),
+ &values.front(), names.size()));
+ }
+
+ if (sfxMode)
+ {
+ 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, operationChain.Size(),
+ updateCallback);
+}
+
+static void EnumerateDirItems(const NWildcard::CCensorNode &curNode,
+ const UString &directory,
+ const UString &prefix,
+ bool checkNameFull,
+ CObjectVector<CDirItem> &dirItems,
+ bool enterToSubFolders)
+{
+ NConsoleClose::CheckCtrlBreak();
+
+ NFind::CEnumeratorW enumerator(directory + wchar_t(kAnyStringWildcard));
+ NFind::CFileInfoW fileInfo;
+ while (enumerator.Next(fileInfo))
+ {
+ NConsoleClose::CheckCtrlBreak();
+ UString unicodeName = fileInfo.Name;
+ if (checkNameFull)
+ {
+ if (curNode.CheckNameFull(unicodeName))
+ AddDirFileInfo(prefix, directory + fileInfo.Name, fileInfo,
+ dirItems);
+ }
+ else
+ {
+ if (curNode.CheckNameRecursive(unicodeName))
+ AddDirFileInfo(prefix, directory + fileInfo.Name, fileInfo,
+ dirItems);
+ }
+ if (enterToSubFolders && fileInfo.IsDirectory())
+ {
+ const NWildcard::CCensorNode *nextNode = &curNode;
+ if (checkNameFull)
+ {
+ nextNode = ((NWildcard::CCensorNode *)&curNode)->FindSubNode(unicodeName);
+ if (nextNode == NULL)
+ nextNode = &curNode;
+ }
+ EnumerateDirItems(*nextNode,
+ directory + fileInfo.Name + wchar_t(kDirDelimiter),
+ prefix + unicodeName + wchar_t(kDirDelimiter),
+ nextNode != (&curNode), dirItems, true);
+ }
+ }
+}
+
+static void EnumerateItems(const NWildcard::CCensorNode &curNode,
+ const UString &directory,
+ const UString &prefix,
+ CObjectVector<CDirItem> &dirItems)
+{
+ NConsoleClose::CheckCtrlBreak();
+ if (!curNode.GetAllowedRecursedNamesVector(false).IsEmpty() ||
+ !curNode.GetAllowedRecursedNamesVector(true).IsEmpty())
+ {
+ EnumerateDirItems(curNode, directory, prefix, true, dirItems,
+ true);
+ return;
+ }
+ if (!curNode.GetAllowedNamesVector(false, true).IsEmpty())
+ {
+ EnumerateDirItems(curNode, directory, prefix, true, dirItems,
+ false);
+ }
+ else
+ {
+ const UStringVector &directNames = curNode.GetAllowedNamesVector(false, false);
+ for (int i = 0; i < directNames.Size(); i++)
+ {
+ const UString &nameSpec = directNames[i];
+ if (curNode.CheckName(nameSpec, false, false))
+ continue;
+
+ NFind::CFileInfoW fileInfo;
+ if (!NFind::FindFile(directory + nameSpec, fileInfo))
+ continue;
+
+ AddDirFileInfo(prefix, directory + fileInfo.Name, fileInfo, dirItems);
+ }
+ }
+ for (int i = 0; i < curNode.SubNodes.Size(); i++)
+ {
+ const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i];
+ EnumerateItems(nextNode,
+ directory + nextNode.Name + wchar_t(kDirDelimiter),
+ prefix + nextNode.Name + wchar_t(kDirDelimiter),
+ dirItems);
+ }
+}
+
+HRESULT GetFileTime(IInArchive *archive, UINT32 index,
+ FILETIME &fileTime, const FILETIME &defaultFileTime)
+{
+ CPropVariant property;
+ RINOK(archive->GetProperty(index, kpidLastWriteTime, &property));
+ if (property.vt == VT_FILETIME)
+ fileTime = property.filetime;
+ else if (property.vt == VT_EMPTY)
+ fileTime = defaultFileTime;
+ else
+ throw 4190407;
+ return S_OK;
+}
+
+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 archiveItem;
+ NCOM::CPropVariant propVariantPath;
+ RINOK(archive->GetProperty(i, kpidPath, &propVariantPath));
+ UString filePath;
+ if(propVariantPath.vt == VT_EMPTY)
+ archiveItem.Name = defaultItemName;
+ else
+ {
+ if(propVariantPath.vt != VT_BSTR)
+ return E_FAIL;
+ archiveItem.Name = propVariantPath.bstrVal;
+ }
+ archiveItem.Censored = censor.CheckName(archiveItem.Name);
+
+ RINOK(GetFileTime(archive, i, archiveItem.LastWriteTime,
+ archiveFileInfo.LastWriteTime));
+
+ CPropVariant propertySize;
+ RINOK(archive->GetProperty(i, kpidSize, &propertySize));
+ if (archiveItem.SizeIsDefined = (propertySize.vt != VT_EMPTY))
+ archiveItem.Size = ConvertPropVariantToUINT64(propertySize);
+
+ CPropVariant propertyIsFolder;
+ RINOK(archive->GetProperty(i, kpidIsFolder, &propertyIsFolder));
+ if(propertyIsFolder.vt != VT_BOOL)
+ return E_FAIL;
+ archiveItem.IsDirectory = VARIANT_BOOLToBool(propertyIsFolder.boolVal);
+
+ archiveItem.IndexInServer = i;
+ archiveItems.Add(archiveItem);
+ }
+ return S_OK;
+}
+
+
+static HRESULT UpdateWithItemLists(
+ const CUpdateArchiveOptions &options,
+ IInArchive *archive,
+ const CObjectVector<CArchiveItem> &archiveItems,
+ const CObjectVector<CDirItem> &dirItems,
+ bool enablePercents)
+{
+ for(int i = 0; i < options.Commands.Size(); i++)
+ {
+ const CUpdateArchiveCommand &command = options.Commands[i];
+ const UString &realArchivePath = command.ArchivePath;
+ if (i == 0 && options.UpdateArchiveItself)
+ {
+ if(archive != 0)
+ g_StdOut << kUpdatingArchiveMessage;
+ else
+ g_StdOut << kCreatingArchiveMessage;
+ g_StdOut << options.ArchivePath;
+ }
+ else
+ g_StdOut << kCreatingArchiveMessage << realArchivePath;
+
+ g_StdOut << endl << endl;
+
+ RINOK(Compress(command.ActionSet, archive,
+ options.MethodMode, realArchivePath,
+ archiveItems, dirItems, enablePercents,
+ options.SfxMode, options.SfxModule));
+
+ g_StdOut << endl;
+ }
+ return S_OK;
+}
+
+HRESULT UpdateArchiveStdMain(const NWildcard::CCensor &censor,
+ CUpdateArchiveOptions &options, const UString &workingDir,
+ IInArchive *archive,
+ const UString *defaultItemName,
+ const NWindows::NFile::NFind::CFileInfoW *archiveFileInfo,
+ bool enablePercents)
+{
+ CObjectVector<CDirItem> dirItems;
+ g_StdOut << kScanningMessage;
+ EnumerateItems(censor._head, L"", L"", dirItems);
+ g_StdOut << endl;
+
+ CFileVectorBundle fileVectorBundle;
+ if(options.UpdateArchiveItself)
+ {
+ if (!NDirectory::MyGetTempFileName(workingDir, kTempArchiveFilePrefixString,
+ options.Commands[0].ArchivePath))
+ throw "create temp file error";
+ }
+
+ int i;
+ for(i = 0; i < options.Commands.Size(); i++)
+ {
+ fileVectorBundle.Add(options.Commands[i].ArchivePath,
+ i > 0 || !options.UpdateArchiveItself);
+ // SetBanOnFile(censor,currentDir, options.Commands[i].ArchivePath);
+ }
+ g_StdOut << endl;
+
+ CObjectVector<CArchiveItem> archiveItems;
+ if (archive != NULL)
+ {
+ RINOK(EnumerateInArchiveItems(censor,
+ archive, *defaultItemName, *archiveFileInfo, archiveItems));
+ }
+
+ RINOK(UpdateWithItemLists(options, archive, archiveItems, dirItems, enablePercents));
+
+ if (archive != NULL)
+ {
+ RINOK(archive->Close());
+ }
+
+ int firstNotTempArchiveIndex = options.UpdateArchiveItself ? 1 : 0;
+ for(i = options.Commands.Size() - 1; i >= firstNotTempArchiveIndex; i--)
+ fileVectorBundle.DisableDeleting(i);
+ if(options.UpdateArchiveItself)
+ {
+ try
+ {
+ if (archive != NULL)
+ if (!NDirectory::DeleteFileAlways(options.ArchivePath))
+ throw "delete file error";
+
+ if (!NDirectory::MyMoveFile(options.Commands[0].ArchivePath, options.ArchivePath))
+ {
+ g_StdOut << endl << "Error: ";
+ g_StdOut << NError::MyFormatMessage(::GetLastError()) << endl;
+ g_StdOut << options.Commands[0].ArchivePath << endl;
+ g_StdOut << options.ArchivePath << endl;
+ throw "move file error";
+ }
+ }
+ catch(...)
+ {
+ fileVectorBundle.DisableDeleting(0);
+ throw;
+ }
+ }
+ g_StdOut << kEverythingIsOk << endl;
+ return S_OK;
+}
diff --git a/7zip/UI/Console/Update.h b/7zip/UI/Console/Update.h
new file mode 100755
index 00000000..3db55d9d
--- /dev/null
+++ b/7zip/UI/Console/Update.h
@@ -0,0 +1,41 @@
+// Update.h
+
+#pragma once
+
+#ifndef __UPDATE_H
+#define __UPDATE_H
+
+#include "Common/Wildcard.h"
+#include "../Common/UpdateAction.h"
+// #include "ProxyHandler.h"
+#include "Windows/FileFind.h"
+#include "../../Archive/IArchive.h"
+#include "CompressionMode.h"
+
+struct CUpdateArchiveCommand
+{
+ UString ArchivePath;
+ NUpdateArchive::CActionSet ActionSet;
+};
+
+struct CUpdateArchiveOptions
+{
+ CObjectVector<CUpdateArchiveCommand> Commands;
+ bool UpdateArchiveItself;
+
+ bool SfxMode;
+ UString SfxModule;
+
+ UString ArchivePath;
+ CCompressionMethodMode MethodMode;
+};
+
+
+HRESULT UpdateArchiveStdMain(const NWildcard::CCensor &censor,
+ CUpdateArchiveOptions &options, const UString &workingDir,
+ IInArchive *archive,
+ const UString *defaultItemName,
+ const NWindows::NFile::NFind::CFileInfoW *archiveFileInfo,
+ bool enablePercents);
+
+#endif
diff --git a/7zip/UI/Console/UpdateCallback.cpp b/7zip/UI/Console/UpdateCallback.cpp
new file mode 100755
index 00000000..744274db
--- /dev/null
+++ b/7zip/UI/Console/UpdateCallback.cpp
@@ -0,0 +1,259 @@
+// UpdateCallback.cpp
+
+#include "StdAfx.h"
+
+#include "UpdateCallback.h"
+
+#include "Common/StdInStream.h"
+#include "Common/StdOutStream.h"
+#include "Common/StringConvert.h"
+#include "Common/Defs.h"
+#include "Windows/PropVariant.h"
+
+#include "../../Common/FileStreams.h"
+// #include "Interface/EnumStatProp.h"
+
+#include "ConsoleClose.h"
+
+CUpdateCallbackImp::CUpdateCallbackImp():
+ m_PercentPrinter(1 << 16) {}
+
+void CUpdateCallbackImp::Init(
+ const CObjectVector<CDirItem> *dirItems,
+ const CObjectVector<CArchiveItem> *archiveItems, // test CItemInfoExList
+ CObjectVector<CUpdatePair2> *updatePairs,
+ bool enablePercents,
+ bool passwordIsDefined,
+ const UString &password,
+ bool askPassword)
+{
+ _passwordIsDefined = passwordIsDefined;
+ _password = password;
+ _askPassword = askPassword;
+
+ m_EnablePercents = enablePercents;
+ m_DirItems = dirItems;
+ m_ArchiveItems = archiveItems;
+ m_UpdatePairs = updatePairs;
+ m_PercentCanBePrint = false;
+ m_NeedBeClosed = false;
+}
+
+void CUpdateCallbackImp::Finilize()
+{
+ if (m_NeedBeClosed)
+ {
+ if (m_EnablePercents)
+ {
+ m_PercentPrinter.ClosePrint();
+ m_PercentCanBePrint = false;
+ m_NeedBeClosed = false;
+ }
+ m_PercentPrinter.PrintNewLine();
+ }
+}
+
+STDMETHODIMP CUpdateCallbackImp::SetTotal(UINT64 size)
+{
+ if (m_EnablePercents)
+ m_PercentPrinter.SetTotal(size);
+ return S_OK;
+}
+
+STDMETHODIMP CUpdateCallbackImp::SetCompleted(const UINT64 *completeValue)
+{
+ if (completeValue != NULL)
+ {
+ if (m_EnablePercents)
+ {
+ m_PercentPrinter.SetRatio(*completeValue);
+ if (m_PercentCanBePrint)
+ m_PercentPrinter.PrintRatio();
+ }
+ }
+
+ if (NConsoleClose::TestBreakSignal())
+ return E_ABORT;
+ return S_OK;
+}
+
+/*
+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 CUpdateCallbackImp::EnumProperties(IEnumSTATPROPSTG **enumerator)
+{
+ return E_NOTIMPL;
+
+ /*
+ return CStatPropEnumerator::CreateEnumerator(kProperties,
+ sizeof(kProperties) / sizeof(kProperties[0]), enumerator);
+ */
+}
+
+STDMETHODIMP CUpdateCallbackImp::GetUpdateItemInfo(UINT32 index,
+ INT32 *newData, INT32 *newProperties, UINT32 *indexInArchive)
+{
+ if (NConsoleClose::TestBreakSignal())
+ return E_ABORT;
+ const CUpdatePair2 &updatePair = (*m_UpdatePairs)[index];
+ if(newData != NULL)
+ *newData = BoolToInt(updatePair.NewData);
+ if(newProperties != NULL)
+ *newProperties = BoolToInt(updatePair.NewProperties);
+ if(indexInArchive != NULL)
+ {
+ if (updatePair.ExistInArchive)
+ *indexInArchive = (*m_ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer;
+ else
+ *indexInArchive = UINT32(-1);
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CUpdateCallbackImp::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
+{
+ const CUpdatePair2 &updatePair = (*m_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 =
+ (*m_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;
+ }
+ }
+ propVariant.Detach(value);
+ return S_OK;
+}
+
+STDMETHODIMP CUpdateCallbackImp::GetStream(UINT32 index,
+ IInStream **inStream)
+{
+ const CUpdatePair2 &updatePair = (*m_UpdatePairs)[index];
+ if(!updatePair.NewData)
+ return E_FAIL;
+
+ if (NConsoleClose::TestBreakSignal())
+ return E_ABORT;
+
+ Finilize();
+
+ if(updatePair.IsAnti)
+ {
+ m_PercentPrinter.PrintString("Anti item ");
+ m_PercentPrinter.PrintString(
+ (*m_ArchiveItems)[updatePair.ArchiveItemIndex].Name);
+ }
+ else
+ {
+ const CDirItem &dirItem =
+ (*m_DirItems)[updatePair.DirItemIndex];
+
+ m_PercentPrinter.PrintString("Compressing ");
+ m_PercentPrinter.PrintString(dirItem.Name);
+ }
+ if (m_EnablePercents)
+ {
+ m_PercentCanBePrint = true;
+ m_PercentPrinter.PreparePrint();
+ m_PercentPrinter.RePrintRatio();
+ }
+
+ if(updatePair.IsAnti)
+ return S_OK;
+
+ const CDirItem &dirItem =
+ (*m_DirItems)[updatePair.DirItemIndex];
+
+ if(dirItem.IsDirectory())
+ return S_OK;
+
+ CInFileStream *inStreamSpec = new CInFileStream;
+ CMyComPtr<IInStream> inStreamLoc(inStreamSpec);
+ if(!inStreamSpec->Open(dirItem.FullPath))
+ return ::GetLastError();
+ *inStream = inStreamLoc.Detach();
+ return S_OK;
+}
+
+STDMETHODIMP CUpdateCallbackImp::SetOperationResult(INT32 operationResult)
+{
+ m_NeedBeClosed = true;
+ return S_OK;
+}
+
+
+STDMETHODIMP CUpdateCallbackImp::CryptoGetTextPassword2(INT32 *passwordIsDefined, BSTR *password)
+{
+ if (!_passwordIsDefined)
+ {
+ if (_askPassword)
+ {
+ g_StdOut << "\nEnter password:";
+ AString oemPassword = g_StdIn.ScanStringUntilNewLine();
+ _password = MultiByteToUnicodeString(oemPassword, CP_OEMCP);
+ _passwordIsDefined = true;
+ }
+ }
+ *passwordIsDefined = BoolToInt(_passwordIsDefined);
+ CMyComBSTR tempName(_password);
+ *password = tempName.Detach();
+ return S_OK;
+}
diff --git a/7zip/UI/Console/UpdateCallback.h b/7zip/UI/Console/UpdateCallback.h
new file mode 100755
index 00000000..1bc6b10f
--- /dev/null
+++ b/7zip/UI/Console/UpdateCallback.h
@@ -0,0 +1,78 @@
+// UpdateCallback.h
+
+#pragma once
+
+#ifndef __UPDATECALLBACK_H
+#define __UPDATECALLBACK_H
+
+// #include "../Format/Common/ArchiveInterface.h"
+#include "Common/MyCom.h"
+#include "Common/String.h"
+
+#include "../../IPassword.h"
+
+#include "../Common/UpdatePair.h"
+#include "../Common/UpdateProduce.h"
+
+#include "PercentPrinter.h"
+
+class CUpdateCallbackImp:
+ public IArchiveUpdateCallback,
+ public ICryptoGetTextPassword2,
+ public CMyUnknownImp
+{
+public:
+ MY_UNKNOWN_IMP1(ICryptoGetTextPassword2)
+
+ // IProfress
+
+ 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, IInStream **inStream);
+
+ STDMETHOD(SetOperationResult)(INT32 operationResult);
+
+ STDMETHOD(CryptoGetTextPassword2)(INT32 *passwordIsDefined, BSTR *password);
+
+private:
+ const CObjectVector<CDirItem> *m_DirItems;
+ const CObjectVector<CArchiveItem> *m_ArchiveItems;
+ const CObjectVector<CUpdatePair2> *m_UpdatePairs;
+
+ CPercentPrinter m_PercentPrinter;
+
+ bool m_EnablePercents;
+ bool m_PercentCanBePrint;
+ bool m_NeedBeClosed;
+
+ bool _passwordIsDefined;
+ UString _password;
+ bool _askPassword;
+
+public:
+ CUpdateCallbackImp();
+ ~CUpdateCallbackImp()
+ { Finilize(); }
+ void Init(
+ const CObjectVector<CDirItem> *dirItems,
+ const CObjectVector<CArchiveItem> *archiveItems, // test CItemInfoExList
+ CObjectVector<CUpdatePair2> *updatePairs,
+ bool enablePercents,
+ bool passwordIsDefined,
+ const UString &password,
+ bool askPassword);
+ void Finilize();
+};
+
+
+
+
+#endif
diff --git a/7zip/UI/Console/UserInputUtils.cpp b/7zip/UI/Console/UserInputUtils.cpp
new file mode 100755
index 00000000..a32cd6f2
--- /dev/null
+++ b/7zip/UI/Console/UserInputUtils.cpp
@@ -0,0 +1,51 @@
+// UserInputUtils.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StdInStream.h"
+#include "Common/StdOutStream.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()
+{
+ g_StdOut << kFirstQuestionMessage;
+ do
+ {
+ g_StdOut << 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;
+ }
+ }
+ while(true);
+}
diff --git a/7zip/UI/Console/UserInputUtils.h b/7zip/UI/Console/UserInputUtils.h
new file mode 100755
index 00000000..dabd27ac
--- /dev/null
+++ b/7zip/UI/Console/UserInputUtils.h
@@ -0,0 +1,23 @@
+// UserInputUtils.h
+
+#pragma once
+
+#ifndef __USERINPUTUTILS_H
+#define __USERINPUTUTILS_H
+
+namespace NUserAnswerMode {
+
+enum EEnum
+{
+ kYes,
+ kNo,
+ kYesAll,
+ kNoAll,
+ kAutoRename,
+ kQuit,
+};
+}
+
+NUserAnswerMode::EEnum ScanUserYesNoAllQuit();
+
+#endif
diff --git a/7zip/UI/Console/afxres.h b/7zip/UI/Console/afxres.h
new file mode 100755
index 00000000..c2fadd4a
--- /dev/null
+++ b/7zip/UI/Console/afxres.h
@@ -0,0 +1 @@
+#include <winresrc.h>
diff --git a/7zip/UI/Console/resource.h b/7zip/UI/Console/resource.h
new file mode 100755
index 00000000..612062a2
--- /dev/null
+++ b/7zip/UI/Console/resource.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/UI/Console/resource.rc b/7zip/UI/Console/resource.rc
new file mode 100755
index 00000000..9670d79e
--- /dev/null
+++ b/7zip/UI/Console/resource.rc
@@ -0,0 +1,121 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,12,0,0
+ PRODUCTVERSION 3,12,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "7-Zip Console version\0"
+ VALUE "FileVersion", "3, 12, 0, 0\0"
+ VALUE "InternalName", "7z\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "7z.exe\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 12, 0, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/UI/Explorer/7-zip.dll.manifest b/7zip/UI/Explorer/7-zip.dll.manifest
new file mode 100755
index 00000000..d7dce9dc
--- /dev/null
+++ b/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="X86" 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="X86" publicKeyToken="6595b64144ccf1df" language="*"/></dependentAssembly></dependency></assembly>
diff --git a/7zip/UI/Explorer/ContextMenu.cpp b/7zip/UI/Explorer/ContextMenu.cpp
new file mode 100755
index 00000000..53071716
--- /dev/null
+++ b/7zip/UI/Explorer/ContextMenu.cpp
@@ -0,0 +1,686 @@
+// 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/System.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
+
+HRESULT CZipContextMenu::GetFileNames(LPDATAOBJECT dataObject,
+ CSysStringVector &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)
+{
+ /*
+ m_IsFolder = false;
+ if (pidlFolder == 0)
+ */
+ // pidlFolder is NULL :(
+ CSysStringVector sysFileNames;
+ RINOK(GetFileNames(dataObject, sysFileNames));
+ _fileNames.Clear();
+ _fileNames.Reserve(sysFileNames.Size());
+ for (int i = 0; i < sysFileNames.Size(); i++)
+ _fileNames.Add(GetUnicodeString(sysFileNames[i]));
+ return S_OK;
+}
+
+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]);
+ 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::kCompressTo,
+ CZipContextMenu::kCompressTo,
+ L"CompressTo",
+ IDS_CONTEXT_COMPRESS_TO,
+ IDS_CONTEXT_COMPRESS_TO_HELP,
+ 0x0200010F
+ },
+ {
+ NContextMenuFlags::kCompressEmail,
+ CZipContextMenu::kCompressEmail,
+ L"CompressEmail",
+ IDS_CONTEXT_COMPRESS_EMAIL,
+ IDS_CONTEXT_COMPRESS_EMAIL_HELP,
+ 0x02000111
+ },
+ {
+ NContextMenuFlags::kCompressToEmail,
+ CZipContextMenu::kCompressToEmail,
+ L"CompressToEmail",
+ 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 = command.Verb;
+ commandMapItem.HelpString = LangLoadStringW(command.ResourceHelpID, command.LangID + 1);
+ mainString = LangLoadStringW(command.ResourceID, command.LangID);
+}
+
+void CZipContextMenu::FillCommand2(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 = command.Verb;
+ commandMapItem.HelpString = LangLoadStringW(command.ResourceHelpID, command.LangID + 1);
+ mainString = LangLoadStringW(command.ResourceID, command.LangID);
+}
+
+
+/*
+CSysString GetExtractPath(const CSysString &archiveName)
+{
+ CSysString s;
+ int dotPos = s.ReverseFind('.');
+ if (dotPos < 0)
+ return archiveName;
+ return archiveName.Left(dotPos);
+}
+*/
+
+static BOOL MyInsertMenu(HMENU hMenu, int pos, UINT id, LPCTSTR s)
+{
+ MENUITEMINFO menuItem;
+ menuItem.cbSize = sizeof(menuItem);
+ menuItem.fType = MFT_STRING;
+ menuItem.fMask = MIIM_TYPE | MIIM_ID;
+ menuItem.wID = id;
+ menuItem.dwTypeData = (LPTSTR)(LPCTSTR)s;
+ return ::InsertMenuItem(hMenu, pos++, TRUE, &menuItem);
+}
+
+static UString GetSubFolderNameForExtract(const UString &archiveName)
+{
+ int dotPos = archiveName.ReverseFind('.');
+ if (dotPos >= 0)
+ return archiveName.Left(dotPos);
+ return archiveName + UString(L"~");
+}
+
+STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
+ UINT commandIDFirst, UINT commandIDLast, UINT flags)
+{
+ 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 = LangLoadStringW(IDS_CONTEXT_CAPTION_HELP, 0x02000102);
+ _commandMap.push_back(commandMapItem);
+
+ menuItem.wID = currentCommandID++;
+ subIndex = 0;
+ }
+ else
+ {
+ popupMenu.Attach(hMenu);
+ }
+
+ UINT32 contextMenuFlags;
+ if (!ReadContextMenuStatus(contextMenuFlags))
+ contextMenuFlags = NContextMenuFlags::GetDefaultFlags();
+
+ int subMenuIndex = 0;
+ 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++, GetSystemString(mainString));
+ _commandMap.push_back(commandMapItem);
+ }
+
+ // Extract
+ if ((contextMenuFlags & NContextMenuFlags::kExtract) != 0)
+ {
+ CCommandMapItem commandMapItem;
+ FillCommand(kExtract, mainString, commandMapItem);
+ commandMapItem.Folder = folderPrefix +
+ GetSubFolderNameForExtract(fileInfo.Name) +
+ UString(L'\\');
+ MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(mainString));
+ _commandMap.push_back(commandMapItem);
+ }
+
+ // Extract Here
+ if ((contextMenuFlags & NContextMenuFlags::kExtractHere) != 0)
+ {
+ CCommandMapItem commandMapItem;
+ FillCommand(kExtractHere, mainString, commandMapItem);
+ MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(mainString));
+ commandMapItem.Folder = folderPrefix;
+ _commandMap.push_back(commandMapItem);
+ }
+
+ // Extract To
+ if ((contextMenuFlags & NContextMenuFlags::kExtractTo) != 0)
+ {
+ CCommandMapItem commandMapItem;
+ UString s;
+ FillCommand2(kExtractTo, s, commandMapItem);
+ UString folder = GetSubFolderNameForExtract(fileInfo.Name) +
+ UString(L'\\');
+ commandMapItem.Folder = folderPrefix + folder;
+ s = MyFormatNew(s, folder);
+ MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(s));
+ _commandMap.push_back(commandMapItem);
+ }
+
+ // Test
+ if ((contextMenuFlags & NContextMenuFlags::kTest) != 0)
+ {
+ CCommandMapItem commandMapItem;
+ FillCommand(kTest, mainString, commandMapItem);
+ MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(mainString));
+ _commandMap.push_back(commandMapItem);
+ }
+ }
+ }
+
+ if(_fileNames.Size() > 0 && currentCommandID + 6 <= commandIDLast)
+ {
+ const UString &fileName = _fileNames.Front();
+ UString archiveName = CreateArchiveName(fileName, _fileNames.Size() > 1, false);
+ UString archiveName7z = archiveName + L".7z";
+ UString archivePathPrefix;
+ NFile::NDirectory::GetOnlyDirPrefix(fileName, archivePathPrefix);
+
+ // Compress
+ if ((contextMenuFlags & NContextMenuFlags::kCompress) != 0)
+ {
+ CCommandMapItem commandMapItem;
+ commandMapItem.Archive = archivePathPrefix + archiveName;
+ FillCommand(kCompress, mainString, commandMapItem);
+ MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(mainString));
+ _commandMap.push_back(commandMapItem);
+ }
+
+
+ // CompressTo
+ if (contextMenuFlags & NContextMenuFlags::kCompressTo)
+ {
+ CCommandMapItem commandMapItem;
+ UString s;
+ FillCommand2(kCompressTo, s, commandMapItem);
+ commandMapItem.Archive = archivePathPrefix + archiveName7z;
+ UString t = UString(L"\"") + archiveName7z + UString(L"\"");
+ s = MyFormatNew(s, t);
+ MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(s));
+ _commandMap.push_back(commandMapItem);
+ }
+
+ // CompressEmail
+ if ((contextMenuFlags & NContextMenuFlags::kCompressEmail) != 0)
+ {
+ CCommandMapItem commandMapItem;
+ commandMapItem.Archive = archiveName;
+ FillCommand(kCompressEmail, mainString, commandMapItem);
+ MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(mainString));
+ _commandMap.push_back(commandMapItem);
+ }
+
+ // CompressToEmail
+ if ((contextMenuFlags & NContextMenuFlags::kCompressToEmail) != 0)
+ {
+ CCommandMapItem commandMapItem;
+ UString s;
+ FillCommand2(kCompressToEmail, s, commandMapItem);
+ commandMapItem.Archive = archiveName7z;
+ UString t = UString(L"\"") + archiveName7z + UString(L"\"");
+ s = MyFormatNew(s, t);
+ MyInsertMenu(popupMenu, subIndex++, currentCommandID++, GetSystemString(s));
+ _commandMap.push_back(commandMapItem);
+ }
+ }
+
+
+ CSysString popupMenuCaption = LangLoadString(IDS_CONTEXT_POPUP_CAPTION, 0x02000101);
+
+ // don't use InsertMenu: See MSDN:
+ // PRB: Duplicate Menu Items In the File Menu For a Shell Context Menu Extension
+ // ID: Q214477
+
+ if (cascadedMenu)
+ {
+ MENUITEMINFO menuItem;
+ menuItem.cbSize = sizeof(menuItem);
+ menuItem.fType = MFT_STRING;
+ menuItem.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID;
+ menuItem.wID = currentCommandID++;
+ menuItem.hSubMenu = popupMenu.Detach();
+ menuDestroyer.Disable();
+ menuItem.dwTypeData = (LPTSTR)(LPCTSTR)popupMenuCaption;
+ ::InsertMenuItem(hMenu, indexMenu++, TRUE, &menuItem);
+ }
+
+ return MAKE_HRESULT(SEVERITY_SUCCESS, 0, currentCommandID - commandIDFirst);
+}
+
+
+UINT 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;
+
+/*
+class CWindowDisable
+{
+ bool m_WasEnabled;
+ CWindow m_Window;
+public:
+ CWindowDisable(HWND aWindow): m_Window(aWindow)
+ {
+ m_WasEnabled = m_Window.IsEnabled();
+ if (m_WasEnabled)
+ m_Window.Enable(false);
+ }
+ ~CWindowDisable()
+ {
+ if (m_WasEnabled)
+ m_Window.Enable(true);
+ }
+};
+*/
+
+/*
+struct CThreadCompressMain
+{
+ CSysStringVector FileNames;
+
+ DWORD Process()
+ {
+ NCOM::CComInitializer comInitializer;
+ try
+ {
+ HRESULT result = CompressArchive(FileNames);
+ }
+ catch(...)
+ {
+ MyMessageBox(IDS_ERROR, 0x02000605);
+ }
+ return 0;
+ }
+
+ static DWORD WINAPI MyThreadFunction(void *param)
+ {
+ CThreadCompressMain *compressor = (CThreadCompressMain *)param;
+ return ((CThreadCompressMain *)param)->Process();
+ delete compressor;
+ }
+};
+*/
+
+static bool IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+
+static UString GetProgramCommand()
+{
+ UString path = L"\"";
+ UString folder;
+ if (GetProgramFolderPath(folder))
+ path += folder;
+ if (IsItWindowsNT())
+ path += L"7zFMn.exe";
+ else
+ path += L"7zFM.exe";
+ path += L"\"";
+ return path;
+}
+
+STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
+{
+ int commandOffset;
+
+ if(HIWORD(commandInfo->lpVerb) == 0)
+ commandOffset = LOWORD(commandInfo->lpVerb);
+ else
+ commandOffset = FindVerb(GetUnicodeString(commandInfo->lpVerb));
+ /*
+ #ifdef _UNICODE
+ if(commandInfo->cbSize == sizeof(CMINVOKECOMMANDINFOEX))
+ {
+ if ((commandInfo->fMask & CMIC_MASK_UNICODE) != 0)
+ {
+ LPCMINVOKECOMMANDINFOEX aCommandInfoEx = (LPCMINVOKECOMMANDINFOEX)commandInfo;
+ if(HIWORD(aCommandInfoEx->lpVerb) == 0)
+ commandOffset = LOWORD(aCommandInfoEx->lpVerb);
+ else
+ {
+ MessageBox(0, TEXT("1"), TEXT("1"), 0);
+ return E_FAIL;
+ }
+ }
+ else
+ {
+ if(HIWORD(commandInfo->lpVerb) == 0)
+ commandOffset = LOWORD(commandInfo->lpVerb);
+ else
+ commandOffset = FindVerb(GetSystemString(commandInfo->lpVerb));
+ }
+ // return E_FAIL;
+ }
+ else
+ {
+ if(HIWORD(commandInfo->lpVerb) == 0)
+ commandOffset = LOWORD(commandInfo->lpVerb);
+ else
+ commandOffset = FindVerb(GetSystemString(commandInfo->lpVerb));
+ }
+
+ #else
+
+ {
+ if(HIWORD(commandInfo->lpVerb) == 0)
+ commandOffset = LOWORD(commandInfo->lpVerb);
+ else
+ commandOffset = FindVerb(commandInfo->lpVerb);
+ }
+
+ #endif
+ */
+
+ if(commandOffset < 0 || commandOffset >= _commandMap.size())
+ return E_FAIL;
+
+ const CCommandMapItem commandMapItem = _commandMap[commandOffset];
+ ECommandInternalID commandInternalID = commandMapItem.CommandInternalID;
+ HWND aHWND = commandInfo->hwnd;
+
+ // CWindowDisable aWindowDisable(aHWND);
+
+ try
+ {
+ switch(commandInternalID)
+ {
+ case kOpen:
+ {
+ UString params;
+ params = GetProgramCommand();
+ params += L" \"";
+ params += _fileNames[0];
+ params += L"\"";
+ MyCreateProcess(params);
+ break;
+ }
+ case kExtract:
+ case kExtractHere:
+ case kExtractTo:
+ {
+ ExtractArchive(_fileNames[0], commandMapItem.Folder,
+ (commandInternalID == kExtract));
+ break;
+ }
+ case kTest:
+ {
+ TestArchive(_fileNames[0]);
+ break;
+ }
+ case kCompress:
+ case kCompressTo:
+ case kCompressEmail:
+ case kCompressToEmail:
+ {
+ bool email = (commandInternalID == kCompressEmail) ||
+ (commandInternalID == kCompressToEmail);
+ bool showDialog = (commandInternalID == kCompress) ||
+ (commandInternalID == kCompressEmail);
+ CompressFiles(commandMapItem.Archive, _fileNames, email, showDialog);
+ break;
+ }
+ }
+ }
+ catch(...)
+ {
+ MyMessageBox(IDS_ERROR, 0x02000605);
+ }
+ return S_OK;
+}
+
+static void MyCopyString(void *dest, const wchar_t *src, bool writeInUnicode)
+{
+ if(writeInUnicode)
+ {
+ wcscpy((wchar_t *)dest, src);
+ }
+ else
+ lstrcpyA((char *)dest, GetAnsiString(src));
+}
+
+STDMETHODIMP CZipContextMenu::GetCommandString(UINT commandOffset, UINT uType,
+ UINT *pwReserved, LPSTR pszName, UINT cchMax)
+{
+ switch(uType)
+ {
+ case GCS_VALIDATEA:
+ case GCS_VALIDATEW:
+ if(commandOffset < 0 || commandOffset >= (UINT)_commandMap.size())
+ return S_FALSE;
+ else
+ return S_OK;
+ }
+ if(commandOffset < 0 || commandOffset >= (UINT)_commandMap.size())
+ return E_FAIL;
+ if(uType == GCS_HELPTEXTA || uType == GCS_HELPTEXTW)
+ {
+ MyCopyString(pszName, _commandMap[commandOffset].HelpString,
+ uType == GCS_HELPTEXTW);
+ return NO_ERROR;
+ }
+ if(uType == GCS_VERBA || uType == GCS_VERBW)
+ {
+ MyCopyString(pszName, _commandMap[commandOffset].Verb,
+ uType == GCS_VERBW);
+ return NO_ERROR;
+ }
+ return E_FAIL;
+}
diff --git a/7zip/UI/Explorer/ContextMenu.h b/7zip/UI/Explorer/ContextMenu.h
new file mode 100755
index 00000000..2dec9c80
--- /dev/null
+++ b/7zip/UI/Explorer/ContextMenu.h
@@ -0,0 +1,92 @@
+// ContextMenu.h
+
+#pragma once
+
+#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"
+
+class CZipContextMenu:
+ public IContextMenu,
+ public IShellExtInit,
+ public IInitContextMenu,
+ public CComObjectRoot,
+ public CComCoClass<CZipContextMenu, &CLSID_CZipContextMenu>
+{
+
+public:
+
+ enum ECommandInternalID
+ {
+ kCommandNULL,
+ kOpen,
+ kExtract,
+ kExtractHere,
+ kExtractTo,
+ kTest,
+ kCompress,
+ kCompressTo,
+ kCompressEmail,
+ kCompressToEmail
+ };
+
+ struct CCommandMapItem
+ {
+ ECommandInternalID CommandInternalID;
+ UString Verb;
+ UString HelpString;
+ UString Folder;
+ UString Archive;
+ };
+
+BEGIN_COM_MAP(CZipContextMenu)
+ COM_INTERFACE_ENTRY(IContextMenu)
+ COM_INTERFACE_ENTRY(IShellExtInit)
+ COM_INTERFACE_ENTRY(IInitContextMenu)
+END_COM_MAP()
+
+DECLARE_NOT_AGGREGATABLE(CZipContextMenu)
+
+DECLARE_REGISTRY(CZipContextMenu,
+ // _T("SevenZip.ContextMenu.1"), _T("SevenZip.ContextMenu"),
+ TEXT("SevenZip.1"), TEXT("SevenZip"),
+ UINT(0), THREADFLAGS_APARTMENT)
+
+ ///////////////////////////////
+ // 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 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;
+ std::vector<CCommandMapItem> _commandMap;
+ HRESULT GetFileNames(LPDATAOBJECT dataObject, CSysStringVector &fileNames);
+ UINT FindVerb(const UString &verb);
+
+ void FillCommand(ECommandInternalID id, UString &mainString,
+ CCommandMapItem &commandMapItem);
+ void FillCommand2(ECommandInternalID id, UString &mainString,
+ CCommandMapItem &commandMapItem);
+};
+
+#endif \ No newline at end of file
diff --git a/7zip/UI/Explorer/ContextMenuFlags.h b/7zip/UI/Explorer/ContextMenuFlags.h
new file mode 100755
index 00000000..3e3bb5f3
--- /dev/null
+++ b/7zip/UI/Explorer/ContextMenuFlags.h
@@ -0,0 +1,28 @@
+// ContextMenuFlags.h
+
+#pragma once
+
+#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 kCompressTo = 1 << 9;
+ const UINT32 kCompressEmail = 1 << 10;
+ const UINT32 kCompressToEmail = 1 << 11;
+
+ inline UINT32 GetDefaultFlags() {
+ return kOpen | kExtract | kExtractHere | kCompress | kTest; }
+}
+
+#endif
diff --git a/7zip/UI/Explorer/DllExports.cpp b/7zip/UI/Explorer/DllExports.cpp
new file mode 100755
index 00000000..88f0ea58
--- /dev/null
+++ b/7zip/UI/Explorer/DllExports.cpp
@@ -0,0 +1,152 @@
+// DLLExports.cpp : Implementation of DLL Exports.
+
+#include "StdAfx.h"
+
+// #include <locale.h>
+
+#include <initguid.h>
+#include <ShlGuid.h>
+#include <windows.h>
+
+// #include "../../Compress/Interface/CompressInterface.h"
+#include "../../IPassword.h"
+#include "../Agent/Agent.h"
+#include "Common/ComTry.h"
+
+#include "ContextMenu.h"
+
+#include "OptionsDialog.h"
+
+CComModule _Module;
+
+BEGIN_OBJECT_MAP(ObjectMap)
+ // OBJECT_ENTRY(CLSID_CAgentArchiveHandler, CAgent)
+ OBJECT_ENTRY(CLSID_CZipContextMenu, CZipContextMenu)
+ // OBJECT_ENTRY(CLSID_CSevenZipOptions, CSevenZipOptions)
+END_OBJECT_MAP()
+
+
+/////////////////////////////////////////////////////////////////////////////
+// DLL Entry Point
+
+HINSTANCE g_hInstance;
+
+static bool IsItWindowsNT()
+{
+ OSVERSIONINFO aVersionInfo;
+ aVersionInfo.dwOSVersionInfoSize = sizeof(aVersionInfo);
+ if (!::GetVersionEx(&aVersionInfo))
+ return false;
+ return (aVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID)
+{
+ // setlocale(LC_COLLATE, ".ACP");
+ g_hInstance = hInstance;
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ #ifdef UNICODE
+ if (!IsItWindowsNT())
+ return FALSE;
+ #endif
+ _Module.Init(ObjectMap, hInstance);
+ //DisableThreadLibraryCalls(hInstance);
+ }
+ else if (dwReason == DLL_PROCESS_DETACH)
+ _Module.Term();
+ return TRUE; // ok
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Used to determine whether the DLL can be unloaded by OLE
+
+STDAPI DllCanUnloadNow(void)
+{
+ return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Returns a class factory to create an object of the requested type
+
+STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
+{
+ return _Module.GetClassObject(rclsid, riid, ppv);
+}
+
+STDAPI DllRegisterServer(void)
+{
+ return _Module.RegisterServer(FALSE);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// DllUnregisterServer - Removes entries from the system registry
+
+STDAPI DllUnregisterServer(void)
+{
+ return _Module.UnregisterServer();
+}
+
+STDAPI CreateObject(
+ const GUID *classID,
+ const GUID *interfaceID,
+ void **outObject)
+{
+ 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/7zip/UI/Explorer/Explorer.def b/7zip/UI/Explorer/Explorer.def
new file mode 100755
index 00000000..a182208b
--- /dev/null
+++ b/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/7zip/UI/Explorer/Explorer.dsp b/7zip/UI/Explorer/Explorer.dsp
new file mode 100755
index 00000000..f1c274bf
--- /dev/null
+++ b/7zip/UI/Explorer/Explorer.dsp
@@ -0,0 +1,807 @@
+# 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-Zipn.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\ArchiveName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiveName.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\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
+# Begin Source File
+
+SOURCE=..\Common\ZipSettings.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\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\SystemPage\resource.rc
+# PROP Exclude_From_Build 1
+# End Source File
+# 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
+# Begin Source File
+
+SOURCE=.\FoldersPage\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\FoldersPage\resource.rc
+# PROP Exclude_From_Build 1
+# 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\ArchiveExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\ArchiveExtractCallback.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\ArchiveUpdateCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\ArchiveUpdateCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\IFolderArchive.h
+# End Source File
+# End Group
+# Begin Group "Spec Interfaces"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Format\Common\ArchiveInterface.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\ArchiveStyleDirItemInfo.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Interface\CompressInterface.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\FolderArchiveInterface.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Format\Common\FormatCryptoInterface.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\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\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.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileMapping.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\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\System.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\System.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
+# 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=".\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/7zip/UI/Explorer/Explorer.dsw b/7zip/UI/Explorer/Explorer.dsw
new file mode 100755
index 00000000..beb8df7b
--- /dev/null
+++ b/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/7zip/UI/Explorer/FoldersPage/FoldersPage.cpp b/7zip/UI/Explorer/FoldersPage/FoldersPage.cpp
new file mode 100755
index 00000000..dc99b979
--- /dev/null
+++ b/7zip/UI/Explorer/FoldersPage/FoldersPage.cpp
@@ -0,0 +1,161 @@
+// FoldersDialog.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]));
+ // CZipRegistryManager aRegistryManager;
+ 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 anEnablePath = (GetWorkMode() == NWorkDir::NMode::kSpecified);
+ m_WorkPath.Enable(anEnablePath);
+ m_ButtonSetWorkPath.Enable(anEnablePath);
+}
+
+void CFoldersPage::GetWorkDir(NWorkDir::CInfo &aWorkDirInfo)
+{
+ m_WorkPath.GetText(aWorkDirInfo.Path);
+ aWorkDirInfo.ForRemovableOnly = IsButtonCheckedBool(IDC_FOLDERS_WORK_CHECK_FOR_REMOVABLE);
+ aWorkDirInfo.Mode = NWorkDir::NMode::EEnum(GetWorkMode());
+}
+
+/*
+bool CFoldersPage::WasChanged()
+{
+ NWorkDir::CInfo aWorkDirInfo;
+ GetWorkDir(aWorkDirInfo);
+ return (aWorkDirInfo.Mode != m_WorkDirInfo.Mode ||
+ aWorkDirInfo.ForRemovableOnly != m_WorkDirInfo.ForRemovableOnly ||
+ aWorkDirInfo.Path.Compare(m_WorkDirInfo.Path) != 0);
+}
+*/
+
+void CFoldersPage::ModifiedEvent()
+{
+ Changed();
+ /*
+ if (WasChanged())
+ Changed();
+ else
+ UnChanged();
+ */
+}
+
+bool CFoldersPage::OnButtonClicked(int aButtonID, HWND aButtonHWND)
+{
+ for (int i = 0; i < kNumWorkModeButtons; i++)
+ if (aButtonID == kWorkModeButtons[i])
+ {
+ MyEnableControls();
+ ModifiedEvent();
+ return true;
+ }
+ switch(aButtonID)
+ {
+ case IDC_FOLDERS_WORK_BUTTON_PATH:
+ OnFoldersWorkButtonPath();
+ break;
+ case IDC_FOLDERS_WORK_CHECK_FOR_REMOVABLE:
+ break;
+ default:
+ return CPropertyPage::OnButtonClicked(aButtonID, aButtonHWND);
+ }
+ ModifiedEvent();
+ return true;
+}
+
+bool CFoldersPage::OnCommand(int aCode, int anItemID, LPARAM lParam)
+{
+ if (aCode == EN_CHANGE && anItemID == IDC_FOLDERS_WORK_EDIT_PATH)
+ {
+ ModifiedEvent();
+ return true;
+ }
+ return CPropertyPage::OnCommand(aCode, anItemID, lParam);
+}
+
+void CFoldersPage::OnFoldersWorkButtonPath()
+{
+ CSysString currentPath;
+ m_WorkPath.GetText(currentPath);
+
+ UString title = LangLoadStringW(IDS_FOLDERS_SET_WORK_PATH_TITLE, 0x01000281);
+
+ CSysString resultPath;
+ if (NShell::BrowseForFolder(HWND(*this), GetSystemString(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/7zip/UI/Explorer/FoldersPage/FoldersPage.h b/7zip/UI/Explorer/FoldersPage/FoldersPage.h
new file mode 100755
index 00000000..66e899b5
--- /dev/null
+++ b/7zip/UI/Explorer/FoldersPage/FoldersPage.h
@@ -0,0 +1,33 @@
+// FoldersPage.h
+
+#pragma once
+
+#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;
+ // int m_RadioWorkMode;
+ void OnFoldersWorkButtonPath();
+ int GetWorkMode() const;
+ void GetWorkDir(NWorkDir::CInfo &aWorkDirInfo);
+ // bool WasChanged();
+public:
+ virtual bool OnInit();
+ virtual bool OnCommand(int aCode, int anItemID, LPARAM lParam);
+ virtual void OnNotifyHelp();
+ virtual LONG OnApply();
+ virtual bool OnButtonClicked(int aButtonID, HWND aButtonHWND);
+};
+
+#endif
diff --git a/7zip/UI/Explorer/FoldersPage/resource.h b/7zip/UI/Explorer/FoldersPage/resource.h
new file mode 100755
index 00000000..f413a54d
--- /dev/null
+++ b/7zip/UI/Explorer/FoldersPage/resource.h
@@ -0,0 +1,27 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDD_FOLDERS 900
+
+#define IDS_FOLDERS_SET_WORK_PATH_TITLE 103
+
+#define IDC_FOLDERS_WORK_RADIO_SYSTEM 1002
+#define IDC_FOLDERS_WORK_EDIT_PATH 1003
+#define IDC_FOLDERS_WORK_BUTTON_PATH 1004
+#define IDC_FOLDERS_WORK_RADIO_CURRENT 1005
+#define IDC_FOLDERS_WORK_RADIO_SPECIFIED 1006
+#define IDC_FOLDERS_WORK_CHECK_FOR_REMOVABLE 1007
+
+#define IDC_FOLDERS_STATIC_WORKING_FOLDER 1019
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 135
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1020
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/UI/Explorer/FoldersPage/resource.rc b/7zip/UI/Explorer/FoldersPage/resource.rc
new file mode 100755
index 00000000..f883e0d6
--- /dev/null
+++ b/7zip/UI/Explorer/FoldersPage/resource.rc
@@ -0,0 +1,109 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_FOLDERS DIALOG DISCARDABLE 0, 0, 210, 154
+STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Folders"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ GROUPBOX "&Working folder",IDC_FOLDERS_STATIC_WORKING_FOLDER,7,7,
+ 196,98
+ CONTROL "&System temp folder",IDC_FOLDERS_WORK_RADIO_SYSTEM,
+ "Button",BS_AUTORADIOBUTTON | WS_GROUP,19,20,150,10
+ CONTROL "&Current",IDC_FOLDERS_WORK_RADIO_CURRENT,"Button",
+ BS_AUTORADIOBUTTON,19,34,150,10
+ CONTROL "Specified:",IDC_FOLDERS_WORK_RADIO_SPECIFIED,"Button",
+ BS_AUTORADIOBUTTON,19,48,151,10
+ EDITTEXT IDC_FOLDERS_WORK_EDIT_PATH,39,63,130,14,ES_AUTOHSCROLL
+ PUSHBUTTON "...",IDC_FOLDERS_WORK_BUTTON_PATH,178,63,18,14
+ CONTROL "Use for removable drives only",
+ IDC_FOLDERS_WORK_CHECK_FOR_REMOVABLE,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,19,87,180,10
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_FOLDERS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 203
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 147
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/7zip/UI/Explorer/MyMessages.cpp b/7zip/UI/Explorer/MyMessages.cpp
new file mode 100755
index 00000000..d2cae72c
--- /dev/null
+++ b/7zip/UI/Explorer/MyMessages.cpp
@@ -0,0 +1,45 @@
+// 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 MyMessageBox(UINT32 id
+ #ifdef LANG
+ ,UINT32 langID
+ #endif
+ )
+{
+ #ifdef LANG
+ MyMessageBox(LangLoadStringW(id, langID));
+ #else
+ MyMessageBox(MyLoadStringW(id));
+ #endif
+}
+
+void ShowErrorMessage(HWND window, DWORD message)
+{
+ MyMessageBox(window, NError::MyFormatMessageW(message));
+}
+
+void ShowLastErrorMessage(HWND window)
+{
+ ShowErrorMessage(window, ::GetLastError());
+}
+
diff --git a/7zip/UI/Explorer/MyMessages.h b/7zip/UI/Explorer/MyMessages.h
new file mode 100755
index 00000000..4921bd6e
--- /dev/null
+++ b/7zip/UI/Explorer/MyMessages.h
@@ -0,0 +1,26 @@
+// MyMessages.h
+
+#pragma once
+
+#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 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/7zip/UI/Explorer/OptionsDialog.cpp b/7zip/UI/Explorer/OptionsDialog.cpp
new file mode 100755
index 00000000..742adae7
--- /dev/null
+++ b/7zip/UI/Explorer/OptionsDialog.cpp
@@ -0,0 +1,107 @@
+// 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"
+
+extern HINSTANCE g_hInstance;
+
+static void FillInPropertyPage(PROPSHEETPAGE* page,
+ HINSTANCE instance,
+ int dialogID,
+ NWindows::NControl::CPropertyPage *propertyPage,
+ CSysString &title)
+{
+ page->dwSize = sizeof(PROPSHEETPAGE);
+ page->dwFlags = PSP_HASHELP;
+ page->hInstance = instance;
+ page->pszTemplate = MAKEINTRESOURCE(dialogID);
+ page->pszIcon = NULL;
+ page->pfnDlgProc = NWindows::NControl::ProperyPageProcedure;
+
+ if (title.IsEmpty())
+ page->pszTitle = NULL;
+ else
+ {
+ page->dwFlags |= PSP_USETITLE;
+ page->pszTitle = title;
+ }
+ page->lParam = LPARAM(propertyPage);
+}
+
+int OptionsDialog(HWND hwndOwner, HINSTANCE hInstance)
+{
+ const int kNumPages = 2;
+
+ PROPSHEETPAGE pages[kNumPages];
+
+ CSystemPage systemPage;
+ CFoldersPage foldersPage;
+
+ CSysStringVector titles;
+ UINT32 langIDs[] = { 0x01000300, 0x01000200};
+ for (int i = 0; i < sizeof(langIDs) / sizeof(langIDs[0]); i++)
+ titles.Add(GetSystemString(LangLoadString(langIDs[i])));
+
+ FillInPropertyPage(&pages[0], hInstance, IDD_SYSTEM, &systemPage, titles[0]);
+ FillInPropertyPage(&pages[1], hInstance, IDD_FOLDERS, &foldersPage, titles[1]);
+
+ PROPSHEETHEADER sheet;
+
+ sheet.dwSize = sizeof(PROPSHEETHEADER);
+ sheet.dwFlags = PSH_PROPSHEETPAGE;
+ sheet.hwndParent = hwndOwner;
+ sheet.hInstance = hInstance;
+
+ CSysString title = LangLoadString(IDS_CONFIG_DIALOG_CAPTION, 0x01000000);
+
+ sheet.pszCaption = title;
+ sheet.nPages = sizeof(pages) / sizeof(PROPSHEETPAGE);
+ sheet.nStartPage = 0;
+ sheet.ppsp = pages;
+
+ return (PropertySheet(&sheet));
+}
+
+STDMETHODIMP CSevenZipOptions::PluginOptions(HWND hWnd,
+ IPluginOptionsCallback *callback)
+{
+ /*
+ CComBSTR programPath;
+ RETUEN_IF_NOT_S_OK(callback->GetProgramPath(programName)));
+ */
+ OptionsDialog(hWnd, g_hInstance);
+ 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/7zip/UI/Explorer/OptionsDialog.h b/7zip/UI/Explorer/OptionsDialog.h
new file mode 100755
index 00000000..f0397011
--- /dev/null
+++ b/7zip/UI/Explorer/OptionsDialog.h
@@ -0,0 +1,25 @@
+// OptionsDialog.h
+
+#pragma once
+
+#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/7zip/UI/Explorer/RegistryContextMenu..cpp b/7zip/UI/Explorer/RegistryContextMenu..cpp
new file mode 100755
index 00000000..21fdec23
--- /dev/null
+++ b/7zip/UI/Explorer/RegistryContextMenu..cpp
@@ -0,0 +1,84 @@
+// RegistryContextMenu.cpp
+
+#include "StdAfx.h"
+
+#include "RegistryContextMenu.h"
+#include "Windows/COM.h"
+#include "Windows/Synchronization.h"
+#include "Windows/Registry.h"
+#include "Windows/System.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 *kContextMenuHandlerCLASSIDValue =
+ TEXT("{23170F69-40C1-278A-1000-000100020000}");
+static const TCHAR *kRootKeyNameForFile = TEXT("*");
+static const TCHAR *kRootKeyNameForFolder = TEXT("Folder");
+static const TCHAR *kRootKeyNameForDirectory = TEXT("Directory");
+
+static CSysString GetFullContextMenuKeyName(const CSysString &keyName)
+ { return (keyName + kContextMenuKeyName); }
+
+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.CollateNoCase(kContextMenuHandlerCLASSIDValue) == 0);
+}
+
+bool CheckContextMenuHandler()
+{
+ return CheckContextMenuHandlerCommon(kRootKeyNameForFile) &&
+ CheckContextMenuHandlerCommon(kRootKeyNameForFolder) &&
+ CheckContextMenuHandlerCommon(kRootKeyNameForDirectory);
+}
+
+static void DeleteContextMenuHandlerCommon(const CSysString &keyName)
+{
+ CKey rootKey;
+ rootKey.Attach(HKEY_CLASSES_ROOT);
+ rootKey.RecurseDeleteKey(GetFullContextMenuKeyName(keyName));
+ rootKey.Detach();
+}
+
+void DeleteContextMenuHandler()
+{
+ DeleteContextMenuHandlerCommon(kRootKeyNameForFile);
+ DeleteContextMenuHandlerCommon(kRootKeyNameForFolder);
+ DeleteContextMenuHandlerCommon(kRootKeyNameForDirectory);
+}
+
+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, kContextMenuHandlerCLASSIDValue);
+}
+
+void AddContextMenuHandler()
+{
+ AddContextMenuHandlerCommon(kRootKeyNameForFile);
+ AddContextMenuHandlerCommon(kRootKeyNameForFolder);
+ AddContextMenuHandlerCommon(kRootKeyNameForDirectory);
+}
+
+}
diff --git a/7zip/UI/Explorer/RegistryContextMenu.h b/7zip/UI/Explorer/RegistryContextMenu.h
new file mode 100755
index 00000000..06d493e1
--- /dev/null
+++ b/7zip/UI/Explorer/RegistryContextMenu.h
@@ -0,0 +1,18 @@
+// RegistryContextMenu.h
+
+#pragma once
+
+#ifndef __REGISTRYCONTEXTMENU_H
+#define __REGISTRYCONTEXTMENU_H
+
+namespace NZipRootRegistry {
+
+ bool CheckContextMenuHandler();
+ void AddContextMenuHandler();
+ void DeleteContextMenuHandler();
+}
+
+// bool GetProgramDirPrefix(CSysString &folder);
+
+
+#endif \ No newline at end of file
diff --git a/7zip/UI/Explorer/StdAfx.cpp b/7zip/UI/Explorer/StdAfx.cpp
new file mode 100755
index 00000000..2550270c
--- /dev/null
+++ b/7zip/UI/Explorer/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "stdafx.h"
diff --git a/7zip/UI/Explorer/StdAfx.h b/7zip/UI/Explorer/StdAfx.h
new file mode 100755
index 00000000..dfb7077f
--- /dev/null
+++ b/7zip/UI/Explorer/StdAfx.h
@@ -0,0 +1,40 @@
+// stdafx.h : include file for standard system include files,
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+
+// #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>
+
+#define _ATL_APARTMENT_THREADED
+
+#define _ATL_NO_UUIDOF
+
+#include <atlbase.h>
+
+extern CComModule _Module;
+
+#include <atlcom.h>
+#include <shlguid.h>
+#include <regstr.h>
+
+// #include <new.h>
+
+#undef _MT
+
+#include <vector>
+#include <map>
+#include <algorithm>
+
+#define _MT
+
+#endif
diff --git a/7zip/UI/Explorer/SystemPage/SystemPage.cpp b/7zip/UI/Explorer/SystemPage/SystemPage.cpp
new file mode 100755
index 00000000..fe800532
--- /dev/null
+++ b/7zip/UI/Explorer/SystemPage/SystemPage.cpp
@@ -0,0 +1,186 @@
+// SystemDialog.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_TO, 0x0200010F, kCompressTo },
+ { IDS_CONTEXT_COMPRESS_EMAIL, 0x02000111, kCompressEmail },
+ { IDS_CONTEXT_COMPRESS_TO_EMAIL, 0x02000113, kCompressToEmail},
+};
+
+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);
+
+ CSysString s; // = TEXT("Items"); // LangLoadString(IDS_PROPERTY_EXTENSION, 0x02000205);
+ LVCOLUMN column;
+ column.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_FMT | LVCF_SUBITEM;
+ column.cx = 270;
+ column.fmt = LVCFMT_LEFT;
+ column.pszText = (LPTSTR)(LPCTSTR)s;
+ column.iSubItem = 0;
+ m_ListView.InsertColumn(0, &column);
+
+ for (int i = 0; i < kNumMenuItems; i++)
+ {
+ CContextMenuItem &menuItem = kMenuItems[i];
+ LVITEM item;
+ item.iItem = i;
+ item.mask = LVIF_TEXT | LVIF_PARAM;
+ item.lParam = i;
+
+ UString s = LangLoadStringW(menuItem.ControlID, menuItem.LangID);
+
+ switch(menuItem.ControlID)
+ {
+ case IDS_CONTEXT_EXTRACT_TO:
+ s = MyFormatNew(s, LangLoadStringW(IDS_CONTEXT_FOLDER, 0x02000140));
+ break;
+ case IDS_CONTEXT_COMPRESS_TO:
+ case IDS_CONTEXT_COMPRESS_TO_EMAIL:
+ s = MyFormatNew(s, LangLoadStringW(IDS_CONTEXT_ARCHIVE, 0x02000141));
+ break;
+ }
+
+ CSysString ext = GetSystemString(s);
+
+ // UString MyFormatNew(const UString &format, const UString &argument);
+
+ item.pszText = (LPTSTR)(LPCTSTR)ext;
+ item.iSubItem = 0;
+ int itemIndex = m_ListView.InsertItem(&item);
+ m_ListView.SetCheckState(itemIndex, ((contextMenuFlags & menuItem.Flag) != 0));
+ }
+
+ _initMode = false;
+ return CPropertyPage::OnInit();
+}
+
+LONG CSystemPage::OnApply()
+{
+ if (IsButtonCheckedBool(IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU))
+ NZipRootRegistry::AddContextMenuHandler();
+ else
+ 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 aButtonID, HWND aButtonHWND)
+{
+ switch(aButtonID)
+ {
+ case IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU:
+ Changed();
+ return true;
+ }
+ return CPropertyPage::OnButtonClicked(aButtonID, aButtonHWND);
+
+}
+
+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/7zip/UI/Explorer/SystemPage/SystemPage.h b/7zip/UI/Explorer/SystemPage/SystemPage.h
new file mode 100755
index 00000000..5fb148a4
--- /dev/null
+++ b/7zip/UI/Explorer/SystemPage/SystemPage.h
@@ -0,0 +1,27 @@
+// SystemPage.h
+
+#pragma once
+
+#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/7zip/UI/Explorer/SystemPage/resource.h b/7zip/UI/Explorer/SystemPage/resource.h
new file mode 100755
index 00000000..7b5bf208
--- /dev/null
+++ b/7zip/UI/Explorer/SystemPage/resource.h
@@ -0,0 +1,20 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#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
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 135
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1025
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/UI/Explorer/SystemPage/resource.rc b/7zip/UI/Explorer/SystemPage/resource.rc
new file mode 100755
index 00000000..20845368
--- /dev/null
+++ b/7zip/UI/Explorer/SystemPage/resource.rc
@@ -0,0 +1,105 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_SYSTEM DIALOG DISCARDABLE 0, 0, 210, 178
+STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "System"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ CONTROL "Integrate 7-Zip to shell context menu",
+ IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,7,7,196,10
+ CONTROL "Cascaded context menu",IDC_SYSTEM_CASCADED_MENU,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,7,21,196,10
+ CONTROL "List1",IDC_SYSTEM_OPTIONS_LIST,"SysListView32",
+ LVS_REPORT | LVS_SINGLESEL | LVS_NOCOLUMNHEADER |
+ WS_BORDER | WS_TABSTOP,7,50,196,121
+ LTEXT "Context menu items:",
+ IDC_SYSTEM_STATIC_CONTEXT_MENU_ITEMS,7,37,196,8
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_SYSTEM, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 203
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 171
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/7zip/UI/Explorer/resource.h b/7zip/UI/Explorer/resource.h
new file mode 100755
index 00000000..98643351
--- /dev/null
+++ b/7zip/UI/Explorer/resource.h
@@ -0,0 +1,47 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#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
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 157
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1110
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/UI/Explorer/resource.rc b/7zip/UI/Explorer/resource.rc
new file mode 100755
index 00000000..3c480e92
--- /dev/null
+++ b/7zip/UI/Explorer/resource.rc
@@ -0,0 +1,181 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""FoldersPage\\resource.rc""\r\n"
+ "#include ""SystemPage\\resource.rc""\r\n"
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,13,0,0
+ PRODUCTVERSION 3,13,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "7-Zip Shell Extension\0"
+ VALUE "FileVersion", "3, 13, 0, 0\0"
+ VALUE "InternalName", "7-zip\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "7-zip.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 13, 0, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// 24
+//
+
+1 24 MOVEABLE PURE "7-zip.dll.manifest"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+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."
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ 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."
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_CONTEXT_FOLDER "<Folder>"
+ IDS_CONTEXT_ARCHIVE "<Archive>"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_ERROR "Error"
+ IDS_CONFIG_DIALOG_CAPTION "7-Zip Options"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "FoldersPage\resource.rc"
+#include "SystemPage\resource.rc"
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/UI/Far/CLSIDConst.cpp b/7zip/UI/Far/CLSIDConst.cpp
new file mode 100755
index 00000000..a6cea92e
--- /dev/null
+++ b/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/7zip/UI/Far/CompressEngine.cpp b/7zip/UI/Far/CompressEngine.cpp
new file mode 100755
index 00000000..bf5f57fc
--- /dev/null
+++ b/7zip/UI/Far/CompressEngine.cpp
@@ -0,0 +1,347 @@
+// CompressEngine.h
+
+#include "StdAfx.h"
+
+#include "ProxyHandler.h"
+#include "CompressEngine.h"
+#include "UpdateEngine.h"
+
+#include "../../Archiver/Common/CompressEngineCommon.h"
+#include "../../Archiver/Common/OpenEngine2.h"
+#include "../../Archiver/Common/UpdateProducer.h"
+#include "../../Archiver/Common/UpdateUtils.h"
+
+#include "Windows/File/Name.h"
+#include "Windows/File/Find.h"
+#include "Windows/File/Directory.h"
+#include "Windows/PropVariant.h"
+#include "Windows/Error.h"
+
+#include "../../../WinWrappers/PropVariantConversions.h"
+
+// #include "CompressDialog.h"
+
+#include "Common/StringConvert.h"
+// #include "ArchiveStyleDirItemInfo.h"
+
+#include "Interface/FileStreams.h"
+
+#include "Messages.h"
+#include "Far/FarUtils.h"
+// #include "ZipViewUtils.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NName;
+using namespace NCOM;
+
+using namespace NFar;
+using namespace NUpdateArchive;
+
+#define RETURN_IF_NOT_S_OK(x) { HRESULT aResult = (x); if(aResult != S_OK) return aResult; }
+
+static LPCTSTR kTempArcivePrefix = "7zi";
+
+static void GetFileTime(CProxyHandler *aProxyHandler, LPCITEMIDLIST anItemIDList,
+ FILETIME &aFileTime)
+{
+ CPropVariant aProperty;
+ aProxyHandler->GetPropertyValue(anItemIDList, kaipidLastWriteTime, &aProperty);
+ if (aProperty.vt == VT_FILETIME)
+ aFileTime = aProperty.filetime;
+ else if (aProperty.vt == VT_EMPTY)
+ aFileTime = aProxyHandler->m_ArchiveFileInfo.LastWriteTime;
+ else
+ throw 4190407;
+}
+
+void EnumerateInArchiveItems(CProxyHandler *aProxyHandler,
+ const CArchiveFolderItem &anItem, const UString &aPrefix,
+ CArchiveItemInfoVector &anArchiveItems)
+{
+ for(int i = 0; i < anItem.m_FileSubItems.Size(); i++)
+ {
+ const CArchiveFolderFileItem &aFileItem = anItem.m_FileSubItems[i];
+ CArchiveItemInfo anItemInfo;
+
+ GetFileTime(aProxyHandler, aFileItem.m_Properties, anItemInfo.LastWriteTime);
+
+ CPropVariant aProperty;
+ aProxyHandler->GetPropertyValue(aFileItem.m_Properties, kaipidSize, &aProperty);
+ if (anItemInfo.SizeIsDefined = (aProperty.vt != VT_EMPTY))
+ anItemInfo.Size = ConvertPropVariantToUINT64(aProperty);
+ anItemInfo.IsDirectory = false;
+ anItemInfo.Name = aPrefix + aFileItem.m_Name;
+ anItemInfo.Censored = true; // test it
+ anItemInfo.IndexInServer = aProxyHandler->GetHandlerItemIndex(aFileItem.m_Properties);
+ anArchiveItems.Add(anItemInfo);
+ }
+ for(i = 0; i < anItem.m_DirSubItems.Size(); i++)
+ {
+ const CArchiveFolderItem &aDirItem = anItem.m_DirSubItems[i];
+ if(!aDirItem.m_IsLeaf)
+ continue;
+ CArchiveItemInfo anItemInfo;
+ GetFileTime(aProxyHandler, aDirItem.m_Properties, anItemInfo.LastWriteTime);
+ anItemInfo.IsDirectory = true;
+ anItemInfo.SizeIsDefined = false;
+ anItemInfo.Name = aPrefix + aDirItem.m_Name;
+ anItemInfo.Censored = true; // test it
+ anItemInfo.IndexInServer = aProxyHandler->GetHandlerItemIndex(
+ aDirItem.m_Properties);
+ anArchiveItems.Add(anItemInfo);
+ EnumerateInArchiveItems(aProxyHandler, aDirItem, anItemInfo.Name +
+ wchar_t(kDirDelimiter), anArchiveItems);
+ }
+}
+
+
+static const char *kExtension = _T(".zip");
+
+
+HRESULT Compress(const CSysStringVector &aFileNames,
+ const UString &anArchiveNamePrefix,
+ const CActionSet &anActionSet, CProxyHandler *aProxyHandler,
+ const CLSID &aClassID, bool aStoreMode, bool aMaximizeRatioMode,
+ CSysString &anArchiveName, CProgressBox *aProgressBox)
+{
+ CComPtr<IOutArchiveHandler> anOutArchive;
+ CArchiveItemInfoVector anArchiveItems;
+ if(aProxyHandler != NULL)
+ {
+ HRESULT aResult = aProxyHandler->m_ArchiveHandler.QueryInterface(&anOutArchive);
+ if(aResult != S_OK)
+ {
+ g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive);
+ return E_FAIL;
+ }
+ EnumerateInArchiveItems(aProxyHandler,
+ aProxyHandler->m_FolderItemHead, L"", anArchiveItems);
+ }
+ else
+ {
+ HRESULT aResult = anOutArchive.CoCreateInstance(aClassID);
+ if (aResult != S_OK)
+ {
+ g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive);
+ return E_FAIL;
+ }
+ }
+ CArchiveStyleDirItemInfoVector aDirItems;
+
+ EnumerateItems(aFileNames, anArchiveNamePrefix, aDirItems, CP_OEMCP);
+
+ CUpdatePairInfoVector anUpdatePairs;
+
+ NFileTimeType::EEnum aFileTimeType;
+ UINT32 aValue;
+ RETURN_IF_NOT_S_OK(anOutArchive->GetFileTimeType(&aValue));
+
+ switch(aValue)
+ {
+ case NFileTimeType::kWindows:
+ case NFileTimeType::kDOS:
+ case NFileTimeType::kUnix:
+ aFileTimeType = NFileTimeType::EEnum(aValue);
+ break;
+ default:
+ return E_FAIL;
+ }
+
+ GetUpdatePairInfoList(aDirItems, anArchiveItems, aFileTimeType, anUpdatePairs);
+
+ CUpdatePairInfo2Vector anOperationChain;
+ UpdateProduce(aDirItems, anArchiveItems, anUpdatePairs, anActionSet,
+ anOperationChain);
+
+ CComObjectNoLock<CUpdateCallBackImp> *anUpdateCallBackSpec =
+ new CComObjectNoLock<CUpdateCallBackImp>;
+ CComPtr<IUpdateCallBack> anUpdateCallBack(anUpdateCallBackSpec );
+
+ anUpdateCallBackSpec->Init(&aDirItems, &anArchiveItems, &anOperationChain,
+ aProgressBox);
+
+ CComObjectNoLock<COutFileStream> *anOutStreamSpec =
+ new CComObjectNoLock<COutFileStream>;
+ CComPtr<IOutStream> anOutStream(anOutStreamSpec);
+
+ {
+ CSysString aResultPath;
+ int aPos;
+ if(! NFile::NDirectory::MyGetFullPathName(anArchiveName, aResultPath, aPos))
+ throw 141716;
+ NFile::NDirectory::CreateComplexDirectory(aResultPath.Left(aPos));
+ }
+ if (!anOutStreamSpec->Open(anArchiveName))
+ {
+ ShowLastErrorMessage();
+ return E_FAIL;
+ }
+
+ HRESULT aResult = anOutArchive->UpdateItems(anOutStream, anOperationChain.Size(),
+ BoolToMyBool(aStoreMode), BoolToMyBool(aMaximizeRatioMode), anUpdateCallBack);
+ return aResult;
+}
+
+
+// The returned string ends with a backslash
+
+
+/*
+
+void CompressArchive(const CSysStringVector &aFileNames)
+{
+ if (aFileNames.Size() == 0)
+ return;
+ CSysString aResultPath;
+ {
+ CParsedPath aParsedPath;
+ aParsedPath.ParsePath(aFileNames.Front());
+ if(aParsedPath.PathParts.Size() == 0)
+ return; // Error
+ if (aFileNames.Size() == 1 || aParsedPath.PathParts.Size() == 1)
+ {
+ CSysString aPureName, aDot, anExtension;
+ SplitNameToPureNameAndExtension(aParsedPath.PathParts.Back(),
+ aPureName, aDot, anExtension);
+ // aParsedPath.PathParts.Back() = aPureName;
+ // aResultPath = aParsedPath.MergePath();
+ aResultPath = aPureName;
+ }
+ else
+ {
+ aParsedPath.PathParts.DeleteBack();
+ // aResultPath = aParsedPath.MergePath();
+ // aResultPath += NFile::NName::kDirDelimiter;
+ // aResultPath += aParsedPath.PathParts.Back();
+ aResultPath = aParsedPath.PathParts.Back();
+ }
+ aResultPath += kExtension;
+ }
+ CSysString aCurrentDir;
+ {
+ CParsedPath aParsedPath;
+ aParsedPath.ParsePath(aFileNames.Front());
+ aParsedPath.PathParts.DeleteBack();
+ aCurrentDir = aParsedPath.MergePath();
+ if (aParsedPath.PathParts.Size() > 0)
+ aCurrentDir += NFile::NName::kDirDelimiter;
+ }
+
+
+ CCompressDialog aDialog;
+
+
+
+ CZipRegistryManager aZipRegistryManager;
+ aDialog.m_ZipRegistryManager = &aZipRegistryManager;
+
+ NZipRootRegistry::CArchiverInfoVector anArchiverInfoList;
+ NZipRootRegistry::ReadArchiverInfoList(anArchiverInfoList);
+ aDialog.m_ArchiverInfoList.Clear();
+ for(int i = 0; i < anArchiverInfoList.Size(); i++)
+ {
+ NZipRootRegistry::CArchiverInfo anArchiverInfo = anArchiverInfoList[i];
+ if (anArchiverInfo.UpdateEnabled)
+ aDialog.m_ArchiverInfoList.Add(anArchiverInfo);
+ }
+ if(aDialog.m_ArchiverInfoList.Size() == 0)
+ {
+ AfxMessageBox("No Update Engines");
+ return;
+ }
+
+ aDialog.m_Info.ArchiveName = aResultPath;
+ aDialog.m_Info.CurrentDirPrefix = aCurrentDir;
+
+ if(aDialog.DoModal() != IDOK)
+ return;
+
+ CSysString anArcPath;
+ if (!aDialog.m_Info.GetFullPathName(anArcPath))
+ {
+ AfxMessageBox("Incorrect archive path");;
+ return;
+ }
+ const CActionSet *anActionSet;
+ switch(aDialog.m_Info.UpdateMode)
+ {
+ case NCompressDialog::NUpdateMode::kAdd:
+ anActionSet = &kAddActionSet;
+ break;
+ case NCompressDialog::NUpdateMode::kUpdate:
+ anActionSet = &kUpdateActionSet;
+ break;
+ case NCompressDialog::NUpdateMode::kFresh:
+ anActionSet = &kFreshActionSet;
+ break;
+ case NCompressDialog::NUpdateMode::kSynchronize:
+ anActionSet = &kSynchronizeActionSet;
+ break;
+ default:
+ throw 1091756;
+ }
+
+
+ NZipSettings::NWorkDir::CInfo aWorkDirInfo;
+ aZipRegistryManager.ReadWorkDirInfo(aWorkDirInfo);
+ CSysString aWorkDir = GetWorkDir(aWorkDirInfo, anArcPath);
+ NFile::NDirectory::CreateComplexDirectory(aWorkDir);
+
+ NFile::NDirectory::CTempFile aTempFile;
+ CSysString aTempFileName;
+ if (aTempFile.Create(aWorkDir, kTempArcivePrefix, aTempFileName) == 0)
+ return;
+
+ CProxyHandler *aProxyHandler;
+ NFind::CFileInfo aFileInfo;
+ if(NFind::FindFile(anArcPath, aFileInfo))
+ {
+ if (aFileInfo.IsDirectory())
+ {
+ CString aMessage;
+ AfxFormatString1(aMessage, IDS_CANT_UPDATE_ARCHIVE, anArcPath);
+ AfxMessageBox(aMessage);
+ return;
+ }
+ bool aHandlerIsNew;
+ if (!g_HandlersManager.GetProxyHandler(anArcPath, &aProxyHandler, aHandlerIsNew))
+ {
+ CString aMessage;
+ AfxFormatString1(aMessage, IDS_CANT_UPDATE_ARCHIVE, anArcPath);
+ AfxMessageBox(aMessage);
+ return;
+ }
+ }
+ else
+ aProxyHandler = NULL;
+
+
+ HRESULT aResult = Compress(aFileNames, *anActionSet, aProxyHandler,
+ aDialog.m_ArchiverInfoList[aDialog.m_Info.ArchiverInfoIndex].ClassID,
+ aDialog.m_Info.Method == NCompressDialog::NMethod::kStore,
+ aDialog.m_Info.Method == NCompressDialog::NMethod::kMaximum,
+ aTempFileName);
+ if (aResult != S_OK)
+ {
+ ShowErrorMessage(aResult);
+ return;
+ }
+ if(aProxyHandler != 0) // Update
+ {
+ if (!NFile::NDirectory::DeleteFileAlways(anArcPath))
+ {
+ ShowLastErrorMessage();
+ return;
+ }
+ }
+ aTempFile.DisableDeleting();
+ if (!MoveFile(aTempFileName, anArcPath))
+ {
+ ShowLastErrorMessage();
+ return;
+ }
+}
+*/
+
+
diff --git a/7zip/UI/Far/CompressEngine.h b/7zip/UI/Far/CompressEngine.h
new file mode 100755
index 00000000..062286ef
--- /dev/null
+++ b/7zip/UI/Far/CompressEngine.h
@@ -0,0 +1,23 @@
+// CompressEngine.h
+
+#pragma once
+
+#ifndef __COMPRESSENGINE_H
+#define __COMPRESSENGINE_H
+
+#include "Common/String.h"
+#include "../../Archiver/Common/CompressEngineCommon.h"
+#include "ProxyHandler.h"
+
+#include "Far/ProgressBox.h"
+
+
+HRESULT Compress(const CSysStringVector &aFileNames,
+ const UString &anArchiveNamePrefix,
+ const NUpdateArchive::CActionSet &anActionSet, CProxyHandler *aProxyHandler,
+ const CLSID &aClassID, bool aStoreMode, bool aMaximizeRatioMode,
+ CSysString &anArchiveName, CProgressBox *aProgressBox);
+
+// void CompressArchive(const CSysStringVector &aFileNames);
+
+#endif
diff --git a/7zip/UI/Far/ExtractEngine.cpp b/7zip/UI/Far/ExtractEngine.cpp
new file mode 100755
index 00000000..90304d94
--- /dev/null
+++ b/7zip/UI/Far/ExtractEngine.cpp
@@ -0,0 +1,165 @@
+// ExtractEngine.h
+
+#include "StdAfx.h"
+
+#include "ExtractEngine.h"
+#include "Far/FarUtils.h"
+
+#include "Messages.h"
+
+#include "OverwriteDialog.h"
+
+#include "Common/WildCard.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/Defs.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;
+ if (oldFileInfo.SizeIsDefined = (existSize != NULL))
+ oldFileInfo.Size = *existSize;
+ oldFileInfo.Name = UnicodeStringToMultiByte(existName, m_CodePage);
+
+
+ newFileInfo.Time = *aNewTime;
+
+ if (newFileInfo.SizeIsDefined = (newSize != NULL))
+ newFileInfo.Size = *newSize;
+ newFileInfo.Name = UnicodeStringToMultiByte(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)
+{
+ m_CurrentFilePath = name;
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallBackImp::MessageError(const wchar_t *message)
+{
+ CSysString s = UnicodeStringToMultiByte(message, CP_OEMCP);
+ if (g_StartupInfo.ShowMessage(s) == -1)
+ return E_ABORT;
+ return S_OK;
+}
+
+STDMETHODIMP CExtractCallBackImp::SetOperationResult(INT32 operationResult)
+{
+ 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/7zip/UI/Far/ExtractEngine.h b/7zip/UI/Far/ExtractEngine.h
new file mode 100755
index 00000000..eeed516f
--- /dev/null
+++ b/7zip/UI/Far/ExtractEngine.h
@@ -0,0 +1,69 @@
+// ExtractEngine.h
+
+#pragma once
+
+#ifndef __EXTRACTENGINE_H
+#define __EXTRACTENGINE_H
+
+#include "Common/MyCom.h"
+#include "Common/String.h"
+#include "Far/ProgressBox.h"
+
+#include "../../IPassword.h"
+#include "../Agent/IFolderArchive.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);
+
+ STDMETHOD(MessageError)(const wchar_t *message);
+ STDMETHOD(SetOperationResult)(INT32 resultEOperationResult);
+ // 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/7zip/UI/Far/Far.def b/7zip/UI/Far/Far.def
new file mode 100755
index 00000000..d96501e2
--- /dev/null
+++ b/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/7zip/UI/Far/Far.dsp b/7zip/UI/Far/Far.dsp
new file mode 100755
index 00000000..0e6e0d10
--- /dev/null
+++ b/7zip/UI/Far/Far.dsp
@@ -0,0 +1,529 @@
+# 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=.\Far.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\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 "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=.\PluginCommon.cpp
+# 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=..\..\..\Far\FarPlugin.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Far\FarUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Far\FarUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Far\ProgressBox.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Far\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
+# Begin Source File
+
+SOURCE=..\..\..\Windows\System.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\System.h
+# End Source File
+# End Group
+# Begin Group "UI Common"
+
+# PROP Default_Filter ""
+# 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\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\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\ArchiveExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\ArchiveExtractCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\ArchiveUpdateCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\ArchiveUpdateCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\IFolderArchive.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
+# End Group
+# End Target
+# End Project
diff --git a/7zip/UI/Far/Far.dsw b/7zip/UI/Far/Far.dsw
new file mode 100755
index 00000000..f4ef0801
--- /dev/null
+++ b/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/7zip/UI/Far/Far.rc b/7zip/UI/Far/Far.rc
new file mode 100755
index 00000000..8e7deeeb
--- /dev/null
+++ b/7zip/UI/Far/Far.rc
@@ -0,0 +1,121 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,13,0,0
+ PRODUCTVERSION 3,13,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "7-Zip FAR Plugin\0"
+ VALUE "FileVersion", "3, 13, 0, 0\0"
+ VALUE "InternalName", "7-ZipFar\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "7-ZipFar.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 13, 0, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/UI/Far/Main.cpp b/7zip/UI/Far/Main.cpp
new file mode 100755
index 00000000..5a74bfe1
--- /dev/null
+++ b/7zip/UI/Far/Main.cpp
@@ -0,0 +1,615 @@
+// 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 "Far/FarUtils.h"
+#include "Far/ProgressBox.h"
+
+#include "Messages.h"
+
+#include "../../Common/FileStreams.h"
+
+#include "../Common/DefaultName.h"
+#include "../Common/OpenArchive.h"
+#include "../Agent/Agent.h"
+// #include "../../Compress/Interface/CompressInterface.h"
+#include "../../IPassword.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;
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ g_hInstance = hInstance;
+ }
+ 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)
+{
+ *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)
+{
+ 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");
+
+ // UString defaultName;
+
+ 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)
+ return INVALID_HANDLE_VALUE;
+
+ // ::OutputDebugString("after OpenArchive\n");
+
+ /*
+ std::auto_ptr<CProxyHandler> aProxyHandler(new CProxyHandler());
+
+ if(aProxyHandler->Init(archiveHandler,
+ fileInfo,
+ GetDefaultName(fullName, archiverInfoResult.Extension),
+ openArchiveCallbackSpec) != S_OK)
+ return INVALID_HANDLE_VALUE;
+
+ // ::OutputDebugString("after Init\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/7zip/UI/Far/Messages.h b/7zip/UI/Far/Messages.h
new file mode 100755
index 00000000..ed156fd2
--- /dev/null
+++ b/7zip/UI/Far/Messages.h
@@ -0,0 +1,152 @@
+// SevenZip/ Messages.h
+
+#pragma once
+
+#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,
+
+ kGetPasswordTitle,
+ kEnterPasswordForFile,
+
+ kExtractTitle,
+ kExtractTo,
+
+ kExtractPathMode,
+ kExtractPathFull,
+ kExtractPathCurrent,
+ kExtractPathNo,
+
+ kExtractOwerwriteMode,
+ kExtractOwerwriteAsk,
+ kExtractOwerwritePrompt,
+ kExtractOwerwriteSkip,
+ kExtractOwerwriteAutoRename,
+
+ 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/7zip/UI/Far/OverwriteDialog.cpp b/7zip/UI/Far/OverwriteDialog.cpp
new file mode 100755
index 00000000..1da2b2ef
--- /dev/null
+++ b/7zip/UI/Far/OverwriteDialog.cpp
@@ -0,0 +1,106 @@
+// OverwriteDialog.cpp : implementation file
+
+#include "StdAfx.h"
+
+#include "OverwriteDialog.h"
+
+#include "Windows/FileName.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariantConversions.h"
+
+#include "Common/String.h"
+#include "Common/StringConvert.h"
+#include "Far/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 = ConvertFileTimeToString2(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/7zip/UI/Far/OverwriteDialog.h b/7zip/UI/Far/OverwriteDialog.h
new file mode 100755
index 00000000..577d5702
--- /dev/null
+++ b/7zip/UI/Far/OverwriteDialog.h
@@ -0,0 +1,35 @@
+// OverwriteDialog.h
+
+#pragma once
+
+#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/7zip/UI/Far/Plugin.cpp b/7zip/UI/Far/Plugin.cpp
new file mode 100755
index 00000000..8b4af589
--- /dev/null
+++ b/7zip/UI/Far/Plugin.cpp
@@ -0,0 +1,690 @@
+// Plugin.cpp
+
+#include "StdAfx.h"
+
+#include "Plugin.h"
+
+// #include "Windows/Time.h"
+#include "Windows/FileName.h"
+#include "Windows/FileDir.h"
+
+#include "Common/StringConvert.h"
+
+#include "Windows/PropVariantConversions.h"
+
+#include "Far/FarUtils.h"
+
+#include "../Common/PropIDUtils.h"
+
+#include "Common/WildCard.h"
+
+#include "Messages.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(int 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 aDir = MultiByteToUnicodeString(aszDir, CP_OEMCP);
+ if (aDir == L"\\")
+ {
+ _folder.Release();
+ m_ArchiveHandler->BindToRootFolder(&_folder);
+ }
+ else if (aDir == L"..")
+ {
+ CMyComPtr<IFolderFolder> newFolder;
+ _folder->BindToParentFolder(&newFolder);
+ if (newFolder == NULL)
+ throw 40312;
+ _folder = newFolder;
+ }
+ else if (aDir.IsEmpty())
+ EnterToDirectory(aDir);
+ else
+ {
+ if (aDir[0] == L'\\')
+ {
+ _folder.Release();
+ m_ArchiveHandler->BindToRootFolder(&_folder);
+ aDir = aDir.Mid(1);
+ }
+ UStringVector pathParts;
+ SplitPathToParts(aDir, pathParts);
+ for(int i = 0; i < pathParts.Size(); i++)
+ EnterToDirectory(pathParts[i]);
+ }
+ m_CurrentDir.Empty();
+ UStringVector pathParts;
+ GetPathParts(pathParts);
+ for (int i = 0; i < pathParts.Size(); i++)
+ {
+ m_CurrentDir += L'\\';
+ m_CurrentDir += pathParts[i];
+ }
+ return TRUE;
+}
+
+void CPlugin::GetPathParts(UStringVector &pathParts)
+{
+ pathParts.Clear();
+ CMyComPtr<IFolderFolder> folderItem = _folder;
+ while (true)
+ {
+ CMyComPtr<IFolderFolder> newFolder;
+ folderItem->BindToParentFolder(&newFolder);
+ if (newFolder == NULL)
+ break;
+ CMyComBSTR name;
+ folderItem->GetName(&name);
+ pathParts.Insert(0, (const wchar_t *)name);
+ folderItem = newFolder;
+ }
+}
+
+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 }
+};
+
+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 < 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/7zip/UI/Far/Plugin.h b/7zip/UI/Far/Plugin.h
new file mode 100755
index 00000000..2357c3c8
--- /dev/null
+++ b/7zip/UI/Far/Plugin.h
@@ -0,0 +1,108 @@
+// Far/Plugin.h
+
+#pragma once
+
+#ifndef __FAR_PLUGIN_H
+#define __FAR_PLUGIN_H
+
+#include "Windows/COM.h"
+#include "Windows/FileFind.h"
+#include "Windows/PropVariant.h"
+#include "Common/MyCom.h"
+#include "Far/FarUtils.h"
+
+#include "../Common/ArchiverInfo.h"
+#include "../Agent/IFolderArchive.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);
+public:
+ UString m_FileName;
+ // UString m_DefaultName;
+ NWindows::NFile::NFind::CFileInfoW m_FileInfo;
+
+ // std::auto_ptr<CProxyHandler> m_ProxyHandler;
+ 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);
+
+
+ /*
+ void AddRealIndexOfFile(const CArchiveFolderItem &aFolder, int anIndexInVector,
+ std::vector<int> &aRealIndexes);
+ void AddRealIndexes(const CArchiveFolderItem &anItem,
+ std::vector<int> &aRealIndexes);
+ void GetRealIndexes(PluginPanelItem *aPanelItems, int itemsNumber,
+ std::vector<int> &aRealIndexes);
+ */
+
+ HRESULT ExtractFiles(
+ bool aDecompressAllItems,
+ const UINT32 *anIndexes,
+ UINT32 numIndices,
+ bool aSilent,
+ NExtractionMode::NPath::EEnum aPathMode,
+ NExtractionMode::NOverwrite::EEnum overwriteMode,
+ const UString &destPath,
+ bool aPasswordIsDefined, 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/7zip/UI/Far/PluginCommon.cpp b/7zip/UI/Far/PluginCommon.cpp
new file mode 100755
index 00000000..5e7679f9
--- /dev/null
+++ b/7zip/UI/Far/PluginCommon.cpp
@@ -0,0 +1,54 @@
+// SevenZip/Plugin.cpp
+
+#include "StdAfx.h"
+
+#include "Plugin.h"
+
+using namespace NWindows;
+using namespace std;
+using namespace NFar;
+
+/*
+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/7zip/UI/Far/PluginDelete.cpp b/7zip/UI/Far/PluginDelete.cpp
new file mode 100755
index 00000000..36dccdc4
--- /dev/null
+++ b/7zip/UI/Far/PluginDelete.cpp
@@ -0,0 +1,169 @@
+// PluginDelete.cpp
+
+#include "StdAfx.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"
+// #include "../Common/OpenEngine2.h"
+
+
+using namespace std;
+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;
+ }
+
+ return(TRUE);
+}
diff --git a/7zip/UI/Far/PluginRead.cpp b/7zip/UI/Far/PluginRead.cpp
new file mode 100755
index 00000000..d4761b8e
--- /dev/null
+++ b/7zip/UI/Far/PluginRead.cpp
@@ -0,0 +1,304 @@
+// 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 std;
+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,
+ NExtractionMode::NPath::EEnum pathMode,
+ NExtractionMode::NOverwrite::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;
+ NExtraction::CInfo extractionInfo;
+ extractionInfo.PathMode = NExtraction::NPathMode::kCurrentPathnames;
+ extractionInfo.OverwriteMode = NExtraction::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 kFilesModeIndex = kOverwriteModeRadioIndex + 5;
+ const int kYSize = 18;
+
+ const int kXMid = 38;
+
+ AString oemPassword = UnicodeStringToMultiByte(password, CP_OEMCP);
+
+ struct CInitDialogItem initItems[]={
+ { DI_DOUBLEBOX, 3, 1, 72, kYSize - 2, false, false, 0, false, NMessageID::kExtractTitle, NULL, NULL },
+ { DI_TEXT, 5, 2, 0, 0, false, false, 0, false, NMessageID::kExtractTo, NULL, NULL },
+
+ { DI_EDIT, 5, 3, 70, 3, true, false, DIF_HISTORY, false, -1, destPath, kExractPathHistoryName},
+ // { DI_EDIT, 5, 3, 70, 3, true, false, 0, false, -1, destPath, NULL},
+
+ { DI_SINGLEBOX, 4, 5, kXMid - 2, 5 + 4, false, false, 0, false, NMessageID::kExtractPathMode, NULL, NULL },
+ { DI_RADIOBUTTON, 6, 6, 0, 0, false,
+ extractionInfo.PathMode == NExtraction::NPathMode::kFullPathnames,
+ DIF_GROUP, false, NMessageID::kExtractPathFull, NULL, NULL },
+ { DI_RADIOBUTTON, 6, 7, 0, 0, false,
+ extractionInfo.PathMode == NExtraction::NPathMode::kCurrentPathnames,
+ 0, false, NMessageID::kExtractPathCurrent, NULL, NULL },
+ { DI_RADIOBUTTON, 6, 8, 0, 0, false,
+ extractionInfo.PathMode == NExtraction::NPathMode::kNoPathnames,
+ false, 0, NMessageID::kExtractPathNo, NULL, NULL },
+
+ { DI_SINGLEBOX, kXMid, 5, 70, 5 + 5, false, false, 0, false, NMessageID::kExtractOwerwriteMode, NULL, NULL },
+ { DI_RADIOBUTTON, kXMid + 2, 6, 0, 0, false,
+ extractionInfo.OverwriteMode == NExtraction::NOverwriteMode::kAskBefore,
+ DIF_GROUP, false, NMessageID::kExtractOwerwriteAsk, NULL, NULL },
+ { DI_RADIOBUTTON, kXMid + 2, 7, 0, 0, false,
+ extractionInfo.OverwriteMode == NExtraction::NOverwriteMode::kWithoutPrompt,
+ 0, false, NMessageID::kExtractOwerwritePrompt, NULL, NULL },
+ { DI_RADIOBUTTON, kXMid + 2, 8, 0, 0, false,
+ extractionInfo.OverwriteMode == NExtraction::NOverwriteMode::kSkipExisting,
+ 0, false, NMessageID::kExtractOwerwriteSkip, NULL, NULL },
+ { DI_RADIOBUTTON, kXMid + 2, 9, 0, 0, false,
+ extractionInfo.OverwriteMode == NExtraction::NOverwriteMode::kAutoRename,
+ 0, false, NMessageID::kExtractOwerwriteAutoRename, NULL, NULL },
+
+ { DI_SINGLEBOX, 4, 10, kXMid- 2, 10 + 3, false, false, 0, false, NMessageID::kExtractFilesMode, NULL, NULL },
+ { DI_RADIOBUTTON, 6, 11, 0, 0, false, true, DIF_GROUP, false, NMessageID::kExtractFilesSelected, NULL, NULL },
+ { DI_RADIOBUTTON, 6, 12, 0, 0, false, false, 0, false, NMessageID::kExtractFilesAll, NULL, NULL },
+
+ { DI_SINGLEBOX, kXMid, 11, 70, 11 + 2, false, false, 0, false, NMessageID::kExtractPassword, NULL, NULL },
+ { DI_PSWEDIT, kXMid + 2, 12, 70 - 2, 12, false, false, 0, false, -1, oemPassword, NULL},
+
+ { DI_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);
+ while(true)
+ {
+ int askCode = g_StartupInfo.ShowDialog(76, 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 = NExtraction::NPathMode::kFullPathnames;
+ else if (dialogItems[kPathModeRadioIndex + 1].Selected)
+ extractionInfo.PathMode = NExtraction::NPathMode::kCurrentPathnames;
+ else if (dialogItems[kPathModeRadioIndex + 2].Selected)
+ extractionInfo.PathMode = NExtraction::NPathMode::kNoPathnames;
+ else
+ throw 31806;
+
+ if (dialogItems[kOverwriteModeRadioIndex].Selected)
+ extractionInfo.OverwriteMode = NExtraction::NOverwriteMode::kAskBefore;
+ else if (dialogItems[kOverwriteModeRadioIndex + 1].Selected)
+ extractionInfo.OverwriteMode = NExtraction::NOverwriteMode::kWithoutPrompt;
+ else if (dialogItems[kOverwriteModeRadioIndex + 2].Selected)
+ extractionInfo.OverwriteMode = NExtraction::NOverwriteMode::kSkipExisting;
+ else if (dialogItems[kOverwriteModeRadioIndex + 3].Selected)
+ extractionInfo.OverwriteMode = NExtraction::NOverwriteMode::kAutoRename;
+ 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);
+
+ NExtractionMode::NPath::EEnum pathMode;
+ NExtractionMode::NOverwrite::EEnum overwriteMode;
+ switch (extractionInfo.OverwriteMode)
+ {
+ case NExtraction::NOverwriteMode::kAskBefore:
+ overwriteMode = NExtractionMode::NOverwrite::kAskBefore;
+ break;
+ case NExtraction::NOverwriteMode::kWithoutPrompt:
+ overwriteMode = NExtractionMode::NOverwrite::kWithoutPrompt;
+ break;
+ case NExtraction::NOverwriteMode::kSkipExisting:
+ overwriteMode = NExtractionMode::NOverwrite::kSkipExisting;
+ break;
+ case NExtraction::NOverwriteMode::kAutoRename:
+ overwriteMode = NExtractionMode::NOverwrite::kAutoRename;
+ break;
+ default:
+ throw 12334454;
+ }
+ switch (extractionInfo.PathMode)
+ {
+ case NExtraction::NPathMode::kFullPathnames:
+ pathMode = NExtractionMode::NPath::kFullPathnames;
+ break;
+ case NExtraction::NPathMode::kCurrentPathnames:
+ pathMode = NExtractionMode::NPath::kCurrentPathnames;
+ break;
+ case NExtraction::NPathMode::kNoPathnames:
+ pathMode = NExtractionMode::NPath::kNoPathnames;
+ break;
+ default:
+ throw 12334455;
+ }
+ HRESULT result = ExtractFiles(decompressAllItems, &indices.Front(), itemsNumber,
+ !showBox, pathMode, 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/7zip/UI/Far/PluginWrite.cpp b/7zip/UI/Far/PluginWrite.cpp
new file mode 100755
index 00000000..5abb136d
--- /dev/null
+++ b/7zip/UI/Far/PluginWrite.cpp
@@ -0,0 +1,712 @@
+// PluginWrite.cpp
+
+#include "StdAfx.h"
+
+#include "Plugin.h"
+
+#include "Messages.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/UpdatePairBasic.h"
+// #include "../Common/CompressEngineCommon.h"
+#include "../Common/WorkDir.h"
+#include "../Common/OpenArchive.h"
+
+#include "Far/ProgressBox.h"
+
+#include "UpdateCallback100.h"
+
+#include "../Agent/Agent.h"
+
+/*
+#include "../../Archiver/Common/DefaultName.h"
+#include "../../Archiver/Common/OpenEngine2.h"
+*/
+
+// #include "CompressEngine.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> aSetProperties;
+ if (outArchive->QueryInterface(&aSetProperties) == S_OK)
+ {
+ CMyComBSTR comBSTR = L"x";
+ CObjectVector<CMyComBSTR> realNames;
+ std::vector<NCOM::CPropVariant> values;
+ realNames.Add(comBSTR);
+ values.push_back(NCOM::CPropVariant((UINT32)method));
+
+ std::vector<BSTR> names;
+ for(int i = 0; i < realNames.Size(); i++)
+ names.push_back(realNames[i]);
+ RINOK(aSetProperties->SetProperties(&names.front(),
+ &values.front(), 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.CollateNoCase(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;
+
+ while(true)
+ {
+ 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);
+
+
+ // std::auto_ptr<CProxyHandler> proxyHandler;
+ 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.CollateNoCase((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/7zip/UI/Far/StdAfx.cpp b/7zip/UI/Far/StdAfx.cpp
new file mode 100755
index 00000000..d0feea85
--- /dev/null
+++ b/7zip/UI/Far/StdAfx.cpp
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
diff --git a/7zip/UI/Far/StdAfx.h b/7zip/UI/Far/StdAfx.h
new file mode 100755
index 00000000..f91028f7
--- /dev/null
+++ b/7zip/UI/Far/StdAfx.h
@@ -0,0 +1,28 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+/*
+#define _ATL_APARTMENT_THREADED
+
+#define _ATL_NO_UUIDOF
+
+#include <atlbase.h>
+
+extern CComModule _Module;
+
+#include <atlcom.h>
+#include <shlobj.h>
+#include <shlguid.h>
+#include <regstr.h>
+#include <stdio.h>
+
+#include <memory>
+// #include <algorithm>
+*/
+#include <vector>
+
+#endif
diff --git a/7zip/UI/Far/UpdateCallback100.cpp b/7zip/UI/Far/UpdateCallback100.cpp
new file mode 100755
index 00000000..72d0c783
--- /dev/null
+++ b/7zip/UI/Far/UpdateCallback100.cpp
@@ -0,0 +1,44 @@
+// UpdateCallback.h
+
+#include "StdAfx.h"
+
+#include "UpdateCallback100.h"
+
+#include "Common/Defs.h"
+#include "Far/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;
+}
diff --git a/7zip/UI/Far/UpdateCallback100.h b/7zip/UI/Far/UpdateCallback100.h
new file mode 100755
index 00000000..57c787ef
--- /dev/null
+++ b/7zip/UI/Far/UpdateCallback100.h
@@ -0,0 +1,46 @@
+// UpdateCallback.h
+
+#pragma once
+
+#ifndef __UPDATECALLBACK100_H
+#define __UPDATECALLBACK100_H
+
+#include "Common/String.h"
+#include "Common/MyCom.h"
+
+#include "../Agent/IFolderArchive.h"
+
+#include "Far/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);
+
+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/7zip/UI/Far/resource.h b/7zip/UI/Far/resource.h
new file mode 100755
index 00000000..93f677cf
--- /dev/null
+++ b/7zip/UI/Far/resource.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by Far.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/UI/GUI/7zG.exe.manifest b/7zip/UI/GUI/7zG.exe.manifest
new file mode 100755
index 00000000..65045abf
--- /dev/null
+++ b/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="X86" 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="X86" publicKeyToken="6595b64144ccf1df" language="*"/></dependentAssembly></dependency></assembly>
diff --git a/7zip/UI/GUI/Compress.cpp b/7zip/UI/GUI/Compress.cpp
new file mode 100755
index 00000000..2212ecc4
--- /dev/null
+++ b/7zip/UI/GUI/Compress.cpp
@@ -0,0 +1,636 @@
+// Compress.cpp
+
+#include "StdAfx.h"
+
+#include <mapi.h>
+
+#include "Compress.h"
+#include "CompressDialog.h"
+#include "resource.h"
+
+#include "Common/StringConvert.h"
+#include "Common/IntToString.h"
+
+#include "Windows/FileName.h"
+#include "Windows/FileFind.h"
+#include "Windows/FileDir.h"
+#include "Windows/Thread.h"
+#include "Windows/COM.h"
+#include "Windows/PropVariant.h"
+
+#include "../../FileManager/ProgramLocation.h"
+#include "../../FileManager/FormatUtils.h"
+#include "../../FileManager/UpdateCallback100.h"
+
+#include "../Agent/Agent.h"
+#include "../Common/UpdateAction.h"
+#include "../Common/WorkDir.h"
+#include "../Common/ZipRegistry.h"
+#include "../Common/OpenArchive.h"
+#include "../Resource/Extract/resource.h"
+#include "../Explorer/MyMessages.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NDirectory;
+using namespace NName;
+
+static LPCWSTR kTempArchivePrefix = L"7zA";
+static LPCWSTR kTempFolderPrefix = L"7zE";
+static LPCWSTR kDefaultSfxModule = L"7zC.sfx";
+
+static void SplitString(const UString &srcString, UStringVector &destStrings)
+{
+ destStrings.Clear();
+ for (int pos = 0; pos < srcString.Length();)
+ {
+ int spacePos = srcString.Find(L' ', pos);
+ if (spacePos < 0)
+ {
+ destStrings.Add(srcString.Mid(pos));
+ return;
+ }
+ if (spacePos != pos)
+ destStrings.Add(srcString.Mid(pos, spacePos - pos));
+ pos = spacePos + 1;
+ }
+}
+
+static bool ParseNumberString(const UString &string, UINT32 &number)
+{
+ wchar_t *endPtr;
+ number = wcstoul(string, &endPtr, 10);
+ return (endPtr - string == string.Length());
+}
+
+static void SetOptions(const UString &options,
+ CObjectVector<CMyComBSTR> &realNames,
+ std::vector<NCOM::CPropVariant> &values)
+{
+ UStringVector strings;
+ SplitString(options, strings);
+ for(int i = 0; i < strings.Size(); i++)
+ {
+ const UString &s = strings[i];
+ int index = s.Find(L'=');
+ CMyComBSTR name;
+ NCOM::CPropVariant propVariant;
+ if (index < 0)
+ name = s;
+ else
+ {
+ name = s.Left(index);
+ UString value = s.Mid(index + 1);
+ if (!value.IsEmpty())
+ {
+ UINT32 number;
+ if (ParseNumberString(value, number))
+ propVariant = number;
+ else
+ propVariant = value;
+ }
+ }
+ realNames.Add(name);
+ values.push_back(propVariant);
+ }
+}
+
+static HRESULT SetOutProperties(IOutFolderArchive * outArchive,
+ bool is7z,
+ UINT32 level,
+ const UString &method,
+ UINT32 dictionary,
+ bool orderMode,
+ UINT32 order,
+ bool solidModeIsAllowed, bool solidMode,
+ bool multiThreadIsAllowed, bool multiThread,
+ bool encryptHeadersIsAllowed, bool encryptHeaders,
+ bool sfxMode,
+ const UString &options)
+{
+ CMyComPtr<ISetProperties> setProperties;
+ if (outArchive->QueryInterface(&setProperties) == S_OK)
+ {
+ CObjectVector<CMyComBSTR> realNames;
+ std::vector<NCOM::CPropVariant> values;
+ if (level != (UINT32)(INT32)-1)
+ {
+ CMyComBSTR comBSTR = L"x";
+ realNames.Add(comBSTR);
+ values.push_back(NCOM::CPropVariant((UINT32)level));
+ }
+ if (!method.IsEmpty())
+ {
+ CMyComBSTR comBSTR;
+ if (is7z)
+ comBSTR = L"0";
+ else
+ comBSTR = L"m";
+ realNames.Add(comBSTR);
+ values.push_back(NCOM::CPropVariant(method));
+ }
+ if (dictionary != (UINT32)(INT32)-1)
+ {
+ CMyComBSTR comBSTR;
+ if (is7z)
+ if (orderMode)
+ comBSTR = L"0mem";
+ else
+ comBSTR = L"0d";
+ else
+ if (orderMode)
+ comBSTR = L"mem";
+ else
+ comBSTR = L"d";
+ realNames.Add(comBSTR);
+ wchar_t s[32];
+ ConvertUINT64ToString(dictionary, s);
+ wcscat(s, L"B");
+ values.push_back(NCOM::CPropVariant(s));
+ }
+ if (order != (UINT32)(INT32)-1)
+ {
+ CMyComBSTR comBSTR;
+ if (is7z)
+ if (orderMode)
+ comBSTR = L"0o";
+ else
+ comBSTR = L"0fb";
+ else
+ if (orderMode)
+ comBSTR = L"o";
+ else
+ comBSTR = L"fb";
+ realNames.Add(comBSTR);
+ values.push_back(NCOM::CPropVariant((UINT32)order));
+ }
+
+ if (sfxMode)
+ {
+ realNames.Add(L"rsfx");
+ values.push_back(NCOM::CPropVariant(L"on"));
+ }
+
+ if (encryptHeadersIsAllowed)
+ {
+ if (encryptHeaders)
+ {
+ realNames.Add(L"he");
+ values.push_back(NCOM::CPropVariant(L"on"));
+ }
+ }
+
+ // Solid
+ if (solidModeIsAllowed)
+ {
+ realNames.Add(L"s");
+ values.push_back(NCOM::CPropVariant(solidMode ? L"on": L"off"));
+ }
+ if (multiThreadIsAllowed)
+ {
+ realNames.Add(L"mt");
+ values.push_back(NCOM::CPropVariant(multiThread ? L"on": L"off"));
+ }
+
+ // Options
+ SetOptions(options, realNames, values);
+
+ std::vector<BSTR> names;
+ for(int i = 0; i < realNames.Size(); i++)
+ names.push_back(realNames[i]);
+ RINOK(setProperties->SetProperties(&names.front(),
+ &values.front(), names.size()));
+ }
+ return S_OK;
+}
+
+struct CThreadUpdateCompress
+{
+ CMyComPtr<IOutFolderArchive> OutArchive;
+ UString LibPath;
+ CLSID ClassID;
+ UString OutArchivePath;
+ BYTE ActionSetByte[NUpdateArchive::NPairState::kNumValues];
+ bool SfxMode;
+ UString SfxModule;
+
+
+ UStringVector FileNames;
+ CRecordVector<const wchar_t *> FileNamePointers;
+ CMyComPtr<IFolderArchiveUpdateCallback> UpdateCallback;
+ CUpdateCallback100Imp *UpdateCallbackSpec;
+ HRESULT Result;
+
+ DWORD Process()
+ {
+ NCOM::CComInitializer comInitializer;
+ UpdateCallbackSpec->ProgressDialog.WaitCreating();
+ try
+ {
+ Result = OutArchive->DoOperation(
+ LibPath, &ClassID,
+ OutArchivePath, ActionSetByte,
+ (SfxMode ? (const wchar_t *)SfxModule: NULL),
+ UpdateCallback);
+ }
+ catch(const UString &s)
+ {
+ MyMessageBox(s);
+ Result = E_FAIL;
+ }
+ catch(...)
+ {
+ Result = E_FAIL;
+ }
+ UpdateCallbackSpec->ProgressDialog.MyClose();
+ return 0;
+ }
+
+ static DWORD WINAPI MyThreadFunction(void *param)
+ {
+ return ((CThreadUpdateCompress *)param)->Process();
+ }
+};
+
+static UString MakeFullArchiveName(const UString &name,
+ const UString &extension, bool sfx)
+{
+ if (sfx)
+ {
+ UString sfxExt = L".exe";
+ if (sfxExt.CollateNoCase(name.Right(sfxExt.Length())) == 0)
+ return name;
+ return name + sfxExt;
+ }
+
+ if (extension.IsEmpty())
+ return name;
+ if (name.IsEmpty())
+ return name;
+ if (name[name.Length() - 1] == '.')
+ return name.Left(name.Length() - 1);
+ int slash1Pos = name.ReverseFind(L'\\');
+ int slash2Pos = name.ReverseFind(L'/');
+ int slashPos = MyMax(slash1Pos, slash2Pos);
+ int dotPos = name.ReverseFind(L'.');
+ if (dotPos >= 0 && (dotPos > slashPos || slashPos < 0))
+ return name;
+ return name + UString(L'.') + extension;
+}
+
+HRESULT CompressArchive(
+ const UString &archivePath,
+ const UStringVector &fileNames,
+ const UString &archiveType,
+ bool email,
+ bool showDialog)
+{
+ if (fileNames.Size() == 0)
+ return S_OK;
+
+ CObjectVector<CArchiverInfo> archivers;
+ ReadArchiverInfoList(archivers);
+
+ CArchiverInfo archiverInfo;
+ UString password;
+ bool encryptHeadersIsAllowed = false;
+ bool encryptHeaders = false;
+ const NUpdateArchive::CActionSet *actionSet;
+ NCompressDialog::CInfo compressInfo;
+
+ UString tempDirPath;
+ UString currentDirPrefix;
+ bool needTempFile = true;
+ NDirectory::CTempDirectoryW tempDirectory;
+ UString archiveName;
+ int pos = archivePath.ReverseFind(L'\\');
+ if (pos < 0)
+ {
+ archiveName = archivePath;
+ MyGetCurrentDirectory(currentDirPrefix);
+ }
+ else
+ {
+ currentDirPrefix = archivePath.Left(pos + 1);
+ archiveName = archivePath.Mid(pos + 1);
+ }
+
+ if (email)
+ {
+ tempDirectory.Create(kTempFolderPrefix);
+ currentDirPrefix = tempDirectory.GetPath();
+ NormalizeDirPathPrefix(currentDirPrefix);
+ needTempFile = false;
+ }
+
+ if (showDialog)
+ {
+ bool oneFile = false;
+ NFind::CFileInfoW fileInfo;
+ if (!NFind::FindFile(fileNames.Front(), fileInfo))
+ return ::GetLastError();
+ if (fileNames.Size() == 1)
+ oneFile = !fileInfo.IsDirectory();
+
+ CCompressDialog dialog;
+ for(int i = 0; i < archivers.Size(); i++)
+ {
+ const CArchiverInfo &archiverInfo = archivers[i];
+ if (archiverInfo.UpdateEnabled &&
+ (oneFile || !archiverInfo.KeepName))
+ dialog.m_ArchiverInfoList.Add(archiverInfo);
+ }
+ if(dialog.m_ArchiverInfoList.Size() == 0)
+ {
+ MyMessageBox(L"No Update Engines");
+ return E_FAIL;
+ }
+ dialog.m_Info.ArchiveName = archiveName;
+ dialog.OriginalFileName = fileInfo.Name;
+
+ dialog.m_Info.CurrentDirPrefix = currentDirPrefix;
+ dialog.m_Info.SFXMode = false;
+ dialog.m_Info.Solid = true;
+ dialog.m_Info.MultiThread = false;
+
+ dialog.m_Info.KeepName = !oneFile;
+
+ if(dialog.Create(0) != IDOK)
+ return S_OK;
+
+ if (dialog.m_Info.VolumeSizeIsDefined)
+ {
+ MyMessageBox(L"Splitting to volumes is not supported");
+ return E_FAIL;
+ }
+
+ switch(dialog.m_Info.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[dialog.m_Info.ArchiverInfoIndex];
+ password = GetUnicodeString(dialog.Password);
+ encryptHeadersIsAllowed = dialog.EncryptHeadersIsAllowed;
+ encryptHeaders = dialog.EncryptHeaders;
+ compressInfo = dialog.m_Info;
+ compressInfo.ArchiveName = MakeFullArchiveName(
+ compressInfo.ArchiveName,
+ archiverInfo.GetMainExtension(), compressInfo.SFXMode);
+ }
+ else
+ {
+ int i;
+ for(i = 0; i < archivers.Size(); i++)
+ {
+ if (archivers[i].Name.CollateNoCase(archiveType) == 0)
+ {
+ archiverInfo = archivers[i];
+ break;
+ }
+ }
+ if (i == archivers.Size())
+ {
+ MyMessageBox(L"No archiver");
+ return E_FAIL;
+ }
+ actionSet = &NUpdateArchive::kAddActionSet;
+ bool is7z = (archiveType.CollateNoCase(L"7z") == 0);
+ compressInfo.SolidIsAllowed = is7z;
+ compressInfo.Solid = true;
+ compressInfo.MultiThreadIsAllowed = is7z;
+ compressInfo.MultiThread = false;
+ compressInfo.SFXMode = false;
+ compressInfo.KeepName = false;
+ compressInfo.ArchiveName = archiveName;
+ compressInfo.CurrentDirPrefix = currentDirPrefix;
+ compressInfo.Level = 5;
+ }
+ UString arcPath;
+ if (!compressInfo.GetFullPathName(arcPath))
+ {
+ MyMessageBox(L"Incorrect archive path");
+ return E_FAIL;
+ }
+ if (compressInfo.ArchiveName.Find('\\') >= 0)
+ {
+ needTempFile = true;
+ }
+
+ // MessageBox(0, arcPath, 0, 0);
+
+ NWorkDir::CInfo workDirInfo;
+ ReadWorkDirInfo(workDirInfo);
+ UString workDir = GetWorkDir(workDirInfo, arcPath);
+ NFile::NDirectory::CreateComplexDirectory(workDir);
+
+ NFile::NDirectory::CTempFileW tempFile;
+ UString tempFileName;
+ if (needTempFile)
+ {
+ if (tempFile.Create(workDir, kTempArchivePrefix, tempFileName) == 0)
+ return E_FAIL;
+ }
+ else
+ tempFileName = arcPath;
+
+
+ /*
+ const CLSID &classID =
+ dialog.m_ArchiverInfoList[dialog.m_Info.ArchiverInfoIndex].ClassID;
+ */
+ NFind::CFileInfoW fileInfo;
+
+ CMyComPtr<IOutFolderArchive> outArchive;
+
+ CMyComPtr<IInFolderArchive> archiveHandler;
+ if(NFind::FindFile(arcPath, fileInfo))
+ {
+ if (fileInfo.IsDirectory())
+ {
+ MyMessageBox(L"There is a folder with such name");
+ return E_FAIL;
+ }
+ CAgent *agentSpec = new CAgent;
+ archiveHandler = agentSpec;
+ // CLSID realClassID;
+ CMyComBSTR archiveType;
+ HRESULT result = agentSpec->Open(
+ GetUnicodeString(arcPath), &archiveType, NULL);
+ if (result == S_FALSE)
+ {
+ MyMessageBox(IDS_OPEN_IS_NOT_SUPORTED_ARCHIVE, 0x02000604);
+ return E_FAIL;
+ }
+ /*
+ HRESULT result = OpenArchive(arcPath, &archiveHandler,
+ archiverInfoResult, defaultName, NULL);
+ if (result == S_FALSE)
+ {
+ MyMessageBox(IDS_OPEN_IS_NOT_SUPORTED_ARCHIVE, 0x02000604);
+ return E_FAIL;
+ }
+ */
+ if (result != S_OK)
+ {
+ MyMessageBox(L"Open error");
+ return E_FAIL;
+ }
+ if (archiverInfo.Name.CollateNoCase((const wchar_t *)archiveType) != 0)
+ {
+ MyMessageBox(L"Type of existing archive differs from specified type");
+ return E_FAIL;
+ }
+ result = archiveHandler.QueryInterface(IID_IOutFolderArchive, &outArchive);
+ if(result != S_OK)
+ {
+ MyMessageBox(MyFormatNew(IDS_CANT_UPDATE_ARCHIVE, 0x02000602,
+ GetUnicodeString(arcPath)));
+ return E_FAIL;
+ }
+ }
+ else
+ {
+ CAgent *agentSpec = new CAgent;
+ outArchive = agentSpec;
+ }
+
+ CRecordVector<const wchar_t *> fileNamePointers;
+ fileNamePointers.Reserve(fileNames.Size());
+
+ int i;
+ for(i = 0; i < fileNames.Size(); i++)
+ fileNamePointers.Add(fileNames[i]);
+
+ outArchive->SetFolder(NULL);
+
+ // Don't uses CurrentFolder here, since files are absolute paths;
+ // MyGetCurrentDirectory(aCurrentFolder);
+
+ UINT codePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
+ outArchive->SetFiles(L"",
+ &fileNamePointers.Front(), fileNamePointers.Size());
+
+ CThreadUpdateCompress updater;
+ for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
+ updater.ActionSetByte[i] = actionSet->StateActions[i];
+ updater.UpdateCallbackSpec = new CUpdateCallback100Imp;
+ updater.UpdateCallback = updater.UpdateCallbackSpec;
+ updater.OutArchive = outArchive;
+ // updater.SrcFolderPrefix = srcPanel._currentFolderPrefix;
+
+ UString title = LangLoadStringW(IDS_PROGRESS_COMPRESSING, 0x02000DC0);
+ updater.UpdateCallbackSpec->Init(0, !password.IsEmpty(), password);
+
+ // UINT32 level = MyMin(compressInfo.Level, UINT32(9));
+ UINT32 level = compressInfo.Level;
+ HRESULT result = SetOutProperties(outArchive,
+ archiverInfo.Name.CompareNoCase(L"7z") == 0,
+ level,
+ compressInfo.Method,
+ compressInfo.Dictionary,
+ compressInfo.OrderMode, compressInfo.Order,
+ compressInfo.SolidIsAllowed, compressInfo.Solid,
+ compressInfo.MultiThreadIsAllowed, compressInfo.MultiThread,
+ encryptHeadersIsAllowed, encryptHeaders,
+ compressInfo.SFXMode,
+ GetUnicodeString(compressInfo.Options));
+
+ if (result != S_OK)
+ {
+ if (result != E_ABORT)
+ ShowErrorMessage(result);
+ return result;
+ }
+
+
+ UString sfxModule;
+ if (compressInfo.SFXMode)
+ {
+ UString sfxModule2;
+ LPCWSTR path = NULL;
+ UString sfxModule3;
+ if (GetProgramFolderPath(sfxModule3))
+ path = sfxModule3;
+ if (!NDirectory::MySearchPath(path, kDefaultSfxModule, NULL, sfxModule2))
+ {
+ MyMessageBox(L"can't find sfx module");
+ return E_FAIL;
+ }
+ sfxModule = sfxModule2;
+ }
+
+ updater.OutArchivePath = GetUnicodeString(tempFileName, codePage);
+ updater.SfxMode = compressInfo.SFXMode;
+ updater.SfxModule = sfxModule;
+ updater.LibPath = GetUnicodeString(archiverInfo.FilePath);
+ updater.ClassID = archiverInfo.ClassID;
+
+ CThread thread;
+ if (!thread.Create(CThreadUpdateCompress::MyThreadFunction, &updater))
+ throw 271824;
+ updater.UpdateCallbackSpec->StartProgressDialog(title);
+ result = updater.Result;
+
+ updater.UpdateCallback.Release();
+
+ updater.OutArchive.Release();
+ outArchive.Release();
+
+ if (result != S_OK)
+ {
+ if (result != E_ABORT)
+ ShowErrorMessage(result);
+ return result;
+ }
+
+ if(archiveHandler)
+ {
+ archiveHandler->Close();
+ if (!DeleteFileAlways(arcPath))
+ {
+ ShowLastErrorMessage();
+ return E_FAIL;
+ }
+ }
+ if (needTempFile)
+ {
+ tempFile.DisableDeleting();
+ if (!NDirectory::MyMoveFile(tempFileName, arcPath))
+ {
+ ShowLastErrorMessage();
+ return E_FAIL;
+ }
+ }
+
+ if (email)
+ {
+ NDLL::CLibrary mapiLib;
+ if (!mapiLib.Load(TEXT("Mapi32.dll")))
+ return E_FAIL;
+ LPMAPISENDDOCUMENTS fnSend = (LPMAPISENDDOCUMENTS)
+ mapiLib.GetProcAddress("MAPISendDocuments");
+ if (fnSend == 0)
+ return E_FAIL;
+
+ UString fileName;
+ GetOnlyName(arcPath, fileName);
+ AString path = GetAnsiString(arcPath);
+ AString name = GetAnsiString(fileName);
+ fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0);
+ }
+
+ return S_OK;
+}
diff --git a/7zip/UI/GUI/Compress.h b/7zip/UI/GUI/Compress.h
new file mode 100755
index 00000000..07562ee7
--- /dev/null
+++ b/7zip/UI/GUI/Compress.h
@@ -0,0 +1,17 @@
+// GUI/Compress.h
+
+#pragma once
+
+#ifndef __GUI_COMPRESS_H
+#define __GUI_COMPRESS_H
+
+#include "Common/String.h"
+
+HRESULT CompressArchive(
+ const UString &archivePath,
+ const UStringVector &fileNames,
+ const UString &archiveType,
+ bool email,
+ bool showDialog);
+
+#endif
diff --git a/7zip/UI/GUI/CompressDialog.cpp b/7zip/UI/GUI/CompressDialog.cpp
new file mode 100755
index 00000000..1b098d91
--- /dev/null
+++ b/7zip/UI/GUI/CompressDialog.cpp
@@ -0,0 +1,1233 @@
+// CompressDialog.cpp
+
+#include "StdAfx.h"
+
+#include "resource.h"
+#include "Common/Defs.h"
+#include "Common/StringConvert.h"
+#include "Common/StringToInt.h"
+#include "Common/IntToString.h"
+#include "Windows/FileDir.h"
+#include "Windows/FileName.h"
+#include "Windows/ResourceString.h"
+
+#include "../../FileManager/HelpUtils.h"
+#include "../Common/ZipRegistry.h"
+
+#include "CompressDialog.h"
+
+#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_PASSWORD, 0x02000802 },
+ { IDC_COMPRESS_CHECK_SHOW_PASSWORD, 0x02000B02 },
+ { 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,
+ kDeflate
+};
+
+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 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
+ },
+ {
+ k7zFormat,
+ (1 << 0) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
+ g_7zMethods, MY_SIZE_OF_ARRAY(g_7zMethods),
+ true, true, true, true, true
+ },
+ {
+ L"Zip",
+ (1 << 0) | (1 << 5) | (1 << 9),
+ g_ZipMethods, MY_SIZE_OF_ARRAY(g_ZipMethods) ,
+ false, false, false, true, false
+ },
+ {
+ L"GZip",
+ (1 << 5) | (1 << 9),
+ g_GZipMethods, MY_SIZE_OF_ARRAY(g_GZipMethods),
+ false, false, false, false, false
+ },
+ {
+ L"BZip2",
+ (1 << 5),
+ g_BZip2Methods,
+ MY_SIZE_OF_ARRAY(g_BZip2Methods),
+ false, false, false, false, false
+ },
+ {
+ L"Tar",
+ (1 << 0),
+ 0, 0,
+ false, false, false, false, false
+ }
+};
+
+class CDoubleZeroStringList
+{
+ CRecordVector<int> m_Indexes;
+ CSysString m_String;
+public:
+ void Add(LPCTSTR s);
+ void SetForBuffer(LPTSTR buffer);
+};
+
+const TCHAR kDelimiterSymbol = TEXT(' ');
+void CDoubleZeroStringList::Add(LPCTSTR s)
+{
+ m_String += s;
+ m_Indexes.Add(m_String.Length());
+ m_String += kDelimiterSymbol;
+}
+
+void CDoubleZeroStringList::SetForBuffer(LPTSTR buffer)
+{
+ lstrcpy(buffer, m_String);
+ for (int i = 0; i < m_Indexes.Size(); i++)
+ buffer[m_Indexes[i]] = TEXT('\0');
+}
+
+
+bool CCompressDialog::OnInit()
+{
+ #ifdef LANG
+ LangSetWindowText(HWND(*this), 0x02000D00);
+ LangSetDlgItemsText(HWND(*this), kIDLangPairs, MY_SIZE_OF_ARRAY(kIDLangPairs) );
+ #endif
+ _passwordControl.Attach(GetItem(IDC_COMPRESS_EDIT_PASSWORD));
+ _passwordControl.SetText(TEXT(""));
+
+ 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));
+
+ m_Volume.AddString(TEXT("1457664 - 3.5 Floppy"));
+ m_Volume.AddString(TEXT("650M - CD-650MB"));
+ m_Volume.AddString(TEXT("700M - CD-700MB"));
+
+ ReadCompressionInfo(m_RegistryInfo);
+ CheckButton(IDC_COMPRESS_CHECK_SHOW_PASSWORD, m_RegistryInfo.ShowPassword);
+ CheckButton(IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES, m_RegistryInfo.EncryptHeaders);
+
+ UpdatePasswordControl();
+
+ m_Info.ArchiverInfoIndex = 0;
+ int i;
+ for(i = 0; i < m_ArchiverInfoList.Size(); i++)
+ {
+ const CArchiverInfo &ai = m_ArchiverInfoList[i];
+ m_Format.AddString(GetSystemString(ai.Name));
+ if (ai.Name.CollateNoCase(
+ m_RegistryInfo.ArchiveType) == 0)
+ m_Info.ArchiverInfoIndex = i;
+ }
+ m_Format.SetCurSel(m_Info.ArchiverInfoIndex);
+
+ SetArchiveName(m_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(LangLoadString(IDS_COMPRESS_UPDATE_MODE_ADD, 0x02000DA1));
+ m_UpdateMode.AddString(LangLoadString(IDS_COMPRESS_UPDATE_MODE_UPDATE, 0x02000DA2));
+ m_UpdateMode.AddString(LangLoadString(IDS_COMPRESS_UPDATE_MODE_FRESH, 0x02000DA3));
+ m_UpdateMode.AddString(LangLoadString(IDS_COMPRESS_UPDATE_MODE_SYNCHRONIZE, 0x02000DA4));
+
+ m_UpdateMode.SetCurSel(0);
+
+ m_Info.Solid = m_RegistryInfo.Solid;
+ m_Info.MultiThread = m_RegistryInfo.MultiThread;
+
+ CheckButton(IDC_COMPRESS_SOLID, m_Info.Solid);
+ CheckButton(IDC_COMPRESS_MULTI_THREAD, m_Info.MultiThread);
+ CheckButton(IDC_COMPRESS_SFX, m_Info.SFXMode);
+
+ CheckControlsEnable();
+
+ OnButtonSFX();
+
+ return CModalDialog::OnInit();
+}
+
+namespace NCompressDialog
+{
+ bool CInfo::GetFullPathName(UString &result) const
+ {
+ NDirectory::MySetCurrentDirectory(CurrentDirPrefix);
+ return MyGetFullPathName(ArchiveName, result);
+ }
+}
+
+void CCompressDialog::UpdatePasswordControl()
+{
+ _passwordControl.SetPasswordChar((IsButtonChecked(
+ IDC_COMPRESS_CHECK_SHOW_PASSWORD) == BST_CHECKED) ? 0: TEXT('*'));
+ CSysString password;
+ _passwordControl.GetText(password);
+ _passwordControl.SetText(password);
+}
+
+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;
+ }
+ }
+ return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
+}
+
+static bool IsMultiProcessor()
+{
+ SYSTEM_INFO systemInfo;
+ GetSystemInfo(&systemInfo);
+ return systemInfo.dwNumberOfProcessors > 1;
+}
+
+void CCompressDialog::CheckSFXControlsEnable()
+{
+ const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()];
+ bool enable = fi.SFX;
+ if (enable)
+ {
+ switch(GetMethodID())
+ {
+ case -1:
+ case kLZMA:
+ case kPPMd:
+ case kCopy:
+ break;
+ default:
+ enable = false;
+ }
+ }
+ if (!enable)
+ CheckButton(IDC_COMPRESS_SFX, false);
+ EnableItem(IDC_COMPRESS_SFX, enable);
+}
+
+void CCompressDialog::CheckControlsEnable()
+{
+ const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()];
+ m_Info.SolidIsAllowed = fi.Solid;
+ bool multiThreadEnable = fi.MultiThread & IsMultiProcessor();
+ m_Info.MultiThreadIsAllowed = multiThreadEnable;
+ EncryptHeadersIsAllowed = fi.EncryptFileNames;
+
+ EnableItem(IDC_COMPRESS_SOLID, fi.Solid);
+ EnableItem(IDC_COMPRESS_MULTI_THREAD, multiThreadEnable);
+ CheckSFXControlsEnable();
+
+ // EnableItem(IDC_STATIC_COMPRESS_VOLUME, enable);
+ // EnableItem(IDC_COMPRESS_COMBO_VOLUME, enable);
+
+ EnableItem(IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES, fi.EncryptFileNames);
+ EnableItem(IDC_COMPRESS_PASSWORD, fi.Encrypt);
+ EnableItem(IDC_COMPRESS_EDIT_PASSWORD, fi.Encrypt);
+ EnableItem(IDC_COMPRESS_CHECK_SHOW_PASSWORD, fi.Encrypt);
+}
+
+bool CCompressDialog::IsSFX()
+{
+ CWindow sfxButton = GetItem(IDC_COMPRESS_SFX);
+ return sfxButton.IsEnabled() && IsButtonCheckedBool(IDC_COMPRESS_SFX);
+}
+
+void CCompressDialog::OnButtonSFX()
+{
+ UString fileName;
+ m_ArchivePath.GetText(fileName);
+ int dotPos = fileName.ReverseFind(L'.');
+ int slashPos = fileName.ReverseFind(L'\\');
+ if (dotPos < 0 || dotPos <= slashPos)
+ dotPos = -1;
+ 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
+ }
+}
+
+void CCompressDialog::OnButtonSetArchive()
+{
+ const int kBufferSize = MAX_PATH * 2;
+ TCHAR buffer[kBufferSize];
+ UString fileName;
+ m_ArchivePath.GetText(fileName);
+ fileName.TrimLeft();
+ fileName.TrimRight();
+ m_Info.ArchiveName = fileName;
+ UString fullFileName;
+ if (!m_Info.GetFullPathName(fullFileName))
+ {
+ fullFileName = m_Info.ArchiveName;
+ // throw "Incorrect archive path";
+ return;
+ }
+ lstrcpy(buffer, GetSystemString(fullFileName));
+
+ OPENFILENAME info;
+ info.lStructSize = sizeof(info);
+ info.hwndOwner = HWND(*this);
+ info.hInstance = 0;
+
+
+ const int kFilterBufferSize = MAX_PATH;
+ TCHAR filterBuffer[kFilterBufferSize];
+ CDoubleZeroStringList doubleZeroStringList;
+ // doubleZeroStringList.Add(TEXT("Zip Files (*.zip)"));
+ // doubleZeroStringList.Add(TEXT("*.zip"));
+ UString s = LangLoadStringW(IDS_OPEN_TYPE_ALL_FILES, 0x02000DB1);
+ s += L" (*.*)";
+ doubleZeroStringList.Add(GetSystemString(s));
+ doubleZeroStringList.Add(TEXT("*.*"));
+ doubleZeroStringList.SetForBuffer(filterBuffer);
+ info.lpstrFilter = filterBuffer;
+
+
+ info.lpstrCustomFilter = NULL;
+ info.nMaxCustFilter = 0;
+ info.nFilterIndex = 0;
+
+ info.lpstrFile = buffer;
+ info.nMaxFile = kBufferSize;
+
+ info.lpstrFileTitle = NULL;
+ info.nMaxFileTitle = 0;
+
+ info.lpstrInitialDir= NULL;
+
+ CSysString title = LangLoadString(IDS_COMPRESS_SET_ARCHIVE_DIALOG_TITLE, 0x02000D90);
+
+ info.lpstrTitle = title;
+
+ info.Flags = OFN_EXPLORER | OFN_HIDEREADONLY;
+ info.nFileOffset = 0;
+ info.nFileExtension = 0;
+ info.lpstrDefExt = NULL;
+
+ info.lCustData = 0;
+ info.lpfnHook = NULL;
+ info.lpTemplateName = NULL;
+
+ if(!GetOpenFileName(&info))
+ return;
+ m_ArchivePath.SetText(buffer);
+}
+
+// in ExtractDialog.cpp
+extern void AddUniqueString(CSysStringVector &strings, const CSysString &srcString);
+
+bool ParseVolumeSize(const CSysString &s, UINT64 &value)
+{
+ const TCHAR *start = s;
+ const TCHAR *end;
+ value = ConvertStringToUINT64(start, &end);
+ if (start == end)
+ return false;
+ while (true)
+ {
+ TCHAR c = *end++;
+ c = MyCharUpper(c);
+ switch(c)
+ {
+ case TEXT('\0'):
+ case TEXT('B'):
+ return true;
+ case TEXT('K'):
+ value <<= 10;
+ return true;
+ case TEXT('M'):
+ value <<= 20;
+ return true;
+ case TEXT('G'):
+ value <<= 30;
+ return true;
+ case TEXT(' '):
+ continue;
+ default:
+ return true;
+ }
+ }
+}
+
+void CCompressDialog::OnOK()
+{
+ _passwordControl.GetText(Password);
+
+ SaveOptionsInMem();
+ int currentItem = m_ArchivePath.GetCurSel();
+ UString s;
+ if(currentItem == CB_ERR)
+ {
+ m_ArchivePath.GetText(s);
+ if(m_ArchivePath.GetCount() >= kHistorySize)
+ currentItem = m_ArchivePath.GetCount() - 1;
+ }
+ else
+ {
+ CSysString sTemp;
+ m_ArchivePath.GetLBText(currentItem, sTemp);
+ s = GetUnicodeString(sTemp);
+ }
+ s.Trim();
+ m_RegistryInfo.HistoryArchives.Clear();
+ AddUniqueString(m_RegistryInfo.HistoryArchives, GetSystemString(s));
+ m_Info.ArchiveName = s;
+ m_Info.UpdateMode = NCompressDialog::NUpdateMode::EEnum(m_UpdateMode.GetCurSel());
+
+ m_Info.Level = GetLevelSpec();
+ m_Info.Dictionary = GetDictionarySpec();
+ m_Info.Order = GetOrderSpec();
+ m_Info.OrderMode = GetOrderMode();
+ m_Info.Method = GetUnicodeString(GetMethodSpec());
+
+ m_Info.ArchiverInfoIndex = m_Format.GetCurSel();
+
+ m_Info.SFXMode = IsSFX();
+ m_RegistryInfo.Solid = m_Info.Solid = IsButtonCheckedBool(IDC_COMPRESS_SOLID);
+ m_RegistryInfo.MultiThread = m_Info.MultiThread = IsButtonCheckedBool(IDC_COMPRESS_MULTI_THREAD);
+ m_RegistryInfo.EncryptHeaders = EncryptHeaders = IsButtonCheckedBool(IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES);
+
+ m_Params.GetText(m_Info.Options);
+ CSysString volumeString;
+ m_Volume.GetText(volumeString);
+ volumeString.Trim();
+ m_Info.VolumeSizeIsDefined = ParseVolumeSize(
+ volumeString, m_Info.VolumeSize);
+ /*
+ if (!m_Info.VolumeSizeIsDefined && !volumeString.IsEmpty())
+ MessageBox(0, TEXT("Incorrect volume size"), TEXT("7-Zip"), 0);
+ */
+
+ for(int i = 0; i < m_ArchivePath.GetCount(); i++)
+ if(i != currentItem)
+ {
+ CSysString sTemp;
+ m_ArchivePath.GetLBText(i, sTemp);
+ sTemp.Trim();
+ AddUniqueString(m_RegistryInfo.HistoryArchives, sTemp);
+ }
+
+ ////////////////////
+ // Method
+
+ m_RegistryInfo.Level = m_Info.Level;
+ m_RegistryInfo.ArchiveType = m_ArchiverInfoList[m_Info.ArchiverInfoIndex].Name;
+
+ m_RegistryInfo.ShowPassword = (IsButtonChecked(
+ IDC_COMPRESS_CHECK_SHOW_PASSWORD) == BST_CHECKED);
+
+ 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.Init();
+ 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 || m_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);
+}
+
+void CCompressDialog::SetArchiveName(const UString &name)
+{
+ UString fileName = name;
+ m_Info.ArchiverInfoIndex = m_Format.GetCurSel();
+ const CArchiverInfo &ai = m_ArchiverInfoList[m_Info.ArchiverInfoIndex];
+ m_PrevFormat = m_Info.ArchiverInfoIndex;
+ if (ai.KeepName)
+ {
+ fileName = OriginalFileName;
+ }
+ else
+ {
+ if (!m_Info.KeepName)
+ {
+ int dotPos = fileName.ReverseFind('.');
+ int slashPos = MyMax(fileName.ReverseFind('\\'), fileName.ReverseFind('/'));
+ if (dotPos > slashPos)
+ 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 (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 = m_Level.AddString(LangLoadString(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 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;
+}
+
+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 = GetUnicodeString(fo.Method);
+ }
+ for(int m = 0; m < fi.NumMethods; m++)
+ {
+ const LPCWSTR method = kMethodsNames[fi.MathodIDs[m]];
+ int itemIndex = m_Method.AddString(GetSystemString(method));
+ if (defaultMethod.CompareNoCase(method) == 0 || m == 0)
+ m_Method.SetCurSel(itemIndex);
+ }
+ SetDictionary();
+ SetOrder();
+}
+
+int CCompressDialog::GetMethodID()
+{
+ CSysString methodSpec;
+ m_Method.GetText(methodSpec);
+ UString methodName = GetUnicodeString(methodSpec);
+ for (int i = 0; i < MY_SIZE_OF_ARRAY(kMethodsNames); i++)
+ if (methodName.CompareNoCase(kMethodsNames[i]) == 0)
+ return i;
+ return -1;
+}
+
+CSysString CCompressDialog::GetMethodSpec()
+{
+ if (m_Method.GetCount() <= 1)
+ return CSysString();
+ CSysString result;
+ m_Method.GetText(result);
+ 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 = 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 CFormatInfo &fi = g_Formats[GetStaticFormatIndex()];
+ 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.CollateNoCase(GetMethodSpec()) == 0)
+ defaultDictionary = fo.Dictionary;
+ }
+ int methodID = GetMethodID();
+ int level = GetLevel2();
+ if (methodID < 0)
+ {
+ SetMemoryUsage();
+ return;
+ }
+ switch (methodID)
+ {
+ case kLZMA:
+ {
+ if (defaultDictionary == UINT32(-1))
+ {
+ if (level >= 9)
+ defaultDictionary = (32 << 20);
+ else if (level >= 7)
+ defaultDictionary = (8 << 20);
+ else if (level >= 5)
+ defaultDictionary = (2 << 20);
+ else
+ defaultDictionary = (32 << 10);
+ }
+ int i;
+ AddDictionarySize(32 << 10);
+ for (i = 20; i < 28; i++)
+ for (int j = 0; j < 2; j++)
+ {
+ if (i == 20 && j > 0)
+ continue;
+ UINT32 dictionary = (1 << i) + (j << (i - 1));
+ AddDictionarySize(dictionary);
+ }
+ 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 = (24 << 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);
+ }
+ 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:
+ {
+ AddDictionarySize(900 << 10);
+ m_Dictionary.SetCurSel(0);
+ break;
+ }
+ }
+ SetMemoryUsage();
+}
+
+UINT32 CCompressDialog::GetDictionary()
+{
+ if (m_Dictionary.GetCount() <= 0)
+ return -1;
+ return m_Dictionary.GetItemData(m_Dictionary.GetCurSel());
+}
+
+UINT32 CCompressDialog::GetDictionarySpec()
+{
+ if (m_Dictionary.GetCount() <= 1)
+ return -1;
+ return GetDictionary();
+}
+
+int CCompressDialog::AddOrder(UINT32 size)
+{
+ TCHAR s[40];
+ ConvertUINT64ToString(size, s);
+ int index = m_Order.AddString(s);
+ m_Order.SetItemData(index, size);
+ return index;
+}
+
+void CCompressDialog::SetOrder()
+{
+ m_Order.ResetContent();
+ const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()];
+ 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.CollateNoCase(GetMethodSpec()) == 0)
+ defaultOrder = fo.Order;
+ }
+ int methodID = GetMethodID();
+ int level = GetLevel2();
+ if (methodID < 0)
+ {
+ SetMemoryUsage();
+ return;
+ }
+ switch (methodID)
+ {
+ case kLZMA:
+ {
+ if (defaultOrder == UINT32(-1))
+ {
+ 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 < 255)
+ AddOrder(order);
+ }
+ AddOrder(255);
+ 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 >= 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 < 255)
+ AddOrder(order);
+ }
+ AddOrder(255);
+ SetNearestSelectComboBox(m_Order, defaultOrder);
+ break;
+ }
+ case kBZip2:
+ {
+ break;
+ }
+ }
+ SetMemoryUsage();
+}
+
+bool CCompressDialog::GetOrderMode()
+{
+ switch (GetMethodID())
+ {
+ case kLZMA:
+ case kDeflate:
+ case kDeflate64:
+ return false;
+ case kPPMd:
+ return true;
+ }
+ return false;
+}
+
+UINT32 CCompressDialog::GetOrder()
+{
+ if (m_Order.GetCount() <= 0)
+ return -1;
+ return m_Order.GetItemData(m_Order.GetCurSel());
+}
+
+UINT32 CCompressDialog::GetOrderSpec()
+{
+ if (m_Order.GetCount() <= 1)
+ return -1;
+ return GetOrder();
+}
+
+UINT64 CCompressDialog::GetMemoryUsage(UINT64 &decompressMemory)
+{
+ decompressMemory = UINT64(INT64(-1));
+ UINT32 dictionary = GetDictionary();
+ int level = GetLevel2();
+ if (level == 0)
+ {
+ decompressMemory = (1 << 20);
+ return decompressMemory;
+ }
+ switch (GetMethodID())
+ {
+ case kLZMA:
+ {
+ UINT64 size;
+ if (level >= 5)
+ {
+ size = ((UINT64)dictionary * 19 / 2) + (2 << 20);
+ if (level >= 9)
+ size += (34 << 20) + (12 << 20) * 2 + (5 << 20);
+ else
+ size += (6 << 20);
+ }
+ else
+ size = ((UINT64)dictionary * 11 / 2) + (2 << 20);
+ decompressMemory = dictionary + (2 << 20);
+ return size;
+ }
+ case kPPMd:
+ {
+ decompressMemory = dictionary + (2 << 20);
+ return decompressMemory;
+ }
+ case kDeflate:
+ case kDeflate64:
+ {
+ UINT32 order = GetOrder();
+ if (order == UINT32(-1))
+ order = 32;
+ UINT64 size = 0;
+ if (level >= 7)
+ size = (order * 2 + 4) * (64 << 10);
+ size += 3 << 20;
+ decompressMemory = (2 << 20);
+ return size;
+ }
+ case kBZip2:
+ {
+ decompressMemory = (7 << 20);
+ return 10 << 20;
+ }
+ }
+ return UINT64(INT64(-1));
+}
+
+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[m_Info.ArchiverInfoIndex];
+ int index = FindRegistryFormatAlways(ai.Name);
+ m_Params.GetText(m_Info.Options);
+ m_Info.Options.Trim();
+ NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index];
+ fo.Options = m_Info.Options;
+ fo.Level = GetLevelSpec();
+ fo.Dictionary = GetDictionarySpec();
+ fo.Order = GetOrderSpec();
+ fo.Method = GetMethodSpec();
+}
diff --git a/7zip/UI/GUI/CompressDialog.h b/7zip/UI/GUI/CompressDialog.h
new file mode 100755
index 00000000..6662c683
--- /dev/null
+++ b/7zip/UI/GUI/CompressDialog.h
@@ -0,0 +1,161 @@
+// CompressDialog.h
+
+#pragma once
+
+#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;
+
+ bool VolumeSizeIsDefined;
+ UINT64 VolumeSize;
+
+ UINT32 Level;
+ UString Method;
+ UINT32 Dictionary;
+ bool OrderMode;
+ UINT32 Order;
+ CSysString Options;
+
+ bool SFXMode;
+
+ UString ArchiveName; // in: Relative for ; out: abs
+ UString CurrentDirPrefix;
+ bool KeepName;
+
+ bool GetFullPathName(UString &result) const;
+
+ int ArchiverInfoIndex;
+
+ void Init()
+ {
+ Level = Dictionary = Order = UINT32(-1);
+ OrderMode = false;
+ Method.Empty();
+ Options.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 _passwordControl;
+
+
+ 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();
+
+ void SetMethod();
+ int GetMethodID();
+ CSysString GetMethodSpec();
+
+ AddDictionarySize(UINT32 size, bool kilo, bool maga);
+ AddDictionarySize(UINT32 size);
+
+ void SetDictionary();
+ UINT32 GetDictionary();
+ UINT32 GetDictionarySpec();
+
+ int AddOrder(UINT32 size);
+ void SetOrder();
+ bool GetOrderMode();
+ UINT32 GetOrder();
+ UINT32 GetOrderSpec();
+
+ UINT64 GetMemoryUsage(UINT64 &decompressMemory);
+ void PrintMemUsage(UINT res, UINT64 value);
+ void SetMemoryUsage();
+ void SetParams();
+ void SaveOptionsInMem();
+
+ void UpdatePasswordControl();
+public:
+ CObjectVector<CArchiverInfo> m_ArchiverInfoList;
+
+ NCompressDialog::CInfo m_Info;
+ UString OriginalFileName; // for bzip2, gzip2
+
+ CSysString Password;
+ bool EncryptHeadersIsAllowed;
+ bool EncryptHeaders;
+
+ INT_PTR Create(HWND wndParent = 0)
+ { return CModalDialog::Create(MAKEINTRESOURCE(IDD_DIALOG_COMPRESS ), wndParent); }
+
+protected:
+
+ void CheckSFXControlsEnable();
+ 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/7zip/UI/GUI/Extract.cpp b/7zip/UI/GUI/Extract.cpp
new file mode 100755
index 00000000..f8ed33af
--- /dev/null
+++ b/7zip/UI/GUI/Extract.cpp
@@ -0,0 +1,225 @@
+// Extract.h
+
+#include "StdAfx.h"
+
+#include "Extract.h"
+
+#include "Common/StringConvert.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/Error.h"
+#include "Windows/FileFind.h"
+#ifndef EXCLUDE_COM
+#include "Windows/DLL.h"
+#endif
+#include "Windows/Thread.h"
+
+#include "../Common/OpenArchive.h"
+#include "../Common/DefaultName.h"
+
+#ifndef EXCLUDE_COM
+#include "../Common/ZipRegistry.h"
+#endif
+
+#include "../Resource/Extract/resource.h"
+
+#include "../Explorer/MyMessages.h"
+#include "../../FileManager/FormatUtils.h"
+
+#include "ExtractDialog.h"
+#include "../../FileManager/ExtractCallback.h"
+
+#include "../Agent/ArchiveExtractCallback.h"
+
+#include "../../FileManager/OpenCallback.h"
+
+using namespace NWindows;
+
+struct CThreadExtracting
+{
+ #ifndef EXCLUDE_COM
+ NDLL::CLibrary Library;
+ #endif
+ CMyComPtr<IInArchive> Archive;
+ CExtractCallbackImp *ExtractCallbackSpec;
+ CMyComPtr<IFolderArchiveExtractCallback> ExtractCallback2;
+ CMyComPtr<IArchiveExtractCallback> ArchiveExtractCallback;
+
+ HRESULT Result;
+
+ DWORD Process()
+ {
+ ExtractCallbackSpec->ProgressDialog.WaitCreating();
+ Result = Archive->Extract(0, -1, BoolToInt(false),
+ ArchiveExtractCallback);
+ ExtractCallbackSpec->ProgressDialog.MyClose();
+ return 0;
+ }
+ static DWORD WINAPI MyThreadFunction(void *param)
+ {
+ return ((CThreadExtracting *)param)->Process();
+ }
+};
+
+static inline UINT GetCurrentFileCodePage()
+ { return AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
+
+HRESULT ExtractArchive(HWND parentWindow, const UString &fileName,
+ bool assumeYes, bool showDialog, const UString &outputFolder)
+{
+ CThreadExtracting extracter;
+
+ CArchiverInfo archiverInfo;
+
+ COpenArchiveCallback *openCallbackSpec = new COpenArchiveCallback;
+ CMyComPtr<IArchiveOpenCallback> openCallback = openCallbackSpec;
+ openCallbackSpec->_passwordIsDefined = false;
+ openCallbackSpec->_parentWindow = parentWindow;
+
+ UString fullName;
+ int fileNamePartStartIndex;
+ NFile::NDirectory::MyGetFullPathName(fileName, fullName, fileNamePartStartIndex);
+
+ openCallbackSpec->LoadFileInfo(
+ fullName.Left(fileNamePartStartIndex),
+ fullName.Mid(fileNamePartStartIndex));
+
+ int subExtIndex;
+ HRESULT res = OpenArchive(fileName,
+ #ifndef EXCLUDE_COM
+ &extracter.Library,
+ #endif
+ &extracter.Archive, archiverInfo, subExtIndex, openCallback);
+ RINOK(res);
+
+ NFile::NFind::CFileInfoW fileInfo;
+ if (!NFile::NFind::FindFile(fileName, fileInfo))
+ return E_FAIL;
+ UString defaultName = GetDefaultName(fileName,
+ archiverInfo.Extensions[subExtIndex].Extension,
+ archiverInfo.Extensions[subExtIndex].AddExtension);
+
+ UString directoryPath;
+ NExtractionDialog::CModeInfo extractModeInfo;
+ UString password;
+ if (openCallbackSpec->_passwordIsDefined)
+ password = openCallbackSpec->_password;
+ if (showDialog)
+ {
+ CExtractDialog dialog;
+ if (!NFile::NDirectory::MyGetFullPathName(outputFolder, dialog.DirectoryPath))
+ {
+ MyMessageBox(L"Error 32432432");
+ return E_FAIL;
+ }
+ // dialog.DirectoryPath = outputFolder;
+ // dialog.FilesMode = NExtractionDialog::NFilesMode::kAll;
+ // dialog._enableSelectedFilesButton = false;
+ dialog.Password = password;
+
+ if(dialog.Create(parentWindow) != IDOK)
+ return E_ABORT;
+ directoryPath = dialog.DirectoryPath;
+ dialog.GetModeInfo(extractModeInfo);
+
+ password = dialog.Password;
+ }
+ else
+ {
+ if (!NFile::NDirectory::MyGetFullPathName(outputFolder, directoryPath))
+ {
+ MyMessageBox(L"Error 98324982");
+ return E_FAIL;
+ }
+ NFile::NName::NormalizeDirPathPrefix(directoryPath);
+
+ extractModeInfo.PathMode = NExtractionDialog::NPathMode::kFullPathnames;
+ extractModeInfo.OverwriteMode = assumeYes ?
+ NExtractionDialog::NOverwriteMode::kWithoutPrompt:
+ NExtractionDialog::NOverwriteMode::kAskBefore;
+ // extractModeInfo.FilesMode = NExtractionDialog::NFilesMode::kAll;
+ }
+ if(!NFile::NDirectory::CreateComplexDirectory(directoryPath))
+ {
+ UString s = GetUnicodeString(NError::MyFormatMessage(GetLastError()));
+ UString s2 = MyFormatNew(IDS_CANNOT_CREATE_FOLDER,
+ #ifdef LANG
+ 0x02000603,
+ #endif
+ directoryPath);
+ MyMessageBox(s2 + UString(L"\n") + s);
+ return E_FAIL;
+ }
+
+ extracter.ExtractCallbackSpec = new CExtractCallbackImp;
+
+ extracter.ExtractCallback2 = extracter.ExtractCallbackSpec;
+
+ extracter.ExtractCallbackSpec->_parentWindow = 0;
+ #ifdef LANG
+ const UString title = LangLoadStringW(IDS_PROGRESS_EXTRACTING, 0x02000890);
+ #else
+ const UString title = NWindows::MyLoadStringW(IDS_PROGRESS_EXTRACTING);
+ #endif
+
+ NFile::NFind::CFileInfoW archiveFileInfo;
+ if (!NFile::NFind::FindFile(fileName, archiveFileInfo))
+ throw "there is no archive file";
+
+ extracter.ExtractCallbackSpec->Init(NExtractionMode::NOverwrite::kAskBefore,
+ !password.IsEmpty(), password);
+
+ NExtractionMode::NPath::EEnum pathMode;
+ NExtractionMode::NOverwrite::EEnum overwriteMode;
+ switch (extractModeInfo.OverwriteMode)
+ {
+ case NExtractionDialog::NOverwriteMode::kAskBefore:
+ overwriteMode = NExtractionMode::NOverwrite::kAskBefore;
+ break;
+ case NExtractionDialog::NOverwriteMode::kWithoutPrompt:
+ overwriteMode = NExtractionMode::NOverwrite::kWithoutPrompt;
+ break;
+ case NExtractionDialog::NOverwriteMode::kSkipExisting:
+ overwriteMode = NExtractionMode::NOverwrite::kSkipExisting;
+ break;
+ case NExtractionDialog::NOverwriteMode::kAutoRename:
+ overwriteMode = NExtractionMode::NOverwrite::kAutoRename;
+ break;
+ default:
+ throw 12334454;
+ }
+ switch (extractModeInfo.PathMode)
+ {
+ case NExtractionDialog::NPathMode::kFullPathnames:
+ pathMode = NExtractionMode::NPath::kFullPathnames;
+ break;
+ case NExtractionDialog::NPathMode::kCurrentPathnames:
+ pathMode = NExtractionMode::NPath::kCurrentPathnames;
+ break;
+ case NExtractionDialog::NPathMode::kNoPathnames:
+ pathMode = NExtractionMode::NPath::kNoPathnames;
+ break;
+ default:
+ throw 12334455;
+ }
+
+ CArchiveExtractCallback *extractCallbackSpec = new
+ CArchiveExtractCallback;
+ extracter.ArchiveExtractCallback = extractCallbackSpec;
+
+ extractCallbackSpec->Init(extracter.Archive,
+ extracter.ExtractCallback2,
+ directoryPath, pathMode,
+ overwriteMode, UStringVector(),
+ defaultName,
+ fileInfo.LastWriteTime, fileInfo.Attributes);
+
+ CThread thread;
+ if (!thread.Create(CThreadExtracting::MyThreadFunction, &extracter))
+ throw 271824;
+ extracter.ExtractCallbackSpec->StartProgressDialog(title);
+ return extracter.Result;
+}
+
+
+
diff --git a/7zip/UI/GUI/Extract.h b/7zip/UI/GUI/Extract.h
new file mode 100755
index 00000000..0c2b6dbe
--- /dev/null
+++ b/7zip/UI/GUI/Extract.h
@@ -0,0 +1,12 @@
+// GUI/Extract.h
+
+#ifndef __GUI_EXTRACT_H
+#define __GUI_EXTRACT_H
+
+#include "Common/String.h"
+
+HRESULT ExtractArchive(HWND parentWindow, const UString &fileName,
+ bool assumeYes, bool showDialog, const UString &outputFolder);
+
+#endif
+
diff --git a/7zip/UI/GUI/ExtractDialog.cpp b/7zip/UI/GUI/ExtractDialog.cpp
new file mode 100755
index 00000000..322b22f8
--- /dev/null
+++ b/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"
+
+#ifdef LANG
+#include "../../FileManager/LangUtils.h"
+#endif
+
+#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 kPathnamesButtons[] =
+{
+ IDC_EXTRACT_RADIO_FULL_PATHNAMES,
+ IDC_EXTRACT_RADIO_CURRENT_PATHNAMES,
+ IDC_EXTRACT_RADIO_NO_PATHNAMES
+};
+static const int kNumPathnamesButtons = sizeof(kPathnamesButtons) / sizeof(kPathnamesButtons[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
+};
+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
+int CExtractDialog::GetPathNameMode() const
+{
+ for (int i = 0; i < kNumPathnamesButtons; i++)
+ if(IsButtonCheckedBool(kPathnamesButtons[i]))
+ return i;
+ throw 0;
+}
+
+int CExtractDialog::GetOverwriteMode() const
+{
+ for (int i = 0; i < kNumOverwriteButtons; i++)
+ if(IsButtonCheckedBool(kOverwriteButtons[i]))
+ return i;
+ throw 0;
+}
+
+/*
+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_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
+
+ NExtraction::CInfo extractionInfo;
+
+ #ifdef NO_REGISTRY
+ extractionInfo.PathMode = NExtraction::NPathMode::kFullPathnames;
+ extractionInfo.OverwriteMode = NExtraction::NOverwriteMode::kAskBefore;
+ // extractionInfo.Paths = NExtraction::NPathMode::kFullPathnames;
+ #else
+ ReadExtractionInfo(extractionInfo);
+ CheckButton(IDC_EXTRACT_CHECK_SHOW_PASSWORD, extractionInfo.ShowPassword);
+ UpdatePasswordControl();
+ #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);
+ */
+
+
+ _pathMode = extractionInfo.PathMode;
+ _overwriteMode = extractionInfo.OverwriteMode;
+
+ #ifndef _SFX
+ CheckRadioButton(kPathnamesButtons[0], kPathnamesButtons[kNumPathnamesButtons - 1],
+ kPathnamesButtons[_pathMode]);
+
+ CheckRadioButton(kOverwriteButtons[0], kOverwriteButtons[kNumOverwriteButtons - 1],
+ kOverwriteButtons[_overwriteMode]);
+
+ /*
+ CheckRadioButton(kFilesButtons[0], kFilesButtons[kNumFilesButtons - 1],
+ kFilesButtons[_filesMode]);
+ */
+
+ // CWindow selectedFilesWindow = GetItem(IDC_EXTRACT_RADIO_SELECTED_FILES);
+ // selectedFilesWindow.Enable(_enableSelectedFilesButton);
+
+
+ #endif
+
+
+ // CWindow aFilesWindow = GetItem(IDC_EXTRACT_RADIO_FILES);
+ // aFilesWindow.Enable(_enableFilesButton);
+
+ // UpdateWildCardState();
+ return CModalDialog::OnInit();
+}
+
+#ifndef _SFX
+void CExtractDialog::UpdatePasswordControl()
+{
+ _passwordControl.SetPasswordChar((IsButtonChecked(
+ IDC_EXTRACT_CHECK_SHOW_PASSWORD) == BST_CHECKED) ? 0: TEXT('*'));
+ CSysString 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()
+{
+ CSysString currentPath;
+ _path.GetText(currentPath);
+
+ #ifdef LANG
+ UString title = LangLoadStringW(IDS_EXTRACT_SET_FOLDER, 0x02000881);
+ #else
+ UString title = MyLoadStringW(IDS_EXTRACT_SET_FOLDER);
+ #endif
+
+
+ CSysString resultPath;
+ if (!NShell::BrowseForFolder(HWND(*this), GetSystemString(title),
+ currentPath, resultPath))
+ return;
+ #ifndef NO_REGISTRY
+ _path.SetCurSel(-1);
+ #endif
+ _path.SetText(resultPath);
+}
+
+void AddUniqueString(CSysStringVector &list, const CSysString &s)
+{
+ for(int i = 0; i < list.Size(); i++)
+ if (s.CollateNoCase(list[i]) == 0)
+ return;
+ list.Add(s);
+}
+
+void CExtractDialog::OnOK()
+{
+ #ifndef _SFX
+ _pathMode = GetPathNameMode();
+ _overwriteMode = GetOverwriteMode();
+ // _filesMode = (NExtractionDialog::NFilesMode::EEnum)GetFilesMode();
+
+ _passwordControl.GetText(Password);
+ #endif
+
+ NExtraction::CInfo extractionInfo;
+ extractionInfo.PathMode = NExtraction::NPathMode::EEnum(_pathMode);
+ extractionInfo.OverwriteMode = NExtraction::NOverwriteMode::EEnum(_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
+ {
+ CSysString sTemp;
+ _path.GetLBText(currentItem, sTemp);
+ s = GetUnicodeString(sTemp);
+ }
+
+ #endif
+
+ s.Trim();
+ #ifndef _SFX
+ AddUniqueString(extractionInfo.Paths, GetSystemString(s));
+ #endif
+ DirectoryPath = s;
+ #ifndef NO_REGISTRY
+ for(int i = 0; i < _path.GetCount(); i++)
+ if(i != currentItem)
+ {
+ CSysString 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));
+}
+*/
+
+/*
+static DWORD aHelpArray[] =
+{
+ IDC_EXTRACT_COMBO_PATH, IDH_EXTRACT_COMBO_PATH,
+ IDC_EXTRACT_BUTTON_SET_PATH, IDH_EXTRACT_BUTTON_SET_PATH,
+
+ IDC_EXTRACT_PATH_MODE, IDH_EXTRACT_PATH_MODE,
+ IDC_EXTRACT_RADIO_FULL_PATHNAMES, IDH_EXTRACT_RADIO_FULL_PATHNAMES,
+ IDC_EXTRACT_RADIO_CURRENT_PATHNAMES,IDH_EXTRACT_RADIO_CURRENT_PATHNAMES,
+ IDC_EXTRACT_RADIO_NO_PATHNAMES,IDH_EXTRACT_RADIO_NO_PATHNAMES,
+
+ IDC_EXTRACT_OVERWRITE_MODE, IDH_EXTRACT_OVERWRITE_MODE,
+ IDC_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE, IDH_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE,
+ IDC_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT, IDH_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT,
+ IDC_EXTRACT_RADIO_SKIP_EXISTING_FILES, IDH_EXTRACT_RADIO_SKIP_EXISTING_FILES,
+
+ IDC_EXTRACT_FILES, IDH_EXTRACT_FILES,
+ IDC_EXTRACT_RADIO_SELECTED_FILES, IDH_EXTRACT_RADIO_SELECTED_FILES,
+ IDC_EXTRACT_RADIO_ALL_FILES, IDH_EXTRACT_RADIO_ALL_FILES,
+ IDC_EXTRACT_RADIO_FILES, IDH_EXTRACT_RADIO_FILES,
+ IDC_EXTRACT_EDIT_WILDCARDS, IDH_EXTRACT_EDIT_WILDCARDS,
+ 0,0
+};
+*/
+
+
+void CExtractDialog::GetModeInfo(NExtractionDialog::CModeInfo &modeInfo)
+{
+ modeInfo.OverwriteMode = NExtractionDialog::NOverwriteMode::EEnum(_overwriteMode);
+ modeInfo.PathMode = NExtractionDialog::NPathMode::EEnum(_pathMode);
+ // modeInfo.FilesMode = NExtractionDialog::NFilesMode::EEnum(FilesMode);
+ modeInfo.FileList.Clear();
+}
+
+#ifndef NO_REGISTRY
+static LPCWSTR kHelpTopic = L"fm/plugins/7-zip/extract.htm";
+void CExtractDialog::OnHelp()
+{
+ ShowHelpWindow(NULL, kHelpTopic);
+ CModalDialog::OnHelp();
+ /*
+ if (pHelpInfo->iContextType == HELPINFO_WINDOW)
+ {
+ return ::HtmlHelp((HWND)pHelpInfo->hItemHandle,
+ TEXT("C:\\SRC\\VC\\ZipView\\Help\\7zip.chm::/Context/Extract.txt"),
+ HH_TP_HELP_WM_HELP, (DWORD)(LPVOID)aHelpArray) != NULL;
+ }
+ */
+}
+#endif
+
diff --git a/7zip/UI/GUI/ExtractDialog.h b/7zip/UI/GUI/ExtractDialog.h
new file mode 100755
index 00000000..3efbcbd0
--- /dev/null
+++ b/7zip/UI/GUI/ExtractDialog.h
@@ -0,0 +1,99 @@
+// ExtractDialog.h
+
+#pragma once
+
+#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
+
+namespace NExtractionDialog
+{
+ namespace NFilesMode
+ {
+ enum EEnum
+ {
+ kSelected,
+ kAll,
+ kSpecified
+ };
+ }
+ namespace NPathMode
+ {
+ enum EEnum
+ {
+ kFullPathnames,
+ kCurrentPathnames,
+ kNoPathnames,
+ };
+ }
+ namespace NOverwriteMode
+ {
+ enum EEnum
+ {
+ kAskBefore,
+ kWithoutPrompt,
+ kSkipExisting,
+ kAutoRename
+ };
+ }
+ struct CModeInfo
+ {
+ NOverwriteMode::EEnum OverwriteMode;
+ NPathMode::EEnum PathMode;
+ // NFilesMode::EEnum FilesMode;
+ UStringVector FileList;
+ };
+}
+
+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
+
+ int _pathMode;
+ int _overwriteMode;
+
+ #ifndef _SFX
+ int GetPathNameMode() const;
+ int GetOverwriteMode() const;
+ // 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;
+ UString DirectoryPath;
+ // NExtractionDialog::NFilesMode::EEnum FilesMode;
+ UString Password;
+
+ INT_PTR Create(HWND aWndParent = 0)
+ { return CModalDialog::Create(MAKEINTRESOURCE(IDD_DIALOG_EXTRACT), aWndParent); }
+ void GetModeInfo(NExtractionDialog::CModeInfo &modeInfo);
+};
+
+#endif
diff --git a/7zip/UI/GUI/FM.ico b/7zip/UI/GUI/FM.ico
new file mode 100755
index 00000000..3a0a34da
--- /dev/null
+++ b/7zip/UI/GUI/FM.ico
Binary files differ
diff --git a/7zip/UI/GUI/GUI.cpp b/7zip/UI/GUI/GUI.cpp
new file mode 100755
index 00000000..71772d4a
--- /dev/null
+++ b/7zip/UI/GUI/GUI.cpp
@@ -0,0 +1,361 @@
+// GUI.cpp
+
+#include "StdAfx.h"
+
+#include <initguid.h>
+
+#include "Common/NewHandler.h"
+#include "Common/StringConvert.h"
+#include "Common/CommandLineParser.h"
+
+#include "Windows/COM.h"
+#include "Windows/FileMapping.h"
+#include "Windows/FileDir.h"
+#include "Windows/Synchronization.h"
+#include "Windows/FileName.h"
+
+#include "../../IStream.h"
+#include "../../IPassword.h"
+
+// #include "../../Compress/Interface/CompressInterface.h"
+// #include "../../FileManager/FolderInterface.h"
+#include "../../FileManager/StringUtils.h"
+
+#include "../Resource/Extract/resource.h"
+#include "../Agent/Agent.h"
+// #include "../Common/FolderArchiveInterface.h"
+#include "../Explorer/MyMessages.h"
+
+#include "Test.h"
+#include "Extract.h"
+#include "Compress.h"
+
+using namespace NWindows;
+using namespace NCommandLineParser;
+
+HINSTANCE g_hInstance;
+
+static const int kNumSwitches = 5;
+
+namespace NKey {
+enum Enum
+{
+ // kHelp1 = 0,
+ // kHelp2,
+ // kDisablePercents,
+ kArchiveType,
+ // kYes,
+ // kPassword,
+ // kProperty,
+ kOutputDir,
+ // kWorkingDir,
+ kInclude,
+ // kExclude,
+ // kUpdate,
+ // kRecursed,
+ // kSfx,
+ // kOverwrite,
+ kEmail,
+ kShowDialog
+ // kMap
+};
+
+}
+
+static const int kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be
+static const int kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be
+static const wchar_t *kRecursedPostCharSet = L"0-";
+static const wchar_t *kOverwritePostCharSet = L"asut";
+
+static const CSwitchForm kSwitchForms[kNumSwitches] =
+ {
+ // { L"?", NSwitchType::kSimple, false },
+ // { L"H", 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"U", NSwitchType::kUnLimitedPostString, true, 1},
+ // { L"R", NSwitchType::kPostChar, false, 0, 0, kRecursedPostCharSet },
+ // { L"SFX", NSwitchType::kUnLimitedPostString, false, 0 },
+ // { L"AO", NSwitchType::kPostChar, false, 1, 1, kOverwritePostCharSet},
+ { L"SEML", NSwitchType::kSimple, false },
+ { L"AD", NSwitchType::kSimple, false }
+ // { L"MAP=", NSwitchType::kUnLimitedPostString, false, 1 }
+ };
+
+
+static bool inline IsItWindowsNT()
+{
+ OSVERSIONINFO versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ if (!::GetVersionEx(&versionInfo))
+ return false;
+ return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+
+static void MyMessageBoxError(const char *message)
+{
+ ::MessageBoxA(0, message, "Error", 0);
+}
+
+static wchar_t *kIncorrectCommandMessage = L"Incorrect command";
+
+static void ErrorMessage(const wchar_t *message)
+{
+ MessageBoxW(0, message, L"7-Zip GUI", MB_ICONERROR);
+}
+
+static bool ParseIncludeMap(const UString &switchParam, UStringVector &fileNames)
+{
+ int splitPos = switchParam.Find(L':');
+ if (splitPos < 0)
+ {
+ ErrorMessage(L"Bad switch");
+ return false;
+ }
+ UString mappingName = switchParam.Left(splitPos);
+
+ UString switchParam2 = switchParam.Mid(splitPos + 1);
+ splitPos = switchParam2.Find(L':');
+ if (splitPos < 0)
+ {
+ ErrorMessage(L"Bad switch");
+ return false;
+ }
+
+ UString mappingSize = switchParam2.Left(splitPos);
+ UString eventName = switchParam2.Mid(splitPos + 1);
+
+ wchar_t *endptr;
+ UINT32 dataSize = wcstoul(mappingSize, &endptr, 10);
+
+ {
+ CFileMapping fileMapping;
+ if (!fileMapping.Open(FILE_MAP_READ, false,
+ GetSystemString(mappingName)))
+ {
+ // ShowLastErrorMessage(0);
+ ErrorMessage(L"Can not open mapping");
+ return false;
+ }
+ LPVOID data = fileMapping.MapViewOfFile(FILE_MAP_READ, 0, dataSize);
+ if (data == NULL)
+ {
+ ErrorMessage(L"MapViewOfFile error");
+ return false;
+ }
+ try
+ {
+ const wchar_t *curData = (const wchar_t *)data;
+ if (*curData != 0)
+ {
+ ErrorMessage(L"Incorrect mapping data");
+ return false;
+ }
+ UINT32 numChars = dataSize /2;
+ UString name;
+
+ for (int i = 1; i < numChars; i++)
+ {
+ wchar_t c = curData[i];
+ if (c == L'\0')
+ {
+ fileNames.Add(name);
+ name.Empty();
+ }
+ else
+ name += c;
+ }
+ if (!name.IsEmpty())
+ {
+ ErrorMessage(L"data error");
+ return false;
+ }
+ }
+ catch(...)
+ {
+ UnmapViewOfFile(data);
+ throw;
+ }
+ UnmapViewOfFile(data);
+ }
+
+ {
+ NSynchronization::CEvent event;
+ event.Open(EVENT_MODIFY_STATE, false, GetSystemString(eventName));
+ event.Set();
+ }
+ return true;
+}
+
+static bool ParseIncludeSwitches(CParser &parser, UStringVector &fileNames)
+{
+ if (parser[NKey::kInclude].ThereIs)
+ {
+ for (int i = 0; i < parser[NKey::kInclude].PostStrings.Size(); i++)
+ {
+ UString switchParam = parser[NKey::kInclude].PostStrings[i];
+ if (switchParam.Length() < 1)
+ return false;
+ if (switchParam[0] == L'#')
+ {
+ if (!ParseIncludeMap(switchParam.Mid(1), fileNames))
+ return false;
+ }
+ else if (switchParam[0] == L'!')
+ {
+ fileNames.Add(switchParam.Mid(1));
+ }
+ else
+ {
+ ErrorMessage(L"Incorrect command");
+ return false;
+ }
+ }
+ }
+ const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
+ for (int i = 2; i < nonSwitchStrings.Size(); i++)
+ {
+ // ErrorMessage(nonSwitchStrings[i]);
+ fileNames.Add(nonSwitchStrings[i]);
+ }
+ return true;
+}
+
+int APIENTRY WinMain(HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine,
+ int nCmdShow)
+{
+ g_hInstance = hInstance;
+ InitCommonControls();
+
+ #ifdef UNICODE
+ if (!IsItWindowsNT())
+ {
+ // g_StdOut << "This program requires Windows NT/2000/XP";
+ return 0;
+ }
+ #endif
+ // setlocale(LC_COLLATE, ".ACP");
+ int result = 0;
+ try
+ {
+ UStringVector commandStrings;
+ SplitCommandLine(GetCommandLineW(), commandStrings);
+ if (commandStrings.Size() > 0)
+ commandStrings.Delete(0);
+ CParser parser(kNumSwitches);
+ try
+ {
+ parser.ParseStrings(kSwitchForms, commandStrings);
+ }
+ catch(...)
+ {
+ MyMessageBox(kIncorrectCommandMessage);
+ return 1;
+ }
+
+ const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
+ int numNonSwitchStrings = nonSwitchStrings.Size();
+
+ if(numNonSwitchStrings < 1)
+ {
+ MyMessageBox(kIncorrectCommandMessage);
+ return 1;
+ }
+
+ UString command = nonSwitchStrings[0];
+
+ if (command == L"t")
+ {
+ if(numNonSwitchStrings < 2)
+ {
+ MyMessageBox(kIncorrectCommandMessage);
+ return 1;
+ }
+ UString archiveName = nonSwitchStrings[1];
+ HRESULT result = TestArchive(0, archiveName);
+ if (result == S_FALSE)
+ MyMessageBox(IDS_OPEN_IS_NOT_SUPORTED_ARCHIVE, 0x02000604);
+ else if (result != S_OK)
+ ShowErrorMessage(0, result);
+ }
+ else if (command == L"x")
+ {
+ if(numNonSwitchStrings < 2)
+ {
+ MyMessageBox(kIncorrectCommandMessage);
+ return 1;
+ }
+ UString archiveName = nonSwitchStrings[1];
+
+ UString outputDir;
+ bool outputDirDefined = parser[NKey::kOutputDir].ThereIs;
+ if(outputDirDefined)
+ outputDir = parser[NKey::kOutputDir].PostStrings[0];
+ else
+ NFile::NDirectory::MyGetCurrentDirectory(outputDir);
+ NFile::NName::NormalizeDirPathPrefix(outputDir);
+ HRESULT result = ExtractArchive(0, archiveName,
+ false, parser[NKey::kShowDialog].ThereIs, outputDir);
+ if (result == S_FALSE)
+ MyMessageBox(IDS_OPEN_IS_NOT_SUPORTED_ARCHIVE, 0x02000604);
+ else if (result != S_OK)
+ ShowErrorMessage(0, result);
+ }
+ else if (command == L"a")
+ {
+ if(numNonSwitchStrings < 2)
+ {
+ MyMessageBox(kIncorrectCommandMessage);
+ return 1;
+ }
+ const UString &archiveName = nonSwitchStrings[1];
+
+ UString mapString, emailString;
+ bool emailMode = parser[NKey::kEmail].ThereIs;
+ UStringVector fileNames;
+ if (!ParseIncludeSwitches(parser, fileNames))
+ return 1;
+ if (fileNames.Size() == 0)
+ {
+ ErrorMessage(L"Incorrect command: No files");
+ return 1;
+ }
+ UString archiveType = L"7z";;
+ if (parser[NKey::kArchiveType].ThereIs)
+ archiveType = parser[NKey::kArchiveType].PostStrings.Front();
+ HRESULT result = CompressArchive(archiveName, fileNames,
+ archiveType, emailMode, parser[NKey::kShowDialog].ThereIs);
+ // if (result != S_OK)
+ // ShowErrorMessage(result);
+ }
+ else
+ {
+ ErrorMessage(L"Use correct command");
+ return 0;
+ }
+ return 0;
+ }
+ catch(const CNewException &)
+ {
+ // MyMessageBoxError(kMemoryExceptionMessage);
+ return 1;
+ }
+ catch(...)
+ {
+ // g_StdOut << kUnknownExceptionMessage;
+ return 2;
+ }
+ return result;
+}
+
+
+
diff --git a/7zip/UI/GUI/GUI.dsp b/7zip/UI/GUI/GUI.dsp
new file mode 100755
index 00000000..3febf756
--- /dev/null
+++ b/7zip/UI/GUI/GUI.dsp
@@ -0,0 +1,868 @@
+# 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" /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" /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" /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" /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=.\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\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\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
+# 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\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\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\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\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 "Console"
+
+# PROP Default_Filter ""
+# 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
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\ProgressDialog2\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\ProgressDialog2\resource.rc
+# PROP Exclude_From_Build 1
+# 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
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\PasswordDialog\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\FileManager\Resource\PasswordDialog\resource.rc
+# PROP Exclude_From_Build 1
+# 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
+# Begin Source File
+
+SOURCE=..\Resource\CompressDialog\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Resource\CompressDialog\resource.rc
+# PROP Exclude_From_Build 1
+# 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
+# Begin Source File
+
+SOURCE=..\Resource\ExtractDialog\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Resource\ExtractDialog\resource.rc
+# PROP Exclude_From_Build 1
+# 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\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 "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\ArchiveExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\ArchiveExtractCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\ArchiveUpdateCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\ArchiveUpdateCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Agent\IFolderArchive.h
+# End Source File
+# End Group
+# Begin Group "Archive Interfaces"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\Format\Common\ArchiveInterface.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Interface\CompressInterface.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\SDK\Interface\CryptoInterface.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\Common\FolderArchiveInterface.h
+# End Source File
+# End Group
+# Begin Group "Engine"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\Compress.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Compress.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Extract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Extract.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Test.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Test.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
+# 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=.\7zG.exe.manifest
+# End Source File
+# Begin Source File
+
+SOURCE=.\FM.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\GUI.cpp
+# End Source File
+# End Target
+# End Project
diff --git a/7zip/UI/GUI/GUI.dsw b/7zip/UI/GUI/GUI.dsw
new file mode 100755
index 00000000..85d33484
--- /dev/null
+++ b/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/7zip/UI/GUI/StdAfx.cpp b/7zip/UI/GUI/StdAfx.cpp
new file mode 100755
index 00000000..e9cf4cfb
--- /dev/null
+++ b/7zip/UI/GUI/StdAfx.cpp
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// GUI.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/7zip/UI/GUI/StdAfx.h b/7zip/UI/GUI/StdAfx.h
new file mode 100755
index 00000000..f10df8d5
--- /dev/null
+++ b/7zip/UI/GUI/StdAfx.h
@@ -0,0 +1,38 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+#include <commctrl.h>
+#include <limits.h>
+#include <shlobj.h>
+
+/*
+#define _ATL_APARTMENT_THREADED
+
+#define _ATL_NO_UUIDOF
+
+#include <atlbase.h>
+
+extern CComModule _Module;
+
+#include <atlcom.h>
+
+#include <crtdbg.h>
+#include <string.h>
+#include <mbstring.h>
+#include <tchar.h>
+#include <shlguid.h>
+#include <regstr.h>
+
+#include <new.h>
+
+#pragma warning(disable:4786)
+
+#include <map>
+#include <algorithm>
+*/
+#include <vector>
+
+#endif
diff --git a/7zip/UI/GUI/Test.cpp b/7zip/UI/GUI/Test.cpp
new file mode 100755
index 00000000..d7128b47
--- /dev/null
+++ b/7zip/UI/GUI/Test.cpp
@@ -0,0 +1,122 @@
+// Test.h
+
+#include "StdAfx.h"
+
+#include "Test.h"
+
+#include "Common/StringConvert.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileFind.h"
+#include "Windows/DLL.h"
+#include "Windows/Thread.h"
+
+#include "../Common/OpenArchive.h"
+#include "../Common/DefaultName.h"
+
+#ifndef EXCLUDE_COM
+#include "../Common/ZipRegistry.h"
+#endif
+
+#include "../Explorer/MyMessages.h"
+#include "../../FileManager/FormatUtils.h"
+
+#include "../../FileManager/ExtractCallback.h"
+#include "../../FileManager/LangUtils.h"
+
+#include "../Agent/ArchiveExtractCallback.h"
+
+#include "resource.h"
+
+#include "../../FileManager/OpenCallback.h"
+
+using namespace NWindows;
+
+struct CThreadTesting
+{
+ NDLL::CLibrary Library;
+ CMyComPtr<IInArchive> Archive;
+ CExtractCallbackImp *ExtractCallbackSpec;
+ CMyComPtr<IFolderArchiveExtractCallback> ExtractCallback2;
+ CMyComPtr<IArchiveExtractCallback> ExtractCallback;
+
+ HRESULT Result;
+
+ DWORD Process()
+ {
+ ExtractCallbackSpec->ProgressDialog.WaitCreating();
+ Result = Archive->Extract(0, -1, BoolToInt(true), ExtractCallback);
+ ExtractCallbackSpec->ProgressDialog.MyClose();
+ return 0;
+ }
+ static DWORD WINAPI MyThreadFunction(void *param)
+ {
+ return ((CThreadTesting *)param)->Process();
+ }
+};
+
+HRESULT TestArchive(HWND parentWindow, const UString &fileName)
+{
+ CThreadTesting tester;
+
+ COpenArchiveCallback *openCallbackSpec = new COpenArchiveCallback;
+ CMyComPtr<IArchiveOpenCallback> openCallback = openCallbackSpec;
+ openCallbackSpec->_passwordIsDefined = false;
+ openCallbackSpec->_parentWindow = parentWindow;
+
+ UString fullName;
+ int fileNamePartStartIndex;
+ NFile::NDirectory::MyGetFullPathName(fileName, fullName, fileNamePartStartIndex);
+
+ openCallbackSpec->LoadFileInfo(
+ fullName.Left(fileNamePartStartIndex),
+ fullName.Mid(fileNamePartStartIndex));
+
+ CArchiverInfo archiverInfo;
+ int subExtIndex;
+ RINOK(OpenArchive(fileName,
+ &tester.Library, &tester.Archive,
+ archiverInfo, subExtIndex, openCallback));
+
+ UString defaultName = GetDefaultName(fileName,
+ archiverInfo.Extensions[subExtIndex].Extension,
+ archiverInfo.Extensions[subExtIndex].AddExtension);
+
+ tester.ExtractCallbackSpec = new CExtractCallbackImp;
+ tester.ExtractCallback2 = tester.ExtractCallbackSpec;
+
+ tester.ExtractCallbackSpec->_parentWindow = 0;
+ #ifdef LANG
+ const UString title = LangLoadStringW(IDS_PROGRESS_TESTING, 0x02000F90);
+ #else
+ const UString title = NWindows::MyLoadStringW(IDS_PROGRESS_TESTING);
+ #endif
+
+ tester.ExtractCallbackSpec->Init(NExtractionMode::NOverwrite::kAskBefore,
+ openCallbackSpec->_passwordIsDefined, openCallbackSpec->_password);
+
+ CArchiveExtractCallback *extractCallback200Spec = new CArchiveExtractCallback;
+ tester.ExtractCallback = extractCallback200Spec;
+
+ FILETIME fileTomeDefault;
+ extractCallback200Spec->Init(tester.Archive,
+ tester.ExtractCallback2,
+ L"", NExtractionMode::NPath::kFullPathnames,
+ NExtractionMode::NOverwrite::kWithoutPrompt, UStringVector(),
+ defaultName,
+ fileTomeDefault, 0);
+
+
+ CThread thread;
+ if (!thread.Create(CThreadTesting::MyThreadFunction, &tester))
+ throw 271824;
+ tester.ExtractCallbackSpec->StartProgressDialog(title);
+
+ if (tester.Result == S_OK && tester.ExtractCallbackSpec->_messages.IsEmpty())
+ {
+ // extractCallbackSpec->DestroyWindows();
+ MessageBoxW(0, LangLoadStringW(IDS_MESSAGE_NO_ERRORS, 0x02000608),
+ LangLoadStringW(IDS_PROGRESS_TESTING, 0x02000F90), 0);
+ }
+ return tester.Result;
+}
diff --git a/7zip/UI/GUI/Test.h b/7zip/UI/GUI/Test.h
new file mode 100755
index 00000000..0356087e
--- /dev/null
+++ b/7zip/UI/GUI/Test.h
@@ -0,0 +1,13 @@
+// GUI/Test.h
+
+#pragma once
+
+#ifndef __GUI_TEST_H
+#define __GUI_TEST_H
+
+#include "Common/String.h"
+
+HRESULT TestArchive(HWND parentWindow, const UString &fileName);
+
+#endif
+
diff --git a/7zip/UI/GUI/resource.h b/7zip/UI/GUI/resource.h
new file mode 100755
index 00000000..6461d2cc
--- /dev/null
+++ b/7zip/UI/GUI/resource.h
@@ -0,0 +1,53 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#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_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 IDD_DIALOG_EXTRACT 137
+#define IDB_DELETE 149
+#define IDC_LIST1 1067
+#define IDC_COLUMN_EDIT_WIDTH 1068
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 157
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1110
+#define _APS_NEXT_SYMED_VALUE 150
+#endif
+#endif
diff --git a/7zip/UI/GUI/resource.rc b/7zip/UI/GUI/resource.rc
new file mode 100755
index 00000000..0dd0cbc2
--- /dev/null
+++ b/7zip/UI/GUI/resource.rc
@@ -0,0 +1,203 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""..\\..\\FileManager\\Resource\\PropertyName\\resource.rc""\r\n"
+ "#include ""..\\..\\FileManager\\Resource\\OverwriteDialog\\resource.rc""\r\n"
+ "#include ""..\\..\\FileManager\\Resource\\PasswordDialog\\resource.rc""\r\n"
+ "#include ""..\\..\\FileManager\\Resource\\MessagesDialog\\resource.rc""\r\n"
+ "#include ""..\\..\\FileManager\\Resource\\ProgressDialog2\\resource.rc""\r\n"
+ "#include ""..\\Resource\\Extract\\resource.rc""\r\n"
+ "#include ""..\\Resource\\ExtractDialog\\resource.rc""\r\n"
+ "#include ""..\\Resource\\CompressDialog\\resource.rc""\r\n"
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,13,0,0
+ PRODUCTVERSION 3,13,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Igor Pavlov\0"
+ VALUE "FileDescription", "7-Zip GUI Module\0"
+ VALUE "FileVersion", "3, 13, 0, 0\0"
+ VALUE "InternalName", "7zg\0"
+ VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "7zg.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "7-Zip\0"
+ VALUE "ProductVersion", "3, 13, 0, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1 ICON DISCARDABLE "FM.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// 24
+//
+
+1 24 MOVEABLE PURE "7zG.exe.manifest"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+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."
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ 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"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ 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"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_COMPRESS_SET_ARCHIVE_DIALOG_TITLE "Browse"
+ 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
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#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"
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/UI/Resource/CompressDialog/resource.h b/7zip/UI/Resource/CompressDialog/resource.h
new file mode 100755
index 00000000..b1d691a5
--- /dev/null
+++ b/7zip/UI/Resource/CompressDialog/resource.h
@@ -0,0 +1,47 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#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_PASSWORD 1107
+#define IDC_COMPRESS_EDIT_PASSWORD 1108
+#define IDC_COMPRESS_CHECK_SHOW_PASSWORD 1109
+#define IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES 1110
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 157
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1110
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/UI/Resource/CompressDialog/resource.rc b/7zip/UI/Resource/CompressDialog/resource.rc
new file mode 100755
index 00000000..a26d8b14
--- /dev/null
+++ b/7zip/UI/Resource/CompressDialog/resource.rc
@@ -0,0 +1,161 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALOG_COMPRESS DIALOG DISCARDABLE 0, 0, 313, 277
+STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Add to Archive"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "&Archive:",IDC_STATIC_COMPRESS_ARCHIVE,7,7,283,8
+ COMBOBOX IDC_COMPRESS_COMBO_ARCHIVE,7,18,259,126,CBS_DROPDOWN |
+ CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "...",IDC_COMPRESS_BUTTON_SET_ARCHIVE,286,17,20,14,
+ WS_GROUP
+ LTEXT "Archive &format:",IDC_STATIC_COMPRESS_FORMAT,7,41,79,8
+ COMBOBOX IDC_COMPRESS_COMBO_FORMAT,88,39,76,80,CBS_DROPDOWNLIST |
+ WS_VSCROLL | WS_TABSTOP
+ LTEXT "Compression &level:",IDC_STATIC_COMPRESS_LEVEL,7,62,79,
+ 8
+ COMBOBOX IDC_COMPRESS_COMBO_LEVEL,88,60,76,80,CBS_DROPDOWNLIST |
+ WS_VSCROLL | WS_TABSTOP
+ LTEXT "Compression &method:",IDC_STATIC_COMPRESS_METHOD,7,83,
+ 79,8
+ COMBOBOX IDC_COMPRESS_COMBO_METHOD,88,81,76,80,CBS_DROPDOWNLIST |
+ WS_VSCROLL | WS_TABSTOP
+ LTEXT "&Dictionary size:",IDC_STATIC_COMPRESS_DICTIONARY,7,104,
+ 79,8
+ COMBOBOX IDC_COMPRESS_COMBO_DICTIONARY,88,102,76,167,
+ CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "&Word size:",IDC_STATIC_COMPRESS_ORDER,7,127,79,8
+ COMBOBOX IDC_COMPRESS_COMBO_ORDER,88,125,76,141,CBS_DROPDOWNLIST |
+ WS_VSCROLL | WS_TABSTOP
+ LTEXT "Memory usage for Compressing:",
+ IDC_STATIC_COMPRESS_MEMORY,7,149,121,8
+ RTEXT "0",IDC_STATIC_COMPRESS_MEMORY_VALUE,128,149,36,8
+ LTEXT "Memory usage for Decompressing:",
+ IDC_STATIC_COMPRESS_MEMORY_DE,7,163,121,8
+ RTEXT "0",IDC_STATIC_COMPRESS_MEMORY_DE_VALUE,128,163,36,8
+ CONTROL "Create &Solid archive",IDC_COMPRESS_SOLID,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,7,181,157,10
+ CONTROL "Multi-threading",IDC_COMPRESS_MULTI_THREAD,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,7,195,157,10
+ LTEXT "Split to &volumes, bytes:",IDC_STATIC_COMPRESS_VOLUME,
+ 186,183,77,8,NOT WS_VISIBLE
+ COMBOBOX IDC_COMPRESS_COMBO_VOLUME,186,196,31,73,CBS_DROPDOWN |
+ CBS_AUTOHSCROLL | NOT WS_VISIBLE | WS_VSCROLL |
+ WS_TABSTOP
+ LTEXT "&Parameters:",IDC_STATIC_COMPRESS_PARAMETERS,7,214,157,
+ 8
+ EDITTEXT IDC_COMPRESS_EDIT_PARAMETERS,7,225,283,14,ES_AUTOHSCROLL
+ LTEXT "&Update mode:",IDC_STATIC_COMPRESS_UPDATE_MODE,186,39,
+ 104,8
+ COMBOBOX IDC_COMPRESS_COMBO_UPDATE_MODE,186,50,120,80,
+ CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ GROUPBOX "Options",IDC_STATIC_COMPRESS_OPTIONS,186,73,120,32
+ CONTROL "Create SF&X archive",IDC_COMPRESS_SFX,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,194,87,105,10
+ GROUPBOX "Password",IDC_COMPRESS_PASSWORD,186,113,120,63
+ EDITTEXT IDC_COMPRESS_EDIT_PASSWORD,194,127,105,14,ES_PASSWORD |
+ ES_AUTOHSCROLL
+ CONTROL "Show Password",IDC_COMPRESS_CHECK_SHOW_PASSWORD,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,194,145,105,10
+ CONTROL "Encrypt file &names",
+ IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,194,159,105,10
+ DEFPUSHBUTTON "OK",IDOK,98,256,64,14
+ PUSHBUTTON "Cancel",IDCANCEL,170,256,64,14
+ PUSHBUTTON "Help",IDHELP,242,256,64,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_DIALOG_COMPRESS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 306
+ VERTGUIDE, 86
+ VERTGUIDE, 88
+ VERTGUIDE, 128
+ VERTGUIDE, 164
+ VERTGUIDE, 186
+ VERTGUIDE, 194
+ VERTGUIDE, 299
+ BOTTOMMARGIN, 270
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/7zip/UI/Resource/Extract/resource.h b/7zip/UI/Resource/Extract/resource.h
new file mode 100755
index 00000000..20e3be45
--- /dev/null
+++ b/7zip/UI/Resource/Extract/resource.h
@@ -0,0 +1,26 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+
+#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_EXTRACT_SET_FOLDER 205
+#define IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CANNOT_OPEN_FILE 206
+#define IDS_PROGRESS_EXTRACTING 207
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 208
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 208
+#endif
+#endif
diff --git a/7zip/UI/Resource/Extract/resource.rc b/7zip/UI/Resource/Extract/resource.rc
new file mode 100755
index 00000000..cc876aab
--- /dev/null
+++ b/7zip/UI/Resource/Extract/resource.rc
@@ -0,0 +1,113 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+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."
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_UNSUPPORTED_METHOD
+ "Unsupported compression method for '{0}'."
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_EXTRACT_SET_FOLDER "Specify a location for extracted files."
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CANNOT_OPEN_FILE
+ "Can not open output file '{0}'."
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_PROGRESS_EXTRACTING "Extracting"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/7zip/UI/Resource/ExtractDialog/resource.h b/7zip/UI/Resource/ExtractDialog/resource.h
new file mode 100755
index 00000000..91fa171a
--- /dev/null
+++ b/7zip/UI/Resource/ExtractDialog/resource.h
@@ -0,0 +1,35 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+
+#define IDC_EXTRACT_COMBO_PATH 1044
+#define IDC_EXTRACT_BUTTON_SET_PATH 1045
+#define IDC_EXTRACT_RADIO_FULL_PATHNAMES 1046
+#define IDC_EXTRACT_RADIO_CURRENT_PATHNAMES 1048
+#define IDC_EXTRACT_RADIO_NO_PATHNAMES 1049
+#define IDC_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE 1050
+#define IDC_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT 1051
+#define IDC_EXTRACT_RADIO_SKIP_EXISTING_FILES 1052
+#define IDC_EXTRACT_RADIO_SELECTED_FILES 1053
+#define IDC_EXTRACT_RADIO_ALL_FILES 1054
+#define IDC_EXTRACT_RADIO_AUTO_RENAME 1055
+#define IDC_EXTRACT_PATH_MODE 1056
+#define IDC_EXTRACT_OVERWRITE_MODE 1057
+#define IDC_EXTRACT_FILES 1058
+#define IDC_EXTRACT_EDIT_PASSWORD 1068
+#define IDC_EXTRACT_PASSWORD 1106
+#define IDC_EXTRACT_CHECK_SHOW_PASSWORD 1109
+#define IDC_STATIC_EXTRACT_EXTRACT_TO 1092
+
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 157
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1110
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/7zip/UI/Resource/ExtractDialog/resource.rc b/7zip/UI/Resource/ExtractDialog/resource.rc
new file mode 100755
index 00000000..6b399665
--- /dev/null
+++ b/7zip/UI/Resource/ExtractDialog/resource.rc
@@ -0,0 +1,116 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+#ifdef _WIN32
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALOG_EXTRACT DIALOG DISCARDABLE 0, 0, 299, 202
+STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Extract"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "E&xtract to:",IDC_STATIC_EXTRACT_EXTRACT_TO,7,7,127,8
+ COMBOBOX IDC_EXTRACT_COMBO_PATH,7,21,252,126,CBS_DROPDOWN |
+ CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "...",IDC_EXTRACT_BUTTON_SET_PATH,272,20,20,14,WS_GROUP
+ GROUPBOX "Path mode",IDC_EXTRACT_PATH_MODE,7,44,127,57
+ CONTROL "Full pathnames",IDC_EXTRACT_RADIO_FULL_PATHNAMES,"Button",
+ BS_AUTORADIOBUTTON | WS_GROUP,13,57,114,10
+ CONTROL "Current pathnames",IDC_EXTRACT_RADIO_CURRENT_PATHNAMES,
+ "Button",BS_AUTORADIOBUTTON,13,71,114,10
+ CONTROL "No pathnames",IDC_EXTRACT_RADIO_NO_PATHNAMES,"Button",
+ BS_AUTORADIOBUTTON,13,85,114,10
+ GROUPBOX "Overwrite mode",IDC_EXTRACT_OVERWRITE_MODE,148,44,144,
+ 75,WS_GROUP
+ CONTROL "Ask before overwrite",
+ IDC_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE,"Button",
+ BS_AUTORADIOBUTTON | WS_GROUP,154,57,130,10
+ CONTROL "Overwrite without prompt",
+ IDC_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT,"Button",
+ BS_AUTORADIOBUTTON,154,71,130,10
+ CONTROL "Skip existing files",
+ IDC_EXTRACT_RADIO_SKIP_EXISTING_FILES,"Button",
+ BS_AUTORADIOBUTTON,154,85,130,10
+ CONTROL "Auto rename",IDC_EXTRACT_RADIO_AUTO_RENAME,"Button",
+ BS_AUTORADIOBUTTON,154,99,130,10
+ GROUPBOX "Files",IDC_EXTRACT_FILES,7,125,127,48,NOT WS_VISIBLE |
+ WS_GROUP
+ CONTROL "&Selected files",IDC_EXTRACT_RADIO_SELECTED_FILES,
+ "Button",BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_GROUP,
+ 13,137,114,10
+ CONTROL "&All files",IDC_EXTRACT_RADIO_ALL_FILES,"Button",
+ BS_AUTORADIOBUTTON | NOT WS_VISIBLE,13,151,114,10
+ GROUPBOX "Password",IDC_EXTRACT_PASSWORD,148,126,144,46
+ EDITTEXT IDC_EXTRACT_EDIT_PASSWORD,154,138,130,14,ES_PASSWORD |
+ ES_AUTOHSCROLL
+ CONTROL "Show Password",IDC_EXTRACT_CHECK_SHOW_PASSWORD,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,154,157,129,10
+ DEFPUSHBUTTON "OK",IDOK,80,181,64,14,WS_GROUP
+ PUSHBUTTON "Cancel",IDCANCEL,154,181,64,14
+ PUSHBUTTON "Help",IDHELP,228,181,64,14
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/Common/AlignedBuffer.cpp b/Common/AlignedBuffer.cpp
new file mode 100755
index 00000000..dd811335
--- /dev/null
+++ b/Common/AlignedBuffer.cpp
@@ -0,0 +1,22 @@
+// AlignedBuffer.cpp
+
+#include "StdAfx.h"
+
+#include "AlignedBuffer.h"
+#include "Types.h"
+
+void *CAlignedBuffer::Allocate(size_t numItems, size_t itemSize, size_t alignValue)
+{
+ Free();
+ m_Buffer = new unsigned char[numItems * itemSize + alignValue - 1];
+ UINT_PTR p = UINT_PTR(m_Buffer) + (alignValue - 1);
+ p -= (p % alignValue);
+ return (void *)p;
+}
+
+void CAlignedBuffer::Free()
+{
+ if (m_Buffer != 0)
+ delete []m_Buffer;
+ m_Buffer = 0;
+}
diff --git a/Common/AlignedBuffer.h b/Common/AlignedBuffer.h
new file mode 100755
index 00000000..1bff6591
--- /dev/null
+++ b/Common/AlignedBuffer.h
@@ -0,0 +1,16 @@
+// AlignedBuffer.h
+
+#ifndef __ALIGNBUFFER_H
+#define __ALIGNBUFFER_H
+
+class CAlignedBuffer
+{
+ unsigned char *m_Buffer;
+public:
+ CAlignedBuffer(): m_Buffer(0) {};
+ ~CAlignedBuffer() { Free(); }
+ void *Allocate(size_t numItems, size_t itemSize, size_t alignValue);
+ void Free();
+};
+
+#endif
diff --git a/Common/Buffer.h b/Common/Buffer.h
new file mode 100755
index 00000000..db80c751
--- /dev/null
+++ b/Common/Buffer.h
@@ -0,0 +1,71 @@
+// Common/Buffer.h
+
+#pragma once
+
+#ifndef __COMMON_BUFFER_H
+#define __COMMON_BUFFER_H
+
+// #include "Common/Defs.h"
+
+template <class T> class CBuffer
+{
+protected:
+ size_t _capacity;
+ T *_items;
+ void Free()
+ {
+ delete []_items;
+ _items = 0;
+ _capacity = 0;
+ }
+public:
+ CBuffer(): _capacity(0), _items(0) {};
+ CBuffer(const CBuffer &buffer): _capacity(0), _items(0) { *this = buffer; }
+ CBuffer(size_t size): _items(0), _capacity(0) { SetCapacity(size); }
+ virtual ~CBuffer() { delete []_items; }
+ operator T *() { return _items; };
+ operator const T *() const { return _items; };
+ size_t GetCapacity() const { return _capacity; }
+ void SetCapacity(size_t newCapacity)
+ {
+ T *newBuffer = new T[newCapacity];
+ if(_capacity > 0)
+ memmove(newBuffer, _items, MyMin(_capacity, newCapacity) * sizeof(T));
+ delete []_items;
+ _items = newBuffer;
+ _capacity = newCapacity;
+ }
+ CBuffer& operator=(const CBuffer &buffer)
+ {
+ Free();
+ if(buffer._capacity > 0)
+ {
+ SetCapacity(buffer._capacity);
+ memmove(_items, buffer._items, buffer._capacity * sizeof(T));
+ }
+ return *this;
+ }
+};
+
+template <class T>
+bool operator==(const CBuffer<T>& b1, const CBuffer<T>& b2)
+{
+ if (b1.GetCapacity() != b2.GetCapacity())
+ return false;
+ for (size_t i = 0; i < b1.GetCapacity(); i++)
+ if (b1[i] != b2[i])
+ return false;
+ return true;
+}
+
+template <class T>
+bool operator!=(const CBuffer<T>& b1, const CBuffer<T>& b2)
+{
+ return !(b1 == b2);
+}
+
+typedef CBuffer<char> CCharBuffer;
+typedef CBuffer<wchar_t> CWCharBuffer;
+typedef CBuffer<unsigned char> CByteBuffer;
+
+#endif
diff --git a/Common/CRC.cpp b/Common/CRC.cpp
new file mode 100755
index 00000000..006da6d9
--- /dev/null
+++ b/Common/CRC.cpp
@@ -0,0 +1,110 @@
+// Common/CRC.cpp
+
+#include "StdAfx.h"
+
+#include "CRC.h"
+
+static const UINT32 kCRCPoly = 0xEDB88320;
+
+UINT32 CCRC::Table[256];
+
+class CCRCTableInit
+{
+public:
+CCRCTableInit()
+{
+ 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] = r;
+ }
+}
+} g_CRCTableInit;
+
+/*
+const UINT32 CCRC::Table[] = {
+ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
+ 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
+ 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
+ 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
+ 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
+ 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
+ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
+ 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
+ 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
+ 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
+ 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
+ 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
+ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
+ 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
+ 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
+ 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
+ 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
+ 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
+ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
+ 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
+ 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
+ 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
+ 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
+ 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
+ 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
+ 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
+ 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
+ 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
+ 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
+ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
+ 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
+ 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
+ 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
+ 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
+ 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
+ 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
+ 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
+ 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
+ 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
+ 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
+ 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
+ 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
+ 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
+ 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
+ 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
+ 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
+ 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
+ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
+ 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
+ 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
+ 0x2d02ef8dL
+};
+*/
+
+#define UPDATE valueLoc = Table[(BYTE)valueLoc] ^ (valueLoc >> 8)
+#define UPDATE4 UPDATE; UPDATE; UPDATE; UPDATE;
+
+void CCRC::Update(const void *data, UINT32 size)
+{
+ UINT32 valueLoc = _value;
+ const BYTE *byteBuffer = (const BYTE *)data;
+
+ for(; (UINT_PTR(byteBuffer) & 3) != 0 && size > 0; size--, byteBuffer++)
+ valueLoc = Table[(((BYTE)(valueLoc)) ^ (*byteBuffer))] ^
+ (valueLoc >> 8);
+
+ const UINT32 kBlockSize = 4;
+ while (size >= kBlockSize)
+ {
+ size -= kBlockSize;
+ valueLoc ^= *(const UINT32 *)byteBuffer;
+ UPDATE4
+ byteBuffer += kBlockSize;
+ }
+ for(UINT32 i = 0; i < size; i++)
+ valueLoc = Table[(((BYTE)(valueLoc)) ^ (byteBuffer)[i])] ^
+ (valueLoc >> 8);
+ _value = valueLoc;
+}
diff --git a/Common/CRC.h b/Common/CRC.h
new file mode 100755
index 00000000..34514883
--- /dev/null
+++ b/Common/CRC.h
@@ -0,0 +1,31 @@
+// Common/CRC.h
+
+// #pragma once
+
+#ifndef __COMMON_CRC_H
+#define __COMMON_CRC_H
+
+#include "Types.h"
+
+class CCRC
+{
+ UINT32 _value;
+public:
+ static UINT32 Table[256];
+ CCRC(): _value(0xFFFFFFFF){};
+ void Init() { _value = 0xFFFFFFFF; }
+ void Update(const void *data, UINT32 size);
+ UINT32 GetDigest() const { return _value ^ 0xFFFFFFFF; }
+ static UINT32 CalculateDigest(const void *data, UINT32 size)
+ {
+ CCRC crc;
+ crc.Update(data, size);
+ return crc.GetDigest();
+ }
+ static bool VerifyDigest(UINT32 digest, const void *data, UINT32 size)
+ {
+ return (CalculateDigest(data, size) == digest);
+ }
+};
+
+#endif
diff --git a/Common/ComTry.h b/Common/ComTry.h
new file mode 100755
index 00000000..3162e502
--- /dev/null
+++ b/Common/ComTry.h
@@ -0,0 +1,14 @@
+// ComTry.h
+
+// #pragma once
+
+#ifndef __Com_Try_H
+#define __Com_Try_H
+
+#include "Exception.h"
+
+#define COM_TRY_BEGIN try {
+#define COM_TRY_END } catch(const CSystemException &e) { return e.ErrorCode; }\
+ catch(...) { return E_FAIL; }
+
+#endif
diff --git a/Common/CommandLineParser.cpp b/Common/CommandLineParser.cpp
new file mode 100755
index 00000000..295465b4
--- /dev/null
+++ b/Common/CommandLineParser.cpp
@@ -0,0 +1,248 @@
+// CommandLineParser.cpp
+
+#include "StdAfx.h"
+
+#include "CommandLineParser.h"
+
+namespace NCommandLineParser {
+
+void SplitCommandLine(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)
+ {
+ i++;
+ break;
+ }
+ else
+ dest1 += c;
+ }
+ dest2 = src.Mid(i);
+}
+
+void SplitCommandLine(const UString &s, UStringVector &parts)
+{
+ UString sTemp = s;
+ sTemp.Trim();
+ parts.Clear();
+ while (true)
+ {
+ UString s1, s2;
+ SplitCommandLine(sTemp, s1, s2);
+ s1.Trim();
+ s2.Trim();
+ if (!s1.IsEmpty())
+ parts.Add(s1);
+ if (s2.IsEmpty())
+ return;
+ sTemp = s2;
+ }
+}
+
+
+static const wchar_t kSwitchID1 = '-';
+static const wchar_t kSwitchID2 = '/';
+
+static const wchar_t kSwitchMinus = '-';
+
+static bool IsItSwitchChar(wchar_t c)
+{
+ return (c == kSwitchID1 || c == kSwitchID2);
+}
+
+CParser::CParser(int numSwitches):
+ _numSwitches(numSwitches)
+{
+ _switches = new CSwitchResult[_numSwitches];
+}
+
+CParser::~CParser()
+{
+ delete []_switches;
+}
+
+void CParser::ParseStrings(const CSwitchForm *switchForms,
+ const UStringVector &commandStrings)
+{
+ int numCommandStrings = commandStrings.Size();
+ for (int i = 0; i < numCommandStrings; i++)
+ if (!ParseString(commandStrings[i], switchForms))
+ NonSwitchStrings.Add(commandStrings[i]);
+}
+
+// if string contains switch then function updates switch structures
+// out: (string is a switch)
+bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms)
+{
+ int len = s.Length();
+ if (len == 0)
+ return false;
+ int pos = 0;
+ if (!IsItSwitchChar(s[pos]))
+ return false;
+ while(pos < len)
+ {
+ if (IsItSwitchChar(s[pos]))
+ pos++;
+ const int kNoLen = -1;
+ int matchedSwitchIndex;
+ int maxLen = kNoLen;
+ for(int switchIndex = 0; switchIndex < _numSwitches; switchIndex++)
+ {
+ int switchLen = wcslen(switchForms[switchIndex].IDString);
+ if (switchLen <= maxLen || pos + switchLen > len)
+ continue;
+
+ UString temp = s + pos;
+ temp = temp.Left(switchLen);
+ if(temp.CompareNoCase(switchForms[switchIndex].IDString) == 0)
+ // if(_strnicmp(switchForms[switchIndex].IDString, LPCSTR(s) + pos, switchLen) == 0)
+ {
+ matchedSwitchIndex = switchIndex;
+ maxLen = switchLen;
+ }
+ }
+ if (maxLen == kNoLen)
+ throw "maxLen == kNoLen";
+ CSwitchResult &matchedSwitch = _switches[matchedSwitchIndex];
+ const CSwitchForm &switchForm = switchForms[matchedSwitchIndex];
+ if ((!switchForm.Multi) && matchedSwitch.ThereIs)
+ throw "switch must be single";
+ matchedSwitch.ThereIs = true;
+ pos += maxLen;
+ int tailSize = len - pos;
+ NSwitchType::EEnum type = switchForm.Type;
+ switch(type)
+ {
+ case (NSwitchType::kPostMinus):
+ {
+ if (tailSize == 0)
+ matchedSwitch.WithMinus = false;
+ else
+ {
+ matchedSwitch.WithMinus = (s[pos] == kSwitchMinus);
+ if (matchedSwitch.WithMinus)
+ pos++;
+ }
+ break;
+ }
+ case (NSwitchType::kPostChar):
+ {
+ if (tailSize < switchForm.MinLen)
+ throw "switch is not full";
+ UString set = switchForm.PostCharSet;
+ const int kEmptyCharValue = -1;
+ if (tailSize == 0)
+ matchedSwitch.PostCharIndex = kEmptyCharValue;
+ else
+ {
+ int index = set.Find(s[pos]);
+ if (index < 0)
+ matchedSwitch.PostCharIndex = kEmptyCharValue;
+ else
+ {
+ matchedSwitch.PostCharIndex = index;
+ pos++;
+ }
+ }
+ break;
+ }
+ case NSwitchType::kLimitedPostString: case NSwitchType::kUnLimitedPostString:
+ {
+ int minLen = switchForm.MinLen;
+ if (tailSize < minLen)
+ throw "switch is not full";
+ if (type == NSwitchType::kUnLimitedPostString)
+ {
+ matchedSwitch.PostStrings.Add(s.Mid(pos));
+ return true;
+ }
+ int maxLen = switchForm.MaxLen;
+ UString stringSwitch = s.Mid(pos, minLen);
+ pos += minLen;
+ for(int i = minLen; i < maxLen && pos < len; i++, pos++)
+ {
+ wchar_t c = s[pos];
+ if (IsItSwitchChar(c))
+ break;
+ stringSwitch += c;
+ }
+ matchedSwitch.PostStrings.Add(stringSwitch);
+ }
+ }
+ }
+ return true;
+}
+
+const CSwitchResult& CParser::operator[](size_t index) const
+{
+ return _switches[index];
+}
+
+/////////////////////////////////
+// Command parsing procedures
+
+int ParseCommand(int numCommandForms, const CCommandForm *commandForms,
+ const UString &commandString, UString &postString)
+{
+ for(int i = 0; i < numCommandForms; i++)
+ {
+ const UString id = commandForms[i].IDString;
+ if (commandForms[i].PostStringMode)
+ {
+ if(commandString.Find(id) == 0)
+ {
+ postString = commandString.Mid(id.Length());
+ return i;
+ }
+ }
+ else
+ if (commandString == id)
+ {
+ postString.Empty();
+ return i;
+ }
+ }
+ return -1;
+}
+
+bool ParseSubCharsCommand(int numForms, const CCommandSubCharsSet *forms,
+ const UString &commandString, CIntVector &indices)
+{
+ indices.Clear();
+ int numUsedChars = 0;
+ for(int i = 0; i < numForms; i++)
+ {
+ const CCommandSubCharsSet &set = forms[i];
+ int currentIndex = -1;
+ int len = wcslen(set.Chars);
+ for(int j = 0; j < len; j++)
+ {
+ wchar_t c = set.Chars[j];
+ int newIndex = commandString.Find(c);
+ if (newIndex >= 0)
+ {
+ if (currentIndex >= 0)
+ return false;
+ if (commandString.Find(c, newIndex + 1) >= 0)
+ return false;
+ currentIndex = j;
+ numUsedChars++;
+ }
+ }
+ if(currentIndex == -1 && !set.EmptyAllowed)
+ return false;
+ indices.Add(currentIndex);
+ }
+ return (numUsedChars == commandString.Length());
+}
+
+}
diff --git a/Common/CommandLineParser.h b/Common/CommandLineParser.h
new file mode 100755
index 00000000..187debe6
--- /dev/null
+++ b/Common/CommandLineParser.h
@@ -0,0 +1,84 @@
+// Common/CommandLineParser.h
+
+#pragma once
+
+#ifndef __COMMON_COMMANDLINEPARSER_H
+#define __COMMON_COMMANDLINEPARSER_H
+
+#include "Common/String.h"
+
+namespace NCommandLineParser {
+
+void SplitCommandLine(const UString &src, UString &dest1, UString &dest2);
+void SplitCommandLine(const UString &s, UStringVector &parts);
+
+namespace NSwitchType {
+ enum EEnum
+ {
+ kSimple,
+ kPostMinus,
+ kLimitedPostString,
+ kUnLimitedPostString,
+ kPostChar
+ };
+}
+
+struct CSwitchForm
+{
+ const wchar_t *IDString;
+ NSwitchType::EEnum Type;
+ bool Multi;
+ int MinLen;
+ int MaxLen;
+ const wchar_t *PostCharSet;
+};
+
+struct CSwitchResult
+{
+ bool ThereIs;
+ bool WithMinus;
+ UStringVector PostStrings;
+ int PostCharIndex;
+ CSwitchResult(): ThereIs(false) {};
+};
+
+class CParser
+{
+ int _numSwitches;
+ CSwitchResult *_switches;
+ bool ParseString(const UString &s, const CSwitchForm *switchForms);
+public:
+ UStringVector NonSwitchStrings;
+ CParser(int numSwitches);
+ ~CParser();
+ void ParseStrings(const CSwitchForm *switchForms,
+ const UStringVector &commandStrings);
+ const CSwitchResult& operator[](size_t index) const;
+};
+
+/////////////////////////////////
+// Command parsing procedures
+
+struct CCommandForm
+{
+ wchar_t *IDString;
+ bool PostStringMode;
+};
+
+// Returns: Index of form and postString; -1, if there is no match
+int ParseCommand(int numCommandForms, const CCommandForm *commandForms,
+ const UString &commandString, UString &postString);
+
+struct CCommandSubCharsSet
+{
+ wchar_t *Chars;
+ bool EmptyAllowed;
+};
+
+// Returns: indices of finded chars; -1 if there is no match
+bool ParseSubCharsCommand(int numForms, const CCommandSubCharsSet *forms,
+ const UString &commandString, CIntVector &indices);
+
+}
+
+#endif
diff --git a/Common/Defs.h b/Common/Defs.h
new file mode 100755
index 00000000..bfaaa6c9
--- /dev/null
+++ b/Common/Defs.h
@@ -0,0 +1,22 @@
+// Common/Defs.h
+
+// #pragma once
+
+#ifndef __COMMON_DEFS_H
+#define __COMMON_DEFS_H
+
+template <class T> inline T MyMin(T a, T b)
+ { return a < b ? a : b; }
+template <class T> inline T MyMax(T a, T b)
+ { return a > b ? a : b; }
+
+template <class T> inline int MyCompare(T a, T b)
+ { return a < b ? -1 : (a == b ? 0 : 1); }
+
+inline int BoolToInt(bool value)
+ { return (value ? 1: 0); }
+
+inline bool IntToBool(int value)
+ { return (value != 0); }
+
+#endif
diff --git a/Common/DynamicBuffer.h b/Common/DynamicBuffer.h
new file mode 100755
index 00000000..c41900c5
--- /dev/null
+++ b/Common/DynamicBuffer.h
@@ -0,0 +1,49 @@
+// Common/DynamicBuffer.h
+
+#pragma once
+
+#ifndef __COMMON_DYNAMICBUFFER_H
+#define __COMMON_DYNAMICBUFFER_H
+
+#include "Buffer.h"
+
+template <class T> class CDynamicBuffer: public CBuffer<T>
+{
+ void GrowLength(size_t size)
+ {
+ size_t delta;
+ if (_capacity > 64)
+ delta = _capacity / 4;
+ else if (_capacity > 8)
+ delta = 16;
+ else
+ delta = 4;
+ delta = MyMax(delta, size);
+ SetCapacity(_capacity + delta);
+ }
+public:
+ CDynamicBuffer(): CBuffer<T>() {};
+ CDynamicBuffer(const CDynamicBuffer &buffer): CBuffer<T>(buffer) {};
+ CDynamicBuffer(size_t size): CBuffer<T>(size) {};
+ CDynamicBuffer& operator=(const CDynamicBuffer &buffer)
+ {
+ Free();
+ if(buffer._capacity > 0)
+ {
+ SetCapacity(buffer._capacity);
+ memmove(_items, buffer._items, buffer._capacity * sizeof(T));
+ }
+ return *this;
+ }
+ void EnsureCapacity(size_t capacity)
+ {
+ if (_capacity < capacity)
+ GrowLength(capacity - _capacity);
+ }
+};
+
+typedef CDynamicBuffer<char> CCharDynamicBuffer;
+typedef CDynamicBuffer<wchar_t> CWCharDynamicBuffer;
+typedef CDynamicBuffer<unsigned char> CByteDynamicBuffer;
+
+#endif
diff --git a/Common/Exception.h b/Common/Exception.h
new file mode 100755
index 00000000..a1023950
--- /dev/null
+++ b/Common/Exception.h
@@ -0,0 +1,24 @@
+// Common/Exception.h
+
+// #pragma once
+
+#ifndef __COMMON_EXCEPTION_H
+#define __COMMON_EXCEPTION_H
+
+/*
+struct CCException
+{
+ CCException() {}
+ virtual ~CCException() {}
+};
+*/
+
+struct CSystemException
+{
+ DWORD ErrorCode;
+ CSystemException(): ErrorCode(::GetLastError()) {}
+ CSystemException(DWORD errorCode): ErrorCode(errorCode) {}
+};
+
+#endif
+
diff --git a/Common/IntToString.cpp b/Common/IntToString.cpp
new file mode 100755
index 00000000..142fa218
--- /dev/null
+++ b/Common/IntToString.cpp
@@ -0,0 +1,57 @@
+// Common/IntToString.cpp
+
+#include "StdAfx.h"
+
+#include "IntToString.h"
+
+void ConvertUINT64ToString(UINT64 value, char *s)
+{
+ char temp[32];
+ int pos = 0;
+ do
+ {
+ temp[pos++] = '0' + int(value % 10);
+ value /= 10;
+ }
+ while (value != 0);
+ while(pos > 0)
+ *s++ = temp[--pos];
+ *s = L'\0';
+}
+
+void ConvertUINT64ToString(UINT64 value, wchar_t *s)
+{
+ wchar_t temp[32];
+ int pos = 0;
+ do
+ {
+ temp[pos++] = L'0' + int(value % 10);
+ value /= 10;
+ }
+ while (value != 0);
+ while(pos > 0)
+ *s++ = temp[--pos];
+ *s = L'\0';
+}
+
+void ConvertINT64ToString(INT64 value, char *s)
+{
+ if (value >= 0)
+ ConvertUINT64ToString(value, s);
+ else
+ {
+ *s++ = '-';
+ ConvertUINT64ToString(-value, s);
+ }
+}
+
+void ConvertINT64ToString(INT64 value, wchar_t *s)
+{
+ if (value >= 0)
+ ConvertUINT64ToString(value, s);
+ else
+ {
+ *s++ = L'-';
+ ConvertUINT64ToString(-value, s);
+ }
+}
diff --git a/Common/IntToString.h b/Common/IntToString.h
new file mode 100755
index 00000000..a40acfba
--- /dev/null
+++ b/Common/IntToString.h
@@ -0,0 +1,18 @@
+// Common/IntToString.h
+
+#pragma once
+
+#ifndef __COMMON_INTTOSTRING_H
+#define __COMMON_INTTOSTRING_H
+
+#include "types.h"
+
+void ConvertUINT64ToString(UINT64 value, char *s);
+void ConvertUINT64ToString(UINT64 value, wchar_t *s);
+
+void ConvertINT64ToString(INT64 value, char *s);
+void ConvertINT64ToString(INT64 value, wchar_t *s);
+
+#endif
+
+
diff --git a/Common/Lang.cpp b/Common/Lang.cpp
new file mode 100755
index 00000000..9a004c37
--- /dev/null
+++ b/Common/Lang.cpp
@@ -0,0 +1,144 @@
+// Common/Lang.cpp
+
+#include "StdAfx.h"
+
+#include "Common/Lang.h"
+#include "Common/TextConfig.h"
+
+#include "StdInStream.h"
+#include "UTFConvert.h"
+#include "Defs.h"
+
+/*
+static UINT32 HexStringToNumber(const char *string, int &finishPos)
+{
+ UINT32 number = 0;
+ for (finishPos = 0; finishPos < 8; finishPos++)
+ {
+ char c = string[finishPos];
+ int a;
+ if (c >= '0' && c <= '9')
+ a = c - '0';
+ else if (c >= 'A' && c <= 'F')
+ a = 10 + c - 'A';
+ else if (c >= 'a' && c <= 'f')
+ a = 10 + c - 'a';
+ else
+ return number;
+ number *= 0x10;
+ number += a;
+ }
+ return number;
+}
+*/
+static bool HexStringToNumber(const UString &string, UINT32 &aResultValue)
+{
+ aResultValue = 0;
+ if (string.IsEmpty())
+ return false;
+ for (int i = 0; i < string.Length(); i++)
+ {
+ wchar_t c = string[i];
+ int a;
+ if (c >= L'0' && c <= L'9')
+ a = c - L'0';
+ else if (c >= L'A' && c <= L'F')
+ a = 10 + c - L'A';
+ else if (c >= L'a' && c <= L'f')
+ a = 10 + c - L'a';
+ else
+ return false;
+ aResultValue *= 0x10;
+ aResultValue += a;
+ }
+ return true;
+}
+
+
+static bool WaitNextLine(const AString &string, int &pos)
+{
+ for (;pos < string.Length(); pos++)
+ if (string[pos] == 0x0A)
+ return true;
+ return false;
+}
+
+static int __cdecl CompareLangItems( const void *elem1, const void *elem2)
+{
+ const CLangPair &langPair1 = *(*((const CLangPair **)elem1));
+ const CLangPair &langPair2 = *(*((const CLangPair **)elem2));
+ return MyCompare(langPair1.Value, langPair2.Value);
+}
+
+bool CLang::Open(LPCTSTR fileName)
+{
+ _langPairs.Clear();
+ CStdInStream file;
+ if (!file.Open(fileName))
+ return false;
+ AString string;
+ file.ReadToString(string);
+ file.Close();
+ int pos = 0;
+ if (string.Length() >= 3)
+ {
+ if (BYTE(string[0]) == 0xEF && BYTE(string[1]) == 0xBB && BYTE(string[2]) == 0xBF)
+ pos += 3;
+ }
+
+ /////////////////////
+ // read header
+
+ AString stringID = ";!@Lang@!UTF-8!";
+ if (string.Mid(pos, stringID.Length()) != stringID)
+ return false;
+ pos += stringID.Length();
+
+ if (!WaitNextLine(string, pos))
+ return false;
+
+ CObjectVector<CTextConfigPair> pairs;
+ if (!GetTextConfig(string.Mid(pos), pairs))
+ return false;
+
+ _langPairs.Reserve(_langPairs.Size());
+ for (int i = 0; i < pairs.Size(); i++)
+ {
+ CTextConfigPair textConfigPair = pairs[i];
+ CLangPair langPair;
+ if (!HexStringToNumber(textConfigPair.ID, langPair.Value))
+ return false;
+ langPair.String = textConfigPair.String;
+ _langPairs.Add(langPair);
+ }
+
+ CPointerVector &pointerVector = _langPairs;
+ qsort(&pointerVector[0], _langPairs.Size(), sizeof(void *), CompareLangItems);
+ return true;
+}
+
+int CLang::FindItem(UINT32 value) const
+{
+ int left = 0, right = _langPairs.Size();
+ while (left != right)
+ {
+ UINT32 mid = (left + right) / 2;
+ UINT32 midValue = _langPairs[mid].Value;
+ if (value == midValue)
+ return mid;
+ if (value < midValue)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ return -1;
+}
+
+bool CLang::GetMessage(UINT32 value, UString &message) const
+{
+ int index = FindItem(value);
+ if (index < 0)
+ return false;
+ message = _langPairs[index].String;
+ return true;
+}
diff --git a/Common/Lang.h b/Common/Lang.h
new file mode 100755
index 00000000..683268db
--- /dev/null
+++ b/Common/Lang.h
@@ -0,0 +1,29 @@
+// Common/Lang.h
+
+#pragma once
+
+#ifndef __COMMON_LANG_H
+#define __COMMON_LANG_H
+
+#include "Common/Vector.h"
+#include "Common/String.h"
+
+struct CLangPair
+{
+ UINT32 Value;
+ UString String;
+};
+
+class CLang
+{
+ CObjectVector<CLangPair> _langPairs;
+public:
+ bool Open(LPCTSTR fileName);
+ void Clear() { _langPairs.Clear(); }
+ int FindItem(UINT32 value) const;
+ bool GetMessage(UINT32 value, UString &message) const;
+};
+
+#endif
+
+
diff --git a/Common/ListFileUtils.cpp b/Common/ListFileUtils.cpp
new file mode 100755
index 00000000..e4370f48
--- /dev/null
+++ b/Common/ListFileUtils.cpp
@@ -0,0 +1,55 @@
+// Common/ListFileUtils.cpp
+
+#include "StdAfx.h"
+
+#include "ListFileUtils.h"
+#include "StdInStream.h"
+#include "StringConvert.h"
+#include "UTFConvert.h"
+
+static const char kQuoteChar = '\"';
+static void RemoveQuote(UString &s)
+{
+ if (s.Length() >= 2)
+ if (s[0] == kQuoteChar && s[s.Length() - 1] == kQuoteChar)
+ s = s.Mid(1, s.Length() - 2);
+}
+
+bool ReadNamesFromListFile(LPCTSTR fileName, UStringVector &resultStrings,
+ UINT codePage)
+{
+ CStdInStream file;
+ if (!file.Open(fileName))
+ return false;
+
+ AString s;
+ file.ReadToString(s);
+ UString u;
+ if (codePage == CP_UTF8)
+ {
+ if (!ConvertUTF8ToUnicode(s, u))
+ return false;
+ }
+ else
+ u = MultiByteToUnicodeString(s, codePage);
+ UString t;
+ for(int i = 0; i < u.Length(); i++)
+ {
+ wchar_t c = u[i];
+ if (c == L'\n')
+ {
+ t.Trim();
+ RemoveQuote(t);
+ if (!t.IsEmpty())
+ resultStrings.Add(t);
+ t.Empty();
+ }
+ else
+ t += c;
+ }
+ t.Trim();
+ RemoveQuote(t);
+ if (!t.IsEmpty())
+ resultStrings.Add(t);
+ return true;
+}
diff --git a/Common/ListFileUtils.h b/Common/ListFileUtils.h
new file mode 100755
index 00000000..7debead8
--- /dev/null
+++ b/Common/ListFileUtils.h
@@ -0,0 +1,14 @@
+// Common/ListFileUtils.h
+
+#pragma once
+
+#ifndef __COMMON_LISTFILEUTILS_H
+#define __COMMON_LISTFILEUTILS_H
+
+#include "Common/String.h"
+#include "Common/Types.h"
+
+bool ReadNamesFromListFile(LPCTSTR fileName, UStringVector &strings,
+ UINT codePage = CP_OEMCP);
+
+#endif
diff --git a/Common/MyCom.h b/Common/MyCom.h
new file mode 100755
index 00000000..40e4ce29
--- /dev/null
+++ b/Common/MyCom.h
@@ -0,0 +1,187 @@
+// MyCom.h
+
+// #pragma once
+
+#ifndef __MYCOM_H
+#define __MYCOM_H
+
+#define RINOK(x) { HRESULT __result_ = (x); if(__result_ != S_OK) return __result_; }
+
+template <class T>
+class CMyComPtr
+{
+ T* _p;
+public:
+ // typedef T _PtrClass;
+ CMyComPtr() { _p = NULL;}
+ CMyComPtr(T* p) {if ((_p = p) != NULL) p->AddRef(); }
+ CMyComPtr(const CMyComPtr<T>& lp)
+ {
+ if ((_p = lp._p) != NULL)
+ _p->AddRef();
+ }
+ ~CMyComPtr() { if (_p) _p->Release(); }
+ void Release() { if (_p) { _p->Release(); _p = NULL; } }
+ operator T*() const { return (T*)_p; }
+ // T& operator*() const { return *_p; }
+ T** operator&() { return &_p; }
+ T* operator->() const { return _p; }
+ T* operator=(T* p)
+ {
+ if (p != 0)
+ p->AddRef();
+ if (_p)
+ _p->Release();
+ _p = p;
+ return p;
+ }
+ T* operator=(const CMyComPtr<T>& lp) { return (*this = lp._p); }
+ bool operator!() const { return (_p == NULL); }
+ // bool operator==(T* pT) const { return _p == pT; }
+ // Compare two objects for equivalence
+ void Attach(T* p2)
+ {
+ Release();
+ _p = p2;
+ }
+ T* Detach()
+ {
+ T* pt = _p;
+ _p = NULL;
+ return pt;
+ }
+ HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
+ {
+ return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p);
+ }
+ /*
+ HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
+ {
+ CLSID clsid;
+ HRESULT hr = CLSIDFromProgID(szProgID, &clsid);
+ ATLASSERT(_p == NULL);
+ if (SUCCEEDED(hr))
+ hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&_p);
+ return hr;
+ }
+ */
+ template <class Q>
+ HRESULT QueryInterface(REFGUID iid, Q** pp) const
+ {
+ return _p->QueryInterface(iid, (void**)pp);
+ }
+};
+
+//////////////////////////////////////////////////////////
+
+class CMyComBSTR
+{
+public:
+ BSTR m_str;
+ CMyComBSTR() { m_str = NULL; }
+ CMyComBSTR(LPCOLESTR pSrc) { m_str = ::SysAllocString(pSrc); }
+ // CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); }
+ // CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize); }
+ CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); }
+ /*
+ CMyComBSTR(REFGUID src)
+ {
+ LPOLESTR szGuid;
+ StringFromCLSID(src, &szGuid);
+ m_str = ::SysAllocString(szGuid);
+ CoTaskMemFree(szGuid);
+ }
+ */
+ ~CMyComBSTR() { ::SysFreeString(m_str); }
+ CMyComBSTR& operator=(const CMyComBSTR& src)
+ {
+ if (m_str != src.m_str)
+ {
+ if (m_str)
+ ::SysFreeString(m_str);
+ m_str = src.MyCopy();
+ }
+ return *this;
+ }
+ CMyComBSTR& operator=(LPCOLESTR pSrc)
+ {
+ ::SysFreeString(m_str);
+ m_str = ::SysAllocString(pSrc);
+ return *this;
+ }
+ unsigned int Length() const { return ::SysStringLen(m_str); }
+ operator BSTR() const { return m_str; }
+ BSTR* operator&() { return &m_str; }
+ BSTR MyCopy() const
+ {
+ int byteLen = ::SysStringByteLen(m_str);
+ BSTR res = ::SysAllocStringByteLen(NULL, byteLen);
+ memmove(res, m_str, byteLen);
+ return res;
+ }
+ void Attach(BSTR src) { m_str = src; }
+ BSTR Detach()
+ {
+ BSTR s = m_str;
+ m_str = NULL;
+ return s;
+ }
+ void Empty()
+ {
+ ::SysFreeString(m_str);
+ m_str = NULL;
+ }
+ bool operator!() const { return (m_str == NULL); }
+};
+
+
+//////////////////////////////////////////////////////////
+
+class CMyUnknownImp
+{
+public:
+ ULONG __m_RefCount;
+ CMyUnknownImp(): __m_RefCount(0) {}
+};
+
+#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \
+ (REFGUID iid, void **outObject) {
+#define MY_QUERYINTERFACE_ENTRY(i) if (iid == IID_ ## i) \
+ { *outObject = (void *)(i *)this; AddRef(); return S_OK; }
+#define MY_QUERYINTERFACE_END return E_NOINTERFACE; }
+
+#define MY_ADDREF_RELEASE \
+STDMETHOD_(ULONG, AddRef)() { return ++__m_RefCount; } \
+STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \
+ return __m_RefCount; delete this; return 0; }
+
+#define MY_UNKNOWN_IMP_SPEC(i) \
+ MY_QUERYINTERFACE_BEGIN \
+ i \
+ MY_QUERYINTERFACE_END \
+ MY_ADDREF_RELEASE
+
+
+#define MY_UNKNOWN_IMP MY_UNKNOWN_IMP_SPEC(;)
+
+#define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY(i) \
+ )
+
+#define MY_UNKNOWN_IMP2(i1, i2) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ )
+#define MY_UNKNOWN_IMP3(i1, i2, i3) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ )
+#define MY_UNKNOWN_IMP4(i1, i2, i3, i4) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ MY_QUERYINTERFACE_ENTRY(i4) \
+ )
+
+#endif
diff --git a/Common/NewHandler.cpp b/Common/NewHandler.cpp
new file mode 100755
index 00000000..d45d51b0
--- /dev/null
+++ b/Common/NewHandler.cpp
@@ -0,0 +1,105 @@
+// NewHandler.cpp
+
+#include "StdAfx.h"
+
+#include "NewHandler.h"
+
+// #define DEBUG_MEMORY_LEAK
+
+#ifndef DEBUG_MEMORY_LEAK
+
+
+void * __cdecl operator new(size_t size)
+{
+ // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
+ void *p = ::malloc(size);
+ if (p == 0)
+ throw CNewException();
+ return p;
+}
+
+void __cdecl operator delete(void *p)
+{
+ /*
+ if (p == 0)
+ return;
+ ::HeapFree(::GetProcessHeap(), 0, p);
+ */
+ ::free(p);
+}
+
+#else
+
+#pragma init_seg(lib)
+const int kDebugSize = 1000000;
+static void *a[kDebugSize];
+static int index = 0;
+
+static int numAllocs = 0;
+void * __cdecl operator new(size_t size)
+{
+ numAllocs++;
+ void *p = HeapAlloc(GetProcessHeap(), 0, size);
+ if (index == 40)
+ {
+ int t = 1;
+ }
+ if (index < kDebugSize)
+ {
+ a[index] = p;
+ index++;
+ }
+ if (p == 0)
+ throw CNewException();
+ printf("Alloc %6d, size = %8d\n", numAllocs, size);
+ return p;
+}
+
+class CC
+{
+public:
+ CC()
+ {
+ for (int i = 0; i < kDebugSize; i++)
+ a[i] = 0;
+ }
+ ~CC()
+ {
+ for (int i = 0; i < kDebugSize; i++)
+ if (a[i] != 0)
+ return;
+ }
+} g_CC;
+
+
+void __cdecl operator delete(void *p)
+{
+ if (p == 0)
+ return;
+ /*
+ for (int i = 0; i < index; i++)
+ if (a[i] == p)
+ a[i] = 0;
+ */
+ HeapFree(GetProcessHeap(), 0, p);
+ numAllocs--;
+ printf("Free %d\n", numAllocs);
+}
+
+#endif
+
+/*
+int MemErrorVC(size_t)
+{
+ throw CNewException();
+ // return 1;
+}
+CNewHandlerSetter::CNewHandlerSetter()
+{
+ // MemErrorOldVCFunction = _set_new_handler(MemErrorVC);
+}
+CNewHandlerSetter::~CNewHandlerSetter()
+{
+ // _set_new_handler(MemErrorOldVCFunction);
+}
+*/
diff --git a/Common/NewHandler.h b/Common/NewHandler.h
new file mode 100755
index 00000000..c1e430e2
--- /dev/null
+++ b/Common/NewHandler.h
@@ -0,0 +1,12 @@
+// Common/NewHandler.h
+
+#pragma once
+
+#ifndef __COMMON_NEWHANDLER_H
+#define __COMMON_NEWHANDLER_H
+
+#include "Exception.h"
+
+class CNewException: public CSystemException{};
+
+#endif
diff --git a/Common/Random.cpp b/Common/Random.cpp
new file mode 100755
index 00000000..6232a920
--- /dev/null
+++ b/Common/Random.cpp
@@ -0,0 +1,16 @@
+// Common/Random.cpp
+
+#include "StdAfx.h"
+
+#include <time.h>
+
+#include "Common/Random.h"
+
+void CRandom::Init(unsigned int seed)
+ { srand(seed); }
+
+void CRandom::Init()
+ { Init(time(NULL)); }
+
+int CRandom::Generate() const
+ { return rand(); }
diff --git a/Common/Random.h b/Common/Random.h
new file mode 100755
index 00000000..6f3b39b7
--- /dev/null
+++ b/Common/Random.h
@@ -0,0 +1,18 @@
+// Common/Random.h
+
+#pragma once
+
+#ifndef __COMMON_RANDOM_H
+#define __COMMON_RANDOM_H
+
+class CRandom
+{
+public:
+ void Init();
+ void Init(unsigned int seed);
+ int Generate() const;
+};
+
+#endif
+
+
diff --git a/Common/StdAfx.h b/Common/StdAfx.h
new file mode 100755
index 00000000..a32fbed6
--- /dev/null
+++ b/Common/StdAfx.h
@@ -0,0 +1,8 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#endif
diff --git a/Common/StdInStream.cpp b/Common/StdInStream.cpp
new file mode 100755
index 00000000..9c45da29
--- /dev/null
+++ b/Common/StdInStream.cpp
@@ -0,0 +1,78 @@
+// Common/StdInStream.cpp
+
+#include "StdAfx.h"
+
+#include <tchar.h>
+#include "StdInStream.h"
+
+static const char kIllegalChar = '\0';
+static const char kNewLineChar = '\n';
+
+static const char *kEOFMessage = "Unexpected end of input stream";
+static const char *kReadErrorMessage ="Error reading input stream";
+static const char *kIllegalCharMessage = "Illegal character in input stream";
+
+static LPCTSTR kFileOpenMode = TEXT("r");
+
+CStdInStream g_StdIn(stdin);
+
+bool CStdInStream::Open(LPCTSTR fileName)
+{
+ Close();
+ _stream = _tfopen(fileName, kFileOpenMode);
+ _streamIsOpen = (_stream != 0);
+ return _streamIsOpen;
+}
+
+bool CStdInStream::Close()
+{
+ if(!_streamIsOpen)
+ return true;
+ _streamIsOpen = (fclose(_stream) != 0);
+ return !_streamIsOpen;
+}
+
+CStdInStream::~CStdInStream()
+{
+ Close();
+}
+
+AString CStdInStream::ScanStringUntilNewLine()
+{
+ AString string;
+ while(true)
+ {
+ int aIntChar = GetChar();
+ if(aIntChar == EOF)
+ throw kEOFMessage;
+ char aChar = char(aIntChar);
+ if (aChar == kIllegalChar)
+ throw kIllegalCharMessage;
+ if(aChar == kNewLineChar)
+ return string;
+ string += aChar;
+ }
+}
+
+void CStdInStream::ReadToString(AString &resultString)
+{
+ resultString.Empty();
+ int c;
+ while((c = GetChar()) != EOF)
+ resultString += char(c);
+}
+
+bool CStdInStream::Eof()
+{
+ return (feof(_stream) != 0);
+}
+
+int CStdInStream::GetChar()
+{
+ int c = getc(_stream);
+ if(c == EOF && !Eof())
+ throw kReadErrorMessage;
+ return c;
+}
+
+
diff --git a/Common/StdInStream.h b/Common/StdInStream.h
new file mode 100755
index 00000000..2a5c18f1
--- /dev/null
+++ b/Common/StdInStream.h
@@ -0,0 +1,33 @@
+// Common/StdInStream.h
+
+#pragma once
+
+#ifndef __COMMON_STDINSTREAM_H
+#define __COMMON_STDINSTREAM_H
+
+#include <stdio.h>
+
+#include "String.h"
+#include "Types.h"
+
+class CStdInStream
+{
+ bool _streamIsOpen;
+ FILE *_stream;
+public:
+ CStdInStream(): _streamIsOpen(false) {};
+ CStdInStream(FILE *stream): _streamIsOpen(false), _stream(stream) {};
+ ~CStdInStream();
+ bool Open(LPCTSTR fileName);
+ bool Close();
+
+ AString ScanStringUntilNewLine();
+ void ReadToString(AString &resultString);
+
+ bool Eof();
+ int GetChar();
+};
+
+extern CStdInStream g_StdIn;
+
+#endif
diff --git a/Common/StdOutStream.cpp b/Common/StdOutStream.cpp
new file mode 100755
index 00000000..f1174a83
--- /dev/null
+++ b/Common/StdOutStream.cpp
@@ -0,0 +1,80 @@
+// Common/StdOutStream.cpp
+
+#include "StdAfx.h"
+
+#include <tchar.h>
+
+#include "StdOutStream.h"
+#include "Common/IntToString.h"
+#include "Common/StringConvert.h"
+
+static const char kNewLineChar = '\n';
+
+static LPCTSTR kFileOpenMode = TEXT("wt");
+
+CStdOutStream g_StdOut(stdout);
+CStdOutStream g_StdErr(stderr);
+
+bool CStdOutStream::Open(LPCTSTR fileName)
+{
+ Close();
+ _stream = _tfopen(fileName, kFileOpenMode);
+ _streamIsOpen = (_stream != 0);
+ return _streamIsOpen;
+}
+
+bool CStdOutStream::Close()
+{
+ if(!_streamIsOpen)
+ return true;
+ _streamIsOpen = (fclose(_stream) != 0);
+ return !_streamIsOpen;
+}
+
+CStdOutStream::~CStdOutStream ()
+{
+ Close();
+}
+
+CStdOutStream & CStdOutStream::operator<<(CStdOutStream & (*aFunction)(CStdOutStream &))
+{
+ (*aFunction)(*this);
+ return *this;
+}
+
+CStdOutStream & endl(CStdOutStream & outStream)
+{
+ return outStream << kNewLineChar;
+}
+
+CStdOutStream & CStdOutStream::operator<<(const char *string)
+{
+ fputs(string, _stream);
+ return *this;
+}
+
+CStdOutStream & CStdOutStream::operator<<(const wchar_t *string)
+{
+ *this << (const char *)UnicodeStringToMultiByte(string, CP_OEMCP);
+ return *this;
+}
+
+CStdOutStream & CStdOutStream::operator<<(char c)
+{
+ fputc(c, _stream);
+ return *this;
+}
+
+CStdOutStream & CStdOutStream::operator<<(int number)
+{
+ char textString[16];
+ ConvertINT64ToString(number, textString);
+ return operator<<(textString);
+}
+
+CStdOutStream & CStdOutStream::operator<<(UINT64 number)
+{
+ char textString[32];
+ ConvertUINT64ToString(number, textString);
+ return operator<<(textString);
+}
diff --git a/Common/StdOutStream.h b/Common/StdOutStream.h
new file mode 100755
index 00000000..8ebf9aa7
--- /dev/null
+++ b/Common/StdOutStream.h
@@ -0,0 +1,36 @@
+// Common/StdOutStream.h
+
+#pragma once
+
+#ifndef __COMMON_STDOUTSTREAM_H
+#define __COMMON_STDOUTSTREAM_H
+
+#include <stdio.h>
+
+#include "Types.h"
+
+class CStdOutStream
+{
+ bool _streamIsOpen;
+ FILE *_stream;
+public:
+ CStdOutStream (): _streamIsOpen(false) {};
+ CStdOutStream (FILE *stream): _streamIsOpen(false), _stream(stream) {};
+ ~CStdOutStream ();
+ bool Open(LPCTSTR fileName);
+ bool Close();
+
+ CStdOutStream & operator<<(CStdOutStream & (* aFunction)(CStdOutStream &));
+ CStdOutStream & operator<<(const char *string);
+ CStdOutStream & operator<<(const wchar_t *string);
+ CStdOutStream & operator<<(char c);
+ CStdOutStream & operator<<(int number);
+ CStdOutStream & operator<<(UINT64 number);
+};
+
+CStdOutStream & endl(CStdOutStream & outStream);
+
+extern CStdOutStream g_StdOut;
+extern CStdOutStream g_StdErr;
+
+#endif
diff --git a/Common/String.cpp b/Common/String.cpp
new file mode 100755
index 00000000..6e109b70
--- /dev/null
+++ b/Common/String.cpp
@@ -0,0 +1,84 @@
+// Common/String.cpp
+
+#include "StdAfx.h"
+
+#include "String.h"
+#include "StringConvert.h"
+
+#ifndef _UNICODE
+
+wchar_t MyCharUpper(wchar_t c)
+{
+ if (c == 0)
+ return 0;
+ wchar_t *res = CharUpperW((LPWSTR)c);
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return (wchar_t)res;
+ const int kBufferSize = 4;
+ char s[kBufferSize];
+ int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0);
+ ::CharUpperA(s);
+ ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1);
+ return c;
+}
+
+wchar_t MyCharLower(wchar_t c)
+{
+ if (c == 0)
+ return 0;
+ wchar_t *res = CharLowerW((LPWSTR)c);
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return (wchar_t)res;
+ const int kBufferSize = 4;
+ char s[kBufferSize];
+ int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0);
+ ::CharLowerA(s);
+ ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1);
+ return c;
+}
+
+wchar_t * MyStringUpper(wchar_t *s)
+{
+ if (s == 0)
+ return 0;
+ wchar_t *res = CharUpperW(s);
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return res;
+ AString a = UnicodeStringToMultiByte(s);
+ a.MakeUpper();
+ return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
+}
+
+wchar_t * MyStringLower(wchar_t *s)
+{
+ if (s == 0)
+ return 0;
+ wchar_t *res = CharLowerW(s);
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return res;
+ AString a = UnicodeStringToMultiByte(s);
+ a.MakeLower();
+ return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
+}
+
+int MyStringCollate(const wchar_t *s1, const wchar_t *s2)
+{
+ int res = CompareStringW(
+ LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1);
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return ConvertCompareResult(res);
+ return MyStringCollate(UnicodeStringToMultiByte(s1),
+ UnicodeStringToMultiByte(s2));
+}
+
+int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2)
+{
+ int res = CompareStringW(
+ LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1);
+ if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return ConvertCompareResult(res);
+ return MyStringCollateNoCase(UnicodeStringToMultiByte(s1),
+ UnicodeStringToMultiByte(s2));
+}
+
+#endif
diff --git a/Common/String.h b/Common/String.h
new file mode 100755
index 00000000..be273271
--- /dev/null
+++ b/Common/String.h
@@ -0,0 +1,672 @@
+// Common/String.h
+
+#pragma once
+
+#ifndef __COMMON_STRING_H
+#define __COMMON_STRING_H
+
+#include "Vector.h"
+
+extern bool g_IsNT;
+
+static const char *kTrimDefaultCharSet = " \n\t";
+
+template <class T>
+inline size_t MyStringLen(const T *s)
+{
+ int i;
+ for (i = 0; s[i] != '\0'; i++);
+ return i;
+}
+
+template <class T>
+inline T * MyStringCopy(T *dest, const T *src)
+{
+ T *destStart = dest;
+ while((*dest++ = *src++) != 0);
+ return destStart;
+}
+
+inline wchar_t* MyStringGetNextCharPointer(wchar_t *p)
+ { return (p + 1); }
+inline const wchar_t* MyStringGetNextCharPointer(const wchar_t *p)
+ { return (p + 1); }
+inline wchar_t* MyStringGetPrevCharPointer(const wchar_t *base, wchar_t *p)
+ { return (p - 1); }
+inline const wchar_t* MyStringGetPrevCharPointer(const wchar_t *base, const wchar_t *p)
+ { return (p - 1); }
+
+#ifdef WIN32
+
+inline char* MyStringGetNextCharPointer(char *p)
+ { return CharNextA(p); }
+inline const char* MyStringGetNextCharPointer(const char *p)
+ { return CharNextA(p); }
+
+inline char* MyStringGetPrevCharPointer(char *base, char *p)
+ { return CharPrevA(base, p); }
+inline const char* MyStringGetPrevCharPointer(const char *base, const char *p)
+ { return CharPrevA(base, p); }
+
+inline char MyCharUpper(char c)
+ { return (char)CharUpperA((LPSTR)(unsigned char)c); }
+#ifdef _UNICODE
+inline wchar_t MyCharUpper(wchar_t c)
+ { return (wchar_t)CharUpperW((LPWSTR)c); }
+#else
+wchar_t MyCharUpper(wchar_t c);
+#endif
+
+inline char MyCharLower(char c)
+ { return (char)CharLowerA((LPSTR)(unsigned char)c); }
+#ifdef _UNICODE
+inline wchar_t MyCharLower(wchar_t c)
+ { return (wchar_t)CharLowerW((LPWSTR)c); }
+#else
+wchar_t MyCharLower(wchar_t c);
+#endif
+
+
+inline char * MyStringUpper(char *s)
+ { return CharUpperA(s); }
+#ifdef _UNICODE
+inline wchar_t * MyStringUpper(wchar_t *s)
+ { return CharUpperW(s); }
+#else
+wchar_t * MyStringUpper(wchar_t *s);
+#endif
+
+inline char * MyStringLower(char *s)
+ { return CharLowerA(s); }
+#ifdef _UNICODE
+inline wchar_t * MyStringLower(wchar_t *s)
+ { return CharLowerW(s); }
+#else
+wchar_t * MyStringLower(wchar_t *s);
+#endif
+
+
+//////////////////////////////////////
+// Compare
+
+inline int ConvertCompareResult(int r)
+ { return r - 2; }
+
+inline int MyStringCollate(const char *s1, const char *s2)
+ { return ConvertCompareResult(CompareStringA(
+ LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1)); }
+#ifdef _UNICODE
+inline int MyStringCollate(const wchar_t *s1, const wchar_t *s2)
+ { return ConvertCompareResult(CompareStringW(
+ LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1)); }
+#else
+int MyStringCollate(const wchar_t *s1, const wchar_t *s2);
+#endif
+
+inline int MyStringCollateNoCase(const char *s1, const char *s2)
+ { return ConvertCompareResult(CompareStringA(
+ LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1)); }
+#ifdef _UNICODE
+inline int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2)
+ { return ConvertCompareResult(CompareStringW(
+ LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1)); }
+#else
+int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2);
+#endif
+
+#else // Standard-C
+
+inline NormalizeCompareResult(int res)
+{
+ if (res < 0)
+ return -1;
+ if (res > 0)
+ return 1;
+ return 0;
+}
+
+inline wchar_t MyCharUpper(wchar_t c)
+ { return towupper(c); }
+
+inline int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2)
+ { return NormalizeCompareResult(wcscoll(s1, s2)); }
+
+#endif
+
+
+template <class T>
+inline int MyStringCompare(const T *s1, const T *s2)
+{
+ while (true)
+ {
+ unsigned int c1 = (unsigned int)*s1++;
+ unsigned int c2 = (unsigned int)*s2++;
+ if (c1 < c2)
+ return -1;
+ if (c1 > c2)
+ return 1;
+ if (c1 == 0)
+ return 0;
+ }
+}
+
+template <class T>
+inline int MyStringCompareNoCase(const T *s1, const T *s2)
+ { return MyStringCollateNoCase(s1, s2); }
+
+template <class T>
+class CStringBase
+{
+ void TrimLeftWithCharSet(const CStringBase &charSet)
+ {
+ const T *p = _chars;
+ while (charSet.Find(*p) >= 0 && (*p != 0))
+ p = GetNextCharPointer(p);
+ Delete(0, p - _chars);
+ }
+ void TrimRightWithCharSet(const CStringBase &charSet)
+ {
+ const T *p = _chars;
+ const T *pLast = NULL;
+ while (*p != 0)
+ {
+ if (charSet.Find(*p) >= 0)
+ {
+ if (pLast == NULL)
+ pLast = p;
+ }
+ else
+ pLast = NULL;
+ p = GetNextCharPointer(p);
+ }
+ if(pLast != NULL)
+ {
+ int i = pLast - _chars;
+ Delete(i, _length - i);
+ }
+
+ }
+ void MoveItems(int destIndex, int srcIndex)
+ {
+ memmove(_chars + destIndex, _chars + srcIndex,
+ sizeof(T) * (_length - srcIndex + 1));
+ }
+
+ void InsertSpace(int &index, int size)
+ {
+ CorrectIndex(index);
+ GrowLength(size);
+ MoveItems(index + size, index);
+ }
+
+ static T *GetNextCharPointer(T *p)
+ { return MyStringGetNextCharPointer(p); }
+ static const T *GetNextCharPointer(const T *p)
+ { return MyStringGetNextCharPointer(p); }
+ static T *GetPrevCharPointer(T *base, T *p)
+ { return MyStringGetPrevCharPointer(base, p); }
+ static const T *GetPrevCharPointer(const T *base, const T *p)
+ { return MyStringGetPrevCharPointer(base, p); }
+protected:
+ T *_chars;
+ int _length;
+ int _capacity;
+
+ void SetCapacity(int newCapacity)
+ {
+ int realCapacity = newCapacity + 1;
+ if(realCapacity == _capacity)
+ return;
+ /*
+ const int kMaxStringSize = 0x20000000;
+ #ifndef _WIN32_WCE
+ if(newCapacity > kMaxStringSize || newCapacity < _length)
+ throw 1052337;
+ #endif
+ */
+ T *newBuffer = new T[realCapacity];
+ if(_capacity > 0)
+ {
+ for (int i = 0; i < (_length + 1); i++)
+ newBuffer[i] = _chars[i];
+ delete []_chars;
+ _chars = newBuffer;
+ }
+ else
+ {
+ _chars = newBuffer;
+ _chars[0] = 0;
+ }
+ _capacity = realCapacity;
+ }
+
+ void GrowLength(int n)
+ {
+ int freeSize = _capacity - _length - 1;
+ if (n <= freeSize)
+ return;
+ int delta;
+ if (_capacity > 64)
+ delta = _capacity / 2;
+ else if (_capacity > 8)
+ delta = 16;
+ else
+ delta = 4;
+ if (freeSize + delta < n)
+ delta = n - freeSize;
+ SetCapacity(_capacity + delta);
+ }
+
+ void CorrectIndex(int &index) const
+ {
+ if (index > _length)
+ index = _length;
+ }
+
+public:
+ CStringBase(): _chars(0), _length(0), _capacity(0)
+ { SetCapacity(16 - 1); }
+ CStringBase(T c): _chars(0), _length(0), _capacity(0)
+ {
+ SetCapacity(1);
+ _chars[0] = c;
+ _chars[1] = 0;
+ _length = 1;
+ }
+ CStringBase(const T *chars): _chars(0), _length(0), _capacity(0)
+ {
+ int length = MyStringLen(chars);
+ SetCapacity(length);
+ MyStringCopy(_chars, chars); // can be optimized by memove()
+ _length = length;
+ }
+ CStringBase(const CStringBase &s): _chars(0), _length(0), _capacity(0)
+ {
+ SetCapacity(s._length);
+ MyStringCopy(_chars, s._chars);
+ _length = s._length;
+ }
+ ~CStringBase() { delete []_chars; }
+
+ operator const T*() const { return _chars;}
+
+ // The minimum size of the character buffer in characters.
+ // This value does not include space for a null terminator.
+ T* GetBuffer(int minBufLength)
+ {
+ if(minBufLength >= _capacity)
+ SetCapacity(minBufLength + 1);
+ return _chars;
+ }
+ void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); }
+ void ReleaseBuffer(int newLength)
+ {
+ /*
+ #ifndef _WIN32_WCE
+ if(newLength >= _capacity)
+ throw 282217;
+ #endif
+ */
+ _chars[newLength] = 0;
+ _length = newLength;
+ }
+
+ CStringBase& operator=(T c)
+ {
+ Empty();
+ SetCapacity(1);
+ _chars[0] = c;
+ _chars[1] = 0;
+ _length = 1;
+ return *this;
+ }
+ CStringBase& operator=(const T *chars)
+ {
+ Empty();
+ int length = MyStringLen(chars);
+ SetCapacity(length);
+ MyStringCopy(_chars, chars);
+ _length = length;
+ return *this;
+ }
+ CStringBase& operator=(const CStringBase& s)
+ {
+ if(&s == this)
+ return *this;
+ Empty();
+ SetCapacity(s._length);
+ MyStringCopy(_chars, s._chars);
+ _length = s._length;
+ return *this;
+ }
+
+ CStringBase& operator+=(T c)
+ {
+ GrowLength(1);
+ _chars[_length] = c;
+ _chars[++_length] = 0;
+ return *this;
+ }
+ CStringBase& operator+=(const T *s)
+ {
+ int len = MyStringLen(s);
+ GrowLength(len);
+ MyStringCopy(_chars + _length, s);
+ _length += len;
+ return *this;
+ }
+ CStringBase& operator+=(const CStringBase &s)
+ {
+ GrowLength(s._length);
+ MyStringCopy(_chars + _length, s._chars);
+ _length += s._length;
+ return *this;
+ }
+ void Empty()
+ {
+ _length = 0;
+ _chars[0] = 0;
+ }
+ int Length() const { return _length; }
+ bool IsEmpty() const { return (_length == 0); }
+
+ CStringBase Mid(int startIndex) const
+ { return Mid(startIndex, _length - startIndex); }
+ CStringBase Mid(int startIndex, int count ) const
+ {
+ if (startIndex + count > _length)
+ count = _length - startIndex;
+
+ if (startIndex == 0 && startIndex + count == _length)
+ return *this;
+
+ CStringBase<T> result;
+ result.SetCapacity(count);
+ // MyStringNCopy(result._chars, _chars + startIndex, count);
+ for (int i = 0; i < count; i++)
+ result._chars[i] = _chars[startIndex + i];
+ result._chars[count] = 0;
+ result._length = count;
+ return result;
+ }
+ CStringBase Left(int count) const
+ { return Mid(0, count); }
+ CStringBase Right(int count) const
+ {
+ if (count > _length)
+ count = _length;
+ return Mid(_length - count, count);
+ }
+
+ void MakeUpper()
+ { MyStringUpper(_chars); }
+ void MakeLower()
+ { MyStringLower(_chars); }
+
+ int Compare(const CStringBase& s) const
+ { return MyStringCompare(_chars, s._chars); }
+
+ int CompareNoCase(const CStringBase& s) const
+ { return MyStringCompareNoCase(_chars, s._chars); }
+ int Collate(const CStringBase& s) const
+ { return MyStringCollate(_chars, s._chars); }
+ int CollateNoCase(const CStringBase& s) const
+ { return MyStringCollateNoCase(_chars, s._chars); }
+
+ int Find(T c) const { return Find(c, 0); }
+ int Find(T c, int startIndex) const
+ {
+ T *p = _chars + startIndex;
+ while (true)
+ {
+ if (*p == c)
+ return p - _chars;
+ if (*p == 0)
+ return -1;
+ p = GetNextCharPointer(p);
+ }
+ }
+ int Find(const CStringBase &s) const { return Find(s, 0); }
+ int Find(const CStringBase &s, int startIndex) const
+ {
+ if (s.IsEmpty())
+ return startIndex;
+ for (; startIndex < _length; startIndex++)
+ {
+ int j;
+ for (j = 0; j < s._length && startIndex + j < _length; j++)
+ if (_chars[startIndex+j] != s._chars[j])
+ break;
+ if (j == s._length)
+ return startIndex;
+ }
+ return -1;
+ }
+ int ReverseFind(T c) const
+ {
+ if (_length == 0)
+ return -1;
+ T *p = _chars + _length - 1;
+ while (true)
+ {
+ if (*p == c)
+ return p - _chars;
+ if (p == _chars)
+ return -1;
+ p = GetPrevCharPointer(_chars, p);
+ }
+ }
+ int FindOneOf(const CStringBase &s) const
+ {
+ for(int i = 0; i < _length; i++)
+ if (s.Find(_chars[i]) >= 0)
+ return i;
+ return -1;
+ }
+
+ void TrimLeft(T c)
+ {
+ const T *p = _chars;
+ while (c == *p)
+ p = GetNextCharPointer(p);
+ Delete(0, p - _chars);
+ }
+ void TrimLeft()
+ {
+ CStringBase<T> charSet;
+ for(int i = 0; i < sizeof(kTrimDefaultCharSet) /
+ sizeof(kTrimDefaultCharSet[0]); i++)
+ charSet += kTrimDefaultCharSet[i];
+ TrimLeftWithCharSet(charSet);
+ }
+ void TrimRight()
+ {
+ CStringBase<T> charSet;
+ for(int i = 0; i < sizeof(kTrimDefaultCharSet) /
+ sizeof(kTrimDefaultCharSet[0]); i++)
+ charSet += kTrimDefaultCharSet[i];
+ TrimRightWithCharSet(charSet);
+ }
+ void TrimRight(T c)
+ {
+ const T *p = _chars;
+ const T *pLast = NULL;
+ while (*p != 0)
+ {
+ if (*p == c)
+ {
+ if (pLast == NULL)
+ pLast = p;
+ }
+ else
+ pLast = NULL;
+ p = GetNextCharPointer(p);
+ }
+ if(pLast != NULL)
+ {
+ int i = pLast - _chars;
+ Delete(i, _length - i);
+ }
+ }
+ void Trim()
+ {
+ TrimRight();
+ TrimLeft();
+ }
+
+ int Insert(int index, T c)
+ {
+ InsertSpace(index, 1);
+ _chars[index] = c;
+ _length++;
+ return _length;
+ }
+ int Insert(int index, const CStringBase &s)
+ {
+ CorrectIndex(index);
+ if (s.IsEmpty())
+ return _length;
+ int numInsertChars = s.Length();
+ InsertSpace(index, numInsertChars);
+ for(int i = 0; i < numInsertChars; i++)
+ _chars[index + i] = s[i];
+ _length += numInsertChars;
+ return _length;
+ }
+
+ // !!!!!!!!!!!!!!! test it if newChar = '\0'
+ int Replace(T oldChar, T newChar)
+ {
+ if (oldChar == newChar)
+ return 0;
+ int number = 0;
+ int pos = 0;
+ while (pos < Length())
+ {
+ pos = Find(oldChar, pos);
+ if (pos < 0)
+ break;
+ _chars[pos] = newChar;
+ pos++;
+ number++;
+ }
+ return number;
+ }
+ int Replace(const CStringBase &oldString, const CStringBase &newString)
+ {
+ if (oldString.IsEmpty())
+ return 0;
+ if (oldString == newString)
+ return 0;
+ int oldStringLength = oldString.Length();
+ int newStringLength = newString.Length();
+ int number = 0;
+ int pos = 0;
+ while (pos < _length)
+ {
+ pos = Find(oldString, pos);
+ if (pos < 0)
+ break;
+ Delete(pos, oldStringLength);
+ Insert(pos, newString);
+ pos += newStringLength;
+ number++;
+ }
+ return number;
+ }
+ int Delete(int index, int count = 1 )
+ {
+ if (index + count > _length)
+ count = _length - index;
+ if (count > 0)
+ {
+ MoveItems(index, index + count);
+ _length -= count;
+ }
+ return _length;
+ }
+};
+
+template <class T>
+CStringBase<T> operator+(const CStringBase<T>& s1, const CStringBase<T>& s2)
+{
+ CStringBase<T> result(s1);
+ result += s2;
+ return result;
+}
+
+template <class T>
+CStringBase<T> operator+(const CStringBase<T>& s, T c)
+{
+ CStringBase<T> result(s);
+ result += c;
+ return result;
+}
+
+template <class T>
+CStringBase<T> operator+(T c, const CStringBase<T>& s)
+{
+ CStringBase<T> result(c);
+ result += s;
+ return result;
+}
+
+template <class T>
+CStringBase<T> operator+(const CStringBase<T>& s, const T * chars)
+{
+ CStringBase<T> result(s);
+ result += chars;
+ return result;
+}
+
+template <class T>
+CStringBase<T> operator+(const T * chars, const CStringBase<T>& s)
+{
+ CStringBase<T> result(chars);
+ result += s;
+ return result;
+}
+
+template <class T>
+bool operator==(const CStringBase<T>& s1, const CStringBase<T>& s2)
+ { return (s1.Compare(s2) == 0); }
+
+template <class T>
+bool operator<(const CStringBase<T>& s1, const CStringBase<T>& s2)
+ { return (s1.Compare(s2) < 0); }
+
+template <class T>
+bool operator==(const T *s1, const CStringBase<T>& s2)
+ { return (s2.Compare(s1) == 0); }
+
+template <class T>
+bool operator==(const CStringBase<T>& s1, const T *s2)
+ { return (s1.Compare(s2) == 0); }
+
+template <class T>
+bool operator!=(const CStringBase<T>& s1, const CStringBase<T>& s2)
+ { return (s1.Compare(s2) != 0); }
+
+template <class T>
+bool operator!=(const T *s1, const CStringBase<T>& s2)
+ { return (s2.Compare(s1) != 0); }
+
+template <class T>
+bool operator!=(const CStringBase<T>& s1, const T *s2)
+ { return (s1.Compare(s2) != 0); }
+
+typedef CStringBase<char> AString;
+typedef CStringBase<wchar_t> UString;
+
+typedef CObjectVector<AString> AStringVector;
+typedef CObjectVector<UString> UStringVector;
+
+#ifdef _UNICODE
+ typedef UString CSysString;
+#else
+ typedef AString CSysString;
+#endif
+
+typedef CObjectVector<CSysString> CSysStringVector;
+
+#endif
diff --git a/Common/StringConvert.cpp b/Common/StringConvert.cpp
new file mode 100755
index 00000000..961c8454
--- /dev/null
+++ b/Common/StringConvert.cpp
@@ -0,0 +1,71 @@
+// Common/StringConvert.cpp
+
+#include "StdAfx.h"
+
+#include "StringConvert.h"
+
+#ifdef WIN32
+UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
+{
+ UString resultString;
+ if(!srcString.IsEmpty())
+ {
+ int numChars = MultiByteToWideChar(codePage, 0, srcString,
+ srcString.Length(), resultString.GetBuffer(srcString.Length()),
+ srcString.Length() + 1);
+ #ifndef _WIN32_WCE
+ if(numChars == 0)
+ throw 282228;
+ #endif
+ resultString.ReleaseBuffer(numChars);
+ }
+ return resultString;
+}
+
+AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage)
+{
+ AString resultString;
+ if(!srcString.IsEmpty())
+ {
+ int numRequiredBytes = srcString.Length() * 2;
+ int numChars = WideCharToMultiByte(codePage, 0, srcString,
+ srcString.Length(), resultString.GetBuffer(numRequiredBytes),
+ numRequiredBytes + 1, NULL, NULL);
+ #ifndef _WIN32_WCE
+ if(numChars == 0)
+ throw 282229;
+ #endif
+ resultString.ReleaseBuffer(numChars);
+ }
+ return resultString;
+}
+
+#ifndef _WIN32_WCE
+AString SystemStringToOemString(const CSysString &srcString)
+{
+ AString result;
+ CharToOem(srcString, result.GetBuffer(srcString.Length() * 2));
+ result.ReleaseBuffer();
+ return result;
+}
+#endif
+
+#else
+
+UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
+{
+ UString resultString;
+ for (int i = 0; i < srcString.Length(); i++)
+ resultString += wchar_t(srcString[i]);
+ return resultString;
+}
+
+AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage)
+{
+ AString resultString;
+ for (int i = 0; i < srcString.Length(); i++)
+ resultString += char(srcString[i]);
+ return resultString;
+}
+
+#endif \ No newline at end of file
diff --git a/Common/StringConvert.h b/Common/StringConvert.h
new file mode 100755
index 00000000..982fb897
--- /dev/null
+++ b/Common/StringConvert.h
@@ -0,0 +1,72 @@
+// Common/StringConvert.h
+
+#pragma once
+
+#ifndef __COMMON_STRINGCONVERT_H
+#define __COMMON_STRINGCONVERT_H
+
+#include "String.h"
+#include "Types.h"
+
+UString MultiByteToUnicodeString(const AString &srcString, UINT codePage = CP_ACP);
+AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage = CP_ACP);
+
+inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString)
+ { return unicodeString; }
+inline const UString& GetUnicodeString(const UString &unicodeString)
+ { return unicodeString; }
+inline UString GetUnicodeString(const AString &ansiString)
+ { return MultiByteToUnicodeString(ansiString); }
+inline UString GetUnicodeString(const AString &multiByteString, UINT codePage)
+ { return MultiByteToUnicodeString(multiByteString, codePage); }
+inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString, UINT codePage)
+ { return unicodeString; }
+inline const UString& GetUnicodeString(const UString &unicodeString, UINT codePage)
+ { return unicodeString; }
+
+inline const char* GetAnsiString(const char* ansiString)
+ { return ansiString; }
+inline const AString& GetAnsiString(const AString &ansiString)
+ { return ansiString; }
+inline AString GetAnsiString(const UString &unicodeString)
+ { return UnicodeStringToMultiByte(unicodeString); }
+
+inline const char* GetOemString(const char* oemString)
+ { return oemString; }
+inline const AString& GetOemString(const AString &oemString)
+ { return oemString; }
+inline AString GetOemString(const UString &unicodeString)
+ { return UnicodeStringToMultiByte(unicodeString, CP_OEMCP); }
+
+
+#ifdef _UNICODE
+ inline const wchar_t* GetSystemString(const wchar_t* unicodeString)
+ { return unicodeString;}
+ inline const UString& GetSystemString(const UString &unicodeString)
+ { return unicodeString;}
+ inline const wchar_t* GetSystemString(const wchar_t* unicodeString, UINT codePage)
+ { return unicodeString;}
+ inline const UString& GetSystemString(const UString &unicodeString, UINT codePage)
+ { return unicodeString;}
+ inline UString GetSystemString(const AString &multiByteString, UINT codePage)
+ { return MultiByteToUnicodeString(multiByteString, codePage);}
+ inline UString GetSystemString(const AString &multiByteString)
+ { return MultiByteToUnicodeString(multiByteString);}
+#else
+ inline const char* GetSystemString(const char *ansiString)
+ { return ansiString; }
+ inline const AString& GetSystemString(const AString &multiByteString, UINT codePage)
+ { return multiByteString; }
+ inline const char * GetSystemString(const char *multiByteString, UINT codePage)
+ { return multiByteString; }
+ inline AString GetSystemString(const UString &unicodeString)
+ { return UnicodeStringToMultiByte(unicodeString); }
+ inline AString GetSystemString(const UString &unicodeString, UINT codePage)
+ { return UnicodeStringToMultiByte(unicodeString, codePage); }
+#endif
+
+#ifndef _WIN32_WCE
+AString SystemStringToOemString(const CSysString &srcString);
+#endif
+
+#endif
diff --git a/Common/StringToInt.cpp b/Common/StringToInt.cpp
new file mode 100755
index 00000000..a592b062
--- /dev/null
+++ b/Common/StringToInt.cpp
@@ -0,0 +1,50 @@
+// Common/StringToInt.cpp
+
+#include "StdAfx.h"
+
+#include "StringToInt.h"
+
+UINT64 ConvertStringToUINT64(const char *s, const char **end)
+{
+ UINT64 result = 0;
+ while(true)
+ {
+ char c = *s;
+ if (c < '0' || c > '9')
+ {
+ if (end != NULL)
+ *end = s;
+ return result;
+ }
+ result *= 10;
+ result += (c - '0');
+ s++;
+ }
+}
+
+UINT64 ConvertStringToUINT64(const wchar_t *s, const wchar_t **end)
+{
+ UINT64 result = 0;
+ while(true)
+ {
+ wchar_t c = *s;
+ if (c < '0' || c > '9')
+ {
+ if (end != NULL)
+ *end = s;
+ return result;
+ }
+ result *= 10;
+ result += (c - '0');
+ s++;
+ }
+}
+
+
+INT64 ConvertStringToINT64(const char *s, const char **end)
+{
+ INT64 result = 0;
+ if (*s == '-')
+ return -(INT64)ConvertStringToUINT64(s + 1, end);
+ return ConvertStringToUINT64(s, end);
+}
diff --git a/Common/StringToInt.h b/Common/StringToInt.h
new file mode 100755
index 00000000..3c7961de
--- /dev/null
+++ b/Common/StringToInt.h
@@ -0,0 +1,15 @@
+// Common/StringToInt.h
+
+#pragma once
+
+#ifndef __COMMON_STRINGTOINT_H
+#define __COMMON_STRINGTOINT_H
+
+UINT64 ConvertStringToUINT64(const char *s, const char **end);
+UINT64 ConvertStringToUINT64(const wchar_t *s, const wchar_t **end);
+
+INT64 ConvertStringToINT64(const char *s, const char **end);
+
+#endif
+
+
diff --git a/Common/TextConfig.cpp b/Common/TextConfig.cpp
new file mode 100755
index 00000000..8e3a8c49
--- /dev/null
+++ b/Common/TextConfig.cpp
@@ -0,0 +1,137 @@
+// Common/TextConfig.cpp
+
+#include "StdAfx.h"
+
+#include "Common/TextConfig.h"
+
+#include "Defs.h"
+#include "Common/UTFConvert.h"
+
+static bool IsDelimitChar(char c)
+{
+ return (c == ' ' || c == 0x0A || c == 0x0D ||
+ c == '\0' || c == '\t');
+}
+
+static AString GetIDString(const char *string, int &finishPos)
+{
+ AString result;
+ for (finishPos = 0; true; finishPos++)
+ {
+ char c = string[finishPos];
+ if (IsDelimitChar(c) || c == '=')
+ return result;
+ result += c;
+ }
+}
+
+static bool WaitNextLine(const AString &string, int &pos)
+{
+ for (;pos < string.Length(); pos++)
+ if (string[pos] == 0x0A)
+ return true;
+ return false;
+}
+
+static bool SkipSpaces(const AString &string, int &pos)
+{
+ for (;pos < string.Length(); pos++)
+ {
+ char c = string[pos];
+ if (!IsDelimitChar(c))
+ {
+ if (c != ';')
+ return true;
+ if (!WaitNextLine(string, pos))
+ return false;
+ }
+ }
+ return false;
+}
+
+bool GetTextConfig(const AString &string, CObjectVector<CTextConfigPair> &pairs)
+{
+ pairs.Clear();
+ int pos = 0;
+
+ /////////////////////
+ // read strings
+
+ while (true)
+ {
+ if (!SkipSpaces(string, pos))
+ break;
+ CTextConfigPair pair;
+ int finishPos;
+ AString temp = GetIDString(((const char *)string) + pos, finishPos);
+ if (!ConvertUTF8ToUnicode(temp, pair.ID))
+ return false;
+ if (finishPos == 0)
+ return false;
+ pos += finishPos;
+ if (!SkipSpaces(string, pos))
+ return false;
+ if (string[pos] != '=')
+ return false;
+ pos++;
+ if (!SkipSpaces(string, pos))
+ return false;
+ if (string[pos] != '\"')
+ return false;
+ pos++;
+ AString message;
+ while(true)
+ {
+ if (pos >= string.Length())
+ return false;
+ char c = string[pos++];
+ if (c == '\"')
+ break;
+ if (c == '\\')
+ {
+ char c = string[pos++];
+ switch(c)
+ {
+ case 'n':
+ message += '\n';
+ break;
+ case 't':
+ message += '\t';
+ break;
+ case '\\':
+ message += '\\';
+ break;
+ case '\"':
+ message += '\"';
+ break;
+ default:
+ message += '\\';
+ message += c;
+ break;
+ }
+ }
+ else
+ message += c;
+ }
+ if (!ConvertUTF8ToUnicode(message, pair.String))
+ return false;
+ pairs.Add(pair);
+ }
+ return true;
+}
+
+int FindItem(const CObjectVector<CTextConfigPair> &pairs, const UString &id)
+{
+ for (int i = 0; i < pairs.Size(); i++)
+ if (pairs[i].ID.Compare(id) == 0)
+ return i;
+ return -1;
+}
+
+UString GetTextConfigValue(const CObjectVector<CTextConfigPair> &pairs, const UString &id)
+{
+ int index = FindItem(pairs, id);
+ if (index < 0)
+ return UString();
+ return pairs[index].String;
+}
diff --git a/Common/TextConfig.h b/Common/TextConfig.h
new file mode 100755
index 00000000..62cf98e9
--- /dev/null
+++ b/Common/TextConfig.h
@@ -0,0 +1,24 @@
+// Common/TextConfig.h
+
+#pragma once
+
+#ifndef __COMMON_TEXTCONFIG_H
+#define __COMMON_TEXTCONFIG_H
+
+#include "Common/Vector.h"
+#include "Common/String.h"
+
+struct CTextConfigPair
+{
+ UString ID;
+ UString String;
+};
+
+bool GetTextConfig(const AString &text, CObjectVector<CTextConfigPair> &pairs);
+
+int FindTextConfigItem(const CObjectVector<CTextConfigPair> &pairs, const UString &id);
+UString GetTextConfigValue(const CObjectVector<CTextConfigPair> &pairs, const UString &id);
+
+#endif
+
+
diff --git a/Common/Types.h b/Common/Types.h
new file mode 100755
index 00000000..02853e0d
--- /dev/null
+++ b/Common/Types.h
@@ -0,0 +1,19 @@
+// Common/Types.h
+
+// #pragma once
+
+#ifndef __COMMON_TYPES_H
+#define __COMMON_TYPES_H
+
+#include <basetsd.h>
+
+typedef unsigned char UINT8;
+typedef unsigned short UINT16;
+typedef short INT16;
+#ifndef _WINDOWS_
+ // typedef unsigned long UINT32;
+ typedef UINT8 BYTE;
+#endif
+
+#endif
+
diff --git a/Common/UTFConvert.cpp b/Common/UTFConvert.cpp
new file mode 100755
index 00000000..22404466
--- /dev/null
+++ b/Common/UTFConvert.cpp
@@ -0,0 +1,70 @@
+// UTFConvert.cpp
+
+#include "StdAfx.h"
+
+#include "UTFConvert.h"
+#include "Types.h"
+
+bool ConvertUTF8ToUnicode(const AString &utfString, UString &resultString)
+{
+ resultString.Empty();
+ for(int i = 0; i < utfString.Length(); i++)
+ {
+ BYTE c = utfString[i];
+ if (c < 0x80)
+ {
+ resultString += c;
+ continue;
+ }
+ if(c < 0xC0 || c >= 0xF0)
+ return false;
+ i++;
+ if (i >= utfString.Length())
+ return false;
+ BYTE c2 = utfString[i];
+ if (c2 < 0x80)
+ return false;
+ c2 -= 0x80;
+ if (c2 >= 0x40)
+ return false;
+ if (c < 0xE0)
+ {
+ resultString += wchar_t( ((wchar_t(c - 0xC0)) << 6) + c2);
+ continue;
+ }
+ i++;
+ if (i >= utfString.Length())
+ return false;
+ BYTE c3 = utfString[i];
+ c3 -= 0x80;
+ if (c3 >= 0x40)
+ return false;
+ resultString += wchar_t(((wchar_t(c - 0xE0)) << 12) +
+ ((wchar_t(c2)) << 6) + c3);
+ }
+ return true;
+}
+
+void ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString)
+{
+ resultString.Empty();
+ for(int i = 0; i < unicodeString.Length(); i++)
+ {
+ wchar_t c = unicodeString[i];
+ if (c < 0x80)
+ {
+ resultString += char(c);
+ continue;
+ }
+ if (c < 0x07FF)
+ {
+ resultString += char(0xC0 + (c >> 6));
+ resultString += char(0x80 + (c & 0x003F));
+ continue;
+ }
+ resultString += char(0xE0 + (c >> 12));
+ resultString += char(0x80 + ((c >> 6) & 0x003F));
+ resultString += char(0x80 + (c & 0x003F));
+ }
+}
+
diff --git a/Common/UTFConvert.h b/Common/UTFConvert.h
new file mode 100755
index 00000000..0e558c88
--- /dev/null
+++ b/Common/UTFConvert.h
@@ -0,0 +1,13 @@
+// Common/UTFConvert.h
+
+#pragma once
+
+#ifndef __COMMON_UTFCONVERT_H
+#define __COMMON_UTFCONVERT_H
+
+#include "Common/String.h"
+
+bool ConvertUTF8ToUnicode(const AString &utfString, UString &resultString);
+void ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString);
+
+#endif
diff --git a/Common/Vector.cpp b/Common/Vector.cpp
new file mode 100755
index 00000000..c8b1c1e9
--- /dev/null
+++ b/Common/Vector.cpp
@@ -0,0 +1,72 @@
+// Common/Vector.cpp
+
+#include "StdAfx.h"
+
+#include "Vector.h"
+
+CBaseRecordVector::~CBaseRecordVector()
+ { delete []((unsigned char *)_items); }
+void CBaseRecordVector::Clear()
+ { DeleteFrom(0); }
+void CBaseRecordVector::DeleteBack()
+ { Delete(_size - 1); }
+void CBaseRecordVector::DeleteFrom(int index)
+ { Delete(index, _size - index); }
+
+void CBaseRecordVector::ReserveOnePosition()
+{
+ if(_size != _capacity)
+ return;
+ int delta;
+ if (_capacity > 64)
+ delta = _capacity / 2;
+ else if (_capacity > 8)
+ delta = 8;
+ else
+ delta = 4;
+ Reserve(_capacity + delta);
+}
+
+void CBaseRecordVector::Reserve(int newCapacity)
+{
+ if(newCapacity <= _capacity)
+ return;
+ /*
+ #ifndef _DEBUG
+ static const unsigned int kMaxVectorSize = 0xF0000000;
+ if(newCapacity < _size ||
+ ((unsigned int )newCapacity * (unsigned int )_itemSize) > kMaxVectorSize)
+ throw 1052354;
+ #endif
+ */
+ unsigned char *p = new unsigned char[newCapacity * _itemSize];
+ int numRecordsToMove = _capacity;
+ memmove(p, _items, _itemSize * numRecordsToMove);
+ delete []_items;
+ _items = p;
+ _capacity = newCapacity;
+}
+
+void CBaseRecordVector::MoveItems(int destIndex, int srcIndex)
+{
+ memmove(((unsigned char *)_items) + destIndex * _itemSize,
+ ((unsigned char *)_items) + srcIndex * _itemSize,
+ _itemSize * (_size - srcIndex));
+}
+
+void CBaseRecordVector::InsertOneItem(int index)
+{
+ ReserveOnePosition();
+ MoveItems(index + 1, index);
+ _size++;
+}
+
+void CBaseRecordVector::Delete(int index, int num)
+{
+ TestIndexAndCorrectNum(index, num);
+ if (num > 0)
+ {
+ MoveItems(index, index + num);
+ _size -= num;
+ }
+}
diff --git a/Common/Vector.h b/Common/Vector.h
new file mode 100755
index 00000000..051d4e46
--- /dev/null
+++ b/Common/Vector.h
@@ -0,0 +1,177 @@
+// Common/Vector.h
+
+#pragma once
+
+#ifndef __COMMON_VECTOR_H
+#define __COMMON_VECTOR_H
+
+#include "Defs.h"
+
+class CBaseRecordVector
+{
+ void MoveItems(int destIndex, int srcIndex);
+protected:
+ int _capacity;
+ int _size;
+ void *_items;
+ size_t _itemSize;
+
+ void ReserveOnePosition();
+ void InsertOneItem(int index);
+ void TestIndexAndCorrectNum(int index, int &num) const
+ { if (index + num > _size) num = _size - index; }
+public:
+ CBaseRecordVector(size_t itemSize):
+ _size(0), _capacity(0), _items(0), _itemSize(itemSize) {}
+ virtual ~CBaseRecordVector();
+ int Size() const { return _size; }
+ bool IsEmpty() const { return (_size == 0); }
+ void Reserve(int newCapacity);
+ virtual void Delete(int index, int num = 1);
+ void Clear();
+ void DeleteFrom(int index);
+ void DeleteBack();
+};
+
+template <class T>
+class CRecordVector: public CBaseRecordVector
+{
+public:
+ CRecordVector():CBaseRecordVector(sizeof(T)){};
+ CRecordVector(const CRecordVector &v):
+ CBaseRecordVector(sizeof(T)) { *this = v;}
+ CRecordVector& operator=(const CRecordVector &v)
+ {
+ Clear();
+ return (*this += v);
+ }
+ CRecordVector& operator+=(const CRecordVector &v)
+ {
+ int size = v.Size();
+ Reserve(Size() + size);
+ for(int i = 0; i < size; i++)
+ Add(v[i]);
+ return *this;
+ }
+ int Add(T item)
+ {
+ ReserveOnePosition();
+ ((T *)_items)[_size] = item;
+ return _size++;
+ }
+ void Insert(int index, T item)
+ {
+ InsertOneItem(index);
+ ((T *)_items)[index] = item;
+ }
+ // T* GetPointer() const { return (T*)_items; }
+ // operator const T *() const { return _items; };
+ const T& operator[](int index) const { return ((T *)_items)[index]; }
+ T& operator[](int index) { return ((T *)_items)[index]; }
+ const T& Front() const { return operator[](0); }
+ T& Front() { return operator[](0); }
+ const T& Back() const { return operator[](_size - 1); }
+ T& Back() { return operator[](_size - 1); }
+ static int __cdecl CompareRecordItems(const void *a1, const void *a2)
+ { return MyCompare(*((const T *)a1), *((const T *)a2)); }
+ void Sort()
+ { qsort(&Front(), Size(), _itemSize, CompareRecordItems); }
+};
+
+typedef CRecordVector<int> CIntVector;
+typedef CRecordVector<unsigned int> CUIntVector;
+typedef CRecordVector<bool> CBoolVector;
+typedef CRecordVector<unsigned char> CByteVector;
+typedef CRecordVector<void *> CPointerVector;
+
+template <class T>
+class CObjectVector: public CPointerVector
+{
+public:
+ CObjectVector(){};
+ ~CObjectVector() { Clear(); }
+ CObjectVector(const CObjectVector &objectVector)
+ { *this = objectVector; }
+ CObjectVector& operator=(const CObjectVector &objectVector)
+ {
+ Clear();
+ return (*this += objectVector);
+ }
+ CObjectVector& operator+=(const CObjectVector &objectVector)
+ {
+ int size = objectVector.Size();
+ Reserve(Size() + size);
+ for(int i = 0; i < size; i++)
+ Add(objectVector[i]);
+ return *this;
+ }
+ const T& operator[](int index) const { return *((T *)CPointerVector::operator[](index)); }
+ T& operator[](int index) { return *((T *)CPointerVector::operator[](index)); }
+ T& Front() { return operator[](0); }
+ const T& Front() const { return operator[](0); }
+ T& Back() { return operator[](_size - 1); }
+ const T& Back() const { return operator[](_size - 1); }
+ int Add(const T& item)
+ { return CPointerVector::Add(new T(item)); }
+ void Insert(int index, const T& item)
+ { CPointerVector::Insert(index, new T(item)); }
+ virtual void Delete(int index, int num = 1)
+ {
+ TestIndexAndCorrectNum(index, num);
+ for(int i = 0; i < num; i++)
+ delete (T *)(((void **)_items)[index + i]);
+ CPointerVector::Delete(index, num);
+ }
+ int Find(const T& item) const
+ {
+ for(int i = 0; i < Size(); i++)
+ if (item == (*this)[mid])
+ return i;
+ return -1;
+ }
+ int FindInSorted(const T& item) const
+ {
+ int left = 0, right = Size();
+ while (left != right)
+ {
+ int mid = (left + right) / 2;
+ const T& midValue = (*this)[mid];
+ if (item == midValue)
+ return mid;
+ if (item < midValue)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ return -1;
+ }
+ int AddToSorted(const T& item)
+ {
+ int left = 0, right = Size();
+ while (left != right)
+ {
+ int mid = (left + right) / 2;
+ const T& midValue = (*this)[mid];
+ if (item == midValue)
+ {
+ right = mid + 1;
+ break;
+ }
+ if (item < midValue)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ Insert(right, item);
+ return right;
+ }
+ static int __cdecl CompareObjectItems(const void *a1, const void *a2)
+ { return MyCompare(*(*((const T **)a1)), *(*((const T **)a2))); }
+ void Sort()
+ {
+ CPointerVector &pointerVector = *this;
+ qsort(&pointerVector[0], Size(), sizeof(void *), CompareObjectItems);
+ }
+};
+
+#endif
diff --git a/Common/Wildcard.cpp b/Common/Wildcard.cpp
new file mode 100755
index 00000000..78385db2
--- /dev/null
+++ b/Common/Wildcard.cpp
@@ -0,0 +1,351 @@
+// Common/Wildcard.cpp
+
+#include "StdAfx.h"
+
+#include "WildCard.h"
+
+static const wchar_t kPeriodChar = L'.';
+static const wchar_t kAnyCharsChar = L'*';
+static const wchar_t kAnyCharChar = L'?';
+
+static const wchar_t kDirDelimiter1 = L'\\';
+static const wchar_t kDirDelimiter2 = L'/';
+
+static const wchar_t kDiskNameDelimiterChar = ':';
+
+static const UString kRootDirName = L"";
+
+static const wchar_t kSpaceChar = L' ';
+
+static const UString kWildCardCharSet = L"?*";
+
+static const UString kIllegalWildCardFileNameChars=
+ L"\x1\x2\x3\x4\x5\x6\x7\x8\x9\xA\xB\xC\xD\xE\xF"
+ L"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
+ L"\"/:<>\\|";
+
+static const UString kIllegalFileNameChars = kIllegalWildCardFileNameChars +
+ kWildCardCharSet;
+
+static inline bool IsCharDirLimiter(wchar_t c)
+{
+ return (c == kDirDelimiter1 || c == kDirDelimiter2);
+}
+
+// -----------------------------------------
+// this function tests is name matches mask
+// ? - any wchar_t or empty
+// * - any characters or empty
+
+static bool EnhancedMaskTest(const UString &mask, int maskPos,
+ const UString &name, int namePos)
+{
+ int maskLen = mask.Length() - maskPos;
+ int nameLen = name.Length() - namePos;
+ if (maskLen == 0)
+ if (nameLen == 0)
+ return true;
+ else
+ return false;
+ wchar_t maskChar = mask[maskPos];
+ if(maskChar == kAnyCharChar)
+ {
+ if (EnhancedMaskTest(mask, maskPos + 1, name, namePos))
+ return true;
+ if (nameLen == 0)
+ return false;
+ return EnhancedMaskTest(mask, maskPos + 1, name, namePos + 1);
+ }
+ else if(maskChar == kAnyCharsChar)
+ {
+ if (EnhancedMaskTest(mask, maskPos + 1, name, namePos))
+ return true;
+ if (nameLen == 0)
+ return false;
+ return EnhancedMaskTest(mask, maskPos, name, namePos + 1);
+ }
+ else
+ {
+ wchar_t c = name[namePos];
+ if (maskChar != c)
+ if (MyCharUpper(maskChar) != MyCharUpper(c))
+ return false;
+ return EnhancedMaskTest(mask, maskPos + 1, name, namePos + 1);
+ }
+}
+
+// --------------------------------------------------
+// Splits path to strings
+
+void SplitPathToParts(const UString &path, UStringVector &pathParts)
+{
+ pathParts.Clear();
+ UString name;
+ int len = path.Length();
+ if (len == 0)
+ return;
+ for (int i = 0; i < len; i++)
+ {
+ wchar_t c = path[i];
+ if (IsCharDirLimiter(c))
+ {
+ pathParts.Add(name);
+ name.Empty();
+ }
+ else
+ name += c;
+ }
+ pathParts.Add(name);
+}
+
+/*
+void SplitPathToParts(const AString &path, AStringVector &pathParts)
+{
+ pathParts.Clear();
+ AString name;
+ int len = path.Length();
+ if (len == 0)
+ return;
+ for (int i = 0; i < len; i++)
+ {
+ wchar_t c = path[i];
+ if (IsCharDirLimiter(c))
+ {
+ pathParts.Add(name);
+ name.Empty();
+ }
+ else
+ name += path[i];
+ }
+ pathParts.Add(name);
+}
+*/
+
+// --------------------------------------------------
+// ExtractFileNameFromPath
+
+UString ExtractFileNameFromPath(const UString &pathName)
+{
+ UString result;
+ int len = pathName.Length();
+ for(int i = len - 1; i >= 0; i--)
+ if(IsCharDirLimiter(pathName[i]))
+ return pathName.Mid(i + 1);
+ return pathName;
+}
+
+bool CompareWildCardWithName(const UString &mask, const UString &name)
+{
+ return EnhancedMaskTest(mask, 0, name, 0);
+}
+
+bool DoesNameContainWildCard(const UString &pathName)
+{
+ return (pathName.FindOneOf(kWildCardCharSet) >= 0);
+}
+
+
+// ----------------------------------------------------------'
+// NWildcard
+
+namespace NWildcard {
+
+static inline int BoolToIndex(bool value)
+{
+ return value ? 1: 0;
+}
+
+const UStringVector& CCensorNode::GetNamesVector(bool allowed, bool recursed, bool wildCard) const
+{
+ return _names[BoolToIndex(allowed)][BoolToIndex(recursed)][BoolToIndex(wildCard)];
+}
+
+void CCensorNode::AddItem(const UString &name, bool allowed, bool recursed, bool wildCard)
+{
+ _names[BoolToIndex(allowed)][BoolToIndex(recursed)][BoolToIndex(wildCard)].Add(name);
+}
+
+CCensorNode *CCensorNode::FindSubNode(const UString &name)
+{
+ for (int i = 0; i < SubNodes.Size(); i++)
+ if (name.CollateNoCase(SubNodes[i].Name) == 0)
+ return &SubNodes[i];
+ return NULL;
+}
+
+CCensorNode *CCensorNode::AddSubNode(const UString &name)
+{
+ CCensorNode *subNode = FindSubNode(name);
+ if (subNode != NULL)
+ return subNode;
+ SubNodes.Add(CCensorNode(this, name));
+ return &SubNodes.Back();
+}
+
+int FindString(const UStringVector &strings, const UString &string)
+{
+ for (int i = 0; i < strings.Size(); i++)
+ if (string.CollateNoCase(strings[i]) == 0)
+ return i;
+ return -1;
+}
+
+int FindInWildcardVector(const UStringVector &strings, const UString &string)
+{
+ for (int i = 0; i < strings.Size(); i++)
+ if (CompareWildCardWithName(strings[i], string))
+ return i;
+ return -1;
+}
+
+bool CCensorNode::CheckName(const UString &name, bool allowed, bool recursed) const
+{
+ if (FindString(_names[BoolToIndex(allowed)][BoolToIndex(recursed)][0], name) >= 0)
+ return true;
+ if (FindInWildcardVector(_names[BoolToIndex(allowed)][BoolToIndex(recursed)][1], name) >= 0)
+ return true;
+ return false;
+}
+
+bool CCensorNode::CheckNameRecursive(const UString &name, bool allowed) const
+{
+ const CCensorNode *curItem = this;
+ while (curItem != NULL)
+ {
+ if (curItem->CheckName(name, allowed, true))
+ return true;
+ curItem = curItem->_parent;
+ }
+ return false;
+}
+
+bool CCensorNode::CheckNameRecursive(const UString &name) const
+{
+ if (!CheckNameRecursive(name, true))
+ return false;
+ return !CheckNameRecursive(name, false);
+}
+
+bool CCensorNode::CheckNameFull(const UString &name, bool allowed) const
+{
+ if (CheckName(name, allowed, false))
+ return true;
+ return CheckNameRecursive(name, allowed);
+}
+
+bool CCensorNode::CheckNameFull(const UString &name) const
+{
+ if (!CheckNameFull(name, true))
+ return false;
+ return !CheckNameFull(name, false);
+}
+
+////////////////////////////////////
+// CCensor
+
+void CCensor::AddItem(const UString &path, bool allowed, bool recursed, bool wildCard)
+{
+ UStringVector pathParts;
+ SplitPathToParts(path, pathParts);
+ int numParts = pathParts.Size();
+ if (numParts == 0)
+ throw "Empty path";
+ CCensorNode *curItem = &_head;
+ int i;
+ for(i = 0; i < numParts - 1; i++)
+ curItem = curItem->AddSubNode(pathParts[i]);
+ curItem->AddItem(pathParts[i], allowed, recursed, wildCard);
+}
+
+
+bool CCensor::CheckName(const UString &path) const
+{
+ UStringVector pathParts;
+ SplitPathToParts(path, pathParts);
+ int numParts = pathParts.Size();
+ if (numParts == 0)
+ throw "Empty path";
+ const CCensorNode *curItem = &_head;
+ const UString &name = pathParts[numParts - 1];
+ for(int i = 0; i < numParts - 1; i++)
+ {
+ const CCensorNode *nextItem = ((CCensorNode *)curItem)->FindSubNode(pathParts[i]);
+ if (nextItem == NULL)
+ return curItem->CheckNameRecursive(name);
+ curItem = nextItem;
+ }
+ return curItem->CheckNameFull(name);
+}
+
+}
+
+////////////////////////////////////
+// Filename and WildCard function
+
+static bool TestStringLengthAndBounds(const UString &string)
+{
+ if (string.Length() <= 0)
+ return false;
+ return (string.ReverseFind(kSpaceChar) != string.Length() - 1);
+}
+bool IsFileNameLegal(const UString &name)
+{
+ if (!TestStringLengthAndBounds(name))
+ return false;
+ return (name.FindOneOf(kIllegalFileNameChars) < 0);
+}
+
+bool IsWildCardFileNameLegal(const UString &name)
+{
+ if (!TestStringLengthAndBounds(name))
+ return false;
+ return (name.FindOneOf(kIllegalWildCardFileNameChars) < 0);
+}
+
+bool IsFilePathLegal(const UString &path)
+{
+ UStringVector pathParts;
+ SplitPathToParts(path, pathParts);
+ int count = pathParts.Size();
+ if (count == 0)
+ return false;
+ for(int i = 0; i < count; i++)
+ if (!IsFileNameLegal(pathParts[i]))
+ return false;
+ return true;
+}
+
+bool IsWildCardFilePathLegal(const UString &path)
+{
+ UStringVector pathParts;
+ SplitPathToParts(path, pathParts);
+ int count = pathParts.Size();
+ if (count == 0)
+ return false;
+ for(int i = 0; i < count - 1; i++)
+ if (!IsFileNameLegal(pathParts[i]))
+ return false;
+ return IsWildCardFileNameLegal(pathParts[count - 1]);
+}
+
+static bool IsCharAPrefixDelimiter(wchar_t c)
+{
+ return (IsCharDirLimiter(c) || c == kDiskNameDelimiterChar);
+}
+
+bool AreTheFileNamesDirDelimiterEqual(const UString &name1, const UString &name2)
+{
+ if(name1.Length() != name2.Length())
+ return false;
+ for(int i = 0; i < name1.Length(); i++)
+ {
+ wchar_t char1 = name1[i], char2 = name2[i];
+ if (char1 == char2)
+ continue;
+ if (IsCharDirLimiter(char1) && IsCharDirLimiter(char2))
+ continue;
+ return false;
+ }
+ return true;
+}
+
diff --git a/Common/Wildcard.h b/Common/Wildcard.h
new file mode 100755
index 00000000..8bed3ead
--- /dev/null
+++ b/Common/Wildcard.h
@@ -0,0 +1,60 @@
+// Common/Wildcard.h
+
+#pragma once
+
+#ifndef __COMMON_WILDCARD_H
+#define __COMMON_WILDCARD_H
+
+#include "Common/String.h"
+
+void SplitPathToParts(const UString &path, UStringVector &aPathParts);
+// void SplitPathToParts(const AString &path, AStringVector &aPathParts);
+UString ExtractFileNameFromPath(const UString &pathName);
+bool DoesNameContainWildCard(const UString &pathName);
+bool CompareWildCardWithName(const UString &mask, const UString &name);
+
+namespace NWildcard {
+
+class CCensorNode
+{
+ CCensorNode *_parent;
+ UStringVector _names[2][2][2];
+ bool CheckNameRecursive(const UString &name, bool allowed) const;
+ bool CheckNameFull(const UString &name, bool allowed) const;
+public:
+ UString Name;
+ CObjectVector<CCensorNode> SubNodes;
+ CCensorNode(CCensorNode *parent, const UString &name):
+ _parent(parent), Name(name) {};
+ CCensorNode *FindSubNode(const UString &name);
+ CCensorNode *AddSubNode(const UString &name);
+ void AddItem(const UString &name, bool allowed, bool recursed, bool wildCard);
+ bool CheckName(const UString &name, bool allowed, bool recursed) const;
+ bool CheckNameRecursive(const UString &name) const;
+ bool CheckNameFull(const UString &name) const;
+
+ const UStringVector&GetNamesVector(bool allowed, bool recursed, bool wildCard) const;
+ const UStringVector&GetAllowedNamesVector(bool recursed, bool wildCard) const
+ { return GetNamesVector(true, recursed, wildCard); }
+ const UStringVector&GetRecursedNamesVector(bool allowed, bool wildCard) const
+ { return GetNamesVector(allowed, true, wildCard); }
+ const UStringVector&GetAllowedRecursedNamesVector(bool wildCard) const
+ { return GetRecursedNamesVector(true, wildCard); }
+
+};
+
+class CCensor
+{
+public:
+ CCensorNode _head;
+ CCensor(): _head(NULL, L"") {}
+ void AddItem(const UString &path, bool allowed, bool recursed, bool wildCard);
+ bool CheckName(const UString &path) const;
+};
+
+}
+
+// return true if names differs only with '\' or '/' characters
+bool AreTheFileNamesDirDelimiterEqual(const UString &name1, const UString &name2);
+
+#endif
diff --git a/Common/WindowsTypes.h b/Common/WindowsTypes.h
new file mode 100755
index 00000000..510eb148
--- /dev/null
+++ b/Common/WindowsTypes.h
@@ -0,0 +1,75 @@
+// Common/WindowsTypes.h
+
+// #pragma once
+
+#ifndef __COMMON_WindowsTypes_H
+#define __COMMON_WindowsTypes_H
+
+ // typedef unsigned long UINT32;
+ typedef unsigned __int64 UINT64;
+ typedef UINT32 UINT;
+ typedef UINT32 DWORD;
+ #define CP_ACP 0
+ #define CP_OEMCP 1
+ #define CP_UTF8 65001
+ typedef const char *LPCTSTR;
+ typedef const wchar_t *LPCWSTR;
+ #define TEXT
+ typedef struct {
+ unsigned long Data1;
+ unsigned short Data2;
+ unsigned short Data3;
+ unsigned char Data4[ 8 ];
+ } GUID;
+ typedef GUID CLSID;
+ typedef char TCHAR;
+ typedef char CHAR;
+ typedef unsigned char UCHAR;
+ typedef short SHORT;
+ typedef unsigned short USHORT;
+ typedef int INT;
+ typedef UINT UINT_PTR;
+ typedef long BOOL;
+ typedef long LONG;
+ typedef unsigned long ULONG;
+ #define FALSE 0
+ #define TRUE 1
+ typedef short VARIANT_BOOL;
+ #define VARIANT_TRUE ((VARIANT_BOOL)-1)
+ #define VARIANT_FALSE ((VARIANT_BOOL)0)
+
+ #define FILE_ATTRIBUTE_READONLY 0x00000001
+ #define FILE_ATTRIBUTE_HIDDEN 0x00000002
+ #define FILE_ATTRIBUTE_SYSTEM 0x00000004
+ #define FILE_ATTRIBUTE_DIRECTORY 0x00000010
+ #define FILE_ATTRIBUTE_ARCHIVE 0x00000020
+ #define FILE_ATTRIBUTE_DEVICE 0x00000040
+ #define FILE_ATTRIBUTE_NORMAL 0x00000080
+ #define FILE_ATTRIBUTE_TEMPORARY 0x00000100
+ #define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200
+ #define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
+ #define FILE_ATTRIBUTE_COMPRESSED 0x00000800
+ #define FILE_ATTRIBUTE_OFFLINE 0x00001000
+ #define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000
+ #define FILE_ATTRIBUTE_ENCRYPTED 0x00004000
+ typedef struct _FILETIME {
+ DWORD dwLowDateTime;
+ DWORD dwHighDateTime;
+ } FILETIME, *PFILETIME, *LPFILETIME;
+ typedef void *HANDLE;
+
+ typedef __int64 LONGLONG;
+ typedef unsigned __int64 ULONGLONG;
+
+ struct LARGE_INTEGER { LONGLONG QuadPart; };
+ struct ULARGE_INTEGER { ULONGLONG QuadPart; };
+ typedef float FLOAT;
+ typedef double DOUBLE;
+ typedef VARIANT_BOOL _VARIANT_BOOL;
+ typedef LONG SCODE;
+ struct CY { LONGLONG int64; };
+ typedef double DATE;
+ typedef wchar_t *BSTR;
+
+#endif
+
diff --git a/DOC/7zFormat.txt b/DOC/7zFormat.txt
new file mode 100755
index 00000000..9710f219
--- /dev/null
+++ b/DOC/7zFormat.txt
@@ -0,0 +1,471 @@
+7z Format description (2.30 Beta 25)
+-----------------------------------
+
+This file contain descrition of 7z archive format.
+7z archive can contain files compressed with any method.
+See "Methods.txt" for description for defined compressing methods.
+
+
+Format structure Overview
+-------------------------
+
+Some fields can be optional.
+
+Archive structure
+~~~~~~~~~~~~~~~~~
+SignatureHeader
+[PackedStreams]
+[PackedStreamsForHeaders]
+[
+ Header
+ or
+ {
+ Packed Header
+ HeaderInfo
+ }
+]
+
+
+
+Header structure
+~~~~~~~~~~~~~~~~
+{
+ ArchiveProperties
+ AdditionalStreams
+ {
+ PackInfo
+ {
+ PackPos
+ NumPackStreams
+ Sizes[NumPackStreams]
+ CRCs[NumPackStreams]
+ }
+ CodersInfo
+ {
+ NumFolders
+ Folders[NumFolders]
+ {
+ NumCoders
+ CodersInfo[NumCoders]
+ {
+ ID
+ NumInStreams;
+ NumOutStreams;
+ PropertiesSize
+ Properties[PropertiesSize]
+ }
+ NumBindPairs
+ BindPairsInfo[NumBindPairs]
+ {
+ InIndex;
+ OutIndex;
+ }
+ PackedIndices
+ }
+ UnPackSize[Folders][Folders.NumOutstreams]
+ CRCs[NumFolders]
+ }
+ SubStreamsInfo
+ {
+ NumUnPackStreamsInFolders[NumFolders];
+ UnPackSizes[]
+ CRCs[]
+ }
+ }
+ MainStreamsInfo
+ {
+ (Same as in AdditionalStreams)
+ }
+ FilesInfo
+ {
+ NumFiles
+ Properties[]
+ {
+ ID
+ Size
+ Data
+ }
+ }
+}
+
+HeaderInfo structure
+~~~~~~~~~~~~~~~~~~~~
+{
+ (Same as in AdditionalStreams)
+}
+
+
+
+Notes about Notation and encoding
+---------------------------------
+
+7z uses little endian encoding.
+
+7z archive format has optional headers that are marked as
+[]
+Header
+[]
+
+REAL_UINT64 means real UINT64.
+
+UINT64 means real UINT64 encoded with the following scheme:
+
+ Size of encoding sequence depends from first byte:
+ First_Byte Extra_Bytes Value
+ (binary)
+ 0xxxxxxx : ( xxxxxxx )
+ 10xxxxxx BYTE y[1] : ( xxxxxx << (8 * 1)) + y
+ 110xxxxx BYTE y[2] : ( xxxxx << (8 * 2)) + y
+ ...
+ 1111110x BYTE y[6] : ( x << (8 * 6)) + y
+ 11111110 BYTE y[7] : y
+ 11111111 BYTE y[8] : y
+
+
+
+Property IDs
+------------
+
+0x00 = kEnd,
+
+0x01 = kHeader,
+
+0x02 = kArchiveProperties,
+
+0x03 = kAdditionalStreamsInfo,
+0x04 = kMainStreamsInfo,
+0x05 = kFilesInfo,
+
+0x06 = kPackInfo,
+0x07 = kUnPackInfo,
+0x08 = kSubStreamsInfo,
+
+0x09 = kSize,
+0x0A = kCRC,
+
+0x0B = kFolder,
+
+0x0C = kCodersUnPackSize,
+0x0D = kNumUnPackStream,
+
+0x0E = kEmptyStream,
+0x0F = kEmptyFile,
+0x10 = kAnti,
+
+0x11 = kName,
+0x12 = kCreationTime,
+0x13 = kLastAccessTime,
+0x14 = kLastWriteTime,
+0x15 = kWinAttributes,
+0x16 = kComment,
+
+0x17 = kEncodedHeader,
+
+
+7z format headers
+-----------------
+
+SignatureHeader
+~~~~~~~~~~~~~~~
+ BYTE kSignature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
+
+ ArchiveVersion
+ {
+ BYTE Major; // now it = 0
+ BYTE Minor; // now it = 1
+ };
+
+ UINT32 StartHeaderCRC;
+
+ StartHeader
+ {
+ REAL_UINT64 NextHeaderOffset
+ REAL_UINT64 NextHeaderSize
+ UINT32 NextHeaderCRC
+ }
+
+
+...........................
+
+
+ArchiveProperties
+~~~~~~~~~~~~~~~~~
+BYTE NID::kArchiveProperties (0x02)
+while(true)
+{
+ BYTE PropertyType;
+ if (aType == 0)
+ break;
+ UINT64 PropertySize;
+ BYTE PropertyData[PropertySize];
+}
+
+
+Digests (NumStreams)
+~~~~~~~~~~~~~~~~~~~~~
+ BYTE AllAreDefined
+ if (AllAreDefined == 0)
+ {
+ for(NumStreams)
+ BIT Defined
+ }
+ UINT32 CRCs[NumDefined]
+
+
+PackInfo
+~~~~~~~~~~~~
+ BYTE NID::kPackInfo (0x06)
+ UINT64 PackPos
+ UINT64 NumPackStreams
+
+ []
+ BYTE NID::kSize (0x09)
+ UINT64 PackSizes[NumPackStreams]
+ []
+
+ []
+ BYTE NID::kCRC (0x0A)
+ PackStreamDigests[NumPackStreams]
+ []
+
+ BYTE NID::kEnd
+
+
+Folder
+~~~~~~
+ UINT64 NumCoders;
+ for (NumCoders)
+ {
+ BYTE
+ {
+ 0:3 DecompressionMethod.IDSize
+ 4:
+ 0 - IsSimple
+ 1 - Is not simple
+ 5:
+ 0 - No Attributes
+ 1 - There Are Attributes
+ 7:
+ 0 - Last Method in Alternative_Method_List
+ 1 - There are more alternative methods
+ }
+ BYTE DecompressionMethod.ID[DecompressionMethod.IDSize]
+ if (!IsSimple)
+ {
+ UINT64 NumInStreams;
+ UINT64 NumOutStreams;
+ }
+ if (DecompressionMethod[0] != 0)
+ {
+ UINT64 PropertiesSize
+ BYTE Properties[PropertiesSize]
+ }
+ }
+
+ NumBindPairs = NumOutStreamsTotal - 1;
+
+ for (NumBindPairs)
+ {
+ UINT64 InIndex;
+ UINT64 OutIndex;
+ }
+
+ NumPackedStreams = NumInStreamsTotal - NumBindPairs;
+ if (NumPackedStreams > 1)
+ for(NumPackedStreams)
+ {
+ UINT64 Index;
+ };
+
+
+
+
+Coders Info
+~~~~~~~~~~~
+
+ BYTE NID::kUnPackInfo (0x07)
+
+
+ BYTE NID::kFolder (0x0B)
+ UINT64 NumFolders
+ BYTE External
+ switch(External)
+ {
+ case 0:
+ Folders[NumFolders]
+ case 1:
+ UINT64 DataStreamIndex
+ }
+
+
+ BYTE ID::kCodersUnPackSize (0x0C)
+ for(Folders)
+ for(Folder.NumOutStreams)
+ UINT64 UnPackSize;
+
+
+ []
+ BYTE NID::kCRC (0x0A)
+ UnPackDigests[NumFolders]
+ []
+
+
+
+ BYTE NID::kEnd
+
+
+
+SubStreams Info
+~~~~~~~~~~~~~~
+ BYTE NID::kSubStreamsInfo; (0x08)
+
+ []
+ BYTE NID::kNumUnPackStream; (0x0D)
+ UINT64 NumUnPackStreamsInFolders[NumFolders];
+ []
+
+
+ []
+ BYTE NID::kSize (0x09)
+ UINT64 UnPackSizes[]
+ []
+
+
+ []
+ BYTE NID::kCRC (0x0A)
+ Digests[Number of streams with unknown CRC]
+ []
+
+
+ BYTE NID::kEnd
+
+
+Streams Info
+~~~~~~~~~~~~
+
+ []
+ PackInfo
+ []
+
+
+ []
+ CodersInfo
+ []
+
+
+ []
+ SubStreamsInfo
+ []
+
+ BYTE NID::kEnd
+
+
+FilesInfo
+~~~~~~~~~
+ BYTE NID::kFilesInfo; (0x05)
+ UINT64 NumFiles
+
+ while(true)
+ {
+ BYTE PropertyType;
+ if (aType == 0)
+ break;
+
+ UINT64 Size;
+
+ switch(PropertyType)
+ {
+ kEmptyStream: (0x0E)
+ for(NumFiles)
+ BIT IsEmptyStream
+
+ kEmptyFile: (0x0F)
+ for(EmptyStreams)
+ BIT IsEmptyFile
+
+ kAnti: (0x10)
+ for(EmptyStreams)
+ BIT IsAntiFile
+
+ case kCreationTime: (0x12)
+ case kLastAccessTime: (0x13)
+ case kLastWriteTime: (0x14)
+ BYTE AllAreDefined
+ if (AllAreDefined == 0)
+ {
+ for(NumFiles)
+ BIT TimeDefined
+ }
+ BYTE External;
+ if(External != 0)
+ UINT64 DataIndex
+ []
+ for(Definded Items)
+ UINT32 Time
+ []
+
+ kNames: (0x11)
+ BYTE External;
+ if(External != 0)
+ UINT64 DataIndex
+ []
+ for(Files)
+ {
+ wchar_t Names[NameSize];
+ wchar_t 0;
+ }
+ []
+
+ kAttributes: (0x15)
+ BYTE AllAreDefined
+ if (AllAreDefined == 0)
+ {
+ for(NumFiles)
+ BIT AttributesAreDefined
+ }
+ BYTE External;
+ if(External != 0)
+ UINT64 DataIndex
+ []
+ for(Definded Attributes)
+ UINT32 Attributes
+ []
+ }
+ }
+
+
+Header
+~~~~~~
+ BYTE NID::kHeader (0x01)
+
+ []
+ ArchiveProperties
+ []
+
+ []
+ BYTE NID::kAdditionalStreamsInfo; (0x03)
+ StreamsInfo
+ []
+
+ []
+ BYTE NID::kMainStreamsInfo; (0x04)
+ StreamsInfo
+ []
+
+ []
+ FilesInfo
+ []
+
+ BYTE NID::kEnd
+
+
+HeaderInfo
+~~~~~~~~~~
+ []
+ BYTE NID::kEncodedHeader; (0x17)
+ StreamsInfo for Encoded Header
+ []
+
+
+---
+End of document
diff --git a/DOC/Methods.txt b/DOC/Methods.txt
new file mode 100755
index 00000000..c766bbb5
--- /dev/null
+++ b/DOC/Methods.txt
@@ -0,0 +1,108 @@
+Compression method IDs (3.08 beta)
+----------------------------------
+
+Each compression method in 7z has unique binary value (ID).
+The length of ID in bytes is arbitrary but it can not exceed 15 bytes.
+
+List of defined IDs
+-------------------
+
+00 - Copy
+01 - Reserved
+02 - Common
+ 03 Swap
+ - 2 Swap2
+ - 4 Swap4
+ 04 Delta (subject to change)
+
+03 - 7z
+ 01 - LZMA
+ 01 - Version
+
+ 03 - Branch
+ 01 - x86
+ 03 - BCJ
+ 1B - BCJ2
+ 02 - PPC
+ 05 - BC_PPC_B (Big Endian)
+ 03 - Alpha
+ 01 - BC_Alpha
+ 04 - IA64
+ 01 - BC_IA64
+ 05 - ARM
+ 01 - BC_ARM
+ 06 - M68
+ 05 - BC_M68_B (Big Endian)
+ 07 - ARM Thumb
+ 01 - BC_ARMThumb
+ 08 - reserved for SPARC
+
+ 04 - PPMD
+ 01 - Version
+
+04 - Misc
+ 00 - Reserved
+ 01 - Zip
+ 06 - Imploded
+ 08 - Deflate
+ 09 - Deflate64
+ 02 - BZip
+ 02 - BZip2
+ 03 - Rar
+ 01 - Rar15
+ 02 - Rar20
+ 03 - Rar29
+ 04 - Arj
+ 01 - Arj (1,2,3)
+ 02 - Arj 4
+
+ 07 - Reserved
+
+
+06 - Crypto
+ 00 -
+ 01 - AES
+ 0x - AES-128
+ 4x - AES-192
+ 8x - AES-256
+
+ x0 - ECB
+ x1 - CBC
+ x2 - CFB
+ x3 - OFB
+
+ 07 - Reserved
+ 0F - Reserved
+
+ F0 - Misc Ciphers (Real Ciphers without hashing algo)
+
+ F1 - Misc Ciphers (Combine)
+ 01 - Zip
+ 01 - Main Zip crypto algo
+ 03 - RAR
+ 02 -
+ 03 - Rar29 AES-128 + (modified SHA-1)
+ 07 - 7z
+ 01 - AES-256 + SHA-256
+
+07 - Hash (subject to change)
+ 00 -
+ 01 - CRC
+ 02 - SHA-1
+ 03 - SHA-256
+ 04 - SHA-384
+ 05 - SHA-512
+
+ F0 - Misc Hash
+
+ F1 - Misc
+ 03 - RAR
+ 03 - Rar29 Password Hashing (modified SHA1)
+ 07 - 7z
+ 01 - SHA-256 Password Hashing
+
+
+
+
+---
+End of document
diff --git a/DOC/copying.txt b/DOC/copying.txt
new file mode 100755
index 00000000..4c389012
--- /dev/null
+++ b/DOC/copying.txt
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/DOC/history.txt b/DOC/history.txt
new file mode 100755
index 00000000..64f7b7c9
--- /dev/null
+++ b/DOC/history.txt
@@ -0,0 +1,213 @@
+Sources history of the 7-Zip
+----------------------------
+
+ Version 3.11 2003-10-06
+ --------------------------------------
+ File functions support unicode strings even
+ on Windows 95/98/ME.
+
+
+ Version 3.08.02 2003-09-20
+ --------------------------------------
+ More compatible with GCC.
+
+
+ Version 3.08.02 beta 2003-08-20
+ --------------------------------------
+ Extracting bug in 7zExtract.cpp was fixed.
+
+
+ Version 3.08 beta 2003-08-19
+ --------------------------------------
+ Big source code reconstruction.
+
+
+ Version 2.30 Beta 32 2003-05-15
+ --------------------------------------
+ Small changes in Deflate decoder.
+
+
+ Version 2.30 Beta 31 2003-04-29
+ --------------------------------------
+ Common/NewHandler.cpp
+ HeapAlloc in (included to beta 30) was changed to malloc.
+ HeapAlloc worked slower in Win95/98/Me.
+
+
+ Version 2.30 Beta 30 2003-04-21
+ --------------------------------------
+ new file: Common/String.cpp
+ Common/NewHandler.* were changed
+
+
+ Version 2.30 Beta 29 2003-04-07
+ --------------------------------------
+ Small changes in LZMA code.
+
+
+ Version 2.30 Beta 28 2003-02-16
+ --------------------------------------
+ Processing anti-files was corrected.
+
+
+ Version 2.30 Beta 27 2003-01-24
+ --------------------------------------
+ Project/Archiver/Format/Common/ArchiveInterface.h:
+ new IArchiveOpenVolumeCallback interface.
+
+
+ Version 2.30 Beta 26 2003-01-12
+ --------------------------------------
+ SDK/Interface/PropID.h:
+ kpidComment now is kpidCommented
+
+
+ Version 2.30 Beta 25 2003-01-02
+ --------------------------------------
+ Main archive interfaces were changed.
+
+
+ Version 2.30 Beta 24 2002-11-01
+ --------------------------------------
+ SDK/Windows/Synchronization.h
+ SDK/Windows/Synchronization.cpp
+ - some changes.
+
+
+ Version 2.30 Beta 23 2002-09-07
+ --------------------------------------
+ Project/FileManager folder was added.
+ Notation of some source files was changed.
+
+
+ Version 2.30 Beta 22 2002-08-28
+ --------------------------------------
+ Project/FileManager folder was added.
+ Notation of some source files was changed.
+
+
+
+ Version 2.30 Beta 21 2002-07-08
+ --------------------------------------
+ Project/Compress/LZ/MatchFinder/BinTree/BinTree.h
+ Project/Compress/LZ/MatchFinder/BinTree/BinTreeMain.h
+ Project/Compress/LZ/MatchFinder/BinTree/HC.h
+ Project/Compress/LZ/MatchFinder/BinTree/HCMain.h
+ - RAM requirements for LZMA (7z) compression were reduced.
+
+
+ Version 2.30 Beta 20 2002-07-01
+ --------------------------------------
+ - SDK/Stream/WindowOut.h
+ now it uses only required memory (dictionary size).
+ - Project/Archiver/Resource
+ contains common resurces
+
+
+ Version 2.30 Beta 19 2002-04-11
+ --------------------------------------
+ - SDK/Archive/Rar/Handler.cpp
+ supporting RAR29
+
+ Version 2.30 Beta 18 2002-03-25
+ --------------------------------------
+ - SDK/Archive/Cab/MSZipDecoder.cpp
+ SDK/Archive/Cab/LZXDecoder.cpp:
+ bug with corrupted archives was fixed
+ - Project/Compress/LZ/MatchFinder/BinTree/BinTree.h
+ - Project/Compress/LZ/MatchFinder/BinTree/BinTreeMain.h
+ some speed optimization (using prefetching)
+
+
+ Version 2.30 Beta 17 2002-03-03
+ --------------------------------------
+ - ARJ suppport.
+
+
+ Version 2.30 Beta 16 2002-02-24
+ --------------------------------------
+ - Project/Compress/LZ/LZMA/Decoder.cpp:
+ Bug was fixed: LZMA could not extract more than 4 GB.
+ - RPM and CPIO formats.
+ - Project/Compress/LZ/LZMA/Encoder.*
+ Project/Archiver/Format/7z/OutHandler.cpp
+ New fast compression mode for LZMA: -m0a=0.
+ - New match finders for LZMA: bt4b, hc3, hc4.
+
+
+ Version 2.30 Beta 15 2002-02-17
+ --------------------------------------
+ - Compression ratio in LZMA was slightly improved:
+ Project/Compress/LZ/LZMA/Encoder.*
+ Project/Archiver/Format/7z/OutHandler.cpp
+
+
+ Version 2.30 Beta 14 2002-02-10
+ --------------------------------------
+ - Supporting multithreading for LZMA:
+ Project/Compress/LZ/MatchFinder/MT
+ - Common/String.h:
+ CStringBase::Replace function was fixed.
+
+
+ Version 2.30 Beta 13 2002-01-27
+ --------------------------------------
+ - Compress/LZ/MatchFinder/BinTree3.h:
+ method
+ - Compress/LZ/MatchFinder/BinTreemain.h:
+ - one VirtualAlloc array was splitted to
+ the for 3 arrays.
+ - Hash-functions were changed.
+
+
+
+ Version 2.30 Beta 12 2002-01-16
+ --------------------------------------
+ - Compress/LZ/MatchFinder/BinTreemain.h:
+ Compress/LZ/MatchFinder/Patricia.h:
+ Compress/PPM/PPMd/SubAlloc.h:
+ Beta 11 bugs were fixed:
+ - VirtualFree was used incorrectly
+ - checking WIN32 instead _WINDOWS.
+ Compress/LZ/MatchFinder/Patricia.h:
+ Beta 11 bug with deleting m_Hash2Descendants was fixed.
+
+
+ Version 2.30 Beta 11 2002-01-15
+ --------------------------------------
+ - Compress/LZ/MatchFinder/BinTreemain.h:
+ Compress/LZ/MatchFinder/Patricia.h:
+ Compress/PPM/PPMd/SubAlloc.h:
+ using VirtualAlloc for memory allocating
+ - Exlorer/ContextMenu.cpp:
+ Testing supporting.
+ CreateProcess instead WinExec
+ - Format/Common/IArchiveHandler.h:
+ Exlorer/ProxyHandler.cpp:
+ FAR/Plugin.cpp:
+ New properties names: Method, HostOS.
+ - Exlorer/OverwriteDialog.cpp:
+ FAR/OverwriteDialog.cpp:
+ Windows/PropVariantConversions.h
+ Using National time format was eliminated.
+
+
+
+ Version 2.30 Beta 10 2002-01-11
+ --------------------------------------
+ - Exlorer/ContextMenu.cpp: bug with context menu on
+ Windows NT4 in Unicode version was fixed.
+ - Format/7z/UpdateArchiveEngine.cpp: bug was fixed -
+ Updating in Beta 8 and 9 didn't work.
+ - Exlorer/CCompressDialog.cpp: history growing bug was fixed.
+
+
+ Version 2.30 Beta 9 2002-01-08
+ --------------------------------------
+ - SDK/Common/Vector.h: sopporting sorted object vectors .
+ - Lang features.
+ - Two new match finders: pat3h and pat4h.
+ - SDK/Archive/Zip/InEngine.cpp: bug was fixed.
+ - SDK/Windows/FileDir.cpp: function CreateComplexDirectory
+ was changed.
+
diff --git a/DOC/readme.txt b/DOC/readme.txt
new file mode 100755
index 00000000..c800237a
--- /dev/null
+++ b/DOC/readme.txt
@@ -0,0 +1,161 @@
+7-Zip 3.11 Sources
+------------------
+
+7-Zip is a file archiver for Windows 95/98/ME/NT/2000/XP.
+
+7-Zip Copyright (C) 1999-2003 Igor Pavlov.
+
+
+License Info
+------------
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+License notes
+-------------
+
+You can support development of 7-Zip by registering and
+paying $20. As registered user, you will be able
+to get technical support via e-mail support@7-zip.org.
+
+7-Zip is free software distributed under the GNU LGPL.
+If you need license with other conditions, write to support@7-zip.org.
+You also can request for help in creating code based on
+7-Zip's code for your custom application.
+
+
+How to compile
+--------------
+To compile sources you need Visual C++ 6.0.
+For compiling some files you also need
+new Platform SDK from Microsoft' Site:
+http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm
+or
+http://www.microsoft.com/msdownload/platformsdk/sdkupdate/
+
+
+Notes:
+------
+7-Zip consists of COM modules (DLL files).
+But 7-Zip doesn't use standard COM interfaces for creating objects.
+Look at
+7zip\UI\Client7z folder for example of using DLL files of 7-Zip.
+Some DLL files can use other DLL files from 7-Zip.
+If you don't like it, you must use standalone version of DLL.
+To compile standalone version of DLL you must include all used parts
+to project and define some defs.
+For example, 7zip\Bundles\Format7z is a standalone version of 7z.dll
+that works with 7z format. So you can use such DLL in your project
+without additional DLL files.
+
+
+Description of 7-Zip sources package
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+DOC Documentation
+---
+ 7zFormat.txt - 7z format description
+ copying.txt - GNU LGPL license
+ history.txt - Sources history
+ Methods.txt - Compression method IDs
+ readme.txt - Readme file
+
+ Alien Must contains third party sources
+ Compress
+ BZip2 BZip2 compression sources from
+ http://sources.redhat.com/bzip2/index.html
+
+
+Common Common modules
+Windows Win32 wrappers
+Far FAR interface wrappers
+
+7zip
+-------
+ Common Common modules for 7-zip
+
+ Archive 7-Zip Archive Format Plugins
+ --------
+ Common
+ 7z
+ Arj
+ BZip2
+ Cab
+ Cpio
+ GZip
+ Rar
+ Rpm
+ Split
+ Tar
+ Zip
+
+ Bundle Modules that are bundles of other modules
+ ------
+ Alone 7za.exe: Standalone version of 7z
+ SFXCon 7zCon.sfx: Console 7z SFX module
+ SFXWin 7z.sfx: Windows 7z SFX module
+ SFXSetup 7zS.sfx: Windows 7z SFX module for Installers
+ Format7z 7za.dll: Standalone version of 7z.dll
+
+ UI
+ --
+ Agent Intermediary modules for FAR plugin and Explorer plugin
+ Console 7z.exe Console version
+ Explorer Explorer plugin
+ Resource Resources
+ Far FAR plugin
+ Client7z Test application for 7za.dll
+
+ Compress
+ --------
+ BZip2 BZip2 compressor
+ Original Download BZip2 compression sources from
+ http://sources.redhat.com/bzip2/index.html
+ to that folder.
+ Branch Branch converter
+ ByteSwap Byte Swap converter
+ Copy Copy coder
+ Deflate
+ Implode
+ Arj
+ LZMA
+ PPMd Dmitry Shkarin's PPMdH with small changes.
+ LZ Lempel - Ziv
+ MT Multi Thread Match finder
+ BinTree Match Finder based on Binary Tree
+ Patricia Match Finder based on Patricia algoritm
+ HashChain Match Finder based on Hash Chains
+
+ Crypto Crypto modules
+ ------
+ 7zAES Cipher for 7z
+ AES AES Cipher
+ Rar20 Cipher for Rar 2.0
+ RarAES Cipher for Rar 3.0
+ Zip Cipher for Zip
+
+ FileManager File Manager
+
+
+---
+Igor Pavlov
+http://www.7-zip.org
+support@7-zip.org
+
+
+---
+End of document
+
diff --git a/Far/FarPlugin.h b/Far/FarPlugin.h
new file mode 100755
index 00000000..31e85c6c
--- /dev/null
+++ b/Far/FarPlugin.h
@@ -0,0 +1,564 @@
+#pragma once
+
+#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;
+ int Selected;
+ 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
diff --git a/Far/FarUtils.cpp b/Far/FarUtils.cpp
new file mode 100755
index 00000000..ad6db12a
--- /dev/null
+++ b/Far/FarUtils.cpp
@@ -0,0 +1,421 @@
+// 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;
+using namespace std;
+
+namespace NFar {
+
+CStartupInfo g_StartupInfo;
+
+
+void CStartupInfo::Init(const PluginStartupInfo &aPluginStartupInfo,
+ const CSysString &aPliginNameForRegestry)
+{
+ m_Data = aPluginStartupInfo;
+ m_RegistryPath = aPluginStartupInfo.RootKey;
+ m_RegistryPath += '\\';
+ m_RegistryPath += aPliginNameForRegestry;
+}
+
+const char *CStartupInfo::GetMsgString(int aMessageId)
+{
+ return (const char*)m_Data.GetMsg(m_Data.ModuleNumber, aMessageId);
+}
+
+int CStartupInfo::ShowMessage(unsigned int aFlags,
+ const char *aHelpTopic, const char **anItems, int anItemsNumber, int aButtonsNumber)
+{
+ return m_Data.Message(m_Data.ModuleNumber, aFlags, (char *)aHelpTopic,
+ (char **)anItems, anItemsNumber, aButtonsNumber);
+}
+
+namespace NMessageID
+{
+ enum
+ {
+ kOk,
+ kCancel,
+ kWarning,
+ kError
+ };
+}
+
+int CStartupInfo::ShowMessage(const char *aMessage)
+{
+ const char *aMessagesItems[]= { GetMsgString(NMessageID::kError), aMessage,
+ GetMsgString(NMessageID::kOk) };
+ return ShowMessage(FMSG_WARNING, NULL, aMessagesItems,
+ sizeof(aMessagesItems) / sizeof(aMessagesItems[0]), 1);
+}
+
+int CStartupInfo::ShowMessage(int aMessageId)
+{
+ return ShowMessage(GetMsgString(aMessageId));
+}
+
+int CStartupInfo::ShowDialog(int X1, int Y1, int X2, int Y2,
+ const char *aHelpTopic, struct FarDialogItem *anItems, int aNumItems)
+{
+ return m_Data.Dialog(m_Data.ModuleNumber, X1, Y1, X2, Y2, (char *)aHelpTopic,
+ anItems, aNumItems);
+}
+
+int CStartupInfo::ShowDialog(int aSizeX, int aSizeY,
+ const char *aHelpTopic, struct FarDialogItem *anItems, int aNumItems)
+{
+ return ShowDialog(-1, -1, aSizeX, aSizeY, aHelpTopic, anItems, aNumItems);
+}
+
+inline static BOOL GetBOOLValue(bool aBool)
+{
+ return (aBool? TRUE: FALSE);
+}
+
+void CStartupInfo::InitDialogItems(const CInitDialogItem *aSrcItems,
+ FarDialogItem *aDestItems, int aNum)
+{
+ for (int i = 0; i < aNum; i++)
+ {
+ const CInitDialogItem &aSrcItem = aSrcItems[i];
+ FarDialogItem &aDestItem = aDestItems[i];
+
+ aDestItem.Type = aSrcItem.Type;
+ aDestItem.X1 = aSrcItem.X1;
+ aDestItem.Y1 = aSrcItem.Y1;
+ aDestItem.X2 = aSrcItem.X2;
+ aDestItem.Y2 = aSrcItem.Y2;
+ aDestItem.Focus = GetBOOLValue(aSrcItem.Focus);
+ if(aSrcItem.HistoryName != NULL)
+ aDestItem.Selected = int(aSrcItem.HistoryName);
+ else
+ aDestItem.Selected = GetBOOLValue(aSrcItem.Selected);
+ aDestItem.Flags = aSrcItem.Flags;
+ aDestItem.DefaultButton = GetBOOLValue(aSrcItem.DefaultButton);
+
+ if(aSrcItem.DataMessageId < 0)
+ strcpy(aDestItem.Data, aSrcItem.DataString);
+ else
+ strcpy(aDestItem.Data, GetMsgString(aSrcItem.DataMessageId));
+
+ /*
+ if ((unsigned int)Init[i].Data < 0xFFF)
+ strcpy(aDestItem.Data, GetMsg((unsigned int)aSrcItem.Data));
+ else
+ strcpy(aDestItem.Data,aSrcItem.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 aHandle)
+{
+ m_Data.RestoreScreen(aHandle);
+}
+
+const char kRegestryKeyDelimiter = '\'';
+
+CSysString CStartupInfo::GetFullKeyName(const CSysString &aKeyName) const
+{
+ return (aKeyName.IsEmpty()) ? m_RegistryPath:
+ (m_RegistryPath + kRegestryKeyDelimiter + aKeyName);
+}
+
+
+LONG CStartupInfo::CreateRegKey(HKEY aKeyParent,
+ const CSysString &aKeyName, NRegistry::CKey &aDestKey) const
+{
+ return aDestKey.Create(aKeyParent, GetFullKeyName(aKeyName));
+}
+
+LONG CStartupInfo::OpenRegKey(HKEY aKeyParent,
+ const CSysString &aKeyName, NRegistry::CKey &aDestKey) const
+{
+ return aDestKey.Open(aKeyParent, GetFullKeyName(aKeyName));
+}
+
+void CStartupInfo::SetRegKeyValue(HKEY aKeyParent, const CSysString &aKeyName,
+ LPCTSTR aValueName, LPCTSTR aValue) const
+{
+ NRegistry::CKey aRegKey;
+ CreateRegKey(aKeyParent, aKeyName, aRegKey);
+ aRegKey.SetValue(aValueName, aValue);
+}
+
+void CStartupInfo::SetRegKeyValue(HKEY aKeyParent, const CSysString &aKeyName,
+ LPCTSTR aValueName, UINT32 aValue) const
+{
+ NRegistry::CKey aRegKey;
+ CreateRegKey(aKeyParent, aKeyName, aRegKey);
+ aRegKey.SetValue(aValueName, aValue);
+}
+
+void CStartupInfo::SetRegKeyValue(HKEY aKeyParent, const CSysString &aKeyName,
+ LPCTSTR aValueName, bool aValue) const
+{
+ NRegistry::CKey aRegKey;
+ CreateRegKey(aKeyParent, aKeyName, aRegKey);
+ aRegKey.SetValue(aValueName, aValue);
+}
+
+CSysString CStartupInfo::QueryRegKeyValue(HKEY aKeyParent, const CSysString &aKeyName,
+ LPCTSTR aValueName, const CSysString &aValueDefault) const
+{
+ NRegistry::CKey aRegKey;
+ if (OpenRegKey(aKeyParent, aKeyName, aRegKey) != ERROR_SUCCESS)
+ return aValueDefault;
+
+ CSysString aValue;
+ if(aRegKey.QueryValue(aValueName, aValue) != ERROR_SUCCESS)
+ return aValueDefault;
+
+ return aValue;
+}
+
+UINT32 CStartupInfo::QueryRegKeyValue(HKEY aKeyParent, const CSysString &aKeyName,
+ LPCTSTR aValueName, UINT32 aValueDefault) const
+{
+ NRegistry::CKey aRegKey;
+ if (OpenRegKey(aKeyParent, aKeyName, aRegKey) != ERROR_SUCCESS)
+ return aValueDefault;
+
+ UINT32 aValue;
+ if(aRegKey.QueryValue(aValueName, aValue) != ERROR_SUCCESS)
+ return aValueDefault;
+
+ return aValue;
+}
+
+bool CStartupInfo::QueryRegKeyValue(HKEY aKeyParent, const CSysString &aKeyName,
+ LPCTSTR aValueName, bool aValueDefault) const
+{
+ NRegistry::CKey aRegKey;
+ if (OpenRegKey(aKeyParent, aKeyName, aRegKey) != ERROR_SUCCESS)
+ return aValueDefault;
+
+ bool aValue;
+ if(aRegKey.QueryValue(aValueName, aValue) != ERROR_SUCCESS)
+ return aValueDefault;
+
+ return aValue;
+}
+
+bool CStartupInfo::Control(HANDLE aPlugin, int aCommand, void *aParam)
+{
+ return BOOLToBool(m_Data.Control(aPlugin, aCommand, aParam));
+}
+
+bool CStartupInfo::ControlRequestActivePanel(int aCommand, void *aParam)
+{
+ return Control(INVALID_HANDLE_VALUE, aCommand, aParam);
+}
+
+bool CStartupInfo::ControlGetActivePanelInfo(PanelInfo &aPanelInfo)
+{
+ return ControlRequestActivePanel(FCTL_GETPANELINFO, &aPanelInfo);
+}
+
+bool CStartupInfo::ControlSetSelection(const PanelInfo &aPanelInfo)
+{
+ return ControlRequestActivePanel(FCTL_SETSELECTION, (void *)&aPanelInfo);
+}
+
+bool CStartupInfo::ControlGetActivePanelCurrentItemInfo(
+ PluginPanelItem &aPluginPanelItem)
+{
+ PanelInfo aPanelInfo;
+ if(!ControlGetActivePanelInfo(aPanelInfo))
+ return false;
+ if(aPanelInfo.ItemsNumber <= 0)
+ throw "There are no items";
+ aPluginPanelItem = aPanelInfo.PanelItems[aPanelInfo.CurrentItem];
+ return true;
+}
+
+bool CStartupInfo::ControlGetActivePanelSelectedOrCurrentItems(
+ CObjectVector<PluginPanelItem> &aPluginPanelItems)
+{
+ aPluginPanelItems.Clear();
+ PanelInfo aPanelInfo;
+ if(!ControlGetActivePanelInfo(aPanelInfo))
+ return false;
+ if(aPanelInfo.ItemsNumber <= 0)
+ throw "There are no items";
+ if (aPanelInfo.SelectedItemsNumber == 0)
+ aPluginPanelItems.Add(aPanelInfo.PanelItems[aPanelInfo.CurrentItem]);
+ else
+ for (int i = 0; i < aPanelInfo.SelectedItemsNumber; i++)
+ aPluginPanelItems.Add(aPanelInfo.SelectedItems[i]);
+ return true;
+}
+
+bool CStartupInfo::ControlClearPanelSelection()
+{
+ PanelInfo aPanelInfo;
+ if(!ControlGetActivePanelInfo(aPanelInfo))
+ return false;
+ for (int i = 0; i < aPanelInfo.ItemsNumber; i++)
+ aPanelInfo.PanelItems[i].Flags &= ~PPIF_SELECTED;
+ return ControlSetSelection(aPanelInfo);
+}
+
+////////////////////////////////////////////////
+// menu function
+
+int CStartupInfo::Menu(
+ int x,
+ int y,
+ int aMaxHeight,
+ unsigned int aFlags,
+ const char *aTitle,
+ const char *aBottom,
+ const char *aHelpTopic,
+ int *aBreakKeys,
+ int *aBreakCode,
+ struct FarMenuItem *anItems,
+ int aNumItems)
+{
+ return m_Data.Menu(m_Data.ModuleNumber, x, y, aMaxHeight, aFlags, (char *)aTitle,
+ (char *)aBottom, (char *)aHelpTopic, aBreakKeys, aBreakCode, anItems, aNumItems);
+}
+
+int CStartupInfo::Menu(
+ unsigned int aFlags,
+ const char *aTitle,
+ const char *aHelpTopic,
+ struct FarMenuItem *anItems,
+ int aNumItems)
+{
+ return Menu(-1, -1, 0, aFlags, aTitle, NULL, aHelpTopic, NULL,
+ NULL, anItems, aNumItems);
+}
+
+int CStartupInfo::Menu(
+ unsigned int aFlags,
+ const char *aTitle,
+ const char *aHelpTopic,
+ const CSysStringVector &anItems,
+ int aSelectedItem)
+{
+ vector<FarMenuItem> aFarMenuItems;
+ for(int i = 0; i < anItems.Size(); i++)
+ {
+ FarMenuItem anItem;
+ anItem.Checked = 0;
+ anItem.Separator = 0;
+ anItem.Selected = (i == aSelectedItem);
+ CSysString aReducedString =
+ anItems[i].Left(sizeof(anItem.Text) / sizeof(anItem.Text[0]) - 1);
+ strcpy(anItem.Text, aReducedString);
+ aFarMenuItems.push_back(anItem);
+ }
+ return Menu(aFlags, aTitle, aHelpTopic, &aFarMenuItems.front(),
+ aFarMenuItems.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 CSysString DWORDToString(DWORD aNumber)
+{
+ char aBuffer[32];
+ ultoa(aNumber, aBuffer, 10);
+ return aBuffer;
+}
+
+void PrintErrorMessage(const char *aMessage, int anCode)
+{
+ CSysString aTmp = aMessage;
+ aTmp += " #";
+ aTmp += DWORDToString(anCode);
+ g_StartupInfo.ShowMessage(aTmp);
+}
+
+void PrintErrorMessage(const char *aMessage, const char *aText)
+{
+ CSysString aTmp = aMessage;
+ aTmp += ": ";
+ aTmp += aText;
+ g_StartupInfo.ShowMessage(aTmp);
+}
+
+bool WasEscPressed()
+{
+ NConsole::CIn anInConsole;
+ HANDLE aHandle = ::GetStdHandle(STD_INPUT_HANDLE);
+ if(aHandle == INVALID_HANDLE_VALUE)
+ return true;
+ anInConsole.Attach(aHandle);
+ while (true)
+ {
+ DWORD aNumberOfEvents;
+ if(!anInConsole.GetNumberOfEvents(aNumberOfEvents))
+ return true;
+ if(aNumberOfEvents == 0)
+ return false;
+
+ INPUT_RECORD anEvent;
+ if(!anInConsole.ReadEvent(anEvent, aNumberOfEvents))
+ return true;
+ if (anEvent.EventType == KEY_EVENT &&
+ anEvent.Event.KeyEvent.bKeyDown &&
+ anEvent.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)
+ return true;
+ }
+}
+
+void ShowErrorMessage(DWORD aError)
+{
+ CSysString aMessage;
+ NError::MyFormatMessage(aError, aMessage);
+ g_StartupInfo.ShowMessage(SystemStringToOemString(aMessage));
+
+}
+
+void ShowLastErrorMessage()
+{
+ ShowErrorMessage(::GetLastError());
+}
+
+}
diff --git a/Far/FarUtils.h b/Far/FarUtils.h
new file mode 100755
index 00000000..a6240349
--- /dev/null
+++ b/Far/FarUtils.h
@@ -0,0 +1,220 @@
+// FarUtils.h
+
+#pragma once
+
+#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 &aKeyName) const;
+ LONG CreateRegKey(HKEY aKeyParent,
+ const CSysString &aKeyName, NWindows::NRegistry::CKey &aDestKey) const;
+ LONG OpenRegKey(HKEY aKeyParent,
+ const CSysString &aKeyName, NWindows::NRegistry::CKey &aDestKey) const;
+
+public:
+ void Init(const PluginStartupInfo &aPluginStartupInfo,
+ const CSysString &aPliginNameForRegestry);
+ const char *GetMsgString(int aMessageId);
+ int ShowMessage(unsigned int aFlags, const char *aHelpTopic,
+ const char **anItems, int anItemsNumber, int aButtonsNumber);
+ int ShowMessage(const char *aMessage);
+ int ShowMessage(int aMessageId);
+
+ int ShowDialog(int X1, int Y1, int X2, int Y2,
+ const char *aHelpTopic, struct FarDialogItem *anItems, int aNumItems);
+ int ShowDialog(int aSizeX, int aSizeY,
+ const char *aHelpTopic, struct FarDialogItem *anItems, int aNumItems);
+
+ void InitDialogItems(const CInitDialogItem *aSrcItems,
+ FarDialogItem *aDestItems, int aNum);
+
+ HANDLE SaveScreen(int X1, int Y1, int X2, int Y2);
+ HANDLE SaveScreen();
+ void RestoreScreen(HANDLE aHandle);
+
+ void SetRegKeyValue(HKEY aKeyParent, const CSysString &aKeyName,
+ const LPCTSTR aValueName, LPCTSTR aValue) const;
+ void SetRegKeyValue(HKEY hRoot, const CSysString &aKeyName,
+ const LPCTSTR aValueName, UINT32 aValue) const;
+ void SetRegKeyValue(HKEY hRoot, const CSysString &aKeyName,
+ const LPCTSTR aValueName, bool aValue) const;
+
+ CSysString QueryRegKeyValue(HKEY aKeyParent, const CSysString &aKeyName,
+ LPCTSTR aValueName, const CSysString &aValueDefault) const;
+
+ UINT32 QueryRegKeyValue(HKEY aKeyParent, const CSysString &aKeyName,
+ LPCTSTR aValueName, UINT32 aValueDefault) const;
+
+ bool QueryRegKeyValue(HKEY aKeyParent, const CSysString &aKeyName,
+ LPCTSTR aValueName, bool aValueDefault) const;
+
+ bool Control(HANDLE aPlugin, int aCommand, void *aParam);
+ bool ControlRequestActivePanel(int aCommand, void *aParam);
+ bool ControlGetActivePanelInfo(PanelInfo &aPanelInfo);
+ bool ControlSetSelection(const PanelInfo &aPanelInfo);
+ bool ControlGetActivePanelCurrentItemInfo(PluginPanelItem &aPluginPanelItem);
+ bool ControlGetActivePanelSelectedOrCurrentItems(
+ CObjectVector<PluginPanelItem> &aPluginPanelItems);
+
+ bool ControlClearPanelSelection();
+
+ int Menu(
+ int x,
+ int y,
+ int aMaxHeight,
+ unsigned int aFlags,
+ const char *aTitle,
+ const char *aBottom,
+ const char *aHelpTopic,
+ int *aBreakKeys,
+ int *aBreakCode,
+ FarMenuItem *anItems,
+ int aNumItems);
+ int Menu(
+ unsigned int aFlags,
+ const char *aTitle,
+ const char *aHelpTopic,
+ FarMenuItem *anItems,
+ int aNumItems);
+
+ int Menu(
+ unsigned int aFlags,
+ const char *aTitle,
+ const char *aHelpTopic,
+ const CSysStringVector &anItems,
+ int aSelectedItem);
+
+ int Editor(const char *aFileName, const char *aTitle,
+ int X1, int Y1, int X2, int Y2, DWORD aFlags, int aStartLine, int aStartChar)
+ { return m_Data.Editor((char *)aFileName, (char *)aTitle, X1, Y1, X2, Y2,
+ aFlags, aStartLine, aStartChar); }
+ int Editor(const char *aFileName)
+ { return Editor(aFileName, NULL, 0, 0, -1, -1, 0, -1, -1); }
+
+ int Viewer(const char *aFileName, const char *aTitle,
+ int X1, int Y1, int X2, int Y2, DWORD aFlags)
+ { return m_Data.Viewer((char *)aFileName, (char *)aTitle, X1, Y1, X2, Y2, aFlags); }
+ int Viewer(const char *aFileName)
+ { return Viewer(aFileName, 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 *aMessage, int anCode);
+void PrintErrorMessage(const char *aMessage, const char *aText);
+
+#define MY_TRY_BEGIN try\
+ {
+
+#define MY_TRY_END1(x) }\
+ catch(int n)\
+ {\
+ PrintErrorMessage(x, n);\
+ return;\
+ }\
+ catch(const CSysString &aText)\
+ {\
+ PrintErrorMessage(x, aText);\
+ return;\
+ }\
+ catch(const char *aText)\
+ {\
+ PrintErrorMessage(x, aText);\
+ return;\
+ }\
+ catch(...)\
+ {\
+ g_StartupInfo.ShowMessage(x);\
+ return;\
+ }
+
+#define MY_TRY_END2(x, y) }\
+ catch(int n)\
+ {\
+ PrintErrorMessage(x, n);\
+ return y;\
+ }\
+ catch(const CSysString &aText)\
+ {\
+ PrintErrorMessage(x, aText);\
+ return y;\
+ }\
+ catch(const char *aText)\
+ {\
+ PrintErrorMessage(x, aText);\
+ return y;\
+ }\
+ catch(...)\
+ {\
+ g_StartupInfo.ShowMessage(x);\
+ return y;\
+ }
+
+bool WasEscPressed();
+
+void ShowErrorMessage(DWORD aError);
+void ShowLastErrorMessage();
+
+}
+
+#endif
diff --git a/Far/ProgressBox.cpp b/Far/ProgressBox.cpp
new file mode 100755
index 00000000..c37c7ad5
--- /dev/null
+++ b/Far/ProgressBox.cpp
@@ -0,0 +1,101 @@
+// ProgressBox.cpp
+
+#include "StdAfx.h"
+
+#include "ProgressBox.h"
+
+#include "FarUtils.h"
+
+using namespace NFar;
+
+static void CopySpaces(char *aString, int aNumSpaces)
+{
+ for(int i = 0; i < aNumSpaces; i++)
+ aString[i] = ' ';
+ aString[i] = '\0';
+}
+
+/////////////////////////////////
+// CMessageBox
+
+const int kNumStringsMax = 10;
+
+void CMessageBox::Init(const CSysString &aTitle, const CSysString &aMessage,
+ int aNumStrings, int aWidth)
+{
+ if (aNumStrings > kNumStringsMax)
+ throw 120620;
+ m_NumStrings = aNumStrings;
+ m_Width = aWidth;
+
+ m_Title = aTitle;
+ m_Message = aMessage;
+}
+
+const int kNumStaticStrings = 2;
+
+void CMessageBox::ShowProcessMessages(const char *aMessages[])
+{
+ const char *aMsgItems[kNumStaticStrings + kNumStringsMax];
+ aMsgItems[0] = m_Title;
+ aMsgItems[1] = m_Message;
+
+ char aFormattedMessages[kNumStringsMax][256];
+
+ for (int i = 0; i < m_NumStrings; i++)
+ {
+ char *aFormattedMessage = aFormattedMessages[i];
+ int aLen = strlen(aMessages[i]);
+ int aSize = MyMax(m_Width, aLen);
+ int aStartPos = (aSize - aLen) / 2;
+ CopySpaces(aFormattedMessage, aStartPos);
+ strcpy(aFormattedMessage + aStartPos, aMessages[i]);
+ CopySpaces(aFormattedMessage + aStartPos + aLen, aSize - aStartPos - aLen);
+ aMsgItems[kNumStaticStrings + i] = aFormattedMessage;
+ }
+
+ g_StartupInfo.ShowMessage(0, NULL, aMsgItems, kNumStaticStrings + m_NumStrings, 0);
+}
+
+/////////////////////////////////
+// CProgressBox
+
+void CProgressBox::Init(const CSysString &aTitle, const CSysString &aMessage,
+ UINT64 aStep)
+{
+ CMessageBox::Init(aTitle, aMessage, 1, 22);
+ m_Step = aStep;
+ m_CompletedPrev = 0;
+ m_Total = 0;
+}
+
+
+void CProgressBox::ShowProcessMessage(const char *aMessage)
+{
+ CMessageBox::ShowProcessMessages(&aMessage);
+}
+
+void CProgressBox::PrintPercent(UINT64 aPercent)
+{
+ char aValueBuffer[32];
+ sprintf(aValueBuffer, "%I64u%%", aPercent);
+ ShowProcessMessage(aValueBuffer);
+}
+
+void CProgressBox::SetTotal(UINT64 aTotal)
+{
+ m_Total = aTotal;
+}
+
+void CProgressBox::PrintCompeteValue(UINT64 aCompleted)
+{
+ if (aCompleted >= m_CompletedPrev + m_Step || aCompleted < m_CompletedPrev ||
+ aCompleted == 0)
+ {
+ if (m_Total == 0)
+ PrintPercent(0);
+ else
+ PrintPercent(aCompleted * 100 / m_Total);
+ m_CompletedPrev = aCompleted;
+ }
+}
diff --git a/Far/ProgressBox.h b/Far/ProgressBox.h
new file mode 100755
index 00000000..1878bc39
--- /dev/null
+++ b/Far/ProgressBox.h
@@ -0,0 +1,36 @@
+// ProgressBox.h
+
+#pragma once
+
+#ifndef __PROGRESSBOX_H
+#define __PROGRESSBOX_H
+
+#include "Common/String.h"
+
+class CMessageBox
+{
+ CSysString m_Title;
+ CSysString m_Message;
+ int m_NumStrings;
+ int m_Width;
+public:
+ void Init(const CSysString &aConvertingTitle,
+ const CSysString &aConvertingMessage, int aNumStrings, int aWidth);
+ void ShowProcessMessages(const char *aMessages[]);
+};
+
+class CProgressBox: public CMessageBox
+{
+ UINT64 m_Total;
+ UINT64 m_CompletedPrev;
+ UINT64 m_Step;
+public:
+ void Init(const CSysString &aConvertingTitle,
+ const CSysString &aConvertingMessage, UINT64 aStep);
+ void ShowProcessMessage(const char *aMessage);
+ void PrintPercent(UINT64 aPercent);
+ void PrintCompeteValue(UINT64 aCompleted);
+ void SetTotal(UINT64 aTotal);
+};
+
+#endif
diff --git a/Windows/COM.cpp b/Windows/COM.cpp
new file mode 100755
index 00000000..2f9fdcda
--- /dev/null
+++ b/Windows/COM.cpp
@@ -0,0 +1,37 @@
+// Windows/COM.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/COM.h"
+#include "Common/StringConvert.h"
+
+namespace NWindows {
+namespace NCOM {
+
+// CoInitialize (NULL); must be called!
+
+UString GUIDToStringW(REFGUID guid)
+{
+ UString string;
+ const int kStringSize = 48;
+ StringFromGUID2(guid, string.GetBuffer(kStringSize), kStringSize);
+ string.ReleaseBuffer();
+ return string;
+}
+
+AString GUIDToStringA(REFGUID guid)
+{
+ return UnicodeStringToMultiByte(GUIDToStringW(guid));
+}
+
+HRESULT StringToGUIDW(const wchar_t *string, GUID &classID)
+{
+ return CLSIDFromString((wchar_t *)string, &classID);
+}
+
+HRESULT StringToGUIDA(const char *string, GUID &classID)
+{
+ return StringToGUIDW(MultiByteToUnicodeString(string), classID);
+}
+
+}} \ No newline at end of file
diff --git a/Windows/COM.h b/Windows/COM.h
new file mode 100755
index 00000000..715d6875
--- /dev/null
+++ b/Windows/COM.h
@@ -0,0 +1,59 @@
+// Windows/COM.h
+
+#pragma once
+
+#ifndef __WINDOWS_COM_H
+#define __WINDOWS_COM_H
+
+#include "Common/String.h"
+
+namespace NWindows {
+namespace NCOM {
+
+class CComInitializer
+{
+public:
+ CComInitializer() { CoInitialize(NULL);};
+ ~CComInitializer() { CoUninitialize(); };
+};
+
+class CStgMedium
+{
+ STGMEDIUM _object;
+public:
+ bool _mustBeReleased;
+ CStgMedium(): _mustBeReleased(false) {}
+ ~CStgMedium() { Free(); }
+ void Free()
+ {
+ if(_mustBeReleased)
+ ReleaseStgMedium(&_object);
+ _mustBeReleased = false;
+ }
+ const STGMEDIUM* operator->() const { return &_object;}
+ STGMEDIUM* operator->() { return &_object;}
+ STGMEDIUM* operator&() { return &_object; }
+};
+
+//////////////////////////////////
+// GUID <--> String Conversions
+UString GUIDToStringW(REFGUID guid);
+AString GUIDToStringA(REFGUID guid);
+#ifdef UNICODE
+ #define GUIDToString GUIDToStringW
+#else
+ #define GUIDToString GUIDToStringA
+#endif // !UNICODE
+
+HRESULT StringToGUIDW(const wchar_t *string, GUID &classID);
+HRESULT StringToGUIDA(const char *string, GUID &classID);
+#ifdef UNICODE
+ #define StringToGUID StringToGUIDW
+#else
+ #define StringToGUID StringToGUIDA
+#endif // !UNICODE
+
+
+}}
+
+#endif
diff --git a/Windows/Console.cpp b/Windows/Console.cpp
new file mode 100755
index 00000000..1dffc377
--- /dev/null
+++ b/Windows/Console.cpp
@@ -0,0 +1,10 @@
+// Windows/Console.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/Console.h"
+
+namespace NWindows{
+namespace NConsole{
+
+}} \ No newline at end of file
diff --git a/Windows/Console.h b/Windows/Console.h
new file mode 100755
index 00000000..edd4e52c
--- /dev/null
+++ b/Windows/Console.h
@@ -0,0 +1,54 @@
+// Windows/Console.h
+
+#ifndef __WINDOWS_CONSOLE_H
+#define __WINDOWS_CONSOLE_H
+
+#pragma once
+
+#include "Windows/Defs.h"
+
+namespace NWindows{
+namespace NConsole{
+
+class CBase
+{
+protected:
+ HANDLE m_Object;
+public:
+ void Attach(HANDLE aHandle) { m_Object = aHandle; };
+ bool GetMode(DWORD &aMode)
+ { return BOOLToBool(::GetConsoleMode(m_Object, &aMode)); }
+ bool SetMode(DWORD aMode)
+ { return BOOLToBool(::SetConsoleMode(m_Object, aMode)); }
+};
+
+class CIn: public CBase
+{
+public:
+ bool PeekEvents(PINPUT_RECORD anEvents, DWORD aNumEvents, DWORD &aNumEventsRead)
+ { return BOOLToBool(::PeekConsoleInput(m_Object, anEvents, aNumEvents, &aNumEventsRead)); }
+ bool PeekEvent(INPUT_RECORD &anEvent, DWORD &aNumEventsRead)
+ { return PeekEvents(&anEvent, 1, aNumEventsRead); }
+ bool ReadEvents(PINPUT_RECORD anEvents, DWORD aNumEvents, DWORD &aNumEventsRead)
+ { return BOOLToBool(::ReadConsoleInput(m_Object, anEvents, aNumEvents, &aNumEventsRead)); }
+ bool ReadEvent(INPUT_RECORD &anEvent, DWORD &aNumEventsRead)
+ { return ReadEvents(&anEvent, 1, aNumEventsRead); }
+ bool GetNumberOfEvents(DWORD &aNumberOfEvents)
+ { return BOOLToBool(::GetNumberOfConsoleInputEvents(m_Object, &aNumberOfEvents)); }
+
+ bool WriteEvents(const INPUT_RECORD *anEvents, DWORD aNumEvents, DWORD &aNumEventsWritten)
+ { return BOOLToBool(::WriteConsoleInput(m_Object, anEvents, aNumEvents, &aNumEventsWritten)); }
+ bool WriteEvent(const INPUT_RECORD &anEvent, DWORD &aNumEventsWritten)
+ { return WriteEvents(&anEvent, 1, aNumEventsWritten); }
+
+ bool Read(LPVOID aBuffer, DWORD aNumberOfCharsToRead, DWORD &aNumberOfCharsRead)
+ { return BOOLToBool(::ReadConsole(m_Object, aBuffer, aNumberOfCharsToRead, &aNumberOfCharsRead, NULL)); }
+
+ bool Flush()
+ { return BOOLToBool(::FlushConsoleInputBuffer(m_Object)); }
+
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/Windows/Control/ComboBox.cpp b/Windows/Control/ComboBox.cpp
new file mode 100755
index 00000000..edef3a21
--- /dev/null
+++ b/Windows/Control/ComboBox.cpp
@@ -0,0 +1,23 @@
+// Windows/Control/ComboBox.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/Control/ComboBox.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+int CComboBox::GetLBText(int index, CSysString &string)
+{
+ string.Empty();
+ int aLength = GetLBTextLen(index);
+ if (aLength == CB_ERR)
+ return aLength;
+ aLength = GetLBText(index, string.GetBuffer(aLength));
+ string.ReleaseBuffer();
+ return aLength;
+}
+
+
+}}
diff --git a/Windows/Control/ComboBox.h b/Windows/Control/ComboBox.h
new file mode 100755
index 00000000..864dbfbc
--- /dev/null
+++ b/Windows/Control/ComboBox.h
@@ -0,0 +1,55 @@
+// Windows/Control/ComboBox.h
+
+#pragma once
+
+#ifndef __WINDOWS_CONTROL_COMBOBOX_H
+#define __WINDOWS_CONTROL_COMBOBOX_H
+
+#include "Windows/Window.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CComboBox: public CWindow
+{
+public:
+ void ResetContent()
+ { SendMessage(CB_RESETCONTENT, 0, 0); }
+ int AddString(LPCTSTR string)
+ { return SendMessage(CB_ADDSTRING, 0, (LPARAM)string); }
+ int SetCurSel(int index)
+ { return SendMessage(CB_SETCURSEL, index, 0); }
+ int GetCurSel()
+ { return SendMessage(CB_GETCURSEL, 0, 0); }
+ int GetCount()
+ { return SendMessage(CB_GETCOUNT, 0, 0); }
+
+ int GetLBTextLen(int index)
+ { return SendMessage(CB_GETLBTEXTLEN, index, 0); }
+ int GetLBText(int index, LPTSTR string)
+ { return SendMessage(CB_GETLBTEXT, index, (LPARAM)string); }
+ int GetLBText(int index, CSysString &string);
+
+ int SetItemData(int index, LPARAM lParam)
+ { return SendMessage(CB_SETITEMDATA, index, lParam); }
+ int GetItemData(int index)
+ { return SendMessage(CB_GETITEMDATA, index, 0); }
+};
+
+class CComboBoxEx: public CWindow
+{
+public:
+ int DeleteItem(int index)
+ { return SendMessage(CBEM_DELETEITEM, index, 0); }
+ int InsertItem(COMBOBOXEXITEM *item)
+ { return SendMessage(CBEM_INSERTITEM, 0, (LPARAM)item); }
+ DWORD SetExtendedStyle(DWORD exMask, DWORD exStyle)
+ { return SendMessage(CBEM_SETEXTENDEDSTYLE, exMask, exStyle); }
+ HWND GetEditControl()
+ { return (HWND)SendMessage(CBEM_GETEDITCONTROL, 0, 0); }
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/Windows/Control/Dialog.cpp b/Windows/Control/Dialog.cpp
new file mode 100755
index 00000000..e911850c
--- /dev/null
+++ b/Windows/Control/Dialog.cpp
@@ -0,0 +1,106 @@
+// Windows/Control/Dialog.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/Control/Dialog.h"
+
+extern HINSTANCE g_hInstance;
+
+namespace NWindows {
+namespace NControl {
+
+BOOL APIENTRY DialogProcedure(HWND dialogHWND, UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+ CWindow aDialogTmp(dialogHWND);
+ if (message == WM_INITDIALOG)
+ aDialogTmp.SetUserDataLongPtr(lParam);
+ CDialog *aDialog = (CDialog *)(aDialogTmp.GetUserDataLongPtr());
+ if (aDialog == NULL)
+ return FALSE;
+ if (message == WM_INITDIALOG)
+ aDialog->Attach(dialogHWND);
+
+ return BoolToBOOL(aDialog->OnMessage(message, wParam, lParam));
+}
+
+bool CDialog::OnMessage(UINT message, UINT wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ return OnInit();
+ case WM_COMMAND:
+ return OnCommand(wParam, lParam);
+ case WM_NOTIFY:
+ return OnNotify(wParam, (LPNMHDR) lParam);
+ case WM_HELP:
+ {
+ OnHelp((LPHELPINFO)lParam);
+ return true;
+ }
+ case WM_TIMER:
+ {
+ return OnTimer(wParam, lParam);
+ }
+ default:
+ return false;
+ }
+}
+
+bool CDialog::OnCommand(WPARAM wParam, LPARAM lParam)
+{
+ return OnCommand(HIWORD(wParam), LOWORD(wParam), lParam);
+}
+
+bool CDialog::OnCommand(int code, int itemID, LPARAM lParam)
+{
+ if (code == BN_CLICKED)
+ return OnButtonClicked(itemID, (HWND)lParam);
+ return false;
+}
+
+bool CDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch(buttonID)
+ {
+ case IDOK:
+ OnOK();
+ break;
+ case IDCANCEL:
+ OnCancel();
+ break;
+ case IDHELP:
+ OnHelp();
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+bool CModelessDialog::Create(LPCTSTR templateName, HWND parentWindow)
+{
+ HWND aHWND = CreateDialogParam(g_hInstance,
+ templateName, parentWindow, DialogProcedure, LPARAM(this));
+ if (aHWND == 0)
+ return false;
+ Attach(aHWND);
+ return true;
+}
+
+INT_PTR CModalDialog::Create(LPCTSTR templateName, HWND parentWindow)
+{
+ return DialogBoxParam(g_hInstance,
+ templateName, parentWindow, DialogProcedure, LPARAM(this));
+}
+
+/*
+INT_PTR CModalDialog::Create(LPCWSTR templateName, HWND parentWindow)
+{
+ return DialogBoxParamW(g_hInstance,
+ templateName, parentWindow, DialogProcedure, LPARAM(this));
+}
+*/
+
+}}
diff --git a/Windows/Control/Dialog.h b/Windows/Control/Dialog.h
new file mode 100755
index 00000000..e59cf4b3
--- /dev/null
+++ b/Windows/Control/Dialog.h
@@ -0,0 +1,137 @@
+// Windows/Control/Dialog.h
+
+#pragma once
+
+#ifndef __WINDOWS_CONTROL_DIALOG_H
+#define __WINDOWS_CONTROL_DIALOG_H
+
+#include "Windows/Window.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+BOOL APIENTRY DialogProcedure(HWND dialogHWND, UINT message, UINT wParam, LPARAM lParam);
+
+class CDialog: public CWindow
+{
+public:
+ CDialog(HWND wndow = NULL): CWindow(wndow){};
+ virtual ~CDialog() {};
+
+ HWND GetItem(int itemID) const
+ { return GetDlgItem(_window, itemID); }
+
+ bool EnableItem(int itemID, bool enable) const
+ { return BOOLToBool(::EnableWindow(GetItem(itemID), BoolToBOOL(enable))); }
+
+ bool SetItemText(int itemID, LPCTSTR s)
+ { return BOOLToBool(SetDlgItemText(_window, itemID, s)); }
+
+ #ifndef _UNICODE
+ bool SetItemText(int itemID, LPCWSTR s)
+ {
+ CWindow window(GetItem(itemID));
+ return window.SetText(s);
+ }
+ #endif
+
+ UINT GetItemText(int itemID, LPTSTR string, int maxCount)
+ { return GetDlgItemText(_window, itemID, string, maxCount); }
+ #ifndef _UNICODE
+ /*
+ bool GetItemText(int itemID, LPWSTR string, int maxCount)
+ {
+ CWindow window(GetItem(itemID));
+ return window.GetText(string, maxCount);
+ }
+ */
+ #endif
+
+ bool SetItemInt(int itemID, UINT value, bool isSigned)
+ { return BOOLToBool(SetDlgItemInt(_window, itemID, value, BoolToBOOL(isSigned))); }
+ bool GetItemInt(int itemID, bool isSigned, UINT &value)
+ {
+ BOOL result;
+ value = GetDlgItemInt(_window, itemID, &result, BoolToBOOL(isSigned));
+ return BOOLToBool(result);
+ }
+
+ HWND GetNextGroupItem(HWND control, bool previous)
+ { return GetNextDlgGroupItem(_window, control, BoolToBOOL(previous)); }
+ HWND GetNextTabItem(HWND control, bool previous)
+ { return GetNextDlgTabItem(_window, control, BoolToBOOL(previous)); }
+
+ bool MapRect(LPRECT rect)
+ { return BOOLToBool(MapDialogRect(_window, rect)); }
+
+ bool IsMessage(LPMSG message)
+ { return BOOLToBool(IsDialogMessage(_window, message)); }
+
+ LRESULT SendItemMessage(int itemID, UINT message, WPARAM wParam, LPARAM lParam)
+ { return SendDlgItemMessage(_window, itemID, message, wParam, lParam); }
+
+ bool CheckButton(int buttonID, UINT checkState)
+ { return BOOLToBool(CheckDlgButton(_window, buttonID, checkState)); }
+ bool CheckButton(int buttonID, bool checkState)
+ { return CheckButton(buttonID, UINT(checkState ? BST_CHECKED : BST_UNCHECKED)); }
+
+ UINT IsButtonChecked(int buttonID) const
+ { return IsDlgButtonChecked(_window, buttonID); }
+ bool IsButtonCheckedBool(int buttonID) const
+ { return (IsButtonChecked(buttonID) == BST_CHECKED); }
+
+ bool CheckRadioButton(int firstButtonID, int lastButtonID, int checkButtonID)
+ { return BOOLToBool(::CheckRadioButton(_window, firstButtonID, lastButtonID, checkButtonID)); }
+
+ virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+ virtual bool OnInit() { return true; }
+ virtual bool OnCommand(WPARAM wParam, LPARAM lParam);
+ virtual bool OnCommand(int code, int itemID, LPARAM lParam);
+ virtual void OnHelp(LPHELPINFO helpInfo) { OnHelp(); };
+ virtual void OnHelp() {};
+ virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
+ virtual void OnOK() {};
+ virtual void OnCancel() {};
+ virtual bool OnNotify(UINT controlID, LPNMHDR lParam) { return false; }
+ virtual bool OnTimer(WPARAM timerID, LPARAM callback) { return false; }
+
+ LONG_PTR SetMsgResult(LONG_PTR newLongPtr )
+ { return SetLongPtr(DWLP_MSGRESULT, newLongPtr); }
+ LONG_PTR GetMsgResult() const
+ { return GetLongPtr(DWLP_MSGRESULT); }
+};
+
+class CModelessDialog: public CDialog
+{
+public:
+ bool Create(LPCTSTR templateName, HWND parentWindow);
+ virtual void OnOK() { Destroy(); }
+ virtual void OnCancel() { Destroy(); }
+};
+
+class CModalDialog: public CDialog
+{
+public:
+ INT_PTR Create(LPCTSTR templateName, HWND parentWindow);
+ // INT_PTR Create(LPCWSTR templateName, HWND parentWindow);
+ bool End(INT_PTR result)
+ { return BOOLToBool(::EndDialog(_window, result)); }
+ virtual void OnOK() { End(IDOK); }
+ virtual void OnCancel() { End(IDCANCEL); }
+};
+
+class CDialogChildControl: public NWindows::CWindow
+{
+public:
+ int m_ID;
+ void Init(const NWindows::NControl::CDialog &parentDialog, int id)
+ {
+ m_ID = id;
+ Attach(parentDialog.GetItem(id));
+ }
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/Windows/Control/Edit.h b/Windows/Control/Edit.h
new file mode 100755
index 00000000..a7c7bb99
--- /dev/null
+++ b/Windows/Control/Edit.h
@@ -0,0 +1,23 @@
+// Windows/Control/Edit.h
+
+#pragma once
+
+#ifndef __WINDOWS_CONTROL_EDIT_H
+#define __WINDOWS_CONTROL_EDIT_H
+
+#include "Windows/Window.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CEdit: public CWindow
+{
+public:
+ void SetPasswordChar(WPARAM c)
+ { SendMessage(EM_SETPASSWORDCHAR, c); }
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/Windows/Control/ImageList.cpp b/Windows/Control/ImageList.cpp
new file mode 100755
index 00000000..16a46fa4
--- /dev/null
+++ b/Windows/Control/ImageList.cpp
@@ -0,0 +1,11 @@
+// Windows/Control/ImageList.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/Control/ImageList.h"
+
+namespace NWindows {
+namespace NControl {
+
+}}
+
diff --git a/Windows/Control/ImageList.h b/Windows/Control/ImageList.h
new file mode 100755
index 00000000..26a3f25c
--- /dev/null
+++ b/Windows/Control/ImageList.h
@@ -0,0 +1,88 @@
+// Windows/Control/ImageList.h
+
+#pragma once
+
+#ifndef __WINDOWS_CONTROL_IMAGELIST_H
+#define __WINDOWS_CONTROL_IMAGELIST_H
+
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CImageList
+{
+ HIMAGELIST m_Object;
+public:
+ operator HIMAGELIST() const {return m_Object; }
+ CImageList(): m_Object(NULL) {}
+ bool Attach(HIMAGELIST imageList)
+ {
+ if(imageList == NULL)
+ return false;
+ m_Object = imageList;
+ return true;
+ }
+
+ HIMAGELIST Detach()
+ {
+ HIMAGELIST imageList = m_Object;
+ m_Object = NULL;
+ return imageList;
+ }
+
+ bool Create(int width, int height, UINT flags, int initialNumber, int grow)
+ {
+ HIMAGELIST a = ImageList_Create(width, height, flags,
+ initialNumber, grow);
+ if(a == NULL)
+ return false;
+ return Attach(a);
+ }
+
+ bool Destroy() // DeleteImageList() in MFC
+ {
+ if (m_Object == NULL)
+ return false;
+ return BOOLToBool(ImageList_Destroy(Detach()));
+ }
+
+ ~CImageList()
+ { Destroy(); }
+
+ int GetImageCount() const
+ { return ImageList_GetImageCount(m_Object); }
+
+ bool GetImageInfo(int index, IMAGEINFO* imageInfo) const
+ { return BOOLToBool(ImageList_GetImageInfo(m_Object, index, imageInfo)); }
+
+ int Add(HBITMAP hbmImage, HBITMAP hbmMask = 0)
+ { return ImageList_Add(m_Object, hbmImage, hbmMask); }
+ int AddMasked(HBITMAP hbmImage, COLORREF mask)
+ { return ImageList_AddMasked(m_Object, hbmImage, mask); }
+ int AddIcon(HICON icon)
+ { return ImageList_AddIcon(m_Object, icon); }
+ int Replace(int index, HICON icon)
+ { return ImageList_ReplaceIcon(m_Object, index, icon); }
+
+ // If index is -1, the function removes all images.
+ bool Remove(int index)
+ { return BOOLToBool(ImageList_Remove(m_Object, index)); }
+ bool RemoveAll()
+ { return BOOLToBool(ImageList_RemoveAll(m_Object)); }
+
+ HICON ExtractIcon(int index)
+ { return ImageList_ExtractIcon(NULL, m_Object, index); }
+ HICON GetIcon(int index, UINT flags)
+ { return ImageList_GetIcon(m_Object, index, flags); }
+
+ bool GetIconSize(int &width, int &height) const
+ { return BOOLToBool(ImageList_GetIconSize(m_Object, &width, &height)); }
+ bool SetIconSize(int width, int height)
+ { return BOOLToBool(ImageList_SetIconSize(m_Object, width, height)); }
+};
+
+}}
+
+#endif
+ \ No newline at end of file
diff --git a/Windows/Control/ListView.cpp b/Windows/Control/ListView.cpp
new file mode 100755
index 00000000..b532a7a4
--- /dev/null
+++ b/Windows/Control/ListView.cpp
@@ -0,0 +1,58 @@
+// Windows/Control/ListView.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/Control/ListView.h"
+
+namespace NWindows {
+namespace NControl {
+
+bool CListView::CreateEx(DWORD exStyle, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam)
+{
+ return CWindow::CreateEx(exStyle, WC_LISTVIEW, TEXT(""), style, x, y, width,
+ height, parentWindow, idOrHMenu, instance, createParam);
+}
+
+bool CListView::GetItemParam(int itemIndex, LPARAM &param) const
+{
+ LVITEM item;
+ item.iItem = itemIndex;
+ item.iSubItem = 0;
+ item.mask = LVIF_PARAM;
+ bool aResult = GetItem(&item);
+ param = item.lParam;
+ return aResult;
+}
+
+/*
+int CListView::InsertItem(UINT mask, int item, LPCTSTR itemText,
+ UINT nState, UINT nStateMask, int nImage, LPARAM lParam)
+{
+ LVITEM item;
+ item.mask = nMask;
+ item.iItem = nItem;
+ item.iSubItem = 0;
+ item.pszText = (LPTSTR)itemText;
+ item.state = nState;
+ item.stateMask = nStateMask;
+ item.iImage = nImage;
+ item.lParam = lParam;
+ return InsertItem(&item);
+}
+
+int CListView::InsertItem(int nItem, LPCTSTR itemText)
+{
+ return InsertItem(LVIF_TEXT, nItem, itemText, 0, 0, 0, 0);
+}
+
+int CListView::InsertItem(int nItem, LPCTSTR itemText, int nImage)
+{
+ return InsertItem(LVIF_TEXT | LVIF_IMAGE, nItem, itemText, 0, 0, nImage, 0);
+}
+*/
+
+}}
+
diff --git a/Windows/Control/ListView.h b/Windows/Control/ListView.h
new file mode 100755
index 00000000..6f446884
--- /dev/null
+++ b/Windows/Control/ListView.h
@@ -0,0 +1,121 @@
+// Windows/Control/ListView.h
+
+#pragma once
+
+#ifndef __WINDOWS_CONTROL_LISTVIEW_H
+#define __WINDOWS_CONTROL_LISTVIEW_H
+
+#include "Windows/Window.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CListView: public NWindows::CWindow
+{
+public:
+ bool CreateEx(DWORD exStyle, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam);
+
+ bool DeleteAllItems()
+ { return BOOLToBool(ListView_DeleteAllItems(_window)); }
+ int InsertColumn(int columnIndex, const LVCOLUMN *columnInfo)
+ { return ListView_InsertColumn(_window, columnIndex, columnInfo); }
+ bool DeleteColumn(int columnIndex)
+ { return BOOLToBool(ListView_DeleteColumn(_window, columnIndex)); }
+
+ int InsertItem(const LVITEM* item)
+ { return ListView_InsertItem(_window, item); }
+ bool SetItem(const LVITEM* item)
+ { return BOOLToBool(ListView_SetItem(_window, item)); }
+ bool DeleteItem(int itemIndex)
+ { return BOOLToBool(ListView_DeleteItem(_window, itemIndex)); }
+
+ UINT GetSelectedCount() const
+ { return ListView_GetSelectedCount(_window); }
+ int GetItemCount() const
+ { return ListView_GetItemCount(_window); }
+
+ INT GetSelectionMark()
+ { return ListView_GetSelectionMark(_window); }
+
+ void SetItemCount(int numItems)
+ { ListView_SetItemCount(_window, numItems); }
+ void SetItemCountEx(int numItems, DWORD flags)
+ { ListView_SetItemCountEx(_window, numItems, flags); }
+
+ int GetNextItem(int startIndex, UINT flags) const
+ { return ListView_GetNextItem(_window, startIndex, flags); }
+ int GetNextSelectedItem(int startIndex) const
+ { return GetNextItem(startIndex, LVNI_SELECTED); }
+ int GetFocusedItem() const
+ { return GetNextItem(-1, LVNI_FOCUSED); }
+
+ bool GetItem(LVITEM* item) const
+ { return BOOLToBool(ListView_GetItem(_window, item)); }
+ bool GetItemParam(int itemIndex, LPARAM &param) const;
+ void GetItemText(int itemIndex, int aSubItemIndex, LPTSTR aText, int aTextSizeMax) const
+ { ListView_GetItemText(_window, itemIndex, aSubItemIndex, aText, aTextSizeMax); }
+ bool SortItems(PFNLVCOMPARE compareFunction, LPARAM dataParam)
+ { return BOOLToBool(ListView_SortItems(_window, compareFunction, dataParam)); }
+
+ void SetItemState(int index, UINT state, UINT mask)
+ { ListView_SetItemState(_window, index, state, mask); }
+ UINT GetItemState(int index, UINT mask)
+ { return ListView_GetItemState(_window, index, mask); }
+
+ bool GetColumn(int columnIndex, LVCOLUMN* columnInfo) const
+ { return BOOLToBool(ListView_GetColumn(_window, columnIndex, columnInfo)); }
+
+ HIMAGELIST SetImageList(HIMAGELIST imageList, int imageListType)
+ { return ListView_SetImageList(_window, imageList, imageListType); }
+
+ // version 4.70: NT5 | (NT4 + ie3) | w98 | (w95 + ie3)
+ DWORD GetExtendedListViewStyle()
+ { return ListView_GetExtendedListViewStyle(_window); }
+ void SetExtendedListViewStyle(DWORD exStyle)
+ { ListView_SetExtendedListViewStyle(_window, exStyle); }
+ void SetExtendedListViewStyle(DWORD exMask, DWORD exStyle)
+ { ListView_SetExtendedListViewStyleEx(_window, exMask, exStyle); }
+
+ #ifndef _WIN32_WCE
+ void SetCheckState(UINT index, bool checkState)
+ { ListView_SetCheckState(_window, index, BoolToBOOL(checkState)); }
+ #endif
+ bool GetCheckState(UINT index)
+ { return BOOLToBool(ListView_GetCheckState(_window, index)); }
+
+
+ bool EnsureVisible(int index, bool partialOK)
+ { return BOOLToBool(ListView_EnsureVisible(_window, index, BoolToBOOL(partialOK))); }
+
+ bool GetItemRect(int index, RECT *rect, int code)
+ { return BOOLToBool(ListView_GetItemRect(_window, index, rect, code)); }
+
+ HWND GetEditControl()
+ { return ListView_GetEditControl(_window) ; }
+ HWND EditLabel(int itemIndex)
+ { return ListView_EditLabel(_window, itemIndex) ; }
+
+ bool RedrawItems(int firstIndex, int lastIndex)
+ { return BOOLToBool(ListView_RedrawItems(_window, firstIndex, lastIndex)); }
+ bool RedrawAllItems()
+ {
+ if (GetItemCount() > 0)
+ return RedrawItems(0, GetItemCount() - 1);
+ return true;
+ }
+ bool RedrawItem(int index)
+ { return RedrawItems(index, index); }
+
+ int HitTest(LPLVHITTESTINFO info)
+ { return ListView_HitTest(_window, info); }
+
+ COLORREF GetBkColor()
+ { return ListView_GetBkColor(_window); }
+};
+
+}}
+#endif \ No newline at end of file
diff --git a/Windows/Control/ProgressBar.h b/Windows/Control/ProgressBar.h
new file mode 100755
index 00000000..0785eba1
--- /dev/null
+++ b/Windows/Control/ProgressBar.h
@@ -0,0 +1,43 @@
+// Windows/Control/ProgressBar.h
+
+#pragma once
+
+#ifndef __WINDOWS_CONTROL_PROGRESSBAR_H
+#define __WINDOWS_CONTROL_PROGRESSBAR_H
+
+#include "Windows/Window.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CProgressBar: public CWindow
+{
+public:
+ LRESULT SetPos(int pos)
+ { return SendMessage(PBM_SETPOS, pos, 0); }
+ LRESULT DeltaPos(int increment)
+ { return SendMessage(PBM_DELTAPOS, increment, 0); }
+ UINT GetPos()
+ { return SendMessage(PBM_GETPOS, 0, 0); }
+ LRESULT SetRange(unsigned short minValue, unsigned short maxValue)
+ { return SendMessage(PBM_SETRANGE, 0, MAKELPARAM(minValue, maxValue)); }
+ DWORD SetRange32(int minValue, int maxValue)
+ { return SendMessage(PBM_SETRANGE32, minValue, maxValue); }
+ int SetStep(int aStep)
+ { return SendMessage(PBM_SETSTEP, aStep, 0); }
+ int StepIt()
+ { return SendMessage(PBM_STEPIT, 0, 0); }
+
+ int GetRange(bool minValue, PPBRANGE range)
+ { return SendMessage(PBM_GETRANGE, BoolToBOOL(minValue), (LPARAM)range); }
+
+ COLORREF SetBarColor(COLORREF color)
+ { return SendMessage(PBM_SETBARCOLOR, 0, color); }
+ COLORREF SetBackgroundColor(COLORREF color)
+ { return SendMessage(PBM_SETBKCOLOR, 0, color); }
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/Windows/Control/PropertyPage.cpp b/Windows/Control/PropertyPage.cpp
new file mode 100755
index 00000000..24085511
--- /dev/null
+++ b/Windows/Control/PropertyPage.cpp
@@ -0,0 +1,59 @@
+// Windows/Control/PropertyPage.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/Control/PropertyPage.h"
+
+namespace NWindows {
+namespace NControl {
+
+BOOL APIENTRY ProperyPageProcedure(HWND dialogHWND, UINT message,
+ UINT wParam, LONG lParam)
+{
+ CDialog tempDialog(dialogHWND);
+ if (message == WM_INITDIALOG)
+ tempDialog.SetUserDataLongPtr(((PROPSHEETPAGE *)lParam)->lParam);
+ CDialog *dialog = (CDialog *)(tempDialog.GetUserDataLongPtr());
+ if (message == WM_INITDIALOG)
+ dialog->Attach(dialogHWND);
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ return dialog->OnInit();
+ case WM_COMMAND:
+ return dialog->OnCommand(wParam, lParam);
+ case WM_NOTIFY:
+ return dialog->OnNotify(wParam, (LPNMHDR) lParam);
+ }
+ if (dialog == NULL)
+ return false;
+ return dialog->OnMessage(message, wParam, lParam);
+}
+
+bool CPropertyPage::OnNotify(UINT controlID, LPNMHDR lParam)
+{
+ switch(lParam->code)
+ {
+ case PSN_APPLY:
+ SetMsgResult(OnApply(LPPSHNOTIFY(lParam)));
+ break;
+ case PSN_KILLACTIVE:
+ SetMsgResult(BoolToBOOL(OnKillActive(LPPSHNOTIFY(lParam))));
+ break;
+ case PSN_SETACTIVE:
+ SetMsgResult(OnSetActive(LPPSHNOTIFY(lParam)));
+ break;
+ case PSN_RESET:
+ OnReset(LPPSHNOTIFY(lParam));
+ break;
+ case PSN_HELP:
+ OnNotifyHelp(LPPSHNOTIFY(lParam));
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+
+}}
diff --git a/Windows/Control/PropertyPage.h b/Windows/Control/PropertyPage.h
new file mode 100755
index 00000000..2f7b4e82
--- /dev/null
+++ b/Windows/Control/PropertyPage.h
@@ -0,0 +1,41 @@
+// Windows/Control/PropertyPage.h
+
+#pragma once
+
+#ifndef __WINDOWS_CONTROL_PROPERTYPAGE_H
+#define __WINDOWS_CONTROL_PROPERTYPAGE_H
+
+#include "Windows/Control/Dialog.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+BOOL APIENTRY ProperyPageProcedure(HWND dialogHWND, UINT message, UINT wParam, LONG lParam);
+
+class CPropertyPage: public CDialog
+{
+public:
+ CPropertyPage(HWND window = NULL): CDialog(window){};
+
+ void Changed() { PropSheet_Changed(GetParent(), HWND(*this)); }
+ void UnChanged() { PropSheet_UnChanged(GetParent(), HWND(*this)); }
+
+ virtual bool OnNotify(UINT controlID, LPNMHDR lParam);
+
+ virtual bool OnKillActive() { return false; } // false = OK
+ virtual bool OnKillActive(const PSHNOTIFY *aPSHNOTIFY) { return OnKillActive(); }
+ virtual LONG OnSetActive() { return false; } // false = OK
+ virtual LONG OnSetActive(const PSHNOTIFY *aPSHNOTIFY) { return OnKillActive(); }
+ virtual LONG OnApply() { return PSNRET_NOERROR; }
+ virtual LONG OnApply(const PSHNOTIFY *aPSHNOTIFY) { return OnApply(); }
+ virtual void OnNotifyHelp() { }
+ virtual void OnNotifyHelp(const PSHNOTIFY *aPSHNOTIFY) { OnNotifyHelp(); }
+ virtual void OnReset() { }
+ virtual void OnReset(const PSHNOTIFY *aPSHNOTIFY) { OnReset(); }
+};
+
+
+}}
+
+#endif
diff --git a/Windows/Control/ReBar.h b/Windows/Control/ReBar.h
new file mode 100755
index 00000000..6dfb3b4e
--- /dev/null
+++ b/Windows/Control/ReBar.h
@@ -0,0 +1,37 @@
+// Windows/Control/ReBar.h
+
+#pragma once
+
+#ifndef __WINDOWS_CONTROL_REBAR_H
+#define __WINDOWS_CONTROL_REBAR_H
+
+#include "Windows/Window.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CReBar: public NWindows::CWindow
+{
+public:
+ bool SetBarInfo(LPREBARINFO barInfo)
+ { return BOOLToBool(SendMessage(RB_SETBARINFO, 0, (LPARAM)barInfo)); }
+ bool InsertBand(int index, LPREBARBANDINFO bandInfo)
+ { return BOOLToBool(SendMessage(RB_INSERTBAND, index, (LPARAM)bandInfo)); }
+ bool SetBandInfo(int index, LPREBARBANDINFO bandInfo)
+ { return BOOLToBool(SendMessage(RB_SETBANDINFO, index, (LPARAM)bandInfo)); }
+ void MaximizeBand(int index, bool ideal)
+ { SendMessage(RB_MAXIMIZEBAND, index, BoolToBOOL(ideal)); }
+ bool SizeToRect(LPRECT rect)
+ { return BOOLToBool(SendMessage(RB_SIZETORECT, 0, (LPARAM)rect)); }
+ UINT GetHeight()
+ { return SendMessage(RB_GETBARHEIGHT); }
+ UINT GetBandCount()
+ { return SendMessage(RB_GETBANDCOUNT); }
+ bool DeleteBand(UINT index)
+ { return BOOLToBool(SendMessage(RB_DELETEBAND, index)); }
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/Windows/Control/Static.h b/Windows/Control/Static.h
new file mode 100755
index 00000000..ba8a3a72
--- /dev/null
+++ b/Windows/Control/Static.h
@@ -0,0 +1,29 @@
+// Windows/Control/Static.h
+
+#pragma once
+
+#ifndef __WINDOWS_CONTROL_STATIC_H
+#define __WINDOWS_CONTROL_STATIC_H
+
+#include "Windows/Window.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CStatic: public CWindow
+{
+public:
+ HICON SetIcon(HICON icon)
+ { return (HICON)SendMessage(STM_SETICON, (WPARAM)icon, 0); }
+ HICON GetIcon()
+ { return (HICON)SendMessage(STM_GETICON, 0, 0); }
+ HANDLE SetImage(WPARAM imageType, HANDLE handle)
+ { return (HANDLE)SendMessage(STM_SETIMAGE, imageType, (LPARAM)handle); }
+ HANDLE GetImage(WPARAM imageType)
+ { return (HANDLE)SendMessage(STM_GETIMAGE, imageType, 0); }
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/Windows/Control/StatusBar.h b/Windows/Control/StatusBar.h
new file mode 100755
index 00000000..fa277259
--- /dev/null
+++ b/Windows/Control/StatusBar.h
@@ -0,0 +1,33 @@
+// Windows/Control/StatusBar.h
+
+#pragma once
+
+#ifndef __WINDOWS_CONTROL_STATUSBAR_H
+#define __WINDOWS_CONTROL_STATUSBAR_H
+
+#include "Windows/Window.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CStatusBar: public NWindows::CWindow
+{
+public:
+ bool Create(LONG style, LPCTSTR text, HWND hwndParent, UINT id)
+ { return (_window = ::CreateStatusWindow(style, text, hwndParent, id)) != 0; }
+ bool SetParts(int numParts, const int *edgePostions)
+ { return BOOLToBool(SendMessage(SB_SETPARTS, numParts, (LPARAM)edgePostions)); }
+ bool SetText(LPCTSTR text)
+ { return CWindow::SetText(text); }
+ bool SetText(int index, LPCTSTR text, UINT type)
+ { return BOOLToBool(SendMessage(SB_SETTEXT, index | type, (LPARAM)text)); }
+ bool SetText(int index, LPCTSTR text)
+ { return SetText(index, text, 0); }
+ void Simple(bool simple)
+ { SendMessage(SB_SIMPLE, BoolToBOOL(simple), 0); }
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/Windows/Control/ToolBar.h b/Windows/Control/ToolBar.h
new file mode 100755
index 00000000..22d72377
--- /dev/null
+++ b/Windows/Control/ToolBar.h
@@ -0,0 +1,32 @@
+// Windows/Control/ToolBar.h
+
+#pragma once
+
+#ifndef __WINDOWS_CONTROL_TOOLBAR_H
+#define __WINDOWS_CONTROL_TOOLBAR_H
+
+#include "Windows/Window.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CToolBar: public NWindows::CWindow
+{
+public:
+ bool GetMaxSize(LPSIZE size)
+ { return BOOLToBool(SendMessage(TB_GETMAXSIZE, 0, (LPARAM)size)); }
+ bool EnableButton(UINT buttonID, bool enable)
+ { return BOOLToBool(SendMessage(TB_ENABLEBUTTON, buttonID,
+ MAKELONG(BoolToBOOL(enable), 0))); }
+ void ButtonStructSize()
+ { SendMessage(TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON)); }
+ HIMAGELIST SetImageList(UINT listIndex, HIMAGELIST imageList)
+ { return HIMAGELIST(SendMessage(TB_SETIMAGELIST, listIndex, (LPARAM)imageList)); }
+ bool AddButton(UINT numButtons, LPTBBUTTON buttons)
+ { return BOOLToBool(SendMessage(TB_ADDBUTTONS, numButtons, (LPARAM)buttons)); }
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/Windows/Control/Trackbar.h b/Windows/Control/Trackbar.h
new file mode 100755
index 00000000..8f1b46ee
--- /dev/null
+++ b/Windows/Control/Trackbar.h
@@ -0,0 +1,30 @@
+// Windows/Control/Trackbar.h
+
+#pragma once
+
+#ifndef __WINDOWS_CONTROL_TRACKBAR_H
+#define __WINDOWS_CONTROL_TRACKBAR_H
+
+#include "Windows/Window.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CTrackbar: public CWindow
+{
+public:
+ void SetRange(int minimum, int maximum, bool redraw = true)
+ { SendMessage(TBM_SETRANGE, BoolToBOOL(redraw), MAKELONG(minimum, maximum)); }
+ void SetPos(int pos, bool redraw = true)
+ { SendMessage(TBM_SETPOS, BoolToBOOL(redraw), pos); }
+ void SetTicFreq(int freq)
+ { SendMessage(TBM_SETTICFREQ, freq); }
+
+ int GetPos()
+ { return SendMessage(TBM_GETPOS); }
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/Windows/Control/Window2.cpp b/Windows/Control/Window2.cpp
new file mode 100755
index 00000000..3e11a63d
--- /dev/null
+++ b/Windows/Control/Window2.cpp
@@ -0,0 +1,125 @@
+// Windows/Control/Window2.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/Control/Window2.h"
+
+// extern HINSTANCE g_hInstance;
+
+namespace NWindows {
+namespace NControl {
+
+static LRESULT CALLBACK WindowProcedure(HWND aHWND, UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+ CWindow tempWindow(aHWND);
+ if (message == WM_NCCREATE)
+ tempWindow.SetUserDataLongPtr(
+ LONG_PTR(((LPCREATESTRUCT)lParam)->lpCreateParams));
+ CWindow2 *window = (CWindow2*)(tempWindow.GetUserDataLongPtr());
+ if (window == NULL)
+ return FALSE;
+ if (message == WM_NCCREATE)
+ window->Attach(aHWND);
+ if (window == 0)
+ return DefWindowProc(aHWND, message, wParam, lParam);
+ return window->OnMessage(message, wParam, lParam);
+}
+
+bool CWindow2::CreateEx(DWORD exStyle, LPCTSTR className,
+ LPCTSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance)
+{
+ WNDCLASS windowClass;
+ if(!::GetClassInfo(instance, className, &windowClass))
+ {
+ // windowClass.style = CS_HREDRAW | CS_VREDRAW;
+ windowClass.style = 0;
+
+ windowClass.lpfnWndProc = WindowProcedure;
+ windowClass.cbClsExtra = NULL;
+ windowClass.cbWndExtra = NULL;
+ windowClass.hInstance = instance;
+ windowClass.hIcon = NULL;
+ windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
+ windowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+ windowClass.lpszMenuName = NULL;
+ windowClass.lpszClassName = className;
+ if (::RegisterClass(&windowClass) == 0)
+ return false;
+ }
+ return CWindow::CreateEx(exStyle, className, windowName,
+ style, x, y, width, height, parentWindow,
+ idOrHMenu, instance, this);
+}
+
+LRESULT CWindow2::OnMessage(UINT message, UINT wParam, LPARAM lParam)
+{
+ LRESULT result;
+ switch (message)
+ {
+ case WM_CREATE:
+ if (!OnCreate((CREATESTRUCT *)lParam))
+ return -1;
+ break;
+ case WM_COMMAND:
+ if (OnCommand(wParam, lParam, result))
+ return result;
+ break;
+ case WM_NOTIFY:
+ if (OnNotify(wParam, (LPNMHDR) lParam, result))
+ return result;
+ break;
+ case WM_DESTROY:
+ OnDestroy();
+ break;
+ case WM_CLOSE:
+ OnClose();
+ return 0;
+ case WM_SIZE:
+ if (OnSize(wParam, LOWORD(lParam), HIWORD(lParam)))
+ return 0;
+ }
+ return DefProc(message, wParam, lParam);
+}
+
+bool CWindow2::OnCommand(WPARAM wParam, LPARAM lParam, LRESULT &result)
+{
+ return OnCommand(HIWORD(wParam), LOWORD(wParam), lParam, result);
+}
+
+bool CWindow2::OnCommand(int code, int itemID, LPARAM lParam, LRESULT &result)
+{
+ return false;
+ // return DefProc(message, wParam, lParam);
+ /*
+ if (code == BN_CLICKED)
+ return OnButtonClicked(itemID, (HWND)lParam);
+ */
+}
+
+/*
+bool CDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
+{
+ switch(aButtonID)
+ {
+ case IDOK:
+ OnOK();
+ break;
+ case IDCANCEL:
+ OnCancel();
+ break;
+ case IDHELP:
+ OnHelp();
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+*/
+
+}}
diff --git a/Windows/Control/Window2.h b/Windows/Control/Window2.h
new file mode 100755
index 00000000..3a8b814e
--- /dev/null
+++ b/Windows/Control/Window2.h
@@ -0,0 +1,54 @@
+// Windows/Control/Window2.h
+
+#pragma once
+
+#ifndef __WINDOWS_CONTROL_WINDOW2_H
+#define __WINDOWS_CONTROL_WINDOW2_H
+
+#include "Windows/Window.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NControl {
+
+class CWindow2: public CWindow
+{
+public:
+ CWindow2(HWND newWindow = NULL): CWindow(newWindow){};
+ virtual ~CWindow2() {};
+
+ LRESULT DefProc(UINT message, WPARAM wParam, LPARAM lParam)
+ { return ::DefWindowProc(_window, message, wParam, lParam); }
+
+ bool CreateEx(DWORD exStyle, LPCTSTR className,
+ LPCTSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance);
+
+ virtual LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+ virtual bool OnCreate(CREATESTRUCT *createStruct) { return true; }
+ // virtual LRESULT OnCommand(WPARAM wParam, LPARAM lParam);
+ virtual bool OnCommand(WPARAM wParam, LPARAM lParam, LRESULT &result);
+ virtual bool OnCommand(int code, int itemID, LPARAM lParam, LRESULT &result);
+ virtual bool OnSize(WPARAM wParam, int xSize, int ySize) { return false; }
+ virtual bool OnNotify(UINT controlID, LPNMHDR lParam, LRESULT &result) { return false; }
+ virtual void OnDestroy() { PostQuitMessage(0); }
+ virtual void OnClose() { Destroy(); }
+ /*
+ virtual LRESULT OnHelp(LPHELPINFO helpInfo) { OnHelp(); };
+ virtual LRESULT OnHelp() {};
+ virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
+ virtual void OnOK() {};
+ virtual void OnCancel() {};
+ */
+
+ LONG_PTR SetMsgResult(LONG_PTR newLongPtr )
+ { return SetLongPtr(DWLP_MSGRESULT, newLongPtr); }
+ LONG_PTR GetMsgResult() const
+ { return GetLongPtr(DWLP_MSGRESULT); }
+};
+
+}}
+
+#endif \ No newline at end of file
diff --git a/Windows/DLL.cpp b/Windows/DLL.cpp
new file mode 100755
index 00000000..cd02eef6
--- /dev/null
+++ b/Windows/DLL.cpp
@@ -0,0 +1,113 @@
+// Windows/DLL.cpp
+
+#include "StdAfx.h"
+
+#include "DLL.h"
+#include "Defs.h"
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+namespace NWindows {
+namespace NDLL {
+
+CLibrary::~CLibrary()
+{
+ Free();
+}
+
+bool CLibrary::Free()
+{
+ if (_module == 0)
+ return true;
+ // MessageBox(0, TEXT(""), TEXT("Free"), 0);
+ // Sleep(5000);
+ if (!::FreeLibrary(_module))
+ return false;
+ _module = 0;
+ return true;
+}
+
+bool CLibrary::LoadOperations(HMODULE newModule)
+{
+ if (newModule == NULL)
+ return false;
+ if(!Free())
+ return false;
+ _module = newModule;
+ return true;
+}
+
+bool CLibrary::LoadEx(LPCTSTR fileName, DWORD flags)
+{
+ // MessageBox(0, fileName, TEXT("LoadEx"), 0);
+ return LoadOperations(::LoadLibraryEx(fileName, NULL, flags));
+}
+
+bool CLibrary::Load(LPCTSTR fileName)
+{
+ // MessageBox(0, fileName, TEXT("Load"), 0);
+ // Sleep(5000);
+ // OutputDebugString(fileName);
+ // OutputDebugString(TEXT("\n"));
+ return LoadOperations(::LoadLibrary(fileName));
+}
+
+#ifndef _UNICODE
+static inline UINT GetCurrentCodePage()
+ { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
+bool CLibrary::LoadEx(LPCWSTR fileName, DWORD flags)
+{
+ HMODULE module = ::LoadLibraryExW(fileName, NULL, flags);
+ if (module != 0)
+ return LoadOperations(module);
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return false;
+ return LoadEx(UnicodeStringToMultiByte(fileName, GetCurrentCodePage()), flags);
+}
+bool CLibrary::Load(LPCWSTR fileName)
+{
+ HMODULE module = ::LoadLibraryW(fileName);
+ if (module != 0)
+ return LoadOperations(module);
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return false;
+ return Load(UnicodeStringToMultiByte(fileName, GetCurrentCodePage()));
+}
+#endif
+
+bool MyGetModuleFileName(HMODULE hModule, CSysString &result)
+{
+ result.Empty();
+ TCHAR fullPath[MAX_PATH + 2];
+ DWORD size = ::GetModuleFileName(hModule, fullPath, MAX_PATH + 1);
+ if (size <= MAX_PATH && size != 0)
+ {
+ result = fullPath;
+ return true;
+ }
+ return false;
+}
+
+#ifndef _UNICODE
+bool MyGetModuleFileName(HMODULE hModule, UString &result)
+{
+ result.Empty();
+ wchar_t fullPath[MAX_PATH + 2];
+ DWORD size = ::GetModuleFileNameW(hModule, fullPath, MAX_PATH + 1);
+ if (size <= MAX_PATH && size != 0)
+ {
+ result = fullPath;
+ return true;
+ }
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return false;
+ CSysString resultSys;
+ if (!MyGetModuleFileName(hModule, resultSys))
+ return false;
+ result = MultiByteToUnicodeString(resultSys, GetCurrentCodePage());
+ return true;
+}
+#endif
+
+}}
diff --git a/Windows/DLL.h b/Windows/DLL.h
new file mode 100755
index 00000000..a4209ac9
--- /dev/null
+++ b/Windows/DLL.h
@@ -0,0 +1,56 @@
+// Windows/DLL.h
+
+#ifndef __WINDOWS_DLL_H
+#define __WINDOWS_DLL_H
+
+#pragma once
+
+#include "../Common/String.h"
+
+namespace NWindows {
+namespace NDLL {
+
+class CLibrary
+{
+ bool LoadOperations(HMODULE newModule);
+protected:
+ HMODULE _module;
+public:
+ operator HMODULE() const { return _module; }
+ HMODULE* operator&() { return &_module; }
+
+ CLibrary():_module(NULL) {};
+ ~CLibrary();
+ void Attach(HMODULE m)
+ {
+ Free();
+ _module = m;
+ }
+ HMODULE Detach()
+ {
+ HMODULE m = _module;
+ _module = NULL;
+ return m;
+ }
+
+ // operator HMODULE() const { return _module; };
+ // bool IsLoaded() const { return (_module != NULL); };
+ bool Free();
+ bool LoadEx(LPCTSTR fileName, DWORD flags = LOAD_LIBRARY_AS_DATAFILE);
+ bool Load(LPCTSTR fileName);
+ #ifndef _UNICODE
+ bool LoadEx(LPCWSTR fileName, DWORD flags = LOAD_LIBRARY_AS_DATAFILE);
+ bool Load(LPCWSTR fileName);
+ #endif
+ FARPROC GetProcAddress(LPCSTR procName) const
+ { return ::GetProcAddress(_module, procName); }
+};
+
+bool MyGetModuleFileName(HMODULE hModule, CSysString &result);
+#ifndef _UNICODE
+bool MyGetModuleFileName(HMODULE hModule, UString &result);
+#endif
+
+}}
+
+#endif
diff --git a/Windows/Defs.h b/Windows/Defs.h
new file mode 100755
index 00000000..1e1aecd5
--- /dev/null
+++ b/Windows/Defs.h
@@ -0,0 +1,23 @@
+// Windows/Defs.h
+
+#pragma once
+
+#ifndef __WINDOWS_DEFS_H
+#define __WINDOWS_DEFS_H
+
+inline bool BOOLToBool(BOOL value)
+ { return (value != FALSE); }
+
+inline BOOL BoolToBOOL(bool value)
+ { return (value ? TRUE: FALSE); }
+
+inline VARIANT_BOOL BoolToVARIANT_BOOL(bool value)
+ { return (value ? VARIANT_TRUE: VARIANT_FALSE); }
+
+inline bool VARIANT_BOOLToBool(VARIANT_BOOL value)
+ { return (value != VARIANT_FALSE); }
+
+// #define RETURN_IF_NOT_S_OK(x) { HRESULT __result_ = (x); if(__result_ != S_OK) return __result_; }
+// #define RINOK(x) { HRESULT __result_ = (x); if(__result_ != S_OK) return __result_; }
+
+#endif
diff --git a/Windows/Error.cpp b/Windows/Error.cpp
new file mode 100755
index 00000000..5852d650
--- /dev/null
+++ b/Windows/Error.cpp
@@ -0,0 +1,59 @@
+// Windows/Error.h
+
+#include "StdAfx.h"
+
+#include "Windows/Error.h"
+#ifndef _UNICODE
+#include "Common/StringConvert.h"
+#endif
+
+namespace NWindows {
+namespace NError {
+
+bool MyFormatMessage(DWORD messageID, CSysString &message)
+{
+ LPVOID msgBuf;
+ if(::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ messageID,
+ 0, // Default language
+ (LPTSTR) &msgBuf,
+ 0,
+ NULL) == 0)
+ return false;
+
+ message = (LPCTSTR)msgBuf;
+ ::LocalFree(msgBuf);
+ return true;
+}
+
+#ifndef _UNICODE
+bool MyFormatMessage(DWORD messageID, UString &message)
+{
+ LPVOID msgBuf;
+ if(::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ messageID,
+ 0, // Default language
+ (LPWSTR) &msgBuf,
+ 0,
+ NULL) == 0)
+ {
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return false;
+ CSysString messageSys;
+ bool result = MyFormatMessage(messageID, messageSys);
+ message = GetUnicodeString(messageSys);
+ return result;
+ }
+ message = (LPCWSTR)msgBuf;
+ ::LocalFree(msgBuf);
+ return true;
+}
+#endif
+
+}}
diff --git a/Windows/Error.h b/Windows/Error.h
new file mode 100755
index 00000000..d42a1116
--- /dev/null
+++ b/Windows/Error.h
@@ -0,0 +1,35 @@
+// Windows/Error.h
+
+#pragma once
+
+#ifndef __WINDOWS_ERROR_H
+#define __WINDOWS_ERROR_H
+
+#include "Common/String.h"
+
+namespace NWindows {
+namespace NError {
+
+bool MyFormatMessage(DWORD messageID, CSysString &message);
+inline CSysString MyFormatMessage(DWORD messageID)
+{
+ CSysString message;
+ MyFormatMessage(messageID, message);
+ return message;
+}
+#ifdef _UNICODE
+inline UString MyFormatMessageW(DWORD messageID)
+ { return MyFormatMessage(messageID); }
+#else
+bool MyFormatMessage(DWORD messageID, UString &message);
+inline UString MyFormatMessageW(DWORD messageID)
+{
+ UString message;
+ MyFormatMessage(messageID, message);
+ return message;
+}
+#endif
+
+}}
+
+#endif
diff --git a/Windows/FileDir.cpp b/Windows/FileDir.cpp
new file mode 100755
index 00000000..a5029f22
--- /dev/null
+++ b/Windows/FileDir.cpp
@@ -0,0 +1,713 @@
+// Windows/FileDir.cpp
+
+#include "StdAfx.h"
+
+#include "FileDir.h"
+#include "FileName.h"
+#include "FileFind.h"
+#include "Defs.h"
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+namespace NWindows {
+namespace NFile {
+namespace NDirectory {
+
+#ifndef _UNICODE
+static inline UINT GetCurrentCodePage()
+ { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
+#endif
+
+bool MyGetWindowsDirectory(CSysString &path)
+{
+ DWORD needLength = ::GetWindowsDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+}
+
+bool MyGetSystemDirectory(CSysString &path)
+{
+ DWORD needLength = ::GetSystemDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+}
+
+#ifndef _UNICODE
+bool MyGetWindowsDirectory(UString &path)
+{
+ DWORD needLength = ::GetWindowsDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
+ path.ReleaseBuffer();
+ if (needLength != 0)
+ return (needLength <= MAX_PATH);
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return false;
+ CSysString sysPath;
+ if (!MyGetWindowsDirectory(sysPath))
+ return false;
+ path = MultiByteToUnicodeString(sysPath, GetCurrentCodePage());
+ return true;
+}
+
+bool MyGetSystemDirectory(UString &path)
+{
+ DWORD needLength = ::GetSystemDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
+ path.ReleaseBuffer();
+ if (needLength != 0)
+ return (needLength <= MAX_PATH);
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return false;
+ CSysString sysPath;
+ if (!MyGetSystemDirectory(sysPath))
+ return false;
+ path = MultiByteToUnicodeString(sysPath, GetCurrentCodePage());
+ return true;
+}
+#endif
+
+#ifndef _UNICODE
+bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes)
+{
+ if (::SetFileAttributesW(fileName, fileAttributes))
+ return true;
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return false;
+ return MySetFileAttributes(UnicodeStringToMultiByte(fileName,
+ GetCurrentCodePage()), fileAttributes);
+}
+
+bool MyRemoveDirectory(LPCWSTR pathName)
+{
+ if (::RemoveDirectoryW(pathName))
+ return true;
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return false;
+ return MyRemoveDirectory(UnicodeStringToMultiByte(pathName,
+ GetCurrentCodePage()));
+}
+
+bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName)
+{
+ if (::MoveFileW(existFileName, newFileName))
+ return true;
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return false;
+ UINT codePage = GetCurrentCodePage();
+ return MyMoveFile(UnicodeStringToMultiByte(existFileName, codePage),
+ UnicodeStringToMultiByte(newFileName, codePage));
+}
+#endif
+
+bool MyCreateDirectory(LPCTSTR pathName)
+{
+ return BOOLToBool(::CreateDirectory(pathName, NULL));
+}
+
+#ifndef _UNICODE
+bool MyCreateDirectory(LPCWSTR pathName)
+{
+ if (::CreateDirectoryW(pathName, NULL))
+ return true;
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return false;
+ return MyCreateDirectory(UnicodeStringToMultiByte(pathName,
+ GetCurrentCodePage()));
+}
+#endif
+
+/*
+bool CreateComplexDirectory(LPCTSTR pathName)
+{
+ NName::CParsedPath path;
+ path.ParsePath(pathName);
+ CSysString fullPath = path.Prefix;
+ DWORD errorCode = ERROR_SUCCESS;
+ for(int i = 0; i < path.PathParts.Size(); i++)
+ {
+ const CSysString &string = path.PathParts[i];
+ if(string.IsEmpty())
+ {
+ if(i != path.PathParts.Size() - 1)
+ return false;
+ return true;
+ }
+ fullPath += path.PathParts[i];
+ if(!MyCreateDirectory(fullPath))
+ {
+ DWORD errorCode = GetLastError();
+ if(errorCode != ERROR_ALREADY_EXISTS)
+ return false;
+ }
+ fullPath += NName::kDirDelimiter;
+ }
+ return true;
+}
+*/
+
+bool CreateComplexDirectory(LPCTSTR _aPathName)
+{
+ CSysString pathName = _aPathName;
+ int pos = pathName.ReverseFind(TEXT('\\'));
+ if (pos > 0 && pos == pathName.Length() - 1)
+ {
+ if (pathName.Length() == 3 && pathName[1] == ':')
+ return true; // Disk folder;
+ pathName.Delete(pos);
+ }
+ CSysString pathName2 = pathName;
+ pos = pathName.Length();
+ while(true)
+ {
+ if(MyCreateDirectory(pathName))
+ break;
+ if(::GetLastError() == ERROR_ALREADY_EXISTS)
+ {
+ NFind::CFileInfo fileInfo;
+ if (!NFind::FindFile(pathName, fileInfo)) // For network folders
+ return true;
+ if (!fileInfo.IsDirectory())
+ return false;
+ break;
+ }
+ pos = pathName.ReverseFind(TEXT('\\'));
+ if (pos < 0 || pos == 0)
+ return false;
+ if (pathName[pos - 1] == ':')
+ return false;
+ pathName = pathName.Left(pos);
+ }
+ pathName = pathName2;
+ while(pos < pathName.Length())
+ {
+ pos = pathName.Find(TEXT('\\'), pos + 1);
+ if (pos < 0)
+ pos = pathName.Length();
+ if(!MyCreateDirectory(pathName.Left(pos)))
+ return false;
+ }
+ return true;
+}
+
+#ifndef _UNICODE
+
+bool CreateComplexDirectory(LPCWSTR _aPathName)
+{
+ UString pathName = _aPathName;
+ int pos = pathName.ReverseFind(L'\\');
+ if (pos > 0 && pos == pathName.Length() - 1)
+ {
+ if (pathName.Length() == 3 && pathName[1] == L':')
+ return true; // Disk folder;
+ pathName.Delete(pos);
+ }
+ UString pathName2 = pathName;
+ pos = pathName.Length();
+ while(true)
+ {
+ if(MyCreateDirectory(pathName))
+ break;
+ if(::GetLastError() == ERROR_ALREADY_EXISTS)
+ {
+ NFind::CFileInfoW fileInfo;
+ if (!NFind::FindFile(pathName, fileInfo)) // For network folders
+ return true;
+ if (!fileInfo.IsDirectory())
+ return false;
+ break;
+ }
+ pos = pathName.ReverseFind(L'\\');
+ if (pos < 0 || pos == 0)
+ return false;
+ if (pathName[pos - 1] == L':')
+ return false;
+ pathName = pathName.Left(pos);
+ }
+ pathName = pathName2;
+ while(pos < pathName.Length())
+ {
+ pos = pathName.Find(L'\\', pos + 1);
+ if (pos < 0)
+ pos = pathName.Length();
+ if(!MyCreateDirectory(pathName.Left(pos)))
+ return false;
+ }
+ return true;
+}
+
+#endif
+
+bool DeleteFileAlways(LPCTSTR name)
+{
+ if(!::SetFileAttributes(name, 0))
+ return false;
+ return BOOLToBool(::DeleteFile(name));
+}
+
+#ifndef _UNICODE
+bool DeleteFileAlways(LPCWSTR name)
+{
+ if(!MySetFileAttributes(name, 0))
+ return false;
+ if (::DeleteFileW(name))
+ return true;
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return false;
+ return DeleteFileAlways(UnicodeStringToMultiByte(name,
+ GetCurrentCodePage()));
+}
+#endif
+
+static bool RemoveDirectorySubItems2(const CSysString pathPrefix,
+ const NFind::CFileInfo &fileInfo)
+{
+ if(fileInfo.IsDirectory())
+ return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
+ else
+ return DeleteFileAlways(pathPrefix + fileInfo.Name);
+}
+
+bool RemoveDirectoryWithSubItems(const CSysString &path)
+{
+ NFind::CFileInfo fileInfo;
+ CSysString pathPrefix = path + NName::kDirDelimiter;
+ {
+ NFind::CEnumerator enumerator(pathPrefix + TCHAR(NName::kAnyStringWildcard));
+ while(enumerator.Next(fileInfo))
+ if(!RemoveDirectorySubItems2(pathPrefix, fileInfo))
+ return false;
+ }
+ if(!BOOLToBool(::SetFileAttributes(path, 0)))
+ return false;
+ return BOOLToBool(::RemoveDirectory(path));
+}
+
+#ifndef _UNICODE
+static bool RemoveDirectorySubItems2(const UString pathPrefix,
+ const NFind::CFileInfoW &fileInfo)
+{
+ if(fileInfo.IsDirectory())
+ return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
+ else
+ return DeleteFileAlways(pathPrefix + fileInfo.Name);
+}
+bool RemoveDirectoryWithSubItems(const UString &path)
+{
+ NFind::CFileInfoW fileInfo;
+ UString pathPrefix = path + UString(NName::kDirDelimiter);
+ {
+ NFind::CEnumeratorW enumerator(pathPrefix + UString(NName::kAnyStringWildcard));
+ while(enumerator.Next(fileInfo))
+ if(!RemoveDirectorySubItems2(pathPrefix, fileInfo))
+ return false;
+ }
+ if(!MySetFileAttributes(path, 0))
+ return false;
+ return MyRemoveDirectory(path);
+}
+#endif
+
+#ifndef _WIN32_WCE
+
+bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath)
+{
+ DWORD needLength = ::GetShortPathName(longPath,
+ shortPath.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
+ shortPath.ReleaseBuffer();
+ if (needLength == 0 || needLength >= MAX_PATH)
+ return false;
+ return true;
+}
+
+bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath,
+ int &fileNamePartStartIndex)
+{
+ LPTSTR fileNamePointer = 0;
+ LPTSTR buffer = resultPath.GetBuffer(MAX_PATH);
+ DWORD needLength = ::GetFullPathName(fileName, MAX_PATH + 1,
+ buffer, &fileNamePointer);
+ resultPath.ReleaseBuffer();
+ if (needLength == 0 || needLength >= MAX_PATH)
+ return false;
+ if (fileNamePointer == 0)
+ fileNamePartStartIndex = lstrlen(fileName);
+ else
+ fileNamePartStartIndex = fileNamePointer - buffer;
+ return true;
+}
+
+#ifndef _UNICODE
+bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath,
+ int &fileNamePartStartIndex)
+{
+ resultPath.Empty();
+ LPWSTR fileNamePointer = 0;
+ LPWSTR buffer = resultPath.GetBuffer(MAX_PATH);
+ DWORD needLength = ::GetFullPathNameW(fileName, MAX_PATH + 1,
+ buffer, &fileNamePointer);
+ resultPath.ReleaseBuffer();
+ if (needLength == 0)
+ {
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return false;
+
+ const UINT currentPage = GetCurrentCodePage();
+ CSysString sysPath;
+ if (!MyGetFullPathName(UnicodeStringToMultiByte(fileName,
+ currentPage), sysPath, fileNamePartStartIndex))
+ return false;
+ UString resultPath1 = MultiByteToUnicodeString(
+ sysPath.Left(fileNamePartStartIndex), currentPage);
+ UString resultPath2 = MultiByteToUnicodeString(
+ sysPath.Mid(fileNamePartStartIndex), currentPage);
+ fileNamePartStartIndex = resultPath1.Length();
+ resultPath = resultPath1 + resultPath2;
+ return true;
+ }
+ else if (needLength >= MAX_PATH)
+ return false;
+ if (fileNamePointer == 0)
+ fileNamePartStartIndex = MyStringLen(fileName);
+ else
+ fileNamePartStartIndex = fileNamePointer - buffer;
+ return true;
+}
+#endif
+
+
+bool MyGetFullPathName(LPCTSTR fileName, CSysString &path)
+{
+ int index;
+ return MyGetFullPathName(fileName, path, index);
+}
+
+#ifndef _UNICODE
+bool MyGetFullPathName(LPCWSTR fileName, UString &path)
+{
+ int index;
+ return MyGetFullPathName(fileName, path, index);
+}
+#endif
+
+bool GetOnlyName(LPCTSTR fileName, CSysString &resultName)
+{
+ int index;
+ if (!MyGetFullPathName(fileName, resultName, index))
+ return false;
+ resultName = resultName.Mid(index);
+ return true;
+}
+
+#ifndef _UNICODE
+bool GetOnlyName(LPCWSTR fileName, UString &resultName)
+{
+ int index;
+ if (!MyGetFullPathName(fileName, resultName, index))
+ return false;
+ resultName = resultName.Mid(index);
+ return true;
+}
+#endif
+
+bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName)
+{
+ int index;
+ if (!MyGetFullPathName(fileName, resultName, index))
+ return false;
+ resultName = resultName.Left(index);
+ return true;
+}
+
+#ifndef _UNICODE
+bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName)
+{
+ int index;
+ if (!MyGetFullPathName(fileName, resultName, index))
+ return false;
+ resultName = resultName.Left(index);
+ return true;
+}
+#endif
+
+bool MyGetCurrentDirectory(CSysString &path)
+{
+ DWORD needLength = ::GetCurrentDirectory(MAX_PATH + 1,
+ path.GetBuffer(MAX_PATH + 1));
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+}
+
+#ifndef _UNICODE
+bool MySetCurrentDirectory(LPCWSTR path)
+{
+ if (::SetCurrentDirectoryW(path))
+ return true;
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return false;
+ return MySetCurrentDirectory(UnicodeStringToMultiByte(path,
+ GetCurrentCodePage()));
+}
+bool MyGetCurrentDirectory(UString &path)
+{
+ DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1,
+ path.GetBuffer(MAX_PATH + 1));
+ path.ReleaseBuffer();
+ if (needLength != 0)
+ return (needLength <= MAX_PATH);
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return false;
+ CSysString sysPath;
+ if (!MyGetCurrentDirectory(sysPath))
+ return false;
+ path = MultiByteToUnicodeString(sysPath, GetCurrentCodePage());
+ return true;
+}
+#endif
+#endif
+
+bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension,
+ CSysString &resultPath, UINT32 &filePart)
+{
+ LPTSTR filePartPointer;
+ DWORD value = ::SearchPath(path, fileName, extension,
+ MAX_PATH, resultPath.GetBuffer(MAX_PATH), &filePartPointer);
+ filePart = filePartPointer - (LPCTSTR)resultPath;
+ resultPath.ReleaseBuffer();
+ if (value == 0 || value > MAX_PATH)
+ return false;
+ return true;
+}
+
+#ifndef _UNICODE
+bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension,
+ UString &resultPath, UINT32 &filePart)
+{
+ LPWSTR filePartPointer = 0;
+ DWORD value = ::SearchPathW(path, fileName, extension,
+ MAX_PATH, resultPath.GetBuffer(MAX_PATH), &filePartPointer);
+ resultPath.ReleaseBuffer();
+ if (value != 0)
+ return (value <= MAX_PATH);
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return false;
+
+ const UINT currentPage = GetCurrentCodePage();
+ CSysString sysPath;
+ if (!MySearchPath(
+ path != 0 ? (LPCTSTR)UnicodeStringToMultiByte(path, currentPage): 0,
+ fileName != 0 ? (LPCTSTR)UnicodeStringToMultiByte(fileName, currentPage): 0,
+ extension != 0 ? (LPCTSTR)UnicodeStringToMultiByte(extension, currentPage): 0,
+ sysPath, filePart))
+ return false;
+ UString resultPath1 = MultiByteToUnicodeString(
+ sysPath.Left(filePart), currentPage);
+ UString resultPath2 = MultiByteToUnicodeString(
+ sysPath.Mid(filePart), currentPage);
+ filePart = resultPath1.Length();
+ resultPath = resultPath1 + resultPath2;
+ return true;
+}
+#endif
+
+bool MyGetTempPath(CSysString &path)
+{
+ DWORD needLength = ::GetTempPath(MAX_PATH + 1,
+ path.GetBuffer(MAX_PATH));
+ path.ReleaseBuffer();
+ return (needLength > 0 && needLength <= MAX_PATH);
+}
+
+#ifndef _UNICODE
+bool MyGetTempPath(UString &path)
+{
+ path.Empty();
+ DWORD needLength = ::GetTempPathW(MAX_PATH + 1,
+ path.GetBuffer(MAX_PATH));
+ path.ReleaseBuffer();
+ if (needLength == 0)
+ {
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return false;
+ CSysString sysPath;
+ if (!MyGetTempPath(sysPath))
+ return false;
+ path = MultiByteToUnicodeString(sysPath, GetCurrentCodePage());
+ return true;
+ }
+ return (needLength > 0 && needLength <= MAX_PATH);
+}
+#endif
+
+UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &path)
+{
+ UINT number = ::GetTempFileName(dirPath, prefix, 0,
+ path.GetBuffer(MAX_PATH));
+ path.ReleaseBuffer();
+ return number;
+}
+
+#ifndef _UNICODE
+UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &path)
+{
+ UINT number = ::GetTempFileNameW(dirPath, prefix, 0,
+ path.GetBuffer(MAX_PATH));
+ path.ReleaseBuffer();
+ if (number == 0)
+ {
+ if (::GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+ {
+ const UINT currentPage = GetCurrentCodePage();
+ CSysString sysPath;
+ number = MyGetTempFileName(
+ dirPath ? (LPCTSTR)UnicodeStringToMultiByte(dirPath, currentPage): 0,
+ prefix ? (LPCTSTR)UnicodeStringToMultiByte(prefix, currentPage): 0,
+ sysPath);
+ path = MultiByteToUnicodeString(sysPath, currentPage);
+ }
+ }
+ return number;
+}
+#endif
+
+UINT CTempFile::Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath)
+{
+ Remove();
+ UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
+ if(number != 0)
+ {
+ _fileName = resultPath;
+ _mustBeDeleted = true;
+ }
+ return number;
+}
+
+bool CTempFile::Create(LPCTSTR prefix, CSysString &resultPath)
+{
+ CSysString tempPath;
+ if(!MyGetTempPath(tempPath))
+ return false;
+ if (Create(tempPath, prefix, resultPath) != 0)
+ return true;
+ if(!MyGetWindowsDirectory(tempPath))
+ return false;
+ return (Create(tempPath, prefix, resultPath) != 0);
+}
+
+bool CTempFile::Remove()
+{
+ if (!_mustBeDeleted)
+ return true;
+ _mustBeDeleted = !DeleteFileAlways(_fileName);
+ return !_mustBeDeleted;
+}
+
+#ifndef _UNICODE
+
+UINT CTempFileW::Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath)
+{
+ Remove();
+ UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
+ if(number != 0)
+ {
+ _fileName = resultPath;
+ _mustBeDeleted = true;
+ }
+ return number;
+}
+
+bool CTempFileW::Create(LPCWSTR prefix, UString &resultPath)
+{
+ UString tempPath;
+ if(!MyGetTempPath(tempPath))
+ return false;
+ if (Create(tempPath, prefix, resultPath) != 0)
+ return true;
+ if(!MyGetWindowsDirectory(tempPath))
+ return false;
+ return (Create(tempPath, prefix, resultPath) != 0);
+}
+
+bool CTempFileW::Remove()
+{
+ if (!_mustBeDeleted)
+ return true;
+ _mustBeDeleted = !DeleteFileAlways(_fileName);
+ return !_mustBeDeleted;
+}
+
+#endif
+
+bool CreateTempDirectory(LPCTSTR prefix, CSysString &dirName)
+{
+ /*
+ CSysString prefix = tempPath + prefixChars;
+ CRandom random;
+ random.Init();
+ */
+ while(true)
+ {
+ CTempFile tempFile;
+ if (!tempFile.Create(prefix, dirName))
+ return false;
+ if (!::DeleteFile(dirName))
+ return false;
+ /*
+ UINT32 randomNumber = random.Generate();
+ TCHAR randomNumberString[32];
+ _stprintf(randomNumberString, _T("%04X"), randomNumber);
+ dirName = prefix + randomNumberString;
+ */
+ if(NFind::DoesFileExist(dirName))
+ continue;
+ if (MyCreateDirectory(dirName))
+ return true;
+ if (::GetLastError() != ERROR_ALREADY_EXISTS)
+ return false;
+ }
+}
+
+bool CTempDirectory::Create(LPCTSTR prefix)
+{
+ Remove();
+ return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));
+}
+
+#ifndef _UNICODE
+
+bool CreateTempDirectory(LPCWSTR prefix, UString &dirName)
+{
+ /*
+ CSysString prefix = tempPath + prefixChars;
+ CRandom random;
+ random.Init();
+ */
+ while(true)
+ {
+ CTempFileW tempFile;
+ if (!tempFile.Create(prefix, dirName))
+ return false;
+ if (!DeleteFileAlways(dirName))
+ return false;
+ /*
+ UINT32 randomNumber = random.Generate();
+ TCHAR randomNumberString[32];
+ _stprintf(randomNumberString, _T("%04X"), randomNumber);
+ dirName = prefix + randomNumberString;
+ */
+ if(NFind::DoesFileExist(dirName))
+ continue;
+ if (MyCreateDirectory(dirName))
+ return true;
+ if (::GetLastError() != ERROR_ALREADY_EXISTS)
+ return false;
+ }
+}
+
+bool CTempDirectoryW::Create(LPCWSTR prefix)
+{
+ Remove();
+ return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));
+}
+
+#endif
+
+}}}
diff --git a/Windows/FileDir.h b/Windows/FileDir.h
new file mode 100755
index 00000000..07e2a0b2
--- /dev/null
+++ b/Windows/FileDir.h
@@ -0,0 +1,189 @@
+// Windows/FileDir.h
+
+#pragma once
+
+#ifndef __WINDOWS_FILEDIR_H
+#define __WINDOWS_FILEDIR_H
+
+#include "../Common/String.h"
+#include "Defs.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NDirectory {
+
+bool MyGetWindowsDirectory(CSysString &path);
+bool MyGetSystemDirectory(CSysString &path);
+#ifndef _UNICODE
+bool MyGetWindowsDirectory(UString &path);
+bool MyGetSystemDirectory(UString &path);
+#endif
+
+inline bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes)
+ { return BOOLToBool(::SetFileAttributes(fileName, fileAttributes)); }
+#ifndef _UNICODE
+bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes);
+#endif
+
+inline bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName)
+ { return BOOLToBool(::MoveFile(existFileName, newFileName)); }
+#ifndef _UNICODE
+bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName);
+#endif
+
+inline bool MyRemoveDirectory(LPCTSTR pathName)
+ { return BOOLToBool(::RemoveDirectory(pathName)); }
+#ifndef _UNICODE
+bool MyRemoveDirectory(LPCWSTR pathName);
+#endif
+
+bool MyCreateDirectory(LPCTSTR pathName);
+bool CreateComplexDirectory(LPCTSTR pathName);
+#ifndef _UNICODE
+bool MyCreateDirectory(LPCWSTR pathName);
+bool CreateComplexDirectory(LPCWSTR pathName);
+#endif
+
+bool DeleteFileAlways(LPCTSTR name);
+#ifndef _UNICODE
+bool DeleteFileAlways(LPCWSTR name);
+#endif
+
+bool RemoveDirectoryWithSubItems(const CSysString &path);
+#ifndef _UNICODE
+bool RemoveDirectoryWithSubItems(const UString &path);
+#endif
+
+#ifndef _WIN32_WCE
+bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath);
+
+bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath,
+ int &fileNamePartStartIndex);
+bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath);
+bool GetOnlyName(LPCTSTR fileName, CSysString &resultName);
+bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName);
+#ifndef _UNICODE
+bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath,
+ int &fileNamePartStartIndex);
+bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath);
+bool GetOnlyName(LPCWSTR fileName, UString &resultName);
+bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName);
+#endif
+
+inline bool MySetCurrentDirectory(LPCTSTR path)
+ { return BOOLToBool(::SetCurrentDirectory(path)); }
+bool MyGetCurrentDirectory(CSysString &resultPath);
+#ifndef _UNICODE
+bool MySetCurrentDirectory(LPCWSTR path);
+bool MyGetCurrentDirectory(UString &resultPath);
+#endif
+#endif
+
+bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension,
+ CSysString &resultPath, UINT32 &filePart);
+#ifndef _UNICODE
+bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension,
+ UString &resultPath, UINT32 &filePart);
+#endif
+
+inline bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension,
+ CSysString &resultPath)
+{
+ UINT32 value;
+ return MySearchPath(path, fileName, extension, resultPath, value);
+}
+
+#ifndef _UNICODE
+inline bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension,
+ UString &resultPath)
+{
+ UINT32 value;
+ return MySearchPath(path, fileName, extension, resultPath, value);
+}
+#endif
+
+bool MyGetTempPath(CSysString &resultPath);
+#ifndef _UNICODE
+bool MyGetTempPath(UString &resultPath);
+#endif
+
+UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath);
+#ifndef _UNICODE
+UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath);
+#endif
+
+class CTempFile
+{
+ bool _mustBeDeleted;
+ CSysString _fileName;
+public:
+ CTempFile(): _mustBeDeleted(false) {}
+ ~CTempFile() { Remove(); }
+ void DisableDeleting() { _mustBeDeleted = false; }
+ UINT Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath);
+ bool Create(LPCTSTR prefix, CSysString &resultPath);
+ bool Remove();
+};
+
+#ifdef _UNICODE
+typedef CTempFile CTempFileW;
+#else
+class CTempFileW
+{
+ bool _mustBeDeleted;
+ UString _fileName;
+public:
+ CTempFileW(): _mustBeDeleted(false) {}
+ ~CTempFileW() { Remove(); }
+ void DisableDeleting() { _mustBeDeleted = false; }
+ UINT Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath);
+ bool Create(LPCWSTR prefix, UString &resultPath);
+ bool Remove();
+};
+#endif
+
+bool CreateTempDirectory(LPCTSTR prefixChars, CSysString &dirName);
+
+class CTempDirectory
+{
+ bool _mustBeDeleted;
+ CSysString _tempDir;
+public:
+ const CSysString &GetPath() const { return _tempDir; }
+ CTempDirectory(): _mustBeDeleted(false) {}
+ ~CTempDirectory() { Remove(); }
+ bool Create(LPCTSTR prefix) ;
+ bool Remove()
+ {
+ if (!_mustBeDeleted)
+ return true;
+ _mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir);
+ return (!_mustBeDeleted);
+ }
+};
+
+#ifdef _UNICODE
+typedef CTempDirectory CTempDirectoryW;
+#else
+class CTempDirectoryW
+{
+ bool _mustBeDeleted;
+ UString _tempDir;
+public:
+ const UString &GetPath() const { return _tempDir; }
+ CTempDirectoryW(): _mustBeDeleted(false) {}
+ ~CTempDirectoryW() { Remove(); }
+ bool Create(LPCWSTR prefix) ;
+ bool Remove()
+ {
+ if (!_mustBeDeleted)
+ return true;
+ _mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir);
+ return (!_mustBeDeleted);
+ }
+};
+#endif
+
+}}}
+
+#endif
diff --git a/Windows/FileFind.cpp b/Windows/FileFind.cpp
new file mode 100755
index 00000000..27e405f4
--- /dev/null
+++ b/Windows/FileFind.cpp
@@ -0,0 +1,312 @@
+// Windows/FileFind.cpp
+
+#include "StdAfx.h"
+
+#include "FileFind.h"
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+namespace NWindows {
+namespace NFile {
+namespace NFind {
+
+static const TCHAR kDot = TEXT('.');
+
+bool CFileInfo::IsDots() const
+{
+ if (!IsDirectory() || Name.IsEmpty())
+ return false;
+ if (Name[0] != kDot)
+ return false;
+ return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
+}
+
+#ifndef _UNICODE
+bool CFileInfoW::IsDots() const
+{
+ if (!IsDirectory() || Name.IsEmpty())
+ return false;
+ if (Name[0] != kDot)
+ return false;
+ return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
+}
+#endif
+
+static void ConvertWIN32_FIND_DATA_To_FileInfo(
+ const WIN32_FIND_DATA &findData,
+ CFileInfo &fileInfo)
+{
+ fileInfo.Attributes = findData.dwFileAttributes;
+ fileInfo.CreationTime = findData.ftCreationTime;
+ fileInfo.LastAccessTime = findData.ftLastAccessTime;
+ fileInfo.LastWriteTime = findData.ftLastWriteTime;
+ fileInfo.Size = (((UINT64)findData.nFileSizeHigh) << 32) +
+ findData.nFileSizeLow;
+ fileInfo.Name = findData.cFileName;
+ #ifndef _WIN32_WCE
+ fileInfo.ReparseTag = findData.dwReserved0;
+ #else
+ fileInfo.ObjectID = findData.dwOID;
+ #endif
+}
+
+#ifndef _UNICODE
+
+static inline UINT GetCurrentCodePage()
+ { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
+
+static void ConvertWIN32_FIND_DATA_To_FileInfo(
+ const WIN32_FIND_DATAW &findData,
+ CFileInfoW &fileInfo)
+{
+ fileInfo.Attributes = findData.dwFileAttributes;
+ fileInfo.CreationTime = findData.ftCreationTime;
+ fileInfo.LastAccessTime = findData.ftLastAccessTime;
+ fileInfo.LastWriteTime = findData.ftLastWriteTime;
+ fileInfo.Size = (((UINT64)findData.nFileSizeHigh) << 32) +
+ findData.nFileSizeLow;
+ fileInfo.Name = findData.cFileName;
+ #ifndef _WIN32_WCE
+ fileInfo.ReparseTag = findData.dwReserved0;
+ #else
+ fileInfo.ObjectID = findData.dwOID;
+ #endif
+}
+
+static void ConvertWIN32_FIND_DATA_To_FileInfo(
+ const WIN32_FIND_DATA &findData,
+ CFileInfoW &fileInfo)
+{
+ fileInfo.Attributes = findData.dwFileAttributes;
+ fileInfo.CreationTime = findData.ftCreationTime;
+ fileInfo.LastAccessTime = findData.ftLastAccessTime;
+ fileInfo.LastWriteTime = findData.ftLastWriteTime;
+ fileInfo.Size = (((UINT64)findData.nFileSizeHigh) << 32) +
+ findData.nFileSizeLow;
+ fileInfo.Name = GetUnicodeString(findData.cFileName, GetCurrentCodePage());
+ #ifndef _WIN32_WCE
+ fileInfo.ReparseTag = findData.dwReserved0;
+ #else
+ fileInfo.ObjectID = findData.dwOID;
+ #endif
+}
+#endif
+
+////////////////////////////////
+// CFindFile
+
+bool CFindFile::Close()
+{
+ if(!_handleAllocated)
+ return true;
+ bool result = BOOLToBool(::FindClose(_handle));
+ _handleAllocated = !result;
+ return result;
+}
+
+bool CFindFile::FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo)
+{
+ Close();
+ WIN32_FIND_DATA findData;
+ _handle = ::FindFirstFile(wildcard, &findData);
+ _handleAllocated = (_handle != INVALID_HANDLE_VALUE);
+ if (_handleAllocated)
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ return _handleAllocated;
+}
+
+#ifndef _UNICODE
+bool CFindFile::FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo)
+{
+ Close();
+ WIN32_FIND_DATAW findDataW;
+ ::SetLastError(0);
+ _handle = ::FindFirstFileW(wildcard, &findDataW);
+ if ((_handle == INVALID_HANDLE_VALUE || _handle == 0) &&
+ ::GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+ {
+ WIN32_FIND_DATA findData;
+ _handle = ::FindFirstFile(UnicodeStringToMultiByte(wildcard,
+ GetCurrentCodePage()), &findData);
+ _handleAllocated = (_handle != INVALID_HANDLE_VALUE);
+ if (_handleAllocated)
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ }
+ else
+ {
+ _handleAllocated = (_handle != INVALID_HANDLE_VALUE);
+ if (_handleAllocated)
+ ConvertWIN32_FIND_DATA_To_FileInfo(findDataW, fileInfo);
+ }
+ return _handleAllocated;
+}
+#endif
+
+bool CFindFile::FindNext(CFileInfo &fileInfo)
+{
+ WIN32_FIND_DATA findData;
+ bool result = BOOLToBool(::FindNextFile(_handle, &findData));
+ if (result)
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ return result;
+}
+
+#ifndef _UNICODE
+bool CFindFile::FindNext(CFileInfoW &fileInfo)
+{
+ WIN32_FIND_DATAW findDataW;
+ if (::FindNextFileW(_handle, &findDataW))
+ {
+ ConvertWIN32_FIND_DATA_To_FileInfo(findDataW, fileInfo);
+ return true;
+ }
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return false;
+ WIN32_FIND_DATA findData;
+ if (!::FindNextFile(_handle, &findData))
+ return false;
+ ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+ return true;
+}
+#endif
+
+bool FindFile(LPCTSTR wildcard, CFileInfo &fileInfo)
+{
+ CFindFile finder;
+ return finder.FindFirst(wildcard, fileInfo);
+}
+
+#ifndef _UNICODE
+bool FindFile(LPCWSTR wildcard, CFileInfoW &fileInfo)
+{
+ CFindFile finder;
+ return finder.FindFirst(wildcard, fileInfo);
+}
+#endif
+
+bool DoesFileExist(LPCTSTR name)
+{
+ CFileInfo fileInfo;
+ return FindFile(name, fileInfo);
+}
+
+#ifndef _UNICODE
+bool DoesFileExist(LPCWSTR name)
+{
+ CFileInfoW fileInfo;
+ return FindFile(name, fileInfo);
+}
+#endif
+
+/////////////////////////////////////
+// CEnumerator
+
+bool CEnumerator::NextAny(CFileInfo &fileInfo)
+{
+ if(_findFile.IsHandleAllocated())
+ return _findFile.FindNext(fileInfo);
+ else
+ return _findFile.FindFirst(_wildcard, fileInfo);
+}
+
+bool CEnumerator::Next(CFileInfo &fileInfo)
+{
+ while(true)
+ {
+ if(!NextAny(fileInfo))
+ return false;
+ if(!fileInfo.IsDots())
+ return true;
+ }
+}
+
+#ifndef _UNICODE
+bool CEnumeratorW::NextAny(CFileInfoW &fileInfo)
+{
+ if(_findFile.IsHandleAllocated())
+ return _findFile.FindNext(fileInfo);
+ else
+ return _findFile.FindFirst(_wildcard, fileInfo);
+}
+
+bool CEnumeratorW::Next(CFileInfoW &fileInfo)
+{
+ while(true)
+ {
+ if(!NextAny(fileInfo))
+ return false;
+ if(!fileInfo.IsDots())
+ return true;
+ }
+}
+#endif
+
+////////////////////////////////
+// CFindChangeNotification
+
+bool CFindChangeNotification::Close()
+{
+ if(_handle == INVALID_HANDLE_VALUE || _handle == 0)
+ return true;
+ bool result = BOOLToBool(::FindCloseChangeNotification(_handle));
+ if (result)
+ _handle = INVALID_HANDLE_VALUE;
+ return result;
+}
+
+HANDLE CFindChangeNotification::FindFirst(LPCTSTR pathName, bool watchSubtree,
+ DWORD notifyFilter)
+{
+ _handle = ::FindFirstChangeNotification(pathName,
+ BoolToBOOL(watchSubtree), notifyFilter);
+ return _handle;
+}
+
+#ifndef _UNICODE
+HANDLE CFindChangeNotification::FindFirst(LPCWSTR pathName, bool watchSubtree,
+ DWORD notifyFilter)
+{
+ ::SetLastError(0);
+ _handle = ::FindFirstChangeNotificationW(pathName,
+ BoolToBOOL(watchSubtree), notifyFilter);
+ if ((_handle == 0 || _handle == INVALID_HANDLE_VALUE) &&
+ ::GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+ return FindFirst(UnicodeStringToMultiByte(pathName,
+ GetCurrentCodePage()), watchSubtree, notifyFilter);
+ return _handle;
+}
+#endif
+
+#ifndef _WIN32_WCE
+bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings)
+{
+ driveStrings.Clear();
+ UINT32 size = GetLogicalDriveStrings(0, NULL);
+ if(size == 0)
+ return false;
+ CSysString buffer;
+ UINT32 newSize = GetLogicalDriveStrings(size, buffer.GetBuffer(size));
+ if(newSize == 0)
+ return false;
+ if(newSize > size)
+ return false;
+ CSysString string;
+ for(UINT32 i = 0; i < newSize; i++)
+ {
+ TCHAR c = buffer[i];
+ if(c == TEXT('\0'))
+ {
+ driveStrings.Add(string);
+ string.Empty();
+ }
+ else
+ string += c;
+ }
+ if(!string.IsEmpty())
+ return false;
+ return true;
+}
+#endif
+
+}}}
diff --git a/Windows/FileFind.h b/Windows/FileFind.h
new file mode 100755
index 00000000..0ff24a92
--- /dev/null
+++ b/Windows/FileFind.h
@@ -0,0 +1,174 @@
+// Windows/FileFind.h
+
+#pragma once
+
+#ifndef __WINDOWS_FILEFIND_H
+#define __WINDOWS_FILEFIND_H
+
+#include "../Common/String.h"
+#include "FileName.h"
+#include "Defs.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NFind {
+
+namespace NAttributes
+{
+ inline bool IsReadOnly(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_READONLY) != 0; }
+ inline bool IsHidden(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_HIDDEN) != 0; }
+ inline bool IsSystem(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_SYSTEM) != 0; }
+ inline bool IsDirectory(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; }
+ inline bool IsArchived(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_ARCHIVE) != 0; }
+ inline bool IsCompressed(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_COMPRESSED) != 0; }
+ inline bool IsEncrypted(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_ENCRYPTED) != 0; }
+}
+
+class CFileInfoBase
+{
+ bool MatchesMask(UINT32 mask) const { return ((Attributes & mask) != 0); }
+public:
+ DWORD Attributes;
+ FILETIME CreationTime;
+ FILETIME LastAccessTime;
+ FILETIME LastWriteTime;
+ UINT64 Size;
+
+ #ifndef _WIN32_WCE
+ UINT32 ReparseTag;
+ #else
+ DWORD ObjectID;
+ #endif
+
+
+ bool IsArchived() const { return MatchesMask(FILE_ATTRIBUTE_ARCHIVE); }
+ bool IsCompressed() const { return MatchesMask(FILE_ATTRIBUTE_COMPRESSED); }
+ bool IsDirectory() const { return MatchesMask(FILE_ATTRIBUTE_DIRECTORY); }
+ bool IsEncrypted() const { return MatchesMask(FILE_ATTRIBUTE_ENCRYPTED); }
+ bool IsHidden() const { return MatchesMask(FILE_ATTRIBUTE_HIDDEN); }
+ bool IsNormal() const { return MatchesMask(FILE_ATTRIBUTE_NORMAL); }
+ bool IsOffline() const { return MatchesMask(FILE_ATTRIBUTE_OFFLINE); }
+ bool IsReadOnly() const { return MatchesMask(FILE_ATTRIBUTE_READONLY); }
+ bool HasReparsePoint() const { return MatchesMask(FILE_ATTRIBUTE_REPARSE_POINT); }
+ bool IsSparse() const { return MatchesMask(FILE_ATTRIBUTE_SPARSE_FILE); }
+ bool IsSystem() const { return MatchesMask(FILE_ATTRIBUTE_SYSTEM); }
+ bool IsTemporary() const { return MatchesMask(FILE_ATTRIBUTE_TEMPORARY); }
+
+};
+
+class CFileInfo: public CFileInfoBase
+{
+public:
+ CSysString Name;
+ bool IsDots() const;
+};
+
+#ifdef _UNICODE
+typedef CFileInfo CFileInfoW;
+#else
+class CFileInfoW: public CFileInfoBase
+{
+public:
+ UString Name;
+ bool IsDots() const;
+};
+#endif
+
+class CFindFile
+{
+ friend class CEnumerator;
+ HANDLE _handle;
+ bool _handleAllocated;
+public:
+ bool IsHandleAllocated() const { return _handleAllocated; }
+ CFindFile(): _handleAllocated(false) {}
+ ~CFindFile() { Close(); }
+ bool FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo);
+ bool FindNext(CFileInfo &fileInfo);
+ #ifndef _UNICODE
+ bool FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo);
+ bool FindNext(CFileInfoW &fileInfo);
+ #endif
+ bool Close();
+};
+
+bool FindFile(LPCTSTR wildcard, CFileInfo &fileInfo);
+
+bool DoesFileExist(LPCTSTR name);
+#ifndef _UNICODE
+bool FindFile(LPCWSTR wildcard, CFileInfoW &fileInfo);
+bool DoesFileExist(LPCWSTR name);
+#endif
+
+class CEnumerator
+{
+ CFindFile _findFile;
+ CSysString _wildcard;
+ bool NextAny(CFileInfo &fileInfo);
+public:
+ CEnumerator(): _wildcard(NName::kAnyStringWildcard) {}
+ CEnumerator(const CSysString &wildcard): _wildcard(wildcard) {}
+ bool Next(CFileInfo &fileInfo);
+};
+
+#ifdef _UNICODE
+typedef CEnumerator CEnumeratorW;
+#else
+class CEnumeratorW
+{
+ CFindFile _findFile;
+ UString _wildcard;
+ bool NextAny(CFileInfoW &fileInfo);
+public:
+ CEnumeratorW(): _wildcard(NName::kAnyStringWildcard) {}
+ CEnumeratorW(const UString &wildcard): _wildcard(wildcard) {}
+ bool Next(CFileInfoW &fileInfo);
+};
+#endif
+
+class CFindChangeNotification
+{
+ HANDLE _handle;
+public:
+ operator HANDLE () { return _handle; }
+ CFindChangeNotification(): _handle(INVALID_HANDLE_VALUE) {}
+ ~CFindChangeNotification() { Close(); }
+ bool Close();
+ HANDLE FindFirst(LPCTSTR pathName, bool watchSubtree, DWORD notifyFilter);
+ #ifndef _UNICODE
+ HANDLE FindFirst(LPCWSTR pathName, bool watchSubtree, DWORD notifyFilter);
+ #endif
+ bool FindNext()
+ { return BOOLToBool(::FindNextChangeNotification(_handle)); }
+};
+
+#ifndef _WIN32_WCE
+bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings);
+#endif
+
+inline bool MyGetCompressedFileSize(LPCTSTR fileName, UINT64 &size)
+{
+ DWORD highPart;
+ DWORD lowPart = ::GetCompressedFileSize(fileName, &highPart);
+ if (lowPart == INVALID_FILE_SIZE)
+ if (::GetLastError() != NO_ERROR)
+ return false;
+ size = (UINT64(highPart) << 32) | lowPart;
+ return true;
+}
+
+inline bool MyGetCompressedFileSizeW(LPCWSTR fileName, UINT64 &size)
+{
+ DWORD highPart;
+ DWORD lowPart = ::GetCompressedFileSizeW(fileName, &highPart);
+ if (lowPart == INVALID_FILE_SIZE)
+ if (::GetLastError() != NO_ERROR)
+ return false;
+ size = (UINT64(highPart) << 32) | lowPart;
+ return true;
+}
+
+}}}
+
+#endif
+
diff --git a/Windows/FileIO.cpp b/Windows/FileIO.cpp
new file mode 100755
index 00000000..7b7c960c
--- /dev/null
+++ b/Windows/FileIO.cpp
@@ -0,0 +1,219 @@
+// Windows/FileIO.cpp
+
+#include "StdAfx.h"
+
+#include "FileIO.h"
+#include "Defs.h"
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+namespace NWindows {
+namespace NFile {
+namespace NIO {
+
+CFileBase::~CFileBase()
+{
+ Close();
+}
+
+bool CFileBase::Create(LPCTSTR fileName, DWORD desiredAccess,
+ DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+{
+ Close();
+ _handle = ::CreateFile(fileName, desiredAccess, shareMode,
+ (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
+ flagsAndAttributes, (HANDLE) NULL);
+ _fileIsOpen = _handle != INVALID_HANDLE_VALUE;
+ return _fileIsOpen;
+}
+
+#ifndef _UNICODE
+bool CFileBase::Create(LPCWSTR fileName, DWORD desiredAccess,
+ DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+{
+ Close();
+ // MessageBoxW(0, fileName, 0, 0);
+ // ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ _handle = ::CreateFileW(fileName, desiredAccess, shareMode,
+ (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
+ flagsAndAttributes, (HANDLE) NULL);
+ if ((_handle == INVALID_HANDLE_VALUE || _handle == 0) &&
+ ::GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+ return Create(UnicodeStringToMultiByte(fileName, ::AreFileApisANSI() ? CP_ACP : CP_OEMCP),
+ desiredAccess, shareMode, creationDisposition, flagsAndAttributes);
+ return (_fileIsOpen = _handle != INVALID_HANDLE_VALUE);
+}
+#endif
+
+bool CFileBase::Close()
+{
+ if(!_fileIsOpen)
+ return true;
+ bool result = BOOLToBool(::CloseHandle(_handle));
+ _fileIsOpen = !result;
+ return result;
+}
+
+bool CFileBase::GetPosition(UINT64 &position) const
+{
+ return Seek(0, FILE_CURRENT, position);
+}
+
+bool CFileBase::GetLength(UINT64 &length) const
+{
+ DWORD sizeHigh;
+ DWORD sizeLow = ::GetFileSize(_handle, &sizeHigh);
+ if(sizeLow == 0xFFFFFFFF)
+ if(::GetLastError() != NO_ERROR )
+ return false;
+ length = (((UINT64)sizeHigh) << 32) + sizeLow;
+ return true;
+}
+
+bool CFileBase::Seek(INT64 distanceToMove, DWORD moveMethod, UINT64 &newPosition) const
+{
+ LARGE_INTEGER *pointer = (LARGE_INTEGER *)&distanceToMove;
+ pointer->LowPart = ::SetFilePointer(_handle, pointer->LowPart,
+ &pointer->HighPart, moveMethod);
+ if (pointer->LowPart == 0xFFFFFFFF)
+ if(::GetLastError() != NO_ERROR)
+ return false;
+ newPosition = *((UINT64 *)pointer);
+ return true;
+}
+
+bool CFileBase::Seek(UINT64 position, UINT64 &newPosition)
+{
+ return Seek(position, FILE_BEGIN, newPosition);
+}
+
+bool CFileBase::SeekToBegin()
+{
+ UINT64 newPosition;
+ return Seek(0, newPosition);
+}
+
+bool CFileBase::SeekToEnd(UINT64 &newPosition)
+{
+ return Seek(0, FILE_END, newPosition);
+}
+
+bool CFileBase::GetFileInformation(CByHandleFileInfo &fileInfo) const
+{
+ BY_HANDLE_FILE_INFORMATION winFileInfo;
+ if(!::GetFileInformationByHandle(_handle, &winFileInfo))
+ return false;
+ fileInfo.Attributes = winFileInfo.dwFileAttributes;
+ fileInfo.CreationTime = winFileInfo.ftCreationTime;
+ fileInfo.LastAccessTime = winFileInfo.ftLastAccessTime;
+ fileInfo.LastWriteTime = winFileInfo.ftLastWriteTime;
+ fileInfo.VolumeSerialNumber = winFileInfo.dwFileAttributes;
+ fileInfo.Size = (((UINT64)winFileInfo.nFileSizeHigh) << 32) +
+ winFileInfo.nFileSizeLow;
+ fileInfo.NumberOfLinks = winFileInfo.nNumberOfLinks;
+ fileInfo.FileIndex = (((UINT64)winFileInfo.nFileIndexHigh) << 32) +
+ winFileInfo.nFileIndexLow;
+ return true;
+}
+
+/////////////////////////
+// CInFile
+
+bool CInFile::Open(LPCTSTR fileName, DWORD shareMode,
+ DWORD creationDisposition, DWORD flagsAndAttributes)
+{
+ return Create(fileName, GENERIC_READ, shareMode,
+ creationDisposition, flagsAndAttributes);
+}
+
+bool CInFile::Open(LPCTSTR fileName)
+{
+ return Open(fileName, FILE_SHARE_READ, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL);
+}
+
+#ifndef _UNICODE
+bool CInFile::Open(LPCWSTR fileName, DWORD shareMode,
+ DWORD creationDisposition, DWORD flagsAndAttributes)
+{
+ return Create(fileName, GENERIC_READ, shareMode,
+ creationDisposition, flagsAndAttributes);
+}
+
+bool CInFile::Open(LPCWSTR fileName)
+{
+ return Open(fileName, FILE_SHARE_READ, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL);
+}
+#endif
+
+bool CInFile::Read(void *data, UINT32 size, UINT32 &processedSize)
+{
+ return BOOLToBool(::ReadFile(_handle, data, size,
+ (DWORD *)&processedSize, NULL));
+}
+
+/////////////////////////
+// COutFile
+
+bool COutFile::Open(LPCTSTR fileName, DWORD shareMode,
+ DWORD creationDisposition, DWORD flagsAndAttributes)
+{
+ return Create(fileName, GENERIC_WRITE, shareMode,
+ creationDisposition, flagsAndAttributes);
+}
+
+bool COutFile::Open(LPCTSTR fileName)
+{
+ return Open(fileName, FILE_SHARE_READ, m_CreationDisposition, FILE_ATTRIBUTE_NORMAL);
+}
+
+#ifndef _UNICODE
+
+bool COutFile::Open(LPCWSTR fileName, DWORD shareMode,
+ DWORD creationDisposition, DWORD flagsAndAttributes)
+{
+ return Create(fileName, GENERIC_WRITE, shareMode,
+ creationDisposition, flagsAndAttributes);
+}
+
+bool COutFile::Open(LPCWSTR fileName)
+{
+ return Open(fileName, FILE_SHARE_READ, m_CreationDisposition, FILE_ATTRIBUTE_NORMAL);
+}
+
+#endif
+
+bool COutFile::SetTime(const FILETIME *creationTime,
+ const FILETIME *lastAccessTime, const FILETIME *lastWriteTime)
+{
+ return BOOLToBool(::SetFileTime(_handle, creationTime,
+ lastAccessTime, lastWriteTime));
+}
+
+bool COutFile::SetLastWriteTime(const FILETIME *lastWriteTime)
+{
+ return SetTime(NULL, NULL, lastWriteTime);
+}
+
+bool COutFile::Write(const void *data, UINT32 size, UINT32 &processedSize)
+{
+ return BOOLToBool(::WriteFile(_handle, data, size,
+ (DWORD *)&processedSize, NULL));
+}
+
+bool COutFile::SetEndOfFile()
+{
+ return BOOLToBool(::SetEndOfFile(_handle));
+}
+
+bool COutFile::SetLength(UINT64 length)
+{
+ UINT64 newPosition;
+ if(!Seek(length, newPosition))
+ return false;
+ if(newPosition != length)
+ return false;
+ return SetEndOfFile();
+}
+
+}}}
diff --git a/Windows/FileIO.h b/Windows/FileIO.h
new file mode 100755
index 00000000..a8360c0c
--- /dev/null
+++ b/Windows/FileIO.h
@@ -0,0 +1,98 @@
+// Windows/FileIO.h
+
+#pragma once
+
+#ifndef __WINDOWS_FILEIO_H
+#define __WINDOWS_FILEIO_H
+
+namespace NWindows {
+namespace NFile {
+namespace NIO {
+
+struct CByHandleFileInfo
+{
+ DWORD Attributes;
+ FILETIME CreationTime;
+ FILETIME LastAccessTime;
+ FILETIME LastWriteTime;
+ DWORD VolumeSerialNumber;
+ UINT64 Size;
+ DWORD NumberOfLinks;
+ UINT64 FileIndex;
+};
+
+class CFileBase
+{
+protected:
+ bool _fileIsOpen;
+ HANDLE _handle;
+ bool Create(LPCTSTR fileName, DWORD desiredAccess,
+ DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ #ifndef _UNICODE
+ bool Create(LPCWSTR fileName, DWORD desiredAccess,
+ DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ #endif
+
+public:
+ CFileBase():
+ _fileIsOpen(false){};
+ virtual ~CFileBase();
+
+ virtual bool Close();
+
+ bool GetPosition(UINT64 &position) const;
+ bool GetLength(UINT64 &length) const;
+
+ bool Seek(INT64 distanceToMove, DWORD moveMethod, UINT64 &newPosition) const;
+ bool Seek(UINT64 position, UINT64 &newPosition);
+ bool SeekToBegin();
+ bool SeekToEnd(UINT64 &newPosition);
+
+ bool GetFileInformation(CByHandleFileInfo &fileInfo) const;
+};
+
+class CInFile: public CFileBase
+{
+public:
+ bool Open(LPCTSTR fileName, DWORD shareMode,
+ DWORD creationDisposition, DWORD flagsAndAttributes);
+ bool Open(LPCTSTR fileName);
+ #ifndef _UNICODE
+ bool Open(LPCWSTR fileName, DWORD shareMode,
+ DWORD creationDisposition, DWORD flagsAndAttributes);
+ bool Open(LPCWSTR fileName);
+ #endif
+ bool Read(void *data, UINT32 size, UINT32 &processedSize);
+};
+
+class COutFile: public CFileBase
+{
+ DWORD m_CreationDisposition;
+public:
+ COutFile(): m_CreationDisposition(CREATE_NEW){};
+ bool Open(LPCTSTR fileName, DWORD shareMode,
+ DWORD creationDisposition, DWORD flagsAndAttributes);
+ bool Open(LPCTSTR fileName);
+
+ #ifndef _UNICODE
+ bool Open(LPCWSTR fileName, DWORD shareMode,
+ DWORD creationDisposition, DWORD flagsAndAttributes);
+ bool Open(LPCWSTR fileName);
+ #endif
+
+ void SetOpenCreationDisposition(DWORD creationDisposition)
+ { m_CreationDisposition = creationDisposition; }
+ void SetOpenCreationDispositionCreateAlways()
+ { m_CreationDisposition = CREATE_ALWAYS; }
+
+ bool SetTime(const FILETIME *creationTime,
+ const FILETIME *lastAccessTime, const FILETIME *lastWriteTime);
+ bool SetLastWriteTime(const FILETIME *lastWriteTime);
+ bool Write(const void *data, UINT32 size, UINT32 &processedSize);
+ bool SetEndOfFile();
+ bool SetLength(UINT64 length);
+};
+
+}}}
+
+#endif
diff --git a/Windows/FileMapping.cpp b/Windows/FileMapping.cpp
new file mode 100755
index 00000000..ead26c78
--- /dev/null
+++ b/Windows/FileMapping.cpp
@@ -0,0 +1,14 @@
+// Windows/FileIO.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/FileMapping.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NMapping {
+
+
+
+
+}}} \ No newline at end of file
diff --git a/Windows/FileMapping.h b/Windows/FileMapping.h
new file mode 100755
index 00000000..7d201597
--- /dev/null
+++ b/Windows/FileMapping.h
@@ -0,0 +1,52 @@
+// Windows/FileMapping.h
+
+#pragma once
+
+#ifndef __WINDOWS_FILEMAPPING_H
+#define __WINDOWS_FILEMAPPING_H
+
+#include "Windows/Handle.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+// namespace NFile {
+// namespace NMapping {
+
+class CFileMapping: public CHandle
+{
+public:
+ bool Create(HANDLE file, LPSECURITY_ATTRIBUTES attributes,
+ DWORD protect, UINT64 maximumSize, LPCTSTR name)
+ {
+ _handle = ::CreateFileMapping(file, attributes,
+ protect, DWORD(maximumSize >> 32), DWORD(maximumSize), name);
+ return (_handle != NULL);
+ }
+
+ bool Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)
+ {
+ _handle = ::OpenFileMapping(desiredAccess, BoolToBOOL(inheritHandle), name);
+ return (_handle != NULL);
+ }
+
+ LPVOID MapViewOfFile(DWORD desiredAccess, UINT64 fileOffset,
+ SIZE_T numberOfBytesToMap)
+ {
+ return ::MapViewOfFile(_handle, desiredAccess,
+ DWORD(fileOffset >> 32), DWORD(fileOffset), numberOfBytesToMap);
+ }
+
+ LPVOID MapViewOfFileEx(DWORD desiredAccess, UINT64 fileOffset,
+ SIZE_T numberOfBytesToMap, LPVOID baseAddress)
+ {
+ return ::MapViewOfFileEx(_handle, desiredAccess,
+ DWORD(fileOffset >> 32), DWORD(fileOffset),
+ numberOfBytesToMap, baseAddress);
+ }
+
+
+};
+
+}
+
+#endif
diff --git a/Windows/FileName.cpp b/Windows/FileName.cpp
new file mode 100755
index 00000000..945caef8
--- /dev/null
+++ b/Windows/FileName.cpp
@@ -0,0 +1,111 @@
+// Windows/FileName.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/FileName.h"
+#include "Common/WildCard.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NName {
+
+static const wchar_t kDiskDelimiter = L':';
+
+/*
+static bool IsCharAPrefixDelimiter(wchar_t c)
+ { return (c == kDirDelimiter || c == kDiskDelimiter); }
+*/
+
+void NormalizeDirPathPrefix(CSysString &dirPath)
+{
+ if (dirPath.IsEmpty())
+ return;
+ if (dirPath.ReverseFind(kDirDelimiter) != dirPath.Length() - 1)
+ dirPath += kDirDelimiter;
+}
+
+#ifndef _UNICODE
+void NormalizeDirPathPrefix(UString &dirPath)
+{
+ if (dirPath.IsEmpty())
+ return;
+ if (dirPath.ReverseFind(wchar_t(kDirDelimiter)) != dirPath.Length() - 1)
+ dirPath += wchar_t(kDirDelimiter);
+}
+#endif
+
+namespace NPathType
+{
+ EEnum GetPathType(const UString &path)
+ {
+ if (path.Length() <= 2)
+ return kLocal;
+ if (path[0] == kDirDelimiter && path[1] == kDirDelimiter)
+ return kUNC;
+ return kLocal;
+ }
+}
+
+void CParsedPath::ParsePath(const UString &path)
+{
+ int curPos = 0;
+ switch (NPathType::GetPathType(path))
+ {
+ case NPathType::kLocal:
+ {
+ int posDiskDelimiter = path.Find(kDiskDelimiter);
+ if(posDiskDelimiter >= 0)
+ {
+ curPos = posDiskDelimiter + 1;
+ if (path.Length() > curPos)
+ if(path[curPos] == kDirDelimiter)
+ curPos++;
+ }
+ break;
+ }
+ case NPathType::kUNC:
+ {
+ int curPos = path.Find(kDirDelimiter, 2);
+ if(curPos < 0)
+ curPos = path.Length();
+ else
+ curPos++;
+ }
+ }
+ Prefix = path.Left(curPos);
+ SplitPathToParts(path.Mid(curPos), PathParts);
+}
+
+UString CParsedPath::MergePath() const
+{
+ UString result = Prefix;
+ for(int i = 0; i < PathParts.Size(); i++)
+ {
+ if (i != 0)
+ result += kDirDelimiter;
+ result += PathParts[i];
+ }
+ return result;
+}
+
+const wchar_t kExtensionDelimiter = L'.';
+
+void SplitNameToPureNameAndExtension(const UString &fullName,
+ UString &pureName, UString &extensionDelimiter, UString &extension)
+{
+ int index = fullName.ReverseFind(kExtensionDelimiter);
+ if (index < 0)
+ {
+ pureName = fullName;
+ extensionDelimiter.Empty();
+ extension.Empty();
+ }
+ else
+ {
+ pureName = fullName.Left(index);
+ extensionDelimiter = kExtensionDelimiter;
+ extension = fullName.Mid(index + 1);
+ }
+}
+
+}}}
diff --git a/Windows/FileName.h b/Windows/FileName.h
new file mode 100755
index 00000000..8adf684c
--- /dev/null
+++ b/Windows/FileName.h
@@ -0,0 +1,45 @@
+// Windows/FileName.h
+
+#pragma once
+
+#ifndef __WINDOWS_FILENAME_H
+#define __WINDOWS_FILENAME_H
+
+#include "../Common/String.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NName {
+
+const TCHAR kDirDelimiter = '\\';
+const TCHAR kAnyStringWildcard = '*';
+
+void NormalizeDirPathPrefix(CSysString &dirPath); // ensures that it ended with '\\'
+#ifndef _UNICODE
+void NormalizeDirPathPrefix(UString &dirPath); // ensures that it ended with '\\'
+#endif
+
+namespace NPathType
+{
+ enum EEnum
+ {
+ kLocal,
+ kUNC
+ };
+ EEnum GetPathType(const UString &path);
+}
+
+struct CParsedPath
+{
+ UString Prefix; // Disk or UNC with slash
+ UStringVector PathParts;
+ void ParsePath(const UString &path);
+ UString MergePath() const;
+};
+
+void SplitNameToPureNameAndExtension(const UString &fullName,
+ UString &pureName, UString &extensionDelimiter, UString &extension);
+
+}}}
+
+#endif
diff --git a/Windows/FileSystem.cpp b/Windows/FileSystem.cpp
new file mode 100755
index 00000000..2f35524d
--- /dev/null
+++ b/Windows/FileSystem.cpp
@@ -0,0 +1,77 @@
+// Windows/FileSystem.cpp
+
+#include "StdAfx.h"
+
+#include "FileSystem.h"
+#include "Defs.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NSystem {
+
+bool MyGetVolumeInformation(
+ LPCTSTR rootPathName,
+ CSysString &volumeName,
+ LPDWORD volumeSerialNumber,
+ LPDWORD maximumComponentLength,
+ LPDWORD fileSystemFlags,
+ CSysString &fileSystemName)
+{
+ bool result = BOOLToBool(GetVolumeInformation(
+ rootPathName,
+ volumeName.GetBuffer(MAX_PATH), MAX_PATH,
+ volumeSerialNumber,
+ maximumComponentLength,
+ fileSystemFlags,
+ fileSystemName.GetBuffer(MAX_PATH), MAX_PATH));
+ volumeName.ReleaseBuffer();
+ fileSystemName.ReleaseBuffer();
+ return result;
+}
+
+typedef BOOL (WINAPI * GetDiskFreeSpaceExPointer)(
+ LPCTSTR lpDirectoryName, // directory name
+ PULARGE_INTEGER lpFreeBytesAvailable, // bytes available to caller
+ PULARGE_INTEGER lpTotalNumberOfBytes, // bytes on disk
+ PULARGE_INTEGER lpTotalNumberOfFreeBytes // free bytes on disk
+);
+
+bool MyGetDiskFreeSpace(LPCTSTR rootPathName,
+ UINT64 &clusterSize, UINT64 &totalSize, UINT64 &freeSize)
+{
+ GetDiskFreeSpaceExPointer pGetDiskFreeSpaceEx =
+ (GetDiskFreeSpaceExPointer)GetProcAddress(
+ GetModuleHandle(TEXT("kernel32.dll")), "GetDiskFreeSpaceExA");
+
+ bool sizeIsDetected = false;
+ if (pGetDiskFreeSpaceEx)
+ {
+ UINT64 i64FreeBytesToCaller;
+ sizeIsDetected = BOOLToBool(pGetDiskFreeSpaceEx(rootPathName,
+ (PULARGE_INTEGER)&i64FreeBytesToCaller,
+ (PULARGE_INTEGER)&totalSize,
+ (PULARGE_INTEGER)&freeSize));
+ }
+
+ DWORD numSectorsPerCluster;
+ DWORD bytesPerSector;
+ DWORD numberOfFreeClusters;
+ DWORD totalNumberOfClusters;
+
+ if (!::GetDiskFreeSpace(rootPathName,
+ &numSectorsPerCluster,
+ &bytesPerSector,
+ &numberOfFreeClusters,
+ &totalNumberOfClusters))
+ return false;
+
+ clusterSize = UINT64(bytesPerSector) * UINT64(numSectorsPerCluster);
+ if (!sizeIsDetected)
+ {
+ totalSize = clusterSize * UINT64(totalNumberOfClusters);
+ freeSize = clusterSize * UINT64(numberOfFreeClusters);
+ }
+ return true;
+}
+
+}}}
diff --git a/Windows/FileSystem.h b/Windows/FileSystem.h
new file mode 100755
index 00000000..5a630d95
--- /dev/null
+++ b/Windows/FileSystem.h
@@ -0,0 +1,28 @@
+// Windows/FileSystem.h
+
+#pragma once
+
+#ifndef __WINDOWS_FILESYSTEM_H
+#define __WINDOWS_FILESYSTEM_H
+
+#include "../Common/String.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NSystem {
+
+bool MyGetVolumeInformation(
+ LPCTSTR rootPathName,
+ CSysString &volumeName,
+ LPDWORD volumeSerialNumber,
+ LPDWORD maximumComponentLength,
+ LPDWORD fileSystemFlags,
+ CSysString &fileSystemName);
+
+bool MyGetDiskFreeSpace(LPCTSTR rootPathName,
+ UINT64 &clusterSize, UINT64 &totalSize, UINT64 &freeSize);
+
+}}}
+
+#endif
+
diff --git a/Windows/Handle.h b/Windows/Handle.h
new file mode 100755
index 00000000..66c893e9
--- /dev/null
+++ b/Windows/Handle.h
@@ -0,0 +1,39 @@
+// Windows/Handle.h
+
+#pragma once
+
+#ifndef __WINDOWS_HANDLE_H
+#define __WINDOWS_HANDLE_H
+
+namespace NWindows {
+
+class CHandle
+{
+protected:
+ HANDLE _handle;
+public:
+ operator HANDLE() { return _handle; }
+ CHandle(): _handle(NULL) {}
+ ~CHandle() { Close(); }
+ bool Close()
+ {
+ if (_handle == NULL)
+ return true;
+ if (!::CloseHandle(_handle))
+ return false;
+ _handle = NULL;
+ return true;
+ }
+ void Attach(HANDLE handle)
+ { _handle = handle; }
+ HANDLE Detach()
+ {
+ HANDLE handle = _handle;
+ _handle = NULL;
+ return handle;
+ }
+};
+
+}
+
+#endif
diff --git a/Windows/ItemIDListUtils.cpp b/Windows/ItemIDListUtils.cpp
new file mode 100755
index 00000000..a429464e
--- /dev/null
+++ b/Windows/ItemIDListUtils.cpp
@@ -0,0 +1,166 @@
+// ItemIDListUtils.h
+
+#include "StdAfx.h"
+
+#include "ItemIDListUtils.h"
+
+namespace NItemIDList {
+
+CHolder::CHolder(const CHolder& anItemIDList):
+ m_Object(NULL)
+{
+ *this = anItemIDList;
+}
+
+bool CHolder::Create(UINT16 aPureSize)
+{
+ Free();
+ m_Object = LPITEMIDLIST(CoTaskMemAlloc(2 + aPureSize + 2));
+ if(m_Object == NULL)
+ return false;
+ m_Object->mkid.cb = 2 + aPureSize;
+ LPITEMIDLIST aNewIDListEnd = LPITEMIDLIST(((BYTE *)m_Object) + 2 + aPureSize);
+ aNewIDListEnd->mkid.cb = 0;
+ return (m_Object != NULL);
+}
+
+void CHolder::Free()
+{
+ if(m_Object == NULL)
+ return;
+ CoTaskMemFree(m_Object);
+ m_Object = NULL;
+}
+
+CHolder& CHolder::operator=(LPCITEMIDLIST anObject)
+{
+ if(m_Object != NULL)
+ Free();
+ UINT32 aSize = GetSize(anObject);
+ m_Object = (LPITEMIDLIST)CoTaskMemAlloc(aSize);
+ if(m_Object != NULL)
+ MoveMemory(m_Object, anObject, aSize);
+ return *this;
+}
+
+CHolder& CHolder::operator=(const CHolder &anObject)
+{
+ if(m_Object != NULL)
+ Free();
+ if(anObject.m_Object != NULL)
+ {
+ UINT32 aSize = GetSize(anObject.m_Object);
+ m_Object = (LPITEMIDLIST)CoTaskMemAlloc(aSize);
+ if(m_Object != NULL)
+ MoveMemory(m_Object, anObject.m_Object, aSize);
+ }
+ return *this;
+}
+
+////////////////////////
+// static
+
+LPITEMIDLIST GetNextItem(LPCITEMIDLIST anIDList)
+{
+ if (anIDList)
+ return (LPITEMIDLIST)(LPBYTE) ( ((LPBYTE)anIDList) + anIDList->mkid.cb);
+ return (NULL);
+}
+
+UINT32 GetSize(LPCITEMIDLIST anIDList)
+{
+ UINT32 aSizeTotal = 0;
+ if(anIDList != NULL)
+ {
+ while(anIDList->mkid.cb != 0)
+ {
+ aSizeTotal += anIDList->mkid.cb;
+ anIDList = GetNextItem(anIDList);
+ }
+ aSizeTotal += sizeof(ITEMIDLIST) - 1;
+ }
+ return (aSizeTotal);
+}
+
+LPITEMIDLIST GetLastItem(LPCITEMIDLIST anIDList)
+{
+ LPITEMIDLIST anIDListLast = NULL;
+ if(anIDList)
+ while(anIDList->mkid.cb != 0)
+ {
+ anIDListLast = (LPITEMIDLIST)anIDList;
+ anIDList = GetNextItem(anIDList);
+ }
+ return anIDListLast;
+}
+
+}
+
+////////////////////////////////////////////////////////////////
+// CItemIDListManager : Class to manage pidls
+
+CItemIDListManager::CItemIDListManager():
+ m_pMalloc(NULL)
+{
+ SHGetMalloc(&m_pMalloc);
+}
+
+CItemIDListManager::~CItemIDListManager()
+{
+ if (m_pMalloc)
+ m_pMalloc->Release();
+}
+
+LPITEMIDLIST CItemIDListManager::Create(UINT16 aPureSize)
+{
+ LPITEMIDLIST aPointer = LPITEMIDLIST(m_pMalloc->Alloc(2 + aPureSize + 2));
+ if(aPointer == NULL)
+ return NULL;
+ aPointer->mkid.cb = 2 + aPureSize;
+ LPITEMIDLIST aNewIDListEnd = LPITEMIDLIST(((BYTE *)aPointer) + 2 + aPureSize);
+ aNewIDListEnd->mkid.cb = 0;
+ return aPointer;
+}
+
+void CItemIDListManager::Delete(LPITEMIDLIST anIDList)
+{
+ m_pMalloc->Free(anIDList);
+}
+
+LPITEMIDLIST CItemIDListManager::Copy(LPCITEMIDLIST anIDListSrc)
+{
+ if (NULL == anIDListSrc)
+ return (NULL);
+ LPITEMIDLIST anIDListTarget = NULL;
+ UINT32 aSize = NItemIDList::GetSize(anIDListSrc);
+ anIDListTarget = (LPITEMIDLIST)m_pMalloc->Alloc(aSize);
+ if (!anIDListTarget)
+ return (NULL);
+ MoveMemory(anIDListTarget, anIDListSrc, aSize);
+ return anIDListTarget;
+}
+
+LPITEMIDLIST CItemIDListManager::Concatenate(LPCITEMIDLIST anIDList1,
+ LPCITEMIDLIST anIDList2)
+{
+ if(!anIDList1 && !anIDList2)
+ return NULL;
+
+ if(!anIDList1)
+ return Copy(anIDList2);
+
+ if(!anIDList2)
+ return Copy(anIDList1);
+
+ UINT32 cb1 = NItemIDList::GetSize(anIDList1) - 2;
+ UINT32 cb2 = NItemIDList::GetSize(anIDList2);
+
+ LPITEMIDLIST anIDListNew = (LPITEMIDLIST)m_pMalloc->Alloc(cb1 + cb2);
+
+ if(anIDListNew)
+ {
+ MoveMemory(anIDListNew, anIDList1, cb1);
+ MoveMemory(((LPBYTE)anIDListNew) + cb1, anIDList2, cb2);
+ }
+ return anIDListNew;
+}
diff --git a/Windows/ItemIDListUtils.h b/Windows/ItemIDListUtils.h
new file mode 100755
index 00000000..53721d41
--- /dev/null
+++ b/Windows/ItemIDListUtils.h
@@ -0,0 +1,98 @@
+// ItemIDListUtils.h
+
+#pragma once
+
+#ifndef __ITEMIDLISTUTILS_H
+#define __ITEMIDLISTUTILS_H
+
+#include "Common/Types.h"
+
+/////////////////////////////
+// It is not for shell using
+// It's for internal using only
+// since it uses CoTaskMemFree instead SHGetMalloc
+
+namespace NItemIDList {
+
+LPITEMIDLIST GetNextItem(LPCITEMIDLIST anIDList);
+UINT32 GetSize(LPCITEMIDLIST anIDList);
+LPITEMIDLIST GetLastItem(LPCITEMIDLIST anIDList);
+
+class CHolder
+{
+ LPITEMIDLIST m_Object;
+public:
+ CHolder(): m_Object(NULL) {}
+ CHolder(const CHolder& anItemIDList);
+ ~CHolder() { Free(); }
+ void Attach(LPITEMIDLIST anObject)
+ {
+ if (m_Object != NULL)
+ Free();
+ m_Object = anObject;
+ }
+ LPITEMIDLIST Detach()
+ {
+ LPITEMIDLIST anObject = m_Object;
+ m_Object = NULL;
+ return anObject;
+ }
+ void Free();
+ bool Create(UINT16 aPureSize);
+ operator LPITEMIDLIST() { return m_Object;}
+ operator LPCITEMIDLIST() const { return m_Object;}
+ LPITEMIDLIST* operator&() { return &m_Object; }
+ LPITEMIDLIST operator->() { return m_Object; }
+
+ CHolder& operator=(LPCITEMIDLIST anObject);
+ CHolder& operator=(const CHolder &anObject);
+};
+
+}
+
+class CItemIDListManager
+{
+public:
+ CItemIDListManager();
+ ~CItemIDListManager();
+public:
+ LPITEMIDLIST Create(UINT16 aPureSize);
+ void Delete(LPITEMIDLIST anIDList);
+ LPITEMIDLIST Copy(LPCITEMIDLIST anIDListSrc);
+ // CZipIDData* GetDataPointer(LPCITEMIDLIST anIDList);
+ LPITEMIDLIST Concatenate(LPCITEMIDLIST anIDList1, LPCITEMIDLIST anIDList2);
+private:
+ LPMALLOC m_pMalloc;
+};
+
+class CShellItemIDList
+{
+ CItemIDListManager *m_Manager;
+ LPITEMIDLIST m_Object;
+public:
+ CShellItemIDList(CItemIDListManager *aManager):
+ m_Manager(aManager),
+ m_Object(NULL) {}
+ bool Create(UINT16 aPureSize)
+ {
+ Free();
+ m_Object = m_Manager->Create(aPureSize);
+ return (m_Object != NULL);
+ }
+ ~CShellItemIDList() { Free(); }
+ void Free()
+ {
+ if(m_Object != NULL)
+ m_Manager->Delete(m_Object);
+ m_Object = NULL;
+ }
+ void Attach(LPITEMIDLIST anObject)
+ {
+ Free();
+ m_Object = anObject;
+ }
+ operator LPITEMIDLIST() { return m_Object;}
+ LPITEMIDLIST* operator&() { return &m_Object; }
+};
+
+#endif \ No newline at end of file
diff --git a/Windows/Memory.cpp b/Windows/Memory.cpp
new file mode 100755
index 00000000..faef9934
--- /dev/null
+++ b/Windows/Memory.cpp
@@ -0,0 +1,59 @@
+// Windows/Memory.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/Memory.h"
+
+namespace NWindows {
+namespace NMemory {
+
+CGlobal::~CGlobal()
+{
+ Free();
+}
+
+// aFlags = GMEM_MOVEABLE
+bool CGlobal::Alloc(UINT aFlags, DWORD aSize)
+{
+ HGLOBAL aNewBlock = ::GlobalAlloc(aFlags, aSize);
+ if (aNewBlock == NULL)
+ return false;
+ m_MemoryHandle = aNewBlock;
+ return true;
+}
+
+bool CGlobal::Free()
+{
+ if (m_MemoryHandle == NULL)
+ return true;
+ m_MemoryHandle = ::GlobalFree(m_MemoryHandle);
+ return (m_MemoryHandle == NULL);
+}
+
+HGLOBAL CGlobal::Detach()
+{
+ HGLOBAL aHandle = m_MemoryHandle;
+ m_MemoryHandle = NULL;
+ return aHandle;
+}
+
+LPVOID CGlobal::Lock() const
+{
+ return ::GlobalLock(m_MemoryHandle);
+}
+
+void CGlobal::Unlock() const
+{
+ ::GlobalUnlock(m_MemoryHandle);
+}
+
+bool CGlobal::ReAlloc(DWORD aSize)
+{
+ HGLOBAL aNewBlock = ::GlobalReAlloc(m_MemoryHandle, aSize, GMEM_MOVEABLE);
+ if (aNewBlock == NULL)
+ return false;
+ m_MemoryHandle = aNewBlock;
+ return true;
+}
+
+}}
diff --git a/Windows/Memory.h b/Windows/Memory.h
new file mode 100755
index 00000000..1a8dde45
--- /dev/null
+++ b/Windows/Memory.h
@@ -0,0 +1,46 @@
+// Windows/Memory.h
+
+#pragma once
+
+#ifndef __WINDOWS_MEMORY_H
+#define __WINDOWS_MEMORY_H
+
+namespace NWindows {
+namespace NMemory {
+
+class CGlobal
+{
+ HGLOBAL m_MemoryHandle;
+public:
+ CGlobal():m_MemoryHandle(NULL){};
+ ~CGlobal();
+ operator HGLOBAL() const { return m_MemoryHandle; };
+ HGLOBAL Detach();
+ bool Alloc(UINT aFlags, DWORD aSize);
+ bool Free();
+ LPVOID Lock() const;
+ void Unlock() const;
+ bool ReAlloc(DWORD aSize);
+};
+
+
+class CGlobalLock
+{
+ const HGLOBAL m_Global;
+ LPVOID m_Pointer;
+public:
+ LPVOID GetPointer() const { return m_Pointer; }
+ CGlobalLock(HGLOBAL aGlobal): m_Global(aGlobal)
+ {
+ m_Pointer = ::GlobalLock(m_Global);
+ };
+ ~CGlobalLock()
+ {
+ if(m_Pointer != NULL)
+ ::GlobalUnlock(m_Global);
+ }
+};
+
+}}
+
+#endif
diff --git a/Windows/Menu.h b/Windows/Menu.h
new file mode 100755
index 00000000..55d33447
--- /dev/null
+++ b/Windows/Menu.h
@@ -0,0 +1,108 @@
+// Windows/Menu.h
+
+#pragma once
+
+#ifndef __WINDOWS_MENU_H
+#define __WINDOWS_MENU_H
+
+#include "Common/String.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+
+class CMenu
+{
+ HMENU _menu;
+public:
+ CMenu(): _menu(NULL) {};
+ operator HMENU() const { return _menu; }
+ void Attach(HMENU menu) { _menu = menu; }
+
+ HMENU Detach()
+ {
+ HMENU menu = _menu;
+ _menu = NULL;
+ return menu;
+ }
+
+ bool Create()
+ {
+ _menu = ::CreateMenu();
+ return (_menu != NULL);
+ }
+
+ bool CreatePopup()
+ {
+ _menu = ::CreatePopupMenu();
+ return (_menu != NULL);
+ }
+
+ bool Destroy()
+ {
+ if (_menu == NULL)
+ return false;
+ return BOOLToBool(::DestroyMenu(Detach()));
+ }
+
+ int GetItemCount()
+ { return GetMenuItemCount(_menu); }
+
+ HMENU GetSubMenu(int pos)
+ { return ::GetSubMenu(_menu, pos); }
+ bool GetItemString(UINT idItem, UINT flag, CSysString &result)
+ {
+ result.Empty();
+ int len = ::GetMenuString(_menu, idItem, 0, 0, flag);
+ len = ::GetMenuString(_menu, idItem, result.GetBuffer(len + 2),
+ len + 1, flag);
+ result.ReleaseBuffer();
+ return (len != 0);
+ }
+ UINT GetItemID(int pos)
+ { return ::GetMenuItemID(_menu, pos); }
+ UINT GetItemState(UINT id, UINT flags)
+ { return ::GetMenuState(_menu, id, flags); }
+
+ bool AppendItem(UINT flags, UINT_PTR newItemID, LPCTSTR newItem)
+ { return BOOLToBool(::AppendMenu(_menu, flags, newItemID, newItem)); }
+
+ bool Insert(UINT position, UINT flags, UINT_PTR idNewItem, LPCTSTR newItem)
+ { return BOOLToBool(::InsertMenu(_menu, position, flags, idNewItem, newItem)); }
+
+ bool InsertItem(UINT itemIndex, bool byPosition, LPCMENUITEMINFO itemInfo)
+ { return BOOLToBool(::InsertMenuItem(_menu, itemIndex,
+ BoolToBOOL(byPosition), itemInfo)); }
+
+ bool RemoveItem(UINT item, UINT flags)
+ { return BOOLToBool(::RemoveMenu(_menu, item, flags)); }
+
+ bool GetItemInfo(UINT itemIndex, bool byPosition, LPMENUITEMINFO itemInfo)
+ { return BOOLToBool(::GetMenuItemInfo(_menu, itemIndex,
+ BoolToBOOL(byPosition), itemInfo)); }
+ bool SetItemInfo(UINT itemIndex, bool byPosition, LPMENUITEMINFO itemInfo)
+ { return BOOLToBool(::SetMenuItemInfo(_menu, itemIndex,
+ BoolToBOOL(byPosition), itemInfo)); }
+
+ int Track(UINT flags, int x, int y, HWND hWnd)
+ { return ::TrackPopupMenuEx(_menu, flags, x, y, hWnd, NULL); }
+
+ bool CheckRadioItem(UINT idFirst, UINT idLast, UINT idCheck, UINT flags)
+ { return BOOLToBool(::CheckMenuRadioItem(_menu, idFirst, idLast, idCheck, flags)); }
+ DWORD CheckItem(UINT id, UINT uCheck)
+ { return ::CheckMenuItem(_menu, id, uCheck); }
+};
+
+class CMenuDestroyer
+{
+ CMenu *_menu;
+public:
+ CMenuDestroyer(CMenu &menu): _menu(&menu) {}
+ CMenuDestroyer(): _menu(0) {}
+ ~CMenuDestroyer() { if (_menu) _menu->Destroy(); }
+ void Attach(CMenu &menu) { _menu = &menu; }
+ void Disable() { _menu = 0; }
+};
+
+}
+
+#endif
diff --git a/Windows/NationalTime.cpp b/Windows/NationalTime.cpp
new file mode 100755
index 00000000..76060216
--- /dev/null
+++ b/Windows/NationalTime.cpp
@@ -0,0 +1,37 @@
+// Windows/NationalTime.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/NationalTime.h"
+
+namespace NWindows {
+namespace NNational {
+namespace NTime {
+
+bool MyGetTimeFormat(LCID locale, DWORD flags, CONST SYSTEMTIME *time,
+ LPCTSTR format, CSysString &resultString)
+{
+ resultString.Empty();
+ int numChars = ::GetTimeFormat(locale, flags, time, format, NULL, 0);
+ if(numChars == 0)
+ return false;
+ numChars = ::GetTimeFormat(locale, flags, time, format,
+ resultString.GetBuffer(numChars), numChars + 1);
+ resultString.ReleaseBuffer();
+ return (numChars != 0);
+}
+
+bool MyGetDateFormat(LCID locale, DWORD flags, CONST SYSTEMTIME *time,
+ LPCTSTR format, CSysString &resultString)
+{
+ resultString.Empty();
+ int numChars = ::GetDateFormat(locale, flags, time, format, NULL, 0);
+ if(numChars == 0)
+ return false;
+ numChars = ::GetDateFormat(locale, flags, time, format,
+ resultString.GetBuffer(numChars), numChars + 1);
+ resultString.ReleaseBuffer();
+ return (numChars != 0);
+}
+
+}}}
diff --git a/Windows/NationalTime.h b/Windows/NationalTime.h
new file mode 100755
index 00000000..70d5967d
--- /dev/null
+++ b/Windows/NationalTime.h
@@ -0,0 +1,22 @@
+// Windows/NationalTime.h
+
+#pragma once
+
+#ifndef __WINDOWS_NATIONALTIME_H
+#define __WINDOWS_NATIONALTIME_H
+
+#include "Common/String.h"
+
+namespace NWindows {
+namespace NNational {
+namespace NTime {
+
+bool MyGetTimeFormat(LCID locale, DWORD flags, CONST SYSTEMTIME *time,
+ LPCTSTR format, CSysString &resultString);
+
+bool MyGetDateFormat(LCID locale, DWORD flags, CONST SYSTEMTIME *time,
+ LPCTSTR format, CSysString &resultString);
+
+}}}
+
+#endif
diff --git a/Windows/Net.cpp b/Windows/Net.cpp
new file mode 100755
index 00000000..febc1340
--- /dev/null
+++ b/Windows/Net.cpp
@@ -0,0 +1,158 @@
+// Windows/Net.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/Net.h"
+
+namespace NWindows {
+namespace NNet {
+
+DWORD CEnum::Open(DWORD scope, DWORD type, DWORD usage, LPNETRESOURCE netResource)
+{
+ Close();
+ DWORD result = ::WNetOpenEnum(scope, type, usage, netResource, &_handle);
+ _handleAllocated = (result == NO_ERROR);
+ return result;
+}
+
+static void SetComplexString(bool &defined, CSysString &destString,
+ LPCTSTR srsString)
+{
+ defined = (srsString != 0);
+ if (defined)
+ destString = srsString;
+ else
+ destString.Empty();
+}
+
+static void ConvertNETRESOURCEToCResource(const NETRESOURCE &netResource,
+ CResource &resource)
+{
+ resource.Scope = netResource.dwScope;
+ resource.Type = netResource.dwType;
+ resource.DisplayType = netResource.dwDisplayType;
+ resource.Usage = netResource.dwUsage;
+ SetComplexString(resource.LocalNameIsDefined, resource.LocalName, netResource.lpLocalName);
+ SetComplexString(resource.RemoteNameIsDefined, resource.RemoteName, netResource.lpRemoteName);
+ SetComplexString(resource.CommentIsDefined, resource.Comment, netResource.lpComment);
+ SetComplexString(resource.ProviderIsDefined, resource.Provider, netResource.lpProvider);
+}
+
+static void SetComplexString2(LPCTSTR &destString, bool defined,
+ const CSysString &srsString)
+{
+ if (defined)
+ destString = srsString;
+ else
+ destString = 0;
+}
+
+static void ConvertCResourceToNETRESOURCE(const CResource &resource,
+ NETRESOURCE &netResource)
+{
+ netResource.dwScope = resource.Scope;
+ netResource.dwType = resource.Type;
+ netResource.dwDisplayType = resource.DisplayType;
+ netResource.dwUsage = resource.Usage;
+ SetComplexString2(netResource.lpLocalName, resource.LocalNameIsDefined, resource.LocalName);
+ SetComplexString2(netResource.lpRemoteName, resource.RemoteNameIsDefined, resource.RemoteName);
+ SetComplexString2(netResource.lpComment, resource.CommentIsDefined, resource.Comment);
+ SetComplexString2(netResource.lpProvider, resource.ProviderIsDefined, resource.Provider);
+}
+
+DWORD CEnum::Open(DWORD scope, DWORD type, DWORD usage,
+ const CResource *resource)
+{
+ NETRESOURCE netResource;
+ LPNETRESOURCE pointer;
+ if (resource == 0)
+ pointer = 0;
+ else
+ {
+ ConvertCResourceToNETRESOURCE(*resource, netResource);
+ pointer = &netResource;
+ }
+ return Open(scope, type, usage, pointer);
+}
+
+DWORD CEnum::Close()
+{
+ if(!_handleAllocated)
+ return NO_ERROR;
+ DWORD result = ::WNetCloseEnum(_handle);
+ _handleAllocated = (result != NO_ERROR);
+ return result;
+}
+
+DWORD CEnum::Next(LPDWORD lpcCount, LPVOID lpBuffer, LPDWORD lpBufferSize)
+{
+ return ::WNetEnumResource(_handle, lpcCount, lpBuffer, lpBufferSize);
+}
+
+DWORD CEnum::Next(CResource &resource)
+{
+ CByteBuffer byteBuffer;
+ const DWORD kBufferSize = 16384;
+ byteBuffer.SetCapacity(kBufferSize);
+ LPNETRESOURCE lpnrLocal = (LPNETRESOURCE) (BYTE *)(byteBuffer);
+ ZeroMemory(lpnrLocal, kBufferSize);
+ DWORD bufferSize = kBufferSize;
+ DWORD numEntries = 1;
+ DWORD result = Next(&numEntries, lpnrLocal, &bufferSize);
+ if (result != NO_ERROR)
+ return result;
+ if (numEntries != 1)
+ return (DWORD)E_FAIL;
+ ConvertNETRESOURCEToCResource(lpnrLocal[0], resource);
+ return result;
+}
+
+DWORD GetResourceParent(const CResource &resource, CResource &parentResource)
+{
+ CByteBuffer byteBuffer;
+ const DWORD kBufferSize = 16384;
+ byteBuffer.SetCapacity(kBufferSize);
+ LPNETRESOURCE lpnrLocal = (LPNETRESOURCE) (BYTE *)(byteBuffer);
+ ZeroMemory(lpnrLocal, kBufferSize);
+ DWORD bufferSize = kBufferSize;
+ NETRESOURCE netResource;
+ ConvertCResourceToNETRESOURCE(resource, netResource);
+ DWORD result = ::WNetGetResourceParent(&netResource, lpnrLocal, &bufferSize);
+ if (result != NO_ERROR)
+ return result;
+ ConvertNETRESOURCEToCResource(lpnrLocal[0], parentResource);
+ return result;
+}
+
+DWORD GetResourceInformation(const CResource &resource,
+ CResource &destResource, CSysString &systemPathPart)
+{
+ CByteBuffer byteBuffer;
+ const DWORD kBufferSize = 16384;
+ byteBuffer.SetCapacity(kBufferSize);
+ LPNETRESOURCE lpnrLocal = (LPNETRESOURCE) (BYTE *)(byteBuffer);
+ ZeroMemory(lpnrLocal, kBufferSize);
+ DWORD bufferSize = kBufferSize;
+ NETRESOURCE netResource;
+ ConvertCResourceToNETRESOURCE(resource, netResource);
+ LPTSTR lplpSystem;
+ DWORD result = ::WNetGetResourceInformation(&netResource,
+ lpnrLocal, &bufferSize, &lplpSystem);
+ if (result != NO_ERROR)
+ return result;
+ if (lplpSystem != 0)
+ systemPathPart = lplpSystem;
+ ConvertNETRESOURCEToCResource(lpnrLocal[0], destResource);
+ return result;
+}
+
+DWORD AddConnection2(const CResource &resource,
+ LPCTSTR password, LPCTSTR userName, DWORD flags)
+{
+ NETRESOURCE netResource;
+ ConvertCResourceToNETRESOURCE(resource, netResource);
+ return ::WNetAddConnection2(&netResource,
+ password, userName, flags);
+}
+
+}}
diff --git a/Windows/Net.h b/Windows/Net.h
new file mode 100755
index 00000000..ead481be
--- /dev/null
+++ b/Windows/Net.h
@@ -0,0 +1,54 @@
+// Windows/Net.h
+
+#pragma once
+
+#ifndef __WINDOWS_NET_H
+#define __WINDOWS_NET_H
+
+#include "Common/Buffer.h"
+#include "Common/String.h"
+
+namespace NWindows {
+namespace NNet {
+
+struct CResource
+{
+ DWORD Scope;
+ DWORD Type;
+ DWORD DisplayType;
+ DWORD Usage;
+ bool LocalNameIsDefined;
+ bool RemoteNameIsDefined;
+ bool CommentIsDefined;
+ bool ProviderIsDefined;
+ CSysString LocalName;
+ CSysString RemoteName;
+ CSysString Comment;
+ CSysString Provider;
+};
+
+class CEnum
+{
+ HANDLE _handle;
+ bool _handleAllocated;
+protected:
+ bool IsHandleAllocated() const { return _handleAllocated; }
+public:
+ CEnum(): _handleAllocated(false) {}
+ ~CEnum() { Close(); }
+ DWORD Open(DWORD scope, DWORD type, DWORD usage, LPNETRESOURCE netResource);
+ DWORD Open(DWORD scope, DWORD type, DWORD usage, const CResource *resource);
+ DWORD Close();
+ DWORD Next(LPDWORD lpcCount, LPVOID lpBuffer, LPDWORD lpBufferSize);
+ DWORD Next(CResource &resource);
+};
+
+DWORD GetResourceParent(const CResource &resource, CResource &parentResource);
+DWORD GetResourceInformation(const CResource &resource,
+ CResource &destResource, CSysString &systemPathPart);
+DWORD AddConnection2(const CResource &resource,
+ LPCTSTR password, LPCTSTR userName, DWORD flags);
+
+}}
+
+#endif
diff --git a/Windows/ProcessMessages.cpp b/Windows/ProcessMessages.cpp
new file mode 100755
index 00000000..2f2841c1
--- /dev/null
+++ b/Windows/ProcessMessages.cpp
@@ -0,0 +1,22 @@
+// Windows/ProcessMessages.cpp
+
+#include "StdAfx.h"
+
+#include "ProcessMessages.h"
+
+namespace NWindows {
+
+void ProcessMessages(HWND window)
+{
+ MSG msg;
+ while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
+ {
+ if (window == (HWND) NULL || !IsDialogMessage(window, &msg))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+}
+
+} \ No newline at end of file
diff --git a/Windows/ProcessMessages.h b/Windows/ProcessMessages.h
new file mode 100755
index 00000000..76643a9f
--- /dev/null
+++ b/Windows/ProcessMessages.h
@@ -0,0 +1,16 @@
+// Windows/ProcessMessages.h
+
+#pragma once
+
+#ifndef __WINDOWS_PROCESSMESSAGES_H
+#define __WINDOWS_PROCESSMESSAGES_H
+
+namespace NWindows {
+
+void ProcessMessages(HWND window);
+
+}
+
+#endif
+
+
diff --git a/Windows/PropVariant.cpp b/Windows/PropVariant.cpp
new file mode 100755
index 00000000..39a412d9
--- /dev/null
+++ b/Windows/PropVariant.cpp
@@ -0,0 +1,479 @@
+// Windows/PropVariant.cpp
+
+#include "StdAfx.h"
+
+#include "PropVariant.h"
+
+#include "../Common/Defs.h"
+
+namespace NWindows {
+namespace NCOM {
+
+CPropVariant::CPropVariant(const PROPVARIANT& varSrc)
+{
+ vt = VT_EMPTY;
+ InternalCopy(&varSrc);
+}
+
+CPropVariant::CPropVariant(const CPropVariant& varSrc)
+{
+ vt = VT_EMPTY;
+ InternalCopy(&varSrc);
+}
+
+CPropVariant::CPropVariant(BSTR bstrSrc)
+{
+ vt = VT_EMPTY;
+ *this = bstrSrc;
+}
+
+CPropVariant::CPropVariant(LPCOLESTR lpszSrc)
+{
+ vt = VT_EMPTY;
+ *this = lpszSrc;
+}
+
+///////////////////////////
+// Assignment Operators
+CPropVariant& CPropVariant::operator=(const CPropVariant& varSrc)
+{
+ InternalCopy(&varSrc);
+ return *this;
+}
+CPropVariant& CPropVariant::operator=(const PROPVARIANT& varSrc)
+{
+ InternalCopy(&varSrc);
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(BSTR bstrSrc)
+{
+ InternalClear();
+ vt = VT_BSTR;
+ bstrVal = ::SysAllocString(bstrSrc);
+ if (bstrVal == NULL && bstrSrc != NULL)
+ {
+ vt = VT_ERROR;
+ scode = E_OUTOFMEMORY;
+ }
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc)
+{
+ InternalClear();
+ vt = VT_BSTR;
+ bstrVal = ::SysAllocString(lpszSrc);
+
+ if (bstrVal == NULL && lpszSrc != NULL)
+ {
+ vt = VT_ERROR;
+ scode = E_OUTOFMEMORY;
+ }
+ return *this;
+}
+
+
+CPropVariant& CPropVariant::operator=(bool bSrc)
+{
+ if (vt != VT_BOOL)
+ {
+ InternalClear();
+ vt = VT_BOOL;
+ }
+ boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(UINT32 value)
+{
+ if (vt != VT_UI4)
+ {
+ InternalClear();
+ vt = VT_UI4;
+ }
+ ulVal = value;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(UINT64 value)
+{
+ if (vt != VT_UI8)
+ {
+ InternalClear();
+ vt = VT_UI8;
+ }
+ uhVal = *(ULARGE_INTEGER*)&value;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(const FILETIME &value)
+{
+ if (vt != VT_FILETIME)
+ {
+ InternalClear();
+ vt = VT_FILETIME;
+ }
+ filetime = value;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(int value)
+{
+ if (vt != VT_I4)
+ {
+ InternalClear();
+ vt = VT_I4;
+ }
+ lVal = value;
+
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(BYTE value)
+{
+ if (vt != VT_UI1)
+ {
+ InternalClear();
+ vt = VT_UI1;
+ }
+ bVal = value;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(short value)
+{
+ if (vt != VT_I2)
+ {
+ InternalClear();
+ vt = VT_I2;
+ }
+ iVal = value;
+ return *this;
+}
+
+CPropVariant& CPropVariant::operator=(long value)
+{
+ if (vt != VT_I4)
+ {
+ InternalClear();
+ vt = VT_I4;
+ }
+ lVal = value;
+ return *this;
+}
+
+static HRESULT MyPropVariantClear(PROPVARIANT *aPropVariant)
+{
+ switch(aPropVariant->vt)
+ {
+ case VT_UI1:
+ case VT_I1:
+ case VT_I2:
+ case VT_UI2:
+ case VT_BOOL:
+ case VT_I4:
+ case VT_UI4:
+ case VT_R4:
+ case VT_INT:
+ case VT_UINT:
+ case VT_ERROR:
+ case VT_FILETIME:
+ case VT_UI8:
+ case VT_R8:
+ case VT_CY:
+ case VT_DATE:
+ aPropVariant->vt = VT_EMPTY;
+ return S_OK;
+ }
+ return ::VariantClear((tagVARIANT *)aPropVariant);
+}
+
+HRESULT CPropVariant::Clear()
+{
+ return MyPropVariantClear(this);
+}
+
+HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc)
+{
+ ::VariantClear((tagVARIANT *)this);
+ switch(pSrc->vt)
+ {
+ case VT_UI1:
+ case VT_I1:
+ case VT_I2:
+ case VT_UI2:
+ case VT_BOOL:
+ case VT_I4:
+ case VT_UI4:
+ case VT_R4:
+ case VT_INT:
+ case VT_UINT:
+ case VT_ERROR:
+ case VT_FILETIME:
+ case VT_UI8:
+ case VT_R8:
+ case VT_CY:
+ case VT_DATE:
+ MoveMemory((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT));
+ return S_OK;
+ }
+ return ::VariantCopy((tagVARIANT *)this, (tagVARIANT *)(pSrc));
+}
+
+
+HRESULT CPropVariant::Attach(PROPVARIANT* pSrc)
+{
+ // Clear out the variant
+ HRESULT hr = Clear();
+ if (!FAILED(hr))
+ {
+ // Copy the contents and give control to CPropVariant
+ memcpy(this, pSrc, sizeof(PROPVARIANT));
+ pSrc->vt = VT_EMPTY;
+ hr = S_OK;
+ }
+ return hr;
+}
+
+HRESULT CPropVariant::Detach(PROPVARIANT* pDest)
+{
+ // Clear out the variant
+ HRESULT hr = MyPropVariantClear(pDest);
+ // HRESULT hr = ::VariantClear((VARIANT* )pDest);
+ if (!FAILED(hr))
+ {
+ // Copy the contents and remove control from CPropVariant
+ memcpy(pDest, this, sizeof(PROPVARIANT));
+ vt = VT_EMPTY;
+ hr = S_OK;
+ }
+ return hr;
+}
+
+HRESULT CPropVariant::ChangeType(VARTYPE vtNew, const PROPVARIANT* pSrc)
+{
+ PROPVARIANT* pVar = const_cast<PROPVARIANT*>(pSrc);
+ // Convert in place if pSrc is NULL
+ if (pVar == NULL)
+ pVar = this;
+ // Do nothing if doing in place convert and vts not different
+ return ::VariantChangeType((VARIANT *)this, (VARIANT *)pVar, 0, vtNew);
+}
+
+HRESULT CPropVariant::InternalClear()
+{
+ HRESULT hr = Clear();
+ if (FAILED(hr))
+ {
+ vt = VT_ERROR;
+ scode = hr;
+ }
+ return hr;
+}
+
+void CPropVariant::InternalCopy(const PROPVARIANT* pSrc)
+{
+ HRESULT hr = Copy(pSrc);
+ if (FAILED(hr))
+ {
+ vt = VT_ERROR;
+ scode = hr;
+ }
+}
+
+HRESULT CPropVariant::WriteToStream(ISequentialStream *stream) const
+{
+ HRESULT aResult = stream->Write(&vt, sizeof(vt), NULL);
+ if (FAILED(aResult))
+ return aResult;
+
+ if (vt == VT_EMPTY)
+ return S_OK;
+
+ int aNumBytes = 0;
+ switch (vt)
+ {
+ case VT_UI1:
+ case VT_I1:
+ aNumBytes = sizeof(BYTE);
+ break;
+ case VT_I2:
+ case VT_UI2:
+ case VT_BOOL:
+ aNumBytes = sizeof(short);
+ break;
+ case VT_I4:
+ case VT_UI4:
+ case VT_R4:
+ case VT_INT:
+ case VT_UINT:
+ case VT_ERROR:
+ aNumBytes = sizeof(long);
+ break;
+ case VT_FILETIME:
+ case VT_UI8:
+ case VT_R8:
+ case VT_CY:
+ case VT_DATE:
+ aNumBytes = sizeof(double);
+ break;
+ default:
+ break;
+ }
+ if (aNumBytes != 0)
+ return stream->Write(&bVal, aNumBytes, NULL);
+
+ if (vt == VT_BSTR)
+ {
+ UINT32 aLen = 0;
+ if(bstrVal != NULL)
+ aLen = SysStringLen(bstrVal);
+ HRESULT aResult = stream->Write(&aLen, sizeof(UINT32), NULL);
+ if (FAILED(aResult))
+ return aResult;
+ if(bstrVal == NULL)
+ return S_OK;
+ if(aLen == 0)
+ return S_OK;
+ return stream->Write(bstrVal, aLen * sizeof(wchar_t), NULL);
+ }
+ else
+ {
+ return E_FAIL;
+ /*
+ CPropVariant varBSTR;
+ HRESULT hr = VariantChangeType(&varBSTR, this, VARIANT_NOVALUEPROP, VT_BSTR);
+ if (FAILED(hr))
+ return;
+ MoveMemory(aMemoryPointer, varBSTR.bstrVal, SysStringLen(varBSTR.bstrVal));
+ */
+ }
+}
+
+HRESULT CPropVariant::ReadFromStream(ISequentialStream *stream)
+{
+ HRESULT hr = Clear();
+ if (FAILED(hr))
+ return hr;
+
+ VARTYPE vtRead;
+ hr = stream->Read(&vtRead, sizeof(VARTYPE), NULL);
+ if (hr == S_FALSE)
+ hr = E_FAIL;
+ if (FAILED(hr))
+ return hr;
+
+ vt = vtRead;
+ if (vt == VT_EMPTY)
+ return S_OK;
+ int aNumBytes = 0;
+ switch (vt)
+ {
+ case VT_UI1:
+ case VT_I1:
+ aNumBytes = sizeof(BYTE);
+ break;
+ case VT_I2:
+ case VT_UI2:
+ case VT_BOOL:
+ aNumBytes = sizeof(short);
+ break;
+ case VT_I4:
+ case VT_UI4:
+ case VT_R4:
+ case VT_INT:
+ case VT_UINT:
+ case VT_ERROR:
+ aNumBytes = sizeof(long);
+ break;
+ case VT_FILETIME:
+ case VT_UI8:
+ case VT_R8:
+ case VT_CY:
+ case VT_DATE:
+ aNumBytes = sizeof(double);
+ break;
+ default:
+ break;
+ }
+ if (aNumBytes != 0)
+ {
+ hr = stream->Read(&bVal, aNumBytes, NULL);
+ if (hr == S_FALSE)
+ hr = E_FAIL;
+ return hr;
+ }
+
+ if (vt == VT_BSTR)
+ {
+ bstrVal = NULL;
+ UINT32 aLen = 0;
+ hr = stream->Read(&aLen, sizeof(UINT32), NULL);
+ if (hr != S_OK)
+ return E_FAIL;
+ bstrVal = SysAllocStringLen(NULL, aLen);
+ if(bstrVal == NULL)
+ return E_OUTOFMEMORY;
+ hr = stream->Read(bstrVal, aLen * sizeof(wchar_t), NULL);
+ if (hr == S_FALSE)
+ hr = E_FAIL;
+ return hr;
+ }
+ else
+ return E_FAIL;
+}
+
+int CPropVariant::Compare(const CPropVariant &a)
+{
+ if(vt != a.vt)
+ return 0; // it's mean some bug
+ switch (vt)
+ {
+ case VT_EMPTY:
+ return 0;
+
+ /*
+ case VT_I1:
+ return MyCompare(cVal, a.cVal);
+ */
+ case VT_UI1:
+ return MyCompare(bVal, a.bVal);
+
+ case VT_I2:
+ return MyCompare(iVal, a.iVal);
+ case VT_UI2:
+ return MyCompare(uiVal, a.uiVal);
+
+ case VT_I4:
+ return MyCompare(lVal, a.lVal);
+ /*
+ case VT_INT:
+ return MyCompare(intVal, a.intVal);
+ */
+ case VT_UI4:
+ return MyCompare(ulVal, a.ulVal);
+ /*
+ case VT_UINT:
+ return MyCompare(uintVal, a.uintVal);
+ */
+ case VT_I8:
+ return MyCompare(INT64(*(const INT64 *)&hVal), INT64(*(const INT64 *)&a.hVal));
+ case VT_UI8:
+ return MyCompare(UINT64(*(const UINT64 *)&uhVal), UINT64(*(const UINT64 *)&a.uhVal));
+
+ case VT_BOOL:
+ return -MyCompare(boolVal, a.boolVal); // Test it
+
+ case VT_FILETIME:
+ return ::CompareFileTime(&filetime, &a.filetime);
+ case VT_BSTR:
+ return 0; // Not implemented
+ // return MyCompare(aPropVarint.cVal);
+
+ default:
+ return 0;
+ }
+}
+
+}}
diff --git a/Windows/PropVariant.h b/Windows/PropVariant.h
new file mode 100755
index 00000000..44fd74f5
--- /dev/null
+++ b/Windows/PropVariant.h
@@ -0,0 +1,60 @@
+// Windows/PropVariant.h
+
+// #pragma once
+
+#ifndef __WINDOWS_PROPVARIANT_H
+#define __WINDOWS_PROPVARIANT_H
+
+namespace NWindows {
+namespace NCOM {
+
+class CPropVariant : public tagPROPVARIANT
+{
+public:
+ CPropVariant() { vt = VT_EMPTY; }
+ ~CPropVariant() { Clear(); }
+ CPropVariant(const PROPVARIANT& varSrc);
+ CPropVariant(const CPropVariant& varSrc);
+ CPropVariant(BSTR bstrSrc);
+ CPropVariant(LPCOLESTR lpszSrc);
+ CPropVariant(bool bSrc) { vt = VT_BOOL; boolVal = (bSrc ? VARIANT_TRUE : VARIANT_FALSE); };
+ CPropVariant(UINT32 value) { vt = VT_UI4; ulVal = value; }
+ CPropVariant(UINT64 value) { vt = VT_UI8; uhVal = *(ULARGE_INTEGER*)&value; }
+ CPropVariant(const FILETIME &value) { vt = VT_FILETIME; filetime = value; }
+ CPropVariant(int value) { vt = VT_I4; lVal = value; }
+ CPropVariant(BYTE value) { vt = VT_UI1; bVal = value; }
+ CPropVariant(short value) { vt = VT_I2; iVal = value; }
+ CPropVariant(long value, VARTYPE vtSrc = VT_I4) { vt = vtSrc; lVal = value; }
+
+ CPropVariant& operator=(const CPropVariant& varSrc);
+ CPropVariant& operator=(const PROPVARIANT& varSrc);
+ CPropVariant& operator=(BSTR bstrSrc);
+ CPropVariant& operator=(LPCOLESTR lpszSrc);
+ CPropVariant& operator=(bool bSrc);
+ CPropVariant& operator=(UINT32 value);
+ CPropVariant& operator=(UINT64 value);
+ CPropVariant& operator=(const FILETIME &value);
+
+ CPropVariant& operator=(int value);
+ CPropVariant& operator=(BYTE value);
+ CPropVariant& operator=(short value);
+ CPropVariant& operator=(long value);
+
+ HRESULT Clear();
+ HRESULT Copy(const PROPVARIANT* pSrc);
+ HRESULT Attach(PROPVARIANT* pSrc);
+ HRESULT Detach(PROPVARIANT* pDest);
+ HRESULT ChangeType(VARTYPE vtNew, const PROPVARIANT* pSrc = NULL);
+
+ HRESULT InternalClear();
+ void InternalCopy(const PROPVARIANT* pSrc);
+
+ HRESULT WriteToStream(ISequentialStream *stream) const;
+ HRESULT ReadFromStream(ISequentialStream *stream);
+
+ int Compare(const CPropVariant &a1);
+};
+
+}}
+
+#endif
diff --git a/Windows/PropVariantConversions.cpp b/Windows/PropVariantConversions.cpp
new file mode 100755
index 00000000..15652693
--- /dev/null
+++ b/Windows/PropVariantConversions.cpp
@@ -0,0 +1,143 @@
+// PropVariantConversions.cpp
+
+#include "StdAfx.h"
+
+#include "PropVariantConversions.h"
+
+#include "Windows/NationalTime.h"
+#include "Windows/Defs.h"
+
+#include "Common/StringConvert.h"
+#include "Common/IntToString.h"
+
+using namespace NWindows;
+
+static UString ConvertUINT64ToString(UINT64 value)
+{
+ wchar_t buffer[32];
+ ConvertUINT64ToString(value, buffer);
+ return buffer;
+}
+
+static UString ConvertINT64ToString(INT64 value)
+{
+ wchar_t buffer[32];
+ ConvertINT64ToString(value, buffer);
+ return buffer;
+}
+
+/*
+CSysString ConvertFileTimeToString(const FILETIME &fileTime, bool includeTime)
+{
+ SYSTEMTIME systemTime;
+ if(!BOOLToBool(FileTimeToSystemTime(&fileTime, &systemTime)))
+ #ifndef _WIN32_WCE
+ throw 311907;
+ #else
+ return CSysString();
+ #endif
+
+ const int kBufferSize = 64;
+ CSysString stringDate;
+ if(!NNational::NTime::MyGetDateFormat(LOCALE_USER_DEFAULT,
+ 0, &systemTime, NULL, stringDate))
+ #ifndef _WIN32_WCE
+ throw 311908;
+ #else
+ return CSysString();
+ #endif
+ if (!includeTime)
+ return stringDate;
+ CSysString stringTime;
+ if(!NNational::NTime::MyGetTimeFormat(LOCALE_USER_DEFAULT,
+ 0, &systemTime, NULL, stringTime))
+ #ifndef _WIN32_WCE
+ throw 311909;
+ #else
+ return CSysString();
+ #endif
+ return stringDate + _T(" ") + stringTime;
+}
+*/
+
+UString ConvertFileTimeToString2(const FILETIME &fileTime,
+ bool includeTime, bool includeSeconds)
+{
+ CSysString string;
+ SYSTEMTIME systemTime;
+ if(!BOOLToBool(FileTimeToSystemTime(&fileTime, &systemTime)))
+ return UString();
+ TCHAR buffer[64];
+ wsprintf(buffer, TEXT("%04d-%02d-%02d"), systemTime.wYear, systemTime.wMonth, systemTime.wDay);
+ if (includeTime)
+ {
+ wsprintf(buffer + lstrlen(buffer), TEXT(" %02d:%02d"), systemTime.wHour, systemTime.wMinute);
+ if (includeSeconds)
+ wsprintf(buffer + lstrlen(buffer), TEXT(":%02d"), systemTime.wSecond);
+ }
+ return GetUnicodeString(buffer);
+}
+
+
+UString ConvertPropVariantToString(const PROPVARIANT &propVariant)
+{
+ switch (propVariant.vt)
+ {
+ case VT_EMPTY:
+ return UString();
+ case VT_BSTR:
+ return propVariant.bstrVal;
+ case VT_UI1:
+ return ConvertUINT64ToString(propVariant.bVal);
+ case VT_UI2:
+ return ConvertUINT64ToString(propVariant.uiVal);
+ case VT_UI4:
+ return ConvertUINT64ToString(propVariant.ulVal);
+ case VT_UI8:
+ return ConvertUINT64ToString(*(UINT64 *)(&propVariant.uhVal));
+ case VT_FILETIME:
+ return ConvertFileTimeToString2(propVariant.filetime, true, true);
+
+
+ /*
+ case VT_I1:
+ return ConvertINT64ToString(propVariant.cVal);
+ */
+ case VT_I2:
+ return ConvertINT64ToString(propVariant.iVal);
+ case VT_I4:
+ return ConvertINT64ToString(propVariant.lVal);
+ case VT_I8:
+ return ConvertINT64ToString(*(INT64 *)(&propVariant.hVal));
+
+ case VT_BOOL:
+ return VARIANT_BOOLToBool(propVariant.boolVal) ? L"1" : L"0";
+ default:
+ #ifndef _WIN32_WCE
+ throw 150245;
+ #else
+ return CSysString();
+ #endif
+ }
+}
+
+UINT64 ConvertPropVariantToUINT64(const PROPVARIANT &propVariant)
+{
+ switch (propVariant.vt)
+ {
+ case VT_UI1:
+ return propVariant.bVal;
+ case VT_UI2:
+ return propVariant.uiVal;
+ case VT_UI4:
+ return propVariant.ulVal;
+ case VT_UI8:
+ return (*(UINT64 *)(&propVariant.uhVal));
+ default:
+ #ifndef _WIN32_WCE
+ throw 151199;
+ #else
+ return 0;
+ #endif
+ }
+}
diff --git a/Windows/PropVariantConversions.h b/Windows/PropVariantConversions.h
new file mode 100755
index 00000000..1067a7d8
--- /dev/null
+++ b/Windows/PropVariantConversions.h
@@ -0,0 +1,17 @@
+// Windows/PropVariantConversions.h
+
+#pragma once
+
+#ifndef __PROPVARIANTCONVERSIONS_H
+#define __PROPVARIANTCONVERSIONS_H
+
+#include "Common/String.h"
+
+// CSysString ConvertFileTimeToString(const FILETIME &fileTime, bool includeTime = true);
+UString ConvertFileTimeToString2(const FILETIME &fileTime, bool includeTime = true,
+ bool includeSeconds = true);
+UString ConvertPropVariantToString(const PROPVARIANT &propVariant);
+
+UINT64 ConvertPropVariantToUINT64(const PROPVARIANT &propVariant);
+
+#endif
diff --git a/Windows/Registry.cpp b/Windows/Registry.cpp
new file mode 100755
index 00000000..baad469d
--- /dev/null
+++ b/Windows/Registry.cpp
@@ -0,0 +1,266 @@
+// Windows/Registry.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/Registry.h"
+
+namespace NWindows {
+namespace NRegistry {
+
+#define MYASSERT(expr) // _ASSERTE(expr)
+
+CKey::~CKey()
+{
+ Close();
+}
+
+HKEY CKey::Detach()
+{
+ HKEY hKey = _object;
+ _object = NULL;
+ return hKey;
+}
+
+void CKey::Attach(HKEY hKey)
+{
+ MYASSERT(_object == NULL);
+ _object = hKey;
+}
+
+LONG CKey::Create(HKEY parentKey, LPCTSTR keyName,
+ LPTSTR keyClass, DWORD options, REGSAM accessMask,
+ LPSECURITY_ATTRIBUTES securityAttributes, LPDWORD disposition)
+{
+ MYASSERT(parentKey != NULL);
+ DWORD dispositionReal;
+ HKEY key = NULL;
+ LONG res = RegCreateKeyEx(parentKey, keyName, 0, keyClass,
+ options, accessMask, securityAttributes, &key, &dispositionReal);
+ if (disposition != NULL)
+ *disposition = dispositionReal;
+ if (res == ERROR_SUCCESS)
+ {
+ res = Close();
+ _object = key;
+ }
+ return res;
+}
+
+LONG CKey::Open(HKEY parentKey, LPCTSTR keyName, REGSAM accessMask)
+{
+ MYASSERT(parentKey != NULL);
+ HKEY key = NULL;
+ LONG res = RegOpenKeyEx(parentKey, keyName, 0, accessMask, &key);
+ if (res == ERROR_SUCCESS)
+ {
+ res = Close();
+ MYASSERT(res == ERROR_SUCCESS);
+ _object = key;
+ }
+ return res;
+}
+
+LONG CKey::Close()
+{
+ LONG res = ERROR_SUCCESS;
+ if (_object != NULL)
+ {
+ res = RegCloseKey(_object);
+ _object = NULL;
+ }
+ return res;
+}
+
+// win95, win98: deletes sunkey and all its subkeys
+// winNT to be deleted must not have subkeys
+LONG CKey::DeleteSubKey(LPCTSTR subKeyName)
+{
+ MYASSERT(_object != NULL);
+ return RegDeleteKey(_object, subKeyName);
+}
+
+LONG CKey::RecurseDeleteKey(LPCTSTR subKeyName)
+{
+ CKey key;
+ LONG res = key.Open(_object, subKeyName, KEY_READ | KEY_WRITE);
+ if (res != ERROR_SUCCESS)
+ return res;
+ FILETIME fileTime;
+ const UINT32 kBufferSize = MAX_PATH + 1; // 256 in ATL
+ DWORD size = kBufferSize;
+ TCHAR buffer[kBufferSize];
+ while (RegEnumKeyEx(key._object, 0, buffer, &size, NULL, NULL, NULL,
+ &fileTime) == ERROR_SUCCESS)
+ {
+ res = key.RecurseDeleteKey(buffer);
+ if (res != ERROR_SUCCESS)
+ return res;
+ size = kBufferSize;
+ }
+ key.Close();
+ return DeleteSubKey(subKeyName);
+}
+
+
+/////////////////////////
+// Value Functions
+
+static inline UINT32 BoolToUINT32(bool value)
+ { return (value ? 1: 0); }
+
+static inline bool UINT32ToBool(UINT32 value)
+ { return (value != 0); }
+
+
+LONG CKey::DeleteValue(LPCTSTR value)
+{
+ MYASSERT(_object != NULL);
+ return RegDeleteValue(_object, (LPTSTR)value);
+}
+
+LONG CKey::SetValue(LPCTSTR valueName, UINT32 value)
+{
+ MYASSERT(_object != NULL);
+ return RegSetValueEx(_object, valueName, NULL, REG_DWORD,
+ (BYTE * const)&value, sizeof(UINT32));
+}
+
+LONG CKey::SetValue(LPCTSTR valueName, bool value)
+{
+ return SetValue(valueName, BoolToUINT32(value));
+}
+
+LONG CKey::SetValue(LPCTSTR valueName, LPCTSTR value)
+{
+ MYASSERT(value != NULL);
+ MYASSERT(_object != NULL);
+ return RegSetValueEx(_object, valueName, NULL, REG_SZ,
+ (const BYTE * )value, (lstrlen(value) + 1) * sizeof(TCHAR));
+}
+
+LONG CKey::SetValue(LPCTSTR valueName, const CSysString &value)
+{
+ MYASSERT(value != NULL);
+ MYASSERT(_object != NULL);
+ return RegSetValueEx(_object, valueName, NULL, REG_SZ,
+ (const BYTE *)(const TCHAR *)value, (value.Length() + 1) * sizeof(TCHAR));
+}
+
+LONG CKey::SetValue(LPCTSTR valueName, const void *value, UINT32 size)
+{
+ MYASSERT(value != NULL);
+ MYASSERT(_object != NULL);
+ return RegSetValueEx(_object, valueName, NULL, REG_BINARY,
+ (const BYTE *)value, size);
+}
+
+LONG SetValue(HKEY parentKey, LPCTSTR keyName,
+ LPCTSTR valueName, LPCTSTR value)
+{
+ MYASSERT(value != NULL);
+ CKey key;
+ LONG res = key.Create(parentKey, keyName);
+ if (res == ERROR_SUCCESS)
+ res = key.SetValue(valueName, value);
+ return res;
+}
+
+LONG CKey::SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value)
+{
+ MYASSERT(value != NULL);
+ CKey key;
+ LONG res = key.Create(_object, keyName);
+ if (res == ERROR_SUCCESS)
+ res = key.SetValue(valueName, value);
+ return res;
+}
+
+LONG CKey::QueryValue(LPCTSTR valueName, UINT32 &value)
+{
+ DWORD type = NULL;
+ DWORD count = sizeof(DWORD);
+ LONG res = RegQueryValueEx(_object, (LPTSTR)valueName, NULL, &type,
+ (LPBYTE)&value, &count);
+ MYASSERT((res!=ERROR_SUCCESS) || (type == REG_DWORD));
+ MYASSERT((res!=ERROR_SUCCESS) || (count == sizeof(UINT32)));
+ return res;
+}
+
+LONG CKey::QueryValue(LPCTSTR valueName, bool &value)
+{
+ UINT32 uintValue = BoolToUINT32(value);
+ LONG res = QueryValue(valueName, uintValue);
+ value = UINT32ToBool(uintValue);
+ return res;
+}
+
+LONG CKey::QueryValue(LPCTSTR valueName, LPTSTR value, UINT32 &count)
+{
+ MYASSERT(count != NULL);
+ DWORD type = NULL;
+ LONG res = RegQueryValueEx(_object, (LPTSTR)valueName, NULL, &type,
+ (LPBYTE)value, (DWORD *)&count);
+ MYASSERT((res!=ERROR_SUCCESS) || (type == REG_SZ) ||
+ (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ));
+ return res;
+}
+
+LONG CKey::QueryValue(LPCTSTR valueName, CSysString &value)
+{
+ value.Empty();
+ DWORD type = NULL;
+ UINT32 currentSize = 0;
+ LONG res = RegQueryValueEx(_object, (LPTSTR)valueName, NULL, &type,
+ NULL, (DWORD *)&currentSize);
+ if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
+ return res;
+ res = QueryValue(valueName, value.GetBuffer(currentSize), currentSize);
+ value.ReleaseBuffer();
+ return res;
+}
+
+LONG CKey::QueryValue(LPCTSTR valueName, void *value, UINT32 &count)
+{
+ DWORD type = NULL;
+ LONG res = RegQueryValueEx(_object, (LPTSTR)valueName, NULL, &type,
+ (LPBYTE)value, (DWORD *)&count);
+ MYASSERT((res!=ERROR_SUCCESS) || (type == REG_BINARY));
+ return res;
+}
+
+
+LONG CKey::QueryValue(LPCTSTR valueName, CByteBuffer &value, UINT32 &dataSize)
+{
+ DWORD type = NULL;
+ dataSize = 0;
+ LONG res = RegQueryValueEx(_object, (LPTSTR)valueName, NULL, &type,
+ NULL, (DWORD *)&dataSize);
+ if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
+ return res;
+ value.SetCapacity(dataSize);
+ return QueryValue(valueName, (BYTE *)value, dataSize);
+}
+
+LONG CKey::EnumKeys(CSysStringVector &keyNames)
+{
+ keyNames.Clear();
+ CSysString keyName;
+ for(UINT32 index = 0; true; index++)
+ {
+ const UINT32 kBufferSize = MAX_PATH + 1; // 256 in ATL
+ FILETIME lastWriteTime;
+ UINT32 aNameSize = kBufferSize;
+ LONG aResult = ::RegEnumKeyEx(_object, index, keyName.GetBuffer(kBufferSize),
+ (DWORD *)&aNameSize, NULL, NULL, NULL, &lastWriteTime);
+ keyName.ReleaseBuffer();
+ if(aResult == ERROR_NO_MORE_ITEMS)
+ break;
+ if(aResult != ERROR_SUCCESS)
+ return aResult;
+ keyNames.Add(keyName);
+ }
+ return ERROR_SUCCESS;
+}
+
+
+}}
diff --git a/Windows/Registry.h b/Windows/Registry.h
new file mode 100755
index 00000000..d47ef22c
--- /dev/null
+++ b/Windows/Registry.h
@@ -0,0 +1,65 @@
+// Windows/Registry.h
+
+#pragma once
+
+#ifndef __WINDOWS_REGISTRY_H
+#define __WINDOWS_REGISTRY_H
+
+#include "Common/Buffer.h"
+#include "Common/String.h"
+
+namespace NWindows {
+namespace NRegistry {
+
+const TCHAR kKeyNameDelimiter = TEXT('\\');
+
+LONG SetValue(HKEY parentKey, LPCTSTR keyName,
+ LPCTSTR valueName, LPCTSTR value);
+
+class CKey
+{
+ HKEY _object;
+public:
+ CKey(): _object(NULL) {}
+ ~CKey();
+
+ operator HKEY() const { return _object; }
+
+ HKEY Detach();
+ void Attach(HKEY key);
+ LONG Create(HKEY parentKey, LPCTSTR keyName,
+ LPTSTR keyClass = REG_NONE, DWORD options = REG_OPTION_NON_VOLATILE,
+ REGSAM accessMask = KEY_ALL_ACCESS,
+ LPSECURITY_ATTRIBUTES securityAttributes = NULL,
+ LPDWORD disposition = NULL);
+ LONG Open(HKEY parentKey, LPCTSTR keyName,
+ REGSAM accessMask = KEY_ALL_ACCESS);
+
+ LONG Close();
+
+ LONG DeleteSubKey(LPCTSTR subKeyName);
+ LONG RecurseDeleteKey(LPCTSTR subKeyName);
+
+ LONG DeleteValue(LPCTSTR value);
+ LONG SetValue(LPCTSTR valueName, UINT32 value);
+ LONG SetValue(LPCTSTR valueName, bool value);
+ LONG SetValue(LPCTSTR valueName, LPCTSTR value);
+ LONG SetValue(LPCTSTR valueName, const CSysString &value);
+ LONG SetValue(LPCTSTR valueName, const void *value, UINT32 size);
+
+ LONG SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value);
+
+ LONG QueryValue(LPCTSTR valueName, UINT32 &value);
+ LONG QueryValue(LPCTSTR valueName, bool &value);
+ LONG QueryValue(LPCTSTR valueName, LPTSTR value, UINT32 &dataSize);
+ LONG QueryValue(LPCTSTR valueName, CSysString &value);
+
+ LONG QueryValue(LPCTSTR valueName, void *value, UINT32 &dataSize);
+ LONG QueryValue(LPCTSTR valueName, CByteBuffer &value, UINT32 &dataSize);
+
+ LONG EnumKeys(CSysStringVector &keyNames);
+};
+
+}}
+
+#endif
diff --git a/Windows/ResourceString.cpp b/Windows/ResourceString.cpp
new file mode 100755
index 00000000..b327298d
--- /dev/null
+++ b/Windows/ResourceString.cpp
@@ -0,0 +1,50 @@
+// Windows/ResourceString.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/ResourceString.h"
+#ifndef _UNICODE
+#include "Common/StringConvert.h"
+#endif
+
+extern HINSTANCE g_hInstance;
+
+namespace NWindows {
+
+CSysString MyLoadString(UINT resourceID)
+{
+ CSysString s;
+ int size = 256;
+ int len;
+ do
+ {
+ size += 256;
+ len = ::LoadString(g_hInstance, resourceID, s.GetBuffer(size - 1), size);
+ } while (size - len <= 1);
+ s.ReleaseBuffer();
+ return s;
+}
+
+#ifndef _UNICODE
+UString MyLoadStringW(UINT resourceID)
+{
+ UString s;
+ int size = 256;
+ int len;
+ do
+ {
+ size += 256;
+ len = ::LoadStringW(g_hInstance, resourceID, s.GetBuffer(size - 1), size);
+ if (len == 0)
+ {
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ break;
+ return GetUnicodeString(MyLoadString(resourceID));
+ }
+ } while (size - len <= 1);
+ s.ReleaseBuffer();
+ return s;
+}
+#endif
+
+} \ No newline at end of file
diff --git a/Windows/ResourceString.h b/Windows/ResourceString.h
new file mode 100755
index 00000000..8819e1a3
--- /dev/null
+++ b/Windows/ResourceString.h
@@ -0,0 +1,22 @@
+// Windows/ResourceString.h
+
+#pragma once
+
+#ifndef __WINDOWS_RESOURCESTRING_H
+#define __WINDOWS_RESOURCESTRING_H
+
+#include "Common/String.h"
+
+namespace NWindows {
+
+CSysString MyLoadString(UINT resourceID);
+#ifdef _UNICODE
+inline UString MyLoadStringW(UINT resourceID)
+ { return MyLoadString(resourceID); }
+#else
+UString MyLoadStringW(UINT resourceID);
+#endif
+
+}
+
+#endif
diff --git a/Windows/Shell.cpp b/Windows/Shell.cpp
new file mode 100755
index 00000000..2d0e8bb2
--- /dev/null
+++ b/Windows/Shell.cpp
@@ -0,0 +1,180 @@
+// Windows/Shell.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyCom.h"
+#include "Windows/Shell.h"
+#include "Windows/COM.h"
+
+namespace NWindows {
+namespace NShell {
+
+/////////////////////////
+// CItemIDList
+
+void CItemIDList::Free()
+{
+ if(m_Object == NULL)
+ return;
+ CMyComPtr<IMalloc> shellMalloc;
+ if(::SHGetMalloc(&shellMalloc) != NOERROR)
+ throw 41099;
+ shellMalloc->Free(m_Object);
+ m_Object = NULL;
+}
+
+/*
+CItemIDList::(LPCITEMIDLIST itemIDList): m_Object(NULL)
+ { *this = itemIDList; }
+CItemIDList::(const CItemIDList& itemIDList): m_Object(NULL)
+ { *this = itemIDList; }
+
+CItemIDList& CItemIDList::operator=(LPCITEMIDLIST object)
+{
+ Free();
+ if (object != 0)
+ {
+ UINT32 size = GetSize(object);
+ m_Object = (LPITEMIDLIST)CoTaskMemAlloc(size);
+ if(m_Object != NULL)
+ MoveMemory(m_Object, object, size);
+ }
+ return *this;
+}
+
+CItemIDList& CItemIDList::operator=(const CItemIDList &object)
+{
+ Free();
+ if(object.m_Object != NULL)
+ {
+ UINT32 size = GetSize(object.m_Object);
+ m_Object = (LPITEMIDLIST)CoTaskMemAlloc(size);
+ if(m_Object != NULL)
+ MoveMemory(m_Object, object.m_Object, size);
+ }
+ return *this;
+}
+*/
+/////////////////////////////
+// CDrop
+
+void CDrop::Attach(HDROP object)
+{
+ Free();
+ m_Object = object;
+ m_Assigned = true;
+}
+
+void CDrop::Free()
+{
+ if(m_MustBeFinished && m_Assigned)
+ Finish();
+ m_Assigned = false;
+}
+
+CDrop::~CDrop()
+{
+ Free();
+}
+
+UINT CDrop::QueryFile(UINT fileIndex, LPTSTR fileName, UINT fileNameSize)
+{
+ return ::DragQueryFile(m_Object, fileIndex, fileName, fileNameSize);
+}
+
+UINT CDrop::QueryCountOfFiles()
+{
+ return QueryFile(0xFFFFFFFF, NULL, 0);
+}
+
+CSysString CDrop::QueryFileName(UINT fileIndex)
+{
+ CSysString fileName;
+ UINT bufferSize = QueryFile(fileIndex, NULL, 0);
+ QueryFile(fileIndex, fileName.GetBuffer(bufferSize), bufferSize + 1);
+ fileName.ReleaseBuffer();
+ return fileName;
+}
+
+void CDrop::QueryFileNames(CSysStringVector &fileNames)
+{
+ fileNames.Clear();
+ UINT numFiles = QueryCountOfFiles();
+ fileNames.Reserve(numFiles);
+ for(UINT i = 0; i < numFiles; i++)
+ fileNames.Add(QueryFileName(i));
+}
+
+
+/////////////////////////////
+// Functions
+
+bool GetPathFromIDList(LPCITEMIDLIST itemIDList, CSysString &path)
+{
+ bool result = BOOLToBool(::SHGetPathFromIDList(itemIDList,
+ path.GetBuffer(MAX_PATH)));
+ path.ReleaseBuffer();
+ return result;
+}
+
+bool BrowseForFolder(LPBROWSEINFO browseInfo, CSysString &resultPath)
+{
+ NWindows::NCOM::CComInitializer comInitializer;
+ LPITEMIDLIST itemIDList = ::SHBrowseForFolder(browseInfo);
+ if (itemIDList == NULL)
+ return false;
+ CItemIDList itemIDListHolder;
+ itemIDListHolder.Attach(itemIDList);
+ return GetPathFromIDList(itemIDList, resultPath);
+}
+
+
+int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lp, LPARAM data)
+{
+ switch(uMsg)
+ {
+ case BFFM_INITIALIZED:
+ {
+ SendMessage(hwnd, BFFM_SETSELECTION, TRUE, data);
+ break;
+ }
+ case BFFM_SELCHANGED:
+ {
+ TCHAR dir[MAX_PATH];
+ if (::SHGetPathFromIDList((LPITEMIDLIST) lp , dir))
+ SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, (LPARAM)dir);
+ else
+ SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, (LPARAM)TEXT(""));
+ break;
+ }
+ default:
+ break;
+ }
+ return 0;
+}
+
+
+bool BrowseForFolder(HWND owner, LPCTSTR title, UINT ulFlags,
+ LPCTSTR initialFolder, CSysString &resultPath)
+{
+ CSysString displayName;
+ BROWSEINFO browseInfo;
+ browseInfo.hwndOwner = owner;
+ browseInfo.pidlRoot = NULL;
+ browseInfo.pszDisplayName = displayName.GetBuffer(MAX_PATH);
+ browseInfo.lpszTitle = title;
+ browseInfo.ulFlags = ulFlags;
+ browseInfo.lpfn = (initialFolder != NULL) ? BrowseCallbackProc : NULL;
+ browseInfo.lParam = (LPARAM)initialFolder;
+ return BrowseForFolder(&browseInfo, resultPath);
+}
+
+bool BrowseForFolder(HWND owner, LPCTSTR title,
+ LPCTSTR initialFolder, CSysString &resultPath)
+{
+ return BrowseForFolder(owner, title,
+ BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT, initialFolder, resultPath);
+ // BIF_STATUSTEXT; BIF_USENEWUI (Version 5.0)
+}
+
+}}
diff --git a/Windows/Shell.h b/Windows/Shell.h
new file mode 100755
index 00000000..88efa9e6
--- /dev/null
+++ b/Windows/Shell.h
@@ -0,0 +1,82 @@
+// Windows/Shell.h
+
+#pragma once
+
+#ifndef __WINDOWS_SHELL_H
+#define __WINDOWS_SHELL_H
+
+#include "Common/String.h"
+#include "Windows/Defs.h"
+
+namespace NWindows{
+namespace NShell{
+
+/////////////////////////
+// CItemIDList
+
+class CItemIDList
+{
+ LPITEMIDLIST m_Object;
+public:
+ CItemIDList(): m_Object(NULL) {}
+ // CItemIDList(LPCITEMIDLIST itemIDList);
+ // CItemIDList(const CItemIDList& itemIDList);
+ ~CItemIDList() { Free(); }
+ void Free();
+ void Attach(LPITEMIDLIST object)
+ {
+ Free();
+ m_Object = object;
+ }
+ LPITEMIDLIST Detach()
+ {
+ LPITEMIDLIST object = m_Object;
+ m_Object = NULL;
+ return object;
+ }
+ operator LPITEMIDLIST() { return m_Object;}
+ operator LPCITEMIDLIST() const { return m_Object;}
+ LPITEMIDLIST* operator&() { return &m_Object; }
+ LPITEMIDLIST operator->() { return m_Object; }
+
+ // CItemIDList& operator=(LPCITEMIDLIST object);
+ // CItemIDList& operator=(const CItemIDList &object);
+};
+
+/////////////////////////////
+// CDrop
+
+class CDrop
+{
+ HDROP m_Object;
+ bool m_MustBeFinished;
+ bool m_Assigned;
+ void Free();
+public:
+ CDrop(bool mustBeFinished) : m_MustBeFinished(mustBeFinished),
+ m_Assigned(false) {}
+ ~CDrop();
+ void Attach(HDROP object);
+ operator HDROP() { return m_Object;}
+ bool QueryPoint(LPPOINT point)
+ { return BOOLToBool(::DragQueryPoint(m_Object, point)); }
+ void Finish() { ::DragFinish(m_Object); }
+ UINT QueryFile(UINT fileIndex, LPTSTR fileName, UINT fileNameSize);
+ UINT QueryCountOfFiles();
+ CSysString QueryFileName(UINT fileIndex);
+ void QueryFileNames(CSysStringVector &fileNames);
+};
+
+/////////////////////////////
+// Functions
+
+bool GetPathFromIDList(LPCITEMIDLIST itemIDList, CSysString &path);
+
+bool BrowseForFolder(LPBROWSEINFO lpbi, CSysString &resultPath);
+bool BrowseForFolder(HWND owner, LPCTSTR title,
+ LPCTSTR initialFolder, CSysString &resultPath);
+
+}}
+
+
+#endif \ No newline at end of file
diff --git a/Windows/StdAfx.h b/Windows/StdAfx.h
new file mode 100755
index 00000000..a32fbed6
--- /dev/null
+++ b/Windows/StdAfx.h
@@ -0,0 +1,8 @@
+// stdafx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+
+#endif
diff --git a/Windows/Synchronization.cpp b/Windows/Synchronization.cpp
new file mode 100755
index 00000000..64b811da
--- /dev/null
+++ b/Windows/Synchronization.cpp
@@ -0,0 +1,17 @@
+// Windows/Synchronization.cpp
+
+#include "StdAfx.h"
+
+#include "Synchronization.h"
+
+namespace NWindows {
+namespace NSynchronization {
+
+CEvent::CEvent(bool manualReset, bool initiallyOwn, LPCTSTR name,
+ LPSECURITY_ATTRIBUTES securityAttributes)
+{
+ if (!Create(manualReset, initiallyOwn, name, securityAttributes))
+ throw "CreateEvent error";
+}
+
+}}
diff --git a/Windows/Synchronization.h b/Windows/Synchronization.h
new file mode 100755
index 00000000..72e51342
--- /dev/null
+++ b/Windows/Synchronization.h
@@ -0,0 +1,116 @@
+// Windows/Synchronization.h
+
+#pragma once
+
+#ifndef __WINDOWS_SYNCHRONIZATION_H
+#define __WINDOWS_SYNCHRONIZATION_H
+
+#include "Defs.h"
+#include "Handle.h"
+
+namespace NWindows {
+namespace NSynchronization {
+
+class CObject: public CHandle
+{
+public:
+ bool Lock(DWORD timeoutInterval = INFINITE)
+ { return (::WaitForSingleObject(_handle, timeoutInterval) == WAIT_OBJECT_0); }
+};
+
+class CBaseEvent: public CObject
+{
+public:
+ bool Create(bool manualReset, bool initiallyOwn, LPCTSTR name = NULL,
+ LPSECURITY_ATTRIBUTES securityAttributes = NULL)
+ {
+ _handle = ::CreateEvent(securityAttributes, BoolToBOOL(manualReset),
+ BoolToBOOL(initiallyOwn), name);
+ return (_handle != 0);
+ }
+
+ bool Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)
+ {
+ _handle = ::OpenEvent(desiredAccess, BoolToBOOL(inheritHandle), name);
+ return (_handle != 0);
+ }
+
+ bool Set() { return BOOLToBool(::SetEvent(_handle)); }
+ bool Pulse() { return BOOLToBool(::PulseEvent(_handle)); }
+ bool Reset() { return BOOLToBool(::ResetEvent(_handle)); }
+};
+
+class CEvent: public CBaseEvent
+{
+public:
+ CEvent() {};
+ CEvent(bool manualReset, bool initiallyOwn,
+ LPCTSTR name = NULL, LPSECURITY_ATTRIBUTES securityAttributes = NULL);
+};
+
+class CManualResetEvent: public CEvent
+{
+public:
+ CManualResetEvent(bool initiallyOwn = false, LPCTSTR name = NULL,
+ LPSECURITY_ATTRIBUTES securityAttributes = NULL):
+ CEvent(true, initiallyOwn, name, securityAttributes) {};
+};
+
+class CAutoResetEvent: public CEvent
+{
+public:
+ CAutoResetEvent(bool initiallyOwn = false, LPCTSTR name = NULL,
+ LPSECURITY_ATTRIBUTES securityAttributes = NULL):
+ CEvent(false, initiallyOwn, name, securityAttributes) {};
+};
+
+class CMutex: public CObject
+{
+public:
+ bool Create(bool initiallyOwn, LPCTSTR name = NULL,
+ LPSECURITY_ATTRIBUTES securityAttributes = NULL)
+ {
+ _handle = ::CreateMutex(securityAttributes, BoolToBOOL(initiallyOwn), name);
+ return (_handle != 0);
+ }
+ bool Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)
+ {
+ _handle = ::OpenMutex(desiredAccess, BoolToBOOL(inheritHandle), name);
+ return (_handle != 0);
+ }
+ bool Release() { return BOOLToBool(::ReleaseMutex(_handle)); }
+};
+
+class CMutexLock
+{
+ CMutex &_object;
+public:
+ CMutexLock(CMutex &object): _object(object) { _object.Lock(); }
+ ~CMutexLock() { _object.Release(); }
+};
+
+class CCriticalSection
+{
+ CRITICAL_SECTION _object;
+ // void Initialize() { ::InitializeCriticalSection(&_object); }
+ // void Delete() { ::DeleteCriticalSection(&_object); }
+public:
+ CCriticalSection() { ::InitializeCriticalSection(&_object); }
+ ~CCriticalSection() { ::DeleteCriticalSection(&_object); }
+ void Enter() { ::EnterCriticalSection(&_object); }
+ void Leave() { ::LeaveCriticalSection(&_object); }
+};
+
+class CCriticalSectionLock
+{
+ CCriticalSection &_object;
+ void Unlock() { _object.Leave(); }
+public:
+ CCriticalSectionLock(CCriticalSection &object): _object(object)
+ {_object.Enter(); }
+ ~CCriticalSectionLock() { Unlock(); }
+};
+
+}}
+
+#endif
diff --git a/Windows/System.cpp b/Windows/System.cpp
new file mode 100755
index 00000000..655857a1
--- /dev/null
+++ b/Windows/System.cpp
@@ -0,0 +1,15 @@
+// Windows/System.h
+
+#include "StdAfx.h"
+
+#include "System.h"
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+namespace NWindows {
+namespace NSystem {
+
+
+}}
+
diff --git a/Windows/System.h b/Windows/System.h
new file mode 100755
index 00000000..1f6fa04e
--- /dev/null
+++ b/Windows/System.h
@@ -0,0 +1,15 @@
+// Windows/System.h
+
+#pragma once
+
+#ifndef __WINDOWS_SYSTEM_H
+#define __WINDOWS_SYSTEM_H
+
+#include "../Common/String.h"
+
+namespace NWindows {
+namespace NSystem {
+
+}}
+
+#endif
diff --git a/Windows/Thread.h b/Windows/Thread.h
new file mode 100755
index 00000000..4cb87e95
--- /dev/null
+++ b/Windows/Thread.h
@@ -0,0 +1,45 @@
+// Windows/Thread.h
+
+#pragma once
+
+#ifndef __WINDOWS_THREAD_H
+#define __WINDOWS_THREAD_H
+
+#include "Handle.h"
+#include "Defs.h"
+
+namespace NWindows {
+
+class CThread: public CHandle
+{
+public:
+ bool Create(LPSECURITY_ATTRIBUTES threadAttributes,
+ SIZE_T stackSize, LPTHREAD_START_ROUTINE startAddress,
+ LPVOID parameter, DWORD creationFlags, LPDWORD threadId)
+ {
+ _handle = ::CreateThread(threadAttributes, stackSize, startAddress,
+ parameter, creationFlags, threadId);
+ return (_handle != NULL);
+ }
+ bool Create(LPTHREAD_START_ROUTINE startAddress, LPVOID parameter)
+ {
+ DWORD threadId;
+ return Create(NULL, 0, startAddress, parameter, 0, &threadId);
+ }
+
+ DWORD Resume()
+ { return ::ResumeThread(_handle); }
+ DWORD Suspend()
+ { return ::SuspendThread(_handle); }
+ bool Terminate(DWORD exitCode)
+ { return BOOLToBool(::TerminateThread(_handle, exitCode)); }
+
+ int GetPriority()
+ { return ::GetThreadPriority(_handle); }
+ bool SetPriority(int priority)
+ { return BOOLToBool(::SetThreadPriority(_handle, priority)); }
+};
+
+}
+
+#endif
diff --git a/Windows/Time.h b/Windows/Time.h
new file mode 100755
index 00000000..296ae963
--- /dev/null
+++ b/Windows/Time.h
@@ -0,0 +1,58 @@
+// Windows/Time.h
+
+#pragma once
+
+#ifndef __WINDOWS_TIME_H
+#define __WINDOWS_TIME_H
+
+#include "Common/Types.h"
+// #include <windows.h>
+// #include <time.h>
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NTime {
+
+inline bool DosTimeToFileTime(UINT32 dosTime, FILETIME &fileTime)
+{
+ return BOOLToBool(::DosDateTimeToFileTime(UINT16(dosTime >> 16),
+ UINT16(dosTime & 0xFFFF), &fileTime));
+}
+
+inline bool FileTimeToDosTime(const FILETIME &fileTime, UINT32 &dosTime)
+{
+ return BOOLToBool(::FileTimeToDosDateTime(&fileTime,
+ ((LPWORD)&dosTime) + 1, (LPWORD)&dosTime));
+}
+
+const UINT64 kUnixTimeStartValue =
+ #if ( __GNUC__)
+ 116444736000000000LL;
+ #else
+ 116444736000000000;
+ #endif
+const UINT32 kNumTimeQuantumsInSecond = 10000000;
+
+inline void UnixTimeToFileTime(long unixTime, FILETIME &fileTime)
+{
+ ULONGLONG ll = UInt32x32To64(unixTime, kNumTimeQuantumsInSecond) +
+ kUnixTimeStartValue;
+ fileTime.dwLowDateTime = (DWORD) ll;
+ fileTime.dwHighDateTime = DWORD(ll >> 32);
+}
+
+inline bool FileTimeToUnixTime(const FILETIME &fileTime, long &unixTime)
+{
+ UINT64 winTime = (((UINT64)fileTime.dwHighDateTime) << 32) + fileTime.dwLowDateTime;
+ if (winTime < kUnixTimeStartValue)
+ return false;
+ winTime = (winTime - kUnixTimeStartValue) / kNumTimeQuantumsInSecond;
+ if (winTime >= 0xFFFFFFFF)
+ return false;
+ unixTime = (long)winTime;
+ return true;
+}
+
+}}
+
+#endif
diff --git a/Windows/Window.cpp b/Windows/Window.cpp
new file mode 100755
index 00000000..61e005c8
--- /dev/null
+++ b/Windows/Window.cpp
@@ -0,0 +1,80 @@
+// Windows/Window.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/Window.h"
+#ifndef _UNICODE
+#include "Common/StringConvert.h"
+#endif
+
+namespace NWindows {
+
+#ifndef _UNICODE
+bool CWindow::SetText(LPCWSTR s)
+{
+ if (::SetWindowTextW(_window, s))
+ return true;
+ if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ return false;
+ return SetText(UnicodeStringToMultiByte(s));
+}
+#endif
+
+bool CWindow::GetText(CSysString &s)
+{
+ s.Empty();
+ int length = GetTextLength();
+ if (length == 0)
+ return (::GetLastError() == ERROR_SUCCESS);
+ length = GetText(s.GetBuffer(length), length + 1);
+ s.ReleaseBuffer();
+ if (length == 0)
+ return (::GetLastError() != ERROR_SUCCESS);
+ return true;
+}
+
+#ifndef _UNICODE
+bool CWindow::GetText(UString &s)
+{
+ s.Empty();
+ int length = GetWindowTextLengthW(_window);
+ if (length == 0)
+ {
+ UINT lastError = ::GetLastError();
+ if (lastError == ERROR_SUCCESS)
+ return true;
+ if (lastError != ERROR_CALL_NOT_IMPLEMENTED)
+ return false;
+ CSysString sysString;
+ bool result = GetText(sysString);
+ s = GetUnicodeString(sysString);
+ return result;
+ }
+ length = GetWindowTextW(_window, s.GetBuffer(length), length + 1);
+ s.ReleaseBuffer();
+ if (length == 0)
+ return (::GetLastError() == ERROR_SUCCESS);
+ return true;
+}
+#endif
+
+/*
+bool CWindow::ModifyStyleBase(int styleOffset,
+ DWORD remove, DWORD add, UINT flags)
+{
+ DWORD style = GetWindowLong(styleOffset);
+ DWORD newStyle = (style & ~remove) | add;
+ if (style == newStyle)
+ return false; // it is not good
+
+ SetWindowLong(styleOffset, newStyle);
+ if (flags != 0)
+ {
+ ::SetWindowPos(_window, NULL, 0, 0, 0, 0,
+ SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | flags);
+ }
+ return TRUE;
+}
+*/
+
+}
diff --git a/Windows/Window.h b/Windows/Window.h
new file mode 100755
index 00000000..24786d12
--- /dev/null
+++ b/Windows/Window.h
@@ -0,0 +1,176 @@
+// Windows/Window.h
+
+#pragma once
+
+#ifndef __WINDOWS_WINDOW_H
+#define __WINDOWS_WINDOW_H
+
+#include "Windows/Defs.h"
+#include "Common/String.h"
+
+namespace NWindows {
+
+class CWindow
+{
+private:
+ // bool ModifyStyleBase(int styleOffset, DWORD remove, DWORD add, UINT flags);
+protected:
+ HWND _window;
+public:
+ CWindow(HWND newWindow = NULL): _window(newWindow){};
+ CWindow& operator=(HWND newWindow)
+ {
+ _window = newWindow;
+ return *this;
+ }
+ operator HWND() const { return _window; }
+ void Attach(HWND newWindow)
+ { _window = newWindow; }
+ HWND Detach()
+ {
+ HWND window = _window;
+ _window = NULL;
+ return window;
+ }
+
+ HWND GetParent() const
+ { return ::GetParent(_window); }
+ bool GetWindowRect(LPRECT rect) const
+ { return BOOLToBool(::GetWindowRect(_window,rect )); }
+ bool IsZoomed() const
+ { return BOOLToBool(::IsZoomed(_window)); }
+
+ bool ClientToScreen(LPPOINT point) const
+ { return BOOLToBool(::ClientToScreen(_window, point)); }
+
+ bool ScreenToClient(LPPOINT point) const
+ { return BOOLToBool(::ScreenToClient(_window, point)); }
+
+ bool CreateEx(DWORD exStyle, LPCTSTR className,
+ LPCTSTR windowName, DWORD style,
+ int x, int y, int width, int height,
+ HWND parentWindow, HMENU idOrHMenu,
+ HINSTANCE instance, LPVOID createParam)
+ {
+ _window = ::CreateWindowEx(exStyle, className, windowName,
+ style, x, y, width, height, parentWindow,
+ idOrHMenu, instance, createParam);
+ return (_window != NULL);
+ }
+
+ bool Destroy()
+ {
+ if (_window == NULL)
+ return true;
+ bool result = BOOLToBool(::DestroyWindow(_window));
+ if(result)
+ _window = NULL;
+ return result;
+ }
+ bool IsWindow()
+ { return BOOLToBool(::IsWindow(_window)); }
+ bool Move(int x, int y, int width, int height, bool repaint = true)
+ { return BOOLToBool(::MoveWindow(_window, x, y, width, height, BoolToBOOL(repaint))); }
+ bool GetClientRect(LPRECT rect)
+ { return BOOLToBool(::GetClientRect(_window, rect)); }
+ bool Show(int cmdShow)
+ { return BOOLToBool(::ShowWindow(_window, cmdShow)); }
+ bool SetPlacement(CONST WINDOWPLACEMENT *placement)
+ { return BOOLToBool(::SetWindowPlacement(_window, placement)); }
+ bool GetPlacement(WINDOWPLACEMENT *placement)
+ { return BOOLToBool(::GetWindowPlacement(_window, placement)); }
+
+ bool Update()
+ { return BOOLToBool(::UpdateWindow(_window)); }
+ bool InvalidateRect(LPCRECT rect, bool backgroundErase = true)
+ { return BOOLToBool(::InvalidateRect(_window, rect, BoolToBOOL(backgroundErase))); }
+ void SetRedraw(bool redraw = true)
+ { SendMessage(WM_SETREDRAW, BoolToBOOL(redraw), 0); }
+
+ #ifndef _WIN32_WCE
+ LONG SetStyle(LONG_PTR style)
+ { return SetLongPtr(GWL_STYLE, style); }
+ DWORD GetStyle( ) const
+ { return GetLongPtr(GWL_STYLE); }
+ #else
+ LONG SetStyle(LONG_PTR style)
+ { return SetLong(GWL_STYLE, style); }
+ DWORD GetStyle( ) const
+ { return GetLong(GWL_STYLE); }
+ #endif
+
+ LONG_PTR SetLong(int index, LONG_PTR newLongPtr )
+ { return ::SetWindowLong(_window, index, newLongPtr); }
+ LONG_PTR GetLong(int index) const
+ { return ::GetWindowLong(_window, index ); }
+ LONG_PTR SetUserDataLong(LONG_PTR newLongPtr )
+ { return SetLong(GWL_USERDATA, newLongPtr); }
+ LONG_PTR GetUserDataLong() const
+ { return GetLong(GWL_USERDATA); }
+
+ #ifndef _WIN32_WCE
+ LONG_PTR SetLongPtr(int index, LONG_PTR newLongPtr )
+ { return ::SetWindowLongPtr(_window, index, newLongPtr); }
+ LONG_PTR GetLongPtr(int index) const
+ { return ::GetWindowLongPtr(_window, index ); }
+ LONG_PTR SetUserDataLongPtr(LONG_PTR newLongPtr )
+ { return SetLongPtr(GWLP_USERDATA, newLongPtr); }
+ LONG_PTR GetUserDataLongPtr() const
+ { return GetLongPtr(GWLP_USERDATA); }
+ #endif
+
+ /*
+ bool ModifyStyle(HWND hWnd, DWORD remove, DWORD add, UINT flags = 0)
+ { return ModifyStyleBase(GWL_STYLE, remove, add, flags); }
+ bool ModifyStyleEx(HWND hWnd, DWORD remove, DWORD add, UINT flags = 0)
+ { return ModifyStyleBase(GWL_EXSTYLE, remove, add, flags); }
+ */
+
+ HWND SetFocus()
+ { return ::SetFocus(_window); }
+
+ LRESULT SendMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
+ { return ::SendMessage(_window, message, wParam, lParam) ;}
+ bool PostMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
+ { return BOOLToBool(::PostMessage(_window, message, wParam, lParam)) ;}
+
+ bool SetText(LPCTSTR s)
+ { return BOOLToBool(::SetWindowText(_window, s)); }
+ #ifndef _UNICODE
+ bool CWindow::SetText(LPCWSTR s);
+ #endif
+
+ int GetTextLength() const
+ { return GetWindowTextLength(_window); }
+ UINT GetText(LPTSTR string, int maxCount) const
+ { return GetWindowText(_window, string, maxCount); }
+ bool GetText(CSysString &s);
+ #ifndef _UNICODE
+ /*
+ UINT GetText(LPWSTR string, int maxCount) const
+ { return GetWindowTextW(_window, string, maxCount); }
+ */
+ bool GetText(UString &s);
+ #endif
+
+ bool Enable(bool enable)
+ { return BOOLToBool(::EnableWindow(_window, BoolToBOOL(enable))); }
+
+ bool IsEnabled()
+ { return BOOLToBool(::IsWindowEnabled(_window)); }
+
+ #ifndef _WIN32_WCE
+ HMENU GetSystemMenu(bool revert)
+ { return ::GetSystemMenu(_window, BoolToBOOL(revert)); }
+ #endif
+
+ UINT_PTR SetTimer(UINT_PTR idEvent, UINT elapse, TIMERPROC timerFunc = 0)
+ { return ::SetTimer(_window, idEvent, elapse, timerFunc); }
+ bool KillTimer(UINT_PTR idEvent)
+ {return BOOLToBool(::KillTimer(_window, idEvent)); }
+};
+
+}
+
+#endif
+