From d9666cf046a8453b33b3e2fbf4d82295a9f87df3 Mon Sep 17 00:00:00 2001 From: Igor Pavlov Date: Sat, 20 Jan 2007 00:00:00 +0000 Subject: 4.44 beta --- CPP/7zip/Archive/7z/7z.dsp | 593 +++++ CPP/7zip/Archive/7z/7z.dsw | 29 + CPP/7zip/Archive/7z/7z.ico | Bin 0 -> 4710 bytes CPP/7zip/Archive/7z/7zCompressionMode.cpp | 3 + CPP/7zip/Archive/7z/7zCompressionMode.h | 64 + CPP/7zip/Archive/7z/7zDecode.cpp | 444 ++++ CPP/7zip/Archive/7z/7zDecode.h | 71 + CPP/7zip/Archive/7z/7zEncode.cpp | 614 ++++++ CPP/7zip/Archive/7z/7zEncode.h | 58 + CPP/7zip/Archive/7z/7zExtract.cpp | 265 +++ CPP/7zip/Archive/7z/7zFolderInStream.cpp | 129 ++ CPP/7zip/Archive/7z/7zFolderInStream.h | 66 + CPP/7zip/Archive/7z/7zFolderOutStream.cpp | 162 ++ CPP/7zip/Archive/7z/7zFolderOutStream.h | 57 + CPP/7zip/Archive/7z/7zHandler.cpp | 794 +++++++ CPP/7zip/Archive/7z/7zHandler.h | 249 +++ CPP/7zip/Archive/7z/7zHandlerOut.cpp | 1148 ++++++++++ CPP/7zip/Archive/7z/7zHeader.cpp | 19 + CPP/7zip/Archive/7z/7zHeader.h | 96 + CPP/7zip/Archive/7z/7zIn.cpp | 1335 ++++++++++++ CPP/7zip/Archive/7z/7zIn.h | 288 +++ CPP/7zip/Archive/7z/7zItem.h | 181 ++ CPP/7zip/Archive/7z/7zMethodID.cpp | 76 + CPP/7zip/Archive/7z/7zMethodID.h | 29 + CPP/7zip/Archive/7z/7zMethods.cpp | 174 ++ CPP/7zip/Archive/7z/7zMethods.h | 36 + CPP/7zip/Archive/7z/7zOut.cpp | 1136 ++++++++++ CPP/7zip/Archive/7z/7zOut.h | 192 ++ CPP/7zip/Archive/7z/7zProperties.cpp | 166 ++ CPP/7zip/Archive/7z/7zProperties.h | 22 + CPP/7zip/Archive/7z/7zSpecStream.cpp | 24 + CPP/7zip/Archive/7z/7zSpecStream.h | 35 + CPP/7zip/Archive/7z/7zUpdate.cpp | 1099 ++++++++++ CPP/7zip/Archive/7z/7zUpdate.h | 79 + CPP/7zip/Archive/7z/DllExports.cpp | 113 + CPP/7zip/Archive/7z/StdAfx.cpp | 3 + CPP/7zip/Archive/7z/StdAfx.h | 9 + CPP/7zip/Archive/7z/makefile | 89 + CPP/7zip/Archive/7z/resource.rc | 5 + CPP/7zip/Archive/Archive.def | 3 + CPP/7zip/Archive/Arj/Arj.dsp | 329 +++ CPP/7zip/Archive/Arj/Arj.dsw | 29 + CPP/7zip/Archive/Arj/ArjHandler.cpp | 485 +++++ CPP/7zip/Archive/Arj/ArjHandler.h | 47 + CPP/7zip/Archive/Arj/ArjHeader.h | 121 + CPP/7zip/Archive/Arj/ArjIn.cpp | 283 +++ CPP/7zip/Archive/Arj/ArjIn.h | 75 + CPP/7zip/Archive/Arj/ArjItem.h | 75 + CPP/7zip/Archive/Arj/DllExports.cpp | 72 + CPP/7zip/Archive/Arj/StdAfx.cpp | 3 + CPP/7zip/Archive/Arj/StdAfx.h | 8 + CPP/7zip/Archive/Arj/arj.ico | Bin 0 -> 3638 bytes CPP/7zip/Archive/Arj/makefile | 66 + CPP/7zip/Archive/Arj/resource.rc | 5 + CPP/7zip/Archive/BZip2/BZip2.dsp | 281 +++ CPP/7zip/Archive/BZip2/BZip2.dsw | 29 + CPP/7zip/Archive/BZip2/BZip2Handler.cpp | 287 +++ CPP/7zip/Archive/BZip2/BZip2Handler.h | 83 + CPP/7zip/Archive/BZip2/BZip2HandlerOut.cpp | 156 ++ CPP/7zip/Archive/BZip2/BZip2Item.h | 20 + CPP/7zip/Archive/BZip2/BZip2Update.cpp | 84 + CPP/7zip/Archive/BZip2/BZip2Update.h | 24 + CPP/7zip/Archive/BZip2/DllExports.cpp | 127 ++ CPP/7zip/Archive/BZip2/StdAfx.cpp | 3 + CPP/7zip/Archive/BZip2/StdAfx.h | 8 + CPP/7zip/Archive/BZip2/bz2.ico | Bin 0 -> 3638 bytes CPP/7zip/Archive/BZip2/makefile | 55 + CPP/7zip/Archive/BZip2/resource.rc | 5 + CPP/7zip/Archive/Cab/Cab.dsp | 395 ++++ CPP/7zip/Archive/Cab/Cab.dsw | 29 + CPP/7zip/Archive/Cab/CabBlockInStream.cpp | 194 ++ CPP/7zip/Archive/Cab/CabBlockInStream.h | 56 + CPP/7zip/Archive/Cab/CabHandler.cpp | 812 +++++++ CPP/7zip/Archive/Cab/CabHandler.h | 45 + CPP/7zip/Archive/Cab/CabHeader.cpp | 19 + CPP/7zip/Archive/Cab/CabHeader.h | 42 + CPP/7zip/Archive/Cab/CabIn.cpp | 343 +++ CPP/7zip/Archive/Cab/CabIn.h | 166 ++ CPP/7zip/Archive/Cab/CabItem.h | 62 + CPP/7zip/Archive/Cab/DllExports.cpp | 72 + CPP/7zip/Archive/Cab/StdAfx.cpp | 3 + CPP/7zip/Archive/Cab/StdAfx.h | 8 + CPP/7zip/Archive/Cab/cab.ico | Bin 0 -> 3638 bytes CPP/7zip/Archive/Cab/makefile | 70 + CPP/7zip/Archive/Cab/resource.rc | 5 + CPP/7zip/Archive/Chm/Chm.dsp | 337 +++ CPP/7zip/Archive/Chm/Chm.dsw | 29 + CPP/7zip/Archive/Chm/ChmHandler.cpp | 731 +++++++ CPP/7zip/Archive/Chm/ChmHandler.h | 46 + CPP/7zip/Archive/Chm/ChmHeader.cpp | 24 + CPP/7zip/Archive/Chm/ChmHeader.h | 28 + CPP/7zip/Archive/Chm/ChmIn.cpp | 925 ++++++++ CPP/7zip/Archive/Chm/ChmIn.h | 242 ++ CPP/7zip/Archive/Chm/DllExports.cpp | 77 + CPP/7zip/Archive/Chm/StdAfx.cpp | 3 + CPP/7zip/Archive/Chm/StdAfx.h | 8 + CPP/7zip/Archive/Chm/makefile | 68 + CPP/7zip/Archive/Chm/resource.rc | 3 + CPP/7zip/Archive/Common/CodecsPath.cpp | 34 + CPP/7zip/Archive/Common/CodecsPath.h | 12 + CPP/7zip/Archive/Common/CoderLoader.cpp | 31 + CPP/7zip/Archive/Common/CoderLoader.h | 147 ++ CPP/7zip/Archive/Common/CoderMixer2.cpp | 121 + CPP/7zip/Archive/Common/CoderMixer2.h | 168 ++ CPP/7zip/Archive/Common/CoderMixer2MT.cpp | 359 +++ CPP/7zip/Archive/Common/CoderMixer2MT.h | 121 + CPP/7zip/Archive/Common/CoderMixer2ST.cpp | 238 ++ CPP/7zip/Archive/Common/CoderMixer2ST.h | 88 + CPP/7zip/Archive/Common/CrossThreadProgress.cpp | 15 + CPP/7zip/Archive/Common/CrossThreadProgress.h | 31 + CPP/7zip/Archive/Common/DummyOutStream.cpp | 20 + CPP/7zip/Archive/Common/DummyOutStream.h | 23 + CPP/7zip/Archive/Common/FilterCoder.cpp | 243 +++ CPP/7zip/Archive/Common/FilterCoder.h | 130 ++ CPP/7zip/Archive/Common/InStreamWithCRC.cpp | 41 + CPP/7zip/Archive/Common/InStreamWithCRC.h | 65 + CPP/7zip/Archive/Common/ItemNameUtils.cpp | 59 + CPP/7zip/Archive/Common/ItemNameUtils.h | 24 + CPP/7zip/Archive/Common/MultiStream.cpp | 201 ++ CPP/7zip/Archive/Common/MultiStream.h | 76 + CPP/7zip/Archive/Common/OutStreamWithCRC.cpp | 24 + CPP/7zip/Archive/Common/OutStreamWithCRC.h | 37 + CPP/7zip/Archive/Common/ParseProperties.cpp | 171 ++ CPP/7zip/Archive/Common/ParseProperties.h | 17 + CPP/7zip/Archive/Common/StdAfx.h | 9 + CPP/7zip/Archive/Cpio/CpioHandler.cpp | 289 +++ CPP/7zip/Archive/Cpio/CpioHandler.h | 47 + CPP/7zip/Archive/Cpio/CpioHeader.cpp | 23 + CPP/7zip/Archive/Cpio/CpioHeader.h | 70 + CPP/7zip/Archive/Cpio/CpioIn.cpp | 271 +++ CPP/7zip/Archive/Cpio/CpioIn.h | 41 + CPP/7zip/Archive/Cpio/CpioItem.h | 55 + CPP/7zip/Archive/Cpio/DllExports.cpp | 65 + CPP/7zip/Archive/Cpio/StdAfx.cpp | 3 + CPP/7zip/Archive/Cpio/StdAfx.h | 8 + CPP/7zip/Archive/Cpio/cpio.dsp | 265 +++ CPP/7zip/Archive/Cpio/cpio.dsw | 29 + CPP/7zip/Archive/Cpio/cpio.ico | Bin 0 -> 3638 bytes CPP/7zip/Archive/Cpio/makefile | 55 + CPP/7zip/Archive/Cpio/resource.rc | 5 + CPP/7zip/Archive/Deb/Deb.dsp | 269 +++ CPP/7zip/Archive/Deb/Deb.dsw | 29 + CPP/7zip/Archive/Deb/DebHandler.cpp | 255 +++ CPP/7zip/Archive/Deb/DebHandler.h | 47 + CPP/7zip/Archive/Deb/DebHeader.cpp | 13 + CPP/7zip/Archive/Deb/DebHeader.h | 38 + CPP/7zip/Archive/Deb/DebIn.cpp | 165 ++ CPP/7zip/Archive/Deb/DebIn.h | 29 + CPP/7zip/Archive/Deb/DebItem.h | 32 + CPP/7zip/Archive/Deb/DllExports.cpp | 73 + CPP/7zip/Archive/Deb/StdAfx.cpp | 3 + CPP/7zip/Archive/Deb/StdAfx.h | 8 + CPP/7zip/Archive/Deb/deb.ico | Bin 0 -> 3638 bytes CPP/7zip/Archive/Deb/makefile | 54 + CPP/7zip/Archive/Deb/resource.rc | 5 + CPP/7zip/Archive/GZip/DllExports.cpp | 125 ++ CPP/7zip/Archive/GZip/GZip.dsp | 321 +++ CPP/7zip/Archive/GZip/GZip.dsw | 29 + CPP/7zip/Archive/GZip/GZipHandler.cpp | 361 +++ CPP/7zip/Archive/GZip/GZipHandler.h | 79 + CPP/7zip/Archive/GZip/GZipHandlerOut.cpp | 200 ++ CPP/7zip/Archive/GZip/GZipHeader.cpp | 20 + CPP/7zip/Archive/GZip/GZipHeader.h | 85 + CPP/7zip/Archive/GZip/GZipIn.cpp | 121 + CPP/7zip/Archive/GZip/GZipIn.h | 31 + CPP/7zip/Archive/GZip/GZipItem.h | 59 + CPP/7zip/Archive/GZip/GZipOut.cpp | 69 + CPP/7zip/Archive/GZip/GZipOut.h | 29 + CPP/7zip/Archive/GZip/GZipUpdate.cpp | 120 + CPP/7zip/Archive/GZip/GZipUpdate.h | 32 + CPP/7zip/Archive/GZip/StdAfx.cpp | 3 + CPP/7zip/Archive/GZip/StdAfx.h | 8 + CPP/7zip/Archive/GZip/gz.ico | Bin 0 -> 3638 bytes CPP/7zip/Archive/GZip/makefile | 60 + CPP/7zip/Archive/GZip/resource.rc | 5 + CPP/7zip/Archive/IArchive.h | 173 ++ CPP/7zip/Archive/Iso/DllExports.cpp | 88 + CPP/7zip/Archive/Iso/Iso.dsp | 273 +++ CPP/7zip/Archive/Iso/Iso.dsw | 29 + CPP/7zip/Archive/Iso/Iso.ico | Bin 0 -> 3638 bytes CPP/7zip/Archive/Iso/IsoHandler.cpp | 301 +++ CPP/7zip/Archive/Iso/IsoHandler.h | 59 + CPP/7zip/Archive/Iso/IsoHeader.cpp | 21 + CPP/7zip/Archive/Iso/IsoHeader.h | 61 + CPP/7zip/Archive/Iso/IsoIn.cpp | 438 ++++ CPP/7zip/Archive/Iso/IsoIn.h | 301 +++ CPP/7zip/Archive/Iso/IsoItem.h | 145 ++ CPP/7zip/Archive/Iso/StdAfx.cpp | 3 + CPP/7zip/Archive/Iso/StdAfx.h | 9 + CPP/7zip/Archive/Iso/makefile | 55 + CPP/7zip/Archive/Iso/resource.rc | 5 + CPP/7zip/Archive/Lzh/DllExports.cpp | 72 + CPP/7zip/Archive/Lzh/Lzh.def | 7 + CPP/7zip/Archive/Lzh/Lzh.dsp | 333 +++ CPP/7zip/Archive/Lzh/Lzh.dsw | 29 + CPP/7zip/Archive/Lzh/LzhCRC.cpp | 43 + CPP/7zip/Archive/Lzh/LzhCRC.h | 27 + CPP/7zip/Archive/Lzh/LzhHandler.cpp | 464 ++++ CPP/7zip/Archive/Lzh/LzhHandler.h | 47 + CPP/7zip/Archive/Lzh/LzhHeader.h | 19 + CPP/7zip/Archive/Lzh/LzhIn.cpp | 171 ++ CPP/7zip/Archive/Lzh/LzhIn.h | 29 + CPP/7zip/Archive/Lzh/LzhItem.h | 172 ++ CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp | 27 + CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.h | 38 + CPP/7zip/Archive/Lzh/StdAfx.cpp | 3 + CPP/7zip/Archive/Lzh/StdAfx.h | 8 + CPP/7zip/Archive/Lzh/lzh.ico | Bin 0 -> 3638 bytes CPP/7zip/Archive/Lzh/makefile | 65 + CPP/7zip/Archive/Lzh/resource.rc | 5 + CPP/7zip/Archive/Nsis/DllExports.cpp | 110 + CPP/7zip/Archive/Nsis/Nsis.dsp | 337 +++ CPP/7zip/Archive/Nsis/Nsis.dsw | 29 + CPP/7zip/Archive/Nsis/NsisDecode.cpp | 150 ++ CPP/7zip/Archive/Nsis/NsisDecode.h | 47 + CPP/7zip/Archive/Nsis/NsisHandler.cpp | 484 ++++ CPP/7zip/Archive/Nsis/NsisHandler.h | 41 + CPP/7zip/Archive/Nsis/NsisIn.cpp | 1169 ++++++++++ CPP/7zip/Archive/Nsis/NsisIn.h | 166 ++ CPP/7zip/Archive/Nsis/StdAfx.cpp | 3 + CPP/7zip/Archive/Nsis/StdAfx.h | 9 + CPP/7zip/Archive/Nsis/makefile | 67 + CPP/7zip/Archive/Nsis/resource.rc | 3 + CPP/7zip/Archive/RPM/DllExports.cpp | 68 + CPP/7zip/Archive/RPM/Rpm.dsp | 205 ++ CPP/7zip/Archive/RPM/Rpm.dsw | 29 + CPP/7zip/Archive/RPM/RpmHandler.cpp | 194 ++ CPP/7zip/Archive/RPM/RpmHandler.h | 46 + CPP/7zip/Archive/RPM/RpmHeader.h | 63 + CPP/7zip/Archive/RPM/RpmIn.cpp | 112 + CPP/7zip/Archive/RPM/RpmIn.h | 15 + CPP/7zip/Archive/RPM/StdAfx.cpp | 3 + CPP/7zip/Archive/RPM/StdAfx.h | 8 + CPP/7zip/Archive/RPM/makefile | 42 + CPP/7zip/Archive/RPM/resource.rc | 5 + CPP/7zip/Archive/RPM/rpm.ico | Bin 0 -> 3638 bytes CPP/7zip/Archive/Rar/DllExports.cpp | 142 ++ CPP/7zip/Archive/Rar/Rar.dsp | 459 ++++ CPP/7zip/Archive/Rar/Rar.dsw | 29 + CPP/7zip/Archive/Rar/RarHandler.cpp | 941 ++++++++ CPP/7zip/Archive/Rar/RarHandler.h | 63 + CPP/7zip/Archive/Rar/RarHeader.cpp | 21 + CPP/7zip/Archive/Rar/RarHeader.h | 224 ++ CPP/7zip/Archive/Rar/RarIn.cpp | 535 +++++ CPP/7zip/Archive/Rar/RarIn.h | 124 ++ CPP/7zip/Archive/Rar/RarItem.cpp | 118 + CPP/7zip/Archive/Rar/RarItem.h | 91 + CPP/7zip/Archive/Rar/RarVolumeInStream.cpp | 79 + CPP/7zip/Archive/Rar/RarVolumeInStream.h | 50 + CPP/7zip/Archive/Rar/StdAfx.cpp | 3 + CPP/7zip/Archive/Rar/StdAfx.h | 8 + CPP/7zip/Archive/Rar/makefile | 90 + CPP/7zip/Archive/Rar/rar.ico | Bin 0 -> 3638 bytes CPP/7zip/Archive/Rar/resource.rc | 5 + CPP/7zip/Archive/Split/DllExports.cpp | 65 + CPP/7zip/Archive/Split/Split.dsp | 237 ++ CPP/7zip/Archive/Split/Split.dsw | 29 + CPP/7zip/Archive/Split/Split.ico | Bin 0 -> 3638 bytes CPP/7zip/Archive/Split/SplitHandler.cpp | 415 ++++ CPP/7zip/Archive/Split/SplitHandler.h | 62 + CPP/7zip/Archive/Split/SplitHandlerOut.cpp | 102 + CPP/7zip/Archive/Split/StdAfx.cpp | 3 + CPP/7zip/Archive/Split/StdAfx.h | 8 + CPP/7zip/Archive/Split/makefile | 51 + CPP/7zip/Archive/Split/resource.rc | 5 + CPP/7zip/Archive/Tar/DllExports.cpp | 86 + CPP/7zip/Archive/Tar/StdAfx.cpp | 3 + CPP/7zip/Archive/Tar/StdAfx.h | 9 + CPP/7zip/Archive/Tar/Tar.dsp | 297 +++ CPP/7zip/Archive/Tar/Tar.dsw | 29 + CPP/7zip/Archive/Tar/TarHandler.cpp | 282 +++ CPP/7zip/Archive/Tar/TarHandler.h | 56 + CPP/7zip/Archive/Tar/TarHandlerOut.cpp | 126 ++ CPP/7zip/Archive/Tar/TarHeader.cpp | 25 + CPP/7zip/Archive/Tar/TarHeader.h | 99 + CPP/7zip/Archive/Tar/TarIn.cpp | 248 +++ CPP/7zip/Archive/Tar/TarIn.h | 30 + CPP/7zip/Archive/Tar/TarItem.h | 69 + CPP/7zip/Archive/Tar/TarOut.cpp | 191 ++ CPP/7zip/Archive/Tar/TarOut.h | 28 + CPP/7zip/Archive/Tar/TarUpdate.cpp | 162 ++ CPP/7zip/Archive/Tar/TarUpdate.h | 36 + CPP/7zip/Archive/Tar/makefile | 59 + CPP/7zip/Archive/Tar/resource.rc | 5 + CPP/7zip/Archive/Tar/tar.ico | Bin 0 -> 3638 bytes CPP/7zip/Archive/Z/DllExports.cpp | 91 + CPP/7zip/Archive/Z/StdAfx.cpp | 3 + CPP/7zip/Archive/Z/StdAfx.h | 8 + CPP/7zip/Archive/Z/Z.dsp | 237 ++ CPP/7zip/Archive/Z/Z.dsw | 29 + CPP/7zip/Archive/Z/Z.ico | Bin 0 -> 3638 bytes CPP/7zip/Archive/Z/ZHandler.cpp | 202 ++ CPP/7zip/Archive/Z/ZHandler.h | 47 + CPP/7zip/Archive/Z/makefile | 52 + CPP/7zip/Archive/Z/resource.rc | 5 + CPP/7zip/Archive/Zip/DllExports.cpp | 152 ++ CPP/7zip/Archive/Zip/StdAfx.cpp | 3 + CPP/7zip/Archive/Zip/StdAfx.h | 8 + CPP/7zip/Archive/Zip/Zip.dsp | 651 ++++++ CPP/7zip/Archive/Zip/Zip.dsw | 29 + CPP/7zip/Archive/Zip/ZipAddCommon.cpp | 309 +++ CPP/7zip/Archive/Zip/ZipAddCommon.h | 58 + CPP/7zip/Archive/Zip/ZipCompressionMode.h | 39 + CPP/7zip/Archive/Zip/ZipHandler.cpp | 766 +++++++ CPP/7zip/Archive/Zip/ZipHandler.h | 100 + CPP/7zip/Archive/Zip/ZipHandlerOut.cpp | 393 ++++ CPP/7zip/Archive/Zip/ZipHeader.cpp | 36 + CPP/7zip/Archive/Zip/ZipHeader.h | 248 +++ CPP/7zip/Archive/Zip/ZipIn.cpp | 797 +++++++ CPP/7zip/Archive/Zip/ZipIn.h | 111 + CPP/7zip/Archive/Zip/ZipItem.cpp | 137 ++ CPP/7zip/Archive/Zip/ZipItem.h | 191 ++ CPP/7zip/Archive/Zip/ZipItemEx.h | 29 + CPP/7zip/Archive/Zip/ZipOut.cpp | 259 +++ CPP/7zip/Archive/Zip/ZipOut.h | 51 + CPP/7zip/Archive/Zip/ZipUpdate.cpp | 734 +++++++ CPP/7zip/Archive/Zip/ZipUpdate.h | 52 + CPP/7zip/Archive/Zip/makefile | 124 ++ CPP/7zip/Archive/Zip/resource.rc | 5 + CPP/7zip/Archive/Zip/zip.ico | Bin 0 -> 3638 bytes CPP/7zip/Archive/makefile | 23 + CPP/7zip/Bundles/Alone/Alone.dsp | 2301 ++++++++++++++++++++ CPP/7zip/Bundles/Alone/Alone.dsw | 29 + CPP/7zip/Bundles/Alone/StdAfx.cpp | 3 + CPP/7zip/Bundles/Alone/StdAfx.h | 9 + CPP/7zip/Bundles/Alone/afxres.h | 1 + CPP/7zip/Bundles/Alone/makefile | 390 ++++ CPP/7zip/Bundles/Alone/resource.rc | 3 + CPP/7zip/Bundles/Alone7z/Alone.dsp | 1358 ++++++++++++ CPP/7zip/Bundles/Alone7z/Alone.dsw | 29 + CPP/7zip/Bundles/Alone7z/StdAfx.cpp | 3 + CPP/7zip/Bundles/Alone7z/StdAfx.h | 9 + CPP/7zip/Bundles/Alone7z/makefile | 196 ++ CPP/7zip/Bundles/Alone7z/resource.rc | 3 + CPP/7zip/Bundles/Format7z/Format7z.dsp | 1006 +++++++++ CPP/7zip/Bundles/Format7z/Format7z.dsw | 29 + CPP/7zip/Bundles/Format7z/StdAfx.cpp | 3 + CPP/7zip/Bundles/Format7z/StdAfx.h | 9 + CPP/7zip/Bundles/Format7z/makefile | 201 ++ CPP/7zip/Bundles/Format7z/resource.rc | 5 + CPP/7zip/Bundles/Format7zExtract/Format7z.dsp | 813 +++++++ CPP/7zip/Bundles/Format7zExtract/Format7z.dsw | 29 + CPP/7zip/Bundles/Format7zExtract/StdAfx.cpp | 3 + CPP/7zip/Bundles/Format7zExtract/StdAfx.h | 9 + CPP/7zip/Bundles/Format7zExtract/makefile | 174 ++ CPP/7zip/Bundles/Format7zExtract/resource.rc | 5 + CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp | 3 + CPP/7zip/Bundles/Format7zExtractR/StdAfx.h | 9 + CPP/7zip/Bundles/Format7zExtractR/makefile | 117 + CPP/7zip/Bundles/Format7zExtractR/resource.rc | 5 + CPP/7zip/Bundles/Format7zR/StdAfx.cpp | 3 + CPP/7zip/Bundles/Format7zR/StdAfx.h | 9 + CPP/7zip/Bundles/Format7zR/makefile | 150 ++ CPP/7zip/Bundles/Format7zR/resource.rc | 5 + CPP/7zip/Bundles/SFXCon/7z.ico | Bin 0 -> 1078 bytes CPP/7zip/Bundles/SFXCon/Main.cpp | 416 ++++ CPP/7zip/Bundles/SFXCon/SFXCon.dsp | 759 +++++++ CPP/7zip/Bundles/SFXCon/SFXCon.dsw | 29 + CPP/7zip/Bundles/SFXCon/StdAfx.cpp | 3 + CPP/7zip/Bundles/SFXCon/StdAfx.h | 9 + CPP/7zip/Bundles/SFXCon/makefile | 180 ++ CPP/7zip/Bundles/SFXCon/resource.rc | 5 + CPP/7zip/Bundles/SFXSetup/ExtractCallback.cpp | 249 +++ CPP/7zip/Bundles/SFXSetup/ExtractCallback.h | 96 + CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp | 139 ++ CPP/7zip/Bundles/SFXSetup/ExtractEngine.h | 17 + CPP/7zip/Bundles/SFXSetup/Main.cpp | 335 +++ CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp | 696 ++++++ CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw | 29 + CPP/7zip/Bundles/SFXSetup/StdAfx.cpp | 3 + CPP/7zip/Bundles/SFXSetup/StdAfx.h | 10 + CPP/7zip/Bundles/SFXSetup/makefile | 156 ++ CPP/7zip/Bundles/SFXSetup/resource.h | 6 + CPP/7zip/Bundles/SFXSetup/resource.rc | 16 + CPP/7zip/Bundles/SFXSetup/setup.ico | Bin 0 -> 1078 bytes CPP/7zip/Bundles/SFXWin/7z.ico | Bin 0 -> 1078 bytes CPP/7zip/Bundles/SFXWin/Main.cpp | 115 + CPP/7zip/Bundles/SFXWin/SFXWin.dsp | 847 +++++++ CPP/7zip/Bundles/SFXWin/SFXWin.dsw | 29 + CPP/7zip/Bundles/SFXWin/StdAfx.cpp | 3 + CPP/7zip/Bundles/SFXWin/StdAfx.h | 12 + CPP/7zip/Bundles/SFXWin/makefile | 207 ++ CPP/7zip/Bundles/SFXWin/resource.h | 7 + CPP/7zip/Bundles/SFXWin/resource.rc | 34 + CPP/7zip/Bundles/makefile | 15 + CPP/7zip/Common/FilePathAutoRename.cpp | 57 + CPP/7zip/Common/FilePathAutoRename.h | 10 + CPP/7zip/Common/FileStreams.cpp | 251 +++ CPP/7zip/Common/FileStreams.h | 98 + CPP/7zip/Common/InBuffer.cpp | 80 + CPP/7zip/Common/InBuffer.h | 76 + CPP/7zip/Common/InMemStream.cpp | 222 ++ CPP/7zip/Common/InMemStream.h | 282 +++ CPP/7zip/Common/InOutTempBuffer.cpp | 122 ++ CPP/7zip/Common/InOutTempBuffer.h | 55 + CPP/7zip/Common/LSBFDecoder.cpp | 27 + CPP/7zip/Common/LSBFDecoder.h | 127 ++ CPP/7zip/Common/LSBFEncoder.cpp | 29 + CPP/7zip/Common/LSBFEncoder.h | 51 + CPP/7zip/Common/LimitedStreams.cpp | 24 + CPP/7zip/Common/LimitedStreams.h | 33 + CPP/7zip/Common/LockedStream.cpp | 23 + CPP/7zip/Common/LockedStream.h | 38 + CPP/7zip/Common/MSBFDecoder.h | 69 + CPP/7zip/Common/MSBFEncoder.h | 59 + CPP/7zip/Common/MemBlocks.cpp | 184 ++ CPP/7zip/Common/MemBlocks.h | 73 + CPP/7zip/Common/OffsetStream.cpp | 35 + CPP/7zip/Common/OffsetStream.h | 25 + CPP/7zip/Common/OutBuffer.cpp | 116 + CPP/7zip/Common/OutBuffer.h | 64 + CPP/7zip/Common/OutMemStream.cpp | 137 ++ CPP/7zip/Common/OutMemStream.h | 88 + CPP/7zip/Common/ProgressMt.cpp | 53 + CPP/7zip/Common/ProgressMt.h | 47 + CPP/7zip/Common/ProgressUtils.cpp | 55 + CPP/7zip/Common/ProgressUtils.h | 43 + CPP/7zip/Common/StdAfx.h | 9 + CPP/7zip/Common/StreamBinder.cpp | 162 ++ CPP/7zip/Common/StreamBinder.h | 37 + CPP/7zip/Common/StreamObjects.cpp | 68 + CPP/7zip/Common/StreamObjects.h | 117 + CPP/7zip/Common/StreamUtils.cpp | 44 + CPP/7zip/Common/StreamUtils.h | 11 + CPP/7zip/Compress/Arj/ArjDecoder1.cpp | 319 +++ CPP/7zip/Compress/Arj/ArjDecoder1.h | 105 + CPP/7zip/Compress/Arj/ArjDecoder2.cpp | 93 + CPP/7zip/Compress/Arj/ArjDecoder2.h | 65 + CPP/7zip/Compress/Arj/StdAfx.h | 8 + CPP/7zip/Compress/BWT/BlockSort.cpp | 487 +++++ CPP/7zip/Compress/BWT/BlockSort.h | 21 + CPP/7zip/Compress/BWT/Mtf8.h | 195 ++ CPP/7zip/Compress/BWT/StdAfx.h | 6 + CPP/7zip/Compress/BZip2/BZip2.dsp | 303 +++ CPP/7zip/Compress/BZip2/BZip2.dsw | 29 + CPP/7zip/Compress/BZip2/BZip2CRC.cpp | 26 + CPP/7zip/Compress/BZip2/BZip2CRC.h | 31 + CPP/7zip/Compress/BZip2/BZip2Const.h | 54 + CPP/7zip/Compress/BZip2/BZip2Decoder.cpp | 770 +++++++ CPP/7zip/Compress/BZip2/BZip2Decoder.h | 164 ++ CPP/7zip/Compress/BZip2/BZip2Encoder.cpp | 883 ++++++++ CPP/7zip/Compress/BZip2/BZip2Encoder.h | 246 +++ CPP/7zip/Compress/BZip2/DllExports.cpp | 93 + CPP/7zip/Compress/BZip2/StdAfx.cpp | 3 + CPP/7zip/Compress/BZip2/StdAfx.h | 8 + CPP/7zip/Compress/BZip2/makefile | 56 + CPP/7zip/Compress/BZip2/resource.rc | 3 + CPP/7zip/Compress/BZip2Original/BZip2Decoder.cpp | 131 ++ CPP/7zip/Compress/BZip2Original/BZip2Decoder.h | 38 + CPP/7zip/Compress/BZip2Original/BZip2Encoder.cpp | 120 + CPP/7zip/Compress/BZip2Original/BZip2Encoder.h | 30 + CPP/7zip/Compress/BZip2Original/BZip2Error.cpp | 10 + CPP/7zip/Compress/BZip2Original/DllExports.cpp | 86 + CPP/7zip/Compress/BZip2Original/StdAfx.cpp | 3 + CPP/7zip/Compress/BZip2Original/StdAfx.h | 8 + CPP/7zip/Compress/Branch/ARM.cpp | 16 + CPP/7zip/Compress/Branch/ARM.h | 10 + CPP/7zip/Compress/Branch/ARMThumb.cpp | 16 + CPP/7zip/Compress/Branch/ARMThumb.h | 10 + CPP/7zip/Compress/Branch/Branch.dsp | 298 +++ CPP/7zip/Compress/Branch/Branch.dsw | 29 + CPP/7zip/Compress/Branch/BranchCoder.cpp | 18 + CPP/7zip/Compress/Branch/BranchCoder.h | 54 + CPP/7zip/Compress/Branch/DllExports.cpp | 152 ++ CPP/7zip/Compress/Branch/IA64.cpp | 16 + CPP/7zip/Compress/Branch/IA64.h | 10 + CPP/7zip/Compress/Branch/PPC.cpp | 17 + CPP/7zip/Compress/Branch/PPC.h | 10 + CPP/7zip/Compress/Branch/SPARC.cpp | 17 + CPP/7zip/Compress/Branch/SPARC.h | 10 + CPP/7zip/Compress/Branch/StdAfx.cpp | 3 + CPP/7zip/Compress/Branch/StdAfx.h | 8 + CPP/7zip/Compress/Branch/makefile | 48 + CPP/7zip/Compress/Branch/resource.rc | 3 + CPP/7zip/Compress/Branch/x86.cpp | 18 + CPP/7zip/Compress/Branch/x86.h | 19 + CPP/7zip/Compress/Branch/x86_2.cpp | 412 ++++ CPP/7zip/Compress/Branch/x86_2.h | 133 ++ CPP/7zip/Compress/ByteSwap/ByteSwap.cpp | 38 + CPP/7zip/Compress/ByteSwap/ByteSwap.dsp | 125 ++ CPP/7zip/Compress/ByteSwap/ByteSwap.dsw | 29 + CPP/7zip/Compress/ByteSwap/ByteSwap.h | 37 + CPP/7zip/Compress/ByteSwap/DllExports.cpp | 91 + CPP/7zip/Compress/ByteSwap/StdAfx.cpp | 3 + CPP/7zip/Compress/ByteSwap/StdAfx.h | 8 + CPP/7zip/Compress/ByteSwap/makefile | 23 + CPP/7zip/Compress/ByteSwap/resource.rc | 3 + CPP/7zip/Compress/Codec.def | 4 + CPP/7zip/Compress/Copy/Copy.dsp | 149 ++ CPP/7zip/Compress/Copy/Copy.dsw | 29 + CPP/7zip/Compress/Copy/CopyCoder.cpp | 52 + CPP/7zip/Compress/Copy/CopyCoder.h | 31 + CPP/7zip/Compress/Copy/DllExports.cpp | 70 + CPP/7zip/Compress/Copy/StdAfx.cpp | 3 + CPP/7zip/Compress/Copy/StdAfx.h | 8 + CPP/7zip/Compress/Copy/makefile | 30 + CPP/7zip/Compress/Copy/resource.rc | 3 + CPP/7zip/Compress/Deflate/Deflate.dsp | 341 +++ CPP/7zip/Compress/Deflate/Deflate.dsw | 29 + CPP/7zip/Compress/Deflate/DeflateConst.h | 134 ++ CPP/7zip/Compress/Deflate/DeflateDecoder.cpp | 339 +++ CPP/7zip/Compress/Deflate/DeflateDecoder.h | 134 ++ CPP/7zip/Compress/Deflate/DeflateEncoder.cpp | 963 ++++++++ CPP/7zip/Compress/Deflate/DeflateEncoder.h | 221 ++ CPP/7zip/Compress/Deflate/DllExports.cpp | 157 ++ CPP/7zip/Compress/Deflate/StdAfx.cpp | 3 + CPP/7zip/Compress/Deflate/StdAfx.h | 8 + CPP/7zip/Compress/Deflate/makefile | 63 + CPP/7zip/Compress/Deflate/resource.rc | 3 + CPP/7zip/Compress/Huffman/HuffmanDecoder.h | 88 + CPP/7zip/Compress/Huffman/StdAfx.h | 6 + CPP/7zip/Compress/Implode/DllExports.cpp | 65 + CPP/7zip/Compress/Implode/ImplodeDecoder.cpp | 222 ++ CPP/7zip/Compress/Implode/ImplodeDecoder.h | 60 + .../Compress/Implode/ImplodeHuffmanDecoder.cpp | 89 + CPP/7zip/Compress/Implode/ImplodeHuffmanDecoder.h | 33 + CPP/7zip/Compress/Implode/StdAfx.cpp | 3 + CPP/7zip/Compress/Implode/StdAfx.h | 8 + CPP/7zip/Compress/LZ/LZOutWindow.cpp | 17 + CPP/7zip/Compress/LZ/LZOutWindow.h | 56 + CPP/7zip/Compress/LZ/StdAfx.h | 6 + CPP/7zip/Compress/LZMA/DllExports.cpp | 109 + CPP/7zip/Compress/LZMA/LZMA.dsp | 478 ++++ CPP/7zip/Compress/LZMA/LZMA.dsw | 29 + CPP/7zip/Compress/LZMA/LZMA.h | 82 + CPP/7zip/Compress/LZMA/LZMADecoder.cpp | 338 +++ CPP/7zip/Compress/LZMA/LZMADecoder.h | 251 +++ CPP/7zip/Compress/LZMA/LZMAEncoder.cpp | 1530 +++++++++++++ CPP/7zip/Compress/LZMA/LZMAEncoder.h | 435 ++++ CPP/7zip/Compress/LZMA/StdAfx.cpp | 3 + CPP/7zip/Compress/LZMA/StdAfx.h | 8 + CPP/7zip/Compress/LZMA/makefile | 69 + CPP/7zip/Compress/LZMA/resource.rc | 3 + CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp | 449 ++++ CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsw | 29 + CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp | 526 +++++ CPP/7zip/Compress/LZMA_Alone/LzmaBench.cpp | 506 +++++ CPP/7zip/Compress/LZMA_Alone/LzmaBench.h | 11 + CPP/7zip/Compress/LZMA_Alone/LzmaRam.cpp | 227 ++ CPP/7zip/Compress/LZMA_Alone/LzmaRam.h | 46 + CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.c | 79 + CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.h | 55 + CPP/7zip/Compress/LZMA_Alone/StdAfx.cpp | 3 + CPP/7zip/Compress/LZMA_Alone/StdAfx.h | 8 + CPP/7zip/Compress/LZMA_Alone/makefile | 124 ++ CPP/7zip/Compress/LZMA_Alone/makefile.gcc | 117 + CPP/7zip/Compress/Lzh/LzhDecoder.cpp | 216 ++ CPP/7zip/Compress/Lzh/LzhDecoder.h | 103 + CPP/7zip/Compress/Lzx/Lzx.h | 61 + CPP/7zip/Compress/Lzx/Lzx86Converter.cpp | 90 + CPP/7zip/Compress/Lzx/Lzx86Converter.h | 45 + CPP/7zip/Compress/Lzx/LzxDecoder.cpp | 382 ++++ CPP/7zip/Compress/Lzx/LzxDecoder.h | 181 ++ CPP/7zip/Compress/Lzx/StdAfx.h | 8 + CPP/7zip/Compress/PPMD/DllExports.cpp | 93 + CPP/7zip/Compress/PPMD/PPMD.dsp | 229 ++ CPP/7zip/Compress/PPMD/PPMD.dsw | 29 + CPP/7zip/Compress/PPMD/PPMDContext.h | 489 +++++ CPP/7zip/Compress/PPMD/PPMDDecode.h | 154 ++ CPP/7zip/Compress/PPMD/PPMDDecoder.cpp | 184 ++ CPP/7zip/Compress/PPMD/PPMDDecoder.h | 89 + CPP/7zip/Compress/PPMD/PPMDEncode.h | 142 ++ CPP/7zip/Compress/PPMD/PPMDEncoder.cpp | 155 ++ CPP/7zip/Compress/PPMD/PPMDEncoder.h | 81 + CPP/7zip/Compress/PPMD/PPMDSubAlloc.h | 292 +++ CPP/7zip/Compress/PPMD/PPMDType.h | 19 + CPP/7zip/Compress/PPMD/StdAfx.cpp | 3 + CPP/7zip/Compress/PPMD/StdAfx.h | 8 + CPP/7zip/Compress/PPMD/makefile | 41 + CPP/7zip/Compress/PPMD/resource.rc | 3 + CPP/7zip/Compress/Quantum/QuantumDecoder.cpp | 173 ++ CPP/7zip/Compress/Quantum/QuantumDecoder.h | 287 +++ CPP/7zip/Compress/RangeCoder/RangeCoder.h | 205 ++ CPP/7zip/Compress/RangeCoder/RangeCoderBit.cpp | 80 + CPP/7zip/Compress/RangeCoder/RangeCoderBit.h | 120 + CPP/7zip/Compress/RangeCoder/RangeCoderBitTree.h | 161 ++ CPP/7zip/Compress/RangeCoder/RangeCoderOpt.h | 31 + CPP/7zip/Compress/RangeCoder/StdAfx.h | 6 + CPP/7zip/Compress/Rar/DllExports.cpp | 91 + CPP/7zip/Compress/Rar/Rar1Decoder.cpp | 485 +++++ CPP/7zip/Compress/Rar/Rar1Decoder.h | 90 + CPP/7zip/Compress/Rar/Rar29.dsp | 297 +++ CPP/7zip/Compress/Rar/Rar29.dsw | 29 + CPP/7zip/Compress/Rar/Rar2Decoder.cpp | 401 ++++ CPP/7zip/Compress/Rar/Rar2Decoder.h | 176 ++ CPP/7zip/Compress/Rar/Rar3Decoder.cpp | 832 +++++++ CPP/7zip/Compress/Rar/Rar3Decoder.h | 294 +++ CPP/7zip/Compress/Rar/Rar3Vm.cpp | 1089 +++++++++ CPP/7zip/Compress/Rar/Rar3Vm.h | 219 ++ CPP/7zip/Compress/Rar/StdAfx.cpp | 3 + CPP/7zip/Compress/Rar/StdAfx.h | 8 + CPP/7zip/Compress/Rar/makefile | 49 + CPP/7zip/Compress/Rar/resource.rc | 3 + CPP/7zip/Compress/Shrink/DllExports.cpp | 64 + CPP/7zip/Compress/Shrink/ShrinkDecoder.cpp | 149 ++ CPP/7zip/Compress/Shrink/ShrinkDecoder.h | 39 + CPP/7zip/Compress/Shrink/StdAfx.cpp | 3 + CPP/7zip/Compress/Shrink/StdAfx.h | 8 + CPP/7zip/Compress/Z/StdAfx.cpp | 3 + CPP/7zip/Compress/Z/StdAfx.h | 8 + CPP/7zip/Compress/Z/ZDecoder.cpp | 172 ++ CPP/7zip/Compress/Z/ZDecoder.h | 44 + CPP/7zip/Compress/makefile | 14 + CPP/7zip/Crypto/7zAES/7zAES.cpp | 305 +++ CPP/7zip/Crypto/7zAES/7zAES.dsp | 245 +++ CPP/7zip/Crypto/7zAES/7zAES.dsw | 29 + CPP/7zip/Crypto/7zAES/7zAES.h | 122 ++ CPP/7zip/Crypto/7zAES/DllExports.cpp | 111 + CPP/7zip/Crypto/7zAES/StdAfx.cpp | 3 + CPP/7zip/Crypto/7zAES/StdAfx.h | 8 + CPP/7zip/Crypto/7zAES/makefile | 52 + CPP/7zip/Crypto/7zAES/resource.rc | 3 + CPP/7zip/Crypto/AES/AES.dsp | 203 ++ CPP/7zip/Crypto/AES/AES.dsw | 29 + CPP/7zip/Crypto/AES/AES_CBC.h | 39 + CPP/7zip/Crypto/AES/DllExports.cpp | 100 + CPP/7zip/Crypto/AES/MyAES.cpp | 94 + CPP/7zip/Crypto/AES/MyAES.h | 106 + CPP/7zip/Crypto/AES/StdAfx.cpp | 3 + CPP/7zip/Crypto/AES/StdAfx.h | 8 + CPP/7zip/Crypto/AES/aes.h | 103 + CPP/7zip/Crypto/AES/aescpp.h | 55 + CPP/7zip/Crypto/AES/aescrypt.c | 421 ++++ CPP/7zip/Crypto/AES/aeskey.c | 363 +++ CPP/7zip/Crypto/AES/aesopt.h | 839 +++++++ CPP/7zip/Crypto/AES/aestab.c | 494 +++++ CPP/7zip/Crypto/AES/makefile | 31 + CPP/7zip/Crypto/AES/resource.rc | 3 + CPP/7zip/Crypto/Codec.def | 4 + CPP/7zip/Crypto/Hash/HmacSha1.cpp | 109 + CPP/7zip/Crypto/Hash/HmacSha1.h | 39 + CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.cpp | 83 + CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.h | 21 + CPP/7zip/Crypto/Hash/RandGen.cpp | 78 + CPP/7zip/Crypto/Hash/RandGen.h | 21 + CPP/7zip/Crypto/Hash/RotateDefs.h | 19 + CPP/7zip/Crypto/Hash/Sha1.cpp | 210 ++ CPP/7zip/Crypto/Hash/Sha1.h | 68 + CPP/7zip/Crypto/Hash/Sha256.cpp | 210 ++ CPP/7zip/Crypto/Hash/Sha256.h | 30 + CPP/7zip/Crypto/Hash/StdAfx.h | 8 + CPP/7zip/Crypto/Rar20/Rar20Cipher.cpp | 76 + CPP/7zip/Crypto/Rar20/Rar20Cipher.h | 35 + CPP/7zip/Crypto/Rar20/Rar20Crypto.cpp | 124 ++ CPP/7zip/Crypto/Rar20/Rar20Crypto.h | 33 + CPP/7zip/Crypto/Rar20/StdAfx.h | 8 + CPP/7zip/Crypto/RarAES/RarAES.cpp | 187 ++ CPP/7zip/Crypto/RarAES/RarAES.h | 61 + CPP/7zip/Crypto/RarAES/StdAfx.h | 8 + CPP/7zip/Crypto/WzAES/StdAfx.cpp | 3 + CPP/7zip/Crypto/WzAES/StdAfx.h | 8 + CPP/7zip/Crypto/WzAES/WzAES.cpp | 246 +++ CPP/7zip/Crypto/WzAES/WzAES.h | 126 ++ CPP/7zip/Crypto/Zip/StdAfx.h | 8 + CPP/7zip/Crypto/Zip/ZipCipher.cpp | 85 + CPP/7zip/Crypto/Zip/ZipCipher.h | 59 + CPP/7zip/Crypto/Zip/ZipCrypto.cpp | 65 + CPP/7zip/Crypto/Zip/ZipCrypto.h | 26 + CPP/7zip/Crypto/makefile | 8 + CPP/7zip/FileManager/7zFM.exe.manifest | 1 + CPP/7zip/FileManager/7zipLogo.ico | Bin 0 -> 9150 bytes CPP/7zip/FileManager/Add.bmp | Bin 0 -> 982 bytes CPP/7zip/FileManager/Add2.bmp | Bin 0 -> 406 bytes CPP/7zip/FileManager/App.cpp | 759 +++++++ CPP/7zip/FileManager/App.h | 332 +++ CPP/7zip/FileManager/AppState.h | 114 + CPP/7zip/FileManager/ClassDefs.cpp | 15 + CPP/7zip/FileManager/Copy.bmp | Bin 0 -> 982 bytes CPP/7zip/FileManager/Copy2.bmp | Bin 0 -> 406 bytes CPP/7zip/FileManager/Delete.bmp | Bin 0 -> 982 bytes CPP/7zip/FileManager/Delete2.bmp | Bin 0 -> 406 bytes CPP/7zip/FileManager/EnumFormatEtc.cpp | 108 + CPP/7zip/FileManager/EnumFormatEtc.h | 10 + CPP/7zip/FileManager/Extract.bmp | Bin 0 -> 982 bytes CPP/7zip/FileManager/Extract2.bmp | Bin 0 -> 406 bytes CPP/7zip/FileManager/ExtractCallback.cpp | 382 ++++ CPP/7zip/FileManager/ExtractCallback.h | 124 ++ CPP/7zip/FileManager/FM.cpp | 788 +++++++ CPP/7zip/FileManager/FM.dsp | 1251 +++++++++++ CPP/7zip/FileManager/FM.dsw | 29 + CPP/7zip/FileManager/FM.ico | Bin 0 -> 4846 bytes CPP/7zip/FileManager/FSDrives.cpp | 240 ++ CPP/7zip/FileManager/FSDrives.h | 66 + CPP/7zip/FileManager/FSFolder.cpp | 655 ++++++ CPP/7zip/FileManager/FSFolder.h | 141 ++ CPP/7zip/FileManager/FSFolderCopy.cpp | 490 +++++ CPP/7zip/FileManager/FileFolderPluginOpen.cpp | 111 + CPP/7zip/FileManager/FileFolderPluginOpen.h | 9 + CPP/7zip/FileManager/FilePlugins.cpp | 113 + CPP/7zip/FileManager/FilePlugins.h | 54 + CPP/7zip/FileManager/FormatUtils.cpp | 40 + CPP/7zip/FileManager/FormatUtils.h | 18 + CPP/7zip/FileManager/HelpUtils.cpp | 23 + CPP/7zip/FileManager/HelpUtils.h | 10 + CPP/7zip/FileManager/IFolder.h | 190 ++ CPP/7zip/FileManager/Info.bmp | Bin 0 -> 982 bytes CPP/7zip/FileManager/Info2.bmp | Bin 0 -> 406 bytes CPP/7zip/FileManager/LangUtils.cpp | 185 ++ CPP/7zip/FileManager/LangUtils.h | 41 + CPP/7zip/FileManager/Move.bmp | Bin 0 -> 982 bytes CPP/7zip/FileManager/Move2.bmp | Bin 0 -> 406 bytes CPP/7zip/FileManager/MyCom2.h | 48 + CPP/7zip/FileManager/MyLoadMenu.cpp | 694 ++++++ CPP/7zip/FileManager/MyLoadMenu.h | 16 + CPP/7zip/FileManager/NetFolder.cpp | 315 +++ CPP/7zip/FileManager/NetFolder.h | 66 + CPP/7zip/FileManager/OpenCallback.cpp | 113 + CPP/7zip/FileManager/OpenCallback.h | 85 + CPP/7zip/FileManager/OptionsDialog.cpp | 65 + CPP/7zip/FileManager/Panel.cpp | 856 ++++++++ CPP/7zip/FileManager/Panel.h | 510 +++++ CPP/7zip/FileManager/PanelCopy.cpp | 208 ++ CPP/7zip/FileManager/PanelCrc.cpp | 361 +++ CPP/7zip/FileManager/PanelDrag.cpp | 796 +++++++ CPP/7zip/FileManager/PanelFolderChange.cpp | 414 ++++ CPP/7zip/FileManager/PanelItemOpen.cpp | 546 +++++ CPP/7zip/FileManager/PanelItems.cpp | 822 +++++++ CPP/7zip/FileManager/PanelKey.cpp | 297 +++ CPP/7zip/FileManager/PanelListNotify.cpp | 388 ++++ CPP/7zip/FileManager/PanelMenu.cpp | 422 ++++ CPP/7zip/FileManager/PanelOperations.cpp | 396 ++++ CPP/7zip/FileManager/PanelSelect.cpp | 297 +++ CPP/7zip/FileManager/PanelSort.cpp | 163 ++ CPP/7zip/FileManager/PanelSplitFile.cpp | 477 ++++ CPP/7zip/FileManager/PhysDriveFolder.cpp | 274 +++ CPP/7zip/FileManager/PhysDriveFolder.h | 89 + CPP/7zip/FileManager/PluginInterface.h | 42 + CPP/7zip/FileManager/PluginLoader.h | 32 + CPP/7zip/FileManager/ProgramLocation.cpp | 24 + CPP/7zip/FileManager/ProgramLocation.h | 10 + CPP/7zip/FileManager/PropertyName.cpp | 74 + CPP/7zip/FileManager/PropertyName.h | 10 + CPP/7zip/FileManager/RegistryAssociations.cpp | 270 +++ CPP/7zip/FileManager/RegistryAssociations.h | 45 + CPP/7zip/FileManager/RegistryPlugins.cpp | 130 ++ CPP/7zip/FileManager/RegistryPlugins.h | 32 + CPP/7zip/FileManager/RegistryUtils.cpp | 150 ++ CPP/7zip/FileManager/RegistryUtils.h | 46 + .../FileManager/Resource/AboutDialog/7zipLogo.ico | Bin 0 -> 9150 bytes .../Resource/AboutDialog/AboutDialog.cpp | 60 + .../FileManager/Resource/AboutDialog/AboutDialog.h | 18 + CPP/7zip/FileManager/Resource/AboutDialog/StdAfx.h | 16 + .../FileManager/Resource/AboutDialog/resource.h | 6 + .../FileManager/Resource/AboutDialog/resource.rc | 41 + .../Resource/BenchmarkDialog/BenchmarkDialog.cpp | 976 +++++++++ .../Resource/BenchmarkDialog/BenchmarkDialog.h | 136 ++ .../FileManager/Resource/BenchmarkDialog/StdAfx.h | 16 + .../Resource/BenchmarkDialog/resource.h | 34 + .../Resource/BenchmarkDialog/resource.rc | 87 + .../Resource/ComboDialog/ComboDialog.cpp | 53 + .../FileManager/Resource/ComboDialog/ComboDialog.h | 25 + CPP/7zip/FileManager/Resource/ComboDialog/StdAfx.h | 16 + .../FileManager/Resource/ComboDialog/resource.h | 4 + .../FileManager/Resource/ComboDialog/resource.rc | 24 + .../FileManager/Resource/CopyDialog/CopyDialog.cpp | 81 + .../FileManager/Resource/CopyDialog/CopyDialog.h | 26 + CPP/7zip/FileManager/Resource/CopyDialog/StdAfx.h | 16 + .../FileManager/Resource/CopyDialog/resource.h | 7 + .../FileManager/Resource/CopyDialog/resource.rc | 28 + .../FileManager/Resource/EditPage/EditPage.cpp | 91 + CPP/7zip/FileManager/Resource/EditPage/EditPage.h | 21 + CPP/7zip/FileManager/Resource/EditPage/StdAfx.h | 16 + CPP/7zip/FileManager/Resource/EditPage/resource.h | 4 + CPP/7zip/FileManager/Resource/EditPage/resource.rc | 16 + .../FileManager/Resource/LangPage/LangPage.cpp | 90 + CPP/7zip/FileManager/Resource/LangPage/LangPage.h | 21 + CPP/7zip/FileManager/Resource/LangPage/StdAfx.h | 16 + CPP/7zip/FileManager/Resource/LangPage/resource.h | 6 + CPP/7zip/FileManager/Resource/LangPage/resource.rc | 21 + .../FileManager/Resource/ListBoxDialog/StdAfx.h | 16 + .../FileManager/Resource/ListBoxDialog/resource.h | 3 + .../FileManager/Resource/ListBoxDialog/resource.rc | 22 + .../Resource/ListViewDialog/ListViewDialog.cpp | 102 + .../Resource/ListViewDialog/ListViewDialog.h | 30 + .../FileManager/Resource/ListViewDialog/StdAfx.h | 16 + .../FileManager/Resource/ListViewDialog/resource.h | 3 + .../Resource/ListViewDialog/resource.rc | 26 + .../Resource/MessagesDialog/MessagesDialog.cpp | 100 + .../Resource/MessagesDialog/MessagesDialog.h | 22 + .../FileManager/Resource/MessagesDialog/StdAfx.h | 16 + .../FileManager/Resource/MessagesDialog/resource.h | 3 + .../Resource/MessagesDialog/resource.rc | 25 + .../Resource/OverwriteDialog/OverwriteDialog.cpp | 124 ++ .../Resource/OverwriteDialog/OverwriteDialog.h | 34 + .../FileManager/Resource/OverwriteDialog/StdAfx.h | 16 + .../Resource/OverwriteDialog/resource.h | 19 + .../Resource/OverwriteDialog/resource.rc | 47 + .../Resource/PasswordDialog/PasswordDialog.cpp | 50 + .../Resource/PasswordDialog/PasswordDialog.h | 21 + .../FileManager/Resource/PasswordDialog/StdAfx.h | 16 + .../FileManager/Resource/PasswordDialog/resource.h | 4 + .../Resource/PasswordDialog/resource.rc | 26 + .../Resource/PluginsPage/PluginsPage.cpp | 220 ++ .../FileManager/Resource/PluginsPage/PluginsPage.h | 26 + CPP/7zip/FileManager/Resource/PluginsPage/StdAfx.h | 16 + .../FileManager/Resource/PluginsPage/resource.h | 4 + .../FileManager/Resource/PluginsPage/resource.rc | 19 + .../Resource/ProgressDialog/ProgressDialog.cpp | 175 ++ .../Resource/ProgressDialog/ProgressDialog.h | 129 ++ .../FileManager/Resource/ProgressDialog/StdAfx.h | 16 + .../FileManager/Resource/ProgressDialog/resource.h | 3 + .../Resource/ProgressDialog/resource.rc | 20 + .../Resource/ProgressDialog2/ProgressDialog.cpp | 432 ++++ .../Resource/ProgressDialog2/ProgressDialog.h | 184 ++ .../FileManager/Resource/ProgressDialog2/StdAfx.h | 16 + .../Resource/ProgressDialog2/resource.h | 17 + .../Resource/ProgressDialog2/resource.rc | 56 + .../FileManager/Resource/PropertyName/resource.h | 28 + .../FileManager/Resource/PropertyName/resource.rc | 35 + .../Resource/SettingsPage/SettingsPage.cpp | 113 + .../Resource/SettingsPage/SettingsPage.h | 19 + .../FileManager/Resource/SettingsPage/StdAfx.h | 16 + .../FileManager/Resource/SettingsPage/resource.h | 11 + .../FileManager/Resource/SettingsPage/resource.rc | 35 + .../Resource/SplitDialog/SplitDialog.cpp | 89 + .../FileManager/Resource/SplitDialog/SplitDialog.h | 27 + CPP/7zip/FileManager/Resource/SplitDialog/StdAfx.h | 18 + .../FileManager/Resource/SplitDialog/resource.h | 8 + .../FileManager/Resource/SplitDialog/resource.rc | 32 + CPP/7zip/FileManager/Resource/SystemPage/StdAfx.h | 16 + .../FileManager/Resource/SystemPage/SystemPage.cpp | 435 ++++ .../FileManager/Resource/SystemPage/SystemPage.h | 40 + .../FileManager/Resource/SystemPage/resource.h | 7 + .../FileManager/Resource/SystemPage/resource.rc | 31 + CPP/7zip/FileManager/RootFolder.cpp | 204 ++ CPP/7zip/FileManager/RootFolder.h | 49 + CPP/7zip/FileManager/SplitUtils.cpp | 85 + CPP/7zip/FileManager/SplitUtils.h | 15 + CPP/7zip/FileManager/StdAfx.cpp | 3 + CPP/7zip/FileManager/StdAfx.h | 23 + CPP/7zip/FileManager/StringUtils.cpp | 68 + CPP/7zip/FileManager/StringUtils.h | 13 + CPP/7zip/FileManager/SysIconUtils.cpp | 157 ++ CPP/7zip/FileManager/SysIconUtils.h | 51 + CPP/7zip/FileManager/Test.bmp | Bin 0 -> 982 bytes CPP/7zip/FileManager/Test2.bmp | Bin 0 -> 406 bytes CPP/7zip/FileManager/TextPairs.cpp | 216 ++ CPP/7zip/FileManager/TextPairs.h | 32 + CPP/7zip/FileManager/UpdateCallback100.cpp | 92 + CPP/7zip/FileManager/UpdateCallback100.h | 67 + CPP/7zip/FileManager/ViewSettings.cpp | 429 ++++ CPP/7zip/FileManager/ViewSettings.h | 99 + CPP/7zip/FileManager/makefile | 187 ++ CPP/7zip/FileManager/resource.h | 154 ++ CPP/7zip/FileManager/resource.rc | 232 ++ CPP/7zip/GuiCommon.rc | 37 + CPP/7zip/Guid.txt | 157 ++ CPP/7zip/ICoder.h | 163 ++ CPP/7zip/IPassword.h | 26 + CPP/7zip/IProgress.h | 32 + CPP/7zip/IStream.h | 62 + CPP/7zip/MyVersion.h | 8 + CPP/7zip/MyVersionInfo.rc | 41 + CPP/7zip/PropID.h | 51 + CPP/7zip/SubBuild.mak | 3 + CPP/7zip/UI/Agent/Agent.cpp | 578 +++++ CPP/7zip/UI/Agent/Agent.h | 314 +++ CPP/7zip/UI/Agent/AgentOut.cpp | 518 +++++ CPP/7zip/UI/Agent/AgentProxy.cpp | 203 ++ CPP/7zip/UI/Agent/AgentProxy.h | 56 + CPP/7zip/UI/Agent/ArchiveFolder.cpp | 72 + CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp | 98 + CPP/7zip/UI/Agent/ArchiveFolderOut.cpp | 215 ++ CPP/7zip/UI/Agent/IFolderArchive.h | 90 + CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp | 80 + CPP/7zip/UI/Agent/UpdateCallbackAgent.h | 24 + CPP/7zip/UI/Client7z/Client7z.cpp | 850 ++++++++ CPP/7zip/UI/Client7z/Client7z.dsp | 226 ++ CPP/7zip/UI/Client7z/Client7z.dsw | 29 + CPP/7zip/UI/Client7z/StdAfx.cpp | 3 + CPP/7zip/UI/Client7z/StdAfx.h | 9 + CPP/7zip/UI/Client7z/makefile | 45 + CPP/7zip/UI/Common/ArchiveCommandLine.cpp | 985 +++++++++ CPP/7zip/UI/Common/ArchiveCommandLine.h | 95 + CPP/7zip/UI/Common/ArchiveExtractCallback.cpp | 448 ++++ CPP/7zip/UI/Common/ArchiveExtractCallback.h | 111 + CPP/7zip/UI/Common/ArchiveName.cpp | 46 + CPP/7zip/UI/Common/ArchiveName.h | 10 + CPP/7zip/UI/Common/ArchiveOpenCallback.cpp | 127 ++ CPP/7zip/UI/Common/ArchiveOpenCallback.h | 89 + CPP/7zip/UI/Common/ArchiverInfo.cpp | 372 ++++ CPP/7zip/UI/Common/ArchiverInfo.h | 66 + CPP/7zip/UI/Common/CompressCall.cpp | 367 ++++ CPP/7zip/UI/Common/CompressCall.h | 28 + CPP/7zip/UI/Common/DefaultName.cpp | 26 + CPP/7zip/UI/Common/DefaultName.h | 11 + CPP/7zip/UI/Common/DirItem.h | 34 + CPP/7zip/UI/Common/EnumDirItems.cpp | 281 +++ CPP/7zip/UI/Common/EnumDirItems.h | 39 + CPP/7zip/UI/Common/ExitCode.h | 27 + CPP/7zip/UI/Common/Extract.cpp | 152 ++ CPP/7zip/UI/Common/Extract.h | 59 + CPP/7zip/UI/Common/ExtractMode.h | 31 + CPP/7zip/UI/Common/ExtractingFilePath.cpp | 75 + CPP/7zip/UI/Common/ExtractingFilePath.h | 12 + CPP/7zip/UI/Common/HandlerLoader.h | 38 + CPP/7zip/UI/Common/IFileExtractCallback.h | 46 + CPP/7zip/UI/Common/OpenArchive.cpp | 531 +++++ CPP/7zip/UI/Common/OpenArchive.h | 134 ++ CPP/7zip/UI/Common/PropIDUtils.cpp | 90 + CPP/7zip/UI/Common/PropIDUtils.h | 11 + CPP/7zip/UI/Common/Property.h | 14 + CPP/7zip/UI/Common/SetProperties.cpp | 65 + CPP/7zip/UI/Common/SetProperties.h | 10 + CPP/7zip/UI/Common/SortUtils.cpp | 78 + CPP/7zip/UI/Common/SortUtils.h | 11 + CPP/7zip/UI/Common/StdAfx.h | 9 + CPP/7zip/UI/Common/TempFiles.cpp | 22 + CPP/7zip/UI/Common/TempFiles.h | 16 + CPP/7zip/UI/Common/Update.cpp | 818 +++++++ CPP/7zip/UI/Common/Update.h | 158 ++ CPP/7zip/UI/Common/UpdateAction.cpp | 64 + CPP/7zip/UI/Common/UpdateAction.h | 57 + CPP/7zip/UI/Common/UpdateCallback.cpp | 258 +++ CPP/7zip/UI/Common/UpdateCallback.h | 70 + CPP/7zip/UI/Common/UpdatePair.cpp | 175 ++ CPP/7zip/UI/Common/UpdatePair.h | 24 + CPP/7zip/UI/Common/UpdateProduce.cpp | 63 + CPP/7zip/UI/Common/UpdateProduce.h | 31 + CPP/7zip/UI/Common/WorkDir.cpp | 64 + CPP/7zip/UI/Common/WorkDir.h | 10 + CPP/7zip/UI/Common/ZipRegistry.cpp | 420 ++++ CPP/7zip/UI/Common/ZipRegistry.h | 99 + CPP/7zip/UI/Console/Console.dsp | 667 ++++++ CPP/7zip/UI/Console/Console.dsw | 29 + CPP/7zip/UI/Console/ConsoleClose.cpp | 65 + CPP/7zip/UI/Console/ConsoleClose.h | 24 + CPP/7zip/UI/Console/ExtractCallbackConsole.cpp | 235 ++ CPP/7zip/UI/Console/ExtractCallbackConsole.h | 65 + CPP/7zip/UI/Console/List.cpp | 532 +++++ CPP/7zip/UI/Console/List.h | 13 + CPP/7zip/UI/Console/Main.cpp | 382 ++++ CPP/7zip/UI/Console/MainAr.cpp | 169 ++ CPP/7zip/UI/Console/OpenCallbackConsole.cpp | 58 + CPP/7zip/UI/Console/OpenCallbackConsole.h | 27 + CPP/7zip/UI/Console/PercentPrinter.cpp | 90 + CPP/7zip/UI/Console/PercentPrinter.h | 31 + CPP/7zip/UI/Console/StdAfx.cpp | 3 + CPP/7zip/UI/Console/StdAfx.h | 9 + CPP/7zip/UI/Console/UpdateCallbackConsole.cpp | 196 ++ CPP/7zip/UI/Console/UpdateCallbackConsole.h | 75 + CPP/7zip/UI/Console/UserInputUtils.cpp | 58 + CPP/7zip/UI/Console/UserInputUtils.h | 24 + CPP/7zip/UI/Console/afxres.h | 1 + CPP/7zip/UI/Console/makefile | 93 + CPP/7zip/UI/Console/resource.rc | 3 + CPP/7zip/UI/Explorer/7-zip.dll.manifest | 1 + CPP/7zip/UI/Explorer/ContextMenu.cpp | 682 ++++++ CPP/7zip/UI/Explorer/ContextMenu.h | 86 + CPP/7zip/UI/Explorer/ContextMenuFlags.h | 34 + CPP/7zip/UI/Explorer/DllExports.cpp | 315 +++ CPP/7zip/UI/Explorer/Explorer.def | 12 + CPP/7zip/UI/Explorer/Explorer.dsp | 818 +++++++ CPP/7zip/UI/Explorer/Explorer.dsw | 29 + CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.cpp | 157 ++ CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.h | 30 + CPP/7zip/UI/Explorer/FoldersPage/resource.h | 12 + CPP/7zip/UI/Explorer/FoldersPage/resource.rc | 36 + CPP/7zip/UI/Explorer/MyMessages.cpp | 58 + CPP/7zip/UI/Explorer/MyMessages.h | 30 + CPP/7zip/UI/Explorer/OptionsDialog.cpp | 71 + CPP/7zip/UI/Explorer/OptionsDialog.h | 23 + CPP/7zip/UI/Explorer/RegistryContextMenu.cpp | 128 ++ CPP/7zip/UI/Explorer/RegistryContextMenu.h | 13 + CPP/7zip/UI/Explorer/StdAfx.cpp | 3 + CPP/7zip/UI/Explorer/StdAfx.h | 26 + CPP/7zip/UI/Explorer/SystemPage/SystemPage.cpp | 212 ++ CPP/7zip/UI/Explorer/SystemPage/SystemPage.h | 25 + CPP/7zip/UI/Explorer/SystemPage/resource.h | 6 + CPP/7zip/UI/Explorer/SystemPage/resource.rc | 24 + CPP/7zip/UI/Explorer/makefile | 137 ++ CPP/7zip/UI/Explorer/resource.h | 31 + CPP/7zip/UI/Explorer/resource.rc | 38 + CPP/7zip/UI/Far/CLSIDConst.cpp | 8 + CPP/7zip/UI/Far/ExtractEngine.cpp | 168 ++ CPP/7zip/UI/Far/ExtractEngine.h | 68 + CPP/7zip/UI/Far/Far.def | 20 + CPP/7zip/UI/Far/Far.dsp | 561 +++++ CPP/7zip/UI/Far/Far.dsw | 29 + CPP/7zip/UI/Far/FarPlugin.h | 577 +++++ CPP/7zip/UI/Far/FarUtils.cpp | 416 ++++ CPP/7zip/UI/Far/FarUtils.h | 185 ++ CPP/7zip/UI/Far/Main.cpp | 622 ++++++ CPP/7zip/UI/Far/Messages.h | 152 ++ CPP/7zip/UI/Far/OverwriteDialog.cpp | 109 + CPP/7zip/UI/Far/OverwriteDialog.h | 33 + CPP/7zip/UI/Far/Plugin.cpp | 693 ++++++ CPP/7zip/UI/Far/Plugin.h | 99 + CPP/7zip/UI/Far/PluginCommon.cpp | 50 + CPP/7zip/UI/Far/PluginDelete.cpp | 169 ++ CPP/7zip/UI/Far/PluginRead.cpp | 278 +++ CPP/7zip/UI/Far/PluginWrite.cpp | 696 ++++++ CPP/7zip/UI/Far/ProgressBox.cpp | 103 + CPP/7zip/UI/Far/ProgressBox.h | 35 + CPP/7zip/UI/Far/StdAfx.cpp | 3 + CPP/7zip/UI/Far/StdAfx.h | 12 + CPP/7zip/UI/Far/UpdateCallback100.cpp | 54 + CPP/7zip/UI/Far/UpdateCallback100.h | 45 + CPP/7zip/UI/Far/makefile | 102 + CPP/7zip/UI/Far/resource.rc | 3 + CPP/7zip/UI/GUI/7zG.exe.manifest | 1 + CPP/7zip/UI/GUI/CompressDialog.cpp | 1373 ++++++++++++ CPP/7zip/UI/GUI/CompressDialog.h | 171 ++ CPP/7zip/UI/GUI/ExtractDialog.cpp | 371 ++++ CPP/7zip/UI/GUI/ExtractDialog.h | 77 + CPP/7zip/UI/GUI/ExtractGUI.cpp | 172 ++ CPP/7zip/UI/GUI/ExtractGUI.h | 20 + CPP/7zip/UI/GUI/FM.ico | Bin 0 -> 4846 bytes CPP/7zip/UI/GUI/GUI.cpp | 260 +++ CPP/7zip/UI/GUI/GUI.dsp | 904 ++++++++ CPP/7zip/UI/GUI/GUI.dsw | 29 + CPP/7zip/UI/GUI/OpenCallbackGUI.cpp | 65 + CPP/7zip/UI/GUI/OpenCallbackGUI.h | 35 + CPP/7zip/UI/GUI/StdAfx.cpp | 3 + CPP/7zip/UI/GUI/StdAfx.h | 13 + CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp | 167 ++ CPP/7zip/UI/GUI/UpdateCallbackGUI.h | 63 + CPP/7zip/UI/GUI/UpdateGUI.cpp | 397 ++++ CPP/7zip/UI/GUI/UpdateGUI.h | 20 + CPP/7zip/UI/GUI/makefile | 135 ++ CPP/7zip/UI/GUI/resource.h | 45 + CPP/7zip/UI/GUI/resource.rc | 57 + CPP/7zip/UI/Resource/CompressDialog/resource.h | 40 + CPP/7zip/UI/Resource/CompressDialog/resource.rc | 117 + CPP/7zip/UI/Resource/Extract/resource.h | 15 + CPP/7zip/UI/Resource/Extract/resource.rc | 19 + CPP/7zip/UI/Resource/ExtractDialog/resource.h | 26 + CPP/7zip/UI/Resource/ExtractDialog/resource.rc | 80 + CPP/7zip/UI/makefile | 10 + CPP/7zip/makefile | 16 + CPP/Build.mak | 62 + CPP/Common/AlignedBuffer.cpp | 22 + CPP/Common/AlignedBuffer.h | 18 + CPP/Common/Alloc.cpp | 133 ++ CPP/Common/Alloc.h | 29 + CPP/Common/AutoPtr.h | 35 + CPP/Common/Buffer.h | 77 + CPP/Common/CRC.cpp | 61 + CPP/Common/CRC.h | 36 + CPP/Common/C_FileIO.cpp | 78 + CPP/Common/C_FileIO.h | 45 + CPP/Common/ComTry.h | 17 + CPP/Common/CommandLineParser.cpp | 232 ++ CPP/Common/CommandLineParser.h | 72 + CPP/Common/Defs.h | 20 + CPP/Common/DynamicBuffer.h | 47 + CPP/Common/Exception.h | 13 + CPP/Common/IntToString.cpp | 63 + CPP/Common/IntToString.h | 15 + CPP/Common/Lang.cpp | 142 ++ CPP/Common/Lang.h | 28 + CPP/Common/ListFileUtils.cpp | 60 + CPP/Common/ListFileUtils.h | 12 + CPP/Common/MyCom.h | 203 ++ CPP/Common/MyGuidDef.h | 54 + CPP/Common/MyInitGuid.h | 13 + CPP/Common/MyUnknown.h | 24 + CPP/Common/MyWindows.cpp | 113 + CPP/Common/MyWindows.h | 203 ++ CPP/Common/NewHandler.cpp | 116 + CPP/Common/NewHandler.h | 16 + CPP/Common/Random.cpp | 17 + CPP/Common/Random.h | 16 + CPP/Common/StdAfx.h | 9 + CPP/Common/StdInStream.cpp | 84 + CPP/Common/StdInStream.h | 31 + CPP/Common/StdOutStream.cpp | 93 + CPP/Common/StdOutStream.h | 35 + CPP/Common/String.cpp | 198 ++ CPP/Common/String.h | 631 ++++++ CPP/Common/StringConvert.cpp | 94 + CPP/Common/StringConvert.h | 71 + CPP/Common/StringToInt.cpp | 68 + CPP/Common/StringToInt.h | 17 + CPP/Common/TextConfig.cpp | 138 ++ CPP/Common/TextConfig.h | 22 + CPP/Common/Types.h | 57 + CPP/Common/UTFConvert.cpp | 91 + CPP/Common/UTFConvert.h | 11 + CPP/Common/Vector.cpp | 83 + CPP/Common/Vector.h | 237 ++ CPP/Common/Wildcard.cpp | 462 ++++ CPP/Common/Wildcard.h | 78 + CPP/Windows/COM.cpp | 37 + CPP/Windows/COM.h | 57 + CPP/Windows/CommonDialog.cpp | 164 ++ CPP/Windows/CommonDialog.h | 17 + CPP/Windows/Console.cpp | 10 + CPP/Windows/Console.h | 52 + CPP/Windows/Control/ComboBox.cpp | 63 + CPP/Windows/Control/ComboBox.h | 54 + CPP/Windows/Control/Dialog.cpp | 145 ++ CPP/Windows/Control/Dialog.h | 144 ++ CPP/Windows/Control/Edit.h | 21 + CPP/Windows/Control/ImageList.cpp | 11 + CPP/Windows/Control/ImageList.h | 86 + CPP/Windows/Control/ListView.cpp | 58 + CPP/Windows/Control/ListView.h | 138 ++ CPP/Windows/Control/ProgressBar.h | 41 + CPP/Windows/Control/PropertyPage.cpp | 163 ++ CPP/Windows/Control/PropertyPage.h | 47 + CPP/Windows/Control/ReBar.h | 35 + CPP/Windows/Control/Static.h | 27 + CPP/Windows/Control/StatusBar.h | 43 + CPP/Windows/Control/StdAfx.h | 9 + CPP/Windows/Control/ToolBar.h | 34 + CPP/Windows/Control/Trackbar.h | 28 + CPP/Windows/Control/Window2.cpp | 203 ++ CPP/Windows/Control/Window2.h | 59 + CPP/Windows/DLL.cpp | 115 + CPP/Windows/DLL.h | 54 + CPP/Windows/Defs.h | 21 + CPP/Windows/Error.cpp | 50 + CPP/Windows/Error.h | 33 + CPP/Windows/FileDevice.cpp | 49 + CPP/Windows/FileDevice.h | 123 ++ CPP/Windows/FileDir.cpp | 835 +++++++ CPP/Windows/FileDir.h | 178 ++ CPP/Windows/FileFind.cpp | 408 ++++ CPP/Windows/FileFind.h | 153 ++ CPP/Windows/FileIO.cpp | 305 +++ CPP/Windows/FileIO.h | 97 + CPP/Windows/FileMapping.cpp | 14 + CPP/Windows/FileMapping.h | 50 + CPP/Windows/FileName.cpp | 111 + CPP/Windows/FileName.h | 43 + CPP/Windows/FileSystem.cpp | 126 ++ CPP/Windows/FileSystem.h | 51 + CPP/Windows/Handle.h | 37 + CPP/Windows/Memory.cpp | 64 + CPP/Windows/Memory.h | 45 + CPP/Windows/MemoryLock.cpp | 78 + CPP/Windows/MemoryLock.h | 13 + CPP/Windows/Menu.cpp | 178 ++ CPP/Windows/Menu.h | 137 ++ CPP/Windows/NationalTime.cpp | 37 + CPP/Windows/NationalTime.h | 20 + CPP/Windows/Net.cpp | 380 ++++ CPP/Windows/Net.h | 87 + CPP/Windows/ProcessMessages.cpp | 22 + CPP/Windows/ProcessMessages.h | 14 + CPP/Windows/PropVariant.cpp | 312 +++ CPP/Windows/PropVariant.h | 57 + CPP/Windows/PropVariantConversions.cpp | 150 ++ CPP/Windows/PropVariantConversions.h | 14 + CPP/Windows/Registry.cpp | 324 +++ CPP/Windows/Registry.h | 77 + CPP/Windows/ResourceString.cpp | 53 + CPP/Windows/ResourceString.h | 20 + CPP/Windows/Security.cpp | 181 ++ CPP/Windows/Security.h | 168 ++ CPP/Windows/Shell.cpp | 292 +++ CPP/Windows/Shell.h | 92 + CPP/Windows/StdAfx.h | 9 + CPP/Windows/Synchronization.cpp | 17 + CPP/Windows/Synchronization.h | 133 ++ CPP/Windows/System.h | 21 + CPP/Windows/Thread.h | 51 + CPP/Windows/Time.h | 66 + CPP/Windows/Window.cpp | 169 ++ CPP/Windows/Window.h | 219 ++ 1161 files changed, 149306 insertions(+) create mode 100755 CPP/7zip/Archive/7z/7z.dsp create mode 100755 CPP/7zip/Archive/7z/7z.dsw create mode 100755 CPP/7zip/Archive/7z/7z.ico create mode 100755 CPP/7zip/Archive/7z/7zCompressionMode.cpp create mode 100755 CPP/7zip/Archive/7z/7zCompressionMode.h create mode 100755 CPP/7zip/Archive/7z/7zDecode.cpp create mode 100755 CPP/7zip/Archive/7z/7zDecode.h create mode 100755 CPP/7zip/Archive/7z/7zEncode.cpp create mode 100755 CPP/7zip/Archive/7z/7zEncode.h create mode 100755 CPP/7zip/Archive/7z/7zExtract.cpp create mode 100755 CPP/7zip/Archive/7z/7zFolderInStream.cpp create mode 100755 CPP/7zip/Archive/7z/7zFolderInStream.h create mode 100755 CPP/7zip/Archive/7z/7zFolderOutStream.cpp create mode 100755 CPP/7zip/Archive/7z/7zFolderOutStream.h create mode 100755 CPP/7zip/Archive/7z/7zHandler.cpp create mode 100755 CPP/7zip/Archive/7z/7zHandler.h create mode 100755 CPP/7zip/Archive/7z/7zHandlerOut.cpp create mode 100755 CPP/7zip/Archive/7z/7zHeader.cpp create mode 100755 CPP/7zip/Archive/7z/7zHeader.h create mode 100755 CPP/7zip/Archive/7z/7zIn.cpp create mode 100755 CPP/7zip/Archive/7z/7zIn.h create mode 100755 CPP/7zip/Archive/7z/7zItem.h create mode 100755 CPP/7zip/Archive/7z/7zMethodID.cpp create mode 100755 CPP/7zip/Archive/7z/7zMethodID.h create mode 100755 CPP/7zip/Archive/7z/7zMethods.cpp create mode 100755 CPP/7zip/Archive/7z/7zMethods.h create mode 100755 CPP/7zip/Archive/7z/7zOut.cpp create mode 100755 CPP/7zip/Archive/7z/7zOut.h create mode 100755 CPP/7zip/Archive/7z/7zProperties.cpp create mode 100755 CPP/7zip/Archive/7z/7zProperties.h create mode 100755 CPP/7zip/Archive/7z/7zSpecStream.cpp create mode 100755 CPP/7zip/Archive/7z/7zSpecStream.h create mode 100755 CPP/7zip/Archive/7z/7zUpdate.cpp create mode 100755 CPP/7zip/Archive/7z/7zUpdate.h create mode 100755 CPP/7zip/Archive/7z/DllExports.cpp create mode 100755 CPP/7zip/Archive/7z/StdAfx.cpp create mode 100755 CPP/7zip/Archive/7z/StdAfx.h create mode 100755 CPP/7zip/Archive/7z/makefile create mode 100755 CPP/7zip/Archive/7z/resource.rc create mode 100755 CPP/7zip/Archive/Archive.def create mode 100755 CPP/7zip/Archive/Arj/Arj.dsp create mode 100755 CPP/7zip/Archive/Arj/Arj.dsw create mode 100755 CPP/7zip/Archive/Arj/ArjHandler.cpp create mode 100755 CPP/7zip/Archive/Arj/ArjHandler.h create mode 100755 CPP/7zip/Archive/Arj/ArjHeader.h create mode 100755 CPP/7zip/Archive/Arj/ArjIn.cpp create mode 100755 CPP/7zip/Archive/Arj/ArjIn.h create mode 100755 CPP/7zip/Archive/Arj/ArjItem.h create mode 100755 CPP/7zip/Archive/Arj/DllExports.cpp create mode 100755 CPP/7zip/Archive/Arj/StdAfx.cpp create mode 100755 CPP/7zip/Archive/Arj/StdAfx.h create mode 100755 CPP/7zip/Archive/Arj/arj.ico create mode 100755 CPP/7zip/Archive/Arj/makefile create mode 100755 CPP/7zip/Archive/Arj/resource.rc create mode 100755 CPP/7zip/Archive/BZip2/BZip2.dsp create mode 100755 CPP/7zip/Archive/BZip2/BZip2.dsw create mode 100755 CPP/7zip/Archive/BZip2/BZip2Handler.cpp create mode 100755 CPP/7zip/Archive/BZip2/BZip2Handler.h create mode 100755 CPP/7zip/Archive/BZip2/BZip2HandlerOut.cpp create mode 100755 CPP/7zip/Archive/BZip2/BZip2Item.h create mode 100755 CPP/7zip/Archive/BZip2/BZip2Update.cpp create mode 100755 CPP/7zip/Archive/BZip2/BZip2Update.h create mode 100755 CPP/7zip/Archive/BZip2/DllExports.cpp create mode 100755 CPP/7zip/Archive/BZip2/StdAfx.cpp create mode 100755 CPP/7zip/Archive/BZip2/StdAfx.h create mode 100755 CPP/7zip/Archive/BZip2/bz2.ico create mode 100755 CPP/7zip/Archive/BZip2/makefile create mode 100755 CPP/7zip/Archive/BZip2/resource.rc create mode 100755 CPP/7zip/Archive/Cab/Cab.dsp create mode 100755 CPP/7zip/Archive/Cab/Cab.dsw create mode 100755 CPP/7zip/Archive/Cab/CabBlockInStream.cpp create mode 100755 CPP/7zip/Archive/Cab/CabBlockInStream.h create mode 100755 CPP/7zip/Archive/Cab/CabHandler.cpp create mode 100755 CPP/7zip/Archive/Cab/CabHandler.h create mode 100755 CPP/7zip/Archive/Cab/CabHeader.cpp create mode 100755 CPP/7zip/Archive/Cab/CabHeader.h create mode 100755 CPP/7zip/Archive/Cab/CabIn.cpp create mode 100755 CPP/7zip/Archive/Cab/CabIn.h create mode 100755 CPP/7zip/Archive/Cab/CabItem.h create mode 100755 CPP/7zip/Archive/Cab/DllExports.cpp create mode 100755 CPP/7zip/Archive/Cab/StdAfx.cpp create mode 100755 CPP/7zip/Archive/Cab/StdAfx.h create mode 100755 CPP/7zip/Archive/Cab/cab.ico create mode 100755 CPP/7zip/Archive/Cab/makefile create mode 100755 CPP/7zip/Archive/Cab/resource.rc create mode 100755 CPP/7zip/Archive/Chm/Chm.dsp create mode 100755 CPP/7zip/Archive/Chm/Chm.dsw create mode 100755 CPP/7zip/Archive/Chm/ChmHandler.cpp create mode 100755 CPP/7zip/Archive/Chm/ChmHandler.h create mode 100755 CPP/7zip/Archive/Chm/ChmHeader.cpp create mode 100755 CPP/7zip/Archive/Chm/ChmHeader.h create mode 100755 CPP/7zip/Archive/Chm/ChmIn.cpp create mode 100755 CPP/7zip/Archive/Chm/ChmIn.h create mode 100755 CPP/7zip/Archive/Chm/DllExports.cpp create mode 100755 CPP/7zip/Archive/Chm/StdAfx.cpp create mode 100755 CPP/7zip/Archive/Chm/StdAfx.h create mode 100755 CPP/7zip/Archive/Chm/makefile create mode 100755 CPP/7zip/Archive/Chm/resource.rc create mode 100755 CPP/7zip/Archive/Common/CodecsPath.cpp create mode 100755 CPP/7zip/Archive/Common/CodecsPath.h create mode 100755 CPP/7zip/Archive/Common/CoderLoader.cpp create mode 100755 CPP/7zip/Archive/Common/CoderLoader.h create mode 100755 CPP/7zip/Archive/Common/CoderMixer2.cpp create mode 100755 CPP/7zip/Archive/Common/CoderMixer2.h create mode 100755 CPP/7zip/Archive/Common/CoderMixer2MT.cpp create mode 100755 CPP/7zip/Archive/Common/CoderMixer2MT.h create mode 100755 CPP/7zip/Archive/Common/CoderMixer2ST.cpp create mode 100755 CPP/7zip/Archive/Common/CoderMixer2ST.h create mode 100755 CPP/7zip/Archive/Common/CrossThreadProgress.cpp create mode 100755 CPP/7zip/Archive/Common/CrossThreadProgress.h create mode 100755 CPP/7zip/Archive/Common/DummyOutStream.cpp create mode 100755 CPP/7zip/Archive/Common/DummyOutStream.h create mode 100755 CPP/7zip/Archive/Common/FilterCoder.cpp create mode 100755 CPP/7zip/Archive/Common/FilterCoder.h create mode 100755 CPP/7zip/Archive/Common/InStreamWithCRC.cpp create mode 100755 CPP/7zip/Archive/Common/InStreamWithCRC.h create mode 100755 CPP/7zip/Archive/Common/ItemNameUtils.cpp create mode 100755 CPP/7zip/Archive/Common/ItemNameUtils.h create mode 100755 CPP/7zip/Archive/Common/MultiStream.cpp create mode 100755 CPP/7zip/Archive/Common/MultiStream.h create mode 100755 CPP/7zip/Archive/Common/OutStreamWithCRC.cpp create mode 100755 CPP/7zip/Archive/Common/OutStreamWithCRC.h create mode 100755 CPP/7zip/Archive/Common/ParseProperties.cpp create mode 100755 CPP/7zip/Archive/Common/ParseProperties.h create mode 100755 CPP/7zip/Archive/Common/StdAfx.h create mode 100755 CPP/7zip/Archive/Cpio/CpioHandler.cpp create mode 100755 CPP/7zip/Archive/Cpio/CpioHandler.h create mode 100755 CPP/7zip/Archive/Cpio/CpioHeader.cpp create mode 100755 CPP/7zip/Archive/Cpio/CpioHeader.h create mode 100755 CPP/7zip/Archive/Cpio/CpioIn.cpp create mode 100755 CPP/7zip/Archive/Cpio/CpioIn.h create mode 100755 CPP/7zip/Archive/Cpio/CpioItem.h create mode 100755 CPP/7zip/Archive/Cpio/DllExports.cpp create mode 100755 CPP/7zip/Archive/Cpio/StdAfx.cpp create mode 100755 CPP/7zip/Archive/Cpio/StdAfx.h create mode 100755 CPP/7zip/Archive/Cpio/cpio.dsp create mode 100755 CPP/7zip/Archive/Cpio/cpio.dsw create mode 100755 CPP/7zip/Archive/Cpio/cpio.ico create mode 100755 CPP/7zip/Archive/Cpio/makefile create mode 100755 CPP/7zip/Archive/Cpio/resource.rc create mode 100755 CPP/7zip/Archive/Deb/Deb.dsp create mode 100755 CPP/7zip/Archive/Deb/Deb.dsw create mode 100755 CPP/7zip/Archive/Deb/DebHandler.cpp create mode 100755 CPP/7zip/Archive/Deb/DebHandler.h create mode 100755 CPP/7zip/Archive/Deb/DebHeader.cpp create mode 100755 CPP/7zip/Archive/Deb/DebHeader.h create mode 100755 CPP/7zip/Archive/Deb/DebIn.cpp create mode 100755 CPP/7zip/Archive/Deb/DebIn.h create mode 100755 CPP/7zip/Archive/Deb/DebItem.h create mode 100755 CPP/7zip/Archive/Deb/DllExports.cpp create mode 100755 CPP/7zip/Archive/Deb/StdAfx.cpp create mode 100755 CPP/7zip/Archive/Deb/StdAfx.h create mode 100755 CPP/7zip/Archive/Deb/deb.ico create mode 100755 CPP/7zip/Archive/Deb/makefile create mode 100755 CPP/7zip/Archive/Deb/resource.rc create mode 100755 CPP/7zip/Archive/GZip/DllExports.cpp create mode 100755 CPP/7zip/Archive/GZip/GZip.dsp create mode 100755 CPP/7zip/Archive/GZip/GZip.dsw create mode 100755 CPP/7zip/Archive/GZip/GZipHandler.cpp create mode 100755 CPP/7zip/Archive/GZip/GZipHandler.h create mode 100755 CPP/7zip/Archive/GZip/GZipHandlerOut.cpp create mode 100755 CPP/7zip/Archive/GZip/GZipHeader.cpp create mode 100755 CPP/7zip/Archive/GZip/GZipHeader.h create mode 100755 CPP/7zip/Archive/GZip/GZipIn.cpp create mode 100755 CPP/7zip/Archive/GZip/GZipIn.h create mode 100755 CPP/7zip/Archive/GZip/GZipItem.h create mode 100755 CPP/7zip/Archive/GZip/GZipOut.cpp create mode 100755 CPP/7zip/Archive/GZip/GZipOut.h create mode 100755 CPP/7zip/Archive/GZip/GZipUpdate.cpp create mode 100755 CPP/7zip/Archive/GZip/GZipUpdate.h create mode 100755 CPP/7zip/Archive/GZip/StdAfx.cpp create mode 100755 CPP/7zip/Archive/GZip/StdAfx.h create mode 100755 CPP/7zip/Archive/GZip/gz.ico create mode 100755 CPP/7zip/Archive/GZip/makefile create mode 100755 CPP/7zip/Archive/GZip/resource.rc create mode 100755 CPP/7zip/Archive/IArchive.h create mode 100755 CPP/7zip/Archive/Iso/DllExports.cpp create mode 100755 CPP/7zip/Archive/Iso/Iso.dsp create mode 100755 CPP/7zip/Archive/Iso/Iso.dsw create mode 100755 CPP/7zip/Archive/Iso/Iso.ico create mode 100755 CPP/7zip/Archive/Iso/IsoHandler.cpp create mode 100755 CPP/7zip/Archive/Iso/IsoHandler.h create mode 100755 CPP/7zip/Archive/Iso/IsoHeader.cpp create mode 100755 CPP/7zip/Archive/Iso/IsoHeader.h create mode 100755 CPP/7zip/Archive/Iso/IsoIn.cpp create mode 100755 CPP/7zip/Archive/Iso/IsoIn.h create mode 100755 CPP/7zip/Archive/Iso/IsoItem.h create mode 100755 CPP/7zip/Archive/Iso/StdAfx.cpp create mode 100755 CPP/7zip/Archive/Iso/StdAfx.h create mode 100755 CPP/7zip/Archive/Iso/makefile create mode 100755 CPP/7zip/Archive/Iso/resource.rc create mode 100755 CPP/7zip/Archive/Lzh/DllExports.cpp create mode 100755 CPP/7zip/Archive/Lzh/Lzh.def create mode 100755 CPP/7zip/Archive/Lzh/Lzh.dsp create mode 100755 CPP/7zip/Archive/Lzh/Lzh.dsw create mode 100755 CPP/7zip/Archive/Lzh/LzhCRC.cpp create mode 100755 CPP/7zip/Archive/Lzh/LzhCRC.h create mode 100755 CPP/7zip/Archive/Lzh/LzhHandler.cpp create mode 100755 CPP/7zip/Archive/Lzh/LzhHandler.h create mode 100755 CPP/7zip/Archive/Lzh/LzhHeader.h create mode 100755 CPP/7zip/Archive/Lzh/LzhIn.cpp create mode 100755 CPP/7zip/Archive/Lzh/LzhIn.h create mode 100755 CPP/7zip/Archive/Lzh/LzhItem.h create mode 100755 CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp create mode 100755 CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.h create mode 100755 CPP/7zip/Archive/Lzh/StdAfx.cpp create mode 100755 CPP/7zip/Archive/Lzh/StdAfx.h create mode 100755 CPP/7zip/Archive/Lzh/lzh.ico create mode 100755 CPP/7zip/Archive/Lzh/makefile create mode 100755 CPP/7zip/Archive/Lzh/resource.rc create mode 100755 CPP/7zip/Archive/Nsis/DllExports.cpp create mode 100755 CPP/7zip/Archive/Nsis/Nsis.dsp create mode 100755 CPP/7zip/Archive/Nsis/Nsis.dsw create mode 100755 CPP/7zip/Archive/Nsis/NsisDecode.cpp create mode 100755 CPP/7zip/Archive/Nsis/NsisDecode.h create mode 100755 CPP/7zip/Archive/Nsis/NsisHandler.cpp create mode 100755 CPP/7zip/Archive/Nsis/NsisHandler.h create mode 100755 CPP/7zip/Archive/Nsis/NsisIn.cpp create mode 100755 CPP/7zip/Archive/Nsis/NsisIn.h create mode 100755 CPP/7zip/Archive/Nsis/StdAfx.cpp create mode 100755 CPP/7zip/Archive/Nsis/StdAfx.h create mode 100755 CPP/7zip/Archive/Nsis/makefile create mode 100755 CPP/7zip/Archive/Nsis/resource.rc create mode 100755 CPP/7zip/Archive/RPM/DllExports.cpp create mode 100755 CPP/7zip/Archive/RPM/Rpm.dsp create mode 100755 CPP/7zip/Archive/RPM/Rpm.dsw create mode 100755 CPP/7zip/Archive/RPM/RpmHandler.cpp create mode 100755 CPP/7zip/Archive/RPM/RpmHandler.h create mode 100755 CPP/7zip/Archive/RPM/RpmHeader.h create mode 100755 CPP/7zip/Archive/RPM/RpmIn.cpp create mode 100755 CPP/7zip/Archive/RPM/RpmIn.h create mode 100755 CPP/7zip/Archive/RPM/StdAfx.cpp create mode 100755 CPP/7zip/Archive/RPM/StdAfx.h create mode 100755 CPP/7zip/Archive/RPM/makefile create mode 100755 CPP/7zip/Archive/RPM/resource.rc create mode 100755 CPP/7zip/Archive/RPM/rpm.ico create mode 100755 CPP/7zip/Archive/Rar/DllExports.cpp create mode 100755 CPP/7zip/Archive/Rar/Rar.dsp create mode 100755 CPP/7zip/Archive/Rar/Rar.dsw create mode 100755 CPP/7zip/Archive/Rar/RarHandler.cpp create mode 100755 CPP/7zip/Archive/Rar/RarHandler.h create mode 100755 CPP/7zip/Archive/Rar/RarHeader.cpp create mode 100755 CPP/7zip/Archive/Rar/RarHeader.h create mode 100755 CPP/7zip/Archive/Rar/RarIn.cpp create mode 100755 CPP/7zip/Archive/Rar/RarIn.h create mode 100755 CPP/7zip/Archive/Rar/RarItem.cpp create mode 100755 CPP/7zip/Archive/Rar/RarItem.h create mode 100755 CPP/7zip/Archive/Rar/RarVolumeInStream.cpp create mode 100755 CPP/7zip/Archive/Rar/RarVolumeInStream.h create mode 100755 CPP/7zip/Archive/Rar/StdAfx.cpp create mode 100755 CPP/7zip/Archive/Rar/StdAfx.h create mode 100755 CPP/7zip/Archive/Rar/makefile create mode 100755 CPP/7zip/Archive/Rar/rar.ico create mode 100755 CPP/7zip/Archive/Rar/resource.rc create mode 100755 CPP/7zip/Archive/Split/DllExports.cpp create mode 100755 CPP/7zip/Archive/Split/Split.dsp create mode 100755 CPP/7zip/Archive/Split/Split.dsw create mode 100755 CPP/7zip/Archive/Split/Split.ico create mode 100755 CPP/7zip/Archive/Split/SplitHandler.cpp create mode 100755 CPP/7zip/Archive/Split/SplitHandler.h create mode 100755 CPP/7zip/Archive/Split/SplitHandlerOut.cpp create mode 100755 CPP/7zip/Archive/Split/StdAfx.cpp create mode 100755 CPP/7zip/Archive/Split/StdAfx.h create mode 100755 CPP/7zip/Archive/Split/makefile create mode 100755 CPP/7zip/Archive/Split/resource.rc create mode 100755 CPP/7zip/Archive/Tar/DllExports.cpp create mode 100755 CPP/7zip/Archive/Tar/StdAfx.cpp create mode 100755 CPP/7zip/Archive/Tar/StdAfx.h create mode 100755 CPP/7zip/Archive/Tar/Tar.dsp create mode 100755 CPP/7zip/Archive/Tar/Tar.dsw create mode 100755 CPP/7zip/Archive/Tar/TarHandler.cpp create mode 100755 CPP/7zip/Archive/Tar/TarHandler.h create mode 100755 CPP/7zip/Archive/Tar/TarHandlerOut.cpp create mode 100755 CPP/7zip/Archive/Tar/TarHeader.cpp create mode 100755 CPP/7zip/Archive/Tar/TarHeader.h create mode 100755 CPP/7zip/Archive/Tar/TarIn.cpp create mode 100755 CPP/7zip/Archive/Tar/TarIn.h create mode 100755 CPP/7zip/Archive/Tar/TarItem.h create mode 100755 CPP/7zip/Archive/Tar/TarOut.cpp create mode 100755 CPP/7zip/Archive/Tar/TarOut.h create mode 100755 CPP/7zip/Archive/Tar/TarUpdate.cpp create mode 100755 CPP/7zip/Archive/Tar/TarUpdate.h create mode 100755 CPP/7zip/Archive/Tar/makefile create mode 100755 CPP/7zip/Archive/Tar/resource.rc create mode 100755 CPP/7zip/Archive/Tar/tar.ico create mode 100755 CPP/7zip/Archive/Z/DllExports.cpp create mode 100755 CPP/7zip/Archive/Z/StdAfx.cpp create mode 100755 CPP/7zip/Archive/Z/StdAfx.h create mode 100755 CPP/7zip/Archive/Z/Z.dsp create mode 100755 CPP/7zip/Archive/Z/Z.dsw create mode 100755 CPP/7zip/Archive/Z/Z.ico create mode 100755 CPP/7zip/Archive/Z/ZHandler.cpp create mode 100755 CPP/7zip/Archive/Z/ZHandler.h create mode 100755 CPP/7zip/Archive/Z/makefile create mode 100755 CPP/7zip/Archive/Z/resource.rc create mode 100755 CPP/7zip/Archive/Zip/DllExports.cpp create mode 100755 CPP/7zip/Archive/Zip/StdAfx.cpp create mode 100755 CPP/7zip/Archive/Zip/StdAfx.h create mode 100755 CPP/7zip/Archive/Zip/Zip.dsp create mode 100755 CPP/7zip/Archive/Zip/Zip.dsw create mode 100755 CPP/7zip/Archive/Zip/ZipAddCommon.cpp create mode 100755 CPP/7zip/Archive/Zip/ZipAddCommon.h create mode 100755 CPP/7zip/Archive/Zip/ZipCompressionMode.h create mode 100755 CPP/7zip/Archive/Zip/ZipHandler.cpp create mode 100755 CPP/7zip/Archive/Zip/ZipHandler.h create mode 100755 CPP/7zip/Archive/Zip/ZipHandlerOut.cpp create mode 100755 CPP/7zip/Archive/Zip/ZipHeader.cpp create mode 100755 CPP/7zip/Archive/Zip/ZipHeader.h create mode 100755 CPP/7zip/Archive/Zip/ZipIn.cpp create mode 100755 CPP/7zip/Archive/Zip/ZipIn.h create mode 100755 CPP/7zip/Archive/Zip/ZipItem.cpp create mode 100755 CPP/7zip/Archive/Zip/ZipItem.h create mode 100755 CPP/7zip/Archive/Zip/ZipItemEx.h create mode 100755 CPP/7zip/Archive/Zip/ZipOut.cpp create mode 100755 CPP/7zip/Archive/Zip/ZipOut.h create mode 100755 CPP/7zip/Archive/Zip/ZipUpdate.cpp create mode 100755 CPP/7zip/Archive/Zip/ZipUpdate.h create mode 100755 CPP/7zip/Archive/Zip/makefile create mode 100755 CPP/7zip/Archive/Zip/resource.rc create mode 100755 CPP/7zip/Archive/Zip/zip.ico create mode 100755 CPP/7zip/Archive/makefile create mode 100755 CPP/7zip/Bundles/Alone/Alone.dsp create mode 100755 CPP/7zip/Bundles/Alone/Alone.dsw create mode 100755 CPP/7zip/Bundles/Alone/StdAfx.cpp create mode 100755 CPP/7zip/Bundles/Alone/StdAfx.h create mode 100755 CPP/7zip/Bundles/Alone/afxres.h create mode 100755 CPP/7zip/Bundles/Alone/makefile create mode 100755 CPP/7zip/Bundles/Alone/resource.rc create mode 100755 CPP/7zip/Bundles/Alone7z/Alone.dsp create mode 100755 CPP/7zip/Bundles/Alone7z/Alone.dsw create mode 100755 CPP/7zip/Bundles/Alone7z/StdAfx.cpp create mode 100755 CPP/7zip/Bundles/Alone7z/StdAfx.h create mode 100755 CPP/7zip/Bundles/Alone7z/makefile create mode 100755 CPP/7zip/Bundles/Alone7z/resource.rc create mode 100755 CPP/7zip/Bundles/Format7z/Format7z.dsp create mode 100755 CPP/7zip/Bundles/Format7z/Format7z.dsw create mode 100755 CPP/7zip/Bundles/Format7z/StdAfx.cpp create mode 100755 CPP/7zip/Bundles/Format7z/StdAfx.h create mode 100755 CPP/7zip/Bundles/Format7z/makefile create mode 100755 CPP/7zip/Bundles/Format7z/resource.rc create mode 100755 CPP/7zip/Bundles/Format7zExtract/Format7z.dsp create mode 100755 CPP/7zip/Bundles/Format7zExtract/Format7z.dsw create mode 100755 CPP/7zip/Bundles/Format7zExtract/StdAfx.cpp create mode 100755 CPP/7zip/Bundles/Format7zExtract/StdAfx.h create mode 100755 CPP/7zip/Bundles/Format7zExtract/makefile create mode 100755 CPP/7zip/Bundles/Format7zExtract/resource.rc create mode 100755 CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp create mode 100755 CPP/7zip/Bundles/Format7zExtractR/StdAfx.h create mode 100755 CPP/7zip/Bundles/Format7zExtractR/makefile create mode 100755 CPP/7zip/Bundles/Format7zExtractR/resource.rc create mode 100755 CPP/7zip/Bundles/Format7zR/StdAfx.cpp create mode 100755 CPP/7zip/Bundles/Format7zR/StdAfx.h create mode 100755 CPP/7zip/Bundles/Format7zR/makefile create mode 100755 CPP/7zip/Bundles/Format7zR/resource.rc create mode 100755 CPP/7zip/Bundles/SFXCon/7z.ico create mode 100755 CPP/7zip/Bundles/SFXCon/Main.cpp create mode 100755 CPP/7zip/Bundles/SFXCon/SFXCon.dsp create mode 100755 CPP/7zip/Bundles/SFXCon/SFXCon.dsw create mode 100755 CPP/7zip/Bundles/SFXCon/StdAfx.cpp create mode 100755 CPP/7zip/Bundles/SFXCon/StdAfx.h create mode 100755 CPP/7zip/Bundles/SFXCon/makefile create mode 100755 CPP/7zip/Bundles/SFXCon/resource.rc create mode 100755 CPP/7zip/Bundles/SFXSetup/ExtractCallback.cpp create mode 100755 CPP/7zip/Bundles/SFXSetup/ExtractCallback.h create mode 100755 CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp create mode 100755 CPP/7zip/Bundles/SFXSetup/ExtractEngine.h create mode 100755 CPP/7zip/Bundles/SFXSetup/Main.cpp create mode 100755 CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp create mode 100755 CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw create mode 100755 CPP/7zip/Bundles/SFXSetup/StdAfx.cpp create mode 100755 CPP/7zip/Bundles/SFXSetup/StdAfx.h create mode 100755 CPP/7zip/Bundles/SFXSetup/makefile create mode 100755 CPP/7zip/Bundles/SFXSetup/resource.h create mode 100755 CPP/7zip/Bundles/SFXSetup/resource.rc create mode 100755 CPP/7zip/Bundles/SFXSetup/setup.ico create mode 100755 CPP/7zip/Bundles/SFXWin/7z.ico create mode 100755 CPP/7zip/Bundles/SFXWin/Main.cpp create mode 100755 CPP/7zip/Bundles/SFXWin/SFXWin.dsp create mode 100755 CPP/7zip/Bundles/SFXWin/SFXWin.dsw create mode 100755 CPP/7zip/Bundles/SFXWin/StdAfx.cpp create mode 100755 CPP/7zip/Bundles/SFXWin/StdAfx.h create mode 100755 CPP/7zip/Bundles/SFXWin/makefile create mode 100755 CPP/7zip/Bundles/SFXWin/resource.h create mode 100755 CPP/7zip/Bundles/SFXWin/resource.rc create mode 100755 CPP/7zip/Bundles/makefile create mode 100755 CPP/7zip/Common/FilePathAutoRename.cpp create mode 100755 CPP/7zip/Common/FilePathAutoRename.h create mode 100755 CPP/7zip/Common/FileStreams.cpp create mode 100755 CPP/7zip/Common/FileStreams.h create mode 100755 CPP/7zip/Common/InBuffer.cpp create mode 100755 CPP/7zip/Common/InBuffer.h create mode 100755 CPP/7zip/Common/InMemStream.cpp create mode 100755 CPP/7zip/Common/InMemStream.h create mode 100755 CPP/7zip/Common/InOutTempBuffer.cpp create mode 100755 CPP/7zip/Common/InOutTempBuffer.h create mode 100755 CPP/7zip/Common/LSBFDecoder.cpp create mode 100755 CPP/7zip/Common/LSBFDecoder.h create mode 100755 CPP/7zip/Common/LSBFEncoder.cpp create mode 100755 CPP/7zip/Common/LSBFEncoder.h create mode 100755 CPP/7zip/Common/LimitedStreams.cpp create mode 100755 CPP/7zip/Common/LimitedStreams.h create mode 100755 CPP/7zip/Common/LockedStream.cpp create mode 100755 CPP/7zip/Common/LockedStream.h create mode 100755 CPP/7zip/Common/MSBFDecoder.h create mode 100755 CPP/7zip/Common/MSBFEncoder.h create mode 100755 CPP/7zip/Common/MemBlocks.cpp create mode 100755 CPP/7zip/Common/MemBlocks.h create mode 100755 CPP/7zip/Common/OffsetStream.cpp create mode 100755 CPP/7zip/Common/OffsetStream.h create mode 100755 CPP/7zip/Common/OutBuffer.cpp create mode 100755 CPP/7zip/Common/OutBuffer.h create mode 100755 CPP/7zip/Common/OutMemStream.cpp create mode 100755 CPP/7zip/Common/OutMemStream.h create mode 100755 CPP/7zip/Common/ProgressMt.cpp create mode 100755 CPP/7zip/Common/ProgressMt.h create mode 100755 CPP/7zip/Common/ProgressUtils.cpp create mode 100755 CPP/7zip/Common/ProgressUtils.h create mode 100755 CPP/7zip/Common/StdAfx.h create mode 100755 CPP/7zip/Common/StreamBinder.cpp create mode 100755 CPP/7zip/Common/StreamBinder.h create mode 100755 CPP/7zip/Common/StreamObjects.cpp create mode 100755 CPP/7zip/Common/StreamObjects.h create mode 100755 CPP/7zip/Common/StreamUtils.cpp create mode 100755 CPP/7zip/Common/StreamUtils.h create mode 100755 CPP/7zip/Compress/Arj/ArjDecoder1.cpp create mode 100755 CPP/7zip/Compress/Arj/ArjDecoder1.h create mode 100755 CPP/7zip/Compress/Arj/ArjDecoder2.cpp create mode 100755 CPP/7zip/Compress/Arj/ArjDecoder2.h create mode 100755 CPP/7zip/Compress/Arj/StdAfx.h create mode 100755 CPP/7zip/Compress/BWT/BlockSort.cpp create mode 100755 CPP/7zip/Compress/BWT/BlockSort.h create mode 100755 CPP/7zip/Compress/BWT/Mtf8.h create mode 100755 CPP/7zip/Compress/BWT/StdAfx.h create mode 100755 CPP/7zip/Compress/BZip2/BZip2.dsp create mode 100755 CPP/7zip/Compress/BZip2/BZip2.dsw create mode 100755 CPP/7zip/Compress/BZip2/BZip2CRC.cpp create mode 100755 CPP/7zip/Compress/BZip2/BZip2CRC.h create mode 100755 CPP/7zip/Compress/BZip2/BZip2Const.h create mode 100755 CPP/7zip/Compress/BZip2/BZip2Decoder.cpp create mode 100755 CPP/7zip/Compress/BZip2/BZip2Decoder.h create mode 100755 CPP/7zip/Compress/BZip2/BZip2Encoder.cpp create mode 100755 CPP/7zip/Compress/BZip2/BZip2Encoder.h create mode 100755 CPP/7zip/Compress/BZip2/DllExports.cpp create mode 100755 CPP/7zip/Compress/BZip2/StdAfx.cpp create mode 100755 CPP/7zip/Compress/BZip2/StdAfx.h create mode 100755 CPP/7zip/Compress/BZip2/makefile create mode 100755 CPP/7zip/Compress/BZip2/resource.rc create mode 100755 CPP/7zip/Compress/BZip2Original/BZip2Decoder.cpp create mode 100755 CPP/7zip/Compress/BZip2Original/BZip2Decoder.h create mode 100755 CPP/7zip/Compress/BZip2Original/BZip2Encoder.cpp create mode 100755 CPP/7zip/Compress/BZip2Original/BZip2Encoder.h create mode 100755 CPP/7zip/Compress/BZip2Original/BZip2Error.cpp create mode 100755 CPP/7zip/Compress/BZip2Original/DllExports.cpp create mode 100755 CPP/7zip/Compress/BZip2Original/StdAfx.cpp create mode 100755 CPP/7zip/Compress/BZip2Original/StdAfx.h create mode 100755 CPP/7zip/Compress/Branch/ARM.cpp create mode 100755 CPP/7zip/Compress/Branch/ARM.h create mode 100755 CPP/7zip/Compress/Branch/ARMThumb.cpp create mode 100755 CPP/7zip/Compress/Branch/ARMThumb.h create mode 100755 CPP/7zip/Compress/Branch/Branch.dsp create mode 100755 CPP/7zip/Compress/Branch/Branch.dsw create mode 100755 CPP/7zip/Compress/Branch/BranchCoder.cpp create mode 100755 CPP/7zip/Compress/Branch/BranchCoder.h create mode 100755 CPP/7zip/Compress/Branch/DllExports.cpp create mode 100755 CPP/7zip/Compress/Branch/IA64.cpp create mode 100755 CPP/7zip/Compress/Branch/IA64.h create mode 100755 CPP/7zip/Compress/Branch/PPC.cpp create mode 100755 CPP/7zip/Compress/Branch/PPC.h create mode 100755 CPP/7zip/Compress/Branch/SPARC.cpp create mode 100755 CPP/7zip/Compress/Branch/SPARC.h create mode 100755 CPP/7zip/Compress/Branch/StdAfx.cpp create mode 100755 CPP/7zip/Compress/Branch/StdAfx.h create mode 100755 CPP/7zip/Compress/Branch/makefile create mode 100755 CPP/7zip/Compress/Branch/resource.rc create mode 100755 CPP/7zip/Compress/Branch/x86.cpp create mode 100755 CPP/7zip/Compress/Branch/x86.h create mode 100755 CPP/7zip/Compress/Branch/x86_2.cpp create mode 100755 CPP/7zip/Compress/Branch/x86_2.h create mode 100755 CPP/7zip/Compress/ByteSwap/ByteSwap.cpp create mode 100755 CPP/7zip/Compress/ByteSwap/ByteSwap.dsp create mode 100755 CPP/7zip/Compress/ByteSwap/ByteSwap.dsw create mode 100755 CPP/7zip/Compress/ByteSwap/ByteSwap.h create mode 100755 CPP/7zip/Compress/ByteSwap/DllExports.cpp create mode 100755 CPP/7zip/Compress/ByteSwap/StdAfx.cpp create mode 100755 CPP/7zip/Compress/ByteSwap/StdAfx.h create mode 100755 CPP/7zip/Compress/ByteSwap/makefile create mode 100755 CPP/7zip/Compress/ByteSwap/resource.rc create mode 100755 CPP/7zip/Compress/Codec.def create mode 100755 CPP/7zip/Compress/Copy/Copy.dsp create mode 100755 CPP/7zip/Compress/Copy/Copy.dsw create mode 100755 CPP/7zip/Compress/Copy/CopyCoder.cpp create mode 100755 CPP/7zip/Compress/Copy/CopyCoder.h create mode 100755 CPP/7zip/Compress/Copy/DllExports.cpp create mode 100755 CPP/7zip/Compress/Copy/StdAfx.cpp create mode 100755 CPP/7zip/Compress/Copy/StdAfx.h create mode 100755 CPP/7zip/Compress/Copy/makefile create mode 100755 CPP/7zip/Compress/Copy/resource.rc create mode 100755 CPP/7zip/Compress/Deflate/Deflate.dsp create mode 100755 CPP/7zip/Compress/Deflate/Deflate.dsw create mode 100755 CPP/7zip/Compress/Deflate/DeflateConst.h create mode 100755 CPP/7zip/Compress/Deflate/DeflateDecoder.cpp create mode 100755 CPP/7zip/Compress/Deflate/DeflateDecoder.h create mode 100755 CPP/7zip/Compress/Deflate/DeflateEncoder.cpp create mode 100755 CPP/7zip/Compress/Deflate/DeflateEncoder.h create mode 100755 CPP/7zip/Compress/Deflate/DllExports.cpp create mode 100755 CPP/7zip/Compress/Deflate/StdAfx.cpp create mode 100755 CPP/7zip/Compress/Deflate/StdAfx.h create mode 100755 CPP/7zip/Compress/Deflate/makefile create mode 100755 CPP/7zip/Compress/Deflate/resource.rc create mode 100755 CPP/7zip/Compress/Huffman/HuffmanDecoder.h create mode 100755 CPP/7zip/Compress/Huffman/StdAfx.h create mode 100755 CPP/7zip/Compress/Implode/DllExports.cpp create mode 100755 CPP/7zip/Compress/Implode/ImplodeDecoder.cpp create mode 100755 CPP/7zip/Compress/Implode/ImplodeDecoder.h create mode 100755 CPP/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp create mode 100755 CPP/7zip/Compress/Implode/ImplodeHuffmanDecoder.h create mode 100755 CPP/7zip/Compress/Implode/StdAfx.cpp create mode 100755 CPP/7zip/Compress/Implode/StdAfx.h create mode 100755 CPP/7zip/Compress/LZ/LZOutWindow.cpp create mode 100755 CPP/7zip/Compress/LZ/LZOutWindow.h create mode 100755 CPP/7zip/Compress/LZ/StdAfx.h create mode 100755 CPP/7zip/Compress/LZMA/DllExports.cpp create mode 100755 CPP/7zip/Compress/LZMA/LZMA.dsp create mode 100755 CPP/7zip/Compress/LZMA/LZMA.dsw create mode 100755 CPP/7zip/Compress/LZMA/LZMA.h create mode 100755 CPP/7zip/Compress/LZMA/LZMADecoder.cpp create mode 100755 CPP/7zip/Compress/LZMA/LZMADecoder.h create mode 100755 CPP/7zip/Compress/LZMA/LZMAEncoder.cpp create mode 100755 CPP/7zip/Compress/LZMA/LZMAEncoder.h create mode 100755 CPP/7zip/Compress/LZMA/StdAfx.cpp create mode 100755 CPP/7zip/Compress/LZMA/StdAfx.h create mode 100755 CPP/7zip/Compress/LZMA/makefile create mode 100755 CPP/7zip/Compress/LZMA/resource.rc create mode 100755 CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp create mode 100755 CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsw create mode 100755 CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp create mode 100755 CPP/7zip/Compress/LZMA_Alone/LzmaBench.cpp create mode 100755 CPP/7zip/Compress/LZMA_Alone/LzmaBench.h create mode 100755 CPP/7zip/Compress/LZMA_Alone/LzmaRam.cpp create mode 100755 CPP/7zip/Compress/LZMA_Alone/LzmaRam.h create mode 100755 CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.c create mode 100755 CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.h create mode 100755 CPP/7zip/Compress/LZMA_Alone/StdAfx.cpp create mode 100755 CPP/7zip/Compress/LZMA_Alone/StdAfx.h create mode 100755 CPP/7zip/Compress/LZMA_Alone/makefile create mode 100755 CPP/7zip/Compress/LZMA_Alone/makefile.gcc create mode 100755 CPP/7zip/Compress/Lzh/LzhDecoder.cpp create mode 100755 CPP/7zip/Compress/Lzh/LzhDecoder.h create mode 100755 CPP/7zip/Compress/Lzx/Lzx.h create mode 100755 CPP/7zip/Compress/Lzx/Lzx86Converter.cpp create mode 100755 CPP/7zip/Compress/Lzx/Lzx86Converter.h create mode 100755 CPP/7zip/Compress/Lzx/LzxDecoder.cpp create mode 100755 CPP/7zip/Compress/Lzx/LzxDecoder.h create mode 100755 CPP/7zip/Compress/Lzx/StdAfx.h create mode 100755 CPP/7zip/Compress/PPMD/DllExports.cpp create mode 100755 CPP/7zip/Compress/PPMD/PPMD.dsp create mode 100755 CPP/7zip/Compress/PPMD/PPMD.dsw create mode 100755 CPP/7zip/Compress/PPMD/PPMDContext.h create mode 100755 CPP/7zip/Compress/PPMD/PPMDDecode.h create mode 100755 CPP/7zip/Compress/PPMD/PPMDDecoder.cpp create mode 100755 CPP/7zip/Compress/PPMD/PPMDDecoder.h create mode 100755 CPP/7zip/Compress/PPMD/PPMDEncode.h create mode 100755 CPP/7zip/Compress/PPMD/PPMDEncoder.cpp create mode 100755 CPP/7zip/Compress/PPMD/PPMDEncoder.h create mode 100755 CPP/7zip/Compress/PPMD/PPMDSubAlloc.h create mode 100755 CPP/7zip/Compress/PPMD/PPMDType.h create mode 100755 CPP/7zip/Compress/PPMD/StdAfx.cpp create mode 100755 CPP/7zip/Compress/PPMD/StdAfx.h create mode 100755 CPP/7zip/Compress/PPMD/makefile create mode 100755 CPP/7zip/Compress/PPMD/resource.rc create mode 100755 CPP/7zip/Compress/Quantum/QuantumDecoder.cpp create mode 100755 CPP/7zip/Compress/Quantum/QuantumDecoder.h create mode 100755 CPP/7zip/Compress/RangeCoder/RangeCoder.h create mode 100755 CPP/7zip/Compress/RangeCoder/RangeCoderBit.cpp create mode 100755 CPP/7zip/Compress/RangeCoder/RangeCoderBit.h create mode 100755 CPP/7zip/Compress/RangeCoder/RangeCoderBitTree.h create mode 100755 CPP/7zip/Compress/RangeCoder/RangeCoderOpt.h create mode 100755 CPP/7zip/Compress/RangeCoder/StdAfx.h create mode 100755 CPP/7zip/Compress/Rar/DllExports.cpp create mode 100755 CPP/7zip/Compress/Rar/Rar1Decoder.cpp create mode 100755 CPP/7zip/Compress/Rar/Rar1Decoder.h create mode 100755 CPP/7zip/Compress/Rar/Rar29.dsp create mode 100755 CPP/7zip/Compress/Rar/Rar29.dsw create mode 100755 CPP/7zip/Compress/Rar/Rar2Decoder.cpp create mode 100755 CPP/7zip/Compress/Rar/Rar2Decoder.h create mode 100755 CPP/7zip/Compress/Rar/Rar3Decoder.cpp create mode 100755 CPP/7zip/Compress/Rar/Rar3Decoder.h create mode 100755 CPP/7zip/Compress/Rar/Rar3Vm.cpp create mode 100755 CPP/7zip/Compress/Rar/Rar3Vm.h create mode 100755 CPP/7zip/Compress/Rar/StdAfx.cpp create mode 100755 CPP/7zip/Compress/Rar/StdAfx.h create mode 100755 CPP/7zip/Compress/Rar/makefile create mode 100755 CPP/7zip/Compress/Rar/resource.rc create mode 100755 CPP/7zip/Compress/Shrink/DllExports.cpp create mode 100755 CPP/7zip/Compress/Shrink/ShrinkDecoder.cpp create mode 100755 CPP/7zip/Compress/Shrink/ShrinkDecoder.h create mode 100755 CPP/7zip/Compress/Shrink/StdAfx.cpp create mode 100755 CPP/7zip/Compress/Shrink/StdAfx.h create mode 100755 CPP/7zip/Compress/Z/StdAfx.cpp create mode 100755 CPP/7zip/Compress/Z/StdAfx.h create mode 100755 CPP/7zip/Compress/Z/ZDecoder.cpp create mode 100755 CPP/7zip/Compress/Z/ZDecoder.h create mode 100755 CPP/7zip/Compress/makefile create mode 100755 CPP/7zip/Crypto/7zAES/7zAES.cpp create mode 100755 CPP/7zip/Crypto/7zAES/7zAES.dsp create mode 100755 CPP/7zip/Crypto/7zAES/7zAES.dsw create mode 100755 CPP/7zip/Crypto/7zAES/7zAES.h create mode 100755 CPP/7zip/Crypto/7zAES/DllExports.cpp create mode 100755 CPP/7zip/Crypto/7zAES/StdAfx.cpp create mode 100755 CPP/7zip/Crypto/7zAES/StdAfx.h create mode 100755 CPP/7zip/Crypto/7zAES/makefile create mode 100755 CPP/7zip/Crypto/7zAES/resource.rc create mode 100755 CPP/7zip/Crypto/AES/AES.dsp create mode 100755 CPP/7zip/Crypto/AES/AES.dsw create mode 100755 CPP/7zip/Crypto/AES/AES_CBC.h create mode 100755 CPP/7zip/Crypto/AES/DllExports.cpp create mode 100755 CPP/7zip/Crypto/AES/MyAES.cpp create mode 100755 CPP/7zip/Crypto/AES/MyAES.h create mode 100755 CPP/7zip/Crypto/AES/StdAfx.cpp create mode 100755 CPP/7zip/Crypto/AES/StdAfx.h create mode 100755 CPP/7zip/Crypto/AES/aes.h create mode 100755 CPP/7zip/Crypto/AES/aescpp.h create mode 100755 CPP/7zip/Crypto/AES/aescrypt.c create mode 100755 CPP/7zip/Crypto/AES/aeskey.c create mode 100755 CPP/7zip/Crypto/AES/aesopt.h create mode 100755 CPP/7zip/Crypto/AES/aestab.c create mode 100755 CPP/7zip/Crypto/AES/makefile create mode 100755 CPP/7zip/Crypto/AES/resource.rc create mode 100755 CPP/7zip/Crypto/Codec.def create mode 100755 CPP/7zip/Crypto/Hash/HmacSha1.cpp create mode 100755 CPP/7zip/Crypto/Hash/HmacSha1.h create mode 100755 CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.cpp create mode 100755 CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.h create mode 100755 CPP/7zip/Crypto/Hash/RandGen.cpp create mode 100755 CPP/7zip/Crypto/Hash/RandGen.h create mode 100755 CPP/7zip/Crypto/Hash/RotateDefs.h create mode 100755 CPP/7zip/Crypto/Hash/Sha1.cpp create mode 100755 CPP/7zip/Crypto/Hash/Sha1.h create mode 100755 CPP/7zip/Crypto/Hash/Sha256.cpp create mode 100755 CPP/7zip/Crypto/Hash/Sha256.h create mode 100755 CPP/7zip/Crypto/Hash/StdAfx.h create mode 100755 CPP/7zip/Crypto/Rar20/Rar20Cipher.cpp create mode 100755 CPP/7zip/Crypto/Rar20/Rar20Cipher.h create mode 100755 CPP/7zip/Crypto/Rar20/Rar20Crypto.cpp create mode 100755 CPP/7zip/Crypto/Rar20/Rar20Crypto.h create mode 100755 CPP/7zip/Crypto/Rar20/StdAfx.h create mode 100755 CPP/7zip/Crypto/RarAES/RarAES.cpp create mode 100755 CPP/7zip/Crypto/RarAES/RarAES.h create mode 100755 CPP/7zip/Crypto/RarAES/StdAfx.h create mode 100755 CPP/7zip/Crypto/WzAES/StdAfx.cpp create mode 100755 CPP/7zip/Crypto/WzAES/StdAfx.h create mode 100755 CPP/7zip/Crypto/WzAES/WzAES.cpp create mode 100755 CPP/7zip/Crypto/WzAES/WzAES.h create mode 100755 CPP/7zip/Crypto/Zip/StdAfx.h create mode 100755 CPP/7zip/Crypto/Zip/ZipCipher.cpp create mode 100755 CPP/7zip/Crypto/Zip/ZipCipher.h create mode 100755 CPP/7zip/Crypto/Zip/ZipCrypto.cpp create mode 100755 CPP/7zip/Crypto/Zip/ZipCrypto.h create mode 100755 CPP/7zip/Crypto/makefile create mode 100755 CPP/7zip/FileManager/7zFM.exe.manifest create mode 100755 CPP/7zip/FileManager/7zipLogo.ico create mode 100755 CPP/7zip/FileManager/Add.bmp create mode 100755 CPP/7zip/FileManager/Add2.bmp create mode 100755 CPP/7zip/FileManager/App.cpp create mode 100755 CPP/7zip/FileManager/App.h create mode 100755 CPP/7zip/FileManager/AppState.h create mode 100755 CPP/7zip/FileManager/ClassDefs.cpp create mode 100755 CPP/7zip/FileManager/Copy.bmp create mode 100755 CPP/7zip/FileManager/Copy2.bmp create mode 100755 CPP/7zip/FileManager/Delete.bmp create mode 100755 CPP/7zip/FileManager/Delete2.bmp create mode 100755 CPP/7zip/FileManager/EnumFormatEtc.cpp create mode 100755 CPP/7zip/FileManager/EnumFormatEtc.h create mode 100755 CPP/7zip/FileManager/Extract.bmp create mode 100755 CPP/7zip/FileManager/Extract2.bmp create mode 100755 CPP/7zip/FileManager/ExtractCallback.cpp create mode 100755 CPP/7zip/FileManager/ExtractCallback.h create mode 100755 CPP/7zip/FileManager/FM.cpp create mode 100755 CPP/7zip/FileManager/FM.dsp create mode 100755 CPP/7zip/FileManager/FM.dsw create mode 100755 CPP/7zip/FileManager/FM.ico create mode 100755 CPP/7zip/FileManager/FSDrives.cpp create mode 100755 CPP/7zip/FileManager/FSDrives.h create mode 100755 CPP/7zip/FileManager/FSFolder.cpp create mode 100755 CPP/7zip/FileManager/FSFolder.h create mode 100755 CPP/7zip/FileManager/FSFolderCopy.cpp create mode 100755 CPP/7zip/FileManager/FileFolderPluginOpen.cpp create mode 100755 CPP/7zip/FileManager/FileFolderPluginOpen.h create mode 100755 CPP/7zip/FileManager/FilePlugins.cpp create mode 100755 CPP/7zip/FileManager/FilePlugins.h create mode 100755 CPP/7zip/FileManager/FormatUtils.cpp create mode 100755 CPP/7zip/FileManager/FormatUtils.h create mode 100755 CPP/7zip/FileManager/HelpUtils.cpp create mode 100755 CPP/7zip/FileManager/HelpUtils.h create mode 100755 CPP/7zip/FileManager/IFolder.h create mode 100755 CPP/7zip/FileManager/Info.bmp create mode 100755 CPP/7zip/FileManager/Info2.bmp create mode 100755 CPP/7zip/FileManager/LangUtils.cpp create mode 100755 CPP/7zip/FileManager/LangUtils.h create mode 100755 CPP/7zip/FileManager/Move.bmp create mode 100755 CPP/7zip/FileManager/Move2.bmp create mode 100755 CPP/7zip/FileManager/MyCom2.h create mode 100755 CPP/7zip/FileManager/MyLoadMenu.cpp create mode 100755 CPP/7zip/FileManager/MyLoadMenu.h create mode 100755 CPP/7zip/FileManager/NetFolder.cpp create mode 100755 CPP/7zip/FileManager/NetFolder.h create mode 100755 CPP/7zip/FileManager/OpenCallback.cpp create mode 100755 CPP/7zip/FileManager/OpenCallback.h create mode 100755 CPP/7zip/FileManager/OptionsDialog.cpp create mode 100755 CPP/7zip/FileManager/Panel.cpp create mode 100755 CPP/7zip/FileManager/Panel.h create mode 100755 CPP/7zip/FileManager/PanelCopy.cpp create mode 100755 CPP/7zip/FileManager/PanelCrc.cpp create mode 100755 CPP/7zip/FileManager/PanelDrag.cpp create mode 100755 CPP/7zip/FileManager/PanelFolderChange.cpp create mode 100755 CPP/7zip/FileManager/PanelItemOpen.cpp create mode 100755 CPP/7zip/FileManager/PanelItems.cpp create mode 100755 CPP/7zip/FileManager/PanelKey.cpp create mode 100755 CPP/7zip/FileManager/PanelListNotify.cpp create mode 100755 CPP/7zip/FileManager/PanelMenu.cpp create mode 100755 CPP/7zip/FileManager/PanelOperations.cpp create mode 100755 CPP/7zip/FileManager/PanelSelect.cpp create mode 100755 CPP/7zip/FileManager/PanelSort.cpp create mode 100755 CPP/7zip/FileManager/PanelSplitFile.cpp create mode 100755 CPP/7zip/FileManager/PhysDriveFolder.cpp create mode 100755 CPP/7zip/FileManager/PhysDriveFolder.h create mode 100755 CPP/7zip/FileManager/PluginInterface.h create mode 100755 CPP/7zip/FileManager/PluginLoader.h create mode 100755 CPP/7zip/FileManager/ProgramLocation.cpp create mode 100755 CPP/7zip/FileManager/ProgramLocation.h create mode 100755 CPP/7zip/FileManager/PropertyName.cpp create mode 100755 CPP/7zip/FileManager/PropertyName.h create mode 100755 CPP/7zip/FileManager/RegistryAssociations.cpp create mode 100755 CPP/7zip/FileManager/RegistryAssociations.h create mode 100755 CPP/7zip/FileManager/RegistryPlugins.cpp create mode 100755 CPP/7zip/FileManager/RegistryPlugins.h create mode 100755 CPP/7zip/FileManager/RegistryUtils.cpp create mode 100755 CPP/7zip/FileManager/RegistryUtils.h create mode 100755 CPP/7zip/FileManager/Resource/AboutDialog/7zipLogo.ico create mode 100755 CPP/7zip/FileManager/Resource/AboutDialog/AboutDialog.cpp create mode 100755 CPP/7zip/FileManager/Resource/AboutDialog/AboutDialog.h create mode 100755 CPP/7zip/FileManager/Resource/AboutDialog/StdAfx.h create mode 100755 CPP/7zip/FileManager/Resource/AboutDialog/resource.h create mode 100755 CPP/7zip/FileManager/Resource/AboutDialog/resource.rc create mode 100755 CPP/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp create mode 100755 CPP/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.h create mode 100755 CPP/7zip/FileManager/Resource/BenchmarkDialog/StdAfx.h create mode 100755 CPP/7zip/FileManager/Resource/BenchmarkDialog/resource.h create mode 100755 CPP/7zip/FileManager/Resource/BenchmarkDialog/resource.rc create mode 100755 CPP/7zip/FileManager/Resource/ComboDialog/ComboDialog.cpp create mode 100755 CPP/7zip/FileManager/Resource/ComboDialog/ComboDialog.h create mode 100755 CPP/7zip/FileManager/Resource/ComboDialog/StdAfx.h create mode 100755 CPP/7zip/FileManager/Resource/ComboDialog/resource.h create mode 100755 CPP/7zip/FileManager/Resource/ComboDialog/resource.rc create mode 100755 CPP/7zip/FileManager/Resource/CopyDialog/CopyDialog.cpp create mode 100755 CPP/7zip/FileManager/Resource/CopyDialog/CopyDialog.h create mode 100755 CPP/7zip/FileManager/Resource/CopyDialog/StdAfx.h create mode 100755 CPP/7zip/FileManager/Resource/CopyDialog/resource.h create mode 100755 CPP/7zip/FileManager/Resource/CopyDialog/resource.rc create mode 100755 CPP/7zip/FileManager/Resource/EditPage/EditPage.cpp create mode 100755 CPP/7zip/FileManager/Resource/EditPage/EditPage.h create mode 100755 CPP/7zip/FileManager/Resource/EditPage/StdAfx.h create mode 100755 CPP/7zip/FileManager/Resource/EditPage/resource.h create mode 100755 CPP/7zip/FileManager/Resource/EditPage/resource.rc create mode 100755 CPP/7zip/FileManager/Resource/LangPage/LangPage.cpp create mode 100755 CPP/7zip/FileManager/Resource/LangPage/LangPage.h create mode 100755 CPP/7zip/FileManager/Resource/LangPage/StdAfx.h create mode 100755 CPP/7zip/FileManager/Resource/LangPage/resource.h create mode 100755 CPP/7zip/FileManager/Resource/LangPage/resource.rc create mode 100755 CPP/7zip/FileManager/Resource/ListBoxDialog/StdAfx.h create mode 100755 CPP/7zip/FileManager/Resource/ListBoxDialog/resource.h create mode 100755 CPP/7zip/FileManager/Resource/ListBoxDialog/resource.rc create mode 100755 CPP/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.cpp create mode 100755 CPP/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.h create mode 100755 CPP/7zip/FileManager/Resource/ListViewDialog/StdAfx.h create mode 100755 CPP/7zip/FileManager/Resource/ListViewDialog/resource.h create mode 100755 CPP/7zip/FileManager/Resource/ListViewDialog/resource.rc create mode 100755 CPP/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.cpp create mode 100755 CPP/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.h create mode 100755 CPP/7zip/FileManager/Resource/MessagesDialog/StdAfx.h create mode 100755 CPP/7zip/FileManager/Resource/MessagesDialog/resource.h create mode 100755 CPP/7zip/FileManager/Resource/MessagesDialog/resource.rc create mode 100755 CPP/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.cpp create mode 100755 CPP/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.h create mode 100755 CPP/7zip/FileManager/Resource/OverwriteDialog/StdAfx.h create mode 100755 CPP/7zip/FileManager/Resource/OverwriteDialog/resource.h create mode 100755 CPP/7zip/FileManager/Resource/OverwriteDialog/resource.rc create mode 100755 CPP/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.cpp create mode 100755 CPP/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.h create mode 100755 CPP/7zip/FileManager/Resource/PasswordDialog/StdAfx.h create mode 100755 CPP/7zip/FileManager/Resource/PasswordDialog/resource.h create mode 100755 CPP/7zip/FileManager/Resource/PasswordDialog/resource.rc create mode 100755 CPP/7zip/FileManager/Resource/PluginsPage/PluginsPage.cpp create mode 100755 CPP/7zip/FileManager/Resource/PluginsPage/PluginsPage.h create mode 100755 CPP/7zip/FileManager/Resource/PluginsPage/StdAfx.h create mode 100755 CPP/7zip/FileManager/Resource/PluginsPage/resource.h create mode 100755 CPP/7zip/FileManager/Resource/PluginsPage/resource.rc create mode 100755 CPP/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.cpp create mode 100755 CPP/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.h create mode 100755 CPP/7zip/FileManager/Resource/ProgressDialog/StdAfx.h create mode 100755 CPP/7zip/FileManager/Resource/ProgressDialog/resource.h create mode 100755 CPP/7zip/FileManager/Resource/ProgressDialog/resource.rc create mode 100755 CPP/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.cpp create mode 100755 CPP/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.h create mode 100755 CPP/7zip/FileManager/Resource/ProgressDialog2/StdAfx.h create mode 100755 CPP/7zip/FileManager/Resource/ProgressDialog2/resource.h create mode 100755 CPP/7zip/FileManager/Resource/ProgressDialog2/resource.rc create mode 100755 CPP/7zip/FileManager/Resource/PropertyName/resource.h create mode 100755 CPP/7zip/FileManager/Resource/PropertyName/resource.rc create mode 100755 CPP/7zip/FileManager/Resource/SettingsPage/SettingsPage.cpp create mode 100755 CPP/7zip/FileManager/Resource/SettingsPage/SettingsPage.h create mode 100755 CPP/7zip/FileManager/Resource/SettingsPage/StdAfx.h create mode 100755 CPP/7zip/FileManager/Resource/SettingsPage/resource.h create mode 100755 CPP/7zip/FileManager/Resource/SettingsPage/resource.rc create mode 100755 CPP/7zip/FileManager/Resource/SplitDialog/SplitDialog.cpp create mode 100755 CPP/7zip/FileManager/Resource/SplitDialog/SplitDialog.h create mode 100755 CPP/7zip/FileManager/Resource/SplitDialog/StdAfx.h create mode 100755 CPP/7zip/FileManager/Resource/SplitDialog/resource.h create mode 100755 CPP/7zip/FileManager/Resource/SplitDialog/resource.rc create mode 100755 CPP/7zip/FileManager/Resource/SystemPage/StdAfx.h create mode 100755 CPP/7zip/FileManager/Resource/SystemPage/SystemPage.cpp create mode 100755 CPP/7zip/FileManager/Resource/SystemPage/SystemPage.h create mode 100755 CPP/7zip/FileManager/Resource/SystemPage/resource.h create mode 100755 CPP/7zip/FileManager/Resource/SystemPage/resource.rc create mode 100755 CPP/7zip/FileManager/RootFolder.cpp create mode 100755 CPP/7zip/FileManager/RootFolder.h create mode 100755 CPP/7zip/FileManager/SplitUtils.cpp create mode 100755 CPP/7zip/FileManager/SplitUtils.h create mode 100755 CPP/7zip/FileManager/StdAfx.cpp create mode 100755 CPP/7zip/FileManager/StdAfx.h create mode 100755 CPP/7zip/FileManager/StringUtils.cpp create mode 100755 CPP/7zip/FileManager/StringUtils.h create mode 100755 CPP/7zip/FileManager/SysIconUtils.cpp create mode 100755 CPP/7zip/FileManager/SysIconUtils.h create mode 100755 CPP/7zip/FileManager/Test.bmp create mode 100755 CPP/7zip/FileManager/Test2.bmp create mode 100755 CPP/7zip/FileManager/TextPairs.cpp create mode 100755 CPP/7zip/FileManager/TextPairs.h create mode 100755 CPP/7zip/FileManager/UpdateCallback100.cpp create mode 100755 CPP/7zip/FileManager/UpdateCallback100.h create mode 100755 CPP/7zip/FileManager/ViewSettings.cpp create mode 100755 CPP/7zip/FileManager/ViewSettings.h create mode 100755 CPP/7zip/FileManager/makefile create mode 100755 CPP/7zip/FileManager/resource.h create mode 100755 CPP/7zip/FileManager/resource.rc create mode 100755 CPP/7zip/GuiCommon.rc create mode 100755 CPP/7zip/Guid.txt create mode 100755 CPP/7zip/ICoder.h create mode 100755 CPP/7zip/IPassword.h create mode 100755 CPP/7zip/IProgress.h create mode 100755 CPP/7zip/IStream.h create mode 100755 CPP/7zip/MyVersion.h create mode 100755 CPP/7zip/MyVersionInfo.rc create mode 100755 CPP/7zip/PropID.h create mode 100755 CPP/7zip/SubBuild.mak create mode 100755 CPP/7zip/UI/Agent/Agent.cpp create mode 100755 CPP/7zip/UI/Agent/Agent.h create mode 100755 CPP/7zip/UI/Agent/AgentOut.cpp create mode 100755 CPP/7zip/UI/Agent/AgentProxy.cpp create mode 100755 CPP/7zip/UI/Agent/AgentProxy.h create mode 100755 CPP/7zip/UI/Agent/ArchiveFolder.cpp create mode 100755 CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp create mode 100755 CPP/7zip/UI/Agent/ArchiveFolderOut.cpp create mode 100755 CPP/7zip/UI/Agent/IFolderArchive.h create mode 100755 CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp create mode 100755 CPP/7zip/UI/Agent/UpdateCallbackAgent.h create mode 100755 CPP/7zip/UI/Client7z/Client7z.cpp create mode 100755 CPP/7zip/UI/Client7z/Client7z.dsp create mode 100755 CPP/7zip/UI/Client7z/Client7z.dsw create mode 100755 CPP/7zip/UI/Client7z/StdAfx.cpp create mode 100755 CPP/7zip/UI/Client7z/StdAfx.h create mode 100755 CPP/7zip/UI/Client7z/makefile create mode 100755 CPP/7zip/UI/Common/ArchiveCommandLine.cpp create mode 100755 CPP/7zip/UI/Common/ArchiveCommandLine.h create mode 100755 CPP/7zip/UI/Common/ArchiveExtractCallback.cpp create mode 100755 CPP/7zip/UI/Common/ArchiveExtractCallback.h create mode 100755 CPP/7zip/UI/Common/ArchiveName.cpp create mode 100755 CPP/7zip/UI/Common/ArchiveName.h create mode 100755 CPP/7zip/UI/Common/ArchiveOpenCallback.cpp create mode 100755 CPP/7zip/UI/Common/ArchiveOpenCallback.h create mode 100755 CPP/7zip/UI/Common/ArchiverInfo.cpp create mode 100755 CPP/7zip/UI/Common/ArchiverInfo.h create mode 100755 CPP/7zip/UI/Common/CompressCall.cpp create mode 100755 CPP/7zip/UI/Common/CompressCall.h create mode 100755 CPP/7zip/UI/Common/DefaultName.cpp create mode 100755 CPP/7zip/UI/Common/DefaultName.h create mode 100755 CPP/7zip/UI/Common/DirItem.h create mode 100755 CPP/7zip/UI/Common/EnumDirItems.cpp create mode 100755 CPP/7zip/UI/Common/EnumDirItems.h create mode 100755 CPP/7zip/UI/Common/ExitCode.h create mode 100755 CPP/7zip/UI/Common/Extract.cpp create mode 100755 CPP/7zip/UI/Common/Extract.h create mode 100755 CPP/7zip/UI/Common/ExtractMode.h create mode 100755 CPP/7zip/UI/Common/ExtractingFilePath.cpp create mode 100755 CPP/7zip/UI/Common/ExtractingFilePath.h create mode 100755 CPP/7zip/UI/Common/HandlerLoader.h create mode 100755 CPP/7zip/UI/Common/IFileExtractCallback.h create mode 100755 CPP/7zip/UI/Common/OpenArchive.cpp create mode 100755 CPP/7zip/UI/Common/OpenArchive.h create mode 100755 CPP/7zip/UI/Common/PropIDUtils.cpp create mode 100755 CPP/7zip/UI/Common/PropIDUtils.h create mode 100755 CPP/7zip/UI/Common/Property.h create mode 100755 CPP/7zip/UI/Common/SetProperties.cpp create mode 100755 CPP/7zip/UI/Common/SetProperties.h create mode 100755 CPP/7zip/UI/Common/SortUtils.cpp create mode 100755 CPP/7zip/UI/Common/SortUtils.h create mode 100755 CPP/7zip/UI/Common/StdAfx.h create mode 100755 CPP/7zip/UI/Common/TempFiles.cpp create mode 100755 CPP/7zip/UI/Common/TempFiles.h create mode 100755 CPP/7zip/UI/Common/Update.cpp create mode 100755 CPP/7zip/UI/Common/Update.h create mode 100755 CPP/7zip/UI/Common/UpdateAction.cpp create mode 100755 CPP/7zip/UI/Common/UpdateAction.h create mode 100755 CPP/7zip/UI/Common/UpdateCallback.cpp create mode 100755 CPP/7zip/UI/Common/UpdateCallback.h create mode 100755 CPP/7zip/UI/Common/UpdatePair.cpp create mode 100755 CPP/7zip/UI/Common/UpdatePair.h create mode 100755 CPP/7zip/UI/Common/UpdateProduce.cpp create mode 100755 CPP/7zip/UI/Common/UpdateProduce.h create mode 100755 CPP/7zip/UI/Common/WorkDir.cpp create mode 100755 CPP/7zip/UI/Common/WorkDir.h create mode 100755 CPP/7zip/UI/Common/ZipRegistry.cpp create mode 100755 CPP/7zip/UI/Common/ZipRegistry.h create mode 100755 CPP/7zip/UI/Console/Console.dsp create mode 100755 CPP/7zip/UI/Console/Console.dsw create mode 100755 CPP/7zip/UI/Console/ConsoleClose.cpp create mode 100755 CPP/7zip/UI/Console/ConsoleClose.h create mode 100755 CPP/7zip/UI/Console/ExtractCallbackConsole.cpp create mode 100755 CPP/7zip/UI/Console/ExtractCallbackConsole.h create mode 100755 CPP/7zip/UI/Console/List.cpp create mode 100755 CPP/7zip/UI/Console/List.h create mode 100755 CPP/7zip/UI/Console/Main.cpp create mode 100755 CPP/7zip/UI/Console/MainAr.cpp create mode 100755 CPP/7zip/UI/Console/OpenCallbackConsole.cpp create mode 100755 CPP/7zip/UI/Console/OpenCallbackConsole.h create mode 100755 CPP/7zip/UI/Console/PercentPrinter.cpp create mode 100755 CPP/7zip/UI/Console/PercentPrinter.h create mode 100755 CPP/7zip/UI/Console/StdAfx.cpp create mode 100755 CPP/7zip/UI/Console/StdAfx.h create mode 100755 CPP/7zip/UI/Console/UpdateCallbackConsole.cpp create mode 100755 CPP/7zip/UI/Console/UpdateCallbackConsole.h create mode 100755 CPP/7zip/UI/Console/UserInputUtils.cpp create mode 100755 CPP/7zip/UI/Console/UserInputUtils.h create mode 100755 CPP/7zip/UI/Console/afxres.h create mode 100755 CPP/7zip/UI/Console/makefile create mode 100755 CPP/7zip/UI/Console/resource.rc create mode 100755 CPP/7zip/UI/Explorer/7-zip.dll.manifest create mode 100755 CPP/7zip/UI/Explorer/ContextMenu.cpp create mode 100755 CPP/7zip/UI/Explorer/ContextMenu.h create mode 100755 CPP/7zip/UI/Explorer/ContextMenuFlags.h create mode 100755 CPP/7zip/UI/Explorer/DllExports.cpp create mode 100755 CPP/7zip/UI/Explorer/Explorer.def create mode 100755 CPP/7zip/UI/Explorer/Explorer.dsp create mode 100755 CPP/7zip/UI/Explorer/Explorer.dsw create mode 100755 CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.cpp create mode 100755 CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.h create mode 100755 CPP/7zip/UI/Explorer/FoldersPage/resource.h create mode 100755 CPP/7zip/UI/Explorer/FoldersPage/resource.rc create mode 100755 CPP/7zip/UI/Explorer/MyMessages.cpp create mode 100755 CPP/7zip/UI/Explorer/MyMessages.h create mode 100755 CPP/7zip/UI/Explorer/OptionsDialog.cpp create mode 100755 CPP/7zip/UI/Explorer/OptionsDialog.h create mode 100755 CPP/7zip/UI/Explorer/RegistryContextMenu.cpp create mode 100755 CPP/7zip/UI/Explorer/RegistryContextMenu.h create mode 100755 CPP/7zip/UI/Explorer/StdAfx.cpp create mode 100755 CPP/7zip/UI/Explorer/StdAfx.h create mode 100755 CPP/7zip/UI/Explorer/SystemPage/SystemPage.cpp create mode 100755 CPP/7zip/UI/Explorer/SystemPage/SystemPage.h create mode 100755 CPP/7zip/UI/Explorer/SystemPage/resource.h create mode 100755 CPP/7zip/UI/Explorer/SystemPage/resource.rc create mode 100755 CPP/7zip/UI/Explorer/makefile create mode 100755 CPP/7zip/UI/Explorer/resource.h create mode 100755 CPP/7zip/UI/Explorer/resource.rc create mode 100755 CPP/7zip/UI/Far/CLSIDConst.cpp create mode 100755 CPP/7zip/UI/Far/ExtractEngine.cpp create mode 100755 CPP/7zip/UI/Far/ExtractEngine.h create mode 100755 CPP/7zip/UI/Far/Far.def create mode 100755 CPP/7zip/UI/Far/Far.dsp create mode 100755 CPP/7zip/UI/Far/Far.dsw create mode 100755 CPP/7zip/UI/Far/FarPlugin.h create mode 100755 CPP/7zip/UI/Far/FarUtils.cpp create mode 100755 CPP/7zip/UI/Far/FarUtils.h create mode 100755 CPP/7zip/UI/Far/Main.cpp create mode 100755 CPP/7zip/UI/Far/Messages.h create mode 100755 CPP/7zip/UI/Far/OverwriteDialog.cpp create mode 100755 CPP/7zip/UI/Far/OverwriteDialog.h create mode 100755 CPP/7zip/UI/Far/Plugin.cpp create mode 100755 CPP/7zip/UI/Far/Plugin.h create mode 100755 CPP/7zip/UI/Far/PluginCommon.cpp create mode 100755 CPP/7zip/UI/Far/PluginDelete.cpp create mode 100755 CPP/7zip/UI/Far/PluginRead.cpp create mode 100755 CPP/7zip/UI/Far/PluginWrite.cpp create mode 100755 CPP/7zip/UI/Far/ProgressBox.cpp create mode 100755 CPP/7zip/UI/Far/ProgressBox.h create mode 100755 CPP/7zip/UI/Far/StdAfx.cpp create mode 100755 CPP/7zip/UI/Far/StdAfx.h create mode 100755 CPP/7zip/UI/Far/UpdateCallback100.cpp create mode 100755 CPP/7zip/UI/Far/UpdateCallback100.h create mode 100755 CPP/7zip/UI/Far/makefile create mode 100755 CPP/7zip/UI/Far/resource.rc create mode 100755 CPP/7zip/UI/GUI/7zG.exe.manifest create mode 100755 CPP/7zip/UI/GUI/CompressDialog.cpp create mode 100755 CPP/7zip/UI/GUI/CompressDialog.h create mode 100755 CPP/7zip/UI/GUI/ExtractDialog.cpp create mode 100755 CPP/7zip/UI/GUI/ExtractDialog.h create mode 100755 CPP/7zip/UI/GUI/ExtractGUI.cpp create mode 100755 CPP/7zip/UI/GUI/ExtractGUI.h create mode 100755 CPP/7zip/UI/GUI/FM.ico create mode 100755 CPP/7zip/UI/GUI/GUI.cpp create mode 100755 CPP/7zip/UI/GUI/GUI.dsp create mode 100755 CPP/7zip/UI/GUI/GUI.dsw create mode 100755 CPP/7zip/UI/GUI/OpenCallbackGUI.cpp create mode 100755 CPP/7zip/UI/GUI/OpenCallbackGUI.h create mode 100755 CPP/7zip/UI/GUI/StdAfx.cpp create mode 100755 CPP/7zip/UI/GUI/StdAfx.h create mode 100755 CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp create mode 100755 CPP/7zip/UI/GUI/UpdateCallbackGUI.h create mode 100755 CPP/7zip/UI/GUI/UpdateGUI.cpp create mode 100755 CPP/7zip/UI/GUI/UpdateGUI.h create mode 100755 CPP/7zip/UI/GUI/makefile create mode 100755 CPP/7zip/UI/GUI/resource.h create mode 100755 CPP/7zip/UI/GUI/resource.rc create mode 100755 CPP/7zip/UI/Resource/CompressDialog/resource.h create mode 100755 CPP/7zip/UI/Resource/CompressDialog/resource.rc create mode 100755 CPP/7zip/UI/Resource/Extract/resource.h create mode 100755 CPP/7zip/UI/Resource/Extract/resource.rc create mode 100755 CPP/7zip/UI/Resource/ExtractDialog/resource.h create mode 100755 CPP/7zip/UI/Resource/ExtractDialog/resource.rc create mode 100755 CPP/7zip/UI/makefile create mode 100755 CPP/7zip/makefile create mode 100755 CPP/Build.mak create mode 100755 CPP/Common/AlignedBuffer.cpp create mode 100755 CPP/Common/AlignedBuffer.h create mode 100755 CPP/Common/Alloc.cpp create mode 100755 CPP/Common/Alloc.h create mode 100755 CPP/Common/AutoPtr.h create mode 100755 CPP/Common/Buffer.h create mode 100755 CPP/Common/CRC.cpp create mode 100755 CPP/Common/CRC.h create mode 100755 CPP/Common/C_FileIO.cpp create mode 100755 CPP/Common/C_FileIO.h create mode 100755 CPP/Common/ComTry.h create mode 100755 CPP/Common/CommandLineParser.cpp create mode 100755 CPP/Common/CommandLineParser.h create mode 100755 CPP/Common/Defs.h create mode 100755 CPP/Common/DynamicBuffer.h create mode 100755 CPP/Common/Exception.h create mode 100755 CPP/Common/IntToString.cpp create mode 100755 CPP/Common/IntToString.h create mode 100755 CPP/Common/Lang.cpp create mode 100755 CPP/Common/Lang.h create mode 100755 CPP/Common/ListFileUtils.cpp create mode 100755 CPP/Common/ListFileUtils.h create mode 100755 CPP/Common/MyCom.h create mode 100755 CPP/Common/MyGuidDef.h create mode 100755 CPP/Common/MyInitGuid.h create mode 100755 CPP/Common/MyUnknown.h create mode 100755 CPP/Common/MyWindows.cpp create mode 100755 CPP/Common/MyWindows.h create mode 100755 CPP/Common/NewHandler.cpp create mode 100755 CPP/Common/NewHandler.h create mode 100755 CPP/Common/Random.cpp create mode 100755 CPP/Common/Random.h create mode 100755 CPP/Common/StdAfx.h create mode 100755 CPP/Common/StdInStream.cpp create mode 100755 CPP/Common/StdInStream.h create mode 100755 CPP/Common/StdOutStream.cpp create mode 100755 CPP/Common/StdOutStream.h create mode 100755 CPP/Common/String.cpp create mode 100755 CPP/Common/String.h create mode 100755 CPP/Common/StringConvert.cpp create mode 100755 CPP/Common/StringConvert.h create mode 100755 CPP/Common/StringToInt.cpp create mode 100755 CPP/Common/StringToInt.h create mode 100755 CPP/Common/TextConfig.cpp create mode 100755 CPP/Common/TextConfig.h create mode 100755 CPP/Common/Types.h create mode 100755 CPP/Common/UTFConvert.cpp create mode 100755 CPP/Common/UTFConvert.h create mode 100755 CPP/Common/Vector.cpp create mode 100755 CPP/Common/Vector.h create mode 100755 CPP/Common/Wildcard.cpp create mode 100755 CPP/Common/Wildcard.h create mode 100755 CPP/Windows/COM.cpp create mode 100755 CPP/Windows/COM.h create mode 100755 CPP/Windows/CommonDialog.cpp create mode 100755 CPP/Windows/CommonDialog.h create mode 100755 CPP/Windows/Console.cpp create mode 100755 CPP/Windows/Console.h create mode 100755 CPP/Windows/Control/ComboBox.cpp create mode 100755 CPP/Windows/Control/ComboBox.h create mode 100755 CPP/Windows/Control/Dialog.cpp create mode 100755 CPP/Windows/Control/Dialog.h create mode 100755 CPP/Windows/Control/Edit.h create mode 100755 CPP/Windows/Control/ImageList.cpp create mode 100755 CPP/Windows/Control/ImageList.h create mode 100755 CPP/Windows/Control/ListView.cpp create mode 100755 CPP/Windows/Control/ListView.h create mode 100755 CPP/Windows/Control/ProgressBar.h create mode 100755 CPP/Windows/Control/PropertyPage.cpp create mode 100755 CPP/Windows/Control/PropertyPage.h create mode 100755 CPP/Windows/Control/ReBar.h create mode 100755 CPP/Windows/Control/Static.h create mode 100755 CPP/Windows/Control/StatusBar.h create mode 100755 CPP/Windows/Control/StdAfx.h create mode 100755 CPP/Windows/Control/ToolBar.h create mode 100755 CPP/Windows/Control/Trackbar.h create mode 100755 CPP/Windows/Control/Window2.cpp create mode 100755 CPP/Windows/Control/Window2.h create mode 100755 CPP/Windows/DLL.cpp create mode 100755 CPP/Windows/DLL.h create mode 100755 CPP/Windows/Defs.h create mode 100755 CPP/Windows/Error.cpp create mode 100755 CPP/Windows/Error.h create mode 100755 CPP/Windows/FileDevice.cpp create mode 100755 CPP/Windows/FileDevice.h create mode 100755 CPP/Windows/FileDir.cpp create mode 100755 CPP/Windows/FileDir.h create mode 100755 CPP/Windows/FileFind.cpp create mode 100755 CPP/Windows/FileFind.h create mode 100755 CPP/Windows/FileIO.cpp create mode 100755 CPP/Windows/FileIO.h create mode 100755 CPP/Windows/FileMapping.cpp create mode 100755 CPP/Windows/FileMapping.h create mode 100755 CPP/Windows/FileName.cpp create mode 100755 CPP/Windows/FileName.h create mode 100755 CPP/Windows/FileSystem.cpp create mode 100755 CPP/Windows/FileSystem.h create mode 100755 CPP/Windows/Handle.h create mode 100755 CPP/Windows/Memory.cpp create mode 100755 CPP/Windows/Memory.h create mode 100755 CPP/Windows/MemoryLock.cpp create mode 100755 CPP/Windows/MemoryLock.h create mode 100755 CPP/Windows/Menu.cpp create mode 100755 CPP/Windows/Menu.h create mode 100755 CPP/Windows/NationalTime.cpp create mode 100755 CPP/Windows/NationalTime.h create mode 100755 CPP/Windows/Net.cpp create mode 100755 CPP/Windows/Net.h create mode 100755 CPP/Windows/ProcessMessages.cpp create mode 100755 CPP/Windows/ProcessMessages.h create mode 100755 CPP/Windows/PropVariant.cpp create mode 100755 CPP/Windows/PropVariant.h create mode 100755 CPP/Windows/PropVariantConversions.cpp create mode 100755 CPP/Windows/PropVariantConversions.h create mode 100755 CPP/Windows/Registry.cpp create mode 100755 CPP/Windows/Registry.h create mode 100755 CPP/Windows/ResourceString.cpp create mode 100755 CPP/Windows/ResourceString.h create mode 100755 CPP/Windows/Security.cpp create mode 100755 CPP/Windows/Security.h create mode 100755 CPP/Windows/Shell.cpp create mode 100755 CPP/Windows/Shell.h create mode 100755 CPP/Windows/StdAfx.h create mode 100755 CPP/Windows/Synchronization.cpp create mode 100755 CPP/Windows/Synchronization.h create mode 100755 CPP/Windows/System.h create mode 100755 CPP/Windows/Thread.h create mode 100755 CPP/Windows/Time.h create mode 100755 CPP/Windows/Window.cpp create mode 100755 CPP/Windows/Window.h (limited to 'CPP') diff --git a/CPP/7zip/Archive/7z/7z.dsp b/CPP/7zip/Archive/7z/7z.dsp new file mode 100755 index 00000000..e57115ef --- /dev/null +++ b/CPP/7zip/Archive/7z/7z.dsp @@ -0,0 +1,593 @@ +# Microsoft Developer Studio Project File - Name="7z" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=7z - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "7z.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "7z.mak" CFG="7z - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "7z - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "7z - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "7z - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-zip\Formats\7z.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-zip\Formats\7z.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "7z - Win32 Release" +# Name "7z - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Archive.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\7zCompressionMode.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zCompressionMode.h +# End Source File +# Begin Source File + +SOURCE=.\7zDecode.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zDecode.h +# End Source File +# Begin Source File + +SOURCE=.\7zEncode.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zEncode.h +# End Source File +# Begin Source File + +SOURCE=.\7zExtract.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zFolderInStream.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zFolderInStream.h +# End Source File +# Begin Source File + +SOURCE=.\7zFolderOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zFolderOutStream.h +# End Source File +# Begin Source File + +SOURCE=.\7zHandler.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zHandler.h +# End Source File +# Begin Source File + +SOURCE=.\7zHandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zHeader.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zHeader.h +# End Source File +# Begin Source File + +SOURCE=.\7zIn.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zIn.h +# End Source File +# Begin Source File + +SOURCE=.\7zItem.h +# End Source File +# Begin Source File + +SOURCE=.\7zMethodID.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zMethodID.h +# End Source File +# Begin Source File + +SOURCE=.\7zMethods.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zMethods.h +# End Source File +# Begin Source File + +SOURCE=.\7zOut.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zOut.h +# End Source File +# Begin Source File + +SOURCE=.\7zProperties.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zProperties.h +# End Source File +# Begin Source File + +SOURCE=.\7zSpecStream.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zSpecStream.h +# End Source File +# Begin Source File + +SOURCE=.\7zUpdate.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zUpdate.h +# End Source File +# End Group +# Begin Group "Interface" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\IArchive.h +# End Source File +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IMyUnknown.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# Begin Source File + +SOURCE=..\..\IStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\PropID.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Buffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynamicBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\CodecsPath.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\CodecsPath.h +# End Source File +# Begin Source File + +SOURCE=..\Common\CoderLoader.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\CoderLoader.h +# End Source File +# Begin Source File + +SOURCE=..\Common\CoderMixer2.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\CoderMixer2.h +# End Source File +# Begin Source File + +SOURCE=..\Common\CoderMixer2MT.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\CoderMixer2MT.h +# End Source File +# Begin Source File + +SOURCE=..\Common\CrossThreadProgress.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\CrossThreadProgress.h +# End Source File +# Begin Source File + +SOURCE=..\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\Common\InStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\InStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\MultiStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\MultiStream.h +# End Source File +# Begin Source File + +SOURCE=..\Common\OutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\OutStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ParseProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ParseProperties.h +# End Source File +# End Group +# Begin Group "7-Zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\InOutTempBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InOutTempBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Handle.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Thread.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\7z.ico +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/Archive/7z/7z.dsw b/CPP/7zip/Archive/7z/7z.dsw new file mode 100755 index 00000000..702a86c7 --- /dev/null +++ b/CPP/7zip/Archive/7z/7z.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "7z"=".\7z.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Archive/7z/7z.ico b/CPP/7zip/Archive/7z/7z.ico new file mode 100755 index 00000000..319753a1 Binary files /dev/null and b/CPP/7zip/Archive/7z/7z.ico differ diff --git a/CPP/7zip/Archive/7z/7zCompressionMode.cpp b/CPP/7zip/Archive/7z/7zCompressionMode.cpp new file mode 100755 index 00000000..6774fc48 --- /dev/null +++ b/CPP/7zip/Archive/7z/7zCompressionMode.cpp @@ -0,0 +1,3 @@ +// CompressionMethod.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Archive/7z/7zCompressionMode.h b/CPP/7zip/Archive/7z/7zCompressionMode.h new file mode 100755 index 00000000..fe54e8a6 --- /dev/null +++ b/CPP/7zip/Archive/7z/7zCompressionMode.h @@ -0,0 +1,64 @@ +// 7zCompressionMode.h + +#ifndef __7Z_COMPRESSION_MODE_H +#define __7Z_COMPRESSION_MODE_H + +#include "../../../Windows/PropVariant.h" + +#include "7zMethodID.h" + +namespace NArchive { +namespace N7z { + +struct CProperty +{ + PROPID PropID; + NWindows::NCOM::CPropVariant Value; +}; + +struct CMethodFull +{ + CMethodID MethodID; + UInt32 NumInStreams; + UInt32 NumOutStreams; + bool IsSimpleCoder() const + { return (NumInStreams == 1) && (NumOutStreams == 1); } + + #ifdef EXCLUDE_COM + #else + CLSID EncoderClassID; + CSysString FilePath; + #endif + + CObjectVector CoderProperties; +}; + +struct CBind +{ + UInt32 InCoder; + UInt32 InStream; + UInt32 OutCoder; + UInt32 OutStream; +}; + +struct CCompressionMethodMode +{ + CObjectVector Methods; + CRecordVector Binds; + #ifdef COMPRESS_MT + UInt32 NumThreads; + #endif + bool PasswordIsDefined; + UString Password; + + bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); } + CCompressionMethodMode(): PasswordIsDefined(false) + #ifdef COMPRESS_MT + , NumThreads(1) + #endif + {} +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/7z/7zDecode.cpp b/CPP/7zip/Archive/7z/7zDecode.cpp new file mode 100755 index 00000000..5c58f817 --- /dev/null +++ b/CPP/7zip/Archive/7z/7zDecode.cpp @@ -0,0 +1,444 @@ +// 7zDecode.cpp + +#include "StdAfx.h" + +#include "7zDecode.h" + +#include "../../IPassword.h" +#include "../../Common/LockedStream.h" +#include "../../Common/StreamObjects.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/LimitedStreams.h" +#include "../Common/FilterCoder.h" + +#include "7zMethods.h" + +#ifdef COMPRESS_LZMA +#include "../../Compress/LZMA/LZMADecoder.h" +static NArchive::N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 }; +#endif + +#ifdef COMPRESS_PPMD +#include "../../Compress/PPMD/PPMDDecoder.h" +static NArchive::N7z::CMethodID k_PPMD = { { 0x3, 0x4, 0x1 }, 3 }; +#endif + +#ifdef COMPRESS_BCJ_X86 +#include "../../Compress/Branch/x86.h" +static NArchive::N7z::CMethodID k_BCJ_X86 = { { 0x3, 0x3, 0x1, 0x3 }, 4 }; +#endif + +#ifdef COMPRESS_BCJ2 +#include "../../Compress/Branch/x86_2.h" +static NArchive::N7z::CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 }; +#endif + +#ifdef COMPRESS_DEFLATE +#ifndef COMPRESS_DEFLATE_DECODER +#define COMPRESS_DEFLATE_DECODER +#endif +#endif + +#ifdef COMPRESS_DEFLATE_DECODER +#include "../../Compress/Deflate/DeflateDecoder.h" +static NArchive::N7z::CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 }; +#endif + +#ifdef COMPRESS_BZIP2 +#ifndef COMPRESS_BZIP2_DECODER +#define COMPRESS_BZIP2_DECODER +#endif +#endif + +#ifdef COMPRESS_BZIP2_DECODER +#include "../../Compress/BZip2/BZip2Decoder.h" +static NArchive::N7z::CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 }; +#endif + +#ifdef COMPRESS_COPY +#include "../../Compress/Copy/CopyCoder.h" +static NArchive::N7z::CMethodID k_Copy = { { 0x0 }, 1 }; +#endif + +#ifdef CRYPTO_7ZAES +#include "../../Crypto/7zAES/7zAES.h" +static NArchive::N7z::CMethodID k_7zAES = { { 0x6, 0xF1, 0x07, 0x01 }, 4 }; +#endif + +namespace NArchive { +namespace N7z { + +static void ConvertFolderItemInfoToBindInfo(const CFolder &folder, + CBindInfoEx &bindInfo) +{ + bindInfo.Clear(); + int i; + for (i = 0; i < folder.BindPairs.Size(); i++) + { + NCoderMixer2::CBindPair bindPair; + bindPair.InIndex = (UInt32)folder.BindPairs[i].InIndex; + bindPair.OutIndex = (UInt32)folder.BindPairs[i].OutIndex; + bindInfo.BindPairs.Add(bindPair); + } + UInt32 outStreamIndex = 0; + for (i = 0; i < folder.Coders.Size(); i++) + { + NCoderMixer2::CCoderStreamsInfo coderStreamsInfo; + const CCoderInfo &coderInfo = folder.Coders[i]; + coderStreamsInfo.NumInStreams = (UInt32)coderInfo.NumInStreams; + coderStreamsInfo.NumOutStreams = (UInt32)coderInfo.NumOutStreams; + bindInfo.Coders.Add(coderStreamsInfo); + const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front(); + bindInfo.CoderMethodIDs.Add(altCoderInfo.MethodID); + for (UInt32 j = 0; j < coderStreamsInfo.NumOutStreams; j++, outStreamIndex++) + if (folder.FindBindPairForOutStream(outStreamIndex) < 0) + bindInfo.OutStreams.Add(outStreamIndex); + } + for (i = 0; i < folder.PackStreams.Size(); i++) + bindInfo.InStreams.Add((UInt32)folder.PackStreams[i]); +} + +static bool AreCodersEqual(const NCoderMixer2::CCoderStreamsInfo &a1, + const NCoderMixer2::CCoderStreamsInfo &a2) +{ + return (a1.NumInStreams == a2.NumInStreams) && + (a1.NumOutStreams == a2.NumOutStreams); +} + +static bool AreBindPairsEqual(const NCoderMixer2::CBindPair &a1, const NCoderMixer2::CBindPair &a2) +{ + return (a1.InIndex == a2.InIndex) && + (a1.OutIndex == a2.OutIndex); +} + +static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2) +{ + if (a1.Coders.Size() != a2.Coders.Size()) + return false; + int i; + for (i = 0; i < a1.Coders.Size(); i++) + if (!AreCodersEqual(a1.Coders[i], a2.Coders[i])) + return false; + if (a1.BindPairs.Size() != a2.BindPairs.Size()) + return false; + for (i = 0; i < a1.BindPairs.Size(); i++) + if (!AreBindPairsEqual(a1.BindPairs[i], a2.BindPairs[i])) + return false; + for (i = 0; i < a1.CoderMethodIDs.Size(); i++) + if (a1.CoderMethodIDs[i] != a2.CoderMethodIDs[i]) + return false; + if (a1.InStreams.Size() != a2.InStreams.Size()) + return false; + if (a1.OutStreams.Size() != a2.OutStreams.Size()) + return false; + return true; +} + +CDecoder::CDecoder(bool multiThread) +{ + #ifndef _ST_MODE + multiThread = true; + #endif + _multiThread = multiThread; + _bindInfoExPrevIsDefined = false; + #ifndef EXCLUDE_COM + LoadMethodMap(); + #endif +} + +HRESULT CDecoder::Decode(IInStream *inStream, + UInt64 startPos, + const UInt64 *packSizes, + const CFolder &folderInfo, + ISequentialOutStream *outStream, + ICompressProgressInfo *compressProgress + #ifndef _NO_CRYPTO + , ICryptoGetTextPassword *getTextPassword + #endif + #ifdef COMPRESS_MT + , bool mtMode, UInt32 numThreads + #endif + ) +{ + CObjectVector< CMyComPtr > inStreams; + + CLockedInStream lockedInStream; + lockedInStream.Init(inStream); + + for (int j = 0; j < folderInfo.PackStreams.Size(); j++) + { + CLockedSequentialInStreamImp *lockedStreamImpSpec = new + CLockedSequentialInStreamImp; + CMyComPtr lockedStreamImp = lockedStreamImpSpec; + lockedStreamImpSpec->Init(&lockedInStream, startPos); + startPos += packSizes[j]; + + CLimitedSequentialInStream *streamSpec = new + CLimitedSequentialInStream; + CMyComPtr inStream = streamSpec; + streamSpec->SetStream(lockedStreamImp); + streamSpec->Init(packSizes[j]); + inStreams.Add(inStream); + } + + int numCoders = folderInfo.Coders.Size(); + + CBindInfoEx bindInfo; + ConvertFolderItemInfoToBindInfo(folderInfo, bindInfo); + bool createNewCoders; + if (!_bindInfoExPrevIsDefined) + createNewCoders = true; + else + createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev); + if (createNewCoders) + { + int i; + _decoders.Clear(); + // _decoders2.Clear(); + + _mixerCoder.Release(); + + if (_multiThread) + { + _mixerCoderMTSpec = new NCoderMixer2::CCoderMixer2MT; + _mixerCoder = _mixerCoderMTSpec; + _mixerCoderCommon = _mixerCoderMTSpec; + } + else + { + #ifdef _ST_MODE + _mixerCoderSTSpec = new NCoderMixer2::CCoderMixer2ST; + _mixerCoder = _mixerCoderSTSpec; + _mixerCoderCommon = _mixerCoderSTSpec; + #endif + } + _mixerCoderCommon->SetBindInfo(bindInfo); + + for (i = 0; i < numCoders; i++) + { + const CCoderInfo &coderInfo = folderInfo.Coders[i]; + const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front(); + #ifndef EXCLUDE_COM + CMethodInfo methodInfo; + if (!GetMethodInfo(altCoderInfo.MethodID, methodInfo)) + return E_NOTIMPL; + #endif + + if (coderInfo.IsSimpleCoder()) + { + CMyComPtr decoder; + CMyComPtr filter; + + #ifdef COMPRESS_LZMA + if (altCoderInfo.MethodID == k_LZMA) + decoder = new NCompress::NLZMA::CDecoder; + #endif + + #ifdef COMPRESS_PPMD + if (altCoderInfo.MethodID == k_PPMD) + decoder = new NCompress::NPPMD::CDecoder; + #endif + + #ifdef COMPRESS_BCJ_X86 + if (altCoderInfo.MethodID == k_BCJ_X86) + filter = new CBCJ_x86_Decoder; + #endif + + #ifdef COMPRESS_DEFLATE_DECODER + if (altCoderInfo.MethodID == k_Deflate) + decoder = new NCompress::NDeflate::NDecoder::CCOMCoder; + #endif + + #ifdef COMPRESS_BZIP2_DECODER + if (altCoderInfo.MethodID == k_BZip2) + decoder = new NCompress::NBZip2::CDecoder; + #endif + + #ifdef COMPRESS_COPY + if (altCoderInfo.MethodID == k_Copy) + decoder = new NCompress::CCopyCoder; + #endif + + #ifdef CRYPTO_7ZAES + if (altCoderInfo.MethodID == k_7zAES) + filter = new NCrypto::NSevenZ::CDecoder; + #endif + + if (filter) + { + CFilterCoder *coderSpec = new CFilterCoder; + decoder = coderSpec; + coderSpec->Filter = filter; + } + #ifndef EXCLUDE_COM + if (decoder == 0) + { + RINOK(_libraries.CreateCoderSpec(methodInfo.FilePath, + methodInfo.Decoder, &decoder)); + } + #endif + + if (decoder == 0) + return E_NOTIMPL; + + _decoders.Add((IUnknown *)decoder); + + if (_multiThread) + _mixerCoderMTSpec->AddCoder(decoder); + #ifdef _ST_MODE + else + _mixerCoderSTSpec->AddCoder(decoder, false); + #endif + } + else + { + CMyComPtr decoder; + + #ifdef COMPRESS_BCJ2 + if (altCoderInfo.MethodID == k_BCJ2) + decoder = new CBCJ2_x86_Decoder; + #endif + + #ifndef EXCLUDE_COM + if (decoder == 0) + { + RINOK(_libraries.CreateCoder2(methodInfo.FilePath, + methodInfo.Decoder, &decoder)); + } + #endif + + if (decoder == 0) + return E_NOTIMPL; + + _decoders.Add((IUnknown *)decoder); + if (_multiThread) + _mixerCoderMTSpec->AddCoder2(decoder); + #ifdef _ST_MODE + else + _mixerCoderSTSpec->AddCoder2(decoder, false); + #endif + } + } + _bindInfoExPrev = bindInfo; + _bindInfoExPrevIsDefined = true; + } + int i; + _mixerCoderCommon->ReInit(); + + UInt32 packStreamIndex = 0, unPackStreamIndex = 0; + UInt32 coderIndex = 0; + // UInt32 coder2Index = 0; + + for (i = 0; i < numCoders; i++) + { + const CCoderInfo &coderInfo = folderInfo.Coders[i]; + const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front(); + CMyComPtr &decoder = _decoders[coderIndex]; + + { + CMyComPtr setDecoderProperties; + decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties); + if (setDecoderProperties) + { + const CByteBuffer &properties = altCoderInfo.Properties; + size_t size = properties.GetCapacity(); + if (size > 0xFFFFFFFF) + return E_NOTIMPL; + if (size > 0) + { + RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)properties, (UInt32)size)); + } + } + } + + #ifdef COMPRESS_MT + if (mtMode) + { + CMyComPtr setCoderMt; + decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt); + if (setCoderMt) + { + RINOK(setCoderMt->SetNumberOfThreads(numThreads)); + } + } + #endif + + #ifndef _NO_CRYPTO + { + CMyComPtr cryptoSetPassword; + decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword); + if (cryptoSetPassword) + { + if (getTextPassword == 0) + return E_FAIL; + CMyComBSTR password; + RINOK(getTextPassword->CryptoGetTextPassword(&password)); + CByteBuffer buffer; + UString unicodePassword(password); + const UInt32 sizeInBytes = unicodePassword.Length() * 2; + buffer.SetCapacity(sizeInBytes); + for (int i = 0; i < unicodePassword.Length(); i++) + { + wchar_t c = unicodePassword[i]; + ((Byte *)buffer)[i * 2] = (Byte)c; + ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); + } + RINOK(cryptoSetPassword->CryptoSetPassword( + (const Byte *)buffer, sizeInBytes)); + } + } + #endif + + coderIndex++; + + UInt32 numInStreams = (UInt32)coderInfo.NumInStreams; + UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams; + CRecordVector packSizesPointers; + CRecordVector unPackSizesPointers; + packSizesPointers.Reserve(numInStreams); + unPackSizesPointers.Reserve(numOutStreams); + UInt32 j; + for (j = 0; j < numOutStreams; j++, unPackStreamIndex++) + unPackSizesPointers.Add(&folderInfo.UnPackSizes[unPackStreamIndex]); + + for (j = 0; j < numInStreams; j++, packStreamIndex++) + { + int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex); + if (bindPairIndex >= 0) + packSizesPointers.Add( + &folderInfo.UnPackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]); + else + { + int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex); + if (index < 0) + return E_FAIL; + packSizesPointers.Add(&packSizes[index]); + } + } + + _mixerCoderCommon->SetCoderInfo(i, + &packSizesPointers.Front(), + &unPackSizesPointers.Front()); + } + UInt32 mainCoder, temp; + bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp); + + if (_multiThread) + _mixerCoderMTSpec->SetProgressCoderIndex(mainCoder); + /* + else + _mixerCoderSTSpec->SetProgressCoderIndex(mainCoder);; + */ + + if (numCoders == 0) + return 0; + CRecordVector inStreamPointers; + inStreamPointers.Reserve(inStreams.Size()); + for (i = 0; i < inStreams.Size(); i++) + inStreamPointers.Add(inStreams[i]); + ISequentialOutStream *outStreamPointer = outStream; + return _mixerCoder->Code(&inStreamPointers.Front(), NULL, + inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress); +} + +}} diff --git a/CPP/7zip/Archive/7z/7zDecode.h b/CPP/7zip/Archive/7z/7zDecode.h new file mode 100755 index 00000000..50f80d4c --- /dev/null +++ b/CPP/7zip/Archive/7z/7zDecode.h @@ -0,0 +1,71 @@ +// 7zDecode.h + +#ifndef __7Z_DECODE_H +#define __7Z_DECODE_H + +#include "../../IStream.h" +#include "../../IPassword.h" + +#include "../Common/CoderMixer2.h" +#include "../Common/CoderMixer2MT.h" +#ifdef _ST_MODE +#include "../Common/CoderMixer2ST.h" +#endif +#ifndef EXCLUDE_COM +#include "../Common/CoderLoader.h" +#endif + +#include "7zItem.h" + +namespace NArchive { +namespace N7z { + +struct CBindInfoEx: public NCoderMixer2::CBindInfo +{ + CRecordVector CoderMethodIDs; + void Clear() + { + CBindInfo::Clear(); + CoderMethodIDs.Clear(); + } +}; + +class CDecoder +{ + #ifndef EXCLUDE_COM + CCoderLibraries _libraries; + #endif + + bool _bindInfoExPrevIsDefined; + CBindInfoEx _bindInfoExPrev; + + bool _multiThread; + #ifdef _ST_MODE + NCoderMixer2::CCoderMixer2ST *_mixerCoderSTSpec; + #endif + NCoderMixer2::CCoderMixer2MT *_mixerCoderMTSpec; + NCoderMixer2::CCoderMixer2 *_mixerCoderCommon; + + CMyComPtr _mixerCoder; + CObjectVector > _decoders; + // CObjectVector > _decoders2; +public: + CDecoder(bool multiThread); + HRESULT Decode(IInStream *inStream, + UInt64 startPos, + const UInt64 *packSizes, + const CFolder &folder, + ISequentialOutStream *outStream, + ICompressProgressInfo *compressProgress + #ifndef _NO_CRYPTO + , ICryptoGetTextPassword *getTextPasswordSpec + #endif + #ifdef COMPRESS_MT + , bool mtMode, UInt32 numThreads + #endif + ); +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/7z/7zEncode.cpp b/CPP/7zip/Archive/7z/7zEncode.cpp new file mode 100755 index 00000000..a9fe2d0a --- /dev/null +++ b/CPP/7zip/Archive/7z/7zEncode.cpp @@ -0,0 +1,614 @@ +// Encode.cpp + +#include "StdAfx.h" + +#include "7zEncode.h" +#include "7zSpecStream.h" +#include "7zMethods.h" + +#include "../../IPassword.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/LimitedStreams.h" +#include "../../Common/InOutTempBuffer.h" +#include "../../Common/StreamObjects.h" +#include "../Common/FilterCoder.h" + +#ifdef COMPRESS_COPY +static NArchive::N7z::CMethodID k_Copy = { { 0x0 }, 1 }; +#include "../../Compress/Copy/CopyCoder.h" +#endif + +static NArchive::N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 }; +static NArchive::N7z::CMethodID k_LZMA2 = { { 0x3, 0x1, 0x2 }, 3 }; + +#ifdef COMPRESS_LZMA +#include "../../Compress/LZMA/LZMAEncoder.h" +#endif + +#ifdef COMPRESS_PPMD +#include "../../Compress/PPMD/PPMDEncoder.h" +static NArchive::N7z::CMethodID k_PPMD = { { 0x3, 0x4, 0x1 }, 3 }; +#endif + +#ifdef COMPRESS_BCJ_X86 +static NArchive::N7z::CMethodID k_BCJ_X86 = { { 0x3, 0x3, 0x1, 0x3 }, 4 }; +#include "../../Compress/Branch/x86.h" +#endif + +#ifdef COMPRESS_BCJ2 +static NArchive::N7z::CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 }; +#include "../../Compress/Branch/x86_2.h" +#endif + +#ifdef COMPRESS_DEFLATE +#ifndef COMPRESS_DEFLATE_ENCODER +#define COMPRESS_DEFLATE_ENCODER +#endif +#endif + +#ifdef COMPRESS_DEFLATE_ENCODER +#include "../../Compress/Deflate/DeflateEncoder.h" +static NArchive::N7z::CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 }; +#endif + +#ifdef COMPRESS_BZIP2 +#ifndef COMPRESS_BZIP2_ENCODER +#define COMPRESS_BZIP2_ENCODER +#endif +#endif + +#ifdef COMPRESS_BZIP2_ENCODER +#include "../../Compress/BZip2/BZip2Encoder.h" +static NArchive::N7z::CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 }; +#endif + +static NArchive::N7z::CMethodID k_AES = { { 0x6, 0xF1, 0x7, 0x1}, 4 }; + +#ifndef EXCLUDE_COM +static const wchar_t *kCryproMethod = L"7zAES"; +/* +// {23170F69-40C1-278B-06F1-070100000100} +DEFINE_GUID(CLSID_CCrypto7zAESEncoder, +0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x07, 0x01, 0x00, 0x00, 0x01, 0x00); +*/ +#endif + +#ifdef CRYPTO_7ZAES +#include "../../Crypto/7zAES/7zAES.h" +#endif + +namespace NArchive { +namespace N7z { + +static void ConvertBindInfoToFolderItemInfo(const NCoderMixer2::CBindInfo &bindInfo, + const CRecordVector decompressionMethods, + CFolder &folder) +{ + folder.Coders.Clear(); + // bindInfo.CoderMethodIDs.Clear(); + // folder.OutStreams.Clear(); + folder.PackStreams.Clear(); + folder.BindPairs.Clear(); + int i; + for (i = 0; i < bindInfo.BindPairs.Size(); i++) + { + CBindPair bindPair; + bindPair.InIndex = bindInfo.BindPairs[i].InIndex; + bindPair.OutIndex = bindInfo.BindPairs[i].OutIndex; + folder.BindPairs.Add(bindPair); + } + for (i = 0; i < bindInfo.Coders.Size(); i++) + { + CCoderInfo coderInfo; + const NCoderMixer2::CCoderStreamsInfo &coderStreamsInfo = bindInfo.Coders[i]; + coderInfo.NumInStreams = coderStreamsInfo.NumInStreams; + coderInfo.NumOutStreams = coderStreamsInfo.NumOutStreams; + + // coderInfo.MethodID = decompressionMethods[i]; + // if (coderInfo.AltCoders.Size() == 0) + coderInfo.AltCoders.Add(CAltCoderInfo()); + CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front(); + altCoderInfo.MethodID = decompressionMethods[i]; + + folder.Coders.Add(coderInfo); + } + for (i = 0; i < bindInfo.InStreams.Size(); i++) + folder.PackStreams.Add(bindInfo.InStreams[i]); +} + +HRESULT CEncoder::CreateMixerCoder(const UInt64 *inSizeForReduce) +{ + _mixerCoderSpec = new NCoderMixer2::CCoderMixer2MT; + _mixerCoder = _mixerCoderSpec; + _mixerCoderSpec->SetBindInfo(_bindInfo); + for (int i = 0; i < _options.Methods.Size(); i++) + { + const CMethodFull &methodFull = _options.Methods[i]; + _codersInfo.Add(CCoderInfo()); + CCoderInfo &encodingInfo = _codersInfo.Back(); + CMyComPtr encoder; + CMyComPtr filter; + CMyComPtr encoder2; + + if (methodFull.IsSimpleCoder()) + { + #ifdef COMPRESS_LZMA + if (methodFull.MethodID == k_LZMA) + encoder = new NCompress::NLZMA::CEncoder; + #endif + + #ifdef COMPRESS_PPMD + if (methodFull.MethodID == k_PPMD) + encoder = new NCompress::NPPMD::CEncoder; + #endif + + #ifdef COMPRESS_BCJ_X86 + if (methodFull.MethodID == k_BCJ_X86) + filter = new CBCJ_x86_Encoder; + #endif + + #ifdef COMPRESS_COPY + if (methodFull.MethodID == k_Copy) + encoder = new NCompress::CCopyCoder; + #endif + + #ifdef COMPRESS_BZIP2_ENCODER + if (methodFull.MethodID == k_BZip2) + encoder = new NCompress::NBZip2::CEncoder; + #endif + + #ifdef COMPRESS_DEFLATE_ENCODER + if (methodFull.MethodID == k_Deflate) + encoder = new NCompress::NDeflate::NEncoder::CCOMCoder; + #endif + + #ifdef CRYPTO_7ZAES + if (methodFull.MethodID == k_AES) + filter = new NCrypto::NSevenZ::CEncoder; + #endif + + if (filter) + { + CFilterCoder *coderSpec = new CFilterCoder; + encoder = coderSpec; + coderSpec->Filter = filter; + } + + #ifndef EXCLUDE_COM + if (encoder == 0) + { + RINOK(_libraries.CreateCoderSpec(methodFull.FilePath, + methodFull.EncoderClassID, &encoder)); + } + #endif + + if (encoder == 0) + return E_FAIL; + + } + else + { + #ifdef COMPRESS_BCJ2 + if (methodFull.MethodID == k_BCJ2) + encoder2 = new CBCJ2_x86_Encoder; + #endif + + #ifndef EXCLUDE_COM + if (encoder2 == 0) + { + RINOK(_libraries.CreateCoder2(methodFull.FilePath, + methodFull.EncoderClassID, &encoder2)); + } + #else + + if (encoder2 == 0) + return E_FAIL; + #endif + } + + bool tryReduce = false; + UInt32 reducedDictionarySize = 1 << 10; + if (inSizeForReduce != 0 && (methodFull.MethodID == k_LZMA || methodFull.MethodID == k_LZMA2)) + { + for (;;) + { + const UInt32 step = (reducedDictionarySize >> 1); + if (reducedDictionarySize >= *inSizeForReduce) + { + tryReduce = true; + break; + } + reducedDictionarySize += step; + if (reducedDictionarySize >= *inSizeForReduce) + { + tryReduce = true; + break; + } + if (reducedDictionarySize >= ((UInt32)11 << 30)) + break; + reducedDictionarySize += step; + } + } + + CMyComPtr encoderCommon = methodFull.IsSimpleCoder() ? (IUnknown *)encoder : (IUnknown *)encoder2; + + #ifdef COMPRESS_MT + { + CMyComPtr setCoderMt; + encoderCommon.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt); + if (setCoderMt) + { + RINOK(setCoderMt->SetNumberOfThreads(_options.NumThreads)); + } + } + #endif + + if (methodFull.CoderProperties.Size() > 0) + { + CRecordVector propIDs; + int numProperties = methodFull.CoderProperties.Size(); + NWindows::NCOM::CPropVariant *values = new NWindows::NCOM::CPropVariant[numProperties]; + try + { + for (int i = 0; i < numProperties; i++) + { + const CProperty &property = methodFull.CoderProperties[i]; + propIDs.Add(property.PropID); + NWindows::NCOM::CPropVariant value = property.Value; + if (tryReduce && property.PropID == NCoderPropID::kDictionarySize && value.vt == VT_UI4 && reducedDictionarySize < value.ulVal) + value.ulVal = reducedDictionarySize; + values[i] = value; + } + CMyComPtr setCoderProperties; + RINOK(encoderCommon.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties)); + RINOK(setCoderProperties->SetCoderProperties(&propIDs.Front(), values, numProperties)); + } + catch(...) + { + delete []values; + throw; + } + delete []values; + } + + CMyComPtr writeCoderProperties; + + encoderCommon.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProperties); + + if (writeCoderProperties != NULL) + { + CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp; + CMyComPtr outStream(outStreamSpec); + outStreamSpec->Init(); + writeCoderProperties->WriteCoderProperties(outStream); + + size_t size = outStreamSpec->GetSize(); + + // encodingInfo.Properties.SetCapacity(size); + if (encodingInfo.AltCoders.Size() == 0) + encodingInfo.AltCoders.Add(CAltCoderInfo()); + CAltCoderInfo &altCoderInfo = encodingInfo.AltCoders.Front(); + altCoderInfo.Properties.SetCapacity(size); + + memmove(altCoderInfo.Properties, outStreamSpec->GetBuffer(), size); + } + + CMyComPtr cryptoSetPassword; + encoderCommon.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword); + + if (cryptoSetPassword) + { + CByteBuffer buffer; + const UInt32 sizeInBytes = _options.Password.Length() * 2; + buffer.SetCapacity(sizeInBytes); + for (int i = 0; i < _options.Password.Length(); i++) + { + wchar_t c = _options.Password[i]; + ((Byte *)buffer)[i * 2] = (Byte)c; + ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); + } + RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes)); + } + + if (methodFull.IsSimpleCoder()) + _mixerCoderSpec->AddCoder(encoder); + else + _mixerCoderSpec->AddCoder2(encoder2); + } + return S_OK; +} + +HRESULT CEncoder::Encode(ISequentialInStream *inStream, + const UInt64 *inStreamSize, const UInt64 *inSizeForReduce, + CFolder &folderItem, + ISequentialOutStream *outStream, + CRecordVector &packSizes, + ICompressProgressInfo *compressProgress) +{ + if (_mixerCoderSpec == NULL) + { + RINOK(CreateMixerCoder(inSizeForReduce)); + } + _mixerCoderSpec->ReInit(); + // _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress); + + CObjectVector inOutTempBuffers; + CObjectVector tempBufferSpecs; + CObjectVector > 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 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 sizePointers; + for (UInt32 i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++) + if (i == mainStreamIndex) + sizePointers.Add(inStreamSize); + else + sizePointers.Add(NULL); + _mixerCoderSpec->SetCoderInfo(mainCoderIndex, &sizePointers.Front(), NULL); + } + + + // UInt64 outStreamStartPos; + // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos)); + + CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = + new CSequentialInStreamSizeCount2; + CMyComPtr inStreamSizeCount = inStreamSizeCountSpec; + CSequentialOutStreamSizeCount *outStreamSizeCountSpec = + new CSequentialOutStreamSizeCount; + CMyComPtr outStreamSizeCount = outStreamSizeCountSpec; + + inStreamSizeCountSpec->Init(inStream); + outStreamSizeCountSpec->SetStream(outStream); + outStreamSizeCountSpec->Init(); + + CRecordVector inStreamPointers; + CRecordVector outStreamPointers; + inStreamPointers.Add(inStreamSizeCount); + outStreamPointers.Add(outStreamSizeCount); + for (i = 1; i < _bindInfo.OutStreams.Size(); i++) + outStreamPointers.Add(tempBuffers[i - 1]); + + RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1, + &outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress)); + + ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods, + folderItem); + + packSizes.Add(outStreamSizeCountSpec->GetSize()); + + for (i = 1; i < _bindInfo.OutStreams.Size(); i++) + { + CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1]; + inOutTempBuffer.FlushWrite(); + inOutTempBuffer.InitReading(); + inOutTempBuffer.WriteToStream(outStream); + packSizes.Add(inOutTempBuffer.GetDataSize()); + } + + for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++) + { + int binder = _bindInfo.FindBinderForInStream( + _bindReverseConverter->DestOutToSrcInMap[i]); + UInt64 streamSize; + if (binder < 0) + streamSize = inStreamSizeCountSpec->GetSize(); + else + streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder); + folderItem.UnPackSizes.Add(streamSize); + } + for (i = numMethods - 1; i >= 0; i--) + { + // folderItem.Coders[numMethods - 1 - i].Properties = _codersInfo[i].Properties; + for (int j = 0; j < _codersInfo[i].AltCoders.Size(); j++) + folderItem.Coders[numMethods - 1 - i].AltCoders[j].Properties + = _codersInfo[i].AltCoders[j].Properties; + } + return S_OK; +} + + +CEncoder::CEncoder(const CCompressionMethodMode &options): + _bindReverseConverter(0) +{ + if (options.IsEmpty()) + throw 1; + + _options = options; + _mixerCoderSpec = NULL; + + if (options.Methods.IsEmpty()) + { + // it has only password method; + if (!options.PasswordIsDefined) + throw 1; + if (!options.Binds.IsEmpty()) + throw 1; + NCoderMixer2::CCoderStreamsInfo coderStreamsInfo; + CMethodFull method; + + method.NumInStreams = 1; + method.NumOutStreams = 1; + coderStreamsInfo.NumInStreams = method.NumOutStreams; + coderStreamsInfo.NumOutStreams = method.NumInStreams; + method.MethodID = k_AES; + + + #ifndef EXCLUDE_COM + CMethodInfo2 methodInfo; + if (!GetMethodInfo(kCryproMethod, methodInfo)) + throw 2; + method.FilePath = methodInfo.FilePath; + method.EncoderClassID = methodInfo.Encoder; + // method.EncoderClassID = CLSID_CCrypto7zAESEncoder; + #endif + + _options.Methods.Add(method); + _bindInfo.Coders.Add(coderStreamsInfo); + + _bindInfo.InStreams.Add(0); + _bindInfo.OutStreams.Add(0); + } + else + { + + UInt32 numInStreams = 0, numOutStreams = 0; + int i; + for (i = 0; i < options.Methods.Size(); i++) + { + const CMethodFull &methodFull = options.Methods[i]; + NCoderMixer2::CCoderStreamsInfo coderStreamsInfo; + coderStreamsInfo.NumInStreams = methodFull.NumOutStreams; + coderStreamsInfo.NumOutStreams = methodFull.NumInStreams; + if (options.Binds.IsEmpty()) + { + if (i < options.Methods.Size() - 1) + { + NCoderMixer2::CBindPair bindPair; + bindPair.InIndex = numInStreams + coderStreamsInfo.NumInStreams; + bindPair.OutIndex = numOutStreams; + _bindInfo.BindPairs.Add(bindPair); + } + else + _bindInfo.OutStreams.Insert(0, numOutStreams); + for (UInt32 j = 1; j < coderStreamsInfo.NumOutStreams; j++) + _bindInfo.OutStreams.Add(numOutStreams + j); + } + + numInStreams += coderStreamsInfo.NumInStreams; + numOutStreams += coderStreamsInfo.NumOutStreams; + + _bindInfo.Coders.Add(coderStreamsInfo); + } + + if (!options.Binds.IsEmpty()) + { + for (i = 0; i < options.Binds.Size(); i++) + { + NCoderMixer2::CBindPair bindPair; + const CBind &bind = options.Binds[i]; + bindPair.InIndex = _bindInfo.GetCoderInStreamIndex(bind.InCoder) + bind.InStream; + bindPair.OutIndex = _bindInfo.GetCoderOutStreamIndex(bind.OutCoder) + bind.OutStream; + _bindInfo.BindPairs.Add(bindPair); + } + for (i = 0; i < (int)numOutStreams; i++) + if (_bindInfo.FindBinderForOutStream(i) == -1) + _bindInfo.OutStreams.Add(i); + } + + for (i = 0; i < (int)numInStreams; i++) + if (_bindInfo.FindBinderForInStream(i) == -1) + _bindInfo.InStreams.Add(i); + + if (_bindInfo.InStreams.IsEmpty()) + throw 1; // this is error + + // Make main stream first in list + int inIndex = _bindInfo.InStreams[0]; + for (;;) + { + UInt32 coderIndex, coderStreamIndex; + _bindInfo.FindInStream(inIndex, coderIndex, coderStreamIndex); + UInt32 outIndex = _bindInfo.GetCoderOutStreamIndex(coderIndex); + int binder = _bindInfo.FindBinderForOutStream(outIndex); + if (binder >= 0) + { + inIndex = _bindInfo.BindPairs[binder].InIndex; + continue; + } + for (i = 0; i < _bindInfo.OutStreams.Size(); i++) + if (_bindInfo.OutStreams[i] == outIndex) + { + _bindInfo.OutStreams.Delete(i); + _bindInfo.OutStreams.Insert(0, outIndex); + break; + } + break; + } + + if (_options.PasswordIsDefined) + { + int numCryptoStreams = _bindInfo.OutStreams.Size(); + + for (i = 0; i < numCryptoStreams; i++) + { + NCoderMixer2::CBindPair bindPair; + bindPair.InIndex = numInStreams + i; + bindPair.OutIndex = _bindInfo.OutStreams[i]; + _bindInfo.BindPairs.Add(bindPair); + } + _bindInfo.OutStreams.Clear(); + + /* + if (numCryptoStreams == 0) + numCryptoStreams = 1; + */ + + for (i = 0; i < numCryptoStreams; i++) + { + NCoderMixer2::CCoderStreamsInfo coderStreamsInfo; + CMethodFull method; + method.NumInStreams = 1; + method.NumOutStreams = 1; + coderStreamsInfo.NumInStreams = method.NumOutStreams; + coderStreamsInfo.NumOutStreams = method.NumInStreams; + method.MethodID = k_AES; + + #ifndef EXCLUDE_COM + CMethodInfo2 methodInfo; + if (!GetMethodInfo(kCryproMethod, methodInfo)) + throw 2; + method.FilePath = methodInfo.FilePath; + method.EncoderClassID = methodInfo.Encoder; + // method.EncoderClassID = CLSID_CCrypto7zAESEncoder; + #endif + + _options.Methods.Add(method); + _bindInfo.Coders.Add(coderStreamsInfo); + _bindInfo.OutStreams.Add(numOutStreams + i); + } + } + + } + + for (int i = _options.Methods.Size() - 1; i >= 0; i--) + { + const CMethodFull &methodFull = _options.Methods[i]; + _decompressionMethods.Add(methodFull.MethodID); + } + + _bindReverseConverter = new NCoderMixer2::CBindReverseConverter(_bindInfo); + _bindReverseConverter->CreateReverseBindInfo(_decompressBindInfo); +} + +CEncoder::~CEncoder() +{ + delete _bindReverseConverter; +} + +}} diff --git a/CPP/7zip/Archive/7z/7zEncode.h b/CPP/7zip/Archive/7z/7zEncode.h new file mode 100755 index 00000000..efd8bba6 --- /dev/null +++ b/CPP/7zip/Archive/7z/7zEncode.h @@ -0,0 +1,58 @@ +// 7zEncode.h + +#ifndef __7Z_ENCODE_H +#define __7Z_ENCODE_H + +// #include "../../Common/StreamObjects.h" + +#include "7zCompressionMode.h" + +#include "../Common/CoderMixer2.h" +#include "../Common/CoderMixer2MT.h" +#ifdef _ST_MODE +#include "../Common/CoderMixer2ST.h" +#endif +#ifndef EXCLUDE_COM +#include "../Common/CoderLoader.h" +#endif +#include "7zMethods.h" +#include "7zItem.h" + +namespace NArchive { +namespace N7z { + +class CEncoder +{ + #ifndef EXCLUDE_COM + // CMethodMap _methodMap; + // it must be in top of objects + CCoderLibraries _libraries; + #endif + + NCoderMixer2::CCoderMixer2MT *_mixerCoderSpec; + CMyComPtr _mixerCoder; + + CObjectVector _codersInfo; + + CCompressionMethodMode _options; + NCoderMixer2::CBindInfo _bindInfo; + NCoderMixer2::CBindInfo _decompressBindInfo; + NCoderMixer2::CBindReverseConverter *_bindReverseConverter; + CRecordVector _decompressionMethods; + + HRESULT CreateMixerCoder(const UInt64 *inSizeForReduce); + +public: + CEncoder(const CCompressionMethodMode &options); + ~CEncoder(); + HRESULT Encode(ISequentialInStream *inStream, + const UInt64 *inStreamSize, const UInt64 *inSizeForReduce, + CFolder &folderItem, + ISequentialOutStream *outStream, + CRecordVector &packSizes, + ICompressProgressInfo *compressProgress); +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/7z/7zExtract.cpp b/CPP/7zip/Archive/7z/7zExtract.cpp new file mode 100755 index 00000000..540241f7 --- /dev/null +++ b/CPP/7zip/Archive/7z/7zExtract.cpp @@ -0,0 +1,265 @@ +// 7zExtract.cpp + +#include "StdAfx.h" + +#include "7zHandler.h" +#include "7zFolderOutStream.h" +#include "7zMethods.h" +#include "7zDecode.h" +// #include "7z1Decode.h" + +#include "../../../Common/ComTry.h" +#include "../../Common/StreamObjects.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/LimitedStreams.h" + +namespace NArchive { +namespace N7z { + +struct CExtractFolderInfo +{ + #ifdef _7Z_VOL + int VolumeIndex; + #endif + CNum FileIndex; + CNum FolderIndex; + CBoolVector ExtractStatuses; + UInt64 UnPackSize; + CExtractFolderInfo( + #ifdef _7Z_VOL + int volumeIndex, + #endif + CNum fileIndex, CNum folderIndex): + #ifdef _7Z_VOL + VolumeIndex(volumeIndex), + #endif + FileIndex(fileIndex), + FolderIndex(folderIndex), + UnPackSize(0) + { + if (fileIndex != kNumNoIndex) + { + ExtractStatuses.Reserve(1); + ExtractStatuses.Add(true); + } + }; +}; + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec) +{ + COM_TRY_BEGIN + bool testMode = (testModeSpec != 0); + CMyComPtr extractCallback = extractCallbackSpec; + UInt64 importantTotalUnPacked = 0; + + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = + #ifdef _7Z_VOL + _refs.Size(); + #else + _database.Files.Size(); + #endif + + if(numItems == 0) + return S_OK; + + /* + if(_volumes.Size() != 1) + return E_FAIL; + const CVolume &volume = _volumes.Front(); + const CArchiveDatabaseEx &_database = volume.Database; + IInStream *_inStream = volume.Stream; + */ + + CObjectVector extractFolderInfoVector; + for(UInt32 ii = 0; ii < numItems; ii++) + { + // UInt32 fileIndex = allFilesMode ? indexIndex : indices[indexIndex]; + UInt32 ref2Index = allFilesMode ? ii : indices[ii]; + // const CRef2 &ref2 = _refs[ref2Index]; + + // for(UInt32 ri = 0; ri < ref2.Refs.Size(); ri++) + { + #ifdef _7Z_VOL + // const CRef &ref = ref2.Refs[ri]; + const CRef &ref = _refs[ref2Index]; + + int volumeIndex = ref.VolumeIndex; + const CVolume &volume = _volumes[volumeIndex]; + const CArchiveDatabaseEx &database = volume.Database; + UInt32 fileIndex = ref.ItemIndex; + #else + const CArchiveDatabaseEx &database = _database; + UInt32 fileIndex = ref2Index; + #endif + + CNum folderIndex = database.FileIndexToFolderIndexMap[fileIndex]; + if (folderIndex == kNumNoIndex) + { + extractFolderInfoVector.Add(CExtractFolderInfo( + #ifdef _7Z_VOL + volumeIndex, + #endif + fileIndex, kNumNoIndex)); + continue; + } + if (extractFolderInfoVector.IsEmpty() || + folderIndex != extractFolderInfoVector.Back().FolderIndex + #ifdef _7Z_VOL + || volumeIndex != extractFolderInfoVector.Back().VolumeIndex + #endif + ) + { + extractFolderInfoVector.Add(CExtractFolderInfo( + #ifdef _7Z_VOL + volumeIndex, + #endif + kNumNoIndex, folderIndex)); + const CFolder &folderInfo = database.Folders[folderIndex]; + UInt64 unPackSize = folderInfo.GetUnPackSize(); + importantTotalUnPacked += unPackSize; + extractFolderInfoVector.Back().UnPackSize = unPackSize; + } + + CExtractFolderInfo &efi = extractFolderInfoVector.Back(); + + // const CFolderInfo &folderInfo = m_dam_Folders[folderIndex]; + CNum startIndex = database.FolderStartFileIndex[folderIndex]; + for (CNum index = efi.ExtractStatuses.Size(); + index <= fileIndex - startIndex; index++) + { + // UInt64 unPackSize = _database.Files[startIndex + index].UnPackSize; + // Count partial_folder_size + // efi.UnPackSize += unPackSize; + // importantTotalUnPacked += unPackSize; + efi.ExtractStatuses.Add(index == fileIndex - startIndex); + } + } + } + + extractCallback->SetTotal(importantTotalUnPacked); + + CDecoder decoder( + #ifdef _ST_MODE + false + #else + true + #endif + ); + // CDecoder1 decoder; + + UInt64 currentImportantTotalUnPacked = 0; + UInt64 totalFolderUnPacked; + + for(int i = 0; i < extractFolderInfoVector.Size(); i++, + currentImportantTotalUnPacked += totalFolderUnPacked) + { + const CExtractFolderInfo &efi = extractFolderInfoVector[i]; + totalFolderUnPacked = efi.UnPackSize; + + RINOK(extractCallback->SetCompleted(¤tImportantTotalUnPacked)); + + CFolderOutStream *folderOutStream = new CFolderOutStream; + CMyComPtr outStream(folderOutStream); + + #ifdef _7Z_VOL + const CVolume &volume = _volumes[efi.VolumeIndex]; + const CArchiveDatabaseEx &database = volume.Database; + #else + const CArchiveDatabaseEx &database = _database; + #endif + + CNum startIndex; + if (efi.FileIndex != kNumNoIndex) + startIndex = efi.FileIndex; + else + startIndex = database.FolderStartFileIndex[efi.FolderIndex]; + + + HRESULT result = folderOutStream->Init(&database, + #ifdef _7Z_VOL + volume.StartRef2Index, + #else + 0, + #endif + startIndex, + &efi.ExtractStatuses, extractCallback, testMode); + + RINOK(result); + + if (efi.FileIndex != kNumNoIndex) + continue; + + CNum folderIndex = efi.FolderIndex; + const CFolder &folderInfo = database.Folders[folderIndex]; + + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr progress = localProgressSpec; + localProgressSpec->Init(extractCallback, false); + + CLocalCompressProgressInfo *localCompressProgressSpec = + new CLocalCompressProgressInfo; + CMyComPtr compressProgress = localCompressProgressSpec; + localCompressProgressSpec->Init(progress, NULL, ¤tImportantTotalUnPacked); + + CNum packStreamIndex = database.FolderStartPackStreamIndex[folderIndex]; + UInt64 folderStartPackPos = database.GetFolderStreamPos(folderIndex, 0); + + #ifndef _NO_CRYPTO + CMyComPtr getTextPassword; + if (extractCallback) + extractCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); + #endif + + try + { + HRESULT result = decoder.Decode( + #ifdef _7Z_VOL + volume.Stream, + #else + _inStream, + #endif + folderStartPackPos, + &database.PackSizes[packStreamIndex], + folderInfo, + outStream, + compressProgress + #ifndef _NO_CRYPTO + , getTextPassword + #endif + #ifdef COMPRESS_MT + , true, _numThreads + #endif + ); + + if (result == S_FALSE) + { + RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError)); + continue; + } + if (result == E_NOTIMPL) + { + RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + continue; + } + if (result != S_OK) + return result; + if (folderOutStream->WasWritingFinished() != S_OK) + { + RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError)); + continue; + } + } + catch(...) + { + RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError)); + continue; + } + } + return S_OK; + COM_TRY_END +} + +}} diff --git a/CPP/7zip/Archive/7z/7zFolderInStream.cpp b/CPP/7zip/Archive/7z/7zFolderInStream.cpp new file mode 100755 index 00000000..fb1cfd3a --- /dev/null +++ b/CPP/7zip/Archive/7z/7zFolderInStream.cpp @@ -0,0 +1,129 @@ +// 7zFolderInStream.cpp + +#include "StdAfx.h" + +#include "7zFolderInStream.h" + +namespace NArchive { +namespace N7z { + +CFolderInStream::CFolderInStream() +{ + _inStreamWithHashSpec = new CSequentialInStreamWithCRC; + _inStreamWithHash = _inStreamWithHashSpec; +} + +void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback, + const UInt32 *fileIndices, UInt32 numFiles) +{ + _updateCallback = updateCallback; + _numFiles = numFiles; + _fileIndex = 0; + _fileIndices = fileIndices; + Processed.Clear(); + CRCs.Clear(); + Sizes.Clear(); + _fileIsOpen = false; + _currentSizeIsDefined = false; +} + +HRESULT CFolderInStream::OpenStream() +{ + _filePos = 0; + while (_fileIndex < _numFiles) + { + _currentSizeIsDefined = false; + CMyComPtr stream; + HRESULT result = _updateCallback->GetStream(_fileIndices[_fileIndex], &stream); + if (result != S_OK && result != S_FALSE) + return result; + _fileIndex++; + _inStreamWithHashSpec->SetStream(stream); + _inStreamWithHashSpec->Init(); + if (!stream) + { + RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); + Sizes.Add(0); + Processed.Add(result == S_OK); + AddDigest(); + continue; + } + CMyComPtr streamGetSize; + if (stream.QueryInterface(IID_IStreamGetSize, &streamGetSize) == S_OK) + { + if(streamGetSize) + { + _currentSizeIsDefined = true; + RINOK(streamGetSize->GetSize(&_currentSize)); + } + } + + _fileIsOpen = true; + return S_OK; + } + return S_OK; +} + +void CFolderInStream::AddDigest() +{ + CRCs.Add(_inStreamWithHashSpec->GetCRC()); +} + +HRESULT CFolderInStream::CloseStream() +{ + RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); + _inStreamWithHashSpec->ReleaseStream(); + _fileIsOpen = false; + Processed.Add(true); + Sizes.Add(_filePos); + AddDigest(); + return S_OK; +} + +STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize = 0; + while ((_fileIndex < _numFiles || _fileIsOpen) && size > 0) + { + if (_fileIsOpen) + { + UInt32 localProcessedSize; + RINOK(_inStreamWithHash->Read( + ((Byte *)data) + realProcessedSize, size, &localProcessedSize)); + if (localProcessedSize == 0) + { + RINOK(CloseStream()); + continue; + } + realProcessedSize += localProcessedSize; + _filePos += localProcessedSize; + size -= localProcessedSize; + break; + } + else + { + RINOK(OpenStream()); + } + } + if (processedSize != 0) + *processedSize = realProcessedSize; + return S_OK; +} + +STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value) +{ + *value = 0; + if (subStream < Sizes.Size()) + { + *value= Sizes[(int)(size_t)subStream]; + return S_OK; + } + if (subStream > Sizes.Size()) + return E_FAIL; + if (!_currentSizeIsDefined) + return S_FALSE; + *value = _currentSize; + return S_OK; +} + +}} diff --git a/CPP/7zip/Archive/7z/7zFolderInStream.h b/CPP/7zip/Archive/7z/7zFolderInStream.h new file mode 100755 index 00000000..9a720c8b --- /dev/null +++ b/CPP/7zip/Archive/7z/7zFolderInStream.h @@ -0,0 +1,66 @@ +// 7z/FolderInStream.h + +#ifndef __7Z_FOLDERINSTREAM_H +#define __7Z_FOLDERINSTREAM_H + +#include "7zItem.h" +#include "7zHeader.h" + +#include "../IArchive.h" +#include "../Common/InStreamWithCRC.h" +#include "../../IStream.h" +#include "../../ICoder.h" + +namespace NArchive { +namespace N7z { + +class CFolderInStream: + public ISequentialInStream, + public ICompressGetSubStreamSize, + public CMyUnknownImp +{ +public: + + MY_UNKNOWN_IMP1(ICompressGetSubStreamSize) + + CFolderInStream(); + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + + STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value); +private: + CSequentialInStreamWithCRC *_inStreamWithHashSpec; + CMyComPtr _inStreamWithHash; + CMyComPtr _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 Processed; + CRecordVector CRCs; + CRecordVector Sizes; + UInt64 GetFullSize() const + { + UInt64 size = 0; + for (int i = 0; i < Sizes.Size(); i++) + size += Sizes[i]; + return size; + } +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/7z/7zFolderOutStream.cpp b/CPP/7zip/Archive/7z/7zFolderOutStream.cpp new file mode 100755 index 00000000..93bed3d9 --- /dev/null +++ b/CPP/7zip/Archive/7z/7zFolderOutStream.cpp @@ -0,0 +1,162 @@ +// 7zFolderOutStream.cpp + +#include "StdAfx.h" + +#include "7zFolderOutStream.h" + +namespace NArchive { +namespace N7z { + +CFolderOutStream::CFolderOutStream() +{ + _outStreamWithHashSpec = new COutStreamWithCRC; + _outStreamWithHash = _outStreamWithHashSpec; +} + +HRESULT CFolderOutStream::Init( + const CArchiveDatabaseEx *archiveDatabase, + UInt32 ref2Offset, + UInt32 startIndex, + const CBoolVector *extractStatuses, + IArchiveExtractCallback *extractCallback, + bool testMode) +{ + _archiveDatabase = archiveDatabase; + _ref2Offset = ref2Offset; + _startIndex = startIndex; + + _extractStatuses = extractStatuses; + _extractCallback = extractCallback; + _testMode = testMode; + + _currentIndex = 0; + _fileIsOpen = false; + return WriteEmptyFiles(); +} + +HRESULT CFolderOutStream::OpenFile() +{ + Int32 askMode; + if((*_extractStatuses)[_currentIndex]) + askMode = _testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + else + askMode = NArchive::NExtract::NAskMode::kSkip; + CMyComPtr realOutStream; + + UInt32 index = _startIndex + _currentIndex; + RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode)); + + _outStreamWithHashSpec->SetStream(realOutStream); + _outStreamWithHashSpec->Init(); + if (askMode == NArchive::NExtract::NAskMode::kExtract && + (!realOutStream)) + { + const CFileItem &fileInfo = _archiveDatabase->Files[index]; + if (!fileInfo.IsAnti && !fileInfo.IsDirectory) + askMode = NArchive::NExtract::NAskMode::kSkip; + } + return _extractCallback->PrepareOperation(askMode); +} + +HRESULT CFolderOutStream::WriteEmptyFiles() +{ + for(;_currentIndex < _extractStatuses->Size(); _currentIndex++) + { + UInt32 index = _startIndex + _currentIndex; + const CFileItem &fileInfo = _archiveDatabase->Files[index]; + if (!fileInfo.IsAnti && !fileInfo.IsDirectory && fileInfo.UnPackSize != 0) + return S_OK; + RINOK(OpenFile()); + RINOK(_extractCallback->SetOperationResult( + NArchive::NExtract::NOperationResult::kOK)); + _outStreamWithHashSpec->ReleaseStream(); + } + return S_OK; +} + +STDMETHODIMP CFolderOutStream::Write(const void *data, + UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize = 0; + while(_currentIndex < _extractStatuses->Size()) + { + if (_fileIsOpen) + { + UInt32 index = _startIndex + _currentIndex; + const CFileItem &fileInfo = _archiveDatabase->Files[index]; + UInt64 fileSize = fileInfo.UnPackSize; + + UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - _filePos, + UInt64(size - realProcessedSize)); + + UInt32 processedSizeLocal; + RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize, + numBytesToWrite, &processedSizeLocal)); + + _filePos += processedSizeLocal; + realProcessedSize += processedSizeLocal; + if (_filePos == fileSize) + { + bool digestsAreEqual; + if (fileInfo.IsFileCRCDefined) + digestsAreEqual = fileInfo.FileCRC == _outStreamWithHashSpec->GetCRC(); + else + digestsAreEqual = true; + + RINOK(_extractCallback->SetOperationResult( + digestsAreEqual ? + NArchive::NExtract::NOperationResult::kOK : + NArchive::NExtract::NOperationResult::kCRCError)); + _outStreamWithHashSpec->ReleaseStream(); + _fileIsOpen = false; + _currentIndex++; + } + if (realProcessedSize == size) + { + if (processedSize != NULL) + *processedSize = realProcessedSize; + return WriteEmptyFiles(); + } + } + else + { + RINOK(OpenFile()); + _fileIsOpen = true; + _filePos = 0; + } + } + if (processedSize != NULL) + *processedSize = size; + return S_OK; +} + +HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult) +{ + while(_currentIndex < _extractStatuses->Size()) + { + if (_fileIsOpen) + { + RINOK(_extractCallback->SetOperationResult(resultEOperationResult)); + _outStreamWithHashSpec->ReleaseStream(); + _fileIsOpen = false; + _currentIndex++; + } + else + { + RINOK(OpenFile()); + _fileIsOpen = true; + } + } + return S_OK; +} + +HRESULT CFolderOutStream::WasWritingFinished() +{ + if (_currentIndex == _extractStatuses->Size()) + return S_OK; + return E_FAIL; +} + +}} diff --git a/CPP/7zip/Archive/7z/7zFolderOutStream.h b/CPP/7zip/Archive/7z/7zFolderOutStream.h new file mode 100755 index 00000000..c132c79a --- /dev/null +++ b/CPP/7zip/Archive/7z/7zFolderOutStream.h @@ -0,0 +1,57 @@ +// 7zFolderOutStream.h + +#ifndef __7Z_FOLDEROUTSTREAM_H +#define __7Z_FOLDEROUTSTREAM_H + +#include "7zIn.h" + +#include "../../IStream.h" +#include "../IArchive.h" +#include "../Common/OutStreamWithCRC.h" + +namespace NArchive { +namespace N7z { + +class CFolderOutStream: + public ISequentialOutStream, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + CFolderOutStream(); + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +private: + + COutStreamWithCRC *_outStreamWithHashSpec; + CMyComPtr _outStreamWithHash; + const CArchiveDatabaseEx *_archiveDatabase; + const CBoolVector *_extractStatuses; + UInt32 _startIndex; + UInt32 _ref2Offset; + int _currentIndex; + // UInt64 _currentDataPos; + CMyComPtr _extractCallback; + bool _testMode; + + bool _fileIsOpen; + UInt64 _filePos; + + HRESULT OpenFile(); + HRESULT WriteEmptyFiles(); +public: + HRESULT Init( + const CArchiveDatabaseEx *archiveDatabase, + UInt32 ref2Offset, + UInt32 startIndex, + const CBoolVector *extractStatuses, + IArchiveExtractCallback *extractCallback, + bool testMode); + HRESULT FlushCorrupted(Int32 resultEOperationResult); + HRESULT WasWritingFinished(); +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/7z/7zHandler.cpp b/CPP/7zip/Archive/7z/7zHandler.cpp new file mode 100755 index 00000000..3321fd71 --- /dev/null +++ b/CPP/7zip/Archive/7z/7zHandler.cpp @@ -0,0 +1,794 @@ +// 7zHandler.cpp + +#include "StdAfx.h" + +#include "7zHandler.h" +#include "7zProperties.h" + +#include "../../../Common/IntToString.h" +#include "../../../Common/ComTry.h" +#include "../../../Windows/Defs.h" + +#include "../Common/ItemNameUtils.h" +#ifdef _7Z_VOL +#include "../Common/MultiStream.h" +#endif + +#ifdef __7Z_SET_PROPERTIES +#ifdef EXTRACT_ONLY +#include "../Common/ParseProperties.h" +#endif +#endif + +using namespace NWindows; + +namespace NArchive { +namespace N7z { + +CHandler::CHandler() +{ + #ifdef COMPRESS_MT + _numThreads = NWindows::NSystem::GetNumberOfProcessors(); + #endif + #ifndef EXTRACT_ONLY + Init(); + #endif + #ifndef EXCLUDE_COM + LoadMethodMap(); + #endif +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = + #ifdef _7Z_VOL + _refs.Size(); + #else + *numItems = _database.Files.Size(); + #endif + return S_OK; +} + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) +{ + value->vt = VT_EMPTY; + return S_OK; +} + +#ifdef _SFX + +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 * /* numProperties */) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */, + BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) +{ + return E_NOTIMPL; +} + +#endif + + +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +{ + *numProperties = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, + BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) +{ + return E_NOTIMPL; +} + + +static void MySetFileTime(bool timeDefined, FILETIME unixTime, + NWindows::NCOM::CPropVariant &propVariant) +{ + if (timeDefined) + propVariant = unixTime; +} + +#ifndef _SFX + +static UString ConvertUInt32ToString(UInt32 value) +{ + wchar_t buffer[32]; + ConvertUInt64ToString(value, buffer); + return buffer; +} + +static UString GetStringForSizeValue(UInt32 value) +{ + for (int i = 31; i >= 0; i--) + if ((UInt32(1) << i) == value) + return ConvertUInt32ToString(i); + UString result; + if (value % (1 << 20) == 0) + { + result += ConvertUInt32ToString(value >> 20); + result += L"m"; + } + else if (value % (1 << 10) == 0) + { + result += ConvertUInt32ToString(value >> 10); + result += L"k"; + } + else + { + result += ConvertUInt32ToString(value); + result += L"b"; + } + return result; +} + +static CMethodID k_Copy = { { 0x0 }, 1 }; +static CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 }; +static CMethodID k_BCJ = { { 0x3, 0x3, 0x1, 0x3 }, 4 }; +static CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 }; +static CMethodID k_PPMD = { { 0x3, 0x4, 0x1 }, 3 }; +static CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 }; +static CMethodID k_Deflate64 = { { 0x4, 0x1, 0x9 }, 3 }; +static CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 }; + +static wchar_t GetHex(Byte value) +{ + return (wchar_t)((value < 10) ? (L'0' + value) : (L'A' + (value - 10))); +} +static inline UString GetHex2(Byte value) +{ + UString result; + result += GetHex((Byte)(value >> 4)); + result += GetHex((Byte)(value & 0xF)); + return result; +} + +#endif + +static CMethodID k_AES = { { 0x6, 0xF1, 0x7, 0x1}, 4 }; + +static inline UInt32 GetUInt32FromMemLE(const Byte *p) +{ + return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24); +} + +bool CHandler::IsEncrypted(UInt32 index2) const +{ + CNum folderIndex = _database.FileIndexToFolderIndexMap[index2]; + if (folderIndex != kNumNoIndex) + { + const CFolder &folderInfo = _database.Folders[folderIndex]; + for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--) + { + const CCoderInfo &coderInfo = folderInfo.Coders[i]; + for (int j = 0; j < coderInfo.AltCoders.Size(); j++) + if (coderInfo.AltCoders[j].MethodID == k_AES) + return true; + } + } + return false; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant propVariant; + + /* + const CRef2 &ref2 = _refs[index]; + if (ref2.Refs.IsEmpty()) + return E_FAIL; + const CRef &ref = ref2.Refs.Front(); + */ + + #ifdef _7Z_VOL + const CRef &ref = _refs[index]; + const CVolume &volume = _volumes[ref.VolumeIndex]; + const CArchiveDatabaseEx &_database = volume.Database; + UInt32 index2 = ref.ItemIndex; + const CFileItem &item = _database.Files[index2]; + #else + const CFileItem &item = _database.Files[index]; + UInt32 index2 = index; + #endif + + switch(propID) + { + case kpidPath: + { + if (!item.Name.IsEmpty()) + propVariant = NItemName::GetOSName(item.Name); + break; + } + case kpidIsFolder: + propVariant = item.IsDirectory; + break; + case kpidSize: + { + propVariant = item.UnPackSize; + // propVariant = ref2.UnPackSize; + break; + } + case kpidPosition: + { + /* + if (ref2.Refs.Size() > 1) + propVariant = ref2.StartPos; + else + */ + if (item.IsStartPosDefined) + propVariant = item.StartPos; + break; + } + case kpidPackedSize: + { + // propVariant = ref2.PackSize; + { + CNum folderIndex = _database.FileIndexToFolderIndexMap[index2]; + if (folderIndex != kNumNoIndex) + { + if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2) + propVariant = _database.GetFolderFullPackSize(folderIndex); + /* + else + propVariant = UInt64(0); + */ + } + else + propVariant = UInt64(0); + } + break; + } + case kpidLastAccessTime: + MySetFileTime(item.IsLastAccessTimeDefined, item.LastAccessTime, propVariant); + break; + case kpidCreationTime: + MySetFileTime(item.IsCreationTimeDefined, item.CreationTime, propVariant); + break; + case kpidLastWriteTime: + MySetFileTime(item.IsLastWriteTimeDefined, item.LastWriteTime, propVariant); + break; + case kpidAttributes: + if (item.AreAttributesDefined) + propVariant = item.Attributes; + break; + case kpidCRC: + if (item.IsFileCRCDefined) + propVariant = item.FileCRC; + break; + case kpidEncrypted: + { + propVariant = IsEncrypted(index2); + break; + } + #ifndef _SFX + case kpidMethod: + { + CNum folderIndex = _database.FileIndexToFolderIndexMap[index2]; + if (folderIndex != kNumNoIndex) + { + const CFolder &folderInfo = _database.Folders[folderIndex]; + UString methodsString; + for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--) + { + const CCoderInfo &coderInfo = folderInfo.Coders[i]; + if (!methodsString.IsEmpty()) + methodsString += L' '; + CMethodInfo methodInfo; + + bool methodIsKnown; + + for (int j = 0; j < coderInfo.AltCoders.Size(); j++) + { + if (j > 0) + methodsString += L"|"; + const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders[j]; + + UString methodName; + #ifdef NO_REGISTRY + + methodIsKnown = true; + if (altCoderInfo.MethodID == k_Copy) + methodName = L"Copy"; + else if (altCoderInfo.MethodID == k_LZMA) + methodName = L"LZMA"; + else if (altCoderInfo.MethodID == k_BCJ) + methodName = L"BCJ"; + else if (altCoderInfo.MethodID == k_BCJ2) + methodName = L"BCJ2"; + else if (altCoderInfo.MethodID == k_PPMD) + methodName = L"PPMD"; + else if (altCoderInfo.MethodID == k_Deflate) + methodName = L"Deflate"; + else if (altCoderInfo.MethodID == k_Deflate64) + methodName = L"Deflate64"; + else if (altCoderInfo.MethodID == k_BZip2) + methodName = L"BZip2"; + else if (altCoderInfo.MethodID == k_AES) + methodName = L"7zAES"; + else + methodIsKnown = false; + + #else + + methodIsKnown = GetMethodInfo( + altCoderInfo.MethodID, methodInfo); + methodName = methodInfo.Name; + + #endif + + if (methodIsKnown) + { + methodsString += methodName; + if (altCoderInfo.MethodID == k_LZMA) + { + if (altCoderInfo.Properties.GetCapacity() >= 5) + { + methodsString += L":"; + UInt32 dicSize = GetUInt32FromMemLE( + ((const Byte *)altCoderInfo.Properties + 1)); + methodsString += GetStringForSizeValue(dicSize); + } + } + else if (altCoderInfo.MethodID == k_PPMD) + { + if (altCoderInfo.Properties.GetCapacity() >= 5) + { + Byte order = *(const Byte *)altCoderInfo.Properties; + methodsString += L":o"; + methodsString += ConvertUInt32ToString(order); + methodsString += L":mem"; + UInt32 dicSize = GetUInt32FromMemLE( + ((const Byte *)altCoderInfo.Properties + 1)); + methodsString += GetStringForSizeValue(dicSize); + } + } + else if (altCoderInfo.MethodID == k_AES) + { + if (altCoderInfo.Properties.GetCapacity() >= 1) + { + methodsString += L":"; + const Byte *data = (const Byte *)altCoderInfo.Properties; + Byte firstByte = *data++; + UInt32 numCyclesPower = firstByte & 0x3F; + methodsString += ConvertUInt32ToString(numCyclesPower); + /* + if ((firstByte & 0xC0) != 0) + { + methodsString += L":"; + return S_OK; + UInt32 saltSize = (firstByte >> 7) & 1; + UInt32 ivSize = (firstByte >> 6) & 1; + if (altCoderInfo.Properties.GetCapacity() >= 2) + { + Byte secondByte = *data++; + saltSize += (secondByte >> 4); + ivSize += (secondByte & 0x0F); + } + } + */ + } + } + else + { + if (altCoderInfo.Properties.GetCapacity() > 0) + { + methodsString += L":["; + for (size_t bi = 0; bi < altCoderInfo.Properties.GetCapacity(); bi++) + { + if (bi > 5 && bi + 1 < altCoderInfo.Properties.GetCapacity()) + { + methodsString += L".."; + break; + } + else + methodsString += GetHex2(altCoderInfo.Properties[bi]); + } + methodsString += L"]"; + } + } + } + else + { + methodsString += altCoderInfo.MethodID.ConvertToString(); + } + } + } + propVariant = methodsString; + } + } + break; + case kpidBlock: + { + CNum folderIndex = _database.FileIndexToFolderIndexMap[index2]; + if (folderIndex != kNumNoIndex) + propVariant = (UInt32)folderIndex; + } + break; + case kpidPackedSize0: + case kpidPackedSize1: + case kpidPackedSize2: + case kpidPackedSize3: + case kpidPackedSize4: + { + CNum folderIndex = _database.FileIndexToFolderIndexMap[index2]; + if (folderIndex != kNumNoIndex) + { + const CFolder &folderInfo = _database.Folders[folderIndex]; + if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2 && + folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0)) + { + propVariant = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0); + } + else + propVariant = UInt64(0); + } + else + propVariant = UInt64(0); + } + break; + #endif + case kpidIsAnti: + propVariant = item.IsAnti; + break; + } + propVariant.Detach(value); + return S_OK; + COM_TRY_END +} + +static const wchar_t *kExt = L"7z"; +static const wchar_t *kAfterPart = L".7z"; + +#ifdef _7Z_VOL + +class CVolumeName +{ + bool _first; + UString _unchangedPart; + UString _changedPart; + UString _afterPart; +public: + bool InitName(const UString &name) + { + _first = true; + int dotPos = name.ReverseFind('.'); + UString basePart = name; + if (dotPos >= 0) + { + UString ext = name.Mid(dotPos + 1); + if (ext.CompareNoCase(kExt)==0 || + ext.CompareNoCase(L"EXE") == 0) + { + _afterPart = kAfterPart; + basePart = name.Left(dotPos); + } + } + + int numLetters = 1; + bool splitStyle = false; + if (basePart.Right(numLetters) == L"1") + { + while (numLetters < basePart.Length()) + { + if (basePart[basePart.Length() - numLetters - 1] != '0') + break; + numLetters++; + } + } + else + return false; + _unchangedPart = basePart.Left(basePart.Length() - numLetters); + _changedPart = basePart.Right(numLetters); + return true; + } + + UString GetNextName() + { + UString newName; + // if (_newStyle || !_first) + { + int i; + int numLetters = _changedPart.Length(); + for (i = numLetters - 1; i >= 0; i--) + { + wchar_t c = _changedPart[i]; + if (c == L'9') + { + c = L'0'; + newName = c + newName; + if (i == 0) + newName = UString(L'1') + newName; + continue; + } + c++; + newName = UString(c) + newName; + i--; + for (; i >= 0; i--) + newName = _changedPart[i] + newName; + break; + } + _changedPart = newName; + } + _first = false; + return _unchangedPart + _changedPart + _afterPart; + } +}; + +#endif + +STDMETHODIMP CHandler::Open(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback) +{ + COM_TRY_BEGIN + Close(); + #ifndef _SFX + _fileInfoPopIDs.Clear(); + #endif + try + { + CMyComPtr openArchiveCallbackTemp = openArchiveCallback; + #ifdef _7Z_VOL + CVolumeName seqName; + + CMyComPtr openVolumeCallback; + #endif + + #ifndef _NO_CRYPTO + CMyComPtr getTextPassword; + if (openArchiveCallback) + { + openArchiveCallbackTemp.QueryInterface( + IID_ICryptoGetTextPassword, &getTextPassword); + } + #endif + #ifdef _7Z_VOL + if (openArchiveCallback) + { + openArchiveCallbackTemp.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback); + } + for (;;) + { + CMyComPtr inStream; + if (!_volumes.IsEmpty()) + { + if (!openVolumeCallback) + break; + if(_volumes.Size() == 1) + { + UString baseName; + { + NCOM::CPropVariant propVariant; + RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant)); + if (propVariant.vt != VT_BSTR) + break; + baseName = propVariant.bstrVal; + } + seqName.InitName(baseName); + } + + UString fullName = seqName.GetNextName(); + HRESULT result = openVolumeCallback->GetStream(fullName, &inStream); + if (result == S_FALSE) + break; + if (result != S_OK) + return result; + if (!stream) + break; + } + else + inStream = stream; + + CInArchive archive; + RINOK(archive.Open(inStream, maxCheckStartPosition)); + + _volumes.Add(CVolume()); + CVolume &volume = _volumes.Back(); + CArchiveDatabaseEx &database = volume.Database; + volume.Stream = inStream; + volume.StartRef2Index = _refs.Size(); + + HRESULT result = archive.ReadDatabase(database + #ifndef _NO_CRYPTO + , getTextPassword + #endif + ); + if (result != S_OK) + { + _volumes.Clear(); + return result; + } + database.Fill(); + for(int i = 0; i < database.Files.Size(); i++) + { + CRef refNew; + refNew.VolumeIndex = _volumes.Size() - 1; + refNew.ItemIndex = i; + _refs.Add(refNew); + /* + const CFileItem &file = database.Files[i]; + int j; + */ + /* + for (j = _refs.Size() - 1; j >= 0; j--) + { + CRef2 &ref2 = _refs[j]; + const CRef &ref = ref2.Refs.Back(); + const CVolume &volume2 = _volumes[ref.VolumeIndex]; + const CArchiveDatabaseEx &database2 = volume2.Database; + const CFileItem &file2 = database2.Files[ref.ItemIndex]; + if (file2.Name.CompareNoCase(file.Name) == 0) + { + if (!file.IsStartPosDefined) + continue; + if (file.StartPos != ref2.StartPos + ref2.UnPackSize) + continue; + ref2.Refs.Add(refNew); + break; + } + } + */ + /* + j = -1; + if (j < 0) + { + CRef2 ref2New; + ref2New.Refs.Add(refNew); + j = _refs.Add(ref2New); + } + CRef2 &ref2 = _refs[j]; + ref2.UnPackSize += file.UnPackSize; + ref2.PackSize += database.GetFilePackSize(i); + if (ref2.Refs.Size() == 1 && file.IsStartPosDefined) + ref2.StartPos = file.StartPos; + */ + } + if (database.Files.Size() != 1) + break; + const CFileItem &file = database.Files.Front(); + if (!file.IsStartPosDefined) + break; + } + #else + CInArchive archive; + RINOK(archive.Open(stream, maxCheckStartPosition)); + HRESULT result = archive.ReadDatabase(_database + #ifndef _NO_CRYPTO + , getTextPassword + #endif + ); + RINOK(result); + _database.Fill(); + _inStream = stream; + #endif + } + catch(...) + { + Close(); + return S_FALSE; + } + // _inStream = stream; + #ifndef _SFX + FillPopIDs(); + #endif + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + COM_TRY_BEGIN + #ifdef _7Z_VOL + _volumes.Clear(); + _refs.Clear(); + #else + _inStream.Release(); + _database.Clear(); + #endif + return S_OK; + COM_TRY_END +} + +#ifdef _7Z_VOL +STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +{ + if (index != 0) + return E_INVALIDARG; + *stream = 0; + CMultiStream *streamSpec = new CMultiStream; + CMyComPtr streamTemp = streamSpec; + + UInt64 pos = 0; + const UString *fileName; + for (int i = 0; i < _refs.Size(); i++) + { + const CRef &ref = _refs[i]; + const CVolume &volume = _volumes[ref.VolumeIndex]; + const CArchiveDatabaseEx &database = volume.Database; + const CFileItem &file = database.Files[ref.ItemIndex]; + if (i == 0) + fileName = &file.Name; + else + if (fileName->Compare(file.Name) != 0) + return S_FALSE; + if (!file.IsStartPosDefined) + return S_FALSE; + if (file.StartPos != pos) + return S_FALSE; + CNum folderIndex = database.FileIndexToFolderIndexMap[ref.ItemIndex]; + if (folderIndex == kNumNoIndex) + { + if (file.UnPackSize != 0) + return E_FAIL; + continue; + } + if (database.NumUnPackStreamsVector[folderIndex] != 1) + return S_FALSE; + const CFolder &folder = database.Folders[folderIndex]; + if (folder.Coders.Size() != 1) + return S_FALSE; + const CCoderInfo &coder = folder.Coders.Front(); + if (coder.NumInStreams != 1 || coder.NumOutStreams != 1) + return S_FALSE; + const CAltCoderInfo &altCoder = coder.AltCoders.Front(); + if (altCoder.MethodID.IDSize != 1 || altCoder.MethodID.ID[0] != 0) + return S_FALSE; + + pos += file.UnPackSize; + CMultiStream::CSubStreamInfo subStreamInfo; + subStreamInfo.Stream = volume.Stream; + subStreamInfo.Pos = database.GetFolderStreamPos(folderIndex, 0); + subStreamInfo.Size = file.UnPackSize; + streamSpec->Streams.Add(subStreamInfo); + } + streamSpec->Init(); + *stream = streamTemp.Detach(); + return S_OK; +} +#endif + + +#ifdef __7Z_SET_PROPERTIES +#ifdef EXTRACT_ONLY + +STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) +{ + COM_TRY_BEGIN + #ifdef COMPRESS_MT + const UInt32 numProcessors = NSystem::GetNumberOfProcessors(); + _numThreads = numProcessors; + #endif + + for (int i = 0; i < numProperties; i++) + { + UString name = names[i]; + name.MakeUpper(); + if (name.IsEmpty()) + return E_INVALIDARG; + const PROPVARIANT &value = values[i]; + UInt32 number; + int index = ParseStringToUInt32(name, number); + if (index == 0) + { + if(name.Left(2).CompareNoCase(L"MT") == 0) + { + #ifdef COMPRESS_MT + RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads)); + #endif + continue; + } + else + return E_INVALIDARG; + } + } + return S_OK; + COM_TRY_END +} + +#endif +#endif + +}} diff --git a/CPP/7zip/Archive/7z/7zHandler.h b/CPP/7zip/Archive/7z/7zHandler.h new file mode 100755 index 00000000..8be9f398 --- /dev/null +++ b/CPP/7zip/Archive/7z/7zHandler.h @@ -0,0 +1,249 @@ +// 7z/Handler.h + +#ifndef __7Z_HANDLER_H +#define __7Z_HANDLER_H + +#include "../IArchive.h" +#include "7zIn.h" + +#include "7zCompressionMode.h" + +#ifndef _SFX +#include "7zMethods.h" +#endif + +#ifdef COMPRESS_MT +#include "../../../Windows/System.h" +#endif + +namespace NArchive { +namespace N7z { + +#ifdef _7Z_VOL +struct CRef +{ + int VolumeIndex; + int ItemIndex; +}; + +/* +struct CRef2 +{ + CRecordVector Refs; + UInt64 UnPackSize; + UInt64 PackSize; + UInt64 StartPos; + CRef2(): UnPackSize(0), PackSize(0), StartPos(0) {} +}; +*/ + +struct CVolume +{ + int StartRef2Index; + CMyComPtr Stream; + CArchiveDatabaseEx Database; +}; +#endif + +#ifndef EXTRACT_ONLY + +struct COneMethodInfo +{ + CObjectVector CoderProperties; + UString MethodName; +}; +#endif + +// {23170F69-40C1-278A-1000-000110070000} +DEFINE_GUID(CLSID_CFormat7z, + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00); + +#ifndef __7Z_SET_PROPERTIES + +#ifdef EXTRACT_ONLY +#ifdef COMPRESS_MT +#define __7Z_SET_PROPERTIES +#endif +#else +#define __7Z_SET_PROPERTIES +#endif + +#endif + + +class CHandler: + public IInArchive, + #ifdef _7Z_VOL + public IInArchiveGetStream, + #endif + #ifdef __7Z_SET_PROPERTIES + public ISetProperties, + #endif + #ifndef EXTRACT_ONLY + public IOutArchive, + #endif + public CMyUnknownImp +{ +public: + #if !defined(_7Z_VOL) && !defined(__7Z_SET_PROPERTIES) && defined(EXTRACT_ONLY) + MY_UNKNOWN_IMP + #else + MY_QUERYINTERFACE_BEGIN + #ifdef _7Z_VOL + MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream) + #endif + #ifdef __7Z_SET_PROPERTIES + MY_QUERYINTERFACE_ENTRY(ISetProperties) + #endif + #ifndef EXTRACT_ONLY + MY_QUERYINTERFACE_ENTRY(IOutArchive) + #endif + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + #endif + + + STDMETHOD(Open)(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback); + STDMETHOD(Close)(); + + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); + + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + #ifdef _7Z_VOL + STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); + #endif + + #ifdef __7Z_SET_PROPERTIES + STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties); + #endif + + #ifndef EXTRACT_ONLY + // IOutArchiveHandler + STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback); + + STDMETHOD(GetFileTimeType)(UInt32 *type); + + // ISetProperties + + HRESULT SetSolidSettings(const UString &s); + HRESULT SetSolidSettings(const PROPVARIANT &value); + #endif + + CHandler(); + +private: + #ifdef _7Z_VOL + CObjectVector _volumes; + CObjectVector _refs; + #else + CMyComPtr _inStream; + NArchive::N7z::CArchiveDatabaseEx _database; + #endif + + #ifdef COMPRESS_MT + UInt32 _numThreads; + #endif + + #ifndef EXTRACT_ONLY + CObjectVector _methods; + CRecordVector _binds; + bool _removeSfxBlock; + UInt64 _numSolidFiles; + UInt64 _numSolidBytes; + bool _numSolidBytesDefined; + bool _solidExtension; + + bool _compressHeaders; + bool _compressHeadersFull; + bool _encryptHeaders; + + bool WriteModified; + bool WriteCreated; + bool WriteAccessed; + + + bool _autoFilter; + UInt32 _level; + + bool _volumeMode; + + + HRESULT SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value); + HRESULT SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString); + + HRESULT SetPassword(CCompressionMethodMode &methodMode, IArchiveUpdateCallback *updateCallback); + + HRESULT SetCompressionMethod(CCompressionMethodMode &method, + CObjectVector &methodsInfo + #ifdef COMPRESS_MT + , UInt32 numThreads + #endif + ); + + HRESULT SetCompressionMethod( + CCompressionMethodMode &method, + CCompressionMethodMode &headerMethod); + + #endif + + bool IsEncrypted(UInt32 index2) const; + #ifndef _SFX + + CRecordVector _fileInfoPopIDs; + void FillPopIDs(); + + #endif + + #ifndef EXTRACT_ONLY + + void InitSolidFiles() { _numSolidFiles = UInt64(Int64(-1)); } + void InitSolidSize() { _numSolidBytes = UInt64(Int64(-1)); } + void InitSolid() + { + InitSolidFiles(); + InitSolidSize(); + _solidExtension = false; + _numSolidBytesDefined = false; + } + + void Init() + { + _removeSfxBlock = false; + _compressHeaders = true; + _compressHeadersFull = true; + _encryptHeaders = false; + + WriteModified = true; + WriteCreated = false; + WriteAccessed = false; + + #ifdef COMPRESS_MT + _numThreads = NWindows::NSystem::GetNumberOfProcessors(); + #endif + + _level = 5; + _autoFilter = true; + _volumeMode = false; + InitSolid(); + } + #endif +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/7z/7zHandlerOut.cpp b/CPP/7zip/Archive/7z/7zHandlerOut.cpp new file mode 100755 index 00000000..8be88c38 --- /dev/null +++ b/CPP/7zip/Archive/7z/7zHandlerOut.cpp @@ -0,0 +1,1148 @@ +// 7z/OutHandler.cpp + +#include "StdAfx.h" + +#include "7zHandler.h" +#include "7zOut.h" +#include "7zUpdate.h" +#include "7zMethods.h" + +#include "../../../Windows/PropVariant.h" + +#include "../../../Common/ComTry.h" +#include "../../../Common/StringToInt.h" +#include "../../IPassword.h" +#include "../../ICoder.h" + +#include "../Common/ItemNameUtils.h" +#include "../Common/ParseProperties.h" + +using namespace NWindows; + +namespace NArchive { +namespace N7z { + +#ifdef COMPRESS_LZMA +static CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 }; +static CMethodID k_LZMA2 = { { 0x3, 0x1, 0x2 }, 3 }; +#endif + +#ifdef COMPRESS_PPMD +static CMethodID k_PPMD = { { 0x3, 0x4, 0x1 }, 3 }; +#endif + +#ifdef COMPRESS_BCJ_X86 +static CMethodID k_BCJ_X86 = { { 0x3, 0x3, 0x1, 0x3 }, 4 }; +#endif + +#ifdef COMPRESS_BCJ2 +static CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 }; +#endif + +#ifdef COMPRESS_COPY +static CMethodID k_Copy = { { 0x0 }, 1 }; +#endif + +#ifdef COMPRESS_DEFLATE +#ifndef COMPRESS_DEFLATE_ENCODER +#define COMPRESS_DEFLATE_ENCODER +#endif +#endif + +#ifdef COMPRESS_DEFLATE_ENCODER +static CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 }; +#endif + +#ifdef COMPRESS_BZIP2 +#ifndef COMPRESS_BZIP2_ENCODER +#define COMPRESS_BZIP2_ENCODER +#endif +#endif + +#ifdef COMPRESS_BZIP2_ENCODER +static CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 }; +#endif + +const wchar_t *kCopyMethod = L"Copy"; +const wchar_t *kLZMAMethodName = L"LZMA"; +const wchar_t *kLZMA2MethodName = L"LZMA2"; +const wchar_t *kBZip2MethodName = L"BZip2"; +const wchar_t *kPpmdMethodName = L"PPMd"; +const wchar_t *kDeflateMethodName = L"Deflate"; +const wchar_t *kDeflate64MethodName = L"Deflate64"; + +static const wchar_t *kLzmaMatchFinderX1 = L"HC4"; +static const wchar_t *kLzmaMatchFinderX5 = L"BT4"; + +static const UInt32 kLzmaAlgorithmX1 = 0; +static const UInt32 kLzmaAlgorithmX5 = 1; + +static const UInt32 kLzmaDicSizeX1 = 1 << 16; +static const UInt32 kLzmaDicSizeX3 = 1 << 20; +static const UInt32 kLzmaDicSizeX5 = 1 << 22; +static const UInt32 kLzmaDicSizeX7 = 1 << 24; +static const UInt32 kLzmaDicSizeX9 = 1 << 26; + +static const UInt32 kLzmaFastBytesX1 = 32; +static const UInt32 kLzmaFastBytesX7 = 64; + +static const UInt32 kPpmdMemSizeX1 = (1 << 22); +static const UInt32 kPpmdMemSizeX5 = (1 << 24); +static const UInt32 kPpmdMemSizeX7 = (1 << 26); +static const UInt32 kPpmdMemSizeX9 = (192 << 20); + +static const UInt32 kPpmdOrderX1 = 4; +static const UInt32 kPpmdOrderX5 = 6; +static const UInt32 kPpmdOrderX7 = 16; +static const UInt32 kPpmdOrderX9 = 32; + +static const UInt32 kDeflateFastBytesX1 = 32; +static const UInt32 kDeflateFastBytesX7 = 64; +static const UInt32 kDeflateFastBytesX9 = 128; + +static const UInt32 kDeflatePassesX1 = 1; +static const UInt32 kDeflatePassesX7 = 3; +static const UInt32 kDeflatePassesX9 = 10; + +static const UInt32 kBZip2NumPassesX1 = 1; +static const UInt32 kBZip2NumPassesX7 = 2; +static const UInt32 kBZip2NumPassesX9 = 7; + +static const UInt32 kBZip2DicSizeX1 = 100000; +static const UInt32 kBZip2DicSizeX3 = 500000; +static const UInt32 kBZip2DicSizeX5 = 900000; + +const wchar_t *kDefaultMethodName = kLZMAMethodName; + +static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2"; +static const UInt32 kDictionaryForHeaders = 1 << 20; +static const UInt32 kNumFastBytesForHeaders = 273; +static const UInt32 kAlgorithmForHeaders = kLzmaAlgorithmX5; + +static bool IsCopyMethod(const UString &methodName) + { return (methodName.CompareNoCase(kCopyMethod) == 0); } + +static bool IsLZMAMethod(const UString &methodName) +{ + return + (methodName.CompareNoCase(kLZMAMethodName) == 0) || + (methodName.CompareNoCase(kLZMA2MethodName) == 0); +} + +/* +static bool IsLZMethod(const UString &methodName) + { return IsLZMAMethod(methodName); } +*/ + +static bool IsBZip2Method(const UString &methodName) + { return (methodName.CompareNoCase(kBZip2MethodName) == 0); } + +static bool IsPpmdMethod(const UString &methodName) + { return (methodName.CompareNoCase(kPpmdMethodName) == 0); } + +static bool IsDeflateMethod(const UString &methodName) + { return (methodName.CompareNoCase(kDeflateMethodName) == 0) || + (methodName.CompareNoCase(kDeflate64MethodName) == 0); } + +STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) +{ + *type = NFileTimeType::kWindows; + return S_OK; +} + +HRESULT CHandler::SetPassword(CCompressionMethodMode &methodMode, + IArchiveUpdateCallback *updateCallback) +{ + CMyComPtr getTextPassword; + if (!getTextPassword) + { + CMyComPtr udateCallback2(updateCallback); + udateCallback2.QueryInterface(IID_ICryptoGetTextPassword2, &getTextPassword); + } + + if (getTextPassword) + { + CMyComBSTR password; + Int32 passwordIsDefined; + RINOK(getTextPassword->CryptoGetTextPassword2( + &passwordIsDefined, &password)); + methodMode.PasswordIsDefined = IntToBool(passwordIsDefined); + if (methodMode.PasswordIsDefined) + methodMode.Password = password; + } + else + methodMode.PasswordIsDefined = false; + return S_OK; +} + +struct CNameToPropID +{ + PROPID PropID; + VARTYPE VarType; + const wchar_t *Name; +}; + +CNameToPropID g_NameToPropID[] = +{ + { NCoderPropID::kOrder, VT_UI4, L"O" }, + { NCoderPropID::kPosStateBits, VT_UI4, L"PB" }, + { NCoderPropID::kLitContextBits, VT_UI4, L"LC" }, + { NCoderPropID::kLitPosBits, VT_UI4, L"LP" }, + + { NCoderPropID::kNumPasses, VT_UI4, L"Pass" }, + { NCoderPropID::kNumFastBytes, VT_UI4, L"fb" }, + { NCoderPropID::kMatchFinderCycles, VT_UI4, L"mc" }, + { NCoderPropID::kAlgorithm, VT_UI4, L"a" }, + { NCoderPropID::kMatchFinder, VT_BSTR, L"mf" }, + { NCoderPropID::kNumThreads, VT_UI4, L"mt" } +}; + +bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType, + NCOM::CPropVariant &destProp) +{ + if (varType == srcProp.vt) + { + destProp = srcProp; + return true; + } + if (varType == VT_UI1) + { + if(srcProp.vt == VT_UI4) + { + UInt32 value = srcProp.ulVal; + if (value > 0xFF) + return false; + destProp = Byte(value); + return true; + } + } + return false; +} + +const int kNumNameToPropIDItems = sizeof(g_NameToPropID) / sizeof(g_NameToPropID[0]); + +int FindPropIdFromStringName(const UString &name) +{ + for (int i = 0; i < kNumNameToPropIDItems; i++) + if (name.CompareNoCase(g_NameToPropID[i].Name) == 0) + return i; + return -1; +} + +HRESULT CHandler::SetCompressionMethod( + CCompressionMethodMode &methodMode, + CCompressionMethodMode &headerMethod) +{ + HRESULT res = SetCompressionMethod(methodMode, _methods + #ifdef COMPRESS_MT + , _numThreads + #endif + ); + RINOK(res); + methodMode.Binds = _binds; + if (_compressHeadersFull) + _compressHeaders = true; + + if (_compressHeaders) + { + // headerMethod.Methods.Add(methodMode.Methods.Back()); + + CObjectVector headerMethodInfoVector; + COneMethodInfo oneMethodInfo; + oneMethodInfo.MethodName = kLZMAMethodName; + { + CProperty property; + property.PropID = NCoderPropID::kMatchFinder; + property.Value = kLzmaMatchFinderForHeaders; + oneMethodInfo.CoderProperties.Add(property); + } + { + CProperty property; + property.PropID = NCoderPropID::kAlgorithm; + property.Value = kAlgorithmForHeaders; + oneMethodInfo.CoderProperties.Add(property); + } + { + CProperty property; + property.PropID = NCoderPropID::kNumFastBytes; + property.Value = UInt32(kNumFastBytesForHeaders); + oneMethodInfo.CoderProperties.Add(property); + } + { + CProperty property; + property.PropID = NCoderPropID::kDictionarySize; + property.Value = UInt32(kDictionaryForHeaders); + oneMethodInfo.CoderProperties.Add(property); + } + headerMethodInfoVector.Add(oneMethodInfo); + HRESULT res = SetCompressionMethod(headerMethod, headerMethodInfoVector + #ifdef COMPRESS_MT + ,1 + #endif + ); + RINOK(res); + } + return S_OK; +} + +static void SetOneMethodProp(COneMethodInfo &oneMethodInfo, PROPID propID, + const NWindows::NCOM::CPropVariant &value) +{ + int j; + for (j = 0; j < oneMethodInfo.CoderProperties.Size(); j++) + if (oneMethodInfo.CoderProperties[j].PropID == propID) + break; + if (j != oneMethodInfo.CoderProperties.Size()) + return; + CProperty property; + property.PropID = propID; + property.Value = value; + oneMethodInfo.CoderProperties.Add(property); +} + +HRESULT CHandler::SetCompressionMethod( + CCompressionMethodMode &methodMode, + CObjectVector &methodsInfo + #ifdef COMPRESS_MT + , UInt32 numThreads + #endif + ) +{ + #ifndef EXCLUDE_COM + /* + CObjectVector methodInfoVector; + if (!NRegistryInfo::EnumerateAllMethods(methodInfoVector)) + return E_FAIL; + */ + #endif + + + UInt32 level = _level; + + if (methodsInfo.IsEmpty()) + { + COneMethodInfo oneMethodInfo; + oneMethodInfo.MethodName = ((level == 0) ? kCopyMethod : kDefaultMethodName); + methodsInfo.Add(oneMethodInfo); + } + + bool needSolid = false; + for(int i = 0; i < methodsInfo.Size(); i++) + { + COneMethodInfo &oneMethodInfo = methodsInfo[i]; + if (oneMethodInfo.MethodName.IsEmpty()) + oneMethodInfo.MethodName = kDefaultMethodName; + + if (!IsCopyMethod(oneMethodInfo.MethodName)) + needSolid = true; + + if (IsLZMAMethod(oneMethodInfo.MethodName)) + { + UInt32 dicSize = + (level >= 9 ? kLzmaDicSizeX9 : + (level >= 7 ? kLzmaDicSizeX7 : + (level >= 5 ? kLzmaDicSizeX5 : + (level >= 3 ? kLzmaDicSizeX3 : + kLzmaDicSizeX1)))); + + UInt32 algorithm = + (level >= 5 ? kLzmaAlgorithmX5 : + kLzmaAlgorithmX1); + + UInt32 fastBytes = + (level >= 7 ? kLzmaFastBytesX7 : + kLzmaFastBytesX1); + + const wchar_t *matchFinder = + (level >= 5 ? kLzmaMatchFinderX5 : + kLzmaMatchFinderX1); + + SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize); + SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algorithm); + SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes); + SetOneMethodProp(oneMethodInfo, NCoderPropID::kMatchFinder, matchFinder); + #ifdef COMPRESS_MT + SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads); + #endif + } + else if (IsDeflateMethod(oneMethodInfo.MethodName)) + { + UInt32 fastBytes = + (level >= 9 ? kDeflateFastBytesX9 : + (level >= 7 ? kDeflateFastBytesX7 : + kDeflateFastBytesX1)); + + UInt32 numPasses = + (level >= 9 ? kDeflatePassesX9 : + (level >= 7 ? kDeflatePassesX7 : + kDeflatePassesX1)); + + SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes); + SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses); + } + else if (IsBZip2Method(oneMethodInfo.MethodName)) + { + UInt32 numPasses = + (level >= 9 ? kBZip2NumPassesX9 : + (level >= 7 ? kBZip2NumPassesX7 : + kBZip2NumPassesX1)); + + UInt32 dicSize = + (level >= 5 ? kBZip2DicSizeX5 : + (level >= 3 ? kBZip2DicSizeX3 : + kBZip2DicSizeX1)); + + SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses); + SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize); + #ifdef COMPRESS_MT + SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads); + #endif + } + else if (IsPpmdMethod(oneMethodInfo.MethodName)) + { + UInt32 useMemSize = + (level >= 9 ? kPpmdMemSizeX9 : + (level >= 7 ? kPpmdMemSizeX7 : + (level >= 5 ? kPpmdMemSizeX5 : + kPpmdMemSizeX1))); + + UInt32 order = + (level >= 9 ? kPpmdOrderX9 : + (level >= 7 ? kPpmdOrderX7 : + (level >= 5 ? kPpmdOrderX5 : + kPpmdOrderX1))); + + SetOneMethodProp(oneMethodInfo, NCoderPropID::kUsedMemorySize, useMemSize); + SetOneMethodProp(oneMethodInfo, NCoderPropID::kOrder, order); + } + + + CMethodFull methodFull; + methodFull.NumInStreams = 1; + methodFull.NumOutStreams = 1; + + bool defined = false; + + #ifdef COMPRESS_LZMA + if (oneMethodInfo.MethodName.CompareNoCase(L"LZMA") == 0) + { + defined = true; + methodFull.MethodID = k_LZMA; + } + #endif + + #ifdef COMPRESS_PPMD + if (oneMethodInfo.MethodName.CompareNoCase(L"PPMD") == 0) + { + defined = true; + methodFull.MethodID = k_PPMD; + } + #endif + + #ifdef COMPRESS_BCJ_X86 + if (oneMethodInfo.MethodName.CompareNoCase(L"BCJ") == 0) + { + defined = true; + methodFull.MethodID = k_BCJ_X86; + } + #endif + + #ifdef COMPRESS_BCJ2 + if (oneMethodInfo.MethodName.CompareNoCase(L"BCJ2") == 0) + { + defined = true; + methodFull.MethodID = k_BCJ2; + methodFull.NumInStreams = 4; + methodFull.NumOutStreams = 1; + } + #endif + + #ifdef COMPRESS_DEFLATE_ENCODER + if (oneMethodInfo.MethodName.CompareNoCase(L"Deflate") == 0) + { + defined = true; + methodFull.MethodID = k_Deflate; + } + #endif + + #ifdef COMPRESS_BZIP2_ENCODER + if (oneMethodInfo.MethodName.CompareNoCase(L"BZip2") == 0) + { + defined = true; + methodFull.MethodID = k_BZip2; + } + #endif + + #ifdef COMPRESS_COPY + if (oneMethodInfo.MethodName.CompareNoCase(L"Copy") == 0) + { + defined = true; + methodFull.MethodID = k_Copy; + } + + #endif + + #ifndef EXCLUDE_COM + + if (!defined) + { + CMethodInfo2 methodInfo; + if (!GetMethodInfo(oneMethodInfo.MethodName, methodInfo)) + return E_INVALIDARG; + if (!methodInfo.EncoderIsAssigned) + return E_INVALIDARG; + + methodFull.MethodID = methodInfo.MethodID; + methodFull.NumInStreams = methodInfo.NumInStreams; + methodFull.NumOutStreams = methodInfo.NumOutStreams; + + methodFull.EncoderClassID = methodInfo.Encoder; + methodFull.FilePath = methodInfo.FilePath; + defined = true; + } + + #endif + if (!defined) + return E_INVALIDARG; + + methodFull.CoderProperties = oneMethodInfo.CoderProperties; + methodMode.Methods.Add(methodFull); + + if (!_numSolidBytesDefined) + { + for (int j = 0; j < methodFull.CoderProperties.Size(); j++) + { + const CProperty &prop = methodFull.CoderProperties[j]; + if ((prop.PropID == NCoderPropID::kDictionarySize || + prop.PropID == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI4) + { + _numSolidBytes = ((UInt64)prop.Value.ulVal) << 7; + const UInt64 kMinSize = (1 << 24); + if (_numSolidBytes < kMinSize) + _numSolidBytes = kMinSize; + _numSolidBytesDefined = true; + break; + } + } + } + } + + if (!needSolid && !_numSolidBytesDefined) + { + _numSolidBytesDefined = true; + _numSolidBytes = 0; + } + return S_OK; +} + +static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, PROPID propID, CArchiveFileTime &filetime, bool &filetimeIsDefined) +{ + filetimeIsDefined = false; + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(index, propID, &propVariant)); + if (propVariant.vt == VT_FILETIME) + { + filetime = propVariant.filetime; + filetimeIsDefined = true; + } + else if (propVariant.vt != VT_EMPTY) + return E_INVALIDARG; + return S_OK; +} + +STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback) +{ + COM_TRY_BEGIN + + const CArchiveDatabaseEx *database = 0; + #ifdef _7Z_VOL + if(_volumes.Size() > 1) + return E_FAIL; + const CVolume *volume = 0; + if (_volumes.Size() == 1) + { + volume = &_volumes.Front(); + database = &volume->Database; + } + #else + if (_inStream != 0) + database = &_database; + #endif + + // CRecordVector compressStatuses; + CObjectVector updateItems; + // CRecordVector copyIndices; + + // CMyComPtr updateCallback2; + // updateCallback->QueryInterface(&updateCallback2); + + for(UInt32 i = 0; i < numItems; i++) + { + Int32 newData; + Int32 newProperties; + UInt32 indexInArchive; + if (!updateCallback) + return E_FAIL; + RINOK(updateCallback->GetUpdateItemInfo(i, + &newData, &newProperties, &indexInArchive)); + CUpdateItem updateItem; + updateItem.NewProperties = IntToBool(newProperties); + updateItem.NewData = IntToBool(newData); + updateItem.IndexInArchive = indexInArchive; + updateItem.IndexInClient = i; + updateItem.IsAnti = false; + updateItem.Size = 0; + + if (updateItem.IndexInArchive != -1) + { + const CFileItem &fileItem = database->Files[updateItem.IndexInArchive]; + updateItem.Name = fileItem.Name; + updateItem.IsDirectory = fileItem.IsDirectory; + updateItem.Size = fileItem.UnPackSize; + updateItem.IsAnti = fileItem.IsAnti; + + updateItem.CreationTime = fileItem.CreationTime; + updateItem.IsCreationTimeDefined = fileItem.IsCreationTimeDefined; + updateItem.LastWriteTime = fileItem.LastWriteTime; + updateItem.IsLastWriteTimeDefined = fileItem.IsLastWriteTimeDefined; + updateItem.LastAccessTime = fileItem.LastAccessTime; + updateItem.IsLastAccessTimeDefined = fileItem.IsLastAccessTimeDefined; + } + + if (updateItem.NewProperties) + { + bool nameIsDefined; + bool folderStatusIsDefined; + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant)); + if (propVariant.vt == VT_EMPTY) + updateItem.AttributesAreDefined = false; + else if (propVariant.vt != VT_UI4) + return E_INVALIDARG; + else + { + updateItem.Attributes = propVariant.ulVal; + updateItem.AttributesAreDefined = true; + } + } + + RINOK(GetTime(updateCallback, i, kpidCreationTime, updateItem.CreationTime, updateItem.IsCreationTimeDefined)); + RINOK(GetTime(updateCallback, i, kpidLastWriteTime, updateItem.LastWriteTime , updateItem.IsLastWriteTimeDefined)); + RINOK(GetTime(updateCallback, i, kpidLastAccessTime, updateItem.LastAccessTime, updateItem.IsLastAccessTimeDefined)); + + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(i, kpidPath, &propVariant)); + if (propVariant.vt == VT_EMPTY) + nameIsDefined = false; + else if (propVariant.vt != VT_BSTR) + return E_INVALIDARG; + else + { + updateItem.Name = NItemName::MakeLegalName(propVariant.bstrVal); + nameIsDefined = true; + } + } + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(i, kpidIsFolder, &propVariant)); + if (propVariant.vt == VT_EMPTY) + folderStatusIsDefined = false; + else if (propVariant.vt != VT_BOOL) + return E_INVALIDARG; + else + { + updateItem.IsDirectory = (propVariant.boolVal != VARIANT_FALSE); + folderStatusIsDefined = true; + } + } + + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(i, kpidIsAnti, &propVariant)); + if (propVariant.vt == VT_EMPTY) + updateItem.IsAnti = false; + else if (propVariant.vt != VT_BOOL) + return E_INVALIDARG; + else + updateItem.IsAnti = (propVariant.boolVal != VARIANT_FALSE); + } + + if (updateItem.IsAnti) + { + updateItem.AttributesAreDefined = false; + + updateItem.IsCreationTimeDefined = false; + updateItem.IsLastWriteTimeDefined = false; + updateItem.IsLastAccessTimeDefined = false; + + updateItem.Size = 0; + } + + if (!folderStatusIsDefined && updateItem.AttributesAreDefined) + updateItem.SetDirectoryStatusFromAttributes(); + } + + if (updateItem.NewData) + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant)); + if (propVariant.vt != VT_UI8) + return E_INVALIDARG; + updateItem.Size = (UInt64)propVariant.uhVal.QuadPart; + if (updateItem.Size != 0 && updateItem.IsAnti) + return E_INVALIDARG; + } + updateItems.Add(updateItem); + } + + CCompressionMethodMode methodMode, headerMethod; + RINOK(SetCompressionMethod(methodMode, headerMethod)); + #ifdef COMPRESS_MT + methodMode.NumThreads = _numThreads; + headerMethod.NumThreads = 1; + #endif + + RINOK(SetPassword(methodMode, updateCallback)); + + bool useAdditionalHeaderStreams = true; + bool compressMainHeader = false; + + if (_compressHeadersFull) + { + useAdditionalHeaderStreams = false; + compressMainHeader = true; + } + if (methodMode.PasswordIsDefined) + { + useAdditionalHeaderStreams = false; + compressMainHeader = true; + if(_encryptHeaders) + RINOK(SetPassword(headerMethod, updateCallback)); + } + + if (numItems < 2) + compressMainHeader = false; + + CUpdateOptions options; + options.Method = &methodMode; + options.HeaderMethod = (_compressHeaders || + (methodMode.PasswordIsDefined && _encryptHeaders)) ? + &headerMethod : 0; + options.UseFilters = _level != 0 && _autoFilter; + options.MaxFilter = _level >= 8; + + options.HeaderOptions.UseAdditionalHeaderStreams = useAdditionalHeaderStreams; + options.HeaderOptions.CompressMainHeader = compressMainHeader; + options.HeaderOptions.WriteModified = WriteModified; + options.HeaderOptions.WriteCreated = WriteCreated; + options.HeaderOptions.WriteAccessed = WriteAccessed; + + options.NumSolidFiles = _numSolidFiles; + options.NumSolidBytes = _numSolidBytes; + options.SolidExtension = _solidExtension; + options.RemoveSfxBlock = _removeSfxBlock; + options.VolumeMode = _volumeMode; + return Update( + #ifdef _7Z_VOL + volume ? volume->Stream: 0, + volume ? database: 0, + #else + _inStream, + database, + #endif + updateItems, outStream, updateCallback, options); + COM_TRY_END +} + +static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream) +{ + stream = 0; + int index = ParseStringToUInt32(srcString, coder); + if (index == 0) + return E_INVALIDARG; + srcString.Delete(0, index); + if (srcString[0] == 'S') + { + srcString.Delete(0); + int index = ParseStringToUInt32(srcString, stream); + if (index == 0) + return E_INVALIDARG; + srcString.Delete(0, index); + } + return S_OK; +} + +static HRESULT GetBindInfo(UString &srcString, CBind &bind) +{ + RINOK(GetBindInfoPart(srcString, bind.OutCoder, bind.OutStream)); + if (srcString[0] != ':') + return E_INVALIDARG; + srcString.Delete(0); + RINOK(GetBindInfoPart(srcString, bind.InCoder, bind.InStream)); + if (!srcString.IsEmpty()) + return E_INVALIDARG; + return S_OK; +} + +static void SplitParams(const UString &srcString, UStringVector &subStrings) +{ + subStrings.Clear(); + UString name; + int len = srcString.Length(); + if (len == 0) + return; + for (int i = 0; i < len; i++) + { + wchar_t c = srcString[i]; + if (c == L':') + { + subStrings.Add(name); + name.Empty(); + } + else + name += c; + } + subStrings.Add(name); +} + +static void SplitParam(const UString ¶m, UString &name, UString &value) +{ + int eqPos = param.Find(L'='); + if (eqPos >= 0) + { + name = param.Left(eqPos); + value = param.Mid(eqPos + 1); + return; + } + for(int i = 0; i < param.Length(); i++) + { + wchar_t c = param[i]; + if (c >= L'0' && c <= L'9') + { + name = param.Left(i); + value = param.Mid(i); + return; + } + } + name = param; +} + +HRESULT CHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value) +{ + CProperty property; + if (name.CompareNoCase(L"D") == 0 || name.CompareNoCase(L"MEM") == 0) + { + UInt32 dicSize; + RINOK(ParsePropDictionaryValue(value, dicSize)); + if (name.CompareNoCase(L"D") == 0) + property.PropID = NCoderPropID::kDictionarySize; + else + property.PropID = NCoderPropID::kUsedMemorySize; + property.Value = dicSize; + oneMethodInfo.CoderProperties.Add(property); + } + else + { + int index = FindPropIdFromStringName(name); + if (index < 0) + return E_INVALIDARG; + + const CNameToPropID &nameToPropID = g_NameToPropID[index]; + property.PropID = nameToPropID.PropID; + + NCOM::CPropVariant propValue; + + + if (nameToPropID.VarType == VT_BSTR) + propValue = value; + else + { + UInt32 number; + if (ParseStringToUInt32(value, number) == value.Length()) + propValue = number; + else + propValue = value; + } + + if (!ConvertProperty(propValue, nameToPropID.VarType, property.Value)) + return E_INVALIDARG; + + oneMethodInfo.CoderProperties.Add(property); + } + return S_OK; +} + +HRESULT CHandler::SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString) +{ + UStringVector params; + SplitParams(srcString, params); + if (params.Size() > 0) + oneMethodInfo.MethodName = params[0]; + for (int i = 1; i < params.Size(); i++) + { + const UString ¶m = params[i]; + UString name, value; + SplitParam(param, name, value); + RINOK(SetParam(oneMethodInfo, name, value)); + } + return S_OK; +} + +HRESULT CHandler::SetSolidSettings(const UString &s) +{ + UString s2 = s; + s2.MakeUpper(); + if (s2.IsEmpty() || s2.Compare(L"ON") == 0) + { + InitSolid(); + return S_OK; + } + if (s2.Compare(L"OFF") == 0) + { + _numSolidFiles = 1; + return S_OK; + } + for (int i = 0; i < s2.Length();) + { + const wchar_t *start = ((const wchar_t *)s2) + i; + const wchar_t *end; + UInt64 v = ConvertStringToUInt64(start, &end); + if (start == end) + { + if (s2[i++] != 'E') + return E_INVALIDARG; + _solidExtension = true; + continue; + } + i += (int)(end - start); + if (i == s2.Length()) + return E_INVALIDARG; + wchar_t c = s2[i++]; + switch(c) + { + case 'F': + if (v < 1) + v = 1; + _numSolidFiles = v; + break; + case 'B': + _numSolidBytes = v; + _numSolidBytesDefined = true; + break; + case 'K': + _numSolidBytes = (v << 10); + _numSolidBytesDefined = true; + break; + case 'M': + _numSolidBytes = (v << 20); + _numSolidBytesDefined = true; + break; + case 'G': + _numSolidBytes = (v << 30); + _numSolidBytesDefined = true; + break; + default: + return E_INVALIDARG; + } + } + return S_OK; +} + +HRESULT CHandler::SetSolidSettings(const PROPVARIANT &value) +{ + switch(value.vt) + { + case VT_EMPTY: + InitSolid(); + return S_OK; + case VT_BSTR: + return SetSolidSettings(value.bstrVal); + default: + return E_INVALIDARG; + } +} + +STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) +{ + COM_TRY_BEGIN + _methods.Clear(); + _binds.Clear(); + Init(); + #ifdef COMPRESS_MT + const UInt32 numProcessors = NSystem::GetNumberOfProcessors(); + #endif + + UInt32 mainDicSize = 0xFFFFFFFF; + UInt32 mainDicMethodIndex = 0xFFFFFFFF; + + UInt32 minNumber = 0; + + for (int i = 0; i < numProperties; i++) + { + UString name = names[i]; + name.MakeUpper(); + if (name.IsEmpty()) + return E_INVALIDARG; + + const PROPVARIANT &value = values[i]; + + if (name[0] == 'X') + { + name.Delete(0); + _level = 9; + RINOK(ParsePropValue(name, value, _level)); + continue; + } + + if (name[0] == 'B') + { + name.Delete(0); + CBind bind; + RINOK(GetBindInfo(name, bind)); + _binds.Add(bind); + continue; + } + + if (name[0] == L'S') + { + name.Delete(0); + if (name.IsEmpty()) + { + RINOK(SetSolidSettings(value)); + } + else + { + RINOK(SetSolidSettings(name)); + } + continue; + } + + + UInt32 number; + int index = ParseStringToUInt32(name, number); + UString realName = name.Mid(index); + if (index == 0) + { + if(name.Left(2).CompareNoCase(L"MT") == 0) + { + #ifdef COMPRESS_MT + RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads)); + #endif + continue; + } + else if (name.CompareNoCase(L"RSFX") == 0) + { + RINOK(SetBoolProperty(_removeSfxBlock, value)); + continue; + } + else if (name.CompareNoCase(L"F") == 0) + { + RINOK(SetBoolProperty(_autoFilter, value)); + continue; + } + else if (name.CompareNoCase(L"HC") == 0) + { + RINOK(SetBoolProperty(_compressHeaders, value)); + continue; + } + else if (name.CompareNoCase(L"HCF") == 0) + { + RINOK(SetBoolProperty(_compressHeadersFull, value)); + continue; + } + else if (name.CompareNoCase(L"HE") == 0) + { + RINOK(SetBoolProperty(_encryptHeaders, value)); + continue; + } + else if (name.CompareNoCase(L"TM") == 0) + { + RINOK(SetBoolProperty(WriteModified, value)); + continue; + } + else if (name.CompareNoCase(L"TC") == 0) + { + RINOK(SetBoolProperty(WriteCreated, value)); + continue; + } + else if (name.CompareNoCase(L"TA") == 0) + { + RINOK(SetBoolProperty(WriteAccessed, value)); + continue; + } + else if (name.CompareNoCase(L"V") == 0) + { + RINOK(SetBoolProperty(_volumeMode, value)); + continue; + } + number = 0; + } + if (number > 10000) + return E_FAIL; + if (number < minNumber) + return E_INVALIDARG; + number -= minNumber; + for(int j = _methods.Size(); j <= (int)number; j++) + { + COneMethodInfo oneMethodInfo; + _methods.Add(oneMethodInfo); + } + + COneMethodInfo &oneMethodInfo = _methods[number]; + + if (realName.Length() == 0) + { + if (value.vt != VT_BSTR) + return E_INVALIDARG; + + // oneMethodInfo.MethodName = UnicodeStringToMultiByte(UString(value.bstrVal)); + RINOK(SetParams(oneMethodInfo, value.bstrVal)); + } + else + { + CProperty property; + if (realName.Left(1).CompareNoCase(L"D") == 0) + { + UInt32 dicSize; + RINOK(ParsePropDictionaryValue(realName.Mid(1), value, dicSize)); + property.PropID = NCoderPropID::kDictionarySize; + property.Value = dicSize; + oneMethodInfo.CoderProperties.Add(property); + if (number <= mainDicMethodIndex) + mainDicSize = dicSize; + } + else if (realName.Left(3).CompareNoCase(L"MEM") == 0) + { + UInt32 dicSize; + RINOK(ParsePropDictionaryValue(realName.Mid(3), value, dicSize)); + property.PropID = NCoderPropID::kUsedMemorySize; + property.Value = dicSize; + oneMethodInfo.CoderProperties.Add(property); + if (number <= mainDicMethodIndex) + mainDicSize = dicSize; + } + else + { + int index = FindPropIdFromStringName(realName); + if (index < 0) + return E_INVALIDARG; + + const CNameToPropID &nameToPropID = g_NameToPropID[index]; + property.PropID = nameToPropID.PropID; + + if (!ConvertProperty(value, nameToPropID.VarType, property.Value)) + return E_INVALIDARG; + + oneMethodInfo.CoderProperties.Add(property); + } + } + } + + return S_OK; + COM_TRY_END +} + +}} diff --git a/CPP/7zip/Archive/7z/7zHeader.cpp b/CPP/7zip/Archive/7z/7zHeader.cpp new file mode 100755 index 00000000..cff4d121 --- /dev/null +++ b/CPP/7zip/Archive/7z/7zHeader.cpp @@ -0,0 +1,19 @@ +// 7z/Header.cpp + +#include "StdAfx.h" +#include "7zHeader.h" + +namespace NArchive { +namespace N7z { + +Byte kSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C}; +Byte kFinishSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C + 1}; + +class SignatureInitializer +{ +public: + SignatureInitializer() { kSignature[0]--; kFinishSignature[0]--;}; +} g_SignatureInitializer; + +}} + diff --git a/CPP/7zip/Archive/7z/7zHeader.h b/CPP/7zip/Archive/7z/7zHeader.h new file mode 100755 index 00000000..59bc7fe5 --- /dev/null +++ b/CPP/7zip/Archive/7z/7zHeader.h @@ -0,0 +1,96 @@ +// 7z/7zHeader.h + +#ifndef __7Z_HEADER_H +#define __7Z_HEADER_H + +#include "7zMethodID.h" + +namespace NArchive { +namespace N7z { + +const int kSignatureSize = 6; +extern Byte kSignature[kSignatureSize]; + +// #define _7Z_VOL +// 7z-MultiVolume is not finished yet. +// It can work already, but I still do not like some +// things of that new multivolume format. +// So please keep it commented. + +#ifdef _7Z_VOL +extern Byte kFinishSignature[kSignatureSize]; +#endif + +struct CArchiveVersion +{ + Byte Major; + Byte Minor; +}; + +const Byte kMajorVersion = 0; + +struct CStartHeader +{ + UInt64 NextHeaderOffset; + UInt64 NextHeaderSize; + UInt32 NextHeaderCRC; +}; + +const UInt32 kStartHeaderSize = 20; + +#ifdef _7Z_VOL +struct CFinishHeader: public CStartHeader +{ + UInt64 ArchiveStartOffset; // data offset from end if that struct + UInt64 AdditionalStartBlockSize; // start signature & start header size +}; + +const UInt32 kFinishHeaderSize = kStartHeaderSize + 16; +#endif + +namespace NID +{ + enum EEnum + { + kEnd, + + kHeader, + + kArchiveProperties, + + kAdditionalStreamsInfo, + kMainStreamsInfo, + kFilesInfo, + + kPackInfo, + kUnPackInfo, + kSubStreamsInfo, + + kSize, + kCRC, + + kFolder, + + kCodersUnPackSize, + kNumUnPackStream, + + kEmptyStream, + kEmptyFile, + kAnti, + + kName, + kCreationTime, + kLastAccessTime, + kLastWriteTime, + kWinAttributes, + kComment, + + kEncodedHeader, + + kStartPos + }; +} + +}} + +#endif diff --git a/CPP/7zip/Archive/7z/7zIn.cpp b/CPP/7zip/Archive/7z/7zIn.cpp new file mode 100755 index 00000000..53d78b1a --- /dev/null +++ b/CPP/7zip/Archive/7z/7zIn.cpp @@ -0,0 +1,1335 @@ +// 7zIn.cpp + +#include "StdAfx.h" + +#include "7zIn.h" +#include "7zMethods.h" +#include "7zDecode.h" +#include "../../Common/StreamObjects.h" +#include "../../Common/StreamUtils.h" +#include "../../../Common/CRC.h" + +// define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader +// #define FORMAT_7Z_RECOVERY + +namespace NArchive { +namespace N7z { + +class CStreamSwitch +{ + CInArchive *_archive; + bool _needRemove; +public: + CStreamSwitch(): _needRemove(false) {} + ~CStreamSwitch() { Remove(); } + void Remove(); + void Set(CInArchive *archive, const Byte *data, size_t size); + void Set(CInArchive *archive, const CByteBuffer &byteBuffer); + HRESULT Set(CInArchive *archive, const CObjectVector *dataVector); +}; + +void CStreamSwitch::Remove() +{ + if (_needRemove) + { + _archive->DeleteByteStream(); + _needRemove = false; + } +} + +void CStreamSwitch::Set(CInArchive *archive, const Byte *data, size_t size) +{ + Remove(); + _archive = archive; + _archive->AddByteStream(data, size); + _needRemove = true; +} + +void CStreamSwitch::Set(CInArchive *archive, const CByteBuffer &byteBuffer) +{ + Set(archive, byteBuffer, byteBuffer.GetCapacity()); +} + +HRESULT CStreamSwitch::Set(CInArchive *archive, const CObjectVector *dataVector) +{ + Remove(); + Byte external; + RINOK(archive->ReadByte(external)); + if (external != 0) + { + CNum dataIndex; + RINOK(archive->ReadNum(dataIndex)); + Set(archive, (*dataVector)[dataIndex]); + } + return S_OK; +} + + +CInArchiveException::CInArchiveException(CCauseType cause): + Cause(cause) +{} + +HRESULT CInArchive::ReadDirect(IInStream *stream, void *data, UInt32 size, + UInt32 *processedSize) +{ + UInt32 realProcessedSize; + HRESULT result = ReadStream(stream, data, size, &realProcessedSize); + if(processedSize != NULL) + *processedSize = realProcessedSize; + _position += realProcessedSize; + return result; +} + +HRESULT CInArchive::ReadDirect(void *data, UInt32 size, UInt32 *processedSize) +{ + return ReadDirect(_stream, data, size, processedSize); +} + +HRESULT CInArchive::SafeReadDirect(void *data, UInt32 size) +{ + UInt32 realProcessedSize; + RINOK(ReadDirect(data, size, &realProcessedSize)); + if (realProcessedSize != size) + throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); + return S_OK; +} + +HRESULT CInArchive::SafeReadDirectByte(Byte &b) +{ + return SafeReadDirect(&b, 1); +} + +HRESULT CInArchive::SafeReadDirectUInt32(UInt32 &value) +{ + value = 0; + for (int i = 0; i < 4; i++) + { + Byte b; + RINOK(SafeReadDirectByte(b)); + value |= (UInt32(b) << (8 * i)); + } + return S_OK; +} + +HRESULT CInArchive::SafeReadDirectUInt64(UInt64 &value) +{ + value = 0; + for (int i = 0; i < 8; i++) + { + Byte b; + RINOK(SafeReadDirectByte(b)); + value |= (UInt64(b) << (8 * i)); + } + return S_OK; +} + +HRESULT CInArchive::ReadNumber(UInt64 &value) +{ + Byte firstByte; + RINOK(ReadByte(firstByte)); + Byte mask = 0x80; + value = 0; + for (int i = 0; i < 8; i++) + { + if ((firstByte & mask) == 0) + { + UInt64 highPart = firstByte & (mask - 1); + value += (highPart << (i * 8)); + return S_OK; + } + Byte b; + RINOK(ReadByte(b)); + value |= (UInt64(b) << (8 * i)); + mask >>= 1; + } + return S_OK; +} + +HRESULT CInArchive::ReadNum(CNum &value) +{ + UInt64 value64; + RINOK(ReadNumber(value64)); + if (value64 > kNumMax) + return E_FAIL; + value = (CNum)value64; + return S_OK; +} + +HRESULT CInArchive::ReadUInt32(UInt32 &value) +{ + value = 0; + for (int i = 0; i < 4; i++) + { + Byte b; + RINOK(ReadByte(b)); + value |= (UInt32(b) << (8 * i)); + } + return S_OK; +} + +HRESULT CInArchive::ReadUInt64(UInt64 &value) +{ + value = 0; + for (int i = 0; i < 8; i++) + { + Byte b; + RINOK(ReadByte(b)); + value |= (UInt64(b) << (8 * i)); + } + return S_OK; +} + +static inline bool TestSignatureCandidate(const void *testBytes) +{ + for (int i = 0; i < kSignatureSize; i++) + if (((const Byte *)testBytes)[i] != kSignature[i]) + return false; + return true; +} + +#ifdef _7Z_VOL +static inline bool TestFinishSignatureCandidate(const void *testBytes) +{ + for (int i = 0; i < kSignatureSize; i++) + if (((const Byte *)testBytes)[i] != kFinishSignature[i]) + return false; + return true; +} +#endif + +HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit) +{ + _position = _arhiveBeginStreamPosition; + RINOK(stream->Seek(_arhiveBeginStreamPosition, STREAM_SEEK_SET, NULL)); + + Byte signature[kSignatureSize]; + UInt32 processedSize; + RINOK(ReadDirect(stream, signature, kSignatureSize, &processedSize)); + if(processedSize != kSignatureSize) + return S_FALSE; + if (TestSignatureCandidate(signature)) + return S_OK; + + CByteBuffer byteBuffer; + const UInt32 kBufferSize = (1 << 16); + byteBuffer.SetCapacity(kBufferSize); + Byte *buffer = byteBuffer; + UInt32 numPrevBytes = kSignatureSize - 1; + memmove(buffer, signature + 1, numPrevBytes); + UInt64 curTestPos = _arhiveBeginStreamPosition + 1; + for (;;) + { + if (searchHeaderSizeLimit != NULL) + if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit) + break; + UInt32 numReadBytes = kBufferSize - numPrevBytes; + RINOK(ReadDirect(stream, buffer + numPrevBytes, numReadBytes, &processedSize)); + UInt32 numBytesInBuffer = numPrevBytes + processedSize; + if (numBytesInBuffer < kSignatureSize) + break; + UInt32 numTests = numBytesInBuffer - kSignatureSize + 1; + for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++) + { + if (TestSignatureCandidate(buffer + pos)) + { + _arhiveBeginStreamPosition = curTestPos; + _position = curTestPos + kSignatureSize; + return stream->Seek(_position, STREAM_SEEK_SET, NULL); + } + } + numPrevBytes = numBytesInBuffer - numTests; + memmove(buffer, buffer + numTests, numPrevBytes); + } + return S_FALSE; +} + +// Out: _position must point to end of signature + +#ifdef _7Z_VOL +HRESULT CInArchive::FindFinishSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit) +{ + RINOK(stream->Seek(0, STREAM_SEEK_END, &_position)); + if (_position < kSignatureSize) + return S_FALSE; + + CByteBuffer byteBuffer; + const UInt32 kBufferSize = (1 << 18); + byteBuffer.SetCapacity(kBufferSize); + Byte *buffer = byteBuffer; + UInt32 numPrevBytes = 0; + UInt64 limitPos = 0; + if (searchHeaderSizeLimit != NULL) + if (*searchHeaderSizeLimit < _position) + limitPos = _position - *searchHeaderSizeLimit; + + while(_position >= limitPos) + { + UInt32 numReadBytes = kBufferSize - numPrevBytes; + if (numReadBytes > _position) + numReadBytes = (UInt32)_position; + UInt32 numBytesInBuffer = numPrevBytes + numReadBytes; + if (numBytesInBuffer < kSignatureSize) + return S_FALSE; + _position -= numReadBytes; + RINOK(stream->Seek(_position, STREAM_SEEK_SET, &_position)); + UInt32 startPos = kBufferSize - numBytesInBuffer; + UInt32 processedSize; + RINOK(ReadDirect(stream, buffer + startPos, numReadBytes, &processedSize)); + if (processedSize != numReadBytes) + return S_FALSE; + _position -= processedSize; + for(UInt32 pos = kBufferSize; pos >= startPos + kSignatureSize; pos--) + { + if (TestFinishSignatureCandidate(buffer + pos - kSignatureSize)) + { + _position += pos - startPos; + return stream->Seek(_position, STREAM_SEEK_SET, NULL); + } + } + numPrevBytes = kSignatureSize - 1; + memmove(buffer + kBufferSize - numPrevBytes, buffer + startPos + 1, numPrevBytes); + } + return S_FALSE; +} +#endif + +// S_FALSE means that file is not archive +HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit) +{ + Close(); + RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition)) + _position = _arhiveBeginStreamPosition; + #ifdef _7Z_VOL + HRESULT result = FindFinishSignature(stream, searchHeaderSizeLimit); + if (result == S_OK) + _finishSignature = true; + else + { + if (result != S_FALSE) + return result; + _finishSignature = false; + RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit)); + } + #else + RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit)); + #endif + _stream = stream; + return S_OK; +} + +void CInArchive::Close() +{ + _stream.Release(); +} + +HRESULT CInArchive::SkeepData(UInt64 size) +{ + for (UInt64 i = 0; i < size; i++) + { + Byte temp; + RINOK(ReadByte(temp)); + } + return S_OK; +} + +HRESULT CInArchive::SkeepData() +{ + UInt64 size; + RINOK(ReadNumber(size)); + return SkeepData(size); +} + +HRESULT CInArchive::ReadArchiveProperties(CInArchiveInfo & /* archiveInfo */) +{ + for (;;) + { + UInt64 type; + RINOK(ReadID(type)); + if (type == NID::kEnd) + break; + SkeepData(); + } + return S_OK; +} + +HRESULT CInArchive::GetNextFolderItem(CFolder &folder) +{ + CNum numCoders; + RINOK(ReadNum(numCoders)); + + folder.Coders.Clear(); + folder.Coders.Reserve((int)numCoders); + CNum numInStreams = 0; + CNum numOutStreams = 0; + CNum i; + for (i = 0; i < numCoders; i++) + { + folder.Coders.Add(CCoderInfo()); + CCoderInfo &coder = folder.Coders.Back(); + + for (;;) + { + coder.AltCoders.Add(CAltCoderInfo()); + CAltCoderInfo &altCoder = coder.AltCoders.Back(); + Byte mainByte = 0; + RINOK(ReadByte(mainByte)); + altCoder.MethodID.IDSize = (Byte)(mainByte & 0xF); + RINOK(ReadBytes(altCoder.MethodID.ID, altCoder.MethodID.IDSize)); + if ((mainByte & 0x10) != 0) + { + RINOK(ReadNum(coder.NumInStreams)); + RINOK(ReadNum(coder.NumOutStreams)); + } + else + { + coder.NumInStreams = 1; + coder.NumOutStreams = 1; + } + if ((mainByte & 0x20) != 0) + { + CNum propertiesSize = 0; + RINOK(ReadNum(propertiesSize)); + altCoder.Properties.SetCapacity((size_t)propertiesSize); + RINOK(ReadBytes((Byte *)altCoder.Properties, (size_t)propertiesSize)); + } + if ((mainByte & 0x80) == 0) + break; + } + numInStreams += coder.NumInStreams; + numOutStreams += coder.NumOutStreams; + } + + CNum numBindPairs; + // RINOK(ReadNumber(numBindPairs)); + numBindPairs = numOutStreams - 1; + folder.BindPairs.Clear(); + folder.BindPairs.Reserve(numBindPairs); + for (i = 0; i < numBindPairs; i++) + { + CBindPair bindPair; + RINOK(ReadNum(bindPair.InIndex)); + RINOK(ReadNum(bindPair.OutIndex)); + folder.BindPairs.Add(bindPair); + } + + CNum numPackedStreams = numInStreams - numBindPairs; + folder.PackStreams.Reserve(numPackedStreams); + if (numPackedStreams == 1) + { + for (CNum j = 0; j < numInStreams; j++) + if (folder.FindBindPairForInStream(j) < 0) + { + folder.PackStreams.Add(j); + break; + } + } + else + for(i = 0; i < numPackedStreams; i++) + { + CNum packStreamInfo; + RINOK(ReadNum(packStreamInfo)); + folder.PackStreams.Add(packStreamInfo); + } + + return S_OK; +} + +HRESULT CInArchive::WaitAttribute(UInt64 attribute) +{ + for (;;) + { + UInt64 type; + RINOK(ReadID(type)); + if (type == attribute) + return S_OK; + if (type == NID::kEnd) + return S_FALSE; + RINOK(SkeepData()); + } +} + +HRESULT CInArchive::ReadHashDigests(int numItems, + CRecordVector &digestsDefined, + CRecordVector &digests) +{ + RINOK(ReadBoolVector2(numItems, digestsDefined)); + digests.Clear(); + digests.Reserve(numItems); + for(int i = 0; i < numItems; i++) + { + UInt32 crc = 0; + if (digestsDefined[i]) + RINOK(ReadUInt32(crc)); + digests.Add(crc); + } + return S_OK; +} + +HRESULT CInArchive::ReadPackInfo( + UInt64 &dataOffset, + CRecordVector &packSizes, + CRecordVector &packCRCsDefined, + CRecordVector &packCRCs) +{ + RINOK(ReadNumber(dataOffset)); + CNum numPackStreams; + RINOK(ReadNum(numPackStreams)); + + RINOK(WaitAttribute(NID::kSize)); + packSizes.Clear(); + packSizes.Reserve(numPackStreams); + for(CNum i = 0; i < numPackStreams; i++) + { + UInt64 size; + RINOK(ReadNumber(size)); + packSizes.Add(size); + } + + UInt64 type; + for (;;) + { + RINOK(ReadID(type)); + if (type == NID::kEnd) + break; + if (type == NID::kCRC) + { + RINOK(ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs)); + continue; + } + RINOK(SkeepData()); + } + if (packCRCsDefined.IsEmpty()) + { + packCRCsDefined.Reserve(numPackStreams); + packCRCsDefined.Clear(); + packCRCs.Reserve(numPackStreams); + packCRCs.Clear(); + for(CNum i = 0; i < numPackStreams; i++) + { + packCRCsDefined.Add(false); + packCRCs.Add(0); + } + } + return S_OK; +} + +HRESULT CInArchive::ReadUnPackInfo( + const CObjectVector *dataVector, + CObjectVector &folders) +{ + RINOK(WaitAttribute(NID::kFolder)); + CNum numFolders; + RINOK(ReadNum(numFolders)); + + { + CStreamSwitch streamSwitch; + RINOK(streamSwitch.Set(this, dataVector)); + folders.Clear(); + folders.Reserve((UInt32)numFolders); + for(CNum i = 0; i < numFolders; i++) + { + folders.Add(CFolder()); + RINOK(GetNextFolderItem(folders.Back())); + } + } + + RINOK(WaitAttribute(NID::kCodersUnPackSize)); + + CNum i; + for(i = 0; i < numFolders; i++) + { + CFolder &folder = folders[i]; + CNum numOutStreams = folder.GetNumOutStreams(); + folder.UnPackSizes.Reserve(numOutStreams); + for(CNum j = 0; j < numOutStreams; j++) + { + UInt64 unPackSize; + RINOK(ReadNumber(unPackSize)); + folder.UnPackSizes.Add(unPackSize); + } + } + + for (;;) + { + UInt64 type; + RINOK(ReadID(type)); + if (type == NID::kEnd) + return S_OK; + if (type == NID::kCRC) + { + CRecordVector crcsDefined; + CRecordVector crcs; + RINOK(ReadHashDigests(numFolders, crcsDefined, crcs)); + for(i = 0; i < numFolders; i++) + { + CFolder &folder = folders[i]; + folder.UnPackCRCDefined = crcsDefined[i]; + folder.UnPackCRC = crcs[i]; + } + continue; + } + RINOK(SkeepData()); + } +} + +HRESULT CInArchive::ReadSubStreamsInfo( + const CObjectVector &folders, + CRecordVector &numUnPackStreamsInFolders, + CRecordVector &unPackSizes, + CRecordVector &digestsDefined, + CRecordVector &digests) +{ + numUnPackStreamsInFolders.Clear(); + numUnPackStreamsInFolders.Reserve(folders.Size()); + UInt64 type; + for (;;) + { + RINOK(ReadID(type)); + if (type == NID::kNumUnPackStream) + { + for(int i = 0; i < folders.Size(); i++) + { + CNum value; + RINOK(ReadNum(value)); + numUnPackStreamsInFolders.Add(value); + } + continue; + } + if (type == NID::kCRC || type == NID::kSize) + break; + if (type == NID::kEnd) + break; + RINOK(SkeepData()); + } + + if (numUnPackStreamsInFolders.IsEmpty()) + for(int i = 0; i < folders.Size(); i++) + numUnPackStreamsInFolders.Add(1); + + int i; + for(i = 0; i < numUnPackStreamsInFolders.Size(); i++) + { + // v3.13 incorrectly worked with empty folders + // v4.07: we check that folder is empty + CNum numSubstreams = numUnPackStreamsInFolders[i]; + if (numSubstreams == 0) + continue; + UInt64 sum = 0; + for (CNum j = 1; j < numSubstreams; j++) + { + UInt64 size; + if (type == NID::kSize) + { + RINOK(ReadNumber(size)); + unPackSizes.Add(size); + sum += size; + } + } + unPackSizes.Add(folders[i].GetUnPackSize() - sum); + } + if (type == NID::kSize) + { + RINOK(ReadID(type)); + } + + int numDigests = 0; + int numDigestsTotal = 0; + for(i = 0; i < folders.Size(); i++) + { + CNum numSubstreams = numUnPackStreamsInFolders[i]; + if (numSubstreams != 1 || !folders[i].UnPackCRCDefined) + numDigests += numSubstreams; + numDigestsTotal += numSubstreams; + } + + for (;;) + { + if (type == NID::kCRC) + { + CRecordVector digestsDefined2; + CRecordVector digests2; + RINOK(ReadHashDigests(numDigests, digestsDefined2, digests2)); + int digestIndex = 0; + for (i = 0; i < folders.Size(); i++) + { + CNum numSubstreams = numUnPackStreamsInFolders[i]; + const CFolder &folder = folders[i]; + if (numSubstreams == 1 && folder.UnPackCRCDefined) + { + digestsDefined.Add(true); + digests.Add(folder.UnPackCRC); + } + else + for (CNum j = 0; j < numSubstreams; j++, digestIndex++) + { + digestsDefined.Add(digestsDefined2[digestIndex]); + digests.Add(digests2[digestIndex]); + } + } + } + else if (type == NID::kEnd) + { + if (digestsDefined.IsEmpty()) + { + digestsDefined.Clear(); + digests.Clear(); + for (int i = 0; i < numDigestsTotal; i++) + { + digestsDefined.Add(false); + digests.Add(0); + } + } + return S_OK; + } + else + { + RINOK(SkeepData()); + } + RINOK(ReadID(type)); + } +} + +HRESULT CInArchive::ReadStreamsInfo( + const CObjectVector *dataVector, + UInt64 &dataOffset, + CRecordVector &packSizes, + CRecordVector &packCRCsDefined, + CRecordVector &packCRCs, + CObjectVector &folders, + CRecordVector &numUnPackStreamsInFolders, + CRecordVector &unPackSizes, + CRecordVector &digestsDefined, + CRecordVector &digests) +{ + for (;;) + { + UInt64 type; + RINOK(ReadID(type)); + switch(type) + { + case NID::kEnd: + return S_OK; + case NID::kPackInfo: + { + RINOK(ReadPackInfo(dataOffset, packSizes, + packCRCsDefined, packCRCs)); + break; + } + case NID::kUnPackInfo: + { + RINOK(ReadUnPackInfo(dataVector, folders)); + break; + } + case NID::kSubStreamsInfo: + { + RINOK(ReadSubStreamsInfo(folders, numUnPackStreamsInFolders, + unPackSizes, digestsDefined, digests)); + break; + } + } + } +} + +HRESULT CInArchive::ReadFileNames(CObjectVector &files) +{ + for(int i = 0; i < files.Size(); i++) + { + UString &name = files[i].Name; + name.Empty(); + for (;;) + { + wchar_t c; + RINOK(ReadWideCharLE(c)); + if (c == L'\0') + break; + name += c; + } + } + return S_OK; +} + +HRESULT CInArchive::ReadBoolVector(int numItems, CBoolVector &v) +{ + v.Clear(); + v.Reserve(numItems); + Byte b = 0; + Byte mask = 0; + for(int i = 0; i < numItems; i++) + { + if (mask == 0) + { + RINOK(ReadByte(b)); + mask = 0x80; + } + v.Add((b & mask) != 0); + mask >>= 1; + } + return S_OK; +} + +HRESULT CInArchive::ReadBoolVector2(int numItems, CBoolVector &v) +{ + Byte allAreDefined; + RINOK(ReadByte(allAreDefined)); + if (allAreDefined == 0) + return ReadBoolVector(numItems, v); + v.Clear(); + v.Reserve(numItems); + for (int i = 0; i < numItems; i++) + v.Add(true); + return S_OK; +} + +HRESULT CInArchive::ReadTime(const CObjectVector &dataVector, + CObjectVector &files, UInt64 type) +{ + CBoolVector boolVector; + RINOK(ReadBoolVector2(files.Size(), boolVector)) + + CStreamSwitch streamSwitch; + RINOK(streamSwitch.Set(this, &dataVector)); + + for(int i = 0; i < files.Size(); i++) + { + CFileItem &file = files[i]; + CArchiveFileTime fileTime; + fileTime.dwLowDateTime = 0; + fileTime.dwHighDateTime = 0; + bool defined = boolVector[i]; + if (defined) + { + UInt32 low, high; + RINOK(ReadUInt32(low)); + RINOK(ReadUInt32(high)); + fileTime.dwLowDateTime = low; + fileTime.dwHighDateTime = high; + } + switch(type) + { + case NID::kCreationTime: + file.IsCreationTimeDefined = defined; + if (defined) + file.CreationTime = fileTime; + break; + case NID::kLastWriteTime: + file.IsLastWriteTimeDefined = defined; + if (defined) + file.LastWriteTime = fileTime; + break; + case NID::kLastAccessTime: + file.IsLastAccessTimeDefined = defined; + if (defined) + file.LastAccessTime = fileTime; + break; + } + } + return S_OK; +} + +HRESULT CInArchive::ReadAndDecodePackedStreams(UInt64 baseOffset, + UInt64 &dataOffset, CObjectVector &dataVector + #ifndef _NO_CRYPTO + , ICryptoGetTextPassword *getTextPassword + #endif + ) +{ + CRecordVector packSizes; + CRecordVector packCRCsDefined; + CRecordVector packCRCs; + CObjectVector folders; + + CRecordVector numUnPackStreamsInFolders; + CRecordVector unPackSizes; + CRecordVector digestsDefined; + CRecordVector digests; + + RINOK(ReadStreamsInfo(NULL, + dataOffset, + packSizes, + packCRCsDefined, + packCRCs, + folders, + numUnPackStreamsInFolders, + unPackSizes, + digestsDefined, + digests)); + + // database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader; + + CNum packIndex = 0; + CDecoder decoder( + #ifdef _ST_MODE + false + #else + true + #endif + ); + UInt64 dataStartPos = baseOffset + dataOffset; + for(int i = 0; i < folders.Size(); i++) + { + const CFolder &folder = folders[i]; + dataVector.Add(CByteBuffer()); + CByteBuffer &data = dataVector.Back(); + UInt64 unPackSize = folder.GetUnPackSize(); + if (unPackSize > kNumMax) + return E_FAIL; + if (unPackSize > 0xFFFFFFFF) + return E_FAIL; + data.SetCapacity((size_t)unPackSize); + + CSequentialOutStreamImp2 *outStreamSpec = new CSequentialOutStreamImp2; + CMyComPtr outStream = outStreamSpec; + outStreamSpec->Init(data, (size_t)unPackSize); + + HRESULT result = decoder.Decode(_stream, dataStartPos, + &packSizes[packIndex], folder, outStream, NULL + #ifndef _NO_CRYPTO + , getTextPassword + #endif + #ifdef COMPRESS_MT + , false, 1 + #endif + ); + RINOK(result); + + if (folder.UnPackCRCDefined) + if (!CCRC::VerifyDigest(folder.UnPackCRC, data, (UInt32)unPackSize)) + throw CInArchiveException(CInArchiveException::kIncorrectHeader); + for (int j = 0; j < folder.PackStreams.Size(); j++) + dataStartPos += packSizes[packIndex++]; + } + return S_OK; +} + +HRESULT CInArchive::ReadHeader(CArchiveDatabaseEx &database + #ifndef _NO_CRYPTO + , ICryptoGetTextPassword *getTextPassword + #endif + ) +{ + UInt64 type; + RINOK(ReadID(type)); + + if (type == NID::kArchiveProperties) + { + RINOK(ReadArchiveProperties(database.ArchiveInfo)); + RINOK(ReadID(type)); + } + + CObjectVector dataVector; + + if (type == NID::kAdditionalStreamsInfo) + { + HRESULT result = ReadAndDecodePackedStreams( + database.ArchiveInfo.StartPositionAfterHeader, + database.ArchiveInfo.DataStartPosition2, + dataVector + #ifndef _NO_CRYPTO + , getTextPassword + #endif + ); + RINOK(result); + database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader; + RINOK(ReadID(type)); + } + + CRecordVector unPackSizes; + CRecordVector digestsDefined; + CRecordVector digests; + + if (type == NID::kMainStreamsInfo) + { + RINOK(ReadStreamsInfo(&dataVector, + database.ArchiveInfo.DataStartPosition, + database.PackSizes, + database.PackCRCsDefined, + database.PackCRCs, + database.Folders, + database.NumUnPackStreamsVector, + unPackSizes, + digestsDefined, + digests)); + database.ArchiveInfo.DataStartPosition += database.ArchiveInfo.StartPositionAfterHeader; + RINOK(ReadID(type)); + } + else + { + for(int i = 0; i < database.Folders.Size(); i++) + { + database.NumUnPackStreamsVector.Add(1); + CFolder &folder = database.Folders[i]; + unPackSizes.Add(folder.GetUnPackSize()); + digestsDefined.Add(folder.UnPackCRCDefined); + digests.Add(folder.UnPackCRC); + } + } + + database.Files.Clear(); + + if (type == NID::kEnd) + return S_OK; + if (type != NID::kFilesInfo) + throw CInArchiveException(CInArchiveException::kIncorrectHeader); + + CNum numFiles; + RINOK(ReadNum(numFiles)); + database.Files.Reserve(numFiles); + CNum i; + for(i = 0; i < numFiles; i++) + database.Files.Add(CFileItem()); + + database.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize); + if (!database.PackSizes.IsEmpty()) + database.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo); + if (numFiles > 0 && !digests.IsEmpty()) + database.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC); + + CBoolVector emptyStreamVector; + emptyStreamVector.Reserve((int)numFiles); + for(i = 0; i < numFiles; i++) + emptyStreamVector.Add(false); + CBoolVector emptyFileVector; + CBoolVector antiFileVector; + CNum numEmptyStreams = 0; + + // int sizePrev = -1; + // int posPrev = 0; + + for (;;) + { + /* + if (sizePrev >= 0) + if (sizePrev != _inByteBack->GetProcessedSize() - posPrev) + throw 2; + */ + UInt64 type; + RINOK(ReadID(type)); + if (type == NID::kEnd) + break; + UInt64 size; + RINOK(ReadNumber(size)); + + // sizePrev = size; + // posPrev = _inByteBack->GetProcessedSize(); + + database.ArchiveInfo.FileInfoPopIDs.Add(type); + switch(type) + { + case NID::kName: + { + CStreamSwitch streamSwitch; + RINOK(streamSwitch.Set(this, &dataVector)); + RINOK(ReadFileNames(database.Files)) + break; + } + case NID::kWinAttributes: + { + CBoolVector boolVector; + RINOK(ReadBoolVector2(database.Files.Size(), boolVector)) + CStreamSwitch streamSwitch; + RINOK(streamSwitch.Set(this, &dataVector)); + for(i = 0; i < numFiles; i++) + { + CFileItem &file = database.Files[i]; + file.AreAttributesDefined = boolVector[i]; + if (file.AreAttributesDefined) + { + RINOK(ReadUInt32(file.Attributes)); + } + } + break; + } + case NID::kStartPos: + { + CBoolVector boolVector; + RINOK(ReadBoolVector2(database.Files.Size(), boolVector)) + CStreamSwitch streamSwitch; + RINOK(streamSwitch.Set(this, &dataVector)); + for(i = 0; i < numFiles; i++) + { + CFileItem &file = database.Files[i]; + file.IsStartPosDefined = boolVector[i]; + if (file.IsStartPosDefined) + { + RINOK(ReadUInt64(file.StartPos)); + } + } + break; + } + case NID::kEmptyStream: + { + RINOK(ReadBoolVector(numFiles, emptyStreamVector)) + for (i = 0; i < (CNum)emptyStreamVector.Size(); i++) + if (emptyStreamVector[i]) + numEmptyStreams++; + emptyFileVector.Reserve(numEmptyStreams); + antiFileVector.Reserve(numEmptyStreams); + for (i = 0; i < numEmptyStreams; i++) + { + emptyFileVector.Add(false); + antiFileVector.Add(false); + } + break; + } + case NID::kEmptyFile: + { + RINOK(ReadBoolVector(numEmptyStreams, emptyFileVector)) + break; + } + case NID::kAnti: + { + RINOK(ReadBoolVector(numEmptyStreams, antiFileVector)) + break; + } + case NID::kCreationTime: + case NID::kLastWriteTime: + case NID::kLastAccessTime: + { + RINOK(ReadTime(dataVector, database.Files, type)) + break; + } + default: + { + database.ArchiveInfo.FileInfoPopIDs.DeleteBack(); + RINOK(SkeepData(size)); + } + } + } + + CNum emptyFileIndex = 0; + CNum sizeIndex = 0; + for(i = 0; i < numFiles; i++) + { + CFileItem &file = database.Files[i]; + file.HasStream = !emptyStreamVector[i]; + if(file.HasStream) + { + file.IsDirectory = false; + file.IsAnti = false; + file.UnPackSize = unPackSizes[sizeIndex]; + file.FileCRC = digests[sizeIndex]; + file.IsFileCRCDefined = digestsDefined[sizeIndex]; + sizeIndex++; + } + else + { + file.IsDirectory = !emptyFileVector[emptyFileIndex]; + file.IsAnti = antiFileVector[emptyFileIndex]; + emptyFileIndex++; + file.UnPackSize = 0; + file.IsFileCRCDefined = false; + } + } + return S_OK; +} + + +void CArchiveDatabaseEx::FillFolderStartPackStream() +{ + FolderStartPackStreamIndex.Clear(); + FolderStartPackStreamIndex.Reserve(Folders.Size()); + CNum startPos = 0; + for(int i = 0; i < Folders.Size(); i++) + { + FolderStartPackStreamIndex.Add(startPos); + startPos += (CNum)Folders[i].PackStreams.Size(); + } +} + +void CArchiveDatabaseEx::FillStartPos() +{ + PackStreamStartPositions.Clear(); + PackStreamStartPositions.Reserve(PackSizes.Size()); + UInt64 startPos = 0; + for(int i = 0; i < PackSizes.Size(); i++) + { + PackStreamStartPositions.Add(startPos); + startPos += PackSizes[i]; + } +} + +void CArchiveDatabaseEx::FillFolderStartFileIndex() +{ + FolderStartFileIndex.Clear(); + FolderStartFileIndex.Reserve(Folders.Size()); + FileIndexToFolderIndexMap.Clear(); + FileIndexToFolderIndexMap.Reserve(Files.Size()); + + int folderIndex = 0; + CNum indexInFolder = 0; + for (int i = 0; i < Files.Size(); i++) + { + const CFileItem &file = Files[i]; + bool emptyStream = !file.HasStream; + if (emptyStream && indexInFolder == 0) + { + FileIndexToFolderIndexMap.Add(kNumNoIndex); + continue; + } + if (indexInFolder == 0) + { + // v3.13 incorrectly worked with empty folders + // v4.07: Loop for skipping empty folders + for (;;) + { + if (folderIndex >= Folders.Size()) + throw CInArchiveException(CInArchiveException::kIncorrectHeader); + FolderStartFileIndex.Add(i); // check it + if (NumUnPackStreamsVector[folderIndex] != 0) + break; + folderIndex++; + } + } + FileIndexToFolderIndexMap.Add(folderIndex); + if (emptyStream) + continue; + indexInFolder++; + if (indexInFolder >= NumUnPackStreamsVector[folderIndex]) + { + folderIndex++; + indexInFolder = 0; + } + } +} + +HRESULT CInArchive::ReadDatabase(CArchiveDatabaseEx &database + #ifndef _NO_CRYPTO + , ICryptoGetTextPassword *getTextPassword + #endif + ) +{ + database.Clear(); + database.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition; + + + RINOK(SafeReadDirect(&database.ArchiveInfo.Version.Major, 1)); + RINOK(SafeReadDirect(&database.ArchiveInfo.Version.Minor, 1)); + if (database.ArchiveInfo.Version.Major != kMajorVersion) + throw CInArchiveException(CInArchiveException::kUnsupportedVersion); + + #ifdef _7Z_VOL + if (_finishSignature) + { + RINOK(_stream->Seek(_position - (4 + kFinishHeaderSize) - + (kSignatureSize + 2), STREAM_SEEK_SET, &_position)); + } + #endif + + UInt32 crcFromArchive; + UInt64 nextHeaderOffset; + UInt64 nextHeaderSize; + UInt32 nextHeaderCRC; + CCRC crc; + RINOK(SafeReadDirectUInt32(crcFromArchive)); + RINOK(SafeReadDirectUInt64(nextHeaderOffset)); + RINOK(SafeReadDirectUInt64(nextHeaderSize)); + RINOK(SafeReadDirectUInt32(nextHeaderCRC)); + + #ifdef FORMAT_7Z_RECOVERY + if (crcFromArchive == 0 && nextHeaderOffset == 0 && nextHeaderSize == 0 && nextHeaderCRC == 0) + { + UInt64 cur, cur2; + RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &cur)); + const int kCheckSize = 500; + Byte buf[kCheckSize]; + RINOK(_stream->Seek(0, STREAM_SEEK_END, &cur2)); + int checkSize = kCheckSize; + if (cur2 - cur < kCheckSize) + checkSize = (int)(cur2 - cur); + RINOK(_stream->Seek(-checkSize, STREAM_SEEK_END, &cur2)); + + UInt32 realProcessedSize; + RINOK(ReadDirect(buf, (UInt32)kCheckSize, &realProcessedSize)); + + int i; + for (i = (int)realProcessedSize - 2; i >= 0; i--) + if (buf[i] == 0x17 && buf[i + 1] == 0x6 || buf[i] == 0x01 && buf[i + 1] == 0x04) + break; + if (i < 0) + return S_FALSE; + nextHeaderSize = realProcessedSize - i; + nextHeaderOffset = cur2 - cur + i; + nextHeaderCRC = CCRC::CalculateDigest(buf + i, (size_t)nextHeaderSize); + RINOK(_stream->Seek(cur, STREAM_SEEK_SET, &_position)); + } + #endif + + crc.UpdateUInt64(nextHeaderOffset); + crc.UpdateUInt64(nextHeaderSize); + crc.UpdateUInt32(nextHeaderCRC); + + #ifdef FORMAT_7Z_RECOVERY + crcFromArchive = crc.GetDigest(); + #endif + + #ifdef _7Z_VOL + UInt64 archiveStartOffset; // data offset from end if that struct + UInt64 additionalStartBlockSize; // start signature & start header size + if (_finishSignature) + { + RINOK(SafeReadDirectUInt64(archiveStartOffset)); + crc.UpdateUInt64(archiveStartOffset); + RINOK(SafeReadDirectUInt64(additionalStartBlockSize)); + crc.UpdateUInt64(additionalStartBlockSize); + database.ArchiveInfo.StartPositionAfterHeader = _position + archiveStartOffset; + } + else + #endif + { + database.ArchiveInfo.StartPositionAfterHeader = _position; + } + if (crc.GetDigest() != crcFromArchive) + throw CInArchiveException(CInArchiveException::kIncorrectHeader); + + if (nextHeaderSize == 0) + return S_OK; + + if (nextHeaderSize >= 0xFFFFFFFF) + return E_FAIL; + + RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, &_position)); + + CByteBuffer buffer2; + buffer2.SetCapacity((size_t)nextHeaderSize); + RINOK(SafeReadDirect(buffer2, (UInt32)nextHeaderSize)); + if (!CCRC::VerifyDigest(nextHeaderCRC, buffer2, (UInt32)nextHeaderSize)) + throw CInArchiveException(CInArchiveException::kIncorrectHeader); + + CStreamSwitch streamSwitch; + streamSwitch.Set(this, buffer2); + + CObjectVector dataVector; + + for (;;) + { + UInt64 type; + RINOK(ReadID(type)); + if (type == NID::kHeader) + break; + if (type != NID::kEncodedHeader) + throw CInArchiveException(CInArchiveException::kIncorrectHeader); + HRESULT result = ReadAndDecodePackedStreams( + database.ArchiveInfo.StartPositionAfterHeader, + database.ArchiveInfo.DataStartPosition2, + dataVector + #ifndef _NO_CRYPTO + , getTextPassword + #endif + ); + RINOK(result); + if (dataVector.Size() == 0) + return S_OK; + if (dataVector.Size() > 1) + throw CInArchiveException(CInArchiveException::kIncorrectHeader); + streamSwitch.Remove(); + streamSwitch.Set(this, dataVector.Front()); + } + + return ReadHeader(database + #ifndef _NO_CRYPTO + , getTextPassword + #endif + ); +} + +}} diff --git a/CPP/7zip/Archive/7z/7zIn.h b/CPP/7zip/Archive/7z/7zIn.h new file mode 100755 index 00000000..4f27aa75 --- /dev/null +++ b/CPP/7zip/Archive/7z/7zIn.h @@ -0,0 +1,288 @@ +// 7zIn.h + +#ifndef __7Z_IN_H +#define __7Z_IN_H + +#include "../../IStream.h" +#include "../../IPassword.h" +#include "../../../Common/MyCom.h" +#include "../../Common/InBuffer.h" + +#include "7zHeader.h" +#include "7zItem.h" + +namespace NArchive { +namespace N7z { + +class CInArchiveException +{ +public: + enum CCauseType + { + kUnsupportedVersion = 0, + kUnexpectedEndOfArchive = 0, + kIncorrectHeader, + } Cause; + CInArchiveException(CCauseType cause); +}; + +struct CInArchiveInfo +{ + CArchiveVersion Version; + UInt64 StartPosition; + UInt64 StartPositionAfterHeader; + UInt64 DataStartPosition; + UInt64 DataStartPosition2; + CRecordVector FileInfoPopIDs; + void Clear() + { + FileInfoPopIDs.Clear(); + } +}; + + +struct CArchiveDatabaseEx: public CArchiveDatabase +{ + CInArchiveInfo ArchiveInfo; + CRecordVector PackStreamStartPositions; + CRecordVector FolderStartPackStreamIndex; + CRecordVector FolderStartFileIndex; + CRecordVector FileIndexToFolderIndexMap; + + void Clear() + { + CArchiveDatabase::Clear(); + ArchiveInfo.Clear(); + PackStreamStartPositions.Clear(); + FolderStartPackStreamIndex.Clear(); + FolderStartFileIndex.Clear(); + FileIndexToFolderIndexMap.Clear(); + } + + void FillFolderStartPackStream(); + void FillStartPos(); + void FillFolderStartFileIndex(); + + void Fill() + { + FillFolderStartPackStream(); + FillStartPos(); + FillFolderStartFileIndex(); + } + + UInt64 GetFolderStreamPos(int folderIndex, int indexInFolder) const + { + return ArchiveInfo.DataStartPosition + + PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] + + indexInFolder]; + } + + UInt64 GetFolderFullPackSize(int folderIndex) const + { + CNum packStreamIndex = FolderStartPackStreamIndex[folderIndex]; + const CFolder &folder = Folders[folderIndex]; + UInt64 size = 0; + for (int i = 0; i < folder.PackStreams.Size(); i++) + size += PackSizes[packStreamIndex + i]; + return size; + } + + UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const + { + return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex]; + } + + UInt64 GetFilePackSize(CNum fileIndex) const + { + CNum folderIndex = FileIndexToFolderIndexMap[fileIndex]; + if (folderIndex >= 0) + { + if (FolderStartFileIndex[folderIndex] == fileIndex) + return GetFolderFullPackSize(folderIndex); + } + return 0; + } +}; + +class CInByte2 +{ + const Byte *_buffer; + size_t _size; + size_t _pos; +public: + void Init(const Byte *buffer, size_t size) + { + _buffer = buffer; + _size = size; + _pos = 0; + } + bool ReadByte(Byte &b) + { + if(_pos >= _size) + return false; + b = _buffer[_pos++]; + return true; + } + void ReadBytes(void *data, size_t size, size_t &processedSize) + { + for(processedSize = 0; processedSize < size && _pos < _size; processedSize++) + ((Byte *)data)[processedSize] = _buffer[_pos++]; + } + + bool ReadBytes(void *data, size_t size) + { + size_t processedSize; + ReadBytes(data, size, processedSize); + return (processedSize == size); + } + + size_t GetProcessedSize() const { return _pos; } +}; + +class CStreamSwitch; +class CInArchive +{ + friend class CStreamSwitch; + + CMyComPtr _stream; + #ifdef _7Z_VOL + bool _finishSignature; + #endif + + CObjectVector _inByteVector; + CInByte2 *_inByteBack; + + UInt64 _arhiveBeginStreamPosition; + UInt64 _position; + + void AddByteStream(const Byte *buffer, size_t size) + { + _inByteVector.Add(CInByte2()); + _inByteBack = &_inByteVector.Back(); + _inByteBack->Init(buffer, size); + } + + void DeleteByteStream() + { + _inByteVector.DeleteBack(); + if (!_inByteVector.IsEmpty()) + _inByteBack = &_inByteVector.Back(); + } + +private: + HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive + #ifdef _7Z_VOL + HRESULT FindFinishSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive + #endif + + HRESULT ReadFileNames(CObjectVector &files); + + HRESULT ReadDirect(IInStream *stream, void *data, UInt32 size, + UInt32 *processedSize); + HRESULT ReadDirect(void *data, UInt32 size, UInt32 *processedSize); + HRESULT SafeReadDirect(void *data, UInt32 size); + HRESULT SafeReadDirectByte(Byte &b); + HRESULT SafeReadDirectUInt32(UInt32 &value); + HRESULT SafeReadDirectUInt64(UInt64 &value); + + HRESULT ReadBytes(void *data, size_t size) + { + if (!_inByteBack->ReadBytes(data, size)) + return E_FAIL; + return S_OK; + } + + HRESULT ReadByte(Byte &b) + { + if (!_inByteBack->ReadByte(b)) + return E_FAIL; + return S_OK; + } + + HRESULT ReadWideCharLE(wchar_t &c) + { + Byte b1 = 0; + if (!_inByteBack->ReadByte(b1)) + return E_FAIL; + Byte b2 = 0; + if (!_inByteBack->ReadByte(b2)) + return E_FAIL; + c = (wchar_t)(((wchar_t)(b2) << 8) + b1); + return S_OK; + } + + HRESULT ReadNumber(UInt64 &value); + HRESULT ReadNum(CNum &value); + HRESULT ReadID(UInt64 &value) { return ReadNumber(value); } + HRESULT ReadUInt32(UInt32 &value); + HRESULT ReadUInt64(UInt64 &value); + + HRESULT SkeepData(UInt64 size); + HRESULT SkeepData(); + HRESULT WaitAttribute(UInt64 attribute); + + HRESULT ReadArchiveProperties(CInArchiveInfo &archiveInfo); + HRESULT GetNextFolderItem(CFolder &itemInfo); + HRESULT ReadHashDigests(int numItems, + CRecordVector &digestsDefined, CRecordVector &digests); + + HRESULT ReadPackInfo( + UInt64 &dataOffset, + CRecordVector &packSizes, + CRecordVector &packCRCsDefined, + CRecordVector &packCRCs); + + HRESULT ReadUnPackInfo( + const CObjectVector *dataVector, + CObjectVector &folders); + + HRESULT ReadSubStreamsInfo( + const CObjectVector &folders, + CRecordVector &numUnPackStreamsInFolders, + CRecordVector &unPackSizes, + CRecordVector &digestsDefined, + CRecordVector &digests); + + HRESULT ReadStreamsInfo( + const CObjectVector *dataVector, + UInt64 &dataOffset, + CRecordVector &packSizes, + CRecordVector &packCRCsDefined, + CRecordVector &packCRCs, + CObjectVector &folders, + CRecordVector &numUnPackStreamsInFolders, + CRecordVector &unPackSizes, + CRecordVector &digestsDefined, + CRecordVector &digests); + + + HRESULT GetNextFileItem(CFileItem &itemInfo); + HRESULT ReadBoolVector(int numItems, CBoolVector &v); + HRESULT ReadBoolVector2(int numItems, CBoolVector &v); + HRESULT ReadTime(const CObjectVector &dataVector, + CObjectVector &files, UInt64 type); + HRESULT ReadAndDecodePackedStreams(UInt64 baseOffset, UInt64 &dataOffset, + CObjectVector &dataVector + #ifndef _NO_CRYPTO + , ICryptoGetTextPassword *getTextPassword + #endif + ); + HRESULT ReadHeader(CArchiveDatabaseEx &database + #ifndef _NO_CRYPTO + ,ICryptoGetTextPassword *getTextPassword + #endif + ); +public: + HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive + void Close(); + + HRESULT ReadDatabase(CArchiveDatabaseEx &database + #ifndef _NO_CRYPTO + ,ICryptoGetTextPassword *getTextPassword + #endif + ); +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/7z/7zItem.h b/CPP/7zip/Archive/7z/7zItem.h new file mode 100755 index 00000000..08ea61f4 --- /dev/null +++ b/CPP/7zip/Archive/7z/7zItem.h @@ -0,0 +1,181 @@ +// 7zItem.h + +#ifndef __7Z_ITEM_H +#define __7Z_ITEM_H + +#include "../../../Common/Buffer.h" +#include "7zMethodID.h" +#include "7zHeader.h" + +namespace NArchive { +namespace N7z { + +struct CAltCoderInfo +{ + CMethodID MethodID; + CByteBuffer Properties; +}; + +typedef UInt32 CNum; +const CNum kNumMax = 0x7FFFFFFF; +const CNum kNumNoIndex = 0xFFFFFFFF; + +struct CCoderInfo +{ + CNum NumInStreams; + CNum NumOutStreams; + CObjectVector AltCoders; + bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); } +}; + +struct CBindPair +{ + CNum InIndex; + CNum OutIndex; +}; + +struct CFolder +{ + CObjectVector Coders; + CRecordVector BindPairs; + CRecordVector PackStreams; + CRecordVector UnPackSizes; + UInt32 UnPackCRC; + bool UnPackCRCDefined; + + CFolder(): UnPackCRCDefined(false) {} + + UInt64 GetUnPackSize() const // test it + { + if (UnPackSizes.IsEmpty()) + return 0; + for (int i = UnPackSizes.Size() - 1; i >= 0; i--) + if (FindBindPairForOutStream(i) < 0) + return UnPackSizes[i]; + throw 1; + } + + CNum GetNumOutStreams() const + { + CNum result = 0; + for (int i = 0; i < Coders.Size(); i++) + result += Coders[i].NumOutStreams; + return result; + } + + int FindBindPairForInStream(CNum inStreamIndex) const + { + for(int i = 0; i < BindPairs.Size(); i++) + if (BindPairs[i].InIndex == inStreamIndex) + return i; + return -1; + } + int FindBindPairForOutStream(CNum outStreamIndex) const + { + for(int i = 0; i < BindPairs.Size(); i++) + if (BindPairs[i].OutIndex == outStreamIndex) + return i; + return -1; + } + int FindPackStreamArrayIndex(CNum inStreamIndex) const + { + for(int i = 0; i < PackStreams.Size(); i++) + if (PackStreams[i] == inStreamIndex) + return i; + return -1; + } +}; + +typedef FILETIME CArchiveFileTime; + +class CFileItem +{ +public: + CArchiveFileTime CreationTime; + CArchiveFileTime LastWriteTime; + CArchiveFileTime LastAccessTime; + UInt64 UnPackSize; + UInt64 StartPos; + UInt32 Attributes; + UInt32 FileCRC; + UString Name; + + bool HasStream; // Test it !!! it means that there is + // stream in some folder. It can be empty stream + bool IsDirectory; + bool IsAnti; + bool IsFileCRCDefined; + bool AreAttributesDefined; + bool IsCreationTimeDefined; + bool IsLastWriteTimeDefined; + bool IsLastAccessTimeDefined; + bool IsStartPosDefined; + + /* + const bool HasStream() const { + return !IsDirectory && !IsAnti && UnPackSize != 0; } + */ + CFileItem(): + HasStream(true), + IsDirectory(false), + IsAnti(false), + IsFileCRCDefined(false), + AreAttributesDefined(false), + IsCreationTimeDefined(false), + IsLastWriteTimeDefined(false), + IsLastAccessTimeDefined(false), + IsStartPosDefined(false) + {} + void SetAttributes(UInt32 attributes) + { + AreAttributesDefined = true; + Attributes = attributes; + } + void SetCreationTime(const CArchiveFileTime &creationTime) + { + IsCreationTimeDefined = true; + CreationTime = creationTime; + } + void SetLastWriteTime(const CArchiveFileTime &lastWriteTime) + { + IsLastWriteTimeDefined = true; + LastWriteTime = lastWriteTime; + } + void SetLastAccessTime(const CArchiveFileTime &lastAccessTime) + { + IsLastAccessTimeDefined = true; + LastAccessTime = lastAccessTime; + } +}; + +struct CArchiveDatabase +{ + CRecordVector PackSizes; + CRecordVector PackCRCsDefined; + CRecordVector PackCRCs; + CObjectVector Folders; + CRecordVector NumUnPackStreamsVector; + CObjectVector Files; + void Clear() + { + PackSizes.Clear(); + PackCRCsDefined.Clear(); + PackCRCs.Clear(); + Folders.Clear(); + NumUnPackStreamsVector.Clear(); + Files.Clear(); + } + bool IsEmpty() const + { + return (PackSizes.IsEmpty() && + PackCRCsDefined.IsEmpty() && + PackCRCs.IsEmpty() && + Folders.IsEmpty() && + NumUnPackStreamsVector.IsEmpty() && + Files.IsEmpty()); + } +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/7z/7zMethodID.cpp b/CPP/7zip/Archive/7z/7zMethodID.cpp new file mode 100755 index 00000000..0d45b732 --- /dev/null +++ b/CPP/7zip/Archive/7z/7zMethodID.cpp @@ -0,0 +1,76 @@ +// 7zMethodID.cpp + +#include "StdAfx.h" + +#include "7zMethodID.h" + +namespace NArchive { +namespace N7z { + +static wchar_t GetHex(Byte value) +{ + return (wchar_t)((value < 10) ? ('0' + value) : ('A' + (value - 10))); +} + +static bool HexCharToInt(wchar_t value, Byte &result) +{ + if (value >= '0' && value <= '9') + result = (Byte)(value - '0'); + else if (value >= 'a' && value <= 'f') + result = (Byte)(10 + value - 'a'); + else if (value >= 'A' && value <= 'F') + result = (Byte)(10 + value - 'A'); + else + return false; + return true; +} + +static bool TwoHexCharsToInt(wchar_t valueHigh, wchar_t valueLow, Byte &result) +{ + Byte resultHigh, resultLow; + if (!HexCharToInt(valueHigh, resultHigh)) + return false; + if (!HexCharToInt(valueLow, resultLow)) + return false; + result = (Byte)((resultHigh << 4) + resultLow); + return true; +} + +UString CMethodID::ConvertToString() const +{ + UString result; + for (int i = 0; i < IDSize; i++) + { + Byte b = ID[i]; + result += GetHex((Byte)(b >> 4)); + result += GetHex((Byte)(b & 0xF)); + } + return result; +} + +bool CMethodID::ConvertFromString(const UString &srcString) +{ + int length = srcString.Length(); + if ((length & 1) != 0 || (length >> 1) > kMethodIDSize) + return false; + IDSize = (Byte)(length / 2); + UInt32 i; + for(i = 0; i < IDSize; i++) + if (!TwoHexCharsToInt(srcString[i * 2], srcString[i * 2 + 1], ID[i])) + return false; + for(; i < kMethodIDSize; i++) + ID[i] = 0; + return true; +} + +bool operator==(const CMethodID &a1, const CMethodID &a2) +{ + if (a1.IDSize != a2.IDSize) + return false; + for (UInt32 i = 0; i < a1.IDSize; i++) + if (a1.ID[i] != a2.ID[i]) + return false; + return true; +} + +}} diff --git a/CPP/7zip/Archive/7z/7zMethodID.h b/CPP/7zip/Archive/7z/7zMethodID.h new file mode 100755 index 00000000..54561054 --- /dev/null +++ b/CPP/7zip/Archive/7z/7zMethodID.h @@ -0,0 +1,29 @@ +// 7zMethodID.h + +#ifndef __7Z_METHOD_ID_H +#define __7Z_METHOD_ID_H + +#include "../../../Common/String.h" +#include "../../../Common/Types.h" + +namespace NArchive { +namespace N7z { + +const int kMethodIDSize = 15; + +struct CMethodID +{ + Byte ID[kMethodIDSize]; + Byte IDSize; + UString ConvertToString() const; + bool ConvertFromString(const UString &srcString); +}; + +bool operator==(const CMethodID &a1, const CMethodID &a2); + +inline bool operator!=(const CMethodID &a1, const CMethodID &a2) + { return !(a1 == a2); } + +}} + +#endif diff --git a/CPP/7zip/Archive/7z/7zMethods.cpp b/CPP/7zip/Archive/7z/7zMethods.cpp new file mode 100755 index 00000000..19270aa4 --- /dev/null +++ b/CPP/7zip/Archive/7z/7zMethods.cpp @@ -0,0 +1,174 @@ +// 7zMethods.cpp + +#include "StdAfx.h" + +#include "7zMethods.h" + +#include "../../../Windows/FileFind.h" +#include "../../../Windows/DLL.h" +#include "../../../Windows/PropVariant.h" +#include "../../../Windows/Synchronization.h" + +#include "../../ICoder.h" +#include "../Common/CodecsPath.h" + +using namespace NWindows; + +namespace NArchive { +namespace N7z { + +static CObjectVector g_Methods; +static bool g_Loaded = false; + +typedef UInt32 (WINAPI *GetNumberOfMethodsFunc)(UInt32 *numMethods); + +typedef UInt32 (WINAPI *GetMethodPropertyFunc)( + UInt32 index, PROPID propID, PROPVARIANT *value); + +static void Load(const CSysString &folderPrefix) +{ + NFile::NFind::CEnumerator enumerator(folderPrefix + CSysString(TEXT("*"))); + NFile::NFind::CFileInfo fileInfo; + while (enumerator.Next(fileInfo)) + { + if (fileInfo.IsDirectory()) + continue; + CSysString filePath = folderPrefix + fileInfo.Name; + { + NDLL::CLibrary library; + if (!library.LoadEx(filePath, LOAD_LIBRARY_AS_DATAFILE)) + continue; + } + NDLL::CLibrary library; + if (!library.Load(filePath)) + continue; + GetMethodPropertyFunc getMethodProperty = (GetMethodPropertyFunc) + library.GetProcAddress("GetMethodProperty"); + if (getMethodProperty == NULL) + continue; + + UInt32 numMethods = 1; + GetNumberOfMethodsFunc getNumberOfMethodsFunc = (GetNumberOfMethodsFunc) + library.GetProcAddress("GetNumberOfMethods"); + if (getNumberOfMethodsFunc != NULL) + if (getNumberOfMethodsFunc(&numMethods) != S_OK) + continue; + + for(UInt32 i = 0; i < numMethods; i++) + { + CMethodInfo2 info; + info.FilePath = filePath; + + NWindows::NCOM::CPropVariant propVariant; + if (getMethodProperty(i, NMethodPropID::kID, &propVariant) != S_OK) + continue; + if (propVariant.vt != VT_BSTR) + continue; + info.MethodID.IDSize = (Byte)SysStringByteLen(propVariant.bstrVal); + memmove(info.MethodID.ID, propVariant.bstrVal, info.MethodID.IDSize); + propVariant.Clear(); + + if (getMethodProperty(i, NMethodPropID::kName, &propVariant) != S_OK) + continue; + if (propVariant.vt == VT_EMPTY) + { + } + else if (propVariant.vt == VT_BSTR) + info.Name = propVariant.bstrVal; + else + continue; + propVariant.Clear(); + + if (getMethodProperty (i, NMethodPropID::kEncoder, &propVariant) != S_OK) + continue; + if (propVariant.vt == VT_EMPTY) + info.EncoderIsAssigned = false; + else if (propVariant.vt == VT_BSTR) + { + info.EncoderIsAssigned = true; + info.Encoder = *(const GUID *)propVariant.bstrVal; + } + else + continue; + propVariant.Clear(); + + if (getMethodProperty (i, NMethodPropID::kDecoder, &propVariant) != S_OK) + continue; + if (propVariant.vt == VT_EMPTY) + info.DecoderIsAssigned = false; + else if (propVariant.vt == VT_BSTR) + { + info.DecoderIsAssigned = true; + info.Decoder = *(const GUID *)propVariant.bstrVal; + } + else + continue; + propVariant.Clear(); + + if (getMethodProperty (i, NMethodPropID::kInStreams, &propVariant) != S_OK) + continue; + if (propVariant.vt == VT_EMPTY) + info.NumInStreams = 1; + else if (propVariant.vt == VT_UI4) + info.NumInStreams = propVariant.ulVal; + else + continue; + propVariant.Clear(); + + if (getMethodProperty (i, NMethodPropID::kOutStreams, &propVariant) != S_OK) + continue; + if (propVariant.vt == VT_EMPTY) + info.NumOutStreams = 1; + else if (propVariant.vt == VT_UI4) + info.NumOutStreams = propVariant.ulVal; + else + continue; + propVariant.Clear(); + + g_Methods.Add(info); + } + } +} + +static NSynchronization::CCriticalSection g_CriticalSection; + +void LoadMethodMap() +{ + NSynchronization::CCriticalSectionLock lock(g_CriticalSection); + if (g_Loaded) + return; + g_Loaded = true; + Load(GetCodecsFolderPrefix()); +} + +bool GetMethodInfo(const CMethodID &methodID, CMethodInfo &methodInfo) +{ + for(int i = 0; i < g_Methods.Size(); i++) + { + const CMethodInfo2 &method = g_Methods[i]; + if (method.MethodID == methodID) + { + methodInfo = (CMethodInfo)method; + return true; + } + } + return false; +} + +bool GetMethodInfo(const UString &name, CMethodInfo2 &methodInfo) +{ + for(int i = 0; i < g_Methods.Size(); i++) + { + const CMethodInfo2 &method = g_Methods[i]; + if (method.Name.CompareNoCase(name) == 0) + { + methodInfo = method; + return true; + } + } + return false; +} + +}} + + diff --git a/CPP/7zip/Archive/7z/7zMethods.h b/CPP/7zip/Archive/7z/7zMethods.h new file mode 100755 index 00000000..231f3183 --- /dev/null +++ b/CPP/7zip/Archive/7z/7zMethods.h @@ -0,0 +1,36 @@ +// 7zMethods.h + +#ifndef __7Z_METHODS_H +#define __7Z_METHODS_H + +#include "7zMethodID.h" + +namespace NArchive { +namespace N7z { + +struct CMethodInfo +{ + UString Name; + bool EncoderIsAssigned; + bool DecoderIsAssigned; + UInt32 NumInStreams; + UInt32 NumOutStreams; + CLSID Encoder; + CLSID Decoder; + // UString Description; + CSysString FilePath; +}; + +struct CMethodInfo2: public CMethodInfo +{ + CMethodID MethodID; +}; + +void LoadMethodMap(); +bool GetMethodInfo(const CMethodID &methodID, CMethodInfo &methodInfo); +bool GetMethodInfo(const UString &name, CMethodInfo2 &methodInfo); + +}} + +#endif + diff --git a/CPP/7zip/Archive/7z/7zOut.cpp b/CPP/7zip/Archive/7z/7zOut.cpp new file mode 100755 index 00000000..5a81a0d5 --- /dev/null +++ b/CPP/7zip/Archive/7z/7zOut.cpp @@ -0,0 +1,1136 @@ +// 7zOut.cpp + +#include "StdAfx.h" + +#include "../../../Common/AutoPtr.h" +#include "../../Common/StreamObjects.h" + +#include "7zOut.h" + +static HRESULT WriteBytes(ISequentialOutStream *stream, const void *data, size_t size) +{ + while (size > 0) + { + UInt32 curSize = (UInt32)MyMin(size, (size_t)0xFFFFFFFF); + UInt32 processedSize; + RINOK(stream->Write(data, curSize, &processedSize)); + if(processedSize == 0) + return E_FAIL; + data = (const void *)((const Byte *)data + processedSize); + size -= processedSize; + } + return S_OK; +} + +namespace NArchive { +namespace N7z { + +HRESULT COutArchive::WriteDirect(const void *data, UInt32 size) +{ + return ::WriteBytes(SeqStream, data, size); +} + +HRESULT COutArchive::WriteDirectUInt32(UInt32 value) +{ + for (int i = 0; i < 4; i++) + { + RINOK(WriteDirectByte((Byte)value)); + value >>= 8; + } + return S_OK; +} + +HRESULT COutArchive::WriteDirectUInt64(UInt64 value) +{ + for (int i = 0; i < 8; i++) + { + RINOK(WriteDirectByte((Byte)value)); + value >>= 8; + } + return S_OK; +} + +HRESULT COutArchive::WriteSignature() +{ + RINOK(WriteDirect(kSignature, kSignatureSize)); + RINOK(WriteDirectByte(kMajorVersion)); + return WriteDirectByte(2); +} + +#ifdef _7Z_VOL +HRESULT COutArchive::WriteFinishSignature() +{ + RINOK(WriteDirect(kFinishSignature, kSignatureSize)); + CArchiveVersion av; + av.Major = kMajorVersion; + av.Minor = 2; + RINOK(WriteDirectByte(av.Major)); + return WriteDirectByte(av.Minor); +} +#endif + +HRESULT COutArchive::WriteStartHeader(const CStartHeader &h) +{ + CCRC crc; + crc.UpdateUInt64(h.NextHeaderOffset); + crc.UpdateUInt64(h.NextHeaderSize); + crc.UpdateUInt32(h.NextHeaderCRC); + RINOK(WriteDirectUInt32(crc.GetDigest())); + RINOK(WriteDirectUInt64(h.NextHeaderOffset)); + RINOK(WriteDirectUInt64(h.NextHeaderSize)); + return WriteDirectUInt32(h.NextHeaderCRC); +} + +#ifdef _7Z_VOL +HRESULT COutArchive::WriteFinishHeader(const CFinishHeader &h) +{ + CCRC crc; + crc.UpdateUInt64(h.NextHeaderOffset); + crc.UpdateUInt64(h.NextHeaderSize); + crc.UpdateUInt32(h.NextHeaderCRC); + crc.UpdateUInt64(h.ArchiveStartOffset); + crc.UpdateUInt64(h.AdditionalStartBlockSize); + RINOK(WriteDirectUInt32(crc.GetDigest())); + RINOK(WriteDirectUInt64(h.NextHeaderOffset)); + RINOK(WriteDirectUInt64(h.NextHeaderSize)); + RINOK(WriteDirectUInt32(h.NextHeaderCRC)); + RINOK(WriteDirectUInt64(h.ArchiveStartOffset)); + return WriteDirectUInt64(h.AdditionalStartBlockSize); +} +#endif + +HRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker) +{ + Close(); + #ifdef _7Z_VOL + // endMarker = false; + _endMarker = endMarker; + #endif + SeqStream = stream; + if (!endMarker) + { + SeqStream.QueryInterface(IID_IOutStream, &Stream); + if (!Stream) + { + return E_NOTIMPL; + // endMarker = true; + } + } + #ifdef _7Z_VOL + if (endMarker) + { + /* + CStartHeader sh; + sh.NextHeaderOffset = (UInt32)(Int32)-1; + sh.NextHeaderSize = (UInt32)(Int32)-1; + sh.NextHeaderCRC = 0; + WriteStartHeader(sh); + */ + } + else + #endif + { + if (!Stream) + return E_FAIL; + WriteSignature(); + RINOK(Stream->Seek(0, STREAM_SEEK_CUR, &_prefixHeaderPos)); + } + return S_OK; +} + +void COutArchive::Close() +{ + SeqStream.Release(); + Stream.Release(); +} + +HRESULT COutArchive::SkeepPrefixArchiveHeader() +{ + #ifdef _7Z_VOL + if (_endMarker) + return S_OK; + #endif + return Stream->Seek(24, STREAM_SEEK_CUR, NULL); +} + +HRESULT COutArchive::WriteBytes(const void *data, size_t size) +{ + if (_mainMode) + { + if (_dynamicMode) + _dynamicBuffer.Write(data, size); + else + _outByte.WriteBytes(data, size); + _crc.Update(data, size); + } + else + { + if (_countMode) + _countSize += size; + else + RINOK(_outByte2.Write(data, size)); + } + return S_OK; +} + +HRESULT COutArchive::WriteBytes(const CByteBuffer &data) +{ + return WriteBytes(data, data.GetCapacity()); +} + +HRESULT COutArchive::WriteByte(Byte b) +{ + return WriteBytes(&b, 1); +} + +HRESULT COutArchive::WriteUInt32(UInt32 value) +{ + for (int i = 0; i < 4; i++) + { + RINOK(WriteByte((Byte)value)); + value >>= 8; + } + return S_OK; +} + +HRESULT COutArchive::WriteNumber(UInt64 value) +{ + Byte firstByte = 0; + Byte mask = 0x80; + int i; + for (i = 0; i < 8; i++) + { + if (value < ((UInt64(1) << ( 7 * (i + 1))))) + { + firstByte |= Byte(value >> (8 * i)); + break; + } + firstByte |= mask; + mask >>= 1; + } + RINOK(WriteByte(firstByte)); + for (;i > 0; i--) + { + RINOK(WriteByte((Byte)value)); + value >>= 8; + } + return S_OK; +} + +static UInt32 GetBigNumberSize(UInt64 value) +{ + int i; + for (i = 0; i < 8; i++) + if (value < ((UInt64(1) << ( 7 * (i + 1))))) + break; + return 1 + i; +} + +#ifdef _7Z_VOL +UInt32 COutArchive::GetVolHeadersSize(UInt64 dataSize, int nameLength, bool props) +{ + UInt32 result = GetBigNumberSize(dataSize) * 2 + 41; + if (nameLength != 0) + { + nameLength = (nameLength + 1) * 2; + result += nameLength + GetBigNumberSize(nameLength) + 2; + } + if (props) + { + result += 20; + } + if (result >= 128) + result++; + result += kSignatureSize + 2 + kFinishHeaderSize; + return result; +} + +UInt64 COutArchive::GetVolPureSize(UInt64 volSize, int nameLength, bool props) +{ + UInt32 headersSizeBase = COutArchive::GetVolHeadersSize(1, nameLength, props); + int testSize; + if (volSize > headersSizeBase) + testSize = volSize - headersSizeBase; + else + testSize = 1; + UInt32 headersSize = COutArchive::GetVolHeadersSize(testSize, nameLength, props); + UInt64 pureSize = 1; + if (volSize > headersSize) + pureSize = volSize - headersSize; + return pureSize; +} +#endif + +HRESULT COutArchive::WriteFolder(const CFolder &folder) +{ + RINOK(WriteNumber(folder.Coders.Size())); + int i; + for (i = 0; i < folder.Coders.Size(); i++) + { + const CCoderInfo &coder = folder.Coders[i]; + for (int j = 0; j < coder.AltCoders.Size(); j++) + { + const CAltCoderInfo &altCoder = coder.AltCoders[j]; + size_t propertiesSize = altCoder.Properties.GetCapacity(); + + Byte b; + b = (Byte)(altCoder.MethodID.IDSize & 0xF); + bool isComplex = !coder.IsSimpleCoder(); + b |= (isComplex ? 0x10 : 0); + b |= ((propertiesSize != 0) ? 0x20 : 0 ); + b |= ((j == coder.AltCoders.Size() - 1) ? 0 : 0x80 ); + RINOK(WriteByte(b)); + RINOK(WriteBytes(altCoder.MethodID.ID, altCoder.MethodID.IDSize)); + if (isComplex) + { + RINOK(WriteNumber(coder.NumInStreams)); + RINOK(WriteNumber(coder.NumOutStreams)); + } + if (propertiesSize == 0) + continue; + RINOK(WriteNumber(propertiesSize)); + RINOK(WriteBytes(altCoder.Properties, propertiesSize)); + } + } + for (i = 0; i < folder.BindPairs.Size(); i++) + { + const CBindPair &bindPair = folder.BindPairs[i]; + RINOK(WriteNumber(bindPair.InIndex)); + RINOK(WriteNumber(bindPair.OutIndex)); + } + if (folder.PackStreams.Size() > 1) + for (i = 0; i < folder.PackStreams.Size(); i++) + { + RINOK(WriteNumber(folder.PackStreams[i])); + } + return S_OK; +} + +HRESULT COutArchive::WriteBoolVector(const CBoolVector &boolVector) +{ + Byte b = 0; + Byte mask = 0x80; + for(int i = 0; i < boolVector.Size(); i++) + { + if (boolVector[i]) + b |= mask; + mask >>= 1; + if (mask == 0) + { + RINOK(WriteByte(b)); + mask = 0x80; + b = 0; + } + } + if (mask != 0x80) + { + RINOK(WriteByte(b)); + } + return S_OK; +} + + +HRESULT COutArchive::WriteHashDigests( + const CRecordVector &digestsDefined, + const CRecordVector &digests) +{ + int numDefined = 0; + int i; + for(i = 0; i < digestsDefined.Size(); i++) + if (digestsDefined[i]) + numDefined++; + if (numDefined == 0) + return S_OK; + + RINOK(WriteByte(NID::kCRC)); + if (numDefined == digestsDefined.Size()) + { + RINOK(WriteByte(1)); + } + else + { + RINOK(WriteByte(0)); + RINOK(WriteBoolVector(digestsDefined)); + } + for(i = 0; i < digests.Size(); i++) + { + if(digestsDefined[i]) + RINOK(WriteUInt32(digests[i])); + } + return S_OK; +} + +HRESULT COutArchive::WritePackInfo( + UInt64 dataOffset, + const CRecordVector &packSizes, + const CRecordVector &packCRCsDefined, + const CRecordVector &packCRCs) +{ + if (packSizes.IsEmpty()) + return S_OK; + RINOK(WriteByte(NID::kPackInfo)); + RINOK(WriteNumber(dataOffset)); + RINOK(WriteNumber(packSizes.Size())); + RINOK(WriteByte(NID::kSize)); + for(int i = 0; i < packSizes.Size(); i++) + RINOK(WriteNumber(packSizes[i])); + + RINOK(WriteHashDigests(packCRCsDefined, packCRCs)); + + return WriteByte(NID::kEnd); +} + +HRESULT COutArchive::WriteUnPackInfo( + bool externalFolders, + CNum externalFoldersStreamIndex, + const CObjectVector &folders) +{ + if (folders.IsEmpty()) + return S_OK; + + RINOK(WriteByte(NID::kUnPackInfo)); + + RINOK(WriteByte(NID::kFolder)); + RINOK(WriteNumber(folders.Size())); + if (externalFolders) + { + RINOK(WriteByte(1)); + RINOK(WriteNumber(externalFoldersStreamIndex)); + } + else + { + RINOK(WriteByte(0)); + for(int i = 0; i < folders.Size(); i++) + RINOK(WriteFolder(folders[i])); + } + + RINOK(WriteByte(NID::kCodersUnPackSize)); + int i; + for(i = 0; i < folders.Size(); i++) + { + const CFolder &folder = folders[i]; + for (int j = 0; j < folder.UnPackSizes.Size(); j++) + RINOK(WriteNumber(folder.UnPackSizes[j])); + } + + CRecordVector unPackCRCsDefined; + CRecordVector unPackCRCs; + for(i = 0; i < folders.Size(); i++) + { + const CFolder &folder = folders[i]; + unPackCRCsDefined.Add(folder.UnPackCRCDefined); + unPackCRCs.Add(folder.UnPackCRC); + } + RINOK(WriteHashDigests(unPackCRCsDefined, unPackCRCs)); + + return WriteByte(NID::kEnd); +} + +HRESULT COutArchive::WriteSubStreamsInfo( + const CObjectVector &folders, + const CRecordVector &numUnPackStreamsInFolders, + const CRecordVector &unPackSizes, + const CRecordVector &digestsDefined, + const CRecordVector &digests) +{ + RINOK(WriteByte(NID::kSubStreamsInfo)); + + int i; + for(i = 0; i < numUnPackStreamsInFolders.Size(); i++) + { + if (numUnPackStreamsInFolders[i] != 1) + { + RINOK(WriteByte(NID::kNumUnPackStream)); + for(i = 0; i < numUnPackStreamsInFolders.Size(); i++) + RINOK(WriteNumber(numUnPackStreamsInFolders[i])); + break; + } + } + + + bool needFlag = true; + CNum index = 0; + for(i = 0; i < numUnPackStreamsInFolders.Size(); i++) + for (CNum j = 0; j < numUnPackStreamsInFolders[i]; j++) + { + if (j + 1 != numUnPackStreamsInFolders[i]) + { + if (needFlag) + RINOK(WriteByte(NID::kSize)); + needFlag = false; + RINOK(WriteNumber(unPackSizes[index])); + } + index++; + } + + CRecordVector digestsDefined2; + CRecordVector digests2; + + int digestIndex = 0; + for (i = 0; i < folders.Size(); i++) + { + int numSubStreams = (int)numUnPackStreamsInFolders[i]; + if (numSubStreams == 1 && folders[i].UnPackCRCDefined) + digestIndex++; + else + for (int j = 0; j < numSubStreams; j++, digestIndex++) + { + digestsDefined2.Add(digestsDefined[digestIndex]); + digests2.Add(digests[digestIndex]); + } + } + RINOK(WriteHashDigests(digestsDefined2, digests2)); + return WriteByte(NID::kEnd); +} + +HRESULT COutArchive::WriteTime( + const CObjectVector &files, Byte type, + bool isExternal, CNum externalDataIndex) +{ + ///////////////////////////////////////////////// + // CreationTime + CBoolVector boolVector; + boolVector.Reserve(files.Size()); + bool thereAreDefined = false; + bool allDefined = true; + int i; + for(i = 0; i < files.Size(); i++) + { + const CFileItem &item = files[i]; + bool defined; + switch(type) + { + case NID::kCreationTime: + defined = item.IsCreationTimeDefined; + break; + case NID::kLastWriteTime: + defined = item.IsLastWriteTimeDefined; + break; + case NID::kLastAccessTime: + defined = item.IsLastAccessTimeDefined; + break; + default: + throw 1; + } + boolVector.Add(defined); + thereAreDefined = (thereAreDefined || defined); + allDefined = (allDefined && defined); + } + if (!thereAreDefined) + return S_OK; + RINOK(WriteByte(type)); + size_t dataSize = 1 + 1; + if (isExternal) + dataSize += GetBigNumberSize(externalDataIndex); + else + dataSize += files.Size() * 8; + if (allDefined) + { + RINOK(WriteNumber(dataSize)); + WriteByte(1); + } + else + { + RINOK(WriteNumber(1 + (boolVector.Size() + 7) / 8 + dataSize)); + WriteByte(0); + RINOK(WriteBoolVector(boolVector)); + } + if (isExternal) + { + RINOK(WriteByte(1)); + RINOK(WriteNumber(externalDataIndex)); + return S_OK; + } + RINOK(WriteByte(0)); + for(i = 0; i < files.Size(); i++) + { + if (boolVector[i]) + { + const CFileItem &item = files[i]; + CArchiveFileTime timeValue; + timeValue.dwLowDateTime = 0; + timeValue.dwHighDateTime = 0; + switch(type) + { + case NID::kCreationTime: + timeValue = item.CreationTime; + break; + case NID::kLastWriteTime: + timeValue = item.LastWriteTime; + break; + case NID::kLastAccessTime: + timeValue = item.LastAccessTime; + break; + } + RINOK(WriteUInt32(timeValue.dwLowDateTime)); + RINOK(WriteUInt32(timeValue.dwHighDateTime)); + } + } + return S_OK; +} + +HRESULT COutArchive::EncodeStream(CEncoder &encoder, const Byte *data, size_t dataSize, + CRecordVector &packSizes, CObjectVector &folders) +{ + CSequentialInStreamImp *streamSpec = new CSequentialInStreamImp; + CMyComPtr stream = streamSpec; + streamSpec->Init(data, dataSize); + CFolder folderItem; + folderItem.UnPackCRCDefined = true; + folderItem.UnPackCRC = CCRC::CalculateDigest(data, dataSize); + UInt64 dataSize64 = dataSize; + RINOK(encoder.Encode(stream, NULL, &dataSize64, folderItem, SeqStream, packSizes, NULL)); + folders.Add(folderItem); + return S_OK; +} + +HRESULT COutArchive::EncodeStream(CEncoder &encoder, const CByteBuffer &data, + CRecordVector &packSizes, CObjectVector &folders) +{ + return EncodeStream(encoder, data, data.GetCapacity(), packSizes, folders); +} + +static void WriteUInt32ToBuffer(Byte *data, UInt32 value) +{ + for (int i = 0; i < 4; i++) + { + *data++ = (Byte)value; + value >>= 8; + } +} + +static void WriteUInt64ToBuffer(Byte *data, UInt64 value) +{ + for (int i = 0; i < 8; i++) + { + *data++ = (Byte)value; + value >>= 8; + } +} + + +HRESULT COutArchive::WriteHeader(const CArchiveDatabase &database, + const CCompressionMethodMode *options, + const CHeaderOptions &headerOptions, + UInt64 &headerOffset) +{ + CObjectVector folders; + + bool compressHeaders = (options != NULL); + CMyAutoPtr encoder; + if (compressHeaders) + { + // it's for gcc2.95.2 + CMyAutoPtr tmp(new CEncoder(*options)); + encoder = tmp; + } + + CRecordVector packSizes; + + CNum dataIndex = 0; + + ////////////////////////// + // Folders + + CNum externalFoldersStreamIndex = 0; + bool externalFolders = (compressHeaders && database.Folders.Size() > 8); + if (externalFolders) + { + _mainMode = false; + _countMode = true; + _countSize = 0; + int i; + for(i = 0; i < database.Folders.Size(); i++) + { + RINOK(WriteFolder(database.Folders[i])); + } + + _countMode = false; + + CByteBuffer foldersData; + foldersData.SetCapacity(_countSize); + _outByte2.Init(foldersData, foldersData.GetCapacity()); + + for(i = 0; i < database.Folders.Size(); i++) + { + RINOK(WriteFolder(database.Folders[i])); + } + + { + externalFoldersStreamIndex = dataIndex++; + RINOK(EncodeStream(*encoder, foldersData, packSizes, folders)); + } + } + + + int i; + + ///////////////////////////////// + // Names + + CNum numDefinedNames = 0; + size_t namesDataSize = 0; + for(i = 0; i < database.Files.Size(); i++) + { + const UString &name = database.Files[i].Name; + if (!name.IsEmpty()) + numDefinedNames++; + namesDataSize += (name.Length() + 1) * 2; + } + + CByteBuffer namesData; + CNum externalNamesStreamIndex = 0; + bool externalNames = (compressHeaders && database.Files.Size() > 8); + if (numDefinedNames > 0) + { + namesData.SetCapacity((size_t)namesDataSize); + size_t pos = 0; + for(int i = 0; i < database.Files.Size(); i++) + { + const UString &name = database.Files[i].Name; + for (int t = 0; t < name.Length(); t++) + { + wchar_t c = name[t]; + namesData[pos++] = Byte(c); + namesData[pos++] = Byte(c >> 8); + } + namesData[pos++] = 0; + namesData[pos++] = 0; + } + + if (externalNames) + { + externalNamesStreamIndex = dataIndex++; + RINOK(EncodeStream(*encoder, namesData, packSizes, folders)); + } + } + + ///////////////////////////////// + // Write Attributes + CBoolVector attributesBoolVector; + attributesBoolVector.Reserve(database.Files.Size()); + int numDefinedAttributes = 0; + for(i = 0; i < database.Files.Size(); i++) + { + bool defined = database.Files[i].AreAttributesDefined; + attributesBoolVector.Add(defined); + if (defined) + numDefinedAttributes++; + } + + CByteBuffer attributesData; + CNum externalAttributesStreamIndex = 0; + bool externalAttributes = (compressHeaders && numDefinedAttributes > 8); + if (numDefinedAttributes > 0) + { + attributesData.SetCapacity(numDefinedAttributes * 4); + size_t pos = 0; + for(i = 0; i < database.Files.Size(); i++) + { + const CFileItem &file = database.Files[i]; + if (file.AreAttributesDefined) + { + WriteUInt32ToBuffer(attributesData + pos, file.Attributes); + pos += 4; + } + } + if (externalAttributes) + { + externalAttributesStreamIndex = dataIndex++; + RINOK(EncodeStream(*encoder, attributesData, packSizes, folders)); + } + } + + ///////////////////////////////// + // Write StartPos + CBoolVector startsBoolVector; + startsBoolVector.Reserve(database.Files.Size()); + int numDefinedStarts = 0; + for(i = 0; i < database.Files.Size(); i++) + { + bool defined = database.Files[i].IsStartPosDefined; + startsBoolVector.Add(defined); + if (defined) + numDefinedStarts++; + } + + CByteBuffer startsData; + CNum externalStartStreamIndex = 0; + bool externalStarts = (compressHeaders && numDefinedStarts > 8); + if (numDefinedStarts > 0) + { + startsData.SetCapacity(numDefinedStarts * 8); + size_t pos = 0; + for(i = 0; i < database.Files.Size(); i++) + { + const CFileItem &file = database.Files[i]; + if (file.IsStartPosDefined) + { + WriteUInt64ToBuffer(startsData + pos, file.StartPos); + pos += 8; + } + } + if (externalStarts) + { + externalStartStreamIndex = dataIndex++; + RINOK(EncodeStream(*encoder, startsData, packSizes, folders)); + } + } + + ///////////////////////////////// + // Write Last Write Time + CNum externalLastWriteTimeStreamIndex = 0; + bool externalLastWriteTime = false; + // /* + CNum numDefinedLastWriteTimes = 0; + for(i = 0; i < database.Files.Size(); i++) + if (database.Files[i].IsLastWriteTimeDefined) + numDefinedLastWriteTimes++; + + externalLastWriteTime = (compressHeaders && numDefinedLastWriteTimes > 64); + if (numDefinedLastWriteTimes > 0) + { + CByteBuffer lastWriteTimeData; + lastWriteTimeData.SetCapacity(numDefinedLastWriteTimes * 8); + size_t pos = 0; + for(i = 0; i < database.Files.Size(); i++) + { + const CFileItem &file = database.Files[i]; + if (file.IsLastWriteTimeDefined) + { + WriteUInt32ToBuffer(lastWriteTimeData + pos, file.LastWriteTime.dwLowDateTime); + pos += 4; + WriteUInt32ToBuffer(lastWriteTimeData + pos, file.LastWriteTime.dwHighDateTime); + pos += 4; + } + } + if (externalLastWriteTime) + { + externalLastWriteTimeStreamIndex = dataIndex++; + RINOK(EncodeStream(*encoder, lastWriteTimeData, packSizes, folders)); + } + } + // */ + + + UInt64 packedSize = 0; + for(i = 0; i < database.PackSizes.Size(); i++) + packedSize += database.PackSizes[i]; + UInt64 headerPackSize = 0; + for (i = 0; i < packSizes.Size(); i++) + headerPackSize += packSizes[i]; + + headerOffset = packedSize + headerPackSize; + + _mainMode = true; + + _outByte.SetStream(SeqStream); + _outByte.Init(); + _crc.Init(); + + + RINOK(WriteByte(NID::kHeader)); + + // Archive Properties + + if (folders.Size() > 0) + { + RINOK(WriteByte(NID::kAdditionalStreamsInfo)); + RINOK(WritePackInfo(packedSize, packSizes, + CRecordVector(), CRecordVector())); + RINOK(WriteUnPackInfo(false, 0, folders)); + RINOK(WriteByte(NID::kEnd)); + } + + //////////////////////////////////////////////////// + + if (database.Folders.Size() > 0) + { + RINOK(WriteByte(NID::kMainStreamsInfo)); + RINOK(WritePackInfo(0, database.PackSizes, + database.PackCRCsDefined, + database.PackCRCs)); + + RINOK(WriteUnPackInfo(externalFolders, externalFoldersStreamIndex, database.Folders)); + + CRecordVector unPackSizes; + CRecordVector digestsDefined; + CRecordVector digests; + for (i = 0; i < database.Files.Size(); i++) + { + const CFileItem &file = database.Files[i]; + if (!file.HasStream) + continue; + unPackSizes.Add(file.UnPackSize); + digestsDefined.Add(file.IsFileCRCDefined); + digests.Add(file.FileCRC); + } + + RINOK(WriteSubStreamsInfo( + database.Folders, + database.NumUnPackStreamsVector, + unPackSizes, + digestsDefined, + digests)); + RINOK(WriteByte(NID::kEnd)); + } + + if (database.Files.IsEmpty()) + { + RINOK(WriteByte(NID::kEnd)); + return _outByte.Flush(); + } + + RINOK(WriteByte(NID::kFilesInfo)); + RINOK(WriteNumber(database.Files.Size())); + + CBoolVector emptyStreamVector; + emptyStreamVector.Reserve(database.Files.Size()); + int numEmptyStreams = 0; + for(i = 0; i < database.Files.Size(); i++) + if (database.Files[i].HasStream) + emptyStreamVector.Add(false); + else + { + emptyStreamVector.Add(true); + numEmptyStreams++; + } + if (numEmptyStreams > 0) + { + RINOK(WriteByte(NID::kEmptyStream)); + RINOK(WriteNumber((emptyStreamVector.Size() + 7) / 8)); + RINOK(WriteBoolVector(emptyStreamVector)); + + CBoolVector emptyFileVector, antiVector; + emptyFileVector.Reserve(numEmptyStreams); + antiVector.Reserve(numEmptyStreams); + CNum numEmptyFiles = 0, numAntiItems = 0; + for(i = 0; i < database.Files.Size(); i++) + { + const CFileItem &file = database.Files[i]; + if (!file.HasStream) + { + emptyFileVector.Add(!file.IsDirectory); + if (!file.IsDirectory) + numEmptyFiles++; + antiVector.Add(file.IsAnti); + if (file.IsAnti) + numAntiItems++; + } + } + + if (numEmptyFiles > 0) + { + RINOK(WriteByte(NID::kEmptyFile)); + RINOK(WriteNumber((emptyFileVector.Size() + 7) / 8)); + RINOK(WriteBoolVector(emptyFileVector)); + } + + if (numAntiItems > 0) + { + RINOK(WriteByte(NID::kAnti)); + RINOK(WriteNumber((antiVector.Size() + 7) / 8)); + RINOK(WriteBoolVector(antiVector)); + } + } + + if (numDefinedNames > 0) + { + ///////////////////////////////////////////////// + RINOK(WriteByte(NID::kName)); + if (externalNames) + { + RINOK(WriteNumber(1 + GetBigNumberSize(externalNamesStreamIndex))); + RINOK(WriteByte(1)); + RINOK(WriteNumber(externalNamesStreamIndex)); + } + else + { + RINOK(WriteNumber(1 + namesData.GetCapacity())); + RINOK(WriteByte(0)); + RINOK(WriteBytes(namesData)); + } + + } + + if (headerOptions.WriteCreated) + { + RINOK(WriteTime(database.Files, NID::kCreationTime, false, 0)); + } + if (headerOptions.WriteModified) + { + RINOK(WriteTime(database.Files, NID::kLastWriteTime, + // false, 0)); + externalLastWriteTime, externalLastWriteTimeStreamIndex)); + } + if (headerOptions.WriteAccessed) + { + RINOK(WriteTime(database.Files, NID::kLastAccessTime, false, 0)); + } + + if (numDefinedAttributes > 0) + { + RINOK(WriteByte(NID::kWinAttributes)); + size_t size = 2; + if (numDefinedAttributes != database.Files.Size()) + size += (attributesBoolVector.Size() + 7) / 8 + 1; + if (externalAttributes) + size += GetBigNumberSize(externalAttributesStreamIndex); + else + size += attributesData.GetCapacity(); + + RINOK(WriteNumber(size)); + if (numDefinedAttributes == database.Files.Size()) + { + RINOK(WriteByte(1)); + } + else + { + RINOK(WriteByte(0)); + RINOK(WriteBoolVector(attributesBoolVector)); + } + + if (externalAttributes) + { + RINOK(WriteByte(1)); + RINOK(WriteNumber(externalAttributesStreamIndex)); + } + else + { + RINOK(WriteByte(0)); + RINOK(WriteBytes(attributesData)); + } + } + + if (numDefinedStarts > 0) + { + RINOK(WriteByte(NID::kStartPos)); + size_t size = 2; + if (numDefinedStarts != database.Files.Size()) + size += (startsBoolVector.Size() + 7) / 8 + 1; + if (externalStarts) + size += GetBigNumberSize(externalStartStreamIndex); + else + size += startsData.GetCapacity(); + + RINOK(WriteNumber(size)); + if (numDefinedStarts == database.Files.Size()) + { + RINOK(WriteByte(1)); + } + else + { + RINOK(WriteByte(0)); + RINOK(WriteBoolVector(startsBoolVector)); + } + + if (externalAttributes) + { + RINOK(WriteByte(1)); + RINOK(WriteNumber(externalStartStreamIndex)); + } + else + { + RINOK(WriteByte(0)); + RINOK(WriteBytes(startsData)); + } + } + + RINOK(WriteByte(NID::kEnd)); // for files + RINOK(WriteByte(NID::kEnd)); // for headers + + return _outByte.Flush(); +} + +HRESULT COutArchive::WriteDatabase(const CArchiveDatabase &database, + const CCompressionMethodMode *options, + const CHeaderOptions &headerOptions) +{ + UInt64 headerOffset; + UInt32 headerCRC; + UInt64 headerSize; + if (database.IsEmpty()) + { + headerSize = 0; + headerOffset = 0; + headerCRC = CCRC::CalculateDigest(0, 0); + } + else + { + _dynamicBuffer.Init(); + _dynamicMode = false; + + if (options != 0) + if (options->IsEmpty()) + options = 0; + const CCompressionMethodMode *additionalStreamsOptions = options; + if (!headerOptions.UseAdditionalHeaderStreams) + additionalStreamsOptions = 0; + /* + if (database.Files.Size() < 2) + compressMainHeader = false; + */ + if (options != 0) + if (options->PasswordIsDefined || headerOptions.CompressMainHeader) + _dynamicMode = true; + RINOK(WriteHeader(database, additionalStreamsOptions, headerOptions, headerOffset)); + + if (_dynamicMode) + { + CCompressionMethodMode encryptOptions; + encryptOptions.PasswordIsDefined = options->PasswordIsDefined; + encryptOptions.Password = options->Password; + CEncoder encoder(headerOptions.CompressMainHeader ? *options : encryptOptions); + CRecordVector packSizes; + CObjectVector folders; + RINOK(EncodeStream(encoder, _dynamicBuffer, + _dynamicBuffer.GetSize(), packSizes, folders)); + _dynamicMode = false; + _mainMode = true; + + _outByte.SetStream(SeqStream); + _outByte.Init(); + _crc.Init(); + + if (folders.Size() == 0) + throw 1; + + RINOK(WriteID(NID::kEncodedHeader)); + RINOK(WritePackInfo(headerOffset, packSizes, + CRecordVector(), CRecordVector())); + RINOK(WriteUnPackInfo(false, 0, folders)); + RINOK(WriteByte(NID::kEnd)); + for (int i = 0; i < packSizes.Size(); i++) + headerOffset += packSizes[i]; + RINOK(_outByte.Flush()); + } + headerCRC = _crc.GetDigest(); + headerSize = _outByte.GetProcessedSize(); + } + #ifdef _7Z_VOL + if (_endMarker) + { + CFinishHeader h; + h.NextHeaderSize = headerSize; + h.NextHeaderCRC = headerCRC; + h.NextHeaderOffset = + UInt64(0) - (headerSize + + 4 + kFinishHeaderSize); + h.ArchiveStartOffset = h.NextHeaderOffset - headerOffset; + h.AdditionalStartBlockSize = 0; + RINOK(WriteFinishHeader(h)); + return WriteFinishSignature(); + } + else + #endif + { + CStartHeader h; + h.NextHeaderSize = headerSize; + h.NextHeaderCRC = headerCRC; + h.NextHeaderOffset = headerOffset; + RINOK(Stream->Seek(_prefixHeaderPos, STREAM_SEEK_SET, NULL)); + return WriteStartHeader(h); + } +} + +}} diff --git a/CPP/7zip/Archive/7z/7zOut.h b/CPP/7zip/Archive/7z/7zOut.h new file mode 100755 index 00000000..cccc813a --- /dev/null +++ b/CPP/7zip/Archive/7z/7zOut.h @@ -0,0 +1,192 @@ +// 7z/Out.h + +#ifndef __7Z_OUT_H +#define __7Z_OUT_H + +#include "7zHeader.h" +#include "7zItem.h" +#include "7zCompressionMode.h" +#include "7zEncode.h" + +#include "../../Common/OutBuffer.h" +#include "../../../Common/DynamicBuffer.h" +#include "../../../Common/CRC.h" + +namespace NArchive { +namespace N7z { + +class CWriteBufferLoc +{ + Byte *_data; + size_t _size; + size_t _pos; +public: + CWriteBufferLoc(): _size(0), _pos(0) {} + void Init(Byte *data, size_t size) + { + _pos = 0; + _data = data; + _size = size; + } + HRESULT Write(const void *data, size_t size) + { + if (_pos + size > _size) + return E_FAIL; + memmove(_data + _pos, data, size); + _pos += size; + return S_OK; + } +}; + +class CWriteDynamicBuffer +{ + CByteDynamicBuffer _buffer; + size_t _pos; +public: + CWriteDynamicBuffer(): _pos(0) {} + void Init() + { + _pos = 0; + } + void Write(const void *data, size_t size) + { + if (_pos + size > _buffer.GetCapacity()) + _buffer.EnsureCapacity(_pos + size); + memmove(((Byte *)_buffer) +_pos, data, size); + _pos += size; + } + operator Byte *() { return (Byte *)_buffer; }; + operator const Byte *() const { return (const Byte *)_buffer; }; + size_t GetSize() const { return _pos; } +}; + +struct CHeaderOptions +{ + bool UseAdditionalHeaderStreams; + bool CompressMainHeader; + bool WriteModified; + bool WriteCreated; + bool WriteAccessed; + + CHeaderOptions(): + UseAdditionalHeaderStreams(false), + CompressMainHeader(true), + WriteModified(true), + WriteCreated(false), + WriteAccessed(false) {} +}; + +class COutArchive +{ + UInt64 _prefixHeaderPos; + + HRESULT WriteDirect(const void *data, UInt32 size); + HRESULT WriteDirectByte(Byte b) { return WriteDirect(&b, 1); } + HRESULT WriteDirectUInt32(UInt32 value); + HRESULT WriteDirectUInt64(UInt64 value); + + HRESULT WriteBytes(const void *data, size_t size); + HRESULT WriteBytes(const CByteBuffer &data); + HRESULT WriteByte(Byte b); + HRESULT WriteUInt32(UInt32 value); + HRESULT WriteNumber(UInt64 value); + HRESULT WriteID(UInt64 value) { return WriteNumber(value); } + + HRESULT WriteFolder(const CFolder &folder); + HRESULT WriteFileHeader(const CFileItem &itemInfo); + HRESULT WriteBoolVector(const CBoolVector &boolVector); + HRESULT WriteHashDigests( + const CRecordVector &digestsDefined, + const CRecordVector &hashDigests); + + HRESULT WritePackInfo( + UInt64 dataOffset, + const CRecordVector &packSizes, + const CRecordVector &packCRCsDefined, + const CRecordVector &packCRCs); + + HRESULT WriteUnPackInfo( + bool externalFolders, + CNum externalFoldersStreamIndex, + const CObjectVector &folders); + + HRESULT WriteSubStreamsInfo( + const CObjectVector &folders, + const CRecordVector &numUnPackStreamsInFolders, + const CRecordVector &unPackSizes, + const CRecordVector &digestsDefined, + const CRecordVector &hashDigests); + + /* + HRESULT WriteStreamsInfo( + UInt64 dataOffset, + const CRecordVector &packSizes, + const CRecordVector &packCRCsDefined, + const CRecordVector &packCRCs, + bool externalFolders, + UInt64 externalFoldersStreamIndex, + const CObjectVector &folders, + const CRecordVector &numUnPackStreamsInFolders, + const CRecordVector &unPackSizes, + const CRecordVector &digestsDefined, + const CRecordVector &hashDigests); + */ + + + HRESULT WriteTime(const CObjectVector &files, Byte type, + bool isExternal, CNum externalDataIndex); + + HRESULT EncodeStream(CEncoder &encoder, const Byte *data, size_t dataSize, + CRecordVector &packSizes, CObjectVector &folders); + HRESULT EncodeStream(CEncoder &encoder, const CByteBuffer &data, + CRecordVector &packSizes, CObjectVector &folders); + HRESULT WriteHeader(const CArchiveDatabase &database, + const CCompressionMethodMode *options, + const CHeaderOptions &headerOptions, + UInt64 &headerOffset); + + bool _mainMode; + + bool _dynamicMode; + + bool _countMode; + size_t _countSize; + COutBuffer _outByte; + CWriteBufferLoc _outByte2; + CWriteDynamicBuffer _dynamicBuffer; + CCRC _crc; + + #ifdef _7Z_VOL + bool _endMarker; + #endif + + HRESULT WriteSignature(); + #ifdef _7Z_VOL + HRESULT WriteFinishSignature(); + #endif + HRESULT WriteStartHeader(const CStartHeader &h); + #ifdef _7Z_VOL + HRESULT WriteFinishHeader(const CFinishHeader &h); + #endif + CMyComPtr Stream; +public: + + COutArchive() { _outByte.Create(1 << 16); } + CMyComPtr SeqStream; + HRESULT Create(ISequentialOutStream *stream, bool endMarker); + void Close(); + HRESULT SkeepPrefixArchiveHeader(); + HRESULT WriteDatabase(const CArchiveDatabase &database, + const CCompressionMethodMode *options, + const CHeaderOptions &headerOptions); + + #ifdef _7Z_VOL + static UInt32 GetVolHeadersSize(UInt64 dataSize, int nameLength = 0, bool props = false); + static UInt64 GetVolPureSize(UInt64 volSize, int nameLength = 0, bool props = false); + #endif + +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/7z/7zProperties.cpp b/CPP/7zip/Archive/7z/7zProperties.cpp new file mode 100755 index 00000000..316f4f09 --- /dev/null +++ b/CPP/7zip/Archive/7z/7zProperties.cpp @@ -0,0 +1,166 @@ +// 7zProperties.cpp + +#include "StdAfx.h" + +#include "7zProperties.h" +#include "7zHeader.h" +#include "7zHandler.h" + +// #define _MULTI_PACK + +namespace NArchive { +namespace N7z { + +struct CPropMap +{ + UInt64 FilePropID; + STATPROPSTG StatPROPSTG; +}; + +CPropMap kPropMap[] = +{ + { NID::kName, NULL, kpidPath, VT_BSTR}, + { NID::kSize, NULL, kpidSize, VT_UI8}, + { NID::kPackInfo, NULL, kpidPackedSize, VT_UI8}, + + #ifdef _MULTI_PACK + { 100, L"Pack0", kpidPackedSize0, VT_UI8}, + { 101, L"Pack1", kpidPackedSize1, VT_UI8}, + { 102, L"Pack2", kpidPackedSize2, VT_UI8}, + { 103, L"Pack3", kpidPackedSize3, VT_UI8}, + { 104, L"Pack4", kpidPackedSize4, VT_UI8}, + #endif + + { NID::kCreationTime, NULL, kpidCreationTime, VT_FILETIME}, + { NID::kLastWriteTime, NULL, kpidLastWriteTime, VT_FILETIME}, + { NID::kLastAccessTime, NULL, kpidLastAccessTime, VT_FILETIME}, + { NID::kWinAttributes, NULL, kpidAttributes, VT_UI4}, + { NID::kStartPos, NULL, kpidPosition, VT_UI4}, + + + { NID::kCRC, NULL, kpidCRC, VT_UI4}, + + { NID::kAnti, L"Anti", kpidIsAnti, VT_BOOL}, + // { 97, NULL, kpidSolid, VT_BOOL}, + #ifndef _SFX + { 98, NULL, kpidMethod, VT_BSTR}, + { 99, L"Block", kpidBlock, VT_UI4} + #endif + // { L"ID", kpidID, VT_BSTR}, + // { L"UnPack Version", kpidUnPackVersion, VT_UI1}, + // { L"Host OS", kpidHostOS, VT_BSTR} +}; + +static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]); + +static int FindPropInMap(UInt64 filePropID) +{ + for (int i = 0; i < kPropMapSize; i++) + if (kPropMap[i].FilePropID == filePropID) + return i; + return -1; +} + +static void CopyOneItem(CRecordVector &src, + CRecordVector &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 &src, UInt32 item) +{ + for (int i = 0; i < src.Size(); i++) + if (src[i] == item) + { + src.Delete(i); + return; + } +} + +static void InsertToHead(CRecordVector &dest, UInt32 item) +{ + for (int i = 0; i < dest.Size(); i++) + if (dest[i] == item) + { + dest.Delete(i); + break; + } + dest.Insert(0, item); +} + +void CHandler::FillPopIDs() +{ + _fileInfoPopIDs.Clear(); + + #ifdef _7Z_VOL + if(_volumes.Size() < 1) + return; + const CVolume &volume = _volumes.Front(); + const CArchiveDatabaseEx &_database = volume.Database; + #endif + + CRecordVector fileInfoPopIDs = _database.ArchiveInfo.FileInfoPopIDs; + + RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream); + RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile); + + CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kName); + CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kAnti); + CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kSize); + CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kPackInfo); + CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCreationTime); + CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastWriteTime); + CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastAccessTime); + CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes); + CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC); + CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment); + _fileInfoPopIDs += fileInfoPopIDs; + + #ifndef _SFX + _fileInfoPopIDs.Add(98); + _fileInfoPopIDs.Add(99); + #endif + #ifdef _MULTI_PACK + _fileInfoPopIDs.Add(100); + _fileInfoPopIDs.Add(101); + _fileInfoPopIDs.Add(102); + _fileInfoPopIDs.Add(103); + _fileInfoPopIDs.Add(104); + #endif + + #ifndef _SFX + InsertToHead(_fileInfoPopIDs, NID::kLastWriteTime); + InsertToHead(_fileInfoPopIDs, NID::kPackInfo); + InsertToHead(_fileInfoPopIDs, NID::kSize); + InsertToHead(_fileInfoPopIDs, NID::kName); + #endif +} + +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = _fileInfoPopIDs.Size(); + return S_OK; +} + +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if((int)index >= _fileInfoPopIDs.Size()) + return E_INVALIDARG; + int indexInMap = FindPropInMap(_fileInfoPopIDs[index]); + if (indexInMap == -1) + return E_INVALIDARG; + const STATPROPSTG &srcItem = kPropMap[indexInMap].StatPROPSTG; + *propID = srcItem.propid; + *varType = srcItem.vt; + *name = 0; + return S_OK; +} + +}} diff --git a/CPP/7zip/Archive/7z/7zProperties.h b/CPP/7zip/Archive/7z/7zProperties.h new file mode 100755 index 00000000..a09839bb --- /dev/null +++ b/CPP/7zip/Archive/7z/7zProperties.h @@ -0,0 +1,22 @@ +// 7zProperties.h + +#ifndef __7Z_PROPERTIES_H +#define __7Z_PROPERTIES_H + +#include "../../PropID.h" + +namespace NArchive { +namespace N7z { + +enum // PropID +{ + kpidPackedSize0 = kpidUserDefined, + kpidPackedSize1, + kpidPackedSize2, + kpidPackedSize3, + kpidPackedSize4, +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/7z/7zSpecStream.cpp b/CPP/7zip/Archive/7z/7zSpecStream.cpp new file mode 100755 index 00000000..80d303a4 --- /dev/null +++ b/CPP/7zip/Archive/7z/7zSpecStream.cpp @@ -0,0 +1,24 @@ +// 7zSpecStream.cpp + +#include "StdAfx.h" + +#include "7zSpecStream.h" + +STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize; + HRESULT result = _stream->Read(data, size, &realProcessedSize); + _size += realProcessedSize; + if (processedSize != 0) + *processedSize = realProcessedSize; + return result; +} + +STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize( + UInt64 subStream, UInt64 *value) +{ + if (_getSubStreamSize == NULL) + return E_NOTIMPL; + return _getSubStreamSize->GetSubStreamSize(subStream, value); +} + diff --git a/CPP/7zip/Archive/7z/7zSpecStream.h b/CPP/7zip/Archive/7z/7zSpecStream.h new file mode 100755 index 00000000..0253c421 --- /dev/null +++ b/CPP/7zip/Archive/7z/7zSpecStream.h @@ -0,0 +1,35 @@ +// 7zSpecStream.h + +#ifndef __7Z_SPEC_STREAM_H +#define __7Z_SPEC_STREAM_H + +#include "../../IStream.h" +#include "../../ICoder.h" +#include "../../../Common/MyCom.h" + +class CSequentialInStreamSizeCount2: + public ISequentialInStream, + public ICompressGetSubStreamSize, + public CMyUnknownImp +{ + CMyComPtr _stream; + CMyComPtr _getSubStreamSize; + UInt64 _size; +public: + void Init(ISequentialInStream *stream) + { + _stream = stream; + _getSubStreamSize = 0; + _stream.QueryInterface(IID_ICompressGetSubStreamSize, &_getSubStreamSize); + _size = 0; + } + UInt64 GetSize() const { return _size; } + + MY_UNKNOWN_IMP1(ICompressGetSubStreamSize) + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + + STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value); +}; + +#endif diff --git a/CPP/7zip/Archive/7z/7zUpdate.cpp b/CPP/7zip/Archive/7z/7zUpdate.cpp new file mode 100755 index 00000000..b3d5009a --- /dev/null +++ b/CPP/7zip/Archive/7z/7zUpdate.cpp @@ -0,0 +1,1099 @@ +// UpdateMain.cpp + +#include "StdAfx.h" + +#include "7zUpdate.h" +#include "7zFolderInStream.h" +#include "7zEncode.h" +#include "7zHandler.h" +#include "7zOut.h" + +#ifndef EXCLUDE_COM +#include "7zMethods.h" +#endif + +#include "../../Compress/Copy/CopyCoder.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/LimitedStreams.h" +#include "../../Common/LimitedStreams.h" +#include "../Common/ItemNameUtils.h" + +namespace NArchive { +namespace N7z { + +static const wchar_t *kMatchFinderForBCJ2_LZMA = L"BT2"; +static const UInt32 kDictionaryForBCJ2_LZMA = 1 << 20; +static const UInt32 kAlgorithmForBCJ2_LZMA = 1; +static const UInt32 kNumFastBytesForBCJ2_LZMA = 64; + +static HRESULT CopyBlock(ISequentialInStream *inStream, + ISequentialOutStream *outStream, ICompressProgressInfo *progress) +{ + CMyComPtr copyCoder = new NCompress::CCopyCoder; + return copyCoder->Code(inStream, outStream, NULL, NULL, progress); +} + +static HRESULT WriteRange( + ISequentialInStream *inStream, + ISequentialOutStream *outStream, + UInt64 size, + IProgress *progress, + UInt64 ¤tComplexity) +{ + CLimitedSequentialInStream *streamSpec = new + CLimitedSequentialInStream; + CMyComPtr inStreamLimited(streamSpec); + streamSpec->SetStream(inStream); + streamSpec->Init(size); + + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr localProgress = localProgressSpec; + localProgressSpec->Init(progress, true); + + CLocalCompressProgressInfo *localCompressProgressSpec = + new CLocalCompressProgressInfo; + CMyComPtr compressProgress = localCompressProgressSpec; + + localCompressProgressSpec->Init(localProgress, ¤tComplexity, ¤tComplexity); + + HRESULT result = CopyBlock(inStreamLimited, outStream, compressProgress); + currentComplexity += size; + return result; +} + + +static HRESULT WriteRange(IInStream *inStream, + ISequentialOutStream *outStream, + UInt64 position, + UInt64 size, + IProgress *progress, + UInt64 ¤tComplexity) +{ + inStream->Seek(position, STREAM_SEEK_SET, 0); + return WriteRange(inStream, outStream, + size, progress, currentComplexity); +} + +static int GetReverseSlashPos(const UString &name) +{ + int slashPos = name.ReverseFind(L'/'); + #ifdef _WIN32 + int slash1Pos = name.ReverseFind(L'\\'); + slashPos = MyMax(slashPos, slash1Pos); + #endif + return slashPos; +} + +int CUpdateItem::GetExtensionPos() const +{ + int slashPos = GetReverseSlashPos(Name); + int dotPos = Name.ReverseFind(L'.'); + if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0)) + return Name.Length(); + return dotPos + 1; +} + +UString CUpdateItem::GetExtension() const +{ + return Name.Mid(GetExtensionPos()); +} + +/* +struct CFolderRef +{ + const CArchiveDatabaseEx *Database; + int FolderIndex; +}; +*/ + +#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } + +static int CompareMethodIDs(const CMethodID &a1, const CMethodID &a2) +{ + for (int i = 0; i < a1.IDSize && i < a2.IDSize; i++) + RINOZ(MyCompare(a1.ID[i], a2.ID[i])); + return MyCompare(a1.IDSize, a2.IDSize); +} + +static int CompareBuffers(const CByteBuffer &a1, const CByteBuffer &a2) +{ + size_t c1 = a1.GetCapacity(); + size_t c2 = a2.GetCapacity(); + RINOZ(MyCompare(c1, c2)); + for (size_t i = 0; i < c1; i++) + RINOZ(MyCompare(a1[i], a2[i])); + return 0; +} + +static int CompareAltCoders(const CAltCoderInfo &a1, const CAltCoderInfo &a2) +{ + RINOZ(CompareMethodIDs(a1.MethodID, a2.MethodID)); + return CompareBuffers(a1.Properties, a2.Properties); +} + +static int CompareCoders(const CCoderInfo &c1, const CCoderInfo &c2) +{ + RINOZ(MyCompare(c1.NumInStreams, c2.NumInStreams)); + RINOZ(MyCompare(c1.NumOutStreams, c2.NumOutStreams)); + int s1 = c1.AltCoders.Size(); + int s2 = c2.AltCoders.Size(); + RINOZ(MyCompare(s1, s2)); + for (int i = 0; i < s1; i++) + RINOZ(CompareAltCoders(c1.AltCoders[i], c2.AltCoders[i])); + return 0; +} + +static int CompareBindPairs(const CBindPair &b1, const CBindPair &b2) +{ + RINOZ(MyCompare(b1.InIndex, b2.InIndex)); + return MyCompare(b1.OutIndex, b2.OutIndex); +} + +static int CompareFolders(const CFolder &f1, const CFolder &f2) +{ + int s1 = f1.Coders.Size(); + int s2 = f2.Coders.Size(); + RINOZ(MyCompare(s1, s2)); + int i; + for (i = 0; i < s1; i++) + RINOZ(CompareCoders(f1.Coders[i], f2.Coders[i])); + s1 = f1.BindPairs.Size(); + s2 = f2.BindPairs.Size(); + RINOZ(MyCompare(s1, s2)); + for (i = 0; i < s1; i++) + RINOZ(CompareBindPairs(f1.BindPairs[i], f2.BindPairs[i])); + return 0; +} + +static int CompareFiles(const CFileItem &f1, const CFileItem &f2) +{ + return MyStringCompareNoCase(f1.Name, f2.Name); +} + +static int CompareFolderRefs(const int *p1, const int *p2, void *param) +{ + int i1 = *p1; + int i2 = *p2; + const CArchiveDatabaseEx &db = *(const CArchiveDatabaseEx *)param; + RINOZ(CompareFolders( + db.Folders[i1], + db.Folders[i2])); + RINOZ(MyCompare( + db.NumUnPackStreamsVector[i1], + db.NumUnPackStreamsVector[i2])); + if (db.NumUnPackStreamsVector[i1] == 0) + return 0; + return CompareFiles( + db.Files[db.FolderStartFileIndex[i1]], + db.Files[db.FolderStartFileIndex[i2]]); +} + +//////////////////////////////////////////////////////////// + +static int CompareEmptyItems(const int *p1, const int *p2, void *param) +{ + const CObjectVector &updateItems = *(const CObjectVector *)param; + const CUpdateItem &u1 = updateItems[*p1]; + const CUpdateItem &u2 = updateItems[*p2]; + if (u1.IsDirectory != u2.IsDirectory) + return (u1.IsDirectory) ? 1 : -1; + if (u1.IsDirectory) + { + if (u1.IsAnti != u2.IsAnti) + return (u1.IsAnti ? 1 : -1); + int n = MyStringCompareNoCase(u1.Name, u2.Name); + return -n; + } + if (u1.IsAnti != u2.IsAnti) + return (u1.IsAnti ? 1 : -1); + return MyStringCompareNoCase(u1.Name, u2.Name); +} + +static const char *g_Exts = + " lzma 7z ace arc arj bz bz2 deb lzo lzx gz pak rpm sit tgz tbz tbz2 tgz cab ha lha lzh rar zoo" + " zip jar ear war msi" + " 3gp avi mov mpeg mpg mpe wmv" + " aac ape fla flac la mp3 m4a mp4 ofr ogg pac ra rm rka shn swa tta wv wma wav" + " swf " + " chm hxi hxs" + " gif jpeg jpg jp2 png tiff bmp ico psd psp" + " awg ps eps cgm dxf svg vrml wmf emf ai md" + " cad dwg pps key sxi" + " max 3ds" + " iso bin nrg mdf img pdi tar cpio xpi" + " vfd vhd vud vmc vsv" + " vmdk dsk nvram vmem vmsd vmsn vmss vmtm" + " inl inc idl acf asa h hpp hxx c cpp cxx rc java cs pas bas vb cls ctl frm dlg def" + " f77 f f90 f95" + " asm sql manifest dep " + " mak clw csproj vcproj sln dsp dsw " + " class " + " bat cmd" + " xml xsd xsl xslt hxk hxc htm html xhtml xht mht mhtml htw asp aspx css cgi jsp shtml" + " awk sed hta js php php3 php4 php5 phptml pl pm py pyo rb sh tcl vbs" + " text txt tex ans asc srt reg ini doc docx mcw dot rtf hlp xls xlr xlt xlw ppt pdf" + " sxc sxd sxi sxg sxw stc sti stw stm odt ott odg otg odp otp ods ots odf" + " abw afp cwk lwp wpd wps wpt wrf wri" + " abf afm bdf fon mgf otf pcf pfa snf ttf" + " dbf mdb nsf ntf wdb db fdb gdb" + " exe dll ocx vbx sfx sys tlb awx com obj lib out o so " + " pdb pch idb ncb opt"; + +int GetExtIndex(const char *ext) +{ + int extIndex = 1; + const char *p = g_Exts; + for (;;) + { + char c = *p++; + if (c == 0) + return extIndex; + if (c == ' ') + continue; + int pos = 0; + for (;;) + { + char c2 = ext[pos++]; + if (c2 == 0 && (c == 0 || c == ' ')) + return extIndex; + if (c != c2) + break; + c = *p++; + } + extIndex++; + for (;;) + { + if (c == 0) + return extIndex; + if (c == ' ') + break; + c = *p++; + } + } +} + +struct CRefItem +{ + UInt32 Index; + const CUpdateItem *UpdateItem; + UInt32 ExtensionPos; + UInt32 NamePos; + int ExtensionIndex; + CRefItem(UInt32 index, const CUpdateItem &updateItem, bool sortByType): + Index(index), + UpdateItem(&updateItem), + ExtensionPos(0), + NamePos(0), + ExtensionIndex(0) + { + if (sortByType) + { + int slashPos = GetReverseSlashPos(updateItem.Name); + NamePos = ((slashPos >= 0) ? (slashPos + 1) : 0); + int dotPos = updateItem.Name.ReverseFind(L'.'); + if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0)) + ExtensionPos = updateItem.Name.Length(); + else + { + ExtensionPos = dotPos + 1; + UString us = updateItem.Name.Mid(ExtensionPos); + if (!us.IsEmpty()) + { + us.MakeLower(); + int i; + AString s; + for (i = 0; i < us.Length(); i++) + { + wchar_t c = us[i]; + if (c >= 0x80) + break; + s += (char)c; + } + if (i == us.Length()) + ExtensionIndex = GetExtIndex(s); + else + ExtensionIndex = 0; + } + } + } + } +}; + +static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *param) +{ + const CRefItem &a1 = *p1; + const CRefItem &a2 = *p2; + const CUpdateItem &u1 = *a1.UpdateItem; + const CUpdateItem &u2 = *a2.UpdateItem; + int n; + if (u1.IsDirectory != u2.IsDirectory) + return (u1.IsDirectory) ? 1 : -1; + if (u1.IsDirectory) + { + if (u1.IsAnti != u2.IsAnti) + return (u1.IsAnti ? 1 : -1); + n = MyStringCompareNoCase(u1.Name, u2.Name); + return -n; + } + bool sortByType = *(bool *)param; + if (sortByType) + { + RINOZ(MyCompare(a1.ExtensionIndex, a2.ExtensionIndex)) + RINOZ(MyStringCompareNoCase(u1.Name + a1.ExtensionPos, u2.Name + a2.ExtensionPos)); + RINOZ(MyStringCompareNoCase(u1.Name + a1.NamePos, u2.Name + a2.NamePos)); + if (u1.IsLastWriteTimeDefined && u2.IsLastWriteTimeDefined) + RINOZ(CompareFileTime(&u1.LastWriteTime, &u2.LastWriteTime)); + RINOZ(MyCompare(u1.Size, u2.Size)) + } + return MyStringCompareNoCase(u1.Name, u2.Name); +} + +struct CSolidGroup +{ + CCompressionMethodMode Method; + CRecordVector 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 &updateItems, + CObjectVector &groups) +{ + if (method.Methods.Size() != 1 || method.Binds.Size() != 0) + useFilters = false; + groups.Clear(); + groups.Add(CSolidGroup()); + groups.Add(CSolidGroup()); + CSolidGroup &generalGroup = groups[0]; + CSolidGroup &exeGroup = groups[1]; + generalGroup.Method = method; + int i; + for (i = 0; i < updateItems.Size(); i++) + { + const CUpdateItem &updateItem = updateItems[i]; + if (!updateItem.NewData) + continue; + if (!updateItem.HasStream()) + continue; + if (useFilters) + { + const UString name = updateItem.Name; + int dotPos = name.ReverseFind(L'.'); + if (dotPos >= 0) + { + UString ext = name.Mid(dotPos + 1); + if (IsExeFile(ext)) + { + exeGroup.Indices.Add(i); + continue; + } + } + } + generalGroup.Indices.Add(i); + } + if (exeGroup.Indices.Size() > 0) + if (!MakeExeMethod(method, maxFilter, exeGroup.Method)) + exeGroup.Method = method; + for (i = 0; i < groups.Size();) + if (groups[i].Indices.Size() == 0) + groups.Delete(i); + else + i++; +} + +static void FromUpdateItemToFileItem(const CUpdateItem &updateItem, + CFileItem &file) +{ + file.Name = NItemName::MakeLegalName(updateItem.Name); + if (updateItem.AttributesAreDefined) + file.SetAttributes(updateItem.Attributes); + + if (updateItem.IsCreationTimeDefined) + file.SetCreationTime(updateItem.CreationTime); + if (updateItem.IsLastWriteTimeDefined) + file.SetLastWriteTime(updateItem.LastWriteTime); + if (updateItem.IsLastAccessTimeDefined) + file.SetLastAccessTime(updateItem.LastAccessTime); + + file.UnPackSize = updateItem.Size; + file.IsDirectory = updateItem.IsDirectory; + file.IsAnti = updateItem.IsAnti; + file.HasStream = updateItem.HasStream(); +} + +static HRESULT Update2( + IInStream *inStream, + const CArchiveDatabaseEx *database, + const CObjectVector &updateItems, + ISequentialOutStream *seqOutStream, + IArchiveUpdateCallback *updateCallback, + const CUpdateOptions &options) +{ + UInt64 numSolidFiles = options.NumSolidFiles; + if (numSolidFiles == 0) + numSolidFiles = 1; + /* + CMyComPtr outStream; + RINOK(seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStream)); + if (!outStream) + return E_NOTIMPL; + */ + + UInt64 startBlockSize = database != 0 ? + database->ArchiveInfo.StartPosition: 0; + if (startBlockSize > 0 && !options.RemoveSfxBlock) + { + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr limitedStream(streamSpec); + RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); + streamSpec->SetStream(inStream); + streamSpec->Init(startBlockSize); + RINOK(CopyBlock(limitedStream, seqOutStream, NULL)); + } + + CRecordVector fileIndexToUpdateIndexMap; + if (database != 0) + { + fileIndexToUpdateIndexMap.Reserve(database->Files.Size()); + for (int i = 0; i < database->Files.Size(); i++) + fileIndexToUpdateIndexMap.Add(-1); + } + int i; + for(i = 0; i < updateItems.Size(); i++) + { + int index = updateItems[i].IndexInArchive; + if (index != -1) + fileIndexToUpdateIndexMap[index] = i; + } + + CRecordVector folderRefs; + if (database != 0) + { + for(i = 0; i < database->Folders.Size(); i++) + { + CNum indexInFolder = 0; + CNum numCopyItems = 0; + CNum numUnPackStreams = database->NumUnPackStreamsVector[i]; + for (CNum fileIndex = database->FolderStartFileIndex[i]; + indexInFolder < numUnPackStreams; fileIndex++) + { + if (database->Files[fileIndex].HasStream) + { + indexInFolder++; + int updateIndex = fileIndexToUpdateIndexMap[fileIndex]; + if (updateIndex >= 0) + if (!updateItems[updateIndex].NewData) + numCopyItems++; + } + } + if (numCopyItems != numUnPackStreams && numCopyItems != 0) + return E_NOTIMPL; // It needs repacking !!! + if (numCopyItems > 0) + folderRefs.Add(i); + } + folderRefs.Sort(CompareFolderRefs, (void *)database); + } + + CArchiveDatabase newDatabase; + + //////////////////////////// + + COutArchive archive; + RINOK(archive.Create(seqOutStream, false)); + RINOK(archive.SkeepPrefixArchiveHeader()); + UInt64 complexity = 0; + for(i = 0; i < folderRefs.Size(); i++) + complexity += database->GetFolderFullPackSize(folderRefs[i]); + UInt64 inSizeForReduce = 0; + for(i = 0; i < updateItems.Size(); i++) + { + const CUpdateItem &updateItem = updateItems[i]; + if (updateItem.NewData) + { + complexity += updateItem.Size; + if (numSolidFiles == 1) + { + if (updateItem.Size > inSizeForReduce) + inSizeForReduce = updateItem.Size; + } + else + inSizeForReduce += updateItem.Size; + } + } + RINOK(updateCallback->SetTotal(complexity)); + complexity = 0; + RINOK(updateCallback->SetCompleted(&complexity)); + + ///////////////////////////////////////// + // Write Copy Items + + for(i = 0; i < folderRefs.Size(); i++) + { + int folderIndex = folderRefs[i]; + + RINOK(WriteRange(inStream, archive.SeqStream, + database->GetFolderStreamPos(folderIndex, 0), + database->GetFolderFullPackSize(folderIndex), + updateCallback, complexity)); + + const CFolder &folder = database->Folders[folderIndex]; + CNum startIndex = database->FolderStartPackStreamIndex[folderIndex]; + for (int j = 0; j < folder.PackStreams.Size(); j++) + { + newDatabase.PackSizes.Add(database->PackSizes[startIndex + j]); + // newDatabase.PackCRCsDefined.Add(database.PackCRCsDefined[startIndex + j]); + // newDatabase.PackCRCs.Add(database.PackCRCs[startIndex + j]); + } + newDatabase.Folders.Add(folder); + + CNum numUnPackStreams = database->NumUnPackStreamsVector[folderIndex]; + newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams); + + CNum indexInFolder = 0; + for (CNum fi = database->FolderStartFileIndex[folderIndex]; + indexInFolder < numUnPackStreams; fi++) + { + CFileItem file = database->Files[fi]; + if (file.HasStream) + { + indexInFolder++; + int updateIndex = fileIndexToUpdateIndexMap[fi]; + if (updateIndex >= 0) + { + const CUpdateItem &updateItem = updateItems[updateIndex]; + if (updateItem.NewProperties) + { + CFileItem file2; + FromUpdateItemToFileItem(updateItem, file2); + file2.UnPackSize = file.UnPackSize; + file2.FileCRC = file.FileCRC; + file2.IsFileCRCDefined = file.IsFileCRCDefined; + file2.HasStream = file.HasStream; + file = file2; + } + } + newDatabase.Files.Add(file); + } + } + } + + ///////////////////////////////////////// + // Compress New Files + + CObjectVector groups; + SplitFilesToGroups(*options.Method, options.UseFilters, options.MaxFilter, + updateItems, groups); + + const UInt32 kMinReduceSize = (1 << 16); + if (inSizeForReduce < kMinReduceSize) + inSizeForReduce = kMinReduceSize; + + for (int groupIndex = 0; groupIndex < groups.Size(); groupIndex++) + { + const CSolidGroup &group = groups[groupIndex]; + int numFiles = group.Indices.Size(); + if (numFiles == 0) + continue; + CRecordVector refItems; + refItems.Reserve(numFiles); + bool sortByType = (numSolidFiles > 1); + for (i = 0; i < numFiles; i++) + refItems.Add(CRefItem(group.Indices[i], updateItems[group.Indices[i]], sortByType)); + refItems.Sort(CompareUpdateItems, (void *)&sortByType); + + CRecordVector indices; + indices.Reserve(numFiles); + + for (i = 0; i < numFiles; i++) + { + UInt32 index = refItems[i].Index; + indices.Add(index); + /* + const CUpdateItem &updateItem = updateItems[index]; + CFileItem file; + if (updateItem.NewProperties) + FromUpdateItemToFileItem(updateItem, file); + else + file = database.Files[updateItem.IndexInArchive]; + if (file.IsAnti || file.IsDirectory) + return E_FAIL; + newDatabase.Files.Add(file); + */ + } + + CEncoder encoder(group.Method); + + for (i = 0; i < numFiles;) + { + UInt64 totalSize = 0; + int numSubFiles; + UString prevExtension; + for (numSubFiles = 0; i + numSubFiles < numFiles && + numSubFiles < numSolidFiles; numSubFiles++) + { + const CUpdateItem &updateItem = updateItems[indices[i + numSubFiles]]; + totalSize += updateItem.Size; + if (totalSize > options.NumSolidBytes) + break; + if (options.SolidExtension) + { + UString ext = updateItem.GetExtension(); + if (numSubFiles == 0) + prevExtension = ext; + else + if (ext.CompareNoCase(prevExtension) != 0) + break; + } + } + if (numSubFiles < 1) + numSubFiles = 1; + + CFolderInStream *inStreamSpec = new CFolderInStream; + CMyComPtr solidInStream(inStreamSpec); + inStreamSpec->Init(updateCallback, &indices[i], numSubFiles); + + CFolder folderItem; + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr localProgress = localProgressSpec; + localProgressSpec->Init(updateCallback, true); + CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo; + CMyComPtr compressProgress = localCompressProgressSpec; + localCompressProgressSpec->Init(localProgress, &complexity, NULL); + + RINOK(encoder.Encode(solidInStream, NULL, &inSizeForReduce, folderItem, + archive.SeqStream, newDatabase.PackSizes, compressProgress)); + // for() + // newDatabase.PackCRCsDefined.Add(false); + // newDatabase.PackCRCs.Add(0); + + newDatabase.Folders.Add(folderItem); + + CNum numUnPackStreams = 0; + for (int subIndex = 0; subIndex < numSubFiles; subIndex++) + { + const CUpdateItem &updateItem = updateItems[indices[i + subIndex]]; + CFileItem file; + if (updateItem.NewProperties) + FromUpdateItemToFileItem(updateItem, file); + else + file = database->Files[updateItem.IndexInArchive]; + if (file.IsAnti || file.IsDirectory) + return E_FAIL; + + /* + CFileItem &file = newDatabase.Files[ + startFileIndexInDatabase + i + subIndex]; + */ + if (!inStreamSpec->Processed[subIndex]) + { + continue; + // file.Name += L".locked"; + } + + file.FileCRC = inStreamSpec->CRCs[subIndex]; + file.UnPackSize = inStreamSpec->Sizes[subIndex]; + if (file.UnPackSize != 0) + { + file.IsFileCRCDefined = true; + file.HasStream = true; + numUnPackStreams++; + complexity += file.UnPackSize; + } + else + { + file.IsFileCRCDefined = false; + file.HasStream = false; + } + newDatabase.Files.Add(file); + } + // numUnPackStreams = 0 is very bad case for locked files + // v3.13 doesn't understand it. + newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams); + i += numSubFiles; + } + } + + { + ///////////////////////////////////////// + // Write Empty Files & Folders + + CRecordVector emptyRefs; + for(i = 0; i < updateItems.Size(); i++) + { + const CUpdateItem &updateItem = updateItems[i]; + if (updateItem.NewData) + { + if (updateItem.HasStream()) + continue; + } + else + if (updateItem.IndexInArchive != -1) + if (database->Files[updateItem.IndexInArchive].HasStream) + continue; + emptyRefs.Add(i); + } + emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems); + for(i = 0; i < emptyRefs.Size(); i++) + { + const CUpdateItem &updateItem = updateItems[emptyRefs[i]]; + CFileItem file; + if (updateItem.NewProperties) + FromUpdateItemToFileItem(updateItem, file); + else + file = database->Files[updateItem.IndexInArchive]; + newDatabase.Files.Add(file); + } + } + + /* + if (newDatabase.Files.Size() != updateItems.Size()) + return E_FAIL; + */ + + return archive.WriteDatabase(newDatabase, options.HeaderMethod, options.HeaderOptions); +} + +#ifdef _7Z_VOL + +static HRESULT WriteVolumeHeader(COutArchive &archive, CFileItem &file, const CUpdateOptions &options) +{ + CAltCoderInfo altCoder; + altCoder.MethodID.IDSize = 1; + altCoder.MethodID.ID[0] = 0; + CCoderInfo coder; + coder.NumInStreams = coder.NumOutStreams = 1; + coder.AltCoders.Add(altCoder); + + CFolder folder; + folder.Coders.Add(coder); + folder.PackStreams.Add(0); + + CNum numUnPackStreams = 0; + if (file.UnPackSize != 0) + { + file.IsFileCRCDefined = true; + file.HasStream = true; + numUnPackStreams++; + } + else + { + throw 1; + file.IsFileCRCDefined = false; + file.HasStream = false; + } + folder.UnPackSizes.Add(file.UnPackSize); + + CArchiveDatabase newDatabase; + newDatabase.Files.Add(file); + newDatabase.Folders.Add(folder); + newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams); + newDatabase.PackSizes.Add(file.UnPackSize); + newDatabase.PackCRCsDefined.Add(false); + newDatabase.PackCRCs.Add(file.FileCRC); + + return archive.WriteDatabase(newDatabase, + options.HeaderMethod, + false, + false); +} + +HRESULT UpdateVolume( + IInStream *inStream, + const CArchiveDatabaseEx *database, + CObjectVector &updateItems, + ISequentialOutStream *seqOutStream, + IArchiveUpdateCallback *updateCallback, + const CUpdateOptions &options) +{ + if (updateItems.Size() != 1) + return E_NOTIMPL; + + CMyComPtr volumeCallback; + RINOK(updateCallback->QueryInterface(IID_IArchiveUpdateCallback2, (void **)&volumeCallback)); + if (!volumeCallback) + return E_NOTIMPL; + + CMyComPtr fileStream; + HRESULT result = updateCallback->GetStream(0, &fileStream); + if (result != S_OK && result != S_FALSE) + return result; + if (result == S_FALSE) + return E_FAIL; + + CFileItem file; + + const CUpdateItem &updateItem = updateItems[0]; + if (updateItem.NewProperties) + FromUpdateItemToFileItem(updateItem, file); + else + file = database->Files[updateItem.IndexInArchive]; + if (file.IsAnti || file.IsDirectory) + return E_FAIL; + + UInt64 complexity = 0; + file.IsStartPosDefined = true; + file.StartPos = 0; + for (UInt64 volumeIndex = 0; true; volumeIndex++) + { + UInt64 volSize; + RINOK(volumeCallback->GetVolumeSize(volumeIndex, &volSize)); + UInt64 pureSize = COutArchive::GetVolPureSize(volSize, file.Name.Length(), true); + CMyComPtr volumeStream; + RINOK(volumeCallback->GetVolumeStream(volumeIndex, &volumeStream)); + + COutArchive archive; + RINOK(archive.Create(volumeStream, true)); + RINOK(archive.SkeepPrefixArchiveHeader()); + + CSequentialInStreamWithCRC *inCrcStreamSpec = new CSequentialInStreamWithCRC; + CMyComPtr inCrcStream = inCrcStreamSpec; + inCrcStreamSpec->Init(fileStream); + + RINOK(WriteRange(inCrcStream, volumeStream, pureSize, + updateCallback, complexity)); + file.UnPackSize = inCrcStreamSpec->GetSize(); + if (file.UnPackSize == 0) + break; + file.FileCRC = inCrcStreamSpec->GetCRC(); + RINOK(WriteVolumeHeader(archive, file, options)); + file.StartPos += file.UnPackSize; + if (file.UnPackSize < pureSize) + break; + } + return S_OK; +} + +class COutVolumeStream: + public ISequentialOutStream, + public CMyUnknownImp +{ + int _volIndex; + UInt64 _volSize; + UInt64 _curPos; + CMyComPtr _volumeStream; + COutArchive _archive; + CCRC _crc; + +public: + MY_UNKNOWN_IMP + + CFileItem _file; + CUpdateOptions _options; + CMyComPtr VolumeCallback; + void Init(IArchiveUpdateCallback2 *volumeCallback, + const UString &name) + { + _file.Name = name; + _file.IsStartPosDefined = true; + _file.StartPos = 0; + + VolumeCallback = volumeCallback; + _volIndex = 0; + _volSize = 0; + } + + HRESULT Flush(); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +HRESULT COutVolumeStream::Flush() +{ + if (_volumeStream) + { + _file.UnPackSize = _curPos; + _file.FileCRC = _crc.GetDigest(); + RINOK(WriteVolumeHeader(_archive, _file, _options)); + _archive.Close(); + _volumeStream.Release(); + _file.StartPos += _file.UnPackSize; + } + return S_OK; +} + +STDMETHODIMP COutVolumeStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if(processedSize != NULL) + *processedSize = 0; + while(size > 0) + { + if (!_volumeStream) + { + RINOK(VolumeCallback->GetVolumeSize(_volIndex, &_volSize)); + RINOK(VolumeCallback->GetVolumeStream(_volIndex, &_volumeStream)); + _volIndex++; + _curPos = 0; + RINOK(_archive.Create(_volumeStream, true)); + RINOK(_archive.SkeepPrefixArchiveHeader()); + _crc.Init(); + continue; + } + UInt64 pureSize = COutArchive::GetVolPureSize(_volSize, _file.Name.Length()); + UInt32 curSize = (UInt32)MyMin(UInt64(size), pureSize - _curPos); + + _crc.Update(data, curSize); + UInt32 realProcessed; + RINOK(_volumeStream->Write(data, curSize, &realProcessed)) + data = (void *)((Byte *)data + realProcessed); + size -= realProcessed; + if(processedSize != NULL) + *processedSize += realProcessed; + _curPos += realProcessed; + if (realProcessed != curSize && realProcessed == 0) + return E_FAIL; + if (_curPos == pureSize) + { + RINOK(Flush()); + } + } + return S_OK; +} + +#endif + +HRESULT Update( + IInStream *inStream, + const CArchiveDatabaseEx *database, + const CObjectVector &updateItems, + ISequentialOutStream *seqOutStream, + IArchiveUpdateCallback *updateCallback, + const CUpdateOptions &options) +{ + #ifdef _7Z_VOL + if (seqOutStream) + #endif + return Update2(inStream, database, updateItems, + seqOutStream, updateCallback, options); + #ifdef _7Z_VOL + if (options.VolumeMode) + return UpdateVolume(inStream, database, updateItems, + seqOutStream, updateCallback, options); + COutVolumeStream *volStreamSpec = new COutVolumeStream; + CMyComPtr volStream = volStreamSpec; + CMyComPtr volumeCallback; + RINOK(updateCallback->QueryInterface(IID_IArchiveUpdateCallback2, (void **)&volumeCallback)); + if (!volumeCallback) + return E_NOTIMPL; + volStreamSpec->Init(volumeCallback, L"a.7z"); + volStreamSpec->_options = options; + RINOK(Update2(inStream, database, updateItems, + volStream, updateCallback, options)); + return volStreamSpec->Flush(); + #endif +} + +}} diff --git a/CPP/7zip/Archive/7z/7zUpdate.h b/CPP/7zip/Archive/7z/7zUpdate.h new file mode 100755 index 00000000..385bd942 --- /dev/null +++ b/CPP/7zip/Archive/7z/7zUpdate.h @@ -0,0 +1,79 @@ +// 7zUpdate.h + +#ifndef __7Z_UPDATE_H +#define __7Z_UPDATE_H + +#include "7zIn.h" +#include "7zOut.h" +#include "7zCompressionMode.h" + +#include "../IArchive.h" + +namespace NArchive { +namespace N7z { + +struct CUpdateItem +{ + bool NewData; + bool NewProperties; + int IndexInArchive; + int IndexInClient; + + UInt32 Attributes; + FILETIME CreationTime; + FILETIME LastWriteTime; + FILETIME LastAccessTime; + + UInt64 Size; + UString Name; + + bool IsAnti; + bool IsDirectory; + + bool IsCreationTimeDefined; + bool IsLastWriteTimeDefined; + bool IsLastAccessTimeDefined; + bool AttributesAreDefined; + + const bool HasStream() const + { return !IsDirectory && !IsAnti && Size != 0; } + CUpdateItem(): + IsAnti(false), + AttributesAreDefined(false), + IsCreationTimeDefined(false), + IsLastWriteTimeDefined(false), + IsLastAccessTimeDefined(false) + {} + void SetDirectoryStatusFromAttributes() + { IsDirectory = ((Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); }; + + int GetExtensionPos() const; + UString GetExtension() const; +}; + +struct CUpdateOptions +{ + const CCompressionMethodMode *Method; + const CCompressionMethodMode *HeaderMethod; + bool UseFilters; + bool MaxFilter; + + CHeaderOptions HeaderOptions; + + UInt64 NumSolidFiles; + UInt64 NumSolidBytes; + bool SolidExtension; + bool RemoveSfxBlock; + bool VolumeMode; +}; + +HRESULT Update( + IInStream *inStream, + const CArchiveDatabaseEx *database, + const CObjectVector &updateItems, + ISequentialOutStream *seqOutStream, + IArchiveUpdateCallback *updateCallback, + const CUpdateOptions &options); +}} + +#endif diff --git a/CPP/7zip/Archive/7z/DllExports.cpp b/CPP/7zip/Archive/7z/DllExports.cpp new file mode 100755 index 00000000..2d70d4de --- /dev/null +++ b/CPP/7zip/Archive/7z/DllExports.cpp @@ -0,0 +1,113 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "../../../Common/MyInitGuid.h" +#include "../../../Common/ComTry.h" +#ifdef _WIN32 +#include "../../../Common/Alloc.h" +#endif + +#include "../../ICoder.h" + +#include "7zHandler.h" + +#ifndef EXCLUDE_COM +// {23170F69-40C1-278B-06F1-070100000100} +DEFINE_GUID(CLSID_CCrypto7zAESEncoder, +0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x07, 0x01, 0x00, 0x00, 0x01, 0x00); +#endif + +HINSTANCE g_hInstance; +#ifndef _UNICODE +bool g_IsNT = false; +static bool IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); +} +#endif + + +extern "C" +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + g_hInstance = hInstance; + #ifndef _UNICODE + g_IsNT = IsItWindowsNT(); + #endif + #ifdef _WIN32 + SetLargePageSize(); + #endif + } + return TRUE; +} + + +STDAPI CreateObject( + const GUID *classID, + const GUID *interfaceID, + void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + if (*classID != NArchive::N7z::CLSID_CFormat7z) + return CLASS_E_CLASSNOTAVAILABLE; + if (*interfaceID == IID_IInArchive) + { + CMyComPtr inArchive = new NArchive::N7z::CHandler; + *outObject = inArchive.Detach(); + } + #ifndef EXTRACT_ONLY + else if (*interfaceID == IID_IOutArchive) + { + CMyComPtr outArchive = new NArchive::N7z::CHandler; + *outObject = outArchive.Detach(); + } + #endif + else + return E_NOINTERFACE; + COM_TRY_END + return S_OK; +} + +STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case NArchive::kName: + propVariant = L"7z"; + break; + case NArchive::kClassID: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&NArchive::N7z::CLSID_CFormat7z, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NArchive::kExtension: + propVariant = L"7z"; + break; + case NArchive::kUpdate: + propVariant = true; + break; + case NArchive::kKeepName: + propVariant = false; + break; + case NArchive::kStartSignature: + { + if ((value->bstrVal = ::SysAllocStringByteLen((const char *)NArchive::N7z::kSignature, + NArchive::N7z::kSignatureSize)) != 0) + value->vt = VT_BSTR; + return S_OK; + } + } + propVariant.Detach(value); + return S_OK; +} diff --git a/CPP/7zip/Archive/7z/StdAfx.cpp b/CPP/7zip/Archive/7z/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Archive/7z/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Archive/7z/StdAfx.h b/CPP/7zip/Archive/7z/StdAfx.h new file mode 100755 index 00000000..2e4be10b --- /dev/null +++ b/CPP/7zip/Archive/7z/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" +#include "../../../Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/Archive/7z/makefile b/CPP/7zip/Archive/7z/makefile new file mode 100755 index 00000000..06bf2f37 --- /dev/null +++ b/CPP/7zip/Archive/7z/makefile @@ -0,0 +1,89 @@ +PROG = 7z.dll +DEF_FILE = ../Archive.def +CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_MT +LIBS = $(LIBS) oleaut32.lib user32.lib + +7Z_OBJS = \ + $O\7zCompressionMode.obj \ + $O\7zDecode.obj \ + $O\7zEncode.obj \ + $O\7zExtract.obj \ + $O\7zFolderInStream.obj \ + $O\7zFolderOutStream.obj \ + $O\7zHandler.obj \ + $O\7zHandlerOut.obj \ + $O\7zHeader.obj \ + $O\7zIn.obj \ + $O\7zMethodID.obj \ + $O\7zMethods.obj \ + $O\7zOut.obj \ + $O\7zProperties.obj \ + $O\7zSpecStream.obj \ + $O\7zUpdate.obj \ + $O\DllExports.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CRC.obj \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\Vector.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\PropVariant.obj \ + $O\Synchronization.obj + +7ZIP_COMMON_OBJS = \ + $O\InOutTempBuffer.obj \ + $O\LimitedStreams.obj \ + $O\LockedStream.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\StreamBinder.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + +AR_COMMON_OBJS = \ + $O\CodecsPath.obj \ + $O\CoderLoader.obj \ + $O\CoderMixer2.obj \ + $O\CoderMixer2MT.obj \ + $O\CrossThreadProgress.obj \ + $O\FilterCoder.obj \ + $O\InStreamWithCRC.obj \ + $O\ItemNameUtils.obj \ + $O\MultiStream.obj \ + $O\OutStreamWithCRC.obj \ + $O\ParseProperties.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(7Z_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $O\CopyCoder.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(7Z_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/Archive/7z/resource.rc b/CPP/7zip/Archive/7z/resource.rc new file mode 100755 index 00000000..8868173c --- /dev/null +++ b/CPP/7zip/Archive/7z/resource.rc @@ -0,0 +1,5 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("7z Plugin", "7z") + +101 ICON "7z.ico" diff --git a/CPP/7zip/Archive/Archive.def b/CPP/7zip/Archive/Archive.def new file mode 100755 index 00000000..befc7d83 --- /dev/null +++ b/CPP/7zip/Archive/Archive.def @@ -0,0 +1,3 @@ +EXPORTS + CreateObject PRIVATE + GetHandlerProperty PRIVATE diff --git a/CPP/7zip/Archive/Arj/Arj.dsp b/CPP/7zip/Archive/Arj/Arj.dsp new file mode 100755 index 00000000..3bc6fa91 --- /dev/null +++ b/CPP/7zip/Archive/Arj/Arj.dsp @@ -0,0 +1,329 @@ +# Microsoft Developer Studio Project File - Name="arj" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=arj - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "arj.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "arj.mak" CFG="arj - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "arj - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "arj - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "arj - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARJ_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARJ_EXPORTS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\arj.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "arj - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARJ_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARJ_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\arj.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "arj - Win32 Release" +# Name "arj - Win32 Debug" +# Begin Group "spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Archive.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ArjHandler.cpp +# End Source File +# Begin Source File + +SOURCE=.\ArjHandler.h +# End Source File +# Begin Source File + +SOURCE=.\ArjHeader.h +# End Source File +# Begin Source File + +SOURCE=.\ArjIn.cpp +# End Source File +# Begin Source File + +SOURCE=.\ArjIn.h +# End Source File +# Begin Source File + +SOURCE=.\ArjItem.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Group "Codecs" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Arj\ArjDecoder1.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Arj\ArjDecoder1.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Arj\ArjDecoder2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Arj\ArjDecoder2.h +# End Source File +# End Group +# Begin Group "LZ" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.h +# End Source File +# End Group +# Begin Group "Copy" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# End Group +# Begin Group "7zip common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MSBFDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\OutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\OutStreamWithCRC.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\arj.ico +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/Archive/Arj/Arj.dsw b/CPP/7zip/Archive/Arj/Arj.dsw new file mode 100755 index 00000000..7ce4bca5 --- /dev/null +++ b/CPP/7zip/Archive/Arj/Arj.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "arj"=.\arj.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Archive/Arj/ArjHandler.cpp b/CPP/7zip/Archive/Arj/ArjHandler.cpp new file mode 100755 index 00000000..a61cc775 --- /dev/null +++ b/CPP/7zip/Archive/Arj/ArjHandler.cpp @@ -0,0 +1,485 @@ +// ArjHandler.cpp + +#include "StdAfx.h" + +#include "Common/Defs.h" +#include "Common/CRC.h" +#include "Common/StringConvert.h" +#include "Common/ComTry.h" + +#include "Windows/Time.h" +#include "Windows/PropVariant.h" + +#include "ArjHandler.h" + +#include "../../ICoder.h" + +#include "../../Common/StreamObjects.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/LimitedStreams.h" + +#include "../../Compress/Copy/CopyCoder.h" +#include "../../Compress/Arj/ArjDecoder1.h" +#include "../../Compress/Arj/ArjDecoder2.h" + +#include "../Common/ItemNameUtils.h" +#include "../Common/OutStreamWithCRC.h" + +using namespace NWindows; +using namespace NTime; + +namespace NArchive { +namespace NArj{ + +const wchar_t *kHostOS[] = +{ + L"MSDOS", + L"PRIMOS", + L"Unix", + L"AMIGA", + L"Mac", + L"OS/2", + L"APPLE GS", + L"Atari ST", + L"Next", + L"VAX VMS", + L"WIN95" +}; + + +const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]); + +const wchar_t *kUnknownOS = L"Unknown"; + + +/* +enum // PropID +{ + kpidHostOS = kpidUserDefined, + kpidUnPackVersion, + kpidMethod, +}; +*/ + +STATPROPSTG kProperties[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackedSize, VT_UI8}, + { NULL, kpidLastWriteTime, VT_FILETIME}, + { NULL, kpidAttributes, VT_UI4}, + + { NULL, kpidEncrypted, VT_BOOL}, + // { NULL, kpidCommented, VT_BOOL}, + + { NULL, kpidCRC, VT_UI4}, + + { NULL, kpidMethod, VT_UI1}, + { NULL, kpidHostOS, VT_BSTR} + + // { L"UnPack Version", kpidUnPackVersion, VT_UI1}, + // { L"Method", kpidMethod, VT_UI1}, + // { L"Host OS", kpidHostOS, VT_BSTR} +}; + + +CHandler::CHandler() +{} + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) +{ + value->vt = VT_EMPTY; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if(index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &srcItem = kProperties[index]; + *propID = srcItem.propid; + *varType = srcItem.vt; + *name = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +{ + *numProperties = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, + BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _items.Size(); + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant propVariant; + const CItemEx &item = _items[index]; + switch(propID) + { + case kpidPath: + propVariant = + NItemName::GetOSName(MultiByteToUnicodeString(item.Name, CP_OEMCP)); + /* + NItemName::GetOSName2( + MultiByteToUnicodeString(item.Name, item.GetCodePage())); + */ + break; + case kpidIsFolder: + propVariant = item.IsDirectory(); + break; + case kpidSize: + propVariant = item.Size; + break; + case kpidPackedSize: + propVariant = item.PackSize; + break; + case kpidLastWriteTime: + { + FILETIME localFileTime, utcFileTime; + if (DosTimeToFileTime(item.ModifiedTime, localFileTime)) + { + if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime)) + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; + } + else + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; + propVariant = utcFileTime; + break; + } + case kpidAttributes: + propVariant = item.GetWinAttributes(); + break; + case kpidEncrypted: + propVariant = item.IsEncrypted(); + break; + /* + case kpidCommented: + propVariant = item.IsCommented(); + break; + */ + case kpidCRC: + propVariant = item.FileCRC; + break; + case kpidMethod: + propVariant = item.Method; + break; + case kpidHostOS: + propVariant = (item.HostOS < kNumHostOSes) ? + (kHostOS[item.HostOS]) : kUnknownOS; + break; + } + propVariant.Detach(value); + return S_OK; + COM_TRY_END +} + +/* +class CPropgressImp: public CProgressVirt +{ +public: + CMyComPtr Callback; + STDMETHOD(SetCompleted)(const UInt64 *numFiles); +}; + +STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles) +{ + if (Callback) + return Callback->SetCompleted(numFiles, NULL); + return S_OK; +} +*/ + +STDMETHODIMP CHandler::Open(IInStream *inStream, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback) +{ + COM_TRY_BEGIN + try + { + _items.Clear(); + CInArchive archive; + if(!archive.Open(inStream, maxCheckStartPosition)) + return S_FALSE; + if (callback != NULL) + { + RINOK(callback->SetTotal(NULL, NULL)); + UInt64 numFiles = _items.Size(); + RINOK(callback->SetCompleted(&numFiles, NULL)); + } + for (;;) + { + CItemEx itemInfo; + bool filled; + HRESULT result = archive.GetNextItem(filled, itemInfo); + if (result == S_FALSE) + return S_FALSE; + if (result != S_OK) + return S_FALSE; + if (!filled) + break; + _items.Add(itemInfo); + archive.IncreaseRealPosition(itemInfo.PackSize); + if (callback != NULL) + { + UInt64 numFiles = _items.Size(); + RINOK(callback->SetCompleted(&numFiles, NULL)); + } + } + _stream = inStream; + } + catch(...) + { + return S_FALSE; + } + COM_TRY_END + return S_OK; +} + +STDMETHODIMP CHandler::Close() +{ + _items.Clear(); + _stream.Release(); + return S_OK; +} + + + +////////////////////////////////////// +// CHandler::DecompressItems + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 testModeSpec, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool testMode = (testModeSpec != 0); + UInt64 totalUnPacked = 0, totalPacked = 0; + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = _items.Size(); + if(numItems == 0) + return S_OK; + UInt32 i; + for(i = 0; i < numItems; i++) + { + const CItemEx &itemInfo = _items[allFilesMode ? i : indices[i]]; + totalUnPacked += itemInfo.Size; + totalPacked += itemInfo.PackSize; + } + extractCallback->SetTotal(totalUnPacked); + + UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0; + UInt64 currentItemUnPacked, currentItemPacked; + + CMyComPtr arj1Decoder; + CMyComPtr arj2Decoder; + CMyComPtr copyCoder; + + for(i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked, + currentTotalPacked += currentItemPacked) + { + currentItemUnPacked = 0; + currentItemPacked = 0; + + RINOK(extractCallback->SetCompleted(¤tTotalUnPacked)); + CMyComPtr 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 outStream(outStreamSpec); + outStreamSpec->SetStream(realOutStream); + outStreamSpec->Init(); + realOutStream.Release(); + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr inStream(streamSpec); + + UInt64 pos; + _stream->Seek(itemInfo.DataPosition, STREAM_SEEK_SET, &pos); + + streamSpec->SetStream(_stream); + streamSpec->Init(itemInfo.PackSize); + + + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr progress = localProgressSpec; + localProgressSpec->Init(extractCallback, false); + + + CLocalCompressProgressInfo *localCompressProgressSpec = + new CLocalCompressProgressInfo; + CMyComPtr compressProgress = localCompressProgressSpec; + localCompressProgressSpec->Init(progress, + ¤tTotalPacked, + ¤tTotalUnPacked); + + 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, ¤tItemUnPacked, 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, ¤tItemUnPacked, compressProgress); + } + if (result == S_FALSE) + throw "data error"; + if (result != S_OK) + return result; + } + catch(...) + { + outStream.Release(); + RINOK(extractCallback->SetOperationResult( + NArchive::NExtract::NOperationResult::kDataError)); + continue; + } + break; + } + default: + RINOK(extractCallback->SetOperationResult( + NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + continue; + } + bool crcOK = outStreamSpec->GetCRC() == itemInfo.FileCRC; + outStream.Release(); + if(crcOK) + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)) + else + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError)) + } + } + return S_OK; + COM_TRY_END +} + + +}} diff --git a/CPP/7zip/Archive/Arj/ArjHandler.h b/CPP/7zip/Archive/Arj/ArjHandler.h new file mode 100755 index 00000000..a1e69ba6 --- /dev/null +++ b/CPP/7zip/Archive/Arj/ArjHandler.h @@ -0,0 +1,47 @@ +// ArjHandler.h + +#ifndef __ARJ_HANDLER_H +#define __ARJ_HANDLER_H + +#include "Common/MyCom.h" +#include "../IArchive.h" +#include "ArjIn.h" + +namespace NArchive { +namespace NArj { + +class CHandler: + public IInArchive, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Open)(IInStream *inStream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *callback); + STDMETHOD(Close)(); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *anExtractCallback); + + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + CHandler(); +private: + CObjectVector _items; + CMyComPtr _stream; +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Arj/ArjHeader.h b/CPP/7zip/Archive/Arj/ArjHeader.h new file mode 100755 index 00000000..58ee8c27 --- /dev/null +++ b/CPP/7zip/Archive/Arj/ArjHeader.h @@ -0,0 +1,121 @@ +// Archive/Arj/Header.h + +#ifndef __ARCHIVE_ARJ_HEADER_H +#define __ARCHIVE_ARJ_HEADER_H + +#include "Common/Types.h" + +namespace NArchive { +namespace NArj { + +const int kMaxBlockSize = 2600; + +namespace NSignature +{ + const Byte kSig0 = 0x60; + const Byte kSig1 = 0xEA; +} + +/* +struct CArchiveHeader +{ + // UInt16 BasicHeaderSize; + Byte FirstHeaderSize; + Byte Version; + Byte ExtractVersion; + Byte HostOS; + Byte Flags; + Byte SecuryVersion; + Byte FileType; + Byte Reserved; + UInt32 CreatedTime; + UInt32 ModifiedTime; + UInt32 ArchiveSize; + UInt32 SecurityEnvelopeFilePosition; + UInt16 FilespecPositionInFilename; + UInt16 LengthOfSecurityEnvelopeSata; + Byte EncryptionVersion; + Byte LastChapter; +}; +*/ + +namespace NFileHeader +{ + namespace NCompressionMethod + { + enum EType + { + kStored = 0, + kCompressed1a = 1, + kCompressed1b = 2, + kCompressed1c = 3, + kCompressed2 = 4, + kNoDataNoCRC = 8, + kNoData = 9, + }; + } + namespace NFileType + { + enum EType + { + kBinary = 0, + k7BitText = 1, + kDirectory = 3, + kVolumeLablel = 4, + kChapterLabel = 5, + }; + } + namespace NFlags + { + const Byte kGarbled = 1; + const Byte kVolume = 4; + const Byte kExtFile = 8; + const Byte kPathSym = 0x10; + const Byte kBackup= 0x20; + } + + /* + struct CHeader + { + Byte FirstHeaderSize; + Byte Version; + Byte ExtractVersion; + Byte HostOS; + Byte Flags; + Byte Method; + Byte FileType; + Byte Reserved; + UInt32 ModifiedTime; + UInt32 PackSize; + UInt32 Size; + UInt32 FileCRC; + UInt16 FilespecPositionInFilename; + UInt16 FileAccessMode; + Byte FirstChapter; + Byte LastChapter; + }; + */ + + namespace NHostOS + { + enum EEnum + { + kMSDOS = 0, // filesystem used by MS-DOS, OS/2, Win32 + // pkarj 2.50 (FAT / VFAT / FAT32 file systems) + kPRIMOS = 1, + kUnix = 2, // VAX/VMS + kAMIGA = 3, + kMac = 4, + kOS_2 = 5, // what if it's a minix filesystem? [cjh] + kAPPLE_GS = 6, // filesystem used by OS/2 (and NT 3.x) + kAtari_ST = 7, + kNext = 8, + kVAX_VMS = 9, + kWIN95 = 10 + }; + } +} + +}} + +#endif diff --git a/CPP/7zip/Archive/Arj/ArjIn.cpp b/CPP/7zip/Archive/Arj/ArjIn.cpp new file mode 100755 index 00000000..5d03ea65 --- /dev/null +++ b/CPP/7zip/Archive/Arj/ArjIn.cpp @@ -0,0 +1,283 @@ +// Archive/arj/InEngine.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Common/Buffer.h" +#include "Common/CRC.h" + +#include "../../Common/StreamUtils.h" + +#include "ArjIn.h" + +namespace NArchive { +namespace NArj { + +HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize; + HRESULT result = ReadStream(_stream, data, size, &realProcessedSize); + if(processedSize != NULL) + *processedSize = realProcessedSize; + IncreasePositionValue(realProcessedSize); + return result; +} + +static inline UInt16 GetUInt16FromMemLE(const Byte *p) +{ + return (UInt16)(p[0] | (((UInt16)p[1]) << 8)); +} + +static inline UInt32 GetUInt32FromMemLE(const Byte *p) +{ + return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24); +} + +inline bool TestMarkerCandidate(const void *testBytes, UInt32 maxSize) +{ + if (maxSize < 2 + 2 + 4) + return false; + const Byte *block = ((const Byte *)(testBytes)); + if (block[0] != NSignature::kSig0 || block[1] != NSignature::kSig1) + return false; + UInt32 blockSize = GetUInt16FromMemLE(block + 2); + if (maxSize < 2 + 2 + blockSize + 4) + return false; + block += 4; + if (blockSize == 0 || blockSize > 2600) + return false; + UInt32 crcFromFile = GetUInt32FromMemLE(block + blockSize); + return (CCRC::VerifyDigest(crcFromFile, block, blockSize)); +} + +bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit) +{ + // _archiveInfo.StartPosition = 0; + _position = _streamStartPosition; + if(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL) != S_OK) + return false; + + const int kMarkerSizeMax = 2 + 2 + kMaxBlockSize + 4; + + CByteBuffer byteBuffer; + static const UInt32 kSearchMarkerBufferSize = 0x10000; + byteBuffer.SetCapacity(kSearchMarkerBufferSize); + Byte *buffer = byteBuffer; + + UInt32 processedSize; + ReadBytes(buffer, kMarkerSizeMax, &processedSize); + if (processedSize == 0) + return false; + if (TestMarkerCandidate(buffer, processedSize)) + { + _position = _streamStartPosition; + if(_stream->Seek(_position, STREAM_SEEK_SET, NULL) != S_OK) + return false; + return true; + } + + UInt32 numBytesPrev = processedSize - 1; + memmove(buffer, buffer + 1, numBytesPrev); + UInt64 curTestPos = _streamStartPosition + 1; + for (;;) + { + if (searchHeaderSizeLimit != NULL) + if (curTestPos - _streamStartPosition > *searchHeaderSizeLimit) + return false; + UInt32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev; + ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize); + UInt32 numBytesInBuffer = numBytesPrev + processedSize; + if (numBytesInBuffer < 1) + return false; + UInt32 numTests = numBytesInBuffer; + for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++) + { + if (TestMarkerCandidate(buffer + pos, numBytesInBuffer - pos)) + { + // _archiveInfo.StartPosition = curTestPos; + _position = curTestPos; + if(_stream->Seek(_position, STREAM_SEEK_SET, NULL) != S_OK) + return false; + return true; + } + } + numBytesPrev = numBytesInBuffer - numTests; + memmove(buffer, buffer + numTests, numBytesPrev); + } +} + +void CInArchive::IncreasePositionValue(UInt64 addValue) +{ + _position += addValue; +} + +void CInArchive::IncreaseRealPosition(UInt64 addValue) +{ + if(_stream->Seek(addValue, STREAM_SEEK_CUR, &_position) != S_OK) + throw CInArchiveException(CInArchiveException::kSeekStreamError); +} + +bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size) +{ + UInt32 realProcessedSize; + if(ReadBytes(data, size, &realProcessedSize) != S_OK) + throw CInArchiveException(CInArchiveException::kReadStreamError); + return (realProcessedSize == size); +} + +void CInArchive::SafeReadBytes(void *data, UInt32 size) +{ + if(!ReadBytesAndTestSize(data, size)) + throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); +} + +Byte CInArchive::SafeReadByte() +{ + Byte b; + SafeReadBytes(&b, 1); + return b; +} + +UInt16 CInArchive::SafeReadUInt16() +{ + UInt16 value = 0; + for (int i = 0; i < 2; i++) + { + Byte b = SafeReadByte(); + value |= (UInt16(b) << (8 * i)); + } + return value; +} + +UInt32 CInArchive::SafeReadUInt32() +{ + UInt32 value = 0; + for (int i = 0; i < 4; i++) + { + Byte b = SafeReadByte(); + value |= (UInt32(b) << (8 * i)); + } + return value; +} + +bool CInArchive::ReadBlock() +{ + _blockPos = 0; + _blockSize = SafeReadUInt16(); + if (_blockSize == 0 || _blockSize > kMaxBlockSize) + return false; + SafeReadBytes(_block, _blockSize); + UInt32 crcFromFile = SafeReadUInt32(); + if (!CCRC::VerifyDigest(crcFromFile, _block, _blockSize)) + throw CInArchiveException(CInArchiveException::kCRCError); + return true; +} + +bool CInArchive::ReadBlock2() +{ + Byte id[2]; + ReadBytesAndTestSize(id, 2); + if (id[0] != NSignature::kSig0 || id[1] != NSignature::kSig1) + throw CInArchiveException(CInArchiveException::kIncorrectArchive); + return ReadBlock(); +} + +bool CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit) +{ + _stream = inStream; + if(_stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition) != S_OK) + return false; + _position = _streamStartPosition; + if (!FindAndReadMarker(searchHeaderSizeLimit)) + return false; + if (!ReadBlock2()) + return false; + for (;;) + if (!ReadBlock()) + break; + return true; +} + +void CInArchive::Close() +{ + _stream.Release(); +} + +void CInArchive::ThrowIncorrectArchiveException() +{ + throw CInArchiveException(CInArchiveException::kIncorrectArchive); +} + +Byte CInArchive::ReadByte() +{ + if (_blockPos >= _blockSize) + ThrowIncorrectArchiveException(); + return _block[_blockPos++]; +} + +UInt16 CInArchive::ReadUInt16() +{ + UInt16 value = 0; + for (int i = 0; i < 2; i++) + { + Byte b = ReadByte(); + value |= (UInt16(b) << (8 * i)); + } + return value; +} + +UInt32 CInArchive::ReadUInt32() +{ + UInt32 value = 0; + for (int i = 0; i < 4; i++) + { + Byte b = ReadByte(); + value |= (UInt32(b) << (8 * i)); + } + return value; +} + +HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) +{ + filled = false; + if (!ReadBlock2()) + return S_OK; + + Byte firstHeaderSize = ReadByte(); + item.Version = ReadByte(); + item.ExtractVersion = ReadByte(); + item.HostOS = ReadByte(); + item.Flags = ReadByte(); + item.Method = ReadByte(); + item.FileType = ReadByte(); + ReadByte(); // Reserved + item.ModifiedTime = ReadUInt32(); + item.PackSize = ReadUInt32(); + item.Size = ReadUInt32(); + item.FileCRC = ReadUInt32(); + ReadUInt16(); // FilespecPositionInFilename + item.FileAccessMode = ReadUInt16(); + ReadByte(); // FirstChapter + ReadByte(); // LastChapter + + /* + UInt32 extraData; + if ((header.Flags & NFileHeader::NFlags::kExtFile) != 0) + extraData = GetUInt32FromMemLE(_block + pos); + */ + _blockPos = firstHeaderSize; + + for (; _blockPos < _blockSize;) + item.Name += (char)ReadByte(); + + for (;;) + if (!ReadBlock()) + break; + + item.DataPosition = _position; + + filled = true; + return S_OK; +} + +}} diff --git a/CPP/7zip/Archive/Arj/ArjIn.h b/CPP/7zip/Archive/Arj/ArjIn.h new file mode 100755 index 00000000..b73d7dba --- /dev/null +++ b/CPP/7zip/Archive/Arj/ArjIn.h @@ -0,0 +1,75 @@ +// Archive/ArjIn.h + +#ifndef __ARCHIVE_ARJIN_H +#define __ARCHIVE_ARJIN_H + +#include "Common/MyCom.h" +#include "../../IStream.h" + +#include "ArjItem.h" + +namespace NArchive { +namespace NArj { + +class CInArchiveException +{ +public: + enum CCauseType + { + kUnexpectedEndOfArchive = 0, + kCRCError, + kIncorrectArchive, + kReadStreamError, + kSeekStreamError + } + Cause; + CInArchiveException(CCauseType cause): Cause(cause) {}; +}; + +class CProgressVirt +{ +public: + STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE; +}; + +class CInArchive +{ + CMyComPtr _stream; + UInt64 _streamStartPosition; + UInt64 _position; + UInt16 _blockSize; + Byte _block[kMaxBlockSize]; + UInt32 _blockPos; + + + bool FindAndReadMarker(const UInt64 *searchHeaderSizeLimit); + + bool ReadBlock(); + bool ReadBlock2(); + + Byte ReadByte(); + UInt16 ReadUInt16(); + UInt32 ReadUInt32(); + + HRESULT ReadBytes(void *data, UInt32 size, UInt32 *processedSize); + bool ReadBytesAndTestSize(void *data, UInt32 size); + void SafeReadBytes(void *data, UInt32 size); + Byte SafeReadByte(); + UInt16 SafeReadUInt16(); + UInt32 SafeReadUInt32(); + + void IncreasePositionValue(UInt64 addValue); + void ThrowIncorrectArchiveException(); + +public: + HRESULT GetNextItem(bool &filled, CItemEx &item); + + bool Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit); + void Close(); + + void IncreaseRealPosition(UInt64 addValue); +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Arj/ArjItem.h b/CPP/7zip/Archive/Arj/ArjItem.h new file mode 100755 index 00000000..d48fe38d --- /dev/null +++ b/CPP/7zip/Archive/Arj/ArjItem.h @@ -0,0 +1,75 @@ +// Archive/ArjItem.h + +#ifndef __ARCHIVE_ARJ_ITEM_H +#define __ARCHIVE_ARJ_ITEM_H + +#include "Common/Types.h" +#include "Common/String.h" +#include "ArjHeader.h" + +namespace NArchive { +namespace NArj { + +struct CVersion +{ + Byte Version; + Byte HostOS; +}; + +inline bool operator==(const CVersion &v1, const CVersion &v2) + { return (v1.Version == v2.Version) && (v1.HostOS == v2.HostOS); } +inline bool operator!=(const CVersion &v1, const CVersion &v2) + { return !(v1 == v2); } + +class CItem +{ +public: + Byte Version; + Byte ExtractVersion; + Byte HostOS; + Byte Flags; + Byte Method; + Byte FileType; + UInt32 ModifiedTime; + UInt32 PackSize; + UInt32 Size; + UInt32 FileCRC; + + // UInt16 FilespecPositionInFilename; + UInt16 FileAccessMode; + // Byte FirstChapter; + // Byte LastChapter; + + AString Name; + + bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kGarbled) != 0; } + bool IsDirectory() const { return (FileType == NFileHeader::NFileType::kDirectory); } + UInt32 GetWinAttributes() const + { + UInt32 winAtrributes; + switch(HostOS) + { + case NFileHeader::NHostOS::kMSDOS: + case NFileHeader::NHostOS::kWIN95: + winAtrributes = FileAccessMode; + break; + default: + winAtrributes = 0; + } + if (IsDirectory()) + winAtrributes |= FILE_ATTRIBUTE_DIRECTORY; + return winAtrributes; + } +}; + +class CItemEx: public CItem +{ +public: + UInt64 DataPosition; +}; + +}} + +#endif + + diff --git a/CPP/7zip/Archive/Arj/DllExports.cpp b/CPP/7zip/Archive/Arj/DllExports.cpp new file mode 100755 index 00000000..d32ca2d6 --- /dev/null +++ b/CPP/7zip/Archive/Arj/DllExports.cpp @@ -0,0 +1,72 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "Windows/PropVariant.h" +#include "../../ICoder.h" +#include "ArjHandler.h" + +// {23170F69-40C1-278A-1000-000110040000} +DEFINE_GUID(CLSID_CArjHandler, + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x04, 0x00, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /*lpReserved*/) +{ + return TRUE; +} + +STDAPI CreateObject( + const GUID *classID, + const GUID *interfaceID, + void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + if (*classID != CLSID_CArjHandler) + return CLASS_E_CLASSNOTAVAILABLE; + if (*interfaceID != IID_IInArchive) + return E_NOINTERFACE; + CMyComPtr inArchive = (IInArchive *)new NArchive::NArj::CHandler; + *outObject = inArchive.Detach(); + COM_TRY_END + return S_OK; +} + +STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case NArchive::kName: + propVariant = L"Arj"; + break; + case NArchive::kClassID: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CArjHandler, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NArchive::kExtension: + propVariant = L"arj"; + break; + case NArchive::kUpdate: + propVariant = false; + break; + case NArchive::kKeepName: + propVariant = false; + break; + case NArchive::kStartSignature: + { + const unsigned char sig[] = { 0x60, 0xEA }; + if ((value->bstrVal = ::SysAllocStringByteLen((const char *)sig, 2)) != 0) + value->vt = VT_BSTR; + return S_OK; + } + } + propVariant.Detach(value); + return S_OK; +} diff --git a/CPP/7zip/Archive/Arj/StdAfx.cpp b/CPP/7zip/Archive/Arj/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Archive/Arj/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Arj/StdAfx.h b/CPP/7zip/Archive/Arj/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Archive/Arj/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Archive/Arj/arj.ico b/CPP/7zip/Archive/Arj/arj.ico new file mode 100755 index 00000000..c0f8b141 Binary files /dev/null and b/CPP/7zip/Archive/Arj/arj.ico differ diff --git a/CPP/7zip/Archive/Arj/makefile b/CPP/7zip/Archive/Arj/makefile new file mode 100755 index 00000000..2609998b --- /dev/null +++ b/CPP/7zip/Archive/Arj/makefile @@ -0,0 +1,66 @@ +PROG = arj.dll +DEF_FILE = ../Archive.def +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib user32.lib + +ARJ_OBJS = \ + $O\DllExports.obj \ + $O\ArjHandler.obj \ + $O\ArjIn.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CRC.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\Vector.obj \ + +WIN_OBJS = \ + $O\PropVariant.obj \ + +7ZIP_COMMON_OBJS = \ + $O\InBuffer.obj \ + $O\LimitedStreams.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ + +AR_COMMON_OBJS = \ + $O\ItemNameUtils.obj \ + $O\OutStreamWithCRC.obj \ + +COMPRESS_ARJ_OBJS = \ + $O\ArjDecoder1.obj \ + $O\ArjDecoder2.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(ARJ_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $(COMPRESS_ARJ_OBJS) \ + $O\CopyCoder.obj \ + $O\LZOutWindow.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(ARJ_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$(COMPRESS_ARJ_OBJS): ../../Compress/Arj/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) +$O\LZOutWindow.obj: ../../Compress/LZ/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/Archive/Arj/resource.rc b/CPP/7zip/Archive/Arj/resource.rc new file mode 100755 index 00000000..5158e405 --- /dev/null +++ b/CPP/7zip/Archive/Arj/resource.rc @@ -0,0 +1,5 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("Arj Plugin", "arj") + +101 ICON "arj.ico" diff --git a/CPP/7zip/Archive/BZip2/BZip2.dsp b/CPP/7zip/Archive/BZip2/BZip2.dsp new file mode 100755 index 00000000..1d14aedb --- /dev/null +++ b/CPP/7zip/Archive/BZip2/BZip2.dsp @@ -0,0 +1,281 @@ +# Microsoft Developer Studio Project File - Name="BZip2" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=BZip2 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "BZip2.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "BZip2.mak" CFG="BZip2 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "BZip2 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "BZip2 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "BZip2 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\bz2.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\bz2.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "BZip2 - Win32 Release" +# Name "BZip2 - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Archive.def +# End Source File +# Begin Source File + +SOURCE=.\BZip2.ico +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# End Group +# Begin Group "Compression" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\CodecsPath.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\CodecsPath.h +# End Source File +# Begin Source File + +SOURCE=..\Common\CoderLoader.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DummyOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\DummyOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ParseProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ParseProperties.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\BZip2Handler.cpp +# End Source File +# Begin Source File + +SOURCE=.\BZip2Handler.h +# End Source File +# Begin Source File + +SOURCE=.\BZip2HandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=.\BZip2Item.h +# End Source File +# Begin Source File + +SOURCE=.\BZip2Update.cpp +# End Source File +# Begin Source File + +SOURCE=.\BZip2Update.h +# End Source File +# End Group +# Begin Group "7zip common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\bz2.ico +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/Archive/BZip2/BZip2.dsw b/CPP/7zip/Archive/BZip2/BZip2.dsw new file mode 100755 index 00000000..697e5095 --- /dev/null +++ b/CPP/7zip/Archive/BZip2/BZip2.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "BZip2"=.\BZip2.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Archive/BZip2/BZip2Handler.cpp b/CPP/7zip/Archive/BZip2/BZip2Handler.cpp new file mode 100755 index 00000000..169b2597 --- /dev/null +++ b/CPP/7zip/Archive/BZip2/BZip2Handler.cpp @@ -0,0 +1,287 @@ +// BZip2Handler.cpp + +#include "StdAfx.h" + +#include "BZip2Handler.h" + +#include "Common/Defs.h" + +#include "../../Common/ProgressUtils.h" +#include "../../Common/StreamUtils.h" + +#include "Windows/PropVariant.h" +#include "Windows/Defs.h" +#include "Common/ComTry.h" + +#include "../Common/DummyOutStream.h" + +#ifdef COMPRESS_BZIP2 +#include "../../Compress/BZip2/BZip2Decoder.h" +#else +// {23170F69-40C1-278B-0402-020000000000} +DEFINE_GUID(CLSID_CCompressBZip2Decoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00); +#include "../Common/CoderLoader.h" +extern CSysString GetBZip2CodecPath(); +#endif + +using namespace NWindows; + +namespace NArchive { +namespace NBZip2 { + +STATPROPSTG kProperties[] = +{ + { NULL, kpidPath, VT_BSTR}, + // { NULL, kpidIsFolder, VT_BOOL}, + // { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackedSize, VT_UI8}, +}; + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) +{ + value->vt = VT_EMPTY; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if(index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &srcItem = kProperties[index]; + *propID = srcItem.propid; + *varType = srcItem.vt; + *name = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +{ + *numProperties = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, + BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) +{ + return E_INVALIDARG; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = 1; + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant propVariant; + if (index != 0) + return E_INVALIDARG; + switch(propID) + { + case kpidIsFolder: + propVariant = false; + break; + case kpidPackedSize: + propVariant = _item.PackSize; + break; + } + propVariant.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */) +{ + COM_TRY_BEGIN + try + { + RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition)); + const int kSignatureSize = 3; + Byte buffer[kSignatureSize]; + UInt32 processedSize; + RINOK(ReadStream(stream, buffer, kSignatureSize, &processedSize)); + if (processedSize != kSignatureSize) + return S_FALSE; + if (buffer[0] != 'B' || buffer[1] != 'Z' || buffer[2] != 'h') + return S_FALSE; + + UInt64 endPosition; + RINOK(stream->Seek(0, STREAM_SEEK_END, &endPosition)); + _item.PackSize = endPosition - _streamStartPosition; + + _stream = stream; + } + catch(...) + { + return S_FALSE; + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + _stream.Release(); + return S_OK; +} + + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 testModeSpec, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool allFilesMode = (numItems == UInt32(-1)); + if (!allFilesMode) + { + if (numItems == 0) + return S_OK; + if (numItems != 1) + return E_INVALIDARG; + if (indices[0] != 0) + return E_INVALIDARG; + } + + bool testMode = (testModeSpec != 0); + + extractCallback->SetTotal(_item.PackSize); + + UInt64 currentTotalPacked = 0, currentTotalUnPacked = 0; + + RINOK(extractCallback->SetCompleted(¤tTotalPacked)); + + CMyComPtr realOutStream; + Int32 askMode; + askMode = testMode ? NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); + + if(!testMode && !realOutStream) + return S_OK; + + + extractCallback->PrepareOperation(askMode); + + #ifndef COMPRESS_BZIP2 + CCoderLibrary lib; + #endif + CMyComPtr decoder; + #ifdef COMPRESS_BZIP2 + decoder = new NCompress::NBZip2::CDecoder; + #else + HRESULT loadResult = lib.LoadAndCreateCoder( + GetBZip2CodecPath(), + CLSID_CCompressBZip2Decoder, &decoder); + if (loadResult != S_OK) + { + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + return S_OK; + } + #endif + + #ifdef COMPRESS_MT + { + CMyComPtr setCoderMt; + decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt); + if (setCoderMt) + { + RINOK(setCoderMt->SetNumberOfThreads(_numThreads)); + } + } + #endif + + CDummyOutStream *outStreamSpec = new CDummyOutStream; + CMyComPtr outStream(outStreamSpec); + outStreamSpec->Init(realOutStream); + + realOutStream.Release(); + + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr progress = localProgressSpec; + localProgressSpec->Init(extractCallback, true); + + CLocalCompressProgressInfo *localCompressProgressSpec = + new CLocalCompressProgressInfo; + CMyComPtr compressProgress = localCompressProgressSpec; + + RINOK(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL)); + + + HRESULT result = S_OK; + + bool firstItem = true; + for (;;) + { + localCompressProgressSpec->Init(progress, + ¤tTotalPacked, + ¤tTotalUnPacked); + + const int kSignatureSize = 3; + Byte buffer[kSignatureSize]; + UInt32 processedSize; + RINOK(ReadStream(_stream, buffer, kSignatureSize, &processedSize)); + if (processedSize < kSignatureSize) + { + if (firstItem) + return E_FAIL; + break; + } + if (buffer[0] != 'B' || buffer[1] != 'Z' || buffer[2] != 'h') + { + if (firstItem) + return E_FAIL; + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)) + return S_OK; + } + firstItem = false; + + UInt64 dataStartPos; + RINOK(_stream->Seek((UInt64)(Int64)(-3), STREAM_SEEK_CUR, &dataStartPos)); + + result = decoder->Code(_stream, outStream, NULL, NULL, compressProgress); + + if (result != S_OK) + break; + + CMyComPtr getInStreamProcessedSize; + decoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, + &getInStreamProcessedSize); + if (!getInStreamProcessedSize) + break; + + UInt64 packSize; + RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&packSize)); + UInt64 pos; + RINOK(_stream->Seek(dataStartPos + packSize, STREAM_SEEK_SET, &pos)); + currentTotalPacked = pos - _streamStartPosition; + } + outStream.Release(); + + int retResult; + if (result == S_OK) + retResult = NArchive::NExtract::NOperationResult::kOK; + else if (result == S_FALSE) + retResult = NArchive::NExtract::NOperationResult::kDataError; + else + return result; + + RINOK(extractCallback->SetOperationResult(retResult)); + + return S_OK; + COM_TRY_END +} + +}} diff --git a/CPP/7zip/Archive/BZip2/BZip2Handler.h b/CPP/7zip/Archive/BZip2/BZip2Handler.h new file mode 100755 index 00000000..7977334e --- /dev/null +++ b/CPP/7zip/Archive/BZip2/BZip2Handler.h @@ -0,0 +1,83 @@ +// BZip2/Handler.h + +#ifndef __BZIP2_HANDLER_H +#define __BZIP2_HANDLER_H + +#include "Common/MyCom.h" +#include "../IArchive.h" +#include "BZip2Item.h" + +#ifdef COMPRESS_MT +#include "../../../Windows/System.h" +#endif + +namespace NArchive { +namespace NBZip2 { + +class CHandler: + public IInArchive, + public IOutArchive, + public ISetProperties, + public CMyUnknownImp +{ + CMyComPtr _stream; + NArchive::NBZip2::CItem _item; + UInt64 _streamStartPosition; + + UInt32 _level; + UInt32 _dicSize; + UInt32 _numPasses; + #ifdef COMPRESS_MT + UInt32 _numThreads; + #endif + void InitMethodProperties() + { + _level = 5; + _dicSize = + _numPasses = 0xFFFFFFFF; + #ifdef COMPRESS_MT + _numThreads = NWindows::NSystem::GetNumberOfProcessors();; + #endif + } + +public: + MY_UNKNOWN_IMP3( + IInArchive, + IOutArchive, + ISetProperties + ) + + STDMETHOD(Open)(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback); + STDMETHOD(Close)(); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); + + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + // IOutArchiveHandler + + STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback); + STDMETHOD(GetFileTimeType)(UInt32 *type); + + // ISetProperties + STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties); + + CHandler() { InitMethodProperties(); } +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/BZip2/BZip2HandlerOut.cpp b/CPP/7zip/Archive/BZip2/BZip2HandlerOut.cpp new file mode 100755 index 00000000..b5fc72a9 --- /dev/null +++ b/CPP/7zip/Archive/BZip2/BZip2HandlerOut.cpp @@ -0,0 +1,156 @@ +// BZip2HandlerOut.cpp + +#include "StdAfx.h" + +#include "BZip2Handler.h" +#include "BZip2Update.h" + +#include "Common/Defs.h" +#include "Common/String.h" + +#include "Windows/PropVariant.h" + +#include "../../Compress/Copy/CopyCoder.h" + +#include "../Common/ParseProperties.h" + +using namespace NWindows; + +static const UInt32 kNumPassesX1 = 1; +static const UInt32 kNumPassesX7 = 2; +static const UInt32 kNumPassesX9 = 7; + +static const UInt32 kDicSizeX1 = 100000; +static const UInt32 kDicSizeX3 = 500000; +static const UInt32 kDicSizeX5 = 900000; + +namespace NArchive { +namespace NBZip2 { + +STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) +{ + *type = NFileTimeType::kUnix; + return S_OK; +} + +static HRESULT CopyStreams(ISequentialInStream *inStream, ISequentialOutStream *outStream) +{ + CMyComPtr copyCoder = new NCompress::CCopyCoder; + return copyCoder->Code(inStream, outStream, NULL, NULL, NULL); +} + +STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback) +{ + if (numItems != 1) + return E_INVALIDARG; + + Int32 newData; + Int32 newProperties; + UInt32 indexInArchive; + if (!updateCallback) + return E_FAIL; + RINOK(updateCallback->GetUpdateItemInfo(0, + &newData, &newProperties, &indexInArchive)); + + if (IntToBool(newProperties)) + { + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(0, kpidIsFolder, &propVariant)); + if (propVariant.vt == VT_BOOL) + { + if (propVariant.boolVal != VARIANT_FALSE) + return E_INVALIDARG; + } + else if (propVariant.vt != VT_EMPTY) + return E_INVALIDARG; + } + } + + if (IntToBool(newData)) + { + UInt64 size; + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(0, kpidSize, &propVariant)); + if (propVariant.vt != VT_UI8) + return E_INVALIDARG; + size = propVariant.uhVal.QuadPart; + } + + UInt32 dicSize = _dicSize; + if (dicSize == 0xFFFFFFFF) + dicSize = (_level >= 5 ? kDicSizeX5 : + (_level >= 3 ? kDicSizeX3 : + kDicSizeX1)); + + UInt32 numPasses = _numPasses; + if (numPasses == 0xFFFFFFFF) + numPasses = (_level >= 9 ? kNumPassesX9 : + (_level >= 7 ? kNumPassesX7 : + kNumPassesX1)); + + return UpdateArchive(size, outStream, 0, dicSize, numPasses, + #ifdef COMPRESS_MT + _numThreads, + #endif + updateCallback); + } + if (indexInArchive != 0) + return E_INVALIDARG; + RINOK(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL)); + return CopyStreams(_stream, outStream); +} + +STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) +{ + InitMethodProperties(); + #ifdef COMPRESS_MT + const UInt32 numProcessors = NSystem::GetNumberOfProcessors(); + _numThreads = numProcessors; + #endif + + for (int i = 0; i < numProperties; i++) + { + UString name = UString(names[i]); + name.MakeUpper(); + if (name.IsEmpty()) + return E_INVALIDARG; + + const PROPVARIANT &prop = values[i]; + + if (name[0] == 'X') + { + UInt32 level = 9; + RINOK(ParsePropValue(name.Mid(1), prop, level)); + _level = level; + continue; + } + if (name[0] == 'D') + { + UInt32 dicSize = kDicSizeX5; + RINOK(ParsePropDictionaryValue(name.Mid(1), prop, dicSize)); + _dicSize = dicSize; + continue; + } + if (name.Left(4) == L"PASS") + { + UInt32 num = kNumPassesX9; + RINOK(ParsePropValue(name.Mid(4), prop, num)); + _numPasses = num; + continue; + } + if (name.Left(2) == L"MT") + { + #ifdef COMPRESS_MT + RINOK(ParseMtProp(name.Mid(2), prop, numProcessors, _numThreads)); + #endif + continue; + } + return E_INVALIDARG; + } + return S_OK; +} + +}} diff --git a/CPP/7zip/Archive/BZip2/BZip2Item.h b/CPP/7zip/Archive/BZip2/BZip2Item.h new file mode 100755 index 00000000..d7508ab9 --- /dev/null +++ b/CPP/7zip/Archive/BZip2/BZip2Item.h @@ -0,0 +1,20 @@ +// Archive/BZip2Item.h + +#ifndef __ARCHIVE_BZIP2_ITEM_H +#define __ARCHIVE_BZIP2_ITEM_H + +namespace NArchive { +namespace NBZip2 { + +struct CItem +{ + UInt64 PackSize; + UInt64 UnPackSize; +}; + +}} + +#endif + + + diff --git a/CPP/7zip/Archive/BZip2/BZip2Update.cpp b/CPP/7zip/Archive/BZip2/BZip2Update.cpp new file mode 100755 index 00000000..d9bdf963 --- /dev/null +++ b/CPP/7zip/Archive/BZip2/BZip2Update.cpp @@ -0,0 +1,84 @@ +// BZip2Update.cpp + +#include "StdAfx.h" + +#include "../../Common/ProgressUtils.h" +#include "Windows/PropVariant.h" + +#include "BZip2Update.h" + +#ifdef COMPRESS_BZIP2 +#include "../../Compress/BZip2/BZip2Encoder.h" +#else +// {23170F69-40C1-278B-0402-020000000100} +DEFINE_GUID(CLSID_CCompressBZip2Encoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00); +#include "../Common/CoderLoader.h" +extern CSysString GetBZip2CodecPath(); +#endif + +namespace NArchive { +namespace NBZip2 { + +HRESULT UpdateArchive(UInt64 unpackSize, + ISequentialOutStream *outStream, + int indexInClient, + UInt32 dictionary, + UInt32 numPasses, + #ifdef COMPRESS_MT + UInt32 numThreads, + #endif + IArchiveUpdateCallback *updateCallback) +{ + RINOK(updateCallback->SetTotal(unpackSize)); + UInt64 complexity = 0; + RINOK(updateCallback->SetCompleted(&complexity)); + + CMyComPtr fileInStream; + + RINOK(updateCallback->GetStream(indexInClient, &fileInStream)); + + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr localProgress = localProgressSpec; + localProgressSpec->Init(updateCallback, true); + + #ifndef COMPRESS_BZIP2 + CCoderLibrary lib; + #endif + CMyComPtr encoder; + #ifdef COMPRESS_BZIP2 + encoder = new NCompress::NBZip2::CEncoder; + #else + RINOK(lib.LoadAndCreateCoder(GetBZip2CodecPath(), + CLSID_CCompressBZip2Encoder, &encoder)); + #endif + + CMyComPtr setCoderProperties; + encoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties); + if (setCoderProperties) + { + NWindows::NCOM::CPropVariant properties[] = + { + dictionary, + numPasses + #ifdef COMPRESS_MT + , numThreads + #endif + }; + PROPID propIDs[] = + { + NCoderPropID::kDictionarySize, + NCoderPropID::kNumPasses + #ifdef COMPRESS_MT + , NCoderPropID::kNumThreads + #endif + }; + RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, sizeof(propIDs) / sizeof(propIDs[0]))); + } + + RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, localProgress)); + + return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK); +} + +}} diff --git a/CPP/7zip/Archive/BZip2/BZip2Update.h b/CPP/7zip/Archive/BZip2/BZip2Update.h new file mode 100755 index 00000000..ce20e323 --- /dev/null +++ b/CPP/7zip/Archive/BZip2/BZip2Update.h @@ -0,0 +1,24 @@ +// BZip2Update.h + +#ifndef __BZIP2_UPDATE_H +#define __BZIP2_UPDATE_H + +#include "../IArchive.h" + +namespace NArchive { +namespace NBZip2 { + +HRESULT UpdateArchive( + UInt64 unpackSize, + ISequentialOutStream *outStream, + int indexInClient, + UInt32 dictionary, + UInt32 numPasses, + #ifdef COMPRESS_MT + UInt32 numThreads, + #endif + IArchiveUpdateCallback *updateCallback); + +}} + +#endif diff --git a/CPP/7zip/Archive/BZip2/DllExports.cpp b/CPP/7zip/Archive/BZip2/DllExports.cpp new file mode 100755 index 00000000..5a861318 --- /dev/null +++ b/CPP/7zip/Archive/BZip2/DllExports.cpp @@ -0,0 +1,127 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "Windows/PropVariant.h" +#include "BZip2Handler.h" +#include "../../ICoder.h" + +// {23170F69-40C1-278B-0402-020000000100} +DEFINE_GUID(CLSID_CCompressBZip2Encoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00); + +// {23170F69-40C1-278B-0402-020000000000} +DEFINE_GUID(CLSID_CCompressBZip2Decoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00); + +// {23170F69-40C1-278A-1000-000110020000} +DEFINE_GUID(CLSID_CBZip2Handler, +0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x02, 0x00, 0x00); + +HINSTANCE g_hInstance; +#ifndef _UNICODE +bool g_IsNT = false; +static bool IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); +} +#endif + +#ifndef COMPRESS_BZIP2 +#include "../Common/CodecsPath.h" +CSysString GetBZip2CodecPath() +{ + return GetCodecsFolderPrefix() + TEXT("BZip2.dll"); +} +#endif + +extern "C" +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + g_hInstance = hInstance; + #ifndef _UNICODE + g_IsNT = IsItWindowsNT(); + #endif + } + return TRUE; +} + +STDAPI CreateObject( + const GUID *classID, + const GUID *interfaceID, + void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + if (*classID != CLSID_CBZip2Handler) + return CLASS_E_CLASSNOTAVAILABLE; + int needIn = *interfaceID == IID_IInArchive; + int needOut = *interfaceID == IID_IOutArchive; + if (needIn || needOut) + { + NArchive::NBZip2::CHandler *temp = new NArchive::NBZip2::CHandler; + if (needIn) + { + CMyComPtr inArchive = (IInArchive *)temp; + *outObject = inArchive.Detach(); + } + else + { + CMyComPtr outArchive = (IOutArchive *)temp; + *outObject = outArchive.Detach(); + } + } + else + return E_NOINTERFACE; + COM_TRY_END + return S_OK; +} + + +STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case NArchive::kName: + propVariant = L"BZip2"; + break; + case NArchive::kClassID: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CBZip2Handler, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NArchive::kExtension: + propVariant = L"bz2 bzip2 tbz2 tbz"; + break; + case NArchive::kAddExtension: + propVariant = L"* * .tar .tar"; + break; + case NArchive::kUpdate: + propVariant = true; + break; + case NArchive::kKeepName: + propVariant = true; + break; + case NArchive::kStartSignature: + { + const char sig[] = { 'B', 'Z', 'h' }; + if ((value->bstrVal = ::SysAllocStringByteLen(sig, 3)) != 0) + value->vt = VT_BSTR; + return S_OK; + } + + } + propVariant.Detach(value); + return S_OK; +} diff --git a/CPP/7zip/Archive/BZip2/StdAfx.cpp b/CPP/7zip/Archive/BZip2/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Archive/BZip2/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Archive/BZip2/StdAfx.h b/CPP/7zip/Archive/BZip2/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Archive/BZip2/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Archive/BZip2/bz2.ico b/CPP/7zip/Archive/BZip2/bz2.ico new file mode 100755 index 00000000..614e3540 Binary files /dev/null and b/CPP/7zip/Archive/BZip2/bz2.ico differ diff --git a/CPP/7zip/Archive/BZip2/makefile b/CPP/7zip/Archive/BZip2/makefile new file mode 100755 index 00000000..20f20bdb --- /dev/null +++ b/CPP/7zip/Archive/BZip2/makefile @@ -0,0 +1,55 @@ +PROG = bz2.dll +DEF_FILE = ../Archive.def +CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_MT +LIBS = $(LIBS) oleaut32.lib user32.lib + +BZ2_OBJS = \ + $O\BZip2Handler.obj \ + $O\BZip2HandlerOut.obj \ + $O\BZip2Update.obj \ + $O\DllExports.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\PropVariant.obj \ + +7ZIP_COMMON_OBJS = \ + $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ + +AR_COMMON_OBJS = \ + $O\CodecsPath.obj \ + $O\DummyOutStream.obj \ + $O\ParseProperties.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(BZ2_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $O\CopyCoder.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(BZ2_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/Archive/BZip2/resource.rc b/CPP/7zip/Archive/BZip2/resource.rc new file mode 100755 index 00000000..2d4f27e3 --- /dev/null +++ b/CPP/7zip/Archive/BZip2/resource.rc @@ -0,0 +1,5 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("BZip2 Plugin", "bz2") + +101 ICON "bz2.ico" diff --git a/CPP/7zip/Archive/Cab/Cab.dsp b/CPP/7zip/Archive/Cab/Cab.dsp new file mode 100755 index 00000000..565661f6 --- /dev/null +++ b/CPP/7zip/Archive/Cab/Cab.dsp @@ -0,0 +1,395 @@ +# Microsoft Developer Studio Project File - Name="Cab" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Cab - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Cab.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Cab.mak" CFG="Cab - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Cab - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Cab - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Cab - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /FAs /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\cab.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Cab - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /FAcs /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\cab.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Cab - Win32 Release" +# Name "Cab - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Archive.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\CabBlockInStream.cpp +# End Source File +# Begin Source File + +SOURCE=.\CabBlockInStream.h +# End Source File +# Begin Source File + +SOURCE=.\CabHandler.cpp +# End Source File +# Begin Source File + +SOURCE=.\CabHandler.h +# End Source File +# Begin Source File + +SOURCE=.\CabHeader.cpp +# End Source File +# Begin Source File + +SOURCE=.\CabHeader.h +# End Source File +# Begin Source File + +SOURCE=.\CabIn.cpp +# End Source File +# Begin Source File + +SOURCE=.\CabIn.h +# End Source File +# Begin Source File + +SOURCE=.\CabItem.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LSBFDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LSBFDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MSBFDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Group "LZ" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.h +# End Source File +# End Group +# Begin Group "Lzx" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Lzx\Lzx.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzx\Lzx86Converter.cpp + +!IF "$(CFG)" == "Cab - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Cab - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzx\Lzx86Converter.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzx\LzxDecoder.cpp + +!IF "$(CFG)" == "Cab - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Cab - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzx\LzxDecoder.h +# End Source File +# End Group +# Begin Group "Deflate" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Deflate\DeflateConst.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Deflate\DeflateDecoder.cpp + +!IF "$(CFG)" == "Cab - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Cab - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Deflate\DeflateDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Deflate\DeflateExtConst.h +# End Source File +# End Group +# Begin Group "Copy" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "Quantum" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Quantum\QuantumDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Quantum\QuantumDecoder.h +# End Source File +# End Group +# Begin Group "Huffman" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Huffman\HuffmanDecoder.h +# End Source File +# End Group +# End Group +# Begin Source File + +SOURCE=.\cab.ico +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/Archive/Cab/Cab.dsw b/CPP/7zip/Archive/Cab/Cab.dsw new file mode 100755 index 00000000..470cb1b3 --- /dev/null +++ b/CPP/7zip/Archive/Cab/Cab.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Cab"=.\Cab.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Archive/Cab/CabBlockInStream.cpp b/CPP/7zip/Archive/Cab/CabBlockInStream.cpp new file mode 100755 index 00000000..b775c105 --- /dev/null +++ b/CPP/7zip/Archive/Cab/CabBlockInStream.cpp @@ -0,0 +1,194 @@ +// CabBlockInStream.cpp + +#include "StdAfx.h" + +#include "Common/Alloc.h" +#include "Common/Defs.h" + +#include "../../Common/StreamUtils.h" + +#include "CabBlockInStream.h" + +namespace NArchive { +namespace NCab { + +static const UInt32 kBlockSize = (1 << 16); + +bool CCabBlockInStream::Create() +{ + if (!_buffer) + _buffer = (Byte *)::MyAlloc(kBlockSize); + return (_buffer != 0); +} + +CCabBlockInStream::~CCabBlockInStream() +{ + MyFree(_buffer); +} + +class CCheckSum2 +{ + UInt32 m_Value; + int m_Pos; + Byte m_Hist[4]; +public: + CCheckSum2(): m_Value(0){}; + void Init() { m_Value = 0; m_Pos = 0; } + void Update(const void *data, UInt32 size); + void FinishDataUpdate() + { + for (int i = 0; i < m_Pos; i++) + m_Value ^= ((UInt32)(m_Hist[i])) << (8 * (m_Pos - i - 1)); + } + void UpdateUInt32(UInt32 v) { m_Value ^= v; } + UInt32 GetResult() const { return m_Value; } +}; + +void CCheckSum2::Update(const void *data, UInt32 size) +{ + UInt32 checkSum = m_Value; + const Byte *dataPointer = (const Byte *)data; + + while (size != 0 && m_Pos != 0) + { + m_Hist[m_Pos] = *dataPointer++; + m_Pos = (m_Pos + 1) & 3; + size--; + if (m_Pos == 0) + for (int i = 0; i < 4; i++) + checkSum ^= ((UInt32)m_Hist[i]) << (8 * i); + } + + int numWords = size / 4; + + while (numWords-- != 0) + { + UInt32 temp = *dataPointer++; + temp |= ((UInt32)(*dataPointer++)) << 8; + temp |= ((UInt32)(*dataPointer++)) << 16; + temp |= ((UInt32)(*dataPointer++)) << 24; + checkSum ^= temp; + } + m_Value = checkSum; + + size &= 3; + + while (size != 0) + { + m_Hist[m_Pos] = *dataPointer++; + m_Pos = (m_Pos + 1) & 3; + size--; + } +} + +static const UInt32 kDataBlockHeaderSize = 8; + +class CTempCabInBuffer2 +{ +public: + Byte Buffer[kDataBlockHeaderSize]; + UInt32 Pos; + Byte ReadByte() + { + return Buffer[Pos++]; + } + UInt32 ReadUInt32() + { + UInt32 value = 0; + for (int i = 0; i < 4; i++) + value |= (((UInt32)ReadByte()) << (8 * i)); + return value; + } + UInt16 ReadUInt16() + { + UInt16 value = 0; + for (int i = 0; i < 2; i++) + value |= (((UInt16)ReadByte()) << (8 * i)); + return value; + } +}; + +HRESULT CCabBlockInStream::PreRead(UInt32 &packSize, UInt32 &unpackSize) +{ + CTempCabInBuffer2 inBuffer; + inBuffer.Pos = 0; + UInt32 processedSizeLoc; + RINOK(ReadStream(_stream, inBuffer.Buffer, kDataBlockHeaderSize, &processedSizeLoc)) + if (processedSizeLoc != kDataBlockHeaderSize) + return S_FALSE; // bad block + + UInt32 checkSum = inBuffer.ReadUInt32(); + packSize = inBuffer.ReadUInt16(); + unpackSize = inBuffer.ReadUInt16(); + if (ReservedSize != 0) + { + RINOK(ReadStream(_stream, _buffer, ReservedSize, &processedSizeLoc)); + if(ReservedSize != processedSizeLoc) + return S_FALSE; // bad block; + } + _pos = 0; + CCheckSum2 checkSumCalc; + checkSumCalc.Init(); + UInt32 packSize2 = packSize; + if (MsZip && _size == 0) + { + if (packSize < 2) + return S_FALSE; // bad block; + Byte sig[2]; + RINOK(ReadStream(_stream, sig, 2, &processedSizeLoc)); + if(processedSizeLoc != 2) + return S_FALSE; + if (sig[0] != 0x43 || sig[1] != 0x4B) + return S_FALSE; + packSize2 -= 2; + checkSumCalc.Update(sig, 2); + } + + if (kBlockSize - _size < packSize2) + return S_FALSE; + + UInt32 curSize = packSize2; + if (curSize != 0) + { + RINOK(ReadStream(_stream, _buffer + _size, curSize, &processedSizeLoc)); + checkSumCalc.Update(_buffer + _size, processedSizeLoc); + _size += processedSizeLoc; + if (processedSizeLoc != curSize) + return S_FALSE; + } + TotalPackSize = _size; + + checkSumCalc.FinishDataUpdate(); + + bool dataError; + if (checkSum == 0) + dataError = false; + else + { + checkSumCalc.UpdateUInt32(packSize | (((UInt32)unpackSize) << 16)); + dataError = (checkSumCalc.GetResult() != checkSum); + } + DataError |= dataError; + return dataError ? S_FALSE : S_OK; +} + +STDMETHODIMP CCabBlockInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize != 0) + *processedSize = 0; + if (size == 0) + return S_OK; + if (_size != 0) + { + size = MyMin(_size, size); + memmove(data, _buffer + _pos, size); + _pos += size; + _size -= size; + if (processedSize != 0) + *processedSize = size; + return S_OK; + } + return S_OK; // no blocks data +} + +}} diff --git a/CPP/7zip/Archive/Cab/CabBlockInStream.h b/CPP/7zip/Archive/Cab/CabBlockInStream.h new file mode 100755 index 00000000..46e15222 --- /dev/null +++ b/CPP/7zip/Archive/Cab/CabBlockInStream.h @@ -0,0 +1,56 @@ +// CabBlockInStream.cpp + +#ifndef __CABBLOCKINSTREAM_H +#define __CABBLOCKINSTREAM_H + +#include "Common/MyCom.h" +#include "../../IStream.h" + +namespace NArchive { +namespace NCab { + +class CCabBlockInStream: + public ISequentialInStream, + public CMyUnknownImp +{ + CMyComPtr _stream; + Byte *_buffer; + UInt32 _pos; + UInt32 _size; + int _align; + +public: + UInt32 TotalPackSize; + UInt32 ReservedSize; + bool DataError; + bool MsZip; + + CCabBlockInStream(): _buffer(0), ReservedSize(0), MsZip(false), DataError(false), _align(0), TotalPackSize(0) {} + ~CCabBlockInStream(); + bool Create(); + void SetStream(ISequentialInStream *stream) { _stream = stream; } + + void InitForNewFolder() + { + _align = 0; + TotalPackSize = 0; + } + + void InitForNewBlock() + { + _size = 0; + _align = (_align + (int)TotalPackSize) & 1; + } + + int GetAlign() const { return _align; } + + MY_UNKNOWN_IMP + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + + HRESULT PreRead(UInt32 &packSize, UInt32 &unpackSize); +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Cab/CabHandler.cpp b/CPP/7zip/Archive/Cab/CabHandler.cpp new file mode 100755 index 00000000..cac79b11 --- /dev/null +++ b/CPP/7zip/Archive/Cab/CabHandler.cpp @@ -0,0 +1,812 @@ +// CabHandler.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Common/Defs.h" +#include "Common/Alloc.h" +#include "Common/UTFConvert.h" +#include "Common/ComTry.h" +#include "Common/IntToString.h" + +#include "Windows/PropVariant.h" +#include "Windows/Time.h" + +#include "CabHandler.h" +#include "CabBlockInStream.h" + +#include "../../Compress/Copy/CopyCoder.h" +#include "../../Compress/Deflate/DeflateDecoder.h" +#include "../../Compress/Lzx/LzxDecoder.h" +#include "../../Compress/Quantum/QuantumDecoder.h" + +#include "../Common/ItemNameUtils.h" + +using namespace NWindows; + +namespace NArchive { +namespace NCab { + +// #define _CAB_DETAILS + +#ifdef _CAB_DETAILS +enum +{ + kpidBlockReal = kpidUserDefined, + kpidOffset, + kpidVolume, +}; +#endif + +STATPROPSTG kProperties[] = +{ + { NULL, kpidPath, VT_BSTR}, + // { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidLastWriteTime, VT_FILETIME}, + { NULL, kpidAttributes, VT_UI4}, + { NULL, kpidMethod, VT_BSTR}, + { NULL, kpidBlock, VT_I4} + #ifdef _CAB_DETAILS + , + { L"BlockReal", kpidBlockReal, VT_UI4}, + { L"Offset", kpidOffset, VT_UI4}, + { L"Volume", kpidVolume, VT_UI4} + #endif +}; + +static const int kNumProperties = sizeof(kProperties) / sizeof(kProperties[0]); + +static const wchar_t *kMethods[] = +{ + L"None", + L"MSZip", + L"Quantum", + L"LZX" +}; + +static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]); +static const wchar_t *kUnknownMethod = L"Unknown"; + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) +{ + value->vt = VT_EMPTY; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if(index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &srcItem = kProperties[index]; + *propID = srcItem.propid; + *varType = srcItem.vt; + if (srcItem.lpwstrName == 0) + *name = 0; + else + *name = ::SysAllocString(srcItem.lpwstrName); + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +{ + *numProperties = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, + BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) +{ + return E_INVALIDARG; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant propVariant; + + const CMvItem &mvItem = m_Database.Items[index]; + const CDatabaseEx &db = m_Database.Volumes[mvItem.VolumeIndex]; + int itemIndex = mvItem.ItemIndex; + const CItem &item = db.Items[itemIndex]; + switch(propID) + { + case kpidPath: + { + UString unicodeName; + if (item.IsNameUTF()) + ConvertUTF8ToUnicode(item.Name, unicodeName); + else + unicodeName = MultiByteToUnicodeString(item.Name, CP_ACP); + propVariant = (const wchar_t *)NItemName::WinNameToOSName(unicodeName); + break; + } + case kpidIsFolder: + propVariant = item.IsDirectory(); + break; + case kpidSize: + propVariant = item.Size; + break; + case kpidLastWriteTime: + { + FILETIME localFileTime, utcFileTime; + if (NTime::DosTimeToFileTime(item.Time, localFileTime)) + { + if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime)) + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; + } + else + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; + propVariant = utcFileTime; + break; + } + case kpidAttributes: + propVariant = item.GetWinAttributes(); + break; + + case kpidMethod: + { + UInt32 realFolderIndex = item.GetFolderIndex(db.Folders.Size()); + const CFolder &folder = db.Folders[realFolderIndex]; + int methodIndex = folder.GetCompressionMethod(); + UString method = (methodIndex < kNumMethods) ? kMethods[methodIndex] : kUnknownMethod; + if (methodIndex == NHeader::NCompressionMethodMajor::kLZX || + methodIndex == NHeader::NCompressionMethodMajor::kQuantum) + { + method += L":"; + wchar_t temp[32]; + ConvertUInt64ToString(folder.CompressionTypeMinor, temp); + method += temp; + } + propVariant = method; + break; + } + case kpidBlock: + propVariant = (Int32)m_Database.GetFolderIndex(&mvItem); + break; + + #ifdef _CAB_DETAILS + + case kpidBlockReal: + propVariant = UInt32(item.FolderIndex); + break; + case kpidOffset: + propVariant = (UInt32)item.Offset; + break; + case kpidVolume: + propVariant = (UInt32)mvItem.VolumeIndex; + break; + + #endif + } + propVariant.Detach(value); + return S_OK; + COM_TRY_END +} + +/* +class CPropgressImp: public CProgressVirt +{ + CMyComPtr m_OpenArchiveCallback; +public: + STDMETHOD(SetTotal)(const UInt64 *numFiles); + STDMETHOD(SetCompleted)(const UInt64 *numFiles); + void Init(IArchiveOpenCallback *openArchiveCallback) + { m_OpenArchiveCallback = openArchiveCallback; } +}; + +STDMETHODIMP CPropgressImp::SetTotal(const UInt64 *numFiles) +{ + if (m_OpenArchiveCallback) + return m_OpenArchiveCallback->SetCompleted(numFiles, NULL); + return S_OK; +} + +STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles) +{ + if (m_OpenArchiveCallback) + return m_OpenArchiveCallback->SetCompleted(numFiles, NULL); + return S_OK; +} +*/ + +STDMETHODIMP CHandler::Open(IInStream *inStream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback) +{ + COM_TRY_BEGIN + Close(); + HRESULT res = S_FALSE; + CInArchive archive; + CMyComPtr openVolumeCallback; + { + CMyComPtr openArchiveCallbackWrap = openArchiveCallback; + openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback); + } + + CMyComPtr nextStream = inStream; + bool prevChecked = false; + UInt64 numItems = 0; + try + { + while(nextStream != 0) + { + CDatabaseEx db; + db.Stream = nextStream; + res = archive.Open(maxCheckStartPosition, db); + if (res == S_OK) + { + if (!m_Database.Volumes.IsEmpty()) + { + const CDatabaseEx &dbPrev = m_Database.Volumes[prevChecked ? m_Database.Volumes.Size() - 1 : 0]; + if (dbPrev.ArchiveInfo.SetID != db.ArchiveInfo.SetID || + dbPrev.ArchiveInfo.CabinetNumber + (prevChecked ? 1: - 1) != + db.ArchiveInfo.CabinetNumber) + res = S_FALSE; + } + } + if (res == S_OK) + m_Database.Volumes.Insert(prevChecked ? m_Database.Volumes.Size() : 0, db); + else if (res != S_FALSE) + return res; + else + { + if (m_Database.Volumes.IsEmpty()) + return S_FALSE; + if (prevChecked) + break; + prevChecked = true; + } + + numItems += db.Items.Size(); + RINOK(openArchiveCallback->SetCompleted(&numItems, NULL)); + + nextStream = 0; + for (;;) + { + const COtherArchive *otherArchive = 0; + if (!prevChecked) + { + const CInArchiveInfo &ai = m_Database.Volumes.Front().ArchiveInfo; + if (ai.IsTherePrev()) + otherArchive = &ai.PreviousArchive; + else + prevChecked = true; + } + if (otherArchive == 0) + { + const CInArchiveInfo &ai = m_Database.Volumes.Back().ArchiveInfo; + if (ai.IsThereNext()) + otherArchive = &ai.NextArchive; + } + if (!otherArchive) + break; + const UString fullName = MultiByteToUnicodeString(otherArchive->FileName, CP_ACP); + HRESULT result = openVolumeCallback->GetStream(fullName, &nextStream); + if (result == S_OK) + break; + if (result != S_FALSE) + return result; + if (prevChecked) + break; + prevChecked = true; + } + } + if (res == S_OK) + { + m_Database.FillSortAndShrink(); + if (!m_Database.Check()) + res = S_FALSE; + } + } + catch(...) + { + res = S_FALSE; + } + if (res != S_OK) + { + Close(); + return res; + } + COM_TRY_END + return S_OK; +} + +STDMETHODIMP CHandler::Close() +{ + m_Database.Clear(); + return S_OK; +} + +class CCabFolderOutStream: + public ISequentialOutStream, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +private: + const CMvDatabaseEx *m_Database; + const CRecordVector *m_ExtractStatuses; + int m_StartIndex; + int m_CurrentIndex; + CMyComPtr m_ExtractCallback; + bool m_TestMode; + + CMyComPtr m_RealOutStream; + + bool m_IsOk; + bool m_FileIsOpen; + UInt64 m_RemainFileSize; + UInt64 m_FolderSize; + UInt64 m_PosInFolder; + + HRESULT OpenFile(); + HRESULT Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK); +public: + HRESULT WriteEmptyFiles(); + + void Init( + const CMvDatabaseEx *database, + const CRecordVector *extractStatuses, + int startIndex, + UInt64 folderSize, + IArchiveExtractCallback *extractCallback, + bool testMode); + HRESULT FlushCorrupted(); + HRESULT Unsupported(); + + UInt64 GetRemain() const { return m_FolderSize - m_PosInFolder; } + UInt64 GetPosInFolder() const { return m_PosInFolder; } +}; + +void CCabFolderOutStream::Init( + const CMvDatabaseEx *database, + const CRecordVector *extractStatuses, + int startIndex, + UInt64 folderSize, + IArchiveExtractCallback *extractCallback, + bool testMode) +{ + m_Database = database; + m_ExtractStatuses = extractStatuses; + m_StartIndex = startIndex; + m_FolderSize = folderSize; + + m_ExtractCallback = extractCallback; + m_TestMode = testMode; + + m_CurrentIndex = 0; + m_PosInFolder = 0; + m_FileIsOpen = false; + m_IsOk = true; +} + +HRESULT CCabFolderOutStream::OpenFile() +{ + Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract) : + NExtract::NAskMode::kSkip; + RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &m_RealOutStream, askMode)); + if (!m_RealOutStream && !m_TestMode) + askMode = NArchive::NExtract::NAskMode::kSkip; + return m_ExtractCallback->PrepareOperation(askMode); +} + +HRESULT CCabFolderOutStream::WriteEmptyFiles() +{ + if (m_FileIsOpen) + return S_OK; + for(;m_CurrentIndex < m_ExtractStatuses->Size(); m_CurrentIndex++) + { + const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex]; + const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; + UInt64 fileSize = item.Size; + if (fileSize != 0) + return S_OK; + HRESULT result = OpenFile(); + m_RealOutStream.Release(); + RINOK(result); + RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + } + return S_OK; +} + +// This is Write function +HRESULT CCabFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK) +{ + UInt32 realProcessed = 0; + if (processedSize != NULL) + *processedSize = 0; + while(size != 0) + { + if (m_FileIsOpen) + { + UInt32 numBytesToWrite = (UInt32)MyMin(m_RemainFileSize, (UInt64)(size)); + HRESULT res = S_OK; + if (numBytesToWrite > 0) + { + if (!isOK) + m_IsOk = false; + if (m_RealOutStream) + { + UInt32 processedSizeLocal = 0; + res = m_RealOutStream->Write((const Byte *)data, numBytesToWrite, &processedSizeLocal); + numBytesToWrite = processedSizeLocal; + } + } + realProcessed += numBytesToWrite; + if (processedSize != NULL) + *processedSize = realProcessed; + data = (const void *)((const Byte *)data + numBytesToWrite); + size -= numBytesToWrite; + m_RemainFileSize -= numBytesToWrite; + m_PosInFolder += numBytesToWrite; + if (res != S_OK) + return res; + if (m_RemainFileSize == 0) + { + m_RealOutStream.Release(); + RINOK(m_ExtractCallback->SetOperationResult( + m_IsOk ? + NArchive::NExtract::NOperationResult::kOK: + NArchive::NExtract::NOperationResult::kDataError)); + m_FileIsOpen = false; + } + if (realProcessed > 0) + break; // with this break this function works as Write-Part + } + else + { + if (m_CurrentIndex >= m_ExtractStatuses->Size()) + return E_FAIL; + + const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex]; + const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; + + m_RemainFileSize = item.Size; + + UInt32 fileOffset = item.Offset; + if (fileOffset < m_PosInFolder) + return E_FAIL; + if (fileOffset > m_PosInFolder) + { + UInt32 numBytesToWrite = (UInt32)MyMin((UInt64)fileOffset - m_PosInFolder, UInt64(size)); + realProcessed += numBytesToWrite; + if (processedSize != NULL) + *processedSize = realProcessed; + data = (const void *)((const Byte *)data + numBytesToWrite); + size -= numBytesToWrite; + m_PosInFolder += numBytesToWrite; + } + if (fileOffset == m_PosInFolder) + { + RINOK(OpenFile()); + m_FileIsOpen = true; + m_CurrentIndex++; + m_IsOk = true; + } + } + } + return WriteEmptyFiles(); +} + +STDMETHODIMP CCabFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + return Write2(data, size, processedSize, true); +} + +HRESULT CCabFolderOutStream::FlushCorrupted() +{ + const UInt32 kBufferSize = (1 << 10); + Byte buffer[kBufferSize]; + for (int i = 0; i < kBufferSize; i++) + buffer[i] = 0; + for (;;) + { + UInt64 remain = GetRemain(); + if (remain == 0) + return S_OK; + UInt32 size = (UInt32)MyMin(remain, (UInt64)kBufferSize); + UInt32 processedSizeLocal = 0; + RINOK(Write2(buffer, size, &processedSizeLocal, false)); + } +} + +HRESULT CCabFolderOutStream::Unsupported() +{ + while(m_CurrentIndex < m_ExtractStatuses->Size()) + { + HRESULT result = OpenFile(); + if (result != S_FALSE && result != S_OK) + return result; + m_RealOutStream.Release(); + RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + m_CurrentIndex++; + } + return S_OK; +} + + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool allFilesMode = (numItems == (UInt32)(-1)); + if (allFilesMode) + numItems = m_Database.Items.Size(); + if(numItems == 0) + return S_OK; + bool testMode = (_aTestMode != 0); + UInt64 totalUnPacked = 0; + + UInt32 i; + int lastFolder = -2; + UInt64 lastFolderSize = 0; + for(i = 0; i < numItems; i++) + { + int index = allFilesMode ? i : indices[i]; + const CMvItem &mvItem = m_Database.Items[index]; + const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; + if (item.IsDirectory()) + continue; + int folderIndex = m_Database.GetFolderIndex(&mvItem); + if (folderIndex != lastFolder) + totalUnPacked += lastFolderSize; + lastFolder = folderIndex; + lastFolderSize = item.GetEndOffset(); + } + totalUnPacked += lastFolderSize; + + extractCallback->SetTotal(totalUnPacked); + + totalUnPacked = 0; + + NCompress::CCopyCoder *copyCoderSpec = NULL; + CMyComPtr copyCoder; + + NCompress::NDeflate::NDecoder::CCOMCoder *deflateDecoderSpec = NULL; + CMyComPtr deflateDecoder; + + NCompress::NLzx::CDecoder *lzxDecoderSpec = NULL; + CMyComPtr lzxDecoder; + + NCompress::NQuantum::CDecoder *quantumDecoderSpec = NULL; + CMyComPtr quantumDecoder; + + CCabBlockInStream *cabBlockInStreamSpec = new CCabBlockInStream(); + CMyComPtr cabBlockInStream = cabBlockInStreamSpec; + if (!cabBlockInStreamSpec->Create()) + return E_OUTOFMEMORY; + + CRecordVector extractStatuses; + for(i = 0; i < numItems;) + { + int index = allFilesMode ? i : indices[i]; + + const CMvItem &mvItem = m_Database.Items[index]; + const CDatabaseEx &db = m_Database.Volumes[mvItem.VolumeIndex]; + int itemIndex = mvItem.ItemIndex; + const CItem &item = db.Items[itemIndex]; + + i++; + if (item.IsDirectory()) + { + Int32 askMode= testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + CMyComPtr realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + RINOK(extractCallback->PrepareOperation(askMode)); + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + continue; + } + int folderIndex = m_Database.GetFolderIndex(&mvItem); + if (folderIndex < 0) + { + // If we need previous archive + Int32 askMode= testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + CMyComPtr realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + RINOK(extractCallback->PrepareOperation(askMode)); + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); + continue; + } + int startIndex2 = m_Database.FolderStartFileIndex[folderIndex]; + int startIndex = startIndex2; + extractStatuses.Clear(); + for (; startIndex < index; startIndex++) + extractStatuses.Add(false); + extractStatuses.Add(true); + startIndex++; + UInt64 curUnpack = item.GetEndOffset(); + for(;i < numItems; i++) + { + int indexNext = allFilesMode ? i : indices[i]; + const CMvItem &mvItem = m_Database.Items[indexNext]; + const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; + if (item.IsDirectory()) + continue; + int newFolderIndex = m_Database.GetFolderIndex(&mvItem); + + if (newFolderIndex != folderIndex) + break; + for (; startIndex < indexNext; startIndex++) + extractStatuses.Add(false); + extractStatuses.Add(true); + startIndex++; + curUnpack = item.GetEndOffset(); + } + + RINOK(extractCallback->SetCompleted(&totalUnPacked)); + + CCabFolderOutStream *cabFolderOutStream = new CCabFolderOutStream; + CMyComPtr outStream(cabFolderOutStream); + + const CFolder &folder = db.Folders[item.GetFolderIndex(db.Folders.Size())]; + + cabFolderOutStream->Init(&m_Database, &extractStatuses, startIndex2, + curUnpack, extractCallback, testMode); + + cabBlockInStreamSpec->MsZip = false; + switch(folder.GetCompressionMethod()) + { + case NHeader::NCompressionMethodMajor::kNone: + if(copyCoderSpec == NULL) + { + copyCoderSpec = new NCompress::CCopyCoder; + copyCoder = copyCoderSpec; + } + break; + case NHeader::NCompressionMethodMajor::kMSZip: + if(deflateDecoderSpec == NULL) + { + deflateDecoderSpec = new NCompress::NDeflate::NDecoder::CCOMCoder; + deflateDecoder = deflateDecoderSpec; + } + cabBlockInStreamSpec->MsZip = true; + break; + case NHeader::NCompressionMethodMajor::kLZX: + if(lzxDecoderSpec == NULL) + { + lzxDecoderSpec = new NCompress::NLzx::CDecoder; + lzxDecoder = lzxDecoderSpec; + } + RINOK(lzxDecoderSpec->SetParams(folder.CompressionTypeMinor)); + break; + case NHeader::NCompressionMethodMajor::kQuantum: + if(quantumDecoderSpec == NULL) + { + quantumDecoderSpec = new NCompress::NQuantum::CDecoder; + quantumDecoder = quantumDecoderSpec; + } + quantumDecoderSpec->SetParams(folder.CompressionTypeMinor); + break; + default: + { + RINOK(cabFolderOutStream->Unsupported()); + totalUnPacked += curUnpack; + continue; + } + } + + cabBlockInStreamSpec->InitForNewFolder(); + + HRESULT res = S_OK; + + { + int volIndex = mvItem.VolumeIndex; + int locFolderIndex = item.GetFolderIndex(db.Folders.Size()); + bool keepHistory = false; + bool keepInputBuffer = false; + for (UInt32 f = 0; cabFolderOutStream->GetRemain() != 0;) + { + if (volIndex >= m_Database.Volumes.Size()) + { + res = S_FALSE; + break; + } + + const CDatabaseEx &db = m_Database.Volumes[volIndex]; + const CFolder &folder = db.Folders[locFolderIndex]; + if (f == 0) + { + cabBlockInStreamSpec->SetStream(db.Stream); + cabBlockInStreamSpec->ReservedSize = db.ArchiveInfo.GetDataBlockReserveSize(); + RINOK(db.Stream->Seek(db.StartPosition + folder.DataStart, STREAM_SEEK_SET, NULL)); + } + if (f == folder.NumDataBlocks) + { + volIndex++; + locFolderIndex = 0; + f = 0; + continue; + } + f++; + + cabBlockInStreamSpec->DataError = false; + + if (!keepInputBuffer) + cabBlockInStreamSpec->InitForNewBlock(); + + UInt32 packSize, unpackSize; + res = cabBlockInStreamSpec->PreRead(packSize, unpackSize); + if (res == S_FALSE) + break; + RINOK(res); + keepInputBuffer = (unpackSize == 0); + if (keepInputBuffer) + continue; + + + UInt64 totalUnPacked2 = totalUnPacked + cabFolderOutStream->GetPosInFolder(); + RINOK(extractCallback->SetCompleted(&totalUnPacked2)); + UInt64 unpackRemain = cabFolderOutStream->GetRemain(); + + const UInt32 kBlockSizeMax = (1 << 15); + if (unpackRemain > kBlockSizeMax) + unpackRemain = kBlockSizeMax; + if (unpackRemain > unpackSize) + unpackRemain = unpackSize; + + switch(folder.GetCompressionMethod()) + { + case NHeader::NCompressionMethodMajor::kNone: + res = copyCoder->Code(cabBlockInStream, outStream, NULL, &unpackRemain, NULL); + break; + case NHeader::NCompressionMethodMajor::kMSZip: + deflateDecoderSpec->SetKeepHistory(keepHistory); + res = deflateDecoder->Code(cabBlockInStream, outStream, NULL, &unpackRemain, NULL); + break; + case NHeader::NCompressionMethodMajor::kLZX: + lzxDecoderSpec->SetKeepHistory(keepHistory, cabBlockInStreamSpec->GetAlign()); + res = lzxDecoder->Code(cabBlockInStream, outStream, NULL, &unpackRemain, NULL); + break; + case NHeader::NCompressionMethodMajor::kQuantum: + quantumDecoderSpec->SetKeepHistory(keepHistory); + res = quantumDecoder->Code(cabBlockInStream, outStream, NULL, &unpackRemain, NULL); + break; + } + if (res != S_OK) + { + if (res != S_FALSE) + RINOK(res); + break; + } + keepHistory = true; + } + if (res == S_OK) + { + RINOK(cabFolderOutStream->WriteEmptyFiles()); + } + } + if (res != S_OK || cabFolderOutStream->GetRemain() != 0) + { + RINOK(cabFolderOutStream->FlushCorrupted()); + } + totalUnPacked += curUnpack; + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = m_Database.Items.Size(); + return S_OK; +} + +}} diff --git a/CPP/7zip/Archive/Cab/CabHandler.h b/CPP/7zip/Archive/Cab/CabHandler.h new file mode 100755 index 00000000..245586b6 --- /dev/null +++ b/CPP/7zip/Archive/Cab/CabHandler.h @@ -0,0 +1,45 @@ +// CabHandler.h + +#ifndef __CAB_HANDLER_H +#define __CAB_HANDLER_H + +#include "Common/MyCom.h" +#include "../IArchive.h" +#include "CabIn.h" + +namespace NArchive { +namespace NCab { + +class CHandler: + public IInArchive, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Open)(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback); + STDMETHOD(Close)(); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); + + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + +private: + CMvDatabaseEx m_Database; +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Cab/CabHeader.cpp b/CPP/7zip/Archive/Cab/CabHeader.cpp new file mode 100755 index 00000000..37533dff --- /dev/null +++ b/CPP/7zip/Archive/Cab/CabHeader.cpp @@ -0,0 +1,19 @@ +// Archive/Cab/Header.h + +#include "StdAfx.h" + +#include "CabHeader.h" + +namespace NArchive{ +namespace NCab{ +namespace NHeader{ + +namespace NArchive { + +UInt32 kSignature = 0x4643534d + 1; +static class CSignatureInitializer +{ public: CSignatureInitializer() { kSignature--; }} g_SignatureInitializer; + +} + +}}} diff --git a/CPP/7zip/Archive/Cab/CabHeader.h b/CPP/7zip/Archive/Cab/CabHeader.h new file mode 100755 index 00000000..5c122743 --- /dev/null +++ b/CPP/7zip/Archive/Cab/CabHeader.h @@ -0,0 +1,42 @@ +// Archive/Cab/Header.h + +#ifndef __ARCHIVE_CAB_HEADER_H +#define __ARCHIVE_CAB_HEADER_H + +#include "Common/Types.h" + +namespace NArchive { +namespace NCab { +namespace NHeader{ + +namespace NArchive +{ + extern UInt32 kSignature; + namespace NFlags + { + const int kPrevCabinet = 0x0001; + const int kNextCabinet = 0x0002; + const int kReservePresent = 0x0004; + } +} + +namespace NCompressionMethodMajor +{ + const Byte kNone = 0; + const Byte kMSZip = 1; + const Byte kQuantum = 2; + const Byte kLZX = 3; +} + +const int kFileNameIsUTFAttributeMask = 0x80; + +namespace NFolderIndex +{ + const int kContinuedFromPrev = 0xFFFD; + const int kContinuedToNext = 0xFFFE; + const int kContinuedPrevAndNext = 0xFFFF; +} + +}}} + +#endif diff --git a/CPP/7zip/Archive/Cab/CabIn.cpp b/CPP/7zip/Archive/Cab/CabIn.cpp new file mode 100755 index 00000000..ae774f19 --- /dev/null +++ b/CPP/7zip/Archive/Cab/CabIn.cpp @@ -0,0 +1,343 @@ +// Archive/CabIn.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Common/MyCom.h" +#include "CabIn.h" +#include "Windows/Defs.h" + +#include "../../Common/StreamUtils.h" + +namespace NArchive{ +namespace NCab{ + +/* +static HRESULT ReadBytes(IInStream *inStream, void *data, UInt32 size) +{ + UInt32 realProcessedSize; + RINOK(ReadStream(inStream, data, size, &realProcessedSize)); + if(realProcessedSize != size) + return S_FALSE; + return S_OK; +} + +static HRESULT SafeRead(IInStream *inStream, void *data, UInt32 size) +{ + UInt32 realProcessedSize; + RINOK(ReadStream(inStream, data, size, &realProcessedSize)); + if(realProcessedSize != size) + throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); + return S_OK; +} + +static void SafeInByteRead(::CInBuffer &inBuffer, void *data, UInt32 size) +{ + UInt32 realProcessedSize; + inBuffer.ReadBytes(data, size, realProcessedSize); + if(realProcessedSize != size) + throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); +} +*/ + +Byte CInArchive::ReadByte() +{ + Byte b; + if (!inBuffer.ReadByte(b)) + throw CInArchiveException(CInArchiveException::kUnsupported); + return b; +} + +UInt16 CInArchive::ReadUInt16() +{ + UInt16 value = 0; + for (int i = 0; i < 2; i++) + { + Byte b = ReadByte(); + value |= (UInt16(b) << (8 * i)); + } + return value; +} + +UInt32 CInArchive::ReadUInt32() +{ + UInt32 value = 0; + for (int i = 0; i < 4; i++) + { + Byte b = ReadByte(); + value |= (UInt32(b) << (8 * i)); + } + return value; +} + +AString CInArchive::SafeReadName() +{ + AString name; + for (;;) + { + Byte b = ReadByte(); + if (b == 0) + return name; + name += (char)b; + } +} + +void CInArchive::ReadOtherArchive(COtherArchive &oa) +{ + oa.FileName = SafeReadName(); + oa.DiskName = SafeReadName(); +} + +void CInArchive::Skeep(size_t size) +{ + while (size-- != 0) + ReadByte(); +} + +HRESULT CInArchive::Open2(IInStream *inStream, + const UInt64 *searchHeaderSizeLimit, + CDatabase &database) +{ + database.Clear(); + RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &database.StartPosition)); + + { + if (!inBuffer.Create(1 << 17)) + return E_OUTOFMEMORY; + inBuffer.SetStream(inStream); + inBuffer.Init(); + UInt64 value = 0; + const int kSignatureSize = 8; + UInt64 kSignature64 = NHeader::NArchive::kSignature; + for (;;) + { + Byte b; + if (!inBuffer.ReadByte(b)) + return S_FALSE; + value >>= 8; + value |= ((UInt64)b) << ((kSignatureSize - 1) * 8); + if (inBuffer.GetProcessedSize() >= kSignatureSize) + { + if (value == kSignature64) + break; + if (searchHeaderSizeLimit != NULL) + if (inBuffer.GetProcessedSize() > (*searchHeaderSizeLimit)) + return S_FALSE; + } + } + database.StartPosition += inBuffer.GetProcessedSize() - kSignatureSize; + } + + CInArchiveInfo &archiveInfo = database.ArchiveInfo; + + archiveInfo.Size = ReadUInt32(); // size of this cabinet file in bytes + if (ReadUInt32() != 0) + return S_FALSE; + archiveInfo.FileHeadersOffset = ReadUInt32(); // offset of the first CFFILE entry + if (ReadUInt32() != 0) + return S_FALSE; + + archiveInfo.VersionMinor = ReadByte(); // cabinet file format version, minor + archiveInfo.VersionMajor = ReadByte(); // cabinet file format version, major + archiveInfo.NumFolders = ReadUInt16(); // number of CFFOLDER entries in this cabinet + archiveInfo.NumFiles = ReadUInt16(); // number of CFFILE entries in this cabinet + archiveInfo.Flags = ReadUInt16(); // number of CFFILE entries in this cabinet + archiveInfo.SetID = ReadUInt16(); // must be the same for all cabinets in a set + archiveInfo.CabinetNumber = ReadUInt16(); // number of this cabinet file in a set + + if (archiveInfo.ReserveBlockPresent()) + { + archiveInfo.PerCabinetAreaSize = ReadUInt16(); // (optional) size of per-cabinet reserved area + archiveInfo.PerFolderAreaSize = ReadByte(); // (optional) size of per-folder reserved area + archiveInfo.PerDataBlockAreaSize = ReadByte(); // (optional) size of per-datablock reserved area + + Skeep(archiveInfo.PerCabinetAreaSize); + } + + { + if (archiveInfo.IsTherePrev()) + ReadOtherArchive(archiveInfo.PreviousArchive); + if (archiveInfo.IsThereNext()) + ReadOtherArchive(archiveInfo.NextArchive); + } + + int i; + for(i = 0; i < archiveInfo.NumFolders; i++) + { + CFolder folder; + + folder.DataStart = ReadUInt32(); + folder.NumDataBlocks = ReadUInt16(); + folder.CompressionTypeMajor = ReadByte(); + folder.CompressionTypeMinor = ReadByte(); + + Skeep(archiveInfo.PerFolderAreaSize); + database.Folders.Add(folder); + } + + RINOK(inStream->Seek(database.StartPosition + archiveInfo.FileHeadersOffset, STREAM_SEEK_SET, NULL)); + + inBuffer.SetStream(inStream); + inBuffer.Init(); + for(i = 0; i < archiveInfo.NumFiles; i++) + { + CItem item; + item.Size = ReadUInt32(); + item.Offset = ReadUInt32(); + item.FolderIndex = ReadUInt16(); + UInt16 pureDate = ReadUInt16(); + UInt16 pureTime = ReadUInt16(); + item.Time = ((UInt32(pureDate) << 16)) | pureTime; + item.Attributes = ReadUInt16(); + item.Name = SafeReadName(); + int folderIndex = item.GetFolderIndex(database.Folders.Size()); + if (folderIndex >= database.Folders.Size()) + return S_FALSE; + database.Items.Add(item); + } + return S_OK; +} + +#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } + +HRESULT CInArchive::Open( + const UInt64 *searchHeaderSizeLimit, + CDatabaseEx &database) +{ + return Open2(database.Stream, searchHeaderSizeLimit, database); +} + + +static int CompareMvItems2(const CMvItem *p1, const CMvItem *p2) +{ + RINOZ(MyCompare(p1->VolumeIndex, p2->VolumeIndex)); + return MyCompare(p1->ItemIndex, p2->ItemIndex); +} + +static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param) +{ + const CMvDatabaseEx &mvDb = *(const CMvDatabaseEx *)param; + const CDatabaseEx &db1 = mvDb.Volumes[p1->VolumeIndex]; + const CDatabaseEx &db2 = mvDb.Volumes[p2->VolumeIndex]; + const CItem &item1 = db1.Items[p1->ItemIndex]; + const CItem &item2 = db2.Items[p2->ItemIndex];; + bool isDir1 = item1.IsDirectory(); + bool isDir2 = item2.IsDirectory(); + if (isDir1 && !isDir2) + return -1; + if (isDir2 && !isDir1) + return 1; + int f1 = mvDb.GetFolderIndex(p1); + int f2 = mvDb.GetFolderIndex(p2); + RINOZ(MyCompare(f1, f2)); + RINOZ(MyCompare(item1.Offset, item2.Offset)); + RINOZ(MyCompare(item1.Size, item2.Size)); + return CompareMvItems2(p1, p2); +} + +bool CMvDatabaseEx::AreItemsEqual(int i1, int i2) +{ + const CMvItem *p1 = &Items[i1]; + const CMvItem *p2 = &Items[i2]; + const CDatabaseEx &db1 = Volumes[p1->VolumeIndex]; + const CDatabaseEx &db2 = Volumes[p2->VolumeIndex]; + const CItem &item1 = db1.Items[p1->ItemIndex]; + const CItem &item2 = db2.Items[p2->ItemIndex];; + int f1 = GetFolderIndex(p1); + int f2 = GetFolderIndex(p2); + if (f1 != f2) + return false; + if (item1.Offset != item2.Offset) + return false; + if (item1.Size != item2.Size) + return false; + + return true; +} + +void CMvDatabaseEx::FillSortAndShrink() +{ + Items.Clear(); + StartFolderOfVol.Clear(); + FolderStartFileIndex.Clear(); + int offset = 0; + for (int v = 0; v < Volumes.Size(); v++) + { + const CDatabaseEx &db = Volumes[v]; + int curOffset = offset; + if (db.IsTherePrevFolder()) + curOffset--; + StartFolderOfVol.Add(curOffset); + offset += db.GetNumberOfNewFolders(); + + CMvItem mvItem; + mvItem.VolumeIndex = v; + for (int i = 0 ; i < db.Items.Size(); i++) + { + mvItem.ItemIndex = i; + Items.Add(mvItem); + } + } + + Items.Sort(CompareMvItems, (void *)this); + int j = 1; + int i; + for (i = 1; i < Items.Size(); i++) + if (!AreItemsEqual(i, i -1)) + Items[j++] = Items[i]; + Items.DeleteFrom(j); + + for (i = 0; i < Items.Size(); i++) + { + const CMvItem &mvItem = Items[i]; + int folderIndex = GetFolderIndex(&mvItem); + if (folderIndex >= FolderStartFileIndex.Size()) + FolderStartFileIndex.Add(i); + } +} + +bool CMvDatabaseEx::Check() +{ + for (int v = 1; v < Volumes.Size(); v++) + { + const CDatabaseEx &db1 = Volumes[v]; + if (db1.IsTherePrevFolder()) + { + const CDatabaseEx &db0 = Volumes[v - 1]; + if (db0.Folders.IsEmpty() || db1.Folders.IsEmpty()) + return false; + const CFolder &f0 = db0.Folders.Back(); + const CFolder &f1 = db1.Folders.Front(); + if (f0.CompressionTypeMajor != f1.CompressionTypeMajor || + f0.CompressionTypeMinor != f1.CompressionTypeMinor) + return false; + } + } + UInt64 maxPos = 0; + int prevFolder = -2; + for(int i = 0; i < Items.Size(); i++) + { + const CMvItem &mvItem = Items[i]; + int fIndex = GetFolderIndex(&mvItem); + if (fIndex >= FolderStartFileIndex.Size()) + return false; + const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; + if (item.IsDirectory()) + continue; + int folderIndex = GetFolderIndex(&mvItem); + if (folderIndex != prevFolder) + { + prevFolder = folderIndex; + maxPos = 0; + continue; + } + if (item.Offset < maxPos) + return false; + maxPos = item.GetEndOffset(); + if (maxPos < item.Offset) + return false; + } + return true; +} + +}} diff --git a/CPP/7zip/Archive/Cab/CabIn.h b/CPP/7zip/Archive/Cab/CabIn.h new file mode 100755 index 00000000..aa3008f1 --- /dev/null +++ b/CPP/7zip/Archive/Cab/CabIn.h @@ -0,0 +1,166 @@ +// Archive/CabIn.h + +#ifndef __ARCHIVE_CAB_IN_H +#define __ARCHIVE_CAB_IN_H + +#include "../../IStream.h" +#include "../../Common/InBuffer.h" +#include "CabHeader.h" +#include "CabItem.h" + +namespace NArchive { +namespace NCab { + +class CInArchiveException +{ +public: + enum CCauseType + { + kUnexpectedEndOfArchive = 0, + kIncorrectArchive, + kUnsupported, + } Cause; + CInArchiveException(CCauseType cause) : Cause(cause) {} +}; + +struct COtherArchive +{ + AString FileName; + AString DiskName; +}; + +struct CArchiveInfo +{ + Byte VersionMinor; /* cabinet file format version, minor */ + Byte VersionMajor; /* cabinet file format version, major */ + UInt16 NumFolders; /* number of CFFOLDER entries in this cabinet */ + UInt16 NumFiles; /* number of CFFILE entries in this cabinet */ + UInt16 Flags; /* cabinet file option indicators */ + UInt16 SetID; /* must be the same for all cabinets in a set */ + UInt16 CabinetNumber; /* number of this cabinet file in a set */ + + bool ReserveBlockPresent() const { return (Flags & NHeader::NArchive::NFlags::kReservePresent) != 0; } + + bool IsTherePrev() const { return (Flags & NHeader::NArchive::NFlags::kPrevCabinet) != 0; } + bool IsThereNext() const { return (Flags & NHeader::NArchive::NFlags::kNextCabinet) != 0; } + + UInt16 PerCabinetAreaSize; // (optional) size of per-cabinet reserved area + Byte PerFolderAreaSize; // (optional) size of per-folder reserved area + Byte PerDataBlockAreaSize; // (optional) size of per-datablock reserved area + + Byte GetDataBlockReserveSize() const { return (Byte)(ReserveBlockPresent() ? PerDataBlockAreaSize : 0); } + + COtherArchive PreviousArchive; + COtherArchive NextArchive; + + CArchiveInfo() + { + Clear(); + } + + void Clear() + { + PerCabinetAreaSize = 0; + PerFolderAreaSize = 0; + PerDataBlockAreaSize = 0; + } +}; + +struct CInArchiveInfo: public CArchiveInfo +{ + UInt32 Size; /* size of this cabinet file in bytes */ + UInt32 FileHeadersOffset; // offset of the first CFFILE entry +}; + + +class CDatabase +{ +public: + UInt64 StartPosition; + CInArchiveInfo ArchiveInfo; + CObjectVector Folders; + CObjectVector Items; + void Clear() + { + ArchiveInfo.Clear(); + Folders.Clear(); + Items.Clear(); + } + bool IsTherePrevFolder() const + { + for (int i = 0; i < Items.Size(); i++) + if (Items[i].ContinuedFromPrev()) + return true; + return false; + } + int GetNumberOfNewFolders() const + { + int res = Folders.Size(); + if (IsTherePrevFolder()) + res--; + return res; + } + UInt32 GetFileOffset(int index) const { return Items[index].Offset; } + UInt32 GetFileSize(int index) const { return Items[index].Size; } +}; + +class CDatabaseEx: public CDatabase +{ +public: + CMyComPtr Stream; +}; + +struct CMvItem +{ + int VolumeIndex; + int ItemIndex; +}; + +class CMvDatabaseEx +{ + bool AreItemsEqual(int i1, int i2); +public: + CObjectVector Volumes; + CRecordVector Items; + CRecordVector StartFolderOfVol; + CRecordVector FolderStartFileIndex; + int GetFolderIndex(const CMvItem *mvi) const + { + const CDatabaseEx &db = Volumes[mvi->VolumeIndex]; + return StartFolderOfVol[mvi->VolumeIndex] + + db.Items[mvi->ItemIndex].GetFolderIndex(db.Folders.Size()); + } + void Clear() + { + Volumes.Clear(); + Items.Clear(); + StartFolderOfVol.Clear(); + FolderStartFileIndex.Clear(); + } + void FillSortAndShrink(); + bool Check(); +}; + +class CInArchive +{ + CInBuffer inBuffer; + + Byte ReadByte(); + UInt16 ReadUInt16(); + UInt32 ReadUInt32(); + AString SafeReadName(); + void Skeep(size_t size); + void ReadOtherArchive(COtherArchive &oa); + + HRESULT Open2(IInStream *inStream, + const UInt64 *searchHeaderSizeLimit, + CDatabase &database); +public: + HRESULT Open( + const UInt64 *searchHeaderSizeLimit, + CDatabaseEx &database); +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Cab/CabItem.h b/CPP/7zip/Archive/Cab/CabItem.h new file mode 100755 index 00000000..21327eca --- /dev/null +++ b/CPP/7zip/Archive/Cab/CabItem.h @@ -0,0 +1,62 @@ +// Archive/CabItem.h + +#ifndef __ARCHIVE_CAB_ITEM_H +#define __ARCHIVE_CAB_ITEM_H + +#include "Common/Types.h" +#include "Common/String.h" +#include "CabHeader.h" + +namespace NArchive { +namespace NCab { + +struct CFolder +{ + UInt32 DataStart; // offset of the first CFDATA block in this folder + UInt16 NumDataBlocks; // number of CFDATA blocks in this folder + Byte CompressionTypeMajor; + Byte CompressionTypeMinor; + Byte GetCompressionMethod() const { return (Byte)(CompressionTypeMajor & 0xF); } +}; + +class CItem +{ +public: + AString Name; + UInt32 Offset; + UInt32 Size; + UInt32 Time; + UInt16 FolderIndex; + UInt16 Flags; + UInt16 Attributes; + UInt64 GetEndOffset() const { return (UInt64)Offset + Size; } + UInt32 GetWinAttributes() const { return (Attributes & ~NHeader::kFileNameIsUTFAttributeMask); } + bool IsNameUTF() const { return (Attributes & NHeader::kFileNameIsUTFAttributeMask) != 0; } + bool IsDirectory() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; } + + bool ContinuedFromPrev() const + { + return + (FolderIndex == NHeader::NFolderIndex::kContinuedFromPrev) || + (FolderIndex == NHeader::NFolderIndex::kContinuedPrevAndNext); + } + bool ContinuedToNext() const + { + return + (FolderIndex == NHeader::NFolderIndex::kContinuedToNext) || + (FolderIndex == NHeader::NFolderIndex::kContinuedPrevAndNext); + } + + int GetFolderIndex(int numFolders) const + { + if (ContinuedFromPrev()) + return 0; + if (ContinuedToNext()) + return (numFolders - 1); + return FolderIndex; + } +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Cab/DllExports.cpp b/CPP/7zip/Archive/Cab/DllExports.cpp new file mode 100755 index 00000000..fa17f10b --- /dev/null +++ b/CPP/7zip/Archive/Cab/DllExports.cpp @@ -0,0 +1,72 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "Windows/PropVariant.h" +#include "CabHandler.h" +#include "../../ICoder.h" + +// {23170F69-40C1-278A-1000-000110080000} +DEFINE_GUID(CLSID_CCabHandler, + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x08, 0x00, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) +{ + return TRUE; +} + +STDAPI CreateObject( + const GUID *classID, + const GUID *interfaceID, + void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + if (*classID != CLSID_CCabHandler) + return CLASS_E_CLASSNOTAVAILABLE; + if (*interfaceID != IID_IInArchive) + return E_NOINTERFACE; + CMyComPtr inArchive = (IInArchive *)new NArchive::NCab::CHandler; + *outObject = inArchive.Detach(); + COM_TRY_END + return S_OK; +} + +STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case NArchive::kName: + propVariant = L"Cab"; + break; + case NArchive::kClassID: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CCabHandler, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NArchive::kExtension: + propVariant = L"cab"; + break; + case NArchive::kUpdate: + propVariant = false; + break; + case NArchive::kKeepName: + propVariant = false; + break; + case NArchive::kStartSignature: + { + const char sig[] = { 0x4D, 0x53, 0x43, 0x46 }; + if ((value->bstrVal = ::SysAllocStringByteLen(sig, 4)) != 0) + value->vt = VT_BSTR; + return S_OK; + } + } + propVariant.Detach(value); + return S_OK; +} diff --git a/CPP/7zip/Archive/Cab/StdAfx.cpp b/CPP/7zip/Archive/Cab/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Archive/Cab/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Cab/StdAfx.h b/CPP/7zip/Archive/Cab/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Archive/Cab/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Archive/Cab/cab.ico b/CPP/7zip/Archive/Cab/cab.ico new file mode 100755 index 00000000..cc2007fc Binary files /dev/null and b/CPP/7zip/Archive/Cab/cab.ico differ diff --git a/CPP/7zip/Archive/Cab/makefile b/CPP/7zip/Archive/Cab/makefile new file mode 100755 index 00000000..672afed3 --- /dev/null +++ b/CPP/7zip/Archive/Cab/makefile @@ -0,0 +1,70 @@ +PROG = cab.dll +DEF_FILE = ../Archive.def +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib user32.lib + +CAB_OBJS = \ + $O\DllExports.obj \ + $O\CabBlockInStream.obj \ + $O\CabHandler.obj \ + $O\CabHeader.obj \ + $O\CabIn.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\UTFConvert.obj \ + $O\Vector.obj \ + +WIN_OBJS = \ + $O\PropVariant.obj \ + +7ZIP_COMMON_OBJS = \ + $O\InBuffer.obj \ + $O\LSBFDecoder.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ + +COMPRESS_LZX_OBJS = \ + $O\LzxDecoder.obj \ + $O\Lzx86Converter.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(CAB_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(COMPRESS_LZX_OBJS) \ + $O\DeflateDecoder.obj \ + $O\QuantumDecoder.obj \ + $O\LZOutWindow.obj \ + $O\CopyCoder.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(CAB_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(COMPRESS_LZX_OBJS): ../../Compress/Lzx/$(*B).cpp + $(COMPL_O2) +$O\DeflateDecoder.obj: ../../Compress/Deflate/$(*B).cpp + $(COMPL_O2) +$O\QuantumDecoder.obj: ../../Compress/Quantum/$(*B).cpp + $(COMPL) +$O\LZOutWindow.obj: ../../Compress/LZ/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) + diff --git a/CPP/7zip/Archive/Cab/resource.rc b/CPP/7zip/Archive/Cab/resource.rc new file mode 100755 index 00000000..fa0792bd --- /dev/null +++ b/CPP/7zip/Archive/Cab/resource.rc @@ -0,0 +1,5 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("Cab Plugin", "cab") + +101 ICON "cab.ico" diff --git a/CPP/7zip/Archive/Chm/Chm.dsp b/CPP/7zip/Archive/Chm/Chm.dsp new file mode 100755 index 00000000..7e0b7c66 --- /dev/null +++ b/CPP/7zip/Archive/Chm/Chm.dsp @@ -0,0 +1,337 @@ +# Microsoft Developer Studio Project File - Name="Chm" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Chm - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Chm.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Chm.mak" CFG="Chm - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Chm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Chm - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Chm - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CHM_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CHM_EXPORTS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\chm.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Chm - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CHM_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CHM_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\chm.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Chm - Win32 Release" +# Name "Chm - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Archive.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ChmHandler.cpp +# End Source File +# Begin Source File + +SOURCE=.\ChmHandler.h +# End Source File +# Begin Source File + +SOURCE=.\ChmHeader.cpp +# End Source File +# Begin Source File + +SOURCE=.\ChmHeader.h +# End Source File +# Begin Source File + +SOURCE=.\ChmIn.cpp +# End Source File +# Begin Source File + +SOURCE=.\ChmIn.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Buffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Group "LZ" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.h +# End Source File +# End Group +# Begin Group "Lzx" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Lzx\Lzx.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzx\Lzx86Converter.cpp + +!IF "$(CFG)" == "Chm - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Chm - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzx\Lzx86Converter.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzx\LzxDecoder.cpp + +!IF "$(CFG)" == "Chm - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Chm - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzx\LzxDecoder.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# End Target +# End Project diff --git a/CPP/7zip/Archive/Chm/Chm.dsw b/CPP/7zip/Archive/Chm/Chm.dsw new file mode 100755 index 00000000..58cb09b2 --- /dev/null +++ b/CPP/7zip/Archive/Chm/Chm.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Chm"=.\Chm.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Archive/Chm/ChmHandler.cpp b/CPP/7zip/Archive/Chm/ChmHandler.cpp new file mode 100755 index 00000000..6b37c73e --- /dev/null +++ b/CPP/7zip/Archive/Chm/ChmHandler.cpp @@ -0,0 +1,731 @@ +// Chm/Handler.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Common/Defs.h" +#include "Common/UTFConvert.h" +#include "Common/ComTry.h" + +#include "Windows/PropVariant.h" +#include "Windows/Time.h" + +#include "../../Common/LimitedStreams.h" +#include "../../Common/StreamUtils.h" +#include "../../Common/ProgressUtils.h" + +#include "../../Compress/Copy/CopyCoder.h" +#include "../../Compress/Lzx/LzxDecoder.h" + +#include "../Common/ItemNameUtils.h" + +#include "ChmHandler.h" + + +using namespace NWindows; +using namespace NTime; + +namespace NArchive { +namespace NChm { + +// #define _CHM_DETAILS + +#ifdef _CHM_DETAILS + +enum +{ + kpidSection = kpidUserDefined, + kpidOffset +}; + +#endif + +STATPROPSTG kProperties[] = +{ + { NULL, kpidPath, VT_BSTR}, + // { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidMethod, VT_BSTR}, + { NULL, kpidBlock, VT_UI4} + + #ifdef _CHM_DETAILS + , + { L"Section", kpidSection, VT_UI4}, + { L"Offset", kpidOffset, VT_UI4} + #endif +}; + +static const int kNumProperties = sizeof(kProperties) / sizeof(kProperties[0]); + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) +{ + value->vt = VT_EMPTY; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if(index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &srcItem = kProperties[index]; + *propID = srcItem.propid; + *varType = srcItem.vt; + if (srcItem.lpwstrName == 0) + *name = 0; + else + *name = ::SysAllocString(srcItem.lpwstrName); + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +{ + *numProperties = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, + BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) +{ + return E_INVALIDARG; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant propVariant; + if (m_Database.NewFormat) + { + switch(propID) + { + case kpidSize: + propVariant = (UInt64)m_Database.NewFormatString.Length(); + break; + } + propVariant.Detach(value); + return S_OK; + } + int entryIndex; + if (m_Database.LowLevel) + entryIndex = index; + else + entryIndex = m_Database.Indices[index]; + const CItem &item = m_Database.Items[entryIndex]; + switch(propID) + { + case kpidPath: + { + UString us; + if (ConvertUTF8ToUnicode(item.Name, us)) + { + if (!m_Database.LowLevel) + { + if (us.Length() > 1) + if (us[0] == L'/') + us.Delete(0); + } + propVariant = NItemName::GetOSName2(us); + } + break; + } + case kpidIsFolder: + propVariant = item.IsDirectory(); + break; + case kpidSize: + propVariant = item.Size; + break; + case kpidMethod: + { + if (!item.IsDirectory()) + if (item.Section == 0) + propVariant = L"Copy"; + else if (item.Section < m_Database.Sections.Size()) + propVariant = m_Database.Sections[(int)item.Section].GetMethodName(); + break; + } + case kpidBlock: + if (m_Database.LowLevel) + propVariant = item.Section; + else if (item.Section != 0) + propVariant = m_Database.GetFolder(index); + break; + + #ifdef _CHM_DETAILS + + case kpidSection: + propVariant = (UInt32)item.Section; + break; + case kpidOffset: + propVariant = (UInt32)item.Offset; + break; + + #endif + } + propVariant.Detach(value); + return S_OK; + COM_TRY_END +} + +class CPropgressImp: public CProgressVirt +{ + CMyComPtr m_OpenArchiveCallback; +public: + STDMETHOD(SetTotal)(const UInt64 *numFiles); + STDMETHOD(SetCompleted)(const UInt64 *numFiles); + void Init(IArchiveOpenCallback *openArchiveCallback) + { m_OpenArchiveCallback = openArchiveCallback; } +}; + +STDMETHODIMP CPropgressImp::SetTotal(const UInt64 *numFiles) +{ + if (m_OpenArchiveCallback) + return m_OpenArchiveCallback->SetCompleted(numFiles, NULL); + return S_OK; +} + +STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles) +{ + if (m_OpenArchiveCallback) + return m_OpenArchiveCallback->SetCompleted(numFiles, NULL); + return S_OK; +} + +STDMETHODIMP CHandler::Open(IInStream *inStream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback) +{ + COM_TRY_BEGIN + m_Stream.Release(); + try + { + CInArchive archive; + CPropgressImp progressImp; + progressImp.Init(openArchiveCallback); + RINOK(archive.Open(inStream, maxCheckStartPosition, m_Database)); + /* + if (m_Database.LowLevel) + return S_FALSE; + */ + m_Stream = inStream; + } + catch(...) + { + return S_FALSE; + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + m_Database.Clear(); + m_Stream.Release(); + return S_OK; +} + +class CChmFolderOutStream: + public ISequentialOutStream, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + HRESULT Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + + UInt64 m_FolderSize; + UInt64 m_PosInFolder; + UInt64 m_PosInSection; + const CRecordVector *m_ExtractStatuses; + int m_StartIndex; + int m_CurrentIndex; + int m_NumFiles; + +private: + const CFilesDatabase *m_Database; + CMyComPtr m_ExtractCallback; + bool m_TestMode; + + bool m_IsOk; + bool m_FileIsOpen; + UInt64 m_RemainFileSize; + CMyComPtr m_RealOutStream; + + HRESULT OpenFile(); + HRESULT WriteEmptyFiles(); +public: + void Init( + const CFilesDatabase *database, + IArchiveExtractCallback *extractCallback, + bool testMode); + HRESULT FlushCorrupted(); +}; + +void CChmFolderOutStream::Init( + const CFilesDatabase *database, + IArchiveExtractCallback *extractCallback, + bool testMode) +{ + m_Database = database; + m_ExtractCallback = extractCallback; + m_TestMode = testMode; + + m_CurrentIndex = 0; + m_FileIsOpen = false; +} + +HRESULT CChmFolderOutStream::OpenFile() +{ + Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract) : + NExtract::NAskMode::kSkip; + m_RealOutStream.Release(); + RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &m_RealOutStream, askMode)); + if (!m_RealOutStream && !m_TestMode) + askMode = NArchive::NExtract::NAskMode::kSkip; + return m_ExtractCallback->PrepareOperation(askMode); +} + +HRESULT CChmFolderOutStream::WriteEmptyFiles() +{ + if (m_FileIsOpen) + return S_OK; + for(;m_CurrentIndex < m_NumFiles; m_CurrentIndex++) + { + UInt64 fileSize = m_Database->GetFileSize(m_StartIndex + m_CurrentIndex); + if (fileSize != 0) + return S_OK; + HRESULT result = OpenFile(); + m_RealOutStream.Release(); + RINOK(result); + RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + } + return S_OK; +} + +// This is WritePart function +HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK) +{ + UInt32 realProcessed = 0; + if (processedSize != NULL) + *processedSize = 0; + while(size != 0) + { + if (m_FileIsOpen) + { + UInt32 numBytesToWrite = (UInt32)MyMin(m_RemainFileSize, (UInt64)(size)); + HRESULT res = S_OK; + if (numBytesToWrite > 0) + { + if (!isOK) + m_IsOk = false; + if (m_RealOutStream) + { + UInt32 processedSizeLocal = 0; + res = m_RealOutStream->Write((const Byte *)data, numBytesToWrite, &processedSizeLocal); + numBytesToWrite = processedSizeLocal; + } + } + realProcessed += numBytesToWrite; + if (processedSize != NULL) + *processedSize = realProcessed; + data = (const void *)((const Byte *)data + numBytesToWrite); + size -= numBytesToWrite; + m_RemainFileSize -= numBytesToWrite; + m_PosInSection += numBytesToWrite; + m_PosInFolder += numBytesToWrite; + if (res != S_OK) + return res; + if (m_RemainFileSize == 0) + { + m_RealOutStream.Release(); + RINOK(m_ExtractCallback->SetOperationResult( + m_IsOk ? + NArchive::NExtract::NOperationResult::kOK: + NArchive::NExtract::NOperationResult::kDataError)); + m_FileIsOpen = false; + } + if (realProcessed > 0) + break; // with this break this function works as write part + } + else + { + if (m_CurrentIndex >= m_NumFiles) + return E_FAIL; + int fullIndex = m_StartIndex + m_CurrentIndex; + m_RemainFileSize = m_Database->GetFileSize(fullIndex); + UInt64 fileOffset = m_Database->GetFileOffset(fullIndex); + if (fileOffset < m_PosInSection) + return E_FAIL; + if (fileOffset > m_PosInSection) + { + UInt32 numBytesToWrite = (UInt32)MyMin(fileOffset - m_PosInSection, UInt64(size)); + realProcessed += numBytesToWrite; + if (processedSize != NULL) + *processedSize = realProcessed; + data = (const void *)((const Byte *)data + numBytesToWrite); + size -= numBytesToWrite; + m_PosInSection += numBytesToWrite; + m_PosInFolder += numBytesToWrite; + } + if (fileOffset == m_PosInSection) + { + RINOK(OpenFile()); + m_FileIsOpen = true; + m_CurrentIndex++; + m_IsOk = true; + } + } + } + return WriteEmptyFiles(); +} + +STDMETHODIMP CChmFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + return Write2(data, size, processedSize, true); +} + +HRESULT CChmFolderOutStream::FlushCorrupted() +{ + const UInt32 kBufferSize = (1 << 10); + Byte buffer[kBufferSize]; + for (int i = 0; i < kBufferSize; i++) + buffer[i] = 0; + while(m_PosInFolder < m_FolderSize) + { + UInt32 size = (UInt32)MyMin(m_FolderSize - m_PosInFolder, (UInt64)kBufferSize); + UInt32 processedSizeLocal = 0; + RINOK(Write2(buffer, size, &processedSizeLocal, false)); + } + return S_OK; +} + + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool allFilesMode = (numItems == UInt32(-1)); + + if (allFilesMode) + numItems = m_Database.NewFormat ? 1: + (m_Database.LowLevel ? + m_Database.Items.Size(): + m_Database.Indices.Size()); + if(numItems == 0) + return S_OK; + bool testMode = (_aTestMode != 0); + + UInt64 currentTotalSize = 0; + + CMyComPtr copyCoder; + UInt32 i; + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr inStream(streamSpec); + + if (m_Database.LowLevel) + { + UInt64 currentItemSize = 0; + UInt64 totalSize = 0; + if (m_Database.NewFormat) + totalSize = m_Database.NewFormatString.Length(); + else + for(i = 0; i < numItems; i++) + totalSize += m_Database.Items[allFilesMode ? i : indices[i]].Size; + extractCallback->SetTotal(totalSize); + + for(i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + { + RINOK(extractCallback->SetCompleted(¤tTotalSize)); + CMyComPtr realOutStream; + Int32 askMode; + askMode = testMode ? NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + Int32 index = allFilesMode ? i : indices[i]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + + if (m_Database.NewFormat) + { + if (index != 0) + return E_FAIL; + if(!testMode && (!realOutStream)) + continue; + if (!testMode) + { + UInt32 size = m_Database.NewFormatString.Length(); + RINOK(WriteStream(realOutStream, (const char *)m_Database.NewFormatString, size, 0)); + } + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + continue; + } + const CItem &item = m_Database.Items[index]; + + currentItemSize = item.Size; + + if(!testMode && (!realOutStream)) + continue; + RINOK(extractCallback->PrepareOperation(askMode)); + if (item.Section != 0) + { + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + continue; + } + + if (testMode) + { + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + continue; + } + + RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL)); + streamSpec->SetStream(m_Stream); + streamSpec->Init(item.Size); + + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr progress = localProgressSpec; + localProgressSpec->Init(extractCallback, false); + + CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo; + CMyComPtr compressProgress = localCompressProgressSpec; + localCompressProgressSpec->Init(progress, ¤tTotalSize, ¤tTotalSize); + + if(!copyCoder) + copyCoder = new NCompress::CCopyCoder; + RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, compressProgress)); + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + } + return S_OK; + } + + UInt64 lastFolderIndex = ((UInt64)0 - 1); + for(i = 0; i < numItems; i++) + { + UInt32 index = allFilesMode ? i : indices[i]; + int entryIndex = m_Database.Indices[index]; + const CItem &item = m_Database.Items[entryIndex]; + UInt64 sectionIndex = item.Section; + if (item.IsDirectory() || item.Size == 0) + continue; + if (sectionIndex == 0) + { + currentTotalSize += item.Size; + continue; + } + const CSectionInfo §ion = m_Database.Sections[(int)item.Section]; + if (section.IsLzx()) + { + const CLzxInfo &lzxInfo = section.Methods[0].LzxInfo; + UInt64 folderIndex = m_Database.GetFolder(index); + if (lastFolderIndex == folderIndex) + folderIndex++; + lastFolderIndex = m_Database.GetLastFolder(index); + for (; folderIndex <= lastFolderIndex; folderIndex++) + currentTotalSize += lzxInfo.GetFolderSize(); + } + } + + RINOK(extractCallback->SetTotal(currentTotalSize)); + + NCompress::NLzx::CDecoder *lzxDecoderSpec = 0; + CMyComPtr lzxDecoder; + CChmFolderOutStream *chmFolderOutStream = 0; + CMyComPtr outStream; + + currentTotalSize = 0; + + CRecordVector extractStatuses; + for(i = 0; i < numItems;) + { + RINOK(extractCallback->SetCompleted(¤tTotalSize)); + UInt32 index = allFilesMode ? i : indices[i]; + i++; + int entryIndex = m_Database.Indices[index]; + const CItem &item = m_Database.Items[entryIndex]; + UInt64 sectionIndex = item.Section; + Int32 askMode= testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + if (item.IsDirectory()) + { + CMyComPtr realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + RINOK(extractCallback->PrepareOperation(askMode)); + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + continue; + } + + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr progress = localProgressSpec; + localProgressSpec->Init(extractCallback, false); + + CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo; + CMyComPtr compressProgress = localCompressProgressSpec; + localCompressProgressSpec->Init(progress, NULL, ¤tTotalSize); + + if (item.Size == 0 || sectionIndex == 0) + { + CMyComPtr realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + if(!testMode && (!realOutStream)) + continue; + RINOK(extractCallback->PrepareOperation(askMode)); + if (!testMode && item.Size != 0) + { + RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL)); + streamSpec->SetStream(m_Stream); + streamSpec->Init(item.Size); + if(!copyCoder) + copyCoder = new NCompress::CCopyCoder; + RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, compressProgress)); + } + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + currentTotalSize += item.Size; + continue; + } + + const CSectionInfo §ion = m_Database.Sections[(int)sectionIndex]; + + if (!section.IsLzx()) + { + CMyComPtr realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + if(!testMode && (!realOutStream)) + continue; + RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + continue; + } + + const CLzxInfo &lzxInfo = section.Methods[0].LzxInfo; + + if (chmFolderOutStream == 0) + { + chmFolderOutStream = new CChmFolderOutStream; + outStream = chmFolderOutStream; + } + + chmFolderOutStream->Init(&m_Database, extractCallback, testMode); + + if(lzxDecoderSpec == NULL) + { + lzxDecoderSpec = new NCompress::NLzx::CDecoder; + lzxDecoder = lzxDecoderSpec; + } + + UInt64 folderIndex = m_Database.GetFolder(index); + + UInt64 compressedPos = m_Database.ContentOffset + section.Offset; + UInt32 numDictBits = lzxInfo.GetNumDictBits(); + RINOK(lzxDecoderSpec->SetParams(numDictBits)); + + const CItem *lastItem = &item; + extractStatuses.Clear(); + extractStatuses.Add(true); + + for (;; folderIndex++) + { + RINOK(extractCallback->SetCompleted(¤tTotalSize)); + + UInt64 startPos = lzxInfo.GetFolderPos(folderIndex); + UInt64 finishPos = lastItem->Offset + lastItem->Size; + UInt64 limitFolderIndex = lzxInfo.GetFolder(finishPos); + + lastFolderIndex = m_Database.GetLastFolder(index); + UInt64 folderSize = lzxInfo.GetFolderSize(); + UInt64 unPackSize = folderSize; + if (extractStatuses.IsEmpty()) + chmFolderOutStream->m_StartIndex = index + 1; + else + chmFolderOutStream->m_StartIndex = index; + if (limitFolderIndex == folderIndex) + { + for(; i < numItems; i++) + { + UInt32 nextIndex = allFilesMode ? i : indices[i]; + int entryIndex = m_Database.Indices[nextIndex]; + const CItem &nextItem = m_Database.Items[entryIndex]; + if (nextItem.Section != sectionIndex) + break; + UInt64 nextFolderIndex = m_Database.GetFolder(nextIndex); + if (nextFolderIndex != folderIndex) + break; + for (index++; index < nextIndex; index++) + extractStatuses.Add(false); + extractStatuses.Add(true); + index = nextIndex; + lastItem = &nextItem; + if (nextItem.Size != 0) + finishPos = nextItem.Offset + nextItem.Size; + lastFolderIndex = m_Database.GetLastFolder(index); + } + } + unPackSize = MyMin(finishPos - startPos, unPackSize); + + chmFolderOutStream->m_FolderSize = folderSize; + chmFolderOutStream->m_PosInFolder = 0; + chmFolderOutStream->m_PosInSection = startPos; + chmFolderOutStream->m_ExtractStatuses = &extractStatuses; + chmFolderOutStream->m_NumFiles = extractStatuses.Size(); + chmFolderOutStream->m_CurrentIndex = 0; + try + { + UInt64 startBlock = lzxInfo.GetBlockIndexFromFolderIndex(folderIndex); + const CResetTable &rt = lzxInfo.ResetTable; + UInt32 numBlocks = (UInt32)rt.GetNumBlocks(unPackSize); + for (UInt32 b = 0; b < numBlocks; b++) + { + UInt64 completedSize = currentTotalSize + chmFolderOutStream->m_PosInSection - startPos; + RINOK(extractCallback->SetCompleted(&completedSize)); + UInt64 bCur = startBlock + b; + if (bCur >= rt.ResetOffsets.Size()) + return E_FAIL; + UInt64 startOffset = rt.ResetOffsets[(int)startBlock]; + UInt64 offset = rt.ResetOffsets[(int)bCur]; + UInt64 compressedSize; + rt.GetCompressedSizeOfBlock(bCur, compressedSize); + UInt64 rem = finishPos - chmFolderOutStream->m_PosInSection; + if (rem > rt.BlockSize) + rem = rt.BlockSize; + // const UInt64 *offsets = (const UInt64 *)&rt.ResetOffsets.Front(); + RINOK(m_Stream->Seek(compressedPos + offset, STREAM_SEEK_SET, NULL)); + streamSpec->SetStream(m_Stream); + streamSpec->Init(compressedSize); + lzxDecoderSpec->SetKeepHistory(b > 0, (int)((offset - startOffset) & 1)); + RINOK(lzxDecoder->Code(inStream, outStream, NULL, &rem, NULL)); + } + } + catch(...) + { + RINOK(chmFolderOutStream->FlushCorrupted()); + } + currentTotalSize += folderSize; + if (folderIndex == lastFolderIndex) + break; + extractStatuses.Clear(); + } + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = m_Database.NewFormat ? 1: + (m_Database.LowLevel ? + m_Database.Items.Size(): + m_Database.Indices.Size()); + return S_OK; +} + +}} diff --git a/CPP/7zip/Archive/Chm/ChmHandler.h b/CPP/7zip/Archive/Chm/ChmHandler.h new file mode 100755 index 00000000..dd0692ba --- /dev/null +++ b/CPP/7zip/Archive/Chm/ChmHandler.h @@ -0,0 +1,46 @@ +// ChmHandler.h + +#ifndef __ARCHIVE_CHM_HANDLER_H +#define __ARCHIVE_CHM_HANDLER_H + +#include "Common/MyCom.h" +#include "../IArchive.h" +#include "ChmIn.h" + +namespace NArchive { +namespace NChm { + +class CHandler: + public IInArchive, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Open)(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback); + STDMETHOD(Close)(); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); + + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + +private: + CFilesDatabase m_Database; + CMyComPtr m_Stream; +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Chm/ChmHeader.cpp b/CPP/7zip/Archive/Chm/ChmHeader.cpp new file mode 100755 index 00000000..4d485b6c --- /dev/null +++ b/CPP/7zip/Archive/Chm/ChmHeader.cpp @@ -0,0 +1,24 @@ +// Archive/Chm/Header.h + +#include "StdAfx.h" + +#include "ChmHeader.h" + +namespace NArchive{ +namespace NChm{ +namespace NHeader{ + +UInt32 kItsfSignature = 0x46535449 + 1; +UInt32 kItolSignature = 0x4C4F5449 + 1; +static class CSignatureInitializer +{ +public: + CSignatureInitializer() + { + kItsfSignature--; + kItolSignature--; + } +}g_SignatureInitializer; + + +}}} diff --git a/CPP/7zip/Archive/Chm/ChmHeader.h b/CPP/7zip/Archive/Chm/ChmHeader.h new file mode 100755 index 00000000..9f1bd42b --- /dev/null +++ b/CPP/7zip/Archive/Chm/ChmHeader.h @@ -0,0 +1,28 @@ +// Archive/Chm/Header.h + +#ifndef __ARCHIVE_CHM_HEADER_H +#define __ARCHIVE_CHM_HEADER_H + +#include "Common/Types.h" + +namespace NArchive { +namespace NChm { +namespace NHeader{ + +const UInt32 kItspSignature = 0x50535449; +const UInt32 kPmglSignature = 0x4C474D50; +const UInt32 kLzxcSignature = 0x43585A4C; + +const UInt32 kIfcmSignature = 0x4D434649; +const UInt32 kAollSignature = 0x4C4C4F41; +const UInt32 kCaolSignature = 0x4C4F4143; + +extern UInt32 kItsfSignature; + +extern UInt32 kItolSignature; +const UInt32 kItlsSignature = 0x534C5449; +UInt64 inline GetHxsSignature() { return ((UInt64)kItlsSignature << 32) | kItolSignature; } + +}}} + +#endif diff --git a/CPP/7zip/Archive/Chm/ChmIn.cpp b/CPP/7zip/Archive/Chm/ChmIn.cpp new file mode 100755 index 00000000..8c56ec91 --- /dev/null +++ b/CPP/7zip/Archive/Chm/ChmIn.cpp @@ -0,0 +1,925 @@ +// Archive/ChmIn.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Common/MyCom.h" +#include "Common/UTFConvert.h" +#include "Common/IntToString.h" +#include "Windows/Defs.h" + +#include "../../Common/LimitedStreams.h" +#include "ChmIn.h" + +namespace NArchive{ +namespace NChm{ + +// define CHM_LOW, if you want to see low level items +// #define CHM_LOW + +static const GUID kChmLzxGuid = + { 0x7FC28940, 0x9D31, 0x11D0, 0x9B, 0x27, 0x00, 0xA0, 0xC9, 0x1E, 0x9C, 0x7C }; +static const GUID kHelp2LzxGuid = + { 0x0A9007C6, 0x4076, 0x11D3, 0x87, 0x89, 0x00, 0x00, 0xF8, 0x10, 0x57, 0x54 }; +static const GUID kDesGuid = + { 0x67F6E4A2, 0x60BF, 0x11D3, 0x85, 0x40, 0x00, 0xC0, 0x4F, 0x58, 0xC3, 0xCF }; + +static bool AreGuidsEqual(REFGUID g1, REFGUID g2) +{ + if (g1.Data1 != g2.Data1 || + g1.Data2 != g2.Data2 || + g1.Data3 != g2.Data3) + return false; + for (int i = 0; i < 8; i++) + if (g1.Data4[i] != g2.Data4[i]) + return false; + return true; +} + +static char GetHex(Byte value) +{ + return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10))); +} + +static void PrintByte(Byte b, AString &s) +{ + s += GetHex(b >> 4); + s += GetHex(b & 0xF); +} + +static void PrintUInt16(UInt16 v, AString &s) +{ + PrintByte((Byte)(v >> 8), s); + PrintByte((Byte)v, s); +} + +static void PrintUInt32(UInt32 v, AString &s) +{ + PrintUInt16((UInt16)(v >> 16), s); + PrintUInt16((UInt16)v, s); +} + +AString CMethodInfo::GetGuidString() const +{ + AString s; + s += '{'; + PrintUInt32(Guid.Data1, s); + s += '-'; + PrintUInt16(Guid.Data2, s); + s += '-'; + PrintUInt16(Guid.Data3, s); + s += '-'; + PrintByte(Guid.Data4[0], s); + PrintByte(Guid.Data4[1], s); + s += '-'; + for (int i = 2; i < 8; i++) + PrintByte(Guid.Data4[i], s); + s += '}'; + return s; +} + +bool CMethodInfo::IsLzx() const +{ + if (AreGuidsEqual(Guid, kChmLzxGuid)) + return true; + return AreGuidsEqual(Guid, kHelp2LzxGuid); +} + +bool CMethodInfo::IsDes() const +{ + return AreGuidsEqual(Guid, kDesGuid); +} + +UString CMethodInfo::GetName() const +{ + UString s; + if (IsLzx()) + { + s = L"LZX:"; + UInt32 numDictBits = LzxInfo.GetNumDictBits(); + wchar_t temp[32]; + ConvertUInt64ToString(numDictBits, temp); + s += temp; + } + else + { + AString s2; + if (IsDes()) + s2 = "DES"; + else + { + s2 = GetGuidString(); + if (ControlData.GetCapacity() > 0) + { + s2 += ":"; + for (size_t i = 0; i < ControlData.GetCapacity(); i++) + PrintByte(ControlData[i], s2); + } + } + ConvertUTF8ToUnicode(s2, s); + } + return s; +} + +bool CSectionInfo::IsLzx() const +{ + if (Methods.Size() != 1) + return false; + return Methods[0].IsLzx(); +} + +UString CSectionInfo::GetMethodName() const +{ + UString s; + if (!IsLzx()) + { + UString temp; + if (ConvertUTF8ToUnicode(Name, temp)) + s += temp; + s += L": "; + } + for (int i = 0; i < Methods.Size(); i++) + { + if (i != 0) + s += L" "; + s += Methods[i].GetName(); + } + return s; +} + +Byte CInArchive::ReadByte() +{ + Byte b; + if (!_inBuffer.ReadByte(b)) + throw 1; + return b; +} + +void CInArchive::Skeep(size_t size) +{ + while (size-- != 0) + ReadByte(); +} + +void CInArchive::ReadBytes(Byte *data, UInt32 size) +{ + for (UInt32 i = 0; i < size; i++) + data[i] = ReadByte(); +} + +UInt16 CInArchive::ReadUInt16() +{ + UInt16 value = 0; + for (int i = 0; i < 2; i++) + value |= ((UInt16)(ReadByte()) << (8 * i)); + return value; +} + +UInt32 CInArchive::ReadUInt32() +{ + UInt32 value = 0; + for (int i = 0; i < 4; i++) + value |= ((UInt32)(ReadByte()) << (8 * i)); + return value; +} + +UInt64 CInArchive::ReadUInt64() +{ + UInt64 value = 0; + for (int i = 0; i < 8; i++) + value |= ((UInt64)(ReadByte()) << (8 * i)); + return value; +} + +UInt64 CInArchive::ReadEncInt() +{ + UInt64 val = 0;; + for (int i = 0; i < 10; i++) + { + Byte b = ReadByte(); + val |= (b & 0x7F); + if (b < 0x80) + return val; + val <<= 7; + } + throw 1; +} + +void CInArchive::ReadGUID(GUID &g) +{ + g.Data1 = ReadUInt32(); + g.Data2 = ReadUInt16(); + g.Data3 = ReadUInt16(); + ReadBytes(g.Data4, 8); +} + +void CInArchive::ReadString(int size, AString &s) +{ + s.Empty(); + while(size-- != 0) + { + char c = (char)ReadByte(); + if (c == 0) + { + Skeep(size); + return; + } + s += c; + } +} + +void CInArchive::ReadUString(int size, UString &s) +{ + s.Empty(); + while(size-- != 0) + { + wchar_t c = ReadUInt16(); + if (c == 0) + { + Skeep(2 * size); + return; + } + s += c; + } +} + +HRESULT CInArchive::ReadChunk(IInStream *inStream, UInt64 pos, UInt64 size) +{ + RINOK(inStream->Seek(pos, STREAM_SEEK_SET, NULL)); + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr limitedStream(streamSpec); + streamSpec->SetStream(inStream); + streamSpec->Init(size); + _inBuffer.SetStream(limitedStream); + _inBuffer.Init(); + return S_OK; +} + +HRESULT CInArchive::ReadDirEntry(CDatabase &database) +{ + CItem item; + UInt64 nameLength = ReadEncInt(); + if (nameLength == 0 || nameLength >= 0x10000000) + return S_FALSE; + ReadString((int)nameLength, item.Name); + item.Section = ReadEncInt(); + item.Offset = ReadEncInt(); + item.Size = ReadEncInt(); + database.Items.Add(item); + return S_OK; +} + +HRESULT CInArchive::OpenChm(IInStream *inStream, CDatabase &database) +{ + UInt32 headerSize = ReadUInt32(); + if (headerSize != 0x60) + return S_FALSE; + UInt32 unknown1 = ReadUInt32(); + if (unknown1 != 0 && unknown1 != 1) // it's 0 in one .sll file + return S_FALSE; + /* UInt32 timeStamp = */ ReadUInt32(); + // Considered as a big-endian DWORD, it appears to contain seconds (MSB) and + // fractional seconds (second byte). + // The third and fourth bytes may contain even more fractional bits. + // The 4 least significant bits in the last byte are constant. + /* UInt32 lang = */ ReadUInt32(); + GUID g; + ReadGUID(g); // {7C01FD10-7BAA-11D0-9E0C-00A0-C922-E6EC} + ReadGUID(g); // {7C01FD11-7BAA-11D0-9E0C-00A0-C922-E6EC} + const int kNumSections = 2; + UInt64 sectionOffsets[kNumSections]; + UInt64 sectionSizes[kNumSections]; + int i; + for (i = 0; i < kNumSections; i++) + { + sectionOffsets[i] = ReadUInt64(); + sectionSizes[i] = ReadUInt64(); + } + // if (chmVersion == 3) + database.ContentOffset = ReadUInt64(); + /* + else + database.ContentOffset = _startPosition + 0x58 + */ + + /* + // Section 0 + ReadChunk(inStream, sectionOffsets[0], sectionSizes[0]); + if (sectionSizes[0] != 0x18) + return S_FALSE; + ReadUInt32(); // unknown: 01FE + ReadUInt32(); // unknown: 0 + UInt64 fileSize = ReadUInt64(); + ReadUInt32(); // unknown: 0 + ReadUInt32(); // unknown: 0 + */ + + // Section 1: The Directory Listing + ReadChunk(inStream, sectionOffsets[1], sectionSizes[1]); + if (ReadUInt32() != NHeader::kItspSignature) + return S_FALSE; + if (ReadUInt32() != 1) // version + return S_FALSE; + /* UInt32 dirHeaderSize = */ ReadUInt32(); + ReadUInt32(); // 0x0A (unknown) + UInt32 dirChunkSize = ReadUInt32(); // $1000 + if (dirChunkSize < 32) + return S_FALSE; + /* UInt32 density = */ ReadUInt32(); // "Density" of quickref section, usually 2. + /* UInt32 depth = */ ReadUInt32(); // Depth of the index tree: 1 there is no index, + // 2 if there is one level of PMGI chunks. + + /* UInt32 chunkNumber = */ ReadUInt32(); // Chunk number of root index chunk, -1 if there is none + // (though at least one file has 0 despite there being no + // index chunk, probably a bug.) + /* UInt32 firstPmglChunkNumber = */ ReadUInt32(); // Chunk number of first PMGL (listing) chunk + /* UInt32 lastPmglChunkNumber = */ ReadUInt32(); // Chunk number of last PMGL (listing) chunk + ReadUInt32(); // -1 (unknown) + UInt32 numDirChunks = ReadUInt32(); // Number of directory chunks (total) + /* UInt32 windowsLangId = */ ReadUInt32(); + ReadGUID(g); // {5D02926A-212E-11D0-9DF9-00A0C922E6EC} + ReadUInt32(); // 0x54 (This is the length again) + ReadUInt32(); // -1 (unknown) + ReadUInt32(); // -1 (unknown) + ReadUInt32(); // -1 (unknown) + + for (UInt32 ci = 0; ci < numDirChunks; ci++) + { + UInt64 chunkPos = _inBuffer.GetProcessedSize(); + if (ReadUInt32() == NHeader::kPmglSignature) + { + // The quickref area is written backwards from the end of the chunk. + // One quickref entry exists for every n entries in the file, where n + // is calculated as 1 + (1 << quickref density). So for density = 2, n = 5. + + UInt32 quickrefLength = ReadUInt32(); // Length of free space and/or quickref area at end of directory chunk + if (quickrefLength > dirChunkSize || quickrefLength < 2) + return S_FALSE; + ReadUInt32(); // Always 0 + ReadUInt32(); // Chunk number of previous listing chunk when reading + // directory in sequence (-1 if this is the first listing chunk) + ReadUInt32(); // Chunk number of next listing chunk when reading + // directory in sequence (-1 if this is the last listing chunk) + int numItems = 0; + for (;;) + { + UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos; + UInt32 offsetLimit = dirChunkSize - quickrefLength; + if (offset > offsetLimit) + return S_FALSE; + if (offset == offsetLimit) + break; + RINOK(ReadDirEntry(database)); + numItems++; + } + Skeep(quickrefLength - 2); + if (ReadUInt16() != numItems) + return S_FALSE; + } + else + Skeep(dirChunkSize - 4); + } + return S_OK; +} + +HRESULT CInArchive::OpenHelp2(IInStream *inStream, CDatabase &database) +{ + if (ReadUInt32() != 1) // version + return S_FALSE; + if (ReadUInt32() != 0x28) // Location of header section table + return S_FALSE; + UInt32 numHeaderSections = ReadUInt32(); + const int kNumHeaderSectionsMax = 5; + if (numHeaderSections != kNumHeaderSectionsMax) + return S_FALSE; + ReadUInt32(); // Length of post-header table + GUID g; + ReadGUID(g); // {0A9007C1-4076-11D3-8789-0000F8105754} + + // header section table + UInt64 sectionOffsets[kNumHeaderSectionsMax]; + UInt64 sectionSizes[kNumHeaderSectionsMax]; + UInt32 i; + for (i = 0; i < numHeaderSections; i++) + { + sectionOffsets[i] = ReadUInt64(); + sectionSizes[i] = ReadUInt64(); + } + + // Post-Header + ReadUInt32(); // 2 + ReadUInt32(); // 0x98: offset to CAOL from beginning of post-header) + // ----- Directory information + ReadUInt64(); // Chunk number of top-level AOLI chunk in directory, or -1 + ReadUInt64(); // Chunk number of first AOLL chunk in directory + ReadUInt64(); // Chunk number of last AOLL chunk in directory + ReadUInt64(); // 0 (unknown) + ReadUInt32(); // $2000 (Directory chunk size of directory) + ReadUInt32(); // Quickref density for main directory, usually 2 + ReadUInt32(); // 0 (unknown) + ReadUInt32(); // Depth of main directory index tree + // 1 there is no index, 2 if there is one level of AOLI chunks. + ReadUInt64(); // 0 (unknown) + UInt64 numDirEntries = ReadUInt64(); // Number of directory entries + // ----- Directory Index Information + ReadUInt64(); // -1 (unknown, probably chunk number of top-level AOLI in directory index) + ReadUInt64(); // Chunk number of first AOLL chunk in directory index + ReadUInt64(); // Chunk number of last AOLL chunk in directory index + ReadUInt64(); // 0 (unknown) + ReadUInt32(); // $200 (Directory chunk size of directory index) + ReadUInt32(); // Quickref density for directory index, usually 2 + ReadUInt32(); // 0 (unknown) + ReadUInt32(); // Depth of directory index index tree. + ReadUInt64(); // Possibly flags -- sometimes 1, sometimes 0. + ReadUInt64(); // Number of directory index entries (same as number of AOLL + // chunks in main directory) + + // (The obvious guess for the following two fields, which recur in a number + // of places, is they are maximum sizes for the directory and directory index. + // However, I have seen no direct evidence that this is the case.) + + ReadUInt32(); // $100000 (Same as field following chunk size in directory) + ReadUInt32(); // $20000 (Same as field following chunk size in directory index) + + ReadUInt64(); // 0 (unknown) + if (ReadUInt32() != NHeader::kCaolSignature) + return S_FALSE; + if (ReadUInt32() != 2) // (Most likely a version number) + return S_FALSE; + UInt32 caolLength = ReadUInt32(); // $50 (Length of the CAOL section, which includes the ITSF section) + if (caolLength >= 0x2C) + { + /* UInt32 c7 = */ ReadUInt16(); // Unknown. Remains the same when identical files are built. + // Does not appear to be a checksum. Many files have + // 'HH' (HTML Help?) here, indicating this may be a compiler ID + // field. But at least one ITOL/ITLS compiler does not set this + // field to a constant value. + ReadUInt16(); // 0 (Unknown. Possibly part of 00A4 field) + ReadUInt32(); // Unknown. Two values have been seen -- $43ED, and 0. + ReadUInt32(); // $2000 (Directory chunk size of directory) + ReadUInt32(); // $200 (Directory chunk size of directory index) + ReadUInt32(); // $100000 (Same as field following chunk size in directory) + ReadUInt32(); // $20000 (Same as field following chunk size in directory index) + ReadUInt32(); // 0 (unknown) + ReadUInt32(); // 0 (Unknown) + if (caolLength == 0x2C) + { + database.ContentOffset = 0; + database.NewFormat = true; + } + else if (caolLength == 0x50) + { + ReadUInt32(); // 0 (Unknown) + if (ReadUInt32() != NHeader::kItsfSignature) + return S_FALSE; + if (ReadUInt32() != 4) // $4 (Version number -- CHM uses 3) + return S_FALSE; + if (ReadUInt32() != 0x20) // $20 (length of ITSF) + return S_FALSE; + UInt32 unknown = ReadUInt32(); + if (unknown != 0 && unknown != 1) // = 0 for some HxW files, 1 in other cases; + return S_FALSE; + database.ContentOffset = _startPosition + ReadUInt64(); + /* UInt32 timeStamp = */ ReadUInt32(); + // A timestamp of some sort. + // Considered as a big-endian DWORD, it appears to contain + // seconds (MSB) and fractional seconds (second byte). + // The third and fourth bytes may contain even more fractional + // bits. The 4 least significant bits in the last byte are constant. + /* UInt32 lang = */ ReadUInt32(); // BE? + } + else + return S_FALSE; + } + + /* + // Section 0 + ReadChunk(inStream, _startPosition + sectionOffsets[0], sectionSizes[0]); + if (sectionSizes[0] != 0x18) + return S_FALSE; + ReadUInt32(); // unknown: 01FE + ReadUInt32(); // unknown: 0 + UInt64 fileSize = ReadUInt64(); + ReadUInt32(); // unknown: 0 + ReadUInt32(); // unknown: 0 + */ + + // Section 1: The Directory Listing + ReadChunk(inStream, _startPosition + sectionOffsets[1], sectionSizes[1]); + if (ReadUInt32() != NHeader::kIfcmSignature) + return S_FALSE; + if (ReadUInt32() != 1) // (probably a version number) + return S_FALSE; + UInt32 dirChunkSize = ReadUInt32(); // $2000 + if (dirChunkSize < 64) + return S_FALSE; + ReadUInt32(); // $100000 (unknown) + ReadUInt32(); // -1 (unknown) + ReadUInt32(); // -1 (unknown) + UInt32 numDirChunks = ReadUInt32(); + ReadUInt32(); // 0 (unknown, probably high word of above) + + for (UInt32 ci = 0; ci < numDirChunks; ci++) + { + UInt64 chunkPos = _inBuffer.GetProcessedSize(); + if (ReadUInt32() == NHeader::kAollSignature) + { + UInt32 quickrefLength = ReadUInt32(); // Length of quickref area at end of directory chunk + if (quickrefLength > dirChunkSize || quickrefLength < 2) + return S_FALSE; + ReadUInt64(); // Directory chunk number + // This must match physical position in file, that is + // the chunk size times the chunk number must be the + // offset from the end of the directory header. + ReadUInt64(); // Chunk number of previous listing chunk when reading + // directory in sequence (-1 if first listing chunk) + ReadUInt64(); // Chunk number of next listing chunk when reading + // directory in sequence (-1 if last listing chunk) + ReadUInt64(); // Number of first listing entry in this chunk + ReadUInt32(); // 1 (unknown -- other values have also been seen here) + ReadUInt32(); // 0 (unknown) + + int numItems = 0; + for (;;) + { + UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos; + UInt32 offsetLimit = dirChunkSize - quickrefLength; + if (offset > offsetLimit) + return S_FALSE; + if (offset == offsetLimit) + break; + if (database.NewFormat) + { + UInt16 nameLength = ReadUInt16(); + if (nameLength == 0) + return S_FALSE; + UString name; + ReadUString((int)nameLength, name); + AString s; + ConvertUnicodeToUTF8(name, s); + Byte b = ReadByte(); + s += ' '; + PrintByte(b, s); + s += ' '; + UInt64 len = ReadEncInt(); + // then number of items ? + // then length ? + // then some data (binary encoding?) + while (len-- != 0) + { + b = ReadByte(); + PrintByte(b, s); + } + database.NewFormatString += s; + database.NewFormatString += "\r\n"; + } + else + { + RINOK(ReadDirEntry(database)); + } + numItems++; + } + Skeep(quickrefLength - 2); + if (ReadUInt16() != numItems) + return S_FALSE; + if (numItems > numDirEntries) + return S_FALSE; + numDirEntries -= numItems; + } + else + Skeep(dirChunkSize - 4); + } + return numDirEntries == 0 ? S_OK : S_FALSE; +} + +HRESULT CInArchive::DecompressStream(IInStream *inStream, const CDatabase &database, const AString &name) +{ + int index = database.FindItem(name); + if (index < 0) + return S_FALSE; + const CItem &item = database.Items[index]; + _chunkSize = item.Size; + return ReadChunk(inStream, database.ContentOffset + item.Offset, item.Size); +} + + +#define DATA_SPACE "::DataSpace/" +static const char *kNameList = DATA_SPACE "NameList"; +static const char *kStorage = DATA_SPACE "Storage/"; +static const char *kContent = "Content"; +static const char *kControlData = "ControlData"; +static const char *kSpanInfo = "SpanInfo"; +static const char *kTransform = "Transform/"; +static const char *kResetTable = "/InstanceData/ResetTable"; +static const char *kTransformList = "List"; + +static AString GetSectionPrefix(const AString &name) +{ + return AString(kStorage) + name + AString("/"); +} + +#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } + +static int CompareFiles(const int *p1, const int *p2, void *param) +{ + const CObjectVector &items = *(const CObjectVector *)param; + const CItem &item1 = items[*p1]; + const CItem &item2 = items[*p2]; + bool isDir1 = item1.IsDirectory(); + bool isDir2 = item2.IsDirectory(); + if (isDir1 && !isDir2) + return -1; + if (isDir2) + { + if (isDir1) + return MyCompare(*p1, *p2); + return 1; + } + RINOZ(MyCompare(item1.Section, item2.Section)); + RINOZ(MyCompare(item1.Offset, item2.Offset)); + RINOZ(MyCompare(item1.Size, item2.Size)); + return MyCompare(*p1, *p2); +} + +void CFilesDatabase::SetIndices() +{ + for (int i = 0; i < Items.Size(); i++) + { + const CItem &item = Items[i]; + if (item.IsUserItem() && item.Name.Length() != 1) + Indices.Add(i); + } +} + +void CFilesDatabase::Sort() +{ + Indices.Sort(CompareFiles, (void *)&Items); +} + +bool CFilesDatabase::Check() +{ + UInt64 maxPos = 0; + UInt64 prevSection = 0; + for(int i = 0; i < Indices.Size(); i++) + { + const CItem &item = Items[Indices[i]]; + if (item.Section == 0 || item.IsDirectory()) + continue; + if (item.Section != prevSection) + { + prevSection = item.Section; + maxPos = 0; + continue; + } + if (item.Offset < maxPos) + return false; + maxPos = item.Offset + item.Size; + if (maxPos < item.Offset) + return false; + } + return true; +} + +HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database) +{ + { + // The NameList file + RINOK(DecompressStream(inStream, database, kNameList)); + /* UInt16 length = */ ReadUInt16(); + UInt16 numSections = ReadUInt16(); + for (int i = 0; i < numSections; i++) + { + CSectionInfo section; + UInt16 nameLength = ReadUInt16(); + UString name; + ReadUString(nameLength, name); + if (ReadUInt16() != 0) + return S_FALSE; + if (!ConvertUnicodeToUTF8(name, section.Name)) + return S_FALSE; + database.Sections.Add(section); + } + } + + int i; + for (i = 1; i < database.Sections.Size(); i++) + { + CSectionInfo §ion = database.Sections[i]; + AString sectionPrefix = GetSectionPrefix(section.Name); + { + // Content + int index = database.FindItem(sectionPrefix + kContent); + if (index < 0) + return S_FALSE; + const CItem &item = database.Items[index]; + section.Offset = item.Offset; + section.CompressedSize = item.Size; + } + AString transformPrefix = sectionPrefix + kTransform; + if (database.Help2Format) + { + // Transform List + RINOK(DecompressStream(inStream, database, transformPrefix + kTransformList)); + if ((_chunkSize & 0xF) != 0) + return S_FALSE; + int numGuids = (int)(_chunkSize / 0x10); + if (numGuids < 1) + return S_FALSE; + for (int i = 0; i < numGuids; i++) + { + CMethodInfo method; + ReadGUID(method.Guid); + section.Methods.Add(method); + } + } + else + { + CMethodInfo method; + method.Guid = kChmLzxGuid; + section.Methods.Add(method); + } + + { + // Control Data + RINOK(DecompressStream(inStream, database, sectionPrefix + kControlData)); + for (int mi = 0; mi < section.Methods.Size(); mi++) + { + CMethodInfo &method = section.Methods[mi]; + UInt32 numDWORDS = ReadUInt32(); + if (method.IsLzx()) + { + if (numDWORDS < 5) + return S_FALSE; + if (ReadUInt32() != NHeader::kLzxcSignature) + return S_FALSE; + CLzxInfo &li = method.LzxInfo; + li.Version = ReadUInt32(); + if (li.Version != 2 && li.Version != 3) + return S_FALSE; + li.ResetInterval = ReadUInt32(); + li.WindowSize = ReadUInt32(); + li.CacheSize = ReadUInt32(); + if (li.ResetInterval != 2 && li.ResetInterval != 4) + return S_FALSE; + if (li.WindowSize != 2 && li.WindowSize != 4) + return S_FALSE; + numDWORDS -= 5; + while (numDWORDS-- != 0) + ReadUInt32(); + } + else + { + UInt32 numBytes = numDWORDS * 4; + method.ControlData.SetCapacity(numBytes); + ReadBytes(method.ControlData, numBytes); + } + } + } + + { + // SpanInfo + RINOK(DecompressStream(inStream, database, sectionPrefix + kSpanInfo)); + section.UncompressedSize = ReadUInt64(); + } + + // read ResetTable for LZX + for (int mi = 0; mi < section.Methods.Size(); mi++) + { + CMethodInfo &method = section.Methods[mi]; + if (method.IsLzx()) + { + // ResetTable; + RINOK(DecompressStream(inStream, database, transformPrefix + + method.GetGuidString() + kResetTable)); + CResetTable &rt = method.LzxInfo.ResetTable; + if (_chunkSize < 4) + { + if (_chunkSize != 0) + return S_FALSE; + // ResetTable is empty in .chw files + if (section.UncompressedSize != 0) + return S_FALSE; + rt.UncompressedSize = 0; + rt.CompressedSize = 0; + rt.BlockSize = 0; + } + else + { + UInt32 ver = ReadUInt32(); // 2 unknown (possibly a version number) + if (ver != 2 && ver != 3) + return S_FALSE; + UInt32 numEntries = ReadUInt32(); + if (ReadUInt32() != 8) // Size of table entry (bytes) + return S_FALSE; + if (ReadUInt32() != 0x28) // Length of table header + return S_FALSE; + rt.UncompressedSize = ReadUInt64(); + rt.CompressedSize = ReadUInt64(); + rt.BlockSize = ReadUInt64(); // 0x8000 block size for locations below + if (rt.BlockSize != 0x8000) + return S_FALSE; + rt.ResetOffsets.Reserve(numEntries); + for (UInt32 i = 0; i < numEntries; i++) + rt.ResetOffsets.Add(ReadUInt64()); + } + } + } + } + + database.SetIndices(); + database.Sort(); + return database.Check() ? S_OK : S_FALSE; +} + +HRESULT CInArchive::Open2(IInStream *inStream, + const UInt64 *searchHeaderSizeLimit, + CFilesDatabase &database) +{ + database.Clear(); + + RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &_startPosition)); + + database.Help2Format = false; + const UInt32 chmVersion = 3; + { + if (!_inBuffer.Create(1 << 14)) + return E_OUTOFMEMORY; + _inBuffer.SetStream(inStream); + _inBuffer.Init(); + UInt64 value = 0; + const int kSignatureSize = 8; + UInt64 hxsSignature = NHeader::GetHxsSignature(); + UInt64 chmSignature = ((UInt64)chmVersion << 32)| NHeader::kItsfSignature; + for (;;) + { + Byte b; + if (!_inBuffer.ReadByte(b)) + return S_FALSE; + value >>= 8; + value |= ((UInt64)b) << ((kSignatureSize - 1) * 8); + if (_inBuffer.GetProcessedSize() >= kSignatureSize) + { + if (value == chmSignature) + break; + if (value == hxsSignature) + { + database.Help2Format = true; + break; + } + if (searchHeaderSizeLimit != NULL) + if (_inBuffer.GetProcessedSize() > (*searchHeaderSizeLimit)) + return S_FALSE; + } + } + _startPosition += _inBuffer.GetProcessedSize() - kSignatureSize; + } + + if (database.Help2Format) + { + RINOK(OpenHelp2(inStream, database)); + if (database.NewFormat) + return S_OK; + } + else + { + RINOK(OpenChm(inStream, database)); + } + + #ifndef CHM_LOW + try + { + HRESULT res = OpenHighLevel(inStream, database); + if (res == S_FALSE) + { + database.HighLevelClear(); + return S_OK; + } + RINOK(res); + database.LowLevel = false; + } + catch(...) + { + return S_OK; + } + #endif + return S_OK; +} + +HRESULT CInArchive::Open(IInStream *inStream, + const UInt64 *searchHeaderSizeLimit, + CFilesDatabase &database) +{ + try + { + HRESULT res = Open2(inStream, searchHeaderSizeLimit, database); + _inBuffer.ReleaseStream(); + return res; + } + catch(...) + { + _inBuffer.ReleaseStream(); + throw; + } +} + +}} diff --git a/CPP/7zip/Archive/Chm/ChmIn.h b/CPP/7zip/Archive/Chm/ChmIn.h new file mode 100755 index 00000000..ebf3c4be --- /dev/null +++ b/CPP/7zip/Archive/Chm/ChmIn.h @@ -0,0 +1,242 @@ +// Archive/ChmIn.h + +#ifndef __ARCHIVE_CHM_IN_H +#define __ARCHIVE_CHM_IN_H + +#include "Common/String.h" +#include "Common/Buffer.h" +#include "../../IStream.h" +#include "../../Common/InBuffer.h" +#include "ChmHeader.h" + +namespace NArchive { +namespace NChm { + +struct CItem +{ + UInt64 Section; + UInt64 Offset; + UInt64 Size; + AString Name; + + bool IsFormatRelatedItem() const + { + if (Name.Length() < 2) + return false; + return Name[0] == ':' && Name[1] == ':'; + } + + bool IsUserItem() const + { + if (Name.Length() < 2) + return false; + return Name[0] == '/'; + } + + bool IsDirectory() const + { + if (Name.Length() == 0) + return false; + return (Name[Name.Length() - 1] == '/'); + } +}; + +struct CDatabase +{ + UInt64 ContentOffset; + CObjectVector Items; + AString NewFormatString; + bool Help2Format; + bool NewFormat; + + int FindItem(const AString &name) const + { + for (int i = 0; i < Items.Size(); i++) + if (Items[i].Name == name) + return i; + return -1; + } + + void Clear() + { + NewFormat = false; + NewFormatString.Empty(); + Help2Format = false; + Items.Clear(); + } +}; + +struct CResetTable +{ + UInt64 UncompressedSize; + UInt64 CompressedSize; + UInt64 BlockSize; + CRecordVector ResetOffsets; + bool GetCompressedSizeOfBlocks(UInt64 blockIndex, UInt32 numBlocks, UInt64 &size) const + { + if (blockIndex >= ResetOffsets.Size()) + return false; + UInt64 startPos = ResetOffsets[(int)blockIndex]; + if (blockIndex + numBlocks >= ResetOffsets.Size()) + size = CompressedSize - startPos; + else + size = ResetOffsets[(int)(blockIndex + numBlocks)] - startPos; + return true; + } + bool GetCompressedSizeOfBlock(UInt64 blockIndex, UInt64 &size) const + { + return GetCompressedSizeOfBlocks(blockIndex, 1, size); + } + UInt64 GetNumBlocks(UInt64 size) const + { + return (size + BlockSize - 1) / BlockSize; + } +}; + +struct CLzxInfo +{ + UInt32 Version; + UInt32 ResetInterval; + UInt32 WindowSize; + UInt32 CacheSize; + CResetTable ResetTable; + + UInt32 GetNumDictBits() const + { + if (Version == 2 || Version == 3) + { + for (int i = 0; i <= 31; i++) + if (((UInt32)1 << i) >= WindowSize) + return 15 + i; + } + return 0; + } + + UInt64 GetFolderSize() const { return ResetTable.BlockSize * ResetInterval; }; + UInt64 GetFolder(UInt64 offset) const { return offset / GetFolderSize(); }; + UInt64 GetFolderPos(UInt64 folderIndex) const { return folderIndex * GetFolderSize(); }; + UInt64 GetBlockIndexFromFolderIndex(UInt64 folderIndex) const { return folderIndex * ResetInterval; }; + bool GetOffsetOfFolder(UInt64 folderIndex, UInt64 &offset) const + { + UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex); + if (blockIndex >= ResetTable.ResetOffsets.Size()) + return false; + offset = ResetTable.ResetOffsets[(int)blockIndex]; + return true; + } + bool GetCompressedSizeOfFolder(UInt64 folderIndex, UInt64 &size) const + { + UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex); + return ResetTable.GetCompressedSizeOfBlocks(blockIndex, ResetInterval, size); + } +}; + +struct CMethodInfo +{ + GUID Guid; + CByteBuffer ControlData; + CLzxInfo LzxInfo; + bool IsLzx() const; + bool IsDes() const; + AString GetGuidString() const; + UString GetName() const; +}; + +struct CSectionInfo +{ + UInt64 Offset; + UInt64 CompressedSize; + UInt64 UncompressedSize; + + AString Name; + CObjectVector Methods; + + bool IsLzx() const; + UString GetMethodName() const; +}; + +class CFilesDatabase: public CDatabase +{ +public: + bool LowLevel; + CRecordVector Indices; + CObjectVector Sections; + + UInt64 GetFileSize(int fileIndex) const { return Items[Indices[fileIndex]].Size; } + UInt64 GetFileOffset(int fileIndex) const { return Items[Indices[fileIndex]].Offset; } + + UInt64 GetFolder(int fileIndex) const + { + const CItem &item = Items[Indices[fileIndex]]; + const CSectionInfo §ion = Sections[(int)item.Section]; + if (section.IsLzx()) + return section.Methods[0].LzxInfo.GetFolder(item.Offset); + return 0; + } + + UInt64 GetLastFolder(int fileIndex) const + { + const CItem &item = Items[Indices[fileIndex]]; + const CSectionInfo §ion = Sections[(int)item.Section]; + if (section.IsLzx()) + return section.Methods[0].LzxInfo.GetFolder(item.Offset + item.Size - 1); + return 0; + } + + void HighLevelClear() + { + LowLevel = true; + Indices.Clear(); + Sections.Clear(); + } + + void Clear() + { + CDatabase::Clear(); + HighLevelClear(); + } + void SetIndices(); + void Sort(); + bool Check(); +}; + +class CProgressVirt +{ +public: + STDMETHOD(SetTotal)(const UInt64 *numFiles) PURE; + STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE; +}; + +class CInArchive +{ + UInt64 _startPosition; + ::CInBuffer _inBuffer; + UInt64 _chunkSize; + + Byte ReadByte(); + void ReadBytes(Byte *data, UInt32 size); + void Skeep(size_t size); + UInt16 ReadUInt16(); + UInt32 ReadUInt32(); + UInt64 ReadUInt64(); + UInt64 ReadEncInt(); + void ReadString(int size, AString &s); + void ReadUString(int size, UString &s); + void ReadGUID(GUID &g); + + HRESULT ReadChunk(IInStream *inStream, UInt64 pos, UInt64 size); + + HRESULT ReadDirEntry(CDatabase &database); + HRESULT DecompressStream(IInStream *inStream, const CDatabase &database, const AString &name); + +public: + HRESULT OpenChm(IInStream *inStream, CDatabase &database); + HRESULT OpenHelp2(IInStream *inStream, CDatabase &database); + HRESULT OpenHighLevel(IInStream *inStream, CFilesDatabase &database); + HRESULT Open2(IInStream *inStream, const UInt64 *searchHeaderSizeLimit, CFilesDatabase &database); + HRESULT Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit, CFilesDatabase &database); +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Chm/DllExports.cpp b/CPP/7zip/Archive/Chm/DllExports.cpp new file mode 100755 index 00000000..ad822094 --- /dev/null +++ b/CPP/7zip/Archive/Chm/DllExports.cpp @@ -0,0 +1,77 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "Windows/PropVariant.h" +#include "ChmHandler.h" +#include "../../ICoder.h" + +// {23170F69-40C1-278A-1000-000110E90000} +DEFINE_GUID(CLSID_CChmHandler, + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xE9, 0x00, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /*lpReserved*/) +{ + return TRUE; +} + +STDAPI CreateObject( + const GUID *classID, + const GUID *interfaceID, + void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + if (*classID != CLSID_CChmHandler) + return CLASS_E_CLASSNOTAVAILABLE; + if (*interfaceID != IID_IInArchive) + return E_NOINTERFACE; + CMyComPtr inArchive = (IInArchive *)new NArchive::NChm::CHandler; + *outObject = inArchive.Detach(); + COM_TRY_END + return S_OK; +} + +STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case NArchive::kName: + propVariant = L"Chm"; + break; + case NArchive::kClassID: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CChmHandler, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NArchive::kExtension: + propVariant = L"chm chi chq chw hxs hxi hxr hxq hxw lit"; + break; + case NArchive::kUpdate: + propVariant = false; + break; + case NArchive::kKeepName: + propVariant = false; + break; + case NArchive::kStartSignature: + { + const char sig[] = { 'I', 'T', 'S', 'F' }; + if ((value->bstrVal = ::SysAllocStringByteLen(sig, 4)) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NArchive::kAssociate: + { + propVariant = false; + break; + } + } + propVariant.Detach(value); + return S_OK; +} diff --git a/CPP/7zip/Archive/Chm/StdAfx.cpp b/CPP/7zip/Archive/Chm/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Archive/Chm/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Chm/StdAfx.h b/CPP/7zip/Archive/Chm/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Archive/Chm/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Archive/Chm/makefile b/CPP/7zip/Archive/Chm/makefile new file mode 100755 index 00000000..4adce2f5 --- /dev/null +++ b/CPP/7zip/Archive/Chm/makefile @@ -0,0 +1,68 @@ +PROG = chm.dll +DEF_FILE = ../Archive.def +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib user32.lib + +CHM_OBJS = \ + $O\DllExports.obj \ + $O\ChmHandler.obj \ + $O\ChmHeader.obj \ + $O\ChmIn.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\UTFConvert.obj \ + $O\Vector.obj \ + +WIN_OBJS = \ + $O\PropVariant.obj \ + +7ZIP_COMMON_OBJS = \ + $O\InBuffer.obj \ + $O\LimitedStreams.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ + +AR_COMMON_OBJS = \ + $O\ItemNameUtils.obj \ + +COMPRESS_LZX_OBJS = \ + $O\LzxDecoder.obj \ + $O\Lzx86Converter.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(CHM_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $(COMPRESS_LZX_OBJS) \ + $O\LZOutWindow.obj \ + $O\CopyCoder.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(CHM_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$(COMPRESS_LZX_OBJS): ../../Compress/Lzx/$(*B).cpp + $(COMPL_O2) +$O\LZOutWindow.obj: ../../Compress/LZ/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) + diff --git a/CPP/7zip/Archive/Chm/resource.rc b/CPP/7zip/Archive/Chm/resource.rc new file mode 100755 index 00000000..fc93ae4f --- /dev/null +++ b/CPP/7zip/Archive/Chm/resource.rc @@ -0,0 +1,3 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("Chm Plugin", "chm") diff --git a/CPP/7zip/Archive/Common/CodecsPath.cpp b/CPP/7zip/Archive/Common/CodecsPath.cpp new file mode 100755 index 00000000..7ee89875 --- /dev/null +++ b/CPP/7zip/Archive/Common/CodecsPath.cpp @@ -0,0 +1,34 @@ +// CodecsPath.cpp + +#include "StdAfx.h" +#include "../../../Common/String.h" + +extern HINSTANCE g_hInstance; + +static CSysString GetLibraryPath() +{ + TCHAR fullPath[MAX_PATH + 1]; + ::GetModuleFileName(g_hInstance, fullPath, MAX_PATH); + return fullPath; +} + +static CSysString GetLibraryFolderPrefix() +{ + CSysString path = GetLibraryPath(); + int pos = path.ReverseFind(TEXT(CHAR_PATH_SEPARATOR)); + return path.Left(pos + 1); +} + +CSysString GetBaseFolderPrefix() +{ + CSysString libPrefix = GetLibraryFolderPrefix(); + CSysString temp = libPrefix; + temp.Delete(temp.Length() - 1); + int pos = temp.ReverseFind(TEXT(CHAR_PATH_SEPARATOR)); + return temp.Left(pos + 1); +} + +CSysString GetCodecsFolderPrefix() +{ + return GetBaseFolderPrefix() + (CSysString)(TEXT("Codecs")) + (CSysString)(TEXT(STRING_PATH_SEPARATOR)); +} diff --git a/CPP/7zip/Archive/Common/CodecsPath.h b/CPP/7zip/Archive/Common/CodecsPath.h new file mode 100755 index 00000000..11145a03 --- /dev/null +++ b/CPP/7zip/Archive/Common/CodecsPath.h @@ -0,0 +1,12 @@ +// CodecsPath.h + +#ifndef __CODECSPATH_H +#define __CODECSPATH_H + +#include "../../../Common/String.h" + +CSysString GetBaseFolderPrefix(); +CSysString GetCodecsFolderPrefix(); + +#endif + diff --git a/CPP/7zip/Archive/Common/CoderLoader.cpp b/CPP/7zip/Archive/Common/CoderLoader.cpp new file mode 100755 index 00000000..bf54f6e0 --- /dev/null +++ b/CPP/7zip/Archive/Common/CoderLoader.cpp @@ -0,0 +1,31 @@ +// CoderLoader.cpp + +#include "StdAfx.h" + +#include "CoderLoader.h" +#include "FilterCoder.h" + +HRESULT CCoderLibrary::CreateCoderSpec(REFGUID clsID, ICompressCoder **coder) +{ + HRESULT result = CreateObject(clsID, IID_ICompressCoder, (void **)coder); + if (result == S_OK || result != E_NOINTERFACE) + return result; + CMyComPtr filter; + RINOK(CreateObject(clsID, IID_ICompressFilter, (void **)&filter)); + CFilterCoder *filterCoderSpec = new CFilterCoder; + CMyComPtr filterCoder = filterCoderSpec; + filterCoderSpec->Filter = filter; + *coder = filterCoder.Detach(); + return S_OK; +} + + +HRESULT CCoderLibrary::LoadAndCreateCoderSpec(LPCTSTR filePath, REFGUID clsID, ICompressCoder **coder) +{ + CCoderLibrary libTemp; + if (!libTemp.Load(filePath)) + return GetLastError(); + RINOK(libTemp.CreateCoderSpec(clsID, coder)); + Attach(libTemp.Detach()); + return S_OK; +} diff --git a/CPP/7zip/Archive/Common/CoderLoader.h b/CPP/7zip/Archive/Common/CoderLoader.h new file mode 100755 index 00000000..02322d8c --- /dev/null +++ b/CPP/7zip/Archive/Common/CoderLoader.h @@ -0,0 +1,147 @@ +// CoderLoader.h + +#ifndef __CODERLOADER_H +#define __CODERLOADER_H + +#include "../../../Common/String.h" +#include "../../../Common/MyCom.h" +#include "../../../Windows/DLL.h" +#include "../../ICoder.h" + +typedef UInt32 (WINAPI * CreateObjectPointer)( + const GUID *clsID, + const GUID *interfaceID, + void **outObject); + +class CCoderLibrary: public NWindows::NDLL::CLibrary +{ +public: + HRESULT CreateObject(REFGUID clsID, REFGUID iid, void **obj) + { + CreateObjectPointer createObject = (CreateObjectPointer) + GetProcAddress("CreateObject"); + if (createObject == NULL) + return GetLastError(); + return createObject(&clsID, &iid, obj); + } + + HRESULT CreateFilter(REFGUID clsID, ICompressFilter **filter) + { + return CreateObject(clsID, IID_ICompressFilter, (void **)filter); + } + + HRESULT CreateCoder(REFGUID clsID, ICompressCoder **coder) + { + return CreateObject(clsID, IID_ICompressCoder, (void **)coder); + } + + HRESULT CreateCoderSpec(REFGUID clsID, ICompressCoder **coder); + + HRESULT LoadAndCreateFilter(LPCTSTR filePath, REFGUID clsID, ICompressFilter **filter) + { + CCoderLibrary libTemp; + if (!libTemp.Load(filePath)) + return GetLastError(); + RINOK(libTemp.CreateFilter(clsID, filter)); + Attach(libTemp.Detach()); + return S_OK; + } + + + HRESULT LoadAndCreateCoder(LPCTSTR filePath, REFGUID clsID, ICompressCoder **coder) + { + CCoderLibrary libTemp; + if (!libTemp.Load(filePath)) + return GetLastError(); + RINOK(libTemp.CreateCoder(clsID, coder)); + Attach(libTemp.Detach()); + return S_OK; + } + + HRESULT LoadAndCreateCoderSpec(LPCTSTR filePath, REFGUID clsID, ICompressCoder **coder); + HRESULT CreateCoder2(REFGUID clsID, ICompressCoder2 **coder) + { + CreateObjectPointer createObject = (CreateObjectPointer) + GetProcAddress("CreateObject"); + if (createObject == NULL) + return GetLastError(); + return createObject(&clsID, &IID_ICompressCoder2, (void **)coder); + } + HRESULT LoadAndCreateCoder2(LPCTSTR filePath, REFGUID clsID, ICompressCoder2 **coder) + { + CCoderLibrary libTemp; + if (!libTemp.Load(filePath)) + return GetLastError(); + RINOK(libTemp.CreateCoder2(clsID, coder)); + Attach(libTemp.Detach()); + return S_OK; + } +}; + + +class CCoderLibraries +{ + struct CPathToLibraryPair + { + CSysString Path; + CCoderLibrary Libary; + }; + CObjectVector Pairs; +public: + int FindPath(LPCTSTR filePath) + { + for (int i = 0; i < Pairs.Size(); i++) + if (Pairs[i].Path.CompareNoCase(filePath) == 0) + return i; + return -1; + } + + HRESULT CreateCoder(LPCTSTR filePath, REFGUID clsID, ICompressCoder **coder) + { + int index = FindPath(filePath); + if (index < 0) + { + CPathToLibraryPair pair; + RINOK(pair.Libary.LoadAndCreateCoder(filePath, clsID, coder)); + pair.Path = filePath; + Pairs.Add(pair); + pair.Libary.Detach(); + return S_OK; + } + return Pairs[index].Libary.CreateCoder(clsID, coder); + } + + HRESULT CreateCoderSpec(LPCTSTR filePath, REFGUID clsID, ICompressCoder **coder) + { + int index = FindPath(filePath); + if (index < 0) + { + CPathToLibraryPair pair; + RINOK(pair.Libary.LoadAndCreateCoderSpec(filePath, clsID, coder)); + pair.Path = filePath; + Pairs.Add(pair); + pair.Libary.Detach(); + return S_OK; + } + return Pairs[index].Libary.CreateCoderSpec(clsID, coder); + } + + HRESULT CreateCoder2(LPCTSTR filePath, REFGUID clsID, ICompressCoder2 **coder) + { + int index = FindPath(filePath); + if (index < 0) + { + CPathToLibraryPair pair; + RINOK(pair.Libary.LoadAndCreateCoder2(filePath, clsID, coder)); + pair.Path = filePath; + Pairs.Add(pair); + pair.Libary.Detach(); + return S_OK; + } + return Pairs[index].Libary.CreateCoder2(clsID, coder); + } +}; + + +#endif + diff --git a/CPP/7zip/Archive/Common/CoderMixer2.cpp b/CPP/7zip/Archive/Common/CoderMixer2.cpp new file mode 100755 index 00000000..8f46e985 --- /dev/null +++ b/CPP/7zip/Archive/Common/CoderMixer2.cpp @@ -0,0 +1,121 @@ +// CoderMixer2.cpp + +#include "StdAfx.h" + +#include "CoderMixer2.h" + +namespace NCoderMixer2 { + +CBindReverseConverter::CBindReverseConverter(const CBindInfo &srcBindInfo): + _srcBindInfo(srcBindInfo) +{ + srcBindInfo.GetNumStreams(NumSrcInStreams, _numSrcOutStreams); + + UInt32 j; + for (j = 0; j < NumSrcInStreams; j++) + { + _srcInToDestOutMap.Add(0); + DestOutToSrcInMap.Add(0); + } + for (j = 0; j < _numSrcOutStreams; j++) + { + _srcOutToDestInMap.Add(0); + _destInToSrcOutMap.Add(0); + } + + UInt32 destInOffset = 0; + UInt32 destOutOffset = 0; + UInt32 srcInOffset = NumSrcInStreams; + UInt32 srcOutOffset = _numSrcOutStreams; + + for (int i = srcBindInfo.Coders.Size() - 1; i >= 0; i--) + { + const CCoderStreamsInfo &srcCoderInfo = srcBindInfo.Coders[i]; + + srcInOffset -= srcCoderInfo.NumInStreams; + srcOutOffset -= srcCoderInfo.NumOutStreams; + + UInt32 j; + for (j = 0; j < srcCoderInfo.NumInStreams; j++, destOutOffset++) + { + UInt32 index = srcInOffset + j; + _srcInToDestOutMap[index] = destOutOffset; + DestOutToSrcInMap[destOutOffset] = index; + } + for (j = 0; j < srcCoderInfo.NumOutStreams; j++, destInOffset++) + { + UInt32 index = srcOutOffset + j; + _srcOutToDestInMap[index] = destInOffset; + _destInToSrcOutMap[destInOffset] = index; + } + } +} + +void CBindReverseConverter::CreateReverseBindInfo(CBindInfo &destBindInfo) +{ + destBindInfo.Coders.Clear(); + destBindInfo.BindPairs.Clear(); + destBindInfo.InStreams.Clear(); + destBindInfo.OutStreams.Clear(); + + int i; + for (i = _srcBindInfo.Coders.Size() - 1; i >= 0; i--) + { + const CCoderStreamsInfo &srcCoderInfo = _srcBindInfo.Coders[i]; + CCoderStreamsInfo destCoderInfo; + destCoderInfo.NumInStreams = srcCoderInfo.NumOutStreams; + destCoderInfo.NumOutStreams = srcCoderInfo.NumInStreams; + destBindInfo.Coders.Add(destCoderInfo); + } + for (i = _srcBindInfo.BindPairs.Size() - 1; i >= 0; i--) + { + const CBindPair &srcBindPair = _srcBindInfo.BindPairs[i]; + CBindPair destBindPair; + destBindPair.InIndex = _srcOutToDestInMap[srcBindPair.OutIndex]; + destBindPair.OutIndex = _srcInToDestOutMap[srcBindPair.InIndex]; + destBindInfo.BindPairs.Add(destBindPair); + } + for (i = 0; i < _srcBindInfo.InStreams.Size(); i++) + destBindInfo.OutStreams.Add(_srcInToDestOutMap[_srcBindInfo.InStreams[i]]); + for (i = 0; i < _srcBindInfo.OutStreams.Size(); i++) + destBindInfo.InStreams.Add(_srcOutToDestInMap[_srcBindInfo.OutStreams[i]]); +} + +CCoderInfo::CCoderInfo(UInt32 numInStreams, UInt32 numOutStreams): + NumInStreams(numInStreams), + NumOutStreams(numOutStreams) +{ + InSizes.Reserve(NumInStreams); + InSizePointers.Reserve(NumInStreams); + OutSizePointers.Reserve(NumOutStreams); + OutSizePointers.Reserve(NumOutStreams); +} + +static void SetSizes(const UInt64 **srcSizes, CRecordVector &sizes, + CRecordVector &sizePointers, UInt32 numItems) +{ + sizes.Clear(); + sizePointers.Clear(); + for(UInt32 i = 0; i < numItems; i++) + { + if (srcSizes == 0 || srcSizes[i] == NULL) + { + sizes.Add(0); + sizePointers.Add(NULL); + } + else + { + sizes.Add(*srcSizes[i]); + sizePointers.Add(&sizes.Back()); + } + } +} + +void CCoderInfo::SetCoderInfo(const UInt64 **inSizes, + const UInt64 **outSizes) +{ + SetSizes(inSizes, InSizes, InSizePointers, NumInStreams); + SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams); +} + +} diff --git a/CPP/7zip/Archive/Common/CoderMixer2.h b/CPP/7zip/Archive/Common/CoderMixer2.h new file mode 100755 index 00000000..78a3f280 --- /dev/null +++ b/CPP/7zip/Archive/Common/CoderMixer2.h @@ -0,0 +1,168 @@ +// CoderMixer2.h + +#ifndef __CODER_MIXER2_H +#define __CODER_MIXER2_H + +#include "../../../Common/Vector.h" +#include "../../../Common/Types.h" +#include "../../../Common/MyCom.h" +#include "../../ICoder.h" + +namespace NCoderMixer2 { + +struct CBindPair +{ + UInt32 InIndex; + UInt32 OutIndex; +}; + +struct CCoderStreamsInfo +{ + UInt32 NumInStreams; + UInt32 NumOutStreams; +}; + +struct CBindInfo +{ + CRecordVector Coders; + CRecordVector BindPairs; + CRecordVector InStreams; + CRecordVector OutStreams; + + void Clear() + { + Coders.Clear(); + BindPairs.Clear(); + InStreams.Clear(); + OutStreams.Clear(); + } + + /* + UInt32 GetCoderStartOutStream(UInt32 coderIndex) const + { + UInt32 numOutStreams = 0; + for (UInt32 i = 0; i < coderIndex; i++) + numOutStreams += Coders[i].NumOutStreams; + return numOutStreams; + } + */ + + + void GetNumStreams(UInt32 &numInStreams, UInt32 &numOutStreams) const + { + numInStreams = 0; + numOutStreams = 0; + for (int i = 0; i < Coders.Size(); i++) + { + const CCoderStreamsInfo &coderStreamsInfo = Coders[i]; + numInStreams += coderStreamsInfo.NumInStreams; + numOutStreams += coderStreamsInfo.NumOutStreams; + } + } + + int FindBinderForInStream(UInt32 inStream) const + { + for (int i = 0; i < BindPairs.Size(); i++) + if (BindPairs[i].InIndex == inStream) + return i; + return -1; + } + int FindBinderForOutStream(UInt32 outStream) const + { + for (int i = 0; i < BindPairs.Size(); i++) + if (BindPairs[i].OutIndex == outStream) + return i; + return -1; + } + + UInt32 GetCoderInStreamIndex(UInt32 coderIndex) const + { + UInt32 streamIndex = 0; + for (UInt32 i = 0; i < coderIndex; i++) + streamIndex += Coders[i].NumInStreams; + return streamIndex; + } + + UInt32 GetCoderOutStreamIndex(UInt32 coderIndex) const + { + UInt32 streamIndex = 0; + for (UInt32 i = 0; i < coderIndex; i++) + streamIndex += Coders[i].NumOutStreams; + return streamIndex; + } + + + void FindInStream(UInt32 streamIndex, UInt32 &coderIndex, + UInt32 &coderStreamIndex) const + { + for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++) + { + UInt32 curSize = Coders[coderIndex].NumInStreams; + if (streamIndex < curSize) + { + coderStreamIndex = streamIndex; + return; + } + streamIndex -= curSize; + } + throw 1; + } + void FindOutStream(UInt32 streamIndex, UInt32 &coderIndex, + UInt32 &coderStreamIndex) const + { + for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++) + { + UInt32 curSize = Coders[coderIndex].NumOutStreams; + if (streamIndex < curSize) + { + coderStreamIndex = streamIndex; + return; + } + streamIndex -= curSize; + } + throw 1; + } +}; + +class CBindReverseConverter +{ + UInt32 _numSrcOutStreams; + NCoderMixer2::CBindInfo _srcBindInfo; + CRecordVector _srcInToDestOutMap; + CRecordVector _srcOutToDestInMap; + CRecordVector _destInToSrcOutMap; +public: + UInt32 NumSrcInStreams; + CRecordVector DestOutToSrcInMap; + + CBindReverseConverter(const NCoderMixer2::CBindInfo &srcBindInfo); + void CreateReverseBindInfo(NCoderMixer2::CBindInfo &destBindInfo); +}; + +struct CCoderInfo +{ + CMyComPtr Coder; + CMyComPtr Coder2; + UInt32 NumInStreams; + UInt32 NumOutStreams; + + CRecordVector InSizes; + CRecordVector OutSizes; + CRecordVector InSizePointers; + CRecordVector OutSizePointers; + + CCoderInfo(UInt32 numInStreams, UInt32 numOutStreams); + void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes); +}; + +class CCoderMixer2 +{ +public: + virtual void SetBindInfo(const CBindInfo &bindInfo) = 0; + virtual void ReInit() = 0; + virtual void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes) = 0; +}; + +} +#endif + diff --git a/CPP/7zip/Archive/Common/CoderMixer2MT.cpp b/CPP/7zip/Archive/Common/CoderMixer2MT.cpp new file mode 100755 index 00000000..9d7944b1 --- /dev/null +++ b/CPP/7zip/Archive/Common/CoderMixer2MT.cpp @@ -0,0 +1,359 @@ +// CoderMixer2MT.cpp + +#include "StdAfx.h" + +#include "CoderMixer2MT.h" +#include "CrossThreadProgress.h" + +using namespace NWindows; +using namespace NSynchronization; + +namespace NCoderMixer2 { + +CThreadCoderInfo::CThreadCoderInfo(UInt32 numInStreams, UInt32 numOutStreams): + ExitEvent(NULL), + CompressEvent(NULL), + CompressionCompletedEvent(NULL), + CCoderInfo(numInStreams, numOutStreams) +{ + InStreams.Reserve(NumInStreams); + InStreamPointers.Reserve(NumInStreams); + OutStreams.Reserve(NumOutStreams); + OutStreamPointers.Reserve(NumOutStreams); +} + +void CThreadCoderInfo::CreateEvents() +{ + CompressEvent = new CAutoResetEvent(false); + CompressionCompletedEvent = new CAutoResetEvent(false); +} + +CThreadCoderInfo::~CThreadCoderInfo() +{ + if (CompressEvent != NULL) + delete CompressEvent; + if (CompressionCompletedEvent != NULL) + delete CompressionCompletedEvent; +} + +class CCoderInfoFlusher2 +{ + CThreadCoderInfo *m_CoderInfo; +public: + CCoderInfoFlusher2(CThreadCoderInfo *coderInfo): m_CoderInfo(coderInfo) {} + ~CCoderInfoFlusher2() + { + int i; + for (i = 0; i < m_CoderInfo->InStreams.Size(); i++) + m_CoderInfo->InStreams[i].Release(); + for (i = 0; i < m_CoderInfo->OutStreams.Size(); i++) + m_CoderInfo->OutStreams[i].Release(); + m_CoderInfo->CompressionCompletedEvent->Set(); + } +}; + +bool CThreadCoderInfo::WaitAndCode() +{ + HANDLE events[2] = { ExitEvent, *CompressEvent }; + DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); + if (waitResult == WAIT_OBJECT_0 + 0) + return false; + + { + InStreamPointers.Clear(); + OutStreamPointers.Clear(); + UInt32 i; + for (i = 0; i < NumInStreams; i++) + { + if (InSizePointers[i] != NULL) + InSizePointers[i] = &InSizes[i]; + InStreamPointers.Add(InStreams[i]); + } + for (i = 0; i < NumOutStreams; i++) + { + if (OutSizePointers[i] != NULL) + OutSizePointers[i] = &OutSizes[i]; + OutStreamPointers.Add(OutStreams[i]); + } + CCoderInfoFlusher2 coderInfoFlusher(this); + if (Coder) + Result = Coder->Code(InStreamPointers[0], + OutStreamPointers[0], + InSizePointers[0], + OutSizePointers[0], + Progress); + else + Result = Coder2->Code(&InStreamPointers.Front(), + &InSizePointers.Front(), + NumInStreams, + &OutStreamPointers.Front(), + &OutSizePointers.Front(), + NumOutStreams, + Progress); + } + return true; +} + +static void SetSizes(const UInt64 **srcSizes, CRecordVector &sizes, + CRecordVector &sizePointers, UInt32 numItems) +{ + sizes.Clear(); + sizePointers.Clear(); + for(UInt32 i = 0; i < numItems; i++) + { + if (srcSizes == 0 || srcSizes[i] == NULL) + { + sizes.Add(0); + sizePointers.Add(NULL); + } + else + { + sizes.Add(*srcSizes[i]); + sizePointers.Add(&sizes.Back()); + } + } +} + + +void CThreadCoderInfo::SetCoderInfo(const UInt64 **inSizes, + const UInt64 **outSizes, ICompressProgressInfo *progress) +{ + Progress = progress; + SetSizes(inSizes, InSizes, InSizePointers, NumInStreams); + SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams); +} + +static DWORD WINAPI CoderThread(void *threadCoderInfo) +{ + for (;;) + { + if (!((CThreadCoderInfo *)threadCoderInfo)->WaitAndCode()) + return 0; + } +} + +////////////////////////////////////// +// CCoderMixer2MT + +static DWORD WINAPI MainCoderThread(void *threadCoderInfo) +{ + for (;;) + { + if (!((CCoderMixer2MT *)threadCoderInfo)->MyCode()) + return 0; + } +} + +CCoderMixer2MT::CCoderMixer2MT() +{ + if (!_mainThread.Create(MainCoderThread, this)) + throw 271825; +} + +CCoderMixer2MT::~CCoderMixer2MT() +{ + _exitEvent.Set(); + _mainThread.Wait(); + for(int i = 0; i < _threads.Size(); i++) + { + _threads[i].Wait(); + _threads[i].Close(); + } +} + +void CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo) +{ + _bindInfo = bindInfo; + _streamBinders.Clear(); + for(int i = 0; i < _bindInfo.BindPairs.Size(); i++) + { + _streamBinders.Add(CStreamBinder()); + _streamBinders.Back().CreateEvents(); + } +} + +void CCoderMixer2MT::AddCoderCommon() +{ + int index = _coderInfoVector.Size(); + const CCoderStreamsInfo &CoderStreamsInfo = _bindInfo.Coders[index]; + + CThreadCoderInfo threadCoderInfo(CoderStreamsInfo.NumInStreams, + CoderStreamsInfo.NumOutStreams); + _coderInfoVector.Add(threadCoderInfo); + _coderInfoVector.Back().CreateEvents(); + _coderInfoVector.Back().ExitEvent = _exitEvent; + _compressingCompletedEvents.Add(*_coderInfoVector.Back().CompressionCompletedEvent); + + NWindows::CThread newThread; + _threads.Add(newThread); + if (!_threads.Back().Create(CoderThread, &_coderInfoVector.Back())) + throw 271824; +} + +void CCoderMixer2MT::AddCoder(ICompressCoder *coder) +{ + AddCoderCommon(); + _coderInfoVector.Back().Coder = coder; +} + +void CCoderMixer2MT::AddCoder2(ICompressCoder2 *coder) +{ + AddCoderCommon(); + _coderInfoVector.Back().Coder2 = coder; +} + +/* +void CCoderMixer2MT::FinishAddingCoders() +{ + for(int i = 0; i < _coderInfoVector.Size(); i++) + { + DWORD id; + HANDLE newThread = ::CreateThread(NULL, 0, CoderThread, + &_coderInfoVector[i], 0, &id); + if (newThread == 0) + throw 271824; + _threads.Add(newThread); + } +} +*/ + +void CCoderMixer2MT::ReInit() +{ + for(int i = 0; i < _streamBinders.Size(); i++) + _streamBinders[i].ReInit(); +} + + +STDMETHODIMP CCoderMixer2MT::Init(ISequentialInStream **inStreams, + ISequentialOutStream **outStreams) +{ + if (_coderInfoVector.Size() != _bindInfo.Coders.Size()) + throw 0; + int i; + for(i = 0; i < _coderInfoVector.Size(); i++) + { + CThreadCoderInfo &coderInfo = _coderInfoVector[i]; + const CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[i]; + coderInfo.InStreams.Clear(); + UInt32 j; + for(j = 0; j < coderStreamsInfo.NumInStreams; j++) + coderInfo.InStreams.Add(NULL); + coderInfo.OutStreams.Clear(); + for(j = 0; j < coderStreamsInfo.NumOutStreams; j++) + coderInfo.OutStreams.Add(NULL); + } + + for(i = 0; i < _bindInfo.BindPairs.Size(); i++) + { + const CBindPair &bindPair = _bindInfo.BindPairs[i]; + UInt32 inCoderIndex, inCoderStreamIndex; + UInt32 outCoderIndex, outCoderStreamIndex; + _bindInfo.FindInStream(bindPair.InIndex, inCoderIndex, inCoderStreamIndex); + _bindInfo.FindOutStream(bindPair.OutIndex, outCoderIndex, outCoderStreamIndex); + + _streamBinders[i].CreateStreams( + &_coderInfoVector[inCoderIndex].InStreams[inCoderStreamIndex], + &_coderInfoVector[outCoderIndex].OutStreams[outCoderStreamIndex]); + } + + for(i = 0; i < _bindInfo.InStreams.Size(); i++) + { + UInt32 inCoderIndex, inCoderStreamIndex; + _bindInfo.FindInStream(_bindInfo.InStreams[i], inCoderIndex, inCoderStreamIndex); + _coderInfoVector[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i]; + } + + for(i = 0; i < _bindInfo.OutStreams.Size(); i++) + { + UInt32 outCoderIndex, outCoderStreamIndex; + _bindInfo.FindOutStream(_bindInfo.OutStreams[i], outCoderIndex, outCoderStreamIndex); + _coderInfoVector[outCoderIndex].OutStreams[outCoderStreamIndex] = outStreams[i]; + } + return S_OK; +} + + +bool CCoderMixer2MT::MyCode() +{ + HANDLE events[2] = { _exitEvent, _startCompressingEvent }; + DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); + if (waitResult == WAIT_OBJECT_0 + 0) + return false; + + for(int i = 0; i < _coderInfoVector.Size(); i++) + _coderInfoVector[i].CompressEvent->Set(); + /* DWORD result = */ ::WaitForMultipleObjects(_compressingCompletedEvents.Size(), + &_compressingCompletedEvents.Front(), TRUE, INFINITE); + + _compressingFinishedEvent.Set(); + + return true; +} + + +STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams, + const UInt64 ** /* inSizes */, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 ** /* outSizes */, + UInt32 numOutStreams, + ICompressProgressInfo *progress) +{ + if (numInStreams != (UInt32)_bindInfo.InStreams.Size() || + numOutStreams != (UInt32)_bindInfo.OutStreams.Size()) + return E_INVALIDARG; + + Init(inStreams, outStreams); + + _compressingFinishedEvent.Reset(); // ? + + CCrossThreadProgress *progressSpec = new CCrossThreadProgress; + CMyComPtr crossProgress = progressSpec; + progressSpec->Init(); + _coderInfoVector[_progressCoderIndex].Progress = crossProgress; + + _startCompressingEvent.Set(); + + + for (;;) + { + HANDLE events[2] = {_compressingFinishedEvent, progressSpec->ProgressEvent }; + DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); + if (waitResult == WAIT_OBJECT_0 + 0) + break; + if (progress != NULL) + progressSpec->Result = progress->SetRatioInfo(progressSpec->InSize, + progressSpec->OutSize); + else + progressSpec->Result = S_OK; + progressSpec->WaitEvent.Set(); + } + + int i; + for(i = 0; i < _coderInfoVector.Size(); i++) + { + HRESULT result = _coderInfoVector[i].Result; + if (result == S_FALSE) + return result; + } + for(i = 0; i < _coderInfoVector.Size(); i++) + { + HRESULT result = _coderInfoVector[i].Result; + if (result != S_OK && result != E_FAIL) + return result; + } + for(i = 0; i < _coderInfoVector.Size(); i++) + { + HRESULT result = _coderInfoVector[i].Result; + if (result != S_OK) + return result; + } + return S_OK; +} + +UInt64 CCoderMixer2MT::GetWriteProcessedSize(UInt32 binderIndex) const +{ + return _streamBinders[binderIndex].ProcessedSize; +} + +} diff --git a/CPP/7zip/Archive/Common/CoderMixer2MT.h b/CPP/7zip/Archive/Common/CoderMixer2MT.h new file mode 100755 index 00000000..78d752de --- /dev/null +++ b/CPP/7zip/Archive/Common/CoderMixer2MT.h @@ -0,0 +1,121 @@ +// CoderMixer2MT.h + +#ifndef __CODER_MIXER2_MT_H +#define __CODER_MIXER2_MT_H + +#include "CoderMixer2.h" +#include "../../../Common/MyCom.h" +#include "../../../Windows/Thread.h" +#include "../../Common/StreamBinder.h" + +namespace NCoderMixer2 { + +// CreateEvents(); +// { +// SetCoderInfo() +// Init Streams +// set CompressEvent() +// wait CompressionCompletedEvent +// } + +struct CThreadCoderInfo: public CCoderInfo +{ + NWindows::NSynchronization::CAutoResetEvent *CompressEvent; + HANDLE ExitEvent; + NWindows::NSynchronization::CAutoResetEvent *CompressionCompletedEvent; + + CObjectVector< CMyComPtr > InStreams; + CObjectVector< CMyComPtr > OutStreams; + CRecordVector InStreamPointers; + CRecordVector OutStreamPointers; + + CMyComPtr Progress; // CMyComPtr + HRESULT Result; + + CThreadCoderInfo(UInt32 numInStreams, UInt32 numOutStreams); + void SetCoderInfo(const UInt64 **inSizes, + const UInt64 **outSizes, ICompressProgressInfo *progress); + ~CThreadCoderInfo(); + bool WaitAndCode(); + void CreateEvents(); +}; + + +// SetBindInfo() +// for each coder +// { +// AddCoder[2]() +// } +// +// for each file +// { +// ReInit() +// for each coder +// { +// SetCoderInfo +// } +// SetProgressIndex(UInt32 coderIndex); +// Code +// } + + +class CCoderMixer2MT: + public ICompressCoder2, + public CCoderMixer2, + public CMyUnknownImp +{ + MY_UNKNOWN_IMP + +public: + STDMETHOD(Init)(ISequentialInStream **inStreams, + ISequentialOutStream **outStreams); + + STDMETHOD(Code)(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress); + + + CCoderMixer2MT(); + ~CCoderMixer2MT(); + void AddCoderCommon(); + void AddCoder(ICompressCoder *coder); + void AddCoder2(ICompressCoder2 *coder); + + void ReInit(); + void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes) + { _coderInfoVector[coderIndex].SetCoderInfo(inSizes, outSizes, NULL); } + void SetProgressCoderIndex(UInt32 coderIndex) + { _progressCoderIndex = coderIndex; } + + + UInt64 GetWriteProcessedSize(UInt32 binderIndex) const; + + + bool MyCode(); + +private: + CBindInfo _bindInfo; + CObjectVector _streamBinders; + CObjectVector _coderInfoVector; + CRecordVector _threads; + NWindows::CThread _mainThread; + + NWindows::NSynchronization::CAutoResetEvent _startCompressingEvent; + CRecordVector _compressingCompletedEvents; + NWindows::NSynchronization::CAutoResetEvent _compressingFinishedEvent; + + NWindows::NSynchronization::CManualResetEvent _exitEvent; + UInt32 _progressCoderIndex; + +public: + void SetBindInfo(const CBindInfo &bindInfo); + +}; + +} +#endif + diff --git a/CPP/7zip/Archive/Common/CoderMixer2ST.cpp b/CPP/7zip/Archive/Common/CoderMixer2ST.cpp new file mode 100755 index 00000000..c01b776d --- /dev/null +++ b/CPP/7zip/Archive/Common/CoderMixer2ST.cpp @@ -0,0 +1,238 @@ +// CoderMixer2ST.cpp + +#include "StdAfx.h" + +#include "CoderMixer2ST.h" + +namespace NCoderMixer2 { + +CCoderMixer2ST::CCoderMixer2ST() {} + +CCoderMixer2ST::~CCoderMixer2ST(){ } + +void CCoderMixer2ST::SetBindInfo(const CBindInfo &bindInfo) +{ + _bindInfo = bindInfo; +} + +void CCoderMixer2ST::AddCoderCommon(bool isMain) +{ + const CCoderStreamsInfo &csi = _bindInfo.Coders[_coders.Size()]; + _coders.Add(CSTCoderInfo(csi.NumInStreams, csi.NumOutStreams, isMain)); +} + +void CCoderMixer2ST::AddCoder(ICompressCoder *coder, bool isMain) +{ + AddCoderCommon(isMain); + _coders.Back().Coder = coder; +} + +void CCoderMixer2ST::AddCoder2(ICompressCoder2 *coder, bool isMain) +{ + AddCoderCommon(isMain); + _coders.Back().Coder2 = coder; +} + +void CCoderMixer2ST::ReInit() { } + +HRESULT CCoderMixer2ST::GetInStream( + ISequentialInStream **inStreams, const UInt64 **inSizes, + UInt32 streamIndex, ISequentialInStream **inStreamRes) +{ + CMyComPtr seqInStream; + int i; + for(i = 0; i < _bindInfo.InStreams.Size(); i++) + if (_bindInfo.InStreams[i] == streamIndex) + { + seqInStream = inStreams[i]; + *inStreamRes = seqInStream.Detach(); + return S_OK; + } + int binderIndex = _bindInfo.FindBinderForInStream(streamIndex); + if (binderIndex < 0) + return E_INVALIDARG; + + UInt32 coderIndex, coderStreamIndex; + _bindInfo.FindOutStream(_bindInfo.BindPairs[binderIndex].OutIndex, + coderIndex, coderStreamIndex); + + CCoderInfo &coder = _coders[coderIndex]; + if (!coder.Coder) + return E_NOTIMPL; + coder.Coder.QueryInterface(IID_ISequentialInStream, &seqInStream); + if (!seqInStream) + return E_NOTIMPL; + + UInt32 startIndex = _bindInfo.GetCoderInStreamIndex(coderIndex); + + CMyComPtr setInStream; + if (!coder.Coder) + return E_NOTIMPL; + coder.Coder.QueryInterface(IID_ICompressSetInStream, &setInStream); + if (!setInStream) + return E_NOTIMPL; + + if (coder.NumInStreams > 1) + return E_NOTIMPL; + for (i = 0; i < (int)coder.NumInStreams; i++) + { + CMyComPtr seqInStream2; + RINOK(GetInStream(inStreams, inSizes, startIndex + i, &seqInStream2)); + RINOK(setInStream->SetInStream(seqInStream2)); + } + *inStreamRes = seqInStream.Detach(); + return S_OK; +} + +HRESULT CCoderMixer2ST::GetOutStream( + ISequentialOutStream **outStreams, const UInt64 **outSizes, + UInt32 streamIndex, ISequentialOutStream **outStreamRes) +{ + CMyComPtr seqOutStream; + int i; + for(i = 0; i < _bindInfo.OutStreams.Size(); i++) + if (_bindInfo.OutStreams[i] == streamIndex) + { + seqOutStream = outStreams[i]; + *outStreamRes = seqOutStream.Detach(); + return S_OK; + } + int binderIndex = _bindInfo.FindBinderForOutStream(streamIndex); + if (binderIndex < 0) + return E_INVALIDARG; + + UInt32 coderIndex, coderStreamIndex; + _bindInfo.FindInStream(_bindInfo.BindPairs[binderIndex].InIndex, + coderIndex, coderStreamIndex); + + CCoderInfo &coder = _coders[coderIndex]; + if (!coder.Coder) + return E_NOTIMPL; + coder.Coder.QueryInterface(IID_ISequentialOutStream, &seqOutStream); + if (!seqOutStream) + return E_NOTIMPL; + + UInt32 startIndex = _bindInfo.GetCoderOutStreamIndex(coderIndex); + + CMyComPtr setOutStream; + if (!coder.Coder) + return E_NOTIMPL; + coder.Coder.QueryInterface(IID_ICompressSetOutStream, &setOutStream); + if (!setOutStream) + return E_NOTIMPL; + + if (coder.NumOutStreams > 1) + return E_NOTIMPL; + for (i = 0; i < (int)coder.NumOutStreams; i++) + { + CMyComPtr seqOutStream2; + RINOK(GetOutStream(outStreams, outSizes, startIndex + i, &seqOutStream2)); + RINOK(setOutStream->SetOutStream(seqOutStream2)); + } + *outStreamRes = seqOutStream.Detach(); + return S_OK; +} + + +STDMETHODIMP CCoderMixer2ST::Code(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress) +{ + if (numInStreams != (UInt32)_bindInfo.InStreams.Size() || + numOutStreams != (UInt32)_bindInfo.OutStreams.Size()) + return E_INVALIDARG; + + // Find main coder + int _mainCoderIndex = -1; + int i; + for (i = 0; i < _coders.Size(); i++) + if (_coders[i].IsMain) + { + _mainCoderIndex = i; + break; + } + if (_mainCoderIndex < 0) + for (i = 0; i < _coders.Size(); i++) + if (_coders[i].NumInStreams > 1) + { + if (_mainCoderIndex >= 0) + return E_NOTIMPL; + _mainCoderIndex = i; + } + if (_mainCoderIndex < 0) + _mainCoderIndex = 0; + + // _mainCoderIndex = 0; + // _mainCoderIndex = _coders.Size() - 1; + CCoderInfo &mainCoder = _coders[_mainCoderIndex]; + + CObjectVector< CMyComPtr > seqInStreams; + CObjectVector< CMyComPtr > seqOutStreams; + UInt32 startInIndex = _bindInfo.GetCoderInStreamIndex(_mainCoderIndex); + UInt32 startOutIndex = _bindInfo.GetCoderOutStreamIndex(_mainCoderIndex); + for (i = 0; i < (int)mainCoder.NumInStreams; i++) + { + CMyComPtr seqInStream; + RINOK(GetInStream(inStreams, inSizes, startInIndex + i, &seqInStream)); + seqInStreams.Add(seqInStream); + } + for (i = 0; i < (int)mainCoder.NumOutStreams; i++) + { + CMyComPtr seqOutStream; + RINOK(GetOutStream(outStreams, outSizes, startOutIndex + i, &seqOutStream)); + seqOutStreams.Add(seqOutStream); + } + CRecordVector< ISequentialInStream * > seqInStreamsSpec; + CRecordVector< ISequentialOutStream * > seqOutStreamsSpec; + for (i = 0; i < (int)mainCoder.NumInStreams; i++) + seqInStreamsSpec.Add(seqInStreams[i]); + for (i = 0; i < (int)mainCoder.NumOutStreams; i++) + seqOutStreamsSpec.Add(seqOutStreams[i]); + + for (i = 0; i < _coders.Size(); i++) + { + if (i == _mainCoderIndex) + continue; + CCoderInfo &coder = _coders[i]; + CMyComPtr setOutStreamSize; + coder.Coder.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize); + if (setOutStreamSize) + { + RINOK(setOutStreamSize->SetOutStreamSize(coder.OutSizePointers[0])); + } + } + if (mainCoder.Coder) + { + RINOK(mainCoder.Coder->Code( + seqInStreamsSpec[0], seqOutStreamsSpec[0], + mainCoder.InSizePointers[0], mainCoder.OutSizePointers[0], + progress)); + } + else + { + RINOK(mainCoder.Coder2->Code( + &seqInStreamsSpec.Front(), + &mainCoder.InSizePointers.Front(), mainCoder.NumInStreams, + &seqOutStreamsSpec.Front(), + &mainCoder.OutSizePointers.Front(), mainCoder.NumOutStreams, + progress)); + } + CMyComPtr flush; + seqOutStreams.Front().QueryInterface(IID_IOutStreamFlush, &flush); + if (flush) + return flush->Flush(); + return S_OK; +} + +/* +UInt64 CCoderMixer2ST::GetWriteProcessedSize(UInt32 binderIndex) const +{ + return _streamBinders[binderIndex].ProcessedSize; +} +*/ + +} diff --git a/CPP/7zip/Archive/Common/CoderMixer2ST.h b/CPP/7zip/Archive/Common/CoderMixer2ST.h new file mode 100755 index 00000000..3144918b --- /dev/null +++ b/CPP/7zip/Archive/Common/CoderMixer2ST.h @@ -0,0 +1,88 @@ +// CoderMixer2ST.h + +#ifndef __CODER_MIXER2_ST_H +#define __CODER_MIXER2_ST_H + +#include "CoderMixer2.h" +#include "../../../Common/MyCom.h" +#include "../../ICoder.h" + +namespace NCoderMixer2 { + +// SetBindInfo() +// for each coder +// { +// AddCoder[2]() +// } +// +// for each file +// { +// ReInit() +// for each coder +// { +// SetCoderInfo +// } +// SetProgressIndex(UInt32 coderIndex); +// Code +// } + +struct CSTCoderInfo: public CCoderInfo +{ + bool IsMain; + CSTCoderInfo(UInt32 numInStreams, UInt32 numOutStreams, bool isMain): + CCoderInfo(numInStreams, numOutStreams),IsMain(isMain) {} +}; + +class CCoderMixer2ST: + public ICompressCoder2, + public CCoderMixer2, + public CMyUnknownImp +{ + MY_UNKNOWN_IMP + + HRESULT GetInStream( + ISequentialInStream **inStreams, const UInt64 **inSizes, + UInt32 streamIndex, ISequentialInStream **inStreamRes); + HRESULT GetOutStream( + ISequentialOutStream **outStreams, const UInt64 **outSizes, + UInt32 streamIndex, ISequentialOutStream **outStreamRes); +public: + STDMETHOD(Code)(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress); + + CCoderMixer2ST(); + ~CCoderMixer2ST(); + void AddCoderCommon(bool isMain); + void AddCoder(ICompressCoder *coder, bool isMain); + void AddCoder2(ICompressCoder2 *coder, bool isMain); + + void ReInit(); + void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes) + { + { _coders[coderIndex].SetCoderInfo(inSizes, outSizes); } + } + + void SetProgressCoderIndex(UInt32 /*coderIndex*/) + { + // _progressCoderIndex = coderIndex; + } + + // UInt64 GetWriteProcessedSize(UInt32 binderIndex) const; + +private: + CBindInfo _bindInfo; + CObjectVector _coders; + int _mainCoderIndex; +public: + void SetBindInfo(const CBindInfo &bindInfo); + +}; + +} +#endif + diff --git a/CPP/7zip/Archive/Common/CrossThreadProgress.cpp b/CPP/7zip/Archive/Common/CrossThreadProgress.cpp new file mode 100755 index 00000000..a974b54c --- /dev/null +++ b/CPP/7zip/Archive/Common/CrossThreadProgress.cpp @@ -0,0 +1,15 @@ +// CrossThreadProgress.cpp + +#include "StdAfx.h" + +#include "CrossThreadProgress.h" + +STDMETHODIMP CCrossThreadProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +{ + InSize = inSize; + OutSize = outSize; + ProgressEvent.Set(); + WaitEvent.Lock(); + return Result; +} + diff --git a/CPP/7zip/Archive/Common/CrossThreadProgress.h b/CPP/7zip/Archive/Common/CrossThreadProgress.h new file mode 100755 index 00000000..5dd339dc --- /dev/null +++ b/CPP/7zip/Archive/Common/CrossThreadProgress.h @@ -0,0 +1,31 @@ +// CrossThreadProgress.h + +#ifndef __CROSSTHREADPROGRESS_H +#define __CROSSTHREADPROGRESS_H + +#include "../../ICoder.h" +#include "../../../Windows/Synchronization.h" +#include "../../../Common/MyCom.h" + +class CCrossThreadProgress: + public ICompressProgressInfo, + public CMyUnknownImp +{ +public: + const UInt64 *InSize; + const UInt64 *OutSize; + HRESULT Result; + NWindows::NSynchronization::CAutoResetEvent ProgressEvent; + NWindows::NSynchronization::CAutoResetEvent WaitEvent; + void Init() + { + ProgressEvent.Reset(); + WaitEvent.Reset(); + } + + MY_UNKNOWN_IMP + + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); +}; + +#endif diff --git a/CPP/7zip/Archive/Common/DummyOutStream.cpp b/CPP/7zip/Archive/Common/DummyOutStream.cpp new file mode 100755 index 00000000..b1d49913 --- /dev/null +++ b/CPP/7zip/Archive/Common/DummyOutStream.cpp @@ -0,0 +1,20 @@ +// DummyOutStream.cpp + +#include "StdAfx.h" + +#include "DummyOutStream.h" + +void CDummyOutStream::Init(ISequentialOutStream *outStream) +{ + m_Stream = outStream; +} + +STDMETHODIMP CDummyOutStream::Write(const void *data, + UInt32 size, UInt32 *processedSize) +{ + if(m_Stream) + return m_Stream->Write(data, size, processedSize); + if(processedSize != NULL) + *processedSize = size; + return S_OK; +} diff --git a/CPP/7zip/Archive/Common/DummyOutStream.h b/CPP/7zip/Archive/Common/DummyOutStream.h new file mode 100755 index 00000000..51690787 --- /dev/null +++ b/CPP/7zip/Archive/Common/DummyOutStream.h @@ -0,0 +1,23 @@ +// DummyOutStream.h + +#ifndef __DUMMYOUTSTREAM_H +#define __DUMMYOUTSTREAM_H + +#include "../../IStream.h" +#include "Common/MyCom.h" + +class CDummyOutStream: + public ISequentialOutStream, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +private: + CMyComPtr m_Stream; +public: + void Init(ISequentialOutStream *outStream); +}; + +#endif diff --git a/CPP/7zip/Archive/Common/FilterCoder.cpp b/CPP/7zip/Archive/Common/FilterCoder.cpp new file mode 100755 index 00000000..5e104c84 --- /dev/null +++ b/CPP/7zip/Archive/Common/FilterCoder.cpp @@ -0,0 +1,243 @@ +// FilterCoder.cpp + +#include "StdAfx.h" + +#include "FilterCoder.h" +#include "../../../Common/Alloc.h" +#include "../../../Common/Defs.h" +#include "../../Common/StreamUtils.h" + +static const int kBufferSize = 1 << 17; + +CFilterCoder::CFilterCoder() +{ + _buffer = (Byte *)::MidAlloc(kBufferSize); +} + +CFilterCoder::~CFilterCoder() +{ + ::MidFree(_buffer); +} + +HRESULT CFilterCoder::WriteWithLimit(ISequentialOutStream *outStream, UInt32 size) +{ + if (_outSizeIsDefined) + { + UInt64 remSize = _outSize - _nowPos64; + if (size > remSize) + size = (UInt32)remSize; + } + UInt32 processedSize = 0; + RINOK(WriteStream(outStream, _buffer, size, &processedSize)); + if (size != processedSize) + return E_FAIL; + _nowPos64 += processedSize; + return S_OK; +} + + +STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + RINOK(Init()); + UInt32 bufferPos = 0; + _outSizeIsDefined = (outSize != 0); + if (_outSizeIsDefined) + _outSize = *outSize; + + while(NeedMore()) + { + UInt32 processedSize; + + // Change it: It can be optimized using ReadPart + RINOK(ReadStream(inStream, _buffer + bufferPos, kBufferSize - bufferPos, &processedSize)); + + UInt32 endPos = bufferPos + processedSize; + + bufferPos = Filter->Filter(_buffer, endPos); + if (bufferPos > endPos) + { + for (; endPos< bufferPos; endPos++) + _buffer[endPos] = 0; + bufferPos = Filter->Filter(_buffer, endPos); + } + + if (bufferPos == 0) + { + if (endPos > 0) + return WriteWithLimit(outStream, endPos); + return S_OK; + } + RINOK(WriteWithLimit(outStream, bufferPos)); + if (progress != NULL) + { + RINOK(progress->SetRatioInfo(&_nowPos64, &_nowPos64)); + } + UInt32 i = 0; + while(bufferPos < endPos) + _buffer[i++] = _buffer[bufferPos++]; + bufferPos = i; + } + return S_OK; +} + +// #ifdef _ST_MODE +STDMETHODIMP CFilterCoder::SetOutStream(ISequentialOutStream *outStream) +{ + _bufferPos = 0; + _outStream = outStream; + return Init(); +} + +STDMETHODIMP CFilterCoder::ReleaseOutStream() +{ + _outStream.Release(); + return S_OK; +}; + + +STDMETHODIMP CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 processedSizeTotal = 0; + while(size > 0) + { + UInt32 sizeMax = kBufferSize - _bufferPos; + UInt32 sizeTemp = size; + if (sizeTemp > sizeMax) + sizeTemp = sizeMax; + memmove(_buffer + _bufferPos, data, sizeTemp); + size -= sizeTemp; + processedSizeTotal += sizeTemp; + data = (const Byte *)data + sizeTemp; + UInt32 endPos = _bufferPos + sizeTemp; + _bufferPos = Filter->Filter(_buffer, endPos); + if (_bufferPos == 0) + { + _bufferPos = endPos; + break; + } + if (_bufferPos > endPos) + { + if (size != 0) + return E_FAIL; + break; + } + RINOK(WriteWithLimit(_outStream, _bufferPos)); + UInt32 i = 0; + while(_bufferPos < endPos) + _buffer[i++] = _buffer[_bufferPos++]; + _bufferPos = i; + } + if (processedSize != NULL) + *processedSize = processedSizeTotal; + return S_OK; +} + +STDMETHODIMP CFilterCoder::Flush() +{ + if (_bufferPos != 0) + { + UInt32 endPos = Filter->Filter(_buffer, _bufferPos); + if (endPos > _bufferPos) + { + for (; _bufferPos < endPos; _bufferPos++) + _buffer[_bufferPos] = 0; + if (Filter->Filter(_buffer, endPos) != endPos) + return E_FAIL; + } + UInt32 processedSize; + RINOK(WriteStream(_outStream, _buffer, _bufferPos, &processedSize)); + if (_bufferPos != processedSize) + return E_FAIL; + _bufferPos = 0; + } + CMyComPtr flush; + _outStream.QueryInterface(IID_IOutStreamFlush, &flush); + if (flush) + return flush->Flush(); + return S_OK; +} + + +STDMETHODIMP CFilterCoder::SetInStream(ISequentialInStream *inStream) +{ + _convertedPosBegin = _convertedPosEnd = _bufferPos = 0; + _inStream = inStream; + return Init(); +} + +STDMETHODIMP CFilterCoder::ReleaseInStream() +{ + _inStream.Release(); + return S_OK; +}; + +STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 processedSizeTotal = 0; + while(size > 0) + { + if (_convertedPosBegin != _convertedPosEnd) + { + UInt32 sizeTemp = MyMin(size, _convertedPosEnd - _convertedPosBegin); + memmove(data, _buffer + _convertedPosBegin, sizeTemp); + _convertedPosBegin += sizeTemp; + data = (void *)((Byte *)data + sizeTemp); + size -= sizeTemp; + processedSizeTotal += sizeTemp; + break; + } + int i; + for (i = 0; _convertedPosEnd + i < _bufferPos; i++) + _buffer[i] = _buffer[i + _convertedPosEnd]; + _bufferPos = i; + _convertedPosBegin = _convertedPosEnd = 0; + UInt32 processedSizeTemp; + UInt32 size0 = kBufferSize - _bufferPos; + // Optimize it: + RINOK(ReadStream(_inStream, _buffer + _bufferPos, size0, &processedSizeTemp)); + _bufferPos = _bufferPos + processedSizeTemp; + _convertedPosEnd = Filter->Filter(_buffer, _bufferPos); + if (_convertedPosEnd == 0) + { + if (_bufferPos == 0) + break; + else + { + _convertedPosEnd = _bufferPos; // check it + continue; + } + } + if (_convertedPosEnd > _bufferPos) + { + for (; _bufferPos < _convertedPosEnd; _bufferPos++) + _buffer[_bufferPos] = 0; + _convertedPosEnd = Filter->Filter(_buffer, _bufferPos); + } + } + if (processedSize != NULL) + *processedSize = processedSizeTotal; + return S_OK; +} + +// #endif // _ST_MODE + +#ifndef _NO_CRYPTO +STDMETHODIMP CFilterCoder::CryptoSetPassword(const Byte *data, UInt32 size) +{ + return _setPassword->CryptoSetPassword(data, size); +} +#endif + +#ifndef EXTRACT_ONLY +STDMETHODIMP CFilterCoder::WriteCoderProperties(ISequentialOutStream *outStream) +{ + return _writeCoderProperties->WriteCoderProperties(outStream); +} +#endif + +STDMETHODIMP CFilterCoder::SetDecoderProperties2(const Byte *data, UInt32 size) +{ + return _setDecoderProperties->SetDecoderProperties2(data, size); +} diff --git a/CPP/7zip/Archive/Common/FilterCoder.h b/CPP/7zip/Archive/Common/FilterCoder.h new file mode 100755 index 00000000..45618172 --- /dev/null +++ b/CPP/7zip/Archive/Common/FilterCoder.h @@ -0,0 +1,130 @@ +// FilterCoder.h + +#ifndef __FILTERCODER_H +#define __FILTERCODER_H + +#include "../../../Common/MyCom.h" +#include "../../ICoder.h" +#include "../../IPassword.h" + +#define MY_QUERYINTERFACE_ENTRY_AG(i, sub0, sub) if (iid == IID_ ## i) \ +{ if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \ +*outObject = (void *)(i *)this; AddRef(); return S_OK; } + +class CFilterCoder: + public ICompressCoder, + // #ifdef _ST_MODE + public ICompressSetInStream, + public ISequentialInStream, + public ICompressSetOutStream, + public ISequentialOutStream, + public IOutStreamFlush, + // #endif + + #ifndef _NO_CRYPTO + public ICryptoSetPassword, + #endif + #ifndef EXTRACT_ONLY + public ICompressWriteCoderProperties, + #endif + public ICompressSetDecoderProperties2, + public CMyUnknownImp +{ +protected: + Byte *_buffer; + // #ifdef _ST_MODE + CMyComPtr _inStream; + CMyComPtr _outStream; + UInt32 _bufferPos; + UInt32 _convertedPosBegin; + UInt32 _convertedPosEnd; + // #endif + bool _outSizeIsDefined; + UInt64 _outSize; + UInt64 _nowPos64; + + HRESULT Init() + { + _nowPos64 = 0; + _outSizeIsDefined = false; + return Filter->Init(); + } + + CMyComPtr _setPassword; + #ifndef EXTRACT_ONLY + CMyComPtr _writeCoderProperties; + #endif + CMyComPtr _setDecoderProperties; +public: + CMyComPtr Filter; + + CFilterCoder(); + ~CFilterCoder(); + HRESULT WriteWithLimit(ISequentialOutStream *outStream, UInt32 size); + bool NeedMore() const + { return (!_outSizeIsDefined || (_nowPos64 < _outSize)); } + +public: + MY_QUERYINTERFACE_BEGIN + MY_QUERYINTERFACE_ENTRY(ICompressCoder) + // #ifdef _ST_MODE + MY_QUERYINTERFACE_ENTRY(ICompressSetInStream) + MY_QUERYINTERFACE_ENTRY(ISequentialInStream) + + MY_QUERYINTERFACE_ENTRY(ICompressSetOutStream) + MY_QUERYINTERFACE_ENTRY(ISequentialOutStream) + MY_QUERYINTERFACE_ENTRY(IOutStreamFlush) + // #endif + + #ifndef _NO_CRYPTO + MY_QUERYINTERFACE_ENTRY_AG(ICryptoSetPassword, Filter, _setPassword) + #endif + + #ifndef EXTRACT_ONLY + MY_QUERYINTERFACE_ENTRY_AG(ICompressWriteCoderProperties, Filter, _writeCoderProperties) + #endif + + MY_QUERYINTERFACE_ENTRY_AG(ICompressSetDecoderProperties2, Filter, _setDecoderProperties) + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + // #ifdef _ST_MODE + STDMETHOD(ReleaseInStream)(); + STDMETHOD(SetInStream)(ISequentialInStream *inStream); + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); \ + STDMETHOD(SetOutStream)(ISequentialOutStream *outStream); + STDMETHOD(ReleaseOutStream)(); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Flush)(); + // #endif + + #ifndef _NO_CRYPTO + STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); + #endif + #ifndef EXTRACT_ONLY + STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); + #endif + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); +}; + +// #ifdef _ST_MODE +class CInStreamReleaser +{ +public: + CFilterCoder *FilterCoder; + CInStreamReleaser(): FilterCoder(0) {} + ~CInStreamReleaser() { if (FilterCoder) FilterCoder->ReleaseInStream(); } +}; + +class COutStreamReleaser +{ +public: + CFilterCoder *FilterCoder; + COutStreamReleaser(): FilterCoder(0) {} + ~COutStreamReleaser() { if (FilterCoder) FilterCoder->ReleaseOutStream(); } +}; +// #endif + +#endif diff --git a/CPP/7zip/Archive/Common/InStreamWithCRC.cpp b/CPP/7zip/Archive/Common/InStreamWithCRC.cpp new file mode 100755 index 00000000..74dff7e1 --- /dev/null +++ b/CPP/7zip/Archive/Common/InStreamWithCRC.cpp @@ -0,0 +1,41 @@ +// InStreamWithCRC.cpp + +#include "StdAfx.h" + +#include "InStreamWithCRC.h" + +STDMETHODIMP CSequentialInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize; + HRESULT result = _stream->Read(data, size, &realProcessedSize); + _size += realProcessedSize; + if (size > 0 && realProcessedSize == 0) + _wasFinished = true; + _crc.Update(data, realProcessedSize); + if(processedSize != NULL) + *processedSize = realProcessedSize; + return result; +} + +STDMETHODIMP CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize; + HRESULT result = _stream->Read(data, size, &realProcessedSize); + if (size > 0 && realProcessedSize == 0) + _wasFinished = true; + _size += realProcessedSize; + _crc.Update(data, realProcessedSize); + if(processedSize != NULL) + *processedSize = realProcessedSize; + return result; +} + +STDMETHODIMP CInStreamWithCRC::Seek(Int64 offset, + UInt32 seekOrigin, UInt64 *newPosition) +{ + if (seekOrigin != STREAM_SEEK_SET || offset != 0) + return E_FAIL; + _size = 0; + _crc.Init(); + return _stream->Seek(offset, seekOrigin, newPosition); +} diff --git a/CPP/7zip/Archive/Common/InStreamWithCRC.h b/CPP/7zip/Archive/Common/InStreamWithCRC.h new file mode 100755 index 00000000..770a1437 --- /dev/null +++ b/CPP/7zip/Archive/Common/InStreamWithCRC.h @@ -0,0 +1,65 @@ +// InStreamWithCRC.h + +#ifndef __INSTREAMWITHCRC_H +#define __INSTREAMWITHCRC_H + +#include "../../../Common/CRC.h" +#include "../../../Common/MyCom.h" +#include "../../IStream.h" + +class CSequentialInStreamWithCRC: + public ISequentialInStream, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); +private: + CMyComPtr _stream; + UInt64 _size; + CCRC _crc; + bool _wasFinished; +public: + void SetStream(ISequentialInStream *stream) { _stream = stream; } + void Init() + { + _size = 0; + _wasFinished = false; + _crc.Init(); + } + void ReleaseStream() { _stream.Release(); } + UInt32 GetCRC() const { return _crc.GetDigest(); } + UInt64 GetSize() const { return _size; } + bool WasFinished() const { return _wasFinished; } +}; + +class CInStreamWithCRC: + public IInStream, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP1(IInStream) + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); +private: + CMyComPtr _stream; + UInt64 _size; + CCRC _crc; + bool _wasFinished; +public: + void SetStream(IInStream *stream) { _stream = stream; } + void Init() + { + _size = 0; + _wasFinished = false; + _crc.Init(); + } + void ReleaseStream() { _stream.Release(); } + UInt32 GetCRC() const { return _crc.GetDigest(); } + UInt64 GetSize() const { return _size; } + bool WasFinished() const { return _wasFinished; } +}; + +#endif diff --git a/CPP/7zip/Archive/Common/ItemNameUtils.cpp b/CPP/7zip/Archive/Common/ItemNameUtils.cpp new file mode 100755 index 00000000..f7c3fcd9 --- /dev/null +++ b/CPP/7zip/Archive/Common/ItemNameUtils.cpp @@ -0,0 +1,59 @@ +// Archive/Common/ItemNameUtils.cpp + +#include "StdAfx.h" + +#include "ItemNameUtils.h" + +namespace NArchive { +namespace NItemName { + +static const wchar_t kOSDirDelimiter = WCHAR_PATH_SEPARATOR; +static const wchar_t kDirDelimiter = L'/'; + +UString MakeLegalName(const UString &name) +{ + UString zipName = name; + zipName.Replace(kOSDirDelimiter, kDirDelimiter); + return zipName; +} + +UString GetOSName(const UString &name) +{ + UString newName = name; + newName.Replace(kDirDelimiter, kOSDirDelimiter); + return newName; +} + +UString GetOSName2(const UString &name) +{ + if (name.IsEmpty()) + return UString(); + UString newName = GetOSName(name); + if (newName[newName.Length() - 1] == kOSDirDelimiter) + newName.Delete(newName.Length() - 1); + return newName; +} + +bool HasTailSlash(const AString &name, UINT codePage) +{ + if (name.IsEmpty()) + return false; + LPCSTR prev = + #ifdef _WIN32 + CharPrevExA((WORD)codePage, name, &name[name.Length()], 0); + #else + (LPCSTR)(name) + (name.Length() - 1); + #endif + return (*prev == '/'); +} + +#ifndef _WIN32 +UString WinNameToOSName(const UString &name) +{ + UString newName = name; + newName.Replace(L'\\', kOSDirDelimiter); + return newName; +} +#endif + +}} diff --git a/CPP/7zip/Archive/Common/ItemNameUtils.h b/CPP/7zip/Archive/Common/ItemNameUtils.h new file mode 100755 index 00000000..63a01563 --- /dev/null +++ b/CPP/7zip/Archive/Common/ItemNameUtils.h @@ -0,0 +1,24 @@ +// Archive/Common/ItemNameUtils.h + +#ifndef __ARCHIVE_ITEMNAMEUTILS_H +#define __ARCHIVE_ITEMNAMEUTILS_H + +#include "../../../Common/String.h" + +namespace NArchive { +namespace NItemName { + + UString MakeLegalName(const UString &name); + UString GetOSName(const UString &name); + UString GetOSName2(const UString &name); + bool HasTailSlash(const AString &name, UINT codePage); + + #ifdef _WIN32 + inline UString WinNameToOSName(const UString &name) { return name; } + #else + UString WinNameToOSName(const UString &name); + #endif + +}} + +#endif diff --git a/CPP/7zip/Archive/Common/MultiStream.cpp b/CPP/7zip/Archive/Common/MultiStream.cpp new file mode 100755 index 00000000..a8cb333e --- /dev/null +++ b/CPP/7zip/Archive/Common/MultiStream.cpp @@ -0,0 +1,201 @@ +// MultiStream.cpp + +#include "StdAfx.h" + +#include "MultiStream.h" + +STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + if(processedSize != NULL) + *processedSize = 0; + while(_streamIndex < Streams.Size() && size > 0) + { + CSubStreamInfo &s = Streams[_streamIndex]; + if (_pos == s.Size) + { + _streamIndex++; + _pos = 0; + continue; + } + RINOK(s.Stream->Seek(s.Pos + _pos, STREAM_SEEK_SET, 0)); + UInt32 sizeToRead = UInt32(MyMin((UInt64)size, s.Size - _pos)); + UInt32 realProcessed; + HRESULT result = s.Stream->Read(data, sizeToRead, &realProcessed); + data = (void *)((Byte *)data + realProcessed); + size -= realProcessed; + if(processedSize != NULL) + *processedSize += realProcessed; + _pos += realProcessed; + _seekPos += realProcessed; + RINOK(result); + break; + } + return S_OK; +} + +STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, + UInt64 *newPosition) +{ + UInt64 newPos; + switch(seekOrigin) + { + case STREAM_SEEK_SET: + newPos = offset; + break; + case STREAM_SEEK_CUR: + newPos = _seekPos + offset; + break; + case STREAM_SEEK_END: + newPos = _totalLength + offset; + break; + default: + return STG_E_INVALIDFUNCTION; + } + _seekPos = 0; + for (_streamIndex = 0; _streamIndex < Streams.Size(); _streamIndex++) + { + UInt64 size = Streams[_streamIndex].Size; + if (newPos < _seekPos + size) + { + _pos = newPos - _seekPos; + _seekPos += _pos; + if (newPosition != 0) + *newPosition = newPos; + return S_OK; + } + _seekPos += size; + } + if (newPos == _seekPos) + { + if (newPosition != 0) + *newPosition = newPos; + return S_OK; + } + return E_FAIL; +} + + +/* +class COutVolumeStream: + public ISequentialOutStream, + public CMyUnknownImp +{ + int _volIndex; + UInt64 _volSize; + UInt64 _curPos; + CMyComPtr _volumeStream; + COutArchive _archive; + CCRC _crc; + +public: + MY_UNKNOWN_IMP + + CFileItem _file; + CUpdateOptions _options; + CMyComPtr VolumeCallback; + void Init(IArchiveUpdateCallback2 *volumeCallback, + const UString &name) + { + _file.Name = name; + _file.IsStartPosDefined = true; + _file.StartPos = 0; + + VolumeCallback = volumeCallback; + _volIndex = 0; + _volSize = 0; + } + + HRESULT Flush(); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +HRESULT COutVolumeStream::Flush() +{ + if (_volumeStream) + { + _file.UnPackSize = _curPos; + _file.FileCRC = _crc.GetDigest(); + RINOK(WriteVolumeHeader(_archive, _file, _options)); + _archive.Close(); + _volumeStream.Release(); + _file.StartPos += _file.UnPackSize; + } + return S_OK; +} +*/ + +/* +STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if(processedSize != NULL) + *processedSize = 0; + while(size > 0) + { + if (_streamIndex >= Streams.Size()) + { + CSubStreamInfo subStream; + RINOK(VolumeCallback->GetVolumeSize(Streams.Size(), &subStream.Size)); + RINOK(VolumeCallback->GetVolumeStream(Streams.Size(), &subStream.Stream)); + subStream.Pos = 0; + Streams.Add(subStream); + continue; + } + CSubStreamInfo &subStream = Streams[_streamIndex]; + if (_offsetPos >= subStream.Size) + { + _offsetPos -= subStream.Size; + _streamIndex++; + continue; + } + if (_offsetPos != subStream.Pos) + { + CMyComPtr outStream; + RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream)); + RINOK(outStream->Seek(_offsetPos, STREAM_SEEK_SET, NULL)); + subStream.Pos = _offsetPos; + } + + UInt32 curSize = (UInt32)MyMin((UInt64)size, subStream.Size - subStream.Pos); + UInt32 realProcessed; + RINOK(subStream.Stream->Write(data, curSize, &realProcessed)); + data = (void *)((Byte *)data + realProcessed); + size -= realProcessed; + subStream.Pos += realProcessed; + _offsetPos += realProcessed; + _absPos += realProcessed; + if (_absPos > _length) + _length = _absPos; + if(processedSize != NULL) + *processedSize += realProcessed; + if (subStream.Pos == subStream.Size) + { + _streamIndex++; + _offsetPos = 0; + } + if (realProcessed != curSize && realProcessed == 0) + return E_FAIL; + } + return S_OK; +} + +STDMETHODIMP COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +{ + if(seekOrigin >= 3) + return STG_E_INVALIDFUNCTION; + switch(seekOrigin) + { + case STREAM_SEEK_SET: + _absPos = offset; + break; + case STREAM_SEEK_CUR: + _absPos += offset; + break; + case STREAM_SEEK_END: + _absPos = _length + offset; + break; + } + _offsetPos = _absPos; + _streamIndex = 0; + return S_OK; +} +*/ diff --git a/CPP/7zip/Archive/Common/MultiStream.h b/CPP/7zip/Archive/Common/MultiStream.h new file mode 100755 index 00000000..5a7cc687 --- /dev/null +++ b/CPP/7zip/Archive/Common/MultiStream.h @@ -0,0 +1,76 @@ +// MultiStream.h + +#ifndef __MULTISTREAM_H +#define __MULTISTREAM_H + +#include "../../../Common/MyCom.h" +#include "../../../Common/Vector.h" +#include "../../Archive/IArchive.h" + +class CMultiStream: + public IInStream, + public CMyUnknownImp +{ + int _streamIndex; + UInt64 _pos; + UInt64 _seekPos; + UInt64 _totalLength; +public: + struct CSubStreamInfo + { + CMyComPtr Stream; + UInt64 Pos; + UInt64 Size; + }; + CObjectVector Streams; + void Init() + { + _streamIndex = 0; + _pos = 0; + _seekPos = 0; + _totalLength = 0; + for (int i = 0; i < Streams.Size(); i++) + _totalLength += Streams[i].Size; + } + + MY_UNKNOWN_IMP1(IInStream) + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); +}; + +/* +class COutMultiStream: + public IOutStream, + public CMyUnknownImp +{ + int _streamIndex; // required stream + UInt64 _offsetPos; // offset from start of _streamIndex index + UInt64 _absPos; + UInt64 _length; + + struct CSubStreamInfo + { + CMyComPtr Stream; + UInt64 Size; + UInt64 Pos; + }; + CObjectVector Streams; +public: + CMyComPtr VolumeCallback; + void Init() + { + _streamIndex = 0; + _offsetPos = 0; + _absPos = 0; + _length = 0; + } + + MY_UNKNOWN_IMP1(IOutStream) + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); +}; +*/ + +#endif diff --git a/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp b/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp new file mode 100755 index 00000000..7ac3f123 --- /dev/null +++ b/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp @@ -0,0 +1,24 @@ +// OutStreamWithCRC.cpp + +#include "StdAfx.h" + +#include "OutStreamWithCRC.h" + +STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize; + HRESULT result; + if(!_stream) + { + realProcessedSize = size; + result = S_OK; + } + else + result = _stream->Write(data, size, &realProcessedSize); + if (_calculateCrc) + _crc.Update(data, realProcessedSize); + _size += realProcessedSize; + if(processedSize != NULL) + *processedSize = realProcessedSize; + return result; +} diff --git a/CPP/7zip/Archive/Common/OutStreamWithCRC.h b/CPP/7zip/Archive/Common/OutStreamWithCRC.h new file mode 100755 index 00000000..0feb542b --- /dev/null +++ b/CPP/7zip/Archive/Common/OutStreamWithCRC.h @@ -0,0 +1,37 @@ +// OutStreamWithCRC.h + +#ifndef __OUTSTREAMWITHCRC_H +#define __OUTSTREAMWITHCRC_H + +#include "../../../Common/CRC.h" +#include "../../../Common/MyCom.h" +#include "../../IStream.h" + +class COutStreamWithCRC: + public ISequentialOutStream, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +private: + CMyComPtr _stream; + UInt64 _size; + CCRC _crc; + bool _calculateCrc; +public: + void SetStream(ISequentialOutStream *stream) { _stream = stream; } + void Init(bool calculateCrc = true) + { + _size = 0; + _calculateCrc = calculateCrc; + _crc.Init(); + } + void ReleaseStream() { _stream.Release(); } + UInt64 GetSize() const { return _size; } + UInt32 GetCRC() const { return _crc.GetDigest(); } + void InitCRC() { _crc.Init(); } +}; + +#endif diff --git a/CPP/7zip/Archive/Common/ParseProperties.cpp b/CPP/7zip/Archive/Common/ParseProperties.cpp new file mode 100755 index 00000000..9866d900 --- /dev/null +++ b/CPP/7zip/Archive/Common/ParseProperties.cpp @@ -0,0 +1,171 @@ +// ParseProperties.cpp + +#include "StdAfx.h" + +#include "ParseProperties.h" + +#include "Common/StringToInt.h" +#include "Common/MyCom.h" + +HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue) +{ + if (prop.vt == VT_UI4) + { + if (!name.IsEmpty()) + return E_INVALIDARG; + resValue = prop.ulVal; + } + else if (prop.vt == VT_EMPTY) + { + if(!name.IsEmpty()) + { + const wchar_t *start = name; + const wchar_t *end; + UInt64 v = ConvertStringToUInt64(start, &end); + if (end - start != name.Length()) + return E_INVALIDARG; + resValue = (UInt32)v; + } + } + else + return E_INVALIDARG; + return S_OK; +} + +static const int kLogarithmicSizeLimit = 32; +static const wchar_t kByteSymbol = L'B'; +static const wchar_t kKiloByteSymbol = L'K'; +static const wchar_t kMegaByteSymbol = L'M'; + +HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize) +{ + UString srcString = srcStringSpec; + srcString.MakeUpper(); + + const wchar_t *start = srcString; + const wchar_t *end; + UInt64 number = ConvertStringToUInt64(start, &end); + int numDigits = (int)(end - start); + if (numDigits == 0 || srcString.Length() > numDigits + 1) + return E_INVALIDARG; + if (srcString.Length() == numDigits) + { + if (number >= kLogarithmicSizeLimit) + return E_INVALIDARG; + dicSize = (UInt32)1 << (int)number; + return S_OK; + } + switch (srcString[numDigits]) + { + case kByteSymbol: + if (number >= ((UInt64)1 << kLogarithmicSizeLimit)) + return E_INVALIDARG; + dicSize = (UInt32)number; + break; + case kKiloByteSymbol: + if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 10))) + return E_INVALIDARG; + dicSize = (UInt32)(number << 10); + break; + case kMegaByteSymbol: + if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 20))) + return E_INVALIDARG; + dicSize = (UInt32)(number << 20); + break; + default: + return E_INVALIDARG; + } + return S_OK; +} + +HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue) +{ + if (name.IsEmpty()) + { + if (prop.vt == VT_UI4) + { + UInt32 logDicSize = prop.ulVal; + if (logDicSize >= 32) + return E_INVALIDARG; + resValue = (UInt32)1 << logDicSize; + return S_OK; + } + if (prop.vt == VT_BSTR) + return ParsePropDictionaryValue(prop.bstrVal, resValue); + return E_INVALIDARG; + } + return ParsePropDictionaryValue(name, resValue); +} + +HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value) +{ + switch(value.vt) + { + case VT_EMPTY: + dest = true; + break; + /* + case VT_UI4: + dest = (value.ulVal != 0); + break; + */ + case VT_BSTR: + { + UString valueString = value.bstrVal; + valueString.MakeUpper(); + if (valueString.Compare(L"ON") == 0) + dest = true; + else if (valueString.Compare(L"OFF") == 0) + dest = false; + else + return E_INVALIDARG; + break; + } + default: + return E_INVALIDARG; + } + return S_OK; +} + +int ParseStringToUInt32(const UString &srcString, UInt32 &number) +{ + const wchar_t *start = srcString; + const wchar_t *end; + UInt64 number64 = ConvertStringToUInt64(start, &end); + if (number64 > 0xFFFFFFFF) + { + number = 0; + return 0; + } + number = (UInt32)number64; + return (int)(end - start); +} + +HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads) +{ + if (name.IsEmpty()) + { + switch(prop.vt) + { + case VT_UI4: + numThreads = prop.ulVal; + break; + default: + { + bool val; + RINOK(SetBoolProperty(val, prop)); + numThreads = (val ? defaultNumThreads : 1); + break; + } + } + } + else + { + UInt32 number; + int index = ParseStringToUInt32(name, number); + if (index != name.Length()) + return E_INVALIDARG; + numThreads = number; + } + return S_OK; +} diff --git a/CPP/7zip/Archive/Common/ParseProperties.h b/CPP/7zip/Archive/Common/ParseProperties.h new file mode 100755 index 00000000..e6db316b --- /dev/null +++ b/CPP/7zip/Archive/Common/ParseProperties.h @@ -0,0 +1,17 @@ +// ParseProperties.h + +#ifndef __PARSEPROPERTIES_H +#define __PARSEPROPERTIES_H + +#include "Common/String.h" +#include "Common/Types.h" + +HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue); +HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize); +HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue); + +HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value); +int ParseStringToUInt32(const UString &srcString, UInt32 &number); +HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads); + +#endif diff --git a/CPP/7zip/Archive/Common/StdAfx.h b/CPP/7zip/Archive/Common/StdAfx.h new file mode 100755 index 00000000..2e4be10b --- /dev/null +++ b/CPP/7zip/Archive/Common/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" +#include "../../../Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/Archive/Cpio/CpioHandler.cpp b/CPP/7zip/Archive/Cpio/CpioHandler.cpp new file mode 100755 index 00000000..601afbd6 --- /dev/null +++ b/CPP/7zip/Archive/Cpio/CpioHandler.cpp @@ -0,0 +1,289 @@ +// Archive/cpio/Handler.cpp + +#include "StdAfx.h" + +#include "CpioHandler.h" + +#include "Common/Defs.h" +#include "Common/StringConvert.h" +#include "Common/NewHandler.h" +#include "Common/ComTry.h" + +#include "Windows/Time.h" +#include "Windows/PropVariant.h" + +#include "../../Common/ProgressUtils.h" +#include "../../Common//LimitedStreams.h" + +#include "../../Compress/Copy/CopyCoder.h" +#include "../Common/ItemNameUtils.h" +#include "CpioIn.h" + +using namespace NWindows; +using namespace NTime; + +namespace NArchive { +namespace NCpio { + +enum // PropID +{ + kpidinode = kpidUserDefined, + kpidiChkSum +}; + +STATPROPSTG kProperties[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackedSize, VT_UI8}, + { NULL, kpidLastWriteTime, VT_FILETIME}, + // { NULL, kpidUser, VT_BSTR}, + // { NULL, kpidGroup, VT_BSTR}, + // { L"inode", kpidinode, VT_UI4} + // { L"CheckSum", kpidiChkSum, VT_UI4} +}; + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) +{ + value->vt = VT_EMPTY; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if(index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &srcItem = kProperties[index]; + *propID = srcItem.propid; + *varType = srcItem.vt; + *name = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +{ + *numProperties = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, + BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) +{ + return E_INVALIDARG; +} + +STDMETHODIMP CHandler::Open(IInStream *inStream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback *openArchiveCallback) +{ + COM_TRY_BEGIN + // try + { + CInArchive archive; + + if(archive.Open(inStream) != S_OK) + return S_FALSE; + + m_Items.Clear(); + + if (openArchiveCallback != NULL) + { + RINOK(openArchiveCallback->SetTotal(NULL, NULL)); + UInt64 numFiles = m_Items.Size(); + RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); + } + + for (;;) + { + CItemEx itemInfo; + bool filled; + HRESULT result = archive.GetNextItem(filled, itemInfo); + if (result == S_FALSE) + return S_FALSE; + if (result != S_OK) + return S_FALSE; + if (!filled) + break; + m_Items.Add(itemInfo); + archive.SkeepDataRecords(itemInfo.Size, itemInfo.Align); + if (openArchiveCallback != NULL) + { + UInt64 numFiles = m_Items.Size(); + RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); + } + } + if (m_Items.Size() == 0) + return S_FALSE; + + m_InStream = inStream; + } + /* + catch(...) + { + return S_FALSE; + } + */ + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + m_Items.Clear(); + m_InStream.Release(); + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = m_Items.Size(); + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant propVariant; + const CItemEx &item = m_Items[index]; + + switch(propID) + { + case kpidPath: + propVariant = (const wchar_t *)NItemName::GetOSName( + MultiByteToUnicodeString(item.Name, CP_OEMCP)); + break; + case kpidIsFolder: + propVariant = item.IsDirectory(); + break; + case kpidSize: + case kpidPackedSize: + propVariant = item.Size; + break; + case kpidLastWriteTime: + { + FILETIME utcFileTime; + if (item.ModificationTime != 0) + NTime::UnixTimeToFileTime(item.ModificationTime, utcFileTime); + else + { + utcFileTime.dwLowDateTime = 0; + utcFileTime.dwHighDateTime = 0; + } + propVariant = utcFileTime; + break; + } + case kpidinode: + propVariant = item.inode; + break; + /* + case kpidiChkSum: + propVariant = item.ChkSum; + break; + */ + } + propVariant.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = m_Items.Size(); + if(numItems == 0) + return S_OK; + bool testMode = (_aTestMode != 0); + UInt64 totalSize = 0; + UInt32 i; + for(i = 0; i < numItems; i++) + totalSize += m_Items[allFilesMode ? i : indices[i]].Size; + extractCallback->SetTotal(totalSize); + + UInt64 currentTotalSize = 0; + UInt64 currentItemSize; + + CMyComPtr copyCoder; + + for(i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + { + RINOK(extractCallback->SetCompleted(¤tTotalSize)); + CMyComPtr 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 inStream(streamSpec); + streamSpec->SetStream(m_InStream); + streamSpec->Init(itemInfo.Size); + + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr progress = localProgressSpec; + localProgressSpec->Init(extractCallback, false); + + CLocalCompressProgressInfo *localCompressProgressSpec = + new CLocalCompressProgressInfo; + CMyComPtr compressProgress = localCompressProgressSpec; + localCompressProgressSpec->Init(progress, + ¤tTotalSize, ¤tTotalSize); + + if(copyCoder == NULL) + { + copyCoder = new NCompress::CCopyCoder; + } + try + { + RINOK(copyCoder->Code(inStream, realOutStream, + NULL, NULL, compressProgress)); + } + catch(...) + { + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); + continue; + } + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + } + } + return S_OK; + COM_TRY_END +} + +}} diff --git a/CPP/7zip/Archive/Cpio/CpioHandler.h b/CPP/7zip/Archive/Cpio/CpioHandler.h new file mode 100755 index 00000000..39702541 --- /dev/null +++ b/CPP/7zip/Archive/Cpio/CpioHandler.h @@ -0,0 +1,47 @@ +// Archive/cpio/Handler.h + +#ifndef __ARCHIVE_CPIO_HANDLER_H +#define __ARCHIVE_CPIO_HANDLER_H + +#include "Common/MyCom.h" +#include "../IArchive.h" + +#include "CpioItem.h" + +namespace NArchive { +namespace NCpio { + +class CHandler: + public IInArchive, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Open)(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback); + STDMETHOD(Close)(); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); + + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + +private: + CObjectVector m_Items; + CMyComPtr m_InStream; +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Cpio/CpioHeader.cpp b/CPP/7zip/Archive/Cpio/CpioHeader.cpp new file mode 100755 index 00000000..9e4d99cb --- /dev/null +++ b/CPP/7zip/Archive/Cpio/CpioHeader.cpp @@ -0,0 +1,23 @@ +// Archive/cpio/Header.h + +#include "StdAfx.h" + +#include "CpioHeader.h" + +namespace NArchive { +namespace NCpio { +namespace NFileHeader { + + namespace NMagic + { + extern const char *kMagic1 = "070701"; + extern const char *kMagic2 = "070702"; + extern const char *kMagic3 = "070707"; + extern const char *kEndName = "TRAILER!!!"; + + const Byte kMagicForRecord2[2] = { 0xC7, 0x71 }; + // unsigned short kMagicForRecord2BE = 0xC771; + } + +}}} + diff --git a/CPP/7zip/Archive/Cpio/CpioHeader.h b/CPP/7zip/Archive/Cpio/CpioHeader.h new file mode 100755 index 00000000..40a0014a --- /dev/null +++ b/CPP/7zip/Archive/Cpio/CpioHeader.h @@ -0,0 +1,70 @@ +// Archive/cpio/Header.h + +#ifndef __ARCHIVE_CPIO_HEADER_H +#define __ARCHIVE_CPIO_HEADER_H + +#include "Common/Types.h" + +namespace NArchive { +namespace NCpio { + +namespace NFileHeader +{ + namespace NMagic + { + extern const char *kMagic1; + extern const char *kMagic2; + extern const char *kMagic3; + extern const char *kEndName; + extern const Byte kMagicForRecord2[2]; + } + + const UInt32 kRecord2Size = 26; + /* + struct CRecord2 + { + unsigned short c_magic; + short c_dev; + unsigned short c_ino; + unsigned short c_mode; + unsigned short c_uid; + unsigned short c_gid; + unsigned short c_nlink; + short c_rdev; + unsigned short c_mtimes[2]; + unsigned short c_namesize; + unsigned short c_filesizes[2]; + }; + */ + + const UInt32 kRecordSize = 110; + /* + struct CRecord + { + char Magic[6]; // "070701" for "new" portable format, "070702" for CRC format + char inode[8]; + char Mode[8]; + char UID[8]; + char GID[8]; + char nlink[8]; + char mtime[8]; + char Size[8]; // must be 0 for FIFOs and directories + char DevMajor[8]; + char DevMinor[8]; + char RDevMajor[8]; //only valid for chr and blk special files + char RDevMinor[8]; //only valid for chr and blk special files + char NameSize[8]; // count includes terminating NUL in pathname + char ChkSum[8]; // 0 for "new" portable format; for CRC format the sum of all the bytes in the file + bool CheckMagic() const + { return memcmp(Magic, NMagic::kMagic1, 6) == 0 || + memcmp(Magic, NMagic::kMagic2, 6) == 0; }; + }; + */ + + const UInt32 kOctRecordSize = 76; + +} + +}} + +#endif diff --git a/CPP/7zip/Archive/Cpio/CpioIn.cpp b/CPP/7zip/Archive/Cpio/CpioIn.cpp new file mode 100755 index 00000000..91399362 --- /dev/null +++ b/CPP/7zip/Archive/Cpio/CpioIn.cpp @@ -0,0 +1,271 @@ +// Archive/cpioIn.cpp + +#include "StdAfx.h" + +#include "CpioIn.h" + +#include "Common/StringToInt.h" +#include "Windows/Defs.h" + +#include "../../Common/StreamUtils.h" + +#include "CpioHeader.h" + +namespace NArchive { +namespace NCpio { + +HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize) +{ + RINOK(ReadStream(m_Stream, data, size, &processedSize)); + m_Position += processedSize; + return S_OK; +} + +Byte CInArchive::ReadByte() +{ + if (_blockPos >= _blockSize) + throw "Incorrect cpio archive"; + return _block[_blockPos++]; +} + +UInt16 CInArchive::ReadUInt16() +{ + UInt16 value = 0; + for (int i = 0; i < 2; i++) + { + Byte b = ReadByte(); + value |= (UInt16(b) << (8 * i)); + } + return value; +} + +UInt32 CInArchive::ReadUInt32() +{ + UInt32 value = 0; + for (int i = 0; i < 4; i++) + { + Byte b = ReadByte(); + value |= (UInt32(b) << (8 * i)); + } + return value; +} + +HRESULT CInArchive::Open(IInStream *inStream) +{ + RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position)); + m_Stream = inStream; + return S_OK; +} + +bool CInArchive::ReadNumber(UInt32 &resultValue) +{ + resultValue = 0; + for (int i = 0; i < 8; i++) + { + char c = char(ReadByte()); + int d; + if (c >= '0' && c <= '9') + d = c - '0'; + else if (c >= 'A' && c <= 'F') + d = 10 + c - 'A'; + else if (c >= 'a' && c <= 'f') + d = 10 + c - 'a'; + else + return false; + resultValue *= 0x10; + resultValue += d; + } + return true; +} + +static bool OctalToNumber(const char *s, UInt64 &res) +{ + const char *end; + res = ConvertOctStringToUInt64(s, &end); + return (*end == ' ' || *end == 0); +} + +static bool OctalToNumber32(const char *s, UInt32 &res) +{ + UInt64 res64; + if (!OctalToNumber(s, res64)) + return false; + res = (UInt32)res64; + return (res64 <= 0xFFFFFFFF); +} + +bool CInArchive::ReadOctNumber(int size, UInt32 &resultValue) +{ + char sz[32 + 4]; + int i; + for (i = 0; i < size && i < 32; i++) + sz[i] = (char)ReadByte(); + sz[i] = 0; + return OctalToNumber32(sz, resultValue); +} + +#define GetFromHex(y) { if (!ReadNumber(y)) return S_FALSE; } +#define GetFromOct6(y) { if (!ReadOctNumber(6, y)) return S_FALSE; } +#define GetFromOct11(y) { if (!ReadOctNumber(11, y)) return S_FALSE; } + +static unsigned short ConvertValue(unsigned short value, bool convert) +{ + if (!convert) + return value; + return (unsigned short)((((unsigned short)(value & 0xFF)) << 8) | (value >> 8)); +} + +static UInt32 GetAlignedSize(UInt32 size, UInt32 align) +{ + while ((size & (align - 1)) != 0) + size++; + return size; +} + + +HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) +{ + filled = false; + + UInt32 processedSize; + item.HeaderPosition = m_Position; + + _blockSize = kMaxBlockSize; + RINOK(ReadBytes(_block, 2, processedSize)); + if (processedSize != 2) + return S_FALSE; + _blockPos = 0; + + UInt32 nameSize; + + bool oldBE = + _block[0] == NFileHeader::NMagic::kMagicForRecord2[1] && + _block[1] == NFileHeader::NMagic::kMagicForRecord2[0]; + + bool binMode = (_block[0] == NFileHeader::NMagic::kMagicForRecord2[0] && + _block[1] == NFileHeader::NMagic::kMagicForRecord2[1]) || + oldBE; + + if (binMode) + { + RINOK(ReadBytes(_block + 2, NFileHeader::kRecord2Size - 2, processedSize)); + if (processedSize != NFileHeader::kRecord2Size - 2) + return S_FALSE; + item.Align = 2; + _blockPos = 2; + item.DevMajor = 0; + item.DevMinor = ConvertValue(ReadUInt16(), oldBE); + item.inode = ConvertValue(ReadUInt16(), oldBE); + item.Mode = ConvertValue(ReadUInt16(), oldBE); + item.UID = ConvertValue(ReadUInt16(), oldBE); + item.GID = ConvertValue(ReadUInt16(), oldBE); + item.NumLinks = ConvertValue(ReadUInt16(), oldBE); + item.RDevMajor =0; + item.RDevMinor = ConvertValue(ReadUInt16(), oldBE); + UInt16 timeHigh = ConvertValue(ReadUInt16(), oldBE); + UInt16 timeLow = ConvertValue(ReadUInt16(), oldBE); + item.ModificationTime = (UInt32(timeHigh) << 16) + timeLow; + nameSize = ConvertValue(ReadUInt16(), oldBE); + UInt16 sizeHigh = ConvertValue(ReadUInt16(), oldBE); + UInt16 sizeLow = ConvertValue(ReadUInt16(), oldBE); + item.Size = (UInt32(sizeHigh) << 16) + sizeLow; + + item.ChkSum = 0; + item.HeaderSize = GetAlignedSize( + nameSize + NFileHeader::kRecord2Size, item.Align); + nameSize = item.HeaderSize - NFileHeader::kRecord2Size; + } + else + { + RINOK(ReadBytes(_block + 2, 4, processedSize)); + if (processedSize != 4) + return S_FALSE; + + bool magicOK = + memcmp(_block, NFileHeader::NMagic::kMagic1, 6) == 0 || + memcmp(_block, NFileHeader::NMagic::kMagic2, 6) == 0; + _blockPos = 6; + if (magicOK) + { + RINOK(ReadBytes(_block + 6, NFileHeader::kRecordSize - 6, processedSize)); + if (processedSize != NFileHeader::kRecordSize - 6) + return S_FALSE; + item.Align = 4; + + GetFromHex(item.inode); + GetFromHex(item.Mode); + GetFromHex(item.UID); + GetFromHex(item.GID); + GetFromHex(item.NumLinks); + UInt32 modificationTime; + GetFromHex(modificationTime); + item.ModificationTime = modificationTime; + GetFromHex(item.Size); + GetFromHex(item.DevMajor); + GetFromHex(item.DevMinor); + GetFromHex(item.RDevMajor); + GetFromHex(item.RDevMinor); + GetFromHex(nameSize); + GetFromHex(item.ChkSum); + item.HeaderSize = GetAlignedSize( + nameSize + NFileHeader::kRecordSize, item.Align); + nameSize = item.HeaderSize - NFileHeader::kRecordSize; + } + else + { + if (!memcmp(_block, NFileHeader::NMagic::kMagic3, 6) == 0) + return S_FALSE; + RINOK(ReadBytes(_block + 6, NFileHeader::kOctRecordSize - 6, processedSize)); + if (processedSize != NFileHeader::kOctRecordSize - 6) + return S_FALSE; + item.Align = 1; + item.DevMajor = 0; + GetFromOct6(item.DevMinor); + GetFromOct6(item.inode); + GetFromOct6(item.Mode); + GetFromOct6(item.UID); + GetFromOct6(item.GID); + GetFromOct6(item.NumLinks); + item.RDevMajor = 0; + GetFromOct6(item.RDevMinor); + UInt32 modificationTime; + GetFromOct11(modificationTime); + item.ModificationTime = modificationTime; + GetFromOct6(nameSize); + GetFromOct11(item.Size); // ????? + item.HeaderSize = GetAlignedSize( + nameSize + NFileHeader::kOctRecordSize, item.Align); + nameSize = item.HeaderSize - NFileHeader::kOctRecordSize; + } + } + if (nameSize == 0 || nameSize >= (1 << 27)) + return E_FAIL; + RINOK(ReadBytes(item.Name.GetBuffer(nameSize), + nameSize, processedSize)); + if (processedSize != nameSize) + return E_FAIL; + item.Name.ReleaseBuffer(); + if (strcmp(item.Name, NFileHeader::NMagic::kEndName) == 0) + return S_OK; + filled = true; + return S_OK; +} + +HRESULT CInArchive::Skeep(UInt64 numBytes) +{ + UInt64 newPostion; + RINOK(m_Stream->Seek(numBytes, STREAM_SEEK_CUR, &newPostion)); + m_Position += numBytes; + if (m_Position != newPostion) + return E_FAIL; + return S_OK; +} + +HRESULT CInArchive::SkeepDataRecords(UInt64 dataSize, UInt32 align) +{ + while ((dataSize & (align - 1)) != 0) + dataSize++; + return Skeep(dataSize); +} + +}} diff --git a/CPP/7zip/Archive/Cpio/CpioIn.h b/CPP/7zip/Archive/Cpio/CpioIn.h new file mode 100755 index 00000000..19e3da10 --- /dev/null +++ b/CPP/7zip/Archive/Cpio/CpioIn.h @@ -0,0 +1,41 @@ +// CpioIn.h + +#ifndef __ARCHIVE_CPIO_IN_H +#define __ARCHIVE_CPIO_IN_H + +#include "Common/MyCom.h" +#include "Common/Types.h" +#include "../../IStream.h" +#include "CpioItem.h" + +namespace NArchive { +namespace NCpio { + +const UInt32 kMaxBlockSize = NFileHeader::kRecordSize; + +class CInArchive +{ + CMyComPtr m_Stream; + UInt64 m_Position; + + UInt16 _blockSize; + Byte _block[kMaxBlockSize]; + UInt32 _blockPos; + Byte ReadByte(); + UInt16 ReadUInt16(); + UInt32 ReadUInt32(); + + bool ReadNumber(UInt32 &resultValue); + bool ReadOctNumber(int size, UInt32 &resultValue); + + HRESULT ReadBytes(void *data, UInt32 size, UInt32 &processedSize); +public: + HRESULT Open(IInStream *inStream); + HRESULT GetNextItem(bool &filled, CItemEx &itemInfo); + HRESULT Skeep(UInt64 numBytes); + HRESULT SkeepDataRecords(UInt64 dataSize, UInt32 align); +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Cpio/CpioItem.h b/CPP/7zip/Archive/Cpio/CpioItem.h new file mode 100755 index 00000000..0eb2a0b4 --- /dev/null +++ b/CPP/7zip/Archive/Cpio/CpioItem.h @@ -0,0 +1,55 @@ +// Archive/cpio/ItemInfo.h + +#ifndef __ARCHIVE_CPIO_ITEMINFO_H +#define __ARCHIVE_CPIO_ITEMINFO_H + +#include + +#include "Common/Types.h" +#include "Common/String.h" +#include "CpioHeader.h" + +namespace NArchive { +namespace NCpio { + +struct CItem +{ + AString Name; + UInt32 inode; + UInt32 Mode; + UInt32 UID; + UInt32 GID; + UInt32 Size; + UInt32 ModificationTime; + + // char LinkFlag; + // AString LinkName; ????? + char Magic[8]; + UInt32 NumLinks; + UInt32 DevMajor; + UInt32 DevMinor; + UInt32 RDevMajor; + UInt32 RDevMinor; + UInt32 ChkSum; + + UInt32 Align; + + bool IsDirectory() const +#ifdef _WIN32 + { return (Mode & _S_IFMT) == _S_IFDIR; } +#else + { return (Mode & S_IFMT) == S_IFDIR; } +#endif +}; + +class CItemEx: public CItem +{ +public: + UInt64 HeaderPosition; + UInt32 HeaderSize; + UInt64 GetDataPosition() const { return HeaderPosition + HeaderSize; }; +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Cpio/DllExports.cpp b/CPP/7zip/Archive/Cpio/DllExports.cpp new file mode 100755 index 00000000..8eb38bfd --- /dev/null +++ b/CPP/7zip/Archive/Cpio/DllExports.cpp @@ -0,0 +1,65 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "Windows/PropVariant.h" +#include "CpioHandler.h" +#include "../../ICoder.h" + +// {23170F69-40C1-278A-1000-000110ED0000} +DEFINE_GUID(CLSID_CCpioHandler, + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xED, 0x00, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /*lpReserved*/) +{ + return TRUE; +} + +STDAPI CreateObject( + const GUID *classID, + const GUID *interfaceID, + void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + if (*classID != CLSID_CCpioHandler) + return CLASS_E_CLASSNOTAVAILABLE; + if (*interfaceID != IID_IInArchive) + return E_NOINTERFACE; + CMyComPtr inArchive = (IInArchive *)new NArchive::NCpio::CHandler; + *outObject = inArchive.Detach(); + COM_TRY_END + return S_OK; +} + +STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case NArchive::kName: + propVariant = L"Cpio"; + break; + case NArchive::kClassID: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CCpioHandler, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NArchive::kExtension: + propVariant = L"cpio"; + break; + case NArchive::kUpdate: + propVariant = false; + break; + case NArchive::kKeepName: + propVariant = false; + break; + } + propVariant.Detach(value); + return S_OK; +} diff --git a/CPP/7zip/Archive/Cpio/StdAfx.cpp b/CPP/7zip/Archive/Cpio/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Archive/Cpio/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Cpio/StdAfx.h b/CPP/7zip/Archive/Cpio/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Archive/Cpio/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Archive/Cpio/cpio.dsp b/CPP/7zip/Archive/Cpio/cpio.dsp new file mode 100755 index 00000000..f30c3e63 --- /dev/null +++ b/CPP/7zip/Archive/Cpio/cpio.dsp @@ -0,0 +1,265 @@ +# Microsoft Developer Studio Project File - Name="cpio" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=cpio - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "cpio.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "cpio.mak" CFG="cpio - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "cpio - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "cpio - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "cpio - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CPIO_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CPIO_EXPORTS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\cpio.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "cpio - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CPIO_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CPIO_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\cpio.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "cpio - Win32 Release" +# Name "cpio - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Archive.def +# End Source File +# Begin Source File + +SOURCE=.\cpio.ico +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\CpioHandler.cpp +# End Source File +# Begin Source File + +SOURCE=.\CpioHandler.h +# End Source File +# Begin Source File + +SOURCE=.\CpioHeader.cpp +# End Source File +# Begin Source File + +SOURCE=.\CpioHeader.h +# End Source File +# Begin Source File + +SOURCE=.\CpioIn.cpp +# End Source File +# Begin Source File + +SOURCE=.\CpioIn.h +# End Source File +# Begin Source File + +SOURCE=.\CpioItem.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# End Target +# End Project diff --git a/CPP/7zip/Archive/Cpio/cpio.dsw b/CPP/7zip/Archive/Cpio/cpio.dsw new file mode 100755 index 00000000..b1b6d98f --- /dev/null +++ b/CPP/7zip/Archive/Cpio/cpio.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "cpio"=.\cpio.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Archive/Cpio/cpio.ico b/CPP/7zip/Archive/Cpio/cpio.ico new file mode 100755 index 00000000..9abaabc7 Binary files /dev/null and b/CPP/7zip/Archive/Cpio/cpio.ico differ diff --git a/CPP/7zip/Archive/Cpio/makefile b/CPP/7zip/Archive/Cpio/makefile new file mode 100755 index 00000000..d7760281 --- /dev/null +++ b/CPP/7zip/Archive/Cpio/makefile @@ -0,0 +1,55 @@ +PROG = cpio.dll +DEF_FILE = ../Archive.def +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib user32.lib + +CPIO_OBJS = \ + $O\DllExports.obj \ + $O\CpioHandler.obj \ + $O\CpioHeader.obj \ + $O\CpioIn.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\Vector.obj \ + +WIN_OBJS = \ + $O\PropVariant.obj \ + +7ZIP_COMMON_OBJS = \ + $O\LimitedStreams.obj \ + $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ + +AR_COMMON_OBJS = \ + $O\ItemNameUtils.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(CPIO_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $(COMPRESS_CPIO_OBJS) \ + $O\CopyCoder.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(CPIO_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/Archive/Cpio/resource.rc b/CPP/7zip/Archive/Cpio/resource.rc new file mode 100755 index 00000000..d5456e5a --- /dev/null +++ b/CPP/7zip/Archive/Cpio/resource.rc @@ -0,0 +1,5 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("Cpio Plugin", "cpio") + +101 ICON "cpio.ico" diff --git a/CPP/7zip/Archive/Deb/Deb.dsp b/CPP/7zip/Archive/Deb/Deb.dsp new file mode 100755 index 00000000..56689305 --- /dev/null +++ b/CPP/7zip/Archive/Deb/Deb.dsp @@ -0,0 +1,269 @@ +# Microsoft Developer Studio Project File - Name="Deb" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Deb - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Deb.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Deb.mak" CFG="Deb - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Deb - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Deb - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Deb - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DEB_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DEB_EXPORTS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\deb.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Deb - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DEB_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DEB_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\deb.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Deb - Win32 Release" +# Name "Deb - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Archive.def +# End Source File +# Begin Source File + +SOURCE=.\Deb.ico +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\DebHandler.cpp +# End Source File +# Begin Source File + +SOURCE=.\DebHandler.h +# End Source File +# Begin Source File + +SOURCE=.\DebHeader.cpp +# End Source File +# Begin Source File + +SOURCE=.\DebHeader.h +# End Source File +# Begin Source File + +SOURCE=.\DebIn.cpp +# End Source File +# Begin Source File + +SOURCE=.\DebIn.h +# End Source File +# Begin Source File + +SOURCE=.\DebItem.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# End Target +# End Project diff --git a/CPP/7zip/Archive/Deb/Deb.dsw b/CPP/7zip/Archive/Deb/Deb.dsw new file mode 100755 index 00000000..c7169534 --- /dev/null +++ b/CPP/7zip/Archive/Deb/Deb.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Deb"=.\Deb.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Archive/Deb/DebHandler.cpp b/CPP/7zip/Archive/Deb/DebHandler.cpp new file mode 100755 index 00000000..8728cec8 --- /dev/null +++ b/CPP/7zip/Archive/Deb/DebHandler.cpp @@ -0,0 +1,255 @@ +// DebHandler.cpp + +#include "StdAfx.h" + +#include "DebHandler.h" +#include "DebIn.h" + +#include "Common/Defs.h" +#include "Common/StringConvert.h" +#include "Common/NewHandler.h" +#include "Common/ComTry.h" + +#include "Windows/Time.h" +#include "Windows/PropVariant.h" + +#include "../../Common/ProgressUtils.h" +#include "../../Common/LimitedStreams.h" + +#include "../../Compress/Copy/CopyCoder.h" + +#include "../Common/ItemNameUtils.h" + +using namespace NWindows; +using namespace NTime; + +namespace NArchive { +namespace NDeb { + +STATPROPSTG kProperties[] = +{ + { NULL, kpidPath, VT_BSTR}, + // { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackedSize, VT_UI8}, + { NULL, kpidLastWriteTime, VT_FILETIME} +}; + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) +{ + value->vt = VT_EMPTY; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if(index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &srcItem = kProperties[index]; + *propID = srcItem.propid; + *varType = srcItem.vt; + *name = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +{ + *numProperties = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, + BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) +{ + return E_INVALIDARG; +} + + +STDMETHODIMP CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback *openArchiveCallback) +{ + COM_TRY_BEGIN + { + CInArchive archive; + if(archive.Open(stream) != S_OK) + return S_FALSE; + _items.Clear(); + + if (openArchiveCallback != NULL) + { + RINOK(openArchiveCallback->SetTotal(NULL, NULL)); + UInt64 numFiles = _items.Size(); + RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); + } + + for (;;) + { + CItemEx itemInfo; + bool filled; + HRESULT result = archive.GetNextItem(filled, itemInfo); + if (result == S_FALSE) + return S_FALSE; + if (result != S_OK) + return S_FALSE; + if (!filled) + break; + _items.Add(itemInfo); + archive.SkeepData(itemInfo.Size); + if (openArchiveCallback != NULL) + { + UInt64 numFiles = _items.Size(); + RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); + } + } + _inStream = stream; + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + _inStream.Release(); + _items.Clear(); + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _items.Size(); + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant propVariant; + const CItemEx &item = _items[index]; + + switch(propID) + { + case kpidPath: + propVariant = (const wchar_t *)NItemName::GetOSName2( + MultiByteToUnicodeString(item.Name, CP_OEMCP)); + break; + case kpidIsFolder: + propVariant = false; + break; + case kpidSize: + case kpidPackedSize: + propVariant = item.Size; + break; + case kpidLastWriteTime: + { + FILETIME utcFileTime; + if (item.ModificationTime != 0) + NTime::UnixTimeToFileTime(item.ModificationTime, utcFileTime); + else + { + utcFileTime.dwLowDateTime = 0; + utcFileTime.dwHighDateTime = 0; + } + propVariant = utcFileTime; + break; + } + } + propVariant.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = _items.Size(); + if(numItems == 0) + return S_OK; + bool testMode = (_aTestMode != 0); + UInt64 totalSize = 0; + UInt32 i; + for(i = 0; i < numItems; i++) + totalSize += _items[allFilesMode ? i : indices[i]].Size; + extractCallback->SetTotal(totalSize); + + UInt64 currentTotalSize = 0; + UInt64 currentItemSize; + + CMyComPtr copyCoder; + + for(i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + { + RINOK(extractCallback->SetCompleted(¤tTotalSize)); + CMyComPtr 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 inStream(streamSpec); + streamSpec->SetStream(_inStream); + streamSpec->Init(itemInfo.Size); + + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr progress = localProgressSpec; + localProgressSpec->Init(extractCallback, false); + + CLocalCompressProgressInfo *localCompressProgressSpec = + new CLocalCompressProgressInfo; + CMyComPtr compressProgress = localCompressProgressSpec; + localCompressProgressSpec->Init(progress, + ¤tTotalSize, ¤tTotalSize); + + if(copyCoder == NULL) + { + copyCoder = new NCompress::CCopyCoder; + } + try + { + RINOK(copyCoder->Code(inStream, realOutStream, + NULL, NULL, compressProgress)); + } + catch(...) + { + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); + continue; + } + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + } + } + return S_OK; + COM_TRY_END +} + +}} diff --git a/CPP/7zip/Archive/Deb/DebHandler.h b/CPP/7zip/Archive/Deb/DebHandler.h new file mode 100755 index 00000000..47de0224 --- /dev/null +++ b/CPP/7zip/Archive/Deb/DebHandler.h @@ -0,0 +1,47 @@ +// DebHandler.h + +#ifndef __DEB_HANDLER_H +#define __DEB_HANDLER_H + +#include "Common/MyCom.h" +#include "../IArchive.h" + +#include "DebItem.h" + +namespace NArchive { +namespace NDeb { + +class CHandler: + public IInArchive, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Open)(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback); + STDMETHOD(Close)(); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); + + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + +private: + CObjectVector _items; + CMyComPtr _inStream; +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Deb/DebHeader.cpp b/CPP/7zip/Archive/Deb/DebHeader.cpp new file mode 100755 index 00000000..dce00e1b --- /dev/null +++ b/CPP/7zip/Archive/Deb/DebHeader.cpp @@ -0,0 +1,13 @@ +// Archive/Deb/Header.h + +#include "StdAfx.h" + +#include "DebHeader.h" + +namespace NArchive { +namespace NDeb { +namespace NHeader { + +const char *kSignature = "!\n"; + +}}} diff --git a/CPP/7zip/Archive/Deb/DebHeader.h b/CPP/7zip/Archive/Deb/DebHeader.h new file mode 100755 index 00000000..c2884000 --- /dev/null +++ b/CPP/7zip/Archive/Deb/DebHeader.h @@ -0,0 +1,38 @@ +// Archive/Deb/Header.h + +#ifndef __ARCHIVE_DEB_HEADER_H +#define __ARCHIVE_DEB_HEADER_H + +#include "Common/Types.h" + +namespace NArchive { +namespace NDeb { + +namespace NHeader +{ + const int kSignatureLen = 8; + extern const char *kSignature; + const int kNameSize = 16; + const int kTimeSize = 12; + const int kModeSize = 8; + const int kSizeSize = 10; + + /* + struct CHeader + { + char Name[kNameSize]; + char ModificationTime[kTimeSize]; + char Number0[6]; + char Number1[6]; + char Mode[kModeSize]; + char Size[kSizeSize]; + char Quote; + char NewLine; + }; + */ + const int kHeaderSize = kNameSize + kTimeSize + 6 + 6 + kModeSize + kSizeSize + 1 + 1; +} + +}} + +#endif diff --git a/CPP/7zip/Archive/Deb/DebIn.cpp b/CPP/7zip/Archive/Deb/DebIn.cpp new file mode 100755 index 00000000..c2221d12 --- /dev/null +++ b/CPP/7zip/Archive/Deb/DebIn.cpp @@ -0,0 +1,165 @@ +// Archive/DebIn.cpp + +#include "StdAfx.h" + +#include "DebIn.h" +#include "DebHeader.h" + +#include "Common/StringToInt.h" +#include "Windows/Defs.h" + +#include "../../Common/StreamUtils.h" + +namespace NArchive { +namespace NDeb { + +using namespace NHeader; + +HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize) +{ + RINOK(ReadStream(m_Stream, data, size, &processedSize)); + m_Position += processedSize; + return S_OK; +} + +HRESULT CInArchive::Open(IInStream *inStream) +{ + RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position)); + char signature[kSignatureLen]; + UInt32 processedSize; + RINOK(ReadStream(inStream, signature, kSignatureLen, &processedSize)); + m_Position += processedSize; + if (processedSize != kSignatureLen) + return S_FALSE; + if (memcmp(signature, kSignature, kSignatureLen) != 0) + return S_FALSE; + m_Stream = inStream; + return S_OK; +} + +static void MyStrNCpy(char *dest, const char *src, int size) +{ + for (int i = 0; i < size; i++) + { + char c = src[i]; + dest[i] = c; + if (c == 0) + break; + } +} + +static bool OctalToNumber(const char *s, int size, UInt64 &res) +{ + char sz[32]; + MyStrNCpy(sz, s, size); + sz[size] = 0; + const char *end; + int i; + for (i = 0; sz[i] == ' '; i++); + res = ConvertOctStringToUInt64(sz + i, &end); + return (*end == ' ' || *end == 0); +} + +static bool OctalToNumber32(const char *s, int size, UInt32 &res) +{ + UInt64 res64; + if (!OctalToNumber(s, size, res64)) + return false; + res = (UInt32)res64; + return (res64 <= 0xFFFFFFFF); +} + +static bool DecimalToNumber(const char *s, int size, UInt64 &res) +{ + char sz[32]; + MyStrNCpy(sz, s, size); + sz[size] = 0; + const char *end; + int i; + for (i = 0; sz[i] == ' '; i++); + res = ConvertStringToUInt64(sz + i, &end); + return (*end == ' ' || *end == 0); +} + +static bool DecimalToNumber32(const char *s, int size, UInt32 &res) +{ + UInt64 res64; + if (!DecimalToNumber(s, size, res64)) + return false; + res = (UInt32)res64; + return (res64 <= 0xFFFFFFFF); +} + +#define RIF(x) { if (!(x)) return S_FALSE; } + + +HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item) +{ + filled = false; + + char header[NHeader::kHeaderSize]; + const char *cur = header; + + UInt32 processedSize; + item.HeaderPosition = m_Position; + RINOK(ReadBytes(header, sizeof(header), processedSize)); + if (processedSize < sizeof(header)) + return S_OK; + + char tempString[kNameSize + 1]; + MyStrNCpy(tempString, cur, kNameSize); + cur += kNameSize; + tempString[kNameSize] = '\0'; + item.Name = tempString; + item.Name.Trim(); + + for (int i = 0; i < item.Name.Length(); i++) + if (((Byte)item.Name[i]) < 0x20) + return S_FALSE; + + RIF(DecimalToNumber32(cur, kTimeSize, item.ModificationTime)); + cur += kTimeSize; + + cur += 6 + 6; + + RIF(OctalToNumber32(cur, kModeSize, item.Mode)); + cur += kModeSize; + + RIF(DecimalToNumber(cur, kSizeSize, item.Size)); + cur += kSizeSize; + + filled = true; + return S_OK; +} + +HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) +{ + for (;;) + { + RINOK(GetNextItemReal(filled, item)); + if (!filled) + return S_OK; + if (item.Name.CompareNoCase("debian-binary") != 0) + return S_OK; + if (item.Size != 4) + return S_OK; + SkeepData(item.Size); + } +} + +HRESULT CInArchive::Skeep(UInt64 numBytes) +{ + UInt64 newPostion; + RINOK(m_Stream->Seek(numBytes, STREAM_SEEK_CUR, &newPostion)); + m_Position += numBytes; + if (m_Position != newPostion) + return E_FAIL; + return S_OK; +} + +HRESULT CInArchive::SkeepData(UInt64 dataSize) +{ + return Skeep((dataSize + 1) & (~((UInt64)0x1))); +} + +}} diff --git a/CPP/7zip/Archive/Deb/DebIn.h b/CPP/7zip/Archive/Deb/DebIn.h new file mode 100755 index 00000000..c1b72b6e --- /dev/null +++ b/CPP/7zip/Archive/Deb/DebIn.h @@ -0,0 +1,29 @@ +// Archive/DebIn.h + +#ifndef __ARCHIVE_DEB_IN_H +#define __ARCHIVE_DEB_IN_H + +#include "Common/MyCom.h" +#include "../../IStream.h" +#include "DebItem.h" + +namespace NArchive { +namespace NDeb { + +class CInArchive +{ + CMyComPtr m_Stream; + UInt64 m_Position; + + HRESULT ReadBytes(void *data, UInt32 size, UInt32 &processedSize); + HRESULT GetNextItemReal(bool &filled, CItemEx &itemInfo); + HRESULT Skeep(UInt64 numBytes); +public: + HRESULT Open(IInStream *inStream); + HRESULT GetNextItem(bool &filled, CItemEx &itemInfo); + HRESULT SkeepData(UInt64 dataSize); +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Deb/DebItem.h b/CPP/7zip/Archive/Deb/DebItem.h new file mode 100755 index 00000000..f587f3f5 --- /dev/null +++ b/CPP/7zip/Archive/Deb/DebItem.h @@ -0,0 +1,32 @@ +// Archive/Deb/ItemInfo.h + +#ifndef __ARCHIVE_DEB_ITEMINFO_H +#define __ARCHIVE_DEB_ITEMINFO_H + +#include "Common/Types.h" +#include "Common/String.h" +#include "DebHeader.h" + +namespace NArchive { +namespace NDeb { + +class CItem +{ +public: + AString Name; + UInt64 Size; + UInt32 ModificationTime; + UInt32 Mode; +}; + +class CItemEx: public CItem +{ +public: + UInt64 HeaderPosition; + UInt64 GetDataPosition() const { return HeaderPosition + NHeader::kHeaderSize; }; + // UInt64 GetFullSize() const { return NFileHeader::kRecordSize + Size; }; +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Deb/DllExports.cpp b/CPP/7zip/Archive/Deb/DllExports.cpp new file mode 100755 index 00000000..fe320531 --- /dev/null +++ b/CPP/7zip/Archive/Deb/DllExports.cpp @@ -0,0 +1,73 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "Windows/PropVariant.h" +#include "DebHandler.h" +#include "../../ICoder.h" + +// {23170F69-40C1-278A-1000-000110EC0000} +DEFINE_GUID(CLSID_CDebHandler, + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xEC, 0x00, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /*lpReserved*/) +{ + return TRUE; +} + +STDAPI CreateObject( + const GUID *classID, + const GUID *interfaceID, + void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + if (*classID != CLSID_CDebHandler) + return CLASS_E_CLASSNOTAVAILABLE; + if (*interfaceID != IID_IInArchive) + return E_NOINTERFACE; + CMyComPtr inArchive = (IInArchive *)new NArchive::NDeb::CHandler; + *outObject = inArchive.Detach(); + COM_TRY_END + return S_OK; +} + +STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case NArchive::kName: + propVariant = L"Deb"; + break; + case NArchive::kClassID: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CDebHandler, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NArchive::kExtension: + propVariant = L"deb"; + break; + case NArchive::kUpdate: + propVariant = false; + break; + case NArchive::kKeepName: + propVariant = false; + break; + case NArchive::kStartSignature: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)NArchive::NDeb::NHeader::kSignature, + NArchive::NDeb::NHeader::kSignatureLen)) != 0) + value->vt = VT_BSTR; + return S_OK; + } + } + propVariant.Detach(value); + return S_OK; +} diff --git a/CPP/7zip/Archive/Deb/StdAfx.cpp b/CPP/7zip/Archive/Deb/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Archive/Deb/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Deb/StdAfx.h b/CPP/7zip/Archive/Deb/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Archive/Deb/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Archive/Deb/deb.ico b/CPP/7zip/Archive/Deb/deb.ico new file mode 100755 index 00000000..97a08654 Binary files /dev/null and b/CPP/7zip/Archive/Deb/deb.ico differ diff --git a/CPP/7zip/Archive/Deb/makefile b/CPP/7zip/Archive/Deb/makefile new file mode 100755 index 00000000..a74f33de --- /dev/null +++ b/CPP/7zip/Archive/Deb/makefile @@ -0,0 +1,54 @@ +PROG = deb.dll +DEF_FILE = ../Archive.def +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib user32.lib + +DEB_OBJS = \ + $O\DllExports.obj \ + $O\DebHandler.obj \ + $O\DebHeader.obj \ + $O\DebIn.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\Vector.obj \ + +WIN_OBJS = \ + $O\PropVariant.obj \ + +7ZIP_COMMON_OBJS = \ + $O\LimitedStreams.obj \ + $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ + +AR_COMMON_OBJS = \ + $O\ItemNameUtils.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(DEB_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $O\CopyCoder.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(DEB_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/Archive/Deb/resource.rc b/CPP/7zip/Archive/Deb/resource.rc new file mode 100755 index 00000000..a80edced --- /dev/null +++ b/CPP/7zip/Archive/Deb/resource.rc @@ -0,0 +1,5 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("Deb Plugin", "deb") + +101 ICON "deb.ico" diff --git a/CPP/7zip/Archive/GZip/DllExports.cpp b/CPP/7zip/Archive/GZip/DllExports.cpp new file mode 100755 index 00000000..3bddcfb9 --- /dev/null +++ b/CPP/7zip/Archive/GZip/DllExports.cpp @@ -0,0 +1,125 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "Windows/PropVariant.h" +#include "../../ICoder.h" +#include "GZipHandler.h" + +// {23170F69-40C1-278A-1000-000110EF0000} +DEFINE_GUID(CLSID_CGZipHandler, +0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xEF, 0x00, 0x00); + +// {23170F69-40C1-278B-0401-080000000100} +DEFINE_GUID(CLSID_CCompressDeflateEncoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00); + +// {23170F69-40C1-278B-0401-080000000000} +DEFINE_GUID(CLSID_CCompressDeflateDecoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00); + +HINSTANCE g_hInstance; +#ifndef _UNICODE +bool g_IsNT = false; +static bool IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); +} +#endif + +#ifndef COMPRESS_DEFLATE +#include "../Common/CodecsPath.h" +CSysString GetDeflateCodecPath() +{ + return GetCodecsFolderPrefix() + TEXT("Deflate.dll"); +} +#endif + +extern "C" +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + g_hInstance = hInstance; + #ifndef _UNICODE + g_IsNT = IsItWindowsNT(); + #endif + } + return TRUE; +} + +STDAPI CreateObject( + const GUID *classID, + const GUID *interfaceID, + void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + if (*classID != CLSID_CGZipHandler) + return CLASS_E_CLASSNOTAVAILABLE; + int needIn = *interfaceID == IID_IInArchive; + int needOut = *interfaceID == IID_IOutArchive; + if (needIn || needOut) + { + NArchive::NGZip::CHandler *temp = new NArchive::NGZip::CHandler; + if (needIn) + { + CMyComPtr inArchive = (IInArchive *)temp; + *outObject = inArchive.Detach(); + } + else + { + CMyComPtr outArchive = (IOutArchive *)temp; + *outObject = outArchive.Detach(); + } + } + else + return E_NOINTERFACE; + COM_TRY_END + return S_OK; +} + +STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case NArchive::kName: + propVariant = L"GZip"; + break; + case NArchive::kClassID: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CGZipHandler, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NArchive::kExtension: + propVariant = L"gz gzip tgz tpz"; + break; + case NArchive::kAddExtension: + propVariant = L"* * .tar .tar"; + break; + case NArchive::kUpdate: + propVariant = true; + break; + case NArchive::kKeepName: + propVariant = true; + break; + case NArchive::kStartSignature: + { + const unsigned char sig[] = { 0x1F, 0x8B }; + if ((value->bstrVal = ::SysAllocStringByteLen((const char *)sig, 2)) != 0) + value->vt = VT_BSTR; + return S_OK; + } + } + propVariant.Detach(value); + return S_OK; +} diff --git a/CPP/7zip/Archive/GZip/GZip.dsp b/CPP/7zip/Archive/GZip/GZip.dsp new file mode 100755 index 00000000..3af06b46 --- /dev/null +++ b/CPP/7zip/Archive/GZip/GZip.dsp @@ -0,0 +1,321 @@ +# Microsoft Developer Studio Project File - Name="GZip" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=GZip - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "GZip.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "GZip.mak" CFG="GZip - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "GZip - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "GZip - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "GZip - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GZIP_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GZIP_EXPORTS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\gz.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "GZip - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GZIP_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GZIP_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\gz.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "GZip - Win32 Release" +# Name "GZip - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Archive.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\GZip.ico +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# End Group +# Begin Group "Compression" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\GZipHandler.cpp +# End Source File +# Begin Source File + +SOURCE=.\GZipHandler.h +# End Source File +# Begin Source File + +SOURCE=.\GZipHandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=.\GZipHeader.cpp +# End Source File +# Begin Source File + +SOURCE=.\GZipHeader.h +# End Source File +# Begin Source File + +SOURCE=.\GZipIn.cpp +# End Source File +# Begin Source File + +SOURCE=.\GZipIn.h +# End Source File +# Begin Source File + +SOURCE=.\GZipItem.h +# End Source File +# Begin Source File + +SOURCE=.\GZipOut.cpp +# End Source File +# Begin Source File + +SOURCE=.\GZipOut.h +# End Source File +# Begin Source File + +SOURCE=.\GZipUpdate.cpp +# End Source File +# Begin Source File + +SOURCE=.\GZipUpdate.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\CodecsPath.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\CodecsPath.h +# End Source File +# Begin Source File + +SOURCE=..\Common\CoderLoader.h +# End Source File +# Begin Source File + +SOURCE=..\Common\InStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\InStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\Common\OutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\OutStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ParseProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ParseProperties.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\gz.ico +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/Archive/GZip/GZip.dsw b/CPP/7zip/Archive/GZip/GZip.dsw new file mode 100755 index 00000000..5ff50d2c --- /dev/null +++ b/CPP/7zip/Archive/GZip/GZip.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "GZip"=.\GZip.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Archive/GZip/GZipHandler.cpp b/CPP/7zip/Archive/GZip/GZipHandler.cpp new file mode 100755 index 00000000..ff592324 --- /dev/null +++ b/CPP/7zip/Archive/GZip/GZipHandler.cpp @@ -0,0 +1,361 @@ +// GZipHandler.cpp + +#include "StdAfx.h" + +#include "GZipHandler.h" + +#include "Common/Defs.h" +#include "Common/CRC.h" +#include "Common/StringConvert.h" +#include "Common/ComTry.h" +#include "Windows/PropVariant.h" +#include "Windows/Time.h" + +#include "../../ICoder.h" +#include "../../Common/ProgressUtils.h" +#include "../Common/OutStreamWithCRC.h" + +#ifdef COMPRESS_DEFLATE +#include "../../Compress/Deflate/DeflateDecoder.h" +#else +// {23170F69-40C1-278B-0401-080000000000} +DEFINE_GUID(CLSID_CCompressDeflateDecoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00); +#include "../Common/CoderLoader.h" +extern CSysString GetDeflateCodecPath(); +#endif + +using namespace NWindows; + +namespace NArchive { +namespace NGZip { + +const wchar_t *kHostOS[] = +{ + L"FAT", + L"AMIGA", + L"VMS", + L"Unix", + L"VM_CMS", + L"Atari", // what if it's a minix filesystem? [cjh] + L"HPFS", // filesystem used by OS/2 (and NT 3.x) + L"Mac", + L"Z_System", + L"CPM", + L"TOPS20", // pkzip 2.50 NTFS + L"NTFS", // filesystem used by Windows NT + L"QDOS ", // SMS/QDOS + L"Acorn", // Archimedes Acorn RISC OS + L"VFAT", // filesystem used by Windows 95, NT + L"MVS", + L"BeOS", // hybrid POSIX/database filesystem + // BeBOX or PowerMac + L"Tandem", + L"THEOS" +}; + +static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]); + +static const wchar_t *kUnknownOS = L"Unknown"; + +/* +enum // PropID +{ + kpidExtraIsPresent = kpidUserDefined, + kpidExtraFlags, + kpidIsText +}; +*/ + +STATPROPSTG kProperties[] = +{ + { NULL, kpidPath, VT_BSTR}, + // { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackedSize, VT_UI8}, + + { NULL, kpidLastWriteTime, VT_FILETIME}, + // { NULL, kpidCommented, VT_BOOL}, + // { NULL, kpidMethod, VT_UI1}, + { NULL, kpidHostOS, VT_BSTR}, + + { NULL, kpidCRC, VT_UI4} + // { L"Extra", kpidExtraIsPresent, VT_BOOL} + // { L"Extra flags", kpidExtraFlags, VT_UI1}, + // { L"Is Text", kpidIsText, VT_BOOL}, +}; + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) +{ + value->vt = VT_EMPTY; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + const STATPROPSTG &prop = kProperties[index]; + *propID = prop.propid; + *varType = prop.vt; + *name = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +{ + *numProperties = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, + BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = 1; + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case kpidPath: + if (m_Item.NameIsPresent()) + propVariant = MultiByteToUnicodeString(m_Item.Name, CP_ACP); + break; + case kpidIsFolder: + propVariant = false; + break; + case kpidLastWriteTime: + { + FILETIME utcTime; + if (m_Item.Time != 0) + { + NTime::UnixTimeToFileTime((UInt32)m_Item.Time, utcTime); + propVariant = utcTime; + } + else + { + // utcTime.dwLowDateTime = utcTime.dwHighDateTime = 0; + // propVariant = utcTime; + } + break; + } + case kpidSize: + propVariant = UInt64(m_Item.UnPackSize32); + break; + case kpidPackedSize: + propVariant = m_PackSize; + break; + case kpidCommented: + propVariant = m_Item.CommentIsPresent(); + break; + case kpidHostOS: + propVariant = (m_Item.HostOS < kNumHostOSes) ? + kHostOS[m_Item.HostOS] : kUnknownOS; + break; + case kpidMethod: + propVariant = m_Item.CompressionMethod; + break; + case kpidCRC: + propVariant = m_Item.FileCRC; + break; + /* + case kpidExtraFlags: + propVariant = m_Item.ExtraFlags; + break; + case kpidIsText: + propVariant = m_Item.IsText(); + break; + case kpidExtraIsPresent: + propVariant = m_Item.ExtraFieldIsPresent(); + break; + */ + } + propVariant.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Open(IInStream *inStream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */) +{ + COM_TRY_BEGIN + try + { + CInArchive archive; + RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition)); + RINOK(archive.ReadHeader(inStream, m_Item)); + m_DataOffset = archive.GetOffset(); + UInt64 newPosition; + RINOK(inStream->Seek(-8, STREAM_SEEK_END, &newPosition)); + m_PackSize = newPosition - (m_StreamStartPosition + m_DataOffset); + if (archive.ReadPostHeader(inStream, m_Item) != S_OK) + return S_FALSE; + m_Stream = inStream; + } + catch(...) + { + return S_FALSE; + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + m_Stream.Release(); + return S_OK; +} + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool allFilesMode = (numItems == UInt32(-1)); + if (!allFilesMode) + { + if (numItems == 0) + return S_OK; + if (numItems != 1) + return E_INVALIDARG; + if (indices[0] != 0) + return E_INVALIDARG; + } + + bool testMode = (_aTestMode != 0); + + extractCallback->SetTotal(m_PackSize); + + UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0; + + RINOK(extractCallback->SetCompleted(¤tTotalPacked)); + CMyComPtr 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 outStream(outStreamSpec); + outStreamSpec->SetStream(realOutStream); + outStreamSpec->Init(); + realOutStream.Release(); + + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr progress = localProgressSpec; + localProgressSpec->Init(extractCallback, true); + + CLocalCompressProgressInfo *localCompressProgressSpec = + new CLocalCompressProgressInfo; + CMyComPtr compressProgress = localCompressProgressSpec; + + #ifndef COMPRESS_DEFLATE + CCoderLibrary lib; + #endif + CMyComPtr deflateDecoder; + bool firstItem = true; + RINOK(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL)); + for (;;) + { + localCompressProgressSpec->Init(progress, + ¤tTotalPacked, + ¤tTotalUnPacked); + + CInArchive archive; + CItem item; + HRESULT result = archive.ReadHeader(m_Stream, item); + if (result != S_OK) + { + if (firstItem) + return E_FAIL; + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)) + return S_OK; + } + firstItem = false; + + UInt64 dataStartPos; + RINOK(m_Stream->Seek(0, STREAM_SEEK_CUR, &dataStartPos)); + + outStreamSpec->InitCRC(); + + switch(item.CompressionMethod) + { + case NFileHeader::NCompressionMethod::kDeflate: + { + if(!deflateDecoder) + { + #ifdef COMPRESS_DEFLATE + deflateDecoder = new NCompress::NDeflate::NDecoder::CCOMCoder; + #else + RINOK(lib.LoadAndCreateCoder(GetDeflateCodecPath(), + CLSID_CCompressDeflateDecoder, &deflateDecoder)); + #endif + } + try + { + HRESULT result = deflateDecoder->Code(m_Stream, outStream, NULL, NULL, compressProgress); + if (result == S_FALSE) + throw "data error"; + if (result != S_OK) + return result; + } + catch(...) + { + outStream.Release(); + RINOK(extractCallback->SetOperationResult( + NArchive::NExtract::NOperationResult::kDataError)); + return S_OK; + } + break; + } + default: + outStream.Release(); + RINOK(extractCallback->SetOperationResult( + NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + return S_OK; + } + CMyComPtr getInStreamProcessedSize; + RINOK(deflateDecoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, + &getInStreamProcessedSize)); + UInt64 packSize; + RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&packSize)); + UInt64 pos; + RINOK(m_Stream->Seek(dataStartPos + packSize, STREAM_SEEK_SET, &pos)); + + currentTotalPacked = pos - m_StreamStartPosition; + + CItem postItem; + if (archive.ReadPostHeader(m_Stream, postItem) != S_OK) + return E_FAIL; + if((outStreamSpec->GetCRC() != postItem.FileCRC)) + { + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError)) + break; + } + } + COM_TRY_END + return S_OK; +} + +}} diff --git a/CPP/7zip/Archive/GZip/GZipHandler.h b/CPP/7zip/Archive/GZip/GZipHandler.h new file mode 100755 index 00000000..9af7e4a4 --- /dev/null +++ b/CPP/7zip/Archive/GZip/GZipHandler.h @@ -0,0 +1,79 @@ +// GZip/Handler.h + +#ifndef __GZIP_HANDLER_H +#define __GZIP_HANDLER_H + +#include "Common/MyCom.h" + +#include "../IArchive.h" + +#include "GZipIn.h" +#include "GZipUpdate.h" + +namespace NArchive { +namespace NGZip { + +class CHandler: + public IInArchive, + public IOutArchive, + public ISetProperties, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP3( + IInArchive, + IOutArchive, + ISetProperties) + + STDMETHOD(Open)(IInStream *inStream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback); + STDMETHOD(Close)(); + + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); + + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + // IOutArchive + + STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback); + + STDMETHOD(GetFileTimeType)(UInt32 *timeType); + + // ISetProperties + STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties); + +public: + CHandler() { InitMethodProperties(); } + +private: + NArchive::NGZip::CItem m_Item; + UInt64 m_StreamStartPosition; + UInt64 m_DataOffset; + UInt64 m_PackSize; + CMyComPtr m_Stream; + CCompressionMethodMode m_Method; + UInt32 m_Level; + + void InitMethodProperties() + { + m_Method.NumMatchFinderCyclesDefined = false; + m_Level = m_Method.NumPasses = m_Method.NumFastBytes = m_Method.NumMatchFinderCycles = 0xFFFFFFFF; + } +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/GZip/GZipHandlerOut.cpp b/CPP/7zip/Archive/GZip/GZipHandlerOut.cpp new file mode 100755 index 00000000..cc896016 --- /dev/null +++ b/CPP/7zip/Archive/GZip/GZipHandlerOut.cpp @@ -0,0 +1,200 @@ +// Archive/GZip/OutHandler.cpp + +#include "StdAfx.h" + +#include "GZipHandler.h" +#include "GZipUpdate.h" + +#include "Common/StringConvert.h" +#include "Common/StringToInt.h" + +#include "Windows/Time.h" +#include "Windows/FileFind.h" +#include "Windows/PropVariant.h" + +#include "../../Compress/Copy/CopyCoder.h" +#include "../Common/ParseProperties.h" + +using namespace NWindows; +using namespace NTime; + +namespace NArchive { +namespace NGZip { + +static const UInt32 kNumPassesX1 = 1; +static const UInt32 kNumPassesX7 = 3; +static const UInt32 kNumPassesX9 = 10; + +static const UInt32 kNumFastBytesX1 = 32; +static const UInt32 kNumFastBytesX7 = 64; +static const UInt32 kNumFastBytesX9 = 128; + + +STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType) +{ + *timeType = NFileTimeType::kUnix; + return S_OK; +} + +static HRESULT CopyStreams(ISequentialInStream *inStream, ISequentialOutStream *outStream) +{ + CMyComPtr copyCoder = new NCompress::CCopyCoder; + return copyCoder->Code(inStream, outStream, NULL, NULL, NULL); +} + +STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback) +{ + if (numItems != 1) + return E_INVALIDARG; + + UInt64 size; + Int32 newData; + Int32 newProperties; + UInt32 indexInArchive; + UInt32 itemIndex = 0; + if (!updateCallback) + return E_FAIL; + RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProperties, &indexInArchive)); + + CItem newItem = m_Item; + newItem.ExtraFlags = 0; + newItem.Flags = 0; + if (IntToBool(newProperties)) + { + UInt32 attributes; + FILETIME utcTime; + UString name; + bool isDirectory; + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(itemIndex, kpidAttributes, &propVariant)); + if (propVariant.vt == VT_EMPTY) + attributes = 0; + else if (propVariant.vt != VT_UI4) + return E_INVALIDARG; + else + attributes = propVariant.ulVal; + } + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(itemIndex, kpidLastWriteTime, &propVariant)); + if (propVariant.vt != VT_FILETIME) + return E_INVALIDARG; + utcTime = propVariant.filetime; + } + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(itemIndex, kpidPath, &propVariant)); + if (propVariant.vt == VT_EMPTY) + name.Empty(); + else if (propVariant.vt != VT_BSTR) + return E_INVALIDARG; + else + name = propVariant.bstrVal; + } + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(itemIndex, kpidIsFolder, &propVariant)); + if (propVariant.vt == VT_EMPTY) + isDirectory = false; + else if (propVariant.vt != VT_BOOL) + return E_INVALIDARG; + else + isDirectory = (propVariant.boolVal != VARIANT_FALSE); + } + if (isDirectory || NFile::NFind::NAttributes::IsDirectory(attributes)) + return E_INVALIDARG; + if(!FileTimeToUnixTime(utcTime, newItem.Time)) + return E_INVALIDARG; + newItem.Name = UnicodeStringToMultiByte(name, CP_ACP); + int dirDelimiterPos = newItem.Name.ReverseFind(CHAR_PATH_SEPARATOR); + if (dirDelimiterPos >= 0) + newItem.Name = newItem.Name.Mid(dirDelimiterPos + 1); + + newItem.SetNameIsPresentFlag(!newItem.Name.IsEmpty()); + } + + if (IntToBool(newData)) + { + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(itemIndex, kpidSize, &propVariant)); + if (propVariant.vt != VT_UI8) + return E_INVALIDARG; + size = propVariant.uhVal.QuadPart; + } + newItem.UnPackSize32 = (UInt32)size; + + UInt32 level = m_Level; + if (level == 0xFFFFFFFF) + level = 5; + if (m_Method.NumPasses == 0xFFFFFFFF) + m_Method.NumPasses = (level >= 9 ? kNumPassesX9 : + (level >= 7 ? kNumPassesX7 : + kNumPassesX1)); + if (m_Method.NumFastBytes == 0xFFFFFFFF) + m_Method.NumFastBytes = (level >= 9 ? kNumFastBytesX9 : + (level >= 7 ? kNumFastBytesX7 : + kNumFastBytesX1)); + + return UpdateArchive(m_Stream, size, outStream, newItem, m_Method, itemIndex, updateCallback); + } + + if (indexInArchive != 0) + return E_INVALIDARG; + + if (IntToBool(newProperties)) + { + COutArchive outArchive; + outArchive.Create(outStream); + outArchive.WriteHeader(newItem); + RINOK(m_Stream->Seek(m_StreamStartPosition + m_DataOffset, STREAM_SEEK_SET, NULL)); + } + else + { + RINOK(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL)); + } + return CopyStreams(m_Stream, outStream); +} + +STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) +{ + InitMethodProperties(); + for (int i = 0; i < numProperties; i++) + { + UString name = names[i]; + name.MakeUpper(); + const PROPVARIANT &prop = values[i]; + if (name[0] == L'X') + { + UInt32 level = 9; + RINOK(ParsePropValue(name.Mid(1), prop, level)); + m_Level = level; + } + else if (name.Left(4) == L"PASS") + { + UInt32 num = kNumPassesX9; + RINOK(ParsePropValue(name.Mid(4), prop, num)); + m_Method.NumPasses = num; + } + else if (name.Left(2) == L"FB") + { + UInt32 num = kNumFastBytesX9; + RINOK(ParsePropValue(name.Mid(2), prop, num)); + m_Method.NumFastBytes = num; + } + else if (name.Left(2) == L"MC") + { + UInt32 num = 0xFFFFFFFF; + RINOK(ParsePropValue(name.Mid(2), prop, num)); + m_Method.NumMatchFinderCycles = num; + m_Method.NumMatchFinderCyclesDefined = true; + } + else + return E_INVALIDARG; + } + return S_OK; +} + +}} diff --git a/CPP/7zip/Archive/GZip/GZipHeader.cpp b/CPP/7zip/Archive/GZip/GZipHeader.cpp new file mode 100755 index 00000000..5e697fa9 --- /dev/null +++ b/CPP/7zip/Archive/GZip/GZipHeader.cpp @@ -0,0 +1,20 @@ +// Archive/GZip/Header.h + +#include "StdAfx.h" + +#include "GZipHeader.h" + +namespace NArchive { +namespace NGZip { + +extern UInt16 kSignature = 0x8B1F + 1; + +static class CMarkersInitializer +{ +public: + CMarkersInitializer() + { kSignature--; } +} g_MarkerInitializer; + +}} + diff --git a/CPP/7zip/Archive/GZip/GZipHeader.h b/CPP/7zip/Archive/GZip/GZipHeader.h new file mode 100755 index 00000000..e83548eb --- /dev/null +++ b/CPP/7zip/Archive/GZip/GZipHeader.h @@ -0,0 +1,85 @@ +// Archive/GZip/Header.h + +#ifndef __ARCHIVE_GZIP_HEADER_H +#define __ARCHIVE_GZIP_HEADER_H + +#include "Common/Types.h" + +namespace NArchive { +namespace NGZip { + +extern UInt16 kSignature; +static const UInt32 kSignatureSize = 2; + +namespace NFileHeader +{ + /* + struct CBlock + { + UInt16 Id; + Byte CompressionMethod; + Byte Flags; + UInt32 Time; + Byte ExtraFlags; + Byte HostOS; + }; + */ + + namespace NFlags + { + const int kDataIsText = 1 << 0; + const int kHeaderCRCIsPresent = 1 << 1; + const int kExtraIsPresent = 1 << 2; + const int kNameIsPresent = 1 << 3; + const int kComentIsPresent = 1 << 4; + } + + namespace NExtraFlags + { + enum EEnum + { + kMaximum = 2, + kFastest = 4 + }; + } + + namespace NCompressionMethod + { + const Byte kDeflate = 8; + } + + namespace NHostOS + { + enum EEnum + { + kFAT = 0, // filesystem used by MS-DOS, OS/2, Win32 + // pkzip 2.50 (FAT / VFAT / FAT32 file systems) + kAMIGA = 1, + kVMS = 2, // VAX/VMS + kUnix = 3, + kVM_CMS = 4, + kAtari = 5, // what if it's a minix filesystem? [cjh] + kHPFS = 6, // filesystem used by OS/2 (and NT 3.x) + kMac = 7, + kZ_System = 8, + kCPM = 9, + kTOPS20 = 10, // pkzip 2.50 NTFS + kNTFS = 11, // filesystem used by Windows NT + kQDOS = 12, // SMS/QDOS + kAcorn = 13, // Archimedes Acorn RISC OS + kVFAT = 14, // filesystem used by Windows 95, NT + kMVS = 15, + kBeOS = 16, // hybrid POSIX/database filesystem + // BeBOX or PowerMac + kTandem = 17, + kTHEOS = 18, + + kUnknown = 255 + }; + const int kNumHostSystems = 19; + } +} + +}} + +#endif diff --git a/CPP/7zip/Archive/GZip/GZipIn.cpp b/CPP/7zip/Archive/GZip/GZipIn.cpp new file mode 100755 index 00000000..2b16d369 --- /dev/null +++ b/CPP/7zip/Archive/GZip/GZipIn.cpp @@ -0,0 +1,121 @@ +// Archive/GZipIn.cpp + +#include "StdAfx.h" + +#include "GZipIn.h" + +#include "Common/Defs.h" +#include "Common/MyCom.h" +#include "Windows/Defs.h" + +#include "../../Common/StreamUtils.h" + +namespace NArchive { +namespace NGZip { + +HRESULT CInArchive::ReadBytes(ISequentialInStream *inStream, void *data, UInt32 size) +{ + UInt32 realProcessedSize; + RINOK(ReadStream(inStream, data, size, &realProcessedSize)); + m_Position += realProcessedSize; + if(realProcessedSize != size) + return S_FALSE; + return S_OK; +} + +HRESULT CInArchive::ReadByte(ISequentialInStream *inStream, Byte &value) +{ + return ReadBytes(inStream, &value, 1); +} + +HRESULT CInArchive::ReadUInt16(ISequentialInStream *inStream, UInt16 &value) +{ + value = 0; + for (int i = 0; i < 2; i++) + { + Byte b; + RINOK(ReadByte(inStream, b)); + value |= (UInt16(b) << (8 * i)); + } + return S_OK; +} + +HRESULT CInArchive::ReadUInt32(ISequentialInStream *inStream, UInt32 &value) +{ + value = 0; + for (int i = 0; i < 4; i++) + { + Byte b; + RINOK(ReadByte(inStream, b)); + value |= (UInt32(b) << (8 * i)); + } + return S_OK; +} + +HRESULT CInArchive::ReadZeroTerminatedString(ISequentialInStream *inStream, AString &resString, CCRC &crc) +{ + resString.Empty(); + for (;;) + { + Byte c; + RINOK(ReadByte(inStream, c)); + crc.UpdateByte(c); + if (c == 0) + return S_OK; + resString += char(c); + } +} + +HRESULT CInArchive::ReadHeader(ISequentialInStream *inStream, CItem &item) +{ + item.Clear(); + m_Position = 0; + + UInt16 signature; + RINOK(ReadUInt16(inStream, signature)); + if (signature != kSignature) + return S_FALSE; + RINOK(ReadByte(inStream, item.CompressionMethod)); + RINOK(ReadByte(inStream, item.Flags)); + RINOK(ReadUInt32(inStream, item.Time)); + RINOK(ReadByte(inStream, item.ExtraFlags)); + RINOK(ReadByte(inStream, item.HostOS)); + + CCRC crc; + crc.Update(&signature, 2); + crc.UpdateByte(item.CompressionMethod); + crc.UpdateByte(item.Flags); + crc.UpdateUInt32(item.Time); + crc.UpdateByte(item.ExtraFlags); + crc.UpdateByte(item.HostOS); + + if (item.ExtraFieldIsPresent()) + { + UInt16 extraSize; + RINOK(ReadUInt16(inStream, extraSize)); + crc.UpdateUInt16(extraSize); + item.Extra.SetCapacity(extraSize); + RINOK(ReadBytes(inStream, item.Extra, extraSize)); + crc.Update(item.Extra, extraSize); + } + if (item.NameIsPresent()) + RINOK(ReadZeroTerminatedString(inStream, item.Name, crc)); + if (item.CommentIsPresent()) + RINOK(ReadZeroTerminatedString(inStream, item.Comment, crc)); + if (item.HeaderCRCIsPresent()) + { + UInt16 headerCRC; + RINOK(ReadUInt16(inStream, headerCRC)); + if ((UInt16)crc.GetDigest() != headerCRC) + return S_FALSE; + } + return S_OK; +} + +HRESULT CInArchive::ReadPostHeader(ISequentialInStream *inStream, CItem &item) +{ + RINOK(ReadUInt32(inStream, item.FileCRC)); + return ReadUInt32(inStream, item.UnPackSize32); +} + +}} diff --git a/CPP/7zip/Archive/GZip/GZipIn.h b/CPP/7zip/Archive/GZip/GZipIn.h new file mode 100755 index 00000000..998470e0 --- /dev/null +++ b/CPP/7zip/Archive/GZip/GZipIn.h @@ -0,0 +1,31 @@ +// Archive/GZipIn.h + +#ifndef __ARCHIVE_GZIP_IN_H +#define __ARCHIVE_GZIP_IN_H + +#include "GZipHeader.h" +#include "GZipItem.h" +#include "Common/CRC.h" +#include "../../IStream.h" + +namespace NArchive { +namespace NGZip { + +class CInArchive +{ + UInt64 m_Position; + + HRESULT ReadBytes(ISequentialInStream *inStream, void *data, UInt32 size); + HRESULT ReadZeroTerminatedString(ISequentialInStream *inStream, AString &resString, CCRC &crc); + HRESULT ReadByte(ISequentialInStream *inStream, Byte &value); + HRESULT ReadUInt16(ISequentialInStream *inStream, UInt16 &value); + HRESULT ReadUInt32(ISequentialInStream *inStream, UInt32 &value); +public: + HRESULT ReadHeader(ISequentialInStream *inStream, CItem &item); + HRESULT ReadPostHeader(ISequentialInStream *inStream, CItem &item); + UInt64 GetOffset() const { return m_Position; } +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/GZip/GZipItem.h b/CPP/7zip/Archive/GZip/GZipItem.h new file mode 100755 index 00000000..7006dfb3 --- /dev/null +++ b/CPP/7zip/Archive/GZip/GZipItem.h @@ -0,0 +1,59 @@ +// Archive/GZipItem.h + +#ifndef __ARCHIVE_GZIP_ITEM_H +#define __ARCHIVE_GZIP_ITEM_H + +#include "Common/Types.h" +#include "Common/String.h" +#include "Common/Buffer.h" + +namespace NArchive { +namespace NGZip { + +class CItem +{ +private: + bool TestFlag(Byte flag) const { return ((Flags & flag) != 0); } +public: + Byte CompressionMethod; + Byte Flags; + UInt32 Time; + Byte ExtraFlags; + Byte HostOS; + UInt32 FileCRC; + UInt32 UnPackSize32; + + AString Name; + AString Comment; + CByteBuffer Extra; + + bool IsText() const + { return TestFlag(NFileHeader::NFlags::kDataIsText); } + bool HeaderCRCIsPresent() const + { return TestFlag(NFileHeader::NFlags::kHeaderCRCIsPresent); } + bool ExtraFieldIsPresent() const + { return TestFlag(NFileHeader::NFlags::kExtraIsPresent); } + bool NameIsPresent() const + { return TestFlag(NFileHeader::NFlags::kNameIsPresent); } + bool CommentIsPresent() const + { return TestFlag(NFileHeader::NFlags::kComentIsPresent); } + + void SetNameIsPresentFlag(bool nameIsPresent) + { + if (nameIsPresent) + Flags |= NFileHeader::NFlags::kNameIsPresent; + else + Flags &= (~NFileHeader::NFlags::kNameIsPresent); + } + + void Clear() + { + Name.Empty(); + Comment.Empty();; + Extra.SetCapacity(0); + } +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/GZip/GZipOut.cpp b/CPP/7zip/Archive/GZip/GZipOut.cpp new file mode 100755 index 00000000..afa8a931 --- /dev/null +++ b/CPP/7zip/Archive/GZip/GZipOut.cpp @@ -0,0 +1,69 @@ +// Archive/GZipOut.cpp + +#include "StdAfx.h" + +#include "GZipOut.h" +#include "Common/CRC.h" +#include "Windows/Defs.h" +#include "../../Common/StreamUtils.h" + +namespace NArchive { +namespace NGZip { + +HRESULT COutArchive::WriteBytes(const void *buffer, UInt32 size) +{ + UInt32 processedSize; + RINOK(WriteStream(m_Stream, buffer, size, &processedSize)); + if(processedSize != size) + return E_FAIL; + return S_OK; +} + +HRESULT COutArchive::WriteByte(Byte value) +{ + return WriteBytes(&value, 1); +} + +HRESULT COutArchive::WriteUInt16(UInt16 value) +{ + for (int i = 0; i < 2; i++) + { + RINOK(WriteByte((Byte)value)); + value >>= 8; + } + return S_OK; +} + +HRESULT COutArchive::WriteUInt32(UInt32 value) +{ + for (int i = 0; i < 4; i++) + { + RINOK(WriteByte((Byte)value)); + value >>= 8; + } + return S_OK; +} + +HRESULT COutArchive::WriteHeader(const CItem &item) +{ + RINOK(WriteUInt16(kSignature)); + RINOK(WriteByte(item.CompressionMethod)); + RINOK(WriteByte((Byte)(item.Flags & NFileHeader::NFlags::kNameIsPresent))); + RINOK(WriteUInt32(item.Time)); + RINOK(WriteByte(item.ExtraFlags)); + RINOK(WriteByte(item.HostOS)); + if (item.NameIsPresent()) + { + RINOK(WriteBytes((const char *)item.Name, item.Name.Length())); + RINOK(WriteByte(0)); + } + return S_OK; +} + +HRESULT COutArchive::WritePostHeader(const CItem &item) +{ + RINOK(WriteUInt32(item.FileCRC)); + return WriteUInt32(item.UnPackSize32); +} + +}} diff --git a/CPP/7zip/Archive/GZip/GZipOut.h b/CPP/7zip/Archive/GZip/GZipOut.h new file mode 100755 index 00000000..a2ba2ebf --- /dev/null +++ b/CPP/7zip/Archive/GZip/GZipOut.h @@ -0,0 +1,29 @@ +// Archive/GZipOut.h + +#ifndef __ARCHIVE_GZIP_OUT_H +#define __ARCHIVE_GZIP_OUT_H + +#include "Common/MyCom.h" +#include "GZipHeader.h" +#include "GZipItem.h" +#include "../../IStream.h" + +namespace NArchive { +namespace NGZip { + +class COutArchive +{ + CMyComPtr m_Stream; + HRESULT WriteBytes(const void *buffer, UInt32 size); + HRESULT WriteByte(Byte value); + HRESULT WriteUInt16(UInt16 value); + HRESULT WriteUInt32(UInt32 value); +public: + void Create(ISequentialOutStream *outStream) { m_Stream = outStream; } + HRESULT WriteHeader(const CItem &item); + HRESULT WritePostHeader(const CItem &item); +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/GZip/GZipUpdate.cpp b/CPP/7zip/Archive/GZip/GZipUpdate.cpp new file mode 100755 index 00000000..45e6e985 --- /dev/null +++ b/CPP/7zip/Archive/GZip/GZipUpdate.cpp @@ -0,0 +1,120 @@ +// GZipUpdate.cpp + +#include "StdAfx.h" + +#include "GZipUpdate.h" + +#include "Common/Defs.h" +#include "Common/StringConvert.h" + +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" + +#include "../../ICoder.h" +#include "../../Common/ProgressUtils.h" +#include "../../Compress/Copy/CopyCoder.h" + +#include "../Common/InStreamWithCRC.h" + +#ifdef COMPRESS_DEFLATE +#include "../../Compress/Deflate/DeflateEncoder.h" +#else +// {23170F69-40C1-278B-0401-080000000100} +DEFINE_GUID(CLSID_CCompressDeflateEncoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00); +#include "../Common/CoderLoader.h" +extern CSysString GetDeflateCodecPath(); +#endif + +namespace NArchive { +namespace NGZip { + +static const Byte kHostOS = NFileHeader::NHostOS::kFAT; + +HRESULT UpdateArchive(IInStream * /* inStream */, + UInt64 unpackSize, + ISequentialOutStream *outStream, + const CItem &newItem, + const CCompressionMethodMode &compressionMethod, + int indexInClient, + IArchiveUpdateCallback *updateCallback) +{ + UInt64 complexity = 0; + + complexity += unpackSize; + + RINOK(updateCallback->SetTotal(complexity)); + + #ifndef COMPRESS_DEFLATE + CCoderLibrary lib; + #endif + CMyComPtr deflateEncoder; + + complexity = 0; + RINOK(updateCallback->SetCompleted(&complexity)); + + CMyComPtr fileInStream; + + RINOK(updateCallback->GetStream(indexInClient, &fileInStream)); + + CSequentialInStreamWithCRC *inStreamSpec = new CSequentialInStreamWithCRC; + CMyComPtr crcStream(inStreamSpec); + inStreamSpec->SetStream(fileInStream); + inStreamSpec->Init(); + + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr localProgress = localProgressSpec; + localProgressSpec->Init(updateCallback, true); + + CLocalCompressProgressInfo *localCompressProgressSpec = + new CLocalCompressProgressInfo; + CMyComPtr compressProgress = localCompressProgressSpec; + + COutArchive outArchive; + outArchive.Create(outStream); + + CItem item = newItem; + item.CompressionMethod = NFileHeader::NCompressionMethod::kDeflate; + item.ExtraFlags = 0; + item.HostOS = kHostOS; + + RINOK(outArchive.WriteHeader(item)); + + localCompressProgressSpec->Init(localProgress, &complexity, NULL); + + { + #ifdef COMPRESS_DEFLATE + deflateEncoder = new NCompress::NDeflate::NEncoder::CCOMCoder; + #else + RINOK(lib.LoadAndCreateCoder(GetDeflateCodecPath(), + CLSID_CCompressDeflateEncoder, &deflateEncoder)); + #endif + + NWindows::NCOM::CPropVariant properties[] = + { + compressionMethod.NumPasses, + compressionMethod.NumFastBytes, + compressionMethod.NumMatchFinderCycles + }; + PROPID propIDs[] = + { + NCoderPropID::kNumPasses, + NCoderPropID::kNumFastBytes, + NCoderPropID::kMatchFinderCycles + }; + int numProps = sizeof(propIDs) / sizeof(propIDs[0]); + if (!compressionMethod.NumMatchFinderCyclesDefined) + numProps--; + CMyComPtr setCoderProperties; + RINOK(deflateEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties)); + RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, numProps)); + } + RINOK(deflateEncoder->Code(crcStream, outStream, NULL, NULL, compressProgress)); + + item.FileCRC = inStreamSpec->GetCRC(); + item.UnPackSize32 = (UInt32)inStreamSpec->GetSize(); + RINOK(outArchive.WritePostHeader(item)); + return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK); +} + +}} diff --git a/CPP/7zip/Archive/GZip/GZipUpdate.h b/CPP/7zip/Archive/GZip/GZipUpdate.h new file mode 100755 index 00000000..c06e8a4c --- /dev/null +++ b/CPP/7zip/Archive/GZip/GZipUpdate.h @@ -0,0 +1,32 @@ +// GZip/Update.h + +#ifndef __GZIP_UPDATE_H +#define __GZIP_UPDATE_H + +#include "../IArchive.h" + +#include "GZipOut.h" +#include "GZipItem.h" + +namespace NArchive { +namespace NGZip { + +struct CCompressionMethodMode +{ + UInt32 NumPasses; + UInt32 NumFastBytes; + bool NumMatchFinderCyclesDefined; + UInt32 NumMatchFinderCycles; +}; + +HRESULT UpdateArchive(IInStream *inStream, + UInt64 unpackSize, + ISequentialOutStream *outStream, + const CItem &newItem, + const CCompressionMethodMode &compressionMethod, + int indexInClient, + IArchiveUpdateCallback *updateCallback); + +}} + +#endif diff --git a/CPP/7zip/Archive/GZip/StdAfx.cpp b/CPP/7zip/Archive/GZip/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Archive/GZip/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Archive/GZip/StdAfx.h b/CPP/7zip/Archive/GZip/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Archive/GZip/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Archive/GZip/gz.ico b/CPP/7zip/Archive/GZip/gz.ico new file mode 100755 index 00000000..f50d8c08 Binary files /dev/null and b/CPP/7zip/Archive/GZip/gz.ico differ diff --git a/CPP/7zip/Archive/GZip/makefile b/CPP/7zip/Archive/GZip/makefile new file mode 100755 index 00000000..abc3f1e4 --- /dev/null +++ b/CPP/7zip/Archive/GZip/makefile @@ -0,0 +1,60 @@ +PROG = gz.dll +DEF_FILE = ../Archive.def +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib user32.lib + +GZ_OBJS = \ + $O\GZipHandler.obj \ + $O\GZipHandlerOut.obj \ + $O\GZipHeader.obj \ + $O\GZipIn.obj \ + $O\GZipOut.obj \ + $O\GZipUpdate.obj \ + $O\DllExports.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CRC.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\PropVariant.obj \ + +7ZIP_COMMON_OBJS = \ + $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ + +AR_COMMON_OBJS = \ + $O\CodecsPath.obj \ + $O\InStreamWithCRC.obj \ + $O\OutStreamWithCRC.obj \ + $O\ParseProperties.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(GZ_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $O\CopyCoder.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(GZ_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/Archive/GZip/resource.rc b/CPP/7zip/Archive/GZip/resource.rc new file mode 100755 index 00000000..29fb4825 --- /dev/null +++ b/CPP/7zip/Archive/GZip/resource.rc @@ -0,0 +1,5 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("GZip Plugin", "gz") + +101 ICON "gz.ico" diff --git a/CPP/7zip/Archive/IArchive.h b/CPP/7zip/Archive/IArchive.h new file mode 100755 index 00000000..d6cbe804 --- /dev/null +++ b/CPP/7zip/Archive/IArchive.h @@ -0,0 +1,173 @@ +// IArchive.h + +#ifndef __IARCHIVE_H +#define __IARCHIVE_H + +#include "../IStream.h" +#include "../IProgress.h" +#include "../PropID.h" + +// MIDL_INTERFACE("23170F69-40C1-278A-0000-000600xx0000") +#define ARCHIVE_INTERFACE_SUB(i, base, x) \ +DEFINE_GUID(IID_ ## i, \ +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x06, 0x00, x, 0x00, 0x00); \ +struct i: public base + +#define ARCHIVE_INTERFACE(i, x) ARCHIVE_INTERFACE_SUB(i, IUnknown, x) + +namespace NFileTimeType +{ + enum EEnum + { + kWindows, + kUnix, + kDOS + }; +} + +namespace NArchive +{ + enum + { + kName = 0, + kClassID, + kExtension, + kAddExtension, + kUpdate, + kKeepName, + kStartSignature, + kFinishSignature, + kAssociate + }; + + namespace NExtract + { + namespace NAskMode + { + enum + { + kExtract = 0, + kTest, + kSkip, + }; + } + namespace NOperationResult + { + enum + { + kOK = 0, + kUnSupportedMethod, + kDataError, + kCRCError, + }; + } + } + namespace NUpdate + { + namespace NOperationResult + { + enum + { + kOK = 0, + kError, + }; + } + } +} + +ARCHIVE_INTERFACE(IArchiveOpenCallback, 0x10) +{ + STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes) PURE; + STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes) PURE; +}; + + +ARCHIVE_INTERFACE_SUB(IArchiveExtractCallback, IProgress, 0x20) +{ + STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, + Int32 askExtractMode) PURE; + // GetStream OUT: S_OK - OK, S_FALSE - skeep this file + STDMETHOD(PrepareOperation)(Int32 askExtractMode) PURE; + STDMETHOD(SetOperationResult)(Int32 resultEOperationResult) PURE; +}; + + +ARCHIVE_INTERFACE(IArchiveOpenVolumeCallback, 0x30) +{ + STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) PURE; + STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) PURE; +}; + + +ARCHIVE_INTERFACE(IInArchiveGetStream, 0x40) +{ + STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) PURE; +}; + + +ARCHIVE_INTERFACE(IArchiveOpenSetSubArchiveName, 0x50) +{ + STDMETHOD(SetSubArchiveName)(const wchar_t *name) PURE; +}; + + +ARCHIVE_INTERFACE(IInArchive, 0x60) +{ + STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback) PURE; + STDMETHOD(Close)() PURE; + STDMETHOD(GetNumberOfItems)(UInt32 *numItems) PURE; + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE; + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) PURE; + // indices must be sorted + // numItems = 0xFFFFFFFF means all files + // testMode != 0 means "test files operation" + + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) PURE; + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) PURE; + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) PURE; + + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties) PURE; + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) PURE; +}; + + +ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback, IProgress, 0x80) +{ + STDMETHOD(GetUpdateItemInfo)(UInt32 index, + Int32 *newData, // 1 - new data, 0 - old data + Int32 *newProperties, // 1 - new properties, 0 - old properties + UInt32 *indexInArchive // -1 if there is no in archive, or if doesn't matter + ) PURE; + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE; + STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) PURE; + STDMETHOD(SetOperationResult)(Int32 operationResult) PURE; +}; + + +ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82) +{ + STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size) PURE; + STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream) PURE; +}; + + +ARCHIVE_INTERFACE(IOutArchive, 0xA0) +{ + STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback) PURE; + STDMETHOD(GetFileTimeType)(UInt32 *type) PURE; +}; + + +ARCHIVE_INTERFACE(ISetProperties, 0x03) +{ + STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) PURE; +}; + + +#endif diff --git a/CPP/7zip/Archive/Iso/DllExports.cpp b/CPP/7zip/Archive/Iso/DllExports.cpp new file mode 100755 index 00000000..f746eea1 --- /dev/null +++ b/CPP/7zip/Archive/Iso/DllExports.cpp @@ -0,0 +1,88 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "Windows/PropVariant.h" +#include "../../ICoder.h" +#include "IsoHandler.h" + +// {23170F69-40C1-278A-1000-000110E70000} +DEFINE_GUID(CLSID_CIsoHandler, + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xE7, 0x00, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /* lpReserved */) +{ + return TRUE; +} + +STDAPI CreateObject( + const GUID *classID, + const GUID *interfaceID, + void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + if (*classID != CLSID_CIsoHandler) + return CLASS_E_CLASSNOTAVAILABLE; + int needIn = *interfaceID == IID_IInArchive; + // int needOut = *interfaceID == IID_IOutArchive; + if (needIn /*|| needOut */) + { + NArchive::NIso::CHandler *temp = new NArchive::NIso::CHandler; + if (needIn) + { + CMyComPtr inArchive = (IInArchive *)temp; + *outObject = inArchive.Detach(); + } + /* + else + { + CMyComPtr outArchive = (IOutArchive *)temp; + *outObject = outArchive.Detach(); + } + */ + } + else + return E_NOINTERFACE; + COM_TRY_END + return S_OK; +} + +STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case NArchive::kName: + propVariant = L"Iso"; + break; + case NArchive::kClassID: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CIsoHandler, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NArchive::kExtension: + propVariant = L"iso"; + break; + case NArchive::kUpdate: + propVariant = false; + break; + case NArchive::kKeepName: + propVariant = false; + break; + case NArchive::kStartSignature: + { + const unsigned char sig[] = { 'C', 'D', '0', '0', '1', 0x1 }; + if ((value->bstrVal = ::SysAllocStringByteLen((const char *)sig, 7)) != 0) + value->vt = VT_BSTR; + return S_OK; + } + } + propVariant.Detach(value); + return S_OK; +} diff --git a/CPP/7zip/Archive/Iso/Iso.dsp b/CPP/7zip/Archive/Iso/Iso.dsp new file mode 100755 index 00000000..a204e9cd --- /dev/null +++ b/CPP/7zip/Archive/Iso/Iso.dsp @@ -0,0 +1,273 @@ +# Microsoft Developer Studio Project File - Name="Iso" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Iso - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Iso.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Iso.mak" CFG="Iso - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Iso - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Iso - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Iso - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TAR_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TAR_EXPORTS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\Iso.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Iso - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TAR_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TAR_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\Iso.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Iso - Win32 Release" +# Name "Iso - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Archive.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\Iso.ico +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Buffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\IsoHandler.cpp +# End Source File +# Begin Source File + +SOURCE=.\IsoHandler.h +# End Source File +# Begin Source File + +SOURCE=.\IsoHeader.cpp +# End Source File +# Begin Source File + +SOURCE=.\IsoHeader.h +# End Source File +# Begin Source File + +SOURCE=.\IsoIn.cpp +# End Source File +# Begin Source File + +SOURCE=.\IsoIn.h +# End Source File +# Begin Source File + +SOURCE=.\IsoItem.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# End Target +# End Project diff --git a/CPP/7zip/Archive/Iso/Iso.dsw b/CPP/7zip/Archive/Iso/Iso.dsw new file mode 100755 index 00000000..27728dd2 --- /dev/null +++ b/CPP/7zip/Archive/Iso/Iso.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Iso"=.\Iso.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Archive/Iso/Iso.ico b/CPP/7zip/Archive/Iso/Iso.ico new file mode 100755 index 00000000..2538e408 Binary files /dev/null and b/CPP/7zip/Archive/Iso/Iso.ico differ diff --git a/CPP/7zip/Archive/Iso/IsoHandler.cpp b/CPP/7zip/Archive/Iso/IsoHandler.cpp new file mode 100755 index 00000000..1831e913 --- /dev/null +++ b/CPP/7zip/Archive/Iso/IsoHandler.cpp @@ -0,0 +1,301 @@ +// Iso/Handler.cpp + +#include "StdAfx.h" + +#include "IsoHandler.h" + +#include "Common/Defs.h" +#include "Common/StringConvert.h" +#include "Common/IntToString.h" +#include "Common/NewHandler.h" +#include "Common/ComTry.h" + +#include "Windows/Time.h" +#include "Windows/PropVariant.h" + +#include "../../Common/ProgressUtils.h" +#include "../../Common/LimitedStreams.h" +#include "../../Compress/Copy/CopyCoder.h" + +#include "../Common/ItemNameUtils.h" + +using namespace NWindows; +using namespace NTime; + +namespace NArchive { +namespace NIso { + +STATPROPSTG kProperties[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackedSize, VT_UI8}, + { NULL, kpidLastWriteTime, VT_FILETIME} +}; + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) +{ + value->vt = VT_EMPTY; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if(index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &srcItem = kProperties[index]; + *propID = srcItem.propid; + *varType = srcItem.vt; + *name = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +{ + *numProperties = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, + BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) +{ + return E_INVALIDARG; +} + +STDMETHODIMP CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */) +{ + COM_TRY_BEGIN + Close(); + // try + { + if(_archive.Open(stream) != S_OK) + return S_FALSE; + _inStream = stream; + } + // catch(...) { return S_FALSE; } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + _archive.Clear(); + _inStream.Release(); + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _archive.Refs.Size() + _archive.BootEntries.Size(); + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant propVariant; + if (index >= (UInt32)_archive.Refs.Size()) + { + index -= _archive.Refs.Size(); + const CBootInitialEntry &be = _archive.BootEntries[index]; + switch(propID) + { + case kpidPath: + { + // wchar_t name[32]; + // ConvertUInt64ToString(index + 1, name); + UString s = L"[BOOT]" WSTRING_PATH_SEPARATOR; + // s += name; + // s += L"-"; + s += be.GetName(); + propVariant = (const wchar_t *)s; + break; + } + case kpidIsFolder: + propVariant = false; + break; + case kpidSize: + case kpidPackedSize: + { + propVariant = (UInt64)_archive.GetBootItemSize(index); + break; + } + } + } + else + { + const CRef &ref = _archive.Refs[index]; + const CDir &item = ref.Dir->_subItems[ref.Index]; + switch(propID) + { + case kpidPath: + if (item.FileId.GetCapacity() >= 0) + { + UString s; + if (_archive.IsJoliet()) + s = item.GetPathU(); + else + s = MultiByteToUnicodeString(item.GetPath(_archive.IsSusp, _archive.SuspSkipSize), CP_OEMCP); + + int pos = s.ReverseFind(L';'); + if (pos >= 0 && pos == s.Length() - 2) + if (s[s.Length() - 1] == L'1') + s = s.Left(pos); + if (!s.IsEmpty()) + if (s[s.Length() - 1] == L'.') + s = s.Left(s.Length() - 1); + propVariant = (const wchar_t *)NItemName::GetOSName2(s); + } + break; + case kpidIsFolder: + propVariant = item.IsDir(); + break; + case kpidSize: + case kpidPackedSize: + if (!item.IsDir()) + propVariant = (UInt64)item.DataLength; + break; + case kpidLastWriteTime: + { + FILETIME utcFileTime; + if (item.DateTime.GetFileTime(utcFileTime)) + propVariant = utcFileTime; + /* + else + { + utcFileTime.dwLowDateTime = 0; + utcFileTime.dwHighDateTime = 0; + } + */ + break; + } + } + } + propVariant.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool testMode = (_aTestMode != 0); + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = _archive.Refs.Size(); + UInt64 totalSize = 0; + if(numItems == 0) + return S_OK; + UInt32 i; + for(i = 0; i < numItems; i++) + { + UInt32 index = (allFilesMode ? i : indices[i]); + if (index < (UInt32)_archive.Refs.Size()) + { + const CRef &ref = _archive.Refs[index]; + const CDir &item = ref.Dir->_subItems[ref.Index]; + totalSize += item.DataLength; + } + else + { + totalSize += _archive.GetBootItemSize(index - _archive.Refs.Size()); + } + } + extractCallback->SetTotal(totalSize); + + UInt64 currentTotalSize = 0; + UInt64 currentItemSize; + + CMyComPtr copyCoder; + + for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + { + currentItemSize = 0; + RINOK(extractCallback->SetCompleted(¤tTotalSize)); + CMyComPtr realOutStream; + Int32 askMode; + askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; + UInt32 index = allFilesMode ? i : indices[i]; + + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + + UInt64 blockIndex; + if (index < (UInt32)_archive.Refs.Size()) + { + const CRef &ref = _archive.Refs[index]; + const CDir &item = ref.Dir->_subItems[ref.Index]; + if(item.IsDir()) + { + RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + continue; + } + currentItemSize = item.DataLength; + blockIndex = item.ExtentLocation; + } + else + { + int bootIndex = index - _archive.Refs.Size(); + const CBootInitialEntry &be = _archive.BootEntries[bootIndex]; + currentItemSize = _archive.GetBootItemSize(bootIndex); + blockIndex = be.LoadRBA; + } + + if(!testMode && (!realOutStream)) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)); + { + if (testMode) + { + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + continue; + } + + RINOK(_inStream->Seek(blockIndex * _archive.BlockSize, STREAM_SEEK_SET, NULL)); + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr inStream(streamSpec); + streamSpec->SetStream(_inStream); + streamSpec->Init(currentItemSize); + + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr progress = localProgressSpec; + localProgressSpec->Init(extractCallback, false); + + CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo; + CMyComPtr compressProgress = localCompressProgressSpec; + localCompressProgressSpec->Init(progress, ¤tTotalSize, ¤tTotalSize); + + Int32 res = NArchive::NExtract::NOperationResult::kOK; + if(!copyCoder) + { + copyCoder = new NCompress::CCopyCoder; + } + try + { + RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, compressProgress)); + } + catch(...) + { + res = NArchive::NExtract::NOperationResult::kDataError; + } + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(res)); + } + } + return S_OK; + COM_TRY_END +} + +}} diff --git a/CPP/7zip/Archive/Iso/IsoHandler.h b/CPP/7zip/Archive/Iso/IsoHandler.h new file mode 100755 index 00000000..e545d2a7 --- /dev/null +++ b/CPP/7zip/Archive/Iso/IsoHandler.h @@ -0,0 +1,59 @@ +// Tar/Handler.h + +#ifndef __ISO_HANDLER_H +#define __ISO_HANDLER_H + +#include "Common/MyCom.h" +#include "../IArchive.h" + +#include "IsoItem.h" +#include "IsoIn.h" + +namespace NArchive { +namespace NIso { + +class CHandler: + public IInArchive, + // public IOutArchive, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP1( + IInArchive + // IOutArchive + ) + + STDMETHOD(Open)(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback); + STDMETHOD(Close)(); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); + + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + /* + // IOutArchive + STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback); + STDMETHOD(GetFileTimeType)(UInt32 *type); + */ + +private: + CMyComPtr _inStream; + CInArchive _archive; +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Iso/IsoHeader.cpp b/CPP/7zip/Archive/Iso/IsoHeader.cpp new file mode 100755 index 00000000..9555e49b --- /dev/null +++ b/CPP/7zip/Archive/Iso/IsoHeader.cpp @@ -0,0 +1,21 @@ +// Archive/Iso/Header.h + +#include "StdAfx.h" + +#include "IsoHeader.h" + +namespace NArchive { +namespace NIso { + +const char *kElToritoSpec = "EL TORITO SPECIFICATION\0\0\0\0\0\0\0\0\0"; + +const wchar_t *kMediaTypes[5] = +{ + L"NoEmulation", + L"1.2M", + L"1.44M", + L"2.88M", + L"HardDisk" +}; + +}} diff --git a/CPP/7zip/Archive/Iso/IsoHeader.h b/CPP/7zip/Archive/Iso/IsoHeader.h new file mode 100755 index 00000000..9702d70a --- /dev/null +++ b/CPP/7zip/Archive/Iso/IsoHeader.h @@ -0,0 +1,61 @@ +// Archive/IsoHeader.h + +#ifndef __ARCHIVE_ISO_HEADER_H +#define __ARCHIVE_ISO_HEADER_H + +#include "Common/Types.h" + +namespace NArchive { +namespace NIso { + +namespace NVolDescType +{ + const Byte kBootRecord = 0; + const Byte kPrimaryVol = 1; + const Byte kSupplementaryVol = 2; + const Byte kVolParttition = 3; + const Byte kTerminator = 255; +} + +const Byte kVersion = 1; + +namespace NFileFlags +{ + const Byte kDirectory = 1 << 1; +} + +extern const char *kElToritoSpec; + +const UInt32 kStartPos = 0x8000; + +namespace NBootEntryId +{ + const Byte kValidationEntry = 1; + const Byte kInitialEntryNotBootable = 0; + const Byte kInitialEntryBootable = 0x88; +} + +namespace NBootPlatformId +{ + const Byte kX86 = 0; + const Byte kPowerPC = 1; + const Byte kMac = 2; +} + +const BYTE kBootMediaTypeMask = 0xF; + +namespace NBootMediaType +{ + const Byte kNoEmulation = 0; + const Byte k1d2Floppy = 1; + const Byte k1d44Floppy = 2; + const Byte k2d88Floppy = 3; + const Byte kHardDisk = 4; +} + +const int kNumBootMediaTypes = 5; +extern const wchar_t *kMediaTypes[]; + +}} + +#endif diff --git a/CPP/7zip/Archive/Iso/IsoIn.cpp b/CPP/7zip/Archive/Iso/IsoIn.cpp new file mode 100755 index 00000000..213b3014 --- /dev/null +++ b/CPP/7zip/Archive/Iso/IsoIn.cpp @@ -0,0 +1,438 @@ +// Archive/IsoIn.cpp + +#include "StdAfx.h" + +#include "IsoIn.h" +#include "IsoHeader.h" + +#include "Windows/Defs.h" + +#include "../../Common/StreamUtils.h" + +namespace NArchive { +namespace NIso { + +HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize) +{ + return ReadStream(_stream, data, size, &processedSize); +} + +Byte CInArchive::ReadByte() +{ + if (m_BufferPos >= BlockSize) + m_BufferPos = 0; + if (m_BufferPos == 0) + { + UInt32 processedSize; + if (ReadBytes(m_Buffer, BlockSize, processedSize) != S_OK) + throw 1; + if (processedSize != BlockSize) + throw 1; + } + Byte b = m_Buffer[m_BufferPos++]; + _position++; + return b; +} + +void CInArchive::ReadBytes(Byte *data, UInt32 size) +{ + for (UInt32 i = 0; i < size; i++) + data[i] = ReadByte(); +} + +void CInArchive::Skeep(size_t size) +{ + while (size-- != 0) + ReadByte(); +} + +void CInArchive::SkeepZeros(size_t size) +{ + while (size-- != 0) + { + Byte b = ReadByte(); + if (b != 0) + throw 1; + } +} + +UInt16 CInArchive::ReadUInt16Spec() +{ + UInt16 value = 0; + for (int i = 0; i < 2; i++) + value |= ((UInt16)(ReadByte()) << (8 * i)); + return value; +} + + +UInt16 CInArchive::ReadUInt16() +{ + Byte b[4]; + ReadBytes(b, 4); + UInt32 value = 0; + for (int i = 0; i < 2; i++) + { + if (b[i] != b[3 - i]) + throw 1; + value |= ((UInt16)(b[i]) << (8 * i)); + } + return (UInt16)value; +} + +UInt32 CInArchive::ReadUInt32Le() +{ + UInt32 value = 0; + for (int i = 0; i < 4; i++) + value |= ((UInt32)(ReadByte()) << (8 * i)); + return value; +} + +UInt32 CInArchive::ReadUInt32Be() +{ + UInt32 value = 0; + for (int i = 0; i < 4; i++) + { + value <<= 8; + value |= ReadByte(); + } + return value; +} + +UInt32 CInArchive::ReadUInt32() +{ + Byte b[8]; + ReadBytes(b, 8); + UInt32 value = 0; + for (int i = 0; i < 4; i++) + { + if (b[i] != b[7 - i]) + throw 1; + value |= ((UInt32)(b[i]) << (8 * i)); + } + return value; +} + +UInt32 CInArchive::ReadDigits(int numDigits) +{ + UInt32 res = 0; + for (int i = 0; i < numDigits; i++) + { + Byte b = ReadByte(); + if (b < '0' || b > '9') + { + if (b == 0) // it's bug in some CD's + b = '0'; + else + throw 1; + } + UInt32 d = (UInt32)(b - '0'); + res *= 10; + res += d; + } + return res; +} + +void CInArchive::ReadDateTime(CDateTime &d) +{ + d.Year = (UInt16)ReadDigits(4); + d.Month = (Byte)ReadDigits(2); + d.Day = (Byte)ReadDigits(2); + d.Hour = (Byte)ReadDigits(2); + d.Minute = (Byte)ReadDigits(2); + d.Second = (Byte)ReadDigits(2); + d.Hundredths = (Byte)ReadDigits(2); + d.GmtOffset = (signed char)ReadByte(); +} + +void CInArchive::ReadBootRecordDescriptor(CBootRecordDescriptor &d) +{ + ReadBytes(d.BootSystemId, sizeof(d.BootSystemId)); + ReadBytes(d.BootId, sizeof(d.BootId)); + ReadBytes(d.BootSystemUse, sizeof(d.BootSystemUse)); +} + +void CInArchive::ReadRecordingDateTime(CRecordingDateTime &t) +{ + t.Year = ReadByte(); + t.Month = ReadByte(); + t.Day = ReadByte(); + t.Hour = ReadByte(); + t.Minute = ReadByte(); + t.Second = ReadByte(); + t.GmtOffset = (signed char)ReadByte(); +} + +void CInArchive::ReadDirRecord2(CDirRecord &r, Byte len) +{ + r.ExtendedAttributeRecordLen = ReadByte(); + if (r.ExtendedAttributeRecordLen != 0) + throw 1; + r.ExtentLocation = ReadUInt32(); + r.DataLength = ReadUInt32(); + ReadRecordingDateTime(r.DateTime); + r.FileFlags = ReadByte(); + r.FileUnitSize = ReadByte(); + r.InterleaveGapSize = ReadByte(); + r.VolSequenceNumber = ReadUInt16(); + Byte idLen = ReadByte(); + r.FileId.SetCapacity(idLen); + ReadBytes((Byte *)r.FileId, idLen); + int padSize = 1 - (idLen & 1); + + // SkeepZeros(1 - (idLen & 1)); + Skeep(1 - (idLen & 1)); // it's bug in some cd's. Must be zeros + + int curPos = 33 + idLen + padSize; + if (curPos > len) + throw 1; + int rem = len - curPos; + r.SystemUse.SetCapacity(rem); + ReadBytes((Byte *)r.SystemUse, rem); +} + +void CInArchive::ReadDirRecord(CDirRecord &r) +{ + Byte len = ReadByte(); + ReadDirRecord2(r, len); +} + +void CInArchive::ReadVolumeDescriptor(CVolumeDescriptor &d) +{ + d.VolFlags = ReadByte(); + ReadBytes(d.SystemId, sizeof(d.SystemId)); + ReadBytes(d.VolumeId, sizeof(d.VolumeId)); + SkeepZeros(8); + d.VolumeSpaceSize = ReadUInt32(); + ReadBytes(d.EscapeSequence, sizeof(d.EscapeSequence)); + d.VolumeSetSize = ReadUInt16(); + d.VolumeSequenceNumber = ReadUInt16(); + d.LogicalBlockSize = ReadUInt16(); + d.PathTableSize = ReadUInt32(); + d.LPathTableLocation = ReadUInt32Le(); + d.LOptionalPathTableLocation = ReadUInt32Le(); + d.MPathTableLocation = ReadUInt32Be(); + d.MOptionalPathTableLocation = ReadUInt32Be(); + ReadDirRecord(d.RootDirRecord); + ReadBytes(d.VolumeSetId, sizeof(d.VolumeSetId)); + ReadBytes(d.PublisherId, sizeof(d.PublisherId)); + ReadBytes(d.DataPreparerId, sizeof(d.DataPreparerId)); + ReadBytes(d.ApplicationId, sizeof(d.ApplicationId)); + ReadBytes(d.CopyrightFileId, sizeof(d.CopyrightFileId)); + ReadBytes(d.AbstractFileId, sizeof(d.AbstractFileId)); + ReadBytes(d.BibFileId, sizeof(d.BibFileId)); + ReadDateTime(d.CreationTime); + ReadDateTime(d.ModificationTime); + ReadDateTime(d.ExpirationTime); + ReadDateTime(d.EffectiveTime); + d.FileStructureVersion = ReadByte(); // = 1 + SkeepZeros(1); + ReadBytes(d.ApplicationUse, sizeof(d.ApplicationUse)); + SkeepZeros(653); +} + +static inline bool CheckDescriptorSignature(const Byte *sig) +{ + return sig[0] == 'C' && + sig[1] == 'D' && + sig[2] == '0' && + sig[3] == '0' && + sig[4] == '1'; +} + +void CInArchive::SeekToBlock(UInt32 blockIndex) +{ + if (_stream->Seek((UInt64)blockIndex * VolDescs[MainVolDescIndex].LogicalBlockSize, STREAM_SEEK_SET, &_position) != S_OK) + throw 1; + m_BufferPos = 0; +} + +void CInArchive::ReadDir(CDir &d, int level) +{ + if (!d.IsDir()) + return; + SeekToBlock(d.ExtentLocation); + UInt64 startPos = _position; + + bool firstItem = true; + for (;;) + { + UInt64 offset = _position - startPos; + if (offset >= d.DataLength) + break; + Byte len = ReadByte(); + if (len == 0) + continue; + CDir subItem; + ReadDirRecord2(subItem, len); + if (firstItem && level == 0) + IsSusp = subItem.CheckSusp(SuspSkipSize); + + if (!subItem.IsSystemItem()) + d._subItems.Add(subItem); + + firstItem = false; + } + for (int i = 0; i < d._subItems.Size(); i++) + ReadDir(d._subItems[i], level + 1); +} + +void CInArchive::CreateRefs(CDir &d) +{ + if (!d.IsDir()) + return; + for (int i = 0; i < d._subItems.Size(); i++) + { + CRef ref; + CDir &subItem = d._subItems[i]; + subItem.Parent = &d; + ref.Dir = &d; + ref.Index = i; + Refs.Add(ref); + CreateRefs(subItem); + } +} + +void CInArchive::ReadBootInfo() +{ + if (!_bootIsDefined) + return; + if (memcmp(_bootDesc.BootSystemId, kElToritoSpec, sizeof(_bootDesc.BootSystemId)) != 0) + return; + + const Byte *p = (const Byte *)_bootDesc.BootSystemUse; + UInt32 blockIndex = p[0] | ((UInt32)p[1] << 8) | ((UInt32)p[2] << 16) | ((UInt32)p[3] << 24); + SeekToBlock(blockIndex); + Byte b = ReadByte(); + if (b != NBootEntryId::kValidationEntry) + return; + { + CBootValidationEntry e; + e.PlatformId = ReadByte(); + if (ReadUInt16Spec() != 0) + throw 1; + ReadBytes(e.Id, sizeof(e.Id)); + /* UInt16 checkSum = */ ReadUInt16Spec(); + if (ReadByte() != 0x55) + throw 1; + if (ReadByte() != 0xAA) + throw 1; + } + b = ReadByte(); + if (b == NBootEntryId::kInitialEntryBootable || b == NBootEntryId::kInitialEntryNotBootable) + { + CBootInitialEntry e; + e.Bootable = (b == NBootEntryId::kInitialEntryBootable); + e.BootMediaType = ReadByte(); + e.LoadSegment = ReadUInt16Spec(); + e.SystemType = ReadByte(); + if (ReadByte() != 0) + throw 1; + e.SectorCount = ReadUInt16Spec(); + e.LoadRBA = ReadUInt32Le(); + if (ReadByte() != 0) + throw 1; + BootEntries.Add(e); + } + else + return; +} + +HRESULT CInArchive::Open2() +{ + Clear(); + RINOK(_stream->Seek(kStartPos, STREAM_SEEK_CUR, &_position)); + + bool primVolDescDefined = false; + m_BufferPos = 0; + BlockSize = kBlockSize; + VolDescs.Add(CVolumeDescriptor()); + for (;;) + { + Byte sig[6]; + ReadBytes(sig, 6); + if (!CheckDescriptorSignature(sig + 1)) + return S_FALSE; + // version = 2 for ISO 9660:1999? + Byte ver = ReadByte(); + if (ver > 2) + throw S_FALSE; + + if (sig[0] == NVolDescType::kTerminator) + break; + switch(sig[0]) + { + case NVolDescType::kBootRecord: + { + _bootIsDefined = true; + ReadBootRecordDescriptor(_bootDesc); + break; + } + case NVolDescType::kPrimaryVol: + { + if (primVolDescDefined) + return S_FALSE; + primVolDescDefined = true; + CVolumeDescriptor &volDesc = VolDescs[0]; + ReadVolumeDescriptor(volDesc); + // some burners write "Joliet" Escape Sequence to primary volume + memset(volDesc.EscapeSequence, 0, sizeof(volDesc.EscapeSequence)); + break; + } + case NVolDescType::kSupplementaryVol: + { + CVolumeDescriptor sd; + ReadVolumeDescriptor(sd); + VolDescs.Add(sd); + break; + } + default: + break; + } + } + MainVolDescIndex = 0; + if (!primVolDescDefined) + return S_FALSE; + for (int i = VolDescs.Size() - 1; i >= 0; i--) + { + if (VolDescs[i].IsJoliet()) + { + MainVolDescIndex = i; + break; + } + } + // MainVolDescIndex = 0; // to read primary volume + if (VolDescs[MainVolDescIndex].LogicalBlockSize != kBlockSize) + return S_FALSE; + (CDirRecord &)_rootDir = VolDescs[MainVolDescIndex].RootDirRecord; + ReadDir(_rootDir, 0); + CreateRefs(_rootDir); + ReadBootInfo(); + return S_OK; +} + +HRESULT CInArchive::Open(IInStream *inStream) +{ + _stream = inStream; + UInt64 pos; + RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &pos)); + RINOK(_stream->Seek(0, STREAM_SEEK_END, &_archiveSize)); + RINOK(_stream->Seek(pos, STREAM_SEEK_SET, &_position)); + HRESULT res = S_FALSE; + try { res = Open2(); } + catch(...) { Clear(); res = S_FALSE; } + _stream.Release(); + return res; +} + +void CInArchive::Clear() +{ + Refs.Clear(); + _rootDir.Clear(); + VolDescs.Clear(); + _bootIsDefined = false; + BootEntries.Clear(); + SuspSkipSize = 0; + IsSusp = false; +} + +}} diff --git a/CPP/7zip/Archive/Iso/IsoIn.h b/CPP/7zip/Archive/Iso/IsoIn.h new file mode 100755 index 00000000..ab850bd9 --- /dev/null +++ b/CPP/7zip/Archive/Iso/IsoIn.h @@ -0,0 +1,301 @@ +// Archive/IsoIn.h + +#ifndef __ARCHIVE_ISO_IN_H +#define __ARCHIVE_ISO_IN_H + +#include "Common/MyCom.h" +#include "Common/IntToString.h" + +#include "../../IStream.h" + +#include "IsoItem.h" +#include "IsoHeader.h" + +namespace NArchive { +namespace NIso { + +struct CDir: public CDirRecord +{ + CDir *Parent; + CObjectVector _subItems; + + void Clear() + { + Parent = 0; + _subItems.Clear(); + } + + int GetLength(bool checkSusp, int skipSize) const + { + int len = GetLengthCur(checkSusp, skipSize); + if (Parent != 0) + if (Parent->Parent != 0) + len += 1 + Parent->GetLength(checkSusp, skipSize); + return len; + } + + int GetLengthU() const + { + int len = (int)(FileId.GetCapacity() / 2); + if (Parent != 0) + if (Parent->Parent != 0) + len += 1 + Parent->GetLengthU(); + return len; + } + + AString GetPath(bool checkSusp, int skipSize) const + { + AString s; + int len = GetLength(checkSusp, skipSize); + char *p = s.GetBuffer(len + 1); + p += len; + *p = 0; + const CDir *cur = this; + for (;;) + { + int curLen = cur->GetLengthCur(checkSusp, skipSize); + p -= curLen; + memmove(p, (const char *)(const Byte *)cur->GetNameCur(checkSusp, skipSize), curLen); + cur = cur->Parent; + if (cur == 0) + break; + if (cur->Parent == 0) + break; + p--; + *p = CHAR_PATH_SEPARATOR; + } + s.ReleaseBuffer(); + return s; + } + + UString GetPathU() const + { + UString s; + int len = GetLengthU(); + wchar_t *p = s.GetBuffer(len + 1); + p += len; + *p = 0; + const CDir *cur = this; + for (;;) + { + int curLen = (int)(cur->FileId.GetCapacity() / 2); + p -= curLen; + for (int i = 0; i < curLen; i++) + { + Byte b0 = ((const Byte *)cur->FileId)[i * 2]; + Byte b1 = ((const Byte *)cur->FileId)[i * 2 + 1]; + p[i] = (wchar_t)(((wchar_t)b0 << 8) | b1); + } + cur = cur->Parent; + if (cur == 0) + break; + if (cur->Parent == 0) + break; + p--; + *p = WCHAR_PATH_SEPARATOR; + } + s.ReleaseBuffer(); + return s; + } +}; + +struct CDateTime +{ + UInt16 Year; + Byte Month; + Byte Day; + Byte Hour; + Byte Minute; + Byte Second; + Byte Hundredths; + signed char GmtOffset; // min intervals from -48 (West) to +52 (East) recorded. + bool NotSpecified() const { return Year == 0 && Month == 0 && Day == 0 && + Hour == 0 && Minute == 0 && Second == 0 && GmtOffset == 0; } +}; + +struct CBootRecordDescriptor +{ + Byte BootSystemId[32]; // a-characters + Byte BootId[32]; // a-characters + Byte BootSystemUse[1977]; +}; + +struct CBootValidationEntry +{ + Byte PlatformId; + Byte Id[24]; // to identify the manufacturer/developer of the CD-ROM. +}; + +struct CBootInitialEntry +{ + bool Bootable; + Byte BootMediaType; + UInt16 LoadSegment; + /* This is the load segment for the initial boot image. If this + value is 0 the system will use the traditional segment of 7C0. If this value + is non-zero the system will use the specified segment. This applies to x86 + architectures only. For "flat" model architectures (such as Motorola) this + is the address divided by 10. */ + Byte SystemType; // This must be a copy of byte 5 (System Type) from the + // Partition Table found in the boot image. + UInt16 SectorCount; // This is the number of virtual/emulated sectors the system + // will store at Load Segment during the initial boot procedure. + UInt32 LoadRBA; // This is the start address of the virtual disk. CD’s use + // Relative/Logical block addressing. + + UInt64 GetSize() const + { + // if (BootMediaType == NBootMediaType::k1d44Floppy) (1440 << 10); + return SectorCount * 512; + } + + UString GetName() const + { + UString s; + if (Bootable) + s += L"Bootable"; + else + s += L"NotBootable"; + s += L"_"; + if (BootMediaType >= kNumBootMediaTypes) + { + wchar_t name[32]; + ConvertUInt64ToString(BootMediaType, name); + s += name; + } + else + s += kMediaTypes[BootMediaType]; + s += L".img"; + return s; + } +}; + +struct CVolumeDescriptor +{ + Byte VolFlags; + Byte SystemId[32]; // a-characters. An identification of a system + // which can recognize and act upon the content of the Logical + // Sectors with logical Sector Numbers 0 to 15 of the volume. + Byte VolumeId[32]; // d-characters. An identification of the volume. + UInt32 VolumeSpaceSize; // the number of Logical Blocks in which the Volume Space of the volume is recorded + Byte EscapeSequence[32]; + UInt16 VolumeSetSize; + UInt16 VolumeSequenceNumber; // the ordinal number of the volume in the Volume Set of which the volume is a member. + UInt16 LogicalBlockSize; + UInt32 PathTableSize; + UInt32 LPathTableLocation; + UInt32 LOptionalPathTableLocation; + UInt32 MPathTableLocation; + UInt32 MOptionalPathTableLocation; + CDirRecord RootDirRecord; + Byte VolumeSetId[128]; + Byte PublisherId[128]; + Byte DataPreparerId[128]; + Byte ApplicationId[128]; + Byte CopyrightFileId[37]; + Byte AbstractFileId[37]; + Byte BibFileId[37]; + CDateTime CreationTime; + CDateTime ModificationTime; + CDateTime ExpirationTime; + CDateTime EffectiveTime; + Byte FileStructureVersion; // = 1; + Byte ApplicationUse[512]; + + bool IsJoliet() const + { + if ((VolFlags & 1) != 0) + return false; + Byte b = EscapeSequence[2]; + return (EscapeSequence[0] == 0x25 && EscapeSequence[1] == 0x2F && + (b == 0x40 || b == 0x43 || b == 0x45)); + } +}; + +struct CRef +{ + CDir *Dir; + UInt32 Index; +}; + +const UInt32 kBlockSize = 1 << 11; + +class CInArchive +{ + CMyComPtr _stream; + UInt64 _position; + + Byte m_Buffer[kBlockSize]; + UInt32 m_BufferPos; + + CDir _rootDir; + bool _bootIsDefined; + CBootRecordDescriptor _bootDesc; + + HRESULT ReadBytes(void *data, UInt32 size, UInt32 &processedSize); + void Skeep(size_t size); + void SkeepZeros(size_t size); + Byte ReadByte(); + void ReadBytes(Byte *data, UInt32 size); + UInt16 ReadUInt16Spec(); + UInt16 ReadUInt16(); + UInt32 ReadUInt32Le(); + UInt32 ReadUInt32Be(); + UInt32 ReadUInt32(); + UInt64 ReadUInt64(); + UInt32 ReadDigits(int numDigits); + void ReadDateTime(CDateTime &d); + void ReadRecordingDateTime(CRecordingDateTime &t); + void ReadDirRecord2(CDirRecord &r, Byte len); + void ReadDirRecord(CDirRecord &r); + + void ReadBootRecordDescriptor(CBootRecordDescriptor &d); + void ReadVolumeDescriptor(CVolumeDescriptor &d); + + void SeekToBlock(UInt32 blockIndex); + void ReadDir(CDir &d, int level); + void CreateRefs(CDir &d); + + void ReadBootInfo(); + HRESULT Open2(); +public: + HRESULT Open(IInStream *inStream); + void Clear(); + + UInt64 _archiveSize; + + CRecordVector Refs; + CObjectVector VolDescs; + int MainVolDescIndex; + UInt32 BlockSize; + CObjectVector BootEntries; + + + bool IsJoliet() const { return VolDescs[MainVolDescIndex].IsJoliet(); } + + UInt64 GetBootItemSize(int index) const + { + const CBootInitialEntry &be = BootEntries[index]; + UInt64 size = be.GetSize(); + if (be.BootMediaType == NBootMediaType::k1d2Floppy) + size = (1200 << 10); + else if (be.BootMediaType == NBootMediaType::k1d44Floppy) + size = (1440 << 10); + else if (be.BootMediaType == NBootMediaType::k2d88Floppy) + size = (2880 << 10); + UInt64 startPos = be.LoadRBA * BlockSize; + if (startPos < _archiveSize) + { + if (_archiveSize - startPos < size) + size = _archiveSize - startPos; + } + return size; + } + + bool IsSusp; + int SuspSkipSize; +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Iso/IsoItem.h b/CPP/7zip/Archive/Iso/IsoItem.h new file mode 100755 index 00000000..14024d8d --- /dev/null +++ b/CPP/7zip/Archive/Iso/IsoItem.h @@ -0,0 +1,145 @@ +// Archive/IsoItem.h + +#ifndef __ARCHIVE_ISO_ITEM_H +#define __ARCHIVE_ISO_ITEM_H + +#include "Common/Types.h" +#include "Common/String.h" +#include "Common/Buffer.h" + +#include "IsoHeader.h" + +namespace NArchive { +namespace NIso { + +struct CRecordingDateTime +{ + Byte Year; + Byte Month; + Byte Day; + Byte Hour; + Byte Minute; + Byte Second; + signed char GmtOffset; // min intervals from -48 (West) to +52 (East) recorded. + + bool GetFileTime(FILETIME &ft) const + { + SYSTEMTIME st; + st.wYear = (WORD)(Year + 1900); + st.wMonth = Month; + st.wDayOfWeek = 0; // check it + st.wDay = Day; + st.wHour = Hour; + st.wMinute = Minute; + st.wSecond = Second; + st.wMilliseconds = 0; + if (!SystemTimeToFileTime(&st, &ft)) + return false; + UInt64 value = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime; + value += (UInt64)((Int64)(int)GmtOffset * 15 * 60); + ft.dwLowDateTime = (DWORD)value; + ft.dwHighDateTime = DWORD(value >> 32); + return true; + } +}; + +struct CDirRecord +{ + Byte ExtendedAttributeRecordLen; + UInt32 ExtentLocation; + UInt32 DataLength; + CRecordingDateTime DateTime; + Byte FileFlags; + Byte FileUnitSize; + Byte InterleaveGapSize; + UInt16 VolSequenceNumber; + CByteBuffer FileId; + CByteBuffer SystemUse; + + bool IsDir() const { return (FileFlags & NFileFlags::kDirectory) != 0; } + bool IsSystemItem() const + { + if (FileId.GetCapacity() != 1) + return false; + Byte b = *(const Byte *)FileId; + return (b == 0 || b == 1); + } + + const Byte* FindSuspName(int skipSize, int &lenRes) const + { + lenRes = 0; + const Byte *p = (const Byte *)SystemUse + skipSize; + int length = (int)(SystemUse.GetCapacity() - skipSize); + while (length >= 5) + { + int len = p[2]; + if (p[0] == 'N' && p[1] == 'M' && p[3] == 1) + { + lenRes = len - 5; + return p + 5; + } + p += len; + length -= len; + } + return 0; + } + + int GetLengthCur(bool checkSusp, int skipSize) const + { + if (checkSusp) + { + int len; + const Byte *res = FindSuspName(skipSize, len); + if (res != 0) + return len; + } + return (int)FileId.GetCapacity(); + } + + const Byte* GetNameCur(bool checkSusp, int skipSize) const + { + if (checkSusp) + { + int len; + const Byte *res = FindSuspName(skipSize, len); + if (res != 0) + return res; + } + return (const Byte *)FileId; + } + + + bool CheckSusp(const Byte *p, int &startPos) const + { + if (p[0] == 'S' && + p[1] == 'P' && + p[2] == 0x7 && + p[3] == 0x1 && + p[4] == 0xBE && + p[5] == 0xEF) + { + startPos = p[6]; + return true; + } + return false; + } + + bool CheckSusp(int &startPos) const + { + const Byte *p = (const Byte *)SystemUse; + int length = (int)SystemUse.GetCapacity(); + const int kMinLen = 7; + if (length < kMinLen) + return false; + if (CheckSusp(p, startPos)) + return true; + const int kOffset2 = 14; + if (length < kOffset2 + kMinLen) + return false; + return CheckSusp(p + kOffset2, startPos); + } +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Iso/StdAfx.cpp b/CPP/7zip/Archive/Iso/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Archive/Iso/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Iso/StdAfx.h b/CPP/7zip/Archive/Iso/StdAfx.h new file mode 100755 index 00000000..2e4be10b --- /dev/null +++ b/CPP/7zip/Archive/Iso/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" +#include "../../../Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/Archive/Iso/makefile b/CPP/7zip/Archive/Iso/makefile new file mode 100755 index 00000000..100a3cd0 --- /dev/null +++ b/CPP/7zip/Archive/Iso/makefile @@ -0,0 +1,55 @@ +PROG = iso.dll +DEF_FILE = ../Archive.def +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib user32.lib + +TAR_OBJS = \ + $O\DllExports.obj \ + $O\IsoHandler.obj \ + $O\IsoHeader.obj \ + $O\IsoIn.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\Vector.obj \ + +WIN_OBJS = \ + $O\PropVariant.obj \ + +7ZIP_COMMON_OBJS = \ + $O\LimitedStreams.obj \ + $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ + +AR_COMMON_OBJS = \ + $O\ItemNameUtils.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(TAR_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $(COMPRESS_TAR_OBJS) \ + $O\CopyCoder.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(TAR_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/Archive/Iso/resource.rc b/CPP/7zip/Archive/Iso/resource.rc new file mode 100755 index 00000000..86929b0e --- /dev/null +++ b/CPP/7zip/Archive/Iso/resource.rc @@ -0,0 +1,5 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("Iso Plugin", "iso") + +101 ICON "iso.ico" diff --git a/CPP/7zip/Archive/Lzh/DllExports.cpp b/CPP/7zip/Archive/Lzh/DllExports.cpp new file mode 100755 index 00000000..c2b30945 --- /dev/null +++ b/CPP/7zip/Archive/Lzh/DllExports.cpp @@ -0,0 +1,72 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "Windows/PropVariant.h" +#include "../../ICoder.h" +#include "LzhHandler.h" + +// {23170F69-40C1-278A-1000-000110060000} +DEFINE_GUID(CLSID_CLzhHandler, + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x06, 0x00, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /* lpReserved */) +{ + return TRUE; +} + +STDAPI CreateObject( + const GUID *classID, + const GUID *interfaceID, + void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + if (*classID != CLSID_CLzhHandler) + return CLASS_E_CLASSNOTAVAILABLE; + if (*interfaceID != IID_IInArchive) + return E_NOINTERFACE; + CMyComPtr inArchive = (IInArchive *)new NArchive::NLzh::CHandler; + *outObject = inArchive.Detach(); + COM_TRY_END + return S_OK; +} + +STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case NArchive::kName: + propVariant = L"Lzh"; + break; + case NArchive::kClassID: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CLzhHandler, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NArchive::kExtension: + propVariant = L"lzh lha"; + break; + case NArchive::kUpdate: + propVariant = false; + break; + case NArchive::kKeepName: + propVariant = false; + break; + case NArchive::kStartSignature: + { + const unsigned char sig[] = { '-', 'l' }; + if ((value->bstrVal = ::SysAllocStringByteLen((const char *)sig, 2)) != 0) + value->vt = VT_BSTR; + return S_OK; + } + } + propVariant.Detach(value); + return S_OK; +} diff --git a/CPP/7zip/Archive/Lzh/Lzh.def b/CPP/7zip/Archive/Lzh/Lzh.def new file mode 100755 index 00000000..e240b3f2 --- /dev/null +++ b/CPP/7zip/Archive/Lzh/Lzh.def @@ -0,0 +1,7 @@ +; Arj.def + +LIBRARY Arj.dll + +EXPORTS + CreateObject PRIVATE + GetHandlerProperty PRIVATE diff --git a/CPP/7zip/Archive/Lzh/Lzh.dsp b/CPP/7zip/Archive/Lzh/Lzh.dsp new file mode 100755 index 00000000..ad00699c --- /dev/null +++ b/CPP/7zip/Archive/Lzh/Lzh.dsp @@ -0,0 +1,333 @@ +# Microsoft Developer Studio Project File - Name="Lzh" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Lzh - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "lzh.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "lzh.mak" CFG="Lzh - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Lzh - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Lzh - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Lzh - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARJ_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARJ_EXPORTS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\lzh.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Lzh - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARJ_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARJ_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\lzh.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Lzh - Win32 Release" +# Name "Lzh - Win32 Debug" +# Begin Group "spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Archive.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Buffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\LzhCRC.cpp +# End Source File +# Begin Source File + +SOURCE=.\LzhCRC.h +# End Source File +# Begin Source File + +SOURCE=.\LzhHandler.cpp +# End Source File +# Begin Source File + +SOURCE=.\LzhHandler.h +# End Source File +# Begin Source File + +SOURCE=.\LzhHeader.h +# End Source File +# Begin Source File + +SOURCE=.\LzhIn.cpp +# End Source File +# Begin Source File + +SOURCE=.\LzhIn.h +# End Source File +# Begin Source File + +SOURCE=.\LzhItem.h +# End Source File +# Begin Source File + +SOURCE=.\LzhOutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=.\LzhOutStreamWithCRC.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Group "Codecs" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Lzh\LzhDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzh\LzhDecoder.h +# End Source File +# End Group +# Begin Group "LZ" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.h +# End Source File +# End Group +# Begin Group "Copy" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "Huffman" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Huffman\HuffmanDecoder.h +# End Source File +# End Group +# End Group +# Begin Group "7zip common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MSBFDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\lzh.ico +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/Archive/Lzh/Lzh.dsw b/CPP/7zip/Archive/Lzh/Lzh.dsw new file mode 100755 index 00000000..41ab2218 --- /dev/null +++ b/CPP/7zip/Archive/Lzh/Lzh.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "lzh"=.\lzh.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Archive/Lzh/LzhCRC.cpp b/CPP/7zip/Archive/Lzh/LzhCRC.cpp new file mode 100755 index 00000000..ca1235bb --- /dev/null +++ b/CPP/7zip/Archive/Lzh/LzhCRC.cpp @@ -0,0 +1,43 @@ +// LzhCRC.cpp + +#include "StdAfx.h" + +#include "LzhCRC.h" + +namespace NArchive { +namespace NLzh { + +static const UInt16 kCRCPoly = 0xA001; + +UInt16 CCRC::Table[256]; + +void CCRC::InitTable() +{ + for (UInt32 i = 0; i < 256; i++) + { + UInt32 r = i; + for (int j = 0; j < 8; j++) + if (r & 1) + r = (r >> 1) ^ kCRCPoly; + else + r >>= 1; + CCRC::Table[i] = (UInt16)r; + } +} + +class CCRCTableInit +{ +public: + CCRCTableInit() { CCRC::InitTable(); } +} g_CRCTableInit; + +void CCRC::Update(const void *data, size_t size) +{ + UInt16 v = _value; + const Byte *p = (const Byte *)data; + for (; size > 0; size--, p++) + v = (UInt16)(Table[((Byte)(v)) ^ *p] ^ (v >> 8)); + _value = v; +} + +}} diff --git a/CPP/7zip/Archive/Lzh/LzhCRC.h b/CPP/7zip/Archive/Lzh/LzhCRC.h new file mode 100755 index 00000000..e49d649c --- /dev/null +++ b/CPP/7zip/Archive/Lzh/LzhCRC.h @@ -0,0 +1,27 @@ +// LzhCRC.h + +#ifndef __LZH_CRC_H +#define __LZH_CRC_H + +#include +#include "Common/Types.h" + +namespace NArchive { +namespace NLzh { + +class CCRC +{ + UInt16 _value; +public: + static UInt16 Table[256]; + static void InitTable(); + + CCRC(): _value(0){}; + void Init() { _value = 0; } + void Update(const void *data, size_t size); + UInt16 GetDigest() const { return _value; } +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Lzh/LzhHandler.cpp b/CPP/7zip/Archive/Lzh/LzhHandler.cpp new file mode 100755 index 00000000..03af11d1 --- /dev/null +++ b/CPP/7zip/Archive/Lzh/LzhHandler.cpp @@ -0,0 +1,464 @@ +// LzhHandler.cpp + +#include "StdAfx.h" + +#include "Common/Defs.h" +#include "Common/StringConvert.h" +#include "Common/ComTry.h" + +#include "Windows/Time.h" +#include "Windows/PropVariant.h" + +#include "LzhHandler.h" +#include "LzhOutStreamWithCRC.h" + +#include "../../ICoder.h" + +#include "../../Common/ProgressUtils.h" +#include "../../Common/LimitedStreams.h" + +#include "../../Compress/Copy/CopyCoder.h" +#include "../../Compress/Lzh/LzhDecoder.h" + +#include "../Common/ItemNameUtils.h" + +using namespace NWindows; +using namespace NTime; + +namespace NArchive { +namespace NLzh{ + +struct COsPair +{ + Byte Id; + const wchar_t *Name; +}; + +COsPair g_OsPairs[] = +{ + { 'M', L"MS-DOS" }, + { '2', L"OS/2" }, + { '9', L"OS9" }, + { 'K', L"OS/68K" }, + { '3', L"OS/386" }, + { 'H', L"HUMAN" }, + { 'U', L"UNIX" }, + { 'C', L"CP/M" }, + { 'F', L"FLEX" }, + { 'm', L"Mac" }, + { 'R', L"Runser" }, + { 'T', L"TownsOS" }, + { 'X', L"XOSK" }, + { 'w', L"Windows95" }, + { 'W', L"WindowsNT" }, + { 0, L"MS-DOS" }, + { 'J', L"Java VM" } +}; + +const wchar_t *kUnknownOS = L"Unknown"; + +const int kNumHostOSes = sizeof(g_OsPairs) / sizeof(g_OsPairs[0]); + +static const wchar_t *GetOS(Byte osId) +{ + for (int i = 0; i < kNumHostOSes; i++) + if (g_OsPairs[i].Id == osId) + return g_OsPairs[i].Name; + return kUnknownOS; +}; + +STATPROPSTG kProperties[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackedSize, VT_UI8}, + { NULL, kpidLastWriteTime, VT_FILETIME}, + { NULL, kpidAttributes, VT_UI4}, + + // { NULL, kpidCommented, VT_BOOL}, + + { NULL, kpidCRC, VT_UI4}, + + { NULL, kpidMethod, VT_UI1}, + { NULL, kpidHostOS, VT_BSTR} + +}; + + +CHandler::CHandler() +{} + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) +{ + value->vt = VT_EMPTY; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if(index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &srcItem = kProperties[index]; + *propID = srcItem.propid; + *varType = srcItem.vt; + *name = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +{ + *numProperties = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, + BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _items.Size(); + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant propVariant; + const CItemEx &item = _items[index]; + switch(propID) + { + case kpidPath: + { + UString s = NItemName::WinNameToOSName(MultiByteToUnicodeString(item.GetName(), CP_OEMCP)); + if (!s.IsEmpty()) + { + if (s[s.Length() - 1] == WCHAR_PATH_SEPARATOR) + s.Delete(s.Length() - 1); + propVariant = s; + } + break; + } + case kpidIsFolder: + propVariant = item.IsDirectory(); + break; + case kpidSize: + propVariant = item.Size; + break; + case kpidPackedSize: + propVariant = item.PackSize; + break; + case kpidLastWriteTime: + { + FILETIME utcFileTime; + UInt32 unixTime; + if (item.GetUnixTime(unixTime)) + { + NTime::UnixTimeToFileTime(unixTime, utcFileTime); + } + else + { + FILETIME localFileTime; + if (DosTimeToFileTime(item.ModifiedTime, localFileTime)) + { + if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime)) + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; + } + else + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; + } + propVariant = utcFileTime; + break; + } + /* + case kpidAttributes: + propVariant = (UInt32)item.Attributes; + break; + case kpidCommented: + propVariant = item.IsCommented(); + break; + */ + case kpidCRC: + propVariant = (UInt32)item.CRC; + break; + case kpidMethod: + { + wchar_t method2[kMethodIdSize + 1]; + method2[kMethodIdSize] = 0; + for (int i = 0; i < kMethodIdSize; i++) + method2[i] = item.Method[i]; + propVariant = method2; + break; + } + case kpidHostOS: + propVariant = GetOS(item.OsId); + break; + } + propVariant.Detach(value); + return S_OK; + COM_TRY_END +} + +/* +class CPropgressImp: public CProgressVirt +{ +public: + CMyComPtr Callback; + STDMETHOD(SetCompleted)(const UInt64 *numFiles); +}; + +STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles) +{ + if (Callback) + return Callback->SetCompleted(numFiles, NULL); + return S_OK; +} +*/ + +STDMETHODIMP CHandler::Open(IInStream *inStream, + const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback *callback) +{ + COM_TRY_BEGIN + try + { + _items.Clear(); + CInArchive archive; + RINOK(archive.Open(inStream)); + if (callback != NULL) + { + RINOK(callback->SetTotal(NULL, NULL)); + UInt64 numFiles = _items.Size(); + RINOK(callback->SetCompleted(&numFiles, NULL)); + } + for (;;) + { + CItemEx itemInfo; + bool filled; + HRESULT result = archive.GetNextItem(filled, itemInfo); + if (result == S_FALSE) + return S_FALSE; + if (result != S_OK) + return S_FALSE; + if (!filled) + break; + _items.Add(itemInfo); + archive.Skeep(itemInfo.PackSize); + if (callback != NULL) + { + UInt64 numFiles = _items.Size(); + RINOK(callback->SetCompleted(&numFiles, NULL)); + } + } + if (_items.IsEmpty()) + return S_FALSE; + + _stream = inStream; + } + catch(...) + { + return S_FALSE; + } + COM_TRY_END + return S_OK; +} + +STDMETHODIMP CHandler::Close() +{ + _items.Clear(); + _stream.Release(); + return S_OK; +} + + + +////////////////////////////////////// +// CHandler::DecompressItems + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 testModeSpec, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool testMode = (testModeSpec != 0); + UInt64 totalUnPacked = 0, totalPacked = 0; + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = _items.Size(); + if(numItems == 0) + return S_OK; + UInt32 i; + for(i = 0; i < numItems; i++) + { + const CItemEx &itemInfo = _items[allFilesMode ? i : indices[i]]; + totalUnPacked += itemInfo.Size; + totalPacked += itemInfo.PackSize; + } + extractCallback->SetTotal(totalUnPacked); + + UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0; + UInt64 currentItemUnPacked, currentItemPacked; + + NCompress::NLzh::NDecoder::CCoder *lzhDecoderSpec = 0; + CMyComPtr lzhDecoder; + CMyComPtr lzh1Decoder; + CMyComPtr arj2Decoder; + CMyComPtr copyCoder; + + for(i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked, + currentTotalPacked += currentItemPacked) + { + currentItemUnPacked = 0; + currentItemPacked = 0; + + RINOK(extractCallback->SetCompleted(¤tTotalUnPacked)); + CMyComPtr 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 outStream(outStreamSpec); + outStreamSpec->Init(realOutStream); + realOutStream.Release(); + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr inStream(streamSpec); + + UInt64 pos; + _stream->Seek(itemInfo.DataPosition, STREAM_SEEK_SET, &pos); + + streamSpec->SetStream(_stream); + streamSpec->Init(itemInfo.PackSize); + + + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr progress = localProgressSpec; + localProgressSpec->Init(extractCallback, false); + + + CLocalCompressProgressInfo *localCompressProgressSpec = + new CLocalCompressProgressInfo; + CMyComPtr compressProgress = localCompressProgressSpec; + localCompressProgressSpec->Init(progress, + ¤tTotalPacked, + ¤tTotalUnPacked); + + HRESULT result; + + if (itemInfo.IsCopyMethod()) + { + if(!copyCoder) + copyCoder = new NCompress::CCopyCoder; + try + { + result = copyCoder->Code(inStream, outStream, NULL, NULL, compressProgress); + if (result == S_FALSE) + throw "data error"; + if (result != S_OK) + return result; + } + catch(...) + { + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); + continue; + } + } + else if (itemInfo.IsLh4GroupMethod()) + { + if(!lzhDecoder) + { + lzhDecoderSpec = new NCompress::NLzh::NDecoder::CCoder; + lzhDecoder = lzhDecoderSpec; + } + try + { + lzhDecoderSpec->SetDictionary(itemInfo.GetNumDictBits()); + result = lzhDecoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, compressProgress); + if (result == S_FALSE) + throw "data error"; + if (result != S_OK) + return result; + } + catch(...) + { + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); + continue; + } + } + /* + else if (itemInfo.IsLh1GroupMethod()) + { + if(!lzh1Decoder) + { + lzh1DecoderSpec = new NCompress::NLzh1::NDecoder::CCoder; + lzh1Decoder = lzh1DecoderSpec; + } + try + { + lzh1DecoderSpec->SetDictionary(itemInfo.GetNumDictBits()); + result = lzh1Decoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, compressProgress); + if (result == S_FALSE) + throw "data error"; + if (result != S_OK) + return result; + } + catch(...) + { + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); + continue; + } + } + */ + else + { + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + continue; + } + + bool crcOK = (outStreamSpec->GetCRC() == itemInfo.CRC); + outStream.Release(); + if(crcOK) + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)) + else + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError)) + } + } + return S_OK; + COM_TRY_END +} + + +}} diff --git a/CPP/7zip/Archive/Lzh/LzhHandler.h b/CPP/7zip/Archive/Lzh/LzhHandler.h new file mode 100755 index 00000000..2dc89494 --- /dev/null +++ b/CPP/7zip/Archive/Lzh/LzhHandler.h @@ -0,0 +1,47 @@ +// LzhHandler.h + +#ifndef __LZH_HANDLER_H +#define __LZH_HANDLER_H + +#include "Common/MyCom.h" +#include "../IArchive.h" +#include "LzhIn.h" + +namespace NArchive { +namespace NLzh { + +class CHandler: + public IInArchive, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Open)(IInStream *inStream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *callback); + STDMETHOD(Close)(); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *anExtractCallback); + + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + CHandler(); +private: + CObjectVector _items; + CMyComPtr _stream; +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Lzh/LzhHeader.h b/CPP/7zip/Archive/Lzh/LzhHeader.h new file mode 100755 index 00000000..845b9a21 --- /dev/null +++ b/CPP/7zip/Archive/Lzh/LzhHeader.h @@ -0,0 +1,19 @@ +// Archive/Lzh/Header.h + +#ifndef __ARCHIVE_LZH_HEADER_H +#define __ARCHIVE_LZH_HEADER_H + +#include "Common/Types.h" + +namespace NArchive { +namespace NLzh { + +const int kMethodIdSize = 5; + +const Byte kExtIdFileName = 0x01; +const Byte kExtIdDirName = 0x02; +const Byte kExtIdUnixTime = 0x54; + +}} + +#endif diff --git a/CPP/7zip/Archive/Lzh/LzhIn.cpp b/CPP/7zip/Archive/Lzh/LzhIn.cpp new file mode 100755 index 00000000..42ef50e4 --- /dev/null +++ b/CPP/7zip/Archive/Lzh/LzhIn.cpp @@ -0,0 +1,171 @@ +// Archive/arj/InEngine.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Common/Buffer.h" +#include "Common/CRC.h" + +#include "../../Common/StreamUtils.h" + +#include "LzhIn.h" + +namespace NArchive { +namespace NLzh { + +HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize) +{ + RINOK(ReadStream(m_Stream, data, size, &processedSize)); + m_Position += processedSize; + return S_OK; +} + +HRESULT CInArchive::CheckReadBytes(void *data, UInt32 size) +{ + UInt32 processedSize; + RINOK(ReadBytes(data, size, processedSize)); + return (processedSize == size) ? S_OK: S_FALSE; +} + +HRESULT CInArchive::Open(IInStream *inStream) +{ + RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position)); + m_Stream = inStream; + return S_OK; +} + +static const Byte *ReadUInt32(const Byte *p, UInt32 &v) +{ + v = 0; + for (int i = 0; i < 4; i++) + v |= ((UInt32)(*p++) << (i * 8)); + return p; +} + +static const Byte *ReadUInt16(const Byte *p, UInt16 &v) +{ + v = 0; + for (int i = 0; i < 2; i++) + v |= ((UInt16)(*p++) << (i * 8)); + return p; +} + +static const Byte *ReadString(const Byte *p, size_t size, AString &s) +{ + s.Empty(); + for (size_t i = 0; i < size; i++) + { + char c = p[i]; + if (c == 0) + break; + s += c; + } + return p + size; +} + +static Byte CalcSum(const Byte *data, size_t size) +{ + Byte sum = 0; + for (size_t i = 0; i < size; i++) + sum = (Byte)(sum + data[i]); + return sum; +} + +HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) +{ + filled = false; + + UInt32 processedSize; + Byte startHeader[2]; + RINOK(ReadBytes(startHeader, 2, processedSize)) + if (processedSize == 0) + return S_OK; + if (processedSize == 1) + return (startHeader[0] == 0) ? S_OK: S_FALSE; + if (startHeader[0] == 0 && startHeader[1] == 0) + return S_OK; + + Byte header[256]; + const UInt32 kBasicPartSize = 22; + RINOK(ReadBytes(header, kBasicPartSize, processedSize)); + if (processedSize != kBasicPartSize) + return (startHeader[0] == 0) ? S_OK: S_FALSE; + + const Byte *p = header; + memmove(item.Method, p, kMethodIdSize); + if (!item.IsValidMethod()) + return S_OK; + p += kMethodIdSize; + p = ReadUInt32(p, item.PackSize); + p = ReadUInt32(p, item.Size); + p = ReadUInt32(p, item.ModifiedTime); + item.Attributes = *p++; + item.Level = *p++; + if (item.Level > 2) + return S_FALSE; + UInt32 headerSize; + if (item.Level < 2) + { + headerSize = startHeader[0]; + if (headerSize < kBasicPartSize) + return S_FALSE; + UInt32 remain = headerSize - kBasicPartSize; + RINOK(CheckReadBytes(header + kBasicPartSize, remain)); + if (startHeader[1] != CalcSum(header, headerSize)) + return S_FALSE; + size_t nameLength = *p++; + if ((p - header) + nameLength + 2 > headerSize) + return S_FALSE; + p = ReadString(p, nameLength, item.Name); + } + else + headerSize = startHeader[0] | ((UInt32)startHeader[1] << 8); + p = ReadUInt16(p, item.CRC); + if (item.Level != 0) + { + if (item.Level == 2) + { + RINOK(CheckReadBytes(header + kBasicPartSize, 2)); + } + if ((size_t)(p - header) + 3 > headerSize) + return S_FALSE; + item.OsId = *p++; + UInt16 nextSize; + p = ReadUInt16(p, nextSize); + while (nextSize != 0) + { + if (nextSize < 3) + return S_FALSE; + if (item.Level == 1) + { + if (item.PackSize < nextSize) + return S_FALSE; + item.PackSize -= nextSize; + } + CExtension ext; + RINOK(CheckReadBytes(&ext.Type, 1)) + nextSize -= 3; + ext.Data.SetCapacity(nextSize); + RINOK(CheckReadBytes((Byte *)ext.Data, nextSize)) + item.Extensions.Add(ext); + Byte hdr2[2]; + RINOK(CheckReadBytes(hdr2, 2)); + ReadUInt16(hdr2, nextSize); + } + } + item.DataPosition = m_Position; + filled = true; + return S_OK; +} + +HRESULT CInArchive::Skeep(UInt64 numBytes) +{ + UInt64 newPostion; + RINOK(m_Stream->Seek(numBytes, STREAM_SEEK_CUR, &newPostion)); + m_Position += numBytes; + if (m_Position != newPostion) + return E_FAIL; + return S_OK; +} + +}} diff --git a/CPP/7zip/Archive/Lzh/LzhIn.h b/CPP/7zip/Archive/Lzh/LzhIn.h new file mode 100755 index 00000000..344a133f --- /dev/null +++ b/CPP/7zip/Archive/Lzh/LzhIn.h @@ -0,0 +1,29 @@ +// Archive/LzhIn.h + +#ifndef __ARCHIVE_LZHIN_H +#define __ARCHIVE_LZHIN_H + +#include "Common/MyCom.h" +#include "../../IStream.h" + +#include "LzhItem.h" + +namespace NArchive { +namespace NLzh { + +class CInArchive +{ + CMyComPtr m_Stream; + UInt64 m_Position; + + HRESULT ReadBytes(void *data, UInt32 size, UInt32 &processedSize); + HRESULT CheckReadBytes(void *data, UInt32 size); +public: + HRESULT Open(IInStream *inStream); + HRESULT GetNextItem(bool &filled, CItemEx &itemInfo); + HRESULT Skeep(UInt64 numBytes); +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Lzh/LzhItem.h b/CPP/7zip/Archive/Lzh/LzhItem.h new file mode 100755 index 00000000..66d4ed75 --- /dev/null +++ b/CPP/7zip/Archive/Lzh/LzhItem.h @@ -0,0 +1,172 @@ +// Archive/LzhItem.h + +#ifndef __ARCHIVE_LZH_ITEM_H +#define __ARCHIVE_LZH_ITEM_H + +#include "Common/Types.h" +#include "Common/String.h" +#include "Common/Buffer.h" +#include "LzhHeader.h" + +namespace NArchive { +namespace NLzh { + +struct CExtension +{ + Byte Type; + CByteBuffer Data; + AString GetString() const + { + AString s; + for (size_t i = 0; i < Data.GetCapacity(); i++) + { + char c = (char)Data[i]; + if (c == 0) + break; + s += c; + } + return s; + } +}; + +struct CItem +{ +public: + AString Name; + Byte Method[kMethodIdSize]; + UInt32 PackSize; + UInt32 Size; + UInt32 ModifiedTime; + Byte Attributes; + Byte Level; + UInt16 CRC; + Byte OsId; + CObjectVector Extensions; + + bool IsValidMethod() const { return (Method[0] == '-' && Method[1] == 'l' && Method[4] == '-'); } + bool IsLhMethod() const {return (IsValidMethod() && Method[2] == 'h'); } + bool IsDirectory() const {return (IsLhMethod() && Method[3] == 'd'); } + + bool IsCopyMethod() const + { + return (IsLhMethod() && Method[3] == '0') || + (IsValidMethod() && Method[2] == 'z' && Method[3] == '4'); + } + + bool IsLh1GroupMethod() const + { + if (!IsLhMethod()) + return false; + switch(Method[3]) + { + case '1': + return true; + } + return false; + } + + bool IsLh4GroupMethod() const + { + if (!IsLhMethod()) + return false; + switch(Method[3]) + { + case '4': + case '5': + case '6': + case '7': + return true; + } + return false; + } + + int GetNumDictBits() const + { + if (!IsLhMethod()) + return 0; + switch(Method[3]) + { + case '1': + return 12; + case '2': + return 13; + case '3': + return 13; + case '4': + return 12; + case '5': + return 13; + case '6': + return 15; + case '7': + return 16; + } + return 0; + } + + int FindExt(Byte type) const + { + for (int i = 0; i < Extensions.Size(); i++) + if (Extensions[i].Type == type) + return i; + return -1; + } + bool GetUnixTime(UInt32 &value) const + { + int index = FindExt(kExtIdUnixTime); + if (index < 0) + { + if (Level == 2) + { + value = ModifiedTime; + return true; + } + return false; + } + const Byte *data = (const Byte *)(Extensions[index].Data); + value = data[0] | + ((UInt32)data[1] << 8) | + ((UInt32)data[2] << 16) | + ((UInt32)data[3] << 24); + return true; + } + + AString GetDirName() const + { + int index = FindExt(kExtIdDirName); + if (index < 0) + return AString(); + return Extensions[index].GetString(); + } + + AString GetFileName() const + { + int index = FindExt(kExtIdFileName); + if (index < 0) + return Name; + return Extensions[index].GetString(); + } + + AString GetName() const + { + AString dirName = GetDirName(); + dirName.Replace((char)(unsigned char)0xFF, '\\'); + if (!dirName.IsEmpty()) + { + char c = dirName[dirName.Length() - 1]; + if (c != '\\') + dirName += '\\'; + } + return dirName + GetFileName(); + } +}; + +class CItemEx: public CItem +{ +public: + UInt64 DataPosition; +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp b/CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp new file mode 100755 index 00000000..2281a884 --- /dev/null +++ b/CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp @@ -0,0 +1,27 @@ +// LzhOutStreamWithCRC.cpp + +#include "StdAfx.h" + +#include "LzhOutStreamWithCRC.h" + +namespace NArchive { +namespace NLzh { + +STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize; + HRESULT result; + if(!_stream) + { + realProcessedSize = size; + result = S_OK; + } + else + result = _stream->Write(data, size, &realProcessedSize); + _crc.Update(data, realProcessedSize); + if(processedSize != NULL) + *processedSize = realProcessedSize; + return result; +} + +}} diff --git a/CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.h b/CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.h new file mode 100755 index 00000000..31b536b7 --- /dev/null +++ b/CPP/7zip/Archive/Lzh/LzhOutStreamWithCRC.h @@ -0,0 +1,38 @@ +// LzhOutStreamWithCRC.h + +#ifndef __LZHOUTSTREAMWITHCRC_H +#define __LZHOUTSTREAMWITHCRC_H + +#include "LzhCRC.h" +#include "../../../Common/MyCom.h" +#include "../../IStream.h" + +namespace NArchive { +namespace NLzh { + +class COutStreamWithCRC: + public ISequentialOutStream, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +private: + CCRC _crc; + CMyComPtr _stream; +public: + void Init(ISequentialOutStream *stream) + { + _stream = stream; + _crc.Init(); + } + void ReleaseStream() { _stream.Release(); } + UInt32 GetCRC() const { return _crc.GetDigest(); } + void InitCRC() { _crc.Init(); } + +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Lzh/StdAfx.cpp b/CPP/7zip/Archive/Lzh/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Archive/Lzh/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Lzh/StdAfx.h b/CPP/7zip/Archive/Lzh/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Archive/Lzh/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Archive/Lzh/lzh.ico b/CPP/7zip/Archive/Lzh/lzh.ico new file mode 100755 index 00000000..84dab49c Binary files /dev/null and b/CPP/7zip/Archive/Lzh/lzh.ico differ diff --git a/CPP/7zip/Archive/Lzh/makefile b/CPP/7zip/Archive/Lzh/makefile new file mode 100755 index 00000000..6f8fd2a0 --- /dev/null +++ b/CPP/7zip/Archive/Lzh/makefile @@ -0,0 +1,65 @@ +PROG = lzh.dll +DEF_FILE = ../Archive.def +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib user32.lib + +LZH_OBJS = \ + $O\DllExports.obj \ + $O\LzhCRC.obj \ + $O\LzhHandler.obj \ + $O\LzhIn.obj \ + $O\LzhOutStreamWithCRC.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\Vector.obj \ + +WIN_OBJS = \ + $O\PropVariant.obj \ + +7ZIP_COMMON_OBJS = \ + $O\InBuffer.obj \ + $O\LimitedStreams.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ + +AR_COMMON_OBJS = \ + $O\ItemNameUtils.obj \ + +COMPRESS_LZH_OBJS = \ + $O\LzhDecoder.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(LZH_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $(COMPRESS_LZH_OBJS) \ + $O\CopyCoder.obj \ + $O\LZOutWindow.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(LZH_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$(COMPRESS_LZH_OBJS): ../../Compress/Lzh/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) +$O\LZOutWindow.obj: ../../Compress/LZ/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/Archive/Lzh/resource.rc b/CPP/7zip/Archive/Lzh/resource.rc new file mode 100755 index 00000000..2870e520 --- /dev/null +++ b/CPP/7zip/Archive/Lzh/resource.rc @@ -0,0 +1,5 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("Lzh Plugin", "lzh") + +101 ICON "lzh.ico" diff --git a/CPP/7zip/Archive/Nsis/DllExports.cpp b/CPP/7zip/Archive/Nsis/DllExports.cpp new file mode 100755 index 00000000..f10f56ea --- /dev/null +++ b/CPP/7zip/Archive/Nsis/DllExports.cpp @@ -0,0 +1,110 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "Windows/PropVariant.h" +#include "../../ICoder.h" +#include "NsisHandler.h" + +// {23170F69-40C1-278A-1000-000110090000} +DEFINE_GUID(CLSID_CNsisHandler, + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x09, 0x00, 0x00); + +HINSTANCE g_hInstance; +#ifndef _UNICODE +bool g_IsNT = false; +static bool IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); +} +#endif + +extern "C" +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + g_hInstance = hInstance; + #ifndef _UNICODE + g_IsNT = IsItWindowsNT(); + #endif + } + return TRUE; +} + +STDAPI CreateObject( + const GUID *classID, + const GUID *interfaceID, + void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + if (*classID != CLSID_CNsisHandler) + return CLASS_E_CLASSNOTAVAILABLE; + int needIn = *interfaceID == IID_IInArchive; + // int needOut = *interfaceID == IID_IOutArchive; + if (needIn /*|| needOut */) + { + NArchive::NNsis::CHandler *temp = new NArchive::NNsis::CHandler; + if (needIn) + { + CMyComPtr inArchive = (IInArchive *)temp; + *outObject = inArchive.Detach(); + } + /* + else + { + CMyComPtr outArchive = (IOutArchive *)temp; + *outObject = outArchive.Detach(); + } + */ + } + else + return E_NOINTERFACE; + COM_TRY_END + return S_OK; +} + +STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case NArchive::kName: + propVariant = L"Nsis"; + break; + case NArchive::kClassID: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CNsisHandler, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NArchive::kExtension: + propVariant = L"exe"; + break; + case NArchive::kUpdate: + propVariant = false; + break; + case NArchive::kStartSignature: + { + if ((value->bstrVal = ::SysAllocStringByteLen((const char *)NArchive::NNsis::kSignature, + NArchive::NNsis::kSignatureSize)) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NArchive::kAssociate: + { + propVariant = false; + break; + } + } + propVariant.Detach(value); + return S_OK; +} diff --git a/CPP/7zip/Archive/Nsis/Nsis.dsp b/CPP/7zip/Archive/Nsis/Nsis.dsp new file mode 100755 index 00000000..45ce0386 --- /dev/null +++ b/CPP/7zip/Archive/Nsis/Nsis.dsp @@ -0,0 +1,337 @@ +# Microsoft Developer Studio Project File - Name="Nsis" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Nsis - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Nsis.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Nsis.mak" CFG="Nsis - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Nsis - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Nsis - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Nsis - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TAR_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TAR_EXPORTS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\nsis.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Nsis - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TAR_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TAR_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\nsis.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Nsis - Win32 Release" +# Name "Nsis - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Archive.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\Nsis.ico +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Buffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\NsisDecode.cpp +# End Source File +# Begin Source File + +SOURCE=.\NsisDecode.h +# End Source File +# Begin Source File + +SOURCE=.\NsisHandler.cpp +# End Source File +# Begin Source File + +SOURCE=.\NsisHandler.h +# End Source File +# Begin Source File + +SOURCE=.\NsisIn.cpp +# End Source File +# Begin Source File + +SOURCE=.\NsisIn.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\CodecsPath.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\CodecsPath.h +# End Source File +# Begin Source File + +SOURCE=..\Common\CoderLoader.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\CoderLoader.h +# End Source File +# Begin Source File + +SOURCE=..\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "7z" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\7z\7zMethodID.cpp +# End Source File +# Begin Source File + +SOURCE=..\7z\7zMethodID.h +# End Source File +# Begin Source File + +SOURCE=..\7z\7zMethods.cpp +# End Source File +# Begin Source File + +SOURCE=..\7z\7zMethods.h +# End Source File +# End Group +# End Target +# End Project diff --git a/CPP/7zip/Archive/Nsis/Nsis.dsw b/CPP/7zip/Archive/Nsis/Nsis.dsw new file mode 100755 index 00000000..d3df6d27 --- /dev/null +++ b/CPP/7zip/Archive/Nsis/Nsis.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Nsis"=.\Nsis.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Archive/Nsis/NsisDecode.cpp b/CPP/7zip/Archive/Nsis/NsisDecode.cpp new file mode 100755 index 00000000..d49b2312 --- /dev/null +++ b/CPP/7zip/Archive/Nsis/NsisDecode.cpp @@ -0,0 +1,150 @@ +// NsisDecode.cpp + +#include "StdAfx.h" + +#include "NsisDecode.h" + +#include "../../Common/StreamUtils.h" + +#include "../7z/7zMethods.h" + +namespace NArchive { +namespace NNsis { + +static const N7z::CMethodID k_Copy = { { 0x0 }, 1 }; +static const N7z::CMethodID k_Deflate = { { 0x4, 0x9, 0x1 }, 3 }; +static const N7z::CMethodID k_BZip2 = { { 0x4, 0x9, 0x2 }, 3 }; +static const N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 }; +static const N7z::CMethodID k_BCJ_X86 = { { 0x3, 0x3, 0x1, 0x3 }, 4 }; + +CDecoder::CDecoder() +{ + N7z::LoadMethodMap(); +} + +HRESULT CDecoder::Init(IInStream *inStream, NMethodType::EEnum method, bool thereIsFilterFlag, bool &useFilter) +{ + useFilter = false; + CObjectVector< CMyComPtr > inStreams; + + if (_decoderInStream) + if (method != _method) + Release(); + _method = method; + if (!_codecInStream) + { + const NArchive::N7z::CMethodID *methodID = 0; + switch (method) + { + case NMethodType::kCopy: + methodID = &k_Copy; + break; + case NMethodType::kDeflate: + methodID = &k_Deflate; + break; + case NMethodType::kBZip2: + methodID = &k_BZip2; + break; + case NMethodType::kLZMA: + methodID = &k_LZMA; + break; + default: + return E_NOTIMPL; + } + N7z::CMethodInfo methodInfo; + if (!N7z::GetMethodInfo(*methodID, methodInfo)) + return E_NOTIMPL; + CMyComPtr coder; + RINOK(_libraries.CreateCoder(methodInfo.FilePath, methodInfo.Decoder, &coder)); + coder.QueryInterface(IID_ISequentialInStream, &_codecInStream); + if (!_codecInStream) + return E_NOTIMPL; + } + + if (thereIsFilterFlag) + { + UInt32 processedSize; + BYTE flag; + RINOK(inStream->Read(&flag, 1, &processedSize)); + if (processedSize != 1) + return E_FAIL; + if (flag > 1) + return E_NOTIMPL; + useFilter = (flag != 0); + } + + if (useFilter) + { + if (!_filterInStream) + { + N7z::CMethodInfo methodInfo; + if (!N7z::GetMethodInfo(k_BCJ_X86, methodInfo)) + return E_NOTIMPL; + CMyComPtr coder; + RINOK(_libraries.CreateCoderSpec(methodInfo.FilePath, methodInfo.Decoder, &coder)); + coder.QueryInterface(IID_ISequentialInStream, &_filterInStream); + if (!_filterInStream) + return E_NOTIMPL; + } + CMyComPtr setInStream; + _filterInStream.QueryInterface(IID_ICompressSetInStream, &setInStream); + if (!setInStream) + return E_NOTIMPL; + RINOK(setInStream->SetInStream(_codecInStream)); + _decoderInStream = _filterInStream; + } + else + _decoderInStream = _codecInStream; + + if (method == NMethodType::kLZMA) + { + CMyComPtr setDecoderProperties; + _codecInStream.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties); + if (setDecoderProperties) + { + static const UInt32 kPropertiesSize = 5; + BYTE properties[kPropertiesSize]; + UInt32 processedSize; + RINOK(inStream->Read(properties, kPropertiesSize, &processedSize)); + if (processedSize != kPropertiesSize) + return E_FAIL; + RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)properties, kPropertiesSize)); + } + } + + { + CMyComPtr setInStream; + _codecInStream.QueryInterface(IID_ICompressSetInStream, &setInStream); + if (!setInStream) + return E_NOTIMPL; + RINOK(setInStream->SetInStream(inStream)); + } + + { + CMyComPtr setOutStreamSize; + _codecInStream.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize); + if (!setOutStreamSize) + return E_NOTIMPL; + RINOK(setOutStreamSize->SetOutStreamSize(NULL)); + } + + if (useFilter) + { + /* + CMyComPtr setOutStreamSize; + _filterInStream.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize); + if (!setOutStreamSize) + return E_NOTIMPL; + RINOK(setOutStreamSize->SetOutStreamSize(NULL)); + */ + } + + return S_OK; +} + +HRESULT CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + return ReadStream(_decoderInStream, data, size, processedSize);; +} + +}} diff --git a/CPP/7zip/Archive/Nsis/NsisDecode.h b/CPP/7zip/Archive/Nsis/NsisDecode.h new file mode 100755 index 00000000..1bec178f --- /dev/null +++ b/CPP/7zip/Archive/Nsis/NsisDecode.h @@ -0,0 +1,47 @@ +// NsisDecode.h + +#ifndef __NSIS_DECODE_H +#define __NSIS_DECODE_H + +#include "../../IStream.h" + +#include "../Common/CoderLoader.h" + +namespace NArchive { +namespace NNsis { + +namespace NMethodType +{ + enum EEnum + { + kCopy, + kDeflate, + kBZip2, + kLZMA + }; +} + +class CDecoder +{ + NMethodType::EEnum _method; + CCoderLibraries _libraries; + + CMyComPtr _filterInStream; + CMyComPtr _codecInStream; + CMyComPtr _decoderInStream; + +public: + CDecoder(); + void Release() + { + _filterInStream.Release(); + _codecInStream.Release(); + _decoderInStream.Release(); + } + HRESULT Init(IInStream *inStream, NMethodType::EEnum method, bool thereIsFilterFlag, bool &useFilter); + HRESULT Read(void *data, UInt32 size, UInt32 *processedSize); +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Nsis/NsisHandler.cpp b/CPP/7zip/Archive/Nsis/NsisHandler.cpp new file mode 100755 index 00000000..0d840479 --- /dev/null +++ b/CPP/7zip/Archive/Nsis/NsisHandler.cpp @@ -0,0 +1,484 @@ +// NSisHandler.cpp + +#include "StdAfx.h" + +#include "NsisHandler.h" + +#include "Common/StringConvert.h" +#include "Common/IntToString.h" +#include "Common/NewHandler.h" +#include "Common/ComTry.h" + +#include "Windows/PropVariant.h" + +#include "../Common/ItemNameUtils.h" + +using namespace NWindows; + +namespace NArchive { +namespace NNsis { + +static const wchar_t *kBcjMethod = L"BCJ"; +static const wchar_t *kUnknownMethod = L"Unknown"; + +static const wchar_t *kMethods[] = +{ + L"Copy", + L"Deflate", + L"BZip2", + L"LZMA" +}; + +static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]); + +STATPROPSTG kProperties[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackedSize, VT_UI8}, + { NULL, kpidLastWriteTime, VT_FILETIME}, + { NULL, kpidMethod, VT_BSTR}, + { NULL, kpidSolid, VT_BOOL} +}; + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) +{ + value->vt = VT_EMPTY; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if(index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &srcItem = kProperties[index]; + *propID = srcItem.propid; + *varType = srcItem.vt; + *name = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +{ + *numProperties = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, + BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) +{ + return E_INVALIDARG; +} + +STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 * maxCheckStartPosition, IArchiveOpenCallback * /* openArchiveCallback */) +{ + COM_TRY_BEGIN + Close(); + { + if(_archive.Open(stream, maxCheckStartPosition) != S_OK) + return S_FALSE; + _inStream = stream; + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + _archive.Clear(); + _archive.Release(); + _inStream.Release(); + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _archive.Items.Size() + #ifdef NSIS_SCRIPT + + 1 + #endif + ; + return S_OK; +} + +static UString ConvertUInt32ToString(UInt32 value) +{ + wchar_t buffer[32]; + ConvertUInt64ToString(value, buffer); + return buffer; +} + +static UString GetStringForSizeValue(UInt32 value) +{ + for (int i = 31; i >= 0; i--) + if ((UInt32(1) << i) == value) + return ConvertUInt32ToString(i); + UString result; + if (value % (1 << 20) == 0) + { + result += ConvertUInt32ToString(value >> 20); + result += L"m"; + } + else if (value % (1 << 10) == 0) + { + result += ConvertUInt32ToString(value >> 10); + result += L"k"; + } + else + { + result += ConvertUInt32ToString(value); + result += L"b"; + } + return result; +} + +bool CHandler::GetUncompressedSize(int index, UInt32 &size) +{ + size = 0; + const CItem &item = _archive.Items[index]; + if (item.SizeIsDefined) + size = item.Size; + else if (_archive.IsSolid && item.EstimatedSizeIsDefined) + size = item.EstimatedSize; + else + return false; + return true; +} + +bool CHandler::GetCompressedSize(int index, UInt32 &size) +{ + size = 0; + const CItem &item = _archive.Items[index]; + if (item.CompressedSizeIsDefined) + size = item.CompressedSize; + else + { + if (_archive.IsSolid) + { + if (index == 0) + size = _archive.FirstHeader.GetDataSize(); + else + return false; + } + else + { + if (!item.IsCompressed) + size = item.Size; + else + return false; + } + } + return true; +} + + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant propVariant; + #ifdef NSIS_SCRIPT + if (index >= (UInt32)_archive.Items.Size()) + { + switch(propID) + { + case kpidPath: + propVariant = L"[NSIS].nsi"; + break; + case kpidIsFolder: + propVariant = false; + break; + case kpidSize: + case kpidPackedSize: + propVariant = (UInt64)_archive.Script.Length(); + break; + case kpidSolid: + propVariant = false; + break; + } + } + else + #endif + { + const CItem &item = _archive.Items[index]; + switch(propID) + { + case kpidPath: + { + const UString s = NItemName::WinNameToOSName(MultiByteToUnicodeString(item.GetReducedName(), CP_ACP)); + propVariant = (const wchar_t *)s; + break; + } + case kpidIsFolder: + propVariant = false; + break; + case kpidSize: + { + UInt32 size; + if (GetUncompressedSize(index, size)) + propVariant = (UInt64)size; + break; + } + case kpidPackedSize: + { + UInt32 size; + if (GetCompressedSize(index, size)) + propVariant = (UInt64)size; + break; + } + case kpidLastWriteTime: + { + if (item.DateTime.dwHighDateTime > 0x01000000 && + item.DateTime.dwHighDateTime < 0xFF000000) + propVariant = item.DateTime; + break; + } + case kpidMethod: + { + NMethodType::EEnum methodIndex = _archive.Method; + UString method; + if (_archive.IsSolid && _archive.UseFilter || !_archive.IsSolid && item.UseFilter) + { + method += kBcjMethod; + method += L" "; + } + method += (methodIndex < kNumMethods) ? kMethods[methodIndex] : kUnknownMethod; + if (methodIndex == NMethodType::kLZMA) + { + method += L":"; + method += GetStringForSizeValue(_archive.IsSolid ? _archive.DictionarySize: item.DictionarySize); + } + propVariant = method; + break; + } + case kpidSolid: + propVariant = _archive.IsSolid; + break; + } + } + propVariant.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool testMode = (_aTestMode != 0); + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + GetNumberOfItems(&numItems); + if(numItems == 0) + return S_OK; + UInt64 totalSize = 0; + + UInt32 i; + for(i = 0; i < numItems; i++) + { + UInt32 index = (allFilesMode ? i : indices[i]); + #ifdef NSIS_SCRIPT + if (index >= (UInt32)_archive.Items.Size()) + totalSize += _archive.Script.Length(); + else + #endif + { + UInt32 size; + if (_archive.IsSolid) + { + GetUncompressedSize(index, size); + UInt64 pos = _archive.GetPosOfSolidItem(index); + if (pos > totalSize) + totalSize = pos + size; + } + else + { + GetCompressedSize(index, size); + totalSize += size; + } + } + } + extractCallback->SetTotal(totalSize); + + UInt64 currentTotalSize = 0; + UInt32 currentItemSize = 0; + + UInt64 streamPos = 0; + if (_archive.IsSolid) + { + RINOK(_inStream->Seek(_archive.StreamOffset, STREAM_SEEK_SET, NULL)); + bool useFilter; + RINOK(_archive.Decoder.Init(_inStream, _archive.Method, _archive.FilterFlag, useFilter)); + } + + bool dataError = false; + for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + { + currentItemSize = 0; + RINOK(extractCallback->SetCompleted(¤tTotalSize)); + CMyComPtr realOutStream; + Int32 askMode; + askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; + UInt32 index = allFilesMode ? i : indices[i]; + + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + + #ifdef NSIS_SCRIPT + if (index >= (UInt32)_archive.Items.Size()) + { + currentItemSize = _archive.Script.Length(); + if(!testMode && (!realOutStream)) + continue; + RINOK(extractCallback->PrepareOperation(askMode)); + if (!testMode) + RINOK(realOutStream->Write((const char *)_archive.Script, (UInt32)_archive.Script.Length(), NULL)); + } + else + #endif + { + const CItem &item = _archive.Items[index]; + + if (_archive.IsSolid) + GetUncompressedSize(index, currentItemSize); + else + GetCompressedSize(index, currentItemSize); + + if(!testMode && (!realOutStream)) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)); + + if (!dataError) + { + bool needDecompress = false; + bool sizeIsKnown = false; + UInt32 fullSize = 0; + + const UInt32 kBufferLength = 1 << 11; + Byte buffer[kBufferLength]; + + if (_archive.IsSolid) + { + UInt64 pos = _archive.GetPosOfSolidItem(index); + while(streamPos < pos) + { + UInt32 curSize = (UInt32)MyMin(pos - streamPos, (UInt64)kBufferLength); + UInt32 processedSize; + HRESULT res = _archive.Decoder.Read(buffer, curSize, &processedSize); + if (res != S_OK) + { + if (res != S_FALSE) + return res; + dataError = true; + break; + } + if (processedSize == 0) + { + dataError = true; + break; + } + streamPos += processedSize; + } + if (streamPos == pos) + { + UInt32 processedSize; + RINOK(_archive.Decoder.Read(buffer, 4, &processedSize)); + if (processedSize != 4) + return E_FAIL; + streamPos += processedSize; + fullSize = GetUInt32FromMemLE(buffer); + sizeIsKnown = true; + needDecompress = true; + } + } + else + { + RINOK(_inStream->Seek(_archive.GetPosOfNonSolidItem(index) + 4, STREAM_SEEK_SET, NULL)); + if (item.IsCompressed) + { + needDecompress = true; + bool useFilter; + RINOK(_archive.Decoder.Init(_inStream, _archive.Method, _archive.FilterFlag, useFilter)); + fullSize = GetUInt32FromMemLE(buffer); + } + else + fullSize = item.Size; + } + if (!dataError) + { + if (needDecompress) + { + UInt64 offset = 0; + while(!sizeIsKnown || fullSize > 0) + { + UInt32 curSize = kBufferLength; + if (sizeIsKnown && curSize > fullSize) + curSize = fullSize; + UInt32 processedSize; + HRESULT res = _archive.Decoder.Read(buffer, curSize, &processedSize); + if (res != S_OK) + { + if (res != S_FALSE) + return res; + dataError = true; + break; + } + if (processedSize == 0) + { + if (sizeIsKnown) + dataError = true; + break; + } + + fullSize -= processedSize; + streamPos += processedSize; + offset += processedSize; + + UInt64 completed; + if (_archive.IsSolid) + completed = streamPos; + else + completed = currentTotalSize + offset; + RINOK(extractCallback->SetCompleted(&completed)); + if (!testMode) + RINOK(realOutStream->Write(buffer, processedSize, NULL)); + } + } + else + { + while(fullSize > 0) + { + UInt32 curSize = MyMin(fullSize, kBufferLength); + UInt32 processedSize; + RINOK(_inStream->Read(buffer, curSize, &processedSize)); + if (processedSize == 0) + { + dataError = true; + break; + } + fullSize -= processedSize; + streamPos += processedSize; + if (!testMode) + RINOK(realOutStream->Write(buffer, processedSize, 0)); + } + } + } + } + } + if (!testMode) + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(dataError ? + NArchive::NExtract::NOperationResult::kDataError : + NArchive::NExtract::NOperationResult::kOK)); + } + return S_OK; + COM_TRY_END +} + +}} diff --git a/CPP/7zip/Archive/Nsis/NsisHandler.h b/CPP/7zip/Archive/Nsis/NsisHandler.h new file mode 100755 index 00000000..1ff8b776 --- /dev/null +++ b/CPP/7zip/Archive/Nsis/NsisHandler.h @@ -0,0 +1,41 @@ +// NSisHandler.h + +#ifndef __NSIS_HANDLER_H +#define __NSIS_HANDLER_H + +#include "Common/MyCom.h" +#include "../IArchive.h" + +#include "NsisIn.h" + +namespace NArchive { +namespace NNsis { + +class CHandler: + public IInArchive, + public CMyUnknownImp +{ + CMyComPtr _inStream; + CInArchive _archive; + + bool GetUncompressedSize(int index, UInt32 &size); + bool GetCompressedSize(int index, UInt32 &size); + +public: + MY_UNKNOWN_IMP1(IInArchive) + + STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback); + STDMETHOD(Close)(); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback); + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType); +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Nsis/NsisIn.cpp b/CPP/7zip/Archive/Nsis/NsisIn.cpp new file mode 100755 index 00000000..0db6ccfd --- /dev/null +++ b/CPP/7zip/Archive/Nsis/NsisIn.cpp @@ -0,0 +1,1169 @@ +// Archive/NsisIn.cpp + +#include "StdAfx.h" + +#include "NsisIn.h" +#include "NsisDecode.h" + +#include "Windows/Defs.h" + +#include "../../Common/StreamUtils.h" + +#include "Common/IntToString.h" + +namespace NArchive { +namespace NNsis { + +Byte kSignature[kSignatureSize] = { 0xEF + 1, 0xBE, 0xAD, 0xDE, +0x4E, 0x75, 0x6C, 0x6C, 0x73, 0x6F, 0x66, 0x74, 0x49, 0x6E, 0x73, 0x74}; + +class SignatureInitializer +{ +public: + SignatureInitializer() { kSignature[0]--; }; +} g_SignatureInitializer; + +static const char *kCrLf = "\x0D\x0A"; + +UInt32 GetUInt32FromMemLE(const Byte *p) +{ + return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24); +} + +Byte CInArchive::ReadByte() +{ + if (_posInData >= _size) + throw 1; + return _data[_posInData++]; +} + +UInt32 CInArchive::ReadUInt32() +{ + UInt32 value = 0; + for (int i = 0; i < 4; i++) + value |= ((UInt32)(ReadByte()) << (8 * i)); + return value; +} + +void CInArchive::ReadBlockHeader(CBlockHeader &bh) +{ + bh.Offset = ReadUInt32(); + bh.Num = ReadUInt32(); +} + +#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } + +static int CompareItems(void *const *p1, void *const *p2, void * /* param */) +{ + RINOZ(MyCompare( + (**(const CItem **)p1).Pos, + (**(const CItem **)p2).Pos)); + return 0; +} + +AString CInArchive::ReadString(UInt32 pos) +{ + AString s; + UInt32 offset = GetOffset() + _stringsPos + pos; + for (;;) + { + if (offset >= _size) + throw 1; + char c = _data[offset++]; + if (c == 0) + break; + s += c; + } + return s; +} + +/* +static AString ParsePrefix(const AString &prefix) +{ + AString res = prefix; + if (prefix.Length() >= 3) + { + if ((Byte)prefix[0] == 0xFD && (Byte)prefix[1] == 0x95 && (Byte)prefix[2] == 0x80) + res = "$INSTDIR" + prefix.Mid(3); + else if ((Byte)prefix[0] == 0xFD && (Byte)prefix[1] == 0x96 && (Byte)prefix[2] == 0x80) + res = "$OUTDIR" + prefix.Mid(3); + } + return res; +} +*/ + +#define SYSREGKEY "Software\\Microsoft\\Windows\\CurrentVersion" + +/* +# define CSIDL_PROGRAMS 0x2 +# define CSIDL_PRINTERS 0x4 +# define CSIDL_PERSONAL 0x5 +# define CSIDL_FAVORITES 0x6 +# define CSIDL_STARTUP 0x7 +# define CSIDL_RECENT 0x8 +# define CSIDL_SENDTO 0x9 +# define CSIDL_STARTMENU 0xB +# define CSIDL_MYMUSIC 0xD +# define CSIDL_MYVIDEO 0xE + +# define CSIDL_DESKTOPDIRECTORY 0x10 +# define CSIDL_NETHOOD 0x13 +# define CSIDL_FONTS 0x14 +# define CSIDL_TEMPLATES 0x15 +# define CSIDL_COMMON_STARTMENU 0x16 +# define CSIDL_COMMON_PROGRAMS 0x17 +# define CSIDL_COMMON_STARTUP 0x18 +# define CSIDL_COMMON_DESKTOPDIRECTORY 0x19 +# define CSIDL_APPDATA 0x1A +# define CSIDL_PRINTHOOD 0x1B +# define CSIDL_LOCAL_APPDATA 0x1C +# define CSIDL_ALTSTARTUP 0x1D +# define CSIDL_COMMON_ALTSTARTUP 0x1E +# define CSIDL_COMMON_FAVORITES 0x1F + +# define CSIDL_INTERNET_CACHE 0x20 +# define CSIDL_COOKIES 0x21 +# define CSIDL_HISTORY 0x22 +# define CSIDL_COMMON_APPDATA 0x23 +# define CSIDL_WINDOWS 0x24 +# define CSIDL_SYSTEM 0x25 +# define CSIDL_PROGRAM_FILES 0x26 +# define CSIDL_MYPICTURES 0x27 +# define CSIDL_PROFILE 0x28 +# define CSIDL_PROGRAM_FILES_COMMON 0x2B +# define CSIDL_COMMON_TEMPLATES 0x2D +# define CSIDL_COMMON_DOCUMENTS 0x2E +# define CSIDL_COMMON_ADMINTOOLS 0x2F + +# define CSIDL_ADMINTOOLS 0x30 +# define CSIDL_COMMON_MUSIC 0x35 +# define CSIDL_COMMON_PICTURES 0x36 +# define CSIDL_COMMON_VIDEO 0x37 +# define CSIDL_RESOURCES 0x38 +# define CSIDL_RESOURCES_LOCALIZED 0x39 +# define CSIDL_CDBURN_AREA 0x3B +*/ + +struct CCommandPair +{ + int NumParams; + const char *Name; +}; + +enum +{ + // 0 + EW_INVALID_OPCODE, // zero is invalid. useful for catching errors. (otherwise an all zeroes instruction + // does nothing, which is easily ignored but means something is wrong. + EW_RET, // return from function call + EW_NOP, // Nop/Jump, do nothing: 1, [?new address+1:advance one] + EW_ABORT, // Abort: 1 [status] + EW_QUIT, // Quit: 0 + EW_CALL, // Call: 1 [new address+1] + EW_UPDATETEXT, // Update status text: 2 [update str, ui_st_updateflag=?ui_st_updateflag:this] + EW_SLEEP, // Sleep: 1 [sleep time in milliseconds] + EW_BRINGTOFRONT, // BringToFront: 0 + EW_CHDETAILSVIEW, // SetDetailsView: 2 [listaction,buttonaction] + + // 10 + EW_SETFILEATTRIBUTES, // SetFileAttributes: 2 [filename, attributes] + EW_CREATEDIR, // Create directory: 2, [path, ?update$INSTDIR] + EW_IFFILEEXISTS, // IfFileExists: 3, [file name, jump amount if exists, jump amount if not exists] + EW_SETFLAG, // Sets a flag: 2 [id, data] + EW_IFFLAG, // If a flag: 4 [on, off, id, new value mask] + EW_GETFLAG, // Gets a flag: 2 [output, id] + EW_RENAME, // Rename: 3 [old, new, rebootok] + EW_GETFULLPATHNAME, // GetFullPathName: 2 [output, input, ?lfn:sfn] + EW_SEARCHPATH, // SearchPath: 2 [output, filename] + EW_GETTEMPFILENAME, // GetTempFileName: 2 [output, base_dir] + + // 20 + EW_EXTRACTFILE, // File to extract: 6 [overwriteflag, output filename, compressed filedata, filedatetimelow, filedatetimehigh, allow ignore] + // overwriteflag: 0x1 = no. 0x0=force, 0x2=try, 0x3=if date is newer + EW_DELETEFILE, // Delete File: 2, [filename, rebootok] + EW_MESSAGEBOX, // MessageBox: 5,[MB_flags,text,retv1:retv2,moveonretv1:moveonretv2] + EW_RMDIR, // RMDir: 2 [path, recursiveflag] + EW_STRLEN, // StrLen: 2 [output, input] + EW_ASSIGNVAR, // Assign: 4 [variable (0-9) to assign, string to assign, maxlen, startpos] + EW_STRCMP, // StrCmp: 5 [str1, str2, jump_if_equal, jump_if_not_equal, case-sensitive?] + EW_READENVSTR, // ReadEnvStr/ExpandEnvStrings: 3 [output, string_with_env_variables, IsRead] + EW_INTCMP, // IntCmp: 6 [val1, val2, equal, val1val2, unsigned?] + EW_INTOP, // IntOp: 4 [output, input1, input2, op] where op: 0=add, 1=sub, 2=mul, 3=div, 4=bor, 5=band, 6=bxor, 7=bnot input1, 8=lnot input1, 9=lor, 10=land], 11=1%2 + + // 30 + EW_INTFMT, // IntFmt: [output, format, input] + EW_PUSHPOP, // Push/Pop/Exchange: 3 [variable/string, ?pop:push, ?exch] + EW_FINDWINDOW, // FindWindow: 5, [outputvar, window class,window name, window_parent, window_after] + EW_SENDMESSAGE, // SendMessage: 6 [output, hwnd, msg, wparam, lparam, [wparamstring?1:0 | lparamstring?2:0 | timeout<<2] + EW_ISWINDOW, // IsWindow: 3 [hwnd, jump_if_window, jump_if_notwindow] + EW_GETDLGITEM, // GetDlgItem: 3: [outputvar, dialog, item_id] + EW_SETCTLCOLORS, // SerCtlColors: 3: [hwnd, pointer to struct colors] + EW_SETBRANDINGIMAGE, // SetBrandingImage: 1: [Bitmap file] + EW_CREATEFONT, // CreateFont: 5: [handle output, face name, height, weight, flags] + EW_SHOWWINDOW, // ShowWindow: 2: [hwnd, show state] + + // 40 + EW_SHELLEXEC, // ShellExecute program: 4, [shell action, complete commandline, parameters, showwindow] + EW_EXECUTE, // Execute program: 3,[complete command line,waitflag,>=0?output errorcode] + EW_GETFILETIME, // GetFileTime; 3 [file highout lowout] + EW_GETDLLVERSION, // GetDLLVersion: 3 [file highout lowout] + EW_REGISTERDLL, // Register DLL: 3,[DLL file name, string ptr of function to call, text to put in display (<0 if none/pass parms), 1 - no unload, 0 - unload] + EW_CREATESHORTCUT, // Make Shortcut: 5, [link file, target file, parameters, icon file, iconindex|show mode<<8|hotkey<<16] + EW_COPYFILES, // CopyFiles: 3 [source mask, destination location, flags] + EW_REBOOT, // Reboot: 0 + EW_WRITEINI, // Write INI String: 4, [Section, Name, Value, INI File] + EW_READINISTR, // ReadINIStr: 4 [output, section, name, ini_file] + + // 50 + EW_DELREG, // DeleteRegValue/DeleteRegKey: 4, [root key(int), KeyName, ValueName, delkeyonlyifempty]. ValueName is -1 if delete key + EW_WRITEREG, // Write Registry value: 5, [RootKey(int),KeyName,ItemName,ItemData,typelen] + // typelen=1 for str, 2 for dword, 3 for binary, 0 for expanded str + EW_READREGSTR, // ReadRegStr: 5 [output, rootkey(int), keyname, itemname, ==1?int::str] + EW_REGENUM, // RegEnum: 5 [output, rootkey, keyname, index, ?key:value] + EW_FCLOSE, // FileClose: 1 [handle] + EW_FOPEN, // FileOpen: 4 [name, openmode, createmode, outputhandle] + EW_FPUTS, // FileWrite: 3 [handle, string, ?int:string] + EW_FGETS, // FileRead: 4 [handle, output, maxlen, ?getchar:gets] + EW_FSEEK, // FileSeek: 4 [handle, offset, mode, >=0?positionoutput] + EW_FINDCLOSE, // FindClose: 1 [handle] + + // 60 + EW_FINDNEXT, // FindNext: 2 [output, handle] + EW_FINDFIRST, // FindFirst: 2 [filespec, output, handleoutput] + EW_WRITEUNINSTALLER, // WriteUninstaller: 3 [name, offset, icon_size] + EW_LOG, // LogText: 2 [0, text] / LogSet: [1, logstate] + EW_SECTIONSET, // SectionSetText: 3: [idx, 0, text] + // SectionGetText: 3: [idx, 1, output] + // SectionSetFlags: 3: [idx, 2, flags] + // SectionGetFlags: 3: [idx, 3, output] + EW_INSTTYPESET, // InstTypeSetFlags: 3: [idx, 0, flags] + // InstTypeGetFlags: 3: [idx, 1, output] + // instructions not actually implemented in exehead, but used in compiler. + EW_GETLABELADDR, // both of these get converted to EW_ASSIGNVAR + EW_GETFUNCTIONADDR, + + EW_LOCKWINDOW +}; + +static CCommandPair kCommandPairs[] = +{ + { 0, "Invalid" }, + { 0, "Return" }, + { 1, "Goto" }, + { 0, "Abort" }, + { 0, "Quit" }, + { 1, "Call" }, + { 2, "UpdateSatusText" }, + { 1, "Sleep" }, + { 0, "BringToFront" }, + { 2, "SetDetailsView" }, + + { 2, "SetFileAttributes" }, + { 2, "SetOutPath" }, + { 3, "IfFileExists" }, + { 2, "SetFlag" }, + { 4, "IfFlag" }, + { 2, "GetFlag" }, + { 3, "Rename" }, + { 2, "GetFullPathName" }, + { 2, "SearchPath" }, + { 2, "GetTempFileName" }, + + { 6, "File" }, + { 2, "Delete" }, + { 5, "MessageBox" }, + { 2, "RMDir" }, + { 2, "Assign" }, + { 4, "StrCpy" }, + { 5, "StrCmp" }, + { 3, "ReadEnvStr" }, + { 6, "IntCmp" }, + { 4, "IntOp" }, + + { 3, "IntFmt" }, + { 3, "PushPop" }, + { 5, "FindWindow" }, + { 6, "SendMessage" }, + { 3, "IsWindow" }, + { 3, "GetDlgItem" }, + { 3, "SerCtlColors" }, + { 1, "SetBrandingImage" }, + { 5, "CreateFont" }, + { 2, "ShowWindow" }, + + { 4, "ShellExecute" }, + { 3, "Execute" }, + { 3, "GetFileTime" }, + { 3, "GetDLLVersion" }, + { 3, "RegisterDLL" }, + { 5, "CreateShortCut" }, + { 3, "CopyFiles" }, + { 0, "Reboot" }, + { 4, "WriteINIStr" }, + { 4, "ReadINIStr" }, + + { 4, "DelReg" }, + { 5, "WriteReg" }, + { 5, "ReadRegStr" }, + { 5, "RegEnum" }, + { 1, "FileClose" }, + { 4, "FileOpen" }, + { 3, "FileWrite" }, + { 4, "FileRead" }, + { 4, "FileSeek" }, + { 1, "FindClose" }, + + { 2, "FindNext" }, + { 2, "FindFirst" }, + { 3, "WriteUninstaller" }, + { 2, "LogText" }, + { 3, "Section?etText" }, + { 3, "InstType?etFlags" }, + { 6, "GetLabelAddr" }, + { 2, "GetFunctionAddress" }, + { 6, "LockWindow" } +}; + + +static const char *kShellStrings[] = +{ + "", + "", + + "SMPROGRAMS", + "", + "PRINTERS", + "DOCUMENTS", + "FAVORITES", + "SMSTARTUP", + "RECENT", + "SENDTO", + "", + "STARTMENU", + "", + "MUSIC", + "VIDEO", + "", + + "DESKTOP", + "", + "", + "NETHOOD", + "FONTS", + "TEMPLATES", + "COMMONSTARTMENU", + "COMMONFILES", + "COMMON_STARTUP", + "COMMON_DESKTOPDIRECTORY", + "QUICKLAUNCH", + "PRINTHOOD", + "LOCALAPPDATA", + "ALTSTARTUP", + "ALTSTARTUP", + "FAVORITES", + + "INTERNET_CACHE", + "COOKIES", + "HISTORY", + "APPDATA", + "WINDIR", + "SYSDIR", + "PROGRAMFILES", + "PICTURES", + "PROFILE", + "", + "", + "COMMONFILES", + "", + "TEMPLATES", + "DOCUMENTS", + "ADMINTOOLS", + + "ADMINTOOLS", + "", + "", + "", + "", + "MUSIC", + "PICTURES", + "VIDEO", + "RESOURCES", + "RESOURCES_LOCALIZED", + "", + "CDBURN_AREA" +}; + +static const int kNumShellStrings = sizeof(kShellStrings) / sizeof(kShellStrings[0]); + +/* +# define CMDLINE 20 // everything before here doesn't have trailing slash removal +# define INSTDIR 21 +# define OUTDIR 22 +# define EXEDIR 23 +# define LANGUAGE 24 +# define TEMP 25 +# define PLUGINSDIR 26 +# define HWNDPARENT 27 +# define _CLICK 28 +# define _OUTDIR 29 +*/ + +static const char *kVarStrings[] = +{ + "CMDLINE", + "INSTDIR", + "OUTDIR", + "EXEDIR", + "LANGUAGE", + "TEMP", + "PLUGINSDIR", + "HWNDPARENT", + "_CLICK", + "_OUTDIR" +}; + +static const int kNumVarStrings = sizeof(kVarStrings) / sizeof(kVarStrings[0]); + + +static AString UIntToString(UInt32 v) +{ + char sz[32]; + ConvertUInt64ToString(v, sz); + return sz; +} + +static AString IntToString(Int32 v) +{ + char sz[32]; + ConvertInt64ToString(v, sz); + return sz; +} + +static AString GetVar(UInt32 index) +{ + AString res = "$"; + if (index < 10) + res += UIntToString(index); + else if (index < 20) + { + res += "R"; + res += UIntToString(index - 10); + } + else if (index < 20 + kNumVarStrings) + res += kVarStrings[index - 20]; + else + { + res += "["; + res += UIntToString(index); + res += "]"; + } + return res; +} + +// $0..$9, $INSTDIR, etc are encoded as ASCII bytes starting from this value. +#define NS_SKIP_CODE 252 +#define NS_VAR_CODE 253 +#define NS_SHELL_CODE 254 +#define NS_LANG_CODE 255 +#define NS_CODES_START NS_SKIP_CODE + +// Based on Dave Laundon's simplified process_string +AString GetNsisString(const AString &s) +{ + AString res; + for (int i = 0; i < s.Length();) + { + unsigned char nVarIdx = s[i++]; + if (nVarIdx > NS_CODES_START && i + 2 <= s.Length()) + { + int nData = s[i++] & 0x7F; + unsigned char c1 = s[i++]; + nData |= (((int)(c1 & 0x7F)) << 7); + + if (nVarIdx == NS_SHELL_CODE) + { + UInt32 index = c1; + bool needPrint = true; + res += "$"; + if (index < kNumShellStrings) + { + const char *sz = kShellStrings[index]; + if (sz[0] != 0) + { + res += sz; + needPrint = false; + } + } + if (needPrint) + { + res += "SHELL["; + res += UIntToString(index); + res += "]"; + } + } + else if (nVarIdx == NS_VAR_CODE) + res += GetVar(nData); + else if (nVarIdx == NS_LANG_CODE) + res += "NS_LANG_CODE"; + } + else if (nVarIdx == NS_SKIP_CODE) + { + if (i < s.Length()) + res += s[i++]; + } + else // Normal char + res += (char)nVarIdx; + } + return res; +} + +AString CInArchive::ReadString2(UInt32 pos) +{ + return GetNsisString(ReadString(pos)); +} + +#define DEL_DIR 1 +#define DEL_RECURSE 2 +#define DEL_REBOOT 4 +// #define DEL_SIMPLE 8 + +static const int kNumEntryParams = 6; + +struct CEntry +{ + UInt32 Which; + UInt32 Params[kNumEntryParams]; + AString GetParamsString(int numParams); + CEntry() + { + Which = 0; + for (UInt32 j = 0; j < kNumEntryParams; j++) + Params[j] = 0; + } +}; + +AString CEntry::GetParamsString(int numParams) +{ + AString s; + for (int i = 0; i < numParams; i++) + { + s += " "; + UInt32 v = Params[i]; + if (v > 0xFFF00000) + s += IntToString((Int32)Params[i]); + else + s += UIntToString(Params[i]); + } + return s; +} + +HRESULT CInArchive::ReadEntries(const CBlockHeader &bh) +{ + _posInData = bh.Offset + GetOffset(); + AString prefix; + for (UInt32 i = 0; i < bh.Num; i++) + { + CEntry e; + e.Which = ReadUInt32(); + for (UInt32 j = 0; j < kNumEntryParams; j++) + e.Params[j] = ReadUInt32(); + #ifdef NSIS_SCRIPT + if (e.Which != EW_PUSHPOP && e.Which < sizeof(kCommandPairs) / sizeof(kCommandPairs[0])) + { + const CCommandPair &pair = kCommandPairs[e.Which]; + Script += pair.Name; + } + #endif + + switch (e.Which) + { + case EW_CREATEDIR: + { + prefix.Empty(); + prefix = ReadString2(e.Params[0]); + #ifdef NSIS_SCRIPT + Script += " "; + Script += prefix; + #endif + break; + } + + case EW_EXTRACTFILE: + { + CItem item; + item.Prefix = prefix; + /* UInt32 overwriteFlag = e.Params[0]; */ + item.Name = ReadString2(e.Params[1]); + item.Pos = e.Params[2]; + item.DateTime.dwLowDateTime = e.Params[3]; + item.DateTime.dwHighDateTime = e.Params[4]; + /* UInt32 allowIgnore = e.Params[5]; */ + if (Items.Size() > 0) + { + /* + if (item.Pos == Items.Back().Pos) + continue; + */ + } + Items.Add(item); + #ifdef NSIS_SCRIPT + Script += " "; + Script += item.Name; + #endif + break; + } + + + #ifdef NSIS_SCRIPT + case EW_UPDATETEXT: + { + Script += " "; + Script += ReadString2(e.Params[0]); + Script += " "; + Script += UIntToString(e.Params[1]); + break; + } + case EW_SETFILEATTRIBUTES: + { + Script += " "; + Script += ReadString2(e.Params[0]); + Script += " "; + Script += UIntToString(e.Params[1]); + break; + } + case EW_IFFILEEXISTS: + { + Script += " "; + Script += ReadString2(e.Params[0]); + Script += " "; + Script += UIntToString(e.Params[1]); + Script += " "; + Script += UIntToString(e.Params[2]); + break; + } + case EW_RENAME: + { + Script += " "; + Script += ReadString2(e.Params[0]); + Script += " "; + Script += ReadString2(e.Params[1]); + Script += " "; + Script += UIntToString(e.Params[2]); + break; + } + case EW_GETFULLPATHNAME: + { + Script += " "; + Script += ReadString2(e.Params[0]); + Script += " "; + Script += ReadString2(e.Params[1]); + Script += " "; + Script += UIntToString(e.Params[2]); + break; + } + case EW_SEARCHPATH: + { + Script += " "; + Script += ReadString2(e.Params[0]); + Script += " "; + Script += ReadString2(e.Params[1]); + break; + } + case EW_GETTEMPFILENAME: + { + AString s; + Script += " "; + Script += ReadString2(e.Params[0]); + Script += " "; + Script += ReadString2(e.Params[1]); + break; + } + + case EW_DELETEFILE: + { + UInt64 flag = e.Params[1]; + if (flag != 0) + { + Script += " "; + if (flag == DEL_REBOOT) + Script += "/REBOOTOK"; + else + Script += UIntToString(e.Params[1]); + } + Script += " "; + Script += ReadString2(e.Params[0]); + break; + } + case EW_RMDIR: + { + UInt64 flag = e.Params[1]; + if (flag != 0) + { + if ((flag & DEL_REBOOT) != 0) + Script += " /REBOOTOK"; + if ((flag & DEL_RECURSE) != 0) + Script += " /r"; + } + Script += " "; + Script += ReadString2(e.Params[0]); + break; + } + case EW_ASSIGNVAR: + { + Script += " "; + Script += GetVar(e.Params[0]);; + Script += " \""; + AString maxLen, startOffset; + Script += ReadString2(e.Params[1]); + Script += "\""; + if (e.Params[2] != 0) + maxLen = ReadString(e.Params[2]); + if (e.Params[3] != 0) + startOffset = ReadString(e.Params[3]); + if (!maxLen.IsEmpty() || !startOffset.IsEmpty()) + { + Script += " "; + if (maxLen.IsEmpty()) + Script += "\"\""; + else + Script += maxLen; + if (!startOffset.IsEmpty()) + { + Script += " "; + Script += startOffset; + } + } + break; + } + case EW_STRCMP: + { + Script += " "; + + Script += " \""; + Script += ReadString2(e.Params[0]); + Script += "\""; + + Script += " \""; + Script += ReadString2(e.Params[1]); + Script += "\""; + + for (int j = 2; j < 5; j++) + { + Script += " "; + Script += UIntToString(e.Params[j]); + } + break; + } + + case EW_PUSHPOP: + { + int isPop = (e.Params[1] != 0); + if (isPop) + { + Script += "Pop"; + Script += " "; + Script += GetVar(e.Params[0]);; + } + else + { + int isExch = (e.Params[2] != 0); + if (isExch) + { + Script += "Exch"; + } + else + { + Script += "Push"; + Script += " "; + Script += ReadString2(e.Params[0]); + } + } + break; + } + + /* + case EW_SENDMESSAGE: + { + Script += " "; + Script += IntToString(e.Params[0]); + Script += " "; + Script += GetVar(e.Params[1]); + Script += " "; + Script += ReadString2(e.Params[2]); + Script += " "; + Script += UIntToString(e.Params[3]); + Script += " "; + Script += IntToString(e.Params[4]); + Script += " "; + Script += UIntToString(e.Params[5]); + break; + } + */ + + case EW_REGISTERDLL: + { + Script += " "; + Script += ReadString2(e.Params[0]); + Script += " "; + Script += ReadString2(e.Params[1]); + Script += " "; + Script += UIntToString(e.Params[2]); + break; + } + + case EW_CREATESHORTCUT: + { + AString s; + + Script += " "; + Script += " \""; + Script += ReadString2(e.Params[0]); + Script += " \""; + + Script += " "; + Script += " \""; + Script += ReadString2(e.Params[1]); + Script += " \""; + + for (int j = 2; j < 5; j++) + { + Script += " "; + Script += UIntToString(e.Params[j]); + } + break; + } + + /* + case EW_DELREG: + { + AString keyName, valueName; + keyName = ReadString2(e.Params[1]); + bool isValue = (e.Params[2] != -1); + if (isValue) + { + valueName = ReadString2(e.Params[2]); + Script += "Key"; + } + else + Script += "Value"; + Script += " "; + Script += UIntToString(e.Params[0]); + Script += " "; + Script += keyName; + if (isValue) + { + Script += " "; + Script += valueName; + } + Script += " "; + Script += UIntToString(e.Params[3]); + break; + } + */ + + case EW_WRITEUNINSTALLER: + { + Script += " "; + Script += ReadString2(e.Params[0]); + for (int j = 1; j < 3; j++) + { + Script += " "; + Script += UIntToString(e.Params[j]); + } + break; + } + + default: + { + int numParams = kNumEntryParams; + if (e.Which < sizeof(kCommandPairs) / sizeof(kCommandPairs[0])) + { + const CCommandPair &pair = kCommandPairs[e.Which]; + // Script += pair.Name; + numParams = pair.NumParams; + } + else + { + Script += "Unknown"; + Script += UIntToString(e.Which); + } + Script += e.GetParamsString(numParams); + } + #endif + } + #ifdef NSIS_SCRIPT + Script += kCrLf; + #endif + } + + { + Items.Sort(CompareItems, 0); + int i; + for (i = 0; i + 1 < Items.Size();) + { + if (Items[i].Pos == Items[i + 1].Pos) + Items.Delete(i + 1); + else + i++; + } + for (i = 0; i + 1 < Items.Size(); i++) + { + CItem &item = Items[i]; + item.EstimatedSizeIsDefined = true; + item.EstimatedSize = Items[i + 1].Pos - item.Pos - 4; + } + if (!IsSolid) + { + for (i = 0; i < Items.Size(); i++) + { + CItem &item = Items[i]; + RINOK(_stream->Seek(GetPosOfNonSolidItem(i), STREAM_SEEK_SET, NULL)); + const UInt32 kSigSize = 4 + 1 + 5; + BYTE sig[kSigSize]; + UInt32 processedSize; + RINOK(ReadStream(_stream, sig, kSigSize, &processedSize)); + if (processedSize < 4) + return S_FALSE; + UInt32 size = GetUInt32FromMemLE(sig); + if ((size & 0x80000000) != 0) + { + item.IsCompressed = true; + // is compressed; + size &= ~0x80000000; + if (Method == NMethodType::kLZMA) + { + if (processedSize < 9) + return S_FALSE; + if (FilterFlag) + item.UseFilter = (sig[4] != 0); + item.DictionarySize = GetUInt32FromMemLE(sig + 5 + (FilterFlag ? 1 : 0)); + } + } + else + { + item.IsCompressed = false; + item.Size = size; + item.SizeIsDefined = true; + } + item.CompressedSize = size; + item.CompressedSizeIsDefined = true; + } + } + } + return S_OK; +} + +HRESULT CInArchive::Parse() +{ + // UInt32 offset = ReadUInt32(); + // ???? offset == FirstHeader.HeaderLength + /* UInt32 ehFlags = */ ReadUInt32(); + CBlockHeader bhPages, bhSections, bhEntries, bhStrings, bhLangTables, bhCtlColors, bhData; + // CBlockHeader bgFont; + ReadBlockHeader(bhPages); + ReadBlockHeader(bhSections); + ReadBlockHeader(bhEntries); + ReadBlockHeader(bhStrings); + ReadBlockHeader(bhLangTables); + ReadBlockHeader(bhCtlColors); + // ReadBlockHeader(bgFont); + ReadBlockHeader(bhData); + + _stringsPos = bhStrings.Offset; + + return ReadEntries(bhEntries); +} + +static bool IsLZMA(const Byte *p, UInt32 &dictionary) +{ + dictionary = GetUInt32FromMemLE(p + 1); + return (p[0] == 0x5D && p[1] == 0x00 && p[2] == 0x00 && p[5] == 0x00); +} + +static bool IsLZMA(const Byte *p, UInt32 &dictionary, bool &thereIsFlag) +{ + if (IsLZMA(p, dictionary)) + { + thereIsFlag = false; + return true; + } + if (IsLZMA(p + 1, dictionary)) + { + thereIsFlag = true; + return true; + } + return false; +} + +HRESULT CInArchive::Open2() +{ + RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &StreamOffset)); + + const UInt32 kSigSize = 4 + 1 + 5 + 1; // size, flag, lzma props, lzma first byte + BYTE sig[kSigSize]; + UInt32 processedSize; + RINOK(ReadStream(_stream, sig, kSigSize, &processedSize)); + if (processedSize != kSigSize) + return S_FALSE; + UInt64 position; + RINOK(_stream->Seek(StreamOffset, STREAM_SEEK_SET, &position)); + + _headerIsCompressed = true; + IsSolid = true; + FilterFlag = false; + + UInt32 compressedHeaderSize = GetUInt32FromMemLE(sig); + + if (compressedHeaderSize == FirstHeader.HeaderLength) + { + _headerIsCompressed = false; + IsSolid = false; + Method = NMethodType::kCopy; + } + else if (IsLZMA(sig, DictionarySize, FilterFlag)) + { + Method = NMethodType::kLZMA; + } + else if (IsLZMA(sig + 4, DictionarySize, FilterFlag)) + { + IsSolid = false; + Method = NMethodType::kLZMA; + } + else if (sig[3] == 0x80) + { + IsSolid = false; + Method = NMethodType::kDeflate; + } + else + { + Method = NMethodType::kDeflate; + } + + _posInData = 0; + if (!IsSolid) + { + _headerIsCompressed = ((compressedHeaderSize & 0x80000000) != 0); + if (_headerIsCompressed) + compressedHeaderSize &= ~0x80000000; + _nonSolidStartOffset = compressedHeaderSize; + RINOK(_stream->Seek(StreamOffset + 4, STREAM_SEEK_SET, NULL)); + } + UInt32 unpackSize = FirstHeader.HeaderLength; + if (_headerIsCompressed) + { + // unpackSize = (1 << 23); + _data.SetCapacity(unpackSize); + RINOK(Decoder.Init(_stream, Method, FilterFlag, UseFilter)); + UInt32 processedSize; + RINOK(Decoder.Read(_data, unpackSize, &processedSize)); + if (processedSize != unpackSize) + return S_FALSE; + _size = (size_t)processedSize; + if (IsSolid) + { + UInt32 size2 = ReadUInt32(); + if (size2 < _size) + _size = size2; + } + } + else + { + _data.SetCapacity(unpackSize); + _size = (size_t)unpackSize; + RINOK(ReadStream(_stream, (Byte *)_data, unpackSize, &processedSize)); + if (processedSize != unpackSize) + return S_FALSE; + } + return Parse(); +} + +/* +NsisExe = +{ + ExeStub + Archive // must start from 512 * N + #ifndef NSIS_CONFIG_CRC_ANAL + { + Some additional data + } +} + +Archive +{ + FirstHeader + Data + #ifdef NSIS_CONFIG_CRC_SUPPORT && FirstHeader.ThereIsCrc() + { + CRC + } +} + +FirstHeader +{ + UInt32 Flags; + Byte Signature[16]; + // points to the header+sections+entries+stringtable in the datablock + UInt32 HeaderLength; + UInt32 ArchiveSize; +} +*/ + +HRESULT CInArchive::Open(IInStream *inStream, const UInt64 *maxCheckStartPosition) +{ + Clear(); + UInt64 pos; + RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &pos)); + RINOK(inStream->Seek(0, STREAM_SEEK_END, &_archiveSize)); + UInt64 position; + RINOK(inStream->Seek(pos, STREAM_SEEK_SET, &position)); + UInt64 maxSize = (maxCheckStartPosition != 0) ? *maxCheckStartPosition : (1 << 20); + const UInt32 kStep = 512; + const UInt32 kStartHeaderSize = 4 * 7; + Byte buffer[kStep]; + bool found = false; + + UInt64 headerPosition = 0; + while (position <= maxSize) + { + UInt32 processedSize; + RINOK(ReadStream(inStream, buffer, kStartHeaderSize, &processedSize)); + if (processedSize != kStartHeaderSize) + return S_FALSE; + headerPosition = position; + position += processedSize; + if(memcmp(buffer + 4, kSignature, kSignatureSize) == 0) + { + found = true; + break; + } + const UInt32 kRem = kStep - kStartHeaderSize; + RINOK(ReadStream(inStream, buffer + kStartHeaderSize, kRem, &processedSize)); + if (processedSize != kRem) + return S_FALSE; + position += processedSize; + } + if (!found) + return S_FALSE; + FirstHeader.Flags = GetUInt32FromMemLE(buffer); + FirstHeader.HeaderLength = GetUInt32FromMemLE(buffer + kSignatureSize + 4); + FirstHeader.ArchiveSize = GetUInt32FromMemLE(buffer + kSignatureSize + 8); + if (_archiveSize - headerPosition < FirstHeader.ArchiveSize) + return S_FALSE; + + _stream = inStream; + HRESULT res = S_FALSE; + try { res = Open2(); } + catch(...) { Clear(); res = S_FALSE; } + _stream.Release(); + return res; +} + +void CInArchive::Clear() +{ + #ifdef NSIS_SCRIPT + Script.Empty(); + #endif + Items.Clear(); +} + +}} diff --git a/CPP/7zip/Archive/Nsis/NsisIn.h b/CPP/7zip/Archive/Nsis/NsisIn.h new file mode 100755 index 00000000..d75a9e6e --- /dev/null +++ b/CPP/7zip/Archive/Nsis/NsisIn.h @@ -0,0 +1,166 @@ +// Archive/NsisIn.h + +#ifndef __ARCHIVE_NSIS_IN_H +#define __ARCHIVE_NSIS_IN_H + +#include "Common/MyCom.h" +#include "Common/IntToString.h" +#include "Common/Buffer.h" + +#include "../../IStream.h" + +#include "NsisDecode.h" + +// #define NSIS_SCRIPT + +namespace NArchive { +namespace NNsis { + +const int kSignatureSize = 16; +extern Byte kSignature[kSignatureSize]; + +const UInt32 kFlagsMask = 0xF; +namespace NFlags +{ + const UInt32 kUninstall = 1; + const UInt32 kSilent = 2; + const UInt32 kNoCrc = 4; + const UInt32 kForceCrc = 8; +} + +struct CFirstHeader +{ + UInt32 Flags; + UInt32 HeaderLength; + + UInt32 ArchiveSize; + + bool ThereIsCrc() const + { + if ((Flags & NFlags::kForceCrc ) != 0) + return true; + return ((Flags & NFlags::kNoCrc) == 0); + } + + UInt32 GetDataSize() const { return ArchiveSize - (ThereIsCrc() ? 4 : 0); } +}; + + +struct CBlockHeader +{ + UInt32 Offset; + UInt32 Num; +}; + +struct CItem +{ + AString Prefix; + AString Name; + UInt32 Pos; + bool SizeIsDefined; + bool CompressedSizeIsDefined; + bool EstimatedSizeIsDefined; + UInt32 Size; + UInt32 CompressedSize; + UInt32 EstimatedSize; + FILETIME DateTime; + UInt32 DictionarySize; + bool IsCompressed; + bool UseFilter; + CItem(): UseFilter(false), SizeIsDefined(false), EstimatedSizeIsDefined(false), + IsCompressed(true), CompressedSizeIsDefined(false), Size(0) {} + + bool IsINSTDIR() const + { + if (Prefix.Length() < 3) + return false; + return true; + } + + AString GetReducedName() const + { + AString prefix = Prefix; + if (prefix.Length() > 0) + if (prefix[prefix.Length() - 1] != '\\') + prefix += '\\'; + AString s2 = prefix + Name; + const int len = 9; + if (s2.Left(len).CompareNoCase("$INSTDIR\\") == 0) + s2 = s2.Mid(len); + return s2; + } + +}; + +class CInArchive +{ + UInt64 _archiveSize; + CMyComPtr _stream; + + Byte ReadByte(); + UInt32 ReadUInt32(); + HRESULT Open2(); + void ReadBlockHeader(CBlockHeader &bh); + AString ReadString(UInt32 pos); + AString ReadString2(UInt32 pos); + HRESULT ReadEntries(const CBlockHeader &bh); + HRESULT Parse(); + + CByteBuffer _data; + UInt64 _size; + + size_t _posInData; + + UInt32 _stringsPos; + + + bool _headerIsCompressed; + UInt32 _nonSolidStartOffset; +public: + HRESULT Open(IInStream *inStream, const UInt64 *maxCheckStartPosition); + void Clear(); + + UInt64 StreamOffset; + CDecoder Decoder; + CObjectVector Items; + bool IsSolid; + CFirstHeader FirstHeader; + NMethodType::EEnum Method; + bool UseFilter; + UInt32 DictionarySize; + bool FilterFlag; + + #ifdef NSIS_SCRIPT + AString Script; + #endif + UInt32 GetOffset() const { return IsSolid ? 4 : 0; } + UInt64 GetDataPos(int index) + { + const CItem &item = Items[index]; + return GetOffset() + FirstHeader.HeaderLength + item.Pos; + } + + UInt64 GetPosOfSolidItem(int index) const + { + const CItem &item = Items[index]; + return 4 + FirstHeader.HeaderLength + item.Pos; + } + + UInt64 GetPosOfNonSolidItem(int index) const + { + const CItem &item = Items[index]; + return StreamOffset + _nonSolidStartOffset + 4 + item.Pos; + } + + void Release() + { + Decoder.Release(); + } + +}; + +UInt32 GetUInt32FromMemLE(const Byte *p); + +}} + +#endif diff --git a/CPP/7zip/Archive/Nsis/StdAfx.cpp b/CPP/7zip/Archive/Nsis/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Archive/Nsis/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Nsis/StdAfx.h b/CPP/7zip/Archive/Nsis/StdAfx.h new file mode 100755 index 00000000..2e4be10b --- /dev/null +++ b/CPP/7zip/Archive/Nsis/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" +#include "../../../Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/Archive/Nsis/makefile b/CPP/7zip/Archive/Nsis/makefile new file mode 100755 index 00000000..69fcf523 --- /dev/null +++ b/CPP/7zip/Archive/Nsis/makefile @@ -0,0 +1,67 @@ +PROG = nsis.dll +DEF_FILE = ../Archive.def +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib user32.lib + +TAR_OBJS = \ + $O\DllExports.obj \ + $O\NsisDecode.obj \ + $O\NsisHandler.obj \ + $O\NsisIn.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\Vector.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\FileFind.obj \ + $O\PropVariant.obj \ + +7ZIP_COMMON_OBJS = \ + $O\LimitedStreams.obj \ + $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ + +AR_COMMON_OBJS = \ + $O\CodecsPath.obj \ + $O\CoderLoader.obj \ + $O\ItemNameUtils.obj \ + $O\FilterCoder.obj \ + +7Z_OBJS = \ + $O\7zMethodID.obj \ + $O\7zMethods.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(TAR_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $(7Z_OBJS) \ + $(COMPRESS_TAR_OBJS) \ + $O\CopyCoder.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(TAR_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$(7Z_OBJS): ../7z/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/Archive/Nsis/resource.rc b/CPP/7zip/Archive/Nsis/resource.rc new file mode 100755 index 00000000..487eb4ee --- /dev/null +++ b/CPP/7zip/Archive/Nsis/resource.rc @@ -0,0 +1,3 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("Nsis Plugin", "nsis") diff --git a/CPP/7zip/Archive/RPM/DllExports.cpp b/CPP/7zip/Archive/RPM/DllExports.cpp new file mode 100755 index 00000000..ed21e64f --- /dev/null +++ b/CPP/7zip/Archive/RPM/DllExports.cpp @@ -0,0 +1,68 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "Windows/PropVariant.h" +#include "../../ICoder.h" +#include "RpmHandler.h" + +// {23170F69-40C1-278A-1000-000110EB0000} +DEFINE_GUID(CLSID_CRpmHandler, + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xEB, 0x00, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /* lpReserved */) +{ + return TRUE; +} + +STDAPI CreateObject( + const GUID *classID, + const GUID *interfaceID, + void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + if (*classID != CLSID_CRpmHandler) + return CLASS_E_CLASSNOTAVAILABLE; + if (*interfaceID != IID_IInArchive) + return E_NOINTERFACE; + CMyComPtr inArchive = (IInArchive *)new NArchive::NRpm::CHandler; + *outObject = inArchive.Detach(); + COM_TRY_END + return S_OK; +} + +STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case NArchive::kName: + propVariant = L"Rpm"; + break; + case NArchive::kClassID: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CRpmHandler, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NArchive::kExtension: + propVariant = L"rpm"; + break; + case NArchive::kAddExtension: + propVariant = L".cpio.gz"; + break; + case NArchive::kUpdate: + propVariant = false; + break; + case NArchive::kKeepName: + propVariant = false; + break; + } + propVariant.Detach(value); + return S_OK; +} diff --git a/CPP/7zip/Archive/RPM/Rpm.dsp b/CPP/7zip/Archive/RPM/Rpm.dsp new file mode 100755 index 00000000..085fe137 --- /dev/null +++ b/CPP/7zip/Archive/RPM/Rpm.dsp @@ -0,0 +1,205 @@ +# Microsoft Developer Studio Project File - Name="Rpm" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Rpm - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Rpm.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Rpm.mak" CFG="Rpm - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Rpm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Rpm - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Rpm - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RPM_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RPM_EXPORTS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-zip\Formats\rpm.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Rpm - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RPM_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "../../../" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RPM_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-zip\Formats\rpm.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Rpm - Win32 Release" +# Name "Rpm - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Archive.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\Rpm.ico +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# End Group +# Begin Group "7-zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\RpmHandler.cpp +# End Source File +# Begin Source File + +SOURCE=.\RpmHandler.h +# End Source File +# Begin Source File + +SOURCE=.\RpmHeader.h +# End Source File +# Begin Source File + +SOURCE=.\RpmIn.cpp +# End Source File +# Begin Source File + +SOURCE=.\RpmIn.h +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/Archive/RPM/Rpm.dsw b/CPP/7zip/Archive/RPM/Rpm.dsw new file mode 100755 index 00000000..a67232ed --- /dev/null +++ b/CPP/7zip/Archive/RPM/Rpm.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Rpm"=.\Rpm.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Archive/RPM/RpmHandler.cpp b/CPP/7zip/Archive/RPM/RpmHandler.cpp new file mode 100755 index 00000000..b1a5bf7d --- /dev/null +++ b/CPP/7zip/Archive/RPM/RpmHandler.cpp @@ -0,0 +1,194 @@ +// RPM/Handler.cpp + +#include "StdAfx.h" + +#include "RpmHandler.h" +#include "RpmIn.h" + +#include "Common/Defs.h" +#include "Common/StringConvert.h" +#include "Common/NewHandler.h" +#include "Common/ComTry.h" + +#include "Windows/PropVariant.h" +#include "Windows/Defs.h" + +#include "../../Common/StreamObjects.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/LimitedStreams.h" + +#include "../../Compress/Copy/CopyCoder.h" +#include "../Common/ItemNameUtils.h" + +using namespace NWindows; + +namespace NArchive { +namespace NRpm { + +STATPROPSTG kProperties[] = +{ +// { NULL, kpidPath, VT_BSTR}, +// { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackedSize, VT_UI8} +}; + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) +{ + value->vt = VT_EMPTY; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if(index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &srcItem = kProperties[index]; + *propID = srcItem.propid; + *varType = srcItem.vt; + *name = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +{ + *numProperties = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, + BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) +{ + return E_INVALIDARG; +} + +STDMETHODIMP CHandler::Open(IInStream *inStream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */) +{ + COM_TRY_BEGIN + try + { + if(OpenArchive(inStream) != S_OK) + return S_FALSE; + RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Pos)); + m_InStream = inStream; + UInt64 endPosition; + RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPosition)); + m_Size = endPosition - m_Pos; + return S_OK; + } + catch(...) + { + return S_FALSE; + } + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + m_InStream.Release(); + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = 1; + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant propVariant; + + switch(propID) + { + /* + case kpidPath: + propVariant = (const wchar_t *)L"a.cpio.gz"; + break; + */ + case kpidIsFolder: + propVariant = false; + break; + case kpidSize: + case kpidPackedSize: + propVariant = m_Size; + break; + } + propVariant.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = 1; + if(numItems == 0) + return S_OK; + if(numItems != 1) + return E_FAIL; + if (indices[0] != 0) + return E_FAIL; + + bool testMode = (_aTestMode != 0); + + UInt64 currentTotalSize = 0; + RINOK(extractCallback->SetTotal(m_Size)); + RINOK(extractCallback->SetCompleted(¤tTotalSize)); + CMyComPtr 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 copyCoder = new NCompress::CCopyCoder; + + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr progress = localProgressSpec; + localProgressSpec->Init(extractCallback, false); + + try + { + RINOK(copyCoder->Code(m_InStream, realOutStream, NULL, NULL, progress)); + } + catch(...) + { + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); + return S_OK; + } + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + return S_OK; + COM_TRY_END +} + +}} diff --git a/CPP/7zip/Archive/RPM/RpmHandler.h b/CPP/7zip/Archive/RPM/RpmHandler.h new file mode 100755 index 00000000..484c6c54 --- /dev/null +++ b/CPP/7zip/Archive/RPM/RpmHandler.h @@ -0,0 +1,46 @@ +// RPM/Handler.h + +#ifndef __RPM_HANDLER_H +#define __RPM_HANDLER_H + +#include "Common/MyCom.h" +#include "../IArchive.h" + +namespace NArchive { +namespace NRpm { + +class CHandler: + public IInArchive, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Open)(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback); + STDMETHOD(Close)(); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); + + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + +private: + CMyComPtr m_InStream; + UInt64 m_Pos; + UInt64 m_Size; +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/RPM/RpmHeader.h b/CPP/7zip/Archive/RPM/RpmHeader.h new file mode 100755 index 00000000..d76963bd --- /dev/null +++ b/CPP/7zip/Archive/RPM/RpmHeader.h @@ -0,0 +1,63 @@ +// Archive/RpmHeader.h + +#ifndef __ARCHIVE_RPM_HEADER_H +#define __ARCHIVE_RPM_HEADER_H + +#include "Common/Types.h" + +namespace NArchive { +namespace NRpm { + +/* Reference: lib/signature.h of rpm package */ +#define RPMSIG_NONE 0 /* Do not change! */ +/* The following types are no longer generated */ +#define RPMSIG_PGP262_1024 1 /* No longer generated */ /* 256 byte */ +/* These are the new-style signatures. They are Header structures. */ +/* Inside them we can put any number of any type of signature we like. */ + +#define RPMSIG_HEADERSIG 5 /* New Header style signature */ + +const UInt32 kLeadSize = 96; +struct CLead +{ + unsigned char Magic[4]; + unsigned char Major; // not supported ver1, only support 2,3 and lator + unsigned char Minor; + UInt16 Type; + UInt16 ArchNum; + char Name[66]; + UInt16 OSNum; + UInt16 SignatureType; + char Reserved[16]; // pad to 96 bytes -- 8 byte aligned + bool MagicCheck() const + { return Magic[0] == 0xed && Magic[1] == 0xab && Magic[2] == 0xee && Magic[3] == 0xdb; }; +}; + +const UInt32 kEntryInfoSize = 16; +/* +struct CEntryInfo +{ + int Tag; + int Type; + int Offset; // Offset from beginning of data segment, only defined on disk + int Count; +}; +*/ + +// case: SignatureType == RPMSIG_HEADERSIG +const UInt32 kCSigHeaderSigSize = 16; +struct CSigHeaderSig +{ + unsigned char Magic[4]; + UInt32 Reserved; + UInt32 IndexLen; // count of index entries + UInt32 DataLen; // number of bytes + bool MagicCheck() + { return Magic[0] == 0x8e && Magic[1] == 0xad && Magic[2] == 0xe8 && Magic[3] == 0x01; }; + UInt32 GetLostHeaderLen() + { return IndexLen * kEntryInfoSize + DataLen; }; +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/RPM/RpmIn.cpp b/CPP/7zip/Archive/RPM/RpmIn.cpp new file mode 100755 index 00000000..c1600894 --- /dev/null +++ b/CPP/7zip/Archive/RPM/RpmIn.cpp @@ -0,0 +1,112 @@ +// Archive/RpmIn.cpp + +#include "StdAfx.h" + +#include "RpmIn.h" + +#include "RpmHeader.h" + +#include "Windows/Defs.h" +#include "Common/MyCom.h" + +#include "../../Common/StreamUtils.h" + +namespace NArchive { +namespace NRpm { + +static UInt16 GetUInt16(const char *data) +{ + return (UInt16)((Byte)data[1] | (((UInt16)(Byte)data[0]) << 8)); +} + +static UInt32 GetUInt32(const char *data) +{ + return + ((UInt32)(Byte)data[3]) | + (((UInt32)(Byte)data[2]) << 8) | + (((UInt32)(Byte)data[1]) << 16) | + (((UInt32)(Byte)data[0]) << 24); +} + +static HRESULT RedSigHeaderSig(IInStream *inStream, CSigHeaderSig &h) +{ + char dat[kCSigHeaderSigSize]; + char *cur = dat; + UInt32 processedSize; + RINOK(ReadStream(inStream, dat, kCSigHeaderSigSize, &processedSize)); + if (kCSigHeaderSigSize != processedSize) + return S_FALSE; + memmove(h.Magic, cur, 4); + cur += 4; + cur += 4; + h.IndexLen = GetUInt32(cur); + cur += 4; + h.DataLen = GetUInt32(cur); + return S_OK; +} + +HRESULT OpenArchive(IInStream *inStream) +{ + UInt64 pos; + char leadData[kLeadSize]; + char *cur = leadData; + CLead lead; + UInt32 processedSize; + RINOK(ReadStream(inStream, leadData, kLeadSize, &processedSize)); + if (kLeadSize != processedSize) + return S_FALSE; + memmove(lead.Magic, cur, 4); + cur += 4; + lead.Major = *cur++; + lead.Minor = *cur++; + lead.Type = GetUInt16(cur); + cur += 2; + lead.ArchNum = GetUInt16(cur); + cur += 2; + memmove(lead.Name, cur, sizeof(lead.Name)); + cur += sizeof(lead.Name); + lead.OSNum = GetUInt16(cur); + cur += 2; + lead.SignatureType = GetUInt16(cur); + cur += 2; + + if (!lead.MagicCheck() || lead.Major < 3) + return S_FALSE; + + CSigHeaderSig sigHeader, header; + if(lead.SignatureType == RPMSIG_NONE) + { + ; + } + else if(lead.SignatureType == RPMSIG_PGP262_1024) + { + UInt64 pos; + RINOK(inStream->Seek(256, STREAM_SEEK_CUR, &pos)); + } + else if(lead.SignatureType == RPMSIG_HEADERSIG) + { + RINOK(RedSigHeaderSig(inStream, sigHeader)); + if(!sigHeader.MagicCheck()) + return S_FALSE; + UInt32 len = sigHeader.GetLostHeaderLen(); + RINOK(inStream->Seek(len, STREAM_SEEK_CUR, &pos)); + if((pos % 8) != 0) + { + RINOK(inStream->Seek((pos / 8 + 1) * 8 - pos, + STREAM_SEEK_CUR, &pos)); + } + } + else + return S_FALSE; + + RINOK(RedSigHeaderSig(inStream, header)); + if(!header.MagicCheck()) + return S_FALSE; + int headerLen = header.GetLostHeaderLen(); + if(headerLen == -1) + return S_FALSE; + RINOK(inStream->Seek(headerLen, STREAM_SEEK_CUR, &pos)); + return S_OK; +} + +}} diff --git a/CPP/7zip/Archive/RPM/RpmIn.h b/CPP/7zip/Archive/RPM/RpmIn.h new file mode 100755 index 00000000..ec798cb8 --- /dev/null +++ b/CPP/7zip/Archive/RPM/RpmIn.h @@ -0,0 +1,15 @@ +// Archive/RpmIn.h + +#ifndef __ARCHIVE_RPM_IN_H +#define __ARCHIVE_RPM_IN_H + +#include "../../IStream.h" + +namespace NArchive { +namespace NRpm { + +HRESULT OpenArchive(IInStream *inStream); + +}} + +#endif diff --git a/CPP/7zip/Archive/RPM/StdAfx.cpp b/CPP/7zip/Archive/RPM/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Archive/RPM/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Archive/RPM/StdAfx.h b/CPP/7zip/Archive/RPM/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Archive/RPM/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Archive/RPM/makefile b/CPP/7zip/Archive/RPM/makefile new file mode 100755 index 00000000..afda1289 --- /dev/null +++ b/CPP/7zip/Archive/RPM/makefile @@ -0,0 +1,42 @@ +PROG = rpm.dll +DEF_FILE = ../Archive.def +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib + +RPM_OBJS = \ + $O\DllExports.obj \ + $O\RpmHandler.obj \ + $O\RpmIn.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\NewHandler.obj \ + +WIN_OBJS = \ + $O\PropVariant.obj \ + +7ZIP_COMMON_OBJS = \ + $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(RPM_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $O\CopyCoder.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(RPM_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/Archive/RPM/resource.rc b/CPP/7zip/Archive/RPM/resource.rc new file mode 100755 index 00000000..926f09aa --- /dev/null +++ b/CPP/7zip/Archive/RPM/resource.rc @@ -0,0 +1,5 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("Rpm Plugin", "rpm") + +101 ICON "rpm.ico" diff --git a/CPP/7zip/Archive/RPM/rpm.ico b/CPP/7zip/Archive/RPM/rpm.ico new file mode 100755 index 00000000..cdeb8d1b Binary files /dev/null and b/CPP/7zip/Archive/RPM/rpm.ico differ diff --git a/CPP/7zip/Archive/Rar/DllExports.cpp b/CPP/7zip/Archive/Rar/DllExports.cpp new file mode 100755 index 00000000..921bffb2 --- /dev/null +++ b/CPP/7zip/Archive/Rar/DllExports.cpp @@ -0,0 +1,142 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "Windows/PropVariant.h" +#include "../../ICoder.h" +#include "../../IPassword.h" +#include "../Common/CodecsPath.h" + +// {23170F69-40C1-278B-0601-010000000000} +DEFINE_GUID(CLSID_CCrypto_AES128_Decoder, +0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00); + +#include "RarHandler.h" + +HINSTANCE g_hInstance; +#ifndef _UNICODE +bool g_IsNT = false; +static bool IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); +} +#endif + +void GetCryptoFolderPrefix(TCHAR *path) +{ + CSysString s = GetCodecsFolderPrefix(); + lstrcpy(path, s); +} + + +// {23170F69-40C1-278B-0403-010000000000} +DEFINE_GUID(CLSID_CCompressRar15Decoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00); + +// {23170F69-40C1-278B-0403-020000000000} +DEFINE_GUID(CLSID_CCompressRar20Decoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00); + +// {23170F69-40C1-278B-0403-030000000000} +DEFINE_GUID(CLSID_CCompressRar29Decoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00); + +/* +// {23170F69-40C1-278B-06F1-0302000000000} +DEFINE_GUID(CLSID_CCryptoRar20Decoder, +0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00); + +// {23170F69-40C1-278B-06F1-0303000000000} +DEFINE_GUID(CLSID_CCryptoRar29Decoder, +0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00); +*/ + +// {23170F69-40C1-278A-1000-000110030000} +DEFINE_GUID(CLSID_CRarHandler, + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x03, 0x00, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + g_hInstance = hInstance; + #ifndef _UNICODE + g_IsNT = IsItWindowsNT(); + #endif + } + return TRUE; +} + +STDAPI CreateObject( + const GUID *classID, + const GUID *interfaceID, + void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + if (*classID != CLSID_CRarHandler) + return CLASS_E_CLASSNOTAVAILABLE; + int needIn = *interfaceID == IID_IInArchive; + if (needIn) + { + NArchive::NRar::CHandler *temp = new NArchive::NRar::CHandler; + if (needIn) + { + CMyComPtr inArchive = (IInArchive *)temp; + *outObject = inArchive.Detach(); + } + else + { + CMyComPtr outArchive = (IOutArchive *)temp; + *outObject = outArchive.Detach(); + } + } + else + return E_NOINTERFACE; + COM_TRY_END + return S_OK; +} + +STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case NArchive::kName: + propVariant = L"Rar"; + break; + case NArchive::kClassID: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CRarHandler, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NArchive::kExtension: + propVariant = L"rar"; + break; + case NArchive::kUpdate: + propVariant = false; + break; + case NArchive::kKeepName: + propVariant = false; + break; + case NArchive::kStartSignature: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)NArchive::NRar::NHeader::kMarker, + NArchive::NRar::NHeader::kMarkerSize)) != 0) + value->vt = VT_BSTR; + return S_OK; + } + } + propVariant.Detach(value); + return S_OK; +} diff --git a/CPP/7zip/Archive/Rar/Rar.dsp b/CPP/7zip/Archive/Rar/Rar.dsp new file mode 100755 index 00000000..739024da --- /dev/null +++ b/CPP/7zip/Archive/Rar/Rar.dsp @@ -0,0 +1,459 @@ +# Microsoft Developer Studio Project File - Name="Rar" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Rar - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Rar.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Rar.mak" CFG="Rar - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Rar - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Rar - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Rar - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RAR_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RAR_EXPORTS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-ZIP\Formats\rar.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Rar - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RAR_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RAR_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-ZIP\Formats\rar.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Rar - Win32 Release" +# Name "Rar - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Archive.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Buffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynamicBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Types.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\CodecsPath.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\CodecsPath.h +# End Source File +# Begin Source File + +SOURCE=..\Common\CoderLoader.h +# End Source File +# Begin Source File + +SOURCE=..\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\Common\IArchiveHandler.h +# End Source File +# Begin Source File + +SOURCE=..\Common\InStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\InStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\Common\OutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\OutStreamWithCRC.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Handle.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Thread.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\RarHandler.cpp +# End Source File +# Begin Source File + +SOURCE=.\RarHandler.h +# End Source File +# Begin Source File + +SOURCE=.\RarHeader.cpp +# End Source File +# Begin Source File + +SOURCE=.\RarHeader.h +# End Source File +# Begin Source File + +SOURCE=.\RarIn.cpp +# End Source File +# Begin Source File + +SOURCE=.\RarIn.h +# End Source File +# Begin Source File + +SOURCE=.\RarItem.cpp +# End Source File +# Begin Source File + +SOURCE=.\RarItem.h +# End Source File +# Begin Source File + +SOURCE=.\RarVolumeInStream.cpp +# End Source File +# Begin Source File + +SOURCE=.\RarVolumeInStream.h +# End Source File +# End Group +# Begin Group "Crypto" + +# PROP Default_Filter "" +# Begin Group "Rar29" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\RarAES\RarAES.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\RarAES\RarAES.h +# End Source File +# End Group +# Begin Group "Rar20" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\Rar20\Rar20Cipher.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Rar20\Rar20Cipher.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Rar20\Rar20Crypto.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Rar20\Rar20Crypto.h +# End Source File +# End Group +# Begin Group "Hash" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\Hash\Sha1.cpp + +!IF "$(CFG)" == "Rar - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Rar - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Hash\Sha1.h +# End Source File +# End Group +# End Group +# Begin Group "7-zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "7z" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\7z\7zMethodID.cpp +# End Source File +# Begin Source File + +SOURCE=..\7z\7zMethodID.h +# End Source File +# Begin Source File + +SOURCE=..\7z\7zMethods.cpp +# End Source File +# Begin Source File + +SOURCE=..\7z\7zMethods.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\Rar.ico +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/Archive/Rar/Rar.dsw b/CPP/7zip/Archive/Rar/Rar.dsw new file mode 100755 index 00000000..3dab87aa --- /dev/null +++ b/CPP/7zip/Archive/Rar/Rar.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Rar"=.\Rar.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Archive/Rar/RarHandler.cpp b/CPP/7zip/Archive/Rar/RarHandler.cpp new file mode 100755 index 00000000..3389f0e2 --- /dev/null +++ b/CPP/7zip/Archive/Rar/RarHandler.cpp @@ -0,0 +1,941 @@ +// RarHandler.cpp + +#include "StdAfx.h" + +#include "RarHandler.h" + +#include "Common/StringConvert.h" +#include "Common/ComTry.h" +#include "Common/IntToString.h" + +#include "Windows/PropVariant.h" +#include "Windows/Time.h" + +#include "../../IPassword.h" + +#include "../../Common//ProgressUtils.h" +#include "../../Compress/Copy/CopyCoder.h" + +#include "../../Crypto/Rar20/Rar20Cipher.h" +#include "../../Crypto/RarAES/RarAES.h" + +#include "../Common/OutStreamWithCRC.h" +#include "../Common/CoderLoader.h" +#include "../Common/CodecsPath.h" +#include "../Common/FilterCoder.h" +#include "../Common/ItemNameUtils.h" + +#include "../7z/7zMethods.h" + +using namespace NWindows; +using namespace NTime; + +// {23170F69-40C1-278B-0403-010000000000} +DEFINE_GUID(CLSID_CCompressRar15Decoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00); + +// {23170F69-40C1-278B-0403-020000000000} +DEFINE_GUID(CLSID_CCompressRar20Decoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00); + +// {23170F69-40C1-278B-0403-030000000000} +DEFINE_GUID(CLSID_CCompressRar29Decoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00); + + +namespace NArchive { +namespace NRar { + +static const wchar_t *kHostOS[] = +{ + L"MS DOS", + L"OS/2", + L"Win32", + L"Unix", + L"Mac OS", + L"BeOS" +}; + +static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]); + +static const wchar_t *kUnknownOS = L"Unknown"; + +enum // PropID +{ + kpidUnPackVersion = kpidUserDefined +}; + +STATPROPSTG kProperties[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackedSize, VT_UI8}, + { NULL, kpidLastWriteTime, VT_FILETIME}, + { NULL, kpidCreationTime, VT_FILETIME}, + { NULL, kpidLastAccessTime, VT_FILETIME}, + { NULL, kpidAttributes, VT_UI4}, + + + { NULL, kpidEncrypted, VT_BOOL}, + { NULL, kpidSolid, VT_BOOL}, + { NULL, kpidCommented, VT_BOOL}, + { NULL, kpidSplitBefore, VT_BOOL}, + { NULL, kpidSplitAfter, VT_BOOL}, + { NULL, kpidCRC, VT_UI4}, + { NULL, kpidHostOS, VT_BSTR}, + { NULL, kpidMethod, VT_BSTR} + // { NULL, kpidDictionarySize, VT_UI4}, + // { L"UnPack Version", kpidUnPackVersion, VT_UI1} +}; + +STATPROPSTG kArchiveProperties[] = +{ + { NULL, kpidSolid, VT_BOOL}, + { NULL, kpidCommented, VT_BOOL}, +}; + +UInt64 CHandler::GetPackSize(int refIndex) const +{ + const CRefItem &refItem = _refItems[refIndex]; + UInt64 totalPackSize = 0; + for (int i = 0; i < refItem.NumItems; i++) + totalPackSize += _items[refItem.ItemIndex + i].PackSize; + return totalPackSize; +} + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case kpidSolid: + propVariant = _archiveInfo.IsSolid(); + break; + case kpidCommented: + propVariant = _archiveInfo.IsCommented(); + break; + } + propVariant.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if(index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &srcItem = kProperties[index]; + *propID = srcItem.propid; + *varType = srcItem.vt; + *name = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kArchiveProperties) / sizeof(kArchiveProperties[0]); + return S_OK; +} + +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if(index >= sizeof(kArchiveProperties) / sizeof(kArchiveProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &srcItem = kArchiveProperties[index]; + *propID = srcItem.propid; + *varType = srcItem.vt; + *name = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _refItems.Size(); + return S_OK; +} + +static bool RarTimeToFileTime(const CRarTime &rarTime, FILETIME &result) +{ + if (!DosTimeToFileTime(rarTime.DosTime, result)) + return false; + UInt64 value = (((UInt64)result.dwHighDateTime) << 32) + result.dwLowDateTime; + value += (UInt64)rarTime.LowSecond * 10000000; + value += ((UInt64)rarTime.SubTime[2] << 16) + + ((UInt64)rarTime.SubTime[1] << 8) + + ((UInt64)rarTime.SubTime[0]); + result.dwLowDateTime = (DWORD)value; + result.dwHighDateTime = DWORD(value >> 32); + return true; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant propVariant; + const CRefItem &refItem = _refItems[index]; + const CItemEx &item = _items[refItem.ItemIndex]; + switch(propID) + { + case kpidPath: + { + UString u; + if (item.HasUnicodeName() && !item.UnicodeName.IsEmpty()) + u = item.UnicodeName; + else + u = MultiByteToUnicodeString(item.Name, CP_OEMCP); + propVariant = (const wchar_t *)NItemName::WinNameToOSName(u); + break; + } + case kpidIsFolder: + propVariant = item.IsDirectory(); + break; + case kpidSize: + propVariant = item.UnPackSize; + break; + case kpidPackedSize: + { + propVariant = GetPackSize(index); + break; + } + case kpidLastWriteTime: + { + FILETIME localFileTime, utcFileTime; + if (RarTimeToFileTime(item.LastWriteTime, localFileTime)) + { + if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime)) + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; + } + else + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; + propVariant = utcFileTime; + break; + } + case kpidCreationTime: + { + if (item.IsCreationTimeDefined) + { + FILETIME localFileTime, utcFileTime; + if (RarTimeToFileTime(item.CreationTime, localFileTime)) + { + if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime)) + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; + } + else + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; + propVariant = utcFileTime; + } + break; + } + case kpidLastAccessTime: + { + if (item.IsLastAccessTimeDefined) + { + FILETIME localFileTime, utcFileTime; + if (RarTimeToFileTime(item.LastAccessTime, localFileTime)) + { + if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime)) + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; + } + else + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; + propVariant = utcFileTime; + } + break; + } + case kpidAttributes: + propVariant = item.GetWinAttributes(); + break; + case kpidEncrypted: + propVariant = item.IsEncrypted(); + break; + case kpidSolid: + propVariant = IsSolid(index); + break; + case kpidCommented: + propVariant = item.IsCommented(); + break; + case kpidSplitBefore: + propVariant = item.IsSplitBefore(); + break; + case kpidSplitAfter: + propVariant = _items[refItem.ItemIndex + refItem.NumItems - 1].IsSplitAfter(); + break; + /* + case kpidDictionarySize: + if (!item.IsDirectory()) + propVariant = UInt32(0x10000 << item.GetDictSize()); + break; + */ + case kpidCRC: + { + const CItemEx &lastItem = + _items[refItem.ItemIndex + refItem.NumItems - 1]; + if (lastItem.IsSplitAfter()) + propVariant = item.FileCRC; + else + propVariant = lastItem.FileCRC; + break; + } + case kpidUnPackVersion: + propVariant = item.UnPackVersion; + break; + case kpidMethod: + { + UString method; + if (item.Method >= Byte('0') && item.Method <= Byte('5')) + { + method = L"m"; + wchar_t temp[32]; + ConvertUInt64ToString(item.Method - Byte('0'), temp); + method += temp; + if (!item.IsDirectory()) + { + method += L":"; + ConvertUInt64ToString(16 + item.GetDictSize(), temp); + method += temp; + } + } + else + { + wchar_t temp[32]; + ConvertUInt64ToString(item.Method, temp); + method += temp; + } + propVariant = method; + break; + } + case kpidHostOS: + propVariant = (item.HostOS < kNumHostOSes) ? + (kHostOS[item.HostOS]) : kUnknownOS; + break; + } + propVariant.Detach(value); + return S_OK; + COM_TRY_END +} + +class CVolumeName +{ + bool _first; + bool _newStyle; + UString _unchangedPart; + UString _changedPart; + UString _afterPart; +public: + CVolumeName(): _newStyle(true) {}; + + bool InitName(const UString &name, bool newStyle) + { + _first = true; + _newStyle = newStyle; + int dotPos = name.ReverseFind('.'); + UString basePart = name; + if (dotPos >= 0) + { + UString ext = name.Mid(dotPos + 1); + if (ext.CompareNoCase(L"RAR")==0 || + ext.CompareNoCase(L"EXE") == 0) + { + _afterPart = L".rar"; + basePart = name.Left(dotPos); + } + } + + if (!_newStyle) + { + _afterPart.Empty(); + _unchangedPart = basePart + UString(L"."); + _changedPart = L"r00"; + return true;; + } + + int numLetters = 1; + if (basePart.Right(numLetters) == L"1") + { + while (numLetters < basePart.Length()) + { + if (basePart[basePart.Length() - numLetters - 1] != '0') + break; + numLetters++; + } + } + else + return false; + _unchangedPart = basePart.Left(basePart.Length() - numLetters); + _changedPart = basePart.Right(numLetters); + return true; + } + + UString GetNextName() + { + UString newName; + if (_newStyle || !_first) + { + int i; + int numLetters = _changedPart.Length(); + for (i = numLetters - 1; i >= 0; i--) + { + wchar_t c = _changedPart[i]; + if (c == L'9') + { + c = L'0'; + newName = c + newName; + if (i == 0) + newName = UString(L'1') + newName; + continue; + } + c++; + newName = UString(c) + newName; + i--; + for (; i >= 0; i--) + newName = _changedPart[i] + newName; + break; + } + _changedPart = newName; + } + _first = false; + return _unchangedPart + _changedPart + _afterPart; + } +}; + +STDMETHODIMP CHandler::Open(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback) +{ + COM_TRY_BEGIN + Close(); + try + { + CMyComPtr openVolumeCallback; + CMyComPtr getTextPassword; + CMyComPtr openArchiveCallbackWrap = openArchiveCallback; + + CVolumeName seqName; + + if (openArchiveCallback != NULL) + { + openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback); + RINOK(openArchiveCallback->SetTotal(NULL, NULL)); + UInt64 numFiles = _items.Size(); + RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); + openArchiveCallbackWrap.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); + } + + for (;;) + { + CMyComPtr inStream; + if (!_archives.IsEmpty()) + { + if (!openVolumeCallback) + break; + + if(_archives.Size() == 1) + { + if (!_archiveInfo.IsVolume()) + break; + UString baseName; + { + NCOM::CPropVariant propVariant; + RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant)); + if (propVariant.vt != VT_BSTR) + break; + baseName = propVariant.bstrVal; + } + seqName.InitName(baseName, _archiveInfo.HaveNewVolumeName()); + } + + UString fullName = seqName.GetNextName(); + HRESULT result = openVolumeCallback->GetStream(fullName, &inStream); + if (result == S_FALSE) + break; + if (result != S_OK) + return result; + if (!stream) + break; + } + else + inStream = stream; + + NArchive::NRar::CInArchive archive; + if(!archive.Open(inStream, maxCheckStartPosition)) + return S_FALSE; + + if (_archives.IsEmpty()) + archive.GetArchiveInfo(_archiveInfo); + + CItemEx item; + for (;;) + { + HRESULT result = archive.GetNextItem(item, getTextPassword); + if (result == S_FALSE) + break; + RINOK(result); + if (item.IgnoreItem()) + continue; + + bool needAdd = true; + if (item.IsSplitBefore()) + { + if (!_refItems.IsEmpty()) + { + CRefItem &refItem = _refItems.Back(); + refItem.NumItems++; + needAdd = false; + } + } + if (needAdd) + { + CRefItem refItem; + refItem.ItemIndex = _items.Size(); + refItem.NumItems = 1; + refItem.VolumeIndex = _archives.Size(); + _refItems.Add(refItem); + } + _items.Add(item); + if (openArchiveCallback != NULL) + { + UInt64 numFiles = _items.Size(); + RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); + } + } + _archives.Add(archive); + } + } + catch(...) + { + return S_FALSE; + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + COM_TRY_BEGIN + _refItems.Clear(); + _items.Clear(); + _archives.Clear(); + return S_OK; + COM_TRY_END +} + +struct CMethodItem +{ + Byte RarUnPackVersion; + CMyComPtr Coder; +}; + + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *_anExtractCallback) +{ + COM_TRY_BEGIN + CMyComPtr getTextPassword; + bool testMode = (_aTestMode != 0); + CMyComPtr 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 importantIndexes; + CRecordVector extractStatuses; + + for(UInt32 t = 0; t < numItems; t++) + { + int index = allFilesMode ? t : indices[t]; + const CRefItem &refItem = _refItems[index]; + const CItemEx &item = _items[refItem.ItemIndex]; + censoredTotalUnPacked += item.UnPackSize; + // censoredTotalPacked += item.PackSize; + int j; + for(j = lastIndex; j <= index; j++) + // if(!_items[_refItems[j].ItemIndex].IsSolid()) + if(!IsSolid(j)) + lastIndex = j; + for(j = lastIndex; j <= index; j++) + { + const CRefItem &refItem = _refItems[j]; + const CItemEx &item = _items[refItem.ItemIndex]; + + // const CItemEx &item = _items[j]; + + importantTotalUnPacked += item.UnPackSize; + // importantTotalPacked += item.PackSize; + importantIndexes.Add(j); + extractStatuses.Add(j == index); + } + lastIndex = index + 1; + } + + extractCallback->SetTotal(importantTotalUnPacked); + UInt64 currentImportantTotalUnPacked = 0; + UInt64 currentImportantTotalPacked = 0; + UInt64 currentUnPackSize, currentPackSize; + + /* + CSysString path = GetCodecsFolderPrefix() + TEXT("Rar29.dll"); + TCHAR compressLibPath[MAX_PATH + 64]; + if (!GetCompressFolderPrefix(compressLibPath)) + return ::GetLastError(); + lstrcat(compressLibPath, TEXT("Rar29.dll")); + */ + N7z::LoadMethodMap(); + CCoderLibraries libraries; + CObjectVector methodItems; + + /* + CCoderLibrary compressLib; + CMyComPtr decoder15; + CMyComPtr decoder20; + CMyComPtr decoder29; + */ + + NCompress::CCopyCoder *copyCoderSpec = NULL; + CMyComPtr copyCoder; + + // CCoderMixer *mixerCoderSpec; + // CMyComPtr mixerCoder; + // bool mixerCoderStoreMethod; + // int mixerCryptoVersion; + + CFilterCoder *filterStreamSpec = new CFilterCoder; + CMyComPtr filterStream = filterStreamSpec; + + NCrypto::NRar20::CDecoder *rar20CryptoDecoderSpec = NULL; + CMyComPtr rar20CryptoDecoder; + NCrypto::NRar29::CDecoder *rar29CryptoDecoderSpec = NULL; + CMyComPtr rar29CryptoDecoder; + + CFolderInStream *folderInStreamSpec = NULL; + CMyComPtr folderInStream; + + for(int i = 0; i < importantIndexes.Size(); i++, + currentImportantTotalUnPacked += currentUnPackSize, + currentImportantTotalPacked += currentPackSize) + { + RINOK(extractCallback->SetCompleted( + ¤tImportantTotalUnPacked)); + CMyComPtr 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 outStream(outStreamSpec); + outStreamSpec->SetStream(realOutStream); + outStreamSpec->Init(); + realOutStream.Release(); + + UInt64 packedPos = currentImportantTotalPacked; + UInt64 unpackedPos = currentImportantTotalUnPacked; + + /* + for (int partIndex = 0; partIndex < 1; partIndex++) + { + CMyComPtr 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 progress = localProgressSpec; + localProgressSpec->Init(extractCallback, false); + + CLocalCompressProgressInfo *localCompressProgressSpec = + new CLocalCompressProgressInfo; + CMyComPtr compressProgress = localCompressProgressSpec; + localCompressProgressSpec->Init(progress, + &packedPos, + &unpackedPos); + + UInt64 packSize = currentPackSize; + + // packedPos += item.PackSize; + // unpackedPos += 0; + + CMyComPtr inStream; + if (item.IsEncrypted()) + { + CMyComPtr cryptoSetPassword; + if (item.UnPackVersion >= 29) + { + if (!rar29CryptoDecoder) + { + rar29CryptoDecoderSpec = new NCrypto::NRar29::CDecoder; + rar29CryptoDecoder = rar29CryptoDecoderSpec; + // RINOK(rar29CryptoDecoder.CoCreateInstance(CLSID_CCryptoRar29Decoder)); + } + rar29CryptoDecoderSpec->SetRar350Mode(item.UnPackVersion < 36); + CMyComPtr cryptoProperties; + RINOK(rar29CryptoDecoder.QueryInterface(IID_ICompressSetDecoderProperties2, + &cryptoProperties)); + RINOK(cryptoProperties->SetDecoderProperties2(item.Salt, item.HasSalt() ? sizeof(item.Salt) : 0)); + filterStreamSpec->Filter = rar29CryptoDecoder; + } + else if (item.UnPackVersion >= 20) + { + if (!rar20CryptoDecoder) + { + rar20CryptoDecoderSpec = new NCrypto::NRar20::CDecoder; + rar20CryptoDecoder = rar20CryptoDecoderSpec; + // RINOK(rar20CryptoDecoder.CoCreateInstance(CLSID_CCryptoRar20Decoder)); + } + filterStreamSpec->Filter = rar20CryptoDecoder; + } + else + { + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + continue; + } + RINOK(filterStreamSpec->Filter.QueryInterface(IID_ICryptoSetPassword, + &cryptoSetPassword)); + + if (!getTextPassword) + extractCallback.QueryInterface(IID_ICryptoGetTextPassword, + &getTextPassword); + if (getTextPassword) + { + CMyComBSTR password; + RINOK(getTextPassword->CryptoGetTextPassword(&password)); + if (item.UnPackVersion >= 29) + { + CByteBuffer buffer; + UString unicodePassword(password); + const UInt32 sizeInBytes = unicodePassword.Length() * 2; + buffer.SetCapacity(sizeInBytes); + for (int i = 0; i < unicodePassword.Length(); i++) + { + wchar_t c = unicodePassword[i]; + ((Byte *)buffer)[i * 2] = (Byte)c; + ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); + } + RINOK(cryptoSetPassword->CryptoSetPassword( + (const Byte *)buffer, sizeInBytes)); + } + else + { + AString oemPassword = UnicodeStringToMultiByte( + (const wchar_t *)password, CP_OEMCP); + RINOK(cryptoSetPassword->CryptoSetPassword( + (const Byte *)(const char *)oemPassword, oemPassword.Length())); + } + } + else + { + RINOK(cryptoSetPassword->CryptoSetPassword(0, 0)); + } + filterStreamSpec->SetInStream(folderInStream); + inStream = filterStream; + } + else + { + inStream = folderInStream; + } + CMyComPtr commonCoder; + switch(item.Method) + { + case '0': + { + if(copyCoderSpec == NULL) + { + copyCoderSpec = new NCompress::CCopyCoder; + copyCoder = copyCoderSpec; + } + commonCoder = copyCoder; + break; + } + case '1': + case '2': + case '3': + case '4': + case '5': + { + /* + if (item.UnPackVersion >= 29) + { + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + continue; + } + */ + int m; + for (m = 0; m < methodItems.Size(); m++) + if (methodItems[m].RarUnPackVersion == item.UnPackVersion) + break; + if (m == methodItems.Size()) + { + CMethodItem mi; + mi.RarUnPackVersion = item.UnPackVersion; + N7z::CMethodID methodID = { { 0x04, 0x03 } , 3 }; + + Byte myID; + if (item.UnPackVersion < 20) + myID = 1; + else if (item.UnPackVersion < 29) + myID = 2; + else + myID = 3; + methodID.ID[2] = myID; + N7z::CMethodInfo methodInfo; + if (!N7z::GetMethodInfo(methodID, methodInfo)) + { + RINOK(extractCallback->SetOperationResult( + NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + continue; + } + RINOK(libraries.CreateCoder(methodInfo.FilePath, + methodInfo.Decoder, &mi.Coder)); + m = methodItems.Add(mi); + } + CMyComPtr decoder = methodItems[m].Coder; + + CMyComPtr compressSetDecoderProperties; + RINOK(decoder.QueryInterface(IID_ICompressSetDecoderProperties2, + &compressSetDecoderProperties)); + + Byte isSolid = (Byte)((IsSolid(index) || item.IsSplitBefore()) ? 1: 0); + + RINOK(compressSetDecoderProperties->SetDecoderProperties2(&isSolid, 1)); + + commonCoder = decoder; + break; + } + default: + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + continue; + } + HRESULT result = commonCoder->Code(inStream, outStream, + &packSize, &item.UnPackSize, compressProgress); + if (item.IsEncrypted()) + filterStreamSpec->ReleaseInStream(); + if (result == S_FALSE) + { + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); + continue; + } + if (result != S_OK) + return result; + + /* + if (refItem.NumItems == 1 && + !item.IsSplitBefore() && !item.IsSplitAfter()) + */ + { + const CItemEx &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1]; + bool crcOK = outStreamSpec->GetCRC() == lastItem.FileCRC; + outStream.Release(); + RINOK(extractCallback->SetOperationResult(crcOK ? NArchive::NExtract::NOperationResult::kOK: + NArchive::NExtract::NOperationResult::kCRCError)); + } + /* + else + { + bool crcOK = true; + for (int partIndex = 0; partIndex < refItem.NumItems; partIndex++) + { + const CItemEx &item = _items[refItem.ItemIndex + partIndex]; + if (item.FileCRC != folderInStreamSpec->CRCs[partIndex]) + { + crcOK = false; + break; + } + } + RINOK(extractCallback->SetOperationResult(crcOK ? NArchive::NExtract::NOperationResult::kOK: + NArchive::NExtract::NOperationResult::kCRCError)); + } + */ + } + return S_OK; + COM_TRY_END +} + +/* +STDMETHODIMP CHandler::ExtractAllItems(Int32 testMode, + IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + CRecordVector indices; + indices.Reserve(_refItems.Size()); + for(int i = 0; i < _refItems.Size(); i++) + indices.Add(i); + return Extract(&indices.Front(), _refItems.Size(), testMode, extractCallback); + COM_TRY_END +} +*/ + +}} diff --git a/CPP/7zip/Archive/Rar/RarHandler.h b/CPP/7zip/Archive/Rar/RarHandler.h new file mode 100755 index 00000000..ea13e01e --- /dev/null +++ b/CPP/7zip/Archive/Rar/RarHandler.h @@ -0,0 +1,63 @@ +// Rar/Handler.h + +#ifndef __RAR_HANDLER_H +#define __RAR_HANDLER_H + +#include "../IArchive.h" +#include "RarIn.h" +#include "RarVolumeInStream.h" + +namespace NArchive { +namespace NRar { + +class CHandler: + public IInArchive, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Open)(IInStream *aStream, + const UInt64 *aMaxCheckStartPosition, + IArchiveOpenCallback *anOpenArchiveCallback); + STDMETHOD(Close)(); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *anExtractCallback); + + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + +private: + CRecordVector _refItems; + CObjectVector _items; + CObjectVector _archives; + NArchive::NRar::CInArchiveInfo _archiveInfo; + + UInt64 GetPackSize(int refIndex) const; + // NArchive::NRar::CInArchive _archive; + + bool IsSolid(int refIndex) + { + const CItemEx &item = _items[_refItems[refIndex].ItemIndex]; + if (item.UnPackVersion < 20) + { + if (_archiveInfo.IsSolid()) + return (refIndex > 0); + return false; + } + return item.IsSolid(); + } +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Rar/RarHeader.cpp b/CPP/7zip/Archive/Rar/RarHeader.cpp new file mode 100755 index 00000000..94481e02 --- /dev/null +++ b/CPP/7zip/Archive/Rar/RarHeader.cpp @@ -0,0 +1,21 @@ +// Archive/Rar/Headers.cpp + +#include "StdAfx.h" + +#include "RarHeader.h" + +namespace NArchive{ +namespace NRar{ +namespace NHeader{ + +Byte kMarker[kMarkerSize] = {0x52 + 1, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00}; + +class CMarkerInitializer +{ +public: + CMarkerInitializer() { kMarker[0]--; }; +}; + +static CMarkerInitializer markerInitializer; + +}}} diff --git a/CPP/7zip/Archive/Rar/RarHeader.h b/CPP/7zip/Archive/Rar/RarHeader.h new file mode 100755 index 00000000..832a21c0 --- /dev/null +++ b/CPP/7zip/Archive/Rar/RarHeader.h @@ -0,0 +1,224 @@ +// Archive/RarHeader.h + +#ifndef __ARCHIVE_RAR_HEADER_H +#define __ARCHIVE_RAR_HEADER_H + +#include "Common/Types.h" + +namespace NArchive{ +namespace NRar{ +namespace NHeader{ + +const int kMarkerSize = 7; +extern Byte kMarker[kMarkerSize]; + +const int kArchiveSolid = 0x1; + +namespace NBlockType +{ + enum EBlockType + { + kMarker = 0x72, + kArchiveHeader = 0x73, + kFileHeader = 0x74, + kCommentHeader = 0x75, + kOldAuthenticity = 0x76, + kSubBlock = 0x77, + kRecoveryRecord = 0x78, + kAuthenticity = 0x79, + + kEndOfArchive = 0x7B // Is not safe + }; +} + +namespace NArchive +{ + const UInt16 kVolume = 1; + const UInt16 kComment = 2; + const UInt16 kLock = 4; + const UInt16 kSolid = 8; + const UInt16 kNewVolName = 0x10; // ('volname.partN.rar') + const UInt16 kAuthenticity = 0x20; + const UInt16 kRecovery = 0x40; + const UInt16 kBlockEncryption = 0x80; + const UInt16 kFirstVolume = 0x100; // (set only by RAR 3.0 and later) + const UInt16 kEncryptVer = 0x200; // RAR 3.6 there is EncryptVer Byte in End of MainHeader + + const int kHeaderSizeMin = 7; + + struct CBlock + { + UInt16 CRC; + Byte Type; + UInt16 Flags; + UInt16 Size; + UInt16 Reserved1; + UInt32 Reserved2; + // UInt16 GetRealCRC() const; + }; + + const int kArchiveHeaderSize = 13; + + const int kBlockHeadersAreEncrypted = 0x80; + + struct CHeader360: public CBlock + { + Byte EncryptVersion; + bool IsEncrypted() const { return (Flags & NHeader::NArchive::kBlockEncryption) != 0; } + bool IsThereEncryptVer() const { return (Flags & NHeader::NArchive::kEncryptVer) != 0; } + bool IsEncryptOld() const { return (!IsThereEncryptVer() || EncryptVersion < 36); } + UInt32 GetBaseSize() const { return kArchiveHeaderSize + (IsEncryptOld() ? 0 : 1); } + }; +} + +namespace NFile +{ + const int kSplitBefore = 1 << 0; + const int kSplitAfter = 1 << 1; + const int kEncrypted = 1 << 2; + const int kComment = 1 << 3; + const int kSolid = 1 << 4; + + const int kDictBitStart = 5; + const int kNumDictBits = 3; + const int kDictMask = (1 << kNumDictBits) - 1; + const int kDictDirectoryValue = 0x7; + + const int kSize64Bits = 1 << 8; + const int kUnicodeName = 1 << 9; + const int kSalt = 1 << 10; + const int kOldVersion = 1 << 11; + const int kExtTime = 1 << 12; + // const int kExtFlags = 1 << 13; + // const int kSkipIfUnknown = 1 << 14; + + const int kLongBlock = 1 << 15; + + /* + struct CBlock + { + // UInt16 HeadCRC; + // Byte Type; + // UInt16 Flags; + // UInt16 HeadSize; + UInt32 PackSize; + UInt32 UnPackSize; + Byte HostOS; + UInt32 FileCRC; + UInt32 Time; + Byte UnPackVersion; + Byte Method; + UInt16 NameSize; + UInt32 Attributes; + }; + */ + + /* + struct CBlock32 + { + UInt16 HeadCRC; + Byte Type; + UInt16 Flags; + UInt16 HeadSize; + UInt32 PackSize; + UInt32 UnPackSize; + Byte HostOS; + UInt32 FileCRC; + UInt32 Time; + Byte UnPackVersion; + Byte Method; + UInt16 NameSize; + UInt32 Attributes; + UInt16 GetRealCRC(const void *aName, UInt32 aNameSize, + bool anExtraDataDefined = false, Byte *anExtraData = 0) const; + }; + struct CBlock64 + { + UInt16 HeadCRC; + Byte Type; + UInt16 Flags; + UInt16 HeadSize; + UInt32 PackSizeLow; + UInt32 UnPackSizeLow; + Byte HostOS; + UInt32 FileCRC; + UInt32 Time; + Byte UnPackVersion; + Byte Method; + UInt16 NameSize; + UInt32 Attributes; + UInt32 PackSizeHigh; + UInt32 UnPackSizeHigh; + UInt16 GetRealCRC(const void *aName, UInt32 aNameSize) const; + }; + */ + + const int kLabelFileAttribute = 0x08; + const int kWinFileDirectoryAttributeMask = 0x10; + + enum CHostOS + { + kHostMSDOS = 0, + kHostOS2 = 1, + kHostWin32 = 2, + kHostUnix = 3, + kHostMacOS = 4, + kHostBeOS = 5 + }; +} + +namespace NBlock +{ + const UInt16 kLongBlock = 1 << 15; + struct CBlock + { + UInt16 CRC; + Byte Type; + UInt16 Flags; + UInt16 HeadSize; + // UInt32 DataSize; + }; +} + +/* +struct CSubBlock +{ + UInt16 HeadCRC; + Byte HeadType; + UInt16 Flags; + UInt16 HeadSize; + UInt32 DataSize; + UInt16 SubType; + Byte Level; // Reserved : Must be 0 +}; + +struct CCommentBlock +{ + UInt16 HeadCRC; + Byte HeadType; + UInt16 Flags; + UInt16 HeadSize; + UInt16 UnpSize; + Byte UnpVer; + Byte Method; + UInt16 CommCRC; +}; + + +struct CProtectHeader +{ + UInt16 HeadCRC; + Byte HeadType; + UInt16 Flags; + UInt16 HeadSize; + UInt32 DataSize; + Byte Version; + UInt16 RecSectors; + UInt32 TotalBlocks; + Byte Mark[8]; +}; +*/ + +}}} + +#endif diff --git a/CPP/7zip/Archive/Rar/RarIn.cpp b/CPP/7zip/Archive/Rar/RarIn.cpp new file mode 100755 index 00000000..9a88feb7 --- /dev/null +++ b/CPP/7zip/Archive/Rar/RarIn.cpp @@ -0,0 +1,535 @@ +// Archive/RarIn.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Common/CRC.h" +#include "Common/UTFConvert.h" + +#include "RarIn.h" +#include "../../Common/LimitedStreams.h" +#include "../../Common/StreamUtils.h" + +namespace NArchive { +namespace NRar { + +static const char kEndOfString = '\0'; + +void CInArchive::ThrowExceptionWithCode( + CInArchiveException::CCauseType cause) +{ + throw CInArchiveException(cause); +} + +bool CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit) +{ + m_CryptoMode = false; + if(inStream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition) != S_OK) + return false; + m_Position = m_StreamStartPosition; + m_Stream = inStream; + if (ReadMarkerAndArchiveHeader(searchHeaderSizeLimit)) + return true; + m_Stream.Release(); + return false; +} + +void CInArchive::Close() +{ + m_Stream.Release(); +} + + +static inline bool TestMarkerCandidate(const void *aTestBytes) +{ + for (UInt32 i = 0; i < NHeader::kMarkerSize; i++) + if (((const Byte *)aTestBytes)[i] != NHeader::kMarker[i]) + return false; + return true; +} + +bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit) +{ + // if (m_Length < NHeader::kMarkerSize) + // return false; + m_ArchiveStartPosition = 0; + m_Position = m_StreamStartPosition; + if(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL) != S_OK) + return false; + + Byte marker[NHeader::kMarkerSize]; + UInt32 processedSize; + ReadBytes(marker, NHeader::kMarkerSize, &processedSize); + if(processedSize != NHeader::kMarkerSize) + return false; + if (TestMarkerCandidate(marker)) + return true; + + CByteDynamicBuffer dynamicBuffer; + static const UInt32 kSearchMarkerBufferSize = 0x10000; + dynamicBuffer.EnsureCapacity(kSearchMarkerBufferSize); + Byte *buffer = dynamicBuffer; + UInt32 numBytesPrev = NHeader::kMarkerSize - 1; + memmove(buffer, marker + 1, numBytesPrev); + UInt64 curTestPos = m_StreamStartPosition + 1; + for (;;) + { + if (searchHeaderSizeLimit != NULL) + if (curTestPos - m_StreamStartPosition > *searchHeaderSizeLimit) + break; + UInt32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev; + ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize); + UInt32 numBytesInBuffer = numBytesPrev + processedSize; + if (numBytesInBuffer < NHeader::kMarkerSize) + break; + UInt32 numTests = numBytesInBuffer - NHeader::kMarkerSize + 1; + for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++) + { + if (TestMarkerCandidate(buffer + pos)) + { + m_ArchiveStartPosition = curTestPos; + m_Position = curTestPos + NHeader::kMarkerSize; + if(m_Stream->Seek(m_Position, STREAM_SEEK_SET, NULL) != S_OK) + return false; + return true; + } + } + numBytesPrev = numBytesInBuffer - numTests; + memmove(buffer, buffer + numTests, numBytesPrev); + } + return false; +} + +void CInArchive::ThrowUnexpectedEndOfArchiveException() +{ + ThrowExceptionWithCode(CInArchiveException::kUnexpectedEndOfArchive); +} + +bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size) +{ + if (m_CryptoMode) + { + const Byte *bufData = (const Byte *)m_DecryptedData; + UInt32 bufSize = m_DecryptedDataSize; + UInt32 i; + for (i = 0; i < size && m_CryptoPos < bufSize; i++) + ((Byte *)data)[i] = bufData[m_CryptoPos++]; + return (i == size); + } + UInt32 processedSize; + ReadStream(m_Stream, data, size, &processedSize); + return (processedSize == size); +} + +void CInArchive::ReadBytesAndTestResult(void *data, UInt32 size) +{ + if(!ReadBytesAndTestSize(data,size)) + ThrowUnexpectedEndOfArchiveException(); +} + +HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize; + HRESULT result = ReadStream(m_Stream, data, size, &realProcessedSize); + if(processedSize != NULL) + *processedSize = realProcessedSize; + AddToSeekValue(realProcessedSize); + return result; +} + +bool CInArchive::ReadMarkerAndArchiveHeader(const UInt64 *searchHeaderSizeLimit) +{ + if (!FindAndReadMarker(searchHeaderSizeLimit)) + return false; + + Byte buf[NHeader::NArchive::kArchiveHeaderSize]; + UInt32 processedSize; + ReadBytes(buf, sizeof(buf), &processedSize); + if (processedSize != sizeof(buf)) + return false; + m_CurData = buf; + m_CurPos = 0; + m_PosLimit = sizeof(buf); + + m_ArchiveHeader.CRC = ReadUInt16(); + m_ArchiveHeader.Type = ReadByte(); + m_ArchiveHeader.Flags = ReadUInt16(); + m_ArchiveHeader.Size = ReadUInt16(); + m_ArchiveHeader.Reserved1 = ReadUInt16(); + m_ArchiveHeader.Reserved2 = ReadUInt32(); + m_ArchiveHeader.EncryptVersion = 0; + + CCRC crc; + crc.UpdateByte(m_ArchiveHeader.Type); + crc.UpdateUInt16(m_ArchiveHeader.Flags); + crc.UpdateUInt16(m_ArchiveHeader.Size); + crc.UpdateUInt16(m_ArchiveHeader.Reserved1); + crc.UpdateUInt32(m_ArchiveHeader.Reserved2); + + if (m_ArchiveHeader.IsThereEncryptVer() && m_ArchiveHeader.Size > NHeader::NArchive::kArchiveHeaderSize) + { + ReadBytes(&m_ArchiveHeader.EncryptVersion, 1, &processedSize); + if (processedSize != 1) + return false; + crc.UpdateByte(m_ArchiveHeader.EncryptVersion); + } + + if(m_ArchiveHeader.CRC != (crc.GetDigest() & 0xFFFF)) + ThrowExceptionWithCode(CInArchiveException::kArchiveHeaderCRCError); + if (m_ArchiveHeader.Type != NHeader::NBlockType::kArchiveHeader) + return false; + m_ArchiveCommentPosition = m_Position; + m_SeekOnArchiveComment = true; + return true; +} + +void CInArchive::SkipArchiveComment() +{ + if (!m_SeekOnArchiveComment) + return; + AddToSeekValue(m_ArchiveHeader.Size - m_ArchiveHeader.GetBaseSize()); + m_SeekOnArchiveComment = false; +} + +void CInArchive::GetArchiveInfo(CInArchiveInfo &archiveInfo) const +{ + archiveInfo.StartPosition = m_ArchiveStartPosition; + archiveInfo.Flags = m_ArchiveHeader.Flags; + archiveInfo.CommentPosition = m_ArchiveCommentPosition; + archiveInfo.CommentSize = (UInt16)(m_ArchiveHeader.Size - NHeader::NArchive::kArchiveHeaderSize); +} + +static void DecodeUnicodeFileName(const char *name, const Byte *encName, + int encSize, wchar_t *unicodeName, int maxDecSize) +{ + int encPos = 0; + int decPos = 0; + int flagBits = 0; + Byte flags = 0; + Byte highByte = encName[encPos++]; + while (encPos < encSize && decPos < maxDecSize) + { + if (flagBits == 0) + { + flags = encName[encPos++]; + flagBits = 8; + } + switch(flags >> 6) + { + case 0: + unicodeName[decPos++] = encName[encPos++]; + break; + case 1: + unicodeName[decPos++] = (wchar_t)(encName[encPos++] + (highByte << 8)); + break; + case 2: + unicodeName[decPos++] = (wchar_t)(encName[encPos] + (encName[encPos + 1] << 8)); + encPos += 2; + break; + case 3: + { + int length = encName[encPos++]; + if (length & 0x80) + { + Byte correction = encName[encPos++]; + for (length = (length & 0x7f) + 2; + length > 0 && decPos < maxDecSize; length--, decPos++) + unicodeName[decPos] = (wchar_t)(((name[decPos] + correction) & 0xff) + (highByte << 8)); + } + else + for (length += 2; length > 0 && decPos < maxDecSize; length--, decPos++) + unicodeName[decPos] = name[decPos]; + } + break; + } + flags <<= 2; + flagBits -= 2; + } + unicodeName[decPos < maxDecSize ? decPos : maxDecSize - 1] = 0; +} + +void CInArchive::ReadName(CItemEx &item, int nameSize) +{ + item.UnicodeName.Empty(); + if (nameSize > 0) + { + m_NameBuffer.EnsureCapacity(nameSize + 1); + char *buffer = (char *)m_NameBuffer; + + for (int i = 0; i < nameSize; i++) + buffer[i] = ReadByte(); + + int mainLen; + for (mainLen = 0; mainLen < nameSize; mainLen++) + if (buffer[mainLen] == '\0') + break; + buffer[mainLen] = '\0'; + item.Name = buffer; + + if(item.HasUnicodeName()) + { + if(mainLen < nameSize) + { + int unicodeNameSizeMax = MyMin(nameSize, (0x400)); + _unicodeNameBuffer.EnsureCapacity(unicodeNameSizeMax + 1); + DecodeUnicodeFileName(buffer, (const Byte *)buffer + mainLen + 1, + nameSize - (mainLen + 1), _unicodeNameBuffer, unicodeNameSizeMax); + item.UnicodeName = _unicodeNameBuffer; + } + else if (!ConvertUTF8ToUnicode(item.Name, item.UnicodeName)) + item.UnicodeName.Empty(); + } + } + else + item.Name.Empty(); +} + +Byte CInArchive::ReadByte() +{ + if (m_CurPos >= m_PosLimit) + throw CInArchiveException(CInArchiveException::kIncorrectArchive); + return m_CurData[m_CurPos++]; +} + +UInt16 CInArchive::ReadUInt16() +{ + UInt16 value = 0; + for (int i = 0; i < 2; i++) + { + Byte b = ReadByte(); + value |= (UInt16(b) << (8 * i)); + } + return value; +} + +UInt32 CInArchive::ReadUInt32() +{ + UInt32 value = 0; + for (int i = 0; i < 4; i++) + { + Byte b = ReadByte(); + value |= (UInt32(b) << (8 * i)); + } + return value; +} + +void CInArchive::ReadTime(Byte mask, CRarTime &rarTime) +{ + rarTime.LowSecond = (Byte)(((mask & 4) != 0) ? 1 : 0); + int numDigits = (mask & 3); + rarTime.SubTime[0] = rarTime.SubTime[1] = rarTime.SubTime[2] = 0; + for (int i = 0; i < numDigits; i++) + rarTime.SubTime[3 - numDigits + i] = ReadByte(); +} + +void CInArchive::ReadHeaderReal(CItemEx &item) +{ + item.Flags = m_BlockHeader.Flags; + item.PackSize = ReadUInt32(); + item.UnPackSize = ReadUInt32(); + item.HostOS = ReadByte(); + item.FileCRC = ReadUInt32(); + item.LastWriteTime.DosTime = ReadUInt32(); + item.UnPackVersion = ReadByte(); + item.Method = ReadByte(); + int nameSize = ReadUInt16(); + item.Attributes = ReadUInt32(); + + item.LastWriteTime.LowSecond = 0; + item.LastWriteTime.SubTime[0] = + item.LastWriteTime.SubTime[1] = + item.LastWriteTime.SubTime[2] = 0; + + if((item.Flags & NHeader::NFile::kSize64Bits) != 0) + { + item.PackSize |= ((UInt64)ReadUInt32() << 32); + item.UnPackSize |= ((UInt64)ReadUInt32() << 32); + } + + ReadName(item, nameSize); + + if (item.HasSalt()) + for (int i = 0; i < sizeof(item.Salt); i++) + item.Salt[i] = ReadByte(); + + // some rar archives have HasExtTime flag without field. + if (m_CurPos < m_PosLimit && item.HasExtTime()) + { + Byte accessMask = (Byte)(ReadByte() >> 4); + Byte b = ReadByte(); + Byte modifMask = (Byte)(b >> 4); + Byte createMask = (Byte)(b & 0xF); + if ((modifMask & 8) != 0) + ReadTime(modifMask, item.LastWriteTime); + item.IsCreationTimeDefined = ((createMask & 8) != 0); + if (item.IsCreationTimeDefined) + { + item.CreationTime.DosTime = ReadUInt32(); + ReadTime(createMask, item.CreationTime); + } + item.IsLastAccessTimeDefined = ((accessMask & 8) != 0); + if (item.IsLastAccessTimeDefined) + { + item.LastAccessTime.DosTime = ReadUInt32(); + ReadTime(accessMask, item.LastAccessTime); + } + } + + UInt16 fileHeaderWithNameSize = (UInt16)m_CurPos; + + item.Position = m_Position; + item.MainPartSize = fileHeaderWithNameSize; + item.CommentSize = (UInt16)(m_BlockHeader.HeadSize - fileHeaderWithNameSize); + + if (m_CryptoMode) + item.AlignSize = (UInt16)((16 - ((m_BlockHeader.HeadSize) & 0xF)) & 0xF); + else + item.AlignSize = 0; + AddToSeekValue(m_BlockHeader.HeadSize); +} + +void CInArchive::AddToSeekValue(UInt64 addValue) +{ + m_Position += addValue; +} + +HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword) +{ + if (m_SeekOnArchiveComment) + SkipArchiveComment(); + for (;;) + { + if(!SeekInArchive(m_Position)) + return S_FALSE; + if (!m_CryptoMode && (m_ArchiveHeader.Flags & + NHeader::NArchive::kBlockHeadersAreEncrypted) != 0) + { + m_CryptoMode = false; + if (getTextPassword == 0) + return S_FALSE; + if(!SeekInArchive(m_Position)) + return S_FALSE; + if (!m_RarAES) + { + m_RarAESSpec = new NCrypto::NRar29::CDecoder; + m_RarAES = m_RarAESSpec; + } + m_RarAESSpec->SetRar350Mode(m_ArchiveHeader.IsEncryptOld()); + + // Salt + const UInt32 kSaltSize = 8; + Byte salt[kSaltSize]; + if(!ReadBytesAndTestSize(salt, kSaltSize)) + return false; + m_Position += kSaltSize; + RINOK(m_RarAESSpec->SetDecoderProperties2(salt, kSaltSize)) + // Password + CMyComBSTR password; + RINOK(getTextPassword->CryptoGetTextPassword(&password)) + UString unicodePassword(password); + + CByteBuffer buffer; + const UInt32 sizeInBytes = unicodePassword.Length() * 2; + buffer.SetCapacity(sizeInBytes); + for (int i = 0; i < unicodePassword.Length(); i++) + { + wchar_t c = unicodePassword[i]; + ((Byte *)buffer)[i * 2] = (Byte)c; + ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); + } + + RINOK(m_RarAESSpec->CryptoSetPassword((const Byte *)buffer, sizeInBytes)); + + const UInt32 kDecryptedBufferSize = (1 << 12); + if (m_DecryptedData.GetCapacity() == 0) + { + m_DecryptedData.SetCapacity(kDecryptedBufferSize); + } + RINOK(m_RarAES->Init()); + RINOK(ReadStream(m_Stream, (Byte *)m_DecryptedData, kDecryptedBufferSize, &m_DecryptedDataSize)); + m_DecryptedDataSize = m_RarAES->Filter((Byte *)m_DecryptedData, m_DecryptedDataSize); + + m_CryptoMode = true; + m_CryptoPos = 0; + } + + m_FileHeaderData.EnsureCapacity(7); + if(!ReadBytesAndTestSize((Byte *)m_FileHeaderData, 7)) + return S_FALSE; + + m_CurData = (Byte *)m_FileHeaderData; + m_CurPos = 0; + m_PosLimit = 7; + m_BlockHeader.CRC = ReadUInt16(); + m_BlockHeader.Type = ReadByte(); + m_BlockHeader.Flags = ReadUInt16(); + m_BlockHeader.HeadSize = ReadUInt16(); + + if (m_BlockHeader.HeadSize < 7) + ThrowExceptionWithCode(CInArchiveException::kIncorrectArchive); + + if (m_BlockHeader.Type == NHeader::NBlockType::kEndOfArchive) + return S_FALSE; + + if (m_BlockHeader.Type == NHeader::NBlockType::kFileHeader) + { + m_FileHeaderData.EnsureCapacity(m_BlockHeader.HeadSize); + m_CurData = (Byte *)m_FileHeaderData; + m_PosLimit = m_BlockHeader.HeadSize; + ReadBytesAndTestResult(m_CurData + m_CurPos, m_BlockHeader.HeadSize - 7); + ReadHeaderReal(item); + if ((CCRC::CalculateDigest(m_CurData + 2, + m_BlockHeader.HeadSize - item.CommentSize - 2) & 0xFFFF) != m_BlockHeader.CRC) + ThrowExceptionWithCode(CInArchiveException::kFileHeaderCRCError); + + FinishCryptoBlock(); + m_CryptoMode = false; + SeekInArchive(m_Position); // Move Position to compressed Data; + AddToSeekValue(item.PackSize); // m_Position points to next header; + return S_OK; + } + if (m_CryptoMode && m_BlockHeader.HeadSize > (1 << 12)) + return E_FAIL; // it's for bad passwords + if ((m_BlockHeader.Flags & NHeader::NBlock::kLongBlock) != 0) + { + m_FileHeaderData.EnsureCapacity(7 + 4); + m_CurData = (Byte *)m_FileHeaderData; + ReadBytesAndTestResult(m_CurData + m_CurPos, 4); // test it + m_PosLimit = 7 + 4; + UInt32 dataSize = ReadUInt32(); + AddToSeekValue(dataSize); + if (m_CryptoMode && dataSize > (1 << 27)) + return E_FAIL; // it's for bad passwords + m_CryptoPos = m_BlockHeader.HeadSize; + } + else + m_CryptoPos = 0; + AddToSeekValue(m_BlockHeader.HeadSize); + FinishCryptoBlock(); + m_CryptoMode = false; + } +} + +void CInArchive::DirectGetBytes(void *data, UInt32 size) +{ + ReadStream(m_Stream, data, size, NULL); +} + +bool CInArchive::SeekInArchive(UInt64 position) +{ + UInt64 newPosition; + m_Stream->Seek(position, STREAM_SEEK_SET, &newPosition); + return newPosition == position; +} + +ISequentialInStream* CInArchive::CreateLimitedStream(UInt64 position, UInt64 size) +{ + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr inStream(streamSpec); + SeekInArchive(position); + streamSpec->SetStream(m_Stream); + streamSpec->Init(size); + return inStream.Detach(); +} + +}} diff --git a/CPP/7zip/Archive/Rar/RarIn.h b/CPP/7zip/Archive/Rar/RarIn.h new file mode 100755 index 00000000..22262a74 --- /dev/null +++ b/CPP/7zip/Archive/Rar/RarIn.h @@ -0,0 +1,124 @@ +// RarIn.h + +#ifndef __ARCHIVE_RAR_IN_H +#define __ARCHIVE_RAR_IN_H + +#include "Common/DynamicBuffer.h" +#include "Common/Exception.h" +#include "Common/MyCom.h" +#include "../../IStream.h" +#include "../../ICoder.h" +#include "../../Common/StreamObjects.h" +#include "../../Crypto/RarAES/RarAES.h" +#include "RarHeader.h" +#include "RarItem.h" + +namespace NArchive { +namespace NRar { + +class CInArchiveException +{ +public: + enum CCauseType + { + kUnexpectedEndOfArchive = 0, + kArchiveHeaderCRCError, + kFileHeaderCRCError, + kIncorrectArchive, + } + Cause; + CInArchiveException(CCauseType cause) : Cause(cause) {} +}; + +class CInArchiveInfo +{ +public: + UInt64 StartPosition; + WORD Flags; + UInt64 CommentPosition; + WORD CommentSize; + bool IsSolid() const { return (Flags & NHeader::NArchive::kSolid) != 0; } + bool IsCommented() const { return (Flags & NHeader::NArchive::kComment) != 0; } + bool IsVolume() const { return (Flags & NHeader::NArchive::kVolume) != 0; } + bool HaveNewVolumeName() const { return (Flags & NHeader::NArchive::kNewVolName) != 0; } + bool IsEncrypted() const { return (Flags & NHeader::NArchive::kBlockEncryption) != 0; } +}; + +class CInArchive +{ + CMyComPtr m_Stream; + + UInt64 m_StreamStartPosition; + UInt64 m_Position; + UInt64 m_ArchiveStartPosition; + + NHeader::NArchive::CHeader360 m_ArchiveHeader; + CDynamicBuffer m_NameBuffer; + CDynamicBuffer _unicodeNameBuffer; + bool m_SeekOnArchiveComment; + UInt64 m_ArchiveCommentPosition; + + void ReadName(CItemEx &item, int nameSize); + void ReadHeaderReal(CItemEx &item); + + HRESULT ReadBytes(void *data, UInt32 size, UInt32 *aProcessedSize); + bool ReadBytesAndTestSize(void *data, UInt32 size); + void ReadBytesAndTestResult(void *data, UInt32 size); + + bool FindAndReadMarker(const UInt64 *searchHeaderSizeLimit); + void ThrowExceptionWithCode(CInArchiveException::CCauseType cause); + void ThrowUnexpectedEndOfArchiveException(); + + void AddToSeekValue(UInt64 addValue); + +protected: + + CDynamicBuffer m_FileHeaderData; + + NHeader::NBlock::CBlock m_BlockHeader; + + NCrypto::NRar29::CDecoder *m_RarAESSpec; + CMyComPtr m_RarAES; + + Byte *m_CurData; // it must point to start of Rar::Block + UInt32 m_CurPos; + UInt32 m_PosLimit; + Byte ReadByte(); + UInt16 ReadUInt16(); + UInt32 ReadUInt32(); + void ReadTime(Byte mask, CRarTime &rarTime); + + CBuffer m_DecryptedData; + UInt32 m_DecryptedDataSize; + + bool m_CryptoMode; + UInt32 m_CryptoPos; + void FinishCryptoBlock() + { + if (m_CryptoMode) + while ((m_CryptoPos & 0xF) != 0) + { + m_CryptoPos++; + m_Position++; + } + } + + bool ReadMarkerAndArchiveHeader(const UInt64 *searchHeaderSizeLimit); +public: + bool Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit); + void Close(); + HRESULT GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPassword); + + void SkipArchiveComment(); + + void GetArchiveInfo(CInArchiveInfo &archiveInfo) const; + + void DirectGetBytes(void *data, UInt32 size); + + bool SeekInArchive(UInt64 position); + ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size); +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Rar/RarItem.cpp b/CPP/7zip/Archive/Rar/RarItem.cpp new file mode 100755 index 00000000..61a72557 --- /dev/null +++ b/CPP/7zip/Archive/Rar/RarItem.cpp @@ -0,0 +1,118 @@ +// RarItem.cpp + +#include "StdAfx.h" + +#include "RarItem.h" +#include "RarHeader.h" + +namespace NArchive{ +namespace NRar{ + +bool CItem::IsEncrypted() const + { return (Flags & NHeader::NFile::kEncrypted) != 0; } +bool CItem::IsSolid() const + { return (Flags & NHeader::NFile::kSolid) != 0; } +bool CItem::IsCommented() const + { return (Flags & NHeader::NFile::kComment) != 0; } +bool CItem::IsSplitBefore() const + { return (Flags & NHeader::NFile::kSplitBefore) != 0; } +bool CItem::IsSplitAfter() const + { return (Flags & NHeader::NFile::kSplitAfter) != 0; } +bool CItem::HasSalt() const + { return (Flags & NHeader::NFile::kSalt) != 0; } +bool CItem::HasExtTime() const + { return (Flags & NHeader::NFile::kExtTime) != 0; } +bool CItem::HasUnicodeName() const + { return (Flags & NHeader::NFile::kUnicodeName) != 0; } +bool CItem::IsOldVersion() const + { return (Flags & NHeader::NFile::kOldVersion) != 0; } + +bool CItem::IgnoreItem() const +{ + switch(HostOS) + { + case NHeader::NFile::kHostMSDOS: + case NHeader::NFile::kHostOS2: + case NHeader::NFile::kHostWin32: + return ((Attributes & NHeader::NFile::kLabelFileAttribute) != 0); + } + return false; +} + +UInt32 CItem::GetDictSize() const +{ return (Flags >> NHeader::NFile::kDictBitStart) & NHeader::NFile::kDictMask; } + +bool CItem::IsDirectory() const +{ + if (GetDictSize() == NHeader::NFile::kDictDirectoryValue) + return true; + switch(HostOS) + { + case NHeader::NFile::kHostMSDOS: + case NHeader::NFile::kHostOS2: + case NHeader::NFile::kHostWin32: + if ((Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) + return true; + } + return false; +} + +UInt32 CItem::GetWinAttributes() const +{ + UInt32 winAttributes; + switch(HostOS) + { + case NHeader::NFile::kHostMSDOS: + case NHeader::NFile::kHostOS2: + case NHeader::NFile::kHostWin32: + winAttributes = Attributes; + break; + default: + winAttributes = 0; // must be converted from unix value;; + } + if (IsDirectory()) // test it; + winAttributes |= NHeader::NFile::kWinFileDirectoryAttributeMask; + return winAttributes; +} + +void CItem::ClearFlags() +{ Flags = 0; } + +void CItem::SetFlagBits(int startBitNumber, int numBits, int value) +{ + UInt16 mask = (UInt16)(((1 << numBits) - 1) << startBitNumber); + Flags &= ~mask; + Flags |= value << startBitNumber; +} + +void CItem::SetBitMask(int bitMask, bool enable) +{ + if(enable) + Flags |= bitMask; + else + Flags &= ~bitMask; +} + +void CItem::SetDictSize(UInt32 size) +{ + SetFlagBits(NHeader::NFile::kDictBitStart, NHeader::NFile::kNumDictBits, (size & NHeader::NFile::kDictMask)); +} + +void CItem::SetAsDirectory(bool directory) +{ + if (directory) + SetDictSize(NHeader::NFile::kDictDirectoryValue); +} + +void CItem::SetEncrypted(bool encrypted) + { SetBitMask(NHeader::NFile::kEncrypted, encrypted); } +void CItem::SetSolid(bool solid) + { SetBitMask(NHeader::NFile::kSolid, solid); } +void CItem::SetCommented(bool commented) + { SetBitMask(NHeader::NFile::kComment, commented); } +void CItem::SetSplitBefore(bool splitBefore) + { SetBitMask(NHeader::NFile::kSplitBefore, splitBefore); } +void CItem::SetSplitAfter(bool splitAfter) + { SetBitMask(NHeader::NFile::kSplitAfter, splitAfter); } + +}} diff --git a/CPP/7zip/Archive/Rar/RarItem.h b/CPP/7zip/Archive/Rar/RarItem.h new file mode 100755 index 00000000..85050a42 --- /dev/null +++ b/CPP/7zip/Archive/Rar/RarItem.h @@ -0,0 +1,91 @@ +// RarItem.h + +#ifndef __ARCHIVE_RAR_ITEM_H +#define __ARCHIVE_RAR_ITEM_H + +#include "Common/Types.h" +#include "Common/String.h" + +namespace NArchive{ +namespace NRar{ + +struct CRarTime +{ + UInt32 DosTime; + Byte LowSecond; + Byte SubTime[3]; +}; + +class CItem +{ +public: + UInt16 Flags; + UInt64 PackSize; + UInt64 UnPackSize; + Byte HostOS; + UInt32 FileCRC; + + CRarTime CreationTime; + CRarTime LastWriteTime; + CRarTime LastAccessTime; + bool IsCreationTimeDefined; + // bool IsLastWriteTimeDefined; + bool IsLastAccessTimeDefined; + + Byte UnPackVersion; + Byte Method; + UInt32 Attributes; + AString Name; + UString UnicodeName; + + Byte Salt[8]; + + bool IsEncrypted() const; + bool IsSolid() const; + bool IsCommented() const; + bool IsSplitBefore() const; + bool IsSplitAfter() const; + bool HasSalt() const; + bool HasExtTime() const; + + bool HasUnicodeName() const; + bool IsOldVersion() const; + + UInt32 GetDictSize() const; + bool IsDirectory() const; + bool IgnoreItem() const; + UInt32 GetWinAttributes() const; + + CItem(): IsCreationTimeDefined(false), IsLastAccessTimeDefined(false) {} +private: + void SetFlagBits(int startBitNumber, int numBits, int value); + void SetBitMask(int bitMask, bool enable); +public: + void ClearFlags(); + void SetDictSize(UInt32 size); + void SetAsDirectory(bool directory); + void SetEncrypted(bool encrypted); + void SetSolid(bool solid); + void SetCommented(bool commented); + void SetSplitBefore(bool splitBefore); + void SetSplitAfter(bool splitAfter); +}; + +class CItemEx: public CItem +{ +public: + UInt64 Position; + UInt16 MainPartSize; + UInt16 CommentSize; + UInt16 AlignSize; + UInt64 GetFullSize() const { return MainPartSize + CommentSize + AlignSize + PackSize; }; + // DWORD GetHeaderWithCommentSize() const { return MainPartSize + CommentSize; }; + UInt64 GetCommentPosition() const { return Position + MainPartSize; }; + UInt64 GetDataPosition() const { return GetCommentPosition() + CommentSize + AlignSize; }; +}; + +}} + +#endif + + diff --git a/CPP/7zip/Archive/Rar/RarVolumeInStream.cpp b/CPP/7zip/Archive/Rar/RarVolumeInStream.cpp new file mode 100755 index 00000000..32078e6d --- /dev/null +++ b/CPP/7zip/Archive/Rar/RarVolumeInStream.cpp @@ -0,0 +1,79 @@ +// RarVolumeInStream.cpp + +#include "StdAfx.h" + +#include "RarVolumeInStream.h" + +#include "Windows/Defs.h" +#include "Common/Defs.h" + +namespace NArchive { +namespace NRar { + +void CFolderInStream::Init( + CObjectVector *archives, + const CObjectVector *items, + const CRefItem &refItem) +{ + _archives = archives; + _items = items; + _refItem = refItem; + _curIndex = 0; + CRCs.Clear(); + _fileIsOpen = false; +} + +HRESULT CFolderInStream::OpenStream() +{ + while (_curIndex < _refItem.NumItems) + { + const CItemEx &item = (*_items)[_refItem.ItemIndex + _curIndex]; + _stream.Attach((*_archives)[_refItem.VolumeIndex + _curIndex]. + CreateLimitedStream(item.GetDataPosition(), item.PackSize)); + _curIndex++; + _fileIsOpen = true; + _crc.Init(); + return S_OK; + } + return S_OK; +} + +HRESULT CFolderInStream::CloseStream() +{ + CRCs.Add(_crc.GetDigest()); + _stream.Release(); + _fileIsOpen = false; + return S_OK; +} + +STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize = 0; + while ((_curIndex < _refItem.NumItems || _fileIsOpen) && size > 0) + { + if (_fileIsOpen) + { + UInt32 localProcessedSize; + RINOK(_stream->Read( + ((Byte *)data) + realProcessedSize, size, &localProcessedSize)); + _crc.Update(((Byte *)data) + realProcessedSize, localProcessedSize); + if (localProcessedSize == 0) + { + RINOK(CloseStream()); + continue; + } + realProcessedSize += localProcessedSize; + size -= localProcessedSize; + break; + } + else + { + RINOK(OpenStream()); + } + } + if (processedSize != 0) + *processedSize = realProcessedSize; + return S_OK; +} + +}} diff --git a/CPP/7zip/Archive/Rar/RarVolumeInStream.h b/CPP/7zip/Archive/Rar/RarVolumeInStream.h new file mode 100755 index 00000000..4c9a9e96 --- /dev/null +++ b/CPP/7zip/Archive/Rar/RarVolumeInStream.h @@ -0,0 +1,50 @@ +// RarVolumeInStream.h + +#ifndef __RAR_VOLUME_IN_STREAM_H +#define __RAR_VOLUME_IN_STREAM_H + +#include "../../IStream.h" +#include "Common/CRC.h" +#include "RarIn.h" + +namespace NArchive { +namespace NRar { + +struct CRefItem +{ + int VolumeIndex; + int ItemIndex; + int NumItems; +}; + +class CFolderInStream: + public ISequentialInStream, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + +private: + CObjectVector *_archives; + const CObjectVector *_items; + CRefItem _refItem; + int _curIndex; + CCRC _crc; + bool _fileIsOpen; + CMyComPtr _stream; + + HRESULT OpenStream(); + HRESULT CloseStream(); +public: + void Init(CObjectVector *archives, + const CObjectVector *items, + const CRefItem &refItem); + + CRecordVector CRCs; +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Rar/StdAfx.cpp b/CPP/7zip/Archive/Rar/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Archive/Rar/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Rar/StdAfx.h b/CPP/7zip/Archive/Rar/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Archive/Rar/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Archive/Rar/makefile b/CPP/7zip/Archive/Rar/makefile new file mode 100755 index 00000000..678dd412 --- /dev/null +++ b/CPP/7zip/Archive/Rar/makefile @@ -0,0 +1,90 @@ +PROG = rar.dll +DEF_FILE = ../Archive.def +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib user32.lib + +RAR_OBJS = \ + $O\DllExports.obj \ + $O\RarHandler.obj \ + $O\RarHeader.obj \ + $O\RarIn.obj \ + $O\RarItem.obj \ + $O\RarVolumeInStream.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CRC.obj \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\UTFConvert.obj \ + $O\Vector.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\FileFind.obj \ + $O\PropVariant.obj \ + +7ZIP_COMMON_OBJS = \ + $O\LimitedStreams.obj \ + $O\ProgressUtils.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + +AR_COMMON_OBJS = \ + $O\CodecsPath.obj \ + $O\FilterCoder.obj \ + $O\InStreamWithCRC.obj \ + $O\OutStreamWithCRC.obj \ + +7Z_OBJS = \ + $O\7zMethodID.obj \ + $O\7zMethods.obj \ + +CRYPTO_HASH_OBJS = \ + $O\Sha1.obj \ + +CRYPTO_RAR20_OBJS = \ + $O\Rar20Cipher.obj \ + $O\Rar20Crypto.obj \ + +CRYPTO_RARAES_OBJS = \ + $O\RarAES.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(RAR_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $(7Z_OBJS) \ + $(CRYPTO_HASH_OBJS) \ + $(CRYPTO_RAR20_OBJS) \ + $(CRYPTO_RARAES_OBJS) \ + $O\CopyCoder.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(RAR_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$(7Z_OBJS): ../7z/$(*B).cpp + $(COMPL) +$(CRYPTO_HASH_OBJS): ../../Crypto/Hash/$(*B).cpp + $(COMPL_O2) +$(CRYPTO_RAR20_OBJS): ../../Crypto/Rar20/$(*B).cpp + $(COMPL) +$(CRYPTO_RARAES_OBJS): ../../Crypto/RarAES/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/Archive/Rar/rar.ico b/CPP/7zip/Archive/Rar/rar.ico new file mode 100755 index 00000000..2918d294 Binary files /dev/null and b/CPP/7zip/Archive/Rar/rar.ico differ diff --git a/CPP/7zip/Archive/Rar/resource.rc b/CPP/7zip/Archive/Rar/resource.rc new file mode 100755 index 00000000..94b4198b --- /dev/null +++ b/CPP/7zip/Archive/Rar/resource.rc @@ -0,0 +1,5 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("Rar Plugin", "rar") + +101 ICON "rar.ico" diff --git a/CPP/7zip/Archive/Split/DllExports.cpp b/CPP/7zip/Archive/Split/DllExports.cpp new file mode 100755 index 00000000..e28f64ce --- /dev/null +++ b/CPP/7zip/Archive/Split/DllExports.cpp @@ -0,0 +1,65 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "Windows/PropVariant.h" +#include "SplitHandler.h" +#include "../../ICoder.h" + +// {23170F69-40C1-278A-1000-000110EA0000} +DEFINE_GUID(CLSID_CSplitHandler, + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xEA, 0x00, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /* lpReserved */) +{ + return TRUE; +} + +STDAPI CreateObject( + const GUID *classID, + const GUID *interfaceID, + void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + if (*classID != CLSID_CSplitHandler) + return CLASS_E_CLASSNOTAVAILABLE; + if (*interfaceID != IID_IInArchive) + return E_NOINTERFACE; + CMyComPtr inArchive = (IInArchive *)new NArchive::NSplit::CHandler; + *outObject = inArchive.Detach(); + COM_TRY_END + return S_OK; +} + +STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case NArchive::kName: + propVariant = L"Split"; + break; + case NArchive::kClassID: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CSplitHandler, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NArchive::kExtension: + propVariant = L"001"; + break; + case NArchive::kUpdate: + propVariant = false; + break; + case NArchive::kKeepName: + propVariant = true; + break; + } + propVariant.Detach(value); + return S_OK; +} diff --git a/CPP/7zip/Archive/Split/Split.dsp b/CPP/7zip/Archive/Split/Split.dsp new file mode 100755 index 00000000..d6229d98 --- /dev/null +++ b/CPP/7zip/Archive/Split/Split.dsp @@ -0,0 +1,237 @@ +# Microsoft Developer Studio Project File - Name="Split" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Split - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Split.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Split.mak" CFG="Split - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Split - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Split - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Split - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SPLIT_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SPLIT_EXPORTS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\split.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Split - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SPLIT_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SPLIT_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\split.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Split - Win32 Release" +# Name "Split - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Archive.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\Split.ico +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\MultiStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\MultiStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "Interface" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\IArchive.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\SplitHandler.cpp +# End Source File +# Begin Source File + +SOURCE=.\SplitHandler.h +# End Source File +# Begin Source File + +SOURCE=.\SplitHandlerOut.cpp +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/Archive/Split/Split.dsw b/CPP/7zip/Archive/Split/Split.dsw new file mode 100755 index 00000000..988ca30a --- /dev/null +++ b/CPP/7zip/Archive/Split/Split.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Split"=.\Split.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Archive/Split/Split.ico b/CPP/7zip/Archive/Split/Split.ico new file mode 100755 index 00000000..5cb93e84 Binary files /dev/null and b/CPP/7zip/Archive/Split/Split.ico differ diff --git a/CPP/7zip/Archive/Split/SplitHandler.cpp b/CPP/7zip/Archive/Split/SplitHandler.cpp new file mode 100755 index 00000000..e919154f --- /dev/null +++ b/CPP/7zip/Archive/Split/SplitHandler.cpp @@ -0,0 +1,415 @@ +// Tar/Handler.cpp + +#include "StdAfx.h" + +#include "SplitHandler.h" + +#include "Common/Defs.h" +#include "Common/StringConvert.h" +#include "Common/NewHandler.h" +#include "Common/ComTry.h" + +#include "Windows/Time.h" +#include "Windows/PropVariant.h" + +#include "../../Common/ProgressUtils.h" +#include "../../Compress/Copy/CopyCoder.h" +#include "../Common/ItemNameUtils.h" +#include "../Common/MultiStream.h" + +using namespace NWindows; +using namespace NTime; + +namespace NArchive { +namespace NSplit { + +STATPROPSTG kProperties[] = +{ + { NULL, kpidPath, VT_BSTR}, +// { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackedSize, VT_UI8}, +}; + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) +{ + value->vt = VT_EMPTY; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if(index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &srcItem = kProperties[index]; + *propID = srcItem.propid; + *varType = srcItem.vt; + *name = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +{ + *numProperties = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, + BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) +{ + return E_INVALIDARG; +} + +class CSeqName +{ +public: + UString _unchangedPart; + UString _changedPart; + bool _splitStyle; + UString GetNextName() + { + UString newName; + if (_splitStyle) + { + int i; + int numLetters = _changedPart.Length(); + for (i = numLetters - 1; i >= 0; i--) + { + wchar_t c = _changedPart[i]; + if (c == 'z') + { + c = 'a'; + newName = c + newName; + continue; + } + else if (c == 'Z') + { + c = 'A'; + newName = c + newName; + continue; + } + c++; + if ((c == 'z' || c == 'Z') && i == 0) + { + _unchangedPart += c; + wchar_t newChar = (c == 'z') ? L'a' : L'A'; + newName.Empty(); + numLetters++; + for (int k = 0; k < numLetters; k++) + newName += newChar; + break; + } + newName = c + newName; + i--; + for (; i >= 0; i--) + newName = _changedPart[i] + newName; + break; + } + } + else + { + int i; + int numLetters = _changedPart.Length(); + for (i = numLetters - 1; i >= 0; i--) + { + wchar_t c = _changedPart[i]; + if (c == L'9') + { + c = L'0'; + newName = c + newName; + if (i == 0) + newName = UString(L'1') + newName; + continue; + } + c++; + newName = c + newName; + i--; + for (; i >= 0; i--) + newName = _changedPart[i] + newName; + break; + } + } + _changedPart = newName; + return _unchangedPart + _changedPart; + } +}; + +STDMETHODIMP CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback *openArchiveCallback) +{ + COM_TRY_BEGIN + Close(); + if (openArchiveCallback == 0) + return S_FALSE; + // try + { + CMyComPtr openVolumeCallback; + CMyComPtr openArchiveCallbackWrap = openArchiveCallback; + if (openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, + &openVolumeCallback) != S_OK) + return S_FALSE; + + { + NCOM::CPropVariant propVariant; + RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant)); + if (propVariant.vt != VT_BSTR) + return S_FALSE; + _name = propVariant.bstrVal; + } + + int dotPos = _name.ReverseFind('.'); + UString prefix, ext; + if (dotPos >= 0) + { + prefix = _name.Left(dotPos + 1); + ext = _name.Mid(dotPos + 1); + } + else + ext = _name; + UString extBig = ext; + extBig.MakeUpper(); + + CSeqName seqName; + + int numLetters = 2; + bool splitStyle = false; + if (extBig.Right(2) == L"AA") + { + splitStyle = true; + while (numLetters < extBig.Length()) + { + if (extBig[extBig.Length() - numLetters - 1] != 'A') + break; + numLetters++; + } + } + else if (ext.Right(2) == L"01") + { + while (numLetters < extBig.Length()) + { + if (extBig[extBig.Length() - numLetters - 1] != '0') + break; + numLetters++; + } + if (numLetters != ext.Length()) + return S_FALSE; + } + else + return S_FALSE; + + _streams.Add(stream); + + seqName._unchangedPart = prefix + ext.Left(extBig.Length() - numLetters); + seqName._changedPart = ext.Right(numLetters); + seqName._splitStyle = splitStyle; + + if (prefix.Length() < 1) + _subName = L"file"; + else + _subName = prefix.Left(prefix.Length() - 1); + + _totalSize = 0; + UInt64 size; + { + NCOM::CPropVariant propVariant; + RINOK(openVolumeCallback->GetProperty(kpidSize, &propVariant)); + if (propVariant.vt != VT_UI8) + return E_INVALIDARG; + size = propVariant.uhVal.QuadPart; + } + _totalSize += size; + _sizes.Add(size); + + if (openArchiveCallback != NULL) + { + RINOK(openArchiveCallback->SetTotal(NULL, NULL)); + UInt64 numFiles = _streams.Size(); + RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); + } + + for (;;) + { + UString fullName = seqName.GetNextName(); + CMyComPtr nextStream; + HRESULT result = openVolumeCallback->GetStream(fullName, &nextStream); + if (result == S_FALSE) + break; + if (result != S_OK) + return result; + if (!stream) + break; + { + NCOM::CPropVariant propVariant; + RINOK(openVolumeCallback->GetProperty(kpidSize, &propVariant)); + if (propVariant.vt != VT_UI8) + return E_INVALIDARG; + size = propVariant.uhVal.QuadPart; + } + _totalSize += size; + _sizes.Add(size); + _streams.Add(nextStream); + if (openArchiveCallback != NULL) + { + UInt64 numFiles = _streams.Size(); + RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); + } + } + } + /* + catch(...) + { + return S_FALSE; + } + */ + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + _sizes.Clear(); + _streams.Clear(); + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _streams.IsEmpty() ? 0 : 1; + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant propVariant; + + switch(propID) + { + case kpidPath: + propVariant = _subName; + break; + case kpidIsFolder: + propVariant = false; + break; + case kpidSize: + case kpidPackedSize: + propVariant = _totalSize; + break; + } + propVariant.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *_anExtractCallback) +{ + COM_TRY_BEGIN + + if (numItems != UInt32(-1)) + { + if (numItems != 1) + return E_INVALIDARG; + if (indices[0] != 0) + return E_INVALIDARG; + } + bool testMode = (_aTestMode != 0); + CMyComPtr extractCallback = _anExtractCallback; + extractCallback->SetTotal(_totalSize); + + /* + CMyComPtr volumeExtractCallback; + if (extractCallback.QueryInterface(&volumeExtractCallback) != S_OK) + return E_FAIL; + */ + + UInt64 currentTotalSize = 0; + UInt64 currentItemSize; + + RINOK(extractCallback->SetCompleted(¤tTotalSize)); + CMyComPtr 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 copyCoder = copyCoderSpec; + + for(int i = 0; i < _streams.Size(); i++, currentTotalSize += currentItemSize) + { + // CMyComPtr inStream; + // RINOK(volumeExtractCallback->GetInStream(_names[i], &inStream)); + + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr progress = localProgressSpec; + localProgressSpec->Init(extractCallback, false); + CLocalCompressProgressInfo *localCompressProgressSpec = + new CLocalCompressProgressInfo; + CMyComPtr compressProgress = localCompressProgressSpec; + localCompressProgressSpec->Init(progress, + ¤tTotalSize, ¤tTotalSize); + IInStream *inStream = _streams[i]; + RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); + try + { + RINOK(copyCoder->Code(inStream, realOutStream, + NULL, NULL, compressProgress)); + } + catch(...) + { + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); + return S_OK;; + } + currentItemSize = copyCoderSpec->TotalSize; + } + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +{ + if (index != 0) + return E_INVALIDARG; + *stream = 0; + CMultiStream *streamSpec = new CMultiStream; + CMyComPtr streamTemp = streamSpec; + for (int i = 0; i < _streams.Size(); i++) + { + CMultiStream::CSubStreamInfo subStreamInfo; + subStreamInfo.Stream = _streams[i]; + subStreamInfo.Pos = 0; + subStreamInfo.Size = _sizes[i]; + streamSpec->Streams.Add(subStreamInfo); + } + streamSpec->Init(); + *stream = streamTemp.Detach(); + return S_OK; +} + +}} diff --git a/CPP/7zip/Archive/Split/SplitHandler.h b/CPP/7zip/Archive/Split/SplitHandler.h new file mode 100755 index 00000000..8b3fcb70 --- /dev/null +++ b/CPP/7zip/Archive/Split/SplitHandler.h @@ -0,0 +1,62 @@ +// Split/Handler.h + +#ifndef __SPLIT_HANDLER_H +#define __SPLIT_HANDLER_H + +#include "Common/MyCom.h" +#include "Common/String.h" +#include "../IArchive.h" + +namespace NArchive { +namespace NSplit { + +class CHandler: + public IInArchive, + public IInArchiveGetStream, + // public IOutArchive, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP1(IInArchiveGetStream) + + STDMETHOD(Open)(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback); + STDMETHOD(Close)(); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); + + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); + + // IOutArchiveHandler + /* + STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback); + + STDMETHOD(GetFileTimeType)(UInt32 *type); + */ + +private: + UString _subName; + UString _name; + CObjectVector > _streams; + CRecordVector _sizes; + + UInt64 _totalSize; +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Split/SplitHandlerOut.cpp b/CPP/7zip/Archive/Split/SplitHandlerOut.cpp new file mode 100755 index 00000000..ea86c281 --- /dev/null +++ b/CPP/7zip/Archive/Split/SplitHandlerOut.cpp @@ -0,0 +1,102 @@ +// Split/OutHandler.cpp + +#include "StdAfx.h" + +#include "SplitHandler.h" +#include "../../../Windows/PropVariant.h" +#include "../../../Common/ComTry.h" +#include "../../../Common/StringToInt.h" + +using namespace NWindows; + +namespace NArchive { +namespace NSplit { + +/* +STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) +{ + *type = NFileTimeType::kWindows; + return S_OK; +} + +STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback) +{ + COM_TRY_BEGIN + + if (numItems != 1) + return E_INVALIDARG; + + UInt64 volumeSize = 0; + + CMyComPtr callback2; + updateCallback->QueryInterface(IID_IArchiveUpdateCallback2, + (void **)&callback2); + + RINOK(callback2->GetVolumeSize(0, &volumeSize)); + + Int32 newData; + Int32 newProperties; + UInt32 indexInArchive; + if (!updateCallback) + return E_FAIL; + + UInt32 fileIndex = 0; + RINOK(updateCallback->GetUpdateItemInfo(fileIndex, + &newData, &newProperties, &indexInArchive)); + + if (newProperties != 0) + { + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(fileIndex, kpidIsFolder, &propVariant)); + if (propVariant.vt == VT_EMPTY) + { + } + else if (propVariant.vt != VT_BOOL) + return E_INVALIDARG; + else + { + if (propVariant.boolVal != VARIANT_FALSE) + return E_INVALIDARG; + } + } + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(fileIndex, kpidIsAnti, &propVariant)); + if (propVariant.vt == VT_EMPTY) + { + } + else if (propVariant.vt != VT_BOOL) + return E_INVALIDARG; + else + { + if (propVariant.boolVal != VARIANT_FALSE) + return E_INVALIDARG; + } + } + } + UInt64 newSize; + bool thereIsCopyData = false; + if (newData != 0) + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(fileIndex, kpidSize, &propVariant)); + if (propVariant.vt != VT_UI8) + return E_INVALIDARG; + newSize = propVariant.uhVal.QuadPart; + } + else + thereIsCopyData = true; + + UInt64 pos = 0; + while(pos < newSize) + { + + } + return S_OK; + COM_TRY_END +} +*/ + +}} diff --git a/CPP/7zip/Archive/Split/StdAfx.cpp b/CPP/7zip/Archive/Split/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Archive/Split/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Split/StdAfx.h b/CPP/7zip/Archive/Split/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Archive/Split/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Archive/Split/makefile b/CPP/7zip/Archive/Split/makefile new file mode 100755 index 00000000..650c750b --- /dev/null +++ b/CPP/7zip/Archive/Split/makefile @@ -0,0 +1,51 @@ +PROG = split.dll +DEF_FILE = ../Archive.def +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib user32.lib + +SPLIT_OBJS = \ + $O\DllExports.obj \ + $O\SplitHandler.obj \ + $O\SplitHandlerOut.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\Vector.obj \ + +WIN_OBJS = \ + $O\PropVariant.obj \ + +7ZIP_COMMON_OBJS = \ + $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ + +AR_COMMON_OBJS = \ + $O\MultiStream.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(SPLIT_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $O\CopyCoder.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(SPLIT_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/Archive/Split/resource.rc b/CPP/7zip/Archive/Split/resource.rc new file mode 100755 index 00000000..3e301754 --- /dev/null +++ b/CPP/7zip/Archive/Split/resource.rc @@ -0,0 +1,5 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("Split Plugin", "split") + +101 ICON "Split.ico" diff --git a/CPP/7zip/Archive/Tar/DllExports.cpp b/CPP/7zip/Archive/Tar/DllExports.cpp new file mode 100755 index 00000000..afa2fd24 --- /dev/null +++ b/CPP/7zip/Archive/Tar/DllExports.cpp @@ -0,0 +1,86 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "Windows/PropVariant.h" +#include "../../ICoder.h" +#include "TarHandler.h" + +// {23170F69-40C1-278A-1000-000110EE0000} +DEFINE_GUID(CLSID_CTarHandler, + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xEE, 0x00, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /* lpReserved */) +{ + return TRUE; +} + +STDAPI CreateObject( + const GUID *classID, + const GUID *interfaceID, + void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + if (*classID != CLSID_CTarHandler) + return CLASS_E_CLASSNOTAVAILABLE; + int needIn = *interfaceID == IID_IInArchive; + int needOut = *interfaceID == IID_IOutArchive; + if (needIn || needOut) + { + NArchive::NTar::CHandler *temp = new NArchive::NTar::CHandler; + if (needIn) + { + CMyComPtr inArchive = (IInArchive *)temp; + *outObject = inArchive.Detach(); + } + else + { + CMyComPtr outArchive = (IOutArchive *)temp; + *outObject = outArchive.Detach(); + } + } + else + return E_NOINTERFACE; + COM_TRY_END + return S_OK; +} + +STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case NArchive::kName: + propVariant = L"Tar"; + break; + case NArchive::kClassID: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CTarHandler, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NArchive::kExtension: + propVariant = L"tar"; + break; + case NArchive::kUpdate: + propVariant = true; + break; + case NArchive::kKeepName: + propVariant = false; + break; + case NArchive::kStartSignature: + { + const unsigned char sig[] = { 'u', 's', 't', 'a', 'r' }; + if ((value->bstrVal = ::SysAllocStringByteLen((const char *)sig, 5)) != 0) + value->vt = VT_BSTR; + return S_OK; + } + } + propVariant.Detach(value); + return S_OK; +} diff --git a/CPP/7zip/Archive/Tar/StdAfx.cpp b/CPP/7zip/Archive/Tar/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Archive/Tar/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Tar/StdAfx.h b/CPP/7zip/Archive/Tar/StdAfx.h new file mode 100755 index 00000000..2e4be10b --- /dev/null +++ b/CPP/7zip/Archive/Tar/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" +#include "../../../Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/Archive/Tar/Tar.dsp b/CPP/7zip/Archive/Tar/Tar.dsp new file mode 100755 index 00000000..c01e7383 --- /dev/null +++ b/CPP/7zip/Archive/Tar/Tar.dsp @@ -0,0 +1,297 @@ +# Microsoft Developer Studio Project File - Name="Tar" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Tar - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Tar.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Tar.mak" CFG="Tar - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Tar - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Tar - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Tar - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TAR_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TAR_EXPORTS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\tar.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Tar - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TAR_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TAR_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\tar.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Tar - Win32 Release" +# Name "Tar - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Archive.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# Begin Source File + +SOURCE=.\Tar.ico +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\TarHandler.cpp +# End Source File +# Begin Source File + +SOURCE=.\TarHandler.h +# End Source File +# Begin Source File + +SOURCE=.\TarHandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=.\TarHeader.cpp +# End Source File +# Begin Source File + +SOURCE=.\TarHeader.h +# End Source File +# Begin Source File + +SOURCE=.\TarIn.cpp +# End Source File +# Begin Source File + +SOURCE=.\TarIn.h +# End Source File +# Begin Source File + +SOURCE=.\TarItem.h +# End Source File +# Begin Source File + +SOURCE=.\TarOut.cpp +# End Source File +# Begin Source File + +SOURCE=.\TarOut.h +# End Source File +# Begin Source File + +SOURCE=.\TarUpdate.cpp +# End Source File +# Begin Source File + +SOURCE=.\TarUpdate.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# End Target +# End Project diff --git a/CPP/7zip/Archive/Tar/Tar.dsw b/CPP/7zip/Archive/Tar/Tar.dsw new file mode 100755 index 00000000..318cce1c --- /dev/null +++ b/CPP/7zip/Archive/Tar/Tar.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Tar"=.\Tar.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Archive/Tar/TarHandler.cpp b/CPP/7zip/Archive/Tar/TarHandler.cpp new file mode 100755 index 00000000..9c2cd006 --- /dev/null +++ b/CPP/7zip/Archive/Tar/TarHandler.cpp @@ -0,0 +1,282 @@ +// Tar/Handler.cpp + +#include "StdAfx.h" + +#include "TarHandler.h" +#include "TarIn.h" + +#include "Common/Defs.h" +#include "Common/StringConvert.h" +#include "Common/NewHandler.h" +#include "Common/ComTry.h" + +#include "Windows/Time.h" +#include "Windows/PropVariant.h" + +#include "../../Common/ProgressUtils.h" +#include "../../Common/LimitedStreams.h" +#include "../../Compress/Copy/CopyCoder.h" + +#include "../Common/ItemNameUtils.h" + +using namespace NWindows; +using namespace NTime; + +namespace NArchive { +namespace NTar { + +STATPROPSTG kProperties[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackedSize, VT_UI8}, + { NULL, kpidLastWriteTime, VT_FILETIME}, + { NULL, kpidUser, VT_BSTR}, + { NULL, kpidGroup, VT_BSTR}, +}; + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) +{ + value->vt = VT_EMPTY; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if(index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &srcItem = kProperties[index]; + *propID = srcItem.propid; + *varType = srcItem.vt; + *name = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +{ + *numProperties = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, + BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) +{ + return E_INVALIDARG; +} + +STDMETHODIMP CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback *openArchiveCallback) +{ + COM_TRY_BEGIN + // try + { + CInArchive archive; + + if(archive.Open(stream) != S_OK) + return S_FALSE; + + _items.Clear(); + + if (openArchiveCallback != NULL) + { + RINOK(openArchiveCallback->SetTotal(NULL, NULL)); + UInt64 numFiles = _items.Size(); + RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); + } + + for (;;) + { + CItemEx item; + bool filled; + HRESULT result = archive.GetNextItem(filled, item); + if (result == S_FALSE) + return S_FALSE; + if (result != S_OK) + return S_FALSE; + if (!filled) + break; + _items.Add(item); + archive.SkeepDataRecords(item.Size); + if (openArchiveCallback != NULL) + { + UInt64 numFiles = _items.Size(); + RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); + } + } + if (_items.Size() == 0) + return S_FALSE; + + _inStream = stream; + } + /* + catch(...) + { + return S_FALSE; + } + */ + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + _items.Clear(); + _inStream.Release(); + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _items.Size(); + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant propVariant; + const NArchive::NTar::CItemEx &item = _items[index]; + + switch(propID) + { + case kpidPath: + propVariant = (const wchar_t *)NItemName::GetOSName2( + MultiByteToUnicodeString(item.Name, CP_OEMCP)); + break; + case kpidIsFolder: + propVariant = item.IsDirectory(); + break; + case kpidSize: + case kpidPackedSize: + propVariant = (UInt64)item.Size; + break; + case kpidLastWriteTime: + { + FILETIME utcFileTime; + if (item.ModificationTime != 0) + NTime::UnixTimeToFileTime((UInt32)item.ModificationTime, utcFileTime); + else + { + utcFileTime.dwLowDateTime = 0; + utcFileTime.dwHighDateTime = 0; + } + propVariant = utcFileTime; + break; + } + case kpidUser: + propVariant = (const wchar_t *) + MultiByteToUnicodeString(item.UserName, CP_OEMCP); + break; + case kpidGroup: + propVariant = (const wchar_t *) + MultiByteToUnicodeString(item.GroupName, CP_OEMCP); + break; + } + propVariant.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool testMode = (_aTestMode != 0); + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = _items.Size(); + UInt64 totalSize = 0; + if(numItems == 0) + return S_OK; + UInt32 i; + for(i = 0; i < numItems; i++) + totalSize += _items[allFilesMode ? i : indices[i]].Size; + extractCallback->SetTotal(totalSize); + + UInt64 currentTotalSize = 0; + UInt64 currentItemSize; + + CMyComPtr copyCoder; + + for(i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + { + RINOK(extractCallback->SetCompleted(¤tTotalSize)); + CMyComPtr 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 inStream(streamSpec); + streamSpec->SetStream(_inStream); + streamSpec->Init(item.Size); + + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr progress = localProgressSpec; + localProgressSpec->Init(extractCallback, false); + + + CLocalCompressProgressInfo *localCompressProgressSpec = + new CLocalCompressProgressInfo; + CMyComPtr compressProgress = localCompressProgressSpec; + localCompressProgressSpec->Init(progress, + ¤tTotalSize, ¤tTotalSize); + + if(!copyCoder) + { + copyCoder = new NCompress::CCopyCoder; + } + try + { + RINOK(copyCoder->Code(inStream, realOutStream, + NULL, NULL, compressProgress)); + } + catch(...) + { + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); + continue; + } + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + } + } + return S_OK; + COM_TRY_END +} + +}} diff --git a/CPP/7zip/Archive/Tar/TarHandler.h b/CPP/7zip/Archive/Tar/TarHandler.h new file mode 100755 index 00000000..7b6e3a40 --- /dev/null +++ b/CPP/7zip/Archive/Tar/TarHandler.h @@ -0,0 +1,56 @@ +// Tar/Handler.h + +#ifndef __TAR_HANDLER_H +#define __TAR_HANDLER_H + +#include "Common/MyCom.h" +#include "../IArchive.h" + +#include "TarItem.h" + +namespace NArchive { +namespace NTar { + +class CHandler: + public IInArchive, + public IOutArchive, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP2( + IInArchive, + IOutArchive + ) + + STDMETHOD(Open)(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback); + STDMETHOD(Close)(); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); + + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + // IOutArchive + STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback); + STDMETHOD(GetFileTimeType)(UInt32 *type); + +private: + CObjectVector _items; + CMyComPtr _inStream; +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp new file mode 100755 index 00000000..110833fb --- /dev/null +++ b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp @@ -0,0 +1,126 @@ +// Tar/HandlerOut.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Common/ComTry.h" + +#include "Windows/PropVariant.h" +#include "Windows/Time.h" + +#include "../Common/ItemNameUtils.h" + +#include "TarHandler.h" +#include "TarUpdate.h" + +using namespace NWindows; +using namespace NCOM; +using namespace NTime; + +namespace NArchive { +namespace NTar { + +STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) +{ + *type = NFileTimeType::kUnix; + return S_OK; +} + +STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback) +{ + COM_TRY_BEGIN + CObjectVector updateItems; + for(UInt32 i = 0; i < numItems; i++) + { + CUpdateItemInfo updateItem; + Int32 newData; + Int32 newProperties; + UInt32 indexInArchive; + if (!updateCallback) + return E_FAIL; + RINOK(updateCallback->GetUpdateItemInfo(i, + &newData, &newProperties, &indexInArchive)); + updateItem.NewProperties = IntToBool(newProperties); + updateItem.NewData = IntToBool(newData); + updateItem.IndexInArchive = indexInArchive; + updateItem.IndexInClient = i; + + if (IntToBool(newProperties)) + { + FILETIME utcTime; + UString name; + bool isDirectoryStatusDefined; + UInt32 attributes; + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant)); + if (propVariant.vt == VT_EMPTY) + attributes = 0; + else if (propVariant.vt != VT_UI4) + return E_INVALIDARG; + else + attributes = propVariant.ulVal; + } + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(i, kpidLastWriteTime, &propVariant)); + if (propVariant.vt != VT_FILETIME) + return E_INVALIDARG; + utcTime = propVariant.filetime; + } + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(i, kpidPath, &propVariant)); + if (propVariant.vt == VT_EMPTY) + name.Empty(); + else if (propVariant.vt != VT_BSTR) + return E_INVALIDARG; + else + name = propVariant.bstrVal; + } + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(i, kpidIsFolder, &propVariant)); + if (propVariant.vt == VT_EMPTY) + isDirectoryStatusDefined = false; + else if (propVariant.vt != VT_BOOL) + return E_INVALIDARG; + else + { + updateItem.IsDirectory = (propVariant.boolVal != VARIANT_FALSE); + isDirectoryStatusDefined = true; + } + } + updateItem.Name = UnicodeStringToMultiByte( + NItemName::MakeLegalName(name), CP_OEMCP); + if (!isDirectoryStatusDefined) + updateItem.IsDirectory = ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); + if (updateItem.IsDirectory) + updateItem.Name += '/'; + + if(!FileTimeToUnixTime(utcTime, updateItem.Time)) + { + updateItem.Time = 0; + // return E_INVALIDARG; + } + } + if (IntToBool(newData)) + { + UInt64 size; + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant)); + if (propVariant.vt != VT_UI8) + return E_INVALIDARG; + size = propVariant.uhVal.QuadPart; + } + updateItem.Size = size; + } + updateItems.Add(updateItem); + } + return UpdateArchive(_inStream, outStream, _items, updateItems, updateCallback); + COM_TRY_END +} + +}} diff --git a/CPP/7zip/Archive/Tar/TarHeader.cpp b/CPP/7zip/Archive/Tar/TarHeader.cpp new file mode 100755 index 00000000..35f0d0cf --- /dev/null +++ b/CPP/7zip/Archive/Tar/TarHeader.cpp @@ -0,0 +1,25 @@ +// Archive/Tar/Header.h + +#include "StdAfx.h" + +#include "TarHeader.h" + +namespace NArchive { +namespace NTar { +namespace NFileHeader { + + // The checksum field is filled with this while the checksum is computed. + const char *kCheckSumBlanks = " "; // 8 blanks, no null + + const char *kLongLink = "././@LongLink"; + const char *kLongLink2 = "@LongLink"; + + // The magic field is filled with this if uname and gname are valid. + namespace NMagic + { + const char *kUsTar = "ustar"; // 5 chars + const char *kGNUTar = "GNUtar "; // 7 chars and a null + const char *kEmpty = "\0\0\0\0\0\0\0\0"; // 7 chars and a null + } + +}}} diff --git a/CPP/7zip/Archive/Tar/TarHeader.h b/CPP/7zip/Archive/Tar/TarHeader.h new file mode 100755 index 00000000..0ab31e52 --- /dev/null +++ b/CPP/7zip/Archive/Tar/TarHeader.h @@ -0,0 +1,99 @@ +// Archive/Tar/Header.h + +#ifndef __ARCHIVE_TAR_HEADER_H +#define __ARCHIVE_TAR_HEADER_H + +#include "Common/Types.h" + +namespace NArchive { +namespace NTar { + +namespace NFileHeader +{ + const int kRecordSize = 512; + const int kNameSize = 100; + const int kUserNameSize = 32; + const int kGroupNameSize = 32; + const int kPrefixSize = 155; + + /* + struct CHeader + { + char Name[kNameSize]; + char Mode[8]; + char UID[8]; + char GID[8]; + char Size[12]; + char ModificationTime[12]; + char CheckSum[8]; + char LinkFlag; + char LinkName[kNameSize]; + char Magic[8]; + char UserName[kUserNameSize]; + char GroupName[kGroupNameSize]; + char DeviceMajor[8]; + char DeviceMinor[8]; + char Prefix[155]; + }; + union CRecord + { + CHeader Header; + Byte Padding[kRecordSize]; + }; + */ + + namespace NMode + { + const int kSetUID = 04000; // Set UID on execution + const int kSetGID = 02000; // Set GID on execution + const int kSaveText = 01000; // Save text (sticky bit) + } + + namespace NFilePermissions + { + const int kUserRead = 00400; // read by owner + const int kUserWrite = 00200; // write by owner + const int kUserExecute = 00100; // execute/search by owner + const int kGroupRead = 00040; // read by group + const int kGroupWrite = 00020; // write by group + const int kGroupExecute = 00010; // execute/search by group + const int kOtherRead = 00004; // read by other + const int kOtherWrite = 00002; // write by other + const int kOtherExecute = 00001; // execute/search by other + } + + + // The linkflag defines the type of file + namespace NLinkFlag + { + const char kOldNormal = '\0'; // Normal disk file, Unix compatible + const char kNormal = '0'; // Normal disk file + const char kLink = '1'; // Link to previously dumped file + const char kSymbolicLink = '2'; // Symbolic link + const char kCharacter = '3'; // Character special file + const char kBlock = '4'; // Block special file + const char kDirectory = '5'; // Directory + const char kFIFO = '6'; // FIFO special file + const char kContiguous = '7'; // Contiguous file + } + // Further link types may be defined later. + + // The checksum field is filled with this while the checksum is computed. + extern const char *kCheckSumBlanks;// = " "; // 8 blanks, no null + + extern const char *kLongLink; // = "././@LongLink"; + extern const char *kLongLink2; // = "@LongLink"; + + // The magic field is filled with this if uname and gname are valid. + namespace NMagic + { + extern const char *kUsTar; // = "ustar"; // 5 chars + extern const char *kGNUTar; // = "GNUtar "; // 7 chars and a null + extern const char *kEmpty; // = "GNUtar "; // 7 chars and a null + } + +} + +}} + +#endif diff --git a/CPP/7zip/Archive/Tar/TarIn.cpp b/CPP/7zip/Archive/Tar/TarIn.cpp new file mode 100755 index 00000000..86afc482 --- /dev/null +++ b/CPP/7zip/Archive/Tar/TarIn.cpp @@ -0,0 +1,248 @@ +// Archive/TarIn.cpp + +#include "StdAfx.h" + +#include "TarIn.h" +#include "TarHeader.h" + +#include "Common/StringToInt.h" +#include "Windows/Defs.h" + +#include "../../Common/StreamUtils.h" + +namespace NArchive { +namespace NTar { + +HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize) +{ + RINOK(ReadStream(m_Stream, data, size, &processedSize)); + m_Position += processedSize; + return S_OK; +} + +HRESULT CInArchive::Open(IInStream *inStream) +{ + RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position)); + m_Stream = inStream; + return S_OK; +} + +static void MyStrNCpy(char *dest, const char *src, int size) +{ + for (int i = 0; i < size; i++) + { + char c = src[i]; + dest[i] = c; + if (c == 0) + break; + } +} + +static bool OctalToNumber(const char *srcString, int size, UInt64 &res) +{ + char sz[32]; + MyStrNCpy(sz, srcString, size); + sz[size] = 0; + const char *end; + int i; + for (i = 0; sz[i] == ' '; i++); + res = ConvertOctStringToUInt64(sz + i, &end); + return (*end == ' ' || *end == 0); +} + +static bool OctalToNumber32(const char *srcString, int size, UInt32 &res) +{ + UInt64 res64; + if (!OctalToNumber(srcString, size, res64)) + return false; + res = (UInt32)res64; + return (res64 <= 0xFFFFFFFF); +} + +#define RIF(x) { if (!(x)) return S_FALSE; } + +static bool IsRecordLast(const char *record) +{ + for (int i = 0; i < NFileHeader::kRecordSize; i++) + if (record[i] != 0) + return false; + return true; +} + +static void ReadString(const char *s, int size, AString &result) +{ + if (size > NFileHeader::kRecordSize) + size = NFileHeader::kNameSize; + char tempString[NFileHeader::kRecordSize + 1]; + MyStrNCpy(tempString, s, size); + tempString[size] = '\0'; + result = tempString; +} + +static char GetHex(Byte value) +{ + return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10))); +} + +HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item) +{ + item.LongLinkSize = 0; + // NFileHeader::CRecord record; + char record[NFileHeader::kRecordSize]; + char *cur = record; + + filled = false; + + UInt32 processedSize; + item.HeaderPosition = m_Position; + RINOK(ReadBytes(record, NFileHeader::kRecordSize, processedSize)); + if (processedSize == 0 || + (processedSize == NFileHeader::kRecordSize && IsRecordLast(record))) + return S_OK; + if (processedSize < NFileHeader::kRecordSize) + return S_FALSE; + + // NFileHeader::CHeader &header = record.Header; + + AString name; + ReadString(cur, NFileHeader::kNameSize, name); + cur += NFileHeader::kNameSize; + + item.Name.Empty(); + int i; + for (i = 0; i < name.Length(); i++) + { + char c = name[i]; + if (((Byte)c) < 0x08) + { + return S_FALSE; + } + if (((Byte)c) < 0x20) + { + item.Name += '['; + item.Name += GetHex((Byte)(((Byte)c) >> 4)); + item.Name += GetHex((Byte)(((Byte)c) & 0xF)); + item.Name += ']'; + } + else + item.Name += c; + } + + RIF(OctalToNumber32(cur, 8, item.Mode)); + cur += 8; + + if (!OctalToNumber32(cur, 8, item.UID)) + item.UID = 0; + cur += 8; + + if (!OctalToNumber32(cur, 8, item.GID)) + item.GID = 0; + cur += 8; + + RIF(OctalToNumber(cur, 12, item.Size)); + cur += 12; + + RIF(OctalToNumber32(cur, 12, item.ModificationTime)); + cur += 12; + + UInt32 checkSum; + RIF(OctalToNumber32(cur, 8, checkSum)); + memmove(cur, NFileHeader::kCheckSumBlanks, 8); + cur += 8; + + item.LinkFlag = *cur++; + + ReadString(cur, NFileHeader::kNameSize, item.LinkName); + cur += NFileHeader::kNameSize; + + memmove(item.Magic, cur, 8); + cur += 8; + + ReadString(cur, NFileHeader::kUserNameSize, item.UserName); + cur += NFileHeader::kUserNameSize; + ReadString(cur, NFileHeader::kUserNameSize, item.GroupName); + cur += NFileHeader::kUserNameSize; + + item.DeviceMajorDefined = (cur[0] != 0); + RIF(OctalToNumber32(cur, 8, item.DeviceMajor)); + cur += 8; + + item.DeviceMinorDefined = (cur[0] != 0); + RIF(OctalToNumber32(cur, 8, item.DeviceMinor)); + cur += 8; + + AString prefix; + ReadString(cur, NFileHeader::kPrefixSize, prefix); + cur += NFileHeader::kPrefixSize; + if (!prefix.IsEmpty() && item.IsMagic()) + item.Name = prefix + AString('/') + item.Name; + + if (item.LinkFlag == NFileHeader::NLinkFlag::kLink) + item.Size = 0; + + + UInt32 checkSumReal = 0; + for(i = 0; i < NFileHeader::kRecordSize; i++) + checkSumReal += Byte(record[i]); + + if (checkSumReal != checkSum) + return S_FALSE; + + filled = true; + return S_OK; +} + +HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) +{ + RINOK(GetNextItemReal(filled, item)); + if (!filled) + return S_OK; + // GNUtar extension + if (item.LinkFlag == 'L') + { + if (item.Name.Compare(NFileHeader::kLongLink) != 0) + if (item.Name.Compare(NFileHeader::kLongLink2) != 0) + return S_FALSE; + UInt64 headerPosition = item.HeaderPosition; + + UInt32 processedSize; + AString fullName; + char *buffer = fullName.GetBuffer((UInt32)item.Size + 1); + RINOK(ReadBytes(buffer, (UInt32)item.Size, processedSize)); + buffer[item.Size] = '\0'; + fullName.ReleaseBuffer(); + if (processedSize != item.Size) + return S_FALSE; + RINOK(Skeep((0 - item.Size) & 0x1FF)); + RINOK(GetNextItemReal(filled, item)); + item.Name = fullName; + item.LongLinkSize = item.HeaderPosition - headerPosition; + item.HeaderPosition = headerPosition; + } + else if (item.LinkFlag == 'g' || item.LinkFlag == 'x') + { + // pax Extended Header + return S_OK; + } + else if (item.LinkFlag > '7' || (item.LinkFlag < '0' && item.LinkFlag != 0)) + return S_FALSE; + return S_OK; +} + +HRESULT CInArchive::Skeep(UInt64 numBytes) +{ + UInt64 newPostion; + RINOK(m_Stream->Seek(numBytes, STREAM_SEEK_CUR, &newPostion)); + m_Position += numBytes; + if (m_Position != newPostion) + return E_FAIL; + return S_OK; +} + + +HRESULT CInArchive::SkeepDataRecords(UInt64 dataSize) +{ + return Skeep((dataSize + 0x1FF) & (~((UInt64)0x1FF))); +} + +}} diff --git a/CPP/7zip/Archive/Tar/TarIn.h b/CPP/7zip/Archive/Tar/TarIn.h new file mode 100755 index 00000000..28781375 --- /dev/null +++ b/CPP/7zip/Archive/Tar/TarIn.h @@ -0,0 +1,30 @@ +// Archive/TarIn.h + +#ifndef __ARCHIVE_TAR_IN_H +#define __ARCHIVE_TAR_IN_H + +#include "Common/MyCom.h" +#include "../../IStream.h" + +#include "TarItem.h" + +namespace NArchive { +namespace NTar { + +class CInArchive +{ + CMyComPtr m_Stream; + UInt64 m_Position; + + HRESULT ReadBytes(void *data, UInt32 size, UInt32 &processedSize); +public: + HRESULT Open(IInStream *inStream); + HRESULT GetNextItemReal(bool &filled, CItemEx &itemInfo); + HRESULT GetNextItem(bool &filled, CItemEx &itemInfo); + HRESULT Skeep(UInt64 numBytes); + HRESULT SkeepDataRecords(UInt64 dataSize); +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Tar/TarItem.h b/CPP/7zip/Archive/Tar/TarItem.h new file mode 100755 index 00000000..71fff7ba --- /dev/null +++ b/CPP/7zip/Archive/Tar/TarItem.h @@ -0,0 +1,69 @@ +// Archive/Tar/Item.h + +#ifndef __ARCHIVE_TAR_ITEM_H +#define __ARCHIVE_TAR_ITEM_H + +#include + +#include "Common/Types.h" +#include "Common/String.h" + +#include "../Common/ItemNameUtils.h" +#include "TarHeader.h" + +namespace NArchive { +namespace NTar { + +class CItem +{ +public: + AString Name; + UInt32 Mode; + UInt32 UID; + UInt32 GID; + UInt64 Size; + UInt32 ModificationTime; + char LinkFlag; + AString LinkName; + char Magic[8]; + AString UserName; + AString GroupName; + + bool DeviceMajorDefined; + UInt32 DeviceMajor; + bool DeviceMinorDefined; + UInt32 DeviceMinor; + + bool IsDirectory() const + { + if (LinkFlag == NFileHeader::NLinkFlag::kDirectory) + return true; + if (LinkFlag == NFileHeader::NLinkFlag::kOldNormal || + LinkFlag == NFileHeader::NLinkFlag::kNormal) + { + return NItemName::HasTailSlash(Name, CP_OEMCP); + } + return false; + } + + bool IsMagic() const + { + for (int i = 0; i < 5; i++) + if (Magic[i] != NFileHeader::NMagic::kUsTar[i]) + return false; + return true; + } +}; + +class CItemEx: public CItem +{ +public: + UInt64 HeaderPosition; + UInt64 LongLinkSize; + UInt64 GetDataPosition() const { return HeaderPosition + LongLinkSize + NFileHeader::kRecordSize; }; + UInt64 GetFullSize() const { return LongLinkSize + NFileHeader::kRecordSize + Size; }; +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Tar/TarOut.cpp b/CPP/7zip/Archive/Tar/TarOut.cpp new file mode 100755 index 00000000..e278edda --- /dev/null +++ b/CPP/7zip/Archive/Tar/TarOut.cpp @@ -0,0 +1,191 @@ +// Archive/TarOut.cpp + +#include "StdAfx.h" + +#include "TarOut.h" +#include "TarHeader.h" + +#include "Common/IntToString.h" +#include "Windows/Defs.h" +#include "../../Common/StreamUtils.h" + +namespace NArchive { +namespace NTar { + +HRESULT COutArchive::WriteBytes(const void *buffer, UInt32 size) +{ + UInt32 processedSize; + RINOK(WriteStream(m_Stream, buffer, size, &processedSize)); + if(processedSize != size) + return E_FAIL; + return S_OK; +} + +void COutArchive::Create(ISequentialOutStream *outStream) +{ + m_Stream = outStream; +} + +static AString MakeOctalString(UInt64 value) +{ + char s[32]; + ConvertUInt64ToString(value, s, 8); + return AString(s) + ' '; +} + +static void MyStrNCpy(char *dest, const char *src, int size) +{ + for (int i = 0; i < size; i++) + { + char c = src[i]; + dest[i] = c; + if (c == 0) + break; + } +} + +static bool MakeOctalString8(char *s, UInt32 value) +{ + AString tempString = MakeOctalString(value); + + const int kMaxSize = 8; + if (tempString.Length() >= kMaxSize) + return false; + int numSpaces = kMaxSize - (tempString.Length() + 1); + for(int i = 0; i < numSpaces; i++) + s[i] = ' '; + MyStringCopy(s + numSpaces, (const char *)tempString); + return true; +} + +static bool MakeOctalString12(char *s, UInt64 value) +{ + AString tempString = MakeOctalString(value); + const int kMaxSize = 12; + if (tempString.Length() > kMaxSize) + return false; + int numSpaces = kMaxSize - tempString.Length(); + for(int i = 0; i < numSpaces; i++) + s[i] = ' '; + memmove(s + numSpaces, (const char *)tempString, tempString.Length()); + return true; +} + +static bool CopyString(char *dest, const AString &src, int maxSize) +{ + if (src.Length() >= maxSize) + return false; + MyStringCopy(dest, (const char *)src); + return true; +} + +#define RETURN_IF_NOT_TRUE(x) { if (!(x)) return E_FAIL; } + +HRESULT COutArchive::WriteHeaderReal(const CItem &item) +{ + char record[NFileHeader::kRecordSize]; + char *cur = record; + int i; + for (i = 0; i < NFileHeader::kRecordSize; i++) + record[i] = 0; + + // RETURN_IF_NOT_TRUE(CopyString(header.Name, item.Name, NFileHeader::kNameSize)); + if (item.Name.Length() > NFileHeader::kNameSize) + return E_FAIL; + MyStrNCpy(cur, item.Name, NFileHeader::kNameSize); + cur += NFileHeader::kNameSize; + + RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.Mode)); + cur += 8; + RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.UID)); + cur += 8; + RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.GID)); + cur += 8; + + RETURN_IF_NOT_TRUE(MakeOctalString12(cur, item.Size)); + cur += 12; + RETURN_IF_NOT_TRUE(MakeOctalString12(cur, item.ModificationTime)); + cur += 12; + + memmove(cur, NFileHeader::kCheckSumBlanks, 8); + cur += 8; + + *cur++ = item.LinkFlag; + + RETURN_IF_NOT_TRUE(CopyString(cur, item.LinkName, NFileHeader::kNameSize)); + cur += NFileHeader::kNameSize; + + memmove(cur, item.Magic, 8); + cur += 8; + + RETURN_IF_NOT_TRUE(CopyString(cur, item.UserName, NFileHeader::kUserNameSize)); + cur += NFileHeader::kUserNameSize; + RETURN_IF_NOT_TRUE(CopyString(cur, item.GroupName, NFileHeader::kGroupNameSize)); + cur += NFileHeader::kUserNameSize; + + + if (item.DeviceMajorDefined) + RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.DeviceMajor)); + cur += 8; + + if (item.DeviceMinorDefined) + RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.DeviceMinor)); + cur += 8; + + + UInt32 checkSumReal = 0; + for(i = 0; i < NFileHeader::kRecordSize; i++) + checkSumReal += Byte(record[i]); + + RETURN_IF_NOT_TRUE(MakeOctalString8(record + 148, checkSumReal)); + + return WriteBytes(record, NFileHeader::kRecordSize); +} + +HRESULT COutArchive::WriteHeader(const CItem &item) +{ + int nameSize = item.Name.Length(); + if (nameSize < NFileHeader::kNameSize) + return WriteHeaderReal(item); + + CItem modifiedItem = item; + int nameStreamSize = nameSize + 1; + modifiedItem.Size = nameStreamSize; + modifiedItem.LinkFlag = 'L'; + modifiedItem.Name = NFileHeader::kLongLink; + modifiedItem.LinkName.Empty(); + RINOK(WriteHeaderReal(modifiedItem)); + RINOK(WriteBytes(item.Name, nameStreamSize)); + RINOK(FillDataResidual(nameStreamSize)); + + modifiedItem = item; + modifiedItem.Name = item.Name.Left(NFileHeader::kNameSize - 1); + return WriteHeaderReal(modifiedItem); +} + +HRESULT COutArchive::FillDataResidual(UInt64 dataSize) +{ + UInt32 lastRecordSize = UInt32(dataSize & (NFileHeader::kRecordSize - 1)); + if (lastRecordSize == 0) + return S_OK; + UInt32 residualSize = NFileHeader::kRecordSize - lastRecordSize; + Byte residualBytes[NFileHeader::kRecordSize]; + for (UInt32 i = 0; i < residualSize; i++) + residualBytes[i] = 0; + return WriteBytes(residualBytes, residualSize); +} + +HRESULT COutArchive::WriteFinishHeader() +{ + Byte record[NFileHeader::kRecordSize]; + int i; + for (i = 0; i < NFileHeader::kRecordSize; i++) + record[i] = 0; + for (i = 0; i < 2; i++) + { + RINOK(WriteBytes(record, NFileHeader::kRecordSize)); + } + return S_OK; +} + +}} diff --git a/CPP/7zip/Archive/Tar/TarOut.h b/CPP/7zip/Archive/Tar/TarOut.h new file mode 100755 index 00000000..ef837869 --- /dev/null +++ b/CPP/7zip/Archive/Tar/TarOut.h @@ -0,0 +1,28 @@ +// Archive/TarOut.h + +#ifndef __ARCHIVE_TAR_OUT_H +#define __ARCHIVE_TAR_OUT_H + +#include "TarItem.h" + +#include "Common/MyCom.h" +#include "../../IStream.h" + +namespace NArchive { +namespace NTar { + +class COutArchive +{ + CMyComPtr m_Stream; + HRESULT WriteBytes(const void *buffer, UInt32 size); +public: + void Create(ISequentialOutStream *outStream); + HRESULT WriteHeaderReal(const CItem &item); + HRESULT WriteHeader(const CItem &item); + HRESULT FillDataResidual(UInt64 dataSize); + HRESULT WriteFinishHeader(); +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Tar/TarUpdate.cpp b/CPP/7zip/Archive/Tar/TarUpdate.cpp new file mode 100755 index 00000000..9a6f64e2 --- /dev/null +++ b/CPP/7zip/Archive/Tar/TarUpdate.cpp @@ -0,0 +1,162 @@ +// TarUpdate.cpp + +#include "StdAfx.h" + +#include "Common/Defs.h" +#include "Common/StringConvert.h" +#include "Windows/Defs.h" + +#include "../../Common/ProgressUtils.h" +#include "../../Common/LimitedStreams.h" +#include "../../Compress/Copy/CopyCoder.h" + +#include "TarOut.h" +#include "TarUpdate.h" + +static const UInt64 kOneItemComplexity = 512; + +namespace NArchive { +namespace NTar { + +static HRESULT CopyBlock(ISequentialInStream *inStream, + ISequentialOutStream *outStream, ICompressProgressInfo *progress, + UInt64 *totalSize = NULL) +{ + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; + CMyComPtr 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 &inputItems, + const CObjectVector &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 localProgress = localProgressSpec; + localProgressSpec->Init(updateCallback, true); + + CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo; + CMyComPtr compressProgress = localCompressProgressSpec; + + localCompressProgressSpec->Init(localProgress, &complexity, NULL); + + const CUpdateItemInfo &updateItem = updateItems[i]; + CItem item; + if (updateItem.NewProperties) + { + item.Mode = 0777; + item.Name = (updateItem.Name); + if (updateItem.IsDirectory) + { + item.LinkFlag = NFileHeader::NLinkFlag::kDirectory; + item.Size = 0; + } + else + { + item.LinkFlag = NFileHeader::NLinkFlag::kNormal; + item.Size = updateItem.Size; + } + item.ModificationTime = updateItem.Time; + item.DeviceMajorDefined = false; + item.DeviceMinorDefined = false; + item.UID = 0; + item.GID = 0; + memmove(item.Magic, NFileHeader::NMagic::kEmpty, 8); + } + else + { + const CItemEx &existItemInfo = inputItems[updateItem.IndexInArchive]; + item = existItemInfo; + } + if (updateItem.NewData) + { + item.Size = updateItem.Size; + if (item.Size == UInt64(Int64(-1))) + return E_INVALIDARG; + } + else + { + const CItemEx &existItemInfo = inputItems[updateItem.IndexInArchive]; + item.Size = existItemInfo.Size; + } + + if (updateItem.NewData) + { + CMyComPtr fileInStream; + HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream); + if (res != S_FALSE) + { + RINOK(res); + RINOK(outArchive.WriteHeader(item)); + if (!updateItem.IsDirectory) + { + UInt64 totalSize; + RINOK(CopyBlock(fileInStream, outStream, compressProgress, &totalSize)); + if (totalSize != item.Size) + return E_FAIL; + RINOK(outArchive.FillDataResidual(item.Size)); + } + } + complexity += updateItem.Size; + RINOK(updateCallback->SetOperationResult( + NArchive::NUpdate::NOperationResult::kOK)); + } + else + { + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr inStreamLimited(streamSpec); + const CItemEx &existItemInfo = inputItems[updateItem.IndexInArchive]; + if (updateItem.NewProperties) + { + RINOK(outArchive.WriteHeader(item)); + RINOK(inStream->Seek(existItemInfo.GetDataPosition(), + STREAM_SEEK_SET, NULL)); + streamSpec->SetStream(inStream); + streamSpec->Init(existItemInfo.Size); + } + else + { + RINOK(inStream->Seek(existItemInfo.HeaderPosition, + STREAM_SEEK_SET, NULL)); + streamSpec->SetStream(inStream); + streamSpec->Init(existItemInfo.GetFullSize()); + } + RINOK(CopyBlock(inStreamLimited, outStream, compressProgress)); + RINOK(outArchive.FillDataResidual(existItemInfo.Size)); + complexity += existItemInfo.GetFullSize(); + } + complexity += kOneItemComplexity; + } + return outArchive.WriteFinishHeader(); +} + +}} + diff --git a/CPP/7zip/Archive/Tar/TarUpdate.h b/CPP/7zip/Archive/Tar/TarUpdate.h new file mode 100755 index 00000000..92f5cebb --- /dev/null +++ b/CPP/7zip/Archive/Tar/TarUpdate.h @@ -0,0 +1,36 @@ +// Tar/Update.h + +#ifndef __TAR_UPDATE_H +#define __TAR_UPDATE_H + +#include "Common/Vector.h" +#include "Common/Types.h" +#include "Common/String.h" + +#include "../IArchive.h" +#include "TarItem.h" + +namespace NArchive { +namespace NTar { + +struct CUpdateItemInfo +{ + bool NewData; + bool NewProperties; + int IndexInArchive; + int IndexInClient; + + UInt32 Time; + UInt64 Size; + AString Name; + bool IsDirectory; +}; + +HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, + const CObjectVector &inputItems, + const CObjectVector &updateItems, + IArchiveUpdateCallback *updateCallback); + +}} + +#endif diff --git a/CPP/7zip/Archive/Tar/makefile b/CPP/7zip/Archive/Tar/makefile new file mode 100755 index 00000000..f892c303 --- /dev/null +++ b/CPP/7zip/Archive/Tar/makefile @@ -0,0 +1,59 @@ +PROG = tar.dll +DEF_FILE = ../Archive.def +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib user32.lib + +TAR_OBJS = \ + $O\DllExports.obj \ + $O\TarHandler.obj \ + $O\TarHandlerOut.obj \ + $O\TarHeader.obj \ + $O\TarIn.obj \ + $O\TarOut.obj \ + $O\TarUpdate.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\Vector.obj \ + +WIN_OBJS = \ + $O\PropVariant.obj \ + +7ZIP_COMMON_OBJS = \ + $O\LimitedStreams.obj \ + $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ + +AR_COMMON_OBJS = \ + $O\ItemNameUtils.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(TAR_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $(COMPRESS_TAR_OBJS) \ + $O\CopyCoder.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(TAR_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/Archive/Tar/resource.rc b/CPP/7zip/Archive/Tar/resource.rc new file mode 100755 index 00000000..3d37f440 --- /dev/null +++ b/CPP/7zip/Archive/Tar/resource.rc @@ -0,0 +1,5 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("Tar Plugin", "tar") + +101 ICON "tar.ico" diff --git a/CPP/7zip/Archive/Tar/tar.ico b/CPP/7zip/Archive/Tar/tar.ico new file mode 100755 index 00000000..6835885b Binary files /dev/null and b/CPP/7zip/Archive/Tar/tar.ico differ diff --git a/CPP/7zip/Archive/Z/DllExports.cpp b/CPP/7zip/Archive/Z/DllExports.cpp new file mode 100755 index 00000000..b8df85f4 --- /dev/null +++ b/CPP/7zip/Archive/Z/DllExports.cpp @@ -0,0 +1,91 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "Windows/PropVariant.h" +#include "ZHandler.h" +#include "../../ICoder.h" + +// {23170F69-40C1-278A-1000-000110050000} +DEFINE_GUID(CLSID_CZHandler, +0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 0x00, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /* lpReserved */) +{ + return TRUE; +} + +STDAPI CreateObject( + const GUID *classID, + const GUID *interfaceID, + void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + if (*classID != CLSID_CZHandler) + return CLASS_E_CLASSNOTAVAILABLE; + int needIn = *interfaceID == IID_IInArchive; + int needOut = *interfaceID == IID_IOutArchive; + if (needIn || needOut) + { + NArchive::NZ::CHandler *temp = new NArchive::NZ::CHandler; + if (needIn) + { + CMyComPtr inArchive = (IInArchive *)temp; + *outObject = inArchive.Detach(); + } + else + { + CMyComPtr outArchive = (IOutArchive *)temp; + *outObject = outArchive.Detach(); + } + } + else + return E_NOINTERFACE; + COM_TRY_END + return S_OK; +} + + +STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case NArchive::kName: + propVariant = L"Z"; + break; + case NArchive::kClassID: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CZHandler, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NArchive::kExtension: + propVariant = L"z taz"; + break; + case NArchive::kAddExtension: + propVariant = L"* .tar"; + break; + case NArchive::kUpdate: + propVariant = false; + break; + case NArchive::kKeepName: + propVariant = true; + break; + case NArchive::kStartSignature: + { + const unsigned char sig[] = { 0x1F, 0x9D }; + if ((value->bstrVal = ::SysAllocStringByteLen((const char *)sig, 2)) != 0) + value->vt = VT_BSTR; + return S_OK; + } + + } + propVariant.Detach(value); + return S_OK; +} diff --git a/CPP/7zip/Archive/Z/StdAfx.cpp b/CPP/7zip/Archive/Z/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Archive/Z/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Z/StdAfx.h b/CPP/7zip/Archive/Z/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Archive/Z/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Archive/Z/Z.dsp b/CPP/7zip/Archive/Z/Z.dsp new file mode 100755 index 00000000..e1f72522 --- /dev/null +++ b/CPP/7zip/Archive/Z/Z.dsp @@ -0,0 +1,237 @@ +# Microsoft Developer Studio Project File - Name="Z" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Z - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Z.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Z.mak" CFG="Z - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Z - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Z - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Z - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\z.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Z - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\z.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Z - Win32 Release" +# Name "Z - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Archive.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# Begin Source File + +SOURCE=.\Z.ico +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# End Group +# Begin Group "Compression" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Z\ZDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Z\ZDecoder.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\DummyOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\DummyOutStream.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ZHandler.cpp +# End Source File +# Begin Source File + +SOURCE=.\ZHandler.h +# End Source File +# End Group +# Begin Group "7zip common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\z.ico +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/Archive/Z/Z.dsw b/CPP/7zip/Archive/Z/Z.dsw new file mode 100755 index 00000000..1f67186a --- /dev/null +++ b/CPP/7zip/Archive/Z/Z.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Z"=.\Z.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Archive/Z/Z.ico b/CPP/7zip/Archive/Z/Z.ico new file mode 100755 index 00000000..2db53583 Binary files /dev/null and b/CPP/7zip/Archive/Z/Z.ico differ diff --git a/CPP/7zip/Archive/Z/ZHandler.cpp b/CPP/7zip/Archive/Z/ZHandler.cpp new file mode 100755 index 00000000..33887690 --- /dev/null +++ b/CPP/7zip/Archive/Z/ZHandler.cpp @@ -0,0 +1,202 @@ +// ZHandler.cpp + +#include "StdAfx.h" + +#include "ZHandler.h" + +#include "Common/Defs.h" + +#include "../../Common/ProgressUtils.h" +#include "../../Compress/Z/ZDecoder.h" +#include "../../Common/StreamUtils.h" + +#include "Windows/PropVariant.h" +#include "Windows/Defs.h" +#include "Common/ComTry.h" + +#include "../Common/DummyOutStream.h" + +namespace NArchive { +namespace NZ { + +STATPROPSTG kProperties[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidPackedSize, VT_UI8}, +}; + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) +{ + value->vt = VT_EMPTY; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if(index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &srcItem = kProperties[index]; + *propID = srcItem.propid; + *varType = srcItem.vt; + *name = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +{ + *numProperties = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, + BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) +{ + return E_INVALIDARG; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = 1; + return S_OK; +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant propVariant; + if (index != 0) + return E_INVALIDARG; + switch(propID) + { + case kpidIsFolder: + propVariant = false; + break; + case kpidPackedSize: + propVariant = _packSize; + break; + } + propVariant.Detach(value); + return S_OK; + COM_TRY_END +} + +static const int kSignatureSize = 3; + +STDMETHODIMP CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */) +{ + COM_TRY_BEGIN + try + { + RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition)); + Byte buffer[kSignatureSize]; + UInt32 processedSize; + RINOK(ReadStream(stream, buffer, kSignatureSize, &processedSize)); + if (processedSize != kSignatureSize) + return S_FALSE; + if (buffer[0] != 0x1F || buffer[1] != 0x9D) + return S_FALSE; + _properties = buffer[2]; + + UInt64 endPosition; + RINOK(stream->Seek(0, STREAM_SEEK_END, &endPosition)); + _packSize = endPosition - _streamStartPosition - kSignatureSize; + + _stream = stream; + } + catch(...) + { + return S_FALSE; + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + _stream.Release(); + return S_OK; +} + + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 testModeSpec, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool allFilesMode = (numItems == (UInt32)(-1)); + if (!allFilesMode) + { + if (numItems == 0) + return S_OK; + if (numItems != 1) + return E_INVALIDARG; + if (indices[0] != 0) + return E_INVALIDARG; + } + + bool testMode = (testModeSpec != 0); + + extractCallback->SetTotal(_packSize); + + UInt64 currentTotalPacked = 0; + + RINOK(extractCallback->SetCompleted(¤tTotalPacked)); + + CMyComPtr 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 outStream(outStreamSpec); + outStreamSpec->Init(realOutStream); + + realOutStream.Release(); + + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr progress = localProgressSpec; + localProgressSpec->Init(extractCallback, true); + + RINOK(_stream->Seek(_streamStartPosition + kSignatureSize, STREAM_SEEK_SET, NULL)); + + CMyComPtr decoder; + NCompress::NZ::CDecoder *decoderSpec = new NCompress::NZ::CDecoder; + decoder = decoderSpec; + + HRESULT result = decoderSpec->SetDecoderProperties2(&_properties, 1); + + int opResult; + if (result != S_OK) + opResult = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + else + { + result = decoder->Code(_stream, outStream, NULL, NULL, progress); + outStream.Release(); + if (result == S_FALSE) + opResult = NArchive::NExtract::NOperationResult::kDataError; + else if (result == S_OK) + opResult = NArchive::NExtract::NOperationResult::kOK; + else + return result; + } + RINOK(extractCallback->SetOperationResult(opResult)); + return S_OK; + COM_TRY_END +} + +}} diff --git a/CPP/7zip/Archive/Z/ZHandler.h b/CPP/7zip/Archive/Z/ZHandler.h new file mode 100755 index 00000000..7abba29f --- /dev/null +++ b/CPP/7zip/Archive/Z/ZHandler.h @@ -0,0 +1,47 @@ +// ZHandler.h + +#ifndef __Z_HANDLER_H +#define __Z_HANDLER_H + +#include "Common/MyCom.h" +#include "../IArchive.h" + +namespace NArchive { +namespace NZ { + +class CHandler: + public IInArchive, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Open)(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback); + STDMETHOD(Close)(); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); + + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + +private: + CMyComPtr _stream; + UInt64 _streamStartPosition; + UInt64 _packSize; + Byte _properties; +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Z/makefile b/CPP/7zip/Archive/Z/makefile new file mode 100755 index 00000000..aff4fc42 --- /dev/null +++ b/CPP/7zip/Archive/Z/makefile @@ -0,0 +1,52 @@ +PROG = z.dll +DEF_FILE = ../Archive.def +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib + +Z_OBJS = \ + $O\DllExports.obj \ + $O\ZHandler.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\NewHandler.obj \ + +WIN_OBJS = \ + $O\PropVariant.obj \ + +7ZIP_COMMON_OBJS = \ + $O\InBuffer.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ + +AR_COMMON_OBJS = \ + $O\DummyOutStream.obj \ + +COMPRESS_Z_OBJS = \ + $O\ZDecoder.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(Z_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $(COMPRESS_Z_OBJS) \ + $O\resource.res + +!include "../../../Build.mak" + +$(Z_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$(COMPRESS_Z_OBJS): ../../Compress/Z/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/Archive/Z/resource.rc b/CPP/7zip/Archive/Z/resource.rc new file mode 100755 index 00000000..05a81423 --- /dev/null +++ b/CPP/7zip/Archive/Z/resource.rc @@ -0,0 +1,5 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("Z Plugin", "z") + +101 ICON "Z.ico" diff --git a/CPP/7zip/Archive/Zip/DllExports.cpp b/CPP/7zip/Archive/Zip/DllExports.cpp new file mode 100755 index 00000000..da2a15a4 --- /dev/null +++ b/CPP/7zip/Archive/Zip/DllExports.cpp @@ -0,0 +1,152 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "ZipHandler.h" +#include "Windows/PropVariant.h" +#include "../../ICoder.h" +#include "../../IPassword.h" +#include "../../Crypto/WzAES/WzAES.h" +#include "../Common/CodecsPath.h" + +// {23170F69-40C1-278B-0401-080000000100} +DEFINE_GUID(CLSID_CCompressDeflateEncoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00); + +// {23170F69-40C1-278B-0401-080000000000} +DEFINE_GUID(CLSID_CCompressDeflateDecoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00); + +// {23170F69-40C1-278B-0401-090000000100} +DEFINE_GUID(CLSID_CCompressDeflate64Encoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00); + +// {23170F69-40C1-278B-0401-090000000000} +DEFINE_GUID(CLSID_CCompressDeflate64Decoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00); + +// {23170F69-40C1-278B-0402-020000000100} +DEFINE_GUID(CLSID_CCompressBZip2Encoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00); + +// {23170F69-40C1-278B-0402-020000000000} +DEFINE_GUID(CLSID_CCompressBZip2Decoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00); + +// {23170F69-40C1-278B-0401-060000000000} +DEFINE_GUID(CLSID_CCompressImplodeDecoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00); + +// {23170F69-40C1-278B-06F1-0101000000100} +DEFINE_GUID(CLSID_CCryptoZipEncoder, +0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00); + +// {23170F69-40C1-278B-06F1-0101000000000} +DEFINE_GUID(CLSID_CCryptoZipDecoder, +0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00); + +// {23170F69-40C1-278A-1000-000110010000} +DEFINE_GUID(CLSID_CZipHandler, + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x01, 0x00, 0x00); + +HINSTANCE g_hInstance; +#ifndef _UNICODE +bool g_IsNT = false; +static bool IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); +} +#endif + +void GetCryptoFolderPrefix(TCHAR *path) +{ + CSysString s = GetCodecsFolderPrefix(); + lstrcpy(path, s); +} + +extern "C" +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + g_hInstance = hInstance; + #ifndef _UNICODE + g_IsNT = IsItWindowsNT(); + #endif + } + return TRUE; +} + + +STDAPI CreateObject( + const GUID *classID, + const GUID *interfaceID, + void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + if (*classID != CLSID_CZipHandler) + return CLASS_E_CLASSNOTAVAILABLE; + int needIn = *interfaceID == IID_IInArchive; + int needOut = *interfaceID == IID_IOutArchive; + if (needIn || needOut) + { + NArchive::NZip::CHandler *temp = new NArchive::NZip::CHandler; + if (needIn) + { + CMyComPtr inArchive = (IInArchive *)temp; + *outObject = inArchive.Detach(); + } + else + { + CMyComPtr outArchive = (IOutArchive *)temp; + *outObject = outArchive.Detach(); + } + } + else + return E_NOINTERFACE; + COM_TRY_END + return S_OK; +} + +STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case NArchive::kName: + propVariant = L"Zip"; + break; + case NArchive::kClassID: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CZipHandler, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NArchive::kExtension: + propVariant = L"zip jar xpi"; + break; + case NArchive::kUpdate: + propVariant = true; + break; + case NArchive::kKeepName: + propVariant = false; + break; + case NArchive::kStartSignature: + { + const char sig[] = { 0x50, 0x4B, 0x03, 0x04 }; + if ((value->bstrVal = ::SysAllocStringByteLen(sig, 4)) != 0) + value->vt = VT_BSTR; + return S_OK; + } + } + propVariant.Detach(value); + return S_OK; +} diff --git a/CPP/7zip/Archive/Zip/StdAfx.cpp b/CPP/7zip/Archive/Zip/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Archive/Zip/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Archive/Zip/StdAfx.h b/CPP/7zip/Archive/Zip/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Archive/Zip/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Archive/Zip/Zip.dsp b/CPP/7zip/Archive/Zip/Zip.dsp new file mode 100755 index 00000000..2ac27f4f --- /dev/null +++ b/CPP/7zip/Archive/Zip/Zip.dsp @@ -0,0 +1,651 @@ +# Microsoft Developer Studio Project File - Name="Zip" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Zip - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Zip.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Zip.mak" CFG="Zip - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Zip - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Zip - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Zip - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZIP_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZIP_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\zip.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Zip - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZIP_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZIP_EXPORTS" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\zip.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Zip - Win32 Release" +# Name "Zip - Win32 Debug" +# Begin Group "spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Archive.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\AutoPtr.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Buffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Random.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Random.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Thread.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\CodecsPath.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\CodecsPath.h +# End Source File +# Begin Source File + +SOURCE=..\Common\CoderLoader.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\CoderLoader.h +# End Source File +# Begin Source File + +SOURCE=..\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\Common\InStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\InStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\OutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\OutStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ParseProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ParseProperties.h +# End Source File +# End Group +# Begin Group "7zip common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LSBFDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LSBFDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MemBlocks.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MemBlocks.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OffsetStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OffsetStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutMemStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutMemStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressMt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressMt.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ZipAddCommon.cpp +# End Source File +# Begin Source File + +SOURCE=.\ZipAddCommon.h +# End Source File +# Begin Source File + +SOURCE=.\ZipCompressionMode.h +# End Source File +# Begin Source File + +SOURCE=.\ZipHandler.cpp +# End Source File +# Begin Source File + +SOURCE=.\ZipHandler.h +# End Source File +# Begin Source File + +SOURCE=.\ZipHandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=.\ZipHeader.cpp +# End Source File +# Begin Source File + +SOURCE=.\ZipHeader.h +# End Source File +# Begin Source File + +SOURCE=.\ZipIn.cpp +# End Source File +# Begin Source File + +SOURCE=.\ZipIn.h +# End Source File +# Begin Source File + +SOURCE=.\ZipItem.cpp +# End Source File +# Begin Source File + +SOURCE=.\ZipItem.h +# End Source File +# Begin Source File + +SOURCE=.\ZipItemEx.h +# End Source File +# Begin Source File + +SOURCE=.\ZipOut.cpp +# End Source File +# Begin Source File + +SOURCE=.\ZipOut.h +# End Source File +# Begin Source File + +SOURCE=.\ZipUpdate.cpp +# End Source File +# Begin Source File + +SOURCE=.\ZipUpdate.h +# End Source File +# End Group +# Begin Group "Crypto" + +# PROP Default_Filter "" +# Begin Group "WzAes" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\WzAES\WzAES.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\WzAES\WzAES.h +# End Source File +# End Group +# Begin Group "Hash" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\Hash\HmacSha1.cpp + +!IF "$(CFG)" == "Zip - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Zip - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Hash\HmacSha1.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Hash\Pbkdf2HmacSha1.cpp + +!IF "$(CFG)" == "Zip - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Zip - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Hash\Pbkdf2HmacSha1.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Hash\RandGen.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Hash\RandGen.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Hash\RotateDefs.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Hash\Sha1.cpp + +!IF "$(CFG)" == "Zip - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Zip - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Hash\Sha1.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\Crypto\Zip\ZipCipher.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Zip\ZipCipher.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Zip\ZipCrypto.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Zip\ZipCrypto.h +# End Source File +# End Group +# Begin Group "7z" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\7z\7zMethodID.cpp +# End Source File +# Begin Source File + +SOURCE=..\7z\7zMethodID.h +# End Source File +# Begin Source File + +SOURCE=..\7z\7zMethods.cpp +# End Source File +# Begin Source File + +SOURCE=..\7z\7zMethods.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Group "Shrink" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Shrink\ShrinkDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Shrink\ShrinkDecoder.h +# End Source File +# End Group +# Begin Group "copy" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "Implode" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Implode\ImplodeDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Implode\ImplodeDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Implode\ImplodeHuffmanDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Implode\ImplodeHuffmanDecoder.h +# End Source File +# End Group +# Begin Group "LZ" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.h +# End Source File +# End Group +# End Group +# Begin Source File + +SOURCE=.\zip.ico +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/Archive/Zip/Zip.dsw b/CPP/7zip/Archive/Zip/Zip.dsw new file mode 100755 index 00000000..0a355329 --- /dev/null +++ b/CPP/7zip/Archive/Zip/Zip.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Zip"=.\Zip.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp new file mode 100755 index 00000000..7eb2787f --- /dev/null +++ b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp @@ -0,0 +1,309 @@ +// AddCommon.cpp + +#include "StdAfx.h" + +#include "Common/CRC.h" +#include "Windows/PropVariant.h" +#include "Windows/Defs.h" +#include "../../ICoder.h" +#include "../../IPassword.h" +#include "../Common/InStreamWithCRC.h" +#include "../7z/7zMethods.h" + +#include "ZipAddCommon.h" +#include "ZipHeader.h" + +#ifdef COMPRESS_DEFLATE +#include "../../Compress/Deflate/DeflateEncoder.h" +#else +// {23170F69-40C1-278B-0401-080000000100} +DEFINE_GUID(CLSID_CCompressDeflateEncoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00); +#endif + +#ifdef COMPRESS_DEFLATE64 +#include "../../Compress/Deflate/DeflateEncoder.h" +#else +// {23170F69-40C1-278B-0401-090000000100} +DEFINE_GUID(CLSID_CCompressDeflate64Encoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00); +#endif + +#ifdef COMPRESS_BZIP2 +#include "../../Compress/BZip2/BZip2Encoder.h" +#else +// {23170F69-40C1-278B-0402-020000000100} +DEFINE_GUID(CLSID_CCompressBZip2Encoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00); +#endif + + +#ifdef CRYPTO_ZIP +#include "../../Crypto/Zip/ZipCipher.h" +#else +// {23170F69-40C1-278B-06F1-0101000000100} +DEFINE_GUID(CLSID_CCryptoZipEncoder, +0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00); +#endif + +namespace NArchive { +namespace NZip { + +CAddCommon::CAddCommon(const CCompressionMethodMode &options): + _options(options), + _copyCoderSpec(NULL), + _cryptoStreamSpec(0) + {} + +static HRESULT GetStreamCRC(ISequentialInStream *inStream, UInt32 &resultCRC) +{ + CCRC crc; + crc.Init(); + const UInt32 kBufferSize = (1 << 14); + Byte buffer[kBufferSize]; + for (;;) + { + UInt32 realProcessedSize; + RINOK(inStream->Read(buffer, kBufferSize, &realProcessedSize)); + if(realProcessedSize == 0) + { + resultCRC = crc.GetDigest(); + return S_OK; + } + crc.Update(buffer, realProcessedSize); + } +} + +HRESULT CAddCommon::Compress(ISequentialInStream *inStream, IOutStream *outStream, + ICompressProgressInfo *progress, CCompressingResult &operationResult) +{ + CSequentialInStreamWithCRC *inSecCrcStreamSpec = 0; + CInStreamWithCRC *inCrcStreamSpec = 0; + CMyComPtr inCrcStream; + { + CMyComPtr inStream2; + // we don't support stdin, since stream from stdin can require 64-bit size header + RINOK(inStream->QueryInterface(IID_IInStream, (void **)&inStream2)); + if (inStream2) + { + inCrcStreamSpec = new CInStreamWithCRC; + inCrcStream = inCrcStreamSpec; + inCrcStreamSpec->SetStream(inStream2); + inCrcStreamSpec->Init(); + } + else + { + inSecCrcStreamSpec = new CSequentialInStreamWithCRC; + inCrcStream = inSecCrcStreamSpec; + inSecCrcStreamSpec->SetStream(inStream); + inSecCrcStreamSpec->Init(); + } + } + + int numTestMethods = _options.MethodSequence.Size(); + if (numTestMethods > 1 || _options.PasswordIsDefined) + { + if (inCrcStreamSpec == 0) + { + if (_options.PasswordIsDefined) + return E_NOTIMPL; + numTestMethods = 1; + } + } + Byte method = 0; + COutStreamReleaser outStreamReleaser; + for(int i = 0; i < numTestMethods; i++) + { + if (inCrcStreamSpec != 0) + RINOK(inCrcStreamSpec->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(outStream->Seek(0, STREAM_SEEK_SET, NULL)); + if (_options.PasswordIsDefined) + { + if (!_cryptoStream) + { + _cryptoStreamSpec = new CFilterCoder; + _cryptoStream = _cryptoStreamSpec; + } + if (_options.IsAesMode) + { + _cryptoStreamSpec->Filter = _aesFilter = _filterAesSpec = new NCrypto::NWzAES::CEncoder; + _filterAesSpec->SetKeyMode(_options.AesKeyMode); + RINOK(_filterAesSpec->CryptoSetPassword( + (const Byte *)(const char *)_options.Password, _options.Password.Length())); + RINOK(_filterAesSpec->WriteHeader(outStream)); + } + else + { + _cryptoStreamSpec->Filter = _zipCryptoFilter = _filterSpec = new NCrypto::NZip::CEncoder; + RINOK(_filterSpec->CryptoSetPassword( + (const Byte *)(const char *)_options.Password, _options.Password.Length())); + UInt32 crc = 0; + RINOK(GetStreamCRC(inStream, crc)); + RINOK(inCrcStreamSpec->Seek(0, STREAM_SEEK_SET, NULL)); + RINOK(_filterSpec->CryptoSetCRC(crc)); + RINOK(_filterSpec->WriteHeader(outStream)); + } + RINOK(_cryptoStreamSpec->SetOutStream(outStream)); + outStreamReleaser.FilterCoder = _cryptoStreamSpec; + } + + method = _options.MethodSequence[i]; + switch(method) + { + case NFileHeader::NCompressionMethod::kStored: + { + if(_copyCoderSpec == NULL) + { + _copyCoderSpec = new NCompress::CCopyCoder; + _copyCoder = _copyCoderSpec; + } + CMyComPtr outStreamNew; + if (_options.PasswordIsDefined) + outStreamNew = _cryptoStream; + else + outStreamNew = outStream; + RINOK(_copyCoder->Code(inCrcStream, outStreamNew, NULL, NULL, progress)); + operationResult.ExtractVersion = NFileHeader::NCompressionMethod::kStoreExtractVersion; + break; + } + default: + { + if(!_compressEncoder) + { + // RINOK(m_MatchFinder.CoCreateInstance(CLSID_CMatchFinderBT3)); + #ifndef COMPRESS_DEFLATE + UString methodName; + N7z::LoadMethodMap(); + #endif + switch(method) + { + case NFileHeader::NCompressionMethod::kDeflated: + { + #ifdef COMPRESS_DEFLATE + _compressEncoder = new NCompress::NDeflate::NEncoder::CCOMCoder; + #else + methodName = L"Deflate"; + #endif + break; + } + case NFileHeader::NCompressionMethod::kDeflated64: + { + #ifdef COMPRESS_DEFLATE64 + _compressEncoder = new NCompress::NDeflate::NEncoder::CCOMCoder64; + #else + methodName = L"Deflate64"; + #endif + break; + } + case NFileHeader::NCompressionMethod::kBZip2: + { + #ifdef COMPRESS_BZIP2 + _compressEncoder = new NCompress::NBZip2::CEncoder; + #else + methodName = L"BZip2"; + #endif + break; + } + } + #ifndef COMPRESS_DEFLATE + N7z::CMethodInfo2 methodInfo; + if (!N7z::GetMethodInfo(methodName, methodInfo)) + return E_NOTIMPL; + RINOK(_compressLib.LoadAndCreateCoder( + methodInfo.FilePath, methodInfo.Encoder, &_compressEncoder)); + #endif + + if (method == NFileHeader::NCompressionMethod::kDeflated || + method == NFileHeader::NCompressionMethod::kDeflated64) + { + NWindows::NCOM::CPropVariant properties[] = + { + _options.NumPasses, + _options.NumFastBytes, + _options.NumMatchFinderCycles + }; + PROPID propIDs[] = + { + NCoderPropID::kNumPasses, + NCoderPropID::kNumFastBytes, + NCoderPropID::kMatchFinderCycles + }; + int numProps = sizeof(propIDs) / sizeof(propIDs[0]); + if (!_options.NumMatchFinderCyclesDefined) + numProps--; + CMyComPtr setCoderProperties; + _compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties); + if (setCoderProperties) + { + RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, numProps)); + } + } + else if (method == NFileHeader::NCompressionMethod::kBZip2) + { + NWindows::NCOM::CPropVariant properties[] = + { + _options.DicSize, + _options.NumPasses + #ifdef COMPRESS_MT + , _options.NumThreads + #endif + }; + PROPID propIDs[] = + { + NCoderPropID::kDictionarySize, + NCoderPropID::kNumPasses + #ifdef COMPRESS_MT + , NCoderPropID::kNumThreads + #endif + }; + CMyComPtr setCoderProperties; + _compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties); + if (setCoderProperties) + { + RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, sizeof(propIDs) / sizeof(propIDs[0]))); + } + } + } + CMyComPtr outStreamNew; + if (_options.PasswordIsDefined) + outStreamNew = _cryptoStream; + else + outStreamNew = outStream; + RINOK(_compressEncoder->Code(inCrcStream, outStreamNew, NULL, NULL, progress)); + operationResult.ExtractVersion = NFileHeader::NCompressionMethod::kDeflateExtractVersion; + break; + } + } + + RINOK(outStream->Seek(0, STREAM_SEEK_CUR, &operationResult.PackSize)); + + if (inCrcStreamSpec != 0) + { + operationResult.CRC = inCrcStreamSpec->GetCRC(); + operationResult.UnpackSize = inCrcStreamSpec->GetSize(); + } + else + { + operationResult.CRC = inSecCrcStreamSpec->GetCRC(); + operationResult.UnpackSize = inSecCrcStreamSpec->GetSize(); + } + + if (_options.PasswordIsDefined) + { + if (operationResult.PackSize < operationResult.UnpackSize + + (_options.IsAesMode ? _filterAesSpec->GetHeaderSize() : NCrypto::NZip::kHeaderSize)) + break; + } + else if (operationResult.PackSize < operationResult.UnpackSize) + break; + } + if (_options.IsAesMode) + { + RINOK(_filterAesSpec->WriteFooter(outStream)); + RINOK(outStream->Seek(0, STREAM_SEEK_CUR, &operationResult.PackSize)); + } + operationResult.Method = method; + return outStream->SetSize(operationResult.PackSize); +} + +}} diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.h b/CPP/7zip/Archive/Zip/ZipAddCommon.h new file mode 100755 index 00000000..26cec643 --- /dev/null +++ b/CPP/7zip/Archive/Zip/ZipAddCommon.h @@ -0,0 +1,58 @@ +// Zip/AddCommon.h + +#ifndef __ZIP_ADDCOMMON_H +#define __ZIP_ADDCOMMON_H + +#include "../../ICoder.h" +#include "../../IProgress.h" +#include "../../Compress/Copy/CopyCoder.h" +#ifndef COMPRESS_DEFLATE +#include "../Common/CoderLoader.h" +#endif +#include "../Common/FilterCoder.h" +#include "ZipCompressionMode.h" +#include "../../Crypto/Zip/ZipCipher.h" +#include "../../Crypto/WzAES/WzAES.h" + +namespace NArchive { +namespace NZip { + +struct CCompressingResult +{ + UInt64 UnpackSize; + UInt64 PackSize; + UInt32 CRC; + UInt16 Method; + Byte ExtractVersion; +}; + +class CAddCommon +{ + CCompressionMethodMode _options; + NCompress::CCopyCoder *_copyCoderSpec; + CMyComPtr _copyCoder; + + #ifndef COMPRESS_DEFLATE + CCoderLibrary _compressLib; + #endif + CMyComPtr _compressEncoder; + + CFilterCoder *_cryptoStreamSpec; + CMyComPtr _cryptoStream; + + NCrypto::NZip::CEncoder *_filterSpec; + NCrypto::NWzAES::CEncoder *_filterAesSpec; + + CMyComPtr _zipCryptoFilter; + CMyComPtr _aesFilter; + + +public: + CAddCommon(const CCompressionMethodMode &options); + HRESULT Compress(ISequentialInStream *inStream, IOutStream *outStream, + ICompressProgressInfo *progress, CCompressingResult &operationResult); +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Zip/ZipCompressionMode.h b/CPP/7zip/Archive/Zip/ZipCompressionMode.h new file mode 100755 index 00000000..f1c79918 --- /dev/null +++ b/CPP/7zip/Archive/Zip/ZipCompressionMode.h @@ -0,0 +1,39 @@ +// CompressionMode.h + +#ifndef __ZIP_COMPRESSIONMETHOD_H +#define __ZIP_COMPRESSIONMETHOD_H + +#include "Common/Vector.h" +#include "Common/String.h" + +namespace NArchive { +namespace NZip { + +struct CCompressionMethodMode +{ + CRecordVector MethodSequence; + // bool MaximizeRatio; + UInt32 NumPasses; + UInt32 NumFastBytes; + bool NumMatchFinderCyclesDefined; + UInt32 NumMatchFinderCycles; + UInt32 DicSize; + #ifdef COMPRESS_MT + UInt32 NumThreads; + #endif + bool PasswordIsDefined; + AString Password; + bool IsAesMode; + Byte AesKeyMode; + + CCompressionMethodMode(): + NumMatchFinderCyclesDefined(false), + PasswordIsDefined(false), + IsAesMode(false), + AesKeyMode(3) + {} +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Zip/ZipHandler.cpp b/CPP/7zip/Archive/Zip/ZipHandler.cpp new file mode 100755 index 00000000..4672d768 --- /dev/null +++ b/CPP/7zip/Archive/Zip/ZipHandler.cpp @@ -0,0 +1,766 @@ +// ZipHandler.cpp + +#include "StdAfx.h" + +#include "ZipHandler.h" + +#include "Common/Defs.h" +#include "Common/CRC.h" +#include "Common/StringConvert.h" +#include "Common/ComTry.h" +#include "Common/IntToString.h" + +#include "Windows/Time.h" +#include "Windows/PropVariant.h" + +#include "../../IPassword.h" + +#include "../../Common/ProgressUtils.h" +#include "../../Common/StreamObjects.h" + +#include "../../Compress/Copy/CopyCoder.h" + +#include "../Common/ItemNameUtils.h" +#include "../Common/OutStreamWithCRC.h" +#include "../Common/FilterCoder.h" +#include "../7z/7zMethods.h" + +#include "../../Compress/Shrink/ShrinkDecoder.h" +#include "../../Compress/Implode/ImplodeDecoder.h" + +#ifdef COMPRESS_DEFLATE +#include "../../Compress/Deflate/DeflateDecoder.h" +#else +// {23170F69-40C1-278B-0401-080000000000} +DEFINE_GUID(CLSID_CCompressDeflateDecoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00); +#endif + +#ifdef COMPRESS_DEFLATE64 +#include "../../Compress/Deflate/DeflateDecoder.h" +#else +// {23170F69-40C1-278B-0401-090000000000} +DEFINE_GUID(CLSID_CCompressDeflate64Decoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00); +#endif + +/* +#ifdef COMPRESS_IMPLODE +#else +// {23170F69-40C1-278B-0401-060000000000} +DEFINE_GUID(CLSID_CCompressImplodeDecoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00); +#endif +*/ + +#ifdef COMPRESS_BZIP2 +#include "../../Compress/BZip2/BZip2Decoder.h" +#else +// {23170F69-40C1-278B-0402-020000000000} +DEFINE_GUID(CLSID_CCompressBZip2Decoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00); +#endif + +#include "../../Crypto/Zip/ZipCipher.h" +#include "../../Crypto/WzAES/WzAES.h" + +#ifndef EXCLUDE_COM +#include "../Common/CoderLoader.h" +#endif + +using namespace NWindows; +using namespace NTime; + +namespace NArchive { +namespace NZip { + +const wchar_t *kHostOS[] = +{ + L"FAT", + L"AMIGA", + L"VMS", + L"Unix", + L"VM_CMS", + L"Atari", // what if it's a minix filesystem? [cjh] + L"HPFS", // filesystem used by OS/2 (and NT 3.x) + L"Mac", + L"Z_System", + L"CPM", + L"TOPS20", // pkzip 2.50 NTFS + L"NTFS", // filesystem used by Windows NT + L"QDOS ", // SMS/QDOS + L"Acorn", // Archimedes Acorn RISC OS + L"VFAT", // filesystem used by Windows 95, NT + L"MVS", + L"BeOS", // hybrid POSIX/database filesystem + // BeBOX or PowerMac + L"Tandem", + L"THEOS" +}; + + +static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]); + +static const wchar_t *kUnknownOS = L"Unknown"; + + +/* +enum // PropID +{ + kpidUnPackVersion, +}; +*/ + +STATPROPSTG kProperties[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackedSize, VT_UI8}, + { NULL, kpidLastWriteTime, VT_FILETIME}, + { NULL, kpidAttributes, VT_UI4}, + + { NULL, kpidEncrypted, VT_BOOL}, + { NULL, kpidComment, VT_BSTR}, + + { NULL, kpidCRC, VT_UI4}, + + { NULL, kpidMethod, VT_BSTR}, + { NULL, kpidHostOS, VT_BSTR} + + // { L"UnPack Version", kpidUnPackVersion, VT_UI1}, +}; + +const wchar_t *kMethods[] = +{ + L"Store", + L"Shrink", + L"Reduced1", + L"Reduced2", + L"Reduced2", + L"Reduced3", + L"Implode", + L"Tokenizing", + L"Deflate", + L"Deflate64", + L"PKImploding", + L"Unknown", + L"BZip2" +}; + +const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]); +// const wchar_t *kUnknownMethod = L"Unknown"; +const wchar_t *kPPMdMethod = L"PPMd"; +const wchar_t *kAESMethod = L"AES"; +const wchar_t *kZipCryptoMethod = L"ZipCrypto"; + +CHandler::CHandler(): + m_ArchiveIsOpen(false) +{ + InitMethodProperties(); +} + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) +{ + value->vt = VT_EMPTY; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if(index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &srcItem = kProperties[index]; + *propID = srcItem.propid; + *varType = srcItem.vt; + *name = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +{ + *numProperties = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, + BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = m_Items.Size(); + return S_OK; +} + +static void MyStrNCpy(char *dest, const char *src, int size) +{ + for (int i = 0; i < size; i++) + { + char c = src[i]; + dest[i] = c; + if (c == 0) + break; + } +} + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID aPropID, PROPVARIANT *aValue) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant propVariant; + const CItemEx &item = m_Items[index]; + switch(aPropID) + { + case kpidPath: + propVariant = NItemName::GetOSName2( + MultiByteToUnicodeString(item.Name, item.GetCodePage())); + break; + case kpidIsFolder: + propVariant = item.IsDirectory(); + break; + case kpidSize: + propVariant = item.UnPackSize; + break; + case kpidPackedSize: + propVariant = item.PackSize; + break; + case kpidLastWriteTime: + { + FILETIME aLocalFileTime, anUTCFileTime; + if (DosTimeToFileTime(item.Time, aLocalFileTime)) + { + if (!LocalFileTimeToFileTime(&aLocalFileTime, &anUTCFileTime)) + anUTCFileTime.dwHighDateTime = anUTCFileTime.dwLowDateTime = 0; + } + else + anUTCFileTime.dwHighDateTime = anUTCFileTime.dwLowDateTime = 0; + propVariant = anUTCFileTime; + break; + } + case kpidAttributes: + propVariant = item.GetWinAttributes(); + break; + case kpidEncrypted: + propVariant = item.IsEncrypted(); + break; + case kpidComment: + { + int size = (int)item.Comment.GetCapacity(); + if (size > 0) + { + AString s; + char *p = s.GetBuffer(size + 1); + MyStrNCpy(p, (const char *)(const Byte *)item.Comment, size); + p[size] = '\0'; + s.ReleaseBuffer(); + propVariant = MultiByteToUnicodeString(s, item.GetCodePage()); + } + break; + } + case kpidCRC: + if (item.IsThereCrc()) + propVariant = item.FileCRC; + break; + case kpidMethod: + { + UInt16 methodId = item.CompressionMethod; + UString method; + if (item.IsEncrypted()) + { + if (methodId == NFileHeader::NCompressionMethod::kWzAES) + { + method = kAESMethod; + CWzAesExtraField aesField; + if (item.CentralExtra.GetWzAesField(aesField)) + { + method += L"-"; + wchar_t s[32]; + ConvertUInt64ToString((aesField.Strength + 1) * 64 , s); + method += s; + method += L" "; + methodId = aesField.Method; + } + } + else + { + method += kZipCryptoMethod; + method += L" "; + } + } + if (methodId < kNumMethods) + method += kMethods[methodId]; + else if (methodId == NFileHeader::NCompressionMethod::kWzPPMd) + method += kPPMdMethod; + else + { + wchar_t s[32]; + ConvertUInt64ToString(methodId, s); + method += s; + } + propVariant = method; + break; + } + case kpidHostOS: + propVariant = (item.MadeByVersion.HostOS < kNumHostOSes) ? + (kHostOS[item.MadeByVersion.HostOS]) : kUnknownOS; + break; + } + propVariant.Detach(aValue); + return S_OK; + COM_TRY_END +} + +class CPropgressImp: public CProgressVirt +{ + CMyComPtr m_OpenArchiveCallback; +public: + STDMETHOD(SetCompleted)(const UInt64 *numFiles); + void Init(IArchiveOpenCallback *openArchiveCallback) + { m_OpenArchiveCallback = openArchiveCallback; } +}; + +STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles) +{ + if (m_OpenArchiveCallback) + return m_OpenArchiveCallback->SetCompleted(numFiles, NULL); + return S_OK; +} + +STDMETHODIMP CHandler::Open(IInStream *inStream, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) +{ + COM_TRY_BEGIN + // try + { + if(!m_Archive.Open(inStream, maxCheckStartPosition)) + return S_FALSE; + m_ArchiveIsOpen = true; + m_Items.Clear(); + if (openArchiveCallback != NULL) + { + RINOK(openArchiveCallback->SetTotal(NULL, NULL)); + } + CPropgressImp propgressImp; + propgressImp.Init(openArchiveCallback); + RINOK(m_Archive.ReadHeaders(m_Items, &propgressImp)); + } + /* + catch(...) + { + return S_FALSE; + } + */ + COM_TRY_END + return S_OK; +} + +STDMETHODIMP CHandler::Close() +{ + m_Items.Clear(); + m_Archive.Close(); + m_ArchiveIsOpen = false; + return S_OK; +} + +////////////////////////////////////// +// CHandler::DecompressItems + +struct CMethodItem +{ + UInt16 ZipMethod; + CMyComPtr Coder; +}; + +class CZipDecoder +{ + NCrypto::NZip::CDecoder *_zipCryptoDecoderSpec; + NCrypto::NWzAES::CDecoder *_aesDecoderSpec; + CMyComPtr _zipCryptoDecoder; + CMyComPtr _aesDecoder; + CFilterCoder *filterStreamSpec; + CMyComPtr filterStream; + CMyComPtr getTextPassword; + #ifndef EXCLUDE_COM + CCoderLibraries libraries; + #endif + CObjectVector methodItems; + +public: + CZipDecoder(): _zipCryptoDecoderSpec(0), _aesDecoderSpec(0), filterStreamSpec(0) {} + + static void Init() + { + #ifndef EXCLUDE_COM + N7z::LoadMethodMap(); + #endif + } + + HRESULT Decode(CInArchive &archive, const CItemEx &item, + ISequentialOutStream *realOutStream, + IArchiveExtractCallback *extractCallback, + ICompressProgressInfo *compressProgress, + UInt32 numThreads, Int32 &res); +}; + +HRESULT CZipDecoder::Decode(CInArchive &archive, const CItemEx &item, + ISequentialOutStream *realOutStream, + IArchiveExtractCallback *extractCallback, + ICompressProgressInfo *compressProgress, + UInt32 numThreads, Int32 &res) +{ + res = NArchive::NExtract::NOperationResult::kDataError; + CInStreamReleaser inStreamReleaser; + + bool needCRC = true; + bool aesMode = false; + UInt16 methodId = item.CompressionMethod; + if (item.IsEncrypted()) + if (methodId == NFileHeader::NCompressionMethod::kWzAES) + { + CWzAesExtraField aesField; + if (item.CentralExtra.GetWzAesField(aesField)) + { + aesMode = true; + needCRC = aesField.NeedCrc(); + } + } + + COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;; + CMyComPtr outStream = outStreamSpec; + outStreamSpec->SetStream(realOutStream); + outStreamSpec->Init(needCRC); + + UInt64 authenticationPos; + + CMyComPtr inStream; + { + UInt64 packSize = item.PackSize; + if (aesMode) + { + if (packSize < NCrypto::NWzAES::kMacSize) + return S_OK; + packSize -= NCrypto::NWzAES::kMacSize; + } + UInt64 dataPos = item.GetDataPosition(); + inStream.Attach(archive.CreateLimitedStream(dataPos, packSize)); + authenticationPos = dataPos + packSize; + } + + CMyComPtr cryptoFilter; + if (item.IsEncrypted()) + { + if (aesMode) + { + CWzAesExtraField aesField; + if (!item.CentralExtra.GetWzAesField(aesField)) + return S_OK; + methodId = aesField.Method; + if (!_aesDecoder) + { + _aesDecoderSpec = new NCrypto::NWzAES::CDecoder; + _aesDecoder = _aesDecoderSpec; + } + cryptoFilter = _aesDecoder; + Byte properties = aesField.Strength; + RINOK(_aesDecoderSpec->SetDecoderProperties2(&properties, 1)); + } + else + { + if (!_zipCryptoDecoder) + { + _zipCryptoDecoderSpec = new NCrypto::NZip::CDecoder; + _zipCryptoDecoder = _zipCryptoDecoderSpec; + } + cryptoFilter = _zipCryptoDecoder; + } + CMyComPtr cryptoSetPassword; + RINOK(cryptoFilter.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword)); + + if (!getTextPassword) + extractCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getTextPassword); + + if (getTextPassword) + { + CMyComBSTR password; + RINOK(getTextPassword->CryptoGetTextPassword(&password)); + AString charPassword; + if (aesMode) + { + charPassword = UnicodeStringToMultiByte((const wchar_t *)password, CP_ACP); + /* + for (int i = 0;; i++) + { + wchar_t c = password[i]; + if (c == 0) + break; + if (c >= 0x80) + { + res = NArchive::NExtract::NOperationResult::kDataError; + return S_OK; + } + charPassword += (char)c; + } + */ + } + else + { + // we use OEM. WinZip/Windows probably use ANSI for some files + charPassword = UnicodeStringToMultiByte((const wchar_t *)password, CP_OEMCP); + } + HRESULT res = cryptoSetPassword->CryptoSetPassword( + (const Byte *)(const char *)charPassword, charPassword.Length()); + if (res != S_OK) + return S_OK; + } + else + { + RINOK(cryptoSetPassword->CryptoSetPassword(0, 0)); + } + } + + int m; + for (m = 0; m < methodItems.Size(); m++) + if (methodItems[m].ZipMethod == methodId) + break; + + if (m == methodItems.Size()) + { + CMethodItem mi; + mi.ZipMethod = methodId; + if (methodId == NFileHeader::NCompressionMethod::kStored) + mi.Coder = new NCompress::CCopyCoder; + else if (methodId == NFileHeader::NCompressionMethod::kShrunk) + mi.Coder = new NCompress::NShrink::CDecoder; + else if (methodId == NFileHeader::NCompressionMethod::kImploded) + mi.Coder = new NCompress::NImplode::NDecoder::CCoder; + else + { + #ifdef EXCLUDE_COM + switch(methodId) + { + case NFileHeader::NCompressionMethod::kDeflated: + mi.Coder = new NCompress::NDeflate::NDecoder::CCOMCoder; + break; + case NFileHeader::NCompressionMethod::kDeflated64: + mi.Coder = new NCompress::NDeflate::NDecoder::CCOMCoder64; + break; + case NFileHeader::NCompressionMethod::kBZip2: + mi.Coder = new NCompress::NBZip2::CDecoder; + break; + default: + res = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + return S_OK; + } + #else + N7z::CMethodID methodID = { { 0x04, 0x01 } , 3 }; + if (methodId > 0xFF) + { + res = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + return S_OK; + } + methodID.ID[2] = (Byte)methodId; + if (methodId == NFileHeader::NCompressionMethod::kStored) + { + methodID.ID[0] = 0; + methodID.IDSize = 1; + } + else if (methodId == NFileHeader::NCompressionMethod::kBZip2) + { + methodID.ID[1] = 0x02; + methodID.ID[2] = 0x02; + } + + N7z::CMethodInfo methodInfo; + if (!N7z::GetMethodInfo(methodID, methodInfo)) + { + res = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + return S_OK; + } + RINOK(libraries.CreateCoder(methodInfo.FilePath, methodInfo.Decoder, &mi.Coder)); + #endif + } + m = methodItems.Add(mi); + } + ICompressCoder *coder = methodItems[m].Coder; + + { + CMyComPtr setDecoderProperties; + coder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties); + if (setDecoderProperties) + { + Byte properties = (Byte)item.Flags; + RINOK(setDecoderProperties->SetDecoderProperties2(&properties, 1)); + } + } + + #ifdef COMPRESS_MT + { + CMyComPtr setCoderMt; + coder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt); + if (setCoderMt) + { + RINOK(setCoderMt->SetNumberOfThreads(numThreads)); + } + } + #endif + + { + HRESULT result; + CMyComPtr inStreamNew; + if (item.IsEncrypted()) + { + if (!filterStream) + { + filterStreamSpec = new CFilterCoder; + filterStream = filterStreamSpec; + } + filterStreamSpec->Filter = cryptoFilter; + if (aesMode) + { + RINOK(_aesDecoderSpec->ReadHeader(inStream)); + } + else + { + RINOK(_zipCryptoDecoderSpec->ReadHeader(inStream)); + } + RINOK(filterStreamSpec->SetInStream(inStream)); + inStreamReleaser.FilterCoder = filterStreamSpec; + inStreamNew = filterStream; + + if (aesMode) + { + if (!_aesDecoderSpec->CheckPasswordVerifyCode()) + return S_OK; + } + } + else + inStreamNew = inStream; + result = coder->Code(inStreamNew, outStream, NULL, &item.UnPackSize, compressProgress); + if (result == S_FALSE) + return S_OK; + RINOK(result); + } + bool crcOK = true; + bool authOk = true; + if (needCRC) + crcOK = (outStreamSpec->GetCRC() == item.FileCRC); + if (aesMode) + { + inStream.Attach(archive.CreateLimitedStream(authenticationPos, NCrypto::NWzAES::kMacSize)); + if (_aesDecoderSpec->CheckMac(inStream, authOk) != S_OK) + authOk = false; + } + + res = ((crcOK && authOk) ? + NArchive::NExtract::NOperationResult::kOK : + NArchive::NExtract::NOperationResult::kCRCError); + return S_OK; +} + + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + CZipDecoder myDecoder; + bool testMode = (_aTestMode != 0); + UInt64 totalUnPacked = 0, totalPacked = 0; + bool allFilesMode = (numItems == UInt32(-1)); + if (allFilesMode) + numItems = m_Items.Size(); + if(numItems == 0) + return S_OK; + UInt32 i; + for(i = 0; i < numItems; i++) + { + const CItemEx &item = m_Items[allFilesMode ? i : indices[i]]; + totalUnPacked += item.UnPackSize; + totalPacked += item.PackSize; + } + extractCallback->SetTotal(totalUnPacked); + + UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0; + UInt64 currentItemUnPacked, currentItemPacked; + + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr progress = localProgressSpec; + CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo; + CMyComPtr compressProgress = localCompressProgressSpec; + + CZipDecoder::Init(); + + for (i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked, + currentTotalPacked += currentItemPacked) + { + currentItemUnPacked = 0; + currentItemPacked = 0; + + RINOK(extractCallback->SetCompleted(¤tTotalUnPacked)); + CMyComPtr realOutStream; + Int32 askMode = testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + Int32 index = allFilesMode ? i : indices[i]; + + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + + CItemEx item = m_Items[index]; + if (!item.FromLocal) + { + HRESULT res = m_Archive.ReadLocalItemAfterCdItem(item); + if (res == S_FALSE) + { + if (item.IsDirectory() || realOutStream || testMode) + { + RINOK(extractCallback->PrepareOperation(askMode)); + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + } + continue; + } + RINOK(res); + } + + if (item.IsDirectory() || item.IgnoreItem()) + { + // if (!testMode) + { + RINOK(extractCallback->PrepareOperation(askMode)); + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + } + continue; + } + + currentItemUnPacked = item.UnPackSize; + currentItemPacked = item.PackSize; + + if (!testMode && (!realOutStream)) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)); + + localProgressSpec->Init(extractCallback, false); + localCompressProgressSpec->Init(progress, ¤tTotalPacked, ¤tTotalUnPacked); + + Int32 res; + RINOK(myDecoder.Decode(m_Archive, item, realOutStream, extractCallback, + compressProgress, _numThreads, res)); + realOutStream.Release(); + + RINOK(extractCallback->SetOperationResult(res)) + } + return S_OK; + COM_TRY_END +} + +}} diff --git a/CPP/7zip/Archive/Zip/ZipHandler.h b/CPP/7zip/Archive/Zip/ZipHandler.h new file mode 100755 index 00000000..ea6becd0 --- /dev/null +++ b/CPP/7zip/Archive/Zip/ZipHandler.h @@ -0,0 +1,100 @@ +// Zip/Handler.h + +#ifndef __ZIP_HANDLER_H +#define __ZIP_HANDLER_H + +#include "Common/DynamicBuffer.h" +#include "../../ICoder.h" +#include "../IArchive.h" + +#include "ZipIn.h" +#include "ZipCompressionMode.h" + +#ifdef COMPRESS_MT +#include "../../../Windows/System.h" +#endif + +namespace NArchive { +namespace NZip { + +class CHandler: + public IInArchive, + public IOutArchive, + public ISetProperties, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP3( + IInArchive, + IOutArchive, + ISetProperties + ) + + STDMETHOD(Open)(IInStream *aStream, + const UInt64 *aMaxCheckStartPosition, + IArchiveOpenCallback *anOpenArchiveCallback); + STDMETHOD(Close)(); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *anExtractCallback); + + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + // IOutArchive + STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback); + STDMETHOD(GetFileTimeType)(UInt32 *timeType); + + // ISetProperties + STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties); + + CHandler(); +private: + CObjectVector m_Items; + CInArchive m_Archive; + bool m_ArchiveIsOpen; + + int m_Level; + int m_MainMethod; + UInt32 m_DicSize; + UInt32 m_NumPasses; + UInt32 m_NumFastBytes; + UInt32 m_NumMatchFinderCycles; + bool m_NumMatchFinderCyclesDefined; + + bool m_IsAesMode; + Byte m_AesKeyMode; + + #ifdef COMPRESS_MT + UInt32 _numThreads; + #endif + + void InitMethodProperties() + { + m_Level = -1; + m_MainMethod = -1; + m_DicSize = + m_NumPasses = + m_NumFastBytes = + m_NumMatchFinderCycles = 0xFFFFFFFF; + m_NumMatchFinderCyclesDefined = false; + m_IsAesMode = false; + m_AesKeyMode = 3; // aes-256 + #ifdef COMPRESS_MT + _numThreads = NWindows::NSystem::GetNumberOfProcessors();; + #endif + } +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp new file mode 100755 index 00000000..e2394172 --- /dev/null +++ b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp @@ -0,0 +1,393 @@ +// Zip/HandlerOut.cpp + +#include "StdAfx.h" + +#include "ZipHandler.h" +#include "ZipUpdate.h" + +#include "Common/StringConvert.h" +#include "Common/ComTry.h" +#include "Common/StringToInt.h" + +#include "Windows/PropVariant.h" +#include "Windows/Time.h" + +#include "../../IPassword.h" +#include "../Common/ItemNameUtils.h" +#include "../Common/ParseProperties.h" +#include "../../Crypto/WzAES/WzAES.h" + +using namespace NWindows; +using namespace NCOM; +using namespace NTime; + +namespace NArchive { +namespace NZip { + +static const UInt32 kDeflateNumPassesX1 = 1; +static const UInt32 kDeflateNumPassesX7 = 3; +static const UInt32 kDeflateNumPassesX9 = 10; + +static const UInt32 kNumFastBytesX1 = 32; +static const UInt32 kNumFastBytesX7 = 64; +static const UInt32 kNumFastBytesX9 = 128; + +static const UInt32 kBZip2NumPassesX1 = 1; +static const UInt32 kBZip2NumPassesX7 = 2; +static const UInt32 kBZip2NumPassesX9 = 7; + +static const UInt32 kBZip2DicSizeX1 = 100000; +static const UInt32 kBZip2DicSizeX3 = 500000; +static const UInt32 kBZip2DicSizeX5 = 900000; + +STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType) +{ + *timeType = NFileTimeType::kDOS; + return S_OK; +} + +static bool IsAsciiString(const UString &s) +{ + for (int i = 0; i < s.Length(); i++) + { + wchar_t c = s[i]; + if (c < 0x20 || c > 0x7F) + return false; + } + return true; +} + +STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback) +{ + COM_TRY_BEGIN + CObjectVector updateItems; + for(UInt32 i = 0; i < numItems; i++) + { + CUpdateItem updateItem; + Int32 newData; + Int32 newProperties; + UInt32 indexInArchive; + if (!updateCallback) + return E_FAIL; + RINOK(updateCallback->GetUpdateItemInfo(i, + &newData, // 1 - compress 0 - copy + &newProperties, + &indexInArchive)); + updateItem.NewProperties = IntToBool(newProperties); + updateItem.NewData = IntToBool(newData); + updateItem.IndexInArchive = indexInArchive; + updateItem.IndexInClient = i; + // bool existInArchive = (indexInArchive != UInt32(-1)); + if (IntToBool(newProperties)) + { + FILETIME utcFileTime; + UString name; + bool isDirectoryStatusDefined; + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant)); + if (propVariant.vt == VT_EMPTY) + updateItem.Attributes = 0; + else if (propVariant.vt != VT_UI4) + return E_INVALIDARG; + else + updateItem.Attributes = propVariant.ulVal; + } + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(i, kpidLastWriteTime, &propVariant)); + if (propVariant.vt != VT_FILETIME) + return E_INVALIDARG; + utcFileTime = propVariant.filetime; + } + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(i, kpidPath, &propVariant)); + if (propVariant.vt == VT_EMPTY) + name.Empty(); + else if (propVariant.vt != VT_BSTR) + return E_INVALIDARG; + else + name = propVariant.bstrVal; + } + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(i, kpidIsFolder, &propVariant)); + if (propVariant.vt == VT_EMPTY) + isDirectoryStatusDefined = false; + else if (propVariant.vt != VT_BOOL) + return E_INVALIDARG; + else + { + updateItem.IsDirectory = (propVariant.boolVal != VARIANT_FALSE); + isDirectoryStatusDefined = true; + } + } + FILETIME localFileTime; + if(!FileTimeToLocalFileTime(&utcFileTime, &localFileTime)) + return E_INVALIDARG; + if(!FileTimeToDosTime(localFileTime, updateItem.Time)) + { + // return E_INVALIDARG; + } + + if (!isDirectoryStatusDefined) + updateItem.IsDirectory = ((updateItem.Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); + + name = NItemName::MakeLegalName(name); + bool needSlash = updateItem.IsDirectory; + const wchar_t kSlash = L'/'; + if (!name.IsEmpty()) + { + if (name[name.Length() - 1] == kSlash) + { + if (!updateItem.IsDirectory) + return E_INVALIDARG; + needSlash = false; + } + } + if (needSlash) + name += kSlash; + updateItem.Name = UnicodeStringToMultiByte(name, CP_OEMCP); + if (updateItem.Name.Length() > 0xFFFF) + return E_INVALIDARG; + + updateItem.IndexInClient = i; + /* + if(existInArchive) + { + const CItemEx &itemInfo = m_Items[indexInArchive]; + // updateItem.Commented = itemInfo.IsCommented(); + updateItem.Commented = false; + if(updateItem.Commented) + { + updateItem.CommentRange.Position = itemInfo.GetCommentPosition(); + updateItem.CommentRange.Size = itemInfo.CommentSize; + } + } + else + updateItem.Commented = false; + */ + } + if (IntToBool(newData)) + { + UInt64 size; + { + NCOM::CPropVariant propVariant; + RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant)); + if (propVariant.vt != VT_UI8) + return E_INVALIDARG; + size = propVariant.uhVal.QuadPart; + } + updateItem.Size = size; + } + updateItems.Add(updateItem); + } + + CMyComPtr getTextPassword; + if (!getTextPassword) + { + CMyComPtr udateCallBack2(updateCallback); + udateCallBack2.QueryInterface(IID_ICryptoGetTextPassword2, &getTextPassword); + } + CCompressionMethodMode options; + + if (getTextPassword) + { + CMyComBSTR password; + Int32 passwordIsDefined; + RINOK(getTextPassword->CryptoGetTextPassword2(&passwordIsDefined, &password)); + options.PasswordIsDefined = IntToBool(passwordIsDefined); + if (options.PasswordIsDefined) + { + if (!IsAsciiString((const wchar_t *)password)) + return E_INVALIDARG; + if (m_IsAesMode) + { + if (options.Password.Length() > NCrypto::NWzAES::kPasswordSizeMax) + return E_INVALIDARG; + } + options.Password = UnicodeStringToMultiByte((const wchar_t *)password, CP_OEMCP); + options.IsAesMode = m_IsAesMode; + options.AesKeyMode = m_AesKeyMode; + } + } + else + options.PasswordIsDefined = false; + + int level = m_Level; + if (level < 0) + level = 5; + + Byte mainMethod; + if (m_MainMethod < 0) + mainMethod = (Byte)(((level == 0) ? + NFileHeader::NCompressionMethod::kStored : + NFileHeader::NCompressionMethod::kDeflated)); + else + mainMethod = (Byte)m_MainMethod; + options.MethodSequence.Add(mainMethod); + if (mainMethod != NFileHeader::NCompressionMethod::kStored) + options.MethodSequence.Add(NFileHeader::NCompressionMethod::kStored); + bool isDeflate = (mainMethod == NFileHeader::NCompressionMethod::kDeflated) || + (mainMethod == NFileHeader::NCompressionMethod::kDeflated64); + bool isBZip2 = (mainMethod == NFileHeader::NCompressionMethod::kBZip2); + options.NumPasses = m_NumPasses; + options.DicSize = m_DicSize; + options.NumFastBytes = m_NumFastBytes; + options.NumMatchFinderCycles = m_NumMatchFinderCycles; + options.NumMatchFinderCyclesDefined = m_NumMatchFinderCyclesDefined; + #ifdef COMPRESS_MT + options.NumThreads = _numThreads; + #endif + if (isDeflate) + { + if (options.NumPasses == 0xFFFFFFFF) + options.NumPasses = (level >= 9 ? kDeflateNumPassesX9 : + (level >= 7 ? kDeflateNumPassesX7 : + kDeflateNumPassesX1)); + if (options.NumFastBytes == 0xFFFFFFFF) + options.NumFastBytes = (level >= 9 ? kNumFastBytesX9 : + (level >= 7 ? kNumFastBytesX7 : + kNumFastBytesX1)); + } + if (isBZip2) + { + if (options.NumPasses == 0xFFFFFFFF) + options.NumPasses = (level >= 9 ? kBZip2NumPassesX9 : + (level >= 7 ? kBZip2NumPassesX7 : + kBZip2NumPassesX1)); + if (options.DicSize == 0xFFFFFFFF) + options.DicSize = (level >= 5 ? kBZip2DicSizeX5 : + (level >= 3 ? kBZip2DicSizeX3 : + kBZip2DicSizeX1)); + } + + return Update(m_Items, updateItems, outStream, + m_ArchiveIsOpen ? &m_Archive : NULL, &options, updateCallback); + COM_TRY_END +} + +STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) +{ + #ifdef COMPRESS_MT + const UInt32 numProcessors = NSystem::GetNumberOfProcessors(); + _numThreads = numProcessors; + #endif + InitMethodProperties(); + for (int i = 0; i < numProperties; i++) + { + UString name = UString(names[i]); + name.MakeUpper(); + if (name.IsEmpty()) + return E_INVALIDARG; + + const PROPVARIANT &prop = values[i]; + + if (name[0] == L'X') + { + UInt32 level = 9; + RINOK(ParsePropValue(name.Mid(1), prop, level)); + m_Level = level; + continue; + } + else if (name == L"M") + { + if (prop.vt == VT_BSTR) + { + UString valueString = prop.bstrVal; + valueString.MakeUpper(); + if (valueString == L"COPY") + m_MainMethod = NFileHeader::NCompressionMethod::kStored; + else if (valueString == L"DEFLATE") + m_MainMethod = NFileHeader::NCompressionMethod::kDeflated; + else if (valueString == L"DEFLATE64") + m_MainMethod = NFileHeader::NCompressionMethod::kDeflated64; + else if (valueString == L"BZIP2") + m_MainMethod = NFileHeader::NCompressionMethod::kBZip2; + else + return E_INVALIDARG; + } + else if (prop.vt == VT_UI4) + { + switch(prop.ulVal) + { + case NFileHeader::NCompressionMethod::kStored: + case NFileHeader::NCompressionMethod::kDeflated: + case NFileHeader::NCompressionMethod::kDeflated64: + case NFileHeader::NCompressionMethod::kBZip2: + m_MainMethod = (Byte)prop.ulVal; + break; + default: + return E_INVALIDARG; + } + } + else + return E_INVALIDARG; + } + else if (name.Left(2) == L"EM") + { + if (prop.vt == VT_BSTR) + { + UString valueString = prop.bstrVal; + valueString.MakeUpper(); + if (valueString.Left(3) == L"AES") + { + valueString = valueString.Mid(3); + if (valueString == L"128") + m_AesKeyMode = 1; + else if (valueString == L"192") + m_AesKeyMode = 2; + else if (valueString == L"256" || valueString.IsEmpty()) + m_AesKeyMode = 3; + else + return E_INVALIDARG; + m_IsAesMode = true; + } + else if (valueString == L"ZIPCRYPTO") + m_IsAesMode = false; + else + return E_INVALIDARG; + } + else + return E_INVALIDARG; + } + else if (name[0] == L'D') + { + UInt32 dicSize = kBZip2DicSizeX5; + RINOK(ParsePropDictionaryValue(name.Mid(1), prop, dicSize)); + m_DicSize = dicSize; + } + else if (name.Left(4) == L"PASS") + { + UInt32 num = kDeflateNumPassesX9; + RINOK(ParsePropValue(name.Mid(4), prop, num)); + m_NumPasses = num; + } + else if (name.Left(2) == L"FB") + { + UInt32 num = kNumFastBytesX9; + RINOK(ParsePropValue(name.Mid(2), prop, num)); + m_NumFastBytes = num; + } + else if (name.Left(2) == L"MC") + { + UInt32 num = 0xFFFFFFFF; + RINOK(ParsePropValue(name.Mid(2), prop, num)); + m_NumMatchFinderCycles = num; + m_NumMatchFinderCyclesDefined = true; + } + else if (name.Left(2) == L"MT") + { + #ifdef COMPRESS_MT + RINOK(ParseMtProp(name.Mid(2), prop, numProcessors, _numThreads)); + #endif + } + else + return E_INVALIDARG; + } + return S_OK; +} + +}} diff --git a/CPP/7zip/Archive/Zip/ZipHeader.cpp b/CPP/7zip/Archive/Zip/ZipHeader.cpp new file mode 100755 index 00000000..fd8856bb --- /dev/null +++ b/CPP/7zip/Archive/Zip/ZipHeader.cpp @@ -0,0 +1,36 @@ +// Archive/Zip/Header.h + +#include "StdAfx.h" + +#include "ZipHeader.h" + +namespace NArchive { +namespace NZip { + +namespace NSignature +{ + UInt32 kLocalFileHeader = 0x04034B50 + 1; + UInt32 kDataDescriptor = 0x08074B50 + 1; + UInt32 kCentralFileHeader = 0x02014B50 + 1; + UInt32 kEndOfCentralDir = 0x06054B50 + 1; + UInt32 kZip64EndOfCentralDir = 0x06064B50 + 1; + UInt32 kZip64EndOfCentralDirLocator = 0x07064B50 + 1; + + class CMarkersInitializer + { + public: + CMarkersInitializer() + { + kLocalFileHeader--; + kDataDescriptor--; + kCentralFileHeader--; + kEndOfCentralDir--; + kZip64EndOfCentralDir--; + kZip64EndOfCentralDirLocator--; + } + }; + static CMarkersInitializer g_MarkerInitializer; +} + +}} + diff --git a/CPP/7zip/Archive/Zip/ZipHeader.h b/CPP/7zip/Archive/Zip/ZipHeader.h new file mode 100755 index 00000000..ac98ea76 --- /dev/null +++ b/CPP/7zip/Archive/Zip/ZipHeader.h @@ -0,0 +1,248 @@ +// Archive/Zip/Header.h + +#ifndef __ARCHIVE_ZIP_HEADER_H +#define __ARCHIVE_ZIP_HEADER_H + +#include "Common/Types.h" + +namespace NArchive { +namespace NZip { + +namespace NSignature +{ + extern UInt32 kLocalFileHeader; + extern UInt32 kDataDescriptor; + extern UInt32 kCentralFileHeader; + extern UInt32 kEndOfCentralDir; + extern UInt32 kZip64EndOfCentralDir; + extern UInt32 kZip64EndOfCentralDirLocator; + + static const UInt32 kMarkerSize = 4; +} + +const UInt32 kEcdSize = 22; +const UInt32 kZip64EcdSize = 44; +const UInt32 kZip64EcdLocatorSize = 20; +/* +struct CEndOfCentralDirectoryRecord +{ + UInt16 ThisDiskNumber; + UInt16 StartCentralDirectoryDiskNumber; + UInt16 NumEntriesInCentaralDirectoryOnThisDisk; + UInt16 NumEntriesInCentaralDirectory; + UInt32 CentralDirectorySize; + UInt32 CentralDirectoryStartOffset; + UInt16 CommentSize; +}; + +struct CEndOfCentralDirectoryRecordFull +{ + UInt32 Signature; + CEndOfCentralDirectoryRecord Header; +}; +*/ + +namespace NFileHeader +{ + /* + struct CVersion + { + Byte Version; + Byte HostOS; + }; + */ + + namespace NCompressionMethod + { + enum EType + { + kStored = 0, + kShrunk = 1, + kReduced1 = 2, + kReduced2 = 3, + kReduced3 = 4, + kReduced4 = 5, + kImploded = 6, + kReservedTokenizing = 7, // reserved for tokenizing + kDeflated = 8, + kDeflated64 = 9, + kPKImploding = 10, + + kBZip2 = 12, + kWzPPMd = 0x62, + kWzAES = 0x63 + }; + const int kNumCompressionMethods = 11; + const Byte kMadeByProgramVersion = 20; + + const Byte kDeflateExtractVersion = 20; + const Byte kStoreExtractVersion = 10; + + const Byte kSupportedVersion = 20; + } + + namespace NExtraID + { + enum + { + kZip64 = 0x01, + kWzAES = 0x9901 + }; + } + + const UInt32 kLocalBlockSize = 26; + /* + struct CLocalBlock + { + CVersion ExtractVersion; + + UInt16 Flags; + UInt16 CompressionMethod; + UInt32 Time; + UInt32 FileCRC; + UInt32 PackSize; + UInt32 UnPackSize; + UInt16 NameSize; + UInt16 ExtraSize; + }; + */ + + const UInt32 kDataDescriptorSize = 16; + /* + struct CDataDescriptor + { + UInt32 Signature; + UInt32 FileCRC; + UInt32 PackSize; + UInt32 UnPackSize; + }; + + struct CLocalBlockFull + { + UInt32 Signature; + CLocalBlock Header; + }; + */ + + const UInt32 kCentralBlockSize = 42; + /* + struct CBlock + { + CVersion MadeByVersion; + CVersion ExtractVersion; + UInt16 Flags; + UInt16 CompressionMethod; + UInt32 Time; + UInt32 FileCRC; + UInt32 PackSize; + UInt32 UnPackSize; + UInt16 NameSize; + UInt16 ExtraSize; + UInt16 CommentSize; + UInt16 DiskNumberStart; + UInt16 InternalAttributes; + UInt32 ExternalAttributes; + UInt32 LocalHeaderOffset; + }; + + struct CBlockFull + { + UInt32 Signature; + CBlock Header; + }; + */ + + namespace NFlags + { + const int kNumUsedBits = 4; + const int kUsedBitsMask = (1 << kNumUsedBits) - 1; + + const int kEncryptedMask = 1 << 0; + const int kDescriptorUsedMask = 1 << 3; + + const int kImplodeDictionarySizeMask = 1 << 1; + const int kImplodeLiteralsOnMask = 1 << 2; + + const int kDeflateTypeBitStart = 1; + const int kNumDeflateTypeBits = 2; + const int kNumDeflateTypes = (1 << kNumDeflateTypeBits); + const int kDeflateTypeMask = (1 << kNumDeflateTypeBits) - 1; + } + + namespace NHostOS + { + enum EEnum + { + kFAT = 0, // filesystem used by MS-DOS, OS/2, Win32 + // pkzip 2.50 (FAT / VFAT / FAT32 file systems) + kAMIGA = 1, + kVMS = 2, // VAX/VMS + kUnix = 3, + kVM_CMS = 4, + kAtari = 5, // what if it's a minix filesystem? [cjh] + kHPFS = 6, // filesystem used by OS/2 (and NT 3.x) + kMac = 7, + kZ_System = 8, + kCPM = 9, + kTOPS20 = 10, // pkzip 2.50 NTFS + kNTFS = 11, // filesystem used by Windows NT + kQDOS = 12, // SMS/QDOS + kAcorn = 13, // Archimedes Acorn RISC OS + kVFAT = 14, // filesystem used by Windows 95, NT + kMVS = 15, + kBeOS = 16, // hybrid POSIX/database filesystem + // BeBOX or PowerMac + kTandem = 17, + kTHEOS = 18 + }; + // const int kNumHostSystems = 19; + } + namespace NUnixAttribute + { + const UInt32 kIFMT = 0170000; /* Unix file type mask */ + + const UInt32 kIFDIR = 0040000; /* Unix directory */ + const UInt32 kIFREG = 0100000; /* Unix regular file */ + const UInt32 kIFSOCK = 0140000; /* Unix socket (BSD, not SysV or Amiga) */ + const UInt32 kIFLNK = 0120000; /* Unix symbolic link (not SysV, Amiga) */ + const UInt32 kIFBLK = 0060000; /* Unix block special (not Amiga) */ + const UInt32 kIFCHR = 0020000; /* Unix character special (not Amiga) */ + const UInt32 kIFIFO = 0010000; /* Unix fifo (BCC, not MSC or Amiga) */ + + const UInt32 kISUID = 04000; /* Unix set user id on execution */ + const UInt32 kISGID = 02000; /* Unix set group id on execution */ + const UInt32 kISVTX = 01000; /* Unix directory permissions control */ + const UInt32 kENFMT = kISGID; /* Unix record locking enforcement flag */ + const UInt32 kIRWXU = 00700; /* Unix read, write, execute: owner */ + const UInt32 kIRUSR = 00400; /* Unix read permission: owner */ + const UInt32 kIWUSR = 00200; /* Unix write permission: owner */ + const UInt32 kIXUSR = 00100; /* Unix execute permission: owner */ + const UInt32 kIRWXG = 00070; /* Unix read, write, execute: group */ + const UInt32 kIRGRP = 00040; /* Unix read permission: group */ + const UInt32 kIWGRP = 00020; /* Unix write permission: group */ + const UInt32 kIXGRP = 00010; /* Unix execute permission: group */ + const UInt32 kIRWXO = 00007; /* Unix read, write, execute: other */ + const UInt32 kIROTH = 00004; /* Unix read permission: other */ + const UInt32 kIWOTH = 00002; /* Unix write permission: other */ + const UInt32 kIXOTH = 00001; /* Unix execute permission: other */ + } + + namespace NAmigaAttribute + { + const UInt32 kIFMT = 06000; /* Amiga file type mask */ + const UInt32 kIFDIR = 04000; /* Amiga directory */ + const UInt32 kIFREG = 02000; /* Amiga regular file */ + const UInt32 kIHIDDEN = 00200; /* to be supported in AmigaDOS 3.x */ + const UInt32 kISCRIPT = 00100; /* executable script (text command file) */ + const UInt32 kIPURE = 00040; /* allow loading into resident memory */ + const UInt32 kIARCHIVE = 00020; /* not modified since bit was last set */ + const UInt32 kIREAD = 00010; /* can be opened for reading */ + const UInt32 kIWRITE = 00004; /* can be opened for writing */ + const UInt32 kIEXECUTE = 00002; /* executable image, a loadable runfile */ + const UInt32 kIDELETE = 00001; /* can be deleted */ + } +} + +}} + +#endif diff --git a/CPP/7zip/Archive/Zip/ZipIn.cpp b/CPP/7zip/Archive/Zip/ZipIn.cpp new file mode 100755 index 00000000..c9e3a7d1 --- /dev/null +++ b/CPP/7zip/Archive/Zip/ZipIn.cpp @@ -0,0 +1,797 @@ +// Archive/ZipIn.cpp + +#include "StdAfx.h" + +#include "ZipIn.h" +#include "Windows/Defs.h" +#include "Common/StringConvert.h" +#include "Common/DynamicBuffer.h" +#include "../../Common/LimitedStreams.h" +#include "../../Common/StreamUtils.h" + +namespace NArchive { +namespace NZip { + +// static const char kEndOfString = '\0'; + +bool CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit) +{ + m_Stream = inStream; + if(m_Stream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition) != S_OK) + return false; + m_Position = m_StreamStartPosition; + return FindAndReadMarker(searchHeaderSizeLimit); +} + +void CInArchive::Close() +{ + m_Stream.Release(); +} + +HRESULT CInArchive::Seek(UInt64 offset) +{ + return m_Stream->Seek(offset, STREAM_SEEK_SET, NULL); +} + +////////////////////////////////////// +// Markers + +static inline bool TestMarkerCandidate(const Byte *p, UInt32 &value) +{ + value = p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24); + return (value == NSignature::kLocalFileHeader) || + (value == NSignature::kEndOfCentralDir); +} + +bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit) +{ + m_ArchiveInfo.Clear(); + m_Position = m_StreamStartPosition; + if(Seek(m_StreamStartPosition) != S_OK) + return false; + + Byte marker[NSignature::kMarkerSize]; + UInt32 processedSize; + ReadBytes(marker, NSignature::kMarkerSize, &processedSize); + if(processedSize != NSignature::kMarkerSize) + return false; + if (TestMarkerCandidate(marker, m_Signature)) + return true; + + CByteDynamicBuffer dynamicBuffer; + static const UInt32 kSearchMarkerBufferSize = 0x10000; + dynamicBuffer.EnsureCapacity(kSearchMarkerBufferSize); + Byte *buffer = dynamicBuffer; + UInt32 numBytesPrev = NSignature::kMarkerSize - 1; + memmove(buffer, marker + 1, numBytesPrev); + UInt64 curTestPos = m_StreamStartPosition + 1; + for (;;) + { + if (searchHeaderSizeLimit != NULL) + if (curTestPos - m_StreamStartPosition > *searchHeaderSizeLimit) + break; + UInt32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev; + ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize); + UInt32 numBytesInBuffer = numBytesPrev + processedSize; + if (numBytesInBuffer < NSignature::kMarkerSize) + break; + UInt32 numTests = numBytesInBuffer - NSignature::kMarkerSize + 1; + for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++) + { + if (TestMarkerCandidate(buffer + pos, m_Signature)) + { + m_ArchiveInfo.StartPosition = curTestPos; + // m_ArchiveInfo.Base = m_ArchiveInfo.StartPosition; + // m_ArchiveInfo.Base = 0; + m_Position = curTestPos + NSignature::kMarkerSize; + if(Seek(m_Position) != S_OK) + return false; + return true; + } + } + numBytesPrev = numBytesInBuffer - numTests; + memmove(buffer, buffer + numTests, numBytesPrev); + } + return false; +} + +HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize; + HRESULT result = ReadStream(m_Stream, data, size, &realProcessedSize); + if(processedSize != NULL) + *processedSize = realProcessedSize; + m_Position += realProcessedSize; + return result; +} + +void CInArchive::IncreaseRealPosition(UInt64 addValue) +{ + if(m_Stream->Seek(addValue, STREAM_SEEK_CUR, &m_Position) != S_OK) + throw CInArchiveException(CInArchiveException::kSeekStreamError); +} + +bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size) +{ + UInt32 realProcessedSize; + if(ReadBytes(data, size, &realProcessedSize) != S_OK) + throw CInArchiveException(CInArchiveException::kReadStreamError); + return (realProcessedSize == size); +} + +void CInArchive::SafeReadBytes(void *data, UInt32 size) +{ + if(!ReadBytesAndTestSize(data, size)) + throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); +} + +void CInArchive::ReadBuffer(CByteBuffer &buffer, UInt32 size) +{ + buffer.SetCapacity(size); + if (size > 0) + SafeReadBytes(buffer, size); +} + +Byte CInArchive::ReadByte() +{ + Byte b; + SafeReadBytes(&b, 1); + return b; +} + +UInt16 CInArchive::ReadUInt16() +{ + UInt16 value = 0; + for (int i = 0; i < 2; i++) + value |= (((UInt16)ReadByte()) << (8 * i)); + return value; +} + +UInt32 CInArchive::ReadUInt32() +{ + UInt32 value = 0; + for (int i = 0; i < 4; i++) + value |= (((UInt32)ReadByte()) << (8 * i)); + return value; +} + +UInt64 CInArchive::ReadUInt64() +{ + UInt64 value = 0; + for (int i = 0; i < 8; i++) + value |= (((UInt64)ReadByte()) << (8 * i)); + return value; +} + +bool CInArchive::ReadUInt32(UInt32 &value) +{ + value = 0; + for (int i = 0; i < 4; i++) + { + Byte b; + if (!ReadBytesAndTestSize(&b, 1)) + return false; + value |= (UInt32(b) << (8 * i)); + } + return true; +} + + +AString CInArchive::ReadFileName(UInt32 nameSize) +{ + if (nameSize == 0) + return AString(); + SafeReadBytes(m_NameBuffer.GetBuffer(nameSize), nameSize); + m_NameBuffer.ReleaseBuffer(nameSize); + return m_NameBuffer; +} + +void CInArchive::GetArchiveInfo(CInArchiveInfo &archiveInfo) const +{ + archiveInfo = m_ArchiveInfo; +} + +/* +void CInArchive::ThrowIncorrectArchiveException() +{ + throw CInArchiveException(CInArchiveException::kIncorrectArchive); +} +*/ + +static UInt32 GetUInt32(const Byte *data) +{ + return + ((UInt32)(Byte)data[0]) | + (((UInt32)(Byte)data[1]) << 8) | + (((UInt32)(Byte)data[2]) << 16) | + (((UInt32)(Byte)data[3]) << 24); +} + +/* +static UInt16 GetUInt16(const Byte *data) +{ + return + ((UInt16)(Byte)data[0]) | + (((UInt16)(Byte)data[1]) << 8); +} +*/ + +static UInt64 GetUInt64(const Byte *data) +{ + return GetUInt32(data) | ((UInt64)GetUInt32(data + 4) << 32); +} + + + +void CInArchive::ReadExtra(UInt32 extraSize, CExtraBlock &extraBlock, + UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber) +{ + extraBlock.Clear(); + UInt32 remain = extraSize; + while(remain >= 4) + { + CExtraSubBlock subBlock; + subBlock.ID = ReadUInt16(); + UInt32 dataSize = ReadUInt16(); + remain -= 4; + if (dataSize > remain) // it's bug + dataSize = remain; + if (subBlock.ID == NFileHeader::NExtraID::kZip64) + { + if (unpackSize == 0xFFFFFFFF) + { + if (dataSize < 8) + break; + unpackSize = ReadUInt64(); + remain -= 8; + dataSize -= 8; + } + if (packSize == 0xFFFFFFFF) + { + if (dataSize < 8) + break; + packSize = ReadUInt64(); + remain -= 8; + dataSize -= 8; + } + if (localHeaderOffset == 0xFFFFFFFF) + { + if (dataSize < 8) + break; + localHeaderOffset = ReadUInt64(); + remain -= 8; + dataSize -= 8; + } + if (diskStartNumber == 0xFFFF) + { + if (dataSize < 4) + break; + diskStartNumber = ReadUInt32(); + remain -= 4; + dataSize -= 4; + } + for (UInt32 i = 0; i < dataSize; i++) + ReadByte(); + } + else + { + ReadBuffer(subBlock.Data, dataSize); + extraBlock.SubBlocks.Add(subBlock); + } + remain -= dataSize; + } + IncreaseRealPosition(remain); +} + +HRESULT CInArchive::ReadLocalItem(CItemEx &item) +{ + item.ExtractVersion.Version = ReadByte(); + item.ExtractVersion.HostOS = ReadByte(); + item.Flags = ReadUInt16(); // & NFileHeader::NFlags::kUsedBitsMask; + item.CompressionMethod = ReadUInt16(); + item.Time = ReadUInt32(); + item.FileCRC = ReadUInt32(); + item.PackSize = ReadUInt32(); + item.UnPackSize = ReadUInt32(); + UInt32 fileNameSize = ReadUInt16(); + item.LocalExtraSize = ReadUInt16(); + item.Name = ReadFileName(fileNameSize); + item.FileHeaderWithNameSize = 4 + NFileHeader::kLocalBlockSize + fileNameSize; + if (item.LocalExtraSize > 0) + { + UInt64 localHeaderOffset = 0; + UInt32 diskStartNumber = 0; + ReadExtra(item.LocalExtraSize, item.LocalExtra, item.UnPackSize, item.PackSize, + localHeaderOffset, diskStartNumber); + } + /* + if (item.IsDirectory()) + item.UnPackSize = 0; // check It + */ + return S_OK; +} + +HRESULT CInArchive::ReadLocalItemAfterCdItem(CItemEx &item) +{ + if (item.FromLocal) + return S_OK; + try + { + RINOK(Seek(m_ArchiveInfo.Base + item.LocalHeaderPosition)); + CItemEx localItem; + if (ReadUInt32() != NSignature::kLocalFileHeader) + return S_FALSE; + RINOK(ReadLocalItem(localItem)); + if (item.Flags != localItem.Flags) + { + if (item.CompressionMethod != NFileHeader::NCompressionMethod::kDeflated || + (item.Flags & 0xFFFC) != (localItem.Flags & 0xFFFC)) + return S_FALSE; + } + + if (item.CompressionMethod != localItem.CompressionMethod || + // item.Time != localItem.Time || + (!localItem.HasDescriptor() && + ( + item.FileCRC != localItem.FileCRC || + item.PackSize != localItem.PackSize || + item.UnPackSize != localItem.UnPackSize + ) + ) || + item.Name.Length() != localItem.Name.Length() + ) + return S_FALSE; + item.FileHeaderWithNameSize = localItem.FileHeaderWithNameSize; + item.LocalExtraSize = localItem.LocalExtraSize; + item.LocalExtra = localItem.LocalExtra; + item.FromLocal = true; + } + catch(...) { return S_FALSE; } + return S_OK; +} + +HRESULT CInArchive::ReadLocalItemDescriptor(CItemEx &item) +{ + if (item.HasDescriptor()) + { + const int kBufferSize = (1 << 12); + Byte buffer[kBufferSize]; + + UInt32 numBytesInBuffer = 0; + UInt32 packedSize = 0; + + bool descriptorWasFound = false; + for (;;) + { + UInt32 processedSize; + RINOK(ReadBytes(buffer + numBytesInBuffer, kBufferSize - numBytesInBuffer, &processedSize)); + numBytesInBuffer += processedSize; + if (numBytesInBuffer < NFileHeader::kDataDescriptorSize) + return S_FALSE; + UInt32 i; + for (i = 0; i <= numBytesInBuffer - NFileHeader::kDataDescriptorSize; i++) + { + // descriptorSignature field is Info-ZIP's extension + // to Zip specification. + UInt32 descriptorSignature = GetUInt32(buffer + i); + + // !!!! It must be fixed for Zip64 archives + UInt32 descriptorPackSize = GetUInt32(buffer + i + 8); + if (descriptorSignature== NSignature::kDataDescriptor && descriptorPackSize == packedSize + i) + { + descriptorWasFound = true; + item.FileCRC = GetUInt32(buffer + i + 4); + item.PackSize = descriptorPackSize; + item.UnPackSize = GetUInt32(buffer + i + 12); + IncreaseRealPosition(Int64(Int32(0 - (numBytesInBuffer - i - NFileHeader::kDataDescriptorSize)))); + break; + } + } + if (descriptorWasFound) + break; + packedSize += i; + int j; + for (j = 0; i < numBytesInBuffer; i++, j++) + buffer[j] = buffer[i]; + numBytesInBuffer = j; + } + } + else + IncreaseRealPosition(item.PackSize); + return S_OK; +} + +HRESULT CInArchive::ReadLocalItemAfterCdItemFull(CItemEx &item) +{ + if (item.FromLocal) + return S_OK; + try + { + RINOK(ReadLocalItemAfterCdItem(item)); + if (item.HasDescriptor()) + { + RINOK(Seek(m_ArchiveInfo.Base + item.GetDataPosition() + item.PackSize)); + if (ReadUInt32() != NSignature::kDataDescriptor) + return S_FALSE; + UInt32 crc = ReadUInt32(); + UInt32 packSize = ReadUInt32(); + UInt32 unpackSize = ReadUInt32(); + if (crc != item.FileCRC || item.PackSize != packSize || item.UnPackSize != unpackSize) + return S_FALSE; + } + } + catch(...) { return S_FALSE; } + return S_OK; +} + +HRESULT CInArchive::ReadCdItem(CItemEx &item) +{ + item.FromCentral = true; + item.MadeByVersion.Version = ReadByte(); + item.MadeByVersion.HostOS = ReadByte(); + item.ExtractVersion.Version = ReadByte(); + item.ExtractVersion.HostOS = ReadByte(); + item.Flags = ReadUInt16(); // & NFileHeader::NFlags::kUsedBitsMask; + item.CompressionMethod = ReadUInt16(); + item.Time = ReadUInt32(); + item.FileCRC = ReadUInt32(); + item.PackSize = ReadUInt32(); + item.UnPackSize = ReadUInt32(); + UInt16 headerNameSize = ReadUInt16(); + UInt16 headerExtraSize = ReadUInt16(); + UInt16 headerCommentSize = ReadUInt16(); + UInt32 headerDiskNumberStart = ReadUInt16(); + item.InternalAttributes = ReadUInt16(); + item.ExternalAttributes = ReadUInt32(); + item.LocalHeaderPosition = ReadUInt32(); + item.Name = ReadFileName(headerNameSize); + + if (headerExtraSize > 0) + { + ReadExtra(headerExtraSize, item.CentralExtra, item.UnPackSize, item.PackSize, + item.LocalHeaderPosition, headerDiskNumberStart); + } + + if (headerDiskNumberStart != 0) + throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported); + + // May be these strings must be deleted + /* + if (item.IsDirectory()) + item.UnPackSize = 0; + */ + + ReadBuffer(item.Comment, headerCommentSize); + return S_OK; +} + +HRESULT CInArchive::TryEcd64(UInt64 offset, CCdInfo &cdInfo) +{ + RINOK(Seek(offset)); + const UInt32 kEcd64Size = 56; + Byte buf[kEcd64Size]; + if(!ReadBytesAndTestSize(buf, kEcd64Size)) + return S_FALSE; + if (GetUInt32(buf) != NSignature::kZip64EndOfCentralDir) + return S_FALSE; + // cdInfo.NumEntries = GetUInt64(buf + 24); + cdInfo.Size = GetUInt64(buf + 40); + cdInfo.Offset = GetUInt64(buf + 48); + return S_OK; +} + +HRESULT CInArchive::FindCd(CCdInfo &cdInfo) +{ + UInt64 endPosition; + RINOK(m_Stream->Seek(0, STREAM_SEEK_END, &endPosition)); + const UInt32 kBufSizeMax = (1 << 16) + kEcdSize + kZip64EcdLocatorSize; + Byte buf[kBufSizeMax]; + UInt32 bufSize = (endPosition < kBufSizeMax) ? (UInt32)endPosition : kBufSizeMax; + if (bufSize < kEcdSize) + return S_FALSE; + UInt64 startPosition = endPosition - bufSize; + RINOK(m_Stream->Seek(startPosition, STREAM_SEEK_SET, &m_Position)); + if (m_Position != startPosition) + return S_FALSE; + if (!ReadBytesAndTestSize(buf, bufSize)) + return S_FALSE; + for (int i = (int)(bufSize - kEcdSize); i >= 0; i--) + { + if (GetUInt32(buf + i) == NSignature::kEndOfCentralDir) + { + if (i >= kZip64EcdLocatorSize) + { + const Byte *locator = buf + i - kZip64EcdLocatorSize; + if (GetUInt32(locator) == NSignature::kZip64EndOfCentralDirLocator) + { + UInt64 ecd64Offset = GetUInt64(locator + 8); + if (TryEcd64(ecd64Offset, cdInfo) == S_OK) + return S_OK; + if (TryEcd64(m_ArchiveInfo.StartPosition + ecd64Offset, cdInfo) == S_OK) + { + m_ArchiveInfo.Base = m_ArchiveInfo.StartPosition; + return S_OK; + } + } + } + if (GetUInt32(buf + i + 4) == 0) + { + // cdInfo.NumEntries = GetUInt16(buf + i + 10); + cdInfo.Size = GetUInt32(buf + i + 12); + cdInfo.Offset = GetUInt32(buf + i + 16); + return S_OK; + } + } + } + return S_FALSE; +} + +HRESULT CInArchive::TryReadCd(CObjectVector &items, UInt64 cdOffset, UInt64 cdSize) +{ + items.Clear(); + RINOK(m_Stream->Seek(cdOffset, STREAM_SEEK_SET, &m_Position)); + if (m_Position != cdOffset) + return S_FALSE; + while(m_Position - cdOffset < cdSize) + { + if(ReadUInt32() != NSignature::kCentralFileHeader) + return S_FALSE; + CItemEx cdItem; + RINOK(ReadCdItem(cdItem)); + items.Add(cdItem); + } + return (m_Position - cdOffset == cdSize) ? S_OK : S_FALSE; +} + +HRESULT CInArchive::ReadCd(CObjectVector &items, UInt64 &cdOffset, UInt64 &cdSize) +{ + m_ArchiveInfo.Base = 0; + CCdInfo cdInfo; + RINOK(FindCd(cdInfo)); + HRESULT res = S_FALSE; + cdSize = cdInfo.Size; + cdOffset = cdInfo.Offset; + res = TryReadCd(items, m_ArchiveInfo.Base + cdOffset, cdSize); + if (res == S_FALSE && m_ArchiveInfo.Base == 0) + { + res = TryReadCd(items, cdInfo.Offset + m_ArchiveInfo.StartPosition, cdSize); + if (res == S_OK) + m_ArchiveInfo.Base = m_ArchiveInfo.StartPosition; + } + if (!ReadUInt32(m_Signature)) + return S_FALSE; + return res; +} + +HRESULT CInArchive::ReadLocalsAndCd(CObjectVector &items, CProgressVirt *progress, UInt64 &cdOffset) +{ + items.Clear(); + while (m_Signature == NSignature::kLocalFileHeader) + { + // FSeek points to next byte after signature + // NFileHeader::CLocalBlock localHeader; + CItemEx item; + item.LocalHeaderPosition = m_Position - m_StreamStartPosition - 4; // points to signature; + RINOK(ReadLocalItem(item)); + item.FromLocal = true; + ReadLocalItemDescriptor(item); + items.Add(item); + if (progress != 0) + { + UInt64 numItems = items.Size(); + RINOK(progress->SetCompleted(&numItems)); + } + if (!ReadUInt32(m_Signature)) + break; + } + cdOffset = m_Position - 4; + for(int i = 0; i < items.Size(); i++) + { + if (progress != 0) + { + UInt64 numItems = items.Size(); + RINOK(progress->SetCompleted(&numItems)); + } + if(m_Signature != NSignature::kCentralFileHeader) + return S_FALSE; + + CItemEx cdItem; + RINOK(ReadCdItem(cdItem)); + + if (i == 0) + { + if (cdItem.LocalHeaderPosition == 0) + m_ArchiveInfo.Base = m_ArchiveInfo.StartPosition; + } + + int index; + int left = 0, right = items.Size(); + for (;;) + { + if (left >= right) + return S_FALSE; + index = (left + right) / 2; + UInt64 position = items[index].LocalHeaderPosition - m_ArchiveInfo.Base; + if (cdItem.LocalHeaderPosition == position) + break; + if (cdItem.LocalHeaderPosition < position) + right = index; + else + left = index + 1; + } + CItemEx &item = items[index]; + item.LocalHeaderPosition = cdItem.LocalHeaderPosition; + item.MadeByVersion = cdItem.MadeByVersion; + item.CentralExtra = cdItem.CentralExtra; + + if ( + // item.ExtractVersion != cdItem.ExtractVersion || + item.Flags != cdItem.Flags || + item.CompressionMethod != cdItem.CompressionMethod || + // item.Time != cdItem.Time || + item.FileCRC != cdItem.FileCRC) + return S_FALSE; + + if (item.Name.Length() != cdItem.Name.Length() || + item.PackSize != cdItem.PackSize || + item.UnPackSize != cdItem.UnPackSize + ) + return S_FALSE; + item.Name = cdItem.Name; + item.InternalAttributes = cdItem.InternalAttributes; + item.ExternalAttributes = cdItem.ExternalAttributes; + item.Comment = cdItem.Comment; + item.FromCentral = cdItem.FromCentral; + if (!ReadUInt32(m_Signature)) + return S_FALSE; + } + return S_OK; +} + +HRESULT CInArchive::ReadHeaders(CObjectVector &items, CProgressVirt *progress) +{ + // m_Signature must be kLocalFileHeaderSignature or + // kEndOfCentralDirSignature + // m_Position points to next byte after signature + + items.Clear(); + if (progress != 0) + { + UInt64 numItems = items.Size(); + RINOK(progress->SetCompleted(&numItems)); + } + + UInt64 cdSize, cdStartOffset; + HRESULT res = ReadCd(items, cdStartOffset, cdSize); + if (res != S_FALSE && res != S_OK) + return res; + + /* + if (res != S_OK) + return res; + res = S_FALSE; + */ + + if (res == S_FALSE) + { + m_ArchiveInfo.Base = 0; + RINOK(m_Stream->Seek(m_ArchiveInfo.StartPosition, STREAM_SEEK_SET, &m_Position)); + if (m_Position != m_ArchiveInfo.StartPosition) + return S_FALSE; + if (!ReadUInt32(m_Signature)) + return S_FALSE; + RINOK(ReadLocalsAndCd(items, progress, cdStartOffset)); + cdSize = (m_Position - 4) - cdStartOffset; + cdStartOffset -= m_ArchiveInfo.Base; + } + + UInt32 thisDiskNumber = 0; + UInt32 startCDDiskNumber = 0; + UInt64 numEntriesInCDOnThisDisk = 0; + UInt64 numEntriesInCD = 0; + UInt64 cdSizeFromRecord = 0; + UInt64 cdStartOffsetFromRecord = 0; + bool isZip64 = false; + UInt64 zip64EcdStartOffset = m_Position - 4 - m_ArchiveInfo.Base; + if(m_Signature == NSignature::kZip64EndOfCentralDir) + { + isZip64 = true; + UInt64 recordSize = ReadUInt64(); + /* UInt16 versionMade = */ ReadUInt16(); + /* UInt16 versionNeedExtract = */ ReadUInt16(); + thisDiskNumber = ReadUInt32(); + startCDDiskNumber = ReadUInt32(); + numEntriesInCDOnThisDisk = ReadUInt64(); + numEntriesInCD = ReadUInt64(); + cdSizeFromRecord = ReadUInt64(); + cdStartOffsetFromRecord = ReadUInt64(); + IncreaseRealPosition(recordSize - kZip64EcdSize); + if (!ReadUInt32(m_Signature)) + return S_FALSE; + if (thisDiskNumber != 0 || startCDDiskNumber != 0) + throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported); + if (numEntriesInCDOnThisDisk != items.Size() || + numEntriesInCD != items.Size() || + cdSizeFromRecord != cdSize || + (cdStartOffsetFromRecord != cdStartOffset && + (!items.IsEmpty()))) + return S_FALSE; + } + if(m_Signature == NSignature::kZip64EndOfCentralDirLocator) + { + /* UInt32 startEndCDDiskNumber = */ ReadUInt32(); + UInt64 endCDStartOffset = ReadUInt64(); + /* UInt32 numberOfDisks = */ ReadUInt32(); + if (zip64EcdStartOffset != endCDStartOffset) + return S_FALSE; + if (!ReadUInt32(m_Signature)) + return S_FALSE; + } + if(m_Signature != NSignature::kEndOfCentralDir) + return S_FALSE; + + UInt16 thisDiskNumber16 = ReadUInt16(); + if (!isZip64 || thisDiskNumber16) + thisDiskNumber = thisDiskNumber16; + + UInt16 startCDDiskNumber16 = ReadUInt16(); + if (!isZip64 || startCDDiskNumber16 != 0xFFFF) + startCDDiskNumber = startCDDiskNumber16; + + UInt16 numEntriesInCDOnThisDisk16 = ReadUInt16(); + if (!isZip64 || numEntriesInCDOnThisDisk16 != 0xFFFF) + numEntriesInCDOnThisDisk = numEntriesInCDOnThisDisk16; + + UInt16 numEntriesInCD16 = ReadUInt16(); + if (!isZip64 || numEntriesInCD16 != 0xFFFF) + numEntriesInCD = numEntriesInCD16; + + UInt32 cdSizeFromRecord32 = ReadUInt32(); + if (!isZip64 || cdSizeFromRecord32 != 0xFFFFFFFF) + cdSizeFromRecord = cdSizeFromRecord32; + + UInt32 cdStartOffsetFromRecord32 = ReadUInt32(); + if (!isZip64 || cdStartOffsetFromRecord32 != 0xFFFFFFFF) + cdStartOffsetFromRecord = cdStartOffsetFromRecord32; + + UInt16 commentSize = ReadUInt16(); + ReadBuffer(m_ArchiveInfo.Comment, commentSize); + + if (thisDiskNumber != 0 || startCDDiskNumber != 0) + throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported); + if ((UInt16)numEntriesInCDOnThisDisk != ((UInt16)items.Size()) || + (UInt16)numEntriesInCD != ((UInt16)items.Size()) || + (UInt32)cdSizeFromRecord != (UInt32)cdSize || + ((UInt32)(cdStartOffsetFromRecord) != (UInt32)cdStartOffset && + (!items.IsEmpty()))) + return S_FALSE; + + return S_OK; +} + +ISequentialInStream* CInArchive::CreateLimitedStream(UInt64 position, UInt64 size) +{ + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr inStream(streamSpec); + SeekInArchive(m_ArchiveInfo.Base + position); + streamSpec->SetStream(m_Stream); + streamSpec->Init(size); + return inStream.Detach(); +} + +IInStream* CInArchive::CreateStream() +{ + CMyComPtr inStream = m_Stream; + return inStream.Detach(); +} + +bool CInArchive::SeekInArchive(UInt64 position) +{ + UInt64 newPosition; + if(m_Stream->Seek(position, STREAM_SEEK_SET, &newPosition) != S_OK) + return false; + return (newPosition == position); +} + +}} + diff --git a/CPP/7zip/Archive/Zip/ZipIn.h b/CPP/7zip/Archive/Zip/ZipIn.h new file mode 100755 index 00000000..80de2272 --- /dev/null +++ b/CPP/7zip/Archive/Zip/ZipIn.h @@ -0,0 +1,111 @@ +// Archive/ZipIn.h + +#ifndef __ZIP_IN_H +#define __ZIP_IN_H + +#include "Common/MyCom.h" +#include "../../IStream.h" + +#include "ZipHeader.h" +#include "ZipItemEx.h" + +namespace NArchive { +namespace NZip { + +class CInArchiveException +{ +public: + enum ECauseType + { + kUnexpectedEndOfArchive = 0, + kArchiceHeaderCRCError, + kFileHeaderCRCError, + kIncorrectArchive, + kDataDescroptorsAreNotSupported, + kMultiVolumeArchiveAreNotSupported, + kReadStreamError, + kSeekStreamError + } + Cause; + CInArchiveException(ECauseType cause): Cause(cause) {} +}; + +class CInArchiveInfo +{ +public: + UInt64 Base; + UInt64 StartPosition; + CByteBuffer Comment; + CInArchiveInfo(): Base(0), StartPosition(0) {} + void Clear() + { + Base = 0; + StartPosition = 0; + Comment.SetCapacity(0); + } +}; + +class CProgressVirt +{ +public: + STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE; +}; + +struct CCdInfo +{ + // UInt64 NumEntries; + UInt64 Size; + UInt64 Offset; +}; + +class CInArchive +{ + CMyComPtr m_Stream; + UInt32 m_Signature; + UInt64 m_StreamStartPosition; + UInt64 m_Position; + CInArchiveInfo m_ArchiveInfo; + AString m_NameBuffer; + + HRESULT Seek(UInt64 offset); + + bool FindAndReadMarker(const UInt64 *searchHeaderSizeLimit); + bool ReadUInt32(UInt32 &signature); + AString ReadFileName(UInt32 nameSize); + + HRESULT ReadBytes(void *data, UInt32 size, UInt32 *processedSize); + bool ReadBytesAndTestSize(void *data, UInt32 size); + void SafeReadBytes(void *data, UInt32 size); + void ReadBuffer(CByteBuffer &buffer, UInt32 size); + Byte ReadByte(); + UInt16 ReadUInt16(); + UInt32 ReadUInt32(); + UInt64 ReadUInt64(); + + void IncreaseRealPosition(UInt64 addValue); + + void ReadExtra(UInt32 extraSize, CExtraBlock &extraBlock, + UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber); + HRESULT ReadLocalItem(CItemEx &item); + HRESULT ReadLocalItemDescriptor(CItemEx &item); + HRESULT ReadCdItem(CItemEx &item); + HRESULT TryEcd64(UInt64 offset, CCdInfo &cdInfo); + HRESULT FindCd(CCdInfo &cdInfo); + HRESULT TryReadCd(CObjectVector &items, UInt64 cdOffset, UInt64 cdSize); + HRESULT ReadCd(CObjectVector &items, UInt64 &cdOffset, UInt64 &cdSize); + HRESULT ReadLocalsAndCd(CObjectVector &items, CProgressVirt *progress, UInt64 &cdOffset); +public: + HRESULT ReadHeaders(CObjectVector &items, CProgressVirt *progress); + HRESULT ReadLocalItemAfterCdItem(CItemEx &item); + HRESULT ReadLocalItemAfterCdItemFull(CItemEx &item); + bool Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit); + void Close(); + void GetArchiveInfo(CInArchiveInfo &archiveInfo) const; + bool SeekInArchive(UInt64 position); + ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size); + IInStream* CreateStream(); +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Zip/ZipItem.cpp b/CPP/7zip/Archive/Zip/ZipItem.cpp new file mode 100755 index 00000000..1934c357 --- /dev/null +++ b/CPP/7zip/Archive/Zip/ZipItem.cpp @@ -0,0 +1,137 @@ +// Archive/ZipItem.cpp + +#include "StdAfx.h" + +#include "ZipHeader.h" +#include "ZipItem.h" +#include "../Common/ItemNameUtils.h" + +namespace NArchive { +namespace NZip { + +bool operator==(const CVersion &v1, const CVersion &v2) +{ + return (v1.Version == v2.Version) && (v1.HostOS == v2.HostOS); +} + +bool operator!=(const CVersion &v1, const CVersion &v2) +{ + return !(v1 == v2); +} + +bool CLocalItem::IsEncrypted() const +{ return (Flags & NFileHeader::NFlags::kEncryptedMask) != 0; } +bool CLocalItem::HasDescriptor() const + { return (Flags & NFileHeader::NFlags::kDescriptorUsedMask) != 0; } + +bool CLocalItem::IsImplodeBigDictionary() const +{ +if (CompressionMethod != NFileHeader::NCompressionMethod::kImploded) + throw 12312212; + return (Flags & NFileHeader::NFlags::kImplodeDictionarySizeMask) != 0; +} + +bool CLocalItem::IsImplodeLiteralsOn() const +{ + if (CompressionMethod != NFileHeader::NCompressionMethod::kImploded) + throw 12312213; + return (Flags & NFileHeader::NFlags::kImplodeLiteralsOnMask) != 0; +} + +static const char *kUnknownAttributes = "Unknown file attributes"; + +bool CLocalItem::IsDirectory() const +{ + return NItemName::HasTailSlash(Name, GetCodePage()); +} + +bool CItem::IsDirectory() const +{ + if (NItemName::HasTailSlash(Name, GetCodePage())) + return true; + if (!FromCentral) + return false; + WORD highAttributes = WORD((ExternalAttributes >> 16 ) & 0xFFFF); + switch(MadeByVersion.HostOS) + { + case NFileHeader::NHostOS::kAMIGA: + switch (highAttributes & NFileHeader::NAmigaAttribute::kIFMT) + { + case NFileHeader::NAmigaAttribute::kIFDIR: + return true; + case NFileHeader::NAmigaAttribute::kIFREG: + return false; + default: + return false; // change it throw kUnknownAttributes; + } + case NFileHeader::NHostOS::kFAT: + case NFileHeader::NHostOS::kNTFS: + case NFileHeader::NHostOS::kHPFS: + case NFileHeader::NHostOS::kVFAT: + return ((ExternalAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0); + case NFileHeader::NHostOS::kAtari: + case NFileHeader::NHostOS::kMac: + case NFileHeader::NHostOS::kVMS: + case NFileHeader::NHostOS::kVM_CMS: + case NFileHeader::NHostOS::kAcorn: + case NFileHeader::NHostOS::kMVS: + return false; // change it throw kUnknownAttributes; + default: + /* + switch (highAttributes & NFileHeader::NUnixAttribute::kIFMT) + { + case NFileHeader::NUnixAttribute::kIFDIR: + return true; + default: + return false; + } + */ + return false; + } +} + +UInt32 CLocalItem::GetWinAttributes() const +{ + DWORD winAttributes = 0; + if (IsDirectory()) + winAttributes |= FILE_ATTRIBUTE_DIRECTORY; + return winAttributes; +} + +UInt32 CItem::GetWinAttributes() const +{ + DWORD winAttributes = 0; + switch(MadeByVersion.HostOS) + { + case NFileHeader::NHostOS::kFAT: + case NFileHeader::NHostOS::kNTFS: + if (FromCentral) + winAttributes = ExternalAttributes; + break; + default: + winAttributes = 0; // must be converted from unix value; + } + if (IsDirectory()) // test it; + winAttributes |= FILE_ATTRIBUTE_DIRECTORY; + return winAttributes; +} + +void CLocalItem::SetFlagBits(int startBitNumber, int numBits, int value) +{ + UInt16 mask = (UInt16)(((1 << numBits) - 1) << startBitNumber); + Flags &= ~mask; + Flags |= value << startBitNumber; +} + +void CLocalItem::SetBitMask(int bitMask, bool enable) +{ + if(enable) + Flags |= bitMask; + else + Flags &= ~bitMask; +} + +void CLocalItem::SetEncrypted(bool encrypted) + { SetBitMask(NFileHeader::NFlags::kEncryptedMask, encrypted); } + +}} diff --git a/CPP/7zip/Archive/Zip/ZipItem.h b/CPP/7zip/Archive/Zip/ZipItem.h new file mode 100755 index 00000000..765bfd85 --- /dev/null +++ b/CPP/7zip/Archive/Zip/ZipItem.h @@ -0,0 +1,191 @@ +// Archive/ZipItem.h + +#ifndef __ARCHIVE_ZIP_ITEM_H +#define __ARCHIVE_ZIP_ITEM_H + +#include "Common/Types.h" +#include "Common/String.h" +#include "Common/Buffer.h" + +#include "ZipHeader.h" + +namespace NArchive { +namespace NZip { + +struct CVersion +{ + Byte Version; + Byte HostOS; +}; + +bool operator==(const CVersion &v1, const CVersion &v2); +bool operator!=(const CVersion &v1, const CVersion &v2); + +struct CExtraSubBlock +{ + UInt16 ID; + CByteBuffer Data; +}; + +struct CWzAesExtraField +{ + UInt16 VendorVersion; // 0x0001 - AE-1, 0x0002 - AE-2, + // UInt16 VendorId; // "AE" + Byte Strength; // 1 - 128-bit , 2 - 192-bit , 3 - 256-bit + UInt16 Method; + + CWzAesExtraField(): VendorVersion(2), Strength(3), Method(0) {} + + bool NeedCrc() const { return (VendorVersion == 1); } + + bool ParseFromSubBlock(const CExtraSubBlock &sb) + { + if (sb.ID != NFileHeader::NExtraID::kWzAES) + return false; + if (sb.Data.GetCapacity() < 7) + return false; + const Byte *p = (const Byte *)sb.Data; + VendorVersion = (((UInt16)p[1]) << 8) | p[0]; + if (p[2] != 'A' || p[3] != 'E') + return false; + Strength = p[4]; + Method = (((UInt16)p[6]) << 16) | p[5]; + return true; + } + void SetSubBlock(CExtraSubBlock &sb) const + { + sb.Data.SetCapacity(7); + sb.ID = NFileHeader::NExtraID::kWzAES; + Byte *p = (Byte *)sb.Data; + p[0] = (Byte)VendorVersion; + p[1] = (Byte)(VendorVersion >> 8); + p[2] = 'A'; + p[3] = 'E'; + p[4] = Strength; + p[5] = (Byte)Method; + p[6] = (Byte)(Method >> 8); + } +}; + +struct CExtraBlock +{ + CObjectVector SubBlocks; + void Clear() { SubBlocks.Clear(); } + size_t GetSize() const + { + size_t res = 0; + for (int i = 0; i < SubBlocks.Size(); i++) + res += SubBlocks[i].Data.GetCapacity() + 2 + 2; + return res; + } + bool GetWzAesField(CWzAesExtraField &aesField) const + { + // size_t res = 0; + for (int i = 0; i < SubBlocks.Size(); i++) + if (aesField.ParseFromSubBlock(SubBlocks[i])) + return true; + return false; + } + + bool HasWzAesField() const + { + CWzAesExtraField aesField; + return GetWzAesField(aesField); + } + + void RemoveUnknownSubBlocks() + { + for (int i = SubBlocks.Size() - 1; i >= 0;) + { + const CExtraSubBlock &subBlock = SubBlocks[i]; + if (subBlock.ID != NFileHeader::NExtraID::kWzAES) + SubBlocks.Delete(i); + else + i--; + } + } +}; + + +class CLocalItem +{ +public: + CVersion ExtractVersion; + UInt16 Flags; + UInt16 CompressionMethod; + UInt32 Time; + UInt32 FileCRC; + UInt64 PackSize; + UInt64 UnPackSize; + + AString Name; + + CExtraBlock LocalExtra; + + bool IsEncrypted() const; + + bool IsImplodeBigDictionary() const; + bool IsImplodeLiteralsOn() const; + + bool IsDirectory() const; + bool IgnoreItem() const { return false; } + UInt32 GetWinAttributes() const; + + bool HasDescriptor() const; + +private: + void SetFlagBits(int startBitNumber, int numBits, int value); + void SetBitMask(int bitMask, bool enable); +public: + void ClearFlags() { Flags = 0; } + void SetEncrypted(bool encrypted); + + WORD GetCodePage() const + { + return CP_OEMCP; + } +}; + +class CItem: public CLocalItem +{ +public: + CVersion MadeByVersion; + UInt16 InternalAttributes; + UInt32 ExternalAttributes; + + UInt64 LocalHeaderPosition; + + CExtraBlock CentralExtra; + CByteBuffer Comment; + + bool FromLocal; + bool FromCentral; + + bool IsDirectory() const; + UInt32 GetWinAttributes() const; + + bool IsThereCrc() const + { + if (CompressionMethod == NFileHeader::NCompressionMethod::kWzAES) + { + CWzAesExtraField aesField; + if (CentralExtra.GetWzAesField(aesField)) + return aesField.NeedCrc(); + } + return true; + } + + WORD GetCodePage() const + { + return (WORD)((MadeByVersion.HostOS == NFileHeader::NHostOS::kFAT + || MadeByVersion.HostOS == NFileHeader::NHostOS::kNTFS + ) ? CP_OEMCP : CP_ACP); + } + CItem() : FromLocal(false), FromCentral(false) {} +}; + +}} + +#endif + + diff --git a/CPP/7zip/Archive/Zip/ZipItemEx.h b/CPP/7zip/Archive/Zip/ZipItemEx.h new file mode 100755 index 00000000..3cacc0e7 --- /dev/null +++ b/CPP/7zip/Archive/Zip/ZipItemEx.h @@ -0,0 +1,29 @@ +// Archive/ZipItemEx.h + +#ifndef __ARCHIVE_ZIP_ITEMEX_H +#define __ARCHIVE_ZIP_ITEMEX_H + +#include "ZipHeader.h" +#include "ZipItem.h" + +namespace NArchive { +namespace NZip { + +class CItemEx: public CItem +{ +public: + UInt32 FileHeaderWithNameSize; + UInt16 LocalExtraSize; + + UInt64 GetLocalFullSize() const + { return FileHeaderWithNameSize + LocalExtraSize + PackSize + + (HasDescriptor() ? NFileHeader::kDataDescriptorSize : 0); }; + UInt64 GetLocalExtraPosition() const + { return LocalHeaderPosition + FileHeaderWithNameSize; }; + UInt64 GetDataPosition() const + { return GetLocalExtraPosition() + LocalExtraSize; }; +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Zip/ZipOut.cpp b/CPP/7zip/Archive/Zip/ZipOut.cpp new file mode 100755 index 00000000..7575d320 --- /dev/null +++ b/CPP/7zip/Archive/Zip/ZipOut.cpp @@ -0,0 +1,259 @@ +// ZipOut.cpp + +#include "StdAfx.h" + +#include "ZipOut.h" +#include "Common/StringConvert.h" +#include "Common/CRC.h" +#include "../../Common/OffsetStream.h" +#include "../../Common/StreamUtils.h" + +namespace NArchive { +namespace NZip { + +void COutArchive::Create(IOutStream *outStream) +{ + m_Stream = outStream; + m_BasePosition = 0; +} + +void COutArchive::MoveBasePosition(UInt64 distanceToMove) +{ + m_BasePosition += distanceToMove; // test overflow +} + +void COutArchive::PrepareWriteCompressedDataZip64(UInt16 fileNameLength, bool isZip64, bool aesEncryption) +{ + m_IsZip64 = isZip64; + m_ExtraSize = isZip64 ? (4 + 8 + 8) : 0; + if (aesEncryption) + m_ExtraSize += 4 + 7; + m_LocalFileHeaderSize = 4 + NFileHeader::kLocalBlockSize + fileNameLength + m_ExtraSize; +} + +void COutArchive::PrepareWriteCompressedData(UInt16 fileNameLength, UInt64 unPackSize, bool aesEncryption) +{ + // We test it to 0xF8000000 to support case when compressed size + // can be larger than uncompressed size. + PrepareWriteCompressedDataZip64(fileNameLength, unPackSize >= 0xF8000000, aesEncryption); +} + +void COutArchive::PrepareWriteCompressedData2(UInt16 fileNameLength, UInt64 unPackSize, UInt64 packSize, bool aesEncryption) +{ + bool isUnPack64 = unPackSize >= 0xFFFFFFFF; + bool isPack64 = packSize >= 0xFFFFFFFF; + bool isZip64 = isPack64 || isUnPack64; + PrepareWriteCompressedDataZip64(fileNameLength, isZip64, aesEncryption); +} + +void COutArchive::WriteBytes(const void *buffer, UInt32 size) +{ + UInt32 processedSize; + if(WriteStream(m_Stream, buffer, size, &processedSize) != S_OK) + throw 0; + if(processedSize != size) + throw 0; + m_BasePosition += size; +} + +void COutArchive::WriteByte(Byte b) +{ + WriteBytes(&b, 1); +} + +void COutArchive::WriteUInt16(UInt16 value) +{ + for (int i = 0; i < 2; i++) + { + WriteByte((Byte)value); + value >>= 8; + } +} + +void COutArchive::WriteUInt32(UInt32 value) +{ + for (int i = 0; i < 4; i++) + { + WriteByte((Byte)value); + value >>= 8; + } +} + +void COutArchive::WriteUInt64(UInt64 value) +{ + for (int i = 0; i < 8; i++) + { + WriteByte((Byte)value); + value >>= 8; + } +} + +void COutArchive::WriteExtra(const CExtraBlock &extra) +{ + if (extra.SubBlocks.Size() != 0) + { + for (int i = 0; i < extra.SubBlocks.Size(); i++) + { + const CExtraSubBlock &subBlock = extra.SubBlocks[i]; + WriteUInt16(subBlock.ID); + WriteUInt16((UInt16)subBlock.Data.GetCapacity()); + WriteBytes(subBlock.Data, (UInt32)subBlock.Data.GetCapacity()); + } + } +} + +HRESULT COutArchive::WriteLocalHeader(const CLocalItem &item) +{ + m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL); + + bool isZip64 = m_IsZip64 || item.PackSize >= 0xFFFFFFFF || item.UnPackSize >= 0xFFFFFFFF; + + WriteUInt32(NSignature::kLocalFileHeader); + WriteByte(item.ExtractVersion.Version); + WriteByte(item.ExtractVersion.HostOS); + WriteUInt16(item.Flags); + WriteUInt16(item.CompressionMethod); + WriteUInt32(item.Time); + WriteUInt32(item.FileCRC); + WriteUInt32(isZip64 ? 0xFFFFFFFF: (UInt32)item.PackSize); + WriteUInt32(isZip64 ? 0xFFFFFFFF: (UInt32)item.UnPackSize); + WriteUInt16((UInt16)item.Name.Length()); + { + UInt16 localExtraSize = (UInt16)((isZip64 ? (4 + 16): 0) + item.LocalExtra.GetSize()); + if (localExtraSize > m_ExtraSize) + return E_FAIL; + } + WriteUInt16((UInt16)m_ExtraSize); // test it; + WriteBytes((const char *)item.Name, item.Name.Length()); + + UInt32 extraPos = 0; + if (isZip64) + { + extraPos += 4 + 16; + WriteUInt16(NFileHeader::NExtraID::kZip64); + WriteUInt16(16); + WriteUInt64(item.UnPackSize); + WriteUInt64(item.PackSize); + } + + WriteExtra(item.LocalExtra); + extraPos += (UInt32)item.LocalExtra.GetSize(); + for (; extraPos < m_ExtraSize; extraPos++) + WriteByte(0); + + MoveBasePosition(item.PackSize); + return m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL); +} + +void COutArchive::WriteCentralHeader(const CItem &item) +{ + m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL); + + bool isUnPack64 = item.UnPackSize >= 0xFFFFFFFF; + bool isPack64 = item.PackSize >= 0xFFFFFFFF; + bool isPosition64 = item.LocalHeaderPosition >= 0xFFFFFFFF; + bool isZip64 = isPack64 || isUnPack64 || isPosition64; + + WriteUInt32(NSignature::kCentralFileHeader); + WriteByte(item.MadeByVersion.Version); + WriteByte(item.MadeByVersion.HostOS); + WriteByte(item.ExtractVersion.Version); + WriteByte(item.ExtractVersion.HostOS); + WriteUInt16(item.Flags); + WriteUInt16(item.CompressionMethod); + WriteUInt32(item.Time); + WriteUInt32(item.FileCRC); + WriteUInt32(isPack64 ? 0xFFFFFFFF: (UInt32)item.PackSize); + WriteUInt32(isUnPack64 ? 0xFFFFFFFF: (UInt32)item.UnPackSize); + WriteUInt16((UInt16)item.Name.Length()); + UInt16 zip64ExtraSize = (UInt16)((isUnPack64 ? 8: 0) + (isPack64 ? 8: 0) + (isPosition64 ? 8: 0)); + UInt16 centralExtraSize = (UInt16)(isZip64 ? (4 + zip64ExtraSize) : 0); + centralExtraSize = (UInt16)(centralExtraSize + item.CentralExtra.GetSize()); + WriteUInt16(centralExtraSize); // test it; + WriteUInt16((UInt16)item.Comment.GetCapacity()); + WriteUInt16(0); // DiskNumberStart; + WriteUInt16(item.InternalAttributes); + WriteUInt32(item.ExternalAttributes); + WriteUInt32(isPosition64 ? 0xFFFFFFFF: (UInt32)item.LocalHeaderPosition); + WriteBytes((const char *)item.Name, item.Name.Length()); + if (isZip64) + { + WriteUInt16(NFileHeader::NExtraID::kZip64); + WriteUInt16(zip64ExtraSize); + if(isUnPack64) + WriteUInt64(item.UnPackSize); + if(isPack64) + WriteUInt64(item.PackSize); + if(isPosition64) + WriteUInt64(item.LocalHeaderPosition); + } + WriteExtra(item.CentralExtra); + if (item.Comment.GetCapacity() > 0) + WriteBytes(item.Comment, (UInt32)item.Comment.GetCapacity()); +} + +void COutArchive::WriteCentralDir(const CObjectVector &items, const CByteBuffer &comment) +{ + m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL); + + UInt64 cdOffset = GetCurrentPosition(); + for(int i = 0; i < items.Size(); i++) + WriteCentralHeader(items[i]); + UInt64 cd64EndOffset = GetCurrentPosition(); + UInt64 cdSize = cd64EndOffset - cdOffset; + bool cdOffset64 = cdOffset >= 0xFFFFFFFF; + bool cdSize64 = cdSize >= 0xFFFFFFFF; + bool items64 = items.Size() >= 0xFFFF; + bool isZip64 = (cdOffset64 || cdSize64 || items64); + + if (isZip64) + { + WriteUInt32(NSignature::kZip64EndOfCentralDir); + WriteUInt64(kZip64EcdSize); // ThisDiskNumber = 0; + WriteUInt16(45); // version + WriteUInt16(45); // version + WriteUInt32(0); // ThisDiskNumber = 0; + WriteUInt32(0); // StartCentralDirectoryDiskNumber;; + WriteUInt64((UInt64)items.Size()); + WriteUInt64((UInt64)items.Size()); + WriteUInt64((UInt64)cdSize); + WriteUInt64((UInt64)cdOffset); + + WriteUInt32(NSignature::kZip64EndOfCentralDirLocator); + WriteUInt32(0); // number of the disk with the start of the zip64 end of central directory + WriteUInt64(cd64EndOffset); + WriteUInt32(1); // total number of disks + } + WriteUInt32(NSignature::kEndOfCentralDir); + WriteUInt16(0); // ThisDiskNumber = 0; + WriteUInt16(0); // StartCentralDirectoryDiskNumber; + WriteUInt16((UInt16)(items64 ? 0xFFFF: items.Size())); + WriteUInt16((UInt16)(items64 ? 0xFFFF: items.Size())); + WriteUInt32(cdSize64 ? 0xFFFFFFFF: (UInt32)cdSize); + WriteUInt32(cdOffset64 ? 0xFFFFFFFF: (UInt32)cdOffset); + UInt16 commentSize = (UInt16)comment.GetCapacity(); + WriteUInt16(commentSize); + if (commentSize > 0) + WriteBytes((const Byte *)comment, commentSize); +} + +void COutArchive::CreateStreamForCompressing(IOutStream **outStream) +{ + COffsetOutStream *streamSpec = new COffsetOutStream; + CMyComPtr 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 tempStream(m_Stream); + *outStream = tempStream.Detach(); +} + +}} diff --git a/CPP/7zip/Archive/Zip/ZipOut.h b/CPP/7zip/Archive/Zip/ZipOut.h new file mode 100755 index 00000000..e08c306e --- /dev/null +++ b/CPP/7zip/Archive/Zip/ZipOut.h @@ -0,0 +1,51 @@ +// ZipOut.h + +#ifndef __ZIP_OUT_H +#define __ZIP_OUT_H + +#include "Common/MyCom.h" + +#include "../../IStream.h" + +#include "ZipItem.h" + +namespace NArchive { +namespace NZip { + +class COutArchive +{ + CMyComPtr m_Stream; + + UInt64 m_BasePosition; + UInt32 m_LocalFileHeaderSize; + UInt32 m_ExtraSize; + bool m_IsZip64; + + void WriteBytes(const void *buffer, UInt32 size); + void WriteByte(Byte b); + void WriteUInt16(UInt16 value); + void WriteUInt32(UInt32 value); + void WriteUInt64(UInt64 value); + + void WriteExtraHeader(const CItem &item); + void WriteCentralHeader(const CItem &item); + void WriteExtra(const CExtraBlock &extra); +public: + void Create(IOutStream *outStream); + void MoveBasePosition(UInt64 distanceToMove); + UInt64 GetCurrentPosition() const { return m_BasePosition; }; + void PrepareWriteCompressedDataZip64(UInt16 fileNameLength, bool isZip64, bool aesEncryption); + void PrepareWriteCompressedData(UInt16 fileNameLength, UInt64 unPackSize, bool aesEncryption); + void PrepareWriteCompressedData2(UInt16 fileNameLength, UInt64 unPackSize, UInt64 packSize, bool aesEncryption); + HRESULT WriteLocalHeader(const CLocalItem &item); + + void WriteCentralDir(const CObjectVector &items, const CByteBuffer &comment); + + void CreateStreamForCompressing(IOutStream **outStream); + void CreateStreamForCopying(ISequentialOutStream **outStream); + void SeekToPackedDataPosition(); +}; + +}} + +#endif diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.cpp b/CPP/7zip/Archive/Zip/ZipUpdate.cpp new file mode 100755 index 00000000..f66fcef9 --- /dev/null +++ b/CPP/7zip/Archive/Zip/ZipUpdate.cpp @@ -0,0 +1,734 @@ +// ZipUpdate.cpp + +#include "StdAfx.h" + +#include + +#include "ZipUpdate.h" +#include "ZipAddCommon.h" +#include "ZipOut.h" + +#include "Common/Defs.h" +#include "Common/AutoPtr.h" +#include "Common/StringConvert.h" +#include "Windows/Defs.h" +#include "Windows/Thread.h" + +#include "../../Common/ProgressUtils.h" +#ifdef COMPRESS_MT +#include "../../Common/ProgressMt.h" +#endif +#include "../../Common/LimitedStreams.h" +#include "../../Common/OutMemStream.h" + +#include "../../Compress/Copy/CopyCoder.h" + +using namespace NWindows; +using namespace NSynchronization; + +namespace NArchive { +namespace NZip { + +class CCriticalSectionLock2 +{ + CCriticalSection *_object; + void Unlock() { if (_object != 0) _object->Leave(); } +public: + CCriticalSectionLock2(): _object(0) {} + void Set(CCriticalSection &object) { _object = &object; _object->Enter(); } + ~CCriticalSectionLock2() { Unlock(); } +}; + +static const Byte kMadeByHostOS = NFileHeader::NHostOS::kFAT; +static const Byte kExtractHostOS = NFileHeader::NHostOS::kFAT; + +static const Byte kMethodForDirectory = NFileHeader::NCompressionMethod::kStored; +static const Byte kExtractVersionForDirectory = NFileHeader::NCompressionMethod::kStoreExtractVersion; + +static HRESULT CopyBlockToArchive(ISequentialInStream *inStream, + COutArchive &outArchive, ICompressProgressInfo *progress) +{ + CMyComPtr outStream; + outArchive.CreateStreamForCopying(&outStream); + CMyComPtr copyCoder = new NCompress::CCopyCoder; + return copyCoder->Code(inStream, outStream, NULL, NULL, progress); +} + +static HRESULT WriteRange(IInStream *inStream, COutArchive &outArchive, + const CUpdateRange &range, ICompressProgressInfo *progress) +{ + UInt64 position; + RINOK(inStream->Seek(range.Position, STREAM_SEEK_SET, &position)); + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr inStreamLimited(streamSpec); + streamSpec->SetStream(inStream); + streamSpec->Init(range.Size); + + RINOK(CopyBlockToArchive(inStreamLimited, outArchive, progress)); + return progress->SetRatioInfo(&range.Size, &range.Size); +} + +static void SetFileHeader( + COutArchive &archive, + const CCompressionMethodMode &options, + const CUpdateItem &updateItem, + CItem &item) +{ + item.UnPackSize = updateItem.Size; + bool isDirectory; + + if (updateItem.NewProperties) + { + isDirectory = updateItem.IsDirectory; + item.Name = updateItem.Name; + item.ExternalAttributes = updateItem.Attributes; + item.Time = updateItem.Time; + } + else + isDirectory = item.IsDirectory(); + + item.LocalHeaderPosition = archive.GetCurrentPosition(); + item.MadeByVersion.HostOS = kMadeByHostOS; + item.MadeByVersion.Version = NFileHeader::NCompressionMethod::kMadeByProgramVersion; + + item.ExtractVersion.HostOS = kExtractHostOS; + + item.InternalAttributes = 0; // test it + item.ClearFlags(); + item.SetEncrypted(!isDirectory && options.PasswordIsDefined); + if (isDirectory) + { + item.ExtractVersion.Version = kExtractVersionForDirectory; + item.CompressionMethod = kMethodForDirectory; + item.PackSize = 0; + item.FileCRC = 0; // test it + } +} + +static void SetItemInfoFromCompressingResult(const CCompressingResult &compressingResult, + bool isAesMode, Byte aesKeyMode, CItem &item) +{ + item.ExtractVersion.Version = compressingResult.ExtractVersion; + item.CompressionMethod = compressingResult.Method; + item.FileCRC = compressingResult.CRC; + item.UnPackSize = compressingResult.UnpackSize; + item.PackSize = compressingResult.PackSize; + + item.LocalExtra.Clear(); + item.CentralExtra.Clear(); + + if (isAesMode) + { + CWzAesExtraField wzAesField; + wzAesField.Strength = aesKeyMode; + wzAesField.Method = compressingResult.Method; + item.CompressionMethod = NFileHeader::NCompressionMethod::kWzAES; + item.FileCRC = 0; + CExtraSubBlock sb; + wzAesField.SetSubBlock(sb); + item.LocalExtra.SubBlocks.Add(sb); + item.CentralExtra.SubBlocks.Add(sb); + } +} + +#ifdef COMPRESS_MT + +static DWORD WINAPI CoderThread(void *threadCoderInfo); + +struct CThreadInfo +{ + NWindows::CThread Thread; + CAutoResetEvent *CompressEvent; + CAutoResetEvent *CompressionCompletedEvent; + bool ExitThread; + + CMtCompressProgress *ProgressSpec; + CMyComPtr Progress; + + COutMemStream *OutStreamSpec; + CMyComPtr OutStream; + CMyComPtr InStream; + + CAddCommon Coder; + HRESULT Result; + CCompressingResult CompressingResult; + + bool IsFree; + UInt32 UpdateIndex; + + CThreadInfo(const CCompressionMethodMode &options): + CompressEvent(NULL), + CompressionCompletedEvent(NULL), + ExitThread(false), + ProgressSpec(0), + OutStreamSpec(0), + Coder(options) + {} + + void CreateEvents() + { + CompressEvent = new CAutoResetEvent(false); + CompressionCompletedEvent = new CAutoResetEvent(false); + } + bool CreateThread() { return Thread.Create(CoderThread, this); } + ~CThreadInfo(); + + void WaitAndCode(); + void StopWaitClose() + { + ExitThread = true; + if (OutStreamSpec != 0) + OutStreamSpec->StopWriting(E_ABORT); + if (CompressEvent != NULL) + CompressEvent->Set(); + Thread.Wait(); + Thread.Close(); + } + +}; + +CThreadInfo::~CThreadInfo() +{ + if (CompressEvent != NULL) + delete CompressEvent; + if (CompressionCompletedEvent != NULL) + delete CompressionCompletedEvent; +} + +void CThreadInfo::WaitAndCode() +{ + for (;;) + { + CompressEvent->Lock(); + if (ExitThread) + return; + Result = Coder.Compress(InStream, OutStream, Progress, CompressingResult); + if (Result == S_OK && Progress) + Result = Progress->SetRatioInfo(&CompressingResult.UnpackSize, &CompressingResult.PackSize); + CompressionCompletedEvent->Set(); + } +} + +static DWORD WINAPI CoderThread(void *threadCoderInfo) +{ + ((CThreadInfo *)threadCoderInfo)->WaitAndCode(); + return 0; +} + +class CThreads +{ +public: + CObjectVector Threads; + ~CThreads() + { + for (int i = 0; i < Threads.Size(); i++) + Threads[i].StopWaitClose(); + } +}; + +struct CMemBlocks2: public CMemLockBlocks +{ + CCompressingResult CompressingResult; + bool Defined; + bool Skip; + CMemBlocks2(): Defined(false), Skip(false) {} +}; + +class CMemRefs +{ +public: + CMemBlockManagerMt *Manager; + CObjectVector Refs; + CMemRefs(CMemBlockManagerMt *manager): Manager(manager) {} ; + ~CMemRefs() + { + for (int i = 0; i < Refs.Size(); i++) + Refs[i].FreeOpt(Manager); + } +}; + +#endif + + +static HRESULT UpdateItemOldData(COutArchive &archive, + IInStream *inStream, + const CUpdateItem &updateItem, CItemEx &item, ICompressProgressInfo *progress, + UInt64 &complexity) +{ + if (updateItem.NewProperties) + { + if (item.HasDescriptor()) + return E_NOTIMPL; + + // use old name size. + // CUpdateRange range(item.GetLocalExtraPosition(), item.LocalExtraSize + item.PackSize); + CUpdateRange range(item.GetDataPosition(), item.PackSize); + + // item.ExternalAttributes = updateItem.Attributes; + // Test it + item.Name = updateItem.Name; + item.Time = updateItem.Time; + item.CentralExtra.RemoveUnknownSubBlocks(); + item.LocalExtra.RemoveUnknownSubBlocks(); + + archive.PrepareWriteCompressedData2((UInt16)item.Name.Length(), item.UnPackSize, item.PackSize, item.LocalExtra.HasWzAesField()); + item.LocalHeaderPosition = archive.GetCurrentPosition(); + archive.SeekToPackedDataPosition(); + RINOK(WriteRange(inStream, archive, range, progress)); + complexity += range.Size; + archive.WriteLocalHeader(item); + } + else + { + CUpdateRange range(item.LocalHeaderPosition, item.GetLocalFullSize()); + + // set new header position + item.LocalHeaderPosition = archive.GetCurrentPosition(); + + RINOK(WriteRange(inStream, archive, range, progress)); + complexity += range.Size; + archive.MoveBasePosition(range.Size); + } + return S_OK; +} + +static HRESULT WriteDirHeader(COutArchive &archive, const CCompressionMethodMode *options, + const CUpdateItem &updateItem, CItemEx &item) +{ + SetFileHeader(archive, *options, updateItem, item); + archive.PrepareWriteCompressedData((UInt16)item.Name.Length(), updateItem.Size, options->IsAesMode); + return archive.WriteLocalHeader(item); +} + +static HRESULT Update2St(COutArchive &archive, + CInArchive *inArchive, + IInStream *inStream, + const CObjectVector &inputItems, + const CObjectVector &updateItems, + const CCompressionMethodMode *options, + const CByteBuffer &comment, + IArchiveUpdateCallback *updateCallback) +{ + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr localProgress = localProgressSpec; + localProgressSpec->Init(updateCallback, true); + + CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo; + CMyComPtr compressProgress = localCompressProgressSpec; + + CAddCommon compressor(*options); + + CObjectVector items; + UInt64 complexity = 0; + + for (int itemIndex = 0; itemIndex < updateItems.Size(); itemIndex++) + { + RINOK(updateCallback->SetCompleted(&complexity)); + const CUpdateItem &updateItem = updateItems[itemIndex]; + CItemEx item; + if (!updateItem.NewProperties || !updateItem.NewData) + { + item = inputItems[updateItem.IndexInArchive]; + if (inArchive->ReadLocalItemAfterCdItemFull(item) != S_OK) + return E_NOTIMPL; + } + + if (updateItem.NewData) + { + bool isDirectory = ((updateItem.NewProperties) ? updateItem.IsDirectory : item.IsDirectory()); + if (isDirectory) + { + RINOK(WriteDirHeader(archive, options, updateItem, item)); + } + else + { + CMyComPtr fileInStream; + HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream); + if (res == S_FALSE) + { + complexity += updateItem.Size + NFileHeader::kLocalBlockSize; + RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); + continue; + } + RINOK(res); + + // file Size can be 64-bit !!! + SetFileHeader(archive, *options, updateItem, item); + archive.PrepareWriteCompressedData((UInt16)item.Name.Length(), updateItem.Size, options->IsAesMode); + CCompressingResult compressingResult; + CMyComPtr outStream; + archive.CreateStreamForCompressing(&outStream); + localCompressProgressSpec->Init(localProgress, &complexity, NULL); + RINOK(compressor.Compress(fileInStream, outStream, compressProgress, compressingResult)); + SetItemInfoFromCompressingResult(compressingResult, options->IsAesMode, options->AesKeyMode, item); + RINOK(archive.WriteLocalHeader(item)); + RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); + complexity += item.UnPackSize; + } + } + else + { + localCompressProgressSpec->Init(localProgress, &complexity, NULL); + RINOK(UpdateItemOldData(archive, inStream, updateItem, item, compressProgress, complexity)); + } + items.Add(item); + complexity += NFileHeader::kLocalBlockSize; + } + archive.WriteCentralDir(items, comment); + return S_OK; +} + +static HRESULT Update2(COutArchive &archive, + CInArchive *inArchive, + IInStream *inStream, + const CObjectVector &inputItems, + const CObjectVector &updateItems, + const CCompressionMethodMode *options, + const CByteBuffer &comment, + IArchiveUpdateCallback *updateCallback) +{ + UInt64 complexity = 0; + UInt64 numFilesToCompress = 0; + UInt64 numBytesToCompress = 0; + + int i; + for(i = 0; i < updateItems.Size(); i++) + { + const CUpdateItem &updateItem = updateItems[i]; + if (updateItem.NewData) + { + complexity += updateItem.Size; + numBytesToCompress += updateItem.Size; + numFilesToCompress++; + /* + if (updateItem.Commented) + complexity += updateItem.CommentRange.Size; + */ + } + else + { + CItemEx inputItem = inputItems[updateItem.IndexInArchive]; + if (inArchive->ReadLocalItemAfterCdItemFull(inputItem) != S_OK) + return E_NOTIMPL; + complexity += inputItem.GetLocalFullSize(); + // complexity += inputItem.GetCentralExtraPlusCommentSize(); + } + complexity += NFileHeader::kLocalBlockSize; + complexity += NFileHeader::kCentralBlockSize; + } + + if (comment != 0) + complexity += comment.GetCapacity(); + complexity++; // end of central + updateCallback->SetTotal(complexity); + + CAddCommon compressor(*options); + + complexity = 0; + + #ifdef COMPRESS_MT + + const size_t kNumMaxThreads = (1 << 10); + UInt32 numThreads = options->NumThreads; + if (numThreads > kNumMaxThreads) + numThreads = kNumMaxThreads; + + const size_t kMemPerThread = (1 << 25); + const size_t kBlockSize = 1 << 16; + + CCompressionMethodMode options2; + if (options != 0) + options2 = *options; + + bool mtMode = ((options != 0) && (numThreads > 1)); + + if (numFilesToCompress <= 1) + mtMode = false; + + if (mtMode) + { + Byte method = options->MethodSequence.Front(); + if (method == NFileHeader::NCompressionMethod::kStored && !options->PasswordIsDefined) + mtMode = false; + if (method == NFileHeader::NCompressionMethod::kBZip2) + { + UInt64 averageSize = numBytesToCompress / numFilesToCompress; + UInt32 blockSize = options->DicSize; + if (blockSize == 0) + blockSize = 1; + UInt64 averageNumberOfBlocks = averageSize / blockSize; + UInt32 numBZip2Threads = 32; + if (averageNumberOfBlocks < numBZip2Threads) + numBZip2Threads = (UInt32)averageNumberOfBlocks; + if (numBZip2Threads < 1) + numBZip2Threads = 1; + numThreads = numThreads / numBZip2Threads; + options2.NumThreads = numBZip2Threads; + if (numThreads <= 1) + mtMode = false; + } + } + + if (!mtMode) + #endif + return Update2St(archive, inArchive,inStream, + inputItems, updateItems, options, comment, updateCallback); + + + #ifdef COMPRESS_MT + + CObjectVector items; + + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr localProgress = localProgressSpec; + localProgressSpec->Init(updateCallback, true); + + CMtCompressProgressMixer mtCompressProgressMixer; + mtCompressProgressMixer.Init(numThreads + 1, localProgress); + + // we need one item for main stream + CMtCompressProgress *progressMainSpec = new CMtCompressProgress(); + CMyComPtr progressMain = progressMainSpec; + progressMainSpec->Init(&mtCompressProgressMixer, (int)numThreads); + + CMemBlockManagerMt memManager(kBlockSize); + CMemRefs refs(&memManager); + + CThreads threads; + CRecordVector compressingCompletedEvents; + CRecordVector threadIndices; // list threads in order of updateItems + + { + if (!memManager.AllocateSpaceAlways((size_t)numThreads * (kMemPerThread / kBlockSize))) + return E_OUTOFMEMORY; + for(i = 0; i < updateItems.Size(); i++) + refs.Refs.Add(CMemBlocks2()); + + UInt32 i; + for (i = 0; i < numThreads; i++) + threads.Threads.Add(CThreadInfo(options2)); + + for (i = 0; i < numThreads; i++) + { + CThreadInfo &threadInfo = threads.Threads[i]; + threadInfo.CreateEvents(); + threadInfo.OutStreamSpec = new COutMemStream(&memManager); + threadInfo.OutStream = threadInfo.OutStreamSpec; + threadInfo.IsFree = true; + threadInfo.ProgressSpec = new CMtCompressProgress(); + threadInfo.Progress = threadInfo.ProgressSpec; + threadInfo.ProgressSpec->Init(&mtCompressProgressMixer, (int)i); + if (!threadInfo.CreateThread()) + return ::GetLastError(); + } + } + int mtItemIndex = 0; + + int itemIndex = 0; + int lastRealStreamItemIndex = -1; + + while (itemIndex < updateItems.Size()) + { + if ((UInt32)threadIndices.Size() < numThreads && mtItemIndex < updateItems.Size()) + { + const CUpdateItem &updateItem = updateItems[mtItemIndex++]; + if (!updateItem.NewData) + continue; + CItemEx item; + if (updateItem.NewProperties) + { + if (updateItem.IsDirectory) + continue; + } + else + { + item = inputItems[updateItem.IndexInArchive]; + if (inArchive->ReadLocalItemAfterCdItemFull(item) != S_OK) + return E_NOTIMPL; + if (item.IsDirectory()) + continue; + } + CMyComPtr fileInStream; + { + NWindows::NSynchronization::CCriticalSectionLock lock(mtCompressProgressMixer.CriticalSection); + HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream); + if (res == S_FALSE) + { + complexity += updateItem.Size; + complexity++; + RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); + refs.Refs[mtItemIndex - 1].Skip = true; + continue; + } + RINOK(res); + RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); + } + + for (UInt32 i = 0; i < numThreads; i++) + { + CThreadInfo &threadInfo = threads.Threads[i]; + if (threadInfo.IsFree) + { + threadInfo.IsFree = false; + threadInfo.InStream = fileInStream; + threadInfo.OutStreamSpec->Init(); + threadInfo.ProgressSpec->Reinit(); + threadInfo.CompressEvent->Set(); + threadInfo.UpdateIndex = mtItemIndex - 1; + + compressingCompletedEvents.Add(*threadInfo.CompressionCompletedEvent); + threadIndices.Add(i); + break; + } + } + continue; + } + + if (refs.Refs[itemIndex].Skip) + { + itemIndex++; + continue; + } + + const CUpdateItem &updateItem = updateItems[itemIndex]; + + CItemEx item; + if (!updateItem.NewProperties || !updateItem.NewData) + { + item = inputItems[updateItem.IndexInArchive]; + if (inArchive->ReadLocalItemAfterCdItemFull(item) != S_OK) + return E_NOTIMPL; + } + + if (updateItem.NewData) + { + bool isDirectory = ((updateItem.NewProperties) ? updateItem.IsDirectory : item.IsDirectory()); + if (isDirectory) + { + RINOK(WriteDirHeader(archive, options, updateItem, item)); + } + else + { + if (lastRealStreamItemIndex < itemIndex) + { + lastRealStreamItemIndex = itemIndex; + SetFileHeader(archive, *options, updateItem, item); + // file Size can be 64-bit !!! + archive.PrepareWriteCompressedData((UInt16)item.Name.Length(), updateItem.Size, options->IsAesMode); + } + + CMemBlocks2 &memRef = refs.Refs[itemIndex]; + if (memRef.Defined) + { + CMyComPtr outStream; + archive.CreateStreamForCompressing(&outStream); + memRef.WriteToStream(memManager.GetBlockSize(), outStream); + SetItemInfoFromCompressingResult(memRef.CompressingResult, + options->IsAesMode, options->AesKeyMode, item); + SetFileHeader(archive, *options, updateItem, item); + RINOK(archive.WriteLocalHeader(item)); + complexity += item.UnPackSize; + // RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); + memRef.FreeOpt(&memManager); + } + else + { + { + CThreadInfo &thread = threads.Threads[threadIndices.Front()]; + if (!thread.OutStreamSpec->WasUnlockEventSent()) + { + CMyComPtr outStream; + archive.CreateStreamForCompressing(&outStream); + thread.OutStreamSpec->SetOutStream(outStream); + thread.OutStreamSpec->SetRealStreamMode(); + } + } + + DWORD result = ::WaitForMultipleObjects(compressingCompletedEvents.Size(), + &compressingCompletedEvents.Front(), FALSE, INFINITE); + int t = (int)(result - WAIT_OBJECT_0); + CThreadInfo &threadInfo = threads.Threads[threadIndices[t]]; + threadInfo.InStream.Release(); + threadInfo.IsFree = true; + RINOK(threadInfo.Result); + threadIndices.Delete(t); + compressingCompletedEvents.Delete(t); + if (t == 0) + { + RINOK(threadInfo.OutStreamSpec->WriteToRealStream()); + threadInfo.OutStreamSpec->ReleaseOutStream(); + SetItemInfoFromCompressingResult(threadInfo.CompressingResult, + options->IsAesMode, options->AesKeyMode, item); + SetFileHeader(archive, *options, updateItem, item); + RINOK(archive.WriteLocalHeader(item)); + complexity += item.UnPackSize; + } + else + { + CMemBlocks2 &memRef = refs.Refs[threadInfo.UpdateIndex]; + threadInfo.OutStreamSpec->DetachData(memRef); + memRef.CompressingResult = threadInfo.CompressingResult; + memRef.Defined = true; + continue; + } + } + } + } + else + { + progressMainSpec->Reinit(); + RINOK(UpdateItemOldData(archive, inStream, updateItem, item, progressMain, complexity)); + } + items.Add(item); + complexity += NFileHeader::kLocalBlockSize; + itemIndex++; + } + archive.WriteCentralDir(items, comment); + return S_OK; + #endif +} + +HRESULT Update( + const CObjectVector &inputItems, + const CObjectVector &updateItems, + ISequentialOutStream *seqOutStream, + CInArchive *inArchive, + CCompressionMethodMode *compressionMethodMode, + IArchiveUpdateCallback *updateCallback) +{ + CMyComPtr outStream; + RINOK(seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStream)); + if (!outStream) + return E_NOTIMPL; + + CInArchiveInfo archiveInfo; + if(inArchive != 0) + { + inArchive->GetArchiveInfo(archiveInfo); + if (archiveInfo.Base != 0) + return E_NOTIMPL; + } + else + archiveInfo.StartPosition = 0; + + COutArchive outArchive; + outArchive.Create(outStream); + if (archiveInfo.StartPosition > 0) + { + CMyComPtr inStream; + inStream.Attach(inArchive->CreateLimitedStream(0, archiveInfo.StartPosition)); + RINOK(CopyBlockToArchive(inStream, outArchive, NULL)); + outArchive.MoveBasePosition(archiveInfo.StartPosition); + } + CMyComPtr inStream; + if(inArchive != 0) + inStream.Attach(inArchive->CreateStream()); + + return Update2(outArchive, inArchive, inStream, + inputItems, updateItems, + compressionMethodMode, + archiveInfo.Comment, updateCallback); +} + +}} diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.h b/CPP/7zip/Archive/Zip/ZipUpdate.h new file mode 100755 index 00000000..d846b05f --- /dev/null +++ b/CPP/7zip/Archive/Zip/ZipUpdate.h @@ -0,0 +1,52 @@ +// Zip/Update.h + +#ifndef __ZIP_UPDATE_H +#define __ZIP_UPDATE_H + +#include "Common/Vector.h" +#include "Common/Types.h" + +#include "../../ICoder.h" +#include "../IArchive.h" + +#include "ZipCompressionMode.h" +#include "ZipIn.h" + +namespace NArchive { +namespace NZip { + +struct CUpdateRange +{ + UInt64 Position; + UInt64 Size; + CUpdateRange() {}; + CUpdateRange(UInt64 position, UInt64 size): Position(position), Size(size) {}; +}; + +struct CUpdateItem +{ + bool NewData; + bool NewProperties; + bool IsDirectory; + int IndexInArchive; + int IndexInClient; + UInt32 Attributes; + UInt32 Time; + UInt64 Size; + AString Name; + // bool Commented; + // CUpdateRange CommentRange; + CUpdateItem(): Size(0) {} +}; + +HRESULT Update( + const CObjectVector &inputItems, + const CObjectVector &updateItems, + ISequentialOutStream *seqOutStream, + CInArchive *inArchive, + CCompressionMethodMode *compressionMethodMode, + IArchiveUpdateCallback *updateCallback); + +}} + +#endif diff --git a/CPP/7zip/Archive/Zip/makefile b/CPP/7zip/Archive/Zip/makefile new file mode 100755 index 00000000..eaf1031f --- /dev/null +++ b/CPP/7zip/Archive/Zip/makefile @@ -0,0 +1,124 @@ +PROG = zip.dll +DEF_FILE = ../Archive.def +CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_MT +LIBS = $(LIBS) oleaut32.lib user32.lib + +ZIP_OBJS = \ + $O\DllExports.obj \ + $O\ZipAddCommon.obj \ + $O\ZipHandler.obj \ + $O\ZipHandlerOut.obj \ + $O\ZipHeader.obj \ + $O\ZipIn.obj \ + $O\ZipItem.obj \ + $O\ZipOut.obj \ + $O\ZipUpdate.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CRC.obj \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\Vector.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\FileFind.obj \ + $O\PropVariant.obj \ + $O\Synchronization.obj \ + +7ZIP_COMMON_OBJS = \ + $O\InBuffer.obj \ + $O\LimitedStreams.obj \ + $O\LSBFDecoder.obj \ + $O\MemBlocks.obj \ + $O\OffsetStream.obj \ + $O\OutBuffer.obj \ + $O\OutMemStream.obj \ + $O\ProgressMt.obj \ + $O\ProgressUtils.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + +AR_COMMON_OBJS = \ + $O\CodecsPath.obj \ + $O\CoderLoader.obj \ + $O\FilterCoder.obj \ + $O\InStreamWithCRC.obj \ + $O\ItemNameUtils.obj \ + $O\OutStreamWithCRC.obj \ + $O\ParseProperties.obj \ + +7Z_OBJS = \ + $O\7zMethodID.obj \ + $O\7zMethods.obj \ + +IMPLODE_OBJS = \ + $O\ImplodeDecoder.obj \ + $O\ImplodeHuffmanDecoder.obj \ + +SHRINK_OBJS = \ + $O\ShrinkDecoder.obj \ + +CRYPTO_HASH_OBJS = \ + $O\HmacSha1.obj \ + $O\Pbkdf2HmacSha1.obj \ + $O\RandGen.obj \ + $O\Sha1.obj \ + +CRYPTO_WZAES_OBJS = \ + $O\WzAES.obj \ + +CRYPTO_ZIP_OBJS = \ + $O\ZipCipher.obj \ + $O\ZipCrypto.obj \ + + +OBJS = \ + $O\StdAfx.obj \ + $(ZIP_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $(7Z_OBJS) \ + $(CRYPTO_HASH_OBJS) \ + $(CRYPTO_WZAES_OBJS) \ + $(CRYPTO_ZIP_OBJS) \ + $(IMPLODE_OBJS) \ + $(SHRINK_OBJS) \ + $O\CopyCoder.obj \ + $O\LZOutWindow.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(ZIP_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$(7Z_OBJS): ../7z/$(*B).cpp + $(COMPL) +$(CRYPTO_HASH_OBJS): ../../Crypto/Hash/$(*B).cpp + $(COMPL_O2) +$(CRYPTO_ZIP_OBJS): ../../Crypto/Zip/$(*B).cpp + $(COMPL) +$(CRYPTO_WZAES_OBJS): ../../Crypto/WzAES/$(*B).cpp + $(COMPL_O2) +$(IMPLODE_OBJS): ../../Compress/Implode/$(*B).cpp + $(COMPL) +$(SHRINK_OBJS): ../../Compress/Shrink/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) +$O\LZOutWindow.obj: ../../Compress/LZ/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/Archive/Zip/resource.rc b/CPP/7zip/Archive/Zip/resource.rc new file mode 100755 index 00000000..388f349e --- /dev/null +++ b/CPP/7zip/Archive/Zip/resource.rc @@ -0,0 +1,5 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("Zip Plugin", "zip") + +101 ICON "zip.ico" diff --git a/CPP/7zip/Archive/Zip/zip.ico b/CPP/7zip/Archive/Zip/zip.ico new file mode 100755 index 00000000..2af46066 Binary files /dev/null and b/CPP/7zip/Archive/Zip/zip.ico differ diff --git a/CPP/7zip/Archive/makefile b/CPP/7zip/Archive/makefile new file mode 100755 index 00000000..7512ad56 --- /dev/null +++ b/CPP/7zip/Archive/makefile @@ -0,0 +1,23 @@ +DIRS = \ + 7z\~ \ + Arj\~ \ + BZip2\~ \ + Cab\~ \ + Chm\~ \ + Cpio\~ \ + Deb\~ \ + GZip\~ \ + Iso\~ \ + Lzh\~ \ + Nsis\~ \ + Rar\~ \ + RPM\~ \ + Split\~ \ + Tar\~ \ + Z\~ \ + Zip\~ \ + +all: $(DIRS) + +$(DIRS): +!include "../SubBuild.mak" diff --git a/CPP/7zip/Bundles/Alone/Alone.dsp b/CPP/7zip/Bundles/Alone/Alone.dsp new file mode 100755 index 00000000..982cfb31 --- /dev/null +++ b/CPP/7zip/Bundles/Alone/Alone.dsp @@ -0,0 +1,2301 @@ +# Microsoft Developer Studio Project File - Name="Alone" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=Alone - Win32 DebugU +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Alone.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Alone.mak" CFG="Alone - Win32 DebugU" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Alone - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "Alone - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "Alone - Win32 ReleaseU" (based on "Win32 (x86) Console Application") +!MESSAGE "Alone - Win32 DebugU" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Alone - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "FORMAT_Z" /D "FORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_DEFLATE64" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /D "COMPRESS_MT" /D "COMPRESS_BZIP2_MT" /Yu"StdAfx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7za.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "FORMAT_Z" /D "FORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_DEFLATE64" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /D "COMPRESS_MT" /D "COMPRESS_BZIP2_MT" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7za.exe" /pdbtype:sept + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ReleaseU" +# PROP BASE Intermediate_Dir "ReleaseU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseU" +# PROP Intermediate_Dir "ReleaseU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "FORMAT_Z" /D "FORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_DEFLATE64" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /D "COMPRESS_MT" /D "COMPRESS_BZIP2_MT" /Yu"StdAfx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7za.exe" /opt:NOWIN98 +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7zan.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "DebugU" +# PROP BASE Intermediate_Dir "DebugU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugU" +# PROP Intermediate_Dir "DebugU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "FORMAT_Z" /D "FORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_DEFLATE64" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /D "COMPRESS_MT" /D "COMPRESS_BZIP2_MT" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7za.exe" /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7zan.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Alone - Win32 Release" +# Name "Alone - Win32 Debug" +# Name "Alone - Win32 ReleaseU" +# Name "Alone - Win32 DebugU" +# Begin Group "Console" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Console\ArError.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\CompressionMode.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\ConsoleClose.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\ConsoleClose.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\ExtractCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\ExtractCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\List.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\List.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\Main.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\MainAr.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\OpenCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\OpenCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\PercentPrinter.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\PercentPrinter.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\UpdateCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\UpdateCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\UserInputUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\UserInputUtils.h +# End Source File +# End Group +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\AlignedBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\AlignedBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\AutoPtr.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Buffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ComTry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynamicBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Exception.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyGuidDef.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyInitGuid.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyUnknown.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Random.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Random.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Types.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Device.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Handle.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Thread.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Time.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CrossThreadProgress.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InOutTempBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InOutTempBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LSBFDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LSBFDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LSBFEncoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LSBFEncoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MemBlocks.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MSBFDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MSBFEncoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OffsetStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OffsetStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutMemStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutMemStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressMt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressMt.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Group "Branch" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Branch\BranchCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\BranchCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\Coder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86_2.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86_2.h +# End Source File +# End Group +# Begin Group "BZip2" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\BZip2\BZip2CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2\BZip2CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2\BZip2Decoder.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2\BZip2Decoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2\BZip2Encoder.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2\BZip2Encoder.h +# End Source File +# End Group +# Begin Group "Copy" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "Deflate" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Deflate\DeflateConst.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Deflate\DeflateDecoder.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Deflate\DeflateDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Deflate\DeflateEncoder.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Deflate\DeflateEncoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Deflate\DeflateExtConst.h +# End Source File +# End Group +# Begin Group "Huffman" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Huffman\HuffmanDecoder.h +# End Source File +# End Group +# Begin Group "Implode" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Implode\ImplodeDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Implode\ImplodeDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Implode\ImplodeHuffmanDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Implode\ImplodeHuffmanDecoder.h +# End Source File +# End Group +# Begin Group "LZ" + +# PROP Default_Filter "" +# Begin Group "MT" + +# PROP Default_Filter "" +# End Group +# Begin Group "HC" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZ\HashChain\HC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\HashChain\HC2.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\HashChain\HC3.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\HashChain\HC4.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\HashChain\HC4b.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\HashChain\HCMain.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\Compress\LZ\IMatchFinder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O1 + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O1 + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.h +# End Source File +# End Group +# Begin Group "LZMA" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZMA\LZMA.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZMA\LZMADecoder.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZMA\LZMADecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZMA\LZMAEncoder.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZMA\LZMAEncoder.h +# End Source File +# End Group +# Begin Group "PPMd" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDContext.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDDecode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDDecoder.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDEncode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDEncoder.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDEncoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDSubAlloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDType.h +# End Source File +# End Group +# Begin Group "RangeCoder" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O1 + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O1 + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoderBitTree.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoderOpt.h +# End Source File +# End Group +# Begin Group "Shrink" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Shrink\ShrinkDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Shrink\ShrinkDecoder.h +# End Source File +# End Group +# Begin Group "Z" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Z\ZDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Z\ZDecoder.h +# End Source File +# End Group +# Begin Group "BWT" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\BWT\BlockSort.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BWT\BlockSort.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BWT\Mtf8.h +# End Source File +# End Group +# Begin Group "LZX" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Lzx\Lzx.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzx\Lzx86Converter.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzx\Lzx86Converter.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzx\LzxDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzx\LzxDecoder.h +# End Source File +# End Group +# Begin Group "Quantum" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Quantum\QuantumDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Quantum\QuantumDecoder.h +# End Source File +# End Group +# End Group +# Begin Group "Archive" + +# PROP Default_Filter "" +# Begin Group "7z" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\7z\7zCompressionMode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zCompressionMode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zEncode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zEncode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zExtract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethodID.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethodID.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zOut.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zProperties.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zSpecStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zSpecStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zUpdate.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zUpdate.h +# End Source File +# End Group +# Begin Group "bz2" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\BZip2\BZip2Handler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\BZip2\BZip2Handler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\BZip2\BZip2HandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\BZip2\BZip2Item.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\BZip2\BZip2Update.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\BZip2\BZip2Update.h +# End Source File +# End Group +# Begin Group "gz" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\GZip\GZipHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\GZip\GZipHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\GZip\GZipHandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\GZip\GZipHeader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\GZip\GZipHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\GZip\GZipIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\GZip\GZipIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\GZip\GZipItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\GZip\GZipOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\GZip\GZipOut.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\GZip\GZipUpdate.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\GZip\GZipUpdate.h +# End Source File +# End Group +# Begin Group "tar" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarHandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarHeader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarOut.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarUpdate.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarUpdate.h +# End Source File +# End Group +# Begin Group "zip" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipAddCommon.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipAddCommon.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipCompressionMode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipHandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipHeader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipItem.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipItemEx.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipOut.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipUpdate.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipUpdate.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2MT.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2ST.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2ST.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\DummyOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\DummyOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\InStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\InStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\MultiStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\MultiStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ParseProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ParseProperties.h +# End Source File +# End Group +# Begin Group "split" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Split\SplitHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Split\SplitHandler.h +# End Source File +# End Group +# Begin Group "Z Format" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Z\ZHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Z\ZHandler.h +# End Source File +# End Group +# Begin Group "cab" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabBlockInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabBlockInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabHeader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabItem.h +# End Source File +# End Group +# End Group +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveCommandLine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveCommandLine.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiverInfo.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiverInfo.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\EnumDirItems.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\EnumDirItems.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Extract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Extract.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractingFilePath.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractingFilePath.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\OpenArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\OpenArchive.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\PropIDUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\PropIDUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\SetProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\SetProperties.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\SortUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\SortUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\TempFiles.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\TempFiles.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Update.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Update.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateAction.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateAction.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdatePair.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdatePair.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateProduce.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateProduce.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\WorkDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\WorkDir.h +# End Source File +# End Group +# Begin Group "Crypto" + +# PROP Default_Filter "" +# Begin Group "Zip Crypto" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\Zip\ZipCipher.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O1 + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O1 + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Zip\ZipCipher.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Zip\ZipCrypto.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O1 + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O1 + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Zip\ZipCrypto.h +# End Source File +# End Group +# Begin Group "AES" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\AES\aes.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\AES_CBC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aescpp.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aescrypt.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aeskey.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aesopt.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aestab.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\MyAES.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\MyAES.h +# End Source File +# End Group +# Begin Group "7z AES" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\7zAES\7zAES.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\7zAES\7zAES.h +# End Source File +# End Group +# Begin Group "WzAES" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\WzAES\WzAES.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\WzAES\WzAES.h +# End Source File +# End Group +# Begin Group "Hash" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\Hash\HmacSha1.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Hash\HmacSha1.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Hash\Pbkdf2HmacSha1.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Hash\Pbkdf2HmacSha1.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Hash\RandGen.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Hash\RandGen.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Hash\Sha1.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Hash\Sha1.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Hash\Sha256.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Hash\Sha256.h +# End Source File +# End Group +# End Group +# Begin Group "7-zip" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IMyUnknown.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# Begin Source File + +SOURCE=..\..\IStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\PropID.h +# End Source File +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Group "C-Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Huffman\HuffmanEncode.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Huffman\HuffmanEncode.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Lz\LzHash.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Lz\MatchFinderMt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Lz\MatchFinderMt.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\IStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Types.h +# End Source File +# End Group +# End Target +# End Project diff --git a/CPP/7zip/Bundles/Alone/Alone.dsw b/CPP/7zip/Bundles/Alone/Alone.dsw new file mode 100755 index 00000000..65eca43f --- /dev/null +++ b/CPP/7zip/Bundles/Alone/Alone.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Alone"=.\Alone.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Bundles/Alone/StdAfx.cpp b/CPP/7zip/Bundles/Alone/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Bundles/Alone/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Bundles/Alone/StdAfx.h b/CPP/7zip/Bundles/Alone/StdAfx.h new file mode 100755 index 00000000..2e4be10b --- /dev/null +++ b/CPP/7zip/Bundles/Alone/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" +#include "../../../Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/Bundles/Alone/afxres.h b/CPP/7zip/Bundles/Alone/afxres.h new file mode 100755 index 00000000..c2fadd4a --- /dev/null +++ b/CPP/7zip/Bundles/Alone/afxres.h @@ -0,0 +1 @@ +#include diff --git a/CPP/7zip/Bundles/Alone/makefile b/CPP/7zip/Bundles/Alone/makefile new file mode 100755 index 00000000..e076ed3a --- /dev/null +++ b/CPP/7zip/Bundles/Alone/makefile @@ -0,0 +1,390 @@ +PROG = 7za.exe +LIBS = $(LIBS) user32.lib oleaut32.lib Advapi32.lib + +CFLAGS = $(CFLAGS) -I ../../../ \ + -DEXCLUDE_COM \ + -DNO_REGISTRY \ + -DWIN_LONG_PATH \ + -DFORMAT_7Z \ + -DFORMAT_BZIP2 \ + -DFORMAT_CAB \ + -DFORMAT_GZIP \ + -DFORMAT_SPLIT \ + -DFORMAT_TAR \ + -DFORMAT_Z \ + -DFORMAT_ZIP \ + -DCOMPRESS_MT \ + -DCOMPRESS_BCJ_X86 \ + -DCOMPRESS_BCJ2 \ + -DCOMPRESS_BZIP2 \ + -DCOMPRESS_BZIP2_MT \ + -DCOMPRESS_COPY \ + -DCOMPRESS_DEFLATE \ + -DCOMPRESS_DEFLATE64 \ + -DCOMPRESS_IMPLODE \ + -DCOMPRESS_LZMA \ + -DCOMPRESS_MF_MT \ + -DCOMPRESS_PPMD \ + -DCRYPTO_7ZAES \ + -DCRYPTO_AES \ + -DCRYPTO_ZIP \ + + +CONSOLE_OBJS = \ + $O\ConsoleClose.obj \ + $O\ExtractCallbackConsole.obj \ + $O\List.obj \ + $O\Main.obj \ + $O\MainAr.obj \ + $O\OpenCallbackConsole.obj \ + $O\PercentPrinter.obj \ + $O\UpdateCallbackConsole.obj \ + $O\UserInputUtils.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CommandLineParser.obj \ + $O\CRC.obj \ + $O\IntToString.obj \ + $O\ListFileUtils.obj \ + $O\NewHandler.obj \ + $O\StdInStream.obj \ + $O\StdOutStream.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\UTFConvert.obj \ + $O\Vector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\Error.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\MemoryLock.obj \ + $O\PropVariant.obj \ + $O\PropVariantConversions.obj \ + $O\Synchronization.obj + +7ZIP_COMMON_OBJS = \ + $O\FilePathAutoRename.obj \ + $O\FileStreams.obj \ + $O\InBuffer.obj \ + $O\InOutTempBuffer.obj \ + $O\LimitedStreams.obj \ + $O\LockedStream.obj \ + $O\LSBFDecoder.obj \ + $O\LSBFEncoder.obj \ + $O\MemBlocks.obj \ + $O\OffsetStream.obj \ + $O\OutBuffer.obj \ + $O\OutMemStream.obj \ + $O\ProgressMt.obj \ + $O\ProgressUtils.obj \ + $O\StreamBinder.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveCommandLine.obj \ + $O\ArchiveExtractCallback.obj \ + $O\ArchiveOpenCallback.obj \ + $O\ArchiverInfo.obj \ + $O\DefaultName.obj \ + $O\EnumDirItems.obj \ + $O\Extract.obj \ + $O\ExtractingFilePath.obj \ + $O\OpenArchive.obj \ + $O\PropIDUtils.obj \ + $O\SetProperties.obj \ + $O\SortUtils.obj \ + $O\TempFiles.obj \ + $O\Update.obj \ + $O\UpdateAction.obj \ + $O\UpdateCallback.obj \ + $O\UpdatePair.obj \ + $O\UpdateProduce.obj \ + $O\WorkDir.obj \ + +AR_COMMON_OBJS = \ + $O\CoderMixer2.obj \ + $O\CoderMixer2MT.obj \ + $O\CrossThreadProgress.obj \ + $O\DummyOutStream.obj \ + $O\FilterCoder.obj \ + $O\InStreamWithCRC.obj \ + $O\ItemNameUtils.obj \ + $O\MultiStream.obj \ + $O\OutStreamWithCRC.obj \ + $O\ParseProperties.obj \ + + +7Z_OBJS = \ + $O\7zCompressionMode.obj \ + $O\7zDecode.obj \ + $O\7zEncode.obj \ + $O\7zExtract.obj \ + $O\7zFolderInStream.obj \ + $O\7zFolderOutStream.obj \ + $O\7zHandler.obj \ + $O\7zHandlerOut.obj \ + $O\7zHeader.obj \ + $O\7zIn.obj \ + $O\7zMethodID.obj \ + $O\7zOut.obj \ + $O\7zProperties.obj \ + $O\7zSpecStream.obj \ + $O\7zUpdate.obj \ + +BZ2_OBJS = \ + $O\BZip2Handler.obj \ + $O\BZip2HandlerOut.obj \ + $O\BZip2Update.obj \ + +CAB_OBJS = \ + $O\CabBlockInStream.obj \ + $O\CabHandler.obj \ + $O\CabHeader.obj \ + $O\CabIn.obj \ + +GZ_OBJS = \ + $O\GZipHandler.obj \ + $O\GZipHandlerOut.obj \ + $O\GZipHeader.obj \ + $O\GZipIn.obj \ + $O\GZipOut.obj \ + $O\GZipUpdate.obj \ + +SPLIT_OBJS = \ + $O\SplitHandler.obj \ + $O\SplitHandlerOut.obj \ + +TAR_OBJS = \ + $O\TarHandler.obj \ + $O\TarHandlerOut.obj \ + $O\TarHeader.obj \ + $O\TarIn.obj \ + $O\TarOut.obj \ + $O\TarUpdate.obj \ + +Z_OBJS = \ + $O\ZHandler.obj \ + +ZIP_OBJS = \ + $O\ZipAddCommon.obj \ + $O\ZipHandler.obj \ + $O\ZipHandlerOut.obj \ + $O\ZipHeader.obj \ + $O\ZipIn.obj \ + $O\ZipItem.obj \ + $O\ZipOut.obj \ + $O\ZipUpdate.obj \ + + +BRANCH_OPT_OBJS = \ + $O\BranchCoder.obj \ + $O\x86.obj \ + $O\x86_2.obj \ + +BZIP2_OBJS = \ + $O\BZip2CRC.obj \ + +BZIP2_OPT_OBJS = \ + $O\BZip2Decoder.obj \ + $O\BZip2Encoder.obj \ + +DEFLATE_OPT_OBJS = \ + $O\DeflateDecoder.obj \ + $O\DeflateEncoder.obj \ + +LZ_OBJS = \ + $O\LzOutWindow.obj \ + +LZMA_OPT_OBJS = \ + $O\LZMADecoder.obj \ + $O\LZMAEncoder.obj \ + +LZX_OBJS = \ + $O\LzxDecoder.obj \ + $O\Lzx86Converter.obj \ + +IMPLODE_OBJS = \ + $O\ImplodeDecoder.obj \ + $O\ImplodeHuffmanDecoder.obj \ + +PPMD_OPT_OBJS = \ + $O\PPMDDecoder.obj \ + $O\PPMDEncoder.obj \ + +SHRINK_OBJS = \ + $O\ShrinkDecoder.obj \ + +COMPRESS_Z_OBJS = \ + $O\ZDecoder.obj \ + + +7ZAES_OPT_OBJS = \ + $O\7zAES.obj \ + +AES_OPT_OBJS = \ + $O\MyAES.obj \ + +AES_ORIG_OBJS = \ + $O\aescrypt.obj \ + $O\aeskey.obj \ + $O\aestab.obj \ + +CRYPTO_HASH_OBJS = \ + $O\HmacSha1.obj \ + $O\Pbkdf2HmacSha1.obj \ + $O\RandGen.obj \ + $O\Sha1.obj \ + $O\Sha256.obj \ + +CRYPTO_WZAES_OBJS = \ + $O\WzAES.obj \ + +CRYPTO_ZIP_OBJS = \ + $O\ZipCipher.obj \ + $O\ZipCrypto.obj \ + +C_OBJS = \ + $O\7zCrc.obj \ + $O\Sort.obj \ + $O\Threads.obj \ + +C_LZ_OBJS = \ + $O\MatchFinder.obj \ + $O\MatchFinderMt.obj \ + + +OBJS = \ + $O\StdAfx.obj \ + $(CONSOLE_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(UI_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $(7Z_OBJS) \ + $(BZ2_OBJS) \ + $(CAB_OBJS) \ + $(GZ_OBJS) \ + $(SPLIT_OBJS) \ + $(TAR_OBJS) \ + $(Z_OBJS) \ + $(ZIP_OBJS) \ + $(BZIP2_OBJS) \ + $(BZIP2_OPT_OBJS) \ + $(BRANCH_OPT_OBJS) \ + $(DEFLATE_OPT_OBJS) \ + $(IMPLODE_OBJS) \ + $(LZ_OBJS) \ + $(LZMA_OPT_OBJS) \ + $(LZX_OBJS) \ + $(PPMD_OPT_OBJS) \ + $(SHRINK_OBJS) \ + $(COMPRESS_Z_OBJS) \ + $(C_OBJS) \ + $(C_LZ_OBJS) \ + $O\BlockSort.obj \ + $O\CopyCoder.obj \ + $O\HuffmanEncode.obj \ + $O\RangeCoderBit.obj \ + $(7ZAES_OPT_OBJS) \ + $(AES_OPT_OBJS) \ + $(AES_ORIG_OBJS) \ + $(CRYPTO_HASH_OBJS) \ + $(CRYPTO_ZIP_OBJS) \ + $(CRYPTO_WZAES_OBJS) \ + $O\QuantumDecoder.obj \ + $O\resource.res + + +!include "../../../Build.mak" + +$(CONSOLE_OBJS): ../../UI/Console/$(*B).cpp + $(COMPL) + +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp + $(COMPL) + +$(7Z_OBJS): ../../Archive/7z/$(*B).cpp + $(COMPL) +$(BZ2_OBJS): ../../Archive/BZip2/$(*B).cpp + $(COMPL) +$(CAB_OBJS): ../../Archive/Cab/$(*B).cpp + $(COMPL) +$(GZ_OBJS): ../../Archive/GZip/$(*B).cpp + $(COMPL) +$(SPLIT_OBJS): ../../Archive/Split/$(*B).cpp + $(COMPL) +$(TAR_OBJS): ../../Archive/Tar/$(*B).cpp + $(COMPL) +$(Z_OBJS): ../../Archive/Z/$(*B).cpp + $(COMPL) +$(ZIP_OBJS): ../../Archive/Zip/$(*B).cpp + $(COMPL) + +$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp + $(COMPL_O2) +$(BZIP2_OBJS): ../../Compress/BZip2/$(*B).cpp + $(COMPL) +$(BZIP2_OPT_OBJS): ../../Compress/BZip2/$(*B).cpp + $(COMPL_O2) +$(DEFLATE_OPT_OBJS): ../../Compress/Deflate/$(*B).cpp + $(COMPL_O2) +$(IMPLODE_OBJS): ../../Compress/Implode/$(*B).cpp + $(COMPL) +$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp + $(COMPL_O2) +$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp + $(COMPL_O2) +$(LZX_OBJS): ../../Compress/Lzx/$(*B).cpp + $(COMPL_O2) +$(PPMD_OPT_OBJS): ../../Compress/PPMD/$(*B).cpp + $(COMPL_O2) +$(SHRINK_OBJS): ../../Compress/Shrink/$(*B).cpp + $(COMPL) +$(COMPRESS_Z_OBJS): ../../Compress/Z/$(*B).cpp + $(COMPL) + +$O\BlockSort.obj: ../../Compress/BWT/$(*B).cpp + $(COMPL_O2) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) +$O\RangeCoderBit.obj: ../../Compress/RangeCoder/$(*B).cpp + $(COMPL) +$O\QuantumDecoder.obj: ../../Compress/Quantum/$(*B).cpp + $(COMPL) + +$(AES_OPT_OBJS): ../../Crypto/AES/$(*B).cpp + $(COMPL_O2) +$(AES_ORIG_OBJS): ../../Crypto/AES/$(*B).c + $(COMPL_O2_W3) +$(7ZAES_OPT_OBJS): ../../Crypto/7zAES/$(*B).cpp + $(COMPL_O2) +$(CRYPTO_HASH_OBJS): ../../Crypto/Hash/$(*B).cpp + $(COMPL_O2) +$(CRYPTO_ZIP_OBJS): ../../Crypto/Zip/$(*B).cpp + $(COMPL) +$(CRYPTO_WZAES_OBJS): ../../Crypto/WzAES/$(*B).cpp + $(COMPL_O2) + +$(C_OBJS): ../../../../C/$(*B).c + $(COMPL_O2) +$(C_LZ_OBJS): ../../../../C/Compress/Lz/$(*B).c + $(COMPL_O2) +$O\HuffmanEncode.obj: ../../../../C/Compress/Huffman/$(*B).c + $(COMPL_O2) diff --git a/CPP/7zip/Bundles/Alone/resource.rc b/CPP/7zip/Bundles/Alone/resource.rc new file mode 100755 index 00000000..fc9063c1 --- /dev/null +++ b/CPP/7zip/Bundles/Alone/resource.rc @@ -0,0 +1,3 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_APP("7-Zip Standalone Console", "7za") diff --git a/CPP/7zip/Bundles/Alone7z/Alone.dsp b/CPP/7zip/Bundles/Alone7z/Alone.dsp new file mode 100755 index 00000000..5ff71f2c --- /dev/null +++ b/CPP/7zip/Bundles/Alone7z/Alone.dsp @@ -0,0 +1,1358 @@ +# Microsoft Developer Studio Project File - Name="Alone" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=Alone - Win32 DebugU +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Alone.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Alone.mak" CFG="Alone - Win32 DebugU" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Alone - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "Alone - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "Alone - Win32 ReleaseU" (based on "Win32 (x86) Console Application") +!MESSAGE "Alone - Win32 DebugU" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Alone - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMFORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7zr.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMFORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7zr.exe" /pdbtype:sept + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ReleaseU" +# PROP BASE Intermediate_Dir "ReleaseU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseU" +# PROP Intermediate_Dir "ReleaseU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMFORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7za.exe" /opt:NOWIN98 +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7zr.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "DebugU" +# PROP BASE Intermediate_Dir "DebugU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugU" +# PROP Intermediate_Dir "DebugU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /W4 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMFORMAT_SPLIT" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7za.exe" /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7zr.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Alone - Win32 Release" +# Name "Alone - Win32 Debug" +# Name "Alone - Win32 ReleaseU" +# Name "Alone - Win32 DebugU" +# Begin Group "Console" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Console\ArError.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\CompressionMode.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\ConsoleClose.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\ConsoleClose.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\ExtractCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\ExtractCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\List.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\List.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\Main.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\MainAr.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\OpenCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\OpenCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\PercentPrinter.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\PercentPrinter.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\UpdateCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\UpdateCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\UserInputUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\UserInputUtils.h +# End Source File +# End Group +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\AlignedBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\AlignedBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\AutoPtr.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Buffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ComTry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynamicBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Exception.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyGuidDef.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyInitGuid.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyUnknown.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Random.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Random.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Types.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Device.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Handle.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Thread.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Time.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CrossThreadProgress.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InOutTempBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InOutTempBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LSBFDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LSBFDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LSBFEncoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LSBFEncoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MSBFDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MSBFEncoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OffsetStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OffsetStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressMt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressMt.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Group "Branch" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Branch\BranchCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\BranchCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\Coder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86_2.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86_2.h +# End Source File +# End Group +# Begin Group "Copy" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "LZ" + +# PROP Default_Filter "" +# Begin Group "MT" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZ\MT\MT.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\MT\MT.h +# End Source File +# End Group +# Begin Group "HC" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZ\HashChain\HC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\HashChain\HC2.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\HashChain\HC3.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\HashChain\HC4.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\HashChain\HC4b.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\HashChain\HCMain.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\Compress\LZ\IMatchFinder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZInWindow.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O1 + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O1 + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZInWindow.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O1 + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O1 + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.h +# End Source File +# End Group +# Begin Group "LZMA" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZMA\LZMA.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZMA\LZMADecoder.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZMA\LZMADecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZMA\LZMAEncoder.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZMA\LZMAEncoder.h +# End Source File +# End Group +# Begin Group "RangeCoder" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O1 + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O1 + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoderBitTree.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoderOpt.h +# End Source File +# End Group +# End Group +# Begin Group "Archive" + +# PROP Default_Filter "" +# Begin Group "7z" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\7z\7zCompressionMode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zCompressionMode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zEncode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zEncode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zExtract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethodID.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethodID.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zOut.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zProperties.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zSpecStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zSpecStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zUpdate.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zUpdate.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2MT.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2ST.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2ST.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\DummyOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\DummyOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\InStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\InStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\MultiStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\MultiStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ParseProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ParseProperties.h +# End Source File +# End Group +# Begin Group "split" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Split\SplitHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Split\SplitHandler.h +# End Source File +# End Group +# End Group +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveCommandLine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveCommandLine.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiverInfo.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiverInfo.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\EnumDirItems.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\EnumDirItems.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Extract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Extract.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractingFilePath.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractingFilePath.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\OpenArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\OpenArchive.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\PropIDUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\PropIDUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\SetProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\SetProperties.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\SortUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\SortUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\TempFiles.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\TempFiles.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Update.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Update.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateAction.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateAction.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdatePair.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdatePair.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateProduce.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateProduce.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\WorkDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\WorkDir.h +# End Source File +# End Group +# Begin Group "7-zip" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IMyUnknown.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# Begin Source File + +SOURCE=..\..\IStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\PropID.h +# End Source File +# End Group +# End Target +# End Project diff --git a/CPP/7zip/Bundles/Alone7z/Alone.dsw b/CPP/7zip/Bundles/Alone7z/Alone.dsw new file mode 100755 index 00000000..65eca43f --- /dev/null +++ b/CPP/7zip/Bundles/Alone7z/Alone.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Alone"=.\Alone.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Bundles/Alone7z/StdAfx.cpp b/CPP/7zip/Bundles/Alone7z/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Bundles/Alone7z/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Bundles/Alone7z/StdAfx.h b/CPP/7zip/Bundles/Alone7z/StdAfx.h new file mode 100755 index 00000000..2e4be10b --- /dev/null +++ b/CPP/7zip/Bundles/Alone7z/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" +#include "../../../Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/Bundles/Alone7z/makefile b/CPP/7zip/Bundles/Alone7z/makefile new file mode 100755 index 00000000..9bec8059 --- /dev/null +++ b/CPP/7zip/Bundles/Alone7z/makefile @@ -0,0 +1,196 @@ +PROG = 7za.exe +LIBS = $(LIBS) user32.lib oleaut32.lib Advapi32.lib + +CFLAGS = $(CFLAGS) -I ../../../ \ + -DEXCLUDE_COM \ + -DNO_REGISTRY \ + -D_NO_CRYPTO \ + -DWIN_LONG_PATH \ + -DFORMAT_7Z \ + -DCOMPRESS_MT \ + -DCOMPRESS_BCJ_X86 \ + -DCOMPRESS_BCJ2 \ + -DCOMPRESS_COPY \ + -DCOMPRESS_LZMA \ + -DCOMPRESS_MF_MT \ + -D_NO_CRYPTO + + +CONSOLE_OBJS = \ + $O\ConsoleClose.obj \ + $O\ExtractCallbackConsole.obj \ + $O\List.obj \ + $O\Main.obj \ + $O\MainAr.obj \ + $O\OpenCallbackConsole.obj \ + $O\PercentPrinter.obj \ + $O\UpdateCallbackConsole.obj \ + $O\UserInputUtils.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CommandLineParser.obj \ + $O\CRC.obj \ + $O\IntToString.obj \ + $O\ListFileUtils.obj \ + $O\NewHandler.obj \ + $O\StdInStream.obj \ + $O\StdOutStream.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\UTFConvert.obj \ + $O\Vector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\Error.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\MemoryLock.obj \ + $O\PropVariant.obj \ + $O\PropVariantConversions.obj \ + $O\Synchronization.obj + +7ZIP_COMMON_OBJS = \ + $O\FilePathAutoRename.obj \ + $O\FileStreams.obj \ + $O\InBuffer.obj \ + $O\InOutTempBuffer.obj \ + $O\LimitedStreams.obj \ + $O\LockedStream.obj \ + $O\OffsetStream.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\StreamBinder.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveCommandLine.obj \ + $O\ArchiveExtractCallback.obj \ + $O\ArchiveOpenCallback.obj \ + $O\ArchiverInfo.obj \ + $O\DefaultName.obj \ + $O\EnumDirItems.obj \ + $O\Extract.obj \ + $O\ExtractingFilePath.obj \ + $O\OpenArchive.obj \ + $O\PropIDUtils.obj \ + $O\SetProperties.obj \ + $O\SortUtils.obj \ + $O\TempFiles.obj \ + $O\Update.obj \ + $O\UpdateAction.obj \ + $O\UpdateCallback.obj \ + $O\UpdatePair.obj \ + $O\UpdateProduce.obj \ + $O\WorkDir.obj \ + +AR_COMMON_OBJS = \ + $O\CoderMixer2.obj \ + $O\CoderMixer2MT.obj \ + $O\CrossThreadProgress.obj \ + $O\DummyOutStream.obj \ + $O\FilterCoder.obj \ + $O\InStreamWithCRC.obj \ + $O\ItemNameUtils.obj \ + $O\MultiStream.obj \ + $O\OutStreamWithCRC.obj \ + $O\ParseProperties.obj \ + + +7Z_OBJS = \ + $O\7zCompressionMode.obj \ + $O\7zDecode.obj \ + $O\7zEncode.obj \ + $O\7zExtract.obj \ + $O\7zFolderInStream.obj \ + $O\7zFolderOutStream.obj \ + $O\7zHandler.obj \ + $O\7zHandlerOut.obj \ + $O\7zHeader.obj \ + $O\7zIn.obj \ + $O\7zMethodID.obj \ + $O\7zOut.obj \ + $O\7zProperties.obj \ + $O\7zSpecStream.obj \ + $O\7zUpdate.obj \ + + +BRANCH_OPT_OBJS = \ + $O\BranchCoder.obj \ + $O\x86.obj \ + $O\x86_2.obj \ + +LZ_OBJS = \ + $O\LZOutWindow.obj \ + +LZMA_OPT_OBJS = \ + $O\LZMADecoder.obj \ + $O\LZMAEncoder.obj \ + +C_OBJS = \ + $O\7zCrc.obj \ + $O\Sort.obj \ + $O\Threads.obj \ + +C_LZ_OBJS = \ + $O\MatchFinder.obj \ + $O\MatchFinderMt.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(CONSOLE_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(UI_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $(7Z_OBJS) \ + $(BRANCH_OPT_OBJS) \ + $(LZ_OBJS) \ + $(LZMA_OPT_OBJS) \ + $(C_OBJS) \ + $(C_LZ_OBJS) \ + $O\CopyCoder.obj \ + $O\RangeCoderBit.obj \ + $O\resource.res + + +!include "../../../Build.mak" + +$(CONSOLE_OBJS): ../../UI/Console/$(*B).cpp + $(COMPL) + +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp + $(COMPL) + +$(7Z_OBJS): ../../Archive/7z/$(*B).cpp + $(COMPL) +$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp + $(COMPL_O2) +$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp + $(COMPL) +$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp + $(COMPL_O2) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) +$O\RangeCoderBit.obj: ../../Compress/RangeCoder/$(*B).cpp + $(COMPL) + +$(C_OBJS): ../../../../C/$(*B).c + $(COMPL_O2) +$(C_LZ_OBJS): ../../../../C/Compress/Lz/$(*B).c + $(COMPL_O2) diff --git a/CPP/7zip/Bundles/Alone7z/resource.rc b/CPP/7zip/Bundles/Alone7z/resource.rc new file mode 100755 index 00000000..fc9063c1 --- /dev/null +++ b/CPP/7zip/Bundles/Alone7z/resource.rc @@ -0,0 +1,3 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_APP("7-Zip Standalone Console", "7za") diff --git a/CPP/7zip/Bundles/Format7z/Format7z.dsp b/CPP/7zip/Bundles/Format7z/Format7z.dsp new file mode 100755 index 00000000..a59cd581 --- /dev/null +++ b/CPP/7zip/Bundles/Format7z/Format7z.dsp @@ -0,0 +1,1006 @@ +# Microsoft Developer Studio Project File - Name="7z" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=7z - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Format7z.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Format7z.mak" CFG="7z - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "7z - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "7z - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "7z - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE_DECODER" /D "COMPRESS_BZIP2_DECODER" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /D "COMPRESS_MT" /D "COMPRESS_BZIP2_MT" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\7za.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none /debug + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\..\SDK" /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE_DECODER" /D "COMPRESS_BZIP2_DECODER" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /D "COMPRESS_MT" /D "COMPRESS_BZIP2_MT" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\7za.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "7z - Win32 Release" +# Name "7z - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\7z\7z.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Archive.def +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# End Group +# Begin Group "Archive common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2MT.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CrossThreadProgress.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\InStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\InStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ParseProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ParseProperties.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Group "LZ" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.h +# End Source File +# End Group +# Begin Group "PPMD" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDContext.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDDecode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDDecoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDEncode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDEncoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDEncoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDSubAlloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDType.h +# End Source File +# End Group +# Begin Group "Branch" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Branch\BranchCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\BranchCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86_2.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86_2.h +# End Source File +# End Group +# Begin Group "LZMA" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZMA\LZMA.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZMA\LZMADecoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZMA\LZMADecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZMA\LZMAEncoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZMA\LZMAEncoder.h +# End Source File +# End Group +# Begin Group "Copy" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "RangeCoder" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoderBitTree.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoderOpt.h +# End Source File +# End Group +# Begin Group "Deflate" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Deflate\DeflateConst.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Deflate\DeflateDecoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Deflate\DeflateDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Deflate\DeflateExtConst.h +# End Source File +# End Group +# Begin Group "BZip2" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\BZip2\BZip2Const.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2\BZip2CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2\BZip2CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2\BZip2Decoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2\BZip2Decoder.h +# End Source File +# End Group +# End Group +# Begin Group "Crypto" + +# PROP Default_Filter "" +# Begin Group "AES" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\AES\aes.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\AES_CBC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aescpp.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aescrypt.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aeskey.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aesopt.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aestab.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\MyAES.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\MyAES.h +# End Source File +# End Group +# Begin Group "7zAES" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\7zAES\7zAES.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\7zAES\7zAES.h +# End Source File +# End Group +# Begin Group "Hash" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\Hash\Sha256.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Hash\Sha256.h +# End Source File +# End Group +# End Group +# Begin Group "7z" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\7z\7zCompressionMode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zCompressionMode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zEncode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zEncode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zExtract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethodID.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethodID.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethods.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zOut.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zProperties.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zSpecStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zSpecStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zUpdate.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zUpdate.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zUpdateItem.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InOutTempBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InOutTempBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LSBFDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LSBFDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Group "C-Lz" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Lz\LzHash.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Lz\MatchFinderMt.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Lz\MatchFinderMt.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.h +# End Source File +# End Group +# End Target +# End Project diff --git a/CPP/7zip/Bundles/Format7z/Format7z.dsw b/CPP/7zip/Bundles/Format7z/Format7z.dsw new file mode 100755 index 00000000..324dab1f --- /dev/null +++ b/CPP/7zip/Bundles/Format7z/Format7z.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "7z"=.\Format7z.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Bundles/Format7z/StdAfx.cpp b/CPP/7zip/Bundles/Format7z/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Bundles/Format7z/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Bundles/Format7z/StdAfx.h b/CPP/7zip/Bundles/Format7z/StdAfx.h new file mode 100755 index 00000000..2e4be10b --- /dev/null +++ b/CPP/7zip/Bundles/Format7z/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" +#include "../../../Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/Bundles/Format7z/makefile b/CPP/7zip/Bundles/Format7z/makefile new file mode 100755 index 00000000..1134faee --- /dev/null +++ b/CPP/7zip/Bundles/Format7z/makefile @@ -0,0 +1,201 @@ +PROG = 7za.dll +DEF_FILE = ../../Archive/Archive.def +LIBS = $(LIBS) user32.lib oleaut32.lib +CFLAGS = $(CFLAGS) -I ../../../ \ + -DEXCLUDE_COM \ + -DNO_REGISTRY \ + -DFORMAT_7Z \ + -DCOMPRESS_MT \ + -DCOMPRESS_BCJ_X86 \ + -DCOMPRESS_BCJ2 \ + -DCOMPRESS_BZIP2_DECODER \ + -DCOMPRESS_BZIP2_MT \ + -DCOMPRESS_COPY \ + -DCOMPRESS_DEFLATE_DECODER \ + -DCOMPRESS_LZMA \ + -DCOMPRESS_MF_MT \ + -DCOMPRESS_PPMD \ + -DCRYPTO_7ZAES \ + -DCRYPTO_AES \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CRC.obj \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\Vector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\PropVariant.obj \ + $O\Synchronization.obj + +7ZIP_COMMON_OBJS = \ + $O\InBuffer.obj \ + $O\InOutTempBuffer.obj \ + $O\LimitedStreams.obj \ + $O\LockedStream.obj \ + $O\LSBFDecoder.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\StreamBinder.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + +AR_COMMON_OBJS = \ + $O\CoderMixer2.obj \ + $O\CoderMixer2MT.obj \ + $O\CrossThreadProgress.obj \ + $O\FilterCoder.obj \ + $O\InStreamWithCRC.obj \ + $O\ItemNameUtils.obj \ + $O\OutStreamWithCRC.obj \ + $O\ParseProperties.obj \ + + +7Z_OBJS = \ + $O\DllExports.obj \ + $O\7zCompressionMode.obj \ + $O\7zDecode.obj \ + $O\7zEncode.obj \ + $O\7zExtract.obj \ + $O\7zFolderInStream.obj \ + $O\7zFolderOutStream.obj \ + $O\7zHandler.obj \ + $O\7zHandlerOut.obj \ + $O\7zHeader.obj \ + $O\7zIn.obj \ + $O\7zMethodID.obj \ + $O\7zOut.obj \ + $O\7zProperties.obj \ + $O\7zSpecStream.obj \ + $O\7zUpdate.obj \ + + +BRANCH_OPT_OBJS = \ + $O\BranchCoder.obj \ + $O\x86.obj \ + $O\x86_2.obj \ + +BZIP2_OBJS = \ + $O\BZip2CRC.obj \ + +BZIP2_OPT_OBJS = \ + $O\BZip2Decoder.obj \ + +DEFLATE_OPT_OBJS = \ + $O\DeflateDecoder.obj \ + +LZ_OBJS = \ + $O\LZOutWindow.obj \ + +LZMA_OPT_OBJS = \ + $O\LZMADecoder.obj \ + $O\LZMAEncoder.obj \ + +PPMD_OPT_OBJS = \ + $O\PPMDDecoder.obj \ + $O\PPMDEncoder.obj \ + + +7ZAES_OPT_OBJS = \ + $O\7zAES.obj \ + +AES_OPT_OBJS = \ + $O\MyAES.obj \ + +AES_ORIG_OBJS = \ + $O\aescrypt.obj \ + $O\aeskey.obj \ + $O\aestab.obj \ + +CRYPTO_HASH_OBJS = \ + $O\Sha256.obj \ + +C_OBJS = \ + $O\7zCrc.obj \ + $O\Threads.obj \ + +C_LZ_OBJS = \ + $O\MatchFinder.obj \ + $O\MatchFinderMt.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(CONSOLE_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $(7Z_OBJS) \ + $(BZIP2_OBJS) \ + $(BZIP2_OPT_OBJS) \ + $(BRANCH_OPT_OBJS) \ + $(DEFLATE_OPT_OBJS) \ + $(LZ_OBJS) \ + $(LZMA_OPT_OBJS) \ + $(PPMD_OPT_OBJS) \ + $(C_OBJS) \ + $(C_LZ_OBJS) \ + $O\CopyCoder.obj \ + $O\RangeCoderBit.obj \ + $(7ZAES_OPT_OBJS) \ + $(AES_OPT_OBJS) \ + $(AES_ORIG_OBJS) \ + $(CRYPTO_HASH_OBJS) \ + $O\resource.res + + +!include "../../../Build.mak" + +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp + $(COMPL) + +$(7Z_OBJS): ../../Archive/7z/$(*B).cpp + $(COMPL) + +$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp + $(COMPL_O2) +$(BZIP2_OBJS): ../../Compress/BZip2/$(*B).cpp + $(COMPL) +$(BZIP2_OPT_OBJS): ../../Compress/BZip2/$(*B).cpp + $(COMPL_O2) +$(DEFLATE_OPT_OBJS): ../../Compress/Deflate/$(*B).cpp + $(COMPL_O2) +$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp + $(COMPL) +$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp + $(COMPL_O2) +$(PPMD_OPT_OBJS): ../../Compress/PPMD/$(*B).cpp + $(COMPL_O2) + +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) +$O\RangeCoderBit.obj: ../../Compress/RangeCoder/$(*B).cpp + $(COMPL) + +$(AES_OPT_OBJS): ../../Crypto/AES/$(*B).cpp + $(COMPL_O2) +$(AES_ORIG_OBJS): ../../Crypto/AES/$(*B).c + $(COMPL_O2_W3) +$(7ZAES_OPT_OBJS): ../../Crypto/7zAES/$(*B).cpp + $(COMPL_O2) +$(CRYPTO_HASH_OBJS): ../../Crypto/Hash/$(*B).cpp + $(COMPL_O2) + +$(C_OBJS): ../../../../C/$(*B).c + $(COMPL_O2) +$(C_LZ_OBJS): ../../../../C/Compress/Lz/$(*B).c + $(COMPL_O2) diff --git a/CPP/7zip/Bundles/Format7z/resource.rc b/CPP/7zip/Bundles/Format7z/resource.rc new file mode 100755 index 00000000..5b3f363e --- /dev/null +++ b/CPP/7zip/Bundles/Format7z/resource.rc @@ -0,0 +1,5 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("7z Standalone Plugin", "7za") + +101 ICON "../../Archive/7z/7z.ico" diff --git a/CPP/7zip/Bundles/Format7zExtract/Format7z.dsp b/CPP/7zip/Bundles/Format7zExtract/Format7z.dsp new file mode 100755 index 00000000..d049d00c --- /dev/null +++ b/CPP/7zip/Bundles/Format7zExtract/Format7z.dsp @@ -0,0 +1,813 @@ +# Microsoft Developer Studio Project File - Name="7z" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=7z - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Format7z.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Format7z.mak" CFG="7z - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "7z - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "7z - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "7z - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "EXTRACT_ONLY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE_DECODER" /D "COMPRESS_BZIP2_DECODER" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /D "COMPRESS_MT" /D "COMPRESS_BZIP2_MT" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\7zxa.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none /debug + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\..\SDK" /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "EXTRACT_ONLY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_MT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE_DECODER" /D "COMPRESS_BZIP2_DECODER" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /D "COMPRESS_MT" /D "COMPRESS_BZIP2_MT" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\7zxa.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "7z - Win32 Release" +# Name "7z - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\7z\7z.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Archive.def +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# End Group +# Begin Group "Archive common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2MT.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CrossThreadProgress.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ParseProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ParseProperties.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Group "LZ" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.h +# End Source File +# End Group +# Begin Group "PPMD" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDContext.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDDecode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDDecoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDSubAlloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDType.h +# End Source File +# End Group +# Begin Group "Branch" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Branch\BranchCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\BranchCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86_2.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86_2.h +# End Source File +# End Group +# Begin Group "LZMA" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZMA\LZMA.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZMA\LZMADecoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZMA\LZMADecoder.h +# End Source File +# End Group +# Begin Group "Copy" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "RangeCoder" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoderBitTree.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder\RangeCoderOpt.h +# End Source File +# End Group +# Begin Group "Deflate" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Deflate\DeflateConst.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Deflate\DeflateDecoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Deflate\DeflateDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Deflate\DeflateExtConst.h +# End Source File +# End Group +# Begin Group "BZip2" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\BZip2\BZip2Const.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2\BZip2CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2\BZip2CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2\BZip2Decoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2\BZip2Decoder.h +# End Source File +# End Group +# End Group +# Begin Group "Crypto" + +# PROP Default_Filter "" +# Begin Group "AES" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\AES\aes.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\AES_CBC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aescpp.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aescrypt.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aeskey.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aesopt.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aestab.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\MyAES.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\MyAES.h +# End Source File +# End Group +# Begin Group "7zAES" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\7zAES\7zAES.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\7zAES\7zAES.h +# End Source File +# End Group +# Begin Group "Hash" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\Hash\Sha256.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Hash\Sha256.h +# End Source File +# End Group +# End Group +# Begin Group "7z" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zExtract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethodID.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethodID.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethods.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zProperties.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LSBFDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LSBFDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# End Target +# End Project diff --git a/CPP/7zip/Bundles/Format7zExtract/Format7z.dsw b/CPP/7zip/Bundles/Format7zExtract/Format7z.dsw new file mode 100755 index 00000000..324dab1f --- /dev/null +++ b/CPP/7zip/Bundles/Format7zExtract/Format7z.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "7z"=.\Format7z.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Bundles/Format7zExtract/StdAfx.cpp b/CPP/7zip/Bundles/Format7zExtract/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Bundles/Format7zExtract/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Bundles/Format7zExtract/StdAfx.h b/CPP/7zip/Bundles/Format7zExtract/StdAfx.h new file mode 100755 index 00000000..2e4be10b --- /dev/null +++ b/CPP/7zip/Bundles/Format7zExtract/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" +#include "../../../Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/Bundles/Format7zExtract/makefile b/CPP/7zip/Bundles/Format7zExtract/makefile new file mode 100755 index 00000000..e52ab019 --- /dev/null +++ b/CPP/7zip/Bundles/Format7zExtract/makefile @@ -0,0 +1,174 @@ +PROG = 7zxa.dll +DEF_FILE = ../../Archive/Archive.def +LIBS = $(LIBS) user32.lib oleaut32.lib +CFLAGS = $(CFLAGS) -I ../../../ \ + -DEXCLUDE_COM \ + -DNO_REGISTRY \ + -DEXTRACT_ONLY \ + -DFORMAT_7Z \ + -DCOMPRESS_MT \ + -DCOMPRESS_BCJ_X86 \ + -DCOMPRESS_BCJ2 \ + -DCOMPRESS_BZIP2_DECODER \ + -DCOMPRESS_BZIP2_MT \ + -DCOMPRESS_COPY \ + -DCOMPRESS_DEFLATE_DECODER \ + -DCOMPRESS_LZMA \ + -DCOMPRESS_PPMD \ + -DCRYPTO_7ZAES \ + -DCRYPTO_AES \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CRC.obj \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\Vector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\PropVariant.obj \ + $O\Synchronization.obj + +7ZIP_COMMON_OBJS = \ + $O\InBuffer.obj \ + $O\InOutTempBuffer.obj \ + $O\LimitedStreams.obj \ + $O\LockedStream.obj \ + $O\LSBFDecoder.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\StreamBinder.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + +AR_COMMON_OBJS = \ + $O\CoderMixer2.obj \ + $O\CoderMixer2MT.obj \ + $O\CrossThreadProgress.obj \ + $O\FilterCoder.obj \ + $O\ItemNameUtils.obj \ + $O\OutStreamWithCRC.obj \ + $O\ParseProperties.obj \ + + +7Z_OBJS = \ + $O\DllExports.obj \ + $O\7zCompressionMode.obj \ + $O\7zDecode.obj \ + $O\7zExtract.obj \ + $O\7zFolderOutStream.obj \ + $O\7zHandler.obj \ + $O\7zHeader.obj \ + $O\7zIn.obj \ + $O\7zMethodID.obj \ + $O\7zProperties.obj \ + + +BRANCH_OPT_OBJS = \ + $O\BranchCoder.obj \ + $O\x86.obj \ + $O\x86_2.obj \ + +BZIP2_OBJS = \ + $O\BZip2CRC.obj \ + +BZIP2_OPT_OBJS = \ + $O\BZip2Decoder.obj \ + +DEFLATE_OPT_OBJS = \ + $O\DeflateDecoder.obj \ + +LZ_OBJS = \ + $O\LZOutWindow.obj \ + +LZMA_OPT_OBJS = \ + $O\LZMADecoder.obj \ + +PPMD_OPT_OBJS = \ + $O\PPMDDecoder.obj \ + + +7ZAES_OPT_OBJS = \ + $O\7zAES.obj \ + +AES_OPT_OBJS = \ + $O\MyAES.obj \ + +AES_ORIG_OBJS = \ + $O\aescrypt.obj \ + $O\aeskey.obj \ + $O\aestab.obj \ + +CRYPTO_HASH_OBJS = \ + $O\Sha256.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(CONSOLE_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $(7Z_OBJS) \ + $(BZIP2_OBJS) \ + $(BZIP2_OPT_OBJS) \ + $(BRANCH_OPT_OBJS) \ + $(DEFLATE_OPT_OBJS) \ + $(LZ_OBJS) \ + $(LZMA_OPT_OBJS) \ + $(PPMD_OPT_OBJS) \ + $O\CopyCoder.obj \ + $(7ZAES_OPT_OBJS) \ + $(AES_OPT_OBJS) \ + $(AES_ORIG_OBJS) \ + $(CRYPTO_HASH_OBJS) \ + $O\resource.res + + +!include "../../../Build.mak" + +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp + $(COMPL) + +$(7Z_OBJS): ../../Archive/7z/$(*B).cpp + $(COMPL) + +$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp + $(COMPL_O2) +$(BZIP2_OBJS): ../../Compress/BZip2/$(*B).cpp + $(COMPL) +$(BZIP2_OPT_OBJS): ../../Compress/BZip2/$(*B).cpp + $(COMPL_O2) +$(DEFLATE_OPT_OBJS): ../../Compress/Deflate/$(*B).cpp + $(COMPL_O2) +$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp + $(COMPL) +$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp + $(COMPL_O2) +$(PPMD_OPT_OBJS): ../../Compress/PPMD/$(*B).cpp + $(COMPL_O2) + +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) + +$(AES_OPT_OBJS): ../../Crypto/AES/$(*B).cpp + $(COMPL_O2) +$(AES_ORIG_OBJS): ../../Crypto/AES/$(*B).c + $(COMPL_O2_W3) +$(7ZAES_OPT_OBJS): ../../Crypto/7zAES/$(*B).cpp + $(COMPL_O2) +$(CRYPTO_HASH_OBJS): ../../Crypto/Hash/$(*B).cpp + $(COMPL_O2) diff --git a/CPP/7zip/Bundles/Format7zExtract/resource.rc b/CPP/7zip/Bundles/Format7zExtract/resource.rc new file mode 100755 index 00000000..56e6b5d7 --- /dev/null +++ b/CPP/7zip/Bundles/Format7zExtract/resource.rc @@ -0,0 +1,5 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("7z Standalone Extracting Plugin", "7zxa") + +101 ICON "../../Archive/7z/7z.ico" diff --git a/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp b/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h b/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h new file mode 100755 index 00000000..2e4be10b --- /dev/null +++ b/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" +#include "../../../Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/Bundles/Format7zExtractR/makefile b/CPP/7zip/Bundles/Format7zExtractR/makefile new file mode 100755 index 00000000..b8bfde85 --- /dev/null +++ b/CPP/7zip/Bundles/Format7zExtractR/makefile @@ -0,0 +1,117 @@ +PROG = 7zxr.dll +DEF_FILE = ../../Archive/Archive.def +LIBS = $(LIBS) user32.lib oleaut32.lib +CFLAGS = $(CFLAGS) -I ../../../ \ + -DEXCLUDE_COM \ + -DNO_REGISTRY \ + -DEXTRACT_ONLY \ + -DFORMAT_7Z \ + -DCOMPRESS_MT \ + -DCOMPRESS_BCJ_X86 \ + -DCOMPRESS_BCJ2 \ + -DCOMPRESS_COPY \ + -DCOMPRESS_LZMA \ + -D_NO_CRYPTO + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CRC.obj \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\Vector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\PropVariant.obj \ + $O\Synchronization.obj + +7ZIP_COMMON_OBJS = \ + $O\InBuffer.obj \ + $O\InOutTempBuffer.obj \ + $O\LimitedStreams.obj \ + $O\LockedStream.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\StreamBinder.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + +AR_COMMON_OBJS = \ + $O\CoderMixer2.obj \ + $O\CoderMixer2MT.obj \ + $O\CrossThreadProgress.obj \ + $O\FilterCoder.obj \ + $O\ItemNameUtils.obj \ + $O\OutStreamWithCRC.obj \ + $O\ParseProperties.obj \ + + +7Z_OBJS = \ + $O\DllExports.obj \ + $O\7zCompressionMode.obj \ + $O\7zDecode.obj \ + $O\7zExtract.obj \ + $O\7zFolderOutStream.obj \ + $O\7zHandler.obj \ + $O\7zHeader.obj \ + $O\7zIn.obj \ + $O\7zMethodID.obj \ + $O\7zProperties.obj \ + + +BRANCH_OPT_OBJS = \ + $O\BranchCoder.obj \ + $O\x86.obj \ + $O\x86_2.obj \ + +LZ_OBJS = \ + $O\LZOutWindow.obj \ + +LZMA_OPT_OBJS = \ + $O\LZMADecoder.obj \ + + +OBJS = \ + $O\StdAfx.obj \ + $(CONSOLE_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $(7Z_OBJS) \ + $(BRANCH_OPT_OBJS) \ + $(LZ_OBJS) \ + $(LZMA_OPT_OBJS) \ + $O\CopyCoder.obj \ + $O\resource.res + + +!include "../../../Build.mak" + +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp + $(COMPL) + +$(7Z_OBJS): ../../Archive/7z/$(*B).cpp + $(COMPL) + +$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp + $(COMPL_O2) +$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp + $(COMPL) +$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp + $(COMPL_O2) + +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/Bundles/Format7zExtractR/resource.rc b/CPP/7zip/Bundles/Format7zExtractR/resource.rc new file mode 100755 index 00000000..09708cff --- /dev/null +++ b/CPP/7zip/Bundles/Format7zExtractR/resource.rc @@ -0,0 +1,5 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("7z Standalone Extracting Plugin", "7zxr") + +101 ICON "../../Archive/7z/7z.ico" diff --git a/CPP/7zip/Bundles/Format7zR/StdAfx.cpp b/CPP/7zip/Bundles/Format7zR/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Bundles/Format7zR/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Bundles/Format7zR/StdAfx.h b/CPP/7zip/Bundles/Format7zR/StdAfx.h new file mode 100755 index 00000000..2e4be10b --- /dev/null +++ b/CPP/7zip/Bundles/Format7zR/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" +#include "../../../Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/Bundles/Format7zR/makefile b/CPP/7zip/Bundles/Format7zR/makefile new file mode 100755 index 00000000..d3cc3d55 --- /dev/null +++ b/CPP/7zip/Bundles/Format7zR/makefile @@ -0,0 +1,150 @@ +PROG = 7zra.dll +DEF_FILE = ../../Archive/Archive.def +LIBS = $(LIBS) user32.lib oleaut32.lib +CFLAGS = $(CFLAGS) -I ../../../ \ + -DEXCLUDE_COM \ + -DNO_REGISTRY \ + -DFORMAT_7Z \ + -DCOMPRESS_MT \ + -DCOMPRESS_BCJ_X86 \ + -DCOMPRESS_BCJ2 \ + -DCOMPRESS_COPY \ + -DCOMPRESS_LZMA \ + -DCOMPRESS_MF_MT \ + -D_NO_CRYPTO + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CRC.obj \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\Vector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\PropVariant.obj \ + $O\Synchronization.obj + +7ZIP_COMMON_OBJS = \ + $O\InBuffer.obj \ + $O\InOutTempBuffer.obj \ + $O\LimitedStreams.obj \ + $O\LockedStream.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\StreamBinder.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + +AR_COMMON_OBJS = \ + $O\CoderMixer2.obj \ + $O\CoderMixer2MT.obj \ + $O\CrossThreadProgress.obj \ + $O\FilterCoder.obj \ + $O\InStreamWithCRC.obj \ + $O\ItemNameUtils.obj \ + $O\OutStreamWithCRC.obj \ + $O\ParseProperties.obj \ + + +7Z_OBJS = \ + $O\DllExports.obj \ + $O\7zCompressionMode.obj \ + $O\7zDecode.obj \ + $O\7zEncode.obj \ + $O\7zExtract.obj \ + $O\7zFolderInStream.obj \ + $O\7zFolderOutStream.obj \ + $O\7zHandler.obj \ + $O\7zHandlerOut.obj \ + $O\7zHeader.obj \ + $O\7zIn.obj \ + $O\7zMethodID.obj \ + $O\7zOut.obj \ + $O\7zProperties.obj \ + $O\7zSpecStream.obj \ + $O\7zUpdate.obj \ + + +BRANCH_OPT_OBJS = \ + $O\BranchCoder.obj \ + $O\x86.obj \ + $O\x86_2.obj \ + +LZ_OBJS = \ + $O\LZOutWindow.obj \ + +LZMA_OPT_OBJS = \ + $O\LZMADecoder.obj \ + $O\LZMAEncoder.obj \ + +C_OBJS = \ + $O\7zCrc.obj \ + $O\Sort.obj \ + $O\Threads.obj \ + +C_LZ_OBJS = \ + $O\MatchFinder.obj \ + $O\MatchFinderMt.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(CONSOLE_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $(7Z_OBJS) \ + $(BZIP2_OBJS) \ + $(BZIP2_OPT_OBJS) \ + $(BRANCH_OPT_OBJS) \ + $(DEFLATE_OPT_OBJS) \ + $(LZ_OBJS) \ + $(LZMA_OPT_OBJS) \ + $(PPMD_OPT_OBJS) \ + $(C_OBJS) \ + $(C_LZ_OBJS) \ + $O\CopyCoder.obj \ + $O\RangeCoderBit.obj \ + $(7ZAES_OPT_OBJS) \ + $(AES_OPT_OBJS) \ + $(AES_ORIG_OBJS) \ + $(CRYPTO_HASH_OBJS) \ + $O\resource.res + + +!include "../../../Build.mak" + +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp + $(COMPL) + +$(7Z_OBJS): ../../Archive/7z/$(*B).cpp + $(COMPL) + +$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp + $(COMPL_O2) +$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp + $(COMPL) +$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp + $(COMPL_O2) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) +$O\RangeCoderBit.obj: ../../Compress/RangeCoder/$(*B).cpp + $(COMPL) + +$(C_OBJS): ../../../../C/$(*B).c + $(COMPL_O2) +$(C_LZ_OBJS): ../../../../C/Compress/Lz/$(*B).c + $(COMPL_O2) diff --git a/CPP/7zip/Bundles/Format7zR/resource.rc b/CPP/7zip/Bundles/Format7zR/resource.rc new file mode 100755 index 00000000..60a17fe8 --- /dev/null +++ b/CPP/7zip/Bundles/Format7zR/resource.rc @@ -0,0 +1,5 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("7z Standalone Plugin", "7zr") + +101 ICON "../../Archive/7z/7z.ico" diff --git a/CPP/7zip/Bundles/SFXCon/7z.ico b/CPP/7zip/Bundles/SFXCon/7z.ico new file mode 100755 index 00000000..47ffb781 Binary files /dev/null and b/CPP/7zip/Bundles/SFXCon/7z.ico differ diff --git a/CPP/7zip/Bundles/SFXCon/Main.cpp b/CPP/7zip/Bundles/SFXCon/Main.cpp new file mode 100755 index 00000000..65ed8931 --- /dev/null +++ b/CPP/7zip/Bundles/SFXCon/Main.cpp @@ -0,0 +1,416 @@ +// Main.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" + +#include "Common/CommandLineParser.h" +#include "Common/StdOutStream.h" +#include "Common/Wildcard.h" +#include "Common/StringConvert.h" +#include "Common/MyCom.h" +#include "Common/Exception.h" + +#include "Windows/FileDir.h" +#include "Windows/FileName.h" +#include "Windows/Defs.h" + +#include "../../IPassword.h" +#include "../../ICoder.h" + +#include "../../UI/Common/OpenArchive.h" +#include "../../UI/Common/DefaultName.h" +#include "../../UI/Common/ExitCode.h" +#include "../../UI/Common/Extract.h" + +#include "../../UI/Console/List.h" +#include "../../UI/Console/OpenCallbackConsole.h" +#include "../../UI/Console/ExtractCallbackConsole.h" + +#include "../../MyVersion.h" + +using namespace NWindows; +using namespace NFile; +using namespace NCommandLineParser; + +extern CStdOutStream *g_StdStream; + +static const char *kCopyrightString = +"\n7-Zip SFX " MY_VERSION_COPYRIGHT_DATE "\n"; + +static const int kNumSwitches = 6; + +#ifdef _WIN32 +static const wchar_t *kDefaultExt = L".exe"; +static const int kDefaultExtLength = 4; +#endif + +namespace NKey { +enum Enum +{ + kHelp1 = 0, + kHelp2, + kDisablePercents, + kYes, + kPassword, + kOutputDir +}; + +} + +namespace NRecursedType { +enum EEnum +{ + kRecursed, + kWildCardOnlyRecursed, + kNonRecursed, +}; +} + +static const char kRecursedIDChar = 'R'; +static const wchar_t *kRecursedPostCharSet = L"0-"; + +namespace NRecursedPostCharIndex { + enum EEnum + { + kWildCardRecursionOnly = 0, + kNoRecursion = 1 + }; +} + +static const char kFileListID = '@'; +static const char kImmediateNameID = '!'; + +static const char kSomeCludePostStringMinSize = 2; // at least <@|!>ame must be +static const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!>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 [] [...]\n" + "\n" + "\n" + " l: List contents of archive\n" + " t: Test integrity of archive\n" + " x: eXtract files with full pathname (default)\n" + "\n" + // " -bd Disable percentage indicator\n" + " -o{Directory}: set Output directory\n" + " -p{Password}: set Password\n" + " -y: assume Yes on all queries\n"; + + +// --------------------------- +// exception messages + +static const char *kUserErrorMessage = "Incorrect command line"; // NExitCode::kUserError +static const char *kIncorrectListFile = "Incorrect wildcard in listfile"; +static const char *kIncorrectWildCardInCommandLine = "Incorrect wildcard in command line"; + +// static const CSysString kFileIsNotArchiveMessageBefore = "File \""; +// static const CSysString kFileIsNotArchiveMessageAfter = "\" is not archive"; + +static const char *kProcessArchiveMessage = " archive: "; + +static const char *kCantFindSFX = " cannot find sfx"; + + +struct CArchiveCommand +{ + NCommandType::EEnum CommandType; + NRecursedType::EEnum DefaultRecursedType() const; +}; + +NRecursedType::EEnum CArchiveCommand::DefaultRecursedType() const +{ + return kCommandRecursedDefault[CommandType]; +} + +void PrintHelp(void) +{ + g_StdOut << kHelpString; +} + +static void ShowMessageAndThrowException(const char *message, NExitCode::EEnum code) +{ + g_StdOut << message << endl; + throw code; +} + +static void PrintHelpAndExit() // yyy +{ + PrintHelp(); + ShowMessageAndThrowException(kUserErrorMessage, NExitCode::kUserError); +} + +bool ParseArchiveCommand(const UString &commandString, CArchiveCommand &command) +{ + UString commandStringUpper = commandString; + commandStringUpper.MakeUpper(); + UString postString; + int commandIndex = ParseCommand(kNumCommandForms, commandForms, commandStringUpper, + postString) ; + if (commandIndex < 0) + return false; + command.CommandType = (NCommandType::EEnum)commandIndex; + return true; +} + +// ------------------------------------------------------------------ +// filenames functions + +static bool AddNameToCensor(NWildcard::CCensor &wildcardCensor, + const UString &name, bool include, NRecursedType::EEnum type) +{ + /* + if(!IsWildCardFilePathLegal(name)) + return false; + */ + bool isWildCard = DoesNameContainWildCard(name); + bool recursed = false; + + switch (type) + { + case NRecursedType::kWildCardOnlyRecursed: + recursed = isWildCard; + break; + case NRecursedType::kRecursed: + recursed = true; + break; + case NRecursedType::kNonRecursed: + recursed = false; + break; + } + wildcardCensor.AddItem(include, name, recursed); + return true; +} + +void AddCommandLineWildCardToCensor(NWildcard::CCensor &wildcardCensor, + const UString &name, bool include, NRecursedType::EEnum type) +{ + if (!AddNameToCensor(wildcardCensor, name, include, type)) + ShowMessageAndThrowException(kIncorrectWildCardInCommandLine, NExitCode::kUserError); +} + +void AddToCensorFromNonSwitchesStrings(NWildcard::CCensor &wildcardCensor, + const UStringVector & /* nonSwitchStrings */, NRecursedType::EEnum type, + bool /* thereAreSwitchIncludeWildCards */) +{ + AddCommandLineWildCardToCensor(wildcardCensor, kUniversalWildcard, true, type); +} + + +#ifndef _WIN32 +static void GetArguments(int numArguments, const char *arguments[], UStringVector &parts) +{ + parts.Clear(); + for(int i = 0; i < numArguments; i++) + { + UString s = MultiByteToUnicodeString(arguments[i]); + parts.Add(s); + } +} +#endif + +int Main2( + #ifndef _WIN32 + int numArguments, const char *arguments[] + #endif +) +{ + #ifdef _WIN32 + SetFileApisToOEM(); + #endif + + g_StdOut << kCopyrightString; + + UStringVector commandStrings; + #ifdef _WIN32 + NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); + #else + GetArguments(numArguments, arguments, commandStrings); + #endif + + UString archiveName = commandStrings.Front(); + + commandStrings.Delete(0); + + NCommandLineParser::CParser parser(kNumSwitches); + try + { + parser.ParseStrings(kSwitchForms, commandStrings); + } + catch(...) + { + PrintHelpAndExit(); + } + + if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs) + { + PrintHelp(); + return 0; + } + const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; + + int numNonSwitchStrings = nonSwitchStrings.Size(); + + CArchiveCommand command; + if (numNonSwitchStrings == 0) + command.CommandType = NCommandType::kFullExtract; + else + { + if (numNonSwitchStrings > 1) + PrintHelpAndExit(); + if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], command)) + PrintHelpAndExit(); + } + + + NRecursedType::EEnum recursedType; + recursedType = command.DefaultRecursedType(); + + NWildcard::CCensor wildcardCensor; + + bool thereAreSwitchIncludeWildCards; + thereAreSwitchIncludeWildCards = false; + AddToCensorFromNonSwitchesStrings(wildcardCensor, nonSwitchStrings, recursedType, + thereAreSwitchIncludeWildCards); + + bool yesToAll = parser[NKey::kYes].ThereIs; + + #ifdef _WIN32 + if (archiveName.Right(kDefaultExtLength).CompareNoCase(kDefaultExt) != 0) + archiveName += kDefaultExt; + #endif + + // NExtractMode::EEnum extractMode; + // bool isExtractGroupCommand = command.IsFromExtractGroup(extractMode); + + bool passwordEnabled = parser[NKey::kPassword].ThereIs; + + UString password; + if(passwordEnabled) + password = parser[NKey::kPassword].PostStrings[0]; + + NFind::CFileInfoW archiveFileInfo; + if (!NFind::FindFile(archiveName, archiveFileInfo)) + throw kCantFindSFX; + if (archiveFileInfo.IsDirectory()) + throw kCantFindSFX; + + UString outputDir; + if(parser[NKey::kOutputDir].ThereIs) + { + outputDir = parser[NKey::kOutputDir].PostStrings[0]; + NName::NormalizeDirPathPrefix(outputDir); + } + + { + UStringVector v1, v2; + v1.Add(archiveName); + v2.Add(archiveName); + const NWildcard::CCensorNode &wildcardCensorHead = + wildcardCensor.Pairs.Front().Head; + if(command.CommandType != NCommandType::kList) + { + CExtractCallbackConsole *ecs = new CExtractCallbackConsole; + CMyComPtr extractCallback = ecs; + ecs->OutStream = g_StdStream; + ecs->PasswordIsDefined = passwordEnabled; + ecs->Password = password; + ecs->Init(); + + COpenCallbackConsole openCallback; + openCallback.OutStream = g_StdStream; + openCallback.PasswordIsDefined = passwordEnabled; + openCallback.Password = password; + + CExtractOptions eo; + eo.StdOutMode = false; + eo.PathMode = NExtract::NPathMode::kFullPathnames; + eo.TestMode = command.CommandType == NCommandType::kTest; + eo.OverwriteMode = yesToAll ? + NExtract::NOverwriteMode::kWithoutPrompt : + NExtract::NOverwriteMode::kAskBefore; + eo.OutputDir = outputDir; + eo.YesToAll = yesToAll; + + UString errorMessage; + HRESULT result = DecompressArchives( + v1, v2, + wildcardCensorHead, + eo, &openCallback, ecs, errorMessage); + if (!errorMessage.IsEmpty()) + { + (*g_StdStream) << endl << "Error: " << errorMessage;; + if (result == S_OK) + result = E_FAIL; + } + + if (ecs->NumArchiveErrors != 0 || ecs->NumFileErrors != 0) + { + if (ecs->NumArchiveErrors != 0) + (*g_StdStream) << endl << "Archive Errors: " << ecs->NumArchiveErrors << endl; + if (ecs->NumFileErrors != 0) + (*g_StdStream) << endl << "Sub items Errors: " << ecs->NumFileErrors << endl; + return NExitCode::kFatalError; + } + if (result != S_OK) + throw CSystemException(result); + } + else + { + HRESULT result = ListArchives( + v1, v2, + wildcardCensorHead, + true, false, + passwordEnabled, + password); + if (result != S_OK) + throw CSystemException(result); + } + } + return 0; +} diff --git a/CPP/7zip/Bundles/SFXCon/SFXCon.dsp b/CPP/7zip/Bundles/SFXCon/SFXCon.dsp new file mode 100755 index 00000000..5b61dae3 --- /dev/null +++ b/CPP/7zip/Bundles/SFXCon/SFXCon.dsp @@ -0,0 +1,759 @@ +# Microsoft Developer Studio Project File - Name="SFXCon" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=SFXCon - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "SFXCon.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "SFXCon.mak" CFG="SFXCon - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "SFXCon - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "SFXCon - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "SFXCon - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "COMPRESS_BCJ2" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_COPY" /D "COMPRESS_PPMD" /D "_SFX" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\Util\7zCon.sfx" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "SFXCon - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "..\..\..\..\\" /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_COPY" /D "COMPRESS_PPMD" /D "_SFX" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\Util\7zCon.sfx" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "SFXCon - Win32 Release" +# Name "SFXCon - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2MT.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2ST.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2ST.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CrossThreadProgress.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.h +# End Source File +# End Group +# Begin Group "Console" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Console\ConsoleClose.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\ConsoleClose.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\ExtractCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\ExtractCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\List.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\List.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\MainAr.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\OpenCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\OpenCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\UserInputUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\UserInputUtils.h +# End Source File +# End Group +# Begin Group "7z" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zExtract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethodID.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethodID.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Group "LZMA" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZMA\LZMADecoder.cpp +# End Source File +# End Group +# Begin Group "Branch" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Branch\BranchCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\BranchCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86_2.cpp +# End Source File +# End Group +# Begin Group "PPMD" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDDecoder.cpp +# End Source File +# End Group +# Begin Group "LZ" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.h +# End Source File +# End Group +# Begin Group "Copy" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# End Group +# Begin Group "Crypto" + +# PROP Default_Filter "" +# Begin Group "7zAES" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\7zAES\7zAES.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\7zAES\7zAES.h +# End Source File +# End Group +# Begin Group "AES" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\AES\aes.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\AES_CBC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aescpp.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aescrypt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aeskey.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aesopt.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aestab.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\MyAES.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\MyAES.h +# End Source File +# End Group +# Begin Group "Hash" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\Hash\RotateDefs.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Hash\Sha256.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Hash\Sha256.h +# End Source File +# End Group +# End Group +# Begin Group "SDK" + +# PROP Default_Filter "" +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Error.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OffsetStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OffsetStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "UI" + +# PROP Default_Filter "" +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiverInfo.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiverInfo.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExitCode.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Extract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Extract.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractingFilePath.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractingFilePath.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractMode.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\OpenArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\OpenArchive.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\PropIDUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\PropIDUtils.h +# End Source File +# End Group +# End Group +# Begin Source File + +SOURCE=.\7z.ico +# End Source File +# Begin Source File + +SOURCE=.\Main.cpp +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/Bundles/SFXCon/SFXCon.dsw b/CPP/7zip/Bundles/SFXCon/SFXCon.dsw new file mode 100755 index 00000000..27bf7e6d --- /dev/null +++ b/CPP/7zip/Bundles/SFXCon/SFXCon.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "SFXCon"=.\SFXCon.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Bundles/SFXCon/StdAfx.cpp b/CPP/7zip/Bundles/SFXCon/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Bundles/SFXCon/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Bundles/SFXCon/StdAfx.h b/CPP/7zip/Bundles/SFXCon/StdAfx.h new file mode 100755 index 00000000..2e4be10b --- /dev/null +++ b/CPP/7zip/Bundles/SFXCon/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" +#include "../../../Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/Bundles/SFXCon/makefile b/CPP/7zip/Bundles/SFXCon/makefile new file mode 100755 index 00000000..7501a497 --- /dev/null +++ b/CPP/7zip/Bundles/SFXCon/makefile @@ -0,0 +1,180 @@ +PROG = 7zCon.sfx +LIBS = $(LIBS) user32.lib oleaut32.lib +CFLAGS = $(CFLAGS) -I ../../../ \ + -DEXCLUDE_COM \ + -DNO_REGISTRY \ + -DEXTRACT_ONLY \ + -D_SFX \ + -DFORMAT_7Z \ + -DCOMPRESS_BCJ_X86 \ + -DCOMPRESS_BCJ2 \ + -DCOMPRESS_COPY \ + -DCOMPRESS_LZMA \ + -DCOMPRESS_PPMD \ + -DCRYPTO_7ZAES \ + -DCRYPTO_AES \ + +SFX_CONSOLE_OBJS = \ + $O\Main.obj \ + +CONSOLE_OBJS = \ + $O\ConsoleClose.obj \ + $O\ExtractCallbackConsole.obj \ + $O\List.obj \ + $O\MainAr.obj \ + $O\OpenCallbackConsole.obj \ + $O\UserInputUtils.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CommandLineParser.obj \ + $O\CRC.obj \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\StdInStream.obj \ + $O\StdOutStream.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\Vector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\Error.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\PropVariant.obj \ + $O\PropVariantConversions.obj \ + $O\Synchronization.obj + +7ZIP_COMMON_OBJS = \ + $O\FilePathAutoRename.obj \ + $O\FileStreams.obj \ + $O\InBuffer.obj \ + $O\LimitedStreams.obj \ + $O\LockedStream.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\StreamBinder.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveExtractCallback.obj \ + $O\ArchiveOpenCallback.obj \ + $O\ArchiverInfo.obj \ + $O\DefaultName.obj \ + $O\Extract.obj \ + $O\ExtractingFilePath.obj \ + $O\OpenArchive.obj \ + $O\PropIDUtils.obj \ + +AR_COMMON_OBJS = \ + $O\CoderMixer2.obj \ + $O\CoderMixer2MT.obj \ + $O\CrossThreadProgress.obj \ + $O\FilterCoder.obj \ + $O\ItemNameUtils.obj \ + $O\OutStreamWithCRC.obj \ + + +7Z_OBJS = \ + $O\7zDecode.obj \ + $O\7zExtract.obj \ + $O\7zFolderOutStream.obj \ + $O\7zHandler.obj \ + $O\7zHeader.obj \ + $O\7zIn.obj \ + $O\7zMethodID.obj \ + +BRANCH_OPT_OBJS = \ + $O\BranchCoder.obj \ + $O\x86.obj \ + $O\x86_2.obj \ + +LZ_OBJS = \ + $O\LZOutWindow.obj \ + +LZMA_OPT_OBJS = \ + $O\LZMADecoder.obj \ + +PPMD_OPT_OBJS = \ + $O\PPMDDecoder.obj \ + +7ZAES_OPT_OBJS = \ + $O\7zAES.obj \ + +AES_OPT_OBJS = \ + $O\MyAES.obj \ + +AES_ORIG_OBJS = \ + $O\aescrypt.obj \ + $O\aeskey.obj \ + $O\aestab.obj \ + +CRYPTO_HASH_OBJS = \ + $O\Sha256.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(SFX_CONSOLE_OBJS) \ + $(CONSOLE_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(UI_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $(7Z_OBJS) \ + $(BRANCH_OPT_OBJS) \ + $(LZ_OBJS) \ + $(LZMA_OPT_OBJS) \ + $(PPMD_OPT_OBJS) \ + $O\CopyCoder.obj \ + $(7ZAES_OPT_OBJS) \ + $(AES_OPT_OBJS) \ + $(AES_ORIG_OBJS) \ + $(CRYPTO_HASH_OBJS) \ + $O\resource.res + + +!include "../../../Build.mak" + +$(SFX_CONSOLE_OBJS): $(*B).cpp + $(COMPL) + +$(CONSOLE_OBJS): ../../UI/Console/$(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp + $(COMPL) + +$(7Z_OBJS): ../../Archive/7z/$(*B).cpp + $(COMPL) +$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp + $(COMPL) +$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp + $(COMPL) +$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp + $(COMPL) +$(PPMD_OPT_OBJS): ../../Compress/PPMD/$(*B).cpp + $(COMPL) + +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) + +$(AES_OPT_OBJS): ../../Crypto/AES/$(*B).cpp + $(COMPL) +$(AES_ORIG_OBJS): ../../Crypto/AES/$(*B).c + $(COMPL_O1_W3) +$(7ZAES_OPT_OBJS): ../../Crypto/7zAES/$(*B).cpp + $(COMPL) +$(CRYPTO_HASH_OBJS): ../../Crypto/Hash/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/Bundles/SFXCon/resource.rc b/CPP/7zip/Bundles/SFXCon/resource.rc new file mode 100755 index 00000000..58331b81 --- /dev/null +++ b/CPP/7zip/Bundles/SFXCon/resource.rc @@ -0,0 +1,5 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_APP("7z Console SFX", "7z.sfx") + +101 ICON "7z.ico" \ No newline at end of file diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractCallback.cpp b/CPP/7zip/Bundles/SFXSetup/ExtractCallback.cpp new file mode 100755 index 00000000..6294516c --- /dev/null +++ b/CPP/7zip/Bundles/SFXSetup/ExtractCallback.cpp @@ -0,0 +1,249 @@ +// ExtractCallback.h + +#include "StdAfx.h" + +#include "ExtractCallback.h" + +#include "Common/Wildcard.h" +#include "Common/StringConvert.h" + +#include "Windows/COM.h" +#include "Windows/FileDir.h" +#include "Windows/FileFind.h" +#include "Windows/Time.h" +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" + +#include "Windows/PropVariantConversions.h" + +using namespace NWindows; +using namespace NFile; + +static LPCWSTR kErrorTitle = L"7-Zip"; +static LPCWSTR kCantDeleteFile = L"Can not delete output file"; +static LPCWSTR kCantOpenFile = L"Can not open output file"; +static LPCWSTR kUnsupportedMethod = L"Unsupported Method"; +// static LPCWSTR kCRCFailed = L"CRC Failed"; +// static LPCWSTR kDataError = L"Data Error"; +// static LPCWSTR kUnknownError = L""Unknown Error"; + +void CExtractCallbackImp::Init(IInArchive *archiveHandler, + const UString &directoryPath, + const UString &itemDefaultName, + const FILETIME &utcLastWriteTimeDefault, + UInt32 attributesDefault) +{ + _message.Empty(); + _isCorrupt = false; + _itemDefaultName = itemDefaultName; + _utcLastWriteTimeDefault = utcLastWriteTimeDefault; + _attributesDefault = attributesDefault; + _archiveHandler = archiveHandler; + _directoryPath = directoryPath; + NName::NormalizeDirPathPrefix(_directoryPath); +} + +STDMETHODIMP CExtractCallbackImp::SetTotal(UInt64 size) +{ + #ifndef _NO_PROGRESS + ProgressDialog.ProgressSynch.SetProgress(size, 0); + #endif + return S_OK; +} + +STDMETHODIMP CExtractCallbackImp::SetCompleted(const UInt64 *completeValue) +{ + #ifndef _NO_PROGRESS + for (;;) + { + if(ProgressDialog.ProgressSynch.GetStopped()) + return E_ABORT; + if(!ProgressDialog.ProgressSynch.GetPaused()) + break; + ::Sleep(100); + } + if (completeValue != NULL) + ProgressDialog.ProgressSynch.SetPos(*completeValue); + #endif + return S_OK; +} + +void CExtractCallbackImp::CreateComplexDirectory(const UStringVector &dirPathParts) +{ + UString fullPath = _directoryPath; + for(int i = 0; i < dirPathParts.Size(); i++) + { + fullPath += dirPathParts[i]; + NDirectory::MyCreateDirectory(fullPath); + fullPath += NName::kDirDelimiter; + } +} + +STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index, + ISequentialOutStream **outStream, Int32 askExtractMode) +{ + #ifndef _NO_PROGRESS + if(ProgressDialog.ProgressSynch.GetStopped()) + return E_ABORT; + #endif + _outFileStream.Release(); + NCOM::CPropVariant propVariantName; + RINOK(_archiveHandler->GetProperty(index, kpidPath, &propVariantName)); + UString fullPath; + if(propVariantName.vt == VT_EMPTY) + fullPath = _itemDefaultName; + else + { + if(propVariantName.vt != VT_BSTR) + return E_FAIL; + fullPath = propVariantName.bstrVal; + } + _filePath = fullPath; + + // m_CurrentFilePath = GetSystemString(fullPath, _codePage); + + if(askExtractMode == NArchive::NExtract::NAskMode::kExtract) + { + NCOM::CPropVariant propVariant; + RINOK(_archiveHandler->GetProperty(index, kpidAttributes, &propVariant)); + if (propVariant.vt == VT_EMPTY) + _processedFileInfo.Attributes = _attributesDefault; + else + { + if (propVariant.vt != VT_UI4) + return E_FAIL; + _processedFileInfo.Attributes = propVariant.ulVal; + } + + RINOK(_archiveHandler->GetProperty(index, kpidIsFolder, &propVariant)); + _processedFileInfo.IsDirectory = VARIANT_BOOLToBool(propVariant.boolVal); + + bool isAnti = false; + { + NCOM::CPropVariant propVariantTemp; + RINOK(_archiveHandler->GetProperty(index, kpidIsAnti, + &propVariantTemp)); + if (propVariantTemp.vt == VT_BOOL) + isAnti = VARIANT_BOOLToBool(propVariantTemp.boolVal); + } + + RINOK(_archiveHandler->GetProperty(index, kpidLastWriteTime, &propVariant)); + switch(propVariant.vt) + { + case VT_EMPTY: + _processedFileInfo.UTCLastWriteTime = _utcLastWriteTimeDefault; + break; + case VT_FILETIME: + _processedFileInfo.UTCLastWriteTime = propVariant.filetime; + break; + default: + return E_FAIL; + } + + UStringVector pathParts; + SplitPathToParts(fullPath, pathParts); + if(pathParts.IsEmpty()) + return E_FAIL; + + UString processedPath = fullPath; + + if(!_processedFileInfo.IsDirectory) + pathParts.DeleteBack(); + if (!pathParts.IsEmpty()) + { + if (!isAnti) + CreateComplexDirectory(pathParts); + } + + UString fullProcessedPath = _directoryPath + processedPath; + + if(_processedFileInfo.IsDirectory) + { + _diskFilePath = fullProcessedPath; + + if (isAnti) + NDirectory::MyRemoveDirectory(_diskFilePath); + return S_OK; + } + + NFind::CFileInfoW fileInfo; + if(NFind::FindFile(fullProcessedPath, fileInfo)) + { + if (!NDirectory::DeleteFileAlways(fullProcessedPath)) + { + _message = kCantDeleteFile; + return E_FAIL; + } + } + + if (!isAnti) + { + _outFileStreamSpec = new COutFileStream; + CMyComPtr outStreamLoc(_outFileStreamSpec); + if (!_outFileStreamSpec->Create(fullProcessedPath, true)) + { + _message = kCantOpenFile; + return E_FAIL; + } + _outFileStream = outStreamLoc; + *outStream = outStreamLoc.Detach(); + } + _diskFilePath = fullProcessedPath; + } + else + { + *outStream = NULL; + } + return S_OK; +} + +STDMETHODIMP CExtractCallbackImp::PrepareOperation(Int32 askExtractMode) +{ + _extractMode = false; + switch (askExtractMode) + { + case NArchive::NExtract::NAskMode::kExtract: + _extractMode = true; + break; + }; + return S_OK; +} + +STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 resultEOperationResult) +{ + switch(resultEOperationResult) + { + case NArchive::NExtract::NOperationResult::kOK: + { + break; + } + default: + { + _outFileStream.Release(); + switch(resultEOperationResult) + { + case NArchive::NExtract::NOperationResult::kUnSupportedMethod: + _message = kUnsupportedMethod; + break; + case NArchive::NExtract::NOperationResult::kCRCError: + _isCorrupt = true; + // _message = kCRCFailed; + break; + case NArchive::NExtract::NOperationResult::kDataError: + _isCorrupt = true; + // _message = kDataError; + break; + default: + _isCorrupt = true; + } + return E_FAIL; + } + } + if(_outFileStream != NULL) + _outFileStreamSpec->File.SetLastWriteTime(&_processedFileInfo.UTCLastWriteTime); + _outFileStream.Release(); + if (_extractMode) + NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attributes); + return S_OK; +} + diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractCallback.h b/CPP/7zip/Bundles/SFXSetup/ExtractCallback.h new file mode 100755 index 00000000..f3880890 --- /dev/null +++ b/CPP/7zip/Bundles/SFXSetup/ExtractCallback.h @@ -0,0 +1,96 @@ +// ExtractCallback.h + +#ifndef __EXTRACTCALLBACK_H +#define __EXTRACTCALLBACK_H + +#include "resource.h" + +#include "Common/String.h" +#include "Windows/ResourceString.h" + +#include "../../Archive/IArchive.h" + +#include "../../Common/FileStreams.h" +#include "../../ICoder.h" + +#ifndef _NO_PROGRESS +#include "../../FileManager/Resource/ProgressDialog/ProgressDialog.h" +#endif + +class CExtractCallbackImp: + public IArchiveExtractCallback, + public CMyUnknownImp +{ +public: + + MY_UNKNOWN_IMP + + // IProgress + STDMETHOD(SetTotal)(UInt64 size); + STDMETHOD(SetCompleted)(const UInt64 *completeValue); + + // IExtractCallback + STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, + Int32 askExtractMode); + STDMETHOD(PrepareOperation)(Int32 askExtractMode); + STDMETHOD(SetOperationResult)(Int32 resultEOperationResult); + +private: + CMyComPtr _archiveHandler; + UString _directoryPath; + + UString _filePath; + + UString _diskFilePath; + + bool _extractMode; + struct CProcessedFileInfo + { + FILETIME UTCLastWriteTime; + bool IsDirectory; + UInt32 Attributes; + } _processedFileInfo; + + COutFileStream *_outFileStreamSpec; + CMyComPtr _outFileStream; + + UString _itemDefaultName; + FILETIME _utcLastWriteTimeDefault; + UInt32 _attributesDefault; + + void CreateComplexDirectory(const UStringVector &dirPathParts); +public: + #ifndef _NO_PROGRESS + CProgressDialog ProgressDialog; + #endif + + bool _isCorrupt; + UString _message; + + void Init(IInArchive *archiveHandler, + const UString &directoryPath, + const UString &itemDefaultName, + const FILETIME &utcLastWriteTimeDefault, + UInt32 attributesDefault); + + #ifndef _NO_PROGRESS + HRESULT StartProgressDialog(const UString &title) + { + ProgressDialog.Create(title, 0); + { + #ifdef LANG + ProgressDialog.SetText(LangLoadString(IDS_PROGRESS_EXTRACTING, 0x02000890)); + #else + ProgressDialog.SetText(NWindows::MyLoadStringW(IDS_PROGRESS_EXTRACTING)); + #endif + } + + ProgressDialog.Show(SW_SHOWNORMAL); + return S_OK; + } + virtual ~CExtractCallbackImp() { ProgressDialog.Destroy(); } + #endif + +}; + +#endif diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp b/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp new file mode 100755 index 00000000..19fcb0d2 --- /dev/null +++ b/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp @@ -0,0 +1,139 @@ +// ExtractEngine.cpp + +#include "StdAfx.h" + +#include "ExtractEngine.h" + +#include "Common/StringConvert.h" + +#include "Windows/FileDir.h" +#include "Windows/FileFind.h" +#include "Windows/Thread.h" + +#include "../../UI/Common/OpenArchive.h" + +#include "../../UI/Explorer/MyMessages.h" +#include "../../FileManager/FormatUtils.h" + +#include "ExtractCallback.h" + +using namespace NWindows; + +struct CThreadExtracting +{ + CArchiveLink ArchiveLink; + + CExtractCallbackImp *ExtractCallbackSpec; + CMyComPtr ExtractCallback; + + #ifndef _NO_PROGRESS + HRESULT Result; + + HRESULT Extract() + { + return ArchiveLink.GetArchive()->Extract(0, (UInt32)-1 , BoolToInt(false), ExtractCallback); + } + DWORD Process() + { + ExtractCallbackSpec->ProgressDialog.WaitCreating(); + Result = Extract(); + ExtractCallbackSpec->ProgressDialog.MyClose(); + return 0; + } + static DWORD WINAPI MyThreadFunction(void *param) + { + return ((CThreadExtracting *)param)->Process(); + } + #endif +}; + +static const LPCWSTR kCantFindArchive = L"Can not find archive file"; +static const LPCWSTR kCantOpenArchive = L"File is not correct archive"; + +HRESULT ExtractArchive( + const UString &fileName, + const UString &folderName, + COpenCallbackGUI *openCallback, + bool showProgress, + bool &isCorrupt, + UString &errorMessage) +{ + isCorrupt = false; + NFile::NFind::CFileInfoW archiveFileInfo; + if (!NFile::NFind::FindFile(fileName, archiveFileInfo)) + { + errorMessage = kCantFindArchive; + return E_FAIL; + } + + CThreadExtracting extracter; + + HRESULT result = MyOpenArchive(fileName, extracter.ArchiveLink, openCallback); + + if (result != S_OK) + { + errorMessage = kCantOpenArchive; + return result; + } + + UString directoryPath = folderName; + NFile::NName::NormalizeDirPathPrefix(directoryPath); + + /* + UString directoryPath; + { + UString fullPath; + int fileNamePartStartIndex; + if (!NWindows::NFile::NDirectory::MyGetFullPathName(fileName, fullPath, fileNamePartStartIndex)) + { + MessageBox(NULL, "Error 1329484", "7-Zip", 0); + return E_FAIL; + } + directoryPath = fullPath.Left(fileNamePartStartIndex); + } + */ + + if(!NFile::NDirectory::CreateComplexDirectory(directoryPath)) + { + errorMessage = MyFormatNew(IDS_CANNOT_CREATE_FOLDER, + #ifdef LANG + 0x02000603, + #endif + directoryPath); + return E_FAIL; + } + + extracter.ExtractCallbackSpec = new CExtractCallbackImp; + extracter.ExtractCallback = extracter.ExtractCallbackSpec; + + extracter.ExtractCallbackSpec->Init( + extracter.ArchiveLink.GetArchive(), + directoryPath, L"Default", archiveFileInfo.LastWriteTime, 0); + + #ifndef _NO_PROGRESS + + if (showProgress) + { + CThread thread; + if (!thread.Create(CThreadExtracting::MyThreadFunction, &extracter)) + throw 271824; + + UString title; + #ifdef LANG + title = LangLoadString(IDS_PROGRESS_EXTRACTING, 0x02000890); + #else + title = NWindows::MyLoadStringW(IDS_PROGRESS_EXTRACTING); + #endif + extracter.ExtractCallbackSpec->StartProgressDialog(title); + result = extracter.Result; + } + else + + #endif + { + result = extracter.Extract(); + } + errorMessage = extracter.ExtractCallbackSpec->_message; + isCorrupt = extracter.ExtractCallbackSpec->_isCorrupt; + return result; +} diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h b/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h new file mode 100755 index 00000000..595d2b29 --- /dev/null +++ b/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h @@ -0,0 +1,17 @@ +// ExtractEngine.h + +#ifndef __EXTRACTENGINE_H +#define __EXTRACTENGINE_H + +#include "Common/String.h" +#include "../../UI/GUI/OpenCallbackGUI.h" + +HRESULT ExtractArchive( + const UString &fileName, + const UString &folderName, + COpenCallbackGUI *openCallback, + bool showProgress, + bool &isCorrupt, + UString &errorMessage); + +#endif diff --git a/CPP/7zip/Bundles/SFXSetup/Main.cpp b/CPP/7zip/Bundles/SFXSetup/Main.cpp new file mode 100755 index 00000000..12de5c01 --- /dev/null +++ b/CPP/7zip/Bundles/SFXSetup/Main.cpp @@ -0,0 +1,335 @@ +// Main.cpp + +#include "StdAfx.h" + +#include + +#include "Common/StringConvert.h" +#include "Common/Random.h" +#include "Common/TextConfig.h" +#include "Common/CommandLineParser.h" + +#include "Windows/FileDir.h" +#include "Windows/FileIO.h" +#include "Windows/FileFind.h" +#include "Windows/FileName.h" +#include "Windows/DLL.h" +#include "Windows/ResourceString.h" + +#include "../../IPassword.h" +#include "../../ICoder.h" +#include "../../Archive/IArchive.h" +#include "../../UI/Explorer/MyMessages.h" + +// #include "../../UI/GUI/ExtractGUI.h" + +#include "ExtractEngine.h" + +#include "resource.h" + +using namespace NWindows; + +HINSTANCE g_hInstance; + +static LPCTSTR kTempDirPrefix = TEXT("7zS"); + +#define _SHELL_EXECUTE + +static bool ReadDataString(LPCWSTR fileName, LPCSTR startID, + LPCSTR endID, AString &stringResult) +{ + stringResult.Empty(); + NFile::NIO::CInFile inFile; + if (!inFile.Open(fileName)) + return false; + const int kBufferSize = (1 << 12); + + Byte buffer[kBufferSize]; + int signatureStartSize = lstrlenA(startID); + int signatureEndSize = lstrlenA(endID); + + UInt32 numBytesPrev = 0; + bool writeMode = false; + UInt64 posTotal = 0; + for (;;) + { + if (posTotal > (1 << 20)) + return (stringResult.IsEmpty()); + UInt32 numReadBytes = kBufferSize - numBytesPrev; + UInt32 processedSize; + if (!inFile.Read(buffer + numBytesPrev, numReadBytes, processedSize)) + return false; + if (processedSize == 0) + return true; + UInt32 numBytesInBuffer = numBytesPrev + processedSize; + UInt32 pos = 0; + for (;;) + { + if (writeMode) + { + if (pos > numBytesInBuffer - signatureEndSize) + break; + if (memcmp(buffer + pos, endID, signatureEndSize) == 0) + return true; + char b = buffer[pos]; + if (b == 0) + return false; + stringResult += b; + pos++; + } + else + { + if (pos > numBytesInBuffer - signatureStartSize) + break; + if (memcmp(buffer + pos, startID, signatureStartSize) == 0) + { + writeMode = true; + pos += signatureStartSize; + } + else + pos++; + } + } + numBytesPrev = numBytesInBuffer - pos; + posTotal += pos; + memmove(buffer, buffer + pos, numBytesPrev); + } +} + +static char kStartID[] = ",!@Install@!UTF-8!"; +static char kEndID[] = ",!@InstallEnd@!"; + +class CInstallIDInit +{ +public: + CInstallIDInit() + { + kStartID[0] = ';'; + kEndID[0] = ';'; + }; +} g_CInstallIDInit; + + +class CCurrentDirRestorer +{ + CSysString m_CurrentDirectory; +public: + CCurrentDirRestorer() + { NFile::NDirectory::MyGetCurrentDirectory(m_CurrentDirectory); } + ~CCurrentDirRestorer() + { RestoreDirectory();} + bool RestoreDirectory() + { return BOOLToBool(::SetCurrentDirectory(m_CurrentDirectory)); } +}; + +#ifndef _UNICODE +bool g_IsNT = false; +static inline bool IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); +} +#endif + +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, LPSTR /* lpCmdLine */,int /* nCmdShow */) +{ + g_hInstance = (HINSTANCE)hInstance; + #ifndef _UNICODE + g_IsNT = IsItWindowsNT(); + #endif + InitCommonControls(); + + UString archiveName, switches; + #ifdef _SHELL_EXECUTE + UString executeFile, executeParameters; + #endif + NCommandLineParser::SplitCommandLine(GetCommandLineW(), archiveName, switches); + + UString fullPath; + NDLL::MyGetModuleFileName(g_hInstance, fullPath); + + switches.Trim(); + bool assumeYes = false; + if (switches.Left(2).CompareNoCase(UString(L"-y")) == 0) + { + assumeYes = true; + switches = switches.Mid(2); + switches.Trim(); + } + + AString config; + if (!ReadDataString(fullPath, kStartID, kEndID, config)) + { + if (!assumeYes) + MyMessageBox(L"Can't load config info"); + return 1; + } + + UString dirPrefix = L".\\"; + UString appLaunched; + bool showProgress = true; + if (!config.IsEmpty()) + { + CObjectVector pairs; + if (!GetTextConfig(config, pairs)) + { + if (!assumeYes) + MyMessageBox(L"Config failed"); + return 1; + } + UString friendlyName = GetTextConfigValue(pairs, L"Title"); + UString installPrompt = GetTextConfigValue(pairs, L"BeginPrompt"); + UString progress = GetTextConfigValue(pairs, L"Progress"); + if (progress.CompareNoCase(L"no") == 0) + showProgress = false; + int index = FindTextConfigItem(pairs, L"Directory"); + if (index >= 0) + dirPrefix = pairs[index].String; + if (!installPrompt.IsEmpty() && !assumeYes) + { + if (MessageBoxW(0, installPrompt, friendlyName, MB_YESNO | + MB_ICONQUESTION) != IDYES) + return 0; + } + appLaunched = GetTextConfigValue(pairs, L"RunProgram"); + + #ifdef _SHELL_EXECUTE + executeFile = GetTextConfigValue(pairs, L"ExecuteFile"); + executeParameters = GetTextConfigValue(pairs, L"ExecuteParameters") + switches; + #endif + } + + NFile::NDirectory::CTempDirectory tempDir; + if (!tempDir.Create(kTempDirPrefix)) + { + if (!assumeYes) + MyMessageBox(L"Can not create temp folder archive"); + return 1; + } + + COpenCallbackGUI openCallback; + + UString tempDirPath = GetUnicodeString(tempDir.GetPath()); + { + bool isCorrupt = false; + UString errorMessage; + HRESULT result = ExtractArchive(fullPath, tempDirPath, &openCallback, showProgress, + isCorrupt, errorMessage); + + if (result != S_OK) + { + if (!assumeYes) + { + if (result == S_FALSE || isCorrupt) + { + errorMessage = NWindows::MyLoadStringW(IDS_EXTRACTION_ERROR_MESSAGE); + result = E_FAIL; + } + if (result != E_ABORT && !errorMessage.IsEmpty()) + ::MessageBoxW(0, errorMessage, NWindows::MyLoadStringW(IDS_EXTRACTION_ERROR_TITLE), MB_ICONERROR); + } + return 1; + } + } + + CCurrentDirRestorer currentDirRestorer; + + if (!SetCurrentDirectory(tempDir.GetPath())) + return 1; + + HANDLE hProcess = 0; +#ifdef _SHELL_EXECUTE + if (!executeFile.IsEmpty()) + { + CSysString filePath = GetSystemString(executeFile); + SHELLEXECUTEINFO execInfo; + execInfo.cbSize = sizeof(execInfo); + execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT; + execInfo.hwnd = NULL; + execInfo.lpVerb = NULL; + execInfo.lpFile = filePath; + + if (!switches.IsEmpty()) + executeParameters += switches; + + CSysString parametersSys = GetSystemString(executeParameters); + if (parametersSys.IsEmpty()) + execInfo.lpParameters = NULL; + else + execInfo.lpParameters = parametersSys; + + execInfo.lpDirectory = NULL; + execInfo.nShow = SW_SHOWNORMAL; + execInfo.hProcess = 0; + /* BOOL success = */ ::ShellExecuteEx(&execInfo); + UINT32 result = (UINT32)(UINT_PTR)execInfo.hInstApp; + if(result <= 32) + { + if (!assumeYes) + MyMessageBox(L"Can not open file"); + return 1; + } + hProcess = execInfo.hProcess; + } + else +#endif + { + if (appLaunched.IsEmpty()) + { + appLaunched = L"setup.exe"; + if (!NFile::NFind::DoesFileExist(GetSystemString(appLaunched))) + { + if (!assumeYes) + MyMessageBox(L"Can not find setup.exe"); + return 1; + } + } + + { + UString s2 = tempDirPath; + NFile::NName::NormalizeDirPathPrefix(s2); + appLaunched.Replace(L"%%T\\", s2); + } + + appLaunched.Replace(L"%%T", tempDirPath); + + if (!switches.IsEmpty()) + { + appLaunched += L' '; + appLaunched += switches; + } + STARTUPINFO startupInfo; + startupInfo.cb = sizeof(startupInfo); + startupInfo.lpReserved = 0; + startupInfo.lpDesktop = 0; + startupInfo.lpTitle = 0; + startupInfo.dwFlags = 0; + startupInfo.cbReserved2 = 0; + startupInfo.lpReserved2 = 0; + + PROCESS_INFORMATION processInformation; + + CSysString appLaunchedSys = GetSystemString(dirPrefix + appLaunched); + + BOOL createResult = CreateProcess(NULL, (LPTSTR)(LPCTSTR)appLaunchedSys, + NULL, NULL, FALSE, 0, NULL, NULL /*tempDir.GetPath() */, + &startupInfo, &processInformation); + if (createResult == 0) + { + if (!assumeYes) + ShowLastErrorMessage(); + return 1; + } + ::CloseHandle(processInformation.hThread); + hProcess = processInformation.hProcess; + } + if (hProcess != 0) + { + WaitForSingleObject(hProcess, INFINITE); + ::CloseHandle(hProcess); + } + return 0; +} diff --git a/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp b/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp new file mode 100755 index 00000000..a58feab5 --- /dev/null +++ b/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp @@ -0,0 +1,696 @@ +# Microsoft Developer Studio Project File - Name="SFXSetup" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=SFXSetup - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "SFXSetup.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "SFXSetup.mak" CFG="SFXSetup - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "SFXSetup - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "SFXSetup - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "SFXSetup - Win32 ReleaseD" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "SFXSetup - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "_SFX" /D "_NO_CRYPTO" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zS.sfx" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "SFXSetup - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "_SFX" /D "_NO_CRYPTO" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\UTIL\7zSfxS.exe" /pdbtype:sept + +!ELSEIF "$(CFG)" == "SFXSetup - Win32 ReleaseD" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ReleaseD" +# PROP BASE Intermediate_Dir "ReleaseD" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseD" +# PROP Intermediate_Dir "ReleaseD" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "_SFX" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "_SFX" /D "_NO_CRYPTO" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\UTIL\7zWinSR.exe" +# SUBTRACT BASE LINK32 /debug /nodefaultlib +# ADD LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zSD.sfx" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "SFXSetup - Win32 Release" +# Name "SFXSetup - Win32 Debug" +# Name "SFXSetup - Win32 ReleaseD" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Interface" + +# PROP Default_Filter "" +# End Group +# Begin Group "7z" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zExtract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethodID.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethodID.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2MT.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CrossThreadProgress.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Group "LZMA" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZMA\LZMADecoder.cpp +# End Source File +# End Group +# Begin Group "Branch" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Branch\BranchCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\BranchCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86_2.cpp +# End Source File +# End Group +# Begin Group "Copy" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "LZ" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.h +# End Source File +# End Group +# End Group +# Begin Group "SDK" + +# PROP Default_Filter "" +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\TextConfig.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\TextConfig.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Group "Control" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.h +# End Source File +# End Group +# Begin Group "7z Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "UI" + +# PROP Default_Filter "" +# Begin Group "Explorer" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Explorer\MyMessages.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Explorer\MyMessages.h +# End Source File +# End Group +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiverInfo.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiverInfo.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractMode.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\OpenArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\OpenArchive.h +# End Source File +# End Group +# Begin Group "GUI" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\GUI\OpenCallbackGUI.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\OpenCallbackGUI.h +# End Source File +# End Group +# End Group +# Begin Group "File Manager" + +# PROP Default_Filter "" +# Begin Group "Dialog" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\FileManager\Resource\ProgressDialog\ProgressDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\Resource\ProgressDialog\ProgressDialog.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\FileManager\FormatUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\FormatUtils.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\ExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=.\ExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=.\ExtractEngine.cpp +# End Source File +# Begin Source File + +SOURCE=.\ExtractEngine.h +# End Source File +# Begin Source File + +SOURCE=.\Main.cpp +# End Source File +# Begin Source File + +SOURCE=.\setup.ico +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw b/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw new file mode 100755 index 00000000..f563b21f --- /dev/null +++ b/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "SFXSetup"=.\SFXSetup.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Bundles/SFXSetup/StdAfx.cpp b/CPP/7zip/Bundles/SFXSetup/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Bundles/SFXSetup/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Bundles/SFXSetup/StdAfx.h b/CPP/7zip/Bundles/SFXSetup/StdAfx.h new file mode 100755 index 00000000..19ece34b --- /dev/null +++ b/CPP/7zip/Bundles/SFXSetup/StdAfx.h @@ -0,0 +1,10 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" +#include "../../../Common/NewHandler.h" +#include + +#endif diff --git a/CPP/7zip/Bundles/SFXSetup/makefile b/CPP/7zip/Bundles/SFXSetup/makefile new file mode 100755 index 00000000..1f86c42c --- /dev/null +++ b/CPP/7zip/Bundles/SFXSetup/makefile @@ -0,0 +1,156 @@ +PROG = 7zS.sfx +LIBS = $(LIBS) user32.lib oleaut32.lib shell32.lib ole32.lib comctl32.lib +CFLAGS = $(CFLAGS) -I ../../../ \ + -DEXCLUDE_COM \ + -DNO_REGISTRY \ + -DEXTRACT_ONLY \ + -D_SFX \ + -DFORMAT_7Z \ + -DCOMPRESS_BCJ_X86 \ + -DCOMPRESS_BCJ2 \ + -DCOMPRESS_COPY \ + -DCOMPRESS_LZMA \ + -D_NO_CRYPTO + +SFX_WIN_OBJS = \ + $O\Main.obj \ + $O\ExtractCallback.obj \ + $O\ExtractEngine.obj \ + +GUI_OBJS = \ + $O\OpenCallbackGUI.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CommandLineParser.obj \ + $O\CRC.obj \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\TextConfig.obj \ + $O\UTFConvert.obj \ + $O\Vector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\Error.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\PropVariant.obj \ + $O\ResourceString.obj \ + $O\Synchronization.obj \ + $O\Window.obj \ + +WIN_CTRL_OBJS = \ + $O\Dialog.obj \ + +7ZIP_COMMON_OBJS = \ + $O\FileStreams.obj \ + $O\InBuffer.obj \ + $O\LimitedStreams.obj \ + $O\LockedStream.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\StreamBinder.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveOpenCallback.obj \ + $O\ArchiverInfo.obj \ + $O\DefaultName.obj \ + $O\OpenArchive.obj \ + +FM_OBJS = \ + $O\FormatUtils.obj \ + +AR_COMMON_OBJS = \ + $O\CoderMixer2.obj \ + $O\CoderMixer2MT.obj \ + $O\CrossThreadProgress.obj \ + $O\FilterCoder.obj \ + $O\ItemNameUtils.obj \ + $O\OutStreamWithCRC.obj \ + +7Z_OBJS = \ + $O\7zDecode.obj \ + $O\7zExtract.obj \ + $O\7zFolderOutStream.obj \ + $O\7zHandler.obj \ + $O\7zHeader.obj \ + $O\7zIn.obj \ + $O\7zMethodID.obj \ + +BRANCH_OPT_OBJS = \ + $O\BranchCoder.obj \ + $O\x86.obj \ + $O\x86_2.obj \ + +LZ_OBJS = \ + $O\LZOutWindow.obj \ + +LZMA_OPT_OBJS = \ + $O\LZMADecoder.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(SFX_WIN_OBJS) \ + $(GUI_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(WIN_CTRL_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(UI_COMMON_OBJS) \ + $(FM_OBJS)\ + $(AR_COMMON_OBJS) \ + $(7Z_OBJS) \ + $(BRANCH_OPT_OBJS) \ + $(LZ_OBJS) \ + $(LZMA_OPT_OBJS) \ + $O\CopyCoder.obj \ + $O\MyMessages.obj \ + $O\ProgressDialog.obj \ + $O\resource.res + + +!include "../../../Build.mak" + +$(SFX_WIN_OBJS): $(*B).cpp + $(COMPL) + +$(GUI_OBJS): ../../UI/GUI/$(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(WIN_CTRL_OBJS): ../../../Windows/Control/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp + $(COMPL) +$(FM_OBJS): ../../FileManager/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp + $(COMPL) + +$(7Z_OBJS): ../../Archive/7z/$(*B).cpp + $(COMPL) +$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp + $(COMPL) +$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp + $(COMPL) +$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp + $(COMPL) + +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) +$O\MyMessages.obj: ../../UI/Explorer/MyMessages.cpp + $(COMPL) +$O\ProgressDialog.obj: ../../FileManager/Resource/ProgressDialog/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/Bundles/SFXSetup/resource.h b/CPP/7zip/Bundles/SFXSetup/resource.h new file mode 100755 index 00000000..2c7e5a22 --- /dev/null +++ b/CPP/7zip/Bundles/SFXSetup/resource.h @@ -0,0 +1,6 @@ +#define IDI_ICON3 159 + +#define IDS_EXTRACTION_ERROR_TITLE 7 +#define IDS_EXTRACTION_ERROR_MESSAGE 8 +#define IDS_CANNOT_CREATE_FOLDER 9 +#define IDS_PROGRESS_EXTRACTING 69 diff --git a/CPP/7zip/Bundles/SFXSetup/resource.rc b/CPP/7zip/Bundles/SFXSetup/resource.rc new file mode 100755 index 00000000..4bf6a585 --- /dev/null +++ b/CPP/7zip/Bundles/SFXSetup/resource.rc @@ -0,0 +1,16 @@ +#include "../../MyVersionInfo.rc" +#include "resource.h" + +MY_VERSION_INFO_APP("7z Setup SFX", "7zS.sfx") + +IDI_ICON3 ICON "setup.ico" + +STRINGTABLE +BEGIN + IDS_EXTRACTION_ERROR_TITLE "Extraction Failed" + IDS_EXTRACTION_ERROR_MESSAGE "File is corrupt" + IDS_CANNOT_CREATE_FOLDER "Cannot create folder '{0}'" + IDS_PROGRESS_EXTRACTING "Extracting" +END + +#include "../../FileManager/Resource/ProgressDialog/resource.rc" diff --git a/CPP/7zip/Bundles/SFXSetup/setup.ico b/CPP/7zip/Bundles/SFXSetup/setup.ico new file mode 100755 index 00000000..bb455be1 Binary files /dev/null and b/CPP/7zip/Bundles/SFXSetup/setup.ico differ diff --git a/CPP/7zip/Bundles/SFXWin/7z.ico b/CPP/7zip/Bundles/SFXWin/7z.ico new file mode 100755 index 00000000..47ffb781 Binary files /dev/null and b/CPP/7zip/Bundles/SFXWin/7z.ico differ diff --git a/CPP/7zip/Bundles/SFXWin/Main.cpp b/CPP/7zip/Bundles/SFXWin/Main.cpp new file mode 100755 index 00000000..166d58cb --- /dev/null +++ b/CPP/7zip/Bundles/SFXWin/Main.cpp @@ -0,0 +1,115 @@ +// Main.cpp + +#include "StdAfx.h" + +#include + +#include "Common/StringConvert.h" +#include "Common/CommandLineParser.h" + +#include "Windows/FileDir.h" +#include "Windows/FileName.h" +#include "Windows/DLL.h" + +#include "../../ICoder.h" +#include "../../IPassword.h" +#include "../../Archive/IArchive.h" +#include "../../UI/Common/Extract.h" +#include "../../UI/Explorer/MyMessages.h" +#include "../../UI/GUI/ExtractGUI.h" + +HINSTANCE g_hInstance; +#ifndef _UNICODE +bool g_IsNT = false; +static inline bool IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); +} +#endif + +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, LPSTR /* lpCmdLine */, int /* nCmdShow */) +{ + g_hInstance = (HINSTANCE)hInstance; + #ifndef _UNICODE + g_IsNT = IsItWindowsNT(); + #endif + + UString password; + bool assumeYes = false; + bool outputFolderDefined = false; + UString outputFolder; + UStringVector subStrings; + NCommandLineParser::SplitCommandLine(GetCommandLineW(), subStrings); + for (int i = 1; i < subStrings.Size(); i++) + { + const UString &s = subStrings[i]; + if (s.CompareNoCase(L"-y") == 0) + assumeYes = true; + else if (s.Left(2).CompareNoCase(L"-o") == 0) + { + outputFolder = s.Mid(2); + NWindows::NFile::NName::NormalizeDirPathPrefix(outputFolder); + outputFolderDefined = !outputFolder.IsEmpty(); + } + else if (s.Left(2).CompareNoCase(L"-p") == 0) + { + password = s.Mid(2); + } + } + + UString path; + NWindows::NDLL::MyGetModuleFileName(g_hInstance, path); + + UString fullPath; + int fileNamePartStartIndex; + if (!NWindows::NFile::NDirectory::MyGetFullPathName(path, fullPath, fileNamePartStartIndex)) + { + MyMessageBox(L"Error 1329484"); + return 1; + } + + COpenCallbackGUI openCallback; + + openCallback.PasswordIsDefined = !password.IsEmpty(); + openCallback.Password = password; + + CExtractCallbackImp *ecs = new CExtractCallbackImp; + CMyComPtr extractCallback = ecs; + ecs->Init(); + ecs->PasswordIsDefined = !password.IsEmpty(); + ecs->Password = password; + + CExtractOptions eo; + eo.OutputDir = outputFolderDefined ? outputFolder : + fullPath.Left(fileNamePartStartIndex); + eo.YesToAll = assumeYes; + eo.OverwriteMode = assumeYes ? + NExtract::NOverwriteMode::kWithoutPrompt : + NExtract::NOverwriteMode::kAskBefore; + eo.PathMode = NExtract::NPathMode::kFullPathnames; + eo.TestMode = false; + + UStringVector v1, v2; + v1.Add(fullPath); + v2.Add(fullPath); + NWildcard::CCensorNode wildcardCensor; + wildcardCensor.AddItem(true, L"*", true, true, true); + + HRESULT result = ExtractGUI(v1, v2, + wildcardCensor, eo, (assumeYes ? false: true), &openCallback, ecs); + + /* + HRESULT result = ExtractArchive(NULL, path, assumeYes, !assumeYes, + outputFolderDefined ? outputFolder : + fullPath.Left(fileNamePartStartIndex)); + */ + if (result == S_FALSE) + MyMessageBox(L"Archive is not supported"); + else if (result != S_OK && result != E_ABORT) + ShowErrorMessage(0, result); + return 0; +} diff --git a/CPP/7zip/Bundles/SFXWin/SFXWin.dsp b/CPP/7zip/Bundles/SFXWin/SFXWin.dsp new file mode 100755 index 00000000..ead66bc6 --- /dev/null +++ b/CPP/7zip/Bundles/SFXWin/SFXWin.dsp @@ -0,0 +1,847 @@ +# Microsoft Developer Studio Project File - Name="SFXWin" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=SFXWin - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "SFXWin.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "SFXWin.mak" CFG="SFXWin - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "SFXWin - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "SFXWin - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "SFXWin - Win32 ReleaseD" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "SFXWin - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_PPMD" /D "_SFX" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7z.sfx" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "SFXWin - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_PPMD" /D "_SFX" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Util\7z.sfx" /pdbtype:sept + +!ELSEIF "$(CFG)" == "SFXWin - Win32 ReleaseD" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "SFXWin___Win32_ReleaseD" +# PROP BASE Intermediate_Dir "SFXWin___Win32_ReleaseD" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "SFXWin___Win32_ReleaseD" +# PROP Intermediate_Dir "SFXWin___Win32_ReleaseD" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_PPMD" /D "_SFX" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "EXTRACT_ONLY" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_PPMD" /D "_SFX" /D "CRYPTO_7ZAES" /D "CRYPTO_AES" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7z.sfx" /opt:NOWIN98 +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zD.sfx" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "SFXWin - Win32 Release" +# Name "SFXWin - Win32 Debug" +# Name "SFXWin - Win32 ReleaseD" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "7z" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zExtract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethodID.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zMethodID.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2MT.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CrossThreadProgress.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Group "LZMA" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZMA\LZMADecoder.cpp +# End Source File +# End Group +# Begin Group "Branch" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Branch\BranchCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\BranchCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Branch\x86_2.cpp +# End Source File +# End Group +# Begin Group "PPMD" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDContext.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDDecode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDSubAlloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PPMD\PPMDType.h +# End Source File +# End Group +# Begin Group "LZ" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.h +# End Source File +# End Group +# Begin Group "Copy" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# End Group +# Begin Group "Crypto" + +# PROP Default_Filter "" +# Begin Group "AES" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\AES\aes.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\AES_CBC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aescpp.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aescrypt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aeskey.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aesopt.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\aestab.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\MyAES.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\AES\MyAES.h +# End Source File +# End Group +# Begin Group "7zAES" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\7zAES\7zAES.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\7zAES\7zAES.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\7zAES\MySHA256.h +# End Source File +# End Group +# Begin Group "Hash" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\Hash\RotateDefs.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Hash\Sha256.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Hash\Sha256.h +# End Source File +# End Group +# End Group +# Begin Group "Dialogs" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\FileManager\Resource\MessagesDialog\MessagesDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\Resource\MessagesDialog\MessagesDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\Resource\OverwriteDialog\OverwriteDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\Resource\OverwriteDialog\OverwriteDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\Resource\PasswordDialog\PasswordDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\Resource\PasswordDialog\PasswordDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\Resource\ProgressDialog\ProgressDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\Resource\ProgressDialog\ProgressDialog.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "File Manager" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\FileManager\ExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\ExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\FormatUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\FormatUtils.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Group "Control" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Shell.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Shell.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "UI" + +# PROP Default_Filter "" +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiverInfo.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiverInfo.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Extract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Extract.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractingFilePath.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractingFilePath.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\OpenArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\OpenArchive.h +# End Source File +# End Group +# Begin Group "GUI" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\GUI\ExtractDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\ExtractDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\ExtractGUI.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\ExtractGUI.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\OpenCallbackGUI.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\OpenCallbackGUI.h +# End Source File +# End Group +# Begin Group "Explorer" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Explorer\MyMessages.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Explorer\MyMessages.h +# End Source File +# End Group +# End Group +# Begin Source File + +SOURCE=.\7z.ico +# End Source File +# Begin Source File + +SOURCE=.\7z1.ico +# End Source File +# Begin Source File + +SOURCE=.\Main.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/Bundles/SFXWin/SFXWin.dsw b/CPP/7zip/Bundles/SFXWin/SFXWin.dsw new file mode 100755 index 00000000..a9926c71 --- /dev/null +++ b/CPP/7zip/Bundles/SFXWin/SFXWin.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "SFXWin"=.\SFXWin.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Bundles/SFXWin/StdAfx.cpp b/CPP/7zip/Bundles/SFXWin/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Bundles/SFXWin/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Bundles/SFXWin/StdAfx.h b/CPP/7zip/Bundles/SFXWin/StdAfx.h new file mode 100755 index 00000000..c5f7231f --- /dev/null +++ b/CPP/7zip/Bundles/SFXWin/StdAfx.h @@ -0,0 +1,12 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" +#include "../../../Common/NewHandler.h" + +#include +#include + +#endif diff --git a/CPP/7zip/Bundles/SFXWin/makefile b/CPP/7zip/Bundles/SFXWin/makefile new file mode 100755 index 00000000..00d3ecc6 --- /dev/null +++ b/CPP/7zip/Bundles/SFXWin/makefile @@ -0,0 +1,207 @@ +PROG = 7z.sfx +LIBS = $(LIBS) user32.lib oleaut32.lib shell32.lib ole32.lib +CFLAGS = $(CFLAGS) -I ../../../ \ + -DEXCLUDE_COM \ + -DNO_REGISTRY \ + -DEXTRACT_ONLY \ + -D_SFX \ + -DFORMAT_7Z \ + -DCOMPRESS_BCJ_X86 \ + -DCOMPRESS_BCJ2 \ + -DCOMPRESS_COPY \ + -DCOMPRESS_LZMA \ + -DCOMPRESS_PPMD \ + -DCRYPTO_AES \ + -DCRYPTO_7ZAES \ + + +SFX_WIN_OBJS = \ + $O\Main.obj \ + +GUI_OBJS = \ + $O\ExtractDialog.obj \ + $O\ExtractGUI.obj \ + $O\OpenCallbackGUI.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CommandLineParser.obj \ + $O\CRC.obj \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\Vector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\Error.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\PropVariant.obj \ + $O\PropVariantConversions.obj \ + $O\ResourceString.obj \ + $O\Shell.obj \ + $O\Synchronization.obj \ + $O\Window.obj \ + +WIN_CTRL_OBJS = \ + $O\Dialog.obj \ + +7ZIP_COMMON_OBJS = \ + $O\FilePathAutoRename.obj \ + $O\FileStreams.obj \ + $O\InBuffer.obj \ + $O\LimitedStreams.obj \ + $O\LockedStream.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\StreamBinder.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveExtractCallback.obj \ + $O\ArchiveOpenCallback.obj \ + $O\ArchiverInfo.obj \ + $O\DefaultName.obj \ + $O\Extract.obj \ + $O\ExtractingFilePath.obj \ + $O\OpenArchive.obj \ + +FM_OBJS = \ + $O\ExtractCallback.obj \ + $O\FormatUtils.obj \ + +AR_COMMON_OBJS = \ + $O\CoderMixer2.obj \ + $O\CoderMixer2MT.obj \ + $O\CrossThreadProgress.obj \ + $O\FilterCoder.obj \ + $O\ItemNameUtils.obj \ + $O\OutStreamWithCRC.obj \ + +7Z_OBJS = \ + $O\7zDecode.obj \ + $O\7zExtract.obj \ + $O\7zFolderOutStream.obj \ + $O\7zHandler.obj \ + $O\7zHeader.obj \ + $O\7zIn.obj \ + $O\7zMethodID.obj \ + +BRANCH_OPT_OBJS = \ + $O\BranchCoder.obj \ + $O\x86.obj \ + $O\x86_2.obj \ + +LZ_OBJS = \ + $O\LZOutWindow.obj \ + +LZMA_OPT_OBJS = \ + $O\LZMADecoder.obj \ + +PPMD_OPT_OBJS = \ + $O\PPMDDecoder.obj \ + +7ZAES_OPT_OBJS = \ + $O\7zAES.obj \ + +AES_OPT_OBJS = \ + $O\MyAES.obj \ + +AES_ORIG_OBJS = \ + $O\aescrypt.obj \ + $O\aeskey.obj \ + $O\aestab.obj \ + +CRYPTO_HASH_OBJS = \ + $O\Sha256.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(SFX_WIN_OBJS) \ + $(GUI_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(WIN_CTRL_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(UI_COMMON_OBJS) \ + $(FM_OBJS)\ + $(AR_COMMON_OBJS) \ + $(7Z_OBJS) \ + $(BRANCH_OPT_OBJS) \ + $(LZ_OBJS) \ + $(LZMA_OPT_OBJS) \ + $(PPMD_OPT_OBJS) \ + $O\CopyCoder.obj \ + $(CRYPTO_HASH_OBJS) \ + $(7ZAES_OPT_OBJS) \ + $(AES_OPT_OBJS) \ + $(AES_ORIG_OBJS) \ + $O\MyMessages.obj \ + $O\MessagesDialog.obj \ + $O\OverwriteDialog.obj \ + $O\PasswordDialog.obj \ + $O\ProgressDialog.obj \ + $O\resource.res + + +!include "../../../Build.mak" + +$(SFX_WIN_OBJS): $(*B).cpp + $(COMPL) + +$(GUI_OBJS): ../../UI/GUI/$(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(WIN_CTRL_OBJS): ../../../Windows/Control/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp + $(COMPL) +$(FM_OBJS): ../../FileManager/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp + $(COMPL) + +$(7Z_OBJS): ../../Archive/7z/$(*B).cpp + $(COMPL) +$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp + $(COMPL) +$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp + $(COMPL) +$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp + $(COMPL) +$(PPMD_OPT_OBJS): ../../Compress/PPMD/$(*B).cpp + $(COMPL) + +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) + +$(CRYPTO_HASH_OBJS): ../../Crypto/Hash/$(*B).cpp + $(COMPL) +$(7ZAES_OPT_OBJS): ../../Crypto/7zAES/$(*B).cpp + $(COMPL) +$(AES_OPT_OBJS): ../../Crypto/AES/$(*B).cpp + $(COMPL) +$(AES_ORIG_OBJS): ../../Crypto/AES/$(*B).c + $(COMPL_O1_W3) + +$O\MyMessages.obj: ../../UI/Explorer/MyMessages.cpp + $(COMPL) +$O\MessagesDialog.obj: ../../FileManager/Resource/MessagesDialog/$(*B).cpp + $(COMPL) +$O\OverwriteDialog.obj: ../../FileManager/Resource/OverwriteDialog./$(*B).cpp + $(COMPL) +$O\PasswordDialog.obj: ../../FileManager/Resource/PasswordDialog/$(*B).cpp + $(COMPL) +$O\ProgressDialog.obj: ../../FileManager/Resource/ProgressDialog/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/Bundles/SFXWin/resource.h b/CPP/7zip/Bundles/SFXWin/resource.h new file mode 100755 index 00000000..0a460213 --- /dev/null +++ b/CPP/7zip/Bundles/SFXWin/resource.h @@ -0,0 +1,7 @@ +#define IDD_DIALOG_EXTRACT 137 + +#define IDI_ICON3 159 + +#define IDC_STATIC_EXTRACT_EXTRACT_TO 1020 +#define IDC_EXTRACT_COMBO_PATH 1021 +#define IDC_EXTRACT_BUTTON_SET_PATH 1022 diff --git a/CPP/7zip/Bundles/SFXWin/resource.rc b/CPP/7zip/Bundles/SFXWin/resource.rc new file mode 100755 index 00000000..60304803 --- /dev/null +++ b/CPP/7zip/Bundles/SFXWin/resource.rc @@ -0,0 +1,34 @@ +#include "../../MyVersionInfo.rc" +#include "../../GuiCommon.rc" +#include "resource.h" + +MY_VERSION_INFO_APP("7z SFX", "7z.sfx") + +#define xSize2 214 +#define ySize2 64 + +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#define bYPos (ySize - marg - bYSize) +#define bXPos1 (xSize - marg - bXSize) +#define bXPos2 (bXPos1 - 10 - bXSize) + +IDI_ICON3 ICON "7z.ico" + +IDD_DIALOG_EXTRACT DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE +CAPTION "7-Zip self-extracting archive" +MY_FONT +BEGIN + LTEXT "E&xtract to:", IDC_STATIC_EXTRACT_EXTRACT_TO, marg, marg, xSize2, 8 + EDITTEXT IDC_EXTRACT_COMBO_PATH, marg, 21, xSize2 - bDotsSize - 13, 14, ES_AUTOHSCROLL + PUSHBUTTON "...", IDC_EXTRACT_BUTTON_SET_PATH, xSize - marg - bDotsSize, 20, bDotsSize, bYSize, WS_GROUP + DEFPUSHBUTTON "Extract", IDOK, , bXPos2, bYPos, bXSize, bYSize, WS_GROUP + PUSHBUTTON "Cancel", IDCANCEL, bXPos1, bYPos, bXSize, bYSize +END + +#include "../../FileManager/Resource/MessagesDialog/resource.rc" +#include "../../FileManager/Resource/OverwriteDialog/resource.rc" +#include "../../FileManager/Resource/PasswordDialog/resource.rc" +#include "../../FileManager/Resource/ProgressDialog/resource.rc" +#include "../../UI/Resource/Extract/resource.rc" diff --git a/CPP/7zip/Bundles/makefile b/CPP/7zip/Bundles/makefile new file mode 100755 index 00000000..7e7d7cdc --- /dev/null +++ b/CPP/7zip/Bundles/makefile @@ -0,0 +1,15 @@ +DIRS = \ + Alone\~ \ + Alone7z\~ \ + Format7z\~ \ + Format7zR\~ \ + Format7zExtract\~ \ + Format7zExtractR\~ \ + SFXCon\~ \ + SFXSetup\~ \ + SFXWin\~ \ + +all: $(DIRS) + +$(DIRS): +!include "../SubBuild.mak" diff --git a/CPP/7zip/Common/FilePathAutoRename.cpp b/CPP/7zip/Common/FilePathAutoRename.cpp new file mode 100755 index 00000000..3c5b910f --- /dev/null +++ b/CPP/7zip/Common/FilePathAutoRename.cpp @@ -0,0 +1,57 @@ +// FilePathAutoRename.cpp + +#include "StdAfx.h" +#include "FilePathAutoRename.h" + +#include "Common/Defs.h" +#include "Common/IntToString.h" + +#include "Windows/FileName.h" +#include "Windows/FileFind.h" + +using namespace NWindows; + +static bool MakeAutoName(const UString &name, + const UString &extension, int value, UString &path) +{ + wchar_t number[32]; + ConvertUInt64ToString(value, number); + path = name; + path += number; + path += extension; + return NFile::NFind::DoesFileExist(path); +} + +bool AutoRenamePath(UString &fullProcessedPath) +{ + UString path; + int dotPos = fullProcessedPath.ReverseFind(L'.'); + + int slashPos = fullProcessedPath.ReverseFind(L'/'); + #ifdef _WIN32 + int slash1Pos = fullProcessedPath.ReverseFind(L'\\'); + slashPos = MyMax(slashPos, slash1Pos); + #endif + + UString name, extension; + if (dotPos > slashPos && dotPos > 0) + { + name = fullProcessedPath.Left(dotPos); + extension = fullProcessedPath.Mid(dotPos); + } + else + name = fullProcessedPath; + name += L'_'; + int indexLeft = 1, indexRight = (1 << 30); + while (indexLeft != indexRight) + { + int indexMid = (indexLeft + indexRight) / 2; + if (MakeAutoName(name, extension, indexMid, path)) + indexLeft = indexMid + 1; + else + indexRight = indexMid; + } + if (MakeAutoName(name, extension, indexRight, fullProcessedPath)) + return false; + return true; +} diff --git a/CPP/7zip/Common/FilePathAutoRename.h b/CPP/7zip/Common/FilePathAutoRename.h new file mode 100755 index 00000000..99323094 --- /dev/null +++ b/CPP/7zip/Common/FilePathAutoRename.h @@ -0,0 +1,10 @@ +// Util/FilePathAutoRename.h + +#ifndef __FILEPATHAUTORENAME_H +#define __FILEPATHAUTORENAME_H + +#include "Common/String.h" + +bool AutoRenamePath(UString &fullProcessedPath); + +#endif diff --git a/CPP/7zip/Common/FileStreams.cpp b/CPP/7zip/Common/FileStreams.cpp new file mode 100755 index 00000000..8a000e4e --- /dev/null +++ b/CPP/7zip/Common/FileStreams.cpp @@ -0,0 +1,251 @@ +// FileStreams.cpp + +#include "StdAfx.h" + +#ifndef _WIN32 +#include +#include +#include +#endif + +#include "FileStreams.h" + +static inline HRESULT ConvertBoolToHRESULT(bool result) +{ + // return result ? S_OK: E_FAIL; + #ifdef _WIN32 + return result ? S_OK: (::GetLastError()); + #else + return result ? S_OK: E_FAIL; + #endif +} + +bool CInFileStream::Open(LPCTSTR fileName) +{ + return File.Open(fileName); +} + +#ifdef _WIN32 +#ifndef _UNICODE +bool CInFileStream::Open(LPCWSTR fileName) +{ + return File.Open(fileName); +} +#endif +#endif + +STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + #ifdef _WIN32 + + UInt32 realProcessedSize; + bool result = File.ReadPart(data, size, realProcessedSize); + if(processedSize != NULL) + *processedSize = realProcessedSize; + return ConvertBoolToHRESULT(result); + + #else + + if(processedSize != NULL) + *processedSize = 0; + ssize_t res = File.Read(data, (size_t)size); + if (res == -1) + return E_FAIL; + if(processedSize != NULL) + *processedSize = (UInt32)res; + return S_OK; + + #endif +} + +#ifndef _WIN32_WCE +STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + #ifdef _WIN32 + UInt32 realProcessedSize; + BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE), + data, size, (DWORD *)&realProcessedSize, NULL); + if(processedSize != NULL) + *processedSize = realProcessedSize; + if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE) + return S_OK; + return ConvertBoolToHRESULT(res != FALSE); + + #else + + if(processedSize != NULL) + *processedSize = 0; + ssize_t res; + do + { + res = read(0, data, (size_t)size); + } + while (res < 0 && (errno == EINTR)); + if (res == -1) + return E_FAIL; + if(processedSize != NULL) + *processedSize = (UInt32)res; + return S_OK; + + #endif +} + +#endif + +STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, + UInt64 *newPosition) +{ + if(seekOrigin >= 3) + return STG_E_INVALIDFUNCTION; + + #ifdef _WIN32 + + UInt64 realNewPosition; + bool result = File.Seek(offset, seekOrigin, realNewPosition); + if(newPosition != NULL) + *newPosition = realNewPosition; + return ConvertBoolToHRESULT(result); + + #else + + off_t res = File.Seek(offset, seekOrigin); + if (res == -1) + return E_FAIL; + if(newPosition != NULL) + *newPosition = (UInt64)res; + return S_OK; + + #endif +} + +STDMETHODIMP CInFileStream::GetSize(UInt64 *size) +{ + return ConvertBoolToHRESULT(File.GetLength(*size)); +} + + +////////////////////////// +// COutFileStream + +bool COutFileStream::Create(LPCTSTR fileName, bool createAlways) +{ + return File.Create(fileName, createAlways); +} + +#ifdef _WIN32 +#ifndef _UNICODE +bool COutFileStream::Create(LPCWSTR fileName, bool createAlways) +{ + return File.Create(fileName, createAlways); +} +#endif +#endif + +STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + #ifdef _WIN32 + + UInt32 realProcessedSize; + bool result = File.WritePart(data, size, realProcessedSize); + if(processedSize != NULL) + *processedSize = realProcessedSize; + return ConvertBoolToHRESULT(result); + + #else + + if(processedSize != NULL) + *processedSize = 0; + ssize_t res = File.Write(data, (size_t)size); + if (res == -1) + return E_FAIL; + if(processedSize != NULL) + *processedSize = (UInt32)res; + return S_OK; + + #endif +} + +STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, + UInt64 *newPosition) +{ + if(seekOrigin >= 3) + return STG_E_INVALIDFUNCTION; + #ifdef _WIN32 + + UInt64 realNewPosition; + bool result = File.Seek(offset, seekOrigin, realNewPosition); + if(newPosition != NULL) + *newPosition = realNewPosition; + return ConvertBoolToHRESULT(result); + + #else + + off_t res = File.Seek(offset, seekOrigin); + if (res == -1) + return E_FAIL; + if(newPosition != NULL) + *newPosition = (UInt64)res; + return S_OK; + + #endif +} + +STDMETHODIMP COutFileStream::SetSize(Int64 newSize) +{ + #ifdef _WIN32 + UInt64 currentPos; + if(!File.Seek(0, FILE_CURRENT, currentPos)) + return E_FAIL; + bool result = File.SetLength(newSize); + UInt64 currentPos2; + result = result && File.Seek(currentPos, currentPos2); + return result ? S_OK : E_FAIL; + #else + return E_FAIL; + #endif +} + +#ifndef _WIN32_WCE +STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if(processedSize != NULL) + *processedSize = 0; + + #ifdef _WIN32 + UInt32 realProcessedSize; + BOOL res = TRUE; + if (size > 0) + { + // Seems that Windows doesn't like big amounts writing to stdout. + // So we limit portions by 32KB. + UInt32 sizeTemp = (1 << 15); + if (sizeTemp > size) + sizeTemp = size; + res = ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), + data, sizeTemp, (DWORD *)&realProcessedSize, NULL); + size -= realProcessedSize; + data = (const void *)((const Byte *)data + realProcessedSize); + if(processedSize != NULL) + *processedSize += realProcessedSize; + } + return ConvertBoolToHRESULT(res != FALSE); + + #else + + ssize_t res; + do + { + res = write(1, data, (size_t)size); + } + while (res < 0 && (errno == EINTR)); + if (res == -1) + return E_FAIL; + if(processedSize != NULL) + *processedSize = (UInt32)res; + return S_OK; + + return S_OK; + #endif +} + +#endif diff --git a/CPP/7zip/Common/FileStreams.h b/CPP/7zip/Common/FileStreams.h new file mode 100755 index 00000000..9326372a --- /dev/null +++ b/CPP/7zip/Common/FileStreams.h @@ -0,0 +1,98 @@ +// FileStreams.h + +#ifndef __FILESTREAMS_H +#define __FILESTREAMS_H + +#ifdef _WIN32 +#include "../../Windows/FileIO.h" +#else +#include "../../Common/C_FileIO.h" +#endif + +#include "../IStream.h" +#include "../../Common/MyCom.h" + +class CInFileStream: + public IInStream, + public IStreamGetSize, + public CMyUnknownImp +{ +public: + #ifdef _WIN32 + NWindows::NFile::NIO::CInFile File; + #else + NC::NFile::NIO::CInFile File; + #endif + CInFileStream() {} + virtual ~CInFileStream() {} + + bool Open(LPCTSTR fileName); + #ifdef _WIN32 + #ifndef _UNICODE + bool Open(LPCWSTR fileName); + #endif + #endif + + MY_UNKNOWN_IMP2(IInStream, IStreamGetSize) + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); + + STDMETHOD(GetSize)(UInt64 *size); +}; + +#ifndef _WIN32_WCE +class CStdInFileStream: + public ISequentialInStream, + public CMyUnknownImp +{ +public: + // HANDLE File; + // CStdInFileStream() File(INVALID_HANDLE_VALUE): {} + // void Open() { File = GetStdHandle(STD_INPUT_HANDLE); }; + MY_UNKNOWN_IMP + + virtual ~CStdInFileStream() {} + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); +}; +#endif + +class COutFileStream: + public IOutStream, + public CMyUnknownImp +{ +public: + #ifdef _WIN32 + NWindows::NFile::NIO::COutFile File; + #else + NC::NFile::NIO::COutFile File; + #endif + virtual ~COutFileStream() {} + bool Create(LPCTSTR fileName, bool createAlways); + #ifdef _WIN32 + #ifndef _UNICODE + bool Create(LPCWSTR fileName, bool createAlways); + #endif + #endif + + MY_UNKNOWN_IMP1(IOutStream) + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); + STDMETHOD(SetSize)(Int64 newSize); +}; + +#ifndef _WIN32_WCE +class CStdOutFileStream: + public ISequentialOutStream, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + virtual ~CStdOutFileStream() {} + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; +#endif + +#endif diff --git a/CPP/7zip/Common/InBuffer.cpp b/CPP/7zip/Common/InBuffer.cpp new file mode 100755 index 00000000..02f2adfa --- /dev/null +++ b/CPP/7zip/Common/InBuffer.cpp @@ -0,0 +1,80 @@ +// InBuffer.cpp + +#include "StdAfx.h" + +#include "InBuffer.h" + +#include "../../Common/Alloc.h" + +CInBuffer::CInBuffer(): + _buffer(0), + _bufferLimit(0), + _bufferBase(0), + _stream(0), + _bufferSize(0) +{} + +bool CInBuffer::Create(UInt32 bufferSize) +{ + const UInt32 kMinBlockSize = 1; + if (bufferSize < kMinBlockSize) + bufferSize = kMinBlockSize; + if (_bufferBase != 0 && _bufferSize == bufferSize) + return true; + Free(); + _bufferSize = bufferSize; + _bufferBase = (Byte *)::MidAlloc(bufferSize); + return (_bufferBase != 0); +} + +void CInBuffer::Free() +{ + ::MidFree(_bufferBase); + _bufferBase = 0; +} + +void CInBuffer::SetStream(ISequentialInStream *stream) +{ + _stream = stream; +} + +void CInBuffer::Init() +{ + _processedSize = 0; + _buffer = _bufferBase; + _bufferLimit = _buffer; + _wasFinished = false; + #ifdef _NO_EXCEPTIONS + ErrorCode = S_OK; + #endif +} + +bool CInBuffer::ReadBlock() +{ + #ifdef _NO_EXCEPTIONS + if (ErrorCode != S_OK) + return false; + #endif + if (_wasFinished) + return false; + _processedSize += (_buffer - _bufferBase); + UInt32 numProcessedBytes; + HRESULT result = _stream->Read(_bufferBase, _bufferSize, &numProcessedBytes); + #ifdef _NO_EXCEPTIONS + ErrorCode = result; + #else + if (result != S_OK) + throw CInBufferException(result); + #endif + _buffer = _bufferBase; + _bufferLimit = _buffer + numProcessedBytes; + _wasFinished = (numProcessedBytes == 0); + return (!_wasFinished); +} + +Byte CInBuffer::ReadBlock2() +{ + if(!ReadBlock()) + return 0xFF; + return *_buffer++; +} diff --git a/CPP/7zip/Common/InBuffer.h b/CPP/7zip/Common/InBuffer.h new file mode 100755 index 00000000..057caa16 --- /dev/null +++ b/CPP/7zip/Common/InBuffer.h @@ -0,0 +1,76 @@ +// InBuffer.h + +#ifndef __INBUFFER_H +#define __INBUFFER_H + +#include "../IStream.h" +#include "../../Common/MyCom.h" + +#ifndef _NO_EXCEPTIONS +class CInBufferException +{ +public: + HRESULT ErrorCode; + CInBufferException(HRESULT errorCode): ErrorCode(errorCode) {} +}; +#endif + +class CInBuffer +{ + Byte *_buffer; + Byte *_bufferLimit; + Byte *_bufferBase; + CMyComPtr _stream; + UInt64 _processedSize; + UInt32 _bufferSize; + bool _wasFinished; + + bool ReadBlock(); + Byte ReadBlock2(); + +public: + #ifdef _NO_EXCEPTIONS + HRESULT ErrorCode; + #endif + + CInBuffer(); + ~CInBuffer() { Free(); } + + bool Create(UInt32 bufferSize); + void Free(); + + void SetStream(ISequentialInStream *stream); + void Init(); + void ReleaseStream() { _stream.Release(); } + + bool ReadByte(Byte &b) + { + if(_buffer >= _bufferLimit) + if(!ReadBlock()) + return false; + b = *_buffer++; + return true; + } + Byte ReadByte() + { + if(_buffer >= _bufferLimit) + return ReadBlock2(); + return *_buffer++; + } + void ReadBytes(void *data, UInt32 size, UInt32 &processedSize) + { + for(processedSize = 0; processedSize < size; processedSize++) + if (!ReadByte(((Byte *)data)[processedSize])) + return; + } + bool ReadBytes(void *data, UInt32 size) + { + UInt32 processedSize; + ReadBytes(data, size, processedSize); + return (processedSize == size); + } + UInt64 GetProcessedSize() const { return _processedSize + (_buffer - _bufferBase); } + bool WasFinished() const { return _wasFinished; } +}; + +#endif diff --git a/CPP/7zip/Common/InMemStream.cpp b/CPP/7zip/Common/InMemStream.cpp new file mode 100755 index 00000000..036ef3bd --- /dev/null +++ b/CPP/7zip/Common/InMemStream.cpp @@ -0,0 +1,222 @@ +// InMemStream.cpp + +#include "StdAfx.h" + +#include + +#include "Windows/Thread.h" + +#include "InMemStream.h" +#include "../../Common/Defs.h" + +void CStreamInfo::Free(IInMemStreamMtCallback *callback) +{ + for (int i = 0; i < Blocks.Size(); i++) + { + callback->FreeBlock(Blocks[i]); + Blocks[i] = 0; + } +} + +bool CInMemStreamMt::Create(int numSubStreams, UInt64 subStreamSize) +{ + Free(); + _subStreamSize = subStreamSize; + size_t blockSize = Callback->GetBlockSize(); + for (int i = 0; i < numSubStreams; i++) + { + _streams.Add(CStreamInfo()); + CStreamInfo &blocks = _streams.Back(); + blocks.Create(); + for (UInt64 j = 0; (UInt64)j * blockSize < _subStreamSize; j++) + blocks.Blocks.Add(0); + } + if (!_streamIndexAllocator.AllocateList(numSubStreams)) + return false; + return true; +} + +void CInMemStreamMt::Free() +{ + while(_streams.Size() > 0) + { + _streams.Back().Free(Callback); + _streams.DeleteBack(); + } +} + +HRESULT CInMemStreamMt::Read() +{ + for (;;) + { + // printf("\n_streamIndexAllocator.AllocateItem\n"); + int index = _streamIndexAllocator.AllocateItem(); + /* + if (_stopReading) + return E_ABORT; + */ + // printf("\nread Index = %d\n", index); + CStreamInfo &blocks = _streams[index]; + blocks.Init(); + Callback->AddStreamIndexToQueue(index); + + for (;;) + { + const Byte *p = (const Byte *)blocks.Blocks[blocks.LastBlockIndex]; + if (p == 0) + { + void **pp = &blocks.Blocks[blocks.LastBlockIndex]; + HRESULT res = Callback->AllocateBlock(pp); + p = (const Byte *)*pp; + RINOK(res); + if (p == 0) + return E_FAIL; + } + size_t blockSize = Callback->GetBlockSize(); + UInt32 curSize = (UInt32)(blockSize - blocks.LastBlockPos); + UInt32 realProcessedSize; + UInt64 pos64 = (UInt64)blocks.LastBlockIndex * blockSize + blocks.LastBlockPos; + if (curSize > _subStreamSize - pos64) + curSize = (UInt32)(_subStreamSize - pos64); + RINOK(_stream->Read((void *)(p + blocks.LastBlockPos), curSize, &realProcessedSize)); + + blocks.Cs->Enter(); + if (realProcessedSize == 0) + { + blocks.StreamWasFinished = true; + blocks.CanReadEvent->Set(); + blocks.Cs->Leave(); + + Callback->AddStreamIndexToQueue(-1); + return S_OK; + } + + blocks.LastBlockPos += realProcessedSize; + if (blocks.LastBlockPos == blockSize) + { + blocks.LastBlockPos = 0; + blocks.LastBlockIndex++; + } + pos64 += realProcessedSize; + if (pos64 >= _subStreamSize) + blocks.StreamWasFinished = true; + blocks.CanReadEvent->Set(); + blocks.Cs->Leave(); + if (pos64 >= _subStreamSize) + break; + } + } +} + +static DWORD WINAPI CoderThread(void *threadCoderInfo) +{ + ((CInMemStreamMt *)threadCoderInfo)->ReadResult = ((CInMemStreamMt *)threadCoderInfo)->Read(); + return 0; +} + +bool CInMemStreamMt::StartReadThread() +{ + // _stopReading = false; + NWindows::CThread Thread; + return Thread.Create(CoderThread, this); +} + +void CInMemStreamMt::FreeSubStream(int subStreamIndex) +{ + // printf("\nFreeSubStream\n"); + _streams[subStreamIndex].Free(Callback); + _streamIndexAllocator.FreeItem(subStreamIndex); + // printf("\nFreeSubStream end\n"); +} + +HRESULT CInMemStreamMt::ReadSubStream(int subStreamIndex, void *data, UInt32 size, UInt32 *processedSize, bool keepData) +{ + if (processedSize != NULL) + *processedSize = 0; + CStreamInfo &blocks = _streams[subStreamIndex]; + while (size > 0) + { + if (blocks.CurBlockPos == Callback->GetBlockSize()) + { + blocks.CurBlockPos = 0; + blocks.CurBlockIndex++; + } + UInt32 curSize; + UInt32 curPos = blocks.CurBlockPos; + + blocks.Cs->Enter(); + if (blocks.CurBlockIndex == blocks.LastBlockIndex) + { + curSize = blocks.LastBlockPos - curPos; + if (curSize == 0) + { + if (blocks.StreamWasFinished) + { + blocks.Cs->Leave(); + void *p = blocks.Blocks[blocks.CurBlockIndex]; + if (p != 0 && !keepData) + { + Callback->FreeBlock(p); + blocks.Blocks[blocks.CurBlockIndex] = 0; + } + return S_OK; + } + blocks.CanReadEvent->Reset(); + blocks.Cs->Leave(); + // printf("\nBlock Lock\n"); + blocks.CanReadEvent->Lock(); + // printf("\nAfter Lock\n"); + if (blocks.ExitResult != S_OK) + return blocks.ExitResult; + continue; + } + } + else + curSize = Callback->GetBlockSize() - curPos; + blocks.Cs->Leave(); + + if (curSize > size) + curSize = size; + void *p = blocks.Blocks[blocks.CurBlockIndex]; + memmove(data, (const Byte *)p + curPos, curSize); + data = (void *)((Byte *)data + curSize); + size -= curSize; + if (processedSize != NULL) + *processedSize += curSize; + curPos += curSize; + + bool needFree = false; + blocks.CurBlockPos = curPos; + + if (curPos == Callback->GetBlockSize()) + needFree = true; + blocks.Cs->Enter(); + if (blocks.CurBlockIndex == blocks.LastBlockIndex && + blocks.CurBlockPos == blocks.LastBlockPos && + blocks.StreamWasFinished) + needFree = true; + blocks.Cs->Leave(); + + if (needFree && !keepData) + { + Callback->FreeBlock(p); + blocks.Blocks[blocks.CurBlockIndex] = 0; + } + return S_OK; + } + return S_OK; +} + +STDMETHODIMP CInMemStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize; + HRESULT result = mtStream->ReadSubStream(Index, data, size, &realProcessedSize, _keepData); + if (processedSize != NULL) + *processedSize = realProcessedSize; + if (realProcessedSize != 0) + { + // printf("\ns = %d\n", Index); + } + _size += realProcessedSize; + return result; +} diff --git a/CPP/7zip/Common/InMemStream.h b/CPP/7zip/Common/InMemStream.h new file mode 100755 index 00000000..fcd0092d --- /dev/null +++ b/CPP/7zip/Common/InMemStream.h @@ -0,0 +1,282 @@ +// InMemStream.h + +#ifndef __INMEMSTREAM_H +#define __INMEMSTREAM_H + +#include + +#include "../../Common/MyCom.h" +#include "MemBlocks.h" + +class CIntListCheck +{ +protected: + int *_data; +public: + CIntListCheck(): _data(0) {} + ~CIntListCheck() { FreeList(); } + + bool AllocateList(int numItems) + { + FreeList(); + if (numItems == 0) + return true; + _data = (int *)::MyAlloc(numItems * sizeof(int)); + return (_data != 0); + } + + void FreeList() + { + ::MyFree(_data); + _data = 0; + } +}; + + +class CResourceList : public CIntListCheck +{ + int _headFree; +public: + CResourceList(): _headFree(-1) {} + + bool AllocateList(int numItems) + { + FreeList(); + if (numItems == 0) + return true; + if (!CIntListCheck::AllocateList(numItems)) + return false; + for (int i = 0; i < numItems; i++) + _data[i] = i + 1; + _data[numItems - 1] = -1; + _headFree = 0; + return true; + } + + void FreeList() + { + CIntListCheck::FreeList(); + _headFree = -1; + } + + int AllocateItem() + { + int res = _headFree; + if (res >= 0) + _headFree = _data[res]; + return res; + } + + void FreeItem(int index) + { + if (index < 0) + return; + _data[index] = _headFree; + _headFree = index; + } +}; + +class CResourceListMt: public CResourceList +{ + NWindows::NSynchronization::CCriticalSection _criticalSection; +public: + NWindows::NSynchronization::CSemaphore Semaphore; + + bool AllocateList(int numItems) + { + if (!CResourceList::AllocateList(numItems)) + return false; + return Semaphore.Create((LONG)numItems, (LONG)numItems); + } + + int AllocateItem() + { + Semaphore.Lock(); + _criticalSection.Enter(); + int res = CResourceList::AllocateItem(); + _criticalSection.Leave(); + return res; + } + + void FreeItem(int index) + { + if (index < 0) + return; + _criticalSection.Enter(); + CResourceList::FreeItem(index); + _criticalSection.Leave(); + Semaphore.Release(); + } +}; + +class CIntQueueMt: public CIntListCheck +{ + int _numItems; + int _head; + int _cur; +public: + CIntQueueMt(): _numItems(0), _head(0), _cur(0) {} + NWindows::NSynchronization::CSemaphore Semaphore; + + bool AllocateList(int numItems) + { + FreeList(); + if (numItems == 0) + return true; + if (!CIntListCheck::AllocateList(numItems)) + return false; + _numItems = numItems; + return Semaphore.Create((LONG)0, (LONG)numItems); + } + + void FreeList() + { + CIntListCheck::FreeList(); + _numItems = 0; + _head = 0; + _cur = 0; + } + + void AddItem(int value) + { + _data[_head++] = value; + if (_head == _numItems) + _head = 0; + LONG previousCount; + Semaphore.Release(1, &previousCount); + // printf("\nRelease prev = %d\n", previousCount); + + } + + int GetItem() + { + // Semaphore.Lock(); + int res = _data[_cur++]; + if (_cur == _numItems) + _cur = 0; + return res; + } +}; + +struct IInMemStreamMtCallback +{ + // must be same for all calls + virtual size_t GetBlockSize() = 0; + + // Out: + // result != S_OK stops Reading + // if *p = 0, result must be != S_OK; + // Locking is allowed + virtual HRESULT AllocateBlock(void **p) = 0; + + virtual void FreeBlock(void *p) = 0; + + // It must allow to add at least numSubStreams + 1 , + // where numSubStreams is value from CInMemStreamMt::Create + // value -1 means End of stream + // Locking is not allowed + virtual void AddStreamIndexToQueue(int index) = 0; +}; + +struct CStreamInfo +{ + CRecordVector Blocks; + + int LastBlockIndex; + size_t LastBlockPos; + bool StreamWasFinished; + + int CurBlockIndex; + size_t CurBlockPos; + + NWindows::NSynchronization::CCriticalSection *Cs; + NWindows::NSynchronization::CManualResetEvent *CanReadEvent; + + HRESULT ExitResult; + + CStreamInfo(): Cs(0), CanReadEvent(0), StreamWasFinished(false) { } + ~CStreamInfo() + { + delete Cs; + delete CanReadEvent; + // Free(); + } + void Create() + { + Cs = new NWindows::NSynchronization::CCriticalSection; + CanReadEvent = new NWindows::NSynchronization::CManualResetEvent; + } + + void Free(IInMemStreamMtCallback *callback); + void Init() + { + LastBlockIndex = CurBlockIndex = 0; + CurBlockPos = LastBlockPos = 0; + StreamWasFinished = false; + ExitResult = S_OK; + } + + // res must be != S_OK + void Exit(HRESULT res) + { + ExitResult = res; + CanReadEvent->Set(); + } +}; + + +class CInMemStreamMt +{ + CMyComPtr _stream; + NWindows::NSynchronization::CCriticalSection CS; + CObjectVector _streams; + int _nextFreeStreamIndex; + int _currentStreamIndex; + UInt64 _subStreamSize; + + CResourceListMt _streamIndexAllocator; + + // bool _stopReading; + +public: + HRESULT Read(); + HRESULT ReadResult; + IInMemStreamMtCallback *Callback; + void FreeSubStream(int subStreamIndex); + HRESULT ReadSubStream(int subStreamIndex, void *data, UInt32 size, UInt32 *processedSize, bool keepData); + + // numSubStreams: min = 1, good min = numThreads + bool Create(int numSubStreams, UInt64 subStreamSize); + ~CInMemStreamMt() { Free(); } + void SetStream(ISequentialInStream *stream) { _stream = stream; } + + // to stop reading you must implement + // returning Error in IInMemStreamMtCallback::AllocateBlock + // and then you must free at least one substream + bool StartReadThread(); + + void Free(); + + // you must free at least one substream after that function to unlock waiting. + // void StopReading() { _stopReading = true; } +}; + +class CInMemStream: + public ISequentialInStream, + public CMyUnknownImp +{ + UInt64 _size; + bool _keepData; +public: + int Index; + CInMemStreamMt *mtStream; + void Init(bool keepData = false) + { + _size = 0; _keepData = keepData ; + } + MY_UNKNOWN_IMP + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + UInt64 GetSize() const { return _size; } +}; + +#endif diff --git a/CPP/7zip/Common/InOutTempBuffer.cpp b/CPP/7zip/Common/InOutTempBuffer.cpp new file mode 100755 index 00000000..ffaed32c --- /dev/null +++ b/CPP/7zip/Common/InOutTempBuffer.cpp @@ -0,0 +1,122 @@ +// InOutTempBuffer.cpp + +#include "StdAfx.h" + +#include "InOutTempBuffer.h" +#include "../../Common/Defs.h" +// #include "Windows/Defs.h" + +#include "StreamUtils.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDirectory; + +static UInt32 kTmpBufferMemorySize = (1 << 20); + +static LPCTSTR kTempFilePrefixString = TEXT("iot"); + +CInOutTempBuffer::CInOutTempBuffer(): + _buffer(NULL) +{ +} + +void CInOutTempBuffer::Create() +{ + _buffer = new Byte[kTmpBufferMemorySize]; +} + +CInOutTempBuffer::~CInOutTempBuffer() +{ + delete []_buffer; +} +void CInOutTempBuffer::InitWriting() +{ + _bufferPosition = 0; + _tmpFileCreated = false; + _fileSize = 0; +} + +bool CInOutTempBuffer::WriteToFile(const void *data, UInt32 size) +{ + if (size == 0) + return true; + if(!_tmpFileCreated) + { + CSysString tempDirPath; + if(!MyGetTempPath(tempDirPath)) + return false; + if (_tempFile.Create(tempDirPath, kTempFilePrefixString, _tmpFileName) == 0) + return false; + // _outFile.SetOpenCreationDispositionCreateAlways(); + if(!_outFile.Create(_tmpFileName, true)) + return false; + _tmpFileCreated = true; + } + UInt32 processedSize; + if(!_outFile.Write(data, size, processedSize)) + return false; + _fileSize += processedSize; + return (processedSize == size); +} + +bool CInOutTempBuffer::FlushWrite() +{ + return _outFile.Close(); +} + +bool CInOutTempBuffer::Write(const void *data, UInt32 size) +{ + if(_bufferPosition < kTmpBufferMemorySize) + { + UInt32 curSize = MyMin(kTmpBufferMemorySize - _bufferPosition, size); + memmove(_buffer + _bufferPosition, (const Byte *)data, curSize); + _bufferPosition += curSize; + size -= curSize; + data = ((const Byte *)data) + curSize; + _fileSize += curSize; + } + return WriteToFile(data, size); +} + +bool CInOutTempBuffer::InitReading() +{ + _currentPositionInBuffer = 0; + if(_tmpFileCreated) + return _inFile.Open(_tmpFileName); + return true; +} + +HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream) +{ + if (_currentPositionInBuffer < _bufferPosition) + { + UInt32 sizeToWrite = _bufferPosition - _currentPositionInBuffer; + RINOK(WriteStream(stream, _buffer + _currentPositionInBuffer, sizeToWrite, NULL)); + _currentPositionInBuffer += sizeToWrite; + } + if (!_tmpFileCreated) + return true; + for (;;) + { + UInt32 localProcessedSize; + if (!_inFile.ReadPart(_buffer, kTmpBufferMemorySize, localProcessedSize)) + return E_FAIL; + if (localProcessedSize == 0) + return S_OK; + RINOK(WriteStream(stream, _buffer, localProcessedSize, NULL)); + } +} + +STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if (!_buffer->Write(data, size)) + { + if (processedSize != NULL) + *processedSize = 0; + return E_FAIL; + } + if (processedSize != NULL) + *processedSize = size; + return S_OK; +} diff --git a/CPP/7zip/Common/InOutTempBuffer.h b/CPP/7zip/Common/InOutTempBuffer.h new file mode 100755 index 00000000..3abe76ec --- /dev/null +++ b/CPP/7zip/Common/InOutTempBuffer.h @@ -0,0 +1,55 @@ +// Util/InOutTempBuffer.h + +#ifndef __IN_OUT_TEMP_BUFFER_H +#define __IN_OUT_TEMP_BUFFER_H + +#include "../../Windows/FileIO.h" +#include "../../Windows/FileDir.h" +#include "../../Common/MyCom.h" + +#include "../IStream.h" + +class CInOutTempBuffer +{ + NWindows::NFile::NDirectory::CTempFile _tempFile; + NWindows::NFile::NIO::COutFile _outFile; + NWindows::NFile::NIO::CInFile _inFile; + Byte *_buffer; + UInt32 _bufferPosition; + UInt32 _currentPositionInBuffer; + CSysString _tmpFileName; + bool _tmpFileCreated; + + UInt64 _fileSize; + + bool WriteToFile(const void *data, UInt32 size); +public: + CInOutTempBuffer(); + ~CInOutTempBuffer(); + void Create(); + + void InitWriting(); + bool Write(const void *data, UInt32 size); + UInt64 GetDataSize() const { return _fileSize; } + bool FlushWrite(); + bool InitReading(); + HRESULT WriteToStream(ISequentialOutStream *stream); +}; + +class CSequentialOutTempBufferImp: + public ISequentialOutStream, + public CMyUnknownImp +{ + CInOutTempBuffer *_buffer; +public: + // CSequentialOutStreamImp(): _size(0) {} + // UInt32 _size; + void Init(CInOutTempBuffer *buffer) { _buffer = buffer; } + // UInt32 GetSize() const { return _size; } + + MY_UNKNOWN_IMP + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +#endif diff --git a/CPP/7zip/Common/LSBFDecoder.cpp b/CPP/7zip/Common/LSBFDecoder.cpp new file mode 100755 index 00000000..76dd090f --- /dev/null +++ b/CPP/7zip/Common/LSBFDecoder.cpp @@ -0,0 +1,27 @@ +// Stream/LSBFDecoder.cpp + +#include "StdAfx.h" + +#include "LSBFDecoder.h" + +namespace NStream { +namespace NLSBF { + +Byte kInvertTable[256]; + +class CInverterTableInitializer +{ +public: + CInverterTableInitializer() + { + for (int i = 0; i < 256; i++) + { + int x = ((i & 0x55) << 1) | ((i & 0xAA) >> 1); + x = ((x & 0x33) << 2) | ((x & 0xCC) >> 2); + kInvertTable[i] = (Byte)(((x & 0x0F) << 4) | ((x & 0xF0) >> 4)); + } + } +} g_InverterTableInitializer; + + +}} diff --git a/CPP/7zip/Common/LSBFDecoder.h b/CPP/7zip/Common/LSBFDecoder.h new file mode 100755 index 00000000..75458452 --- /dev/null +++ b/CPP/7zip/Common/LSBFDecoder.h @@ -0,0 +1,127 @@ +// LSBFDecoder.h + +#ifndef __STREAM_LSBFDECODER_H +#define __STREAM_LSBFDECODER_H + +#include "../IStream.h" + +namespace NStream { +namespace NLSBF { + +const int kNumBigValueBits = 8 * 4; + +const int kNumValueBytes = 3; +const int kNumValueBits = 8 * kNumValueBytes; + +const UInt32 kMask = (1 << kNumValueBits) - 1; + +extern Byte kInvertTable[256]; +// the Least Significant Bit of byte is First + +template +class CBaseDecoder +{ +protected: + int m_BitPos; + UInt32 m_Value; + TInByte m_Stream; +public: + UInt32 NumExtraBytes; + bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } + void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream); } + void ReleaseStream() { m_Stream.ReleaseStream(); } + void Init() + { + m_Stream.Init(); + m_BitPos = kNumBigValueBits; + m_Value = 0; + NumExtraBytes = 0; + } + UInt64 GetProcessedSize() const + { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; } + UInt64 GetProcessedBitsSize() const + { return (m_Stream.GetProcessedSize() << 3) - (kNumBigValueBits - m_BitPos); } + int GetBitPosition() const { return (m_BitPos & 7); } + + void Normalize() + { + for (;m_BitPos >= 8; m_BitPos -= 8) + { + Byte b = 0; + if (!m_Stream.ReadByte(b)) + { + b = 0xFF; // check it + NumExtraBytes++; + } + m_Value = (b << (kNumBigValueBits - m_BitPos)) | m_Value; + } + } + + UInt32 ReadBits(int numBits) + { + Normalize(); + UInt32 res = m_Value & ((1 << numBits) - 1); + m_BitPos += numBits; + m_Value >>= numBits; + return res; + } + + bool ExtraBitsWereRead() const + { + if (NumExtraBytes == 0) + return false; + return ((UInt32)(kNumBigValueBits - m_BitPos) < (NumExtraBytes << 3)); + } +}; + +template +class CDecoder: public CBaseDecoder +{ + UInt32 m_NormalValue; + +public: + void Init() + { + CBaseDecoder::Init(); + m_NormalValue = 0; + } + + void Normalize() + { + for (; this->m_BitPos >= 8; this->m_BitPos -= 8) + { + Byte b = 0; + if (!this->m_Stream.ReadByte(b)) + { + b = 0xFF; // check it + this->NumExtraBytes++; + } + m_NormalValue = (b << (kNumBigValueBits - this->m_BitPos)) | m_NormalValue; + this->m_Value = (this->m_Value << 8) | kInvertTable[b]; + } + } + + UInt32 GetValue(int numBits) + { + Normalize(); + return ((this->m_Value >> (8 - this->m_BitPos)) & kMask) >> (kNumValueBits - numBits); + } + + void MovePos(int numBits) + { + this->m_BitPos += numBits; + m_NormalValue >>= numBits; + } + + UInt32 ReadBits(int numBits) + { + Normalize(); + UInt32 res = m_NormalValue & ( (1 << numBits) - 1); + MovePos(numBits); + return res; + } +}; + +}} + +#endif diff --git a/CPP/7zip/Common/LSBFEncoder.cpp b/CPP/7zip/Common/LSBFEncoder.cpp new file mode 100755 index 00000000..6322cae3 --- /dev/null +++ b/CPP/7zip/Common/LSBFEncoder.cpp @@ -0,0 +1,29 @@ +// LSBFEncoder.cpp + +#include "StdAfx.h" + +#include "LSBFEncoder.h" +#include "Common/Defs.h" + +namespace NStream { +namespace NLSBF { + +void CEncoder::WriteBits(UInt32 value, int numBits) +{ + while(numBits > 0) + { + if (numBits < m_BitPos) + { + m_CurByte |= (value & ((1 << numBits) - 1)) << (8 - m_BitPos); + m_BitPos -= numBits; + return; + } + numBits -= m_BitPos; + m_Stream.WriteByte((Byte)(m_CurByte | (value << (8 - m_BitPos)))); + value >>= m_BitPos; + m_BitPos = 8; + m_CurByte = 0; + } +} + +}} diff --git a/CPP/7zip/Common/LSBFEncoder.h b/CPP/7zip/Common/LSBFEncoder.h new file mode 100755 index 00000000..72c84d9f --- /dev/null +++ b/CPP/7zip/Common/LSBFEncoder.h @@ -0,0 +1,51 @@ +// Stream/LSBFEncoder.h + +#ifndef __STREAM_LSBFENCODER_H +#define __STREAM_LSBFENCODER_H + +#include "../IStream.h" +#include "OutBuffer.h" + +namespace NStream { +namespace NLSBF { + +class CEncoder +{ + COutBuffer m_Stream; + int m_BitPos; + Byte m_CurByte; +public: + bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } + void SetStream(ISequentialOutStream *outStream) { m_Stream.SetStream(outStream); } + void ReleaseStream() { m_Stream.ReleaseStream(); } + void Init() + { + m_Stream.Init(); + m_BitPos = 8; + m_CurByte = 0; + } + HRESULT Flush() + { + FlushByte(); + return m_Stream.Flush(); + } + + void FlushByte() + { + if(m_BitPos < 8) + m_Stream.WriteByte(m_CurByte); + m_BitPos = 8; + m_CurByte = 0; + } + + void WriteBits(UInt32 value, int numBits); + UInt32 GetBitPosition() const { return (8 - m_BitPos); } + UInt64 GetProcessedSize() const { + return m_Stream.GetProcessedSize() + (8 - m_BitPos + 7) /8; } + void WriteByte(Byte b) { m_Stream.WriteByte(b);} +}; + + +}} + +#endif diff --git a/CPP/7zip/Common/LimitedStreams.cpp b/CPP/7zip/Common/LimitedStreams.cpp new file mode 100755 index 00000000..af721146 --- /dev/null +++ b/CPP/7zip/Common/LimitedStreams.cpp @@ -0,0 +1,24 @@ +// LimitedStreams.cpp + +#include "StdAfx.h" + +#include "LimitedStreams.h" +#include "../../Common/Defs.h" + +STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize = 0; + UInt32 sizeToRead = (UInt32)MyMin((_size - _pos), (UInt64)size); + HRESULT result = S_OK; + if (sizeToRead > 0) + { + result = _stream->Read(data, sizeToRead, &realProcessedSize); + _pos += realProcessedSize; + if (realProcessedSize == 0) + _wasFinished = true; + } + if(processedSize != NULL) + *processedSize = realProcessedSize; + return result; +} + diff --git a/CPP/7zip/Common/LimitedStreams.h b/CPP/7zip/Common/LimitedStreams.h new file mode 100755 index 00000000..ec4a3a70 --- /dev/null +++ b/CPP/7zip/Common/LimitedStreams.h @@ -0,0 +1,33 @@ +// LimitedStreams.h + +#ifndef __LIMITEDSTREAMS_H +#define __LIMITEDSTREAMS_H + +#include "../../Common/MyCom.h" +#include "../IStream.h" + +class CLimitedSequentialInStream: + public ISequentialInStream, + public CMyUnknownImp +{ + CMyComPtr _stream; + UInt64 _size; + UInt64 _pos; + bool _wasFinished; +public: + void SetStream(ISequentialInStream *stream) { _stream = stream; } + void Init(UInt64 streamSize) + { + _size = streamSize; + _pos = 0; + _wasFinished = false; + } + + MY_UNKNOWN_IMP + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + UInt64 GetSize() const { return _pos; } + bool WasFinished() const { return _wasFinished; } +}; + +#endif diff --git a/CPP/7zip/Common/LockedStream.cpp b/CPP/7zip/Common/LockedStream.cpp new file mode 100755 index 00000000..36be1ceb --- /dev/null +++ b/CPP/7zip/Common/LockedStream.cpp @@ -0,0 +1,23 @@ +// LockedStream.cpp + +#include "StdAfx.h" + +#include "LockedStream.h" + +HRESULT CLockedInStream::Read(UInt64 startPos, void *data, UInt32 size, + UInt32 *processedSize) +{ + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + RINOK(_stream->Seek(startPos, STREAM_SEEK_SET, NULL)); + return _stream->Read(data, size, processedSize); +} + +STDMETHODIMP CLockedSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize = 0; + HRESULT result = _lockedInStream->Read(_pos, data, size, &realProcessedSize); + _pos += realProcessedSize; + if (processedSize != NULL) + *processedSize = realProcessedSize; + return result; +} diff --git a/CPP/7zip/Common/LockedStream.h b/CPP/7zip/Common/LockedStream.h new file mode 100755 index 00000000..1c1e1793 --- /dev/null +++ b/CPP/7zip/Common/LockedStream.h @@ -0,0 +1,38 @@ +// LockedStream.h + +#ifndef __LOCKEDSTREAM_H +#define __LOCKEDSTREAM_H + +#include "../../Windows/Synchronization.h" +#include "../../Common/MyCom.h" +#include "../IStream.h" + +class CLockedInStream +{ + CMyComPtr _stream; + NWindows::NSynchronization::CCriticalSection _criticalSection; +public: + void Init(IInStream *stream) + { _stream = stream; } + HRESULT Read(UInt64 startPos, void *data, UInt32 size, UInt32 *processedSize); +}; + +class CLockedSequentialInStreamImp: + public ISequentialInStream, + public CMyUnknownImp +{ + CLockedInStream *_lockedInStream; + UInt64 _pos; +public: + void Init(CLockedInStream *lockedInStream, UInt64 startPos) + { + _lockedInStream = lockedInStream; + _pos = startPos; + } + + MY_UNKNOWN_IMP + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); +}; + +#endif diff --git a/CPP/7zip/Common/MSBFDecoder.h b/CPP/7zip/Common/MSBFDecoder.h new file mode 100755 index 00000000..dc80c0f7 --- /dev/null +++ b/CPP/7zip/Common/MSBFDecoder.h @@ -0,0 +1,69 @@ +// MSBFDecoder.h +// the Most Significant Bit of byte is First + +#ifndef __STREAM_MSBFDECODER_H +#define __STREAM_MSBFDECODER_H + +#include "../../Common/Types.h" +#include "../IStream.h" + +namespace NStream { +namespace NMSBF { + +const int kNumBigValueBits = 8 * 4; +const int kNumValueBytes = 3; +const int kNumValueBits = 8 * kNumValueBytes; + +const UInt32 kMask = (1 << kNumValueBits) - 1; + +template +class CDecoder +{ + UInt32 m_BitPos; + UInt32 m_Value; +public: + TInByte m_Stream; + bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } + void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream);} + void ReleaseStream() { m_Stream.ReleaseStream();} + + void Init() + { + m_Stream.Init(); + m_BitPos = kNumBigValueBits; + Normalize(); + } + + UInt64 GetProcessedSize() const + { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; } + UInt32 GetBitPosition() const { return (m_BitPos & 7); } + + void Normalize() + { + for (;m_BitPos >= 8; m_BitPos -= 8) + m_Value = (m_Value << 8) | m_Stream.ReadByte(); + } + + UInt32 GetValue(UInt32 numBits) const + { + // return (m_Value << m_BitPos) >> (kNumBigValueBits - numBits); + return ((m_Value >> (8 - m_BitPos)) & kMask) >> (kNumValueBits - numBits); + } + + void MovePos(UInt32 numBits) + { + m_BitPos += numBits; + Normalize(); + } + + UInt32 ReadBits(UInt32 numBits) + { + UInt32 res = GetValue(numBits); + MovePos(numBits); + return res; + } +}; + +}} + +#endif diff --git a/CPP/7zip/Common/MSBFEncoder.h b/CPP/7zip/Common/MSBFEncoder.h new file mode 100755 index 00000000..767a0e57 --- /dev/null +++ b/CPP/7zip/Common/MSBFEncoder.h @@ -0,0 +1,59 @@ +// Stream/MSBFEncoder.h + +#ifndef __STREAM_MSBFENCODER_H +#define __STREAM_MSBFENCODER_H + +#include "Common/Defs.h" +#include "../IStream.h" +#include "OutBuffer.h" + +namespace NStream { +namespace NMSBF { + +template +class CEncoder +{ + TOutByte m_Stream; + int m_BitPos; + Byte m_CurByte; +public: + bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } + void SetStream(ISequentialOutStream *outStream) { m_Stream.SetStream(outStream);} + void ReleaseStream() { m_Stream.ReleaseStream(); } + void Init() + { + m_Stream.Init(); + m_BitPos = 8; + m_CurByte = 0; + } + HRESULT Flush() + { + if(m_BitPos < 8) + WriteBits(0, m_BitPos); + return m_Stream.Flush(); + } + + void WriteBits(UInt32 value, int numBits) + { + while(numBits > 0) + { + if (numBits < m_BitPos) + { + m_CurByte |= ((Byte)value << (m_BitPos -= numBits)); + return; + } + numBits -= m_BitPos; + UInt32 newBits = (value >> numBits); + value -= (newBits << numBits); + m_Stream.WriteByte((Byte)(m_CurByte | newBits)); + m_BitPos = 8; + m_CurByte = 0; + } + } + UInt64 GetProcessedSize() const { + return m_Stream.GetProcessedSize() + (8 - m_BitPos + 7) / 8; } +}; + +}} + +#endif diff --git a/CPP/7zip/Common/MemBlocks.cpp b/CPP/7zip/Common/MemBlocks.cpp new file mode 100755 index 00000000..d2b79a70 --- /dev/null +++ b/CPP/7zip/Common/MemBlocks.cpp @@ -0,0 +1,184 @@ +// MemBlocks.cpp + +#include "StdAfx.h" + +#include "Common/MyCom.h" + +#include "StreamUtils.h" +#include "MemBlocks.h" + +bool CMemBlockManager::AllocateSpace(size_t numBlocks) +{ + FreeSpace(); + if (_blockSize < sizeof(void *) || numBlocks < 1) + return false; + size_t totalSize = numBlocks * _blockSize; + if (totalSize / _blockSize != numBlocks) + return false; + _data = ::MidAlloc(totalSize); + if (_data == 0) + return false; + Byte *p = (Byte *)_data; + for (size_t i = 0; i + 1 < numBlocks; i++, p += _blockSize) + *(Byte **)p = (p + _blockSize); + *(Byte **)p = 0; + _headFree = _data; + return true; +} + +void CMemBlockManager::FreeSpace() +{ + ::MidFree(_data); + _data = 0; + _headFree= 0; +} + +void *CMemBlockManager::AllocateBlock() +{ + if (_headFree == 0) + return 0; + void *p = _headFree; + _headFree = *(void **)_headFree; + return p; +} + +void CMemBlockManager::FreeBlock(void *p) +{ + if (p == 0) + return; + *(void **)p = _headFree; + _headFree = p; +} + + +bool CMemBlockManagerMt::AllocateSpace(size_t numBlocks, size_t numNoLockBlocks) +{ + if (numNoLockBlocks > numBlocks) + return false; + if (!CMemBlockManager::AllocateSpace(numBlocks)) + return false; + size_t numLockBlocks = numBlocks - numNoLockBlocks; + return Semaphore.Create((LONG)numLockBlocks, (LONG)numLockBlocks); +} + +bool CMemBlockManagerMt::AllocateSpaceAlways(size_t desiredNumberOfBlocks, size_t numNoLockBlocks) +{ + if (numNoLockBlocks > desiredNumberOfBlocks) + return false; + for (;;) + { + if (AllocateSpace(desiredNumberOfBlocks, numNoLockBlocks)) + return true; + if (desiredNumberOfBlocks == numNoLockBlocks) + return false; + desiredNumberOfBlocks = numNoLockBlocks + ((desiredNumberOfBlocks - numNoLockBlocks) >> 1); + } +} + +void CMemBlockManagerMt::FreeSpace() +{ + Semaphore.Close(); + CMemBlockManager::FreeSpace(); +} + +void *CMemBlockManagerMt::AllocateBlock() +{ + // Semaphore.Lock(); + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + return CMemBlockManager::AllocateBlock(); +} + +void CMemBlockManagerMt::FreeBlock(void *p, bool lockMode) +{ + if (p == 0) + return; + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + CMemBlockManager::FreeBlock(p); + } + if (lockMode) + Semaphore.Release(); +} + +void CMemBlocks::Free(CMemBlockManagerMt *manager) +{ + while(Blocks.Size() > 0) + { + manager->FreeBlock(Blocks.Back()); + Blocks.DeleteBack(); + } + TotalSize = 0; +} + +void CMemBlocks::FreeOpt(CMemBlockManagerMt *manager) +{ + Free(manager); + Blocks.Free(); // to reduce memory usage +} + +HRESULT CMemBlocks::WriteToStream(size_t blockSize, ISequentialOutStream *outStream) const +{ + UInt64 totalSize = TotalSize; + for (int blockIndex = 0; totalSize > 0; blockIndex++) + { + UInt32 curSize = (UInt32)blockSize; + if (totalSize < curSize) + curSize = (UInt32)totalSize; + UInt32 processedSize; + if (blockIndex >= Blocks.Size()) + return E_FAIL; + RINOK(WriteStream(outStream, Blocks[blockIndex], curSize, &processedSize)); + if (processedSize != curSize) + return E_FAIL; + totalSize -= processedSize; + } + return S_OK; +} + + +void CMemLockBlocks::FreeBlock(int index, CMemBlockManagerMt *memManager) +{ + memManager->FreeBlock(Blocks[index], LockMode); + Blocks[index] = 0; +} + +void CMemLockBlocks::Free(CMemBlockManagerMt *memManager) +{ + while (Blocks.Size() > 0) + { + FreeBlock(Blocks.Size() - 1, memManager); + Blocks.DeleteBack(); + } + TotalSize = 0; +} + +bool CMemLockBlocks::SwitchToNoLockMode(CMemBlockManagerMt *memManager) +{ + if (LockMode) + { + if (Blocks.Size() > 0) + if (!memManager->ReleaseLockedBlocks(Blocks.Size())) + return false; + LockMode = false; + } + return true; +} + +void CMemLockBlocks::Detach(CMemLockBlocks &blocks, CMemBlockManagerMt *memManager) +{ + blocks.Free(memManager); + blocks.LockMode = LockMode; + UInt64 totalSize = 0; + size_t blockSize = memManager->GetBlockSize(); + for (int i = 0; i < Blocks.Size(); i++) + { + if (totalSize < TotalSize) + blocks.Blocks.Add(Blocks[i]); + else + FreeBlock(i, memManager); + Blocks[i] = 0; + totalSize += blockSize; + } + blocks.TotalSize = TotalSize; + Free(memManager); +} diff --git a/CPP/7zip/Common/MemBlocks.h b/CPP/7zip/Common/MemBlocks.h new file mode 100755 index 00000000..31cd3546 --- /dev/null +++ b/CPP/7zip/Common/MemBlocks.h @@ -0,0 +1,73 @@ +// MemBlocks.h + +#ifndef __MEMBLOCKS_H +#define __MEMBLOCKS_H + +#include "Common/Alloc.h" +#include "Common/Types.h" +#include "Common/Vector.h" + +#include "Windows/Synchronization.h" + +#include "../IStream.h" + +class CMemBlockManager +{ + void *_data; + size_t _blockSize; + void *_headFree; +public: + CMemBlockManager(size_t blockSize = (1 << 20)): _data(0), _blockSize(blockSize), _headFree(0) {} + ~CMemBlockManager() { FreeSpace(); } + + bool AllocateSpace(size_t numBlocks); + void FreeSpace(); + size_t GetBlockSize() const { return _blockSize; } + void *AllocateBlock(); + void FreeBlock(void *p); +}; + + +class CMemBlockManagerMt: public CMemBlockManager +{ + NWindows::NSynchronization::CCriticalSection _criticalSection; +public: + NWindows::NSynchronization::CSemaphore Semaphore; + + CMemBlockManagerMt(size_t blockSize = (1 << 20)): CMemBlockManager(blockSize) {} + ~CMemBlockManagerMt() { FreeSpace(); } + + bool AllocateSpace(size_t numBlocks, size_t numNoLockBlocks = 0); + bool AllocateSpaceAlways(size_t desiredNumberOfBlocks, size_t numNoLockBlocks = 0); + void FreeSpace(); + void *AllocateBlock(); + void FreeBlock(void *p, bool lockMode = true); + bool ReleaseLockedBlocks(int number) { return Semaphore.Release(number); } +}; + + +class CMemBlocks +{ + void Free(CMemBlockManagerMt *manager); +public: + CRecordVector Blocks; + UInt64 TotalSize; + + CMemBlocks(): TotalSize(0) {} + + void FreeOpt(CMemBlockManagerMt *manager); + HRESULT WriteToStream(size_t blockSize, ISequentialOutStream *outStream) const; +}; + +struct CMemLockBlocks: public CMemBlocks +{ + bool LockMode; + + CMemLockBlocks(): LockMode(true) {}; + void Free(CMemBlockManagerMt *memManager); + void FreeBlock(int index, CMemBlockManagerMt *memManager); + bool SwitchToNoLockMode(CMemBlockManagerMt *memManager); + void Detach(CMemLockBlocks &blocks, CMemBlockManagerMt *memManager); +}; + +#endif diff --git a/CPP/7zip/Common/OffsetStream.cpp b/CPP/7zip/Common/OffsetStream.cpp new file mode 100755 index 00000000..997ccae2 --- /dev/null +++ b/CPP/7zip/Common/OffsetStream.cpp @@ -0,0 +1,35 @@ +// OffsetStream.cpp + +#include "StdAfx.h" + +#include "Common/Defs.h" +#include "OffsetStream.h" + +HRESULT COffsetOutStream::Init(IOutStream *stream, UInt64 offset) +{ + _offset = offset; + _stream = stream; + return _stream->Seek(offset, STREAM_SEEK_SET, NULL); +} + +STDMETHODIMP COffsetOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + return _stream->Write(data, size, processedSize); +} + +STDMETHODIMP COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin, + UInt64 *newPosition) +{ + UInt64 absoluteNewPosition; + if (seekOrigin == STREAM_SEEK_SET) + offset += _offset; + HRESULT result = _stream->Seek(offset, seekOrigin, &absoluteNewPosition); + if (newPosition != NULL) + *newPosition = absoluteNewPosition - _offset; + return result; +} + +STDMETHODIMP COffsetOutStream::SetSize(Int64 newSize) +{ + return _stream->SetSize(_offset + newSize); +} diff --git a/CPP/7zip/Common/OffsetStream.h b/CPP/7zip/Common/OffsetStream.h new file mode 100755 index 00000000..57a055cc --- /dev/null +++ b/CPP/7zip/Common/OffsetStream.h @@ -0,0 +1,25 @@ +// OffsetStream.h + +#ifndef __OFFSETSTREAM_H +#define __OFFSETSTREAM_H + +#include "Common/MyCom.h" +#include "../IStream.h" + +class COffsetOutStream: + public IOutStream, + public CMyUnknownImp +{ + UInt64 _offset; + CMyComPtr _stream; +public: + HRESULT Init(IOutStream *stream, UInt64 offset); + + MY_UNKNOWN_IMP + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); + STDMETHOD(SetSize)(Int64 newSize); +}; + +#endif diff --git a/CPP/7zip/Common/OutBuffer.cpp b/CPP/7zip/Common/OutBuffer.cpp new file mode 100755 index 00000000..a73fa7c5 --- /dev/null +++ b/CPP/7zip/Common/OutBuffer.cpp @@ -0,0 +1,116 @@ +// OutByte.cpp + +#include "StdAfx.h" + +#include "OutBuffer.h" + +#include "../../Common/Alloc.h" + +bool COutBuffer::Create(UInt32 bufferSize) +{ + const UInt32 kMinBlockSize = 1; + if (bufferSize < kMinBlockSize) + bufferSize = kMinBlockSize; + if (_buffer != 0 && _bufferSize == bufferSize) + return true; + Free(); + _bufferSize = bufferSize; + _buffer = (Byte *)::MidAlloc(bufferSize); + return (_buffer != 0); +} + +void COutBuffer::Free() +{ + ::MidFree(_buffer); + _buffer = 0; +} + +void COutBuffer::SetStream(ISequentialOutStream *stream) +{ + _stream = stream; +} + +void COutBuffer::Init() +{ + _streamPos = 0; + _limitPos = _bufferSize; + _pos = 0; + _processedSize = 0; + _overDict = false; + #ifdef _NO_EXCEPTIONS + ErrorCode = S_OK; + #endif +} + +UInt64 COutBuffer::GetProcessedSize() const +{ + UInt64 res = _processedSize + _pos - _streamPos; + if (_streamPos > _pos) + res += _bufferSize; + return res; +} + + +HRESULT COutBuffer::FlushPart() +{ + // _streamPos < _bufferSize + UInt32 size = (_streamPos >= _pos) ? (_bufferSize - _streamPos) : (_pos - _streamPos); + HRESULT result = S_OK; + #ifdef _NO_EXCEPTIONS + result = ErrorCode; + #endif + if (_buffer2 != 0) + { + memmove(_buffer2, _buffer + _streamPos, size); + _buffer2 += size; + } + + if (_stream != 0 + #ifdef _NO_EXCEPTIONS + && (ErrorCode == S_OK) + #endif + ) + { + UInt32 processedSize = 0; + result = _stream->Write(_buffer + _streamPos, size, &processedSize); + size = processedSize; + } + _streamPos += size; + if (_streamPos == _bufferSize) + _streamPos = 0; + if (_pos == _bufferSize) + { + _overDict = true; + _pos = 0; + } + _limitPos = (_streamPos > _pos) ? _streamPos : _bufferSize; + _processedSize += size; + return result; +} + +HRESULT COutBuffer::Flush() +{ + #ifdef _NO_EXCEPTIONS + if (ErrorCode != S_OK) + return ErrorCode; + #endif + + while(_streamPos != _pos) + { + HRESULT result = FlushPart(); + if (result != S_OK) + return result; + } + return S_OK; +} + +void COutBuffer::FlushWithCheck() +{ + HRESULT result = FlushPart(); + #ifdef _NO_EXCEPTIONS + ErrorCode = result; + #else + if (result != S_OK) + throw COutBufferException(result); + #endif +} diff --git a/CPP/7zip/Common/OutBuffer.h b/CPP/7zip/Common/OutBuffer.h new file mode 100755 index 00000000..0ce54e21 --- /dev/null +++ b/CPP/7zip/Common/OutBuffer.h @@ -0,0 +1,64 @@ +// OutBuffer.h + +#ifndef __OUTBUFFER_H +#define __OUTBUFFER_H + +#include "../IStream.h" +#include "../../Common/MyCom.h" + +#ifndef _NO_EXCEPTIONS +struct COutBufferException +{ + HRESULT ErrorCode; + COutBufferException(HRESULT errorCode): ErrorCode(errorCode) {} +}; +#endif + +class COutBuffer +{ +protected: + Byte *_buffer; + UInt32 _pos; + UInt32 _limitPos; + UInt32 _streamPos; + UInt32 _bufferSize; + CMyComPtr _stream; + UInt64 _processedSize; + Byte *_buffer2; + bool _overDict; + + HRESULT FlushPart(); + void FlushWithCheck(); +public: + #ifdef _NO_EXCEPTIONS + HRESULT ErrorCode; + #endif + + COutBuffer(): _buffer(0), _pos(0), _stream(0), _buffer2(0) {} + ~COutBuffer() { Free(); } + + bool Create(UInt32 bufferSize); + void Free(); + + void SetMemStream(Byte *buffer) { _buffer2 = buffer; } + void SetStream(ISequentialOutStream *stream); + void Init(); + HRESULT Flush(); + void ReleaseStream() { _stream.Release(); } + + void WriteByte(Byte b) + { + _buffer[_pos++] = b; + if(_pos == _limitPos) + FlushWithCheck(); + } + void WriteBytes(const void *data, size_t size) + { + for (size_t i = 0; i < size; i++) + WriteByte(((const Byte *)data)[i]); + } + + UInt64 GetProcessedSize() const; +}; + +#endif diff --git a/CPP/7zip/Common/OutMemStream.cpp b/CPP/7zip/Common/OutMemStream.cpp new file mode 100755 index 00000000..2953afd8 --- /dev/null +++ b/CPP/7zip/Common/OutMemStream.cpp @@ -0,0 +1,137 @@ +// OutMemStream.cpp + +#include "StdAfx.h" + +#include "OutMemStream.h" + +void COutMemStream::Free() +{ + Blocks.Free(_memManager); + Blocks.LockMode = true; +} + +void COutMemStream::Init() +{ + WriteToRealStreamEvent.Reset(); + _unlockEventWasSent = false; + _realStreamMode = false; + Free(); + _curBlockPos = 0; + _curBlockIndex = 0; +} + +void COutMemStream::DetachData(CMemLockBlocks &blocks) +{ + Blocks.Detach(blocks, _memManager); + Free(); +} + + +HRESULT COutMemStream::WriteToRealStream() +{ + RINOK(Blocks.WriteToStream(_memManager->GetBlockSize(), OutSeqStream)); + Blocks.Free(_memManager); + return S_OK; +} + +STDMETHODIMP COutMemStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if (_realStreamMode) + return OutSeqStream->Write(data, size, processedSize); + if (processedSize != 0) + *processedSize = 0; + while(size != 0) + { + if ((int)_curBlockIndex < Blocks.Blocks.Size()) + { + Byte *p = (Byte *)Blocks.Blocks[(int)_curBlockIndex] + _curBlockPos; + size_t curSize = _memManager->GetBlockSize() - _curBlockPos; + if (size < curSize) + curSize = size; + memmove(p, data, curSize); + if (processedSize != 0) + *processedSize += (UInt32)curSize; + data = (const void *)((const Byte *)data + curSize); + size -= (UInt32)curSize; + _curBlockPos += curSize; + + UInt64 pos64 = GetPos(); + if (pos64 > Blocks.TotalSize) + Blocks.TotalSize = pos64; + if (_curBlockPos == _memManager->GetBlockSize()) + { + _curBlockIndex++; + _curBlockPos = 0; + } + continue; + } + HANDLE events[4] = { StopWritingEvent, WriteToRealStreamEvent, NoLockEvent, _memManager->Semaphore }; + DWORD waitResult = ::WaitForMultipleObjects((Blocks.LockMode ? 4 : 2), events, FALSE, INFINITE); + switch (waitResult) + { + case (WAIT_OBJECT_0 + 0): + return StopWriteResult; + case (WAIT_OBJECT_0 + 1): + { + _realStreamMode = true; + RINOK(WriteToRealStream()); + UInt32 processedSize2; + HRESULT res = OutSeqStream->Write(data, size, &processedSize2); + if (processedSize != 0) + *processedSize += processedSize2; + return res; + } + case (WAIT_OBJECT_0 + 2): + { + if (!Blocks.SwitchToNoLockMode(_memManager)) + return E_FAIL; + break; + } + case (WAIT_OBJECT_0 + 3): + break; + default: + return E_FAIL; + } + Blocks.Blocks.Add(_memManager->AllocateBlock()); + } + return S_OK; +} + +STDMETHODIMP COutMemStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +{ + if (_realStreamMode) + { + if (!OutStream) + return E_FAIL; + return OutStream->Seek(offset, seekOrigin, newPosition); + } + if (seekOrigin == STREAM_SEEK_CUR) + { + if (offset != 0) + return E_NOTIMPL; + } + else if (seekOrigin == STREAM_SEEK_SET) + { + if (offset != 0) + return E_NOTIMPL; + _curBlockIndex = 0; + _curBlockPos = 0; + } + else + return E_NOTIMPL; + if (newPosition != 0) + *newPosition = GetPos(); + return S_OK; +} + +STDMETHODIMP COutMemStream::SetSize(Int64 newSize) +{ + if (_realStreamMode) + { + if (!OutStream) + return E_FAIL; + return OutStream->SetSize(newSize); + } + Blocks.TotalSize = newSize; + return S_OK; +} diff --git a/CPP/7zip/Common/OutMemStream.h b/CPP/7zip/Common/OutMemStream.h new file mode 100755 index 00000000..ea98de17 --- /dev/null +++ b/CPP/7zip/Common/OutMemStream.h @@ -0,0 +1,88 @@ +// OutMemStream.h + +#ifndef __OUTMEMSTREAM_H +#define __OUTMEMSTREAM_H + +#include "Common/MyCom.h" +#include "MemBlocks.h" + +class COutMemStream: + public IOutStream, + public CMyUnknownImp +{ + CMemBlockManagerMt *_memManager; + size_t _curBlockIndex; + size_t _curBlockPos; + bool _realStreamMode; + + bool _unlockEventWasSent; + NWindows::NSynchronization::CAutoResetEvent StopWritingEvent; + NWindows::NSynchronization::CAutoResetEvent WriteToRealStreamEvent; + NWindows::NSynchronization::CAutoResetEvent NoLockEvent; + + HRESULT StopWriteResult; + CMemLockBlocks Blocks; + + UInt64 GetPos() const { return (UInt64)_curBlockIndex * _memManager->GetBlockSize() + _curBlockPos; } + + CMyComPtr OutSeqStream; + CMyComPtr OutStream; + +public: + + void SetOutStream(IOutStream *outStream) + { + OutStream = outStream; + OutSeqStream = outStream; + } + + void SetSeqOutStream(ISequentialOutStream *outStream) + { + OutStream = NULL; + OutSeqStream = outStream; + } + + void ReleaseOutStream() + { + OutStream.Release(); + OutSeqStream.Release(); + } + + COutMemStream(CMemBlockManagerMt *memManager): _memManager(memManager) { } + + ~COutMemStream() { Free(); } + void Free(); + + void Init(); + HRESULT WriteToRealStream(); + + void DetachData(CMemLockBlocks &blocks); + + bool WasUnlockEventSent() const { return _unlockEventWasSent; } + + void SetRealStreamMode() + { + _unlockEventWasSent = true; + WriteToRealStreamEvent.Set(); + } + + void SetNoLockMode() + { + _unlockEventWasSent = true; + NoLockEvent.Set(); + } + + void StopWriting(HRESULT res) + { + StopWriteResult = res; + StopWritingEvent.Set(); + } + + MY_UNKNOWN_IMP + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); + STDMETHOD(SetSize)(Int64 newSize); +}; + +#endif diff --git a/CPP/7zip/Common/ProgressMt.cpp b/CPP/7zip/Common/ProgressMt.cpp new file mode 100755 index 00000000..319bd241 --- /dev/null +++ b/CPP/7zip/Common/ProgressMt.cpp @@ -0,0 +1,53 @@ +// ProgressMt.h + +#include "StdAfx.h" + +#include "ProgressMt.h" + +void CMtCompressProgressMixer::Init(int numItems, ICompressProgressInfo *progress) +{ + NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); + InSizes.Clear(); + OutSizes.Clear(); + for (int i = 0; i < numItems; i++) + { + InSizes.Add(0); + OutSizes.Add(0); + } + TotalInSize = 0; + TotalOutSize = 0; + _progress = progress; +} + +void CMtCompressProgressMixer::Reinit(int index) +{ + NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); + InSizes[index] = 0; + OutSizes[index] = 0; +} + +HRESULT CMtCompressProgressMixer::SetRatioInfo(int index, const UInt64 *inSize, const UInt64 *outSize) +{ + NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); + if (inSize != 0) + { + UInt64 diff = *inSize - InSizes[index]; + InSizes[index] = *inSize; + TotalInSize += diff; + } + if (outSize != 0) + { + UInt64 diff = *outSize - OutSizes[index]; + OutSizes[index] = *outSize; + TotalOutSize += diff; + } + if (_progress) + return _progress->SetRatioInfo(&TotalInSize, &TotalOutSize); + return S_OK; +} + + +STDMETHODIMP CMtCompressProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +{ + return _progress->SetRatioInfo(_index, inSize, outSize); +} diff --git a/CPP/7zip/Common/ProgressMt.h b/CPP/7zip/Common/ProgressMt.h new file mode 100755 index 00000000..c0776944 --- /dev/null +++ b/CPP/7zip/Common/ProgressMt.h @@ -0,0 +1,47 @@ +// ProgressMt.h + +#ifndef __PROGRESSMT_H +#define __PROGRESSMT_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" +#include "../IProgress.h" + +#include "Windows/Synchronization.h" +#include "../../Common/Vector.h" + +class CMtCompressProgressMixer +{ + CMyComPtr _progress; + CRecordVector InSizes; + CRecordVector OutSizes; + UInt64 TotalInSize; + UInt64 TotalOutSize; +public: + NWindows::NSynchronization::CCriticalSection CriticalSection; + void Init(int numItems, ICompressProgressInfo *progress); + void Reinit(int index); + HRESULT SetRatioInfo(int index, const UInt64 *inSize, const UInt64 *outSize); +}; + +class CMtCompressProgress: + public ICompressProgressInfo, + public CMyUnknownImp +{ + CMtCompressProgressMixer *_progress; + int _index; +public: + void Init(CMtCompressProgressMixer *progress, int index) + { + _progress = progress; + _index = index; + } + void Reinit() { _progress->Reinit(_index); } + + MY_UNKNOWN_IMP + + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); +}; + +#endif diff --git a/CPP/7zip/Common/ProgressUtils.cpp b/CPP/7zip/Common/ProgressUtils.cpp new file mode 100755 index 00000000..40e13877 --- /dev/null +++ b/CPP/7zip/Common/ProgressUtils.cpp @@ -0,0 +1,55 @@ +// ProgressUtils.h + +#include "StdAfx.h" + +#include "ProgressUtils.h" + +void CLocalCompressProgressInfo::Init(ICompressProgressInfo *progress, + const UInt64 *inStartValue, const UInt64 *outStartValue) +{ + _progress = progress; + _inStartValueIsAssigned = (inStartValue != NULL); + if (_inStartValueIsAssigned) + _inStartValue = *inStartValue; + _outStartValueIsAssigned = (outStartValue != NULL); + if (_outStartValueIsAssigned) + _outStartValue = *outStartValue; +} + +STDMETHODIMP CLocalCompressProgressInfo::SetRatioInfo( + const UInt64 *inSize, const UInt64 *outSize) +{ + UInt64 inSizeNew, outSizeNew; + const UInt64 *inSizeNewPointer; + const UInt64 *outSizeNewPointer; + if (_inStartValueIsAssigned && inSize != NULL) + { + inSizeNew = _inStartValue + (*inSize); + inSizeNewPointer = &inSizeNew; + } + else + inSizeNewPointer = NULL; + + if (_outStartValueIsAssigned && outSize != NULL) + { + outSizeNew = _outStartValue + (*outSize); + outSizeNewPointer = &outSizeNew; + } + else + outSizeNewPointer = NULL; + return _progress->SetRatioInfo(inSizeNewPointer, outSizeNewPointer); +} + +/////////////////////////////////// + +void CLocalProgress::Init(IProgress *progress, bool inSizeIsMain) +{ + _progress = progress; + _inSizeIsMain = inSizeIsMain; +} + +STDMETHODIMP CLocalProgress::SetRatioInfo( + const UInt64 *inSize, const UInt64 *outSize) +{ + return _progress->SetCompleted(_inSizeIsMain ? inSize : outSize); +} diff --git a/CPP/7zip/Common/ProgressUtils.h b/CPP/7zip/Common/ProgressUtils.h new file mode 100755 index 00000000..f89839fa --- /dev/null +++ b/CPP/7zip/Common/ProgressUtils.h @@ -0,0 +1,43 @@ +// ProgressUtils.h + +#ifndef __PROGRESSUTILS_H +#define __PROGRESSUTILS_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" +#include "../IProgress.h" + +class CLocalCompressProgressInfo: + public ICompressProgressInfo, + public CMyUnknownImp +{ + CMyComPtr _progress; + bool _inStartValueIsAssigned; + bool _outStartValueIsAssigned; + UInt64 _inStartValue; + UInt64 _outStartValue; +public: + void Init(ICompressProgressInfo *progress, + const UInt64 *inStartValue, const UInt64 *outStartValue); + + MY_UNKNOWN_IMP + + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); +}; + +class CLocalProgress: + public ICompressProgressInfo, + public CMyUnknownImp +{ + CMyComPtr _progress; + bool _inSizeIsMain; +public: + void Init(IProgress *progress, bool inSizeIsMain); + + MY_UNKNOWN_IMP + + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); +}; + +#endif diff --git a/CPP/7zip/Common/StdAfx.h b/CPP/7zip/Common/StdAfx.h new file mode 100755 index 00000000..27a77b10 --- /dev/null +++ b/CPP/7zip/Common/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../Common/MyWindows.h" +#include "../../Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/Common/StreamBinder.cpp b/CPP/7zip/Common/StreamBinder.cpp new file mode 100755 index 00000000..2984c2d9 --- /dev/null +++ b/CPP/7zip/Common/StreamBinder.cpp @@ -0,0 +1,162 @@ +// StreamBinder.cpp + +#include "StdAfx.h" + +#include "StreamBinder.h" +#include "../../Common/Defs.h" +#include "../../Common/MyCom.h" + +using namespace NWindows; +using namespace NSynchronization; + +class CSequentialInStreamForBinder: + public ISequentialInStream, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); +private: + CStreamBinder *m_StreamBinder; +public: + ~CSequentialInStreamForBinder() { m_StreamBinder->CloseRead(); } + void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; } +}; + +STDMETHODIMP CSequentialInStreamForBinder::Read(void *data, UInt32 size, UInt32 *processedSize) + { return m_StreamBinder->Read(data, size, processedSize); } + +class CSequentialOutStreamForBinder: + public ISequentialOutStream, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + +private: + CStreamBinder *m_StreamBinder; +public: + ~CSequentialOutStreamForBinder() { m_StreamBinder->CloseWrite(); } + void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; } +}; + +STDMETHODIMP CSequentialOutStreamForBinder::Write(const void *data, UInt32 size, UInt32 *processedSize) + { return m_StreamBinder->Write(data, size, processedSize); } + + +////////////////////////// +// CStreamBinder +// (_thereAreBytesToReadEvent && _bufferSize == 0) means that stream is finished. + +void CStreamBinder::CreateEvents() +{ + _allBytesAreWritenEvent = new CManualResetEvent(true); + _thereAreBytesToReadEvent = new CManualResetEvent(false); + _readStreamIsClosedEvent = new CManualResetEvent(false); +} + +void CStreamBinder::ReInit() +{ + _thereAreBytesToReadEvent->Reset(); + _readStreamIsClosedEvent->Reset(); + ProcessedSize = 0; +} + +CStreamBinder::~CStreamBinder() +{ + if (_allBytesAreWritenEvent != NULL) + delete _allBytesAreWritenEvent; + if (_thereAreBytesToReadEvent != NULL) + delete _thereAreBytesToReadEvent; + if (_readStreamIsClosedEvent != NULL) + delete _readStreamIsClosedEvent; +} + + + + +void CStreamBinder::CreateStreams(ISequentialInStream **inStream, + ISequentialOutStream **outStream) +{ + CSequentialInStreamForBinder *inStreamSpec = new + CSequentialInStreamForBinder; + CMyComPtr inStreamLoc(inStreamSpec); + inStreamSpec->SetBinder(this); + *inStream = inStreamLoc.Detach(); + + CSequentialOutStreamForBinder *outStreamSpec = new + CSequentialOutStreamForBinder; + CMyComPtr outStreamLoc(outStreamSpec); + outStreamSpec->SetBinder(this); + *outStream = outStreamLoc.Detach(); + + _buffer = NULL; + _bufferSize= 0; + ProcessedSize = 0; +} + +HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 sizeToRead = size; + if (size > 0) + { + if(!_thereAreBytesToReadEvent->Lock()) + return E_FAIL; + sizeToRead = MyMin(_bufferSize, size); + if (_bufferSize > 0) + { + MoveMemory(data, _buffer, sizeToRead); + _buffer = ((const Byte *)_buffer) + sizeToRead; + _bufferSize -= sizeToRead; + if (_bufferSize == 0) + { + _thereAreBytesToReadEvent->Reset(); + _allBytesAreWritenEvent->Set(); + } + } + } + if (processedSize != NULL) + *processedSize = sizeToRead; + ProcessedSize += sizeToRead; + return S_OK; +} + +void CStreamBinder::CloseRead() +{ + _readStreamIsClosedEvent->Set(); +} + +HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if (size > 0) + { + _buffer = data; + _bufferSize = size; + _allBytesAreWritenEvent->Reset(); + _thereAreBytesToReadEvent->Set(); + + HANDLE events[2]; + events[0] = *_allBytesAreWritenEvent; + events[1] = *_readStreamIsClosedEvent; + DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); + if (waitResult != WAIT_OBJECT_0 + 0) + { + // ReadingWasClosed = true; + return E_FAIL; + } + // if(!_allBytesAreWritenEvent.Lock()) + // return E_FAIL; + } + if (processedSize != NULL) + *processedSize = size; + return S_OK; +} + +void CStreamBinder::CloseWrite() +{ + // _bufferSize must be = 0 + _thereAreBytesToReadEvent->Set(); +} diff --git a/CPP/7zip/Common/StreamBinder.h b/CPP/7zip/Common/StreamBinder.h new file mode 100755 index 00000000..a66c3acb --- /dev/null +++ b/CPP/7zip/Common/StreamBinder.h @@ -0,0 +1,37 @@ +// StreamBinder.h + +#ifndef __STREAMBINDER_H +#define __STREAMBINDER_H + +#include "../IStream.h" +#include "../../Windows/Synchronization.h" + +class CStreamBinder +{ + NWindows::NSynchronization::CManualResetEvent *_allBytesAreWritenEvent; + NWindows::NSynchronization::CManualResetEvent *_thereAreBytesToReadEvent; + NWindows::NSynchronization::CManualResetEvent *_readStreamIsClosedEvent; + UInt32 _bufferSize; + const void *_buffer; +public: + // bool ReadingWasClosed; + UInt64 ProcessedSize; + CStreamBinder(): + _allBytesAreWritenEvent(NULL), + _thereAreBytesToReadEvent(NULL), + _readStreamIsClosedEvent(NULL) + {} + ~CStreamBinder(); + void CreateEvents(); + + void CreateStreams(ISequentialInStream **inStream, + ISequentialOutStream **outStream); + HRESULT Read(void *data, UInt32 size, UInt32 *processedSize); + void CloseRead(); + + HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize); + void CloseWrite(); + void ReInit(); +}; + +#endif diff --git a/CPP/7zip/Common/StreamObjects.cpp b/CPP/7zip/Common/StreamObjects.cpp new file mode 100755 index 00000000..32f8f306 --- /dev/null +++ b/CPP/7zip/Common/StreamObjects.cpp @@ -0,0 +1,68 @@ +// StreamObjects.cpp + +#include "StdAfx.h" + +#include "StreamObjects.h" +#include "../../Common/Defs.h" + + +STDMETHODIMP CSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 numBytesToRead = (UInt32)(MyMin(_pos + size, _size) - _pos); + memmove(data, _dataPointer + _pos, numBytesToRead); + _pos += numBytesToRead; + if(processedSize != NULL) + *processedSize = numBytesToRead; + return S_OK; +} + + +void CWriteBuffer::Write(const void *data, size_t size) +{ + size_t newCapacity = _size + size; + _buffer.EnsureCapacity(newCapacity); + memmove(_buffer + _size, data, size); + _size += size; +} + +STDMETHODIMP CSequentialOutStreamImp::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + _writeBuffer.Write(data, size); + if(processedSize != NULL) + *processedSize = size; + return S_OK; +} + +STDMETHODIMP CSequentialOutStreamImp2::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 newSize = size; + if (_pos + size > _size) + newSize = (UInt32)(_size - _pos); + memmove(_buffer + _pos, data, newSize); + if(processedSize != NULL) + *processedSize = newSize; + _pos += newSize; + if (newSize != size) + return E_FAIL; + return S_OK; +} + +STDMETHODIMP CSequentialInStreamSizeCount::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize; + HRESULT result = _stream->Read(data, size, &realProcessedSize); + _size += realProcessedSize; + if (processedSize != 0) + *processedSize = realProcessedSize; + return result; +} + +STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 realProcessedSize; + HRESULT result = _stream->Write(data, size, &realProcessedSize); + _size += realProcessedSize; + if (processedSize != 0) + *processedSize = realProcessedSize; + return result; +} diff --git a/CPP/7zip/Common/StreamObjects.h b/CPP/7zip/Common/StreamObjects.h new file mode 100755 index 00000000..6f670f59 --- /dev/null +++ b/CPP/7zip/Common/StreamObjects.h @@ -0,0 +1,117 @@ +// StreamObjects.h + +#ifndef __STREAMOBJECTS_H +#define __STREAMOBJECTS_H + +#include "../../Common/DynamicBuffer.h" +#include "../../Common/MyCom.h" +#include "../IStream.h" + +class CSequentialInStreamImp: + public ISequentialInStream, + public CMyUnknownImp +{ + const Byte *_dataPointer; + size_t _size; + size_t _pos; + +public: + void Init(const Byte *dataPointer, size_t size) + { + _dataPointer = dataPointer; + _size = size; + _pos = 0; + } + + MY_UNKNOWN_IMP + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); +}; + + +class CWriteBuffer +{ + CByteDynamicBuffer _buffer; + size_t _size; +public: + CWriteBuffer(): _size(0) {} + void Init() { _size = 0; } + void Write(const void *data, size_t size); + size_t GetSize() const { return _size; } + const CByteDynamicBuffer& GetBuffer() const { return _buffer; } +}; + +class CSequentialOutStreamImp: + public ISequentialOutStream, + public CMyUnknownImp +{ + CWriteBuffer _writeBuffer; +public: + void Init() { _writeBuffer.Init(); } + size_t GetSize() const { return _writeBuffer.GetSize(); } + const CByteDynamicBuffer& GetBuffer() const { return _writeBuffer.GetBuffer(); } + + MY_UNKNOWN_IMP + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +class CSequentialOutStreamImp2: + public ISequentialOutStream, + public CMyUnknownImp +{ + Byte *_buffer; + size_t _size; + size_t _pos; +public: + + void Init(Byte *buffer, size_t size) + { + _buffer = buffer; + _pos = 0; + _size = size; + } + + size_t GetPos() const { return _pos; } + + MY_UNKNOWN_IMP + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +class CSequentialInStreamSizeCount: + public ISequentialInStream, + public CMyUnknownImp +{ + CMyComPtr _stream; + UInt64 _size; +public: + void Init(ISequentialInStream *stream) + { + _stream = stream; + _size = 0; + } + UInt64 GetSize() const { return _size; } + + MY_UNKNOWN_IMP + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); +}; + +class CSequentialOutStreamSizeCount: + public ISequentialOutStream, + public CMyUnknownImp +{ + CMyComPtr _stream; + UInt64 _size; +public: + void SetStream(ISequentialOutStream *stream) { _stream = stream; } + void Init() { _size = 0; } + UInt64 GetSize() const { return _size; } + + MY_UNKNOWN_IMP + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +#endif diff --git a/CPP/7zip/Common/StreamUtils.cpp b/CPP/7zip/Common/StreamUtils.cpp new file mode 100755 index 00000000..a5d9ac0e --- /dev/null +++ b/CPP/7zip/Common/StreamUtils.cpp @@ -0,0 +1,44 @@ +// StreamUtils.cpp + +#include "StdAfx.h" + +#include "../../Common/MyCom.h" +#include "StreamUtils.h" + +HRESULT ReadStream(ISequentialInStream *stream, void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize != 0) + *processedSize = 0; + while(size != 0) + { + UInt32 processedSizeLoc; + HRESULT res = stream->Read(data, size, &processedSizeLoc); + if (processedSize != 0) + *processedSize += processedSizeLoc; + data = (Byte *)((Byte *)data + processedSizeLoc); + size -= processedSizeLoc; + RINOK(res); + if (processedSizeLoc == 0) + return S_OK; + } + return S_OK; +} + +HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize != 0) + *processedSize = 0; + while(size != 0) + { + UInt32 processedSizeLoc; + HRESULT res = stream->Write(data, size, &processedSizeLoc); + if (processedSize != 0) + *processedSize += processedSizeLoc; + data = (const void *)((const Byte *)data + processedSizeLoc); + size -= processedSizeLoc; + RINOK(res); + if (processedSizeLoc == 0) + break; + } + return S_OK; +} diff --git a/CPP/7zip/Common/StreamUtils.h b/CPP/7zip/Common/StreamUtils.h new file mode 100755 index 00000000..59f88733 --- /dev/null +++ b/CPP/7zip/Common/StreamUtils.h @@ -0,0 +1,11 @@ +// StreamUtils.h + +#ifndef __STREAMUTILS_H +#define __STREAMUTILS_H + +#include "../IStream.h" + +HRESULT ReadStream(ISequentialInStream *stream, void *data, UInt32 size, UInt32 *processedSize); +HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size, UInt32 *processedSize); + +#endif diff --git a/CPP/7zip/Compress/Arj/ArjDecoder1.cpp b/CPP/7zip/Compress/Arj/ArjDecoder1.cpp new file mode 100755 index 00000000..7f720807 --- /dev/null +++ b/CPP/7zip/Compress/Arj/ArjDecoder1.cpp @@ -0,0 +1,319 @@ +// Arj/Decoder.cpp + +#include "StdAfx.h" + +#include "ArjDecoder1.h" + +#include "Windows/Defs.h" + +namespace NCompress{ +namespace NArj { +namespace NDecoder1 { + +static const UInt32 kHistorySize = 26624; +static const UInt32 kMatchMaxLen = 256; +static const UInt32 kMatchMinLen = 3; + +static const UInt32 kNC = 255 + kMatchMaxLen + 2 - kMatchMinLen; + +void CCoder::MakeTable(int nchar, Byte *bitlen, int tablebits, + UInt32 *table, int tablesize) +{ + UInt32 count[17], weight[17], start[18], *p; + UInt32 i, k, len, ch, jutbits, avail, nextcode, mask; + + for (i = 1; i <= 16; i++) + count[i] = 0; + for (i = 0; (int)i < nchar; i++) + count[bitlen[i]]++; + + start[1] = 0; + for (i = 1; i <= 16; i++) + start[i + 1] = start[i] + (count[i] << (16 - i)); + if (start[17] != (UInt32) (1 << 16)) + throw "Data error"; + + jutbits = 16 - tablebits; + for (i = 1; (int)i <= tablebits; i++) + { + start[i] >>= jutbits; + weight[i] = 1 << (tablebits - i); + } + while (i <= 16) + { + weight[i] = 1 << (16 - i); + i++; + } + + i = start[tablebits + 1] >> jutbits; + if (i != (UInt32) (1 << 16)) + { + k = 1 << tablebits; + while (i != k) + table[i++] = 0; + } + + avail = nchar; + mask = 1 << (15 - tablebits); + for (ch = 0; (int)ch < nchar; ch++) + { + if ((len = bitlen[ch]) == 0) + continue; + k = start[len]; + nextcode = k + weight[len]; + if ((int)len <= tablebits) + { + if (nextcode > (UInt32)tablesize) + throw "Data error"; + for (i = start[len]; i < nextcode; i++) + table[i] = ch; + } + else + { + p = &table[k >> jutbits]; + i = len - tablebits; + while (i != 0) + { + if (*p == 0) + { + right[avail] = left[avail] = 0; + *p = avail++; + } + if (k & mask) + p = &right[*p]; + else + p = &left[*p]; + k <<= 1; + i--; + } + *p = ch; + } + start[len] = nextcode; + } +} + +void CCoder::read_pt_len(int nn, int nbit, int i_special) +{ + UInt32 n = m_InBitStream.ReadBits(nbit); + if (n == 0) + { + UInt32 c = m_InBitStream.ReadBits(nbit); + int i; + for (i = 0; i < nn; i++) + pt_len[i] = 0; + for (i = 0; i < 256; i++) + pt_table[i] = c; + } + else + { + UInt32 i = 0; + while (i < n) + { + UInt32 bitBuf = m_InBitStream.GetValue(16); + int c = bitBuf >> 13; + if (c == 7) + { + UInt32 mask = 1 << (12); + while (mask & bitBuf) + { + mask >>= 1; + c++; + } + } + m_InBitStream.MovePos((c < 7) ? 3 : (int)(c - 3)); + pt_len[i++] = (Byte)c; + if (i == (UInt32)i_special) + { + c = m_InBitStream.ReadBits(2); + while (--c >= 0) + pt_len[i++] = 0; + } + } + while (i < (UInt32)nn) + pt_len[i++] = 0; + MakeTable(nn, pt_len, 8, pt_table, PTABLESIZE); + } +} + +void CCoder::read_c_len() +{ + int i, c, n; + UInt32 mask; + + n = m_InBitStream.ReadBits(CBIT); + if (n == 0) + { + c = m_InBitStream.ReadBits(CBIT); + for (i = 0; i < NC; i++) + c_len[i] = 0; + for (i = 0; i < CTABLESIZE; i++) + c_table[i] = c; + } + else + { + i = 0; + while (i < n) + { + UInt32 bitBuf = m_InBitStream.GetValue(16); + c = pt_table[bitBuf >> (8)]; + if (c >= NT) + { + mask = 1 << (7); + do + { + if (bitBuf & mask) + c = right[c]; + else + c = left[c]; + mask >>= 1; + } while (c >= NT); + } + m_InBitStream.MovePos((int)(pt_len[c])); + if (c <= 2) + { + if (c == 0) + c = 1; + else if (c == 1) + c = m_InBitStream.ReadBits(4) + 3; + else + c = m_InBitStream.ReadBits(CBIT) + 20; + while (--c >= 0) + c_len[i++] = 0; + } + else + c_len[i++] = (Byte)(c - 2); + } + while (i < NC) + c_len[i++] = 0; + MakeTable(NC, c_len, 12, c_table, CTABLESIZE); + } +} + +UInt32 CCoder::decode_c() +{ + UInt32 j, mask; + UInt32 bitbuf = m_InBitStream.GetValue(16); + j = c_table[bitbuf >> 4]; + if (j >= NC) + { + mask = 1 << (3); + do + { + if (bitbuf & mask) + j = right[j]; + else + j = left[j]; + mask >>= 1; + } while (j >= NC); + } + m_InBitStream.MovePos((int)(c_len[j])); + return j; +} + +UInt32 CCoder::decode_p() +{ + UInt32 j, mask; + UInt32 bitbuf = m_InBitStream.GetValue(16); + j = pt_table[bitbuf >> (8)]; + if (j >= NP) + { + mask = 1 << (7); + do + { + if (bitbuf & mask) + j = right[j]; + else + j = left[j]; + mask >>= 1; + } while (j >= NP); + } + m_InBitStream.MovePos((int)(pt_len[j])); + if (j != 0) + { + j--; + j = (1 << j) + m_InBitStream.ReadBits((int)j); + } + return j; +} + + +STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + if (outSize == NULL) + return E_INVALIDARG; + + if (!m_OutWindowStream.Create(kHistorySize)) + return E_OUTOFMEMORY; + if (!m_InBitStream.Create(1 << 20)) + return E_OUTOFMEMORY; + + int size1 = sizeof(c_table) / sizeof(c_table[0]); + for (int i = 0; i < size1; i++) + { + if (i % 100 == 0) + c_table[i] = 0; + + c_table[i] = 0; + } + + + UInt64 pos = 0; + m_OutWindowStream.SetStream(outStream); + m_OutWindowStream.Init(false); + m_InBitStream.SetStream(inStream); + m_InBitStream.Init(); + + CCoderReleaser coderReleaser(this); + + UInt32 blockSize = 0; + + while(pos < *outSize) + { + if (blockSize == 0) + { + if (progress != NULL) + { + UInt64 packSize = m_InBitStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &pos)); + } + blockSize = m_InBitStream.ReadBits(16); + read_pt_len(NT, TBIT, 3); + read_c_len(); + read_pt_len(NP, PBIT, -1); + } + blockSize--; + + UInt32 number = decode_c(); + if (number < 256) + { + m_OutWindowStream.PutByte((Byte)number); + pos++; + continue; + } + else + { + UInt32 len = number - 256 + kMatchMinLen; + UInt32 distance = decode_p(); + if (distance >= pos) + throw "data error"; + m_OutWindowStream.CopyBlock(distance, len); + pos += len; + } + } + coderReleaser.NeedFlush = false; + return m_OutWindowStream.Flush(); +} + +STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress);} + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const CLZOutWindowException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +}}} diff --git a/CPP/7zip/Compress/Arj/ArjDecoder1.h b/CPP/7zip/Compress/Arj/ArjDecoder1.h new file mode 100755 index 00000000..434a0a41 --- /dev/null +++ b/CPP/7zip/Compress/Arj/ArjDecoder1.h @@ -0,0 +1,105 @@ +// Arj/Decoder1.h + +#ifndef __COMPRESS_ARJ_DECODER1_H +#define __COMPRESS_ARJ_DECODER1_H + +#include "../../../Common/MyCom.h" +#include "../../ICoder.h" +#include "../../Common/MSBFDecoder.h" +#include "../../Common/InBuffer.h" +#include "../LZ/LZOutWindow.h" + +/* +// {23170F69-40C1-278B-0404-010000000000} +DEFINE_GUID(CLSID_CCompressArjDecoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00); +*/ + +namespace NCompress { +namespace NArj { +namespace NDecoder1 { + +#define CODE_BIT 16 + +#define THRESHOLD 3 +#define DDICSIZ 26624 +#define MAXDICBIT 16 +#define MATCHBIT 8 +#define MAXMATCH 256 +#define NC (0xFF + MAXMATCH + 2 - THRESHOLD) +#define NP (MAXDICBIT + 1) +#define CBIT 9 +#define NT (CODE_BIT + 3) +#define PBIT 5 +#define TBIT 5 + +#if NT > NP +#define NPT NT +#else +#define NPT NP +#endif + +#define CTABLESIZE 4096 +#define PTABLESIZE 256 + + +class CCoder : + public ICompressCoder, + public CMyUnknownImp +{ + CLZOutWindow m_OutWindowStream; + NStream::NMSBF::CDecoder m_InBitStream; + + UInt32 left[2 * NC - 1]; + UInt32 right[2 * NC - 1]; + Byte c_len[NC]; + Byte pt_len[NPT]; + + UInt32 c_table[CTABLESIZE]; + UInt32 pt_table[PTABLESIZE]; + + void ReleaseStreams() + { + m_OutWindowStream.ReleaseStream(); + m_InBitStream.ReleaseStream(); + } + + class CCoderReleaser + { + CCoder *m_Coder; + public: + bool NeedFlush; + CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {} + ~CCoderReleaser() + { + if (NeedFlush) + m_Coder->m_OutWindowStream.Flush(); + m_Coder->ReleaseStreams(); + } + }; + friend class CCoderReleaser; + + void MakeTable(int nchar, Byte *bitlen, int tablebits, UInt32 *table, int tablesize); + + void read_c_len(); + void read_pt_len(int nn, int nbit, int i_special); + UInt32 decode_c(); + UInt32 decode_p(); + +public: + + MY_UNKNOWN_IMP + + STDMETHOD(CodeReal)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + +}; + +}}} + +#endif diff --git a/CPP/7zip/Compress/Arj/ArjDecoder2.cpp b/CPP/7zip/Compress/Arj/ArjDecoder2.cpp new file mode 100755 index 00000000..a734d1b4 --- /dev/null +++ b/CPP/7zip/Compress/Arj/ArjDecoder2.cpp @@ -0,0 +1,93 @@ +// Arj/Decoder2.cpp + +#include "StdAfx.h" + +#include "ArjDecoder2.h" + +namespace NCompress{ +namespace NArj { +namespace NDecoder2 { + +static const UInt32 kHistorySize = 26624; +static const UInt32 kMatchMaxLen = 256; +static const UInt32 kMatchMinLen = 3; + +STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize, + ICompressProgressInfo * /* progress */) +{ + if (outSize == NULL) + return E_INVALIDARG; + + if (!m_OutWindowStream.Create(kHistorySize)) + return E_OUTOFMEMORY; + if (!m_InBitStream.Create(1 << 20)) + return E_OUTOFMEMORY; + + UInt64 pos = 0; + m_OutWindowStream.SetStream(outStream); + m_OutWindowStream.Init(false); + m_InBitStream.SetStream(inStream); + m_InBitStream.Init(); + CCoderReleaser coderReleaser(this); + + while(pos < *outSize) + { + const UInt32 kStartWidth = 0; + const UInt32 kStopWidth = 7; + UInt32 power = 1 << kStartWidth; + UInt32 width; + UInt32 len = 0; + for (width = kStartWidth; width < kStopWidth; width++) + { + if (m_InBitStream.ReadBits(1) == 0) + break; + len += power; + power <<= 1; + } + if (width != 0) + len += m_InBitStream.ReadBits(width); + if (len == 0) + { + m_OutWindowStream.PutByte((Byte)m_InBitStream.ReadBits(8)); + pos++; + continue; + } + else + { + len = len - 1 + kMatchMinLen; + const UInt32 kStartWidth = 9; + const UInt32 kStopWidth = 13; + UInt32 power = 1 << kStartWidth; + UInt32 width; + UInt32 distance = 0; + for (width = kStartWidth; width < kStopWidth; width++) + { + if (m_InBitStream.ReadBits(1) == 0) + break; + distance += power; + power <<= 1; + } + if (width != 0) + distance += m_InBitStream.ReadBits(width); + if (distance >= pos) + throw "data error"; + m_OutWindowStream.CopyBlock(distance, len); + pos += len; + } + } + coderReleaser.NeedFlush = false; + return m_OutWindowStream.Flush(); +} + +STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress);} + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const CLZOutWindowException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +}}} diff --git a/CPP/7zip/Compress/Arj/ArjDecoder2.h b/CPP/7zip/Compress/Arj/ArjDecoder2.h new file mode 100755 index 00000000..7a33f6bd --- /dev/null +++ b/CPP/7zip/Compress/Arj/ArjDecoder2.h @@ -0,0 +1,65 @@ +// Arj/Decoder2.h + +#ifndef __COMPRESS_ARJ_DECODER2_H +#define __COMPRESS_ARJ_DECODER2_H + +#include "../../../Common/MyCom.h" +#include "../../ICoder.h" +#include "../../Common/MSBFDecoder.h" +#include "../../Common/InBuffer.h" +#include "../LZ/LZOutWindow.h" + +/* +// {23170F69-40C1-278B-0404-020000000000} +DEFINE_GUID(CLSID_CCompressArj2Decoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00); +*/ + +namespace NCompress { +namespace NArj { +namespace NDecoder2 { + +class CCoder : + public ICompressCoder, + public CMyUnknownImp +{ + CLZOutWindow m_OutWindowStream; + NStream::NMSBF::CDecoder m_InBitStream; + + void ReleaseStreams() + { + m_OutWindowStream.ReleaseStream(); + m_InBitStream.ReleaseStream(); + } + + class CCoderReleaser + { + CCoder *m_Coder; + public: + bool NeedFlush; + CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {} + ~CCoderReleaser() + { + if (NeedFlush) + m_Coder->m_OutWindowStream.Flush(); + m_Coder->ReleaseStreams(); + } + }; + friend class CCoderReleaser; + +public: + MY_UNKNOWN_IMP + + STDMETHOD(CodeReal)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + +}; + +}}} + +#endif diff --git a/CPP/7zip/Compress/Arj/StdAfx.h b/CPP/7zip/Compress/Arj/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Compress/Arj/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Compress/BWT/BlockSort.cpp b/CPP/7zip/Compress/BWT/BlockSort.cpp new file mode 100755 index 00000000..9e28c85f --- /dev/null +++ b/CPP/7zip/Compress/BWT/BlockSort.cpp @@ -0,0 +1,487 @@ +// BlockSort.cpp + +#include "StdAfx.h" + +#include "BlockSort.h" + +extern "C" +{ + #include "../../../../C/Sort.h" +} + +// use BLOCK_SORT_EXTERNAL_FLAGS if blockSize > 1M +// #define BLOCK_SORT_USE_HEAP_SORT + +#if _MSC_VER >= 1300 + #define NO_INLINE __declspec(noinline) __fastcall +#else +#ifdef _MSC_VER + #define NO_INLINE __fastcall +#else + #define NO_INLINE +#endif +#endif + +// Don't change it !! +static const int kNumHashBytes = 2; +static const UInt32 kNumHashValues = 1 << (kNumHashBytes * 8); + +static const int kNumRefBitsMax = 12; // must be < (kNumHashBytes * 8) = 16 +static const UInt32 kNumRefsMax = (1 << kNumRefBitsMax); + +#define BS_TEMP_SIZE kNumHashValues + +#ifdef BLOCK_SORT_EXTERNAL_FLAGS + +static const int kNumFlagsBits = 5; // 32 Flags in UInt32 word +static const UInt32 kNumFlagsInWord = (1 << kNumFlagsBits); +static const UInt32 kFlagsMask = kNumFlagsInWord - 1; +static const UInt32 kAllFlags = 0xFFFFFFFF; + +#else + +const int kNumBitsMax = 20; +const UInt32 kIndexMask = (1 << kNumBitsMax) - 1; +const int kNumExtraBits = 32 - kNumBitsMax; +const int kNumExtra0Bits = kNumExtraBits - 2; +const UInt32 kNumExtra0Mask = (1 << kNumExtra0Bits) - 1; + +#define SetFinishedGroupSize(p, size) \ + { *(p) |= ((((size) - 1) & kNumExtra0Mask) << kNumBitsMax); \ + if ((size) > (1 << kNumExtra0Bits)) { \ + *(p) |= 0x40000000; *((p) + 1) |= ((((size) - 1)>> kNumExtra0Bits) << kNumBitsMax); } } \ + +inline void SetGroupSize(UInt32 *p, UInt32 size) +{ + if (--size == 0) + return; + *p |= 0x80000000 | ((size & kNumExtra0Mask) << kNumBitsMax); + if (size >= (1 << kNumExtra0Bits)) + { + *p |= 0x40000000; + p[1] |= ((size >> kNumExtra0Bits) << kNumBitsMax); + } +} + +#endif + +// SortGroup - is recursive Range-Sort function with HeapSort optimization for small blocks +// "range" is not real range. It's only for optimization. +// returns: 1 - if there are groups, 0 - no more groups + +UInt32 NO_INLINE SortGroup(UInt32 BlockSize, UInt32 NumSortedBytes, UInt32 groupOffset, UInt32 groupSize, int NumRefBits, UInt32 *Indices + #ifndef BLOCK_SORT_USE_HEAP_SORT + , UInt32 left, UInt32 range + #endif + ) +{ + UInt32 *ind2 = Indices + groupOffset; + if (groupSize <= 1) + { + /* + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + SetFinishedGroupSize(ind2, 1); + #endif + */ + return 0; + } + UInt32 *Groups = Indices + BlockSize + BS_TEMP_SIZE; + if (groupSize <= ((UInt32)1 << NumRefBits) + #ifndef BLOCK_SORT_USE_HEAP_SORT + && groupSize <= range + #endif + ) + { + UInt32 *temp = Indices + BlockSize; + UInt32 j; + { + UInt32 gPrev; + UInt32 gRes = 0; + { + UInt32 sp = ind2[0] + NumSortedBytes; + if (sp >= BlockSize) sp -= BlockSize; + gPrev = Groups[sp]; + temp[0] = (gPrev << NumRefBits); + } + + for (j = 1; j < groupSize; j++) + { + UInt32 sp = ind2[j] + NumSortedBytes; + if (sp >= BlockSize) sp -= BlockSize; + UInt32 g = Groups[sp]; + temp[j] = (g << NumRefBits) | j; + gRes |= (gPrev ^ g); + } + if (gRes == 0) + { + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + SetGroupSize(ind2, groupSize); + #endif + return 1; + } + } + + HeapSort(temp, groupSize); + const UInt32 mask = ((1 << NumRefBits) - 1); + UInt32 thereAreGroups = 0; + + UInt32 group = groupOffset; + UInt32 cg = (temp[0] >> NumRefBits); + temp[0] = ind2[temp[0] & mask]; + + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 *Flags = Groups + BlockSize; + #else + UInt32 prevGroupStart = 0; + #endif + + for (j = 1; j < groupSize; j++) + { + UInt32 val = temp[j]; + UInt32 cgCur = (val >> NumRefBits); + + if (cgCur != cg) + { + cg = cgCur; + group = groupOffset + j; + + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 t = group - 1; + Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); + #else + SetGroupSize(temp + prevGroupStart, j - prevGroupStart); + prevGroupStart = j; + #endif + } + else + thereAreGroups = 1; + UInt32 ind = ind2[val & mask]; + temp[j] = ind; + Groups[ind] = group; + } + + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + SetGroupSize(temp + prevGroupStart, j - prevGroupStart); + #endif + + for (j = 0; j < groupSize; j++) + ind2[j] = temp[j]; + return thereAreGroups; + } + + // Check that all strings are in one group (cannot sort) + { + UInt32 sp = ind2[0] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; + UInt32 group = Groups[sp]; + UInt32 j; + for (j = 1; j < groupSize; j++) + { + sp = ind2[j] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; + if (Groups[sp] != group) + break; + } + if (j == groupSize) + { + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + SetGroupSize(ind2, groupSize); + #endif + return 1; + } + } + + #ifndef BLOCK_SORT_USE_HEAP_SORT + //-------------------------------------- + // Range Sort + UInt32 i; + UInt32 mid; + for (;;) + { + if (range <= 1) + { + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + SetGroupSize(ind2, groupSize); + #endif + return 1; + } + mid = left + ((range + 1) >> 1); + UInt32 j = groupSize; + i = 0; + do + { + UInt32 sp = ind2[i] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; + if (Groups[sp] >= mid) + { + for (j--; j > i; j--) + { + sp = ind2[j] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; + if (Groups[sp] < mid) + { + UInt32 temp = ind2[i]; ind2[i] = ind2[j]; ind2[j] = temp; + break; + } + } + if (i >= j) + break; + } + } + while(++i < j); + if (i == 0) + { + range = range - (mid - left); + left = mid; + } + else if (i == groupSize) + range = (mid - left); + else + break; + } + + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + { + UInt32 t = (groupOffset + i - 1); + UInt32 *Flags = Groups + BlockSize; + Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); + } + #endif + + for (UInt32 j = i; j < groupSize; j++) + Groups[ind2[j]] = groupOffset + i; + + UInt32 res = SortGroup(BlockSize, NumSortedBytes, groupOffset, i, NumRefBits, Indices, left, mid - left); + return res | SortGroup(BlockSize, NumSortedBytes, groupOffset + i, groupSize - i, NumRefBits, Indices, mid, range - (mid - left)); + + #else + + //-------------------------------------- + // Heap Sort + + { + UInt32 j; + for (j = 0; j < groupSize; j++) + { + UInt32 sp = ind2[j] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; + ind2[j] = sp; + } + + HeapSortRef(ind2, Groups, groupSize); + + // Write Flags + UInt32 sp = ind2[0]; + UInt32 group = Groups[sp]; + + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 *Flags = Groups + BlockSize; + #else + UInt32 prevGroupStart = 0; + #endif + + for (j = 1; j < groupSize; j++) + { + sp = ind2[j]; + if (Groups[sp] != group) + { + group = Groups[sp]; + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 t = groupOffset + j - 1; + Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); + #else + SetGroupSize(ind2 + prevGroupStart, j - prevGroupStart); + prevGroupStart = j; + #endif + } + } + + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + SetGroupSize(ind2 + prevGroupStart, j - prevGroupStart); + #endif + + // Write new Groups values and Check that there are groups + UInt32 thereAreGroups = 0; + for (j = 0; j < groupSize; j++) + { + UInt32 group = groupOffset + j; + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 subGroupSize = ((ind2[j] & ~0xC0000000) >> kNumBitsMax); + if ((ind2[j] & 0x40000000) != 0) + subGroupSize += ((ind2[j + 1] >> kNumBitsMax) << kNumExtra0Bits); + subGroupSize++; + for (;;) + { + UInt32 original = ind2[j]; + UInt32 sp = original & kIndexMask; + if (sp < NumSortedBytes) sp += BlockSize; sp -= NumSortedBytes; + ind2[j] = sp | (original & ~kIndexMask); + Groups[sp] = group; + if (--subGroupSize == 0) + break; + j++; + thereAreGroups = 1; + } + #else + for (;;) + { + UInt32 sp = ind2[j]; if (sp < NumSortedBytes) sp += BlockSize; sp -= NumSortedBytes; + ind2[j] = sp; + Groups[sp] = group; + if ((Flags[(groupOffset + j) >> kNumFlagsBits] & (1 << ((groupOffset + j) & kFlagsMask))) == 0) + break; + j++; + thereAreGroups = 1; + } + #endif + } + return thereAreGroups; + } + #endif +} + +// conditions: blockSize > 0 +UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize) +{ + UInt32 *counters = Indices + blockSize; + UInt32 i; + + // Radix-Sort for 2 bytes + for (i = 0; i < kNumHashValues; i++) + counters[i] = 0; + for (i = 0; i < blockSize - 1; i++) + counters[((UInt32)data[i] << 8) | data[i + 1]]++; + counters[((UInt32)data[i] << 8) | data[0]]++; + + UInt32 *Groups = counters + BS_TEMP_SIZE; + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 *Flags = Groups + blockSize; + { + UInt32 numWords = (blockSize + kFlagsMask) >> kNumFlagsBits; + for (i = 0; i < numWords; i++) + Flags[i] = kAllFlags; + } + #endif + + { + UInt32 sum = 0; + for (i = 0; i < kNumHashValues; i++) + { + UInt32 groupSize = counters[i]; + if (groupSize > 0) + { + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 t = sum + groupSize - 1; + Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); + #endif + sum += groupSize; + } + counters[i] = sum - groupSize; + } + + for (i = 0; i < blockSize - 1; i++) + Groups[i] = counters[((UInt32)data[i] << 8) | data[i + 1]]; + Groups[i] = counters[((UInt32)data[i] << 8) | data[0]]; + + for (i = 0; i < blockSize - 1; i++) + Indices[counters[((UInt32)data[i] << 8) | data[i + 1]]++] = i; + Indices[counters[((UInt32)data[i] << 8) | data[0]]++] = i; + + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 prev = 0; + for (i = 0; i < kNumHashValues; i++) + { + UInt32 prevGroupSize = counters[i] - prev; + if (prevGroupSize == 0) + continue; + SetGroupSize(Indices + prev, prevGroupSize); + prev = counters[i]; + } + #endif + } + + int NumRefBits; + for (NumRefBits = 0; ((blockSize - 1) >> NumRefBits) != 0; NumRefBits++); + NumRefBits = 32 - NumRefBits; + if (NumRefBits > kNumRefBitsMax) + NumRefBits = kNumRefBitsMax; + + for (UInt32 NumSortedBytes = kNumHashBytes; ; NumSortedBytes <<= 1) + { + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 finishedGroupSize = 0; + #endif + UInt32 newLimit = 0; + for (i = 0; i < blockSize;) + { + #ifdef BLOCK_SORT_EXTERNAL_FLAGS + + if ((Flags[i >> kNumFlagsBits] & (1 << (i & kFlagsMask))) == 0) + { + i++; + continue; + } + UInt32 groupSize; + for(groupSize = 1; + (Flags[(i + groupSize) >> kNumFlagsBits] & (1 << ((i + groupSize) & kFlagsMask))) != 0; + groupSize++); + + groupSize++; + + #else + + UInt32 groupSize = ((Indices[i] & ~0xC0000000) >> kNumBitsMax); + bool finishedGroup = ((Indices[i] & 0x80000000) == 0); + if ((Indices[i] & 0x40000000) != 0) + { + groupSize += ((Indices[i + 1] >> kNumBitsMax) << kNumExtra0Bits); + Indices[i + 1] &= kIndexMask; + } + Indices[i] &= kIndexMask; + groupSize++; + if (finishedGroup || groupSize == 1) + { + Indices[i - finishedGroupSize] &= kIndexMask; + if (finishedGroupSize > 1) + Indices[i - finishedGroupSize + 1] &= kIndexMask; + UInt32 newGroupSize = groupSize + finishedGroupSize; + SetFinishedGroupSize(Indices + i - finishedGroupSize, newGroupSize); + finishedGroupSize = newGroupSize; + i += groupSize; + continue; + } + finishedGroupSize = 0; + + #endif + + if (NumSortedBytes >= blockSize) + for (UInt32 j = 0; j < groupSize; j++) + { + UInt32 t = (i + j); + // Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); + Groups[Indices[t]] = t; + } + else + if (SortGroup(blockSize, NumSortedBytes, i, groupSize, NumRefBits, Indices + #ifndef BLOCK_SORT_USE_HEAP_SORT + , 0, blockSize + #endif + ) != 0) + newLimit = i + groupSize; + i += groupSize; + } + if (newLimit == 0) + break; + } + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + for (i = 0; i < blockSize;) + { + UInt32 groupSize = ((Indices[i] & ~0xC0000000) >> kNumBitsMax); + if ((Indices[i] & 0x40000000) != 0) + { + groupSize += ((Indices[i + 1] >> kNumBitsMax) << kNumExtra0Bits); + Indices[i + 1] &= kIndexMask; + } + Indices[i] &= kIndexMask; + groupSize++; + i += groupSize; + } + #endif + return Groups[0]; +} + diff --git a/CPP/7zip/Compress/BWT/BlockSort.h b/CPP/7zip/Compress/BWT/BlockSort.h new file mode 100755 index 00000000..def48a96 --- /dev/null +++ b/CPP/7zip/Compress/BWT/BlockSort.h @@ -0,0 +1,21 @@ +// BlockSort.h + +#ifndef __BLOCKSORT_H +#define __BLOCKSORT_H + +#include "Common/Types.h" + +// use BLOCK_SORT_EXTERNAL_FLAGS if blockSize can be > 1M +// #define BLOCK_SORT_EXTERNAL_FLAGS + +#ifdef BLOCK_SORT_EXTERNAL_FLAGS +#define BLOCK_SORT_EXTERNAL_SIZE(blockSize) ((((blockSize) + 31) >> 5)) +#else +#define BLOCK_SORT_EXTERNAL_SIZE(blockSize) 0 +#endif + +#define BLOCK_SORT_BUF_SIZE(blockSize) ((blockSize) * 2 + BLOCK_SORT_EXTERNAL_SIZE(blockSize) + (1 << 16)) + +UInt32 BlockSort(UInt32 *indices, const Byte *data, UInt32 blockSize); + +#endif diff --git a/CPP/7zip/Compress/BWT/Mtf8.h b/CPP/7zip/Compress/BWT/Mtf8.h new file mode 100755 index 00000000..92e4df20 --- /dev/null +++ b/CPP/7zip/Compress/BWT/Mtf8.h @@ -0,0 +1,195 @@ +// Mtf8.h + +#ifndef __MTF8_H +#define __MTF8_H + +#include "Common/Types.h" + +namespace NCompress { + +class CMtf8Encoder +{ +public: + Byte Buffer[256]; + int FindAndMove(Byte v) + { + int pos; + for (pos = 0; Buffer[pos] != v; pos++); + int resPos = pos; + for (; pos >= 8; pos -= 8) + { + Buffer[pos] = Buffer[pos - 1]; + Buffer[pos - 1] = Buffer[pos - 2]; + Buffer[pos - 2] = Buffer[pos - 3]; + Buffer[pos - 3] = Buffer[pos - 4]; + Buffer[pos - 4] = Buffer[pos - 5]; + Buffer[pos - 5] = Buffer[pos - 6]; + Buffer[pos - 6] = Buffer[pos - 7]; + Buffer[pos - 7] = Buffer[pos - 8]; + } + for (; pos > 0; pos--) + Buffer[pos] = Buffer[pos - 1]; + Buffer[0] = v; + return resPos; + } +}; + +/* +class CMtf8Decoder +{ +public: + Byte Buffer[256]; + void Init(int) {}; + Byte GetHead() const { return Buffer[0]; } + Byte GetAndMove(int pos) + { + Byte res = Buffer[pos]; + for (; pos >= 8; pos -= 8) + { + Buffer[pos] = Buffer[pos - 1]; + Buffer[pos - 1] = Buffer[pos - 2]; + Buffer[pos - 2] = Buffer[pos - 3]; + Buffer[pos - 3] = Buffer[pos - 4]; + Buffer[pos - 4] = Buffer[pos - 5]; + Buffer[pos - 5] = Buffer[pos - 6]; + Buffer[pos - 6] = Buffer[pos - 7]; + Buffer[pos - 7] = Buffer[pos - 8]; + } + for (; pos > 0; pos--) + Buffer[pos] = Buffer[pos - 1]; + Buffer[0] = res; + return res; + } +}; +*/ + +#ifdef _WIN64 +#define MODE_64BIT +#endif + +#ifdef MODE_64BIT +typedef UInt64 CMtfVar; +#define MTF_MOVS 3 +#else +typedef UInt32 CMtfVar; +#define MTF_MOVS 2 +#endif + +#define MTF_MASK ((1 << MTF_MOVS) - 1) + + +class CMtf8Decoder +{ +public: + CMtfVar Buffer[256 >> MTF_MOVS]; + void StartInit() { memset(Buffer, 0, sizeof(Buffer)); } + void Add(unsigned int pos, Byte val) { Buffer[pos >> MTF_MOVS] |= ((CMtfVar)val << ((pos & MTF_MASK) << 3)); } + Byte GetHead() const { return (Byte)Buffer[0]; } + Byte GetAndMove(unsigned int pos) + { + UInt32 lim = ((UInt32)pos >> MTF_MOVS); + pos = (pos & MTF_MASK) << 3; + CMtfVar prev = (Buffer[lim] >> pos) & 0xFF; + + UInt32 i = 0; + if ((lim & 1) != 0) + { + CMtfVar next = Buffer[0]; + Buffer[0] = (next << 8) | prev; + prev = (next >> (MTF_MASK << 3)); + i = 1; + lim -= 1; + } + for (; i < lim; i += 2) + { + CMtfVar next = Buffer[i]; + Buffer[i] = (next << 8) | prev; + prev = (next >> (MTF_MASK << 3)); + next = Buffer[i + 1]; + Buffer[i + 1] = (next << 8) | prev; + prev = (next >> (MTF_MASK << 3)); + } + CMtfVar next = Buffer[i]; + CMtfVar mask = (((CMtfVar)0x100 << pos) - 1); + Buffer[i] = (next & ~mask) | (((next << 8) | prev) & mask); + return (Byte)Buffer[0]; + } +}; + +/* +const int kSmallSize = 64; +class CMtf8Decoder +{ + Byte SmallBuffer[kSmallSize]; + int SmallSize; + Byte Counts[16]; + int Size; +public: + Byte Buffer[256]; + + Byte GetHead() const + { + if (SmallSize > 0) + return SmallBuffer[kSmallSize - SmallSize]; + return Buffer[0]; + } + + void Init(int size) + { + Size = size; + SmallSize = 0; + for (int i = 0; i < 16; i++) + { + Counts[i] = ((size >= 16) ? 16 : size); + size -= Counts[i]; + } + } + + Byte GetAndMove(int pos) + { + if (pos < SmallSize) + { + Byte *p = SmallBuffer + kSmallSize - SmallSize; + Byte res = p[pos]; + for (; pos > 0; pos--) + p[pos] = p[pos - 1]; + SmallBuffer[kSmallSize - SmallSize] = res; + return res; + } + if (SmallSize == kSmallSize) + { + int i = Size - 1; + int g = 16; + do + { + g--; + int offset = (g << 4); + for (int t = Counts[g] - 1; t >= 0; t--, i--) + Buffer[i] = Buffer[offset + t]; + } + while(g != 0); + + for (i = kSmallSize - 1; i >= 0; i--) + Buffer[i] = SmallBuffer[i]; + Init(Size); + } + pos -= SmallSize; + int g; + for (g = 0; pos >= Counts[g]; g++) + pos -= Counts[g]; + int offset = (g << 4); + Byte res = Buffer[offset + pos]; + for (pos; pos < 16 - 1; pos++) + Buffer[offset + pos] = Buffer[offset + pos + 1]; + + SmallSize++; + SmallBuffer[kSmallSize - SmallSize] = res; + + Counts[g]--; + return res; + } +}; +*/ + +} +#endif diff --git a/CPP/7zip/Compress/BWT/StdAfx.h b/CPP/7zip/Compress/BWT/StdAfx.h new file mode 100755 index 00000000..b637fd40 --- /dev/null +++ b/CPP/7zip/Compress/BWT/StdAfx.h @@ -0,0 +1,6 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#endif diff --git a/CPP/7zip/Compress/BZip2/BZip2.dsp b/CPP/7zip/Compress/BZip2/BZip2.dsp new file mode 100755 index 00000000..121602d8 --- /dev/null +++ b/CPP/7zip/Compress/BZip2/BZip2.dsp @@ -0,0 +1,303 @@ +# Microsoft Developer Studio Project File - Name="BZip2" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=BZip2 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "BZip2.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "BZip2.mak" CFG="BZip2 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "BZip2 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "BZip2 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "BZip2 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "BZ_NO_STDIO" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /D "COMPRESS_BZIP2_MT" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\BZip2.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BZIP2_EXPORTS" /D "COMPRESS_BZIP2_MT" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\BZip2.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "BZip2 - Win32 Release" +# Name "BZip2 - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Codec.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# End Group +# Begin Group "Huffman" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Huffman\HuffmanDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Huffman\HuffmanEncode.c + +!IF "$(CFG)" == "BZip2 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Huffman\HuffmanEncode.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.c + +!IF "$(CFG)" == "BZip2 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.h +# End Source File +# End Group +# Begin Group "7-Zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MSBFDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MSBFEncoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# End Group +# Begin Group "BWT" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\BWT\BlockSort.cpp + +!IF "$(CFG)" == "BZip2 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\BWT\BlockSort.h +# End Source File +# Begin Source File + +SOURCE=..\BWT\Mtf8.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Thread.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\BZip2Const.h +# End Source File +# Begin Source File + +SOURCE=.\BZip2CRC.cpp +# End Source File +# Begin Source File + +SOURCE=.\BZip2CRC.h +# End Source File +# Begin Source File + +SOURCE=.\BZip2Decoder.cpp + +!IF "$(CFG)" == "BZip2 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\BZip2Decoder.h +# End Source File +# Begin Source File + +SOURCE=.\BZip2Encoder.cpp + +!IF "$(CFG)" == "BZip2 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "BZip2 - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\BZip2Encoder.h +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/Compress/BZip2/BZip2.dsw b/CPP/7zip/Compress/BZip2/BZip2.dsw new file mode 100755 index 00000000..697e5095 --- /dev/null +++ b/CPP/7zip/Compress/BZip2/BZip2.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "BZip2"=.\BZip2.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Compress/BZip2/BZip2CRC.cpp b/CPP/7zip/Compress/BZip2/BZip2CRC.cpp new file mode 100755 index 00000000..ba9ddb7e --- /dev/null +++ b/CPP/7zip/Compress/BZip2/BZip2CRC.cpp @@ -0,0 +1,26 @@ +// BZip2CRC.cpp + +#include "StdAfx.h" + +#include "BZip2CRC.h" + +UInt32 CBZip2CRC::Table[256]; + +static const UInt32 kBZip2CRCPoly = 0x04c11db7; /* AUTODIN II, Ethernet, & FDDI */ + +void CBZip2CRC::InitTable() +{ + for (UInt32 i = 0; i < 256; i++) + { + UInt32 r = (i << 24); + for (int j = 8; j > 0; j--) + r = (r & 0x80000000) ? ((r << 1) ^ kBZip2CRCPoly) : (r << 1); + Table[i] = r; + } +} + +class CBZip2CRCTableInit +{ +public: + CBZip2CRCTableInit() { CBZip2CRC::InitTable(); } +} g_BZip2CRCTableInit; diff --git a/CPP/7zip/Compress/BZip2/BZip2CRC.h b/CPP/7zip/Compress/BZip2/BZip2CRC.h new file mode 100755 index 00000000..8ac2a504 --- /dev/null +++ b/CPP/7zip/Compress/BZip2/BZip2CRC.h @@ -0,0 +1,31 @@ +// BZip2CRC.h + +#ifndef __BZIP2_CRC_H +#define __BZIP2_CRC_H + +#include "Common/Types.h" + +class CBZip2CRC +{ + UInt32 _value; + static UInt32 Table[256]; +public: + static void InitTable(); + CBZip2CRC(): _value(0xFFFFFFFF) {}; + void Init() { _value = 0xFFFFFFFF; } + void UpdateByte(Byte b) { _value = Table[(_value >> 24) ^ b] ^ (_value << 8); } + void UpdateByte(unsigned int b) { _value = Table[(_value >> 24) ^ b] ^ (_value << 8); } + UInt32 GetDigest() const { return _value ^ 0xFFFFFFFF; } +}; + +class CBZip2CombinedCRC +{ + UInt32 _value; +public: + CBZip2CombinedCRC(): _value(0){}; + void Init() { _value = 0; } + void Update(UInt32 v) { _value = ((_value << 1) | (_value >> 31)) ^ v; } + UInt32 GetDigest() const { return _value ; } +}; + +#endif diff --git a/CPP/7zip/Compress/BZip2/BZip2Const.h b/CPP/7zip/Compress/BZip2/BZip2Const.h new file mode 100755 index 00000000..62427aa6 --- /dev/null +++ b/CPP/7zip/Compress/BZip2/BZip2Const.h @@ -0,0 +1,54 @@ +// Compress/BZip2Const.h + +#ifndef __COMPRESS_BZIP2_CONST_H +#define __COMPRESS_BZIP2_CONST_H + +namespace NCompress { +namespace NBZip2 { + +const Byte kArSig0 = 'B'; +const Byte kArSig1 = 'Z'; +const Byte kArSig2 = 'h'; +const Byte kArSig3 = '0'; + +const Byte kFinSig0 = 0x17; +const Byte kFinSig1 = 0x72; +const Byte kFinSig2 = 0x45; +const Byte kFinSig3 = 0x38; +const Byte kFinSig4 = 0x50; +const Byte kFinSig5 = 0x90; + +const Byte kBlockSig0 = 0x31; +const Byte kBlockSig1 = 0x41; +const Byte kBlockSig2 = 0x59; +const Byte kBlockSig3 = 0x26; +const Byte kBlockSig4 = 0x53; +const Byte kBlockSig5 = 0x59; + +const int kNumOrigBits = 24; + +const int kNumTablesBits = 3; +const int kNumTablesMin = 2; +const int kNumTablesMax = 6; + +const int kNumLevelsBits = 5; + +const int kMaxHuffmanLen = 20; // Check it + +const int kMaxAlphaSize = 258; + +const int kGroupSize = 50; + +const int kBlockSizeMultMin = 1; +const int kBlockSizeMultMax = 9; +const UInt32 kBlockSizeStep = 100000; +const UInt32 kBlockSizeMax = kBlockSizeMultMax * kBlockSizeStep; + +const int kNumSelectorsBits = 15; +const UInt32 kNumSelectorsMax = (2 + (kBlockSizeMax / kGroupSize)); + +const int kRleModeRepSize = 4; + +}} + +#endif diff --git a/CPP/7zip/Compress/BZip2/BZip2Decoder.cpp b/CPP/7zip/Compress/BZip2/BZip2Decoder.cpp new file mode 100755 index 00000000..a0b16b18 --- /dev/null +++ b/CPP/7zip/Compress/BZip2/BZip2Decoder.cpp @@ -0,0 +1,770 @@ +// BZip2Decoder.cpp + +#include "StdAfx.h" + +#include "BZip2Decoder.h" + +#include "../../../Common/Alloc.h" +#include "../../../Common/Defs.h" +#include "../BWT/Mtf8.h" +#include "BZip2CRC.h" + +namespace NCompress { +namespace NBZip2 { + +const UInt32 kNumThreadsMax = 4; + +static const UInt32 kBufferSize = (1 << 17); + +static Int16 kRandNums[512] = { + 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, + 985, 724, 205, 454, 863, 491, 741, 242, 949, 214, + 733, 859, 335, 708, 621, 574, 73, 654, 730, 472, + 419, 436, 278, 496, 867, 210, 399, 680, 480, 51, + 878, 465, 811, 169, 869, 675, 611, 697, 867, 561, + 862, 687, 507, 283, 482, 129, 807, 591, 733, 623, + 150, 238, 59, 379, 684, 877, 625, 169, 643, 105, + 170, 607, 520, 932, 727, 476, 693, 425, 174, 647, + 73, 122, 335, 530, 442, 853, 695, 249, 445, 515, + 909, 545, 703, 919, 874, 474, 882, 500, 594, 612, + 641, 801, 220, 162, 819, 984, 589, 513, 495, 799, + 161, 604, 958, 533, 221, 400, 386, 867, 600, 782, + 382, 596, 414, 171, 516, 375, 682, 485, 911, 276, + 98, 553, 163, 354, 666, 933, 424, 341, 533, 870, + 227, 730, 475, 186, 263, 647, 537, 686, 600, 224, + 469, 68, 770, 919, 190, 373, 294, 822, 808, 206, + 184, 943, 795, 384, 383, 461, 404, 758, 839, 887, + 715, 67, 618, 276, 204, 918, 873, 777, 604, 560, + 951, 160, 578, 722, 79, 804, 96, 409, 713, 940, + 652, 934, 970, 447, 318, 353, 859, 672, 112, 785, + 645, 863, 803, 350, 139, 93, 354, 99, 820, 908, + 609, 772, 154, 274, 580, 184, 79, 626, 630, 742, + 653, 282, 762, 623, 680, 81, 927, 626, 789, 125, + 411, 521, 938, 300, 821, 78, 343, 175, 128, 250, + 170, 774, 972, 275, 999, 639, 495, 78, 352, 126, + 857, 956, 358, 619, 580, 124, 737, 594, 701, 612, + 669, 112, 134, 694, 363, 992, 809, 743, 168, 974, + 944, 375, 748, 52, 600, 747, 642, 182, 862, 81, + 344, 805, 988, 739, 511, 655, 814, 334, 249, 515, + 897, 955, 664, 981, 649, 113, 974, 459, 893, 228, + 433, 837, 553, 268, 926, 240, 102, 654, 459, 51, + 686, 754, 806, 760, 493, 403, 415, 394, 687, 700, + 946, 670, 656, 610, 738, 392, 760, 799, 887, 653, + 978, 321, 576, 617, 626, 502, 894, 679, 243, 440, + 680, 879, 194, 572, 640, 724, 926, 56, 204, 700, + 707, 151, 457, 449, 797, 195, 791, 558, 945, 679, + 297, 59, 87, 824, 713, 663, 412, 693, 342, 606, + 134, 108, 571, 364, 631, 212, 174, 643, 304, 329, + 343, 97, 430, 751, 497, 314, 983, 374, 822, 928, + 140, 206, 73, 263, 980, 736, 876, 478, 430, 305, + 170, 514, 364, 692, 829, 82, 855, 953, 676, 246, + 369, 970, 294, 750, 807, 827, 150, 790, 288, 923, + 804, 378, 215, 828, 592, 281, 565, 555, 710, 82, + 896, 831, 547, 261, 524, 462, 293, 465, 502, 56, + 661, 821, 976, 991, 658, 869, 905, 758, 745, 193, + 768, 550, 608, 933, 378, 286, 215, 979, 792, 961, + 61, 688, 793, 644, 986, 403, 106, 366, 905, 644, + 372, 567, 466, 434, 645, 210, 389, 550, 919, 135, + 780, 773, 635, 389, 707, 100, 626, 958, 165, 504, + 920, 176, 193, 713, 857, 265, 203, 50, 668, 108, + 645, 990, 626, 197, 510, 357, 358, 850, 858, 364, + 936, 638 +}; + +bool CState::Alloc() +{ + if (Counters == 0) + Counters = (UInt32 *)BigAlloc((256 + kBlockSizeMax) * sizeof(UInt32)); + return (Counters != 0); +} + +void CState::Free() +{ + ::BigFree(Counters); + Counters = 0; +} + +UInt32 CDecoder::ReadBits(int numBits) { return m_InStream.ReadBits(numBits); } +Byte CDecoder::ReadByte() {return (Byte)ReadBits(8); } +bool CDecoder::ReadBit() { return ReadBits(1) != 0; } + +UInt32 CDecoder::ReadCRC() +{ + UInt32 crc = 0; + for (int i = 0; i < 4; i++) + { + crc <<= 8; + crc |= ReadByte(); + } + return crc; +} + +UInt32 NO_INLINE ReadBits(NStream::NMSBF::CDecoder *m_InStream, int num) +{ + return m_InStream->ReadBits(num); +} + +UInt32 NO_INLINE ReadBit(NStream::NMSBF::CDecoder *m_InStream) +{ + return m_InStream->ReadBits(1); +} + +static HRESULT NO_INLINE ReadBlock(NStream::NMSBF::CDecoder *m_InStream, + UInt32 *CharCounters, UInt32 blockSizeMax, Byte *m_Selectors, CHuffmanDecoder *m_HuffmanDecoders, + UInt32 *blockSizeRes, UInt32 *origPtrRes, bool *randRes) +{ + *randRes = ReadBit(m_InStream) ? true : false; + *origPtrRes = ReadBits(m_InStream, kNumOrigBits); + + // in original code it compares OrigPtr to (UInt32)(10 + blockSizeMax)) : why ? + if (*origPtrRes >= blockSizeMax) + return S_FALSE; + + CMtf8Decoder mtf; + mtf.StartInit(); + + int numInUse = 0; + { + Byte inUse16[16]; + int i; + for (i = 0; i < 16; i++) + inUse16[i] = (Byte)ReadBit(m_InStream); + for (i = 0; i < 256; i++) + if (inUse16[i >> 4]) + { + if (ReadBit(m_InStream)) + mtf.Add(numInUse++, (Byte)i); + } + if (numInUse == 0) + return S_FALSE; + // mtf.Init(numInUse); + } + int alphaSize = numInUse + 2; + + int numTables = ReadBits(m_InStream, kNumTablesBits); + if (numTables < kNumTablesMin || numTables > kNumTablesMax) + return S_FALSE; + + UInt32 numSelectors = ReadBits(m_InStream, kNumSelectorsBits); + if (numSelectors < 1 || numSelectors > kNumSelectorsMax) + return S_FALSE; + + { + Byte mtfPos[kNumTablesMax]; + int t = 0; + do + mtfPos[t] = (Byte)t; + while(++t < numTables); + UInt32 i = 0; + do + { + int j = 0; + while (ReadBit(m_InStream)) + if (++j >= numTables) + return S_FALSE; + Byte tmp = mtfPos[j]; + for (;j > 0; j--) + mtfPos[j] = mtfPos[j - 1]; + m_Selectors[i] = mtfPos[0] = tmp; + } + while(++i < numSelectors); + } + + int t = 0; + do + { + Byte lens[kMaxAlphaSize]; + int len = (int)ReadBits(m_InStream, kNumLevelsBits); + int i; + for (i = 0; i < alphaSize; i++) + { + for (;;) + { + if (len < 1 || len > kMaxHuffmanLen) + return S_FALSE; + if (!ReadBit(m_InStream)) + break; + len += 1 - (int)(ReadBit(m_InStream) << 1); + } + lens[i] = (Byte)len; + } + for (; i < kMaxAlphaSize; i++) + lens[i] = 0; + if(!m_HuffmanDecoders[t].SetCodeLengths(lens)) + return S_FALSE; + } + while(++t < numTables); + + { + for (int i = 0; i < 256; i++) + CharCounters[i] = 0; + } + + UInt32 blockSize = 0; + { + UInt32 groupIndex = 0; + UInt32 groupSize = 0; + CHuffmanDecoder *huffmanDecoder = 0; + int runPower = 0; + UInt32 runCounter = 0; + + for (;;) + { + if (groupSize == 0) + { + if (groupIndex >= numSelectors) + return S_FALSE; + groupSize = kGroupSize; + huffmanDecoder = &m_HuffmanDecoders[m_Selectors[groupIndex++]]; + } + groupSize--; + + UInt32 nextSym = huffmanDecoder->DecodeSymbol(m_InStream); + + if (nextSym < 2) + { + runCounter += ((UInt32)(nextSym + 1) << runPower++); + if (blockSizeMax - blockSize < runCounter) + return S_FALSE; + continue; + } + if (runCounter != 0) + { + UInt32 b = (UInt32)mtf.GetHead(); + CharCounters[b] += runCounter; + do + CharCounters[256 + blockSize++] = b; + while(--runCounter != 0); + runPower = 0; + } + if (nextSym <= (UInt32)numInUse) + { + UInt32 b = (UInt32)mtf.GetAndMove((int)nextSym - 1); + if (blockSize >= blockSizeMax) + return S_FALSE; + CharCounters[b]++; + CharCounters[256 + blockSize++] = b; + } + else if (nextSym == (UInt32)numInUse + 1) + break; + else + return S_FALSE; + } + } + *blockSizeRes = blockSize; + return (*origPtrRes < blockSize) ? S_OK : S_FALSE; +} + +void NO_INLINE DecodeBlock1(UInt32 *charCounters, UInt32 blockSize) +{ + { + UInt32 sum = 0; + for (UInt32 i = 0; i < 256; i++) + { + sum += charCounters[i]; + charCounters[i] = sum - charCounters[i]; + } + } + + UInt32 *tt = charCounters + 256; + // Compute the T^(-1) vector + UInt32 i = 0; + do + tt[charCounters[tt[i] & 0xFF]++] |= (i << 8); + while(++i < blockSize); +} + +static UInt32 NO_INLINE DecodeBlock2(const UInt32 *tt, UInt32 blockSize, UInt32 OrigPtr, COutBuffer &m_OutStream) +{ + CBZip2CRC crc; + + // it's for speed optimization: prefetch & prevByte_init; + UInt32 tPos = tt[tt[OrigPtr] >> 8]; + unsigned int prevByte = (unsigned int)(tPos & 0xFF); + + int numReps = 0; + + do + { + unsigned int b = (unsigned int)(tPos & 0xFF); + tPos = tt[tPos >> 8]; + + if (numReps == kRleModeRepSize) + { + for (; b > 0; b--) + { + crc.UpdateByte(prevByte); + m_OutStream.WriteByte((Byte)prevByte); + } + numReps = 0; + continue; + } + if (b != prevByte) + numReps = 0; + numReps++; + prevByte = b; + crc.UpdateByte(b); + m_OutStream.WriteByte((Byte)b); + + /* + prevByte = b; + crc.UpdateByte(b); + m_OutStream.WriteByte((Byte)b); + for (; --blockSize != 0;) + { + b = (unsigned int)(tPos & 0xFF); + tPos = tt[tPos >> 8]; + crc.UpdateByte(b); + m_OutStream.WriteByte((Byte)b); + if (b != prevByte) + { + prevByte = b; + continue; + } + if (--blockSize == 0) + break; + + b = (unsigned int)(tPos & 0xFF); + tPos = tt[tPos >> 8]; + crc.UpdateByte(b); + m_OutStream.WriteByte((Byte)b); + if (b != prevByte) + { + prevByte = b; + continue; + } + if (--blockSize == 0) + break; + + b = (unsigned int)(tPos & 0xFF); + tPos = tt[tPos >> 8]; + crc.UpdateByte(b); + m_OutStream.WriteByte((Byte)b); + if (b != prevByte) + { + prevByte = b; + continue; + } + --blockSize; + break; + } + if (blockSize == 0) + break; + + b = (unsigned int)(tPos & 0xFF); + tPos = tt[tPos >> 8]; + + for (; b > 0; b--) + { + crc.UpdateByte(prevByte); + m_OutStream.WriteByte((Byte)prevByte); + } + */ + } + while(--blockSize != 0); + return crc.GetDigest(); +} + +static UInt32 NO_INLINE DecodeBlock2Rand(const UInt32 *tt, UInt32 blockSize, UInt32 OrigPtr, COutBuffer &m_OutStream) +{ + CBZip2CRC crc; + + UInt32 randIndex = 1; + UInt32 randToGo = kRandNums[0] - 2; + + int numReps = 0; + + // it's for speed optimization: prefetch & prevByte_init; + UInt32 tPos = tt[tt[OrigPtr] >> 8]; + unsigned int prevByte = (unsigned int)(tPos & 0xFF); + + do + { + unsigned int b = (unsigned int)(tPos & 0xFF); + tPos = tt[tPos >> 8]; + + { + if (randToGo == 0) + { + b ^= 1; + randToGo = kRandNums[randIndex++]; + randIndex &= 0x1FF; + } + randToGo--; + } + + if (numReps == kRleModeRepSize) + { + for (; b > 0; b--) + { + crc.UpdateByte(prevByte); + m_OutStream.WriteByte((Byte)prevByte); + } + numReps = 0; + continue; + } + if (b != prevByte) + numReps = 0; + numReps++; + prevByte = b; + crc.UpdateByte(b); + m_OutStream.WriteByte((Byte)b); + } + while(--blockSize != 0); + return crc.GetDigest(); +} + +#ifdef COMPRESS_BZIP2_MT + +static DWORD WINAPI MFThread(void *p) { ((CState *)p)->ThreadFunc(); return 0; } + +CDecoder::CDecoder(): + m_States(0) +{ + m_NumThreadsPrev = 0; + NumThreads = 1; + CS.Enter(); +} + +CDecoder::~CDecoder() +{ + Free(); +} + +bool CDecoder::Create() +{ + try + { + if (m_States != 0 && m_NumThreadsPrev == NumThreads) + return true; + Free(); + MtMode = (NumThreads > 1); + m_NumThreadsPrev = NumThreads; + m_States = new CState[NumThreads]; + if (m_States == 0) + return false; + #ifdef COMPRESS_BZIP2_MT + for (UInt32 t = 0; t < NumThreads; t++) + { + CState &ti = m_States[t]; + ti.Decoder = this; + if (MtMode) + if (!ti.Thread.Create(MFThread, &ti)) + { + NumThreads = t; + Free(); + return false; + } + } + #endif + } + catch(...) { return false; } + return true; +} + +void CDecoder::Free() +{ + if (!m_States) + return; + CloseThreads = true; + CS.Leave(); + for (UInt32 t = 0; t < NumThreads; t++) + { + CState &s = m_States[t]; + if (MtMode) + s.Thread.Wait(); + s.Free(); + } + delete []m_States; + m_States = 0; +} +#endif + +HRESULT CDecoder::ReadSignatures(bool &wasFinished, UInt32 &crc) +{ + wasFinished = false; + Byte s[6]; + for (int i = 0; i < 6; i++) + s[i] = ReadByte(); + crc = ReadCRC(); + if (s[0] == kFinSig0) + { + if (s[1] != kFinSig1 || + s[2] != kFinSig2 || + s[3] != kFinSig3 || + s[4] != kFinSig4 || + s[5] != kFinSig5) + return S_FALSE; + + wasFinished = true; + return (crc == CombinedCRC.GetDigest()) ? S_OK : S_FALSE; + } + if (s[0] != kBlockSig0 || + s[1] != kBlockSig1 || + s[2] != kBlockSig2 || + s[3] != kBlockSig3 || + s[4] != kBlockSig4 || + s[5] != kBlockSig5) + return S_FALSE; + CombinedCRC.Update(crc); + return S_OK; +} + +HRESULT CDecoder::DecodeFile(bool &isBZ, ICompressProgressInfo *progress) +{ + #ifdef COMPRESS_BZIP2_MT + Progress = progress; + if (!Create()) + return E_FAIL; + for (UInt32 t = 0; t < NumThreads; t++) + { + CState &s = m_States[t]; + if (!s.Alloc()) + return E_OUTOFMEMORY; + s.StreamWasFinishedEvent.Reset(); + s.WaitingWasStartedEvent.Reset(); + s.CanWriteEvent.Reset(); + } + #else + if (!m_States[0].Alloc()) + return E_OUTOFMEMORY; + #endif + + isBZ = false; + Byte s[6]; + int i; + for (i = 0; i < 4; i++) + s[i] = ReadByte(); + if (s[0] != kArSig0 || + s[1] != kArSig1 || + s[2] != kArSig2 || + s[3] <= kArSig3 || + s[3] > kArSig3 + kBlockSizeMultMax) + return S_OK; + isBZ = true; + UInt32 dicSize = (UInt32)(s[3] - kArSig3) * kBlockSizeStep; + + CombinedCRC.Init(); + #ifdef COMPRESS_BZIP2_MT + if (MtMode) + { + NextBlockIndex = 0; + StreamWasFinished1 = StreamWasFinished2 = false; + CloseThreads = false; + CanStartWaitingEvent.Reset(); + m_States[0].CanWriteEvent.Set(); + BlockSizeMax = dicSize; + Result1 = Result2 = S_OK; + CS.Leave(); + UInt32 t; + for (t = 0; t < NumThreads; t++) + m_States[t].StreamWasFinishedEvent.Lock(); + CS.Enter(); + CanStartWaitingEvent.Set(); + for (t = 0; t < NumThreads; t++) + m_States[t].WaitingWasStartedEvent.Lock(); + CanStartWaitingEvent.Reset(); + RINOK(Result2); + RINOK(Result1); + } + else + #endif + { + CState &state = m_States[0]; + for (;;) + { + if (progress) + { + UInt64 packSize = m_InStream.GetProcessedSize(); + UInt64 unpackSize = m_OutStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &unpackSize)); + } + bool wasFinished; + UInt32 crc; + RINOK(ReadSignatures(wasFinished, crc)); + if (wasFinished) + return S_OK; + + UInt32 blockSize, origPtr; + bool randMode; + RINOK(ReadBlock(&m_InStream, state.Counters, dicSize, + m_Selectors, m_HuffmanDecoders, + &blockSize, &origPtr, &randMode)); + DecodeBlock1(state.Counters, blockSize); + if ((randMode ? + DecodeBlock2Rand(state.Counters + 256, blockSize, origPtr, m_OutStream) : + DecodeBlock2(state.Counters + 256, blockSize, origPtr, m_OutStream)) != crc) + return S_FALSE; + } + } + return S_OK; +} + +HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 * /* outSize */, + ICompressProgressInfo *progress) +{ + if (!m_InStream.Create(kBufferSize)) + return E_OUTOFMEMORY; + if (!m_OutStream.Create(kBufferSize)) + return E_OUTOFMEMORY; + + m_InStream.SetStream(inStream); + m_InStream.Init(); + + m_OutStream.SetStream(outStream); + m_OutStream.Init(); + + CDecoderFlusher flusher(this); + + bool isBZ; + RINOK(DecodeFile(isBZ, progress)); + return isBZ ? S_OK: S_FALSE; +} + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const COutBufferException &e) { return e.ErrorCode; } + catch(...) { return E_FAIL; } +} + +STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) +{ + if (value == NULL) + return E_INVALIDARG; + *value = m_InStream.GetProcessedSize(); + return S_OK; +} + +#ifdef COMPRESS_BZIP2_MT +void CState::FinishStream() +{ + Decoder->StreamWasFinished1 = true; + StreamWasFinishedEvent.Set(); + Decoder->CS.Leave(); + Decoder->CanStartWaitingEvent.Lock(); + WaitingWasStartedEvent.Set(); +} + +void CState::ThreadFunc() +{ + for (;;) + { + Decoder->CS.Enter(); + if (Decoder->CloseThreads) + { + Decoder->CS.Leave(); + return; + } + if (Decoder->StreamWasFinished1) + { + FinishStream(); + continue; + } + HRESULT res = S_OK; + + UInt32 blockIndex = Decoder->NextBlockIndex; + UInt32 nextBlockIndex = blockIndex + 1; + if (nextBlockIndex == Decoder->NumThreads) + nextBlockIndex = 0; + Decoder->NextBlockIndex = nextBlockIndex; + UInt32 crc; + UInt64 packSize; + UInt32 blockSize = 0, origPtr = 0; + bool randMode = false; + + try + { + bool wasFinished; + res = Decoder->ReadSignatures(wasFinished, crc); + if (res != S_OK) + { + Decoder->Result1 = res; + FinishStream(); + continue; + } + if (wasFinished) + { + Decoder->Result1 = res; + FinishStream(); + continue; + } + + res = ReadBlock(&Decoder->m_InStream, Counters, Decoder->BlockSizeMax, + Decoder->m_Selectors, Decoder->m_HuffmanDecoders, + &blockSize, &origPtr, &randMode); + if (res != S_OK) + { + Decoder->Result1 = res; + FinishStream(); + continue; + } + packSize = Decoder->m_InStream.GetProcessedSize(); + } + catch(const CInBufferException &e) { res = e.ErrorCode; if (res != S_OK) res = E_FAIL; } + catch(...) { res = E_FAIL; } + if (res != S_OK) + { + Decoder->Result1 = res; + FinishStream(); + continue; + } + + Decoder->CS.Leave(); + + DecodeBlock1(Counters, blockSize); + + bool needFinish = true; + try + { + Decoder->m_States[blockIndex].CanWriteEvent.Lock(); + needFinish = Decoder->StreamWasFinished2; + if (!needFinish) + { + if ((randMode ? + DecodeBlock2Rand(Counters + 256, blockSize, origPtr, Decoder->m_OutStream) : + DecodeBlock2(Counters + 256, blockSize, origPtr, Decoder->m_OutStream)) == crc) + { + if (Decoder->Progress) + { + UInt64 unpackSize = Decoder->m_OutStream.GetProcessedSize(); + res = Decoder->Progress->SetRatioInfo(&packSize, &unpackSize); + } + } + else + res = S_FALSE; + } + } + catch(const COutBufferException &e) { res = e.ErrorCode; if (res != S_OK) res = E_FAIL; } + catch(...) { res = E_FAIL; } + if (res != S_OK) + { + Decoder->Result2 = res; + Decoder->StreamWasFinished2 = true; + } + Decoder->m_States[nextBlockIndex].CanWriteEvent.Set(); + if (res != S_OK || needFinish) + { + StreamWasFinishedEvent.Set(); + Decoder->CanStartWaitingEvent.Lock(); + WaitingWasStartedEvent.Set(); + } + } +} + +STDMETHODIMP CDecoder::SetNumberOfThreads(UInt32 numThreads) +{ + NumThreads = numThreads; + if (NumThreads < 1) + NumThreads = 1; + if (NumThreads > kNumThreadsMax) + NumThreads = kNumThreadsMax; + return S_OK; +} +#endif + +}} diff --git a/CPP/7zip/Compress/BZip2/BZip2Decoder.h b/CPP/7zip/Compress/BZip2/BZip2Decoder.h new file mode 100755 index 00000000..2375b755 --- /dev/null +++ b/CPP/7zip/Compress/BZip2/BZip2Decoder.h @@ -0,0 +1,164 @@ +// Compress/BZip2/Decoder.h + +#ifndef __COMPRESS_BZIP2_DECODER_H +#define __COMPRESS_BZIP2_DECODER_H + +#include "../../ICoder.h" +#include "../../../Common/MyCom.h" +#include "../../Common/MSBFDecoder.h" +#include "../../Common/InBuffer.h" +#include "../../Common/OutBuffer.h" +#include "../Huffman/HuffmanDecoder.h" +#include "BZip2Const.h" +#include "BZip2CRC.h" + +#ifdef COMPRESS_BZIP2_MT +#include "../../../Windows/Thread.h" +#include "../../../Windows/Synchronization.h" +#endif + +#if _MSC_VER >= 1300 +#define NO_INLINE __declspec(noinline) __fastcall +#else +#ifdef _MSC_VER +#define NO_INLINE __fastcall +#endif +#endif + +namespace NCompress { +namespace NBZip2 { + +typedef NCompress::NHuffman::CDecoder CHuffmanDecoder; + +class CDecoder; + +struct CState +{ + UInt32 *Counters; + + #ifdef COMPRESS_BZIP2_MT + + CDecoder *Decoder; + NWindows::CThread Thread; + bool m_OptimizeNumTables; + + NWindows::NSynchronization::CAutoResetEvent StreamWasFinishedEvent; + NWindows::NSynchronization::CAutoResetEvent WaitingWasStartedEvent; + + // it's not member of this thread. We just need one event per thread + NWindows::NSynchronization::CAutoResetEvent CanWriteEvent; + + Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size. + + void FinishStream(); + void ThreadFunc(); + + #endif + + CState(): Counters(0) {} + ~CState() { Free(); } + bool Alloc(); + void Free(); +}; + +class CDecoder : + public ICompressCoder, + #ifdef COMPRESS_BZIP2_MT + public ICompressSetCoderMt, + #endif + public ICompressGetInStreamProcessedSize, + public CMyUnknownImp +{ +public: + COutBuffer m_OutStream; + Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size. + NStream::NMSBF::CDecoder m_InStream; + Byte m_Selectors[kNumSelectorsMax]; + CHuffmanDecoder m_HuffmanDecoders[kNumTablesMax]; +private: + + UInt32 m_NumThreadsPrev; + + UInt32 ReadBits(int numBits); + Byte ReadByte(); + bool ReadBit(); + UInt32 ReadCRC(); + HRESULT PrepareBlock(CState &state); + HRESULT DecodeFile(bool &isBZ, ICompressProgressInfo *progress); + HRESULT CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + class CDecoderFlusher + { + CDecoder *_decoder; + public: + bool NeedFlush; + CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {} + ~CDecoderFlusher() + { + if (NeedFlush) + _decoder->Flush(); + _decoder->ReleaseStreams(); + } + }; + +public: + CBZip2CombinedCRC CombinedCRC; + + #ifdef COMPRESS_BZIP2_MT + ICompressProgressInfo *Progress; + CState *m_States; + + NWindows::NSynchronization::CCriticalSection CS; + UInt32 NumThreads; + bool MtMode; + UInt32 NextBlockIndex; + bool CloseThreads; + bool StreamWasFinished1; + bool StreamWasFinished2; + NWindows::NSynchronization::CManualResetEvent CanStartWaitingEvent; + + HRESULT Result1; + HRESULT Result2; + + UInt32 BlockSizeMax; + CDecoder(); + ~CDecoder(); + bool Create(); + void Free(); + + #else + CState m_States[1]; + #endif + + HRESULT ReadSignatures(bool &wasFinished, UInt32 &crc); + + + HRESULT Flush() { return m_OutStream.Flush(); } + void ReleaseStreams() + { + m_InStream.ReleaseStream(); + m_OutStream.ReleaseStream(); + } + + #ifdef COMPRESS_BZIP2_MT + MY_UNKNOWN_IMP2(ICompressSetCoderMt, ICompressGetInStreamProcessedSize) + #else + MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize) + #endif + + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); + + #ifdef COMPRESS_BZIP2_MT + STDMETHOD(SetNumberOfThreads)(UInt32 numThreads); + #endif +}; + +}} + +#endif diff --git a/CPP/7zip/Compress/BZip2/BZip2Encoder.cpp b/CPP/7zip/Compress/BZip2/BZip2Encoder.cpp new file mode 100755 index 00000000..1542b07c --- /dev/null +++ b/CPP/7zip/Compress/BZip2/BZip2Encoder.cpp @@ -0,0 +1,883 @@ +// BZip2Encoder.cpp + +#include "StdAfx.h" + +#include "../../../Common/Alloc.h" + +#include "BZip2Encoder.h" + +#include "../BWT/BlockSort.h" +#include "../BWT/Mtf8.h" +#include "BZip2CRC.h" + +extern "C" +{ + #include "../../../../C/Compress/Huffman/HuffmanEncode.h" +} + +namespace NCompress { +namespace NBZip2 { + +const int kMaxHuffmanLenForEncoding = 16; // it must be < kMaxHuffmanLen = 20 + +static const UInt32 kBufferSize = (1 << 17); +static const int kNumHuffPasses = 4; + +bool CThreadInfo::Create() +{ + if (m_BlockSorterIndex != 0) + return true; + m_BlockSorterIndex = (UInt32 *)::BigAlloc(BLOCK_SORT_BUF_SIZE(kBlockSizeMax) * sizeof(UInt32)); + if (m_BlockSorterIndex == 0) + return false; + + + if (m_Block == 0) + { + m_Block = (Byte *)::MidAlloc(kBlockSizeMax * 5 + kBlockSizeMax / 10 + (20 << 10)); + if (m_Block == 0) + return false; + m_MtfArray = m_Block + kBlockSizeMax; + m_TempArray = m_MtfArray + kBlockSizeMax * 2 + 2; + } + return true; +} + +void CThreadInfo::Free() +{ + ::BigFree(m_BlockSorterIndex); + m_BlockSorterIndex = 0; + ::MidFree(m_Block); + m_Block = 0; +} + +#ifdef COMPRESS_BZIP2_MT +void CThreadInfo::FinishStream(bool needLeave) +{ + Encoder->StreamWasFinished = true; + StreamWasFinishedEvent.Set(); + if (needLeave) + Encoder->CS.Leave(); + Encoder->CanStartWaitingEvent.Lock(); + WaitingWasStartedEvent.Set(); +} + +DWORD CThreadInfo::ThreadFunc() +{ + for (;;) + { + Encoder->CS.Enter(); + if (Encoder->CloseThreads) + { + Encoder->CS.Leave(); + return 0; + } + if (Encoder->StreamWasFinished) + { + FinishStream(true); + continue; + } + HRESULT res = S_OK; + bool needLeave = true; + try + { + UInt32 blockSize = Encoder->ReadRleBlock(m_Block); + m_PackSize = Encoder->m_InStream.GetProcessedSize(); + m_BlockIndex = Encoder->NextBlockIndex; + if (++Encoder->NextBlockIndex == Encoder->NumThreads) + Encoder->NextBlockIndex = 0; + if (blockSize == 0) + { + FinishStream(true); + continue; + } + Encoder->CS.Leave(); + needLeave = false; + res = EncodeBlock3(blockSize); + } + catch(const CInBufferException &e) { res = e.ErrorCode; } + catch(const COutBufferException &e) { res = e.ErrorCode; } + catch(...) { res = E_FAIL; } + if (res != S_OK) + { + Encoder->Result = res; + FinishStream(needLeave); + continue; + } + } +} + +static DWORD WINAPI MFThread(void *threadCoderInfo) +{ + return ((CThreadInfo *)threadCoderInfo)->ThreadFunc(); +} +#endif + +CEncoder::CEncoder(): + NumPasses(1), + m_OptimizeNumTables(false), + m_BlockSizeMult(kBlockSizeMultMax) +{ + #ifdef COMPRESS_BZIP2_MT + ThreadsInfo = 0; + m_NumThreadsPrev = 0; + NumThreads = 1; + CS.Enter(); + #endif +} + +#ifdef COMPRESS_BZIP2_MT +CEncoder::~CEncoder() +{ + Free(); +} + +bool CEncoder::Create() +{ + try + { + if (ThreadsInfo != 0 && m_NumThreadsPrev == NumThreads) + return true; + Free(); + MtMode = (NumThreads > 1); + m_NumThreadsPrev = NumThreads; + ThreadsInfo = new CThreadInfo[NumThreads]; + if (ThreadsInfo == 0) + return false; + for (UInt32 t = 0; t < NumThreads; t++) + { + CThreadInfo &ti = ThreadsInfo[t]; + ti.Encoder = this; + if (MtMode) + if (!ti.Thread.Create(MFThread, &ti)) + { + NumThreads = t; + Free(); + return false; + } + } + } + catch(...) { return false; } + return true; +} + +void CEncoder::Free() +{ + if (!ThreadsInfo) + return; + CloseThreads = true; + CS.Leave(); + for (UInt32 t = 0; t < NumThreads; t++) + { + CThreadInfo &ti = ThreadsInfo[t]; + if (MtMode) + ti.Thread.Wait(); + ti.Free(); + } + delete []ThreadsInfo; + ThreadsInfo = 0; +} +#endif + +UInt32 CEncoder::ReadRleBlock(Byte *buffer) +{ + UInt32 i = 0; + Byte prevByte; + if (m_InStream.ReadByte(prevByte)) + { + UInt32 blockSize = m_BlockSizeMult * kBlockSizeStep - 1; + int numReps = 1; + buffer[i++] = prevByte; + while (i < blockSize) // "- 1" to support RLE + { + Byte b; + if (!m_InStream.ReadByte(b)) + break; + if (b != prevByte) + { + if (numReps >= kRleModeRepSize) + buffer[i++] = (Byte)(numReps - kRleModeRepSize); + buffer[i++] = b; + numReps = 1; + prevByte = b; + continue; + } + numReps++; + if (numReps <= kRleModeRepSize) + buffer[i++] = b; + else if (numReps == kRleModeRepSize + 255) + { + buffer[i++] = (Byte)(numReps - kRleModeRepSize); + numReps = 0; + } + } + // it's to support original BZip2 decoder + if (numReps >= kRleModeRepSize) + buffer[i++] = (Byte)(numReps - kRleModeRepSize); + } + return i; +} + +void CThreadInfo::WriteBits2(UInt32 value, UInt32 numBits) + { m_OutStreamCurrent->WriteBits(value, numBits); } +void CThreadInfo::WriteByte2(Byte b) { WriteBits2(b , 8); } +void CThreadInfo::WriteBit2(bool v) { WriteBits2((v ? 1 : 0), 1); } +void CThreadInfo::WriteCRC2(UInt32 v) +{ + for (int i = 0; i < 4; i++) + WriteByte2(((Byte)(v >> (24 - i * 8)))); +} + +void CEncoder::WriteBits(UInt32 value, UInt32 numBits) + { m_OutStream.WriteBits(value, numBits); } +void CEncoder::WriteByte(Byte b) { WriteBits(b , 8); } +void CEncoder::WriteBit(bool v) { WriteBits((v ? 1 : 0), 1); } +void CEncoder::WriteCRC(UInt32 v) +{ + for (int i = 0; i < 4; i++) + WriteByte(((Byte)(v >> (24 - i * 8)))); +} + + +// blockSize > 0 +void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) +{ + WriteBit2(false); // Randomised = false + + { + UInt32 origPtr = BlockSort(m_BlockSorterIndex, block, blockSize); + // if (m_BlockSorterIndex[origPtr] != 0) throw 1; + m_BlockSorterIndex[origPtr] = blockSize; + WriteBits2(origPtr, kNumOrigBits); + } + + CMtf8Encoder mtf; + int numInUse = 0; + { + bool inUse[256]; + bool inUse16[16]; + UInt32 i; + for (i = 0; i < 256; i++) + inUse[i] = false; + for (i = 0; i < 16; i++) + inUse16[i] = false; + for (i = 0; i < blockSize; i++) + inUse[block[i]] = true; + for (i = 0; i < 256; i++) + if (inUse[i]) + { + inUse16[i >> 4] = true; + mtf.Buffer[numInUse++] = (Byte)i; + } + for (i = 0; i < 16; i++) + WriteBit2(inUse16[i]); + for (i = 0; i < 256; i++) + if (inUse16[i >> 4]) + WriteBit2(inUse[i]); + } + int alphaSize = numInUse + 2; + + Byte *mtfs = m_MtfArray; + UInt32 mtfArraySize = 0; + UInt32 symbolCounts[kMaxAlphaSize]; + { + for (int i = 0; i < kMaxAlphaSize; i++) + symbolCounts[i] = 0; + } + + { + UInt32 rleSize = 0; + UInt32 i = 0; + const UInt32 *bsIndex = m_BlockSorterIndex; + block--; + do + { + int pos = mtf.FindAndMove(block[bsIndex[i]]); + if (pos == 0) + rleSize++; + else + { + while (rleSize != 0) + { + rleSize--; + mtfs[mtfArraySize++] = (Byte)(rleSize & 1); + symbolCounts[rleSize & 1]++; + rleSize >>= 1; + } + if (pos >= 0xFE) + { + mtfs[mtfArraySize++] = 0xFF; + mtfs[mtfArraySize++] = (Byte)(pos - 0xFE); + } + else + mtfs[mtfArraySize++] = (Byte)(pos + 1); + symbolCounts[pos + 1]++; + } + } + while (++i < blockSize); + + while (rleSize != 0) + { + rleSize--; + mtfs[mtfArraySize++] = (Byte)(rleSize & 1); + symbolCounts[rleSize & 1]++; + rleSize >>= 1; + } + + if (alphaSize < 256) + mtfs[mtfArraySize++] = (Byte)(alphaSize - 1); + else + { + mtfs[mtfArraySize++] = 0xFF; + mtfs[mtfArraySize++] = (Byte)(alphaSize - 256); + } + symbolCounts[alphaSize - 1]++; + } + + UInt32 numSymbols = 0; + { + for (int i = 0; i < kMaxAlphaSize; i++) + numSymbols += symbolCounts[i]; + } + + int bestNumTables = kNumTablesMin; + UInt32 bestPrice = 0xFFFFFFFF; + UInt32 startPos = m_OutStreamCurrent->GetPos(); + Byte startCurByte = m_OutStreamCurrent->GetCurByte(); + for (int nt = kNumTablesMin; nt <= kNumTablesMax + 1; nt++) + { + int numTables; + + if(m_OptimizeNumTables) + { + m_OutStreamCurrent->SetPos(startPos); + m_OutStreamCurrent->SetCurState((startPos & 7), startCurByte); + if (nt <= kNumTablesMax) + numTables = nt; + else + numTables = bestNumTables; + } + else + { + if (numSymbols < 200) numTables = 2; + else if (numSymbols < 600) numTables = 3; + else if (numSymbols < 1200) numTables = 4; + else if (numSymbols < 2400) numTables = 5; + else numTables = 6; + } + + WriteBits2(numTables, kNumTablesBits); + + UInt32 numSelectors = (numSymbols + kGroupSize - 1) / kGroupSize; + WriteBits2(numSelectors, kNumSelectorsBits); + + { + UInt32 remFreq = numSymbols; + int gs = 0; + int t = numTables; + do + { + UInt32 tFreq = remFreq / t; + int ge = gs; + UInt32 aFreq = 0; + while (aFreq < tFreq) // && ge < alphaSize) + aFreq += symbolCounts[ge++]; + + if (ge - 1 > gs && t != numTables && t != 1 && (((numTables - t) & 1) == 1)) + aFreq -= symbolCounts[--ge]; + + Byte *lens = Lens[t - 1]; + int i = 0; + do + lens[i] = (i >= gs && i < ge) ? 0 : 1; + while (++i < alphaSize); + gs = ge; + remFreq -= aFreq; + } + while(--t != 0); + } + + + for (int pass = 0; pass < kNumHuffPasses; pass++) + { + { + int t = 0; + do + memset(Freqs[t], 0, sizeof(Freqs[t])); + while(++t < numTables); + } + + { + UInt32 mtfPos = 0; + UInt32 g = 0; + do + { + UInt32 symbols[kGroupSize]; + int i = 0; + do + { + UInt32 symbol = mtfs[mtfPos++]; + if (symbol >= 0xFF) + symbol += mtfs[mtfPos++]; + symbols[i] = symbol; + } + while (++i < kGroupSize && mtfPos < mtfArraySize); + + UInt32 bestPrice = 0xFFFFFFFF; + int t = 0; + do + { + const Byte *lens = Lens[t]; + UInt32 price = 0; + int j = 0; + do + price += lens[symbols[j]]; + while (++j < i); + if (price < bestPrice) + { + m_Selectors[g] = (Byte)t; + bestPrice = price; + } + } + while(++t < numTables); + UInt32 *freqs = Freqs[m_Selectors[g++]]; + int j = 0; + do + freqs[symbols[j]]++; + while (++j < i); + } + while (mtfPos < mtfArraySize); + } + + int t = 0; + do + { + UInt32 *freqs = Freqs[t]; + int i = 0; + do + if (freqs[i] == 0) + freqs[i] = 1; + while(++i < alphaSize); + Huffman_Generate(freqs, Codes[t], Lens[t], kMaxAlphaSize, kMaxHuffmanLenForEncoding); + } + while(++t < numTables); + } + + { + Byte mtfSel[kNumTablesMax]; + { + int t = 0; + do + mtfSel[t] = (Byte)t; + while(++t < numTables); + } + + UInt32 i = 0; + do + { + Byte sel = m_Selectors[i]; + int pos; + for (pos = 0; mtfSel[pos] != sel; pos++) + WriteBit2(true); + WriteBit2(false); + for (; pos > 0; pos--) + mtfSel[pos] = mtfSel[pos - 1]; + mtfSel[0] = sel; + } + while(++i < numSelectors); + } + + { + int t = 0; + do + { + const Byte *lens = Lens[t]; + UInt32 len = lens[0]; + WriteBits2(len, kNumLevelsBits); + int i = 0; + do + { + UInt32 level = lens[i]; + while (len != level) + { + WriteBit2(true); + if (len < level) + { + WriteBit2(false); + len++; + } + else + { + WriteBit2(true); + len--; + } + } + WriteBit2(false); + } + while (++i < alphaSize); + } + while(++t < numTables); + } + + { + UInt32 groupSize = 0; + UInt32 groupIndex = 0; + const Byte *lens = 0; + const UInt32 *codes = 0; + UInt32 mtfPos = 0; + do + { + UInt32 symbol = mtfs[mtfPos++]; + if (symbol >= 0xFF) + symbol += mtfs[mtfPos++]; + if (groupSize == 0) + { + groupSize = kGroupSize; + int t = m_Selectors[groupIndex++]; + lens = Lens[t]; + codes = Codes[t]; + } + groupSize--; + m_OutStreamCurrent->WriteBits(codes[symbol], lens[symbol]); + } + while (mtfPos < mtfArraySize); + } + + if (!m_OptimizeNumTables) + break; + UInt32 price = m_OutStreamCurrent->GetPos() - startPos; + if (price <= bestPrice) + { + if (nt == kNumTablesMax) + break; + bestPrice = price; + bestNumTables = nt; + } + } +} + +// blockSize > 0 +UInt32 CThreadInfo::EncodeBlockWithHeaders(const Byte *block, UInt32 blockSize) +{ + WriteByte2(kBlockSig0); + WriteByte2(kBlockSig1); + WriteByte2(kBlockSig2); + WriteByte2(kBlockSig3); + WriteByte2(kBlockSig4); + WriteByte2(kBlockSig5); + + CBZip2CRC crc; + int numReps = 0; + Byte prevByte = block[0]; + UInt32 i = 0; + do + { + Byte b = block[i]; + if (numReps == kRleModeRepSize) + { + for (; b > 0; b--) + crc.UpdateByte(prevByte); + numReps = 0; + continue; + } + if (prevByte == b) + numReps++; + else + { + numReps = 1; + prevByte = b; + } + crc.UpdateByte(b); + } + while (++i < blockSize); + UInt32 crcRes = crc.GetDigest(); + WriteCRC2(crcRes); + EncodeBlock(block, blockSize); + return crcRes; +} + +void CThreadInfo::EncodeBlock2(const Byte *block, UInt32 blockSize, UInt32 numPasses) +{ + UInt32 numCrcs = m_NumCrcs; + bool needCompare = false; + + UInt32 startBytePos = m_OutStreamCurrent->GetBytePos(); + UInt32 startPos = m_OutStreamCurrent->GetPos(); + Byte startCurByte = m_OutStreamCurrent->GetCurByte(); + Byte endCurByte = 0; + UInt32 endPos = 0; + if (numPasses > 1 && blockSize >= (1 << 10)) + { + UInt32 blockSize0 = blockSize / 2; + for (;(block[blockSize0] == block[blockSize0 - 1] || + block[blockSize0 - 1] == block[blockSize0 - 2]) && + blockSize0 < blockSize; blockSize0++); + if (blockSize0 < blockSize) + { + EncodeBlock2(block, blockSize0, numPasses - 1); + EncodeBlock2(block + blockSize0, blockSize - blockSize0, numPasses - 1); + endPos = m_OutStreamCurrent->GetPos(); + endCurByte = m_OutStreamCurrent->GetCurByte(); + if ((endPos & 7) > 0) + WriteBits2(0, 8 - (endPos & 7)); + m_OutStreamCurrent->SetCurState((startPos & 7), startCurByte); + needCompare = true; + } + } + + UInt32 startBytePos2 = m_OutStreamCurrent->GetBytePos(); + UInt32 startPos2 = m_OutStreamCurrent->GetPos(); + UInt32 crcVal = EncodeBlockWithHeaders(block, blockSize); + UInt32 endPos2 = m_OutStreamCurrent->GetPos(); + + if (needCompare) + { + UInt32 size2 = endPos2 - startPos2; + if (size2 < endPos - startPos) + { + UInt32 numBytes = m_OutStreamCurrent->GetBytePos() - startBytePos2; + Byte *buffer = m_OutStreamCurrent->GetStream(); + for (UInt32 i = 0; i < numBytes; i++) + buffer[startBytePos + i] = buffer[startBytePos2 + i]; + m_OutStreamCurrent->SetPos(startPos + endPos2 - startPos2); + m_NumCrcs = numCrcs; + m_CRCs[m_NumCrcs++] = crcVal; + } + else + { + m_OutStreamCurrent->SetPos(endPos); + m_OutStreamCurrent->SetCurState((endPos & 7), endCurByte); + } + } + else + { + m_NumCrcs = numCrcs; + m_CRCs[m_NumCrcs++] = crcVal; + } +} + +HRESULT CThreadInfo::EncodeBlock3(UInt32 blockSize) +{ + CMsbfEncoderTemp outStreamTemp; + outStreamTemp.SetStream(m_TempArray); + outStreamTemp.Init(); + m_OutStreamCurrent = &outStreamTemp; + + m_NumCrcs = 0; + + EncodeBlock2(m_Block, blockSize, Encoder->NumPasses); + + #ifdef COMPRESS_BZIP2_MT + if (Encoder->MtMode) + Encoder->ThreadsInfo[m_BlockIndex].CanWriteEvent.Lock(); + #endif + for (UInt32 i = 0; i < m_NumCrcs; i++) + Encoder->CombinedCRC.Update(m_CRCs[i]); + Encoder->WriteBytes(m_TempArray, outStreamTemp.GetPos(), outStreamTemp.GetCurByte()); + HRESULT res = S_OK; + #ifdef COMPRESS_BZIP2_MT + if (Encoder->MtMode) + { + UInt32 blockIndex = m_BlockIndex + 1; + if (blockIndex == Encoder->NumThreads) + blockIndex = 0; + + if (Encoder->Progress) + { + UInt64 unpackSize = Encoder->m_OutStream.GetProcessedSize(); + res = Encoder->Progress->SetRatioInfo(&m_PackSize, &unpackSize); + } + + Encoder->ThreadsInfo[blockIndex].CanWriteEvent.Set(); + } + #endif + return res; +} + +void CEncoder::WriteBytes(const Byte *data, UInt32 sizeInBits, Byte lastByte) +{ + UInt32 bytesSize = (sizeInBits / 8); + for (UInt32 i = 0; i < bytesSize; i++) + m_OutStream.WriteBits(data[i], 8); + WriteBits(lastByte, (sizeInBits & 7)); +} + + +HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 * /* outSize */, + ICompressProgressInfo *progress) +{ + #ifdef COMPRESS_BZIP2_MT + Progress = progress; + if (!Create()) + return E_FAIL; + for (UInt32 t = 0; t < NumThreads; t++) + #endif + { + #ifdef COMPRESS_BZIP2_MT + CThreadInfo &ti = ThreadsInfo[t]; + ti.StreamWasFinishedEvent.Reset(); + ti.WaitingWasStartedEvent.Reset(); + ti.CanWriteEvent.Reset(); + #else + CThreadInfo &ti = ThreadsInfo; + ti.Encoder = this; + #endif + + ti.m_OptimizeNumTables = m_OptimizeNumTables; + + if (!ti.Create()) + return E_OUTOFMEMORY; + } + + + if (!m_InStream.Create(kBufferSize)) + return E_OUTOFMEMORY; + if (!m_OutStream.Create(kBufferSize)) + return E_OUTOFMEMORY; + + + m_InStream.SetStream(inStream); + m_InStream.Init(); + + m_OutStream.SetStream(outStream); + m_OutStream.Init(); + + CFlusher flusher(this); + + CombinedCRC.Init(); + #ifdef COMPRESS_BZIP2_MT + NextBlockIndex = 0; + StreamWasFinished = false; + CloseThreads = false; + CanStartWaitingEvent.Reset(); + #endif + + WriteByte(kArSig0); + WriteByte(kArSig1); + WriteByte(kArSig2); + WriteByte((Byte)(kArSig3 + m_BlockSizeMult)); + + #ifdef COMPRESS_BZIP2_MT + + if (MtMode) + { + ThreadsInfo[0].CanWriteEvent.Set(); + Result = S_OK; + CS.Leave(); + UInt32 t; + for (t = 0; t < NumThreads; t++) + ThreadsInfo[t].StreamWasFinishedEvent.Lock(); + CS.Enter(); + CanStartWaitingEvent.Set(); + for (t = 0; t < NumThreads; t++) + ThreadsInfo[t].WaitingWasStartedEvent.Lock(); + CanStartWaitingEvent.Reset(); + RINOK(Result); + } + else + #endif + { + for (;;) + { + CThreadInfo &ti = + #ifdef COMPRESS_BZIP2_MT + ThreadsInfo[0]; + #else + ThreadsInfo; + #endif + UInt32 blockSize = ReadRleBlock(ti.m_Block); + if (blockSize == 0) + break; + RINOK(ti.EncodeBlock3(blockSize)); + if (progress) + { + UInt64 packSize = m_InStream.GetProcessedSize(); + UInt64 unpackSize = m_OutStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &unpackSize)); + } + } + } + WriteByte(kFinSig0); + WriteByte(kFinSig1); + WriteByte(kFinSig2); + WriteByte(kFinSig3); + WriteByte(kFinSig4); + WriteByte(kFinSig5); + + WriteCRC(CombinedCRC.GetDigest()); + return S_OK; +} + +STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const COutBufferException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +HRESULT CEncoder::SetCoderProperties(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties) +{ + for(UInt32 i = 0; i < numProperties; i++) + { + const PROPVARIANT &property = properties[i]; + switch(propIDs[i]) + { + case NCoderPropID::kNumPasses: + { + if (property.vt != VT_UI4) + return E_INVALIDARG; + UInt32 numPasses = property.ulVal; + if (numPasses == 0) + numPasses = 1; + if (numPasses > kNumPassesMax) + numPasses = kNumPassesMax; + NumPasses = numPasses; + m_OptimizeNumTables = (NumPasses > 1); + break; + } + case NCoderPropID::kDictionarySize: + { + if (property.vt != VT_UI4) + return E_INVALIDARG; + UInt32 dictionary = property.ulVal / kBlockSizeStep; + if (dictionary < kBlockSizeMultMin) + dictionary = kBlockSizeMultMin; + else if (dictionary > kBlockSizeMultMax) + dictionary = kBlockSizeMultMax; + m_BlockSizeMult = dictionary; + break; + } + case NCoderPropID::kNumThreads: + { + #ifdef COMPRESS_BZIP2_MT + if (property.vt != VT_UI4) + return E_INVALIDARG; + NumThreads = property.ulVal; + if (NumThreads < 1) + NumThreads = 1; + #endif + break; + } + default: + return E_INVALIDARG; + } + } + return S_OK; +} + +#ifdef COMPRESS_BZIP2_MT +STDMETHODIMP CEncoder::SetNumberOfThreads(UInt32 numThreads) +{ + NumThreads = numThreads; + if (NumThreads < 1) + NumThreads = 1; + return S_OK; +} +#endif + +}} diff --git a/CPP/7zip/Compress/BZip2/BZip2Encoder.h b/CPP/7zip/Compress/BZip2/BZip2Encoder.h new file mode 100755 index 00000000..62b255d4 --- /dev/null +++ b/CPP/7zip/Compress/BZip2/BZip2Encoder.h @@ -0,0 +1,246 @@ +// Compress/BZip2/Encoder.h + +#ifndef __COMPRESS_BZIP2_ENCODER_H +#define __COMPRESS_BZIP2_ENCODER_H + +#include "../../ICoder.h" +#include "../../../Common/MyCom.h" +#include "../../Common/MSBFEncoder.h" +#include "../../Common/InBuffer.h" +#include "../../Common/OutBuffer.h" +#include "BZip2Const.h" +#include "BZip2CRC.h" + +#ifdef COMPRESS_BZIP2_MT +#include "../../../Windows/Thread.h" +#include "../../../Windows/Synchronization.h" +#endif + +namespace NCompress { +namespace NBZip2 { + +class CMsbfEncoderTemp +{ + UInt32 m_Pos; + int m_BitPos; + Byte m_CurByte; + Byte *Buffer; +public: + void SetStream(Byte *buffer) { Buffer = buffer; } + Byte *GetStream() const { return Buffer; } + + void Init() + { + m_Pos = 0; + m_BitPos = 8; + m_CurByte = 0; + } + + void Flush() + { + if(m_BitPos < 8) + WriteBits(0, m_BitPos); + } + + void WriteBits(UInt32 value, int numBits) + { + while(numBits > 0) + { + int numNewBits = MyMin(numBits, m_BitPos); + numBits -= numNewBits; + + m_CurByte <<= numNewBits; + UInt32 newBits = value >> numBits; + m_CurByte |= Byte(newBits); + value -= (newBits << numBits); + + m_BitPos -= numNewBits; + + if (m_BitPos == 0) + { + Buffer[m_Pos++] = m_CurByte; + m_BitPos = 8; + } + } + } + + UInt32 GetBytePos() const { return m_Pos ; } + UInt32 GetPos() const { return m_Pos * 8 + (8 - m_BitPos); } + Byte GetCurByte() const { return m_CurByte; } + void SetPos(UInt32 bitPos) + { + m_Pos = bitPos / 8; + m_BitPos = 8 - (bitPos & 7); + } + void SetCurState(UInt32 bitPos, Byte curByte) + { + m_BitPos = 8 - bitPos; + m_CurByte = curByte; + } +}; + +class CEncoder; + +const int kNumPassesMax = 10; + +class CThreadInfo +{ +public: + Byte *m_Block; +private: + Byte *m_MtfArray; + Byte *m_TempArray; + UInt32 *m_BlockSorterIndex; + + CMsbfEncoderTemp *m_OutStreamCurrent; + + Byte Lens[kNumTablesMax][kMaxAlphaSize]; + UInt32 Freqs[kNumTablesMax][kMaxAlphaSize]; + UInt32 Codes[kNumTablesMax][kMaxAlphaSize]; + + Byte m_Selectors[kNumSelectorsMax]; + + UInt32 m_CRCs[1 << kNumPassesMax]; + UInt32 m_NumCrcs; + + int m_BlockIndex; + + void FinishStream(bool needLeave); + + void WriteBits2(UInt32 value, UInt32 numBits); + void WriteByte2(Byte b); + void WriteBit2(bool v); + void WriteCRC2(UInt32 v); + + void EncodeBlock(const Byte *block, UInt32 blockSize); + UInt32 EncodeBlockWithHeaders(const Byte *block, UInt32 blockSize); + void EncodeBlock2(const Byte *block, UInt32 blockSize, UInt32 numPasses); +public: + bool m_OptimizeNumTables; + CEncoder *Encoder; + #ifdef COMPRESS_BZIP2_MT + NWindows::CThread Thread; + + NWindows::NSynchronization::CAutoResetEvent StreamWasFinishedEvent; + NWindows::NSynchronization::CAutoResetEvent WaitingWasStartedEvent; + + // it's not member of this thread. We just need one event per thread + NWindows::NSynchronization::CAutoResetEvent CanWriteEvent; + + UInt64 m_PackSize; + + Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size. + #endif + + CThreadInfo(): m_BlockSorterIndex(0), m_Block(0) {} + ~CThreadInfo() { Free(); } + bool Create(); + void Free(); + + HRESULT EncodeBlock3(UInt32 blockSize); + DWORD ThreadFunc(); +}; + +class CEncoder : + public ICompressCoder, + public ICompressSetCoderProperties, + #ifdef COMPRESS_BZIP2_MT + public ICompressSetCoderMt, + #endif + public CMyUnknownImp +{ + UInt32 m_BlockSizeMult; + bool m_OptimizeNumTables; + + UInt32 m_NumPassesPrev; + + UInt32 m_NumThreadsPrev; +public: + CInBuffer m_InStream; + Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size. + NStream::NMSBF::CEncoder m_OutStream; + UInt32 NumPasses; + CBZip2CombinedCRC CombinedCRC; + + #ifdef COMPRESS_BZIP2_MT + CThreadInfo *ThreadsInfo; + NWindows::NSynchronization::CCriticalSection CS; + UInt32 NumThreads; + bool MtMode; + UInt32 NextBlockIndex; + + bool CloseThreads; + bool StreamWasFinished; + NWindows::NSynchronization::CManualResetEvent CanStartWaitingEvent; + + HRESULT Result; + ICompressProgressInfo *Progress; + #else + CThreadInfo ThreadsInfo; + #endif + + UInt32 ReadRleBlock(Byte *buffer); + void WriteBytes(const Byte *data, UInt32 sizeInBits, Byte lastByte); + + void WriteBits(UInt32 value, UInt32 numBits); + void WriteByte(Byte b); + void WriteBit(bool v); + void WriteCRC(UInt32 v); + + #ifdef COMPRESS_BZIP2_MT + bool Create(); + void Free(); + #endif + +public: + CEncoder(); + #ifdef COMPRESS_BZIP2_MT + ~CEncoder(); + #endif + + HRESULT Flush() { return m_OutStream.Flush(); } + + void ReleaseStreams() + { + m_InStream.ReleaseStream(); + m_OutStream.ReleaseStream(); + } + + class CFlusher + { + CEncoder *_coder; + public: + bool NeedFlush; + CFlusher(CEncoder *coder): _coder(coder), NeedFlush(true) {} + ~CFlusher() + { + if (NeedFlush) + _coder->Flush(); + _coder->ReleaseStreams(); + } + }; + + #ifdef COMPRESS_BZIP2_MT + MY_UNKNOWN_IMP2(ICompressSetCoderMt, ICompressSetCoderProperties) + #else + MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize) + #endif + + HRESULT CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + STDMETHOD(SetCoderProperties)(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties); + + #ifdef COMPRESS_BZIP2_MT + STDMETHOD(SetNumberOfThreads)(UInt32 numThreads); + #endif +}; + +}} + +#endif diff --git a/CPP/7zip/Compress/BZip2/DllExports.cpp b/CPP/7zip/Compress/BZip2/DllExports.cpp new file mode 100755 index 00000000..57a3ae65 --- /dev/null +++ b/CPP/7zip/Compress/BZip2/DllExports.cpp @@ -0,0 +1,93 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#ifdef _WIN32 +#include "Common/Alloc.h" +#endif + +#include "BZip2Encoder.h" +#include "BZip2Decoder.h" + +// {23170F69-40C1-278B-0402-020000000000} +DEFINE_GUID(CLSID_CCompressBZip2Decoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00); + +// {23170F69-40C1-278B-0402-020000000100} +DEFINE_GUID(CLSID_CCompressBZip2Encoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD dwReason, LPVOID /*lpReserved*/) +{ + #ifdef _WIN32 + if (dwReason == DLL_PROCESS_ATTACH) + SetLargePageSize(); + #endif + return TRUE; +} + +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + int correctInterface = (*iid == IID_ICompressCoder); + CMyComPtr coder; + if (*clsid == CLSID_CCompressBZip2Decoder) + { + if (!correctInterface) + return E_NOINTERFACE; + coder = (ICompressCoder *)new NCompress::NBZip2::CDecoder; + } + else if (*clsid == CLSID_CCompressBZip2Encoder) + { + if (!correctInterface) + return E_NOINTERFACE; + coder = (ICompressCoder *)new NCompress::NBZip2::CEncoder; + } + else + return CLASS_E_CLASSNOTAVAILABLE; + *outObject = coder.Detach(); + COM_TRY_END + return S_OK; +} + +STDAPI GetNumberOfMethods(UINT32 *numMethods) +{ + *numMethods = 1; + return S_OK; +} + +STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +{ + if (index != 0) + return E_INVALIDARG; + ::VariantClear((tagVARIANT *)value); + switch(propID) + { + case NMethodPropID::kID: + { + const char id[] = { 0x04, 0x02, 0x02 }; + if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NMethodPropID::kName: + if ((value->bstrVal = ::SysAllocString(L"BZip2")) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kDecoder: + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CCompressBZip2Decoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kEncoder: + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CCompressBZip2Encoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + return S_OK; +} diff --git a/CPP/7zip/Compress/BZip2/StdAfx.cpp b/CPP/7zip/Compress/BZip2/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Compress/BZip2/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Compress/BZip2/StdAfx.h b/CPP/7zip/Compress/BZip2/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Compress/BZip2/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Compress/BZip2/makefile b/CPP/7zip/Compress/BZip2/makefile new file mode 100755 index 00000000..9e8cbdcb --- /dev/null +++ b/CPP/7zip/Compress/BZip2/makefile @@ -0,0 +1,56 @@ +PROG = BZip2.dll +DEF_FILE = ../Codec.def +CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_BZIP2_MT +LIBS = $(LIBS) oleaut32.lib + +BZIP2_OBJS = \ + $O\DllExports.obj \ + $O\BZip2CRC.obj \ + +BZIP2_OPT_OBJS = \ + $O\BZip2Decoder.obj \ + $O\BZip2Encoder.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + +WIN_OBJS = \ + $O\Synchronization.obj + +7ZIP_COMMON_OBJS = \ + $O\InBuffer.obj \ + $O\OutBuffer.obj \ + +C_OBJS = \ + $O\Sort.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(BZIP2_OBJS) \ + $(BZIP2_OPT_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $O\BlockSort.obj \ + $(C_OBJS) \ + $O\HuffmanEncode.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(BZIP2_OBJS): $(*B).cpp + $(COMPL) +$(BZIP2_OPT_OBJS): $(*B).cpp + $(COMPL_O2) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$O\BlockSort.obj: ../BWT/$(*B).cpp + $(COMPL_O2) +$(C_OBJS): ../../../../C/$(*B).c + $(COMPL_O2) +$O\HuffmanEncode.obj: ../../../../C/Compress/Huffman/$(*B).c + $(COMPL_O2) diff --git a/CPP/7zip/Compress/BZip2/resource.rc b/CPP/7zip/Compress/BZip2/resource.rc new file mode 100755 index 00000000..c5bea782 --- /dev/null +++ b/CPP/7zip/Compress/BZip2/resource.rc @@ -0,0 +1,3 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("BZip2 Codec", "BZip2") diff --git a/CPP/7zip/Compress/BZip2Original/BZip2Decoder.cpp b/CPP/7zip/Compress/BZip2Original/BZip2Decoder.cpp new file mode 100755 index 00000000..5fb77d01 --- /dev/null +++ b/CPP/7zip/Compress/BZip2Original/BZip2Decoder.cpp @@ -0,0 +1,131 @@ +// BZip2Decoder.cpp + +#include "StdAfx.h" + +#include "BZip2Decoder.h" + +#include "../../../Common/Alloc.h" +#include "Original/bzlib.h" + +namespace NCompress { +namespace NBZip2 { + +static const UInt32 kBufferSize = (1 << 20); + +CDecoder::~CDecoder() +{ + BigFree(m_InBuffer); +} + +struct CBZip2Decompressor: public bz_stream +{ + int Init(int verbosity, int small) { return BZ2_bzDecompressInit(this, verbosity, small); } + int Decompress() { return BZ2_bzDecompress(this); } + int End() { return BZ2_bzDecompressEnd(this); } + UInt64 GetTotalIn() const { return (UInt64(total_in_hi32) << 32) + total_in_lo32; } + UInt64 GetTotalOut() const { return (UInt64(total_out_hi32) << 32) + total_out_lo32; } +}; + +class CBZip2DecompressorReleaser +{ + CBZip2Decompressor *m_Decompressor; +public: + CBZip2DecompressorReleaser(CBZip2Decompressor *decompressor): m_Decompressor(decompressor) {} + void Diable() { m_Decompressor = NULL; } + ~CBZip2DecompressorReleaser() { if (m_Decompressor != NULL) m_Decompressor->End(); } +}; + +STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + m_InSize = 0; + if (m_InBuffer == 0) + { + m_InBuffer = (Byte *)BigAlloc(kBufferSize * 2); + if (m_InBuffer == 0) + return E_OUTOFMEMORY; + } + Byte *outBuffer = m_InBuffer + kBufferSize; + + CBZip2Decompressor bzStream; + bzStream.bzalloc = NULL; + bzStream.bzfree = NULL; + bzStream.opaque = NULL; + + int result = bzStream.Init(0, 0); + switch(result) + { + case BZ_OK: + break; + case BZ_MEM_ERROR: + return E_OUTOFMEMORY; + default: + return E_FAIL; + } + CBZip2DecompressorReleaser releaser(&bzStream); + bzStream.avail_in = 0; + for (;;) + { + if (bzStream.avail_in == 0) + { + bzStream.next_in = (char *)m_InBuffer; + UInt32 processedSize; + RINOK(inStream->Read(m_InBuffer, kBufferSize, &processedSize)); + bzStream.avail_in = processedSize; + } + + bzStream.next_out = (char *)outBuffer; + bzStream.avail_out = kBufferSize; + result = bzStream.Decompress(); + UInt32 numBytesToWrite = kBufferSize - bzStream.avail_out; + if (numBytesToWrite > 0) + { + UInt32 processedSize; + RINOK(outStream->Write(outBuffer, numBytesToWrite, &processedSize)); + if (numBytesToWrite != processedSize) + return E_FAIL; + } + + if (result == BZ_STREAM_END) + break; + switch(result) + { + case BZ_DATA_ERROR: + case BZ_DATA_ERROR_MAGIC: + return S_FALSE; + case BZ_OK: + break; + case BZ_MEM_ERROR: + return E_OUTOFMEMORY; + default: + return E_FAIL; + } + if (progress != NULL) + { + UInt64 totalIn = bzStream.GetTotalIn(); + UInt64 totalOut = bzStream.GetTotalOut(); + RINOK(progress->SetRatioInfo(&totalIn, &totalOut)); + } + } + m_InSize = bzStream.GetTotalIn(); + return S_OK; +} + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(...) { return S_FALSE; } +} + +STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) +{ + if (value == NULL) + return E_INVALIDARG; + *value = m_InSize; + return S_OK; +} + +}} diff --git a/CPP/7zip/Compress/BZip2Original/BZip2Decoder.h b/CPP/7zip/Compress/BZip2Original/BZip2Decoder.h new file mode 100755 index 00000000..e41f730f --- /dev/null +++ b/CPP/7zip/Compress/BZip2Original/BZip2Decoder.h @@ -0,0 +1,38 @@ +// Compress/BZip2/Decoder.h + +#ifndef __COMPRESS_BZIP2_DECODER_H +#define __COMPRESS_BZIP2_DECODER_H + +#include "../../ICoder.h" +#include "../../../Common/MyCom.h" + +namespace NCompress { +namespace NBZip2 { + +class CDecoder : + public ICompressCoder, + public ICompressGetInStreamProcessedSize, + public CMyUnknownImp +{ + Byte *m_InBuffer; + UInt64 m_InSize; +public: + CDecoder(): m_InBuffer(0), m_InSize(0) {}; + ~CDecoder(); + + MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize) + + STDMETHOD(CodeReal)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); +}; + +}} + +#endif diff --git a/CPP/7zip/Compress/BZip2Original/BZip2Encoder.cpp b/CPP/7zip/Compress/BZip2Original/BZip2Encoder.cpp new file mode 100755 index 00000000..bcd7dec0 --- /dev/null +++ b/CPP/7zip/Compress/BZip2Original/BZip2Encoder.cpp @@ -0,0 +1,120 @@ +// BZip2Encoder.cpp + +#include "StdAfx.h" + +#include "BZip2Encoder.h" + +#include "../../../Common/Alloc.h" +#include "Original/bzlib.h" + +namespace NCompress { +namespace NBZip2 { + +static const UInt32 kBufferSize = (1 << 20); + +CEncoder::~CEncoder() +{ + BigFree(m_InBuffer); +} + +struct CBZip2Compressor: public bz_stream +{ + int Init(int blockSize100k, int verbosity, int small) + { return BZ2_bzCompressInit(this, blockSize100k, verbosity, small); } + int Compress(int action ) { return BZ2_bzCompress(this, action ); } + int End() { return BZ2_bzCompressEnd(this); } + UInt64 GetTotalIn() const { return (UInt64(total_in_hi32) << 32) + total_in_lo32; } + UInt64 GetTotalOut() const { return (UInt64(total_out_hi32) << 32) + total_out_lo32; } +}; + +class CBZip2CompressorReleaser +{ + CBZip2Compressor *m_Compressor; +public: + CBZip2CompressorReleaser(CBZip2Compressor *compressor): m_Compressor(compressor) {} + void Disable() { m_Compressor = NULL; } + ~CBZip2CompressorReleaser() { if (m_Compressor != NULL) m_Compressor->End(); } +}; + + +STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + if (m_InBuffer == 0) + { + m_InBuffer = (Byte *)BigAlloc(kBufferSize * 2); + if (m_InBuffer == 0) + return E_OUTOFMEMORY; + } + Byte *outBuffer = m_InBuffer + kBufferSize; + + CBZip2Compressor bzStream; + bzStream.bzalloc = NULL; + bzStream.bzfree = NULL; + bzStream.opaque = NULL; + + int result = bzStream.Init(9, 0, 0); + switch(result) + { + case BZ_OK: + break; + case BZ_MEM_ERROR: + return E_OUTOFMEMORY; + default: + return E_FAIL; + } + CBZip2CompressorReleaser releaser(&bzStream); + bzStream.avail_in = 0; + for (;;) + { + if (bzStream.avail_in == 0) + { + bzStream.next_in = (char *)m_InBuffer; + UInt32 processedSize; + RINOK(inStream->Read(m_InBuffer, kBufferSize, &processedSize)); + bzStream.avail_in = processedSize; + } + + bzStream.next_out = (char *)outBuffer; + bzStream.avail_out = kBufferSize; + bool askFinish = (bzStream.avail_in == 0); + result = bzStream.Compress(askFinish ? BZ_FINISH : BZ_RUN); + UInt32 numBytesToWrite = kBufferSize - bzStream.avail_out; + if (numBytesToWrite > 0) + { + UInt32 processedSize; + RINOK(outStream->Write(outBuffer, numBytesToWrite, &processedSize)); + if (numBytesToWrite != processedSize) + return E_FAIL; + } + + if (result == BZ_STREAM_END) + break; + switch(result) + { + case BZ_RUN_OK: + if (!askFinish) + break; + return E_FAIL; + case BZ_FINISH_OK: + if (askFinish) + break; + return E_FAIL; + case BZ_MEM_ERROR: + return E_OUTOFMEMORY; + default: + return E_FAIL; + } + if (progress != NULL) + { + UInt64 totalIn = bzStream.GetTotalIn(); + UInt64 totalOut = bzStream.GetTotalOut(); + RINOK(progress->SetRatioInfo(&totalIn, &totalOut)); + } + } + // result = bzStream.End(); + return S_OK; +} + +}} diff --git a/CPP/7zip/Compress/BZip2Original/BZip2Encoder.h b/CPP/7zip/Compress/BZip2Original/BZip2Encoder.h new file mode 100755 index 00000000..c451a08d --- /dev/null +++ b/CPP/7zip/Compress/BZip2Original/BZip2Encoder.h @@ -0,0 +1,30 @@ +// Compress/BZip2/Encoder.h + +#ifndef __COMPRESS_BZIP2_ENCODER_H +#define __COMPRESS_BZIP2_ENCODER_H + +#include "../../ICoder.h" +#include "../../../Common/MyCom.h" + +namespace NCompress { +namespace NBZip2 { + +class CEncoder : + public ICompressCoder, + public CMyUnknownImp +{ + Byte *m_InBuffer; +public: + CEncoder(): m_InBuffer(0) {}; + ~CEncoder(); + + MY_UNKNOWN_IMP + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); +}; + +}} + +#endif diff --git a/CPP/7zip/Compress/BZip2Original/BZip2Error.cpp b/CPP/7zip/Compress/BZip2Original/BZip2Error.cpp new file mode 100755 index 00000000..c8a912dc --- /dev/null +++ b/CPP/7zip/Compress/BZip2Original/BZip2Error.cpp @@ -0,0 +1,10 @@ +#include "StdAfx.h" + +#include "Original/bzlib.h" + +extern "C" + +void bz_internal_error (int errcode) +{ + throw "error"; +} \ No newline at end of file diff --git a/CPP/7zip/Compress/BZip2Original/DllExports.cpp b/CPP/7zip/Compress/BZip2Original/DllExports.cpp new file mode 100755 index 00000000..572d1fda --- /dev/null +++ b/CPP/7zip/Compress/BZip2Original/DllExports.cpp @@ -0,0 +1,86 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" + +#include "BZip2Encoder.h" +#include "BZip2Decoder.h" + +// {23170F69-40C1-278B-0402-020000000000} +DEFINE_GUID(CLSID_CCompressBZip2Decoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00); + +// {23170F69-40C1-278B-0402-020000000100} +DEFINE_GUID(CLSID_CCompressBZip2Encoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +{ + return TRUE; +} + +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + int correctInterface = (*iid == IID_ICompressCoder); + CMyComPtr coder; + if (*clsid == CLSID_CCompressBZip2Decoder) + { + if (!correctInterface) + return E_NOINTERFACE; + coder = (ICompressCoder *)new NCompress::NBZip2::CDecoder; + } + else if (*clsid == CLSID_CCompressBZip2Encoder) + { + if (!correctInterface) + return E_NOINTERFACE; + coder = (ICompressCoder *)new NCompress::NBZip2::CEncoder; + } + else + return CLASS_E_CLASSNOTAVAILABLE; + *outObject = coder.Detach(); + COM_TRY_END + return S_OK; +} + +STDAPI GetNumberOfMethods(UINT32 *numMethods) +{ + *numMethods = 1; + return S_OK; +} + +STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +{ + if (index != 0) + return E_INVALIDARG; + ::VariantClear((tagVARIANT *)value); + switch(propID) + { + case NMethodPropID::kID: + { + const char id[] = { 0x04, 0x02, 0x02 }; + if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NMethodPropID::kName: + if ((value->bstrVal = ::SysAllocString(L"BZip2")) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kDecoder: + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CCompressBZip2Decoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kEncoder: + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CCompressBZip2Encoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + return S_OK; +} diff --git a/CPP/7zip/Compress/BZip2Original/StdAfx.cpp b/CPP/7zip/Compress/BZip2Original/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Compress/BZip2Original/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Compress/BZip2Original/StdAfx.h b/CPP/7zip/Compress/BZip2Original/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Compress/BZip2Original/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Compress/Branch/ARM.cpp b/CPP/7zip/Compress/Branch/ARM.cpp new file mode 100755 index 00000000..0918cfb7 --- /dev/null +++ b/CPP/7zip/Compress/Branch/ARM.cpp @@ -0,0 +1,16 @@ +// ARM.cpp + +#include "StdAfx.h" +#include "ARM.h" + +#include "../../../../C/Compress/Branch/BranchARM.c" + +UInt32 CBC_ARM_Encoder::SubFilter(Byte *data, UInt32 size) +{ + return ::ARM_Convert(data, size, _bufferPos, 1); +} + +UInt32 CBC_ARM_Decoder::SubFilter(Byte *data, UInt32 size) +{ + return ::ARM_Convert(data, size, _bufferPos, 0); +} diff --git a/CPP/7zip/Compress/Branch/ARM.h b/CPP/7zip/Compress/Branch/ARM.h new file mode 100755 index 00000000..5561299b --- /dev/null +++ b/CPP/7zip/Compress/Branch/ARM.h @@ -0,0 +1,10 @@ +// ARM.h + +#ifndef __ARM_H +#define __ARM_H + +#include "BranchCoder.h" + +MyClassA(BC_ARM, 0x05, 1) + +#endif diff --git a/CPP/7zip/Compress/Branch/ARMThumb.cpp b/CPP/7zip/Compress/Branch/ARMThumb.cpp new file mode 100755 index 00000000..50189adb --- /dev/null +++ b/CPP/7zip/Compress/Branch/ARMThumb.cpp @@ -0,0 +1,16 @@ +// ARMThumb.cpp + +#include "StdAfx.h" +#include "ARMThumb.h" + +#include "../../../../C/Compress/Branch/BranchARMThumb.c" + +UInt32 CBC_ARMThumb_Encoder::SubFilter(Byte *data, UInt32 size) +{ + return ::ARMThumb_Convert(data, size, _bufferPos, 1); +} + +UInt32 CBC_ARMThumb_Decoder::SubFilter(Byte *data, UInt32 size) +{ + return ::ARMThumb_Convert(data, size, _bufferPos, 0); +} diff --git a/CPP/7zip/Compress/Branch/ARMThumb.h b/CPP/7zip/Compress/Branch/ARMThumb.h new file mode 100755 index 00000000..601e40bf --- /dev/null +++ b/CPP/7zip/Compress/Branch/ARMThumb.h @@ -0,0 +1,10 @@ +// ARMThumb.h + +#ifndef __ARMTHUMB_H +#define __ARMTHUMB_H + +#include "BranchCoder.h" + +MyClassA(BC_ARMThumb, 0x07, 1) + +#endif diff --git a/CPP/7zip/Compress/Branch/Branch.dsp b/CPP/7zip/Compress/Branch/Branch.dsp new file mode 100755 index 00000000..220cb8ab --- /dev/null +++ b/CPP/7zip/Compress/Branch/Branch.dsp @@ -0,0 +1,298 @@ +# Microsoft Developer Studio Project File - Name="Branch" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Branch - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Branch.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Branch.mak" CFG="Branch - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Branch - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Branch - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Branch - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BRANCH_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O2 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BRANCH_EXPORTS" /FD /c +# SUBTRACT CPP /YX /Yc /Yu +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\Branch.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Branch - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BRANCH_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BRANCH_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\Branch.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Branch - Win32 Release" +# Name "Branch - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Codec.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Methods" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ARM.cpp + +!IF "$(CFG)" == "Branch - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Branch - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\ARM.h +# End Source File +# Begin Source File + +SOURCE=.\ARMThumb.cpp + +!IF "$(CFG)" == "Branch - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Branch - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\ARMThumb.h +# End Source File +# Begin Source File + +SOURCE=.\BranchCoder.cpp +# End Source File +# Begin Source File + +SOURCE=.\BranchCoder.h +# End Source File +# Begin Source File + +SOURCE=.\BranchTypes.h +# End Source File +# Begin Source File + +SOURCE=.\BranchX86.h +# End Source File +# Begin Source File + +SOURCE=.\IA64.cpp + +!IF "$(CFG)" == "Branch - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Branch - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\IA64.h +# End Source File +# Begin Source File + +SOURCE=.\PPC.cpp + +!IF "$(CFG)" == "Branch - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Branch - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\PPC.h +# End Source File +# Begin Source File + +SOURCE=.\SPARC.cpp +# End Source File +# Begin Source File + +SOURCE=.\SPARC.h +# End Source File +# Begin Source File + +SOURCE=.\x86.cpp + +!IF "$(CFG)" == "Branch - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Branch - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\x86.h +# End Source File +# Begin Source File + +SOURCE=.\x86_2.cpp + +!IF "$(CFG)" == "Branch - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Branch - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\x86_2.h +# End Source File +# End Group +# Begin Group "Stream" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# End Group +# Begin Group "RangeCoder" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\RangeCoder\RangeCoder.h +# End Source File +# Begin Source File + +SOURCE=..\RangeCoder\RangeCoderBit.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# End Group +# End Target +# End Project diff --git a/CPP/7zip/Compress/Branch/Branch.dsw b/CPP/7zip/Compress/Branch/Branch.dsw new file mode 100755 index 00000000..841c85a3 --- /dev/null +++ b/CPP/7zip/Compress/Branch/Branch.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Branch"=.\Branch.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Compress/Branch/BranchCoder.cpp b/CPP/7zip/Compress/Branch/BranchCoder.cpp new file mode 100755 index 00000000..8d25f0d5 --- /dev/null +++ b/CPP/7zip/Compress/Branch/BranchCoder.cpp @@ -0,0 +1,18 @@ +// BranchCoder.cpp + +#include "StdAfx.h" +#include "BranchCoder.h" + +STDMETHODIMP CBranchConverter::Init() +{ + _bufferPos = 0; + SubInit(); + return S_OK; +} + +STDMETHODIMP_(UInt32) CBranchConverter::Filter(Byte *data, UInt32 size) +{ + UInt32 processedSize = SubFilter(data, size); + _bufferPos += processedSize; + return processedSize; +} diff --git a/CPP/7zip/Compress/Branch/BranchCoder.h b/CPP/7zip/Compress/Branch/BranchCoder.h new file mode 100755 index 00000000..4b53b6cb --- /dev/null +++ b/CPP/7zip/Compress/Branch/BranchCoder.h @@ -0,0 +1,54 @@ +// BranchCoder.h + +#ifndef __BRANCH_CODER_H +#define __BRANCH_CODER_H + +#include "Common/MyCom.h" +#include "Common/Types.h" +#include "Common/Alloc.h" + +#include "../../ICoder.h" + +class CBranchConverter: + public ICompressFilter, + public CMyUnknownImp +{ +protected: + UInt32 _bufferPos; + virtual void SubInit() {} + virtual UInt32 SubFilter(Byte *data, UInt32 size) = 0; +public: + MY_UNKNOWN_IMP; + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); +}; + +#define MyClassEncoderA(Name) class C ## Name: public CBranchConverter \ + { public: UInt32 SubFilter(Byte *data, UInt32 size); }; + +#define MyClassDecoderA(Name) class C ## Name: public CBranchConverter \ + { public: UInt32 SubFilter(Byte *data, UInt32 size); }; + +#define MyClassEncoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \ + { public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT}; + +#define MyClassDecoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \ + { public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT}; + +#define MyClass2b(Name, id, subId, encodingId) \ +DEFINE_GUID(CLSID_CCompressConvert ## Name, \ +0x23170F69, 0x40C1, 0x278B, 0x03, 0x03, id, subId, 0x00, 0x00, encodingId, 0x00); + +#define MyClassA(Name, id, subId) \ +MyClass2b(Name ## _Encoder, id, subId, 0x01) \ +MyClassEncoderA(Name ## _Encoder) \ +MyClass2b(Name ## _Decoder, id, subId, 0x00) \ +MyClassDecoderA(Name ## _Decoder) + +#define MyClassB(Name, id, subId, ADD_ITEMS, ADD_INIT) \ +MyClass2b(Name ## _Encoder, id, subId, 0x01) \ +MyClassEncoderB(Name ## _Encoder, ADD_ITEMS, ADD_INIT) \ +MyClass2b(Name ## _Decoder, id, subId, 0x00) \ +MyClassDecoderB(Name ## _Decoder, ADD_ITEMS, ADD_INIT) + +#endif diff --git a/CPP/7zip/Compress/Branch/DllExports.cpp b/CPP/7zip/Compress/Branch/DllExports.cpp new file mode 100755 index 00000000..e7928f75 --- /dev/null +++ b/CPP/7zip/Compress/Branch/DllExports.cpp @@ -0,0 +1,152 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" + +#include "x86.h" +#include "PPC.h" +#include "IA64.h" +#include "ARM.h" +#include "ARMThumb.h" +#include "x86_2.h" +#include "SPARC.h" + +#define MY_CreateClass0(n) \ +if (*clsid == CLSID_CCompressConvert ## n ## _Encoder) { \ + if (!correctInterface) \ + return E_NOINTERFACE; \ + filter = (ICompressFilter *)new C ## n ## _Encoder(); \ + } else if (*clsid == CLSID_CCompressConvert ## n ## _Decoder){ \ + if (!correctInterface) \ + return E_NOINTERFACE; \ + filter = (ICompressFilter *)new C ## n ## _Decoder(); \ + } + +extern "C" +BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /*lpReserved*/) +{ + return TRUE; +} + +STDAPI CreateObject( + const GUID *clsid, + const GUID *interfaceID, + void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + int correctInterface = (*interfaceID == IID_ICompressFilter); + CMyComPtr filter; + MY_CreateClass0(BCJ_x86) + else + MY_CreateClass0(BC_ARM) + else + MY_CreateClass0(BC_PPC_B) + else + MY_CreateClass0(BC_IA64) + else + MY_CreateClass0(BC_ARMThumb) + else + MY_CreateClass0(BC_SPARC) + else + { + CMyComPtr coder2; + correctInterface = (*interfaceID == IID_ICompressCoder2); + if (*clsid == CLSID_CCompressConvertBCJ2_x86_Encoder) + { + if (!correctInterface) + return E_NOINTERFACE; + coder2 = (ICompressCoder2 *)new CBCJ2_x86_Encoder(); + } + else if (*clsid == CLSID_CCompressConvertBCJ2_x86_Decoder) + { + if (!correctInterface) + return E_NOINTERFACE; + coder2 = (ICompressCoder2 *)new CBCJ2_x86_Decoder(); + } + else + return CLASS_E_CLASSNOTAVAILABLE; + *outObject = coder2.Detach(); + return S_OK; + } + *outObject = filter.Detach(); + return S_OK; + + COM_TRY_END +} + +struct CBranchMethodItem +{ + char ID[4]; + const wchar_t *UserName; + const GUID *Decoder; + const GUID *Encoder; + UINT32 NumInStreams; +}; + +#define METHOD_ITEM(Name, id, subId, UserName, NumInStreams) \ + { { 0x03, 0x03, id, subId }, UserName, \ + &CLSID_CCompressConvert ## Name ## _Decoder, \ + &CLSID_CCompressConvert ## Name ## _Encoder, NumInStreams } + + +static CBranchMethodItem g_Methods[] = +{ + METHOD_ITEM(BCJ_x86, 0x01, 0x03, L"BCJ", 1), + METHOD_ITEM(BCJ2_x86, 0x01, 0x1B, L"BCJ2", 4), + METHOD_ITEM(BC_PPC_B, 0x02, 0x05, L"BC_PPC_B", 1), + // METHOD_ITEM(BC_Alpha, 0x03, 1, L"BC_Alpha", 1), + METHOD_ITEM(BC_IA64, 0x04, 1, L"BC_IA64", 1), + METHOD_ITEM(BC_ARM, 0x05, 1, L"BC_ARM", 1), + // METHOD_ITEM(BC_M68_B, 0x06, 5, L"BC_M68_B", 1), + METHOD_ITEM(BC_ARMThumb, 0x07, 1, L"BC_ARMThumb", 1), + METHOD_ITEM(BC_SPARC, 0x08, 0x05, L"BC_SPARC", 1) +}; + +STDAPI GetNumberOfMethods(UINT32 *numMethods) +{ + *numMethods = sizeof(g_Methods) / sizeof(g_Methods[1]); + return S_OK; +} + +STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +{ + if (index > sizeof(g_Methods) / sizeof(g_Methods[1])) + return E_INVALIDARG; + VariantClear((tagVARIANT *)value); + const CBranchMethodItem &method = g_Methods[index]; + switch(propID) + { + case NMethodPropID::kID: + if ((value->bstrVal = ::SysAllocStringByteLen(method.ID, + sizeof(method.ID))) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kName: + if ((value->bstrVal = ::SysAllocString(method.UserName)) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kDecoder: + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)method.Decoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kEncoder: + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)method.Encoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kInStreams: + { + if (method.NumInStreams != 1) + { + value->vt = VT_UI4; + value->ulVal = method.NumInStreams; + } + return S_OK; + } + } + return S_OK; +} diff --git a/CPP/7zip/Compress/Branch/IA64.cpp b/CPP/7zip/Compress/Branch/IA64.cpp new file mode 100755 index 00000000..4d57916c --- /dev/null +++ b/CPP/7zip/Compress/Branch/IA64.cpp @@ -0,0 +1,16 @@ +// IA64.cpp + +#include "StdAfx.h" +#include "IA64.h" + +#include "../../../../C/Compress/Branch/BranchIA64.c" + +UInt32 CBC_IA64_Encoder::SubFilter(Byte *data, UInt32 size) +{ + return ::IA64_Convert(data, size, _bufferPos, 1); +} + +UInt32 CBC_IA64_Decoder::SubFilter(Byte *data, UInt32 size) +{ + return ::IA64_Convert(data, size, _bufferPos, 0); +} diff --git a/CPP/7zip/Compress/Branch/IA64.h b/CPP/7zip/Compress/Branch/IA64.h new file mode 100755 index 00000000..7fe715ed --- /dev/null +++ b/CPP/7zip/Compress/Branch/IA64.h @@ -0,0 +1,10 @@ +// IA64.h + +#ifndef __IA64_H +#define __IA64_H + +#include "BranchCoder.h" + +MyClassA(BC_IA64, 0x04, 1) + +#endif diff --git a/CPP/7zip/Compress/Branch/PPC.cpp b/CPP/7zip/Compress/Branch/PPC.cpp new file mode 100755 index 00000000..08c436e1 --- /dev/null +++ b/CPP/7zip/Compress/Branch/PPC.cpp @@ -0,0 +1,17 @@ +// PPC.cpp + +#include "StdAfx.h" +#include "PPC.h" + +#include "Windows/Defs.h" +#include "../../../../C/Compress/Branch/BranchPPC.c" + +UInt32 CBC_PPC_B_Encoder::SubFilter(Byte *data, UInt32 size) +{ + return ::PPC_B_Convert(data, size, _bufferPos, 1); +} + +UInt32 CBC_PPC_B_Decoder::SubFilter(Byte *data, UInt32 size) +{ + return ::PPC_B_Convert(data, size, _bufferPos, 0); +} diff --git a/CPP/7zip/Compress/Branch/PPC.h b/CPP/7zip/Compress/Branch/PPC.h new file mode 100755 index 00000000..a0e33444 --- /dev/null +++ b/CPP/7zip/Compress/Branch/PPC.h @@ -0,0 +1,10 @@ +// PPC.h + +#ifndef __PPC_H +#define __PPC_H + +#include "BranchCoder.h" + +MyClassA(BC_PPC_B, 0x02, 5) + +#endif diff --git a/CPP/7zip/Compress/Branch/SPARC.cpp b/CPP/7zip/Compress/Branch/SPARC.cpp new file mode 100755 index 00000000..7a218fe4 --- /dev/null +++ b/CPP/7zip/Compress/Branch/SPARC.cpp @@ -0,0 +1,17 @@ +// SPARC.cpp + +#include "StdAfx.h" +#include "SPARC.h" + +#include "Windows/Defs.h" +#include "../../../../C/Compress/Branch/BranchSPARC.c" + +UInt32 CBC_SPARC_Encoder::SubFilter(Byte *data, UInt32 size) +{ + return ::SPARC_Convert(data, size, _bufferPos, 1); +} + +UInt32 CBC_SPARC_Decoder::SubFilter(Byte *data, UInt32 size) +{ + return ::SPARC_Convert(data, size, _bufferPos, 0); +} diff --git a/CPP/7zip/Compress/Branch/SPARC.h b/CPP/7zip/Compress/Branch/SPARC.h new file mode 100755 index 00000000..e0a682ef --- /dev/null +++ b/CPP/7zip/Compress/Branch/SPARC.h @@ -0,0 +1,10 @@ +// SPARC.h + +#ifndef __SPARC_H +#define __SPARC_H + +#include "BranchCoder.h" + +MyClassA(BC_SPARC, 0x08, 5) + +#endif diff --git a/CPP/7zip/Compress/Branch/StdAfx.cpp b/CPP/7zip/Compress/Branch/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Compress/Branch/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Compress/Branch/StdAfx.h b/CPP/7zip/Compress/Branch/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Compress/Branch/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Compress/Branch/makefile b/CPP/7zip/Compress/Branch/makefile new file mode 100755 index 00000000..6857d39f --- /dev/null +++ b/CPP/7zip/Compress/Branch/makefile @@ -0,0 +1,48 @@ +PROG = Branch.dll +DEF_FILE = ../Codec.def +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib + +BRANCH_OBJS = \ + $O\DllExports.obj \ + +BRANCH_OPT_OBJS = \ + $O\ARM.obj \ + $O\ARMThumb.obj \ + $O\BranchCoder.obj \ + $O\IA64.obj \ + $O\PPC.obj \ + $O\SPARC.obj \ + $O\x86.obj \ + $O\x86_2.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + +7ZIP_COMMON_OBJS = \ + $O\InBuffer.obj \ + $O\OutBuffer.obj \ + + +OBJS = \ + $O\StdAfx.obj \ + $(BRANCH_OBJS) \ + $(BRANCH_OPT_OBJS) \ + $(COMMON_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $O\RangeCoderBit.obj \ + $O\resource.res + + +!include "../../../Build.mak" + +$(BRANCH_OBJS): $(*B).cpp + $(COMPL) +$(BRANCH_OPT_OBJS): $(*B).cpp + $(COMPL_O2) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$O\RangeCoderBit.obj: ../RangeCoder/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/Compress/Branch/resource.rc b/CPP/7zip/Compress/Branch/resource.rc new file mode 100755 index 00000000..5476d4fa --- /dev/null +++ b/CPP/7zip/Compress/Branch/resource.rc @@ -0,0 +1,3 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("Branch Filter", "Branch") diff --git a/CPP/7zip/Compress/Branch/x86.cpp b/CPP/7zip/Compress/Branch/x86.cpp new file mode 100755 index 00000000..60640d29 --- /dev/null +++ b/CPP/7zip/Compress/Branch/x86.cpp @@ -0,0 +1,18 @@ +// x86.cpp + +#include "StdAfx.h" +#include "x86.h" + +#include "Windows/Defs.h" + +#include "../../../../C/Compress/Branch/BranchX86.c" + +UInt32 CBCJ_x86_Encoder::SubFilter(Byte *data, UInt32 size) +{ + return ::x86_Convert(data, size, _bufferPos, &_prevMask, &_prevPos, 1); +} + +UInt32 CBCJ_x86_Decoder::SubFilter(Byte *data, UInt32 size) +{ + return ::x86_Convert(data, size, _bufferPos, &_prevMask, &_prevPos, 0); +} diff --git a/CPP/7zip/Compress/Branch/x86.h b/CPP/7zip/Compress/Branch/x86.h new file mode 100755 index 00000000..f795e778 --- /dev/null +++ b/CPP/7zip/Compress/Branch/x86.h @@ -0,0 +1,19 @@ +// x86.h + +#ifndef __X86_H +#define __X86_H + +#include "BranchCoder.h" +#include "../../../../C/Compress/Branch/BranchX86.h" + +struct CBranch86 +{ + UInt32 _prevMask; + UInt32 _prevPos; + void x86Init() { x86_Convert_Init(_prevMask, _prevPos); } +}; + +MyClassB(BCJ_x86, 0x01, 3, CBranch86 , + virtual void SubInit() { x86Init(); }) + +#endif diff --git a/CPP/7zip/Compress/Branch/x86_2.cpp b/CPP/7zip/Compress/Branch/x86_2.cpp new file mode 100755 index 00000000..ca37ab83 --- /dev/null +++ b/CPP/7zip/Compress/Branch/x86_2.cpp @@ -0,0 +1,412 @@ +// x86_2.cpp + +#include "StdAfx.h" +#include "x86_2.h" + +#include "../../../Common/Alloc.h" + +static const int kBufferSize = 1 << 17; + +inline bool IsJcc(Byte b0, Byte b1) +{ + return (b0 == 0x0F && (b1 & 0xF0) == 0x80); +} + +#ifndef EXTRACT_ONLY + +static bool inline Test86MSByte(Byte b) +{ + return (b == 0 || b == 0xFF); +} + +bool CBCJ2_x86_Encoder::Create() +{ + if (!_mainStream.Create(1 << 16)) + return false; + if (!_callStream.Create(1 << 20)) + return false; + if (!_jumpStream.Create(1 << 20)) + return false; + if (!_rangeEncoder.Create(1 << 20)) + return false; + if (_buffer == 0) + { + _buffer = (Byte *)MidAlloc(kBufferSize); + if (_buffer == 0) + return false; + } + return true; +} + +CBCJ2_x86_Encoder::~CBCJ2_x86_Encoder() +{ + ::MidFree(_buffer); +} + +HRESULT CBCJ2_x86_Encoder::Flush() +{ + RINOK(_mainStream.Flush()); + RINOK(_callStream.Flush()); + RINOK(_jumpStream.Flush()); + _rangeEncoder.FlushData(); + return _rangeEncoder.FlushStream(); +} + +const UInt32 kDefaultLimit = (1 << 24); + +HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 ** /* outSizes */, + UInt32 numOutStreams, + ICompressProgressInfo *progress) +{ + if (numInStreams != 1 || numOutStreams != 4) + return E_INVALIDARG; + + if (!Create()) + return E_OUTOFMEMORY; + + bool sizeIsDefined = false; + UInt64 inSize = 0; + if (inSizes != NULL) + if (inSizes[0] != NULL) + { + inSize = *inSizes[0]; + if (inSize <= kDefaultLimit) + sizeIsDefined = true; + } + + ISequentialInStream *inStream = inStreams[0]; + + _mainStream.SetStream(outStreams[0]); + _mainStream.Init(); + _callStream.SetStream(outStreams[1]); + _callStream.Init(); + _jumpStream.SetStream(outStreams[2]); + _jumpStream.Init(); + _rangeEncoder.SetStream(outStreams[3]); + _rangeEncoder.Init(); + for (int i = 0; i < 256; i++) + _statusE8Encoder[i].Init(); + _statusE9Encoder.Init(); + _statusJccEncoder.Init(); + CCoderReleaser releaser(this); + + CMyComPtr getSubStreamSize; + { + inStream->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize); + } + + UInt32 nowPos = 0; + UInt64 nowPos64 = 0; + UInt32 bufferPos = 0; + + Byte prevByte = 0; + + UInt64 subStreamIndex = 0; + UInt64 subStreamStartPos = 0; + UInt64 subStreamEndPos = 0; + + for (;;) + { + UInt32 processedSize = 0; + for (;;) + { + UInt32 size = kBufferSize - (bufferPos + processedSize); + UInt32 processedSizeLoc; + if (size == 0) + break; + RINOK(inStream->Read(_buffer + bufferPos + processedSize, size, &processedSizeLoc)); + if (processedSizeLoc == 0) + break; + processedSize += processedSizeLoc; + } + UInt32 endPos = bufferPos + processedSize; + + if (endPos < 5) + { + // change it + for (bufferPos = 0; bufferPos < endPos; bufferPos++) + { + Byte b = _buffer[bufferPos]; + _mainStream.WriteByte(b); + if (b == 0xE8) + _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0); + else if (b == 0xE9) + _statusE9Encoder.Encode(&_rangeEncoder, 0); + else if (IsJcc(prevByte, b)) + _statusJccEncoder.Encode(&_rangeEncoder, 0); + prevByte = b; + } + return Flush(); + } + + bufferPos = 0; + + UInt32 limit = endPos - 5; + while(bufferPos <= limit) + { + Byte b = _buffer[bufferPos]; + _mainStream.WriteByte(b); + if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b)) + { + bufferPos++; + prevByte = b; + continue; + } + Byte nextByte = _buffer[bufferPos + 4]; + UInt32 src = + (UInt32(nextByte) << 24) | + (UInt32(_buffer[bufferPos + 3]) << 16) | + (UInt32(_buffer[bufferPos + 2]) << 8) | + (_buffer[bufferPos + 1]); + UInt32 dest = (nowPos + bufferPos + 5) + src; + // if (Test86MSByte(nextByte)) + bool convert; + if (getSubStreamSize != NULL) + { + UInt64 currentPos = (nowPos64 + bufferPos); + while (subStreamEndPos < currentPos) + { + UInt64 subStreamSize; + HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize); + if (result == S_OK) + { + subStreamStartPos = subStreamEndPos; + subStreamEndPos += subStreamSize; + subStreamIndex++; + } + else if (result == S_FALSE || result == E_NOTIMPL) + { + getSubStreamSize.Release(); + subStreamStartPos = 0; + subStreamEndPos = subStreamStartPos - 1; + } + else + return result; + } + if (getSubStreamSize == NULL) + { + if (sizeIsDefined) + convert = (dest < inSize); + else + convert = Test86MSByte(nextByte); + } + else if (subStreamEndPos - subStreamStartPos > kDefaultLimit) + convert = Test86MSByte(nextByte); + else + { + UInt64 dest64 = (currentPos + 5) + Int64(Int32(src)); + convert = (dest64 >= subStreamStartPos && dest64 < subStreamEndPos); + } + } + else if (sizeIsDefined) + convert = (dest < inSize); + else + convert = Test86MSByte(nextByte); + if (convert) + { + if (b == 0xE8) + _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 1); + else if (b == 0xE9) + _statusE9Encoder.Encode(&_rangeEncoder, 1); + else + _statusJccEncoder.Encode(&_rangeEncoder, 1); + + bufferPos += 5; + if (b == 0xE8) + { + _callStream.WriteByte((Byte)(dest >> 24)); + _callStream.WriteByte((Byte)(dest >> 16)); + _callStream.WriteByte((Byte)(dest >> 8)); + _callStream.WriteByte((Byte)(dest)); + } + else + { + _jumpStream.WriteByte((Byte)(dest >> 24)); + _jumpStream.WriteByte((Byte)(dest >> 16)); + _jumpStream.WriteByte((Byte)(dest >> 8)); + _jumpStream.WriteByte((Byte)(dest)); + } + prevByte = nextByte; + } + else + { + if (b == 0xE8) + _statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0); + else if (b == 0xE9) + _statusE9Encoder.Encode(&_rangeEncoder, 0); + else + _statusJccEncoder.Encode(&_rangeEncoder, 0); + bufferPos++; + prevByte = b; + } + } + nowPos += bufferPos; + nowPos64 += bufferPos; + + if (progress != NULL) + { + RINOK(progress->SetRatioInfo(&nowPos64, NULL)); + } + + UInt32 i = 0; + while(bufferPos < endPos) + _buffer[i++] = _buffer[bufferPos++]; + bufferPos = i; + } +} + +STDMETHODIMP CBCJ2_x86_Encoder::Code(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress) +{ + try + { + return CodeReal(inStreams, inSizes, numInStreams, + outStreams, outSizes,numOutStreams, progress); + } + catch(const COutBufferException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +#endif + +HRESULT CBCJ2_x86_Decoder::CodeReal(ISequentialInStream **inStreams, + const UInt64 ** /* inSizes */, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 ** /* outSizes */, + UInt32 numOutStreams, + ICompressProgressInfo *progress) +{ + if (numInStreams != 4 || numOutStreams != 1) + return E_INVALIDARG; + + if (!_mainInStream.Create(1 << 16)) + return E_OUTOFMEMORY; + if (!_callStream.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!_jumpStream.Create(1 << 16)) + return E_OUTOFMEMORY; + if (!_rangeDecoder.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!_outStream.Create(1 << 16)) + return E_OUTOFMEMORY; + + _mainInStream.SetStream(inStreams[0]); + _callStream.SetStream(inStreams[1]); + _jumpStream.SetStream(inStreams[2]); + _rangeDecoder.SetStream(inStreams[3]); + _outStream.SetStream(outStreams[0]); + + _mainInStream.Init(); + _callStream.Init(); + _jumpStream.Init(); + _rangeDecoder.Init(); + _outStream.Init(); + + for (int i = 0; i < 256; i++) + _statusE8Decoder[i].Init(); + _statusE9Decoder.Init(); + _statusJccDecoder.Init(); + + CCoderReleaser releaser(this); + + Byte prevByte = 0; + UInt32 processedBytes = 0; + for (;;) + { + if (processedBytes > (1 << 20) && progress != NULL) + { + UInt64 nowPos64 = _outStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(NULL, &nowPos64)); + processedBytes = 0; + } + processedBytes++; + Byte b; + if (!_mainInStream.ReadByte(b)) + return Flush(); + _outStream.WriteByte(b); + if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b)) + { + prevByte = b; + continue; + } + bool status; + if (b == 0xE8) + status = (_statusE8Decoder[prevByte].Decode(&_rangeDecoder) == 1); + else if (b == 0xE9) + status = (_statusE9Decoder.Decode(&_rangeDecoder) == 1); + else + status = (_statusJccDecoder.Decode(&_rangeDecoder) == 1); + if (status) + { + UInt32 src; + if (b == 0xE8) + { + Byte b0; + if(!_callStream.ReadByte(b0)) + return S_FALSE; + src = ((UInt32)b0) << 24; + if(!_callStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0) << 16; + if(!_callStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0) << 8; + if(!_callStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0); + } + else + { + Byte b0; + if(!_jumpStream.ReadByte(b0)) + return S_FALSE; + src = ((UInt32)b0) << 24; + if(!_jumpStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0) << 16; + if(!_jumpStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0) << 8; + if(!_jumpStream.ReadByte(b0)) + return S_FALSE; + src |= ((UInt32)b0); + } + UInt32 dest = src - (UInt32(_outStream.GetProcessedSize()) + 4) ; + _outStream.WriteByte((Byte)(dest)); + _outStream.WriteByte((Byte)(dest >> 8)); + _outStream.WriteByte((Byte)(dest >> 16)); + _outStream.WriteByte((Byte)(dest >> 24)); + prevByte = (Byte)(dest >> 24); + processedBytes += 4; + } + else + prevByte = b; + } +} + +STDMETHODIMP CBCJ2_x86_Decoder::Code(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress) +{ + try + { + return CodeReal(inStreams, inSizes, numInStreams, + outStreams, outSizes,numOutStreams, progress); + } + catch(const COutBufferException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} diff --git a/CPP/7zip/Compress/Branch/x86_2.h b/CPP/7zip/Compress/Branch/x86_2.h new file mode 100755 index 00000000..3d34eb8d --- /dev/null +++ b/CPP/7zip/Compress/Branch/x86_2.h @@ -0,0 +1,133 @@ +// x86_2.h + +#ifndef __BRANCH_X86_2_H +#define __BRANCH_X86_2_H + +#include "../../../Common/MyCom.h" +#include "../RangeCoder/RangeCoderBit.h" +#include "../../ICoder.h" + +// {23170F69-40C1-278B-0303-010100000100} +#define MyClass2_a(Name, id, subId, encodingId) \ +DEFINE_GUID(CLSID_CCompressConvert ## Name, \ +0x23170F69, 0x40C1, 0x278B, 0x03, 0x03, id, subId, 0x00, 0x00, encodingId, 0x00); + +#define MyClass_a(Name, id, subId) \ +MyClass2_a(Name ## _Encoder, id, subId, 0x01) \ +MyClass2_a(Name ## _Decoder, id, subId, 0x00) + +MyClass_a(BCJ2_x86, 0x01, 0x1B) + +const int kNumMoveBits = 5; + +#ifndef EXTRACT_ONLY + +class CBCJ2_x86_Encoder: + public ICompressCoder2, + public CMyUnknownImp +{ + Byte *_buffer; +public: + CBCJ2_x86_Encoder(): _buffer(0) {}; + ~CBCJ2_x86_Encoder(); + bool Create(); + + COutBuffer _mainStream; + COutBuffer _callStream; + COutBuffer _jumpStream; + NCompress::NRangeCoder::CEncoder _rangeEncoder; + NCompress::NRangeCoder::CBitEncoder _statusE8Encoder[256]; + NCompress::NRangeCoder::CBitEncoder _statusE9Encoder; + NCompress::NRangeCoder::CBitEncoder _statusJccEncoder; + + HRESULT Flush(); + void ReleaseStreams() + { + _mainStream.ReleaseStream(); + _callStream.ReleaseStream(); + _jumpStream.ReleaseStream(); + _rangeEncoder.ReleaseStream(); + } + + class CCoderReleaser + { + CBCJ2_x86_Encoder *_coder; + public: + CCoderReleaser(CBCJ2_x86_Encoder *coder): _coder(coder) {} + ~CCoderReleaser() { _coder->ReleaseStreams(); } + }; + +public: + + MY_UNKNOWN_IMP + + HRESULT CodeReal(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress); + STDMETHOD(Code)(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress); +}; + +#endif + +class CBCJ2_x86_Decoder: + public ICompressCoder2, + public CMyUnknownImp +{ +public: + CInBuffer _mainInStream; + CInBuffer _callStream; + CInBuffer _jumpStream; + NCompress::NRangeCoder::CDecoder _rangeDecoder; + NCompress::NRangeCoder::CBitDecoder _statusE8Decoder[256]; + NCompress::NRangeCoder::CBitDecoder _statusE9Decoder; + NCompress::NRangeCoder::CBitDecoder _statusJccDecoder; + + COutBuffer _outStream; + + void ReleaseStreams() + { + _mainInStream.ReleaseStream(); + _callStream.ReleaseStream(); + _jumpStream.ReleaseStream(); + _rangeDecoder.ReleaseStream(); + _outStream.ReleaseStream(); + } + + HRESULT Flush() { return _outStream.Flush(); } + class CCoderReleaser + { + CBCJ2_x86_Decoder *_coder; + public: + CCoderReleaser(CBCJ2_x86_Decoder *coder): _coder(coder) {} + ~CCoderReleaser() { _coder->ReleaseStreams(); } + }; + +public: + MY_UNKNOWN_IMP + HRESULT CodeReal(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress); + STDMETHOD(Code)(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress); +}; + +#endif diff --git a/CPP/7zip/Compress/ByteSwap/ByteSwap.cpp b/CPP/7zip/Compress/ByteSwap/ByteSwap.cpp new file mode 100755 index 00000000..3f252f2c --- /dev/null +++ b/CPP/7zip/Compress/ByteSwap/ByteSwap.cpp @@ -0,0 +1,38 @@ +// ByteSwap.cpp + +#include "StdAfx.h" + +#include "ByteSwap.h" + +STDMETHODIMP CByteSwap2::Init() { return S_OK; } + +STDMETHODIMP_(UInt32) CByteSwap2::Filter(Byte *data, UInt32 size) +{ + const UInt32 kStep = 2; + UInt32 i; + for (i = 0; i + kStep <= size; i += kStep) + { + Byte b = data[i]; + data[i] = data[i + 1]; + data[i + 1] = b; + } + return i; +} + +STDMETHODIMP CByteSwap4::Init() { return S_OK; } + +STDMETHODIMP_(UInt32) CByteSwap4::Filter(Byte *data, UInt32 size) +{ + const UInt32 kStep = 4; + UInt32 i; + for (i = 0; i + kStep <= size; i += kStep) + { + Byte b0 = data[i]; + Byte b1 = data[i + 1]; + data[i] = data[i + 3]; + data[i + 1] = data[i + 2]; + data[i + 2] = b1; + data[i + 3] = b0; + } + return i; +} diff --git a/CPP/7zip/Compress/ByteSwap/ByteSwap.dsp b/CPP/7zip/Compress/ByteSwap/ByteSwap.dsp new file mode 100755 index 00000000..1a73d67f --- /dev/null +++ b/CPP/7zip/Compress/ByteSwap/ByteSwap.dsp @@ -0,0 +1,125 @@ +# Microsoft Developer Studio Project File - Name="ByteSwap" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=ByteSwap - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "ByteSwap.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "ByteSwap.mak" CFG="ByteSwap - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "ByteSwap - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "ByteSwap - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "ByteSwap - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BYTESWAP_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BYTESWAP_EXPORTS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\Swap.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "ByteSwap - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BYTESWAP_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BYTESWAP_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\Swap.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "ByteSwap - Win32 Release" +# Name "ByteSwap - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Codec.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\ByteSwap.cpp +# End Source File +# Begin Source File + +SOURCE=.\ByteSwap.h +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/Compress/ByteSwap/ByteSwap.dsw b/CPP/7zip/Compress/ByteSwap/ByteSwap.dsw new file mode 100755 index 00000000..413d7e6e --- /dev/null +++ b/CPP/7zip/Compress/ByteSwap/ByteSwap.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "ByteSwap"=.\ByteSwap.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Compress/ByteSwap/ByteSwap.h b/CPP/7zip/Compress/ByteSwap/ByteSwap.h new file mode 100755 index 00000000..00303063 --- /dev/null +++ b/CPP/7zip/Compress/ByteSwap/ByteSwap.h @@ -0,0 +1,37 @@ +// ByteSwap.h + +#ifndef __BYTESWAP_H +#define __BYTESWAP_H + +#include "../../ICoder.h" +#include "Common/MyCom.h" + +// {23170F69-40C1-278B-0203-020000000000} +DEFINE_GUID(CLSID_CCompressConvertByteSwap2, +0x23170F69, 0x40C1, 0x278B, 0x02, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00); + +// {23170F69-40C1-278B-0203-040000000000} +DEFINE_GUID(CLSID_CCompressConvertByteSwap4, +0x23170F69, 0x40C1, 0x278B, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00); + +class CByteSwap2: + public ICompressFilter, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); +}; + +class CByteSwap4: + public ICompressFilter, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); +}; + +#endif diff --git a/CPP/7zip/Compress/ByteSwap/DllExports.cpp b/CPP/7zip/Compress/ByteSwap/DllExports.cpp new file mode 100755 index 00000000..cc737590 --- /dev/null +++ b/CPP/7zip/Compress/ByteSwap/DllExports.cpp @@ -0,0 +1,91 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "ByteSwap.h" +#include "../../ICoder.h" + +extern "C" +BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /*lpReserved*/) +{ + return TRUE; +} + +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + int correctInterface = (*iid == IID_ICompressFilter); + CMyComPtr coder; + if (*clsid == CLSID_CCompressConvertByteSwap2) + { + if (!correctInterface) + return E_NOINTERFACE; + coder = (ICompressFilter *)new CByteSwap2(); + } + else if (*clsid == CLSID_CCompressConvertByteSwap4) + { + if (!correctInterface) + return E_NOINTERFACE; + coder = (ICompressFilter *)new CByteSwap4(); + } + else + return CLASS_E_CLASSNOTAVAILABLE; + *outObject = coder.Detach(); + COM_TRY_END + return S_OK; +} + +struct CSwapMethodInfo +{ + char ID[3]; + const wchar_t *Name; + const GUID *clsid; +}; + +static CSwapMethodInfo g_Methods[] = +{ + { { 0x2, 0x03, 0x02 }, L"Swap2", &CLSID_CCompressConvertByteSwap2 }, + { { 0x2, 0x03, 0x04 }, L"Swap4", &CLSID_CCompressConvertByteSwap4 } +}; + +STDAPI GetNumberOfMethods(UINT32 *numMethods) +{ + *numMethods = sizeof(g_Methods) / sizeof(g_Methods[1]); + return S_OK; +} + +STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +{ + if (index > sizeof(g_Methods) / sizeof(g_Methods[1])) + return E_INVALIDARG; + ::VariantClear((tagVARIANT *)value); + const CSwapMethodInfo &method = g_Methods[index]; + switch(propID) + { + case NMethodPropID::kID: + { + if ((value->bstrVal = ::SysAllocStringByteLen(method.ID, + sizeof(method.ID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NMethodPropID::kName: + { + if ((value->bstrVal = ::SysAllocString(method.Name)) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NMethodPropID::kDecoder: + case NMethodPropID::kEncoder: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)method.clsid, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + } + return S_OK; +} diff --git a/CPP/7zip/Compress/ByteSwap/StdAfx.cpp b/CPP/7zip/Compress/ByteSwap/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Compress/ByteSwap/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Compress/ByteSwap/StdAfx.h b/CPP/7zip/Compress/ByteSwap/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Compress/ByteSwap/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Compress/ByteSwap/makefile b/CPP/7zip/Compress/ByteSwap/makefile new file mode 100755 index 00000000..f73a8079 --- /dev/null +++ b/CPP/7zip/Compress/ByteSwap/makefile @@ -0,0 +1,23 @@ +PROG = Swap.dll +DEF_FILE = ../Codec.def +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib + +SWAP_OBJS = \ + $O\DllExports.obj \ + +SWAP_OPT_OBJS = \ + $O\ByteSwap.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(SWAP_OBJS) \ + $(SWAP_OPT_OBJS) \ + $O\resource.res + +!include "../../../Build.mak" + +$(SWAP_OBJS): $(*B).cpp + $(COMPL) +$(SWAP_OPT_OBJS): $(*B).cpp + $(COMPL_O2) diff --git a/CPP/7zip/Compress/ByteSwap/resource.rc b/CPP/7zip/Compress/ByteSwap/resource.rc new file mode 100755 index 00000000..21c0c505 --- /dev/null +++ b/CPP/7zip/Compress/ByteSwap/resource.rc @@ -0,0 +1,3 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("SWAP filter Codec", "SWAP") diff --git a/CPP/7zip/Compress/Codec.def b/CPP/7zip/Compress/Codec.def new file mode 100755 index 00000000..ebf73a3b --- /dev/null +++ b/CPP/7zip/Compress/Codec.def @@ -0,0 +1,4 @@ +EXPORTS + CreateObject PRIVATE + GetNumberOfMethods PRIVATE + GetMethodProperty PRIVATE diff --git a/CPP/7zip/Compress/Copy/Copy.dsp b/CPP/7zip/Compress/Copy/Copy.dsp new file mode 100755 index 00000000..099a433d --- /dev/null +++ b/CPP/7zip/Compress/Copy/Copy.dsp @@ -0,0 +1,149 @@ +# Microsoft Developer Studio Project File - Name="Copy" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Copy - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Copy.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Copy.mak" CFG="Copy - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Copy - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Copy - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Copy - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COPY_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COPY_EXPORTS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-zip\Codecs\Copy.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Copy - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COPY_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COPY_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-zip\Codecs\Copy.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Copy - Win32 Release" +# Name "Copy - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Codec.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# End Group +# Begin Group "7-Zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=.\CopyCoder.h +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/Compress/Copy/Copy.dsw b/CPP/7zip/Compress/Copy/Copy.dsw new file mode 100755 index 00000000..53ddf6cf --- /dev/null +++ b/CPP/7zip/Compress/Copy/Copy.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Copy"=".\Copy.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Compress/Copy/CopyCoder.cpp b/CPP/7zip/Compress/Copy/CopyCoder.cpp new file mode 100755 index 00000000..ce1bde03 --- /dev/null +++ b/CPP/7zip/Compress/Copy/CopyCoder.cpp @@ -0,0 +1,52 @@ +// Compress/CopyCoder.cpp + +#include "StdAfx.h" + +#include "CopyCoder.h" +#include "../../../Common/Alloc.h" +#include "../../Common/StreamUtils.h" + +namespace NCompress { + +static const UInt32 kBufferSize = 1 << 17; + +CCopyCoder::~CCopyCoder() +{ + ::MidFree(_buffer); +} + +STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + if (_buffer == 0) + { + _buffer = (Byte *)::MidAlloc(kBufferSize); + if (_buffer == 0) + return E_OUTOFMEMORY; + } + + TotalSize = 0; + for (;;) + { + UInt32 realProcessedSize; + UInt32 size = kBufferSize; + if (outSize != 0) + if (size > *outSize - TotalSize) + size = (UInt32)(*outSize - TotalSize); + RINOK(inStream->Read(_buffer, size, &realProcessedSize)); + if(realProcessedSize == 0) + break; + RINOK(WriteStream(outStream, _buffer, realProcessedSize, NULL)); + TotalSize += realProcessedSize; + if (progress != NULL) + { + RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize)); + } + } + return S_OK; +} + +} + diff --git a/CPP/7zip/Compress/Copy/CopyCoder.h b/CPP/7zip/Compress/Copy/CopyCoder.h new file mode 100755 index 00000000..d2a26a89 --- /dev/null +++ b/CPP/7zip/Compress/Copy/CopyCoder.h @@ -0,0 +1,31 @@ +// Compress/CopyCoder.h + +#ifndef __COMPRESS_COPYCODER_H +#define __COMPRESS_COPYCODER_H + +#include "../../ICoder.h" +#include "../../../Common/MyCom.h" + +namespace NCompress { + +class CCopyCoder: + public ICompressCoder, + public CMyUnknownImp +{ + Byte *_buffer; +public: + UInt64 TotalSize; + CCopyCoder(): TotalSize(0) , _buffer(0) {}; + ~CCopyCoder(); + + MY_UNKNOWN_IMP + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); +}; + +} + +#endif diff --git a/CPP/7zip/Compress/Copy/DllExports.cpp b/CPP/7zip/Compress/Copy/DllExports.cpp new file mode 100755 index 00000000..756dcc9c --- /dev/null +++ b/CPP/7zip/Compress/Copy/DllExports.cpp @@ -0,0 +1,70 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "../../../Common/MyInitGuid.h" +#include "../../../Common/ComTry.h" + +#include "CopyCoder.h" + +// {23170F69-40C1-278B-0000-000000000000} +DEFINE_GUID(CLSID_CCompressCopyCoder, +0x23170F69, 0x40C1, 0x278B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /*lpReserved*/) +{ + return TRUE; +} + +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + if (*clsid != CLSID_CCompressCopyCoder) + return CLASS_E_CLASSNOTAVAILABLE; + if (*iid != IID_ICompressCoder) + return E_NOINTERFACE; + CMyComPtr coder = (ICompressCoder *)new NCompress::CCopyCoder(); + *outObject = coder.Detach(); + COM_TRY_END + return S_OK; +} + +STDAPI GetNumberOfMethods(UINT32 *numMethods) +{ + *numMethods = 1; + return S_OK; +} + +STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +{ + if (index != 0) + return E_INVALIDARG; + // ::VariantClear((tagVARIANT *)value); + switch(propID) + { + case NMethodPropID::kID: + { + const char id[] = { 0x0 }; + if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NMethodPropID::kName: + { + if ((value->bstrVal = ::SysAllocString(L"Copy")) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NMethodPropID::kDecoder: + case NMethodPropID::kEncoder: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CCompressCopyCoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + } + return S_OK; +} diff --git a/CPP/7zip/Compress/Copy/StdAfx.cpp b/CPP/7zip/Compress/Copy/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Compress/Copy/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Compress/Copy/StdAfx.h b/CPP/7zip/Compress/Copy/StdAfx.h new file mode 100755 index 00000000..92239aeb --- /dev/null +++ b/CPP/7zip/Compress/Copy/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Compress/Copy/makefile b/CPP/7zip/Compress/Copy/makefile new file mode 100755 index 00000000..8c108fbc --- /dev/null +++ b/CPP/7zip/Compress/Copy/makefile @@ -0,0 +1,30 @@ +PROG = Copy.dll +DEF_FILE = ../Codec.def +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib + +COPY_OBJS = \ + $O\DllExports.obj \ + $O\CopyCoder.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + +7ZIP_COMMON_OBJS = \ + $O\StreamUtils.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(COPY_OBJS) \ + $(COMMON_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $O\resource.res + +!include "../../../Build.mak" + +$(COPY_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/Compress/Copy/resource.rc b/CPP/7zip/Compress/Copy/resource.rc new file mode 100755 index 00000000..234c85bf --- /dev/null +++ b/CPP/7zip/Compress/Copy/resource.rc @@ -0,0 +1,3 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("Copy Codec", "Copy") diff --git a/CPP/7zip/Compress/Deflate/Deflate.dsp b/CPP/7zip/Compress/Deflate/Deflate.dsp new file mode 100755 index 00000000..a1baccad --- /dev/null +++ b/CPP/7zip/Compress/Deflate/Deflate.dsp @@ -0,0 +1,341 @@ +# Microsoft Developer Studio Project File - Name="Deflate" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Deflate - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Deflate.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Deflate.mak" CFG="Deflate - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Deflate - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Deflate - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Deflate - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DEFLATE_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DEFLATE_EXPORTS" /D "_ST_MODE" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\Deflate.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Deflate - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DEFLATE_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DEFLATE_EXPORTS" /D "_ST_MODE" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\Deflate.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Deflate - Win32 Release" +# Name "Deflate - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Codec.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Huffman" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Huffman\HuffmanDecoder.h +# End Source File +# End Group +# Begin Group "Interface" + +# PROP Default_Filter "" +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LSBFDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LSBFDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LSBFEncoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LSBFEncoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# End Group +# Begin Group "LZ" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\LZ\LZOutWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\LZ\LZOutWindow.h +# End Source File +# End Group +# Begin Group "LZ_C" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.c + +!IF "$(CFG)" == "Deflate - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Deflate - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Lz\LzHash.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.c + +!IF "$(CFG)" == "Deflate - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Deflate - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.h +# End Source File +# End Group +# Begin Group "C Huffman" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Huffman\HuffmanEncode.c + +!IF "$(CFG)" == "Deflate - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Deflate - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Huffman\HuffmanEncode.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.c + +!IF "$(CFG)" == "Deflate - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Deflate - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\DeflateConst.h +# End Source File +# Begin Source File + +SOURCE=.\DeflateDecoder.cpp + +!IF "$(CFG)" == "Deflate - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Deflate - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\DeflateDecoder.h +# End Source File +# Begin Source File + +SOURCE=.\DeflateEncoder.cpp + +!IF "$(CFG)" == "Deflate - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Deflate - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\DeflateEncoder.h +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/Compress/Deflate/Deflate.dsw b/CPP/7zip/Compress/Deflate/Deflate.dsw new file mode 100755 index 00000000..f17203ed --- /dev/null +++ b/CPP/7zip/Compress/Deflate/Deflate.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Deflate"=.\Deflate.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Compress/Deflate/DeflateConst.h b/CPP/7zip/Compress/Deflate/DeflateConst.h new file mode 100755 index 00000000..766b589a --- /dev/null +++ b/CPP/7zip/Compress/Deflate/DeflateConst.h @@ -0,0 +1,134 @@ +// DeflateConst.h + +#ifndef __DEFLATE_CONST_H +#define __DEFLATE_CONST_H + +namespace NCompress { +namespace NDeflate { + +const int kNumHuffmanBits = 15; + +const UInt32 kHistorySize32 = (1 << 15); +const UInt32 kHistorySize64 = (1 << 16); + +const UInt32 kDistTableSize32 = 30; +const UInt32 kDistTableSize64 = 32; + +const UInt32 kNumLenSymbols32 = 256; +const UInt32 kNumLenSymbols64 = 255; // don't change it. It must be <= 255. +const UInt32 kNumLenSymbolsMax = kNumLenSymbols32; + +const UInt32 kNumLenSlots = 29; + +const UInt32 kFixedDistTableSize = 32; +const UInt32 kFixedLenTableSize = 31; + +const UInt32 kSymbolEndOfBlock = 0x100; +const UInt32 kSymbolMatch = kSymbolEndOfBlock + 1; + +const UInt32 kMainTableSize = kSymbolMatch + kNumLenSlots; +const UInt32 kFixedMainTableSize = kSymbolMatch + kFixedLenTableSize; + +const UInt32 kLevelTableSize = 19; + +const UInt32 kTableDirectLevels = 16; +const UInt32 kTableLevelRepNumber = kTableDirectLevels; +const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1; +const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1; + +const UInt32 kLevelMask = 0xF; + +const Byte kLenStart32[kFixedLenTableSize] = + {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 255, 0, 0}; +const Byte kLenStart64[kFixedLenTableSize] = + {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 0, 0, 0}; + +const Byte kLenDirectBits32[kFixedLenTableSize] = + {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0}; +const Byte kLenDirectBits64[kFixedLenTableSize] = + {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 16, 0, 0}; + +const UInt32 kDistStart[kDistTableSize64] = + {0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768, + 1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768,49152}; +const Byte kDistDirectBits[kDistTableSize64] = + {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14}; + +const Byte kLevelDirectBits[3] = {2, 3, 7}; + +const Byte kCodeLengthAlphabetOrder[kLevelTableSize] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +const UInt32 kMatchMinLen = 3; +const UInt32 kMatchMaxLen32 = kNumLenSymbols32 + kMatchMinLen - 1; //256 + 2 +const UInt32 kMatchMaxLen64 = kNumLenSymbols64 + kMatchMinLen - 1; //255 + 2 +const UInt32 kMatchMaxLen = kMatchMaxLen32; + +const int kFinalBlockFieldSize = 1; + +namespace NFinalBlockField +{ + enum + { + kNotFinalBlock = 0, + kFinalBlock = 1 + }; +} + +const int kBlockTypeFieldSize = 2; + +namespace NBlockType +{ + enum + { + kStored = 0, + kFixedHuffman = 1, + kDynamicHuffman = 2 + }; +} + +const int kNumLenCodesFieldSize = 5; +const int kNumDistCodesFieldSize = 5; +const int kNumLevelCodesFieldSize = 4; + +const UInt32 kNumLitLenCodesMin = 257; +const UInt32 kNumDistCodesMin = 1; +const UInt32 kNumLevelCodesMin = 4; + +const int kLevelFieldSize = 3; + +const int kStoredBlockLengthFieldSize = 16; + +struct CLevels +{ + Byte litLenLevels[kFixedMainTableSize]; + Byte distLevels[kFixedDistTableSize]; + + void SubClear() + { + UInt32 i; + for(i = kNumLitLenCodesMin; i < kFixedMainTableSize; i++) + litLenLevels[i] = 0; + for(i = 0; i < kFixedDistTableSize; i++) + distLevels[i] = 0; + } + + void SetFixedLevels() + { + int i; + + for (i = 0; i < 144; i++) + litLenLevels[i] = 8; + for (; i < 256; i++) + litLenLevels[i] = 9; + for (; i < 280; i++) + litLenLevels[i] = 7; + for (; i < 288; i++) + litLenLevels[i] = 8; + for (i = 0; i < kFixedDistTableSize; i++) // test it: InfoZip only uses kDistTableSize + distLevels[i] = 5; + } +}; + +}} + +#endif diff --git a/CPP/7zip/Compress/Deflate/DeflateDecoder.cpp b/CPP/7zip/Compress/Deflate/DeflateDecoder.cpp new file mode 100755 index 00000000..0de5534b --- /dev/null +++ b/CPP/7zip/Compress/Deflate/DeflateDecoder.cpp @@ -0,0 +1,339 @@ +// DeflateDecoder.cpp + +#include "StdAfx.h" + +#include "DeflateDecoder.h" + +namespace NCompress { +namespace NDeflate { +namespace NDecoder { + +static const int kLenIdFinished = -1; +static const int kLenIdNeedInit = -2; + +CCoder::CCoder(bool deflate64Mode, bool deflateNSIS): + _deflate64Mode(deflate64Mode), + _deflateNSIS(deflateNSIS), + _keepHistory(false) {} + +UInt32 CCoder::ReadBits(int numBits) +{ + return m_InBitStream.ReadBits(numBits); +} + +bool CCoder::DeCodeLevelTable(Byte *values, int numSymbols) +{ + int i = 0; + do + { + UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); + if (number < kTableDirectLevels) + values[i++] = (Byte)number; + else if (number < kLevelTableSize) + { + if (number == kTableLevelRepNumber) + { + if (i == 0) + return false; + int num = ReadBits(2) + 3; + for (; num > 0 && i < numSymbols; num--, i++) + values[i] = values[i - 1]; + } + else + { + int num; + if (number == kTableLevel0Number) + num = ReadBits(3) + 3; + else + num = ReadBits(7) + 11; + for (;num > 0 && i < numSymbols; num--) + values[i++] = 0; + } + } + else + return false; + } + while(i < numSymbols); + return true; +} + +#define RIF(x) { if (!(x)) return false; } + +bool CCoder::ReadTables(void) +{ + m_FinalBlock = (ReadBits(kFinalBlockFieldSize) == NFinalBlockField::kFinalBlock); + UInt32 blockType = ReadBits(kBlockTypeFieldSize); + if (blockType > NBlockType::kDynamicHuffman) + return false; + + if (blockType == NBlockType::kStored) + { + m_StoredMode = true; + UInt32 currentBitPosition = m_InBitStream.GetBitPosition(); + int numBitsForAlign = (int)(currentBitPosition > 0 ? (8 - currentBitPosition): 0); + ReadBits(numBitsForAlign); + m_StoredBlockSize = ReadBits(kStoredBlockLengthFieldSize); + if (_deflateNSIS) + return true; + return (m_StoredBlockSize == (UInt16)~ReadBits(kStoredBlockLengthFieldSize)); + } + + m_StoredMode = false; + + CLevels levels; + if (blockType == NBlockType::kFixedHuffman) + { + levels.SetFixedLevels(); + _numDistLevels = _deflate64Mode ? kDistTableSize64 : kDistTableSize32; + } + else + { + int numLitLenLevels = ReadBits(kNumLenCodesFieldSize) + kNumLitLenCodesMin; + _numDistLevels = ReadBits(kNumDistCodesFieldSize) + kNumDistCodesMin; + int numLevelCodes = ReadBits(kNumLevelCodesFieldSize) + kNumLevelCodesMin; + + if (!_deflate64Mode) + if (_numDistLevels > kDistTableSize32) + return false; + + Byte levelLevels[kLevelTableSize]; + for (int i = 0; i < kLevelTableSize; i++) + { + int position = kCodeLengthAlphabetOrder[i]; + if(i < numLevelCodes) + levelLevels[position] = (Byte)ReadBits(kLevelFieldSize); + else + levelLevels[position] = 0; + } + + RIF(m_LevelDecoder.SetCodeLengths(levelLevels)); + + Byte tmpLevels[kFixedMainTableSize + kFixedDistTableSize]; + if (!DeCodeLevelTable(tmpLevels, numLitLenLevels + _numDistLevels)) + return false; + + levels.SubClear(); + memcpy(levels.litLenLevels, tmpLevels, numLitLenLevels); + memcpy(levels.distLevels, tmpLevels + numLitLenLevels, _numDistLevels); + } + RIF(m_MainDecoder.SetCodeLengths(levels.litLenLevels)); + return m_DistDecoder.SetCodeLengths(levels.distLevels); +} + +HRESULT CCoder::CodeSpec(UInt32 curSize) +{ + if (_remainLen == kLenIdFinished) + return S_OK; + if (_remainLen == kLenIdNeedInit) + { + if (!_keepHistory) + if (!m_OutWindowStream.Create(_deflate64Mode ? kHistorySize64: kHistorySize32)) + return E_OUTOFMEMORY; + if (!m_InBitStream.Create(1 << 17)) + return E_OUTOFMEMORY; + m_OutWindowStream.Init(_keepHistory); + m_InBitStream.Init(); + m_FinalBlock = false; + _remainLen = 0; + _needReadTable = true; + } + + if (curSize == 0) + return S_OK; + + while(_remainLen > 0 && curSize > 0) + { + _remainLen--; + Byte b = m_OutWindowStream.GetByte(_rep0); + m_OutWindowStream.PutByte(b); + curSize--; + } + + while(curSize > 0) + { + if (_needReadTable) + { + if (m_FinalBlock) + { + _remainLen = kLenIdFinished; + break; + } + if (!ReadTables()) + return S_FALSE; + _needReadTable = false; + } + + if(m_StoredMode) + { + for (; m_StoredBlockSize > 0 && curSize > 0; m_StoredBlockSize--, curSize--) + m_OutWindowStream.PutByte((Byte)m_InBitStream.ReadBits(8)); + _needReadTable = (m_StoredBlockSize == 0); + continue; + } + while(curSize > 0) + { + if (m_InBitStream.NumExtraBytes > 4) + return S_FALSE; + + UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); + if (number < 0x100) + { + m_OutWindowStream.PutByte((Byte)number); + curSize--; + continue; + } + else if (number == kSymbolEndOfBlock) + { + _needReadTable = true; + break; + } + else if (number < kMainTableSize) + { + number -= kSymbolMatch; + UInt32 len; + { + int numBits; + if (_deflate64Mode) + { + len = kLenStart64[number]; + numBits = kLenDirectBits64[number]; + } + else + { + len = kLenStart32[number]; + numBits = kLenDirectBits32[number]; + } + len += kMatchMinLen + m_InBitStream.ReadBits(numBits); + } + UInt32 locLen = len; + if (locLen > curSize) + locLen = (UInt32)curSize; + number = m_DistDecoder.DecodeSymbol(&m_InBitStream); + if (number >= _numDistLevels) + return S_FALSE; + UInt32 distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]); + if (!m_OutWindowStream.CopyBlock(distance, locLen)) + return S_FALSE; + curSize -= locLen; + len -= locLen; + if (len != 0) + { + _remainLen = (Int32)len; + _rep0 = distance; + break; + } + } + else + return S_FALSE; + } + } + return S_OK; +} + +HRESULT CCoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + SetInStream(inStream); + m_OutWindowStream.SetStream(outStream); + SetOutStreamSize(outSize); + CCoderReleaser flusher(this); + + const UInt64 start = m_OutWindowStream.GetProcessedSize(); + for (;;) + { + UInt32 curSize = 1 << 18; + if (outSize != 0) + { + const UInt64 rem = *outSize - (m_OutWindowStream.GetProcessedSize() - start); + if (curSize > rem) + curSize = (UInt32)rem; + } + if (curSize == 0) + break; + RINOK(CodeSpec(curSize)); + if (_remainLen == kLenIdFinished) + break; + if (progress != NULL) + { + const UInt64 inSize = m_InBitStream.GetProcessedSize(); + const UInt64 nowPos64 = m_OutWindowStream.GetProcessedSize() - start; + RINOK(progress->SetRatioInfo(&inSize, &nowPos64)); + } + } + flusher.NeedFlush = false; + return Flush(); +} + + +#ifdef _NO_EXCEPTIONS + +#define DEFLATE_TRY_BEGIN +#define DEFLATE_TRY_END + +#else + +#define DEFLATE_TRY_BEGIN try { +#define DEFLATE_TRY_END } \ + catch(const CInBufferException &e) { return e.ErrorCode; } \ + catch(const CLZOutWindowException &e) { return e.ErrorCode; } \ + catch(...) { return S_FALSE; } + +#endif + +HRESULT CCoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + DEFLATE_TRY_BEGIN + return CodeReal(inStream, outStream, inSize, outSize, progress); + DEFLATE_TRY_END +} + +STDMETHODIMP CCoder::GetInStreamProcessedSize(UInt64 *value) +{ + if (value == NULL) + return E_INVALIDARG; + *value = m_InBitStream.GetProcessedSize(); + return S_OK; +} + +STDMETHODIMP CCoder::SetInStream(ISequentialInStream *inStream) +{ + m_InBitStream.SetStream(inStream); + return S_OK; +} + +STDMETHODIMP CCoder::ReleaseInStream() +{ + m_InBitStream.ReleaseStream(); + return S_OK; +} + +STDMETHODIMP CCoder::SetOutStreamSize(const UInt64 * /* outSize */) +{ + _remainLen = kLenIdNeedInit; + m_OutWindowStream.Init(_keepHistory); + return S_OK; +} + +#ifdef _ST_MODE + +STDMETHODIMP CCoder::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + DEFLATE_TRY_BEGIN + if (processedSize) + *processedSize = 0; + const UInt64 startPos = m_OutWindowStream.GetProcessedSize(); + m_OutWindowStream.SetMemStream((Byte *)data); + RINOK(CodeSpec(size)); + if (processedSize) + *processedSize = (UInt32)(m_OutWindowStream.GetProcessedSize() - startPos); + return Flush(); + DEFLATE_TRY_END +} + +#endif + +}}} diff --git a/CPP/7zip/Compress/Deflate/DeflateDecoder.h b/CPP/7zip/Compress/Deflate/DeflateDecoder.h new file mode 100755 index 00000000..99928b72 --- /dev/null +++ b/CPP/7zip/Compress/Deflate/DeflateDecoder.h @@ -0,0 +1,134 @@ +// DeflateDecoder.h + +#ifndef __DEFLATE_DECODER_H +#define __DEFLATE_DECODER_H + +#include "../../../Common/MyCom.h" + +#include "../../ICoder.h" +#include "../../Common/LSBFDecoder.h" +#include "../../Common/InBuffer.h" +#include "../LZ/LZOutWindow.h" +#include "../Huffman/HuffmanDecoder.h" + +#include "DeflateConst.h" + +namespace NCompress { +namespace NDeflate { +namespace NDecoder { + +class CCoder: + public ICompressCoder, + public ICompressGetInStreamProcessedSize, + #ifdef _ST_MODE + public ICompressSetInStream, + public ICompressSetOutStreamSize, + public ISequentialInStream, + #endif + public CMyUnknownImp +{ + CLZOutWindow m_OutWindowStream; + NStream::NLSBF::CDecoder m_InBitStream; + NCompress::NHuffman::CDecoder m_MainDecoder; + NCompress::NHuffman::CDecoder m_DistDecoder; + NCompress::NHuffman::CDecoder m_LevelDecoder; + + UInt32 m_StoredBlockSize; + + bool m_FinalBlock; + bool m_StoredMode; + UInt32 _numDistLevels; + + + bool _deflateNSIS; + bool _deflate64Mode; + bool _keepHistory; + Int32 _remainLen; + UInt32 _rep0; + bool _needReadTable; + + UInt32 ReadBits(int numBits); + + bool DeCodeLevelTable(Byte *values, int numSymbols); + bool ReadTables(); + + void ReleaseStreams() + { + m_OutWindowStream.ReleaseStream(); + ReleaseInStream(); + } + + HRESULT Flush() { return m_OutWindowStream.Flush(); } + class CCoderReleaser + { + CCoder *m_Coder; + public: + bool NeedFlush; + CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {} + ~CCoderReleaser() + { + if (NeedFlush) + m_Coder->Flush(); + m_Coder->ReleaseStreams(); + } + }; + friend class CCoderReleaser; + + HRESULT CodeSpec(UInt32 curSize); +public: + CCoder(bool deflate64Mode, bool deflateNSIS = false); + void SetKeepHistory(bool keepHistory) { _keepHistory = keepHistory; } + + HRESULT CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + #ifdef _ST_MODE + MY_UNKNOWN_IMP4( + ICompressGetInStreamProcessedSize, + ICompressSetInStream, + ICompressSetOutStreamSize, + ISequentialInStream + ) + #else + MY_UNKNOWN_IMP1( + ICompressGetInStreamProcessedSize) + #endif + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(SetInStream)(ISequentialInStream *inStream); + STDMETHOD(ReleaseInStream)(); + STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); + + #ifdef _ST_MODE + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + #endif + + // IGetInStreamProcessedSize + STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); +}; + +class CCOMCoder : public CCoder +{ +public: + CCOMCoder(): CCoder(false) {} +}; + +class CNsisCOMCoder : public CCoder +{ +public: + CNsisCOMCoder(): CCoder(false, true) {} +}; + +class CCOMCoder64 : public CCoder +{ +public: + CCOMCoder64(): CCoder(true) {} +}; + +}}} + +#endif diff --git a/CPP/7zip/Compress/Deflate/DeflateEncoder.cpp b/CPP/7zip/Compress/Deflate/DeflateEncoder.cpp new file mode 100755 index 00000000..4e9ffe6d --- /dev/null +++ b/CPP/7zip/Compress/Deflate/DeflateEncoder.cpp @@ -0,0 +1,963 @@ +// DeflateEncoder.cpp + +#include "StdAfx.h" + +#include "DeflateEncoder.h" + +#include "Windows/Defs.h" +#include "Common/ComTry.h" +#include "../../../Common/Alloc.h" +// #include "../LZ/BinTree/BinTree3Z.h" + +#if _MSC_VER >= 1300 +#define NO_INLINE __declspec(noinline) +#else +#define NO_INLINE +#endif + +extern "C" +{ + #include "../../../../C/Compress/Huffman/HuffmanEncode.h" +} + +namespace NCompress { +namespace NDeflate { +namespace NEncoder { + +const int kNumDivPassesMax = 10; // [0, 16); ratio/speed/ram tradeoff; use big value for better compression ratio. +const UInt32 kNumTables = (1 << kNumDivPassesMax); + +static UInt32 kFixedHuffmanCodeBlockSizeMax = (1 << 8); // [0, (1 << 32)); ratio/speed tradeoff; use big value for better compression ratio. +static UInt32 kDivideCodeBlockSizeMin = (1 << 6); // [1, (1 << 32)); ratio/speed tradeoff; use small value for better compression ratio. +static UInt32 kDivideBlockSizeMin = (1 << 6); // [1, (1 << 32)); ratio/speed tradeoff; use small value for better compression ratio. + +static const UInt32 kMaxUncompressedBlockSize = ((1 << 16) - 1) * 1; // [1, (1 << 32)) +static const UInt32 kMatchArraySize = kMaxUncompressedBlockSize * 10; // [kMatchMaxLen * 2, (1 << 32)) +static const UInt32 kMatchArrayLimit = kMatchArraySize - kMatchMaxLen * 4 * sizeof(UInt16); +static const UInt32 kBlockUncompressedSizeThreshold = kMaxUncompressedBlockSize - + kMatchMaxLen - kNumOpts; + +static const int kMaxCodeBitLength = 15; +static const int kMaxLevelBitLength = 7; + +static Byte kNoLiteralStatPrice = 13; +static Byte kNoLenStatPrice = 13; +static Byte kNoPosStatPrice = 6; + +static Byte g_LenSlots[kNumLenSymbolsMax]; +static Byte g_FastPos[1 << 9]; + +class CFastPosInit +{ +public: + CFastPosInit() + { + int i; + for(i = 0; i < kNumLenSlots; i++) + { + int c = kLenStart32[i]; + int j = 1 << kLenDirectBits32[i]; + for(int k = 0; k < j; k++, c++) + g_LenSlots[c] = (Byte)i; + } + + const int kFastSlots = 18; + int c = 0; + for (Byte slotFast = 0; slotFast < kFastSlots; slotFast++) + { + UInt32 k = (1 << kDistDirectBits[slotFast]); + for (UInt32 j = 0; j < k; j++, c++) + g_FastPos[c] = slotFast; + } + } +}; + +static CFastPosInit g_FastPosInit; + + +inline UInt32 GetPosSlot(UInt32 pos) +{ + if (pos < 0x200) + return g_FastPos[pos]; + return g_FastPos[pos >> 8] + 16; +} + +void *SzAlloc(size_t size) +{ + if (size == 0) + return 0; + return malloc(size); +} + +void SzFree(void *address) +{ + free(address); +} + +ISzAlloc g_Alloc = { SzAlloc, SzFree }; + +CCoder::CCoder(bool deflate64Mode): + m_Deflate64Mode(deflate64Mode), + m_NumPasses(1), + m_NumDivPasses(1), + m_NumFastBytes(32), + m_OnePosMatchesMemory(0), + m_DistanceMemory(0), + m_Created(false), + m_Values(0), + m_Tables(0), + m_MatchFinderCycles(0) + // m_SetMfPasses(0) +{ + m_MatchMaxLen = deflate64Mode ? kMatchMaxLen64 : kMatchMaxLen32; + m_NumLenCombinations = deflate64Mode ? kNumLenSymbols64 : kNumLenSymbols32; + m_LenStart = deflate64Mode ? kLenStart64 : kLenStart32; + m_LenDirectBits = deflate64Mode ? kLenDirectBits64 : kLenDirectBits32; + MatchFinder_Construct(&_lzInWindow); +} + +HRESULT CCoder::Create() +{ + COM_TRY_BEGIN + if (m_Values == 0) + { + m_Values = (CCodeValue *)MyAlloc((kMaxUncompressedBlockSize) * sizeof(CCodeValue)); + if (m_Values == 0) + return E_OUTOFMEMORY; + } + if (m_Tables == 0) + { + m_Tables = (CTables *)MyAlloc((kNumTables) * sizeof(CTables)); + if (m_Tables == 0) + return E_OUTOFMEMORY; + } + + if (m_IsMultiPass) + { + if (m_OnePosMatchesMemory == 0) + { + m_OnePosMatchesMemory = (UInt16 *)::MidAlloc(kMatchArraySize * sizeof(UInt16)); + if (m_OnePosMatchesMemory == 0) + return E_OUTOFMEMORY; + } + } + else + { + if (m_DistanceMemory == 0) + { + m_DistanceMemory = (UInt16 *)MyAlloc((kMatchMaxLen + 2) * 2 * sizeof(UInt16)); + if (m_DistanceMemory == 0) + return E_OUTOFMEMORY; + m_MatchDistances = m_DistanceMemory; + } + } + + if (!m_Created) + { + _lzInWindow.btMode = 1; + _lzInWindow.numHashBytes = 3; + if (!MatchFinder_Create(&_lzInWindow, + m_Deflate64Mode ? kHistorySize64 : kHistorySize32, + kNumOpts + kMaxUncompressedBlockSize, + m_NumFastBytes, m_MatchMaxLen - m_NumFastBytes, &g_Alloc)) + return E_OUTOFMEMORY; + if (!m_OutStream.Create(1 << 20)) + return E_OUTOFMEMORY; + } + if (m_MatchFinderCycles != 0) + _lzInWindow.cutValue = m_MatchFinderCycles; + m_Created = true; + return S_OK; + COM_TRY_END +} + +// ICompressSetEncoderProperties2 +HRESULT CCoder::BaseSetEncoderProperties2(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties) +{ + for(UInt32 i = 0; i < numProperties; i++) + { + const PROPVARIANT &prop = properties[i]; + switch(propIDs[i]) + { + case NCoderPropID::kNumPasses: + if (prop.vt != VT_UI4) + return E_INVALIDARG; + m_NumDivPasses = prop.ulVal; + if (m_NumDivPasses == 0) + m_NumDivPasses = 1; + if (m_NumDivPasses == 1) + m_NumPasses = 1; + else if (m_NumDivPasses <= kNumDivPassesMax) + m_NumPasses = 2; + else + { + m_NumPasses = 2 + (m_NumDivPasses - kNumDivPassesMax); + m_NumDivPasses = kNumDivPassesMax; + } + break; + case NCoderPropID::kNumFastBytes: + if (prop.vt != VT_UI4) + return E_INVALIDARG; + m_NumFastBytes = prop.ulVal; + if(m_NumFastBytes < kMatchMinLen || m_NumFastBytes > m_MatchMaxLen) + return E_INVALIDARG; + break; + case NCoderPropID::kMatchFinderCycles: + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + m_MatchFinderCycles = prop.ulVal; + break; + } + default: + return E_INVALIDARG; + } + } + return S_OK; +} + +void CCoder::Free() +{ + ::MidFree(m_OnePosMatchesMemory); + m_OnePosMatchesMemory = 0; + ::MyFree(m_DistanceMemory); + m_DistanceMemory = 0; + ::MyFree(m_Values); + m_Values = 0; + ::MyFree(m_Tables); + m_Tables = 0; +} + +CCoder::~CCoder() +{ + Free(); + MatchFinder_Free(&_lzInWindow, &g_Alloc); +} + +void CCoder::GetMatches() +{ + if (m_IsMultiPass) + { + m_MatchDistances = m_OnePosMatchesMemory + m_Pos; + if (m_SecondPass) + { + m_Pos += *m_MatchDistances + 1; + return; + } + } + + UInt32 distanceTmp[kMatchMaxLen * 2 + 3]; + + UInt32 numPairs = Bt3Zip_MatchFinder_GetMatches(&_lzInWindow, distanceTmp); + *m_MatchDistances = (UInt16)numPairs; + + if (numPairs > 0) + { + UInt32 i; + for(i = 0; i < numPairs; i += 2) + { + m_MatchDistances[i + 1] = (UInt16)distanceTmp[i]; + m_MatchDistances[i + 2] = (UInt16)distanceTmp[i + 1]; + } + UInt32 len = distanceTmp[numPairs - 2]; + if (len == m_NumFastBytes && m_NumFastBytes != m_MatchMaxLen) + { + UInt32 numAvail = Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) + 1; + const Byte *pby = Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow) - 1; + UInt32 distance = distanceTmp[numPairs - 1] + 1; + if (numAvail > m_MatchMaxLen) + numAvail = m_MatchMaxLen; + for (; len < numAvail && pby[len] == pby[(size_t)len - distance]; len++); + m_MatchDistances[i - 1] = (UInt16)len; + } + } + if (m_IsMultiPass) + m_Pos += numPairs + 1; + if (!m_SecondPass) + m_AdditionalOffset++; +} + +void CCoder::MovePos(UInt32 num) +{ + if (!m_SecondPass && num > 0) + { + Bt3Zip_MatchFinder_Skip(&_lzInWindow, num); + m_AdditionalOffset += num; + } +} + +static const UInt32 kIfinityPrice = 0xFFFFFFF; + +NO_INLINE UInt32 CCoder::Backward(UInt32 &backRes, UInt32 cur) +{ + m_OptimumEndIndex = cur; + UInt32 posMem = m_Optimum[cur].PosPrev; + UInt16 backMem = m_Optimum[cur].BackPrev; + do + { + UInt32 posPrev = posMem; + UInt16 backCur = backMem; + backMem = m_Optimum[posPrev].BackPrev; + posMem = m_Optimum[posPrev].PosPrev; + m_Optimum[posPrev].BackPrev = backCur; + m_Optimum[posPrev].PosPrev = (UInt16)cur; + cur = posPrev; + } + while(cur > 0); + backRes = m_Optimum[0].BackPrev; + m_OptimumCurrentIndex = m_Optimum[0].PosPrev; + return m_OptimumCurrentIndex; +} + +NO_INLINE UInt32 CCoder::GetOptimal(UInt32 &backRes) +{ + if(m_OptimumEndIndex != m_OptimumCurrentIndex) + { + UInt32 len = m_Optimum[m_OptimumCurrentIndex].PosPrev - m_OptimumCurrentIndex; + backRes = m_Optimum[m_OptimumCurrentIndex].BackPrev; + m_OptimumCurrentIndex = m_Optimum[m_OptimumCurrentIndex].PosPrev; + return len; + } + m_OptimumCurrentIndex = m_OptimumEndIndex = 0; + + GetMatches(); + + UInt32 numDistancePairs = m_MatchDistances[0]; + if(numDistancePairs == 0) + return 1; + + const UInt16 *matchDistances = m_MatchDistances + 1; + UInt32 lenMain = matchDistances[numDistancePairs - 2]; + + if(lenMain > m_NumFastBytes) + { + backRes = matchDistances[numDistancePairs - 1]; + MovePos(lenMain - 1); + return lenMain; + } + m_Optimum[1].Price = m_LiteralPrices[Inline_MatchFinder_GetIndexByte(&_lzInWindow, 0 - m_AdditionalOffset)]; + m_Optimum[1].PosPrev = 0; + + m_Optimum[2].Price = kIfinityPrice; + m_Optimum[2].PosPrev = 1; + + + UInt32 offs = 0; + for(UInt32 i = kMatchMinLen; i <= lenMain; i++) + { + UInt32 distance = matchDistances[offs + 1]; + m_Optimum[i].PosPrev = 0; + m_Optimum[i].BackPrev = (UInt16)distance; + m_Optimum[i].Price = m_LenPrices[i - kMatchMinLen] + m_PosPrices[GetPosSlot(distance)]; + if (i == matchDistances[offs]) + offs += 2; + } + + UInt32 cur = 0; + UInt32 lenEnd = lenMain; + for (;;) + { + ++cur; + if(cur == lenEnd || cur == kNumOptsBase || m_Pos >= kMatchArrayLimit) + return Backward(backRes, cur); + GetMatches(); + matchDistances = m_MatchDistances + 1; + + UInt32 numDistancePairs = m_MatchDistances[0]; + UInt32 newLen = 0; + if(numDistancePairs != 0) + { + newLen = matchDistances[numDistancePairs - 2]; + if(newLen > m_NumFastBytes) + { + UInt32 len = Backward(backRes, cur); + m_Optimum[cur].BackPrev = matchDistances[numDistancePairs - 1]; + m_OptimumEndIndex = cur + newLen; + m_Optimum[cur].PosPrev = (UInt16)m_OptimumEndIndex; + MovePos(newLen - 1); + return len; + } + } + UInt32 curPrice = m_Optimum[cur].Price; + UInt32 curAnd1Price = curPrice + m_LiteralPrices[Inline_MatchFinder_GetIndexByte(&_lzInWindow, cur - m_AdditionalOffset)]; + COptimal &optimum = m_Optimum[cur + 1]; + if (curAnd1Price < optimum.Price) + { + optimum.Price = curAnd1Price; + optimum.PosPrev = (UInt16)cur; + } + if(numDistancePairs == 0) + continue; + while(lenEnd < cur + newLen) + m_Optimum[++lenEnd].Price = kIfinityPrice; + offs = 0; + UInt32 distance = matchDistances[offs + 1]; + curPrice += m_PosPrices[GetPosSlot(distance)]; + for(UInt32 lenTest = kMatchMinLen; ; lenTest++) + { + UInt32 curAndLenPrice = curPrice + m_LenPrices[lenTest - kMatchMinLen]; + COptimal &optimum = m_Optimum[cur + lenTest]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = (UInt16)cur; + optimum.BackPrev = (UInt16)distance; + } + if (lenTest == matchDistances[offs]) + { + offs += 2; + if (offs == numDistancePairs) + break; + curPrice -= m_PosPrices[GetPosSlot(distance)]; + distance = matchDistances[offs + 1]; + curPrice += m_PosPrices[GetPosSlot(distance)]; + } + } + } +} + +void CTables::InitStructures() +{ + UInt32 i; + for(i = 0; i < 256; i++) + litLenLevels[i] = 8; + litLenLevels[i++] = 13; + for(;i < kFixedMainTableSize; i++) + litLenLevels[i] = 5; + for(i = 0; i < kFixedDistTableSize; i++) + distLevels[i] = 5; +} + +NO_INLINE void CCoder::LevelTableDummy(const Byte *levels, int numLevels, UInt32 *freqs) +{ + int prevLen = 0xFF; + int nextLen = levels[0]; + int count = 0; + int maxCount = 7; + int minCount = 4; + if (nextLen == 0) + { + maxCount = 138; + minCount = 3; + } + for (int n = 0; n < numLevels; n++) + { + int curLen = nextLen; + nextLen = (n < numLevels - 1) ? levels[n + 1] : 0xFF; + count++; + if (count < maxCount && curLen == nextLen) + continue; + + if (count < minCount) + freqs[curLen] += (UInt32)count; + else if (curLen != 0) + { + if (curLen != prevLen) + { + freqs[curLen]++; + count--; + } + freqs[kTableLevelRepNumber]++; + } + else if (count <= 10) + freqs[kTableLevel0Number]++; + else + freqs[kTableLevel0Number2]++; + + count = 0; + prevLen = curLen; + + if (nextLen == 0) + { + maxCount = 138; + minCount = 3; + } + else if (curLen == nextLen) + { + maxCount = 6; + minCount = 3; + } + else + { + maxCount = 7; + minCount = 4; + } + } +} + +#define WRITE_HF2(codes, lens, i) m_OutStream.WriteBits(codes[i], lens[i]) +#define WRITE_HF(i) m_OutStream.WriteBits(codes[i], lens[i]) + +NO_INLINE void CCoder::LevelTableCode(const Byte *levels, int numLevels, const Byte *lens, const UInt32 *codes) +{ + int prevLen = 0xFF; + int nextLen = levels[0]; + int count = 0; + int maxCount = 7; + int minCount = 4; + if (nextLen == 0) + { + maxCount = 138; + minCount = 3; + } + for (int n = 0; n < numLevels; n++) + { + int curLen = nextLen; + nextLen = (n < numLevels - 1) ? levels[n + 1] : 0xFF; + count++; + if (count < maxCount && curLen == nextLen) + continue; + + if (count < minCount) + for(int i = 0; i < count; i++) + WRITE_HF(curLen); + else if (curLen != 0) + { + if (curLen != prevLen) + { + WRITE_HF(curLen); + count--; + } + WRITE_HF(kTableLevelRepNumber); + m_OutStream.WriteBits(count - 3, 2); + } + else if (count <= 10) + { + WRITE_HF(kTableLevel0Number); + m_OutStream.WriteBits(count - 3, 3); + } + else + { + WRITE_HF(kTableLevel0Number2); + m_OutStream.WriteBits(count - 11, 7); + } + + count = 0; + prevLen = curLen; + + if (nextLen == 0) + { + maxCount = 138; + minCount = 3; + } + else if (curLen == nextLen) + { + maxCount = 6; + minCount = 3; + } + else + { + maxCount = 7; + minCount = 4; + } + } +} + +NO_INLINE void CCoder::MakeTables() +{ + Huffman_Generate(mainFreqs, mainCodes, m_NewLevels.litLenLevels, kFixedMainTableSize, kMaxCodeBitLength); + Huffman_Generate(distFreqs, distCodes, m_NewLevels.distLevels, kDistTableSize64, kMaxCodeBitLength); +} + +NO_INLINE UInt32 Huffman_GetPrice(const UInt32 *freqs, const Byte *lens, UInt32 num) +{ + UInt32 price = 0; + UInt32 i; + for (i = 0; i < num; i++) + price += lens[i] * freqs[i]; + return price; +}; + +NO_INLINE UInt32 Huffman_GetPrice_Spec(const UInt32 *freqs, const Byte *lens, UInt32 num, const Byte *extraBits, UInt32 extraBase) +{ + return Huffman_GetPrice(freqs, lens, num) + + Huffman_GetPrice(freqs + extraBase, extraBits, num - extraBase); +} + +NO_INLINE UInt32 CCoder::GetLzBlockPrice() const +{ + return + Huffman_GetPrice_Spec(mainFreqs, m_NewLevels.litLenLevels, kFixedMainTableSize, m_LenDirectBits, kSymbolMatch) + + Huffman_GetPrice_Spec(distFreqs, m_NewLevels.distLevels, kDistTableSize64, kDistDirectBits, 0); +} + +NO_INLINE void CCoder::TryBlock() +{ + memset(mainFreqs, 0, sizeof(mainFreqs)); + memset(distFreqs, 0, sizeof(distFreqs)); + + m_ValueIndex = 0; + UInt32 blockSize = BlockSizeRes; + BlockSizeRes = 0; + for (;;) + { + if (m_OptimumCurrentIndex == m_OptimumEndIndex) + { + if (m_Pos >= kMatchArrayLimit || BlockSizeRes >= blockSize || !m_SecondPass && + ((Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) == 0) || m_ValueIndex >= m_ValueBlockSize)) + break; + } + UInt32 pos; + UInt32 len = GetOptimal(pos); + CCodeValue &codeValue = m_Values[m_ValueIndex++]; + if (len >= kMatchMinLen) + { + UInt32 newLen = len - kMatchMinLen; + codeValue.Len = (UInt16)newLen; + mainFreqs[kSymbolMatch + g_LenSlots[newLen]]++; + codeValue.Pos = (UInt16)pos; + distFreqs[GetPosSlot(pos)]++; + } + else + { + Byte b = Inline_MatchFinder_GetIndexByte(&_lzInWindow, 0 - m_AdditionalOffset); + mainFreqs[b]++; + codeValue.SetAsLiteral(); + codeValue.Pos = b; + } + m_AdditionalOffset -= len; + BlockSizeRes += len; + } + mainFreqs[kSymbolEndOfBlock]++; + m_AdditionalOffset += BlockSizeRes; + m_SecondPass = true; +} + +NO_INLINE void CCoder::SetPrices(const CLevels &levels) +{ + UInt32 i; + for(i = 0; i < 256; i++) + { + Byte price = levels.litLenLevels[i]; + m_LiteralPrices[i] = ((price != 0) ? price : kNoLiteralStatPrice); + } + + for(i = 0; i < m_NumLenCombinations; i++) + { + UInt32 slot = g_LenSlots[i]; + Byte price = levels.litLenLevels[kSymbolMatch + slot]; + m_LenPrices[i] = (Byte)(((price != 0) ? price : kNoLenStatPrice) + m_LenDirectBits[slot]); + } + + for(i = 0; i < kDistTableSize64; i++) + { + Byte price = levels.distLevels[i]; + m_PosPrices[i] = (Byte)(((price != 0) ? price: kNoPosStatPrice) + kDistDirectBits[i]); + } +} + +NO_INLINE void Huffman_ReverseBits(UInt32 *codes, const Byte *lens, UInt32 num) +{ + for (UInt32 i = 0; i < num; i++) + { + UInt32 x = codes[i]; + x = ((x & 0x5555) << 1) | ((x & 0xAAAA) >> 1); + x = ((x & 0x3333) << 2) | ((x & 0xCCCC) >> 2); + x = ((x & 0x0F0F) << 4) | ((x & 0xF0F0) >> 4); + codes[i] = (((x & 0x00FF) << 8) | ((x & 0xFF00) >> 8)) >> (16 - lens[i]); + } +} + +NO_INLINE void CCoder::WriteBlock() +{ + Huffman_ReverseBits(mainCodes, m_NewLevels.litLenLevels, kFixedMainTableSize); + Huffman_ReverseBits(distCodes, m_NewLevels.distLevels, kDistTableSize64); + + for (UInt32 i = 0; i < m_ValueIndex; i++) + { + const CCodeValue &codeValue = m_Values[i]; + if (codeValue.IsLiteral()) + WRITE_HF2(mainCodes, m_NewLevels.litLenLevels, codeValue.Pos); + else + { + UInt32 len = codeValue.Len; + UInt32 lenSlot = g_LenSlots[len]; + WRITE_HF2(mainCodes, m_NewLevels.litLenLevels, kSymbolMatch + lenSlot); + m_OutStream.WriteBits(len - m_LenStart[lenSlot], m_LenDirectBits[lenSlot]); + UInt32 dist = codeValue.Pos; + UInt32 posSlot = GetPosSlot(dist); + WRITE_HF2(distCodes, m_NewLevels.distLevels, posSlot); + m_OutStream.WriteBits(dist - kDistStart[posSlot], kDistDirectBits[posSlot]); + } + } + WRITE_HF2(mainCodes, m_NewLevels.litLenLevels, kSymbolEndOfBlock); +} + +static UInt32 GetStorePrice(UInt32 blockSize, int bitPosition) +{ + UInt32 price = 0; + do + { + UInt32 nextBitPosition = (bitPosition + kFinalBlockFieldSize + kBlockTypeFieldSize) & 7; + int numBitsForAlign = nextBitPosition > 0 ? (8 - nextBitPosition): 0; + UInt32 curBlockSize = (blockSize < (1 << 16)) ? blockSize : (1 << 16) - 1; + price += kFinalBlockFieldSize + kBlockTypeFieldSize + numBitsForAlign + (2 + 2) * 8 + curBlockSize * 8; + bitPosition = 0; + blockSize -= curBlockSize; + } + while(blockSize != 0); + return price; +} + +void CCoder::WriteStoreBlock(UInt32 blockSize, UInt32 additionalOffset, bool finalBlock) +{ + do + { + UInt32 curBlockSize = (blockSize < (1 << 16)) ? blockSize : (1 << 16) - 1; + blockSize -= curBlockSize; + m_OutStream.WriteBits((finalBlock && (blockSize == 0) ? NFinalBlockField::kFinalBlock: NFinalBlockField::kNotFinalBlock), kFinalBlockFieldSize); + m_OutStream.WriteBits(NBlockType::kStored, kBlockTypeFieldSize); + m_OutStream.FlushByte(); + m_OutStream.WriteBits((UInt16)curBlockSize, kStoredBlockLengthFieldSize); + m_OutStream.WriteBits((UInt16)~curBlockSize, kStoredBlockLengthFieldSize); + const Byte *data = Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow)- additionalOffset; + for(UInt32 i = 0; i < curBlockSize; i++) + m_OutStream.WriteByte(data[i]); + additionalOffset -= curBlockSize; + } + while(blockSize != 0); +} + +NO_INLINE UInt32 CCoder::TryDynBlock(int tableIndex, UInt32 numPasses) +{ + CTables &t = m_Tables[tableIndex]; + BlockSizeRes = t.BlockSizeRes; + UInt32 posTemp = t.m_Pos; + SetPrices(t); + + for (UInt32 p = 0; p < numPasses; p++) + { + m_Pos = posTemp; + TryBlock(); + MakeTables(); + SetPrices(m_NewLevels); + } + + (CLevels &)t = m_NewLevels; + + m_NumLitLenLevels = kMainTableSize; + while(m_NumLitLenLevels > kNumLitLenCodesMin && m_NewLevels.litLenLevels[m_NumLitLenLevels - 1] == 0) + m_NumLitLenLevels--; + + m_NumDistLevels = kDistTableSize64; + while(m_NumDistLevels > kNumDistCodesMin && m_NewLevels.distLevels[m_NumDistLevels - 1] == 0) + m_NumDistLevels--; + + UInt32 levelFreqs[kLevelTableSize]; + memset(levelFreqs, 0, sizeof(levelFreqs)); + + LevelTableDummy(m_NewLevels.litLenLevels, m_NumLitLenLevels, levelFreqs); + LevelTableDummy(m_NewLevels.distLevels, m_NumDistLevels, levelFreqs); + + Huffman_Generate(levelFreqs, levelCodes, levelLens, kLevelTableSize, kMaxLevelBitLength); + + m_NumLevelCodes = kNumLevelCodesMin; + for (UInt32 i = 0; i < kLevelTableSize; i++) + { + Byte level = levelLens[kCodeLengthAlphabetOrder[i]]; + if (level > 0 && i >= m_NumLevelCodes) + m_NumLevelCodes = i + 1; + m_LevelLevels[i] = level; + } + + return GetLzBlockPrice() + + Huffman_GetPrice_Spec(levelFreqs, levelLens, kLevelTableSize, kLevelDirectBits, kTableDirectLevels) + + kNumLenCodesFieldSize + kNumDistCodesFieldSize + kNumLevelCodesFieldSize + + m_NumLevelCodes * kLevelFieldSize + kFinalBlockFieldSize + kBlockTypeFieldSize; +} + +NO_INLINE UInt32 CCoder::TryFixedBlock(int tableIndex) +{ + CTables &t = m_Tables[tableIndex]; + BlockSizeRes = t.BlockSizeRes; + m_Pos = t.m_Pos; + m_NewLevels.SetFixedLevels(); + SetPrices(m_NewLevels); + TryBlock(); + return kFinalBlockFieldSize + kBlockTypeFieldSize + GetLzBlockPrice(); +} + +NO_INLINE UInt32 CCoder::GetBlockPrice(int tableIndex, int numDivPasses) +{ + CTables &t = m_Tables[tableIndex]; + t.StaticMode = false; + UInt32 price = TryDynBlock(tableIndex, m_NumPasses); + t.BlockSizeRes = BlockSizeRes; + UInt32 numValues = m_ValueIndex; + UInt32 posTemp = m_Pos; + UInt32 additionalOffsetEnd = m_AdditionalOffset; + + if (m_CheckStatic && m_ValueIndex <= kFixedHuffmanCodeBlockSizeMax) + { + const UInt32 fixedPrice = TryFixedBlock(tableIndex); + t.StaticMode = (fixedPrice < price); + if (t.StaticMode) + price = fixedPrice; + } + + const UInt32 storePrice = GetStorePrice(BlockSizeRes, 0); // bitPosition + t.StoreMode = (storePrice <= price); + if (t.StoreMode) + price = storePrice; + + t.UseSubBlocks = false; + + if (numDivPasses > 1 && numValues >= kDivideCodeBlockSizeMin) + { + CTables &t0 = m_Tables[(tableIndex << 1)]; + (CLevels &)t0 = t; + t0.BlockSizeRes = t.BlockSizeRes >> 1; + t0.m_Pos = t.m_Pos; + UInt32 subPrice = GetBlockPrice((tableIndex << 1), numDivPasses - 1); + + UInt32 blockSize2 = t.BlockSizeRes - t0.BlockSizeRes; + if (t0.BlockSizeRes >= kDivideBlockSizeMin && blockSize2 >= kDivideBlockSizeMin) + { + CTables &t1 = m_Tables[(tableIndex << 1) + 1]; + (CLevels &)t1 = t; + t1.BlockSizeRes = blockSize2; + t1.m_Pos = m_Pos; + m_AdditionalOffset -= t0.BlockSizeRes; + subPrice += GetBlockPrice((tableIndex << 1) + 1, numDivPasses - 1); + t.UseSubBlocks = (subPrice < price); + if (t.UseSubBlocks) + price = subPrice; + } + } + m_AdditionalOffset = additionalOffsetEnd; + m_Pos = posTemp; + return price; +} + +void CCoder::CodeBlock(int tableIndex, bool finalBlock) +{ + CTables &t = m_Tables[tableIndex]; + if (t.UseSubBlocks) + { + CodeBlock((tableIndex << 1), false); + CodeBlock((tableIndex << 1) + 1, finalBlock); + } + else + { + if (t.StoreMode) + WriteStoreBlock(t.BlockSizeRes, m_AdditionalOffset, finalBlock); + else + { + m_OutStream.WriteBits((finalBlock ? NFinalBlockField::kFinalBlock: NFinalBlockField::kNotFinalBlock), kFinalBlockFieldSize); + if (t.StaticMode) + { + m_OutStream.WriteBits(NBlockType::kFixedHuffman, kBlockTypeFieldSize); + TryFixedBlock(tableIndex); + int i; + for (i = 0; i < kFixedMainTableSize; i++) + mainFreqs[i] = (UInt32)1 << (kNumHuffmanBits - m_NewLevels.litLenLevels[i]); + for (i = 0; i < kFixedDistTableSize; i++) + distFreqs[i] = (UInt32)1 << (kNumHuffmanBits - m_NewLevels.distLevels[i]); + MakeTables(); + } + else + { + if (m_NumDivPasses > 1 || m_CheckStatic) + TryDynBlock(tableIndex, 1); + m_OutStream.WriteBits(NBlockType::kDynamicHuffman, kBlockTypeFieldSize); + m_OutStream.WriteBits(m_NumLitLenLevels - kNumLitLenCodesMin, kNumLenCodesFieldSize); + m_OutStream.WriteBits(m_NumDistLevels - kNumDistCodesMin, kNumDistCodesFieldSize); + m_OutStream.WriteBits(m_NumLevelCodes - kNumLevelCodesMin, kNumLevelCodesFieldSize); + + for (UInt32 i = 0; i < m_NumLevelCodes; i++) + m_OutStream.WriteBits(m_LevelLevels[i], kLevelFieldSize); + + Huffman_ReverseBits(levelCodes, levelLens, kLevelTableSize); + LevelTableCode(m_NewLevels.litLenLevels, m_NumLitLenLevels, levelLens, levelCodes); + LevelTableCode(m_NewLevels.distLevels, m_NumDistLevels, levelLens, levelCodes); + } + WriteBlock(); + } + m_AdditionalOffset -= t.BlockSizeRes; + } +} + +HRes Read(void *object, void *data, UInt32 size, UInt32 *processedSize) +{ + return (HRes)((CSeqInStream *)object)->RealStream->Read(data, size, processedSize); +} + +HRESULT CCoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 * /* inSize */ , const UInt64 * /* outSize */ , + ICompressProgressInfo *progress) +{ + m_CheckStatic = (m_NumPasses != 1 || m_NumDivPasses != 1); + m_IsMultiPass = (m_CheckStatic || (m_NumPasses != 1 || m_NumDivPasses != 1)); + + RINOK(Create()); + + m_ValueBlockSize = (1 << 13) + (1 << 12) * m_NumDivPasses; + + UInt64 nowPos = 0; + + _seqInStream.RealStream = inStream; + _seqInStream.SeqInStream.Read = Read; + _lzInWindow.stream = &_seqInStream.SeqInStream; + + MatchFinder_Init(&_lzInWindow); + m_OutStream.SetStream(outStream); + m_OutStream.Init(); + + CCoderReleaser coderReleaser(this); + + m_OptimumEndIndex = m_OptimumCurrentIndex = 0; + + CTables &t = m_Tables[1]; + t.m_Pos = 0; + t.InitStructures(); + + m_AdditionalOffset = 0; + do + { + t.BlockSizeRes = kBlockUncompressedSizeThreshold; + m_SecondPass = false; + GetBlockPrice(1, m_NumDivPasses); + CodeBlock(1, Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) == 0); + nowPos += m_Tables[1].BlockSizeRes; + if (progress != NULL) + { + UInt64 packSize = m_OutStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&nowPos, &packSize)); + } + } + while (Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) != 0); + if (_lzInWindow.result != SZ_OK) + return _lzInWindow.result; + return m_OutStream.Flush(); +} + +HRESULT CCoder::BaseCode(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const COutBufferException &e) { return e.ErrorCode; } + catch(...) { return E_FAIL; } +} + +STDMETHODIMP CCOMCoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) + { return BaseCode(inStream, outStream, inSize, outSize, progress); } + +STDMETHODIMP CCOMCoder::SetCoderProperties(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties) + { return BaseSetEncoderProperties2(propIDs, properties, numProperties); } + +STDMETHODIMP CCOMCoder64::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) + { return BaseCode(inStream, outStream, inSize, outSize, progress); } + +STDMETHODIMP CCOMCoder64::SetCoderProperties(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties) + { return BaseSetEncoderProperties2(propIDs, properties, numProperties); } + +}}} + diff --git a/CPP/7zip/Compress/Deflate/DeflateEncoder.h b/CPP/7zip/Compress/Deflate/DeflateEncoder.h new file mode 100755 index 00000000..86eede6f --- /dev/null +++ b/CPP/7zip/Compress/Deflate/DeflateEncoder.h @@ -0,0 +1,221 @@ +// DeflateEncoder.h + +#ifndef __DEFLATE_ENCODER_H +#define __DEFLATE_ENCODER_H + +#include "Common/MyCom.h" + +#include "../../ICoder.h" +#include "../../Common/LSBFEncoder.h" + +#include "DeflateConst.h" + +extern "C" +{ + #include "../../../../C/Compress/Lz/MatchFinder.h" +} + +namespace NCompress { +namespace NDeflate { +namespace NEncoder { + +struct CCodeValue +{ + UInt16 Len; + UInt16 Pos; + void SetAsLiteral() { Len = (1 << 15); } + bool IsLiteral() const { return ((Len & (1 << 15)) != 0); } +}; + +struct COptimal +{ + UInt32 Price; + UInt16 PosPrev; + UInt16 BackPrev; +}; + +const UInt32 kNumOptsBase = 1 << 12; +const UInt32 kNumOpts = kNumOptsBase + kMatchMaxLen; + +class CCoder; + +struct CTables: public CLevels +{ + bool UseSubBlocks; + bool StoreMode; + bool StaticMode; + UInt32 BlockSizeRes; + UInt32 m_Pos; + void InitStructures(); +}; + +typedef struct _CSeqInStream +{ + ISeqInStream SeqInStream; + CMyComPtr RealStream; +} CSeqInStream; + +class CCoder +{ + CMatchFinder _lzInWindow; + NStream::NLSBF::CEncoder m_OutStream; + + CSeqInStream _seqInStream; + +public: + CCodeValue *m_Values; + + UInt16 *m_MatchDistances; + UInt32 m_NumFastBytes; + + UInt16 *m_OnePosMatchesMemory; + UInt16 *m_DistanceMemory; + + UInt32 m_Pos; + + int m_NumPasses; + int m_NumDivPasses; + bool m_CheckStatic; + bool m_IsMultiPass; + UInt32 m_ValueBlockSize; + + UInt32 m_NumLenCombinations; + UInt32 m_MatchMaxLen; + const Byte *m_LenStart; + const Byte *m_LenDirectBits; + + bool m_Created; + bool m_Deflate64Mode; + + Byte m_LevelLevels[kLevelTableSize]; + int m_NumLitLenLevels; + int m_NumDistLevels; + UInt32 m_NumLevelCodes; + UInt32 m_ValueIndex; + + bool m_SecondPass; + UInt32 m_AdditionalOffset; + + UInt32 m_OptimumEndIndex; + UInt32 m_OptimumCurrentIndex; + + Byte m_LiteralPrices[256]; + Byte m_LenPrices[kNumLenSymbolsMax]; + Byte m_PosPrices[kDistTableSize64]; + + CLevels m_NewLevels; + UInt32 mainFreqs[kFixedMainTableSize]; + UInt32 distFreqs[kDistTableSize64]; + UInt32 mainCodes[kFixedMainTableSize]; + UInt32 distCodes[kDistTableSize64]; + UInt32 levelCodes[kLevelTableSize]; + Byte levelLens[kLevelTableSize]; + + UInt32 BlockSizeRes; + + CTables *m_Tables; + COptimal m_Optimum[kNumOpts]; + + UInt32 m_MatchFinderCycles; + // IMatchFinderSetNumPasses *m_SetMfPasses; + + void GetMatches(); + void MovePos(UInt32 num); + UInt32 Backward(UInt32 &backRes, UInt32 cur); + UInt32 GetOptimal(UInt32 &backRes); + + void LevelTableDummy(const Byte *levels, int numLevels, UInt32 *freqs); + void LevelTableCode(const Byte *levels, int numLevels, const Byte *lens, const UInt32 *codes); + + void MakeTables(); + UInt32 GetLzBlockPrice() const; + void TryBlock(); + UInt32 TryDynBlock(int tableIndex, UInt32 numPasses); + + UInt32 TryFixedBlock(int tableIndex); + + void SetPrices(const CLevels &levels); + void WriteBlock(); + + HRESULT Create(); + void Free(); + + void WriteStoreBlock(UInt32 blockSize, UInt32 additionalOffset, bool finalBlock); + void WriteTables(bool writeMode, bool finalBlock); + + void WriteBlockData(bool writeMode, bool finalBlock); + + void ReleaseStreams() + { + _seqInStream.RealStream.Release(); + m_OutStream.ReleaseStream(); + } + class CCoderReleaser + { + CCoder *m_Coder; + public: + CCoderReleaser(CCoder *coder): m_Coder(coder) {} + ~CCoderReleaser() { m_Coder->ReleaseStreams(); } + }; + friend class CCoderReleaser; + + UInt32 GetBlockPrice(int tableIndex, int numDivPasses); + void CodeBlock(int tableIndex, bool finalBlock); + +public: + CCoder(bool deflate64Mode = false); + ~CCoder(); + + HRESULT CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + HRESULT BaseCode(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + // ICompressSetCoderProperties + HRESULT BaseSetEncoderProperties2(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties); +}; + +/////////////////////////////////////////////////////////////// + +class CCOMCoder : + public ICompressCoder, + public ICompressSetCoderProperties, + public CMyUnknownImp, + public CCoder +{ +public: + MY_UNKNOWN_IMP1(ICompressSetCoderProperties) + CCOMCoder(): CCoder(false) {}; + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + // ICompressSetCoderProperties + STDMETHOD(SetCoderProperties)(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties); +}; + +class CCOMCoder64 : + public ICompressCoder, + public ICompressSetCoderProperties, + public CMyUnknownImp, + public CCoder +{ +public: + MY_UNKNOWN_IMP1(ICompressSetCoderProperties) + CCOMCoder64(): CCoder(true) {}; + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + // ICompressSetCoderProperties + STDMETHOD(SetCoderProperties)(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties); +}; + + +}}} + +#endif diff --git a/CPP/7zip/Compress/Deflate/DllExports.cpp b/CPP/7zip/Compress/Deflate/DllExports.cpp new file mode 100755 index 00000000..a0b23562 --- /dev/null +++ b/CPP/7zip/Compress/Deflate/DllExports.cpp @@ -0,0 +1,157 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" + +#include "DeflateEncoder.h" +#include "DeflateDecoder.h" + +#ifdef CRC_GENERATE_TABLE +extern "C" +{ + #include "../../../../C/7zCrc.h" +} +#endif + +// {23170F69-40C1-278B-0401-080000000000} +DEFINE_GUID(CLSID_CCompressDeflateDecoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00); + +// {23170F69-40C1-278B-0401-090000000000} +DEFINE_GUID(CLSID_CCompressDeflate64Decoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00); + +// {23170F69-40C1-278B-0401-080000000100} +DEFINE_GUID(CLSID_CCompressDeflateEncoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00); + +// {23170F69-40C1-278B-0401-090000000100} +DEFINE_GUID(CLSID_CCompressDeflate64Encoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00); + + +// {23170F69-40C1-278B-0409-010000000000} +DEFINE_GUID(CLSID_CCompressDeflateNsisDecoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD dwReason, LPVOID /*lpReserved*/) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + #ifdef CRC_GENERATE_TABLE + CrcGenerateTable(); + #endif + } + return TRUE; +} + +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + int correctInterface = (*iid == IID_ICompressCoder); + CMyComPtr coder; + if (*clsid == CLSID_CCompressDeflateDecoder) + { + if (!correctInterface) + return E_NOINTERFACE; + coder = (ICompressCoder *)new NCompress::NDeflate::NDecoder::CCOMCoder(); + } + else if (*clsid == CLSID_CCompressDeflateNsisDecoder) + { + if (!correctInterface) + return E_NOINTERFACE; + coder = (ICompressCoder *)new NCompress::NDeflate::NDecoder::CNsisCOMCoder(); + } + else if (*clsid == CLSID_CCompressDeflateEncoder) + { + if (!correctInterface) + return E_NOINTERFACE; + coder = (ICompressCoder *)new NCompress::NDeflate::NEncoder::CCOMCoder(); + } + else if (*clsid == CLSID_CCompressDeflate64Decoder) + { + if (!correctInterface) + return E_NOINTERFACE; + coder = (ICompressCoder *)new NCompress::NDeflate::NDecoder::CCOMCoder64(); + } + else if (*clsid == CLSID_CCompressDeflate64Encoder) + { + if (!correctInterface) + return E_NOINTERFACE; + coder = (ICompressCoder *)new NCompress::NDeflate::NEncoder::CCOMCoder64(); + } + else + return CLASS_E_CLASSNOTAVAILABLE; + *outObject = coder.Detach(); + COM_TRY_END + return S_OK; +} + +struct CDeflateMethodItem +{ + char ID[3]; + const wchar_t *UserName; + const GUID *Decoder; + const GUID *Encoder; +}; + +#define METHOD_ITEM(Name, id, UserName) \ + { { 0x04, 0x01, id }, UserName, \ + &CLSID_CCompress ## Name ## Decoder, \ + &CLSID_CCompress ## Name ## Encoder } + +#define METHOD_ITEM_DE(Name, id1, id2, UserName) \ + { { 0x04, id1, id2 }, UserName, \ + &CLSID_CCompress ## Name ## Decoder, NULL } + + +static CDeflateMethodItem g_Methods[] = +{ + METHOD_ITEM(Deflate, 0x08, L"Deflate"), + METHOD_ITEM(Deflate64, 0x09, L"Deflate64"), + METHOD_ITEM_DE(DeflateNsis, 0x09, 0x01, L"DeflateNSIS") +}; + +STDAPI GetNumberOfMethods(UINT32 *numMethods) +{ + *numMethods = sizeof(g_Methods) / sizeof(g_Methods[0]); + return S_OK; +} + +STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +{ + if (index > sizeof(g_Methods) / sizeof(g_Methods[0])) + return E_INVALIDARG; + VariantClear((tagVARIANT *)value); + const CDeflateMethodItem &method = g_Methods[index]; + switch(propID) + { + case NMethodPropID::kID: + if ((value->bstrVal = ::SysAllocStringByteLen(method.ID, + sizeof(method.ID))) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kName: + if ((value->bstrVal = ::SysAllocString(method.UserName)) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kDecoder: + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)method.Decoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kEncoder: + if (method.Encoder) + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)method.Encoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + } + return S_OK; + } + return S_OK; +} diff --git a/CPP/7zip/Compress/Deflate/StdAfx.cpp b/CPP/7zip/Compress/Deflate/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Compress/Deflate/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Compress/Deflate/StdAfx.h b/CPP/7zip/Compress/Deflate/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Compress/Deflate/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Compress/Deflate/makefile b/CPP/7zip/Compress/Deflate/makefile new file mode 100755 index 00000000..c533d7cc --- /dev/null +++ b/CPP/7zip/Compress/Deflate/makefile @@ -0,0 +1,63 @@ +PROG = Deflate.dll +DEF_FILE = ../Codec.def +CFLAGS = $(CFLAGS) -I ../../../ -D_ST_MODE +LIBS = $(LIBS) oleaut32.lib + +DEFLATE_OBJS = \ + $O\DllExports.obj \ + +DEFLATE_OPT_OBJS = \ + $O\DeflateDecoder.obj \ + $O\DeflateEncoder.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CRC.obj \ + +7ZIP_COMMON_OBJS = \ + $O\InBuffer.obj \ + $O\OutBuffer.obj \ + $O\LSBFDecoder.obj \ + $O\LSBFEncoder.obj \ + +LZ_OBJS = \ + $O\LZOutWindow.obj \ + +C_OBJS = \ + $O\7zCrc.obj \ + $O\Sort.obj \ + +C_LZ_OBJS = \ + $O\MatchFinder.obj \ + + +OBJS = \ + $O\StdAfx.obj \ + $(DEFLATE_OBJS) \ + $(DEFLATE_OPT_OBJS) \ + $(COMMON_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(LZ_OBJS) \ + $(C_OBJS) \ + $(C_LZ_OBJS) \ + $O\HuffmanEncode.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(DEFLATE_OBJS): $(*B).cpp + $(COMPL) +$(DEFLATE_OPT_OBJS): $(*B).cpp + $(COMPL_O2) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(LZ_OBJS): ../LZ/$(*B).cpp + $(COMPL) +$(C_OBJS): ../../../../C/$(*B).c + $(COMPL_O2) +$(C_LZ_OBJS): ../../../../C/Compress/Lz/$(*B).c + $(COMPL_O2) +$O\HuffmanEncode.obj: ../../../../C/Compress/Huffman/$(*B).c + $(COMPL_O2) diff --git a/CPP/7zip/Compress/Deflate/resource.rc b/CPP/7zip/Compress/Deflate/resource.rc new file mode 100755 index 00000000..910bc281 --- /dev/null +++ b/CPP/7zip/Compress/Deflate/resource.rc @@ -0,0 +1,3 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("Deflate Codec", "Deflate") diff --git a/CPP/7zip/Compress/Huffman/HuffmanDecoder.h b/CPP/7zip/Compress/Huffman/HuffmanDecoder.h new file mode 100755 index 00000000..57115197 --- /dev/null +++ b/CPP/7zip/Compress/Huffman/HuffmanDecoder.h @@ -0,0 +1,88 @@ +// Compress/HuffmanDecoder.h + +#ifndef __COMPRESS_HUFFMANDECODER_H +#define __COMPRESS_HUFFMANDECODER_H + +#include "../../../Common/Types.h" + +namespace NCompress { +namespace NHuffman { + +const int kNumTableBits = 9; + +template +class CDecoder +{ + UInt32 m_Limits[kNumBitsMax + 1]; // m_Limits[i] = value limit for symbols with length = i + UInt32 m_Positions[kNumBitsMax + 1]; // m_Positions[i] = index in m_Symbols[] of first symbol with length = i + UInt32 m_Symbols[m_NumSymbols]; + Byte m_Lengths[1 << kNumTableBits]; // Table oh length for short codes. + +public: + + bool SetCodeLengths(const Byte *codeLengths) + { + int lenCounts[kNumBitsMax + 1], tmpPositions[kNumBitsMax + 1]; + int i; + for(i = 1; i <= kNumBitsMax; i++) + lenCounts[i] = 0; + UInt32 symbol; + for (symbol = 0; symbol < m_NumSymbols; symbol++) + { + int len = codeLengths[symbol]; + if (len > kNumBitsMax) + return false; + lenCounts[len]++; + m_Symbols[symbol] = 0xFFFFFFFF; + } + lenCounts[0] = 0; + m_Positions[0] = m_Limits[0] = 0; + UInt32 startPos = 0; + UInt32 index = 0; + const UInt32 kMaxValue = (1 << kNumBitsMax); + for (i = 1; i <= kNumBitsMax; i++) + { + startPos += lenCounts[i] << (kNumBitsMax - i); + if (startPos > kMaxValue) + return false; + m_Limits[i] = (i == kNumBitsMax) ? kMaxValue : startPos; + m_Positions[i] = m_Positions[i - 1] + lenCounts[i - 1]; + tmpPositions[i] = m_Positions[i]; + if(i <= kNumTableBits) + { + UInt32 limit = (m_Limits[i] >> (kNumBitsMax - kNumTableBits)); + for (; index < limit; index++) + m_Lengths[index] = (Byte)i; + } + } + for (symbol = 0; symbol < m_NumSymbols; symbol++) + { + int len = codeLengths[symbol]; + if (len != 0) + m_Symbols[tmpPositions[len]++] = symbol; + } + return true; + } + + template + UInt32 DecodeSymbol(TBitDecoder *bitStream) + { + int numBits; + UInt32 value = bitStream->GetValue(kNumBitsMax); + if (value < m_Limits[kNumTableBits]) + numBits = m_Lengths[value >> (kNumBitsMax - kNumTableBits)]; + else + for (numBits = kNumTableBits + 1; value >= m_Limits[numBits]; numBits++); + bitStream->MovePos(numBits); + UInt32 index = m_Positions[numBits] + + ((value - m_Limits[numBits - 1]) >> (kNumBitsMax - numBits)); + if (index >= m_NumSymbols) + // throw CDecoderException(); // test it + return 0xFFFFFFFF; + return m_Symbols[index]; + } +}; + +}} + +#endif diff --git a/CPP/7zip/Compress/Huffman/StdAfx.h b/CPP/7zip/Compress/Huffman/StdAfx.h new file mode 100755 index 00000000..b637fd40 --- /dev/null +++ b/CPP/7zip/Compress/Huffman/StdAfx.h @@ -0,0 +1,6 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#endif diff --git a/CPP/7zip/Compress/Implode/DllExports.cpp b/CPP/7zip/Compress/Implode/DllExports.cpp new file mode 100755 index 00000000..ff8cbe64 --- /dev/null +++ b/CPP/7zip/Compress/Implode/DllExports.cpp @@ -0,0 +1,65 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "ImplodeDecoder.h" + +// {23170F69-40C1-278B-0401-060000000000} +DEFINE_GUID(CLSID_CCompressImplodeDecoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +{ + return TRUE; +} + +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + if (*clsid != CLSID_CCompressImplodeDecoder) + return CLASS_E_CLASSNOTAVAILABLE; + if (*iid != IID_ICompressCoder) + return E_NOINTERFACE; + CMyComPtr coder = (ICompressCoder *)new + NCompress::NImplode::NDecoder::CCoder; + *outObject = coder.Detach(); + COM_TRY_END + return S_OK; +} + +STDAPI GetNumberOfMethods(UINT32 *numMethods) +{ + *numMethods = 1; + return S_OK; +} + +STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +{ + if (index != 0) + return E_INVALIDARG; + ::VariantClear((tagVARIANT *)value); + switch(propID) + { + case NMethodPropID::kID: + { + const char id[] = { 0x04, 0x01, 0x06 }; + if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NMethodPropID::kName: + if ((value->bstrVal = ::SysAllocString(L"Implode")) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kDecoder: + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CCompressImplodeDecoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + return S_OK; +} diff --git a/CPP/7zip/Compress/Implode/ImplodeDecoder.cpp b/CPP/7zip/Compress/Implode/ImplodeDecoder.cpp new file mode 100755 index 00000000..19634c5c --- /dev/null +++ b/CPP/7zip/Compress/Implode/ImplodeDecoder.cpp @@ -0,0 +1,222 @@ +// Implode/Decoder.cpp + +#include "StdAfx.h" + +#include "ImplodeDecoder.h" +#include "Common/Defs.h" + +namespace NCompress { +namespace NImplode { +namespace NDecoder { + +class CException +{ +public: + enum ECauseType + { + kData + } m_Cause; + CException(ECauseType cause): m_Cause(cause) {} +}; + +static const int kNumDistanceLowDirectBitsForBigDict = 7; +static const int kNumDistanceLowDirectBitsForSmallDict = 6; + +static const int kNumBitsInByte = 8; + +static const int kLevelStructuresNumberFieldSize = kNumBitsInByte; +static const int kLevelStructuresNumberAdditionalValue = 1; + +static const int kNumLevelStructureLevelBits = 4; +static const int kLevelStructureLevelAdditionalValue = 1; + +static const int kNumLevelStructureRepNumberBits = 4; +static const int kLevelStructureRepNumberAdditionalValue = 1; + + +static const int kLiteralTableSize = (1 << kNumBitsInByte); +static const int kDistanceTableSize = 64; +static const int kLengthTableSize = 64; + +static const UInt32 kHistorySize = + (1 << MyMax(kNumDistanceLowDirectBitsForBigDict, + kNumDistanceLowDirectBitsForSmallDict)) * + kDistanceTableSize; // = 8 KB; + +static const int kNumAdditionalLengthBits = 8; + +static const UInt32 kMatchMinLenWhenLiteralsOn = 3; +static const UInt32 kMatchMinLenWhenLiteralsOff = 2; + +static const UInt32 kMatchMinLenMax = MyMax(kMatchMinLenWhenLiteralsOn, + kMatchMinLenWhenLiteralsOff); // 3 + +static const UInt32 kMatchMaxLenMax = kMatchMinLenMax + + (kLengthTableSize - 1) + (1 << kNumAdditionalLengthBits) - 1; // or 2 + +enum +{ + kMatchId = 0, + kLiteralId = 1 +}; + + +CCoder::CCoder(): + m_LiteralDecoder(kLiteralTableSize), + m_LengthDecoder(kLengthTableSize), + m_DistanceDecoder(kDistanceTableSize) +{ +} + +void CCoder::ReleaseStreams() +{ + m_OutWindowStream.ReleaseStream(); + m_InBitStream.ReleaseStream(); +} + +bool CCoder::ReadLevelItems(NImplode::NHuffman::CDecoder &decoder, + Byte *levels, int numLevelItems) +{ + int numCodedStructures = m_InBitStream.ReadBits(kNumBitsInByte) + + kLevelStructuresNumberAdditionalValue; + int currentIndex = 0; + for(int i = 0; i < numCodedStructures; i++) + { + int level = m_InBitStream.ReadBits(kNumLevelStructureLevelBits) + + kLevelStructureLevelAdditionalValue; + int rep = m_InBitStream.ReadBits(kNumLevelStructureRepNumberBits) + + kLevelStructureRepNumberAdditionalValue; + if (currentIndex + rep > numLevelItems) + throw CException(CException::kData); + for(int j = 0; j < rep; j++) + levels[currentIndex++] = (Byte)level; + } + if (currentIndex != numLevelItems) + return false; + return decoder.SetCodeLengths(levels); +} + + +bool CCoder::ReadTables(void) +{ + if (m_LiteralsOn) + { + Byte literalLevels[kLiteralTableSize]; + if (!ReadLevelItems(m_LiteralDecoder, literalLevels, kLiteralTableSize)) + return false; + } + + Byte lengthLevels[kLengthTableSize]; + if (!ReadLevelItems(m_LengthDecoder, lengthLevels, kLengthTableSize)) + return false; + + Byte distanceLevels[kDistanceTableSize]; + return ReadLevelItems(m_DistanceDecoder, distanceLevels, kDistanceTableSize); +} + +class CCoderReleaser +{ + CCoder *m_Coder; +public: + CCoderReleaser(CCoder *coder): m_Coder(coder) {} + ~CCoderReleaser() { m_Coder->ReleaseStreams(); } +}; + +STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + if (!m_InBitStream.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!m_OutWindowStream.Create(kHistorySize)) + return E_OUTOFMEMORY; + if (outSize == NULL) + return E_INVALIDARG; + UInt64 pos = 0, unPackSize = *outSize; + + m_OutWindowStream.SetStream(outStream); + m_OutWindowStream.Init(false); + m_InBitStream.SetStream(inStream); + m_InBitStream.Init(); + CCoderReleaser coderReleaser(this); + + if (!ReadTables()) + return S_FALSE; + + while(pos < unPackSize) + { + if (progress != NULL && pos % (1 << 16) == 0) + { + UInt64 packSize = m_InBitStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &pos)); + } + if(m_InBitStream.ReadBits(1) == kMatchId) // match + { + UInt32 lowDistBits = m_InBitStream.ReadBits(m_NumDistanceLowDirectBits); + UInt32 distance = m_DistanceDecoder.DecodeSymbol(&m_InBitStream); + if (distance >= kDistanceTableSize) + return S_FALSE; + distance = (distance << m_NumDistanceLowDirectBits) + lowDistBits; + UInt32 lengthSymbol = m_LengthDecoder.DecodeSymbol(&m_InBitStream); + if (lengthSymbol >= kLengthTableSize) + return S_FALSE; + UInt32 length = lengthSymbol + m_MinMatchLength; + if (lengthSymbol == kLengthTableSize - 1) // special symbol = 63 + length += m_InBitStream.ReadBits(kNumAdditionalLengthBits); + while(distance >= pos && length > 0) + { + m_OutWindowStream.PutByte(0); + pos++; + length--; + } + if (length > 0) + m_OutWindowStream.CopyBlock(distance, length); + pos += length; + } + else + { + Byte b; + if (m_LiteralsOn) + { + UInt32 temp = m_LiteralDecoder.DecodeSymbol(&m_InBitStream); + if (temp >= kLiteralTableSize) + return S_FALSE; + b = (Byte)temp; + } + else + b = (Byte)m_InBitStream.ReadBits(kNumBitsInByte); + m_OutWindowStream.PutByte(b); + pos++; + } + } + if (pos > unPackSize) + throw CException(CException::kData); + return m_OutWindowStream.Flush(); +} + +STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const CLZOutWindowException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +STDMETHODIMP CCoder::SetDecoderProperties2(const Byte *data, UInt32 size) +{ + if (size < 1) + return E_INVALIDARG; + Byte flag = data[0]; + m_BigDictionaryOn = ((flag & 2) != 0); + m_NumDistanceLowDirectBits = m_BigDictionaryOn ? + kNumDistanceLowDirectBitsForBigDict: + kNumDistanceLowDirectBitsForSmallDict; + m_LiteralsOn = ((flag & 4) != 0); + m_MinMatchLength = m_LiteralsOn ? + kMatchMinLenWhenLiteralsOn : + kMatchMinLenWhenLiteralsOff; + return S_OK; +} + +}}} diff --git a/CPP/7zip/Compress/Implode/ImplodeDecoder.h b/CPP/7zip/Compress/Implode/ImplodeDecoder.h new file mode 100755 index 00000000..627edba4 --- /dev/null +++ b/CPP/7zip/Compress/Implode/ImplodeDecoder.h @@ -0,0 +1,60 @@ +// ImplodeDecoder.h + +#ifndef __IMPLODE_DECODER_H +#define __IMPLODE_DECODER_H + +#include "../../../Common/MyCom.h" + +#include "../../ICoder.h" +#include "../LZ/LZOutWindow.h" + +#include "ImplodeHuffmanDecoder.h" + +namespace NCompress { +namespace NImplode { +namespace NDecoder { + +class CCoder : + public ICompressCoder, + public ICompressSetDecoderProperties2, + public CMyUnknownImp +{ + CLZOutWindow m_OutWindowStream; + NStream::NLSBF::CDecoder m_InBitStream; + + NImplode::NHuffman::CDecoder m_LiteralDecoder; + NImplode::NHuffman::CDecoder m_LengthDecoder; + NImplode::NHuffman::CDecoder m_DistanceDecoder; + + bool m_BigDictionaryOn; + bool m_LiteralsOn; + + int m_NumDistanceLowDirectBits; + UInt32 m_MinMatchLength; + + bool ReadLevelItems(NImplode::NHuffman::CDecoder &table, Byte *levels, int numLevelItems); + bool ReadTables(); + void DeCodeLevelTable(Byte *newLevels, int numLevels); +public: + CCoder(); + + MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) + + void ReleaseStreams(); + HRESULT (Flush)() { return m_OutWindowStream.Flush(); } + + STDMETHOD(CodeReal)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + // ICompressSetDecoderProperties + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); +}; + +}}} + +#endif diff --git a/CPP/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp b/CPP/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp new file mode 100755 index 00000000..ad2061c3 --- /dev/null +++ b/CPP/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp @@ -0,0 +1,89 @@ +// ImplodeHuffmanDecoder.cpp + +#include "StdAfx.h" + +#include "ImplodeHuffmanDecoder.h" + +namespace NCompress { +namespace NImplode { +namespace NHuffman { + +CDecoder::CDecoder(UInt32 numSymbols): + m_NumSymbols(numSymbols) +{ + m_Symbols = new UInt32[m_NumSymbols]; +} + +CDecoder::~CDecoder() +{ + delete []m_Symbols; +} + +bool CDecoder::SetCodeLengths(const Byte *codeLengths) +{ + // int lenCounts[kNumBitsInLongestCode + 1], tmpPositions[kNumBitsInLongestCode + 1]; + int lenCounts[kNumBitsInLongestCode + 2], tmpPositions[kNumBitsInLongestCode + 1]; + int i; + for(i = 0; i <= kNumBitsInLongestCode; i++) + lenCounts[i] = 0; + UInt32 symbolIndex; + for (symbolIndex = 0; symbolIndex < m_NumSymbols; symbolIndex++) + lenCounts[codeLengths[symbolIndex]]++; + // lenCounts[0] = 0; + + // tmpPositions[0] = m_Positions[0] = m_Limitits[0] = 0; + m_Limitits[kNumBitsInLongestCode + 1] = 0; + m_Positions[kNumBitsInLongestCode + 1] = 0; + lenCounts[kNumBitsInLongestCode + 1] = 0; + + + UInt32 startPos = 0; + static const UInt32 kMaxValue = (1 << kNumBitsInLongestCode); + + for (i = kNumBitsInLongestCode; i > 0; i--) + { + startPos += lenCounts[i] << (kNumBitsInLongestCode - i); + if (startPos > kMaxValue) + return false; + m_Limitits[i] = startPos; + m_Positions[i] = m_Positions[i + 1] + lenCounts[i + 1]; + tmpPositions[i] = m_Positions[i] + lenCounts[i]; + + } + + // if _ZIP_MODE do not throw exception for trees containing only one node + // #ifndef _ZIP_MODE + if (startPos != kMaxValue) + return false; + // #endif + + for (symbolIndex = 0; symbolIndex < m_NumSymbols; symbolIndex++) + if (codeLengths[symbolIndex] != 0) + m_Symbols[--tmpPositions[codeLengths[symbolIndex]]] = symbolIndex; + return true; +} + +UInt32 CDecoder::DecodeSymbol(CInBit *inStream) +{ + UInt32 numBits = 0; + UInt32 value = inStream->GetValue(kNumBitsInLongestCode); + int i; + for(i = kNumBitsInLongestCode; i > 0; i--) + { + if (value < m_Limitits[i]) + { + numBits = i; + break; + } + } + if (i == 0) + return 0xFFFFFFFF; + inStream->MovePos(numBits); + UInt32 index = m_Positions[numBits] + + ((value - m_Limitits[numBits + 1]) >> (kNumBitsInLongestCode - numBits)); + if (index >= m_NumSymbols) + return 0xFFFFFFFF; + return m_Symbols[index]; +} + +}}} diff --git a/CPP/7zip/Compress/Implode/ImplodeHuffmanDecoder.h b/CPP/7zip/Compress/Implode/ImplodeHuffmanDecoder.h new file mode 100755 index 00000000..9f7aeca1 --- /dev/null +++ b/CPP/7zip/Compress/Implode/ImplodeHuffmanDecoder.h @@ -0,0 +1,33 @@ +// ImplodeHuffmanDecoder.h + +#ifndef __IMPLODE_HUFFMAN_DECODER_H +#define __IMPLODE_HUFFMAN_DECODER_H + +#include "../../Common/LSBFDecoder.h" +#include "../../Common/InBuffer.h" + +namespace NCompress { +namespace NImplode { +namespace NHuffman { + +const int kNumBitsInLongestCode = 16; + +typedef NStream::NLSBF::CDecoder CInBit; + +class CDecoder +{ + UInt32 m_Limitits[kNumBitsInLongestCode + 2]; // m_Limitits[i] = value limit for symbols with length = i + UInt32 m_Positions[kNumBitsInLongestCode + 2]; // m_Positions[i] = index in m_Symbols[] of first symbol with length = i + UInt32 m_NumSymbols; // number of symbols in m_Symbols + UInt32 *m_Symbols; // symbols: at first with len=1 then 2, ... 15. +public: + CDecoder(UInt32 numSymbols); + ~CDecoder(); + + bool SetCodeLengths(const Byte *codeLengths); + UInt32 DecodeSymbol(CInBit *inStream); +}; + +}}} + +#endif diff --git a/CPP/7zip/Compress/Implode/StdAfx.cpp b/CPP/7zip/Compress/Implode/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Compress/Implode/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Compress/Implode/StdAfx.h b/CPP/7zip/Compress/Implode/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Compress/Implode/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Compress/LZ/LZOutWindow.cpp b/CPP/7zip/Compress/LZ/LZOutWindow.cpp new file mode 100755 index 00000000..e2d6aba1 --- /dev/null +++ b/CPP/7zip/Compress/LZ/LZOutWindow.cpp @@ -0,0 +1,17 @@ +// LZOutWindow.cpp + +#include "StdAfx.h" + +#include "../../../Common/Alloc.h" +#include "LZOutWindow.h" + +void CLZOutWindow::Init(bool solid) +{ + if(!solid) + COutBuffer::Init(); + #ifdef _NO_EXCEPTIONS + ErrorCode = S_OK; + #endif +} + + diff --git a/CPP/7zip/Compress/LZ/LZOutWindow.h b/CPP/7zip/Compress/LZ/LZOutWindow.h new file mode 100755 index 00000000..3c50c6e7 --- /dev/null +++ b/CPP/7zip/Compress/LZ/LZOutWindow.h @@ -0,0 +1,56 @@ +// LZOutWindow.h + +#ifndef __LZ_OUT_WINDOW_H +#define __LZ_OUT_WINDOW_H + +#include "../../IStream.h" +#include "../../Common/OutBuffer.h" + +#ifndef _NO_EXCEPTIONS +typedef COutBufferException CLZOutWindowException; +#endif + +class CLZOutWindow: public COutBuffer +{ +public: + void Init(bool solid = false); + + // distance >= 0, len > 0, + bool CopyBlock(UInt32 distance, UInt32 len) + { + UInt32 pos = _pos - distance - 1; + if (distance >= _pos) + { + if (!_overDict || distance >= _bufferSize) + return false; + pos += _bufferSize; + } + do + { + if (pos == _bufferSize) + pos = 0; + _buffer[_pos++] = _buffer[pos++]; + if (_pos == _limitPos) + FlushWithCheck(); + } + while(--len != 0); + return true; + } + + void PutByte(Byte b) + { + _buffer[_pos++] = b; + if (_pos == _limitPos) + FlushWithCheck(); + } + + Byte GetByte(UInt32 distance) const + { + UInt32 pos = _pos - distance - 1; + if (pos >= _bufferSize) + pos += _bufferSize; + return _buffer[pos]; + } +}; + +#endif diff --git a/CPP/7zip/Compress/LZ/StdAfx.h b/CPP/7zip/Compress/LZ/StdAfx.h new file mode 100755 index 00000000..3ff6d8a2 --- /dev/null +++ b/CPP/7zip/Compress/LZ/StdAfx.h @@ -0,0 +1,6 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#endif diff --git a/CPP/7zip/Compress/LZMA/DllExports.cpp b/CPP/7zip/Compress/LZMA/DllExports.cpp new file mode 100755 index 00000000..1fc65b84 --- /dev/null +++ b/CPP/7zip/Compress/LZMA/DllExports.cpp @@ -0,0 +1,109 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "../../../Common/MyInitGuid.h" +#include "../../../Common/ComTry.h" +#ifdef _WIN32 +#include "../../../Common/Alloc.h" +#endif + +#include "LZMAEncoder.h" +#include "LZMADecoder.h" + +#ifdef CRC_GENERATE_TABLE +extern "C" +{ + #include "../../../../C/7zCrc.h" +} +#endif + +// {23170F69-40C1-278B-0301-010000000000} +DEFINE_GUID(CLSID_CLZMADecoder, +0x23170F69, 0x40C1, 0x278B, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00); + +// {23170F69-40C1-278B-0301-010000000100} +DEFINE_GUID(CLSID_CLZMAEncoder, +0x23170F69, 0x40C1, 0x278B, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD dwReason, LPVOID /*lpReserved*/) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + // NCompress::NRangeCoder::g_PriceTables.Init(); + #ifdef CRC_GENERATE_TABLE + CrcGenerateTable(); + #endif + #ifdef _WIN32 + SetLargePageSize(); + #endif + } + return TRUE; +} + +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) +{ + // NCompress::NRangeCoder::g_PriceTables.Init(); + // CCRC::InitTable(); + COM_TRY_BEGIN + *outObject = 0; + int correctInterface = (*iid == IID_ICompressCoder); + CMyComPtr coder; + if (*clsid == CLSID_CLZMADecoder) + { + if (!correctInterface) + return E_NOINTERFACE; + coder = (ICompressCoder *)new NCompress::NLZMA::CDecoder(); + } + else if (*clsid == CLSID_CLZMAEncoder) + { + if (!correctInterface) + return E_NOINTERFACE; + coder = (ICompressCoder *)new NCompress::NLZMA::CEncoder(); + } + else + return CLASS_E_CLASSNOTAVAILABLE; + *outObject = coder.Detach(); + COM_TRY_END + return S_OK; +} + +STDAPI GetNumberOfMethods(UINT32 *numMethods) +{ + *numMethods = 1; + return S_OK; +} + +STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +{ + if (index != 0) + return E_INVALIDARG; + // ::VariantClear((tagVARIANT *)value); + switch(propID) + { + case NMethodPropID::kID: + { + const char id[] = { 0x03, 0x01, 0x01 }; + if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NMethodPropID::kName: + if ((value->bstrVal = ::SysAllocString(L"LZMA")) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kDecoder: + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CLZMADecoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kEncoder: + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CLZMAEncoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + return S_OK; +} + diff --git a/CPP/7zip/Compress/LZMA/LZMA.dsp b/CPP/7zip/Compress/LZMA/LZMA.dsp new file mode 100755 index 00000000..3d51f1ff --- /dev/null +++ b/CPP/7zip/Compress/LZMA/LZMA.dsp @@ -0,0 +1,478 @@ +# Microsoft Developer Studio Project File - Name="LZMA" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=LZMA - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "LZMA.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "LZMA.mak" CFG="LZMA - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "LZMA - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "LZMA - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "LZMA - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMA_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMA_EXPORTS" /D "COMPRESS_MF_MT" /D "_ST_MODE" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-zip\Codecs\LZMA.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none /debug + +!ELSEIF "$(CFG)" == "LZMA - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMA_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "../../../" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMA_EXPORTS" /D "COMPRESS_MF_MT" /D "_ST_MODE" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-zip\Codecs\LZMA.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "LZMA - Win32 Release" +# Name "LZMA - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Codec.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "7-zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "RangeCoder" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\RangeCoder\RangeCoder.h +# End Source File +# Begin Source File + +SOURCE=..\RangeCoder\RangeCoderBit.cpp +# End Source File +# Begin Source File + +SOURCE=..\RangeCoder\RangeCoderBit.h +# End Source File +# Begin Source File + +SOURCE=..\RangeCoder\RangeCoderBitTree.h +# End Source File +# Begin Source File + +SOURCE=..\RangeCoder\RangeCoderOpt.h +# End Source File +# End Group +# Begin Group "Interface" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\MatchFinders\IMatchFinder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IStream.h +# End Source File +# End Group +# Begin Group "LZ" + +# PROP Default_Filter "" +# Begin Group "BT" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree2.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree3.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTree4.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTreeBase.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTreeD.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTreeD4.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTreeDMain.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTreeMain.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTreeR.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTreeR4.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\BinTree\BinTreeRMain.h +# End Source File +# End Group +# Begin Group "HC" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\LZ\HashChain\HC4.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\HashChain\HCMain.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\LZ\IMatchFinder.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\LZInWindow.h +# End Source File +# Begin Source File + +SOURCE=..\LZ\LZOutWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\LZ\LZOutWindow.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\AlignedBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\AlignedBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ComTry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Exception.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyUnknown.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Handle.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Thread.h +# End Source File +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Group "C_Lz" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Lz\LzHash.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.c + +!IF "$(CFG)" == "LZMA - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "LZMA - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Lz\MatchFinderMt.c + +!IF "$(CFG)" == "LZMA - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "LZMA - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Lz\MatchFinderMt.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.c + +!IF "$(CFG)" == "LZMA - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "LZMA - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\IStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Types.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\LZMA.h +# End Source File +# Begin Source File + +SOURCE=.\LZMADecoder.cpp + +!IF "$(CFG)" == "LZMA - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "LZMA - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\LZMADecoder.h +# End Source File +# Begin Source File + +SOURCE=.\LZMAEncoder.cpp + +!IF "$(CFG)" == "LZMA - Win32 Release" + +# ADD CPP /O2 /FAs +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "LZMA - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\LZMAEncoder.h +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/Compress/LZMA/LZMA.dsw b/CPP/7zip/Compress/LZMA/LZMA.dsw new file mode 100755 index 00000000..f750e453 --- /dev/null +++ b/CPP/7zip/Compress/LZMA/LZMA.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "LZMA"=".\LZMA.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Compress/LZMA/LZMA.h b/CPP/7zip/Compress/LZMA/LZMA.h new file mode 100755 index 00000000..7bc4c438 --- /dev/null +++ b/CPP/7zip/Compress/LZMA/LZMA.h @@ -0,0 +1,82 @@ +// LZMA.h + +#ifndef __LZMA_H +#define __LZMA_H + +namespace NCompress { +namespace NLZMA { + +const UInt32 kNumRepDistances = 4; + +const int kNumStates = 12; + +const Byte kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; +const Byte kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; +const Byte kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; +const Byte kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; + +class CState +{ +public: + Byte Index; + void Init() { Index = 0; } + void UpdateChar() { Index = kLiteralNextStates[Index]; } + void UpdateMatch() { Index = kMatchNextStates[Index]; } + void UpdateRep() { Index = kRepNextStates[Index]; } + void UpdateShortRep() { Index = kShortRepNextStates[Index]; } + bool IsCharState() const { return Index < 7; } +}; + +const int kNumPosSlotBits = 6; +const int kDicLogSizeMin = 0; +const int kDicLogSizeMax = 32; +const int kDistTableSizeMax = kDicLogSizeMax * 2; + +const UInt32 kNumLenToPosStates = 4; + +inline UInt32 GetLenToPosState(UInt32 len) +{ + len -= 2; + if (len < kNumLenToPosStates) + return len; + return kNumLenToPosStates - 1; +} + +namespace NLength { + +const int kNumPosStatesBitsMax = 4; +const UInt32 kNumPosStatesMax = (1 << kNumPosStatesBitsMax); + +const int kNumPosStatesBitsEncodingMax = 4; +const UInt32 kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax); + +const int kNumLowBits = 3; +const int kNumMidBits = 3; +const int kNumHighBits = 8; +const UInt32 kNumLowSymbols = 1 << kNumLowBits; +const UInt32 kNumMidSymbols = 1 << kNumMidBits; +const UInt32 kNumSymbolsTotal = kNumLowSymbols + kNumMidSymbols + (1 << kNumHighBits); + +} + +const UInt32 kMatchMinLen = 2; +const UInt32 kMatchMaxLen = kMatchMinLen + NLength::kNumSymbolsTotal - 1; + +const int kNumAlignBits = 4; +const UInt32 kAlignTableSize = 1 << kNumAlignBits; +const UInt32 kAlignMask = (kAlignTableSize - 1); + +const UInt32 kStartPosModelIndex = 4; +const UInt32 kEndPosModelIndex = 14; +const UInt32 kNumPosModels = kEndPosModelIndex - kStartPosModelIndex; + +const UInt32 kNumFullDistances = 1 << (kEndPosModelIndex / 2); + +const int kNumLitPosStatesBitsEncodingMax = 4; +const int kNumLitContextBitsMax = 8; + +const int kNumMoveBits = 5; + +}} + +#endif diff --git a/CPP/7zip/Compress/LZMA/LZMADecoder.cpp b/CPP/7zip/Compress/LZMA/LZMADecoder.cpp new file mode 100755 index 00000000..75de2245 --- /dev/null +++ b/CPP/7zip/Compress/LZMA/LZMADecoder.cpp @@ -0,0 +1,338 @@ +// LZMADecoder.cpp + +#include "StdAfx.h" + +#include "LZMADecoder.h" +#include "../../../Common/Defs.h" + +namespace NCompress { +namespace NLZMA { + +const int kLenIdFinished = -1; +const int kLenIdNeedInit = -2; + +void CDecoder::Init() +{ + { + for(int i = 0; i < kNumStates; i++) + { + for (UInt32 j = 0; j <= _posStateMask; j++) + { + _isMatch[i][j].Init(); + _isRep0Long[i][j].Init(); + } + _isRep[i].Init(); + _isRepG0[i].Init(); + _isRepG1[i].Init(); + _isRepG2[i].Init(); + } + } + { + for (UInt32 i = 0; i < kNumLenToPosStates; i++) + _posSlotDecoder[i].Init(); + } + { + for(UInt32 i = 0; i < kNumFullDistances - kEndPosModelIndex; i++) + _posDecoders[i].Init(); + } + _posAlignDecoder.Init(); + _lenDecoder.Init(_posStateMask + 1); + _repMatchLenDecoder.Init(_posStateMask + 1); + _literalDecoder.Init(); + + _state.Init(); + _reps[0] = _reps[1] = _reps[2] = _reps[3] = 0; +} + +HRESULT CDecoder::CodeSpec(UInt32 curSize) +{ + if (_outSizeDefined) + { + const UInt64 rem = _outSize - _outWindowStream.GetProcessedSize(); + if (curSize > rem) + curSize = (UInt32)rem; + } + + if (_remainLen == kLenIdFinished) + return S_OK; + if (_remainLen == kLenIdNeedInit) + { + _rangeDecoder.Init(); + Init(); + _remainLen = 0; + } + if (curSize == 0) + return S_OK; + + UInt32 rep0 = _reps[0]; + UInt32 rep1 = _reps[1]; + UInt32 rep2 = _reps[2]; + UInt32 rep3 = _reps[3]; + CState state = _state; + Byte previousByte; + + while(_remainLen > 0 && curSize > 0) + { + previousByte = _outWindowStream.GetByte(rep0); + _outWindowStream.PutByte(previousByte); + _remainLen--; + curSize--; + } + UInt64 nowPos64 = _outWindowStream.GetProcessedSize(); + if (nowPos64 == 0) + previousByte = 0; + else + previousByte = _outWindowStream.GetByte(0); + + while(curSize > 0) + { + { + #ifdef _NO_EXCEPTIONS + if (_rangeDecoder.Stream.ErrorCode != S_OK) + return _rangeDecoder.Stream.ErrorCode; + #endif + if (_rangeDecoder.Stream.WasFinished()) + return S_FALSE; + UInt32 posState = UInt32(nowPos64) & _posStateMask; + if (_isMatch[state.Index][posState].Decode(&_rangeDecoder) == 0) + { + if(!state.IsCharState()) + previousByte = _literalDecoder.DecodeWithMatchByte(&_rangeDecoder, + (UInt32)nowPos64, previousByte, _outWindowStream.GetByte(rep0)); + else + previousByte = _literalDecoder.DecodeNormal(&_rangeDecoder, + (UInt32)nowPos64, previousByte); + _outWindowStream.PutByte(previousByte); + state.UpdateChar(); + curSize--; + nowPos64++; + } + else + { + UInt32 len; + if(_isRep[state.Index].Decode(&_rangeDecoder) == 1) + { + len = 0; + if(_isRepG0[state.Index].Decode(&_rangeDecoder) == 0) + { + if(_isRep0Long[state.Index][posState].Decode(&_rangeDecoder) == 0) + { + state.UpdateShortRep(); + len = 1; + } + } + else + { + UInt32 distance; + if(_isRepG1[state.Index].Decode(&_rangeDecoder) == 0) + distance = rep1; + else + { + if (_isRepG2[state.Index].Decode(&_rangeDecoder) == 0) + distance = rep2; + else + { + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + if (len == 0) + { + len = _repMatchLenDecoder.Decode(&_rangeDecoder, posState) + kMatchMinLen; + state.UpdateRep(); + } + } + else + { + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + len = kMatchMinLen + _lenDecoder.Decode(&_rangeDecoder, posState); + state.UpdateMatch(); + UInt32 posSlot = _posSlotDecoder[GetLenToPosState(len)].Decode(&_rangeDecoder); + if (posSlot >= kStartPosModelIndex) + { + UInt32 numDirectBits = (posSlot >> 1) - 1; + rep0 = ((2 | (posSlot & 1)) << numDirectBits); + + if (posSlot < kEndPosModelIndex) + rep0 += NRangeCoder::ReverseBitTreeDecode(_posDecoders + + rep0 - posSlot - 1, &_rangeDecoder, numDirectBits); + else + { + rep0 += (_rangeDecoder.DecodeDirectBits( + numDirectBits - kNumAlignBits) << kNumAlignBits); + rep0 += _posAlignDecoder.ReverseDecode(&_rangeDecoder); + if (rep0 == 0xFFFFFFFF) + { + _remainLen = kLenIdFinished; + return S_OK; + } + } + } + else + rep0 = posSlot; + } + UInt32 locLen = len; + if (len > curSize) + locLen = (UInt32)curSize; + if (!_outWindowStream.CopyBlock(rep0, locLen)) + return S_FALSE; + previousByte = _outWindowStream.GetByte(0); + curSize -= locLen; + nowPos64 += locLen; + len -= locLen; + if (len != 0) + { + _remainLen = (Int32)len; + break; + } + + #ifdef _NO_EXCEPTIONS + if (_outWindowStream.ErrorCode != S_OK) + return _outWindowStream.ErrorCode; + #endif + } + } + } + if (_rangeDecoder.Stream.WasFinished()) + return S_FALSE; + _reps[0] = rep0; + _reps[1] = rep1; + _reps[2] = rep2; + _reps[3] = rep3; + _state = state; + + return S_OK; +} + +STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + SetInStream(inStream); + _outWindowStream.SetStream(outStream); + SetOutStreamSize(outSize); + CDecoderFlusher flusher(this); + + for (;;) + { + UInt32 curSize = 1 << 18; + RINOK(CodeSpec(curSize)); + if (_remainLen == kLenIdFinished) + break; + if (progress != NULL) + { + UInt64 inSize = _rangeDecoder.GetProcessedSize(); + UInt64 nowPos64 = _outWindowStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&inSize, &nowPos64)); + } + if (_outSizeDefined) + if (_outWindowStream.GetProcessedSize() >= _outSize) + break; + } + flusher.NeedFlush = false; + return Flush(); +} + + +#ifdef _NO_EXCEPTIONS + +#define LZMA_TRY_BEGIN +#define LZMA_TRY_END + +#else + +#define LZMA_TRY_BEGIN try { +#define LZMA_TRY_END } \ + catch(const CInBufferException &e) { return e.ErrorCode; } \ + catch(const CLZOutWindowException &e) { return e.ErrorCode; } \ + catch(...) { return S_FALSE; } + +#endif + + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + LZMA_TRY_BEGIN + return CodeReal(inStream, outStream, inSize, outSize, progress); + LZMA_TRY_END +} + +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *properties, UInt32 size) +{ + if (size < 5) + return E_INVALIDARG; + int lc = properties[0] % 9; + Byte remainder = (Byte)(properties[0] / 9); + int lp = remainder % 5; + int pb = remainder / 5; + if (pb > NLength::kNumPosStatesBitsMax) + return E_INVALIDARG; + _posStateMask = (1 << pb) - 1; + UInt32 dictionarySize = 0; + for (int i = 0; i < 4; i++) + dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8); + if (!_outWindowStream.Create(dictionarySize)) + return E_OUTOFMEMORY; + if (!_literalDecoder.Create(lp, lc)) + return E_OUTOFMEMORY; + if (!_rangeDecoder.Create(1 << 20)) + return E_OUTOFMEMORY; + return S_OK; +} + +STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) +{ + *value = _rangeDecoder.GetProcessedSize(); + return S_OK; +} + +STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) +{ + _rangeDecoder.SetStream(inStream); + return S_OK; +} + +STDMETHODIMP CDecoder::ReleaseInStream() +{ + _rangeDecoder.ReleaseStream(); + return S_OK; +} + +STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) +{ + _outSizeDefined = (outSize != NULL); + if (_outSizeDefined) + _outSize = *outSize; + _remainLen = kLenIdNeedInit; + _outWindowStream.Init(); + return S_OK; +} + +#ifdef _ST_MODE + +STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + LZMA_TRY_BEGIN + if (processedSize) + *processedSize = 0; + const UInt64 startPos = _outWindowStream.GetProcessedSize(); + _outWindowStream.SetMemStream((Byte *)data); + RINOK(CodeSpec(size)); + if (processedSize) + *processedSize = (UInt32)(_outWindowStream.GetProcessedSize() - startPos); + return Flush(); + LZMA_TRY_END +} + +#endif + +}} diff --git a/CPP/7zip/Compress/LZMA/LZMADecoder.h b/CPP/7zip/Compress/LZMA/LZMADecoder.h new file mode 100755 index 00000000..1c10409f --- /dev/null +++ b/CPP/7zip/Compress/LZMA/LZMADecoder.h @@ -0,0 +1,251 @@ +// LZMA/Decoder.h + +#ifndef __LZMA_DECODER_H +#define __LZMA_DECODER_H + +#include "../../../Common/MyCom.h" +#include "../../../Common/Alloc.h" +#include "../../ICoder.h" +#include "../LZ/LZOutWindow.h" +#include "../RangeCoder/RangeCoderBitTree.h" + +#include "LZMA.h" + +namespace NCompress { +namespace NLZMA { + +typedef NRangeCoder::CBitDecoder CMyBitDecoder; + +class CLiteralDecoder2 +{ + CMyBitDecoder _decoders[0x300]; +public: + void Init() + { + for (int i = 0; i < 0x300; i++) + _decoders[i].Init(); + } + Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder) + { + UInt32 symbol = 1; + RC_INIT_VAR + do + { + // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder); + RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol) + } + while (symbol < 0x100); + RC_FLUSH_VAR + return (Byte)symbol; + } + Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, Byte matchByte) + { + UInt32 symbol = 1; + RC_INIT_VAR + do + { + UInt32 matchBit = (matchByte >> 7) & 1; + matchByte <<= 1; + // UInt32 bit = _decoders[1 + matchBit][symbol].Decode(rangeDecoder); + // symbol = (symbol << 1) | bit; + UInt32 bit; + RC_GETBIT2(kNumMoveBits, _decoders[0x100 + (matchBit << 8) + symbol].Prob, symbol, + bit = 0, bit = 1) + if (matchBit != bit) + { + while (symbol < 0x100) + { + // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder); + RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol) + } + break; + } + } + while (symbol < 0x100); + RC_FLUSH_VAR + return (Byte)symbol; + } +}; + +class CLiteralDecoder +{ + CLiteralDecoder2 *_coders; + int _numPrevBits; + int _numPosBits; + UInt32 _posMask; +public: + CLiteralDecoder(): _coders(0) {} + ~CLiteralDecoder() { Free(); } + void Free() + { + MyFree(_coders); + _coders = 0; + } + bool Create(int numPosBits, int numPrevBits) + { + if (_coders == 0 || (numPosBits + numPrevBits) != + (_numPrevBits + _numPosBits) ) + { + Free(); + UInt32 numStates = 1 << (numPosBits + numPrevBits); + _coders = (CLiteralDecoder2 *)MyAlloc(numStates * sizeof(CLiteralDecoder2)); + } + _numPosBits = numPosBits; + _posMask = (1 << numPosBits) - 1; + _numPrevBits = numPrevBits; + return (_coders != 0); + } + void Init() + { + UInt32 numStates = 1 << (_numPrevBits + _numPosBits); + for (UInt32 i = 0; i < numStates; i++) + _coders[i].Init(); + } + UInt32 GetState(UInt32 pos, Byte prevByte) const + { return ((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits)); } + Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte) + { return _coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); } + Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte, Byte matchByte) + { return _coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); } +}; + +namespace NLength { + +class CDecoder +{ + CMyBitDecoder _choice; + CMyBitDecoder _choice2; + NRangeCoder::CBitTreeDecoder _lowCoder[kNumPosStatesMax]; + NRangeCoder::CBitTreeDecoder _midCoder[kNumPosStatesMax]; + NRangeCoder::CBitTreeDecoder _highCoder; +public: + void Init(UInt32 numPosStates) + { + _choice.Init(); + _choice2.Init(); + for (UInt32 posState = 0; posState < numPosStates; posState++) + { + _lowCoder[posState].Init(); + _midCoder[posState].Init(); + } + _highCoder.Init(); + } + UInt32 Decode(NRangeCoder::CDecoder *rangeDecoder, UInt32 posState) + { + if(_choice.Decode(rangeDecoder) == 0) + return _lowCoder[posState].Decode(rangeDecoder); + if(_choice2.Decode(rangeDecoder) == 0) + return kNumLowSymbols + _midCoder[posState].Decode(rangeDecoder); + return kNumLowSymbols + kNumMidSymbols + _highCoder.Decode(rangeDecoder); + } +}; + +} + +class CDecoder: + public ICompressCoder, + public ICompressSetDecoderProperties2, + public ICompressGetInStreamProcessedSize, + #ifdef _ST_MODE + public ICompressSetInStream, + public ICompressSetOutStreamSize, + public ISequentialInStream, + #endif + public CMyUnknownImp +{ + CLZOutWindow _outWindowStream; + NRangeCoder::CDecoder _rangeDecoder; + + CMyBitDecoder _isMatch[kNumStates][NLength::kNumPosStatesMax]; + CMyBitDecoder _isRep[kNumStates]; + CMyBitDecoder _isRepG0[kNumStates]; + CMyBitDecoder _isRepG1[kNumStates]; + CMyBitDecoder _isRepG2[kNumStates]; + CMyBitDecoder _isRep0Long[kNumStates][NLength::kNumPosStatesMax]; + + NRangeCoder::CBitTreeDecoder _posSlotDecoder[kNumLenToPosStates]; + + CMyBitDecoder _posDecoders[kNumFullDistances - kEndPosModelIndex]; + NRangeCoder::CBitTreeDecoder _posAlignDecoder; + + NLength::CDecoder _lenDecoder; + NLength::CDecoder _repMatchLenDecoder; + + CLiteralDecoder _literalDecoder; + + UInt32 _posStateMask; + + /////////////////// + // State + UInt32 _reps[4]; + CState _state; + Int32 _remainLen; // -1 means end of stream. // -2 means need Init + UInt64 _outSize; + bool _outSizeDefined; + + void Init(); + HRESULT CodeSpec(UInt32 size); +public: + + #ifdef _ST_MODE + MY_UNKNOWN_IMP5( + ICompressSetDecoderProperties2, + ICompressGetInStreamProcessedSize, + ICompressSetInStream, + ICompressSetOutStreamSize, + ISequentialInStream) + #else + MY_UNKNOWN_IMP2( + ICompressSetDecoderProperties2, + ICompressGetInStreamProcessedSize) + #endif + + void ReleaseStreams() + { + _outWindowStream.ReleaseStream(); + ReleaseInStream(); + } + + class CDecoderFlusher + { + CDecoder *_decoder; + public: + bool NeedFlush; + CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {} + ~CDecoderFlusher() + { + if (NeedFlush) + _decoder->Flush(); + _decoder->ReleaseStreams(); + } + }; + + HRESULT Flush() { return _outWindowStream.Flush(); } + + STDMETHOD(CodeReal)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + + STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); + + STDMETHOD(SetInStream)(ISequentialInStream *inStream); + STDMETHOD(ReleaseInStream)(); + STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); + + #ifdef _ST_MODE + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + #endif + + CDecoder(): _outSizeDefined(false) {} + virtual ~CDecoder() {} +}; + +}} + +#endif diff --git a/CPP/7zip/Compress/LZMA/LZMAEncoder.cpp b/CPP/7zip/Compress/LZMA/LZMAEncoder.cpp new file mode 100755 index 00000000..0589f8a1 --- /dev/null +++ b/CPP/7zip/Compress/LZMA/LZMAEncoder.cpp @@ -0,0 +1,1530 @@ +// LZMA/Encoder.cpp + +#include "StdAfx.h" + +#include + +#include "../../../Common/Defs.h" +#include "../../Common/StreamUtils.h" + +#include "LZMAEncoder.h" + +// extern "C" { #include "../../../../C/7zCrc.h" } + +// #define SHOW_STAT + + +namespace NCompress { +namespace NLZMA { + +// struct CCrcInit { CCrcInit() { InitCrcTable(); } } g_CrcInit; + +const int kDefaultDictionaryLogSize = 22; +const UInt32 kNumFastBytesDefault = 0x20; + +Byte g_FastPos[1 << 11]; + +class CFastPosInit +{ +public: + CFastPosInit() { Init(); } + void Init() + { + const Byte kFastSlots = 22; + int c = 2; + g_FastPos[0] = 0; + g_FastPos[1] = 1; + + for (Byte slotFast = 2; slotFast < kFastSlots; slotFast++) + { + UInt32 k = (1 << ((slotFast >> 1) - 1)); + for (UInt32 j = 0; j < k; j++, c++) + g_FastPos[c] = slotFast; + } + } +} g_FastPosInit; + +void CLiteralEncoder2::Encode(NRangeCoder::CEncoder *rangeEncoder, Byte symbol) +{ + UInt32 context = 1; + int i = 8; + do + { + i--; + UInt32 bit = (symbol >> i) & 1; + _encoders[context].Encode(rangeEncoder, bit); + context = (context << 1) | bit; + } + while(i != 0); +} + +void CLiteralEncoder2::EncodeMatched(NRangeCoder::CEncoder *rangeEncoder, + Byte matchByte, Byte symbol) +{ + UInt32 context = 1; + int i = 8; + do + { + i--; + UInt32 bit = (symbol >> i) & 1; + UInt32 matchBit = (matchByte >> i) & 1; + _encoders[0x100 + (matchBit << 8) + context].Encode(rangeEncoder, bit); + context = (context << 1) | bit; + if (matchBit != bit) + { + while(i != 0) + { + i--; + UInt32 bit = (symbol >> i) & 1; + _encoders[context].Encode(rangeEncoder, bit); + context = (context << 1) | bit; + } + break; + } + } + while(i != 0); +} + +UInt32 CLiteralEncoder2::GetPrice(bool matchMode, Byte matchByte, Byte symbol) const +{ + UInt32 price = 0; + UInt32 context = 1; + int i = 8; + if (matchMode) + { + do + { + i--; + UInt32 matchBit = (matchByte >> i) & 1; + UInt32 bit = (symbol >> i) & 1; + price += _encoders[0x100 + (matchBit << 8) + context].GetPrice(bit); + context = (context << 1) | bit; + if (matchBit != bit) + break; + } + while (i != 0); + } + while(i != 0) + { + i--; + UInt32 bit = (symbol >> i) & 1; + price += _encoders[context].GetPrice(bit); + context = (context << 1) | bit; + } + return price; +}; + + +namespace NLength { + +void CEncoder::Init(UInt32 numPosStates) +{ + _choice.Init(); + _choice2.Init(); + for (UInt32 posState = 0; posState < numPosStates; posState++) + { + _lowCoder[posState].Init(); + _midCoder[posState].Init(); + } + _highCoder.Init(); +} + +void CEncoder::Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState) +{ + if(symbol < kNumLowSymbols) + { + _choice.Encode(rangeEncoder, 0); + _lowCoder[posState].Encode(rangeEncoder, symbol); + } + else + { + _choice.Encode(rangeEncoder, 1); + if(symbol < kNumLowSymbols + kNumMidSymbols) + { + _choice2.Encode(rangeEncoder, 0); + _midCoder[posState].Encode(rangeEncoder, symbol - kNumLowSymbols); + } + else + { + _choice2.Encode(rangeEncoder, 1); + _highCoder.Encode(rangeEncoder, symbol - kNumLowSymbols - kNumMidSymbols); + } + } +} + +void CEncoder::SetPrices(UInt32 posState, UInt32 numSymbols, UInt32 *prices) const +{ + UInt32 a0 = _choice.GetPrice0(); + UInt32 a1 = _choice.GetPrice1(); + UInt32 b0 = a1 + _choice2.GetPrice0(); + UInt32 b1 = a1 + _choice2.GetPrice1(); + UInt32 i = 0; + for (i = 0; i < kNumLowSymbols; i++) + { + if (i >= numSymbols) + return; + prices[i] = a0 + _lowCoder[posState].GetPrice(i); + } + for (; i < kNumLowSymbols + kNumMidSymbols; i++) + { + if (i >= numSymbols) + return; + prices[i] = b0 + _midCoder[posState].GetPrice(i - kNumLowSymbols); + } + for (; i < numSymbols; i++) + prices[i] = b1 + _highCoder.GetPrice(i - kNumLowSymbols - kNumMidSymbols); +} + +} + +CEncoder::CEncoder(): + _numFastBytes(kNumFastBytesDefault), + _distTableSize(kDefaultDictionaryLogSize * 2), + _posStateBits(2), + _posStateMask(4 - 1), + _numLiteralPosStateBits(0), + _numLiteralContextBits(3), + _dictionarySize(1 << kDefaultDictionaryLogSize), + _matchFinderCycles(0), + #ifdef COMPRESS_MF_MT + _multiThread(false), + #endif + _writeEndMark(false) +{ + MatchFinder_Construct(&_matchFinderBase); + // _maxMode = false; + _fastMode = false; + #ifdef COMPRESS_MF_MT + MatchFinderMt_Construct(&_matchFinderMt); + _matchFinderMt.MatchFinder = &_matchFinderBase; + #endif +} + + +static void *SzAlloc(size_t size) { return BigAlloc(size); } +static void SzFree(void *address) { BigFree(address); } +ISzAlloc g_Alloc = { SzAlloc, SzFree }; + +CEncoder::~CEncoder() +{ + #ifdef COMPRESS_MF_MT + MatchFinderMt_Destruct(&_matchFinderMt, &g_Alloc); + #endif + MatchFinder_Free(&_matchFinderBase, &g_Alloc); +} + +static const UInt32 kBigHashDicLimit = (UInt32)1 << 24; + +HRESULT CEncoder::Create() +{ + if (!_rangeEncoder.Create(1 << 20)) + return E_OUTOFMEMORY; + bool btMode = (_matchFinderBase.btMode != 0); + #ifdef COMPRESS_MF_MT + _mtMode = (_multiThread && !_fastMode && btMode); + #endif + + if (!_literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits)) + return E_OUTOFMEMORY; + + _matchFinderBase.bigHash = (_dictionarySize > kBigHashDicLimit); + + UInt32 numCycles = 16 + (_numFastBytes >> 1); + if (!btMode) + numCycles >>= 1; + if (_matchFinderCycles != 0) + numCycles = _matchFinderCycles; + _matchFinderBase.cutValue = numCycles; + #ifdef COMPRESS_MF_MT + if (_mtMode) + { + RINOK(MatchFinderMt_Create(&_matchFinderMt, _dictionarySize, kNumOpts, _numFastBytes, kMatchMaxLen, &g_Alloc)); + _matchFinderObj = &_matchFinderMt; + MatchFinderMt_CreateVTable(&_matchFinderMt, &_matchFinder); + } + else + #endif + { + if (!MatchFinder_Create(&_matchFinderBase, _dictionarySize, kNumOpts, _numFastBytes, kMatchMaxLen, &g_Alloc)) + return E_OUTOFMEMORY; + _matchFinderObj = &_matchFinderBase; + MatchFinder_CreateVTable(&_matchFinderBase, &_matchFinder); + } + return S_OK; +} + +inline wchar_t GetUpperChar(wchar_t c) +{ + if (c >= 'a' && c <= 'z') + c -= 0x20; + return c; +} + +static int ParseMatchFinder(const wchar_t *s, int *btMode, UInt32 *numHashBytes /* , int *skipModeBits */) +{ + wchar_t c = GetUpperChar(*s++); + if (c == L'H') + { + if (GetUpperChar(*s++) != L'C') + return 0; + int numHashBytesLoc = (int)(*s++ - L'0'); + if (numHashBytesLoc < 4 || numHashBytesLoc > 4) + return 0; + if (*s++ != 0) + return 0; + *btMode = 0; + *numHashBytes = numHashBytesLoc; + return 1; + } + if (c != L'B') + return 0; + + if (GetUpperChar(*s++) != L'T') + return 0; + int numHashBytesLoc = (int)(*s++ - L'0'); + if (numHashBytesLoc < 2 || numHashBytesLoc > 4) + return 0; + c = GetUpperChar(*s++); + /* + int skipModeBitsLoc = 0; + if (c == L'D') + { + skipModeBitsLoc = 2; + c = GetUpperChar(*s++); + } + */ + if (c != L'\0') + return 0; + *btMode = 1; + *numHashBytes = numHashBytesLoc; + // *skipModeBits = skipModeBitsLoc; + return 1; +} + +STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties) +{ + for (UInt32 i = 0; i < numProperties; i++) + { + const PROPVARIANT &prop = properties[i]; + switch(propIDs[i]) + { + case NCoderPropID::kNumFastBytes: + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + UInt32 numFastBytes = prop.ulVal; + if(numFastBytes < 5 || numFastBytes > kMatchMaxLen) + return E_INVALIDARG; + _numFastBytes = numFastBytes; + break; + } + case NCoderPropID::kMatchFinderCycles: + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + _matchFinderCycles = prop.ulVal; + break; + } + case NCoderPropID::kAlgorithm: + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + UInt32 maximize = prop.ulVal; + _fastMode = (maximize == 0); + // _maxMode = (maximize >= 2); + break; + } + case NCoderPropID::kMatchFinder: + { + if (prop.vt != VT_BSTR) + return E_INVALIDARG; + if (!ParseMatchFinder(prop.bstrVal, &_matchFinderBase.btMode, &_matchFinderBase.numHashBytes /* , &_matchFinderBase.skipModeBits */)) + return E_INVALIDARG; + break; + } + #ifdef COMPRESS_MF_MT + case NCoderPropID::kMultiThread: + { + if (prop.vt != VT_BOOL) + return E_INVALIDARG; + Bool newMultiThread = (prop.boolVal == VARIANT_TRUE); + if (newMultiThread != _multiThread) + { + ReleaseMatchFinder(); + _multiThread = newMultiThread; + } + break; + } + case NCoderPropID::kNumThreads: + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + Bool newMultiThread = (prop.ulVal > 1) ? True : False; + if (newMultiThread != _multiThread) + { + ReleaseMatchFinder(); + _multiThread = newMultiThread; + } + break; + } + #endif + case NCoderPropID::kDictionarySize: + { + const int kDicLogSizeMaxCompress = 30; + if (prop.vt != VT_UI4) + return E_INVALIDARG; + UInt32 dictionarySize = prop.ulVal; + if (dictionarySize < UInt32(1 << kDicLogSizeMin) || + dictionarySize > UInt32(1 << kDicLogSizeMaxCompress)) + return E_INVALIDARG; + _dictionarySize = dictionarySize; + UInt32 dicLogSize; + for(dicLogSize = 0; dicLogSize < (UInt32)kDicLogSizeMaxCompress; dicLogSize++) + if (dictionarySize <= (UInt32(1) << dicLogSize)) + break; + _distTableSize = dicLogSize * 2; + break; + } + case NCoderPropID::kPosStateBits: + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + UInt32 value = prop.ulVal; + if (value > (UInt32)NLength::kNumPosStatesBitsEncodingMax) + return E_INVALIDARG; + _posStateBits = value; + _posStateMask = (1 << _posStateBits) - 1; + break; + } + case NCoderPropID::kLitPosBits: + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + UInt32 value = prop.ulVal; + if (value > (UInt32)kNumLitPosStatesBitsEncodingMax) + return E_INVALIDARG; + _numLiteralPosStateBits = value; + break; + } + case NCoderPropID::kLitContextBits: + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + UInt32 value = prop.ulVal; + if (value > (UInt32)kNumLitContextBitsMax) + return E_INVALIDARG; + _numLiteralContextBits = value; + break; + } + case NCoderPropID::kEndMarker: + { + if (prop.vt != VT_BOOL) + return E_INVALIDARG; + SetWriteEndMarkerMode(prop.boolVal == VARIANT_TRUE); + break; + } + default: + return E_INVALIDARG; + } + } + return S_OK; +} + +STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) +{ + const UInt32 kPropSize = 5; + Byte properties[kPropSize]; + properties[0] = (Byte)((_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits); + for (int i = 0; i < 4; i++) + properties[1 + i] = Byte(_dictionarySize >> (8 * i)); + return WriteStream(outStream, properties, kPropSize, NULL); +} + +STDMETHODIMP CEncoder::SetOutStream(ISequentialOutStream *outStream) +{ + _rangeEncoder.SetStream(outStream); + return S_OK; +} + +STDMETHODIMP CEncoder::ReleaseOutStream() +{ + _rangeEncoder.ReleaseStream(); + return S_OK; +} + +HRESULT CEncoder::Init() +{ + CBaseState::Init(); + + _rangeEncoder.Init(); + + for(int i = 0; i < kNumStates; i++) + { + for (UInt32 j = 0; j <= _posStateMask; j++) + { + _isMatch[i][j].Init(); + _isRep0Long[i][j].Init(); + } + _isRep[i].Init(); + _isRepG0[i].Init(); + _isRepG1[i].Init(); + _isRepG2[i].Init(); + } + + _literalEncoder.Init(); + + { + for(UInt32 i = 0; i < kNumLenToPosStates; i++) + _posSlotEncoder[i].Init(); + } + { + for(UInt32 i = 0; i < kNumFullDistances - kEndPosModelIndex; i++) + _posEncoders[i].Init(); + } + + _lenEncoder.Init(1 << _posStateBits); + _repMatchLenEncoder.Init(1 << _posStateBits); + + _posAlignEncoder.Init(); + + _longestMatchWasFound = false; + _optimumEndIndex = 0; + _optimumCurrentIndex = 0; + _additionalOffset = 0; + + return S_OK; +} + +#ifdef SHOW_STAT +static int ttt = 0; +#endif + +void CEncoder::MovePos(UInt32 num) +{ + #ifdef SHOW_STAT + ttt += num; + printf("\n MovePos %d", num); + #endif + if (num != 0) + { + _additionalOffset += num; + _matchFinder.Skip(_matchFinderObj, num); + } +} + +UInt32 CEncoder::Backward(UInt32 &backRes, UInt32 cur) +{ + _optimumEndIndex = cur; + UInt32 posMem = _optimum[cur].PosPrev; + UInt32 backMem = _optimum[cur].BackPrev; + do + { + if (_optimum[cur].Prev1IsChar) + { + _optimum[posMem].MakeAsChar(); + _optimum[posMem].PosPrev = posMem - 1; + if (_optimum[cur].Prev2) + { + _optimum[posMem - 1].Prev1IsChar = false; + _optimum[posMem - 1].PosPrev = _optimum[cur].PosPrev2; + _optimum[posMem - 1].BackPrev = _optimum[cur].BackPrev2; + } + } + UInt32 posPrev = posMem; + UInt32 backCur = backMem; + + backMem = _optimum[posPrev].BackPrev; + posMem = _optimum[posPrev].PosPrev; + + _optimum[posPrev].BackPrev = backCur; + _optimum[posPrev].PosPrev = cur; + cur = posPrev; + } + while(cur != 0); + backRes = _optimum[0].BackPrev; + _optimumCurrentIndex = _optimum[0].PosPrev; + return _optimumCurrentIndex; +} + +/* +Out: + (lenRes == 1) && (backRes == 0xFFFFFFFF) means Literal +*/ + +UInt32 CEncoder::GetOptimum(UInt32 position, UInt32 &backRes) +{ + if(_optimumEndIndex != _optimumCurrentIndex) + { + const COptimal &optimum = _optimum[_optimumCurrentIndex]; + UInt32 lenRes = optimum.PosPrev - _optimumCurrentIndex; + backRes = optimum.BackPrev; + _optimumCurrentIndex = optimum.PosPrev; + return lenRes; + } + _optimumCurrentIndex = _optimumEndIndex = 0; + + UInt32 numAvailableBytes = _matchFinder.GetNumAvailableBytes(_matchFinderObj); + + UInt32 lenMain, numDistancePairs; + if (!_longestMatchWasFound) + { + lenMain = ReadMatchDistances(numDistancePairs); + } + else + { + lenMain = _longestMatchLength; + numDistancePairs = _numDistancePairs; + _longestMatchWasFound = false; + } + + const Byte *data = _matchFinder.GetPointerToCurrentPos(_matchFinderObj) - 1; + if (numAvailableBytes < 2) + { + backRes = (UInt32)(-1); + return 1; + } + if (numAvailableBytes > kMatchMaxLen) + numAvailableBytes = kMatchMaxLen; + + UInt32 reps[kNumRepDistances]; + UInt32 repLens[kNumRepDistances]; + UInt32 repMaxIndex = 0; + UInt32 i; + for(i = 0; i < kNumRepDistances; i++) + { + reps[i] = _repDistances[i]; + UInt32 backOffset = reps[i] + 1; + if (data[0] != data[(size_t)0 - backOffset] || data[1] != data[(size_t)1 - backOffset]) + { + repLens[i] = 0; + continue; + } + UInt32 lenTest; + for (lenTest = 2; lenTest < numAvailableBytes && + data[lenTest] == data[(size_t)lenTest - backOffset]; lenTest++); + repLens[i] = lenTest; + if (lenTest > repLens[repMaxIndex]) + repMaxIndex = i; + } + if(repLens[repMaxIndex] >= _numFastBytes) + { + backRes = repMaxIndex; + UInt32 lenRes = repLens[repMaxIndex]; + MovePos(lenRes - 1); + return lenRes; + } + + UInt32 *matchDistances = _matchDistances; + if(lenMain >= _numFastBytes) + { + backRes = matchDistances[numDistancePairs - 1] + kNumRepDistances; + MovePos(lenMain - 1); + return lenMain; + } + Byte currentByte = *data; + Byte matchByte = data[(size_t)0 - reps[0] - 1]; + + if(lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2) + { + backRes = (UInt32)-1; + return 1; + } + + _optimum[0].State = _state; + + UInt32 posState = (position & _posStateMask); + + _optimum[1].Price = _isMatch[_state.Index][posState].GetPrice0() + + _literalEncoder.GetSubCoder(position, _previousByte)->GetPrice(!_state.IsCharState(), matchByte, currentByte); + _optimum[1].MakeAsChar(); + + UInt32 matchPrice = _isMatch[_state.Index][posState].GetPrice1(); + UInt32 repMatchPrice = matchPrice + _isRep[_state.Index].GetPrice1(); + + if(matchByte == currentByte) + { + UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState); + if(shortRepPrice < _optimum[1].Price) + { + _optimum[1].Price = shortRepPrice; + _optimum[1].MakeAsShortRep(); + } + } + UInt32 lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]); + + if(lenEnd < 2) + { + backRes = _optimum[1].BackPrev; + return 1; + } + + _optimum[1].PosPrev = 0; + for (i = 0; i < kNumRepDistances; i++) + _optimum[0].Backs[i] = reps[i]; + + UInt32 len = lenEnd; + do + _optimum[len--].Price = kIfinityPrice; + while (len >= 2); + + for(i = 0; i < kNumRepDistances; i++) + { + UInt32 repLen = repLens[i]; + if (repLen < 2) + continue; + UInt32 price = repMatchPrice + GetPureRepPrice(i, _state, posState); + do + { + UInt32 curAndLenPrice = price + _repMatchLenEncoder.GetPrice(repLen - 2, posState); + COptimal &optimum = _optimum[repLen]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = 0; + optimum.BackPrev = i; + optimum.Prev1IsChar = false; + } + } + while(--repLen >= 2); + } + + UInt32 normalMatchPrice = matchPrice + _isRep[_state.Index].GetPrice0(); + + len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); + if (len <= lenMain) + { + UInt32 offs = 0; + while (len > matchDistances[offs]) + offs += 2; + for(; ; len++) + { + UInt32 distance = matchDistances[offs + 1]; + UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(distance, len, posState); + COptimal &optimum = _optimum[len]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = 0; + optimum.BackPrev = distance + kNumRepDistances; + optimum.Prev1IsChar = false; + } + if (len == matchDistances[offs]) + { + offs += 2; + if (offs == numDistancePairs) + break; + } + } + } + + UInt32 cur = 0; + + for (;;) + { + cur++; + if(cur == lenEnd) + { + return Backward(backRes, cur); + } + UInt32 numAvailableBytesFull = _matchFinder.GetNumAvailableBytes(_matchFinderObj); + UInt32 newLen, numDistancePairs; + newLen = ReadMatchDistances(numDistancePairs); + if(newLen >= _numFastBytes) + { + _numDistancePairs = numDistancePairs; + _longestMatchLength = newLen; + _longestMatchWasFound = true; + return Backward(backRes, cur); + } + position++; + COptimal &curOptimum = _optimum[cur]; + UInt32 posPrev = curOptimum.PosPrev; + CState state; + if (curOptimum.Prev1IsChar) + { + posPrev--; + if (curOptimum.Prev2) + { + state = _optimum[curOptimum.PosPrev2].State; + if (curOptimum.BackPrev2 < kNumRepDistances) + state.UpdateRep(); + else + state.UpdateMatch(); + } + else + state = _optimum[posPrev].State; + state.UpdateChar(); + } + else + state = _optimum[posPrev].State; + if (posPrev == cur - 1) + { + if (curOptimum.IsShortRep()) + state.UpdateShortRep(); + else + state.UpdateChar(); + } + else + { + UInt32 pos; + if (curOptimum.Prev1IsChar && curOptimum.Prev2) + { + posPrev = curOptimum.PosPrev2; + pos = curOptimum.BackPrev2; + state.UpdateRep(); + } + else + { + pos = curOptimum.BackPrev; + if (pos < kNumRepDistances) + state.UpdateRep(); + else + state.UpdateMatch(); + } + const COptimal &prevOptimum = _optimum[posPrev]; + if (pos < kNumRepDistances) + { + reps[0] = prevOptimum.Backs[pos]; + UInt32 i; + for(i = 1; i <= pos; i++) + reps[i] = prevOptimum.Backs[i - 1]; + for(; i < kNumRepDistances; i++) + reps[i] = prevOptimum.Backs[i]; + } + else + { + reps[0] = (pos - kNumRepDistances); + for(UInt32 i = 1; i < kNumRepDistances; i++) + reps[i] = prevOptimum.Backs[i - 1]; + } + } + curOptimum.State = state; + for(UInt32 i = 0; i < kNumRepDistances; i++) + curOptimum.Backs[i] = reps[i]; + UInt32 curPrice = curOptimum.Price; + const Byte *data = _matchFinder.GetPointerToCurrentPos(_matchFinderObj) - 1; + const Byte currentByte = *data; + const Byte matchByte = data[(size_t)0 - reps[0] - 1]; + + UInt32 posState = (position & _posStateMask); + + UInt32 curAnd1Price = curPrice + + _isMatch[state.Index][posState].GetPrice0() + + _literalEncoder.GetSubCoder(position, data[(size_t)0 - 1])->GetPrice(!state.IsCharState(), matchByte, currentByte); + + COptimal &nextOptimum = _optimum[cur + 1]; + + bool nextIsChar = false; + if (curAnd1Price < nextOptimum.Price) + { + nextOptimum.Price = curAnd1Price; + nextOptimum.PosPrev = cur; + nextOptimum.MakeAsChar(); + nextIsChar = true; + } + + UInt32 matchPrice = curPrice + _isMatch[state.Index][posState].GetPrice1(); + UInt32 repMatchPrice = matchPrice + _isRep[state.Index].GetPrice1(); + + if(matchByte == currentByte && + !(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0)) + { + UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState); + if(shortRepPrice <= nextOptimum.Price) + { + nextOptimum.Price = shortRepPrice; + nextOptimum.PosPrev = cur; + nextOptimum.MakeAsShortRep(); + nextIsChar = true; + } + } + /* + if(newLen == 2 && matchDistances[2] >= kDistLimit2) // test it maybe set 2000 ? + continue; + */ + + numAvailableBytesFull = MyMin(kNumOpts - 1 - cur, numAvailableBytesFull); + UInt32 numAvailableBytes = numAvailableBytesFull; + + if (numAvailableBytes < 2) + continue; + if (numAvailableBytes > _numFastBytes) + numAvailableBytes = _numFastBytes; + if (!nextIsChar && matchByte != currentByte) // speed optimization + { + // try Literal + rep0 + UInt32 backOffset = reps[0] + 1; + UInt32 limit = MyMin(numAvailableBytesFull, _numFastBytes + 1); + UInt32 temp; + for (temp = 1; temp < limit && + data[temp] == data[(size_t)temp - backOffset]; temp++); + UInt32 lenTest2 = temp - 1; + if (lenTest2 >= 2) + { + CState state2 = state; + state2.UpdateChar(); + UInt32 posStateNext = (position + 1) & _posStateMask; + UInt32 nextRepMatchPrice = curAnd1Price + + _isMatch[state2.Index][posStateNext].GetPrice1() + + _isRep[state2.Index].GetPrice1(); + // for (; lenTest2 >= 2; lenTest2--) + { + UInt32 offset = cur + 1 + lenTest2; + while(lenEnd < offset) + _optimum[++lenEnd].Price = kIfinityPrice; + UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice( + 0, lenTest2, state2, posStateNext); + COptimal &optimum = _optimum[offset]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = cur + 1; + optimum.BackPrev = 0; + optimum.Prev1IsChar = true; + optimum.Prev2 = false; + } + } + } + } + + UInt32 startLen = 2; // speed optimization + for(UInt32 repIndex = 0; repIndex < kNumRepDistances; repIndex++) + { + // UInt32 repLen = _matchFinder.GetMatchLen(0 - 1, reps[repIndex], newLen); // test it; + UInt32 backOffset = reps[repIndex] + 1; + if (data[0] != data[(size_t)0 - backOffset] || + data[1] != data[(size_t)1 - backOffset]) + continue; + UInt32 lenTest; + for (lenTest = 2; lenTest < numAvailableBytes && + data[lenTest] == data[(size_t)lenTest - backOffset]; lenTest++); + while(lenEnd < cur + lenTest) + _optimum[++lenEnd].Price = kIfinityPrice; + UInt32 lenTestTemp = lenTest; + UInt32 price = repMatchPrice + GetPureRepPrice(repIndex, state, posState); + do + { + UInt32 curAndLenPrice = price + _repMatchLenEncoder.GetPrice(lenTest - 2, posState); + COptimal &optimum = _optimum[cur + lenTest]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = cur; + optimum.BackPrev = repIndex; + optimum.Prev1IsChar = false; + } + } + while(--lenTest >= 2); + lenTest = lenTestTemp; + + if (repIndex == 0) + startLen = lenTest + 1; + + // if (_maxMode) + { + UInt32 lenTest2 = lenTest + 1; + UInt32 limit = MyMin(numAvailableBytesFull, lenTest2 + _numFastBytes); + for (; lenTest2 < limit && + data[lenTest2] == data[(size_t)lenTest2 - backOffset]; lenTest2++); + lenTest2 -= lenTest + 1; + if (lenTest2 >= 2) + { + CState state2 = state; + state2.UpdateRep(); + UInt32 posStateNext = (position + lenTest) & _posStateMask; + UInt32 curAndLenCharPrice = + price + _repMatchLenEncoder.GetPrice(lenTest - 2, posState) + + _isMatch[state2.Index][posStateNext].GetPrice0() + + _literalEncoder.GetSubCoder(position + lenTest, data[(size_t)lenTest - 1])->GetPrice( + true, data[(size_t)lenTest - backOffset], data[lenTest]); + state2.UpdateChar(); + posStateNext = (position + lenTest + 1) & _posStateMask; + UInt32 nextRepMatchPrice = curAndLenCharPrice + + _isMatch[state2.Index][posStateNext].GetPrice1() + + _isRep[state2.Index].GetPrice1(); + + // for(; lenTest2 >= 2; lenTest2--) + { + UInt32 offset = cur + lenTest + 1 + lenTest2; + while(lenEnd < offset) + _optimum[++lenEnd].Price = kIfinityPrice; + UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice( + 0, lenTest2, state2, posStateNext); + COptimal &optimum = _optimum[offset]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = cur + lenTest + 1; + optimum.BackPrev = 0; + optimum.Prev1IsChar = true; + optimum.Prev2 = true; + optimum.PosPrev2 = cur; + optimum.BackPrev2 = repIndex; + } + } + } + } + } + + // for(UInt32 lenTest = 2; lenTest <= newLen; lenTest++) + if (newLen > numAvailableBytes) + { + newLen = numAvailableBytes; + for (numDistancePairs = 0; newLen > matchDistances[numDistancePairs]; numDistancePairs += 2); + matchDistances[numDistancePairs] = newLen; + numDistancePairs += 2; + } + if (newLen >= startLen) + { + UInt32 normalMatchPrice = matchPrice + _isRep[state.Index].GetPrice0(); + while(lenEnd < cur + newLen) + _optimum[++lenEnd].Price = kIfinityPrice; + + UInt32 offs = 0; + while(startLen > matchDistances[offs]) + offs += 2; + UInt32 curBack = matchDistances[offs + 1]; + UInt32 posSlot = GetPosSlot2(curBack); + for(UInt32 lenTest = /*2*/ startLen; ; lenTest++) + { + UInt32 curAndLenPrice = normalMatchPrice; + UInt32 lenToPosState = GetLenToPosState(lenTest); + if (curBack < kNumFullDistances) + curAndLenPrice += _distancesPrices[lenToPosState][curBack]; + else + curAndLenPrice += _posSlotPrices[lenToPosState][posSlot] + _alignPrices[curBack & kAlignMask]; + + curAndLenPrice += _lenEncoder.GetPrice(lenTest - kMatchMinLen, posState); + + COptimal &optimum = _optimum[cur + lenTest]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = cur; + optimum.BackPrev = curBack + kNumRepDistances; + optimum.Prev1IsChar = false; + } + + if (/*_maxMode && */lenTest == matchDistances[offs]) + { + // Try Match + Literal + Rep0 + UInt32 backOffset = curBack + 1; + UInt32 lenTest2 = lenTest + 1; + UInt32 limit = MyMin(numAvailableBytesFull, lenTest2 + _numFastBytes); + for (; lenTest2 < limit && + data[lenTest2] == data[(size_t)lenTest2 - backOffset]; lenTest2++); + lenTest2 -= lenTest + 1; + if (lenTest2 >= 2) + { + CState state2 = state; + state2.UpdateMatch(); + UInt32 posStateNext = (position + lenTest) & _posStateMask; + UInt32 curAndLenCharPrice = curAndLenPrice + + _isMatch[state2.Index][posStateNext].GetPrice0() + + _literalEncoder.GetSubCoder(position + lenTest, data[(size_t)lenTest - 1])->GetPrice( + true, data[(size_t)lenTest - backOffset], data[lenTest]); + state2.UpdateChar(); + posStateNext = (posStateNext + 1) & _posStateMask; + UInt32 nextRepMatchPrice = curAndLenCharPrice + + _isMatch[state2.Index][posStateNext].GetPrice1() + + _isRep[state2.Index].GetPrice1(); + + // for(; lenTest2 >= 2; lenTest2--) + { + UInt32 offset = cur + lenTest + 1 + lenTest2; + while(lenEnd < offset) + _optimum[++lenEnd].Price = kIfinityPrice; + UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext); + COptimal &optimum = _optimum[offset]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = cur + lenTest + 1; + optimum.BackPrev = 0; + optimum.Prev1IsChar = true; + optimum.Prev2 = true; + optimum.PosPrev2 = cur; + optimum.BackPrev2 = curBack + kNumRepDistances; + } + } + } + offs += 2; + if (offs == numDistancePairs) + break; + curBack = matchDistances[offs + 1]; + if (curBack >= kNumFullDistances) + posSlot = GetPosSlot2(curBack); + } + } + } + } +} + +static inline bool ChangePair(UInt32 smallDist, UInt32 bigDist) +{ + return ((bigDist >> 7) > smallDist); +} + +UInt32 CEncoder::ReadMatchDistances(UInt32 &numDistancePairs) +{ + UInt32 lenRes = 0; + numDistancePairs = _matchFinder.GetMatches(_matchFinderObj, _matchDistances); + #ifdef SHOW_STAT + printf("\n i = %d numPairs = %d ", ttt, numDistancePairs / 2); + if (ttt >= 61994) + ttt = ttt; + + ttt++; + for (UInt32 i = 0; i < numDistancePairs; i += 2) + printf("%2d %6d | ", _matchDistances[i], _matchDistances[i + 1]); + #endif + if (numDistancePairs > 0) + { + lenRes = _matchDistances[numDistancePairs - 2]; + if (lenRes == _numFastBytes) + { + UInt32 numAvail = _matchFinder.GetNumAvailableBytes(_matchFinderObj) + 1; + const Byte *pby = _matchFinder.GetPointerToCurrentPos(_matchFinderObj) - 1; + UInt32 distance = _matchDistances[numDistancePairs - 1] + 1; + if (numAvail > kMatchMaxLen) + numAvail = kMatchMaxLen; + for (; lenRes < numAvail && pby[lenRes] == pby[(size_t)lenRes - distance]; lenRes++); + } + } + _additionalOffset++; + return lenRes; +} + +UInt32 CEncoder::GetOptimumFast(UInt32 &backRes) +{ + UInt32 numAvailableBytes = _matchFinder.GetNumAvailableBytes(_matchFinderObj); + UInt32 lenMain, numDistancePairs; + if (!_longestMatchWasFound) + { + lenMain = ReadMatchDistances(numDistancePairs); + } + else + { + lenMain = _longestMatchLength; + numDistancePairs = _numDistancePairs; + _longestMatchWasFound = false; + } + + const Byte *data = _matchFinder.GetPointerToCurrentPos(_matchFinderObj) - 1; + if (numAvailableBytes > kMatchMaxLen) + numAvailableBytes = kMatchMaxLen; + if (numAvailableBytes < 2) + { + backRes = (UInt32)(-1); + return 1; + } + + UInt32 repLens[kNumRepDistances]; + UInt32 repMaxIndex = 0; + + for(UInt32 i = 0; i < kNumRepDistances; i++) + { + UInt32 backOffset = _repDistances[i] + 1; + if (data[0] != data[(size_t)0 - backOffset] || data[1] != data[(size_t)1 - backOffset]) + { + repLens[i] = 0; + continue; + } + UInt32 len; + for (len = 2; len < numAvailableBytes && data[len] == data[(size_t)len - backOffset]; len++); + if(len >= _numFastBytes) + { + backRes = i; + MovePos(len - 1); + return len; + } + repLens[i] = len; + if (len > repLens[repMaxIndex]) + repMaxIndex = i; + } + UInt32 *matchDistances = _matchDistances; + if(lenMain >= _numFastBytes) + { + backRes = matchDistances[numDistancePairs - 1] + kNumRepDistances; + MovePos(lenMain - 1); + return lenMain; + } + + UInt32 backMain = 0; // for GCC + if (lenMain >= 2) + { + backMain = matchDistances[numDistancePairs - 1]; + while (numDistancePairs > 2 && lenMain == matchDistances[numDistancePairs - 4] + 1) + { + if (!ChangePair(matchDistances[numDistancePairs - 3], backMain)) + break; + numDistancePairs -= 2; + lenMain = matchDistances[numDistancePairs - 2]; + backMain = matchDistances[numDistancePairs - 1]; + } + if (lenMain == 2 && backMain >= 0x80) + lenMain = 1; + } + + if (repLens[repMaxIndex] >= 2) + { + if (repLens[repMaxIndex] + 1 >= lenMain || + repLens[repMaxIndex] + 2 >= lenMain && (backMain > (1 << 9)) || + repLens[repMaxIndex] + 3 >= lenMain && (backMain > (1 << 15))) + { + backRes = repMaxIndex; + UInt32 lenRes = repLens[repMaxIndex]; + MovePos(lenRes - 1); + return lenRes; + } + } + + if (lenMain >= 2 && numAvailableBytes > 2) + { + numAvailableBytes = _matchFinder.GetNumAvailableBytes(_matchFinderObj); + _longestMatchLength = ReadMatchDistances(_numDistancePairs); + if (_longestMatchLength >= 2) + { + UInt32 newDistance = matchDistances[_numDistancePairs - 1]; + if (_longestMatchLength >= lenMain && newDistance < backMain || + _longestMatchLength == lenMain + 1 && !ChangePair(backMain, newDistance) || + _longestMatchLength > lenMain + 1 || + _longestMatchLength + 1 >= lenMain && lenMain >= 3 && ChangePair(newDistance, backMain)) + { + _longestMatchWasFound = true; + backRes = UInt32(-1); + return 1; + } + } + data = _matchFinder.GetPointerToCurrentPos(_matchFinderObj) - 1; + for(UInt32 i = 0; i < kNumRepDistances; i++) + { + UInt32 backOffset = _repDistances[i] + 1; + if (data[1] != data[(size_t)1 - backOffset] || data[2] != data[(size_t)2 - backOffset]) + { + repLens[i] = 0; + continue; + } + UInt32 len; + for (len = 2; len < numAvailableBytes && data[len] == data[(size_t)len - backOffset]; len++); + if (len + 1 >= lenMain) + { + _longestMatchWasFound = true; + backRes = UInt32(-1); + return 1; + } + } + backRes = backMain + kNumRepDistances; + MovePos(lenMain - 2); + return lenMain; + } + backRes = UInt32(-1); + return 1; +} + +HRESULT CEncoder::Flush(UInt32 nowPos) +{ + // ReleaseMFStream(); + if (_matchFinderBase.result != SZ_OK) + return _matchFinderBase.result; + WriteEndMarker(nowPos & _posStateMask); + _rangeEncoder.FlushData(); + return _rangeEncoder.FlushStream(); +} + +void CEncoder::WriteEndMarker(UInt32 posState) +{ + // This function for writing End Mark for stream version of LZMA. + // In current version this feature is not used. + if (!_writeEndMark) + return; + + _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 1); + _isRep[_state.Index].Encode(&_rangeEncoder, 0); + _state.UpdateMatch(); + UInt32 len = kMatchMinLen; // kMatchMaxLen; + _lenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState, !_fastMode); + UInt32 posSlot = (1 << kNumPosSlotBits) - 1; + UInt32 lenToPosState = GetLenToPosState(len); + _posSlotEncoder[lenToPosState].Encode(&_rangeEncoder, posSlot); + UInt32 footerBits = 30; + UInt32 posReduced = (UInt32(1) << footerBits) - 1; + _rangeEncoder.EncodeDirectBits(posReduced >> kNumAlignBits, footerBits - kNumAlignBits); + _posAlignEncoder.ReverseEncode(&_rangeEncoder, posReduced & kAlignMask); +} + +HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + // _needReleaseMFStream = false; + CCoderReleaser coderReleaser(this); + RINOK(SetStreams(inStream, outStream, inSize, outSize)); + for (;;) + { + UInt64 processedInSize; + UInt64 processedOutSize; + Int32 finished; + RINOK(CodeOneBlock(&processedInSize, &processedOutSize, &finished)); + if (finished != 0) + break; + if (progress != 0) + { + RINOK(progress->SetRatioInfo(&processedInSize, &processedOutSize)); + } + } + return S_OK; +} + +HRESULT CEncoder::SetStreams(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 * /* outSize */) +{ + _inStream = inStream; + _finished = false; + RINOK(Create()); + RINOK(SetOutStream(outStream)); + RINOK(Init()); + + if (!_fastMode) + { + FillDistancesPrices(); + FillAlignPrices(); + } + + _lenEncoder.SetTableSize(_numFastBytes + 1 - kMatchMinLen); + _lenEncoder.UpdateTables(1 << _posStateBits); + _repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - kMatchMinLen); + _repMatchLenEncoder.UpdateTables(1 << _posStateBits); + + nowPos64 = 0; + return S_OK; +} + +static HRes MyRead(void *object, void *data, UInt32 size, UInt32 *processedSize) +{ + return (HRes)((CSeqInStream *)object)->RealStream->Read(data, size, processedSize); +} + +HRESULT CEncoder::CodeOneBlock(UInt64 *inSize, UInt64 *outSize, Int32 *finished) +{ + if (_inStream != 0) + { + _seqInStream.RealStream = _inStream; + _seqInStream.SeqInStream.Read = MyRead; + _matchFinderBase.stream = &_seqInStream.SeqInStream; + _matchFinder.Init(_matchFinderObj); + _needReleaseMFStream = true; + _inStream = 0; + } + + + *finished = 1; + if (_finished) + return _matchFinderBase.result; + _finished = true; + + if (nowPos64 == 0) + { + if (_matchFinder.GetNumAvailableBytes(_matchFinderObj) == 0) + return Flush((UInt32)nowPos64); + UInt32 len, numDistancePairs; + len = ReadMatchDistances(numDistancePairs); + UInt32 posState = UInt32(nowPos64) & _posStateMask; + _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 0); + _state.UpdateChar(); + Byte curByte = _matchFinder.GetIndexByte(_matchFinderObj, 0 - _additionalOffset); + _literalEncoder.GetSubCoder(UInt32(nowPos64), _previousByte)->Encode(&_rangeEncoder, curByte); + _previousByte = curByte; + _additionalOffset--; + nowPos64++; + } + + UInt32 nowPos32 = (UInt32)nowPos64; + UInt32 progressPosValuePrev = nowPos32; + + if (_matchFinder.GetNumAvailableBytes(_matchFinderObj) == 0) + return Flush(nowPos32); + + for (;;) + { + #ifdef _NO_EXCEPTIONS + if (_rangeEncoder.Stream.ErrorCode != S_OK) + return _rangeEncoder.Stream.ErrorCode; + #endif + UInt32 pos, len; + + if (_fastMode) + len = GetOptimumFast(pos); + else + len = GetOptimum(nowPos32, pos); + + UInt32 posState = nowPos32 & _posStateMask; + if(len == 1 && pos == 0xFFFFFFFF) + { + _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 0); + Byte curByte = _matchFinder.GetIndexByte(_matchFinderObj, 0 - _additionalOffset); + CLiteralEncoder2 *subCoder = _literalEncoder.GetSubCoder(nowPos32, _previousByte); + if(_state.IsCharState()) + subCoder->Encode(&_rangeEncoder, curByte); + else + { + Byte matchByte = _matchFinder.GetIndexByte(_matchFinderObj, 0 - _repDistances[0] - 1 - _additionalOffset); + subCoder->EncodeMatched(&_rangeEncoder, matchByte, curByte); + } + _state.UpdateChar(); + _previousByte = curByte; + } + else + { + _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 1); + if(pos < kNumRepDistances) + { + _isRep[_state.Index].Encode(&_rangeEncoder, 1); + if(pos == 0) + { + _isRepG0[_state.Index].Encode(&_rangeEncoder, 0); + _isRep0Long[_state.Index][posState].Encode(&_rangeEncoder, ((len == 1) ? 0 : 1)); + } + else + { + UInt32 distance = _repDistances[pos]; + _isRepG0[_state.Index].Encode(&_rangeEncoder, 1); + if (pos == 1) + _isRepG1[_state.Index].Encode(&_rangeEncoder, 0); + else + { + _isRepG1[_state.Index].Encode(&_rangeEncoder, 1); + _isRepG2[_state.Index].Encode(&_rangeEncoder, pos - 2); + if (pos == 3) + _repDistances[3] = _repDistances[2]; + _repDistances[2] = _repDistances[1]; + } + _repDistances[1] = _repDistances[0]; + _repDistances[0] = distance; + } + if (len == 1) + _state.UpdateShortRep(); + else + { + _repMatchLenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState, !_fastMode); + _state.UpdateRep(); + } + } + else + { + _isRep[_state.Index].Encode(&_rangeEncoder, 0); + _state.UpdateMatch(); + _lenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState, !_fastMode); + pos -= kNumRepDistances; + UInt32 posSlot = GetPosSlot(pos); + _posSlotEncoder[GetLenToPosState(len)].Encode(&_rangeEncoder, posSlot); + + if (posSlot >= kStartPosModelIndex) + { + UInt32 footerBits = ((posSlot >> 1) - 1); + UInt32 base = ((2 | (posSlot & 1)) << footerBits); + UInt32 posReduced = pos - base; + + if (posSlot < kEndPosModelIndex) + NRangeCoder::ReverseBitTreeEncode(_posEncoders + base - posSlot - 1, + &_rangeEncoder, footerBits, posReduced); + else + { + _rangeEncoder.EncodeDirectBits(posReduced >> kNumAlignBits, footerBits - kNumAlignBits); + _posAlignEncoder.ReverseEncode(&_rangeEncoder, posReduced & kAlignMask); + _alignPriceCount++; + } + } + _repDistances[3] = _repDistances[2]; + _repDistances[2] = _repDistances[1]; + _repDistances[1] = _repDistances[0]; + _repDistances[0] = pos; + _matchPriceCount++; + } + _previousByte = _matchFinder.GetIndexByte(_matchFinderObj, len - 1 - _additionalOffset); + } + _additionalOffset -= len; + nowPos32 += len; + if (_additionalOffset == 0) + { + if (!_fastMode) + { + if (_matchPriceCount >= (1 << 7)) + FillDistancesPrices(); + if (_alignPriceCount >= kAlignTableSize) + FillAlignPrices(); + } + if (_matchFinder.GetNumAvailableBytes(_matchFinderObj) == 0) + return Flush(nowPos32); + if (nowPos32 - progressPosValuePrev >= (1 << 14)) + { + nowPos64 += nowPos32 - progressPosValuePrev; + *inSize = nowPos64; + *outSize = _rangeEncoder.GetProcessedSize(); + _finished = false; + *finished = 0; + return _matchFinderBase.result; + } + } + } +} + +STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + #ifndef _NO_EXCEPTIONS + try + { + #endif + return CodeReal(inStream, outStream, inSize, outSize, progress); + #ifndef _NO_EXCEPTIONS + } + catch(const COutBufferException &e) { return e.ErrorCode; } + catch(...) { return E_FAIL; } + #endif +} + +void CEncoder::FillDistancesPrices() +{ + UInt32 tempPrices[kNumFullDistances]; + for (UInt32 i = kStartPosModelIndex; i < kNumFullDistances; i++) + { + UInt32 posSlot = GetPosSlot(i); + UInt32 footerBits = ((posSlot >> 1) - 1); + UInt32 base = ((2 | (posSlot & 1)) << footerBits); + tempPrices[i] = NRangeCoder::ReverseBitTreeGetPrice(_posEncoders + + base - posSlot - 1, footerBits, i - base); + } + + for (UInt32 lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) + { + UInt32 posSlot; + NRangeCoder::CBitTreeEncoder &encoder = _posSlotEncoder[lenToPosState]; + UInt32 *posSlotPrices = _posSlotPrices[lenToPosState]; + for (posSlot = 0; posSlot < _distTableSize; posSlot++) + posSlotPrices[posSlot] = encoder.GetPrice(posSlot); + for (posSlot = kEndPosModelIndex; posSlot < _distTableSize; posSlot++) + posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << NRangeCoder::kNumBitPriceShiftBits); + + UInt32 *distancesPrices = _distancesPrices[lenToPosState]; + UInt32 i; + for (i = 0; i < kStartPosModelIndex; i++) + distancesPrices[i] = posSlotPrices[i]; + for (; i < kNumFullDistances; i++) + distancesPrices[i] = posSlotPrices[GetPosSlot(i)] + tempPrices[i]; + } + _matchPriceCount = 0; +} + +void CEncoder::FillAlignPrices() +{ + for (UInt32 i = 0; i < kAlignTableSize; i++) + _alignPrices[i] = _posAlignEncoder.ReverseGetPrice(i); + _alignPriceCount = 0; +} + +}} diff --git a/CPP/7zip/Compress/LZMA/LZMAEncoder.h b/CPP/7zip/Compress/LZMA/LZMAEncoder.h new file mode 100755 index 00000000..c1dc7a69 --- /dev/null +++ b/CPP/7zip/Compress/LZMA/LZMAEncoder.h @@ -0,0 +1,435 @@ +// LZMA/Encoder.h + +#ifndef __LZMA_ENCODER_H +#define __LZMA_ENCODER_H + +#include "../../../Common/MyCom.h" +#include "../../../Common/Alloc.h" +#include "../../ICoder.h" + +extern "C" +{ + #include "../../../../C/Compress/Lz/MatchFinder.h" + #ifdef COMPRESS_MF_MT + #include "../../../../C/Compress/Lz/MatchFinderMt.h" + #endif +} + +#include "../RangeCoder/RangeCoderBitTree.h" + +#include "LZMA.h" + +namespace NCompress { +namespace NLZMA { + +typedef NRangeCoder::CBitEncoder CMyBitEncoder; + +class CBaseState +{ +protected: + CState _state; + Byte _previousByte; + UInt32 _repDistances[kNumRepDistances]; + void Init() + { + _state.Init(); + _previousByte = 0; + for(UInt32 i = 0 ; i < kNumRepDistances; i++) + _repDistances[i] = 0; + } +}; + +struct COptimal +{ + CState State; + + bool Prev1IsChar; + bool Prev2; + + UInt32 PosPrev2; + UInt32 BackPrev2; + + UInt32 Price; + UInt32 PosPrev; // posNext; + UInt32 BackPrev; + UInt32 Backs[kNumRepDistances]; + void MakeAsChar() { BackPrev = UInt32(-1); Prev1IsChar = false; } + void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; } + bool IsShortRep() { return (BackPrev == 0); } +}; + + +extern Byte g_FastPos[1 << 11]; +inline UInt32 GetPosSlot(UInt32 pos) +{ + if (pos < (1 << 11)) + return g_FastPos[pos]; + if (pos < (1 << 21)) + return g_FastPos[pos >> 10] + 20; + return g_FastPos[pos >> 20] + 40; +} + +inline UInt32 GetPosSlot2(UInt32 pos) +{ + if (pos < (1 << 17)) + return g_FastPos[pos >> 6] + 12; + if (pos < (1 << 27)) + return g_FastPos[pos >> 16] + 32; + return g_FastPos[pos >> 26] + 52; +} + +const UInt32 kIfinityPrice = 0xFFFFFFF; + +const UInt32 kNumOpts = 1 << 12; + + +class CLiteralEncoder2 +{ + CMyBitEncoder _encoders[0x300]; +public: + void Init() + { + for (int i = 0; i < 0x300; i++) + _encoders[i].Init(); + } + void Encode(NRangeCoder::CEncoder *rangeEncoder, Byte symbol); + void EncodeMatched(NRangeCoder::CEncoder *rangeEncoder, Byte matchByte, Byte symbol); + UInt32 GetPrice(bool matchMode, Byte matchByte, Byte symbol) const; +}; + +class CLiteralEncoder +{ + CLiteralEncoder2 *_coders; + int _numPrevBits; + int _numPosBits; + UInt32 _posMask; +public: + CLiteralEncoder(): _coders(0) {} + ~CLiteralEncoder() { Free(); } + void Free() + { + MyFree(_coders); + _coders = 0; + } + bool Create(int numPosBits, int numPrevBits) + { + if (_coders == 0 || (numPosBits + numPrevBits) != (_numPrevBits + _numPosBits)) + { + Free(); + UInt32 numStates = 1 << (numPosBits + numPrevBits); + _coders = (CLiteralEncoder2 *)MyAlloc(numStates * sizeof(CLiteralEncoder2)); + } + _numPosBits = numPosBits; + _posMask = (1 << numPosBits) - 1; + _numPrevBits = numPrevBits; + return (_coders != 0); + } + void Init() + { + UInt32 numStates = 1 << (_numPrevBits + _numPosBits); + for (UInt32 i = 0; i < numStates; i++) + _coders[i].Init(); + } + CLiteralEncoder2 *GetSubCoder(UInt32 pos, Byte prevByte) + { return &_coders[((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits))]; } +}; + +namespace NLength { + +class CEncoder +{ + CMyBitEncoder _choice; + CMyBitEncoder _choice2; + NRangeCoder::CBitTreeEncoder _lowCoder[kNumPosStatesEncodingMax]; + NRangeCoder::CBitTreeEncoder _midCoder[kNumPosStatesEncodingMax]; + NRangeCoder::CBitTreeEncoder _highCoder; +public: + void Init(UInt32 numPosStates); + void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState); + void SetPrices(UInt32 posState, UInt32 numSymbols, UInt32 *prices) const; +}; + +const UInt32 kNumSpecSymbols = kNumLowSymbols + kNumMidSymbols; + +class CPriceTableEncoder: public CEncoder +{ + UInt32 _prices[kNumPosStatesEncodingMax][kNumSymbolsTotal]; + UInt32 _tableSize; + UInt32 _counters[kNumPosStatesEncodingMax]; +public: + void SetTableSize(UInt32 tableSize) { _tableSize = tableSize; } + UInt32 GetPrice(UInt32 symbol, UInt32 posState) const { return _prices[posState][symbol]; } + void UpdateTable(UInt32 posState) + { + SetPrices(posState, _tableSize, _prices[posState]); + _counters[posState] = _tableSize; + } + void UpdateTables(UInt32 numPosStates) + { + for (UInt32 posState = 0; posState < numPosStates; posState++) + UpdateTable(posState); + } + void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState, bool updatePrice) + { + CEncoder::Encode(rangeEncoder, symbol, posState); + if (updatePrice) + if (--_counters[posState] == 0) + UpdateTable(posState); + } +}; + +} + +typedef struct _CSeqInStream +{ + ISeqInStream SeqInStream; + CMyComPtr RealStream; +} CSeqInStream; + + +class CEncoder : + public ICompressCoder, + public ICompressSetOutStream, + public ICompressSetCoderProperties, + public ICompressWriteCoderProperties, + public CBaseState, + public CMyUnknownImp +{ + NRangeCoder::CEncoder _rangeEncoder; + + IMatchFinder _matchFinder; + void *_matchFinderObj; + + #ifdef COMPRESS_MF_MT + Bool _multiThread; + Bool _mtMode; + CMatchFinderMt _matchFinderMt; + #endif + + CMatchFinder _matchFinderBase; + #ifdef COMPRESS_MF_MT + Byte _pad1[kMtCacheLineDummy]; + #endif + + COptimal _optimum[kNumOpts]; + + CMyBitEncoder _isMatch[kNumStates][NLength::kNumPosStatesEncodingMax]; + CMyBitEncoder _isRep[kNumStates]; + CMyBitEncoder _isRepG0[kNumStates]; + CMyBitEncoder _isRepG1[kNumStates]; + CMyBitEncoder _isRepG2[kNumStates]; + CMyBitEncoder _isRep0Long[kNumStates][NLength::kNumPosStatesEncodingMax]; + + NRangeCoder::CBitTreeEncoder _posSlotEncoder[kNumLenToPosStates]; + + CMyBitEncoder _posEncoders[kNumFullDistances - kEndPosModelIndex]; + NRangeCoder::CBitTreeEncoder _posAlignEncoder; + + NLength::CPriceTableEncoder _lenEncoder; + NLength::CPriceTableEncoder _repMatchLenEncoder; + + CLiteralEncoder _literalEncoder; + + UInt32 _matchDistances[kMatchMaxLen * 2 + 2 + 1]; + + bool _fastMode; + // bool _maxMode; + UInt32 _numFastBytes; + UInt32 _longestMatchLength; + UInt32 _numDistancePairs; + + UInt32 _additionalOffset; + + UInt32 _optimumEndIndex; + UInt32 _optimumCurrentIndex; + + bool _longestMatchWasFound; + + UInt32 _posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; + + UInt32 _distancesPrices[kNumLenToPosStates][kNumFullDistances]; + + UInt32 _alignPrices[kAlignTableSize]; + UInt32 _alignPriceCount; + + UInt32 _distTableSize; + + UInt32 _posStateBits; + UInt32 _posStateMask; + UInt32 _numLiteralPosStateBits; + UInt32 _numLiteralContextBits; + + UInt32 _dictionarySize; + + UInt32 _matchPriceCount; + UInt64 nowPos64; + bool _finished; + ISequentialInStream *_inStream; + + CSeqInStream _seqInStream; + + UInt32 _matchFinderCycles; + // int _numSkip + + bool _writeEndMark; + + bool _needReleaseMFStream; + + void ReleaseMatchFinder() + { + _matchFinder.Init = 0; + _seqInStream.RealStream.Release(); + } + + void ReleaseMFStream() + { + if (_matchFinderObj && _needReleaseMFStream) + { + #ifdef COMPRESS_MF_MT + if (_mtMode) + MatchFinderMt_ReleaseStream(&_matchFinderMt); + #endif + _needReleaseMFStream = false; + } + _seqInStream.RealStream.Release(); + } + + UInt32 ReadMatchDistances(UInt32 &numDistancePairs); + + void MovePos(UInt32 num); + UInt32 GetRepLen1Price(CState state, UInt32 posState) const + { + return _isRepG0[state.Index].GetPrice0() + + _isRep0Long[state.Index][posState].GetPrice0(); + } + + UInt32 GetPureRepPrice(UInt32 repIndex, CState state, UInt32 posState) const + { + UInt32 price; + if(repIndex == 0) + { + price = _isRepG0[state.Index].GetPrice0(); + price += _isRep0Long[state.Index][posState].GetPrice1(); + } + else + { + price = _isRepG0[state.Index].GetPrice1(); + if (repIndex == 1) + price += _isRepG1[state.Index].GetPrice0(); + else + { + price += _isRepG1[state.Index].GetPrice1(); + price += _isRepG2[state.Index].GetPrice(repIndex - 2); + } + } + return price; + } + UInt32 GetRepPrice(UInt32 repIndex, UInt32 len, CState state, UInt32 posState) const + { + return _repMatchLenEncoder.GetPrice(len - kMatchMinLen, posState) + + GetPureRepPrice(repIndex, state, posState); + } + /* + UInt32 GetPosLen2Price(UInt32 pos, UInt32 posState) const + { + if (pos >= kNumFullDistances) + return kIfinityPrice; + return _distancesPrices[0][pos] + _lenEncoder.GetPrice(0, posState); + } + UInt32 GetPosLen3Price(UInt32 pos, UInt32 len, UInt32 posState) const + { + UInt32 price; + UInt32 lenToPosState = GetLenToPosState(len); + if (pos < kNumFullDistances) + price = _distancesPrices[lenToPosState][pos]; + else + price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] + + _alignPrices[pos & kAlignMask]; + return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState); + } + */ + UInt32 GetPosLenPrice(UInt32 pos, UInt32 len, UInt32 posState) const + { + UInt32 price; + UInt32 lenToPosState = GetLenToPosState(len); + if (pos < kNumFullDistances) + price = _distancesPrices[lenToPosState][pos]; + else + price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] + + _alignPrices[pos & kAlignMask]; + return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState); + } + + UInt32 Backward(UInt32 &backRes, UInt32 cur); + UInt32 GetOptimum(UInt32 position, UInt32 &backRes); + UInt32 GetOptimumFast(UInt32 &backRes); + + void FillDistancesPrices(); + void FillAlignPrices(); + + void ReleaseStreams() + { + ReleaseMFStream(); + ReleaseOutStream(); + } + + HRESULT Flush(UInt32 nowPos); + class CCoderReleaser + { + CEncoder *_coder; + public: + CCoderReleaser(CEncoder *coder): _coder(coder) {} + ~CCoderReleaser() { _coder->ReleaseStreams(); } + }; + friend class CCoderReleaser; + + void WriteEndMarker(UInt32 posState); + +public: + CEncoder(); + void SetWriteEndMarkerMode(bool writeEndMarker) + { _writeEndMark= writeEndMarker; } + + HRESULT Create(); + + MY_UNKNOWN_IMP3( + ICompressSetOutStream, + ICompressSetCoderProperties, + ICompressWriteCoderProperties + ) + + HRESULT Init(); + + // ICompressCoder interface + HRESULT SetStreams(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize); + HRESULT CodeOneBlock(UInt64 *inSize, UInt64 *outSize, Int32 *finished); + + HRESULT CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + // ICompressCoder interface + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + // ICompressSetCoderProperties2 + STDMETHOD(SetCoderProperties)(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties); + + // ICompressWriteCoderProperties + STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); + + STDMETHOD(SetOutStream)(ISequentialOutStream *outStream); + STDMETHOD(ReleaseOutStream)(); + + virtual ~CEncoder(); +}; + +}} + +#endif diff --git a/CPP/7zip/Compress/LZMA/StdAfx.cpp b/CPP/7zip/Compress/LZMA/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Compress/LZMA/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Compress/LZMA/StdAfx.h b/CPP/7zip/Compress/LZMA/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Compress/LZMA/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Compress/LZMA/makefile b/CPP/7zip/Compress/LZMA/makefile new file mode 100755 index 00000000..0b692541 --- /dev/null +++ b/CPP/7zip/Compress/LZMA/makefile @@ -0,0 +1,69 @@ +PROG = LZMA.dll +DEF_FILE = ../Codec.def +CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_MF_MT -D_ST_MODE +LIBS = $(LIBS) oleaut32.lib + +LZMA_OBJS = \ + $O\DllExports.obj \ + +LZMA_OPT_OBJS = \ + $O\LZMADecoder.obj \ + $O\LZMAEncoder.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CRC.obj \ + +WIN_OBJS = \ + $O\Synchronization.obj + +7ZIP_COMMON_OBJS = \ + $O\InBuffer.obj \ + $O\OutBuffer.obj \ + $O\StreamUtils.obj \ + +LZ_OBJS = \ + $O\LZOutWindow.obj \ + +C_OBJS = \ + $O\7zCrc.obj \ + $O\Sort.obj \ + $O\Threads.obj \ + +C_LZ_OBJS = \ + $O\MatchFinder.obj \ + $O\MatchFinderMt.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(LZMA_OBJS) \ + $(LZMA_OPT_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(LZ_OBJS) \ + $(C_OBJS) \ + $(C_LZ_OBJS) \ + $O\RangeCoderBit.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(LZMA_OBJS): $(*B).cpp + $(COMPL) +$(LZMA_OPT_OBJS): $(*B).cpp + $(COMPL_O2) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(LZ_OBJS): ../LZ/$(*B).cpp + $(COMPL) +$O\RangeCoderBit.obj: ../RangeCoder/$(*B).cpp + $(COMPL) +$(C_OBJS): ../../../../C/$(*B).c + $(COMPL_O2) +$(C_LZ_OBJS): ../../../../C/Compress/Lz/$(*B).c + $(COMPL_O2) diff --git a/CPP/7zip/Compress/LZMA/resource.rc b/CPP/7zip/Compress/LZMA/resource.rc new file mode 100755 index 00000000..1b2b6abb --- /dev/null +++ b/CPP/7zip/Compress/LZMA/resource.rc @@ -0,0 +1,3 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("LZMA Codec", "LZMA") diff --git a/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp b/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp new file mode 100755 index 00000000..6401206c --- /dev/null +++ b/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp @@ -0,0 +1,449 @@ +# Microsoft Developer Studio Project File - Name="AloneLZMA" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=AloneLZMA - Win32 DebugU +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AloneLZMA.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AloneLZMA.mak" CFG="AloneLZMA - Win32 DebugU" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AloneLZMA - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "AloneLZMA - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "AloneLZMA - Win32 ReleaseU" (based on "Win32 (x86) Console Application") +!MESSAGE "AloneLZMA - Win32 DebugU" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "AloneLZMA - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\lzma.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "AloneLZMA - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\lzma.exe" /pdbtype:sept + +!ELSEIF "$(CFG)" == "AloneLZMA - Win32 ReleaseU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ReleaseU" +# PROP BASE Intermediate_Dir "ReleaseU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseU" +# PROP Intermediate_Dir "ReleaseU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7za2.exe" /opt:NOWIN98 +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\lzma.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "AloneLZMA - Win32 DebugU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "DebugU" +# PROP BASE Intermediate_Dir "DebugU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugU" +# PROP Intermediate_Dir "DebugU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7za2.exe" /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\lzma.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "AloneLZMA - Win32 Release" +# Name "AloneLZMA - Win32 Debug" +# Name "AloneLZMA - Win32 ReleaseU" +# Name "AloneLZMA - Win32 DebugU" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Group "LZMA" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\LZMA\LZMA.h +# End Source File +# Begin Source File + +SOURCE=..\LZMA\LZMADecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\LZMA\LZMADecoder.h +# End Source File +# Begin Source File + +SOURCE=..\LZMA\LZMAEncoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\LZMA\LZMAEncoder.h +# End Source File +# End Group +# Begin Group "RangeCoder" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\RangeCoder\RangeCoder.h +# End Source File +# Begin Source File + +SOURCE=..\RangeCoder\RangeCoderBit.cpp +# End Source File +# Begin Source File + +SOURCE=..\RangeCoder\RangeCoderBit.h +# End Source File +# Begin Source File + +SOURCE=..\RangeCoder\RangeCoderBitTree.h +# End Source File +# Begin Source File + +SOURCE=..\RangeCoder\RangeCoderOpt.h +# End Source File +# End Group +# Begin Group "LZ" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\LZ\LZOutWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\LZ\LZOutWindow.h +# End Source File +# End Group +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Types.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Group "C-Lz" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.h +# End Source File +# End Group +# Begin Group "LZMA_C" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Lzma\LzmaDecode.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Lzma\LzmaDecode.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Lzma\LzmaTypes.h +# End Source File +# End Group +# Begin Group "Branch" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Branch\BranchTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Branch\BranchX86.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Branch\BranchX86.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=.\LzmaAlone.cpp +# End Source File +# Begin Source File + +SOURCE=.\LzmaBench.cpp +# End Source File +# Begin Source File + +SOURCE=.\LzmaBench.h +# End Source File +# Begin Source File + +SOURCE=.\LzmaRam.cpp +# End Source File +# Begin Source File + +SOURCE=.\LzmaRam.h +# End Source File +# Begin Source File + +SOURCE=.\LzmaRamDecode.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=.\LzmaRamDecode.h +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsw b/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsw new file mode 100755 index 00000000..d7482d8a --- /dev/null +++ b/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AloneLZMA"=.\AloneLZMA.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp b/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp new file mode 100755 index 00000000..f5ad65da --- /dev/null +++ b/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp @@ -0,0 +1,526 @@ +// LzmaAlone.cpp + +#include "StdAfx.h" + +#include "../../../Common/MyWindows.h" +#include "../../../Common/MyInitGuid.h" + +#include + +#if defined(_WIN32) || defined(OS2) || defined(MSDOS) +#include +#include +#define MY_SET_BINARY_MODE(file) _setmode(_fileno(file), O_BINARY) +#else +#define MY_SET_BINARY_MODE(file) +#endif + +#include "../../../Common/CommandLineParser.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/StringToInt.h" + +#include "../../Common/FileStreams.h" +#include "../../Common/StreamUtils.h" + +#include "../LZMA/LZMADecoder.h" +#include "../LZMA/LZMAEncoder.h" + +#include "LzmaBench.h" +#include "LzmaRam.h" + +extern "C" +{ +#include "LzmaRamDecode.h" +} + +using namespace NCommandLineParser; + +#ifdef _WIN32 +bool g_IsNT = false; +static inline bool IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); +} +#endif + +static const char *kCantAllocate = "Can not allocate memory"; +static const char *kReadError = "Read error"; +static const char *kWriteError = "Write error"; + +namespace NKey { +enum Enum +{ + kHelp1 = 0, + kHelp2, + kMode, + kDictionary, + kFastBytes, + kMatchFinderCycles, + kLitContext, + kLitPos, + kPosBits, + kMatchFinder, + kEOS, + kStdIn, + kStdOut, + kFilter86 +}; +} + +static const CSwitchForm kSwitchForms[] = +{ + { L"?", NSwitchType::kSimple, false }, + { L"H", NSwitchType::kSimple, false }, + { L"A", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"D", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"FB", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"MC", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"LC", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"LP", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"PB", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"MF", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"EOS", NSwitchType::kSimple, false }, + { L"SI", NSwitchType::kSimple, false }, + { L"SO", NSwitchType::kSimple, false }, + { L"F86", NSwitchType::kSimple, false } +}; + +static const int kNumSwitches = sizeof(kSwitchForms) / sizeof(kSwitchForms[0]); + +static void PrintHelp() +{ + fprintf(stderr, "\nUsage: LZMA inputFile outputFile [...]\n" + " e: encode file\n" + " d: decode file\n" + " b: Benchmark\n" + "\n" + " -a{N}: set compression mode - [0, 1], default: 1 (max)\n" + " -d{N}: set dictionary - [0,30], default: 23 (8MB)\n" + " -fb{N}: set number of fast bytes - [5, 273], default: 128\n" + " -mc{N}: set number of cycles for match finder\n" + " -lc{N}: set number of literal context bits - [0, 8], default: 3\n" + " -lp{N}: set number of literal pos bits - [0, 4], default: 0\n" + " -pb{N}: set number of pos bits - [0, 4], default: 2\n" + " -mf{MF_ID}: set Match Finder: [bt2, bt3, bt4, hc4], default: bt4\n" + " -eos: write End Of Stream marker\n" + " -si: read data from stdin\n" + " -so: write data to stdout\n" + ); +} + +static void PrintHelpAndExit(const char *s) +{ + fprintf(stderr, "\nError: %s\n\n", s); + PrintHelp(); + throw -1; +} + +static void IncorrectCommand() +{ + PrintHelpAndExit("Incorrect command"); +} + +static void WriteArgumentsToStringList(int numArguments, const char *arguments[], + UStringVector &strings) +{ + for(int i = 1; i < numArguments; i++) + strings.Add(MultiByteToUnicodeString(arguments[i])); +} + +static bool GetNumber(const wchar_t *s, UInt32 &value) +{ + value = 0; + if (MyStringLen(s) == 0) + return false; + const wchar_t *end; + UInt64 res = ConvertStringToUInt64(s, &end); + if (*end != L'\0') + return false; + if (res > 0xFFFFFFFF) + return false; + value = UInt32(res); + return true; +} + +int main2(int n, const char *args[]) +{ + #ifdef _WIN32 + g_IsNT = IsItWindowsNT(); + #endif + + fprintf(stderr, "\nLZMA 4.44 Copyright (c) 1999-2006 Igor Pavlov 2006-12-26\n"); + + if (n == 1) + { + PrintHelp(); + return 0; + } + + bool unsupportedTypes = (sizeof(Byte) != 1 || sizeof(UInt32) < 4 || sizeof(UInt64) < 4); + if (unsupportedTypes) + { + fprintf(stderr, "Unsupported base types. Edit Common/Types.h and recompile"); + return 1; + } + + UStringVector commandStrings; + WriteArgumentsToStringList(n, args, commandStrings); + CParser parser(kNumSwitches); + try + { + parser.ParseStrings(kSwitchForms, commandStrings); + } + catch(...) + { + IncorrectCommand(); + } + + if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs) + { + PrintHelp(); + return 0; + } + const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; + + int paramIndex = 0; + if (paramIndex >= nonSwitchStrings.Size()) + IncorrectCommand(); + const UString &command = nonSwitchStrings[paramIndex++]; + + bool dictionaryIsDefined = false; + UInt32 dictionary = 1 << 21; + if(parser[NKey::kDictionary].ThereIs) + { + UInt32 dicLog; + if (!GetNumber(parser[NKey::kDictionary].PostStrings[0], dicLog)) + IncorrectCommand(); + dictionary = 1 << dicLog; + dictionaryIsDefined = true; + } + UString mf = L"BT4"; + if (parser[NKey::kMatchFinder].ThereIs) + mf = parser[NKey::kMatchFinder].PostStrings[0]; + + if (command.CompareNoCase(L"b") == 0) + { + const UInt32 kNumDefaultItereations = 10; + UInt32 numIterations = kNumDefaultItereations; + { + if (paramIndex < nonSwitchStrings.Size()) + if (!GetNumber(nonSwitchStrings[paramIndex++], numIterations)) + numIterations = kNumDefaultItereations; + } + return LzmaBenchmark(stderr, numIterations, dictionary); + } + + bool encodeMode = false; + if (command.CompareNoCase(L"e") == 0) + encodeMode = true; + else if (command.CompareNoCase(L"d") == 0) + encodeMode = false; + else + IncorrectCommand(); + + bool stdInMode = parser[NKey::kStdIn].ThereIs; + bool stdOutMode = parser[NKey::kStdOut].ThereIs; + + CMyComPtr inStream; + CInFileStream *inStreamSpec = 0; + if (stdInMode) + { + inStream = new CStdInFileStream; + MY_SET_BINARY_MODE(stdin); + } + else + { + if (paramIndex >= nonSwitchStrings.Size()) + IncorrectCommand(); + const UString &inputName = nonSwitchStrings[paramIndex++]; + inStreamSpec = new CInFileStream; + inStream = inStreamSpec; + if (!inStreamSpec->Open(GetSystemString(inputName))) + { + fprintf(stderr, "\nError: can not open input file %s\n", + (const char *)GetOemString(inputName)); + return 1; + } + } + + CMyComPtr outStream; + if (stdOutMode) + { + outStream = new CStdOutFileStream; + MY_SET_BINARY_MODE(stdout); + } + else + { + if (paramIndex >= nonSwitchStrings.Size()) + IncorrectCommand(); + const UString &outputName = nonSwitchStrings[paramIndex++]; + COutFileStream *outStreamSpec = new COutFileStream; + outStream = outStreamSpec; + if (!outStreamSpec->Create(GetSystemString(outputName), true)) + { + fprintf(stderr, "\nError: can not open output file %s\n", + (const char *)GetOemString(outputName)); + return 1; + } + } + + if (parser[NKey::kFilter86].ThereIs) + { + // -f86 switch is for x86 filtered mode: BCJ + LZMA. + if (parser[NKey::kEOS].ThereIs || stdInMode) + throw "Can not use stdin in this mode"; + UInt64 fileSize; + inStreamSpec->File.GetLength(fileSize); + if (fileSize > 0xF0000000) + throw "File is too big"; + UInt32 inSize = (UInt32)fileSize; + Byte *inBuffer = 0; + if (inSize != 0) + { + inBuffer = (Byte *)MyAlloc((size_t)inSize); + if (inBuffer == 0) + throw kCantAllocate; + } + + UInt32 processedSize; + if (ReadStream(inStream, inBuffer, (UInt32)inSize, &processedSize) != S_OK) + throw "Can not read"; + if ((UInt32)inSize != processedSize) + throw "Read size error"; + + Byte *outBuffer = 0; + size_t outSizeProcessed; + if (encodeMode) + { + // we allocate 105% of original size for output buffer + size_t outSize = (size_t)fileSize / 20 * 21 + (1 << 16); + if (outSize != 0) + { + outBuffer = (Byte *)MyAlloc((size_t)outSize); + if (outBuffer == 0) + throw kCantAllocate; + } + if (!dictionaryIsDefined) + dictionary = 1 << 23; + int res = LzmaRamEncode(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed, + dictionary, SZ_FILTER_AUTO); + if (res != 0) + { + fprintf(stderr, "\nEncoder error = %d\n", (int)res); + return 1; + } + } + else + { + size_t outSize; + if (LzmaRamGetUncompressedSize(inBuffer, inSize, &outSize) != 0) + throw "data error"; + if (outSize != 0) + { + outBuffer = (Byte *)MyAlloc(outSize); + if (outBuffer == 0) + throw kCantAllocate; + } + int res = LzmaRamDecompress(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed, malloc, free); + if (res != 0) + throw "LzmaDecoder error"; + } + if (WriteStream(outStream, outBuffer, (UInt32)outSizeProcessed, &processedSize) != S_OK) + throw kWriteError; + MyFree(outBuffer); + MyFree(inBuffer); + return 0; + } + + + UInt64 fileSize; + if (encodeMode) + { + NCompress::NLZMA::CEncoder *encoderSpec = + new NCompress::NLZMA::CEncoder; + CMyComPtr encoder = encoderSpec; + + if (!dictionaryIsDefined) + dictionary = 1 << 23; + + UInt32 posStateBits = 2; + UInt32 litContextBits = 3; // for normal files + // UInt32 litContextBits = 0; // for 32-bit data + UInt32 litPosBits = 0; + // UInt32 litPosBits = 2; // for 32-bit data + UInt32 algorithm = 1; + UInt32 numFastBytes = 128; + UInt32 matchFinderCycles = 16 + numFastBytes / 2; + bool matchFinderCyclesDefined = false; + + bool eos = parser[NKey::kEOS].ThereIs || stdInMode; + + if(parser[NKey::kMode].ThereIs) + if (!GetNumber(parser[NKey::kMode].PostStrings[0], algorithm)) + IncorrectCommand(); + + if(parser[NKey::kFastBytes].ThereIs) + if (!GetNumber(parser[NKey::kFastBytes].PostStrings[0], numFastBytes)) + IncorrectCommand(); + matchFinderCyclesDefined = parser[NKey::kMatchFinderCycles].ThereIs; + if (matchFinderCyclesDefined) + if (!GetNumber(parser[NKey::kMatchFinderCycles].PostStrings[0], matchFinderCycles)) + IncorrectCommand(); + if(parser[NKey::kLitContext].ThereIs) + if (!GetNumber(parser[NKey::kLitContext].PostStrings[0], litContextBits)) + IncorrectCommand(); + if(parser[NKey::kLitPos].ThereIs) + if (!GetNumber(parser[NKey::kLitPos].PostStrings[0], litPosBits)) + IncorrectCommand(); + if(parser[NKey::kPosBits].ThereIs) + if (!GetNumber(parser[NKey::kPosBits].PostStrings[0], posStateBits)) + IncorrectCommand(); + + PROPID propIDs[] = + { + NCoderPropID::kDictionarySize, + NCoderPropID::kPosStateBits, + NCoderPropID::kLitContextBits, + NCoderPropID::kLitPosBits, + NCoderPropID::kAlgorithm, + NCoderPropID::kNumFastBytes, + NCoderPropID::kMatchFinder, + NCoderPropID::kEndMarker, + NCoderPropID::kMatchFinderCycles + }; + const int kNumPropsMax = sizeof(propIDs) / sizeof(propIDs[0]); + /* + NWindows::NCOM::CPropVariant properties[kNumProps]; + properties[0] = UInt32(dictionary); + properties[1] = UInt32(posStateBits); + properties[2] = UInt32(litContextBits); + + properties[3] = UInt32(litPosBits); + properties[4] = UInt32(algorithm); + properties[5] = UInt32(numFastBytes); + properties[6] = mf; + properties[7] = eos; + */ + PROPVARIANT properties[kNumPropsMax]; + for (int p = 0; p < 6; p++) + properties[p].vt = VT_UI4; + + properties[0].ulVal = UInt32(dictionary); + properties[1].ulVal = UInt32(posStateBits); + properties[2].ulVal = UInt32(litContextBits); + properties[3].ulVal = UInt32(litPosBits); + properties[4].ulVal = UInt32(algorithm); + properties[5].ulVal = UInt32(numFastBytes); + + properties[8].vt = VT_UI4; + properties[8].ulVal = UInt32(matchFinderCycles); + + properties[6].vt = VT_BSTR; + properties[6].bstrVal = (BSTR)(const wchar_t *)mf; + + properties[7].vt = VT_BOOL; + properties[7].boolVal = eos ? VARIANT_TRUE : VARIANT_FALSE; + + int numProps = kNumPropsMax; + if (!matchFinderCyclesDefined) + numProps--; + + if (encoderSpec->SetCoderProperties(propIDs, properties, numProps) != S_OK) + IncorrectCommand(); + encoderSpec->WriteCoderProperties(outStream); + + if (eos || stdInMode) + fileSize = (UInt64)(Int64)-1; + else + inStreamSpec->File.GetLength(fileSize); + + for (int i = 0; i < 8; i++) + { + Byte b = Byte(fileSize >> (8 * i)); + if (outStream->Write(&b, 1, 0) != S_OK) + { + fprintf(stderr, kWriteError); + return 1; + } + } + HRESULT result = encoder->Code(inStream, outStream, 0, 0, 0); + if (result == E_OUTOFMEMORY) + { + fprintf(stderr, "\nError: Can not allocate memory\n"); + return 1; + } + else if (result != S_OK) + { + fprintf(stderr, "\nEncoder error = %X\n", (unsigned int)result); + return 1; + } + } + else + { + NCompress::NLZMA::CDecoder *decoderSpec = + new NCompress::NLZMA::CDecoder; + CMyComPtr decoder = decoderSpec; + const UInt32 kPropertiesSize = 5; + Byte properties[kPropertiesSize]; + UInt32 processedSize; + if (ReadStream(inStream, properties, kPropertiesSize, &processedSize) != S_OK) + { + fprintf(stderr, kReadError); + return 1; + } + if (processedSize != kPropertiesSize) + { + fprintf(stderr, kReadError); + return 1; + } + if (decoderSpec->SetDecoderProperties2(properties, kPropertiesSize) != S_OK) + { + fprintf(stderr, "SetDecoderProperties error"); + return 1; + } + fileSize = 0; + for (int i = 0; i < 8; i++) + { + Byte b; + if (inStream->Read(&b, 1, &processedSize) != S_OK) + { + fprintf(stderr, kReadError); + return 1; + } + if (processedSize != 1) + { + fprintf(stderr, kReadError); + return 1; + } + fileSize |= ((UInt64)b) << (8 * i); + } + if (decoder->Code(inStream, outStream, 0, &fileSize, 0) != S_OK) + { + fprintf(stderr, "Decoder error"); + return 1; + } + } + return 0; +} + +int main(int n, const char *args[]) +{ + try { return main2(n, args); } + catch(const char *s) + { + fprintf(stderr, "\nError: %s\n", s); + return 1; + } + catch(...) + { + fprintf(stderr, "\nError\n"); + return 1; + } +} diff --git a/CPP/7zip/Compress/LZMA_Alone/LzmaBench.cpp b/CPP/7zip/Compress/LZMA_Alone/LzmaBench.cpp new file mode 100755 index 00000000..f9924165 --- /dev/null +++ b/CPP/7zip/Compress/LZMA_Alone/LzmaBench.cpp @@ -0,0 +1,506 @@ +// LzmaBench.cpp + +#include "StdAfx.h" + +#include "LzmaBench.h" + +#ifndef _WIN32 +#include +#endif + +#include "../../../Common/CRC.h" +#include "../LZMA/LZMADecoder.h" +#include "../LZMA/LZMAEncoder.h" + +static const UInt32 kAdditionalSize = +#ifdef _WIN32_WCE +(1 << 20); +#else +(6 << 20); +#endif + +static const UInt32 kCompressedAdditionalSize = (1 << 10); +static const UInt32 kMaxLzmaPropSize = 10; + +class CRandomGenerator +{ + UInt32 A1; + UInt32 A2; +public: + CRandomGenerator() { Init(); } + void Init() { A1 = 362436069; A2 = 521288629;} + UInt32 GetRnd() + { + return + ((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) ^ + ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) ); + } +}; + +class CBitRandomGenerator +{ + CRandomGenerator RG; + UInt32 Value; + int NumBits; +public: + void Init() + { + Value = 0; + NumBits = 0; + } + UInt32 GetRnd(int numBits) + { + if (NumBits > numBits) + { + UInt32 result = Value & ((1 << numBits) - 1); + Value >>= numBits; + NumBits -= numBits; + return result; + } + numBits -= NumBits; + UInt32 result = (Value << numBits); + Value = RG.GetRnd(); + result |= Value & ((1 << numBits) - 1); + Value >>= numBits; + NumBits = 32 - numBits; + return result; + } +}; + +class CBenchRandomGenerator +{ + CBitRandomGenerator RG; + UInt32 Pos; + UInt32 Rep0; +public: + UInt32 BufferSize; + Byte *Buffer; + CBenchRandomGenerator(): Buffer(0) {} + ~CBenchRandomGenerator() { Free(); } + void Free() + { + ::MidFree(Buffer); + Buffer = 0; + } + bool Alloc(UInt32 bufferSize) + { + if (Buffer != 0 && BufferSize == bufferSize) + return true; + Free(); + Buffer = (Byte *)::MidAlloc(bufferSize); + Pos = 0; + BufferSize = bufferSize; + return (Buffer != 0); + } + UInt32 GetRndBit() { return RG.GetRnd(1); } + /* + UInt32 GetLogRand(int maxLen) + { + UInt32 len = GetRnd() % (maxLen + 1); + return GetRnd() & ((1 << len) - 1); + } + */ + UInt32 GetLogRandBits(int numBits) + { + UInt32 len = RG.GetRnd(numBits); + return RG.GetRnd(len); + } + UInt32 GetOffset() + { + if (GetRndBit() == 0) + return GetLogRandBits(4); + return (GetLogRandBits(4) << 10) | RG.GetRnd(10); + } + UInt32 GetLen1() { return RG.GetRnd(1 + (int)RG.GetRnd(2)); } + UInt32 GetLen2() { return RG.GetRnd(2 + (int)RG.GetRnd(2)); } + void Generate() + { + RG.Init(); + Rep0 = 1; + while(Pos < BufferSize) + { + if (GetRndBit() == 0 || Pos < 1) + Buffer[Pos++] = (Byte)RG.GetRnd(8); + else + { + UInt32 len; + if (RG.GetRnd(3) == 0) + len = 1 + GetLen1(); + else + { + do + Rep0 = GetOffset(); + while (Rep0 >= Pos); + Rep0++; + len = 2 + GetLen2(); + } + for (UInt32 i = 0; i < len && Pos < BufferSize; i++, Pos++) + Buffer[Pos] = Buffer[Pos - Rep0]; + } + } + } +}; + +class CBenchmarkInStream: + public ISequentialInStream, + public CMyUnknownImp +{ + const Byte *Data; + UInt32 Pos; + UInt32 Size; +public: + MY_UNKNOWN_IMP + void Init(const Byte *data, UInt32 size) + { + Data = data; + Size = size; + Pos = 0; + } + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); +}; + +STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 remain = Size - Pos; + if (size > remain) + size = remain; + for (UInt32 i = 0; i < size; i++) + ((Byte *)data)[i] = Data[Pos + i]; + Pos += size; + if(processedSize != NULL) + *processedSize = size; + return S_OK; +} + +class CBenchmarkOutStream: + public ISequentialOutStream, + public CMyUnknownImp +{ + UInt32 BufferSize; + FILE *_f; +public: + UInt32 Pos; + Byte *Buffer; + CBenchmarkOutStream(): _f(0), Buffer(0) {} + virtual ~CBenchmarkOutStream() { delete []Buffer; } + void Init(FILE *f, UInt32 bufferSize) + { + delete []Buffer; + Buffer = 0; + Buffer = new Byte[bufferSize]; + Pos = 0; + BufferSize = bufferSize; + _f = f; + } + MY_UNKNOWN_IMP + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 i; + for (i = 0; i < size && Pos < BufferSize; i++) + Buffer[Pos++] = ((const Byte *)data)[i]; + if(processedSize != NULL) + *processedSize = i; + if (i != size) + { + fprintf(_f, "\nERROR: Buffer is full\n"); + return E_FAIL; + } + return S_OK; +} + +class CCrcOutStream: + public ISequentialOutStream, + public CMyUnknownImp +{ +public: + CCRC CRC; + MY_UNKNOWN_IMP + void Init() { CRC.Init(); } + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +STDMETHODIMP CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + CRC.Update(data, size); + if(processedSize != NULL) + *processedSize = size; + return S_OK; +} + +static UInt64 GetTimeCount() +{ + #ifdef _WIN32 + LARGE_INTEGER value; + if (::QueryPerformanceCounter(&value)) + return value.QuadPart; + return GetTickCount(); + #else + return clock(); + #endif +} + +static UInt64 GetFreq() +{ + #ifdef _WIN32 + LARGE_INTEGER value; + if (::QueryPerformanceFrequency(&value)) + return value.QuadPart; + return 1000; + #else + return CLOCKS_PER_SEC; + #endif +} + +struct CProgressInfo: + public ICompressProgressInfo, + public CMyUnknownImp +{ + UInt64 ApprovedStart; + UInt64 InSize; + UInt64 Time; + void Init() + { + InSize = 0; + Time = 0; + } + MY_UNKNOWN_IMP + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); +}; + +STDMETHODIMP CProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */) +{ + if (*inSize >= ApprovedStart && InSize == 0) + { + Time = ::GetTimeCount(); + InSize = *inSize; + } + return S_OK; +} + +static const int kSubBits = 8; + +static UInt32 GetLogSize(UInt32 size) +{ + for (int i = kSubBits; i < 32; i++) + for (UInt32 j = 0; j < (1 << kSubBits); j++) + if (size <= (((UInt32)1) << i) + (j << (i - kSubBits))) + return (i << kSubBits) + j; + return (32 << kSubBits); +} + +static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime) +{ + UInt64 freq = GetFreq(); + UInt64 elTime = elapsedTime; + while(freq > 1000000) + { + freq >>= 1; + elTime >>= 1; + } + if (elTime == 0) + elTime = 1; + return value * freq / elTime; +} + +static UInt64 GetCompressRating(UInt32 dictionarySize, UInt64 elapsedTime, UInt64 size) +{ + UInt64 t = GetLogSize(dictionarySize) - (18 << kSubBits); + UInt64 numCommandsForOne = 1060 + ((t * t * 10) >> (2 * kSubBits)); + UInt64 numCommands = (UInt64)(size) * numCommandsForOne; + return MyMultDiv64(numCommands, elapsedTime); +} + +static UInt64 GetDecompressRating(UInt64 elapsedTime, + UInt64 outSize, UInt64 inSize) +{ + UInt64 numCommands = inSize * 220 + outSize * 20; + return MyMultDiv64(numCommands, elapsedTime); +} + +/* +static UInt64 GetTotalRating( + UInt32 dictionarySize, + bool isBT4, + UInt64 elapsedTimeEn, UInt64 sizeEn, + UInt64 elapsedTimeDe, + UInt64 inSizeDe, UInt64 outSizeDe) +{ + return (GetCompressRating(dictionarySize, isBT4, elapsedTimeEn, sizeEn) + + GetDecompressRating(elapsedTimeDe, inSizeDe, outSizeDe)) / 2; +} +*/ + +static void PrintRating(FILE *f, UInt64 rating) +{ + fprintf(f, "%5d MIPS", (unsigned int)(rating / 1000000)); +} + +static void PrintResults( + FILE *f, + UInt32 dictionarySize, + UInt64 elapsedTime, + UInt64 size, + bool decompressMode, UInt64 secondSize) +{ + UInt64 speed = MyMultDiv64(size, elapsedTime); + fprintf(f, "%6d KB/s ", (unsigned int)(speed / 1024)); + UInt64 rating; + if (decompressMode) + rating = GetDecompressRating(elapsedTime, size, secondSize); + else + rating = GetCompressRating(dictionarySize, elapsedTime, size); + PrintRating(f, rating); +} + +static void ThrowError(FILE *f, HRESULT result, const char *s) +{ + fprintf(f, "\nError: "); + if (result == E_ABORT) + fprintf(f, "User break"); + if (result == E_OUTOFMEMORY) + fprintf(f, "Can not allocate memory"); + else + fprintf(f, s); + fprintf(f, "\n"); +} + +const wchar_t *bt2 = L"BT2"; +const wchar_t *bt4 = L"BT4"; + +int LzmaBenchmark(FILE *f, UInt32 numIterations, UInt32 dictionarySize) +{ + if (numIterations == 0) + return 0; + if (dictionarySize < (1 << 18)) + { + fprintf(f, "\nError: dictionary size for benchmark must be >= 19 (512 KB)\n"); + return 1; + } + fprintf(f, "\n Compressing Decompressing\n\n"); + NCompress::NLZMA::CEncoder *encoderSpec = new NCompress::NLZMA::CEncoder; + CMyComPtr encoder = encoderSpec; + + NCompress::NLZMA::CDecoder *decoderSpec = new NCompress::NLZMA::CDecoder; + CMyComPtr decoder = decoderSpec; + + CBenchmarkOutStream *propStreamSpec = new CBenchmarkOutStream; + CMyComPtr propStream = propStreamSpec; + propStreamSpec->Init(f, kMaxLzmaPropSize); + + PROPID propIDs[] = + { + NCoderPropID::kDictionarySize + }; + const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]); + PROPVARIANT properties[kNumProps]; + properties[0].vt = VT_UI4; + properties[0].ulVal = UInt32(dictionarySize); + + const UInt32 kBufferSize = dictionarySize + kAdditionalSize; + const UInt32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize; + + if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK) + { + fprintf(f, "\nError: Incorrect command\n"); + return 1; + } + encoderSpec->WriteCoderProperties(propStream); + + CBenchRandomGenerator rg; + if (!rg.Alloc(kBufferSize)) + { + fprintf(f, "\nError: Can't allocate memory\n"); + return 1; + } + + rg.Generate(); + CCRC crc; + crc.Update(rg.Buffer, rg.BufferSize); + + CProgressInfo *progressInfoSpec = new CProgressInfo; + CMyComPtr progressInfo = progressInfoSpec; + + progressInfoSpec->ApprovedStart = dictionarySize; + + UInt64 totalBenchSize = 0; + UInt64 totalEncodeTime = 0; + UInt64 totalDecodeTime = 0; + UInt64 totalCompressedSize = 0; + + for (UInt32 i = 0; i < numIterations; i++) + { + progressInfoSpec->Init(); + CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream; + inStreamSpec->Init(rg.Buffer, rg.BufferSize); + CMyComPtr inStream = inStreamSpec; + CBenchmarkOutStream *outStreamSpec = new CBenchmarkOutStream; + outStreamSpec->Init(f, kCompressedBufferSize); + CMyComPtr outStream = outStreamSpec; + HRESULT result = encoder->Code(inStream, outStream, 0, 0, progressInfo); + UInt64 encodeTime = ::GetTimeCount() - progressInfoSpec->Time; + UInt32 compressedSize = outStreamSpec->Pos; + if(result != S_OK) + { + ThrowError(f, result, "Encoder Error"); + return 1; + } + if (progressInfoSpec->InSize == 0) + { + fprintf(f, "\nError: Internal ERROR 1282\n"); + return 1; + } + + /////////////////////// + // Decompressing + + CCrcOutStream *crcOutStreamSpec = new CCrcOutStream; + CMyComPtr crcOutStream = crcOutStreamSpec; + + UInt64 decodeTime = 0; + for (int j = 0; j < 2; j++) + { + inStreamSpec->Init(outStreamSpec->Buffer, compressedSize); + crcOutStreamSpec->Init(); + + if (decoderSpec->SetDecoderProperties2(propStreamSpec->Buffer, propStreamSpec->Pos) != S_OK) + { + fprintf(f, "\nError: Set Decoder Properties Error\n"); + return 1; + } + UInt64 outSize = kBufferSize; + UInt64 startTime = ::GetTimeCount(); + result = decoder->Code(inStream, crcOutStream, 0, &outSize, 0); + decodeTime = ::GetTimeCount() - startTime; + if(result != S_OK) + { + ThrowError(f, result, "Decode Error"); + return 1; + } + if (crcOutStreamSpec->CRC.GetDigest() != crc.GetDigest()) + { + fprintf(f, "\nError: CRC Error\n"); + return 1; + } + } + UInt64 benchSize = kBufferSize - progressInfoSpec->InSize; + PrintResults(f, dictionarySize, encodeTime, benchSize, false, 0); + fprintf(f, " "); + PrintResults(f, dictionarySize, decodeTime, kBufferSize, true, compressedSize); + fprintf(f, "\n"); + + totalBenchSize += benchSize; + totalEncodeTime += encodeTime; + totalDecodeTime += decodeTime; + totalCompressedSize += compressedSize; + } + fprintf(f, "---------------------------------------------------\n"); + PrintResults(f, dictionarySize, totalEncodeTime, totalBenchSize, false, 0); + fprintf(f, " "); + PrintResults(f, dictionarySize, totalDecodeTime, + kBufferSize * numIterations, true, totalCompressedSize); + fprintf(f, " Average\n"); + return 0; +} diff --git a/CPP/7zip/Compress/LZMA_Alone/LzmaBench.h b/CPP/7zip/Compress/LZMA_Alone/LzmaBench.h new file mode 100755 index 00000000..a6a0e82e --- /dev/null +++ b/CPP/7zip/Compress/LZMA_Alone/LzmaBench.h @@ -0,0 +1,11 @@ +// LzmaBench.h + +#ifndef __LzmaBench_h +#define __LzmaBench_h + +#include +#include "../../../Common/Types.h" + +int LzmaBenchmark(FILE *f, UInt32 numIterations, UInt32 dictionarySize); + +#endif diff --git a/CPP/7zip/Compress/LZMA_Alone/LzmaRam.cpp b/CPP/7zip/Compress/LZMA_Alone/LzmaRam.cpp new file mode 100755 index 00000000..31ca1c74 --- /dev/null +++ b/CPP/7zip/Compress/LZMA_Alone/LzmaRam.cpp @@ -0,0 +1,227 @@ +// LzmaRam.cpp + +#include "StdAfx.h" +#include "../../../Common/Types.h" +#include "../LZMA/LZMADecoder.h" +#include "../LZMA/LZMAEncoder.h" +#include "LzmaRam.h" + +extern "C" +{ + #include "../../../../C/Compress/Branch/BranchX86.h" +} + +class CInStreamRam: + public ISequentialInStream, + public CMyUnknownImp +{ + const Byte *Data; + size_t Size; + size_t Pos; +public: + MY_UNKNOWN_IMP + void Init(const Byte *data, size_t size) + { + Data = data; + Size = size; + Pos = 0; + } + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); +}; + +STDMETHODIMP CInStreamRam::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + if (size > (Size - Pos)) + size = (UInt32)(Size - Pos); + for (UInt32 i = 0; i < size; i++) + ((Byte *)data)[i] = Data[Pos + i]; + Pos += size; + if(processedSize != NULL) + *processedSize = size; + return S_OK; +} + +class COutStreamRam: + public ISequentialOutStream, + public CMyUnknownImp +{ + size_t Size; +public: + Byte *Data; + size_t Pos; + bool Overflow; + void Init(Byte *data, size_t size) + { + Data = data; + Size = size; + Pos = 0; + Overflow = false; + } + void SetPos(size_t pos) + { + Overflow = false; + Pos = pos; + } + MY_UNKNOWN_IMP + HRESULT WriteByte(Byte b) + { + if (Pos >= Size) + { + Overflow = true; + return E_FAIL; + } + Data[Pos++] = b; + return S_OK; + } + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +STDMETHODIMP COutStreamRam::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 i; + for (i = 0; i < size && Pos < Size; i++) + Data[Pos++] = ((const Byte *)data)[i]; + if(processedSize != NULL) + *processedSize = i; + if (i != size) + { + Overflow = true; + return E_FAIL; + } + return S_OK; +} + +#define SZ_RAM_E_FAIL (1) +#define SZ_RAM_E_OUTOFMEMORY (2) +#define SZE_OUT_OVERFLOW (3) + +int LzmaRamEncode( + const Byte *inBuffer, size_t inSize, + Byte *outBuffer, size_t outSize, size_t *outSizeProcessed, + UInt32 dictionarySize, ESzFilterMode filterMode) +{ + #ifndef _NO_EXCEPTIONS + try { + #endif + + *outSizeProcessed = 0; + const size_t kIdSize = 1; + const size_t kLzmaPropsSize = 5; + const size_t kMinDestSize = kIdSize + kLzmaPropsSize + 8; + if (outSize < kMinDestSize) + return SZE_OUT_OVERFLOW; + NCompress::NLZMA::CEncoder *encoderSpec = new NCompress::NLZMA::CEncoder; + CMyComPtr encoder = encoderSpec; + + PROPID propIDs[] = + { + NCoderPropID::kAlgorithm, + NCoderPropID::kDictionarySize, + NCoderPropID::kNumFastBytes, + }; + const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]); + PROPVARIANT properties[kNumProps]; + properties[0].vt = VT_UI4; + properties[1].vt = VT_UI4; + properties[2].vt = VT_UI4; + properties[0].ulVal = (UInt32)2; + properties[1].ulVal = (UInt32)dictionarySize; + properties[2].ulVal = (UInt32)64; + + if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK) + return 1; + + COutStreamRam *outStreamSpec = new COutStreamRam; + if (outStreamSpec == 0) + return SZ_RAM_E_OUTOFMEMORY; + CMyComPtr outStream = outStreamSpec; + CInStreamRam *inStreamSpec = new CInStreamRam; + if (inStreamSpec == 0) + return SZ_RAM_E_OUTOFMEMORY; + CMyComPtr inStream = inStreamSpec; + + outStreamSpec->Init(outBuffer, outSize); + if (outStreamSpec->WriteByte(0) != S_OK) + return SZE_OUT_OVERFLOW; + + if (encoderSpec->WriteCoderProperties(outStream) != S_OK) + return SZE_OUT_OVERFLOW; + if (outStreamSpec->Pos != kIdSize + kLzmaPropsSize) + return 1; + + int i; + for (i = 0; i < 8; i++) + { + UInt64 t = (UInt64)(inSize); + if (outStreamSpec->WriteByte((Byte)((t) >> (8 * i))) != S_OK) + return SZE_OUT_OVERFLOW; + } + + Byte *filteredStream = 0; + + bool useFilter = (filterMode != SZ_FILTER_NO); + if (useFilter) + { + if (inSize != 0) + { + filteredStream = (Byte *)MyAlloc(inSize); + if (filteredStream == 0) + return SZ_RAM_E_OUTOFMEMORY; + memmove(filteredStream, inBuffer, inSize); + } + UInt32 _prevMask; + UInt32 _prevPos; + x86_Convert_Init(_prevMask, _prevPos); + x86_Convert(filteredStream, (UInt32)inSize, 0, &_prevMask, &_prevPos, 1); + } + + size_t minSize = 0; + int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1; + bool bestIsFiltered = false; + int mainResult = 0; + size_t startPos = outStreamSpec->Pos; + for (i = 0; i < numPasses; i++) + { + if (numPasses > 1 && i == numPasses - 1 && !bestIsFiltered) + break; + outStreamSpec->SetPos(startPos); + bool curModeIsFiltered = false; + if (useFilter && i == 0) + curModeIsFiltered = true; + if (numPasses > 1 && i == numPasses - 1) + curModeIsFiltered = true; + + inStreamSpec->Init(curModeIsFiltered ? filteredStream : inBuffer, inSize); + + HRESULT lzmaResult = encoder->Code(inStream, outStream, 0, 0, 0); + + mainResult = 0; + if (lzmaResult == E_OUTOFMEMORY) + { + mainResult = SZ_RAM_E_OUTOFMEMORY; + break; + } + if (i == 0 || outStreamSpec->Pos <= minSize) + { + minSize = outStreamSpec->Pos; + bestIsFiltered = curModeIsFiltered; + } + if (outStreamSpec->Overflow) + mainResult = SZE_OUT_OVERFLOW; + else if (lzmaResult != S_OK) + { + mainResult = SZ_RAM_E_FAIL; + break; + } + } + *outSizeProcessed = outStreamSpec->Pos; + if (bestIsFiltered) + outBuffer[0] = 1; + if (useFilter) + MyFree(filteredStream); + return mainResult; + + #ifndef _NO_EXCEPTIONS + } catch(...) { return SZ_RAM_E_OUTOFMEMORY; } + #endif +} diff --git a/CPP/7zip/Compress/LZMA_Alone/LzmaRam.h b/CPP/7zip/Compress/LZMA_Alone/LzmaRam.h new file mode 100755 index 00000000..1244dc86 --- /dev/null +++ b/CPP/7zip/Compress/LZMA_Alone/LzmaRam.h @@ -0,0 +1,46 @@ +// LzmaRam.h + +#ifndef __LzmaRam_h +#define __LzmaRam_h + +#include +#include "../../../Common/Types.h" + +/* +LzmaRamEncode: BCJ + LZMA RAM->RAM compressing. +It uses .lzma format, but it writes one additional byte to .lzma file: + 0: - no filter + 1: - x86(BCJ) filter. + +To provide best compression ratio dictionarySize mustbe >= inSize + +LzmaRamEncode allocates Data with MyAlloc/BigAlloc functions. +RAM Requirements: + RamSize = dictionarySize * 9.5 + 6MB + FilterBlockSize + FilterBlockSize = 0, if useFilter == false + FilterBlockSize = inSize, if useFilter == true + + Return code: + 0 - OK + 1 - Unspecified Error + 2 - Memory allocating error + 3 - Output buffer OVERFLOW + +If you use SZ_FILTER_AUTO mode, then encoder will use 2 or 3 passes: + 2 passes when FILTER_NO provides better compression. + 3 passes when FILTER_YES provides better compression. +*/ + +enum ESzFilterMode +{ + SZ_FILTER_NO, + SZ_FILTER_YES, + SZ_FILTER_AUTO +}; + +int LzmaRamEncode( + const Byte *inBuffer, size_t inSize, + Byte *outBuffer, size_t outSize, size_t *outSizeProcessed, + UInt32 dictionarySize, ESzFilterMode filterMode); + +#endif diff --git a/CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.c b/CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.c new file mode 100755 index 00000000..0767ba21 --- /dev/null +++ b/CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.c @@ -0,0 +1,79 @@ +/* LzmaRamDecode.c */ + +#include "LzmaRamDecode.h" +#ifdef _SZ_ONE_DIRECTORY +#include "LzmaDecode.h" +#include "BranchX86.h" +#else +#include "../../../../C/Compress/Lzma/LzmaDecode.h" +#include "../../../../C/Compress/Branch/BranchX86.h" +#endif + +#define LZMA_PROPS_SIZE 14 +#define LZMA_SIZE_OFFSET 6 + +int LzmaRamGetUncompressedSize( + const unsigned char *inBuffer, + size_t inSize, + size_t *outSize) +{ + unsigned int i; + if (inSize < LZMA_PROPS_SIZE) + return 1; + *outSize = 0; + for(i = 0; i < sizeof(size_t); i++) + *outSize += ((size_t)inBuffer[LZMA_SIZE_OFFSET + i]) << (8 * i); + for(; i < 8; i++) + if (inBuffer[LZMA_SIZE_OFFSET + i] != 0) + return 1; + return 0; +} + +#define SZE_DATA_ERROR (1) +#define SZE_OUTOFMEMORY (2) + +int LzmaRamDecompress( + const unsigned char *inBuffer, + size_t inSize, + unsigned char *outBuffer, + size_t outSize, + size_t *outSizeProcessed, + void * (*allocFunc)(size_t size), + void (*freeFunc)(void *)) +{ + CLzmaDecoderState state; /* it's about 24 bytes structure, if int is 32-bit */ + int result; + SizeT outSizeProcessedLoc; + SizeT inProcessed; + int useFilter; + + if (inSize < LZMA_PROPS_SIZE) + return 1; + useFilter = inBuffer[0]; + + *outSizeProcessed = 0; + if (useFilter > 1) + return 1; + + if (LzmaDecodeProperties(&state.Properties, inBuffer + 1, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK) + return 1; + state.Probs = (CProb *)allocFunc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb)); + if (state.Probs == 0) + return SZE_OUTOFMEMORY; + + result = LzmaDecode(&state, + inBuffer + LZMA_PROPS_SIZE, (SizeT)inSize - LZMA_PROPS_SIZE, &inProcessed, + outBuffer, (SizeT)outSize, &outSizeProcessedLoc); + freeFunc(state.Probs); + if (result != LZMA_RESULT_OK) + return 1; + *outSizeProcessed = (size_t)outSizeProcessedLoc; + if (useFilter == 1) + { + UInt32 _prevMask; + UInt32 _prevPos; + x86_Convert_Init(_prevMask, _prevPos); + x86_Convert(outBuffer, (UInt32)outSizeProcessedLoc, 0, &_prevMask, &_prevPos, 0); + } + return 0; +} diff --git a/CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.h b/CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.h new file mode 100755 index 00000000..7e641c55 --- /dev/null +++ b/CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.h @@ -0,0 +1,55 @@ +/* LzmaRamDecode.h */ + +#ifndef __LzmaRamDecode_h +#define __LzmaRamDecode_h + +#include + +/* +LzmaRamGetUncompressedSize: + In: + inBuffer - input data + inSize - input data size + Out: + outSize - uncompressed size + Return code: + 0 - OK + 1 - Error in headers +*/ + +int LzmaRamGetUncompressedSize( + const unsigned char *inBuffer, + size_t inSize, + size_t *outSize); + + +/* +LzmaRamDecompress: + In: + inBuffer - input data + inSize - input data size + outBuffer - output data + outSize - output size + allocFunc - alloc function (can be malloc) + freeFunc - free function (can be free) + Out: + outSizeProcessed - processed size + Return code: + 0 - OK + 1 - Error in headers / data stream + 2 - Memory allocating error + +Memory requirements depend from properties of LZMA stream. +With default lzma settings it's about 16 KB. +*/ + +int LzmaRamDecompress( + const unsigned char *inBuffer, + size_t inSize, + unsigned char *outBuffer, + size_t outSize, + size_t *outSizeProcessed, + void * (*allocFunc)(size_t size), + void (*freeFunc)(void *)); + +#endif diff --git a/CPP/7zip/Compress/LZMA_Alone/StdAfx.cpp b/CPP/7zip/Compress/LZMA_Alone/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Compress/LZMA_Alone/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Compress/LZMA_Alone/StdAfx.h b/CPP/7zip/Compress/LZMA_Alone/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Compress/LZMA_Alone/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Compress/LZMA_Alone/makefile b/CPP/7zip/Compress/LZMA_Alone/makefile new file mode 100755 index 00000000..d3d80d88 --- /dev/null +++ b/CPP/7zip/Compress/LZMA_Alone/makefile @@ -0,0 +1,124 @@ +PROG = lzma.exe +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib user32.lib + +!IFDEF CPU +LIBS = $(LIBS) bufferoverflowU.lib +CFLAGS = $(CFLAGS) -GS- -Zc:forScope -W4 -Wp64 -DUNICODE -D_UNICODE +!ENDIF + +!IFNDEF O +!IFDEF CPU +O=$(CPU) +!ELSE +O=O +!ENDIF +!ENDIF + +!IFDEF MY_STATIC_LINK +!IFNDEF MY_SINGLE_THREAD +CFLAGS = $(CFLAGS) -MT +!ENDIF +!ELSE +CFLAGS = $(CFLAGS) -MD +!ENDIF + + +CFLAGS = $(CFLAGS) -nologo -EHsc -c -Fo$O/ -WX +CFLAGS_O1 = $(CFLAGS) -O1 +CFLAGS_O2 = $(CFLAGS) -O2 + +LFLAGS = $(LFLAGS) -nologo -OPT:NOWIN98 + +PROGPATH = $O\$(PROG) + +COMPL_O1 = $(CPP) $(CFLAGS_O1) $** +COMPL_O2 = $(CPP) $(CFLAGS_O2) $** +COMPL = $(CPP) $(CFLAGS_O1) $** + + +LZMA_OBJS = \ + $O\LzmaAlone.obj \ + $O\LzmaBench.obj \ + $O\LzmaRam.obj \ + +LZMA_OPT_OBJS = \ + $O\LZMADecoder.obj \ + $O\LZMAEncoder.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CRC.obj \ + $O\CommandLineParser.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\Vector.obj + +7ZIP_COMMON_OBJS = \ + $O\InBuffer.obj \ + $O\OutBuffer.obj \ + $O\StreamUtils.obj \ + +LZ_OBJS = \ + $O\LZOutWindow.obj \ + +C_OBJS = \ + $O\7zCrc.obj \ + +C_LZ_OBJS = \ + $O\MatchFinder.obj \ + +OBJS = \ + $(LZMA_OBJS) \ + $(LZMA_OPT_OBJS) \ + $(COMMON_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(LZ_OBJS) \ + $(C_OBJS) \ + $(C_LZ_OBJS) \ + $O\LzmaRamDecode.obj \ + $O\LzmaDecode.obj \ + $O\FileStreams.obj \ + $O\FileIO.obj \ + $O\RangeCoderBit.obj \ + $O\BranchX86.obj \ + +all: $(PROGPATH) + +clean: + -del /Q $(PROGPATH) $O\*.exe $O\*.dll $O\*.obj $O\*.lib $O\*.exp $O\*.res $O\*.pch + +$O: + if not exist "$O" mkdir "$O" + +$(PROGPATH): $O $(OBJS) + link $(LFLAGS) -out:$(PROGPATH) $(OBJS) $(LIBS) + + +$(LZMA_OBJS): $(*B).cpp + $(COMPL) +$(LZMA_OPT_OBJS): ../LZMA/$(*B).cpp + $(COMPL_O2) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(LZ_OBJS): ../LZ/$(*B).cpp + $(COMPL) +$O\RangeCoderBit.obj: ../RangeCoder/$(*B).cpp + $(COMPL) +$O\LzmaRamDecode.obj: LzmaRamDecode.c + $(COMPL_O1) +$O\LzmaDecode.obj: ../../../../C/Compress/Lzma/LzmaDecode.c + $(COMPL_O2) +$O\BranchX86.obj: ../../../../C/Compress/Branch/BranchX86.c + $(COMPL_O2) +$O\FileStreams.obj: ../../Common/FileStreams.cpp + $(COMPL) +$O\FileIO.obj: ../../../Windows/FileIO.cpp + $(COMPL) +$(C_OBJS): ../../../../C/$(*B).c + $(COMPL_O2) +$(C_LZ_OBJS): ../../../../C/Compress/Lz/$(*B).c + $(COMPL_O2) diff --git a/CPP/7zip/Compress/LZMA_Alone/makefile.gcc b/CPP/7zip/Compress/LZMA_Alone/makefile.gcc new file mode 100755 index 00000000..b83717a5 --- /dev/null +++ b/CPP/7zip/Compress/LZMA_Alone/makefile.gcc @@ -0,0 +1,117 @@ +PROG = lzma +CXX = g++ -O2 -Wall +CXX_C = gcc -O2 -Wall +LIB = -lm +RM = rm -f +CFLAGS = -c -I ../../../ + +OBJS = \ + LzmaAlone.o \ + LzmaBench.o \ + LzmaRam.o \ + LzmaRamDecode.o \ + LzmaDecode.o \ + BranchX86.o \ + LZMADecoder.o \ + LZMAEncoder.o \ + 7zCrc.o \ + MatchFinder.o \ + LZOutWindow.o \ + RangeCoderBit.o \ + InBuffer.o \ + OutBuffer.o \ + FileStreams.o \ + StreamUtils.o \ + Alloc.o \ + C_FileIO.o \ + CommandLineParser.o \ + CRC.o \ + String.o \ + StringConvert.o \ + StringToInt.o \ + Vector.o \ + + +all: $(PROG) + +$(PROG): $(OBJS) + $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB) + +LzmaAlone.o: LzmaAlone.cpp + $(CXX) $(CFLAGS) LzmaAlone.cpp + +LzmaBench.o: LzmaBench.cpp + $(CXX) $(CFLAGS) LzmaBench.cpp + +LzmaRam.o: LzmaRam.cpp + $(CXX) $(CFLAGS) LzmaRam.cpp + +LzmaRamDecode.o: LzmaRamDecode.c + $(CXX_C) $(CFLAGS) LzmaRamDecode.c + +LzmaDecode.o: ../../../../C/Compress/Lzma/LzmaDecode.c + $(CXX_C) $(CFLAGS) ../../../../C/Compress/Lzma/LzmaDecode.c + +BranchX86.o: ../../../../C/Compress/Branch/BranchX86.c + $(CXX_C) $(CFLAGS) ../../../../C/Compress/Branch/BranchX86.c + +LZMADecoder.o: ../LZMA/LZMADecoder.cpp + $(CXX) $(CFLAGS) ../LZMA/LZMADecoder.cpp + +LZMAEncoder.o: ../LZMA/LZMAEncoder.cpp + $(CXX) $(CFLAGS) ../LZMA/LZMAEncoder.cpp + +MatchFinder.o: ../../../../C/Compress/Lz/MatchFinder.c + $(CXX_C) $(CFLAGS) ../../../../C/Compress/Lz/MatchFinder.c + +7zCrc.o: ../../../../C/7zCrc.c + $(CXX_C) $(CFLAGS) ../../../../C/7zCrc.c + +LZOutWindow.o: ../LZ/LZOutWindow.cpp + $(CXX) $(CFLAGS) ../LZ/LZOutWindow.cpp + +RangeCoderBit.o: ../RangeCoder/RangeCoderBit.cpp + $(CXX) $(CFLAGS) ../RangeCoder/RangeCoderBit.cpp + +InBuffer.o: ../../Common/InBuffer.cpp + $(CXX) $(CFLAGS) ../../Common/InBuffer.cpp + +OutBuffer.o: ../../Common/OutBuffer.cpp + $(CXX) $(CFLAGS) ../../Common/OutBuffer.cpp + +FileStreams.o: ../../Common/FileStreams.cpp + $(CXX) $(CFLAGS) ../../Common/FileStreams.cpp + +StreamUtils.o: ../../Common/StreamUtils.cpp + $(CXX) $(CFLAGS) ../../Common/StreamUtils.cpp + +Alloc.o: ../../../Common/Alloc.cpp + $(CXX) $(CFLAGS) ../../../Common/Alloc.cpp + +C_FileIO.o: ../../../Common/C_FileIO.cpp + $(CXX) $(CFLAGS) ../../../Common/C_FileIO.cpp + +CommandLineParser.o: ../../../Common/CommandLineParser.cpp + $(CXX) $(CFLAGS) ../../../Common/CommandLineParser.cpp + +CRC.o: ../../../Common/CRC.cpp + $(CXX) $(CFLAGS) ../../../Common/CRC.cpp + +MyWindows.o: ../../../Common/MyWindows.cpp + $(CXX) $(CFLAGS) ../../../Common/MyWindows.cpp + +String.o: ../../../Common/String.cpp + $(CXX) $(CFLAGS) ../../../Common/String.cpp + +StringConvert.o: ../../../Common/StringConvert.cpp + $(CXX) $(CFLAGS) ../../../Common/StringConvert.cpp + +StringToInt.o: ../../../Common/StringToInt.cpp + $(CXX) $(CFLAGS) ../../../Common/StringToInt.cpp + +Vector.o: ../../../Common/Vector.cpp + $(CXX) $(CFLAGS) ../../../Common/Vector.cpp + +clean: + -$(RM) $(PROG) $(OBJS) + diff --git a/CPP/7zip/Compress/Lzh/LzhDecoder.cpp b/CPP/7zip/Compress/Lzh/LzhDecoder.cpp new file mode 100755 index 00000000..5a661047 --- /dev/null +++ b/CPP/7zip/Compress/Lzh/LzhDecoder.cpp @@ -0,0 +1,216 @@ +// LzhDecoder.cpp + +#include "StdAfx.h" + +#include "LzhDecoder.h" + +#include "Windows/Defs.h" + +namespace NCompress{ +namespace NLzh { +namespace NDecoder { + +static const UInt32 kHistorySize = (1 << 16); + +static const int kBlockSizeBits = 16; +static const int kNumCBits = 9; +static const int kNumLevelBits = 5; // smallest integer such that (1 << kNumLevelBits) > kNumLevelSymbols/ + +UInt32 CCoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); } + +HRESULT CCoder::ReadLevelTable() +{ + int n = ReadBits(kNumLevelBits); + if (n == 0) + { + m_LevelHuffman.Symbol = ReadBits(kNumLevelBits); + if (m_LevelHuffman.Symbol >= kNumLevelSymbols) + return S_FALSE; + } + else + { + if (n > kNumLevelSymbols) + return S_FALSE; + m_LevelHuffman.Symbol = -1; + Byte lens[kNumLevelSymbols]; + int i = 0; + while (i < n) + { + int c = m_InBitStream.ReadBits(3); + if (c == 7) + while (ReadBits(1)) + if (c++ > kMaxHuffmanLen) + return S_FALSE; + lens[i++] = (Byte)c; + if (i == kNumSpecLevelSymbols) + { + c = ReadBits(2); + while (--c >= 0) + lens[i++] = 0; + } + } + while (i < kNumLevelSymbols) + lens[i++] = 0; + m_LevelHuffman.SetCodeLengths(lens); + } + return S_OK; +} + +HRESULT CCoder::ReadPTable(int numBits) +{ + int n = ReadBits(numBits); + if (n == 0) + { + m_PHuffmanDecoder.Symbol = ReadBits(numBits); + if (m_PHuffmanDecoder.Symbol >= kNumDistanceSymbols) + return S_FALSE; + } + else + { + if (n > kNumDistanceSymbols) + return S_FALSE; + m_PHuffmanDecoder.Symbol = -1; + Byte lens[kNumDistanceSymbols]; + int i = 0; + while (i < n) + { + int c = m_InBitStream.ReadBits(3); + if (c == 7) + while (ReadBits(1)) + { + if (c > kMaxHuffmanLen) + return S_FALSE; + c++; + } + lens[i++] = (Byte)c; + } + while (i < kNumDistanceSymbols) + lens[i++] = 0; + m_PHuffmanDecoder.SetCodeLengths(lens); + } + return S_OK; +} + +HRESULT CCoder::ReadCTable() +{ + int n = ReadBits(kNumCBits); + if (n == 0) + { + m_CHuffmanDecoder.Symbol = ReadBits(kNumCBits); + if (m_CHuffmanDecoder.Symbol >= kNumCSymbols) + return S_FALSE; + } + else + { + if (n > kNumCSymbols) + return S_FALSE; + m_CHuffmanDecoder.Symbol = -1; + Byte lens[kNumCSymbols]; + int i = 0; + while (i < n) + { + int c = m_LevelHuffman.Decode(&m_InBitStream); + if (c < kNumSpecLevelSymbols) + { + if (c == 0) + c = 1; + else if (c == 1) + c = ReadBits(4) + 3; + else + c = ReadBits(kNumCBits) + 20; + while (--c >= 0) + { + if (i > kNumCSymbols) + return S_FALSE; + lens[i++] = 0; + } + } + else + lens[i++] = (Byte)(c - 2); + } + while (i < kNumCSymbols) + lens[i++] = 0; + m_CHuffmanDecoder.SetCodeLengths(lens); + } + return S_OK; +} + +STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + if (outSize == NULL) + return E_INVALIDARG; + + if (!m_OutWindowStream.Create(kHistorySize)) + return E_OUTOFMEMORY; + if (!m_InBitStream.Create(1 << 20)) + return E_OUTOFMEMORY; + + UInt64 pos = 0; + m_OutWindowStream.SetStream(outStream); + m_OutWindowStream.Init(false); + m_InBitStream.SetStream(inStream); + m_InBitStream.Init(); + + CCoderReleaser coderReleaser(this); + + int pbit; + if (m_NumDictBits <= 13) + pbit = 4; + else + pbit = 5; + + UInt32 blockSize = 0; + + while(pos < *outSize) + { + // for (i = 0; i < dictSize; i++) dtext[i] = 0x20; + + if (blockSize == 0) + { + if (progress != NULL) + { + UInt64 packSize = m_InBitStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &pos)); + } + blockSize = ReadBits(kBlockSizeBits); + ReadLevelTable(); + ReadCTable(); + RINOK(ReadPTable(pbit)); + } + blockSize--; + UInt32 c = m_CHuffmanDecoder.Decode(&m_InBitStream); + if (c < 256) + { + m_OutWindowStream.PutByte((Byte)c); + pos++; + } + else + { + // offset = (interface->method == LARC_METHOD_NUM) ? 0x100 - 2 : 0x100 - 3; + UInt32 len = c - 256 + kMinMatch; + UInt32 distance = m_PHuffmanDecoder.Decode(&m_InBitStream); + if (distance != 0) + distance = (1 << (distance - 1)) + ReadBits(distance - 1); + pos += len; + if (distance >= pos) + throw 1; + m_OutWindowStream.CopyBlock(distance, len); + } + } + coderReleaser.NeedFlush = false; + return m_OutWindowStream.Flush(); +} + +STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress);} + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const CLZOutWindowException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +}}} diff --git a/CPP/7zip/Compress/Lzh/LzhDecoder.h b/CPP/7zip/Compress/Lzh/LzhDecoder.h new file mode 100755 index 00000000..79f71b88 --- /dev/null +++ b/CPP/7zip/Compress/Lzh/LzhDecoder.h @@ -0,0 +1,103 @@ +// LzhDecoder.h + +#ifndef __COMPRESS_LZH_DECODER_H +#define __COMPRESS_LZH_DECODER_H + +#include "../../../Common/MyCom.h" +#include "../../ICoder.h" +#include "../../Common/MSBFDecoder.h" +#include "../../Common/InBuffer.h" +#include "../Huffman/HuffmanDecoder.h" +#include "../LZ/LZOutWindow.h" + +namespace NCompress { +namespace NLzh { +namespace NDecoder { + +const int kMaxHuffmanLen = 16; // Check it + +const int kNumSpecLevelSymbols = 3; +const int kNumLevelSymbols = kNumSpecLevelSymbols + kMaxHuffmanLen; + +const int kDictBitsMax = 16; +const int kNumDistanceSymbols = kDictBitsMax + 1; + +const int kMaxMatch = 256; +const int kMinMatch = 3; +const int kNumCSymbols = 256 + kMaxMatch + 2 - kMinMatch; + +template +class CHuffmanDecoder:public NCompress::NHuffman::CDecoder +{ +public: + int Symbol; + template + UInt32 Decode(TBitDecoder *bitStream) + { + if (Symbol >= 0) + return (UInt32)Symbol; + return DecodeSymbol(bitStream); + } +}; + +class CCoder : + public ICompressCoder, + public CMyUnknownImp +{ + CLZOutWindow m_OutWindowStream; + NStream::NMSBF::CDecoder m_InBitStream; + + int m_NumDictBits; + + CHuffmanDecoder m_LevelHuffman; + CHuffmanDecoder m_PHuffmanDecoder; + CHuffmanDecoder m_CHuffmanDecoder; + + void ReleaseStreams() + { + m_OutWindowStream.ReleaseStream(); + m_InBitStream.ReleaseStream(); + } + + class CCoderReleaser + { + CCoder *m_Coder; + public: + bool NeedFlush; + CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {} + ~CCoderReleaser() + { + if (NeedFlush) + m_Coder->m_OutWindowStream.Flush(); + m_Coder->ReleaseStreams(); + } + }; + friend class CCoderReleaser; + + void MakeTable(int nchar, Byte *bitlen, int tablebits, + UInt32 *table, int tablesize); + + UInt32 ReadBits(int numBits); + HRESULT ReadLevelTable(); + HRESULT ReadPTable(int numBits); + HRESULT ReadCTable(); + +public: + + MY_UNKNOWN_IMP + + STDMETHOD(CodeReal)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + void SetDictionary(int numDictBits) { m_NumDictBits = numDictBits; } + CCoder(): m_NumDictBits(0) {} +}; + +}}} + +#endif diff --git a/CPP/7zip/Compress/Lzx/Lzx.h b/CPP/7zip/Compress/Lzx/Lzx.h new file mode 100755 index 00000000..386a17c3 --- /dev/null +++ b/CPP/7zip/Compress/Lzx/Lzx.h @@ -0,0 +1,61 @@ +// Lzx.h + +#ifndef __COMPRESS_LZX_H +#define __COMPRESS_LZX_H + +namespace NCompress { +namespace NLzx { + +const int kNumHuffmanBits = 16; +const UInt32 kNumRepDistances = 3; + +const UInt32 kNumLenSlots = 8; +const UInt32 kMatchMinLen = 2; +const UInt32 kNumLenSymbols = 249; +const UInt32 kMatchMaxLen = kMatchMinLen + (kNumLenSlots - 1) + kNumLenSymbols - 1; + +const int kNumAlignBits = 3; +const UInt32 kAlignTableSize = 1 << kNumAlignBits; + +const UInt32 kNumPosSlots = 50; +const UInt32 kNumPosLenSlots = kNumPosSlots * kNumLenSlots; + +const UInt32 kMainTableSize = 256 + kNumPosLenSlots; +const UInt32 kLevelTableSize = 20; +const UInt32 kMaxTableSize = kMainTableSize; + +const int kNumBlockTypeBits = 3; +const int kBlockTypeVerbatim = 1; +const int kBlockTypeAligned = 2; +const int kBlockTypeUncompressed = 3; + +const int kUncompressedBlockSizeNumBits = 24; + +const int kNumBitsForPreTreeLevel = 4; + +const int kLevelSymbolZeros = 17; +const int kLevelSymbolZerosBig = 18; +const int kLevelSymbolSame = 19; + +const int kLevelSymbolZerosStartValue = 4; +const int kLevelSymbolZerosNumBits = 4; + +const int kLevelSymbolZerosBigStartValue = kLevelSymbolZerosStartValue + + (1 << kLevelSymbolZerosNumBits); +const int kLevelSymbolZerosBigNumBits = 5; + +const int kLevelSymbolSameNumBits = 1; +const int kLevelSymbolSameStartValue = 4; + +const int kNumBitsForAlignLevel = 3; + +const int kNumDictionaryBitsMin = 15; +const int kNumDictionaryBitsMax = 21; +const UInt32 kDictionarySizeMax = (1 << kNumDictionaryBitsMax); + +const int kNumLinearPosSlotBits = 17; +const UInt32 kNumPowerPosSlots = 0x26; + +}} + +#endif diff --git a/CPP/7zip/Compress/Lzx/Lzx86Converter.cpp b/CPP/7zip/Compress/Lzx/Lzx86Converter.cpp new file mode 100755 index 00000000..1265dba0 --- /dev/null +++ b/CPP/7zip/Compress/Lzx/Lzx86Converter.cpp @@ -0,0 +1,90 @@ +// Lzx86Converter.cpp + +#include "StdAfx.h" + +#include "Common/Defs.h" + +#include "Lzx86Converter.h" + +namespace NCompress { +namespace NLzx { + +static const int kResidue = 6 + 4; + +void Cx86ConvertOutStream::MakeTranslation() +{ + if (m_Pos <= kResidue) + return; + UInt32 numBytes = m_Pos - kResidue; + Byte *buffer = m_Buffer; + for (UInt32 i = 0; i < numBytes;) + { + if (buffer[i++] == 0xE8) + { + Int32 absValue = 0; + int j; + for(j = 0; j < 4; j++) + absValue += (UInt32)buffer[i + j] << (j * 8); + Int32 pos = (Int32)(m_ProcessedSize + i - 1); + if (absValue >= -pos && absValue < (Int32)m_TranslationSize) + { + UInt32 offset = (absValue >= 0) ? + absValue - pos : + absValue + m_TranslationSize; + for(j = 0; j < 4; j++) + { + buffer[i + j] = (Byte)(offset & 0xFF); + offset >>= 8; + } + } + i += 4; + } + } +} + +STDMETHODIMP Cx86ConvertOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize != NULL) + *processedSize = 0; + if (!m_TranslationMode) + return m_Stream->Write(data, size, processedSize); + UInt32 realProcessedSize = 0; + while (realProcessedSize < size) + { + UInt32 writeSize = MyMin(size - realProcessedSize, kUncompressedBlockSize - m_Pos); + memmove(m_Buffer + m_Pos, (const Byte *)data + realProcessedSize, writeSize); + m_Pos += writeSize; + realProcessedSize += writeSize; + if (m_Pos == kUncompressedBlockSize) + { + RINOK(Flush()); + } + } + if (processedSize != NULL) + *processedSize = realProcessedSize; + return S_OK; +} + +HRESULT Cx86ConvertOutStream::Flush() +{ + if (m_Pos == 0) + return S_OK; + if (m_TranslationMode) + MakeTranslation(); + UInt32 pos = 0; + do + { + UInt32 processed; + RINOK(m_Stream->Write(m_Buffer + pos, m_Pos - pos, &processed)); + if (processed == 0) + return E_FAIL; + pos += processed; + } + while(pos < m_Pos); + m_ProcessedSize += m_Pos; + m_Pos = 0; + m_TranslationMode = (m_TranslationMode && (m_ProcessedSize < (1 << 30))); + return S_OK; +} + +}} diff --git a/CPP/7zip/Compress/Lzx/Lzx86Converter.h b/CPP/7zip/Compress/Lzx/Lzx86Converter.h new file mode 100755 index 00000000..b507a612 --- /dev/null +++ b/CPP/7zip/Compress/Lzx/Lzx86Converter.h @@ -0,0 +1,45 @@ +// Lzx/x86Converter.h + +#ifndef __LZX_X86CONVERTER_H +#define __LZX_X86CONVERTER_H + +#include "Common/MyCom.h" +#include "../../IStream.h" + +namespace NCompress { +namespace NLzx { + +const int kUncompressedBlockSize = 1 << 15; + +class Cx86ConvertOutStream: + public ISequentialOutStream, + public CMyUnknownImp +{ + CMyComPtr m_Stream; + UInt32 m_ProcessedSize; + UInt32 m_Pos; + UInt32 m_TranslationSize; + bool m_TranslationMode; + Byte m_Buffer[kUncompressedBlockSize]; + + void MakeTranslation(); +public: + void SetStream(ISequentialOutStream *outStream) { m_Stream = outStream; } + void ReleaseStream() { m_Stream.Release(); } + void Init(bool translationMode, UInt32 translationSize) + { + m_TranslationMode = translationMode; + m_TranslationSize = translationSize; + m_ProcessedSize = 0; + m_Pos = 0; + } + HRESULT Flush(); + + MY_UNKNOWN_IMP + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +}} + +#endif diff --git a/CPP/7zip/Compress/Lzx/LzxDecoder.cpp b/CPP/7zip/Compress/Lzx/LzxDecoder.cpp new file mode 100755 index 00000000..e854af32 --- /dev/null +++ b/CPP/7zip/Compress/Lzx/LzxDecoder.cpp @@ -0,0 +1,382 @@ +// LzxDecoder.cpp + +#include "StdAfx.h" + +#include "LzxDecoder.h" + +#include "Common/Defs.h" +#include "Common/Alloc.h" +#include "Windows/Defs.h" + +namespace NCompress { +namespace NLzx { + +const int kLenIdNeedInit = -2; + +CDecoder::CDecoder(): + _keepHistory(false), + m_AlignPos(0) +{ + m_x86ConvertOutStreamSpec = new Cx86ConvertOutStream; + m_x86ConvertOutStream = m_x86ConvertOutStreamSpec; +} + +void CDecoder::ReleaseStreams() +{ + m_OutWindowStream.ReleaseStream(); + m_InBitStream.ReleaseStream(); + m_x86ConvertOutStreamSpec->ReleaseStream(); +} + +STDMETHODIMP CDecoder::Flush() +{ + RINOK(m_OutWindowStream.Flush()); + return m_x86ConvertOutStreamSpec->Flush(); +} + +UInt32 CDecoder::ReadBits(UInt32 numBits) { return m_InBitStream.ReadBits(numBits); } + +#define RIF(x) { if (!(x)) return false; } + +bool CDecoder::ReadTable(Byte *lastLevels, Byte *newLevels, UInt32 numSymbols) +{ + Byte levelLevels[kLevelTableSize]; + UInt32 i; + for (i = 0; i < kLevelTableSize; i++) + levelLevels[i] = (Byte)ReadBits(kNumBitsForPreTreeLevel); + RIF(m_LevelDecoder.SetCodeLengths(levelLevels)); + int num = 0; + Byte symbol = 0; + for (i = 0; i < numSymbols;) + { + if (num != 0) + { + lastLevels[i] = newLevels[i] = symbol; + i++; + num--; + continue; + } + UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); + if (number == kLevelSymbolZeros) + { + num = kLevelSymbolZerosStartValue + ReadBits(kLevelSymbolZerosNumBits); + symbol = 0; + } + else if (number == kLevelSymbolZerosBig) + { + num = kLevelSymbolZerosBigStartValue + ReadBits(kLevelSymbolZerosBigNumBits); + symbol = 0; + } + else if (number == kLevelSymbolSame || number <= kNumHuffmanBits) + { + if (number <= kNumHuffmanBits) + num = 1; + else + { + num = kLevelSymbolSameStartValue + ReadBits(kLevelSymbolSameNumBits); + number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); + if (number > kNumHuffmanBits) + return false; + } + symbol = Byte((17 + lastLevels[i] - number) % (kNumHuffmanBits + 1)); + } + else + return false; + } + return true; +} + +bool CDecoder::ReadTables(void) +{ + Byte newLevels[kMaxTableSize]; + { + int blockType = (int)ReadBits(kNumBlockTypeBits); + if (blockType > kBlockTypeUncompressed) + return false; + m_UnCompressedBlockSize = m_InBitStream.ReadBitsBig(kUncompressedBlockSizeNumBits); + + m_IsUncompressedBlock = (blockType == kBlockTypeUncompressed); + if (m_IsUncompressedBlock) + { + m_InBitStream.ReadBits(16 - m_InBitStream.GetBitPosition()); + if (!m_InBitStream.ReadUInt32(m_RepDistances[0])) + return false; + m_RepDistances[0]--; + for (int i = 1; i < kNumRepDistances; i++) + { + UInt32 rep = 0; + for (int j = 0; j < 4; j++) + rep |= (UInt32)m_InBitStream.DirectReadByte() << (8 * j); + m_RepDistances[i] = rep - 1; + } + return true; + } + m_AlignIsUsed = (blockType == kBlockTypeAligned); + if (m_AlignIsUsed) + { + for(int i = 0; i < kAlignTableSize; i++) + newLevels[i] = (Byte)ReadBits(kNumBitsForAlignLevel); + RIF(m_AlignDecoder.SetCodeLengths(newLevels)); + } + } + + RIF(ReadTable(m_LastMainLevels, newLevels, 256)); + RIF(ReadTable(m_LastMainLevels + 256, newLevels + 256, m_NumPosLenSlots)); + for (UInt32 i = 256 + m_NumPosLenSlots; i < kMainTableSize; i++) + newLevels[i] = 0; + RIF(m_MainDecoder.SetCodeLengths(newLevels)); + + RIF(ReadTable(m_LastLenLevels, newLevels, kNumLenSymbols)); + return m_LenDecoder.SetCodeLengths(newLevels); +} + +class CDecoderFlusher +{ + CDecoder *m_Decoder; +public: + bool NeedFlush; + CDecoderFlusher(CDecoder *decoder): m_Decoder(decoder), NeedFlush(true) {} + ~CDecoderFlusher() + { + if (NeedFlush) + m_Decoder->Flush(); + m_Decoder->ReleaseStreams(); + } +}; + + +void CDecoder::ClearPrevLevels() +{ + int i; + for (i = 0; i < kMainTableSize; i++) + m_LastMainLevels[i] = 0; + for (i = 0; i < kNumLenSymbols; i++) + m_LastLenLevels[i] = 0; +}; + + +HRESULT CDecoder::CodeSpec(UInt32 curSize) +{ + if (_remainLen == kLenIdNeedInit) + { + _remainLen = 0; + if (_keepHistory && m_IsUncompressedBlock && m_UnCompressedBlockSize > 0) + m_InBitStream.InitDirect(); + else + m_InBitStream.InitNormal(); + if (!_keepHistory) + { + m_UnCompressedBlockSize = 0; + ClearPrevLevels(); + UInt32 i86TranslationSize = 0; + bool translationMode = (ReadBits(1) != 0); + if (translationMode) + { + i86TranslationSize = ReadBits(16) << 16; + i86TranslationSize |= ReadBits(16); + } + m_x86ConvertOutStreamSpec->Init(translationMode, i86TranslationSize); + + for(int i = 0 ; i < kNumRepDistances; i++) + m_RepDistances[i] = 0; + } + } + + if (curSize == 0) + return S_OK; + + while(_remainLen > 0 && curSize > 0) + { + m_OutWindowStream.PutByte(m_OutWindowStream.GetByte(m_RepDistances[0])); + _remainLen--; + curSize--; + } + + while(curSize > 0) + { + if (m_UnCompressedBlockSize == 0) + if (!ReadTables()) + return S_FALSE; + UInt32 next = (Int32)MyMin(m_UnCompressedBlockSize, curSize); + curSize -= next; + m_UnCompressedBlockSize -= next; + if (m_IsUncompressedBlock) + { + while(next > 0) + { + m_OutWindowStream.PutByte(m_InBitStream.DirectReadByte()); + next--; + } + if (m_UnCompressedBlockSize == 0) + { + m_InBitStream.Align(m_AlignPos); + // m_AlignPos = 0; + } + } + else while(next > 0) + { + UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); + if (number < 256) + { + m_OutWindowStream.PutByte((Byte)number); + next--; + } + else + { + UInt32 posLenSlot = number - 256; + if (posLenSlot >= m_NumPosLenSlots) + return S_FALSE; + UInt32 posSlot = posLenSlot / kNumLenSlots; + UInt32 lenSlot = posLenSlot % kNumLenSlots; + UInt32 len = kMatchMinLen + lenSlot; + if (lenSlot == kNumLenSlots - 1) + { + UInt32 lenTemp = m_LenDecoder.DecodeSymbol(&m_InBitStream); + if (lenTemp >= kNumLenSymbols) + return S_FALSE; + len += lenTemp; + } + + if (posSlot < kNumRepDistances) + { + UInt32 distance = m_RepDistances[posSlot]; + m_RepDistances[posSlot] = m_RepDistances[0]; + m_RepDistances[0] = distance; + } + else + { + UInt32 distance; + int numDirectBits; + if (posSlot < kNumPowerPosSlots) + { + numDirectBits = (posSlot >> 1) - 1; + distance = ((2 | (posSlot & 1)) << numDirectBits); + } + else + { + numDirectBits = kNumLinearPosSlotBits; + distance = ((posSlot - 0x22) << kNumLinearPosSlotBits); + } + + if (m_AlignIsUsed && numDirectBits >= kNumAlignBits) + { + distance += (m_InBitStream.ReadBits(numDirectBits - kNumAlignBits) << kNumAlignBits); + UInt32 alignTemp = m_AlignDecoder.DecodeSymbol(&m_InBitStream); + if (alignTemp >= kAlignTableSize) + return S_FALSE; + distance += alignTemp; + } + else + distance += m_InBitStream.ReadBits(numDirectBits); + m_RepDistances[2] = m_RepDistances[1]; + m_RepDistances[1] = m_RepDistances[0]; + m_RepDistances[0] = distance - kNumRepDistances; + } + + UInt32 locLen = len; + if (locLen > next) + locLen = next; + + if (!m_OutWindowStream.CopyBlock(m_RepDistances[0], locLen)) + return S_FALSE; + + len -= locLen; + next -= locLen; + if (len != 0) + { + _remainLen = len; + return S_OK; + } + } + } + } + return S_OK; +} + +HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + if (outSize == NULL) + return E_INVALIDARG; + UInt64 size = *outSize; + + RINOK(SetInStream(inStream)); + m_x86ConvertOutStreamSpec->SetStream(outStream); + m_OutWindowStream.SetStream(m_x86ConvertOutStream); + RINOK(SetOutStreamSize(outSize)); + + CDecoderFlusher flusher(this); + + const UInt64 start = m_OutWindowStream.GetProcessedSize(); + for (;;) + { + UInt32 curSize = 1 << 18; + UInt64 rem = size - (m_OutWindowStream.GetProcessedSize() - start); + if (curSize > rem) + curSize = (UInt32)rem; + if (curSize == 0) + break; + RINOK(CodeSpec(curSize)); + if (progress != NULL) + { + UInt64 inSize = m_InBitStream.GetProcessedSize(); + UInt64 nowPos64 = m_OutWindowStream.GetProcessedSize() - start; + RINOK(progress->SetRatioInfo(&inSize, &nowPos64)); + } + } + flusher.NeedFlush = false; + return Flush(); +} + +HRESULT CDecoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const CLZOutWindowException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) +{ + m_InBitStream.SetStream(inStream); + return S_OK; +} + +STDMETHODIMP CDecoder::ReleaseInStream() +{ + m_InBitStream.ReleaseStream(); + return S_OK; +} + +STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) +{ + if (outSize == NULL) + return E_FAIL; + _remainLen = kLenIdNeedInit; + m_OutWindowStream.Init(_keepHistory); + return S_OK; +} + +HRESULT CDecoder::SetParams(int numDictBits) +{ + if (numDictBits < kNumDictionaryBitsMin || numDictBits > kNumDictionaryBitsMax) + return E_INVALIDARG; + UInt32 numPosSlots; + if (numDictBits < 20) + numPosSlots = 30 + (numDictBits - 15) * 2; + else if (numDictBits == 20) + numPosSlots = 42; + else + numPosSlots = 50; + m_NumPosLenSlots = numPosSlots * kNumLenSlots; + if (!m_OutWindowStream.Create(kDictionarySizeMax)) + return E_OUTOFMEMORY; + if (!m_InBitStream.Create(1 << 16)) + return E_OUTOFMEMORY; + return S_OK; +} + +}} diff --git a/CPP/7zip/Compress/Lzx/LzxDecoder.h b/CPP/7zip/Compress/Lzx/LzxDecoder.h new file mode 100755 index 00000000..a62662ec --- /dev/null +++ b/CPP/7zip/Compress/Lzx/LzxDecoder.h @@ -0,0 +1,181 @@ +// LzxDecoder.h + +#ifndef __LZXDECODER_H +#define __LZXDECODER_H + +#include "../../ICoder.h" + +#include "../../Compress/Huffman/HuffmanDecoder.h" +#include "../../Compress/LZ/LZOutWindow.h" +#include "../../Common/InBuffer.h" + +#include "Lzx.h" +#include "Lzx86Converter.h" + +namespace NCompress { +namespace NLzx { + +namespace NBitStream { + +const int kNumBigValueBits = 8 * 4; +const int kNumValueBits = 17; +const UInt32 kBitDecoderValueMask = (1 << kNumValueBits) - 1; + +class CDecoder +{ + CInBuffer m_Stream; + UInt32 m_Value; + int m_BitPos; +public: + CDecoder() {} + bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } + + void SetStream(ISequentialInStream *s) { m_Stream.SetStream(s); } + void ReleaseStream() { m_Stream.ReleaseStream(); } + + void InitNormal() + { + m_Stream.Init(); + m_BitPos = kNumBigValueBits; + Normalize(); + } + + void InitDirect() + { + m_Stream.Init(); + m_BitPos = kNumBigValueBits; + } + + UInt64 GetProcessedSize() const + { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; } + + int GetBitPosition() const { return m_BitPos & 0xF; } + + void Normalize() + { + for (;m_BitPos >= 16; m_BitPos -= 16) + { + Byte b0 = m_Stream.ReadByte(); + Byte b1 = m_Stream.ReadByte(); + m_Value = (m_Value << 8) | b1; + m_Value = (m_Value << 8) | b0; + } + } + + UInt32 GetValue(int numBits) const + { + return ((m_Value >> ((32 - kNumValueBits) - m_BitPos)) & kBitDecoderValueMask) >> + (kNumValueBits - numBits); + } + + void MovePos(UInt32 numBits) + { + m_BitPos += numBits; + Normalize(); + } + + UInt32 ReadBits(int numBits) + { + UInt32 res = GetValue(numBits); + MovePos(numBits); + return res; + } + + UInt32 ReadBitsBig(int numBits) + { + UInt32 numBits0 = numBits / 2; + UInt32 numBits1 = numBits - numBits0; + UInt32 res = ReadBits(numBits0) << numBits1; + return res + ReadBits(numBits1); + } + + bool ReadUInt32(UInt32 &v) + { + if (m_BitPos != 0) + return false; + v = ((m_Value >> 16) & 0xFFFF) | ((m_Value << 16) & 0xFFFF0000); + m_BitPos = kNumBigValueBits; + return true; + } + + Byte DirectReadByte() { return m_Stream.ReadByte(); } + + void Align(int alignPos) + { + if (((m_Stream.GetProcessedSize() + alignPos) & 1) != 0) + m_Stream.ReadByte(); + Normalize(); + } +}; +} + +class CDecoder : + public ICompressCoder, + public CMyUnknownImp +{ + NBitStream::CDecoder m_InBitStream; + CLZOutWindow m_OutWindowStream; + + UInt32 m_RepDistances[kNumRepDistances]; + UInt32 m_NumPosLenSlots; + + bool m_IsUncompressedBlock; + bool m_AlignIsUsed; + + NCompress::NHuffman::CDecoder m_MainDecoder; + NCompress::NHuffman::CDecoder m_LenDecoder; + NCompress::NHuffman::CDecoder m_AlignDecoder; + NCompress::NHuffman::CDecoder m_LevelDecoder; + + Byte m_LastMainLevels[kMainTableSize]; + Byte m_LastLenLevels[kNumLenSymbols]; + + Cx86ConvertOutStream *m_x86ConvertOutStreamSpec; + CMyComPtr m_x86ConvertOutStream; + + UInt32 m_UnCompressedBlockSize; + + bool _keepHistory; + int _remainLen; + int m_AlignPos; + + UInt32 ReadBits(UInt32 numBits); + bool ReadTable(Byte *lastLevels, Byte *newLevels, UInt32 numSymbols); + bool ReadTables(); + void ClearPrevLevels(); + + HRESULT CodeSpec(UInt32 size); + + HRESULT CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); +public: + CDecoder(); + + MY_UNKNOWN_IMP + + void ReleaseStreams(); + STDMETHOD(Flush)(); + + // ICompressCoder interface + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(SetInStream)(ISequentialInStream *inStream); + STDMETHOD(ReleaseInStream)(); + STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); + + HRESULT SetParams(int numDictBits); + void SetKeepHistory(bool keepHistory, int alignPos) + { + _keepHistory = keepHistory; + m_AlignPos = alignPos; + } +}; + +}} + +#endif diff --git a/CPP/7zip/Compress/Lzx/StdAfx.h b/CPP/7zip/Compress/Lzx/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Compress/Lzx/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Compress/PPMD/DllExports.cpp b/CPP/7zip/Compress/PPMD/DllExports.cpp new file mode 100755 index 00000000..8159a2f8 --- /dev/null +++ b/CPP/7zip/Compress/PPMD/DllExports.cpp @@ -0,0 +1,93 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#ifdef _WIN32 +#include "Common/Alloc.h" +#endif + +#include "PPMDEncoder.h" +#include "PPMDDecoder.h" + +// {23170F69-40C1-278B-0304-010000000000} +DEFINE_GUID(CLSID_CCompressPPMDDecoder, +0x23170F69, 0x40C1, 0x278B, 0x03, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00); + +// {23170F69-40C1-278B-0304-010000000100} +DEFINE_GUID(CLSID_CCompressPPMDEncoder, +0x23170F69, 0x40C1, 0x278B, 0x03, 0x04, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD dwReason, LPVOID /*lpReserved*/) +{ + #ifdef _WIN32 + if (dwReason == DLL_PROCESS_ATTACH) + SetLargePageSize(); + #endif + return TRUE; +} + +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + int correctInterface = (*iid == IID_ICompressCoder); + CMyComPtr coder; + if (*clsid == CLSID_CCompressPPMDDecoder) + { + if (!correctInterface) + return E_NOINTERFACE; + coder = (ICompressCoder *)new NCompress::NPPMD::CDecoder(); + } + else if (*clsid == CLSID_CCompressPPMDEncoder) + { + if (!correctInterface) + return E_NOINTERFACE; + coder = (ICompressCoder *)new NCompress::NPPMD::CEncoder(); + } + else + return CLASS_E_CLASSNOTAVAILABLE; + *outObject = coder.Detach(); + COM_TRY_END + return S_OK; +} + +STDAPI GetNumberOfMethods(UINT32 *numMethods) +{ + *numMethods = 1; + return S_OK; +} + +STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +{ + if (index != 0) + return E_INVALIDARG; + ::VariantClear((tagVARIANT *)value); + switch(propID) + { + case NMethodPropID::kID: + { + const char id[] = { 0x03, 0x04, 0x01 }; + if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NMethodPropID::kName: + if ((value->bstrVal = ::SysAllocString(L"PPMD")) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kDecoder: + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CCompressPPMDDecoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kEncoder: + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CCompressPPMDEncoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + return S_OK; +} diff --git a/CPP/7zip/Compress/PPMD/PPMD.dsp b/CPP/7zip/Compress/PPMD/PPMD.dsp new file mode 100755 index 00000000..9e512f6c --- /dev/null +++ b/CPP/7zip/Compress/PPMD/PPMD.dsp @@ -0,0 +1,229 @@ +# Microsoft Developer Studio Project File - Name="PPMD" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=PPMD - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "PPMD.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "PPMD.mak" CFG="PPMD - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "PPMD - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "PPMD - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "PPMD - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PPMD_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PPMD_EXPORTS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\PPMd.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "PPMD - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PPMD_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PPMD_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\PPMd.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "PPMD - Win32 Release" +# Name "PPMD - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Codec.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "PPMD" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\PPMDContext.h +# End Source File +# Begin Source File + +SOURCE=.\PPMDDecode.h +# End Source File +# Begin Source File + +SOURCE=.\PPMDDecoder.cpp + +!IF "$(CFG)" == "PPMD - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "PPMD - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\PPMDDecoder.h +# End Source File +# Begin Source File + +SOURCE=.\PPMDEncode.h +# End Source File +# Begin Source File + +SOURCE=.\PPMDEncoder.cpp + +!IF "$(CFG)" == "PPMD - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "PPMD - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\PPMDEncoder.h +# End Source File +# Begin Source File + +SOURCE=.\PPMDSubAlloc.h +# End Source File +# Begin Source File + +SOURCE=.\PPMDType.h +# End Source File +# End Group +# Begin Group "7zip common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "RangeCoder" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\RangeCoder\RangeCoder.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Types.h +# End Source File +# End Group +# End Target +# End Project diff --git a/CPP/7zip/Compress/PPMD/PPMD.dsw b/CPP/7zip/Compress/PPMD/PPMD.dsw new file mode 100755 index 00000000..8032f3db --- /dev/null +++ b/CPP/7zip/Compress/PPMD/PPMD.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "PPMD"=.\PPMD.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Compress/PPMD/PPMDContext.h b/CPP/7zip/Compress/PPMD/PPMDContext.h new file mode 100755 index 00000000..a6a8dd60 --- /dev/null +++ b/CPP/7zip/Compress/PPMD/PPMDContext.h @@ -0,0 +1,489 @@ +// Compress/PPMD/Context.h +// This code is based on Dmitry Shkarin's PPMdH code + +#ifndef __COMPRESS_PPMD_CONTEXT_H +#define __COMPRESS_PPMD_CONTEXT_H + +#include "../../../Common/Types.h" + +#include "../RangeCoder/RangeCoder.h" +#include "PPMDSubAlloc.h" + +namespace NCompress { +namespace NPPMD { + +const int INT_BITS=7, PERIOD_BITS=7, TOT_BITS=INT_BITS+PERIOD_BITS, + INTERVAL=1 << INT_BITS, BIN_SCALE=1 << TOT_BITS, MAX_FREQ=124; + +struct SEE2_CONTEXT +{ + // SEE-contexts for PPM-contexts with masked symbols + UInt16 Summ; + Byte Shift, Count; + void init(int InitVal) { Summ = (UInt16)(InitVal << (Shift=PERIOD_BITS-4)); Count=4; } + unsigned int getMean() + { + unsigned int RetVal=(Summ >> Shift); + Summ = (UInt16)(Summ - RetVal); + return RetVal+(RetVal == 0); + } + void update() + { + if (Shift < PERIOD_BITS && --Count == 0) + { + Summ <<= 1; + Count = (Byte)(3 << Shift++); + } + } +}; + +struct PPM_CONTEXT +{ + UInt16 NumStats; // sizeof(UInt16) > sizeof(Byte) + UInt16 SummFreq; + + struct STATE + { + Byte Symbol, Freq; + UInt16 SuccessorLow; + UInt16 SuccessorHigh; + + UInt32 GetSuccessor() const { return SuccessorLow | ((UInt32)SuccessorHigh << 16); } + void SetSuccessor(UInt32 v) + { + SuccessorLow = (UInt16)(v & 0xFFFF); + SuccessorHigh = (UInt16)((v >> 16) & 0xFFFF); + } + }; + + UInt32 Stats; + UInt32 Suffix; + + PPM_CONTEXT* createChild(CSubAllocator &subAllocator, STATE* pStats, STATE& FirstState) + { + PPM_CONTEXT* pc = (PPM_CONTEXT*) subAllocator.AllocContext(); + if (pc) + { + pc->NumStats = 1; + pc->oneState() = FirstState; + pc->Suffix = subAllocator.GetOffset(this); + pStats->SetSuccessor(subAllocator.GetOffsetNoCheck(pc)); + } + return pc; + } + + STATE& oneState() const { return (STATE&) SummFreq; } +}; + +///////////////////////////////// + +const UInt16 InitBinEsc[] = + {0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051}; + +struct CInfo +{ + CSubAllocator SubAllocator; + SEE2_CONTEXT SEE2Cont[25][16], DummySEE2Cont; + PPM_CONTEXT * MinContext, * MaxContext; + + PPM_CONTEXT::STATE* FoundState; // found next state transition + int NumMasked, InitEsc, OrderFall, RunLength, InitRL, MaxOrder; + Byte CharMask[256], NS2Indx[256], NS2BSIndx[256], HB2Flag[256]; + Byte EscCount, PrintCount, PrevSuccess, HiBitsFlag; + UInt16 BinSumm[128][64]; // binary SEE-contexts + + UInt16 &GetBinSumm(const PPM_CONTEXT::STATE &rs, int numStates) + { + HiBitsFlag = HB2Flag[FoundState->Symbol]; + return BinSumm[rs.Freq - 1][ + PrevSuccess + NS2BSIndx[numStates - 1] + + HiBitsFlag + 2 * HB2Flag[rs.Symbol] + + ((RunLength >> 26) & 0x20)]; + } + + PPM_CONTEXT *GetContext(UInt32 offset) const { return (PPM_CONTEXT *)SubAllocator.GetPtr(offset); } + PPM_CONTEXT *GetContextNoCheck(UInt32 offset) const { return (PPM_CONTEXT *)SubAllocator.GetPtrNoCheck(offset); } + PPM_CONTEXT::STATE *GetState(UInt32 offset) const { return (PPM_CONTEXT::STATE *)SubAllocator.GetPtr(offset); } + PPM_CONTEXT::STATE *GetStateNoCheck(UInt32 offset) const { return (PPM_CONTEXT::STATE *)SubAllocator.GetPtr(offset); } + + void RestartModelRare() + { + int i, k, m; + memset(CharMask,0,sizeof(CharMask)); + SubAllocator.InitSubAllocator(); + InitRL = -((MaxOrder < 12) ? MaxOrder : 12) - 1; + MinContext = MaxContext = (PPM_CONTEXT*) SubAllocator.AllocContext(); + MinContext->Suffix = 0; + OrderFall = MaxOrder; + MinContext->SummFreq = (UInt16)((MinContext->NumStats = 256) + 1); + FoundState = (PPM_CONTEXT::STATE*)SubAllocator.AllocUnits(256 / 2); + MinContext->Stats = SubAllocator.GetOffsetNoCheck(FoundState); + PrevSuccess = 0; + for (RunLength = InitRL, i = 0; i < 256; i++) + { + PPM_CONTEXT::STATE &state = FoundState[i]; + state.Symbol = (Byte)i; + state.Freq = 1; + state.SetSuccessor(0); + } + for (i = 0; i < 128; i++) + for (k = 0; k < 8; k++) + for ( m=0; m < 64; m += 8) + BinSumm[i][k + m] = (UInt16)(BIN_SCALE - InitBinEsc[k] / (i + 2)); + for (i = 0; i < 25; i++) + for (k = 0; k < 16; k++) + SEE2Cont[i][k].init(5*i+10); + } + + void StartModelRare(int MaxOrder) + { + int i, k, m ,Step; + EscCount=PrintCount=1; + if (MaxOrder < 2) + { + memset(CharMask,0,sizeof(CharMask)); + OrderFall = this->MaxOrder; + MinContext = MaxContext; + while (MinContext->Suffix != 0) + { + MinContext = GetContextNoCheck(MinContext->Suffix); + OrderFall--; + } + FoundState = GetState(MinContext->Stats); + MinContext = MaxContext; + } + else + { + this->MaxOrder = MaxOrder; + RestartModelRare(); + NS2BSIndx[0] = 2 * 0; + NS2BSIndx[1] = 2 * 1; + memset(NS2BSIndx + 2, 2 * 2, 9); + memset(NS2BSIndx + 11, 2 * 3, 256 - 11); + for (i = 0; i < 3; i++) + NS2Indx[i] = (Byte)i; + for (m = i, k = Step = 1; i < 256; i++) + { + NS2Indx[i] = (Byte)m; + if ( !--k ) + { + k = ++Step; + m++; + } + } + memset(HB2Flag, 0, 0x40); + memset(HB2Flag + 0x40, 0x08, 0x100 - 0x40); + DummySEE2Cont.Shift = PERIOD_BITS; + } + } + + PPM_CONTEXT* CreateSuccessors(bool skip, PPM_CONTEXT::STATE* p1) + { + // static UpState declaration bypasses IntelC bug + // static PPM_CONTEXT::STATE UpState; + PPM_CONTEXT::STATE UpState; + + PPM_CONTEXT *pc = MinContext; + PPM_CONTEXT *UpBranch = GetContext(FoundState->GetSuccessor()); + PPM_CONTEXT::STATE * p, * ps[MAX_O], ** pps = ps; + if ( !skip ) + { + *pps++ = FoundState; + if ( !pc->Suffix ) + goto NO_LOOP; + } + if ( p1 ) + { + p = p1; + pc = GetContext(pc->Suffix); + goto LOOP_ENTRY; + } + do + { + pc = GetContext(pc->Suffix); + if (pc->NumStats != 1) + { + if ((p = GetStateNoCheck(pc->Stats))->Symbol != FoundState->Symbol) + do { p++; } while (p->Symbol != FoundState->Symbol); + } + else + p = &(pc->oneState()); +LOOP_ENTRY: + if (GetContext(p->GetSuccessor()) != UpBranch) + { + pc = GetContext(p->GetSuccessor()); + break; + } + *pps++ = p; + } + while ( pc->Suffix ); +NO_LOOP: + if (pps == ps) + return pc; + UpState.Symbol = *(Byte*) UpBranch; + UpState.SetSuccessor(SubAllocator.GetOffset(UpBranch) + 1); + if (pc->NumStats != 1) + { + if ((p = GetStateNoCheck(pc->Stats))->Symbol != UpState.Symbol) + do { p++; } while (p->Symbol != UpState.Symbol); + unsigned int cf = p->Freq-1; + unsigned int s0 = pc->SummFreq - pc->NumStats - cf; + UpState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : + ((2 * cf + 3 * s0 - 1) / (2 * s0)))); + } + else + UpState.Freq = pc->oneState().Freq; + do + { + pc = pc->createChild(SubAllocator, *--pps, UpState); + if ( !pc ) + return NULL; + } + while (pps != ps); + return pc; + } + + void UpdateModel() + { + PPM_CONTEXT::STATE fs = *FoundState, * p = NULL; + PPM_CONTEXT* pc, * Successor; + unsigned int ns1, ns, cf, sf, s0; + if (fs.Freq < MAX_FREQ / 4 && MinContext->Suffix != 0) + { + pc = GetContextNoCheck(MinContext->Suffix); + + if (pc->NumStats != 1) + { + if ((p = GetStateNoCheck(pc->Stats))->Symbol != fs.Symbol) + { + do { p++; } while (p->Symbol != fs.Symbol); + if (p[0].Freq >= p[-1].Freq) + { + _PPMD_SWAP(p[0],p[-1]); + p--; + } + } + if (p->Freq < MAX_FREQ-9) + { + p->Freq += 2; + pc->SummFreq += 2; + } + } + else + { + p = &(pc->oneState()); + p->Freq = (Byte)(p->Freq + ((p->Freq < 32) ? 1 : 0)); + } + } + if ( !OrderFall ) + { + MinContext = MaxContext = CreateSuccessors(true, p); + FoundState->SetSuccessor(SubAllocator.GetOffset(MinContext)); + if (MinContext == 0) + goto RESTART_MODEL; + return; + } + *SubAllocator.pText++ = fs.Symbol; + Successor = (PPM_CONTEXT*) SubAllocator.pText; + if (SubAllocator.pText >= SubAllocator.UnitsStart) + goto RESTART_MODEL; + if (fs.GetSuccessor() != 0) + { + if ((Byte *)GetContext(fs.GetSuccessor()) <= SubAllocator.pText) + { + PPM_CONTEXT* cs = CreateSuccessors(false, p); + fs.SetSuccessor(SubAllocator.GetOffset(cs)); + if (cs == NULL) + goto RESTART_MODEL; + } + if ( !--OrderFall ) + { + Successor = GetContext(fs.GetSuccessor()); + SubAllocator.pText -= (MaxContext != MinContext); + } + } + else + { + FoundState->SetSuccessor(SubAllocator.GetOffsetNoCheck(Successor)); + fs.SetSuccessor(SubAllocator.GetOffsetNoCheck(MinContext)); + } + s0 = MinContext->SummFreq - (ns = MinContext->NumStats) - (fs.Freq - 1); + for (pc = MaxContext; pc != MinContext; pc = GetContext(pc->Suffix)) + { + if ((ns1 = pc->NumStats) != 1) + { + if ((ns1 & 1) == 0) + { + void *ppp = SubAllocator.ExpandUnits(GetState(pc->Stats), ns1 >> 1); + pc->Stats = SubAllocator.GetOffset(ppp); + if (!ppp) + goto RESTART_MODEL; + } + pc->SummFreq = (UInt16)(pc->SummFreq + (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) & + (pc->SummFreq <= 8 * ns1))); + } + else + { + p = (PPM_CONTEXT::STATE*) SubAllocator.AllocUnits(1); + if ( !p ) + goto RESTART_MODEL; + *p = pc->oneState(); + pc->Stats = SubAllocator.GetOffsetNoCheck(p); + if (p->Freq < MAX_FREQ / 4 - 1) + p->Freq <<= 1; + else + p->Freq = MAX_FREQ - 4; + pc->SummFreq = (UInt16)(p->Freq + InitEsc + (ns > 3)); + } + cf = 2 * fs.Freq * (pc->SummFreq+6); + sf = s0 + pc->SummFreq; + if (cf < 6 * sf) + { + cf = 1 + (cf > sf)+(cf >= 4 * sf); + pc->SummFreq += 3; + } + else + { + cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf); + pc->SummFreq = (UInt16)(pc->SummFreq + cf); + } + p = GetState(pc->Stats) + ns1; + p->SetSuccessor(SubAllocator.GetOffset(Successor)); + p->Symbol = fs.Symbol; + p->Freq = (Byte)cf; + pc->NumStats = (UInt16)++ns1; + } + MaxContext = MinContext = GetContext(fs.GetSuccessor()); + return; +RESTART_MODEL: + RestartModelRare(); + EscCount = 0; + PrintCount = 0xFF; + } + + void ClearMask() + { + EscCount = 1; + memset(CharMask, 0, sizeof(CharMask)); + // if (++PrintCount == 0) + // PrintInfo(DecodedFile,EncodedFile); + } + + void update1(PPM_CONTEXT::STATE* p) + { + (FoundState = p)->Freq += 4; + MinContext->SummFreq += 4; + if (p[0].Freq > p[-1].Freq) + { + _PPMD_SWAP(p[0],p[-1]); + FoundState = --p; + if (p->Freq > MAX_FREQ) + rescale(); + } + } + + + void update2(PPM_CONTEXT::STATE* p) + { + (FoundState = p)->Freq += 4; + MinContext->SummFreq += 4; + if (p->Freq > MAX_FREQ) + rescale(); + EscCount++; + RunLength = InitRL; + } + + SEE2_CONTEXT* makeEscFreq2(int Diff, UInt32 &scale) + { + SEE2_CONTEXT* psee2c; + if (MinContext->NumStats != 256) + { + psee2c = SEE2Cont[NS2Indx[Diff-1]] + + (Diff < (GetContext(MinContext->Suffix))->NumStats - MinContext->NumStats) + + 2 * (MinContext->SummFreq < 11 * MinContext->NumStats) + + 4 * (NumMasked > Diff) + + HiBitsFlag; + scale = psee2c->getMean(); + } + else + { + psee2c = &DummySEE2Cont; + scale = 1; + } + return psee2c; + } + + + + void rescale() + { + int OldNS = MinContext->NumStats, i = MinContext->NumStats - 1, Adder, EscFreq; + PPM_CONTEXT::STATE* p1, * p; + PPM_CONTEXT::STATE *stats = GetStateNoCheck(MinContext->Stats); + for (p = FoundState; p != stats; p--) + _PPMD_SWAP(p[0], p[-1]); + stats->Freq += 4; + MinContext->SummFreq += 4; + EscFreq = MinContext->SummFreq - p->Freq; + Adder = (OrderFall != 0); + p->Freq = (Byte)((p->Freq + Adder) >> 1); + MinContext->SummFreq = p->Freq; + do + { + EscFreq -= (++p)->Freq; + p->Freq = (Byte)((p->Freq + Adder) >> 1); + MinContext->SummFreq = (UInt16)(MinContext->SummFreq + p->Freq); + if (p[0].Freq > p[-1].Freq) + { + PPM_CONTEXT::STATE tmp = *(p1 = p); + do + { + p1[0] = p1[-1]; + } + while (--p1 != stats && tmp.Freq > p1[-1].Freq); + *p1 = tmp; + } + } + while ( --i ); + if (p->Freq == 0) + { + do { i++; } while ((--p)->Freq == 0); + EscFreq += i; + MinContext->NumStats = (UInt16)(MinContext->NumStats - i); + if (MinContext->NumStats == 1) + { + PPM_CONTEXT::STATE tmp = *stats; + do { tmp.Freq = (Byte)(tmp.Freq - (tmp.Freq >> 1)); EscFreq >>= 1; } while (EscFreq > 1); + SubAllocator.FreeUnits(stats, (OldNS+1) >> 1); + *(FoundState = &MinContext->oneState()) = tmp; return; + } + } + EscFreq -= (EscFreq >> 1); + MinContext->SummFreq = (UInt16)(MinContext->SummFreq + EscFreq); + int n0 = (OldNS+1) >> 1, n1 = (MinContext->NumStats + 1) >> 1; + if (n0 != n1) + MinContext->Stats = SubAllocator.GetOffset(SubAllocator.ShrinkUnits(stats, n0, n1)); + FoundState = GetState(MinContext->Stats); + } + + void NextContext() + { + PPM_CONTEXT *c = GetContext(FoundState->GetSuccessor()); + if (!OrderFall && (Byte *)c > SubAllocator.pText) + MinContext = MaxContext = c; + else + { + UpdateModel(); + if (EscCount == 0) + ClearMask(); + } + } +}; + +// Tabulated escapes for exponential symbol distribution +const Byte ExpEscape[16]={ 25,14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 }; +#define GET_MEAN(SUMM,SHIFT,ROUND) ((SUMM+(1 << (SHIFT-ROUND))) >> (SHIFT)) + +}} + +#endif diff --git a/CPP/7zip/Compress/PPMD/PPMDDecode.h b/CPP/7zip/Compress/PPMD/PPMDDecode.h new file mode 100755 index 00000000..b05d8ee0 --- /dev/null +++ b/CPP/7zip/Compress/PPMD/PPMDDecode.h @@ -0,0 +1,154 @@ +// PPMDDecode.h +// This code is based on Dmitry Shkarin's PPMdH code + +#ifndef __COMPRESS_PPMD_DECODE_H +#define __COMPRESS_PPMD_DECODE_H + +#include "PPMDContext.h" + +namespace NCompress { +namespace NPPMD { + +class CRangeDecoderVirt +{ +public: + virtual UInt32 GetThreshold(UInt32 total) = 0; + virtual void Decode(UInt32 start, UInt32 size) = 0; + virtual UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) = 0; +}; + +typedef NRangeCoder::CDecoder CRangeDecoderMy; + +class CRangeDecoder:public CRangeDecoderVirt, public CRangeDecoderMy +{ + UInt32 GetThreshold(UInt32 total) { return CRangeDecoderMy::GetThreshold(total); } + void Decode(UInt32 start, UInt32 size) { CRangeDecoderMy::Decode(start, size); } + UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) { return CRangeDecoderMy::DecodeBit(size0, numTotalBits); } +}; + +struct CDecodeInfo: public CInfo +{ + void DecodeBinSymbol(CRangeDecoderVirt *rangeDecoder) + { + PPM_CONTEXT::STATE& rs = MinContext->oneState(); + UInt16& bs = GetBinSumm(rs, GetContextNoCheck(MinContext->Suffix)->NumStats); + if (rangeDecoder->DecodeBit(bs, TOT_BITS) == 0) + { + FoundState = &rs; + rs.Freq = (Byte)(rs.Freq + (rs.Freq < 128 ? 1: 0)); + bs = (UInt16)(bs + INTERVAL - GET_MEAN(bs, PERIOD_BITS, 2)); + PrevSuccess = 1; + RunLength++; + } + else + { + bs = (UInt16)(bs - GET_MEAN(bs, PERIOD_BITS, 2)); + InitEsc = ExpEscape[bs >> 10]; + NumMasked = 1; + CharMask[rs.Symbol] = EscCount; + PrevSuccess = 0; + FoundState = NULL; + } + } + + void DecodeSymbol1(CRangeDecoderVirt *rangeDecoder) + { + PPM_CONTEXT::STATE* p = GetStateNoCheck(MinContext->Stats); + int i, count, hiCnt; + if ((count = rangeDecoder->GetThreshold(MinContext->SummFreq)) < (hiCnt = p->Freq)) + { + PrevSuccess = (2 * hiCnt > MinContext->SummFreq); + RunLength += PrevSuccess; + rangeDecoder->Decode(0, p->Freq); // MinContext->SummFreq); + (FoundState = p)->Freq = (Byte)(hiCnt += 4); + MinContext->SummFreq += 4; + if (hiCnt > MAX_FREQ) + rescale(); + return; + } + PrevSuccess = 0; + i = MinContext->NumStats - 1; + while ((hiCnt += (++p)->Freq) <= count) + if (--i == 0) + { + HiBitsFlag = HB2Flag[FoundState->Symbol]; + rangeDecoder->Decode(hiCnt, MinContext->SummFreq - hiCnt); // , MinContext->SummFreq); + CharMask[p->Symbol] = EscCount; + i = (NumMasked = MinContext->NumStats)-1; + FoundState = NULL; + do { CharMask[(--p)->Symbol] = EscCount; } while ( --i ); + return; + } + rangeDecoder->Decode(hiCnt - p->Freq, p->Freq); // , MinContext->SummFreq); + update1(p); + } + + + void DecodeSymbol2(CRangeDecoderVirt *rangeDecoder) + { + int count, hiCnt, i = MinContext->NumStats - NumMasked; + UInt32 freqSum; + SEE2_CONTEXT* psee2c = makeEscFreq2(i, freqSum); + PPM_CONTEXT::STATE* ps[256], ** pps = ps, * p = GetStateNoCheck(MinContext->Stats)-1; + hiCnt = 0; + do + { + do { p++; } while (CharMask[p->Symbol] == EscCount); + hiCnt += p->Freq; + *pps++ = p; + } + while ( --i ); + + freqSum += hiCnt; + count = rangeDecoder->GetThreshold(freqSum); + + p = *(pps = ps); + if (count < hiCnt) + { + hiCnt = 0; + while ((hiCnt += p->Freq) <= count) + p=*++pps; + rangeDecoder->Decode(hiCnt - p->Freq, p->Freq); // , freqSum); + + psee2c->update(); + update2(p); + } + else + { + rangeDecoder->Decode(hiCnt, freqSum - hiCnt); // , freqSum); + + i = MinContext->NumStats - NumMasked; + pps--; + do { CharMask[(*++pps)->Symbol] = EscCount; } while ( --i ); + psee2c->Summ = (UInt16)(psee2c->Summ + freqSum); + NumMasked = MinContext->NumStats; + } + } + + int DecodeSymbol(CRangeDecoderVirt *rangeDecoder) + { + if (MinContext->NumStats != 1) + DecodeSymbol1(rangeDecoder); + else + DecodeBinSymbol(rangeDecoder); + while ( !FoundState ) + { + do + { + OrderFall++; + MinContext = GetContext(MinContext->Suffix); + if (MinContext == 0) + return -1; + } + while (MinContext->NumStats == NumMasked); + DecodeSymbol2(rangeDecoder); + } + Byte symbol = FoundState->Symbol; + NextContext(); + return symbol; + } +}; + +}} + +#endif diff --git a/CPP/7zip/Compress/PPMD/PPMDDecoder.cpp b/CPP/7zip/Compress/PPMD/PPMDDecoder.cpp new file mode 100755 index 00000000..2d0a2f52 --- /dev/null +++ b/CPP/7zip/Compress/PPMD/PPMDDecoder.cpp @@ -0,0 +1,184 @@ +// PPMDDecoder.cpp + +#include "StdAfx.h" + +#include "Common/Defs.h" +#include "Windows/Defs.h" + +#include "PPMDDecoder.h" + +namespace NCompress { +namespace NPPMD { + +const int kLenIdFinished = -1; +const int kLenIdNeedInit = -2; + +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *properties, UInt32 size) +{ + if (size < 5) + return E_INVALIDARG; + _order = properties[0]; + _usedMemorySize = 0; + for (int i = 0; i < 4; i++) + _usedMemorySize += ((UInt32)(properties[1 + i])) << (i * 8); + + if (_usedMemorySize > kMaxMemBlockSize) + return E_NOTIMPL; + + if (!_rangeDecoder.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!_info.SubAllocator.StartSubAllocator(_usedMemorySize)) + return E_OUTOFMEMORY; + + return S_OK; +} + +class CDecoderFlusher +{ + CDecoder *_coder; +public: + bool NeedFlush; + CDecoderFlusher(CDecoder *coder): _coder(coder), NeedFlush(true) {} + ~CDecoderFlusher() + { + if (NeedFlush) + _coder->Flush(); + _coder->ReleaseStreams(); + } +}; + +HRESULT CDecoder::CodeSpec(UInt32 size, Byte *memStream) +{ + if (_outSizeDefined) + { + const UInt64 rem = _outSize - _processedSize; + if (size > rem) + size = (UInt32)rem; + } + const UInt32 startSize = size; + + if (_remainLen == kLenIdFinished) + return S_OK; + if (_remainLen == kLenIdNeedInit) + { + _rangeDecoder.Init(); + _remainLen = 0; + _info.MaxOrder = 0; + _info.StartModelRare(_order); + } + while (size != 0) + { + int symbol = _info.DecodeSymbol(&_rangeDecoder); + if (symbol < 0) + { + _remainLen = kLenIdFinished; + break; + } + if (memStream != 0) + *memStream++ = (Byte)symbol; + else + _outStream.WriteByte((Byte)symbol); + size--; + } + _processedSize += startSize - size; + return S_OK; +} + +STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + if (!_outStream.Create(1 << 20)) + return E_OUTOFMEMORY; + + SetInStream(inStream); + _outStream.SetStream(outStream); + SetOutStreamSize(outSize); + CDecoderFlusher flusher(this); + + for (;;) + { + _processedSize = _outStream.GetProcessedSize(); + UInt32 curSize = (1 << 18); + RINOK(CodeSpec(curSize, NULL)); + if (_remainLen == kLenIdFinished) + break; + if (progress != NULL) + { + UInt64 inSize = _rangeDecoder.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&inSize, &_processedSize)); + } + if (_outSizeDefined) + if (_outStream.GetProcessedSize() >= _outSize) + break; + } + flusher.NeedFlush = false; + return Flush(); +} + +#ifdef _NO_EXCEPTIONS + +#define PPMD_TRY_BEGIN +#define PPMD_TRY_END + +#else + +#define PPMD_TRY_BEGIN try { +#define PPMD_TRY_END } \ + catch(const CInBufferException &e) { return e.ErrorCode; } \ + catch(const COutBufferException &e) { return e.ErrorCode; } \ + catch(...) { return S_FALSE; } + +#endif + + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + PPMD_TRY_BEGIN + return CodeReal(inStream, outStream, inSize, outSize, progress); + PPMD_TRY_END +} + +STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) +{ + _rangeDecoder.SetStream(inStream); + return S_OK; +} + +STDMETHODIMP CDecoder::ReleaseInStream() +{ + _rangeDecoder.ReleaseStream(); + return S_OK; +} + +STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) +{ + _outSizeDefined = (outSize != NULL); + if (_outSizeDefined) + _outSize = *outSize; + _processedSize = 0; + _remainLen = kLenIdNeedInit; + _outStream.Init(); + return S_OK; +} + +#ifdef _ST_MODE + +STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + PPMD_TRY_BEGIN + if (processedSize) + *processedSize = 0; + const UInt64 startPos = _processedSize; + RINOK(CodeSpec(size, (Byte *)data)); + if (processedSize) + *processedSize = (UInt32)(_processedSize - startPos); + return Flush(); + PPMD_TRY_END +} + +#endif + +}} diff --git a/CPP/7zip/Compress/PPMD/PPMDDecoder.h b/CPP/7zip/Compress/PPMD/PPMDDecoder.h new file mode 100755 index 00000000..8e30c35c --- /dev/null +++ b/CPP/7zip/Compress/PPMD/PPMDDecoder.h @@ -0,0 +1,89 @@ +// Compress/PPM/PPMDDecoder.h + +#ifndef __COMPRESS_PPMD_DECODER_H +#define __COMPRESS_PPMD_DECODER_H + +#include "../../../Common/MyCom.h" + +#include "../../ICoder.h" +#include "../../Common/OutBuffer.h" +#include "../RangeCoder/RangeCoder.h" + +#include "PPMDDecode.h" + +namespace NCompress { +namespace NPPMD { + +class CDecoder : + public ICompressCoder, + public ICompressSetDecoderProperties2, + #ifdef _ST_MODE + public ICompressSetInStream, + public ICompressSetOutStreamSize, + public ISequentialInStream, + #endif + public CMyUnknownImp +{ + CRangeDecoder _rangeDecoder; + + COutBuffer _outStream; + + CDecodeInfo _info; + + Byte _order; + UInt32 _usedMemorySize; + + int _remainLen; + UInt64 _outSize; + bool _outSizeDefined; + UInt64 _processedSize; + + HRESULT CodeSpec(UInt32 num, Byte *memStream); +public: + + #ifdef _ST_MODE + MY_UNKNOWN_IMP4( + ICompressSetDecoderProperties2, + ICompressSetInStream, + ICompressSetOutStreamSize, + ISequentialInStream) + #else + MY_UNKNOWN_IMP1( + ICompressSetDecoderProperties2) + #endif + + void ReleaseStreams() + { + ReleaseInStream(); + _outStream.ReleaseStream(); + } + + HRESULT Flush() { return _outStream.Flush(); } + + STDMETHOD(CodeReal)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + + STDMETHOD(SetInStream)(ISequentialInStream *inStream); + STDMETHOD(ReleaseInStream)(); + STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); + + #ifdef _ST_MODE + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + #endif + + CDecoder(): _outSizeDefined(false) {} + +}; + +}} + +#endif diff --git a/CPP/7zip/Compress/PPMD/PPMDEncode.h b/CPP/7zip/Compress/PPMD/PPMDEncode.h new file mode 100755 index 00000000..6a720cac --- /dev/null +++ b/CPP/7zip/Compress/PPMD/PPMDEncode.h @@ -0,0 +1,142 @@ +// PPMDEncode.h +// This code is based on Dmitry Shkarin's PPMdH code + +#ifndef __COMPRESS_PPMD_ENCODE_H +#define __COMPRESS_PPMD_ENCODE_H + +#include "PPMDContext.h" + +namespace NCompress { +namespace NPPMD { + +struct CEncodeInfo: public CInfo +{ + + void EncodeBinSymbol(int symbol, NRangeCoder::CEncoder *rangeEncoder) + { + PPM_CONTEXT::STATE& rs = MinContext->oneState(); + UInt16 &bs = GetBinSumm(rs, GetContextNoCheck(MinContext->Suffix)->NumStats); + if (rs.Symbol == symbol) + { + FoundState = &rs; + rs.Freq = (Byte)(rs.Freq + (rs.Freq < 128 ? 1: 0)); + rangeEncoder->EncodeBit(bs, TOT_BITS, 0); + bs = (UInt16)(bs + INTERVAL - GET_MEAN(bs, PERIOD_BITS, 2)); + PrevSuccess = 1; + RunLength++; + } + else + { + rangeEncoder->EncodeBit(bs, TOT_BITS, 1); + bs = (UInt16)(bs - GET_MEAN(bs, PERIOD_BITS, 2)); + InitEsc = ExpEscape[bs >> 10]; + NumMasked = 1; + CharMask[rs.Symbol] = EscCount; + PrevSuccess = 0; + FoundState = NULL; + } + } + + void EncodeSymbol1(int symbol, NRangeCoder::CEncoder *rangeEncoder) + { + PPM_CONTEXT::STATE* p = GetStateNoCheck(MinContext->Stats); + if (p->Symbol == symbol) + { + PrevSuccess = (2 * (p->Freq) > MinContext->SummFreq); + RunLength += PrevSuccess; + rangeEncoder->Encode(0, p->Freq, MinContext->SummFreq); + (FoundState = p)->Freq += 4; + MinContext->SummFreq += 4; + if (p->Freq > MAX_FREQ) + rescale(); + return; + } + PrevSuccess = 0; + int LoCnt = p->Freq, i = MinContext->NumStats - 1; + while ((++p)->Symbol != symbol) + { + LoCnt += p->Freq; + if (--i == 0) + { + HiBitsFlag = HB2Flag[FoundState->Symbol]; + CharMask[p->Symbol] = EscCount; + i=(NumMasked = MinContext->NumStats)-1; + FoundState = NULL; + do { CharMask[(--p)->Symbol] = EscCount; } while ( --i ); + rangeEncoder->Encode(LoCnt, MinContext->SummFreq - LoCnt, MinContext->SummFreq); + return; + } + } + rangeEncoder->Encode(LoCnt, p->Freq, MinContext->SummFreq); + update1(p); + } + + void EncodeSymbol2(int symbol, NRangeCoder::CEncoder *rangeEncoder) + { + int hiCnt, i = MinContext->NumStats - NumMasked; + UInt32 scale; + SEE2_CONTEXT* psee2c = makeEscFreq2(i, scale); + PPM_CONTEXT::STATE* p = GetStateNoCheck(MinContext->Stats) - 1; + hiCnt = 0; + do + { + do { p++; } while (CharMask[p->Symbol] == EscCount); + hiCnt += p->Freq; + if (p->Symbol == symbol) + goto SYMBOL_FOUND; + CharMask[p->Symbol] = EscCount; + } + while ( --i ); + + rangeEncoder->Encode(hiCnt, scale, hiCnt + scale); + scale += hiCnt; + + psee2c->Summ = (UInt16)(psee2c->Summ + scale); + NumMasked = MinContext->NumStats; + return; +SYMBOL_FOUND: + + UInt32 highCount = hiCnt; + UInt32 lowCount = highCount - p->Freq; + if ( --i ) + { + PPM_CONTEXT::STATE* p1 = p; + do + { + do { p1++; } while (CharMask[p1->Symbol] == EscCount); + hiCnt += p1->Freq; + } + while ( --i ); + } + // SubRange.scale += hiCnt; + scale += hiCnt; + rangeEncoder->Encode(lowCount, highCount - lowCount, scale); + psee2c->update(); + update2(p); + } + + void EncodeSymbol(int c, NRangeCoder::CEncoder *rangeEncoder) + { + if (MinContext->NumStats != 1) + EncodeSymbol1(c, rangeEncoder); + else + EncodeBinSymbol(c, rangeEncoder); + while ( !FoundState ) + { + do + { + OrderFall++; + MinContext = GetContext(MinContext->Suffix); + if (MinContext == 0) + return; // S_OK; + } + while (MinContext->NumStats == NumMasked); + EncodeSymbol2(c, rangeEncoder); + } + NextContext(); + } + +}; +}} + +#endif diff --git a/CPP/7zip/Compress/PPMD/PPMDEncoder.cpp b/CPP/7zip/Compress/PPMD/PPMDEncoder.cpp new file mode 100755 index 00000000..fe99ea5a --- /dev/null +++ b/CPP/7zip/Compress/PPMD/PPMDEncoder.cpp @@ -0,0 +1,155 @@ +// Compress/Associative/Encoder.h + +#include "StdAfx.h" + +#include "Windows/Defs.h" + +// #include +// #include + +#include "Common/Defs.h" + +#include "../../Common/StreamUtils.h" + +#include "PPMDEncoder.h" + +namespace NCompress { +namespace NPPMD { + +const UInt32 kMinMemSize = (1 << 11); +const UInt32 kMinOrder = 2; + +/* +UInt32 g_NumInner = 0; +UInt32 g_InnerCycles = 0; + +UInt32 g_Encode2 = 0; +UInt32 g_Encode2Cycles = 0; +UInt32 g_Encode2Cycles2 = 0; + +class CCounter +{ +public: + CCounter() {} + ~CCounter() + { + ofstream ofs("Res.dat"); + ofs << "innerEncode1 = " << setw(10) << g_NumInner << endl; + ofs << "g_InnerCycles = " << setw(10) << g_InnerCycles << endl; + ofs << "g_Encode2 = " << setw(10) << g_Encode2 << endl; + ofs << "g_Encode2Cycles = " << setw(10) << g_Encode2Cycles << endl; + ofs << "g_Encode2Cycles2= " << setw(10) << g_Encode2Cycles2 << endl; + + } +}; +CCounter g_Counter; +*/ + +STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties) +{ + for (UInt32 i = 0; i < numProperties; i++) + { + const PROPVARIANT &prop = properties[i]; + switch(propIDs[i]) + { + case NCoderPropID::kUsedMemorySize: + if (prop.vt != VT_UI4) + return E_INVALIDARG; + if (prop.ulVal < kMinMemSize || prop.ulVal > kMaxMemBlockSize) + return E_INVALIDARG; + _usedMemorySize = (UInt32)prop.ulVal; + break; + case NCoderPropID::kOrder: + if (prop.vt != VT_UI4) + return E_INVALIDARG; + if (prop.ulVal < kMinOrder || prop.ulVal > kMaxOrderCompress) + return E_INVALIDARG; + _order = (Byte)prop.ulVal; + break; + default: + return E_INVALIDARG; + } + } + return S_OK; +} + +STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) +{ + const UInt32 kPropSize = 5; + Byte properties[kPropSize]; + properties[0] = _order; + for (int i = 0; i < 4; i++) + properties[1 + i] = Byte(_usedMemorySize >> (8 * i)); + return WriteStream(outStream, properties, kPropSize, NULL); +} + +const UInt32 kUsedMemorySizeDefault = (1 << 24); +const int kOrderDefault = 6; + +CEncoder::CEncoder(): + _usedMemorySize(kUsedMemorySizeDefault), + _order(kOrderDefault) +{ +} + + +HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 * /* outSize */, + ICompressProgressInfo *progress) +{ + if (!_inStream.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!_rangeEncoder.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!_info.SubAllocator.StartSubAllocator(_usedMemorySize)) + return E_OUTOFMEMORY; + + _inStream.SetStream(inStream); + _inStream.Init(); + + _rangeEncoder.SetStream(outStream); + _rangeEncoder.Init(); + + CEncoderFlusher flusher(this); + + _info.MaxOrder = 0; + _info.StartModelRare(_order); + + for (;;) + { + UInt32 size = (1 << 18); + do + { + Byte symbol; + if (!_inStream.ReadByte(symbol)) + { + // here we can write End Mark for stream version. + // In current version this feature is not used. + // _info.EncodeSymbol(-1, &_rangeEncoder); + return S_OK; + } + _info.EncodeSymbol(symbol, &_rangeEncoder); + } + while (--size != 0); + if (progress != NULL) + { + UInt64 inSize = _inStream.GetProcessedSize(); + UInt64 outSize = _rangeEncoder.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&inSize, &outSize)); + } + } +} + +STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const COutBufferException &e) { return e.ErrorCode; } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(...) { return E_FAIL; } +} + +}} diff --git a/CPP/7zip/Compress/PPMD/PPMDEncoder.h b/CPP/7zip/Compress/PPMD/PPMDEncoder.h new file mode 100755 index 00000000..915180b9 --- /dev/null +++ b/CPP/7zip/Compress/PPMD/PPMDEncoder.h @@ -0,0 +1,81 @@ +// Compress/PPMD/Encoder.h + +#ifndef __COMPRESS_PPMD_ENCODER_H +#define __COMPRESS_PPMD_ENCODER_H + +#include "../../../Common/MyCom.h" + +#include "../../ICoder.h" +#include "../../Common/InBuffer.h" +#include "../RangeCoder/RangeCoder.h" + +#include "PPMDEncode.h" + +namespace NCompress { +namespace NPPMD { + +class CEncoder : + public ICompressCoder, + public ICompressSetCoderProperties, + public ICompressWriteCoderProperties, + public CMyUnknownImp +{ +public: + CInBuffer _inStream; + + NRangeCoder::CEncoder _rangeEncoder; + + CEncodeInfo _info; + UInt32 _usedMemorySize; + Byte _order; + + HRESULT Flush() + { + _rangeEncoder.FlushData(); + return _rangeEncoder.FlushStream(); + } + + void ReleaseStreams() + { + _inStream.ReleaseStream(); + _rangeEncoder.ReleaseStream(); + } + + HRESULT CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + class CEncoderFlusher + { + CEncoder *_encoder; + public: + CEncoderFlusher(CEncoder *encoder): _encoder(encoder) {} + ~CEncoderFlusher() + { + _encoder->Flush(); + _encoder->ReleaseStreams(); + } + }; + +public: + + MY_UNKNOWN_IMP2( + ICompressSetCoderProperties, + ICompressWriteCoderProperties) + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(SetCoderProperties)(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties); + + STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); + + CEncoder(); + +}; + +}} + +#endif diff --git a/CPP/7zip/Compress/PPMD/PPMDSubAlloc.h b/CPP/7zip/Compress/PPMD/PPMDSubAlloc.h new file mode 100755 index 00000000..dce765d6 --- /dev/null +++ b/CPP/7zip/Compress/PPMD/PPMDSubAlloc.h @@ -0,0 +1,292 @@ +// PPMDSubAlloc.h +// This code is based on Dmitry Shkarin's PPMdH code + +#ifndef __PPMD_SUBALLOC_H +#define __PPMD_SUBALLOC_H + +#include "PPMDType.h" + +#include "../../../Common/Alloc.h" + +const UINT N1=4, N2=4, N3=4, N4=(128+3-1*N1-2*N2-3*N3)/4; +const UINT UNIT_SIZE=12, N_INDEXES=N1+N2+N3+N4; + +// Extra 1 * UNIT_SIZE for NULL support +// Extra 2 * UNIT_SIZE for s0 in GlueFreeBlocks() +const UInt32 kExtraSize = (UNIT_SIZE * 3); +const UInt32 kMaxMemBlockSize = 0xFFFFFFFF - kExtraSize; + +struct MEM_BLK +{ + UInt16 Stamp, NU; + UInt32 Next, Prev; + void InsertAt(Byte *Base, UInt32 p) + { + Prev = p; + MEM_BLK *pp = (MEM_BLK *)(Base + p); + Next = pp->Next; + pp->Next = ((MEM_BLK *)(Base + Next))->Prev = (UInt32)((Byte *)this - Base); + } + void Remove(Byte *Base) + { + ((MEM_BLK *)(Base + Prev))->Next = Next; + ((MEM_BLK *)(Base + Next))->Prev = Prev; + } +}; + + +class CSubAllocator +{ + UInt32 SubAllocatorSize; + Byte Indx2Units[N_INDEXES], Units2Indx[128], GlueCount; + UInt32 FreeList[N_INDEXES]; + + Byte *Base; + Byte *HeapStart, *LoUnit, *HiUnit; +public: + Byte *pText, *UnitsStart; + CSubAllocator(): + SubAllocatorSize(0), + GlueCount(0), + LoUnit(0), + HiUnit(0), + pText(0), + UnitsStart(0) + { + memset(Indx2Units, 0, sizeof(Indx2Units)); + memset(FreeList, 0, sizeof(FreeList)); + } + ~CSubAllocator() + { + StopSubAllocator(); + }; + + void *GetPtr(UInt32 offset) const { return (offset == 0) ? 0 : (void *)(Base + offset); } + void *GetPtrNoCheck(UInt32 offset) const { return (void *)(Base + offset); } + UInt32 GetOffset(void *ptr) const { return (ptr == 0) ? 0 : (UInt32)((Byte *)ptr - Base); } + UInt32 GetOffsetNoCheck(void *ptr) const { return (UInt32)((Byte *)ptr - Base); } + MEM_BLK *GetBlk(UInt32 offset) const { return (MEM_BLK *)(Base + offset); } + UInt32 *GetNode(UInt32 offset) const { return (UInt32 *)(Base + offset); } + + void InsertNode(void* p, int indx) + { + *(UInt32 *)p = FreeList[indx]; + FreeList[indx] = GetOffsetNoCheck(p); + } + + void* RemoveNode(int indx) + { + UInt32 offset = FreeList[indx]; + UInt32 *p = GetNode(offset); + FreeList[indx] = *p; + return (void *)p; + } + + UINT U2B(int NU) const { return (UINT)(NU) * UNIT_SIZE; } + + void SplitBlock(void* pv, int oldIndx, int newIndx) + { + int i, UDiff = Indx2Units[oldIndx] - Indx2Units[newIndx]; + Byte* p = ((Byte*)pv) + U2B(Indx2Units[newIndx]); + if (Indx2Units[i = Units2Indx[UDiff-1]] != UDiff) + { + InsertNode(p, --i); + p += U2B(i = Indx2Units[i]); + UDiff -= i; + } + InsertNode(p, Units2Indx[UDiff - 1]); + } + + UInt32 GetUsedMemory() const + { + UInt32 RetVal = SubAllocatorSize - (UInt32)(HiUnit - LoUnit) - (UInt32)(UnitsStart - pText); + for (UInt32 i = 0; i < N_INDEXES; i++) + for (UInt32 pn = FreeList[i]; pn != 0; RetVal -= (UInt32)Indx2Units[i] * UNIT_SIZE) + pn = *GetNode(pn); + return (RetVal >> 2); + } + + UInt32 GetSubAllocatorSize() const { return SubAllocatorSize; } + + void StopSubAllocator() + { + if (SubAllocatorSize != 0) + { + BigFree(Base); + SubAllocatorSize = 0; + Base = 0; + } + } + + bool StartSubAllocator(UInt32 size) + { + if (SubAllocatorSize == size) + return true; + StopSubAllocator(); + if (size == 0) + Base = 0; + else + { + if ((Base = (Byte *)::BigAlloc(size + kExtraSize)) == 0) + return false; + HeapStart = Base + UNIT_SIZE; // we need such code to support NULL; + } + SubAllocatorSize = size; + return true; + } + + void InitSubAllocator() + { + int i, k; + memset(FreeList, 0, sizeof(FreeList)); + HiUnit = (pText = HeapStart) + SubAllocatorSize; + UINT Diff = UNIT_SIZE * (SubAllocatorSize / 8 / UNIT_SIZE * 7); + LoUnit = UnitsStart = HiUnit - Diff; + for (i = 0, k=1; i < N1 ; i++, k += 1) Indx2Units[i] = (Byte)k; + for (k++; i < N1 + N2 ;i++, k += 2) Indx2Units[i] = (Byte)k; + for (k++; i < N1 + N2 + N3 ;i++,k += 3) Indx2Units[i] = (Byte)k; + for (k++; i < N1 + N2 + N3 + N4; i++, k += 4) Indx2Units[i] = (Byte)k; + GlueCount = 0; + for (k = i = 0; k < 128; k++) + { + i += (Indx2Units[i] < k+1); + Units2Indx[k] = (Byte)i; + } + } + + void GlueFreeBlocks() + { + UInt32 s0 = (UInt32)(HeapStart + SubAllocatorSize - Base); + + // We need add exta MEM_BLK with Stamp=0 + GetBlk(s0)->Stamp = 0; + s0 += UNIT_SIZE; + MEM_BLK *ps0 = GetBlk(s0); + + UInt32 p; + int i; + if (LoUnit != HiUnit) + *LoUnit=0; + ps0->Next = ps0->Prev = s0; + + for (i = 0; i < N_INDEXES; i++) + while (FreeList[i] != 0) + { + MEM_BLK *pp = (MEM_BLK *)RemoveNode(i); + pp->InsertAt(Base, s0); + pp->Stamp = 0xFFFF; + pp->NU = Indx2Units[i]; + } + for (p = ps0->Next; p != s0; p = GetBlk(p)->Next) + { + for (;;) + { + MEM_BLK *pp = GetBlk(p); + MEM_BLK *pp1 = GetBlk(p + pp->NU * UNIT_SIZE); + if (pp1->Stamp != 0xFFFF || int(pp->NU) + pp1->NU >= 0x10000) + break; + pp1->Remove(Base); + pp->NU = (UInt16)(pp->NU + pp1->NU); + } + } + while ((p = ps0->Next) != s0) + { + MEM_BLK *pp = GetBlk(p); + pp->Remove(Base); + int sz; + for (sz = pp->NU; sz > 128; sz -= 128, p += 128 * UNIT_SIZE) + InsertNode(Base + p, N_INDEXES - 1); + if (Indx2Units[i = Units2Indx[sz-1]] != sz) + { + int k = sz - Indx2Units[--i]; + InsertNode(Base + p + (sz - k) * UNIT_SIZE, k - 1); + } + InsertNode(Base + p, i); + } + } + void* AllocUnitsRare(int indx) + { + if ( !GlueCount ) + { + GlueCount = 255; + GlueFreeBlocks(); + if (FreeList[indx] != 0) + return RemoveNode(indx); + } + int i = indx; + do + { + if (++i == N_INDEXES) + { + GlueCount--; + i = U2B(Indx2Units[indx]); + return (UnitsStart - pText > i) ? (UnitsStart -= i) : (NULL); + } + } while (FreeList[i] == 0); + void* RetVal = RemoveNode(i); + SplitBlock(RetVal, i, indx); + return RetVal; + } + + void* AllocUnits(int NU) + { + int indx = Units2Indx[NU - 1]; + if (FreeList[indx] != 0) + return RemoveNode(indx); + void* RetVal = LoUnit; + LoUnit += U2B(Indx2Units[indx]); + if (LoUnit <= HiUnit) + return RetVal; + LoUnit -= U2B(Indx2Units[indx]); + return AllocUnitsRare(indx); + } + + void* AllocContext() + { + if (HiUnit != LoUnit) + return (HiUnit -= UNIT_SIZE); + if (FreeList[0] != 0) + return RemoveNode(0); + return AllocUnitsRare(0); + } + + void* ExpandUnits(void* oldPtr, int oldNU) + { + int i0=Units2Indx[oldNU - 1], i1=Units2Indx[oldNU - 1 + 1]; + if (i0 == i1) + return oldPtr; + void* ptr = AllocUnits(oldNU + 1); + if (ptr) + { + memcpy(ptr, oldPtr, U2B(oldNU)); + InsertNode(oldPtr, i0); + } + return ptr; + } + + void* ShrinkUnits(void* oldPtr, int oldNU, int newNU) + { + int i0 = Units2Indx[oldNU - 1], i1 = Units2Indx[newNU - 1]; + if (i0 == i1) + return oldPtr; + if (FreeList[i1] != 0) + { + void* ptr = RemoveNode(i1); + memcpy(ptr, oldPtr, U2B(newNU)); + InsertNode(oldPtr,i0); + return ptr; + } + else + { + SplitBlock(oldPtr, i0, i1); + return oldPtr; + } + } + + void FreeUnits(void* ptr, int oldNU) + { + InsertNode(ptr, Units2Indx[oldNU - 1]); + } +}; + +#endif diff --git a/CPP/7zip/Compress/PPMD/PPMDType.h b/CPP/7zip/Compress/PPMD/PPMDType.h new file mode 100755 index 00000000..5200fa54 --- /dev/null +++ b/CPP/7zip/Compress/PPMD/PPMDType.h @@ -0,0 +1,19 @@ +/**************************************************************************** + * This file is part of PPMd project * + * Written and distributed to public domain by Dmitry Shkarin 1997, * + * 1999-2001 * + * Contents: compilation parameters and miscelaneous definitions * + * Comments: system & compiler dependent file + + * modified by Igor Pavlov (2004-08-29). + ****************************************************************************/ +#ifndef __PPMD_TYPE_H +#define __PPMD_TYPE_H + +const int kMaxOrderCompress = 32; +const int MAX_O = 255; /* maximum allowed model order */ + +template +inline void _PPMD_SWAP(T& t1,T& t2) { T tmp = t1; t1 = t2; t2 = tmp; } + +#endif diff --git a/CPP/7zip/Compress/PPMD/StdAfx.cpp b/CPP/7zip/Compress/PPMD/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Compress/PPMD/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Compress/PPMD/StdAfx.h b/CPP/7zip/Compress/PPMD/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Compress/PPMD/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Compress/PPMD/makefile b/CPP/7zip/Compress/PPMD/makefile new file mode 100755 index 00000000..2e687a70 --- /dev/null +++ b/CPP/7zip/Compress/PPMD/makefile @@ -0,0 +1,41 @@ +PROG = PPMd.dll +DEF_FILE = ../Codec.def +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib + +PPMD_OBJS = \ + $O\DllExports.obj \ + +PPMD_OPT_OBJS = \ + $O\PPMDDecoder.obj \ + $O\PPMDEncoder.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + +7ZIP_COMMON_OBJS = \ + $O\InBuffer.obj \ + $O\OutBuffer.obj \ + $O\StreamUtils.obj \ + + +OBJS = \ + $O\StdAfx.obj \ + $(PPMD_OBJS) \ + $(PPMD_OPT_OBJS) \ + $(COMMON_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $O\resource.res + + +!include "../../../Build.mak" + +$(PPMD_OBJS): $(*B).cpp + $(COMPL) +$(PPMD_OPT_OBJS): $(*B).cpp + $(COMPL_O2) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) + diff --git a/CPP/7zip/Compress/PPMD/resource.rc b/CPP/7zip/Compress/PPMD/resource.rc new file mode 100755 index 00000000..fed98e19 --- /dev/null +++ b/CPP/7zip/Compress/PPMD/resource.rc @@ -0,0 +1,3 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("PPMd Codec", "PPMd") diff --git a/CPP/7zip/Compress/Quantum/QuantumDecoder.cpp b/CPP/7zip/Compress/Quantum/QuantumDecoder.cpp new file mode 100755 index 00000000..5cf863bb --- /dev/null +++ b/CPP/7zip/Compress/Quantum/QuantumDecoder.cpp @@ -0,0 +1,173 @@ +// QuantumDecoder.cpp + +#include "StdAfx.h" + +#include "QuantumDecoder.h" +#include "../../../Common/Defs.h" + +namespace NCompress { +namespace NQuantum { + +const UInt32 kDictionarySizeMax = (1 << 21); + +const int kLenIdNeedInit = -2; + +void CDecoder::Init() +{ + m_Selector.Init(kNumSelectors); + for (unsigned int i = 0; i < kNumLitSelectors; i++) + m_Literals[i].Init(kNumLitSymbols); + unsigned int numItems = _numDictBits << 1; + m_PosSlot[0].Init(MyMin(numItems, kNumLen3PosSymbolsMax)); + m_PosSlot[1].Init(MyMin(numItems, kNumLen4PosSymbolsMax)); + m_PosSlot[2].Init(MyMin(numItems, kNumLen5PosSymbolsMax)); + m_LenSlot.Init(kNumLenSymbols); +} + +HRESULT CDecoder::CodeSpec(UInt32 curSize) +{ + if (_remainLen == kLenIdNeedInit) + { + if (!_keepHistory) + { + if (!_outWindowStream.Create(_dictionarySize)) + return E_OUTOFMEMORY; + Init(); + } + if (!_rangeDecoder.Create(1 << 20)) + return E_OUTOFMEMORY; + _rangeDecoder.Init(); + _remainLen = 0; + } + if (curSize == 0) + return S_OK; + + while(_remainLen > 0 && curSize > 0) + { + _remainLen--; + Byte b = _outWindowStream.GetByte(_rep0); + _outWindowStream.PutByte(b); + curSize--; + } + + while(curSize > 0) + { + if (_rangeDecoder.Stream.WasFinished()) + return S_FALSE; + + unsigned int selector = m_Selector.Decode(&_rangeDecoder); + if (selector < kNumLitSelectors) + { + Byte b = (Byte)((selector << (8 - kNumLitSelectorBits)) + m_Literals[selector].Decode(&_rangeDecoder)); + _outWindowStream.PutByte(b); + curSize--; + } + else + { + selector -= kNumLitSelectors; + unsigned int len = selector + kMatchMinLen; + if (selector == 2) + { + unsigned int lenSlot = m_LenSlot.Decode(&_rangeDecoder);; + if (lenSlot >= kNumSimpleLenSlots) + { + lenSlot -= 2; + int numDirectBits = (int)(lenSlot >> 2); + len += ((4 | (lenSlot & 3)) << numDirectBits) - 2; + if (numDirectBits < 6) + len += _rangeDecoder.Stream.ReadBits(numDirectBits); + } + else + len += lenSlot; + } + UInt32 rep0 = m_PosSlot[selector].Decode(&_rangeDecoder);; + if (rep0 >= kNumSimplePosSlots) + { + int numDirectBits = (int)((rep0 >> 1) - 1); + rep0 = ((2 | (rep0 & 1)) << numDirectBits) + _rangeDecoder.Stream.ReadBits(numDirectBits); + } + unsigned int locLen = len; + if (len > curSize) + locLen = (unsigned int)curSize; + if (!_outWindowStream.CopyBlock(rep0, locLen)) + return S_FALSE; + curSize -= locLen; + len -= locLen; + if (len != 0) + { + _remainLen = (int)len; + _rep0 = rep0; + break; + } + } + } + return _rangeDecoder.Stream.WasFinished() ? S_FALSE : S_OK; +} + +HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + if (outSize == NULL) + return E_INVALIDARG; + UInt64 size = *outSize; + + SetInStream(inStream); + _outWindowStream.SetStream(outStream); + SetOutStreamSize(outSize); + CDecoderFlusher flusher(this); + + const UInt64 start = _outWindowStream.GetProcessedSize(); + for (;;) + { + UInt32 curSize = 1 << 18; + UInt64 rem = size - (_outWindowStream.GetProcessedSize() - start); + if (curSize > rem) + curSize = (UInt32)rem; + if (curSize == 0) + break; + RINOK(CodeSpec(curSize)); + if (progress != NULL) + { + UInt64 inSize = _rangeDecoder.GetProcessedSize(); + UInt64 nowPos64 = _outWindowStream.GetProcessedSize() - start; + RINOK(progress->SetRatioInfo(&inSize, &nowPos64)); + } + } + flusher.NeedFlush = false; + return Flush(); +} + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const CLZOutWindowException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) +{ + _rangeDecoder.SetStream(inStream); + return S_OK; +} + +STDMETHODIMP CDecoder::ReleaseInStream() +{ + _rangeDecoder.ReleaseStream(); + return S_OK; +} + +STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) +{ + if (outSize == NULL) + return E_FAIL; + _remainLen = kLenIdNeedInit; + _outWindowStream.Init(_keepHistory); + return S_OK; +} + +}} diff --git a/CPP/7zip/Compress/Quantum/QuantumDecoder.h b/CPP/7zip/Compress/Quantum/QuantumDecoder.h new file mode 100755 index 00000000..8b5aaaba --- /dev/null +++ b/CPP/7zip/Compress/Quantum/QuantumDecoder.h @@ -0,0 +1,287 @@ +// QuantumDecoder.h + +#ifndef __QUANTUM_DECODER_H +#define __QUANTUM_DECODER_H + +#include "../../../Common/MyCom.h" + +#include "../../Common/InBuffer.h" +#include "../../ICoder.h" +#include "../LZ/LZOutWindow.h" + +namespace NCompress { +namespace NQuantum { + +class CStreamBitDecoder +{ + UInt32 m_Value; + CInBuffer m_Stream; +public: + bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } + void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream);} + void ReleaseStream() { m_Stream.ReleaseStream();} + + void Finish() { m_Value = 0x10000; } + + void Init() + { + m_Stream.Init(); + m_Value = 0x10000; + } + + UInt64 GetProcessedSize() const { return m_Stream.GetProcessedSize(); } + bool WasFinished() const { return m_Stream.WasFinished(); }; + + UInt32 ReadBit() + { + if (m_Value >= 0x10000) + m_Value = 0x100 | m_Stream.ReadByte(); + UInt32 res = (m_Value >> 7) & 1; + m_Value <<= 1; + return res; + } + + UInt32 ReadBits(int numBits) // numBits > 0 + { + UInt32 res = 0; + do + res = (res << 1) | ReadBit(); + while(--numBits != 0); + return res; + } +}; + +const int kNumLitSelectorBits = 2; +const unsigned int kNumLitSelectors = (1 << kNumLitSelectorBits); +const unsigned int kNumLitSymbols = 1 << (8 - kNumLitSelectorBits); +const unsigned int kNumMatchSelectors = 3; +const unsigned int kNumSelectors = kNumLitSelectors + kNumMatchSelectors; +const unsigned int kNumLen3PosSymbolsMax = 24; +const unsigned int kNumLen4PosSymbolsMax = 36; +const unsigned int kNumLen5PosSymbolsMax = 42; +const unsigned int kNumLenSymbols = 27; + +const unsigned int kNumSymbolsMax = kNumLitSymbols; // 64 + +const unsigned int kMatchMinLen = 3; +const unsigned int kNumSimplePosSlots = 4; +const unsigned int kNumSimpleLenSlots = 6; + +namespace NRangeCoder { + +class CDecoder +{ + UInt32 Low; + UInt32 Range; + UInt32 Code; +public: + CStreamBitDecoder Stream; + bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); } + void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); } + void ReleaseStream() { Stream.ReleaseStream(); } + + void Init() + { + Stream.Init(); + Low = 0; + Range = 0x10000; + Code = Stream.ReadBits(16); + } + + void Finish() + { + // we need these extra two Bit_reads + Stream.ReadBit(); + Stream.ReadBit(); + Stream.Finish(); + } + + UInt64 GetProcessedSize() const { return Stream.GetProcessedSize(); } + + UInt32 GetThreshold(UInt32 total) const + { + return ((Code + 1) * total - 1) / Range; // & 0xFFFF is not required; + } + + void Decode(UInt32 start, UInt32 end, UInt32 total) + { + UInt32 high = Low + end * Range / total - 1; + UInt32 offset = start * Range / total; + Code -= offset; + Low += offset; + for (;;) + { + if ((Low & 0x8000) != (high & 0x8000)) + { + if ((Low & 0x4000) == 0 || (high & 0x4000) != 0) + break; + Low &= 0x3FFF; + high |= 0x4000; + } + Low = (Low << 1) & 0xFFFF; + high = ((high << 1) | 1) & 0xFFFF; + Code = ((Code << 1) | Stream.ReadBit()); + } + Range = high - Low + 1; + } +}; + +const UInt16 kUpdateStep = 8; +const UInt16 kFreqSumMax = 3800; +const UInt16 kReorderCountStart = 4; +const UInt16 kReorderCount = 50; + +class CModelDecoder +{ + unsigned int NumItems; + unsigned int ReorderCount; + UInt16 Freqs[kNumSymbolsMax + 1]; + Byte Values[kNumSymbolsMax]; +public: + void Init(unsigned int numItems) + { + NumItems = numItems; + ReorderCount = kReorderCountStart; + for(unsigned int i = 0; i < numItems; i++) + { + Freqs[i] = (UInt16)(numItems - i); + Values[i] = (Byte)i; + } + Freqs[numItems] = 0; + } + + unsigned int Decode(CDecoder *rangeDecoder) + { + UInt32 threshold = rangeDecoder->GetThreshold(Freqs[0]); + unsigned int i; + for (i = 1; Freqs[i] > threshold; i++); + rangeDecoder->Decode(Freqs[i], Freqs[i - 1], Freqs[0]); + unsigned int res = Values[--i]; + do + Freqs[i] += kUpdateStep; + while(i-- != 0); + + if (Freqs[0] > kFreqSumMax) + { + if (--ReorderCount == 0) + { + ReorderCount = kReorderCount; + for(i = 0; i < NumItems; i++) + Freqs[i] = (UInt16)(((Freqs[i] - Freqs[i + 1]) + 1) >> 1); + for(i = 0; i < NumItems - 1; i++) + for(unsigned int j = i + 1; j < NumItems; j++) + if (Freqs[i] < Freqs[j]) + { + UInt16 tmpFreq = Freqs[i]; + Byte tmpVal = Values[i]; + Freqs[i] = Freqs[j]; + Values[i] = Values[j]; + Freqs[j] = tmpFreq; + Values[j] = tmpVal; + } + do + Freqs[i] = (UInt16)(Freqs[i] + Freqs[i + 1]); + while(i-- != 0); + } + else + { + i = NumItems - 1; + do + { + Freqs[i] >>= 1; + if (Freqs[i] <= Freqs[i + 1]) + Freqs[i] = (UInt16)(Freqs[i + 1] + 1); + } + while(i-- != 0); + } + } + return res; + }; +}; + +} + +class CDecoder: + public ICompressCoder, + public ICompressSetInStream, + public ICompressSetOutStreamSize, + public CMyUnknownImp +{ + CLZOutWindow _outWindowStream; + NRangeCoder::CDecoder _rangeDecoder; + + /////////////////// + // State + UInt64 _outSize; + // UInt64 _nowPos64; + int _remainLen; // -1 means end of stream. // -2 means need Init + UInt32 _rep0; + + int _numDictBits; + UInt32 _dictionarySize; + + NRangeCoder::CModelDecoder m_Selector; + NRangeCoder::CModelDecoder m_Literals[kNumLitSelectors]; + NRangeCoder::CModelDecoder m_PosSlot[kNumMatchSelectors]; + NRangeCoder::CModelDecoder m_LenSlot; + + bool _keepHistory; + + void Init(); + HRESULT CodeSpec(UInt32 size); +public: + MY_UNKNOWN_IMP2( + ICompressSetInStream, + ICompressSetOutStreamSize) + + void ReleaseStreams() + { + _outWindowStream.ReleaseStream(); + ReleaseInStream(); + } + + class CDecoderFlusher + { + CDecoder *_decoder; + public: + bool NeedFlush; + CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {} + ~CDecoderFlusher() + { + if (NeedFlush) + _decoder->Flush(); + _decoder->ReleaseStreams(); + } + }; + + HRESULT Flush() { return _outWindowStream.Flush(); } + + HRESULT CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(SetInStream)(ISequentialInStream *inStream); + STDMETHOD(ReleaseInStream)(); + STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); + + void SetParams(int numDictBits) + { + _numDictBits = numDictBits; + _dictionarySize = (UInt32)1 << numDictBits; + } + void SetKeepHistory(bool keepHistory) + { + _keepHistory = keepHistory; + } + + CDecoder(): _keepHistory(false) {} + virtual ~CDecoder() {} +}; + +}} + +#endif diff --git a/CPP/7zip/Compress/RangeCoder/RangeCoder.h b/CPP/7zip/Compress/RangeCoder/RangeCoder.h new file mode 100755 index 00000000..bbb2ba82 --- /dev/null +++ b/CPP/7zip/Compress/RangeCoder/RangeCoder.h @@ -0,0 +1,205 @@ +// Compress/RangeCoder/RangeCoder.h + +#ifndef __COMPRESS_RANGECODER_H +#define __COMPRESS_RANGECODER_H + +#include "../../Common/InBuffer.h" +#include "../../Common/OutBuffer.h" + +namespace NCompress { +namespace NRangeCoder { + +const int kNumTopBits = 24; +const UInt32 kTopValue = (1 << kNumTopBits); + +class CEncoder +{ + UInt32 _cacheSize; + Byte _cache; +public: + UInt64 Low; + UInt32 Range; + COutBuffer Stream; + bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); } + + void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); } + void Init() + { + Stream.Init(); + Low = 0; + Range = 0xFFFFFFFF; + _cacheSize = 1; + _cache = 0; + } + + void FlushData() + { + // Low += 1; + for(int i = 0; i < 5; i++) + ShiftLow(); + } + + HRESULT FlushStream() { return Stream.Flush(); } + + void ReleaseStream() { Stream.ReleaseStream(); } + + void Encode(UInt32 start, UInt32 size, UInt32 total) + { + Low += start * (Range /= total); + Range *= size; + while (Range < kTopValue) + { + Range <<= 8; + ShiftLow(); + } + } + + void ShiftLow() + { + if ((UInt32)Low < (UInt32)0xFF000000 || (int)(Low >> 32) != 0) + { + Byte temp = _cache; + do + { + Stream.WriteByte((Byte)(temp + (Byte)(Low >> 32))); + temp = 0xFF; + } + while(--_cacheSize != 0); + _cache = (Byte)((UInt32)Low >> 24); + } + _cacheSize++; + Low = (UInt32)Low << 8; + } + + void EncodeDirectBits(UInt32 value, int numTotalBits) + { + for (int i = numTotalBits - 1; i >= 0; i--) + { + Range >>= 1; + if (((value >> i) & 1) == 1) + Low += Range; + if (Range < kTopValue) + { + Range <<= 8; + ShiftLow(); + } + } + } + + void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol) + { + UInt32 newBound = (Range >> numTotalBits) * size0; + if (symbol == 0) + Range = newBound; + else + { + Low += newBound; + Range -= newBound; + } + while (Range < kTopValue) + { + Range <<= 8; + ShiftLow(); + } + } + + UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _cacheSize + 4; } +}; + +class CDecoder +{ +public: + CInBuffer Stream; + UInt32 Range; + UInt32 Code; + bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); } + + void Normalize() + { + while (Range < kTopValue) + { + Code = (Code << 8) | Stream.ReadByte(); + Range <<= 8; + } + } + + void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); } + void Init() + { + Stream.Init(); + Code = 0; + Range = 0xFFFFFFFF; + for(int i = 0; i < 5; i++) + Code = (Code << 8) | Stream.ReadByte(); + } + + void ReleaseStream() { Stream.ReleaseStream(); } + + UInt32 GetThreshold(UInt32 total) + { + return (Code) / ( Range /= total); + } + + void Decode(UInt32 start, UInt32 size) + { + Code -= start * Range; + Range *= size; + Normalize(); + } + + UInt32 DecodeDirectBits(int numTotalBits) + { + UInt32 range = Range; + UInt32 code = Code; + UInt32 result = 0; + for (int i = numTotalBits; i != 0; i--) + { + range >>= 1; + /* + result <<= 1; + if (code >= range) + { + code -= range; + result |= 1; + } + */ + UInt32 t = (code - range) >> 31; + code -= range & (t - 1); + result = (result << 1) | (1 - t); + + if (range < kTopValue) + { + code = (code << 8) | Stream.ReadByte(); + range <<= 8; + } + } + Range = range; + Code = code; + return result; + } + + UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) + { + UInt32 newBound = (Range >> numTotalBits) * size0; + UInt32 symbol; + if (Code < newBound) + { + symbol = 0; + Range = newBound; + } + else + { + symbol = 1; + Code -= newBound; + Range -= newBound; + } + Normalize(); + return symbol; + } + + UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); } +}; + +}} + +#endif diff --git a/CPP/7zip/Compress/RangeCoder/RangeCoderBit.cpp b/CPP/7zip/Compress/RangeCoder/RangeCoderBit.cpp new file mode 100755 index 00000000..8e4c4d3a --- /dev/null +++ b/CPP/7zip/Compress/RangeCoder/RangeCoderBit.cpp @@ -0,0 +1,80 @@ +// Compress/RangeCoder/RangeCoderBit.cpp + +#include "StdAfx.h" + +#include "RangeCoderBit.h" + +namespace NCompress { +namespace NRangeCoder { + +UInt32 CPriceTables::ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; +static CPriceTables g_PriceTables; + +CPriceTables::CPriceTables() { Init(); } + +void CPriceTables::Init() +{ + const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits); + for(int i = kNumBits - 1; i >= 0; i--) + { + UInt32 start = 1 << (kNumBits - i - 1); + UInt32 end = 1 << (kNumBits - i); + for (UInt32 j = start; j < end; j++) + ProbPrices[j] = (i << kNumBitPriceShiftBits) + + (((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1)); + } + + /* + // simplest: bad solution + for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++) + ProbPrices[i] = kBitPrice; + */ + + /* + const double kDummyMultMid = (1.0 / kBitPrice) / 2; + const double kDummyMultMid = 0; + // float solution + double ln2 = log(double(2)); + double lnAll = log(double(kBitModelTotal >> kNumMoveReducingBits)); + for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++) + ProbPrices[i] = UInt32((fabs(lnAll - log(double(i))) / ln2 + kDummyMultMid) * kBitPrice); + */ + + /* + // experimental, slow, solution: + for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++) + { + const int kCyclesBits = 5; + const UInt32 kCycles = (1 << kCyclesBits); + + UInt32 range = UInt32(-1); + UInt32 bitCount = 0; + for (UInt32 j = 0; j < kCycles; j++) + { + range >>= (kNumBitModelTotalBits - kNumMoveReducingBits); + range *= i; + while(range < (1 << 31)) + { + range <<= 1; + bitCount++; + } + } + bitCount <<= kNumBitPriceShiftBits; + range -= (1 << 31); + for (int k = kNumBitPriceShiftBits - 1; k >= 0; k--) + { + range <<= 1; + if (range > (1 << 31)) + { + bitCount += (1 << k); + range -= (1 << 31); + } + } + ProbPrices[i] = (bitCount + // + (1 << (kCyclesBits - 1)) + ) >> kCyclesBits; + } + */ +} + +}} diff --git a/CPP/7zip/Compress/RangeCoder/RangeCoderBit.h b/CPP/7zip/Compress/RangeCoder/RangeCoderBit.h new file mode 100755 index 00000000..624f887c --- /dev/null +++ b/CPP/7zip/Compress/RangeCoder/RangeCoderBit.h @@ -0,0 +1,120 @@ +// Compress/RangeCoder/RangeCoderBit.h + +#ifndef __COMPRESS_RANGECODER_BIT_H +#define __COMPRESS_RANGECODER_BIT_H + +#include "RangeCoder.h" + +namespace NCompress { +namespace NRangeCoder { + +const int kNumBitModelTotalBits = 11; +const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits); + +const int kNumMoveReducingBits = 2; + +const int kNumBitPriceShiftBits = 6; +const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits; + +class CPriceTables +{ +public: + static UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; + static void Init(); + CPriceTables(); +}; + +template +class CBitModel +{ +public: + UInt32 Prob; + void UpdateModel(UInt32 symbol) + { + /* + Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits; + Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits); + */ + if (symbol == 0) + Prob += (kBitModelTotal - Prob) >> numMoveBits; + else + Prob -= (Prob) >> numMoveBits; + } +public: + void Init() { Prob = kBitModelTotal / 2; } +}; + +template +class CBitEncoder: public CBitModel +{ +public: + void Encode(CEncoder *encoder, UInt32 symbol) + { + /* + encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol); + this->UpdateModel(symbol); + */ + UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob; + if (symbol == 0) + { + encoder->Range = newBound; + this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits; + } + else + { + encoder->Low += newBound; + encoder->Range -= newBound; + this->Prob -= (this->Prob) >> numMoveBits; + } + if (encoder->Range < kTopValue) + { + encoder->Range <<= 8; + encoder->ShiftLow(); + } + } + UInt32 GetPrice(UInt32 symbol) const + { + return CPriceTables::ProbPrices[ + (((this->Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits]; + } + UInt32 GetPrice0() const { return CPriceTables::ProbPrices[this->Prob >> kNumMoveReducingBits]; } + UInt32 GetPrice1() const { return CPriceTables::ProbPrices[(kBitModelTotal - this->Prob) >> kNumMoveReducingBits]; } +}; + + +template +class CBitDecoder: public CBitModel +{ +public: + UInt32 Decode(CDecoder *decoder) + { + UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob; + if (decoder->Code < newBound) + { + decoder->Range = newBound; + this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits; + if (decoder->Range < kTopValue) + { + decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte(); + decoder->Range <<= 8; + } + return 0; + } + else + { + decoder->Range -= newBound; + decoder->Code -= newBound; + this->Prob -= (this->Prob) >> numMoveBits; + if (decoder->Range < kTopValue) + { + decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte(); + decoder->Range <<= 8; + } + return 1; + } + } +}; + +}} + +#endif diff --git a/CPP/7zip/Compress/RangeCoder/RangeCoderBitTree.h b/CPP/7zip/Compress/RangeCoder/RangeCoderBitTree.h new file mode 100755 index 00000000..4f0c78b4 --- /dev/null +++ b/CPP/7zip/Compress/RangeCoder/RangeCoderBitTree.h @@ -0,0 +1,161 @@ +// Compress/RangeCoder/RangeCoderBitTree.h + +#ifndef __COMPRESS_RANGECODER_BIT_TREE_H +#define __COMPRESS_RANGECODER_BIT_TREE_H + +#include "RangeCoderBit.h" +#include "RangeCoderOpt.h" + +namespace NCompress { +namespace NRangeCoder { + +template +class CBitTreeEncoder +{ + CBitEncoder Models[1 << NumBitLevels]; +public: + void Init() + { + for(UInt32 i = 1; i < (1 << NumBitLevels); i++) + Models[i].Init(); + } + void Encode(CEncoder *rangeEncoder, UInt32 symbol) + { + UInt32 modelIndex = 1; + for (int bitIndex = NumBitLevels; bitIndex != 0 ;) + { + bitIndex--; + UInt32 bit = (symbol >> bitIndex) & 1; + Models[modelIndex].Encode(rangeEncoder, bit); + modelIndex = (modelIndex << 1) | bit; + } + }; + void ReverseEncode(CEncoder *rangeEncoder, UInt32 symbol) + { + UInt32 modelIndex = 1; + for (int i = 0; i < NumBitLevels; i++) + { + UInt32 bit = symbol & 1; + Models[modelIndex].Encode(rangeEncoder, bit); + modelIndex = (modelIndex << 1) | bit; + symbol >>= 1; + } + } + UInt32 GetPrice(UInt32 symbol) const + { + symbol |= (1 << NumBitLevels); + UInt32 price = 0; + while (symbol != 1) + { + price += Models[symbol >> 1].GetPrice(symbol & 1); + symbol >>= 1; + } + return price; + } + UInt32 ReverseGetPrice(UInt32 symbol) const + { + UInt32 price = 0; + UInt32 modelIndex = 1; + for (int i = NumBitLevels; i != 0; i--) + { + UInt32 bit = symbol & 1; + symbol >>= 1; + price += Models[modelIndex].GetPrice(bit); + modelIndex = (modelIndex << 1) | bit; + } + return price; + } +}; + +template +class CBitTreeDecoder +{ + CBitDecoder Models[1 << NumBitLevels]; +public: + void Init() + { + for(UInt32 i = 1; i < (1 << NumBitLevels); i++) + Models[i].Init(); + } + UInt32 Decode(CDecoder *rangeDecoder) + { + UInt32 modelIndex = 1; + RC_INIT_VAR + for(int bitIndex = NumBitLevels; bitIndex != 0; bitIndex--) + { + // modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder); + RC_GETBIT(numMoveBits, Models[modelIndex].Prob, modelIndex) + } + RC_FLUSH_VAR + return modelIndex - (1 << NumBitLevels); + }; + UInt32 ReverseDecode(CDecoder *rangeDecoder) + { + UInt32 modelIndex = 1; + UInt32 symbol = 0; + RC_INIT_VAR + for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++) + { + // UInt32 bit = Models[modelIndex].Decode(rangeDecoder); + // modelIndex <<= 1; + // modelIndex += bit; + // symbol |= (bit << bitIndex); + RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex)) + } + RC_FLUSH_VAR + return symbol; + } +}; + +template +void ReverseBitTreeEncode(CBitEncoder *Models, + CEncoder *rangeEncoder, int NumBitLevels, UInt32 symbol) +{ + UInt32 modelIndex = 1; + for (int i = 0; i < NumBitLevels; i++) + { + UInt32 bit = symbol & 1; + Models[modelIndex].Encode(rangeEncoder, bit); + modelIndex = (modelIndex << 1) | bit; + symbol >>= 1; + } +} + +template +UInt32 ReverseBitTreeGetPrice(CBitEncoder *Models, + UInt32 NumBitLevels, UInt32 symbol) +{ + UInt32 price = 0; + UInt32 modelIndex = 1; + for (int i = NumBitLevels; i != 0; i--) + { + UInt32 bit = symbol & 1; + symbol >>= 1; + price += Models[modelIndex].GetPrice(bit); + modelIndex = (modelIndex << 1) | bit; + } + return price; +} + +template +UInt32 ReverseBitTreeDecode(CBitDecoder *Models, + CDecoder *rangeDecoder, int NumBitLevels) +{ + UInt32 modelIndex = 1; + UInt32 symbol = 0; + RC_INIT_VAR + for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++) + { + // UInt32 bit = Models[modelIndex].Decode(rangeDecoder); + // modelIndex <<= 1; + // modelIndex += bit; + // symbol |= (bit << bitIndex); + RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex)) + } + RC_FLUSH_VAR + return symbol; +} + +}} + +#endif diff --git a/CPP/7zip/Compress/RangeCoder/RangeCoderOpt.h b/CPP/7zip/Compress/RangeCoder/RangeCoderOpt.h new file mode 100755 index 00000000..668b9a5b --- /dev/null +++ b/CPP/7zip/Compress/RangeCoder/RangeCoderOpt.h @@ -0,0 +1,31 @@ +// Compress/RangeCoder/RangeCoderOpt.h + +#ifndef __COMPRESS_RANGECODER_OPT_H +#define __COMPRESS_RANGECODER_OPT_H + +#define RC_INIT_VAR \ + UInt32 range = rangeDecoder->Range; \ + UInt32 code = rangeDecoder->Code; + +#define RC_FLUSH_VAR \ + rangeDecoder->Range = range; \ + rangeDecoder->Code = code; + +#define RC_NORMALIZE \ + if (range < NCompress::NRangeCoder::kTopValue) \ + { code = (code << 8) | rangeDecoder->Stream.ReadByte(); range <<= 8; } + +#define RC_GETBIT2(numMoveBits, prob, mi, A0, A1) \ + { UInt32 bound = (range >> NCompress::NRangeCoder::kNumBitModelTotalBits) * prob; \ + if (code < bound) \ + { A0; range = bound; \ + prob += (NCompress::NRangeCoder::kBitModelTotal - prob) >> numMoveBits; \ + mi <<= 1; } \ + else \ + { A1; range -= bound; code -= bound; prob -= (prob) >> numMoveBits; \ + mi = (mi + mi) + 1; }} \ + RC_NORMALIZE + +#define RC_GETBIT(numMoveBits, prob, mi) RC_GETBIT2(numMoveBits, prob, mi, ; , ;) + +#endif diff --git a/CPP/7zip/Compress/RangeCoder/StdAfx.h b/CPP/7zip/Compress/RangeCoder/StdAfx.h new file mode 100755 index 00000000..b637fd40 --- /dev/null +++ b/CPP/7zip/Compress/RangeCoder/StdAfx.h @@ -0,0 +1,6 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#endif diff --git a/CPP/7zip/Compress/Rar/DllExports.cpp b/CPP/7zip/Compress/Rar/DllExports.cpp new file mode 100755 index 00000000..acc3068e --- /dev/null +++ b/CPP/7zip/Compress/Rar/DllExports.cpp @@ -0,0 +1,91 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" + +#include "Rar1Decoder.h" +#include "Rar2Decoder.h" +#include "Rar3Decoder.h" +// #include "Rar29Decoder.h" + +#define RarClassId(ver) CLSID_CCompressRar ## ver ## Decoder + +#define MyClassRar(ver) DEFINE_GUID(RarClassId(ver), \ +0x23170F69, 0x40C1, 0x278B, 0x04, 0x03, ver, 0x00, 0x00, 0x00, 0x00, 0x00); + +MyClassRar(1); +MyClassRar(2); +MyClassRar(3); + +#define CreateCoder(ver) if (*clsid == RarClassId(ver)) \ +{ if (!correctInterface) return E_NOINTERFACE; \ +coder = (ICompressCoder *)new NCompress::NRar ## ver::CDecoder; } + +extern "C" +BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /*lpReserved*/) +{ + return TRUE; +} + +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + int correctInterface = (*iid == IID_ICompressCoder); + CMyComPtr coder; + CreateCoder(1) else + CreateCoder(2) else + CreateCoder(3) else + return CLASS_E_CLASSNOTAVAILABLE; + *outObject = coder.Detach(); + COM_TRY_END + return S_OK; +} + +struct CRarMethodItem +{ + char ID[3]; + const wchar_t *UserName; + const GUID *Decoder; +}; + +static CRarMethodItem g_Methods[] = +{ + { { 0x04, 0x03, 0x01 }, L"Rar15", &RarClassId(1) }, + { { 0x04, 0x03, 0x02 }, L"Rar20", &RarClassId(2) }, + { { 0x04, 0x03, 0x03 }, L"Rar29", &RarClassId(3) } +}; + +STDAPI GetNumberOfMethods(UINT32 *numMethods) +{ + *numMethods = sizeof(g_Methods) / sizeof(g_Methods[1]); + return S_OK; +} + +STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +{ + if (index > sizeof(g_Methods) / sizeof(g_Methods[1])) + return E_INVALIDARG; + VariantClear((tagVARIANT *)value); + const CRarMethodItem &method = g_Methods[index]; + switch(propID) + { + case NMethodPropID::kID: + if ((value->bstrVal = ::SysAllocStringByteLen(method.ID, + sizeof(method.ID))) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kName: + if ((value->bstrVal = ::SysAllocString(method.UserName)) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kDecoder: + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)method.Decoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + return S_OK; +} diff --git a/CPP/7zip/Compress/Rar/Rar1Decoder.cpp b/CPP/7zip/Compress/Rar/Rar1Decoder.cpp new file mode 100755 index 00000000..c30443de --- /dev/null +++ b/CPP/7zip/Compress/Rar/Rar1Decoder.cpp @@ -0,0 +1,485 @@ +// Rar1Decoder.cpp +// According to unRAR license, +// this code may not be used to develop a +// RAR (WinRAR) compatible archiver + +#include "StdAfx.h" + +#include "Rar1Decoder.h" + +namespace NCompress { +namespace NRar1 { + +static UInt32 PosL1[]={0,0,0,2,3,5,7,11,16,20,24,32,32, 256}; +static UInt32 PosL2[]={0,0,0,0,5,7,9,13,18,22,26,34,36, 256}; +static UInt32 PosHf0[]={0,0,0,0,0,8,16,24,33,33,33,33,33, 257}; +static UInt32 PosHf1[]={0,0,0,0,0,0,4,44,60,76,80,80,127, 257}; +static UInt32 PosHf2[]={0,0,0,0,0,0,2,7,53,117,233, 257,0}; +static UInt32 PosHf3[]={0,0,0,0,0,0,0,2,16,218,251, 257,0}; +static UInt32 PosHf4[]={0,0,0,0,0,0,0,0,0,255, 257,0,0}; + +static const UInt32 kHistorySize = (1 << 16); + +class CCoderReleaser +{ + CDecoder *m_Coder; +public: + CCoderReleaser(CDecoder *coder): m_Coder(coder) {} + ~CCoderReleaser() { m_Coder->ReleaseStreams(); } +}; + +CDecoder::CDecoder(): m_IsSolid(false) { } + +void CDecoder::InitStructures() +{ + for(int i = 0; i < kNumRepDists; i++) + m_RepDists[i] = 0; + m_RepDistPtr = 0; + LastLength = 0; + LastDist = 0; +} + +UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); } + +HRESULT CDecoder::CopyBlock(UInt32 distance, UInt32 len) +{ + m_UnpackSize -= len; + return m_OutWindowStream.CopyBlock(distance, len) ? S_OK : S_FALSE; +} + + +UInt32 CDecoder::DecodeNum(const UInt32 *posTab) +{ + UInt32 startPos = 2; + UInt32 num = m_InBitStream.GetValue(12); + for (;;) + { + UInt32 cur = (posTab[startPos + 1] - posTab[startPos]) << (12 - startPos); + if (num < cur) + break; + startPos++; + num -= cur; + } + m_InBitStream.MovePos(startPos); + return((num >> (12 - startPos)) + posTab[startPos]); +} + +static Byte kShortLen1[] = {1,3,4,4,5,6,7,8,8,4,4,5,6,6 }; +static Byte kShortLen1a[] = {1,4,4,4,5,6,7,8,8,4,4,5,6,6,4 }; +static Byte kShortLen2[] = {2,3,3,3,4,4,5,6,6,4,4,5,6,6 }; +static Byte kShortLen2a[] = {2,3,3,4,4,4,5,6,6,4,4,5,6,6,4 }; +static UInt32 kShortXor1[] = {0,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xc0,0x80,0x90,0x98,0x9c,0xb0}; +static UInt32 kShortXor2[] = {0,0x40,0x60,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xc0,0x80,0x90,0x98,0x9c,0xb0}; + +HRESULT CDecoder::ShortLZ() +{ + UInt32 len, saveLen, dist; + int distancePlace; + Byte *kShortLen; + const UInt32 *kShortXor; + NumHuf = 0; + + if (LCount == 2) + { + if (ReadBits(1)) + return CopyBlock(LastDist, LastLength); + LCount = 0; + } + + UInt32 bitField = m_InBitStream.GetValue(8); + + if (AvrLn1 < 37) + { + kShortLen = Buf60 ? kShortLen1a : kShortLen1; + kShortXor = kShortXor1; + } + else + { + kShortLen = Buf60 ? kShortLen2a : kShortLen2; + kShortXor = kShortXor2; + } + + for (len = 0; ((bitField ^ kShortXor[len]) & (~(0xff >> kShortLen[len]))) != 0; len++); + m_InBitStream.MovePos(kShortLen[len]); + + if (len >= 9) + { + if (len == 9) + { + LCount++; + return CopyBlock(LastDist, LastLength); + } + if (len == 14) + { + LCount = 0; + len = DecodeNum(PosL2) + 5; + dist = 0x8000 + ReadBits(15) - 1; + LastLength = len; + LastDist = dist; + return CopyBlock(dist, len); + } + + LCount = 0; + saveLen = len; + dist = m_RepDists[(m_RepDistPtr - (len - 9)) & 3]; + len = DecodeNum(PosL1) + 2; + if (len == 0x101 && saveLen == 10) + { + Buf60 ^= 1; + return S_OK; + } + if (dist >= 256) + len++; + if (dist >= MaxDist3 - 1) + len++; + } + else + { + LCount = 0; + AvrLn1 += len; + AvrLn1 -= AvrLn1 >> 4; + + distancePlace = DecodeNum(PosHf2) & 0xff; + dist = ChSetA[distancePlace]; + if (--distancePlace != -1) + { + PlaceA[dist]--; + UInt32 lastDistance = ChSetA[distancePlace]; + PlaceA[lastDistance]++; + ChSetA[distancePlace + 1] = lastDistance; + ChSetA[distancePlace] = dist; + } + len += 2; + } + m_RepDists[m_RepDistPtr++] = dist; + m_RepDistPtr &= 3; + LastLength = len; + LastDist = dist; + return CopyBlock(dist, len); +} + + +HRESULT CDecoder::LongLZ() +{ + UInt32 len; + UInt32 dist; + UInt32 distancePlace, newDistancePlace; + UInt32 oldAvr2, oldAvr3; + + NumHuf = 0; + Nlzb += 16; + if (Nlzb > 0xff) + { + Nlzb = 0x90; + Nhfb >>= 1; + } + oldAvr2=AvrLn2; + + if (AvrLn2 >= 122) + len = DecodeNum(PosL2); + else if (AvrLn2 >= 64) + len = DecodeNum(PosL1); + else + { + UInt32 bitField = m_InBitStream.GetValue(16); + if (bitField < 0x100) + { + len = bitField; + m_InBitStream.MovePos(16); + } + else + { + for (len = 0; ((bitField << len) & 0x8000) == 0; len++) + ; + m_InBitStream.MovePos(len + 1); + } + } + + AvrLn2 += len; + AvrLn2 -= AvrLn2 >> 5; + + if (AvrPlcB > 0x28ff) + distancePlace = DecodeNum(PosHf2); + else if (AvrPlcB > 0x6ff) + distancePlace = DecodeNum(PosHf1); + else + distancePlace = DecodeNum(PosHf0); + + AvrPlcB += distancePlace; + AvrPlcB -= AvrPlcB >> 8; + for (;;) + { + dist = ChSetB[distancePlace & 0xff]; + newDistancePlace = NToPlB[dist++ & 0xff]++; + if (!(dist & 0xff)) + CorrHuff(ChSetB,NToPlB); + else + break; + } + + ChSetB[distancePlace] = ChSetB[newDistancePlace]; + ChSetB[newDistancePlace] = dist; + + dist = ((dist & 0xff00) >> 1) | ReadBits(7); + + oldAvr3 = AvrLn3; + if (len != 1 && len != 4) + if (len == 0 && dist <= MaxDist3) + { + AvrLn3++; + AvrLn3 -= AvrLn3 >> 8; + } + else + if (AvrLn3 > 0) + AvrLn3--; + len += 3; + if (dist >= MaxDist3) + len++; + if (dist <= 256) + len += 8; + if (oldAvr3 > 0xb0 || AvrPlc >= 0x2a00 && oldAvr2 < 0x40) + MaxDist3 = 0x7f00; + else + MaxDist3 = 0x2001; + m_RepDists[m_RepDistPtr++] = --dist; + m_RepDistPtr &= 3; + LastLength = len; + LastDist = dist; + return CopyBlock(dist, len); +} + + +HRESULT CDecoder::HuffDecode() +{ + UInt32 curByte, newBytePlace; + UInt32 len; + UInt32 dist; + int bytePlace; + + if (AvrPlc > 0x75ff) bytePlace = DecodeNum(PosHf4); + else if (AvrPlc > 0x5dff) bytePlace = DecodeNum(PosHf3); + else if (AvrPlc > 0x35ff) bytePlace = DecodeNum(PosHf2); + else if (AvrPlc > 0x0dff) bytePlace = DecodeNum(PosHf1); + else bytePlace = DecodeNum(PosHf0); + if (StMode) + { + if (--bytePlace == -1) + { + if (ReadBits(1)) + { + NumHuf = StMode = 0; + return S_OK; + } + else + { + len = (ReadBits(1)) ? 4 : 3; + dist = DecodeNum(PosHf2); + dist = (dist << 5) | ReadBits(5); + return CopyBlock(dist - 1, len); + } + } + } + else if (NumHuf++ >= 16 && FlagsCnt == 0) + StMode = 1; + bytePlace &= 0xff; + AvrPlc += bytePlace; + AvrPlc -= AvrPlc >> 8; + Nhfb+=16; + if (Nhfb > 0xff) + { + Nhfb=0x90; + Nlzb >>= 1; + } + + m_UnpackSize --; + m_OutWindowStream.PutByte((Byte)(ChSet[bytePlace] >> 8)); + + for (;;) + { + curByte = ChSet[bytePlace]; + newBytePlace = NToPl[curByte++ & 0xff]++; + if ((curByte & 0xff) > 0xa1) + CorrHuff(ChSet, NToPl); + else + break; + } + + ChSet[bytePlace] = ChSet[newBytePlace]; + ChSet[newBytePlace] = curByte; + return S_OK; +} + + +void CDecoder::GetFlagsBuf() +{ + UInt32 flags, newFlagsPlace; + UInt32 flagsPlace = DecodeNum(PosHf2); + + for (;;) + { + flags = ChSetC[flagsPlace]; + FlagBuf = flags >> 8; + newFlagsPlace = NToPlC[flags++ & 0xff]++; + if ((flags & 0xff) != 0) + break; + CorrHuff(ChSetC, NToPlC); + } + + ChSetC[flagsPlace] = ChSetC[newFlagsPlace]; + ChSetC[newFlagsPlace] = flags; +} + +void CDecoder::InitData() +{ + if (!m_IsSolid) + { + AvrPlcB = AvrLn1 = AvrLn2 = AvrLn3 = NumHuf = Buf60 = 0; + AvrPlc = 0x3500; + MaxDist3 = 0x2001; + Nhfb = Nlzb = 0x80; + } + FlagsCnt = 0; + FlagBuf = 0; + StMode = 0; + LCount = 0; +} + +void CDecoder::CorrHuff(UInt32 *CharSet,UInt32 *NumToPlace) +{ + int i; + for (i = 7; i >= 0; i--) + for (int j = 0; j < 32; j++, CharSet++) + *CharSet = (*CharSet & ~0xff) | i; + memset(NumToPlace, 0, sizeof(NToPl)); + for (i = 6; i >= 0; i--) + NumToPlace[i] = (7 - i) * 32; +} + +void CDecoder::InitHuff() +{ + for (UInt32 i = 0; i < 256; i++) + { + Place[i] = PlaceA[i] = PlaceB[i] = i; + PlaceC[i] = (~i + 1) & 0xff; + ChSet[i] = ChSetB[i] = i << 8; + ChSetA[i] = i; + ChSetC[i] = ((~i + 1) & 0xff) << 8; + } + memset(NToPl, 0, sizeof(NToPl)); + memset(NToPlB, 0, sizeof(NToPlB)); + memset(NToPlC, 0, sizeof(NToPlC)); + CorrHuff(ChSetB, NToPlB); +} + +STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo * /* progress */) +{ + if (inSize == NULL || outSize == NULL) + return E_INVALIDARG; + + if (!m_OutWindowStream.Create(kHistorySize)) + return E_OUTOFMEMORY; + if (!m_InBitStream.Create(1 << 20)) + return E_OUTOFMEMORY; + + m_UnpackSize = (Int64)*outSize; + m_OutWindowStream.SetStream(outStream); + m_OutWindowStream.Init(m_IsSolid); + m_InBitStream.SetStream(inStream); + m_InBitStream.Init(); + + CCoderReleaser coderReleaser(this); + InitData(); + if (!m_IsSolid) + { + InitStructures(); + InitHuff(); + } + if (m_UnpackSize > 0) + { + GetFlagsBuf(); + FlagsCnt = 8; + } + + while (m_UnpackSize > 0) + { + if (StMode) + { + RINOK(HuffDecode()); + continue; + } + + if (--FlagsCnt < 0) + { + GetFlagsBuf(); + FlagsCnt=7; + } + + if (FlagBuf & 0x80) + { + FlagBuf <<= 1; + if (Nlzb > Nhfb) + { + RINOK(LongLZ()); + } + else + { + RINOK(HuffDecode()); + } + } + else + { + FlagBuf <<= 1; + if (--FlagsCnt < 0) + { + GetFlagsBuf(); + FlagsCnt = 7; + } + if (FlagBuf & 0x80) + { + FlagBuf <<= 1; + if (Nlzb > Nhfb) + { + RINOK(HuffDecode()); + } + else + { + RINOK(LongLZ()); + } + } + else + { + FlagBuf <<= 1; + RINOK(ShortLZ()); + } + } + } + if (m_UnpackSize < 0) + return S_FALSE; + return m_OutWindowStream.Flush(); +} + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try + { + HRESULT res = CodeReal(inStream, outStream, inSize, outSize, progress); + m_OutWindowStream.Flush(); + return res; + } + catch(const CLZOutWindowException &e) { m_OutWindowStream.Flush(); return e.ErrorCode; } + catch(...) { m_OutWindowStream.Flush(); return S_FALSE; } +} + +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) +{ + if (size < 1) + return E_INVALIDARG; + m_IsSolid = (data[0] != 0); + return S_OK; +} + +}} diff --git a/CPP/7zip/Compress/Rar/Rar1Decoder.h b/CPP/7zip/Compress/Rar/Rar1Decoder.h new file mode 100755 index 00000000..bdaf4d85 --- /dev/null +++ b/CPP/7zip/Compress/Rar/Rar1Decoder.h @@ -0,0 +1,90 @@ +// Rar15Decoder.h +// According to unRAR license, +// this code may not be used to develop a +// RAR (WinRAR) compatible archiver + +#ifndef __RAR10_DECODER_H +#define __RAR10_DECODER_H + +#include "../../../Common/MyCom.h" + +#include "../../ICoder.h" +#include "../../Common/MSBFDecoder.h" +#include "../../Common/InBuffer.h" + +#include "../LZ/LZOutWindow.h" +#include "../Huffman/HuffmanDecoder.h" + +namespace NCompress { +namespace NRar1 { + +const UInt32 kNumRepDists = 4; + +typedef NStream::NMSBF::CDecoder CBitDecoder; + +class CDecoder : + public ICompressCoder, + public ICompressSetDecoderProperties2, + public CMyUnknownImp +{ +public: + CLZOutWindow m_OutWindowStream; + CBitDecoder m_InBitStream; + + UInt32 m_RepDists[kNumRepDists]; + UInt32 m_RepDistPtr; + + UInt32 LastDist; + UInt32 LastLength; + + Int64 m_UnpackSize; + bool m_IsSolid; + + UInt32 ReadBits(int numBits); + HRESULT CopyBlock(UInt32 distance, UInt32 len); + + UInt32 DecodeNum(const UInt32 *posTab); + HRESULT ShortLZ(); + HRESULT LongLZ(); + HRESULT HuffDecode(); + void GetFlagsBuf(); + void InitData(); + void InitHuff(); + void CorrHuff(UInt32 *CharSet, UInt32 *NumToPlace); + void OldUnpWriteBuf(); + + UInt32 ChSet[256],ChSetA[256],ChSetB[256],ChSetC[256]; + UInt32 Place[256],PlaceA[256],PlaceB[256],PlaceC[256]; + UInt32 NToPl[256],NToPlB[256],NToPlC[256]; + UInt32 FlagBuf,AvrPlc,AvrPlcB,AvrLn1,AvrLn2,AvrLn3; + int Buf60,NumHuf,StMode,LCount,FlagsCnt; + UInt32 Nhfb,Nlzb,MaxDist3; + + void InitStructures(); + +public: + CDecoder(); + + MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) + + void ReleaseStreams() + { + m_OutWindowStream.ReleaseStream(); + m_InBitStream.ReleaseStream(); + } + + STDMETHOD(CodeReal)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + +}; + +}} + +#endif diff --git a/CPP/7zip/Compress/Rar/Rar29.dsp b/CPP/7zip/Compress/Rar/Rar29.dsp new file mode 100755 index 00000000..9a0b86bb --- /dev/null +++ b/CPP/7zip/Compress/Rar/Rar29.dsp @@ -0,0 +1,297 @@ +# Microsoft Developer Studio Project File - Name="Rar29" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Rar29 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Rar29.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Rar29.mak" CFG="Rar29 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Rar29 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Rar29 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Rar29 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RAR29_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RAR29_EXPORTS" /D "SILENT" /D "NOCRYPT" /D "NOVOLUME" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\Rar29.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RAR29_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RAR29_EXPORTS" /D "SILENT" /D "NOCRYPT" /D "NOVOLUME" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\Rar29.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Rar29 - Win32 Release" +# Name "Rar29 - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Codec.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MSBFDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "LZ" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\LZ\LZOutWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\LZ\LZOutWindow.h +# End Source File +# End Group +# Begin Group "Huffman" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Huffman\HuffmanDecoder.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# End Group +# Begin Group "Rar3" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\PPMD\PPMDContext.h +# End Source File +# Begin Source File + +SOURCE=..\PPMD\PPMDDecode.h +# End Source File +# Begin Source File + +SOURCE=..\PPMD\PPMDSubAlloc.h +# End Source File +# Begin Source File + +SOURCE=..\PPMD\PPMDType.h +# End Source File +# Begin Source File + +SOURCE=.\Rar1Decoder.cpp + +!IF "$(CFG)" == "Rar29 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\Rar1Decoder.h +# End Source File +# Begin Source File + +SOURCE=.\Rar2Decoder.cpp + +!IF "$(CFG)" == "Rar29 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\Rar2Decoder.h +# End Source File +# Begin Source File + +SOURCE=.\Rar3Decoder.cpp + +!IF "$(CFG)" == "Rar29 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\Rar3Decoder.h +# End Source File +# Begin Source File + +SOURCE=.\Rar3Vm.cpp + +!IF "$(CFG)" == "Rar29 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\Rar3Vm.h +# End Source File +# End Group +# End Target +# End Project diff --git a/CPP/7zip/Compress/Rar/Rar29.dsw b/CPP/7zip/Compress/Rar/Rar29.dsw new file mode 100755 index 00000000..70172e1a --- /dev/null +++ b/CPP/7zip/Compress/Rar/Rar29.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Rar29"=.\Rar29.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Compress/Rar/Rar2Decoder.cpp b/CPP/7zip/Compress/Rar/Rar2Decoder.cpp new file mode 100755 index 00000000..43473695 --- /dev/null +++ b/CPP/7zip/Compress/Rar/Rar2Decoder.cpp @@ -0,0 +1,401 @@ +// Rar2Decoder.cpp +// According to unRAR license, +// this code may not be used to develop a +// RAR (WinRAR) compatible archiver + +#include "StdAfx.h" + +#include "Rar2Decoder.h" + +namespace NCompress { +namespace NRar2 { + +namespace NMultimedia { + +Byte CFilter::Decode(int &channelDelta, Byte deltaByte) +{ + D4 = D3; + D3 = D2; + D2 = LastDelta - D1; + D1 = LastDelta; + int predictedValue = ((8 * LastChar + K1 * D1 + K2 * D2 + K3 * D3 + K4 * D4 + K5 * channelDelta) >> 3); + + Byte realValue = (Byte)(predictedValue - deltaByte); + int i = ((int)(signed char)deltaByte) << 3; + + Dif[0] += abs(i); + Dif[1] += abs(i - D1); + Dif[2] += abs(i + D1); + Dif[3] += abs(i - D2); + Dif[4] += abs(i + D2); + Dif[5] += abs(i - D3); + Dif[6] += abs(i + D3); + Dif[7] += abs(i - D4); + Dif[8] += abs(i + D4); + Dif[9] += abs(i - channelDelta); + Dif[10] += abs(i + channelDelta); + + channelDelta = LastDelta = (signed char)(realValue - LastChar); + LastChar = realValue; + + if (((++ByteCount) & 0x1F) == 0) + { + UInt32 minDif = Dif[0]; + UInt32 numMinDif = 0; + Dif[0] = 0; + for (i = 1; i < sizeof(Dif) / sizeof(Dif[0]); i++) + { + if (Dif[i] < minDif) + { + minDif = Dif[i]; + numMinDif = i; + } + Dif[i] = 0; + } + switch(numMinDif) + { + case 1: if (K1 >= -16) K1--; break; + case 2: if (K1 < 16) K1++; break; + case 3: if (K2 >= -16) K2--; break; + case 4: if (K2 < 16) K2++; break; + case 5: if (K3 >= -16) K3--; break; + case 6: if (K3 < 16) K3++; break; + case 7: if (K4 >= -16) K4--; break; + case 8: if (K4 < 16) K4++; break; + case 9: if (K5 >= -16) K5--; break; + case 10:if (K5 < 16) K5++; break; + } + } + return realValue; +} +} + +class CException +{ +public: + enum ECauseType + { + kData + } Cause; + CException(ECauseType cause): Cause(cause) {} +}; + +static const char *kNumberErrorMessage = "Number error"; + +static const UInt32 kHistorySize = 1 << 20; + +static const int kNumStats = 11; + +static const UInt32 kWindowReservSize = (1 << 22) + 256; + +CDecoder::CDecoder(): + m_IsSolid(false) +{ +} + +void CDecoder::InitStructures() +{ + m_MmFilter.Init(); + for(int i = 0; i < kNumRepDists; i++) + m_RepDists[i] = 0; + m_RepDistPtr = 0; + m_LastLength = 0; + memset(m_LastLevels, 0, kMaxTableSize); +} + +UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); } + +#define RIF(x) { if (!(x)) return false; } + +bool CDecoder::ReadTables(void) +{ + Byte levelLevels[kLevelTableSize]; + Byte newLevels[kMaxTableSize]; + m_AudioMode = (ReadBits(1) == 1); + + if (ReadBits(1) == 0) + memset(m_LastLevels, 0, kMaxTableSize); + int numLevels; + if (m_AudioMode) + { + m_NumChannels = ReadBits(2) + 1; + if (m_MmFilter.CurrentChannel >= m_NumChannels) + m_MmFilter.CurrentChannel = 0; + numLevels = m_NumChannels * kMMTableSize; + } + else + numLevels = kHeapTablesSizesSum; + + int i; + for (i = 0; i < kLevelTableSize; i++) + levelLevels[i] = (Byte)ReadBits(4); + RIF(m_LevelDecoder.SetCodeLengths(levelLevels)); + i = 0; + while (i < numLevels) + { + UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); + if (number < kTableDirectLevels) + { + newLevels[i] = (Byte)((number + m_LastLevels[i]) & kLevelMask); + i++; + } + else + { + if (number == kTableLevelRepNumber) + { + int t = ReadBits(2) + 3; + for (int reps = t; reps > 0 && i < numLevels ; reps--, i++) + newLevels[i] = newLevels[i - 1]; + } + else + { + int num; + if (number == kTableLevel0Number) + num = ReadBits(3) + 3; + else if (number == kTableLevel0Number2) + num = ReadBits(7) + 11; + else + return false; + for (;num > 0 && i < numLevels; num--) + newLevels[i++] = 0; + } + } + } + if (m_AudioMode) + for (i = 0; i < m_NumChannels; i++) + { + RIF(m_MMDecoders[i].SetCodeLengths(&newLevels[i * kMMTableSize])); + } + else + { + RIF(m_MainDecoder.SetCodeLengths(&newLevels[0])); + RIF(m_DistDecoder.SetCodeLengths(&newLevels[kMainTableSize])); + RIF(m_LenDecoder.SetCodeLengths(&newLevels[kMainTableSize + kDistTableSize])); + } + memcpy(m_LastLevels, newLevels, kMaxTableSize); + return true; +} + +bool CDecoder::ReadLastTables() +{ + // it differs a little from pure RAR sources; + // UInt64 ttt = m_InBitStream.GetProcessedSize() + 2; + // + 2 works for: return 0xFF; in CInBuffer::ReadByte. + if (m_InBitStream.GetProcessedSize() + 7 <= m_PackSize) // test it: probably incorrect; + // if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect; + if (m_AudioMode) + { + UInt32 symbol = m_MMDecoders[m_MmFilter.CurrentChannel].DecodeSymbol(&m_InBitStream); + if (symbol == 256) + return ReadTables(); + if (symbol >= kMMTableSize) + return false; + } + else + { + UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); + if (number == kReadTableNumber) + return ReadTables(); + if (number >= kMainTableSize) + return false; + } + return true; +} + +class CCoderReleaser +{ + CDecoder *m_Coder; +public: + CCoderReleaser(CDecoder *coder): m_Coder(coder) {} + ~CCoderReleaser() + { + m_Coder->ReleaseStreams(); + } +}; + +bool CDecoder::DecodeMm(UInt32 pos) +{ + while (pos-- > 0) + { + UInt32 symbol = m_MMDecoders[m_MmFilter.CurrentChannel].DecodeSymbol(&m_InBitStream); + if (symbol == 256) + return true; + if (symbol >= kMMTableSize) + return false; + /* + Byte byPredict = m_Predictor.Predict(); + Byte byReal = (Byte)(byPredict - (Byte)symbol); + m_Predictor.Update(byReal, byPredict); + */ + Byte byReal = m_MmFilter.Decode((Byte)symbol); + m_OutWindowStream.PutByte(byReal); + if (++m_MmFilter.CurrentChannel == m_NumChannels) + m_MmFilter.CurrentChannel = 0; + } + return true; +} + +bool CDecoder::DecodeLz(Int32 pos) +{ + while (pos > 0) + { + UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); + UInt32 length, distance; + if (number < 256) + { + m_OutWindowStream.PutByte(Byte(number)); + pos--; + continue; + } + else if (number >= kMatchNumber) + { + number -= kMatchNumber; + length = kNormalMatchMinLen + UInt32(kLenStart[number]) + + m_InBitStream.ReadBits(kLenDirectBits[number]); + number = m_DistDecoder.DecodeSymbol(&m_InBitStream); + if (number >= kDistTableSize) + return false; + distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]); + if (distance >= kDistLimit3) + { + length += 2 - ((distance - kDistLimit4) >> 31); + // length++; + // if (distance >= kDistLimit4) + // length++; + } + } + else if (number == kRepBothNumber) + { + length = m_LastLength; + distance = m_RepDists[(m_RepDistPtr + 4 - 1) & 3]; + } + else if (number < kLen2Number) + { + distance = m_RepDists[(m_RepDistPtr - (number - kRepNumber + 1)) & 3]; + number = m_LenDecoder.DecodeSymbol(&m_InBitStream); + if (number >= kLenTableSize) + return false; + length = 2 + kLenStart[number] + m_InBitStream.ReadBits(kLenDirectBits[number]); + if (distance >= kDistLimit2) + { + length++; + if (distance >= kDistLimit3) + { + length += 2 - ((distance - kDistLimit4) >> 31); + // length++; + // if (distance >= kDistLimit4) + // length++; + } + } + } + else if (number < kReadTableNumber) + { + number -= kLen2Number; + distance = kLen2DistStarts[number] + + m_InBitStream.ReadBits(kLen2DistDirectBits[number]); + length = 2; + } + else if (number == kReadTableNumber) + return true; + else + return false; + m_RepDists[m_RepDistPtr++ & 3] = distance; + m_LastLength = length; + if (!m_OutWindowStream.CopyBlock(distance, length)) + return false; + pos -= length; + } + return true; +} + +STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + if (inSize == NULL || outSize == NULL) + return E_INVALIDARG; + + if (!m_OutWindowStream.Create(kHistorySize)) + return E_OUTOFMEMORY; + if (!m_InBitStream.Create(1 << 20)) + return E_OUTOFMEMORY; + + m_PackSize = *inSize; + + UInt64 pos = 0, unPackSize = *outSize; + + m_OutWindowStream.SetStream(outStream); + m_OutWindowStream.Init(m_IsSolid); + m_InBitStream.SetStream(inStream); + m_InBitStream.Init(); + + CCoderReleaser coderReleaser(this); + if (!m_IsSolid) + { + InitStructures(); + if (unPackSize == 0) + { + if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect; + if (!ReadTables()) + return S_FALSE; + return S_OK; + } + if (!ReadTables()) + return S_FALSE; + } + + UInt64 startPos = m_OutWindowStream.GetProcessedSize(); + while(pos < unPackSize) + { + UInt32 blockSize = 1 << 20; + if (blockSize > unPackSize - pos) + blockSize = (UInt32)(unPackSize - pos); + UInt64 blockStartPos = m_OutWindowStream.GetProcessedSize(); + if (m_AudioMode) + { + if (!DecodeMm(blockSize)) + return S_FALSE; + } + else + { + if (!DecodeLz((Int32)blockSize)) + return S_FALSE; + } + UInt64 globalPos = m_OutWindowStream.GetProcessedSize(); + pos = globalPos - blockStartPos; + if (pos < blockSize) + if (!ReadTables()) + return S_FALSE; + pos = globalPos - startPos; + if (progress != 0) + { + UInt64 packSize = m_InBitStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &pos)); + } + } + if (pos > unPackSize) + throw CException(CException::kData); + + if (!ReadLastTables()) + return S_FALSE; + return m_OutWindowStream.Flush(); +} + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const CLZOutWindowException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) +{ + if (size < 1) + return E_INVALIDARG; + m_IsSolid = (data[0] != 0); + return S_OK; +} + +}} diff --git a/CPP/7zip/Compress/Rar/Rar2Decoder.h b/CPP/7zip/Compress/Rar/Rar2Decoder.h new file mode 100755 index 00000000..dfd0f816 --- /dev/null +++ b/CPP/7zip/Compress/Rar/Rar2Decoder.h @@ -0,0 +1,176 @@ +// Rar2Decoder.h +// According to unRAR license, +// this code may not be used to develop a +// RAR (WinRAR) compatible archiver + +#ifndef __RAR2DECODER_H +#define __RAR2DECODER_H + +#include "../../../Common/MyCom.h" + +#include "../../ICoder.h" +#include "../../Common/MSBFDecoder.h" +#include "../../Common/InBuffer.h" + +#include "../LZ/LZOutWindow.h" +#include "../Huffman/HuffmanDecoder.h" + +namespace NCompress { +namespace NRar2 { + +const UInt32 kNumRepDists = 4; +const UInt32 kDistTableSize = 48; + +const int kMMTableSize = 256 + 1; + +const UInt32 kMainTableSize = 298; +const UInt32 kLenTableSize = 28; + +const UInt32 kDistTableStart = kMainTableSize; +const UInt32 kLenTableStart = kDistTableStart + kDistTableSize; + +const UInt32 kHeapTablesSizesSum = kMainTableSize + kDistTableSize + kLenTableSize; + +const UInt32 kLevelTableSize = 19; + +const UInt32 kMMTablesSizesSum = kMMTableSize * 4; + +const UInt32 kMaxTableSize = kMMTablesSizesSum; + +const UInt32 kTableDirectLevels = 16; +const UInt32 kTableLevelRepNumber = kTableDirectLevels; +const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1; +const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1; + +const UInt32 kLevelMask = 0xF; + + +const UInt32 kRepBothNumber = 256; +const UInt32 kRepNumber = kRepBothNumber + 1; +const UInt32 kLen2Number = kRepNumber + 4; + +const UInt32 kLen2NumNumbers = 8; +const UInt32 kReadTableNumber = kLen2Number + kLen2NumNumbers; +const UInt32 kMatchNumber = kReadTableNumber + 1; + +const Byte kLenStart[kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224}; +const Byte kLenDirectBits[kLenTableSize] = {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5}; + +const UInt32 kDistStart[kDistTableSize] = {0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768U,49152U,65536,98304,131072,196608,262144,327680,393216,458752,524288,589824,655360,720896,786432,851968,917504,983040}; +const Byte kDistDirectBits[kDistTableSize] = {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}; + +const Byte kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7}; + +const Byte kLen2DistStarts[kLen2NumNumbers]={0,4,8,16,32,64,128,192}; +const Byte kLen2DistDirectBits[kLen2NumNumbers]={2,2,3, 4, 5, 6, 6, 6}; + +const UInt32 kDistLimit2 = 0x101 - 1; +const UInt32 kDistLimit3 = 0x2000 - 1; +const UInt32 kDistLimit4 = 0x40000 - 1; + +const UInt32 kMatchMaxLen = 255 + 2; +const UInt32 kMatchMaxLenMax = 255 + 5; +const UInt32 kNormalMatchMinLen = 3; + +namespace NMultimedia { + +struct CFilter +{ + int K1,K2,K3,K4,K5; + int D1,D2,D3,D4; + int LastDelta; + UInt32 Dif[11]; + UInt32 ByteCount; + int LastChar; + + Byte Decode(int &channelDelta, Byte delta); + + void Init() { memset(this, 0, sizeof(*this)); } + +}; + +const int kNumChanelsMax = 4; + +class CFilter2 +{ +public: + CFilter m_Filters[kNumChanelsMax]; + int m_ChannelDelta; + int CurrentChannel; + + void Init() { memset(this, 0, sizeof(*this)); } + Byte Decode(Byte delta) + { + return m_Filters[CurrentChannel].Decode(m_ChannelDelta, delta); + } + +}; + +} + +typedef NStream::NMSBF::CDecoder CBitDecoder; + +const int kNumHuffmanBits = 15; + +class CDecoder : + public ICompressCoder, + public ICompressSetDecoderProperties2, + public CMyUnknownImp +{ + CLZOutWindow m_OutWindowStream; + CBitDecoder m_InBitStream; + NHuffman::CDecoder m_MainDecoder; + NHuffman::CDecoder m_DistDecoder; + NHuffman::CDecoder m_LenDecoder; + NHuffman::CDecoder m_MMDecoders[NMultimedia::kNumChanelsMax]; + NHuffman::CDecoder m_LevelDecoder; + + bool m_AudioMode; + + NMultimedia::CFilter2 m_MmFilter; + int m_NumChannels; + + UInt32 m_RepDists[kNumRepDists]; + UInt32 m_RepDistPtr; + + UInt32 m_LastLength; + + Byte m_LastLevels[kMaxTableSize]; + + UInt64 m_PackSize; + bool m_IsSolid; + + void InitStructures(); + UInt32 ReadBits(int numBits); + bool ReadTables(); + bool ReadLastTables(); + + bool DecodeMm(UInt32 pos); + bool DecodeLz(Int32 pos); + +public: + CDecoder(); + + MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) + + void ReleaseStreams() + { + m_OutWindowStream.ReleaseStream(); + m_InBitStream.ReleaseStream(); + } + + STDMETHOD(CodeReal)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + +}; + +}} + +#endif diff --git a/CPP/7zip/Compress/Rar/Rar3Decoder.cpp b/CPP/7zip/Compress/Rar/Rar3Decoder.cpp new file mode 100755 index 00000000..478b6587 --- /dev/null +++ b/CPP/7zip/Compress/Rar/Rar3Decoder.cpp @@ -0,0 +1,832 @@ +// Rar3Decoder.cpp +// According to unRAR license, +// this code may not be used to develop a +// RAR (WinRAR) compatible archiver + +#include "StdAfx.h" + +#include "Rar3Decoder.h" +#include "../../Common/StreamUtils.h" + +namespace NCompress { +namespace NRar3 { + +static const UInt32 kNumAlignReps = 15; + +static const UInt32 kSymbolReadTable = 256; +static const UInt32 kSymbolRep = 259; +static const UInt32 kSymbolLen2 = kSymbolRep + kNumReps; + +static const Byte kLenStart[kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224}; +static const Byte kLenDirectBits[kLenTableSize] = {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5}; + +static const Byte kDistDirectBits[kDistTableSize] = + {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 18,18,18,18,18,18,18,18,18,18,18,18}; + +static const Byte kLevelDirectBits[kLevelTableSize] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +static const Byte kLen2DistStarts[kNumLen2Symbols]={0,4,8,16,32,64,128,192}; +static const Byte kLen2DistDirectBits[kNumLen2Symbols]={2,2,3, 4, 5, 6, 6, 6}; + +static const UInt32 kDistLimit3 = 0x2000 - 2; +static const UInt32 kDistLimit4 = 0x40000 - 2; + +static const UInt32 kNormalMatchMinLen = 3; + +static const UInt32 kVmDataSizeMax = 1 << 16; +static const UInt32 kVmCodeSizeMax = 1 << 16; + +CDecoder::CDecoder(): + _window(0), + _winPos(0), + _wrPtr(0), + _lzSize(0), + _writtenFileSize(0), + _vmData(0), + _vmCode(0), + m_IsSolid(false) +{ +} + +CDecoder::~CDecoder() +{ + InitFilters(); + if (_vmData) + ::MidFree(_vmData); +} + +HRESULT CDecoder::WriteDataToStream(const Byte *data, UInt32 size) +{ + UInt32 processedSize; + HRESULT res = WriteStream(_outStream, data, size, &processedSize); + if (res == S_OK && processedSize != size) + res = E_FAIL; + return res; +} + +HRESULT CDecoder::WriteData(const Byte *data, UInt32 size) +{ + HRESULT res = S_OK; + if (_writtenFileSize < _unpackSize) + { + UInt32 curSize = size; + UInt64 remain = _unpackSize - _writtenFileSize; + if (remain < curSize) + curSize = (UInt32)remain; + res = WriteDataToStream(data, curSize); + } + _writtenFileSize += size; + return res; +} + +HRESULT CDecoder::WriteArea(UInt32 startPtr, UInt32 endPtr) +{ + if (startPtr <= endPtr) + return WriteData(_window + startPtr, endPtr - startPtr); + RINOK(WriteData(_window + startPtr, kWindowSize - startPtr)); + return WriteData(_window, endPtr); +} + +void CDecoder::ExecuteFilter(int tempFilterIndex, NVm::CBlockRef &outBlockRef) +{ + CTempFilter *tempFilter = _tempFilters[tempFilterIndex]; + tempFilter->InitR[6] = (UInt32)_writtenFileSize; + NVm::SetValue32(&tempFilter->GlobalData[0x24], (UInt32)_writtenFileSize); + NVm::SetValue32(&tempFilter->GlobalData[0x28], (UInt32)(_writtenFileSize >> 32)); + CFilter *filter = _filters[tempFilter->FilterIndex]; + _vm.Execute(filter, tempFilter, outBlockRef, filter->GlobalData); + delete tempFilter; + _tempFilters[tempFilterIndex] = 0; +} + +HRESULT CDecoder::WriteBuf() +{ + UInt32 writtenBorder = _wrPtr; + UInt32 writeSize = (_winPos - writtenBorder) & kWindowMask; + for (int i = 0; i < _tempFilters.Size(); i++) + { + CTempFilter *filter = _tempFilters[i]; + if (filter == NULL) + continue; + if (filter->NextWindow) + { + filter->NextWindow = false; + continue; + } + UInt32 blockStart = filter->BlockStart; + UInt32 blockSize = filter->BlockSize; + if (((blockStart - writtenBorder) & kWindowMask) < writeSize) + { + if (writtenBorder != blockStart) + { + RINOK(WriteArea(writtenBorder, blockStart)); + writtenBorder = blockStart; + writeSize = (_winPos - writtenBorder) & kWindowMask; + } + if (blockSize <= writeSize) + { + UInt32 blockEnd = (blockStart + blockSize) & kWindowMask; + if (blockStart < blockEnd || blockEnd == 0) + _vm.SetMemory(0, _window + blockStart, blockSize); + else + { + UInt32 tailSize = kWindowSize - blockStart; + _vm.SetMemory(0, _window + blockStart, tailSize); + _vm.SetMemory(tailSize, _window, blockEnd); + } + NVm::CBlockRef outBlockRef; + ExecuteFilter(i, outBlockRef); + while (i + 1 < _tempFilters.Size()) + { + CTempFilter *nextFilter = _tempFilters[i + 1]; + if (nextFilter == NULL || nextFilter->BlockStart != blockStart || + nextFilter->BlockSize != outBlockRef.Size || nextFilter->NextWindow) + break; + _vm.SetMemory(0, _vm.GetDataPointer(outBlockRef.Offset), outBlockRef.Size); + ExecuteFilter(++i, outBlockRef); + } + WriteDataToStream(_vm.GetDataPointer(outBlockRef.Offset), outBlockRef.Size); + _writtenFileSize += outBlockRef.Size; + writtenBorder = blockEnd; + writeSize = (_winPos - writtenBorder) & kWindowMask; + } + else + { + for (int j = i; j < _tempFilters.Size(); j++) + { + CTempFilter *filter = _tempFilters[j]; + if (filter != NULL && filter->NextWindow) + filter->NextWindow = false; + } + _wrPtr = writtenBorder; + return S_OK; // check it + } + } + } + + _wrPtr = _winPos; + return WriteArea(writtenBorder, _winPos); +} + +void CDecoder::InitFilters() +{ + _lastFilter = 0; + int i; + for (i = 0; i < _tempFilters.Size(); i++) + delete _tempFilters[i]; + _tempFilters.Clear(); + for (i = 0; i < _filters.Size(); i++) + delete _filters[i]; + _filters.Clear(); +} + +bool CDecoder::AddVmCode(UInt32 firstByte, UInt32 codeSize) +{ + CMemBitDecoder inp; + inp.Init(_vmData, codeSize); + + UInt32 filterIndex; + if (firstByte & 0x80) + { + filterIndex = NVm::ReadEncodedUInt32(inp); + if (filterIndex == 0) + InitFilters(); + else + filterIndex--; + } + else + filterIndex = _lastFilter; + if (filterIndex > (UInt32)_filters.Size()) + return false; + _lastFilter = filterIndex; + bool newFilter = (filterIndex == (UInt32)_filters.Size()); + + CFilter *filter; + if (newFilter) + { + // check if too many filters + if (filterIndex > 1024) + return false; + filter = new CFilter; + _filters.Add(filter); + } + else + { + filter = _filters[filterIndex]; + filter->ExecCount++; + } + + int numEmptyItems = 0; + int i; + for (i = 0; i < _tempFilters.Size(); i++) + { + _tempFilters[i - numEmptyItems] = _tempFilters[i]; + if (_tempFilters[i] == NULL) + numEmptyItems++; + if (numEmptyItems > 0) + _tempFilters[i] = NULL; + } + if (numEmptyItems == 0) + { + _tempFilters.Add(NULL); + numEmptyItems = 1; + } + CTempFilter *tempFilter = new CTempFilter; + _tempFilters[_tempFilters.Size() - numEmptyItems] = tempFilter; + tempFilter->FilterIndex = filterIndex; + tempFilter->ExecCount = filter->ExecCount; + + UInt32 blockStart = NVm::ReadEncodedUInt32(inp); + if (firstByte & 0x40) + blockStart += 258; + tempFilter->BlockStart = (blockStart + _winPos) & kWindowMask; + if (firstByte & 0x20) + filter->BlockSize = NVm::ReadEncodedUInt32(inp); + tempFilter->BlockSize = filter->BlockSize; + tempFilter->NextWindow = _wrPtr != _winPos && ((_wrPtr - _winPos) & kWindowMask) <= blockStart; + + memset(tempFilter->InitR, 0, sizeof(tempFilter->InitR)); + tempFilter->InitR[3] = NVm::kGlobalOffset; + tempFilter->InitR[4] = tempFilter->BlockSize; + tempFilter->InitR[5] = tempFilter->ExecCount; + if (firstByte & 0x10) + { + UInt32 initMask = inp.ReadBits(NVm::kNumGpRegs); + for (int i = 0; i < NVm::kNumGpRegs; i++) + if (initMask & (1 << i)) + tempFilter->InitR[i] = NVm::ReadEncodedUInt32(inp); + } + if (newFilter) + { + UInt32 vmCodeSize = NVm::ReadEncodedUInt32(inp); + if (vmCodeSize >= kVmCodeSizeMax || vmCodeSize == 0) + return false; + for (UInt32 i = 0; i < vmCodeSize; i++) + _vmCode[i] = (Byte)inp.ReadBits(8); + _vm.PrepareProgram(_vmCode, vmCodeSize, filter); + } + + tempFilter->AllocateEmptyFixedGlobal(); + + Byte *globalData = &tempFilter->GlobalData[0]; + for (i = 0; i < NVm::kNumGpRegs; i++) + NVm::SetValue32(&globalData[i * 4], tempFilter->InitR[i]); + NVm::SetValue32(&globalData[NVm::NGlobalOffset::kBlockSize], tempFilter->BlockSize); + NVm::SetValue32(&globalData[NVm::NGlobalOffset::kBlockPos], 0); // It was commented. why? + NVm::SetValue32(&globalData[NVm::NGlobalOffset::kExecCount], tempFilter->ExecCount); + + if (firstByte & 8) + { + UInt32 dataSize = NVm::ReadEncodedUInt32(inp); + if (dataSize > NVm::kGlobalSize - NVm::kFixedGlobalSize) + return false; + CRecordVector &globalData = tempFilter->GlobalData; + int requredSize = (int)(dataSize + NVm::kFixedGlobalSize); + if (globalData.Size() < requredSize) + { + globalData.Reserve(requredSize); + for (; globalData.Size() < requredSize; i++) + globalData.Add(0); + } + for (UInt32 i = 0; i < dataSize; i++) + globalData[NVm::kFixedGlobalSize + i] = (Byte)inp.ReadBits(8); + } + return true; +} + +bool CDecoder::ReadVmCodeLZ() +{ + UInt32 firstByte = m_InBitStream.ReadBits(8); + UInt32 length = (firstByte & 7) + 1; + if (length == 7) + length = m_InBitStream.ReadBits(8) + 7; + else if (length == 8) + length = m_InBitStream.ReadBits(16); + if (length > kVmDataSizeMax) + return false; + for (UInt32 i = 0; i < length; i++) + _vmData[i] = (Byte)m_InBitStream.ReadBits(8); + return AddVmCode(firstByte, length); +} + +bool CDecoder::ReadVmCodePPM() +{ + int firstByte = DecodePpmSymbol(); + if (firstByte == -1) + return false; + UInt32 length = (firstByte & 7) + 1; + if (length == 7) + { + int b1 = DecodePpmSymbol(); + if (b1 == -1) + return false; + length = b1 + 7; + } + else if (length == 8) + { + int b1 = DecodePpmSymbol(); + if (b1 == -1) + return false; + int b2 = DecodePpmSymbol(); + if (b2 == -1) + return false; + length = b1 * 256 + b2; + } + if (length > kVmDataSizeMax) + return false; + for (UInt32 i = 0; i < length; i++) + { + int b = DecodePpmSymbol(); + if (b == -1) + return false; + _vmData[i] = (Byte)b; + } + return AddVmCode(firstByte, length); +} + +#define RIF(x) { if (!(x)) return S_FALSE; } + +UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); } + +///////////////////////////////////////////////// +// PPM + +HRESULT CDecoder::InitPPM() +{ + Byte maxOrder = (Byte)ReadBits(7); + + bool reset = ((maxOrder & 0x20) != 0); + int maxMB = 0; + if (reset) + maxMB = (Byte)ReadBits(8); + else + { + if (_ppm.SubAllocator.GetSubAllocatorSize()== 0) + return S_FALSE; + } + if (maxOrder & 0x40) + PpmEscChar = (Byte)ReadBits(8); + m_InBitStream.InitRangeCoder(); + /* + if (m_InBitStream.m_BitPos != 0) + return S_FALSE; + */ + if (reset) + { + maxOrder = (maxOrder & 0x1F) + 1; + if (maxOrder > 16) + maxOrder = 16 + (maxOrder - 16) * 3; + if (maxOrder == 1) + { + // SubAlloc.StopSubAllocator(); + _ppm.SubAllocator.StopSubAllocator(); + return S_FALSE; + } + // SubAlloc.StartSubAllocator(MaxMB+1); + // StartModelRare(maxOrder); + + if (!_ppm.SubAllocator.StartSubAllocator((maxMB + 1) << 20)) + return E_OUTOFMEMORY; + _ppm.MaxOrder = 0; + _ppm.StartModelRare(maxOrder); + + } + // return (minContext != NULL); + + return S_OK; +} + +int CDecoder::DecodePpmSymbol() { return _ppm.DecodeSymbol(&m_InBitStream); } + +HRESULT CDecoder::DecodePPM(Int32 num, bool &keepDecompressing) +{ + keepDecompressing = false; + do + { + if (((_wrPtr - _winPos) & kWindowMask) < 260 && _wrPtr != _winPos) + { + RINOK(WriteBuf()); + if (_writtenFileSize > _unpackSize) + return S_OK; + } + int c = DecodePpmSymbol(); + if (c == -1) + { + // Original code sets PPMError=true here and then it returns S_OK. Why ??? + // return S_OK; + return S_FALSE; + } + if (c == PpmEscChar) + { + int nextCh = DecodePpmSymbol(); + if (nextCh == 0) + return ReadTables(keepDecompressing); + if (nextCh == 2 || nextCh == -1) + return S_OK; + if (nextCh == 3) + { + if (!ReadVmCodePPM()) + return S_FALSE; + continue; + } + if (nextCh == 4 || nextCh == 5) + { + UInt32 distance = 0; + UInt32 length = 4; + if (nextCh == 4) + { + for (int i = 0; i < 3; i++) + { + int c = DecodePpmSymbol(); + if (c == -1) + return S_OK; + distance = (distance << 8) + (Byte)c; + } + distance++; + length += 28; + } + int c = DecodePpmSymbol(); + if (c == -1) + return S_OK; + length += c; + if (distance >= _lzSize) + return S_FALSE; + CopyBlock(distance, length); + num -= (Int32)length; + continue; + } + } + PutByte((Byte)c); + num--; + } + while (num >= 0); + keepDecompressing = true; + return S_OK; +} + +///////////////////////////////////////////////// +// LZ + +HRESULT CDecoder::ReadTables(bool &keepDecompressing) +{ + keepDecompressing = true; + ReadBits((8 - m_InBitStream.GetBitPosition()) & 7); + if (ReadBits(1) != 0) + { + _lzMode = false; + return InitPPM(); + } + + _lzMode = true; + PrevAlignBits = 0; + PrevAlignCount = 0; + + Byte levelLevels[kLevelTableSize]; + Byte newLevels[kTablesSizesSum]; + + if (ReadBits(1) == 0) + memset(m_LastLevels, 0, kTablesSizesSum); + + int i; + for (i = 0; i < kLevelTableSize; i++) + { + UInt32 length = ReadBits(4); + if (length == 15) + { + UInt32 zeroCount = ReadBits(4); + if (zeroCount != 0) + { + zeroCount += 2; + while (zeroCount-- > 0 && i < kLevelTableSize) + levelLevels[i++]=0; + i--; + continue; + } + } + levelLevels[i] = (Byte)length; + } + RIF(m_LevelDecoder.SetCodeLengths(levelLevels)); + i = 0; + while (i < kTablesSizesSum) + { + UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); + if (number < 16) + { + newLevels[i] = Byte((number + m_LastLevels[i]) & 15); + i++; + } + else if (number > kLevelTableSize) + return S_FALSE; + else + { + int num; + if (((number - 16) & 1) == 0) + num = ReadBits(3) + 3; + else + num = ReadBits(7) + 11; + if (number < 18) + { + if (i == 0) + return S_FALSE; + for (; num > 0 && i < kTablesSizesSum; num--, i++) + newLevels[i] = newLevels[i - 1]; + } + else + { + for (; num > 0 && i < kTablesSizesSum; num--) + newLevels[i++] = 0; + } + } + } + TablesRead = true; + + // original code has check here: + /* + if (InAddr > ReadTop) + { + keepDecompressing = false; + return true; + } + */ + + RIF(m_MainDecoder.SetCodeLengths(&newLevels[0])); + RIF(m_DistDecoder.SetCodeLengths(&newLevels[kMainTableSize])); + RIF(m_AlignDecoder.SetCodeLengths(&newLevels[kMainTableSize + kDistTableSize])); + RIF(m_LenDecoder.SetCodeLengths(&newLevels[kMainTableSize + kDistTableSize + kAlignTableSize])); + + memcpy(m_LastLevels, newLevels, kTablesSizesSum); + return S_OK; +} + +class CCoderReleaser +{ + CDecoder *m_Coder; +public: + CCoderReleaser(CDecoder *coder): m_Coder(coder) {} + ~CCoderReleaser() + { + // m_Coder->m_OutWindowStream.Flush(); + m_Coder->ReleaseStreams(); + } +}; + +HRESULT CDecoder::ReadEndOfBlock(bool &keepDecompressing) +{ + if (ReadBits(1) != 0) + { + // old file + TablesRead = false; + return ReadTables(keepDecompressing); + } + // new file + keepDecompressing = false; + TablesRead = (ReadBits(1) == 0); + return S_OK; +} + +UInt32 kDistStart[kDistTableSize]; + +class CDistInit +{ +public: + CDistInit() { Init(); } + void Init() + { + UInt32 start = 0; + for (UInt32 i = 0; i < kDistTableSize; i++) + { + kDistStart[i] = start; + start += (1 << kDistDirectBits[i]); + } + } +} g_DistInit; + +HRESULT CDecoder::DecodeLZ(bool &keepDecompressing) +{ + UInt32 rep0 = _reps[0]; + UInt32 rep1 = _reps[1]; + UInt32 rep2 = _reps[2]; + UInt32 rep3 = _reps[3]; + UInt32 length = _lastLength; + for (;;) + { + if (((_wrPtr - _winPos) & kWindowMask) < 260 && _wrPtr != _winPos) + { + RINOK(WriteBuf()); + if (_writtenFileSize > _unpackSize) + return S_OK; + } + UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); + if (number < 256) + { + PutByte(Byte(number)); + + continue; + } + else if (number == kSymbolReadTable) + { + RINOK(ReadEndOfBlock(keepDecompressing)); + break; + } + else if (number == 257) + { + if (!ReadVmCodeLZ()) + return S_FALSE; + continue; + } + else if (number == 258) + { + } + else if (number < kSymbolRep + 4) + { + if (number != kSymbolRep) + { + UInt32 distance; + if (number == kSymbolRep + 1) + distance = rep1; + else + { + if (number == kSymbolRep + 2) + distance = rep2; + else + { + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + + UInt32 number = m_LenDecoder.DecodeSymbol(&m_InBitStream); + if (number >= kLenTableSize) + return S_FALSE; + length = 2 + kLenStart[number] + m_InBitStream.ReadBits(kLenDirectBits[number]); + } + else + { + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + if (number < 271) + { + number -= 263; + rep0 = kLen2DistStarts[number] + m_InBitStream.ReadBits(kLen2DistDirectBits[number]); + length = 2; + } + else if (number < 299) + { + number -= 271; + length = kNormalMatchMinLen + (UInt32)kLenStart[number] + m_InBitStream.ReadBits(kLenDirectBits[number]); + UInt32 number = m_DistDecoder.DecodeSymbol(&m_InBitStream); + if (number >= kDistTableSize) + return S_FALSE; + rep0 = kDistStart[number]; + int numBits = kDistDirectBits[number]; + if (number >= (kNumAlignBits * 2) + 2) + { + if (numBits > kNumAlignBits) + rep0 += (m_InBitStream.ReadBits(numBits - kNumAlignBits) << kNumAlignBits); + if (PrevAlignCount > 0) + { + PrevAlignCount--; + rep0 += PrevAlignBits; + } + else + { + UInt32 number = m_AlignDecoder.DecodeSymbol(&m_InBitStream); + if (number < (1 << kNumAlignBits)) + { + rep0 += number; + PrevAlignBits = number; + } + else if (number == (1 << kNumAlignBits)) + { + PrevAlignCount = kNumAlignReps; + rep0 += PrevAlignBits; + } + else + return S_FALSE; + } + } + else + rep0 += m_InBitStream.ReadBits(numBits); + length += ((kDistLimit4 - rep0) >> 31) + ((kDistLimit3 - rep0) >> 31); + } + else + return S_FALSE; + } + if (rep0 >= _lzSize) + return S_FALSE; + CopyBlock(rep0, length); + } + _reps[0] = rep0; + _reps[1] = rep1; + _reps[2] = rep2; + _reps[3] = rep3; + _lastLength = length; + + return S_OK; +} + +HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) +{ + _writtenFileSize = 0; + if (!m_IsSolid) + { + _lzSize = 0; + _winPos = 0; + _wrPtr = 0; + for (int i = 0; i < kNumReps; i++) + _reps[i] = 0; + _lastLength = 0; + memset(m_LastLevels, 0, kTablesSizesSum); + TablesRead = false; + PpmEscChar = 2; + InitFilters(); + } + if (!m_IsSolid || !TablesRead) + { + bool keepDecompressing; + RINOK(ReadTables(keepDecompressing)); + if (!keepDecompressing) + return S_OK; + } + + for(;;) + { + bool keepDecompressing; + if (_lzMode) + { + RINOK(DecodeLZ(keepDecompressing)) + } + else + { + RINOK(DecodePPM(1 << 18, keepDecompressing)) + } + UInt64 packSize = m_InBitStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize)); + if (!keepDecompressing) + break; + } + RINOK(WriteBuf()); + if (_writtenFileSize < _unpackSize) + return S_FALSE; + // return m_OutWindowStream.Flush(); + return S_OK; +} + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try + { + if (inSize == NULL || outSize == NULL) + return E_INVALIDARG; + + if (_vmData == 0) + { + _vmData = (Byte *)::MidAlloc(kVmDataSizeMax + kVmCodeSizeMax); + if (_vmData == 0) + return E_OUTOFMEMORY; + _vmCode = _vmData + kVmDataSizeMax; + } + + if (_window == 0) + { + _window = (Byte *)::MidAlloc(kWindowSize); + if (_window == 0) + return E_OUTOFMEMORY; + } + if (!m_InBitStream.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!_vm.Create()) + return E_OUTOFMEMORY; + + + m_InBitStream.SetStream(inStream); + m_InBitStream.Init(); + _outStream = outStream; + + CCoderReleaser coderReleaser(this); + _unpackSize = *outSize; + return CodeReal(progress); + } + catch(...) { return S_FALSE; } + // CNewException is possible here. But probably CNewException is caused + // by error in data stream. +} + +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) +{ + if (size < 1) + return E_INVALIDARG; + m_IsSolid = (data[0] != 0); + return S_OK; +} + +}} diff --git a/CPP/7zip/Compress/Rar/Rar3Decoder.h b/CPP/7zip/Compress/Rar/Rar3Decoder.h new file mode 100755 index 00000000..ec07a4d3 --- /dev/null +++ b/CPP/7zip/Compress/Rar/Rar3Decoder.h @@ -0,0 +1,294 @@ +// Rar3Decoder.h +// According to unRAR license, +// this code may not be used to develop a +// RAR (WinRAR) compatible archiver + +#ifndef __RAR3DECODER_H +#define __RAR3DECODER_H + +#include "../../../Common/MyCom.h" + +#include "../../ICoder.h" +#include "../../Common/MSBFDecoder.h" +#include "../../Common/InBuffer.h" + +// #include "../LZ/LZOutWindow.h" +#include "../Huffman/HuffmanDecoder.h" +#include "../PPMD/PPMDDecode.h" +#include "Rar3Vm.h" + +namespace NCompress { +namespace NRar3 { + +const UInt32 kWindowSize = 1 << 22; +const UInt32 kWindowMask = (kWindowSize - 1); + +const UInt32 kNumReps = 4; +const UInt32 kNumLen2Symbols = 8; +const UInt32 kLenTableSize = 28; +const UInt32 kMainTableSize = 256 + 1 + 1 + 1 + kNumReps + kNumLen2Symbols + kLenTableSize; +const UInt32 kDistTableSize = 60; + +const int kNumAlignBits = 4; +const UInt32 kAlignTableSize = (1 << kNumAlignBits) + 1; + +const UInt32 kLevelTableSize = 20; + +const UInt32 kTablesSizesSum = kMainTableSize + kDistTableSize + kAlignTableSize + kLenTableSize; + +template +class CBitDecoder2 +{ + UInt32 m_Value; +public: + UInt32 m_BitPos; + TInByte m_Stream; + bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } + void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream);} + void ReleaseStream() { m_Stream.ReleaseStream();} + + void Init() + { + m_Stream.Init(); + m_BitPos = 0; + m_Value = 0; + // m_BitPos = kNumBigValueBits; + // Normalize(); + } + + UInt64 GetProcessedSize() const + { return m_Stream.GetProcessedSize() - (m_BitPos) / 8; } + UInt32 GetBitPosition() const { return ((8 - m_BitPos) & 7); } + + /* + void Normalize() + { + for (;m_BitPos >= 8; m_BitPos -= 8) + m_Value = (m_Value << 8) | m_Stream.ReadByte(); + } + */ + + UInt32 GetValue(UInt32 numBits) + { + // return (m_Value << m_BitPos) >> (kNumBigValueBits - numBits); + // return ((m_Value >> (8 - m_BitPos)) & kMask) >> (kNumValueBits - numBits); + if (m_BitPos < numBits) + { + m_BitPos += 8; + m_Value = (m_Value << 8) | m_Stream.ReadByte(); + if (m_BitPos < numBits) + { + m_BitPos += 8; + m_Value = (m_Value << 8) | m_Stream.ReadByte(); + } + } + return m_Value >> (m_BitPos - numBits); + } + + void MovePos(UInt32 numBits) + { + m_BitPos -= numBits; + m_Value = m_Value & ((1 << m_BitPos) - 1); + } + + UInt32 ReadBits(UInt32 numBits) + { + UInt32 res = GetValue(numBits); + MovePos(numBits); + return res; + } +}; + +typedef CBitDecoder2 CBitDecoder; + +const int kNumTopBits = 24; +const UInt32 kTopValue = (1 << kNumTopBits); +const UInt32 kBot = (1 << 15); + +class CRangeDecoder:public NPPMD::CRangeDecoderVirt, public CBitDecoder +{ +public: + UInt32 Range; + UInt32 Low; + UInt32 Code; + + void Normalize() + { + while ((Low ^ (Low + Range)) < kTopValue || + Range < kBot && ((Range = (0 - Low) & (kBot - 1)), 1)) + { + Code = (Code << 8) | m_Stream.ReadByte(); + Range <<= 8; + Low <<= 8; + } + } + + void InitRangeCoder() + { + Code = 0; + Low = 0; + Range = 0xFFFFFFFF; + for(int i = 0; i < 4; i++) + Code = (Code << 8) | ReadBits(8); + } + + virtual UInt32 GetThreshold(UInt32 total) + { + return (Code - Low) / ( Range /= total); + } + + virtual void Decode(UInt32 start, UInt32 size) + { + Low += start * Range; + Range *= size; + Normalize(); + } + + virtual UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) + { + if (((Code - Low) / (Range >>= numTotalBits)) < size0) + { + Decode(0, size0); + return 0; + } + else + { + Decode(size0, (1 << numTotalBits) - size0); + return 1; + } + } + + // UInt64 GetProcessedSizeRangeCoder() {return Stream.GetProcessedSize(); } +}; + + +struct CFilter: public NVm::CProgram +{ + CRecordVector GlobalData; + UInt32 BlockStart; + UInt32 BlockSize; + UInt32 ExecCount; + CFilter(): BlockStart(0), BlockSize(0), ExecCount(0) {} +}; + +struct CTempFilter: public NVm::CProgramInitState +{ + UInt32 BlockStart; + UInt32 BlockSize; + UInt32 ExecCount; + bool NextWindow; + + UInt32 FilterIndex; +}; + +const int kNumHuffmanBits = 15; + +class CDecoder: + public ICompressCoder, + public ICompressSetDecoderProperties2, + public CMyUnknownImp +{ + CRangeDecoder m_InBitStream; + Byte *_window; + UInt32 _winPos; + UInt32 _wrPtr; + UInt64 _lzSize; + UInt64 _unpackSize; + UInt64 _writtenFileSize; // if it's > _unpackSize, then _unpackSize only written + CMyComPtr _outStream; + NHuffman::CDecoder m_MainDecoder; + NHuffman::CDecoder m_DistDecoder; + NHuffman::CDecoder m_AlignDecoder; + NHuffman::CDecoder m_LenDecoder; + NHuffman::CDecoder m_LevelDecoder; + + UInt32 _reps[kNumReps]; + UInt32 _lastLength; + + Byte m_LastLevels[kTablesSizesSum]; + + Byte *_vmData; + Byte *_vmCode; + NVm::CVm _vm; + CRecordVector _filters; + CRecordVector _tempFilters; + UInt32 _lastFilter; + + bool m_IsSolid; + + bool _lzMode; + + UInt32 PrevAlignBits; + UInt32 PrevAlignCount; + + bool TablesRead; + + NPPMD::CDecodeInfo _ppm; + int PpmEscChar; + + HRESULT WriteDataToStream(const Byte *data, UInt32 size); + HRESULT WriteData(const Byte *data, UInt32 size); + HRESULT WriteArea(UInt32 startPtr, UInt32 endPtr); + void ExecuteFilter(int tempFilterIndex, NVm::CBlockRef &outBlockRef); + HRESULT WriteBuf(); + + void InitFilters(); + bool AddVmCode(UInt32 firstByte, UInt32 codeSize); + bool ReadVmCodeLZ(); + bool ReadVmCodePPM(); + + UInt32 ReadBits(int numBits); + + HRESULT InitPPM(); + int DecodePpmSymbol(); + HRESULT DecodePPM(Int32 num, bool &keepDecompressing); + + HRESULT ReadTables(bool &keepDecompressing); + HRESULT ReadEndOfBlock(bool &keepDecompressing); + HRESULT DecodeLZ(bool &keepDecompressing); + HRESULT CodeReal(ICompressProgressInfo *progress); +public: + CDecoder(); + ~CDecoder(); + + MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) + + void ReleaseStreams() + { + _outStream.Release(); + m_InBitStream.ReleaseStream(); + } + + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + + void CopyBlock(UInt32 distance, UInt32 len) + { + _lzSize += len; + UInt32 pos = (_winPos - distance - 1) & kWindowMask; + do + { + _window[_winPos] = _window[pos]; + _winPos = (_winPos + 1) & kWindowMask; + pos = (pos + 1) & kWindowMask; + } + while(--len != 0); + } + + void PutByte(Byte b) + { + _window[_winPos] = b; + _winPos = (_winPos + 1) & kWindowMask; + _lzSize++; + } + + +}; + +}} + +#endif diff --git a/CPP/7zip/Compress/Rar/Rar3Vm.cpp b/CPP/7zip/Compress/Rar/Rar3Vm.cpp new file mode 100755 index 00000000..69918d94 --- /dev/null +++ b/CPP/7zip/Compress/Rar/Rar3Vm.cpp @@ -0,0 +1,1089 @@ +// Rar3Vm.cpp +// According to unRAR license, +// this code may not be used to develop a +// RAR (WinRAR) compatible archiver + +/* +Note: + Due to performance considerations Rar VM may set Flags C incorrectly + for some operands (SHL x, 0, ... ). + Check implementation of concrete VM command + to see if it sets flags right. +*/ + +#include "StdAfx.h" + +#include "Rar3Vm.h" +#include "Common/CRC.h" +#include "Common/Alloc.h" + +namespace NCompress { +namespace NRar3 { + +UInt32 CMemBitDecoder::ReadBits(int numBits) +{ + UInt32 res = 0; + for (;;) + { + Byte b = _bitPos < _bitSize ? _data[_bitPos >> 3] : 0; + int avail = (int)(8 - (_bitPos & 7)); + if (numBits <= avail) + { + _bitPos += numBits; + return res | (b >> (avail - numBits)) & ((1 << numBits) - 1); + } + numBits -= avail; + res |= (UInt32)(b & ((1 << avail) - 1)) << numBits; + _bitPos += avail; + } +} + +UInt32 CMemBitDecoder::ReadBit() { return ReadBits(1); } + +namespace NVm { + +const UInt32 kStackRegIndex = kNumRegs - 1; + +enum EFlags {FLAG_C = 1, FLAG_Z = 2, FLAG_S = 0x80000000}; + +const Byte CF_OP0 = 0; +const Byte CF_OP1 = 1; +const Byte CF_OP2 = 2; +const Byte CF_OPMASK = 3; +const Byte CF_BYTEMODE = 4; +const Byte CF_JUMP = 8; +const Byte CF_PROC = 16; +const Byte CF_USEFLAGS = 32; +const Byte CF_CHFLAGS = 64; + +static Byte kCmdFlags[]= +{ + /* CMD_MOV */ CF_OP2 | CF_BYTEMODE, + /* CMD_CMP */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_ADD */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_SUB */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_JZ */ CF_OP1 | CF_JUMP | CF_USEFLAGS, + /* CMD_JNZ */ CF_OP1 | CF_JUMP | CF_USEFLAGS, + /* CMD_INC */ CF_OP1 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_DEC */ CF_OP1 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_JMP */ CF_OP1 | CF_JUMP, + /* CMD_XOR */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_AND */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_OR */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_TEST */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_JS */ CF_OP1 | CF_JUMP | CF_USEFLAGS, + /* CMD_JNS */ CF_OP1 | CF_JUMP | CF_USEFLAGS, + /* CMD_JB */ CF_OP1 | CF_JUMP | CF_USEFLAGS, + /* CMD_JBE */ CF_OP1 | CF_JUMP | CF_USEFLAGS, + /* CMD_JA */ CF_OP1 | CF_JUMP | CF_USEFLAGS, + /* CMD_JAE */ CF_OP1 | CF_JUMP | CF_USEFLAGS, + /* CMD_PUSH */ CF_OP1, + /* CMD_POP */ CF_OP1, + /* CMD_CALL */ CF_OP1 | CF_PROC, + /* CMD_RET */ CF_OP0 | CF_PROC, + /* CMD_NOT */ CF_OP1 | CF_BYTEMODE, + /* CMD_SHL */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_SHR */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_SAR */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_NEG */ CF_OP1 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_PUSHA */ CF_OP0, + /* CMD_POPA */ CF_OP0, + /* CMD_PUSHF */ CF_OP0 | CF_USEFLAGS, + /* CMD_POPF */ CF_OP0 | CF_CHFLAGS, + /* CMD_MOVZX */ CF_OP2, + /* CMD_MOVSX */ CF_OP2, + /* CMD_XCHG */ CF_OP2 | CF_BYTEMODE, + /* CMD_MUL */ CF_OP2 | CF_BYTEMODE, + /* CMD_DIV */ CF_OP2 | CF_BYTEMODE, + /* CMD_ADC */ CF_OP2 | CF_BYTEMODE | CF_USEFLAGS | CF_CHFLAGS , + /* CMD_SBB */ CF_OP2 | CF_BYTEMODE | CF_USEFLAGS | CF_CHFLAGS , + /* CMD_PRINT */ CF_OP0 +}; + +CVm::CVm(): Mem(NULL) {} + +bool CVm::Create() +{ + if (Mem == NULL) + Mem = (Byte *)::MyAlloc(kSpaceSize + 4); + return (Mem != NULL); +} + +CVm::~CVm() +{ + ::MyFree(Mem); +} + +// CVm::Execute can change CProgram object: it clears progarm if VM returns error. + +bool CVm::Execute(CProgram *prg, const CProgramInitState *initState, + CBlockRef &outBlockRef, CRecordVector &outGlobalData) +{ + memcpy(R, initState->InitR, sizeof(initState->InitR)); + R[kStackRegIndex] = kSpaceSize; + R[kNumRegs] = 0; + Flags = 0; + + UInt32 globalSize = MyMin((UInt32)initState->GlobalData.Size(), kGlobalSize); + if (globalSize != 0) + memcpy(Mem + kGlobalOffset, &initState->GlobalData[0], globalSize); + UInt32 staticSize = MyMin((UInt32)prg->StaticData.Size(), kGlobalSize - globalSize); + if (staticSize != 0) + memcpy(Mem + kGlobalOffset + globalSize, &prg->StaticData[0], staticSize); + + bool res = true; + #ifdef RARVM_STANDARD_FILTERS + if (prg->StandardFilterIndex >= 0) + ExecuteStandardFilter(prg->StandardFilterIndex); + else + #endif + { + res = ExecuteCode(prg); + if (!res) + prg->Commands[0].OpCode = CMD_RET; + } + UInt32 newBlockPos = GetFixedGlobalValue32(NGlobalOffset::kBlockPos) & kSpaceMask; + UInt32 newBlockSize = GetFixedGlobalValue32(NGlobalOffset::kBlockSize) & kSpaceMask; + if (newBlockPos + newBlockSize >= kSpaceSize) + newBlockPos = newBlockSize = 0; + outBlockRef.Offset = newBlockPos; + outBlockRef.Size = newBlockSize; + + outGlobalData.Clear(); + UInt32 dataSize = GetFixedGlobalValue32(NGlobalOffset::kGlobalMemOutSize); + dataSize = MyMin(dataSize, kGlobalSize - kFixedGlobalSize); + if (dataSize != 0) + { + dataSize += kFixedGlobalSize; + outGlobalData.Reserve(dataSize); + for (UInt32 i = 0; i < dataSize; i++) + outGlobalData.Add(Mem[kGlobalOffset + i]); + } + return res; +} + + +#define SET_IP(IP) \ + if ((IP) >= numCommands) return true; \ + if (--maxOpCount <= 0) return false; \ + cmd = commands + (IP); + +#define GET_FLAG_S_B(res) (((res) & 0x80) ? FLAG_S : 0) +#define SET_IP_OP1 { UInt32 val = GetOperand32(&cmd->Op1); SET_IP(val); } +#define FLAGS_UPDATE_SZ Flags = res == 0 ? FLAG_Z : res & FLAG_S +#define FLAGS_UPDATE_SZ_B Flags = (res & 0xFF) == 0 ? FLAG_Z : GET_FLAG_S_B(res) + +UInt32 CVm::GetOperand32(const COperand *op) const +{ + switch(op->Type) + { + case OP_TYPE_REG: return R[op->Data]; + case OP_TYPE_REGMEM: return GetValue32(&Mem[(op->Base + R[op->Data]) & kSpaceMask]); + default: return op->Data; + } +} + +void CVm::SetOperand32(const COperand *op, UInt32 val) +{ + switch(op->Type) + { + case OP_TYPE_REG: R[op->Data] = val; return; + case OP_TYPE_REGMEM: SetValue32(&Mem[(op->Base + R[op->Data]) & kSpaceMask], val); return; + } +} + +Byte CVm::GetOperand8(const COperand *op) const +{ + switch(op->Type) + { + case OP_TYPE_REG: return (Byte)R[op->Data]; + case OP_TYPE_REGMEM: return Mem[(op->Base + R[op->Data]) & kSpaceMask];; + default: return (Byte)op->Data; + } +} + +void CVm::SetOperand8(const COperand *op, Byte val) +{ + switch(op->Type) + { + case OP_TYPE_REG: R[op->Data] = (R[op->Data] & 0xFFFFFF00) | val; return; + case OP_TYPE_REGMEM: Mem[(op->Base + R[op->Data]) & kSpaceMask] = val; return; + } +} + +UInt32 CVm::GetOperand(bool byteMode, const COperand *op) const +{ + if (byteMode) + return GetOperand8(op); + return GetOperand32(op); +} + +void CVm::SetOperand(bool byteMode, const COperand *op, UInt32 val) +{ + if (byteMode) + SetOperand8(op, (Byte)(val & 0xFF)); + else + SetOperand32(op, val); +} + +bool CVm::ExecuteCode(const CProgram *prg) +{ + Int32 maxOpCount = 25000000; + const CCommand *commands = &prg->Commands[0]; + const CCommand *cmd = commands; + UInt32 numCommands = prg->Commands.Size(); + for (;;) + { + switch(cmd->OpCode) + { + #ifndef RARVM_NO_VM + + case CMD_MOV: + SetOperand32(&cmd->Op1, GetOperand32(&cmd->Op2)); + break; + case CMD_MOVB: + SetOperand8(&cmd->Op1, GetOperand8(&cmd->Op2)); + break; + case CMD_CMP: + { + UInt32 v1 = GetOperand32(&cmd->Op1); + UInt32 res = v1 - GetOperand32(&cmd->Op2); + Flags = res == 0 ? FLAG_Z : (res > v1) | (res & FLAG_S); + } + break; + case CMD_CMPB: + { + Byte v1 = GetOperand8(&cmd->Op1); + Byte res = v1 - GetOperand8(&cmd->Op2); + res &= 0xFF; + Flags = res == 0 ? FLAG_Z : (res > v1) | GET_FLAG_S_B(res); + } + break; + case CMD_ADD: + { + UInt32 v1 = GetOperand32(&cmd->Op1); + UInt32 res = v1 + GetOperand32(&cmd->Op2); + SetOperand32(&cmd->Op1, res); + Flags = (res < v1) | (res == 0 ? FLAG_Z : (res & FLAG_S)); + } + break; + case CMD_ADDB: + { + Byte v1 = GetOperand8(&cmd->Op1); + Byte res = v1 + GetOperand8(&cmd->Op2); + res &= 0xFF; + SetOperand8(&cmd->Op1, (Byte)res); + Flags = (res < v1) | (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)); + } + break; + case CMD_ADC: + { + UInt32 v1 = GetOperand(cmd->ByteMode, &cmd->Op1); + UInt32 FC = (Flags & FLAG_C); + UInt32 res = v1 + GetOperand(cmd->ByteMode, &cmd->Op2) + FC; + if (cmd->ByteMode) + res &= 0xFF; + SetOperand(cmd->ByteMode, &cmd->Op1, res); + Flags = (res < v1 || res == v1 && FC) | (res == 0 ? FLAG_Z : (res & FLAG_S)); + } + break; + case CMD_SUB: + { + UInt32 v1 = GetOperand32(&cmd->Op1); + UInt32 res = v1 - GetOperand32(&cmd->Op2); + SetOperand32(&cmd->Op1, res); + Flags = res == 0 ? FLAG_Z : (res > v1) | (res & FLAG_S); + } + break; + case CMD_SUBB: + { + UInt32 v1 = GetOperand8(&cmd->Op1); + UInt32 res = v1 - GetOperand8(&cmd->Op2); + SetOperand8(&cmd->Op1, (Byte)res); + Flags = res == 0 ? FLAG_Z : (res > v1) | (res & FLAG_S); + } + break; + case CMD_SBB: + { + UInt32 v1 = GetOperand(cmd->ByteMode, &cmd->Op1); + UInt32 FC = (Flags & FLAG_C); + UInt32 res = v1 - GetOperand(cmd->ByteMode, &cmd->Op2) - FC; + // Flags = res == 0 ? FLAG_Z : (res > v1 || res == v1 && FC) | (res & FLAG_S); + if (cmd->ByteMode) + res &= 0xFF; + SetOperand(cmd->ByteMode, &cmd->Op1, res); + Flags = (res > v1 || res == v1 && FC) | (res == 0 ? FLAG_Z : (res & FLAG_S)); + } + break; + case CMD_INC: + { + UInt32 res = GetOperand32(&cmd->Op1) + 1; + SetOperand32(&cmd->Op1, res); + FLAGS_UPDATE_SZ; + } + break; + case CMD_INCB: + { + Byte res = GetOperand8(&cmd->Op1) + 1; + SetOperand8(&cmd->Op1, res);; + FLAGS_UPDATE_SZ_B; + } + break; + case CMD_DEC: + { + UInt32 res = GetOperand32(&cmd->Op1) - 1; + SetOperand32(&cmd->Op1, res); + FLAGS_UPDATE_SZ; + } + break; + case CMD_DECB: + { + Byte res = GetOperand8(&cmd->Op1) - 1; + SetOperand8(&cmd->Op1, res);; + FLAGS_UPDATE_SZ_B; + } + break; + case CMD_XOR: + { + UInt32 res = GetOperand32(&cmd->Op1) ^ GetOperand32(&cmd->Op2); + SetOperand32(&cmd->Op1, res); + FLAGS_UPDATE_SZ; + } + break; + case CMD_XORB: + { + Byte res = GetOperand8(&cmd->Op1) ^ GetOperand8(&cmd->Op2); + SetOperand8(&cmd->Op1, res); + FLAGS_UPDATE_SZ_B; + } + break; + case CMD_AND: + { + UInt32 res = GetOperand32(&cmd->Op1) & GetOperand32(&cmd->Op2); + SetOperand32(&cmd->Op1, res); + FLAGS_UPDATE_SZ; + } + break; + case CMD_ANDB: + { + Byte res = GetOperand8(&cmd->Op1) & GetOperand8(&cmd->Op2); + SetOperand8(&cmd->Op1, res); + FLAGS_UPDATE_SZ_B; + } + break; + case CMD_OR: + { + UInt32 res = GetOperand32(&cmd->Op1) | GetOperand32(&cmd->Op2); + SetOperand32(&cmd->Op1, res); + FLAGS_UPDATE_SZ; + } + break; + case CMD_ORB: + { + Byte res = GetOperand8(&cmd->Op1) | GetOperand8(&cmd->Op2); + SetOperand8(&cmd->Op1, res); + FLAGS_UPDATE_SZ_B; + } + break; + case CMD_TEST: + { + UInt32 res = GetOperand32(&cmd->Op1) & GetOperand32(&cmd->Op2); + FLAGS_UPDATE_SZ; + } + break; + case CMD_TESTB: + { + Byte res = GetOperand8(&cmd->Op1) & GetOperand8(&cmd->Op2); + FLAGS_UPDATE_SZ_B; + } + break; + case CMD_NOT: + SetOperand(cmd->ByteMode, &cmd->Op1, ~GetOperand(cmd->ByteMode, &cmd->Op1)); + break; + case CMD_NEG: + { + UInt32 res = 0 - GetOperand32(&cmd->Op1); + SetOperand32(&cmd->Op1, res); + Flags = res == 0 ? FLAG_Z : FLAG_C | (res & FLAG_S); + } + break; + case CMD_NEGB: + { + Byte res = (Byte)(0 - GetOperand8(&cmd->Op1)); + SetOperand8(&cmd->Op1, res); + Flags = res == 0 ? FLAG_Z : FLAG_C | GET_FLAG_S_B(res); + } + break; + + case CMD_SHL: + { + UInt32 v1 = GetOperand32(&cmd->Op1); + int v2 = (int)GetOperand32(&cmd->Op2); + UInt32 res = v1 << v2; + SetOperand32(&cmd->Op1, res); + Flags = (res == 0 ? FLAG_Z : (res & FLAG_S)) | ((v1 << (v2 - 1)) & 0x80000000 ? FLAG_C : 0); + } + break; + case CMD_SHLB: + { + Byte v1 = GetOperand8(&cmd->Op1); + int v2 = (int)GetOperand8(&cmd->Op2); + Byte res = (Byte)(v1 << v2); + SetOperand8(&cmd->Op1, res); + Flags = (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)) | ((v1 << (v2 - 1)) & 0x80 ? FLAG_C : 0); + } + break; + case CMD_SHR: + { + UInt32 v1 = GetOperand32(&cmd->Op1); + int v2 = (int)GetOperand32(&cmd->Op2); + UInt32 res = v1 >> v2; + SetOperand32(&cmd->Op1, res); + Flags = (res == 0 ? FLAG_Z : (res & FLAG_S)) | ((v1 >> (v2 - 1)) & FLAG_C); + } + break; + case CMD_SHRB: + { + Byte v1 = GetOperand8(&cmd->Op1); + int v2 = (int)GetOperand8(&cmd->Op2); + Byte res = (Byte)(v1 >> v2); + SetOperand8(&cmd->Op1, res); + Flags = (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)) | ((v1 >> (v2 - 1)) & FLAG_C); + } + break; + case CMD_SAR: + { + UInt32 v1 = GetOperand32(&cmd->Op1); + int v2 = (int)GetOperand32(&cmd->Op2); + UInt32 res = UInt32(((Int32)v1) >> v2); + SetOperand32(&cmd->Op1, res); + Flags= (res == 0 ? FLAG_Z : (res & FLAG_S)) | ((v1 >> (v2 - 1)) & FLAG_C); + } + break; + case CMD_SARB: + { + Byte v1 = GetOperand8(&cmd->Op1); + int v2 = (int)GetOperand8(&cmd->Op2); + Byte res = (Byte)(((signed char)v1) >> v2); + SetOperand8(&cmd->Op1, res); + Flags= (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)) | ((v1 >> (v2 - 1)) & FLAG_C); + } + break; + + case CMD_JMP: + SET_IP_OP1; + continue; + case CMD_JZ: + if ((Flags & FLAG_Z) != 0) + { + SET_IP_OP1; + continue; + } + break; + case CMD_JNZ: + if ((Flags & FLAG_Z) == 0) + { + SET_IP_OP1; + continue; + } + break; + case CMD_JS: + if ((Flags & FLAG_S) != 0) + { + SET_IP_OP1; + continue; + } + break; + case CMD_JNS: + if ((Flags & FLAG_S) == 0) + { + SET_IP_OP1; + continue; + } + break; + case CMD_JB: + if ((Flags & FLAG_C) != 0) + { + SET_IP_OP1; + continue; + } + break; + case CMD_JBE: + if ((Flags & (FLAG_C | FLAG_Z)) != 0) + { + SET_IP_OP1; + continue; + } + break; + case CMD_JA: + if ((Flags & (FLAG_C | FLAG_Z)) == 0) + { + SET_IP_OP1; + continue; + } + break; + case CMD_JAE: + if ((Flags & FLAG_C) == 0) + { + SET_IP_OP1; + continue; + } + break; + + case CMD_PUSH: + R[kStackRegIndex] -= 4; + SetValue32(&Mem[R[kStackRegIndex] & kSpaceMask], GetOperand32(&cmd->Op1)); + break; + case CMD_POP: + SetOperand32(&cmd->Op1, GetValue32(&Mem[R[kStackRegIndex] & kSpaceMask])); + R[kStackRegIndex] += 4; + break; + case CMD_CALL: + R[kStackRegIndex] -= 4; + SetValue32(&Mem[R[kStackRegIndex] & kSpaceMask], (UInt32)(cmd - commands + 1)); + SET_IP_OP1; + continue; + + case CMD_PUSHA: + { + for (UInt32 i = 0, SP = R[kStackRegIndex] - 4; i < kNumRegs; i++, SP -= 4) + SetValue32(&Mem[SP & kSpaceMask], R[i]); + R[kStackRegIndex] -= kNumRegs * 4; + } + break; + case CMD_POPA: + { + for (UInt32 i = 0, SP = R[kStackRegIndex]; i < kNumRegs; i++, SP += 4) + R[kStackRegIndex - i] = GetValue32(&Mem[SP & kSpaceMask]); + } + break; + case CMD_PUSHF: + R[kStackRegIndex] -= 4; + SetValue32(&Mem[R[kStackRegIndex]&kSpaceMask], Flags); + break; + case CMD_POPF: + Flags = GetValue32(&Mem[R[kStackRegIndex] & kSpaceMask]); + R[kStackRegIndex] += 4; + break; + + case CMD_MOVZX: + SetOperand32(&cmd->Op1, GetOperand8(&cmd->Op2)); + break; + case CMD_MOVSX: + SetOperand32(&cmd->Op1, (UInt32)(Int32)(signed char)GetOperand8(&cmd->Op2)); + break; + case CMD_XCHG: + { + UInt32 v1 = GetOperand(cmd->ByteMode, &cmd->Op1); + SetOperand(cmd->ByteMode, &cmd->Op1, GetOperand(cmd->ByteMode, &cmd->Op2)); + SetOperand(cmd->ByteMode, &cmd->Op2, v1); + } + break; + case CMD_MUL: + { + UInt32 res = GetOperand32(&cmd->Op1) * GetOperand32(&cmd->Op2); + SetOperand32(&cmd->Op1, res); + } + break; + case CMD_MULB: + { + Byte res = GetOperand8(&cmd->Op1) * GetOperand8(&cmd->Op2); + SetOperand8(&cmd->Op1, res); + } + break; + case CMD_DIV: + { + UInt32 divider = GetOperand(cmd->ByteMode, &cmd->Op2); + if (divider != 0) + { + UInt32 res = GetOperand(cmd->ByteMode, &cmd->Op1) / divider; + SetOperand(cmd->ByteMode, &cmd->Op1, res); + } + } + break; + + #endif + + case CMD_RET: + { + if (R[kStackRegIndex] >= kSpaceSize) + return true; + UInt32 ip = GetValue32(&Mem[R[kStackRegIndex] & kSpaceMask]); + SET_IP(ip); + R[kStackRegIndex] += 4; + continue; + } + case CMD_PRINT: + break; + } + cmd++; + --maxOpCount; + } +} + + +////////////////////////////////////////////////////// +// Read program + +UInt32 ReadEncodedUInt32(CMemBitDecoder &inp) +{ + switch(inp.ReadBits(2)) + { + case 0: + return inp.ReadBits(4); + case 1: + { + UInt32 v = inp.ReadBits(4); + if (v == 0) + return 0xFFFFFF00 | inp.ReadBits(8); + else + return (v << 4) | inp.ReadBits(4); + } + case 2: + return inp.ReadBits(16); + default: + return inp.ReadBits(32); + } +} + +void CVm::DecodeArg(CMemBitDecoder &inp, COperand &op, bool byteMode) +{ + if (inp.ReadBit()) + { + op.Type = OP_TYPE_REG; + op.Data = inp.ReadBits(kNumRegBits); + } + else if (inp.ReadBit() == 0) + { + op.Type = OP_TYPE_INT; + if (byteMode) + op.Data = inp.ReadBits(8); + else + op.Data = ReadEncodedUInt32(inp); + } + else + { + op.Type = OP_TYPE_REGMEM; + if (inp.ReadBit() == 0) + { + op.Data = inp.ReadBits(kNumRegBits); + op.Base = 0; + } + else + { + if (inp.ReadBit() == 0) + op.Data = inp.ReadBits(kNumRegBits); + else + op.Data = kNumRegs; + op.Base = ReadEncodedUInt32(inp); + } + } +} + +void CVm::ReadVmProgram(const Byte *code, UInt32 codeSize, CProgram *prg) +{ + CMemBitDecoder inp; + inp.Init(code, codeSize); + + prg->StaticData.Clear(); + if (inp.ReadBit()) + { + UInt32 dataSize = ReadEncodedUInt32(inp) + 1; + for (UInt32 i = 0; inp.Avail() && i < dataSize; i++) + prg->StaticData.Add((Byte)inp.ReadBits(8)); + } + while (inp.Avail()) + { + prg->Commands.Add(CCommand()); + CCommand *cmd = &prg->Commands.Back(); + if (inp.ReadBit() == 0) + cmd->OpCode = (ECommand)inp.ReadBits(3); + else + cmd->OpCode = (ECommand)(8 + inp.ReadBits(5)); + if (kCmdFlags[cmd->OpCode] & CF_BYTEMODE) + cmd->ByteMode = (inp.ReadBit()) ? true : false; + else + cmd->ByteMode = 0; + int opNum = (kCmdFlags[cmd->OpCode] & CF_OPMASK); + if (opNum > 0) + { + DecodeArg(inp, cmd->Op1, cmd->ByteMode); + if (opNum == 2) + DecodeArg(inp, cmd->Op2, cmd->ByteMode); + else + { + if (cmd->Op1.Type == OP_TYPE_INT && (kCmdFlags[cmd->OpCode] & (CF_JUMP | CF_PROC))) + { + int Distance = cmd->Op1.Data; + if (Distance >= 256) + Distance -= 256; + else + { + if (Distance >= 136) + Distance -= 264; + else if (Distance >= 16) + Distance -= 8; + else if (Distance >= 8) + Distance -= 16; + Distance += prg->Commands.Size() - 1; + } + cmd->Op1.Data = Distance; + } + } + } + if (cmd->ByteMode) + { + switch (cmd->OpCode) + { + case CMD_MOV: cmd->OpCode = CMD_MOVB; break; + case CMD_CMP: cmd->OpCode = CMD_CMPB; break; + case CMD_ADD: cmd->OpCode = CMD_ADDB; break; + case CMD_SUB: cmd->OpCode = CMD_SUBB; break; + case CMD_INC: cmd->OpCode = CMD_INCB; break; + case CMD_DEC: cmd->OpCode = CMD_DECB; break; + case CMD_XOR: cmd->OpCode = CMD_XORB; break; + case CMD_AND: cmd->OpCode = CMD_ANDB; break; + case CMD_OR: cmd->OpCode = CMD_ORB; break; + case CMD_TEST: cmd->OpCode = CMD_TESTB; break; + case CMD_NEG: cmd->OpCode = CMD_NEGB; break; + case CMD_SHL: cmd->OpCode = CMD_SHLB; break; + case CMD_SHR: cmd->OpCode = CMD_SHRB; break; + case CMD_SAR: cmd->OpCode = CMD_SARB; break; + case CMD_MUL: cmd->OpCode = CMD_MULB; break; + } + } + } +} + +#ifdef RARVM_STANDARD_FILTERS + +enum EStandardFilter +{ + SF_E8, + SF_E8E9, + SF_ITANIUM, + SF_RGB, + SF_AUDIO, + SF_DELTA, + SF_UPCASE +}; + +struct StandardFilterSignature +{ + UInt32 Length; + UInt32 CRC; + EStandardFilter Type; +} +kStdFilters[]= +{ + 53, 0xad576887, SF_E8, + 57, 0x3cd7e57e, SF_E8E9, + 120, 0x3769893f, SF_ITANIUM, + 29, 0x0e06077d, SF_DELTA, + 149, 0x1c2c5dc8, SF_RGB, + 216, 0xbc85e701, SF_AUDIO, + 40, 0x46b9c560, SF_UPCASE +}; + +static int FindStandardFilter(const Byte *code, UInt32 codeSize) +{ + UInt32 crc = CCRC::CalculateDigest(code, codeSize); + for (int i = 0; i < sizeof(kStdFilters) / sizeof(kStdFilters[0]); i++) + { + StandardFilterSignature &sfs = kStdFilters[i]; + if (sfs.CRC == crc && sfs.Length == codeSize) + return i; + } + return -1; +} + +#endif + +void CVm::PrepareProgram(const Byte *code, UInt32 codeSize, CProgram *prg) +{ + Byte xorSum = 0; + for (UInt32 i = 1; i < codeSize; i++) + xorSum ^= code[i]; + + prg->Commands.Clear(); + #ifdef RARVM_STANDARD_FILTERS + prg->StandardFilterIndex = -1; + #endif + + if (xorSum == code[0] && codeSize > 0) + { + #ifdef RARVM_STANDARD_FILTERS + prg->StandardFilterIndex = FindStandardFilter(code, codeSize); + if (prg->StandardFilterIndex >= 0) + return; + #endif + // 1 byte for checksum + ReadVmProgram(code + 1, codeSize - 1, prg); + } + prg->Commands.Add(CCommand()); + CCommand *cmd = &prg->Commands.Back(); + cmd->OpCode = CMD_RET; +} + +void CVm::SetMemory(UInt32 pos, const Byte *data, UInt32 dataSize) +{ + if (pos < kSpaceSize && data != Mem + pos) + memmove(Mem + pos, data, MyMin(dataSize, kSpaceSize - pos)); +} + +#ifdef RARVM_STANDARD_FILTERS + +static void E8E9Decode(Byte *data, UInt32 dataSize, UInt32 fileOffset, bool e9) +{ + if (dataSize <= 4) + return; + dataSize -= 4; + const UInt32 kFileSize = 0x1000000; + Byte cmpByte2 = (e9 ? 0xE9 : 0xE8); + for (UInt32 curPos = 0; curPos < dataSize;) + { + Byte curByte = *(data++); + curPos++; + if (curByte == 0xE8 || curByte == cmpByte2) + { + UInt32 offset = curPos + fileOffset; + UInt32 addr = (Int32)GetValue32(data); + if (addr < kFileSize) + SetValue32(data, addr - offset); + else if ((Int32)addr < 0 && (Int32)(addr + offset) >= 0) + SetValue32(data, addr + kFileSize); + data += 4; + curPos += 4; + } + } +} + +static inline UInt32 ItaniumGetOpType(const Byte *data, int bitPos) +{ + return (data[(unsigned int)bitPos >> 3] >> (bitPos & 7)) & 0xF; +} + + +static void ItaniumDecode(Byte *data, UInt32 dataSize, UInt32 fileOffset) +{ + UInt32 curPos = 0; + fileOffset >>= 4; + while (curPos < dataSize - 21) + { + int b = (data[0] & 0x1F) - 0x10; + if (b >= 0) + { + static Byte kCmdMasks[16] = {4,4,6,6,0,0,7,7,4,4,0,0,4,4,0,0}; + Byte cmdMask = kCmdMasks[b]; + if (cmdMask != 0) + for (int i = 0; i < 3; i++) + if (cmdMask & (1 << i)) + { + int startPos = i * 41 + 18; + if (ItaniumGetOpType(data, startPos + 24) == 5) + { + const UInt32 kMask = 0xFFFFF; + Byte *p = data + ((unsigned int)startPos >> 3); + UInt32 bitField = ((UInt32)p[0]) | ((UInt32)p[1] << 8) | ((UInt32)p[2] << 16); + int inBit = (startPos & 7); + UInt32 offset = (bitField >> inBit) & kMask; + UInt32 andMask = ~(kMask << inBit); + bitField = ((offset - fileOffset) & kMask) << inBit; + for (int j = 0; j < 3; j++) + { + p[j] &= andMask; + p[j] |= bitField; + andMask >>= 8; + bitField >>= 8; + } + } + } + } + data += 16; + curPos += 16; + fileOffset++; + } +} + +static void DeltaDecode(Byte *data, UInt32 dataSize, UInt32 numChannels) +{ + UInt32 srcPos = 0; + UInt32 border = dataSize * 2; + for (UInt32 curChannel = 0; curChannel < numChannels; curChannel++) + { + Byte prevByte = 0; + for (UInt32 destPos = dataSize + curChannel; destPos < border; destPos += numChannels) + data[destPos] = (prevByte = prevByte - data[srcPos++]); + } +} + +static void RgbDecode(Byte *srcData, UInt32 dataSize, UInt32 width, UInt32 posR) +{ + Byte *destData = srcData + dataSize; + const UInt32 numChannels = 3; + for (UInt32 curChannel = 0; curChannel < numChannels; curChannel++) + { + Byte prevByte = 0; + + for (UInt32 i = curChannel; i < dataSize; i+= numChannels) + { + unsigned int predicted; + if (i < width) + predicted = prevByte; + else + { + unsigned int upperLeftByte = destData[i - width]; + unsigned int upperByte = destData[i - width + 3]; + predicted = prevByte + upperByte - upperLeftByte; + int pa = abs((int)(predicted - prevByte)); + int pb = abs((int)(predicted - upperByte)); + int pc = abs((int)(predicted - upperLeftByte)); + if (pa <= pb && pa <= pc) + predicted = prevByte; + else + if (pb <= pc) + predicted = upperByte; + else + predicted = upperLeftByte; + } + destData[i] = prevByte = (Byte)(predicted - *(srcData++)); + } + } + if (dataSize < 3) + return; + for (UInt32 i = posR, border = dataSize - 2; i < border; i += 3) + { + Byte g = destData[i + 1]; + destData[i] = destData[i] + g; + destData[i + 2] = destData[i + 2] + g; + } +} + +static void AudioDecode(Byte *srcData, UInt32 dataSize, UInt32 numChannels) +{ + Byte *destData = srcData + dataSize; + for (UInt32 curChannel = 0; curChannel < numChannels; curChannel++) + { + UInt32 prevByte = 0, prevDelta = 0, dif[7]; + Int32 D1 = 0, D2 = 0, D3; + Int32 K1 = 0, K2 = 0, K3 = 0; + memset(dif, 0, sizeof(dif)); + + for (UInt32 i = curChannel, byteCount = 0; i < dataSize; i += numChannels, byteCount++) + { + D3 = D2; + D2 = prevDelta - D1; + D1 = prevDelta; + + UInt32 predicted = 8 * prevByte + K1 * D1 + K2 * D2 + K3 * D3; + predicted = (predicted >> 3) & 0xFF; + + UInt32 curByte = *(srcData++); + + predicted -= curByte; + destData[i] = (Byte)predicted; + prevDelta = (UInt32)(Int32)(signed char)(predicted - prevByte); + prevByte = predicted; + + Int32 D = ((Int32)(signed char)curByte) << 3; + + dif[0] += abs(D); + dif[1] += abs(D - D1); + dif[2] += abs(D + D1); + dif[3] += abs(D - D2); + dif[4] += abs(D + D2); + dif[5] += abs(D - D3); + dif[6] += abs(D + D3); + + if ((byteCount & 0x1F) == 0) + { + UInt32 minDif = dif[0], numMinDif = 0; + dif[0] = 0; + for (int j = 1; j < sizeof(dif) / sizeof(dif[0]); j++) + { + if (dif[j] < minDif) + { + minDif = dif[j]; + numMinDif = j; + } + dif[j] = 0; + } + switch (numMinDif) + { + case 1: if (K1 >= -16) K1--; break; + case 2: if (K1 < 16) K1++; break; + case 3: if (K2 >= -16) K2--; break; + case 4: if (K2 < 16) K2++; break; + case 5: if (K3 >= -16) K3--; break; + case 6: if (K3 < 16) K3++; break; + } + } + } + } +} + +static UInt32 UpCaseDecode(Byte *data, UInt32 dataSize) +{ + UInt32 srcPos = 0, destPos = dataSize; + while (srcPos < dataSize) + { + Byte curByte = data[srcPos++]; + if (curByte == 2 && (curByte = data[srcPos++]) != 2) + curByte -= 32; + data[destPos++] = curByte; + } + return destPos - dataSize; +} + +void CVm::ExecuteStandardFilter(int filterIndex) +{ + UInt32 dataSize = R[4]; + if (dataSize >= kGlobalOffset) + return; + EStandardFilter filterType = kStdFilters[filterIndex].Type; + + switch (filterType) + { + case SF_E8: + case SF_E8E9: + E8E9Decode(Mem, dataSize, R[6], (filterType == SF_E8E9)); + break; + case SF_ITANIUM: + ItaniumDecode(Mem, dataSize, R[6]); + break; + case SF_DELTA: + if (dataSize >= kGlobalOffset / 2) + break; + SetBlockPos(dataSize); + DeltaDecode(Mem, dataSize, R[0]); + break; + case SF_RGB: + if (dataSize >= kGlobalOffset / 2) + break; + { + UInt32 width = R[0]; + if (width <= 3) + break; + SetBlockPos(dataSize); + RgbDecode(Mem, dataSize, width, R[1]); + } + break; + case SF_AUDIO: + if (dataSize >= kGlobalOffset / 2) + break; + SetBlockPos(dataSize); + AudioDecode(Mem, dataSize, R[0]); + break; + case SF_UPCASE: + if (dataSize >= kGlobalOffset / 2) + break; + UInt32 destSize = UpCaseDecode(Mem, dataSize); + SetBlockSize(destSize); + SetBlockPos(dataSize); + break; + } +} + +#endif + +}}} diff --git a/CPP/7zip/Compress/Rar/Rar3Vm.h b/CPP/7zip/Compress/Rar/Rar3Vm.h new file mode 100755 index 00000000..d0a4f82c --- /dev/null +++ b/CPP/7zip/Compress/Rar/Rar3Vm.h @@ -0,0 +1,219 @@ +// Rar3Vm.h +// According to unRAR license, +// this code may not be used to develop a +// RAR (WinRAR) compatible archiver + +#ifndef __RAR3VM_H +#define __RAR3VM_H + +#include "Common/Types.h" +#include "Common/Vector.h" + +#define RARVM_STANDARD_FILTERS +#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__) // || defined(_M_IA64) || defined(__ia64__) +// Define RARVM_LITTLE_ENDIAN_UNALIGN, if CPU is LITTLE_ENDIAN and if it supports +// unaligned 32-bit memory accesses. +// It's for speed optimization, if you are not sure, just don't define it. +#define RARVM_LITTLE_ENDIAN_UNALIGN +#endif + +namespace NCompress { +namespace NRar3 { + +class CMemBitDecoder +{ + const Byte *_data; + UInt32 _bitSize; + UInt32 _bitPos; +public: + void Init(const Byte *data, UInt32 byteSize) + { + _data = data; + _bitSize = (byteSize << 3); + _bitPos = 0; + } + UInt32 ReadBits(int numBits); + UInt32 ReadBit(); + bool Avail() const { return (_bitPos < _bitSize); } +}; + +namespace NVm { + +inline UInt32 GetValue32(const void *addr) +{ + #ifdef RARVM_LITTLE_ENDIAN_UNALIGN + return *(const UInt32 *)addr; + #else + const Byte *b = (const Byte *)addr; + return UInt32((UInt32)b[0]|((UInt32)b[1]<<8)|((UInt32)b[2]<<16)|((UInt32)b[3]<<24)); + #endif +} + +inline void SetValue32(void *addr, UInt32 value) +{ + #ifdef RARVM_LITTLE_ENDIAN_UNALIGN + *(UInt32 *)addr = value; + #else + ((Byte *)addr)[0] = (Byte)value; + ((Byte *)addr)[1] = (Byte)(value >> 8); + ((Byte *)addr)[2] = (Byte)(value >> 16); + ((Byte *)addr)[3] = (Byte)(value >> 24); + #endif +} + +UInt32 ReadEncodedUInt32(CMemBitDecoder &inp); + +const int kNumRegBits = 3; +const UInt32 kNumRegs = 1 << kNumRegBits; +const UInt32 kNumGpRegs = kNumRegs - 1; + +const UInt32 kSpaceSize = 0x40000; +const UInt32 kSpaceMask = kSpaceSize -1; +const UInt32 kGlobalOffset = 0x3C000; +const UInt32 kGlobalSize = 0x2000; +const UInt32 kFixedGlobalSize = 64; + +namespace NGlobalOffset +{ + const UInt32 kBlockSize = 0x1C; + const UInt32 kBlockPos = 0x20; + const UInt32 kExecCount = 0x2C; + const UInt32 kGlobalMemOutSize = 0x30; +}; + +enum ECommand +{ + CMD_MOV, CMD_CMP, CMD_ADD, CMD_SUB, CMD_JZ, CMD_JNZ, CMD_INC, CMD_DEC, + CMD_JMP, CMD_XOR, CMD_AND, CMD_OR, CMD_TEST, CMD_JS, CMD_JNS, CMD_JB, + CMD_JBE, CMD_JA, CMD_JAE, CMD_PUSH, CMD_POP, CMD_CALL, CMD_RET, CMD_NOT, + CMD_SHL, CMD_SHR, CMD_SAR, CMD_NEG, CMD_PUSHA,CMD_POPA, CMD_PUSHF,CMD_POPF, + CMD_MOVZX,CMD_MOVSX,CMD_XCHG, CMD_MUL, CMD_DIV, CMD_ADC, CMD_SBB, CMD_PRINT, + + CMD_MOVB, CMD_CMPB, CMD_ADDB, CMD_SUBB, CMD_INCB, CMD_DECB, + CMD_XORB, CMD_ANDB, CMD_ORB, CMD_TESTB,CMD_NEGB, + CMD_SHLB, CMD_SHRB, CMD_SARB, CMD_MULB +}; + +enum EOpType {OP_TYPE_REG, OP_TYPE_INT, OP_TYPE_REGMEM, OP_TYPE_NONE}; + +// Addr in COperand object can link (point) to CVm object!!! + +struct COperand +{ + EOpType Type; + UInt32 Data; + UInt32 Base; + COperand(): Type(OP_TYPE_NONE), Data(0), Base(0) {} +}; + +struct CCommand +{ + ECommand OpCode; + bool ByteMode; + COperand Op1, Op2; +}; + +struct CBlockRef +{ + UInt32 Offset; + UInt32 Size; +}; + +struct CProgram +{ + CRecordVector Commands; + #ifdef RARVM_STANDARD_FILTERS + int StandardFilterIndex; + #endif + CRecordVector StaticData; +}; + +struct CProgramInitState +{ + UInt32 InitR[kNumGpRegs]; + CRecordVector GlobalData; + + void AllocateEmptyFixedGlobal() + { + GlobalData.Clear(); + GlobalData.Reserve(NVm::kFixedGlobalSize); + for (UInt32 i = 0; i < NVm::kFixedGlobalSize; i++) + GlobalData.Add(0); + } +}; + +class CVm +{ + static UInt32 GetValue(bool byteMode, const void *addr) + { + if (byteMode) + return(*(const Byte *)addr); + else + { + #ifdef RARVM_LITTLE_ENDIAN_UNALIGN + return *(const UInt32 *)addr; + #else + const Byte *b = (const Byte *)addr; + return UInt32((UInt32)b[0]|((UInt32)b[1]<<8)|((UInt32)b[2]<<16)|((UInt32)b[3]<<24)); + #endif + } + } + + static void SetValue(bool byteMode, void *addr, UInt32 value) + { + if (byteMode) + *(Byte *)addr = (Byte)value; + else + { + #ifdef RARVM_LITTLE_ENDIAN_UNALIGN + *(UInt32 *)addr = value; + #else + ((Byte *)addr)[0] = (Byte)value; + ((Byte *)addr)[1] = (Byte)(value >> 8); + ((Byte *)addr)[2] = (Byte)(value >> 16); + ((Byte *)addr)[3] = (Byte)(value >> 24); + #endif + } + } + + UInt32 GetFixedGlobalValue32(UInt32 globalOffset) { return GetValue(false, &Mem[kGlobalOffset + globalOffset]); } + + void SetBlockSize(UInt32 v) { SetValue(&Mem[kGlobalOffset + NGlobalOffset::kBlockSize], v); } + void SetBlockPos(UInt32 v) { SetValue(&Mem[kGlobalOffset + NGlobalOffset::kBlockPos], v); } +public: + static void SetValue(void *addr, UInt32 value) { SetValue(false, addr, value); } +private: + UInt32 GetOperand32(const COperand *op) const; + void SetOperand32(const COperand *op, UInt32 val); + Byte GetOperand8(const COperand *op) const; + void SetOperand8(const COperand *op, Byte val); + UInt32 GetOperand(bool byteMode, const COperand *op) const; + void SetOperand(bool byteMode, const COperand *op, UInt32 val); + + void DecodeArg(CMemBitDecoder &inp, COperand &op, bool byteMode); + + bool ExecuteCode(const CProgram *prg); + + #ifdef RARVM_STANDARD_FILTERS + void ExecuteStandardFilter(int filterIndex); + #endif + + Byte *Mem; + UInt32 R[kNumRegs + 1]; // R[kNumRegs] = 0 always (speed optimization) + UInt32 Flags; + void ReadVmProgram(const Byte *code, UInt32 codeSize, CProgram *prg); +public: + CVm(); + ~CVm(); + bool Create(); + void PrepareProgram(const Byte *code, UInt32 codeSize, CProgram *prg); + void SetMemory(UInt32 pos, const Byte *data, UInt32 dataSize); + bool Execute(CProgram *prg, const CProgramInitState *initState, + CBlockRef &outBlockRef, CRecordVector &outGlobalData); + const Byte *GetDataPointer(UInt32 offset) const { return Mem + offset; } + +}; + +#endif + +}}} diff --git a/CPP/7zip/Compress/Rar/StdAfx.cpp b/CPP/7zip/Compress/Rar/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Compress/Rar/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Compress/Rar/StdAfx.h b/CPP/7zip/Compress/Rar/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Compress/Rar/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Compress/Rar/makefile b/CPP/7zip/Compress/Rar/makefile new file mode 100755 index 00000000..4d8d5304 --- /dev/null +++ b/CPP/7zip/Compress/Rar/makefile @@ -0,0 +1,49 @@ +PROG = Rar29.dll +DEF_FILE = ../Codec.def +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib + +RAR29_OBJS = \ + $O\DllExports.obj \ + +RAR29_OPT_OBJS = \ + $O\Rar1Decoder.obj \ + $O\Rar2Decoder.obj \ + $O\Rar3Decoder.obj \ + $O\Rar3Vm.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CRC.obj \ + $O\Vector.obj \ + +7ZIP_COMMON_OBJS = \ + $O\InBuffer.obj \ + $O\OutBuffer.obj \ + $O\StreamUtils.obj \ + +LZ_OBJS = \ + $O\LZOutWindow.obj \ + + +OBJS = \ + $O\StdAfx.obj \ + $(RAR29_OBJS) \ + $(RAR29_OPT_OBJS) \ + $(COMMON_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(LZ_OBJS) \ + $O\resource.res + +!include "../../../Build.mak" + +$(RAR29_OBJS): $(*B).cpp + $(COMPL) +$(RAR29_OPT_OBJS): $(*B).cpp + $(COMPL_O2) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(LZ_OBJS): ../LZ/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/Compress/Rar/resource.rc b/CPP/7zip/Compress/Rar/resource.rc new file mode 100755 index 00000000..bb5e2ec9 --- /dev/null +++ b/CPP/7zip/Compress/Rar/resource.rc @@ -0,0 +1,3 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("Rar29 Codec", "Rar29") diff --git a/CPP/7zip/Compress/Shrink/DllExports.cpp b/CPP/7zip/Compress/Shrink/DllExports.cpp new file mode 100755 index 00000000..61bd5e69 --- /dev/null +++ b/CPP/7zip/Compress/Shrink/DllExports.cpp @@ -0,0 +1,64 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "ShrinkDecoder.h" + +// {23170F69-40C1-278B-0401-010000000000} +DEFINE_GUID(CLSID_CCompressShrinkDecoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +{ + return TRUE; +} + +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + if (*clsid != CLSID_CCompressShrinkDecoder) + return CLASS_E_CLASSNOTAVAILABLE; + if (*iid != IID_ICompressCoder) + return E_NOINTERFACE; + CMyComPtr coder = (ICompressCoder *)new NCompress::NShrink::CDecoder; + *outObject = coder.Detach(); + COM_TRY_END + return S_OK; +} + +STDAPI GetNumberOfMethods(UINT32 *numMethods) +{ + *numMethods = 1; + return S_OK; +} + +STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +{ + if (index != 0) + return E_INVALIDARG; + ::VariantClear((tagVARIANT *)value); + switch(propID) + { + case NMethodPropID::kID: + { + const char id[] = { 0x04, 0x01, 0x01 }; + if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NMethodPropID::kName: + if ((value->bstrVal = ::SysAllocString(L"Shrink")) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kDecoder: + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CCompressShrinkDecoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + return S_OK; +} diff --git a/CPP/7zip/Compress/Shrink/ShrinkDecoder.cpp b/CPP/7zip/Compress/Shrink/ShrinkDecoder.cpp new file mode 100755 index 00000000..12d1b8d0 --- /dev/null +++ b/CPP/7zip/Compress/Shrink/ShrinkDecoder.cpp @@ -0,0 +1,149 @@ +// ShrinkDecoder.cpp + +#include "StdAfx.h" + +#include "ShrinkDecoder.h" + +#include "../../../Common/Alloc.h" +#include "../../Common/InBuffer.h" +#include "../../Common/OutBuffer.h" +#include "../../Common/LSBFDecoder.h" + +namespace NCompress { +namespace NShrink { + +static const UInt32 kBufferSize = (1 << 20); + +static const int kNumMinBits = 9; + +STDMETHODIMP CDecoder ::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 * /* outSize */, + ICompressProgressInfo *progress) +{ + NStream::NLSBF::CBaseDecoder inBuffer; + COutBuffer outBuffer; + + if (!inBuffer.Create(kBufferSize)) + return E_OUTOFMEMORY; + inBuffer.SetStream(inStream); + inBuffer.Init(); + + if (!outBuffer.Create(kBufferSize)) + return E_OUTOFMEMORY; + outBuffer.SetStream(outStream); + outBuffer.Init(); + + UInt64 prevPos = 0; + int numBits = kNumMinBits; + UInt32 head = 257; + + bool needPrev = false; + + _parents[256] = 0; // virus protection + _suffixes[256] = 0; + + int i; + for (i = 0; i < 257; i++) + _isFree[i] = false; + for (; i < kNumItems; i++) + _isFree[i] = true; + + UInt32 lastSymbol = 0; + for (;;) + { + outBuffer.Flush(); + UInt32 symbol = inBuffer.ReadBits(numBits); + if (inBuffer.ExtraBitsWereRead()) + break; + if (_isFree[symbol]) + return S_FALSE; + if (symbol == 256) + { + // fix it; + UInt32 symbol = inBuffer.ReadBits(numBits); + if (symbol == 1) + { + if (numBits < kNumMaxBits) + numBits++; + } + else if (symbol == 2) + { + /* + maybe need delete prev also ? + if (needPrev) + _isFree[head - 1] = true; + */ + for (i = 257; i < kNumItems; i++) + _isParent[i] = false; + for (i = 257; i < kNumItems; i++) + if (!_isFree[i]) + _isParent[_parents[i]] = true; + for (i = 257; i < kNumItems; i++) + if (!_isParent[i]) + _isFree[i] = true; + head = 257; + while(head < ((UInt32)1 << numBits) && !_isFree[head]) + head++; + if (head < ((UInt32)1 << numBits)) + { + needPrev = true; + _isFree[head] = false; + _parents[head] = (UInt16)lastSymbol; + head++; + } + } + else + return S_FALSE; + continue; + } + UInt32 cur = symbol; + i = 0; + while (cur >= 256) + { + _stack[i++] = _suffixes[cur]; + cur = _parents[cur]; + } + _stack[i++] = (Byte)cur; + if (needPrev) + { + _suffixes[head - 1] = (Byte)cur; + if (symbol == head - 1) + _stack[0] = (Byte)cur; + } + while (i > 0) + outBuffer.WriteByte((_stack[--i])); + while(head < ((UInt32)1 << numBits) && !_isFree[head]) + head++; + if (head < ((UInt32)1 << numBits)) + { + needPrev = true; + _isFree[head] = false; + _parents[head] = (UInt16)symbol; + head++; + } + else + needPrev = false; + lastSymbol = symbol; + + UInt64 nowPos = outBuffer.GetProcessedSize(); + if (progress != NULL && nowPos - prevPos > (1 << 18)) + { + prevPos = nowPos; + UInt64 packSize = inBuffer.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &nowPos)); + } + } + return outBuffer.Flush(); +} + +STDMETHODIMP CDecoder ::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const COutBufferException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +}} diff --git a/CPP/7zip/Compress/Shrink/ShrinkDecoder.h b/CPP/7zip/Compress/Shrink/ShrinkDecoder.h new file mode 100755 index 00000000..1c15ea8a --- /dev/null +++ b/CPP/7zip/Compress/Shrink/ShrinkDecoder.h @@ -0,0 +1,39 @@ +// ShrinkDecoder.h + +#ifndef __SHRINK_DECODER_H +#define __SHRINK_DECODER_H + +#include "../../../Common/MyCom.h" + +#include "../../ICoder.h" + +namespace NCompress { +namespace NShrink { + +const int kNumMaxBits = 13; +const UInt32 kNumItems = 1 << kNumMaxBits; + +class CDecoder : + public ICompressCoder, + public CMyUnknownImp +{ + UInt16 _parents[kNumItems]; + Byte _suffixes[kNumItems]; + Byte _stack[kNumItems]; + bool _isFree[kNumItems]; + bool _isParent[kNumItems]; +public: + MY_UNKNOWN_IMP + + STDMETHOD(CodeReal)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); +}; + +}} + +#endif diff --git a/CPP/7zip/Compress/Shrink/StdAfx.cpp b/CPP/7zip/Compress/Shrink/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Compress/Shrink/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Compress/Shrink/StdAfx.h b/CPP/7zip/Compress/Shrink/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Compress/Shrink/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Compress/Z/StdAfx.cpp b/CPP/7zip/Compress/Z/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Compress/Z/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Compress/Z/StdAfx.h b/CPP/7zip/Compress/Z/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Compress/Z/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Compress/Z/ZDecoder.cpp b/CPP/7zip/Compress/Z/ZDecoder.cpp new file mode 100755 index 00000000..2415efd8 --- /dev/null +++ b/CPP/7zip/Compress/Z/ZDecoder.cpp @@ -0,0 +1,172 @@ +// ZDecoder.cpp + +#include "StdAfx.h" + +#include "ZDecoder.h" + +#include "../../../Common/Alloc.h" +#include "../../Common/InBuffer.h" +#include "../../Common/OutBuffer.h" +#include "../../Common/LSBFDecoder.h" + +namespace NCompress { +namespace NZ { + +static const UInt32 kBufferSize = (1 << 20); +static const Byte kNumBitsMask = 0x1F; +static const Byte kBlockModeMask = 0x80; +static const int kNumMinBits = 9; +static const int kNumMaxBits = 16; + +void CDecoder::Free() +{ + MyFree(_parents); + _parents = 0; + MyFree(_suffixes); + _suffixes = 0; + MyFree(_stack); + _stack = 0; +} + +bool CDecoder::Alloc(size_t numItems) +{ + Free(); + _parents = (UInt16 *)MyAlloc(numItems * sizeof(UInt16)); + if (_parents == 0) + return false; + _suffixes = (Byte *)MyAlloc(numItems * sizeof(Byte)); + if (_suffixes == 0) + return false; + _stack = (Byte *)MyAlloc(numItems * sizeof(Byte)); + return _stack != 0; +} + +CDecoder::~CDecoder() +{ + Free(); +} + +STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 * /* outSize */, + ICompressProgressInfo *progress) +{ + NStream::NLSBF::CBaseDecoder inBuffer; + COutBuffer outBuffer; + + if (!inBuffer.Create(kBufferSize)) + return E_OUTOFMEMORY; + inBuffer.SetStream(inStream); + inBuffer.Init(); + + if (!outBuffer.Create(kBufferSize)) + return E_OUTOFMEMORY; + outBuffer.SetStream(outStream); + outBuffer.Init(); + + int maxbits = _properties & kNumBitsMask; + if (maxbits < kNumMinBits || maxbits > kNumMaxBits) + return S_FALSE; + UInt32 numItems = 1 << maxbits; + bool blockMode = ((_properties & kBlockModeMask) != 0); + if (!blockMode) + return E_NOTIMPL; + + if (maxbits != _numMaxBits || _parents == 0 || _suffixes == 0 || _stack == 0) + { + if (!Alloc(numItems)) + return E_OUTOFMEMORY; + _numMaxBits = maxbits; + } + + UInt64 prevPos = 0; + int numBits = kNumMinBits; + UInt32 head = blockMode ? 257 : 256; + + bool needPrev = false; + + int keepBits = 0; + + _parents[256] = 0; // virus protection + _suffixes[256] = 0; + + for (;;) + { + if (keepBits < numBits) + keepBits = numBits * 8; + UInt32 symbol = inBuffer.ReadBits(numBits); + if (inBuffer.ExtraBitsWereRead()) + break; + keepBits -= numBits; + if (symbol >= head) + return S_FALSE; + if (blockMode && symbol == 256) + { + for (;keepBits > 0; keepBits--) + inBuffer.ReadBits(1); + numBits = kNumMinBits; + head = 257; + needPrev = false; + continue; + } + UInt32 cur = symbol; + int i = 0; + while (cur >= 256) + { + _stack[i++] = _suffixes[cur]; + cur = _parents[cur]; + } + _stack[i++] = (Byte)cur; + if (needPrev) + { + _suffixes[head - 1] = (Byte)cur; + if (symbol == head - 1) + _stack[0] = (Byte)cur; + } + while (i > 0) + outBuffer.WriteByte((_stack[--i])); + if (head < numItems) + { + needPrev = true; + _parents[head++] = (UInt16)symbol; + if (head > ((UInt32)1 << numBits)) + { + if (numBits < maxbits) + { + numBits++; + keepBits = numBits * 8; + } + } + } + else + needPrev = false; + + UInt64 nowPos = outBuffer.GetProcessedSize(); + if (progress != NULL && nowPos - prevPos > (1 << 18)) + { + prevPos = nowPos; + UInt64 packSize = inBuffer.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &nowPos)); + } + } + return outBuffer.Flush(); +} + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const COutBufferException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) +{ + if (size < 1) + return E_INVALIDARG; + _properties = data[0]; + return S_OK; +} + +}} diff --git a/CPP/7zip/Compress/Z/ZDecoder.h b/CPP/7zip/Compress/Z/ZDecoder.h new file mode 100755 index 00000000..1640c7f4 --- /dev/null +++ b/CPP/7zip/Compress/Z/ZDecoder.h @@ -0,0 +1,44 @@ +// ZDecoder.h + +#ifndef __COMPRESS_ZDECODER_H +#define __COMPRESS_ZDECODER_H + +#include "../../../Common/MyCom.h" +#include "../../ICoder.h" + +namespace NCompress { +namespace NZ { + +class CDecoder : + public ICompressCoder, + public ICompressSetDecoderProperties2, + public CMyUnknownImp +{ + BYTE _properties; + int _numMaxBits; + UInt16 *_parents; + Byte *_suffixes; + Byte *_stack; + +public: + CDecoder(): _properties(0), _numMaxBits(0), _parents(0), _suffixes(0), _stack(0) {}; + ~CDecoder(); + void Free(); + bool Alloc(size_t numItems); + + MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) + + STDMETHOD(CodeReal)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); +}; + +}} + +#endif diff --git a/CPP/7zip/Compress/makefile b/CPP/7zip/Compress/makefile new file mode 100755 index 00000000..7c1387c8 --- /dev/null +++ b/CPP/7zip/Compress/makefile @@ -0,0 +1,14 @@ +DIRS = \ + Branch\~ \ + ByteSwap\~ \ + BZip2\~ \ + Copy\~ \ + Deflate\~ \ + LZMA\~ \ + PPMD\~ \ + Rar\~ \ + +all: $(DIRS) + +$(DIRS): +!include "../SubBuild.mak" diff --git a/CPP/7zip/Crypto/7zAES/7zAES.cpp b/CPP/7zip/Crypto/7zAES/7zAES.cpp new file mode 100755 index 00000000..843d9027 --- /dev/null +++ b/CPP/7zip/Crypto/7zAES/7zAES.cpp @@ -0,0 +1,305 @@ +// 7z_AES.cpp + +#include "StdAfx.h" + +#include "Windows/Defs.h" +#include "Windows/Synchronization.h" +#include "../../Common/StreamObjects.h" +#include "../../Common/StreamUtils.h" + +#include "7zAES.h" +// #include "../../Hash/Common/CryptoHashInterface.h" + +#ifdef CRYPTO_AES +#include "../AES/MyAES.h" +#endif + +#include "../Hash/Sha256.h" + +using namespace NWindows; + +#ifndef CRYPTO_AES +extern HINSTANCE g_hInstance; +#endif + +namespace NCrypto { +namespace NSevenZ { + +bool CKeyInfo::IsEqualTo(const CKeyInfo &a) const +{ + if (SaltSize != a.SaltSize || NumCyclesPower != a.NumCyclesPower) + return false; + for (UInt32 i = 0; i < SaltSize; i++) + if (Salt[i] != a.Salt[i]) + return false; + return (Password == a.Password); +} + +void CKeyInfo::CalculateDigest() +{ + if (NumCyclesPower == 0x3F) + { + UInt32 pos; + for (pos = 0; pos < SaltSize; pos++) + Key[pos] = Salt[pos]; + for (UInt32 i = 0; i < Password.GetCapacity() && pos < kKeySize; i++) + Key[pos++] = Password[i]; + for (; pos < kKeySize; pos++) + Key[pos] = 0; + } + else + { + NCrypto::NSha256::CContext sha; + const UInt64 numRounds = UInt64(1) << (NumCyclesPower); + Byte temp[8] = { 0,0,0,0,0,0,0,0 }; + for (UInt64 round = 0; round < numRounds; round++) + { + sha.Update(Salt, SaltSize); + sha.Update(Password, Password.GetCapacity()); + sha.Update(temp, 8); + for (int i = 0; i < 8; i++) + if (++(temp[i]) != 0) + break; + } + sha.Final(Key); + } +} + +bool CKeyInfoCache::Find(CKeyInfo &key) +{ + for (int i = 0; i < Keys.Size(); i++) + { + const CKeyInfo &cached = Keys[i]; + if (key.IsEqualTo(cached)) + { + for (int j = 0; j < kKeySize; j++) + key.Key[j] = cached.Key[j]; + if (i != 0) + { + Keys.Insert(0, cached); + Keys.Delete(i+1); + } + return true; + } + } + return false; +} + +void CKeyInfoCache::Add(CKeyInfo &key) +{ + if (Find(key)) + return; + if (Keys.Size() >= Size) + Keys.DeleteBack(); + Keys.Insert(0, key); +} + +static CKeyInfoCache g_GlobalKeyCache(32); +static NSynchronization::CCriticalSection g_GlobalKeyCacheCriticalSection; + +CBase::CBase(): + _cachedKeys(16) +{ + for (int i = 0; i < sizeof(_iv); i++) + _iv[i] = 0; +} + +void CBase::CalculateDigest() +{ + NSynchronization::CCriticalSectionLock lock(g_GlobalKeyCacheCriticalSection); + if (_cachedKeys.Find(_key)) + g_GlobalKeyCache.Add(_key); + else + { + if (!g_GlobalKeyCache.Find(_key)) + { + _key.CalculateDigest(); + g_GlobalKeyCache.Add(_key); + } + _cachedKeys.Add(_key); + } +} + + +/* +static void GetRandomData(Byte *data) +{ + // probably we don't need truly random. + // it's enough to prevent dictionary attack; + // but it gives some info about time when compressing + // was made. + UInt64 tempValue; + SYSTEMTIME systemTime; + FILETIME fileTime; + ::GetSystemTime(&systemTime); + ::SystemTimeToFileTime(&systemTime, &fileTime); + tempValue = *(const UInt64 *)&fileTime; + LARGE_INTEGER counter; + ::QueryPerformanceCounter(&counter); + tempValue += *(const UInt64 *)&counter; + tempValue += (UInt64)(GetTickCount()) << 32; + *(UInt64 *)data = tempValue; +} +*/ + +STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) +{ + _key.Init(); + for (UInt32 i = 0; i < sizeof(_iv); i++) + _iv[i] = 0; + + _key.SaltSize = 0; + + // _key.SaltSize = 8; + // GetRandomData(_key.Salt); + + int ivSize = 0; + + // _key.NumCyclesPower = 0x3F; + _key.NumCyclesPower = 18; + + Byte firstByte = (Byte)(_key.NumCyclesPower | + (((_key.SaltSize == 0) ? 0 : 1) << 7) | + (((ivSize == 0) ? 0 : 1) << 6)); + RINOK(outStream->Write(&firstByte, 1, NULL)); + if (_key.SaltSize == 0 && ivSize == 0) + return S_OK; + Byte saltSizeSpec = (Byte)((_key.SaltSize == 0) ? 0 : (_key.SaltSize - 1)); + Byte ivSizeSpec = (Byte)((ivSize == 0) ? 0 : (ivSize - 1)); + Byte secondByte = (Byte)(((saltSizeSpec) << 4) | ivSizeSpec); + RINOK(outStream->Write(&secondByte, 1, NULL)); + if (_key.SaltSize > 0) + { + RINOK(WriteStream(outStream, _key.Salt, _key.SaltSize, NULL)); + } + if (ivSize > 0) + { + RINOK(WriteStream(outStream, _iv, ivSize, NULL)); + } + return S_OK; +} + +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) +{ + _key.Init(); + UInt32 i; + for (i = 0; i < sizeof(_iv); i++) + _iv[i] = 0; + if (size == 0) + return S_OK; + UInt32 pos = 0; + Byte firstByte = data[pos++]; + + _key.NumCyclesPower = firstByte & 0x3F; + if ((firstByte & 0xC0) == 0) + return S_OK; + _key.SaltSize = (firstByte >> 7) & 1; + UInt32 ivSize = (firstByte >> 6) & 1; + + if (pos >= size) + return E_INVALIDARG; + Byte secondByte = data[pos++]; + + _key.SaltSize += (secondByte >> 4); + ivSize += (secondByte & 0x0F); + + if (pos + _key.SaltSize + ivSize > size) + return E_INVALIDARG; + for (i = 0; i < _key.SaltSize; i++) + _key.Salt[i] = data[pos++]; + for (i = 0; i < ivSize; i++) + _iv[i] = data[pos++]; + return S_OK; +} + +STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size) +{ + _key.Password.SetCapacity(size); + memcpy(_key.Password, data, size); + return S_OK; +} + +/* +static Byte *WideToRaw(const wchar_t *src, Byte *dest, int destSize=0x10000000) +{ + for (int i = 0; i < destSize; i++, src++) + { + dest[i * 2] = (Byte)*src; + dest[i * 2 + 1]= (Byte)(*src >> 8); + if (*src == 0) + break; + } + return(dest); +} +*/ + +#ifndef CRYPTO_AES +bool GetAESLibPath(TCHAR *path) +{ + TCHAR fullPath[MAX_PATH + 1]; + if (::GetModuleFileName(g_hInstance, fullPath, MAX_PATH) == 0) + return false; + LPTSTR fileNamePointer; + DWORD needLength = ::GetFullPathName(fullPath, MAX_PATH + 1, + path, &fileNamePointer); + if (needLength == 0 || needLength >= MAX_PATH) + return false; + lstrcpy(fileNamePointer, TEXT("AES.dll")); + return true; +} +#endif + +STDMETHODIMP CBaseCoder::Init() +{ + CalculateDigest(); + if (_aesFilter == 0) + { + RINOK(CreateFilter()); + } + CMyComPtr cp; + RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp)); + RINOK(cp->SetKey(_key.Key, sizeof(_key.Key))); + RINOK(cp->SetInitVector(_iv, sizeof(_iv))); + return S_OK; +} + +STDMETHODIMP_(UInt32) CBaseCoder::Filter(Byte *data, UInt32 size) +{ + return _aesFilter->Filter(data, size); +} + +#ifndef CRYPTO_AES +HRESULT CBaseCoder::CreateFilterFromDLL(REFCLSID clsID) +{ + if (!_aesLibrary) + { + TCHAR filePath[MAX_PATH + 2]; + if (!GetAESLibPath(filePath)) + return ::GetLastError(); + return _aesLibrary.LoadAndCreateFilter(filePath, clsID, &_aesFilter); + } + return S_OK; +} +#endif + +HRESULT CEncoder::CreateFilter() +{ + #ifdef CRYPTO_AES + _aesFilter = new CAES_CBC_Encoder; + return S_OK; + #else + return CreateFilterFromDLL(CLSID_CCrypto_AES_CBC_Encoder); + #endif +} + +HRESULT CDecoder::CreateFilter() +{ + #ifdef CRYPTO_AES + _aesFilter = new CAES_CBC_Decoder; + return S_OK; + #else + return CreateFilterFromDLL(CLSID_CCrypto_AES_CBC_Decoder); + #endif +} + +}} diff --git a/CPP/7zip/Crypto/7zAES/7zAES.dsp b/CPP/7zip/Crypto/7zAES/7zAES.dsp new file mode 100755 index 00000000..37cd7792 --- /dev/null +++ b/CPP/7zip/Crypto/7zAES/7zAES.dsp @@ -0,0 +1,245 @@ +# Microsoft Developer Studio Project File - Name="7zAES" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=7zAES - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "7zAES.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "7zAES.mak" CFG="7zAES - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "7zAES - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "7zAES - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "7zAES - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "7zAES_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\7zAES.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "7zAES - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "7zAES_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\7zAES.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "7zAES - Win32 Release" +# Name "7zAES - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Codec.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# End Group +# Begin Group "7-Zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderLoader.h +# End Source File +# End Group +# Begin Group "Hash" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Hash\RotateDefs.h +# End Source File +# Begin Source File + +SOURCE=..\Hash\Sha256.cpp + +!IF "$(CFG)" == "7zAES - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7zAES - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\Hash\Sha256.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\7zAES.cpp + +!IF "$(CFG)" == "7zAES - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7zAES - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\7zAES.h +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/Crypto/7zAES/7zAES.dsw b/CPP/7zip/Crypto/7zAES/7zAES.dsw new file mode 100755 index 00000000..08efbad8 --- /dev/null +++ b/CPP/7zip/Crypto/7zAES/7zAES.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "7zAES"=.\7zAES.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Crypto/7zAES/7zAES.h b/CPP/7zip/Crypto/7zAES/7zAES.h new file mode 100755 index 00000000..f312f7e6 --- /dev/null +++ b/CPP/7zip/Crypto/7zAES/7zAES.h @@ -0,0 +1,122 @@ +// 7z_AES.h + +#ifndef __CRYPTO_7Z_AES_H +#define __CRYPTO_7Z_AES_H + +#include "Common/MyCom.h" +#include "Common/Types.h" +#include "Common/Buffer.h" +#include "Common/Vector.h" + +#include "../../ICoder.h" +#include "../../IPassword.h" + +#ifndef CRYPTO_AES +#include "../../Archive/Common/CoderLoader.h" +#endif + +DEFINE_GUID(CLSID_CCrypto_AES_CBC_Encoder, +0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0xC1, 0x00, 0x00, 0x00, 0x01, 0x00); + +DEFINE_GUID(CLSID_CCrypto_AES_CBC_Decoder, +0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00); + +namespace NCrypto { +namespace NSevenZ { + +const int kKeySize = 32; + +class CKeyInfo +{ +public: + int NumCyclesPower; + UInt32 SaltSize; + Byte Salt[16]; + CByteBuffer Password; + Byte Key[kKeySize]; + + bool IsEqualTo(const CKeyInfo &a) const; + void CalculateDigest(); + + CKeyInfo() { Init(); } + void Init() + { + NumCyclesPower = 0; + SaltSize = 0; + for (int i = 0; i < sizeof(Salt); i++) + Salt[i] = 0; + } +}; + +class CKeyInfoCache +{ + int Size; + CObjectVector Keys; +public: + CKeyInfoCache(int size): Size(size) {} + bool Find(CKeyInfo &key); + // HRESULT Calculate(CKeyInfo &key); + void Add(CKeyInfo &key); +}; + +class CBase +{ + CKeyInfoCache _cachedKeys; +protected: + CKeyInfo _key; + Byte _iv[16]; + // int _ivSize; + void CalculateDigest(); + CBase(); +}; + +class CBaseCoder: + public ICompressFilter, + public ICryptoSetPassword, + public CMyUnknownImp, + public CBase +{ +protected: + #ifndef CRYPTO_AES + CCoderLibrary _aesLibrary; + #endif + CMyComPtr _aesFilter; + + virtual HRESULT CreateFilter() = 0; + #ifndef CRYPTO_AES + HRESULT CreateFilterFromDLL(REFCLSID clsID); + #endif +public: + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + + STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); +}; + +class CEncoder: + public CBaseCoder, + public ICompressWriteCoderProperties +{ + virtual HRESULT CreateFilter(); +public: + MY_UNKNOWN_IMP2( + ICryptoSetPassword, + ICompressWriteCoderProperties) + STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); +}; + +class CDecoder: + public CBaseCoder, + public ICompressSetDecoderProperties2 +{ + virtual HRESULT CreateFilter(); +public: + MY_UNKNOWN_IMP2( + ICryptoSetPassword, + ICompressSetDecoderProperties2) + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); +}; + +}} + +#endif diff --git a/CPP/7zip/Crypto/7zAES/DllExports.cpp b/CPP/7zip/Crypto/7zAES/DllExports.cpp new file mode 100755 index 00000000..8766ded4 --- /dev/null +++ b/CPP/7zip/Crypto/7zAES/DllExports.cpp @@ -0,0 +1,111 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "7zAES.h" + +/* +// {23170F69-40C1-278B-0703-000000000000} +DEFINE_GUID(CLSID_CCrypto_Hash_SHA256, +0x23170F69, 0x40C1, 0x278B, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); +*/ + +// {23170F69-40C1-278B-06F1-070100000100} +DEFINE_GUID(CLSID_CCrypto7zAESEncoder, +0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x07, 0x01, 0x00, 0x00, 0x01, 0x00); + +// {23170F69-40C1-278B-06F1-070100000000} +DEFINE_GUID(CLSID_CCrypto7zAESDecoder, +0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00); + +HINSTANCE g_hInstance; +#ifndef _UNICODE +bool g_IsNT = false; +static bool IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); +} +#endif + +extern "C" +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + g_hInstance = hInstance; + #ifndef _UNICODE + g_IsNT = IsItWindowsNT(); + #endif + } + return TRUE; +} + +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + int correctInterface = (*iid == IID_ICompressFilter); + CMyComPtr filter; + if (*clsid == CLSID_CCrypto7zAESDecoder) + { + if (!correctInterface) + return E_NOINTERFACE; + filter = (ICompressFilter *)new NCrypto::NSevenZ::CDecoder(); + } + else if (*clsid == CLSID_CCrypto7zAESEncoder) + { + if (!correctInterface) + return E_NOINTERFACE; + filter = (ICompressFilter *)new NCrypto::NSevenZ::CEncoder(); + } + else + return CLASS_E_CLASSNOTAVAILABLE; + *outObject = filter.Detach(); + COM_TRY_END + return S_OK; +} + +STDAPI GetNumberOfMethods(UINT32 *numMethods) +{ + *numMethods = 1; + return S_OK; +} + +STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +{ + if (index != 0) + return E_INVALIDARG; + ::VariantClear((tagVARIANT *)value); + switch(propID) + { + case NMethodPropID::kID: + { + const char id[] = { 0x06, (char)(unsigned char)0xF1, 0x07, 0x01 }; + if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NMethodPropID::kName: + if ((value->bstrVal = ::SysAllocString(L"7zAES")) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kDecoder: + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CCrypto7zAESDecoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kEncoder: + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CCrypto7zAESEncoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + return S_OK; +} + diff --git a/CPP/7zip/Crypto/7zAES/StdAfx.cpp b/CPP/7zip/Crypto/7zAES/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Crypto/7zAES/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Crypto/7zAES/StdAfx.h b/CPP/7zip/Crypto/7zAES/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Crypto/7zAES/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Crypto/7zAES/makefile b/CPP/7zip/Crypto/7zAES/makefile new file mode 100755 index 00000000..c3d9a51d --- /dev/null +++ b/CPP/7zip/Crypto/7zAES/makefile @@ -0,0 +1,52 @@ +PROG = 7zAES.dll +DEF_FILE = ../Codec.def +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib user32.lib + +7ZAES_OBJS = \ + $O\DllExports.obj \ + +7ZAES_OPT_OBJS = \ + $O\7zAES.obj \ + +CRYPTO_HASH_OBJS = \ + $O\Sha256.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\NewHandler.obj \ + $O\StringConvert.obj \ + $O\Vector.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\Synchronization.obj + +7ZIP_COMMON_OBJS = \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(7ZAES_OBJS) \ + $(7ZAES_OPT_OBJS) \ + $(CRYPTO_HASH_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $O\resource.res + +!include "../../../Build.mak" + +$(7ZAES_OBJS): $(*B).cpp + $(COMPL) +$(7ZAES_OPT_OBJS): $(*B).cpp + $(COMPL) +$(CRYPTO_HASH_OBJS): ../../Crypto/Hash/$(*B).cpp + $(COMPL_O2) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/Crypto/7zAES/resource.rc b/CPP/7zip/Crypto/7zAES/resource.rc new file mode 100755 index 00000000..24d428de --- /dev/null +++ b/CPP/7zip/Crypto/7zAES/resource.rc @@ -0,0 +1,3 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("7zAES Codec", "7zAES") diff --git a/CPP/7zip/Crypto/AES/AES.dsp b/CPP/7zip/Crypto/AES/AES.dsp new file mode 100755 index 00000000..d039be77 --- /dev/null +++ b/CPP/7zip/Crypto/AES/AES.dsp @@ -0,0 +1,203 @@ +# Microsoft Developer Studio Project File - Name="AES" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=AES - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "AES.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "AES.mak" CFG="AES - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "AES - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "AES - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "AES - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AES_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AES_EXPORTS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\AES.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "AES - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AES_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AES_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\AES.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "AES - Win32 Release" +# Name "AES - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Codec.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "AES" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\aes.h +# End Source File +# Begin Source File + +SOURCE=.\aescpp.h +# End Source File +# Begin Source File + +SOURCE=.\aescrypt.c + +!IF "$(CFG)" == "AES - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "AES - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\aeskey.c + +!IF "$(CFG)" == "AES - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "AES - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\aesopt.h +# End Source File +# Begin Source File + +SOURCE=.\aestab.c + +!IF "$(CFG)" == "AES - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "AES - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# End Group +# Begin Source File + +SOURCE=.\AES_CBC.h +# End Source File +# Begin Source File + +SOURCE=.\MyAES.cpp + +!IF "$(CFG)" == "AES - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "AES - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\MyAES.h +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/Crypto/AES/AES.dsw b/CPP/7zip/Crypto/AES/AES.dsw new file mode 100755 index 00000000..7fa9d07b --- /dev/null +++ b/CPP/7zip/Crypto/AES/AES.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "AES"=.\AES.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/Crypto/AES/AES_CBC.h b/CPP/7zip/Crypto/AES/AES_CBC.h new file mode 100755 index 00000000..fa3485a9 --- /dev/null +++ b/CPP/7zip/Crypto/AES/AES_CBC.h @@ -0,0 +1,39 @@ +// AES_CBC.h + +#ifndef __AES_CBC_H +#define __AES_CBC_H + +#include "aescpp.h" + +class CAES_CBC: public AESclass +{ +protected: + Byte _prevBlock[16]; +public: + void Init(const Byte *iv) + { + for (int i = 0; i < 16; i++) + _prevBlock[i] = iv[i]; + } + void Encode(const Byte *inBlock, Byte *outBlock) + { + int i; + for (i = 0; i < 16; i++) + _prevBlock[i] ^= inBlock[i]; + enc_blk(_prevBlock, outBlock); + for (i = 0; i < 16; i++) + _prevBlock[i] = outBlock[i]; + } + + void Decode(const Byte *inBlock, Byte *outBlock) + { + dec_blk(inBlock, outBlock); + int i; + for (i = 0; i < 16; i++) + outBlock[i] ^= _prevBlock[i]; + for (i = 0; i < 16; i++) + _prevBlock[i] = inBlock[i]; + } +}; + +#endif diff --git a/CPP/7zip/Crypto/AES/DllExports.cpp b/CPP/7zip/Crypto/AES/DllExports.cpp new file mode 100755 index 00000000..7c21ac5c --- /dev/null +++ b/CPP/7zip/Crypto/AES/DllExports.cpp @@ -0,0 +1,100 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "MyAES.h" + +extern "C" +BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /* lpReserved */) +{ + return TRUE; +} + +#define MY_CreateClass(n) \ +if (*clsid == CLSID_CCrypto_ ## n ## _Encoder) { \ + if (!correctInterface) return E_NOINTERFACE; \ + filter = (ICompressFilter *)new C ## n ## _Encoder(); \ + } else if (*clsid == CLSID_CCrypto_ ## n ## _Decoder){ \ + if (!correctInterface) return E_NOINTERFACE; \ + filter = (ICompressFilter *)new C ## n ## _Decoder(); \ + } + +STDAPI CreateObject( + const GUID *clsid, + const GUID *interfaceID, + void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + int correctInterface = (*interfaceID == IID_ICompressFilter); + CMyComPtr filter; + + MY_CreateClass(AES_CBC) + else + MY_CreateClass(AES_ECB) + else + return CLASS_E_CLASSNOTAVAILABLE; + *outObject = filter.Detach(); + return S_OK; + COM_TRY_END +} + +struct CAESMethodItem +{ + char ID[3]; + const wchar_t *UserName; + const GUID *Decoder; + const GUID *Encoder; +}; + +#define METHOD_ITEM(Name, id, UserName) \ + { { 0x06, 0x01, id }, UserName, \ + &CLSID_CCrypto_ ## Name ## _Decoder, \ + &CLSID_CCrypto_ ## Name ## _Encoder } + + +static CAESMethodItem g_Methods[] = +{ + METHOD_ITEM(AES_ECB, (char)(unsigned char)0xC0, L"AES-ECB"), + METHOD_ITEM(AES_CBC, (char)(unsigned char)0xC1, L"AES") +}; + +STDAPI GetNumberOfMethods(UINT32 *numMethods) +{ + *numMethods = sizeof(g_Methods) / sizeof(g_Methods[1]); + return S_OK; +} + +STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +{ + if (index > sizeof(g_Methods) / sizeof(g_Methods[1])) + return E_INVALIDARG; + VariantClear((tagVARIANT *)value); + const CAESMethodItem &method = g_Methods[index]; + switch(propID) + { + case NMethodPropID::kID: + if ((value->bstrVal = ::SysAllocStringByteLen(method.ID, + sizeof(method.ID))) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kName: + if ((value->bstrVal = ::SysAllocString(method.UserName)) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kDecoder: + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)method.Decoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kEncoder: + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)method.Encoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + return S_OK; +} + diff --git a/CPP/7zip/Crypto/AES/MyAES.cpp b/CPP/7zip/Crypto/AES/MyAES.cpp new file mode 100755 index 00000000..359caa25 --- /dev/null +++ b/CPP/7zip/Crypto/AES/MyAES.cpp @@ -0,0 +1,94 @@ +// Crypto/AES/MyAES.cpp + +#include "StdAfx.h" + +#include "windows.h" + +#include "MyAES.h" +#include "Windows/Defs.h" + +#include "AES_CBC.h" + +static const int kAESBlockSize = 16; + +extern "C" +{ +#include "aesopt.h" +} + +class CTabInit +{ +public: + CTabInit() { gen_tabs();} +} g_TabInit; + +STDMETHODIMP CAESFilter::Init() { return S_OK; } + +STDMETHODIMP_(UInt32) CAESFilter::Filter(Byte *data, UInt32 size) +{ + if (size > 0 && size < kAESBlockSize) + return kAESBlockSize; + UInt32 i; + for (i = 0; i + kAESBlockSize <= size; i += kAESBlockSize) + { + Byte outBlock[kAESBlockSize]; + SubFilter(data + i, outBlock); + for (int j = 0; j < kAESBlockSize; j++) + data[i + j] = outBlock[j]; + } + return i; +} + +STDMETHODIMP CAESFilter::SetInitVector(const Byte *data, UInt32 size) +{ + if (size != 16) + return E_INVALIDARG; + AES.Init(data); + return S_OK; +} + +STDMETHODIMP CAESEncoder::SetKey(const Byte *data, UInt32 size) + { return (AES.enc_key(data, size) == aes_good) ? S_OK: E_FAIL; } + +void CAESEncoder::SubFilter(const Byte *inBlock, Byte *outBlock) + { AES.Encode(inBlock, outBlock); } + +STDMETHODIMP CAESDecoder::SetKey(const Byte *data, UInt32 size) + { return (AES.dec_key(data, size) == aes_good) ? S_OK: E_FAIL; } + +void CAESDecoder::SubFilter(const Byte *inBlock, Byte *outBlock) + { AES.Decode(inBlock, outBlock); } + +//////////////////////////// +// ECB mode + +STDMETHODIMP CAesEcbFilter::Init() { return S_OK; } +STDMETHODIMP CAesEcbFilter::SetInitVector(const Byte * /* data */, UInt32 size) + { return (size == 0) ? S_OK: E_INVALIDARG; } + +STDMETHODIMP_(UInt32) CAesEcbFilter::Filter(Byte *data, UInt32 size) +{ + if (size > 0 && size < kAESBlockSize) + return kAESBlockSize; + UInt32 i; + for (i = 0; i + kAESBlockSize <= size; i += kAESBlockSize) + { + Byte outBlock[kAESBlockSize]; + SubFilter(data + i, outBlock); + for (int j = 0; j < kAESBlockSize; j++) + data[i + j] = outBlock[j]; + } + return i; +} + +STDMETHODIMP CAesEcbEncoder::SetKey(const Byte *data, UInt32 size) + { return (AES.enc_key(data, size) == aes_good) ? S_OK: E_FAIL; } + +void CAesEcbEncoder::SubFilter(const Byte *inBlock, Byte *outBlock) + { AES.enc_blk(inBlock, outBlock); } + +STDMETHODIMP CAesEcbDecoder::SetKey(const Byte *data, UInt32 size) + { return (AES.dec_key(data, size) == aes_good) ? S_OK: E_FAIL; } + +void CAesEcbDecoder::SubFilter(const Byte *inBlock, Byte *outBlock) + { AES.dec_blk(inBlock, outBlock); } diff --git a/CPP/7zip/Crypto/AES/MyAES.h b/CPP/7zip/Crypto/AES/MyAES.h new file mode 100755 index 00000000..f58913ae --- /dev/null +++ b/CPP/7zip/Crypto/AES/MyAES.h @@ -0,0 +1,106 @@ +// Crypto/AES/MyAES.h + +#ifndef __CIPHER_MYAES_H +#define __CIPHER_MYAES_H + +#include "Common/Types.h" +#include "Common/MyCom.h" + +#include "../../ICoder.h" +#include "AES_CBC.h" + +class CAESFilter: + public ICompressFilter, + public ICryptoProperties, + public CMyUnknownImp +{ +protected: + CAES_CBC AES; + // Byte Key[32]; + // Byte IV[kAESBlockSize]; +public: + MY_UNKNOWN_IMP1(ICryptoProperties) + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + STDMETHOD(SetKey)(const Byte *data, UInt32 size) = 0; + STDMETHOD(SetInitVector)(const Byte *data, UInt32 size); + virtual void SubFilter(const Byte *inBlock, Byte *outBlock) = 0; +}; + +class CAESEncoder: public CAESFilter +{ +public: + STDMETHOD(SetKey)(const Byte *data, UInt32 size); + virtual void SubFilter(const Byte *inBlock, Byte *outBlock); +}; + +class CAESDecoder: public CAESFilter +{ +public: + STDMETHOD(SetKey)(const Byte *data, UInt32 size); + virtual void SubFilter(const Byte *inBlock, Byte *outBlock); +}; + +#define MyClassCrypto3E(Name) class C ## Name: public CAESEncoder { }; +#define MyClassCrypto3D(Name) class C ## Name: public CAESDecoder { }; + +// {23170F69-40C1-278B-0601-000000000000} +#define MyClassCrypto2(Name, id, encodingId) \ +DEFINE_GUID(CLSID_CCrypto_ ## Name, \ +0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, id, 0x00, 0x00, 0x00, encodingId, 0x00); + +#define MyClassCrypto(Name, id) \ +MyClassCrypto2(Name ## _Encoder, id, 0x01) \ +MyClassCrypto3E(Name ## _Encoder) \ +MyClassCrypto2(Name ## _Decoder, id, 0x00) \ +MyClassCrypto3D(Name ## _Decoder) \ + +MyClassCrypto(AES_CBC, 0xC1) + +class CAesEcbFilter: + public ICompressFilter, + public ICryptoProperties, + public CMyUnknownImp +{ +protected: + AESclass AES; +public: + MY_UNKNOWN_IMP1(ICryptoProperties) + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + STDMETHOD(SetKey)(const Byte *data, UInt32 size) = 0; + STDMETHOD(SetInitVector)(const Byte *data, UInt32 size); + virtual void SubFilter(const Byte *inBlock, Byte *outBlock) = 0; +}; + +class CAesEcbEncoder: public CAesEcbFilter +{ +public: + STDMETHOD(SetKey)(const Byte *data, UInt32 size); + virtual void SubFilter(const Byte *inBlock, Byte *outBlock); +}; + +class CAesEcbDecoder: public CAesEcbFilter +{ +public: + STDMETHOD(SetKey)(const Byte *data, UInt32 size); + virtual void SubFilter(const Byte *inBlock, Byte *outBlock); +}; + +#define MyClassCrypto3E_Ecb(Name) class C ## Name: public CAesEcbEncoder { }; +#define MyClassCrypto3D_Ecb(Name) class C ## Name: public CAesEcbDecoder { }; + +// {23170F69-40C1-278B-0601-000000000000} +#define MyClassCrypto2_Ecb(Name, id, encodingId) \ +DEFINE_GUID(CLSID_CCrypto_ ## Name, \ +0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, id, 0x00, 0x00, 0x00, encodingId, 0x00); + +#define MyClassCrypto_Ecb(Name, id) \ +MyClassCrypto2_Ecb(Name ## _Encoder, id, 0x01) \ +MyClassCrypto3E_Ecb(Name ## _Encoder) \ +MyClassCrypto2_Ecb(Name ## _Decoder, id, 0x00) \ +MyClassCrypto3D_Ecb(Name ## _Decoder) \ + +MyClassCrypto_Ecb(AES_ECB, 0xC0) + +#endif diff --git a/CPP/7zip/Crypto/AES/StdAfx.cpp b/CPP/7zip/Crypto/AES/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Crypto/AES/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Crypto/AES/StdAfx.h b/CPP/7zip/Crypto/AES/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Crypto/AES/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Crypto/AES/aes.h b/CPP/7zip/Crypto/AES/aes.h new file mode 100755 index 00000000..9aaba978 --- /dev/null +++ b/CPP/7zip/Crypto/AES/aes.h @@ -0,0 +1,103 @@ +/* + ------------------------------------------------------------------------- + Copyright (c) 2001, Dr Brian Gladman , Worcester, UK. + All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and fitness for purpose. + ------------------------------------------------------------------------- + Issue Date: 29/07/2002 + + This file contains the definitions required to use AES (Rijndael) in C. +*/ + +#ifndef _AES_H +#define _AES_H + +/* This include is used only to find 8 and 32 bit unsigned integer types */ + +#include "limits.h" + +#if UCHAR_MAX == 0xff /* an unsigned 8 bit type for internal AES use */ + typedef unsigned char aes_08t; +#else +#error Please define an unsigned 8 bit type in aes.h +#endif + +#if UINT_MAX == 0xffffffff /* an unsigned 32 bit type for internal AES use */ + typedef unsigned int aes_32t; +#elif ULONG_MAX == 0xffffffff + typedef unsigned long aes_32t; +#else +#error Please define an unsigned 32 bit type in aes.h +#endif + +/* BLOCK_SIZE is in BYTES: 16, 24, 32 or undefined for aes.c and 16, 20, + 24, 28, 32 or undefined for aespp.c. When left undefined a slower + version that provides variable block length is compiled. +*/ + +#define BLOCK_SIZE 16 + +/* key schedule length (in 32-bit words) */ + +#if !defined(BLOCK_SIZE) +#define KS_LENGTH 128 +#else +#define KS_LENGTH 4 * BLOCK_SIZE +#endif + +#if defined(__cplusplus) +extern "C" +{ +#endif + +typedef unsigned int aes_fret; /* type for function return value */ +#define aes_bad 0 /* bad function return value */ +#define aes_good 1 /* good function return value */ +#ifndef AES_DLL /* implement normal or DLL functions */ +#define aes_rval aes_fret +#else +#define aes_rval aes_fret __declspec(dllexport) _stdcall +#endif + + +typedef struct /* the AES context for encryption */ +{ aes_32t k_sch[KS_LENGTH]; /* the encryption key schedule */ + aes_32t n_rnd; /* the number of cipher rounds */ + aes_32t n_blk; /* the number of bytes in the state */ +} aes_ctx; + +#if !defined(BLOCK_SIZE) +aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1]); +#endif + +aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]); +aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]); + +aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]); +aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/CPP/7zip/Crypto/AES/aescpp.h b/CPP/7zip/Crypto/AES/aescpp.h new file mode 100755 index 00000000..93e3c8b0 --- /dev/null +++ b/CPP/7zip/Crypto/AES/aescpp.h @@ -0,0 +1,55 @@ + +/* + ------------------------------------------------------------------------- + Copyright (c) 2001, Dr Brian Gladman , Worcester, UK. + All rights reserved. + + TERMS + + Redistribution and use in source and binary forms, with or without + modification, are permitted subject to the following conditions: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The copyright holder's name must not be used to endorse or promote + any products derived from this software without his specific prior + written permission. + + This software is provided 'as is' with no express or implied warranties + of correctness or fitness for purpose. + ------------------------------------------------------------------------- + Issue Date: 21/01/2002 + + This file contains the definitions required to use AES (Rijndael) in C++. +*/ + +#ifndef _AESCPP_H +#define _AESCPP_H + +#include "aes.h" + +class AESclass +{ aes_ctx cx[1]; +public: +#if defined(BLOCK_SIZE) + AESclass() { cx->n_blk = BLOCK_SIZE; cx->n_rnd = 0; } +#else + AESclass(unsigned int blen = 16) { cx->n_blk = blen; cx->n_rnd = 0; } + aes_rval blk_len(unsigned int blen) { return aes_blk_len(blen, cx); } +#endif + aes_rval enc_key(const unsigned char in_key[], unsigned int klen) + { return aes_enc_key(in_key, klen, cx); } + aes_rval dec_key(const unsigned char in_key[], unsigned int klen) + { return aes_dec_key(in_key, klen, cx); } + aes_rval enc_blk(const unsigned char in_blk[], unsigned char out_blk[]) + { return aes_enc_blk(in_blk, out_blk, cx); } + aes_rval dec_blk(const unsigned char in_blk[], unsigned char out_blk[]) + { return aes_dec_blk(in_blk, out_blk, cx); } +}; + +#endif diff --git a/CPP/7zip/Crypto/AES/aescrypt.c b/CPP/7zip/Crypto/AES/aescrypt.c new file mode 100755 index 00000000..095a61c4 --- /dev/null +++ b/CPP/7zip/Crypto/AES/aescrypt.c @@ -0,0 +1,421 @@ +/* + ------------------------------------------------------------------------- + Copyright (c) 2001, Dr Brian Gladman , Worcester, UK. + All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and fitness for purpose. + ------------------------------------------------------------------------- + Issue Date: 29/07/2002 + + This file contains the code for implementing encryption and decryption + for AES (Rijndael) for block and key sizes of 16, 24 and 32 bytes. It + can optionally be replaced by code written in assembler using NASM. +*/ + +#include "aesopt.h" + +#if defined(BLOCK_SIZE) && (BLOCK_SIZE & 7) +#error An illegal block size has been specified. +#endif + +#define unused 77 /* Sunset Strip */ + +#define si(y,x,k,c) s(y,c) = word_in(x + 4 * c) ^ k[c] +#define so(y,x,c) word_out(y + 4 * c, s(x,c)) + +#if BLOCK_SIZE == 16 + +#if defined(ARRAYS) +#define locals(y,x) x[4],y[4] +#else +#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3 + /* + the following defines prevent the compiler requiring the declaration + of generated but unused variables in the fwd_var and inv_var macros + */ +#define b04 unused +#define b05 unused +#define b06 unused +#define b07 unused +#define b14 unused +#define b15 unused +#define b16 unused +#define b17 unused +#endif +#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \ + s(y,2) = s(x,2); s(y,3) = s(x,3); +#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3) +#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3) +#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3) + +#elif BLOCK_SIZE == 24 + +#if defined(ARRAYS) +#define locals(y,x) x[6],y[6] +#else +#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \ + y##0,y##1,y##2,y##3,y##4,y##5 +#define b06 unused +#define b07 unused +#define b16 unused +#define b17 unused +#endif +#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \ + s(y,2) = s(x,2); s(y,3) = s(x,3); \ + s(y,4) = s(x,4); s(y,5) = s(x,5); +#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \ + si(y,x,k,3); si(y,x,k,4); si(y,x,k,5) +#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \ + so(y,x,3); so(y,x,4); so(y,x,5) +#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \ + rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5) +#else + +#if defined(ARRAYS) +#define locals(y,x) x[8],y[8] +#else +#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \ + y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7 +#endif +#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \ + s(y,2) = s(x,2); s(y,3) = s(x,3); \ + s(y,4) = s(x,4); s(y,5) = s(x,5); \ + s(y,6) = s(x,6); s(y,7) = s(x,7); + +#if BLOCK_SIZE == 32 + +#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \ + si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7) +#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \ + so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7) +#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \ + rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7) +#else + +#define state_in(y,x,k) \ +switch(nc) \ +{ case 8: si(y,x,k,7); si(y,x,k,6); \ + case 6: si(y,x,k,5); si(y,x,k,4); \ + case 4: si(y,x,k,3); si(y,x,k,2); \ + si(y,x,k,1); si(y,x,k,0); \ +} + +#define state_out(y,x) \ +switch(nc) \ +{ case 8: so(y,x,7); so(y,x,6); \ + case 6: so(y,x,5); so(y,x,4); \ + case 4: so(y,x,3); so(y,x,2); \ + so(y,x,1); so(y,x,0); \ +} + +#if defined(FAST_VARIABLE) + +#define round(rm,y,x,k) \ +switch(nc) \ +{ case 8: rm(y,x,k,7); rm(y,x,k,6); \ + rm(y,x,k,5); rm(y,x,k,4); \ + rm(y,x,k,3); rm(y,x,k,2); \ + rm(y,x,k,1); rm(y,x,k,0); \ + break; \ + case 6: rm(y,x,k,5); rm(y,x,k,4); \ + rm(y,x,k,3); rm(y,x,k,2); \ + rm(y,x,k,1); rm(y,x,k,0); \ + break; \ + case 4: rm(y,x,k,3); rm(y,x,k,2); \ + rm(y,x,k,1); rm(y,x,k,0); \ + break; \ +} +#else + +#define round(rm,y,x,k) \ +switch(nc) \ +{ case 8: rm(y,x,k,7); rm(y,x,k,6); \ + case 6: rm(y,x,k,5); rm(y,x,k,4); \ + case 4: rm(y,x,k,3); rm(y,x,k,2); \ + rm(y,x,k,1); rm(y,x,k,0); \ +} + +#endif + +#endif +#endif + +#if defined(ENCRYPTION) + +/* I am grateful to Frank Yellin for the following construction + (and that for decryption) which, given the column (c) of the + output state variable, gives the input state variables which + are needed in its computation for each row (r) of the state. + + For the fixed block size options, compilers should be able to + reduce this complex expression (and the equivalent one for + decryption) to a static variable reference at compile time. + But for variable block size code, there will be some limbs on + which conditional clauses will be returned. +*/ + +/* y = output word, x = input word, r = row, c = column for r = 0, + 1, 2 and 3 = column accessed for row r. +*/ + +#define fwd_var(x,r,c)\ + ( r == 0 ? \ + ( c == 0 ? s(x,0) \ + : c == 1 ? s(x,1) \ + : c == 2 ? s(x,2) \ + : c == 3 ? s(x,3) \ + : c == 4 ? s(x,4) \ + : c == 5 ? s(x,5) \ + : c == 6 ? s(x,6) \ + : s(x,7))\ + : r == 1 ? \ + ( c == 0 ? s(x,1) \ + : c == 1 ? s(x,2) \ + : c == 2 ? s(x,3) \ + : c == 3 ? nc == 4 ? s(x,0) : s(x,4) \ + : c == 4 ? s(x,5) \ + : c == 5 ? nc == 8 ? s(x,6) : s(x,0) \ + : c == 6 ? s(x,7) \ + : s(x,0))\ + : r == 2 ? \ + ( c == 0 ? nc == 8 ? s(x,3) : s(x,2) \ + : c == 1 ? nc == 8 ? s(x,4) : s(x,3) \ + : c == 2 ? nc == 4 ? s(x,0) : nc == 8 ? s(x,5) : s(x,4) \ + : c == 3 ? nc == 4 ? s(x,1) : nc == 8 ? s(x,6) : s(x,5) \ + : c == 4 ? nc == 8 ? s(x,7) : s(x,0) \ + : c == 5 ? nc == 8 ? s(x,0) : s(x,1) \ + : c == 6 ? s(x,1) \ + : s(x,2))\ + : \ + ( c == 0 ? nc == 8 ? s(x,4) : s(x,3) \ + : c == 1 ? nc == 4 ? s(x,0) : nc == 8 ? s(x,5) : s(x,4) \ + : c == 2 ? nc == 4 ? s(x,1) : nc == 8 ? s(x,6) : s(x,5) \ + : c == 3 ? nc == 4 ? s(x,2) : nc == 8 ? s(x,7) : s(x,0) \ + : c == 4 ? nc == 8 ? s(x,0) : s(x,1) \ + : c == 5 ? nc == 8 ? s(x,1) : s(x,2) \ + : c == 6 ? s(x,2) \ + : s(x,3))) + +#if defined(FT4_SET) +#undef dec_fmvars +#define dec_fmvars +#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c) +#elif defined(FT1_SET) +#undef dec_fmvars +#define dec_fmvars +#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c) +#else +#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c] +#endif + +#if defined(FL4_SET) +#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c) +#elif defined(FL1_SET) +#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c) +#else +#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c] +#endif + +aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]) +{ aes_32t locals(b0, b1); + const aes_32t *kp = cx->k_sch; + dec_fmvars /* declare variables for fwd_mcol() if needed */ + + if(!(cx->n_blk & 1)) return aes_bad; + + state_in(b0, in_blk, kp); + +#if (ENC_UNROLL == FULL) + + kp += (cx->n_rnd - 9) * nc; + + switch(cx->n_rnd) + { + case 14: round(fwd_rnd, b1, b0, kp - 4 * nc); + round(fwd_rnd, b0, b1, kp - 3 * nc); + case 12: round(fwd_rnd, b1, b0, kp - 2 * nc); + round(fwd_rnd, b0, b1, kp - nc); + case 10: round(fwd_rnd, b1, b0, kp ); + round(fwd_rnd, b0, b1, kp + nc); + round(fwd_rnd, b1, b0, kp + 2 * nc); + round(fwd_rnd, b0, b1, kp + 3 * nc); + round(fwd_rnd, b1, b0, kp + 4 * nc); + round(fwd_rnd, b0, b1, kp + 5 * nc); + round(fwd_rnd, b1, b0, kp + 6 * nc); + round(fwd_rnd, b0, b1, kp + 7 * nc); + round(fwd_rnd, b1, b0, kp + 8 * nc); + round(fwd_lrnd, b0, b1, kp + 9 * nc); + } +#else + +#if (ENC_UNROLL == PARTIAL) + { aes_32t rnd; + for(rnd = 0; rnd < (cx->n_rnd >> 1) - 1; ++rnd) + { + kp += nc; + round(fwd_rnd, b1, b0, kp); + kp += nc; + round(fwd_rnd, b0, b1, kp); + } + kp += nc; + round(fwd_rnd, b1, b0, kp); +#else + { aes_32t rnd, *p0 = b0, *p1 = b1, *pt; + for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd) + { + kp += nc; + round(fwd_rnd, p1, p0, kp); + pt = p0, p0 = p1, p1 = pt; + } +#endif + kp += nc; + round(fwd_lrnd, b0, b1, kp); + } +#endif + + state_out(out_blk, b0); + return aes_good; +} + +#endif + +#if defined(DECRYPTION) + +#define inv_var(x,r,c) \ + ( r == 0 ? \ + ( c == 0 ? s(x,0) \ + : c == 1 ? s(x,1) \ + : c == 2 ? s(x,2) \ + : c == 3 ? s(x,3) \ + : c == 4 ? s(x,4) \ + : c == 5 ? s(x,5) \ + : c == 6 ? s(x,6) \ + : s(x,7))\ + : r == 1 ? \ + ( c == 0 ? nc == 4 ? s(x,3) : nc == 8 ? s(x,7) : s(x,5) \ + : c == 1 ? s(x,0) \ + : c == 2 ? s(x,1) \ + : c == 3 ? s(x,2) \ + : c == 4 ? s(x,3) \ + : c == 5 ? s(x,4) \ + : c == 6 ? s(x,5) \ + : s(x,6))\ + : r == 2 ? \ + ( c == 0 ? nc == 4 ? s(x,2) : nc == 8 ? s(x,5) : s(x,4) \ + : c == 1 ? nc == 4 ? s(x,3) : nc == 8 ? s(x,6) : s(x,5) \ + : c == 2 ? nc == 8 ? s(x,7) : s(x,0) \ + : c == 3 ? nc == 8 ? s(x,0) : s(x,1) \ + : c == 4 ? nc == 8 ? s(x,1) : s(x,2) \ + : c == 5 ? nc == 8 ? s(x,2) : s(x,3) \ + : c == 6 ? s(x,3) \ + : s(x,4))\ + : \ + ( c == 0 ? nc == 4 ? s(x,1) : nc == 8 ? s(x,4) : s(x,3) \ + : c == 1 ? nc == 4 ? s(x,2) : nc == 8 ? s(x,5) : s(x,4) \ + : c == 2 ? nc == 4 ? s(x,3) : nc == 8 ? s(x,6) : s(x,5) \ + : c == 3 ? nc == 8 ? s(x,7) : s(x,0) \ + : c == 4 ? nc == 8 ? s(x,0) : s(x,1) \ + : c == 5 ? nc == 8 ? s(x,1) : s(x,2) \ + : c == 6 ? s(x,2) \ + : s(x,3))) + +#if defined(IT4_SET) +#undef dec_imvars +#define dec_imvars +#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c) +#elif defined(IT1_SET) +#undef dec_imvars +#define dec_imvars +#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c) +#else +#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]) +#endif + +#if defined(IL4_SET) +#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c) +#elif defined(IL1_SET) +#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c) +#else +#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c] +#endif + +aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]) +{ aes_32t locals(b0, b1); + const aes_32t *kp = cx->k_sch + nc * cx->n_rnd; + dec_imvars /* declare variables for inv_mcol() if needed */ + + if(!(cx->n_blk & 2)) return aes_bad; + + state_in(b0, in_blk, kp); + +#if (DEC_UNROLL == FULL) + + kp = cx->k_sch + 9 * nc; + switch(cx->n_rnd) + { + case 14: round(inv_rnd, b1, b0, kp + 4 * nc); + round(inv_rnd, b0, b1, kp + 3 * nc); + case 12: round(inv_rnd, b1, b0, kp + 2 * nc); + round(inv_rnd, b0, b1, kp + nc ); + case 10: round(inv_rnd, b1, b0, kp ); + round(inv_rnd, b0, b1, kp - nc); + round(inv_rnd, b1, b0, kp - 2 * nc); + round(inv_rnd, b0, b1, kp - 3 * nc); + round(inv_rnd, b1, b0, kp - 4 * nc); + round(inv_rnd, b0, b1, kp - 5 * nc); + round(inv_rnd, b1, b0, kp - 6 * nc); + round(inv_rnd, b0, b1, kp - 7 * nc); + round(inv_rnd, b1, b0, kp - 8 * nc); + round(inv_lrnd, b0, b1, kp - 9 * nc); + } +#else + +#if (DEC_UNROLL == PARTIAL) + { aes_32t rnd; + for(rnd = 0; rnd < (cx->n_rnd >> 1) - 1; ++rnd) + { + kp -= nc; + round(inv_rnd, b1, b0, kp); + kp -= nc; + round(inv_rnd, b0, b1, kp); + } + kp -= nc; + round(inv_rnd, b1, b0, kp); +#else + { aes_32t rnd, *p0 = b0, *p1 = b1, *pt; + for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd) + { + kp -= nc; + round(inv_rnd, p1, p0, kp); + pt = p0, p0 = p1, p1 = pt; + } +#endif + kp -= nc; + round(inv_lrnd, b0, b1, kp); + } +#endif + + state_out(out_blk, b0); + return aes_good; +} + +#endif diff --git a/CPP/7zip/Crypto/AES/aeskey.c b/CPP/7zip/Crypto/AES/aeskey.c new file mode 100755 index 00000000..d281e1a8 --- /dev/null +++ b/CPP/7zip/Crypto/AES/aeskey.c @@ -0,0 +1,363 @@ +/* + ------------------------------------------------------------------------- + Copyright (c) 2001, Dr Brian Gladman , Worcester, UK. + All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and fitness for purpose. + ------------------------------------------------------------------------- + Issue Date: 29/07/2002 + + This file contains the code for implementing the key schedule for AES + (Rijndael) for block and key sizes of 16, 24, and 32 bytes. +*/ + +#include "aesopt.h" + +#if defined(BLOCK_SIZE) && (BLOCK_SIZE & 7) +#error An illegal block size has been specified. +#endif + +/* Subroutine to set the block size (if variable) in bytes, legal + values being 16, 24 and 32. +*/ + +#if !defined(BLOCK_SIZE) + +aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1]) +{ +#if !defined(FIXED_TABLES) + if(!tab_init) gen_tabs(); +#endif + + if((blen & 7) || blen < 16 || blen > 32) + { + cx->n_blk = 0; return aes_bad; + } + + cx->n_blk = blen; + return aes_good; +} + +#endif + +/* Initialise the key schedule from the user supplied key. The key + length is now specified in bytes - 16, 24 or 32 as appropriate. + This corresponds to bit lengths of 128, 192 and 256 bits, and + to Nk values of 4, 6 and 8 respectively. + + The following macros implement a single cycle in the key + schedule generation process. The number of cycles needed + for each cx->n_col and nk value is: + + nk = 4 5 6 7 8 + ------------------------------ + cx->n_col = 4 10 9 8 7 7 + cx->n_col = 5 14 11 10 9 9 + cx->n_col = 6 19 15 12 11 11 + cx->n_col = 7 21 19 16 13 14 + cx->n_col = 8 29 23 19 17 14 +*/ + +#define ke4(k,i) \ +{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \ + k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \ +} +#define kel4(k,i) \ +{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \ + k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \ +} + +#define ke6(k,i) \ +{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \ + k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \ + k[6*(i)+10] = ss[4] ^= ss[3]; k[6*(i)+11] = ss[5] ^= ss[4]; \ +} +#define kel6(k,i) \ +{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \ + k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \ +} + +#define ke8(k,i) \ +{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \ + k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \ + k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); k[8*(i)+13] = ss[5] ^= ss[4]; \ + k[8*(i)+14] = ss[6] ^= ss[5]; k[8*(i)+15] = ss[7] ^= ss[6]; \ +} +#define kel8(k,i) \ +{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \ + k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \ +} + +#if defined(ENCRYPTION_KEY_SCHEDULE) + +aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]) +{ aes_32t ss[8]; + +#if !defined(FIXED_TABLES) + if(!tab_init) gen_tabs(); +#endif + +#if !defined(BLOCK_SIZE) + if(!cx->n_blk) cx->n_blk = 16; +#else + cx->n_blk = BLOCK_SIZE; +#endif + + cx->n_blk = (cx->n_blk & ~3) | 1; + + cx->k_sch[0] = ss[0] = word_in(in_key ); + cx->k_sch[1] = ss[1] = word_in(in_key + 4); + cx->k_sch[2] = ss[2] = word_in(in_key + 8); + cx->k_sch[3] = ss[3] = word_in(in_key + 12); + +#if (BLOCK_SIZE == 16) && (ENC_UNROLL != NONE) + + switch(klen) + { + case 16: ke4(cx->k_sch, 0); ke4(cx->k_sch, 1); + ke4(cx->k_sch, 2); ke4(cx->k_sch, 3); + ke4(cx->k_sch, 4); ke4(cx->k_sch, 5); + ke4(cx->k_sch, 6); ke4(cx->k_sch, 7); + ke4(cx->k_sch, 8); kel4(cx->k_sch, 9); + cx->n_rnd = 10; break; + case 24: cx->k_sch[4] = ss[4] = word_in(in_key + 16); + cx->k_sch[5] = ss[5] = word_in(in_key + 20); + ke6(cx->k_sch, 0); ke6(cx->k_sch, 1); + ke6(cx->k_sch, 2); ke6(cx->k_sch, 3); + ke6(cx->k_sch, 4); ke6(cx->k_sch, 5); + ke6(cx->k_sch, 6); kel6(cx->k_sch, 7); + cx->n_rnd = 12; break; + case 32: cx->k_sch[4] = ss[4] = word_in(in_key + 16); + cx->k_sch[5] = ss[5] = word_in(in_key + 20); + cx->k_sch[6] = ss[6] = word_in(in_key + 24); + cx->k_sch[7] = ss[7] = word_in(in_key + 28); + ke8(cx->k_sch, 0); ke8(cx->k_sch, 1); + ke8(cx->k_sch, 2); ke8(cx->k_sch, 3); + ke8(cx->k_sch, 4); ke8(cx->k_sch, 5); + kel8(cx->k_sch, 6); + cx->n_rnd = 14; break; + default: cx->n_rnd = 0; return aes_bad; + } +#else + { aes_32t i, l; + cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6; + l = (nc * cx->n_rnd + nc - 1) / (klen >> 2); + + switch(klen) + { + case 16: for(i = 0; i < l; ++i) + ke4(cx->k_sch, i); + break; + case 24: cx->k_sch[4] = ss[4] = word_in(in_key + 16); + cx->k_sch[5] = ss[5] = word_in(in_key + 20); + for(i = 0; i < l; ++i) + ke6(cx->k_sch, i); + break; + case 32: cx->k_sch[4] = ss[4] = word_in(in_key + 16); + cx->k_sch[5] = ss[5] = word_in(in_key + 20); + cx->k_sch[6] = ss[6] = word_in(in_key + 24); + cx->k_sch[7] = ss[7] = word_in(in_key + 28); + for(i = 0; i < l; ++i) + ke8(cx->k_sch, i); + break; + default: cx->n_rnd = 0; return aes_bad; + } + } +#endif + + return aes_good; +} + +#endif + +#if defined(DECRYPTION_KEY_SCHEDULE) + +#if (DEC_ROUND != NO_TABLES) +#define d_vars dec_imvars +#define ff(x) inv_mcol(x) +#else +#define ff(x) (x) +#define d_vars +#endif + +#if 1 +#define kdf4(k,i) \ +{ ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; ss[1] = ss[1] ^ ss[3]; ss[2] = ss[2] ^ ss[3]; ss[3] = ss[3]; \ + ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; \ + ss[4] ^= k[4*(i)]; k[4*(i)+4] = ff(ss[4]); ss[4] ^= k[4*(i)+1]; k[4*(i)+5] = ff(ss[4]); \ + ss[4] ^= k[4*(i)+2]; k[4*(i)+6] = ff(ss[4]); ss[4] ^= k[4*(i)+3]; k[4*(i)+7] = ff(ss[4]); \ +} +#define kd4(k,i) \ +{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \ + k[4*(i)+4] = ss[4] ^= k[4*(i)]; k[4*(i)+5] = ss[4] ^= k[4*(i)+1]; \ + k[4*(i)+6] = ss[4] ^= k[4*(i)+2]; k[4*(i)+7] = ss[4] ^= k[4*(i)+3]; \ +} +#define kdl4(k,i) \ +{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; \ + k[4*(i)+4] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; k[4*(i)+5] = ss[1] ^ ss[3]; \ + k[4*(i)+6] = ss[0]; k[4*(i)+7] = ss[1]; \ +} +#else +#define kdf4(k,i) \ +{ ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+ 4] = ff(ss[0]); ss[1] ^= ss[0]; k[4*(i)+ 5] = ff(ss[1]); \ + ss[2] ^= ss[1]; k[4*(i)+ 6] = ff(ss[2]); ss[3] ^= ss[2]; k[4*(i)+ 7] = ff(ss[3]); \ +} +#define kd4(k,i) \ +{ ss[4] = ls_box(ss[3],3) ^ rcon_tab[i]; \ + ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[4*(i)+ 4] = ss[4] ^= k[4*(i)]; \ + ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[4] ^= k[4*(i)+ 1]; \ + ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[4] ^= k[4*(i)+ 2]; \ + ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[4] ^= k[4*(i)+ 3]; \ +} +#define kdl4(k,i) \ +{ ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+ 4] = ss[0]; ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[1]; \ + ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[2]; ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[3]; \ +} +#endif + +#define kdf6(k,i) \ +{ ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 6] = ff(ss[0]); ss[1] ^= ss[0]; k[6*(i)+ 7] = ff(ss[1]); \ + ss[2] ^= ss[1]; k[6*(i)+ 8] = ff(ss[2]); ss[3] ^= ss[2]; k[6*(i)+ 9] = ff(ss[3]); \ + ss[4] ^= ss[3]; k[6*(i)+10] = ff(ss[4]); ss[5] ^= ss[4]; k[6*(i)+11] = ff(ss[5]); \ +} +#define kd6(k,i) \ +{ ss[6] = ls_box(ss[5],3) ^ rcon_tab[i]; \ + ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[6*(i)+ 6] = ss[6] ^= k[6*(i)]; \ + ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[6] ^= k[6*(i)+ 1]; \ + ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[6] ^= k[6*(i)+ 2]; \ + ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[6] ^= k[6*(i)+ 3]; \ + ss[4] ^= ss[3]; k[6*(i)+10] = ss[6] ^= k[6*(i)+ 4]; \ + ss[5] ^= ss[4]; k[6*(i)+11] = ss[6] ^= k[6*(i)+ 5]; \ +} +#define kdl6(k,i) \ +{ ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 6] = ss[0]; ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[1]; \ + ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[2]; ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[3]; \ +} + +#define kdf8(k,i) \ +{ ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 8] = ff(ss[0]); ss[1] ^= ss[0]; k[8*(i)+ 9] = ff(ss[1]); \ + ss[2] ^= ss[1]; k[8*(i)+10] = ff(ss[2]); ss[3] ^= ss[2]; k[8*(i)+11] = ff(ss[3]); \ + ss[4] ^= ls_box(ss[3],0); k[8*(i)+12] = ff(ss[4]); ss[5] ^= ss[4]; k[8*(i)+13] = ff(ss[5]); \ + ss[6] ^= ss[5]; k[8*(i)+14] = ff(ss[6]); ss[7] ^= ss[6]; k[8*(i)+15] = ff(ss[7]); \ +} +#define kd8(k,i) \ +{ aes_32t g = ls_box(ss[7],3) ^ rcon_tab[i]; \ + ss[0] ^= g; g = ff(g); k[8*(i)+ 8] = g ^= k[8*(i)]; \ + ss[1] ^= ss[0]; k[8*(i)+ 9] = g ^= k[8*(i)+ 1]; \ + ss[2] ^= ss[1]; k[8*(i)+10] = g ^= k[8*(i)+ 2]; \ + ss[3] ^= ss[2]; k[8*(i)+11] = g ^= k[8*(i)+ 3]; \ + g = ls_box(ss[3],0); \ + ss[4] ^= g; g = ff(g); k[8*(i)+12] = g ^= k[8*(i)+ 4]; \ + ss[5] ^= ss[4]; k[8*(i)+13] = g ^= k[8*(i)+ 5]; \ + ss[6] ^= ss[5]; k[8*(i)+14] = g ^= k[8*(i)+ 6]; \ + ss[7] ^= ss[6]; k[8*(i)+15] = g ^= k[8*(i)+ 7]; \ +} +#define kdl8(k,i) \ +{ ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 8] = ss[0]; ss[1] ^= ss[0]; k[8*(i)+ 9] = ss[1]; \ + ss[2] ^= ss[1]; k[8*(i)+10] = ss[2]; ss[3] ^= ss[2]; k[8*(i)+11] = ss[3]; \ +} + +aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]) +{ aes_32t ss[8]; + d_vars + +#if !defined(FIXED_TABLES) + if(!tab_init) gen_tabs(); +#endif + +#if !defined(BLOCK_SIZE) + if(!cx->n_blk) cx->n_blk = 16; +#else + cx->n_blk = BLOCK_SIZE; +#endif + + cx->n_blk = (cx->n_blk & ~3) | 2; + + cx->k_sch[0] = ss[0] = word_in(in_key ); + cx->k_sch[1] = ss[1] = word_in(in_key + 4); + cx->k_sch[2] = ss[2] = word_in(in_key + 8); + cx->k_sch[3] = ss[3] = word_in(in_key + 12); + +#if (BLOCK_SIZE == 16) && (DEC_UNROLL != NONE) + + switch(klen) + { + case 16: kdf4(cx->k_sch, 0); kd4(cx->k_sch, 1); + kd4(cx->k_sch, 2); kd4(cx->k_sch, 3); + kd4(cx->k_sch, 4); kd4(cx->k_sch, 5); + kd4(cx->k_sch, 6); kd4(cx->k_sch, 7); + kd4(cx->k_sch, 8); kdl4(cx->k_sch, 9); + cx->n_rnd = 10; break; + case 24: cx->k_sch[4] = ff(ss[4] = word_in(in_key + 16)); + cx->k_sch[5] = ff(ss[5] = word_in(in_key + 20)); + kdf6(cx->k_sch, 0); kd6(cx->k_sch, 1); + kd6(cx->k_sch, 2); kd6(cx->k_sch, 3); + kd6(cx->k_sch, 4); kd6(cx->k_sch, 5); + kd6(cx->k_sch, 6); kdl6(cx->k_sch, 7); + cx->n_rnd = 12; break; + case 32: cx->k_sch[4] = ff(ss[4] = word_in(in_key + 16)); + cx->k_sch[5] = ff(ss[5] = word_in(in_key + 20)); + cx->k_sch[6] = ff(ss[6] = word_in(in_key + 24)); + cx->k_sch[7] = ff(ss[7] = word_in(in_key + 28)); + kdf8(cx->k_sch, 0); kd8(cx->k_sch, 1); + kd8(cx->k_sch, 2); kd8(cx->k_sch, 3); + kd8(cx->k_sch, 4); kd8(cx->k_sch, 5); + kdl8(cx->k_sch, 6); + cx->n_rnd = 14; break; + default: cx->n_rnd = 0; return aes_bad; + } +#else + { aes_32t i, l; + cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6; + l = (nc * cx->n_rnd + nc - 1) / (klen >> 2); + + switch(klen) + { + case 16: + for(i = 0; i < l; ++i) + ke4(cx->k_sch, i); + break; + case 24: cx->k_sch[4] = ss[4] = word_in(in_key + 16); + cx->k_sch[5] = ss[5] = word_in(in_key + 20); + for(i = 0; i < l; ++i) + ke6(cx->k_sch, i); + break; + case 32: cx->k_sch[4] = ss[4] = word_in(in_key + 16); + cx->k_sch[5] = ss[5] = word_in(in_key + 20); + cx->k_sch[6] = ss[6] = word_in(in_key + 24); + cx->k_sch[7] = ss[7] = word_in(in_key + 28); + for(i = 0; i < l; ++i) + ke8(cx->k_sch, i); + break; + default: cx->n_rnd = 0; return aes_bad; + } +#if (DEC_ROUND != NO_TABLES) + for(i = nc; i < nc * cx->n_rnd; ++i) + cx->k_sch[i] = inv_mcol(cx->k_sch[i]); +#endif + } +#endif + + return aes_good; +} + +#endif diff --git a/CPP/7zip/Crypto/AES/aesopt.h b/CPP/7zip/Crypto/AES/aesopt.h new file mode 100755 index 00000000..bcad345f --- /dev/null +++ b/CPP/7zip/Crypto/AES/aesopt.h @@ -0,0 +1,839 @@ +/* + ------------------------------------------------------------------------- + Copyright (c) 2001, Dr Brian Gladman , 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 +# include +#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 +#elif !defined(_WIN32) +# include +# if !defined (_ENDIAN_H) +# include +# else +# include _ENDIAN_H +# endif +#endif + +/* 2. BYTE ORDER IN 32-BIT WORDS + + To obtain the highest speed on processors with 32-bit words, this code + needs to determine the order in which bytes are packed into such words. + The following block of code is an attempt to capture the most obvious + ways in which various environemnts define byte order. It may well fail, + in which case the definitions will need to be set by editing at the + points marked **** EDIT HERE IF NECESSARY **** below. +*/ +#define AES_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */ +#define AES_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */ + +#if !defined(PLATFORM_BYTE_ORDER) +#if defined(LITTLE_ENDIAN) || defined(BIG_ENDIAN) +# if defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN) +# if defined(BYTE_ORDER) +# if (BYTE_ORDER == LITTLE_ENDIAN) +# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN +# elif (BYTE_ORDER == BIG_ENDIAN) +# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN +# endif +# endif +# elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN) +# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN +# elif !defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN) +# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN +# endif +#elif defined(_LITTLE_ENDIAN) || defined(_BIG_ENDIAN) +# if defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN) +# if defined(_BYTE_ORDER) +# if (_BYTE_ORDER == _LITTLE_ENDIAN) +# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN +# elif (_BYTE_ORDER == _BIG_ENDIAN) +# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN +# endif +# endif +# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) +# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN +# elif !defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN) +# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN +# endif +#elif 0 /* **** EDIT HERE IF NECESSARY **** */ +#define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN +#elif 0 /* **** EDIT HERE IF NECESSARY **** */ +#define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN +#elif (('1234' >> 24) == '1') +# define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN +#elif (('4321' >> 24) == '1') +# define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN +#endif +#endif + +#if !defined(PLATFORM_BYTE_ORDER) +# error Please set undetermined byte order (lines 233 or 235 of aesopt.h). +#endif + +/* 3. ASSEMBLER SUPPORT + + If the assembler code is used for encryption and decryption this file only + provides key scheduling so the following defines are used +*/ +#ifdef AES_ASM +#define ENCRYPTION_KEY_SCHEDULE +#define DECRYPTION_KEY_SCHEDULE +#else + +/* 4. FUNCTIONS REQUIRED + + This implementation provides five main subroutines which provide for + setting block length, setting encryption and decryption keys and for + encryption and decryption. When the assembler code is not being used + the following definition blocks allow the selection of the routines + that are to be included in the compilation. +*/ +#if 1 +#define ENCRYPTION_KEY_SCHEDULE +#endif + +#if 1 +#define DECRYPTION_KEY_SCHEDULE +#endif + +#if 1 +#define ENCRYPTION +#endif + +#if 1 +#define DECRYPTION +#endif + +#endif + +/* 5. BYTE ORDER WITHIN 32 BIT WORDS + + The fundamental data processing units in Rijndael are 8-bit bytes. The + input, output and key input are all enumerated arrays of bytes in which + bytes are numbered starting at zero and increasing to one less than the + number of bytes in the array in question. This enumeration is only used + for naming bytes and does not imply any adjacency or order relationship + from one byte to another. When these inputs and outputs are considered + as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to + byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte. + In this implementation bits are numbered from 0 to 7 starting at the + numerically least significant end of each byte (bit n represents 2^n). + + However, Rijndael can be implemented more efficiently using 32-bit + words by packing bytes into words so that bytes 4*n to 4*n+3 are placed + into word[n]. While in principle these bytes can be assembled into words + in any positions, this implementation only supports the two formats in + which bytes in adjacent positions within words also have adjacent byte + numbers. This order is called big-endian if the lowest numbered bytes + in words have the highest numeric significance and little-endian if the + opposite applies. + + This code can work in either order irrespective of the order used by the + machine on which it runs. Normally the internal byte order will be set + to the order of the processor on which the code is to be run but this + define can be used to reverse this in special situations +*/ +#if 1 +#define INTERNAL_BYTE_ORDER PLATFORM_BYTE_ORDER +#elif defined(AES_LITTLE_ENDIAN) +#define INTERNAL_BYTE_ORDER AES_LITTLE_ENDIAN +#elif defined(AES_BIG_ENDIAN) +#define INTERNAL_BYTE_ORDER AES_BIG_ENDIAN +#endif + +/* 6. FAST INPUT/OUTPUT OPERATIONS. + + On some machines it is possible to improve speed by transferring the + bytes in the input and output arrays to and from the internal 32-bit + variables by addressing these arrays as if they are arrays of 32-bit + words. On some machines this will always be possible but there may + be a large performance penalty if the byte arrays are not aligned on + the normal word boundaries. On other machines this technique will + lead to memory access errors when such 32-bit word accesses are not + properly aligned. The option SAFE_IO avoids such problems but will + often be slower on those machines that support misaligned access + (especially so if care is taken to align the input and output byte + arrays on 32-bit word boundaries). If SAFE_IO is not defined it is + assumed that access to byte arrays as if they are arrays of 32-bit + words will not cause problems when such accesses are misaligned. +*/ +#if 1 +#define SAFE_IO +#endif + +/* 7. LOOP UNROLLING + + The code for encryption and decrytpion cycles through a number of rounds + that can be implemented either in a loop or by expanding the code into a + long sequence of instructions, the latter producing a larger program but + one that will often be much faster. The latter is called loop unrolling. + There are also potential speed advantages in expanding two iterations in + a loop with half the number of iterations, which is called partial loop + unrolling. The following options allow partial or full loop unrolling + to be set independently for encryption and decryption +*/ +#if 1 +#define ENC_UNROLL FULL +#elif 0 +#define ENC_UNROLL PARTIAL +#else +#define ENC_UNROLL NONE +#endif + +// 7-Zip: Small size for SFX +#ifdef _SFX +#define DEC_UNROLL NONE +#else + +#if 1 +#define DEC_UNROLL FULL +#elif 0 +#define DEC_UNROLL PARTIAL +#else +#define DEC_UNROLL NONE +#endif + +#endif + +/* 8. FIXED OR DYNAMIC TABLES + + When this section is included the tables used by the code are comipled + statically into the binary file. Otherwise they are computed once when + the code is first used. +*/ +#if 0 +#define FIXED_TABLES +#endif + +/* 9. FAST FINITE FIELD OPERATIONS + + If this section is included, tables are used to provide faster finite + field arithmetic (this has no effect if FIXED_TABLES is defined). +*/ +#if 1 +#define FF_TABLES +#endif + +/* 10. INTERNAL STATE VARIABLE FORMAT + + The internal state of Rijndael is stored in a number of local 32-bit + word varaibles which can be defined either as an array or as individual + names variables. Include this section if you want to store these local + varaibles in arrays. Otherwise individual local variables will be used. +*/ +#if 1 +#define ARRAYS +#endif + +/* In this implementation the columns of the state array are each held in + 32-bit words. The state array can be held in various ways: in an array + of words, in a number of individual word variables or in a number of + processor registers. The following define maps a variable name x and + a column number c to the way the state array variable is to be held. + The first define below maps the state into an array x[c] whereas the + second form maps the state into a number of individual variables x0, + x1, etc. Another form could map individual state colums to machine + register names. +*/ + +#if defined(ARRAYS) +#define s(x,c) x[c] +#else +#define s(x,c) x##c +#endif + +/* 11. VARIABLE BLOCK SIZE SPEED + + This section is only relevant if you wish to use the variable block + length feature of the code. Include this section if you place more + emphasis on speed rather than code size. +*/ +#if 1 +#define FAST_VARIABLE +#endif + +/* 12. INTERNAL TABLE CONFIGURATION + + This cipher proceeds by repeating in a number of cycles known as 'rounds' + which are implemented by a round function which can optionally be speeded + up using tables. The basic tables are each 256 32-bit words, with either + one or four tables being required for each round function depending on + how much speed is required. The encryption and decryption round functions + are different and the last encryption and decrytpion round functions are + different again making four different round functions in all. + + This means that: + 1. Normal encryption and decryption rounds can each use either 0, 1 + or 4 tables and table spaces of 0, 1024 or 4096 bytes each. + 2. The last encryption and decryption rounds can also use either 0, 1 + or 4 tables and table spaces of 0, 1024 or 4096 bytes each. + + Include or exclude the appropriate definitions below to set the number + of tables used by this implementation. +*/ + +#if 1 /* set tables for the normal encryption round */ +#define ENC_ROUND FOUR_TABLES +#elif 0 +#define ENC_ROUND ONE_TABLE +#else +#define ENC_ROUND NO_TABLES +#endif + +#if 1 /* set tables for the last encryption round */ +#define LAST_ENC_ROUND FOUR_TABLES +#elif 0 +#define LAST_ENC_ROUND ONE_TABLE +#else +#define LAST_ENC_ROUND NO_TABLES +#endif + +#if 1 /* set tables for the normal decryption round */ +#define DEC_ROUND FOUR_TABLES +#elif 0 +#define DEC_ROUND ONE_TABLE +#else +#define DEC_ROUND NO_TABLES +#endif + +#if 1 /* set tables for the last decryption round */ +#define LAST_DEC_ROUND FOUR_TABLES +#elif 0 +#define LAST_DEC_ROUND ONE_TABLE +#else +#define LAST_DEC_ROUND NO_TABLES +#endif + +/* The decryption key schedule can be speeded up with tables in the same + way that the round functions can. Include or exclude the following + defines to set this requirement. +*/ +#if 1 +#define KEY_SCHED FOUR_TABLES +#elif 0 +#define KEY_SCHED ONE_TABLE +#else +#define KEY_SCHED NO_TABLES +#endif + +/* END OF CONFIGURATION OPTIONS */ + +#define NO_TABLES 0 /* DO NOT CHANGE */ +#define ONE_TABLE 1 /* DO NOT CHANGE */ +#define FOUR_TABLES 4 /* DO NOT CHANGE */ +#define NONE 0 /* DO NOT CHANGE */ +#define PARTIAL 1 /* DO NOT CHANGE */ +#define FULL 2 /* DO NOT CHANGE */ + +#if defined(BLOCK_SIZE) && ((BLOCK_SIZE & 3) || BLOCK_SIZE < 16 || BLOCK_SIZE > 32) +#error An illegal block size has been specified. +#endif + +#if !defined(BLOCK_SIZE) +#define RC_LENGTH 29 +#else +#define RC_LENGTH 5 * BLOCK_SIZE / 4 - (BLOCK_SIZE == 16 ? 10 : 11) +#endif + +/* Disable at least some poor combinations of options */ + +#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES +#undef LAST_ENC_ROUND +#define LAST_ENC_ROUND NO_TABLES +#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES +#undef LAST_ENC_ROUND +#define LAST_ENC_ROUND ONE_TABLE +#endif + +#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE +#undef ENC_UNROLL +#define ENC_UNROLL NONE +#endif + +#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES +#undef LAST_DEC_ROUND +#define LAST_DEC_ROUND NO_TABLES +#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES +#undef LAST_DEC_ROUND +#define LAST_DEC_ROUND ONE_TABLE +#endif + +#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE +#undef DEC_UNROLL +#define DEC_UNROLL NONE +#endif + +/* upr(x,n): rotates bytes within words by n positions, moving bytes to + higher index positions with wrap around into low positions + ups(x,n): moves bytes by n positions to higher index positions in + words but without wrap around + bval(x,n): extracts a byte from a word + + NOTE: The definitions given here are intended only for use with + unsigned variables and with shift counts that are compile + time constants +*/ + +#if (INTERNAL_BYTE_ORDER == AES_LITTLE_ENDIAN) +#if defined(_MSC_VER) +#define upr(x,n) _lrotl((aes_32t)(x), 8 * (n)) +#else +#define upr(x,n) ((aes_32t)(x) << 8 * (n) | (aes_32t)(x) >> 32 - 8 * (n)) +#endif +#define ups(x,n) ((aes_32t)(x) << 8 * (n)) +#define bval(x,n) ((aes_08t)((x) >> 8 * (n))) +#define bytes2word(b0, b1, b2, b3) \ + (((aes_32t)(b3) << 24) | ((aes_32t)(b2) << 16) | ((aes_32t)(b1) << 8) | (b0)) +#endif + +#if (INTERNAL_BYTE_ORDER == AES_BIG_ENDIAN) +#define upr(x,n) ((aes_32t)(x) >> 8 * (n) | (aes_32t)(x) << 32 - 8 * (n)) +#define ups(x,n) ((aes_32t)(x) >> 8 * (n))) +#define bval(x,n) ((aes_08t)((x) >> 24 - 8 * (n))) +#define bytes2word(b0, b1, b2, b3) \ + (((aes_32t)(b0) << 24) | ((aes_32t)(b1) << 16) | ((aes_32t)(b2) << 8) | (b3)) +#endif + +#if defined(SAFE_IO) + +#define word_in(x) bytes2word((x)[0], (x)[1], (x)[2], (x)[3]) +#define word_out(x,v) { (x)[0] = bval(v,0); (x)[1] = bval(v,1); \ + (x)[2] = bval(v,2); (x)[3] = bval(v,3); } + +#elif (INTERNAL_BYTE_ORDER == PLATFORM_BYTE_ORDER) + +#define word_in(x) *(aes_32t*)(x) +#define word_out(x,v) *(aes_32t*)(x) = (v) + +#else + +#if !defined(bswap_32) +#if !defined(_MSC_VER) +#define _lrotl(x,n) ((aes_32t)(x) << n | (aes_32t)(x) >> 32 - n) +#endif +#define bswap_32(x) ((_lrotl((x),8) & 0x00ff00ff) | (_lrotl((x),24) & 0xff00ff00)) +#endif + +#define word_in(x) bswap_32(*(aes_32t*)(x)) +#define word_out(x,v) *(aes_32t*)(x) = bswap_32(v) + +#endif + +/* the finite field modular polynomial and elements */ + +#define WPOLY 0x011b +#define BPOLY 0x1b + +/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */ + +#define m1 0x80808080 +#define m2 0x7f7f7f7f +#define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * BPOLY)) + +/* The following defines provide alternative definitions of FFmulX that might + give improved performance if a fast 32-bit multiply is not available. Note + that a temporary variable u needs to be defined where FFmulX is used. + +#define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6)) +#define m4 (0x01010101 * BPOLY) +#define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4) +*/ + +/* Work out which tables are needed for the different options */ + +#ifdef AES_ASM +#ifdef ENC_ROUND +#undef ENC_ROUND +#endif +#define ENC_ROUND FOUR_TABLES +#ifdef LAST_ENC_ROUND +#undef LAST_ENC_ROUND +#endif +#define LAST_ENC_ROUND FOUR_TABLES +#ifdef DEC_ROUND +#undef DEC_ROUND +#endif +#define DEC_ROUND FOUR_TABLES +#ifdef LAST_DEC_ROUND +#undef LAST_DEC_ROUND +#endif +#define LAST_DEC_ROUND FOUR_TABLES +#ifdef KEY_SCHED +#undef KEY_SCHED +#define KEY_SCHED FOUR_TABLES +#endif +#endif + +#if defined(ENCRYPTION) || defined(AES_ASM) +#if ENC_ROUND == ONE_TABLE +#define FT1_SET +#elif ENC_ROUND == FOUR_TABLES +#define FT4_SET +#else +#define SBX_SET +#endif +#if LAST_ENC_ROUND == ONE_TABLE +#define FL1_SET +#elif LAST_ENC_ROUND == FOUR_TABLES +#define FL4_SET +#elif !defined(SBX_SET) +#define SBX_SET +#endif +#endif + +#if defined(DECRYPTION) || defined(AES_ASM) +#if DEC_ROUND == ONE_TABLE +#define IT1_SET +#elif DEC_ROUND == FOUR_TABLES +#define IT4_SET +#else +#define ISB_SET +#endif +#if LAST_DEC_ROUND == ONE_TABLE +#define IL1_SET +#elif LAST_DEC_ROUND == FOUR_TABLES +#define IL4_SET +#elif !defined(ISB_SET) +#define ISB_SET +#endif +#endif + +#if defined(ENCRYPTION_KEY_SCHEDULE) || defined(DECRYPTION_KEY_SCHEDULE) +#if KEY_SCHED == ONE_TABLE +#define LS1_SET +#define IM1_SET +#elif KEY_SCHED == FOUR_TABLES +#define LS4_SET +#define IM4_SET +#elif !defined(SBX_SET) +#define SBX_SET +#endif +#endif + +#ifdef FIXED_TABLES +#define prefx extern const +#else +#define prefx extern +extern aes_08t tab_init; +void gen_tabs(void); +#endif + +prefx aes_32t rcon_tab[29]; + +#ifdef SBX_SET +prefx aes_08t s_box[256]; +#endif + +#ifdef ISB_SET +prefx aes_08t inv_s_box[256]; +#endif + +#ifdef FT1_SET +prefx aes_32t ft_tab[256]; +#endif + +#ifdef FT4_SET +prefx aes_32t ft_tab[4][256]; +#endif + +#ifdef FL1_SET +prefx aes_32t fl_tab[256]; +#endif + +#ifdef FL4_SET +prefx aes_32t fl_tab[4][256]; +#endif + +#ifdef IT1_SET +prefx aes_32t it_tab[256]; +#endif + +#ifdef IT4_SET +prefx aes_32t it_tab[4][256]; +#endif + +#ifdef IL1_SET +prefx aes_32t il_tab[256]; +#endif + +#ifdef IL4_SET +prefx aes_32t il_tab[4][256]; +#endif + +#ifdef LS1_SET +#ifdef FL1_SET +#undef LS1_SET +#else +prefx aes_32t ls_tab[256]; +#endif +#endif + +#ifdef LS4_SET +#ifdef FL4_SET +#undef LS4_SET +#else +prefx aes_32t ls_tab[4][256]; +#endif +#endif + +#ifdef IM1_SET +prefx aes_32t im_tab[256]; +#endif + +#ifdef IM4_SET +prefx aes_32t im_tab[4][256]; +#endif + +/* Set the number of columns in nc. Note that it is important + that nc is a constant which is known at compile time if the + highest speed version of the code is needed. +*/ + +#if defined(BLOCK_SIZE) +#define nc (BLOCK_SIZE >> 2) +#else +#define nc (cx->n_blk >> 2) +#endif + +/* generic definitions of Rijndael macros that use tables */ + +#define no_table(x,box,vf,rf,c) bytes2word( \ + box[bval(vf(x,0,c),rf(0,c))], \ + box[bval(vf(x,1,c),rf(1,c))], \ + box[bval(vf(x,2,c),rf(2,c))], \ + box[bval(vf(x,3,c),rf(3,c))]) + +#define one_table(x,op,tab,vf,rf,c) \ + ( tab[bval(vf(x,0,c),rf(0,c))] \ + ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \ + ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \ + ^ op(tab[bval(vf(x,3,c),rf(3,c))],3)) + +#define four_tables(x,tab,vf,rf,c) \ + ( tab[0][bval(vf(x,0,c),rf(0,c))] \ + ^ tab[1][bval(vf(x,1,c),rf(1,c))] \ + ^ tab[2][bval(vf(x,2,c),rf(2,c))] \ + ^ tab[3][bval(vf(x,3,c),rf(3,c))]) + +#define vf1(x,r,c) (x) +#define rf1(r,c) (r) +#define rf2(r,c) ((r-c)&3) + +/* perform forward and inverse column mix operation on four bytes in long word x in */ +/* parallel. NOTE: x must be a simple variable, NOT an expression in these macros. */ + +#define dec_fmvars +#if defined(FM4_SET) /* not currently used */ +#define fwd_mcol(x) four_tables(x,fm_tab,vf1,rf1,0) +#elif defined(FM1_SET) /* not currently used */ +#define fwd_mcol(x) one_table(x,upr,fm_tab,vf1,rf1,0) +#else +#undef dec_fmvars +#define dec_fmvars aes_32t f1, f2; +#define fwd_mcol(x) (f1 = (x), f2 = FFmulX(f1), f2 ^ upr(f1 ^ f2, 3) ^ upr(f1, 2) ^ upr(f1, 1)) +#endif + +#define dec_imvars +#if defined(IM4_SET) +#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0) +#elif defined(IM1_SET) +#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0) +#else +#undef dec_imvars +#define dec_imvars aes_32t f2, f4, f8, f9; +#define inv_mcol(x) \ + (f9 = (x), f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \ + f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1)) +#endif + +#if defined(FL4_SET) +#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c) +#elif defined(LS4_SET) +#define ls_box(x,c) four_tables(x,ls_tab,vf1,rf2,c) +#elif defined(FL1_SET) +#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c) +#elif defined(LS1_SET) +#define ls_box(x,c) one_table(x,upr,ls_tab,vf1,rf2,c) +#else +#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c) +#endif + +#endif diff --git a/CPP/7zip/Crypto/AES/aestab.c b/CPP/7zip/Crypto/AES/aestab.c new file mode 100755 index 00000000..de1d7eea --- /dev/null +++ b/CPP/7zip/Crypto/AES/aestab.c @@ -0,0 +1,494 @@ +/* + ------------------------------------------------------------------------- + Copyright (c) 2001, Dr Brian Gladman , Worcester, UK. + All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and fitness for purpose. + ------------------------------------------------------------------------- + Issue Date: 29/07/2002 +*/ + +#include "aesopt.h" + +#if defined(FIXED_TABLES) || !defined(FF_TABLES) + +/* finite field arithmetic operations */ + +#define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY)) +#define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY)) +#define f8(x) ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \ + ^ (((x>>5) & 4) * WPOLY)) +#define f3(x) (f2(x) ^ x) +#define f9(x) (f8(x) ^ x) +#define fb(x) (f8(x) ^ f2(x) ^ x) +#define fd(x) (f8(x) ^ f4(x) ^ x) +#define fe(x) (f8(x) ^ f4(x) ^ f2(x)) + +#endif + +#if defined(FIXED_TABLES) + +#define sb_data(w) \ + w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\ + w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\ + w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\ + w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\ + w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\ + w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\ + w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\ + w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\ + w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\ + w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\ + w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\ + w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\ + w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\ + w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\ + w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\ + w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\ + w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\ + w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\ + w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\ + w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\ + w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\ + w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\ + w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\ + w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\ + w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\ + w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\ + w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\ + w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\ + w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\ + w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\ + w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\ + w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) + +#define isb_data(w) \ + w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\ + w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\ + w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\ + w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\ + w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\ + w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\ + w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\ + w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\ + w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\ + w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\ + w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\ + w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\ + w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\ + w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\ + w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\ + w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\ + w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\ + w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\ + w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\ + w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\ + w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\ + w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\ + w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\ + w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\ + w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\ + w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\ + w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\ + w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\ + w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\ + w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\ + w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\ + w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d), + +#define mm_data(w) \ + w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\ + w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\ + w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\ + w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\ + w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\ + w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\ + w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\ + w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\ + w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\ + w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\ + w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\ + w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\ + w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\ + w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\ + w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\ + w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\ + w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\ + w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\ + w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\ + w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\ + w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\ + w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\ + w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\ + w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\ + w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\ + w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\ + w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\ + w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\ + w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\ + w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\ + w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\ + w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff) + +#define h0(x) (x) + +/* These defines are used to ensure tables are generated in the + right format depending on the internal byte order required +*/ + +#define w0(p) bytes2word(p, 0, 0, 0) +#define w1(p) bytes2word(0, p, 0, 0) +#define w2(p) bytes2word(0, 0, p, 0) +#define w3(p) bytes2word(0, 0, 0, p) + +/* Number of elements required in this table for different + block and key lengths is: + + Rcon Table key length (bytes) + Length 16 20 24 28 32 + --------------------- + block 16 | 10 9 8 7 7 + length 20 | 14 11 10 9 9 + (bytes) 24 | 19 15 12 11 11 + 28 | 24 19 16 13 13 + 32 | 29 23 19 17 14 + + this table can be a table of bytes if the key schedule + code is adjusted accordingly +*/ + +#define u0(p) bytes2word(f2(p), p, p, f3(p)) +#define u1(p) bytes2word(f3(p), f2(p), p, p) +#define u2(p) bytes2word(p, f3(p), f2(p), p) +#define u3(p) bytes2word(p, p, f3(p), f2(p)) + +#define v0(p) bytes2word(fe(p), f9(p), fd(p), fb(p)) +#define v1(p) bytes2word(fb(p), fe(p), f9(p), fd(p)) +#define v2(p) bytes2word(fd(p), fb(p), fe(p), f9(p)) +#define v3(p) bytes2word(f9(p), fd(p), fb(p), fe(p)) + +const aes_32t rcon_tab[29] = +{ + w0(0x01), w0(0x02), w0(0x04), w0(0x08), + w0(0x10), w0(0x20), w0(0x40), w0(0x80), + w0(0x1b), w0(0x36), w0(0x6c), w0(0xd8), + w0(0xab), w0(0x4d), w0(0x9a), w0(0x2f), + w0(0x5e), w0(0xbc), w0(0x63), w0(0xc6), + w0(0x97), w0(0x35), w0(0x6a), w0(0xd4), + w0(0xb3), w0(0x7d), w0(0xfa), w0(0xef), + w0(0xc5) +}; + +#ifdef SBX_SET +const aes_08t s_box[256] = { sb_data(h0) }; +#endif +#ifdef ISB_SET +const aes_08t inv_s_box[256] = { isb_data(h0) }; +#endif + +#ifdef FT1_SET +const aes_32t ft_tab[256] = { sb_data(u0) }; +#endif +#ifdef FT4_SET +const aes_32t ft_tab[4][256] = + { { sb_data(u0) }, { sb_data(u1) }, { sb_data(u2) }, { sb_data(u3) } }; +#endif + +#ifdef FL1_SET +const aes_32t fl_tab[256] = { sb_data(w0) }; +#endif +#ifdef FL4_SET +const aes_32t fl_tab[4][256] = + { { sb_data(w0) }, { sb_data(w1) }, { sb_data(w2) }, { sb_data(w3) } }; +#endif + +#ifdef IT1_SET +const aes_32t it_tab[256] = { isb_data(v0) }; +#endif +#ifdef IT4_SET +const aes_32t it_tab[4][256] = + { { isb_data(v0) }, { isb_data(v1) }, { isb_data(v2) }, { isb_data(v3) } }; +#endif + +#ifdef IL1_SET +const aes_32t il_tab[256] = { isb_data(w0) }; +#endif +#ifdef IL4_SET +const aes_32t il_tab[4][256] = + { { isb_data(w0) }, { isb_data(w1) }, { isb_data(w2) }, { isb_data(w3) } }; +#endif + +#ifdef LS1_SET +const aes_32t ls_tab[256] = { sb_data(w0) }; +#endif +#ifdef LS4_SET +const aes_32t ls_tab[4][256] = + { { sb_data(w0) }, { sb_data(w1) }, { sb_data(w2) }, { sb_data(w3) } }; +#endif + +#ifdef IM1_SET +const aes_32t im_tab[256] = { mm_data(v0) }; +#endif +#ifdef IM4_SET +const aes_32t im_tab[4][256] = + { { mm_data(v0) }, { mm_data(v1) }, { mm_data(v2) }, { mm_data(v3) } }; +#endif + +#else /* dynamic table generation */ + +aes_08t tab_init = 0; + +#define const + +aes_32t rcon_tab[29]; + +#ifdef SBX_SET +aes_08t s_box[256]; +#endif +#ifdef ISB_SET +aes_08t inv_s_box[256]; +#endif + +#ifdef FT1_SET +aes_32t ft_tab[256]; +#endif +#ifdef FT4_SET +aes_32t ft_tab[4][256]; +#endif + +#ifdef FL1_SET +aes_32t fl_tab[256]; +#endif +#ifdef FL4_SET +aes_32t fl_tab[4][256]; +#endif + +#ifdef IT1_SET +aes_32t it_tab[256]; +#endif +#ifdef IT4_SET +aes_32t it_tab[4][256]; +#endif + +#ifdef IL1_SET +aes_32t il_tab[256]; +#endif +#ifdef IL4_SET +aes_32t il_tab[4][256]; +#endif + +#ifdef LS1_SET +aes_32t ls_tab[256]; +#endif +#ifdef LS4_SET +aes_32t ls_tab[4][256]; +#endif + +#ifdef IM1_SET +aes_32t im_tab[256]; +#endif +#ifdef IM4_SET +aes_32t im_tab[4][256]; +#endif + +#if !defined(FF_TABLES) + +/* Generate the tables for the dynamic table option + + It will generally be sensible to use tables to compute finite + field multiplies and inverses but where memory is scarse this + code might sometimes be better. But it only has effect during + initialisation so its pretty unimportant in overall terms. +*/ + +/* return 2 ^ (n - 1) where n is the bit number of the highest bit + set in x with x in the range 1 < x < 0x00000200. This form is + used so that locals within fi can be bytes rather than words +*/ + +static aes_08t hibit(const aes_32t x) +{ aes_08t r = (aes_08t)((x >> 1) | (x >> 2)); + + r |= (r >> 2); + r |= (r >> 4); + return (r + 1) >> 1; +} + +/* return the inverse of the finite field element x */ + +static aes_08t fi(const aes_08t x) +{ aes_08t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0; + + if(x < 2) return x; + + for(;;) + { + if(!n1) return v1; + + while(n2 >= n1) + { + n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2); + } + + if(!n2) return v2; + + while(n1 >= n2) + { + n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1); + } + } +} + +#else + +/* define the finite field multiplies required for Rijndael */ + +#define f2(x) ((x) ? pow[log[x] + 0x19] : 0) +#define f3(x) ((x) ? pow[log[x] + 0x01] : 0) +#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0) +#define fb(x) ((x) ? pow[log[x] + 0x68] : 0) +#define fd(x) ((x) ? pow[log[x] + 0xee] : 0) +#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0) +#define fi(x) ((x) ? pow[255 - log[x]]: 0) + +#endif + +/* The forward and inverse affine transformations used in the S-box */ + +#define fwd_affine(x) \ + (w = (aes_32t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(aes_08t)(w^(w>>8))) + +#define inv_affine(x) \ + (w = (aes_32t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(aes_08t)(w^(w>>8))) + +void gen_tabs(void) +{ aes_32t i, w; + +#if defined(FF_TABLES) + + aes_08t pow[512], log[256]; + + /* log and power tables for GF(2^8) finite field with + WPOLY as modular polynomial - the simplest primitive + root is 0x03, used here to generate the tables + */ + + i = 0; w = 1; + do + { + pow[i] = (aes_08t)w; + pow[i + 255] = (aes_08t)w; + log[w] = (aes_08t)i++; + w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0); + } + while (w != 1); + +#endif + + for(i = 0, w = 1; i < RC_LENGTH; ++i) + { + rcon_tab[i] = bytes2word(w, 0, 0, 0); + w = f2(w); + } + + for(i = 0; i < 256; ++i) + { aes_08t b; + + b = fwd_affine(fi((aes_08t)i)); + w = bytes2word(f2(b), b, b, f3(b)); + +#ifdef SBX_SET + s_box[i] = b; +#endif + +#ifdef FT1_SET /* tables for a normal encryption round */ + ft_tab[i] = w; +#endif +#ifdef FT4_SET + ft_tab[0][i] = w; + ft_tab[1][i] = upr(w,1); + ft_tab[2][i] = upr(w,2); + ft_tab[3][i] = upr(w,3); +#endif + w = bytes2word(b, 0, 0, 0); + +#ifdef FL1_SET /* tables for last encryption round (may also */ + fl_tab[i] = w; /* be used in the key schedule) */ +#endif +#ifdef FL4_SET + fl_tab[0][i] = w; + fl_tab[1][i] = upr(w,1); + fl_tab[2][i] = upr(w,2); + fl_tab[3][i] = upr(w,3); +#endif + +#ifdef LS1_SET /* table for key schedule if fl_tab above is */ + ls_tab[i] = w; /* not of the required form */ +#endif +#ifdef LS4_SET + ls_tab[0][i] = w; + ls_tab[1][i] = upr(w,1); + ls_tab[2][i] = upr(w,2); + ls_tab[3][i] = upr(w,3); +#endif + + b = fi(inv_affine((aes_08t)i)); + w = bytes2word(fe(b), f9(b), fd(b), fb(b)); + +#ifdef IM1_SET /* tables for the inverse mix column operation */ + im_tab[b] = w; +#endif +#ifdef IM4_SET + im_tab[0][b] = w; + im_tab[1][b] = upr(w,1); + im_tab[2][b] = upr(w,2); + im_tab[3][b] = upr(w,3); +#endif + +#ifdef ISB_SET + inv_s_box[i] = b; +#endif +#ifdef IT1_SET /* tables for a normal decryption round */ + it_tab[i] = w; +#endif +#ifdef IT4_SET + it_tab[0][i] = w; + it_tab[1][i] = upr(w,1); + it_tab[2][i] = upr(w,2); + it_tab[3][i] = upr(w,3); +#endif + w = bytes2word(b, 0, 0, 0); +#ifdef IL1_SET /* tables for last decryption round */ + il_tab[i] = w; +#endif +#ifdef IL4_SET + il_tab[0][i] = w; + il_tab[1][i] = upr(w,1); + il_tab[2][i] = upr(w,2); + il_tab[3][i] = upr(w,3); +#endif + } + + tab_init = 1; +} + +#endif diff --git a/CPP/7zip/Crypto/AES/makefile b/CPP/7zip/Crypto/AES/makefile new file mode 100755 index 00000000..28f99965 --- /dev/null +++ b/CPP/7zip/Crypto/AES/makefile @@ -0,0 +1,31 @@ +PROG = AES.dll +DEF_FILE = ../Codec.def +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib + +AES_OBJS = \ + $O\DllExports.obj \ + +AES_OPT_OBJS = \ + $O\MyAES.obj \ + +AES_ORIG_OBJS = \ + $O\aescrypt.obj \ + $O\aeskey.obj \ + $O\aestab.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(AES_OBJS) \ + $(AES_OPT_OBJS) \ + $(AES_ORIG_OBJS) \ + $O\resource.res + +!include "../../../Build.mak" + +$(AES_OBJS): $(*B).cpp + $(COMPL) +$(AES_OPT_OBJS): $(*B).cpp + $(COMPL_O2) +$(AES_ORIG_OBJS): $(*B).c + $(COMPL_O2_W3) diff --git a/CPP/7zip/Crypto/AES/resource.rc b/CPP/7zip/Crypto/AES/resource.rc new file mode 100755 index 00000000..1ea1bfe7 --- /dev/null +++ b/CPP/7zip/Crypto/AES/resource.rc @@ -0,0 +1,3 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("AES Codec", "AES") diff --git a/CPP/7zip/Crypto/Codec.def b/CPP/7zip/Crypto/Codec.def new file mode 100755 index 00000000..ebf73a3b --- /dev/null +++ b/CPP/7zip/Crypto/Codec.def @@ -0,0 +1,4 @@ +EXPORTS + CreateObject PRIVATE + GetNumberOfMethods PRIVATE + GetMethodProperty PRIVATE diff --git a/CPP/7zip/Crypto/Hash/HmacSha1.cpp b/CPP/7zip/Crypto/Hash/HmacSha1.cpp new file mode 100755 index 00000000..a5c20a75 --- /dev/null +++ b/CPP/7zip/Crypto/Hash/HmacSha1.cpp @@ -0,0 +1,109 @@ +// HmacSha1.cpp + +#include "StdAfx.h" + +#include "HmacSha1.h" + +namespace NCrypto { +namespace NSha1 { + +void CHmac::SetKey(const Byte *key, size_t keySize) +{ + Byte keyTemp[kBlockSize]; + size_t i; + for (i = 0; i < kBlockSize; i++) + keyTemp[i] = 0; + if(keySize > kBlockSize) + { + _sha.Init(); + _sha.Update(key, keySize); + _sha.Final(keyTemp); + keySize = kDigestSize; + } + else + for (i = 0; i < keySize; i++) + keyTemp[i] = key[i]; + for (i = 0; i < kBlockSize; i++) + keyTemp[i] ^= 0x36; + _sha.Init(); + _sha.Update(keyTemp, kBlockSize); + for (i = 0; i < kBlockSize; i++) + keyTemp[i] ^= 0x36 ^ 0x5C; + _sha2.Init(); + _sha2.Update(keyTemp, kBlockSize); +} + +void CHmac::Final(Byte *mac, size_t macSize) +{ + Byte digest[kDigestSize]; + _sha.Final(digest); + _sha2.Update(digest, kDigestSize); + _sha2.Final(digest); + for(size_t i = 0; i < macSize; i++) + mac[i] = digest[i]; +} + + +void CHmac32::SetKey(const Byte *key, size_t keySize) +{ + UInt32 keyTemp[kBlockSizeInWords]; + size_t i; + for (i = 0; i < kBlockSizeInWords; i++) + keyTemp[i] = 0; + if(keySize > kBlockSize) + { + CContext sha; + sha.Init(); + sha.Update(key, keySize); + Byte digest[kDigestSize]; + sha.Final(digest); + + for (int i = 0 ; i < kDigestSizeInWords; i++) + keyTemp[i] = + ((UInt32)(digest[i * 4 + 0]) << 24) | + ((UInt32)(digest[i * 4 + 1]) << 16) | + ((UInt32)(digest[i * 4 + 2]) << 8) | + ((UInt32)(digest[i * 4 + 3])); + keySize = kDigestSizeInWords; + } + else + for (size_t i = 0; i < keySize; i++) + keyTemp[i / 4] |= (key[i] << (24 - 8 * (i & 3))); + for (i = 0; i < kBlockSizeInWords; i++) + keyTemp[i] ^= 0x36363636; + _sha.Init(); + _sha.Update(keyTemp, kBlockSizeInWords); + for (i = 0; i < kBlockSizeInWords; i++) + keyTemp[i] ^= 0x36363636 ^ 0x5C5C5C5C; + _sha2.Init(); + _sha2.Update(keyTemp, kBlockSizeInWords); +} + +void CHmac32::Final(UInt32 *mac, size_t macSize) +{ + UInt32 digest[kDigestSizeInWords]; + _sha.Final(digest); + _sha2.Update(digest, kDigestSizeInWords); + _sha2.Final(digest); + for(size_t i = 0; i < macSize; i++) + mac[i] = digest[i]; +} + +void CHmac32::GetLoopXorDigest(UInt32 *mac, UInt32 numIteration) +{ + UInt32 block[kBlockSizeInWords]; + UInt32 block2[kBlockSizeInWords]; + _sha.PrepareBlock(block, kDigestSizeInWords); + _sha2.PrepareBlock(block2, kDigestSizeInWords); + for(unsigned int s = 0; s < kDigestSizeInWords; s++) + block[s] = mac[s]; + for(UInt32 i = 0; i < numIteration; i++) + { + _sha.GetBlockDigest(block, block2); + _sha2.GetBlockDigest(block2, block); + for (unsigned int s = 0; s < kDigestSizeInWords; s++) + mac[s] ^= block[s]; + } +} + +}} diff --git a/CPP/7zip/Crypto/Hash/HmacSha1.h b/CPP/7zip/Crypto/Hash/HmacSha1.h new file mode 100755 index 00000000..bca5bcf8 --- /dev/null +++ b/CPP/7zip/Crypto/Hash/HmacSha1.h @@ -0,0 +1,39 @@ +// HmacSha1.h +// Implements HMAC-SHA-1 (RFC2104, FIPS-198) + +#ifndef _HMAC_H +#define _HMAC_H + +#include "Sha1.h" + +namespace NCrypto { +namespace NSha1 { + +// Use: SetKey(key, keySize); for () Update(data, size); Final(mac, macSize); + +class CHmac +{ + CContext _sha; + CContext _sha2; +public: + void SetKey(const Byte *key, size_t keySize); + void Update(const Byte *data, size_t dataSize) { _sha.Update(data, dataSize); } + void Final(Byte *mac, size_t macSize = kDigestSize); +}; + +class CHmac32 +{ + CContext32 _sha; + CContext32 _sha2; +public: + void SetKey(const Byte *key, size_t keySize); + void Update(const UInt32 *data, size_t dataSize) { _sha.Update(data, dataSize); } + void Final(UInt32 *mac, size_t macSize = kDigestSizeInWords); + + // It'sa for hmac function. in,out: mac[kDigestSizeInWords]. + void GetLoopXorDigest(UInt32 *mac, UInt32 numIteration); +}; + +}} + +#endif diff --git a/CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.cpp b/CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.cpp new file mode 100755 index 00000000..b11881b7 --- /dev/null +++ b/CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.cpp @@ -0,0 +1,83 @@ +// Pbkdf2HmacSha1.cpp + +#include "StdAfx.h" + +#include "HmacSha1.h" + +namespace NCrypto { +namespace NSha1 { + +void Pbkdf2Hmac(const Byte *pwd, size_t pwdSize, const Byte *salt, size_t saltSize, + UInt32 numIterations, Byte *key, size_t keySize) +{ + CHmac baseCtx; + baseCtx.SetKey(pwd, pwdSize); + for (UInt32 i = 1; keySize > 0; i++) + { + CHmac ctx = baseCtx; + ctx.Update(salt, saltSize); + Byte u[kDigestSize] = { (Byte)(i >> 24), (Byte)(i >> 16), (Byte)(i >> 8), (Byte)(i) }; + const unsigned int curSize = (keySize < kDigestSize) ? (unsigned int)keySize : kDigestSize; + ctx.Update(u, 4); + ctx.Final(u, kDigestSize); + + unsigned int s; + for (s = 0; s < curSize; s++) + key[s] = u[s]; + + for (UInt32 j = numIterations; j > 1; j--) + { + ctx = baseCtx; + ctx.Update(u, kDigestSize); + ctx.Final(u, kDigestSize); + for (s = 0; s < curSize; s++) + key[s] ^= u[s]; + } + + key += curSize; + keySize -= curSize; + } +} + +void Pbkdf2Hmac32(const Byte *pwd, size_t pwdSize, const UInt32 *salt, size_t saltSize, + UInt32 numIterations, UInt32 *key, size_t keySize) +{ + CHmac32 baseCtx; + baseCtx.SetKey(pwd, pwdSize); + for (UInt32 i = 1; keySize > 0; i++) + { + CHmac32 ctx = baseCtx; + ctx.Update(salt, saltSize); + UInt32 u[kDigestSizeInWords] = { i }; + const unsigned int curSize = (keySize < kDigestSizeInWords) ? (unsigned int)keySize : kDigestSizeInWords; + ctx.Update(u, 1); + ctx.Final(u, kDigestSizeInWords); + + // Speed-optimized code start + ctx = baseCtx; + ctx.GetLoopXorDigest(u, numIterations - 1); + // Speed-optimized code end + + unsigned int s; + for (s = 0; s < curSize; s++) + key[s] = u[s]; + + /* + // Default code start + for (UInt32 j = numIterations; j > 1; j--) + { + ctx = baseCtx; + ctx.Update(u, kDigestSizeInWords); + ctx.Final(u, kDigestSizeInWords); + for (s = 0; s < curSize; s++) + key[s] ^= u[s]; + } + // Default code end + */ + + key += curSize; + keySize -= curSize; + } +} + +}} diff --git a/CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.h b/CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.h new file mode 100755 index 00000000..00a5e009 --- /dev/null +++ b/CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.h @@ -0,0 +1,21 @@ +// Pbkdf2HmacSha1.h +// Password-Based Key Derivation Function (RFC 2898, PKCS #5) based on HMAC-SHA-1 + +#ifndef __PBKDF2HMACSHA1_H +#define __PBKDF2HMACSHA1_H + +#include +#include "../../../Common/Types.h" + +namespace NCrypto { +namespace NSha1 { + +void Pbkdf2Hmac(const Byte *pwd, size_t pwdSize, const Byte *salt, size_t saltSize, + UInt32 numIterations, Byte *key, size_t keySize); + +void Pbkdf2Hmac32(const Byte *pwd, size_t pwdSize, const UInt32 *salt, size_t saltSize, + UInt32 numIterations, UInt32 *key, size_t keySize); + +}} + +#endif diff --git a/CPP/7zip/Crypto/Hash/RandGen.cpp b/CPP/7zip/Crypto/Hash/RandGen.cpp new file mode 100755 index 00000000..480e04ca --- /dev/null +++ b/CPP/7zip/Crypto/Hash/RandGen.cpp @@ -0,0 +1,78 @@ +// RandGen.cpp + +#include "StdAfx.h" + +#include + +#include "Windows/Synchronization.h" + +#include "RandGen.h" + +// This is not very good random number generator. +// Please use it only for salt. +// First genrated data block depends from timer. +// Other genrated data blocks depend from previous state +// Maybe it's possible to restore original timer vaue from generated value. + +void CRandomGenerator::Init() +{ + NCrypto::NSha1::CContext hash; + hash.Init(); + + #ifdef _WIN32 + DWORD w = ::GetCurrentProcessId(); + hash.Update((const Byte *)&w, sizeof(w)); + w = ::GetCurrentThreadId(); + hash.Update((const Byte *)&w, sizeof(w)); + #endif + + for (int i = 0; i < 1000; i++) + { + #ifdef _WIN32 + LARGE_INTEGER v; + if (::QueryPerformanceCounter(&v)) + hash.Update((const Byte *)&v.QuadPart, sizeof(v.QuadPart)); + #endif + + DWORD tickCount = ::GetTickCount(); + hash.Update((const Byte *)&tickCount, sizeof(tickCount)); + + for (int j = 0; j < 100; j++) + { + hash.Final(_buff); + hash.Init(); + hash.Update(_buff, NCrypto::NSha1::kDigestSize); + } + } + hash.Final(_buff); + _needInit = false; +} + +static NWindows::NSynchronization::CCriticalSection g_CriticalSection; + +void CRandomGenerator::Generate(Byte *data, unsigned int size) +{ + g_CriticalSection.Enter(); + if (_needInit) + Init(); + while (size > 0) + { + NCrypto::NSha1::CContext hash; + + hash.Init(); + hash.Update(_buff, NCrypto::NSha1::kDigestSize); + hash.Final(_buff); + + hash.Init(); + UInt32 salt = 0xF672ABD1; + hash.Update((const Byte *)&salt, sizeof(salt)); + hash.Update(_buff, NCrypto::NSha1::kDigestSize); + Byte buff[NCrypto::NSha1::kDigestSize]; + hash.Final(buff); + for (unsigned int i = 0; i < NCrypto::NSha1::kDigestSize && size > 0; i++, size--) + *data++ = buff[i]; + } + g_CriticalSection.Leave(); +} + +CRandomGenerator g_RandomGenerator; diff --git a/CPP/7zip/Crypto/Hash/RandGen.h b/CPP/7zip/Crypto/Hash/RandGen.h new file mode 100755 index 00000000..3b58a032 --- /dev/null +++ b/CPP/7zip/Crypto/Hash/RandGen.h @@ -0,0 +1,21 @@ +// RandGen.h + +#ifndef __RANDGEN_H +#define __RANDGEN_H + +#include "Sha1.h" + +class CRandomGenerator +{ + Byte _buff[NCrypto::NSha1::kDigestSize]; + bool _needInit; + + void Init(); +public: + CRandomGenerator(): _needInit(true) {}; + void Generate(Byte *data, unsigned int size); +}; + +extern CRandomGenerator g_RandomGenerator; + +#endif diff --git a/CPP/7zip/Crypto/Hash/RotateDefs.h b/CPP/7zip/Crypto/Hash/RotateDefs.h new file mode 100755 index 00000000..832e7357 --- /dev/null +++ b/CPP/7zip/Crypto/Hash/RotateDefs.h @@ -0,0 +1,19 @@ +// RotateDefs.h + +#ifndef __ROTATEDEFS_H +#define __ROTATEDEFS_H + +#ifdef _MSC_VER + +#include +#define rotlFixed(x, n) _rotl((x), (n)) +#define rotrFixed(x, n) _rotr((x), (n)) + +#else + +#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) +#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n)))) + +#endif + +#endif diff --git a/CPP/7zip/Crypto/Hash/Sha1.cpp b/CPP/7zip/Crypto/Hash/Sha1.cpp new file mode 100755 index 00000000..0e1d2ecf --- /dev/null +++ b/CPP/7zip/Crypto/Hash/Sha1.cpp @@ -0,0 +1,210 @@ +// Sha1.cpp +// This file is based on public domain +// Steve Reid and Wei Dai's code from Crypto++ + +#include "StdAfx.h" + +#include "Sha1.h" +#include "RotateDefs.h" + +namespace NCrypto { +namespace NSha1 { + +// define it for speed optimization +// #define _SHA1_UNROLL + +static const unsigned int kNumW = + #ifdef _SHA1_UNROLL + 16; + #else + 80; + #endif + + +#define w0(i) (W[(i)] = data[(i)]) + +#ifdef _SHA1_UNROLL +#define w1(i) (W[(i)&15] = rotlFixed(W[((i)-3)&15] ^ W[((i)-8)&15] ^ W[((i)-14)&15] ^ W[((i)-16)&15], 1)) +#else +#define w1(i) (W[(i)] = rotlFixed(W[(i)-3] ^ W[(i)-8] ^ W[(i)-14] ^ W[(i)-16], 1)) +#endif + +#define f1(x,y,z) (z^(x&(y^z))) +#define f2(x,y,z) (x^y^z) +#define f3(x,y,z) ((x&y)|(z&(x|y))) +#define f4(x,y,z) (x^y^z) + +#define RK1(a,b,c,d,e,i, f, w, k) e += f(b,c,d) + w(i) + k + rotlFixed(a,5); b = rotlFixed(b,30); + +#define R0(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f1, w0, 0x5A827999) +#define R1(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f1, w1, 0x5A827999) +#define R2(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f2, w1, 0x6ED9EBA1) +#define R3(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f3, w1, 0x8F1BBCDC) +#define R4(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f4, w1, 0xCA62C1D6) + +#define RX_1_4(rx1, rx4, i) rx1(a,b,c,d,e,i); rx4(e,a,b,c,d,i+1); rx4(d,e,a,b,c,i+2); rx4(c,d,e,a,b,i+3); rx4(b,c,d,e,a,i+4); +#define RX_5(rx, i) RX_1_4(rx, rx, i); + +void CContextBase::Init() +{ + _state[0] = 0x67452301; + _state[1] = 0xEFCDAB89; + _state[2] = 0x98BADCFE; + _state[3] = 0x10325476; + _state[4] = 0xC3D2E1F0; + _count = 0; +} + +void CContextBase::GetBlockDigest(UInt32 *data, UInt32 *destDigest, bool returnRes) +{ + UInt32 a, b, c, d, e; + UInt32 W[kNumW]; + + a = _state[0]; + b = _state[1]; + c = _state[2]; + d = _state[3]; + e = _state[4]; + #ifdef _SHA1_UNROLL + RX_5(R0, 0); RX_5(R0, 5); RX_5(R0, 10); + #else + int i; + for (i = 0; i < 15; i += 5) { RX_5(R0, i); } + #endif + + RX_1_4(R0, R1, 15); + + + #ifdef _SHA1_UNROLL + RX_5(R2, 20); RX_5(R2, 25); RX_5(R2, 30); RX_5(R2, 35); + RX_5(R3, 40); RX_5(R3, 45); RX_5(R3, 50); RX_5(R3, 55); + RX_5(R4, 60); RX_5(R4, 65); RX_5(R4, 70); RX_5(R4, 75); + #else + i = 20; + for (; i < 40; i += 5) { RX_5(R2, i); } + for (; i < 60; i += 5) { RX_5(R3, i); } + for (; i < 80; i += 5) { RX_5(R4, i); } + #endif + + destDigest[0] = _state[0] + a; + destDigest[1] = _state[1] + b; + destDigest[2] = _state[2] + c; + destDigest[3] = _state[3] + d; + destDigest[4] = _state[4] + e; + + if (returnRes) + for (int i = 0 ; i < 16; i++) + data[i] = W[kNumW - 16 + i]; + + // Wipe variables + // a = b = c = d = e = 0; +} + +void CContextBase::PrepareBlock(UInt32 *block, unsigned int size) const +{ + unsigned int curBufferPos = size & 0xF; + block[curBufferPos++] = 0x80000000; + while (curBufferPos != (16 - 2)) + block[curBufferPos++] = 0; + const UInt64 lenInBits = (_count << 9) + ((UInt64)size << 5); + block[curBufferPos++] = (UInt32)(lenInBits >> 32); + block[curBufferPos++] = (UInt32)(lenInBits); +} + +void CContext::Update(Byte *data, size_t size, bool rar350Mode) +{ + bool returnRes = false; + unsigned int curBufferPos = _count2; + while (size-- > 0) + { + int pos = (int)(curBufferPos & 3); + if (pos == 0) + _buffer[curBufferPos >> 2] = 0; + _buffer[curBufferPos >> 2] |= ((UInt32)*data++) << (8 * (3 - pos)); + if (++curBufferPos == kBlockSize) + { + curBufferPos = 0; + CContextBase::UpdateBlock(_buffer, returnRes); + if (returnRes) + for (int i = 0; i < kBlockSizeInWords; i++) + { + UInt32 d = _buffer[i]; + data[i * 4 + 0 - kBlockSize] = (Byte)(d); + data[i * 4 + 1 - kBlockSize] = (Byte)(d >> 8); + data[i * 4 + 2 - kBlockSize] = (Byte)(d >> 16); + data[i * 4 + 3 - kBlockSize] = (Byte)(d >> 24); + } + returnRes = rar350Mode; + } + } + _count2 = curBufferPos; +} + +void CContext::Final(Byte *digest) +{ + const UInt64 lenInBits = (_count << 9) + ((UInt64)_count2 << 3); + unsigned int curBufferPos = _count2; + int pos = (int)(curBufferPos & 3); + curBufferPos >>= 2; + if (pos == 0) + _buffer[curBufferPos] = 0; + _buffer[curBufferPos++] |= ((UInt32)0x80) << (8 * (3 - pos)); + + while (curBufferPos != (16 - 2)) + { + curBufferPos &= 0xF; + if (curBufferPos == 0) + UpdateBlock(); + _buffer[curBufferPos++] = 0; + } + _buffer[curBufferPos++] = (UInt32)(lenInBits >> 32); + _buffer[curBufferPos++] = (UInt32)(lenInBits); + UpdateBlock(); + + int i; + for (i = 0; i < kDigestSizeInWords; i++) + { + UInt32 state = _state[i] & 0xFFFFFFFF; + *digest++ = (Byte)(state >> 24); + *digest++ = (Byte)(state >> 16); + *digest++ = (Byte)(state >> 8); + *digest++ = (Byte)(state); + } + Init(); +} + +/////////////////////////// +// Words version + +void CContext32::Update(const UInt32 *data, size_t size) +{ + while (size-- > 0) + { + _buffer[_count2++] = *data++; + if (_count2 == kBlockSizeInWords) + { + _count2 = 0; + UpdateBlock(); + } + } +} + +void CContext32::Final(UInt32 *digest) +{ + const UInt64 lenInBits = (_count << 9) + ((UInt64)_count2 << 5); + unsigned int curBufferPos = _count2; + _buffer[curBufferPos++] = 0x80000000; + while (curBufferPos != (16 - 2)) + { + curBufferPos &= 0xF; + if (curBufferPos == 0) + UpdateBlock(); + _buffer[curBufferPos++] = 0; + } + _buffer[curBufferPos++] = (UInt32)(lenInBits >> 32); + _buffer[curBufferPos++] = (UInt32)(lenInBits); + GetBlockDigest(_buffer, digest); + Init(); +} + +}} diff --git a/CPP/7zip/Crypto/Hash/Sha1.h b/CPP/7zip/Crypto/Hash/Sha1.h new file mode 100755 index 00000000..ebb11142 --- /dev/null +++ b/CPP/7zip/Crypto/Hash/Sha1.h @@ -0,0 +1,68 @@ +// Sha1.h +// This file is based on public domain +// Steve Reid and Wei Dai's code from Crypto++ + +#ifndef __SHA1_H +#define __SHA1_H + +#include +#include "../../../Common/Types.h" + +// Sha1 implementation in RAR before version 3.60 has bug: +// it changes data bytes in some cases. +// So this class supports both versions: normal_SHA and rar3Mode + +namespace NCrypto { +namespace NSha1 { + +const unsigned int kBlockSize = 64; +const unsigned int kDigestSize = 20; + +const unsigned int kBlockSizeInWords = (kBlockSize >> 2); +const unsigned int kDigestSizeInWords = (kDigestSize >> 2); + +class CContextBase +{ +protected: + UInt32 _state[5]; + UInt64 _count; + void UpdateBlock(UInt32 *data, bool returnRes = false) + { + GetBlockDigest(data, _state, returnRes); + _count++; + } +public: + void Init(); + void GetBlockDigest(UInt32 *blockData, UInt32 *destDigest, bool returnRes = false); + // PrepareBlock can be used only when size <= 13. size in Words + void PrepareBlock(UInt32 *block, unsigned int size) const; +}; + +class CContextBase2: public CContextBase +{ +protected: + unsigned int _count2; + UInt32 _buffer[kBlockSizeInWords]; + void UpdateBlock() { CContextBase::UpdateBlock(_buffer); } +public: + void Init() { CContextBase::Init(); _count2 = 0; } +}; + +class CContext: public CContextBase2 +{ +public: + void Update(Byte *data, size_t size, bool rar350Mode = false); + void Update(const Byte *data, size_t size) { Update((Byte *)data, size, false); } + void Final(Byte *digest); +}; + +class CContext32: public CContextBase2 +{ +public: + void Update(const UInt32 *data, size_t size); + void Final(UInt32 *digest); +}; + +}} + +#endif diff --git a/CPP/7zip/Crypto/Hash/Sha256.cpp b/CPP/7zip/Crypto/Hash/Sha256.cpp new file mode 100755 index 00000000..db236058 --- /dev/null +++ b/CPP/7zip/Crypto/Hash/Sha256.cpp @@ -0,0 +1,210 @@ +// Crypto/Sha256.cpp +// This code is based on code from Wei Dai's Crypto++ library. + +#include "StdAfx.h" + +#include "Sha256.h" +#include "RotateDefs.h" + +namespace NCrypto { +namespace NSha256 { + +// define it for speed optimization +// #define _SHA256_UNROLL +// #define _SHA256_UNROLL2 + +void CContext::Init() +{ + _state[0] = 0x6a09e667; + _state[1] = 0xbb67ae85; + _state[2] = 0x3c6ef372; + _state[3] = 0xa54ff53a; + _state[4] = 0x510e527f; + _state[5] = 0x9b05688c; + _state[6] = 0x1f83d9ab; + _state[7] = 0x5be0cd19; + + _count = 0; +} + +#define S0(x) (rotrFixed(x, 2) ^ rotrFixed(x,13) ^ rotrFixed(x, 22)) +#define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x, 25)) +#define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3)) +#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10)) + +#define blk0(i) (W[i] = data[i]) +#define blk2(i) (W[i&15] += s1(W[(i-2)&15]) + W[(i-7)&15] + s0(W[(i-15)&15])) + +#define Ch(x,y,z) (z^(x&(y^z))) +#define Maj(x,y,z) ((x&y)|(z&(x|y))) + +#define a(i) T[(0-(i))&7] +#define b(i) T[(1-(i))&7] +#define c(i) T[(2-(i))&7] +#define d(i) T[(3-(i))&7] +#define e(i) T[(4-(i))&7] +#define f(i) T[(5-(i))&7] +#define g(i) T[(6-(i))&7] +#define h(i) T[(7-(i))&7] + + +#ifdef _SHA256_UNROLL2 + +#define R(a,b,c,d,e,f,g,h, i) h += S1(e) + Ch(e,f,g) + K[i+j] + (j?blk2(i):blk0(i));\ + d += h; h += S0(a) + Maj(a, b, c) + +#define RX_8(i) \ + R(a,b,c,d,e,f,g,h, i); \ + R(h,a,b,c,d,e,f,g, i+1); \ + R(g,h,a,b,c,d,e,f, i+2); \ + R(f,g,h,a,b,c,d,e, i+3); \ + R(e,f,g,h,a,b,c,d, i+4); \ + R(d,e,f,g,h,a,b,c, i+5); \ + R(c,d,e,f,g,h,a,b, i+6); \ + R(b,c,d,e,f,g,h,a, i+7) + +#else + +#define R(i) h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[i+j] + (j?blk2(i):blk0(i));\ + d(i) += h(i); h(i) += S0(a(i)) + Maj(a(i), b(i), c(i)) + +#ifdef _SHA256_UNROLL + +#define RX_8(i) R(i+0); R(i+1); R(i+2); R(i+3); R(i+4); R(i+5); R(i+6); R(i+7); + +#endif + +#endif + + +void CContext::Transform(UInt32 *state, const UInt32 *data) +{ + UInt32 W[16]; + + #ifdef _SHA256_UNROLL2 + UInt32 a,b,c,d,e,f,g,h; + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + #else + UInt32 T[8]; + for (int s = 0; s < 8; s++) + T[s] = state[s]; + #endif + + for (unsigned int j = 0; j < 64; j += 16) + { + #if defined(_SHA256_UNROLL) || defined(_SHA256_UNROLL2) + RX_8(0); RX_8(8); + #else + for (unsigned int i = 0; i < 16; i++) { R(i); } + #endif + } + + #ifdef _SHA256_UNROLL2 + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; + #else + for (int i = 0; i < 8; i++) + state[i] += T[i]; + #endif + + // Wipe variables + // memset(W, 0, sizeof(W)); + // memset(T, 0, sizeof(T)); +} + +const UInt32 CContext::K[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +#undef S0 +#undef S1 +#undef s0 +#undef s1 + +void CContext::WriteByteBlock() +{ + UInt32 data32[16]; + for (int i = 0; i < 16; i++) + { + data32[i] = (UInt32(_buffer[i * 4]) << 24) + + (UInt32(_buffer[i * 4 + 1]) << 16) + + (UInt32(_buffer[i * 4 + 2]) << 8) + + UInt32(_buffer[i * 4 + 3]); + } + Transform(_state, data32); +} + +void CContext::Update(const Byte *data, size_t size) +{ + UInt32 curBufferPos = (UInt32)_count & 0x3F; + while (size > 0) + { + _buffer[curBufferPos++] = *data++; + _count++; + size--; + if (curBufferPos == 64) + { + curBufferPos = 0; + WriteByteBlock(); + } + } +} + +void CContext::Final(Byte *digest) +{ + UInt64 lenInBits = (_count << 3); + UInt32 curBufferPos = (UInt32)_count & 0x3F; + _buffer[curBufferPos++] = 0x80; + while (curBufferPos != (64 - 8)) + { + curBufferPos &= 0x3F; + if (curBufferPos == 0) + WriteByteBlock(); + _buffer[curBufferPos++] = 0; + } + for (int i = 0; i < 8; i++) + { + _buffer[curBufferPos++] = (Byte)(lenInBits >> 56); + lenInBits <<= 8; + } + WriteByteBlock(); + + for (int j = 0; j < 8; j++) + { + *digest++ = (Byte)(_state[j] >> 24); + *digest++ = (Byte)(_state[j] >> 16); + *digest++ = (Byte)(_state[j] >> 8); + *digest++ = (Byte)(_state[j]); + } + Init(); +} + +}} diff --git a/CPP/7zip/Crypto/Hash/Sha256.h b/CPP/7zip/Crypto/Hash/Sha256.h new file mode 100755 index 00000000..e4788f41 --- /dev/null +++ b/CPP/7zip/Crypto/Hash/Sha256.h @@ -0,0 +1,30 @@ +// Crypto/Sha256.h + +#ifndef __CRYPTO_SHA256_H +#define __CRYPTO_SHA256_H + +#include "Common/Types.h" + +namespace NCrypto { +namespace NSha256 { + +class CContext +{ + static const UInt32 K[64]; + + UInt32 _state[8]; + UInt64 _count; + Byte _buffer[64]; + static void Transform(UInt32 *digest, const UInt32 *data); + void WriteByteBlock(); +public: + enum {DIGESTSIZE = 32}; + CContext() { Init(); } ; + void Init(); + void Update(const Byte *data, size_t size); + void Final(Byte *digest); +}; + +}} + +#endif diff --git a/CPP/7zip/Crypto/Hash/StdAfx.h b/CPP/7zip/Crypto/Hash/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Crypto/Hash/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Crypto/Rar20/Rar20Cipher.cpp b/CPP/7zip/Crypto/Rar20/Rar20Cipher.cpp new file mode 100755 index 00000000..27ccc493 --- /dev/null +++ b/CPP/7zip/Crypto/Rar20/Rar20Cipher.cpp @@ -0,0 +1,76 @@ +// Crypto/Rar20Cipher.cpp + +#include "StdAfx.h" + +#include "Rar20Cipher.h" +#include "Windows/Defs.h" + +namespace NCrypto { +namespace NRar20 { + +static const int kBufferSize = 1 << 17; + +STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size) +{ + _coder.SetPassword(data, size); + return S_OK; +} + +STDMETHODIMP CDecoder::Init() +{ + return S_OK; +} + +STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) +{ + const UInt16 kBlockSize = 16; + if (size > 0 && size < kBlockSize) + return kBlockSize; + UInt32 i; + for (i = 0; i + kBlockSize <= size; i += kBlockSize) + { + _coder.DecryptBlock(data + i); + } + return i; +} + +/* +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + UInt64 nowPos = 0; + UInt32 bufferPos = 0; + UInt32 processedSize; + for (;;) + { + UInt32 size = kBufferSize - bufferPos; + RINOK(inStream->Read(_buffer + bufferPos, size, &processedSize)); + + UInt32 anEndPos = bufferPos + processedSize; + for (;bufferPos + 16 <= anEndPos; bufferPos += 16) + _coder.DecryptBlock(_buffer + bufferPos); + + if (bufferPos == 0) + return S_OK; + + if (outSize != NULL && nowPos + bufferPos > *outSize) + bufferPos = UInt32(*outSize - nowPos); + + RINOK(outStream->Write(_buffer, bufferPos, &processedSize)); + if (bufferPos != processedSize) + return E_FAIL; + + nowPos += processedSize; + if (outSize != NULL && nowPos == *outSize) + return S_OK; + + int i = 0; + while(bufferPos < anEndPos) + _buffer[i++] = _buffer[bufferPos++]; + bufferPos = i; + } +} +*/ + +}} diff --git a/CPP/7zip/Crypto/Rar20/Rar20Cipher.h b/CPP/7zip/Crypto/Rar20/Rar20Cipher.h new file mode 100755 index 00000000..e2091cda --- /dev/null +++ b/CPP/7zip/Crypto/Rar20/Rar20Cipher.h @@ -0,0 +1,35 @@ +// Crypto/Rar20Cipher.h + +#ifndef __CRYPTO_RAR20_CIPHER_H +#define __CRYPTO_RAR20_CIPHER_H + +#include "../../ICoder.h" +#include "../../IPassword.h" +#include "Common/MyCom.h" + +#include "Common/Types.h" +#include "Rar20Crypto.h" + +namespace NCrypto { +namespace NRar20 { + +class CDecoder: + public ICompressFilter, + public ICryptoSetPassword, + public CMyUnknownImp +{ +public: + CData _coder; + + MY_UNKNOWN_IMP1(ICryptoSetPassword) + + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + + STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); + +}; + +}} + +#endif diff --git a/CPP/7zip/Crypto/Rar20/Rar20Crypto.cpp b/CPP/7zip/Crypto/Rar20/Rar20Crypto.cpp new file mode 100755 index 00000000..d8be2279 --- /dev/null +++ b/CPP/7zip/Crypto/Rar20/Rar20Crypto.cpp @@ -0,0 +1,124 @@ +// Crypto/Rar20/Crypto.cpp + +#include "StdAfx.h" + +#include "Rar20Crypto.h" +#include "../../../Common/CRC.h" + +#define rol(x,n) (((x) << (n)) | ((x) >> (8 * sizeof(x) - (n)))) +#define ror(x,n) (((x) >> (n)) | ((x) << (8 * sizeof(x) - (n)))) + +namespace NCrypto { +namespace NRar20 { + +static const int kNumRounds = 32; + +static const Byte InitSubstTable[256] = { + 215, 19,149, 35, 73,197,192,205,249, 28, 16,119, 48,221, 2, 42, + 232, 1,177,233, 14, 88,219, 25,223,195,244, 90, 87,239,153,137, + 255,199,147, 70, 92, 66,246, 13,216, 40, 62, 29,217,230, 86, 6, + 71, 24,171,196,101,113,218,123, 93, 91,163,178,202, 67, 44,235, + 107,250, 75,234, 49,167,125,211, 83,114,157,144, 32,193,143, 36, + 158,124,247,187, 89,214,141, 47,121,228, 61,130,213,194,174,251, + 97,110, 54,229,115, 57,152, 94,105,243,212, 55,209,245, 63, 11, + 164,200, 31,156, 81,176,227, 21, 76, 99,139,188,127, 17,248, 51, + 207,120,189,210, 8,226, 41, 72,183,203,135,165,166, 60, 98, 7, + 122, 38,155,170, 69,172,252,238, 39,134, 59,128,236, 27,240, 80, + 131, 3, 85,206,145, 79,154,142,159,220,201,133, 74, 64, 20,129, + 224,185,138,103,173,182, 43, 34,254, 82,198,151,231,180, 58, 10, + 118, 26,102, 12, 50,132, 22,191,136,111,162,179, 45, 4,148,108, + 161, 56, 78,126,242,222, 15,175,146, 23, 33,241,181,190, 77,225, + 0, 46,169,186, 68, 95,237, 65, 53,208,253,168, 9, 18,100, 52, + 116,184,160, 96,109, 37, 30,106,140,104,150, 5,204,117,112, 84 +}; + +void CData::UpdateKeys(const Byte *data) +{ + for (int i = 0; i < 16; i += 4) + for (int j = 0; j < 4; j++) + Keys[j] ^= CCRC::Table[data[i + j]]; +} + +static void Swap(Byte *b1, Byte *b2) +{ + Byte b = *b1; + *b1 = *b2; + *b2 = b; +} + +void CData::SetPassword(const Byte *password, UInt32 passwordLength) +{ + // SetOldKeys(password); + + Keys[0] = 0xD3A3B879L; + Keys[1] = 0x3F6D12F7L; + Keys[2] = 0x7515A235L; + Keys[3] = 0xA4E7F123L; + + Byte psw[256]; + memset(psw, 0, sizeof(psw)); + + memmove(psw, password, passwordLength); + + memcpy(SubstTable, InitSubstTable, sizeof(SubstTable)); + for (UInt32 j = 0; j < 256; j++) + for (UInt32 i = 0; i < passwordLength; i += 2) + { + UInt32 n2 = (Byte)CCRC::Table[(psw[i + 1] + j) & 0xFF]; + UInt32 n1 = (Byte)CCRC::Table[(psw[i] - j) & 0xFF]; + for (UInt32 k = 1; (n1 & 0xFF) != n2; n1++, k++) + Swap(&SubstTable[n1 & 0xFF], &SubstTable[(n1 + i + k) & 0xFF]); + } + for (UInt32 i = 0; i < passwordLength; i+= 16) + EncryptBlock(&psw[i]); +} + +static inline UInt32 GetUInt32FromMemLE(const Byte *p) +{ + return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24); +} + +static inline void WriteUInt32ToMemLE(UInt32 v, Byte *p) +{ + p[0] = (Byte)v; + p[1] = (Byte)(v >> 8); + p[2] = (Byte)(v >> 16); + p[3] = (Byte)(v >> 24); +} + +void CData::CryptBlock(Byte *buf, bool encrypt) +{ + Byte inBuf[16]; + UInt32 A, B, C, D, T, TA, TB; + + A = GetUInt32FromMemLE(buf + 0) ^ Keys[0]; + B = GetUInt32FromMemLE(buf + 4) ^ Keys[1]; + C = GetUInt32FromMemLE(buf + 8) ^ Keys[2]; + D = GetUInt32FromMemLE(buf + 12) ^ Keys[3]; + + if (!encrypt) + memcpy(inBuf, buf, sizeof(inBuf)); + + for(int i = 0; i < kNumRounds; i++) + { + UInt32 key = Keys[(encrypt ? i : (kNumRounds - 1 - i)) & 3]; + T = ((C + rol(D, 11)) ^ key); + TA = A ^ SubstLong(T); + T = ((D ^ rol(C, 17)) + key); + TB = B ^ SubstLong(T); + A = C; + B = D; + C = TA; + D = TB; + } + + WriteUInt32ToMemLE(C ^ Keys[0], buf + 0); + WriteUInt32ToMemLE(D ^ Keys[1], buf + 4); + WriteUInt32ToMemLE(A ^ Keys[2], buf + 8); + WriteUInt32ToMemLE(B ^ Keys[3], buf + 12); + + UpdateKeys(encrypt ? buf : inBuf); +} + + +}} diff --git a/CPP/7zip/Crypto/Rar20/Rar20Crypto.h b/CPP/7zip/Crypto/Rar20/Rar20Crypto.h new file mode 100755 index 00000000..071d01f1 --- /dev/null +++ b/CPP/7zip/Crypto/Rar20/Rar20Crypto.h @@ -0,0 +1,33 @@ +// Crypto/Rar20/Crypto.h + +#ifndef __CRYPTO_RAR20_CRYPTO_H +#define __CRYPTO_RAR20_CRYPTO_H + +#include "../../../Common/Types.h" + +namespace NCrypto { +namespace NRar20 { + +class CData +{ + Byte SubstTable[256]; + UInt32 Keys[4]; + UInt32 SubstLong(UInt32 t) + { + return (UInt32)SubstTable[(int)t & 255] | + ((UInt32)SubstTable[(int)(t >> 8) & 255] << 8) | + ((UInt32)SubstTable[(int)(t >> 16) & 255] << 16) | + ((UInt32)SubstTable[(int)(t >> 24) & 255] << 24); + } + + void UpdateKeys(const Byte *data); + void CryptBlock(Byte *buf, bool encrypt); +public: + void EncryptBlock(Byte *buf) { CryptBlock(buf, true); } + void DecryptBlock(Byte *buf) { CryptBlock(buf, false); } + void SetPassword(const Byte *password, UInt32 passwordLength); +}; + +}} + +#endif diff --git a/CPP/7zip/Crypto/Rar20/StdAfx.h b/CPP/7zip/Crypto/Rar20/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Crypto/Rar20/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Crypto/RarAES/RarAES.cpp b/CPP/7zip/Crypto/RarAES/RarAES.cpp new file mode 100755 index 00000000..ae22bb2a --- /dev/null +++ b/CPP/7zip/Crypto/RarAES/RarAES.cpp @@ -0,0 +1,187 @@ +// Crypto/RarAES/RarAES.h +// This code is based on UnRar sources + +#include "StdAfx.h" + +#include "RarAES.h" +#include "../Hash/Sha1.h" + +extern void GetCryptoFolderPrefix(TCHAR *path); + +namespace NCrypto { +namespace NRar29 { + +CDecoder::CDecoder(): + _thereIsSalt(false), + _needCalculate(true), + _rar350Mode(false) +{ + for (int i = 0; i < sizeof(_salt); i++) + _salt[i] = 0; +} + +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) +{ + bool thereIsSaltPrev = _thereIsSalt; + _thereIsSalt = false; + if (size == 0) + return S_OK; + if (size < 8) + return E_INVALIDARG; + _thereIsSalt = true; + bool same = false; + if (_thereIsSalt == thereIsSaltPrev) + { + same = true; + if (_thereIsSalt) + { + for (int i = 0; i < sizeof(_salt); i++) + if (_salt[i] != data[i]) + { + same = false; + break; + } + } + } + for (int i = 0; i < sizeof(_salt); i++) + _salt[i] = data[i]; + if (!_needCalculate && !same) + _needCalculate = true; + return S_OK; +} + +static const int kMaxPasswordLength = 127 * 2; + +STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size) +{ + if (size > kMaxPasswordLength) + size = kMaxPasswordLength; + bool same = false; + if (size == buffer.GetCapacity()) + { + same = true; + for (UInt32 i = 0; i < size; i++) + if (data[i] != buffer[i]) + { + same = false; + break; + } + } + if (!_needCalculate && !same) + _needCalculate = true; + buffer.SetCapacity(size); + memcpy(buffer, data, size); + return S_OK; +} + +STDMETHODIMP CDecoder::Init() +{ + Calculate(); + RINOK(CreateFilter()); + CMyComPtr cp; + RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp)); + RINOK(cp->SetKey(aesKey, 16)); + RINOK(cp->SetInitVector(aesInit, 16)); + _aesFilter->Init(); + return S_OK; +} + +HRESULT CDecoder::CreateFilter() +{ + if (_aesFilter) + return S_OK; + TCHAR aesLibPath[MAX_PATH + 64]; + GetCryptoFolderPrefix(aesLibPath); + lstrcat(aesLibPath, TEXT("AES.dll")); + return _aesLib.LoadAndCreateFilter(aesLibPath, CLSID_CCrypto_AES_CBC_Decoder, &_aesFilter); +} + +STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) +{ + return _aesFilter->Filter(data, size); +} + +void CDecoder::Calculate() +{ + if (_needCalculate) + { + const int kSaltSize = 8; + + Byte rawPassword[kMaxPasswordLength + kSaltSize]; + + memcpy(rawPassword, buffer, buffer.GetCapacity()); + + size_t rawLength = buffer.GetCapacity(); + + if (_thereIsSalt) + { + memcpy(rawPassword + rawLength, _salt, kSaltSize); + rawLength += kSaltSize; + } + + NSha1::CContext sha; + sha.Init(); + + // seems rar reverts hash for sha. + const int hashRounds = 0x40000; + int i; + for (i = 0; i < hashRounds; i++) + { + sha.Update(rawPassword, rawLength, _rar350Mode); + Byte pswNum[3] = { (Byte)i, (Byte)(i >> 8), (Byte)(i >> 16) }; + sha.Update(pswNum, 3, _rar350Mode); + if (i % (hashRounds / 16) == 0) + { + NSha1::CContext shaTemp = sha; + Byte digest[NSha1::kDigestSize]; + shaTemp.Final(digest); + aesInit[i / (hashRounds / 16)] = (Byte)digest[4 * 4 + 3]; + } + } + /* + // it's test message for sha + const char *message = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; + sha.Update((const Byte *)message, strlen(message)); + */ + Byte digest[20]; + sha.Final(digest); + for (i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + aesKey[i * 4 + j] = (digest[i * 4 + 3 - j]); + } + _needCalculate = false; +} + + + +/* +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, UInt64 const *inSize, + const UInt64 *outSize,ICompressProgressInfo *progress) +{ + Calculate(); + TCHAR aesLibPath[MAX_PATH + 64]; + GetCryptoFolderPrefix(aesLibPath); + lstrcat(aesLibPath, TEXT("AES.dll")); + CCoderLibrary aesLib; + CMyComPtr aesDecoder; + RINOK(aesLib.LoadAndCreateCoder2(aesLibPath, CLSID_CCrypto_AES128_Decoder, &aesDecoder)); + + CSequentialInStreamImp *ivStreamSpec = new CSequentialInStreamImp; + CMyComPtr ivStream(ivStreamSpec); + ivStreamSpec->Init(aesInit, 16); + + CSequentialInStreamImp *keyStreamSpec = new CSequentialInStreamImp; + CMyComPtr keyStream(keyStreamSpec); + keyStreamSpec->Init(aesKey, 16); + + ISequentialInStream *inStreams[3] = { inStream, ivStream, keyStream }; + UInt64 ivSize = 16; + UInt64 keySize = 16; + const UInt64 *inSizes[3] = { inSize, &ivSize, &ivSize, }; + return aesDecoder->Code(inStreams, inSizes, 3, + &outStream, &outSize, 1, progress); +} +*/ + +}} diff --git a/CPP/7zip/Crypto/RarAES/RarAES.h b/CPP/7zip/Crypto/RarAES/RarAES.h new file mode 100755 index 00000000..4b435b5e --- /dev/null +++ b/CPP/7zip/Crypto/RarAES/RarAES.h @@ -0,0 +1,61 @@ +// Crypto/CRarAES/RarAES.h + +#ifndef __CRYPTO_RARAES_H +#define __CRYPTO_RARAES_H + +#include "Common/MyCom.h" +#include "../../ICoder.h" +#include "../../IPassword.h" +#include "../../Archive/Common/CoderLoader.h" + +#include "Common/Types.h" +#include "Common/Buffer.h" + +DEFINE_GUID(CLSID_CCrypto_AES_CBC_Decoder, +0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00); + +namespace NCrypto { +namespace NRar29 { + +class CDecoder: + public ICompressFilter, + public ICompressSetDecoderProperties2, + public ICryptoSetPassword, + public CMyUnknownImp +{ + Byte _salt[8]; + bool _thereIsSalt; + CByteBuffer buffer; + Byte aesKey[16]; + Byte aesInit[16]; + bool _needCalculate; + + CCoderLibrary _aesLib; + CMyComPtr _aesFilter; + + bool _rar350Mode; + + void Calculate(); + HRESULT CreateFilter(); + +public: + + MY_UNKNOWN_IMP2( + ICryptoSetPassword, + ICompressSetDecoderProperties2) + + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + + STDMETHOD(CryptoSetPassword)(const Byte *aData, UInt32 aSize); + + // ICompressSetDecoderProperties + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + + CDecoder(); + void SetRar350Mode(bool rar350Mode) { _rar350Mode = rar350Mode; } +}; + +}} + +#endif diff --git a/CPP/7zip/Crypto/RarAES/StdAfx.h b/CPP/7zip/Crypto/RarAES/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Crypto/RarAES/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Crypto/WzAES/StdAfx.cpp b/CPP/7zip/Crypto/WzAES/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/Crypto/WzAES/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/Crypto/WzAES/StdAfx.h b/CPP/7zip/Crypto/WzAES/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Crypto/WzAES/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Crypto/WzAES/WzAES.cpp b/CPP/7zip/Crypto/WzAES/WzAES.cpp new file mode 100755 index 00000000..8bf53b43 --- /dev/null +++ b/CPP/7zip/Crypto/WzAES/WzAES.cpp @@ -0,0 +1,246 @@ +// WzAES.cpp +/* +This code implements Brian Gladman's scheme +specified in password Based File Encryption Utility. +*/ + +#include "StdAfx.h" + +#include "Windows/Defs.h" +#include "../../Common/StreamObjects.h" +#include "../../Common/StreamUtils.h" +#include "../Hash/Pbkdf2HmacSha1.h" +#include "../Hash/RandGen.h" + +#include "WzAES.h" + +#ifdef CRYPTO_AES +#include "../AES/MyAES.h" +#else +extern void GetCryptoFolderPrefix(TCHAR *path); +#endif + +// define it if you don't want to use speed-optimized version of Pbkdf2HmacSha1 +// #define _NO_WZAES_OPTIMIZATIONS + +namespace NCrypto { +namespace NWzAES { + +const unsigned int kAesKeySizeMax = 32; + +static const UInt32 kNumKeyGenIterations = 1000; + +STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size) +{ + if(size > kPasswordSizeMax) + return E_INVALIDARG; + _key.Password.SetCapacity(size); + memcpy(_key.Password, data, size); + return S_OK; +} + +void CBaseCoder::EncryptData(Byte *data, UInt32 size) +{ + unsigned int pos = _blockPos; + for (; size > 0; size--) + { + if (pos == kAesBlockSize) + { + int j; + for (j = 0; j < 8 && ++_counter[j] == 0; j++); + for (j = 0; j < 8; j++) + _buffer[j] = _counter[j]; + for (; j < kAesBlockSize; j++) + _buffer[j] = 0; + _aesFilter->Filter(_buffer, kAesBlockSize); + pos = 0; + } + *data++ ^= _buffer[pos++]; + } + _blockPos = pos; +} + +#ifndef _NO_WZAES_OPTIMIZATIONS + +static void BytesToBeUInt32s(const Byte *src, UInt32 *dest, int destSize) +{ + for (int i = 0 ; i < destSize; i++) + dest[i] = + ((UInt32)(src[i * 4 + 0]) << 24) | + ((UInt32)(src[i * 4 + 1]) << 16) | + ((UInt32)(src[i * 4 + 2]) << 8) | + ((UInt32)(src[i * 4 + 3])); +} + +#endif + +STDMETHODIMP CBaseCoder::Init() +{ + UInt32 keySize = _key.GetKeySize(); + UInt32 keysTotalSize = 2 * keySize + kPwdVerifCodeSize; + Byte buf[2 * kAesKeySizeMax + kPwdVerifCodeSize]; + + // for (int ii = 0; ii < 1000; ii++) + { + #ifdef _NO_WZAES_OPTIMIZATIONS + + NSha1::Pbkdf2Hmac( + _key.Password, _key.Password.GetCapacity(), + _key.Salt, _key.GetSaltSize(), + kNumKeyGenIterations, + buf, keysTotalSize); + + #else + + UInt32 buf32[(2 * kAesKeySizeMax + kPwdVerifCodeSize + 3) / 4]; + UInt32 key32SizeTotal = (keysTotalSize + 3) / 4; + UInt32 salt[kSaltSizeMax * 4]; + UInt32 saltSizeInWords = _key.GetSaltSize() / 4; + BytesToBeUInt32s(_key.Salt, salt, saltSizeInWords); + NSha1::Pbkdf2Hmac32( + _key.Password, _key.Password.GetCapacity(), + salt, saltSizeInWords, + kNumKeyGenIterations, + buf32, key32SizeTotal); + for (UInt32 j = 0; j < keysTotalSize; j++) + buf[j] = (Byte)(buf32[j / 4] >> (24 - 8 * (j & 3))); + + #endif + } + + _hmac.SetKey(buf + keySize, keySize); + memcpy(_key.PwdVerifComputed, buf + 2 * keySize, kPwdVerifCodeSize); + + _blockPos = kAesBlockSize; + for (int i = 0; i < 8; i++) + _counter[i] = 0; + + RINOK(CreateFilters()); + CMyComPtr cp; + RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp)); + return cp->SetKey(buf, keySize); +} + +static HRESULT SafeWrite(ISequentialOutStream *outStream, const Byte *data, UInt32 size) +{ + UInt32 processedSize; + RINOK(WriteStream(outStream, data, size, &processedSize)); + return ((processedSize == size) ? S_OK : E_FAIL); +} + +/* +STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) +{ + Byte keySizeMode = 3; + return outStream->Write(&keySizeMode, 1, NULL); +} +*/ + +HRESULT CEncoder::WriteHeader(ISequentialOutStream *outStream) +{ + UInt32 saltSize = _key.GetSaltSize(); + g_RandomGenerator.Generate(_key.Salt, saltSize); + Init(); + RINOK(SafeWrite(outStream, _key.Salt, saltSize)); + return SafeWrite(outStream, _key.PwdVerifComputed, kPwdVerifCodeSize); +} + +HRESULT CEncoder::WriteFooter(ISequentialOutStream *outStream) +{ + Byte mac[kMacSize]; + _hmac.Final(mac, kMacSize); + return SafeWrite(outStream, mac, kMacSize); +} + +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) +{ + if (size != 1) + return E_INVALIDARG; + _key.Init(); + Byte keySizeMode = data[0]; + if (keySizeMode < 1 || keySizeMode > 3) + return E_INVALIDARG; + _key.KeySizeMode = keySizeMode; + return S_OK; +} + +HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream) +{ + UInt32 saltSize = _key.GetSaltSize(); + UInt32 extraSize = saltSize + kPwdVerifCodeSize; + Byte temp[kSaltSizeMax + kPwdVerifCodeSize]; + UInt32 processedSize; + RINOK(ReadStream(inStream, temp, extraSize, &processedSize)); + if (processedSize != extraSize) + return E_FAIL; + UInt32 i; + for (i = 0; i < saltSize; i++) + _key.Salt[i] = temp[i]; + for (i = 0; i < kPwdVerifCodeSize; i++) + _pwdVerifFromArchive[i] = temp[saltSize + i]; + return S_OK; +} + +static bool CompareArrays(const Byte *p1, const Byte *p2, UInt32 size) +{ + for (UInt32 i = 0; i < size; i++) + if (p1[i] != p2[i]) + return false; + return true; +} + +bool CDecoder::CheckPasswordVerifyCode() +{ + return CompareArrays(_key.PwdVerifComputed, _pwdVerifFromArchive, kPwdVerifCodeSize); +} + +HRESULT CDecoder::CheckMac(ISequentialInStream *inStream, bool &isOK) +{ + isOK = false; + UInt32 processedSize; + Byte mac1[kMacSize]; + RINOK(ReadStream(inStream, mac1, kMacSize, &processedSize)); + if (processedSize != kMacSize) + return E_FAIL; + Byte mac2[kMacSize]; + _hmac.Final(mac2, kMacSize); + isOK = CompareArrays(mac1, mac2, kMacSize); + return S_OK; +} + +STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size) +{ + EncryptData(data, size); + _hmac.Update(data, size); + return size; +} + +STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) +{ + _hmac.Update(data, size); + EncryptData(data, size); + return size; +} + + +HRESULT CBaseCoder::CreateFilters() +{ + if (!_aesFilter) + { + #ifdef CRYPTO_AES + + _aesFilter = new CAES_ECB_Encoder; + + #else + + TCHAR aesLibPath[MAX_PATH + 64]; + GetCryptoFolderPrefix(aesLibPath); + lstrcat(aesLibPath, TEXT("AES.dll")); + RINOK(_aesLibrary.LoadAndCreateFilter(aesLibPath, CLSID_CCrypto_AES_ECB_Encoder, &_aesFilter)); + + #endif + } + return S_OK; +} + +}} diff --git a/CPP/7zip/Crypto/WzAES/WzAES.h b/CPP/7zip/Crypto/WzAES/WzAES.h new file mode 100755 index 00000000..c27bd326 --- /dev/null +++ b/CPP/7zip/Crypto/WzAES/WzAES.h @@ -0,0 +1,126 @@ +// WzAES.h +/* +This code implements Brian Gladman's scheme +specified in password Based File Encryption Utility: + - AES encryption (128,192,256-bit) in Counter (CTR) mode. + - HMAC-SHA1 authentication for encrypted data (10 bytes) + - Keys are derived by PPKDF2(RFC2898)-HMAC-SHA1 from ASCII password and + Salt (saltSize = aesKeySize / 2). + - 2 bytes contain Password Verifier's Code +*/ + +#ifndef __CRYPTO_WZ_AES_H +#define __CRYPTO_WZ_AES_H + +#include "../Hash/HmacSha1.h" + +#include "Common/MyCom.h" +#include "Common/Buffer.h" +#include "Common/Vector.h" + +#include "../../ICoder.h" +#include "../../IPassword.h" + +#ifndef CRYPTO_AES +#include "../../Archive/Common/CoderLoader.h" +#endif + +DEFINE_GUID(CLSID_CCrypto_AES_ECB_Encoder, +0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0xC0, 0x00, 0x00, 0x00, 0x01, 0x00); + +namespace NCrypto { +namespace NWzAES { + +const unsigned int kAesBlockSize = 16; +const unsigned int kSaltSizeMax = 16; +const unsigned int kMacSize = 10; + +const UInt32 kPasswordSizeMax = 99; // 128; + +// Password Verification Code Size +const unsigned int kPwdVerifCodeSize = 2; + +class CKeyInfo +{ +public: + Byte KeySizeMode; // 1 - 128-bit , 2 - 192-bit , 3 - 256-bit + Byte Salt[kSaltSizeMax]; + Byte PwdVerifComputed[kPwdVerifCodeSize]; + + CByteBuffer Password; + + UInt32 GetKeySize() const { return (8 * (KeySizeMode & 3) + 8); } + UInt32 GetSaltSize() const { return (4 * (KeySizeMode & 3) + 4); } + + CKeyInfo() { Init(); } + void Init() { KeySizeMode = 3; } +}; + +class CBaseCoder: + public ICompressFilter, + public ICryptoSetPassword, + public CMyUnknownImp +{ +protected: + CKeyInfo _key; + Byte _counter[8]; + Byte _buffer[kAesBlockSize]; + NSha1::CHmac _hmac; + unsigned int _blockPos; + Byte _pwdVerifFromArchive[kPwdVerifCodeSize]; + + void EncryptData(Byte *data, UInt32 size); + + #ifndef CRYPTO_AES + CCoderLibrary _aesLibrary; + #endif + CMyComPtr _aesFilter; + + HRESULT CreateFilters(); +public: + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) = 0; + + STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); + + UInt32 GetHeaderSize() const { return _key.GetSaltSize() + kPwdVerifCodeSize; } +}; + +class CEncoder: + public CBaseCoder + // public ICompressWriteCoderProperties +{ +public: + MY_UNKNOWN_IMP1(ICryptoSetPassword) + // ICompressWriteCoderProperties + // STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + HRESULT WriteHeader(ISequentialOutStream *outStream); + HRESULT WriteFooter(ISequentialOutStream *outStream); + bool SetKeyMode(Byte mode) + { + if (mode < 1 || mode > 3) + return false; + _key.KeySizeMode = mode; + return true; + } +}; + +class CDecoder: + public CBaseCoder, + public ICompressSetDecoderProperties2 +{ +public: + MY_UNKNOWN_IMP2( + ICryptoSetPassword, + ICompressSetDecoderProperties2) + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + HRESULT ReadHeader(ISequentialInStream *inStream); + bool CheckPasswordVerifyCode(); + HRESULT CheckMac(ISequentialInStream *inStream, bool &isOK); +}; + +}} + +#endif diff --git a/CPP/7zip/Crypto/Zip/StdAfx.h b/CPP/7zip/Crypto/Zip/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/CPP/7zip/Crypto/Zip/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/CPP/7zip/Crypto/Zip/ZipCipher.cpp b/CPP/7zip/Crypto/Zip/ZipCipher.cpp new file mode 100755 index 00000000..639776ce --- /dev/null +++ b/CPP/7zip/Crypto/Zip/ZipCipher.cpp @@ -0,0 +1,85 @@ +// Crypto/ZipCipher.h + +#include "StdAfx.h" + +#include "ZipCipher.h" +#include "Windows/Defs.h" + +#include "../../Common/StreamUtils.h" +#include "../Hash/RandGen.h" + +namespace NCrypto { +namespace NZip { + +STDMETHODIMP CEncoder::CryptoSetPassword(const Byte *data, UInt32 size) +{ + _cipher.SetPassword(data, size); + return S_OK; +} + +STDMETHODIMP CEncoder::CryptoSetCRC(UInt32 crc) +{ + _crc = crc; + return S_OK; +} + +STDMETHODIMP CEncoder::Init() +{ + return S_OK; +} + +HRESULT CEncoder::WriteHeader(ISequentialOutStream *outStream) +{ + Byte header[kHeaderSize]; + g_RandomGenerator.Generate(header, kHeaderSize - 2); + + header[kHeaderSize - 1] = Byte(_crc >> 24); + header[kHeaderSize - 2] = Byte(_crc >> 16); + + UInt32 processedSize; + _cipher.EncryptHeader(header); + RINOK(WriteStream(outStream, header, kHeaderSize, &processedSize)); + if (processedSize != kHeaderSize) + return E_FAIL; + return S_OK; +} + +STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size) +{ + UInt32 i; + for (i = 0; i < size; i++) + data[i] = _cipher.EncryptByte(data[i]); + return i; +} + +STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size) +{ + _cipher.SetPassword(data, size); + return S_OK; +} + +HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream) +{ + Byte header[kHeaderSize]; + UInt32 processedSize; + RINOK(ReadStream(inStream, header, kHeaderSize, &processedSize)); + if (processedSize != kHeaderSize) + return E_FAIL; + _cipher.DecryptHeader(header); + return S_OK; +} + +STDMETHODIMP CDecoder::Init() +{ + return S_OK; +} + +STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) +{ + UInt32 i; + for (i = 0; i < size; i++) + data[i] = _cipher.DecryptByte(data[i]); + return i; +} + +}} diff --git a/CPP/7zip/Crypto/Zip/ZipCipher.h b/CPP/7zip/Crypto/Zip/ZipCipher.h new file mode 100755 index 00000000..d750336c --- /dev/null +++ b/CPP/7zip/Crypto/Zip/ZipCipher.h @@ -0,0 +1,59 @@ +// Crypto/ZipCipher.h + +#ifndef __CRYPTO_ZIPCIPHER_H +#define __CRYPTO_ZIPCIPHER_H + +#include "Common/MyCom.h" +#include "Common/Types.h" + +#include "../../ICoder.h" +#include "../../IPassword.h" + +#include "ZipCrypto.h" + +namespace NCrypto { +namespace NZip { + +class CEncoder : + public ICompressFilter, + public ICryptoSetPassword, + public ICryptoSetCRC, + public CMyUnknownImp +{ + CCipher _cipher; + UInt32 _crc; +public: + MY_UNKNOWN_IMP2( + ICryptoSetPassword, + ICryptoSetCRC + ) + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + + STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); + STDMETHOD(CryptoSetCRC)(UInt32 crc); + HRESULT WriteHeader(ISequentialOutStream *outStream); +}; + + +class CDecoder: + public ICompressFilter, + public ICryptoSetPassword, + public CMyUnknownImp + // public CBuffer2 +{ + CCipher _cipher; +public: + + MY_UNKNOWN_IMP1(ICryptoSetPassword) + + STDMETHOD(Init)(); + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); + + HRESULT ReadHeader(ISequentialInStream *inStream); + STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); +}; + +}} + +#endif diff --git a/CPP/7zip/Crypto/Zip/ZipCrypto.cpp b/CPP/7zip/Crypto/Zip/ZipCrypto.cpp new file mode 100755 index 00000000..79f0953c --- /dev/null +++ b/CPP/7zip/Crypto/Zip/ZipCrypto.cpp @@ -0,0 +1,65 @@ +// Crypto/ZipCrypto.cpp + +#include "StdAfx.h" + +#include "ZipCipher.h" +#include "../../../Common/CRC.h" + +namespace NCrypto { +namespace NZip { + +static inline UInt32 ZipCRC32(UInt32 c, Byte b) +{ + return CCRC::Table[(c ^ b) & 0xFF] ^ (c >> 8); +} + +void CCipher::UpdateKeys(Byte b) +{ + Keys[0] = ZipCRC32(Keys[0], b); + Keys[1] += Keys[0] & 0xff; + Keys[1] = Keys[1] * 134775813L + 1; + Keys[2] = ZipCRC32(Keys[2], (Byte)(Keys[1] >> 24)); +} + +void CCipher::SetPassword(const Byte *password, UInt32 passwordLength) +{ + Keys[0] = 305419896L; + Keys[1] = 591751049L; + Keys[2] = 878082192L; + for (UInt32 i = 0; i < passwordLength; i++) + UpdateKeys(password[i]); +} + +Byte CCipher::DecryptByteSpec() +{ + UInt32 temp = Keys[2] | 2; + return (Byte)((temp * (temp ^ 1)) >> 8); +} + +Byte CCipher::DecryptByte(Byte encryptedByte) +{ + Byte c = (Byte)(encryptedByte ^ DecryptByteSpec()); + UpdateKeys(c); + return c; +} + +Byte CCipher::EncryptByte(Byte b) +{ + Byte c = (Byte)(b ^ DecryptByteSpec()); + UpdateKeys(b); + return c; +} + +void CCipher::DecryptHeader(Byte *buffer) +{ + for (int i = 0; i < 12; i++) + buffer[i] = DecryptByte(buffer[i]); +} + +void CCipher::EncryptHeader(Byte *buffer) +{ + for (int i = 0; i < 12; i++) + buffer[i] = EncryptByte(buffer[i]); +} + +}} diff --git a/CPP/7zip/Crypto/Zip/ZipCrypto.h b/CPP/7zip/Crypto/Zip/ZipCrypto.h new file mode 100755 index 00000000..6b4ecaaa --- /dev/null +++ b/CPP/7zip/Crypto/Zip/ZipCrypto.h @@ -0,0 +1,26 @@ +// Crypto/ZipCrypto.h + +#ifndef __CRYPTO_ZIP_CRYPTO_H +#define __CRYPTO_ZIP_CRYPTO_H + +namespace NCrypto { +namespace NZip { + +const int kHeaderSize = 12; +class CCipher +{ + UInt32 Keys[3]; + void UpdateKeys(Byte b); + Byte DecryptByteSpec(); +public: + void SetPassword(const Byte *password, UInt32 passwordLength); + Byte DecryptByte(Byte encryptedByte); + Byte EncryptByte(Byte b); + void DecryptHeader(Byte *buffer); + void EncryptHeader(Byte *buffer); + +}; + +}} + +#endif diff --git a/CPP/7zip/Crypto/makefile b/CPP/7zip/Crypto/makefile new file mode 100755 index 00000000..61f59603 --- /dev/null +++ b/CPP/7zip/Crypto/makefile @@ -0,0 +1,8 @@ +DIRS = \ + 7zAES\~ \ + AES\~ \ + +all: $(DIRS) + +$(DIRS): +!include "../SubBuild.mak" diff --git a/CPP/7zip/FileManager/7zFM.exe.manifest b/CPP/7zip/FileManager/7zFM.exe.manifest new file mode 100755 index 00000000..06710e04 --- /dev/null +++ b/CPP/7zip/FileManager/7zFM.exe.manifest @@ -0,0 +1 @@ +7-Zip File manager. diff --git a/CPP/7zip/FileManager/7zipLogo.ico b/CPP/7zip/FileManager/7zipLogo.ico new file mode 100755 index 00000000..973241c8 Binary files /dev/null and b/CPP/7zip/FileManager/7zipLogo.ico differ diff --git a/CPP/7zip/FileManager/Add.bmp b/CPP/7zip/FileManager/Add.bmp new file mode 100755 index 00000000..a8577fc7 Binary files /dev/null and b/CPP/7zip/FileManager/Add.bmp differ diff --git a/CPP/7zip/FileManager/Add2.bmp b/CPP/7zip/FileManager/Add2.bmp new file mode 100755 index 00000000..252fc253 Binary files /dev/null and b/CPP/7zip/FileManager/Add2.bmp differ diff --git a/CPP/7zip/FileManager/App.cpp b/CPP/7zip/FileManager/App.cpp new file mode 100755 index 00000000..28e2ff0f --- /dev/null +++ b/CPP/7zip/FileManager/App.cpp @@ -0,0 +1,759 @@ +// App.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "Common/StringConvert.h" +#include "Windows/FileDir.h" +#include "Windows/Error.h" +#include "Windows/COM.h" +#include "Windows/Thread.h" +#include "IFolder.h" + +#include "App.h" + +#include "Resource/CopyDialog/CopyDialog.h" + +#include "ExtractCallback.h" +#include "ViewSettings.h" +#include "RegistryUtils.h" + +using namespace NWindows; +using namespace NFile; +using namespace NFind; + +extern DWORD g_ComCtl32Version; +extern HINSTANCE g_hInstance; + +static LPCWSTR kTempDirPrefix = L"7zE"; + +void CPanelCallbackImp::OnTab() +{ + if (g_App.NumPanels != 1) + _app->Panels[1 - _index].SetFocusToList(); +} + +void CPanelCallbackImp::SetFocusToPath(int index) +{ + int newPanelIndex = index; + if (g_App.NumPanels == 1) + newPanelIndex = g_App.LastFocusedPanel; + _app->Panels[newPanelIndex]._headerComboBox.SetFocus(); +} + + +void CPanelCallbackImp::OnCopy(bool move, bool copyToSame) + { _app->OnCopy(move, copyToSame, _index); } + +void CPanelCallbackImp::OnSetSameFolder() + { _app->OnSetSameFolder(_index); } + +void CPanelCallbackImp::OnSetSubFolder() + { _app->OnSetSubFolder(_index); } + +void CPanelCallbackImp::PanelWasFocused() + { _app->SetFocusedPanel(_index); } + +void CPanelCallbackImp::DragBegin() + { _app->DragBegin(_index); } + +void CPanelCallbackImp::DragEnd() + { _app->DragEnd(); } + +void CApp::SetListSettings() +{ + bool showDots = ReadShowDots(); + bool showRealFileIcons = ReadShowRealFileIcons(); + + DWORD extendedStyle = LVS_EX_HEADERDRAGDROP; + if (ReadFullRow()) + extendedStyle |= LVS_EX_FULLROWSELECT; + if (ReadShowGrid()) + extendedStyle |= LVS_EX_GRIDLINES; + bool mySelectionMode = ReadAlternativeSelection(); + + /* + if (ReadSingleClick()) + { + extendedStyle |= LVS_EX_ONECLICKACTIVATE + | LVS_EX_TRACKSELECT; + if (ReadUnderline()) + extendedStyle |= LVS_EX_UNDERLINEHOT; + } + */ + + for (int i = 0; i < kNumPanelsMax; i++) + { + CPanel &panel = Panels[i]; + panel._mySelectMode = mySelectionMode; + panel._showDots = showDots; + panel._showRealFileIcons = showRealFileIcons; + panel._exStyle = extendedStyle; + + DWORD style = (DWORD)panel._listView.GetStyle(); + if (mySelectionMode) + style |= LVS_SINGLESEL; + else + style &= ~LVS_SINGLESEL; + panel._listView.SetStyle(style); + panel.SetExtendedStyle(); + } +} + +void CApp::SetShowSystemMenu() +{ + ShowSystemMenu = ReadShowSystemMenu(); +} + +void CApp::CreateOnePanel(int panelIndex, const UString &mainPath, bool &archiveIsOpened, bool &encrypted) +{ + if (PanelsCreated[panelIndex]) + return; + m_PanelCallbackImp[panelIndex].Init(this, panelIndex); + UString path; + if (mainPath.IsEmpty()) + { + if (!::ReadPanelPath(panelIndex, path)) + path.Empty(); + } + else + path = mainPath; + int id = 1000 + 100 * panelIndex; + Panels[panelIndex].Create(_window, _window, + id, path, &m_PanelCallbackImp[panelIndex], &AppState, archiveIsOpened, encrypted); + PanelsCreated[panelIndex] = true; +} + +static void CreateToolbar( + HWND parent, + NWindows::NControl::CImageList &imageList, + NWindows::NControl::CToolBar &toolBar, + bool LargeButtons) +{ + toolBar.Attach(::CreateWindowEx(0, + TOOLBARCLASSNAME, + NULL, 0 + | WS_VISIBLE + | TBSTYLE_FLAT + | TBSTYLE_TOOLTIPS + | WS_CHILD + | CCS_NOPARENTALIGN + | CCS_NORESIZE + | CCS_NODIVIDER + // | TBSTYLE_AUTOSIZE + // | CCS_ADJUSTABLE + ,0,0,0,0, parent, NULL, g_hInstance, NULL)); + + // TB_BUTTONSTRUCTSIZE message, which is required for + // backward compatibility. + toolBar.ButtonStructSize(); + + imageList.Create( + LargeButtons ? 48: 24, + LargeButtons ? 36: 24, + ILC_MASK, 0, 0); + toolBar.SetImageList(0, imageList); +} + +struct CButtonInfo +{ + UINT commandID; + UINT BitmapResID; + UINT Bitmap2ResID; + UINT StringResID; + UINT32 LangID; + UString GetText()const { return LangString(StringResID, LangID); }; +}; + +static CButtonInfo g_StandardButtons[] = +{ + { IDM_COPY_TO, IDB_COPY, IDB_COPY2, IDS_BUTTON_COPY, 0x03020420}, + { IDM_MOVE_TO, IDB_MOVE, IDB_MOVE2, IDS_BUTTON_MOVE, 0x03020421}, + { IDM_DELETE, IDB_DELETE, IDB_DELETE2, IDS_BUTTON_DELETE, 0x03020422} , + { IDM_FILE_PROPERTIES, IDB_INFO, IDB_INFO2, IDS_BUTTON_INFO, 0x03020423} +}; + +static CButtonInfo g_ArchiveButtons[] = +{ + { kAddCommand, IDB_ADD, IDB_ADD2, IDS_ADD, 0x03020400}, + { kExtractCommand, IDB_EXTRACT, IDB_EXTRACT2, IDS_EXTRACT, 0x03020401}, + { kTestCommand , IDB_TEST, IDB_TEST2, IDS_TEST, 0x03020402} +}; + +bool SetButtonText(UINT32 commandID, CButtonInfo *buttons, int numButtons, UString &s) +{ + for (int i = 0; i < numButtons; i++) + { + const CButtonInfo &b = buttons[i]; + if (b.commandID == commandID) + { + s = b.GetText(); + return true; + } + } + return false; +} + +void SetButtonText(UINT32 commandID, UString &s) +{ + if (SetButtonText(commandID, g_StandardButtons, + sizeof(g_StandardButtons) / sizeof(g_StandardButtons[0]), s)) + return; + SetButtonText(commandID, g_ArchiveButtons, + sizeof(g_ArchiveButtons) / sizeof(g_ArchiveButtons[0]), s); +} + +static void AddButton( + NControl::CImageList &imageList, + NControl::CToolBar &toolBar, + CButtonInfo &butInfo, + bool showText, + bool large) +{ + TBBUTTON but; + but.iBitmap = 0; + but.idCommand = butInfo.commandID; + but.fsState = TBSTATE_ENABLED; + but.fsStyle = BTNS_BUTTON + // | BTNS_AUTOSIZE + ; + but.dwData = 0; + + UString s = butInfo.GetText(); + but.iString = 0; + if (showText) + but.iString = (INT_PTR)(LPCWSTR)s; + + but.iBitmap = imageList.GetImageCount(); + HBITMAP b = ::LoadBitmap(g_hInstance, + large ? + MAKEINTRESOURCE(butInfo.BitmapResID): + MAKEINTRESOURCE(butInfo.Bitmap2ResID)); + if (b != 0) + { + imageList.AddMasked(b, RGB(255, 0, 255)); + ::DeleteObject(b); + } + #ifdef _UNICODE + toolBar.AddButton(1, &but); + #else + toolBar.AddButtonW(1, &but); + #endif +} + +static void AddBand(NControl::CReBar &reBar, NControl::CToolBar &toolBar) +{ + SIZE size; + toolBar.GetMaxSize(&size); + + RECT rect; + toolBar.GetWindowRect(&rect); + + REBARBANDINFO rbBand; + rbBand.cbSize = sizeof(REBARBANDINFO); // Required + rbBand.fMask = RBBIM_STYLE + | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE; + rbBand.fStyle = RBBS_CHILDEDGE; // RBBS_NOGRIPPER; + rbBand.cxMinChild = size.cx; // rect.right - rect.left; + rbBand.cyMinChild = size.cy; // rect.bottom - rect.top; + rbBand.cyChild = rbBand.cyMinChild; + rbBand.cx = rbBand.cxMinChild; + rbBand.cxIdeal = rbBand.cxMinChild; + rbBand.hwndChild = toolBar; + reBar.InsertBand(-1, &rbBand); +} + +void CApp::ReloadToolbars() +{ + if (!_rebar) + return; + HWND parent = _rebar; + + while(_rebar.GetBandCount() > 0) + _rebar.DeleteBand(0); + + _archiveToolBar.Destroy(); + _archiveButtonsImageList.Destroy(); + + _standardButtonsImageList.Destroy(); + _standardToolBar.Destroy(); + + if (ShowArchiveToolbar) + { + CreateToolbar(parent, _archiveButtonsImageList, _archiveToolBar, LargeButtons); + for (int i = 0; i < sizeof(g_ArchiveButtons) / sizeof(g_ArchiveButtons[0]); i++) + AddButton(_archiveButtonsImageList, _archiveToolBar, g_ArchiveButtons[i], + ShowButtonsLables, LargeButtons); + AddBand(_rebar, _archiveToolBar); + } + + if (ShowStandardToolbar) + { + CreateToolbar(parent, _standardButtonsImageList, _standardToolBar, LargeButtons); + for (int i = 0; i < sizeof(g_StandardButtons) / sizeof(g_StandardButtons[0]); i++) + AddButton(_standardButtonsImageList, _standardToolBar, g_StandardButtons[i], + ShowButtonsLables, LargeButtons); + AddBand(_rebar, _standardToolBar); + } +} + +void CApp::ReloadRebar(HWND hwnd) +{ + _rebar.Destroy(); + if (!ShowArchiveToolbar && !ShowStandardToolbar) + return; + if (g_ComCtl32Version >= MAKELONG(71, 4)) + { + INITCOMMONCONTROLSEX icex; + icex.dwSize = sizeof(INITCOMMONCONTROLSEX); + icex.dwICC = ICC_COOL_CLASSES | ICC_BAR_CLASSES; + InitCommonControlsEx(&icex); + + _rebar.Attach(::CreateWindowEx(WS_EX_TOOLWINDOW, + REBARCLASSNAME, + NULL, + WS_VISIBLE + | WS_BORDER + | WS_CHILD + | WS_CLIPCHILDREN + | WS_CLIPSIBLINGS + // | CCS_NODIVIDER + // | CCS_NOPARENTALIGN // it's bead for moveing of two bands + // | CCS_TOP + | RBS_VARHEIGHT + | RBS_BANDBORDERS + // | RBS_AUTOSIZE + ,0,0,0,0, hwnd, NULL, g_hInstance, NULL)); + } + if (_rebar == 0) + return; + REBARINFO rbi; + rbi.cbSize = sizeof(REBARINFO); // Required when using this struct. + rbi.fMask = 0; + rbi.himl = (HIMAGELIST)NULL; + _rebar.SetBarInfo(&rbi); + ReloadToolbars(); +} + +void CApp::Create(HWND hwnd, const UString &mainPath, int xSizes[2], bool &archiveIsOpened, bool &encrypted) +{ + ReadToolbar(); + ReloadRebar(hwnd); + + int i; + for (i = 0; i < kNumPanelsMax; i++) + PanelsCreated[i] = false; + + _window.Attach(hwnd); + AppState.Read(); + SetListSettings(); + SetShowSystemMenu(); + if (LastFocusedPanel >= kNumPanelsMax) + LastFocusedPanel = 0; + + CListMode listMode; + ReadListMode(listMode); + for (i = 0; i < kNumPanelsMax; i++) + { + Panels[i]._ListViewMode = listMode.Panels[i]; + Panels[i]._xSize = xSizes[i]; + } + for (i = 0; i < kNumPanelsMax; i++) + if (NumPanels > 1 || i == LastFocusedPanel) + { + if (NumPanels == 1) + Panels[i]._xSize = xSizes[0] + xSizes[1]; + bool archiveIsOpened2 = false; + bool encrypted2 = false; + bool mainPanel = (i == LastFocusedPanel); + CreateOnePanel(i, mainPanel ? mainPath : L"", archiveIsOpened2, encrypted2); + if (mainPanel) + { + archiveIsOpened = archiveIsOpened2; + encrypted = encrypted2; + } + } + SetFocusedPanel(LastFocusedPanel); + Panels[LastFocusedPanel].SetFocusToList(); +} + +extern void MoveSubWindows(HWND hWnd); + +void CApp::SwitchOnOffOnePanel() +{ + if (NumPanels == 1) + { + NumPanels++; + bool archiveIsOpened, encrypted; + CreateOnePanel(1 - LastFocusedPanel, UString(), archiveIsOpened, encrypted); + Panels[1 - LastFocusedPanel].Enable(true); + Panels[1 - LastFocusedPanel].Show(SW_SHOWNORMAL); + } + else + { + NumPanels--; + Panels[1 - LastFocusedPanel].Enable(false); + Panels[1 - LastFocusedPanel].Show(SW_HIDE); + } + MoveSubWindows(_window); +} + +void CApp::Save() +{ + AppState.Save(); + CListMode listMode; + for (int i = 0; i < kNumPanelsMax; i++) + { + const CPanel &panel = Panels[i]; + UString path; + if (panel._parentFolders.IsEmpty()) + path = panel._currentFolderPrefix; + else + path = GetFolderPath(panel._parentFolders[0].ParentFolder); + SavePanelPath(i, path); + listMode.Panels[i] = panel.GetListViewMode(); + } + SaveListMode(listMode); +} + +void CApp::Release() +{ + // It's for unloading COM dll's: don't change it. + for (int i = 0; i < kNumPanelsMax; i++) + Panels[i].Release(); +} + +static bool IsThereFolderOfPath(const UString &path) +{ + CFileInfoW fileInfo; + if (!FindFile(path, fileInfo)) + return false; + return fileInfo.IsDirectory(); +} + +// reduces path to part that exists on disk +static void ReducePathToRealFileSystemPath(UString &path) +{ + while(!path.IsEmpty()) + { + if (IsThereFolderOfPath(path)) + { + NName::NormalizeDirPathPrefix(path); + break; + } + int pos = path.ReverseFind('\\'); + if (pos < 0) + path.Empty(); + else + { + path = path.Left(pos + 1); + if (path.Length() == 3 && path[1] == L':') + break; + path = path.Left(pos); + } + } +} + +// return true for dir\, if dir exist +static bool CheckFolderPath(const UString &path) +{ + UString pathReduced = path; + ReducePathToRealFileSystemPath(pathReduced); + return (pathReduced == path); +} + +static bool IsPathAbsolute(const UString &path) +{ + if ((path.Length() >= 1 && path[0] == L'\\') || + (path.Length() >= 3 && path[1] == L':' && path[2] == L'\\')) + return true; + return false; +} + +void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex) +{ + int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); + CPanel &srcPanel = Panels[srcPanelIndex]; + CPanel &destPanel = Panels[destPanelIndex]; + + CPanel::CDisableTimerProcessing disableTimerProcessing1(destPanel); + CPanel::CDisableTimerProcessing disableTimerProcessing2(srcPanel); + + if (!srcPanel.DoesItSupportOperations()) + { + srcPanel.MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + + CRecordVector indices; + UString destPath; + bool useDestPanel = false; + + { + if (copyToSame) + { + int focusedItem = srcPanel._listView.GetFocusedItem(); + if (focusedItem < 0) + return; + int realIndex = srcPanel.GetRealItemIndex(focusedItem); + if (realIndex == kParentIndex) + return; + indices.Add(realIndex); + destPath = srcPanel.GetItemName(realIndex); + } + else + { + srcPanel.GetOperatedItemIndices(indices); + if (indices.Size() == 0) + return; + destPath = destPanel._currentFolderPrefix; + if (NumPanels == 1) + ReducePathToRealFileSystemPath(destPath); + } + + CCopyDialog copyDialog; + UStringVector copyFolders; + ReadCopyHistory(copyFolders); + + copyDialog.Strings = copyFolders; + copyDialog.Value = destPath; + + copyDialog.Title = move ? + LangString(IDS_MOVE, 0x03020202): + LangString(IDS_COPY, 0x03020201); + copyDialog.Static = move ? + LangString(IDS_MOVE_TO, 0x03020204): + LangString(IDS_COPY_TO, 0x03020203); + + if (copyDialog.Create(srcPanel.GetParent()) == IDCANCEL) + return; + + destPath = copyDialog.Value; + + if (!IsPathAbsolute(destPath)) + { + if (!srcPanel.IsFSFolder()) + { + srcPanel.MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + destPath = srcPanel._currentFolderPrefix + destPath; + } + + if (indices.Size() > 1 || (destPath.Length() > 0 && destPath.ReverseFind('\\') == destPath.Length() - 1) || + IsThereFolderOfPath(destPath)) + { + NDirectory::CreateComplexDirectory(destPath); + NName::NormalizeDirPathPrefix(destPath); + if (!CheckFolderPath(destPath)) + { + if (NumPanels < 2 || destPath != destPanel._currentFolderPrefix || !destPanel.DoesItSupportOperations()) + { + srcPanel.MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + useDestPanel = true; + } + } + else + { + int pos = destPath.ReverseFind('\\'); + if (pos >= 0) + { + UString prefix = destPath.Left(pos + 1); + NDirectory::CreateComplexDirectory(prefix); + if (!CheckFolderPath(prefix)) + { + srcPanel.MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + } + } + + AddUniqueStringToHeadOfList(copyFolders, destPath); + while (copyFolders.Size() > 20) + copyFolders.DeleteBack(); + SaveCopyHistory(copyFolders); + } + + bool useSrcPanel = (!useDestPanel || !srcPanel.IsFSFolder() || destPanel.IsFSFolder()); + bool useTemp = useSrcPanel && useDestPanel; + NFile::NDirectory::CTempDirectoryW tempDirectory; + UString tempDirPrefix; + if (useTemp) + { + tempDirectory.Create(kTempDirPrefix); + tempDirPrefix = tempDirectory.GetPath(); + NFile::NName::NormalizeDirPathPrefix(tempDirPrefix); + } + + CSelectedState srcSelState; + CSelectedState destSelState; + srcPanel.SaveSelectedState(srcSelState); + destPanel.SaveSelectedState(destSelState); + + HRESULT result; + if (useSrcPanel) + { + UString folder = useTemp ? tempDirPrefix : destPath; + result = srcPanel.CopyTo(indices, folder, move, true, 0); + if (result != S_OK) + { + disableTimerProcessing1.Restore(); + disableTimerProcessing2.Restore(); + // For Password: + srcPanel.SetFocusToList(); + if (result != E_ABORT) + srcPanel.MessageBoxError(result, L"Error"); + return; + } + } + + if (useDestPanel) + { + UStringVector filePaths; + UString folderPrefix; + if (useTemp) + folderPrefix = tempDirPrefix; + else + folderPrefix = srcPanel._currentFolderPrefix; + filePaths.Reserve(indices.Size()); + for(int i = 0; i < indices.Size(); i++) + filePaths.Add(srcPanel.GetItemRelPath(indices[i])); + + result = destPanel.CopyFrom(folderPrefix, filePaths, true, 0); + + if (result != S_OK) + { + disableTimerProcessing1.Restore(); + disableTimerProcessing2.Restore(); + // For Password: + srcPanel.SetFocusToList(); + if (result != E_ABORT) + srcPanel.MessageBoxError(result, L"Error"); + return; + } + } + + if (copyToSame || move) + { + srcPanel.RefreshListCtrl(srcSelState); + } + if (!copyToSame) + { + destPanel.RefreshListCtrl(destSelState); + srcPanel.KillSelection(); + } + disableTimerProcessing1.Restore(); + disableTimerProcessing2.Restore(); + srcPanel.SetFocusToList(); +} + +void CApp::OnSetSameFolder(int srcPanelIndex) +{ + if (NumPanels <= 1) + return; + const CPanel &srcPanel = Panels[srcPanelIndex]; + CPanel &destPanel = Panels[1 - srcPanelIndex]; + destPanel.BindToPathAndRefresh(srcPanel._currentFolderPrefix); +} + +void CApp::OnSetSubFolder(int srcPanelIndex) +{ + if (NumPanels <= 1) + return; + const CPanel &srcPanel = Panels[srcPanelIndex]; + CPanel &destPanel = Panels[1 - srcPanelIndex]; + + int focusedItem = srcPanel._listView.GetFocusedItem(); + if (focusedItem < 0) + return; + int realIndex = srcPanel.GetRealItemIndex(focusedItem); + if (!srcPanel.IsItemFolder(realIndex)) + return; + + + /* + UString string = srcPanel._currentFolderPrefix + + srcPanel.GetItemName(realIndex) + L'\\'; + destPanel.BindToFolder(string); + */ + CMyComPtr newFolder; + if (realIndex == kParentIndex) + { + if (srcPanel._folder->BindToParentFolder(&newFolder) != S_OK) + return; + } + else + { + if (srcPanel._folder->BindToFolder(realIndex, &newFolder) != S_OK) + return; + } + destPanel.CloseOpenFolders(); + destPanel._folder = newFolder; + destPanel.RefreshListCtrl(); +} + +/* +int CApp::GetFocusedPanelIndex() const +{ + return LastFocusedPanel; + HWND hwnd = ::GetFocus(); + for (;;) + { + if (hwnd == 0) + return 0; + for (int i = 0; i < kNumPanelsMax; i++) + { + if (PanelsCreated[i] && + ((HWND)Panels[i] == hwnd || Panels[i]._listView == hwnd)) + return i; + } + hwnd = GetParent(hwnd); + } +} + */ + +static UString g_ToolTipBuffer; +static CSysString g_ToolTipBufferSys; + +void CApp::OnNotify(int /* ctrlID */, LPNMHDR pnmh) +{ + if (pnmh->hwndFrom == _rebar) + { + switch(pnmh->code) + { + case RBN_HEIGHTCHANGE: + { + MoveSubWindows(g_HWND); + return; + } + } + return ; + } + else + { + if (pnmh->code == TTN_GETDISPINFO) + { + LPNMTTDISPINFO info = (LPNMTTDISPINFO)pnmh; + info->hinst = 0; + g_ToolTipBuffer.Empty(); + SetButtonText((UINT32)info->hdr.idFrom, g_ToolTipBuffer); + g_ToolTipBufferSys = GetSystemString(g_ToolTipBuffer); + info->lpszText = (LPTSTR)(LPCTSTR)g_ToolTipBufferSys; + return; + } + #ifndef _UNICODE + if (pnmh->code == TTN_GETDISPINFOW) + { + LPNMTTDISPINFOW info = (LPNMTTDISPINFOW)pnmh; + info->hinst = 0; + g_ToolTipBuffer.Empty(); + SetButtonText((UINT32)info->hdr.idFrom, g_ToolTipBuffer); + info->lpszText = (LPWSTR)(LPCWSTR)g_ToolTipBuffer; + return; + } + #endif + } +} diff --git a/CPP/7zip/FileManager/App.h b/CPP/7zip/FileManager/App.h new file mode 100755 index 00000000..faa40afe --- /dev/null +++ b/CPP/7zip/FileManager/App.h @@ -0,0 +1,332 @@ +// App.h + +#ifndef __APP_H +#define __APP_H + +#include "Panel.h" +#include "AppState.h" +#include "Windows/Control/ImageList.h" + +class CApp; + +extern CApp g_App; +extern HWND g_HWND; + +const int kNumPanelsMax = 2; + +extern void MoveSubWindows(HWND hWnd); + +enum +{ + kAddCommand = kToolbarStartID, + kExtractCommand, + kTestCommand +}; + +class CPanelCallbackImp: public CPanelCallback +{ + CApp *_app; + int _index; +public: + void Init(CApp *app, int index) + { + _app = app; + _index = index; + } + virtual void OnTab(); + virtual void SetFocusToPath(int index); + virtual void OnCopy(bool move, bool copyToSame); + virtual void OnSetSameFolder(); + virtual void OnSetSubFolder(); + virtual void PanelWasFocused(); + virtual void DragBegin(); + virtual void DragEnd(); +}; + +class CApp; + +class CDropTarget: + public IDropTarget, + public CMyUnknownImp +{ + CMyComPtr m_DataObject; + UStringVector m_SourcePaths; + int m_SelectionIndex; + bool m_DropIsAllowed; // = true, if data contain fillist + bool m_PanelDropIsAllowed; // = false, if current target_panel is source_panel. + // check it only if m_DropIsAllowed == true + int m_SubFolderIndex; + UString m_SubFolderName; + + CPanel *m_Panel; + bool m_IsAppTarget; // true, if we want to drop to app window (not to panel). + + bool m_SetPathIsOK; + + bool IsItSameDrive() const; + + void QueryGetData(IDataObject *dataObject); + bool IsFsFolderPath() const; + DWORD GetEffect(DWORD keyState, POINTL pt, DWORD allowedEffect); + void RemoveSelection(); + void PositionCursor(POINTL ptl); + UString GetTargetPath() const; + bool SetPath(bool enablePath) const; + bool SetPath(); + +public: + MY_UNKNOWN_IMP1_MT(IDropTarget) + STDMETHOD(DragEnter)(IDataObject * dataObject, DWORD keyState, + POINTL pt, DWORD *effect); + STDMETHOD(DragOver)(DWORD keyState, POINTL pt, DWORD * effect); + STDMETHOD(DragLeave)(); + STDMETHOD(Drop)(IDataObject * dataObject, DWORD keyState, + POINTL pt, DWORD *effect); + + CDropTarget(): + TargetPanelIndex(-1), + SrcPanelIndex(-1), + m_IsAppTarget(false), + m_Panel(0), + App(0), + m_PanelDropIsAllowed(false), + m_DropIsAllowed(false), + m_SelectionIndex(-1), + m_SubFolderIndex(-1), + m_SetPathIsOK(false) {} + + CApp *App; + int SrcPanelIndex; // index of D&D source_panel + int TargetPanelIndex; // what panel to use as target_panel of Application +}; + +class CApp +{ +public: + NWindows::CWindow _window; + bool ShowSystemMenu; + int NumPanels; + int LastFocusedPanel; + + bool ShowStandardToolbar; + bool ShowArchiveToolbar; + bool ShowButtonsLables; + bool LargeButtons; + + CAppState AppState; + CPanelCallbackImp m_PanelCallbackImp[kNumPanelsMax]; + CPanel Panels[kNumPanelsMax]; + bool PanelsCreated[kNumPanelsMax]; + + NWindows::NControl::CImageList _archiveButtonsImageList; + NWindows::NControl::CImageList _standardButtonsImageList; + + NWindows::NControl::CReBar _rebar; + NWindows::NControl::CToolBar _archiveToolBar; + NWindows::NControl::CToolBar _standardToolBar; + + CDropTarget *_dropTargetSpec; + CMyComPtr _dropTarget; + + void CreateDragTarget() + { + _dropTargetSpec = new CDropTarget(); + _dropTarget = _dropTargetSpec; + _dropTargetSpec->App = (this); + } + + void SetFocusedPanel(int index) + { + LastFocusedPanel = index; + _dropTargetSpec->TargetPanelIndex = LastFocusedPanel; + } + + void DragBegin(int panelIndex) + { + _dropTargetSpec->TargetPanelIndex = (NumPanels > 1) ? 1 - panelIndex : panelIndex; + _dropTargetSpec->SrcPanelIndex = panelIndex; + } + + void DragEnd() + { + _dropTargetSpec->TargetPanelIndex = LastFocusedPanel; + _dropTargetSpec->SrcPanelIndex = -1; + } + + + void OnCopy(bool move, bool copyToSame, int srcPanelIndex); + void OnSetSameFolder(int srcPanelIndex); + void OnSetSubFolder(int srcPanelIndex); + + void CreateOnePanel(int panelIndex, const UString &mainPath, bool &archiveIsOpened, bool &encrypted); + void Create(HWND hwnd, const UString &mainPath, int xSizes[2], bool &archiveIsOpened, bool &encrypted); + void Read(); + void Save(); + void Release(); + + + /* + void SetFocus(int panelIndex) + { Panels[panelIndex].SetFocusToList(); } + */ + void SetFocusToLastItem() + { Panels[LastFocusedPanel].SetFocusToLastRememberedItem(); } + + int GetFocusedPanelIndex() const { return LastFocusedPanel; } + + bool IsPanelVisible(int index) const { return (NumPanels > 1 || index == LastFocusedPanel); } + + /* + void SetCurrentIndex() + { CurrentPanel = GetFocusedPanelIndex(); } + */ + + CApp(): NumPanels(2), LastFocusedPanel(0) {} + CPanel &GetFocusedPanel() + { return Panels[GetFocusedPanelIndex()]; } + + // File Menu + void OpenItem() + { GetFocusedPanel().OpenSelectedItems(true); } + void OpenItemInside() + { GetFocusedPanel().OpenFocusedItemAsInternal(); } + void OpenItemOutside() + { GetFocusedPanel().OpenSelectedItems(false); } + void EditItem() + { GetFocusedPanel().EditItem(); } + void Rename() + { GetFocusedPanel().RenameFile(); } + void CopyTo() + { OnCopy(false, false, GetFocusedPanelIndex()); } + void MoveTo() + { OnCopy(true, false, GetFocusedPanelIndex()); } + void Delete(bool toRecycleBin) + { GetFocusedPanel().DeleteItems(toRecycleBin); } + void CalculateCrc(); + void Split(); + void Combine(); + void Properties() + { GetFocusedPanel().Properties(); } + void Comment() + { GetFocusedPanel().ChangeComment(); } + + void CreateFolder() + { GetFocusedPanel().CreateFolder(); } + void CreateFile() + { GetFocusedPanel().CreateFile(); } + + // Edit + void EditCopy() + { GetFocusedPanel().EditCopy(); } + void EditPaste() + { GetFocusedPanel().EditPaste(); } + + void SelectAll(bool selectMode) + { GetFocusedPanel().SelectAll(selectMode); } + void InvertSelection() + { GetFocusedPanel().InvertSelection(); } + void SelectSpec(bool selectMode) + { GetFocusedPanel().SelectSpec(selectMode); } + void SelectByType(bool selectMode) + { GetFocusedPanel().SelectByType(selectMode); } + + void RefreshStatusBar() + { GetFocusedPanel().RefreshStatusBar(); } + + void SetListViewMode(UINT32 index) + { GetFocusedPanel().SetListViewMode(index); } + UINT32 GetListViewMode() + { return GetFocusedPanel().GetListViewMode(); } + + void SortItemsWithPropID(PROPID propID) + { GetFocusedPanel().SortItemsWithPropID(propID); } + + void OpenRootFolder() + { GetFocusedPanel().OpenDrivesFolder(); } + void OpenParentFolder() + { GetFocusedPanel().OpenParentFolder(); } + void FoldersHistory() + { GetFocusedPanel().FoldersHistory(); } + void RefreshView() + { GetFocusedPanel().OnReload(); } + void RefreshAllPanels() + { + for (int i = 0; i < NumPanels; i++) + { + int index = i; + if (NumPanels == 1) + index = LastFocusedPanel; + Panels[index].OnReload(); + } + } + void SetListSettings(); + void SetShowSystemMenu(); + void SwitchOnOffOnePanel(); + bool GetFlatMode() { return Panels[LastFocusedPanel].GetFlatMode(); } + void ChangeFlatMode() { Panels[LastFocusedPanel].ChangeFlatMode(); } + + void OpenBookmark(int index) + { GetFocusedPanel().OpenBookmark(index); } + void SetBookmark(int index) + { GetFocusedPanel().SetBookmark(index); } + + void ReloadRebar(HWND hwnd); + void ReloadToolbars(); + void ReadToolbar() + { + UINT32 mask = ReadToolbarsMask(); + ShowButtonsLables = ((mask & 1) != 0); + LargeButtons = ((mask & 2) != 0); + ShowStandardToolbar = ((mask & 4) != 0); + ShowArchiveToolbar = ((mask & 8) != 0); + } + void SaveToolbar() + { + UINT32 mask = 0; + if (ShowButtonsLables) mask |= 1; + if (LargeButtons) mask |= 2; + if (ShowStandardToolbar) mask |= 4; + if (ShowArchiveToolbar) mask |= 8; + SaveToolbarsMask(mask); + } + void SwitchStandardToolbar() + { + ShowStandardToolbar = !ShowStandardToolbar; + SaveToolbar(); + ReloadRebar(g_HWND); + MoveSubWindows(_window); + } + void SwitchArchiveToolbar() + { + ShowArchiveToolbar = !ShowArchiveToolbar; + SaveToolbar(); + ReloadRebar(g_HWND); + MoveSubWindows(_window); + } + void SwitchButtonsLables() + { + ShowButtonsLables = !ShowButtonsLables; + SaveToolbar(); + ReloadRebar(g_HWND); + MoveSubWindows(_window); + } + void SwitchLargeButtons() + { + LargeButtons = !LargeButtons; + SaveToolbar(); + ReloadRebar(g_HWND); + MoveSubWindows(_window); + } + + + void AddToArchive() + { GetFocusedPanel().AddToArchive(); } + void ExtractArchives() + { GetFocusedPanel().ExtractArchives(); } + void TestArchives() + { GetFocusedPanel().TestArchives(); } + + void OnNotify(int ctrlID, LPNMHDR pnmh); +}; + +#endif diff --git a/CPP/7zip/FileManager/AppState.h b/CPP/7zip/FileManager/AppState.h new file mode 100755 index 00000000..318c0258 --- /dev/null +++ b/CPP/7zip/FileManager/AppState.h @@ -0,0 +1,114 @@ +// AppState.h + +#ifndef __APPSTATE_H +#define __APPSTATE_H + +#include "Windows/Synchronization.h" + +void inline AddUniqueStringToHead(UStringVector &list, + const UString &string) +{ + for(int i = 0; i < list.Size();) + if (string.CompareNoCase(list[i]) == 0) + list.Delete(i); + else + i++; + list.Insert(0, string); +} + +class CFastFolders +{ + NWindows::NSynchronization::CCriticalSection _criticalSection; +public: + UStringVector Strings; + void SetString(int index, const UString &string) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + while(Strings.Size() <= index) + Strings.Add(UString()); + Strings[index] = string; + } + UString GetString(int index) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + if (index >= Strings.Size()) + return UString(); + return Strings[index]; + } + void Save() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + SaveFastFolders(Strings); + } + void Read() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + ReadFastFolders(Strings); + } +}; + +class CFolderHistory +{ + NWindows::NSynchronization::CCriticalSection _criticalSection; + UStringVector Strings; +public: + + void GetList(UStringVector &foldersHistory) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + foldersHistory = Strings; + } + + void Normalize() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + const int kMaxSize = 100; + if (Strings.Size() > kMaxSize) + Strings.Delete(kMaxSize, Strings.Size() - kMaxSize); + } + + void AddString(const UString &string) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + AddUniqueStringToHead(Strings, string); + Normalize(); + } + + void RemoveAll() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + Strings.Clear(); + } + + void Save() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + SaveFolderHistory(Strings); + } + + void Read() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + ReadFolderHistory(Strings); + Normalize(); + } +}; + +struct CAppState +{ + CFastFolders FastFolders; + CFolderHistory FolderHistory; + void Save() + { + FastFolders.Save(); + FolderHistory.Save(); + } + void Read() + { + FastFolders.Read(); + FolderHistory.Read(); + } +}; + + +#endif \ No newline at end of file diff --git a/CPP/7zip/FileManager/ClassDefs.cpp b/CPP/7zip/FileManager/ClassDefs.cpp new file mode 100755 index 00000000..ded9c8d8 --- /dev/null +++ b/CPP/7zip/FileManager/ClassDefs.cpp @@ -0,0 +1,15 @@ +// ClassDefs.cpp + +#include "StdAfx.h" + +#include + +#include "IFolder.h" +#include "../IPassword.h" +#include "PluginInterface.h" +#include "ExtractCallback.h" +#include "../ICoder.h" + +// {23170F69-40C1-278A-1000-000100020000} +DEFINE_GUID(CLSID_CZipContextMenu, +0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00); diff --git a/CPP/7zip/FileManager/Copy.bmp b/CPP/7zip/FileManager/Copy.bmp new file mode 100755 index 00000000..0f28a324 Binary files /dev/null and b/CPP/7zip/FileManager/Copy.bmp differ diff --git a/CPP/7zip/FileManager/Copy2.bmp b/CPP/7zip/FileManager/Copy2.bmp new file mode 100755 index 00000000..ba88ded0 Binary files /dev/null and b/CPP/7zip/FileManager/Copy2.bmp differ diff --git a/CPP/7zip/FileManager/Delete.bmp b/CPP/7zip/FileManager/Delete.bmp new file mode 100755 index 00000000..d1004d82 Binary files /dev/null and b/CPP/7zip/FileManager/Delete.bmp differ diff --git a/CPP/7zip/FileManager/Delete2.bmp b/CPP/7zip/FileManager/Delete2.bmp new file mode 100755 index 00000000..60e08c6a Binary files /dev/null and b/CPP/7zip/FileManager/Delete2.bmp differ diff --git a/CPP/7zip/FileManager/EnumFormatEtc.cpp b/CPP/7zip/FileManager/EnumFormatEtc.cpp new file mode 100755 index 00000000..ef9463fb --- /dev/null +++ b/CPP/7zip/FileManager/EnumFormatEtc.cpp @@ -0,0 +1,108 @@ +// EnumFormatEtc.cpp + +#include "StdAfx.h" + +#include "EnumFormatEtc.h" +#include "MyCom2.h" + +class CEnumFormatEtc : +public IEnumFORMATETC, +public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP1_MT(IEnumFORMATETC) + + STDMETHOD(Next)(ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched); + STDMETHOD(Skip)(ULONG celt); + STDMETHOD(Reset)(void); + STDMETHOD(Clone)(IEnumFORMATETC **ppEnumFormatEtc); + + CEnumFormatEtc(const FORMATETC *pFormatEtc, ULONG numFormats); + ~CEnumFormatEtc(); + +private: + LONG m_RefCount; + ULONG m_NumFormats; + FORMATETC *m_Formats; + ULONG m_Index; +}; + +static void DeepCopyFormatEtc(FORMATETC *dest, const FORMATETC *src) +{ + *dest = *src; + if(src->ptd) + { + dest->ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(sizeof(DVTARGETDEVICE)); + *(dest->ptd) = *(src->ptd); + } +} + +CEnumFormatEtc::CEnumFormatEtc(const FORMATETC *pFormatEtc, ULONG numFormats) +{ + m_RefCount = 1; + m_Index = 0; + m_NumFormats = 0; + m_Formats = new FORMATETC[numFormats]; + if(m_Formats) + { + m_NumFormats = numFormats; + for(ULONG i = 0; i < numFormats; i++) + DeepCopyFormatEtc(&m_Formats[i], &pFormatEtc[i]); + } +} + +CEnumFormatEtc::~CEnumFormatEtc() +{ + if(m_Formats) + { + for(ULONG i = 0; i < m_NumFormats; i++) + if(m_Formats[i].ptd) + CoTaskMemFree(m_Formats[i].ptd); + delete[]m_Formats; + } +} + +STDMETHODIMP CEnumFormatEtc::Next(ULONG celt, FORMATETC *pFormatEtc, ULONG *pceltFetched) +{ + ULONG copied = 0; + if(celt == 0 || pFormatEtc == 0) + return E_INVALIDARG; + while(m_Index < m_NumFormats && copied < celt) + { + DeepCopyFormatEtc(&pFormatEtc[copied], &m_Formats[m_Index]); + copied++; + m_Index++; + } + if(pceltFetched != 0) + *pceltFetched = copied; + return (copied == celt) ? S_OK : S_FALSE; +} + +STDMETHODIMP CEnumFormatEtc::Skip(ULONG celt) +{ + m_Index += celt; + return (m_Index <= m_NumFormats) ? S_OK : S_FALSE; +} + +STDMETHODIMP CEnumFormatEtc::Reset(void) +{ + m_Index = 0; + return S_OK; +} + +STDMETHODIMP CEnumFormatEtc::Clone(IEnumFORMATETC ** ppEnumFormatEtc) +{ + HRESULT hResult = CreateEnumFormatEtc(m_NumFormats, m_Formats, ppEnumFormatEtc); + if(hResult == S_OK) + ((CEnumFormatEtc *)*ppEnumFormatEtc)->m_Index = m_Index; + return hResult; +} + +// replacement for SHCreateStdEnumFmtEtc +HRESULT CreateEnumFormatEtc(UINT numFormats, const FORMATETC *formats, IEnumFORMATETC **enumFormat) +{ + if(numFormats == 0 || formats == 0 || enumFormat == 0) + return E_INVALIDARG; + *enumFormat = new CEnumFormatEtc(formats, numFormats); + return (*enumFormat) ? S_OK : E_OUTOFMEMORY; +} diff --git a/CPP/7zip/FileManager/EnumFormatEtc.h b/CPP/7zip/FileManager/EnumFormatEtc.h new file mode 100755 index 00000000..6c476f1a --- /dev/null +++ b/CPP/7zip/FileManager/EnumFormatEtc.h @@ -0,0 +1,10 @@ +// EnumFormatEtc.h + +#ifndef __ENUMFORMATETC_H +#define __ENUMFORMATETC_H + +#include + +HRESULT CreateEnumFormatEtc(UINT numFormats, const FORMATETC *formats, IEnumFORMATETC **enumFormat); + +#endif diff --git a/CPP/7zip/FileManager/Extract.bmp b/CPP/7zip/FileManager/Extract.bmp new file mode 100755 index 00000000..0aeba923 Binary files /dev/null and b/CPP/7zip/FileManager/Extract.bmp differ diff --git a/CPP/7zip/FileManager/Extract2.bmp b/CPP/7zip/FileManager/Extract2.bmp new file mode 100755 index 00000000..a7e57753 Binary files /dev/null and b/CPP/7zip/FileManager/Extract2.bmp differ diff --git a/CPP/7zip/FileManager/ExtractCallback.cpp b/CPP/7zip/FileManager/ExtractCallback.cpp new file mode 100755 index 00000000..d6ea8f8f --- /dev/null +++ b/CPP/7zip/FileManager/ExtractCallback.cpp @@ -0,0 +1,382 @@ +// ExtractCallback.h + +#include "StdAfx.h" + +#include "ExtractCallback.h" + +#include "Windows/FileFind.h" +#include "Windows/FileDir.h" +#include "Windows/Error.h" + +#include "Resource/OverwriteDialog/OverwriteDialog.h" +#ifndef _NO_CRYPTO +#include "Resource/PasswordDialog/PasswordDialog.h" +#endif +#include "Resource/MessagesDialog/MessagesDialog.h" +#include "../UI/Resource/Extract/resource.h" +#include "../UI/GUI/resource.h" + +#include "Common/Wildcard.h" +#include "Common/StringConvert.h" + +#include "FormatUtils.h" + +#include "../Common/FilePathAutoRename.h" + +using namespace NWindows; +using namespace NFile; +using namespace NFind; + +CExtractCallbackImp::~CExtractCallbackImp() +{ + if (ShowMessages && !Messages.IsEmpty()) + { + CMessagesDialog messagesDialog; + messagesDialog.Messages = &Messages; + messagesDialog.Create(ParentWindow); + } +} + +void CExtractCallbackImp::Init() +{ + Messages.Clear(); + NumArchiveErrors = 0; +} + +void CExtractCallbackImp::AddErrorMessage(LPCWSTR message) +{ + Messages.Add(message); +} + +STDMETHODIMP CExtractCallbackImp::SetTotal(UInt64 total) +{ + ProgressDialog.ProgressSynch.SetProgress(total, 0); + return S_OK; +} + +STDMETHODIMP CExtractCallbackImp::SetCompleted(const UInt64 *completeValue) +{ + for (;;) + { + if(ProgressDialog.ProgressSynch.GetStopped()) + return E_ABORT; + if(!ProgressDialog.ProgressSynch.GetPaused()) + break; + ::Sleep(100); + } + if (completeValue != NULL) + ProgressDialog.ProgressSynch.SetPos(*completeValue); + return S_OK; +} + +STDMETHODIMP CExtractCallbackImp::AskOverwrite( + const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, + const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, + Int32 *answer) +{ + COverwriteDialog dialog; + + dialog.OldFileInfo.Time = *existTime; + dialog.OldFileInfo.SizeIsDefined = (existSize != NULL); + if (dialog.OldFileInfo.SizeIsDefined) + dialog.OldFileInfo.Size = *existSize; + dialog.OldFileInfo.Name = existName; + + if (newTime == 0) + dialog.NewFileInfo.TimeIsDefined = false; + else + { + dialog.NewFileInfo.TimeIsDefined = true; + dialog.NewFileInfo.Time = *newTime; + } + + dialog.NewFileInfo.SizeIsDefined = (newSize != NULL); + if (dialog.NewFileInfo.SizeIsDefined) + dialog.NewFileInfo.Size = *newSize; + dialog.NewFileInfo.Name = newName; + + /* + NOverwriteDialog::NResult::EEnum writeAnswer = + NOverwriteDialog::Execute(oldFileInfo, newFileInfo); + */ + INT_PTR writeAnswer = dialog.Create(NULL); // ParentWindow doesn't work with 7z + + switch(writeAnswer) + { + case IDCANCEL: + return E_ABORT; + // askResult = NAskOverwriteAnswer::kCancel; + // break; + case IDNO: + *answer = NOverwriteAnswer::kNo; + break; + case IDC_BUTTON_OVERWRITE_NO_TO_ALL: + *answer = NOverwriteAnswer::kNoToAll; + break; + case IDC_BUTTON_OVERWRITE_YES_TO_ALL: + *answer = NOverwriteAnswer::kYesToAll; + break; + case IDC_BUTTON_OVERWRITE_AUTO_RENAME: + *answer = NOverwriteAnswer::kAutoRename; + break; + case IDYES: + *answer = NOverwriteAnswer::kYes; + break; + default: + throw 20413; + } + return S_OK; +} + + +STDMETHODIMP CExtractCallbackImp::PrepareOperation(const wchar_t *name, Int32 /* askExtractMode */, const UInt64 * /* position */) +{ + return SetCurrentFilePath(name); +} + +STDMETHODIMP CExtractCallbackImp::MessageError(const wchar_t *message) +{ + AddErrorMessage(message); + return S_OK; +} + +STDMETHODIMP CExtractCallbackImp::ShowMessage(const wchar_t *message) +{ + AddErrorMessage(message); + return S_OK; +} + +STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 operationResult, bool encrypted) +{ + switch(operationResult) + { + case NArchive::NExtract::NOperationResult::kOK: + break; + default: + { + UINT messageID; + UInt32 langID; + switch(operationResult) + { + case NArchive::NExtract::NOperationResult::kUnSupportedMethod: + messageID = IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_UNSUPPORTED_METHOD; + langID = 0x02000A91; + break; + case NArchive::NExtract::NOperationResult::kDataError: + messageID = encrypted ? + IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED: + IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_DATA_ERROR; + langID = encrypted ? 0x02000A94 : 0x02000A92; + break; + case NArchive::NExtract::NOperationResult::kCRCError: + messageID = encrypted ? + IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CRC_ENCRYPTED: + IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CRC; + langID = encrypted ? 0x02000A95 : 0x02000A93; + break; + default: + return E_FAIL; + } + if (_needWriteArchivePath) + { + AddErrorMessage(_currentArchivePath); + _needWriteArchivePath = false; + } + AddErrorMessage( + MyFormatNew(messageID, + #ifdef LANG + langID, + #endif + _currentFilePath)); + } + } + return S_OK; +} + +//////////////////////////////////////// +// IExtractCallbackUI + +HRESULT CExtractCallbackImp::BeforeOpen(const wchar_t *name) +{ + #ifndef _SFX + ProgressDialog.ProgressSynch.SetTitleFileName(name); + #endif + _currentArchivePath = name; + return S_OK; +} + +HRESULT CExtractCallbackImp::SetCurrentFilePath(const wchar_t *path) +{ + _currentFilePath = path; + #ifndef _SFX + ProgressDialog.ProgressSynch.SetCurrentFileName(path); + #endif + return S_OK; +} + +HRESULT CExtractCallbackImp::OpenResult(const wchar_t *name, HRESULT result, bool encrypted) +{ + if (result != S_OK) + { + MessageError(MyFormatNew(encrypted ? IDS_CANT_OPEN_ENCRYPTED_ARCHIVE : IDS_CANT_OPEN_ARCHIVE, + #ifdef LANG + (encrypted ? 0x0200060A : 0x02000609), + #endif + name)); + NumArchiveErrors++; + } + _currentArchivePath = name; + _needWriteArchivePath = true; + return S_OK; +} + +HRESULT CExtractCallbackImp::ThereAreNoFiles() +{ + return S_OK; +} + +HRESULT CExtractCallbackImp::ExtractResult(HRESULT result) +{ + if (result == S_OK) + return result; + NumArchiveErrors++; + if (result == E_ABORT || result == ERROR_DISK_FULL) + return result; + MessageError(_currentFilePath); + MessageError(NError::MyFormatMessageW(result)); + return S_OK; +} + +HRESULT CExtractCallbackImp::SetPassword(const UString &password) +{ + PasswordIsDefined = true; + Password = password; + return S_OK; +} + +STDMETHODIMP CExtractCallbackImp::CryptoGetTextPassword(BSTR *password) +{ + if (!PasswordIsDefined) + { + CPasswordDialog dialog; + + if (dialog.Create(ParentWindow) == IDCANCEL) + return E_ABORT; + + Password = dialog.Password; + PasswordIsDefined = true; + } + CMyComBSTR tempName(Password); + *password = tempName.Detach(); + + return S_OK; +} + + +// IExtractCallBack3 +STDMETHODIMP CExtractCallbackImp::AskWrite( + const wchar_t *srcPath, Int32 srcIsFolder, + const FILETIME *srcTime, const UInt64 *srcSize, + const wchar_t *destPath, + BSTR *destPathResult, + Int32 *writeAnswer) +{ + UString destPathResultTemp = destPath; + /* + { + CMyComBSTR destPathResultBSTR = destPath; + *destPathResult = destPathResultBSTR.Detach(); + } + */ + *destPathResult = 0; + *writeAnswer = BoolToInt(false); + + UString destPathSpec = destPath; + UString destPathSys = destPathSpec; + bool srcIsFolderSpec = IntToBool(srcIsFolder); + CFileInfoW destFileInfo; + if (FindFile(destPathSys, destFileInfo)) + { + if (srcIsFolderSpec) + { + if (!destFileInfo.IsDirectory()) + { + UString message = UString(L"can not replace file \'") + + destPathSpec + + UString(L"\' with folder with same name"); + RINOK(MessageError(message)); + return E_ABORT; + } + *writeAnswer = BoolToInt(false); + return S_OK; + } + if (destFileInfo.IsDirectory()) + { + UString message = UString(L"can not replace folder \'") + + destPathSpec + + UString(L"\' with file with same name"); + RINOK(MessageError(message)); + return E_FAIL; + } + + switch(OverwriteMode) + { + case NExtract::NOverwriteMode::kSkipExisting: + return S_OK; + case NExtract::NOverwriteMode::kAskBefore: + { + Int32 overwiteResult; + RINOK(AskOverwrite( + destPathSpec, + &destFileInfo.LastWriteTime, &destFileInfo.Size, + srcPath, + srcTime, srcSize, + &overwiteResult)); + switch(overwiteResult) + { + case NOverwriteAnswer::kCancel: + return E_ABORT; + case NOverwriteAnswer::kNo: + return S_OK; + case NOverwriteAnswer::kNoToAll: + OverwriteMode = NExtract::NOverwriteMode::kSkipExisting; + return S_OK; + case NOverwriteAnswer::kYesToAll: + OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt; + break; + case NOverwriteAnswer::kYes: + break; + case NOverwriteAnswer::kAutoRename: + OverwriteMode = NExtract::NOverwriteMode::kAutoRename; + break; + default: + throw 20413; + } + } + } + if (OverwriteMode == NExtract::NOverwriteMode::kAutoRename) + { + if (!AutoRenamePath(destPathSys)) + { + UString message = UString(L"can not create name of file ") + + destPathSys; + RINOK(MessageError(message)); + return E_ABORT; + } + destPathResultTemp = destPathSys; + } + else + if (!NFile::NDirectory::DeleteFileAlways(destPathSys)) + { + UString message = UString(L"can not delete output file ") + + destPathSys; + RINOK(MessageError(message)); + return E_ABORT; + } + } + CMyComBSTR destPathResultBSTR = destPathResultTemp; + *destPathResult = destPathResultBSTR.Detach(); + *writeAnswer = BoolToInt(true); + return S_OK; +} + diff --git a/CPP/7zip/FileManager/ExtractCallback.h b/CPP/7zip/FileManager/ExtractCallback.h new file mode 100755 index 00000000..7bf8864e --- /dev/null +++ b/CPP/7zip/FileManager/ExtractCallback.h @@ -0,0 +1,124 @@ +// ExtractCallback.h + +#ifndef __EXTRACTCALLBACK_H +#define __EXTRACTCALLBACK_H + +#include "../UI/Agent/IFolderArchive.h" +#include "Common/String.h" + +#ifdef _SFX +#include "Resource/ProgressDialog/ProgressDialog.h" +#else +#include "Resource/ProgressDialog2/ProgressDialog.h" +#endif + +#include "Windows/ResourceString.h" + +#ifdef LANG +#include "LangUtils.h" +#endif + +#ifndef _NO_CRYPTO +#include "../IPassword.h" +#endif +#include "Common/MyCom.h" +#include "IFolder.h" + +class CExtractCallbackImp: + public IExtractCallbackUI, + public IFolderOperationsExtractCallback, + #ifndef _NO_CRYPTO + public ICryptoGetTextPassword, + #endif + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP3( + IFolderArchiveExtractCallback, + IFolderOperationsExtractCallback, + ICryptoGetTextPassword + ) + + // IProgress + STDMETHOD(SetTotal)(UInt64 total); + STDMETHOD(SetCompleted)(const UInt64 *completeValue); + + // IFolderArchiveExtractCallback + STDMETHOD(AskOverwrite)( + const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, + const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, + Int32 *answer); + STDMETHOD (PrepareOperation)(const wchar_t *name, Int32 askExtractMode, const UInt64 *position); + + STDMETHOD(MessageError)(const wchar_t *message); + STDMETHOD(SetOperationResult)(Int32 operationResult, bool encrypted); + + // IExtractCallbackUI + + HRESULT BeforeOpen(const wchar_t *name); + HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted); + HRESULT ThereAreNoFiles(); + HRESULT ExtractResult(HRESULT result); + + #ifndef _NO_CRYPTO + HRESULT SetPassword(const UString &password); + #endif + + // IFolderOperationsExtractCallback + STDMETHOD(AskWrite)( + const wchar_t *srcPath, + Int32 srcIsFolder, + const FILETIME *srcTime, + const UInt64 *srcSize, + const wchar_t *destPathRequest, + BSTR *destPathResult, + Int32 *writeAnswer); + STDMETHOD(ShowMessage)(const wchar_t *message); + STDMETHOD(SetCurrentFilePath)(const wchar_t *filePath); + + // ICryptoGetTextPassword + #ifndef _NO_CRYPTO + STDMETHOD(CryptoGetTextPassword)(BSTR *password); + #endif + +private: + // bool _extractMode; + UString _currentArchivePath; + bool _needWriteArchivePath; + + UString _currentFilePath; + + // void CreateComplexDirectory(const UStringVector &aDirPathParts); + + void AddErrorMessage(LPCWSTR message); +public: + CProgressDialog ProgressDialog; + UStringVector Messages; + bool ShowMessages; + HWND ParentWindow; + INT_PTR StartProgressDialog(const UString &title) + { + return ProgressDialog.Create(title, ParentWindow); + } + UInt32 NumArchiveErrors; + NExtract::NOverwriteMode::EEnum OverwriteMode; + + #ifndef _NO_CRYPTO + bool PasswordIsDefined; + UString Password; + #endif + + CExtractCallbackImp(): + #ifndef _NO_CRYPTO + PasswordIsDefined(false), + #endif + OverwriteMode(NExtract::NOverwriteMode::kAskBefore), + ParentWindow(0), + ShowMessages(true) + {} + + ~CExtractCallbackImp(); + void Init(); +}; + +#endif diff --git a/CPP/7zip/FileManager/FM.cpp b/CPP/7zip/FileManager/FM.cpp new file mode 100755 index 00000000..c64f0b51 --- /dev/null +++ b/CPP/7zip/FileManager/FM.cpp @@ -0,0 +1,788 @@ +// FAM.cpp + +#include "StdAfx.h" + +#include "resource.h" +#include "Panel.h" + +#include "Common/Defs.h" +#include "Common/StringConvert.h" +#include "Common/Alloc.h" +// #include "Common/CommandLineParser.h" + +#include "Windows/Control/Toolbar.h" +#include "Windows/Error.h" +#include "Windows/COM.h" +#include "Windows/DLL.h" +#include "Windows/Security.h" +#include "Windows/MemoryLock.h" + +#include "ViewSettings.h" +#include "../UI/Resource/Extract/resource.h" + +#include "App.h" +#include "StringUtils.h" + +#include "MyLoadMenu.h" +#include "LangUtils.h" +#include "FormatUtils.h" +#include "RegistryUtils.h" + +using namespace NWindows; +using namespace NFile; +using namespace NFind; +// using namespace NCommandLineParser; + +// NWindows::NCOM::CComInitializer aComInitializer; + +#define MAX_LOADSTRING 100 + +#define MENU_HEIGHT 26 + +#ifndef _UNICODE +bool g_IsNT = false; +#endif +HINSTANCE g_hInstance; +HWND g_HWND; +bool g_OpenArchive = false; +static UString g_MainPath; + +const int kNumDefaultPanels = 1; + +const int kSplitterWidth = 4; +int kSplitterRateMax = 1 << 16; + +// bool OnMenuCommand(HWND hWnd, int id); + +static UString GetProgramPath() +{ + UString s; + NDLL::MyGetModuleFileName(g_hInstance, s); + return s; +} + +UString GetProgramFolderPrefix() +{ + UString path = GetProgramPath(); + int pos = path.ReverseFind(L'\\'); + return path.Left(pos + 1); +} + + +class CSplitterPos +{ + int _ratio; // 10000 is max + int _pos; + int _fullWidth; + void SetRatioFromPos(HWND hWnd) + { _ratio = (_pos + kSplitterWidth / 2) * kSplitterRateMax / + MyMax(GetWidth(hWnd), 1); } +public: + int GetPos() const + { return _pos; } + int GetWidth(HWND hWnd) const + { + RECT rect; + ::GetClientRect(hWnd, &rect); + return rect.right; + } + void SetRatio(HWND hWnd, int aRatio) + { + _ratio = aRatio; + SetPosFromRatio(hWnd); + } + void SetPosPure(HWND hWnd, int pos) + { + int posMax = GetWidth(hWnd) - kSplitterWidth; + if (pos > posMax) + pos = posMax; + if (pos < 0) + pos = 0; + _pos = pos; + } + void SetPos(HWND hWnd, int pos) + { + _fullWidth = GetWidth(hWnd); + SetPosPure(hWnd, pos); + SetRatioFromPos(hWnd); + } + void SetPosFromRatio(HWND hWnd) + { + int fullWidth = GetWidth(hWnd); + if (_fullWidth != fullWidth) + { + _fullWidth = fullWidth; + SetPosPure(hWnd, GetWidth(hWnd) * _ratio / kSplitterRateMax - kSplitterWidth / 2); + } + } +}; + +bool g_CanChangeSplitter = false; +UINT32 g_SplitterPos = 0; +CSplitterPos g_Splitter; +bool g_PanelsInfoDefined = false; + +int g_StartCaptureMousePos; +int g_StartCaptureSplitterPos; + +CApp g_App; + +void MoveSubWindows(HWND hWnd); +void OnSize(HWND hWnd); + +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + +const wchar_t *kWindowClass = L"FM"; + +#ifndef _UNICODE +static bool IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); +} +#endif + +// FUNCTION: InitInstance(HANDLE, int) +BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) +{ + CWindow wnd; + + g_hInstance = hInstance; + + ReloadLangSmart(); + + // LoadString(hInstance, IDS_CLASS, windowClass, MAX_LOADSTRING); + + // LoadString(hInstance, IDS_APP_TITLE, title, MAX_LOADSTRING); + UString title = LangString(IDS_APP_TITLE, 0x03000000); + + /* + //If it is already running, then focus on the window + hWnd = FindWindow(windowClass, title); + if (hWnd) + { + SetForegroundWindow ((HWND) (((DWORD)hWnd) | 0x01)); + return 0; + } + */ + + WNDCLASSW wc; + + // wc.style = CS_HREDRAW | CS_VREDRAW; + wc.style = 0; + wc.lpfnWndProc = (WNDPROC) WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_FAM)); + + // wc.hCursor = LoadCursor (NULL, IDC_ARROW); + wc.hCursor = ::LoadCursor(0, IDC_SIZEWE); + // wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); + wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); + + wc.lpszMenuName = MAKEINTRESOURCEW(IDM_MENU); + wc.lpszClassName = kWindowClass; + + MyRegisterClass(&wc); + + // RECT rect; + // GetClientRect(hWnd, &rect); + + DWORD style = WS_OVERLAPPEDWINDOW; + // DWORD style = 0; + + RECT rect; + bool maximized = false; + int x , y, xSize, ySize; + x = y = xSize = ySize = CW_USEDEFAULT; + bool windowPosIsRead = ReadWindowSize(rect, maximized); + + if (windowPosIsRead) + { + // x = rect.left; + // y = rect.top; + xSize = rect.right - rect.left; + ySize = rect.bottom - rect.top; + } + + UINT32 numPanels, currentPanel; + g_PanelsInfoDefined = ReadPanelsInfo(numPanels, currentPanel, g_SplitterPos); + if (g_PanelsInfoDefined) + { + if (numPanels < 1 || numPanels > 2) + numPanels = kNumDefaultPanels; + if (currentPanel >= 2) + currentPanel = 0; + } + else + { + numPanels = kNumDefaultPanels; + currentPanel = 0; + } + g_App.NumPanels = numPanels; + g_App.LastFocusedPanel = currentPanel; + + if (!wnd.Create(kWindowClass, title, style, + x, y, xSize, ySize, NULL, NULL, hInstance, NULL)) + return FALSE; + g_HWND = (HWND)wnd; + + WINDOWPLACEMENT placement; + placement.length = sizeof(placement); + if (wnd.GetPlacement(&placement)) + { + if (nCmdShow == SW_SHOWNORMAL || nCmdShow == SW_SHOW || + nCmdShow == SW_SHOWDEFAULT) + { + if (maximized) + placement.showCmd = SW_SHOWMAXIMIZED; + else + placement.showCmd = SW_SHOWNORMAL; + } + else + placement.showCmd = nCmdShow; + if (windowPosIsRead) + placement.rcNormalPosition = rect; + wnd.SetPlacement(&placement); + // window.Show(nCmdShow); + } + else + wnd.Show(nCmdShow); + return TRUE; +} + +/* +static void GetCommands(const UString &aCommandLine, UString &aCommands) +{ + UString aProgramName; + aCommands.Empty(); + bool aQuoteMode = false; + for (int i = 0; i < aCommandLine.Length(); i++) + { + wchar_t aChar = aCommandLine[i]; + if (aChar == L'\"') + aQuoteMode = !aQuoteMode; + else if (aChar == L' ' && !aQuoteMode) + { + if (!aQuoteMode) + { + i++; + break; + } + } + else + aProgramName += aChar; + } + aCommands = aCommandLine.Mid(i); +} +*/ + +DWORD GetDllVersion(LPCTSTR lpszDllName) +{ + HINSTANCE hinstDll; + DWORD dwVersion = 0; + hinstDll = LoadLibrary(lpszDllName); + if(hinstDll) + { + DLLGETVERSIONPROC pDllGetVersion; + pDllGetVersion = (DLLGETVERSIONPROC) GetProcAddress(hinstDll, "DllGetVersion"); + + /*Because some DLLs might not implement this function, you + must test for it explicitly. Depending on the particular + DLL, the lack of a DllGetVersion function can be a useful + indicator of the version. + */ + if(pDllGetVersion) + { + DLLVERSIONINFO dvi; + HRESULT hr; + + ZeroMemory(&dvi, sizeof(dvi)); + dvi.cbSize = sizeof(dvi); + + hr = (*pDllGetVersion)(&dvi); + + if(SUCCEEDED(hr)) + { + dwVersion = MAKELONG(dvi.dwMinorVersion, dvi.dwMajorVersion); + } + } + FreeLibrary(hinstDll); + } + return dwVersion; +} + +DWORD g_ComCtl32Version; + +/* +#ifndef _WIN64 +typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); + +static bool IsWow64() +{ + LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress( + GetModuleHandle("kernel32"), "IsWow64Process"); + if (fnIsWow64Process == NULL) + return false; + BOOL isWow; + if (!fnIsWow64Process(GetCurrentProcess(),&isWow)) + return false; + return isWow != FALSE; +} +#endif +*/ + +bool IsLargePageSupported() +{ + #ifdef _WIN64 + return true; + #else + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + if (versionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || versionInfo.dwMajorVersion < 5) + return false; + if (versionInfo.dwMajorVersion > 5) + return true; + if (versionInfo.dwMinorVersion < 1) + return false; + if (versionInfo.dwMinorVersion > 1) + return true; + // return IsWow64(); + return false; + #endif +} + +static void SetMemoryLock() +{ + if (!IsLargePageSupported()) + return; + // if (ReadLockMemoryAdd()) + NSecurity::AddLockMemoryPrivilege(); + + if (ReadLockMemoryEnable()) + NSecurity::EnableLockMemoryPrivilege(); +} + +/* +static const int kNumSwitches = 1; + +namespace NKey { +enum Enum +{ + kOpenArachive = 0, +}; + +} + +static const CSwitchForm kSwitchForms[kNumSwitches] = + { + { L"SOA", NSwitchType::kSimple, false }, + }; +*/ + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, LPSTR /* lpCmdLine */, int nCmdShow) +{ + #ifndef _UNICODE + g_IsNT = IsItWindowsNT(); + #endif + + #ifdef _WIN32 + SetLargePageSize(); + #endif + + InitCommonControls(); + + g_ComCtl32Version = ::GetDllVersion(TEXT("comctl32.dll")); + + // OleInitialize is required for drag and drop. + OleInitialize(NULL); + // Maybe needs CoInitializeEx also ? + // NCOM::CComInitializer comInitializer; + + UString programString, commandsString; + // MessageBoxW(0, GetCommandLineW(), L"", 0); + SplitStringToTwoStrings(GetCommandLineW(), programString, commandsString); + + commandsString.Trim(); + UString paramString, tailString; + SplitStringToTwoStrings(commandsString, paramString, tailString); + paramString.Trim(); + + if (!paramString.IsEmpty()) + { + g_MainPath = paramString; + // MessageBoxW(0, paramString, L"", 0); + } + /* + UStringVector commandStrings; + NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); + NCommandLineParser::CParser parser(kNumSwitches); + try + { + parser.ParseStrings(kSwitchForms, commandStrings); + const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; + if(nonSwitchStrings.Size() > 1) + { + g_MainPath = nonSwitchStrings[1]; + // g_OpenArchive = parser[NKey::kOpenArachive].ThereIs; + CFileInfoW fileInfo; + if (FindFile(g_MainPath, fileInfo)) + { + if (!fileInfo.IsDirectory()) + g_OpenArchive = true; + } + } + } + catch(...) { } + */ + + + SetMemoryLock(); + + MSG msg; + if (!InitInstance (hInstance, nCmdShow)) + return FALSE; + + MyLoadMenu(g_HWND); + + #ifndef _UNICODE + if (g_IsNT) + { + HACCEL hAccels = LoadAcceleratorsW(hInstance, MAKEINTRESOURCEW(IDR_ACCELERATOR1)); + while (GetMessageW(&msg, NULL, 0, 0)) + { + if (TranslateAcceleratorW(g_HWND, hAccels, &msg) == 0) + { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + } + } + else + #endif + { + HACCEL hAccels = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1)); + while (GetMessage(&msg, NULL, 0, 0)) + { + if (TranslateAccelerator(g_HWND, hAccels, &msg) == 0) + { + // if (g_Hwnd != NULL || !IsDialogMessage(g_Hwnd, &msg)) + // if (!IsDialogMessage(g_Hwnd, &msg)) + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + } + + g_HWND = 0; + OleUninitialize(); + return (int)msg.wParam; +} + +static void SaveWindowInfo(HWND aWnd) +{ + /* + RECT rect; + if (!::GetWindowRect(aWnd, &rect)) + return; + */ + WINDOWPLACEMENT placement; + placement.length = sizeof(placement); + if (!::GetWindowPlacement(aWnd, &placement)) + return; + SaveWindowSize(placement.rcNormalPosition, + BOOLToBool(::IsZoomed(aWnd))); + SavePanelsInfo(g_App.NumPanels, g_App.LastFocusedPanel, + g_Splitter.GetPos()); +} + +void ExecuteCommand(UINT commandID) +{ + switch (commandID) + { + case kAddCommand: + g_App.AddToArchive(); + break; + case kExtractCommand: + g_App.ExtractArchives(); + break; + case kTestCommand: + g_App.TestArchives(); + break; + } +} + +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + int wmId, wmEvent; + switch (message) + { + case WM_COMMAND: + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + if ((HWND) lParam != NULL && wmEvent != 0) + break; + if (wmId >= kToolbarStartID) + { + ExecuteCommand(wmId); + return 0; + } + if (OnMenuCommand(hWnd, wmId)) + return 0; + break; + case WM_INITMENUPOPUP: + OnMenuActivating(hWnd, HMENU(wParam), LOWORD(lParam)); + break; + + /* + It doesn't help + case WM_EXITMENULOOP: + { + OnMenuUnActivating(hWnd); + break; + } + case WM_UNINITMENUPOPUP: + OnMenuUnActivating(hWnd, HMENU(wParam), lParam); + break; + */ + + case WM_CREATE: + { + + /* + INITCOMMONCONTROLSEX icex; + icex.dwSize = sizeof(INITCOMMONCONTROLSEX); + icex.dwICC = ICC_BAR_CLASSES; + InitCommonControlsEx(&icex); + + // Toolbar buttons used to create the first 4 buttons. + TBBUTTON tbb [ ] = + { + // {0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0}, + // {VIEW_PARENTFOLDER, kParentFolderID, TBSTATE_ENABLED, BTNS_BUTTON, 0L, 0}, + // {0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0}, + {VIEW_NEWFOLDER, ID_FILE_CREATEFOLDER, TBSTATE_ENABLED, BTNS_BUTTON, 0L, 0}, + }; + + int baseID = 100; + NWindows::NControl::CToolBar aToolBar; + aToolBar.Attach(::CreateToolbarEx (hWnd, + WS_CHILD | WS_BORDER | WS_VISIBLE | TBSTYLE_TOOLTIPS, // | TBSTYLE_FLAT + baseID + 2, 11, + (HINSTANCE)HINST_COMMCTRL, IDB_VIEW_SMALL_COLOR, + (LPCTBBUTTON)&tbb, sizeof(tbb) / sizeof(tbb[0]), + 0, 0, 100, 30, sizeof (TBBUTTON))); + */ + // HCURSOR cursor = ::LoadCursor(0, IDC_SIZEWE); + // ::SetCursor(cursor); + + if (g_PanelsInfoDefined) + g_Splitter.SetPos(hWnd, g_SplitterPos); + else + { + g_Splitter.SetRatio(hWnd, kSplitterRateMax / 2); + g_SplitterPos = g_Splitter.GetPos(); + } + + RECT rect; + ::GetClientRect(hWnd, &rect); + int xSize = rect.right; + int xSizes[2]; + xSizes[0] = g_Splitter.GetPos(); + xSizes[1] = xSize - kSplitterWidth - xSizes[0]; + if (xSizes[1] < 0) + xSizes[1] = 0; + + g_App.CreateDragTarget(); + bool archiveIsOpened; + bool encrypted; + g_App.Create(hWnd, g_MainPath, xSizes, archiveIsOpened, encrypted); + if (!archiveIsOpened && g_OpenArchive) + { + UString message; + if (encrypted) + message = MyFormatNew(IDS_CANT_OPEN_ENCRYPTED_ARCHIVE, 0x0200060A, g_MainPath); + else + message = MyFormatNew(IDS_CANT_OPEN_ARCHIVE, 0x02000609, g_MainPath); + MessageBoxW(0, message, L"7-zip", MB_ICONERROR); + return -1; + } + // g_SplitterPos = 0; + + // ::DragAcceptFiles(hWnd, TRUE); + RegisterDragDrop(hWnd, g_App._dropTarget); + + break; + } + case WM_DESTROY: + { + // ::DragAcceptFiles(hWnd, FALSE); + RevokeDragDrop(hWnd); + g_App._dropTarget.Release(); + + g_App.Save(); + g_App.Release(); + SaveWindowInfo(hWnd); + PostQuitMessage(0); + break; + } + /* + case WM_MOVE: + { + break; + } + */ + case WM_LBUTTONDOWN: + g_StartCaptureMousePos = LOWORD(lParam); + g_StartCaptureSplitterPos = g_Splitter.GetPos(); + ::SetCapture(hWnd); + break; + case WM_LBUTTONUP: + { + ::ReleaseCapture(); + break; + } + case WM_MOUSEMOVE: + { + if ((wParam & MK_LBUTTON) != 0 && ::GetCapture() == hWnd) + { + g_Splitter.SetPos(hWnd, g_StartCaptureSplitterPos + + (short)LOWORD(lParam) - g_StartCaptureMousePos); + MoveSubWindows(hWnd); + } + break; + } + + case WM_SIZE: + { + if (g_CanChangeSplitter) + g_Splitter.SetPosFromRatio(hWnd); + else + { + g_Splitter.SetPos(hWnd, g_SplitterPos ); + g_CanChangeSplitter = true; + } + + OnSize(hWnd); + /* + int xSize = LOWORD(lParam); + int ySize = HIWORD(lParam); + // int xSplitter = 2; + int xWidth = g_SplitPos; + // int xSplitPos = xWidth; + g_Panel[0]._listView.MoveWindow(0, 0, xWidth, ySize); + g_Panel[1]._listView.MoveWindow(xSize - xWidth, 0, xWidth, ySize); + */ + return 0; + break; + } + case WM_SETFOCUS: + // g_App.SetFocus(g_App.LastFocusedPanel); + g_App.SetFocusToLastItem(); + break; + /* + case WM_ACTIVATE: + { + int fActive = LOWORD(wParam); + switch (fActive) + { + case WA_INACTIVE: + { + // g_FocusIndex = g_App.LastFocusedPanel; + // g_App.LastFocusedPanel = g_App.GetFocusedPanelIndex(); + // return 0; + } + } + break; + } + */ + /* + case kLangWasChangedMessage: + MyLoadMenu(g_HWND); + return 0; + */ + + /* + case WM_SETTINGCHANGE: + break; + */ + case WM_NOTIFY: + { + g_App.OnNotify((int)wParam, (LPNMHDR)lParam); + break; + } + /* + case WM_DROPFILES: + { + g_App.GetFocusedPanel().CompressDropFiles((HDROP)wParam); + return 0 ; + } + */ + } + #ifndef _UNICODE + if (g_IsNT) + return DefWindowProcW(hWnd, message, wParam, lParam); + else + #endif + return DefWindowProc(hWnd, message, wParam, lParam); + +} + +void OnSize(HWND hWnd) +{ + /* + if (g_App._rebar) + { + RECT rect; + ::GetClientRect(hWnd, &rect); + int xSize = rect.right; + int ySize = rect.bottom; + // rect.bottom = 0; + // g_App._rebar.SizeToRect(&rect); + // g_App._rebar.Move(0, 0, xSize, ySize); + } + */ + MoveSubWindows(hWnd); +} + +void MoveSubWindows(HWND hWnd) +{ + RECT rect; + ::GetClientRect(hWnd, &rect); + int xSize = rect.right; + int kHeaderSize = 0; + int ySize = MyMax(int(rect.bottom - kHeaderSize), 0); + if (g_App._rebar) + { + RECT barRect; + g_App._rebar.GetWindowRect(&barRect); + kHeaderSize = barRect.bottom - barRect.top; + ySize = MyMax(int(rect.bottom - kHeaderSize), 0); + } + + // g_App._headerToolBar.Move(0, 2, xSize, kHeaderSize - 2); + RECT rect2 = rect; + rect2.bottom = 0; + // g_App._headerReBar.SizeToRect(&rect2); + if (g_App.NumPanels > 1) + { + g_App.Panels[0].Move(0, kHeaderSize, g_Splitter.GetPos(), ySize); + int xWidth1 = g_Splitter.GetPos() + kSplitterWidth; + g_App.Panels[1].Move(xWidth1, kHeaderSize, xSize - xWidth1, ySize); + } + else + { + /* + int otherPanel = 1 - g_App.LastFocusedPanel; + if (g_App.PanelsCreated[otherPanel]) + g_App.Panels[otherPanel].Move(0, kHeaderSize, 0, ySize); + */ + g_App.Panels[g_App.LastFocusedPanel].Move(0, kHeaderSize, xSize, ySize); + } +} diff --git a/CPP/7zip/FileManager/FM.dsp b/CPP/7zip/FileManager/FM.dsp new file mode 100755 index 00000000..75c95ead --- /dev/null +++ b/CPP/7zip/FileManager/FM.dsp @@ -0,0 +1,1251 @@ +# Microsoft Developer Studio Project File - Name="FM" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=FM - Win32 DebugU +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "FM.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "FM.mak" CFG="FM - Win32 DebugU" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "FM - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "FM - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "FM - Win32 ReleaseU" (based on "Win32 (x86) Application") +!MESSAGE "FM - Win32 DebugU" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "FM - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "WIN_LONG_PATH" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Program Files\7-ZIP\7zFM.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "FM - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "WIN_LONG_PATH" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Program Files\7-ZIP\7zFM.exe" /pdbtype:sept + +!ELSEIF "$(CFG)" == "FM - Win32 ReleaseU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ReleaseU" +# PROP BASE Intermediate_Dir "ReleaseU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseU" +# PROP Intermediate_Dir "ReleaseU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "WIN_LONG_PATH" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Program Files\7-ZIP\7zFMn.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "FM - Win32 DebugU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "DebugU" +# PROP BASE Intermediate_Dir "DebugU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugU" +# PROP Intermediate_Dir "DebugU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "WIN_LONG_PATH" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Program Files\7-ZIP\7zFMn.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "FM - Win32 Release" +# Name "FM - Win32 Debug" +# Name "FM - Win32 ReleaseU" +# Name "FM - Win32 DebugU" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Resource\AboutDialog\7zipLogo.ico +# End Source File +# Begin Source File + +SOURCE=.\add.bmp +# End Source File +# Begin Source File + +SOURCE=.\ClassDefs.cpp +# End Source File +# Begin Source File + +SOURCE=.\Copy.bmp +# End Source File +# Begin Source File + +SOURCE=.\Delete.bmp +# End Source File +# Begin Source File + +SOURCE=.\Extract.bmp +# End Source File +# Begin Source File + +SOURCE=.\FM.ico +# End Source File +# Begin Source File + +SOURCE=.\Move.bmp +# End Source File +# Begin Source File + +SOURCE=.\Parent.bmp +# End Source File +# Begin Source File + +SOURCE=.\Properties.bmp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# ADD BASE RSC /l 0x419 +# ADD RSC /l 0x409 +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# Begin Source File + +SOURCE=.\Test.bmp +# End Source File +# End Group +# Begin Group "Archive Interfaces" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Archive\IArchive.h +# End Source File +# Begin Source File + +SOURCE=..\UI\Agent\IFolderArchive.h +# End Source File +# End Group +# Begin Group "Folders" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\FSDrives.cpp +# End Source File +# Begin Source File + +SOURCE=.\FSDrives.h +# End Source File +# Begin Source File + +SOURCE=.\FSFolder.cpp +# End Source File +# Begin Source File + +SOURCE=.\FSFolder.h +# End Source File +# Begin Source File + +SOURCE=.\FSFolderCopy.cpp +# End Source File +# Begin Source File + +SOURCE=.\IFolder.h +# End Source File +# Begin Source File + +SOURCE=.\NetFolder.cpp +# End Source File +# Begin Source File + +SOURCE=.\NetFolder.h +# End Source File +# Begin Source File + +SOURCE=.\PhysDriveFolder.cpp +# End Source File +# Begin Source File + +SOURCE=.\PhysDriveFolder.h +# End Source File +# Begin Source File + +SOURCE=.\RootFolder.cpp +# End Source File +# Begin Source File + +SOURCE=.\RootFolder.h +# End Source File +# End Group +# Begin Group "Registry" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\RegistryAssociations.cpp +# End Source File +# Begin Source File + +SOURCE=.\RegistryAssociations.h +# End Source File +# Begin Source File + +SOURCE=.\RegistryPlugins.cpp +# End Source File +# Begin Source File + +SOURCE=.\RegistryPlugins.h +# End Source File +# Begin Source File + +SOURCE=.\RegistryUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\RegistryUtils.h +# End Source File +# Begin Source File + +SOURCE=.\ViewSettings.cpp +# End Source File +# Begin Source File + +SOURCE=.\ViewSettings.h +# End Source File +# End Group +# Begin Group "Panel" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\App.cpp +# End Source File +# Begin Source File + +SOURCE=.\App.h +# End Source File +# Begin Source File + +SOURCE=.\AppState.h +# End Source File +# Begin Source File + +SOURCE=.\EnumFormatEtc.cpp +# End Source File +# Begin Source File + +SOURCE=.\EnumFormatEtc.h +# End Source File +# Begin Source File + +SOURCE=.\FileFolderPluginOpen.cpp +# End Source File +# Begin Source File + +SOURCE=.\FileFolderPluginOpen.h +# End Source File +# Begin Source File + +SOURCE=.\Panel.cpp +# End Source File +# Begin Source File + +SOURCE=.\Panel.h +# End Source File +# Begin Source File + +SOURCE=.\PanelCopy.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelCrc.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelDrag.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelFolderChange.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelItemOpen.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelItems.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelKey.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelListNotify.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelMenu.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelOperations.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelSelect.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelSort.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelSplitFile.cpp +# End Source File +# End Group +# Begin Group "Dialog" + +# PROP Default_Filter "" +# Begin Group "Options" + +# PROP Default_Filter "" +# Begin Group "Settings" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Resource\SettingsPage\SettingsPage.cpp +# End Source File +# Begin Source File + +SOURCE=.\Resource\SettingsPage\SettingsPage.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\Resource\EditPage\EditPage.cpp +# End Source File +# Begin Source File + +SOURCE=.\Resource\EditPage\EditPage.h +# End Source File +# Begin Source File + +SOURCE=.\Resource\LangPage\LangPage.cpp +# End Source File +# Begin Source File + +SOURCE=.\Resource\LangPage\LangPage.h +# End Source File +# Begin Source File + +SOURCE=.\Resource\PluginsPage\PluginsPage.cpp +# End Source File +# Begin Source File + +SOURCE=.\Resource\PluginsPage\PluginsPage.h +# End Source File +# Begin Source File + +SOURCE=.\Resource\SystemPage\SystemPage.cpp +# End Source File +# Begin Source File + +SOURCE=.\Resource\SystemPage\SystemPage.h +# End Source File +# End Group +# Begin Group "Password" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=Resource\PasswordDialog\PasswordDialog.cpp +# End Source File +# Begin Source File + +SOURCE=Resource\PasswordDialog\PasswordDialog.h +# End Source File +# End Group +# Begin Group "Progress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Resource\ProgressDialog2\ProgressDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\Resource\ProgressDialog2\ProgressDialog.h +# End Source File +# End Group +# Begin Group "About" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Resource\AboutDialog\AboutDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\Resource\AboutDialog\AboutDialog.h +# End Source File +# End Group +# Begin Group "Benchmark" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Resource\BenchmarkDialog\BenchmarkDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\Resource\BenchmarkDialog\BenchmarkDialog.h +# End Source File +# End Group +# Begin Group "Split" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Resource\SplitDialog\SplitDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\Resource\SplitDialog\SplitDialog.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\Resource\ComboDialog\ComboDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\Resource\ComboDialog\ComboDialog.h +# End Source File +# Begin Source File + +SOURCE=.\Resource\CopyDialog\CopyDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\Resource\CopyDialog\CopyDialog.h +# End Source File +# Begin Source File + +SOURCE=.\Resource\ListViewDialog\ListViewDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\Resource\ListViewDialog\ListViewDialog.h +# End Source File +# Begin Source File + +SOURCE=Resource\MessagesDialog\MessagesDialog.cpp +# End Source File +# Begin Source File + +SOURCE=Resource\MessagesDialog\MessagesDialog.h +# End Source File +# Begin Source File + +SOURCE=Resource\OverwriteDialog\OverwriteDialog.cpp +# End Source File +# Begin Source File + +SOURCE=Resource\OverwriteDialog\OverwriteDialog.h +# End Source File +# End Group +# Begin Group "FM Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=.\ExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=.\FormatUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\FormatUtils.h +# End Source File +# Begin Source File + +SOURCE=.\HelpUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\HelpUtils.h +# End Source File +# Begin Source File + +SOURCE=.\LangUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\LangUtils.h +# End Source File +# Begin Source File + +SOURCE=.\ProgramLocation.cpp +# End Source File +# Begin Source File + +SOURCE=.\ProgramLocation.h +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallback100.cpp +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallback100.h +# End Source File +# End Group +# Begin Group "SDK" + +# PROP Default_Filter "" +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Group "Control" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Windows\Control\ComboBox.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Control\ComboBox.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Control\CommandBar.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Control\Dialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Control\Dialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Control\Edit.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Control\ImageList.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Control\ListView.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Control\ListView.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Control\ProgressBar.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Control\PropertyPage.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Control\PropertyPage.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Control\ReBar.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Control\Static.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Control\StatusBar.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Control\ToolBar.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Control\Trackbar.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Control\Window2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Control\Window2.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\Windows\CommonDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\CommonDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Device.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Error.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Error.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\FileDevice.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\FileDevice.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\FileSystem.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\FileSystem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Handle.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Memory.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Memory.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\MemoryLock.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\MemoryLock.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Menu.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Menu.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Net.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Net.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Process.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\PropVariant.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\PropVariantConversions.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\PropVariantConversions.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Registry.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Registry.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\ResourceString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\ResourceString.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Security.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Security.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Shell.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Shell.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Thread.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Time.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Timer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Window.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Windows\Window.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\Buffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CommandLineParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CommandLineParser.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ComTry.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\DynamicBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\Exception.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\Lang.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\Lang.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\Random.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\Random.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StdInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StdInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StdOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StdOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\TextConfig.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\TextConfig.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\Types.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\Vector.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\Wildcard.h +# End Source File +# End Group +# End Group +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\UI\Common\ArchiveName.cpp +# End Source File +# Begin Source File + +SOURCE=..\UI\Common\ArchiveName.h +# End Source File +# Begin Source File + +SOURCE=..\UI\Common\CompressCall.cpp +# End Source File +# Begin Source File + +SOURCE=..\UI\Common\CompressCall.h +# End Source File +# Begin Source File + +SOURCE=..\UI\Common\PropIDUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\UI\Common\PropIDUtils.h +# End Source File +# End Group +# Begin Group "7-Zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\FilePathAutoRename.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\FilePathAutoRename.h +# End Source File +# Begin Source File + +SOURCE=..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\StreamObjects.h +# End Source File +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\C\Sort.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\C\Sort.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\7zFM.exe.manifest +# End Source File +# Begin Source File + +SOURCE=.\7zipLogo.ico +# End Source File +# Begin Source File + +SOURCE=.\Add2.bmp +# End Source File +# Begin Source File + +SOURCE=.\Copy2.bmp +# End Source File +# Begin Source File + +SOURCE=.\Delete2.bmp +# End Source File +# Begin Source File + +SOURCE=.\Extract2.bmp +# End Source File +# Begin Source File + +SOURCE=.\FilePlugins.cpp +# End Source File +# Begin Source File + +SOURCE=.\FilePlugins.h +# End Source File +# Begin Source File + +SOURCE=.\FM.cpp +# End Source File +# Begin Source File + +SOURCE=.\Info.bmp +# End Source File +# Begin Source File + +SOURCE=.\Info2.bmp +# End Source File +# Begin Source File + +SOURCE=.\Move2.bmp +# End Source File +# Begin Source File + +SOURCE=.\MyCom2.h +# End Source File +# Begin Source File + +SOURCE=.\MyLoadMenu.cpp +# End Source File +# Begin Source File + +SOURCE=.\MyLoadMenu.h +# End Source File +# Begin Source File + +SOURCE=.\OpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=.\OpenCallback.h +# End Source File +# Begin Source File + +SOURCE=.\OptionsDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\PluginInterface.h +# End Source File +# Begin Source File + +SOURCE=.\PluginLoader.h +# End Source File +# Begin Source File + +SOURCE=.\PropertyName.cpp +# End Source File +# Begin Source File + +SOURCE=.\PropertyName.h +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\SplitUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\SplitUtils.h +# End Source File +# Begin Source File + +SOURCE=.\StringUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\StringUtils.h +# End Source File +# Begin Source File + +SOURCE=.\SysIconUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\SysIconUtils.h +# End Source File +# Begin Source File + +SOURCE=.\Test2.bmp +# End Source File +# Begin Source File + +SOURCE=.\TextPairs.cpp +# End Source File +# Begin Source File + +SOURCE=.\TextPairs.h +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/FileManager/FM.dsw b/CPP/7zip/FileManager/FM.dsw new file mode 100755 index 00000000..1c955d95 --- /dev/null +++ b/CPP/7zip/FileManager/FM.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "FM"=.\FM.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/FileManager/FM.ico b/CPP/7zip/FileManager/FM.ico new file mode 100755 index 00000000..3a0a34da Binary files /dev/null and b/CPP/7zip/FileManager/FM.ico differ diff --git a/CPP/7zip/FileManager/FSDrives.cpp b/CPP/7zip/FileManager/FSDrives.cpp new file mode 100755 index 00000000..447ff4dc --- /dev/null +++ b/CPP/7zip/FileManager/FSDrives.cpp @@ -0,0 +1,240 @@ +// FSDrives.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "FSDrives.h" + +#include "Common/StringConvert.h" +#include "../PropID.h" +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" +#include "Windows/FileDir.h" +#include "Windows/FileSystem.h" + +#include "SysIconUtils.h" +#include "FSFolder.h" +#include "PhysDriveFolder.h" +#include "LangUtils.h" + +using namespace NWindows; +using namespace NFile; +using namespace NFind; + +static const STATPROPSTG kProperties[] = +{ + { NULL, kpidName, VT_BSTR}, + // { NULL, kpidIsFolder, VT_BOOL}, + { L"Total Size", kpidTotalSize, VT_UI8}, + { L"Free Space", kpidFreeSpace, VT_UI8}, + { NULL, kpidType, VT_BSTR}, + { L"Label", kpidVolumeName, VT_BSTR}, + { L"File system", kpidFileSystem, VT_BSTR}, + { L"Cluster Size", kpidClusterSize, VT_UI8} +}; + +static const wchar_t *kDriveTypes[] = +{ + L"Unknown", + L"No Root Dir", + L"Removable", + L"Fixed", + L"Remote", + L"CD-ROM", + L"RAM disk" +}; + +STDMETHODIMP CFSDrives::LoadItems() +{ + _drives.Clear(); + + UStringVector driveStrings; + MyGetLogicalDriveStrings(driveStrings); + for (int i = 0; i < driveStrings.Size(); i++) + { + CDriveInfo driveInfo; + + const UString &driveName = driveStrings[i]; + + driveInfo.FullSystemName = driveName; + + driveInfo.Name = driveInfo.FullSystemName.Left( + driveInfo.FullSystemName.Length() - 1); + driveInfo.ClusterSize = 0; + driveInfo.DriveSize = 0; + driveInfo.FreeSpace = 0; + UINT driveType = NFile::NSystem::MyGetDriveType(driveName); + if (driveType < sizeof(kDriveTypes) / sizeof(kDriveTypes[0])) + { + driveInfo.Type = kDriveTypes[driveType]; + } + bool needRead = true; + if (driveType == DRIVE_CDROM || driveType == DRIVE_REMOVABLE) + { + /* + DWORD dwSerialNumber;` + if (!::GetVolumeInformation(driveInfo.FullSystemName, + NULL, 0, &dwSerialNumber, NULL, NULL, NULL, 0)) + */ + driveInfo.KnownSizes = false; + { + needRead = false; + } + } + if (needRead) + { + UString volumeName, fileSystemName; + DWORD volumeSerialNumber, maximumComponentLength, fileSystemFlags; + NFile::NSystem::MyGetVolumeInformation(driveName, + volumeName, + &volumeSerialNumber, &maximumComponentLength, &fileSystemFlags, + fileSystemName); + driveInfo.VolumeName = volumeName; + driveInfo.FileSystemName = fileSystemName; + + NFile::NSystem::MyGetDiskFreeSpace(driveName, + driveInfo.ClusterSize, driveInfo.DriveSize, driveInfo.FreeSpace); + driveInfo.KnownSizes = true; + } + _drives.Add(driveInfo); + } + return S_OK; +} + +STDMETHODIMP CFSDrives::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _drives.Size(); + return S_OK; +} + +STDMETHODIMP CFSDrives::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value) +{ + if (itemIndex >= (UInt32)_drives.Size()) + return E_INVALIDARG; + NCOM::CPropVariant propVariant; + const CDriveInfo &driveInfo = _drives[itemIndex]; + switch(propID) + { + case kpidIsFolder: + propVariant = true; + break; + case kpidName: + propVariant = driveInfo.Name; + break; + case kpidTotalSize: + if (driveInfo.KnownSizes) + propVariant = driveInfo.DriveSize; + break; + case kpidFreeSpace: + if (driveInfo.KnownSizes) + propVariant = driveInfo.FreeSpace; + break; + case kpidClusterSize: + if (driveInfo.KnownSizes) + propVariant = driveInfo.ClusterSize; + break; + case kpidType: + propVariant = driveInfo.Type; + break; + case kpidVolumeName: + propVariant = driveInfo.VolumeName; + break; + case kpidFileSystem: + propVariant = driveInfo.FileSystemName; + break; + } + propVariant.Detach(value); + return S_OK; +} + +HRESULT CFSDrives::BindToFolderSpec(const wchar_t *name, IFolderFolder **resultFolder) +{ + *resultFolder = 0; + CFSFolder *fsFolderSpec = new CFSFolder; + CMyComPtr subFolder = fsFolderSpec; + RINOK(fsFolderSpec->Init(name, 0)); + *resultFolder = subFolder.Detach(); + return S_OK; +} + +STDMETHODIMP CFSDrives::BindToFolder(UInt32 index, IFolderFolder **resultFolder) +{ + *resultFolder = 0; + if (index >= (UInt32)_drives.Size()) + return E_INVALIDARG; + const CDriveInfo &driveInfo = _drives[index]; + if (_volumeMode) + { + *resultFolder = 0; + CPhysDriveFolder *folderSpec = new CPhysDriveFolder; + CMyComPtr subFolder = folderSpec; + RINOK(folderSpec->Init(driveInfo.Name)); + *resultFolder = subFolder.Detach(); + return S_OK; + } + return BindToFolderSpec(driveInfo.FullSystemName, resultFolder); +} + +STDMETHODIMP CFSDrives::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder) +{ + return BindToFolderSpec(name, resultFolder); +} + +STDMETHODIMP CFSDrives::BindToParentFolder(IFolderFolder **resultFolder) +{ + *resultFolder = 0; + return S_OK; +} + +STDMETHODIMP CFSDrives::GetName(BSTR * /* name */) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CFSDrives::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CFSDrives::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if (index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &prop = kProperties[index]; + *propID = prop.propid; + *varType = prop.vt; + *name = 0; + return S_OK; +} + + +STDMETHODIMP CFSDrives::GetTypeID(BSTR *name) +{ + CMyComBSTR temp = L"FSDrives"; + *name = temp.Detach(); + return S_OK; +} + +STDMETHODIMP CFSDrives::GetPath(BSTR *path) +{ + CMyComBSTR temp = LangString(IDS_COMPUTER, 0x03020300) + UString(L'\\'); + *path = temp.Detach(); + return S_OK; +} + +STDMETHODIMP CFSDrives::GetSystemIconIndex(UInt32 index, INT32 *iconIndex) +{ + *iconIndex = 0; + const CDriveInfo &driveInfo = _drives[index]; + int iconIndexTemp; + if (GetRealIconIndex(driveInfo.FullSystemName, 0, iconIndexTemp) != 0) + { + *iconIndex = iconIndexTemp; + return S_OK; + } + return GetLastError(); +} + diff --git a/CPP/7zip/FileManager/FSDrives.h b/CPP/7zip/FileManager/FSDrives.h new file mode 100755 index 00000000..496e8fc1 --- /dev/null +++ b/CPP/7zip/FileManager/FSDrives.h @@ -0,0 +1,66 @@ +// FSDrives.h + +#ifndef __FSDRIVES_H +#define __FSDRIVES_H + +#include "Common/String.h" +#include "Common/Types.h" +#include "Common/MyCom.h" +#include "Windows/FileFind.h" +#include "Windows/PropVariant.h" + +#include "IFolder.h" + +struct CDriveInfo +{ + UString Name; + UString FullSystemName; + bool KnownSizes; + UInt64 DriveSize; + UInt64 FreeSpace; + UInt64 ClusterSize; + UString Type; + UString VolumeName; + UString FileSystemName; +}; + +class CFSDrives: + public IFolderFolder, + public IEnumProperties, + public IFolderGetTypeID, + public IFolderGetPath, + public IFolderGetSystemIconIndex, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP4( + IEnumProperties, + IFolderGetTypeID, + IFolderGetPath, + IFolderGetSystemIconIndex + ) + + STDMETHOD(LoadItems)(); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 itemIndex, PROPID propID, PROPVARIANT *value); + STDMETHOD(BindToFolder)(UInt32 index, IFolderFolder **resultFolder); + STDMETHOD(BindToFolder)(const wchar_t *name, IFolderFolder **resultFolder); + STDMETHOD(BindToParentFolder)(IFolderFolder **resultFolder); + STDMETHOD(GetName)(BSTR *name); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + STDMETHOD(GetTypeID)(BSTR *name); + STDMETHOD(GetPath)(BSTR *path); + STDMETHOD(GetSystemIconIndex)(UInt32 index, INT32 *iconIndex); + +private: + HRESULT BindToFolderSpec(const wchar_t *name, IFolderFolder **resultFolder); + CObjectVector _drives; + bool _volumeMode; +public: + void Init() { _volumeMode = false;} +}; + +#endif diff --git a/CPP/7zip/FileManager/FSFolder.cpp b/CPP/7zip/FileManager/FSFolder.cpp new file mode 100755 index 00000000..309128ae --- /dev/null +++ b/CPP/7zip/FileManager/FSFolder.cpp @@ -0,0 +1,655 @@ +// FSFolder.cpp + +#include "StdAfx.h" + +#include "FSFolder.h" + +#include "Common/StringConvert.h" +#include "Common/StdInStream.h" +#include "Common/StdOutStream.h" +#include "Common/UTFConvert.h" + +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" +#include "Windows/FileDir.h" +#include "Windows/FileIO.h" + +#include "../PropID.h" + +#include "SysIconUtils.h" +#include "FSDrives.h" +#include "NetFolder.h" + +namespace NWindows { +namespace NFile { + +bool GetLongPath(LPCWSTR path, UString &longPath); + +}} + +using namespace NWindows; +using namespace NFile; +using namespace NFind; + +static STATPROPSTG kProperties[] = +{ + { NULL, kpidName, VT_BSTR}, + // { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidLastWriteTime, VT_FILETIME}, + { NULL, kpidCreationTime, VT_FILETIME}, + { NULL, kpidLastAccessTime, VT_FILETIME}, + { NULL, kpidAttributes, VT_UI4}, + { NULL, kpidPackedSize, VT_UI8}, + { NULL, kpidComment, VT_BSTR}, + { NULL, kpidPrefix, VT_BSTR} +}; + +HRESULT CFSFolder::Init(const UString &path, IFolderFolder *parentFolder) +{ + _parentFolder = parentFolder; + _path = path; + + _findChangeNotification.FindFirst(_path, false, + FILE_NOTIFY_CHANGE_FILE_NAME | + FILE_NOTIFY_CHANGE_DIR_NAME | + FILE_NOTIFY_CHANGE_ATTRIBUTES | + FILE_NOTIFY_CHANGE_SIZE | + FILE_NOTIFY_CHANGE_LAST_WRITE /*| + FILE_NOTIFY_CHANGE_LAST_ACCESS | + FILE_NOTIFY_CHANGE_CREATION | + FILE_NOTIFY_CHANGE_SECURITY */); + if (!_findChangeNotification.IsHandleAllocated()) + { + DWORD lastError = GetLastError(); + CFindFile findFile; + CFileInfoW fileInfo; + if (!findFile.FindFirst(_path + UString(L"*"), fileInfo)) + return lastError; + } + return S_OK; +} + +static HRESULT GetFolderSize(const UString &path, UInt64 &size, IProgress *progress) +{ + RINOK(progress->SetCompleted(NULL)); + size = 0; + CEnumeratorW enumerator(path + UString(L"\\*")); + CFileInfoW fileInfo; + while (enumerator.Next(fileInfo)) + { + if (fileInfo.IsDirectory()) + { + UInt64 subSize; + RINOK(GetFolderSize(path + UString(L"\\") + fileInfo.Name, subSize, progress)); + size += subSize; + } + else + size += fileInfo.Size; + } + return S_OK; +} + +HRESULT CFSFolder::LoadSubItems(CDirItem &dirItem, const UString &path) +{ + { + CEnumeratorW enumerator(path + L"*"); + CDirItem fileInfo; + while (enumerator.Next(fileInfo)) + { + fileInfo.CompressedSizeIsDefined = false; + /* + if (!GetCompressedFileSize(_path + fileInfo.Name, + fileInfo.CompressedSize)) + fileInfo.CompressedSize = fileInfo.Size; + */ + if (fileInfo.IsDirectory()) + { + // fileInfo.Size = GetFolderSize(_path + fileInfo.Name); + fileInfo.Size = 0; + } + dirItem.Files.Add(fileInfo); + } + } + if (!_flatMode) + return S_OK; + + for (int i = 0; i < dirItem.Files.Size(); i++) + { + CDirItem &item = dirItem.Files[i]; + if (item.IsDirectory()) + LoadSubItems(item, path + item.Name + L'\\'); + } + return S_OK; +} + +void CFSFolder::AddRefs(CDirItem &dirItem) +{ + int i; + for (i = 0; i < dirItem.Files.Size(); i++) + { + CDirItem &item = dirItem.Files[i]; + item.Parent = &dirItem; + _refs.Add(&item); + } + if (!_flatMode) + return; + for (i = 0; i < dirItem.Files.Size(); i++) + { + CDirItem &item = dirItem.Files[i]; + if (item.IsDirectory()) + AddRefs(item); + } +} + +STDMETHODIMP CFSFolder::LoadItems() +{ + // OutputDebugString(TEXT("Start\n")); + INT32 dummy; + WasChanged(&dummy); + Clear(); + RINOK(LoadSubItems(_root, _path)); + AddRefs(_root); + + // OutputDebugString(TEXT("Finish\n")); + _commentsAreLoaded = false; + return S_OK; +} + +static const wchar_t *kDescriptionFileName = L"descript.ion"; + +bool CFSFolder::LoadComments() +{ + if (_commentsAreLoaded) + return true; + _comments.Clear(); + _commentsAreLoaded = true; + NIO::CInFile file; + if (!file.Open(_path + kDescriptionFileName)) + return false; + UInt64 length; + if (!file.GetLength(length)) + return false; + if (length >= (1 << 28)) + return false; + AString s; + char *p = s.GetBuffer((int)((size_t)length + 1)); + UInt32 processedSize; + file.Read(p, (UInt32)length, processedSize); + p[length] = 0; + s.ReleaseBuffer(); + s.Replace("\r\n", "\n"); + if (processedSize != length) + return false; + file.Close(); + UString unicodeString; + if (!ConvertUTF8ToUnicode(s, unicodeString)) + return false; + return _comments.ReadFromString(unicodeString); +} + +static bool IsAscii(const UString &testString) +{ + for (int i = 0; i < testString.Length(); i++) + if (testString[i] >= 0x80) + return false; + return true; +} + +bool CFSFolder::SaveComments() +{ + NIO::COutFile file; + if (!file.Create(_path + kDescriptionFileName, true)) + return false; + UString unicodeString; + _comments.SaveToString(unicodeString); + AString utfString; + ConvertUnicodeToUTF8(unicodeString, utfString); + UInt32 processedSize; + if (!IsAscii(unicodeString)) + { + Byte bom [] = { 0xEF, 0xBB, 0xBF, 0x0D, 0x0A }; + file.Write(bom , sizeof(bom), processedSize); + } + utfString.Replace("\n", "\r\n"); + file.Write(utfString, utfString.Length(), processedSize); + _commentsAreLoaded = false; + return true; +} + +STDMETHODIMP CFSFolder::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _refs.Size(); + return S_OK; +} + +/* +STDMETHODIMP CFSFolder::GetNumberOfSubFolders(UInt32 *numSubFolders) +{ + UInt32 numSubFoldersLoc = 0; + for (int i = 0; i < _files.Size(); i++) + if (_files[i].IsDirectory()) + numSubFoldersLoc++; + *numSubFolders = numSubFoldersLoc; + return S_OK; +} +*/ + +bool MyGetCompressedFileSizeW(LPCWSTR fileName, UInt64 &size) +{ + DWORD highPart; + DWORD lowPart = ::GetCompressedFileSizeW(fileName, &highPart); + if (lowPart == INVALID_FILE_SIZE && ::GetLastError() != NO_ERROR) + { + #ifdef WIN_LONG_PATH + { + UString longPath; + if (GetLongPath(fileName, longPath)) + lowPart = ::GetCompressedFileSizeW(longPath, &highPart); + } + #endif + if (lowPart == INVALID_FILE_SIZE && ::GetLastError() != NO_ERROR) + return false; + } + size = (UInt64(highPart) << 32) | lowPart; + return true; +} + +STDMETHODIMP CFSFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value) +{ + NCOM::CPropVariant propVariant; + if (itemIndex >= (UInt32)_refs.Size()) + return E_INVALIDARG; + CDirItem &fileInfo = *_refs[itemIndex]; + switch(propID) + { + case kpidIsFolder: + propVariant = fileInfo.IsDirectory(); + break; + case kpidName: + propVariant = fileInfo.Name; + break; + case kpidSize: + propVariant = fileInfo.Size; + break; + case kpidPackedSize: + if (!fileInfo.CompressedSizeIsDefined) + { + fileInfo.CompressedSizeIsDefined = true; + if (fileInfo.IsDirectory () || + !MyGetCompressedFileSizeW(_path + GetRelPath(fileInfo), fileInfo.CompressedSize)) + fileInfo.CompressedSize = fileInfo.Size; + } + propVariant = fileInfo.CompressedSize; + break; + case kpidAttributes: + propVariant = (UInt32)fileInfo.Attributes; + break; + case kpidCreationTime: + propVariant = fileInfo.CreationTime; + break; + case kpidLastAccessTime: + propVariant = fileInfo.LastAccessTime; + break; + case kpidLastWriteTime: + propVariant = fileInfo.LastWriteTime; + break; + case kpidComment: + { + LoadComments(); + UString comment; + if (_comments.GetValue(GetRelPath(fileInfo), comment)) + propVariant = comment; + break; + } + case kpidPrefix: + { + if (_flatMode) + { + propVariant = GetPrefix(fileInfo); + } + break; + } + } + propVariant.Detach(value); + return S_OK; +} + +HRESULT CFSFolder::BindToFolderSpec(const wchar_t *name, IFolderFolder **resultFolder) +{ + *resultFolder = 0; + CFSFolder *folderSpec = new CFSFolder; + CMyComPtr subFolder = folderSpec; + RINOK(folderSpec->Init(_path + name + UString(L'\\'), 0)); + *resultFolder = subFolder.Detach(); + return S_OK; +} + +UString CFSFolder::GetPrefix(const CDirItem &item) const +{ + UString path; + CDirItem *cur = item.Parent; + while (cur->Parent != 0) + { + path = cur->Name + UString('\\') + path; + cur = cur->Parent; + } + return path; +} + +UString CFSFolder::GetRelPath(const CDirItem &item) const +{ + return GetPrefix(item) + item.Name; +} + +STDMETHODIMP CFSFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder) +{ + *resultFolder = 0; + const CDirItem &fileInfo = *_refs[index]; + if (!fileInfo.IsDirectory()) + return E_INVALIDARG; + return BindToFolderSpec(GetRelPath(fileInfo), resultFolder); +} + +STDMETHODIMP CFSFolder::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder) +{ + return BindToFolderSpec(name, resultFolder); +} + +STDMETHODIMP CFSFolder::BindToParentFolder(IFolderFolder **resultFolder) +{ + *resultFolder = 0; + if (_parentFolder) + { + CMyComPtr parentFolder = _parentFolder; + *resultFolder = parentFolder.Detach(); + return S_OK; + } + if (_path.IsEmpty()) + return E_INVALIDARG; + int pos = _path.ReverseFind(L'\\'); + if (pos < 0 || pos != _path.Length() - 1) + return E_FAIL; + UString parentPath = _path.Left(pos); + pos = parentPath.ReverseFind(L'\\'); + if (pos < 0) + { + parentPath.Empty(); + CFSDrives *drivesFolderSpec = new CFSDrives; + CMyComPtr drivesFolder = drivesFolderSpec; + drivesFolderSpec->Init(); + *resultFolder = drivesFolder.Detach(); + return S_OK; + } + UString parentPathReduced = parentPath.Left(pos); + parentPath = parentPath.Left(pos + 1); + pos = parentPathReduced.ReverseFind(L'\\'); + if (pos == 1) + { + if (parentPath[0] != L'\\') + return E_FAIL; + CNetFolder *netFolderSpec = new CNetFolder; + CMyComPtr netFolder = netFolderSpec; + netFolderSpec->Init(parentPath); + *resultFolder = netFolder.Detach(); + return S_OK; + } + CFSFolder *parentFolderSpec = new CFSFolder; + CMyComPtr parentFolder = parentFolderSpec; + RINOK(parentFolderSpec->Init(parentPath, 0)); + *resultFolder = parentFolder.Detach(); + return S_OK; +} + +STDMETHODIMP CFSFolder::GetName(BSTR * /* name */) +{ + return E_NOTIMPL; + /* + CMyComBSTR aBSTRName = m_ProxyFolderItem->m_Name; + *name = aBSTRName.Detach(); + return S_OK; + */ +} + +STDMETHODIMP CFSFolder::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + if (!_flatMode) + (*numProperties)--; + return S_OK; +} + +STDMETHODIMP CFSFolder::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if (index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &prop = kProperties[index]; + *propID = prop.propid; + *varType = prop.vt; + *name = 0; + return S_OK; +} + + +STDMETHODIMP CFSFolder::GetTypeID(BSTR *name) +{ + CMyComBSTR temp = L"FSFolder"; + *name = temp.Detach(); + return S_OK; +} + +STDMETHODIMP CFSFolder::GetPath(BSTR *path) +{ + CMyComBSTR temp = _path; + *path = temp.Detach(); + return S_OK; +} + + +STDMETHODIMP CFSFolder::WasChanged(INT32 *wasChanged) +{ + bool wasChangedMain = false; + for (;;) + { + if (!_findChangeNotification.IsHandleAllocated()) + { + *wasChanged = BoolToInt(false); + return S_OK; + } + + DWORD waitResult = ::WaitForSingleObject(_findChangeNotification, 0); + bool wasChangedLoc = (waitResult == WAIT_OBJECT_0); + if (wasChangedLoc) + { + _findChangeNotification.FindNext(); + wasChangedMain = true; + } + else + break; + } + *wasChanged = BoolToInt(wasChangedMain); + return S_OK; +} + +STDMETHODIMP CFSFolder::Clone(IFolderFolder **resultFolder) +{ + CFSFolder *fsFolderSpec = new CFSFolder; + CMyComPtr folderNew = fsFolderSpec; + fsFolderSpec->Init(_path, 0); + *resultFolder = folderNew.Detach(); + return S_OK; +} + +HRESULT CFSFolder::GetItemFullSize(int index, UInt64 &size, IProgress *progress) +{ + const CDirItem &fileInfo = *_refs[index]; + if (fileInfo.IsDirectory()) + { + /* + CMyComPtr subFolder; + RINOK(BindToFolder(index, &subFolder)); + CMyComPtr aFolderReload; + subFolder.QueryInterface(&aFolderReload); + aFolderReload->Reload(); + UInt32 numItems; + RINOK(subFolder->GetNumberOfItems(&numItems)); + CMyComPtr aGetItemFullSize; + subFolder.QueryInterface(&aGetItemFullSize); + for (UInt32 i = 0; i < numItems; i++) + { + UInt64 size; + RINOK(aGetItemFullSize->GetItemFullSize(i, &size)); + *totalSize += size; + } + */ + return GetFolderSize(_path + GetRelPath(fileInfo), size, progress); + } + size = fileInfo.Size; + return S_OK; +} + +STDMETHODIMP CFSFolder::GetItemFullSize(UInt32 index, PROPVARIANT *value, IProgress *progress) +{ + NCOM::CPropVariant propVariant; + if (index >= (UInt32)_refs.Size()) + return E_INVALIDARG; + UInt64 size = 0; + HRESULT result = GetItemFullSize(index, size, progress); + propVariant = size; + propVariant.Detach(value); + return result; +} + +HRESULT CFSFolder::GetComplexName(const wchar_t *name, UString &resultPath) +{ + UString newName = name; + resultPath = _path + newName; + if (newName.Length() < 1) + return S_OK; + if (newName[0] == L'\\') + { + resultPath = newName; + return S_OK; + } + if (newName.Length() < 2) + return S_OK; + if (newName[1] == L':') + resultPath = newName; + return S_OK; +} + +STDMETHODIMP CFSFolder::CreateFolder(const wchar_t *name, IProgress * /* progress */) +{ + UString processedName; + RINOK(GetComplexName(name, processedName)); + if(NDirectory::MyCreateDirectory(processedName)) + return S_OK; + if(::GetLastError() == ERROR_ALREADY_EXISTS) + return ::GetLastError(); + if (!NDirectory::CreateComplexDirectory(processedName)) + return ::GetLastError(); + return S_OK; +} + +STDMETHODIMP CFSFolder::CreateFile(const wchar_t *name, IProgress * /* progress */) +{ + UString processedName; + RINOK(GetComplexName(name, processedName)); + NIO::COutFile outFile; + if (!outFile.Create(processedName, false)) + return ::GetLastError(); + return S_OK; +} + +STDMETHODIMP CFSFolder::Rename(UInt32 index, const wchar_t *newName, IProgress * /* progress */) +{ + const CDirItem &fileInfo = *_refs[index]; + const UString fullPrefix = _path + GetPrefix(fileInfo); + if (!NDirectory::MyMoveFile(fullPrefix + fileInfo.Name, fullPrefix + newName)) + return GetLastError(); + return S_OK; +} + +STDMETHODIMP CFSFolder::Delete(const UInt32 *indices, UInt32 numItems,IProgress *progress) +{ + RINOK(progress->SetTotal(numItems)); + for (UInt32 i = 0; i < numItems; i++) + { + const CDirItem &fileInfo = *_refs[indices[i]]; + const UString fullPath = _path + GetRelPath(fileInfo); + bool result; + if (fileInfo.IsDirectory()) + result = NDirectory::RemoveDirectoryWithSubItems(fullPath); + else + result = NDirectory::DeleteFileAlways(fullPath); + if (!result) + return GetLastError(); + UInt64 completed = i; + RINOK(progress->SetCompleted(&completed)); + } + return S_OK; +} + +STDMETHODIMP CFSFolder::SetProperty(UInt32 index, PROPID propID, + const PROPVARIANT *value, IProgress * /* progress */) +{ + if (index >= (UInt32)_refs.Size()) + return E_INVALIDARG; + CDirItem &fileInfo = *_refs[index]; + if (fileInfo.Parent->Parent != 0) + return E_NOTIMPL; + switch(propID) + { + case kpidComment: + { + UString filename = fileInfo.Name; + filename.Trim(); + if (value->vt == VT_EMPTY) + _comments.DeletePair(filename); + else if (value->vt == VT_BSTR) + { + CTextPair pair; + pair.ID = filename; + pair.ID.Trim(); + pair.Value = value->bstrVal; + pair.Value.Trim(); + if (pair.Value.IsEmpty()) + _comments.DeletePair(filename); + else + _comments.AddPair(pair); + } + else + return E_INVALIDARG; + SaveComments(); + break; + } + default: + return E_NOTIMPL; + } + return S_OK; +} + +STDMETHODIMP CFSFolder::GetSystemIconIndex(UInt32 index, INT32 *iconIndex) +{ + if (index >= (UInt32)_refs.Size()) + return E_INVALIDARG; + const CDirItem &fileInfo = *_refs[index]; + *iconIndex = 0; + int iconIndexTemp; + if (GetRealIconIndex(_path + GetRelPath(fileInfo), fileInfo.Attributes, iconIndexTemp) != 0) + { + *iconIndex = iconIndexTemp; + return S_OK; + } + return GetLastError(); +} + +STDMETHODIMP CFSFolder::SetFlatMode(Int32 flatMode) +{ + _flatMode = IntToBool(flatMode); + return S_OK; +} + +// static const LPCTSTR kInvalidFileChars = TEXT("\\/:*?\"<>|"); + diff --git a/CPP/7zip/FileManager/FSFolder.h b/CPP/7zip/FileManager/FSFolder.h new file mode 100755 index 00000000..4641c018 --- /dev/null +++ b/CPP/7zip/FileManager/FSFolder.h @@ -0,0 +1,141 @@ +// FSFolder.h + +#ifndef __FSFOLDER_H +#define __FSFOLDER_H + +#include "Common/String.h" +#include "Common/MyCom.h" +#include "Windows/FileFind.h" +#include "Windows/PropVariant.h" + +#include "IFolder.h" + +#include "TextPairs.h" + +class CFSFolder; + +struct CFileInfoEx: public NWindows::NFile::NFind::CFileInfoW +{ + bool CompressedSizeIsDefined; + UInt64 CompressedSize; +}; + +struct CDirItem; + +struct CDirItem: public CFileInfoEx +{ + CDirItem *Parent; + CObjectVector Files; + + CDirItem(): Parent(0) {} + void Clear() + { + Files.Clear(); + Parent = 0; + } +}; + +class CFSFolder: + public IFolderFolder, + public IEnumProperties, + public IFolderGetTypeID, + public IFolderGetPath, + public IFolderWasChanged, + public IFolderOperations, + // public IFolderOperationsDeleteToRecycleBin, + public IFolderGetItemFullSize, + public IFolderClone, + public IFolderGetSystemIconIndex, + public IFolderSetFlatMode, + public CMyUnknownImp +{ + UInt64 GetSizeOfItem(int anIndex) const; +public: + MY_QUERYINTERFACE_BEGIN + MY_QUERYINTERFACE_ENTRY(IEnumProperties) + MY_QUERYINTERFACE_ENTRY(IFolderGetTypeID) + MY_QUERYINTERFACE_ENTRY(IFolderGetPath) + MY_QUERYINTERFACE_ENTRY(IFolderWasChanged) + // MY_QUERYINTERFACE_ENTRY(IFolderOperationsDeleteToRecycleBin) + MY_QUERYINTERFACE_ENTRY(IFolderOperations) + MY_QUERYINTERFACE_ENTRY(IFolderGetItemFullSize) + MY_QUERYINTERFACE_ENTRY(IFolderClone) + MY_QUERYINTERFACE_ENTRY(IFolderGetSystemIconIndex) + MY_QUERYINTERFACE_ENTRY(IFolderSetFlatMode) + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + + + STDMETHOD(LoadItems)(); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 itemIndex, PROPID propID, PROPVARIANT *value); + STDMETHOD(BindToFolder)(UInt32 index, IFolderFolder **resultFolder); + STDMETHOD(BindToFolder)(const wchar_t *name, IFolderFolder **resultFolder); + STDMETHOD(BindToParentFolder)(IFolderFolder **resultFolder); + STDMETHOD(GetName)(BSTR *name); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + STDMETHOD(GetTypeID)(BSTR *name); + STDMETHOD(GetPath)(BSTR *path); + STDMETHOD(WasChanged)(INT32 *wasChanged); + STDMETHOD(Clone)(IFolderFolder **resultFolder); + STDMETHOD(GetItemFullSize)(UInt32 index, PROPVARIANT *value, IProgress *progress); + + STDMETHOD(SetFlatMode)(Int32 flatMode); + + // IFolderOperations + + STDMETHOD(CreateFolder)(const wchar_t *name, IProgress *progress); + STDMETHOD(CreateFile)(const wchar_t *name, IProgress *progress); + STDMETHOD(Rename)(UInt32 index, const wchar_t *newName, IProgress *progress); + STDMETHOD(Delete)(const UInt32 *indices, UInt32 numItems, IProgress *progress); + STDMETHOD(CopyTo)(const UInt32 *indices, UInt32 numItems, + const wchar_t *path, IFolderOperationsExtractCallback *callback); + STDMETHOD(MoveTo)(const UInt32 *indices, UInt32 numItems, + const wchar_t *path, IFolderOperationsExtractCallback *callback); + STDMETHOD(CopyFrom)(const wchar_t *fromFolderPath, + const wchar_t **itemsPaths, UInt32 numItems, IProgress *progress); + STDMETHOD(SetProperty)(UInt32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress); + STDMETHOD(GetSystemIconIndex)(UInt32 index, INT32 *iconIndex); + +private: + UString _path; + CDirItem _root; + CRecordVector _refs; + + CMyComPtr _parentFolder; + + bool _commentsAreLoaded; + CPairsStorage _comments; + + bool _flatMode; + + NWindows::NFile::NFind::CFindChangeNotification _findChangeNotification; + + HRESULT GetItemFullSize(int index, UInt64 &size, IProgress *progress); + HRESULT GetComplexName(const wchar_t *name, UString &resultPath); + HRESULT BindToFolderSpec(const wchar_t *name, IFolderFolder **resultFolder); + + bool LoadComments(); + bool SaveComments(); + HRESULT LoadSubItems(CDirItem &dirItem, const UString &path); + void AddRefs(CDirItem &dirItem); +public: + HRESULT Init(const UString &path, IFolderFolder *parentFolder); + + CFSFolder() : _flatMode(false) {} + + UString GetPrefix(const CDirItem &item) const; + UString GetRelPath(const CDirItem &item) const; + UString GetRelPath(UInt32 index) const { return GetRelPath(*_refs[index]); } + + void Clear() + { + _root.Clear(); + _refs.Clear(); + } +}; + +#endif diff --git a/CPP/7zip/FileManager/FSFolderCopy.cpp b/CPP/7zip/FileManager/FSFolderCopy.cpp new file mode 100755 index 00000000..7566c8f2 --- /dev/null +++ b/CPP/7zip/FileManager/FSFolderCopy.cpp @@ -0,0 +1,490 @@ +// FSFolderCopy.cpp + +#include "StdAfx.h" + +#include + +#include "FSFolder.h" +#include "Windows/FileDir.h" +#include "Windows/Error.h" + +#include "Common/StringConvert.h" + +#include "../Common/FilePathAutoRename.h" + +using namespace NWindows; +using namespace NFile; +using namespace NFind; + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +/* +static bool IsItWindows2000orHigher() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) && + (versionInfo.dwMajorVersion >= 5); +} +*/ + +struct CProgressInfo +{ + UINT64 StartPos; + IProgress *Progress; +}; + +static DWORD CALLBACK CopyProgressRoutine( + LARGE_INTEGER /* TotalFileSize */, // file size + LARGE_INTEGER TotalBytesTransferred, // bytes transferred + LARGE_INTEGER /* StreamSize */, // bytes in stream + LARGE_INTEGER /* StreamBytesTransferred */, // bytes transferred for stream + DWORD /* dwStreamNumber */, // current stream + DWORD /* dwCallbackReason */, // callback reason + HANDLE /* hSourceFile */, // handle to source file + HANDLE /* hDestinationFile */, // handle to destination file + LPVOID lpData // from CopyFileEx +) +{ + CProgressInfo &progressInfo = *(CProgressInfo *)lpData; + UINT64 completed = progressInfo.StartPos + TotalBytesTransferred.QuadPart; + if (progressInfo.Progress->SetCompleted(&completed) != S_OK) + return PROGRESS_CANCEL; + return PROGRESS_CONTINUE; +} + +typedef BOOL (WINAPI * CopyFileExPointer)( + IN LPCSTR lpExistingFileName, + IN LPCSTR lpNewFileName, + IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL, + IN LPVOID lpData OPTIONAL, + IN LPBOOL pbCancel OPTIONAL, + IN DWORD dwCopyFlags + ); + +typedef BOOL (WINAPI * CopyFileExPointerW)( + IN LPCWSTR lpExistingFileName, + IN LPCWSTR lpNewFileName, + IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL, + IN LPVOID lpData OPTIONAL, + IN LPBOOL pbCancel OPTIONAL, + IN DWORD dwCopyFlags + ); + +#ifndef _UNICODE +static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; } +static CSysString GetSysPath(LPCWSTR sysPath) + { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); } +#endif + +static bool MyCopyFile(LPCWSTR existingFile, LPCWSTR newFile, + IProgress *progress, UINT64 &completedSize) +{ + CProgressInfo progressInfo; + progressInfo.Progress = progress; + progressInfo.StartPos = completedSize; + BOOL CancelFlag = FALSE; + #ifndef _UNICODE + if (g_IsNT) + #endif + { + CopyFileExPointerW copyFunctionW = (CopyFileExPointerW) + ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"), + "CopyFileExW"); + if (copyFunctionW == 0) + return false; + if (copyFunctionW(existingFile, newFile, CopyProgressRoutine, + &progressInfo, &CancelFlag, COPY_FILE_FAIL_IF_EXISTS)) + return true; + #ifdef WIN_LONG_PATH + UString longPathExisting, longPathNew; + if (!NDirectory::GetLongPaths(existingFile, newFile, longPathExisting, longPathNew)) + return false; + if (copyFunctionW(longPathExisting, longPathNew, CopyProgressRoutine, + &progressInfo, &CancelFlag, COPY_FILE_FAIL_IF_EXISTS)) + return true; + #endif + return false; + } + #ifndef _UNICODE + else + { + CopyFileExPointer copyFunction = (CopyFileExPointer) + ::GetProcAddress(::GetModuleHandleA("kernel32.dll"), + "CopyFileExA"); + if (copyFunction != 0) + { + if (copyFunction(GetSysPath(existingFile), GetSysPath(newFile), + CopyProgressRoutine,&progressInfo, &CancelFlag, COPY_FILE_FAIL_IF_EXISTS)) + return true; + if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return false; + } + return BOOLToBool(::CopyFile(GetSysPath(existingFile), GetSysPath(newFile), TRUE)); + } + #endif +} + +typedef BOOL (WINAPI * MoveFileWithProgressPointer)( + IN LPCWSTR lpExistingFileName, + IN LPCWSTR lpNewFileName, + IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL, + IN LPVOID lpData OPTIONAL, + IN DWORD dwFlags + ); + +static bool MyMoveFile(LPCWSTR existingFile, LPCWSTR newFile, + IProgress *progress, UINT64 &completedSize) +{ + // if (IsItWindows2000orHigher()) + // { + CProgressInfo progressInfo; + progressInfo.Progress = progress; + progressInfo.StartPos = completedSize; + + MoveFileWithProgressPointer moveFunction = (MoveFileWithProgressPointer) + ::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")), + "MoveFileWithProgressW"); + if (moveFunction != 0) + { + if (moveFunction( + existingFile, newFile, CopyProgressRoutine, + &progressInfo, MOVEFILE_COPY_ALLOWED)) + return true; + if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + { + #ifdef WIN_LONG_PATH + UString longPathExisting, longPathNew; + if (!NDirectory::GetLongPaths(existingFile, newFile, longPathExisting, longPathNew)) + return false; + if (moveFunction(longPathExisting, longPathNew, CopyProgressRoutine, + &progressInfo, MOVEFILE_COPY_ALLOWED)) + return true; + #endif + if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return false; + } + } + // } + // else + return NDirectory::MyMoveFile(existingFile, newFile); +} + +static HRESULT MyCopyFile( + const UString &srcPath, + const CFileInfoW &srcFileInfo, + const UString &destPathSpec, + IFolderOperationsExtractCallback *callback, + UINT64 &completedSize) +{ + UString destPath = destPathSpec; + if (destPath.CompareNoCase(srcPath) == 0) + { + UString message = UString(L"can not move file \'") + destPath + UString(L"\' onto itself"); + RINOK(callback->ShowMessage(message)); + return E_ABORT; + } + + INT32 writeAskResult; + CMyComBSTR destPathResult; + RINOK(callback->AskWrite( + srcPath, + BoolToInt(false), + &srcFileInfo.LastWriteTime, &srcFileInfo.Size, + destPath, + &destPathResult, + &writeAskResult)); + if (IntToBool(writeAskResult)) + { + UString destPathNew = UString(destPathResult); + RINOK(callback->SetCurrentFilePath(srcPath)); + if (!::MyCopyFile(srcPath, destPathNew, callback, completedSize)) + { + UString message = NError::MyFormatMessageW(GetLastError()) + + UString(L" \'") + + UString(destPathNew) + + UString(L"\'"); + RINOK(callback->ShowMessage(message)); + return E_ABORT; + } + } + completedSize += srcFileInfo.Size; + return callback->SetCompleted(&completedSize); +} + +static HRESULT CopyFolder( + const UString &srcPath, + const UString &destPathSpec, + IFolderOperationsExtractCallback *callback, + UINT64 &completedSize) +{ + RINOK(callback->SetCompleted(&completedSize)); + + UString destPath = destPathSpec; + int len = srcPath.Length(); + if (destPath.Length() >= len && srcPath.CompareNoCase(destPath.Left(len)) == 0) + { + if (destPath.Length() == len || destPath[len] == L'\\') + { + UString message = UString(L"can not copy folder \'") + + destPath + UString(L"\' onto itself"); + RINOK(callback->ShowMessage(message)); + return E_ABORT; + } + } + + if (!NDirectory::CreateComplexDirectory(destPath)) + { + UString message = UString(L"can not create folder ") + destPath; + RINOK(callback->ShowMessage(message)); + return E_ABORT; + } + CEnumeratorW enumerator(srcPath + UString(L"\\*")); + CFileInfoEx fileInfo; + while (enumerator.Next(fileInfo)) + { + const UString srcPath2 = srcPath + UString(L"\\") + fileInfo.Name; + const UString destPath2 = destPath + UString(L"\\") + fileInfo.Name; + if (fileInfo.IsDirectory()) + { + RINOK(CopyFolder(srcPath2, destPath2, callback, completedSize)); + } + else + { + RINOK(MyCopyFile(srcPath2, fileInfo, destPath2, callback, completedSize)); + } + } + return S_OK; +} + +STDMETHODIMP CFSFolder::CopyTo(const UInt32 *indices, UInt32 numItems, + const wchar_t *path, IFolderOperationsExtractCallback *callback) +{ + if (numItems == 0) + return S_OK; + UINT64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + { + int index = indices[i]; + if (index >= _refs.Size()) + return E_INVALIDARG; + UINT64 size; + RINOK(GetItemFullSize(indices[i], size, callback)); + totalSize += size; + } + + callback->SetTotal(totalSize); + UString destPath = path; + if (destPath.IsEmpty()) + return E_INVALIDARG; + bool directName = (destPath[destPath.Length() - 1] != L'\\'); + if (directName) + { + if (numItems > 1) + return E_INVALIDARG; + } + /* + // doesn't work in network + else + if (!NDirectory::CreateComplexDirectory(destPath))) + { + DWORD lastError = ::GetLastError(); + UString message = UString(L"can not create folder ") + + destPath; + RINOK(callback->ShowMessage(message)); + return E_ABORT; + } + */ + + UINT64 completedSize = 0; + RINOK(callback->SetCompleted(&completedSize)); + for (i = 0; i < numItems; i++) + { + const CDirItem &fileInfo = *_refs[indices[i]]; + UString destPath2 = destPath; + if (!directName) + destPath2 += fileInfo.Name; + UString srcPath = _path + GetPrefix(fileInfo) + fileInfo.Name; + if (fileInfo.IsDirectory()) + { + RINOK(CopyFolder(srcPath, destPath2, callback, completedSize)); + } + else + { + RINOK(MyCopyFile(srcPath, fileInfo, destPath2, callback, completedSize)); + } + } + return S_OK; +} + +///////////////////////////////////////////////// +// Move Operations + +HRESULT MyMoveFile( + const UString &srcPath, + const CFileInfoW &srcFileInfo, + const UString &destPathSpec, + IFolderOperationsExtractCallback *callback, + UINT64 &completedSize) +{ + UString destPath = destPathSpec; + if (destPath.CompareNoCase(srcPath) == 0) + { + UString message = UString(L"can not move file \'") + + destPath + + UString(L"\' onto itself"); + RINOK(callback->ShowMessage(message)); + return E_ABORT; + } + + INT32 writeAskResult; + CMyComBSTR destPathResult; + RINOK(callback->AskWrite( + srcPath, + BoolToInt(false), + &srcFileInfo.LastWriteTime, &srcFileInfo.Size, + destPath, + &destPathResult, + &writeAskResult)); + if (IntToBool(writeAskResult)) + { + UString destPathNew = UString(destPathResult); + RINOK(callback->SetCurrentFilePath(srcPath)); + if (!MyMoveFile(srcPath, destPathNew, callback, completedSize)) + { + UString message = UString(L"can not move to file ") + destPathNew; + RINOK(callback->ShowMessage(message)); + } + } + completedSize += srcFileInfo.Size; + RINOK(callback->SetCompleted(&completedSize)); + return S_OK; +} + +HRESULT MyMoveFolder( + const UString &srcPath, + const UString &destPathSpec, + IFolderOperationsExtractCallback *callback, + UINT64 &completedSize) +{ + UString destPath = destPathSpec; + int len = srcPath.Length(); + if (destPath.Length() >= len && srcPath.CompareNoCase(destPath.Left(len)) == 0) + { + if (destPath.Length() == len || destPath[len] == L'\\') + { + UString message = UString(L"can not move folder \'") + + destPath + UString(L"\' onto itself"); + RINOK(callback->ShowMessage(message)); + return E_ABORT; + } + } + + if (MyMoveFile(srcPath, destPath, callback, completedSize)) + return S_OK; + + if (!NDirectory::CreateComplexDirectory(destPath)) + { + UString message = UString(L"can not create folder ") + destPath; + RINOK(callback->ShowMessage(message)); + return E_ABORT; + } + { + CEnumeratorW enumerator(srcPath + UString(L"\\*")); + CFileInfoEx fileInfo; + while (enumerator.Next(fileInfo)) + { + const UString srcPath2 = srcPath + UString(L"\\") + fileInfo.Name; + const UString destPath2 = destPath + UString(L"\\") + fileInfo.Name; + if (fileInfo.IsDirectory()) + { + RINOK(MyMoveFolder(srcPath2, destPath2, callback, completedSize)); + } + else + { + RINOK(MyMoveFile(srcPath2, fileInfo, destPath2, callback, completedSize)); + } + } + } + if (!NDirectory::MyRemoveDirectory(srcPath)) + { + UString message = UString(L"can not remove folder") + srcPath; + RINOK(callback->ShowMessage(message)); + return E_ABORT; + } + return S_OK; +} + +STDMETHODIMP CFSFolder::MoveTo( + const UInt32 *indices, + UInt32 numItems, + const wchar_t *path, + IFolderOperationsExtractCallback *callback) +{ + if (numItems == 0) + return S_OK; + + UINT64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + { + int index = indices[i]; + if (index >= _refs.Size()) + return E_INVALIDARG; + UINT64 size; + RINOK(GetItemFullSize(indices[i], size, callback)); + totalSize += size; + } + callback->SetTotal(totalSize); + + UString destPath = path; + if (destPath.IsEmpty()) + return E_INVALIDARG; + bool directName = (destPath[destPath.Length() - 1] != L'\\'); + if (directName) + { + if (numItems > 1) + return E_INVALIDARG; + } + else + if (!NDirectory::CreateComplexDirectory(destPath)) + { + UString message = UString(L"can not create folder ") + + destPath; + RINOK(callback->ShowMessage(message)); + return E_ABORT; + } + + UINT64 completedSize = 0; + RINOK(callback->SetCompleted(&completedSize)); + for (i = 0; i < numItems; i++) + { + const CDirItem &fileInfo = *_refs[indices[i]]; + UString destPath2 = destPath; + if (!directName) + destPath2 += fileInfo.Name; + UString srcPath = _path + GetPrefix(fileInfo) + fileInfo.Name; + if (fileInfo.IsDirectory()) + { + RINOK(MyMoveFolder(srcPath, destPath2, callback, completedSize)); + } + else + { + RINOK(MyMoveFile(srcPath, fileInfo, destPath2, callback, completedSize)); + } + } + return S_OK; +} + +STDMETHODIMP CFSFolder::CopyFrom(const wchar_t * /* fromFolderPath */, + const wchar_t ** /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */) +{ + return E_NOTIMPL; +} + + diff --git a/CPP/7zip/FileManager/FileFolderPluginOpen.cpp b/CPP/7zip/FileManager/FileFolderPluginOpen.cpp new file mode 100755 index 00000000..3e3f40ba --- /dev/null +++ b/CPP/7zip/FileManager/FileFolderPluginOpen.cpp @@ -0,0 +1,111 @@ +// FileFolderPluginOpen.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Windows/Defs.h" +#include "Windows/FileDir.h" +#include "Windows/FileName.h" +#include "Windows/DLL.h" + +#include "IFolder.h" +#include "RegistryAssociations.h" +#include "RegistryPlugins.h" + +#include "OpenCallback.h" +#include "PluginLoader.h" + +using namespace NWindows; +using namespace NRegistryAssociations; + +static int FindPlugin(const CObjectVector &plugins, + const UString &pluginName) +{ + for (int i = 0; i < plugins.Size(); i++) + if (plugins[i].Name.CompareNoCase(pluginName) == 0) + return i; + return -1; +} + +HRESULT OpenFileFolderPlugin( + const UString &path, + HMODULE *module, + IFolderFolder **resultFolder, + HWND parentWindow, + bool &encrypted) +{ + encrypted = false; + CObjectVector 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 folderManager; + CMyComPtr folder; + HRESULT result = library.LoadAndCreateManager( + plugin.FilePath, plugin.ClassID, &folderManager); + if (result != S_OK) + continue; + + COpenArchiveCallback *openCallbackSpec = new COpenArchiveCallback; + CMyComPtr openCallback = openCallbackSpec; + openCallbackSpec->PasswordIsDefined = false; + openCallbackSpec->ParentWindow = parentWindow; + openCallbackSpec->LoadFileInfo(dirPrefix, fileName); + result = folderManager->OpenFolderFile(path, &folder, openCallback); + if (openCallbackSpec->PasswordWasAsked) + encrypted = true; + if (result == S_OK) + { + *module = library.Detach(); + *resultFolder = folder.Detach(); + return S_OK; + } + continue; + + /* + if (result != S_FALSE) + return result; + */ + } + return S_FALSE; +} \ No newline at end of file diff --git a/CPP/7zip/FileManager/FileFolderPluginOpen.h b/CPP/7zip/FileManager/FileFolderPluginOpen.h new file mode 100755 index 00000000..295048a9 --- /dev/null +++ b/CPP/7zip/FileManager/FileFolderPluginOpen.h @@ -0,0 +1,9 @@ +// FileFolderPluginOpen.h + +#ifndef __FILEFOLDERPLUGINOPEN_H +#define __FILEFOLDERPLUGINOPEN_H + +HRESULT OpenFileFolderPlugin(const UString &path, + HMODULE *module, IFolderFolder **resultFolder, HWND parentWindow, bool &encrypted); + +#endif diff --git a/CPP/7zip/FileManager/FilePlugins.cpp b/CPP/7zip/FileManager/FilePlugins.cpp new file mode 100755 index 00000000..524b6aa7 --- /dev/null +++ b/CPP/7zip/FileManager/FilePlugins.cpp @@ -0,0 +1,113 @@ +// FilePlugins.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Common/MyCom.h" + +#include "IFolder.h" +#include "FilePlugins.h" +#include "StringUtils.h" +#include "PluginLoader.h" + +using namespace NRegistryAssociations; + +int CExtDatabase::FindExtInfoBig(const UString &ext) +{ + for (int i = 0; i < ExtBigItems.Size(); i++) + if (ExtBigItems[i].Ext.CompareNoCase(ext) == 0) + return i; + return -1; +} + +int CExtDatabase::FindPlugin(const UString &plugin) +{ + for (int i = 0; i < Plugins.Size(); i++) + if (Plugins[i].Name.CompareNoCase(plugin) == 0) + return i; + return -1; +} + +void CExtDatabase::Read() +{ + CObjectVector 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 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 extItems; + for (int i = 0; i < ExtBigItems.Size(); i++) + { + const CExtInfoBig &extInfoBig = ExtBigItems[i]; + CExtInfo extInfo; + // extInfo.Enabled = extInfoBig.Associated; + extInfo.Ext = extInfoBig.Ext; + for (int p = 0; p < extInfoBig.PluginsPairs.Size(); p++) + { + CPluginEnabledPair pluginPair = extInfoBig.PluginsPairs[p]; + if (pluginPair.Enabled) + extInfo.Plugins.Add(Plugins[pluginPair.Index].Name); + } + extItems.Add(extInfo); + } + WriteInternalAssociations(extItems); +} + + diff --git a/CPP/7zip/FileManager/FilePlugins.h b/CPP/7zip/FileManager/FilePlugins.h new file mode 100755 index 00000000..805cac2a --- /dev/null +++ b/CPP/7zip/FileManager/FilePlugins.h @@ -0,0 +1,54 @@ +// FilePlugins.h + +#ifndef __FILEPLUGINS_H +#define __FILEPLUGINS_H + +#include "RegistryPlugins.h" +#include "RegistryAssociations.h" + +struct CPluginEnabledPair +{ + int Index; + bool Enabled; + CPluginEnabledPair(int index, bool enabled): Index(index),Enabled(enabled) {} +}; + +struct CExtInfoBig +{ + UString Ext; + bool Associated; + CRecordVector 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 ExtBigItems; + CObjectVector Plugins; + int FindExtInfoBig(const UString &ext); + int FindPlugin(const UString &plugin); + + UString GetMainPluginNameForExtItem(int extIndex) const + { + const CExtInfoBig &extInfo = ExtBigItems[extIndex]; + if (extInfo.PluginsPairs.IsEmpty()) + return UString(); + else + return Plugins[extInfo.PluginsPairs.Front().Index].Name; + } + + void Read(); + void Save(); +}; + + +#endif + + diff --git a/CPP/7zip/FileManager/FormatUtils.cpp b/CPP/7zip/FileManager/FormatUtils.cpp new file mode 100755 index 00000000..553d8bcd --- /dev/null +++ b/CPP/7zip/FileManager/FormatUtils.cpp @@ -0,0 +1,40 @@ +// FormatUtils.cpp + +#include "StdAfx.h" + +#include "FormatUtils.h" +#include "Common/IntToString.h" +#include "Windows/ResourceString.h" + +#ifdef LANG +#include "LangUtils.h" +#endif + +UString NumberToString(UInt64 number) +{ + wchar_t numberString[32]; + ConvertUInt64ToString(number, numberString); + return numberString; +} + +UString MyFormatNew(const UString &format, const UString &argument) +{ + UString result = format; + result.Replace(L"{0}", argument); + return result; +} + +UString MyFormatNew(UINT resourceID, + #ifdef LANG + UInt32 langID, + #endif + const UString &argument) +{ + return MyFormatNew( + #ifdef LANG + LangString(resourceID, langID), + #else + NWindows::MyLoadStringW(resourceID), + #endif + argument); +} diff --git a/CPP/7zip/FileManager/FormatUtils.h b/CPP/7zip/FileManager/FormatUtils.h new file mode 100755 index 00000000..f7e9b193 --- /dev/null +++ b/CPP/7zip/FileManager/FormatUtils.h @@ -0,0 +1,18 @@ +// FormatUtils.h + +#ifndef __FORMATUTILS_H +#define __FORMATUTILS_H + +#include "Common/Types.h" +#include "Common/String.h" + +UString NumberToString(UInt64 number); + +UString MyFormatNew(const UString &format, const UString &argument); +UString MyFormatNew(UINT resourceID, + #ifdef LANG + UInt32 langID, + #endif + const UString &argument); + +#endif diff --git a/CPP/7zip/FileManager/HelpUtils.cpp b/CPP/7zip/FileManager/HelpUtils.cpp new file mode 100755 index 00000000..c2bf49a5 --- /dev/null +++ b/CPP/7zip/FileManager/HelpUtils.cpp @@ -0,0 +1,23 @@ +// HelpUtils.cpp + +#include "StdAfx.h" + +#include + +#include "Common/StringConvert.h" +#include "HelpUtils.h" +#include "ProgramLocation.h" + +static LPCWSTR kHelpFileName = L"7-zip.chm::/"; + +void ShowHelpWindow(HWND hwnd, LPCWSTR topicFile) +{ + UString path; + if (!::GetProgramFolderPath(path)) + return; + path += kHelpFileName; + path += topicFile; + HtmlHelp(hwnd, GetSystemString(path), HH_DISPLAY_TOPIC, NULL); +} + + diff --git a/CPP/7zip/FileManager/HelpUtils.h b/CPP/7zip/FileManager/HelpUtils.h new file mode 100755 index 00000000..b993f09b --- /dev/null +++ b/CPP/7zip/FileManager/HelpUtils.h @@ -0,0 +1,10 @@ +// HelpUtils.h + +#ifndef __HELPUTILS_H +#define __HELPUTILS_H + +#include "Common/String.h" + +void ShowHelpWindow(HWND hwnd, LPCWSTR topicFile); + +#endif diff --git a/CPP/7zip/FileManager/IFolder.h b/CPP/7zip/FileManager/IFolder.h new file mode 100755 index 00000000..aa50a39d --- /dev/null +++ b/CPP/7zip/FileManager/IFolder.h @@ -0,0 +1,190 @@ +// FolderInterface.h + +#ifndef __FOLDERINTERFACE_H +#define __FOLDERINTERFACE_H + +#include "../IProgress.h" + +#define FOLDER_INTERFACE_SUB(i, b, x, y) \ +DEFINE_GUID(IID_ ## i, \ +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, x, y, 0x00); \ +struct i: public b + +#define FOLDER_INTERFACE2(i, x, y) FOLDER_INTERFACE_SUB(i, IUnknown, x, y) + +#define FOLDER_INTERFACE(i, x) FOLDER_INTERFACE2(i, x, 0x00) + +namespace NPlugin +{ + enum + { + kName = 0, + kType, + kClassID, + kOptionsClassID + }; +} + +FOLDER_INTERFACE(IFolderFolder, 0x00) +{ + STDMETHOD(LoadItems)() PURE; + STDMETHOD(GetNumberOfItems)(UInt32 *numItems) PURE; + // STDMETHOD(GetNumberOfSubFolders)(UInt32 *numSubFolders) PURE; + STDMETHOD(GetProperty)(UInt32 itemIndex, PROPID propID, PROPVARIANT *value) PURE; + STDMETHOD(BindToFolder)(UInt32 index, IFolderFolder **resultFolder) PURE; + STDMETHOD(BindToFolder)(const wchar_t *name, IFolderFolder **resultFolder) PURE; + STDMETHOD(BindToParentFolder)(IFolderFolder **resultFolder) PURE; + STDMETHOD(GetName)(BSTR *name) PURE; +}; + +FOLDER_INTERFACE(IEnumProperties, 0x01) +{ + // STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator) PURE; + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) PURE; + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) PURE; +}; + +FOLDER_INTERFACE(IFolderGetTypeID, 0x02) +{ + STDMETHOD(GetTypeID)(BSTR *name) PURE; +}; + +FOLDER_INTERFACE(IFolderGetPath, 0x03) +{ + STDMETHOD(GetPath)(BSTR *path) PURE; +}; + +FOLDER_INTERFACE(IFolderWasChanged, 0x04) +{ + STDMETHOD(WasChanged)(Int32 *wasChanged) PURE; +}; + +/* +FOLDER_INTERFACE(IFolderReload, 0x05) +{ + STDMETHOD(Reload)() PURE; +}; +*/ + +FOLDER_INTERFACE_SUB(IFolderOperationsExtractCallback, IProgress, 0x06, 0x01) +{ + STDMETHOD(AskWrite)( + const wchar_t *srcPath, + Int32 srcIsFolder, + const FILETIME *srcTime, + const UInt64 *srcSize, + const wchar_t *destPathRequest, + BSTR *destPathResult, + Int32 *writeAnswer) PURE; + STDMETHOD(ShowMessage)(const wchar_t *message) PURE; + STDMETHOD(SetCurrentFilePath)(const wchar_t *filePath) PURE; +}; + +/* +FOLDER_INTERFACE_SUB(IFolderOperationsUpdateCallback, IProgress, 0x06, 0x02) +{ + STDMETHOD(AskOverwrite)( + const wchar_t *srcPath, + Int32 destIsFolder, + const FILETIME *destTime, + const UInt64 *destSize, + const wchar_t *aDestPathRequest, + const wchar_t *aDestName, + BSTR *aDestPathResult, + Int32 *aResult); +}; +*/ + +FOLDER_INTERFACE(IFolderOperations, 0x06) +{ + STDMETHOD(CreateFolder)(const wchar_t *name, IProgress *progress) PURE; + STDMETHOD(CreateFile)(const wchar_t *name, IProgress *progress) PURE; + STDMETHOD(Rename)(UInt32 index, const wchar_t *newName, IProgress *progress) PURE; + STDMETHOD(Delete)(const UInt32 *indices, UInt32 numItems, IProgress *progress) PURE; + STDMETHOD(CopyTo)(const UInt32 *indices, UInt32 numItems, + const wchar_t *path, IFolderOperationsExtractCallback *callback) PURE; + STDMETHOD(MoveTo)(const UInt32 *indices, UInt32 numItems, + const wchar_t *path, IFolderOperationsExtractCallback *callback) PURE; + STDMETHOD(CopyFrom)(const wchar_t *fromFolderPath, + const wchar_t **itemsPaths, UInt32 numItems, IProgress *progress) PURE; + STDMETHOD(SetProperty)(UInt32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress) PURE; +}; + +/* +FOLDER_INTERFACE2(IFolderOperationsDeleteToRecycleBin, 0x06, 0x03) +{ + STDMETHOD(DeleteToRecycleBin)(const UInt32 *indices, UInt32 numItems, IProgress *progress) PURE; +}; +*/ + +FOLDER_INTERFACE(IFolderGetSystemIconIndex, 0x07) +{ + STDMETHOD(GetSystemIconIndex)(UInt32 index, Int32 *iconIndex) PURE; +}; + +FOLDER_INTERFACE(IFolderGetItemFullSize, 0x08) +{ + STDMETHOD(GetItemFullSize)(UInt32 index, PROPVARIANT *value, IProgress *progress) PURE; +}; + +FOLDER_INTERFACE(IFolderClone, 0x09) +{ + STDMETHOD(Clone)(IFolderFolder **resultFolder) PURE; +}; + +FOLDER_INTERFACE(IFolderSetFlatMode, 0x0A) +{ + STDMETHOD(SetFlatMode)(Int32 flatMode) PURE; +}; + +/* +FOLDER_INTERFACE(IFolderOpen, 0x10) +{ + STDMETHOD(FolderOpen)( + const wchar_t *aFileName, + // IArchiveHandler100 **anArchiveHandler, + // NZipRootRegistry::CArchiverInfo &anArchiverInfoResult, + // UString &aDefaultName, + IOpenArchive2CallBack *anOpenArchive2CallBack) PURE; +}; +*/ + +#define FOLDER_MANAGER_INTERFACE(i, x) \ +DEFINE_GUID(IID_ ## i, \ +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x09, 0x00, x, 0x00, 0x00); \ +struct i: public IUnknown + +FOLDER_MANAGER_INTERFACE(IFolderManager, 0x00) +{ + STDMETHOD(OpenFolderFile)(const wchar_t *filePath, IFolderFolder **resultFolder, IProgress *progress) PURE; + STDMETHOD(GetTypes)(BSTR *types) PURE; + STDMETHOD(GetExtension)(const wchar_t *type, BSTR *extension) PURE; + STDMETHOD(CreateFolderFile)(const wchar_t *type, const wchar_t *filePath, IProgress *progress) PURE; +}; + +FOLDER_MANAGER_INTERFACE(IFolderManagerGetIconPath, 0x01) +{ + STDMETHOD(GetIconPath)(const wchar_t *type, BSTR *iconPath) PURE; +}; + +/* +FOLDER_INTERFACE(IFolderExtract, 0x05, 0x0A); +{ + STDMETHOD(Clone)(IFolderFolder **aFolder) PURE; +}; + +FOLDER_INTERFACE(IFolderChangeNotify,0x05, 0x04, 0x00); +IFolderChangeNotify: public IUnknown +{ + STDMETHOD(OnChanged)() PURE; +}; + +FOLDER_INTERFACE(IFolderSetChangeNotify, 0x05, 0x05); +{ + STDMETHOD(SetChangeNotify)(IFolderChangeNotify *aChangeNotify) PURE; +}; +*/ + + +#endif diff --git a/CPP/7zip/FileManager/Info.bmp b/CPP/7zip/FileManager/Info.bmp new file mode 100755 index 00000000..d769a661 Binary files /dev/null and b/CPP/7zip/FileManager/Info.bmp differ diff --git a/CPP/7zip/FileManager/Info2.bmp b/CPP/7zip/FileManager/Info2.bmp new file mode 100755 index 00000000..af724d27 Binary files /dev/null and b/CPP/7zip/FileManager/Info2.bmp differ diff --git a/CPP/7zip/FileManager/LangUtils.cpp b/CPP/7zip/FileManager/LangUtils.cpp new file mode 100755 index 00000000..decff306 --- /dev/null +++ b/CPP/7zip/FileManager/LangUtils.cpp @@ -0,0 +1,185 @@ +// LangUtils.cpp + +#include "StdAfx.h" + +#include "LangUtils.h" +#include "Common/StringConvert.h" +#include "Common/StringToInt.h" +#include "Windows/Synchronization.h" +#include "Windows/Window.h" +#include "Windows/FileFind.h" +#include "RegistryUtils.h" +#include "ProgramLocation.h" + +using namespace NWindows; + +static CLang g_Lang; +UString g_LangID; + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +void ReloadLang() +{ + ReadRegLang(g_LangID); + g_Lang.Clear(); + if (!g_LangID.IsEmpty() && g_LangID != L"-") + { + UString langPath = g_LangID; + if (langPath.Find('\\') < 0) + { + if (langPath.Find('.') < 0) + langPath += L".txt"; + UString folderPath; + if (GetProgramFolderPath(folderPath)) + langPath = folderPath + UString(L"Lang\\") + langPath; + } + g_Lang.Open(GetSystemString(langPath)); + } +} + +static bool g_Loaded = false; +static NSynchronization::CCriticalSection g_CriticalSection; + +void LoadLangOneTime() +{ + NSynchronization::CCriticalSectionLock lock(g_CriticalSection); + if (g_Loaded) + return; + g_Loaded = true; + ReloadLang(); +} + +void LangSetDlgItemsText(HWND dialogWindow, CIDLangPair *idLangPairs, int numItems) +{ + for (int i = 0; i < numItems; i++) + { + const CIDLangPair &idLangPair = idLangPairs[i]; + UString message; + if (g_Lang.GetMessage(idLangPair.LangID, message)) + { + NWindows::CWindow window(GetDlgItem(dialogWindow, idLangPair.ControlID)); + window.SetText(message); + } + } +} + +void LangSetWindowText(HWND window, UInt32 langID) +{ + UString message; + if (g_Lang.GetMessage(langID, message)) + MySetWindowText(window, message); +} + +UString LangString(UInt32 langID) +{ + UString message; + if (g_Lang.GetMessage(langID, message)) + return message; + return UString(); +} + +UString LangString(UINT resourceID, UInt32 langID) +{ + UString message; + if (g_Lang.GetMessage(langID, message)) + return message; + return NWindows::MyLoadStringW(resourceID); +} + +void LoadLangs(CObjectVector &langs) +{ + langs.Clear(); + UString folderPath; + if (!::GetProgramFolderPath(folderPath)) + return; + folderPath += L"Lang\\"; + NWindows::NFile::NFind::CEnumeratorW enumerator(folderPath + L"*.txt"); + NWindows::NFile::NFind::CFileInfoW fileInfo; + while (enumerator.Next(fileInfo)) + { + if (fileInfo.IsDirectory()) + continue; + CLangEx lang; + UString filePath = folderPath + fileInfo.Name; + const int kExtSize = 4; + if (fileInfo.Name.Right(kExtSize) != L".txt") + continue; + lang.ShortName = fileInfo.Name.Left(fileInfo.Name.Length() - kExtSize); + if (lang.Lang.Open(GetSystemString(filePath))) + langs.Add(lang); + } +} + +bool SplidID(const UString &id, WORD &primID, WORD &subID) +{ + primID = 0; + subID = 0; + const wchar_t *start = id; + const wchar_t *end; + UInt64 value = ConvertStringToUInt64(start, &end); + if (start == end) + return false; + primID = (WORD)value; + if (*end == 0) + return true; + if (*end != L'-') + return false; + start = end + 1; + value = ConvertStringToUInt64(start, &end); + if (start == end) + return false; + subID = (WORD)value; + return (*end == 0); +} + +void FindMatchLang(UString &shortName) +{ + shortName.Empty(); + LANGID langID = GetUserDefaultLangID(); + WORD primLang = (WORD)(PRIMARYLANGID(langID)); + WORD subLang = (WORD)(SUBLANGID(langID)); + CObjectVector langs; + LoadLangs(langs); + for (int i = 0; i < langs.Size(); i++) + { + const CLangEx &lang = langs[i]; + UString id; + if (lang.Lang.GetMessage(0x00000002, id)) + { + WORD primID; + WORD subID; + if (SplidID(id, primID, subID)) + if (primID == primLang) + { + if (subID == 0) + shortName = lang.ShortName; + if (subLang == subID) + { + shortName = lang.ShortName; + return; + } + } + } + } +} + +void ReloadLangSmart() +{ + #ifndef _UNICODE + if (g_IsNT) + #endif + { + ReadRegLang(g_LangID); + if (g_LangID.IsEmpty()) + { + UString shortName; + FindMatchLang(shortName); + if (shortName.IsEmpty()) + shortName = L"-"; + SaveRegLang(shortName); + } + } + ReloadLang(); +} diff --git a/CPP/7zip/FileManager/LangUtils.h b/CPP/7zip/FileManager/LangUtils.h new file mode 100755 index 00000000..40debdfe --- /dev/null +++ b/CPP/7zip/FileManager/LangUtils.h @@ -0,0 +1,41 @@ +// LangUtils.h + +#ifndef __LANGUTILS_H +#define __LANGUTILS_H + +#include "Common/Lang.h" +#include "Windows/ResourceString.h" + +extern UString g_LangID; + +struct CIDLangPair +{ + int ControlID; + UInt32 LangID; +}; + +void ReloadLang(); +void LoadLangOneTime(); +void ReloadLangSmart(); + +struct CLangEx +{ + CLang Lang; + UString ShortName; +}; + +void LoadLangs(CObjectVector &langs); + +void LangSetDlgItemsText(HWND dialogWindow, CIDLangPair *idLangPairs, int numItems); +void LangSetWindowText(HWND window, UInt32 langID); + +UString LangString(UInt32 langID); +UString LangString(UINT resourceID, UInt32 langID); + +#ifdef LANG +#define LangStringSpec(resourceID, langID) LangString(resourceID, langID) +#else +#define LangStringSpec(resourceID, langID) NWindows::MyLoadStringW(resourceID) +#endif + +#endif diff --git a/CPP/7zip/FileManager/Move.bmp b/CPP/7zip/FileManager/Move.bmp new file mode 100755 index 00000000..eb5f20f9 Binary files /dev/null and b/CPP/7zip/FileManager/Move.bmp differ diff --git a/CPP/7zip/FileManager/Move2.bmp b/CPP/7zip/FileManager/Move2.bmp new file mode 100755 index 00000000..58679eff Binary files /dev/null and b/CPP/7zip/FileManager/Move2.bmp differ diff --git a/CPP/7zip/FileManager/MyCom2.h b/CPP/7zip/FileManager/MyCom2.h new file mode 100755 index 00000000..756a8169 --- /dev/null +++ b/CPP/7zip/FileManager/MyCom2.h @@ -0,0 +1,48 @@ +// MyCom2.h + +#ifndef __MYCOM2_H +#define __MYCOM2_H + +#include "Common/MyCom.h" + +#define MY_ADDREF_RELEASE_MT \ +STDMETHOD_(ULONG, AddRef)() { InterlockedIncrement((LONG *)&__m_RefCount); return __m_RefCount; } \ +STDMETHOD_(ULONG, Release)() { InterlockedDecrement((LONG *)&__m_RefCount); if (__m_RefCount != 0) \ + return __m_RefCount; delete this; return 0; } + +#define MY_UNKNOWN_IMP_SPEC_MT(i) \ + MY_QUERYINTERFACE_BEGIN \ + MY_QUERYINTERFACE_ENTRY(IUnknown) \ + i \ + MY_QUERYINTERFACE_END \ + MY_ADDREF_RELEASE_MT + +#define MY_UNKNOWN_IMP_SPEC_MT2(i1, i) \ + MY_QUERYINTERFACE_BEGIN \ + if (iid == IID_IUnknown) \ + { *outObject = (void *)(IUnknown *)(i1 *)this; AddRef(); return S_OK; } i \ + MY_QUERYINTERFACE_END \ + MY_ADDREF_RELEASE_MT + + +#define MY_UNKNOWN_IMP_MT MY_UNKNOWN_IMP_SPEC_MT(;) + +#define MY_UNKNOWN_IMP1_MT(i) MY_UNKNOWN_IMP_SPEC_MT2( \ + i, \ + MY_QUERYINTERFACE_ENTRY(i) \ + ) + +#define MY_UNKNOWN_IMP2_MT(i1, i2) MY_UNKNOWN_IMP_SPEC_MT2( \ + i1, \ + MY_QUERYINTERFACE_ENTRY(i1) \ + MY_QUERYINTERFACE_ENTRY(i2) \ + ) + +#define MY_UNKNOWN_IMP3_MT(i1, i2, i3) MY_UNKNOWN_IMP_SPEC_MT2( \ + i1, \ + MY_QUERYINTERFACE_ENTRY(i1) \ + MY_QUERYINTERFACE_ENTRY(i2) \ + MY_QUERYINTERFACE_ENTRY(i3) \ + ) + +#endif diff --git a/CPP/7zip/FileManager/MyLoadMenu.cpp b/CPP/7zip/FileManager/MyLoadMenu.cpp new file mode 100755 index 00000000..8be1e28f --- /dev/null +++ b/CPP/7zip/FileManager/MyLoadMenu.cpp @@ -0,0 +1,694 @@ +// MyLoadMenu + +#include "StdAfx.h" + +#include "Common/StringConvert.h" + +#include "Windows/Menu.h" +#include "Windows/Error.h" + +#include "../PropID.h" + +#include "resource.h" +#include "App.h" +#include "Resource/AboutDialog/AboutDialog.h" +#include "Resource/BenchmarkDialog/BenchmarkDialog.h" + +#include "HelpUtils.h" +#include "LangUtils.h" +#include "PluginInterface.h" + +static const UINT kOpenBookmarkMenuID = 730; +static const UINT kSetBookmarkMenuID = 740; + +extern HINSTANCE g_hInstance; + +static LPCWSTR kFMHelpTopic = L"FM/index.htm"; + +extern void OptionsDialog(HWND hwndOwner, HINSTANCE hInstance); + +using namespace NWindows; + +static const int kFileMenuIndex = 0; +static const int kViewMenuIndex = 2; +static const int kBookmarksMenuIndex = kViewMenuIndex + 1; + +struct CStringLangPair +{ + wchar_t *String; + UINT32 LangID; +}; + +static CStringLangPair kStringLangPairs[] = +{ + { L"&File", 0x03000102 }, + { L"&Edit", 0x03000103 }, + { L"&View", 0x03000104 }, + { L"&Bookmarks", 0x03000107 }, + { L"&Tools", 0x03000105 }, + { L"&Help", 0x03000106 }, +}; + +UINT32 kAddToFavoritesLangID = 0x03000710; +UINT32 kToolbarsLangID = 0x03000451; + +/* +static int FindStringLangItem(const UString &anItem) +{ + for (int i = 0; i < sizeof(kStringLangPairs) / + sizeof(kStringLangPairs[0]); i++) + if (anItem.CompareNoCase(kStringLangPairs[i].String) == 0) + return i; + return -1; +} +*/ + +static CIDLangPair kIDLangPairs[] = +{ + // File + { IDM_FILE_OPEN, 0x03000210 }, + { IDM_FILE_OPEN_INSIDE, 0x03000211 }, + { IDM_FILE_OPEN_OUTSIDE, 0x03000212 }, + { IDM_FILE_VIEW, 0x03000220 }, + { IDM_FILE_EDIT, 0x03000221 }, + { IDM_RENAME, 0x03000230 }, + { IDM_COPY_TO, 0x03000231 }, + { IDM_MOVE_TO, 0x03000232 }, + { IDM_DELETE, 0x03000233 }, + { IDM_FILE_PROPERTIES, 0x03000240 }, + { IDM_FILE_COMMENT, 0x03000241 }, + { IDM_FILE_CRC, 0x03000242 }, + { IDM_FILE_SPLIT, 0x03000270 }, + { IDM_FILE_COMBINE, 0x03000271 }, + { IDM_CREATE_FOLDER, 0x03000250 }, + { IDM_CREATE_FILE, 0x03000251 }, + { IDCLOSE, 0x03000260 }, + + // Edit + { IDM_EDIT_CUT, 0x03000320 }, + { IDM_EDIT_COPY, 0x03000321 }, + { IDM_EDIT_PASTE, 0x03000322 }, + + { IDM_SELECT_ALL, 0x03000330 }, + { IDM_DESELECT_ALL, 0x03000331 }, + { IDM_INVERT_SELECTION, 0x03000332 }, + { IDM_SELECT, 0x03000333 }, + { IDM_DESELECT, 0x03000334 }, + { IDM_SELECT_BY_TYPE, 0x03000335 }, + { IDM_DESELECT_BY_TYPE, 0x03000336 }, + + { IDM_VIEW_LARGE_ICONS, 0x03000410 }, + { IDM_VIEW_SMALL_ICONS, 0x03000411 }, + { IDM_VIEW_LIST, 0x03000412 }, + { IDM_VIEW_DETAILS, 0x03000413 }, + + { IDM_VIEW_ARANGE_BY_NAME, 0x02000204 }, + { IDM_VIEW_ARANGE_BY_TYPE, 0x02000214 }, + { IDM_VIEW_ARANGE_BY_DATE, 0x0200020C }, + { IDM_VIEW_ARANGE_BY_SIZE, 0x02000207 }, + { IDM_VIEW_ARANGE_NO_SORT, 0x03000420 }, + + { IDM_OPEN_ROOT_FOLDER, 0x03000430 }, + { IDM_OPEN_PARENT_FOLDER, 0x03000431 }, + { IDM_FOLDERS_HISTORY, 0x03000432 }, + + { IDM_VIEW_REFRESH, 0x03000440 }, + + { IDM_VIEW_FLAT_VIEW, 0x03000449 }, + { IDM_VIEW_TWO_PANELS, 0x03000450 }, + { IDM_VIEW_ARCHIVE_TOOLBAR, 0x03000460 }, + { IDM_VIEW_STANDARD_TOOLBAR, 0x03000461 }, + { IDM_VIEW_TOOLBARS_LARGE_BUTTONS, 0x03000462 }, + { IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT, 0x03000463 }, + + { IDM_OPTIONS, 0x03000510 }, + { IDM_BENCHMARK, 0x03000511 }, + + { IDM_HELP_CONTENTS, 0x03000610 }, + { IDM_ABOUT, 0x03000620 } +}; + + +static int FindLangItem(int ControlID) +{ + for (int i = 0; i < sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]); i++) + if (kIDLangPairs[i].ControlID == ControlID) + return i; + return -1; +} + + +/* +static bool g_IsNew_fMask = true; + +class CInit_fMask +{ +public: + CInit_fMask() + { + g_IsNew_fMask = false; + OSVERSIONINFO vi; + vi.dwOSVersionInfoSize = sizeof(vi); + if (::GetVersionEx(&vi)) + { + g_IsNew_fMask = (vi.dwMajorVersion > 4 || + (vi.dwMajorVersion == 4 && vi.dwMinorVersion > 0)); + } + g_IsNew_fMask = false; + } +} g_Init_fMask; + +// it's hack for supporting Windows NT +// constants are from WinUser.h + +#if(WINVER < 0x0500) +#define MIIM_STRING 0x00000040 +#define MIIM_BITMAP 0x00000080 +#define MIIM_FTYPE 0x00000100 +#endif + +static UINT Get_fMaskForString() +{ + return g_IsNew_fMask ? MIIM_STRING : MIIM_TYPE; +} + +static UINT Get_fMaskForFTypeAndString() +{ + return g_IsNew_fMask ? (MIIM_STRING | MIIM_FTYPE) : MIIM_TYPE; +} +*/ + +static UINT Get_fMaskForString() +{ + return MIIM_TYPE; +} + +static UINT Get_fMaskForFTypeAndString() +{ + return MIIM_TYPE; +} + + + +static void MyChangeMenu(HMENU menuLoc, int level, int menuIndex) +{ + CMenu menu; + menu.Attach(menuLoc); + for (int i = 0; i < menu.GetItemCount(); i++) + { + CMenuItem item; + item.fMask = Get_fMaskForString() | MIIM_SUBMENU | MIIM_ID; + item.fType = MFT_STRING; + if (menu.GetItem(i, true, item)) + { + UString newString; + if (item.hSubMenu) + { + if (level == 1 && menuIndex == kBookmarksMenuIndex) + newString = LangString(kAddToFavoritesLangID); + else + { + MyChangeMenu(item.hSubMenu, level + 1, i); + if (level == 1 && menuIndex == kViewMenuIndex) + { + newString = LangString(kToolbarsLangID); + } + else + { + if (level == 0 && i < sizeof(kStringLangPairs) / + sizeof(kStringLangPairs[0])) + newString = LangString(kStringLangPairs[i].LangID); + else + continue; + } + } + if (newString.IsEmpty()) + continue; + } + else + { + int langPos = FindLangItem(item.wID); + if (langPos < 0) + continue; + newString = LangString(kIDLangPairs[langPos].LangID); + if (newString.IsEmpty()) + continue; + UString shorcutString = item.StringValue; + int tabPos = shorcutString.ReverseFind(wchar_t('\t')); + if (tabPos >= 0) + newString += shorcutString.Mid(tabPos); + } + { + item.StringValue = newString; + item.fMask = Get_fMaskForString(); + item.fType = MFT_STRING; + menu.SetItem(i, true, item); + } + } + } +} + +CMenu g_FileMenu; + +class CFileMenuDestroyer +{ +public: + ~CFileMenuDestroyer() + { + if ((HMENU)g_FileMenu != 0) + g_FileMenu.Destroy(); + } +} g_FileMenuDestroyer; + + +void MyLoadMenu(HWND hWnd) +{ + if ((HMENU)g_FileMenu != 0) + g_FileMenu.Destroy(); + HMENU oldMenu = ::GetMenu(hWnd); + HMENU baseMenu = ::LoadMenu(g_hInstance, MAKEINTRESOURCE(IDM_MENU)); + ::SetMenu(hWnd, baseMenu); + ::DestroyMenu(oldMenu); + if (!g_LangID.IsEmpty()) + { + HMENU menuOld = ::GetMenu(hWnd); + MyChangeMenu(menuOld, 0, 0); + } + ::DrawMenuBar(hWnd); +} + +extern HWND g_HWND; +void MyLoadMenu() +{ + MyLoadMenu(g_HWND); +} + +static void CopyMenu(HMENU srcMenuSpec, HMENU destMenuSpec) +{ + CMenu srcMenu; + srcMenu.Attach(srcMenuSpec); + CMenu destMenu; + destMenu.Attach(destMenuSpec); + int startPos = 0; + for (int i = 0; i < srcMenu.GetItemCount(); i++) + { + CMenuItem item; + item.fMask = MIIM_STATE | MIIM_ID | Get_fMaskForFTypeAndString(); + item.fType = MFT_STRING; + if (srcMenu.GetItem(i, true, item)) + if (destMenu.InsertItem(startPos, true, item)) + startPos++; + } +} + +void OnMenuActivating(HWND /* hWnd */, HMENU hMenu, int position) +{ + if (::GetSubMenu(::GetMenu(g_HWND), position) != hMenu) + return; + if (position == kFileMenuIndex) + { + if ((HMENU)g_FileMenu == 0) + { + g_FileMenu.CreatePopup(); + CopyMenu(hMenu, g_FileMenu); + } + CMenu menu; + menu.Attach(hMenu); + while (menu.GetItemCount() > 0) + { + if (!menu.RemoveItem(0, MF_BYPOSITION)) + break; + } + // CopyMenu(g_FileMenu, hMenu); + g_App.GetFocusedPanel().CreateFileMenu(hMenu); + + } + else if (position == kViewMenuIndex) + { + // View; + CMenu menu; + menu.Attach(hMenu); + menu.CheckRadioItem(IDM_VIEW_LARGE_ICONS, IDM_VIEW_DETAILS, + IDM_VIEW_LARGE_ICONS + g_App.GetListViewMode(), MF_BYCOMMAND); + menu.CheckItem(IDM_VIEW_TWO_PANELS, MF_BYCOMMAND | + ((g_App.NumPanels == 2) ? MF_CHECKED : MF_UNCHECKED)); + menu.CheckItem(IDM_VIEW_FLAT_VIEW, MF_BYCOMMAND | + ((g_App.GetFlatMode()) ? MF_CHECKED : MF_UNCHECKED)); + menu.CheckItem(IDM_VIEW_ARCHIVE_TOOLBAR, MF_BYCOMMAND | + (g_App.ShowArchiveToolbar ? MF_CHECKED : MF_UNCHECKED)); + menu.CheckItem(IDM_VIEW_STANDARD_TOOLBAR, MF_BYCOMMAND | + (g_App.ShowStandardToolbar ? MF_CHECKED : MF_UNCHECKED)); + menu.CheckItem(IDM_VIEW_TOOLBARS_LARGE_BUTTONS, MF_BYCOMMAND | + (g_App.LargeButtons ? MF_CHECKED : MF_UNCHECKED)); + menu.CheckItem(IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT, MF_BYCOMMAND | + (g_App.ShowButtonsLables ? MF_CHECKED : MF_UNCHECKED)); + } + else if (position == kBookmarksMenuIndex) + { + CMenu menu; + menu.Attach(hMenu); + + CMenu subMenu; + subMenu.Attach(menu.GetSubMenu(0)); + while (subMenu.GetItemCount() > 0) + subMenu.RemoveItem(subMenu.GetItemCount() - 1, MF_BYPOSITION); + int i; + for (i = 0; i < 10; i++) + { + UString s = LangString(IDS_BOOKMARK, 0x03000720); + s += L" "; + wchar_t c = (wchar_t)(L'0' + i); + s += c; + s += L"\tAlt+Shift+"; + s += c; + subMenu.AppendItem(MF_STRING, kSetBookmarkMenuID + i, s); + } + + while (menu.GetItemCount() > 2) + menu.RemoveItem(menu.GetItemCount() - 1, MF_BYPOSITION); + + for (i = 0; i < 10; i++) + { + UString path = g_App.AppState.FastFolders.GetString(i); + const int kMaxSize = 100; + const int kFirstPartSize = kMaxSize / 2; + if (path.Length() > kMaxSize) + { + path = path.Left(kFirstPartSize) + UString(L" ... ") + + path.Right(kMaxSize - kFirstPartSize); + } + UString s = path; + if (s.IsEmpty()) + s = L"-"; + s += L"\tAlt+"; + s += (wchar_t)(L'0' + i); + menu.AppendItem(MF_STRING, kOpenBookmarkMenuID + i, s); + } + } +} + +/* +It doesn't help +void OnMenuUnActivating(HWND hWnd, HMENU hMenu, int id) +{ + if (::GetSubMenu(::GetMenu(g_HWND), 0) != hMenu) + return; + // g_App.GetFocusedPanel()._contextMenu.Release(); +} + +void OnMenuUnActivating(HWND hWnd) +{ +} +*/ + + +void LoadFileMenu(HMENU hMenu, int startPos, bool /* forFileMode */, bool programMenu) +{ + { + CMenu srcMenu; + srcMenu.Attach(::GetSubMenu(::GetMenu(g_HWND), 0)); + if ((HMENU)g_FileMenu == 0) + { + g_FileMenu.CreatePopup(); + CopyMenu(srcMenu, g_FileMenu); + } + } + + CMenu destMenu; + destMenu.Attach(hMenu); + + for (int i = 0; i < g_FileMenu.GetItemCount(); i++) + { + CMenuItem item; + + item.fMask = MIIM_STATE | MIIM_ID | Get_fMaskForFTypeAndString(); + item.fType = MFT_STRING; + if (g_FileMenu.GetItem(i, true, item)) + { + if (!programMenu) + if (item.wID == IDCLOSE) + continue; + /* + bool createItem = (item.wID == IDM_CREATE_FOLDER || item.wID == IDM_CREATE_FILE); + if (forFileMode) + { + if (createItem) + continue; + } + else + { + if (!createItem) + continue; + } + */ + if (destMenu.InsertItem(startPos, true, item)) + startPos++; + } + } + while (destMenu.GetItemCount() > 0) + { + CMenuItem item; + item.fMask = MIIM_TYPE; + item.fType = 0; + // item.dwTypeData = 0; + int lastIndex = destMenu.GetItemCount() - 1; + if (!destMenu.GetItem(lastIndex, true, item)) + break; + if(item.fType != MFT_SEPARATOR) + break; + if (!destMenu.RemoveItem(lastIndex, MF_BYPOSITION)) + break; + } +} + +bool ExecuteFileCommand(int id) +{ + if (id >= kPluginMenuStartID) + { + g_App.GetFocusedPanel().InvokePluginCommand(id); + g_App.GetFocusedPanel()._sevenZipContextMenu.Release(); + g_App.GetFocusedPanel()._systemContextMenu.Release(); + return true; + } + + switch (id) + { + // File + case IDM_FILE_OPEN: + g_App.OpenItem(); + break; + case IDM_FILE_OPEN_INSIDE: + g_App.OpenItemInside(); + break; + case IDM_FILE_OPEN_OUTSIDE: + g_App.OpenItemOutside(); + break; + case IDM_FILE_VIEW: + break; + case IDM_FILE_EDIT: + g_App.EditItem(); + break; + case IDM_RENAME: + g_App.Rename(); + break; + case IDM_COPY_TO: + g_App.CopyTo(); + break; + case IDM_MOVE_TO: + g_App.MoveTo(); + break; + case IDM_DELETE: + { + bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0; + g_App.Delete(!shift); + break; + } + case IDM_FILE_CRC: + g_App.CalculateCrc(); + break; + case IDM_FILE_SPLIT: + g_App.Split(); + break; + case IDM_FILE_COMBINE: + g_App.Combine(); + break; + case IDM_FILE_PROPERTIES: + g_App.Properties(); + break; + case IDM_FILE_COMMENT: + g_App.Comment(); + break; + + case IDM_CREATE_FOLDER: + g_App.CreateFolder(); + break; + case IDM_CREATE_FILE: + g_App.CreateFile(); + break; + default: + return false; + } + return true; +} + +bool OnMenuCommand(HWND hWnd, int id) +{ + if (ExecuteFileCommand(id)) + return true; + + switch (id) + { + // File + case IDCLOSE: + SendMessage(hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)hWnd); + SendMessage (hWnd, WM_CLOSE, 0, 0); + break; + + // Edit + case IDM_EDIT_COPY: + g_App.EditCopy(); + break; + case IDM_EDIT_PASTE: + g_App.EditPaste(); + break; + case IDM_SELECT_ALL: + g_App.SelectAll(true); + g_App.RefreshStatusBar(); + break; + case IDM_DESELECT_ALL: + g_App.SelectAll(false); + g_App.RefreshStatusBar(); + break; + case IDM_INVERT_SELECTION: + g_App.InvertSelection(); + g_App.RefreshStatusBar(); + break; + case IDM_SELECT: + g_App.SelectSpec(true); + g_App.RefreshStatusBar(); + break; + case IDM_DESELECT: + g_App.SelectSpec(false); + g_App.RefreshStatusBar(); + break; + case IDM_SELECT_BY_TYPE: + g_App.SelectByType(true); + g_App.RefreshStatusBar(); + break; + case IDM_DESELECT_BY_TYPE: + g_App.SelectByType(false); + g_App.RefreshStatusBar(); + break; + + //View + case IDM_VIEW_LARGE_ICONS: + case IDM_VIEW_SMALL_ICONS: + case IDM_VIEW_LIST: + case IDM_VIEW_DETAILS: + { + UINT index = id - IDM_VIEW_LARGE_ICONS; + if (index < 4) + { + g_App.SetListViewMode(index); + /* + CMenu menu; + menu.Attach(::GetSubMenu(::GetMenu(hWnd), kViewMenuIndex)); + menu.CheckRadioItem(IDM_VIEW_LARGE_ICONS, IDM_VIEW_DETAILS, + id, MF_BYCOMMAND); + */ + } + break; + } + case IDM_VIEW_ARANGE_BY_NAME: + { + g_App.SortItemsWithPropID(kpidName); + break; + } + case IDM_VIEW_ARANGE_BY_TYPE: + { + g_App.SortItemsWithPropID(kpidExtension); + break; + } + case IDM_VIEW_ARANGE_BY_DATE: + { + g_App.SortItemsWithPropID(kpidLastWriteTime); + break; + } + case IDM_VIEW_ARANGE_BY_SIZE: + { + g_App.SortItemsWithPropID(kpidSize); + break; + } + case IDM_VIEW_ARANGE_NO_SORT: + { + g_App.SortItemsWithPropID(kpidNoProperty); + break; + } + + case IDM_OPEN_ROOT_FOLDER: + g_App.OpenRootFolder(); + break; + case IDM_OPEN_PARENT_FOLDER: + g_App.OpenParentFolder(); + break; + case IDM_FOLDERS_HISTORY: + g_App.FoldersHistory(); + break; + case IDM_VIEW_REFRESH: + g_App.RefreshView(); + break; + case IDM_VIEW_FLAT_VIEW: + g_App.ChangeFlatMode(); + break; + case IDM_VIEW_TWO_PANELS: + g_App.SwitchOnOffOnePanel(); + break; + case IDM_VIEW_STANDARD_TOOLBAR: + g_App.SwitchStandardToolbar(); + break; + case IDM_VIEW_ARCHIVE_TOOLBAR: + g_App.SwitchArchiveToolbar(); + break; + case IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT: + g_App.SwitchButtonsLables(); + break; + case IDM_VIEW_TOOLBARS_LARGE_BUTTONS: + g_App.SwitchLargeButtons(); + break; + + // Tools + case IDM_OPTIONS: + OptionsDialog(hWnd, g_hInstance); + break; + + case IDM_BENCHMARK: + Benchmark(hWnd); + break; + // Help + case IDM_HELP_CONTENTS: + ShowHelpWindow(NULL, kFMHelpTopic); + break; + case IDM_ABOUT: + { + CAboutDialog dialog; + dialog.Create(hWnd); + break; + } + default: + { + if (id >= kOpenBookmarkMenuID && id <= kOpenBookmarkMenuID + 9) + { + g_App.OpenBookmark(id - kOpenBookmarkMenuID); + return true; + } + else if (id >= kSetBookmarkMenuID && id <= kSetBookmarkMenuID + 9) + { + g_App.SetBookmark(id - kSetBookmarkMenuID); + return true; + } + return false; + } + } + return true; +} + diff --git a/CPP/7zip/FileManager/MyLoadMenu.h b/CPP/7zip/FileManager/MyLoadMenu.h new file mode 100755 index 00000000..490dc6d8 --- /dev/null +++ b/CPP/7zip/FileManager/MyLoadMenu.h @@ -0,0 +1,16 @@ +// MyLoadMenu.h + +#ifndef __MYLOADMENU_H +#define __MYLOADMENU_H + +void OnMenuActivating(HWND hWnd, HMENU hMenu, int position); +// void OnMenuUnActivating(HWND hWnd, HMENU hMenu, int id); +// void OnMenuUnActivating(HWND hWnd); + +void MyLoadMenu(HWND hWnd); +bool OnMenuCommand(HWND hWnd, int id); +void MyLoadMenu(); +void LoadFileMenu(HMENU hMenu, int startPos, bool forFileMode, bool programMenu); +bool ExecuteFileCommand(int id); + +#endif diff --git a/CPP/7zip/FileManager/NetFolder.cpp b/CPP/7zip/FileManager/NetFolder.cpp new file mode 100755 index 00000000..a5cd379a --- /dev/null +++ b/CPP/7zip/FileManager/NetFolder.cpp @@ -0,0 +1,315 @@ +// NetFolder.cpp + +#include "StdAfx.h" + +#include "NetFolder.h" + +#include "Common/StringConvert.h" +#include "../PropID.h" +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" +#include "Windows/FileFind.h" + +#include "SysIconUtils.h" +#include "FSFolder.h" + +using namespace NWindows; +using namespace NNet; + +static const STATPROPSTG kProperties[] = +{ + { NULL, kpidName, VT_BSTR}, + { NULL, kpidLocalName, VT_BSTR}, + { NULL, kpidComment, VT_BSTR}, + { NULL, kpidProvider, VT_BSTR} +}; + +void CNetFolder::Init(const UString &path) +{ + /* + if (path.Length() > 2) + { + if (path[0] == L'\\' && path[1] == L'\\') + { + CResource netResource; + netResource.RemoteName = GetSystemString(path.Left(path.Length() - 1)); + netResource.Scope = RESOURCE_GLOBALNET; + netResource.Type = RESOURCETYPE_DISK; + netResource.DisplayType = RESOURCEDISPLAYTYPE_SERVER; + netResource.Usage = RESOURCEUSAGE_CONTAINER; + Init(&netResource, 0, path); + return; + } + } + Init(0, 0 , L""); + */ + CResourceW resource; + resource.RemoteNameIsDefined = true; + resource.RemoteName = path.Left(path.Length() - 1); + resource.ProviderIsDefined = false; + resource.LocalNameIsDefined = false; + resource.CommentIsDefined = false; + resource.Type = RESOURCETYPE_DISK; + resource.Scope = RESOURCE_GLOBALNET; + resource.Usage = 0; + resource.DisplayType = 0; + CResourceW destResource; + UString systemPathPart; + DWORD result = GetResourceInformation(resource, destResource, systemPathPart); + if (result == NO_ERROR) + Init(&destResource, 0, path); + else + Init(0, 0 , L""); + return; +} + +void CNetFolder::Init(const NWindows::NNet::CResourceW *netResource, + IFolderFolder *parentFolder, const UString &path) +{ + _path = path; + if (netResource == 0) + _netResourcePointer = 0; + else + { + _netResource = *netResource; + _netResourcePointer = &_netResource; + + // if (_netResource.DisplayType == RESOURCEDISPLAYTYPE_SERVER) + _path = _netResource.RemoteName + L'\\'; + } + _parentFolder = parentFolder; +} + +STDMETHODIMP CNetFolder::LoadItems() +{ + _items.Clear(); + CEnum enumerator; + + for (;;) + { + DWORD result = enumerator.Open( + RESOURCE_GLOBALNET, + RESOURCETYPE_DISK, + 0, // enumerate all resources + _netResourcePointer + ); + if (result == NO_ERROR) + break; + if (result != ERROR_ACCESS_DENIED) + return result; + if (_netResourcePointer != 0) + result = AddConnection2(_netResource, + 0, 0, CONNECT_INTERACTIVE); + if (result != NO_ERROR) + return result; + } + + for (;;) + { + CResourceEx resource; + DWORD result = enumerator.Next(resource); + if (result == NO_ERROR) + { + if (!resource.RemoteNameIsDefined) // For Win 98, I don't know what's wrong + resource.RemoteName = resource.Comment; + resource.Name = resource.RemoteName; + int aPos = resource.Name.ReverseFind(L'\\'); + if (aPos >= 0) + { + // _path = resource.Name.Left(aPos + 1); + resource.Name = resource.Name.Mid(aPos + 1); + } + _items.Add(resource); + } + else if (result == ERROR_NO_MORE_ITEMS) + break; + else + return result; + } + + /* + It's too slow for some systems. + if (_netResourcePointer && _netResource.DisplayType == RESOURCEDISPLAYTYPE_SERVER) + { + for (char c = 'a'; c <= 'z'; c++) + { + CResourceEx resource; + resource.Name = UString(wchar_t(c)) + L'$'; + resource.RemoteNameIsDefined = true; + resource.RemoteName = _path + resource.Name; + + NFile::NFind::CFindFile findFile; + NFile::NFind::CFileInfoW fileInfo; + if (!findFile.FindFirst(resource.RemoteName + UString(L"\\*"), fileInfo)) + continue; + resource.Usage = RESOURCEUSAGE_CONNECTABLE; + resource.LocalNameIsDefined = false; + resource.CommentIsDefined = false; + resource.ProviderIsDefined = false; + _items.Add(resource); + } + } + */ + return S_OK; +} + + +STDMETHODIMP CNetFolder::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _items.Size(); + return S_OK; +} + +STDMETHODIMP CNetFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value) +{ + NCOM::CPropVariant propVariant; + const CResourceEx &item = _items[itemIndex]; + switch(propID) + { + case kpidIsFolder: + propVariant = true; + break; + case kpidName: + // if (item.RemoteNameIsDefined) + propVariant = item.Name; + break; + case kpidLocalName: + if (item.LocalNameIsDefined) + propVariant = item.LocalName; + break; + case kpidComment: + if (item.CommentIsDefined) + propVariant = item.Comment; + break; + case kpidProvider: + if (item.ProviderIsDefined) + propVariant = item.Provider; + break; + } + propVariant.Detach(value); + return S_OK; +} + +STDMETHODIMP CNetFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder) +{ + *resultFolder = 0; + const CResourceEx &resource = _items[index]; + if (resource.Usage == RESOURCEUSAGE_CONNECTABLE || + resource.DisplayType == RESOURCEDISPLAYTYPE_SHARE) + { + CFSFolder *fsFolderSpec = new CFSFolder; + CMyComPtr subFolder = fsFolderSpec; + RINOK(fsFolderSpec->Init(resource.RemoteName + L'\\', this)); + *resultFolder = subFolder.Detach(); + } + else + { + CNetFolder *netFolder = new CNetFolder; + CMyComPtr subFolder = netFolder; + netFolder->Init(&resource, this, resource.Name + L'\\'); + *resultFolder = subFolder.Detach(); + } + return S_OK; +} + +STDMETHODIMP CNetFolder::BindToFolder(const wchar_t * /* name */, IFolderFolder ** /* resultFolder */) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CNetFolder::BindToParentFolder(IFolderFolder **resultFolder) +{ + *resultFolder = 0; + if (_parentFolder) + { + CMyComPtr parentFolder = _parentFolder; + *resultFolder = parentFolder.Detach(); + return S_OK; + } + if (_netResourcePointer != 0) + { + CResourceW resourceParent; + DWORD result = GetResourceParent(_netResource, resourceParent); + if (result != NO_ERROR) + return result; + if (!_netResource.RemoteNameIsDefined) + return S_OK; + + CNetFolder *netFolder = new CNetFolder; + CMyComPtr subFolder = netFolder; + netFolder->Init(&resourceParent, 0, L'\\'); + *resultFolder = subFolder.Detach(); + } + return S_OK; +} + +STDMETHODIMP CNetFolder::GetName(BSTR *name) +{ + *name = 0; + return E_NOTIMPL; + /* + CMyComBSTR aBSTRName = m_ProxyFolderItem->m_Name; + *aName = aBSTRName.Detach(); + return S_OK; + */ +} + +STDMETHODIMP CNetFolder::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CNetFolder::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if (index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &prop = kProperties[index]; + *propID = prop.propid; + *varType = prop.vt; + *name = 0; + return S_OK; +} + +STDMETHODIMP CNetFolder::GetTypeID(BSTR *name) +{ + CMyComBSTR aBSTRName = L"NetFolder"; + *name = aBSTRName.Detach(); + return S_OK; +} + +STDMETHODIMP CNetFolder::GetPath(BSTR *path) +{ + CMyComBSTR aBSTRName = _path; + *path = aBSTRName.Detach(); + return S_OK; +} + +STDMETHODIMP CNetFolder::GetSystemIconIndex(UInt32 index, INT32 *iconIndex) +{ + if (index >= (UInt32)_items.Size()) + return E_INVALIDARG; + *iconIndex = 0; + const CResourceW &resource = _items[index]; + int iconIndexTemp; + if (resource.DisplayType == RESOURCEDISPLAYTYPE_SERVER || + resource.Usage == RESOURCEUSAGE_CONNECTABLE) + { + if (GetRealIconIndex(resource.RemoteName, 0, iconIndexTemp)) + { + *iconIndex = iconIndexTemp; + return S_OK; + } + } + else + { + if (GetRealIconIndex(TEXT(""), FILE_ATTRIBUTE_DIRECTORY, iconIndexTemp)) + { + *iconIndex = iconIndexTemp; + return S_OK; + } + // *anIconIndex = GetRealIconIndex(0, L"\\\\HOME"); + } + return GetLastError(); +} diff --git a/CPP/7zip/FileManager/NetFolder.h b/CPP/7zip/FileManager/NetFolder.h new file mode 100755 index 00000000..f23c7e4e --- /dev/null +++ b/CPP/7zip/FileManager/NetFolder.h @@ -0,0 +1,66 @@ +// NetFolder.h + +#ifndef __NETFOLDER_H +#define __NETFOLDER_H + +#include "Common/String.h" +#include "Common/Buffer.h" +#include "Common/MyCom.h" +#include "Windows/PropVariant.h" +#include "Windows/Net.h" + +#include "IFolder.h" + +struct CResourceEx: public NWindows::NNet::CResourceW +{ + UString Name; +}; + +class CNetFolder: + public IFolderFolder, + public IEnumProperties, + public IFolderGetTypeID, + public IFolderGetPath, + public IFolderGetSystemIconIndex, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP4( + IEnumProperties, + IFolderGetTypeID, + IFolderGetPath, + IFolderGetSystemIconIndex + ) + + STDMETHOD(LoadItems)(); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 itemIndex, PROPID propID, PROPVARIANT *value); + STDMETHOD(BindToFolder)(UInt32 index, IFolderFolder **resultFolder); + STDMETHOD(BindToFolder)(const wchar_t *name, IFolderFolder **resultFolder); + STDMETHOD(BindToParentFolder)(IFolderFolder **resultFolder); + STDMETHOD(GetName)(BSTR *name); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + STDMETHOD(GetTypeID)(BSTR *name); + STDMETHOD(GetPath)(BSTR *path); + STDMETHOD(GetSystemIconIndex)(UInt32 index, INT32 *iconIndex); + +private: + NWindows::NNet::CResourceW _netResource; + NWindows::NNet::CResourceW *_netResourcePointer; + + CObjectVector _items; + + CMyComPtr _parentFolder; + UString _path; + +public: + void Init(const UString &path); + void Init(const NWindows::NNet::CResourceW *netResource, + IFolderFolder *parentFolder, const UString &path); + CNetFolder(): _netResourcePointer(0) {} +}; + +#endif diff --git a/CPP/7zip/FileManager/OpenCallback.cpp b/CPP/7zip/FileManager/OpenCallback.cpp new file mode 100755 index 00000000..a69de62c --- /dev/null +++ b/CPP/7zip/FileManager/OpenCallback.cpp @@ -0,0 +1,113 @@ +// OpenCallback.cpp + +#include "StdAfx.h" + +#include "OpenCallback.h" + +#include "Common/StringConvert.h" +#include "Resource/PasswordDialog/PasswordDialog.h" +#include "Windows/PropVariant.h" +#include "../Common/FileStreams.h" + +STDMETHODIMP COpenArchiveCallback::SetTotal(const UINT64 * /* numFiles */, const UINT64 * /* numBytes */) +{ + return S_OK; +} + +STDMETHODIMP COpenArchiveCallback::SetCompleted(const UINT64 * /* numFiles */, const UINT64 * /* numBytes */) +{ + return S_OK; +} + +STDMETHODIMP COpenArchiveCallback::SetTotal(const UINT64 /* total */) +{ + return S_OK; +} + +STDMETHODIMP COpenArchiveCallback::SetCompleted(const UINT64 * /* completed */) +{ + return S_OK; +} + +STDMETHODIMP COpenArchiveCallback::GetProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + if (_subArchiveMode) + { + switch(propID) + { + case kpidName: + propVariant = _subArchiveName; + break; + } + propVariant.Detach(value); + return S_OK; + } + switch(propID) + { + case kpidName: + propVariant = _fileInfo.Name; + break; + case kpidIsFolder: + propVariant = _fileInfo.IsDirectory(); + break; + case kpidSize: + propVariant = _fileInfo.Size; + break; + case kpidAttributes: + propVariant = (UINT32)_fileInfo.Attributes; + break; + case kpidLastAccessTime: + propVariant = _fileInfo.LastAccessTime; + break; + case kpidCreationTime: + propVariant = _fileInfo.CreationTime; + break; + case kpidLastWriteTime: + propVariant = _fileInfo.LastWriteTime; + break; + } + propVariant.Detach(value); + return S_OK; +} + +STDMETHODIMP COpenArchiveCallback::GetStream(const wchar_t *name, + IInStream **inStream) +{ + *inStream = NULL; + if (_subArchiveMode) + return S_FALSE; + + NWindows::NFile::NFind::CFileInfoW fileInfo; + + UString fullPath = _folderPrefix + name; + if (!NWindows::NFile::NFind::FindFile(fullPath, fileInfo)) + return S_FALSE; + _fileInfo = fileInfo; + if (_fileInfo.IsDirectory()) + return S_FALSE; + CInFileStream *inFile = new CInFileStream; + CMyComPtr inStreamTemp = inFile; + if (!inFile->Open(fullPath)) + return ::GetLastError(); + *inStream = inStreamTemp.Detach(); + return S_OK; +} + +STDMETHODIMP COpenArchiveCallback::CryptoGetTextPassword(BSTR *password) +{ + PasswordWasAsked = true; + if (!PasswordIsDefined) + { + CPasswordDialog dialog; + + if (dialog.Create(ParentWindow) == IDCANCEL) + return E_ABORT; + + Password = dialog.Password; + PasswordIsDefined = true; + } + CMyComBSTR tempName(Password); + *password = tempName.Detach(); + return S_OK; +} diff --git a/CPP/7zip/FileManager/OpenCallback.h b/CPP/7zip/FileManager/OpenCallback.h new file mode 100755 index 00000000..853c0e44 --- /dev/null +++ b/CPP/7zip/FileManager/OpenCallback.h @@ -0,0 +1,85 @@ +// OpenCallback.h + +#ifndef __OPENCALLBACK_H +#define __OPENCALLBACK_H + +#include "Common/String.h" +#include "Common/MyCom.h" +#include "Windows/FileFind.h" + +#include "../IPassword.h" + +#include "../Archive/IArchive.h" + +class COpenArchiveCallback: + public IArchiveOpenCallback, + public IArchiveOpenVolumeCallback, + public IArchiveOpenSetSubArchiveName, + public IProgress, + public ICryptoGetTextPassword, + public CMyUnknownImp +{ + UString _folderPrefix; + NWindows::NFile::NFind::CFileInfoW _fileInfo; +public: + bool PasswordIsDefined; + UString Password; + bool PasswordWasAsked; + HWND ParentWindow; + + bool _subArchiveMode; + UString _subArchiveName; + +public: + MY_UNKNOWN_IMP5( + IArchiveOpenCallback, + IArchiveOpenVolumeCallback, + IArchiveOpenSetSubArchiveName, + IProgress, + ICryptoGetTextPassword) + + // IProgress + STDMETHOD(SetTotal)(UINT64 total); + STDMETHOD(SetCompleted)(const UINT64 *completeValue); + + // IArchiveOpenCallback + STDMETHOD(SetTotal)(const UINT64 *numFiles, const UINT64 *numBytes); + STDMETHOD(SetCompleted)(const UINT64 *numFiles, const UINT64 *numBytes); + + // IArchiveOpenVolumeCallback + STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value); + STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream); + + // ICryptoGetTextPassword + STDMETHOD(CryptoGetTextPassword)(BSTR *password); + + STDMETHOD(SetSubArchiveName(const wchar_t *name)) + { + _subArchiveMode = true; + _subArchiveName = name; + return S_OK; + } + + COpenArchiveCallback() + { + _subArchiveMode = false; + PasswordIsDefined = false; + PasswordWasAsked = false; + } + /* + void Init() + { + PasswordIsDefined = false; + _subArchiveMode = false; + } + */ + void LoadFileInfo(const UString &folderPrefix, const UString &fileName) + { + _folderPrefix = folderPrefix; + if (!NWindows::NFile::NFind::FindFile(_folderPrefix + fileName, _fileInfo)) + throw 1; + } + void ShowMessage(const UINT64 *completed); +}; + +#endif diff --git a/CPP/7zip/FileManager/OptionsDialog.cpp b/CPP/7zip/FileManager/OptionsDialog.cpp new file mode 100755 index 00000000..7413bafc --- /dev/null +++ b/CPP/7zip/FileManager/OptionsDialog.cpp @@ -0,0 +1,65 @@ +// OptionsDialog.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "Common/StringConvert.h" + +#include "Windows/Control/PropertyPage.h" +#include "Windows/Error.h" + +#include "Resource/LangPage/LangPage.h" +#include "Resource/LangPage/resource.h" +#include "Resource/PluginsPage/PluginsPage.h" +#include "Resource/PluginsPage/resource.h" +#include "Resource/SystemPage/SystemPage.h" +#include "Resource/SystemPage/resource.h" +#include "Resource/EditPage/EditPage.h" +#include "Resource/EditPage/resource.h" +#include "Resource/SettingsPage/SettingsPage.h" +#include "Resource/SettingsPage/resource.h" + +#include "LangUtils.h" +#include "MyLoadMenu.h" +#include "App.h" + +using namespace NWindows; + +void OptionsDialog(HWND hwndOwner, HINSTANCE /* hInstance */) +{ + CSystemPage systemPage; + CPluginsPage pluginsPage; + CEditPage editPage; + CSettingsPage settingsPage; + CLangPage langPage; + + CObjectVector pages; + UINT32 langIDs[] = { 0x03010300, 0x03010100, 0x03010200, 0x03010400, 0x01000400}; + UINT pageIDs[] = { IDD_SYSTEM, IDD_PLUGINS, IDD_EDIT, IDD_SETTINGS, IDD_LANG}; + NControl::CPropertyPage *pagePinters[] = { &systemPage, &pluginsPage, &editPage, &settingsPage, &langPage }; + const int kNumPages = sizeof(langIDs) / sizeof(langIDs[0]); + for (int i = 0; i < kNumPages; i++) + { + NControl::CPageInfo page; + page.Title = LangString(langIDs[i]); + page.ID = pageIDs[i]; + page.Page = pagePinters[i]; + pages.Add(page); + } + + INT_PTR res = NControl::MyPropertySheet(pages, hwndOwner, LangString(IDS_OPTIONS, 0x03010000)); + if (res != -1 && res != 0) + { + if (langPage._langWasChanged) + { + g_App._window.SetText(LangString(IDS_APP_TITLE, 0x03000000)); + MyLoadMenu(); + } + g_App.SetListSettings(); + g_App.SetShowSystemMenu(); + g_App.RefreshAllPanels(); + g_App.ReloadToolbars(); + // ::PostMessage(hwndOwner, kLangWasChangedMessage, 0 , 0); + } +} diff --git a/CPP/7zip/FileManager/Panel.cpp b/CPP/7zip/FileManager/Panel.cpp new file mode 100755 index 00000000..fcc33edf --- /dev/null +++ b/CPP/7zip/FileManager/Panel.cpp @@ -0,0 +1,856 @@ +// Panel.cpp + +#include "StdAfx.h" + +#include + +#include "Common/Defs.h" +#include "Common/StringConvert.h" +#include "Windows/Error.h" +#include "Windows/PropVariant.h" + +#include "../PropID.h" + +#include "Panel.h" +#include "RootFolder.h" +#include "FSFolder.h" +#include "FormatUtils.h" +#include "App.h" + +#include "../UI/Common/CompressCall.h" +#include "../UI/Common/ArchiveName.h" + +using namespace NWindows; + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +static const UINT_PTR kTimerID = 1; +static const UINT kTimerElapse = 1000; + +static LPCWSTR kSelectOneFile = L"Select one file"; +static LPCWSTR kSelectFiles = L"Select files"; + +static DWORD kStyles[4] = { LVS_ICON, LVS_SMALLICON, LVS_LIST, LVS_REPORT }; + +// static const int kCreateFolderID = 101; +// static const UINT kFileChangeNotifyMessage = WM_APP; + +extern HINSTANCE g_hInstance; +extern DWORD g_ComCtl32Version; + +void CPanel::Release() +{ + // It's for unloading COM dll's: don't change it. + CloseOpenFolders(); + _sevenZipContextMenu.Release(); + _systemContextMenu.Release(); +} + +CPanel::~CPanel() +{ + CloseOpenFolders(); +} + +static LPCWSTR kClassName = L"7-Zip::Panel"; + + +LRESULT CPanel::Create(HWND mainWindow, HWND parentWindow, UINT id, + const UString ¤tFolderPrefix, CPanelCallback *panelCallback, CAppState *appState, + bool &archiveIsOpened, bool &encrypted) +{ + _mainWindow = mainWindow; + _processTimer = true; + _processNotify = true; + + _panelCallback = panelCallback; + _appState = appState; + // _index = index; + _baseID = id; + _comboBoxID = _baseID + 3; + _statusBarID = _comboBoxID + 1; + + UString cfp = currentFolderPrefix; + + if (!currentFolderPrefix.IsEmpty()) + if (currentFolderPrefix[0] == L'.') + if (!NFile::NDirectory::MyGetFullPathName(currentFolderPrefix, cfp)) + cfp = currentFolderPrefix; + BindToPath(cfp, archiveIsOpened, encrypted); + + if (!CreateEx(0, kClassName, 0, WS_CHILD | WS_VISIBLE, + 0, 0, _xSize, 260, + parentWindow, (HMENU)(UINT_PTR)id, g_hInstance)) + return E_FAIL; + return S_OK; +} + +LRESULT CPanel::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch(message) + { + case kShiftSelectMessage: + OnShiftSelectMessage(); + return 0; + case kReLoadMessage: + RefreshListCtrl(_selectedState); + return 0; + case kSetFocusToListView: + _listView.SetFocus(); + return 0; + case kOpenItemChanged: + return OnOpenItemChanged(lParam); + case kRefreshStatusBar: + OnRefreshStatusBar(); + return 0; + case WM_TIMER: + OnTimer(); + return 0; + case WM_CONTEXTMENU: + if (OnContextMenu(HANDLE(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))) + return 0; + break; + /* + case WM_DROPFILES: + CompressDropFiles(HDROP(wParam)); + return 0; + */ + } + return CWindow2::OnMessage(message, wParam, lParam); +} + +static LRESULT APIENTRY ListViewSubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + CWindow tempDialog(hwnd); + CMyListView *w = (CMyListView *)(tempDialog.GetUserDataLongPtr()); + if (w == NULL) + return 0; + return w->OnMessage(message, wParam, lParam); +} + +LRESULT CMyListView::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + if (message == WM_CHAR) + { + UINT scanCode = (UINT)((lParam >> 16) & 0xFF); + bool extended = ((lParam & 0x1000000) != 0); + UINT virtualKey = MapVirtualKey(scanCode, 1); + if (virtualKey == VK_MULTIPLY || virtualKey == VK_ADD || + virtualKey == VK_SUBTRACT) + return 0; + if ((wParam == '/' && extended) + || wParam == '\\' || wParam == '/') + { + _panel->OpenDrivesFolder(); + return 0; + } + } + else if (message == WM_SYSCHAR) + { + // For Alt+Enter Beep disabling + UINT scanCode = (UINT)(lParam >> 16) & 0xFF; + UINT virtualKey = MapVirtualKey(scanCode, 1); + if (virtualKey == VK_RETURN || virtualKey == VK_MULTIPLY || + virtualKey == VK_ADD || virtualKey == VK_SUBTRACT) + return 0; + } + /* + else if (message == WM_SYSKEYDOWN) + { + // return 0; + } + */ + else if (message == WM_KEYDOWN) + { + bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0; + bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; + // bool leftCtrl = (::GetKeyState(VK_LCONTROL) & 0x8000) != 0; + // bool RightCtrl = (::GetKeyState(VK_RCONTROL) & 0x8000) != 0; + bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0; + switch(wParam) + { + case VK_RETURN: + { + if (shift && !alt && !ctrl) + { + _panel->OpenSelectedItems(false); + return 0; + } + break; + } + case VK_NEXT: + { + if (ctrl && !alt && !shift) + { + _panel->OpenFocusedItemAsInternal(); + return 0; + } + break; + } + case VK_PRIOR: + if (ctrl && !alt && !shift) + { + _panel->OpenParentFolder(); + return 0; + } + } + } + else if (message == WM_SETFOCUS) + { + _panel->_lastFocusedIsList = true; + _panel->_panelCallback->PanelWasFocused(); + } + #ifndef _UNICODE + if (g_IsNT) + return CallWindowProcW(_origWindowProc, *this, message, wParam, lParam); + else + #endif + return CallWindowProc(_origWindowProc, *this, message, wParam, lParam); +} + +/* +static LRESULT APIENTRY ComboBoxSubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + CWindow tempDialog(hwnd); + CMyComboBox *w = (CMyComboBox *)(tempDialog.GetUserDataLongPtr()); + if (w == NULL) + return 0; + return w->OnMessage(message, wParam, lParam); +} + +LRESULT CMyComboBox::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + return CallWindowProc(_origWindowProc, *this, message, wParam, lParam); +} +*/ +static LRESULT APIENTRY ComboBoxEditSubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + CWindow tempDialog(hwnd); + CMyComboBoxEdit *w = (CMyComboBoxEdit *)(tempDialog.GetUserDataLongPtr()); + if (w == NULL) + return 0; + return w->OnMessage(message, wParam, lParam); +} + +LRESULT CMyComboBoxEdit::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + // See MSDN / Subclassing a Combo Box / Creating a Combo-box Toolbar + switch (message) + { + case WM_SYSKEYDOWN: + switch (wParam) + { + case VK_F1: + case VK_F2: + { + // check ALT + if ((lParam & (1<<29)) == 0) + break; + bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0; + bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; + bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0; + if (alt && !ctrl && !shift) + { + _panel->_panelCallback->SetFocusToPath(wParam == VK_F1 ? 0 : 1); + return 0; + } + break; + } + } + break; + case WM_KEYDOWN: + switch (wParam) + { + case VK_TAB: + // SendMessage(hwndMain, WM_ENTER, 0, 0); + _panel->SetFocusToList(); + return 0; + case VK_F9: + { + bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0; + bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; + bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0; + if (!alt && !ctrl && !shift) + { + g_App.SwitchOnOffOnePanel();; + return 0; + } + break; + } + } + break; + case WM_CHAR: + switch (wParam) + { + case VK_TAB: + case VK_ESCAPE: + return 0; + } + } + #ifndef _UNICODE + if (g_IsNT) + return CallWindowProcW(_origWindowProc, *this, message, wParam, lParam); + else + #endif + return CallWindowProc(_origWindowProc, *this, message, wParam, lParam); +} + +bool CPanel::OnCreate(CREATESTRUCT * /* createStruct */) +{ + // _virtualMode = false; + // _sortIndex = 0; + _sortID = kpidName; + _ascending = true; + _lastFocusedIsList = true; + + DWORD style = WS_CHILD | WS_VISIBLE; // | WS_BORDER ; // | LVS_SHAREIMAGELISTS; // | LVS_SHOWSELALWAYS;; + + style |= LVS_SHAREIMAGELISTS; + // style |= LVS_AUTOARRANGE; + style |= WS_CLIPCHILDREN; + style |= WS_CLIPSIBLINGS; + + const UINT32 kNumListModes = sizeof(kStyles) / sizeof(kStyles[0]); + if (_ListViewMode >= kNumListModes) + _ListViewMode = kNumListModes - 1; + + style |= kStyles[_ListViewMode] + | WS_TABSTOP + | LVS_EDITLABELS; + if (_mySelectMode) + style |= LVS_SINGLESEL; + + /* + if (_virtualMode) + style |= LVS_OWNERDATA; + */ + + DWORD exStyle; + exStyle = WS_EX_CLIENTEDGE; + + if (!_listView.CreateEx(exStyle, style, 0, 0, 116, 260, + HWND(*this), (HMENU)(UINT_PTR)(_baseID + 1), g_hInstance, NULL)) + return false; + + _listView.SetUnicodeFormat(true); + + _listView.SetUserDataLongPtr(LONG_PTR(&_listView)); + _listView._panel = this; + + #ifndef _UNICODE + if(g_IsNT) + _listView._origWindowProc = + (WNDPROC)_listView.SetLongPtrW(GWLP_WNDPROC, LONG_PTR(ListViewSubclassProc)); + else + #endif + _listView._origWindowProc = + (WNDPROC)_listView.SetLongPtr(GWLP_WNDPROC, LONG_PTR(ListViewSubclassProc)); + + SHFILEINFO shellInfo; + HIMAGELIST imageList = (HIMAGELIST)SHGetFileInfo(TEXT(""), + FILE_ATTRIBUTE_NORMAL | + FILE_ATTRIBUTE_DIRECTORY, + &shellInfo, sizeof(shellInfo), + SHGFI_USEFILEATTRIBUTES | + SHGFI_SYSICONINDEX | + SHGFI_SMALLICON + ); + _listView.SetImageList(imageList, LVSIL_SMALL); + imageList = (HIMAGELIST)SHGetFileInfo(TEXT(""), + FILE_ATTRIBUTE_NORMAL | + FILE_ATTRIBUTE_DIRECTORY, + &shellInfo, sizeof(shellInfo), + SHGFI_USEFILEATTRIBUTES | + SHGFI_SYSICONINDEX | + SHGFI_ICON + ); + _listView.SetImageList(imageList, LVSIL_NORMAL); + + // _exStyle |= LVS_EX_HEADERDRAGDROP; + // DWORD extendedStyle = _listView.GetExtendedListViewStyle(); + // extendedStyle |= _exStyle; + // _listView.SetExtendedListViewStyle(extendedStyle); + SetExtendedStyle(); + + _listView.Show(SW_SHOW); + _listView.InvalidateRect(NULL, true); + _listView.Update(); + + // Ensure that the common control DLL is loaded. + INITCOMMONCONTROLSEX icex; + + icex.dwSize = sizeof(INITCOMMONCONTROLSEX); + icex.dwICC = ICC_BAR_CLASSES; + InitCommonControlsEx(&icex); + + TBBUTTON tbb [ ] = + { + // {0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0}, + {VIEW_PARENTFOLDER, kParentFolderID, TBSTATE_ENABLED, BTNS_BUTTON, 0L, 0}, + // {0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0}, + // {VIEW_NEWFOLDER, kCreateFolderID, TBSTATE_ENABLED, BTNS_BUTTON, 0L, 0}, + }; + + if (g_ComCtl32Version >= MAKELONG(71, 4)) + { + icex.dwSize = sizeof(INITCOMMONCONTROLSEX); + icex.dwICC = ICC_COOL_CLASSES | ICC_BAR_CLASSES; + InitCommonControlsEx(&icex); + + _headerReBar.Attach(::CreateWindowEx(WS_EX_TOOLWINDOW, + REBARCLASSNAME, + NULL, WS_VISIBLE | WS_BORDER | WS_CHILD | + WS_CLIPCHILDREN | WS_CLIPSIBLINGS + | CCS_NODIVIDER + | CCS_NOPARENTALIGN + | CCS_TOP + | RBS_VARHEIGHT + | RBS_BANDBORDERS + ,0,0,0,0, HWND(*this), NULL, g_hInstance, NULL)); + } + + DWORD toolbarStyle = WS_CHILD | WS_VISIBLE ; + if (_headerReBar) + { + toolbarStyle |= 0 + // | WS_CLIPCHILDREN + // | WS_CLIPSIBLINGS + + | TBSTYLE_TOOLTIPS + | CCS_NODIVIDER + | CCS_NORESIZE + | TBSTYLE_FLAT + ; + } + + _headerToolBar.Attach(::CreateToolbarEx ((*this), toolbarStyle, + _baseID + 2, 11, + (HINSTANCE)HINST_COMMCTRL, + IDB_VIEW_SMALL_COLOR, + (LPCTBBUTTON)&tbb, sizeof(tbb) / sizeof(tbb[0]), + 0, 0, 0, 0, sizeof (TBBUTTON))); + + icex.dwSize = sizeof(INITCOMMONCONTROLSEX); + icex.dwICC = ICC_USEREX_CLASSES; + InitCommonControlsEx(&icex); + + _headerComboBox.CreateEx(0, WC_COMBOBOXEXW, NULL, + WS_BORDER | WS_VISIBLE |WS_CHILD | CBS_DROPDOWN | CBS_AUTOHSCROLL, + 0, 0, 100, 20, + ((_headerReBar == 0) ? HWND(*this) : _headerToolBar), + (HMENU)(UINT_PTR)(_comboBoxID), + g_hInstance, NULL); + // _headerComboBox.SendMessage(CBEM_SETUNICODEFORMAT, (WPARAM)(BOOL)TRUE, 0); + + + _headerComboBox.SetExtendedStyle(CBES_EX_PATHWORDBREAKPROC, CBES_EX_PATHWORDBREAKPROC); + + /* + _headerComboBox.SetUserDataLongPtr(LONG_PTR(&_headerComboBox)); + _headerComboBox._panel = this; + _headerComboBox._origWindowProc = + (WNDPROC)_headerComboBox.SetLongPtr(GWLP_WNDPROC, + LONG_PTR(ComboBoxSubclassProc)); + */ + _comboBoxEdit.Attach(_headerComboBox.GetEditControl()); + + // _comboBoxEdit.SendMessage(CCM_SETUNICODEFORMAT, (WPARAM)(BOOL)TRUE, 0); + + _comboBoxEdit.SetUserDataLongPtr(LONG_PTR(&_comboBoxEdit)); + _comboBoxEdit._panel = this; + #ifndef _UNICODE + if(g_IsNT) + _comboBoxEdit._origWindowProc = + (WNDPROC)_comboBoxEdit.SetLongPtrW(GWLP_WNDPROC, LONG_PTR(ComboBoxEditSubclassProc)); + else + #endif + _comboBoxEdit._origWindowProc = + (WNDPROC)_comboBoxEdit.SetLongPtr(GWLP_WNDPROC, LONG_PTR(ComboBoxEditSubclassProc)); + + + + if (_headerReBar) + { + REBARINFO rbi; + rbi.cbSize = sizeof(REBARINFO); // Required when using this struct. + rbi.fMask = 0; + rbi.himl = (HIMAGELIST)NULL; + _headerReBar.SetBarInfo(&rbi); + + // Send the TB_BUTTONSTRUCTSIZE message, which is required for + // backward compatibility. + // _headerToolBar.SendMessage(TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0); + SIZE size; + _headerToolBar.GetMaxSize(&size); + + REBARBANDINFO rbBand; + rbBand.cbSize = sizeof(REBARBANDINFO); // Required + rbBand.fMask = RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE; + rbBand.fStyle = RBBS_NOGRIPPER; + rbBand.cxMinChild = size.cx; + rbBand.cyMinChild = size.cy; + rbBand.cyChild = size.cy; + rbBand.cx = size.cx; + rbBand.hwndChild = _headerToolBar; + _headerReBar.InsertBand(-1, &rbBand); + + RECT rc; + ::GetWindowRect(_headerComboBox, &rc); + rbBand.cxMinChild = 30; + rbBand.cyMinChild = rc.bottom - rc.top; + rbBand.cx = 1000; + rbBand.hwndChild = _headerComboBox; + _headerReBar.InsertBand(-1, &rbBand); + // _headerReBar.MaximizeBand(1, false); + } + + _statusBar.Create(WS_CHILD | WS_VISIBLE, L"Status", (*this), _statusBarID); + // _statusBar2.Create(WS_CHILD | WS_VISIBLE, L"Status", (*this), _statusBarID + 1); + + int sizes[] = {150, 200, 250, -1}; + _statusBar.SetParts(4, sizes); + // _statusBar2.SetParts(5, sizes); + + /* + RECT rect; + GetClientRect(&rect); + OnSize(0, rect.right - rect.left, rect.top - rect.bottom); + */ + + SetTimer(kTimerID, kTimerElapse); + + // InitListCtrl(); + RefreshListCtrl(); + RefreshStatusBar(); + + return true; +} + +void CPanel::OnDestroy() +{ + SaveListViewInfo(); + CWindow2::OnDestroy(); +} + +void CPanel::ChangeWindowSize(int xSize, int ySize) +{ + int kHeaderSize; + int kStatusBarSize; + // int kStatusBar2Size; + RECT rect; + if (_headerReBar) + _headerReBar.GetWindowRect(&rect); + else + _headerToolBar.GetWindowRect(&rect); + + kHeaderSize = rect.bottom - rect.top; + + _statusBar.GetWindowRect(&rect); + kStatusBarSize = rect.bottom - rect.top; + + // _statusBar2.GetWindowRect(&rect); + // kStatusBar2Size = rect.bottom - rect.top; + + int yListViewSize = MyMax(ySize - kHeaderSize - kStatusBarSize, 0); + const int kStartXPos = 32; + if (_headerReBar) + { + } + else + { + _headerToolBar.Move(0, 0, xSize, 0); + _headerComboBox.Move(kStartXPos, 2, + MyMax(xSize - kStartXPos - 10, kStartXPos), 0); + } + _listView.Move(0, kHeaderSize, xSize, yListViewSize); + _statusBar.Move(0, kHeaderSize + yListViewSize, xSize, kStatusBarSize); + // _statusBar2.MoveWindow(0, kHeaderSize + yListViewSize + kStatusBarSize, xSize, kStatusBar2Size); + // _statusBar.MoveWindow(0, 100, xSize, kStatusBarSize); + // _statusBar2.MoveWindow(0, 200, xSize, kStatusBar2Size); +} + +bool CPanel::OnSize(WPARAM /* wParam */, int xSize, int ySize) +{ + if (_headerReBar) + _headerReBar.Move(0, 0, xSize, 0); + ChangeWindowSize(xSize, ySize); + return true; +} + +bool CPanel::OnNotifyReBar(LPNMHDR header, LRESULT & /* result */) +{ + switch(header->code) + { + case RBN_HEIGHTCHANGE: + { + RECT rect; + GetWindowRect(&rect); + ChangeWindowSize(rect.right - rect.left, rect.bottom - rect.top); + return false; + } + } + return false; +} + +bool CPanel::OnNotify(UINT /* controlID */, LPNMHDR header, LRESULT &result) +{ + if (!_processNotify) + return false; + if (header->hwndFrom == _headerComboBox) + return OnNotifyComboBox(header, result); + else if (header->hwndFrom == _headerReBar) + return OnNotifyReBar(header, result); + // if (header->hwndFrom == _listView) + else if (header->hwndFrom == _listView) + return OnNotifyList(header, result); + else if (::GetParent(header->hwndFrom) == _listView && + header->code == NM_RCLICK) + return OnRightClick((LPNMITEMACTIVATE)header, result); + return false; +} + +bool CPanel::OnCommand(int code, int itemID, LPARAM lParam, LRESULT &result) +{ + if (itemID == kParentFolderID) + { + OpenParentFolder(); + result = 0; + return true; + } + /* + if (itemID == kCreateFolderID) + { + CreateFolder(); + result = 0; + return true; + } + */ + if (itemID == _comboBoxID) + { + OnComboBoxCommand(code, lParam); + } + return CWindow2::OnCommand(code, itemID, lParam, result); +} + +void CPanel::MessageBoxInfo(LPCWSTR message, LPCWSTR caption) + { ::MessageBoxW(HWND(*this), message, caption, MB_OK); } +void CPanel::MessageBox(LPCWSTR message, LPCWSTR caption) + { ::MessageBoxW(HWND(*this), message, caption, MB_OK | MB_ICONSTOP); } +void CPanel::MessageBox(LPCWSTR message) + { MessageBox(message, L"7-Zip"); } +void CPanel::MessageBoxMyError(LPCWSTR message) + { MessageBox(message, L"Error"); } +void CPanel::MessageBoxError(HRESULT errorCode, LPCWSTR caption) + { MessageBox(NError::MyFormatMessageW(errorCode), caption); } +void CPanel::MessageBoxError(HRESULT errorCode) + { MessageBoxError(errorCode, L"7-Zip"); } +void CPanel::MessageBoxLastError(LPCWSTR caption) + { MessageBoxError(::GetLastError(), caption); } +void CPanel::MessageBoxLastError() + { MessageBoxLastError(L"Error"); } + +void CPanel::SetFocusToList() +{ + _listView.SetFocus(); + // SetCurrentPathText(); +} + +void CPanel::SetFocusToLastRememberedItem() +{ + if (_lastFocusedIsList) + SetFocusToList(); + else + _headerComboBox.SetFocus(); +} + +UString CPanel::GetFolderTypeID() const +{ + CMyComPtr folderGetTypeID; + if(_folder.QueryInterface(IID_IFolderGetTypeID, &folderGetTypeID) != S_OK) + return L""; + CMyComBSTR typeID; + folderGetTypeID->GetTypeID(&typeID); + return (wchar_t *)typeID; +} + +bool CPanel::IsRootFolder() const +{ + return (GetFolderTypeID() == L"RootFolder"); +} + +bool CPanel::IsFSFolder() const +{ + return (GetFolderTypeID() == L"FSFolder"); +} + +bool CPanel::IsFSDrivesFolder() const +{ + return (GetFolderTypeID() == L"FSDrives"); +} + +UString CPanel::GetFsPath() const +{ + if (IsFSDrivesFolder()) + return UString(); + return _currentFolderPrefix; +} + +UString CPanel::GetDriveOrNetworkPrefix() const +{ + if (!IsFSFolder()) + return UString(); + UString drive = GetFsPath(); + if (drive.Length() < 3) + return UString(); + if (drive[0] == L'\\' && drive[1] == L'\\') + { + // if network + int pos = drive.Find(L'\\', 2); + if (pos < 0) + return UString(); + pos = drive.Find(L'\\', pos + 1); + if (pos < 0) + return UString(); + return drive.Left(pos + 1); + } + if (drive[1] != L':' || drive[2] != L'\\') + return UString(); + return drive.Left(3); +} + +bool CPanel::DoesItSupportOperations() const +{ + CMyComPtr folderOperations; + return _folder.QueryInterface(IID_IFolderOperations, &folderOperations) == S_OK; +} + +void CPanel::SetListViewMode(UINT32 index) +{ + if (index >= 4) + return; + _ListViewMode = index; + DWORD oldStyle = (DWORD)_listView.GetStyle(); + DWORD newStyle = kStyles[index]; + if ((oldStyle & LVS_TYPEMASK) != newStyle) + _listView.SetStyle((oldStyle & ~LVS_TYPEMASK) | newStyle); + // RefreshListCtrlSaveFocused(); +} + +void CPanel::ChangeFlatMode() +{ + _flatMode = !_flatMode; + RefreshListCtrlSaveFocused(); +} + + +void CPanel::RefreshStatusBar() +{ + PostMessage(kRefreshStatusBar); +} + +void CPanel::AddToArchive() +{ + CRecordVector indices; + GetOperatedItemIndices(indices); + if (!IsFSFolder()) + { + MessageBox(L"Compress operation is not supported for that folder"); + return; + } + if (indices.Size() == 0) + { + MessageBox(kSelectFiles); + return; + } + UStringVector names; + for (int i = 0; i < indices.Size(); i++) + { + int index = indices[i]; + names.Add(_currentFolderPrefix + GetItemRelPath(index)); + } + const UString archiveName = CreateArchiveName( + names.Front(), (names.Size() > 1), false); + HRESULT res = CompressFiles(_currentFolderPrefix, archiveName, L"", names, false, true, false); + if (res != S_OK) + { + if (_currentFolderPrefix.Length() >= MAX_PATH) + MessageBox(L"Can't call this operation for file with long path"); + else + MessageBoxError(res, L"Error"); + } + // KillSelection(); +} + +static UString GetSubFolderNameForExtract(const UString &archiveName) +{ + int slashPos = archiveName.ReverseFind(L'\\'); + int dotPos = archiveName.ReverseFind(L'.'); + if (dotPos < 0 || slashPos > dotPos) + return archiveName + UString(L"~"); + UString res = archiveName.Left(dotPos); + res.TrimRight(); + return res; +} + +void CPanel::ExtractArchives() +{ + if (_parentFolders.Size() > 0) + { + _panelCallback->OnCopy(false, false); + return; + } + CRecordVector indices; + GetOperatedItemIndices(indices); + UStringVector paths; + if (indices.Size() == 0) + { + MessageBox(kSelectOneFile); + return; + } + for (int i = 0; i < indices.Size(); i++) + { + int index = indices[i]; + if (IsItemFolder(index)) + { + MessageBox(kSelectOneFile); + return; + } + paths.Add(_currentFolderPrefix + GetItemRelPath(index)); + } + UString folderName; + if (indices.Size() == 1) + folderName = GetSubFolderNameForExtract(GetItemRelPath(indices[0])); + else + folderName = L"*"; + ::ExtractArchives(paths, _currentFolderPrefix + folderName + UString(L"\\"), true); +} + +void CPanel::TestArchives() +{ + CRecordVector indices; + GetOperatedItemIndices(indices); + if (!IsFSFolder()) + { + MessageBox(L"Test archive operation is not supported for that folder"); + return; + } + UStringVector paths; + if (indices.Size() == 0) + { + MessageBox(kSelectOneFile); + return; + } + for (int i = 0; i < indices.Size(); i++) + { + int index = indices[i]; + if (IsItemFolder(index)) + { + MessageBox(kSelectOneFile); + return; + } + paths.Add(_currentFolderPrefix + GetItemRelPath(index)); + } + ::TestArchives(paths); +} + diff --git a/CPP/7zip/FileManager/Panel.h b/CPP/7zip/FileManager/Panel.h new file mode 100755 index 00000000..ba0e0884 --- /dev/null +++ b/CPP/7zip/FileManager/Panel.h @@ -0,0 +1,510 @@ +// Panel.h + +#ifndef __PANEL_H +#define __PANEL_H + +#include "Common/MyCom.h" + +#include "Windows/DLL.h" +#include "Windows/FileFind.h" +#include "Windows/FileDir.h" +#include "Windows/Synchronization.h" +#include "Windows/Handle.h" + +#include "Windows/Control/ToolBar.h" +#include "Windows/Control/ReBar.h" +#include "Windows/Control/ListView.h" +#include "Windows/Control/Static.h" +#include "Windows/Control/Edit.h" +#include "Windows/Control/ComboBox.h" +#include "Windows/Control/Window2.h" +#include "Windows/Control/StatusBar.h" + +#include "SysIconUtils.h" +#include "IFolder.h" +#include "ViewSettings.h" +#include "AppState.h" +#include "MyCom2.h" + +const int kParentFolderID = 100; +const int kPluginMenuStartID = 1000; +const int kToolbarStartID = 2000; + +const int kParentIndex = -1; + +class CPanelCallback +{ +public: + virtual void OnTab() = 0; + virtual void SetFocusToPath(int index) = 0; + virtual void OnCopy(bool move, bool copyToSame) = 0; + virtual void OnSetSameFolder() = 0; + virtual void OnSetSubFolder() = 0; + virtual void PanelWasFocused() = 0; + virtual void DragBegin() = 0; + virtual void DragEnd() = 0; +}; + +void PanelCopyItems(); + +struct CItemProperty +{ + UString Name; + PROPID ID; + VARTYPE Type; + int Order; + bool IsVisible; + UInt32 Width; +}; + +inline bool operator<(const CItemProperty &a1, const CItemProperty &a2) + { return (a1.Order < a2.Order); } + +inline bool operator==(const CItemProperty &a1, const CItemProperty &a2) + { return (a1.Order == a2.Order); } + +class CItemProperties: public CObjectVector +{ +public: + int FindItemWithID(PROPID id) + { + for (int i = 0; i < Size(); i++) + if ((*this)[i].ID == id) + return i; + return -1; + } +}; + +struct CTempFileInfo +{ + UString ItemName; + UString FolderPath; + UString FilePath; + NWindows::NFile::NFind::CFileInfoW FileInfo; + void DeleteDirAndFile() + { + NWindows::NFile::NDirectory::DeleteFileAlways(FilePath); + NWindows::NFile::NDirectory::MyRemoveDirectory(FolderPath); + } +}; + +struct CFolderLink: public CTempFileInfo +{ + NWindows::NDLL::CLibrary Library; + CMyComPtr ParentFolder; +}; + +enum MyMessages +{ + kShiftSelectMessage = WM_USER + 1, + kReLoadMessage, + kSetFocusToListView, + kOpenItemChanged, + kRefreshStatusBar +}; + +UString GetFolderPath(IFolderFolder * folder); + +class CPanel; + +class CMyListView: public NWindows::NControl::CListView +{ +public: + WNDPROC _origWindowProc; + CPanel *_panel; + LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); +}; + +/* +class CMyComboBox: public NWindows::NControl::CComboBoxEx +{ +public: + WNDPROC _origWindowProc; + CPanel *_panel; + LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); +}; +*/ +class CMyComboBoxEdit: public NWindows::NControl::CEdit +{ +public: + WNDPROC _origWindowProc; + CPanel *_panel; + LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); +}; + +struct CSelectedState +{ + int FocusedItem; + UString FocusedName; + bool SelectFocused; + UStringVector SelectedNames; + CSelectedState(): FocusedItem(-1), SelectFocused(false) {} +}; + +class CPanel:public NWindows::NControl::CWindow2 +{ + HWND _mainWindow; + + CExtToIconMap _extToIconMap; + UINT _baseID; + int _comboBoxID; + UINT _statusBarID; + + CAppState *_appState; + + bool OnCommand(int code, int itemID, LPARAM lParam, LRESULT &result); + LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); + virtual bool OnCreate(CREATESTRUCT *createStruct); + virtual bool OnSize(WPARAM wParam, int xSize, int ySize); + virtual void OnDestroy(); + virtual bool OnNotify(UINT controlID, LPNMHDR lParam, LRESULT &result); + void OnComboBoxCommand(UINT code, LPARAM &aParam); + bool OnNotifyComboBoxEndEdit(PNMCBEENDEDITW info, LRESULT &result); + #ifndef _UNICODE + bool OnNotifyComboBoxEndEdit(PNMCBEENDEDIT info, LRESULT &result); + #endif + bool OnNotifyReBar(LPNMHDR lParam, LRESULT &result); + bool OnNotifyComboBox(LPNMHDR lParam, LRESULT &result); + void OnItemChanged(NMLISTVIEW *item); + bool OnNotifyList(LPNMHDR lParam, LRESULT &result); + void OnDrag(LPNMLISTVIEW nmListView); + bool OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result); + BOOL OnBeginLabelEdit(LV_DISPINFOW * lpnmh); + BOOL OnEndLabelEdit(LV_DISPINFOW * lpnmh); + void OnColumnClick(LPNMLISTVIEW info); + bool OnCustomDraw(LPNMLVCUSTOMDRAW lplvcd, LRESULT &result); + +public: + CPanelCallback *_panelCallback; + + void DeleteItems(bool toRecycleBin); + void DeleteItemsInternal(CRecordVector &indices); + void CreateFolder(); + void CreateFile(); + +private: + + void ChangeWindowSize(int xSize, int ySize); + + void InitColumns(); + // void InitColumns2(PROPID sortID); + void InsertColumn(int index); + + void SetFocusedSelectedItem(int index, bool select); + void RefreshListCtrl(const UString &focusedName, int focusedPos, bool selectFocused, + const UStringVector &selectedNames); + + void OnShiftSelectMessage(); + void OnArrowWithShift(); + + void OnInsert(); + // void OnUpWithShift(); + // void OnDownWithShift(); +public: + void UpdateSelection(); + void SelectSpec(bool selectMode); + void SelectByType(bool selectMode); + void SelectAll(bool selectMode); + void InvertSelection(); +private: + + // UString GetFileType(UInt32 index); + LRESULT SetItemText(LVITEMW &item); + + // CRecordVector m_ColumnsPropIDs; + +public: + NWindows::NControl::CReBar _headerReBar; + NWindows::NControl::CToolBar _headerToolBar; + NWindows::NControl::CComboBoxEx _headerComboBox; + // CMyComboBox _headerComboBox; + CMyComboBoxEdit _comboBoxEdit; + CMyListView _listView; + NWindows::NControl::CStatusBar _statusBar; + bool _lastFocusedIsList; + // NWindows::NControl::CStatusBar _statusBar2; + + DWORD _exStyle; + bool _showDots; + bool _showRealFileIcons; + // bool _virtualMode; + // CUIntVector _realIndices; + bool _enableItemChangeNotify; + bool _mySelectMode; + CBoolVector _selectedStatusVector; + + CSelectedState _selectedState; + + UInt32 GetRealIndex(const LVITEMW &item) const + { + /* + if (_virtualMode) + return _realIndices[item.iItem]; + */ + return (UInt32)item.lParam; + } + int GetRealItemIndex(int indexInListView) const + { + /* + if (_virtualMode) + return indexInListView; + */ + LPARAM param; + if (!_listView.GetItemParam(indexInListView, param)) + throw 1; + return (int)param; + } + + UInt32 _ListViewMode; + int _xSize; + + bool _flatMode; + + bool _dontShowMode; + + + UString _currentFolderPrefix; + + CObjectVector _parentFolders; + NWindows::NDLL::CLibrary _library; + CMyComPtr _folder; + // CMyComPtr _folderGetSystemIconIndex; + + UStringVector _fastFolders; + + void GetSelectedNames(UStringVector &selectedNames); + void SaveSelectedState(CSelectedState &s); + void RefreshListCtrl(const CSelectedState &s); + void RefreshListCtrlSaveFocused(); + + UString GetItemName(int itemIndex) const; + UString GetItemPrefix(int itemIndex) const; + UString GetItemRelPath(int itemIndex) const; + bool IsItemFolder(int itemIndex) const; + UInt64 GetItemSize(int itemIndex) const; + + //////////////////////// + // PanelFolderChange.cpp + + void SetToRootFolder(); + HRESULT BindToPath(const UString &fullPath, bool &archiveIsOpened, bool &encrypted); // can be prefix + HRESULT BindToPathAndRefresh(const UString &path); + void OpenDrivesFolder(); + + void SetBookmark(int index); + void OpenBookmark(int index); + + void LoadFullPath(); + void LoadFullPathAndShow(); + void FoldersHistory(); + void OpenParentFolder(); + void CloseOpenFolders(); + void OpenRootFolder(); + + + LRESULT Create(HWND mainWindow, HWND parentWindow, + UINT id, + const UString ¤tFolderPrefix, + CPanelCallback *panelCallback, + CAppState *appState, bool &archiveIsOpened, bool &encrypted); + void SetFocusToList(); + void SetFocusToLastRememberedItem(); + + + void ReadListViewInfo(); + void SaveListViewInfo(); + + CPanel() : + // _virtualMode(flase), + _exStyle(0), + _showDots(false), + _showRealFileIcons(false), + _needSaveInfo(false), + _startGroupSelect(0), + _selectionIsDefined(false), + _ListViewMode(3), + _flatMode(false), + _xSize(300), + _mySelectMode(false), + _enableItemChangeNotify(true), + _dontShowMode(false) + {} + + void SetExtendedStyle() + { + if (_listView != 0) + _listView.SetExtendedListViewStyle(_exStyle); + } + + + bool _needSaveInfo; + UString _typeIDString; + CListViewInfo _listViewInfo; + CItemProperties _properties; + CItemProperties _visibleProperties; + + PROPID _sortID; + // int _sortIndex; + bool _ascending; + + void Release(); + ~CPanel(); + void OnLeftClick(LPNMITEMACTIVATE itemActivate); + bool OnRightClick(LPNMITEMACTIVATE itemActivate, LRESULT &result); + + void OnTimer(); + void OnReload(); + bool OnContextMenu(HANDLE windowHandle, int xPos, int yPos); + + CMyComPtr _sevenZipContextMenu; + CMyComPtr _systemContextMenu; + HRESULT CreateShellContextMenu( + const CRecordVector &operatedIndices, + CMyComPtr &systemContextMenu); + void CreateSystemMenu(HMENU menu, + const CRecordVector &operatedIndices, + CMyComPtr &systemContextMenu); + void CreateSevenZipMenu(HMENU menu, + const CRecordVector &operatedIndices, + CMyComPtr &sevenZipContextMenu); + void CreateFileMenu(HMENU menu, + CMyComPtr &sevenZipContextMenu, + CMyComPtr &systemContextMenu, + bool programMenu); + void CreateFileMenu(HMENU menu); + bool InvokePluginCommand(int id); + bool InvokePluginCommand(int id, IContextMenu *sevenZipContextMenu, + IContextMenu *systemContextMenu); + + 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 &indices) const; + void GetOperatedItemIndices(CRecordVector &indices) const; + // void GetOperatedListViewIndices(CRecordVector &indices) const; + void KillSelection(); + + UString GetFolderTypeID() const; + bool IsRootFolder() const; + bool IsFSFolder() const; + bool IsFSDrivesFolder() const; + + UString GetFsPath() const; + UString GetDriveOrNetworkPrefix() const; + + bool DoesItSupportOperations() const; + + bool _processTimer; + bool _processNotify; + + class CDisableTimerProcessing + { + bool _processTimerMem; + bool _processNotifyMem; + + CPanel &_panel; + public: + + CDisableTimerProcessing(CPanel &panel): _panel(panel) + { + Disable(); + } + void Disable() + { + _processTimerMem = _panel._processTimer; + _processNotifyMem = _panel._processNotify; + _panel._processTimer = false; + _panel._processNotify = false; + } + void Restore() + { + _panel._processTimer = _processTimerMem; + _panel._processNotify = _processNotifyMem; + } + ~CDisableTimerProcessing() + { + Restore(); + } + CDisableTimerProcessing& operator=(const CDisableTimerProcessing &) {; } + }; + + // bool _passwordIsDefined; + // UString _password; + + void RefreshListCtrl(); + + void MessageBoxInfo(LPCWSTR message, LPCWSTR caption); + void MessageBox(LPCWSTR message); + void MessageBox(LPCWSTR message, LPCWSTR caption); + void MessageBoxMyError(LPCWSTR message); + void MessageBoxError(HRESULT errorCode, LPCWSTR caption); + void MessageBoxError(HRESULT errorCode); + void MessageBoxLastError(LPCWSTR caption); + void MessageBoxLastError(); + + + void OpenFocusedItemAsInternal(); + void OpenSelectedItems(bool internal); + + void OpenFolderExternal(int index); + + void OpenFolder(int index); + HRESULT OpenParentArchiveFolder(); + HRESULT OpenItemAsArchive(const UString &name, + const UString &folderPath, + const UString &filePath, bool &encrypted); + HRESULT OpenItemAsArchive(const UString &aName); + HRESULT OpenItemAsArchive(int index); + void OpenItemInArchive(int index, bool tryInternal, bool tryExternal, + bool editMode); + HRESULT OnOpenItemChanged(const UString &folderPath, const UString &itemName); + LRESULT OnOpenItemChanged(LPARAM lParam); + + void OpenItem(int index, bool tryInternal, bool tryExternal); + void EditItem(); + void EditItem(int index); + + void RenameFile(); + void ChangeComment(); + + void SetListViewMode(UInt32 index); + UInt32 GetListViewMode() const { return _ListViewMode; }; + + void ChangeFlatMode(); + bool GetFlatMode() const { return _flatMode; }; + + void RefreshStatusBar(); + void OnRefreshStatusBar(); + + void AddToArchive(); + void ExtractArchives(); + void TestArchives(); + + HRESULT CopyTo(const CRecordVector &indices, const UString &folder, + bool moveMode, bool showErrorMessages, UStringVector *messages); + + HRESULT CopyFrom(const UString &folderPrefix, const UStringVector &filePaths, + bool showErrorMessages, UStringVector *messages); + + void CopyFrom(const UStringVector &filePaths); + + // empty folderPath means create new Archive to path of first fileName. + void DropObject(IDataObject * dataObject, const UString &folderPath); + + // empty folderPath means create new Archive to path of first fileName. + void CompressDropFiles(const UStringVector &fileNames, const UString &folderPath); +}; + +#endif diff --git a/CPP/7zip/FileManager/PanelCopy.cpp b/CPP/7zip/FileManager/PanelCopy.cpp new file mode 100755 index 00000000..4b62b878 --- /dev/null +++ b/CPP/7zip/FileManager/PanelCopy.cpp @@ -0,0 +1,208 @@ +// PanelExtract.cpp + +#include "StdAfx.h" + +#include "Windows/COM.h" + +#include "Panel.h" +#include "resource.h" +#include "LangUtils.h" +#include "ExtractCallback.h" +#include "Windows/Thread.h" +//////////////////////////////////////////////////////////////// + +#include "UpdateCallback100.h" + +using namespace NWindows; + +struct CThreadExtractInArchive2 +{ + CMyComPtr FolderOperations; + CRecordVector Indices; + UString DestPath; + CExtractCallbackImp *ExtractCallbackSpec; + CMyComPtr ExtractCallback; + HRESULT Result; + bool MoveMode; + + CThreadExtractInArchive2(): MoveMode(false) {} + + DWORD Extract() + { + // NCOM::CComInitializer comInitializer; + ExtractCallbackSpec->ProgressDialog.WaitCreating(); + if (MoveMode) + Result = FolderOperations->MoveTo(&Indices.Front(), Indices.Size(), + DestPath, ExtractCallback); + else + Result = FolderOperations->CopyTo(&Indices.Front(), Indices.Size(), + DestPath, ExtractCallback); + ExtractCallbackSpec->ProgressDialog.MyClose(); + return 0; + } + + static DWORD WINAPI MyThreadFunction(void *param) + { + return ((CThreadExtractInArchive2 *)param)->Extract(); + } +}; + +HRESULT CPanel::CopyTo(const CRecordVector &indices, const UString &folder, + bool moveMode, bool showErrorMessages, UStringVector *messages) +{ + CMyComPtr folderOperations; + if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) + { + UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208); + if (showErrorMessages) + MessageBox(errorMessage); + else if (messages != 0) + messages->Add(errorMessage); + return E_FAIL; + } + + CThreadExtractInArchive2 extracter; + + extracter.ExtractCallbackSpec = new CExtractCallbackImp; + extracter.ExtractCallback = extracter.ExtractCallbackSpec; + extracter.ExtractCallbackSpec->ParentWindow = GetParent(); + extracter.ExtractCallbackSpec->ShowMessages = showErrorMessages; + + UString title = moveMode ? + LangString(IDS_MOVING, 0x03020206): + LangString(IDS_COPYING, 0x03020205); + UString progressWindowTitle = LangString(IDS_APP_TITLE, 0x03000000); + + extracter.ExtractCallbackSpec->ProgressDialog.MainWindow = GetParent(); + extracter.ExtractCallbackSpec->ProgressDialog.MainTitle = progressWindowTitle; + extracter.ExtractCallbackSpec->ProgressDialog.MainAddTitle = title + L" "; + + extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kAskBefore; + extracter.ExtractCallbackSpec->Init(); + extracter.Indices = indices; + extracter.DestPath = folder; + extracter.FolderOperations = folderOperations; + extracter.MoveMode = moveMode; + + CThread extractThread; + if (!extractThread.Create(CThreadExtractInArchive2::MyThreadFunction, &extracter)) + throw 271824; + extracter.ExtractCallbackSpec->StartProgressDialog(title); + + if (messages != 0) + *messages = extracter.ExtractCallbackSpec->Messages; + return extracter.Result; +} + + +struct CThreadUpdate +{ + CMyComPtr FolderOperations; + UString FolderPrefix; + UStringVector FileNames; + CRecordVector FileNamePointers; + CMyComPtr UpdateCallback; + CUpdateCallback100Imp *UpdateCallbackSpec; + HRESULT Result; + + DWORD Process() + { + NCOM::CComInitializer comInitializer; + UpdateCallbackSpec->ProgressDialog.WaitCreating(); + Result = FolderOperations->CopyFrom( + FolderPrefix, + &FileNamePointers.Front(), + FileNamePointers.Size(), + UpdateCallback); + UpdateCallbackSpec->ProgressDialog.MyClose(); + return 0; + } + + static DWORD WINAPI MyThreadFunction(void *param) + { + return ((CThreadUpdate *)param)->Process(); + } +}; + + +HRESULT CPanel::CopyFrom(const UString &folderPrefix, const UStringVector &filePaths, + bool showErrorMessages, UStringVector *messages) +{ + CMyComPtr folderOperations; + if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) + { + UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208); + if (showErrorMessages) + MessageBox(errorMessage); + else if (messages != 0) + messages->Add(errorMessage); + return E_FAIL; + } + + CThreadUpdate updater; + updater.UpdateCallbackSpec = new CUpdateCallback100Imp; + updater.UpdateCallback = updater.UpdateCallbackSpec; + + UString title = LangString(IDS_COPYING, 0x03020205); + UString progressWindowTitle = LangString(IDS_APP_TITLE, 0x03000000); + + updater.UpdateCallbackSpec->ProgressDialog.MainWindow = GetParent(); + updater.UpdateCallbackSpec->ProgressDialog.MainTitle = progressWindowTitle; + updater.UpdateCallbackSpec->ProgressDialog.MainAddTitle = title + UString(L" "); + + updater.UpdateCallbackSpec->Init((HWND)*this, false, L""); + updater.FolderOperations = folderOperations; + updater.FolderPrefix = folderPrefix; + updater.FileNames.Reserve(filePaths.Size()); + int i; + for(i = 0; i < filePaths.Size(); i++) + updater.FileNames.Add(filePaths[i]); + updater.FileNamePointers.Reserve(updater.FileNames.Size()); + for(i = 0; i < updater.FileNames.Size(); i++) + updater.FileNamePointers.Add(updater.FileNames[i]); + + CThread thread; + if (!thread.Create(CThreadUpdate::MyThreadFunction, &updater)) + throw 271824; + updater.UpdateCallbackSpec->StartProgressDialog(title); + + if (messages != 0) + *messages = updater.UpdateCallbackSpec->Messages; + + return updater.Result; +} + +void CPanel::CopyFrom(const UStringVector &filePaths) +{ + UString title = LangString(IDS_CONFIRM_FILE_COPY, 0x03020222); + UString message = LangString(IDS_WANT_TO_COPY_FILES, 0x03020223); + message += L"\n\'"; + message += _currentFolderPrefix; + message += L"\' ?"; + int res = ::MessageBoxW(*(this), message, title, MB_YESNOCANCEL | MB_ICONQUESTION | MB_SYSTEMMODAL); + if (res != IDYES) + return; + + CDisableTimerProcessing disableTimerProcessing(*this); + + CSelectedState srcSelState; + SaveSelectedState(srcSelState); + + HRESULT result = CopyFrom(L"", filePaths, true, 0); + + if (result != S_OK) + { + disableTimerProcessing.Restore(); + // For Password: + SetFocusToList(); + if (result != E_ABORT) + MessageBoxError(result); + return; + } + + RefreshListCtrl(srcSelState); + + disableTimerProcessing.Restore(); + SetFocusToList(); +} + diff --git a/CPP/7zip/FileManager/PanelCrc.cpp b/CPP/7zip/FileManager/PanelCrc.cpp new file mode 100755 index 00000000..12dcee55 --- /dev/null +++ b/CPP/7zip/FileManager/PanelCrc.cpp @@ -0,0 +1,361 @@ +// PanelSplitFile.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "Common/Alloc.h" +#include "Common/CRC.h" +#include "Common/IntToString.h" +#include "Common/StringConvert.h" + +#include "Windows/FileIO.h" +#include "Windows/FileFind.h" +#include "Windows/FileName.h" +#include "Windows/Thread.h" +#include "Windows/Error.h" + +#include "Resource/ProgressDialog2/ProgressDialog.h" +#include "Resource/OverwriteDialog/resource.h" + +#include "App.h" +#include "FormatUtils.h" +#include "LangUtils.h" + +using namespace NWindows; +using namespace NFile; +using namespace NName; + +static const UInt32 kBufSize = (1 << 15); + +struct CDirEnumerator +{ + bool FlatMode; + UString BasePrefix; + UStringVector FileNames; + + CObjectVector Enumerators; + UStringVector Prefixes; + int Index; + bool GetNextFile(NFind::CFileInfoW &fileInfo, bool &filled, UString &fullPath, DWORD &errorCode); + void Init(); + + CDirEnumerator(): FlatMode(false) {}; +}; + +void CDirEnumerator::Init() +{ + Enumerators.Clear(); + Prefixes.Clear(); + Index = 0; +} + +bool CDirEnumerator::GetNextFile(NFind::CFileInfoW &fileInfo, bool &filled, UString &resPath, DWORD &errorCode) +{ + filled = false; + for (;;) + { + if (Enumerators.IsEmpty()) + { + if (Index >= FileNames.Size()) + return true; + const UString &path = FileNames[Index]; + int pos = path.ReverseFind('\\'); + resPath.Empty(); + if (pos >= 0) + resPath = path.Left(pos + 1); + if (!NFind::FindFile(BasePrefix + path, fileInfo)) + { + errorCode = ::GetLastError(); + resPath = path; + return false; + } + Index++; + break; + } + bool found; + if (!Enumerators.Back().Next(fileInfo, found)) + { + errorCode = ::GetLastError(); + resPath = Prefixes.Back(); + return false; + } + if (found) + { + resPath = Prefixes.Back(); + break; + } + Enumerators.DeleteBack(); + Prefixes.DeleteBack(); + } + resPath += fileInfo.Name; + if (!FlatMode && fileInfo.IsDirectory()) + { + UString prefix = resPath + (UString)(wchar_t)kDirDelimiter; + Enumerators.Add(NFind::CEnumeratorW(BasePrefix + prefix + (UString)(wchar_t)kAnyStringWildcard)); + Prefixes.Add(prefix); + } + filled = true; + return true; +} + +struct CThreadCrc +{ + class CMyBuffer + { + void *_data; + public: + CMyBuffer(): _data(0) {} + operator void *() { return _data; } + bool Allocate(size_t size) + { + if (_data != 0) + return false; + _data = ::MidAlloc(size); + return _data != 0; + } + ~CMyBuffer() { ::MidFree(_data); } + }; + + CProgressDialog *ProgressDialog; + + CDirEnumerator DirEnumerator; + + UInt64 NumFiles; + UInt64 NumFolders; + UInt64 DataSize; + UInt32 DataCrcSum; + UInt32 DataNameCrcSum; + + HRESULT Result; + DWORD ErrorCode; + UString ErrorPath; + UString Error; + bool ThereIsError; + + void Process2() + { + DataSize = NumFolders = NumFiles = DataCrcSum = DataNameCrcSum = 0; + ProgressDialog->WaitCreating(); + + CMyBuffer bufferObject; + if (!bufferObject.Allocate(kBufSize)) + { + Error = L"Can not allocate memory"; + ThereIsError = true; + return; + } + Byte *buffer = (Byte *)(void *)bufferObject; + + UInt64 totalSize = 0; + + DirEnumerator.Init(); + + UString scanningStr = LangString(IDS_SCANNING, 0x03020800); + scanningStr += L" "; + + for (;;) + { + NFile::NFind::CFileInfoW fileInfo; + bool filled; + UString resPath; + if (!DirEnumerator.GetNextFile(fileInfo, filled, resPath, ErrorCode)) + { + ThereIsError = true; + ErrorPath = resPath; + return; + } + if (!filled) + break; + if (!fileInfo.IsDirectory()) + totalSize += fileInfo.Size; + ProgressDialog->ProgressSynch.SetCurrentFileName(scanningStr + resPath); + ProgressDialog->ProgressSynch.SetProgress(totalSize, 0); + Result = ProgressDialog->ProgressSynch.SetPosAndCheckPaused(0); + if (Result != S_OK) + return; + } + + ProgressDialog->ProgressSynch.SetProgress(totalSize, 0); + + DirEnumerator.Init(); + + for (;;) + { + NFile::NFind::CFileInfoW fileInfo; + bool filled; + UString resPath; + if (!DirEnumerator.GetNextFile(fileInfo, filled, resPath, ErrorCode)) + { + ThereIsError = true; + ErrorPath = resPath; + return; + } + if (!filled) + break; + + CCRC crc; + if (fileInfo.IsDirectory()) + NumFolders++; + else + { + NFile::NIO::CInFile inFile; + if (!inFile.Open(DirEnumerator.BasePrefix + resPath)) + { + ErrorCode = ::GetLastError(); + ThereIsError = true; + ErrorPath = resPath; + return; + } + NumFiles++; + ProgressDialog->ProgressSynch.SetCurrentFileName(resPath); + for (;;) + { + UInt32 processedSize; + if (!inFile.Read(buffer, kBufSize, processedSize)) + { + ErrorCode = ::GetLastError(); + ThereIsError = true; + ErrorPath = resPath; + return; + } + if (processedSize == 0) + break; + crc.Update(buffer, processedSize); + DataSize += processedSize; + Result = ProgressDialog->ProgressSynch.SetPosAndCheckPaused(DataSize); + if (Result != S_OK) + return; + } + DataCrcSum += crc.GetDigest(); + } + for (int i = 0; i < resPath.Length(); i++) + { + wchar_t c = resPath[i]; + crc.UpdateByte((Byte)(c & 0xFF)); + crc.UpdateByte((Byte)((c >> 8) & 0xFF)); + } + DataNameCrcSum += crc.GetDigest(); + Result = ProgressDialog->ProgressSynch.SetPosAndCheckPaused(DataSize); + if (Result != S_OK) + return; + } + } + DWORD Process() + { + try { Process2(); } + catch(...) { Error = L"Error"; ThereIsError = true;} + ProgressDialog->MyClose(); + return 0; + } + + static DWORD WINAPI MyThreadFunction(void *param) + { + return ((CThreadCrc *)param)->Process(); + } +}; + +static void ConvertUInt32ToHex(UInt32 value, wchar_t *s) +{ + for (int i = 0; i < 8; i++) + { + int t = value & 0xF; + value >>= 4; + s[7 - i] = (wchar_t)((t < 10) ? (L'0' + t) : (L'A' + (t - 10))); + } + s[8] = L'\0'; +} + +void CApp::CalculateCrc() +{ + int srcPanelIndex = GetFocusedPanelIndex(); + CPanel &srcPanel = Panels[srcPanelIndex]; + if (!srcPanel.IsFSFolder()) + { + srcPanel.MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + CRecordVector indices; + srcPanel.GetOperatedItemIndices(indices); + if (indices.IsEmpty()) + return; + + CThreadCrc combiner; + for (int i = 0; i < indices.Size(); i++) + combiner.DirEnumerator.FileNames.Add(srcPanel.GetItemRelPath(indices[i])); + combiner.DirEnumerator.BasePrefix = srcPanel._currentFolderPrefix; + combiner.DirEnumerator.FlatMode = GetFlatMode(); + + CProgressDialog progressDialog; + combiner.ProgressDialog = &progressDialog; + combiner.ErrorCode = 0; + combiner.Result = S_OK; + combiner.ThereIsError = false; + + UString progressWindowTitle = LangString(IDS_APP_TITLE, 0x03000000); + UString title = LangString(IDS_CHECKSUM_CALCULATING, 0x03020710); + + progressDialog.MainWindow = _window; + progressDialog.MainTitle = progressWindowTitle; + progressDialog.MainAddTitle = title + UString(L" "); + + CThread thread; + if (!thread.Create(CThreadCrc::MyThreadFunction, &combiner)) + throw 271824; + progressDialog.Create(title, _window); + + if (combiner.Result != S_OK) + { + if (combiner.Result != E_ABORT) + srcPanel.MessageBoxError(combiner.Result); + } + else if (combiner.ThereIsError) + { + if (combiner.Error.IsEmpty()) + { + UString message = combiner.DirEnumerator.BasePrefix + combiner.ErrorPath; + message += L"\n"; + message += NError::MyFormatMessageW(combiner.ErrorCode); + srcPanel.MessageBoxMyError(message); + } + else + srcPanel.MessageBoxMyError(combiner.Error); + } + else + { + UString s; + { + wchar_t sz[32]; + + s += LangString(IDS_FILES_COLON, 0x02000320); + s += L" "; + ConvertUInt64ToString(combiner.NumFiles, sz); + s += sz; + s += L"\n"; + + s += LangString(IDS_FOLDERS_COLON, 0x02000321); + s += L" "; + ConvertUInt64ToString(combiner.NumFolders, sz); + s += sz; + s += L"\n"; + + s += LangString(IDS_SIZE_COLON, 0x02000322); + s += L" "; + ConvertUInt64ToString(combiner.DataSize, sz); + s += MyFormatNew(IDS_FILE_SIZE, 0x02000982, sz);; + s += L"\n"; + + s += LangString(IDS_CHECKSUM_CRC_DATA, 0x03020721); + s += L" "; + ConvertUInt32ToHex(combiner.DataCrcSum, sz); + s += sz; + s += L"\n"; + + s += LangString(IDS_CHECKSUM_CRC_DATA_NAMES, 0x03020722); + s += L" "; + ConvertUInt32ToHex(combiner.DataNameCrcSum, sz); + s += sz; + } + srcPanel.MessageBoxInfo(s, LangString(IDS_CHECKSUM_INFORMATION, 0x03020720)); + } +} diff --git a/CPP/7zip/FileManager/PanelDrag.cpp b/CPP/7zip/FileManager/PanelDrag.cpp new file mode 100755 index 00000000..24f1def0 --- /dev/null +++ b/CPP/7zip/FileManager/PanelDrag.cpp @@ -0,0 +1,796 @@ +// PanelDrag.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" + +#include "Windows/Memory.h" +#include "Windows/FileDir.h" +#include "Windows/Shell.h" + +#include "../UI/Common/ArchiveName.h" +#include "../UI/Common/CompressCall.h" + +#include "Resource/MessagesDialog/MessagesDialog.h" + +#include "App.h" +#include "EnumFormatEtc.h" + +using namespace NWindows; + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +static wchar_t *kTempDirPrefix = L"7zE"; +static LPCTSTR kSvenZipSetFolderFormat = TEXT("7-Zip::SetTargetFolder"); + +//////////////////////////////////////////////////////// + +class CDataObject: + public IDataObject, + public CMyUnknownImp +{ +private: + FORMATETC m_Etc; + UINT m_SetFolderFormat; + +public: + MY_UNKNOWN_IMP1_MT(IDataObject) + + STDMETHODIMP GetData(LPFORMATETC pformatetcIn, LPSTGMEDIUM medium); + STDMETHODIMP GetDataHere(LPFORMATETC pformatetc, LPSTGMEDIUM medium); + STDMETHODIMP QueryGetData(LPFORMATETC pformatetc ); + + STDMETHODIMP GetCanonicalFormatEtc ( LPFORMATETC /* pformatetc */, LPFORMATETC pformatetcOut) + { pformatetcOut->ptd = NULL; return ResultFromScode(E_NOTIMPL); } + + STDMETHODIMP SetData(LPFORMATETC etc, STGMEDIUM *medium, BOOL release); + STDMETHODIMP EnumFormatEtc(DWORD drection, LPENUMFORMATETC *enumFormatEtc); + + STDMETHODIMP DAdvise(FORMATETC * /* etc */, DWORD /* advf */, LPADVISESINK /* pAdvSink */, DWORD * /* pdwConnection */) + { return OLE_E_ADVISENOTSUPPORTED; } + STDMETHODIMP DUnadvise(DWORD /* dwConnection */) { return OLE_E_ADVISENOTSUPPORTED; } + STDMETHODIMP EnumDAdvise( LPENUMSTATDATA * /* ppenumAdvise */) { return OLE_E_ADVISENOTSUPPORTED; } + + CDataObject(); + + NMemory::CGlobal hGlobal; + UString Path; +}; + +CDataObject::CDataObject() +{ + m_SetFolderFormat = RegisterClipboardFormat(kSvenZipSetFolderFormat); + m_Etc.cfFormat = CF_HDROP; + m_Etc.ptd = NULL; + m_Etc.dwAspect = DVASPECT_CONTENT; + m_Etc.lindex = -1; + m_Etc.tymed = TYMED_HGLOBAL; +} + +STDMETHODIMP CDataObject::SetData(LPFORMATETC etc, STGMEDIUM *medium, BOOL /* release */) +{ + if (etc->cfFormat == m_SetFolderFormat && etc->tymed == TYMED_HGLOBAL && + etc->dwAspect == DVASPECT_CONTENT && medium->tymed == TYMED_HGLOBAL) + { + Path.Empty(); + if (medium->hGlobal == 0) + return S_OK; + size_t size = GlobalSize(medium->hGlobal) / sizeof(wchar_t); + const wchar_t *src = (const wchar_t *)GlobalLock(medium->hGlobal); + if (src != 0) + { + for (size_t i = 0; i < size; i++) + { + wchar_t c = src[i]; + if (c == 0) + break; + Path += c; + } + GlobalUnlock(medium->hGlobal); + return S_OK; + } + } + return E_NOTIMPL; +} + +static HGLOBAL DuplicateGlobalMem(HGLOBAL srcGlobal) +{ + SIZE_T size = GlobalSize(srcGlobal); + const void *src = GlobalLock(srcGlobal); + if (src == 0) + return 0; + HGLOBAL destGlobal = GlobalAlloc(GHND | GMEM_SHARE, size); + if (destGlobal != 0) + { + void *dest = GlobalLock(destGlobal); + if (dest == 0) + { + GlobalFree(destGlobal); + destGlobal = 0; + } + else + { + memcpy(dest, src, size); + GlobalUnlock(destGlobal); + } + } + GlobalUnlock(srcGlobal); + return destGlobal; +} + +STDMETHODIMP CDataObject::GetData(LPFORMATETC etc, LPSTGMEDIUM medium) +{ + RINOK(QueryGetData(etc)); + medium->tymed = m_Etc.tymed; + medium->pUnkForRelease = 0; + medium->hGlobal = DuplicateGlobalMem(hGlobal); + if (medium->hGlobal == 0) + return E_OUTOFMEMORY; + return S_OK; +} + +STDMETHODIMP CDataObject::GetDataHere(LPFORMATETC /* etc */, LPSTGMEDIUM /* medium */) +{ + // Seems Windows doesn't call it, so we will not implement it. + return E_UNEXPECTED; +} + + +STDMETHODIMP CDataObject::QueryGetData(LPFORMATETC etc) +{ + if ((m_Etc.tymed & etc->tymed) && + m_Etc.cfFormat == etc->cfFormat && + m_Etc.dwAspect == etc->dwAspect) + return S_OK; + return DV_E_FORMATETC; +} + +STDMETHODIMP CDataObject::EnumFormatEtc(DWORD direction, LPENUMFORMATETC FAR* enumFormatEtc) +{ + if(direction != DATADIR_GET) + return E_NOTIMPL; + return CreateEnumFormatEtc(1, &m_Etc, enumFormatEtc); +} + +//////////////////////////////////////////////////////// + +class CDropSource: + public IDropSource, + public CMyUnknownImp +{ + DWORD m_Effect; +public: + MY_UNKNOWN_IMP1_MT(IDropSource) + STDMETHOD(QueryContinueDrag)(BOOL escapePressed, DWORD keyState); + STDMETHOD(GiveFeedback)(DWORD effect); + + + bool NeedExtract; + CPanel *Panel; + CRecordVector Indices; + UString Folder; + CDataObject *DataObjectSpec; + CMyComPtr DataObject; + + bool NeedPostCopy; + HRESULT Result; + UStringVector Messages; + + CDropSource(): NeedPostCopy(false), Panel(0), Result(S_OK), m_Effect(DROPEFFECT_NONE) {} +}; + +STDMETHODIMP CDropSource::QueryContinueDrag(BOOL escapePressed, DWORD keyState) +{ + if(escapePressed == TRUE) + return DRAGDROP_S_CANCEL; + if((keyState & MK_LBUTTON) == 0) + { + if (m_Effect == DROPEFFECT_NONE) + return DRAGDROP_S_CANCEL; + Result = S_OK; + bool needExtract = NeedExtract; + // MoveMode = (((keyState & MK_SHIFT) != 0) && MoveIsAllowed); + if (!DataObjectSpec->Path.IsEmpty()) + { + needExtract = false; + NeedPostCopy = true; + } + if (needExtract) + { + Result = Panel->CopyTo(Indices, Folder, + false, // moveMode, + false, // showMessages + &Messages); + if (Result != S_OK || !Messages.IsEmpty()) + return DRAGDROP_S_CANCEL; + } + return DRAGDROP_S_DROP; + } + return S_OK; +} + +STDMETHODIMP CDropSource::GiveFeedback(DWORD effect) +{ + m_Effect = effect; + return DRAGDROP_S_USEDEFAULTCURSORS; +} + +static bool CopyNamesToHGlobal(NMemory::CGlobal &hgDrop, const UStringVector &names) +{ + size_t totalLength = 1; + + #ifndef _UNICODE + if (!g_IsNT) + { + AStringVector namesA; + int i; + for (i = 0; i < names.Size(); i++) + namesA.Add(GetSystemString(names[i])); + for (i = 0; i < names.Size(); i++) + totalLength += namesA[i].Length() + 1; + + if (!hgDrop.Alloc(GHND | GMEM_SHARE, totalLength * sizeof(CHAR) + sizeof(DROPFILES))) + return false; + + NMemory::CGlobalLock dropLock(hgDrop); + DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer(); + if (dropFiles == 0) + return false; + dropFiles->fNC = FALSE; + dropFiles->pt.x = 0; + dropFiles->pt.y = 0; + dropFiles->pFiles = sizeof(DROPFILES); + dropFiles->fWide = FALSE; + CHAR *p = (CHAR *)((BYTE *)dropFiles + sizeof(DROPFILES)); + for (i = 0; i < names.Size(); i++) + { + const AString &s = namesA[i]; + int fullLength = s.Length() + 1; + MyStringCopy(p, (const char *)s); + p += fullLength; + totalLength -= fullLength; + } + *p = 0; + } + else + #endif + { + int i; + for (i = 0; i < names.Size(); i++) + totalLength += names[i].Length() + 1; + + if (!hgDrop.Alloc(GHND | GMEM_SHARE, totalLength * sizeof(WCHAR) + sizeof(DROPFILES))) + return false; + + NMemory::CGlobalLock dropLock(hgDrop); + DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer(); + if (dropFiles == 0) + return false; + dropFiles->fNC = FALSE; + dropFiles->pt.x = 0; + dropFiles->pt.y = 0; + dropFiles->pFiles = sizeof(DROPFILES); + dropFiles->fWide = TRUE; + WCHAR *p = (WCHAR *)((BYTE *)dropFiles + sizeof(DROPFILES)); + for (i = 0; i < names.Size(); i++) + { + const UString &s = names[i]; + int fullLength = s.Length() + 1; + MyStringCopy(p, (const WCHAR *)s); + p += fullLength; + totalLength -= fullLength; + } + *p = 0; + } + return true; +} + +void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */) +{ + CPanel::CDisableTimerProcessing disableTimerProcessing2(*this); + if (!DoesItSupportOperations()) + return; + CRecordVector indices; + GetOperatedItemIndices(indices); + if (indices.Size() == 0) + return; + + // CSelectedState selState; + // SaveSelectedState(selState); + + UString dirPrefix; + NFile::NDirectory::CTempDirectoryW tempDirectory; + + bool isFSFolder = IsFSFolder(); + if (isFSFolder) + dirPrefix = _currentFolderPrefix; + else + { + tempDirectory.Create(kTempDirPrefix); + dirPrefix = tempDirectory.GetPath(); + NFile::NName::NormalizeDirPathPrefix(dirPrefix); + } + + CDataObject *dataObjectSpec = new CDataObject; + CMyComPtr dataObject = dataObjectSpec; + + { + UStringVector names; + for (int i = 0; i < indices.Size(); i++) + { + UInt32 index = indices[i]; + UString s; + if (isFSFolder) + s = GetItemRelPath(index); + else + s = GetItemName(index); + names.Add(dirPrefix + s); + } + if (!CopyNamesToHGlobal(dataObjectSpec->hGlobal, names)) + return; + } + + CDropSource *dropSourceSpec = new CDropSource; + CMyComPtr dropSource = dropSourceSpec; + dropSourceSpec->NeedExtract = !isFSFolder; + dropSourceSpec->Panel = this; + dropSourceSpec->Indices = indices; + dropSourceSpec->Folder = dirPrefix; + dropSourceSpec->DataObjectSpec = dataObjectSpec; + dropSourceSpec->DataObject = dataObjectSpec; + + bool moveIsAllowed = isFSFolder; + + DWORD effectsOK = DROPEFFECT_COPY; + if (moveIsAllowed) + effectsOK |= DROPEFFECT_MOVE; + DWORD effect; + _panelCallback->DragBegin(); + HRESULT res = DoDragDrop(dataObject, dropSource, effectsOK, &effect); + _panelCallback->DragEnd(); + bool canceled = (res == DRAGDROP_S_CANCEL); + if (res == DRAGDROP_S_DROP) + { + res = dropSourceSpec->Result; + if (dropSourceSpec->NeedPostCopy) + if (!dataObjectSpec->Path.IsEmpty()) + { + NFile::NName::NormalizeDirPathPrefix(dataObjectSpec->Path); + res = CopyTo(indices, dataObjectSpec->Path, + (effect == DROPEFFECT_MOVE),// dropSourceSpec->MoveMode, + false, // showErrorMessages + &dropSourceSpec->Messages); + } + /* + if (effect == DROPEFFECT_MOVE) + RefreshListCtrl(selState); + */ + } + else + { + if (res != DRAGDROP_S_CANCEL && res != S_OK) + MessageBoxError(res); + res = dropSourceSpec->Result; + } + + if (!dropSourceSpec->Messages.IsEmpty()) + { + CMessagesDialog messagesDialog; + messagesDialog.Messages = &dropSourceSpec->Messages; + messagesDialog.Create((*this)); + } + if (res != S_OK && res != E_ABORT) + MessageBoxError(res); + if (res == S_OK && dropSourceSpec->Messages.IsEmpty() && !canceled) + KillSelection(); +} + +void CDropTarget::QueryGetData(IDataObject *dataObject) +{ + FORMATETC etc = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + m_DropIsAllowed = (dataObject->QueryGetData(&etc) == S_OK); + +} + +static void MySetDropHighlighted(HWND hWnd, int index, bool enable) +{ + LVITEM item; + item.mask = LVIF_STATE; + item.iItem = index; + item.iSubItem = 0; + item.state = enable ? LVIS_DROPHILITED : 0; + item.stateMask = LVIS_DROPHILITED; + item.pszText = 0; + ListView_SetItem(hWnd, &item); +} + +void CDropTarget::RemoveSelection() +{ + if (m_SelectionIndex >= 0 && m_Panel != 0) + MySetDropHighlighted(m_Panel->_listView, m_SelectionIndex, false); + m_SelectionIndex = -1; +} + +void CDropTarget::PositionCursor(POINTL ptl) +{ + m_SubFolderIndex = -1; + POINT pt; + pt.x = ptl.x; + pt.y = ptl.y; + + RemoveSelection(); + m_IsAppTarget = true; + m_Panel = NULL; + + m_PanelDropIsAllowed = true; + if (!m_DropIsAllowed) + return; + { + POINT pt2 = pt; + App->_window.ScreenToClient(&pt2); + for (int i = 0; i < kNumPanelsMax; i++) + if (App->IsPanelVisible(i)) + if (App->Panels[i].IsEnabled()) + if (ChildWindowFromPointEx(App->_window, pt2, + CWP_SKIPINVISIBLE | CWP_SKIPDISABLED) == (HWND)App->Panels[i]) + { + m_Panel = &App->Panels[i]; + m_IsAppTarget = false; + if (i == SrcPanelIndex) + { + m_PanelDropIsAllowed = false; + return; + } + break; + } + if (m_IsAppTarget) + { + if (TargetPanelIndex >= 0) + m_Panel = &App->Panels[TargetPanelIndex]; + return; + } + } + + /* + m_PanelDropIsAllowed = m_Panel->DoesItSupportOperations(); + if (!m_PanelDropIsAllowed) + return; + */ + + if (!m_Panel->IsFSFolder() && !m_Panel->IsFSDrivesFolder()) + return; + + if (WindowFromPoint(pt) != (HWND)m_Panel->_listView) + return; + + LVHITTESTINFO info; + m_Panel->_listView.ScreenToClient(&pt); + info.pt = pt; + int index = ListView_HitTest(m_Panel->_listView, &info); + if (index < 0) + return; + int realIndex = m_Panel->GetRealItemIndex(index); + if (realIndex == kParentIndex) + return; + if (!m_Panel->IsItemFolder(realIndex)) + return; + m_SubFolderIndex = realIndex; + m_SubFolderName = m_Panel->GetItemName(m_SubFolderIndex); + MySetDropHighlighted(m_Panel->_listView, index, true); + m_SelectionIndex = index; +} + +bool CDropTarget::IsFsFolderPath() const +{ + if (!m_IsAppTarget && m_Panel != 0) + return (m_Panel->IsFSFolder() || (m_Panel->IsFSDrivesFolder() && m_SelectionIndex >= 0)); + return false; +} + +static void ReadUnicodeStrings(const wchar_t *p, size_t size, UStringVector &names) +{ + names.Clear(); + UString name; + for (;size > 0; size--) + { + wchar_t c = *p++; + if (c == 0) + { + if (name.IsEmpty()) + break; + names.Add(name); + name.Empty(); + } + else + name += c; + } +} + +static void ReadAnsiStrings(const char *p, size_t size, UStringVector &names) +{ + names.Clear(); + AString name; + for (;size > 0; size--) + { + char c = *p++; + if (c == 0) + { + if (name.IsEmpty()) + break; + names.Add(GetUnicodeString(name)); + name.Empty(); + } + else + name += c; + } +} + +static void GetNamesFromDataObject(IDataObject *dataObject, UStringVector &names) +{ + names.Clear(); + FORMATETC etc = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + STGMEDIUM medium; + HRESULT res = dataObject->GetData(&etc, &medium); + if (res != S_OK) + return; + if (medium.tymed != TYMED_HGLOBAL) + return; + { + NMemory::CGlobal global; + global.Attach(medium.hGlobal); + size_t blockSize = GlobalSize(medium.hGlobal); + NMemory::CGlobalLock dropLock(medium.hGlobal); + const DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer(); + if (dropFiles == 0) + return; + if (blockSize < dropFiles->pFiles) + return; + size_t size = blockSize - dropFiles->pFiles; + const void *namesData = (const Byte *)dropFiles + dropFiles->pFiles; + if (dropFiles->fWide) + ReadUnicodeStrings((const wchar_t *)namesData, size / sizeof(wchar_t), names); + else + ReadAnsiStrings((const char *)namesData, size, names); + } +} + +bool CDropTarget::IsItSameDrive() const +{ + if (m_Panel == 0) + return false; + if (!IsFsFolderPath()) + return false; + UString drive; + if (m_Panel->IsFSFolder()) + { + drive = m_Panel->GetDriveOrNetworkPrefix(); + if (drive.IsEmpty()) + return false; + } + else if (m_Panel->IsFSDrivesFolder() && m_SelectionIndex >= 0) + drive = m_SubFolderName + L'\\'; + else + return false; + + if (m_SourcePaths.Size() == 0) + return false; + for (int i = 0; i < m_SourcePaths.Size(); i++) + { + const UString &path = m_SourcePaths[i]; + if (drive.CompareNoCase(path.Left(drive.Length())) != 0) + return false; + } + return true; + +} + +DWORD CDropTarget::GetEffect(DWORD keyState, POINTL /* pt */, DWORD allowedEffect) +{ + if (!m_DropIsAllowed || !m_PanelDropIsAllowed) + return DROPEFFECT_NONE; + + if (!IsFsFolderPath()) + allowedEffect &= ~DROPEFFECT_MOVE; + + if (!m_SetPathIsOK) + allowedEffect &= ~DROPEFFECT_MOVE; + + DWORD effect = 0; + if (keyState & MK_CONTROL) + effect = allowedEffect & DROPEFFECT_COPY; + else if (keyState & MK_SHIFT) + effect = allowedEffect & DROPEFFECT_MOVE; + if(effect == 0) + { + if(allowedEffect & DROPEFFECT_COPY) + effect = DROPEFFECT_COPY; + if(allowedEffect & DROPEFFECT_MOVE) + { + if (IsItSameDrive()) + effect = DROPEFFECT_MOVE; + } + } + if(effect == 0) + return DROPEFFECT_NONE; + return effect; +} + +UString CDropTarget::GetTargetPath() const +{ + if (!IsFsFolderPath()) + return UString(); + UString path = m_Panel->_currentFolderPrefix; + if (m_Panel->IsFSDrivesFolder()) + path.Empty(); + if (m_SubFolderIndex >= 0 && !m_SubFolderName.IsEmpty()) + { + path += m_SubFolderName; + path += L"\\"; + } + return path; +} + +bool CDropTarget::SetPath(bool enablePath) const +{ + UINT setFolderFormat = RegisterClipboardFormat(kSvenZipSetFolderFormat); + + FORMATETC etc = { (CLIPFORMAT)setFolderFormat, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + STGMEDIUM medium; + medium.tymed = etc.tymed; + medium.pUnkForRelease = 0; + UString path; + if (enablePath) + path = GetTargetPath(); + size_t size = path.Length() + 1; + medium.hGlobal = GlobalAlloc(GHND | GMEM_SHARE, size * sizeof(wchar_t)); + if (medium.hGlobal == 0) + return false; + wchar_t *dest = (wchar_t *)GlobalLock(medium.hGlobal); + if (dest == 0) + { + GlobalUnlock(medium.hGlobal); + return false; + } + MyStringCopy(dest, (const wchar_t *)path); + GlobalUnlock(medium.hGlobal); + bool res = m_DataObject->SetData(&etc, &medium, FALSE) == S_OK; + GlobalFree(medium.hGlobal); + return res; +} + +bool CDropTarget::SetPath() +{ + m_SetPathIsOK = SetPath(m_DropIsAllowed && m_PanelDropIsAllowed && IsFsFolderPath()); + return m_SetPathIsOK; +} + +STDMETHODIMP CDropTarget::DragEnter(IDataObject * dataObject, DWORD keyState, + POINTL pt, DWORD *effect) +{ + GetNamesFromDataObject(dataObject, m_SourcePaths); + QueryGetData(dataObject); + m_DataObject = dataObject; + return DragOver(keyState, pt, effect); +} + + +STDMETHODIMP CDropTarget::DragOver(DWORD keyState, POINTL pt, DWORD *effect) +{ + PositionCursor(pt); + SetPath(); + *effect = GetEffect(keyState, pt, *effect); + return S_OK; +} + + +STDMETHODIMP CDropTarget::DragLeave() +{ + RemoveSelection(); + SetPath(false); + m_DataObject.Release(); + return S_OK; +} + +// We suppose that there was ::DragOver for same POINTL_pt before ::Drop +// So SetPath() is same as in Drop. + +STDMETHODIMP CDropTarget::Drop(IDataObject *dataObject, DWORD keyState, + POINTL pt, DWORD * effect) +{ + QueryGetData(dataObject); + PositionCursor(pt); + m_DataObject = dataObject; + bool needDrop = true; + if(m_DropIsAllowed && m_PanelDropIsAllowed) + if (IsFsFolderPath()) + needDrop = !SetPath(); + *effect = GetEffect(keyState, pt, *effect); + if(m_DropIsAllowed && m_PanelDropIsAllowed) + { + if (needDrop) + { + UString path = GetTargetPath(); + if (m_IsAppTarget && m_Panel) + if (m_Panel->IsFSFolder()) + path = m_Panel->_currentFolderPrefix; + m_Panel->DropObject(dataObject, path); + } + } + RemoveSelection(); + m_DataObject.Release(); + return S_OK; +} + +void CPanel::DropObject(IDataObject *dataObject, const UString &folderPath) +{ + UStringVector names; + GetNamesFromDataObject(dataObject, names); + CompressDropFiles(names, folderPath); +} + +/* +void CPanel::CompressDropFiles(HDROP dr) +{ + UStringVector fileNames; + { + NShell::CDrop drop(true); + drop.Attach(dr); + drop.QueryFileNames(fileNames); + } + CompressDropFiles(fileNamesUnicode); +} +*/ + +static bool IsFolderInTemp(const UString &path) +{ + UString tempPath; + if (!NFile::NDirectory::MyGetTempPath(tempPath)) + return false; + if (tempPath.IsEmpty()) + return false; + return (tempPath.CompareNoCase(path.Left(tempPath.Length())) == 0); +} + +static bool AreThereNamesFromTemp(const UStringVector &fileNames) +{ + UString tempPath; + if (!NFile::NDirectory::MyGetTempPath(tempPath)) + return false; + if (tempPath.IsEmpty()) + return false; + for (int i = 0; i < fileNames.Size(); i++) + if (tempPath.CompareNoCase(fileNames[i].Left(tempPath.Length())) == 0) + return true; + return false; +} + +void CPanel::CompressDropFiles(const UStringVector &fileNames, const UString &folderPath) +{ + if (fileNames.Size() == 0) + return; + const UString archiveName = CreateArchiveName(fileNames.Front(), + (fileNames.Size() > 1), false); + bool createNewArchive = true; + if (!IsFSFolder()) + createNewArchive = !DoesItSupportOperations(); + + if (createNewArchive) + { + UString folderPath2 = folderPath; + if (folderPath2.IsEmpty()) + { + NFile::NDirectory::GetOnlyDirPrefix(fileNames.Front(), folderPath2); + if (IsFolderInTemp(folderPath2)) + folderPath2 = L"C:\\"; // fix it + } + CompressFiles(folderPath2, archiveName, L"", fileNames, + false, // email + true, // showDialog + AreThereNamesFromTemp(fileNames) // waitFinish + ); + } + else + CopyFrom(fileNames); +} diff --git a/CPP/7zip/FileManager/PanelFolderChange.cpp b/CPP/7zip/FileManager/PanelFolderChange.cpp new file mode 100755 index 00000000..29841f54 --- /dev/null +++ b/CPP/7zip/FileManager/PanelFolderChange.cpp @@ -0,0 +1,414 @@ +// PanelFolderChange.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Common/Wildcard.h" +#include "Windows/FileDir.h" + +#include "Panel.h" +#include "Resource/ListViewDialog/ListViewDialog.h" +#include "RootFolder.h" +#include "ViewSettings.h" +#include "FSDrives.h" +#include "LangUtils.h" +#include "resource.h" + +using namespace NWindows; +using namespace NFile; +using namespace NFind; + +void CPanel::SetToRootFolder() +{ + _folder.Release(); + _library.Free(); + CRootFolder *rootFolderSpec = new CRootFolder; + _folder = rootFolderSpec; + rootFolderSpec->Init(); +} + +HRESULT CPanel::BindToPath(const UString &fullPath, bool &archiveIsOpened, bool &encrypted) +{ + archiveIsOpened = false; + encrypted = false; + CDisableTimerProcessing disableTimerProcessing1(*this); + CloseOpenFolders(); + UString sysPath = fullPath; + CFileInfoW fileInfo; + UStringVector reducedParts; + while(!sysPath.IsEmpty()) + { + if (FindFile(sysPath, fileInfo)) + break; + int pos = sysPath.ReverseFind(L'\\'); + if (pos < 0) + sysPath.Empty(); + else + { + if (reducedParts.Size() > 0 || pos < sysPath.Length() - 1) + reducedParts.Add(sysPath.Mid(pos + 1)); + sysPath = sysPath.Left(pos); + } + } + SetToRootFolder(); + CMyComPtr newFolder; + if (sysPath.IsEmpty()) + { + if (_folder->BindToFolder(fullPath, &newFolder) == S_OK) + _folder = newFolder; + } + else if (fileInfo.IsDirectory()) + { + NName::NormalizeDirPathPrefix(sysPath); + if (_folder->BindToFolder(sysPath, &newFolder) == S_OK) + _folder = newFolder; + } + else + { + UString dirPrefix; + if (!NDirectory::GetOnlyDirPrefix(sysPath, dirPrefix)) + dirPrefix.Empty(); + if (_folder->BindToFolder(dirPrefix, &newFolder) == S_OK) + { + _folder = newFolder; + LoadFullPath(); + UString fileName; + if (NDirectory::GetOnlyName(sysPath, fileName)) + { + if (OpenItemAsArchive(fileName, _currentFolderPrefix, + _currentFolderPrefix + fileName, encrypted) == S_OK) + { + archiveIsOpened = true; + for (int i = reducedParts.Size() - 1; i >= 0; i--) + { + CMyComPtr newFolder; + _folder->BindToFolder(reducedParts[i], &newFolder); + if (!newFolder) + break; + _folder = newFolder; + } + } + } + } + } + return S_OK; +} + +HRESULT CPanel::BindToPathAndRefresh(const UString &path) +{ + CDisableTimerProcessing disableTimerProcessing1(*this); + bool archiveIsOpened, encrypted; + RINOK(BindToPath(path, archiveIsOpened, encrypted)); + RefreshListCtrl(UString(), -1, true, UStringVector()); + return S_OK; +} + +void CPanel::SetBookmark(int index) +{ + _appState->FastFolders.SetString(index, _currentFolderPrefix); +} + +void CPanel::OpenBookmark(int index) +{ + BindToPathAndRefresh(_appState->FastFolders.GetString(index)); +} + +UString GetFolderPath(IFolderFolder * folder) +{ + CMyComPtr folderGetPath; + if (folder->QueryInterface(IID_IFolderGetPath, (void **)&folderGetPath) == S_OK) + { + CMyComBSTR path; + if (folderGetPath->GetPath(&path) == S_OK) + return (const wchar_t *)path; + } + return UString(); +} + +void CPanel::LoadFullPath() +{ + _currentFolderPrefix.Empty(); + for (int i = 0; i < _parentFolders.Size(); i++) + { + const CFolderLink &folderLink = _parentFolders[i]; + _currentFolderPrefix += GetFolderPath(folderLink.ParentFolder); + _currentFolderPrefix += folderLink.ItemName; + _currentFolderPrefix += L'\\'; + } + if (_folder) + _currentFolderPrefix += GetFolderPath(_folder); +} + +void CPanel::LoadFullPathAndShow() +{ + LoadFullPath(); + _appState->FolderHistory.AddString(_currentFolderPrefix); + + // _headerComboBox.SendMessage(CB_RESETCONTENT, 0, 0); + _headerComboBox.SetText(_currentFolderPrefix); + + /* + for (int i = 0; i < g_Folders.m_Strings.Size(); i++) + { + UString string = g_Folders.m_Strings[i]; + COMBOBOXEXITEM item; + item.mask = CBEIF_TEXT; + item.iItem = i; + item.pszText = (LPTSTR)(LPCTSTR)string; + _headerComboBox.InsertItem(&item); + } + */ +} + +bool CPanel::OnNotifyComboBoxEndEdit(PNMCBEENDEDITW info, LRESULT &result) +{ + if (info->iWhy == CBENF_ESCAPE) + { + _headerComboBox.SetText(_currentFolderPrefix); + PostMessage(kSetFocusToListView); + result = FALSE; + return true; + } + if (info->iWhy == CBENF_DROPDOWN) + { + result = FALSE; + return true; + } + + if (info->iWhy == CBENF_RETURN) + { + UString s; + _headerComboBox.GetText(s); + // length of NMCBEENDEDITW.szText is limited by MAX_PATH + // if (BindToPathAndRefresh(info->szText) != S_OK) + if (BindToPathAndRefresh(s) != S_OK) + { + result = TRUE; + return true; + } + result = FALSE; + PostMessage(kSetFocusToListView); + return true; + } + return false; +} + +#ifndef _UNICODE +bool CPanel::OnNotifyComboBoxEndEdit(PNMCBEENDEDIT info, LRESULT &result) +{ + if (info->iWhy == CBENF_ESCAPE) + { + _headerComboBox.SetText(_currentFolderPrefix); + PostMessage(kSetFocusToListView); + result = FALSE; + return true; + } + if (info->iWhy == CBENF_DROPDOWN) + { + result = FALSE; + return true; + } + + if (info->iWhy == CBENF_RETURN) + { + if (BindToPathAndRefresh(GetUnicodeString(info->szText)) != S_OK) + { + result = TRUE; + return true; + } + result = FALSE; + PostMessage(kSetFocusToListView); + return true; + } + return false; +} +#endif + +void CPanel::OnComboBoxCommand(UINT /* code */, LPARAM & /* param */) +{ + /* + if (code == CBN_SELENDOK) + { + UString path; + if (!_headerComboBox.GetText(path)) + return; + CRootFolder *rootFolderSpec = new CRootFolder; + CMyComPtr rootFolder = rootFolderSpec; + rootFolderSpec->Init(); + CMyComPtr newFolder; + if (rootFolder->BindToFolder(path, &newFolder) != S_OK) + return; + _folder = newFolder; + SetCurrentPathText(); + RefreshListCtrl(UString(), -1, UStringVector()); + PostMessage(kSetFocusToListView); + } + */ +} + +bool CPanel::OnNotifyComboBox(LPNMHDR header, LRESULT &result) +{ + switch(header->code) + { + case CBEN_BEGINEDIT: + { + _lastFocusedIsList = false; + _panelCallback->PanelWasFocused(); + } + #ifndef _UNICODE + case CBEN_ENDEDIT: + { + return OnNotifyComboBoxEndEdit((PNMCBEENDEDIT)header, result); + } + #endif + case CBEN_ENDEDITW: + { + return OnNotifyComboBoxEndEdit((PNMCBEENDEDITW)header, result); + } + } + return false; +} + + +void CPanel::FoldersHistory() +{ + CListViewDialog listViewDialog; + listViewDialog.DeleteIsAllowed = true; + listViewDialog.Title = LangString(IDS_FOLDERS_HISTORY, 0x03020260); + _appState->FolderHistory.GetList(listViewDialog.Strings); + if (listViewDialog.Create(GetParent()) == IDCANCEL) + return; + UString selectString; + if (listViewDialog.StringsWereChanged) + { + _appState->FolderHistory.RemoveAll(); + for (int i = listViewDialog.Strings.Size() - 1; i >= 0; i--) + _appState->FolderHistory.AddString(listViewDialog.Strings[i]); + if (listViewDialog.FocusedItemIndex >= 0) + selectString = listViewDialog.Strings[listViewDialog.FocusedItemIndex]; + } + else + { + if (listViewDialog.FocusedItemIndex >= 0) + selectString = listViewDialog.Strings[listViewDialog.FocusedItemIndex]; + } + if (listViewDialog.FocusedItemIndex >= 0) + BindToPathAndRefresh(selectString); +} + +void CPanel::OpenParentFolder() +{ + LoadFullPath(); // Maybe we don't need it ?? + UString focucedName; + if (!_currentFolderPrefix.IsEmpty()) + { + UString string = _currentFolderPrefix; + string.Delete(string.Length() - 1); + int pos = string.ReverseFind(L'\\'); + if (pos < 0) + pos = 0; + else + pos++; + focucedName = string.Mid(pos); + } + + CDisableTimerProcessing disableTimerProcessing1(*this); + CMyComPtr newFolder; + _folder->BindToParentFolder(&newFolder); + if (newFolder) + _folder = newFolder; + else + { + if (_parentFolders.IsEmpty()) + { + SetToRootFolder(); + if (focucedName.IsEmpty()) + focucedName = GetItemName(0); + } + else + { + _folder.Release(); + _library.Free(); + CFolderLink &link = _parentFolders.Back(); + _folder = link.ParentFolder; + _library.Attach(link.Library.Detach()); + focucedName = link.ItemName; + if (_parentFolders.Size () > 1) + OpenParentArchiveFolder(); + _parentFolders.DeleteBack(); + } + } + + UStringVector selectedItems; + /* + if (!focucedName.IsEmpty()) + selectedItems.Add(focucedName); + */ + LoadFullPath(); + // ::SetCurrentDirectory(::_currentFolderPrefix); + RefreshListCtrl(focucedName, -1, true, selectedItems); + _listView.EnsureVisible(_listView.GetFocusedItem(), false); + RefreshStatusBar(); +} + +void CPanel::CloseOpenFolders() +{ + while(_parentFolders.Size() > 0) + { + _folder.Release(); + _library.Free(); + _folder = _parentFolders.Back().ParentFolder; + _library.Attach(_parentFolders.Back().Library.Detach()); + if (_parentFolders.Size () > 1) + OpenParentArchiveFolder(); + _parentFolders.DeleteBack(); + } + _folder.Release(); + _library.Free(); +} + +void CPanel::OpenRootFolder() +{ + CDisableTimerProcessing disableTimerProcessing1(*this); + _parentFolders.Clear(); + SetToRootFolder(); + RefreshListCtrl(UString(), -1, true, UStringVector()); + // ::SetCurrentDirectory(::_currentFolderPrefix); + /* + BeforeChangeFolder(); + _currentFolderPrefix.Empty(); + AfterChangeFolder(); + SetCurrentPathText(); + RefreshListCtrl(UString(), 0, UStringVector()); + _listView.EnsureVisible(_listView.GetFocusedItem(), false); + */ +} + +void CPanel::OpenDrivesFolder() +{ + CloseOpenFolders(); + CFSDrives *fsFolderSpec = new CFSDrives; + _folder = fsFolderSpec; + fsFolderSpec->Init(); + RefreshListCtrl(); +} + +void CPanel::OpenFolder(int index) +{ + if (index == kParentIndex) + { + OpenParentFolder(); + return; + } + CMyComPtr newFolder; + _folder->BindToFolder(index, &newFolder); + if (!newFolder) + return; + _folder = newFolder; + LoadFullPath(); + // ::SetCurrentDirectory(::_currentFolderPrefix); + RefreshListCtrl(); + UINT state = LVIS_SELECTED; + _listView.SetItemState(_listView.GetFocusedItem(), state, state); + _listView.EnsureVisible(_listView.GetFocusedItem(), false); +} diff --git a/CPP/7zip/FileManager/PanelItemOpen.cpp b/CPP/7zip/FileManager/PanelItemOpen.cpp new file mode 100755 index 00000000..be2d9024 --- /dev/null +++ b/CPP/7zip/FileManager/PanelItemOpen.cpp @@ -0,0 +1,546 @@ +// PanelItemOpen.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "Common/StringConvert.h" +#include "Common/Random.h" +#include "Common/StringConvert.h" +#include "Common/AutoPtr.h" + +#include "Windows/FileDir.h" +#include "Windows/FileFind.h" +#include "Windows/Thread.h" +#include "Windows/Synchronization.h" +#include "Windows/Error.h" +#include "Windows/COM.h" + +#include "ExtractCallback.h" +#include "IFolder.h" +#include "FileFolderPluginOpen.h" +#include "FormatUtils.h" +#include "Panel.h" +#include "RegistryUtils.h" + +using namespace NWindows; +using namespace NSynchronization; +using namespace NFile; +using namespace NDirectory; + +extern HWND g_HWND; +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +static wchar_t *kTempDirPrefix = L"7zO"; + +static const wchar_t *virusMessage = L"File looks like virus (file name has long spaces in name). 7-Zip will not open it"; + +static bool IsNameVirus(const UString &name) +{ + return (name.Find(L" ") >= 0); +} + +struct CTmpProcessInfo: public CTempFileInfo +{ + HANDLE ProcessHandle; + HWND Window; + UString FullPathFolderPrefix; +}; + +class CTmpProcessInfoRelease +{ + CTmpProcessInfo *_tmpProcessInfo; +public: + bool _needDelete; + CTmpProcessInfoRelease(CTmpProcessInfo &tmpProcessInfo): + _tmpProcessInfo(&tmpProcessInfo), _needDelete(true) {} + ~CTmpProcessInfoRelease() + { + if (_needDelete) + _tmpProcessInfo->DeleteDirAndFile(); + } +}; + +HRESULT CPanel::OpenItemAsArchive(const UString &name, + const UString &folderPath, const UString &filePath, bool &encrypted) +{ + encrypted = false; + CFolderLink folderLink; + if (!NFile::NFind::FindFile(filePath, folderLink.FileInfo)) + return E_FAIL; + if (folderLink.FileInfo.IsDirectory()) + return S_FALSE; + + folderLink.FilePath = filePath; + folderLink.FolderPath = folderPath; + + CMyComPtr newFolder; + + // _passwordIsDefined = false; + // _password.Empty(); + + NDLL::CLibrary library; + RINOK(OpenFileFolderPlugin(filePath, &library, &newFolder, GetParent(), encrypted)); + + folderLink.ParentFolder = _folder; + folderLink.ItemName = name; + _parentFolders.Add(folderLink); + _parentFolders.Back().Library.Attach(_library.Detach()); + + _folder.Release(); + _library.Free(); + _folder = newFolder; + _library.Attach(library.Detach()); + + return S_OK; +} + +HRESULT CPanel::OpenItemAsArchive(const UString &name) +{ + bool encrypted; + return OpenItemAsArchive(name, _currentFolderPrefix, _currentFolderPrefix + name, encrypted); +} + +HRESULT CPanel::OpenItemAsArchive(int index) +{ + CDisableTimerProcessing disableTimerProcessing1(*this); + RINOK(OpenItemAsArchive(GetItemRelPath(index))); + RefreshListCtrl(); + return S_OK; +} + +HRESULT CPanel::OpenParentArchiveFolder() +{ + CDisableTimerProcessing disableTimerProcessing1(*this); + if (_parentFolders.Size() < 2) + return S_OK; + CFolderLink &folderLink = _parentFolders.Back(); + NFind::CFileInfoW newFileInfo; + if (NFind::FindFile(folderLink.FilePath, newFileInfo)) + { + if (newFileInfo.Size != folderLink.FileInfo.Size || + CompareFileTime(&newFileInfo.LastWriteTime, + &folderLink.FileInfo.LastWriteTime) != 0) + { + UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, + 0x03020280, folderLink.ItemName); + if (::MessageBoxW(HWND(*this), message, L"7-Zip", MB_OKCANCEL | MB_ICONQUESTION) == IDOK) + { + if (OnOpenItemChanged(folderLink.FolderPath, folderLink.ItemName) != S_OK) + { + ::MessageBoxW(HWND(*this), MyFormatNew(IDS_CANNOT_UPDATE_FILE, + 0x03020281, folderLink.FilePath), L"7-Zip", MB_OK | MB_ICONSTOP); + return S_OK; + } + } + } + } + folderLink.DeleteDirAndFile(); + return S_OK; +} + +static const wchar_t *kStartExtensions[] = +{ + L"exe", + L"bat", + L"com", + L"chm", + L"msi", + L"doc", + L"odt", + L"pdf", + L"xls" +}; + +static bool DoItemAlwaysStart(const UString &name) +{ + int extPos = name.ReverseFind('.'); + if (extPos < 0) + return false; + UString ext = name.Mid(extPos + 1); + ext.MakeLower(); + for (int i = 0; i < sizeof(kStartExtensions) / sizeof(kStartExtensions[0]); i++) + if (ext.Compare(kStartExtensions[i]) == 0) + return true; + return false; +} + +static HANDLE StartEditApplication(const UString &path, HWND window) +{ + UString command; + ReadRegEditor(command); + if (command.IsEmpty()) + { + if (!MyGetWindowsDirectory(command)) + return 0; + NFile::NName::NormalizeDirPathPrefix(command); + command += L"notepad.exe"; + } + command = UString(L"\"") + command + UString(L"\""); + command += L" \""; + command += UString(path); + command += L"\""; + + PROCESS_INFORMATION processInformation; + BOOL result; + #ifndef _UNICODE + if (!g_IsNT) + { + STARTUPINFOA startupInfo; + startupInfo.cb = sizeof(startupInfo); + startupInfo.lpReserved = 0; + startupInfo.lpDesktop = 0; + startupInfo.lpTitle = 0; + startupInfo.dwFlags = 0; + startupInfo.cbReserved2 = 0; + startupInfo.lpReserved2 = 0; + + result = ::CreateProcessA(NULL, (CHAR *)(const CHAR *)GetSystemString(command), + NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation); + } + else + #endif + { + STARTUPINFOW startupInfo; + startupInfo.cb = sizeof(startupInfo); + startupInfo.lpReserved = 0; + startupInfo.lpDesktop = 0; + startupInfo.lpTitle = 0; + startupInfo.dwFlags = 0; + startupInfo.cbReserved2 = 0; + startupInfo.lpReserved2 = 0; + + result = ::CreateProcessW(NULL, (WCHAR *)(const WCHAR *)command, + NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation); + } + + if (result != FALSE) + { + ::CloseHandle(processInformation.hThread); + return processInformation.hProcess; + } + ::MessageBoxW(window, LangString(IDS_CANNOT_START_EDITOR, 0x03020282), + L"7-Zip", MB_OK | MB_ICONSTOP); + return 0; +} + +#ifndef _UNICODE +typedef BOOL (WINAPI * ShellExecuteExWP)(LPSHELLEXECUTEINFOW lpExecInfo); +#endif + +static HANDLE StartApplication(const UString &path, HWND window) +{ + UINT32 result; + HANDLE hProcess; + #ifndef _UNICODE + if (g_IsNT) + { + SHELLEXECUTEINFOW execInfo; + execInfo.cbSize = sizeof(execInfo); + execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT; + execInfo.hwnd = NULL; + execInfo.lpVerb = NULL; + execInfo.lpFile = path; + execInfo.lpParameters = NULL; + execInfo.lpDirectory = NULL; + execInfo.nShow = SW_SHOWNORMAL; + execInfo.hProcess = 0; + ShellExecuteExWP shellExecuteExW = (ShellExecuteExWP) + ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "ShellExecuteExW"); + if (shellExecuteExW == 0) + return 0; + shellExecuteExW(&execInfo); + result = (UINT32)(UINT_PTR)execInfo.hInstApp; + hProcess = execInfo.hProcess; + } + else + #endif + { + SHELLEXECUTEINFO execInfo; + execInfo.cbSize = sizeof(execInfo); + execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT; + execInfo.hwnd = NULL; + execInfo.lpVerb = NULL; + const CSysString sysPath = GetSystemString(path); + execInfo.lpFile = sysPath; + execInfo.lpParameters = NULL; + execInfo.lpDirectory = NULL; + execInfo.nShow = SW_SHOWNORMAL; + execInfo.hProcess = 0; + ::ShellExecuteEx(&execInfo); + result = (UINT32)(UINT_PTR)execInfo.hInstApp; + hProcess = execInfo.hProcess; + } + if(result <= 32) + { + switch(result) + { + case SE_ERR_NOASSOC: + ::MessageBoxW(window, + NError::MyFormatMessageW(::GetLastError()), + // L"There is no application associated with the given file name extension", + L"7-Zip", MB_OK | MB_ICONSTOP); + } + } + return hProcess; +} + +void CPanel::EditItem(int index) +{ + if (!_parentFolders.IsEmpty()) + { + OpenItemInArchive(index, false, true, true); + return; + } + HANDLE hProcess = StartEditApplication(_currentFolderPrefix + GetItemRelPath(index), (HWND)*this); + if (hProcess != 0) + ::CloseHandle(hProcess); +} + +void CPanel::OpenFolderExternal(int index) +{ + HANDLE hProcess = StartApplication(GetFsPath() + GetItemRelPath(index), (HWND)*this); + if (hProcess != 0) + ::CloseHandle(hProcess); +} + +void CPanel::OpenItem(int index, bool tryInternal, bool tryExternal) +{ + CDisableTimerProcessing disableTimerProcessing1(*this); + if (!_parentFolders.IsEmpty()) + { + OpenItemInArchive(index, tryInternal, tryExternal, false); + return; + } + UString name = GetItemRelPath(index); + if (IsNameVirus(name)) + { + MessageBoxMyError(virusMessage); + return; + } + UString fullPath = _currentFolderPrefix + name; + if (tryInternal) + if (!tryExternal || !DoItemAlwaysStart(name)) + if (OpenItemAsArchive(index) == S_OK) + return; + if (tryExternal) + { + NDirectory::MySetCurrentDirectory(_currentFolderPrefix); + HANDLE hProcess = StartApplication(fullPath, (HWND)*this); + if (hProcess != 0) + ::CloseHandle(hProcess); + } +} + +HRESULT CPanel::OnOpenItemChanged(const UString &folderPath, const UString &itemName) +{ + CMyComPtr folderOperations; + if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) + { + MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return E_FAIL; + } + UStringVector fileNames; + CRecordVector fileNamePointers; + fileNames.Add(itemName); + fileNamePointers.Add(fileNames[0]); + + UString pathPrefix = folderPath; + NName::NormalizeDirPathPrefix(pathPrefix); + return folderOperations->CopyFrom(pathPrefix, &fileNamePointers.Front(),fileNamePointers.Size(), NULL); +} + +LRESULT CPanel::OnOpenItemChanged(LPARAM lParam) +{ + CTmpProcessInfo &tmpProcessInfo = *(CTmpProcessInfo *)lParam; + // LoadCurrentPath() + if (tmpProcessInfo.FullPathFolderPrefix != _currentFolderPrefix) + return 0; + + CSelectedState state; + SaveSelectedState(state); + + HRESULT result = OnOpenItemChanged(tmpProcessInfo.FolderPath, tmpProcessInfo.ItemName); + if (result != S_OK) + return 0; + RefreshListCtrl(state); + return 1; +} + +/* +class CTmpProcessInfoList +{ +public: + CObjectVector _items; +} g_TmpProcessInfoList; +*/ + +class CExitEventLauncher +{ +public: + CManualResetEvent _exitEvent; + CExitEventLauncher(): _exitEvent(false) {}; + ~CExitEventLauncher() { _exitEvent.Set(); } +} g_ExitEventLauncher; + +static DWORD WINAPI MyThreadFunction(void *param) +{ + CMyAutoPtr tmpProcessInfoPtr((CTmpProcessInfo *)param); + CTmpProcessInfo *tmpProcessInfo = tmpProcessInfoPtr.get(); + + HANDLE hProcess = tmpProcessInfo->ProcessHandle; + HANDLE events[2] = { g_ExitEventLauncher._exitEvent, hProcess}; + DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); + ::CloseHandle(hProcess); + if (waitResult == WAIT_OBJECT_0 + 0) + return 0; + if (waitResult != WAIT_OBJECT_0 + 1) + return 1; + Sleep(200); + NFind::CFileInfoW newFileInfo; + if (NFind::FindFile(tmpProcessInfo->FilePath, newFileInfo)) + { + if (newFileInfo.Size != tmpProcessInfo->FileInfo.Size || + CompareFileTime(&newFileInfo.LastWriteTime, + &tmpProcessInfo->FileInfo.LastWriteTime) != 0) + { + UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, + 0x03020280, tmpProcessInfo->ItemName); + if (::MessageBoxW(g_HWND, message, L"7-Zip", MB_OKCANCEL | MB_ICONQUESTION) == IDOK) + { + if (SendMessage(tmpProcessInfo->Window, kOpenItemChanged, 0, (LONG_PTR)tmpProcessInfo) != 1) + { + ::MessageBoxW(g_HWND, MyFormatNew(IDS_CANNOT_UPDATE_FILE, + 0x03020281, tmpProcessInfo->FilePath), L"7-Zip", MB_OK | MB_ICONSTOP); + return 0; + } + } + } + } + tmpProcessInfo->DeleteDirAndFile(); + return 0; +} + +void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, + bool editMode) +{ + const UString name = GetItemName(index); + if (IsNameVirus(name)) + { + MessageBoxMyError(virusMessage); + return; + } + + CMyComPtr folderOperations; + if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) + { + MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + + NFile::NDirectory::CTempDirectoryW tempDirectory; + tempDirectory.Create(kTempDirPrefix); + UString tempDir = tempDirectory.GetPath(); + UString tempDirNorm = tempDir; + NFile::NName::NormalizeDirPathPrefix(tempDirNorm); + + CRecordVector indices; + indices.Add(index); + + UStringVector messages; + HRESULT result = CopyTo(indices, tempDirNorm, false, true, &messages); + + if (!messages.IsEmpty()) + return; + if (result != S_OK) + { + if (result != E_ABORT) + MessageBoxError(result); + return; + } + + UString tempFilePath = tempDirNorm + name; + + CMyAutoPtr tmpProcessInfoPtr(new CTmpProcessInfo()); + CTmpProcessInfo *tmpProcessInfo = tmpProcessInfoPtr.get(); + tmpProcessInfo->FolderPath = tempDir; + tmpProcessInfo->FilePath = tempFilePath; + if (!NFind::FindFile(tempFilePath, tmpProcessInfo->FileInfo)) + return; + + if (tryInternal) + { + if (!tryExternal || !DoItemAlwaysStart(name)) + { + bool encrypted; + if (OpenItemAsArchive(name, tempDir, tempFilePath, encrypted) == S_OK) + { + RefreshListCtrl(); + return; + } + } + } + + CTmpProcessInfoRelease tmpProcessInfoRelease(*tmpProcessInfo); + + if (!tryExternal) + return; + + HANDLE hProcess; + if (editMode) + hProcess = StartEditApplication(tempFilePath, (HWND)*this); + else + hProcess = StartApplication(tempFilePath, (HWND)*this); + + if (hProcess == 0) + return; + + tmpProcessInfo->Window = (HWND)(*this); + tmpProcessInfo->FullPathFolderPrefix = _currentFolderPrefix; + tmpProcessInfo->ItemName = name; + tmpProcessInfo->ProcessHandle = hProcess; + + CThread thread; + if (!thread.Create(MyThreadFunction, tmpProcessInfo)) + throw 271824; + tempDirectory.DisableDeleting(); + tmpProcessInfoPtr.release(); + tmpProcessInfoRelease._needDelete = false; +} + +/* +static const UINT64 kTimeLimit = UINT64(10000000) * 3600 * 24; + +static bool CheckDeleteItem(UINT64 currentFileTime, UINT64 folderFileTime) +{ + return (currentFileTime - folderFileTime > kTimeLimit && + folderFileTime - currentFileTime > kTimeLimit); +} + +void DeleteOldTempFiles() +{ + UString tempPath; + if(!NFile::NDirectory::MyGetTempPath(tempPath)) + throw 1; + + SYSTEMTIME systemTime; + ::GetSystemTime(&systemTime); + UINT64 currentFileTime; + if(!::SystemTimeToFileTime(&systemTime, (FILETIME *)¤tFileTime)) + throw 2; + UString searchWildCard = tempPath + kTempDirPrefix + L"*.tmp"; + searchWildCard += WCHAR(NName::kAnyStringWildcard); + NFind::CEnumeratorW enumerator(searchWildCard); + NFind::CFileInfoW fileInfo; + while(enumerator.Next(fileInfo)) + { + if (!fileInfo.IsDirectory()) + continue; + const UINT64 &creationTime = *(const UINT64 *)(&fileInfo.CreationTime); + if(CheckDeleteItem(creationTime, currentFileTime)) + RemoveDirectoryWithSubItems(tempPath + fileInfo.Name); + } +} +*/ diff --git a/CPP/7zip/FileManager/PanelItems.cpp b/CPP/7zip/FileManager/PanelItems.cpp new file mode 100755 index 00000000..16c8d29a --- /dev/null +++ b/CPP/7zip/FileManager/PanelItems.cpp @@ -0,0 +1,822 @@ +// PanelItems.cpp + +#include "StdAfx.h" + +#include "Common/String.h" +#include "Common/StringConvert.h" + +#include "Windows/PropVariant.h" +#include "Windows/PropVariantConversions.h" +#include "Windows/Menu.h" + +#include "../PropID.h" + +#include "Panel.h" +#include "resource.h" + +#include "RootFolder.h" + +#include "PropertyName.h" +#include "LangUtils.h" + +extern "C" +{ + #include "../../../C/Sort.h" +} + +using namespace NWindows; + +static int GetColumnAlign(PROPID propID, VARTYPE varType) +{ + switch(propID) + { + case kpidCreationTime: + case kpidLastAccessTime: + case kpidLastWriteTime: + return LVCFMT_LEFT; + } + switch(varType) + { + case VT_UI1: + case VT_I2: + case VT_UI2: + case VT_I4: + case VT_INT: + case VT_UI4: + case VT_UINT: + case VT_I8: + case VT_UI8: + case VT_BOOL: + return LVCFMT_RIGHT; + + case VT_EMPTY: + case VT_I1: + case VT_FILETIME: + case VT_BSTR: + return LVCFMT_LEFT; + + default: + return LVCFMT_CENTER; + } +} + +void CPanel::InitColumns() +{ + if (_needSaveInfo) + SaveListViewInfo(); + + _listView.DeleteAllItems(); + _selectedStatusVector.Clear(); + + ReadListViewInfo(); + + + PROPID sortID; + /* + if (_listViewInfo.SortIndex >= 0) + sortID = _listViewInfo.Columns[_listViewInfo.SortIndex].PropID; + */ + sortID = _listViewInfo.SortID; + + _ascending = _listViewInfo.Ascending; + + _properties.Clear(); + + CMyComPtr enumProperties; + // CMyComPtr enumSTATPROPSTG; + /* + if (m_ArchiveHandler) + { + if (m_ArchiveHandler->EnumProperties(&enumSTATPROPSTG) != S_OK) + throw 1; + } + else + */ + { + if (_folder.QueryInterface(IID_IEnumProperties, &enumProperties) != S_OK) + throw 1; + /* + if (enumProperties->EnumProperties(&enumSTATPROPSTG)!= S_OK) + throw 1; + */ + } + + _needSaveInfo = true; + + UINT32 numProperties; + enumProperties->GetNumberOfProperties(&numProperties); + int i; + for (i = 0; i < (int)numProperties; i++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE varType; + + if (enumProperties->GetPropertyInfo(i, &name, &propID, &varType) != S_OK) + throw 1; + + CItemProperty destProperty; + destProperty.Type = varType; + destProperty.ID = propID; + if (propID == kpidIsFolder) + continue; + { + if (name != NULL) + destProperty.Name = name; + else + destProperty.Name = L"Error"; + } + UString propName = GetNameOfProperty(propID); + if (!propName.IsEmpty()) + destProperty.Name = propName; + destProperty.Order = -1; + destProperty.IsVisible = true; + destProperty.Width = 100; + _properties.Add(destProperty); + } + // InitColumns2(sortID); + + for (;;) + if (!_listView.DeleteColumn(0)) + break; + + int order = 0; + for(i = 0; i < _listViewInfo.Columns.Size(); i++) + { + const CColumnInfo &columnInfo = _listViewInfo.Columns[i]; + int index = _properties.FindItemWithID(columnInfo.PropID); + if (index >= 0) + { + CItemProperty &item = _properties[index]; + item.IsVisible = columnInfo.IsVisible; + item.Width = columnInfo.Width; + if (columnInfo.IsVisible) + item.Order = order++; + continue; + } + } + for(i = 0; i < _properties.Size(); i++) + { + CItemProperty &item = _properties[i]; + if (item.Order < 0) + item.Order = order++; + } + + _visibleProperties.Clear(); + for (i = 0; i < _properties.Size(); i++) + { + const CItemProperty &property = _properties[i]; + if (property.IsVisible) + _visibleProperties.Add(property); + } + + // _sortIndex = 0; + _sortID = kpidName; + /* + if (_listViewInfo.SortIndex >= 0) + { + int sortIndex = _properties.FindItemWithID(sortID); + if (sortIndex >= 0) + _sortIndex = sortIndex; + } + */ + _sortID = _listViewInfo.SortID; + + for (i = 0; i < _visibleProperties.Size(); i++) + { + InsertColumn(i); + } +} + +void CPanel::InsertColumn(int index) +{ + const CItemProperty &property = _visibleProperties[index]; + LV_COLUMNW column; + column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM | LVCF_ORDER; + column.cx = property.Width; + column.fmt = GetColumnAlign(property.ID, property.Type); + column.iOrder = property.Order; + column.iSubItem = index; + UString propertyName = GetNameOfProperty(property.ID); + if (propertyName.IsEmpty()) + propertyName = property.Name; + column.pszText = (wchar_t *)(const wchar_t *)propertyName; + _listView.InsertColumn(index, &column); +} + +void CPanel::RefreshListCtrl() +{ + RefreshListCtrl(UString(), -1, true, UStringVector()); +} + +int CALLBACK CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData); + + +void CPanel::GetSelectedNames(UStringVector &selectedNames) +{ + selectedNames.Clear(); + + CRecordVector indices; + GetSelectedItemsIndices(indices); + selectedNames.Reserve(indices.Size()); + for (int i = 0; i < indices.Size(); i++) + selectedNames.Add(GetItemRelPath(indices[i])); + + /* + for (int i = 0; i < _listView.GetItemCount(); i++) + { + const int kSize = 1024; + WCHAR name[kSize + 1]; + LVITEMW item; + item.iItem = i; + item.pszText = name; + item.cchTextMax = kSize; + item.iSubItem = 0; + item.mask = LVIF_TEXT | LVIF_PARAM; + if (!_listView.GetItem(&item)) + continue; + int realIndex = GetRealIndex(item); + if (realIndex == kParentIndex) + continue; + if (_selectedStatusVector[realIndex]) + selectedNames.Add(item.pszText); + } + */ + selectedNames.Sort(); +} + +void CPanel::SaveSelectedState(CSelectedState &s) +{ + s.FocusedName.Empty(); + s.SelectedNames.Clear(); + s.FocusedItem = _listView.GetFocusedItem(); + { + if (s.FocusedItem >= 0) + { + int realIndex = GetRealItemIndex(s.FocusedItem); + if (realIndex != kParentIndex) + s.FocusedName = GetItemRelPath(realIndex); + /* + const int kSize = 1024; + WCHAR name[kSize + 1]; + LVITEMW item; + item.iItem = focusedItem; + item.pszText = name; + item.cchTextMax = kSize; + item.iSubItem = 0; + item.mask = LVIF_TEXT; + if (_listView.GetItem(&item)) + focusedName = item.pszText; + */ + } + } + GetSelectedNames(s.SelectedNames); +} + +void CPanel::RefreshListCtrl(const CSelectedState &s) +{ + bool selectFocused = s.SelectFocused; + if (_mySelectMode) + selectFocused = true; + RefreshListCtrl(s.FocusedName, s.FocusedItem, selectFocused, s.SelectedNames); +} + +void CPanel::RefreshListCtrlSaveFocused() +{ + CSelectedState state; + SaveSelectedState(state); + RefreshListCtrl(state); +} + +void CPanel::SetFocusedSelectedItem(int index, bool select) +{ + UINT state = LVIS_FOCUSED; + if (select) + state |= LVIS_SELECTED; + _listView.SetItemState(index, state, state); + if (!_mySelectMode && select) + { + int realIndex = GetRealItemIndex(index); + if (realIndex != kParentIndex) + _selectedStatusVector[realIndex] = true; + } +} + +void CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool selectFocused, + const UStringVector &selectedNames) +{ + _dontShowMode = false; + LoadFullPathAndShow(); + // OutputDebugStringA("=======\n"); + // OutputDebugStringA("s1 \n"); + CDisableTimerProcessing timerProcessing(*this); + + if (focusedPos < 0) + focusedPos = 0; + + _listView.SetRedraw(false); + // m_RedrawEnabled = false; + + LVITEMW item; + ZeroMemory(&item, sizeof(item)); + + _listView.DeleteAllItems(); + _selectedStatusVector.Clear(); + // _realIndices.Clear(); + _startGroupSelect = 0; + + _selectionIsDefined = false; + + // m_Files.Clear(); + // _folder.Release(); + + if (!_folder) + { + // throw 1; + SetToRootFolder(); + } + + _headerToolBar.EnableButton(kParentFolderID, !IsRootFolder()); + + CMyComPtr folderSetFlatMode; + _folder.QueryInterface(IID_IFolderSetFlatMode, &folderSetFlatMode); + if (folderSetFlatMode) + folderSetFlatMode->SetFlatMode(BoolToInt(_flatMode)); + + if (_folder->LoadItems() != S_OK) + return; + + InitColumns(); + + + // OutputDebugString(TEXT("Start Dir\n")); + UINT32 numItems; + _folder->GetNumberOfItems(&numItems); + + bool showDots = _showDots && !IsRootFolder(); + + _listView.SetItemCount(numItems + (showDots ? 1 : 0)); + + _selectedStatusVector.Reserve(numItems); + int cursorIndex = -1; + + CMyComPtr folderGetSystemIconIndex; + if (!IsFSFolder() || _showRealFileIcons) + _folder.QueryInterface(IID_IFolderGetSystemIconIndex, &folderGetSystemIconIndex); + + if (showDots) + { + UString itemName = L".."; + item.iItem = _listView.GetItemCount(); + if (itemName.CompareNoCase(focusedName) == 0) + cursorIndex = item.iItem; + item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; + int subItem = 0; + item.iSubItem = subItem++; + item.lParam = kParentIndex; + item.pszText = (wchar_t *)(const wchar_t *)itemName; + UINT32 attributes = FILE_ATTRIBUTE_DIRECTORY; + item.iImage = _extToIconMap.GetIconIndex(attributes, itemName); + if (item.iImage < 0) + item.iImage = 0; + if(_listView.InsertItem(&item) == -1) + return; + } + + // OutputDebugStringA("S1\n"); + + for(UInt32 i = 0; i < numItems; i++) + { + UString itemName = GetItemName(i); + const UString relPath = GetItemRelPath(i); + if (relPath.CompareNoCase(focusedName) == 0) + cursorIndex = _listView.GetItemCount(); + bool selected = false; + if (selectedNames.FindInSorted(relPath) >= 0) + selected = true; + _selectedStatusVector.Add(selected); + + item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; + + if (!_mySelectMode) + if (selected) + { + item.mask |= LVIF_STATE; + item.state = LVIS_SELECTED; + } + + int subItem = 0; + item.iItem = _listView.GetItemCount(); + + item.iSubItem = subItem++; + item.lParam = i; + + UString correctedName; + if (itemName.Find(L" ") >= 0) + { + int pos = 0; + for (;;) + { + int posNew = itemName.Find(L" ", pos); + if (posNew < 0) + { + correctedName += itemName.Mid(pos); + break; + } + correctedName += itemName.Mid(pos, posNew - pos); + correctedName += L" ... "; + pos = posNew; + while (itemName[++pos] == ' '); + } + item.pszText = (wchar_t *)(const wchar_t *)correctedName; + } + else + item.pszText = (wchar_t *)(const wchar_t *)itemName; + + NCOM::CPropVariant propVariant; + _folder->GetProperty(i, kpidAttributes, &propVariant); + UINT32 attributes = 0; + if (propVariant.vt == VT_UI4) + attributes = propVariant.ulVal; + else + { + if (IsItemFolder(i)) + attributes |= FILE_ATTRIBUTE_DIRECTORY; + } + + bool defined = false; + + if (folderGetSystemIconIndex) + { + folderGetSystemIconIndex->GetSystemIconIndex(i, &item.iImage); + defined = (item.iImage > 0); + } + if (!defined) + { + if (_currentFolderPrefix.IsEmpty()) + { + int iconIndexTemp; + GetRealIconIndex(itemName + L"\\", attributes, iconIndexTemp); + item.iImage = iconIndexTemp; + } + else + { + item.iImage = _extToIconMap.GetIconIndex(attributes, itemName); + } + } + if (item.iImage < 0) + item.iImage = 0; + + if(_listView.InsertItem(&item) == -1) + return; // error + } + // OutputDebugStringA("End2\n"); + + if(_listView.GetItemCount() > 0 && cursorIndex >= 0) + SetFocusedSelectedItem(cursorIndex, selectFocused); + _listView.SortItems(CompareItems, (LPARAM)this); + if (cursorIndex < 0 && _listView.GetItemCount() > 0) + { + if (focusedPos >= _listView.GetItemCount()) + focusedPos = _listView.GetItemCount() - 1; + SetFocusedSelectedItem(focusedPos, true); + } + // m_RedrawEnabled = true; + _listView.EnsureVisible(_listView.GetFocusedItem(), false); + _listView.SetRedraw(true); + _listView.InvalidateRect(NULL, true); + // OutputDebugStringA("End1\n"); + /* + _listView.UpdateWindow(); + */ +} + +void CPanel::GetSelectedItemsIndices(CRecordVector &indices) const +{ + indices.Clear(); + /* + int itemIndex = -1; + while ((itemIndex = _listView.GetNextItem(itemIndex, LVNI_SELECTED)) != -1) + { + LPARAM param; + if (_listView.GetItemParam(itemIndex, param)) + indices.Add(param); + } + */ + for (int i = 0; i < _selectedStatusVector.Size(); i++) + if (_selectedStatusVector[i]) + indices.Add(i); + HeapSort(&indices.Front(), indices.Size()); +} + +void CPanel::GetOperatedItemIndices(CRecordVector &indices) const +{ + GetSelectedItemsIndices(indices); + if (!indices.IsEmpty()) + return; + if (_listView.GetSelectedCount() == 0) + return; + int focusedItem = _listView.GetFocusedItem(); + if (focusedItem >= 0) + { + if(_listView.GetItemState(focusedItem, LVIS_SELECTED) == LVIS_SELECTED) + { + int realIndex = GetRealItemIndex(focusedItem); + if (realIndex != kParentIndex) + indices.Add(realIndex); + } + } +} + +/* +void CPanel::GetOperatedListViewIndices(CRecordVector &indices) const +{ + indices.Clear(); + int numItems = _listView.GetItemCount(); + for (int i = 0; i < numItems; i++) + { + int realIndex = GetRealItemIndex(i); + if (realIndex >= 0) + if (_selectedStatusVector[realIndex]) + indices.Add(i); + } + if (indices.IsEmpty()) + { + int focusedItem = _listView.GetFocusedItem(); + if (focusedItem >= 0) + indices.Add(focusedItem); + } +} +*/ + +void CPanel::EditItem() +{ + int focusedItem = _listView.GetFocusedItem(); + if (focusedItem < 0) + return; + int realIndex = GetRealItemIndex(focusedItem); + if (realIndex == kParentIndex) + return; + if (!IsItemFolder(realIndex)) + EditItem(realIndex); +} + +void CPanel::OpenFocusedItemAsInternal() +{ + int focusedItem = _listView.GetFocusedItem(); + if (focusedItem < 0) + return; + int realIndex = GetRealItemIndex(focusedItem); + if (IsItemFolder(realIndex)) + OpenFolder(realIndex); + else + OpenItem(realIndex, true, false); +} + +void CPanel::OpenSelectedItems(bool tryInternal) +{ + CRecordVector indices; + GetOperatedItemIndices(indices); + if (indices.Size() > 20) + { + MessageBox(LangString(IDS_TOO_MANY_ITEMS, 0x02000606)); + return; + } + + int focusedItem = _listView.GetFocusedItem(); + if (focusedItem >= 0) + { + int realIndex = GetRealItemIndex(focusedItem); + if (realIndex == kParentIndex && (tryInternal || indices.Size() == 0)) + indices.Insert(0, realIndex); + } + + bool dirIsStarted = false; + for(int i = 0; i < indices.Size(); i++) + { + UINT32 index = indices[i]; + // CFileInfo &aFile = m_Files[index]; + if (IsItemFolder(index)) + { + if (!dirIsStarted) + { + if (tryInternal) + { + OpenFolder(index); + dirIsStarted = true; + break; + } + else + OpenFolderExternal(index); + } + } + else + OpenItem(index, (tryInternal && indices.Size() == 1), true); + } +} + +UString CPanel::GetItemName(int itemIndex) const +{ + if (itemIndex == kParentIndex) + return L".."; + NCOM::CPropVariant propVariant; + if (_folder->GetProperty(itemIndex, kpidName, &propVariant) != S_OK) + throw 2723400; + if (propVariant.vt != VT_BSTR) + throw 2723401; + return (propVariant.bstrVal); +} + +UString CPanel::GetItemPrefix(int itemIndex) const +{ + if (itemIndex == kParentIndex) + return UString(); + NCOM::CPropVariant propVariant; + if (_folder->GetProperty(itemIndex, kpidPrefix, &propVariant) != S_OK) + throw 2723400; + UString prefix; + if (propVariant.vt == VT_BSTR) + prefix = propVariant.bstrVal; + return prefix; +} + +UString CPanel::GetItemRelPath(int itemIndex) const +{ + return GetItemPrefix(itemIndex) + GetItemName(itemIndex); +} + + +bool CPanel::IsItemFolder(int itemIndex) const +{ + if (itemIndex == kParentIndex) + return true; + NCOM::CPropVariant propVariant; + if (_folder->GetProperty(itemIndex, kpidIsFolder, &propVariant) != S_OK) + throw 2723400; + if (propVariant.vt == VT_BOOL) + return VARIANT_BOOLToBool(propVariant.boolVal); + if (propVariant.vt == VT_EMPTY) + return false; + return false; +} + +UINT64 CPanel::GetItemSize(int itemIndex) const +{ + if (itemIndex == kParentIndex) + return 0; + NCOM::CPropVariant propVariant; + if (_folder->GetProperty(itemIndex, kpidSize, &propVariant) != S_OK) + throw 2723400; + if (propVariant.vt == VT_EMPTY) + return 0; + return ConvertPropVariantToUInt64(propVariant); +} + +void CPanel::ReadListViewInfo() +{ + CMyComPtr folderGetTypeID; + if(_folder.QueryInterface(IID_IFolderGetTypeID, &folderGetTypeID) != S_OK) + return; + CMyComBSTR typeID; + folderGetTypeID->GetTypeID(&typeID); + _typeIDString = typeID; + ::ReadListViewInfo(_typeIDString, _listViewInfo); +} + +void CPanel::SaveListViewInfo() +{ + int i; + for(i = 0; i < _visibleProperties.Size(); i++) + { + CItemProperty &property = _visibleProperties[i]; + LVCOLUMN winColumnInfo; + winColumnInfo.mask = LVCF_ORDER | LVCF_WIDTH; + if (!_listView.GetColumn(i, &winColumnInfo)) + throw 1; + property.Order = winColumnInfo.iOrder; + property.Width = winColumnInfo.cx; + } + + CListViewInfo viewInfo; + + // PROPID sortPropID = _properties[_sortIndex].ID; + PROPID sortPropID = _sortID; + + _visibleProperties.Sort(); + for(i = 0; i < _visibleProperties.Size(); i++) + { + const CItemProperty &property = _visibleProperties[i]; + CColumnInfo columnInfo; + columnInfo.IsVisible = property.IsVisible; + columnInfo.PropID = property.ID; + columnInfo.Width = property.Width; + viewInfo.Columns.Add(columnInfo); + } + for(i = 0; i < _properties.Size(); i++) + { + const CItemProperty &property = _properties[i]; + if (!property.IsVisible) + { + CColumnInfo columnInfo; + columnInfo.IsVisible = property.IsVisible; + columnInfo.PropID = property.ID; + columnInfo.Width = property.Width; + viewInfo.Columns.Add(columnInfo); + } + } + + // viewInfo.SortIndex = viewInfo.FindColumnWithID(sortPropID); + viewInfo.SortID = sortPropID; + + viewInfo.Ascending = _ascending; + if (!_listViewInfo.IsEqual(viewInfo)) + { + ::SaveListViewInfo(_typeIDString, viewInfo); + _listViewInfo = viewInfo; + } +} + +bool CPanel::OnRightClick(LPNMITEMACTIVATE itemActiveate, LRESULT &result) +{ + if(itemActiveate->hdr.hwndFrom == HWND(_listView)) + return false; + + POINT point; + ::GetCursorPos(&point); + + CMenu menu; + CMenuDestroyer menuDestroyer(menu); + + menu.CreatePopup(); + + const int kCommandStart = 100; + for(int i = 0; i < _properties.Size(); i++) + { + const CItemProperty &property = _properties[i]; + UINT flags = MF_STRING; + if (property.IsVisible) + flags |= MF_CHECKED; + if (i == 0) + flags |= MF_GRAYED; + menu.AppendItem(flags, kCommandStart + i, GetSystemString(property.Name)); + } + int menuResult = menu.Track(TPM_LEFTALIGN | TPM_RETURNCMD | TPM_NONOTIFY, + point.x, point.y, _listView); + if (menuResult >= kCommandStart && menuResult <= kCommandStart + _properties.Size()) + { + int index = menuResult - kCommandStart; + CItemProperty &property = _properties[index]; + property.IsVisible = !property.IsVisible; + + if (property.IsVisible) + { + int prevVisibleSize = _visibleProperties.Size(); + property.Order = prevVisibleSize; + _visibleProperties.Add(property); + InsertColumn(prevVisibleSize); + } + else + { + int visibleIndex = _visibleProperties.FindItemWithID(property.ID); + _visibleProperties.Delete(visibleIndex); + /* + if (_sortIndex == index) + { + _sortIndex = 0; + _ascending = true; + } + */ + if (_sortID == property.ID) + { + _sortID = kpidName; + _ascending = true; + } + + _listView.DeleteColumn(visibleIndex); + } + } + result = TRUE; + return true; +} + +void CPanel::OnReload() +{ + RefreshListCtrlSaveFocused(); + OnRefreshStatusBar(); +} + +void CPanel::OnTimer() +{ + if (!_processTimer) + return; + CMyComPtr folderWasChanged; + if (_folder.QueryInterface(IID_IFolderWasChanged, &folderWasChanged) != S_OK) + return; + INT32 wasChanged; + if (folderWasChanged->WasChanged(&wasChanged) != S_OK) + return; + if (wasChanged == 0) + return; + OnReload(); +} + diff --git a/CPP/7zip/FileManager/PanelKey.cpp b/CPP/7zip/FileManager/PanelKey.cpp new file mode 100755 index 00000000..9c6ddac1 --- /dev/null +++ b/CPP/7zip/FileManager/PanelKey.cpp @@ -0,0 +1,297 @@ +// PanelKey.cpp + +#include "StdAfx.h" + +#include "Panel.h" +#include "HelpUtils.h" + +#include "../PropID.h" +#include "App.h" + +// static LPCWSTR kHelpTopic = L"FM/index.htm"; + +struct CVKeyPropIDPair +{ + WORD VKey; + PROPID PropID; +}; + +static CVKeyPropIDPair g_VKeyPropIDPairs[] = +{ + { VK_F3, kpidName }, + { VK_F4, kpidExtension }, + { VK_F5, kpidLastWriteTime }, + { VK_F6, kpidSize }, + { VK_F7, kpidNoProperty } +}; + +static int FindVKeyPropIDPair(WORD vKey) +{ + for (int i = 0; i < sizeof(g_VKeyPropIDPairs) / sizeof(g_VKeyPropIDPairs[0]); i++) + if (g_VKeyPropIDPairs[i].VKey == vKey) + return i; + return -1; +} + + +bool CPanel::OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result) +{ + if (keyDownInfo->wVKey == VK_TAB && keyDownInfo->hdr.hwndFrom == _listView) + { + _panelCallback->OnTab(); + return false; + } + bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0; + bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; + // bool leftCtrl = (::GetKeyState(VK_LCONTROL) & 0x8000) != 0; + bool rightCtrl = (::GetKeyState(VK_RCONTROL) & 0x8000) != 0; + bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0; + result = 0; + + if (keyDownInfo->wVKey >= '0' && keyDownInfo->wVKey <= '9' && + (rightCtrl || alt)) + { + int index = keyDownInfo->wVKey - '0'; + if (shift) + { + SetBookmark(index); + return true; + } + else + { + OpenBookmark(index); + return true; + } + } + + if ((keyDownInfo->wVKey == VK_F2 || + keyDownInfo->wVKey == VK_F1) && alt && !ctrl && !shift) + { + _panelCallback->SetFocusToPath(keyDownInfo->wVKey == VK_F1 ? 0 : 1); + return true; + } + + if ((keyDownInfo->wVKey == VK_F9) && !alt && !ctrl && !shift) + { + g_App.SwitchOnOffOnePanel(); + } + + if(keyDownInfo->wVKey >= VK_F3 && keyDownInfo->wVKey <= VK_F12 && ctrl) + { + int index = FindVKeyPropIDPair(keyDownInfo->wVKey); + if (index >= 0) + SortItemsWithPropID(g_VKeyPropIDPairs[index].PropID); + } + + switch(keyDownInfo->wVKey) + { + case VK_SHIFT: + { + _selectionIsDefined = false; + _prevFocusedItem = _listView.GetFocusedItem(); + break; + } + /* + case VK_F1: + { + // ShowHelpWindow(NULL, kHelpTopic); + break; + } + */ + case VK_F2: + { + if (!alt && !ctrl &&!shift) + { + RenameFile(); + return true; + } + break; + } + case VK_F4: + { + if (!alt && !ctrl && !shift) + { + EditItem(); + return true; + } + if (!alt && !ctrl && shift) + { + CreateFile(); + return true; + } + break; + } + case VK_F5: + { + if (!alt && !ctrl) + { + _panelCallback->OnCopy(false, shift); + return true; + } + break; + } + case VK_F6: + { + if (!alt && !ctrl) + { + _panelCallback->OnCopy(true, shift); + return true; + } + break; + } + /* + case VK_F7: + { + if (!alt && !ctrl && !shift) + { + CreateFolder(); + return true; + } + break; + } + */ + case VK_DELETE: + { + DeleteItems(!shift); + return true; + } + case VK_INSERT: + { + OnInsert(); + return true; + } + case VK_DOWN: + { + if(shift) + OnArrowWithShift(); + return false; + } + case VK_UP: + { + if (alt) + _panelCallback->OnSetSameFolder(); + else if(shift) + OnArrowWithShift(); + return false; + } + case VK_RIGHT: + { + if (alt) + _panelCallback->OnSetSubFolder(); + else if(shift) + OnArrowWithShift(); + return false; + } + case VK_LEFT: + { + if (alt) + _panelCallback->OnSetSubFolder(); + else if(shift) + OnArrowWithShift(); + return false; + } + case VK_NEXT: + { + if (ctrl && !alt && !shift) + { + // EnterToFocused(); + return true; + } + break; + } + case VK_ADD: + { + if (alt) + SelectByType(true); + else if (shift) + SelectAll(true); + else if(!ctrl) + SelectSpec(true); + return true; + } + case VK_SUBTRACT: + { + if (alt) + SelectByType(false); + else if (shift) + SelectAll(false); + else + SelectSpec(false); + return true; + } + /* + case VK_DELETE: + CommandDelete(); + return 0; + case VK_F1: + CommandHelp(); + return 0; + */ + case VK_BACK: + OpenParentFolder(); + return true; + /* + case VK_DIVIDE: + case '\\': + case '/': + case VK_OEM_5: + { + // OpenRootFolder(); + OpenDrivesFolder(); + + return true; + } + */ + case 'A': + if(ctrl) + { + SelectAll(true); + return true; + } + return false; + case 'N': + if (ctrl) + { + CreateFile(); + return true; + } + return false; + case 'R': + if(ctrl) + { + OnReload(); + return true; + } + return false; + case 'Z': + if(ctrl) + { + ChangeComment(); + return true; + } + return false; + case '1': + case '2': + case '3': + case '4': + if(ctrl) + { + int styleIndex = keyDownInfo->wVKey - '1'; + SetListViewMode(styleIndex); + return true; + } + return false; + case VK_MULTIPLY: + { + InvertSelection(); + return true; + } + case VK_F12: + if (alt && !ctrl && !shift) + { + FoldersHistory(); + return true; + } + } + return false; +} diff --git a/CPP/7zip/FileManager/PanelListNotify.cpp b/CPP/7zip/FileManager/PanelListNotify.cpp new file mode 100755 index 00000000..44bb3e8b --- /dev/null +++ b/CPP/7zip/FileManager/PanelListNotify.cpp @@ -0,0 +1,388 @@ +// PanelListNotify.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "Common/IntToString.h" +#include "Common/StringConvert.h" + +#include "Windows/PropVariant.h" +#include "Windows/PropVariantConversions.h" +#include "Windows/COM.h" + +#include "../UI/Common/PropIDUtils.h" +#include "../PropID.h" + +#include "Panel.h" +#include "FormatUtils.h" + +using namespace NWindows; + +static UString ConvertSizeToString(UINT64 value) +{ + wchar_t s[64]; + if (value < (UINT64(10000) << 0) /*&& ((value & 0x3FF) != 0 || value == 0)*/) + { + ConvertUInt64ToString(value, s); + return UString(s) + L" B"; + } + if (value < (UINT64(10000) << 10)) + { + ConvertUInt64ToString((value >> 10), s); + return UString(s) + L" K"; + } + if (value < (UINT64(10000) << 20)) + { + ConvertUInt64ToString((value >> 20), s); + return UString(s) + L" M"; + } + ConvertUInt64ToString((value >> 30), s); + return UString(s) + L" G"; +} + +LRESULT CPanel::SetItemText(LVITEMW &item) +{ + if (_dontShowMode) + return 0; + + UINT32 realIndex = GetRealIndex(item); + /* + if ((item.mask & LVIF_IMAGE) != 0) + { + bool defined = false; + CComPtr folderGetSystemIconIndex; + _folder.QueryInterface(&folderGetSystemIconIndex); + if (folderGetSystemIconIndex) + { + folderGetSystemIconIndex->GetSystemIconIndex(index, &item.iImage); + defined = (item.iImage > 0); + } + if (!defined) + { + NCOM::CPropVariant propVariant; + _folder->GetProperty(index, kpidAttributes, &propVariant); + UINT32 attributes = 0; + if (propVariant.vt == VT_UI4) + attributes = propVariant.ulVal; + else + { + if (IsItemFolder(index)) + attributes |= FILE_ATTRIBUTE_DIRECTORY; + } + if (_currentFolderPrefix.IsEmpty()) + { + throw 1; + } + else + item.iImage = _extToIconMap.GetIconIndex(attributes, + GetSystemString(GetItemName(index))); + } + // item.iImage = 1; + } + */ + + if ((item.mask & LVIF_TEXT) == 0) + return 0; + + if (realIndex == kParentIndex) + return 0; + UString s; + UINT32 subItemIndex = item.iSubItem; + PROPID propID = _visibleProperties[subItemIndex].ID; + /* + { + NCOM::CPropVariant property; + if(propID == kpidType) + string = GetFileType(index); + else + { + HRESULT result = m_ArchiveFolder->GetProperty(index, propID, &property); + if (result != S_OK) + { + // PrintMessage("GetPropertyValue error"); + return 0; + } + string = ConvertPropertyToString(property, propID, false); + } + } + */ + // const NFind::CFileInfo &aFileInfo = m_Files[index]; + + NCOM::CPropVariant propVariant; + /* + bool needRead = true; + if (propID == kpidSize) + { + CComPtr getItemFullSize; + if (_folder.QueryInterface(&getItemFullSize) == S_OK) + { + if (getItemFullSize->GetItemFullSize(index, &propVariant) == S_OK) + needRead = false; + } + } + if (needRead) + */ + + if (_folder->GetProperty(realIndex, propID, &propVariant) != S_OK) + throw 2723407; + + if ((propID == kpidSize || propID == kpidPackedSize || + propID == kpidTotalSize || propID == kpidFreeSpace || + propID == kpidClusterSize) + && + (propVariant.vt == VT_UI8 || propVariant.vt == VT_UI4)) + s = ConvertSizeToString(ConvertPropVariantToUInt64(propVariant)); + else + s = ConvertPropertyToString(propVariant, propID, false); + + int size = item.cchTextMax; + if(size > 0) + { + if(s.Length() + 1 > size) + s = s.Left(size - 1); + MyStringCopy(item.pszText, (const wchar_t *)s); + } + return 0; +} + +extern DWORD g_ComCtl32Version; + +void CPanel::OnItemChanged(NMLISTVIEW *item) +{ + int index = (int)item->lParam; + if (index == kParentIndex) + return; + bool oldSelected = (item->uOldState & LVIS_SELECTED) != 0; + bool newSelected = (item->uNewState & LVIS_SELECTED) != 0; + // Don't change this code. It works only with such check + if(oldSelected != newSelected) + _selectedStatusVector[index] = newSelected; +} + +bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result) +{ + // bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0; + // bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; + // bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0; + switch(header->code) + { + case LVN_ITEMCHANGED: + { + if (_enableItemChangeNotify) + { + if (!_mySelectMode) + OnItemChanged((LPNMLISTVIEW)header); + RefreshStatusBar(); + } + return false; + } + /* + + case LVN_ODSTATECHANGED: + { + break; + } + */ + + case LVN_GETDISPINFOW: + { + LV_DISPINFOW *dispInfo = (LV_DISPINFOW *)header; + + //is the sub-item information being requested? + + if((dispInfo->item.mask & LVIF_TEXT) != 0 || + (dispInfo->item.mask & LVIF_IMAGE) != 0) + SetItemText(dispInfo->item); + return false; + } + case LVN_KEYDOWN: + { + bool boolResult = OnKeyDown(LPNMLVKEYDOWN(header), result); + RefreshStatusBar(); + return boolResult; + } + + case LVN_COLUMNCLICK: + OnColumnClick(LPNMLISTVIEW(header)); + return false; + /* + case LVN_ITEMACTIVATE: + RefreshStatusBar(); + if (!alt && !ctrl && !shift) + OpenSelectedItems(true); + return false; + */ + + case NM_DBLCLK: + RefreshStatusBar(); + OpenSelectedItems(true); + return false; + case NM_RETURN: + { + bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0; + bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; + // bool leftCtrl = (::GetKeyState(VK_LCONTROL) & 0x8000) != 0; + // bool RightCtrl = (::GetKeyState(VK_RCONTROL) & 0x8000) != 0; + bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0; + if (!shift && alt && !ctrl) + { + Properties(); + return false; + } + OpenSelectedItems(true); + return false; + } + case NM_RCLICK: + RefreshStatusBar(); + break; + + /* + return OnRightClick((LPNMITEMACTIVATE)header, result); + */ + /* + case NM_CLICK: + SendRefreshStatusBarMessage(); + return 0; + + // TODO : Handler default action... + return 0; + case LVN_ITEMCHANGED: + { + NMLISTVIEW *pNMLV = (NMLISTVIEW *) lpnmh; + SelChange(pNMLV); + return TRUE; + } + case NM_SETFOCUS: + return onSetFocus(NULL); + case NM_KILLFOCUS: + return onKillFocus(NULL); + */ + case NM_CLICK: + { + // we need SetFocusToList, if we drag-select items from other panel. + SetFocusToList(); + RefreshStatusBar(); + if(_mySelectMode) + if(g_ComCtl32Version >= MAKELONG(71, 4)) + OnLeftClick((LPNMITEMACTIVATE)header); + return false; + } + case LVN_BEGINLABELEDITW: + result = OnBeginLabelEdit((LV_DISPINFOW *)header); + return true; + case LVN_ENDLABELEDITW: + result = OnEndLabelEdit((LV_DISPINFOW *)header); + return true; + + case NM_CUSTOMDRAW: + { + if (_mySelectMode) + return OnCustomDraw((LPNMLVCUSTOMDRAW)header, result); + break; + } + case LVN_BEGINDRAG: + { + OnDrag((LPNMLISTVIEW)header); + RefreshStatusBar(); + break; + } + // case LVN_BEGINRDRAG: + } + return false; +} + +bool CPanel::OnCustomDraw(LPNMLVCUSTOMDRAW lplvcd, LRESULT &result) +{ + switch(lplvcd->nmcd.dwDrawStage) + { + case CDDS_PREPAINT : + result = CDRF_NOTIFYITEMDRAW; + return true; + + case CDDS_ITEMPREPAINT: + /* + SelectObject(lplvcd->nmcd.hdc, + GetFontForItem(lplvcd->nmcd.dwItemSpec, + lplvcd->nmcd.lItemlParam) ); + lplvcd->clrText = GetColorForItem(lplvcd->nmcd.dwItemSpec, + lplvcd->nmcd.lItemlParam); + lplvcd->clrTextBk = GetBkColorForItem(lplvcd->nmcd.dwItemSpec, + lplvcd->nmcd.lItemlParam); + */ + int realIndex = (int)lplvcd->nmcd.lItemlParam; + bool selected = false; + if (realIndex != kParentIndex) + selected = _selectedStatusVector[realIndex]; + if (selected) + lplvcd->clrTextBk = RGB(255, 192, 192); + // lplvcd->clrText = RGB(255, 0, 128); + else + lplvcd->clrTextBk = _listView.GetBkColor(); + // lplvcd->clrText = RGB(0, 0, 0); + // result = CDRF_NEWFONT; + result = CDRF_NOTIFYITEMDRAW; + return true; + + // return false; + // return true; + /* + case CDDS_SUBITEM | CDDS_ITEMPREPAINT: + if (lplvcd->iSubItem == 0) + { + // lplvcd->clrText = RGB(255, 0, 0); + lplvcd->clrTextBk = RGB(192, 192, 192); + } + else + { + lplvcd->clrText = RGB(0, 0, 0); + lplvcd->clrTextBk = RGB(255, 255, 255); + } + return true; + */ + + /* At this point, you can change the background colors for the item + and any subitems and return CDRF_NEWFONT. If the list-view control + is in report mode, you can simply return CDRF_NOTIFYSUBITEMREDRAW + to customize the item's subitems individually */ + } + return false; +} + +void CPanel::OnRefreshStatusBar() +{ + CRecordVector indices; + GetOperatedItemIndices(indices); + + _statusBar.SetText(0, MyFormatNew(IDS_N_SELECTED_ITEMS, 0x02000301, NumberToString(indices.Size()))); + + UString selectSizeString; + + if (indices.Size() > 0) + { + UINT64 totalSize = 0; + for (int i = 0; i < indices.Size(); i++) + totalSize += GetItemSize(indices[i]); + selectSizeString = ConvertSizeToString(totalSize); + } + _statusBar.SetText(1, selectSizeString); + + int focusedItem = _listView.GetFocusedItem(); + UString sizeString; + UString dateString; + if (focusedItem >= 0 && _listView.GetSelectedCount() > 0) + { + int realIndex = GetRealItemIndex(focusedItem); + if (realIndex != kParentIndex) + { + sizeString = ConvertSizeToString(GetItemSize(realIndex)); + NCOM::CPropVariant propVariant; + if (_folder->GetProperty(realIndex, kpidLastWriteTime, &propVariant) == S_OK) + dateString = ConvertPropertyToString(propVariant, kpidLastWriteTime, false); + } + } + _statusBar.SetText(2, sizeString); + _statusBar.SetText(3, dateString); + // _statusBar.SetText(4, nameString); + // _statusBar2.SetText(1, MyFormatNew(L"{0} bytes", NumberToStringW(totalSize))); +} diff --git a/CPP/7zip/FileManager/PanelMenu.cpp b/CPP/7zip/FileManager/PanelMenu.cpp new file mode 100755 index 00000000..64db53ee --- /dev/null +++ b/CPP/7zip/FileManager/PanelMenu.cpp @@ -0,0 +1,422 @@ +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Windows/Menu.h" +#include "Windows/COM.h" + +#include "Panel.h" +#include "PluginInterface.h" +#include "MyLoadMenu.h" +#include "App.h" +#include "LangUtils.h" +#include "resource.h" + +using namespace NWindows; + +// {23170F69-40C1-278A-1000-000100020000} +DEFINE_GUID(CLSID_CZipContextMenu, +0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00); + +static const UINT kSevenZipStartMenuID = kPluginMenuStartID ; +static const UINT kSystemStartMenuID = kPluginMenuStartID + 100; + +void CPanel::InvokeSystemCommand(const char *command) +{ + if (!IsFSFolder() && !IsFSDrivesFolder()) + return; + CRecordVector operatedIndices; + GetOperatedItemIndices(operatedIndices); + if (operatedIndices.IsEmpty()) + return; + CMyComPtr contextMenu; + if (CreateShellContextMenu(operatedIndices, contextMenu) != S_OK) + return; + + CMINVOKECOMMANDINFO ci; + ZeroMemory(&ci, sizeof(ci)); + ci.cbSize = sizeof(CMINVOKECOMMANDINFO); + ci.hwnd = GetParent(); + ci.lpVerb = command; + contextMenu->InvokeCommand(&ci); +} + +void CPanel::Properties() +{ + InvokeSystemCommand("properties"); +} + +// Copy and paste do not work, if you know why write me. + +void CPanel::EditCopy() +{ + NCOM::CComInitializer comInitializer; + InvokeSystemCommand("copy"); +} + +void CPanel::EditPaste() +{ + NCOM::CComInitializer comInitializer; + InvokeSystemCommand("paste"); +} + +HRESULT CPanel::CreateShellContextMenu( + const CRecordVector &operatedIndices, + CMyComPtr &systemContextMenu) +{ + systemContextMenu.Release(); + UString folderPath = GetFsPath(); + + CMyComPtr desktopFolder; + RINOK(::SHGetDesktopFolder(&desktopFolder)); + if (!desktopFolder) + { + // ShowMessage("Failed to get Desktop folder."); + return E_FAIL; + } + + // Separate the file from the folder. + + + // Get a pidl for the folder the file + // is located in. + LPITEMIDLIST parentPidl; + DWORD eaten; + RINOK(desktopFolder->ParseDisplayName( + GetParent(), 0, (wchar_t *)(const wchar_t *)folderPath, + &eaten, &parentPidl, 0)); + + // Get an IShellFolder for the folder + // the file is located in. + CMyComPtr parentFolder; + RINOK(desktopFolder->BindToObject(parentPidl, + 0, IID_IShellFolder, (void**)&parentFolder)); + if (!parentFolder) + { + // ShowMessage("Invalid file name."); + return E_FAIL; + } + + // Get a pidl for the file itself. + CRecordVector pidls; + pidls.Reserve(operatedIndices.Size()); + for (int i = 0; i < operatedIndices.Size(); i++) + { + LPITEMIDLIST pidl; + UString fileName = GetItemRelPath(operatedIndices[i]); + if (IsFSDrivesFolder()) + fileName += L'\\'; + RINOK(parentFolder->ParseDisplayName(GetParent(), 0, + (wchar_t *)(const wchar_t *)fileName, &eaten, &pidl, 0)); + pidls.Add(pidl); + } + + ITEMIDLIST temp; + if (pidls.Size() == 0) + { + temp.mkid.cb = 0; + /* + LPITEMIDLIST pidl; + HRESULT result = parentFolder->ParseDisplayName(GetParent(), 0, + L".\\", &eaten, &pidl, 0); + if (result != NOERROR) + return; + */ + pidls.Add(&temp); + } + + // Get the IContextMenu for the file. + CMyComPtr cm; + RINOK( parentFolder->GetUIObjectOf(GetParent(), pidls.Size(), + (LPCITEMIDLIST *)&pidls.Front(), IID_IContextMenu, 0, (void**)&cm)); + if (!cm) + { + // ShowMessage("Unable to get context menu interface."); + return E_FAIL; + } + systemContextMenu = cm; + return S_OK; +} + +void CPanel::CreateSystemMenu(HMENU menuSpec, + const CRecordVector &operatedIndices, + CMyComPtr &systemContextMenu) +{ + systemContextMenu.Release(); + + CreateShellContextMenu(operatedIndices, systemContextMenu); + + if (systemContextMenu == 0) + return; + + // Set up a CMINVOKECOMMANDINFO structure. + CMINVOKECOMMANDINFO ci; + ZeroMemory(&ci, sizeof(ci)); + ci.cbSize = sizeof(CMINVOKECOMMANDINFO); + ci.hwnd = GetParent(); + + /* + if (Sender == GoBtn) + { + // Verbs that can be used are cut, paste, + // properties, delete, and so on. + String action; + if (CutRb->Checked) + action = "cut"; + else if (CopyRb->Checked) + action = "copy"; + else if (DeleteRb->Checked) + action = "delete"; + else if (PropertiesRb->Checked) + action = "properties"; + + ci.lpVerb = action.c_str(); + result = cm->InvokeCommand(&ci); + if (result) + ShowMessage( + "Error copying file to clipboard."); + + } + else + */ + { + // HMENU hMenu = CreatePopupMenu(); + CMenu popupMenu; + // CMenuDestroyer menuDestroyer(popupMenu); + if(!popupMenu.CreatePopup()) + throw 210503; + + HMENU hMenu = popupMenu; + + DWORD Flags = CMF_EXPLORE; + // Optionally the shell will show the extended + // context menu on some operating systems when + // the shift key is held down at the time the + // context menu is invoked. The following is + // commented out but you can uncommnent this + // line to show the extended context menu. + // Flags |= 0x00000080; + systemContextMenu->QueryContextMenu(hMenu, 0, kSystemStartMenuID, 0x7FFF, Flags); + + + { + CMenu menu; + menu.Attach(menuSpec); + CMenuItem menuItem; + menuItem.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID; + menuItem.fType = MFT_STRING; + menuItem.hSubMenu = popupMenu.Detach(); + // menuDestroyer.Disable(); + menuItem.StringValue = LangString(IDS_SYSTEM, 0x030202A0); + menu.InsertItem(0, true, menuItem); + } + /* + if (Cmd < 100 && Cmd != 0) + { + ci.lpVerb = MAKEINTRESOURCE(Cmd - 1); + ci.lpParameters = ""; + ci.lpDirectory = ""; + ci.nShow = SW_SHOWNORMAL; + cm->InvokeCommand(&ci); + } + // If Cmd is > 100 then it's one of our + // inserted menu items. + else + // Find the menu item. + for (int i = 0; i < popupMenu1->Items->Count; i++) + { + TMenuItem* menu = popupMenu1->Items->Items[i]; + // Call its OnClick handler. + if (menu->Command == Cmd - 100) + menu->OnClick(this); + } + // Release the memory allocated for the menu. + DestroyMenu(hMenu); + */ + } +} + +void CPanel::CreateFileMenu(HMENU menuSpec) +{ + CreateFileMenu(menuSpec, _sevenZipContextMenu, _systemContextMenu, true); +} + +void CPanel::CreateSevenZipMenu(HMENU menuSpec, + const CRecordVector &operatedIndices, + CMyComPtr &sevenZipContextMenu) +{ + sevenZipContextMenu.Release(); + + CMenu menu; + menu.Attach(menuSpec); + // CMenuDestroyer menuDestroyer(menu); + // menu.CreatePopup(); + + bool sevenZipMenuCreated = false; + + CMyComPtr contextMenu; + if (contextMenu.CoCreateInstance(CLSID_CZipContextMenu, IID_IContextMenu) == S_OK) + { + CMyComPtr initContextMenu; + if (contextMenu.QueryInterface(IID_IInitContextMenu, &initContextMenu) != S_OK) + return; + UString currentFolderUnicode = _currentFolderPrefix; + UStringVector names; + int i; + for(i = 0; i < operatedIndices.Size(); i++) + names.Add(currentFolderUnicode + GetItemRelPath(operatedIndices[i])); + CRecordVector namePointers; + for(i = 0; i < operatedIndices.Size(); i++) + namePointers.Add(names[i]); + + // NFile::NDirectory::MySetCurrentDirectory(currentFolderUnicode); + if (initContextMenu->InitContextMenu(currentFolderUnicode, &namePointers.Front(), + operatedIndices.Size()) == S_OK) + { + HRESULT res = contextMenu->QueryContextMenu(menu, 0, kSevenZipStartMenuID, + kSystemStartMenuID - 1, 0); + sevenZipMenuCreated = (HRESULT_SEVERITY(res) == SEVERITY_SUCCESS); + if (sevenZipMenuCreated) + sevenZipContextMenu = contextMenu; + // int code = HRESULT_CODE(res); + // int nextItemID = code; + } + } +} + +void CPanel::CreateFileMenu(HMENU menuSpec, + CMyComPtr &sevenZipContextMenu, + CMyComPtr &systemContextMenu, + bool programMenu) +{ + sevenZipContextMenu.Release(); + systemContextMenu.Release(); + + CRecordVector operatedIndices; + GetOperatedItemIndices(operatedIndices); + + CMenu menu; + menu.Attach(menuSpec); + + CreateSevenZipMenu(menu, operatedIndices, sevenZipContextMenu); + if (g_App.ShowSystemMenu) + CreateSystemMenu(menu, operatedIndices, systemContextMenu); + + if (menu.GetItemCount() > 0) + menu.AppendItem(MF_SEPARATOR, 0, (LPCTSTR)0); + + LoadFileMenu(menu, menu.GetItemCount(), !operatedIndices.IsEmpty(), programMenu); +} + +bool CPanel::InvokePluginCommand(int id) +{ + return InvokePluginCommand(id, _sevenZipContextMenu, _systemContextMenu); +} + +bool CPanel::InvokePluginCommand(int id, + IContextMenu *sevenZipContextMenu, IContextMenu *systemContextMenu) +{ + UINT32 offset; + bool isSystemMenu = (id >= kSystemStartMenuID); + if (isSystemMenu) + offset = id - kSystemStartMenuID; + else + offset = id - kSevenZipStartMenuID; + + CMINVOKECOMMANDINFOEX commandInfo; + commandInfo.cbSize = sizeof(commandInfo); + commandInfo.fMask = CMIC_MASK_UNICODE; + commandInfo.hwnd = GetParent(); + commandInfo.lpVerb = (LPCSTR)(MAKEINTRESOURCE(offset)); + commandInfo.lpParameters = NULL; + CSysString currentFolderSys = GetSystemString(_currentFolderPrefix); + commandInfo.lpDirectory = (LPCSTR)(LPCTSTR)(currentFolderSys); + commandInfo.nShow = SW_SHOW; + commandInfo.lpTitle = ""; + commandInfo.lpVerbW = (LPCWSTR)(MAKEINTRESOURCEW(offset)); + commandInfo.lpParameters = NULL; + UString currentFolderUnicode = _currentFolderPrefix; + commandInfo.lpDirectoryW = currentFolderUnicode; + commandInfo.lpTitleW = L""; + // commandInfo.ptInvoke.x = xPos; + // commandInfo.ptInvoke.y = yPos; + commandInfo.ptInvoke.x = 0; + commandInfo.ptInvoke.y = 0; + HRESULT result; + if (isSystemMenu) + result = systemContextMenu->InvokeCommand(LPCMINVOKECOMMANDINFO(&commandInfo)); + else + result = sevenZipContextMenu->InvokeCommand(LPCMINVOKECOMMANDINFO(&commandInfo)); + if (result == NOERROR) + { + KillSelection(); + return true; + } + return false; +} + +bool CPanel::OnContextMenu(HANDLE windowHandle, int xPos, int yPos) +{ + if (windowHandle != _listView) + return false; + /* + POINT point; + point.x = xPos; + point.y = yPos; + if (!_listView.ScreenToClient(&point)) + return false; + + LVHITTESTINFO info; + info.pt = point; + int index = _listView.HitTest(&info); + */ + + CRecordVector 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 sevenZipContextMenu; + CMyComPtr systemContextMenu; + CreateFileMenu(menu, sevenZipContextMenu, systemContextMenu, false); + + int result = menu.Track(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY, + xPos, yPos, _listView); + + if (result == 0) + return true; + + if (result >= kPluginMenuStartID) + { + InvokePluginCommand(result, sevenZipContextMenu, systemContextMenu); + return true; + } + if (ExecuteFileCommand(result)) + return true; + return true; +} diff --git a/CPP/7zip/FileManager/PanelOperations.cpp b/CPP/7zip/FileManager/PanelOperations.cpp new file mode 100755 index 00000000..66993f39 --- /dev/null +++ b/CPP/7zip/FileManager/PanelOperations.cpp @@ -0,0 +1,396 @@ +// PanelOperations.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "Panel.h" + +#include "Common/StringConvert.h" +#include "Common/DynamicBuffer.h" +#include "Windows/FileDir.h" +#include "Windows/ResourceString.h" +#include "Windows/Thread.h" +#include "Windows/COM.h" + +#include "Resource/ComboDialog/ComboDialog.h" + +#include "FSFolder.h" +#include "LangUtils.h" +#include "FormatUtils.h" + +#include "UpdateCallback100.h" + +using namespace NWindows; +using namespace NFile; + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +struct CThreadDelete +{ + CMyComPtr FolderOperations; + CRecordVector Indices; + CMyComPtr UpdateCallback; + CUpdateCallback100Imp *UpdateCallbackSpec; + HRESULT Result; + + DWORD Process() + { + NCOM::CComInitializer comInitializer; + UpdateCallbackSpec->ProgressDialog.WaitCreating(); + Result = FolderOperations->Delete(&Indices.Front(), Indices.Size(), UpdateCallback); + UpdateCallbackSpec->ProgressDialog.MyClose(); + return 0; + } + + static DWORD WINAPI MyThreadFunction(void *param) + { + return ((CThreadDelete *)param)->Process(); + } +}; + +#ifndef _UNICODE +typedef int (WINAPI * SHFileOperationWP)(LPSHFILEOPSTRUCTW lpFileOp); +#endif + +void CPanel::DeleteItems(bool toRecycleBin) +{ + CPanel::CDisableTimerProcessing disableTimerProcessing2(*this); + CRecordVector indices; + GetOperatedItemIndices(indices); + if (indices.IsEmpty()) + return; + CSelectedState state; + SaveSelectedState(state); + bool useInternalDelete = false; + if (IsFSFolder() && toRecycleBin) + { + #ifndef _UNICODE + if (!g_IsNT) + { + CDynamicBuffer buffer; + size_t size = 0; + for (int i = 0; i < indices.Size(); i++) + { + const AString path = GetSystemString(GetFsPath() + GetItemRelPath(indices[i])); + buffer.EnsureCapacity(size + path.Length() + 1); + memmove(((CHAR *)buffer) + size, (const CHAR *)path, (path.Length() + 1) * sizeof(CHAR)); + size += path.Length() + 1; + } + buffer.EnsureCapacity(size + 1); + ((CHAR *)buffer)[size] = 0; + SHFILEOPSTRUCTA fo; + fo.hwnd = GetParent(); + fo.wFunc = FO_DELETE; + fo.pFrom = (const CHAR *)buffer; + fo.pTo = 0; + fo.fFlags = 0; + if (toRecycleBin) + fo.fFlags |= FOF_ALLOWUNDO; + // fo.fFlags |= FOF_NOCONFIRMATION; + // fo.fFlags |= FOF_NOERRORUI; + // fo.fFlags |= FOF_SILENT; + // fo.fFlags |= FOF_WANTNUKEWARNING; + fo.fAnyOperationsAborted = FALSE; + fo.hNameMappings = 0; + fo.lpszProgressTitle = 0; + /* int res = */ ::SHFileOperationA(&fo); + } + else + #endif + { + CDynamicBuffer buffer; + size_t size = 0; + int maxLen = 0; + for (int i = 0; i < indices.Size(); i++) + { + // L"\\\\?\\") doesn't work here. + const UString path = GetFsPath() + GetItemRelPath(indices[i]); + if (path.Length() > maxLen) + maxLen = path.Length(); + buffer.EnsureCapacity(size + path.Length() + 1); + memmove(((WCHAR *)buffer) + size, (const WCHAR *)path, (path.Length() + 1) * sizeof(WCHAR)); + size += path.Length() + 1; + } + buffer.EnsureCapacity(size + 1); + ((WCHAR *)buffer)[size] = 0; + if (maxLen >= MAX_PATH) + { + if (toRecycleBin) + { + MessageBoxMyError(L"You can't send file with long path to Recycle Bin"); + return; + } + useInternalDelete = true; + } + else + { + SHFILEOPSTRUCTW fo; + fo.hwnd = GetParent(); + fo.wFunc = FO_DELETE; + fo.pFrom = (const WCHAR *)buffer; + fo.pTo = 0; + fo.fFlags = 0; + if (toRecycleBin) + fo.fFlags |= FOF_ALLOWUNDO; + fo.fAnyOperationsAborted = FALSE; + fo.hNameMappings = 0; + fo.lpszProgressTitle = 0; + int res; + #ifdef _UNICODE + res = ::SHFileOperationW(&fo); + #else + SHFileOperationWP shFileOperationW = (SHFileOperationWP) + ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "SHFileOperationW"); + if (shFileOperationW == 0) + return; + res = shFileOperationW(&fo); + #endif + } + } + /* + if (fo.fAnyOperationsAborted) + MessageBoxError(result, LangString(IDS_ERROR_DELETING, 0x03020217)); + */ + } + else + useInternalDelete = true; + if (useInternalDelete) + DeleteItemsInternal(indices); + RefreshListCtrl(state); +} + +void CPanel::DeleteItemsInternal(CRecordVector &indices) +{ + CMyComPtr folderOperations; + if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) + { + MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + + UString title; + UString message; + if (indices.Size() == 1) + { + int index = indices[0]; + const UString itemName = GetItemRelPath(index); + if (IsItemFolder(index)) + { + title = LangString(IDS_CONFIRM_FOLDER_DELETE, 0x03020211); + message = MyFormatNew(IDS_WANT_TO_DELETE_FOLDER, 0x03020214, itemName); + } + else + { + title = LangString(IDS_CONFIRM_FILE_DELETE, 0x03020210); + message = MyFormatNew(IDS_WANT_TO_DELETE_FILE, 0x03020213, itemName); + } + } + else + { + title = LangString(IDS_CONFIRM_ITEMS_DELETE, 0x03020212); + message = MyFormatNew(IDS_WANT_TO_DELETE_ITEMS, 0x03020215, + NumberToString(indices.Size())); + } + if (::MessageBoxW(GetParent(), message, title, MB_OKCANCEL | MB_ICONQUESTION) != IDOK) + return; + + CThreadDelete deleter; + deleter.UpdateCallbackSpec = new CUpdateCallback100Imp; + deleter.UpdateCallback = deleter.UpdateCallbackSpec; + deleter.UpdateCallbackSpec->Init(GetParent(), false, L""); + + UString progressTitle = LangString(IDS_DELETING, 0x03020216); + + deleter.UpdateCallbackSpec->ProgressDialog.MainWindow = _mainWindow; + deleter.UpdateCallbackSpec->ProgressDialog.MainTitle = LangString(IDS_APP_TITLE, 0x03000000); + deleter.UpdateCallbackSpec->ProgressDialog.MainAddTitle = progressTitle + UString(L" "); + + deleter.FolderOperations = folderOperations; + deleter.Indices = indices; + + CThread thread; + if (!thread.Create(CThreadDelete::MyThreadFunction, &deleter)) + throw 271824; + deleter.UpdateCallbackSpec->StartProgressDialog(progressTitle); + + HRESULT result = deleter.Result; + if (result != S_OK) + MessageBoxError(result, LangString(IDS_ERROR_DELETING, 0x03020217)); +} + +BOOL CPanel::OnBeginLabelEdit(LV_DISPINFOW * lpnmh) +{ + int realIndex = GetRealIndex(lpnmh->item); + if (realIndex == kParentIndex) + return TRUE; + CMyComPtr folderOperations; + if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) + return TRUE; + return FALSE; +} + +BOOL CPanel::OnEndLabelEdit(LV_DISPINFOW * lpnmh) +{ + if (lpnmh->item.pszText == NULL) + return FALSE; + CMyComPtr folderOperations; + if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) + { + MessageBoxMyError(L"Renaming is not supported"); + return FALSE; + } + const UString newName = lpnmh->item.pszText; + CPanel::CDisableTimerProcessing disableTimerProcessing2(*this); + + SaveSelectedState(_selectedState); + + int realIndex = GetRealIndex(lpnmh->item); + if (realIndex == kParentIndex) + return FALSE; + const UString prefix = GetItemPrefix(realIndex); + HRESULT result = folderOperations->Rename(realIndex, newName, 0); + if (result != S_OK) + { + MessageBoxError(result, LangString(IDS_ERROR_RENAMING, 0x03020221)); + return FALSE; + } + // Can't use RefreshListCtrl here. + // RefreshListCtrlSaveFocused(); + _selectedState.FocusedName = prefix + newName; + _selectedState.SelectFocused = true; + + // We need clear all items to disable GetText before Reload: + // number of items can change. + // _listView.DeleteAllItems(); + // But seems it can still call GetText (maybe for current item) + // so we can't delete items. + + _dontShowMode = true; + + PostMessage(kReLoadMessage); + return TRUE; +} + +void CPanel::CreateFolder() +{ + CMyComPtr folderOperations; + if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) + { + MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + CPanel::CDisableTimerProcessing disableTimerProcessing2(*this); + CSelectedState state; + SaveSelectedState(state); + CComboDialog comboDialog; + comboDialog.Title = LangString(IDS_CREATE_FOLDER, 0x03020230); + comboDialog.Static = LangString(IDS_CREATE_FOLDER_NAME, 0x03020231); + comboDialog.Value = LangString(IDS_CREATE_FOLDER_DEFAULT_NAME, /*0x03020232*/ (UInt32)-1); + if (comboDialog.Create(GetParent()) == IDCANCEL) + return; + UString newName = comboDialog.Value; + HRESULT result = folderOperations->CreateFolder(newName, 0); + if (result != S_OK) + { + MessageBoxError(result, LangString(IDS_CREATE_FOLDER_ERROR, 0x03020233)); + return; + } + int pos = newName.Find(L'\\'); + if (pos >= 0) + newName = newName.Left(pos); + if (!_mySelectMode) + state.SelectedNames.Clear(); + state.FocusedName = newName; + state.SelectFocused = true; + RefreshListCtrl(state); +} + +void CPanel::CreateFile() +{ + CMyComPtr folderOperations; + if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) + { + MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + CPanel::CDisableTimerProcessing disableTimerProcessing2(*this); + CSelectedState state; + SaveSelectedState(state); + CComboDialog comboDialog; + comboDialog.Title = LangString(IDS_CREATE_FILE, 0x03020240); + comboDialog.Static = LangString(IDS_CREATE_FILE_NAME, 0x03020241); + comboDialog.Value = LangString(IDS_CREATE_FILE_DEFAULT_NAME, /*0x03020242*/ (UInt32)-1); + if (comboDialog.Create(GetParent()) == IDCANCEL) + return; + UString newName = comboDialog.Value; + HRESULT result = folderOperations->CreateFile(newName, 0); + if (result != S_OK) + { + MessageBoxError(result, LangString(IDS_CREATE_FILE_ERROR, 0x03020243)); + return; + } + int pos = newName.Find(L'\\'); + if (pos >= 0) + newName = newName.Left(pos); + if (!_mySelectMode) + state.SelectedNames.Clear(); + state.FocusedName = newName; + state.SelectFocused = true; + RefreshListCtrl(state); +} + +void CPanel::RenameFile() +{ + int index = _listView.GetFocusedItem(); + if (index >= 0) + _listView.EditLabel(index); +} + +void CPanel::ChangeComment() +{ + CPanel::CDisableTimerProcessing disableTimerProcessing2(*this); + int index = _listView.GetFocusedItem(); + if (index < 0) + return; + int realIndex = GetRealItemIndex(index); + if (realIndex == kParentIndex) + return; + CSelectedState state; + SaveSelectedState(state); + CMyComPtr folderOperations; + if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) + { + MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + + UString comment; + { + NCOM::CPropVariant propVariant; + if (_folder->GetProperty(realIndex, kpidComment, &propVariant) != S_OK) + return; + if (propVariant.vt == VT_BSTR) + comment = propVariant.bstrVal; + else if (propVariant.vt != VT_EMPTY) + return; + } + UString name = GetItemRelPath(realIndex); + CComboDialog comboDialog; + comboDialog.Title = name + L" " + LangString(IDS_COMMENT, 0x03020290); + comboDialog.Value = comment; + comboDialog.Static = LangString(IDS_COMMENT2, 0x03020291); + if (comboDialog.Create(GetParent()) == IDCANCEL) + return; + NCOM::CPropVariant propVariant = comboDialog.Value; + + HRESULT result = folderOperations->SetProperty(realIndex, kpidComment, &propVariant, NULL); + if (result != S_OK) + { + MessageBoxError(result, L"Set Comment Error"); + } + RefreshListCtrl(state); +} + diff --git a/CPP/7zip/FileManager/PanelSelect.cpp b/CPP/7zip/FileManager/PanelSelect.cpp new file mode 100755 index 00000000..e769195f --- /dev/null +++ b/CPP/7zip/FileManager/PanelSelect.cpp @@ -0,0 +1,297 @@ +// PanelSelect.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "Common/StringConvert.h" +#include "Common/Wildcard.h" + +#include "Panel.h" + +#include "Resource/ComboDialog/ComboDialog.h" + +#include "LangUtils.h" + +void CPanel::OnShiftSelectMessage() +{ + if (!_mySelectMode) + return; + int focusedItem = _listView.GetFocusedItem(); + if (focusedItem < 0) + return; + if (!_selectionIsDefined) + return; + int startItem = MyMin(focusedItem, _prevFocusedItem); + int finishItem = MyMax(focusedItem, _prevFocusedItem); + for (int i = 0; i < _listView.GetItemCount(); i++) + { + int realIndex = GetRealItemIndex(i); + if (realIndex == kParentIndex) + continue; + if (i >= startItem && i <= finishItem) + if (_selectedStatusVector[realIndex] != _selectMark) + { + _selectedStatusVector[realIndex] = _selectMark; + _listView.RedrawItem(i); + } + } + _prevFocusedItem = focusedItem; +} + +void CPanel::OnArrowWithShift() +{ + if (!_mySelectMode) + return; + int focusedItem = _listView.GetFocusedItem(); + if (focusedItem < 0) + return; + int realIndex = GetRealItemIndex(focusedItem); + if (_selectionIsDefined) + { + if (realIndex != kParentIndex) + _selectedStatusVector[realIndex] = _selectMark; + } + else + { + if (realIndex == kParentIndex) + { + _selectionIsDefined = true; + _selectMark = true; + } + else + { + _selectionIsDefined = true; + _selectMark = !_selectedStatusVector[realIndex]; + _selectedStatusVector[realIndex] = _selectMark; + } + } + _prevFocusedItem = focusedItem; + PostMessage(kShiftSelectMessage); + _listView.RedrawItem(focusedItem); +} + +void CPanel::OnInsert() +{ + /* + const int kState = CDIS_MARKED; // LVIS_DROPHILITED; + UINT state = (_listView.GetItemState(focusedItem, LVIS_CUT) == 0) ? + LVIS_CUT : 0; + _listView.SetItemState(focusedItem, state, LVIS_CUT); + // _listView.SetItemState(focusedItem, LVIS_SELECTED, LVIS_SELECTED); + + */ + int focusedItem = _listView.GetFocusedItem(); + if (focusedItem < 0) + return; + int realIndex = GetRealItemIndex(focusedItem); + bool isSelected = !_selectedStatusVector[realIndex]; + if (realIndex != kParentIndex) + _selectedStatusVector[realIndex] = isSelected; + + if (!_mySelectMode) + _listView.SetItemState(focusedItem, isSelected ? LVIS_SELECTED: 0, LVIS_SELECTED); + + _listView.RedrawItem(focusedItem); + + int nextIndex = focusedItem + 1; + if (nextIndex < _listView.GetItemCount()) + { + _listView.SetItemState(nextIndex, LVIS_FOCUSED | LVIS_SELECTED, + LVIS_FOCUSED | LVIS_SELECTED); + _listView.EnsureVisible(nextIndex, false); + } +} + +/* +void CPanel::OnUpWithShift() +{ + int focusedItem = _listView.GetFocusedItem(); + if (focusedItem < 0) + return; + int index = GetRealItemIndex(focusedItem); + _selectedStatusVector[index] = !_selectedStatusVector[index]; + _listView.RedrawItem(index); +} + +void CPanel::OnDownWithShift() +{ + int focusedItem = _listView.GetFocusedItem(); + if (focusedItem < 0) + return; + int index = GetRealItemIndex(focusedItem); + _selectedStatusVector[index] = !_selectedStatusVector[index]; + _listView.RedrawItem(index); +} +*/ + +void CPanel::UpdateSelection() +{ + if (!_mySelectMode) + { + bool enableTemp = _enableItemChangeNotify; + _enableItemChangeNotify = false; + int numItems = _listView.GetItemCount(); + for (int i = 0; i < numItems; i++) + { + int realIndex = GetRealItemIndex(i); + if (realIndex != kParentIndex) + { + UINT value = 0; + value = _selectedStatusVector[realIndex] ? LVIS_SELECTED: 0; + _listView.SetItemState(i, value, LVIS_SELECTED); + } + } + _enableItemChangeNotify = enableTemp; + } + _listView.RedrawAllItems(); +} + + +void CPanel::SelectSpec(bool selectMode) +{ + CComboDialog comboDialog; + comboDialog.Title = selectMode ? + LangString(IDS_SELECT, 0x03020250): + LangString(IDS_DESELECT, 0x03020251); + comboDialog.Static = LangString(IDS_SELECT_MASK, 0x03020252); + comboDialog.Value = L"*"; + if (comboDialog.Create(GetParent()) == IDCANCEL) + return; + const UString &mask = comboDialog.Value; + for (int i = 0; i < _selectedStatusVector.Size(); i++) + if (CompareWildCardWithName(mask, GetItemName(i))) + _selectedStatusVector[i] = selectMode; + UpdateSelection(); +} + +void CPanel::SelectByType(bool selectMode) +{ + int focusedItem = _listView.GetFocusedItem(); + if (focusedItem < 0) + return; + int realIndex = GetRealItemIndex(focusedItem); + UString name = GetItemName(realIndex); + bool isItemFolder = IsItemFolder(realIndex); + + /* + UINT32 numItems; + _folder->GetNumberOfItems(&numItems); + if ((UInt32)_selectedStatusVector.Size() != numItems) + throw 11111; + */ + + if (isItemFolder) + { + for (int i = 0; i < _selectedStatusVector.Size(); i++) + if (IsItemFolder(i) == isItemFolder) + _selectedStatusVector[i] = selectMode; + } + else + { + int pos = name.ReverseFind(L'.'); + if (pos < 0) + { + for (int i = 0; i < _selectedStatusVector.Size(); i++) + if (IsItemFolder(i) == isItemFolder && GetItemName(i).ReverseFind(L'.') < 0) + _selectedStatusVector[i] = selectMode; + } + else + { + UString mask = UString(L'*') + name.Mid(pos); + for (int i = 0; i < _selectedStatusVector.Size(); i++) + if (IsItemFolder(i) == isItemFolder && CompareWildCardWithName(mask, GetItemName(i))) + _selectedStatusVector[i] = selectMode; + } + } + UpdateSelection(); +} + +void CPanel::SelectAll(bool selectMode) +{ + for (int i = 0; i < _selectedStatusVector.Size(); i++) + _selectedStatusVector[i] = selectMode; + UpdateSelection(); +} + +void CPanel::InvertSelection() +{ + if (!_mySelectMode) + { + int numSelected = 0; + for (int i = 0; i < _selectedStatusVector.Size(); i++) + if (_selectedStatusVector[i]) + numSelected++; + if (numSelected == 1) + { + int focused = _listView.GetFocusedItem(); + if (focused >= 0) + { + int realIndex = GetRealItemIndex(focused); + if (realIndex >= 0) + if (_selectedStatusVector[realIndex]) + _selectedStatusVector[realIndex] = false; + } + } + } + for (int i = 0; i < _selectedStatusVector.Size(); i++) + _selectedStatusVector[i] = !_selectedStatusVector[i]; + UpdateSelection(); +} + +void CPanel::KillSelection() +{ + SelectAll(false); + if (!_mySelectMode) + { + int focused = _listView.GetFocusedItem(); + if (focused >= 0) + _listView.SetItemState(focused, LVIS_SELECTED, LVIS_SELECTED); + } +} + +void CPanel::OnLeftClick(LPNMITEMACTIVATE itemActivate) +{ + if(itemActivate->hdr.hwndFrom != HWND(_listView)) + return; + // It will be work only for Version 4.71 (IE 4); + int indexInList = itemActivate->iItem; + if (indexInList < 0) + return; + if ((itemActivate->uKeyFlags & LVKF_SHIFT) != 0) + { + // int focusedIndex = _listView.GetFocusedItem(); + int focusedIndex = _startGroupSelect; + if (focusedIndex < 0) + return; + int startItem = MyMin(focusedIndex, indexInList); + int finishItem = MyMax(focusedIndex, indexInList); + for (int i = 0; i < _selectedStatusVector.Size(); i++) + { + int realIndex = GetRealItemIndex(i); + if (realIndex == kParentIndex) + continue; + bool selected = (i >= startItem && i <= finishItem); + if (_selectedStatusVector[realIndex] != selected) + { + _selectedStatusVector[realIndex] = selected; + _listView.RedrawItem(i); + } + } + } + else + { + _startGroupSelect = indexInList; + if ((itemActivate->uKeyFlags & LVKF_CONTROL) != 0) + { + int realIndex = GetRealItemIndex(indexInList); + if (realIndex != kParentIndex) + { + _selectedStatusVector[realIndex] = !_selectedStatusVector[realIndex]; + _listView.RedrawItem(indexInList); + } + } + } + return; +} + diff --git a/CPP/7zip/FileManager/PanelSort.cpp b/CPP/7zip/FileManager/PanelSort.cpp new file mode 100755 index 00000000..fd9027b9 --- /dev/null +++ b/CPP/7zip/FileManager/PanelSort.cpp @@ -0,0 +1,163 @@ +// PanelSort.cpp + +#include "StdAfx.h" + +#include "Windows/PropVariant.h" + +#include "../PropID.h" + +#include "Panel.h" + +using namespace NWindows; + +static UString GetExtension(const UString &name) +{ + int dotPos = name.ReverseFind(L'.'); + if (dotPos < 0) + return UString(); + return name.Mid(dotPos); +} + +int CALLBACK CompareItems2(LPARAM lParam1, LPARAM lParam2, LPARAM lpData) +{ + if(lpData == NULL) + return 0; + CPanel *panel = (CPanel*)lpData; + + switch(panel->_sortID) + { + // if (panel->_sortIndex == 0) + case kpidName: + { + const UString name1 = panel->GetItemName((int)lParam1); + const UString name2 = panel->GetItemName((int)lParam2); + int res = name1.CompareNoCase(name2); + /* + if (res != 0 || !panel->_flatMode) + return res; + const UString prefix1 = panel->GetItemPrefix(lParam1); + const UString prefix2 = panel->GetItemPrefix(lParam2); + return res = prefix1.CompareNoCase(prefix2); + */ + return res; + } + case kpidNoProperty: + { + return MyCompare(lParam1, lParam2); + } + case kpidExtension: + { + const UString ext1 = GetExtension(panel->GetItemName((int)lParam1)); + const UString ext2 = GetExtension(panel->GetItemName((int)lParam2)); + return ext1.CompareNoCase(ext2); + } + } + /* + if (panel->_sortIndex == 1) + return MyCompare(file1.Size, file2.Size); + return ::CompareFileTime(&file1.LastWriteTime, &file2.LastWriteTime); + */ + + // PROPID propID = panel->_properties[panel->_sortIndex].ID; + PROPID propID = panel->_sortID; + + NCOM::CPropVariant propVariant1, propVariant2; + // Name must be first property + panel->_folder->GetProperty((UINT32)lParam1, propID, &propVariant1); + panel->_folder->GetProperty((UINT32)lParam2, propID, &propVariant2); + if(propVariant1.vt != propVariant2.vt) + return 0; // It means some BUG + if (propVariant1.vt == VT_BSTR) + { + return _wcsicmp(propVariant1.bstrVal, propVariant2.bstrVal); + } + return propVariant1.Compare(propVariant2); + // return 0; +} + +int CALLBACK CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData) +{ + if(lpData == NULL) + return 0; + if (lParam1 == kParentIndex) + return -1; + if (lParam2 == kParentIndex) + return 1; + + CPanel *panel = (CPanel*)lpData; + + bool isDirectory1 = panel->IsItemFolder((int)lParam1); + bool isDirectory2 = panel->IsItemFolder((int)lParam2); + + if(isDirectory1 && (!isDirectory2)) + return -1; + if((!isDirectory1) && isDirectory2) + return 1; + + int result = CompareItems2(lParam1, lParam2, lpData); + return panel->_ascending ? result: (-result); +} + + +/* +void CPanel::SortItems(int index) +{ + if(index == _sortIndex) + _ascending = !_ascending; + else + { + _sortIndex = index; + _ascending = true; + switch (_properties[_sortIndex].ID) + { + case kpidSize: + case kpidPackedSize: + case kpidCreationTime: + case kpidLastAccessTime: + case kpidLastWriteTime: + _ascending = false; + break; + } + } + _listView.SortItems(CompareItems, (LPARAM)this); + _listView.EnsureVisible(_listView.GetFocusedItem(), false); +} +void CPanel::SortItemsWithPropID(PROPID propID) +{ + int index = _properties.FindItemWithID(propID); + if (index >= 0) + SortItems(index); +} +*/ +void CPanel::SortItemsWithPropID(PROPID propID) +{ + if(propID == _sortID) + _ascending = !_ascending; + else + { + _sortID = propID; + _ascending = true; + switch (propID) + { + case kpidSize: + case kpidPackedSize: + case kpidCreationTime: + case kpidLastAccessTime: + case kpidLastWriteTime: + _ascending = false; + break; + } + } + _listView.SortItems(CompareItems, (LPARAM)this); + _listView.EnsureVisible(_listView.GetFocusedItem(), false); +} + + +void CPanel::OnColumnClick(LPNMLISTVIEW info) +{ + /* + int index = _properties.FindItemWithID(_visibleProperties[info->iSubItem].ID); + SortItems(index); + */ + SortItemsWithPropID(_visibleProperties[info->iSubItem].ID); +} diff --git a/CPP/7zip/FileManager/PanelSplitFile.cpp b/CPP/7zip/FileManager/PanelSplitFile.cpp new file mode 100755 index 00000000..8e095628 --- /dev/null +++ b/CPP/7zip/FileManager/PanelSplitFile.cpp @@ -0,0 +1,477 @@ +// PanelSplitFile.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "Common/Alloc.h" +#include "Common/Types.h" +#include "Common/IntToString.h" + +#include "Windows/COM.h" +#include "Windows/FileIO.h" +#include "Windows/FileFind.h" +#include "Windows/Thread.h" +#include "Resource/ProgressDialog2/ProgressDialog.h" +#include "Resource/SplitDialog/SplitDialog.h" +#include "Resource/CopyDialog/CopyDialog.h" + +#include "../UI/Resource/Extract/resource.h" + +#include "SplitUtils.h" +#include "App.h" +#include "FormatUtils.h" +#include "LangUtils.h" + +using namespace NWindows; + +class CMyBuffer +{ + void *_data; +public: + CMyBuffer(): _data(0) {} + operator void *() { return _data; } + bool Allocate(size_t size) + { + if (_data != 0) + return false; + _data = ::MidAlloc(size); + return _data != 0; + } + ~CMyBuffer() { ::MidFree(_data); } +}; + +struct CVolSeqName +{ + UString UnchangedPart; + UString ChangedPart; + CVolSeqName(): ChangedPart(L"000") {}; + + bool ParseName(const UString &name) + { + if (name.Right(2) != L"01") + return false; + int numLetters = 2; + while (numLetters < name.Length()) + { + if (name[name.Length() - numLetters - 1] != '0') + break; + numLetters++; + } + UnchangedPart = name.Left(name.Length() - numLetters); + ChangedPart = name.Right(numLetters); + return true; + } + + UString GetNextName() + { + UString newName; + int i; + int numLetters = ChangedPart.Length(); + for (i = numLetters - 1; i >= 0; i--) + { + wchar_t c = ChangedPart[i]; + if (c == L'9') + { + c = L'0'; + newName = c + newName; + if (i == 0) + newName = UString(L'1') + newName; + continue; + } + c++; + newName = c + newName; + i--; + for (; i >= 0; i--) + newName = ChangedPart[i] + newName; + break; + } + ChangedPart = newName; + return UnchangedPart + ChangedPart; + } +}; + +static const UInt32 kBufSize = (1 << 20); + +struct CThreadSplit +{ + // HRESULT Result; + // CPanel *Panel; + CProgressDialog *ProgressDialog; + UString FilePath; + UString VolBasePath; + CRecordVector VolumeSizes; + UString Error; + + void Process2() + { + // NCOM::CComInitializer comInitializer; + ProgressDialog->WaitCreating(); + NFile::NIO::CInFile inFile; + if (!inFile.Open(FilePath)) + throw L"Can not open file"; + NFile::NIO::COutFile outFile; + CMyBuffer bufferObject; + if (!bufferObject.Allocate(kBufSize)) + throw L"Can not allocate buffer"; + Byte *buffer = (Byte *)(void *)bufferObject; + UInt64 curVolSize = 0; + CVolSeqName seqName; + UInt64 length; + if (!inFile.GetLength(length)) + throw "error"; + + ProgressDialog->ProgressSynch.SetProgress(length, 0); + UInt64 pos = 0; + + int volIndex = 0; + + for (;;) + { + UInt64 volSize; + if (volIndex < VolumeSizes.Size()) + volSize = VolumeSizes[volIndex]; + else + volSize = VolumeSizes.Back(); + + UInt32 needSize = (UInt32)(MyMin((UInt64)kBufSize, volSize - curVolSize)); + UInt32 processedSize; + if (!inFile.Read(buffer, needSize, processedSize)) + throw L"Can not read input file"; + if (processedSize == 0) + break; + needSize = processedSize; + if (curVolSize == 0) + { + UString name = VolBasePath; + name += L"."; + name += seqName.GetNextName(); + if (!outFile.Create(name, false)) + throw L"Can not create output file"; + ProgressDialog->ProgressSynch.SetCurrentFileName(name); + } + if (!outFile.Write(buffer, needSize, processedSize)) + throw L"Can not write output file"; + if (needSize != processedSize) + throw L"Can not write output file"; + curVolSize += processedSize; + if (curVolSize == volSize) + { + outFile.Close(); + if (volIndex < VolumeSizes.Size()) + volIndex++; + curVolSize = 0; + } + pos += processedSize; + HRESULT res = ProgressDialog->ProgressSynch.SetPosAndCheckPaused(pos); + if (res != S_OK) + return; + } + } + DWORD Process() + { + try { Process2(); } + catch(const wchar_t *s) { Error = s; } + catch(...) { Error = L"Error"; } + ProgressDialog->MyClose(); + return 0; + } + + static DWORD WINAPI MyThreadFunction(void *param) + { + return ((CThreadSplit *)param)->Process(); + } +}; + +void CApp::Split() +{ + int srcPanelIndex = GetFocusedPanelIndex(); + CPanel &srcPanel = Panels[srcPanelIndex]; + if (!srcPanel.IsFSFolder()) + { + srcPanel.MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + CRecordVector indices; + srcPanel.GetOperatedItemIndices(indices); + if (indices.IsEmpty()) + return; + if (indices.Size() != 1) + { + srcPanel.MessageBox(L"Select one file"); + return; + } + int index = indices[0]; + if (srcPanel.IsItemFolder(index)) + { + srcPanel.MessageBox(L"Select one file"); + return; + } + const UString itemName = srcPanel.GetItemName(index); + + UString srcPath = srcPanel._currentFolderPrefix + srcPanel.GetItemPrefix(index); + UString path = srcPath; + int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); + CPanel &destPanel = Panels[destPanelIndex]; + if (NumPanels > 1) + if (destPanel.IsFSFolder()) + path = destPanel._currentFolderPrefix; + CSplitDialog splitDialog; + splitDialog.FilePath = srcPanel.GetItemRelPath(index); + splitDialog.Path = path; + if (splitDialog.Create(srcPanel.GetParent()) == IDCANCEL) + return; + + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(srcPath + itemName, fileInfo)) + { + srcPanel.MessageBoxMyError(L"Can not find file"); + return; + } + if (fileInfo.Size <= splitDialog.VolumeSizes.Front()) + { + srcPanel.MessageBoxMyError(LangString(IDS_SPLIT_VOL_MUST_BE_SMALLER, 0x03020522)); + return; + } + const UInt64 numVolumes = GetNumberOfVolumes(fileInfo.Size, splitDialog.VolumeSizes); + if (numVolumes >= 100) + { + wchar_t s[32]; + ConvertUInt64ToString(numVolumes, s); + if (::MessageBoxW(srcPanel, MyFormatNew(IDS_SPLIT_CONFIRM_MESSAGE, 0x03020521, s), + LangString(IDS_SPLIT_CONFIRM_TITLE, 0x03020520), + MB_YESNOCANCEL | MB_ICONQUESTION | MB_TASKMODAL) != IDYES) + return; + } + + path = splitDialog.Path; + NFile::NName::NormalizeDirPathPrefix(path); + if (!NFile::NDirectory::CreateComplexDirectory(path)) + { + srcPanel.MessageBoxMyError(MyFormatNew(IDS_CANNOT_CREATE_FOLDER, 0x02000603, path)); + return; + } + + CThreadSplit spliter; + // spliter.Panel = this; + + CProgressDialog progressDialog; + spliter.ProgressDialog = &progressDialog; + + UString progressWindowTitle = LangString(IDS_APP_TITLE, 0x03000000); + UString title = LangString(IDS_SPLITTING, 0x03020510); + + progressDialog.MainWindow = _window; + progressDialog.MainTitle = progressWindowTitle; + progressDialog.MainAddTitle = title + UString(L" "); + progressDialog.ProgressSynch.SetTitleFileName(itemName); + + + spliter.FilePath = srcPath + itemName; + spliter.VolBasePath = path + itemName; + spliter.VolumeSizes = splitDialog.VolumeSizes; + + // if (splitDialog.VolumeSizes.Size() == 0) return; + + // CPanel::CDisableTimerProcessing disableTimerProcessing1(srcPanel); + // CPanel::CDisableTimerProcessing disableTimerProcessing2(destPanel); + + CThread thread; + if (!thread.Create(CThreadSplit::MyThreadFunction, &spliter)) + throw 271824; + progressDialog.Create(title, _window); + + if (!spliter.Error.IsEmpty()) + srcPanel.MessageBoxMyError(spliter.Error); + // disableTimerProcessing1.Restore(); + // disableTimerProcessing2.Restore(); + // srcPanel.SetFocusToList(); + // srcPanel.RefreshListCtrlSaveFocused(); +} + + +struct CThreadCombine +{ + CProgressDialog *ProgressDialog; + UString InputDirPrefix; + UString FirstVolumeName; + UString OutputDirPrefix; + UString Error; + + void Process2() + { + // NCOM::CComInitializer comInitializer; + ProgressDialog->WaitCreating(); + + CVolSeqName volSeqName; + if (!volSeqName.ParseName(FirstVolumeName)) + throw L"Can not detect file as splitted file"; + + UString nextName = InputDirPrefix + FirstVolumeName; + UInt64 totalSize = 0; + for (;;) + { + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(nextName, fileInfo)) + break; + if (fileInfo.IsDirectory()) + break; + totalSize += fileInfo.Size; + nextName = InputDirPrefix + volSeqName.GetNextName(); + } + if (totalSize == 0) + throw L"no data"; + ProgressDialog->ProgressSynch.SetProgress(totalSize, 0); + + if (!volSeqName.ParseName(FirstVolumeName)) + throw L"Can not detect file as splitted file"; + + UString outName = volSeqName.UnchangedPart; + while(!outName.IsEmpty()) + { + int lastIndex = outName.Length() - 1; + if (outName[lastIndex] != L'.') + break; + outName.Delete(lastIndex); + } + if (outName.IsEmpty()) + outName = L"file"; + NFile::NIO::COutFile outFile; + if (!outFile.Create(OutputDirPrefix + outName, false)) + throw L"Can create open output file"; + + NFile::NIO::CInFile inFile; + CMyBuffer bufferObject; + if (!bufferObject.Allocate(kBufSize)) + throw L"Can not allocate buffer"; + Byte *buffer = (Byte *)(void *)bufferObject; + UInt64 pos = 0; + nextName = InputDirPrefix + FirstVolumeName; + bool needOpen = true; + for (;;) + { + if (needOpen) + { + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(nextName, fileInfo)) + break; + if (fileInfo.IsDirectory()) + break; + if (!inFile.Open(nextName)) + throw L"Can not open file"; + ProgressDialog->ProgressSynch.SetCurrentFileName(fileInfo.Name); + nextName = InputDirPrefix + volSeqName.GetNextName(); + needOpen = false; + } + UInt32 processedSize; + if (!inFile.Read(buffer, kBufSize, processedSize)) + throw L"Can not read input file"; + if (processedSize == 0) + { + needOpen = true; + continue; + } + UInt32 needSize = processedSize; + if (!outFile.Write(buffer, needSize, processedSize)) + throw L"Can not write output file"; + if (needSize != processedSize) + throw L"Can not write output file"; + pos += processedSize; + HRESULT res = ProgressDialog->ProgressSynch.SetPosAndCheckPaused(pos); + if (res != S_OK) + return; + } + } + DWORD Process() + { + try { Process2(); } + catch(const wchar_t *s) { Error = s; } + catch(...) { Error = L"Error";} + ProgressDialog->MyClose(); + return 0; + } + + static DWORD WINAPI MyThreadFunction(void *param) + { + return ((CThreadCombine *)param)->Process(); + } +}; + +void CApp::Combine() +{ + int srcPanelIndex = GetFocusedPanelIndex(); + CPanel &srcPanel = Panels[srcPanelIndex]; + if (!srcPanel.IsFSFolder()) + { + srcPanel.MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + CRecordVector indices; + srcPanel.GetOperatedItemIndices(indices); + if (indices.IsEmpty()) + return; + int index = indices[0]; + if (indices.Size() != 1 || srcPanel.IsItemFolder(index)) + { + srcPanel.MessageBox(LangString(IDS_COMBINE_SELECT_ONE_FILE, 0x03020620)); + return; + } + const UString itemName = srcPanel.GetItemName(index); + + UString srcPath = srcPanel._currentFolderPrefix + srcPanel.GetItemPrefix(index); + UString path = srcPath; + int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); + CPanel &destPanel = Panels[destPanelIndex]; + if (NumPanels > 1) + if (destPanel.IsFSFolder()) + path = destPanel._currentFolderPrefix; + CCopyDialog copyDialog; + copyDialog.Value = path; + copyDialog.Title = LangString(IDS_COMBINE, 0x03020600); + copyDialog.Title += ' '; + copyDialog.Title += srcPanel.GetItemRelPath(index); + + copyDialog.Static = LangString(IDS_COMBINE_TO, 0x03020601);; + if (copyDialog.Create(srcPanel.GetParent()) == IDCANCEL) + return; + + CThreadCombine combiner; + // combiner.Panel = this; + + CProgressDialog progressDialog; + combiner.ProgressDialog = &progressDialog; + + UString progressWindowTitle = LangString(IDS_APP_TITLE, 0x03000000); + UString title = LangString(IDS_COMBINING, 0x03020610); + + progressDialog.MainWindow = _window; + progressDialog.MainTitle = progressWindowTitle; + progressDialog.MainAddTitle = title + UString(L" "); + + path = copyDialog.Value; + NFile::NName::NormalizeDirPathPrefix(path); + if (!NFile::NDirectory::CreateComplexDirectory(path)) + { + srcPanel.MessageBoxMyError(MyFormatNew(IDS_CANNOT_CREATE_FOLDER, 0x02000603, path)); + return; + } + + combiner.InputDirPrefix = srcPath; + combiner.FirstVolumeName = itemName; + combiner.OutputDirPrefix = path; + + // CPanel::CDisableTimerProcessing disableTimerProcessing1(srcPanel); + // CPanel::CDisableTimerProcessing disableTimerProcessing2(destPanel); + + CThread thread; + if (!thread.Create(CThreadCombine::MyThreadFunction, &combiner)) + throw 271824; + progressDialog.Create(title, _window); + + if (!combiner.Error.IsEmpty()) + srcPanel.MessageBoxMyError(combiner.Error); + // disableTimerProcessing1.Restore(); + // disableTimerProcessing2.Restore(); + // srcPanel.SetFocusToList(); + // srcPanel.RefreshListCtrlSaveFocused(); +} diff --git a/CPP/7zip/FileManager/PhysDriveFolder.cpp b/CPP/7zip/FileManager/PhysDriveFolder.cpp new file mode 100755 index 00000000..b69d3cb3 --- /dev/null +++ b/CPP/7zip/FileManager/PhysDriveFolder.cpp @@ -0,0 +1,274 @@ +// PhysDriveFolder.cpp + +#include "StdAfx.h" + +#include "PhysDriveFolder.h" + +#include "Common/Alloc.h" + +#include "Windows/PropVariant.h" +#include "Windows/FileDevice.h" +#include "Windows/FileSystem.h" + +#include "../PropID.h" + +using namespace NWindows; + +static const UInt32 kBufferSize = (4 << 20); + +static STATPROPSTG kProperties[] = +{ + { NULL, kpidName, VT_BSTR}, + { NULL, kpidSize, VT_UI8} +}; + +CPhysDriveFolder::~CPhysDriveFolder() +{ + if (_buffer != 0) + MyFree(_buffer); +} + +HRESULT CPhysDriveFolder::Init(const UString &path) +{ + _prefix = L"\\\\.\\"; + _path = path; + NFile::NDevice::CInFile inFile; + if (!inFile.Open(GetFullPath())) + return GetLastError(); + return S_OK; +} + +STDMETHODIMP CPhysDriveFolder::LoadItems() +{ + _driveType = NFile::NSystem::MyGetDriveType(_path + L"\\"); + _name = _path.Left(1); + _name += L'.'; + if (_driveType == DRIVE_CDROM) + _name += L"iso"; + else + _name += L"img"; + Int32 dummy; + WasChanged(&dummy); + return GetLength(_length); +} + +STDMETHODIMP CPhysDriveFolder::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = 1; + return S_OK; +} + +STDMETHODIMP CPhysDriveFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value) +{ + NCOM::CPropVariant propVariant; + if (itemIndex >= 1) + return E_INVALIDARG; + switch(propID) + { + case kpidIsFolder: + propVariant = false; + break; + case kpidName: + propVariant = _name; + break; + case kpidSize: + propVariant = _length; + break; + } + propVariant.Detach(value); + return S_OK; +} + +STDMETHODIMP CPhysDriveFolder::BindToFolder(UInt32 /* index */, IFolderFolder ** /* resultFolder */) + { return E_NOTIMPL; } + +STDMETHODIMP CPhysDriveFolder::BindToFolder(const wchar_t * /* name */, IFolderFolder ** /* resultFolder */) + { return E_NOTIMPL; } + +STDMETHODIMP CPhysDriveFolder::BindToParentFolder(IFolderFolder **resultFolder) +{ + *resultFolder = 0; + return S_OK; +} + +STDMETHODIMP CPhysDriveFolder::GetName(BSTR * /* name */) + { return E_NOTIMPL; } + +STDMETHODIMP CPhysDriveFolder::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CPhysDriveFolder::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if (index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &prop = kProperties[index]; + *propID = prop.propid; + *varType = prop.vt; + *name = 0; + return S_OK; +} + + +STDMETHODIMP CPhysDriveFolder::GetTypeID(BSTR *name) +{ + CMyComBSTR temp = L"PhysDrive"; + *name = temp.Detach(); + return S_OK; +} + +STDMETHODIMP CPhysDriveFolder::GetPath(BSTR *path) +{ + UString tempPath = GetFullPath() + L"\\"; + CMyComBSTR temp = tempPath; + *path = temp.Detach(); + return S_OK; +} + +STDMETHODIMP CPhysDriveFolder::WasChanged(Int32 *wasChanged) +{ + bool wasChangedMain = false; + *wasChanged = BoolToInt(wasChangedMain); + return S_OK; +} + +STDMETHODIMP CPhysDriveFolder::Clone(IFolderFolder **resultFolder) +{ + CPhysDriveFolder *folderSpec = new CPhysDriveFolder; + CMyComPtr folderNew = folderSpec; + folderSpec->Init(_path); + *resultFolder = folderNew.Detach(); + return S_OK; +} + +STDMETHODIMP CPhysDriveFolder::GetItemFullSize(UInt32 index, PROPVARIANT *value, IProgress * /* progress */) +{ + NCOM::CPropVariant propVariant; + if (index >= 1) + return E_INVALIDARG; + UInt64 size = 0; + HRESULT result = GetLength(size); + propVariant = size; + propVariant.Detach(value); + return result; +} + +STDMETHODIMP CPhysDriveFolder::CreateFolder(const wchar_t * /* name */, IProgress * /* progress */) + { return E_NOTIMPL; } + +STDMETHODIMP CPhysDriveFolder::CreateFile(const wchar_t * /* name */, IProgress * /* progress */) + { return E_NOTIMPL; } + +STDMETHODIMP CPhysDriveFolder::Rename(UInt32 /* index */, const wchar_t * /* newName */, IProgress * /* progress */) + { return E_NOTIMPL; } + +STDMETHODIMP CPhysDriveFolder::Delete(const UInt32 * /* indices */, UInt32 /* numItems */, IProgress * /* progress */) + { return E_NOTIMPL; } + +STDMETHODIMP CPhysDriveFolder::SetProperty(UInt32 index, PROPID /* propID */, + const PROPVARIANT * /* value */, IProgress * /* progress */) +{ + if (index >= 1) + return E_INVALIDARG; + return E_NOTIMPL; +} + +HRESULT CPhysDriveFolder::GetLength(UInt64 &length) const +{ + NFile::NDevice::CInFile inFile; + if (!inFile.Open(GetFullPath())) + return GetLastError(); + if (!inFile.GetLengthSmart(length)) + return GetLastError(); + return S_OK; +} + +STDMETHODIMP CPhysDriveFolder::CopyTo(const UInt32 * /* indices */, UInt32 numItems, + const wchar_t *path, IFolderOperationsExtractCallback *callback) +{ + if (numItems == 0) + return S_OK; + UString destPath = path; + if (destPath.IsEmpty()) + return E_INVALIDARG; + bool directName = (destPath[destPath.Length() - 1] != L'\\'); + if (directName) + { + if (numItems > 1) + return E_INVALIDARG; + } + else + destPath += _name; + + UInt64 fileSize; + if (GetLength(fileSize) == S_OK) + { + RINOK(callback->SetTotal(fileSize)); + } + + Int32 writeAskResult; + CMyComBSTR destPathResult; + RINOK(callback->AskWrite(GetFullPath(), BoolToInt(false), NULL, &fileSize, + destPath, &destPathResult, &writeAskResult)); + if (!IntToBool(writeAskResult)) + return S_OK; + + RINOK(callback->SetCurrentFilePath(GetFullPathWithName())); + + NFile::NDevice::CInFile inFile; + if (!inFile.Open(GetFullPath())) + return GetLastError(); + NFile::NIO::COutFile outFile; + if (!outFile.Create(destPathResult, true)) + return GetLastError(); + if (_buffer == 0) + { + _buffer = MyAlloc(kBufferSize); + if (_buffer == 0) + return E_OUTOFMEMORY; + } + UInt64 pos = 0; + UInt32 bufferSize = kBufferSize; + if (_driveType == DRIVE_REMOVABLE) + bufferSize = (18 << 10) * 4; + pos = 0; + while(pos < fileSize) + { + RINOK(callback->SetCompleted(&pos)); + UInt32 curSize = (UInt32)MyMin(fileSize - pos, (UInt64)bufferSize); + UInt32 processedSize; + if (!inFile.Read(_buffer, curSize, processedSize)) + return GetLastError(); + if (processedSize == 0) + break; + curSize = processedSize; + if (!outFile.Write(_buffer, curSize, processedSize)) + return GetLastError(); + if (curSize != processedSize) + return E_FAIL; + pos += curSize; + } + return S_OK; +} + +///////////////////////////////////////////////// +// Move Operations + +STDMETHODIMP CPhysDriveFolder::MoveTo( + const UInt32 * /* indices */, + UInt32 /* numItems */, + const wchar_t * /* path */, + IFolderOperationsExtractCallback * /* callback */) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CPhysDriveFolder::CopyFrom( + const wchar_t * /* fromFolderPath */, + const wchar_t ** /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */) +{ + return E_NOTIMPL; +} diff --git a/CPP/7zip/FileManager/PhysDriveFolder.h b/CPP/7zip/FileManager/PhysDriveFolder.h new file mode 100755 index 00000000..076b0718 --- /dev/null +++ b/CPP/7zip/FileManager/PhysDriveFolder.h @@ -0,0 +1,89 @@ +// PhysDriveFolder.h + +#ifndef __PHYSDRIVEFOLDER_H +#define __PHYSDRIVEFOLDER_H + +#include "Common/String.h" +#include "Common/MyCom.h" + +#include "IFolder.h" + +class CPhysDriveFolder: + public IFolderFolder, + public IEnumProperties, + public IFolderGetTypeID, + public IFolderGetPath, + public IFolderWasChanged, + public IFolderOperations, + public IFolderGetItemFullSize, + public IFolderClone, + // public IFolderGetSystemIconIndex, + public CMyUnknownImp +{ + UInt64 GetSizeOfItem(int anIndex) const; +public: + MY_QUERYINTERFACE_BEGIN + MY_QUERYINTERFACE_ENTRY(IEnumProperties) + MY_QUERYINTERFACE_ENTRY(IFolderGetTypeID) + MY_QUERYINTERFACE_ENTRY(IFolderGetPath) + MY_QUERYINTERFACE_ENTRY(IFolderWasChanged) + MY_QUERYINTERFACE_ENTRY(IFolderOperations) + MY_QUERYINTERFACE_ENTRY(IFolderGetItemFullSize) + MY_QUERYINTERFACE_ENTRY(IFolderClone) + // MY_QUERYINTERFACE_ENTRY(IFolderGetSystemIconIndex) + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + + + STDMETHOD(LoadItems)(); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 itemIndex, PROPID propID, PROPVARIANT *value); + STDMETHOD(BindToFolder)(UInt32 index, IFolderFolder **resultFolder); + STDMETHOD(BindToFolder)(const wchar_t *name, IFolderFolder **resultFolder); + STDMETHOD(BindToParentFolder)(IFolderFolder **resultFolder); + STDMETHOD(GetName)(BSTR *name); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + STDMETHOD(GetTypeID)(BSTR *name); + STDMETHOD(GetPath)(BSTR *path); + STDMETHOD(WasChanged)(INT32 *wasChanged); + STDMETHOD(Clone)(IFolderFolder **resultFolder); + STDMETHOD(GetItemFullSize)(UInt32 index, PROPVARIANT *value, IProgress *progress); + + // IFolderOperations + STDMETHOD(CreateFolder)(const wchar_t *name, IProgress *progress); + STDMETHOD(CreateFile)(const wchar_t *name, IProgress *progress); + STDMETHOD(Rename)(UInt32 index, const wchar_t *newName, IProgress *progress); + STDMETHOD(Delete)(const UInt32 *indices, UInt32 numItems, IProgress *progress); + STDMETHOD(CopyTo)(const UInt32 *indices, UInt32 numItems, + const wchar_t *path, IFolderOperationsExtractCallback *callback); + STDMETHOD(MoveTo)(const UInt32 *indices, UInt32 numItems, + const wchar_t *path, IFolderOperationsExtractCallback *callback); + STDMETHOD(CopyFrom)(const wchar_t *fromFolderPath, + const wchar_t **itemsPaths, UInt32 numItems, IProgress *progress); + STDMETHOD(SetProperty)(UInt32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress); + // STDMETHOD(GetSystemIconIndex)(UInt32 index, INT32 *iconIndex); + +private: + UString _name; + UString _prefix; + UString _path; + UString GetFullPath() const { return _prefix + _path; } + UString GetFullPathWithName() const { return GetFullPath() + L'\\' + _name; } + CMyComPtr _parentFolder; + void *_buffer; + + UINT _driveType; + DISK_GEOMETRY geom; + UInt64 _length; + +public: + HRESULT Init(const UString &path); + HRESULT GetLength(UInt64 &size) const; + CPhysDriveFolder(): _buffer(0) {} + ~CPhysDriveFolder(); +}; + +#endif diff --git a/CPP/7zip/FileManager/PluginInterface.h b/CPP/7zip/FileManager/PluginInterface.h new file mode 100755 index 00000000..249f5644 --- /dev/null +++ b/CPP/7zip/FileManager/PluginInterface.h @@ -0,0 +1,42 @@ +// PluginInterface.h + +#ifndef __PLUGININTERFACE_H +#define __PLUGININTERFACE_H + +#include "Common/String.h" + +// {23170F69-40C1-278D-0000-000100010000} +DEFINE_GUID(IID_IInitContextMenu, +0x23170F69, 0x40C1, 0x278D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278D-0000-000100010000") +IInitContextMenu: public IUnknown +{ +public: + STDMETHOD(InitContextMenu)(const wchar_t *aFolder, const wchar_t **aNames, UINT32 aNumFiles) PURE; + +}; + +// {23170F69-40C1-278D-0000-000100020100} +DEFINE_GUID(IID_IPluginOptionsCallback, +0x23170F69, 0x40C1, 0x278D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278D-0000-000100020000") +IPluginOptionsCallback: public IUnknown +{ +public: + STDMETHOD(GetProgramFolderPath)(BSTR *value) PURE; + STDMETHOD(GetProgramPath)(BSTR *value) PURE; + STDMETHOD(GetRegistryCUPath)(BSTR *value) PURE; +}; + +// {23170F69-40C1-278D-0000-000100020000} +DEFINE_GUID(IID_IPluginOptions, +0x23170F69, 0x40C1, 0x278D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278D-0000-000100020000") +IPluginOptions: public IUnknown +{ +public: + STDMETHOD(PluginOptions)(HWND hWnd, IPluginOptionsCallback *callback) PURE; + // STDMETHOD(GetFileExtensions)(BSTR *extensions) PURE; +}; + +#endif diff --git a/CPP/7zip/FileManager/PluginLoader.h b/CPP/7zip/FileManager/PluginLoader.h new file mode 100755 index 00000000..598a874b --- /dev/null +++ b/CPP/7zip/FileManager/PluginLoader.h @@ -0,0 +1,32 @@ +// PluginLoader.h + +#ifndef __PLUGINLOADER_H +#define __PLUGINLOADER_H + +#include "Windows/DLL.h" + +typedef UINT32 (WINAPI * CreateObjectPointer)( + const GUID *clsID, + const GUID *interfaceID, + void **outObject); + +class CPluginLibrary: public NWindows::NDLL::CLibrary +{ +public: + HRESULT CreateManager(REFGUID clsID, IFolderManager **manager) + { + CreateObjectPointer createObject = (CreateObjectPointer) + GetProcAddress("CreateObject"); + if (createObject == NULL) + return GetLastError(); + return createObject(&clsID, &IID_IFolderManager, (void **)manager); + } + HRESULT LoadAndCreateManager(LPCWSTR filePath, REFGUID clsID, IFolderManager **manager) + { + if (!Load(filePath)) + return GetLastError(); + return CreateManager(clsID, manager); + } +}; + +#endif diff --git a/CPP/7zip/FileManager/ProgramLocation.cpp b/CPP/7zip/FileManager/ProgramLocation.cpp new file mode 100755 index 00000000..88c18d5e --- /dev/null +++ b/CPP/7zip/FileManager/ProgramLocation.cpp @@ -0,0 +1,24 @@ +// ProgramLocation.h + +#include "StdAfx.h" + +#include "ProgramLocation.h" + +#include "Windows/FileName.h" +#include "Windows/DLL.h" + +using namespace NWindows; + +extern HINSTANCE g_hInstance; + +bool GetProgramFolderPath(UString &folder) +{ + if (!NDLL::MyGetModuleFileName(g_hInstance, folder)) + return false; + int pos = folder.ReverseFind(L'\\'); + if (pos < 0) + return false; + folder = folder.Left(pos + 1); + return true; +} + diff --git a/CPP/7zip/FileManager/ProgramLocation.h b/CPP/7zip/FileManager/ProgramLocation.h new file mode 100755 index 00000000..8a8dcf7d --- /dev/null +++ b/CPP/7zip/FileManager/ProgramLocation.h @@ -0,0 +1,10 @@ +// ProgramLocation.h + +#ifndef __PROGRAMLOCATION_H +#define __PROGRAMLOCATION_H + +#include "Common/String.h" + +bool GetProgramFolderPath(UString &folder); // normalized + +#endif diff --git a/CPP/7zip/FileManager/PropertyName.cpp b/CPP/7zip/FileManager/PropertyName.cpp new file mode 100755 index 00000000..848a8855 --- /dev/null +++ b/CPP/7zip/FileManager/PropertyName.cpp @@ -0,0 +1,74 @@ +// PropertyName.cpp + +#include "StdAfx.h" + +#include "../PropID.h" +#include "Windows/ResourceString.h" +#include "resource.h" +#include "PropertyName.h" +#include "Resource/PropertyName/resource.h" +#include "LangUtils.h" + +struct CPropertyIDNamePair +{ + PROPID PropID; + UINT ResourceID; + UINT LangID; +}; + +static CPropertyIDNamePair kPropertyIDNamePairs[] = +{ + { kpidPath, IDS_PROPERTY_PATH, 0x02000203 }, + { kpidName, IDS_PROPERTY_NAME, 0x02000204 }, + // { kpidExtension, L"Extension" }, + { kpidIsFolder, IDS_PROPERTY_IS_FOLDER, 0x02000206}, + { kpidSize, IDS_PROPERTY_SIZE, 0x02000207}, + { kpidPackedSize, IDS_PROPERTY_PACKED_SIZE, 0x02000208 }, + { kpidAttributes, IDS_PROPERTY_ATTRIBUTES, 0x02000209 }, + { kpidCreationTime, IDS_PROPERTY_CREATION_TIME, 0x0200020A }, + { kpidLastAccessTime, IDS_PROPERTY_LAST_ACCESS_TIME, 0x0200020B }, + { kpidLastWriteTime, IDS_PROPERTY_LAST_WRITE_TIME, 0x0200020C }, + { kpidSolid, IDS_PROPERTY_SOLID, 0x0200020D }, + { kpidCommented, IDS_PROPERTY_C0MMENTED, 0x0200020E }, + { kpidEncrypted, IDS_PROPERTY_ENCRYPTED, 0x0200020F }, + { kpidSplitBefore, IDS_PROPERTY_SPLIT_BEFORE, 0x02000210 }, + { kpidSplitAfter, IDS_PROPERTY_SPLIT_AFTER, 0x02000211 }, + { kpidDictionarySize, IDS_PROPERTY_DICTIONARY_SIZE, 0x02000212 }, + { kpidCRC, IDS_PROPERTY_CRC, 0x02000213 }, + { kpidType, IDS_PROPERTY_FILE_TYPE, 0x02000214}, + { kpidIsAnti, IDS_PROPERTY_ANTI, 0x02000215 }, + { kpidMethod, IDS_PROPERTY_METHOD, 0x02000216 }, + { kpidHostOS, IDS_PROPERTY_HOST_OS, 0x02000217 }, + { kpidFileSystem, IDS_PROPERTY_FILE_SYSTEM, 0x02000218}, + { kpidUser, IDS_PROPERTY_USER, 0x02000219}, + { kpidGroup, IDS_PROPERTY_GROUP, 0x0200021A}, + { kpidBlock, IDS_PROPERTY_BLOCK, 0x0200021B }, + { kpidComment, IDS_PROPERTY_COMMENT, 0x0200021C }, + { kpidPosition, IDS_PROPERTY_POSITION, 0x0200021D }, + { kpidPrefix, IDS_PROPERTY_PREFIX, 0x0200021E }, + + { kpidTotalSize, IDS_PROPERTY_TOTAL_SIZE, 0x03031100 }, + { kpidFreeSpace, IDS_PROPERTY_FREE_SPACE, 0x03031101 }, + { kpidClusterSize, IDS_PROPERTY_CLUSTER_SIZE, 0x03031102}, + { kpidVolumeName, IDS_PROPERTY_VOLUME_NAME, 0x03031103 }, + + { kpidLocalName, IDS_PROPERTY_LOCAL_NAME, 0x03031200 }, + { kpidProvider, IDS_PROPERTY_PROVIDER, 0x03031201 } +}; + +int FindProperty(PROPID propID) +{ + for (int i = 0; i < sizeof(kPropertyIDNamePairs) / sizeof(kPropertyIDNamePairs[0]); i++) + if(kPropertyIDNamePairs[i].PropID == propID) + return i; + return -1; +} + +UString GetNameOfProperty(PROPID propID) +{ + int index = FindProperty(propID); + if (index < 0) + return UString(); + const CPropertyIDNamePair &pair = kPropertyIDNamePairs[index]; + return LangString(pair.ResourceID, pair.LangID); +} diff --git a/CPP/7zip/FileManager/PropertyName.h b/CPP/7zip/FileManager/PropertyName.h new file mode 100755 index 00000000..c99fe933 --- /dev/null +++ b/CPP/7zip/FileManager/PropertyName.h @@ -0,0 +1,10 @@ +// PropertyName.h + +#ifndef __PROPERTYNAME_H +#define __PROPERTYNAME_H + +#include "Common/String.h" + +UString GetNameOfProperty(PROPID propID); + +#endif diff --git a/CPP/7zip/FileManager/RegistryAssociations.cpp b/CPP/7zip/FileManager/RegistryAssociations.cpp new file mode 100755 index 00000000..b4b35c67 --- /dev/null +++ b/CPP/7zip/FileManager/RegistryAssociations.cpp @@ -0,0 +1,270 @@ +// RegistryAssociations.cpp + +#include "StdAfx.h" + +#include "RegistryAssociations.h" + +#include "Common/StringConvert.h" + +#include "Windows/COM.h" +#include "Windows/Synchronization.h" +#include "Windows/Registry.h" + +#include "Windows/FileName.h" + +#include "StringUtils.h" + +using namespace NWindows; +using namespace NCOM; +using namespace NRegistry; + + +namespace NRegistryAssociations { + +static NSynchronization::CCriticalSection g_CriticalSection; + +static const TCHAR *kCUKeyPath = TEXT("Software\\7-ZIP\\FM"); +static const TCHAR *kAssociations = TEXT("Associations"); +static const WCHAR *kExtPlugins = L"Plugins"; +static const TCHAR *kExtEnabled = TEXT("Enabled"); + +static CSysString GetAssociationsPath() +{ + return CSysString(kCUKeyPath) + CSysString('\\') + CSysString(kAssociations); +} + +bool ReadInternalAssociation(const wchar_t *ext, CExtInfo &extInfo) +{ + NSynchronization::CCriticalSectionLock lock(g_CriticalSection); + CKey key; + if(key.Open(HKEY_CURRENT_USER, GetAssociationsPath() + CSysString('\\') + + CSysString(GetSystemString(ext)), KEY_READ) != ERROR_SUCCESS) + return false; + UString pluginsString; + key.QueryValue(kExtPlugins, pluginsString); + SplitString(pluginsString, extInfo.Plugins); + return true; +} + +void ReadInternalAssociations(CObjectVector &items) +{ + items.Clear(); + NSynchronization::CCriticalSectionLock lock(g_CriticalSection); + CKey associationsKey; + if(associationsKey.Open(HKEY_CURRENT_USER, GetAssociationsPath(), KEY_READ) != ERROR_SUCCESS) + return; + CSysStringVector extNames; + associationsKey.EnumKeys(extNames); + for(int i = 0; i < extNames.Size(); i++) + { + const CSysString extName = extNames[i]; + CExtInfo extInfo; + // extInfo.Enabled = false; + extInfo.Ext = GetUnicodeString(extName); + CKey key; + if(key.Open(associationsKey, extName, KEY_READ) != ERROR_SUCCESS) + return; + UString pluginsString; + key.QueryValue(kExtPlugins, pluginsString); + SplitString(pluginsString, extInfo.Plugins); + /* + if (key.QueryValue(kExtEnabled, extInfo.Enabled) != ERROR_SUCCESS) + extInfo.Enabled = false; + */ + items.Add(extInfo); + } +} + +void WriteInternalAssociations(const CObjectVector &items) +{ + NSynchronization::CCriticalSectionLock lock(g_CriticalSection); + CKey mainKey; + mainKey.Create(HKEY_CURRENT_USER, kCUKeyPath); + mainKey.RecurseDeleteKey(kAssociations); + CKey associationsKey; + associationsKey.Create(mainKey, kAssociations); + for(int i = 0; i < items.Size(); i++) + { + const CExtInfo &extInfo = items[i]; + CKey key; + key.Create(associationsKey, GetSystemString(extInfo.Ext)); + key.SetValue(kExtPlugins, JoinStrings(extInfo.Plugins)); + // key.SetValue(kExtEnabled, extInfo.Enabled); + } +} + +/////////////////////////////////// +// External + +static const TCHAR *kShellNewKeyName = TEXT("ShellNew"); +static const TCHAR *kShellNewDataValueName = TEXT("Data"); + +static const TCHAR *kDefaultIconKeyName = TEXT("DefaultIcon"); +static const TCHAR *kShellKeyName = TEXT("shell"); +static const TCHAR *kOpenKeyName = TEXT("open"); +static const TCHAR *kCommandKeyName = TEXT("command"); + +static CSysString GetExtensionKeyName(const CSysString &extension) +{ + return CSysString(TEXT(".")) + extension; +} + +static CSysString GetExtProgramKeyName(const CSysString &extension) +{ + return CSysString(TEXT("7-Zip.")) + extension; +} + +static bool CheckShellExtensionInfo2(const CSysString &extension) +{ + NSynchronization::CCriticalSectionLock lock(g_CriticalSection); + CKey extKey; + if (extKey.Open(HKEY_CLASSES_ROOT, GetExtensionKeyName(extension), KEY_READ) != ERROR_SUCCESS) + return false; + CSysString programNameValue; + if (extKey.QueryValue(NULL, programNameValue) != ERROR_SUCCESS) + return false; + CSysString extProgramKeyName = GetExtProgramKeyName(extension); + return (programNameValue.CompareNoCase(extProgramKeyName) == 0); +} + +bool CheckShellExtensionInfo(const CSysString &extension) +{ + NSynchronization::CCriticalSectionLock lock(g_CriticalSection); + if (!CheckShellExtensionInfo2(extension)) + return false; + CKey extProgKey; + return (extProgKey.Open(HKEY_CLASSES_ROOT, GetExtProgramKeyName(extension), KEY_READ) == ERROR_SUCCESS); +} + +static void DeleteShellExtensionKey(const CSysString &extension) +{ + NSynchronization::CCriticalSectionLock lock(g_CriticalSection); + CKey rootKey; + rootKey.Attach(HKEY_CLASSES_ROOT); + rootKey.RecurseDeleteKey(GetExtensionKeyName(extension)); + rootKey.Detach(); +} + +static void DeleteShellExtensionProgramKey(const CSysString &extension) +{ + NSynchronization::CCriticalSectionLock lock(g_CriticalSection); + CKey rootKey; + rootKey.Attach(HKEY_CLASSES_ROOT); + rootKey.RecurseDeleteKey(GetExtProgramKeyName(extension)); + rootKey.Detach(); +} + +void DeleteShellExtensionInfo(const CSysString &extension) +{ + if (CheckShellExtensionInfo2(extension)) + DeleteShellExtensionKey(extension); + DeleteShellExtensionProgramKey(extension); +} + +void AddShellExtensionInfo(const CSysString &extension, + const UString &programTitle, + const UString &programOpenCommand, + const UString &iconPath, + const void *shellNewData, int shellNewDataSize) +{ + DeleteShellExtensionKey(extension); + DeleteShellExtensionProgramKey(extension); + NSynchronization::CCriticalSectionLock lock(g_CriticalSection); + CSysString programKeyName = GetExtProgramKeyName(extension); + { + CKey extKey; + extKey.Create(HKEY_CLASSES_ROOT, GetExtensionKeyName(extension)); + extKey.SetValue(NULL, programKeyName); + if (shellNewData != NULL) + { + CKey shellNewKey; + shellNewKey.Create(extKey, kShellNewKeyName); + shellNewKey.SetValue(kShellNewDataValueName, shellNewData, shellNewDataSize); + } + } + CKey programKey; + programKey.Create(HKEY_CLASSES_ROOT, programKeyName); + programKey.SetValue(NULL, programTitle); + { + CKey iconKey; + iconKey.Create(programKey, kDefaultIconKeyName); + iconKey.SetValue(NULL, iconPath); + } + + CKey shellKey; + shellKey.Create(programKey, kShellKeyName); + shellKey.SetValue(NULL, TEXT("")); + + CKey openKey; + openKey.Create(shellKey, kOpenKeyName); + openKey.SetValue(NULL, TEXT("")); + + CKey commandKey; + commandKey.Create(openKey, kCommandKeyName); + + commandKey.SetValue(NULL, programOpenCommand); +} + +/////////////////////////// +// ContextMenu +/* + +static const TCHAR *kContextMenuKeyName = TEXT("\\shellex\\ContextMenuHandlers\\7-ZIP"); +static const TCHAR *kContextMenuHandlerCLASSIDValue = + TEXT("{23170F69-40C1-278A-1000-000100020000}"); +static const TCHAR *kRootKeyNameForFile = TEXT("*"); +static const TCHAR *kRootKeyNameForFolder = TEXT("Folder"); + +static CSysString GetFullContextMenuKeyName(const CSysString &aKeyName) + { return (aKeyName + kContextMenuKeyName); } + +static bool CheckContextMenuHandlerCommon(const CSysString &aKeyName) +{ + NSynchronization::CCriticalSectionLock lock(&g_CriticalSection, true); + CKey aKey; + if (aKey.Open(HKEY_CLASSES_ROOT, GetFullContextMenuKeyName(aKeyName), KEY_READ) + != ERROR_SUCCESS) + return false; + CSysString aValue; + if (aKey.QueryValue(NULL, aValue) != ERROR_SUCCESS) + return false; + return (aValue.CompareNoCase(kContextMenuHandlerCLASSIDValue) == 0); +} + +bool CheckContextMenuHandler() +{ + return CheckContextMenuHandlerCommon(kRootKeyNameForFile) && + CheckContextMenuHandlerCommon(kRootKeyNameForFolder); +} + +static void DeleteContextMenuHandlerCommon(const CSysString &aKeyName) +{ + CKey rootKey; + rootKey.Attach(HKEY_CLASSES_ROOT); + rootKey.RecurseDeleteKey(GetFullContextMenuKeyName(aKeyName)); + rootKey.Detach(); +} + +void DeleteContextMenuHandler() +{ + DeleteContextMenuHandlerCommon(kRootKeyNameForFile); + DeleteContextMenuHandlerCommon(kRootKeyNameForFolder); +} + +static void AddContextMenuHandlerCommon(const CSysString &aKeyName) +{ + DeleteContextMenuHandlerCommon(aKeyName); + NSynchronization::CCriticalSectionLock lock(&g_CriticalSection, true); + CKey aKey; + aKey.Create(HKEY_CLASSES_ROOT, GetFullContextMenuKeyName(aKeyName)); + aKey.SetValue(NULL, kContextMenuHandlerCLASSIDValue); +} + +void AddContextMenuHandler() +{ + AddContextMenuHandlerCommon(kRootKeyNameForFile); + AddContextMenuHandlerCommon(kRootKeyNameForFolder); +} +*/ + +} diff --git a/CPP/7zip/FileManager/RegistryAssociations.h b/CPP/7zip/FileManager/RegistryAssociations.h new file mode 100755 index 00000000..c225aca4 --- /dev/null +++ b/CPP/7zip/FileManager/RegistryAssociations.h @@ -0,0 +1,45 @@ +// RegistryAssociations.h + +#ifndef __REGISTRYASSOCIATIONS_H +#define __REGISTRYASSOCIATIONS_H + +#include "Common/String.h" +#include "Common/Vector.h" + +namespace NRegistryAssociations { + + struct CExtInfo + { + UString Ext; + UStringVector Plugins; + // bool Enabled; + }; + bool ReadInternalAssociation(const wchar_t *ext, CExtInfo &extInfo); + void ReadInternalAssociations(CObjectVector &items); + void WriteInternalAssociations(const CObjectVector &items); + + bool CheckShellExtensionInfo(const CSysString &extension); + + // void ReadCompressionInfo(NZipSettings::NCompression::CInfo &anInfo, + void DeleteShellExtensionInfo(const CSysString &extension); + + void AddShellExtensionInfo(const CSysString &extension, + const UString &programTitle, + const UString &programOpenCommand, + const UString &iconPath, + const void *shellNewData, int shellNewDataSize); + + + /////////////////////////// + // ContextMenu + /* + bool CheckContextMenuHandler(); + void AddContextMenuHandler(); + void DeleteContextMenuHandler(); + */ + +} + +// bool GetProgramDirPrefix(CSysString &aFolder); + +#endif diff --git a/CPP/7zip/FileManager/RegistryPlugins.cpp b/CPP/7zip/FileManager/RegistryPlugins.cpp new file mode 100755 index 00000000..cad3b43d --- /dev/null +++ b/CPP/7zip/FileManager/RegistryPlugins.cpp @@ -0,0 +1,130 @@ +// RegistryPlugins.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +// #include "Windows/Registry.h" +// #include "Windows/Synchronization.h" +// #include "Windows/COM.h" + +#include "Windows/DLL.h" +#include "Windows/PropVariant.h" +#include "Windows/FileFind.h" + +#include "RegistryPlugins.h" +#include "IFolder.h" + +using namespace NWindows; +using namespace NFile; +// using namespace NRegistry; +// using namespace NCOM; + +/* +static const TCHAR *kLMBasePath = TEXT("Software\\7-Zip\\FM"); + +static const TCHAR *kPluginsKeyName = TEXT("Plugins"); +static const TCHAR *kPluginsOpenClassIDValue = TEXT("CLSID"); +static const TCHAR *kPluginsOptionsClassIDValue = TEXT("Options"); +static const TCHAR *kPluginsTypeValue = TEXT("Type"); + +static CSysString GetFileFolderPluginsKeyName() +{ + return CSysString(kLMBasePath) + CSysString(TEXT('\\')) + + CSysString(kPluginsKeyName); +} + +static NSynchronization::CCriticalSection g_CriticalSection; +*/ +typedef UINT32 (WINAPI * GetPluginPropertyFunc)( + PROPID propID, PROPVARIANT *value); + +static bool ReadPluginInfo(CPluginInfo &pluginInfo) +{ + { + NDLL::CLibrary library; + if (!library.LoadEx(pluginInfo.FilePath, LOAD_LIBRARY_AS_DATAFILE)) + return false; + } + NDLL::CLibrary library; + if (!library.Load(pluginInfo.FilePath)) + return false; + GetPluginPropertyFunc getPluginProperty = (GetPluginPropertyFunc) + library.GetProcAddress("GetPluginProperty"); + if (getPluginProperty == NULL) + return false; + + NCOM::CPropVariant propVariant; + if (getPluginProperty(NPlugin::kName, &propVariant) != S_OK) + return false; + if (propVariant.vt != VT_BSTR) + return false; + pluginInfo.Name = propVariant.bstrVal; + propVariant.Clear(); + + if (getPluginProperty(NPlugin::kClassID, &propVariant) != S_OK) + return false; + if (propVariant.vt != VT_BSTR) + return false; + pluginInfo.ClassID = *(const GUID *)propVariant.bstrVal; + propVariant.Clear(); + + if (getPluginProperty(NPlugin::kOptionsClassID, &propVariant) != S_OK) + return false; + if (propVariant.vt == VT_EMPTY) + pluginInfo.OptionsClassIDDefined = false; + else if (propVariant.vt != VT_BSTR) + return false; + else + { + pluginInfo.OptionsClassIDDefined = true; + pluginInfo.OptionsClassID = *(const GUID *)propVariant.bstrVal; + } + propVariant.Clear(); + + if (getPluginProperty(NPlugin::kType, &propVariant) != S_OK) + return false; + if (propVariant.vt == VT_EMPTY) + pluginInfo.Type = kPluginTypeFF; + else if (propVariant.vt == VT_UI4) + pluginInfo.Type = (EPluginType)propVariant.ulVal; + else + return false; + return true; +} + +UString GetProgramFolderPrefix(); + +void ReadPluginInfoList(CObjectVector &plugins) +{ + plugins.Clear(); + + UString baseFolderPrefix = GetProgramFolderPrefix(); + { + CPluginInfo pluginInfo; + pluginInfo.FilePath = baseFolderPrefix + L"7-zip.dll"; + if (::ReadPluginInfo(pluginInfo)) + plugins.Add(pluginInfo); + } + UString folderPath = baseFolderPrefix + L"Plugins\\"; + NFind::CEnumeratorW enumerator(folderPath + L"*"); + NFind::CFileInfoW fileInfo; + while (enumerator.Next(fileInfo)) + { + if (fileInfo.IsDirectory()) + continue; + CPluginInfo pluginInfo; + pluginInfo.FilePath = folderPath + fileInfo.Name; + if (::ReadPluginInfo(pluginInfo)) + plugins.Add(pluginInfo); + } +} + +void ReadFileFolderPluginInfoList(CObjectVector &plugins) +{ + ReadPluginInfoList(plugins); + for (int i = 0; i < plugins.Size();) + if (plugins[i].Type != kPluginTypeFF) + plugins.Delete(i); + else + i++; +} diff --git a/CPP/7zip/FileManager/RegistryPlugins.h b/CPP/7zip/FileManager/RegistryPlugins.h new file mode 100755 index 00000000..4a30857c --- /dev/null +++ b/CPP/7zip/FileManager/RegistryPlugins.h @@ -0,0 +1,32 @@ +// RegistryPlugins.h + +#ifndef __REGISTRYPLUGINS_H +#define __REGISTRYPLUGINS_H + +#include "Common/Vector.h" +#include "Common/String.h" + +enum EPluginType +{ + kPluginTypeFF = 0 +}; + +struct CPluginInfo +{ + UString FilePath; + EPluginType Type; + UString Name; + CLSID ClassID; + CLSID OptionsClassID; + bool OptionsClassIDDefined; + + // CSysString Extension; + // CSysString AddExtension; + // bool UpdateEnabled; + // bool KeepName; +}; + +void ReadPluginInfoList(CObjectVector &plugins); +void ReadFileFolderPluginInfoList(CObjectVector &plugins); + +#endif diff --git a/CPP/7zip/FileManager/RegistryUtils.cpp b/CPP/7zip/FileManager/RegistryUtils.cpp new file mode 100755 index 00000000..22869c46 --- /dev/null +++ b/CPP/7zip/FileManager/RegistryUtils.cpp @@ -0,0 +1,150 @@ +// RegistryUtils.cpp + +#include "StdAfx.h" + +#include "RegistryUtils.h" +#include "Windows/Registry.h" + +using namespace NWindows; +using namespace NRegistry; + +static const TCHAR *kCUBasePath = TEXT("Software\\7-ZIP"); +static const TCHAR *kCU_FMPath = TEXT("Software\\7-ZIP\\FM"); +static const TCHAR *kLM_Path = TEXT("Software\\7-ZIP\\FM"); + +static const WCHAR *kLangValueName = L"Lang"; +static const WCHAR *kEditor = L"Editor"; +static const TCHAR *kShowDots = TEXT("ShowDots"); +static const TCHAR *kShowRealFileIcons = TEXT("ShowRealFileIcons"); +static const TCHAR *kShowSystemMenu = TEXT("ShowSystemMenu"); + +static const TCHAR *kFullRow = TEXT("FullRow"); +static const TCHAR *kShowGrid = TEXT("ShowGrid"); +static const TCHAR *kAlternativeSelection = TEXT("AlternativeSelection"); +static const TCHAR *kLockMemoryAdd = TEXT("LockMemoryAdd"); +static const TCHAR *kLargePagesEnable = TEXT("LargePages"); +// static const TCHAR *kSingleClick = TEXT("SingleClick"); +// static const TCHAR *kUnderline = TEXT("Underline"); + +void SaveRegLang(const UString &langFile) +{ + CKey key; + key.Create(HKEY_CURRENT_USER, kCUBasePath); + key.SetValue(kLangValueName, langFile); +} + +void ReadRegLang(UString &langFile) +{ + langFile.Empty(); + CKey key; + if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) == ERROR_SUCCESS) + key.QueryValue(kLangValueName, langFile); +} + +void SaveRegEditor(const UString &editorPath) +{ + CKey key; + key.Create(HKEY_CURRENT_USER, kCU_FMPath); + key.SetValue(kEditor, editorPath); +} + +void ReadRegEditor(UString &editorPath) +{ + editorPath.Empty(); + CKey key; + if (key.Open(HKEY_CURRENT_USER, kCU_FMPath, KEY_READ) == ERROR_SUCCESS) + key.QueryValue(kEditor, editorPath); +} + +static void Save7ZipOption(const TCHAR *value, bool enabled) +{ + CKey key; + key.Create(HKEY_CURRENT_USER, kCUBasePath); + key.SetValue(value, enabled); +} + +static void SaveOption(const TCHAR *value, bool enabled) +{ + CKey key; + key.Create(HKEY_CURRENT_USER, kCU_FMPath); + key.SetValue(value, enabled); +} + +static bool Read7ZipOption(const TCHAR *value, bool defaultValue) +{ + CKey key; + if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) == ERROR_SUCCESS) + { + bool enabled; + if (key.QueryValue(value, enabled) == ERROR_SUCCESS) + return enabled; + } + return defaultValue; +} + +static bool ReadOption(const TCHAR *value, bool defaultValue) +{ + CKey key; + if (key.Open(HKEY_CURRENT_USER, kCU_FMPath, KEY_READ) == ERROR_SUCCESS) + { + bool enabled; + if (key.QueryValue(value, enabled) == ERROR_SUCCESS) + return enabled; + } + return defaultValue; +} + +/* +static void SaveLmOption(const TCHAR *value, bool enabled) +{ + CKey key; + key.Create(HKEY_LOCAL_MACHINE, kLM_Path); + key.SetValue(value, enabled); +} + +static bool ReadLmOption(const TCHAR *value, bool defaultValue) +{ + CKey key; + if (key.Open(HKEY_LOCAL_MACHINE, kLM_Path, KEY_READ) == ERROR_SUCCESS) + { + bool enabled; + if (key.QueryValue(value, enabled) == ERROR_SUCCESS) + return enabled; + } + return defaultValue; +} +*/ + +void SaveShowDots(bool showDots) { SaveOption(kShowDots, showDots); } +bool ReadShowDots() { return ReadOption(kShowDots, false); } + +void SaveShowRealFileIcons(bool show) { SaveOption(kShowRealFileIcons, show); } +bool ReadShowRealFileIcons() { return ReadOption(kShowRealFileIcons, false); } + +void SaveShowSystemMenu(bool show) { SaveOption(kShowSystemMenu, show); } +bool ReadShowSystemMenu(){ return ReadOption(kShowSystemMenu, false); } + +void SaveFullRow(bool enable) { SaveOption(kFullRow, enable); } +bool ReadFullRow() { return ReadOption(kFullRow, false); } + +void SaveShowGrid(bool enable) { SaveOption(kShowGrid, enable); } +bool ReadShowGrid(){ return ReadOption(kShowGrid, false); } + +void SaveAlternativeSelection(bool enable) { SaveOption(kAlternativeSelection, enable); } +bool ReadAlternativeSelection(){ return ReadOption(kAlternativeSelection, false); } + +/* +void SaveSingleClick(bool enable) { SaveOption(kSingleClick, enable); } +bool ReadSingleClick(){ return ReadOption(kSingleClick, false); } + +void SaveUnderline(bool enable) { SaveOption(kUnderline, enable); } +bool ReadUnderline(){ return ReadOption(kUnderline, false); } +*/ + +// void SaveLockMemoryAdd(bool enable) { SaveLmOption(kLockMemoryAdd, enable); } +// bool ReadLockMemoryAdd() { return ReadLmOption(kLockMemoryAdd, true); } + +void SaveLockMemoryEnable(bool enable) { Save7ZipOption(kLargePagesEnable, enable); } +bool ReadLockMemoryEnable() { return Read7ZipOption(kLargePagesEnable, false); } + + diff --git a/CPP/7zip/FileManager/RegistryUtils.h b/CPP/7zip/FileManager/RegistryUtils.h new file mode 100755 index 00000000..0fec6f80 --- /dev/null +++ b/CPP/7zip/FileManager/RegistryUtils.h @@ -0,0 +1,46 @@ +// RegistryUtils.h + +#include "Common/StringConvert.h" + +#ifndef __REGISTRYUTILS_H +#define __REGISTRYUTILS_H + +void SaveRegLang(const UString &langFile); +void ReadRegLang(UString &langFile); + +void SaveRegEditor(const UString &editorPath); +void ReadRegEditor(UString &editorPath); + +void SaveShowDots(bool showDots); +bool ReadShowDots(); + +void SaveShowRealFileIcons(bool show); +bool ReadShowRealFileIcons(); + +void SaveShowSystemMenu(bool showSystemMenu); +bool ReadShowSystemMenu(); + +void SaveFullRow(bool enable); +bool ReadFullRow(); + +void SaveShowGrid(bool enable); +bool ReadShowGrid(); + +void SaveAlternativeSelection(bool enable); +bool ReadAlternativeSelection(); + +// void SaveLockMemoryAdd(bool enable); +// bool ReadLockMemoryAdd(); + +bool ReadLockMemoryEnable(); +void SaveLockMemoryEnable(bool enable); + +/* +void SaveSingleClick(bool enable); +bool ReadSingleClick(); + +void SaveUnderline(bool enable); +bool ReadUnderline(); +*/ + +#endif diff --git a/CPP/7zip/FileManager/Resource/AboutDialog/7zipLogo.ico b/CPP/7zip/FileManager/Resource/AboutDialog/7zipLogo.ico new file mode 100755 index 00000000..973241c8 Binary files /dev/null and b/CPP/7zip/FileManager/Resource/AboutDialog/7zipLogo.ico differ diff --git a/CPP/7zip/FileManager/Resource/AboutDialog/AboutDialog.cpp b/CPP/7zip/FileManager/Resource/AboutDialog/AboutDialog.cpp new file mode 100755 index 00000000..e4dd2313 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/AboutDialog/AboutDialog.cpp @@ -0,0 +1,60 @@ +// AboutDialog.cpp + +#include "StdAfx.h" + +#include "resource.h" +#include "AboutDialog.h" +#include "../../HelpUtils.h" +#include "../../LangUtils.h" + +static CIDLangPair kIDLangPairs[] = +{ + { IDC_ABOUT_STATIC_REGISTER_INFO, 0x01000103 }, + { IDC_ABOUT_BUTTON_SUPPORT, 0x01000104 }, + { IDC_ABOUT_BUTTON_REGISTER, 0x01000105 }, + { IDOK, 0x02000702 } +}; + +#define MY_HOME_PAGE TEXT("http://www.7-zip.org/") + +static LPCTSTR kHomePageURL = MY_HOME_PAGE; +static LPCTSTR kRegisterPageURL = MY_HOME_PAGE TEXT("register.html"); +static LPCTSTR kSupportPageURL = MY_HOME_PAGE TEXT("support.html"); + +static LPCWSTR kHelpTopic = L"start.htm"; + +bool CAboutDialog::OnInit() +{ + LangSetWindowText(HWND(*this), 0x01000100); + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + return CModalDialog::OnInit(); +} + +void CAboutDialog::OnHelp() +{ + ShowHelpWindow(NULL, kHelpTopic); +} + +static void MyShellExecute(LPCTSTR url) +{ + ::ShellExecute(NULL, NULL, url, NULL, NULL, SW_SHOWNORMAL); +} + +bool CAboutDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) + { + case IDC_ABOUT_BUTTON_HOMEPAGE: + ::MyShellExecute(kHomePageURL); + break; + case IDC_ABOUT_BUTTON_REGISTER: + ::MyShellExecute(kRegisterPageURL); + break; + case IDC_ABOUT_BUTTON_SUPPORT: + ::MyShellExecute(kSupportPageURL); + break; + default: + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); + } + return true; +} diff --git a/CPP/7zip/FileManager/Resource/AboutDialog/AboutDialog.h b/CPP/7zip/FileManager/Resource/AboutDialog/AboutDialog.h new file mode 100755 index 00000000..278d7c82 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/AboutDialog/AboutDialog.h @@ -0,0 +1,18 @@ +// AboutDialog.h + +#ifndef __ABOUTDIALOG_H +#define __ABOUTDIALOG_H + +#include "resource.h" +#include "Windows/Control/Dialog.h" + +class CAboutDialog: public NWindows::NControl::CModalDialog +{ +public: + virtual bool OnInit(); + virtual void OnHelp(); + virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); + INT_PTR Create(HWND wndParent = 0) { return CModalDialog::Create(IDD_ABOUT, wndParent); } +}; + +#endif diff --git a/CPP/7zip/FileManager/Resource/AboutDialog/StdAfx.h b/CPP/7zip/FileManager/Resource/AboutDialog/StdAfx.h new file mode 100755 index 00000000..a444ca31 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/AboutDialog/StdAfx.h @@ -0,0 +1,16 @@ +// stdafx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#define _WIN32_WINNT 0x0400 + +// it's for Windows NT supporting (MENUITEMINFOW) +#define WINVER 0x0400 + +#include +#include + +#include "Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/FileManager/Resource/AboutDialog/resource.h b/CPP/7zip/FileManager/Resource/AboutDialog/resource.h new file mode 100755 index 00000000..54475484 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/AboutDialog/resource.h @@ -0,0 +1,6 @@ +#define IDD_ABOUT 100 +#define IDI_LOGO 138 +#define IDC_ABOUT_STATIC_REGISTER_INFO 1010 +#define IDC_ABOUT_BUTTON_HOMEPAGE 1020 +#define IDC_ABOUT_BUTTON_SUPPORT 1021 +#define IDC_ABOUT_BUTTON_REGISTER 1022 diff --git a/CPP/7zip/FileManager/Resource/AboutDialog/resource.rc b/CPP/7zip/FileManager/Resource/AboutDialog/resource.rc new file mode 100755 index 00000000..b93fdd41 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/AboutDialog/resource.rc @@ -0,0 +1,41 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" +#include "../../../MyVersion.h" + +#define xSize2 224 +#define ySize2 158 +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#define bXPos (xSize - marg - bXSize) +#define bYPos (ySize - marg - bYSize) + +#undef b2XSize +#undef b2XPos +#undef infoYPos +#undef infoYSize + +#define b2XSize 94 +#define b2XPos (xSize - marg - b2XSize) +#define gSpace 2 +#define gSize (xSize2 - gSpace - b2XSize) + +#define infoYPos 91 +#define infoYSize (ySize2 - infoYPos - bYSize - 2) + +IDI_LOGO ICON "7zipLogo.ico" + +IDD_ABOUT DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE +CAPTION "About 7-Zip" +MY_FONT +BEGIN + PUSHBUTTON "OK", IDOK, bXPos, bYPos, bXSize, bYSize + PUSHBUTTON "www.7-zip.org", IDC_ABOUT_BUTTON_HOMEPAGE, b2XPos, 7, b2XSize, bYSize + PUSHBUTTON "Support", IDC_ABOUT_BUTTON_SUPPORT, b2XPos, 30, b2XSize, bYSize + PUSHBUTTON "Register", IDC_ABOUT_BUTTON_REGISTER, b2XPos, 53, b2XSize, bYSize + ICON IDI_LOGO, -1, marg, marg, 20, 20, SS_REALSIZEIMAGE + LTEXT MY_7ZIP_VERSION, -1, marg, 54, gSize, 9 + LTEXT MY_COPYRIGHT, -1, marg, 67, gSize, 17 + LTEXT "7-Zip is free software. However, you can support development of 7-Zip by registering.", + IDC_ABOUT_STATIC_REGISTER_INFO, marg, infoYPos, xSize2, infoYSize +END diff --git a/CPP/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp b/CPP/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp new file mode 100755 index 00000000..1083fc4c --- /dev/null +++ b/CPP/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp @@ -0,0 +1,976 @@ +// BenchmarkDialog.cpp + +#include "StdAfx.h" + +#include "Common/IntToString.h" +#include "Common/StringToInt.h" +#include "Common/Exception.h" +#include "Common/Alloc.h" +#include "Windows/Thread.h" +#include "Windows/PropVariant.h" +#include "Windows/Error.h" +#include "Windows/DLL.h" +#include "Windows/FileFind.h" +#include "../../ProgramLocation.h" +#include "../../HelpUtils.h" +#include "../../../Common/StreamObjects.h" +#include "resource.h" +#include "BenchmarkDialog.h" +#include "Common/CRC.h" + +using namespace NWindows; + +static LPCWSTR kHelpTopic = L"fm/benchmark.htm"; + +static const UINT_PTR kTimerID = 4; +static const UINT kTimerElapse = 1000; + +static const UInt32 kAdditionalSize = (6 << 20); +static const UInt32 kCompressedAdditionalSize = (1 << 10); +static const int kSubBits = 8; + +#ifdef LANG +#include "../../LangUtils.h" +#endif + +using namespace NWindows; + +#ifdef LANG +static CIDLangPair kIDLangPairs[] = +{ + { IDC_BENCHMARK_DICTIONARY, 0x02000D0C }, + { IDC_BENCHMARK_MEMORY, 0x03080001 }, + { IDC_BENCHMARK_MULTITHREADING, 0x02000D09 }, + { IDC_BENCHMARK_SPEED_LABEL, 0x03080004 }, + { IDC_BENCHMARK_RATING_LABEL, 0x03080005 }, + { IDC_BENCHMARK_COMPRESSING, 0x03080002 }, + { IDC_BENCHMARK_DECOMPRESSING, 0x03080003 }, + { IDC_BENCHMARK_CURRENT, 0x03080007 }, + { IDC_BENCHMARK_RESULTING, 0x03080008 }, + { IDC_BENCHMARK_CURRENT2, 0x03080007 }, + { IDC_BENCHMARK_RESULTING2, 0x03080008 }, + { IDC_BENCHMARK_TOTAL_RATING, 0x03080006 }, + { IDC_BENCHMARK_ELAPSED, 0x02000C01 }, + { IDC_BENCHMARK_SIZE, 0x02000C03 }, + { IDC_BENCHMARK_PASSES, 0x03080009 }, + { IDC_BENCHMARK_ERRORS, 0x0308000A }, + { IDC_BUTTON_STOP, 0x02000714 }, + { IDC_BUTTON_RESTART, 0x02000715 }, + { IDHELP, 0x02000720 }, + { IDCANCEL, 0x02000710 } +}; +#endif + +static void MyMessageBoxError(HWND hwnd, LPCWSTR message) +{ + MessageBoxW(hwnd, message, L"7-Zip", MB_ICONERROR); +} + +UInt64 GetTimeCount() +{ + return GetTickCount(); + /* + LARGE_INTEGER value; + if (::QueryPerformanceCounter(&value)) + return value.QuadPart; + return GetTickCount(); + */ +} + +UInt64 GetFreq() +{ + return 1000; + /* + LARGE_INTEGER value; + if (::QueryPerformanceFrequency(&value)) + return value.QuadPart; + return 1000; + */ +} + +class CRandomGenerator +{ + UInt32 A1; + UInt32 A2; +public: + CRandomGenerator() { Init(); } + void Init() { A1 = 362436069; A2 = 521288629;} + UInt32 GetRnd() + { + return + ((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) ^ + ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) ); + } +}; + +class CBitRandomGenerator +{ + CRandomGenerator RG; + UInt32 Value; + int NumBits; +public: + void Init() + { + Value = 0; + NumBits = 0; + } + UInt32 GetRnd(int numBits) + { + if (NumBits > numBits) + { + UInt32 result = Value & ((1 << numBits) - 1); + Value >>= numBits; + NumBits -= numBits; + return result; + } + numBits -= NumBits; + UInt32 result = (Value << numBits); + Value = RG.GetRnd(); + result |= Value & ((1 << numBits) - 1); + Value >>= numBits; + NumBits = 32 - numBits; + return result; + } +}; + +class CBenchRandomGenerator +{ + CBitRandomGenerator RG; + UInt32 Pos; + UInt32 Rep0; +public: + UInt32 BufferSize; + Byte *Buffer; + CBenchRandomGenerator(): Buffer(0) {} + ~CBenchRandomGenerator() { Free(); } + void Free() + { + ::MidFree(Buffer); + Buffer = 0; + } + bool Alloc(UInt32 bufferSize) + { + if (Buffer != 0 && BufferSize == bufferSize) + return true; + Free(); + Buffer = (Byte *)::MidAlloc(bufferSize); + Pos = 0; + BufferSize = bufferSize; + return (Buffer != 0); + } + UInt32 GetRndBit() { return RG.GetRnd(1); } + /* + UInt32 GetLogRand(int maxLen) + { + UInt32 len = GetRnd() % (maxLen + 1); + return GetRnd() & ((1 << len) - 1); + } + */ + UInt32 GetLogRandBits(int numBits) + { + UInt32 len = RG.GetRnd(numBits); + return RG.GetRnd(len); + } + UInt32 GetOffset() + { + if (GetRndBit() == 0) + return GetLogRandBits(4); + return (GetLogRandBits(4) << 10) | RG.GetRnd(10); + } + UInt32 GetLen1() { return RG.GetRnd(1 + RG.GetRnd(2)); } + UInt32 GetLen2() { return RG.GetRnd(2 + RG.GetRnd(2)); } + void Generate() + { + RG.Init(); + Rep0 = 1; + while(Pos < BufferSize) + { + if (GetRndBit() == 0 || Pos < 1) + Buffer[Pos++] = Byte(RG.GetRnd(8)); + else + { + UInt32 len; + if (RG.GetRnd(3) == 0) + len = 1 + GetLen1(); + else + { + do + Rep0 = GetOffset(); + while (Rep0 >= Pos); + Rep0++; + len = 2 + GetLen2(); + } + for (UInt32 i = 0; i < len && Pos < BufferSize; i++, Pos++) + Buffer[Pos] = Buffer[Pos - Rep0]; + } + } + } +}; + +const LPCTSTR kProcessingString = TEXT("..."); +const LPCTSTR kMB = TEXT(" MB"); +const LPCTSTR kMIPS = TEXT(" MIPS"); +const LPCTSTR kKBs = TEXT(" KB/s"); + +bool CBenchmarkDialog::OnInit() +{ + #ifdef LANG + LangSetWindowText(HWND(*this), 0x03080000); + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + #endif + + m_Dictionary.Attach(GetItem(IDC_BENCHMARK_COMBO_DICTIONARY)); + for (int i = kNumBenchDictionaryBitsStart; i <= 30; i++) + for (int j = 0; j < 2; j++) + { + UInt32 dictionary = (1 << i) + (j << (i - 1)); + if(dictionary > + #ifdef _WIN64 + (1 << 30) + #else + (1 << 27) + #endif + ) + continue; + TCHAR s[40]; + ConvertUInt64ToString((dictionary >> 20), s); + lstrcat(s, kMB); + int index = (int)m_Dictionary.AddString(s); + m_Dictionary.SetItemData(index, dictionary); + } + m_Dictionary.SetCurSel(0); + OnChangeSettings(); + + _syncInfo.Init(); + _syncInfo.InitSettings(); + + _syncInfo._startEvent.Set(); + _timer = SetTimer(kTimerID, kTimerElapse); + return CModalDialog::OnInit(); +} + +static UInt64 GetLZMAUsage(UInt32 dictionary) +{ + UInt32 hs = dictionary - 1; + hs |= (hs >> 1); + hs |= (hs >> 2); + hs |= (hs >> 4); + hs |= (hs >> 8); + hs >>= 1; + hs |= 0xFFFF; + if (hs > (1 << 24)) + hs >>= 1; + hs++; + return ((hs + (1 << 16)) + (UInt64)dictionary * 2) * 4 + (UInt64)dictionary * 3 / 2 + (1 << 20); +} + +static UInt64 GetMemoryUsage(UInt32 dictionary, bool mtMode) +{ + const UInt32 kBufferSize = dictionary + kAdditionalSize; + const UInt32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize; + return (mtMode ? (6 << 20) : 0 )+ kBufferSize + kCompressedBufferSize + + GetLZMAUsage(dictionary) + dictionary + (2 << 20); +} + +UInt32 CBenchmarkDialog::OnChangeDictionary() +{ + UInt32 dictionary = (UInt32)m_Dictionary.GetItemData(m_Dictionary.GetCurSel()); + UInt64 memUsage = GetMemoryUsage(dictionary, IsButtonCheckedBool(IDC_BENCHMARK_MULTITHREADING)); + memUsage = (memUsage + (1 << 20) - 1) >> 20; + TCHAR s[40]; + ConvertUInt64ToString(memUsage, s); + lstrcat(s, kMB); + SetItemText(IDC_BENCHMARK_MEMORY_VALUE, s); + return dictionary; +} + +void CBenchmarkDialog::OnChangeSettings() +{ + EnableItem(IDC_BUTTON_STOP, true); + UInt32 dictionary = OnChangeDictionary(); + SetItemText(IDC_BENCHMARK_COMPRESSING_SPEED, kProcessingString); + SetItemText(IDC_BENCHMARK_COMPRESSING_SPEED2, kProcessingString); + SetItemText(IDC_BENCHMARK_COMPRESSING_RATING, kProcessingString); + SetItemText(IDC_BENCHMARK_COMPRESSING_RATING2, kProcessingString); + SetItemText(IDC_BENCHMARK_DECOMPRESSING_SPEED, kProcessingString); + SetItemText(IDC_BENCHMARK_DECOMPRESSING_SPEED2, kProcessingString); + SetItemText(IDC_BENCHMARK_DECOMPRESSING_RATING, kProcessingString); + SetItemText(IDC_BENCHMARK_DECOMPRESSING_RATING2, kProcessingString); + SetItemText(IDC_BENCHMARK_TOTAL_RATING_VALUE, kProcessingString); + _startTime = GetTickCount(); + PrintTime(); + NWindows::NSynchronization::CCriticalSectionLock lock(_syncInfo.CS); + _syncInfo.Init(); + _syncInfo.DictionarySize = dictionary; + _syncInfo.Changed = true; + _syncInfo.MultiThread = IsButtonCheckedBool(IDC_BENCHMARK_MULTITHREADING); +} + +void CBenchmarkDialog::OnRestartButton() +{ + OnChangeSettings(); +} + +void CBenchmarkDialog::OnStopButton() +{ + EnableItem(IDC_BUTTON_STOP, false); + _syncInfo.Pause(); +} + +void CBenchmarkDialog::OnHelp() +{ + ShowHelpWindow(NULL, kHelpTopic); +} + +void CBenchmarkDialog::OnCancel() +{ + _syncInfo.Stop(); + KillTimer(_timer); + CModalDialog::OnCancel(); +} + +static void GetTimeString(UInt64 timeValue, TCHAR *s) +{ + wsprintf(s, TEXT("%02d:%02d:%02d"), + UInt32(timeValue / 3600), + UInt32((timeValue / 60) % 60), + UInt32(timeValue % 60)); +} + +void CBenchmarkDialog::PrintTime() +{ + UInt32 curTime = ::GetTickCount(); + UInt32 elapsedTime = (curTime - _startTime); + UInt32 elapsedSec = elapsedTime / 1000; + TCHAR s[40]; + GetTimeString(elapsedSec, s); + SetItemText(IDC_BENCHMARK_ELAPSED_VALUE, s); +} + +static UInt32 GetLogSize(UInt32 size) +{ + for (int i = kSubBits; i < 32; i++) + for (UInt32 j = 0; j < (1 << kSubBits); j++) + if (size <= (((UInt32)1) << i) + (j << (i - kSubBits))) + return (i << kSubBits) + j; + return (32 << kSubBits); +} + +static UInt64 GetCompressRating(UInt32 dictionarySize, + UInt64 elapsedTime, UInt64 size) +{ + if (elapsedTime == 0) + elapsedTime = 1; + UInt64 t = GetLogSize(dictionarySize) - (18 << kSubBits); + UInt64 numCommandsForOne = 1060 + ((t * t * 10) >> (2 * kSubBits)); + UInt64 numCommands = (UInt64)(size) * numCommandsForOne; + return numCommands * GetFreq() / elapsedTime; +} + +static UInt64 GetDecompressRating(UInt64 elapsedTime, + UInt64 outSize, UInt64 inSize) +{ + if (elapsedTime == 0) + elapsedTime = 1; + UInt64 numCommands = inSize * 220 + outSize * 20; + return numCommands * GetFreq() / elapsedTime; +} + +static UInt64 GetTotalRating( + UInt32 dictionarySize, + UInt64 elapsedTimeEn, UInt64 sizeEn, + UInt64 elapsedTimeDe, + UInt64 inSizeDe, UInt64 outSizeDe) +{ + return (GetCompressRating(dictionarySize, elapsedTimeEn, sizeEn) + + GetDecompressRating(elapsedTimeDe, inSizeDe, outSizeDe)) / 2; +} + +void CBenchmarkDialog::PrintRating(UInt64 rating, UINT controlID) +{ + TCHAR s[40]; + ConvertUInt64ToString(rating / 1000000, s); + lstrcat(s, kMIPS); + SetItemText(controlID, s); +} + +void CBenchmarkDialog::PrintResults( + UInt32 dictionarySize, + UInt64 elapsedTime, + UInt64 size, UINT speedID, UINT ratingID, + bool decompressMode, UInt64 secondSize) +{ + TCHAR s[40]; + UInt64 speed = size * GetFreq() / elapsedTime; + ConvertUInt64ToString(speed / 1024, s); + lstrcat(s, kKBs); + SetItemText(speedID, s); + UInt64 rating; + if (decompressMode) + rating = GetDecompressRating(elapsedTime, size, secondSize); + else + rating = GetCompressRating(dictionarySize, elapsedTime, size); + PrintRating(rating, ratingID); +} + +bool CBenchmarkDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */) +{ + PrintTime(); + NWindows::NSynchronization::CCriticalSectionLock lock(_syncInfo.CS); + + TCHAR s[40]; + ConvertUInt64ToString((_syncInfo.ProcessedSize >> 20), s); + lstrcat(s, kMB); + SetItemText(IDC_BENCHMARK_SIZE_VALUE, s); + + ConvertUInt64ToString(_syncInfo.NumPasses, s); + SetItemText(IDC_BENCHMARK_PASSES_VALUE, s); + + ConvertUInt64ToString(_syncInfo.NumErrors, s); + SetItemText(IDC_BENCHMARK_ERRORS_VALUE, s); + + UInt64 elapsedTime = _syncInfo.CompressingInfoTemp.Time; + if (elapsedTime >= 1) + { + UInt32 dicSizeTemp = (UInt32)MyMax(_syncInfo.ProcessedSize, UInt64(1) << 20); + dicSizeTemp = MyMin(dicSizeTemp, _syncInfo.DictionarySize), + PrintResults(dicSizeTemp, elapsedTime, + _syncInfo.CompressingInfoTemp.InSize, + IDC_BENCHMARK_COMPRESSING_SPEED, + IDC_BENCHMARK_COMPRESSING_RATING); + } + + if (_syncInfo.CompressingInfo.Time >= 1) + { + PrintResults( + _syncInfo.DictionarySize, + _syncInfo.CompressingInfo.Time, + _syncInfo.CompressingInfo.InSize, + IDC_BENCHMARK_COMPRESSING_SPEED2, + IDC_BENCHMARK_COMPRESSING_RATING2); + } + + if (_syncInfo.DecompressingInfoTemp.Time >= 1) + { + PrintResults( + _syncInfo.DictionarySize, + _syncInfo.DecompressingInfoTemp.Time, + _syncInfo.DecompressingInfoTemp.OutSize, + IDC_BENCHMARK_DECOMPRESSING_SPEED, + IDC_BENCHMARK_DECOMPRESSING_RATING, + true, + _syncInfo.DecompressingInfoTemp.InSize); + } + if (_syncInfo.DecompressingInfo.Time >= 1) + { + PrintResults( + _syncInfo.DictionarySize, + _syncInfo.DecompressingInfo.Time, + _syncInfo.DecompressingInfo.OutSize, + IDC_BENCHMARK_DECOMPRESSING_SPEED2, + IDC_BENCHMARK_DECOMPRESSING_RATING2, + true, + _syncInfo.DecompressingInfo.InSize); + if (_syncInfo.CompressingInfo.Time >= 1) + { + PrintRating(GetTotalRating( + _syncInfo.DictionarySize, + _syncInfo.CompressingInfo.Time, + _syncInfo.CompressingInfo.InSize, + _syncInfo.DecompressingInfo.Time, + _syncInfo.DecompressingInfo.OutSize, + _syncInfo.DecompressingInfo.InSize), + IDC_BENCHMARK_TOTAL_RATING_VALUE); + } + } + return true; +} + +bool CBenchmarkDialog::OnCommand(int code, int itemID, LPARAM lParam) +{ + if (code == CBN_SELCHANGE && itemID == IDC_BENCHMARK_COMBO_DICTIONARY) + { + OnChangeSettings(); + return true; + } + return CModalDialog::OnCommand(code, itemID, lParam); +} + +bool CBenchmarkDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) + { + case IDC_BUTTON_RESTART: + OnRestartButton(); + return true; + case IDC_BUTTON_STOP: + OnStopButton(); + return true; + case IDC_BENCHMARK_MULTITHREADING: + OnChangeSettings(); + return true; + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} + +class CBenchmarkInStream: + public ISequentialInStream, + public CMyUnknownImp +{ + const Byte *Data; + UInt32 Pos; + UInt32 Size; +public: + MY_UNKNOWN_IMP + void Init(const Byte *data, UInt32 size) + { + Data = data; + Size = size; + Pos = 0; + } + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); +}; + +STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 remain = Size - Pos; + if (size > remain) + size = remain; + for (UInt32 i = 0; i < size; i++) + { + ((Byte *)data)[i] = Data[Pos + i]; + } + Pos += size; + if(processedSize != NULL) + *processedSize = size; + return S_OK; +} + +class CBenchmarkOutStream: + public ISequentialOutStream, + public CMyUnknownImp +{ + UInt32 BufferSize; +public: + UInt32 Pos; + Byte *Buffer; + CBenchmarkOutStream(): Buffer(0) {} + ~CBenchmarkOutStream() { Free(); } + void Free() + { + ::MidFree(Buffer); + Buffer = 0; + } + + bool Alloc(UInt32 bufferSize) + { + if (Buffer != 0 && BufferSize == bufferSize) + return true; + Free(); + Buffer = (Byte *)::MidAlloc(bufferSize); + Init(); + BufferSize = bufferSize; + return (Buffer != 0); + } + + void Init() + { + Pos = 0; + } + + MY_UNKNOWN_IMP + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + UInt32 i; + for (i = 0; i < size && Pos < BufferSize; i++) + Buffer[Pos++] = ((const Byte *)data)[i]; + if(processedSize != NULL) + *processedSize = i; + if (i != size) + { + MessageBoxW(0, L"Buffer is full", L"7-zip error", 0); + return E_FAIL; + } + return S_OK; +} + +class CCompareOutStream: + public ISequentialOutStream, + public CMyUnknownImp +{ +public: + CCRC CRC; + MY_UNKNOWN_IMP + void Init() { CRC.Init(); } + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +STDMETHODIMP CCompareOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + CRC.Update(data, size); + if(processedSize != NULL) + *processedSize = size; + return S_OK; +} + +typedef UInt32 (WINAPI * CreateObjectPointer)(const GUID *clsID, + const GUID *interfaceID, void **outObject); + +struct CDecoderProgressInfo: + public ICompressProgressInfo, + public CMyUnknownImp +{ + CProgressSyncInfo *SyncInfo; + MY_UNKNOWN_IMP + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); +}; + +STDMETHODIMP CDecoderProgressInfo::SetRatioInfo( + const UInt64 * /* inSize */, const UInt64 * /* outSize */) +{ + NSynchronization::CCriticalSectionLock lock(SyncInfo->CS); + if (SyncInfo->Changed) + return E_ABORT; + return S_OK; +} + +struct CThreadBenchmark: + public ICompressProgressInfo, + public CMyUnknownImp +{ + CProgressSyncInfo *SyncInfo; + UInt64 _startTime; + UInt64 _approvedStart; + NDLL::CLibrary Library; + CMyComPtr Encoder; + CMyComPtr Decoder; + HRESULT Process(); + HRESULT Result; + static DWORD WINAPI MyThreadFunction(void *param) + { + ((CThreadBenchmark *)param)->Result = ((CThreadBenchmark *)param)->Process(); + return 0; + } + MY_UNKNOWN_IMP + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); +}; + +HRESULT CThreadBenchmark::Process() +{ + try + { + SyncInfo->WaitCreating(); + CBenchRandomGenerator randomGenerator; + CMyComPtr writeCoderProperties; + Encoder.QueryInterface(IID_ICompressWriteCoderProperties, + &writeCoderProperties); + CMyComPtr compressSetDecoderProperties; + Decoder.QueryInterface( + IID_ICompressSetDecoderProperties2, &compressSetDecoderProperties); + CSequentialOutStreamImp *propStreamSpec = 0; + CMyComPtr propStream; + if (writeCoderProperties != NULL) + { + propStreamSpec = new CSequentialOutStreamImp; + propStream = propStreamSpec; + } + + CMyComPtr setCoderProperties; + Encoder.QueryInterface(IID_ICompressSetCoderProperties, + &setCoderProperties); + + CDecoderProgressInfo *decoderProgressInfoSpec = new + CDecoderProgressInfo; + CMyComPtr decoderProgress = decoderProgressInfoSpec; + decoderProgressInfoSpec->SyncInfo = SyncInfo; + + for (;;) + { + if (SyncInfo->WasStopped()) + return 0; + if (SyncInfo->WasPaused()) + { + Sleep(200); + continue; + } + UInt32 dictionarySize; + bool multiThread; + { + NSynchronization::CCriticalSectionLock lock(SyncInfo->CS); + dictionarySize = SyncInfo->DictionarySize; + multiThread = SyncInfo->MultiThread; + if (SyncInfo->Changed) + SyncInfo->Init(); + } + + const UInt32 kBufferSize = dictionarySize + kAdditionalSize; + const UInt32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize; + + if (setCoderProperties) + { + PROPID propIDs[] = + { + NCoderPropID::kDictionarySize, + NCoderPropID::kMultiThread + }; + const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]); + NWindows::NCOM::CPropVariant properties[kNumProps]; + properties[0] = UInt32(dictionarySize); + properties[1] = bool(multiThread); + HRESULT res = setCoderProperties->SetCoderProperties(propIDs, + properties, kNumProps); + if (res != S_OK) + { + // SyncInfo->Pause(); + MessageBox(0, NError::MyFormatMessage(res), TEXT("7-Zip"), MB_ICONERROR); + return res; + } + } + + if (propStream) + { + propStreamSpec->Init(); + writeCoderProperties->WriteCoderProperties(propStream); + } + + if (!randomGenerator.Alloc(kBufferSize)) + return E_OUTOFMEMORY; + + randomGenerator.Generate(); + CCRC crc; + + // randomGenerator.BufferSize + crc.Update(randomGenerator.Buffer, randomGenerator.BufferSize); + + { + NSynchronization::CCriticalSectionLock lock(SyncInfo->CS); + if (SyncInfo->Changed) + continue; + } + + CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream; + CMyComPtr inStream = inStreamSpec; + CBenchmarkOutStream *outStreamSpec = new CBenchmarkOutStream; + CMyComPtr outStream = outStreamSpec; + if (!outStreamSpec->Alloc(kCompressedBufferSize)) + return E_OUTOFMEMORY; + + { + // this code is for reducing time of memory allocationg + inStreamSpec->Init(randomGenerator.Buffer, MyMin((UInt32)1, randomGenerator.BufferSize)); + outStreamSpec->Init(); + /* HRESULT result = */ Encoder->Code(inStream, outStream, 0, 0, NULL); + } + + inStreamSpec->Init(randomGenerator.Buffer, randomGenerator.BufferSize); + outStreamSpec->Init(); + + _approvedStart = dictionarySize; + _startTime = ::GetTimeCount(); + HRESULT result = Encoder->Code(inStream, outStream, 0, 0, this); + UInt64 tickCount = ::GetTimeCount() - _startTime; + UInt32 compressedSize = outStreamSpec->Pos; + { + NSynchronization::CCriticalSectionLock lock(SyncInfo->CS); + if (result == S_OK) + { + if (SyncInfo->ApprovedInfo.InSize != 0) + { + SyncInfo->CompressingInfoTemp.InSize = kBufferSize - SyncInfo->ApprovedInfo.InSize; + SyncInfo->CompressingInfoTemp.OutSize = compressedSize - SyncInfo->ApprovedInfo.OutSize; + SyncInfo->CompressingInfoTemp.Time = tickCount - SyncInfo->ApprovedInfo.Time; + if (SyncInfo->CompressingInfo.Time == 0) + SyncInfo->CompressingInfo = SyncInfo->CompressingInfoTemp; + } + } + SyncInfo->ApprovedInfo.Init(); + } + if(result != S_OK) + { + if (result != E_ABORT) + { + SyncInfo->Pause(); + MessageBox(0, NError::MyFormatMessage(result), TEXT("7-Zip"), MB_ICONERROR); + } + continue; + } + { + NSynchronization::CCriticalSectionLock lock(SyncInfo->CS); + SyncInfo->NumPasses++; + } + + /////////////////////// + // Decompressing + + + CCompareOutStream *outCompareStreamSpec = new CCompareOutStream; + CMyComPtr outCompareStream = outCompareStreamSpec; + + for (int i = 0; i < 2; i++) + { + inStreamSpec->Init(outStreamSpec->Buffer, compressedSize); + outCompareStreamSpec->Init(); + + if (compressSetDecoderProperties) + { + RINOK(compressSetDecoderProperties->SetDecoderProperties2( + propStreamSpec->GetBuffer(), (UInt32)propStreamSpec->GetSize())); + } + + UInt64 outSize = kBufferSize; + UInt64 startTime = ::GetTimeCount(); + result = Decoder->Code(inStream, outCompareStream, 0, &outSize, decoderProgress); + tickCount = ::GetTimeCount() - startTime; + { + NSynchronization::CCriticalSectionLock lock(SyncInfo->CS); + if (result == S_OK) + { + SyncInfo->DecompressingInfoTemp.InSize = compressedSize; + SyncInfo->DecompressingInfoTemp.OutSize = kBufferSize; + SyncInfo->DecompressingInfoTemp.Time = tickCount; + if (SyncInfo->DecompressingInfo.Time == 0 && i >= 1) + SyncInfo->DecompressingInfo = SyncInfo->DecompressingInfoTemp; + if (outCompareStreamSpec->CRC.GetDigest() != crc.GetDigest()) + { + SyncInfo->NumErrors++; + break; + } + } + else + { + if(result != E_ABORT) + { + SyncInfo->NumErrors++; + break; + } + } + } + } + } + } + catch(CSystemException &e) + { + MessageBox(0, NError::MyFormatMessage(e.ErrorCode), TEXT("7-Zip"), MB_ICONERROR); + return E_FAIL; + } + catch(...) + { + MyMessageBoxError(0, L"Some error"); + return E_FAIL; + } +} + +STDMETHODIMP CThreadBenchmark::SetRatioInfo( + const UInt64 *inSize, const UInt64 *outSize) +{ + NSynchronization::CCriticalSectionLock lock(SyncInfo->CS); + if (SyncInfo->Changed || SyncInfo->WasPaused() || SyncInfo->WasStopped()) + return E_ABORT; + CProgressInfo ci; + ci.InSize = *inSize; + ci.OutSize = *outSize; + ci.Time = ::GetTimeCount() - _startTime; + SyncInfo->ProcessedSize = *inSize; + + UInt64 deltaTime = ci.Time - SyncInfo->CompressingInfoPrev.Time; + if (deltaTime >= GetFreq()) + { + SyncInfo->CompressingInfoTemp.Time = deltaTime; + SyncInfo->CompressingInfoTemp.InSize = ci.InSize - SyncInfo->CompressingInfoPrev.InSize; + SyncInfo->CompressingInfoTemp.OutSize = ci.InSize - SyncInfo->CompressingInfoPrev.OutSize; + SyncInfo->CompressingInfoPrev = ci; + } + if (*inSize >= _approvedStart && SyncInfo->ApprovedInfo.InSize == 0) + SyncInfo->ApprovedInfo = ci; + return S_OK; +} + +static bool GetCoderPath(UString &path) +{ + if (!GetProgramFolderPath(path)) + return false; + path += L"Codecs\\LZMA.dll"; + return true; +} + +typedef UInt32 (WINAPI *GetMethodPropertyFunc)( + UInt32 index, PROPID propID, PROPVARIANT *value); + +static bool LoadCoder( + const UString &filePath, + NWindows::NDLL::CLibrary &library, + CLSID &encoder, CLSID &decoder) +{ + if (!library.Load(filePath)) + return false; + GetMethodPropertyFunc getMethodProperty = (GetMethodPropertyFunc) + library.GetProcAddress("GetMethodProperty"); + if (getMethodProperty == NULL) + return false; + + NWindows::NCOM::CPropVariant propVariant; + if (getMethodProperty (0, NMethodPropID::kEncoder, &propVariant) != S_OK) + return false; + if (propVariant.vt != VT_BSTR) + return false; + encoder = *(const GUID *)propVariant.bstrVal; + propVariant.Clear(); + + if (getMethodProperty (0, NMethodPropID::kDecoder, &propVariant) != S_OK) + return false; + if (propVariant.vt != VT_BSTR) + return false; + decoder = *(const GUID *)propVariant.bstrVal; + propVariant.Clear(); + return true; +} + +void Benchmark(HWND hwnd) +{ + UString path; + if (!GetCoderPath(path)) + { + MyMessageBoxError(hwnd, L"Can't find LZMA.dll"); + return; + } + CLSID encoder; + CLSID decoder; + CThreadBenchmark benchmarker; + if (!LoadCoder(path, benchmarker.Library, encoder, decoder)) + { + MyMessageBoxError(hwnd, L"Can't load LZMA.dll"); + return; + } + + CreateObjectPointer createObject = (CreateObjectPointer) + benchmarker.Library.GetProcAddress("CreateObject"); + if (createObject == NULL) + { + MyMessageBoxError(hwnd, L"Incorrect LZMA.dll"); + return; + } + if (createObject(&encoder, &IID_ICompressCoder, (void **)&benchmarker.Encoder) != S_OK) + { + MyMessageBoxError(hwnd, L"Can't create codec"); + return; + } + if (createObject(&decoder, &IID_ICompressCoder, (void **)&benchmarker.Decoder) != S_OK) + { + MyMessageBoxError(hwnd, L"Can't create codec"); + return; + } + + CBenchmarkDialog benchmarkDialog; + benchmarker.SyncInfo = &benchmarkDialog._syncInfo; + CThread thread; + if (!thread.Create(CThreadBenchmark::MyThreadFunction, &benchmarker)) + { + MyMessageBoxError(hwnd, L"error"); + return; + } + benchmarkDialog.Create(hwnd); + WaitForSingleObject(thread, INFINITE); +} diff --git a/CPP/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.h b/CPP/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.h new file mode 100755 index 00000000..244e7fe5 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.h @@ -0,0 +1,136 @@ +// BenchmarkDialog.h + +#ifndef __BENCHMARKDIALOG_H +#define __BENCHMARKDIALOG_H + +#include "resource.h" + +#include "Common/MyCom.h" +#include "Windows/Control/Dialog.h" +#include "Windows/Control/ComboBox.h" +#include "Windows/Synchronization.h" +#include "../../../ICoder.h" + +const int kNumBenchDictionaryBitsStart = 21; + +struct CProgressInfo +{ + UINT64 InSize; + UINT64 OutSize; + UINT64 Time; + void Init() + { + InSize = 0; + OutSize = 0; + Time = 0; + } +}; + +class CProgressSyncInfo +{ + bool Stopped; + bool Paused; +public: + bool Changed; + UINT32 DictionarySize; + bool MultiThread; + UINT64 NumPasses; + UINT64 NumErrors; + NWindows::NSynchronization::CManualResetEvent _startEvent; + NWindows::NSynchronization::CCriticalSection CS; + + CProgressInfo ApprovedInfo; + CProgressInfo CompressingInfoPrev; + CProgressInfo CompressingInfoTemp; + CProgressInfo CompressingInfo; + UINT64 ProcessedSize; + + CProgressInfo DecompressingInfoTemp; + CProgressInfo DecompressingInfo; + + void Init() + { + Changed = false; + ApprovedInfo.Init(); + CompressingInfoPrev.Init(); + CompressingInfoTemp.Init(); + CompressingInfo.Init(); + ProcessedSize = 0; + + DecompressingInfoTemp.Init(); + DecompressingInfo.Init(); + + Stopped = false; + Paused = false; + NumPasses = 0; + NumErrors = 0; + } + void InitSettings() + { + DictionarySize = (1 << kNumBenchDictionaryBitsStart); + MultiThread = false; + } + void Stop() + { + NWindows::NSynchronization::CCriticalSectionLock lock(CS); + Stopped = true; + } + bool WasStopped() + { + NWindows::NSynchronization::CCriticalSectionLock lock(CS); + return Stopped; + } + void Pause() + { + NWindows::NSynchronization::CCriticalSectionLock lock(CS); + Paused = true; + } + void Start() + { + NWindows::NSynchronization::CCriticalSectionLock lock(CS); + Paused = false; + } + bool WasPaused() + { + NWindows::NSynchronization::CCriticalSectionLock lock(CS); + return Paused; + } + void WaitCreating() { _startEvent.Lock(); } +}; + +class CBenchmarkDialog: + public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CComboBox m_Dictionary; + UINT_PTR _timer; + UINT32 _startTime; + + bool OnTimer(WPARAM timerID, LPARAM callback); + virtual bool OnInit(); + void OnRestartButton(); + void OnStopButton(); + void OnHelp(); + virtual void OnCancel(); + bool OnButtonClicked(int buttonID, HWND buttonHWND); + bool OnCommand(int code, int itemID, LPARAM lParam); + + void PrintTime(); + void PrintRating(UINT64 rating, UINT controlID); + void PrintResults( + UINT32 dictionarySize, + UINT64 elapsedTime, + UINT64 size, UINT speedID, UINT ratingID, + bool decompressMode = false, UINT64 secondSize = 0); + + UINT32 OnChangeDictionary(); + void OnChangeSettings(); +public: + CProgressSyncInfo _syncInfo; + + CBenchmarkDialog(): _timer(0) {} + INT_PTR Create(HWND wndParent = 0) { return CModalDialog::Create(IDD_DIALOG_BENCHMARK, wndParent); } +}; + +void Benchmark(HWND hwnd); + +#endif diff --git a/CPP/7zip/FileManager/Resource/BenchmarkDialog/StdAfx.h b/CPP/7zip/FileManager/Resource/BenchmarkDialog/StdAfx.h new file mode 100755 index 00000000..a444ca31 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/BenchmarkDialog/StdAfx.h @@ -0,0 +1,16 @@ +// stdafx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#define _WIN32_WINNT 0x0400 + +// it's for Windows NT supporting (MENUITEMINFOW) +#define WINVER 0x0400 + +#include +#include + +#include "Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/FileManager/Resource/BenchmarkDialog/resource.h b/CPP/7zip/FileManager/Resource/BenchmarkDialog/resource.h new file mode 100755 index 00000000..d720058d --- /dev/null +++ b/CPP/7zip/FileManager/Resource/BenchmarkDialog/resource.h @@ -0,0 +1,34 @@ +#define IDD_DIALOG_BENCHMARK 800 +#define IDC_BUTTON_STOP 1001 +#define IDC_BUTTON_RESTART 1002 +#define IDC_BENCHMARK_DICTIONARY 1010 +#define IDC_BENCHMARK_COMBO_DICTIONARY 1011 +#define IDC_BENCHMARK_MEMORY 1012 +#define IDC_BENCHMARK_MEMORY_VALUE 1013 +#define IDC_BENCHMARK_MULTITHREADING 1014 +#define IDC_BENCHMARK_SPEED_LABEL 1020 +#define IDC_BENCHMARK_RATING_LABEL 1021 +#define IDC_BENCHMARK_COMPRESSING 1022 +#define IDC_BENCHMARK_DECOMPRESSING 1023 +#define IDC_BENCHMARK_CURRENT 1024 +#define IDC_BENCHMARK_RESULTING 1025 +#define IDC_BENCHMARK_CURRENT2 1026 +#define IDC_BENCHMARK_RESULTING2 1027 +#define IDC_BENCHMARK_COMPRESSING_SPEED 1030 +#define IDC_BENCHMARK_COMPRESSING_SPEED2 1031 +#define IDC_BENCHMARK_COMPRESSING_RATING 1032 +#define IDC_BENCHMARK_COMPRESSING_RATING2 1033 +#define IDC_BENCHMARK_DECOMPRESSING_SPEED 1040 +#define IDC_BENCHMARK_DECOMPRESSING_SPEED2 1041 +#define IDC_BENCHMARK_DECOMPRESSING_RATING 1042 +#define IDC_BENCHMARK_DECOMPRESSING_RATING2 1043 +#define IDC_BENCHMARK_TOTAL_RATING 1050 +#define IDC_BENCHMARK_TOTAL_RATING_VALUE 1051 +#define IDC_BENCHMARK_ELAPSED 1060 +#define IDC_BENCHMARK_ELAPSED_VALUE 1061 +#define IDC_BENCHMARK_SIZE 1062 +#define IDC_BENCHMARK_SIZE_VALUE 1063 +#define IDC_BENCHMARK_ERRORS 1064 +#define IDC_BENCHMARK_ERRORS_VALUE 1065 +#define IDC_BENCHMARK_PASSES 1066 +#define IDC_BENCHMARK_PASSES_VALUE 1067 diff --git a/CPP/7zip/FileManager/Resource/BenchmarkDialog/resource.rc b/CPP/7zip/FileManager/Resource/BenchmarkDialog/resource.rc new file mode 100755 index 00000000..5ab220e5 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/BenchmarkDialog/resource.rc @@ -0,0 +1,87 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" + +#define xSize2 210 +#define ySize2 228 + +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#define bXPos1 (xSize - marg - bXSize) +#define bXPos2 (bXPos1 - 10 - bXSize) + +#define bYPos (ySize - marg - bYSize) + +#define gSize 160 +#define gSpace 24 + +#define g0XSize 75 +#define g1XSize 44 +#define g1XPos (marg + g0XSize) + +#define g10XPos (marg + marg) +#define gRatingSize 51 +#define gSpeedSize 64 +#define gRatingPos (xSize - marg - marg - gRatingSize) +#define gSpeedPos (gRatingPos - gSpeedSize) +#define gLabelSize (gSpeedPos - g10XPos) +#define gTotalRatingSize (gRatingSize + marg + marg) +#define gTotalRatingPos (xSize - marg - gTotalRatingSize) + +#define g2XSize 58 +#define g3XSize 36 +#define g3XPos (marg + g2XSize) + + +IDD_DIALOG_BENCHMARK DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE | WS_MINIMIZEBOX +CAPTION "Benchmark" +MY_FONT +BEGIN + PUSHBUTTON "&Restart", IDC_BUTTON_RESTART, bXPos1, marg, bXSize, bYSize + PUSHBUTTON "&Stop", IDC_BUTTON_STOP, bXPos1, 27, bXSize, bYSize + + PUSHBUTTON "&Help", IDHELP, bXPos2, bYPos, bXSize,bYSize + PUSHBUTTON "Cancel", IDCANCEL, bXPos1, bYPos, bXSize, bYSize + + LTEXT "&Dictionary size:", IDC_BENCHMARK_DICTIONARY, marg, marg + 1, g0XSize, 8 + COMBOBOX IDC_BENCHMARK_COMBO_DICTIONARY, g1XPos, marg, g1XSize, 140, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Memory usage:", IDC_BENCHMARK_MEMORY, marg, 25, g0XSize, 8 + LTEXT "0 MB", IDC_BENCHMARK_MEMORY_VALUE, g1XPos,25,g1XSize,8 + CONTROL "Multi-threading", IDC_BENCHMARK_MULTITHREADING, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, 41, g0XSize, 10 + + RTEXT "Speed", IDC_BENCHMARK_SPEED_LABEL, gSpeedPos, 53, gSpeedSize, 8 + RTEXT "Rating", IDC_BENCHMARK_RATING_LABEL, gRatingPos, 53, gRatingSize, 8 + + GROUPBOX "Compressing", IDC_BENCHMARK_COMPRESSING, marg, 64, xSize2, 40 + + LTEXT "Current", IDC_BENCHMARK_CURRENT, g10XPos, 76, gLabelSize, 8 + RTEXT "100 KB/s", IDC_BENCHMARK_COMPRESSING_SPEED, gSpeedPos, 76, gSpeedSize, 8 + RTEXT "0", IDC_BENCHMARK_COMPRESSING_RATING, gRatingPos, 76, gRatingSize, 8 + + LTEXT "Resulting", IDC_BENCHMARK_RESULTING, g10XPos, 89, gLabelSize, 8 + RTEXT "100 KB/s", IDC_BENCHMARK_COMPRESSING_SPEED2, gSpeedPos, 89, gSpeedSize, 8 + RTEXT "0", IDC_BENCHMARK_COMPRESSING_RATING2, gRatingPos, 89, gRatingSize, 8 + + GROUPBOX "Decompressing", IDC_BENCHMARK_DECOMPRESSING, marg, 111, xSize2, 40 + + LTEXT "Current", IDC_BENCHMARK_CURRENT2, g10XPos, 123, gLabelSize, 8 + RTEXT "100 KB/s", IDC_BENCHMARK_DECOMPRESSING_SPEED, gSpeedPos, 123, gSpeedSize, 8 + RTEXT "0", IDC_BENCHMARK_DECOMPRESSING_RATING, gRatingPos, 123, gRatingSize, 8 + + LTEXT "Resulting", IDC_BENCHMARK_RESULTING2, g10XPos, 136, gLabelSize, 8 + RTEXT "100 KB/s", IDC_BENCHMARK_DECOMPRESSING_SPEED2, gSpeedPos, 136, gSpeedSize, 8 + RTEXT "0", IDC_BENCHMARK_DECOMPRESSING_RATING2, gRatingPos, 136, gRatingSize, 8 + + GROUPBOX "Total Rating", IDC_BENCHMARK_TOTAL_RATING, gTotalRatingPos, 163, gTotalRatingSize, 38 + RTEXT "0", IDC_BENCHMARK_TOTAL_RATING_VALUE, gRatingPos, 181, gRatingSize, 8 + + LTEXT "Elapsed time:", IDC_BENCHMARK_ELAPSED, marg, 163, g2XSize, 8 + LTEXT "Size:", IDC_BENCHMARK_SIZE, marg, 176, g2XSize, 8 + LTEXT "Passes:", IDC_BENCHMARK_PASSES, marg, 189, g2XSize, 8 + LTEXT "Errors:", IDC_BENCHMARK_ERRORS, marg, 202, g2XSize, 8 + RTEXT "00:00:00", IDC_BENCHMARK_ELAPSED_VALUE, g3XPos, 163, g3XSize, 8 + RTEXT "0", IDC_BENCHMARK_SIZE_VALUE, g3XPos, 176, g3XSize, 8 + RTEXT "0", IDC_BENCHMARK_PASSES_VALUE, g3XPos, 189, g3XSize, 8 + RTEXT "0", IDC_BENCHMARK_ERRORS_VALUE, g3XPos, 202, g3XSize, 8 +END diff --git a/CPP/7zip/FileManager/Resource/ComboDialog/ComboDialog.cpp b/CPP/7zip/FileManager/Resource/ComboDialog/ComboDialog.cpp new file mode 100755 index 00000000..2dc42ee0 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/ComboDialog/ComboDialog.cpp @@ -0,0 +1,53 @@ +// ComboDialog.cpp + +#include "StdAfx.h" +#include "ComboDialog.h" + +#include "Windows/Control/Static.h" + +#ifdef LANG +#include "../../LangUtils.h" +#endif + +using namespace NWindows; + +#ifdef LANG +static CIDLangPair kIDLangPairs[] = +{ + { IDOK, 0x02000702 }, + { IDCANCEL, 0x02000710 } +}; +#endif + +bool CComboDialog::OnInit() +{ + #ifdef LANG + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + #endif + _comboBox.Attach(GetItem(IDC_COMBO_COMBO)); + + /* + // why it doesn't work ? + DWORD style = _comboBox.GetStyle(); + if (Sorted) + style |= CBS_SORT; + else + style &= ~CBS_SORT; + _comboBox.SetStyle(style); + */ + SetText(Title); + + NControl::CStatic staticContol; + staticContol.Attach(GetItem(IDC_COMBO_STATIC)); + staticContol.SetText(Static); + _comboBox.SetText(Value); + for(int i = 0; i < Strings.Size(); i++) + _comboBox.AddString(Strings[i]); + return CModalDialog::OnInit(); +} + +void CComboDialog::OnOK() +{ + _comboBox.GetText(Value); + CModalDialog::OnOK(); +} diff --git a/CPP/7zip/FileManager/Resource/ComboDialog/ComboDialog.h b/CPP/7zip/FileManager/Resource/ComboDialog/ComboDialog.h new file mode 100755 index 00000000..1838783d --- /dev/null +++ b/CPP/7zip/FileManager/Resource/ComboDialog/ComboDialog.h @@ -0,0 +1,25 @@ +// ComboDialog.h + +#ifndef __COMBODIALOG_H +#define __COMBODIALOG_H + +#include "Windows/Control/Dialog.h" +#include "Windows/Control/ComboBox.h" +#include "resource.h" + +class CComboDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CComboBox _comboBox; + virtual void OnOK(); + virtual bool OnInit(); +public: + // bool Sorted; + UString Title; + UString Static; + UString Value; + UStringVector Strings; + // CComboDialog(): Sorted(false) {}; + INT_PTR Create(HWND parentWindow = 0) { return CModalDialog::Create(IDD_DIALOG_COMBO, parentWindow); } +}; + +#endif diff --git a/CPP/7zip/FileManager/Resource/ComboDialog/StdAfx.h b/CPP/7zip/FileManager/Resource/ComboDialog/StdAfx.h new file mode 100755 index 00000000..a444ca31 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/ComboDialog/StdAfx.h @@ -0,0 +1,16 @@ +// stdafx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#define _WIN32_WINNT 0x0400 + +// it's for Windows NT supporting (MENUITEMINFOW) +#define WINVER 0x0400 + +#include +#include + +#include "Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/FileManager/Resource/ComboDialog/resource.h b/CPP/7zip/FileManager/Resource/ComboDialog/resource.h new file mode 100755 index 00000000..b5111ddf --- /dev/null +++ b/CPP/7zip/FileManager/Resource/ComboDialog/resource.h @@ -0,0 +1,4 @@ +#define IDD_DIALOG_COMBO 200 + +#define IDC_COMBO_STATIC 1000 +#define IDC_COMBO_COMBO 1001 diff --git a/CPP/7zip/FileManager/Resource/ComboDialog/resource.rc b/CPP/7zip/FileManager/Resource/ComboDialog/resource.rc new file mode 100755 index 00000000..7bf25365 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/ComboDialog/resource.rc @@ -0,0 +1,24 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" + +#define xSize2 233 +#define ySize2 57 + +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#define bYPos (ySize - marg - bYSize) +#define b1XPos (xSize - marg - bXSize) +#define b2XPos (b1XPos - 10 - bXSize) + + +IDD_DIALOG_COMBO DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE +CAPTION "Combo" +MY_FONT +BEGIN + LTEXT "", IDC_COMBO_STATIC, marg, marg, xSize2, 8 + COMBOBOX IDC_COMBO_COMBO, marg, 20, xSize2, 65, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + + DEFPUSHBUTTON "OK", IDOK, b2XPos, bYPos, bXSize, bYSize + PUSHBUTTON "Cancel", IDCANCEL, b1XPos, bYPos, bXSize, bYSize +END diff --git a/CPP/7zip/FileManager/Resource/CopyDialog/CopyDialog.cpp b/CPP/7zip/FileManager/Resource/CopyDialog/CopyDialog.cpp new file mode 100755 index 00000000..c0bcf2bc --- /dev/null +++ b/CPP/7zip/FileManager/Resource/CopyDialog/CopyDialog.cpp @@ -0,0 +1,81 @@ +// CopyDialog.cpp + +#include "StdAfx.h" +#include "CopyDialog.h" + +#include "Common/StringConvert.h" + +#include "Windows/Control/Static.h" +#include "Windows/Shell.h" +#include "Windows/FileName.h" + +#ifdef LANG +#include "../../LangUtils.h" +#endif + +using namespace NWindows; + +#ifdef LANG +static CIDLangPair kIDLangPairs[] = +{ + { IDOK, 0x02000702 }, + { IDCANCEL, 0x02000710 } +}; +#endif + +bool CCopyDialog::OnInit() +{ + #ifdef LANG + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + #endif + _path.Attach(GetItem(IDC_COPY_COMBO)); + SetText(Title); + + NControl::CStatic staticContol; + staticContol.Attach(GetItem(IDC_COPY_STATIC)); + staticContol.SetText(Static); + for(int i = 0; i < Strings.Size(); i++) + _path.AddString(Strings[i]); + _path.SetText(Value); + return CModalDialog::OnInit(); +} + +bool CCopyDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) + { + case IDC_COPY_SET_PATH: + OnButtonSetPath(); + return true; + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} + +void CCopyDialog::OnButtonSetPath() +{ + UString currentPath; + _path.GetText(currentPath); + + /* + #ifdef LANG + UString title = LangLoadString(IDS_EXTRACT_SET_FOLDER, 0x02000881); + #else + UString title = MyLoadString(IDS_EXTRACT_SET_FOLDER); + #endif + */ + UString title = LangStringSpec(IDS_SET_FOLDER, 0x03020209); + // UString title = L"Specify a location for output folder"; + + UString resultPath; + if (!NShell::BrowseForFolder(HWND(*this), title, currentPath, resultPath)) + return; + NFile::NName::NormalizeDirPathPrefix(resultPath); + _path.SetCurSel(-1); + _path.SetText(resultPath); +} + +void CCopyDialog::OnOK() +{ + _path.GetText(Value); + CModalDialog::OnOK(); +} diff --git a/CPP/7zip/FileManager/Resource/CopyDialog/CopyDialog.h b/CPP/7zip/FileManager/Resource/CopyDialog/CopyDialog.h new file mode 100755 index 00000000..353f6807 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/CopyDialog/CopyDialog.h @@ -0,0 +1,26 @@ +// CopyDialog.h + +#ifndef __COPYDIALOG_H +#define __COPYDIALOG_H + +#include "Windows/Control/Dialog.h" +#include "Windows/Control/ComboBox.h" +#include "resource.h" + +class CCopyDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CComboBox _path; + virtual void OnOK(); + virtual bool OnInit(); + void OnButtonSetPath(); + bool OnButtonClicked(int buttonID, HWND buttonHWND); +public: + UString Title; + UString Static; + UString Value; + UStringVector Strings; + + INT_PTR Create(HWND parentWindow = 0) { return CModalDialog::Create(IDD_DIALOG_COPY, parentWindow); } +}; + +#endif diff --git a/CPP/7zip/FileManager/Resource/CopyDialog/StdAfx.h b/CPP/7zip/FileManager/Resource/CopyDialog/StdAfx.h new file mode 100755 index 00000000..a444ca31 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/CopyDialog/StdAfx.h @@ -0,0 +1,16 @@ +// stdafx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#define _WIN32_WINNT 0x0400 + +// it's for Windows NT supporting (MENUITEMINFOW) +#define WINVER 0x0400 + +#include +#include + +#include "Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/FileManager/Resource/CopyDialog/resource.h b/CPP/7zip/FileManager/Resource/CopyDialog/resource.h new file mode 100755 index 00000000..7ec6162a --- /dev/null +++ b/CPP/7zip/FileManager/Resource/CopyDialog/resource.h @@ -0,0 +1,7 @@ +#define IDD_DIALOG_COPY 202 + +#define IDC_COPY_STATIC 1000 +#define IDC_COPY_COMBO 1001 +#define IDC_COPY_SET_PATH 1002 + +#define IDS_SET_FOLDER 210 diff --git a/CPP/7zip/FileManager/Resource/CopyDialog/resource.rc b/CPP/7zip/FileManager/Resource/CopyDialog/resource.rc new file mode 100755 index 00000000..156b56cf --- /dev/null +++ b/CPP/7zip/FileManager/Resource/CopyDialog/resource.rc @@ -0,0 +1,28 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" + +#define xSize2 346 +#define ySize2 57 + +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#define bYPos (ySize - marg - bYSize) +#define b1XPos (xSize - marg - bXSize) +#define b2XPos (b1XPos - 10 - bXSize) + +IDD_DIALOG_COPY DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE +CAPTION "Copy" +MY_FONT +BEGIN + LTEXT "", IDC_COPY_STATIC, marg, marg, xSize2, 8 + COMBOBOX IDC_COPY_COMBO, marg, 20, xSize2 - bDotsSize - 12, 65, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "...", IDC_COPY_SET_PATH, (xSize - marg - bDotsSize), 20, bDotsSize, 14, WS_GROUP + DEFPUSHBUTTON "OK", IDOK, b2XPos, bYPos, bXSize, bYSize + PUSHBUTTON "Cancel", IDCANCEL, b1XPos, bYPos, bXSize, bYSize +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_SET_FOLDER "Specify a location for output folder." +END diff --git a/CPP/7zip/FileManager/Resource/EditPage/EditPage.cpp b/CPP/7zip/FileManager/Resource/EditPage/EditPage.cpp new file mode 100755 index 00000000..0e6e1d71 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/EditPage/EditPage.cpp @@ -0,0 +1,91 @@ +// EditPage.cpp + +#include "StdAfx.h" +#include "resource.h" +#include "EditPage.h" + +#include "Common/StringConvert.h" + +#include "Windows/Defs.h" +#include "Windows/CommonDialog.h" +// #include "Windows/FileFind.h" +// #include "Windows/FileDir.h" + +#include "../../RegistryUtils.h" +#include "../../HelpUtils.h" +#include "../../LangUtils.h" +#include "../../ProgramLocation.h" + +using namespace NWindows; + +static CIDLangPair kIDLangPairs[] = +{ + { IDC_EDIT_STATIC_EDITOR, 0x03010201} +}; + +static LPCWSTR kEditTopic = L"FM/options.htm#editor"; + +bool CEditPage::OnInit() +{ + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + + _editorEdit.Attach(GetItem(IDC_EDIT_EDIT_EDITOR)); + UString editorPath; + ReadRegEditor(editorPath); + _editorEdit.SetText(editorPath); + return CPropertyPage::OnInit(); +} + +LONG CEditPage::OnApply() +{ + // int selectedIndex = _langCombo.GetCurSel(); + // int pathIndex = _langCombo.GetItemData(selectedIndex); + // ReloadLang(); + UString editorPath; + _editorEdit.GetText(editorPath); + SaveRegEditor(editorPath); + return PSNRET_NOERROR; +} + +void CEditPage::OnNotifyHelp() +{ + ShowHelpWindow(NULL, kEditTopic); // change it +} + +bool CEditPage::OnButtonClicked(int aButtonID, HWND aButtonHWND) +{ + switch(aButtonID) + { + case IDC_EDIT_BUTTON_SET: + { + OnSetEditorButton(); + // if (!NShell::BrowseForFolder(HWND(*this), title, currentPath, aResultPath)) + // return; + return true; + } + } + return CPropertyPage::OnButtonClicked(aButtonID, aButtonHWND); +} + +void CEditPage::OnSetEditorButton() +{ + UString editorPath; + _editorEdit.GetText(editorPath); + UString resPath; + if(!MyGetOpenFileName(HWND(*this), 0, editorPath, L"*.exe", resPath)) + return; + _editorEdit.SetText(resPath); + // Changed(); +} + +bool CEditPage::OnCommand(int code, int itemID, LPARAM param) +{ + if (code == EN_CHANGE && itemID == IDC_EDIT_EDIT_EDITOR) + { + Changed(); + return true; + } + return CPropertyPage::OnCommand(code, itemID, param); +} + + diff --git a/CPP/7zip/FileManager/Resource/EditPage/EditPage.h b/CPP/7zip/FileManager/Resource/EditPage/EditPage.h new file mode 100755 index 00000000..26999dcf --- /dev/null +++ b/CPP/7zip/FileManager/Resource/EditPage/EditPage.h @@ -0,0 +1,21 @@ +// EditPage.h + +#ifndef __EDITPAGE_H +#define __EDITPAGE_H + +#include "Windows/Control/PropertyPage.h" +#include "Windows/Control/Edit.h" + +class CEditPage: public NWindows::NControl::CPropertyPage +{ + NWindows::NControl::CEdit _editorEdit; + void OnSetEditorButton(); +public: + virtual bool OnInit(); + virtual void OnNotifyHelp(); + virtual bool OnCommand(int code, int itemID, LPARAM param); + virtual LONG OnApply(); + virtual bool OnButtonClicked(int aButtonID, HWND aButtonHWND); +}; + +#endif diff --git a/CPP/7zip/FileManager/Resource/EditPage/StdAfx.h b/CPP/7zip/FileManager/Resource/EditPage/StdAfx.h new file mode 100755 index 00000000..a444ca31 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/EditPage/StdAfx.h @@ -0,0 +1,16 @@ +// stdafx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#define _WIN32_WINNT 0x0400 + +// it's for Windows NT supporting (MENUITEMINFOW) +#define WINVER 0x0400 + +#include +#include + +#include "Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/FileManager/Resource/EditPage/resource.h b/CPP/7zip/FileManager/Resource/EditPage/resource.h new file mode 100755 index 00000000..a2de1970 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/EditPage/resource.h @@ -0,0 +1,4 @@ +#define IDD_EDIT 903 +#define IDC_EDIT_STATIC_EDITOR 1000 +#define IDC_EDIT_EDIT_EDITOR 1002 +#define IDC_EDIT_BUTTON_SET 1003 diff --git a/CPP/7zip/FileManager/Resource/EditPage/resource.rc b/CPP/7zip/FileManager/Resource/EditPage/resource.rc new file mode 100755 index 00000000..d4d8b9cd --- /dev/null +++ b/CPP/7zip/FileManager/Resource/EditPage/resource.rc @@ -0,0 +1,16 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" + +#define xSize2 196 +#define ySize2 140 +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +IDD_EDIT DIALOG 0, 0, xSize, ySize MY_PAGE_STYLE +CAPTION "Editor" +MY_FONT +BEGIN + LTEXT "&Editor:", IDC_EDIT_STATIC_EDITOR, marg, marg, xSize2, 8 + EDITTEXT IDC_EDIT_EDIT_EDITOR, marg, 20, xSize2 - 12 - bDotsSize, 14, ES_AUTOHSCROLL + PUSHBUTTON "...", IDC_EDIT_BUTTON_SET, (xSize - marg - bDotsSize), 20, bDotsSize, bYSize +END diff --git a/CPP/7zip/FileManager/Resource/LangPage/LangPage.cpp b/CPP/7zip/FileManager/Resource/LangPage/LangPage.cpp new file mode 100755 index 00000000..9974759a --- /dev/null +++ b/CPP/7zip/FileManager/Resource/LangPage/LangPage.cpp @@ -0,0 +1,90 @@ +// LangPage.cpp + +#include "StdAfx.h" +#include "resource.h" +#include "LangPage.h" + +#include "Common/StringConvert.h" + +#include "Windows/ResourceString.h" + +#include "../../RegistryUtils.h" +#include "../../HelpUtils.h" +#include "../../LangUtils.h" + +static CIDLangPair kIDLangPairs[] = +{ + { IDC_LANG_STATIC_LANG, 0x01000401} +}; + +static LPCWSTR kLangTopic = L"fm/options.htm#language"; + +bool CLangPage::OnInit() +{ + _langWasChanged = false; + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + + _langCombo.Attach(GetItem(IDC_LANG_COMBO_LANG)); + + UString s = NWindows::MyLoadStringW(IDS_LANG_ENGLISH); + s += L" ("; + s += NWindows::MyLoadStringW(IDS_LANG_NATIVE); + s += L")"; + int index = (int)_langCombo.AddString(s); + _langCombo.SetItemData(index, _paths.Size()); + _paths.Add(L"-"); + _langCombo.SetCurSel(0); + + CObjectVector langs; + LoadLangs(langs); + for (int i = 0; i < langs.Size(); i++) + { + const CLangEx &lang = langs[i]; + UString name; + UString englishName, nationalName; + if (lang.Lang.GetMessage(0x00000000, englishName)) + name = englishName; + else + name = lang.ShortName; + if (lang.Lang.GetMessage(0x00000001, nationalName)) + { + if (!nationalName.IsEmpty()) + { + name += L" ("; + name += nationalName; + name += L")"; + } + } + index = (int)_langCombo.AddString(name); + _langCombo.SetItemData(index, _paths.Size()); + _paths.Add(lang.ShortName); + if (g_LangID.CompareNoCase(lang.ShortName) == 0) + _langCombo.SetCurSel(index); + } + return CPropertyPage::OnInit(); +} + +LONG CLangPage::OnApply() +{ + int selectedIndex = _langCombo.GetCurSel(); + int pathIndex = (int)_langCombo.GetItemData(selectedIndex); + SaveRegLang(_paths[pathIndex]); + ReloadLang(); + _langWasChanged = true; + return PSNRET_NOERROR; +} + +void CLangPage::OnNotifyHelp() +{ + ShowHelpWindow(NULL, kLangTopic); // change it +} + +bool CLangPage::OnCommand(int code, int itemID, LPARAM param) +{ + if (code == CBN_SELCHANGE && itemID == IDC_LANG_COMBO_LANG) + { + Changed(); + return true; + } + return CPropertyPage::OnCommand(code, itemID, param); +} diff --git a/CPP/7zip/FileManager/Resource/LangPage/LangPage.h b/CPP/7zip/FileManager/Resource/LangPage/LangPage.h new file mode 100755 index 00000000..b28d6984 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/LangPage/LangPage.h @@ -0,0 +1,21 @@ +// LangPage.h + +#ifndef __LANGPAGE_H +#define __LANGPAGE_H + +#include "Windows/Control/PropertyPage.h" +#include "Windows/Control/ComboBox.h" + +class CLangPage: public NWindows::NControl::CPropertyPage +{ + NWindows::NControl::CComboBox _langCombo; + UStringVector _paths; +public: + bool _langWasChanged; + virtual bool OnInit(); + virtual void OnNotifyHelp(); + virtual bool OnCommand(int code, int itemID, LPARAM param); + virtual LONG OnApply(); +}; + +#endif diff --git a/CPP/7zip/FileManager/Resource/LangPage/StdAfx.h b/CPP/7zip/FileManager/Resource/LangPage/StdAfx.h new file mode 100755 index 00000000..a444ca31 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/LangPage/StdAfx.h @@ -0,0 +1,16 @@ +// stdafx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#define _WIN32_WINNT 0x0400 + +// it's for Windows NT supporting (MENUITEMINFOW) +#define WINVER 0x0400 + +#include +#include + +#include "Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/FileManager/Resource/LangPage/resource.h b/CPP/7zip/FileManager/Resource/LangPage/resource.h new file mode 100755 index 00000000..39571e53 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/LangPage/resource.h @@ -0,0 +1,6 @@ +#define IDD_LANG 900 +#define IDS_LANG_ENGLISH 995 +#define IDS_LANG_NATIVE 996 + +#define IDC_LANG_STATIC_LANG 1000 +#define IDC_LANG_COMBO_LANG 1001 diff --git a/CPP/7zip/FileManager/Resource/LangPage/resource.rc b/CPP/7zip/FileManager/Resource/LangPage/resource.rc new file mode 100755 index 00000000..abaa9481 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/LangPage/resource.rc @@ -0,0 +1,21 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" + +#define xSize2 238 +#define ySize2 204 +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +IDD_LANG DIALOG 0, 0, xSize, ySize MY_PAGE_STYLE +CAPTION "Language" +MY_FONT +BEGIN + LTEXT "Language:", IDC_LANG_STATIC_LANG, marg, marg, xSize2, 8 + COMBOBOX IDC_LANG_COMBO_LANG, marg, 20, 146, ySize2 - 12, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP +END + +STRINGTABLE +BEGIN + IDS_LANG_ENGLISH "English" + IDS_LANG_NATIVE "English" +END diff --git a/CPP/7zip/FileManager/Resource/ListBoxDialog/StdAfx.h b/CPP/7zip/FileManager/Resource/ListBoxDialog/StdAfx.h new file mode 100755 index 00000000..a444ca31 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/ListBoxDialog/StdAfx.h @@ -0,0 +1,16 @@ +// stdafx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#define _WIN32_WINNT 0x0400 + +// it's for Windows NT supporting (MENUITEMINFOW) +#define WINVER 0x0400 + +#include +#include + +#include "Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/FileManager/Resource/ListBoxDialog/resource.h b/CPP/7zip/FileManager/Resource/ListBoxDialog/resource.h new file mode 100755 index 00000000..507e17bd --- /dev/null +++ b/CPP/7zip/FileManager/Resource/ListBoxDialog/resource.h @@ -0,0 +1,3 @@ +#define IDD_DIALOG_LISTBOX 202 + +#define IDC_LISTBOX_LIST 1000 diff --git a/CPP/7zip/FileManager/Resource/ListBoxDialog/resource.rc b/CPP/7zip/FileManager/Resource/ListBoxDialog/resource.rc new file mode 100755 index 00000000..728aaa94 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/ListBoxDialog/resource.rc @@ -0,0 +1,22 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" + +#define xSize2 223 +#define ySize2 177 + +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#define bYPos (ySize - marg - bYSize) +#define b1XPos (xSize - marg - bXSize) +#define b2XPos (b1XPos - 10 - bXSize) + + +IDD_DIALOG_LISTBOX DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE +CAPTION "List Box" +MY_FONT +BEGIN + LISTBOX IDC_LISTBOX_LIST, marg, marg, xSize2, 149, LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "OK", IDOK, b2XPos, bYPos, bXSize, bYSize + PUSHBUTTON "Cancel", IDCANCEL, b1XPos, bYPos, bXSize, bYSize +END diff --git a/CPP/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.cpp b/CPP/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.cpp new file mode 100755 index 00000000..ca7b7935 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.cpp @@ -0,0 +1,102 @@ +// ListViewDialog.cpp + +#include "StdAfx.h" +#include "ListViewDialog.h" + +#include "Common/Vector.h" + +#ifdef LANG +#include "../../LangUtils.h" +static CIDLangPair kIDLangPairs[] = +{ + { IDOK, 0x02000702 }, + { IDCANCEL, 0x02000710 } +}; +#endif + +bool CListViewDialog::OnInit() +{ + #ifdef LANG + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + #endif + _listView.Attach(GetItem(IDC_LISTVIEW_LIST)); + SetText(Title); + + LVCOLUMN columnInfo; + columnInfo.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM; + columnInfo.fmt = LVCFMT_LEFT; + columnInfo.iSubItem = 0; + columnInfo.cx = 1000; + + _listView.InsertColumn(0, &columnInfo); + + for(int i = 0; i < Strings.Size(); i++) + { + LVITEMW item; + item.mask = LVIF_TEXT; + item.iItem = i; + item.pszText = (LPWSTR)(LPCWSTR)Strings[i]; + item.iSubItem = 0; + _listView.InsertItem(&item); + } + if (Strings.Size() > 0) + _listView.SetItemState(0, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); + StringsWereChanged = false; + return CModalDialog::OnInit(); +} + +bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header) +{ + if (header->hwndFrom != _listView) + return false; + switch(header->code) + { + case LVN_KEYDOWN: + { + LPNMLVKEYDOWN keyDownInfo = LPNMLVKEYDOWN(header); + switch(keyDownInfo->wVKey) + { + case VK_DELETE: + { + if (!DeleteIsAllowed) + return false; + int focusedIndex = _listView.GetFocusedItem(); + if (focusedIndex < 0) + focusedIndex = 0; + for (;;) + { + int index = _listView.GetNextSelectedItem(-1); + if (index < 0) + break; + StringsWereChanged = true; + _listView.DeleteItem(index); + Strings.Delete(index); + } + if (focusedIndex >= _listView.GetItemCount()) + focusedIndex = _listView.GetItemCount() - 1; + if (focusedIndex >= 0) + _listView.SetItemState(focusedIndex, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); + return true; + } + case 'A': + { + bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; + if (ctrl) + { + int numItems = _listView.GetItemCount(); + for (int i = 0; i < numItems; i++) + _listView.SetItemState(i, LVIS_SELECTED, LVIS_SELECTED); + return true; + } + } + } + } + } + return false; +} + +void CListViewDialog::OnOK() +{ + FocusedItemIndex = _listView.GetFocusedItem(); + CModalDialog::OnOK(); +} diff --git a/CPP/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.h b/CPP/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.h new file mode 100755 index 00000000..ad107eba --- /dev/null +++ b/CPP/7zip/FileManager/Resource/ListViewDialog/ListViewDialog.h @@ -0,0 +1,30 @@ +// ListViewDialog.h + +#ifndef __LISTVIEWDIALOG_H +#define __LISTVIEWDIALOG_H + +#include "Windows/Control/Dialog.h" +#include "Windows/Control/ListView.h" +#include "resource.h" + +class CListViewDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CListView _listView; + virtual void OnOK(); + virtual bool OnInit(); + virtual bool OnNotify(UINT controlID, LPNMHDR header); + +public: + UString Title; + bool DeleteIsAllowed; + UStringVector Strings; + bool StringsWereChanged; + int FocusedItemIndex; + + INT_PTR Create(HWND wndParent = 0) { return CModalDialog::Create(IDD_DIALOG_LISTVIEW, wndParent); } + + CListViewDialog(): DeleteIsAllowed(false) {} + +}; + +#endif diff --git a/CPP/7zip/FileManager/Resource/ListViewDialog/StdAfx.h b/CPP/7zip/FileManager/Resource/ListViewDialog/StdAfx.h new file mode 100755 index 00000000..a444ca31 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/ListViewDialog/StdAfx.h @@ -0,0 +1,16 @@ +// stdafx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#define _WIN32_WINNT 0x0400 + +// it's for Windows NT supporting (MENUITEMINFOW) +#define WINVER 0x0400 + +#include +#include + +#include "Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/FileManager/Resource/ListViewDialog/resource.h b/CPP/7zip/FileManager/Resource/ListViewDialog/resource.h new file mode 100755 index 00000000..440d14b0 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/ListViewDialog/resource.h @@ -0,0 +1,3 @@ +#define IDD_DIALOG_LISTVIEW 201 + +#define IDC_LISTVIEW_LIST 1000 diff --git a/CPP/7zip/FileManager/Resource/ListViewDialog/resource.rc b/CPP/7zip/FileManager/Resource/ListViewDialog/resource.rc new file mode 100755 index 00000000..5c0bdbcd --- /dev/null +++ b/CPP/7zip/FileManager/Resource/ListViewDialog/resource.rc @@ -0,0 +1,26 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" + +#define xSize2 342 +#define ySize2 220 + +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#define bYPos (ySize - marg - bYSize) +#define b1XPos (xSize - marg - bXSize) +#define b2XPos (b1XPos - 10 - bXSize) + + +IDD_DIALOG_LISTVIEW DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE +CAPTION "ListView" +MY_FONT +BEGIN + CONTROL "List1", IDC_LISTVIEW_LIST, "SysListView32", LVS_REPORT | LVS_SHOWSELALWAYS | + LVS_AUTOARRANGE | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP, + marg, marg, xSize2, ySize2 - bYSize - 10 + DEFPUSHBUTTON "OK", IDOK, b2XPos, bYPos, bXSize, bYSize + PUSHBUTTON "Cancel", IDCANCEL, b1XPos, bYPos, bXSize, bYSize +END + + diff --git a/CPP/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.cpp b/CPP/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.cpp new file mode 100755 index 00000000..d156f823 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.cpp @@ -0,0 +1,100 @@ +// MessagesDialog.cpp + +#include "StdAfx.h" +#include "MessagesDialog.h" +#include "Common/StringConvert.h" +#include "Common/IntToString.h" +#include "Windows/ResourceString.h" + +#ifdef LANG +#include "../../LangUtils.h" +#endif + +using namespace NWindows; + +#ifdef LANG +static CIDLangPair kIDLangPairs[] = +{ + { IDOK, 0x02000713 } +}; +#endif + +void CMessagesDialog::AddMessageDirect(LPCWSTR message) +{ + int itemIndex = _messageList.GetItemCount(); + LVITEMW item; + item.mask = LVIF_TEXT; + item.iItem = itemIndex; + + wchar_t sz[32]; + ConvertInt64ToString(itemIndex, sz); + + item.pszText = sz; + item.iSubItem = 0; + _messageList.InsertItem(&item); + + item.pszText = (LPWSTR)message; + item.iSubItem = 1; + _messageList.SetItem(&item); +} + +void CMessagesDialog::AddMessage(LPCWSTR message) +{ + UString s = message; + while (!s.IsEmpty()) + { + int pos = s.Find(L'\n'); + if (pos < 0) + break; + AddMessageDirect(s.Left(pos)); + s.Delete(0, pos + 1); + } + AddMessageDirect(s); +} + +bool CMessagesDialog::OnInit() +{ + #ifdef LANG + LangSetWindowText(HWND(*this), 0x02000A00); + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + #endif + _messageList.Attach(GetItem(IDC_MESSAGE_LIST)); + _messageList.SetUnicodeFormat(true); + + LVCOLUMNW columnInfo; + columnInfo.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; + columnInfo.fmt = LVCFMT_LEFT; + columnInfo.pszText = L"#"; + columnInfo.iSubItem = 0; + columnInfo.cx = 30; + + _messageList.InsertColumn(0, &columnInfo); + + + columnInfo.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; + columnInfo.fmt = LVCFMT_LEFT; + UString s = + #ifdef LANG + LangString(IDS_MESSAGES_DIALOG_MESSAGE_COLUMN, 0x02000A80); + #else + MyLoadStringW(IDS_MESSAGES_DIALOG_MESSAGE_COLUMN); + #endif + + columnInfo.pszText = (LPWSTR)(LPCWSTR)s; + columnInfo.iSubItem = 1; + columnInfo.cx = 600; + + _messageList.InsertColumn(1, &columnInfo); + + for(int i = 0; i < Messages->Size(); i++) + AddMessage((*Messages)[i]); + + /* + if(_messageList.GetItemCount() > 0) + { + UINT aState = LVIS_SELECTED | LVIS_FOCUSED; + _messageList.SetItemState(0, aState, aState); + } + */ + return CModalDialog::OnInit(); +} diff --git a/CPP/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.h b/CPP/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.h new file mode 100755 index 00000000..2ec22d80 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/MessagesDialog/MessagesDialog.h @@ -0,0 +1,22 @@ +// MessagesDialog.h + +#ifndef __MESSAGESDIALOG_H +#define __MESSAGESDIALOG_H + +#include "resource.h" + +#include "Windows/Control/Dialog.h" +#include "Windows/Control/ListView.h" + +class CMessagesDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CListView _messageList; + void AddMessageDirect(LPCWSTR message); + void AddMessage(LPCWSTR message); + virtual bool OnInit(); +public: + const UStringVector *Messages; + INT_PTR Create(HWND parent = 0) { return CModalDialog::Create(IDD_DIALOG_MESSAGES, parent); } +}; + +#endif diff --git a/CPP/7zip/FileManager/Resource/MessagesDialog/StdAfx.h b/CPP/7zip/FileManager/Resource/MessagesDialog/StdAfx.h new file mode 100755 index 00000000..a444ca31 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/MessagesDialog/StdAfx.h @@ -0,0 +1,16 @@ +// stdafx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#define _WIN32_WINNT 0x0400 + +// it's for Windows NT supporting (MENUITEMINFOW) +#define WINVER 0x0400 + +#include +#include + +#include "Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/FileManager/Resource/MessagesDialog/resource.h b/CPP/7zip/FileManager/Resource/MessagesDialog/resource.h new file mode 100755 index 00000000..39d49f57 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/MessagesDialog/resource.h @@ -0,0 +1,3 @@ +#define IDS_MESSAGES_DIALOG_MESSAGE_COLUMN 503 +#define IDD_DIALOG_MESSAGES 503 +#define IDC_MESSAGE_LIST 1000 diff --git a/CPP/7zip/FileManager/Resource/MessagesDialog/resource.rc b/CPP/7zip/FileManager/Resource/MessagesDialog/resource.rc new file mode 100755 index 00000000..eae00bf0 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/MessagesDialog/resource.rc @@ -0,0 +1,25 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" + +#define xSize2 430 +#define ySize2 140 +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) +#define bXPos (xSize - marg - bXSize) +#define bYPos (ySize - marg - bYSize) + + +IDD_DIALOG_MESSAGES DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE +CAPTION "7-Zip: Diagnostic messages" +MY_FONT +BEGIN + DEFPUSHBUTTON "&Close", IDOK, bXPos, bYPos, bXSize, bYSize + CONTROL "List1",IDC_MESSAGE_LIST,"SysListView32", + LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, + marg, marg, xSize2, ySize2 - bYSize - 6 +END + +STRINGTABLE +BEGIN + IDS_MESSAGES_DIALOG_MESSAGE_COLUMN "Message" +END diff --git a/CPP/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.cpp b/CPP/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.cpp new file mode 100755 index 00000000..8f13a43a --- /dev/null +++ b/CPP/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.cpp @@ -0,0 +1,124 @@ +// OverwriteDialog.cpp + +#include "StdAfx.h" + +#include "OverwriteDialog.h" + +#include "Common/StringConvert.h" +#include "Windows/FileName.h" +#include "Windows/Defs.h" +#include "Windows/ResourceString.h" +#include "Windows/Control/Static.h" +#include "Windows/PropVariantConversions.h" + +#include "../../FormatUtils.h" + +// #include "../resource.h" + +#ifdef LANG +#include "../../LangUtils.h" +#endif + +using namespace NWindows; + +#ifdef LANG +static CIDLangPair kIDLangPairs[] = +{ + { IDC_STATIC_OVERWRITE_HEADER, 0x02000901}, + { IDC_STATIC_OVERWRITE_QUESTION_BEGIN, 0x02000902 }, + { IDC_STATIC_OVERWRITE_QUESTION_END, 0x02000903 }, + { IDYES, 0x02000705 }, + { IDC_BUTTON_OVERWRITE_YES_TO_ALL, 0x02000707 }, + { IDNO, 0x02000709 }, + { IDC_BUTTON_OVERWRITE_NO_TO_ALL,0x0200070B }, + { IDC_BUTTON_OVERWRITE_AUTO_RENAME, 0x02000911 }, + { IDCANCEL, 0x02000711 } +}; +#endif + +void COverwriteDialog::SetFileInfoControl(int textID, int iconID, + const NOverwriteDialog::CFileInfo &fileInfo) +{ + UString sizeString; + if (fileInfo.SizeIsDefined) + sizeString = MyFormatNew(IDS_FILE_SIZE, + #ifdef LANG + 0x02000982, + #endif + NumberToString(fileInfo.Size)); + + UString reducedName; + const int kLineSize = 88; + for (int i = 0; i < fileInfo.Name.Length();) + { + reducedName += fileInfo.Name.Mid(i, kLineSize); + reducedName += L" "; + i += kLineSize; + } + + UString fullString = reducedName; + fullString += L"\n"; + fullString += sizeString; + fullString += L"\n"; + + if (fileInfo.TimeIsDefined) + { + UString timeString; + FILETIME localFileTime; + if (!FileTimeToLocalFileTime(&fileInfo.Time, &localFileTime)) + throw 4190402; + timeString = ConvertFileTimeToString(localFileTime); + + fullString += + #ifdef LANG + LangString(IDS_FILE_MODIFIED, 0x02000983); + #else + MyLoadStringW(IDS_FILE_MODIFIED); + #endif + + fullString += L" "; + fullString += timeString; + } + + NWindows::NControl::CDialogChildControl control; + control.Init(*this, textID); + control.SetText(fullString); + + SHFILEINFO shellFileInfo; + if (::SHGetFileInfo( + GetSystemString(fileInfo.Name), FILE_ATTRIBUTE_NORMAL, &shellFileInfo, + sizeof(shellFileInfo), SHGFI_ICON | SHGFI_USEFILEATTRIBUTES | SHGFI_LARGEICON)) + { + NControl::CStatic staticContol; + staticContol.Attach(GetItem(iconID)); + staticContol.SetIcon(shellFileInfo.hIcon); + } +} + +bool COverwriteDialog::OnInit() +{ + #ifdef LANG + LangSetWindowText(HWND(*this), 0x02000900); + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + #endif + SetFileInfoControl(IDC_STATIC_OVERWRITE_OLD_FILE_SIZE_TIME, + IDC_STATIC_OVERWRITE_OLD_FILE_ICON, OldFileInfo); + SetFileInfoControl(IDC_STATIC_OVERWRITE_NEW_FILE_SIZE_TIME, + IDC_STATIC_OVERWRITE_NEW_FILE_ICON, NewFileInfo); + return CModalDialog::OnInit(); +} + +bool COverwriteDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) + { + case IDYES: + case IDC_BUTTON_OVERWRITE_YES_TO_ALL: + case IDNO: + case IDC_BUTTON_OVERWRITE_NO_TO_ALL: + case IDC_BUTTON_OVERWRITE_AUTO_RENAME: + End(buttonID); + return true; + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} diff --git a/CPP/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.h b/CPP/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.h new file mode 100755 index 00000000..193efb85 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/OverwriteDialog/OverwriteDialog.h @@ -0,0 +1,34 @@ +// OverwriteDialog.h + +#ifndef __OVERWRITEDIALOG_H +#define __OVERWRITEDIALOG_H + +#include "resource.h" +#include "Windows/Control/Dialog.h" + +namespace NOverwriteDialog +{ + struct CFileInfo + { + bool SizeIsDefined; + UINT64 Size; + bool TimeIsDefined; + FILETIME Time; + UString Name; + }; +} + +class COverwriteDialog: public NWindows::NControl::CModalDialog +{ + void SetFileInfoControl(int textID, int iconID, + const NOverwriteDialog::CFileInfo &fileInfo); + virtual bool OnInit(); + bool OnButtonClicked(int buttonID, HWND buttonHWND); +public: + INT_PTR Create(HWND parent = 0) { return CModalDialog::Create(IDD_DIALOG_OVERWRITE, parent); } + + NOverwriteDialog::CFileInfo OldFileInfo; + NOverwriteDialog::CFileInfo NewFileInfo; +}; + +#endif diff --git a/CPP/7zip/FileManager/Resource/OverwriteDialog/StdAfx.h b/CPP/7zip/FileManager/Resource/OverwriteDialog/StdAfx.h new file mode 100755 index 00000000..a444ca31 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/OverwriteDialog/StdAfx.h @@ -0,0 +1,16 @@ +// stdafx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#define _WIN32_WINNT 0x0400 + +// it's for Windows NT supporting (MENUITEMINFOW) +#define WINVER 0x0400 + +#include +#include + +#include "Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/FileManager/Resource/OverwriteDialog/resource.h b/CPP/7zip/FileManager/Resource/OverwriteDialog/resource.h new file mode 100755 index 00000000..66710f84 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/OverwriteDialog/resource.h @@ -0,0 +1,19 @@ +#define IDS_FILE_MODIFIED 600 +#define IDS_FILE_SIZE 601 + +#define IDD_DIALOG_OVERWRITE 502 + +#define IDC_STATIC_OVERWRITE_HEADER 1000 + +#define IDC_STATIC_OVERWRITE_QUESTION_BEGIN 1001 +#define IDC_STATIC_OVERWRITE_QUESTION_END 1002 + +#define IDC_STATIC_OVERWRITE_OLD_FILE_ICON 1003 +#define IDC_STATIC_OVERWRITE_NEW_FILE_ICON 1004 + +#define IDC_STATIC_OVERWRITE_OLD_FILE_SIZE_TIME 1005 +#define IDC_STATIC_OVERWRITE_NEW_FILE_SIZE_TIME 1006 + +#define IDC_BUTTON_OVERWRITE_YES_TO_ALL 1010 +#define IDC_BUTTON_OVERWRITE_NO_TO_ALL 1011 +#define IDC_BUTTON_OVERWRITE_AUTO_RENAME 1012 diff --git a/CPP/7zip/FileManager/Resource/OverwriteDialog/resource.rc b/CPP/7zip/FileManager/Resource/OverwriteDialog/resource.rc new file mode 100755 index 00000000..1a907955 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/OverwriteDialog/resource.rc @@ -0,0 +1,47 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" + +#define xSize2 357 +#define ySize2 204 + +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#undef iconSize +#define iconSize 20 + +#undef fiXPos +#undef fiXSize +#undef fiYSize +#define fiXPos (iconSize + 12) +#define fiXSize (xSize2 - fiXPos) +#define fiYSize 50 + +#define b1YPos (ySize - marg - bYSize) +#define b2YPos (b1YPos - bYSize - 10) + +IDD_DIALOG_OVERWRITE DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE +CAPTION "Confirm File Replace" +MY_FONT +BEGIN + LTEXT "Destination folder already contains processed file.", IDC_STATIC_OVERWRITE_HEADER, marg, 7, xSize2, 8 + LTEXT "Would you like to replace the existing file", IDC_STATIC_OVERWRITE_QUESTION_BEGIN, marg, 28, xSize2, 8 + ICON "", IDC_STATIC_OVERWRITE_OLD_FILE_ICON, marg, 44, iconSize, iconSize + LTEXT "", IDC_STATIC_OVERWRITE_OLD_FILE_SIZE_TIME, fiXPos, 44, fiXSize, fiYSize, SS_NOPREFIX + LTEXT "with this one?",IDC_STATIC_OVERWRITE_QUESTION_END, marg, 98, xSize2, 8 + ICON "",IDC_STATIC_OVERWRITE_NEW_FILE_ICON, marg, 114, iconSize, iconSize + LTEXT "",IDC_STATIC_OVERWRITE_NEW_FILE_SIZE_TIME, fiXPos, 114, fiXSize, fiYSize, SS_NOPREFIX + PUSHBUTTON "&Yes", IDYES, 78, b2YPos, bXSize, bYSize + PUSHBUTTON "Yes to &All", IDC_BUTTON_OVERWRITE_YES_TO_ALL, 152, b2YPos, bXSize, bYSize + PUSHBUTTON "&No", IDNO, 226, b2YPos, bXSize, bYSize + PUSHBUTTON "No to A&ll", IDC_BUTTON_OVERWRITE_NO_TO_ALL, 300, b2YPos, bXSize, bYSize + PUSHBUTTON "A&uto Rename", IDC_BUTTON_OVERWRITE_AUTO_RENAME, 181, b1YPos, 109, bYSize + PUSHBUTTON "&Cancel", IDCANCEL, 300, b1YPos, bXSize, bYSize +END + + +STRINGTABLE +BEGIN + IDS_FILE_MODIFIED "modified on" + IDS_FILE_SIZE "{0} bytes" +END diff --git a/CPP/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.cpp b/CPP/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.cpp new file mode 100755 index 00000000..4f09f7f7 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.cpp @@ -0,0 +1,50 @@ +// PasswordDialog.cpp + +#include "StdAfx.h" +#include "PasswordDialog.h" + +#ifdef LANG +#include "../../LangUtils.h" +#endif + +#ifdef LANG +static CIDLangPair kIDLangPairs[] = +{ + { IDC_STATIC_PASSWORD_HEADER, 0x02000B01 }, + { IDC_CHECK_PASSWORD_SHOW, 0x02000B02 }, + +}; +#endif + + +bool CPasswordDialog::OnInit() +{ + #ifdef LANG + LangSetWindowText(HWND(*this), 0x02000B00); + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + #endif + _passwordControl.Attach(GetItem(IDC_EDIT_PASSWORD)); + _passwordControl.SetText(Password); + _passwordControl.SetPasswordChar(TEXT('*')); + return CModalDialog::OnInit(); +} + +bool CPasswordDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + if (buttonID == IDC_CHECK_PASSWORD_SHOW) + { + _passwordControl.SetPasswordChar((IsButtonChecked( + IDC_CHECK_PASSWORD_SHOW) == BST_CHECKED) ? 0: TEXT('*')); + UString password; + _passwordControl.GetText(password); + _passwordControl.SetText(password); + return true; + } + return CDialog::OnButtonClicked(buttonID, buttonHWND); +} + +void CPasswordDialog::OnOK() +{ + _passwordControl.GetText(Password); + CModalDialog::OnOK(); +} diff --git a/CPP/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.h b/CPP/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.h new file mode 100755 index 00000000..f77cd2be --- /dev/null +++ b/CPP/7zip/FileManager/Resource/PasswordDialog/PasswordDialog.h @@ -0,0 +1,21 @@ +// PasswordDialog.h + +#ifndef __PASSWORDDIALOG_H +#define __PASSWORDDIALOG_H + +#include "Windows/Control/Dialog.h" +#include "Windows/Control/Edit.h" +#include "resource.h" + +class CPasswordDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CEdit _passwordControl; + virtual void OnOK(); + virtual bool OnInit(); + virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); +public: + UString Password; + INT_PTR Create(HWND parentWindow = 0) { return CModalDialog::Create(IDD_DIALOG_PASSWORD, parentWindow); } +}; + +#endif diff --git a/CPP/7zip/FileManager/Resource/PasswordDialog/StdAfx.h b/CPP/7zip/FileManager/Resource/PasswordDialog/StdAfx.h new file mode 100755 index 00000000..a444ca31 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/PasswordDialog/StdAfx.h @@ -0,0 +1,16 @@ +// stdafx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#define _WIN32_WINNT 0x0400 + +// it's for Windows NT supporting (MENUITEMINFOW) +#define WINVER 0x0400 + +#include +#include + +#include "Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/FileManager/Resource/PasswordDialog/resource.h b/CPP/7zip/FileManager/Resource/PasswordDialog/resource.h new file mode 100755 index 00000000..e0b42661 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/PasswordDialog/resource.h @@ -0,0 +1,4 @@ +#define IDD_DIALOG_PASSWORD 501 +#define IDC_STATIC_PASSWORD_HEADER 1000 +#define IDC_EDIT_PASSWORD 1001 +#define IDC_CHECK_PASSWORD_SHOW 1002 diff --git a/CPP/7zip/FileManager/Resource/PasswordDialog/resource.rc b/CPP/7zip/FileManager/Resource/PasswordDialog/resource.rc new file mode 100755 index 00000000..7e2658c7 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/PasswordDialog/resource.rc @@ -0,0 +1,26 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" + +#define xSize2 172 +#define ySize2 68 +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#define bYPos (ySize - marg - bYSize) +#define b1XPos (xSize - marg - bXSize) +#define b2XPos (b1XPos - 10 - bXSize) + + +IDD_DIALOG_PASSWORD DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE +CAPTION "Enter password" +MY_FONT +BEGIN + LTEXT "&Enter password:", IDC_STATIC_PASSWORD_HEADER, marg, marg, xSize2, 8 + EDITTEXT IDC_EDIT_PASSWORD, marg , 19, xSize2, 14, ES_PASSWORD | ES_AUTOHSCROLL + + CONTROL "&Show password", IDC_CHECK_PASSWORD_SHOW, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, 41, xSize2, 10 + + DEFPUSHBUTTON "OK", IDOK, b2XPos, bYPos, bXSize, bYSize + PUSHBUTTON "Cancel", IDCANCEL, b1XPos, bYPos, bXSize, bYSize +END diff --git a/CPP/7zip/FileManager/Resource/PluginsPage/PluginsPage.cpp b/CPP/7zip/FileManager/Resource/PluginsPage/PluginsPage.cpp new file mode 100755 index 00000000..0ccdf07e --- /dev/null +++ b/CPP/7zip/FileManager/Resource/PluginsPage/PluginsPage.cpp @@ -0,0 +1,220 @@ +// PluginsPage.cpp + +#include "StdAfx.h" +#include "resource.h" +#include "PluginsPage.h" + +#include "Common/StringConvert.h" +#include "Common/MyCom.h" + +#include "Windows/Defs.h" +#include "Windows/DLL.h" +#include "Windows/Control/ListView.h" +#include "Windows/FileFind.h" + +#include "../../RegistryUtils.h" +#include "../../HelpUtils.h" +#include "../../LangUtils.h" +#include "../../ProgramLocation.h" + +#include "../../PluginInterface.h" + +static CIDLangPair kIDLangPairs[] = +{ + { IDC_PLUGINS_STATIC_PLUGINS, 0x03010101}, + { IDC_PLUGINS_BUTTON_OPTIONS, 0x03010110} +}; + +static LPCWSTR kPluginsTopic = L"FM/options.htm#plugins"; + +bool CPluginsPage::OnInit() +{ + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + + _listView.Attach(GetItem(IDC_PLUGINS_LIST)); + + UINT32 newFlags = /*LVS_EX_CHECKBOXES | */ LVS_EX_FULLROWSELECT; + _listView.SetExtendedListViewStyle(newFlags, newFlags); + + UString title = L"Plugins"; + LVCOLUMNW column; + column.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_FMT | LVCF_SUBITEM; + column.cx = 160; + column.fmt = LVCFMT_LEFT; + column.pszText = (LPWSTR)(LPCWSTR)title; + column.iSubItem = 0; + _listView.InsertColumn(0, &column); + + ReadFileFolderPluginInfoList(_plugins); + + _listView.SetRedraw(false); + // _listView.DeleteAllItems(); + for(int i = 0; i < _plugins.Size(); i++) + { + LVITEMW item; + item.iItem = i; + item.mask = LVIF_TEXT | LVIF_STATE; + UString pluginName = _plugins[i].Name; + item.pszText = (WCHAR *)(const WCHAR *)pluginName; + item.state = 0; + item.stateMask = UINT(-1); + item.iSubItem = 0; + _listView.InsertItem(&item); + _listView.SetCheckState(i, true); + } + _listView.SetRedraw(true); + if(_listView.GetItemCount() > 0) + { + UINT state = LVIS_SELECTED | LVIS_FOCUSED; + _listView.SetItemState(0, state, state); + } + + return CPropertyPage::OnInit(); +} + +LONG CPluginsPage::OnApply() +{ + /* + int selectedIndex = m_Lang.GetCurSel(); + int aPathIndex = m_Lang.GetItemData(selectedIndex); + SaveRegLang(m_Paths[aPathIndex]); + ReloadLang(); + */ + return PSNRET_NOERROR; +} + +void CPluginsPage::OnNotifyHelp() +{ + ShowHelpWindow(NULL, kPluginsTopic); +} + +bool CPluginsPage::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) + { + case IDC_PLUGINS_BUTTON_OPTIONS: + OnButtonOptions(); + break; + default: + return CPropertyPage::OnButtonClicked(buttonID, buttonHWND); + } + return true; +} + +class CPluginOptionsCallback: + public IPluginOptionsCallback, + public CMyUnknownImp +{ + UString _pluginName; +public: + MY_UNKNOWN_IMP + + STDMETHOD(GetProgramFolderPath)(BSTR *value); + STDMETHOD(GetProgramPath)(BSTR *Value); + STDMETHOD(GetRegistryCUPath)(BSTR *Value); + void Init(const UString &pluginName) + { _pluginName = pluginName; } +}; + +STDMETHODIMP CPluginOptionsCallback::GetProgramFolderPath(BSTR *value) +{ + *value = 0; + UString folder; + if (!::GetProgramFolderPath(folder)) + return E_FAIL; + CMyComBSTR valueTemp = folder; + *value = valueTemp.Detach(); + return S_OK; +} + +static UString GetDefaultProgramName() +{ + return L"7zFM.exe"; +} + +STDMETHODIMP CPluginOptionsCallback::GetProgramPath(BSTR *value) +{ + *value = 0; + UString folder; + if (!::GetProgramFolderPath(folder)) + return E_FAIL; + CMyComBSTR valueTemp = folder + GetDefaultProgramName(); + *value = valueTemp.Detach(); + return S_OK; +} + +STDMETHODIMP CPluginOptionsCallback::GetRegistryCUPath(BSTR *value) +{ + CMyComBSTR valueTemp = UString(L"Software\\7-Zip\\FM\\Plugins\\") + _pluginName; + *value = valueTemp.Detach(); + return S_OK; +} + +void CPluginsPage::OnButtonOptions() +{ + int index = _listView.GetSelectionMark(); + if (index < 0) + return; + + CPluginInfo pluginInfo = _plugins[index]; + if (!pluginInfo.OptionsClassIDDefined) + { + MessageBoxW(HWND(*this), L"There are no options", L"7-Zip", 0); + return; + } + NWindows::NDLL::CLibrary library; + CMyComPtr 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 callback(callbackSpec); + callbackSpec->Init(pluginInfo.Name); + pluginOptions->PluginOptions(HWND(*this), callback); +} + +bool CPluginsPage::OnNotify(UINT controlID, LPNMHDR lParam) +{ + if (lParam->hwndFrom == HWND(_listView) && lParam->code == LVN_ITEMCHANGED) + { + const NMLISTVIEW *aNMListView = (const NMLISTVIEW *)lParam; + if ((aNMListView->uChanged & LVIF_STATE) != 0) + { + UINT oldState = aNMListView->uOldState & LVIS_STATEIMAGEMASK; + UINT newState = aNMListView->uNewState & LVIS_STATEIMAGEMASK; + if (oldState != newState) + Changed(); + } + return true; + } + return CPropertyPage::OnNotify(controlID, lParam); +} + +/* +bool CPluginsPage::OnCommand(int code, int itemID, LPARAM lParam) +{ + if (code == CBN_SELCHANGE && itemID == IDC_LANG_COMBO_LANG) + { + Changed(); + return true; + } + return CPropertyPage::OnCommand(code, itemID, lParam); +} + +*/ \ No newline at end of file diff --git a/CPP/7zip/FileManager/Resource/PluginsPage/PluginsPage.h b/CPP/7zip/FileManager/Resource/PluginsPage/PluginsPage.h new file mode 100755 index 00000000..78e81dbb --- /dev/null +++ b/CPP/7zip/FileManager/Resource/PluginsPage/PluginsPage.h @@ -0,0 +1,26 @@ +// PluginsPage.h + +#include "Windows/Control/ListView.h" + +#ifndef __PLUGINSPAGE_H +#define __PLUGINSPAGE_H + +#include "Windows/Control/PropertyPage.h" +#include "Windows/Control/ComboBox.h" + +#include "../../RegistryPlugins.h" + +class CPluginsPage: public NWindows::NControl::CPropertyPage +{ + NWindows::NControl::CListView _listView; + CObjectVector _plugins; +public: + virtual bool OnInit(); + virtual void OnNotifyHelp(); + virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); + virtual void OnButtonOptions(); + virtual LONG OnApply(); + virtual bool OnNotify(UINT controlID, LPNMHDR lParam); +}; + +#endif diff --git a/CPP/7zip/FileManager/Resource/PluginsPage/StdAfx.h b/CPP/7zip/FileManager/Resource/PluginsPage/StdAfx.h new file mode 100755 index 00000000..a444ca31 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/PluginsPage/StdAfx.h @@ -0,0 +1,16 @@ +// stdafx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#define _WIN32_WINNT 0x0400 + +// it's for Windows NT supporting (MENUITEMINFOW) +#define WINVER 0x0400 + +#include +#include + +#include "Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/FileManager/Resource/PluginsPage/resource.h b/CPP/7zip/FileManager/Resource/PluginsPage/resource.h new file mode 100755 index 00000000..8fc923ee --- /dev/null +++ b/CPP/7zip/FileManager/Resource/PluginsPage/resource.h @@ -0,0 +1,4 @@ +#define IDD_PLUGINS 901 +#define IDC_PLUGINS_STATIC_PLUGINS 1000 +#define IDC_PLUGINS_LIST 1001 +#define IDC_PLUGINS_BUTTON_OPTIONS 1002 diff --git a/CPP/7zip/FileManager/Resource/PluginsPage/resource.rc b/CPP/7zip/FileManager/Resource/PluginsPage/resource.rc new file mode 100755 index 00000000..7b74107b --- /dev/null +++ b/CPP/7zip/FileManager/Resource/PluginsPage/resource.rc @@ -0,0 +1,19 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" + +#define xSize2 196 +#define ySize2 140 +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + + +IDD_PLUGINS DIALOG 0, 0, xSize, ySize MY_PAGE_STYLE +CAPTION "Plugins" +MY_FONT +BEGIN + LTEXT "&Plugins:", IDC_PLUGINS_STATIC_PLUGINS, marg, marg, xSize2, 8 + CONTROL "List1", IDC_PLUGINS_LIST, "SysListView32", LVS_REPORT | LVS_SHOWSELALWAYS | + LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, + marg, 20, xSize2 - bXSize - 12, ySize2 - 12 + PUSHBUTTON "Options...", IDC_PLUGINS_BUTTON_OPTIONS, (xSize - marg - bXSize), 20, bXSize, bYSize +END diff --git a/CPP/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.cpp b/CPP/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.cpp new file mode 100755 index 00000000..ea0f6fd6 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.cpp @@ -0,0 +1,175 @@ +// ProgressDialog.cpp + +#include "StdAfx.h" +#include "resource.h" +#include "ProgressDialog.h" +#include "Common/IntToString.h" +#include "Common/IntToString.h" + +using namespace NWindows; + +static const UINT_PTR kTimerID = 3; +static const UINT kTimerElapse = 50; + +#ifdef LANG +#include "../../LangUtils.h" +#endif + +#ifdef LANG +static CIDLangPair kIDLangPairs[] = +{ + { IDCANCEL, 0x02000711 } +}; +#endif + +#ifndef _SFX +CProgressDialog::~CProgressDialog() +{ + AddToTitle(TEXT("")); +} +void CProgressDialog::AddToTitle(LPCWSTR s) +{ + if (MainWindow != 0) + ::MySetWindowText(MainWindow, UString(s) + MainTitle); +} +#endif + + + +bool CProgressDialog::OnInit() +{ + _range = UINT64(-1); + _prevPercentValue = -1; + + #ifdef LANG + // LangSetWindowText(HWND(*this), 0x02000C00); + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + #endif + + m_ProgressBar.Attach(GetItem(IDC_PROGRESS1)); + _timer = SetTimer(kTimerID, kTimerElapse); + _dialogCreatedEvent.Set(); + SetText(_title); + return CModalDialog::OnInit(); +} + +void CProgressDialog::OnCancel() +{ + ProgressSynch.SetStopped(true); +} + +void CProgressDialog::SetRange(UINT64 range) +{ + _range = range; + _peviousPos = (UInt64)(Int64)-1; + _converter.Init(range); + m_ProgressBar.SetRange32(0 , _converter.Count(range)); // Test it for 100% +} + +void CProgressDialog::SetPos(UINT64 pos) +{ + bool redraw = true; + if (pos < _range && pos > _peviousPos) + { + UINT64 posDelta = pos - _peviousPos; + if (posDelta < (_range >> 10)) + redraw = false; + } + if(redraw) + { + m_ProgressBar.SetPos(_converter.Count(pos)); // Test it for 100% + _peviousPos = pos; + } +} + +bool CProgressDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */) +{ + if (ProgressSynch.GetPaused()) + return true; + UINT64 total, completed; + ProgressSynch.GetProgress(total, completed); + if (total != _range) + SetRange(total); + SetPos(completed); + + if (total == 0) + total = 1; + + int percentValue = (int)(completed * 100 / total); + if (percentValue != _prevPercentValue) + { + wchar_t s[64]; + ConvertUInt64ToString(percentValue, s); + UString title = s; + title += L"% "; + SetText(title + _title); + #ifndef _SFX + AddToTitle(title + MainAddTitle); + #endif + _prevPercentValue = percentValue; + } + return true; +} + + +//////////////////// +// CU64ToI32Converter + +static const UINT64 kMaxIntValue = 0x7FFFFFFF; + +void CU64ToI32Converter::Init(UINT64 range) +{ + _numShiftBits = 0; + while(range > kMaxIntValue) + { + range >>= 1; + _numShiftBits++; + } +} + +int CU64ToI32Converter::Count(UINT64 aValue) +{ + return int(aValue >> _numShiftBits); +} + +const UINT CProgressDialog::kCloseMessage = WM_USER + 1; + +bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch(message) + { + case kCloseMessage: + { + KillTimer(_timer); + _timer = 0; + End(0); + return true; + } + case WM_SETTEXT: + { + if (_timer == 0) + return true; + } + } + return CModalDialog::OnMessage(message, wParam, lParam); +} + +bool CProgressDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) + { + case IDCANCEL: + { + bool paused = ProgressSynch.GetPaused();; + ProgressSynch.SetPaused(true); + int res = ::MessageBoxW(HWND(*this), + L"Are you sure you want to cancel?", + _title, MB_YESNOCANCEL); + ProgressSynch.SetPaused(paused); + if (res == IDCANCEL || res == IDNO) + return true; + break; + } + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} diff --git a/CPP/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.h b/CPP/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.h new file mode 100755 index 00000000..e11ffc51 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/ProgressDialog/ProgressDialog.h @@ -0,0 +1,129 @@ +// ProgressDialog.h + +#ifndef __PROGRESSDIALOG_H +#define __PROGRESSDIALOG_H + +#include "resource.h" + +#include "Windows/Control/Dialog.h" +#include "Windows/Control/ProgressBar.h" +#include "Windows/Synchronization.h" + +class CProgressSynch +{ + NWindows::NSynchronization::CCriticalSection _criticalSection; + bool _stopped; + bool _paused; + UINT64 _total; + UINT64 _completed; +public: + CProgressSynch(): _stopped(false), _paused(false), _total(1), _completed(0) {} + + bool GetStopped() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + return _stopped; + } + void SetStopped(bool value) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + _stopped = value; + } + bool GetPaused() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + return _paused; + } + void SetPaused(bool value) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + _paused = value; + } + void SetProgress(UINT64 total, UINT64 completed) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + _total = total; + _completed = completed; + } + void SetPos(UINT64 completed) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + _completed = completed; + } + void GetProgress(UINT64 &total, UINT64 &completed) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + total = _total; + completed = _completed; + } +}; + +class CU64ToI32Converter +{ + UINT64 _numShiftBits; +public: + void Init(UINT64 _range); + int Count(UINT64 aValue); +}; + +// class CProgressDialog: public NWindows::NControl::CModelessDialog + +class CProgressDialog: public NWindows::NControl::CModalDialog +{ +private: + UINT_PTR _timer; + + UString _title; + CU64ToI32Converter _converter; + UINT64 _peviousPos; + UINT64 _range; + NWindows::NControl::CProgressBar m_ProgressBar; + + int _prevPercentValue; + + bool OnTimer(WPARAM timerID, LPARAM callback); + void SetRange(UINT64 range); + void SetPos(UINT64 pos); + virtual bool OnInit(); + virtual void OnCancel(); + NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent; + #ifndef _SFX + void AddToTitle(LPCWSTR string); + #endif + bool OnButtonClicked(int buttonID, HWND buttonHWND); +public: + CProgressSynch ProgressSynch; + + #ifndef _SFX + HWND MainWindow; + UString MainTitle; + UString MainAddTitle; + ~CProgressDialog(); + #endif + + CProgressDialog(): _timer(0) + #ifndef _SFX + ,MainWindow(0) + #endif + {} + + void WaitCreating() { _dialogCreatedEvent.Lock(); } + + + INT_PTR Create(const UString &title, HWND wndParent = 0) + { + _title = title; + return CModalDialog::Create(IDD_DIALOG_PROGRESS, wndParent); + } + + static const UINT kCloseMessage; + + virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); + + void MyClose() + { + PostMessage(kCloseMessage); + }; +}; + +#endif diff --git a/CPP/7zip/FileManager/Resource/ProgressDialog/StdAfx.h b/CPP/7zip/FileManager/Resource/ProgressDialog/StdAfx.h new file mode 100755 index 00000000..a444ca31 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/ProgressDialog/StdAfx.h @@ -0,0 +1,16 @@ +// stdafx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#define _WIN32_WINNT 0x0400 + +// it's for Windows NT supporting (MENUITEMINFOW) +#define WINVER 0x0400 + +#include +#include + +#include "Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/FileManager/Resource/ProgressDialog/resource.h b/CPP/7zip/FileManager/Resource/ProgressDialog/resource.h new file mode 100755 index 00000000..97e47228 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/ProgressDialog/resource.h @@ -0,0 +1,3 @@ +#define IDD_DIALOG_PROGRESS 500 + +#define IDC_PROGRESS1 1000 diff --git a/CPP/7zip/FileManager/Resource/ProgressDialog/resource.rc b/CPP/7zip/FileManager/Resource/ProgressDialog/resource.rc new file mode 100755 index 00000000..a6b375ed --- /dev/null +++ b/CPP/7zip/FileManager/Resource/ProgressDialog/resource.rc @@ -0,0 +1,20 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" + +#define xSize2 172 +#define ySize2 42 +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#define bYPos (ySize - marg - bYSize) +#define bXPos (xSize - marg - bXSize) + + +IDD_DIALOG_PROGRESS DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE +CAPTION "Progress" +MY_FONT +BEGIN + PUSHBUTTON "Cancel", IDCANCEL, bXPos, bYPos , bXSize, bYSize + CONTROL "Progress1", IDC_PROGRESS1,"msctls_progress32",PBS_SMOOTH | WS_BORDER, + marg,marg, xSize2, 14 +END diff --git a/CPP/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.cpp b/CPP/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.cpp new file mode 100755 index 00000000..e5a496bd --- /dev/null +++ b/CPP/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.cpp @@ -0,0 +1,432 @@ +// ProgressDialog.cpp + +#include "StdAfx.h" +#include "resource.h" +#include "ProgressDialog.h" +#include "Common/IntToString.h" +#include "Common/IntToString.h" + +using namespace NWindows; + +static const UINT_PTR kTimerID = 3; +static const UINT kTimerElapse = 50; + +#ifdef LANG +#include "../../LangUtils.h" +#endif + +#ifdef LANG +static CIDLangPair kIDLangPairs[] = +{ + { IDCANCEL, 0x02000C00 }, + { IDC_PROGRESS_ELAPSED, 0x02000C01 }, + { IDC_PROGRESS_REMAINING, 0x02000C02 }, + { IDC_PROGRESS_TOTAL, 0x02000C03 }, + { IDC_PROGRESS_SPEED, 0x02000C04 }, + { IDC_BUTTON_PROGRESS_PRIORITY, 0x02000C10 }, + { IDC_BUTTON_PAUSE, 0x02000C12 }, + { IDCANCEL, 0x02000711 }, +}; +#endif + +HRESULT CProgressSynch::SetPosAndCheckPaused(UInt64 completed) +{ + for (;;) + { + if(GetStopped()) + return E_ABORT; + if(!GetPaused()) + break; + ::Sleep(100); + } + SetPos(completed); + return S_OK; +} + +#ifndef _SFX +CProgressDialog::~CProgressDialog() +{ + AddToTitle(L""); +} +void CProgressDialog::AddToTitle(LPCWSTR s) +{ + if (MainWindow != 0) + { + CWindow window(MainWindow); + window.SetText(s + UString(MainTitle)); + } +} + +static const int kTitleFileNameSizeLimit = 36; +static const int kCurrentFileNameSizeLimit = 68; + +static void ReduceString(UString &s, int size) +{ + if (s.Length() > size) + s = s.Left(size / 2) + UString(L" ... ") + s.Right(size / 2); +} +#endif + +bool CProgressDialog::OnInit() +{ + _range = (UInt64)(Int64)(-1); + _prevPercentValue = UInt32(-1); + _prevElapsedSec = UInt32(-1); + _prevRemainingSec = UInt32(-1); + _prevSpeed = UInt32(-1); + _prevMode = kSpeedBytes; + _prevTime = ::GetTickCount(); + _elapsedTime = 0; + _foreground = true; + + #ifdef LANG + // LangSetWindowText(HWND(*this), 0x02000C00); + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + #endif + + + CWindow window(GetItem(IDC_BUTTON_PROGRESS_PRIORITY)); + window.GetText(backgroundString); + backgroundedString = backgroundString; + backgroundedString.Replace(L"&", L""); + + window = GetItem(IDC_BUTTON_PAUSE); + window.GetText(pauseString); + + foregroundString = LangString(IDS_PROGRESS_FOREGROUND, 0x02000C11); + continueString = LangString(IDS_PROGRESS_CONTINUE, 0x02000C13); + pausedString = LangString(IDS_PROGRESS_PAUSED, 0x02000C20); + + m_ProgressBar.Attach(GetItem(IDC_PROGRESS1)); + _timer = SetTimer(kTimerID, kTimerElapse); + _dialogCreatedEvent.Set(); + SetText(_title); + SetPauseText(); + SetPriorityText(); + return CModalDialog::OnInit(); +} + +void CProgressDialog::OnCancel() +{ + ProgressSynch.SetStopped(true); +} + +static void ConvertSizeToString(UInt64 value, wchar_t *s) +{ + const wchar_t *kModif = L" KMGTP"; + for (int i = 0; ; i++) + if (i == 5 || value < (UInt64(10000) << (i * 10))) + { + ConvertUInt64ToString(value >> (i * 10), s); + s += wcslen(s); + *s++ = ' '; + if (i != 0) + *s++ = kModif[i]; + *s++ = L'B'; + *s++ = L'\0'; + return; + } +} + +void CProgressDialog::SetRange(UInt64 range) +{ + _range = range; + _previousPos = (UInt64)(Int64)-1; + _converter.Init(range); + m_ProgressBar.SetRange32(0 , _converter.Count(range)); // Test it for 100% + + wchar_t s[32]; + ConvertSizeToString(_range, s); + SetItemText(IDC_PROGRESS_SPEED_TOTAL_VALUE, s); +} + +void CProgressDialog::SetPos(UInt64 pos) +{ + bool redraw = true; + if (pos < _range && pos > _previousPos) + { + if (pos - _previousPos < (_range >> 10)) + redraw = false; + } + if(redraw) + { + m_ProgressBar.SetPos(_converter.Count(pos)); // Test it for 100% + _previousPos = pos; + } +} + +static void GetTimeString(UInt64 timeValue, TCHAR *s) +{ + wsprintf(s, TEXT("%02d:%02d:%02d"), + UInt32(timeValue / 3600), + UInt32((timeValue / 60) % 60), + UInt32(timeValue % 60)); +} + +bool CProgressDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */) +{ + if (ProgressSynch.GetPaused()) + return true; + UInt64 total, completed; + ProgressSynch.GetProgress(total, completed); + + UInt32 curTime = ::GetTickCount(); + + if (total != _range) + SetRange(total); + if (total == (UInt64)(Int64)-1) + { + SetPos(0); + SetRange(completed); + } + else + SetPos(completed); + + _elapsedTime += (curTime - _prevTime); + _prevTime = curTime; + + UInt32 elapsedSec = _elapsedTime / 1000; + + bool elapsedChanged = false; + if (elapsedSec != _prevElapsedSec) + { + TCHAR s[40]; + GetTimeString(elapsedSec, s); + SetItemText(IDC_PROGRESS_ELAPSED_VALUE, s); + _prevElapsedSec = elapsedSec; + elapsedChanged = true; + } + + if (completed != 0 && elapsedChanged) + { + if (total == (UInt64)(Int64)-1) + { + SetItemText(IDC_PROGRESS_REMAINING_VALUE, L""); + } + else + { + UInt64 remainingTime = 0; + if (completed < total) + remainingTime = _elapsedTime * (total - completed) / completed; + UInt64 remainingSec = remainingTime / 1000; + if (remainingSec != _prevRemainingSec) + { + TCHAR s[40]; + GetTimeString(remainingSec, s); + SetItemText(IDC_PROGRESS_REMAINING_VALUE, s); + _prevRemainingSec = remainingSec; + } + } + // if (elapsedChanged) + { + UInt64 speedB = (completed * 1000) / _elapsedTime; + UInt64 speedKB = speedB / 1024; + UInt64 speedMB = speedKB / 1024; + const UInt32 kLimit1 = 10; + TCHAR s[40]; + bool needRedraw = false; + if (speedMB >= kLimit1) + { + if (_prevMode != kSpeedMBytes || speedMB != _prevSpeed) + { + ConvertUInt64ToString(speedMB, s); + lstrcat(s, TEXT(" MB/s")); + _prevMode = kSpeedMBytes; + _prevSpeed = speedMB; + needRedraw = true; + } + } + else if (speedKB >= kLimit1) + { + if (_prevMode != kSpeedKBytes || speedKB != _prevSpeed) + { + ConvertUInt64ToString(speedKB, s); + lstrcat(s, TEXT(" KB/s")); + _prevMode = kSpeedKBytes; + _prevSpeed = speedKB; + needRedraw = true; + } + } + else + { + if (_prevMode != kSpeedBytes || speedB != _prevSpeed) + { + ConvertUInt64ToString(speedB, s); + lstrcat(s, TEXT(" B/s")); + _prevMode = kSpeedBytes; + _prevSpeed = speedB; + needRedraw = true; + } + } + if (needRedraw) + SetItemText(IDC_PROGRESS_SPEED_VALUE, s); + } + } + + if (total == 0) + total = 1; + UInt32 percentValue = (UInt32)(completed * 100 / total); + UString titleName; + ProgressSynch.GetTitleFileName(titleName); + if (percentValue != _prevPercentValue || _prevTitleName != titleName) + { + _prevPercentValue = percentValue; + SetTitleText(); + _prevTitleName = titleName; + } + UString fileName; + ProgressSynch.GetCurrentFileName(fileName); + if (_prevFileName != fileName) + { + ReduceString(fileName, kCurrentFileNameSizeLimit); + SetItemText(IDC_PROGRESS_FILE_NAME, fileName); + _prevFileName == fileName; + } + + return true; +} + + +//////////////////// +// CU64ToI32Converter + +static const UInt64 kMaxIntValue = 0x7FFFFFFF; + +void CU64ToI32Converter::Init(UInt64 range) +{ + _numShiftBits = 0; + while(range > kMaxIntValue) + { + range >>= 1; + _numShiftBits++; + } +} + +int CU64ToI32Converter::Count(UInt64 aValue) +{ + return int(aValue >> _numShiftBits); +} + +const UINT CProgressDialog::kCloseMessage = WM_USER + 1; + +bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch(message) + { + case kCloseMessage: + { + KillTimer(_timer); + _timer = 0; + End(0); + return true; + } + case WM_SETTEXT: + { + if (_timer == 0) + return true; + } + } + return CModalDialog::OnMessage(message, wParam, lParam); +} + +void CProgressDialog::SetTitleText() +{ + UString title; + if (ProgressSynch.GetPaused()) + { + title = pausedString; + title += L" "; + } + if (_prevPercentValue != UInt32(-1)) + { + wchar_t s[64]; + ConvertUInt64ToString(_prevPercentValue, s); + title += s; + title += L"%"; + } + if (!_foreground) + { + title += L" "; + title += backgroundedString; + } + title += L" "; + UString totalTitle = title + _title; + UString fileName; + ProgressSynch.GetTitleFileName(fileName); + if (!fileName.IsEmpty()) + { + ReduceString(fileName, kTitleFileNameSizeLimit); + totalTitle += L" "; + totalTitle += fileName; + } + SetText(totalTitle); + #ifndef _SFX + AddToTitle(title + MainAddTitle); + #endif +} + +void CProgressDialog::SetPauseText() +{ + SetItemText(IDC_BUTTON_PAUSE, ProgressSynch.GetPaused() ? + continueString : pauseString); + SetTitleText(); +} + +void CProgressDialog::OnPauseButton() +{ + bool paused = !ProgressSynch.GetPaused(); + ProgressSynch.SetPaused(paused); + UInt32 curTime = ::GetTickCount(); + if (paused) + _elapsedTime += (curTime - _prevTime); + _prevTime = curTime; + SetPauseText(); +} + +void CProgressDialog::SetPriorityText() +{ + SetItemText(IDC_BUTTON_PROGRESS_PRIORITY, _foreground ? + backgroundString : + foregroundString); + SetTitleText(); +} + +void CProgressDialog::OnPriorityButton() +{ + _foreground = !_foreground; + SetPriorityClass(GetCurrentProcess(), _foreground ? + NORMAL_PRIORITY_CLASS: IDLE_PRIORITY_CLASS); + SetPriorityText(); +} + +bool CProgressDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) + { + case IDCANCEL: + { + bool paused = ProgressSynch.GetPaused();; + // ProgressSynch.SetPaused(true); + if (!paused) + OnPauseButton(); + int res = ::MessageBoxW(HWND(*this), + LangString(IDS_PROGRESS_ASK_CANCEL, 0x02000C30), + _title, MB_YESNOCANCEL); + // ProgressSynch.SetPaused(paused); + if (!paused) + OnPauseButton(); + if (res == IDCANCEL || res == IDNO) + return true; + break; + } + case IDC_BUTTON_PAUSE: + OnPauseButton(); + return true; + case IDC_BUTTON_PROGRESS_PRIORITY: + { + OnPriorityButton(); + return true; + } + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} diff --git a/CPP/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.h b/CPP/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.h new file mode 100755 index 00000000..0625eadd --- /dev/null +++ b/CPP/7zip/FileManager/Resource/ProgressDialog2/ProgressDialog.h @@ -0,0 +1,184 @@ +// ProgressDialog.h + +#ifndef __PROGRESSDIALOG_H +#define __PROGRESSDIALOG_H + +#include "resource.h" + +#include "Common/Types.h" + +#include "Windows/Control/Dialog.h" +#include "Windows/Control/ProgressBar.h" +#include "Windows/Synchronization.h" + +class CProgressSynch +{ + NWindows::NSynchronization::CCriticalSection _criticalSection; + bool _stopped; + bool _paused; + UInt64 _total; + UInt64 _completed; + UString TitleFileName; + UString CurrentFileName; +public: + CProgressSynch(): _stopped(false), _paused(false), _total((UInt64)(Int64)-1), _completed(0) {} + + bool GetStopped() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + return _stopped; + } + void SetStopped(bool value) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + _stopped = value; + } + bool GetPaused() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + return _paused; + } + void SetPaused(bool value) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + _paused = value; + } + void SetProgress(UInt64 total, UInt64 completed) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + _total = total; + _completed = completed; + } + void SetPos(UInt64 completed) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + _completed = completed; + } + HRESULT SetPosAndCheckPaused(UInt64 completed); + void GetProgress(UInt64 &total, UInt64 &completed) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + total = _total; + completed = _completed; + } + void SetTitleFileName(const UString &fileName) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + TitleFileName = fileName; + } + void GetTitleFileName(UString &fileName) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + fileName = TitleFileName; + } + void SetCurrentFileName(const UString &fileName) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + CurrentFileName = fileName; + } + void GetCurrentFileName(UString &fileName) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + fileName = CurrentFileName; + } +}; + +class CU64ToI32Converter +{ + UInt64 _numShiftBits; +public: + void Init(UInt64 _range); + int Count(UInt64 aValue); +}; + +// class CProgressDialog: public NWindows::NControl::CModelessDialog + +enum ESpeedMode +{ + kSpeedBytes, + kSpeedKBytes, + kSpeedMBytes +}; + +class CProgressDialog: public NWindows::NControl::CModalDialog +{ + UString _prevFileName; + UString _prevTitleName; +private: + UString backgroundString; + UString backgroundedString; + UString foregroundString; + UString pauseString; + UString continueString; + UString pausedString; + + + + UINT_PTR _timer; + + UString _title; + CU64ToI32Converter _converter; + UInt64 _previousPos; + UInt64 _range; + NWindows::NControl::CProgressBar m_ProgressBar; + + UInt32 _prevPercentValue; + UInt32 _prevTime; + UInt32 _elapsedTime; + UInt32 _prevElapsedSec; + UInt64 _prevRemainingSec; + ESpeedMode _prevMode; + UInt64 _prevSpeed; + + bool _foreground; + + bool OnTimer(WPARAM timerID, LPARAM callback); + void SetRange(UInt64 range); + void SetPos(UInt64 pos); + virtual bool OnInit(); + virtual void OnCancel(); + NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent; + #ifndef _SFX + void AddToTitle(LPCWSTR string); + #endif + + void SetPauseText(); + void SetPriorityText(); + void OnPauseButton(); + void OnPriorityButton(); + bool OnButtonClicked(int buttonID, HWND buttonHWND); + + void SetTitleText(); +public: + CProgressSynch ProgressSynch; + + #ifndef _SFX + HWND MainWindow; + UString MainTitle; + UString MainAddTitle; + ~CProgressDialog(); + #endif + + CProgressDialog(): _timer(0) + #ifndef _SFX + ,MainWindow(0) + #endif + {} + + void WaitCreating() { _dialogCreatedEvent.Lock(); } + + + INT_PTR Create(const UString &title, HWND wndParent = 0) + { + _title = title; + return CModalDialog::Create(IDD_DIALOG_PROGRESS, wndParent); + } + + static const UINT kCloseMessage; + + virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); + + void MyClose() { PostMessage(kCloseMessage); }; +}; + +#endif diff --git a/CPP/7zip/FileManager/Resource/ProgressDialog2/StdAfx.h b/CPP/7zip/FileManager/Resource/ProgressDialog2/StdAfx.h new file mode 100755 index 00000000..a444ca31 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/ProgressDialog2/StdAfx.h @@ -0,0 +1,16 @@ +// stdafx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#define _WIN32_WINNT 0x0400 + +// it's for Windows NT supporting (MENUITEMINFOW) +#define WINVER 0x0400 + +#include +#include + +#include "Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/FileManager/Resource/ProgressDialog2/resource.h b/CPP/7zip/FileManager/Resource/ProgressDialog2/resource.h new file mode 100755 index 00000000..be1da4ad --- /dev/null +++ b/CPP/7zip/FileManager/Resource/ProgressDialog2/resource.h @@ -0,0 +1,17 @@ +#define IDC_BUTTON_PAUSE 3 +#define IDC_BUTTON_PROGRESS_PRIORITY 4 +#define IDD_DIALOG_PROGRESS 500 +#define IDS_PROGRESS_PAUSED 700 +#define IDS_PROGRESS_FOREGROUND 701 +#define IDS_PROGRESS_CONTINUE 702 +#define IDS_PROGRESS_ASK_CANCEL 703 +#define IDC_PROGRESS1 1000 +#define IDC_PROGRESS_ELAPSED 1002 +#define IDC_PROGRESS_ELAPSED_VALUE 1003 +#define IDC_PROGRESS_REMAINING 1004 +#define IDC_PROGRESS_REMAINING_VALUE 1005 +#define IDC_PROGRESS_SPEED 1006 +#define IDC_PROGRESS_SPEED_VALUE 1007 +#define IDC_PROGRESS_TOTAL 1008 +#define IDC_PROGRESS_SPEED_TOTAL_VALUE 1009 +#define IDC_PROGRESS_FILE_NAME 1010 diff --git a/CPP/7zip/FileManager/Resource/ProgressDialog2/resource.rc b/CPP/7zip/FileManager/Resource/ProgressDialog2/resource.rc new file mode 100755 index 00000000..9f395bff --- /dev/null +++ b/CPP/7zip/FileManager/Resource/ProgressDialog2/resource.rc @@ -0,0 +1,56 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" + +#define xSize2 290 +#define ySize2 76 + +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#define bYPos (ySize - marg - bYSize) + +#undef bXSize +#define bXSize 72 + +#define bXPos1 (xSize - marg - bXSize) +#define bXPos2 (bXPos1 - 10 - bXSize) +#define bXPos3 (bXPos2 - 10 - bXSize) + +#define valSize 42 +#define timeSize 91 +#define labelPos 178 +#define valPos1 (marg + timeSize) +#define valPos2 (xSize - marg - valSize) +#define labelSize (valPos2 - labelPos) + +#undef yPos +#define yPos (marg + 11) + + +IDD_DIALOG_PROGRESS DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE | WS_MINIMIZEBOX +CAPTION "Progress" +MY_FONT +BEGIN + PUSHBUTTON "&Background", IDC_BUTTON_PROGRESS_PRIORITY, bXPos3, bYPos, bXSize, bYSize + PUSHBUTTON "&Pause", IDC_BUTTON_PAUSE, bXPos2, bYPos, bXSize, bYSize + PUSHBUTTON "Cancel", IDCANCEL, bXPos1, bYPos, bXSize, bYSize + LTEXT "Elapsed time:", IDC_PROGRESS_ELAPSED, marg, marg, timeSize, 8 + LTEXT "Remaining time:", IDC_PROGRESS_REMAINING, marg, yPos, timeSize, 8 + LTEXT "Size:", IDC_PROGRESS_TOTAL, labelPos, marg, labelSize, 8 + LTEXT "Speed:", IDC_PROGRESS_SPEED, labelPos, yPos, labelSize, 8 + RTEXT "00:00:00", IDC_PROGRESS_ELAPSED_VALUE, valPos1, marg, valSize, 8 + RTEXT "", IDC_PROGRESS_REMAINING_VALUE, valPos1, yPos, valSize, 8 + RTEXT "", IDC_PROGRESS_SPEED_TOTAL_VALUE, valPos2, marg, valSize, 8 + RTEXT "", IDC_PROGRESS_SPEED_VALUE, valPos2, yPos, valSize, 8 + LTEXT "", IDC_PROGRESS_FILE_NAME, marg, yPos + 16, xSize2, 8, SS_NOPREFIX + CONTROL "Progress1", IDC_PROGRESS1, "msctls_progress32", PBS_SMOOTH | WS_BORDER, marg, bYPos - 20, xSize2, 13 +END + + +STRINGTABLE DISCARDABLE +BEGIN + IDS_PROGRESS_PAUSED "Paused" + IDS_PROGRESS_FOREGROUND "&Foreground" + IDS_PROGRESS_CONTINUE "&Continue" + IDS_PROGRESS_ASK_CANCEL "Are you sure you want to cancel?" +END diff --git a/CPP/7zip/FileManager/Resource/PropertyName/resource.h b/CPP/7zip/FileManager/Resource/PropertyName/resource.h new file mode 100755 index 00000000..f3d56ef3 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/PropertyName/resource.h @@ -0,0 +1,28 @@ +#define IDS_PROPERTY_PATH 3 +#define IDS_PROPERTY_NAME 4 +#define IDS_PROPERTY_EXTENSION 5 +#define IDS_PROPERTY_IS_FOLDER 6 +#define IDS_PROPERTY_SIZE 7 +#define IDS_PROPERTY_PACKED_SIZE 8 +#define IDS_PROPERTY_ATTRIBUTES 9 +#define IDS_PROPERTY_CREATION_TIME 10 +#define IDS_PROPERTY_LAST_ACCESS_TIME 11 +#define IDS_PROPERTY_LAST_WRITE_TIME 12 +#define IDS_PROPERTY_SOLID 13 +#define IDS_PROPERTY_C0MMENTED 14 +#define IDS_PROPERTY_ENCRYPTED 15 +#define IDS_PROPERTY_DICTIONARY_SIZE 16 +#define IDS_PROPERTY_SPLIT_BEFORE 17 +#define IDS_PROPERTY_SPLIT_AFTER 18 +#define IDS_PROPERTY_CRC 19 +#define IDS_PROPERTY_FILE_TYPE 20 +#define IDS_PROPERTY_ANTI 21 +#define IDS_PROPERTY_METHOD 22 +#define IDS_PROPERTY_HOST_OS 23 +#define IDS_PROPERTY_FILE_SYSTEM 24 +#define IDS_PROPERTY_USER 25 +#define IDS_PROPERTY_GROUP 26 +#define IDS_PROPERTY_BLOCK 27 +#define IDS_PROPERTY_COMMENT 28 +#define IDS_PROPERTY_POSITION 29 +#define IDS_PROPERTY_PREFIX 30 diff --git a/CPP/7zip/FileManager/Resource/PropertyName/resource.rc b/CPP/7zip/FileManager/Resource/PropertyName/resource.rc new file mode 100755 index 00000000..3f517aff --- /dev/null +++ b/CPP/7zip/FileManager/Resource/PropertyName/resource.rc @@ -0,0 +1,35 @@ +#include "resource.h" + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +STRINGTABLE +BEGIN + IDS_PROPERTY_PATH "Path" + IDS_PROPERTY_NAME "Name" + IDS_PROPERTY_EXTENSION "Extension" + IDS_PROPERTY_IS_FOLDER "Folder" + IDS_PROPERTY_SIZE "Size" + IDS_PROPERTY_PACKED_SIZE "Packed Size" + IDS_PROPERTY_ATTRIBUTES "Attributes" + IDS_PROPERTY_CREATION_TIME "Created" + IDS_PROPERTY_LAST_ACCESS_TIME "Accessed" + IDS_PROPERTY_LAST_WRITE_TIME "Modified" + IDS_PROPERTY_SOLID "Solid" + IDS_PROPERTY_C0MMENTED "Commented" + IDS_PROPERTY_ENCRYPTED "Encrypted" + IDS_PROPERTY_DICTIONARY_SIZE "Dictionary Size" + IDS_PROPERTY_SPLIT_BEFORE "Split Before" + IDS_PROPERTY_SPLIT_AFTER "Split After" + IDS_PROPERTY_CRC "CRC" + IDS_PROPERTY_FILE_TYPE "Type" + IDS_PROPERTY_ANTI "Anti" + IDS_PROPERTY_METHOD "Method" + IDS_PROPERTY_HOST_OS "Host OS" + IDS_PROPERTY_FILE_SYSTEM "File System" + IDS_PROPERTY_USER "User" + IDS_PROPERTY_GROUP "Group" + IDS_PROPERTY_BLOCK "Block" + IDS_PROPERTY_COMMENT "Comment" + IDS_PROPERTY_POSITION "Position" + IDS_PROPERTY_PREFIX "Path Prefix" +END diff --git a/CPP/7zip/FileManager/Resource/SettingsPage/SettingsPage.cpp b/CPP/7zip/FileManager/Resource/SettingsPage/SettingsPage.cpp new file mode 100755 index 00000000..6a681fbc --- /dev/null +++ b/CPP/7zip/FileManager/Resource/SettingsPage/SettingsPage.cpp @@ -0,0 +1,113 @@ +// SettingsPage.cpp + +#include "StdAfx.h" +#include "resource.h" +#include "SettingsPage.h" + +#include "Common/StringConvert.h" + +#include "Windows/Defs.h" +#include "Windows/MemoryLock.h" + +#include "../../RegistryUtils.h" +#include "../../HelpUtils.h" +#include "../../LangUtils.h" +#include "../../ProgramLocation.h" + +using namespace NWindows; + +static CIDLangPair kIDLangPairs[] = +{ + { IDC_SETTINGS_SHOW_DOTS, 0x03010401}, + { IDC_SETTINGS_SHOW_REAL_FILE_ICONS, 0x03010402}, + { IDC_SETTINGS_SHOW_SYSTEM_MENU, 0x03010410}, + { IDC_SETTINGS_FULL_ROW, 0x03010420}, + { IDC_SETTINGS_SHOW_GRID, 0x03010421}, + { IDC_SETTINGS_ALTERNATIVE_SELECTION, 0x03010430}, + { IDC_SETTINGS_LARGE_PAGES, 0x03010440} + // { IDC_SETTINGS_SINGLE_CLICK, 0x03010422}, + // { IDC_SETTINGS_UNDERLINE, 0x03010423} +}; + +static LPCWSTR kEditTopic = L"FM/options.htm#settings"; + +extern bool IsLargePageSupported(); + +bool CSettingsPage::OnInit() +{ + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + + CheckButton(IDC_SETTINGS_SHOW_DOTS, ReadShowDots()); + CheckButton(IDC_SETTINGS_SHOW_SYSTEM_MENU, ReadShowSystemMenu()); + CheckButton(IDC_SETTINGS_SHOW_REAL_FILE_ICONS, ReadShowRealFileIcons()); + + CheckButton(IDC_SETTINGS_FULL_ROW, ReadFullRow()); + CheckButton(IDC_SETTINGS_SHOW_GRID, ReadShowGrid()); + CheckButton(IDC_SETTINGS_ALTERNATIVE_SELECTION, ReadAlternativeSelection()); + if (IsLargePageSupported()) + CheckButton(IDC_SETTINGS_LARGE_PAGES, ReadLockMemoryEnable()); + else + EnableItem(IDC_SETTINGS_LARGE_PAGES, false); + // CheckButton(IDC_SETTINGS_SINGLE_CLICK, ReadSingleClick()); + // CheckButton(IDC_SETTINGS_UNDERLINE, ReadUnderline()); + + // EnableSubItems(); + + return CPropertyPage::OnInit(); +} + +/* +void CSettingsPage::EnableSubItems() +{ + EnableItem(IDC_SETTINGS_UNDERLINE, IsButtonCheckedBool(IDC_SETTINGS_SINGLE_CLICK)); +} +*/ + +LONG CSettingsPage::OnApply() +{ + SaveShowDots(IsButtonCheckedBool(IDC_SETTINGS_SHOW_DOTS)); + SaveShowSystemMenu(IsButtonCheckedBool(IDC_SETTINGS_SHOW_SYSTEM_MENU)); + SaveShowRealFileIcons(IsButtonCheckedBool(IDC_SETTINGS_SHOW_REAL_FILE_ICONS)); + + SaveFullRow(IsButtonCheckedBool(IDC_SETTINGS_FULL_ROW)); + SaveShowGrid(IsButtonCheckedBool(IDC_SETTINGS_SHOW_GRID)); + SaveAlternativeSelection(IsButtonCheckedBool(IDC_SETTINGS_ALTERNATIVE_SELECTION)); + if (IsLargePageSupported()) + { + bool enable = IsButtonCheckedBool(IDC_SETTINGS_LARGE_PAGES); + NSecurity::EnableLockMemoryPrivilege(enable); + SaveLockMemoryEnable(enable); + } + + // SaveSingleClick(IsButtonCheckedBool(IDC_SETTINGS_SINGLE_CLICK)); + // SaveUnderline(IsButtonCheckedBool(IDC_SETTINGS_UNDERLINE)); + + return PSNRET_NOERROR; +} + +void CSettingsPage::OnNotifyHelp() +{ + ShowHelpWindow(NULL, kEditTopic); // change it +} + +bool CSettingsPage::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) + { + /* + case IDC_SETTINGS_SINGLE_CLICK: + EnableSubItems(); + break; + */ + case IDC_SETTINGS_SHOW_DOTS: + case IDC_SETTINGS_SHOW_SYSTEM_MENU: + case IDC_SETTINGS_SHOW_REAL_FILE_ICONS: + case IDC_SETTINGS_FULL_ROW: + case IDC_SETTINGS_SHOW_GRID: + case IDC_SETTINGS_ALTERNATIVE_SELECTION: + case IDC_SETTINGS_LARGE_PAGES: + Changed(); + return true; + } + return CPropertyPage::OnButtonClicked(buttonID, buttonHWND); +} diff --git a/CPP/7zip/FileManager/Resource/SettingsPage/SettingsPage.h b/CPP/7zip/FileManager/Resource/SettingsPage/SettingsPage.h new file mode 100755 index 00000000..e5fe6e67 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/SettingsPage/SettingsPage.h @@ -0,0 +1,19 @@ +// SettingsPage.h + +#ifndef __SETTINGSPAGE_H +#define __SETTINGSPAGE_H + +#include "Windows/Control/PropertyPage.h" +#include "Windows/Control/Edit.h" + +class CSettingsPage: public NWindows::NControl::CPropertyPage +{ + // void EnableSubItems(); + bool OnButtonClicked(int buttonID, HWND buttonHWND); +public: + virtual bool OnInit(); + virtual void OnNotifyHelp(); + virtual LONG OnApply(); +}; + +#endif diff --git a/CPP/7zip/FileManager/Resource/SettingsPage/StdAfx.h b/CPP/7zip/FileManager/Resource/SettingsPage/StdAfx.h new file mode 100755 index 00000000..a444ca31 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/SettingsPage/StdAfx.h @@ -0,0 +1,16 @@ +// stdafx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#define _WIN32_WINNT 0x0400 + +// it's for Windows NT supporting (MENUITEMINFOW) +#define WINVER 0x0400 + +#include +#include + +#include "Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/FileManager/Resource/SettingsPage/resource.h b/CPP/7zip/FileManager/Resource/SettingsPage/resource.h new file mode 100755 index 00000000..8932dc0e --- /dev/null +++ b/CPP/7zip/FileManager/Resource/SettingsPage/resource.h @@ -0,0 +1,11 @@ +#define IDD_SETTINGS 904 +#define IDC_SETTINGS_SHOW_DOTS 1000 +#define IDC_SETTINGS_SHOW_REAL_FILE_ICONS 1001 + +#define IDC_SETTINGS_SHOW_SYSTEM_MENU 1010 +#define IDC_SETTINGS_FULL_ROW 1011 +#define IDC_SETTINGS_SHOW_GRID 1013 +#define IDC_SETTINGS_SINGLE_CLICK 1014 +#define IDC_SETTINGS_UNDERLINE 1015 +#define IDC_SETTINGS_ALTERNATIVE_SELECTION 1016 +#define IDC_SETTINGS_LARGE_PAGES 1017 diff --git a/CPP/7zip/FileManager/Resource/SettingsPage/resource.rc b/CPP/7zip/FileManager/Resource/SettingsPage/resource.rc new file mode 100755 index 00000000..69afeba7 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/SettingsPage/resource.rc @@ -0,0 +1,35 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" + +#define xSize2 196 +#define ySize2 140 +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + + +IDD_SETTINGS DIALOG 0, 0, xSize, ySize MY_PAGE_STYLE +CAPTION "Settings" +MY_FONT +BEGIN + CONTROL "Show "".."" item", IDC_SETTINGS_SHOW_DOTS, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, marg, xSize2, 10 + CONTROL "Show real file &icons", IDC_SETTINGS_SHOW_REAL_FILE_ICONS, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, 21, xSize2, 10 + CONTROL "Show system &menu", IDC_SETTINGS_SHOW_SYSTEM_MENU, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, 35, xSize2, 10 + CONTROL "&Full row select", IDC_SETTINGS_FULL_ROW, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, 63, xSize2, 10 + CONTROL "Show &grid lines", IDC_SETTINGS_SHOW_GRID, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, 77, xSize2, 10 + CONTROL "&Single-click to open an item", IDC_SETTINGS_SINGLE_CLICK, "Button", BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP, + marg, 91, xSize2, 10 + CONTROL "&Underline current name", IDC_SETTINGS_UNDERLINE, "Button", BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP, + marg + 12, 105, xSize2 - 12, 10 + + CONTROL "&Alternative selection mode", IDC_SETTINGS_ALTERNATIVE_SELECTION, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, 122, xSize2, 10 + + CONTROL "Use &large memory pages", IDC_SETTINGS_LARGE_PAGES, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, 142, xSize2, 10 + +END diff --git a/CPP/7zip/FileManager/Resource/SplitDialog/SplitDialog.cpp b/CPP/7zip/FileManager/Resource/SplitDialog/SplitDialog.cpp new file mode 100755 index 00000000..383fa48a --- /dev/null +++ b/CPP/7zip/FileManager/Resource/SplitDialog/SplitDialog.cpp @@ -0,0 +1,89 @@ +// SplitDialog.cpp + +#include "StdAfx.h" +#include "SplitDialog.h" + +#include "Common/StringToInt.h" +#include "Windows/Shell.h" +#include "Windows/FileName.h" + +#include "../../SplitUtils.h" +#ifdef LANG +#include "../../LangUtils.h" +#endif + +#include "../CopyDialog/resource.h" + +using namespace NWindows; + +#ifdef LANG +static CIDLangPair kIDLangPairs[] = +{ + { IDC_STATIC_SPLIT_PATH, 0x03020501 }, + { IDC_STATIC_SPLIT_VOLUME, 0x02000D40 }, +}; +#endif + + +bool CSplitDialog::OnInit() +{ + #ifdef LANG + LangSetWindowText(HWND(*this), 0x03020500); + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + #endif + _pathCombo.Attach(GetItem(IDC_COMBO_SPLIT_PATH)); + _volumeCombo.Attach(GetItem(IDC_COMBO_SPLIT_VOLUME)); + + if (!FilePath.IsEmpty()) + { + UString title; + GetText(title); + title += L' '; + title += FilePath; + SetText(title); + } + _pathCombo.SetText(Path); + AddVolumeItems(_volumeCombo); + _volumeCombo.SetCurSel(0); + return CModalDialog::OnInit(); +} + +bool CSplitDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) + { + case IDC_BUTTON_SPLIT_PATH: + OnButtonSetPath(); + return true; + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} + +void CSplitDialog::OnButtonSetPath() +{ + UString currentPath; + _pathCombo.GetText(currentPath); + // UString title = L"Specify a location for output folder"; + UString title = LangStringSpec(IDS_SET_FOLDER, 0x03020209); + + UString resultPath; + if (!NShell::BrowseForFolder(HWND(*this), title, currentPath, resultPath)) + return; + NFile::NName::NormalizeDirPathPrefix(resultPath); + _pathCombo.SetCurSel(-1); + _pathCombo.SetText(resultPath); +} + +void CSplitDialog::OnOK() +{ + _pathCombo.GetText(Path); + UString volumeString; + _volumeCombo.GetText(volumeString); + volumeString.Trim(); + if (!ParseVolumeSizes(volumeString, VolumeSizes) || VolumeSizes.Size() == 0) + { + ::MessageBoxW(*this, LangString(IDS_COMPRESS_INCORRECT_VOLUME_SIZE, 0x02000D41), L"7-Zip", 0); + return; + } + CModalDialog::OnOK(); +} diff --git a/CPP/7zip/FileManager/Resource/SplitDialog/SplitDialog.h b/CPP/7zip/FileManager/Resource/SplitDialog/SplitDialog.h new file mode 100755 index 00000000..d73dcbca --- /dev/null +++ b/CPP/7zip/FileManager/Resource/SplitDialog/SplitDialog.h @@ -0,0 +1,27 @@ +// SplitDialog.h + +#ifndef __SPLITDIALOG_H +#define __SPLITDIALOG_H + +#include "Common/Types.h" +#include "Windows/Control/Dialog.h" +#include "Windows/Control/ComboBox.h" +#include "resource.h" + +class CSplitDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CComboBox _pathCombo; + NWindows::NControl::CComboBox _volumeCombo; + virtual void OnOK(); + virtual bool OnInit(); + virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); + void OnButtonSetPath(); +public: + UString FilePath; + UString Path; + CRecordVector VolumeSizes; + INT_PTR Create(HWND parentWindow = 0) + { return CModalDialog::Create(IDD_DIALOG_SPLIT, parentWindow); } +}; + +#endif diff --git a/CPP/7zip/FileManager/Resource/SplitDialog/StdAfx.h b/CPP/7zip/FileManager/Resource/SplitDialog/StdAfx.h new file mode 100755 index 00000000..eb2ba641 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/SplitDialog/StdAfx.h @@ -0,0 +1,18 @@ +// stdafx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#define _WIN32_WINNT 0x0400 + +// it's for Windows NT supporting (MENUITEMINFOW) +#define WINVER 0x0400 + +#include +#include + +// #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +#include "Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/FileManager/Resource/SplitDialog/resource.h b/CPP/7zip/FileManager/Resource/SplitDialog/resource.h new file mode 100755 index 00000000..019b7029 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/SplitDialog/resource.h @@ -0,0 +1,8 @@ +#define IDD_DIALOG_SPLIT 504 +#define IDC_STATIC_SPLIT_PATH 1000 +#define IDC_COMBO_SPLIT_PATH 1001 +#define IDC_BUTTON_SPLIT_PATH 1002 +#define IDC_STATIC_SPLIT_VOLUME 1010 +#define IDC_COMBO_SPLIT_VOLUME 1011 + +#define IDS_COMPRESS_INCORRECT_VOLUME_SIZE 95 diff --git a/CPP/7zip/FileManager/Resource/SplitDialog/resource.rc b/CPP/7zip/FileManager/Resource/SplitDialog/resource.rc new file mode 100755 index 00000000..5282ee7d --- /dev/null +++ b/CPP/7zip/FileManager/Resource/SplitDialog/resource.rc @@ -0,0 +1,32 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" + +#define xSize2 223 +#define ySize2 89 + +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#define bYPos (ySize - marg - bYSize) +#define b1XPos (xSize - marg - bXSize) +#define b2XPos (b1XPos - 10 - bXSize) + + + +IDD_DIALOG_SPLIT DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE +CAPTION "Split File" +MY_FONT +BEGIN + LTEXT "&Split to:", IDC_STATIC_SPLIT_PATH, marg, marg, xSize2, 8 + COMBOBOX IDC_COMBO_SPLIT_PATH, marg, 18, xSize2 - bDotsSize - 12, 126, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "...", IDC_BUTTON_SPLIT_PATH, xSize - marg - bDotsSize, 17, bDotsSize, bYSize, WS_GROUP + LTEXT "Split to &volumes, bytes:", IDC_STATIC_SPLIT_VOLUME, marg, 38, xSize2, 8 + COMBOBOX IDC_COMBO_SPLIT_VOLUME, marg, 50, 120, 52, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "OK", IDOK, b2XPos, bYPos, bXSize, bYSize + PUSHBUTTON "Cancel", IDCANCEL, b1XPos, bYPos, bXSize, bYSize +END + +STRINGTABLE +BEGIN + IDS_COMPRESS_INCORRECT_VOLUME_SIZE "Incorrect volume size" +END diff --git a/CPP/7zip/FileManager/Resource/SystemPage/StdAfx.h b/CPP/7zip/FileManager/Resource/SystemPage/StdAfx.h new file mode 100755 index 00000000..a444ca31 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/SystemPage/StdAfx.h @@ -0,0 +1,16 @@ +// stdafx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#define _WIN32_WINNT 0x0400 + +// it's for Windows NT supporting (MENUITEMINFOW) +#define WINVER 0x0400 + +#include +#include + +#include "Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/FileManager/Resource/SystemPage/SystemPage.cpp b/CPP/7zip/FileManager/Resource/SystemPage/SystemPage.cpp new file mode 100755 index 00000000..ca3b7432 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/SystemPage/SystemPage.cpp @@ -0,0 +1,435 @@ +// SystemDialog.cpp + +#include "StdAfx.h" +#include "resource.h" +#include "SystemPage.h" + +#include "Common/StringConvert.h" +#include "Common/MyCom.h" + +#include "Windows/Defs.h" +#include "Windows/Control/ListView.h" + +#include "../../IFolder.h" +#include "../../HelpUtils.h" +#include "../../LangUtils.h" +#include "../../PluginLoader.h" +#include "../../ProgramLocation.h" +#include "../../StringUtils.h" + +#include "../PropertyName/resource.h" + +using namespace NRegistryAssociations; + +const int kRefreshpluginsListMessage = WM_USER + 1; +const int kUpdateDatabase = kRefreshpluginsListMessage + 1; + +static CIDLangPair kIDLangPairs[] = +{ + { IDC_SYSTEM_STATIC_ASSOCIATE, 0x03010302}, + { IDC_SYSTEM_SELECT_ALL, 0x03000330} +}; + +static LPCWSTR kSystemTopic = L"FM/options.htm#system"; + + +bool CSystemPage::OnInit() +{ + _initMode = true; + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + + _listViewExt.Attach(GetItem(IDC_SYSTEM_LIST_ASSOCIATE)); + _listViewPlugins.Attach(GetItem(IDC_SYSTEM_LIST_PLUGINS)); + + /* + CheckButton(IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU, + NRegistryAssociations::CheckContextMenuHandler()); + */ + + UINT32 newFlags = LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT; + _listViewExt.SetExtendedListViewStyle(newFlags, newFlags); + _listViewPlugins.SetExtendedListViewStyle(newFlags, newFlags); + + UString s = LangString(IDS_PROPERTY_EXTENSION, 0x02000205); + LVCOLUMNW column; + column.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_FMT | LVCF_SUBITEM; + column.cx = 70; + column.fmt = LVCFMT_LEFT; + column.pszText = (LPWSTR)(LPCWSTR)s; + column.iSubItem = 0; + _listViewExt.InsertColumn(0, &column); + + s = LangString(IDS_PLUGIN, 0x03010310); + column.cx = 70; + column.pszText = (LPWSTR)(LPCWSTR)s; + column.iSubItem = 1; + _listViewExt.InsertColumn(1, &column); + + s = LangString(IDS_PLUGIN, 0x03010310); + column.cx = 70; + column.pszText = (LPWSTR)(LPCWSTR)s; + column.iSubItem = 0; + _listViewPlugins.InsertColumn(0, &column); + + _extDatabase.Read(); + + for (int i = 0; i < _extDatabase.ExtBigItems.Size(); i++) + { + CExtInfoBig &extInfo = _extDatabase.ExtBigItems[i]; + + LVITEMW item; + item.iItem = i; + item.mask = LVIF_TEXT | LVIF_PARAM; + item.lParam = i; + item.pszText = (LPWSTR)(LPCWSTR)extInfo.Ext; + item.iSubItem = 0; + int itemIndex = _listViewExt.InsertItem(&item); + + extInfo.Associated = NRegistryAssociations::CheckShellExtensionInfo(GetSystemString(extInfo.Ext)); + _listViewExt.SetCheckState(itemIndex, extInfo.Associated); + + SetMainPluginText(itemIndex, i); + } + // _listViewExt.SortItems(); + + if(_listViewExt.GetItemCount() > 0) + { + UINT state = LVIS_SELECTED | LVIS_FOCUSED; + _listViewExt.SetItemState(0, state, state); + } + RefreshPluginsList(-1); + _initMode = false; + + return CPropertyPage::OnInit(); +} + +void CSystemPage::SetMainPluginText(int itemIndex, int indexInDatabase) +{ + LVITEMW item; + item.iItem = itemIndex; + item.mask = LVIF_TEXT; + UString mainPlugin = _extDatabase.GetMainPluginNameForExtItem(indexInDatabase); + item.pszText = (WCHAR *)(const WCHAR *)mainPlugin; + item.iSubItem = 1; + _listViewExt.SetItem(&item); +} + +static UString GetProgramCommand() +{ + UString path = L"\""; + UString folder; + if (GetProgramFolderPath(folder)) + path += folder; + path += L"7zFM.exe\" \"%1\""; + return path; +} + +static UString GetIconPath(const UString &filePath, + const CLSID &clsID, const UString &extension) +{ + CPluginLibrary library; + CMyComPtr folderManager; + CMyComPtr folder; + if (library.LoadAndCreateManager(filePath, clsID, &folderManager) != S_OK) + return UString(); + CMyComBSTR typesString; + if (folderManager->GetTypes(&typesString) != S_OK) + return UString(); + UStringVector types; + SplitString((const wchar_t *)typesString, types); + for (int typeIndex = 0; typeIndex < types.Size(); typeIndex++) + { + const UString &type = types[typeIndex]; + CMyComBSTR extTemp; + if (folderManager->GetExtension(type, &extTemp) != S_OK) + continue; + if (extension.CompareNoCase((const wchar_t *)extTemp) == 0) + { + CMyComPtr getIconPath; + if (folderManager.QueryInterface(IID_IFolderManagerGetIconPath, &getIconPath) != S_OK) + break; + CMyComBSTR iconPathTemp; + if (getIconPath->GetIconPath(type, &iconPathTemp) != S_OK) + break; + return (const wchar_t *)iconPathTemp; + } + } + return UString(); +} + +LONG CSystemPage::OnApply() +{ + UpdateDatabase(); + _extDatabase.Save(); + UString command = GetProgramCommand(); + + for (int i = 0; i < _extDatabase.ExtBigItems.Size(); i++) + { + const CExtInfoBig &extInfo = _extDatabase.ExtBigItems[i]; + if (extInfo.Associated) + { + UString title = extInfo.Ext + UString(L" Archive"); + UString command = GetProgramCommand(); + UString iconPath; + if (!extInfo.PluginsPairs.IsEmpty()) + { + const CPluginInfo &plugin = _extDatabase.Plugins[extInfo.PluginsPairs[0].Index]; + iconPath = GetIconPath(plugin.FilePath, plugin.ClassID, extInfo.Ext); + } + NRegistryAssociations::AddShellExtensionInfo( + GetSystemString(extInfo.Ext), + title, + command, + iconPath, NULL, 0); + } + else + NRegistryAssociations::DeleteShellExtensionInfo(GetSystemString(extInfo.Ext)); + } + /* + if (IsButtonCheckedBool(IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU)) + NRegistryAssociations::AddContextMenuHandler(); + else + NRegistryAssociations::DeleteContextMenuHandler(); + */ + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); + return PSNRET_NOERROR; +} + +void CSystemPage::OnNotifyHelp() +{ + ShowHelpWindow(NULL, kSystemTopic); +} + +void CSystemPage::SelectAll() +{ + int count = _listViewExt.GetItemCount(); + for (int i = 0; i < count; i++) + _listViewExt.SetCheckState(i, true); + UpdateDatabase(); +} + +bool CSystemPage::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) + { + case IDC_SYSTEM_SELECT_ALL: + { + SelectAll(); + Changed(); + return true; + } + } + return CPropertyPage::OnButtonClicked(buttonID, buttonHWND); +} + +bool CSystemPage::OnNotify(UINT controlID, LPNMHDR lParam) +{ + if (lParam->hwndFrom == HWND(_listViewExt)) + { + switch(lParam->code) + { + case (LVN_ITEMCHANGED): + return OnItemChanged((const NMLISTVIEW *)lParam); + case NM_RCLICK: + case NM_DBLCLK: + case LVN_KEYDOWN: + case NM_CLICK: + case LVN_BEGINRDRAG: + PostMessage(kRefreshpluginsListMessage, 0); + PostMessage(kUpdateDatabase, 0); + break; + } + } + else if (lParam->hwndFrom == HWND(_listViewPlugins)) + { + switch(lParam->code) + { + case NM_RCLICK: + case NM_DBLCLK: + // case LVN_KEYDOWN: + case NM_CLICK: + case LVN_BEGINRDRAG: + PostMessage(kUpdateDatabase, 0); + break; + + case (LVN_ITEMCHANGED): + { + OnItemChanged((const NMLISTVIEW *)lParam); + PostMessage(kUpdateDatabase, 0); + break; + } + case LVN_KEYDOWN: + { + OnPluginsKeyDown((LPNMLVKEYDOWN)lParam); + PostMessage(kUpdateDatabase, 0); + break; + } + } + } + return CPropertyPage::OnNotify(controlID, lParam); +} + +bool CSystemPage::OnPluginsKeyDown(LPNMLVKEYDOWN keyDownInfo) +{ + bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0; + // bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; + switch(keyDownInfo->wVKey) + { + case VK_UP: + { + if (alt) + MovePlugin(true); + return true; + } + case VK_DOWN: + { + if (alt) + MovePlugin(false); + return true; + } + } + return false; +} + +void CSystemPage::MovePlugin(bool upDirection) +{ + int selectedPlugin = _listViewPlugins.GetSelectionMark(); + if (selectedPlugin < 0) + return; + int newIndex = selectedPlugin + (upDirection ? -1: 1); + if (newIndex < 0 || newIndex >= _listViewPlugins.GetItemCount()) + return; + int selectedExtIndex = GetSelectedExtIndex(); + if (selectedExtIndex < 0) + return; + CExtInfoBig &extInfo = _extDatabase.ExtBigItems[selectedExtIndex]; + CPluginEnabledPair pluginPairTemp = extInfo.PluginsPairs[newIndex]; + extInfo.PluginsPairs[newIndex] = extInfo.PluginsPairs[selectedPlugin]; + extInfo.PluginsPairs[selectedPlugin] = pluginPairTemp; + + SetMainPluginText(_listViewExt.GetSelectionMark(), selectedExtIndex); + RefreshPluginsList(newIndex); + + Changed(); +} + +bool CSystemPage::OnItemChanged(const NMLISTVIEW *info) +{ + if (_initMode) + return true; + if ((info->uChanged & LVIF_STATE) != 0) + { + UINT oldState = info->uOldState & LVIS_STATEIMAGEMASK; + UINT newState = info->uNewState & LVIS_STATEIMAGEMASK; + if (oldState != newState) + Changed(); + } + // PostMessage(kRefreshpluginsListMessage, 0); + // RefreshPluginsList(); + return true; +} + +bool CSystemPage::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch(message) + { + case kRefreshpluginsListMessage: + RefreshPluginsList(-1); + return true; + case kUpdateDatabase: + UpdateDatabase(); + return true; + } + return CPropertyPage::OnMessage(message, wParam, lParam); +} + +void CSystemPage::UpdateDatabase() +{ + int i; + for (i = 0; i < _listViewExt.GetItemCount(); i++) + { + LPARAM param; + if (!_listViewExt.GetItemParam(i, param)) + return; + CExtInfoBig &extInfo = _extDatabase.ExtBigItems[(int)param]; + extInfo.Associated = _listViewExt.GetCheckState(i); + } + + int selectedExtIndex = GetSelectedExtIndex(); + if (selectedExtIndex < 0) + return; + + CExtInfoBig &extInfo = _extDatabase.ExtBigItems[selectedExtIndex]; + for (i = 0; i < _listViewPlugins.GetItemCount(); i++) + { + extInfo.PluginsPairs[i].Enabled = _listViewPlugins.GetCheckState(i); + } +} + + + +int CSystemPage::GetSelectedExtIndex() +{ + int selectedIndex = _listViewExt.GetSelectionMark(); + if (selectedIndex < 0) + return -1; + LPARAM param; + if (!_listViewExt.GetItemParam(selectedIndex, param)) + return -1; + return (int)param; +} + + +void CSystemPage::RefreshPluginsList(int selectIndex) +{ + _listViewPlugins.DeleteAllItems(); + int selectedExtIndex = GetSelectedExtIndex(); + if (selectedExtIndex < 0) + return; + const CExtInfoBig &extInfo = _extDatabase.ExtBigItems[selectedExtIndex]; + + _initMode = true; + for (int i = 0; i < extInfo.PluginsPairs.Size(); i++) + { + CPluginEnabledPair pluginPair = extInfo.PluginsPairs[i]; + UString pluginName = _extDatabase.Plugins[pluginPair.Index].Name; + LVITEMW item; + item.iItem = i; + item.mask = LVIF_TEXT | LVIF_PARAM; + item.lParam = i; + item.pszText = (LPWSTR)(LPCWSTR)pluginName; + item.iSubItem = 0; + int itemIndex = _listViewPlugins.InsertItem(&item); + _listViewPlugins.SetCheckState(itemIndex, pluginPair.Enabled); + } + if(_listViewPlugins.GetItemCount() > 0) + { + if (selectIndex < 0) + selectIndex = 0; + UINT state = LVIS_SELECTED | LVIS_FOCUSED; + _listViewPlugins.SetItemState(selectIndex, state, state); + } + _initMode = false; +} + + + +/* +static BYTE kZipShellNewData[] = + { 0x50-1, 0x4B, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0 }; + +static BYTE kRarShellNewData[] = + { 0x52-1, 0x61, 0x72, 0x21, 0x1A, 7, 0, 0xCF, 0x90, 0x73, 0, 0, 0x0D, 0, 0, 0, 0, 0, 0, 0}; + +class CSignatureMaker +{ +public: + CSignatureMaker() + { + kZipShellNewData[0]++; + kRarShellNewData[0]++; + }; +}; + +static CSignatureMaker g_SignatureMaker; +*/ diff --git a/CPP/7zip/FileManager/Resource/SystemPage/SystemPage.h b/CPP/7zip/FileManager/Resource/SystemPage/SystemPage.h new file mode 100755 index 00000000..3798f640 --- /dev/null +++ b/CPP/7zip/FileManager/Resource/SystemPage/SystemPage.h @@ -0,0 +1,40 @@ +// SystemPage.h + +#ifndef __SYSTEMPAGE_H +#define __SYSTEMPAGE_H + +#include "Windows/Control/PropertyPage.h" +#include "Windows/Control/ListView.h" + +#include "../../FilePlugins.h" + +class CSystemPage: public NWindows::NControl::CPropertyPage +{ + bool _initMode; + CExtDatabase _extDatabase; + + // CObjectVector m_Archivers; + NWindows::NControl::CListView _listViewExt; + NWindows::NControl::CListView _listViewPlugins; + + void SetMainPluginText(int itemIndex, int indexInDatabase); + + int GetSelectedExtIndex(); + void RefreshPluginsList(int selectIndex); + void MovePlugin(bool upDirection); + void UpdateDatabase(); + void SelectAll(); + +public: + virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); + virtual bool OnInit(); + virtual void OnNotifyHelp(); + virtual bool OnNotify(UINT controlID, LPNMHDR lParam); + virtual bool OnItemChanged(const NMLISTVIEW *info); + + virtual LONG OnApply(); + virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); + bool OnPluginsKeyDown(LPNMLVKEYDOWN keyDownInfo); +}; + +#endif diff --git a/CPP/7zip/FileManager/Resource/SystemPage/resource.h b/CPP/7zip/FileManager/Resource/SystemPage/resource.h new file mode 100755 index 00000000..8dce778b --- /dev/null +++ b/CPP/7zip/FileManager/Resource/SystemPage/resource.h @@ -0,0 +1,7 @@ +#define IDD_SYSTEM 902 +#define IDS_PLUGIN 990 +// #define IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU 1010 +#define IDC_SYSTEM_STATIC_ASSOCIATE 1020 +#define IDC_SYSTEM_LIST_ASSOCIATE 1021 +#define IDC_SYSTEM_LIST_PLUGINS 1022 +#define IDC_SYSTEM_SELECT_ALL 1023 diff --git a/CPP/7zip/FileManager/Resource/SystemPage/resource.rc b/CPP/7zip/FileManager/Resource/SystemPage/resource.rc new file mode 100755 index 00000000..cf19d11b --- /dev/null +++ b/CPP/7zip/FileManager/Resource/SystemPage/resource.rc @@ -0,0 +1,31 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" + +#define xSize2 238 +#define ySize2 214 +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) +#define gSpace 30 +#define g0Size 110 +#define gYSize (ySize2 - 20 - bYSize) + + +IDD_SYSTEM DIALOG 0, 0, xSize, ySize MY_PAGE_STYLE +CAPTION "System" +MY_FONT +BEGIN + LTEXT "Associate 7-Zip with:", IDC_SYSTEM_STATIC_ASSOCIATE, marg, marg, xSize2, 8 + CONTROL "List1", IDC_SYSTEM_LIST_ASSOCIATE, "SysListView32", + LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP, + marg, 20, g0Size, gYSize + CONTROL "List1", IDC_SYSTEM_LIST_PLUGINS, "SysListView32", + LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | NOT WS_VISIBLE | WS_BORDER | WS_TABSTOP, + marg + g0Size + gSpace, 20, xSize2 - gSpace - g0Size, gYSize + PUSHBUTTON "Select all", IDC_SYSTEM_SELECT_ALL, marg, (ySize - marg - bYSize), 90, bYSize + +END + +STRINGTABLE +BEGIN + IDS_PLUGIN "Plugin" +END diff --git a/CPP/7zip/FileManager/RootFolder.cpp b/CPP/7zip/FileManager/RootFolder.cpp new file mode 100755 index 00000000..4ff0660b --- /dev/null +++ b/CPP/7zip/FileManager/RootFolder.cpp @@ -0,0 +1,204 @@ +// RootFolder.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "RootFolder.h" + +#include "Common/StringConvert.h" +#include "../PropID.h" +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" + +#include "FSDrives.h" +#include "PhysDriveFolder.h" +#include "NetFolder.h" +#include "SysIconUtils.h" +#include "LangUtils.h" + +using namespace NWindows; + + +static const STATPROPSTG kProperties[] = +{ + { NULL, kpidName, VT_BSTR} +}; + +// static const wchar_t *kMyComputerTitle = L"Computer"; +// static const wchar_t *kMyNetworkTitle = L"Network"; + +void CRootFolder::Init() +{ + _computerName = LangString(IDS_COMPUTER, 0x03020300); + _networkName = LangString(IDS_NETWORK, 0x03020301); +}; + +STDMETHODIMP CRootFolder::LoadItems() +{ + Init(); + return S_OK; +} + +STDMETHODIMP CRootFolder::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = 2; + return S_OK; +} + +STDMETHODIMP CRootFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value) +{ + NCOM::CPropVariant propVariant; + switch(propID) + { + case kpidIsFolder: + propVariant = true; + break; + case kpidName: + if (itemIndex == 0) + propVariant = _computerName; + else if (itemIndex == 1) + propVariant = _networkName; + break; + } + propVariant.Detach(value); + return S_OK; +} + +STDMETHODIMP CRootFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder) +{ + if (index == 0) + { + CFSDrives *fsDrivesSpec = new CFSDrives; + CMyComPtr subFolder = fsDrivesSpec; + fsDrivesSpec->Init(); + *resultFolder = subFolder.Detach(); + } + else if (index == 1) + { + CNetFolder *netFolderSpec = new CNetFolder; + CMyComPtr subFolder = netFolderSpec; + netFolderSpec->Init(0, 0, _networkName + L'\\'); + *resultFolder = subFolder.Detach(); + } + else + return E_INVALIDARG; + return S_OK; +} + +STDMETHODIMP CRootFolder::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder) +{ + *resultFolder = 0; + UString name2 = name; + name2.Trim(); + if (name2.IsEmpty()) + { + CRootFolder *rootFolderSpec = new CRootFolder; + CMyComPtr 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 subFolder = this; + *resultFolder = subFolder.Detach(); + return S_OK; + } + + if (name2.Length () < 2) + return E_INVALIDARG; + + CMyComPtr subFolder; + + if (name2.Left(4) == L"\\\\.\\") + { + CPhysDriveFolder *folderSpec = new CPhysDriveFolder; + subFolder = folderSpec; + RINOK(folderSpec->Init(name2.Mid(4, 2))); + } + else + { + if (name2[name2.Length () - 1] != L'\\') + name2 += L'\\'; + CFSFolder *fsFolderSpec = new CFSFolder; + subFolder = fsFolderSpec; + if (fsFolderSpec->Init(name2, 0) != S_OK) + { + if (name2[0] == L'\\') + { + CNetFolder *netFolderSpec = new CNetFolder; + subFolder = netFolderSpec; + netFolderSpec->Init(name2); + } + else + return E_INVALIDARG; + } + } + *resultFolder = subFolder.Detach(); + return S_OK; +} + +STDMETHODIMP CRootFolder::BindToParentFolder(IFolderFolder **resultFolder) +{ + *resultFolder = 0; + return S_OK; +} + +STDMETHODIMP CRootFolder::GetName(BSTR * /* name */) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CRootFolder::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CRootFolder::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if (index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &prop = kProperties[index]; + *propID = prop.propid; + *varType = prop.vt; + *name = 0; + return S_OK; +} + +STDMETHODIMP CRootFolder::GetTypeID(BSTR *name) +{ + CMyComBSTR temp = L"RootFolder"; + *name = temp.Detach(); + return S_OK; +} + +STDMETHODIMP CRootFolder::GetPath(BSTR *path) +{ + CMyComBSTR temp = L""; + *path = temp.Detach(); + return S_OK; +} + +STDMETHODIMP CRootFolder::GetSystemIconIndex(UInt32 index, INT32 *iconIndex) +{ + int aCSIDL; + if (index == 0) + aCSIDL = CSIDL_DRIVES; + else + aCSIDL = CSIDL_NETWORK; + *iconIndex = GetIconIndexForCSIDL(aCSIDL); + return S_OK; +} + + + + diff --git a/CPP/7zip/FileManager/RootFolder.h b/CPP/7zip/FileManager/RootFolder.h new file mode 100755 index 00000000..16bac250 --- /dev/null +++ b/CPP/7zip/FileManager/RootFolder.h @@ -0,0 +1,49 @@ +// RootFolder.h + +#ifndef __ROOTFOLDER_H +#define __ROOTFOLDER_H + +#include "Common/String.h" + +#include "Windows/PropVariant.h" + +#include "FSFolder.h" + +class CRootFolder: + public IFolderFolder, + public IEnumProperties, + public IFolderGetTypeID, + public IFolderGetPath, + public IFolderGetSystemIconIndex, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP4( + IEnumProperties, + IFolderGetTypeID, + IFolderGetPath, + IFolderGetSystemIconIndex + ) + + STDMETHOD(LoadItems)(); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 itemIndex, PROPID propID, PROPVARIANT *value); + STDMETHOD(BindToFolder)(UInt32 index, IFolderFolder **resultFolder); + STDMETHOD(BindToFolder)(const wchar_t *name, IFolderFolder **resultFolder); + STDMETHOD(BindToParentFolder)(IFolderFolder **resultFolder); + STDMETHOD(GetName)(BSTR *name); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + STDMETHOD(GetTypeID)(BSTR *name); + STDMETHOD(GetPath)(BSTR *path); + STDMETHOD(GetSystemIconIndex)(UInt32 index, INT32 *iconIndex); + + void Init(); +private: + UString _computerName; + UString _networkName; +}; + +#endif diff --git a/CPP/7zip/FileManager/SplitUtils.cpp b/CPP/7zip/FileManager/SplitUtils.cpp new file mode 100755 index 00000000..3a7635fa --- /dev/null +++ b/CPP/7zip/FileManager/SplitUtils.cpp @@ -0,0 +1,85 @@ +// SplitUtils.cpp + +#include "StdAfx.h" + +#include "Common/StringToInt.h" + +#include "SplitUtils.h" +#include "StringUtils.h" + +bool ParseVolumeSizes(const UString &s, CRecordVector &values) +{ + values.Clear(); + UStringVector destStrings; + SplitString(s, destStrings); + bool prevIsNumber = false; + for (int i = 0; i < destStrings.Size(); i++) + { + UString subString = destStrings[i]; + subString.MakeUpper(); + if (subString.IsEmpty()) + return false; + if (subString == L"-") + return true; + if (prevIsNumber) + { + wchar_t c = subString[0]; + UInt64 &value = values.Back(); + prevIsNumber = false; + switch(c) + { + case L'B': + continue; + case L'K': + value <<= 10; + continue; + case L'M': + value <<= 20; + continue; + case L'G': + value <<= 30; + continue; + } + } + const wchar_t *start = subString; + const wchar_t *end; + UInt64 value = ConvertStringToUInt64(start, &end); + if (start == end) + return false; + if (value == 0) + return false; + values.Add(value); + prevIsNumber = true; + UString rem = subString.Mid((int)(end - start)); + if (!rem.IsEmpty()) + destStrings.Insert(i + 1, rem); + } + return true; +} + +void AddVolumeItems(NWindows::NControl::CComboBox &volumeCombo) +{ + volumeCombo.AddString(TEXT("1457664 - 3.5\" floppy")); + volumeCombo.AddString(TEXT("650M - CD")); + volumeCombo.AddString(TEXT("700M - CD")); + volumeCombo.AddString(TEXT("4480M - DVD")); +} + +UInt64 GetNumberOfVolumes(UInt64 size, CRecordVector &volSizes) +{ + if (size == 0 || volSizes.Size() == 0) + return 1; + UInt64 numVolumes = 0; + for (int i = 0; i < volSizes.Size(); i++) + { + UInt64 volSize = volSizes[i]; + numVolumes++; + if (volSize >= size) + return numVolumes; + size -= volSize; + } + UInt64 volSize = volSizes.Back(); + if (volSize == 0) + return (UInt64)(Int64)-1; + return numVolumes + (size - 1) / volSize + 1; +} diff --git a/CPP/7zip/FileManager/SplitUtils.h b/CPP/7zip/FileManager/SplitUtils.h new file mode 100755 index 00000000..fe359f04 --- /dev/null +++ b/CPP/7zip/FileManager/SplitUtils.h @@ -0,0 +1,15 @@ +// SplitUtils.h + +#ifndef __SPLITUTILS_H +#define __SPLITUTILS_H + +#include "Common/String.h" +#include "Common/Types.h" +#include "Windows/Control/ComboBox.h" + +bool ParseVolumeSizes(const UString &s, CRecordVector &values); +void AddVolumeItems(NWindows::NControl::CComboBox &volumeCombo); + +UInt64 GetNumberOfVolumes(UInt64 size, CRecordVector &volSizes); + +#endif diff --git a/CPP/7zip/FileManager/StdAfx.cpp b/CPP/7zip/FileManager/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/FileManager/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/FileManager/StdAfx.h b/CPP/7zip/FileManager/StdAfx.h new file mode 100755 index 00000000..b09de592 --- /dev/null +++ b/CPP/7zip/FileManager/StdAfx.h @@ -0,0 +1,23 @@ +// stdafx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#define _WIN32_WINNT 0x0400 + +// it's for Windows NT supporting (MENUITEMINFOW) +#define WINVER 0x0400 + +#include +#include +#include +#include +#include +#include +#include + +// #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +#include "Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/FileManager/StringUtils.cpp b/CPP/7zip/FileManager/StringUtils.cpp new file mode 100755 index 00000000..63eebdba --- /dev/null +++ b/CPP/7zip/FileManager/StringUtils.cpp @@ -0,0 +1,68 @@ +// StringUtils.cpp + +#include "StdAfx.h" + +#include "StringUtils.h" + +void SplitStringToTwoStrings(const UString &src, UString &dest1, UString &dest2) +{ + dest1.Empty(); + dest2.Empty(); + bool quoteMode = false; + int i; + for (i = 0; i < src.Length(); i++) + { + wchar_t c = src[i]; + if (c == L'\"') + quoteMode = !quoteMode; + else if (c == L' ' && !quoteMode) + { + if (!quoteMode) + { + i++; + break; + } + } + else + dest1 += c; + } + dest2 = src.Mid(i); +} + +void SplitString(const UString &srcString, UStringVector &destStrings) +{ + destStrings.Clear(); + UString string; + int len = srcString.Length(); + if (len == 0) + return; + for (int i = 0; i < len; i++) + { + wchar_t c = srcString[i]; + if (c == L' ') + { + if (!string.IsEmpty()) + { + destStrings.Add(string); + string.Empty(); + } + } + else + string += c; + } + if (!string.IsEmpty()) + destStrings.Add(string); +} + +UString JoinStrings(const UStringVector &srcStrings) +{ + UString destString; + for (int i = 0; i < srcStrings.Size(); i++) + { + if (i != 0) + destString += L' '; + destString += srcStrings[i]; + } + return destString; +} + diff --git a/CPP/7zip/FileManager/StringUtils.h b/CPP/7zip/FileManager/StringUtils.h new file mode 100755 index 00000000..376a3024 --- /dev/null +++ b/CPP/7zip/FileManager/StringUtils.h @@ -0,0 +1,13 @@ +// StringUtils.h + +#ifndef __STRINGUTILS_H +#define __STRINGUTILS_H + +#include "Common/String.h" + +void SplitStringToTwoStrings(const UString &src, UString &dest1, UString &dest2); + +void SplitString(const UString &srcString, UStringVector &destStrings); +UString JoinStrings(const UStringVector &srcStrings); + +#endif diff --git a/CPP/7zip/FileManager/SysIconUtils.cpp b/CPP/7zip/FileManager/SysIconUtils.cpp new file mode 100755 index 00000000..0d337550 --- /dev/null +++ b/CPP/7zip/FileManager/SysIconUtils.cpp @@ -0,0 +1,157 @@ +// SysIconUtils.h + +#include "StdAfx.h" + +#include "SysIconUtils.h" +#ifndef _UNICODE +#include "Common/StringConvert.h" +#endif + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +int GetIconIndexForCSIDL(int aCSIDL) +{ + LPITEMIDLIST pidlMyComputer = 0; + SHGetSpecialFolderLocation(NULL, aCSIDL, &pidlMyComputer); + if (pidlMyComputer) + { + SHFILEINFO shellInfo; + SHGetFileInfo(LPCTSTR(pidlMyComputer), FILE_ATTRIBUTE_NORMAL, + &shellInfo, sizeof(shellInfo), + SHGFI_PIDL | SHGFI_SYSICONINDEX); + IMalloc *pMalloc; + SHGetMalloc(&pMalloc); + if(pMalloc) + { + pMalloc->Free(pidlMyComputer); + pMalloc->Release(); + } + return shellInfo.iIcon; + } + return 0; +} + +DWORD_PTR GetRealIconIndex(LPCTSTR path, UINT32 attributes, int &iconIndex) +{ + SHFILEINFO shellInfo; + DWORD_PTR res = ::SHGetFileInfo(path, FILE_ATTRIBUTE_NORMAL | attributes, &shellInfo, + sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX); + iconIndex = shellInfo.iIcon; + return res; +} + + +#ifndef _UNICODE +typedef int (WINAPI * SHGetFileInfoWP)(LPCWSTR pszPath, DWORD dwFileAttributes, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags); + +struct CSHGetFileInfoInit +{ + SHGetFileInfoWP shGetFileInfoW; + CSHGetFileInfoInit() + { + shGetFileInfoW = (SHGetFileInfoWP) + ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "SHGetFileInfoW"); + } +} g_SHGetFileInfoInit; +#endif + +DWORD_PTR MySHGetFileInfoW(LPCWSTR pszPath, DWORD dwFileAttributes, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags) +{ + #ifdef _UNICODE + return SHGetFileInfoW( + #else + if (g_SHGetFileInfoInit.shGetFileInfoW == 0) + return 0; + return g_SHGetFileInfoInit.shGetFileInfoW( + #endif + pszPath, dwFileAttributes, psfi, cbFileInfo, uFlags); +} + +#ifndef _UNICODE +// static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; } +DWORD_PTR GetRealIconIndex(LPCWSTR path, UINT32 attributes, int &iconIndex) +{ + if(g_IsNT) + { + SHFILEINFOW shellInfo; + DWORD_PTR res = ::MySHGetFileInfoW(path, FILE_ATTRIBUTE_NORMAL | attributes, &shellInfo, + sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX); + iconIndex = shellInfo.iIcon; + return res; + } + else + return GetRealIconIndex(UnicodeStringToMultiByte(path), attributes, iconIndex); +} +#endif + +DWORD_PTR GetRealIconIndex(const UString &fileName, UINT32 attributes, + int &iconIndex, UString &typeName) +{ + #ifndef _UNICODE + if(!g_IsNT) + { + SHFILEINFO shellInfo; + shellInfo.szTypeName[0] = 0; + DWORD_PTR res = ::SHGetFileInfoA(GetSystemString(fileName), FILE_ATTRIBUTE_NORMAL | attributes, &shellInfo, + sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX + | SHGFI_TYPENAME); + typeName = GetUnicodeString(shellInfo.szTypeName); + iconIndex = shellInfo.iIcon; + return res; + } + else + #endif + { + SHFILEINFOW shellInfo; + shellInfo.szTypeName[0] = 0; + DWORD_PTR res = ::MySHGetFileInfoW(fileName, FILE_ATTRIBUTE_NORMAL | attributes, &shellInfo, + sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX + | SHGFI_TYPENAME); + typeName = shellInfo.szTypeName; + iconIndex = shellInfo.iIcon; + return res; + } +} + +int CExtToIconMap::GetIconIndex(UINT32 attributes, const UString &fileNameSpec, UString &typeName) +{ + UString fileName = fileNameSpec; + if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) + { + fileName = L"__Fldr__"; + if (_dirIconIndex < 0) + GetRealIconIndex(fileName, attributes, _dirIconIndex, _dirTypeName); + typeName = _dirTypeName; + return _dirIconIndex; + } + int dotPos = fileName.ReverseFind('.'); + if (dotPos < 0) + { + fileName = L"__File__"; + if (_noExtIconIndex < 0) + { + int iconIndexTemp; + GetRealIconIndex(fileName, attributes, iconIndexTemp, _noExtTypeName); + } + typeName = _noExtTypeName; + return _noExtIconIndex; + } + CExtIconPair extIconPair; + extIconPair.Ext = fileName.Mid(dotPos + 1); + int anIndex = _map.FindInSorted(extIconPair); + if (anIndex >= 0) + return _map[anIndex].IconIndex; + fileName = fileName.Mid(dotPos); + GetRealIconIndex(fileName, attributes, extIconPair.IconIndex, extIconPair.TypeName); + _map.AddToSorted(extIconPair); + typeName = extIconPair.TypeName; + return extIconPair.IconIndex; +} + +int CExtToIconMap::GetIconIndex(UINT32 attributes, const UString &fileName) +{ + UString typeName; + return GetIconIndex(attributes, fileName, typeName); +} diff --git a/CPP/7zip/FileManager/SysIconUtils.h b/CPP/7zip/FileManager/SysIconUtils.h new file mode 100755 index 00000000..51294751 --- /dev/null +++ b/CPP/7zip/FileManager/SysIconUtils.h @@ -0,0 +1,51 @@ +// SysIconUtils.h + +#ifndef __SYSICONUTILS_H +#define __SYSICONUTILS_H + +#include "Common/String.h" + +struct CExtIconPair +{ + UString Ext; + int IconIndex; + UString TypeName; + +}; + +inline bool operator==(const CExtIconPair &a1, const CExtIconPair &a2) +{ + return (a1.Ext == a2.Ext); +} + +inline bool operator<(const CExtIconPair &a1, const CExtIconPair &a2) +{ + return (a1.Ext < a2.Ext); +} + +class CExtToIconMap +{ + int _dirIconIndex; + UString _dirTypeName; + int _noExtIconIndex; + UString _noExtTypeName; + CObjectVector _map; +public: + CExtToIconMap(): _dirIconIndex(-1), _noExtIconIndex(-1) {} + void Clear() + { + _dirIconIndex = -1; + _noExtIconIndex = -1; + _map.Clear(); + } + int GetIconIndex(UINT32 attributes, const UString &fileName, UString &typeName); + int GetIconIndex(UINT32 attributes, const UString &fileName); +}; + +DWORD_PTR GetRealIconIndex(LPCTSTR path, UINT32 attributes, int &iconIndex); +#ifndef _UNICODE +DWORD_PTR GetRealIconIndex(LPCWSTR path, UINT32 attributes, int &iconIndex); +#endif +int GetIconIndexForCSIDL(int aCSIDL); + +#endif diff --git a/CPP/7zip/FileManager/Test.bmp b/CPP/7zip/FileManager/Test.bmp new file mode 100755 index 00000000..ef85ba23 Binary files /dev/null and b/CPP/7zip/FileManager/Test.bmp differ diff --git a/CPP/7zip/FileManager/Test2.bmp b/CPP/7zip/FileManager/Test2.bmp new file mode 100755 index 00000000..99b7dbf0 Binary files /dev/null and b/CPP/7zip/FileManager/Test2.bmp differ diff --git a/CPP/7zip/FileManager/TextPairs.cpp b/CPP/7zip/FileManager/TextPairs.cpp new file mode 100755 index 00000000..76c97b8c --- /dev/null +++ b/CPP/7zip/FileManager/TextPairs.cpp @@ -0,0 +1,216 @@ +// Common/TextPairs.cpp + +#include "StdAfx.h" + +#include "TextPairs.h" + +#include "Common/Defs.h" +#include "Common/UTFConvert.h" + +static const wchar_t kNewLineChar = '\n'; + +static const wchar_t kSpaceChar = ' '; +static const wchar_t kTabChar = '\t'; + +static const wchar_t kQuoteChar = '\"'; +static const wchar_t kEndOfLine = '\0'; + +static const wchar_t kBOM = wchar_t(0xFEFF); + +static bool IsSeparatorChar(wchar_t c) +{ + return (c == kSpaceChar || c == kTabChar); +} + +static UString GetIDString(const wchar_t *srcString, int &finishPos) +{ + UString result; + bool quotes = false; + for (finishPos = 0;;) + { + wchar_t c = srcString[finishPos]; + if (c == kEndOfLine) + break; + finishPos++; + bool isSeparatorChar = IsSeparatorChar(c); + if (c == kNewLineChar || (isSeparatorChar && !quotes) + || (c == kQuoteChar && quotes)) + break; + else if (c == kQuoteChar) + quotes = true; + else + result += c; + } + result.Trim(); + return result; +} + +static UString GetValueString(const wchar_t *srcString, int &finishPos) +{ + UString result; + for (finishPos = 0;;) + { + wchar_t c = srcString[finishPos]; + if (c == kEndOfLine) + break; + finishPos++; + if (c == kNewLineChar) + break; + result += c; + } + result.Trim(); + return result; +} + +static bool GetTextPairs(const UString &srcString, CObjectVector &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 &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 &pairs, const UString &id) +{ + int index = FindItem(pairs, id); + if (index < 0) + return UString(); + return pairs[index].Value; +} + +static int ComparePairIDs(const UString &s1, const UString &s2) + { return s1.CompareNoCase(s2); } +static int ComparePairItems(const CTextPair &p1, const CTextPair &p2) + { return ComparePairIDs(p1.ID, p2.ID); } + +// typedef void* MY_PVOID; + +// static int ComparePairItems(const MY_PVOID *a1, const MY_PVOID *a2, void *param) +static int ComparePairItems(void *const *a1, void *const *a2, void * /* param */) + { return ComparePairItems(**(const CTextPair **)a1, **(const CTextPair **)a2); } + +void CPairsStorage::Sort() + { Pairs.Sort(ComparePairItems, 0); } + +int CPairsStorage::FindID(const UString &id, int &insertPos) +{ + int left = 0, right = Pairs.Size(); + while (left != right) + { + UINT32 mid = (left + right) / 2; + int compResult = ComparePairIDs(id, Pairs[mid].ID); + if (compResult == 0) + return mid; + if (compResult < 0) + right = mid; + else + left = mid + 1; + } + insertPos = left; + return -1; +} + +int CPairsStorage::FindID(const UString &id) +{ + int pos; + return FindID(id, pos); +} + +void CPairsStorage::AddPair(const CTextPair &pair) +{ + int insertPos; + int pos = FindID(pair.ID, insertPos); + if (pos >= 0) + Pairs[pos] = pair; + else + Pairs.Insert(insertPos, pair); +} + +void CPairsStorage::DeletePair(const UString &id) +{ + int pos = FindID(id); + if (pos >= 0) + Pairs.Delete(pos); +} + +bool CPairsStorage::GetValue(const UString &id, UString &value) +{ + value.Empty(); + int pos = FindID(id); + if (pos < 0) + return false; + value = Pairs[pos].Value; + return true; +} + +UString CPairsStorage::GetValue(const UString &id) +{ + int pos = FindID(id); + if (pos < 0) + return UString(); + return Pairs[pos].Value; +} + +bool CPairsStorage::ReadFromString(const UString &text) +{ + bool result = ::GetTextPairs(text, Pairs); + if (result) + Sort(); + else + Pairs.Clear(); + return result; +} + +void CPairsStorage::SaveToString(UString &text) +{ + for (int i = 0; i < Pairs.Size(); i++) + { + const CTextPair &pair = Pairs[i]; + bool multiWord = (pair.ID.Find(L' ') >= 0); + if (multiWord) + text += L'\"'; + text += pair.ID; + if (multiWord) + text += L'\"'; + text += L' '; + text += pair.Value; + text += L'\n'; + } +} diff --git a/CPP/7zip/FileManager/TextPairs.h b/CPP/7zip/FileManager/TextPairs.h new file mode 100755 index 00000000..247a92d9 --- /dev/null +++ b/CPP/7zip/FileManager/TextPairs.h @@ -0,0 +1,32 @@ +// Common/TextPairs.h + +#ifndef __COMMON_TEXTPAIRS_H +#define __COMMON_TEXTPAIRS_H + +#include "Common/Vector.h" +#include "Common/String.h" + +struct CTextPair +{ + UString ID; + UString Value; +}; + +class CPairsStorage +{ + CObjectVector Pairs; + int FindID(const UString &id, int &insertPos); + int FindID(const UString &id); + void Sort(); +public: + void Clear() { Pairs.Clear(); }; + bool ReadFromString(const UString &text); + void SaveToString(UString &text); + + bool GetValue(const UString &id, UString &value); + UString GetValue(const UString &id); + void AddPair(const CTextPair &pair); + void DeletePair(const UString &id); +}; + +#endif diff --git a/CPP/7zip/FileManager/UpdateCallback100.cpp b/CPP/7zip/FileManager/UpdateCallback100.cpp new file mode 100755 index 00000000..ddd2e55d --- /dev/null +++ b/CPP/7zip/FileManager/UpdateCallback100.cpp @@ -0,0 +1,92 @@ +// UpdateCallback.h + +#include "StdAfx.h" + +#include "Common/StringConvert.h" + +#include "UpdateCallback100.h" +// #include "Windows/ProcessMessages.h" +// #include "Resource/PasswordDialog/PasswordDialog.h" +#include "Resource/MessagesDialog/MessagesDialog.h" + +#include "Common/Defs.h" + +using namespace NWindows; + +CUpdateCallback100Imp::~CUpdateCallback100Imp() +{ + if (ShowMessages && !Messages.IsEmpty()) + { + CMessagesDialog messagesDialog; + messagesDialog.Messages = &Messages; + messagesDialog.Create(_parentWindow); + } +} + +void CUpdateCallback100Imp::AddErrorMessage(LPCWSTR message) +{ + Messages.Add(message); +} + +STDMETHODIMP CUpdateCallback100Imp::SetTotal(UINT64 size) +{ + ProgressDialog.ProgressSynch.SetProgress(size, 0); + return S_OK; +} + +STDMETHODIMP CUpdateCallback100Imp::SetCompleted(const UINT64 *completeValue) +{ + for (;;) + { + if(ProgressDialog.ProgressSynch.GetStopped()) + return E_ABORT; + if(!ProgressDialog.ProgressSynch.GetPaused()) + break; + ::Sleep(100); + } + if (completeValue != NULL) + ProgressDialog.ProgressSynch.SetPos(*completeValue); + return S_OK; +} + +STDMETHODIMP CUpdateCallback100Imp::CompressOperation(const wchar_t *name) +{ + ProgressDialog.ProgressSynch.SetCurrentFileName(name); + return S_OK; +} + +STDMETHODIMP CUpdateCallback100Imp::DeleteOperation(const wchar_t * /* name */) +{ + return S_OK; +} + +STDMETHODIMP CUpdateCallback100Imp::OperationResult(INT32 /* operationResult */) +{ + return S_OK; +} + +STDMETHODIMP CUpdateCallback100Imp::UpdateErrorMessage(const wchar_t *message) +{ + AddErrorMessage(message); + return S_OK; +} + +STDMETHODIMP CUpdateCallback100Imp::CryptoGetTextPassword2(INT32 *passwordIsDefined, BSTR *password) +{ + *passwordIsDefined = BoolToInt(_passwordIsDefined); + if (!_passwordIsDefined) + { + return S_OK; + /* + CPasswordDialog dialog; + if (dialog.Create(_parentWindow) == IDCANCEL) + return E_ABORT; + _password = dialog._password; + _passwordIsDefined = true; + */ + } + *passwordIsDefined = BoolToInt(_passwordIsDefined); + CMyComBSTR tempName = _password; + *password = tempName.Detach(); + return S_OK; +} diff --git a/CPP/7zip/FileManager/UpdateCallback100.h b/CPP/7zip/FileManager/UpdateCallback100.h new file mode 100755 index 00000000..4cce5b52 --- /dev/null +++ b/CPP/7zip/FileManager/UpdateCallback100.h @@ -0,0 +1,67 @@ +// UpdateCallback100.h + +#ifndef __UPDATE_CALLBACK100_H +#define __UPDATE_CALLBACK100_H + +#include "Common/MyCom.h" +#include "Common/String.h" + +#include "../UI/Agent/IFolderArchive.h" +#include "Resource/ProgressDialog2/ProgressDialog.h" +#include "../IPassword.h" + +#ifdef LANG +#include "LangUtils.h" +#endif + +class CUpdateCallback100Imp: + public IFolderArchiveUpdateCallback, + public ICryptoGetTextPassword2, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP2( + IFolderArchiveUpdateCallback, + ICryptoGetTextPassword2) + + // IProgress + + STDMETHOD(SetTotal)(UINT64 size); + STDMETHOD(SetCompleted)(const UINT64 *completeValue); + + // IUpdateCallBack + STDMETHOD(CompressOperation)(const wchar_t *name); + STDMETHOD(DeleteOperation)(const wchar_t *name); + STDMETHOD(OperationResult)(INT32 operationResult); + STDMETHOD(UpdateErrorMessage)(const wchar_t *message); + + STDMETHOD(CryptoGetTextPassword2)(INT32 *passwordIsDefined, BSTR *password); +private: + bool _passwordIsDefined; + UString _password; + + void AddErrorMessage(LPCWSTR message); + bool ShowMessages; + +public: + CUpdateCallback100Imp(): ShowMessages(true) {} + ~CUpdateCallback100Imp(); + CProgressDialog ProgressDialog; + HWND _parentWindow; + UStringVector Messages; + + void Init(HWND parentWindow, + bool passwordIsDefined, const UString &password) + { + _passwordIsDefined = passwordIsDefined; + _password = password; + _parentWindow = parentWindow; + } + void StartProgressDialog(const UString &title) + { + ProgressDialog.Create(title, _parentWindow); + } + +}; + +#endif diff --git a/CPP/7zip/FileManager/ViewSettings.cpp b/CPP/7zip/FileManager/ViewSettings.cpp new file mode 100755 index 00000000..9102cc4e --- /dev/null +++ b/CPP/7zip/FileManager/ViewSettings.cpp @@ -0,0 +1,429 @@ +// ViewSettings.h + +#include "StdAfx.h" + +#include "Common/IntToString.h" +#include "Common/StringConvert.h" + +#include "ViewSettings.h" +#include "Windows/Registry.h" +#include "Windows/Synchronization.h" + +using namespace NWindows; +using namespace NRegistry; + +static const TCHAR *kCUBasePath = TEXT("Software\\7-Zip\\FM"); + +static const TCHAR *kCulumnsKeyName = TEXT("Columns"); + +static const TCHAR *kPositionValueName = TEXT("Position"); +static const TCHAR *kPanelsInfoValueName = TEXT("Panels"); +static const TCHAR *kToolbars = TEXT("Toolbars"); + +static const WCHAR *kPanelPathValueName = L"PanelPath"; +static const TCHAR *kListMode = TEXT("ListMode"); +static const TCHAR *kFolderHistoryValueName = TEXT("FolderHistory"); +static const TCHAR *kFastFoldersValueName = TEXT("FolderShortcuts"); +static const TCHAR *kCopyHistoryValueName = TEXT("CopyHistory"); + +/* +class CColumnInfoSpec +{ + UInt32 PropID; + Byte IsVisible; + UInt32 Width; +}; + +struct CColumnHeader +{ + UInt32 Version; + UInt32 SortID; + Byte Ascending; +}; +*/ + +static const UInt32 kColumnInfoSpecHeader = 12; +static const UInt32 kColumnHeaderSize = 12; + +static const UInt32 kColumnInfoVersion = 1; + +static NSynchronization::CCriticalSection g_RegistryOperationsCriticalSection; + +class CTempOutBufferSpec +{ + CByteBuffer Buffer; + UInt32 Size; + UInt32 Pos; +public: + operator const Byte *() const { return (const Byte *)Buffer; } + void Init(UInt32 dataSize) + { + Buffer.SetCapacity(dataSize); + Size = dataSize; + Pos = 0; + } + void WriteByte(Byte value) + { + if (Pos >= Size) + throw "overflow"; + ((Byte *)Buffer)[Pos++] = value; + } + void WriteUInt32(UInt32 value) + { + for (int i = 0; i < 4; i++) + { + WriteByte((Byte)value); + value >>= 8; + } + } + void WriteBool(bool value) + { + WriteUInt32(value ? 1 : 0); + } +}; + +class CTempInBufferSpec +{ +public: + Byte *Buffer; + UInt32 Size; + UInt32 Pos; + Byte ReadByte() + { + if (Pos >= Size) + throw "overflow"; + return Buffer[Pos++]; + } + UInt32 ReadUInt32() + { + UInt32 value = 0; + for (int i = 0; i < 4; i++) + value |= (((UInt32)ReadByte()) << (8 * i)); + return value; + } + bool ReadBool() + { + return (ReadUInt32() != 0); + } +}; + +void SaveListViewInfo(const UString &id, const CListViewInfo &viewInfo) +{ + const CObjectVector &columns = viewInfo.Columns; + CTempOutBufferSpec buffer; + UInt32 dataSize = kColumnHeaderSize + kColumnInfoSpecHeader * columns.Size(); + buffer.Init(dataSize); + + buffer.WriteUInt32(kColumnInfoVersion); + buffer.WriteUInt32(viewInfo.SortID); + buffer.WriteBool(viewInfo.Ascending); + for(int i = 0; i < columns.Size(); i++) + { + const CColumnInfo &column = columns[i]; + buffer.WriteUInt32(column.PropID); + buffer.WriteBool(column.IsVisible); + buffer.WriteUInt32(column.Width); + } + { + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CSysString keyName = kCUBasePath; + keyName += kKeyNameDelimiter; + keyName += kCulumnsKeyName; + CKey key; + key.Create(HKEY_CURRENT_USER, keyName); + key.SetValue(GetSystemString(id), (const Byte *)buffer, dataSize); + } +} + +void ReadListViewInfo(const UString &id, CListViewInfo &viewInfo) +{ + viewInfo.Clear(); + CObjectVector &columns = viewInfo.Columns; + CByteBuffer buffer; + UInt32 size; + { + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CSysString keyName = kCUBasePath; + keyName += kKeyNameDelimiter; + keyName += kCulumnsKeyName; + CKey key; + if(key.Open(HKEY_CURRENT_USER, keyName, KEY_READ) != ERROR_SUCCESS) + return; + if (key.QueryValue(GetSystemString(id), buffer, size) != ERROR_SUCCESS) + return; + } + if (size < kColumnHeaderSize) + return; + CTempInBufferSpec inBuffer; + inBuffer.Size = size; + inBuffer.Buffer = (Byte *)buffer; + inBuffer.Pos = 0; + + + UInt32 version = inBuffer.ReadUInt32(); + if (version != kColumnInfoVersion) + return; + viewInfo.SortID = inBuffer.ReadUInt32(); + viewInfo.Ascending = inBuffer.ReadBool(); + + size -= kColumnHeaderSize; + if (size % kColumnInfoSpecHeader != 0) + return; + int numItems = size / kColumnInfoSpecHeader; + columns.Reserve(numItems); + for(int i = 0; i < numItems; i++) + { + CColumnInfo columnInfo; + columnInfo.PropID = inBuffer.ReadUInt32(); + columnInfo.IsVisible = inBuffer.ReadBool(); + columnInfo.Width = inBuffer.ReadUInt32(); + columns.Add(columnInfo); + } +} + +static const UInt32 kWindowPositionHeaderSize = 5 * 4; +static const UInt32 kPanelsInfoHeaderSize = 3 * 4; + +/* +struct CWindowPosition +{ + RECT Rect; + UInt32 Maximized; +}; + +struct CPanelsInfo +{ + UInt32 NumPanels; + UInt32 CurrentPanel; + UInt32 SplitterPos; +}; +*/ + +void SaveWindowSize(const RECT &rect, bool maximized) +{ + CSysString keyName = kCUBasePath; + CKey key; + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + key.Create(HKEY_CURRENT_USER, keyName); + // CWindowPosition position; + CTempOutBufferSpec buffer; + buffer.Init(kWindowPositionHeaderSize); + buffer.WriteUInt32(rect.left); + buffer.WriteUInt32(rect.top); + buffer.WriteUInt32(rect.right); + buffer.WriteUInt32(rect.bottom); + buffer.WriteBool(maximized); + key.SetValue(kPositionValueName, (const Byte *)buffer, kWindowPositionHeaderSize); +} + +bool ReadWindowSize(RECT &rect, bool &maximized) +{ + CSysString keyName = kCUBasePath; + CKey key; + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + if(key.Open(HKEY_CURRENT_USER, keyName, KEY_READ) != ERROR_SUCCESS) + return false; + CByteBuffer buffer; + UInt32 size; + if (key.QueryValue(kPositionValueName, buffer, size) != ERROR_SUCCESS) + return false; + if (size != kWindowPositionHeaderSize) + return false; + CTempInBufferSpec inBuffer; + inBuffer.Size = size; + inBuffer.Buffer = (Byte *)buffer; + inBuffer.Pos = 0; + rect.left = inBuffer.ReadUInt32(); + rect.top = inBuffer.ReadUInt32(); + rect.right = inBuffer.ReadUInt32(); + rect.bottom = inBuffer.ReadUInt32(); + maximized = inBuffer.ReadBool(); + return true; +} + +void SavePanelsInfo(UInt32 numPanels, UInt32 currentPanel, UInt32 splitterPos) +{ + CSysString keyName = kCUBasePath; + CKey key; + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + key.Create(HKEY_CURRENT_USER, keyName); + + CTempOutBufferSpec buffer; + buffer.Init(kPanelsInfoHeaderSize); + buffer.WriteUInt32(numPanels); + buffer.WriteUInt32(currentPanel); + buffer.WriteUInt32(splitterPos); + key.SetValue(kPanelsInfoValueName, (const Byte *)buffer, kPanelsInfoHeaderSize); +} + +bool ReadPanelsInfo(UInt32 &numPanels, UInt32 ¤tPanel, UInt32 &splitterPos) +{ + CSysString keyName = kCUBasePath; + CKey key; + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + if(key.Open(HKEY_CURRENT_USER, keyName, KEY_READ) != ERROR_SUCCESS) + return false; + CByteBuffer buffer; + UInt32 size; + if (key.QueryValue(kPanelsInfoValueName, buffer, size) != ERROR_SUCCESS) + return false; + if (size != kPanelsInfoHeaderSize) + return false; + CTempInBufferSpec inBuffer; + inBuffer.Size = size; + inBuffer.Buffer = (Byte *)buffer; + inBuffer.Pos = 0; + numPanels = inBuffer.ReadUInt32(); + currentPanel = inBuffer.ReadUInt32(); + splitterPos = inBuffer.ReadUInt32(); + return true; +} + +void SaveToolbarsMask(UInt32 toolbarMask) +{ + CKey key; + key.Create(HKEY_CURRENT_USER, kCUBasePath); + key.SetValue(kToolbars, toolbarMask); +} + +static const UInt32 kDefaultToolbarMask = 8 | 4 | 1; + +UInt32 ReadToolbarsMask() +{ + CKey key; + if(key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) + return kDefaultToolbarMask; + UInt32 mask; + if (key.QueryValue(kToolbars, mask) != ERROR_SUCCESS) + return kDefaultToolbarMask; + return mask; +} + + +static UString GetPanelPathName(UInt32 panelIndex) +{ + WCHAR panelString[32]; + ConvertUInt64ToString(panelIndex, panelString); + return UString(kPanelPathValueName) + panelString; +} + + +void SavePanelPath(UInt32 panel, const UString &path) +{ + CKey key; + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + key.Create(HKEY_CURRENT_USER, kCUBasePath); + key.SetValue(GetPanelPathName(panel), path); +} + +bool ReadPanelPath(UInt32 panel, UString &path) +{ + CKey key; + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + if(key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) + return false; + return (key.QueryValue(GetPanelPathName(panel), path) == ERROR_SUCCESS); +} + +void SaveListMode(const CListMode &listMode) +{ + CKey key; + key.Create(HKEY_CURRENT_USER, kCUBasePath); + UInt32 t = 0; + for (int i = 0; i < 2; i++) + t |= ((listMode.Panels[i]) & 0xFF) << (i * 8); + key.SetValue(kListMode, t); +} + +void ReadListMode(CListMode &listMode) +{ + CKey key; + listMode.Init(); + if(key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) + return; + UInt32 t; + if (key.QueryValue(kListMode, t) != ERROR_SUCCESS) + return; + for (int i = 0; i < 2; i++) + { + listMode.Panels[i] = (t & 0xFF); + t >>= 8; + } +} + + +void SaveStringList(LPCTSTR valueName, const UStringVector &folders) +{ + UInt32 sizeInChars = 0; + int i; + for (i = 0; i < folders.Size(); i++) + sizeInChars += folders[i].Length() + 1; + CBuffer buffer; + buffer.SetCapacity(sizeInChars); + int pos = 0; + for (i = 0; i < folders.Size(); i++) + { + MyStringCopy((wchar_t *)buffer + pos, (const wchar_t *)folders[i]); + pos += folders[i].Length() + 1; + } + CKey key; + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + key.Create(HKEY_CURRENT_USER, kCUBasePath); + key.SetValue(valueName, buffer, sizeInChars * sizeof(wchar_t)); +} + +void ReadStringList(LPCTSTR valueName, UStringVector &folders) +{ + folders.Clear(); + CKey key; + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + if(key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) + return; + CByteBuffer buffer; + UInt32 dataSize; + if (key.QueryValue(valueName, buffer, dataSize) != ERROR_SUCCESS) + return; + if (dataSize % sizeof(wchar_t) != 0) + return; + const wchar_t *data = (const wchar_t *)(const Byte *)buffer; + int sizeInChars = dataSize / sizeof(wchar_t); + UString string; + for (int i = 0; i < sizeInChars; i++) + { + wchar_t c = data[i]; + if (c == L'\0') + { + folders.Add(string); + string.Empty(); + } + else + string += c; + } +} + +void SaveFolderHistory(const UStringVector &folders) + { SaveStringList(kFolderHistoryValueName, folders); } +void ReadFolderHistory(UStringVector &folders) + { ReadStringList(kFolderHistoryValueName, folders); } + +void SaveFastFolders(const UStringVector &folders) + { SaveStringList(kFastFoldersValueName, folders); } +void ReadFastFolders(UStringVector &folders) + { ReadStringList(kFastFoldersValueName, folders); } + +void SaveCopyHistory(const UStringVector &folders) + { SaveStringList(kCopyHistoryValueName, folders); } +void ReadCopyHistory(UStringVector &folders) + { ReadStringList(kCopyHistoryValueName, folders); } + +void AddUniqueStringToHeadOfList(UStringVector &list, + const UString &string) +{ + for(int i = 0; i < list.Size();) + if (string.CompareNoCase(list[i]) == 0) + list.Delete(i); + else + i++; + list.Insert(0, string); +} + diff --git a/CPP/7zip/FileManager/ViewSettings.h b/CPP/7zip/FileManager/ViewSettings.h new file mode 100755 index 00000000..4894a6f9 --- /dev/null +++ b/CPP/7zip/FileManager/ViewSettings.h @@ -0,0 +1,99 @@ +// ViewSettings.h + +#ifndef __VIEWSETTINGS_H +#define __VIEWSETTINGS_H + +#include "Common/Vector.h" +#include "Common/String.h" + +struct CColumnInfo +{ + PROPID PropID; + bool IsVisible; + UInt32 Width; +}; + +inline bool operator==(const CColumnInfo &a1, const CColumnInfo &a2) +{ + return (a1.PropID == a2.PropID) && + (a1.IsVisible == a2.IsVisible) && (a1.Width == a2.Width); +} + +inline bool operator!=(const CColumnInfo &a1, const CColumnInfo &a2) +{ + return !(a1 == a2); +} + +struct CListViewInfo +{ + CObjectVector Columns; + PROPID SortID; + bool Ascending; + + void Clear() + { + SortID = 0; + Ascending = true; + Columns.Clear(); + } + + int FindColumnWithID(PROPID propID) const + { + for (int i = 0; i < Columns.Size(); i++) + if (Columns[i].PropID == propID) + return i; + return -1; + } + + bool IsEqual(const CListViewInfo &aNewInfo) const + { + if (Columns.Size() != aNewInfo.Columns.Size() || + // SortIndex != aNewInfo.SortIndex || + SortID != aNewInfo.SortID || + Ascending != aNewInfo.Ascending) + return false; + for (int i = 0; i < Columns.Size(); i++) + if (Columns[i] != aNewInfo.Columns[i]) + return false; + return true; + } +}; + +void SaveListViewInfo(const UString &id, const CListViewInfo &viewInfo); +void ReadListViewInfo(const UString &id, CListViewInfo &viewInfo); + +void SaveWindowSize(const RECT &rect, bool maximized); +bool ReadWindowSize(RECT &rect, bool &maximized); + +void SavePanelsInfo(UInt32 numPanels, UInt32 currentPanel, UInt32 splitterPos); +bool ReadPanelsInfo(UInt32 &numPanels, UInt32 ¤tPanel, UInt32 &splitterPos); + +void SaveToolbarsMask(UInt32 toolbarMask); +UInt32 ReadToolbarsMask(); + +void SavePanelPath(UInt32 panel, const UString &path); +bool ReadPanelPath(UInt32 panel, UString &path); + +struct CListMode +{ + UInt32 Panels[2]; + void Init() { Panels[0] = Panels[1] = 3; } + CListMode() { Init(); } +}; + +void SaveListMode(const CListMode &listMode); +void ReadListMode(CListMode &listMode); + +void SaveFolderHistory(const UStringVector &folders); +void ReadFolderHistory(UStringVector &folders); + +void SaveFastFolders(const UStringVector &folders); +void ReadFastFolders(UStringVector &folders); + +void SaveCopyHistory(const UStringVector &folders); +void ReadCopyHistory(UStringVector &folders); + +void AddUniqueStringToHeadOfList(UStringVector &list, + const UString &string); + +#endif diff --git a/CPP/7zip/FileManager/makefile b/CPP/7zip/FileManager/makefile new file mode 100755 index 00000000..42619e0a --- /dev/null +++ b/CPP/7zip/FileManager/makefile @@ -0,0 +1,187 @@ +PROG = 7zFM.exe +LIBS = $(LIBS) user32.lib oleaut32.lib advapi32.lib shell32.lib ole32.lib comctl32.lib htmlhelp.lib Mpr.lib Gdi32.lib comdlg32.lib +CFLAGS = $(CFLAGS) -I../../ -DLANG -DWIN_LONG_PATH + +FM_OBJS = \ + $O\App.obj \ + $O\ClassDefs.obj \ + $O\EnumFormatEtc.obj \ + $O\ExtractCallback.obj \ + $O\FileFolderPluginOpen.obj \ + $O\FilePlugins.obj \ + $O\FM.obj \ + $O\FormatUtils.obj \ + $O\FSDrives.obj \ + $O\FSFolder.obj \ + $O\FSFolderCopy.obj \ + $O\HelpUtils.obj \ + $O\LangUtils.obj \ + $O\MyLoadMenu.obj \ + $O\NetFolder.obj \ + $O\OpenCallback.obj \ + $O\OptionsDialog.obj \ + $O\Panel.obj \ + $O\PanelCopy.obj \ + $O\PanelCrc.obj \ + $O\PanelDrag.obj \ + $O\PanelFolderChange.obj \ + $O\PanelItemOpen.obj \ + $O\PanelItems.obj \ + $O\PanelKey.obj \ + $O\PanelListNotify.obj \ + $O\PanelMenu.obj \ + $O\PanelOperations.obj \ + $O\PanelSelect.obj \ + $O\PanelSort.obj \ + $O\PanelSplitFile.obj \ + $O\PhysDriveFolder.obj \ + $O\ProgramLocation.obj \ + $O\PropertyName.obj \ + $O\RegistryAssociations.obj \ + $O\RegistryPlugins.obj \ + $O\RegistryUtils.obj \ + $O\RootFolder.obj \ + $O\SplitUtils.obj \ + $O\StringUtils.obj \ + $O\SysIconUtils.obj \ + $O\TextPairs.obj \ + $O\UpdateCallback100.obj \ + $O\ViewSettings.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CRC.obj \ + $O\IntToString.obj \ + $O\Lang.obj \ + $O\ListFileUtils.obj \ + $O\NewHandler.obj \ + $O\Random.obj \ + $O\StdInStream.obj \ + $O\StdOutStream.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\TextConfig.obj \ + $O\UTFConvert.obj \ + $O\Vector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\CommonDialog.obj \ + $O\DLL.obj \ + $O\Error.obj \ + $O\FileDevice.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\FileSystem.obj \ + $O\Memory.obj \ + $O\MemoryLock.obj \ + $O\Menu.obj \ + $O\Net.obj \ + $O\PropVariant.obj \ + $O\PropVariantConversions.obj \ + $O\Registry.obj \ + $O\ResourceString.obj \ + $O\Security.obj \ + $O\Shell.obj \ + $O\Synchronization.obj \ + $O\Window.obj \ + +WIN_CTRL_OBJS = \ + $O\ComboBox.obj \ + $O\Dialog.obj \ + $O\ListView.obj \ + $O\PropertyPage.obj \ + $O\Window2.obj \ + +7ZIP_COMMON_OBJS = \ + $O\FilePathAutoRename.obj \ + $O\FileStreams.obj \ + $O\StreamObjects.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveName.obj \ + $O\CompressCall.obj \ + $O\PropIDUtils.obj \ + +C_OBJS = \ + $O\Sort.obj \ + + +OBJS = \ + $O\StdAfx.obj \ + $(FM_OBJS)\ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(WIN_CTRL_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(UI_COMMON_OBJS) \ + $O\AboutDialog.obj \ + $O\BenchmarkDialog.obj \ + $O\ComboDialog.obj \ + $O\CopyDialog.obj \ + $O\EditPage.obj \ + $O\LangPage.obj \ + $O\ListViewDialog.obj \ + $O\MessagesDialog.obj \ + $O\OverwriteDialog.obj \ + $O\PasswordDialog.obj \ + $O\PluginsPage.obj \ + $O\ProgressDialog.obj \ + $O\SettingsPage.obj \ + $O\SplitDialog.obj \ + $O\SystemPage.obj \ + $O\resource.res \ + $(C_OBJS) \ + +!include "../../Build.mak" + +$(FM_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../Windows/$(*B).cpp + $(COMPL) +$(WIN_CTRL_OBJS): ../../Windows/Control/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$(UI_COMMON_OBJS): ../UI/Common/$(*B).cpp + $(COMPL) + +$O\AboutDialog.obj: Resource/AboutDialog/AboutDialog.cpp + $(COMPL) +$O\BenchmarkDialog.obj: Resource/BenchmarkDialog/BenchmarkDialog.cpp + $(COMPL) +$O\ComboDialog.obj: Resource/ComboDialog/ComboDialog.cpp + $(COMPL) +$O\CopyDialog.obj: Resource/CopyDialog/CopyDialog.cpp + $(COMPL) +$O\EditPage.obj: Resource/EditPage/EditPage.cpp + $(COMPL) +$O\LangPage.obj: Resource/LangPage/LangPage.cpp + $(COMPL) +$O\ListViewDialog.obj: Resource/ListViewDialog/ListViewDialog.cpp + $(COMPL) +$O\MessagesDialog.obj: Resource/MessagesDialog/MessagesDialog.cpp + $(COMPL) +$O\OverwriteDialog.obj: Resource/OverwriteDialog/OverwriteDialog.cpp + $(COMPL) +$O\PasswordDialog.obj: Resource/PasswordDialog/PasswordDialog.cpp + $(COMPL) +$O\PluginsPage.obj: Resource/PluginsPage/PluginsPage.cpp + $(COMPL) +$O\ProgressDialog.obj: Resource/ProgressDialog2/ProgressDialog.cpp + $(COMPL) +$O\SettingsPage.obj: Resource/SettingsPage/SettingsPage.cpp + $(COMPL) +$O\SplitDialog.obj: Resource/SplitDialog/SplitDialog.cpp + $(COMPL) +$O\SystemPage.obj: Resource/SystemPage/SystemPage.cpp + $(COMPL) +$(C_OBJS): ../../../C/$(*B).c + $(COMPL_O2) + + diff --git a/CPP/7zip/FileManager/resource.h b/CPP/7zip/FileManager/resource.h new file mode 100755 index 00000000..bc809306 --- /dev/null +++ b/CPP/7zip/FileManager/resource.h @@ -0,0 +1,154 @@ +#define IDI_FAM 101 +#define IDI_FM 101 +#define IDR_MENUBAR1 103 +#define IDM_MENU 103 +#define IDR_ACCELERATOR1 209 +#define IDM_FILE_OPEN 210 +#define IDM_FILE_OPEN_INSIDE 211 +#define IDM_FILE_OPEN_OUTSIDE 212 +#define IDM_FILE_VIEW 220 +#define IDM_FILE_EDIT 221 +#define IDM_RENAME 230 +#define IDM_COPY_TO 231 +#define IDM_MOVE_TO 232 +#define IDM_DELETE 233 +#define IDM_FILE_SPLIT 238 +#define IDM_FILE_COMBINE 239 +#define IDM_FILE_PROPERTIES 240 +#define IDM_FILE_COMMENT 241 +#define IDM_FILE_CRC 242 +#define IDM_CREATE_FOLDER 250 +#define IDM_CREATE_FILE 251 +#define IDM_EDIT_CUT 320 +#define IDM_EDIT_COPY 321 +#define IDM_EDIT_PASTE 322 +#define IDM_SELECT_ALL 330 +#define IDM_DESELECT_ALL 331 +#define IDM_INVERT_SELECTION 332 +#define IDM_SELECT 333 +#define IDM_DESELECT 334 +#define IDM_SELECT_BY_TYPE 335 +#define IDM_DESELECT_BY_TYPE 336 +#define IDM_VIEW_LARGE_ICONS 410 +#define IDM_VIEW_SMALL_ICONS 411 +#define IDM_VIEW_LIST 412 +#define IDM_VIEW_DETAILS 413 +#define IDM_VIEW_ARANGE_BY_NAME 420 +#define IDM_VIEW_ARANGE_BY_TYPE 421 +#define IDM_VIEW_ARANGE_BY_DATE 422 +#define IDM_VIEW_ARANGE_BY_SIZE 423 +#define IDM_VIEW_ARANGE_NO_SORT 424 +#define IDM_OPEN_ROOT_FOLDER 430 +#define IDM_OPEN_PARENT_FOLDER 431 +#define IDM_FOLDERS_HISTORY 432 +#define IDM_VIEW_REFRESH 440 +#define IDM_VIEW_FLAT_VIEW 449 +#define IDM_VIEW_TWO_PANELS 450 +#define IDM_VIEW_TOOLBARS 451 +#define IDM_VIEW_STANDARD_TOOLBAR 460 +#define IDM_VIEW_ARCHIVE_TOOLBAR 461 +#define IDM_VIEW_TOOLBARS_LARGE_BUTTONS 462 +#define IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT 463 +#define IDM_OPTIONS 510 +#define IDM_BENCHMARK 511 +#define IDM_HELP_CONTENTS 610 +#define IDM_ABOUT 620 +#define IDS_BOOKMARK 720 +#define IDB_ADD 2002 +#define IDB_EXTRACT 2003 +#define IDB_TEST 2004 +#define IDB_COPY 2010 +#define IDB_MOVE 2011 +#define IDB_DELETE 2012 +#define IDB_INFO 2013 +#define IDB_ADD2 2082 +#define IDB_EXTRACT2 2083 +#define IDB_TEST2 2084 +#define IDB_COPY2 2090 +#define IDB_MOVE2 2091 +#define IDB_DELETE2 2092 +#define IDB_INFO2 2093 +#define IDS_APP_TITLE 2200 +#define IDS_COPY 2201 +#define IDS_MOVE 2202 +#define IDS_COPY_TO 2203 +#define IDS_MOVE_TO 2204 +#define IDS_COPYING 2205 +#define IDS_MOVING 2206 +#define IDS_CANNOT_COPY 2207 +#define IDS_OPERATION_IS_NOT_SUPPORTED 2208 + +#define IDS_CONFIRM_FILE_DELETE 2210 +#define IDS_CONFIRM_FOLDER_DELETE 2211 +#define IDS_CONFIRM_ITEMS_DELETE 2212 +#define IDS_WANT_TO_DELETE_FILE 2213 +#define IDS_WANT_TO_DELETE_FOLDER 2214 +#define IDS_WANT_TO_DELETE_ITEMS 2215 +#define IDS_DELETING 2216 +#define IDS_ERROR_DELETING 2217 + +#define IDS_RENAMING 2220 +#define IDS_ERROR_RENAMING 2221 +#define IDS_CONFIRM_FILE_COPY 2222 +#define IDS_WANT_TO_COPY_FILES 2223 + + +#define IDS_CREATE_FOLDER 2230 +#define IDS_CREATE_FOLDER_NAME 2231 +#define IDS_CREATE_FOLDER_DEFAULT_NAME 2232 +#define IDS_CREATE_FOLDER_ERROR 2233 +#define IDS_CREATE_FILE 2240 +#define IDS_CREATE_FILE_NAME 2241 +#define IDS_CREATE_FOLDER_DEFAULT_FILE_NAME 2242 +#define IDS_CREATE_FILE_DEFAULT_NAME 2242 +#define IDS_CREATE_FILE_ERROR 2243 +#define IDS_SELECT 2250 +#define IDS_DESELECT 2251 +#define IDS_SELECT_MASK 2252 +#define IDS_FOLDERS_HISTORY 2260 +#define IDS_N_SELECTED_ITEMS 2270 +#define IDS_FILES_COLON 2274 +#define IDS_FOLDERS_COLON 2275 +#define IDS_SIZE_COLON 2276 + +#define IDS_TOO_MANY_ITEMS 2279 +#define IDS_WANT_UPDATE_MODIFIED_FILE 2280 +#define IDS_CANNOT_UPDATE_FILE 2281 +#define IDS_CANNOT_START_EDITOR 2282 +#define IDS_OPENNING 2283 +#define IDS_COMPUTER 2300 +#define IDS_NETWORK 2301 +#define IDS_ADD 2400 +#define IDS_EXTRACT 2401 +#define IDS_TEST 2402 +#define IDS_BUTTON_COPY 2420 +#define IDS_BUTTON_MOVE 2421 +#define IDS_BUTTON_DELETE 2422 +#define IDS_BUTTON_INFO 2423 +#define IDS_PROPERTY_TOTAL_SIZE 3100 +#define IDS_PROPERTY_FREE_SPACE 3101 +#define IDS_PROPERTY_CLUSTER_SIZE 3102 +#define IDS_PROPERTY_VOLUME_NAME 3103 +#define IDS_PROPERTY_LOCAL_NAME 3200 +#define IDS_PROPERTY_PROVIDER 3201 +#define IDS_OPTIONS 4000 +#define IDS_COMMENT 4001 +#define IDS_COMMENT2 4002 +#define IDS_SYSTEM 4010 + +#define IDS_SPLITTING 4020 +#define IDS_SPLIT_CONFIRM_TITLE 4021 +#define IDS_SPLIT_CONFIRM_MESSAGE 4022 +#define IDS_SPLIT_VOL_MUST_BE_SMALLER 4023 + +#define IDS_COMBINE 4030 +#define IDS_COMBINE_TO 4031 +#define IDS_COMBINING 4032 +#define IDS_COMBINE_SELECT_ONE_FILE 4033 + +#define IDS_CHECKSUM_CALCULATING 4040 +#define IDS_CHECKSUM_INFORMATION 4041 +#define IDS_CHECKSUM_CRC_DATA 4042 +#define IDS_CHECKSUM_CRC_DATA_NAMES 4043 + +#define IDS_SCANNING 4050 diff --git a/CPP/7zip/FileManager/resource.rc b/CPP/7zip/FileManager/resource.rc new file mode 100755 index 00000000..ed56cd48 --- /dev/null +++ b/CPP/7zip/FileManager/resource.rc @@ -0,0 +1,232 @@ +#include "../MyVersionInfo.rc" +#include "../GuiCommon.rc" +#include "resource.h" + +MY_VERSION_INFO_APP("7-Zip File Manager", "7zFM") + + +IDR_ACCELERATOR1 ACCELERATORS +BEGIN + "N", IDM_CREATE_FILE, VIRTKEY, CONTROL, NOINVERT + VK_F1, IDM_HELP_CONTENTS, VIRTKEY, NOINVERT + VK_F12, IDM_FOLDERS_HISTORY, VIRTKEY, ALT, NOINVERT + VK_F7, IDM_CREATE_FOLDER, VIRTKEY, NOINVERT +END + + +IDM_MENU MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Open\tEnter", IDM_FILE_OPEN + MENUITEM "Open &Inside\tCtrl+PgDn", IDM_FILE_OPEN_INSIDE + MENUITEM "Open O&utside\tShift+Enter", IDM_FILE_OPEN_OUTSIDE + MENUITEM "&Edit\tF4", IDM_FILE_EDIT + MENUITEM SEPARATOR + MENUITEM "Rena&me\tF2", IDM_RENAME + MENUITEM "&Copy To...\tF5", IDM_COPY_TO + MENUITEM "&Move To...\tF6", IDM_MOVE_TO + MENUITEM "&Delete\tDel", IDM_DELETE + MENUITEM SEPARATOR + MENUITEM "&Split file...", IDM_FILE_SPLIT + MENUITEM "Com&bine files...", IDM_FILE_COMBINE + MENUITEM SEPARATOR + MENUITEM "P&roperties\tAlt+Enter", IDM_FILE_PROPERTIES + MENUITEM "Comme&nt\tCtrl+Z", IDM_FILE_COMMENT + MENUITEM "Calculate checksum", IDM_FILE_CRC + MENUITEM SEPARATOR + MENUITEM "Create Folder\tF7", IDM_CREATE_FOLDER + MENUITEM "Create File\tCtrl+N", IDM_CREATE_FILE + MENUITEM SEPARATOR + MENUITEM "E&xit\tAlt+F4", IDCLOSE + END + POPUP "&Edit" + BEGIN + MENUITEM "Cu&t\tCtrl+X", IDM_EDIT_CUT, GRAYED + MENUITEM "&Copy\tCtrl+C", IDM_EDIT_COPY, GRAYED + MENUITEM "&Paste\tCtrl+V", IDM_EDIT_PASTE, GRAYED + MENUITEM SEPARATOR + MENUITEM "Select &All\tShift+[Grey +]", IDM_SELECT_ALL + MENUITEM "Deselect All\tShift+[Grey -]", IDM_DESELECT_ALL + MENUITEM "&Invert Selection\tGrey *", IDM_INVERT_SELECTION + MENUITEM "Select...\tGrey +", IDM_SELECT + MENUITEM "Deselect...\tGrey -", IDM_DESELECT + MENUITEM "Select by Type\tAlt+[Grey+]", IDM_SELECT_BY_TYPE + MENUITEM "Deselect by Type\tAlt+[Grey -]", IDM_DESELECT_BY_TYPE + END + POPUP "&View" + BEGIN + MENUITEM "Lar&ge Icons\tCtrl+1", IDM_VIEW_LARGE_ICONS + MENUITEM "S&mall Icons\tCtrl+2", IDM_VIEW_SMALL_ICONS + MENUITEM "&List\tCtrl+3", IDM_VIEW_LIST + MENUITEM "&Details\tCtrl+4", IDM_VIEW_DETAILS, CHECKED + MENUITEM SEPARATOR + MENUITEM "Name\tCtrl+F3", IDM_VIEW_ARANGE_BY_NAME + MENUITEM "Type\tCtrl+F4", IDM_VIEW_ARANGE_BY_TYPE + MENUITEM "Date\tCtrl+F5", IDM_VIEW_ARANGE_BY_DATE + MENUITEM "Size\tCtrl+F6", IDM_VIEW_ARANGE_BY_SIZE + MENUITEM "Unsorted\tCtrl+F7", IDM_VIEW_ARANGE_NO_SORT + MENUITEM SEPARATOR + MENUITEM "Flat View", IDM_VIEW_FLAT_VIEW + MENUITEM "&2 Panels\tF9", IDM_VIEW_TWO_PANELS + POPUP "Toolbars" + BEGIN + MENUITEM "Archive Toolbar", IDM_VIEW_ARCHIVE_TOOLBAR + MENUITEM "Standard Toolbar", IDM_VIEW_STANDARD_TOOLBAR + MENUITEM SEPARATOR + MENUITEM "Large Buttons", IDM_VIEW_TOOLBARS_LARGE_BUTTONS + MENUITEM "Show Buttons Text", IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT + END + MENUITEM SEPARATOR + MENUITEM "Open Root Folder\t\\", IDM_OPEN_ROOT_FOLDER + MENUITEM "Up One Level\tBackspace", IDM_OPEN_PARENT_FOLDER + MENUITEM "Folders History...\tAlt+F12", IDM_FOLDERS_HISTORY + MENUITEM SEPARATOR + MENUITEM "&Refresh\tCtrl+R", IDM_VIEW_REFRESH + END + POPUP "F&avorites" + BEGIN + POPUP "&Add folder to Favorites as" + BEGIN + MENUITEM SEPARATOR + END + MENUITEM SEPARATOR + END + POPUP "&Tools" + BEGIN + MENUITEM "&Options...", IDM_OPTIONS + MENUITEM "&Benchmark", IDM_BENCHMARK + END + POPUP "&Help" + BEGIN + MENUITEM "&Contents...\tF1", IDM_HELP_CONTENTS + MENUITEM SEPARATOR + MENUITEM "&About 7-Zip...", IDM_ABOUT + END +END + + +IDI_FM ICON "FM.ico" + +1 24 MOVEABLE PURE "7zFM.exe.manifest" + +IDB_ADD BITMAP "Add.bmp" +IDB_EXTRACT BITMAP "Extract.bmp" +IDB_TEST BITMAP "Test.bmp" +IDB_COPY BITMAP "Copy.bmp" +IDB_MOVE BITMAP "Move.bmp" +IDB_DELETE BITMAP "Delete.bmp" +IDB_INFO BITMAP "Info.bmp" +IDB_ADD2 BITMAP "Add2.bmp" +IDB_EXTRACT2 BITMAP "Extract2.bmp" +IDB_TEST2 BITMAP "Test2.bmp" +IDB_COPY2 BITMAP "Copy2.bmp" +IDB_MOVE2 BITMAP "Move2.bmp" +IDB_DELETE2 BITMAP "Delete2.bmp" +IDB_INFO2 BITMAP "Info2.bmp" + + +STRINGTABLE +BEGIN + IDS_APP_TITLE "7-Zip File Manager" + IDS_COPY "Copy" + IDS_MOVE "Move" + IDS_COPY_TO "Copy to:" + IDS_MOVE_TO "Move to:" + IDS_COPYING "Copying..." + IDS_MOVING "Moving..." + IDS_CANNOT_COPY "You cannot move or copy items for such folders." + IDS_SPLITTING "Splitting..." + IDS_SPLIT_CONFIRM_TITLE "Confirm Splitting" + IDS_SPLIT_CONFIRM_MESSAGE "Are you sure you want to split file into {0} volumes?" + IDS_SPLIT_VOL_MUST_BE_SMALLER "Volume size must be smaller than size of original file" + + IDS_COMBINE "Combine Files" + IDS_COMBINE_TO "&Combine to:" + IDS_COMBINING "Combining..." + IDS_COMBINE_SELECT_ONE_FILE "Select only first file" + + IDS_CHECKSUM_CALCULATING "Checksum calculating..." + IDS_CHECKSUM_INFORMATION "Checksum information" + IDS_CHECKSUM_CRC_DATA "CRC checksum for data:" + IDS_CHECKSUM_CRC_DATA_NAMES "CRC checksum for data and names:" + + IDS_SCANNING "Scanning..." + + IDS_OPERATION_IS_NOT_SUPPORTED "Operation is not supported." + + IDS_CONFIRM_FILE_DELETE "Confirm File Delete" + IDS_CONFIRM_FOLDER_DELETE "Confirm Folder Delete" + IDS_CONFIRM_ITEMS_DELETE "Confirm Multiple File Delete" + IDS_WANT_TO_DELETE_FILE "Are you sure you want to delete '{0}'?" + IDS_WANT_TO_DELETE_FOLDER "Are you sure you want to delete the folder '{0}' and all its contents?" + IDS_WANT_TO_DELETE_ITEMS "Are you sure you want to delete these {0} items?" + IDS_DELETING "Deleting..." + IDS_ERROR_DELETING "Error Deleting File or Folder" + IDS_RENAMING "Renaming..." + IDS_ERROR_RENAMING "Error Renaming File or Folder" + IDS_CONFIRM_FILE_COPY "Confirm File Copy" + IDS_WANT_TO_COPY_FILES "Are you sure you want to copy files to archive" + + IDS_CREATE_FOLDER "Create Folder" + IDS_CREATE_FOLDER_NAME "Folder name:" + IDS_CREATE_FOLDER_DEFAULT_NAME "New Folder" + IDS_CREATE_FOLDER_ERROR "Error Creating Folder" + IDS_CREATE_FILE "Create File" + IDS_CREATE_FILE_NAME "File Name:" + IDS_CREATE_FILE_DEFAULT_NAME "New File" + IDS_CREATE_FILE_ERROR "Error Creating File" + IDS_SELECT "Select" + IDS_DESELECT "Deselect" + IDS_SELECT_MASK "Mask:" + IDS_FOLDERS_HISTORY "Folders History" + IDS_N_SELECTED_ITEMS "{0} object(s) selected" + IDS_FILES_COLON "Files:" + IDS_FOLDERS_COLON "Folders:" + IDS_SIZE_COLON "Size:" + + IDS_PROPERTY_TOTAL_SIZE "Total Size" + IDS_PROPERTY_FREE_SPACE "Free Space" + IDS_PROPERTY_CLUSTER_SIZE "Cluster Size" + IDS_PROPERTY_VOLUME_NAME "Label" + IDS_PROPERTY_LOCAL_NAME "Local Name" + IDS_PROPERTY_PROVIDER "Provider" + IDS_OPTIONS "Options" + IDS_COMMENT "Comment" + IDS_COMMENT2 "&Comment:" + IDS_SYSTEM "System" + IDS_TOO_MANY_ITEMS "Too many items" + IDS_WANT_UPDATE_MODIFIED_FILE "File '{0}' was modified.\nDo you want to update it in the archive?" + IDS_CANNOT_UPDATE_FILE "Can not update file\n'{0}'" + IDS_CANNOT_START_EDITOR "Cannot start editor." + IDS_OPENNING "Opening..." + IDS_ADD "Add" + IDS_EXTRACT "Extract" + IDS_TEST "Test" + IDS_BUTTON_COPY "Copy" + IDS_BUTTON_MOVE "Move" + IDS_BUTTON_DELETE "Delete" + IDS_BUTTON_INFO "Info" + IDS_BOOKMARK "Bookmark" + IDS_COMPUTER "Computer" + IDS_NETWORK "Network" +END + + +#include "Resource/ComboDialog/resource.rc" +#include "Resource/CopyDialog/resource.rc" +#include "Resource/ListViewDialog/resource.rc" +#include "Resource/PropertyName/resource.rc" +#include "Resource/MessagesDialog/resource.rc" +#include "Resource/OverwriteDialog/resource.rc" +#include "Resource/PasswordDialog/resource.rc" +#include "Resource/SplitDialog/resource.rc" +#include "Resource/ProgressDialog2/resource.rc" +#include "Resource/BenchmarkDialog/resource.rc" +#include "Resource/AboutDialog/resource.rc" +#include "Resource/LangPage/resource.rc" +#include "Resource/PluginsPage/resource.rc" +#include "Resource/SystemPage/resource.rc" +#include "Resource/EditPage/resource.rc" +#include "Resource/SettingsPage/resource.rc" +#include "../UI/Resource/Extract/resource.rc" diff --git a/CPP/7zip/GuiCommon.rc b/CPP/7zip/GuiCommon.rc new file mode 100755 index 00000000..66dc5ca6 --- /dev/null +++ b/CPP/7zip/GuiCommon.rc @@ -0,0 +1,37 @@ +#include +#include +#include + +#define marg 7 +#undef bXSize +#undef bYSize +#define bXSize 64 +#define bYSize 14 +#define bDotsSize 20 + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +#undef xSize2 +#undef ySize2 +#undef xSize +#undef ySize +#undef bXPos +#undef bYPos +#undef b1XPos +#undef b1YPos +#undef b2XPos +#undef b2YPos +#undef b3XPos +#undef b3YPos +#undef gPos +#undef gPos2 +#undef gSpace +#undef gSize +#undef marg2 +#undef marg3 + + +#define MY_MODAL_DIALOG_STYLE STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +#define MY_PAGE_STYLE STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION + +#define MY_FONT FONT 8, "MS Shell Dlg" diff --git a/CPP/7zip/Guid.txt b/CPP/7zip/Guid.txt new file mode 100755 index 00000000..8fa5a291 --- /dev/null +++ b/CPP/7zip/Guid.txt @@ -0,0 +1,157 @@ +{23170F69-40C1-278A-0000-} + +000000xx0000 IProgress.h + +05 IProgress + + +000300xx0000 IStream.h + +01 ISequentialInStream +02 ISequentialOutStream +03 IInStream +04 IOutStream +06 IStreamGetSize +07 IOutStreamFlush + + +000400xx0000 ICoder.h + +04 ICompressProgressInfo +05 ICompressCoder +18 ICompressCoder2 +20 ICompressSetCoderProperties +21 ICompressSetDecoderProperties // +22 ICompressSetDecoderProperties2 +23 ICompressWriteCoderProperties +24 ICompressGetInStreamProcessedSize +25 ICompressSetCoderMt +30 ICompressGetSubStreamSize +31 ICompressSetInStream +32 ICompressSetOutStream +33 ICompressSetInStreamSize +34 ICompressSetOutStreamSize +40 ICompressFilter +80 ICryptoProperties +90 ICryptoSetPassword +A0 ICryptoSetCRC + + +000500xx0000 IPassword.h + +10 ICryptoGetTextPassword +11 ICryptoGetTextPassword2 + + +000600xx0000 IArchive.h + +03 ISetProperties + +10 IArchiveOpenCallback +20 IArchiveExtractCallback +30 IArchiveOpenVolumeCallback +40 IInArchiveGetStream +50 IArchiveOpenSetSubArchiveName +60 IInArchive + +80 IArchiveUpdateCallback +82 IArchiveUpdateCallback2 +A0 IOutArchive + + +000100050001 Agent.h::IArchiveFolderInternal + + +000100xx0000 IFolderArchive.h + +05 IArchiveFolder +06 IInFolderArchive +07 IFileExtractCallback.h::IFolderArchiveExtractCallback +0A IOutFolderArchive +0B IFolderArchiveUpdateCallback + + + + +000800xxyy00 FolderInterface.h:: + +00 IFolderFolder +01 IEnumProperties +02 IFolderGetTypeID +03 IFolderGetPath +04 IFolderWasChanged +05 IFolderReload // +0504 IFolderChangeNotify +0505 IFolderSetChangeNotify +050A IFolderExtract // +06 IFolderOperations +0601 IFolderOperationsExtractCallback +0602 IFolderOperationsUpdateCallback // +0603 IFolderOperationsDeleteToRecycleBin // +07 IFolderGetSystemIconIndex +08 IFolderGetItemFullSize +09 IFolderClone +0A IFolderSetFlatMode + +000900000000} FolderInterface.h::IFolderManager +000900010000} FolderInterface.h::IFolderManagerGetIconPath + + +{23170F69-40C1-278D-0000-000100010000} PluginInterface::IInitContextMenu +{23170F69-40C1-278D-0000-000100020100} PluginInterface::IPluginOptionsCallback +{23170F69-40C1-278D-0000-000100020000} PluginInterface::IPluginOptions + + +Handler GUIDs: + +{23170F69-40C1-278A-1000-000110xx0000} + +01 Zip +02 BZip2 +03 Rar +04 Arj +05 Z +06 Lzh +07 7z +08 Cab +09 Nsis +0A Lzma + +E7 Iso +E8 Bkf +E9 Chm +EA Split +EB Rpm +EC Deb +ED Cpio +EE Tar +EF GZip + +{23170F69-40C1-278A-1000-000100030000} CAgentArchiveHandle +{23170F69-40C1-278A-1000-000100020000} ContextMenu.h::CZipContextMenu + +{23170F69-40C1-278B- + +0000-000000000000} Copy +0203-020000000000} Swap2 +0203-040000000000} Swap4 +0301-01000000ee00} LZMA +0303-xxdd0000ee00} Branch +0304-01000000ee00} PPMD +0401-01000000ee00} Shrink +0401-06000000ee00} Implode +0401-08000000ee00} Deflate +0401-09000000ee00} Deflate64 +0402-02000000ee00} Bzip2 +0402-050000000000} Z +0403-010000000000} Rar15 +0403-020000000000} Rar20 +0403-030000000000} Rar29 +0601-01000000ee00} AES128_CBC +0601-81000000ee00} AES256_CBC +06F1-070100000000} 7zAES + + + +{23170F69-40C1-278D-1000-000100020000} OptionsDialog.h::CLSID_CSevenZipOptions + diff --git a/CPP/7zip/ICoder.h b/CPP/7zip/ICoder.h new file mode 100755 index 00000000..d84575dc --- /dev/null +++ b/CPP/7zip/ICoder.h @@ -0,0 +1,163 @@ +// ICoder.h + +#ifndef __ICODER_H +#define __ICODER_H + +#include "IStream.h" + +// "23170F69-40C1-278A-0000-000400xx0000" +#define CODER_INTERFACE(i, x) \ +DEFINE_GUID(IID_ ## i, \ +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x04, 0x00, x, 0x00, 0x00); \ +struct i: public IUnknown + +CODER_INTERFACE(ICompressProgressInfo, 0x04) +{ + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) PURE; +}; + +CODER_INTERFACE(ICompressCoder, 0x05) +{ + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *inSize, + const UInt64 *outSize, + ICompressProgressInfo *progress) PURE; +}; + +CODER_INTERFACE(ICompressCoder2, 0x18) +{ + STDMETHOD(Code)(ISequentialInStream **inStreams, + const UInt64 **inSizes, + UInt32 numInStreams, + ISequentialOutStream **outStreams, + const UInt64 **outSizes, + UInt32 numOutStreams, + ICompressProgressInfo *progress) PURE; +}; + +namespace NCoderPropID +{ + enum EEnum + { + kDictionarySize = 0x400, + kUsedMemorySize, + kOrder, + kPosStateBits = 0x440, + kLitContextBits, + kLitPosBits, + kNumFastBytes = 0x450, + kMatchFinder, + kMatchFinderCycles, + kNumPasses = 0x460, + kAlgorithm = 0x470, + kMultiThread = 0x480, + kNumThreads, + kEndMarker = 0x490 + }; +} + +CODER_INTERFACE(ICompressSetCoderProperties, 0x20) +{ + STDMETHOD(SetCoderProperties)(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties) PURE; +}; + +/* +CODER_INTERFACE(ICompressSetCoderProperties, 0x21) +{ + STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE; +}; +*/ + +CODER_INTERFACE(ICompressSetDecoderProperties2, 0x22) +{ + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size) PURE; +}; + +CODER_INTERFACE(ICompressWriteCoderProperties, 0x23) +{ + STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStreams) PURE; +}; + +CODER_INTERFACE(ICompressGetInStreamProcessedSize, 0x24) +{ + STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE; +}; + +CODER_INTERFACE(ICompressSetCoderMt, 0x25) +{ + STDMETHOD(SetNumberOfThreads)(UInt32 numThreads) PURE; +}; + +CODER_INTERFACE(ICompressGetSubStreamSize, 0x30) +{ + STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value) PURE; +}; + +CODER_INTERFACE(ICompressSetInStream, 0x31) +{ + STDMETHOD(SetInStream)(ISequentialInStream *inStream) PURE; + STDMETHOD(ReleaseInStream)() PURE; +}; + +CODER_INTERFACE(ICompressSetOutStream, 0x32) +{ + STDMETHOD(SetOutStream)(ISequentialOutStream *outStream) PURE; + STDMETHOD(ReleaseOutStream)() PURE; +}; + +CODER_INTERFACE(ICompressSetInStreamSize, 0x33) +{ + STDMETHOD(SetInStreamSize)(const UInt64 *inSize) PURE; +}; + +CODER_INTERFACE(ICompressSetOutStreamSize, 0x34) +{ + STDMETHOD(SetOutStreamSize)(const UInt64 *outSize) PURE; +}; + +CODER_INTERFACE(ICompressFilter, 0x40) +{ + STDMETHOD(Init)() PURE; + STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) PURE; + // Filter return outSize (UInt32) + // if (outSize <= size): Filter have converted outSize bytes + // if (outSize > size): Filter have not converted anything. + // and it needs at least outSize bytes to convert one block + // (it's for crypto block algorithms). +}; + +CODER_INTERFACE(ICryptoProperties, 0x80) +{ + STDMETHOD(SetKey)(const Byte *data, UInt32 size) PURE; + STDMETHOD(SetInitVector)(const Byte *data, UInt32 size) PURE; +}; + +CODER_INTERFACE(ICryptoSetPassword, 0x90) +{ + STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size) PURE; +}; + +CODER_INTERFACE(ICryptoSetCRC, 0xA0) +{ + STDMETHOD(CryptoSetCRC)(UInt32 crc) PURE; +}; + +////////////////////// +// It's for DLL file +namespace NMethodPropID +{ + enum EEnum + { + kID, + kName, + kDecoder, + kEncoder, + kInStreams, + kOutStreams, + kDescription + }; +} + +#endif diff --git a/CPP/7zip/IPassword.h b/CPP/7zip/IPassword.h new file mode 100755 index 00000000..8f2adcca --- /dev/null +++ b/CPP/7zip/IPassword.h @@ -0,0 +1,26 @@ +// IPassword.h + +#ifndef __IPASSWORD_H +#define __IPASSWORD_H + +#include "../Common/MyUnknown.h" +#include "../Common/Types.h" + +// MIDL_INTERFACE("23170F69-40C1-278A-0000-000500xx0000") +#define PASSWORD_INTERFACE(i, x) \ +DEFINE_GUID(IID_ ## i, \ +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x05, 0x00, x, 0x00, 0x00); \ +struct i: public IUnknown + +PASSWORD_INTERFACE(ICryptoGetTextPassword, 0x10) +{ + STDMETHOD(CryptoGetTextPassword)(BSTR *password) PURE; +}; + +PASSWORD_INTERFACE(ICryptoGetTextPassword2, 0x11) +{ + STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password) PURE; +}; + +#endif + diff --git a/CPP/7zip/IProgress.h b/CPP/7zip/IProgress.h new file mode 100755 index 00000000..aa3b64cc --- /dev/null +++ b/CPP/7zip/IProgress.h @@ -0,0 +1,32 @@ +// Interface/IProgress.h + +#ifndef __IPROGRESS_H +#define __IPROGRESS_H + +#include "../Common/MyUnknown.h" +#include "../Common/Types.h" + +// {23170F69-40C1-278A-0000-000000050000} +DEFINE_GUID(IID_IProgress, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000000050000") +IProgress: public IUnknown +{ + STDMETHOD(SetTotal)(UInt64 total) PURE; + STDMETHOD(SetCompleted)(const UInt64 *completeValue) PURE; +}; + +/* +// {23170F69-40C1-278A-0000-000000050002} +DEFINE_GUID(IID_IProgress2, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000000050002") +IProgress2: public IUnknown +{ +public: + STDMETHOD(SetTotal)(const UInt64 *total) PURE; + STDMETHOD(SetCompleted)(const UInt64 *completeValue) PURE; +}; +*/ + +#endif diff --git a/CPP/7zip/IStream.h b/CPP/7zip/IStream.h new file mode 100755 index 00000000..bba21a31 --- /dev/null +++ b/CPP/7zip/IStream.h @@ -0,0 +1,62 @@ +// IStream.h + +#ifndef __ISTREAM_H +#define __ISTREAM_H + +#include "../Common/MyUnknown.h" +#include "../Common/Types.h" + +// "23170F69-40C1-278A-0000-000300xx0000" + +#define STREAM_INTERFACE_SUB(i, b, x) \ +DEFINE_GUID(IID_ ## i, \ +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x03, 0x00, x, 0x00, 0x00); \ +struct i: public b + +#define STREAM_INTERFACE(i, x) STREAM_INTERFACE_SUB(i, IUnknown, x) + +STREAM_INTERFACE(ISequentialInStream, 0x01) +{ + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE; + /* + Out: if size != 0, return_value = S_OK and (*processedSize == 0), + then there are no more bytes in stream. + if (size > 0) && there are bytes in stream, + this function must read at least 1 byte. + This function is allowed to read less than number of remaining bytes in stream. + You must call Read function in loop, if you need exact amount of data + */ +}; + +STREAM_INTERFACE(ISequentialOutStream, 0x02) +{ + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) PURE; + /* + if (size > 0) this function must write at least 1 byte. + This function is allowed to write less than "size". + You must call Write function in loop, if you need to write exact amount of data + */ +}; + +STREAM_INTERFACE_SUB(IInStream, ISequentialInStream, 0x03) +{ + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE; +}; + +STREAM_INTERFACE_SUB(IOutStream, ISequentialOutStream, 0x04) +{ + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE; + STDMETHOD(SetSize)(Int64 newSize) PURE; +}; + +STREAM_INTERFACE(IStreamGetSize, 0x06) +{ + STDMETHOD(GetSize)(UInt64 *size) PURE; +}; + +STREAM_INTERFACE(IOutStreamFlush, 0x07) +{ + STDMETHOD(Flush)() PURE; +}; + +#endif diff --git a/CPP/7zip/MyVersion.h b/CPP/7zip/MyVersion.h new file mode 100755 index 00000000..7243563c --- /dev/null +++ b/CPP/7zip/MyVersion.h @@ -0,0 +1,8 @@ +#define MY_VER_MAJOR 4 +#define MY_VER_MINOR 44 +#define MY_VER_BUILD 3 +#define MY_VERSION "4.44 beta" +#define MY_7ZIP_VERSION "7-Zip 4.44 beta" +#define MY_DATE "2007-01-20" +#define MY_COPYRIGHT "Copyright (c) 1999-2007 Igor Pavlov" +#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE diff --git a/CPP/7zip/MyVersionInfo.rc b/CPP/7zip/MyVersionInfo.rc new file mode 100755 index 00000000..fd52d6aa --- /dev/null +++ b/CPP/7zip/MyVersionInfo.rc @@ -0,0 +1,41 @@ +#include +#include "MyVersion.h" + +#define MY_VER MY_VER_MAJOR,MY_VER_MINOR,MY_VER_BUILD,0 + +#ifdef DEBUG +#define DBG_FL VS_FF_DEBUG +#else +#define DBG_FL 0 +#endif + +#define MY_VERSION_INFO(fileType, descr, intName, origName) \ +LANGUAGE 9, 1 \ +1 VERSIONINFO \ + FILEVERSION MY_VER \ + PRODUCTVERSION MY_VER \ + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK \ + FILEFLAGS DBG_FL \ + FILEOS VOS_NT_WINDOWS32 \ + FILETYPE fileType \ + FILESUBTYPE 0x0L \ +BEGIN \ + BLOCK "StringFileInfo" \ + BEGIN \ + BLOCK "040904b0" \ + BEGIN \ + VALUE "CompanyName", "Igor Pavlov" \ + VALUE "FileDescription", descr \ + VALUE "FileVersion", MY_VERSION \ + VALUE "InternalName", intName \ + VALUE "LegalCopyright", MY_COPYRIGHT \ + VALUE "OriginalFilename", origName \ + VALUE "ProductName", "7-Zip" \ + VALUE "ProductVersion", MY_VERSION \ + END \ + END \ +END + +#define MY_VERSION_INFO_APP(descr, intName) MY_VERSION_INFO(VFT_APP, descr, intName, intName ".exe") + +#define MY_VERSION_INFO_DLL(descr, intName) MY_VERSION_INFO(VFT_DLL, descr, intName, intName ".dll") diff --git a/CPP/7zip/PropID.h b/CPP/7zip/PropID.h new file mode 100755 index 00000000..79f82452 --- /dev/null +++ b/CPP/7zip/PropID.h @@ -0,0 +1,51 @@ +// Interface/PropID.h + +#ifndef __INTERFACE_PROPID_H +#define __INTERFACE_PROPID_H + +enum +{ + kpidNoProperty = 0, + + kpidHandlerItemIndex = 2, + kpidPath, + kpidName, + kpidExtension, + kpidIsFolder, + kpidSize, + kpidPackedSize, + kpidAttributes, + kpidCreationTime, + kpidLastAccessTime, + kpidLastWriteTime, + kpidSolid, + kpidCommented, + kpidEncrypted, + kpidSplitBefore, + kpidSplitAfter, + kpidDictionarySize, + kpidCRC, + kpidType, + kpidIsAnti, + kpidMethod, + kpidHostOS, + kpidFileSystem, + kpidUser, + kpidGroup, + kpidBlock, + kpidComment, + kpidPosition, + kpidPrefix, + + kpidTotalSize = 0x1100, + kpidFreeSpace, + kpidClusterSize, + kpidVolumeName, + + kpidLocalName = 0x1200, + kpidProvider, + + kpidUserDefined = 0x10000 +}; + +#endif diff --git a/CPP/7zip/SubBuild.mak b/CPP/7zip/SubBuild.mak new file mode 100755 index 00000000..f86ce436 --- /dev/null +++ b/CPP/7zip/SubBuild.mak @@ -0,0 +1,3 @@ + cd $(@D) + $(MAKE) -nologo $(TARGETS) + cd .. diff --git a/CPP/7zip/UI/Agent/Agent.cpp b/CPP/7zip/UI/Agent/Agent.cpp new file mode 100755 index 00000000..f983e2f9 --- /dev/null +++ b/CPP/7zip/UI/Agent/Agent.cpp @@ -0,0 +1,578 @@ +// Agent.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Common/ComTry.h" +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" +#include "Windows/FileFind.h" + +#include "../Common/DefaultName.h" +#include "../Common/ArchiveExtractCallback.h" + +#include "Agent.h" + +#ifdef FORMAT_7Z +#include "../../Archive/7z/7zHandler.h" +#endif + +extern "C" +{ + #include "../../../../C/Sort.h" +} + + +using namespace NWindows; + +STDMETHODIMP CAgentFolder::GetAgentFolder(CAgentFolder **agentFolder) +{ + *agentFolder = this; + return S_OK; +} + +void CAgentFolder::LoadFolder(CProxyFolder *folder) +{ + int i; + CProxyItem item; + item.Folder = folder; + for (i = 0; i < folder->Folders.Size(); i++) + { + item.Index = i; + _items.Add(item); + LoadFolder(&folder->Folders[i]); + } + int start = folder->Folders.Size(); + for (i = 0; i < folder->Files.Size(); i++) + { + item.Index = start + i; + _items.Add(item); + } +} + + +STDMETHODIMP CAgentFolder::LoadItems() +{ + _items.Clear(); + if (_flatMode) + LoadFolder(_proxyFolderItem); + return S_OK; +} + +STDMETHODIMP CAgentFolder::GetNumberOfItems(UINT32 *numItems) +{ + if (_flatMode) + *numItems = _items.Size(); + else + *numItems = _proxyFolderItem->Folders.Size() +_proxyFolderItem->Files.Size(); + return S_OK; +} + +/* +STDMETHODIMP CAgentFolder::GetNumberOfSubFolders(UINT32 *aNumSubFolders) +{ + *aNumSubFolders = _proxyFolderItem->Folders.Size(); + return S_OK; +} +*/ + +UString CAgentFolder::GetName(UInt32 index) const +{ + UInt32 realIndex; + const CProxyFolder *folder; + if (_flatMode) + { + const CProxyItem &item = _items[index]; + folder = item.Folder; + realIndex = item.Index; + } + else + { + folder = _proxyFolderItem; + realIndex = index; + } + + if (realIndex < (UINT32)folder->Folders.Size()) + return folder->Folders[realIndex].Name; + return folder->Files[realIndex - folder->Folders.Size()].Name; +} + +UString CAgentFolder::GetPrefix(UInt32 index) const +{ + if (!_flatMode) + return UString(); + const CProxyItem &item = _items[index]; + const CProxyFolder *folder = item.Folder; + UString path; + while(folder != _proxyFolderItem) + { + path = folder->Name + UString(L"\\") + path; + folder = folder->Parent; + } + return path; +} + +UString CAgentFolder::GetFullPathPrefixPlusPrefix(UInt32 index) const +{ + return _proxyFolderItem->GetFullPathPrefix() + GetPrefix(index); +} + +void CAgentFolder::GetPrefixIfAny(UInt32 index, NCOM::CPropVariant &propVariant) const +{ + if (!_flatMode) + return; + propVariant = GetPrefix(index); +} + + +STDMETHODIMP CAgentFolder::GetProperty(UINT32 itemIndex, PROPID propID, PROPVARIANT *value) +{ + NCOM::CPropVariant propVariant; + const CProxyFolder *folder; + UInt32 realIndex; + if (_flatMode) + { + const CProxyItem &item = _items[itemIndex]; + folder = item.Folder; + realIndex = item.Index; + } + else + { + folder = _proxyFolderItem; + realIndex = itemIndex; + } + + if (realIndex < (UINT32)folder->Folders.Size()) + { + const CProxyFolder &item = folder->Folders[realIndex]; + switch(propID) + { + case kpidIsFolder: + propVariant = true; + break; + case kpidName: + propVariant = item.Name; + break; + case kpidPrefix: + GetPrefixIfAny(itemIndex, propVariant); + break; + default: + if (item.IsLeaf) + return _agentSpec->GetArchive()->GetProperty(item.Index, propID, value); + } + } + else + { + realIndex -= folder->Folders.Size(); + const CProxyFile &item = folder->Files[realIndex]; + switch(propID) + { + case kpidIsFolder: + propVariant = false; + break; + case kpidName: + propVariant = item.Name; + break; + case kpidPrefix: + GetPrefixIfAny(itemIndex, propVariant); + break; + default: + return _agentSpec->GetArchive()->GetProperty(item.Index, propID, value); + } + } + propVariant.Detach(value); + return S_OK; +} + +HRESULT CAgentFolder::BindToFolder(CProxyFolder *folder, IFolderFolder **resultFolder) +{ + CMyComPtr parentFolder; + if (folder->Parent != _proxyFolderItem) + { + RINOK(BindToFolder(folder->Parent, &parentFolder)); + } + else + parentFolder = this; + CAgentFolder *folderSpec = new CAgentFolder; + CMyComPtr agentFolder = folderSpec; + folderSpec->Init(_proxyArchive, folder, parentFolder, _agentSpec); + *resultFolder = agentFolder.Detach(); + return S_OK; +} + +STDMETHODIMP CAgentFolder::BindToFolder(UINT32 index, IFolderFolder **resultFolder) +{ + COM_TRY_BEGIN + + CProxyFolder *folder; + UInt32 realIndex; + if (_flatMode) + { + const CProxyItem &item = _items[index]; + folder = item.Folder; + realIndex = item.Index; + } + else + { + folder = _proxyFolderItem; + realIndex = index; + } + if (realIndex >= (UINT32)folder->Folders.Size()) + return E_INVALIDARG; + return BindToFolder(&folder->Folders[realIndex], resultFolder); + COM_TRY_END +} + +STDMETHODIMP CAgentFolder::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder) +{ + COM_TRY_BEGIN + int index = _proxyFolderItem->FindDirSubItemIndex(name); + if (index < 0) + return E_INVALIDARG; + return BindToFolder(index, resultFolder); + COM_TRY_END +} + +STDMETHODIMP CAgentFolder::BindToParentFolder(IFolderFolder **resultFolder) +{ + COM_TRY_BEGIN + CMyComPtr parentFolder = _parentFolder; + *resultFolder = parentFolder.Detach(); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CAgentFolder::GetName(BSTR *name) +{ + CMyComBSTR temp = _proxyFolderItem->Name; + *name = temp.Detach(); + return S_OK; +} + + +#ifdef NEW_FOLDER_INTERFACE + +struct CArchiveItemPropertyTemp +{ + UString Name; + PROPID ID; + VARTYPE Type; +}; + +STDMETHODIMP CAgentFolder::GetNumberOfProperties(UINT32 *numProperties) +{ + COM_TRY_BEGIN + RINOK(_agentSpec->GetArchive()->GetNumberOfProperties(numProperties)); + if (_flatMode) + (*numProperties)++; + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CAgentFolder::GetPropertyInfo(UINT32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + COM_TRY_BEGIN + UINT32 numProperties; + _agentSpec->GetArchive()->GetNumberOfProperties(&numProperties); + if (index < numProperties) + { + RINOK(_agentSpec->GetArchive()->GetPropertyInfo(index, name, propID, varType)); + if (*propID == kpidPath) + *propID = kpidName; + } + else + { + *name = NULL; + *propID = kpidPrefix; + *varType = VT_BSTR; + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CAgentFolder::GetTypeID(BSTR *name) +{ + COM_TRY_BEGIN + UString temp = UString(L"7-Zip.") + _agentSpec->ArchiveType; + CMyComBSTR bstrTemp = temp; + *name = bstrTemp.Detach(); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CAgentFolder::GetPath(BSTR *path) +{ + COM_TRY_BEGIN + UStringVector pathParts; + pathParts.Clear(); + CMyComPtr currentFolder = this; + for (;;) + { + CMyComPtr newFolder; + currentFolder->BindToParentFolder(&newFolder); + if (newFolder == NULL) + break; + CMyComBSTR aName; + currentFolder->GetName(&aName); + pathParts.Insert(0, (const wchar_t *)aName); + currentFolder = newFolder; + } + + UString prefix; + for(int i = 0; i < pathParts.Size(); i++) + { + prefix += pathParts[i]; + prefix += L'\\'; + } + + CMyComBSTR tempPath = prefix; + *path = tempPath.Detach(); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CAgentFolder::SetFlatMode(Int32 flatMode) +{ + _flatMode = IntToBool(flatMode); + return S_OK; +} + +#endif + +void CAgentFolder::GetRealIndices(const UINT32 *indices, UINT32 numItems, CUIntVector &realIndices) const +{ + if (!_flatMode) + { + _proxyFolderItem->GetRealIndices(indices, numItems, realIndices); + return; + } + realIndices.Clear(); + for(UINT32 i = 0; i < numItems; i++) + { + const CProxyItem &item = _items[indices[i]]; + const CProxyFolder *folder = item.Folder; + UInt32 realIndex = item.Index; + if (realIndex < (UINT32)folder->Folders.Size()) + continue; + realIndices.Add(folder->Files[realIndex - folder->Folders.Size()].Index); + } + HeapSort(&realIndices.Front(), realIndices.Size()); +} + +STDMETHODIMP CAgentFolder::Extract(const UINT32 *indices, + UINT32 numItems, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, + const wchar_t *path, + INT32 testMode, + IFolderArchiveExtractCallback *extractCallback2) +{ + COM_TRY_BEGIN + CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback; + CMyComPtr extractCallback = extractCallbackSpec; + UStringVector pathParts; + CProxyFolder *currentProxyFolder = _proxyFolderItem; + while (currentProxyFolder->Parent) + { + pathParts.Insert(0, currentProxyFolder->Name); + currentProxyFolder = currentProxyFolder->Parent; + } + + /* + if (_flatMode) + pathMode = NExtract::NPathMode::kNoPathnames; + */ + + extractCallbackSpec->Init(_agentSpec->GetArchive(), + extractCallback2, + false, + path, + pathMode, + overwriteMode, + pathParts, + _agentSpec->DefaultName, + _agentSpec->DefaultTime, + _agentSpec->DefaultAttributes + // ,_agentSpec->_srcDirectoryPrefix + ); + CUIntVector realIndices; + GetRealIndices(indices, numItems, realIndices); + return _agentSpec->GetArchive()->Extract(&realIndices.Front(), + realIndices.Size(), testMode, extractCallback); + COM_TRY_END +} + +///////////////////////////////////////// +// CAgent + +CAgent::CAgent(): + _proxyArchive(NULL) +{ +} + +CAgent::~CAgent() +{ + if (_proxyArchive != NULL) + delete _proxyArchive; +} + +STDMETHODIMP CAgent::Open( + const wchar_t *filePath, + BSTR *archiveType, + // CLSID *clsIDResult, + IArchiveOpenCallback *openArchiveCallback) +{ + COM_TRY_BEGIN + _archiveFilePath = filePath; + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(_archiveFilePath, fileInfo)) + return ::GetLastError(); + if (fileInfo.IsDirectory()) + return E_FAIL; + CArchiverInfo archiverInfo0, archiverInfo1; + HRESULT res = OpenArchive(_archiveFilePath, _archiveLink, openArchiveCallback); + // _archive = _archiveLink.GetArchive(); + DefaultName = _archiveLink.GetDefaultItemName(); + const CArchiverInfo &ai = _archiveLink.GetArchiverInfo(); + + RINOK(res); + DefaultTime = fileInfo.LastWriteTime; + DefaultAttributes = fileInfo.Attributes; + ArchiveType = ai.Name; + if (archiveType != 0) + { + CMyComBSTR name = ArchiveType; + *archiveType = name.Detach(); + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CAgent::ReOpen( + // const wchar_t *filePath, + IArchiveOpenCallback * /* openArchiveCallback */) +{ + COM_TRY_BEGIN + if (_proxyArchive != NULL) + { + delete _proxyArchive; + _proxyArchive = NULL; + } + RINOK(ReOpenArchive(_archiveLink, _archiveFilePath)); + return ReadItems(); + COM_TRY_END +} + +STDMETHODIMP CAgent::Close() +{ + COM_TRY_BEGIN + RINOK(_archiveLink.Close()); + if (_archiveLink.GetNumLevels() > 1) + { + // return S_OK; + } + // _archive->Close(); + return S_OK; + COM_TRY_END +} + +/* +STDMETHODIMP CAgent::EnumProperties(IEnumSTATPROPSTG **EnumProperties) +{ + return _archive->EnumProperties(EnumProperties); +} +*/ + +HRESULT CAgent::ReadItems() +{ + if (_proxyArchive != NULL) + return S_OK; + _proxyArchive = new CProxyArchive(); + return _proxyArchive->Load(GetArchive(), + DefaultName, + // _defaultTime, + // _defaultAttributes, + NULL); +} + +STDMETHODIMP CAgent::BindToRootFolder(IFolderFolder **resultFolder) +{ + COM_TRY_BEGIN + RINOK(ReadItems()); + CAgentFolder *folderSpec = new CAgentFolder; + CMyComPtr rootFolder = folderSpec; + folderSpec->Init(_proxyArchive, &_proxyArchive->RootFolder, NULL, this); + *resultFolder = rootFolder.Detach(); + return S_OK; + COM_TRY_END +} + + +STDMETHODIMP CAgent::Extract( + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, + const wchar_t *path, + INT32 testMode, + IFolderArchiveExtractCallback *extractCallback2) +{ + COM_TRY_BEGIN + CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback; + CMyComPtr extractCallback = extractCallbackSpec; + extractCallbackSpec->Init(GetArchive(), + extractCallback2, + false, + path, + pathMode, + overwriteMode, + UStringVector(), + DefaultName, + DefaultTime, + DefaultAttributes + // ,_srcDirectoryPrefix + ); + return GetArchive()->Extract(0, (UInt32)(Int32)-1, testMode, extractCallback); + COM_TRY_END +} + +STDMETHODIMP CAgent::GetNumberOfProperties(UINT32 *numProperties) +{ + COM_TRY_BEGIN + return GetArchive()->GetNumberOfProperties(numProperties); + COM_TRY_END +} + +STDMETHODIMP CAgent::GetPropertyInfo(UINT32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + COM_TRY_BEGIN + RINOK(GetArchive()->GetPropertyInfo(index, name, propID, varType)); + if (*propID == kpidPath) + *propID = kpidName; + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CAgent::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + return GetArchive()->GetArchiveProperty(propID, value); + COM_TRY_END +} + +STDMETHODIMP CAgent::GetNumberOfArchiveProperties(UINT32 *numProperties) +{ + COM_TRY_BEGIN + return GetArchive()->GetNumberOfArchiveProperties(numProperties); + COM_TRY_END +} + +STDMETHODIMP CAgent::GetArchivePropertyInfo(UINT32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + COM_TRY_BEGIN + return GetArchive()->GetArchivePropertyInfo(index, + name, propID, varType); + COM_TRY_END +} + diff --git a/CPP/7zip/UI/Agent/Agent.h b/CPP/7zip/UI/Agent/Agent.h new file mode 100755 index 00000000..41f80266 --- /dev/null +++ b/CPP/7zip/UI/Agent/Agent.h @@ -0,0 +1,314 @@ +// Agent/Agent.h + +#ifndef __AGENT_AGENT_H +#define __AGENT_AGENT_H + +#include "Common/MyCom.h" +#include "Windows/PropVariant.h" + +#include "../Common/UpdateAction.h" +#include "../Common/ArchiverInfo.h" +#include "../Common/OpenArchive.h" + +#include "IFolderArchive.h" +#include "AgentProxy.h" + +#ifndef EXCLUDE_COM +#include "Windows/DLL.h" +#endif +#ifdef NEW_FOLDER_INTERFACE +#include "../../FileManager/IFolder.h" +#endif + +class CAgentFolder; + +// {23170F69-40C1-278A-0000-000100050001} +DEFINE_GUID(IID_IArchiveFolderInternal, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000100050001") +IArchiveFolderInternal: public IUnknown +{ +public: + STDMETHOD(GetAgentFolder)(CAgentFolder **agentFolder) PURE; +}; + +struct CProxyItem +{ + CProxyFolder *Folder; + UInt32 Index; +}; + +class CAgent; + +class CAgentFolder: + public IFolderFolder, + public IArchiveFolder, + public IArchiveFolderInternal, +#ifdef NEW_FOLDER_INTERFACE + public IEnumProperties, + public IFolderGetTypeID, + public IFolderGetPath, + public IFolderOperations, + public IFolderSetFlatMode, +#endif + public CMyUnknownImp +{ +public: + + MY_QUERYINTERFACE_BEGIN + MY_QUERYINTERFACE_ENTRY(IFolderFolder) + MY_QUERYINTERFACE_ENTRY(IArchiveFolder) + MY_QUERYINTERFACE_ENTRY(IArchiveFolderInternal) + #ifdef NEW_FOLDER_INTERFACE + MY_QUERYINTERFACE_ENTRY(IEnumProperties) + MY_QUERYINTERFACE_ENTRY(IFolderGetTypeID) + MY_QUERYINTERFACE_ENTRY(IFolderGetPath) + MY_QUERYINTERFACE_ENTRY(IFolderOperations) + MY_QUERYINTERFACE_ENTRY(IFolderSetFlatMode) + #endif + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + + // IFolderFolder + + void LoadFolder(CProxyFolder *folder); + HRESULT BindToFolder(CProxyFolder *folder, IFolderFolder **resultFolder); + void GetRealIndices(const UINT32 *indices, UINT32 numItems, CUIntVector &realIndices) const; + + STDMETHOD(LoadItems)(); + STDMETHOD(GetNumberOfItems)(UINT32 *numItems); + STDMETHOD(GetProperty)(UINT32 itemIndex, PROPID propID, PROPVARIANT *value); + STDMETHOD(BindToFolder)(UINT32 index, IFolderFolder **resultFolder); + STDMETHOD(BindToFolder)(const wchar_t *name, IFolderFolder **resultFolder); + STDMETHOD(BindToParentFolder)(IFolderFolder **resultFolder); + STDMETHOD(GetName)(BSTR *name); + + // IArchiveFolder + STDMETHOD(Extract)(const UINT32 *indices, UINT32 numItems, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, + const wchar_t *path, + INT32 testMode, + IFolderArchiveExtractCallback *extractCallback); + + STDMETHOD(GetAgentFolder)(CAgentFolder **agentFolder); + + #ifdef NEW_FOLDER_INTERFACE + STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties); + STDMETHOD(GetPropertyInfo)(UINT32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + STDMETHOD(GetTypeID)(BSTR *name); + STDMETHOD(GetPath)(BSTR *path); + + + // IFolderOperations + STDMETHOD(CreateFolder)(const wchar_t *name, IProgress *progress); + STDMETHOD(CreateFile)(const wchar_t *name, IProgress *progress); + STDMETHOD(Rename)(UINT32 index, const wchar_t *newName, IProgress *progress); + STDMETHOD(Delete)(const UINT32 *indices, UINT32 numItems, IProgress *progress); + STDMETHOD(CopyTo)(const UINT32 *indices, UINT32 numItems, + const wchar_t *path, IFolderOperationsExtractCallback *callback); + STDMETHOD(MoveTo)(const UINT32 *indices, UINT32 numItems, + const wchar_t *path, IFolderOperationsExtractCallback *callback); + STDMETHOD(CopyFrom)(const wchar_t *fromFolderPath, + const wchar_t **itemsPaths, UINT32 numItems, IProgress *progress); + STDMETHOD(SetProperty)(UINT32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress); + + STDMETHOD(SetFlatMode)(Int32 flatMode); + #endif + + CAgentFolder(): _proxyFolderItem(NULL), _flatMode(0) {} + + void Init(CProxyArchive *proxyHandler, + CProxyFolder *proxyFolderItem, + IFolderFolder *parentFolder, + CAgent *agent) + { + _proxyArchive = proxyHandler; + _proxyFolderItem = proxyFolderItem; + _parentFolder = parentFolder; + _agent = (IInFolderArchive *)agent; + _agentSpec = agent; + } + + void GetPathParts(UStringVector &pathParts); + HRESULT CommonUpdateOperation( + bool deleteOperation, + bool createFolderOperation, + bool renameOperation, + const wchar_t *newItemName, + const NUpdateArchive::CActionSet *actionSet, + const UINT32 *indices, UINT32 numItems, + IFolderArchiveUpdateCallback *updateCallback100); + + + UString GetPrefix(UInt32 index) const; + UString GetName(UInt32 index) const; + UString GetFullPathPrefixPlusPrefix(UInt32 index) const; + void GetPrefixIfAny(UInt32 index, NWindows::NCOM::CPropVariant &propVariant) const; + +public: + CProxyArchive *_proxyArchive; + CProxyFolder *_proxyFolderItem; + CMyComPtr _parentFolder; + CMyComPtr _agent; + CAgent *_agentSpec; + + CRecordVector _items; + bool _flatMode; +private: +}; + +// {23170F69-40C1-278A-1000-000100030000} +DEFINE_GUID(CLSID_CAgentArchiveHandler, + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00); + +class CAgent: + public IInFolderArchive, + #ifndef EXTRACT_ONLY + public IOutFolderArchive, + public ISetProperties, + #endif + public CMyUnknownImp +{ +public: + + MY_QUERYINTERFACE_BEGIN + MY_QUERYINTERFACE_ENTRY(IInFolderArchive) + #ifndef EXTRACT_ONLY + MY_QUERYINTERFACE_ENTRY(IOutFolderArchive) + MY_QUERYINTERFACE_ENTRY(ISetProperties) + #endif + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + + STDMETHOD(Open)( + const wchar_t *filePath, + // CLSID *clsIDResult, + BSTR *archiveType, + IArchiveOpenCallback *openArchiveCallback); + + STDMETHOD(ReOpen)( + // const wchar_t *filePath, + IArchiveOpenCallback *openArchiveCallback); + /* + STDMETHOD(ReOpen)(IInStream *stream, + const wchar_t *defaultName, + const FILETIME *defaultTime, + UINT32 defaultAttributes, + const UINT64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback); + */ + STDMETHOD(Close)(); + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties); + STDMETHOD(GetPropertyInfo)(UINT32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UINT32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + STDMETHOD(BindToRootFolder)(IFolderFolder **resultFolder); + STDMETHOD(Extract)( + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, + const wchar_t *path, + INT32 testMode, + IFolderArchiveExtractCallback *extractCallback2); + + #ifndef EXTRACT_ONLY + STDMETHOD(SetFolder)(IFolderFolder *folder); + STDMETHOD(SetFiles)(const wchar_t *folderPrefix, const wchar_t **names, UINT32 numNames); + STDMETHOD(DeleteItems)(const wchar_t *newArchiveName, const UINT32 *indices, + UINT32 numItems, IFolderArchiveUpdateCallback *updateCallback); + STDMETHOD(DoOperation)( + const wchar_t *filePath, + const CLSID *clsID, + const wchar_t *newArchiveName, + const Byte *stateActions, + const wchar_t *sfxModule, + IFolderArchiveUpdateCallback *updateCallback); + + HRESULT CommonUpdate( + const wchar_t *newArchiveName, + int numUpdateItems, + IArchiveUpdateCallback *updateCallback); + + HRESULT CreateFolder( + const wchar_t *newArchiveName, + const wchar_t *folderName, + IFolderArchiveUpdateCallback *updateCallback100); + + HRESULT RenameItem( + const wchar_t *newArchiveName, + const UINT32 *indices, UINT32 numItems, + const wchar_t *newItemName, + IFolderArchiveUpdateCallback *updateCallback100); + + // ISetProperties + STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, INT32 numProperties); + #endif + + CAgent(); + ~CAgent(); +private: + HRESULT ReadItems(); +public: + CProxyArchive *_proxyArchive; + + CArchiveLink _archiveLink; + // IInArchive *_archive2; + + // CLSID _CLSID; + // CMyComPtr m_RootFolder; + + UString DefaultName; + + FILETIME DefaultTime; + UINT32 DefaultAttributes; + + UString ArchiveType; + + UStringVector _names; + UString _folderPrefix; + + UString _archiveNamePrefix; + CAgentFolder *_agentFolder; + + UString _archiveFilePath; + + #ifndef EXTRACT_ONLY + CObjectVector m_PropNames; + CObjectVector m_PropValues; + #endif + + IInArchive *GetArchive() { return _archiveLink.GetArchive(); } + bool CanUpdate() const { return _archiveLink.GetNumLevels() <= 1; } +}; + +#ifdef NEW_FOLDER_INTERFACE +class CArchiveFolderManager: + public IFolderManager, + public IFolderManagerGetIconPath, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP2( + IFolderManager, + IFolderManagerGetIconPath + ) + // IFolderManager + STDMETHOD(OpenFolderFile)(const wchar_t *filePath, IFolderFolder **resultFolder, IProgress *progress); + STDMETHOD(GetTypes)(BSTR *types); + STDMETHOD(GetExtension)(const wchar_t *type, BSTR *extension); + STDMETHOD(CreateFolderFile)(const wchar_t *type, const wchar_t *filePath, IProgress *progress); + STDMETHOD(GetIconPath)(const wchar_t *type, BSTR *iconPath); + CArchiveFolderManager(): _formatsLoaded(false) {} +private: + void LoadFormats(); + int FindFormat(const UString &type); + bool _formatsLoaded; + CObjectVector _formats; +}; +#endif + +#endif diff --git a/CPP/7zip/UI/Agent/AgentOut.cpp b/CPP/7zip/UI/Agent/AgentOut.cpp new file mode 100755 index 00000000..25d65bb2 --- /dev/null +++ b/CPP/7zip/UI/Agent/AgentOut.cpp @@ -0,0 +1,518 @@ +// AgentOut.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Common/IntToString.h" + +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" +#include "Windows/PropVariantConversions.h" +#include "Windows/FileDir.h" + +#include "../../Compress/Copy/CopyCoder.h" +#include "../../Common/FileStreams.h" + +#include "../Common/UpdatePair.h" +#include "../Common/EnumDirItems.h" +#include "../Common/HandlerLoader.h" +#include "../Common/UpdateCallback.h" +#include "../Common/OpenArchive.h" + +#include "Agent.h" +#include "UpdateCallbackAgent.h" + +using namespace NWindows; +using namespace NCOM; + +static HRESULT CopyBlock(ISequentialInStream *inStream, ISequentialOutStream *outStream) +{ + CMyComPtr copyCoder = new NCompress::CCopyCoder; + return copyCoder->Code(inStream, outStream, NULL, NULL, NULL); +} + +STDMETHODIMP CAgent::SetFolder(IFolderFolder *folder) +{ + _archiveNamePrefix.Empty(); + if (folder == NULL) + { + _agentFolder = NULL; + return S_OK; + } + else + { + CMyComPtr archiveFolder = folder; + CMyComPtr archiveFolderInternal; + RINOK(archiveFolder.QueryInterface(IID_IArchiveFolderInternal, &archiveFolderInternal)); + RINOK(archiveFolderInternal->GetAgentFolder(&_agentFolder)); + } + + UStringVector pathParts; + pathParts.Clear(); + CMyComPtr folderItem = folder; + if (folderItem != NULL) + for (;;) + { + CMyComPtr newFolder; + folderItem->BindToParentFolder(&newFolder); + if (newFolder == NULL) + break; + CMyComBSTR name; + folderItem->GetName(&name); + pathParts.Insert(0, (const wchar_t *)name); + folderItem = newFolder; + } + + for(int i = 0; i < pathParts.Size(); i++) + { + _archiveNamePrefix += pathParts[i]; + _archiveNamePrefix += L'\\'; + } + return S_OK; +} + +STDMETHODIMP CAgent::SetFiles(const wchar_t *folderPrefix, + const wchar_t **names, UINT32 numNames) +{ + _folderPrefix = folderPrefix; + _names.Clear(); + _names.Reserve(numNames); + for (UINT32 i = 0; i < numNames; i++) + _names.Add(names[i]); + return S_OK; +} + + +static HRESULT GetFileTime(CAgent *agent, UINT32 itemIndex, FILETIME &fileTime) +{ + CPropVariant property; + RINOK(agent->GetArchive()->GetProperty(itemIndex, kpidLastWriteTime, &property)); + if (property.vt == VT_FILETIME) + fileTime = property.filetime; + else if (property.vt == VT_EMPTY) + fileTime = agent->DefaultTime; + else + throw 4190407; + return S_OK; +} + +static HRESULT EnumerateArchiveItems(CAgent *agent, + const CProxyFolder &item, + const UString &prefix, + CObjectVector &archiveItems) +{ + int i; + for(i = 0; i < item.Files.Size(); i++) + { + const CProxyFile &fileItem = item.Files[i]; + CArchiveItem archiveItem; + + RINOK(::GetFileTime(agent, fileItem.Index, archiveItem.LastWriteTime)); + + CPropVariant property; + agent->GetArchive()->GetProperty(fileItem.Index, kpidSize, &property); + archiveItem.SizeIsDefined = (property.vt != VT_EMPTY); + if (archiveItem.SizeIsDefined) + archiveItem.Size = ConvertPropVariantToUInt64(property); + archiveItem.IsDirectory = false; + archiveItem.Name = prefix + fileItem.Name; + archiveItem.Censored = true; // test it + archiveItem.IndexInServer = fileItem.Index; + archiveItems.Add(archiveItem); + } + for(i = 0; i < item.Folders.Size(); i++) + { + const CProxyFolder &dirItem = item.Folders[i]; + UString fullName = prefix + dirItem.Name; + if(dirItem.IsLeaf) + { + CArchiveItem archiveItem; + RINOK(::GetFileTime(agent, dirItem.Index, archiveItem.LastWriteTime)); + archiveItem.IsDirectory = true; + archiveItem.SizeIsDefined = false; + archiveItem.Name = fullName; + archiveItem.Censored = true; // test it + archiveItem.IndexInServer = dirItem.Index; + archiveItems.Add(archiveItem); + } + RINOK(EnumerateArchiveItems(agent, dirItem, fullName + UString(L'\\'), archiveItems)); + } + return S_OK; +} + +STDMETHODIMP CAgent::DoOperation( + const wchar_t *filePath, + const CLSID *clsID, + const wchar_t *newArchiveName, + const Byte *stateActions, + const wchar_t *sfxModule, + IFolderArchiveUpdateCallback *updateCallback100) +{ + if (!CanUpdate()) + return E_NOTIMPL; + NUpdateArchive::CActionSet actionSet; + int i; + for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++) + actionSet.StateActions[i] = (NUpdateArchive::NPairAction::EEnum)stateActions[i]; + + CObjectVector dirItems; + + UString folderPrefix = _folderPrefix; + NFile::NName::NormalizeDirPathPrefix(folderPrefix); + UStringVector errorPaths; + CRecordVector errorCodes; + ::EnumerateDirItems(folderPrefix, _names, _archiveNamePrefix, dirItems, errorPaths, errorCodes); + if (errorCodes.Size() > 0) + { + return errorCodes.Front(); + } + + NWindows::NDLL::CLibrary library; + + CMyComPtr outArchive; + if (GetArchive()) + { + RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive)); + } + else + { + CHandlerLoader loader; + RINOK(loader.CreateHandler(filePath, *clsID, (void **)&outArchive, true)); + library.Attach(loader.Detach()); + } + + NFileTimeType::EEnum fileTimeType; + UINT32 value; + RINOK(outArchive->GetFileTimeType(&value)); + + switch(value) + { + case NFileTimeType::kWindows: + case NFileTimeType::kDOS: + case NFileTimeType::kUnix: + fileTimeType = NFileTimeType::EEnum(value); + break; + default: + return E_FAIL; + } + + CObjectVector updatePairs; + + CObjectVector archiveItems; + if (GetArchive()) + { + RINOK(ReadItems()); + EnumerateArchiveItems(this, _proxyArchive->RootFolder, L"", archiveItems); + } + + GetUpdatePairInfoList(dirItems, archiveItems, fileTimeType, updatePairs); + + CObjectVector updatePairs2; + UpdateProduce(updatePairs, actionSet, updatePairs2); + + CUpdateCallbackAgent updateCallbackAgent; + updateCallbackAgent.Callback = updateCallback100; + CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; + CMyComPtr updateCallback(updateCallbackSpec ); + + updateCallbackSpec->DirPrefix = folderPrefix; + updateCallbackSpec->DirItems = &dirItems; + updateCallbackSpec->ArchiveItems = &archiveItems; + updateCallbackSpec->UpdatePairs = &updatePairs2; + updateCallbackSpec->Archive = GetArchive(); + updateCallbackSpec->Callback = &updateCallbackAgent; + + COutFileStream *outStreamSpec = new COutFileStream; + CMyComPtr outStream(outStreamSpec); + UString archiveName = newArchiveName; + { + UString resultPath; + int pos; + if(!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos)) + throw 141716; + NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos)); + } + if (!outStreamSpec->Create(archiveName, true)) + { + // ShowLastErrorMessage(); + return E_FAIL; + } + + CMyComPtr setProperties; + if (outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties) == S_OK) + { + if (m_PropNames.Size() == 0) + { + RINOK(setProperties->SetProperties(0, 0, 0)); + } + else + { + CRecordVector names; + for(i = 0; i < m_PropNames.Size(); i++) + names.Add((const wchar_t *)m_PropNames[i]); + + NWindows::NCOM::CPropVariant *propValues = new NWindows::NCOM::CPropVariant[m_PropValues.Size()]; + try + { + for (int i = 0; i < m_PropValues.Size(); i++) + propValues[i] = m_PropValues[i]; + RINOK(setProperties->SetProperties(&names.Front(), propValues, names.Size())); + } + catch(...) + { + delete []propValues; + throw; + } + delete []propValues; + } + } + m_PropNames.Clear(); + m_PropValues.Clear(); + + if (sfxModule != NULL) + { + CInFileStream *sfxStreamSpec = new CInFileStream; + CMyComPtr sfxStream(sfxStreamSpec); + if (!sfxStreamSpec->Open(sfxModule)) + throw "Can't open sfx module"; + RINOK(CopyBlock(sfxStream, outStream)); + } + + return outArchive->UpdateItems(outStream, updatePairs2.Size(),updateCallback); +} + + +HRESULT CAgent::CommonUpdate( + const wchar_t *newArchiveName, + int numUpdateItems, + IArchiveUpdateCallback *updateCallback) +{ + if (!CanUpdate()) + return E_NOTIMPL; + CMyComPtr outArchive; + RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive)); + + COutFileStream *outStreamSpec = new COutFileStream; + CMyComPtr outStream(outStreamSpec); + + UString archiveName = newArchiveName; + { + UString resultPath; + int pos; + if(!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos)) + throw 141716; + NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos)); + } + + /* + bool isOK = false; + for (int i = 0; i < (1 << 16); i++) + { + resultName = newArchiveName; + if (i > 0) + { + wchar_t s[32]; + ConvertUInt64ToString(i, s); + resultName += s; + } + if (outStreamSpec->Open(realPath)) + { + isOK = true; + break; + } + if (::GetLastError() != ERROR_FILE_EXISTS) + return ::GetLastError(); + } + if (!isOK) + return ::GetLastError(); + */ + if (!outStreamSpec->Create(archiveName, true)) + { + // ShowLastErrorMessage(); + return E_FAIL; + } + + return outArchive->UpdateItems(outStream, numUpdateItems, updateCallback); +} + + +STDMETHODIMP CAgent::DeleteItems( + const wchar_t *newArchiveName, + const UINT32 *indices, UINT32 numItems, + IFolderArchiveUpdateCallback *updateCallback100) +{ + if (!CanUpdate()) + return E_NOTIMPL; + CUpdateCallbackAgent updateCallbackAgent; + updateCallbackAgent.Callback = updateCallback100; + CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; + CMyComPtr updateCallback(updateCallbackSpec); + + CUIntVector realIndices; + _agentFolder->GetRealIndices(indices, numItems, realIndices); + CObjectVector updatePairs; + int curIndex = 0; + UInt32 numItemsInArchive; + RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)); + for (UInt32 i = 0; i < numItemsInArchive; i++) + { + if (curIndex < realIndices.Size()) + if (realIndices[curIndex] == i) + { + curIndex++; + continue; + } + CUpdatePair2 updatePair; + updatePair.NewData = updatePair.NewProperties = false; + updatePair.ExistInArchive = true; + updatePair.ExistOnDisk = false; + updatePair.IsAnti = false; // check it. Maybe it can be undefined + updatePair.ArchiveItemIndex = i; + updatePairs.Add(updatePair); + } + updateCallbackSpec->UpdatePairs = &updatePairs; + updateCallbackSpec->Archive = GetArchive(); + updateCallbackSpec->Callback = &updateCallbackAgent; + return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback); +} + +HRESULT CAgent::CreateFolder( + const wchar_t *newArchiveName, + const wchar_t *folderName, + IFolderArchiveUpdateCallback *updateCallback100) +{ + if (!CanUpdate()) + return E_NOTIMPL; + CUpdateCallbackAgent updateCallbackAgent; + updateCallbackAgent.Callback = updateCallback100; + CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; + CMyComPtr updateCallback(updateCallbackSpec); + + CObjectVector updatePairs; + UINT32 numItemsInArchive; + RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)); + for (UInt32 i = 0; i < numItemsInArchive; i++) + { + CUpdatePair2 updatePair; + updatePair.NewData = updatePair.NewProperties = false; + updatePair.ExistInArchive = true; + updatePair.ExistOnDisk = false; + updatePair.IsAnti = false; // check it. + updatePair.ArchiveItemIndex = i; + updatePairs.Add(updatePair); + } + CUpdatePair2 updatePair; + updatePair.NewData = updatePair.NewProperties = true; + updatePair.ExistInArchive = false; + updatePair.ExistOnDisk = true; + updatePair.IsAnti = false; + updatePair.ArchiveItemIndex = -1; + updatePair.DirItemIndex = 0; + + updatePairs.Add(updatePair); + + CObjectVector dirItems; + CDirItem dirItem; + + dirItem.Attributes = FILE_ATTRIBUTE_DIRECTORY; + dirItem.Size = 0; + dirItem.Name = _agentFolder->_proxyFolderItem->GetFullPathPrefix() + folderName; + + SYSTEMTIME systemTime; + FILETIME fileTime; + ::GetSystemTime(&systemTime); + ::SystemTimeToFileTime(&systemTime, &fileTime); + dirItem.LastAccessTime = dirItem.LastWriteTime = + dirItem.CreationTime = fileTime; + + dirItems.Add(dirItem); + + updateCallbackSpec->Callback = &updateCallbackAgent; + updateCallbackSpec->DirItems = &dirItems; + updateCallbackSpec->UpdatePairs = &updatePairs; + updateCallbackSpec->Archive = GetArchive(); + return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback); +} + + +HRESULT CAgent::RenameItem( + const wchar_t *newArchiveName, + const UINT32 *indices, UINT32 numItems, + const wchar_t *newItemName, + IFolderArchiveUpdateCallback *updateCallback100) +{ + if (!CanUpdate()) + return E_NOTIMPL; + if (numItems != 1) + return E_INVALIDARG; + CUpdateCallbackAgent updateCallbackAgent; + updateCallbackAgent.Callback = updateCallback100; + CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; + CMyComPtr updateCallback(updateCallbackSpec); + + CUIntVector realIndices; + _agentFolder->GetRealIndices(indices, numItems, realIndices); + + UString fullPrefix = _agentFolder->GetFullPathPrefixPlusPrefix(indices[0]); + UString oldItemPath = fullPrefix + _agentFolder->GetName(indices[0]); + UString newItemPath = fullPrefix + newItemName; + + CObjectVector updatePairs; + int curIndex = 0; + UINT32 numItemsInArchive; + RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)); + for (UInt32 i = 0; i < numItemsInArchive; i++) + { + if (curIndex < realIndices.Size()) + if (realIndices[curIndex] == i) + { + CUpdatePair2 updatePair; + updatePair.NewData = false; + updatePair.NewProperties = true; + updatePair.ExistInArchive = true; + updatePair.ExistOnDisk = false; + RINOK(IsArchiveItemAnti(GetArchive(), i, updatePair.IsAnti)); + updatePair.ArchiveItemIndex = i; + updatePair.NewNameIsDefined = true; + + updatePair.NewName = newItemName; + + UString oldFullPath; + RINOK(GetArchiveItemPath(GetArchive(), i, DefaultName, oldFullPath)); + + if (oldItemPath.CompareNoCase(oldFullPath.Left(oldItemPath.Length())) != 0) + return E_INVALIDARG; + + updatePair.NewName = newItemPath + oldFullPath.Mid(oldItemPath.Length()); + updatePairs.Add(updatePair); + curIndex++; + continue; + } + CUpdatePair2 updatePair; + updatePair.NewData = updatePair.NewProperties = false; + updatePair.ExistInArchive = true; + updatePair.ExistOnDisk = false; + updatePair.IsAnti = false; + updatePair.ArchiveItemIndex = i; + updatePairs.Add(updatePair); + } + updateCallbackSpec->Callback = &updateCallbackAgent; + updateCallbackSpec->UpdatePairs = &updatePairs; + updateCallbackSpec->Archive = GetArchive(); + return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback); +} + +STDMETHODIMP CAgent::SetProperties(const wchar_t **names, + const PROPVARIANT *values, INT32 numProperties) +{ + m_PropNames.Clear(); + m_PropValues.Clear(); + for (int i = 0; i < numProperties; i++) + { + m_PropNames.Add(names[i]); + m_PropValues.Add(values[i]); + } + return S_OK; +} + + diff --git a/CPP/7zip/UI/Agent/AgentProxy.cpp b/CPP/7zip/UI/Agent/AgentProxy.cpp new file mode 100755 index 00000000..42063e67 --- /dev/null +++ b/CPP/7zip/UI/Agent/AgentProxy.cpp @@ -0,0 +1,203 @@ +// AgentProxy.cpp + +#include "StdAfx.h" + +#include "AgentProxy.h" + +#include "Common/MyCom.h" +#include "Windows/PropVariant.h" +#include "Windows/Defs.h" +#include "../Common/OpenArchive.h" + +extern "C" +{ + #include "../../../../C/Sort.h" +} + +using namespace NWindows; + +int CProxyFolder::FindDirSubItemIndex(const UString &name, int &insertPos) const +{ + int left = 0, right = Folders.Size(); + for (;;) + { + if (left == right) + { + insertPos = left; + return -1; + } + int mid = (left + right) / 2; + int compare = name.CompareNoCase(Folders[mid].Name); + if (compare == 0) + return mid; + if (compare < 0) + right = mid; + else + left = mid + 1; + } +} + +int CProxyFolder::FindDirSubItemIndex(const UString &name) const +{ + int insertPos; + return FindDirSubItemIndex(name, insertPos); +} + +void CProxyFolder::AddFileSubItem(UINT32 index, const UString &name) +{ + Files.Add(CProxyFile()); + Files.Back().Name = name; + Files.Back().Index = index; +} + +CProxyFolder* CProxyFolder::AddDirSubItem(UINT32 index, bool leaf, + const UString &name) +{ + int insertPos; + int folderIndex = FindDirSubItemIndex(name, insertPos); + if (folderIndex >= 0) + { + CProxyFolder *item = &Folders[folderIndex]; + if(leaf) + { + item->Index = index; + item->IsLeaf = true; + } + return item; + } + Folders.Insert(insertPos, CProxyFolder()); + CProxyFolder *item = &Folders[insertPos]; + item->Name = name; + item->Index = index; + item->Parent = this; + item->IsLeaf = leaf; + return item; +} + +void CProxyFolder::Clear() +{ + Folders.Clear(); + Files.Clear(); +} + +UString CProxyFolder::GetFullPathPrefix() const +{ + UString result; + const CProxyFolder *current = this; + while (current->Parent != NULL) + { + result = current->Name + UString(L'\\') + result; + current = current->Parent; + } + return result; +} + +UString CProxyFolder::GetItemName(UINT32 index) const +{ + if (index < (UINT32)Folders.Size()) + return Folders[index].Name; + return Files[index - Folders.Size()].Name; +} + +void CProxyFolder::AddRealIndices(CUIntVector &realIndices) const +{ + if (IsLeaf) + realIndices.Add(Index); + int i; + for(i = 0; i < Folders.Size(); i++) + Folders[i].AddRealIndices(realIndices); + for(i = 0; i < Files.Size(); i++) + realIndices.Add(Files[i].Index); +} + +void CProxyFolder::GetRealIndices(const UINT32 *indices, + UINT32 numItems, CUIntVector &realIndices) const +{ + realIndices.Clear(); + for(UINT32 i = 0; i < numItems; i++) + { + int index = indices[i]; + int numDirItems = Folders.Size(); + if (index < numDirItems) + Folders[index].AddRealIndices(realIndices); + else + realIndices.Add(Files[index - numDirItems].Index); + } + HeapSort(&realIndices.Front(), realIndices.Size()); +} + +/////////////////////////////////////////////// +// CProxyArchive + +HRESULT CProxyArchive::Reload(IInArchive *archive, IProgress *progress) +{ + RootFolder.Clear(); + return ReadObjects(archive, progress); +} + +HRESULT CProxyArchive::Load(IInArchive *archive, + const UString &defaultName, + // const FILETIME &defaultTime, + // UINT32 defaultAttributes, + IProgress *progress) +{ + DefaultName = defaultName; + // DefaultTime = defaultTime; + // DefaultAttributes = defaultAttributes; + return Reload(archive, progress); +} + + +HRESULT CProxyArchive::ReadObjects(IInArchive *archiveHandler, IProgress *progress) +{ + UINT32 numItems; + RINOK(archiveHandler->GetNumberOfItems(&numItems)); + if (progress != NULL) + { + UINT64 totalItems = numItems; + RINOK(progress->SetTotal(totalItems)); + } + for(UINT32 i = 0; i < numItems; i++) + { + if (progress != NULL) + { + UINT64 currentItemIndex = i; + RINOK(progress->SetCompleted(¤tItemIndex)); + } + NCOM::CPropVariant propVariantPath; + RINOK(archiveHandler->GetProperty(i, kpidPath, &propVariantPath)); + CProxyFolder *currentItem = &RootFolder; + UString fileName; + if(propVariantPath.vt == VT_EMPTY) + fileName = DefaultName; + else + { + if(propVariantPath.vt != VT_BSTR) + return E_FAIL; + UString filePath = propVariantPath.bstrVal; + + int len = filePath.Length(); + for (int i = 0; i < len; i++) + { + wchar_t c = filePath[i]; + if (c == '\\' || c == '/') + { + currentItem = currentItem->AddDirSubItem((UInt32)(Int32)-1, false, fileName); + fileName.Empty(); + } + else + fileName += c; + } + } + + NCOM::CPropVariant propVariantIsFolder; + bool isFolder; + RINOK(IsArchiveItemFolder(archiveHandler, i, isFolder)); + if(isFolder) + currentItem->AddDirSubItem(i, true, fileName); + else + currentItem->AddFileSubItem(i, fileName); + } + return S_OK; +} + diff --git a/CPP/7zip/UI/Agent/AgentProxy.h b/CPP/7zip/UI/Agent/AgentProxy.h new file mode 100755 index 00000000..9402cfdd --- /dev/null +++ b/CPP/7zip/UI/Agent/AgentProxy.h @@ -0,0 +1,56 @@ +// AgentProxy.h + +#ifndef __AGENT_PROXY_H +#define __AGENT_PROXY_H + +#include "Common/String.h" + +#include "../../Archive/IArchive.h" + +class CProxyFile +{ +public: + UINT32 Index; + UString Name; +}; + +class CProxyFolder: public CProxyFile +{ +public: + CProxyFolder *Parent; + CObjectVector Folders; + CObjectVector Files; + bool IsLeaf; + + CProxyFolder(): Parent(NULL) {}; + int FindDirSubItemIndex(const UString &name, int &insertPos) const; + int FindDirSubItemIndex(const UString &name) const; + CProxyFolder* AddDirSubItem(UINT32 index, + bool leaf, const UString &name); + void AddFileSubItem(UINT32 index, const UString &name); + void Clear(); + + UString GetFullPathPrefix() const; + UString GetItemName(UINT32 index) const; + void AddRealIndices(CUIntVector &realIndices) const; + void GetRealIndices(const UINT32 *indices, UINT32 numItems, + CUIntVector &realIndices) const; +}; + +class CProxyArchive +{ + HRESULT ReadObjects(IInArchive *inArchive, IProgress *progress); +public: + UString DefaultName; + // FILETIME DefaultTime; + // UINT32 DefaultAttributes; + CProxyFolder RootFolder; + HRESULT Reload(IInArchive *archive, IProgress *progress); + HRESULT Load(IInArchive *archive, + const UString &defaultName, + // const FILETIME &defaultTime, + // UINT32 defaultAttributes, + IProgress *progress); +}; + +#endif \ No newline at end of file diff --git a/CPP/7zip/UI/Agent/ArchiveFolder.cpp b/CPP/7zip/UI/Agent/ArchiveFolder.cpp new file mode 100755 index 00000000..0ce553dc --- /dev/null +++ b/CPP/7zip/UI/Agent/ArchiveFolder.cpp @@ -0,0 +1,72 @@ +// Zip/ArchiveFolder.cpp + +#include "StdAfx.h" + +#include "Common/ComTry.h" +#include "Common/StringConvert.h" +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" +#include "Windows/PropVariantConversions.h" +#include "Windows/FileDir.h" + +#include "../../Common/FileStreams.h" + +#include "../Common/UpdatePair.h" +#include "../Common/ArchiveExtractCallback.h" + +#include "Agent.h" + +using namespace NWindows; +using namespace NCOM; + +STDMETHODIMP CAgentFolder::CopyTo(const UINT32 *indices, UINT32 numItems, + const wchar_t *path, IFolderOperationsExtractCallback *callback) +{ + COM_TRY_BEGIN + CArchiveExtractCallback *extractCallbackSpec = new + CArchiveExtractCallback; + CMyComPtr extractCallback = extractCallbackSpec; + UStringVector pathParts; + CProxyFolder *currentProxyFolder = _proxyFolderItem; + while (currentProxyFolder->Parent) + { + pathParts.Insert(0, currentProxyFolder->Name); + currentProxyFolder = currentProxyFolder->Parent; + } + + CMyComPtr extractCallback2; + { + CMyComPtr callbackWrap = callback; + RINOK(callbackWrap.QueryInterface( + IID_IFolderArchiveExtractCallback, &extractCallback2)); + } + + NExtract::NPathMode::EEnum pathMode = _flatMode ? + NExtract::NPathMode::kNoPathnames : + NExtract::NPathMode::kCurrentPathnames; + + extractCallbackSpec->Init(_agentSpec->GetArchive(), + extractCallback2, + false, + path, + pathMode, + NExtract::NOverwriteMode::kAskBefore, + pathParts, + _agentSpec->DefaultName, + _agentSpec->DefaultTime, + _agentSpec->DefaultAttributes + // ,_agentSpec->_srcDirectoryPrefix + ); + CUIntVector realIndices; + GetRealIndices(indices, numItems, realIndices); + return _agentSpec->GetArchive()->Extract(&realIndices.Front(), + realIndices.Size(), BoolToInt(false), extractCallback); + COM_TRY_END +} + +STDMETHODIMP CAgentFolder::MoveTo(const UINT32 * /* indices */, UINT32 /* numItems */, + const wchar_t * /* path */, IFolderOperationsExtractCallback * /* callback */) +{ + return E_NOTIMPL; +} + diff --git a/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp b/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp new file mode 100755 index 00000000..ce423941 --- /dev/null +++ b/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp @@ -0,0 +1,98 @@ +// Zip/ArchiveFolder.cpp + +#include "StdAfx.h" + +#include "Agent.h" + +#include "Common/StringConvert.h" + +#include "../Common/OpenArchive.h" + +static const UInt64 kMaxCheckStartPosition = 1 << 20; + +static inline UINT GetCurrentFileCodePage() + { return AreFileApisANSI() ? CP_ACP : CP_OEMCP; } + +void CArchiveFolderManager::LoadFormats() +{ + if (!_formatsLoaded) + ReadArchiverInfoList(_formats); +} + +int CArchiveFolderManager::FindFormat(const UString &type) +{ + // LoadFormats(); + for (int i = 0; i < _formats.Size(); i++) + if (type.CompareNoCase(_formats[i].Name) == 0) + return i; + return -1; +} + +STDMETHODIMP CArchiveFolderManager::OpenFolderFile(const wchar_t *filePath, + IFolderFolder **resultFolder, IProgress *progress) +{ + CMyComPtr openArchiveCallback; + if (progress != 0) + { + CMyComPtr progressWrapper = progress; + progressWrapper.QueryInterface(IID_IArchiveOpenCallback, &openArchiveCallback); + } + CAgent *agent = new CAgent(); + CMyComPtr archive = agent; + RINOK(agent->Open(filePath, NULL, openArchiveCallback)); + return agent->BindToRootFolder(resultFolder); +} + +/* +HRESULT CAgent::FolderReOpen( + IArchiveOpenCallback *openArchiveCallback) +{ + return ReOpenArchive(_archive, _archiveFilePath); +} +*/ + +STDMETHODIMP CArchiveFolderManager::GetTypes(BSTR *types) +{ + LoadFormats(); + UString typesStrings; + for(int i = 0; i < _formats.Size(); i++) + { + const CArchiverInfo &ai = _formats[i]; + if (!ai.Associate) + continue; + if (i != 0) + typesStrings += L' '; + typesStrings += ai.Name; + } + CMyComBSTR valueTemp = typesStrings; + *types = valueTemp.Detach(); + return S_OK; +} + +STDMETHODIMP CArchiveFolderManager::GetExtension(const wchar_t *type, BSTR *extension) +{ + *extension = 0; + int formatIndex = FindFormat(type); + if (formatIndex < 0) + return E_INVALIDARG; + CMyComBSTR valueTemp = _formats[formatIndex].Extensions[0].Ext; + *extension = valueTemp.Detach(); + return S_OK; +} + +STDMETHODIMP CArchiveFolderManager::GetIconPath(const wchar_t *type, BSTR *iconPath) +{ + *iconPath = 0; + int formatIndex = FindFormat(type); + if (formatIndex < 0) + return E_INVALIDARG; + CMyComBSTR iconPathTemp = _formats[formatIndex].FilePath; + *iconPath = iconPathTemp.Detach(); + return S_OK; +} + +STDMETHODIMP CArchiveFolderManager::CreateFolderFile(const wchar_t * /* type */, + const wchar_t * /* filePath */, IProgress * /* progress */) +{ + return E_NOTIMPL; +} diff --git a/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp b/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp new file mode 100755 index 00000000..4d66d86d --- /dev/null +++ b/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp @@ -0,0 +1,215 @@ +// FolderOut.cpp + +#include "StdAfx.h" +#include "Agent.h" + +#include "Common/StringConvert.h" +#include "Common/ComTry.h" +#include "Windows/FileDir.h" + +// #include "../Common/CompressEngineCommon.h" +#include "../Common/ZipRegistry.h" +#include "../Common/UpdateAction.h" +#include "../Common/WorkDir.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDirectory; + +static LPCWSTR kTempArcivePrefix = L"7zA"; + +void CAgentFolder::GetPathParts(UStringVector &pathParts) +{ + pathParts.Clear(); + CMyComPtr folder = this; + for (;;) + { + CMyComPtr newFolder; + folder->BindToParentFolder(&newFolder); + if (newFolder == NULL) + break; + CMyComBSTR name; + folder->GetName(&name); + pathParts.Insert(0, (const wchar_t *)name); + folder = newFolder; + } +} + +HRESULT CAgentFolder::CommonUpdateOperation( + bool deleteOperation, + bool createFolderOperation, + bool renameOperation, + const wchar_t *newItemName, + const NUpdateArchive::CActionSet *actionSet, + const UINT32 *indices, UINT32 numItems, + IFolderArchiveUpdateCallback *updateCallback100) +{ + NWorkDir::CInfo workDirInfo; + ReadWorkDirInfo(workDirInfo); + UString archiveFilePath = _agentSpec->_archiveFilePath; + UString workDir = GetWorkDir(workDirInfo, archiveFilePath ); + CreateComplexDirectory(workDir); + + CTempFileW tempFile; + UString tempFileName; + if (tempFile.Create(workDir, kTempArcivePrefix, tempFileName) == 0) + return E_FAIL; + + /* + if (SetOutProperties(anOutArchive, aCompressionInfo.Method) != S_OK) + return NFileOperationReturnCode::kError; + */ + + //////////////////////////// + // Save FolderItem; + + UStringVector pathParts; + GetPathParts(pathParts); + + HRESULT result; + if (deleteOperation) + result = _agentSpec->DeleteItems(tempFileName, + indices, numItems, updateCallback100); + else if (createFolderOperation) + { + result = _agentSpec->CreateFolder(tempFileName, + newItemName, updateCallback100); + } + else if (renameOperation) + { + result = _agentSpec->RenameItem( + tempFileName, + indices, numItems, + newItemName, + updateCallback100); + } + else + { + Byte actionSetByte[NUpdateArchive::NPairState::kNumValues]; + for (int i = 0; i < NUpdateArchive::NPairState::kNumValues; i++) + actionSetByte[i] = (Byte)actionSet->StateActions[i]; + result = _agentSpec->DoOperation(NULL, NULL, + tempFileName, actionSetByte, NULL, updateCallback100); + } + + if (result != S_OK) + return result; + + _agentSpec->Close(); + + // m_FolderItem = NULL; + + if (!DeleteFileAlways(archiveFilePath )) + return GetLastError(); + + tempFile.DisableDeleting(); + if (!MyMoveFile(tempFileName, archiveFilePath )) + return GetLastError(); + + RINOK(_agentSpec->ReOpen(NULL)); + + //////////////////////////// + // Restore FolderItem; + + CMyComPtr archiveFolder; + RINOK(_agentSpec->BindToRootFolder(&archiveFolder)); + for (int i = 0; i < pathParts.Size(); i++) + { + CMyComPtr newFolder; + archiveFolder->BindToFolder(pathParts[i], &newFolder); + if(!newFolder) + break; + archiveFolder = newFolder; + } + + CMyComPtr 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 updateCallback100; + if (progress != 0) + { + CMyComPtr 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 updateCallback100; + if (progress != 0) + { + CMyComPtr 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 updateCallback100; + if (progress != 0) + { + CMyComPtr progressWrapper = progress; + RINOK(progressWrapper.QueryInterface(IID_IFolderArchiveUpdateCallback, &updateCallback100)); + } + return CommonUpdateOperation(false, true, false, name, NULL, NULL, 0, updateCallback100); + COM_TRY_END +} + +STDMETHODIMP CAgentFolder::Rename(UINT32 index, const wchar_t *newName, IProgress *progress) +{ + COM_TRY_BEGIN + CUIntVector indices; + indices.Add(index); + RINOK(_agentSpec->SetFolder(this)); + CMyComPtr updateCallback100; + if (progress != 0) + { + CMyComPtr progressWrapper = progress; + RINOK(progressWrapper.QueryInterface(IID_IFolderArchiveUpdateCallback, &updateCallback100)); + } + return CommonUpdateOperation(false, false, true, newName, NULL, &indices.Front(), + indices.Size(), updateCallback100); + COM_TRY_END +} + +STDMETHODIMP CAgentFolder::CreateFile(const wchar_t * /* name */, IProgress * /* progress */) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CAgentFolder::SetProperty(UINT32 /* index */, PROPID /* propID */, + const PROPVARIANT * /* value */, IProgress * /* progress */) +{ + return E_NOTIMPL; +} diff --git a/CPP/7zip/UI/Agent/IFolderArchive.h b/CPP/7zip/UI/Agent/IFolderArchive.h new file mode 100755 index 00000000..41d9eb22 --- /dev/null +++ b/CPP/7zip/UI/Agent/IFolderArchive.h @@ -0,0 +1,90 @@ +// IFolderArchive.h + +#ifndef __IFOLDER_ARCHIVE_H +#define __IFOLDER_ARCHIVE_H + +#include "../../Archive/IArchive.h" +// #include "../Format/Common/ArchiveInterface.h" +#include "../../FileManager/IFolder.h" +#include "../Common/IFileExtractCallback.h" +#include "../Common/ExtractMode.h" + +// {23170F69-40C1-278A-0000-000100050000} +DEFINE_GUID(IID_IArchiveFolder, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000100050000") +IArchiveFolder: public IUnknown +{ +public: + STDMETHOD(Extract)(const UINT32 *indices, UINT32 numItems, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, + const wchar_t *path, + INT32 testMode, + IFolderArchiveExtractCallback *extractCallback2) PURE; +}; + +// {23170F69-40C1-278A-0000-000100060000} +DEFINE_GUID(IID_IInFolderArchive, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000100060000") +IInFolderArchive: public IUnknown +{ +public: + STDMETHOD(Open)(const wchar_t *filePath, + // CLSID *clsIDResult, + BSTR *archiveType, + IArchiveOpenCallback *openArchiveCallback) PURE; + STDMETHOD(ReOpen)( + // const wchar_t *filePath, + IArchiveOpenCallback *openArchiveCallback) PURE; + STDMETHOD(Close)() PURE; + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) PURE; + STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties) PURE; + STDMETHOD(GetPropertyInfo)(UINT32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) PURE; + STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties) PURE; + STDMETHOD(GetArchivePropertyInfo)(UINT32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) PURE; + STDMETHOD(BindToRootFolder)(IFolderFolder **resultFolder) PURE; + STDMETHOD(Extract)( + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, + const wchar_t *path, + INT32 testMode, + IFolderArchiveExtractCallback *extractCallback2) PURE; +}; + +// {23170F69-40C1-278A-0000-0001000B0000} +DEFINE_GUID(IID_IFolderArchiveUpdateCallback, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-0001000B0000") +IFolderArchiveUpdateCallback: public IProgress +{ +public: + STDMETHOD(CompressOperation)(const wchar_t *name) PURE; + STDMETHOD(DeleteOperation)(const wchar_t *name) PURE; + STDMETHOD(OperationResult)(INT32 operationResult) PURE; + STDMETHOD(UpdateErrorMessage)(const wchar_t *message) PURE; +}; + +// {23170F69-40C1-278A-0000-0001000A0000} +DEFINE_GUID(IID_IOutFolderArchive, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-0001000A0000") +IOutFolderArchive: public IUnknown +{ + STDMETHOD(SetFolder)(IFolderFolder *folder) PURE; + STDMETHOD(SetFiles)(const wchar_t *folderPrefix, const wchar_t **names, UINT32 numNames) PURE; + STDMETHOD(DeleteItems)(const wchar_t *newArchiveName, + const UINT32 *indices, UINT32 numItems, IFolderArchiveUpdateCallback *updateCallback) PURE; + STDMETHOD(DoOperation)( + const wchar_t *filePath, + const CLSID *clsID, + const wchar_t *newArchiveName, + const Byte *stateActions, + const wchar_t *sfxModule, + IFolderArchiveUpdateCallback *updateCallback) PURE; +}; + +#endif diff --git a/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp b/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp new file mode 100755 index 00000000..0d57307c --- /dev/null +++ b/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp @@ -0,0 +1,80 @@ +// UpdateCallbackAgent.h + +#include "StdAfx.h" + +#include "Windows/Error.h" + +#include "UpdateCallbackAgent.h" + +using namespace NWindows; + +HRESULT CUpdateCallbackAgent::SetTotal(UINT64 size) +{ + if (Callback) + return Callback->SetTotal(size); + return S_OK; +} + +HRESULT CUpdateCallbackAgent::SetCompleted(const UINT64 *completeValue) +{ + if (Callback) + return Callback->SetCompleted(completeValue); + return S_OK; +} + +HRESULT CUpdateCallbackAgent::CheckBreak() +{ + return S_OK; +} + +HRESULT CUpdateCallbackAgent::Finilize() +{ + return S_OK; +} + +HRESULT CUpdateCallbackAgent::OpenFileError(const wchar_t *name, DWORD systemError) +{ + // if (systemError == ERROR_SHARING_VIOLATION) + { + if (Callback) + { + RINOK(Callback->UpdateErrorMessage( + UString(L"WARNING: ") + + NError::MyFormatMessageW(systemError) + + UString(L": ") + + UString(name))); + return S_FALSE; + } + } + // FailedFiles.Add(name); + return systemError; +} + +HRESULT CUpdateCallbackAgent::GetStream(const wchar_t *name, bool /* isAnti */) +{ + if (Callback) + return Callback->CompressOperation(name); + return S_OK; +} + +HRESULT CUpdateCallbackAgent::SetOperationResult(INT32 operationResult) +{ + if (Callback) + return Callback->OperationResult(operationResult); + return S_OK; +} + +HRESULT CUpdateCallbackAgent::CryptoGetTextPassword2(INT32 *passwordIsDefined, BSTR *password) +{ + *passwordIsDefined = BoolToInt(false); + if (!_cryptoGetTextPassword) + { + if (!Callback) + return S_OK; + HRESULT result = Callback.QueryInterface( + IID_ICryptoGetTextPassword2, &_cryptoGetTextPassword); + if (result != S_OK) + return S_OK; + } + return _cryptoGetTextPassword->CryptoGetTextPassword2(passwordIsDefined, password); +} diff --git a/CPP/7zip/UI/Agent/UpdateCallbackAgent.h b/CPP/7zip/UI/Agent/UpdateCallbackAgent.h new file mode 100755 index 00000000..1cff501a --- /dev/null +++ b/CPP/7zip/UI/Agent/UpdateCallbackAgent.h @@ -0,0 +1,24 @@ +// UpdateCallbackAgent.h + +#ifndef __UPDATECALLBACKAGENT_H +#define __UPDATECALLBACKAGENT_H + +#include "../Common/UpdateCallback.h" +#include "IFolderArchive.h" + +class CUpdateCallbackAgent: public IUpdateCallbackUI +{ + virtual HRESULT SetTotal(UINT64 size); + virtual HRESULT SetCompleted(const UINT64 *completeValue); + virtual HRESULT CheckBreak(); + virtual HRESULT Finilize(); + virtual HRESULT GetStream(const wchar_t *name, bool isAnti); + virtual HRESULT OpenFileError(const wchar_t *name, DWORD systemError); + virtual HRESULT SetOperationResult(INT32 operationResult); + virtual HRESULT CryptoGetTextPassword2(INT32 *passwordIsDefined, BSTR *password); + CMyComPtr _cryptoGetTextPassword; +public: + CMyComPtr Callback; +}; + +#endif diff --git a/CPP/7zip/UI/Client7z/Client7z.cpp b/CPP/7zip/UI/Client7z/Client7z.cpp new file mode 100755 index 00000000..46bdb727 --- /dev/null +++ b/CPP/7zip/UI/Client7z/Client7z.cpp @@ -0,0 +1,850 @@ +// Client7z.cpp + +#include "StdAfx.h" + +#include + +#include "Common/StringConvert.h" +#include "Common/IntToString.h" +#include "../../Common/FileStreams.h" +#include "../../Archive/IArchive.h" +#include "../../IPassword.h" + +#include "Windows/PropVariant.h" +#include "Windows/PropVariantConversions.h" +#include "Windows/DLL.h" +#include "Windows/FileDir.h" +#include "Windows/FileName.h" +#include "Windows/FileFind.h" + +// {23170F69-40C1-278A-1000-000110070000} +DEFINE_GUID(CLSID_CFormat7z, + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00); + +using namespace NWindows; + +static const char *kCopyrightString = "7-Zip 4.43 (7za.DLL client example) (c) 1999-2006 Igor Pavlov 2006-08-10\n"; +static const char *kHelpString = +"Usage: Client7z.exe [a | l | x ] archive.7z [fileName ...]\n" +"Examples:\n" +" Client7z.exe a archive.7z f1.txt f2.txt : compress two files to archive.7z\n" +" Client7z.exe l archive.7z : List contents of archive.7z\n" +" Client7z.exe x archive.7z : eXtract files from archive.7z\n"; + + +typedef UINT32 (WINAPI * CreateObjectFunc)( + const GUID *clsID, + const GUID *interfaceID, + void **outObject); + +#ifndef _UNICODE +bool g_IsNT = false; +static inline bool IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); +} +#endif + +void PrintString(const UString &s) +{ + printf("%s", (LPCSTR)GetOemString(s)); +} + +void PrintString(const AString &s) +{ + printf("%s", s); +} + +void PrintNewLine() +{ + PrintString("\n"); +} + +void PrintStringLn(const AString &s) +{ + PrintString(s); + PrintNewLine(); +} + +static HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result) +{ + NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, propID, &prop)); + if(prop.vt == VT_BOOL) + result = VARIANT_BOOLToBool(prop.boolVal); + else if (prop.vt == VT_EMPTY) + result = false; + else + return E_FAIL; + return S_OK; +} + +static HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result) +{ + return IsArchiveItemProp(archive, index, kpidIsFolder, result); +} + + +static const wchar_t *kEmptyFileAlias = L"[Content]"; + + +////////////////////////////////////////////////////////////// +// Archive Open callback class + + +class CArchiveOpenCallback: + public IArchiveOpenCallback, + public ICryptoGetTextPassword, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP1(ICryptoGetTextPassword) + + STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes); + STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes); + + STDMETHOD(CryptoGetTextPassword)(BSTR *password); + + bool PasswordIsDefined; + UString Password; + + CArchiveOpenCallback() : PasswordIsDefined(false) {} +}; + +STDMETHODIMP CArchiveOpenCallback::SetTotal(const UInt64 *files, const UInt64 *bytes) +{ + return S_OK; +} + +STDMETHODIMP CArchiveOpenCallback::SetCompleted(const UInt64 *files, const UInt64 *bytes) +{ + return S_OK; +} + +STDMETHODIMP CArchiveOpenCallback::CryptoGetTextPassword(BSTR *password) +{ + if (!PasswordIsDefined) + { + // You can ask real password here from user + // Password = GetPassword(OutStream); + // PasswordIsDefined = true; + PrintStringLn("Password is not defined"); + return E_ABORT; + } + CMyComBSTR tempName(Password); + *password = tempName.Detach(); + return S_OK; +} + + +////////////////////////////////////////////////////////////// +// Archive Extracting callback class + +static const wchar_t *kCantDeleteOutputFile = L"ERROR: Can not delete output file "; + +static const char *kTestingString = "Testing "; +static const char *kExtractingString = "Extracting "; +static const char *kSkippingString = "Skipping "; + +static const char *kUnsupportedMethod = "Unsupported Method"; +static const char *kCRCFailed = "CRC Failed"; +static const char *kDataError = "Data Error"; +static const char *kUnknownError = "Unknown Error"; + +class CArchiveExtractCallback: + public IArchiveExtractCallback, + public ICryptoGetTextPassword, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP1(ICryptoGetTextPassword) + + // IProgress + STDMETHOD(SetTotal)(UInt64 size); + STDMETHOD(SetCompleted)(const UInt64 *completeValue); + + // IArchiveExtractCallback + STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode); + STDMETHOD(PrepareOperation)(Int32 askExtractMode); + STDMETHOD(SetOperationResult)(Int32 resultEOperationResult); + + // ICryptoGetTextPassword + STDMETHOD(CryptoGetTextPassword)(BSTR *aPassword); + +private: + CMyComPtr _archiveHandler; + UString _directoryPath; // Output directory + UString _filePath; // name inside arcvhive + UString _diskFilePath; // full path to file on disk + bool _extractMode; + struct CProcessedFileInfo + { + FILETIME UTCLastWriteTime; + UInt32 Attributes; + bool IsDirectory; + bool AttributesAreDefined; + bool UTCLastWriteTimeIsDefined; + } _processedFileInfo; + + COutFileStream *_outFileStreamSpec; + CMyComPtr _outFileStream; + +public: + void Init(IInArchive *archiveHandler, const UString &directoryPath); + + UInt64 NumErrors; + bool PasswordIsDefined; + UString Password; + + CArchiveExtractCallback() : PasswordIsDefined(false) {} +}; + +void CArchiveExtractCallback::Init(IInArchive *archiveHandler, const UString &directoryPath) +{ + NumErrors = 0; + _archiveHandler = archiveHandler; + _directoryPath = directoryPath; + NFile::NName::NormalizeDirPathPrefix(_directoryPath); +} + +STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 size) +{ + return S_OK; +} + +STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue) +{ + return S_OK; +} + +STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, + ISequentialOutStream **outStream, Int32 askExtractMode) +{ + *outStream = 0; + _outFileStream.Release(); + + { + // Get Name + NCOM::CPropVariant propVariant; + RINOK(_archiveHandler->GetProperty(index, kpidPath, &propVariant)); + + UString fullPath; + if(propVariant.vt == VT_EMPTY) + fullPath = kEmptyFileAlias; + else + { + if(propVariant.vt != VT_BSTR) + return E_FAIL; + fullPath = propVariant.bstrVal; + } + _filePath = fullPath; + } + + { + // Get Attributes + NCOM::CPropVariant propVariant; + RINOK(_archiveHandler->GetProperty(index, kpidAttributes, &propVariant)); + if (propVariant.vt == VT_EMPTY) + { + _processedFileInfo.Attributes = 0; + _processedFileInfo.AttributesAreDefined = false; + } + else + { + if (propVariant.vt != VT_UI4) + throw "incorrect item"; + _processedFileInfo.Attributes = propVariant.ulVal; + _processedFileInfo.AttributesAreDefined = true; + } + } + + RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.IsDirectory)); + + { + // Get Modified Time + NCOM::CPropVariant propVariant; + RINOK(_archiveHandler->GetProperty(index, kpidLastWriteTime, &propVariant)); + _processedFileInfo.UTCLastWriteTimeIsDefined = false; + switch(propVariant.vt) + { + case VT_EMPTY: + // _processedFileInfo.UTCLastWriteTime = _utcLastWriteTimeDefault; + break; + case VT_FILETIME: + _processedFileInfo.UTCLastWriteTime = propVariant.filetime; + _processedFileInfo.UTCLastWriteTimeIsDefined = true; + break; + default: + return E_FAIL; + } + + } + { + // Get Size + NCOM::CPropVariant propVariant; + RINOK(_archiveHandler->GetProperty(index, kpidSize, &propVariant)); + bool newFileSizeDefined = (propVariant.vt != VT_EMPTY); + UInt64 newFileSize; + if (newFileSizeDefined) + newFileSize = ConvertPropVariantToUInt64(propVariant); + } + + + { + // Create folders for file + int slashPos = _filePath.ReverseFind(WCHAR_PATH_SEPARATOR); + if (slashPos >= 0) + NFile::NDirectory::CreateComplexDirectory(_directoryPath + _filePath.Left(slashPos)); + } + + UString fullProcessedPath = _directoryPath + _filePath; + _diskFilePath = fullProcessedPath; + + if (_processedFileInfo.IsDirectory) + { + NFile::NDirectory::CreateComplexDirectory(fullProcessedPath); + } + else + { + NFile::NFind::CFileInfoW fileInfo; + if(NFile::NFind::FindFile(fullProcessedPath, fileInfo)) + { + if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath)) + { + PrintString(UString(kCantDeleteOutputFile) + fullProcessedPath); + return E_ABORT; + } + } + + _outFileStreamSpec = new COutFileStream; + CMyComPtr outStreamLoc(_outFileStreamSpec); + if (!_outFileStreamSpec->File.Open(fullProcessedPath, CREATE_ALWAYS)) + { + PrintString((UString)L"can not open output file " + fullProcessedPath); + return E_ABORT; + } + _outFileStream = outStreamLoc; + *outStream = outStreamLoc.Detach(); + } + return S_OK; +} + +STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode) +{ + _extractMode = false; + switch (askExtractMode) + { + case NArchive::NExtract::NAskMode::kExtract: + _extractMode = true; + }; + switch (askExtractMode) + { + case NArchive::NExtract::NAskMode::kExtract: + PrintString(kExtractingString); + break; + case NArchive::NExtract::NAskMode::kTest: + PrintString(kTestingString); + break; + case NArchive::NExtract::NAskMode::kSkip: + PrintString(kSkippingString); + break; + }; + PrintString(_filePath); + return S_OK; +} + +STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult) +{ + switch(operationResult) + { + case NArchive::NExtract::NOperationResult::kOK: + break; + default: + { + NumErrors++; + PrintString(" "); + switch(operationResult) + { + case NArchive::NExtract::NOperationResult::kUnSupportedMethod: + PrintString(kUnsupportedMethod); + break; + case NArchive::NExtract::NOperationResult::kCRCError: + PrintString(kCRCFailed); + break; + case NArchive::NExtract::NOperationResult::kDataError: + PrintString(kDataError); + break; + default: + PrintString(kUnknownError); + } + } + } + + if(_outFileStream != NULL && _processedFileInfo.UTCLastWriteTimeIsDefined) + _outFileStreamSpec->File.SetLastWriteTime(&_processedFileInfo.UTCLastWriteTime); + _outFileStream.Release(); + if (_extractMode && _processedFileInfo.AttributesAreDefined) + NFile::NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attributes); + PrintNewLine(); + return S_OK; +} + + +STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password) +{ + if (!PasswordIsDefined) + { + // You can ask real password here from user + // Password = GetPassword(OutStream); + // PasswordIsDefined = true; + PrintStringLn("Password is not defined"); + return E_ABORT; + } + CMyComBSTR tempName(Password); + *password = tempName.Detach(); + return S_OK; +} + + + +////////////////////////////////////////////////////////////// +// Archive Creating callback class + +struct CDirItem +{ + UInt32 Attributes; + FILETIME CreationTime; + FILETIME LastAccessTime; + FILETIME LastWriteTime; + UInt64 Size; + UString Name; + UString FullPath; + bool IsDirectory() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0 ; } +}; + +class CArchiveUpdateCallback: + public IArchiveUpdateCallback2, + public ICryptoGetTextPassword2, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP2(IArchiveUpdateCallback2, ICryptoGetTextPassword2) + + // IProgress + STDMETHOD(SetTotal)(UInt64 size); + STDMETHOD(SetCompleted)(const UInt64 *completeValue); + + // IUpdateCallback2 + STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator); + STDMETHOD(GetUpdateItemInfo)(UInt32 index, + Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream); + STDMETHOD(SetOperationResult)(Int32 operationResult); + STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size); + STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream); + + STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password); + +public: + CRecordVector VolumesSizes; + UString VolName; + UString VolExt; + + UString DirPrefix; + const CObjectVector *DirItems; + + bool PasswordIsDefined; + UString Password; + bool AskPassword; + + bool m_NeedBeClosed; + + UStringVector FailedFiles; + CRecordVector FailedCodes; + + CArchiveUpdateCallback(): PasswordIsDefined(false), AskPassword(false), DirItems(0) {}; + + ~CArchiveUpdateCallback() { Finilize(); } + HRESULT Finilize(); + + void Init(const CObjectVector *dirItems) + { + DirItems = dirItems; + m_NeedBeClosed = false; + FailedFiles.Clear(); + FailedCodes.Clear(); + } +}; + +STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size) +{ + return S_OK; +} + +STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue) +{ + return S_OK; +} + + +STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **enumerator) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index, + Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive) +{ + if(newData != NULL) + *newData = BoolToInt(true); + if(newProperties != NULL) + *newProperties = BoolToInt(true); + if(indexInArchive != NULL) + *indexInArchive = UInt32(-1); + return S_OK; +} + +STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + + if (propID == kpidIsAnti) + { + propVariant = false; + propVariant.Detach(value); + return S_OK; + } + + { + const CDirItem &dirItem = (*DirItems)[index]; + switch(propID) + { + case kpidPath: + propVariant = dirItem.Name; + break; + case kpidIsFolder: + propVariant = dirItem.IsDirectory(); + break; + case kpidSize: + propVariant = dirItem.Size; + break; + case kpidAttributes: + propVariant = dirItem.Attributes; + break; + case kpidLastAccessTime: + propVariant = dirItem.LastAccessTime; + break; + case kpidCreationTime: + propVariant = dirItem.CreationTime; + break; + case kpidLastWriteTime: + propVariant = dirItem.LastWriteTime; + break; + } + } + propVariant.Detach(value); + return S_OK; +} + +HRESULT CArchiveUpdateCallback::Finilize() +{ + if (m_NeedBeClosed) + { + PrintNewLine(); + m_NeedBeClosed = false; + } + return S_OK; +} + +static void GetStream2(const wchar_t *name) +{ + PrintString("Compressing "); + if (name[0] == 0) + name = kEmptyFileAlias; + PrintString(name); +} + +STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream) +{ + RINOK(Finilize()); + + const CDirItem &dirItem = (*DirItems)[index]; + GetStream2(dirItem.Name); + + if(dirItem.IsDirectory()) + return S_OK; + + { + CInFileStream *inStreamSpec = new CInFileStream; + CMyComPtr inStreamLoc(inStreamSpec); + UString path = DirPrefix + dirItem.FullPath; + if(!inStreamSpec->Open(path)) + { + DWORD sysError = ::GetLastError(); + FailedCodes.Add(sysError); + FailedFiles.Add(path); + // if (systemError == ERROR_SHARING_VIOLATION) + { + PrintNewLine(); + PrintStringLn("WARNING: can't open file"); + // PrintString(NError::MyFormatMessageW(systemError)); + return S_FALSE; + } + // return sysError; + } + *inStream = inStreamLoc.Detach(); + } + return S_OK; +} + +STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 operationResult) +{ + m_NeedBeClosed = true; + return S_OK; +} + +STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size) +{ + if (VolumesSizes.Size() == 0) + return S_FALSE; + if (index >= (UInt32)VolumesSizes.Size()) + index = VolumesSizes.Size() - 1; + *size = VolumesSizes[index]; + return S_OK; +} + +STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream) +{ + wchar_t temp[32]; + ConvertUInt64ToString(index + 1, temp); + UString res = temp; + while (res.Length() < 2) + res = UString(L'0') + res; + UString fileName = VolName; + fileName += L'.'; + fileName += res; + fileName += VolExt; + COutFileStream *streamSpec = new COutFileStream; + CMyComPtr streamLoc(streamSpec); + if(!streamSpec->Create(fileName, false)) + return ::GetLastError(); + *volumeStream = streamLoc.Detach(); + return S_OK; +} + +STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) +{ + if (!PasswordIsDefined) + { + if (AskPassword) + { + // You can ask real password here from user + // Password = GetPassword(OutStream); + // PasswordIsDefined = true; + PrintStringLn("Password is not defined"); + return E_ABORT; + } + } + *passwordIsDefined = BoolToInt(PasswordIsDefined); + CMyComBSTR tempName(Password); + *password = tempName.Detach(); + return S_OK; +} + + + +////////////////////////////////////////////////////////////////////////// +// Main function + +int +#ifdef _MSC_VER +__cdecl +#endif +main(int argc, char* argv[]) +{ + #ifndef _UNICODE + g_IsNT = IsItWindowsNT(); + #endif + + PrintStringLn(kCopyrightString); + + if (argc < 3) + { + PrintStringLn(kHelpString); + return 1; + } + NWindows::NDLL::CLibrary library; + if (!library.Load(TEXT("7za.dll"))) + { + PrintStringLn("Can not load library"); + return 1; + } + CreateObjectFunc createObjectFunc = (CreateObjectFunc)library.GetProcAddress("CreateObject"); + if (createObjectFunc == 0) + { + PrintStringLn("Can not get CreateObject"); + return 1; + } + + AString command = argv[1]; + UString archiveName = GetUnicodeString(argv[2], CP_OEMCP); + if (command.CompareNoCase("a") == 0) + { + // create archive command + if (argc < 4) + { + PrintStringLn(kHelpString); + return 1; + } + CObjectVector dirItems; + int i; + for (i = 3; i < argc; i++) + { + CDirItem item; + UString name = GetUnicodeString(argv[i], CP_OEMCP); + + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(name, fileInfo)) + { + PrintString(UString(L"Can't find file") + name); + return 1; + } + + item.Attributes = fileInfo.Attributes; + item.Size = fileInfo.Size; + item.CreationTime = fileInfo.CreationTime; + item.LastAccessTime = fileInfo.LastAccessTime; + item.LastWriteTime = fileInfo.LastWriteTime; + item.Name = name; + item.FullPath = name; + dirItems.Add(item); + } + COutFileStream *outFileStreamSpec = new COutFileStream; + CMyComPtr outFileStream = outFileStreamSpec; + if (!outFileStreamSpec->Create(archiveName, false)) + { + PrintStringLn("can't create archive file"); + return 1; + } + + CMyComPtr outArchive; + if (createObjectFunc(&CLSID_CFormat7z, &IID_IOutArchive, (void **)&outArchive) != S_OK) + { + PrintStringLn("Can not get class object"); + return 1; + } + + CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; + CMyComPtr updateCallback(updateCallbackSpec); + updateCallbackSpec->Init(&dirItems); + // updateCallbackSpec->PasswordIsDefined = true; + // updateCallbackSpec->Password = L"1"; + + HRESULT result = outArchive->UpdateItems(outFileStream, dirItems.Size(), updateCallback); + updateCallbackSpec->Finilize(); + if (result != S_OK) + { + PrintStringLn("Update Error"); + return 1; + } + for (i = 0; i < updateCallbackSpec->FailedFiles.Size(); i++) + { + PrintNewLine(); + PrintString((UString)L"Error for file: " + updateCallbackSpec->FailedFiles[i]); + } + if (updateCallbackSpec->FailedFiles.Size() != 0) + return 1; + } + else + { + if (argc != 3) + { + PrintStringLn(kHelpString); + return 1; + } + + bool listCommand; + if (command.CompareNoCase("l") == 0) + listCommand = true; + else if (command.CompareNoCase("x") == 0) + listCommand = false; + else + { + PrintStringLn("incorrect command"); + return 1; + } + + CMyComPtr archive; + if (createObjectFunc(&CLSID_CFormat7z, &IID_IInArchive, (void **)&archive) != S_OK) + { + PrintStringLn("Can not get class object"); + return 1; + } + + CInFileStream *fileSpec = new CInFileStream; + CMyComPtr file = fileSpec; + + if (!fileSpec->Open(archiveName)) + { + PrintStringLn("Can not open archive file"); + return 1; + } + + { + CArchiveOpenCallback *openCallbackSpec = new CArchiveOpenCallback; + CMyComPtr openCallback(openCallbackSpec); + openCallbackSpec->PasswordIsDefined = false; + // openCallbackSpec->PasswordIsDefined = true; + // openCallbackSpec->Password = L"1"; + + if (archive->Open(file, 0, openCallback) != S_OK) + { + PrintStringLn("Can not open archive"); + return 1; + } + } + + if (listCommand) + { + // List command + UInt32 numItems = 0; + archive->GetNumberOfItems(&numItems); + for (UInt32 i = 0; i < numItems; i++) + { + { + // Get uncompressed size of file + NWindows::NCOM::CPropVariant propVariant; + archive->GetProperty(i, kpidSize, &propVariant); + UString s = ConvertPropVariantToString(propVariant); + PrintString(s); + PrintString(" "); + } + { + // Get name of file + NWindows::NCOM::CPropVariant propVariant; + archive->GetProperty(i, kpidPath, &propVariant); + UString s = ConvertPropVariantToString(propVariant); + PrintString(s); + } + PrintString("\n"); + } + } + else + { + // Extract command + CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback; + CMyComPtr extractCallback(extractCallbackSpec); + extractCallbackSpec->Init(archive, L""); // second parameter is output folder path + extractCallbackSpec->PasswordIsDefined = false; + // extractCallbackSpec->PasswordIsDefined = true; + // extractCallbackSpec->Password = L"1"; + archive->Extract(0, (UInt32)(Int32)(-1), false, extractCallback); + } + } + return 0; +} diff --git a/CPP/7zip/UI/Client7z/Client7z.dsp b/CPP/7zip/UI/Client7z/Client7z.dsp new file mode 100755 index 00000000..b574bdb7 --- /dev/null +++ b/CPP/7zip/UI/Client7z/Client7z.dsp @@ -0,0 +1,226 @@ +# Microsoft Developer Studio Project File - Name="Client7z" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=Client7z - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Client7z.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Client7z.mak" CFG="Client7z - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Client7z - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "Client7z - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Client7z - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "Client7z - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Client7z - Win32 Release" +# Name "Client7z - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"stdafx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\Client7z.cpp +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/UI/Client7z/Client7z.dsw b/CPP/7zip/UI/Client7z/Client7z.dsw new file mode 100755 index 00000000..598a6d3f --- /dev/null +++ b/CPP/7zip/UI/Client7z/Client7z.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Client7z"=.\Client7z.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/UI/Client7z/StdAfx.cpp b/CPP/7zip/UI/Client7z/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/UI/Client7z/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/UI/Client7z/StdAfx.h b/CPP/7zip/UI/Client7z/StdAfx.h new file mode 100755 index 00000000..b23436e9 --- /dev/null +++ b/CPP/7zip/UI/Client7z/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include +#include + +#endif diff --git a/CPP/7zip/UI/Client7z/makefile b/CPP/7zip/UI/Client7z/makefile new file mode 100755 index 00000000..c4ae0aaf --- /dev/null +++ b/CPP/7zip/UI/Client7z/makefile @@ -0,0 +1,45 @@ +PROG = 7z.exe +LIBS = $(LIBS) user32.lib oleaut32.lib advapi32.lib +CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_MT + +CONSOLE_OBJS = \ + $O\Client7z.obj \ + +COMMON_OBJS = \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\Vector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\PropVariant.obj \ + $O\PropVariantConversions.obj \ + +7ZIP_COMMON_OBJS = \ + $O\FileStreams.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(CONSOLE_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + +!include "../../../Build.mak" + +$(CONSOLE_OBJS): $(*B).cpp + $(COMPL_O1_W3) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp new file mode 100755 index 00000000..6f951a27 --- /dev/null +++ b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp @@ -0,0 +1,985 @@ +// ArchiveCommandLine.cpp + +#include "StdAfx.h" + +#include +#include + +#include "Common/ListFileUtils.h" +#include "Common/StringConvert.h" +#include "Common/StringToInt.h" + +#include "Windows/FileName.h" +#include "Windows/FileDir.h" +#ifdef _WIN32 +#include "Windows/FileMapping.h" +#include "Windows/Synchronization.h" +#endif + +#include "ArchiveCommandLine.h" +#include "UpdateAction.h" +#include "Update.h" +#include "ArchiverInfo.h" +#include "SortUtils.h" +#include "EnumDirItems.h" + +using namespace NCommandLineParser; +using namespace NWindows; +using namespace NFile; + +static const int kNumSwitches = 28; + +namespace NKey { +enum Enum +{ + kHelp1 = 0, + kHelp2, + kHelp3, + kDisableHeaders, + kDisablePercents, + kArchiveType, + kYes, + kPassword, + kProperty, + kOutputDir, + kWorkingDir, + kInclude, + kExclude, + kArInclude, + kArExclude, + kNoArName, + kUpdate, + kVolume, + kRecursed, + kSfx, + kStdIn, + kStdOut, + kOverwrite, + kEmail, + kShowDialog, + kLargePages, + kCharSet, + kTechMode +}; + +} + + +static const wchar_t kRecursedIDChar = 'R'; +static const wchar_t *kRecursedPostCharSet = L"0-"; + +static const wchar_t *kDefaultArchiveType = L"7z"; +static const wchar_t *kSFXExtension = + #ifdef _WIN32 + L"exe"; + #else + L""; + #endif + +namespace NRecursedPostCharIndex { + enum EEnum + { + kWildCardRecursionOnly = 0, + kNoRecursion = 1 + }; +} + +static const char kImmediateNameID = '!'; +static const char kMapNameID = '#'; +static const char kFileListID = '@'; + +static const char kSomeCludePostStringMinSize = 2; // at least <@|!>ame must be +static const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!>ame must be + +static const wchar_t *kOverwritePostCharSet = L"asut"; + +NExtract::NOverwriteMode::EEnum k_OverwriteModes[] = +{ + NExtract::NOverwriteMode::kWithoutPrompt, + NExtract::NOverwriteMode::kSkipExisting, + NExtract::NOverwriteMode::kAutoRename, + NExtract::NOverwriteMode::kAutoRenameExisting +}; + +static const CSwitchForm kSwitchForms[kNumSwitches] = + { + { L"?", NSwitchType::kSimple, false }, + { L"H", NSwitchType::kSimple, false }, + { L"-HELP", NSwitchType::kSimple, false }, + { L"BA", NSwitchType::kSimple, false }, + { L"BD", NSwitchType::kSimple, false }, + { L"T", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"Y", NSwitchType::kSimple, false }, + { L"P", NSwitchType::kUnLimitedPostString, false, 0 }, + { L"M", NSwitchType::kUnLimitedPostString, true, 1 }, + { L"O", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"W", NSwitchType::kUnLimitedPostString, false, 0 }, + { L"I", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize}, + { L"X", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize}, + { L"AI", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize}, + { L"AX", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize}, + { L"AN", NSwitchType::kSimple, false }, + { L"U", NSwitchType::kUnLimitedPostString, true, 1}, + { L"V", NSwitchType::kUnLimitedPostString, true, 1}, + { L"R", NSwitchType::kPostChar, false, 0, 0, kRecursedPostCharSet }, + { L"SFX", NSwitchType::kUnLimitedPostString, false, 0 }, + { L"SI", NSwitchType::kUnLimitedPostString, false, 0 }, + { L"SO", NSwitchType::kSimple, false, 0 }, + { L"AO", NSwitchType::kPostChar, false, 1, 1, kOverwritePostCharSet}, + { L"SEML", NSwitchType::kUnLimitedPostString, false, 0}, + { L"AD", NSwitchType::kSimple, false }, + { L"SLP", NSwitchType::kUnLimitedPostString, false, 0}, + { L"SCS", NSwitchType::kUnLimitedPostString, false, 0}, + { L"SLT", NSwitchType::kSimple, false } + }; + +static const int kNumCommandForms = 7; + +static const CCommandForm g_CommandForms[kNumCommandForms] = +{ + { L"A", false }, + { L"U", false }, + { L"D", false }, + { L"T", false }, + { L"E", false }, + { L"X", false }, + { L"L", false } +}; + +static const int kMaxCmdLineSize = 1000; +static const wchar_t *kUniversalWildcard = L"*"; +static const int kMinNonSwitchWords = 1; +static const int kCommandIndex = 0; + +// --------------------------- +// exception messages + +static const char *kUserErrorMessage = "Incorrect command line"; +static const char *kIncorrectListFile = "Incorrect wildcard in listfile"; +static const char *kIncorrectWildCardInListFile = "Incorrect wildcard in listfile"; +static const char *kIncorrectWildCardInCommandLine = "Incorrect wildcard in command line"; +static const char *kTerminalOutError = "I won't write compressed data to a terminal"; +static const char *kSameTerminalError = "I won't write data and program's messages to same terminal"; + +static void ThrowException(const char *errorMessage) +{ + throw CArchiveCommandLineException(errorMessage); +}; + +static void ThrowUserErrorException() +{ + ThrowException(kUserErrorMessage); +}; + +// --------------------------- + +bool CArchiveCommand::IsFromExtractGroup() const +{ + switch(CommandType) + { + case NCommandType::kTest: + case NCommandType::kExtract: + case NCommandType::kFullExtract: + return true; + default: + return false; + } +} + +NExtract::NPathMode::EEnum CArchiveCommand::GetPathMode() const +{ + switch(CommandType) + { + case NCommandType::kTest: + case NCommandType::kFullExtract: + return NExtract::NPathMode::kFullPathnames; + default: + return NExtract::NPathMode::kNoPathnames; + } +} + +bool CArchiveCommand::IsFromUpdateGroup() const +{ + return (CommandType == NCommandType::kAdd || + CommandType == NCommandType::kUpdate || + CommandType == NCommandType::kDelete); +} + +static NRecursedType::EEnum GetRecursedTypeFromIndex(int index) +{ + switch (index) + { + case NRecursedPostCharIndex::kWildCardRecursionOnly: + return NRecursedType::kWildCardOnlyRecursed; + case NRecursedPostCharIndex::kNoRecursion: + return NRecursedType::kNonRecursed; + default: + return NRecursedType::kRecursed; + } +} + +static bool ParseArchiveCommand(const UString &commandString, CArchiveCommand &command) +{ + UString commandStringUpper = commandString; + commandStringUpper.MakeUpper(); + UString postString; + int commandIndex = ParseCommand(kNumCommandForms, g_CommandForms, commandStringUpper, + postString) ; + if (commandIndex < 0) + return false; + command.CommandType = (NCommandType::EEnum)commandIndex; + return true; +} + +// ------------------------------------------------------------------ +// filenames functions + +static bool AddNameToCensor(NWildcard::CCensor &wildcardCensor, + const UString &name, bool include, NRecursedType::EEnum type) +{ + bool isWildCard = DoesNameContainWildCard(name); + bool recursed = false; + + switch (type) + { + case NRecursedType::kWildCardOnlyRecursed: + recursed = isWildCard; + break; + case NRecursedType::kRecursed: + recursed = true; + break; + case NRecursedType::kNonRecursed: + recursed = false; + break; + } + wildcardCensor.AddItem(include, name, recursed); + return true; +} + +static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; } + +static void AddToCensorFromListFile(NWildcard::CCensor &wildcardCensor, + LPCWSTR fileName, bool include, NRecursedType::EEnum type, UINT codePage) +{ + UStringVector names; + if (!ReadNamesFromListFile(GetSystemString(fileName, GetCurrentCodePage()), names, codePage)) + throw kIncorrectListFile; + for (int i = 0; i < names.Size(); i++) + if (!AddNameToCensor(wildcardCensor, names[i], include, type)) + throw kIncorrectWildCardInListFile; +} + +static void AddCommandLineWildCardToCensr(NWildcard::CCensor &wildcardCensor, + const UString &name, bool include, NRecursedType::EEnum recursedType) +{ + if (!AddNameToCensor(wildcardCensor, name, include, recursedType)) + throw kIncorrectWildCardInCommandLine; +} + +static void AddToCensorFromNonSwitchesStrings( + int startIndex, + NWildcard::CCensor &wildcardCensor, + const UStringVector &nonSwitchStrings, NRecursedType::EEnum type, + bool thereAreSwitchIncludes, UINT codePage) +{ + if(nonSwitchStrings.Size() == startIndex && (!thereAreSwitchIncludes)) + AddCommandLineWildCardToCensr(wildcardCensor, kUniversalWildcard, true, type); + for(int i = startIndex; i < nonSwitchStrings.Size(); i++) + { + const UString &s = nonSwitchStrings[i]; + if (s[0] == kFileListID) + AddToCensorFromListFile(wildcardCensor, s.Mid(1), true, type, codePage); + else + AddCommandLineWildCardToCensr(wildcardCensor, s, true, type); + } +} + +#ifdef _WIN32 +static void ParseMapWithPaths(NWildcard::CCensor &wildcardCensor, + const UString &switchParam, bool include, + NRecursedType::EEnum commonRecursedType) +{ + int splitPos = switchParam.Find(L':'); + if (splitPos < 0) + ThrowUserErrorException(); + UString mappingName = switchParam.Left(splitPos); + + UString switchParam2 = switchParam.Mid(splitPos + 1); + splitPos = switchParam2.Find(L':'); + if (splitPos < 0) + ThrowUserErrorException(); + + UString mappingSize = switchParam2.Left(splitPos); + UString eventName = switchParam2.Mid(splitPos + 1); + + UInt64 dataSize64 = ConvertStringToUInt64(mappingSize, NULL); + UInt32 dataSize = (UInt32)dataSize64; + { + CFileMapping fileMapping; + if (!fileMapping.Open(FILE_MAP_READ, false, GetSystemString(mappingName))) + ThrowException("Can not open mapping"); + LPVOID data = fileMapping.MapViewOfFile(FILE_MAP_READ, 0, dataSize); + if (data == NULL) + ThrowException("MapViewOfFile error"); + try + { + const wchar_t *curData = (const wchar_t *)data; + if (*curData != 0) + ThrowException("Incorrect mapping data"); + UInt32 numChars = dataSize / sizeof(wchar_t); + UString name; + for (UInt32 i = 1; i < numChars; i++) + { + wchar_t c = curData[i]; + if (c == L'\0') + { + AddCommandLineWildCardToCensr(wildcardCensor, + name, include, commonRecursedType); + name.Empty(); + } + else + name += c; + } + if (!name.IsEmpty()) + ThrowException("data error"); + } + catch(...) + { + UnmapViewOfFile(data); + throw; + } + UnmapViewOfFile(data); + } + + { + NSynchronization::CEvent event; + event.Open(EVENT_MODIFY_STATE, false, GetSystemString(eventName)); + event.Set(); + } +} +#endif + +static void AddSwitchWildCardsToCensor(NWildcard::CCensor &wildcardCensor, + const UStringVector &strings, bool include, + NRecursedType::EEnum commonRecursedType, UINT codePage) +{ + for(int i = 0; i < strings.Size(); i++) + { + const UString &name = strings[i]; + NRecursedType::EEnum recursedType; + int pos = 0; + if (name.Length() < kSomeCludePostStringMinSize) + ThrowUserErrorException(); + if (::MyCharUpper(name[pos]) == kRecursedIDChar) + { + pos++; + int index = UString(kRecursedPostCharSet).Find(name[pos]); + recursedType = GetRecursedTypeFromIndex(index); + if (index >= 0) + pos++; + } + else + recursedType = commonRecursedType; + if (name.Length() < pos + kSomeCludeAfterRecursedPostStringMinSize) + ThrowUserErrorException(); + UString tail = name.Mid(pos + 1); + if (name[pos] == kImmediateNameID) + AddCommandLineWildCardToCensr(wildcardCensor, tail, include, recursedType); + else if (name[pos] == kFileListID) + AddToCensorFromListFile(wildcardCensor, tail, include, recursedType, codePage); + #ifdef _WIN32 + else if (name[pos] == kMapNameID) + ParseMapWithPaths(wildcardCensor, tail, include, recursedType); + #endif + else + ThrowUserErrorException(); + } +} + +#ifdef _WIN32 + +// This code converts all short file names to long file names. + +static void ConvertToLongName(const UString &prefix, UString &name) +{ + if (name.IsEmpty() || DoesNameContainWildCard(name)) + return; + NFind::CFileInfoW fileInfo; + if (NFind::FindFile(prefix + name, fileInfo)) + name = fileInfo.Name; +} + +static void ConvertToLongNames(const UString &prefix, CObjectVector &items) +{ + for (int i = 0; i < items.Size(); i++) + { + NWildcard::CItem &item = items[i]; + if (item.Recursive || item.PathParts.Size() != 1) + continue; + ConvertToLongName(prefix, item.PathParts.Front()); + } +} + +static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &node) +{ + ConvertToLongNames(prefix, node.IncludeItems); + ConvertToLongNames(prefix, node.ExcludeItems); + int i; + for (i = 0; i < node.SubNodes.Size(); i++) + ConvertToLongName(prefix, node.SubNodes[i].Name); + // mix folders with same name + for (i = 0; i < node.SubNodes.Size(); i++) + { + NWildcard::CCensorNode &nextNode1 = node.SubNodes[i]; + for (int j = i + 1; j < node.SubNodes.Size();) + { + const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j]; + if (nextNode1.Name.CompareNoCase(nextNode2.Name) == 0) + { + nextNode1.IncludeItems += nextNode2.IncludeItems; + nextNode1.ExcludeItems += nextNode2.ExcludeItems; + node.SubNodes.Delete(j); + } + else + j++; + } + } + for (i = 0; i < node.SubNodes.Size(); i++) + { + NWildcard::CCensorNode &nextNode = node.SubNodes[i]; + ConvertToLongNames(prefix + nextNode.Name + wchar_t(NFile::NName::kDirDelimiter), nextNode); + } +} + +static void ConvertToLongNames(NWildcard::CCensor &censor) +{ + for (int i = 0; i < censor.Pairs.Size(); i++) + { + NWildcard::CPair &pair = censor.Pairs[i]; + ConvertToLongNames(pair.Prefix, pair.Head); + } +} + +#endif + +static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i) +{ + switch(i) + { + case NUpdateArchive::NPairAction::kIgnore: return NUpdateArchive::NPairAction::kIgnore; + case NUpdateArchive::NPairAction::kCopy: return NUpdateArchive::NPairAction::kCopy; + case NUpdateArchive::NPairAction::kCompress: return NUpdateArchive::NPairAction::kCompress; + case NUpdateArchive::NPairAction::kCompressAsAnti: return NUpdateArchive::NPairAction::kCompressAsAnti; + } + throw 98111603; +} + +const UString kUpdatePairStateIDSet = L"PQRXYZW"; +const int kUpdatePairStateNotSupportedActions[] = {2, 2, 1, -1, -1, -1, -1}; + +const UString kUpdatePairActionIDSet = L"0123"; //Ignore, Copy, Compress, Create Anti + +const wchar_t *kUpdateIgnoreItselfPostStringID = L"-"; +const wchar_t kUpdateNewArchivePostCharID = '!'; + + +static bool ParseUpdateCommandString2(const UString &command, + NUpdateArchive::CActionSet &actionSet, UString &postString) +{ + for(int i = 0; i < command.Length();) + { + wchar_t c = MyCharUpper(command[i]); + int statePos = kUpdatePairStateIDSet.Find(c); + if (statePos < 0) + { + postString = command.Mid(i); + return true; + } + i++; + if (i >= command.Length()) + return false; + int actionPos = kUpdatePairActionIDSet.Find(::MyCharUpper(command[i])); + if (actionPos < 0) + return false; + actionSet.StateActions[statePos] = GetUpdatePairActionType(actionPos); + if (kUpdatePairStateNotSupportedActions[statePos] == actionPos) + return false; + i++; + } + postString.Empty(); + return true; +} + +static void ParseUpdateCommandString(CUpdateOptions &options, + const UStringVector &updatePostStrings, + const NUpdateArchive::CActionSet &defaultActionSet) +{ + for(int i = 0; i < updatePostStrings.Size(); i++) + { + const UString &updateString = updatePostStrings[i]; + if(updateString.CompareNoCase(kUpdateIgnoreItselfPostStringID) == 0) + { + if(options.UpdateArchiveItself) + { + options.UpdateArchiveItself = false; + options.Commands.Delete(0); + } + } + else + { + NUpdateArchive::CActionSet actionSet = defaultActionSet; + + UString postString; + if (!ParseUpdateCommandString2(updateString, actionSet, postString)) + ThrowUserErrorException(); + if(postString.IsEmpty()) + { + if(options.UpdateArchiveItself) + options.Commands[0].ActionSet = actionSet; + } + else + { + if(MyCharUpper(postString[0]) != kUpdateNewArchivePostCharID) + ThrowUserErrorException(); + CUpdateArchiveCommand uc; + UString archivePath = postString.Mid(1); + if (archivePath.IsEmpty()) + ThrowUserErrorException(); + uc.ArchivePath.BaseExtension = options.ArchivePath.BaseExtension; + uc.ArchivePath.VolExtension = options.ArchivePath.VolExtension; + uc.ArchivePath.ParseFromPath(archivePath); + uc.ActionSet = actionSet; + options.Commands.Add(uc); + } + } + } +} + +static const char kByteSymbol = 'B'; +static const char kKiloSymbol = 'K'; +static const char kMegaSymbol = 'M'; +static const char kGigaSymbol = 'G'; + +static bool ParseComplexSize(const UString &src, UInt64 &result) +{ + UString s = src; + s.MakeUpper(); + + const wchar_t *start = s; + const wchar_t *end; + UInt64 number = ConvertStringToUInt64(start, &end); + int numDigits = (int)(end - start); + if (numDigits == 0 || s.Length() > numDigits + 1) + return false; + if (s.Length() == numDigits) + { + result = number; + return true; + } + int numBits; + switch (s[numDigits]) + { + case kByteSymbol: + result = number; + return true; + case kKiloSymbol: + numBits = 10; + break; + case kMegaSymbol: + numBits = 20; + break; + case kGigaSymbol: + numBits = 30; + break; + default: + return false; + } + if (number >= ((UInt64)1 << (64 - numBits))) + return false; + result = number << numBits; + return true; +} + +static void SetAddCommandOptions( + NCommandType::EEnum commandType, + const CParser &parser, + CUpdateOptions &options) +{ + NUpdateArchive::CActionSet defaultActionSet; + switch(commandType) + { + case NCommandType::kAdd: + defaultActionSet = NUpdateArchive::kAddActionSet; + break; + case NCommandType::kDelete: + defaultActionSet = NUpdateArchive::kDeleteActionSet; + break; + default: + defaultActionSet = NUpdateArchive::kUpdateActionSet; + } + + options.UpdateArchiveItself = true; + + options.Commands.Clear(); + CUpdateArchiveCommand updateMainCommand; + updateMainCommand.ActionSet = defaultActionSet; + options.Commands.Add(updateMainCommand); + if(parser[NKey::kUpdate].ThereIs) + ParseUpdateCommandString(options, parser[NKey::kUpdate].PostStrings, + defaultActionSet); + if(parser[NKey::kWorkingDir].ThereIs) + { + const UString &postString = parser[NKey::kWorkingDir].PostStrings[0]; + if (postString.IsEmpty()) + NDirectory::MyGetTempPath(options.WorkingDir); + else + options.WorkingDir = postString; + } + options.SfxMode = parser[NKey::kSfx].ThereIs; + if (options.SfxMode) + options.SfxModule = parser[NKey::kSfx].PostStrings[0]; + + if (parser[NKey::kVolume].ThereIs) + { + const UStringVector &sv = parser[NKey::kVolume].PostStrings; + for (int i = 0; i < sv.Size(); i++) + { + UInt64 size; + if (!ParseComplexSize(sv[i], size)) + ThrowException("Incorrect volume size"); + options.VolumesSizes.Add(size); + } + } +} + +static void SetMethodOptions(const CParser &parser, CObjectVector &properties) +{ + if (parser[NKey::kProperty].ThereIs) + { + // options.MethodMode.Properties.Clear(); + for(int i = 0; i < parser[NKey::kProperty].PostStrings.Size(); i++) + { + CProperty property; + const UString &postString = parser[NKey::kProperty].PostStrings[i]; + int index = postString.Find(L'='); + if (index < 0) + property.Name = postString; + else + { + property.Name = postString.Left(index); + property.Value = postString.Mid(index + 1); + } + properties.Add(property); + } + } +} + + +static void SetArchiveType(const UString &archiveType, +#ifndef EXCLUDE_COM + UString &filePath, CLSID &classID, +#else + UString &formatName, +#endif + UString &archiveExtension) +{ + CObjectVector archiverInfoVector; + ReadArchiverInfoList(archiverInfoVector); + if (archiverInfoVector.Size() == 0) + ThrowException("There are no installed archive handlers"); + if (archiveType.IsEmpty()) + ThrowException("Incorrect archive type was assigned"); + for (int i = 0; i < archiverInfoVector.Size(); i++) + { + const CArchiverInfo &archiverInfo = archiverInfoVector[i]; + if (archiverInfo.Name.CompareNoCase(archiveType) == 0) + { + #ifndef EXCLUDE_COM + classID = archiverInfo.ClassID; + filePath = archiverInfo.FilePath; + #else + formatName = archiverInfo.Name; + + #endif + + archiveExtension = archiverInfo.GetMainExtension(); + return; + } + } + ThrowException("Incorrect archive type was assigned"); +} + + +CArchiveCommandLineParser::CArchiveCommandLineParser(): parser(kNumSwitches) {} + +void CArchiveCommandLineParser::Parse1(const UStringVector &commandStrings, + CArchiveCommandLineOptions &options) +{ + try + { + parser.ParseStrings(kSwitchForms, commandStrings); + } + catch(...) + { + ThrowUserErrorException(); + } + + options.IsInTerminal = (_isatty(_fileno(stdin)) != 0); + options.IsStdOutTerminal = (_isatty(_fileno(stdout)) != 0); + options.IsStdErrTerminal = (_isatty(_fileno(stderr)) != 0); + options.StdOutMode = parser[NKey::kStdOut].ThereIs; + options.EnableHeaders = !parser[NKey::kDisableHeaders].ThereIs; + options.HelpMode = parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs || parser[NKey::kHelp3].ThereIs; + + #ifdef _WIN32 + options.LargePages = false; + if (parser[NKey::kLargePages].ThereIs) + { + const UString &postString = parser[NKey::kLargePages].PostStrings.Front(); + if (postString.IsEmpty()) + options.LargePages = true; + } + #endif +} + +struct CCodePagePair +{ + const wchar_t *Name; + UINT CodePage; +}; + +static CCodePagePair g_CodePagePairs[] = +{ + { L"UTF-8", CP_UTF8 }, + { L"WIN", CP_ACP }, + { L"DOS", CP_OEMCP } +}; + +static const int kNumCodePages = sizeof(g_CodePagePairs) / sizeof(g_CodePagePairs[0]); + +void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options) +{ + const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; + int numNonSwitchStrings = nonSwitchStrings.Size(); + if(numNonSwitchStrings < kMinNonSwitchWords) + ThrowUserErrorException(); + + if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], options.Command)) + ThrowUserErrorException(); + + options.TechMode = parser[NKey::kTechMode].ThereIs; + + NRecursedType::EEnum recursedType; + if (parser[NKey::kRecursed].ThereIs) + recursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex); + else + recursedType = NRecursedType::kNonRecursed; + + UINT codePage = CP_UTF8; + if (parser[NKey::kCharSet].ThereIs) + { + UString name = parser[NKey::kCharSet].PostStrings.Front(); + name.MakeUpper(); + int i; + for (i = 0; i < kNumCodePages; i++) + { + const CCodePagePair &pair = g_CodePagePairs[i]; + if (name.Compare(pair.Name) == 0) + { + codePage = pair.CodePage; + break; + } + } + if (i >= kNumCodePages) + ThrowUserErrorException(); + } + + bool thereAreSwitchIncludes = false; + if (parser[NKey::kInclude].ThereIs) + { + thereAreSwitchIncludes = true; + AddSwitchWildCardsToCensor(options.WildcardCensor, + parser[NKey::kInclude].PostStrings, true, recursedType, codePage); + } + if (parser[NKey::kExclude].ThereIs) + AddSwitchWildCardsToCensor(options.WildcardCensor, + parser[NKey::kExclude].PostStrings, false, recursedType, codePage); + + int curCommandIndex = kCommandIndex + 1; + bool thereIsArchiveName = !parser[NKey::kNoArName].ThereIs; + if (thereIsArchiveName) + { + if(curCommandIndex >= numNonSwitchStrings) + ThrowUserErrorException(); + options.ArchiveName = nonSwitchStrings[curCommandIndex++]; + } + + AddToCensorFromNonSwitchesStrings( + curCommandIndex, options.WildcardCensor, + nonSwitchStrings, recursedType, thereAreSwitchIncludes, codePage); + + options.YesToAll = parser[NKey::kYes].ThereIs; + + bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); + + options.PasswordEnabled = parser[NKey::kPassword].ThereIs; + + if(options.PasswordEnabled) + options.Password = parser[NKey::kPassword].PostStrings[0]; + + options.StdInMode = parser[NKey::kStdIn].ThereIs; + options.ShowDialog = parser[NKey::kShowDialog].ThereIs; + + if(isExtractGroupCommand || options.Command.CommandType == NCommandType::kList) + { + if (options.StdInMode) + ThrowException("Reading archives from stdin is not implemented"); + if (!options.WildcardCensor.AllAreRelative()) + ThrowException("Cannot use absolute pathnames for this command"); + + NWildcard::CCensor archiveWildcardCensor; + + if (parser[NKey::kArInclude].ThereIs) + { + AddSwitchWildCardsToCensor(archiveWildcardCensor, + parser[NKey::kArInclude].PostStrings, true, NRecursedType::kNonRecursed, codePage); + } + if (parser[NKey::kArExclude].ThereIs) + AddSwitchWildCardsToCensor(archiveWildcardCensor, + parser[NKey::kArExclude].PostStrings, false, NRecursedType::kNonRecursed, codePage); + + if (thereIsArchiveName) + AddCommandLineWildCardToCensr(archiveWildcardCensor, options.ArchiveName, true, NRecursedType::kNonRecursed); + + #ifdef _WIN32 + ConvertToLongNames(archiveWildcardCensor); + #endif + + archiveWildcardCensor.ExtendExclude(); + + CObjectVector dirItems; + { + UStringVector errorPaths; + CRecordVector errorCodes; + HRESULT res = EnumerateItems(archiveWildcardCensor, dirItems, NULL, errorPaths, errorCodes); + if (res != S_OK || errorPaths.Size() > 0) + throw "cannot find archive"; + } + UStringVector archivePaths; + int i; + for (i = 0; i < dirItems.Size(); i++) + { + const CDirItem &dirItem = dirItems[i]; + if (!dirItem.IsDirectory()) + archivePaths.Add(dirItem.FullPath); + } + + if (archivePaths.Size() == 0) + throw "there is no such archive"; + + UStringVector archivePathsFull; + + for (i = 0; i < archivePaths.Size(); i++) + { + UString fullPath; + NFile::NDirectory::MyGetFullPathName(archivePaths[i], fullPath); + archivePathsFull.Add(fullPath); + } + CIntVector indices; + SortStringsToIndices(archivePathsFull, indices); + options.ArchivePathsSorted.Reserve(indices.Size()); + options.ArchivePathsFullSorted.Reserve(indices.Size()); + for (i = 0; i < indices.Size(); i++) + { + options.ArchivePathsSorted.Add(archivePaths[indices[i]]); + options.ArchivePathsFullSorted.Add(archivePathsFull[indices[i]]); + } + + if (isExtractGroupCommand) + { + SetMethodOptions(parser, options.ExtractProperties); + if (options.StdOutMode && options.IsStdOutTerminal && options.IsStdErrTerminal) + throw kSameTerminalError; + if(parser[NKey::kOutputDir].ThereIs) + { + options.OutputDir = parser[NKey::kOutputDir].PostStrings[0]; + NFile::NName::NormalizeDirPathPrefix(options.OutputDir); + } + + options.OverwriteMode = NExtract::NOverwriteMode::kAskBefore; + if(parser[NKey::kOverwrite].ThereIs) + options.OverwriteMode = + k_OverwriteModes[parser[NKey::kOverwrite].PostCharIndex]; + else if (options.YesToAll) + options.OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt; + } + } + else if(options.Command.IsFromUpdateGroup()) + { + CUpdateOptions &updateOptions = options.UpdateOptions; + + UString archiveType; + if(parser[NKey::kArchiveType].ThereIs) + archiveType = parser[NKey::kArchiveType].PostStrings[0]; + else + archiveType = kDefaultArchiveType; + + UString typeExtension; + if (!archiveType.IsEmpty()) + { + #ifndef EXCLUDE_COM + SetArchiveType(archiveType, updateOptions.MethodMode.FilePath, + updateOptions.MethodMode.ClassID, typeExtension); + #else + SetArchiveType(archiveType, updateOptions.MethodMode.Name, typeExtension); + #endif + } + UString extension = typeExtension; + if(parser[NKey::kSfx].ThereIs) + extension = kSFXExtension; + updateOptions.ArchivePath.BaseExtension = extension; + updateOptions.ArchivePath.VolExtension = typeExtension; + updateOptions.ArchivePath.ParseFromPath(options.ArchiveName); + SetAddCommandOptions(options.Command.CommandType, parser, updateOptions); + + SetMethodOptions(parser, updateOptions.MethodMode.Properties); + + options.EnablePercents = !parser[NKey::kDisablePercents].ThereIs; + + if (options.EnablePercents) + { + if ((options.StdOutMode && !options.IsStdErrTerminal) || + (!options.StdOutMode && !options.IsStdOutTerminal)) + options.EnablePercents = false; + } + + updateOptions.EMailMode = parser[NKey::kEmail].ThereIs; + if (updateOptions.EMailMode) + { + updateOptions.EMailAddress = parser[NKey::kEmail].PostStrings.Front(); + if (updateOptions.EMailAddress.Length() > 0) + if (updateOptions.EMailAddress[0] == L'.') + { + updateOptions.EMailRemoveAfter = true; + updateOptions.EMailAddress.Delete(0); + } + } + + updateOptions.StdOutMode = options.StdOutMode; + updateOptions.StdInMode = options.StdInMode; + + if (updateOptions.StdOutMode && updateOptions.EMailMode) + throw "stdout mode and email mode cannot be combined"; + if (updateOptions.StdOutMode && options.IsStdOutTerminal) + throw kTerminalOutError; + if(updateOptions.StdInMode) + updateOptions.StdInFileName = parser[NKey::kStdIn].PostStrings.Front(); + + #ifdef _WIN32 + ConvertToLongNames(options.WildcardCensor); + #endif + } + else + ThrowUserErrorException(); + options.WildcardCensor.ExtendExclude(); +} diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.h b/CPP/7zip/UI/Common/ArchiveCommandLine.h new file mode 100755 index 00000000..daa66fb6 --- /dev/null +++ b/CPP/7zip/UI/Common/ArchiveCommandLine.h @@ -0,0 +1,95 @@ +// ArchiveCommandLine.h + +#ifndef __ARCHIVECOMMANDLINE_H +#define __ARCHIVECOMMANDLINE_H + +#include "Common/Wildcard.h" +#include "Common/CommandLineParser.h" + +#include "Extract.h" +#include "Update.h" + +struct CArchiveCommandLineException: public AString +{ + CArchiveCommandLineException(const char *errorMessage): AString(errorMessage) {} +}; + +namespace NCommandType { enum EEnum +{ + kAdd = 0, + kUpdate, + kDelete, + kTest, + kExtract, + kFullExtract, + kList +};} + +namespace NRecursedType { enum EEnum +{ + kRecursed, + kWildCardOnlyRecursed, + kNonRecursed, +};} + +struct CArchiveCommand +{ + NCommandType::EEnum CommandType; + bool IsFromExtractGroup() const; + bool IsFromUpdateGroup() const; + bool IsTestMode() const { return CommandType == NCommandType::kTest; } + NExtract::NPathMode::EEnum GetPathMode() const; +}; + +struct CArchiveCommandLineOptions +{ + bool HelpMode; + + #ifdef _WIN32 + bool LargePages; + #endif + + bool IsInTerminal; + bool IsStdOutTerminal; + bool IsStdErrTerminal; + bool StdInMode; + bool StdOutMode; + bool EnableHeaders; + + bool YesToAll; + bool ShowDialog; + // NWildcard::CCensor ArchiveWildcardCensor; + NWildcard::CCensor WildcardCensor; + + CArchiveCommand Command; + UString ArchiveName; + + bool PasswordEnabled; + UString Password; + + bool TechMode; + // Extract + bool AppendName; + UString OutputDir; + NExtract::NOverwriteMode::EEnum OverwriteMode; + UStringVector ArchivePathsSorted; + UStringVector ArchivePathsFullSorted; + CObjectVector ExtractProperties; + + CUpdateOptions UpdateOptions; + bool EnablePercents; + + CArchiveCommandLineOptions(): StdInMode(false), StdOutMode(false) {}; + +}; + +class CArchiveCommandLineParser +{ + NCommandLineParser::CParser parser; +public: + CArchiveCommandLineParser(); + void Parse1(const UStringVector &commandStrings, CArchiveCommandLineOptions &options); + void Parse2(CArchiveCommandLineOptions &options); +}; + +#endif diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp new file mode 100755 index 00000000..05520fed --- /dev/null +++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp @@ -0,0 +1,448 @@ +// ArchiveExtractCallback.cpp + +#include "StdAfx.h" + +#include "ArchiveExtractCallback.h" + +#include "Common/Wildcard.h" +#include "Common/StringConvert.h" +#include "Common/ComTry.h" + +#include "Windows/FileDir.h" +#include "Windows/FileFind.h" +#include "Windows/Time.h" +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" + +#include "Windows/PropVariantConversions.h" + +#include "../../Common/FilePathAutoRename.h" + +#include "../Common/ExtractingFilePath.h" +#include "OpenArchive.h" + +using namespace NWindows; + +static const wchar_t *kCantAutoRename = L"ERROR: Can not create file with auto name"; +static const wchar_t *kCantRenameFile = L"ERROR: Can not rename existing file "; +static const wchar_t *kCantDeleteOutputFile = L"ERROR: Can not delete output file "; + + +void CArchiveExtractCallback::Init( + IInArchive *archiveHandler, + IFolderArchiveExtractCallback *extractCallback2, + bool stdOutMode, + const UString &directoryPath, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, + const UStringVector &removePathParts, + const UString &itemDefaultName, + const FILETIME &utcLastWriteTimeDefault, + UInt32 attributesDefault) +{ + _stdOutMode = stdOutMode; + _numErrors = 0; + _extractCallback2 = extractCallback2; + _itemDefaultName = itemDefaultName; + _utcLastWriteTimeDefault = utcLastWriteTimeDefault; + _attributesDefault = attributesDefault; + _removePathParts = removePathParts; + _pathMode = pathMode; + _overwriteMode = overwriteMode; + _archiveHandler = archiveHandler; + _directoryPath = directoryPath; + NFile::NName::NormalizeDirPathPrefix(_directoryPath); +} + +STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 size) +{ + COM_TRY_BEGIN + return _extractCallback2->SetTotal(size); + COM_TRY_END +} + +STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue) +{ + COM_TRY_BEGIN + return _extractCallback2->SetCompleted(completeValue); + COM_TRY_END +} + +void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPathParts, UString &fullPath) +{ + fullPath = _directoryPath; + for(int i = 0; i < dirPathParts.Size(); i++) + { + if (i > 0) + fullPath += wchar_t(NFile::NName::kDirDelimiter); + fullPath += dirPathParts[i]; + NFile::NDirectory::MyCreateDirectory(fullPath); + } +} + +static UString MakePathNameFromParts(const UStringVector &parts) +{ + UString result; + for(int i = 0; i < parts.Size(); i++) + { + if(i != 0) + result += wchar_t(NFile::NName::kDirDelimiter); + result += parts[i]; + } + return result; +} + + +HRESULT CArchiveExtractCallback::GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined) +{ + filetimeIsDefined = false; + NCOM::CPropVariant prop; + RINOK(_archiveHandler->GetProperty(index, propID, &prop)); + if (prop.vt == VT_FILETIME) + { + filetime = prop.filetime; + filetimeIsDefined = true; + } + else if (prop.vt != VT_EMPTY) + return E_FAIL; + return S_OK; +} + +STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) +{ + COM_TRY_BEGIN + *outStream = 0; + _outFileStream.Release(); + + _encrypted = false; + _isSplit = false; + + UString fullPath; + { + NCOM::CPropVariant prop; + RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop)); + + if(prop.vt == VT_EMPTY) + fullPath = _itemDefaultName; + else + { + if(prop.vt != VT_BSTR) + return E_FAIL; + fullPath = prop.bstrVal; + } + } + + // UString fullPathCorrect = GetCorrectPath(fullPath); + _filePath = fullPath; + + { + NCOM::CPropVariant prop; + RINOK(_archiveHandler->GetProperty(index, kpidPosition, &prop)); + if (prop.vt != VT_EMPTY) + { + if (prop.vt != VT_UI8) + return E_FAIL; + _position = prop.uhVal.QuadPart; + _isSplit = true; + } + } + + { + NCOM::CPropVariant prop; + RINOK(_archiveHandler->GetProperty(index, kpidEncrypted, &prop)); + if (prop.vt == VT_BOOL) + _encrypted = VARIANT_BOOLToBool(prop.boolVal); + else if (prop.vt != VT_EMPTY) + return E_FAIL; + } + + if(askExtractMode == NArchive::NExtract::NAskMode::kExtract) + { + if (_stdOutMode) + { + CMyComPtr outStreamLoc = new CStdOutFileStream; + *outStream = outStreamLoc.Detach(); + return S_OK; + } + + { + NCOM::CPropVariant prop; + RINOK(_archiveHandler->GetProperty(index, kpidAttributes, &prop)); + if (prop.vt == VT_EMPTY) + { + _processedFileInfo.Attributes = _attributesDefault; + _processedFileInfo.AttributesAreDefined = false; + } + else + { + if (prop.vt != VT_UI4) + throw "incorrect item"; + _processedFileInfo.Attributes = prop.ulVal; + _processedFileInfo.AttributesAreDefined = true; + } + } + + RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.IsDirectory)); + + RINOK(GetTime(index, kpidCreationTime, _processedFileInfo.CreationTime, + _processedFileInfo.IsCreationTimeDefined)); + RINOK(GetTime(index, kpidLastWriteTime, _processedFileInfo.LastWriteTime, + _processedFileInfo.IsLastWriteTimeDefined)); + RINOK(GetTime(index, kpidLastAccessTime, _processedFileInfo.LastAccessTime, + _processedFileInfo.IsLastAccessTimeDefined)); + + bool newFileSizeDefined; + UInt64 newFileSize; + { + NCOM::CPropVariant prop; + RINOK(_archiveHandler->GetProperty(index, kpidSize, &prop)); + newFileSizeDefined = (prop.vt != VT_EMPTY); + if (newFileSizeDefined) + newFileSize = ConvertPropVariantToUInt64(prop); + } + + bool isAnti = false; + { + NCOM::CPropVariant prop; + RINOK(_archiveHandler->GetProperty(index, kpidIsAnti, &prop)); + if (prop.vt == VT_BOOL) + isAnti = VARIANT_BOOLToBool(prop.boolVal); + } + + UStringVector pathParts; + SplitPathToParts(fullPath, pathParts); + + if(pathParts.IsEmpty()) + return E_FAIL; + UString processedPath; + switch(_pathMode) + { + case NExtract::NPathMode::kFullPathnames: + { + processedPath = fullPath; + break; + } + case NExtract::NPathMode::kCurrentPathnames: + { + // for incorrect paths: "/dir1/dir2/file" + int numRemovePathParts = _removePathParts.Size(); + if(pathParts.Size() <= numRemovePathParts) + return E_FAIL; + for(int i = 0; i < numRemovePathParts; i++) + if(_removePathParts[i].CompareNoCase(pathParts[i]) != 0) + return E_FAIL; + pathParts.Delete(0, numRemovePathParts); + processedPath = MakePathNameFromParts(pathParts); + break; + } + case NExtract::NPathMode::kNoPathnames: + { + processedPath = pathParts.Back(); + pathParts.Delete(0, pathParts.Size() - 1); // Test it!! + break; + } + } + processedPath = GetCorrectPath(processedPath); + if(!_processedFileInfo.IsDirectory) + pathParts.DeleteBack(); + + MakeCorrectPath(pathParts); + + if (!isAnti) + { + if (!pathParts.IsEmpty()) + { + UString fullPathNew; + CreateComplexDirectory(pathParts, fullPathNew); + if (_processedFileInfo.IsDirectory) + NFile::NDirectory::SetDirTime(fullPathNew, + (WriteCreated && _processedFileInfo.IsCreationTimeDefined) ? &_processedFileInfo.CreationTime : NULL, + (WriteAccessed && _processedFileInfo.IsLastAccessTimeDefined) ? &_processedFileInfo.LastAccessTime : NULL, + (WriteModified && _processedFileInfo.IsLastWriteTimeDefined) ? &_processedFileInfo.LastWriteTime : &_utcLastWriteTimeDefault); + } + } + + + UString fullProcessedPath = _directoryPath + processedPath; + + if(_processedFileInfo.IsDirectory) + { + _diskFilePath = fullProcessedPath; + if (isAnti) + NFile::NDirectory::MyRemoveDirectory(_diskFilePath); + return S_OK; + } + + if (!_isSplit) + { + NFile::NFind::CFileInfoW fileInfo; + if(NFile::NFind::FindFile(fullProcessedPath, fileInfo)) + { + switch(_overwriteMode) + { + case NExtract::NOverwriteMode::kSkipExisting: + return S_OK; + case NExtract::NOverwriteMode::kAskBefore: + { + Int32 overwiteResult; + RINOK(_extractCallback2->AskOverwrite( + fullProcessedPath, &fileInfo.LastWriteTime, &fileInfo.Size, fullPath, + _processedFileInfo.IsLastWriteTimeDefined ? &_processedFileInfo.LastWriteTime : NULL, + newFileSizeDefined ? &newFileSize : NULL, + &overwiteResult)) + + switch(overwiteResult) + { + case NOverwriteAnswer::kCancel: + return E_ABORT; + case NOverwriteAnswer::kNo: + return S_OK; + case NOverwriteAnswer::kNoToAll: + _overwriteMode = NExtract::NOverwriteMode::kSkipExisting; + return S_OK; + case NOverwriteAnswer::kYesToAll: + _overwriteMode = NExtract::NOverwriteMode::kWithoutPrompt; + break; + case NOverwriteAnswer::kYes: + break; + case NOverwriteAnswer::kAutoRename: + _overwriteMode = NExtract::NOverwriteMode::kAutoRename; + break; + default: + throw 20413; + } + } + } + if (_overwriteMode == NExtract::NOverwriteMode::kAutoRename) + { + if (!AutoRenamePath(fullProcessedPath)) + { + UString message = UString(kCantAutoRename) + fullProcessedPath; + RINOK(_extractCallback2->MessageError(message)); + return E_FAIL; + } + } + else if (_overwriteMode == NExtract::NOverwriteMode::kAutoRenameExisting) + { + UString existPath = fullProcessedPath; + if (!AutoRenamePath(existPath)) + { + UString message = kCantAutoRename + fullProcessedPath; + RINOK(_extractCallback2->MessageError(message)); + return E_FAIL; + } + if(!NFile::NDirectory::MyMoveFile(fullProcessedPath, existPath)) + { + UString message = UString(kCantRenameFile) + fullProcessedPath; + RINOK(_extractCallback2->MessageError(message)); + return E_FAIL; + } + } + else + if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath)) + { + UString message = UString(kCantDeleteOutputFile) + + fullProcessedPath; + RINOK(_extractCallback2->MessageError(message)); + return E_FAIL; + } + } + } + if (!isAnti) + { + _outFileStreamSpec = new COutFileStream; + CMyComPtr outStreamLoc(_outFileStreamSpec); + if (!_outFileStreamSpec->File.Open(fullProcessedPath, + _isSplit ? OPEN_ALWAYS: CREATE_ALWAYS)) + { + // if (::GetLastError() != ERROR_FILE_EXISTS || !isSplit) + { + UString message = L"can not open output file " + fullProcessedPath; + RINOK(_extractCallback2->MessageError(message)); + return S_OK; + } + } + if (_isSplit) + { + RINOK(_outFileStreamSpec->Seek(_position, STREAM_SEEK_SET, NULL)); + } + _outFileStream = outStreamLoc; + *outStream = outStreamLoc.Detach(); + } + _diskFilePath = fullProcessedPath; + } + else + { + *outStream = NULL; + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode) +{ + COM_TRY_BEGIN + _extractMode = false; + switch (askExtractMode) + { + case NArchive::NExtract::NAskMode::kExtract: + _extractMode = true; + }; + return _extractCallback2->PrepareOperation(_filePath, askExtractMode, _isSplit ? &_position: 0); + COM_TRY_END +} + +STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult) +{ + COM_TRY_BEGIN + switch(operationResult) + { + case NArchive::NExtract::NOperationResult::kOK: + case NArchive::NExtract::NOperationResult::kUnSupportedMethod: + case NArchive::NExtract::NOperationResult::kCRCError: + case NArchive::NExtract::NOperationResult::kDataError: + break; + default: + _outFileStream.Release(); + return E_FAIL; + } + if(_outFileStream != NULL) + _outFileStreamSpec->File.SetTime( + (WriteCreated && _processedFileInfo.IsCreationTimeDefined) ? &_processedFileInfo.CreationTime : NULL, + (WriteAccessed && _processedFileInfo.IsLastAccessTimeDefined) ? &_processedFileInfo.LastAccessTime : NULL, + (WriteModified && _processedFileInfo.IsLastWriteTimeDefined) ? &_processedFileInfo.LastWriteTime : &_utcLastWriteTimeDefault); + _outFileStream.Release(); + if (_extractMode && _processedFileInfo.AttributesAreDefined) + NFile::NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attributes); + RINOK(_extractCallback2->SetOperationResult(operationResult, _encrypted)); + return S_OK; + COM_TRY_END +} + +/* +STDMETHODIMP CArchiveExtractCallback::GetInStream( + const wchar_t *name, ISequentialInStream **inStream) +{ + COM_TRY_BEGIN + CInFileStream *inFile = new CInFileStream; + CMyComPtr inStreamTemp = inFile; + if (!inFile->Open(_srcDirectoryPrefix + name)) + return ::GetLastError(); + *inStream = inStreamTemp.Detach(); + return S_OK; + COM_TRY_END +} +*/ + +STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password) +{ + COM_TRY_BEGIN + if (!_cryptoGetTextPassword) + { + RINOK(_extractCallback2.QueryInterface(IID_ICryptoGetTextPassword, + &_cryptoGetTextPassword)); + } + return _cryptoGetTextPassword->CryptoGetTextPassword(password); + COM_TRY_END +} + diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.h b/CPP/7zip/UI/Common/ArchiveExtractCallback.h new file mode 100755 index 00000000..4fd63a53 --- /dev/null +++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.h @@ -0,0 +1,111 @@ +// ArchiveExtractCallback.h + +#ifndef __ARCHIVEEXTRACTCALLBACK_H +#define __ARCHIVEEXTRACTCALLBACK_H + +#include "../../Archive/IArchive.h" +#include "IFileExtractCallback.h" + +#include "Common/String.h" +#include "Common/MyCom.h" + +#include "../../Common/FileStreams.h" +#include "../../IPassword.h" + +#include "ExtractMode.h" + +class CArchiveExtractCallback: + public IArchiveExtractCallback, + // public IArchiveVolumeExtractCallback, + public ICryptoGetTextPassword, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP1(ICryptoGetTextPassword) + // COM_INTERFACE_ENTRY(IArchiveVolumeExtractCallback) + + // IProgress + STDMETHOD(SetTotal)(UInt64 size); + STDMETHOD(SetCompleted)(const UInt64 *completeValue); + + // IExtractCallBack + STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode); + STDMETHOD(PrepareOperation)(Int32 askExtractMode); + STDMETHOD(SetOperationResult)(Int32 resultEOperationResult); + + // IArchiveVolumeExtractCallback + // STDMETHOD(GetInStream)(const wchar_t *name, ISequentialInStream **inStream); + + // ICryptoGetTextPassword + STDMETHOD(CryptoGetTextPassword)(BSTR *aPassword); + +private: + CMyComPtr _archiveHandler; + CMyComPtr _extractCallback2; + CMyComPtr _cryptoGetTextPassword; + UString _directoryPath; + NExtract::NPathMode::EEnum _pathMode; + NExtract::NOverwriteMode::EEnum _overwriteMode; + + UString _filePath; + UInt64 _position; + bool _isSplit; + + UString _diskFilePath; + + bool _extractMode; + + bool WriteModified; + bool WriteCreated; + bool WriteAccessed; + + bool _encrypted; + + struct CProcessedFileInfo + { + FILETIME CreationTime; + FILETIME LastWriteTime; + FILETIME LastAccessTime; + UInt32 Attributes; + + bool IsCreationTimeDefined; + bool IsLastWriteTimeDefined; + bool IsLastAccessTimeDefined; + + bool IsDirectory; + bool AttributesAreDefined; + } _processedFileInfo; + + COutFileStream *_outFileStreamSpec; + CMyComPtr _outFileStream; + UStringVector _removePathParts; + + UString _itemDefaultName; + FILETIME _utcLastWriteTimeDefault; + UInt32 _attributesDefault; + bool _stdOutMode; + + void CreateComplexDirectory(const UStringVector &dirPathParts, UString &fullPath); + HRESULT GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined); +public: + CArchiveExtractCallback(): + WriteModified(true), + WriteCreated(false), + WriteAccessed(false) + {} + void Init( + IInArchive *archiveHandler, + IFolderArchiveExtractCallback *extractCallback2, + bool stdOutMode, + const UString &directoryPath, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, + const UStringVector &removePathParts, + const UString &itemDefaultName, + const FILETIME &utcLastWriteTimeDefault, + UInt32 attributesDefault); + + UInt64 _numErrors; +}; + +#endif diff --git a/CPP/7zip/UI/Common/ArchiveName.cpp b/CPP/7zip/UI/Common/ArchiveName.cpp new file mode 100755 index 00000000..2d50ede1 --- /dev/null +++ b/CPP/7zip/UI/Common/ArchiveName.cpp @@ -0,0 +1,46 @@ +// ArchiveName.cpp + +#include "StdAfx.h" + +#include "Windows/FileFind.h" +#include "Windows/FileDir.h" + +using namespace NWindows; + +UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName) +{ + UString resultName = L"Archive"; + if (fromPrev) + { + UString dirPrefix; + if (NFile::NDirectory::GetOnlyDirPrefix(srcName, dirPrefix)) + { + if (dirPrefix.Length() > 0) + if (dirPrefix[dirPrefix.Length() - 1] == '\\') + { + dirPrefix.Delete(dirPrefix.Length() - 1); + NFile::NFind::CFileInfoW fileInfo; + if (NFile::NFind::FindFile(dirPrefix, fileInfo)) + resultName = fileInfo.Name; + } + } + } + else + { + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(srcName, fileInfo)) + return resultName; + resultName = fileInfo.Name; + if (!fileInfo.IsDirectory() && !keepName) + { + int dotPos = resultName.ReverseFind('.'); + if (dotPos > 0) + { + UString archiveName2 = resultName.Left(dotPos); + if (archiveName2.ReverseFind('.') < 0) + resultName = archiveName2; + } + } + } + return resultName; +} diff --git a/CPP/7zip/UI/Common/ArchiveName.h b/CPP/7zip/UI/Common/ArchiveName.h new file mode 100755 index 00000000..6b001a5a --- /dev/null +++ b/CPP/7zip/UI/Common/ArchiveName.h @@ -0,0 +1,10 @@ +// ArchiveName.h + +#ifndef __ARCHIVENAME_H +#define __ARCHIVENAME_H + +#include "Common/String.h" + +UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName); + +#endif diff --git a/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp b/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp new file mode 100755 index 00000000..1d2944d8 --- /dev/null +++ b/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp @@ -0,0 +1,127 @@ +// ArchiveOpenCallback.cpp + +#include "StdAfx.h" + +#include "ArchiveOpenCallback.h" + +#include "Common/StringConvert.h" +#include "Common/ComTry.h" +#include "Windows/PropVariant.h" + +#include "../../Common/FileStreams.h" + +using namespace NWindows; + +STDMETHODIMP COpenCallbackImp::SetTotal(const UInt64 *files, const UInt64 *bytes) +{ + COM_TRY_BEGIN + return Callback->SetTotal(files, bytes); + COM_TRY_END +} + +STDMETHODIMP COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *bytes) +{ + COM_TRY_BEGIN + return Callback->SetTotal(files, bytes); + COM_TRY_END +} + +STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NCOM::CPropVariant propVariant; + if (_subArchiveMode) + { + switch(propID) + { + case kpidName: + propVariant = _subArchiveName; + break; + } + propVariant.Detach(value); + return S_OK; + } + switch(propID) + { + case kpidName: + propVariant = _fileInfo.Name; + break; + case kpidIsFolder: + propVariant = _fileInfo.IsDirectory(); + break; + case kpidSize: + propVariant = _fileInfo.Size; + break; + case kpidAttributes: + propVariant = (UInt32)_fileInfo.Attributes; + break; + case kpidLastAccessTime: + propVariant = _fileInfo.LastAccessTime; + break; + case kpidCreationTime: + propVariant = _fileInfo.CreationTime; + break; + case kpidLastWriteTime: + propVariant = _fileInfo.LastWriteTime; + break; + } + propVariant.Detach(value); + return S_OK; + COM_TRY_END +} + +int COpenCallbackImp::FindName(const UString &name) +{ + for (int i = 0; i < FileNames.Size(); i++) + if (name.CompareNoCase(FileNames[i]) == 0) + return i; + return -1; +} + +struct CInFileStreamVol: public CInFileStream +{ + UString Name; + COpenCallbackImp *OpenCallbackImp; + CMyComPtr OpenCallbackRef; + ~CInFileStreamVol() + { + int index = OpenCallbackImp->FindName(Name); + if (index >= 0) + OpenCallbackImp->FileNames.Delete(index); + } +}; + +STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStream) +{ + COM_TRY_BEGIN + if (_subArchiveMode) + return S_FALSE; + RINOK(Callback->CheckBreak()); + *inStream = NULL; + UString fullPath = _folderPrefix + name; + if (!NFile::NFind::FindFile(fullPath, _fileInfo)) + return S_FALSE; + if (_fileInfo.IsDirectory()) + return S_FALSE; + CInFileStreamVol *inFile = new CInFileStreamVol; + CMyComPtr inStreamTemp = inFile; + if (!inFile->Open(fullPath)) + return ::GetLastError(); + *inStream = inStreamTemp.Detach(); + inFile->Name = name; + inFile->OpenCallbackImp = this; + inFile->OpenCallbackRef = this; + FileNames.Add(name); + return S_OK; + COM_TRY_END +} + +#ifndef _NO_CRYPTO +STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password) +{ + COM_TRY_BEGIN + return Callback->CryptoGetTextPassword(password); + COM_TRY_END +} +#endif + diff --git a/CPP/7zip/UI/Common/ArchiveOpenCallback.h b/CPP/7zip/UI/Common/ArchiveOpenCallback.h new file mode 100755 index 00000000..454873ad --- /dev/null +++ b/CPP/7zip/UI/Common/ArchiveOpenCallback.h @@ -0,0 +1,89 @@ +// ArchiveOpenCallback.h + +#ifndef __ARCHIVE_OPEN_CALLBACK_H +#define __ARCHIVE_OPEN_CALLBACK_H + +#include "Common/String.h" +#include "Common/MyCom.h" +#include "Windows/FileFind.h" + +#ifndef _NO_CRYPTO +#include "../../IPassword.h" +#endif +#include "../../Archive/IArchive.h" + +struct IOpenCallbackUI +{ + virtual HRESULT CheckBreak() = 0; + virtual HRESULT SetTotal(const UInt64 *files, const UInt64 *bytes) = 0; + virtual HRESULT SetCompleted(const UInt64 *files, const UInt64 *bytes) = 0; + #ifndef _NO_CRYPTO + virtual HRESULT CryptoGetTextPassword(BSTR *password) = 0; + virtual HRESULT GetPasswordIfAny(UString &password) = 0; + virtual bool WasPasswordAsked() = 0; + virtual void ClearPasswordWasAskedFlag() = 0; + #endif +}; + +class COpenCallbackImp: + public IArchiveOpenCallback, + public IArchiveOpenVolumeCallback, + public IArchiveOpenSetSubArchiveName, + #ifndef _NO_CRYPTO + public ICryptoGetTextPassword, + #endif + public CMyUnknownImp +{ +public: + #ifndef _NO_CRYPTO + MY_UNKNOWN_IMP3( + IArchiveOpenVolumeCallback, + ICryptoGetTextPassword, + IArchiveOpenSetSubArchiveName + ) + #else + MY_UNKNOWN_IMP2( + IArchiveOpenVolumeCallback, + IArchiveOpenSetSubArchiveName + ) + #endif + + STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes); + STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes); + + // IArchiveOpenVolumeCallback + STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value); + STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream); + + #ifndef _NO_CRYPTO + // ICryptoGetTextPassword + STDMETHOD(CryptoGetTextPassword)(BSTR *password); + #endif + + STDMETHOD(SetSubArchiveName(const wchar_t *name)) + { + _subArchiveMode = true; + _subArchiveName = name; + return S_OK; + } + +private: + UString _folderPrefix; + NWindows::NFile::NFind::CFileInfoW _fileInfo; + bool _subArchiveMode; + UString _subArchiveName; +public: + UStringVector FileNames; + IOpenCallbackUI *Callback; + void Init(const UString &folderPrefix, const UString &fileName) + { + _folderPrefix = folderPrefix; + if (!NWindows::NFile::NFind::FindFile(_folderPrefix + fileName, _fileInfo)) + throw 1; + FileNames.Clear(); + _subArchiveMode = false; + } + int FindName(const UString &name); +}; + +#endif diff --git a/CPP/7zip/UI/Common/ArchiverInfo.cpp b/CPP/7zip/UI/Common/ArchiverInfo.cpp new file mode 100755 index 00000000..7833ed3c --- /dev/null +++ b/CPP/7zip/UI/Common/ArchiverInfo.cpp @@ -0,0 +1,372 @@ +// ArchiverInfo.cpp + +#include "StdAfx.h" + +#include "ArchiverInfo.h" + +#ifndef EXCLUDE_COM + +#include "Common/StringConvert.h" +#include "Windows/FileFind.h" +#include "Windows/FileName.h" +#include "Windows/DLL.h" +#ifdef _WIN32 +#include "Windows/Registry.h" +#endif +#include "Windows/PropVariant.h" +#include "../../Archive/IArchive.h" + +using namespace NWindows; +using namespace NFile; + +#endif + +extern HINSTANCE g_hInstance; + +#ifndef EXCLUDE_COM + +static void SplitString(const UString &srcString, UStringVector &destStrings) +{ + destStrings.Clear(); + UString string; + int len = srcString.Length(); + if (len == 0) + return; + for (int i = 0; i < len; i++) + { + wchar_t c = srcString[i]; + if (c == L' ') + { + if (!string.IsEmpty()) + { + destStrings.Add(string); + string.Empty(); + } + } + else + string += c; + } + if (!string.IsEmpty()) + destStrings.Add(string); +} + +typedef UInt32 (WINAPI * GetHandlerPropertyFunc)( + PROPID propID, PROPVARIANT *value); + +static UString GetModuleFolderPrefix() +{ + UString path; + NDLL::MyGetModuleFileName(g_hInstance, path); + int pos = path.ReverseFind(WCHAR_PATH_SEPARATOR); + return path.Left(pos + 1); +} + +static wchar_t *kFormatFolderName = L"Formats"; + +#ifdef _WIN32 +static LPCTSTR kRegistryPath = TEXT("Software\\7-zip"); +static LPCWSTR kProgramPathValue = L"Path"; +static bool ReadPathFromRegistry(HKEY baseKey, UString &path) +{ + NRegistry::CKey key; + if(key.Open(baseKey, kRegistryPath, KEY_READ) == ERROR_SUCCESS) + if (key.QueryValue(kProgramPathValue, path) == ERROR_SUCCESS) + { + NName::NormalizeDirPathPrefix(path); + return true; + } + return false; +} +#endif + +static UString GetBaseFolderPrefixFromRegistry() +{ + UString moduleFolderPrefix = GetModuleFolderPrefix(); + NFind::CFileInfoW fileInfo; + if (NFind::FindFile(moduleFolderPrefix + kFormatFolderName, fileInfo)) + if (fileInfo.IsDirectory()) + return moduleFolderPrefix; + UString path; + #ifdef _WIN32 + if(ReadPathFromRegistry(HKEY_CURRENT_USER, path)) + return path; + if(ReadPathFromRegistry(HKEY_LOCAL_MACHINE, path)) + return path; + #endif + return moduleFolderPrefix; +} + +typedef UInt32 (WINAPI *CreateObjectPointer)( + const GUID *clsID, + const GUID *interfaceID, + void **outObject); + +#endif + +#ifndef _SFX +static inline void SetBuffer(CByteBuffer &bb, const Byte *data, int size) +{ + bb.SetCapacity(size); + memmove((Byte *)bb, data, size); +} +#endif + +void ReadArchiverInfoList(CObjectVector &archivers) +{ + archivers.Clear(); + + #ifdef EXCLUDE_COM + + #ifdef FORMAT_7Z + { + CArchiverInfo item; + item.UpdateEnabled = true; + item.Name = L"7z"; + item.Extensions.Add(CArchiverExtInfo(L"7z")); + #ifndef _SFX + const unsigned char kSig[] = {'7' , 'z', 0xBC, 0xAF, 0x27, 0x1C}; + SetBuffer(item.StartSignature, kSig, 6); + #endif + archivers.Add(item); + } + #endif + + #ifdef FORMAT_BZIP2 + { + CArchiverInfo item; + item.UpdateEnabled = true; + item.KeepName = true; + item.Name = L"BZip2"; + item.Extensions.Add(CArchiverExtInfo(L"bz2")); + item.Extensions.Add(CArchiverExtInfo(L"tbz2", L".tar")); + #ifndef _SFX + const unsigned char sig[] = {'B' , 'Z', 'h' }; + SetBuffer(item.StartSignature, sig, 3); + #endif + archivers.Add(item); + } + #endif + + #ifdef FORMAT_CAB + { + CArchiverInfo item; + item.Name = L"Cab"; + item.Extensions.Add(CArchiverExtInfo(L"cab")); + #ifndef _SFX + const unsigned char sig[] = { 0x4D, 0x53, 0x43, 0x46 }; + SetBuffer(item.StartSignature, sig, 4); + #endif + archivers.Add(item); + } + #endif + + #ifdef FORMAT_GZIP + { + CArchiverInfo item; + item.UpdateEnabled = true; + item.Name = L"GZip"; + item.Extensions.Add(CArchiverExtInfo(L"gz")); + item.Extensions.Add(CArchiverExtInfo(L"tgz", L".tar")); + #ifndef _SFX + const unsigned char sig[] = { 0x1F, 0x8B }; + SetBuffer(item.StartSignature, sig, 2); + #endif + archivers.Add(item); + } + #endif + + #ifdef FORMAT_SPLIT + { + CArchiverInfo item; + item.UpdateEnabled = false; + item.KeepName = true; + item.Name = L"Split"; + item.Extensions.Add(CArchiverExtInfo(L"001")); + archivers.Add(item); + } + #endif + + #ifdef FORMAT_TAR + { + CArchiverInfo item; + item.UpdateEnabled = true; + item.Name = L"Tar"; + item.Extensions.Add(CArchiverExtInfo(L"tar")); + archivers.Add(item); + } + #endif + + #ifdef FORMAT_ZIP + { + CArchiverInfo item; + item.UpdateEnabled = true; + item.Name = L"Zip"; + item.Extensions.Add(CArchiverExtInfo(L"zip")); + #ifndef _SFX + const unsigned char sig[] = { 0x50, 0x4B, 0x03, 0x04 }; + SetBuffer(item.StartSignature, sig, 4); + #endif + archivers.Add(item); + } + #endif + + #ifdef FORMAT_CPIO + { + CArchiverInfo item; + item.Name = L"Cpio"; + item.Extensions.Add(CArchiverExtInfo(L"cpio")); + archivers.Add(item); + } + #endif + + #ifdef FORMAT_RPM + { + CArchiverInfo item; + item.Name = L"Rpm"; + item.Extensions.Add(CArchiverExtInfo(L"rpm", L".cpio.gz")); + archivers.Add(item); + } + #endif + + #ifdef FORMAT_ARJ + { + CArchiverInfo item; + item.Name = L"Arj"; + item.Extensions.Add(CArchiverExtInfo(L"arj")); + #ifndef _SFX + const unsigned char sig[] = { 0x60, 0xEA }; + SetBuffer(item.StartSignature, sig, 2); + #endif + archivers.Add(item); + } + #endif + + #ifdef FORMAT_Z + { + CArchiverInfo item; + item.Name = L"Z"; + item.Extensions.Add(CArchiverExtInfo(L"Z")); + #ifndef _SFX + const unsigned char sig[] = { 0x1F, 0x9D }; + SetBuffer(item.StartSignature, sig, 2); + #endif + archivers.Add(item); + } + #endif + + #else + + UString folderPath = GetBaseFolderPrefixFromRegistry() + + (UString)kFormatFolderName + (UString)WSTRING_PATH_SEPARATOR; + NFind::CEnumeratorW enumerator(folderPath + L"*"); + NFind::CFileInfoW fileInfo; + while (enumerator.Next(fileInfo)) + { + if (fileInfo.IsDirectory()) + continue; + UString filePath = folderPath + fileInfo.Name; + { + NDLL::CLibrary library; + if (!library.LoadEx(filePath, LOAD_LIBRARY_AS_DATAFILE)) + continue; + } + + NDLL::CLibrary library; + if (!library.Load(filePath)) + continue; + GetHandlerPropertyFunc getHandlerProperty = (GetHandlerPropertyFunc) + library.GetProcAddress("GetHandlerProperty"); + if (getHandlerProperty == NULL) + continue; + + CArchiverInfo item; + item.FilePath = filePath; + + NWindows::NCOM::CPropVariant prop; + if (getHandlerProperty(NArchive::kName, &prop) != S_OK) + continue; + if (prop.vt != VT_BSTR) + continue; + item.Name = prop.bstrVal; + prop.Clear(); + + if (getHandlerProperty(NArchive::kClassID, &prop) != S_OK) + continue; + if (prop.vt != VT_BSTR) + continue; + item.ClassID = *(const GUID *)prop.bstrVal; + prop.Clear(); + + if (getHandlerProperty(NArchive::kExtension, &prop) != S_OK) + continue; + if (prop.vt != VT_BSTR) + continue; + + UString ext = prop.bstrVal; + UString addExt; + + prop.Clear(); + + if (getHandlerProperty(NArchive::kAddExtension, &prop) != S_OK) + continue; + if (prop.vt == VT_BSTR) + { + addExt = prop.bstrVal; + } + else if (prop.vt != VT_EMPTY) + continue; + prop.Clear(); + + UStringVector exts, addExts; + SplitString(ext, exts); + SplitString(addExt, addExts); + + prop.Clear(); + for (int i = 0; i < exts.Size(); i++) + { + CArchiverExtInfo extInfo; + extInfo.Ext = exts[i]; + if (addExts.Size() > 0) + extInfo.AddExt = addExts[i]; + if (extInfo.AddExt == L"*") + extInfo.AddExt.Empty(); + item.Extensions.Add(extInfo); + } + + if (getHandlerProperty(NArchive::kUpdate, &prop) == S_OK) + if (prop.vt == VT_BOOL) + item.UpdateEnabled = VARIANT_BOOLToBool(prop.boolVal); + prop.Clear(); + + if (item.UpdateEnabled) + { + if (getHandlerProperty(NArchive::kKeepName, &prop) == S_OK) + if (prop.vt == VT_BOOL) + item.KeepName = VARIANT_BOOLToBool(prop.boolVal); + prop.Clear(); + } + + if (getHandlerProperty(NArchive::kStartSignature, &prop) == S_OK) + { + if (prop.vt == VT_BSTR) + { + UINT len = ::SysStringByteLen(prop.bstrVal); + item.StartSignature.SetCapacity(len); + memmove(item.StartSignature, prop.bstrVal, len); + } + } + prop.Clear(); + + if (getHandlerProperty(NArchive::kAssociate, &prop) == S_OK) + if (prop.vt == VT_BOOL) + item.Associate = VARIANT_BOOLToBool(prop.boolVal); + prop.Clear(); + + + archivers.Add(item); + } + + #endif +} + + diff --git a/CPP/7zip/UI/Common/ArchiverInfo.h b/CPP/7zip/UI/Common/ArchiverInfo.h new file mode 100755 index 00000000..3b829518 --- /dev/null +++ b/CPP/7zip/UI/Common/ArchiverInfo.h @@ -0,0 +1,66 @@ +// ArchiverInfo.h + +#ifndef __ARCHIVERINFO_H +#define __ARCHIVERINFO_H + +#include "Common/String.h" +#include "Common/Types.h" +#include "Common/Buffer.h" + +struct CArchiverExtInfo +{ + UString Ext; + UString AddExt; + CArchiverExtInfo() {} + CArchiverExtInfo(const UString &ext): Ext(ext) {} + CArchiverExtInfo(const UString &ext, const UString &addExt): Ext(ext), AddExt(addExt) {} +}; + +struct CArchiverInfo +{ + #ifndef EXCLUDE_COM + UString FilePath; + CLSID ClassID; + #endif + UString Name; + CObjectVector Extensions; + #ifndef _SFX + CByteBuffer StartSignature; + CByteBuffer FinishSignature; + bool Associate; + #endif + int FindExtension(const UString &ext) const + { + for (int i = 0; i < Extensions.Size(); i++) + if (ext.CompareNoCase(Extensions[i].Ext) == 0) + return i; + return -1; + } + UString GetAllExtensions() const + { + UString s; + for (int i = 0; i < Extensions.Size(); i++) + { + if (i > 0) + s += ' '; + s += Extensions[i].Ext; + } + return s; + } + const UString &GetMainExtension() const + { + return Extensions[0].Ext; + } + bool UpdateEnabled; + bool KeepName; + + CArchiverInfo(): UpdateEnabled(false), KeepName(false) + #ifndef _SFX + ,Associate(true) + #endif + {} +}; + +void ReadArchiverInfoList(CObjectVector &archivers); + +#endif diff --git a/CPP/7zip/UI/Common/CompressCall.cpp b/CPP/7zip/UI/Common/CompressCall.cpp new file mode 100755 index 00000000..86bdd297 --- /dev/null +++ b/CPP/7zip/UI/Common/CompressCall.cpp @@ -0,0 +1,367 @@ +// CompressCall.cpp + +#include "StdAfx.h" + +#include "CompressCall.h" + +#include "Common/Random.h" +#include "Common/IntToString.h" +#include "Common/MyCom.h" +#include "Common/StringConvert.h" + +#include "Windows/Synchronization.h" +#include "Windows/FileMapping.h" +#include "Windows/FileDir.h" + +#include "../../FileManager/ProgramLocation.h" +#include "../../FileManager/RegistryUtils.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif _UNICODE + +using namespace NWindows; + +static LPCWSTR kShowDialogSwitch = L" -ad"; +static LPCWSTR kEmailSwitch = L" -seml."; +static LPCWSTR kMapSwitch = L" -i#"; +static LPCWSTR kArchiveNoNameSwitch = L" -an"; +static LPCWSTR kArchiveTypeSwitch = L" -t"; +static LPCWSTR kArchiveMapSwitch = L" -ai#"; +static LPCWSTR kStopSwitchParsing = L" --"; +static LPCWSTR kLargePagesDisable = L" -slp-"; + +static void AddLagePagesSwitch(UString ¶ms) +{ + if (!ReadLockMemoryEnable()) + params += kLargePagesDisable; +} + +HRESULT MyCreateProcess(const UString ¶ms, + LPCWSTR curDir, bool waitFinish, + NWindows::NSynchronization::CEvent *event) +{ + const UString params2 = params; + PROCESS_INFORMATION processInformation; + BOOL result; + #ifndef _UNICODE + if (!g_IsNT) + { + STARTUPINFOA startupInfo; + startupInfo.cb = sizeof(startupInfo); + startupInfo.lpReserved = 0; + startupInfo.lpDesktop = 0; + startupInfo.lpTitle = 0; + startupInfo.dwFlags = 0; + startupInfo.cbReserved2 = 0; + startupInfo.lpReserved2 = 0; + + CSysString curDirA; + if (curDir != 0) + curDirA = GetSystemString(curDir); + result = ::CreateProcessA(NULL, (LPSTR)(LPCSTR)GetSystemString(params), + NULL, NULL, FALSE, 0, NULL, + ((curDir != 0) ? (LPCSTR)curDirA: 0), + &startupInfo, &processInformation); + } + else + #endif + { + STARTUPINFOW startupInfo; + startupInfo.cb = sizeof(startupInfo); + startupInfo.lpReserved = 0; + startupInfo.lpDesktop = 0; + startupInfo.lpTitle = 0; + startupInfo.dwFlags = 0; + startupInfo.cbReserved2 = 0; + startupInfo.lpReserved2 = 0; + + result = ::CreateProcessW(NULL, (LPWSTR)(LPCWSTR)params, + NULL, NULL, FALSE, 0, NULL, + curDir, + &startupInfo, &processInformation); + } + if (result == 0) + return ::GetLastError(); + else + { + ::CloseHandle(processInformation.hThread); + if (waitFinish) + WaitForSingleObject(processInformation.hProcess, INFINITE); + else if (event != NULL) + { + HANDLE handles[] = {processInformation.hProcess, *event }; + ::WaitForMultipleObjects(sizeof(handles) / sizeof(handles[0]), + handles, FALSE, INFINITE); + } + ::CloseHandle(processInformation.hProcess); + } + return S_OK; +} + +static UString GetQuotedString(const UString &s) +{ + return UString(L"\"") + s + UString(L"\""); +} + +static UString Get7zGuiPath() +{ + UString path; + UString folder; + if (GetProgramFolderPath(folder)) + path += folder; + path += L"7zG.exe"; + return GetQuotedString(path); +} + +static HRESULT CreateMap(const UStringVector &names, + const UString &id, + CFileMapping &fileMapping, NSynchronization::CEvent &event, + UString ¶ms) +{ + UInt32 extraSize = 2; + UInt32 dataSize = 0; + for (int i = 0; i < names.Size(); i++) + dataSize += (names[i].Length() + 1) * sizeof(wchar_t); + UInt32 totalSize = extraSize + dataSize; + + UString mappingName; + UString eventName; + + CRandom random; + random.Init(GetTickCount()); + for (;;) + { + int number = random.Generate(); + wchar_t temp[32]; + ConvertUInt64ToString(UInt32(number), temp); + mappingName = id; + mappingName += L"Mapping"; + mappingName += temp; + if (!fileMapping.Create(INVALID_HANDLE_VALUE, NULL, + PAGE_READWRITE, totalSize, GetSystemString(mappingName))) + return E_FAIL; + if (::GetLastError() != ERROR_ALREADY_EXISTS) + break; + fileMapping.Close(); + } + + for (;;) + { + int number = random.Generate(); + wchar_t temp[32]; + ConvertUInt64ToString(UInt32(number), temp); + eventName = id; + eventName += L"MappingEndEvent"; + eventName += temp; + if (!event.Create(true, false, GetSystemString(eventName))) + return E_FAIL; + if (::GetLastError() != ERROR_ALREADY_EXISTS) + break; + event.Close(); + } + + params += mappingName; + params += L":"; + wchar_t string[10]; + ConvertUInt64ToString(totalSize, string); + params += string; + + params += L":"; + params += eventName; + + LPVOID data = fileMapping.MapViewOfFile(FILE_MAP_WRITE, 0, totalSize); + if (data == NULL) + return E_FAIL; + { + wchar_t *curData = (wchar_t *)data; + *curData = 0; + curData++; + for (int i = 0; i < names.Size(); i++) + { + const UString &s = names[i]; + memcpy(curData, (const wchar_t *)s, s.Length() * sizeof(wchar_t)); + curData += s.Length(); + *curData++ = L'\0'; + } + } + return S_OK; +} + +HRESULT CompressFiles( + const UString &curDir, + const UString &archiveName, + const UString &archiveType, + const UStringVector &names, + // const UString &outFolder, + bool email, + bool showDialog, + bool waitFinish) +{ + /* + UString curDir; + if (names.Size() > 0) + { + NFile::NDirectory::GetOnlyDirPrefix(names[0], curDir); + } + */ + UString params; + params = Get7zGuiPath(); + params += L" a"; + params += kMapSwitch; + // params += _fileNames[0]; + + UInt32 extraSize = 2; + UInt32 dataSize = 0; + for (int i = 0; i < names.Size(); i++) + dataSize += (names[i].Length() + 1) * sizeof(wchar_t); + UInt32 totalSize = extraSize + dataSize; + + UString mappingName; + UString eventName; + + CFileMapping fileMapping; + CRandom random; + random.Init(GetTickCount()); + for (;;) + { + int number = random.Generate(); + wchar_t temp[32]; + ConvertUInt64ToString(UInt32(number), temp); + mappingName = L"7zCompressMapping"; + mappingName += temp; + if (!fileMapping.Create(INVALID_HANDLE_VALUE, NULL, + PAGE_READWRITE, totalSize, GetSystemString(mappingName))) + { + // MyMessageBox(IDS_ERROR, 0x02000605); + return E_FAIL; + } + if (::GetLastError() != ERROR_ALREADY_EXISTS) + break; + fileMapping.Close(); + } + + NSynchronization::CEvent event; + for (;;) + { + int number = random.Generate(); + wchar_t temp[32]; + ConvertUInt64ToString(UInt32(number), temp); + eventName = L"7zCompressMappingEndEvent"; + eventName += temp; + if (!event.Create(true, false, GetSystemString(eventName))) + { + // MyMessageBox(IDS_ERROR, 0x02000605); + return E_FAIL; + } + if (::GetLastError() != ERROR_ALREADY_EXISTS) + break; + event.Close(); + } + + params += mappingName; + params += L":"; + wchar_t string[10]; + ConvertUInt64ToString(totalSize, string); + params += string; + + params += L":"; + params += eventName; + + if (!archiveType.IsEmpty()) + { + params += kArchiveTypeSwitch; + params += archiveType; + } + + if (email) + params += kEmailSwitch; + + if (showDialog) + params += kShowDialogSwitch; + + AddLagePagesSwitch(params); + + params += kStopSwitchParsing; + params += L" "; + + params += GetQuotedString(archiveName); + + LPVOID data = fileMapping.MapViewOfFile(FILE_MAP_WRITE, 0, totalSize); + if (data == NULL) + { + // MyMessageBox(IDS_ERROR, 0x02000605); + return E_FAIL; + } + try + { + wchar_t *curData = (wchar_t *)data; + *curData = 0; + curData++; + for (int i = 0; i < names.Size(); i++) + { + const UString &unicodeString = names[i]; + memcpy(curData, (const wchar_t *)unicodeString , + unicodeString .Length() * sizeof(wchar_t)); + curData += unicodeString.Length(); + *curData++ = L'\0'; + } + // MessageBox(0, params, 0, 0); + RINOK(MyCreateProcess(params, + (curDir.IsEmpty()? 0: (LPCWSTR)curDir), + waitFinish, &event)); + } + catch(...) + { + UnmapViewOfFile(data); + throw; + } + UnmapViewOfFile(data); + + + /* + CThreadCompressMain *compressor = new CThreadCompressMain();; + compressor->FileNames = _fileNames; + CThread thread; + if (!thread.Create(CThreadCompressMain::MyThreadFunction, compressor)) + throw 271824; + */ + return S_OK; +} + +static HRESULT ExtractGroupCommand(const UStringVector &archivePaths, + const UString ¶ms) +{ + UString params2 = params; + AddLagePagesSwitch(params2); + params2 += kArchiveNoNameSwitch; + params2 += kArchiveMapSwitch; + CFileMapping fileMapping; + NSynchronization::CEvent event; + RINOK(CreateMap(archivePaths, L"7zExtract", fileMapping, event, params2)); + return MyCreateProcess(params2, 0, false, &event); +} + +HRESULT ExtractArchives(const UStringVector &archivePaths, + const UString &outFolder, bool showDialog) +{ + UString params; + params = Get7zGuiPath(); + params += L" x"; + if (!outFolder.IsEmpty()) + { + params += L" -o"; + params += GetQuotedString(outFolder); + } + if (showDialog) + params += kShowDialogSwitch; + return ExtractGroupCommand(archivePaths, params); +} + +HRESULT TestArchives(const UStringVector &archivePaths) +{ + UString params; + params = Get7zGuiPath(); + params += L" t"; + return ExtractGroupCommand(archivePaths, params); +} diff --git a/CPP/7zip/UI/Common/CompressCall.h b/CPP/7zip/UI/Common/CompressCall.h new file mode 100755 index 00000000..95be95c3 --- /dev/null +++ b/CPP/7zip/UI/Common/CompressCall.h @@ -0,0 +1,28 @@ +// CompressCall.h + +#ifndef __COMPRESSCALL_H +#define __COMPRESSCALL_H + +#include "Common/String.h" +#include "Windows/Synchronization.h" + +HRESULT MyCreateProcess(const UString ¶ms, + LPCWSTR lpCurrentDirectory, bool waitFinish, + NWindows::NSynchronization::CEvent *event); + +HRESULT CompressFiles( + const UString &curDir, + const UString &archiveName, + const UString &archiveType, + const UStringVector &names, + // const UString &outFolder, + bool email, bool showDialog, bool waitFinish); + +HRESULT ExtractArchives( + const UStringVector &archivePaths, + const UString &outFolder, bool showDialog); + +HRESULT TestArchives(const UStringVector &archivePaths); + +#endif + diff --git a/CPP/7zip/UI/Common/DefaultName.cpp b/CPP/7zip/UI/Common/DefaultName.cpp new file mode 100755 index 00000000..8ee7c048 --- /dev/null +++ b/CPP/7zip/UI/Common/DefaultName.cpp @@ -0,0 +1,26 @@ +// DefaultName.cpp + +#include "StdAfx.h" + +#include "DefaultName.h" + +static const wchar_t *kEmptyFileAlias = L"[Content]"; + +UString GetDefaultName2(const UString &fileName, + const UString &extension, const UString &addSubExtension) +{ + int extLength = extension.Length(); + int fileNameLength = fileName.Length(); + if (fileNameLength > extLength + 1) + { + int dotPos = fileNameLength - (extLength + 1); + if (fileName[dotPos] == '.') + if (extension.CompareNoCase(fileName.Mid(dotPos + 1)) == 0) + return fileName.Left(dotPos) + addSubExtension; + } + int dotPos = fileName.ReverseFind(L'.'); + if (dotPos > 0) + return fileName.Left(dotPos) + addSubExtension; + return kEmptyFileAlias; +} + diff --git a/CPP/7zip/UI/Common/DefaultName.h b/CPP/7zip/UI/Common/DefaultName.h new file mode 100755 index 00000000..ff6330fa --- /dev/null +++ b/CPP/7zip/UI/Common/DefaultName.h @@ -0,0 +1,11 @@ +// DefaultName.h + +#ifndef __DEFAULTNAME_H +#define __DEFAULTNAME_H + +#include "Common/String.h" + +UString GetDefaultName2(const UString &fileName, + const UString &extension, const UString &addSubExtension); + +#endif diff --git a/CPP/7zip/UI/Common/DirItem.h b/CPP/7zip/UI/Common/DirItem.h new file mode 100755 index 00000000..9537071c --- /dev/null +++ b/CPP/7zip/UI/Common/DirItem.h @@ -0,0 +1,34 @@ +// DirItem.h + +#ifndef __DIR_ITEM_H +#define __DIR_ITEM_H + +#include "Common/String.h" +#include "Common/Types.h" + +struct CDirItem +{ + UInt32 Attributes; + FILETIME CreationTime; + FILETIME LastAccessTime; + FILETIME LastWriteTime; + UInt64 Size; + UString Name; + UString FullPath; + bool IsDirectory() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0 ; } +}; + +struct CArchiveItem +{ + bool IsDirectory; + // DWORD Attributes; + // NWindows::NCOM::CPropVariant LastWriteTime; + FILETIME LastWriteTime; + bool SizeIsDefined; + UInt64 Size; + UString Name; + bool Censored; + int IndexInServer; +}; + +#endif diff --git a/CPP/7zip/UI/Common/EnumDirItems.cpp b/CPP/7zip/UI/Common/EnumDirItems.cpp new file mode 100755 index 00000000..454092ec --- /dev/null +++ b/CPP/7zip/UI/Common/EnumDirItems.cpp @@ -0,0 +1,281 @@ +// EnumDirItems.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Common/Wildcard.h" +#include "Common/MyCom.h" + +#include "EnumDirItems.h" + +using namespace NWindows; +using namespace NFile; +using namespace NName; + +void AddDirFileInfo( + const UString &prefix, // prefix for logical path + const UString &fullPathName, // path on disk: can be relative to some basePrefix + const NFind::CFileInfoW &fileInfo, + CObjectVector &dirItems) +{ + CDirItem item; + item.Attributes = fileInfo.Attributes; + item.Size = fileInfo.Size; + item.CreationTime = fileInfo.CreationTime; + item.LastAccessTime = fileInfo.LastAccessTime; + item.LastWriteTime = fileInfo.LastWriteTime; + item.Name = prefix + fileInfo.Name; + item.FullPath = fullPathName; + dirItems.Add(item); +} + +static void EnumerateDirectory( + const UString &baseFolderPrefix, // base (disk) prefix for scanning + const UString &directory, // additional disk prefix starting from baseFolderPrefix + const UString &prefix, // logical prefix + CObjectVector &dirItems, + UStringVector &errorPaths, + CRecordVector &errorCodes) +{ + NFind::CEnumeratorW enumerator(baseFolderPrefix + directory + wchar_t(kAnyStringWildcard)); + for (;;) + { + NFind::CFileInfoW fileInfo; + bool found; + if (!enumerator.Next(fileInfo, found)) + { + errorCodes.Add(::GetLastError()); + errorPaths.Add(baseFolderPrefix + directory); + return; + } + if (!found) + break; + AddDirFileInfo(prefix, directory + fileInfo.Name, fileInfo, dirItems); + if (fileInfo.IsDirectory()) + { + EnumerateDirectory(baseFolderPrefix, directory + fileInfo.Name + wchar_t(kDirDelimiter), + prefix + fileInfo.Name + wchar_t(kDirDelimiter), dirItems, errorPaths, errorCodes); + } + } +} + +void EnumerateDirItems( + const UString &baseFolderPrefix, // base (disk) prefix for scanning + const UStringVector &fileNames, // names relative to baseFolderPrefix + const UString &archiveNamePrefix, + CObjectVector &dirItems, + UStringVector &errorPaths, + CRecordVector &errorCodes) +{ + for(int i = 0; i < fileNames.Size(); i++) + { + const UString &fileName = fileNames[i]; + NFind::CFileInfoW fileInfo; + if (!NFind::FindFile(baseFolderPrefix + fileName, fileInfo)) + { + errorCodes.Add(::GetLastError()); + errorPaths.Add(baseFolderPrefix + fileName); + continue; + } + AddDirFileInfo(archiveNamePrefix, fileName, fileInfo, dirItems); + if (fileInfo.IsDirectory()) + { + EnumerateDirectory(baseFolderPrefix, fileName + wchar_t(kDirDelimiter), + archiveNamePrefix + fileInfo.Name + wchar_t(kDirDelimiter), + dirItems, errorPaths, errorCodes); + } + } +} + +static HRESULT EnumerateDirItems( + const NWildcard::CCensorNode &curNode, + const UString &diskPrefix, // full disk path prefix + const UString &archivePrefix, // prefix from root + const UStringVector &addArchivePrefix, // prefix from curNode + CObjectVector &dirItems, + bool enterToSubFolders, + IEnumDirItemCallback *callback, + UStringVector &errorPaths, + CRecordVector &errorCodes) +{ + if (!enterToSubFolders) + if (curNode.NeedCheckSubDirs()) + enterToSubFolders = true; + if (callback) + RINOK(callback->CheckBreak()); + + // try direct_names case at first + if (addArchivePrefix.IsEmpty() && !enterToSubFolders) + { + // check that all names are direct + int i; + for (i = 0; i < curNode.IncludeItems.Size(); i++) + { + const NWildcard::CItem &item = curNode.IncludeItems[i]; + if (item.Recursive || item.PathParts.Size() != 1) + break; + const UString &name = item.PathParts.Front(); + if (name.IsEmpty() || DoesNameContainWildCard(name)) + break; + } + if (i == curNode.IncludeItems.Size()) + { + // all names are direct (no wildcards) + // so we don't need file_system's dir enumerator + CRecordVector needEnterVector; + for (i = 0; i < curNode.IncludeItems.Size(); i++) + { + const NWildcard::CItem &item = curNode.IncludeItems[i]; + const UString &name = item.PathParts.Front(); + const UString fullPath = diskPrefix + name; + NFind::CFileInfoW fileInfo; + if (!NFind::FindFile(fullPath, fileInfo)) + { + errorCodes.Add(::GetLastError()); + errorPaths.Add(fullPath); + continue; + } + bool isDir = fileInfo.IsDirectory(); + if (isDir && !item.ForDir || !isDir && !item.ForFile) + { + errorCodes.Add((DWORD)E_FAIL); + errorPaths.Add(fullPath); + continue; + } + const UString realName = fileInfo.Name; + const UString realDiskPath = diskPrefix + realName; + { + UStringVector pathParts; + pathParts.Add(fileInfo.Name); + if (curNode.CheckPathToRoot(false, pathParts, !isDir)) + continue; + } + AddDirFileInfo(archivePrefix, realDiskPath, fileInfo, dirItems); + if (!isDir) + continue; + + UStringVector addArchivePrefixNew; + const NWildcard::CCensorNode *nextNode = 0; + int index = curNode.FindSubNode(name); + if (index >= 0) + { + for (int t = needEnterVector.Size(); t <= index; t++) + needEnterVector.Add(true); + needEnterVector[index] = false; + nextNode = &curNode.SubNodes[index]; + } + else + { + nextNode = &curNode; + addArchivePrefixNew.Add(name); // don't change it to realName. It's for shortnames support + } + RINOK(EnumerateDirItems(*nextNode, + realDiskPath + wchar_t(kDirDelimiter), + archivePrefix + realName + wchar_t(kDirDelimiter), + addArchivePrefixNew, dirItems, true, callback, errorPaths, errorCodes)); + } + for (i = 0; i < curNode.SubNodes.Size(); i++) + { + if (i < needEnterVector.Size()) + if (!needEnterVector[i]) + continue; + const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i]; + const UString fullPath = diskPrefix + nextNode.Name; + NFind::CFileInfoW fileInfo; + if (!NFind::FindFile(fullPath, fileInfo)) + { + if (!nextNode.AreThereIncludeItems()) + continue; + errorCodes.Add(::GetLastError()); + errorPaths.Add(fullPath); + continue; + } + if (!fileInfo.IsDirectory()) + { + errorCodes.Add((DWORD)E_FAIL); + errorPaths.Add(fullPath); + continue; + } + RINOK(EnumerateDirItems(nextNode, + diskPrefix + fileInfo.Name + wchar_t(kDirDelimiter), + archivePrefix + fileInfo.Name + wchar_t(kDirDelimiter), + UStringVector(), dirItems, false, callback, errorPaths, errorCodes)); + } + return S_OK; + } + } + + + NFind::CEnumeratorW enumerator(diskPrefix + wchar_t(kAnyStringWildcard)); + for (;;) + { + NFind::CFileInfoW fileInfo; + bool found; + if (!enumerator.Next(fileInfo, found)) + { + errorCodes.Add(::GetLastError()); + errorPaths.Add(diskPrefix); + break; + } + if (!found) + break; + + if (callback) + RINOK(callback->CheckBreak()); + const UString &name = fileInfo.Name; + bool enterToSubFolders2 = enterToSubFolders; + UStringVector addArchivePrefixNew = addArchivePrefix; + addArchivePrefixNew.Add(name); + { + UStringVector addArchivePrefixNewTemp(addArchivePrefixNew); + if (curNode.CheckPathToRoot(false, addArchivePrefixNewTemp, !fileInfo.IsDirectory())) + continue; + } + if (curNode.CheckPathToRoot(true, addArchivePrefixNew, !fileInfo.IsDirectory())) + { + AddDirFileInfo(archivePrefix, diskPrefix + name, fileInfo, dirItems); + if (fileInfo.IsDirectory()) + enterToSubFolders2 = true; + } + if (!fileInfo.IsDirectory()) + continue; + + const NWildcard::CCensorNode *nextNode = 0; + if (addArchivePrefix.IsEmpty()) + { + int index = curNode.FindSubNode(name); + if (index >= 0) + nextNode = &curNode.SubNodes[index]; + } + if (!enterToSubFolders2 && nextNode == 0) + continue; + + addArchivePrefixNew = addArchivePrefix; + if (nextNode == 0) + { + nextNode = &curNode; + addArchivePrefixNew.Add(name); + } + RINOK(EnumerateDirItems(*nextNode, + diskPrefix + name + wchar_t(kDirDelimiter), + archivePrefix + name + wchar_t(kDirDelimiter), + addArchivePrefixNew, dirItems, enterToSubFolders2, callback, errorPaths, errorCodes)); + } + return S_OK; +} + +HRESULT EnumerateItems( + const NWildcard::CCensor &censor, + CObjectVector &dirItems, + IEnumDirItemCallback *callback, + UStringVector &errorPaths, + CRecordVector &errorCodes) +{ + for (int i = 0; i < censor.Pairs.Size(); i++) + { + const NWildcard::CPair &pair = censor.Pairs[i]; + RINOK(EnumerateDirItems(pair.Head, pair.Prefix, L"", UStringVector(), dirItems, false, + callback, errorPaths, errorCodes)); + } + return S_OK; +} diff --git a/CPP/7zip/UI/Common/EnumDirItems.h b/CPP/7zip/UI/Common/EnumDirItems.h new file mode 100755 index 00000000..8d5495a8 --- /dev/null +++ b/CPP/7zip/UI/Common/EnumDirItems.h @@ -0,0 +1,39 @@ +// EnumDirItems.h + +#ifndef __ENUM_DIR_ITEMS_H +#define __ENUM_DIR_ITEMS_H + +#include "Common/Wildcard.h" +#include "DirItem.h" + +#include "Windows/FileFind.h" + +void AddDirFileInfo( + const UString &prefix, + const UString &fullPathName, + const NWindows::NFile::NFind::CFileInfoW &fileInfo, + CObjectVector &dirItems); + + +void EnumerateDirItems( + const UString &baseFolderPrefix, + const UStringVector &fileNames, + const UString &archiveNamePrefix, + CObjectVector &dirItems, + UStringVector &errorPaths, + CRecordVector &errorCodes); + +struct IEnumDirItemCallback +{ + virtual HRESULT CheckBreak() { return S_OK; } +}; + + +HRESULT EnumerateItems( + const NWildcard::CCensor &censor, + CObjectVector &dirItems, + IEnumDirItemCallback *callback, + UStringVector &errorPaths, + CRecordVector &errorCodes); + +#endif diff --git a/CPP/7zip/UI/Common/ExitCode.h b/CPP/7zip/UI/Common/ExitCode.h new file mode 100755 index 00000000..0aac3695 --- /dev/null +++ b/CPP/7zip/UI/Common/ExitCode.h @@ -0,0 +1,27 @@ +// ExitCode.h + +#ifndef __EXIT_CODE_H +#define __EXIT_CODE_H + +namespace NExitCode { + +enum EEnum { + + kSuccess = 0, // Successful operation + kWarning = 1, // Non fatal error(s) occurred + kFatalError = 2, // A fatal error occurred + // kCRCError = 3, // A CRC error occurred when unpacking + // kLockedArchive = 4, // Attempt to modify an archive previously locked + // kWriteError = 5, // Write to disk error + // kOpenError = 6, // Open file error + kUserError = 7, // Command line option error + kMemoryError = 8, // Not enough memory for operation + // kCreateFileError = 9, // Create file error + + kUserBreak = 255 // User stopped the process + +}; + +} + +#endif diff --git a/CPP/7zip/UI/Common/Extract.cpp b/CPP/7zip/UI/Common/Extract.cpp new file mode 100755 index 00000000..34fb383b --- /dev/null +++ b/CPP/7zip/UI/Common/Extract.cpp @@ -0,0 +1,152 @@ +// Extract.cpp + +#include "StdAfx.h" + +#include "Extract.h" + +#include "Windows/Defs.h" +#include "Windows/FileDir.h" + +#include "OpenArchive.h" +#include "SetProperties.h" + +#ifndef EXCLUDE_COM +#include "Windows/DLL.h" +#endif + +using namespace NWindows; + +HRESULT DecompressArchive( + IInArchive *archive, + const UString &defaultName, + const NWildcard::CCensorNode &wildcardCensor, + const CExtractOptions &options, + IExtractCallbackUI *callback, + UString &errorMessage) +{ + CRecordVector realIndices; + UInt32 numItems; + RINOK(archive->GetNumberOfItems(&numItems)); + + for(UInt32 i = 0; i < numItems; i++) + { + UString filePath; + RINOK(GetArchiveItemPath(archive, i, options.DefaultItemName, filePath)); + bool isFolder; + RINOK(IsArchiveItemFolder(archive, i, isFolder)); + if (!wildcardCensor.CheckPath(filePath, !isFolder)) + continue; + realIndices.Add(i); + } + if (realIndices.Size() == 0) + { + callback->ThereAreNoFiles(); + return S_OK; + } + + CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback; + CMyComPtr extractCallback(extractCallbackSpec); + + UStringVector removePathParts; + + UString outDir = options.OutputDir; + outDir.Replace(L"*", defaultName); + if(!outDir.IsEmpty()) + if(!NFile::NDirectory::CreateComplexDirectory(outDir)) + { + HRESULT res = ::GetLastError(); + if (res == S_OK) + res = E_FAIL; + errorMessage = ((UString)L"Can not create output directory ") + outDir; + return res; + } + + extractCallbackSpec->Init( + archive, + callback, + options.StdOutMode, + outDir, + options.PathMode, + options.OverwriteMode, + removePathParts, + options.DefaultItemName, + options.ArchiveFileInfo.LastWriteTime, + options.ArchiveFileInfo.Attributes); + + #ifdef COMPRESS_MT + RINOK(SetProperties(archive, options.Properties)); + #endif + + HRESULT result = archive->Extract(&realIndices.Front(), + realIndices.Size(), options.TestMode? 1: 0, + extractCallback); + + return callback->ExtractResult(result); +} + +HRESULT DecompressArchives( + UStringVector &archivePaths, UStringVector &archivePathsFull, + const NWildcard::CCensorNode &wildcardCensor, + const CExtractOptions &optionsSpec, + IOpenCallbackUI *openCallback, + IExtractCallbackUI *extractCallback, + UString &errorMessage) +{ + CExtractOptions options = optionsSpec; + for (int i = 0; i < archivePaths.Size(); i++) + { + const UString &archivePath = archivePaths[i]; + NFile::NFind::CFileInfoW archiveFileInfo; + if (!NFile::NFind::FindFile(archivePath, archiveFileInfo)) + throw "there is no such archive"; + + if (archiveFileInfo.IsDirectory()) + throw "there is no such archive"; + + options.ArchiveFileInfo = archiveFileInfo; + + #ifndef _NO_CRYPTO + openCallback->ClearPasswordWasAskedFlag(); + #endif + + RINOK(extractCallback->BeforeOpen(archivePath)); + CArchiveLink archiveLink; + HRESULT result = MyOpenArchive(archivePath, archiveLink, openCallback); + + bool crypted = false; + #ifndef _NO_CRYPTO + crypted = openCallback->WasPasswordAsked(); + #endif + + RINOK(extractCallback->OpenResult(archivePath, result, crypted)); + if (result != S_OK) + continue; + + for (int v = 0; v < archiveLink.VolumePaths.Size(); v++) + { + int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]); + if (index >= 0 && index > i) + { + archivePaths.Delete(index); + archivePathsFull.Delete(index); + } + } + + #ifndef _NO_CRYPTO + UString password; + RINOK(openCallback->GetPasswordIfAny(password)); + if (!password.IsEmpty()) + { + RINOK(extractCallback->SetPassword(password)); + } + #endif + + options.DefaultItemName = archiveLink.GetDefaultItemName(); + RINOK(DecompressArchive( + archiveLink.GetArchive(), archiveLink.GetDefaultItemName(), + wildcardCensor, options, extractCallback, errorMessage)); + if (!errorMessage.IsEmpty()) + return E_FAIL; + } + return S_OK; +} diff --git a/CPP/7zip/UI/Common/Extract.h b/CPP/7zip/UI/Common/Extract.h new file mode 100755 index 00000000..c7b47c84 --- /dev/null +++ b/CPP/7zip/UI/Common/Extract.h @@ -0,0 +1,59 @@ +// Extract.h + +#ifndef __EXTRACT_H +#define __EXTRACT_H + +#include "Common/Wildcard.h" +#include "Windows/FileFind.h" + +#include "../../Archive/IArchive.h" + +#include "ArchiveExtractCallback.h" +#include "ArchiveOpenCallback.h" +#include "ExtractMode.h" +#include "Property.h" + +class CExtractOptions +{ +public: + bool StdOutMode; + bool TestMode; + NExtract::NPathMode::EEnum PathMode; + + UString OutputDir; + bool YesToAll; + UString DefaultItemName; + NWindows::NFile::NFind::CFileInfoW ArchiveFileInfo; + + // bool ShowDialog; + // bool PasswordEnabled; + // UString Password; + #ifdef COMPRESS_MT + CObjectVector Properties; + #endif + + NExtract::NOverwriteMode::EEnum OverwriteMode; + + CExtractOptions(): + StdOutMode(false), + YesToAll(false), + TestMode(false), + PathMode(NExtract::NPathMode::kFullPathnames), + OverwriteMode(NExtract::NOverwriteMode::kAskBefore) + {} + + /* + bool FullPathMode() const { return (ExtractMode == NExtractMode::kTest) || + (ExtractMode == NExtractMode::kFullPath); } + */ +}; + +HRESULT DecompressArchives( + UStringVector &archivePaths, UStringVector &archivePathsFull, + const NWildcard::CCensorNode &wildcardCensor, + const CExtractOptions &options, + IOpenCallbackUI *openCallback, + IExtractCallbackUI *extractCallback, + UString &errorMessage); + +#endif diff --git a/CPP/7zip/UI/Common/ExtractMode.h b/CPP/7zip/UI/Common/ExtractMode.h new file mode 100755 index 00000000..96b5a8cd --- /dev/null +++ b/CPP/7zip/UI/Common/ExtractMode.h @@ -0,0 +1,31 @@ +// ExtractMode.h + +#ifndef __EXTRACT_MODE_H +#define __EXTRACT_MODE_H + +namespace NExtract { + + namespace NPathMode + { + enum EEnum + { + kFullPathnames, + kCurrentPathnames, + kNoPathnames + }; + } + + namespace NOverwriteMode + { + enum EEnum + { + kAskBefore, + kWithoutPrompt, + kSkipExisting, + kAutoRename, + kAutoRenameExisting + }; + } +} + +#endif diff --git a/CPP/7zip/UI/Common/ExtractingFilePath.cpp b/CPP/7zip/UI/Common/ExtractingFilePath.cpp new file mode 100755 index 00000000..a0b17282 --- /dev/null +++ b/CPP/7zip/UI/Common/ExtractingFilePath.cpp @@ -0,0 +1,75 @@ +// ExtractingFilePath.cpp + +#include "StdAfx.h" +#include "ExtractingFilePath.h" + +static void ReplaceDisk(UString &s) +{ + int i; + for (i = 0; i < s.Length(); i++) + if (s[i] != ' ') + break; + if (s.Length() > i + 1) + { + if (s[i + 1] == L':') + { + s.Delete(i + 1); + // s.Insert(i + 1, L'_'); + } + } +} + +UString GetCorrectFileName(const UString &path) +{ + UString result = path; + { + UString test = path; + test.Trim(); + if (test == L"..") + result.Replace(L"..", L""); + } + ReplaceDisk(result); + return result; +} + +UString GetCorrectPath(const UString &path) +{ + UString result = path; + int first; + for (first = 0; first < result.Length(); first++) + if (result[first] != ' ') + break; + while(result.Length() > first) + { + if ( + #ifdef _WIN32 + result[first] == L'\\' || + #endif + result[first] == L'/') + { + result.Delete(first); + continue; + } + break; + } + #ifdef _WIN32 + result.Replace(L"..\\", L""); + #endif + result.Replace(L"../", L""); + + ReplaceDisk(result); + return result; +} + +void MakeCorrectPath(UStringVector &pathParts) +{ + for (int i = 0; i < pathParts.Size();) + { + UString &s = pathParts[i]; + s = GetCorrectFileName(s); + if (s.IsEmpty()) + pathParts.Delete(i); + else + i++; + } +} diff --git a/CPP/7zip/UI/Common/ExtractingFilePath.h b/CPP/7zip/UI/Common/ExtractingFilePath.h new file mode 100755 index 00000000..0ae9e9b8 --- /dev/null +++ b/CPP/7zip/UI/Common/ExtractingFilePath.h @@ -0,0 +1,12 @@ +// ExtractingFilePath.h + +#ifndef __EXTRACTINGFILEPATH_H +#define __EXTRACTINGFILEPATH_H + +#include "Common/String.h" + +UString GetCorrectFileName(const UString &path); +UString GetCorrectPath(const UString &path); +void MakeCorrectPath(UStringVector &pathParts); + +#endif diff --git a/CPP/7zip/UI/Common/HandlerLoader.h b/CPP/7zip/UI/Common/HandlerLoader.h new file mode 100755 index 00000000..2a878019 --- /dev/null +++ b/CPP/7zip/UI/Common/HandlerLoader.h @@ -0,0 +1,38 @@ +// HandlerLoader.h + +#ifndef __HANDLERLOADER_H +#define __HANDLERLOADER_H + +#include "../../ICoder.h" +#include "Windows/DLL.h" + +typedef UInt32 (WINAPI * CreateObjectFunc)( + const GUID *clsID, + const GUID *interfaceID, + void **outObject); + +class CHandlerLoader: public NWindows::NDLL::CLibrary +{ +public: + HRESULT CreateHandler(LPCWSTR filepath, REFGUID clsID, + void **archive, bool outHandler) + { + if (!Load(filepath)) + return GetLastError(); + CreateObjectFunc createObject = (CreateObjectFunc) + GetProcAddress("CreateObject"); + if (createObject == NULL) + { + HRESULT res = ::GetLastError(); + Free(); + return res; + } + HRESULT res = createObject(&clsID, + outHandler ? &IID_IOutArchive : &IID_IInArchive, (void **)archive); + if (res != 0) + Free(); + return res; + } +}; + +#endif diff --git a/CPP/7zip/UI/Common/IFileExtractCallback.h b/CPP/7zip/UI/Common/IFileExtractCallback.h new file mode 100755 index 00000000..c70d7021 --- /dev/null +++ b/CPP/7zip/UI/Common/IFileExtractCallback.h @@ -0,0 +1,46 @@ +// IFileExtractCallback.h + +#ifndef __IFILEEXTRACTCALLBACK_H +#define __IFILEEXTRACTCALLBACK_H + +#include "Common/String.h" + +namespace NOverwriteAnswer +{ + enum EEnum + { + kYes, + kYesToAll, + kNo, + kNoToAll, + kAutoRename, + kCancel, + }; +} + +// {23170F69-40C1-278A-0000-000100070000} +DEFINE_GUID(IID_IFolderArchiveExtractCallback, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000100070000") +IFolderArchiveExtractCallback: public IProgress +{ +public: + STDMETHOD(AskOverwrite)( + const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, + const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, + Int32 *answer) PURE; + STDMETHOD(PrepareOperation)(const wchar_t *name, Int32 askExtractMode, const UInt64 *position) PURE; + STDMETHOD(MessageError)(const wchar_t *message) PURE; + STDMETHOD(SetOperationResult)(Int32 operationResult, bool encrypted) PURE; +}; + +struct IExtractCallbackUI: IFolderArchiveExtractCallback +{ + virtual HRESULT BeforeOpen(const wchar_t *name) = 0; + virtual HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted) = 0; + virtual HRESULT ThereAreNoFiles() = 0; + virtual HRESULT ExtractResult(HRESULT result) = 0; + virtual HRESULT SetPassword(const UString &password) = 0; +}; + +#endif diff --git a/CPP/7zip/UI/Common/OpenArchive.cpp b/CPP/7zip/UI/Common/OpenArchive.cpp new file mode 100755 index 00000000..ce1a6de3 --- /dev/null +++ b/CPP/7zip/UI/Common/OpenArchive.cpp @@ -0,0 +1,531 @@ +// OpenArchive.cpp + +#include "StdAfx.h" + +#include "OpenArchive.h" + +#include "Common/Wildcard.h" + +#include "Windows/FileName.h" +#include "Windows/FileDir.h" +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" + +#include "../../Common/FileStreams.h" +#include "../../Common/StreamUtils.h" + +#include "Common/StringConvert.h" + +#ifdef FORMAT_7Z +#include "../../Archive/7z/7zHandler.h" +#endif + +#ifdef FORMAT_BZIP2 +#include "../../Archive/BZip2/BZip2Handler.h" +#endif + +#ifdef FORMAT_CAB +#include "../../Archive/Cab/CabHandler.h" +#endif + +#ifdef FORMAT_GZIP +#include "../../Archive/GZip/GZipHandler.h" +#endif + +#ifdef FORMAT_SPLIT +#include "../../Archive/Split/SplitHandler.h" +#endif + +#ifdef FORMAT_TAR +#include "../../Archive/Tar/TarHandler.h" +#endif + +#ifdef FORMAT_ZIP +#include "../../Archive/Zip/ZipHandler.h" +#endif + +#ifdef FORMAT_Z +#include "../../Archive/Z/ZHandler.h" +#endif + +#ifndef EXCLUDE_COM +#include "HandlerLoader.h" +#endif + +#include "DefaultName.h" + +using namespace NWindows; + +HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, UString &result) +{ + NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, kpidPath, &prop)); + if(prop.vt == VT_BSTR) + result = prop.bstrVal; + else if (prop.vt == VT_EMPTY) + result.Empty(); + else + return E_FAIL; + return S_OK; +} + +HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, const UString &defaultName, UString &result) +{ + RINOK(GetArchiveItemPath(archive, index, result)); + if (result.IsEmpty()) + result = defaultName; + return S_OK; +} + +HRESULT GetArchiveItemFileTime(IInArchive *archive, UInt32 index, + const FILETIME &defaultFileTime, FILETIME &fileTime) +{ + NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, kpidLastWriteTime, &prop)); + if (prop.vt == VT_FILETIME) + fileTime = prop.filetime; + else if (prop.vt == VT_EMPTY) + fileTime = defaultFileTime; + else + return E_FAIL; + return S_OK; +} + +static HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result) +{ + NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, propID, &prop)); + if(prop.vt == VT_BOOL) + result = VARIANT_BOOLToBool(prop.boolVal); + else if (prop.vt == VT_EMPTY) + result = false; + else + return E_FAIL; + return S_OK; +} + +HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result) +{ + return IsArchiveItemProp(archive, index, kpidIsFolder, result); +} + +HRESULT IsArchiveItemAnti(IInArchive *archive, UInt32 index, bool &result) +{ + return IsArchiveItemProp(archive, index, kpidIsAnti, result); +} + +// Static-SFX (for Linux) can be big. +const UInt64 kMaxCheckStartPosition = 1 << 22; + +HRESULT ReOpenArchive(IInArchive *archive, const UString &fileName) +{ + CInFileStream *inStreamSpec = new CInFileStream; + CMyComPtr inStream(inStreamSpec); + inStreamSpec->Open(fileName); + return archive->Open(inStream, &kMaxCheckStartPosition, NULL); +} + +#ifndef _SFX +static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size) +{ + for (size_t i = 0; i < size; i++) + if (p1[i] != p2[i]) + return false; + return true; +} +#endif + +HRESULT OpenArchive( + IInStream *inStream, + const UString &fileName, + #ifndef EXCLUDE_COM + HMODULE *module, + #endif + IInArchive **archiveResult, + CArchiverInfo &archiverInfoResult, + UString &defaultItemName, + IArchiveOpenCallback *openArchiveCallback) +{ + *archiveResult = NULL; + CObjectVector archiverInfoList; + ReadArchiverInfoList(archiverInfoList); + UString extension; + { + int dotPos = fileName.ReverseFind(L'.'); + if (dotPos >= 0) + extension = fileName.Mid(dotPos + 1); + } + CIntVector orderIndices; + int i; + bool finded = false; + for(i = 0; i < archiverInfoList.Size(); i++) + { + if (archiverInfoList[i].FindExtension(extension) >= 0) + { + orderIndices.Insert(0, i); + finded = true; + } + else + orderIndices.Add(i); + } + + #ifndef _SFX + if (!finded) + { + CByteBuffer byteBuffer; + const UInt32 kBufferSize = (200 << 10); + byteBuffer.SetCapacity(kBufferSize); + Byte *buffer = byteBuffer; + RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); + UInt32 processedSize; + RINOK(ReadStream(inStream, buffer, kBufferSize, &processedSize)); + int numFinded = 0; + for (int pos = (int)processedSize; pos >= 0 ; pos--) + { + for(int i = numFinded; i < orderIndices.Size(); i++) + { + int index = orderIndices[i]; + const CArchiverInfo &ai = archiverInfoList[index]; + const CByteBuffer &sig = ai.StartSignature; + if (sig.GetCapacity() == 0) + continue; + if (pos + sig.GetCapacity() > processedSize) + continue; + if (TestSignature(buffer + pos, sig, sig.GetCapacity())) + { + orderIndices.Delete(i); + orderIndices.Insert(0, index); + numFinded++; + } + } + } + } + #endif + + HRESULT badResult = S_OK; + for(i = 0; i < orderIndices.Size(); i++) + { + inStream->Seek(0, STREAM_SEEK_SET, NULL); + const CArchiverInfo &archiverInfo = archiverInfoList[orderIndices[i]]; + #ifndef EXCLUDE_COM + CHandlerLoader loader; + #endif + CMyComPtr archive; + + #ifdef FORMAT_7Z + if (archiverInfo.Name.CompareNoCase(L"7z") == 0) + archive = new NArchive::N7z::CHandler; + #endif + + #ifdef FORMAT_BZIP2 + if (archiverInfo.Name.CompareNoCase(L"BZip2") == 0) + archive = new NArchive::NBZip2::CHandler; + #endif + + #ifdef FORMAT_CAB + if (archiverInfo.Name.CompareNoCase(L"Cab") == 0) + archive = new NArchive::NCab::CHandler; + #endif + + #ifdef FORMAT_GZIP + if (archiverInfo.Name.CompareNoCase(L"GZip") == 0) + archive = new NArchive::NGZip::CHandler; + #endif + + #ifdef FORMAT_SPLIT + if (archiverInfo.Name.CompareNoCase(L"Split") == 0) + archive = new NArchive::NSplit::CHandler; + #endif + + #ifdef FORMAT_TAR + if (archiverInfo.Name.CompareNoCase(L"Tar") == 0) + archive = new NArchive::NTar::CHandler; + #endif + + #ifdef FORMAT_ZIP + if (archiverInfo.Name.CompareNoCase(L"Zip") == 0) + archive = new NArchive::NZip::CHandler; + #endif + + #ifdef FORMAT_Z + if (archiverInfo.Name.CompareNoCase(L"Z") == 0) + archive = new NArchive::NZ::CHandler; + #endif + + + #ifndef EXCLUDE_COM + if (!archive) + { + HRESULT result = loader.CreateHandler(archiverInfo.FilePath, + archiverInfo.ClassID, (void **)&archive, false); + if (result != S_OK) + continue; + } + #endif + + if (!archive) + return E_FAIL; + + HRESULT result = archive->Open(inStream, &kMaxCheckStartPosition, openArchiveCallback); + if(result == S_FALSE) + continue; + if(result != S_OK) + { + badResult = result; + if(result == E_ABORT) + break; + continue; + } + *archiveResult = archive.Detach(); + #ifndef EXCLUDE_COM + *module = loader.Detach(); + #endif + archiverInfoResult = archiverInfo; + int subExtIndex = archiverInfo.FindExtension(extension); + if (subExtIndex < 0) + subExtIndex = 0; + defaultItemName = GetDefaultName2(fileName, + archiverInfo.Extensions[subExtIndex].Ext, + archiverInfo.Extensions[subExtIndex].AddExt); + + return S_OK; + } + if (badResult != S_OK) + return badResult; + return S_FALSE; +} + +HRESULT OpenArchive(const UString &filePath, + #ifndef EXCLUDE_COM + HMODULE *module, + #endif + IInArchive **archiveResult, + CArchiverInfo &archiverInfo, + UString &defaultItemName, + IArchiveOpenCallback *openArchiveCallback) +{ + CInFileStream *inStreamSpec = new CInFileStream; + CMyComPtr inStream(inStreamSpec); + if (!inStreamSpec->Open(filePath)) + return GetLastError(); + return OpenArchive(inStream, ExtractFileNameFromPath(filePath), + #ifndef EXCLUDE_COM + module, + #endif + archiveResult, archiverInfo, + defaultItemName, openArchiveCallback); +} + +static void MakeDefaultName(UString &name) +{ + int dotPos = name.ReverseFind(L'.'); + if (dotPos < 0) + return; + UString ext = name.Mid(dotPos + 1); + if (ext.IsEmpty()) + return; + for (int pos = 0; pos < ext.Length(); pos++) + if (ext[pos] < L'0' || ext[pos] > L'9') + return; + name = name.Left(dotPos); +} + +HRESULT OpenArchive(const UString &fileName, + #ifndef EXCLUDE_COM + HMODULE *module0, + HMODULE *module1, + #endif + IInArchive **archive0, + IInArchive **archive1, + CArchiverInfo &archiverInfo0, + CArchiverInfo &archiverInfo1, + UString &defaultItemName0, + UString &defaultItemName1, + IArchiveOpenCallback *openArchiveCallback) +{ + HRESULT result = OpenArchive(fileName, + #ifndef EXCLUDE_COM + module0, + #endif + archive0, archiverInfo0, defaultItemName0, openArchiveCallback); + RINOK(result); + CMyComPtr getStream; + result = (*archive0)->QueryInterface(IID_IInArchiveGetStream, (void **)&getStream); + if (result != S_OK || getStream == 0) + return S_OK; + + CMyComPtr subSeqStream; + result = getStream->GetStream(0, &subSeqStream); + if (result != S_OK) + return S_OK; + + CMyComPtr subStream; + if (subSeqStream.QueryInterface(IID_IInStream, &subStream) != S_OK) + return S_OK; + if (!subStream) + return S_OK; + + UInt32 numItems; + RINOK((*archive0)->GetNumberOfItems(&numItems)); + if (numItems < 1) + return S_OK; + + UString subPath; + RINOK(GetArchiveItemPath(*archive0, 0, subPath)) + if (subPath.IsEmpty()) + { + MakeDefaultName(defaultItemName0); + subPath = defaultItemName0; + if (archiverInfo0.Name.CompareNoCase(L"7z") == 0) + { + if (subPath.Right(3).CompareNoCase(L".7z") != 0) + subPath += L".7z"; + } + } + else + subPath = ExtractFileNameFromPath(subPath); + + CMyComPtr setSubArchiveName; + openArchiveCallback->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName); + if (setSubArchiveName) + setSubArchiveName->SetSubArchiveName(subPath); + + result = OpenArchive(subStream, subPath, + #ifndef EXCLUDE_COM + module1, + #endif + archive1, archiverInfo1, defaultItemName1, openArchiveCallback); + return S_OK; +} + +HRESULT MyOpenArchive(const UString &archiveName, + #ifndef EXCLUDE_COM + HMODULE *module, + #endif + IInArchive **archive, + UString &defaultItemName, + IOpenCallbackUI *openCallbackUI) +{ + COpenCallbackImp *openCallbackSpec = new COpenCallbackImp; + CMyComPtr openCallback = openCallbackSpec; + openCallbackSpec->Callback = openCallbackUI; + + UString fullName; + int fileNamePartStartIndex; + NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartIndex); + openCallbackSpec->Init( + fullName.Left(fileNamePartStartIndex), + fullName.Mid(fileNamePartStartIndex)); + + CArchiverInfo archiverInfo; + return OpenArchive(archiveName, + #ifndef EXCLUDE_COM + module, + #endif + archive, + archiverInfo, + defaultItemName, + openCallback); +} + +HRESULT MyOpenArchive(const UString &archiveName, + #ifndef EXCLUDE_COM + HMODULE *module0, + HMODULE *module1, + #endif + IInArchive **archive0, + IInArchive **archive1, + UString &defaultItemName0, + UString &defaultItemName1, + UStringVector &volumePaths, + IOpenCallbackUI *openCallbackUI) +{ + COpenCallbackImp *openCallbackSpec = new COpenCallbackImp; + CMyComPtr openCallback = openCallbackSpec; + openCallbackSpec->Callback = openCallbackUI; + + UString fullName; + int fileNamePartStartIndex; + NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartIndex); + UString prefix = fullName.Left(fileNamePartStartIndex); + UString name = fullName.Mid(fileNamePartStartIndex); + openCallbackSpec->Init(prefix, name); + + CArchiverInfo archiverInfo0, archiverInfo1; + HRESULT result = OpenArchive(archiveName, + #ifndef EXCLUDE_COM + module0, + module1, + #endif + archive0, + archive1, + archiverInfo0, + archiverInfo1, + defaultItemName0, + defaultItemName1, + openCallback); + RINOK(result); + volumePaths.Add(prefix + name); + for (int i = 0; i < openCallbackSpec->FileNames.Size(); i++) + volumePaths.Add(prefix + openCallbackSpec->FileNames[i]); + return S_OK; +} + +HRESULT CArchiveLink::Close() +{ + if (Archive1 != 0) + RINOK(Archive1->Close()); + if (Archive0 != 0) + RINOK(Archive0->Close()); + return S_OK; +} + +void CArchiveLink::Release() +{ + if (Archive1 != 0) + Archive1.Release(); + if (Archive0 != 0) + Archive0.Release(); + #ifndef EXCLUDE_COM + Library1.Free(); + Library0.Free(); + #endif +} + +HRESULT OpenArchive(const UString &archiveName, + CArchiveLink &archiveLink, + IArchiveOpenCallback *openCallback) +{ + return OpenArchive(archiveName, + #ifndef EXCLUDE_COM + &archiveLink.Library0, &archiveLink.Library1, + #endif + &archiveLink.Archive0, &archiveLink.Archive1, + archiveLink.ArchiverInfo0, archiveLink.ArchiverInfo1, + archiveLink.DefaultItemName0, archiveLink.DefaultItemName1, + openCallback); +} + +HRESULT MyOpenArchive(const UString &archiveName, + CArchiveLink &archiveLink, + IOpenCallbackUI *openCallbackUI) +{ + return MyOpenArchive(archiveName, + #ifndef EXCLUDE_COM + &archiveLink.Library0, &archiveLink.Library1, + #endif + &archiveLink.Archive0, &archiveLink.Archive1, + archiveLink.DefaultItemName0, archiveLink.DefaultItemName1, + archiveLink.VolumePaths, + openCallbackUI); +} + +HRESULT ReOpenArchive(CArchiveLink &archiveLink, + const UString &fileName) +{ + if (archiveLink.GetNumLevels() > 1) + return E_NOTIMPL; + if (archiveLink.GetNumLevels() == 0) + return MyOpenArchive(fileName, archiveLink, 0); + return ReOpenArchive(archiveLink.GetArchive(), fileName); +} diff --git a/CPP/7zip/UI/Common/OpenArchive.h b/CPP/7zip/UI/Common/OpenArchive.h new file mode 100755 index 00000000..f96b1ebf --- /dev/null +++ b/CPP/7zip/UI/Common/OpenArchive.h @@ -0,0 +1,134 @@ +// OpenArchive.h + +#ifndef __OPENARCHIVE_H +#define __OPENARCHIVE_H + +#include "Common/String.h" +#include "Windows/FileFind.h" + +#include "../../Archive/IArchive.h" +#include "ArchiverInfo.h" +#include "ArchiveOpenCallback.h" + +#ifndef EXCLUDE_COM +#include "Windows/DLL.h" +#endif + +HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, UString &result); +HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, const UString &defaultName, UString &result); +HRESULT GetArchiveItemFileTime(IInArchive *archive, UInt32 index, + const FILETIME &defaultFileTime, FILETIME &fileTime); +HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result); +HRESULT IsArchiveItemAnti(IInArchive *archive, UInt32 index, bool &result); + +struct ISetSubArchiveName +{ + virtual void SetSubArchiveName(const wchar_t *name) = 0; +}; + +HRESULT OpenArchive( + IInStream *inStream, + const UString &fileName, + #ifndef EXCLUDE_COM + HMODULE *module, + #endif + IInArchive **archiveResult, + CArchiverInfo &archiverInfoResult, + UString &defaultItemName, + IArchiveOpenCallback *openArchiveCallback); + +HRESULT OpenArchive(const UString &filePath, + #ifndef EXCLUDE_COM + HMODULE *module, + #endif + IInArchive **archive, + CArchiverInfo &archiverInfo, + UString &defaultItemName, + IArchiveOpenCallback *openArchiveCallback); + +HRESULT OpenArchive(const UString &filePath, + #ifndef EXCLUDE_COM + HMODULE *module0, + HMODULE *module1, + #endif + IInArchive **archive0, + IInArchive **archive1, + CArchiverInfo &archiverInfo0, + CArchiverInfo &archiverInfo1, + UString &defaultItemName0, + UString &defaultItemName1, + IArchiveOpenCallback *openArchiveCallback); + + +HRESULT ReOpenArchive(IInArchive *archive, + const UString &fileName); + +HRESULT MyOpenArchive(const UString &archiveName, + #ifndef EXCLUDE_COM + HMODULE *module, + #endif + IInArchive **archive, + UString &defaultItemName, + IOpenCallbackUI *openCallbackUI); + +HRESULT MyOpenArchive(const UString &archiveName, + #ifndef EXCLUDE_COM + HMODULE *module0, + HMODULE *module1, + #endif + IInArchive **archive0, + IInArchive **archive1, + UString &defaultItemName0, + UString &defaultItemName1, + UStringVector &volumePaths, + IOpenCallbackUI *openCallbackUI); + +struct CArchiveLink +{ + #ifndef EXCLUDE_COM + NWindows::NDLL::CLibrary Library0; + NWindows::NDLL::CLibrary Library1; + #endif + CMyComPtr Archive0; + CMyComPtr Archive1; + UString DefaultItemName0; + UString DefaultItemName1; + + CArchiverInfo ArchiverInfo0; + CArchiverInfo ArchiverInfo1; + + UStringVector VolumePaths; + + int GetNumLevels() const + { + int result = 0; + if (Archive0) + { + result++; + if (Archive1) + result++; + } + return result; + } + + + IInArchive *GetArchive() { return Archive1 != 0 ? Archive1: Archive0; } + UString GetDefaultItemName() { return Archive1 != 0 ? DefaultItemName1: DefaultItemName0; } + const CArchiverInfo &GetArchiverInfo() { return Archive1 != 0 ? ArchiverInfo1: ArchiverInfo0; } + HRESULT Close(); + void Release(); +}; + +HRESULT OpenArchive(const UString &archiveName, + CArchiveLink &archiveLink, + IArchiveOpenCallback *openCallback); + +HRESULT MyOpenArchive(const UString &archiveName, + CArchiveLink &archiveLink, + IOpenCallbackUI *openCallbackUI); + +HRESULT ReOpenArchive(CArchiveLink &archiveLink, + const UString &fileName); + +#endif + diff --git a/CPP/7zip/UI/Common/PropIDUtils.cpp b/CPP/7zip/UI/Common/PropIDUtils.cpp new file mode 100755 index 00000000..8869e565 --- /dev/null +++ b/CPP/7zip/UI/Common/PropIDUtils.cpp @@ -0,0 +1,90 @@ +// PropIDUtils.cpp + +#include "StdAfx.h" + +#include "PropIDUtils.h" + +#include "Common/IntToString.h" +#include "Common/StringConvert.h" + +#include "Windows/FileFind.h" +#include "Windows/PropVariantConversions.h" + +#include "../../PropID.h" + +using namespace NWindows; + +static UString ConvertUInt32ToString(UInt32 value) +{ + wchar_t buffer[32]; + ConvertUInt64ToString(value, buffer); + return buffer; +} + +static void ConvertUInt32ToHex(UInt32 value, wchar_t *s) +{ + for (int i = 0; i < 8; i++) + { + int t = value & 0xF; + value >>= 4; + s[7 - i] = (wchar_t)((t < 10) ? (L'0' + t) : (L'A' + (t - 10))); + } + s[8] = L'\0'; +} + +UString ConvertPropertyToString(const PROPVARIANT &propVariant, + PROPID propID, bool full) +{ + switch(propID) + { + case kpidCreationTime: + case kpidLastWriteTime: + case kpidLastAccessTime: + { + if (propVariant.vt != VT_FILETIME) + return UString(); // It is error; + FILETIME localFileTime; + if (propVariant.filetime.dwHighDateTime == 0 && + propVariant.filetime.dwLowDateTime == 0) + return UString(); + if (!::FileTimeToLocalFileTime(&propVariant.filetime, &localFileTime)) + return UString(); // It is error; + return ConvertFileTimeToString(localFileTime, true, full); + } + case kpidCRC: + { + if(propVariant.vt != VT_UI4) + break; + wchar_t temp[12]; + ConvertUInt32ToHex(propVariant.ulVal, temp); + return temp; + } + case kpidAttributes: + { + if(propVariant.vt != VT_UI4) + break; + UString result; + UInt32 attributes = propVariant.ulVal; + if (NFile::NFind::NAttributes::IsReadOnly(attributes)) result += L'R'; + if (NFile::NFind::NAttributes::IsHidden(attributes)) result += L'H'; + if (NFile::NFind::NAttributes::IsSystem(attributes)) result += L'S'; + if (NFile::NFind::NAttributes::IsDirectory(attributes)) result += L'D'; + if (NFile::NFind::NAttributes::IsArchived(attributes)) result += L'A'; + if (NFile::NFind::NAttributes::IsCompressed(attributes)) result += L'C'; + if (NFile::NFind::NAttributes::IsEncrypted(attributes)) result += L'E'; + return result; + } + case kpidDictionarySize: + { + if(propVariant.vt != VT_UI4) + break; + UInt32 size = propVariant.ulVal; + if (size % (1 << 20) == 0) + return ConvertUInt32ToString(size >> 20) + L"MB"; + if (size % (1 << 10) == 0) + return ConvertUInt32ToString(size >> 10) + L"KB"; + return ConvertUInt32ToString(size); + } + } + return ConvertPropVariantToString(propVariant); +} diff --git a/CPP/7zip/UI/Common/PropIDUtils.h b/CPP/7zip/UI/Common/PropIDUtils.h new file mode 100755 index 00000000..aa540885 --- /dev/null +++ b/CPP/7zip/UI/Common/PropIDUtils.h @@ -0,0 +1,11 @@ +// PropIDUtils.h + +#ifndef __PROPIDUTILS_H +#define __PROPIDUTILS_H + +#include "Common/String.h" + +UString ConvertPropertyToString(const PROPVARIANT &aPropVariant, + PROPID aPropID, bool aFull = true); + +#endif diff --git a/CPP/7zip/UI/Common/Property.h b/CPP/7zip/UI/Common/Property.h new file mode 100755 index 00000000..57e7b452 --- /dev/null +++ b/CPP/7zip/UI/Common/Property.h @@ -0,0 +1,14 @@ +// Property.h + +#ifndef __PROPERTY_H +#define __PROPERTY_H + +#include "Common/String.h" + +struct CProperty +{ + UString Name; + UString Value; +}; + +#endif diff --git a/CPP/7zip/UI/Common/SetProperties.cpp b/CPP/7zip/UI/Common/SetProperties.cpp new file mode 100755 index 00000000..6c92a847 --- /dev/null +++ b/CPP/7zip/UI/Common/SetProperties.cpp @@ -0,0 +1,65 @@ +// SetProperties.cpp + +#include "StdAfx.h" + +#include "SetProperties.h" + +#include "Windows/PropVariant.h" +#include "Common/String.h" +#include "Common/StringToInt.h" +#include "Common/MyCom.h" + +#include "../../Archive/IArchive.h" + +using namespace NWindows; +using namespace NCOM; + +static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop) +{ + const wchar_t *endPtr; + UInt64 result = ConvertStringToUInt64(s, &endPtr); + if (endPtr - (const wchar_t *)s != s.Length()) + prop = s; + else if (result <= 0xFFFFFFFF) + prop = (UInt32)result; + else + prop = result; +} + +HRESULT SetProperties(IUnknown *unknown, const CObjectVector &properties) +{ + if (properties.IsEmpty()) + return S_OK; + CMyComPtr setProperties; + unknown->QueryInterface(IID_ISetProperties, (void **)&setProperties); + if (!setProperties) + return S_OK; + + UStringVector realNames; + CPropVariant *values = new CPropVariant[properties.Size()]; + try + { + int i; + for(i = 0; i < properties.Size(); i++) + { + const CProperty &property = properties[i]; + NCOM::CPropVariant propVariant; + if (!property.Value.IsEmpty()) + ParseNumberString(property.Value, propVariant); + realNames.Add(property.Name); + values[i] = propVariant; + } + CRecordVector names; + for(i = 0; i < realNames.Size(); i++) + names.Add((const wchar_t *)realNames[i]); + + RINOK(setProperties->SetProperties(&names.Front(), values, names.Size())); + } + catch(...) + { + delete []values; + throw; + } + delete []values; + return S_OK; +} diff --git a/CPP/7zip/UI/Common/SetProperties.h b/CPP/7zip/UI/Common/SetProperties.h new file mode 100755 index 00000000..892f1a21 --- /dev/null +++ b/CPP/7zip/UI/Common/SetProperties.h @@ -0,0 +1,10 @@ +// SetProperties.h + +#ifndef __SETPROPERTIES_H +#define __SETPROPERTIES_H + +#include "Property.h" + +HRESULT SetProperties(IUnknown *unknown, const CObjectVector &properties); + +#endif diff --git a/CPP/7zip/UI/Common/SortUtils.cpp b/CPP/7zip/UI/Common/SortUtils.cpp new file mode 100755 index 00000000..c0111581 --- /dev/null +++ b/CPP/7zip/UI/Common/SortUtils.cpp @@ -0,0 +1,78 @@ +// SortUtils.cpp + +#include "StdAfx.h" + +#include "SortUtils.h" +#include "Common/Types.h" + +/* +template +void TSortRefDown(T *p, UInt32 k, UInt32 size, int (*compare)(const T*, const T*, void *), void *param) +{ + T temp = p[k]; + for (;;) + { + UInt32 s = (k << 1); + if (s > size) + break; + if (s < size && compare(p + s + 1, p + s, param) > 0) + s++; + if (compare(&temp, p + s, param) >= 0) + break; + p[k] = p[s]; + k = s; + } + p[k] = temp; +} + +template +void TSort(T* p, UInt32 size, int (*compare)(const T*, const T*, void *), void *param) +{ + if (size <= 1) + return; + p--; + { + UInt32 i = size / 2; + do + TSortRefDown(p, i, size, compare, param); + while(--i != 0); + } + do + { + T temp = p[size]; + p[size--] = p[1]; + p[1] = temp; + TSortRefDown(p, 1, size, compare, param); + } + while (size > 1); +} +*/ + +static int CompareStrings(const int *p1, const int *p2, void *param) +{ + const UStringVector &strings = *(const UStringVector *)param; + const UString &s1 = strings[*p1]; + const UString &s2 = strings[*p2]; + return s1.CompareNoCase(s2); +} + +void SortStringsToIndices(const UStringVector &strings, CIntVector &indices) +{ + indices.Clear(); + int numItems = strings.Size(); + indices.Reserve(numItems); + for(int i = 0; i < numItems; i++) + indices.Add(i); + indices.Sort(CompareStrings, (void *)&strings); + // TSort(&indices.Front(), indices.Size(), CompareStrings, (void *)&strings); +} + +void SortStrings(const UStringVector &src, UStringVector &dest) +{ + CIntVector indices; + SortStringsToIndices(src, indices); + dest.Clear(); + dest.Reserve(indices.Size()); + for (int i = 0; i < indices.Size(); i++) + dest.Add(src[indices[i]]); +} diff --git a/CPP/7zip/UI/Common/SortUtils.h b/CPP/7zip/UI/Common/SortUtils.h new file mode 100755 index 00000000..5b9af264 --- /dev/null +++ b/CPP/7zip/UI/Common/SortUtils.h @@ -0,0 +1,11 @@ +// SortUtils.h + +#ifndef __SORTUTLS_H +#define __SORTUTLS_H + +#include "Common/String.h" + +void SortStringsToIndices(const UStringVector &strings, CIntVector &indices); +void SortStrings(const UStringVector &src, UStringVector &dest); + +#endif diff --git a/CPP/7zip/UI/Common/StdAfx.h b/CPP/7zip/UI/Common/StdAfx.h new file mode 100755 index 00000000..100f4344 --- /dev/null +++ b/CPP/7zip/UI/Common/StdAfx.h @@ -0,0 +1,9 @@ +// stdafx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" +#include "../../../Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/UI/Common/TempFiles.cpp b/CPP/7zip/UI/Common/TempFiles.cpp new file mode 100755 index 00000000..3e604aea --- /dev/null +++ b/CPP/7zip/UI/Common/TempFiles.cpp @@ -0,0 +1,22 @@ +// TempFiles.cpp + +#include "StdAfx.h" + +#include "TempFiles.h" + +#include "Windows/FileDir.h" +#include "Windows/FileIO.h" + +using namespace NWindows; +using namespace NFile; + +void CTempFiles::Clear() +{ + while(!Paths.IsEmpty()) + { + NDirectory::DeleteFileAlways(Paths.Back()); + Paths.DeleteBack(); + } +} + + diff --git a/CPP/7zip/UI/Common/TempFiles.h b/CPP/7zip/UI/Common/TempFiles.h new file mode 100755 index 00000000..173713a0 --- /dev/null +++ b/CPP/7zip/UI/Common/TempFiles.h @@ -0,0 +1,16 @@ +// TempFiles.h + +#ifndef __TEMPFILES_H +#define __TEMPFILES_H + +#include "Common/String.h" + +class CTempFiles +{ + void Clear(); +public: + UStringVector Paths; + ~CTempFiles() { Clear(); } +}; + +#endif diff --git a/CPP/7zip/UI/Common/Update.cpp b/CPP/7zip/UI/Common/Update.cpp new file mode 100755 index 00000000..cd7975d0 --- /dev/null +++ b/CPP/7zip/UI/Common/Update.cpp @@ -0,0 +1,818 @@ +// Update.cpp + +#include "StdAfx.h" + +#ifdef _WIN32 +#include +#endif + +#include "Update.h" + +#include "Common/IntToString.h" +#include "Common/StringConvert.h" +#include "Common/CommandLineParser.h" + +#ifdef _WIN32 +#include "Windows/DLL.h" +#endif + +#include "Windows/Defs.h" +#include "Windows/FileDir.h" +#include "Windows/FileFind.h" +#include "Windows/FileName.h" +#include "Windows/PropVariant.h" +#include "Windows/PropVariantConversions.h" +// #include "Windows/Synchronization.h" + +#include "../../Common/FileStreams.h" +#include "../../Compress/Copy/CopyCoder.h" + +#include "../Common/DirItem.h" +#include "../Common/EnumDirItems.h" +#include "../Common/UpdateProduce.h" +#include "../Common/OpenArchive.h" + +#include "TempFiles.h" +#include "UpdateCallback.h" +#include "EnumDirItems.h" +#include "SetProperties.h" + +#ifdef FORMAT_7Z +#include "../../Archive/7z/7zHandler.h" +#endif + +#ifdef FORMAT_BZIP2 +#include "../../Archive/BZip2/BZip2Handler.h" +#endif + +#ifdef FORMAT_GZIP +#include "../../Archive/GZip/GZipHandler.h" +#endif + +#ifdef FORMAT_TAR +#include "../../Archive/Tar/TarHandler.h" +#endif + +#ifdef FORMAT_ZIP +#include "../../Archive/Zip/ZipHandler.h" +#endif + +#ifndef EXCLUDE_COM +#include "../Common/HandlerLoader.h" +#endif + +static const char *kUpdateIsNotSupoorted = + "update operations are not supported for this archive"; + +using namespace NCommandLineParser; +using namespace NWindows; +using namespace NCOM; +using namespace NFile; +using namespace NName; + +static const wchar_t *kTempArchiveFilePrefixString = L"7zi"; +static const wchar_t *kTempFolderPrefix = L"7zE"; + +static const char *kIllegalFileNameMessage = "Illegal file name for temp archive"; + +using namespace NUpdateArchive; + +static HRESULT CopyBlock(ISequentialInStream *inStream, ISequentialOutStream *outStream) +{ + CMyComPtr copyCoder = new NCompress::CCopyCoder; + return copyCoder->Code(inStream, outStream, NULL, NULL, NULL); +} + +class COutMultiVolStream: + public IOutStream, + public CMyUnknownImp +{ + int _streamIndex; // required stream + UInt64 _offsetPos; // offset from start of _streamIndex index + UInt64 _absPos; + UInt64 _length; + + struct CSubStreamInfo + { + CMyComPtr Stream; + UString Name; + UInt64 Pos; + UInt64 RealSize; + }; + CObjectVector Streams; +public: + // CMyComPtr VolumeCallback; + CRecordVector Sizes; + UString Prefix; + CTempFiles *TempFiles; + + void Init() + { + _streamIndex = 0; + _offsetPos = 0; + _absPos = 0; + _length = 0; + } + + MY_UNKNOWN_IMP1(IOutStream) + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); + STDMETHOD(SetSize)(Int64 newSize); +}; + +// static NSynchronization::CCriticalSection g_TempPathsCS; + +STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if(processedSize != NULL) + *processedSize = 0; + while(size > 0) + { + if (_streamIndex >= Streams.Size()) + { + CSubStreamInfo subStream; + + wchar_t temp[32]; + ConvertUInt64ToString(_streamIndex + 1, temp); + UString res = temp; + while (res.Length() < 3) + res = UString(L'0') + res; + UString name = Prefix + res; + COutFileStream *streamSpec = new COutFileStream; + subStream.Stream = streamSpec; + if(!streamSpec->Create(name, false)) + return ::GetLastError(); + { + // NSynchronization::CCriticalSectionLock lock(g_TempPathsCS); + TempFiles->Paths.Add(name); + } + + subStream.Pos = 0; + subStream.RealSize = 0; + subStream.Name = name; + Streams.Add(subStream); + continue; + } + CSubStreamInfo &subStream = Streams[_streamIndex]; + + int index = _streamIndex; + if (index >= Sizes.Size()) + index = Sizes.Size() - 1; + UInt64 volSize = Sizes[index]; + + if (_offsetPos >= volSize) + { + _offsetPos -= volSize; + _streamIndex++; + continue; + } + if (_offsetPos != subStream.Pos) + { + // CMyComPtr outStream; + // RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream)); + RINOK(subStream.Stream->Seek(_offsetPos, STREAM_SEEK_SET, NULL)); + subStream.Pos = _offsetPos; + } + + UInt32 curSize = (UInt32)MyMin((UInt64)size, volSize - subStream.Pos); + UInt32 realProcessed; + RINOK(subStream.Stream->Write(data, curSize, &realProcessed)); + data = (void *)((Byte *)data + realProcessed); + size -= realProcessed; + subStream.Pos += realProcessed; + _offsetPos += realProcessed; + _absPos += realProcessed; + if (_absPos > _length) + _length = _absPos; + if (_offsetPos > subStream.RealSize) + subStream.RealSize = _offsetPos; + if(processedSize != NULL) + *processedSize += realProcessed; + if (subStream.Pos == volSize) + { + _streamIndex++; + _offsetPos = 0; + } + if (realProcessed == 0 && curSize != 0) + return E_FAIL; + break; + } + return S_OK; +} + +STDMETHODIMP COutMultiVolStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +{ + if(seekOrigin >= 3) + return STG_E_INVALIDFUNCTION; + switch(seekOrigin) + { + case STREAM_SEEK_SET: + _absPos = offset; + break; + case STREAM_SEEK_CUR: + _absPos += offset; + break; + case STREAM_SEEK_END: + _absPos = _length + offset; + break; + } + _offsetPos = _absPos; + if (newPosition != NULL) + *newPosition = _absPos; + _streamIndex = 0; + return S_OK; +} + +STDMETHODIMP COutMultiVolStream::SetSize(Int64 newSize) +{ + if (newSize < 0) + return E_INVALIDARG; + int i = 0; + while (i < Streams.Size()) + { + CSubStreamInfo &subStream = Streams[i++]; + if ((UInt64)newSize < subStream.RealSize) + { + RINOK(subStream.Stream->SetSize(newSize)); + subStream.RealSize = newSize; + break; + } + newSize -= subStream.RealSize; + } + while (i < Streams.Size()) + { + { + CSubStreamInfo &subStream = Streams.Back(); + subStream.Stream.Release(); + NDirectory::DeleteFileAlways(subStream.Name); + } + Streams.DeleteBack(); + } + _offsetPos = _absPos; + _streamIndex = 0; + _length = newSize; + return S_OK; +} + + +static HRESULT Compress( + const CActionSet &actionSet, + IInArchive *archive, + const CCompressionMethodMode &compressionMethod, + CArchivePath &archivePath, + const CObjectVector &archiveItems, + bool stdInMode, + /* const UString & stdInFileName, */ + bool stdOutMode, + const CObjectVector &dirItems, + bool sfxMode, + const UString &sfxModule, + const CRecordVector &volumesSizes, + CTempFiles &tempFiles, + CUpdateErrorInfo &errorInfo, + IUpdateCallbackUI *callback) +{ + #ifndef EXCLUDE_COM + CHandlerLoader loader; + #endif + + CMyComPtr outArchive; + if(archive != NULL) + { + CMyComPtr archive2 = archive; + HRESULT result = archive2.QueryInterface(IID_IOutArchive, &outArchive); + if(result != S_OK) + throw kUpdateIsNotSupoorted; + } + else + { + #ifndef EXCLUDE_COM + + if (loader.CreateHandler(compressionMethod.FilePath, + compressionMethod.ClassID, (void **)&outArchive, true) != S_OK) + throw kUpdateIsNotSupoorted; + #endif + + #ifdef FORMAT_7Z + if (compressionMethod.Name.CompareNoCase(L"7z") == 0) + outArchive = new NArchive::N7z::CHandler; + #endif + + #ifdef FORMAT_BZIP2 + if (compressionMethod.Name.CompareNoCase(L"BZip2") == 0) + outArchive = new NArchive::NBZip2::CHandler; + #endif + + #ifdef FORMAT_GZIP + if (compressionMethod.Name.CompareNoCase(L"GZip") == 0) + outArchive = new NArchive::NGZip::CHandler; + #endif + + #ifdef FORMAT_TAR + if (compressionMethod.Name.CompareNoCase(L"Tar") == 0) + outArchive = new NArchive::NTar::CHandler; + #endif + + #ifdef FORMAT_ZIP + if (compressionMethod.Name.CompareNoCase(L"Zip") == 0) + outArchive = new NArchive::NZip::CHandler; + #endif + + } + if (outArchive == 0) + throw kUpdateIsNotSupoorted; + + NFileTimeType::EEnum fileTimeType; + UInt32 value; + RINOK(outArchive->GetFileTimeType(&value)); + + switch(value) + { + case NFileTimeType::kWindows: + case NFileTimeType::kDOS: + case NFileTimeType::kUnix: + fileTimeType = NFileTimeType::EEnum(value); + break; + default: + return E_FAIL; + } + + CObjectVector updatePairs; + GetUpdatePairInfoList(dirItems, archiveItems, fileTimeType, updatePairs); // must be done only once!!! + + CObjectVector updatePairs2; + UpdateProduce(updatePairs, actionSet, updatePairs2); + + CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; + CMyComPtr updateCallback(updateCallbackSpec ); + + updateCallbackSpec->StdInMode = stdInMode; + updateCallbackSpec->Callback = callback; + updateCallbackSpec->DirItems = &dirItems; + updateCallbackSpec->ArchiveItems = &archiveItems; + updateCallbackSpec->UpdatePairs = &updatePairs2; + + CMyComPtr outStream; + + const UString &archiveName = archivePath.GetFinalPath(); + if (!stdOutMode) + { + UString resultPath; + int pos; + if(!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos)) + throw 1417161; + NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos)); + } + if (volumesSizes.Size() == 0) + { + if (stdOutMode) + outStream = new CStdOutFileStream; + else + { + COutFileStream *outStreamSpec = new COutFileStream; + outStream = outStreamSpec; + bool isOK = false; + UString realPath; + for (int i = 0; i < (1 << 16); i++) + { + if (archivePath.Temp) + { + if (i > 0) + { + wchar_t s[32]; + ConvertUInt64ToString(i, s); + archivePath.TempPostfix = s; + } + realPath = archivePath.GetTempPath(); + } + else + realPath = archivePath.GetFinalPath(); + if (outStreamSpec->Create(realPath, false)) + { + tempFiles.Paths.Add(realPath); + isOK = true; + break; + } + if (::GetLastError() != ERROR_FILE_EXISTS) + break; + if (!archivePath.Temp) + break; + } + if (!isOK) + { + errorInfo.SystemError = ::GetLastError(); + errorInfo.FileName = realPath; + errorInfo.Message = L"Can not open file"; + return E_FAIL; + } + } + } + else + { + if (stdOutMode) + return E_FAIL; + COutMultiVolStream *volStreamSpec = new COutMultiVolStream; + outStream = volStreamSpec; + volStreamSpec->Sizes = volumesSizes; + volStreamSpec->Prefix = archivePath.GetFinalPath() + UString(L"."); + volStreamSpec->TempFiles = &tempFiles; + volStreamSpec->Init(); + + /* + updateCallbackSpec->VolumesSizes = volumesSizes; + updateCallbackSpec->VolName = archivePath.Prefix + archivePath.Name; + if (!archivePath.VolExtension.IsEmpty()) + updateCallbackSpec->VolExt = UString(L'.') + archivePath.VolExtension; + */ + } + + RINOK(SetProperties(outArchive, compressionMethod.Properties)); + + if (sfxMode) + { + CInFileStream *sfxStreamSpec = new CInFileStream; + CMyComPtr sfxStream(sfxStreamSpec); + if (!sfxStreamSpec->Open(sfxModule)) + { + errorInfo.SystemError = ::GetLastError(); + errorInfo.Message = L"Can't open sfx module"; + errorInfo.FileName = sfxModule; + return E_FAIL; + } + + CMyComPtr sfxOutStream; + if (volumesSizes.Size() == 0) + sfxOutStream = outStream; + else + { + COutFileStream *outStreamSpec = new COutFileStream; + sfxOutStream = outStreamSpec; + UString realPath = archivePath.GetFinalPath(); + if (!outStreamSpec->Create(realPath, false)) + { + errorInfo.SystemError = ::GetLastError(); + errorInfo.FileName = realPath; + errorInfo.Message = L"Can not open file"; + return E_FAIL; + } + } + RINOK(CopyBlock(sfxStream, sfxOutStream)); + } + + HRESULT result = outArchive->UpdateItems(outStream, updatePairs2.Size(), + updateCallback); + callback->Finilize(); + return result; +} + + + +HRESULT EnumerateInArchiveItems(const NWildcard::CCensor &censor, + IInArchive *archive, + const UString &defaultItemName, + const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo, + CObjectVector &archiveItems) +{ + archiveItems.Clear(); + UInt32 numItems; + RINOK(archive->GetNumberOfItems(&numItems)); + archiveItems.Reserve(numItems); + for(UInt32 i = 0; i < numItems; i++) + { + CArchiveItem ai; + + RINOK(GetArchiveItemPath(archive, i, ai.Name)); + RINOK(IsArchiveItemFolder(archive, i, ai.IsDirectory)); + ai.Censored = censor.CheckPath(ai.Name.IsEmpty() ? defaultItemName : ai.Name, !ai.IsDirectory); + RINOK(GetArchiveItemFileTime(archive, i, + archiveFileInfo.LastWriteTime, ai.LastWriteTime)); + + CPropVariant propertySize; + RINOK(archive->GetProperty(i, kpidSize, &propertySize)); + ai.SizeIsDefined = (propertySize.vt != VT_EMPTY); + if (ai.SizeIsDefined) + ai.Size = ConvertPropVariantToUInt64(propertySize); + + ai.IndexInServer = i; + archiveItems.Add(ai); + } + return S_OK; +} + + +static HRESULT UpdateWithItemLists( + CUpdateOptions &options, + IInArchive *archive, + const CObjectVector &archiveItems, + const CObjectVector &dirItems, + CTempFiles &tempFiles, + CUpdateErrorInfo &errorInfo, + IUpdateCallbackUI2 *callback) +{ + for(int i = 0; i < options.Commands.Size(); i++) + { + CUpdateArchiveCommand &command = options.Commands[i]; + if (options.StdOutMode) + { + RINOK(callback->StartArchive(0, archive != 0)); + } + else + { + RINOK(callback->StartArchive(command.ArchivePath.GetFinalPath(), + i == 0 && options.UpdateArchiveItself && archive != 0)); + } + + RINOK(Compress(command.ActionSet, archive, + options.MethodMode, + command.ArchivePath, + archiveItems, + options.StdInMode, + /* options.StdInFileName, */ + options.StdOutMode, + dirItems, + options.SfxMode, options.SfxModule, + options.VolumesSizes, + tempFiles, + errorInfo, callback)); + + RINOK(callback->FinishArchive()); + } + return S_OK; +} + +#ifdef _WIN32 +class CCurrentDirRestorer +{ + UString m_CurrentDirectory; +public: + CCurrentDirRestorer() + { NFile::NDirectory::MyGetCurrentDirectory(m_CurrentDirectory); } + ~CCurrentDirRestorer() + { RestoreDirectory();} + bool RestoreDirectory() + { return BOOLToBool(NFile::NDirectory::MySetCurrentDirectory(m_CurrentDirectory)); } +}; +#endif + +struct CEnumDirItemUpdateCallback: public IEnumDirItemCallback +{ + IUpdateCallbackUI2 *Callback; + HRESULT CheckBreak() { return Callback->CheckBreak(); } +}; + +HRESULT UpdateArchive(const NWildcard::CCensor &censor, + CUpdateOptions &options, + CUpdateErrorInfo &errorInfo, + IOpenCallbackUI *openCallback, + IUpdateCallbackUI2 *callback) +{ + if (options.StdOutMode && options.EMailMode) + return E_FAIL; + + if (options.VolumesSizes.Size() > 0 && (options.EMailMode || options.SfxMode)) + return E_NOTIMPL; + + if (options.SfxMode) + { + CProperty property; + property.Name = L"rsfx"; + property.Value = L"on"; + options.MethodMode.Properties.Add(property); + if (options.SfxModule.IsEmpty()) + { + errorInfo.Message = L"sfx file is not specified"; + return E_FAIL; + } + UString name = options.SfxModule; + if (!NDirectory::MySearchPath(NULL, name, NULL, options.SfxModule)) + { + errorInfo.Message = L"can't find specified sfx module"; + return E_FAIL; + } + } + + const UString archiveName = options.ArchivePath.GetFinalPath(); + + UString defaultItemName; + NFind::CFileInfoW archiveFileInfo; + + CArchiveLink archiveLink; + IInArchive *archive = 0; + if (NFind::FindFile(archiveName, archiveFileInfo)) + { + if (archiveFileInfo.IsDirectory()) + throw "there is no such archive"; + if (options.VolumesSizes.Size() > 0) + return E_NOTIMPL; + HRESULT result = MyOpenArchive(archiveName, archiveLink, openCallback); + RINOK(callback->OpenResult(archiveName, result)); + RINOK(result); + if (archiveLink.VolumePaths.Size() > 1) + { + errorInfo.SystemError = (DWORD)E_NOTIMPL; + errorInfo.Message = L"Updating for multivolume archives is not implemented"; + return E_NOTIMPL; + } + archive = archiveLink.GetArchive(); + defaultItemName = archiveLink.GetDefaultItemName(); + } + else + { + /* + if (archiveType.IsEmpty()) + throw "type of archive is not specified"; + */ + } + + CObjectVector dirItems; + if (options.StdInMode) + { + CDirItem item; + item.FullPath = item.Name = options.StdInFileName; + item.Size = (UInt64)(Int64)-1; + item.Attributes = 0; + SYSTEMTIME st; + FILETIME ft; + GetSystemTime(&st); + SystemTimeToFileTime(&st, &ft); + item.CreationTime = item.LastAccessTime = item.LastWriteTime = ft; + dirItems.Add(item); + } + else + { + bool needScanning = false; + for(int i = 0; i < options.Commands.Size(); i++) + if (options.Commands[i].ActionSet.NeedScanning()) + needScanning = true; + if (needScanning) + { + CEnumDirItemUpdateCallback enumCallback; + enumCallback.Callback = callback; + RINOK(callback->StartScanning()); + UStringVector errorPaths; + CRecordVector errorCodes; + HRESULT res = EnumerateItems(censor, dirItems, &enumCallback, errorPaths, errorCodes); + for (int i = 0; i < errorPaths.Size(); i++) + { + RINOK(callback->CanNotFindError(errorPaths[i], errorCodes[i])); + } + if(res != S_OK) + { + errorInfo.Message = L"Scanning error"; + // errorInfo.FileName = errorPath; + return res; + } + RINOK(callback->FinishScanning()); + } + } + + UString tempDirPrefix; + bool usesTempDir = false; + + #ifdef _WIN32 + NDirectory::CTempDirectoryW tempDirectory; + if (options.EMailMode && options.EMailRemoveAfter) + { + tempDirectory.Create(kTempFolderPrefix); + tempDirPrefix = tempDirectory.GetPath(); + NormalizeDirPathPrefix(tempDirPrefix); + usesTempDir = true; + } + #endif + + CTempFiles tempFiles; + + bool createTempFile = false; + if(!options.StdOutMode && options.UpdateArchiveItself) + { + CArchivePath &ap = options.Commands[0].ArchivePath; + ap = options.ArchivePath; + // if ((archive != 0 && !usesTempDir) || !options.WorkingDir.IsEmpty()) + if ((archive != 0 || !options.WorkingDir.IsEmpty()) && !usesTempDir && options.VolumesSizes.Size() == 0) + { + createTempFile = true; + ap.Temp = true; + if (!options.WorkingDir.IsEmpty()) + { + ap.TempPrefix = options.WorkingDir; + NormalizeDirPathPrefix(ap.TempPrefix); + } + } + } + + for(int i = 0; i < options.Commands.Size(); i++) + { + CArchivePath &ap = options.Commands[i].ArchivePath; + if (usesTempDir) + { + // Check it + ap.Prefix = tempDirPrefix; + // ap.Temp = true; + // ap.TempPrefix = tempDirPrefix; + } + if (i > 0 || !createTempFile) + { + const UString &path = ap.GetFinalPath(); + if (NFind::DoesFileExist(path)) + { + errorInfo.SystemError = 0; + errorInfo.Message = L"File already exists"; + errorInfo.FileName = path; + return E_FAIL; + } + } + } + + CObjectVector archiveItems; + if (archive != NULL) + { + RINOK(EnumerateInArchiveItems(censor, + archive, defaultItemName, archiveFileInfo, archiveItems)); + } + + RINOK(UpdateWithItemLists(options, archive, archiveItems, dirItems, + tempFiles, errorInfo, callback)); + + if (archive != NULL) + { + RINOK(archiveLink.Close()); + archiveLink.Release(); + } + + tempFiles.Paths.Clear(); + if(createTempFile) + { + try + { + CArchivePath &ap = options.Commands[0].ArchivePath; + const UString &tempPath = ap.GetTempPath(); + if (archive != NULL) + if (!NDirectory::DeleteFileAlways(archiveName)) + { + errorInfo.SystemError = ::GetLastError(); + errorInfo.Message = L"delete file error"; + errorInfo.FileName = archiveName; + return E_FAIL; + } + if (!NDirectory::MyMoveFile(tempPath, archiveName)) + { + errorInfo.SystemError = ::GetLastError(); + errorInfo.Message = L"move file error"; + errorInfo.FileName = tempPath; + errorInfo.FileName2 = archiveName; + return E_FAIL; + } + } + catch(...) + { + throw; + } + } + + #ifdef _WIN32 + if (options.EMailMode) + { + NDLL::CLibrary mapiLib; + if (!mapiLib.Load(TEXT("Mapi32.dll"))) + { + errorInfo.SystemError = ::GetLastError(); + errorInfo.Message = L"can not load Mapi32.dll"; + return E_FAIL; + } + LPMAPISENDDOCUMENTS fnSend = (LPMAPISENDDOCUMENTS) + mapiLib.GetProcAddress("MAPISendDocuments"); + if (fnSend == 0) + { + errorInfo.SystemError = ::GetLastError(); + errorInfo.Message = L"can not find MAPISendDocuments function"; + return E_FAIL; + } + UStringVector fullPaths; + int i; + for(i = 0; i < options.Commands.Size(); i++) + { + CArchivePath &ap = options.Commands[i].ArchivePath; + UString arcPath; + if(!NFile::NDirectory::MyGetFullPathName(ap.GetFinalPath(), arcPath)) + { + errorInfo.SystemError = ::GetLastError(); + return E_FAIL; + } + fullPaths.Add(arcPath); + } + CCurrentDirRestorer curDirRestorer; + for(i = 0; i < fullPaths.Size(); i++) + { + UString arcPath = fullPaths[i]; + UString fileName = ExtractFileNameFromPath(arcPath); + AString path = GetAnsiString(arcPath); + AString name = GetAnsiString(fileName); + // Warning!!! MAPISendDocuments function changes Current directory + fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0); + } + } + #endif + return S_OK; +} + diff --git a/CPP/7zip/UI/Common/Update.h b/CPP/7zip/UI/Common/Update.h new file mode 100755 index 00000000..465acc24 --- /dev/null +++ b/CPP/7zip/UI/Common/Update.h @@ -0,0 +1,158 @@ +// Update.h + +#ifndef __UPDATE_H +#define __UPDATE_H + +#include "Common/Wildcard.h" +#include "Windows/FileFind.h" +#include "../../Archive/IArchive.h" + +#include "UpdateAction.h" +#include "ArchiveOpenCallback.h" +#include "UpdateCallback.h" +#include "Property.h" + +struct CArchivePath +{ + UString Prefix; // path(folder) prefix including slash + UString Name; // base name + UString BaseExtension; // archive type extension or "exe" extension + UString VolExtension; // archive type extension for volumes + + bool Temp; + UString TempPrefix; // path(folder) for temp location + UString TempPostfix; + + CArchivePath(): Temp(false) {}; + + void ParseFromPath(const UString &path) + { + SplitPathToParts(path, Prefix, Name); + if (Name.IsEmpty()) + return; + int dotPos = Name.ReverseFind(L'.'); + if (dotPos <= 0) + return; + if (dotPos == Name.Length() - 1) + { + Name = Name.Left(dotPos); + BaseExtension.Empty(); + return; + } + if (BaseExtension.CompareNoCase(Name.Mid(dotPos + 1)) == 0) + { + BaseExtension = Name.Mid(dotPos + 1); + Name = Name.Left(dotPos); + } + else + BaseExtension.Empty(); + } + + UString GetPathWithoutExt() const + { + return Prefix + Name; + } + + UString GetFinalPath() const + { + UString path = GetPathWithoutExt(); + if (!BaseExtension.IsEmpty()) + path += UString(L'.') + BaseExtension; + return path; + } + + + UString GetTempPath() const + { + UString path = TempPrefix + Name; + if (!BaseExtension.IsEmpty()) + path += UString(L'.') + BaseExtension; + path += L".tmp"; + path += TempPostfix; + return path; + } +}; + +struct CUpdateArchiveCommand +{ + CArchivePath ArchivePath; + NUpdateArchive::CActionSet ActionSet; +}; + +struct CCompressionMethodMode +{ + #ifndef EXCLUDE_COM + UString FilePath; + CLSID ClassID; + #else + UString Name; + #endif + CObjectVector Properties; +}; + +struct CUpdateOptions +{ + CCompressionMethodMode MethodMode; + + CObjectVector Commands; + bool UpdateArchiveItself; + CArchivePath ArchivePath; + + bool SfxMode; + UString SfxModule; + + bool StdInMode; + UString StdInFileName; + bool StdOutMode; + + bool EMailMode; + bool EMailRemoveAfter; + UString EMailAddress; + + UString WorkingDir; + + CUpdateOptions(): + UpdateArchiveItself(true), + SfxMode(false), + StdInMode(false), + StdOutMode(false), + EMailMode(false), + EMailRemoveAfter(false) + {}; + CRecordVector VolumesSizes; +}; + +struct CErrorInfo +{ + DWORD SystemError; + UString FileName; + UString FileName2; + UString Message; + // UStringVector ErrorPaths; + // CRecordVector ErrorCodes; + CErrorInfo(): SystemError(0) {}; +}; + +struct CUpdateErrorInfo: public CErrorInfo +{ +}; + +struct IUpdateCallbackUI2: public IUpdateCallbackUI +{ + virtual HRESULT OpenResult(const wchar_t *name, HRESULT result) = 0; + + virtual HRESULT StartScanning() = 0; + virtual HRESULT CanNotFindError(const wchar_t *name, DWORD systemError) = 0; + virtual HRESULT FinishScanning() = 0; + + virtual HRESULT StartArchive(const wchar_t *name, bool updating) = 0; + virtual HRESULT FinishArchive() = 0; +}; + +HRESULT UpdateArchive(const NWildcard::CCensor &censor, + CUpdateOptions &options, + CUpdateErrorInfo &errorInfo, + IOpenCallbackUI *openCallback, + IUpdateCallbackUI2 *callback); + +#endif diff --git a/CPP/7zip/UI/Common/UpdateAction.cpp b/CPP/7zip/UI/Common/UpdateAction.cpp new file mode 100755 index 00000000..5e3b5a10 --- /dev/null +++ b/CPP/7zip/UI/Common/UpdateAction.cpp @@ -0,0 +1,64 @@ +// UpdateAction.cpp + +#include "StdAfx.h" + +#include "UpdateAction.h" + +namespace NUpdateArchive { + +const CActionSet kAddActionSet = +{ + NPairAction::kCopy, + NPairAction::kCopy, + NPairAction::kCompress, + NPairAction::kCompress, + NPairAction::kCompress, + NPairAction::kCompress, + NPairAction::kCompress +}; + +const CActionSet kUpdateActionSet = +{ + NPairAction::kCopy, + NPairAction::kCopy, + NPairAction::kCompress, + NPairAction::kCopy, + NPairAction::kCompress, + NPairAction::kCopy, + NPairAction::kCompress +}; + +const CActionSet kFreshActionSet = +{ + NPairAction::kCopy, + NPairAction::kCopy, + NPairAction::kIgnore, + NPairAction::kCopy, + NPairAction::kCompress, + NPairAction::kCopy, + NPairAction::kCompress +}; + +const CActionSet kSynchronizeActionSet = +{ + NPairAction::kCopy, + NPairAction::kIgnore, + NPairAction::kCompress, + NPairAction::kCopy, + NPairAction::kCompress, + NPairAction::kCopy, + NPairAction::kCompress, +}; + +const CActionSet kDeleteActionSet = +{ + NPairAction::kCopy, + NPairAction::kIgnore, + NPairAction::kIgnore, + NPairAction::kIgnore, + NPairAction::kIgnore, + NPairAction::kIgnore, + NPairAction::kIgnore +}; + +} diff --git a/CPP/7zip/UI/Common/UpdateAction.h b/CPP/7zip/UI/Common/UpdateAction.h new file mode 100755 index 00000000..aa050975 --- /dev/null +++ b/CPP/7zip/UI/Common/UpdateAction.h @@ -0,0 +1,57 @@ +// UpdateAction.h + +#ifndef __UPDATE_ACTION_H +#define __UPDATE_ACTION_H + +namespace NUpdateArchive { + + namespace NPairState + { + const int kNumValues = 7; + enum EEnum + { + kNotMasked = 0, + kOnlyInArchive, + kOnlyOnDisk, + kNewInArchive, + kOldInArchive, + kSameFiles, + kUnknowNewerFiles + }; + } + namespace NPairAction + { + enum EEnum + { + kIgnore = 0, + kCopy, + kCompress, + kCompressAsAnti + }; + } + struct CActionSet + { + NPairAction::EEnum StateActions[NPairState::kNumValues]; + bool NeedScanning() const + { + int i; + for (i = 0; i < NPairState::kNumValues; i++) + if (StateActions[i] == NPairAction::kCompress) + return true; + for (i = 1; i < NPairState::kNumValues; i++) + if (StateActions[i] != NPairAction::kIgnore) + return true; + return false; + } + }; + extern const CActionSet kAddActionSet; + extern const CActionSet kUpdateActionSet; + extern const CActionSet kFreshActionSet; + extern const CActionSet kSynchronizeActionSet; + extern const CActionSet kDeleteActionSet; +}; + + +#endif + + diff --git a/CPP/7zip/UI/Common/UpdateCallback.cpp b/CPP/7zip/UI/Common/UpdateCallback.cpp new file mode 100755 index 00000000..db3bf805 --- /dev/null +++ b/CPP/7zip/UI/Common/UpdateCallback.cpp @@ -0,0 +1,258 @@ +// UpdateCallback.cpp + +#include "StdAfx.h" + +#include "UpdateCallback.h" + +#include "Common/StringConvert.h" +#include "Common/IntToString.h" +#include "Common/Defs.h" +#include "Common/ComTry.h" + +#include "Windows/PropVariant.h" + +#include "../../Common/FileStreams.h" + +using namespace NWindows; + +CArchiveUpdateCallback::CArchiveUpdateCallback(): + Callback(0), + StdInMode(false), + DirItems(0), + ArchiveItems(0), + UpdatePairs(0) + {} + + +STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size) +{ + COM_TRY_BEGIN + return Callback->SetTotal(size); + COM_TRY_END +} + +STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue) +{ + COM_TRY_BEGIN + return Callback->SetCompleted(completeValue); + COM_TRY_END +} + +/* +STATPROPSTG kProperties[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidLastAccessTime, VT_FILETIME}, + { NULL, kpidCreationTime, VT_FILETIME}, + { NULL, kpidLastWriteTime, VT_FILETIME}, + { NULL, kpidAttributes, VT_UI4}, + { NULL, kpidIsAnti, VT_BOOL} +}; +*/ + +STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **) +{ + return E_NOTIMPL; + /* + return CStatPropEnumerator::CreateEnumerator(kProperties, + sizeof(kProperties) / sizeof(kProperties[0]), enumerator); + */ +} + +STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index, + Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive) +{ + COM_TRY_BEGIN + RINOK(Callback->CheckBreak()); + const CUpdatePair2 &updatePair = (*UpdatePairs)[index]; + if(newData != NULL) + *newData = BoolToInt(updatePair.NewData); + if(newProperties != NULL) + *newProperties = BoolToInt(updatePair.NewProperties); + if(indexInArchive != NULL) + { + if (updatePair.ExistInArchive) + { + if (ArchiveItems == 0) + *indexInArchive = updatePair.ArchiveItemIndex; + else + *indexInArchive = (*ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer; + } + else + *indexInArchive = UInt32(-1); + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + const CUpdatePair2 &updatePair = (*UpdatePairs)[index]; + NWindows::NCOM::CPropVariant propVariant; + + if (propID == kpidIsAnti) + { + propVariant = updatePair.IsAnti; + propVariant.Detach(value); + return S_OK; + } + + if (updatePair.IsAnti) + { + switch(propID) + { + case kpidIsFolder: + case kpidPath: + break; + case kpidSize: + propVariant = (UInt64)0; + propVariant.Detach(value); + return S_OK; + default: + propVariant.Detach(value); + return S_OK; + } + } + + if(updatePair.ExistOnDisk) + { + const CDirItem &dirItem = (*DirItems)[updatePair.DirItemIndex]; + switch(propID) + { + case kpidPath: + propVariant = dirItem.Name; + break; + case kpidIsFolder: + propVariant = dirItem.IsDirectory(); + break; + case kpidSize: + propVariant = dirItem.Size; + break; + case kpidAttributes: + propVariant = dirItem.Attributes; + break; + case kpidLastAccessTime: + propVariant = dirItem.LastAccessTime; + break; + case kpidCreationTime: + propVariant = dirItem.CreationTime; + break; + case kpidLastWriteTime: + propVariant = dirItem.LastWriteTime; + break; + } + } + else + { + if (propID == kpidPath) + { + if (updatePair.NewNameIsDefined) + { + propVariant = updatePair.NewName; + propVariant.Detach(value); + return S_OK; + } + } + if (updatePair.ExistInArchive && Archive) + { + UInt32 indexInArchive; + if (ArchiveItems == 0) + indexInArchive = updatePair.ArchiveItemIndex; + else + indexInArchive = (*ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer; + return Archive->GetProperty(indexInArchive, propID, value); + } + } + propVariant.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream) +{ + COM_TRY_BEGIN + const CUpdatePair2 &updatePair = (*UpdatePairs)[index]; + if(!updatePair.NewData) + return E_FAIL; + + RINOK(Callback->CheckBreak()); + RINOK(Callback->Finilize()); + + if(updatePair.IsAnti) + { + return Callback->GetStream((*ArchiveItems)[updatePair.ArchiveItemIndex].Name, true); + } + const CDirItem &dirItem = (*DirItems)[updatePair.DirItemIndex]; + RINOK(Callback->GetStream(dirItem.Name, false)); + + if(dirItem.IsDirectory()) + return S_OK; + + if (StdInMode) + { + CStdInFileStream *inStreamSpec = new CStdInFileStream; + CMyComPtr inStreamLoc(inStreamSpec); + *inStream = inStreamLoc.Detach(); + } + else + { + CInFileStream *inStreamSpec = new CInFileStream; + CMyComPtr inStreamLoc(inStreamSpec); + UString path = DirPrefix + dirItem.FullPath; + if(!inStreamSpec->Open(path)) + { + return Callback->OpenFileError(path, ::GetLastError()); + } + *inStream = inStreamLoc.Detach(); + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 operationResult) +{ + COM_TRY_BEGIN + return Callback->SetOperationResult(operationResult); + COM_TRY_END +} + +STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size) +{ + if (VolumesSizes.Size() == 0) + return S_FALSE; + if (index >= (UInt32)VolumesSizes.Size()) + index = VolumesSizes.Size() - 1; + *size = VolumesSizes[index]; + return S_OK; +} + +STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream) +{ + COM_TRY_BEGIN + wchar_t temp[32]; + ConvertUInt64ToString(index + 1, temp); + UString res = temp; + while (res.Length() < 2) + res = UString(L'0') + res; + UString fileName = VolName; + fileName += L'.'; + fileName += res; + fileName += VolExt; + COutFileStream *streamSpec = new COutFileStream; + CMyComPtr streamLoc(streamSpec); + if(!streamSpec->Create(fileName, false)) + return ::GetLastError(); + *volumeStream = streamLoc.Detach(); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) +{ + COM_TRY_BEGIN + return Callback->CryptoGetTextPassword2(passwordIsDefined, password); + COM_TRY_END +} diff --git a/CPP/7zip/UI/Common/UpdateCallback.h b/CPP/7zip/UI/Common/UpdateCallback.h new file mode 100755 index 00000000..8b14a9dc --- /dev/null +++ b/CPP/7zip/UI/Common/UpdateCallback.h @@ -0,0 +1,70 @@ +// UpdateCallback.h + +#ifndef __UPDATECALLBACK_H +#define __UPDATECALLBACK_H + +#include "Common/MyCom.h" +#include "Common/String.h" + +#include "../../IPassword.h" + +#include "../Common/UpdatePair.h" +#include "../Common/UpdateProduce.h" + +struct IUpdateCallbackUI +{ + virtual HRESULT SetTotal(UInt64 size) = 0; + virtual HRESULT SetCompleted(const UInt64 *completeValue) = 0; + virtual HRESULT CheckBreak() = 0; + virtual HRESULT Finilize() = 0; + virtual HRESULT GetStream(const wchar_t *name, bool isAnti) = 0; + virtual HRESULT OpenFileError(const wchar_t *name, DWORD systemError) = 0; + virtual HRESULT SetOperationResult(Int32 operationResult) = 0; + virtual HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) = 0; + virtual HRESULT CloseProgress() { return S_OK; }; +}; + +class CArchiveUpdateCallback: + public IArchiveUpdateCallback2, + public ICryptoGetTextPassword2, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP2(IArchiveUpdateCallback2, + ICryptoGetTextPassword2) + + // IProgress + STDMETHOD(SetTotal)(UInt64 size); + STDMETHOD(SetCompleted)(const UInt64 *completeValue); + + // IUpdateCallback + STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator); + STDMETHOD(GetUpdateItemInfo)(UInt32 index, + Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream); + STDMETHOD(SetOperationResult)(Int32 operationResult); + + STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size); + STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream); + + STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password); + +public: + CRecordVector VolumesSizes; + UString VolName; + UString VolExt; + + IUpdateCallbackUI *Callback; + + UString DirPrefix; + bool StdInMode; + const CObjectVector *DirItems; + const CObjectVector *ArchiveItems; + const CObjectVector *UpdatePairs; + CMyComPtr Archive; + + CArchiveUpdateCallback(); +}; + +#endif diff --git a/CPP/7zip/UI/Common/UpdatePair.cpp b/CPP/7zip/UI/Common/UpdatePair.cpp new file mode 100755 index 00000000..dd51646f --- /dev/null +++ b/CPP/7zip/UI/Common/UpdatePair.cpp @@ -0,0 +1,175 @@ +// UpdatePair.cpp + +#include "StdAfx.h" + +#include + +#include "Common/Defs.h" +#include "Windows/Time.h" + +#include "UpdatePair.h" +#include "SortUtils.h" + +using namespace NWindows; +using namespace NTime; + +static int MyCompareTime(NFileTimeType::EEnum fileTimeType, + const FILETIME &time1, const FILETIME &time2) +{ + switch(fileTimeType) + { + case NFileTimeType::kWindows: + return ::CompareFileTime(&time1, &time2); + case NFileTimeType::kUnix: + { + UInt32 unixTime1, unixTime2; + if (!FileTimeToUnixTime(time1, unixTime1)) + { + unixTime1 = 0; + // throw 4191614; + } + if (!FileTimeToUnixTime(time2, unixTime2)) + { + unixTime2 = 0; + // throw 4191615; + } + return MyCompare(unixTime1, unixTime2); + } + case NFileTimeType::kDOS: + { + UInt32 dosTime1, dosTime2; + FileTimeToDosTime(time1, dosTime1); + FileTimeToDosTime(time2, dosTime2); + /* + if (!FileTimeToDosTime(time1, dosTime1)) + throw 4191616; + if (!FileTimeToDosTime(time2, dosTime2)) + throw 4191617; + */ + return MyCompare(dosTime1, dosTime2); + } + } + throw 4191618; +} + +static const wchar_t *kDuplicateFileNameMessage = L"Duplicate filename:"; + +/* +static const char *kNotCensoredCollisionMessaged = "Internal file name collision:\n"; +static const char *kSameTimeChangedSizeCollisionMessaged = + "Collision between files with same date/time and different sizes:\n"; +*/ + +static inline int MyFileNameCompare(const UString &s1, const UString &s2) +{ + return + #ifdef _WIN32 + s1.CompareNoCase(s2); + #else + s1.Compare(s2); + #endif +} + +static void TestDuplicateString(const UStringVector &strings, const CIntVector &indices) +{ + for(int i = 0; i + 1 < indices.Size(); i++) + if (MyFileNameCompare(strings[indices[i]], strings[indices[i + 1]]) == 0) + { + UString message = kDuplicateFileNameMessage; + message += L"\n"; + message += strings[indices[i]]; + message += L"\n"; + message += strings[indices[i + 1]]; + throw message; + } +} + +void GetUpdatePairInfoList( + const CObjectVector &dirItems, + const CObjectVector &archiveItems, + NFileTimeType::EEnum fileTimeType, + CObjectVector &updatePairs) +{ + CIntVector dirIndices, archiveIndices; + UStringVector dirNames, archiveNames; + + int numDirItems = dirItems.Size(); + int i; + for(i = 0; i < numDirItems; i++) + dirNames.Add(dirItems[i].Name); + SortStringsToIndices(dirNames, dirIndices); + TestDuplicateString(dirNames, dirIndices); + + int numArchiveItems = archiveItems.Size(); + for(i = 0; i < numArchiveItems; i++) + archiveNames.Add(archiveItems[i].Name); + SortStringsToIndices(archiveNames, archiveIndices); + TestDuplicateString(archiveNames, archiveIndices); + + int dirItemIndex = 0, archiveItemIndex = 0; + CUpdatePair pair; + while(dirItemIndex < numDirItems && archiveItemIndex < numArchiveItems) + { + int dirItemIndex2 = dirIndices[dirItemIndex], + archiveItemIndex2 = archiveIndices[archiveItemIndex]; + const CDirItem &dirItem = dirItems[dirItemIndex2]; + const CArchiveItem &archiveItem = archiveItems[archiveItemIndex2]; + int compareResult = MyFileNameCompare(dirItem.Name, archiveItem.Name); + if (compareResult < 0) + { + pair.State = NUpdateArchive::NPairState::kOnlyOnDisk; + pair.DirItemIndex = dirItemIndex2; + dirItemIndex++; + } + else if (compareResult > 0) + { + pair.State = archiveItem.Censored ? + NUpdateArchive::NPairState::kOnlyInArchive: NUpdateArchive::NPairState::kNotMasked; + pair.ArchiveItemIndex = archiveItemIndex2; + archiveItemIndex++; + } + else + { + if (!archiveItem.Censored) + throw 1082022;; // TTString(kNotCensoredCollisionMessaged + dirItem.Name); + pair.DirItemIndex = dirItemIndex2; + pair.ArchiveItemIndex = archiveItemIndex2; + switch (MyCompareTime(fileTimeType, dirItem.LastWriteTime, archiveItem.LastWriteTime)) + { + case -1: + pair.State = NUpdateArchive::NPairState::kNewInArchive; + break; + case 1: + pair.State = NUpdateArchive::NPairState::kOldInArchive; + break; + default: + if (archiveItem.SizeIsDefined) + if (dirItem.Size != archiveItem.Size) + // throw 1082034; // kSameTimeChangedSizeCollisionMessaged; + pair.State = NUpdateArchive::NPairState::kUnknowNewerFiles; + else + pair.State = NUpdateArchive::NPairState::kSameFiles; + else + pair.State = NUpdateArchive::NPairState::kUnknowNewerFiles; + } + dirItemIndex++; + archiveItemIndex++; + } + updatePairs.Add(pair); + } + for(;dirItemIndex < numDirItems; dirItemIndex++) + { + pair.State = NUpdateArchive::NPairState::kOnlyOnDisk; + pair.DirItemIndex = dirIndices[dirItemIndex]; + updatePairs.Add(pair); + } + for(;archiveItemIndex < numArchiveItems; archiveItemIndex++) + { + int archiveItemIndex2 = archiveIndices[archiveItemIndex]; + const CArchiveItem &archiveItem = archiveItems[archiveItemIndex2]; + pair.State = archiveItem.Censored ? + NUpdateArchive::NPairState::kOnlyInArchive: NUpdateArchive::NPairState::kNotMasked; + pair.ArchiveItemIndex = archiveItemIndex2; + updatePairs.Add(pair); + } +} diff --git a/CPP/7zip/UI/Common/UpdatePair.h b/CPP/7zip/UI/Common/UpdatePair.h new file mode 100755 index 00000000..f50a23f8 --- /dev/null +++ b/CPP/7zip/UI/Common/UpdatePair.h @@ -0,0 +1,24 @@ +// UpdatePair.h + +#ifndef __UPDATE_PAIR_H +#define __UPDATE_PAIR_H + +#include "DirItem.h" +#include "UpdateAction.h" + +#include "../../Archive/IArchive.h" + +struct CUpdatePair +{ + NUpdateArchive::NPairState::EEnum State; + int ArchiveItemIndex; + int DirItemIndex; +}; + +void GetUpdatePairInfoList( + const CObjectVector &dirItems, + const CObjectVector &archiveItems, + NFileTimeType::EEnum fileTimeType, + CObjectVector &updatePairs); + +#endif diff --git a/CPP/7zip/UI/Common/UpdateProduce.cpp b/CPP/7zip/UI/Common/UpdateProduce.cpp new file mode 100755 index 00000000..992bbeec --- /dev/null +++ b/CPP/7zip/UI/Common/UpdateProduce.cpp @@ -0,0 +1,63 @@ +// UpdateProduce.cpp + +#include "StdAfx.h" + +#include "UpdateProduce.h" + +using namespace NUpdateArchive; + +static const char *kUpdateActionSetCollision = + "Internal collision in update action set"; + +void UpdateProduce( + const CObjectVector &updatePairs, + const NUpdateArchive::CActionSet &actionSet, + CObjectVector &operationChain) +{ + for(int i = 0; i < updatePairs.Size(); i++) + { + // CUpdateArchiveRange aRange; + const CUpdatePair &pair = updatePairs[i]; + + CUpdatePair2 pair2; + pair2.IsAnti = false; + pair2.ArchiveItemIndex = pair.ArchiveItemIndex; + pair2.DirItemIndex = pair.DirItemIndex; + pair2.ExistInArchive = (pair.State != NPairState::kOnlyOnDisk); + pair2.ExistOnDisk = (pair.State != NPairState::kOnlyInArchive); + switch(actionSet.StateActions[pair.State]) + { + case NPairAction::kIgnore: + /* + if (pair.State != NPairState::kOnlyOnDisk) + IgnoreArchiveItem(m_ArchiveItems[pair.ArchiveItemIndex]); + // cout << "deleting"; + */ + break; + case NPairAction::kCopy: + { + if (pair.State == NPairState::kOnlyOnDisk) + throw kUpdateActionSetCollision; + pair2.NewData = pair2.NewProperties = false; + operationChain.Add(pair2); + break; + } + case NPairAction::kCompress: + { + if (pair.State == NPairState::kOnlyInArchive || + pair.State == NPairState::kNotMasked) + throw kUpdateActionSetCollision; + pair2.NewData = pair2.NewProperties = true; + operationChain.Add(pair2); + break; + } + case NPairAction::kCompressAsAnti: + { + pair2.IsAnti = true; + pair2.NewData = pair2.NewProperties = true; + operationChain.Add(pair2); + break; + } + } + } +} diff --git a/CPP/7zip/UI/Common/UpdateProduce.h b/CPP/7zip/UI/Common/UpdateProduce.h new file mode 100755 index 00000000..8f58dab9 --- /dev/null +++ b/CPP/7zip/UI/Common/UpdateProduce.h @@ -0,0 +1,31 @@ +// UpdateProduce.h + +#ifndef __UPDATE_PRODUCE_H +#define __UPDATE_PRODUCE_H + +#include "UpdatePair.h" + +struct CUpdatePair2 +{ + // bool OperationIsCompress; + bool NewData; + bool NewProperties; + + bool ExistInArchive; + bool ExistOnDisk; + bool IsAnti; + int ArchiveItemIndex; + int DirItemIndex; + + bool NewNameIsDefined; + UString NewName; + + CUpdatePair2(): NewNameIsDefined(false) {} +}; + +void UpdateProduce( + const CObjectVector &updatePairs, + const NUpdateArchive::CActionSet &actionSet, + CObjectVector &operationChain); + +#endif diff --git a/CPP/7zip/UI/Common/WorkDir.cpp b/CPP/7zip/UI/Common/WorkDir.cpp new file mode 100755 index 00000000..8db6f4f1 --- /dev/null +++ b/CPP/7zip/UI/Common/WorkDir.cpp @@ -0,0 +1,64 @@ +// WorkDir.cpp + +#include "StdAfx.h" + +#include "WorkDir.h" + +#include "Common/StringConvert.h" +#include "Common/Wildcard.h" + +#include "Windows/FileName.h" +#include "Windows/FileDir.h" + +static inline UINT GetCurrentCodePage() + { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; } + +using namespace NWindows; +using namespace NFile; +using namespace NName; + +UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const UString &path) +{ + NWorkDir::NMode::EEnum mode = workDirInfo.Mode; + if (workDirInfo.ForRemovableOnly) + { + mode = NWorkDir::NMode::kCurrent; + UString prefix = path.Left(3); + if (prefix[1] == L':' && prefix[2] == L'\\') + { + UINT driveType = GetDriveType(GetSystemString(prefix, GetCurrentCodePage())); + if (driveType == DRIVE_CDROM || driveType == DRIVE_REMOVABLE) + mode = workDirInfo.Mode; + } + /* + CParsedPath parsedPath; + parsedPath.ParsePath(archiveName); + UINT driveType = GetDriveType(parsedPath.Prefix); + if ((driveType != DRIVE_CDROM) && (driveType != DRIVE_REMOVABLE)) + mode = NZipSettings::NWorkDir::NMode::kCurrent; + */ + } + switch(mode) + { + case NWorkDir::NMode::kCurrent: + { + return ExtractDirPrefixFromPath(path); + } + case NWorkDir::NMode::kSpecified: + { + UString tempDir = workDirInfo.Path; + NormalizeDirPathPrefix(tempDir); + return tempDir; + } + default: + { + UString tempDir; + if(!NFile::NDirectory::MyGetTempPath(tempDir)) + throw 141717; + return tempDir; + } + } +} + + + diff --git a/CPP/7zip/UI/Common/WorkDir.h b/CPP/7zip/UI/Common/WorkDir.h new file mode 100755 index 00000000..0643d67a --- /dev/null +++ b/CPP/7zip/UI/Common/WorkDir.h @@ -0,0 +1,10 @@ +// WorkDir.h + +#ifndef __WORKDIR_H +#define __WORKDIR_H + +#include "ZipRegistry.h" + +UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const UString &path); + +#endif diff --git a/CPP/7zip/UI/Common/ZipRegistry.cpp b/CPP/7zip/UI/Common/ZipRegistry.cpp new file mode 100755 index 00000000..e449d6b4 --- /dev/null +++ b/CPP/7zip/UI/Common/ZipRegistry.cpp @@ -0,0 +1,420 @@ +// ZipRegistry.cpp + +#include "StdAfx.h" + +#include "ZipRegistry.h" + +#include "Common/IntToString.h" +#include "Common/StringConvert.h" + +#include "Windows/Synchronization.h" +#include "Windows/Registry.h" + +#include "Windows/FileDir.h" + +using namespace NWindows; +using namespace NRegistry; + +static const TCHAR *kCUBasePath = TEXT("Software\\7-ZIP"); + +// static const TCHAR *kArchiversKeyName = TEXT("Archivers"); + +static NSynchronization::CCriticalSection g_RegistryOperationsCriticalSection; + +////////////////////// +// ExtractionInfo + +static const TCHAR *kExtractionKeyName = TEXT("Extraction"); + +static const TCHAR *kExtractionPathHistoryKeyName = TEXT("PathHistory"); +static const TCHAR *kExtractionExtractModeValueName = TEXT("ExtarctMode"); +static const TCHAR *kExtractionOverwriteModeValueName = TEXT("OverwriteMode"); +static const TCHAR *kExtractionShowPasswordValueName = TEXT("ShowPassword"); + +static CSysString GetKeyPath(const CSysString &path) +{ + return CSysString(kCUBasePath) + CSysString('\\') + CSysString(path); +} + +void SaveExtractionInfo(const NExtract::CInfo &info) +{ + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey extractionKey; + extractionKey.Create(HKEY_CURRENT_USER, GetKeyPath(kExtractionKeyName)); + extractionKey.RecurseDeleteKey(kExtractionPathHistoryKeyName); + { + CKey pathHistoryKey; + pathHistoryKey.Create(extractionKey, kExtractionPathHistoryKeyName); + for(int i = 0; i < info.Paths.Size(); i++) + { + wchar_t numberString[16]; + ConvertUInt64ToString(i, numberString); + pathHistoryKey.SetValue(numberString, info.Paths[i]); + } + } + extractionKey.SetValue(kExtractionExtractModeValueName, UInt32(info.PathMode)); + extractionKey.SetValue(kExtractionOverwriteModeValueName, UInt32(info.OverwriteMode)); + extractionKey.SetValue(kExtractionShowPasswordValueName, info.ShowPassword); +} + +void ReadExtractionInfo(NExtract::CInfo &info) +{ + info.Paths.Clear(); + info.PathMode = NExtract::NPathMode::kCurrentPathnames; + info.OverwriteMode = NExtract::NOverwriteMode::kAskBefore; + info.ShowPassword = false; + + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey extractionKey; + if(extractionKey.Open(HKEY_CURRENT_USER, GetKeyPath(kExtractionKeyName), KEY_READ) != ERROR_SUCCESS) + return; + + { + CKey pathHistoryKey; + if(pathHistoryKey.Open(extractionKey, kExtractionPathHistoryKeyName, KEY_READ) == + ERROR_SUCCESS) + { + for (;;) + { + wchar_t numberString[16]; + ConvertUInt64ToString(info.Paths.Size(), numberString); + UString path; + if (pathHistoryKey.QueryValue(numberString, path) != ERROR_SUCCESS) + break; + info.Paths.Add(path); + } + } + } + UInt32 extractModeIndex; + if (extractionKey.QueryValue(kExtractionExtractModeValueName, extractModeIndex) == ERROR_SUCCESS) + { + switch (extractModeIndex) + { + case NExtract::NPathMode::kFullPathnames: + case NExtract::NPathMode::kCurrentPathnames: + case NExtract::NPathMode::kNoPathnames: + info.PathMode = NExtract::NPathMode::EEnum(extractModeIndex); + break; + } + } + UInt32 overwriteModeIndex; + if (extractionKey.QueryValue(kExtractionOverwriteModeValueName, overwriteModeIndex) == ERROR_SUCCESS) + { + switch (overwriteModeIndex) + { + case NExtract::NOverwriteMode::kAskBefore: + case NExtract::NOverwriteMode::kWithoutPrompt: + case NExtract::NOverwriteMode::kSkipExisting: + case NExtract::NOverwriteMode::kAutoRename: + case NExtract::NOverwriteMode::kAutoRenameExisting: + info.OverwriteMode = NExtract::NOverwriteMode::EEnum(overwriteModeIndex); + break; + } + } + if (extractionKey.QueryValue(kExtractionShowPasswordValueName, + info.ShowPassword) != ERROR_SUCCESS) + info.ShowPassword = false; +} + +/////////////////////////////////// +// CompressionInfo + +static const TCHAR *kCompressionKeyName = TEXT("Compression"); + +static const TCHAR *kCompressionHistoryArchivesKeyName = TEXT("ArcHistory"); +static const TCHAR *kCompressionLevelValueName = TEXT("Level"); +static const TCHAR *kCompressionLastFormatValueName = TEXT("Archiver"); +static const TCHAR *kCompressionShowPasswordValueName = TEXT("ShowPassword"); +static const TCHAR *kCompressionEncryptHeadersValueName = TEXT("EncryptHeaders"); +// static const TCHAR *kCompressionMaximizeValueName = TEXT("Maximize"); + +static const TCHAR *kCompressionOptionsKeyName = TEXT("Options"); +static const TCHAR *kSolid = TEXT("Solid"); +static const TCHAR *kMultiThread = TEXT("Multithread"); + +static const WCHAR *kCompressionOptions = L"Options"; +static const TCHAR *kCompressionLevel = TEXT("Level"); +static const WCHAR *kCompressionMethod = L"Method"; +static const WCHAR *kEncryptionMethod = L"EncryptionMethod"; +static const TCHAR *kCompressionDictionary = TEXT("Dictionary"); +static const TCHAR *kCompressionOrder = TEXT("Order"); + + +static void SetRegString(CKey &key, const WCHAR *name, const UString &value) +{ + if (value.IsEmpty()) + key.DeleteValue(name); + else + key.SetValue(name, value); +} + +static void SetRegUInt32(CKey &key, const TCHAR *name, UInt32 value) +{ + if (value == (UInt32)-1) + key.DeleteValue(name); + else + key.SetValue(name, value); +} + +static void GetRegString(CKey &key, const WCHAR *name, UString &value) +{ + if (key.QueryValue(name, value) != ERROR_SUCCESS) + value.Empty(); +} + +static void GetRegUInt32(CKey &key, const TCHAR *name, UInt32 &value) +{ + if (key.QueryValue(name, value) != ERROR_SUCCESS) + value = UInt32(-1); +} + +void SaveCompressionInfo(const NCompression::CInfo &info) +{ + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + + CKey compressionKey; + compressionKey.Create(HKEY_CURRENT_USER, GetKeyPath(kCompressionKeyName)); + compressionKey.RecurseDeleteKey(kCompressionHistoryArchivesKeyName); + { + CKey historyArchivesKey; + historyArchivesKey.Create(compressionKey, kCompressionHistoryArchivesKeyName); + for(int i = 0; i < info.HistoryArchives.Size(); i++) + { + wchar_t numberString[16]; + ConvertUInt64ToString(i, numberString); + historyArchivesKey.SetValue(numberString, info.HistoryArchives[i]); + } + } + + compressionKey.SetValue(kSolid, info.Solid); + compressionKey.SetValue(kMultiThread, info.MultiThread); + compressionKey.RecurseDeleteKey(kCompressionOptionsKeyName); + { + CKey optionsKey; + optionsKey.Create(compressionKey, kCompressionOptionsKeyName); + for(int i = 0; i < info.FormatOptionsVector.Size(); i++) + { + const NCompression::CFormatOptions &fo = info.FormatOptionsVector[i]; + CKey formatKey; + formatKey.Create(optionsKey, fo.FormatID); + + SetRegString(formatKey, kCompressionOptions, fo.Options); + SetRegString(formatKey, kCompressionMethod, fo.Method); + SetRegString(formatKey, kEncryptionMethod, fo.EncryptionMethod); + + SetRegUInt32(formatKey, kCompressionLevel, fo.Level); + SetRegUInt32(formatKey, kCompressionDictionary, fo.Dictionary); + SetRegUInt32(formatKey, kCompressionOrder, fo.Order); + } + } + + compressionKey.SetValue(kCompressionLevelValueName, UInt32(info.Level)); + compressionKey.SetValue(kCompressionLastFormatValueName, + GetSystemString(info.ArchiveType)); + + compressionKey.SetValue(kCompressionShowPasswordValueName, info.ShowPassword); + compressionKey.SetValue(kCompressionEncryptHeadersValueName, info.EncryptHeaders); + // compressionKey.SetValue(kCompressionMaximizeValueName, info.Maximize); +} + +static bool IsMultiProcessor() +{ + SYSTEM_INFO systemInfo; + GetSystemInfo(&systemInfo); + return systemInfo.dwNumberOfProcessors > 1; +} + +void ReadCompressionInfo(NCompression::CInfo &info) +{ + info.HistoryArchives.Clear(); + + info.Solid = true; + info.MultiThread = IsMultiProcessor(); + info.FormatOptionsVector.Clear(); + + info.Level = 5; + info.ArchiveType = L"7z"; + // definedStatus.Maximize = false; + info.ShowPassword = false; + info.EncryptHeaders = false; + + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey compressionKey; + + if(compressionKey.Open(HKEY_CURRENT_USER, + GetKeyPath(kCompressionKeyName), KEY_READ) != ERROR_SUCCESS) + return; + + { + CKey historyArchivesKey; + if(historyArchivesKey.Open(compressionKey, kCompressionHistoryArchivesKeyName, KEY_READ) == + ERROR_SUCCESS) + { + for (;;) + { + wchar_t numberString[16]; + ConvertUInt64ToString(info.HistoryArchives.Size(), numberString); + UString path; + if (historyArchivesKey.QueryValue(numberString, path) != ERROR_SUCCESS) + break; + info.HistoryArchives.Add(path); + } + } + } + + + bool solid = false; + if (compressionKey.QueryValue(kSolid, solid) == ERROR_SUCCESS) + info.Solid = solid; + bool multiThread = false; + if (compressionKey.QueryValue(kMultiThread, multiThread) == ERROR_SUCCESS) + info.MultiThread = multiThread; + + { + CKey optionsKey; + if(optionsKey.Open(compressionKey, kCompressionOptionsKeyName, KEY_READ) == + ERROR_SUCCESS) + { + CSysStringVector formatIDs; + optionsKey.EnumKeys(formatIDs); + for(int i = 0; i < formatIDs.Size(); i++) + { + CKey formatKey; + NCompression::CFormatOptions fo; + fo.FormatID = formatIDs[i]; + if(formatKey.Open(optionsKey, fo.FormatID, KEY_READ) == ERROR_SUCCESS) + { + GetRegString(formatKey, kCompressionOptions, fo.Options); + GetRegString(formatKey, kCompressionMethod, fo.Method); + GetRegString(formatKey, kEncryptionMethod, fo.EncryptionMethod); + + GetRegUInt32(formatKey, kCompressionLevel, fo.Level); + GetRegUInt32(formatKey, kCompressionDictionary, fo.Dictionary); + GetRegUInt32(formatKey, kCompressionOrder, fo.Order); + + info.FormatOptionsVector.Add(fo); + } + + } + } + } + + UInt32 level; + if (compressionKey.QueryValue(kCompressionLevelValueName, level) == ERROR_SUCCESS) + info.Level = level; + CSysString archiveType; + if (compressionKey.QueryValue(kCompressionLastFormatValueName, archiveType) == ERROR_SUCCESS) + info.ArchiveType = GetUnicodeString(archiveType); + if (compressionKey.QueryValue(kCompressionShowPasswordValueName, + info.ShowPassword) != ERROR_SUCCESS) + info.ShowPassword = false; + if (compressionKey.QueryValue(kCompressionEncryptHeadersValueName, + info.EncryptHeaders) != ERROR_SUCCESS) + info.EncryptHeaders = false; + /* + if (compressionKey.QueryValue(kCompressionLevelValueName, info.Maximize) == ERROR_SUCCESS) + definedStatus.Maximize = true; + */ +} + + +/////////////////////////////////// +// WorkDirInfo + +static const TCHAR *kOptionsInfoKeyName = TEXT("Options"); + +static const TCHAR *kWorkDirTypeValueName = TEXT("WorkDirType"); +static const WCHAR *kWorkDirPathValueName = L"WorkDirPath"; +static const TCHAR *kTempRemovableOnlyValueName = TEXT("TempRemovableOnly"); +static const TCHAR *kCascadedMenuValueName = TEXT("CascadedMenu"); +static const TCHAR *kContextMenuValueName = TEXT("ContextMenu"); + +void SaveWorkDirInfo(const NWorkDir::CInfo &info) +{ + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey optionsKey; + optionsKey.Create(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName)); + optionsKey.SetValue(kWorkDirTypeValueName, UInt32(info.Mode)); + optionsKey.SetValue(kWorkDirPathValueName, info.Path); + optionsKey.SetValue(kTempRemovableOnlyValueName, info.ForRemovableOnly); +} + +void ReadWorkDirInfo(NWorkDir::CInfo &info) +{ + info.SetDefault(); + + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey optionsKey; + if(optionsKey.Open(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName), KEY_READ) != ERROR_SUCCESS) + return; + + UInt32 dirType; + if (optionsKey.QueryValue(kWorkDirTypeValueName, dirType) != ERROR_SUCCESS) + return; + switch (dirType) + { + case NWorkDir::NMode::kSystem: + case NWorkDir::NMode::kCurrent: + case NWorkDir::NMode::kSpecified: + info.Mode = NWorkDir::NMode::EEnum(dirType); + } + UString sysWorkDir; + if (optionsKey.QueryValue(kWorkDirPathValueName, sysWorkDir) != ERROR_SUCCESS) + { + info.Path.Empty(); + if (info.Mode == NWorkDir::NMode::kSpecified) + info.Mode = NWorkDir::NMode::kSystem; + } + info.Path = GetUnicodeString(sysWorkDir); + if (optionsKey.QueryValue(kTempRemovableOnlyValueName, info.ForRemovableOnly) != ERROR_SUCCESS) + info.SetForRemovableOnlyDefault(); +} + +static void SaveOption(const TCHAR *value, bool enabled) +{ + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey optionsKey; + optionsKey.Create(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName)); + optionsKey.SetValue(value, enabled); +} + +static bool ReadOption(const TCHAR *value, bool defaultValue) +{ + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey optionsKey; + if(optionsKey.Open(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName), KEY_READ) != ERROR_SUCCESS) + return defaultValue; + bool enabled; + if (optionsKey.QueryValue(value, enabled) != ERROR_SUCCESS) + return defaultValue; + return enabled; +} + +void SaveCascadedMenu(bool show) + { SaveOption(kCascadedMenuValueName, show); } +bool ReadCascadedMenu() + { return ReadOption(kCascadedMenuValueName, true); } + + +static void SaveValue(const TCHAR *value, UInt32 valueToWrite) +{ + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey optionsKey; + optionsKey.Create(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName)); + optionsKey.SetValue(value, valueToWrite); +} + +static bool ReadValue(const TCHAR *value, UInt32 &result) +{ + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey optionsKey; + if(optionsKey.Open(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName), KEY_READ) != ERROR_SUCCESS) + return false; + return (optionsKey.QueryValue(value, result) == ERROR_SUCCESS); +} + +void SaveContextMenuStatus(UInt32 value) + { SaveValue(kContextMenuValueName, value); } + +bool ReadContextMenuStatus(UInt32 &value) + { return ReadValue(kContextMenuValueName, value); } diff --git a/CPP/7zip/UI/Common/ZipRegistry.h b/CPP/7zip/UI/Common/ZipRegistry.h new file mode 100755 index 00000000..30e7ee44 --- /dev/null +++ b/CPP/7zip/UI/Common/ZipRegistry.h @@ -0,0 +1,99 @@ +// ZipRegistry.h + +#ifndef __ZIPREGISTRY_H +#define __ZIPREGISTRY_H + +#include "Common/String.h" +#include "Common/Types.h" +#include "ExtractMode.h" + +namespace NExtract +{ + struct CInfo + { + NPathMode::EEnum PathMode; + NOverwriteMode::EEnum OverwriteMode; + UStringVector Paths; + bool ShowPassword; + }; +} + +namespace NCompression { + + struct CFormatOptions + { + CSysString FormatID; + UString Options; + UString Method; + UString EncryptionMethod; + UInt32 Level; + UInt32 Dictionary; + UInt32 Order; + void ResetForLevelChange() + { + Level = Dictionary = Order = UInt32(-1); + Method.Empty(); + // EncryptionMethod.Empty(); + // Options.Empty(); + } + CFormatOptions() { ResetForLevelChange(); } + }; + + struct CInfo + { + UStringVector HistoryArchives; + // bool LevelIsDefined; + UInt32 Level; + UString ArchiveType; + + bool Solid; + bool MultiThread; + CObjectVector FormatOptionsVector; + + bool ShowPassword; + bool EncryptHeaders; + }; +} + +namespace NWorkDir{ + + namespace NMode + { + enum EEnum + { + kSystem, + kCurrent, + kSpecified + }; + } + struct CInfo + { + NMode::EEnum Mode; + UString Path; + bool ForRemovableOnly; + void SetForRemovableOnlyDefault() { ForRemovableOnly = true; } + void SetDefault() + { + Mode = NMode::kSystem; + Path.Empty(); + SetForRemovableOnlyDefault(); + } + }; +} + +void SaveExtractionInfo(const NExtract::CInfo &info); +void ReadExtractionInfo(NExtract::CInfo &info); + +void SaveCompressionInfo(const NCompression::CInfo &info); +void ReadCompressionInfo(NCompression::CInfo &info); + +void SaveWorkDirInfo(const NWorkDir::CInfo &info); +void ReadWorkDirInfo(NWorkDir::CInfo &info); + +void SaveCascadedMenu(bool enabled); +bool ReadCascadedMenu(); + +void SaveContextMenuStatus(UInt32 value); +bool ReadContextMenuStatus(UInt32 &value); + +#endif diff --git a/CPP/7zip/UI/Console/Console.dsp b/CPP/7zip/UI/Console/Console.dsp new file mode 100755 index 00000000..e457008c --- /dev/null +++ b/CPP/7zip/UI/Console/Console.dsp @@ -0,0 +1,667 @@ +# Microsoft Developer Studio Project File - Name="Console" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=Console - Win32 DebugU +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Console.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Console.mak" CFG="Console - Win32 DebugU" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Console - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "Console - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "Console - Win32 ReleaseU" (based on "Win32 (x86) Console Application") +!MESSAGE "Console - Win32 DebugU" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Console - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\UTIL\7z.exe" /OPT:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Console - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "../../../" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\UTIL\7z.exe" /pdbtype:sept + +!ELSEIF "$(CFG)" == "Console - Win32 ReleaseU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Console___Win32_ReleaseU" +# PROP BASE Intermediate_Dir "Console___Win32_ReleaseU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseU" +# PROP Intermediate_Dir "ReleaseU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\UTIL\7z.exe" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\UTIL\7zn.exe" /OPT:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Console - Win32 DebugU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Console___Win32_DebugU" +# PROP BASE Intermediate_Dir "Console___Win32_DebugU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugU" +# PROP Intermediate_Dir "DebugU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "../../../" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "../../../" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\UTIL\7z.exe" /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\UTIL\7z.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Console - Win32 Release" +# Name "Console - Win32 Debug" +# Name "Console - Win32 ReleaseU" +# Name "Console - Win32 DebugU" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Console" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ConsoleClose.cpp +# End Source File +# Begin Source File + +SOURCE=.\ConsoleClose.h +# End Source File +# Begin Source File + +SOURCE=.\ExtractCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=.\ExtractCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=.\List.cpp +# End Source File +# Begin Source File + +SOURCE=.\List.h +# End Source File +# Begin Source File + +SOURCE=.\Main.cpp +# End Source File +# Begin Source File + +SOURCE=.\MainAr.cpp +# End Source File +# Begin Source File + +SOURCE=.\OpenCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=.\OpenCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=.\PercentPrinter.cpp +# End Source File +# Begin Source File + +SOURCE=.\PercentPrinter.h +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=.\UserInputUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\UserInputUtils.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Time.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Buffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ComTry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Exception.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\ArchiveCommandLine.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveCommandLine.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiverInfo.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiverInfo.h +# End Source File +# Begin Source File + +SOURCE=..\Common\CompressionMode.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DirItem.h +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExitCode.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Extract.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\Extract.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.h +# End Source File +# Begin Source File + +SOURCE=..\Common\HandlerLoader.h +# End Source File +# Begin Source File + +SOURCE=..\Common\IFileExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Property.h +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\SetProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\SetProperties.h +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\TempFiles.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\TempFiles.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Update.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\Update.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateProduce.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateProduce.h +# End Source File +# Begin Source File + +SOURCE=..\Common\WorkDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\WorkDir.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ZipRegistry.h +# End Source File +# End Group +# Begin Group "7-zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# End Target +# End Project diff --git a/CPP/7zip/UI/Console/Console.dsw b/CPP/7zip/UI/Console/Console.dsw new file mode 100755 index 00000000..0d93da2f --- /dev/null +++ b/CPP/7zip/UI/Console/Console.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Console"=".\Console.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/UI/Console/ConsoleClose.cpp b/CPP/7zip/UI/Console/ConsoleClose.cpp new file mode 100755 index 00000000..a514c12a --- /dev/null +++ b/CPP/7zip/UI/Console/ConsoleClose.cpp @@ -0,0 +1,65 @@ +// ConsoleClose.cpp + +#include "StdAfx.h" + +#include + +#include "ConsoleClose.h" + +static int g_BreakCounter = 0; +static const int kBreakAbortThreshold = 2; + +namespace NConsoleClose { + +static BOOL WINAPI HandlerRoutine(DWORD ctrlType) +{ + if (ctrlType == CTRL_LOGOFF_EVENT) + { + // printf("\nCTRL_LOGOFF_EVENT\n"); + return TRUE; + } + + g_BreakCounter++; + if (g_BreakCounter < kBreakAbortThreshold) + return TRUE; + return FALSE; + /* + switch(ctrlType) + { + case CTRL_C_EVENT: + case CTRL_BREAK_EVENT: + if (g_BreakCounter < kBreakAbortThreshold) + return TRUE; + } + return FALSE; + */ +} + +bool TestBreakSignal() +{ + /* + if (g_BreakCounter > 0) + return true; + */ + return (g_BreakCounter > 0); +} + +void CheckCtrlBreak() +{ + if (TestBreakSignal()) + throw CCtrlBreakException(); +} + +CCtrlHandlerSetter::CCtrlHandlerSetter() +{ + if(!SetConsoleCtrlHandler(HandlerRoutine, TRUE)) + throw "SetConsoleCtrlHandler fails"; +} + +CCtrlHandlerSetter::~CCtrlHandlerSetter() +{ + if(!SetConsoleCtrlHandler(HandlerRoutine, FALSE)) + throw "SetConsoleCtrlHandler fails"; +} + +} diff --git a/CPP/7zip/UI/Console/ConsoleClose.h b/CPP/7zip/UI/Console/ConsoleClose.h new file mode 100755 index 00000000..3c5fd55d --- /dev/null +++ b/CPP/7zip/UI/Console/ConsoleClose.h @@ -0,0 +1,24 @@ +// ConsoleCloseUtils.h + +#ifndef __CONSOLECLOSEUTILS_H +#define __CONSOLECLOSEUTILS_H + +namespace NConsoleClose { + +bool TestBreakSignal(); + +class CCtrlHandlerSetter +{ +public: + CCtrlHandlerSetter(); + virtual ~CCtrlHandlerSetter(); +}; + +class CCtrlBreakException +{}; + +void CheckCtrlBreak(); + +} + +#endif diff --git a/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp b/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp new file mode 100755 index 00000000..9bd605ec --- /dev/null +++ b/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp @@ -0,0 +1,235 @@ +// ExtractCallbackConsole.h + +#include "StdAfx.h" + +#include "ExtractCallbackConsole.h" +#include "UserInputUtils.h" +#include "ConsoleClose.h" + +#include "Common/Wildcard.h" + +#include "Windows/FileDir.h" +#include "Windows/FileFind.h" +#include "Windows/Time.h" +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" +#include "Windows/Error.h" +#include "Windows/PropVariantConversions.h" + +#include "../../Common/FilePathAutoRename.h" + +#include "../Common/ExtractingFilePath.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDirectory; + +static const char *kTestingString = "Testing "; +static const char *kExtractingString = "Extracting "; +static const char *kSkippingString = "Skipping "; + +static const char *kCantAutoRename = "can not create file with auto name\n"; +static const char *kCantRenameFile = "can not rename existing file\n"; +static const char *kCantDeleteOutputFile = "can not delete output file "; +static const char *kError = "ERROR: "; +static const char *kMemoryExceptionMessage = "Can't allocate required memory!"; + +static const char *kProcessing = "Processing archive: "; +static const char *kEverythingIsOk = "Everything is Ok"; +static const char *kNoFiles = "No files to process"; + +static const char *kUnsupportedMethod = "Unsupported Method"; +static const char *kCrcFailed = "CRC Failed"; +static const char *kCrcFailedEncrypted = "CRC Failed in encrypted file. Wrong password?"; +static const char *kDataError = "Data Error"; +static const char *kDataErrorEncrypted = "Data Error in encrypted file. Wrong password?"; +static const char *kUnknownError = "Unknown Error"; + +STDMETHODIMP CExtractCallbackConsole::SetTotal(UInt64) +{ + if (NConsoleClose::TestBreakSignal()) + return E_ABORT; + return S_OK; +} + +STDMETHODIMP CExtractCallbackConsole::SetCompleted(const UInt64 *) +{ + if (NConsoleClose::TestBreakSignal()) + return E_ABORT; + return S_OK; +} + +STDMETHODIMP CExtractCallbackConsole::AskOverwrite( + const wchar_t *existName, const FILETIME *, const UInt64 *, + const wchar_t *newName, const FILETIME *, const UInt64 *, + Int32 *answer) +{ + (*OutStream) << "file " << existName << + "\nalready exists. Overwrite with " << endl; + (*OutStream) << newName; + + NUserAnswerMode::EEnum overwriteAnswer = ScanUserYesNoAllQuit(OutStream); + + switch(overwriteAnswer) + { + case NUserAnswerMode::kQuit: + return E_ABORT; + case NUserAnswerMode::kNo: + *answer = NOverwriteAnswer::kNo; + break; + case NUserAnswerMode::kNoAll: + *answer = NOverwriteAnswer::kNoToAll; + break; + case NUserAnswerMode::kYesAll: + *answer = NOverwriteAnswer::kYesToAll; + break; + case NUserAnswerMode::kYes: + *answer = NOverwriteAnswer::kYes; + break; + case NUserAnswerMode::kAutoRename: + *answer = NOverwriteAnswer::kAutoRename; + break; + default: + return E_FAIL; + } + return S_OK; +} + +STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int32 askExtractMode, const UInt64 *position) +{ + switch (askExtractMode) + { + case NArchive::NExtract::NAskMode::kExtract: + (*OutStream) << kExtractingString; + break; + case NArchive::NExtract::NAskMode::kTest: + (*OutStream) << kTestingString; + break; + case NArchive::NExtract::NAskMode::kSkip: + (*OutStream) << kSkippingString; + break; + }; + (*OutStream) << name; + if (position != 0) + (*OutStream) << " <" << *position << ">"; + return S_OK; +} + +STDMETHODIMP CExtractCallbackConsole::MessageError(const wchar_t *message) +{ + (*OutStream) << message << endl; + NumFileErrorsInCurrentArchive++; + NumFileErrors++; + return S_OK; +} + +STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 operationResult, bool encrypted) +{ + switch(operationResult) + { + case NArchive::NExtract::NOperationResult::kOK: + break; + default: + { + NumFileErrorsInCurrentArchive++; + NumFileErrors++; + (*OutStream) << " "; + switch(operationResult) + { + case NArchive::NExtract::NOperationResult::kUnSupportedMethod: + (*OutStream) << kUnsupportedMethod; + break; + case NArchive::NExtract::NOperationResult::kCRCError: + (*OutStream) << (encrypted ? kCrcFailedEncrypted: kCrcFailed); + break; + case NArchive::NExtract::NOperationResult::kDataError: + (*OutStream) << (encrypted ? kDataErrorEncrypted : kDataError); + break; + default: + (*OutStream) << kUnknownError; + } + } + } + (*OutStream) << endl; + return S_OK; +} + +STDMETHODIMP CExtractCallbackConsole::CryptoGetTextPassword(BSTR *password) +{ + if (!PasswordIsDefined) + { + Password = GetPassword(OutStream); + PasswordIsDefined = true; + } + CMyComBSTR tempName(Password); + *password = tempName.Detach(); + return S_OK; +} + +HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name) +{ + NumArchives++; + NumFileErrorsInCurrentArchive = 0; + (*OutStream) << endl << kProcessing << name << endl; + return S_OK; +} + +HRESULT CExtractCallbackConsole::OpenResult(const wchar_t * /* name */, HRESULT result, bool encrypted) +{ + (*OutStream) << endl; + if (result != S_OK) + { + (*OutStream) << "Error: "; + if (encrypted) + (*OutStream) << "Can not open encrypted archive. Wrong password?"; + else + (*OutStream) << "Can not open file as archive"; + (*OutStream) << endl; + NumArchiveErrors++; + } + return S_OK; +} + +HRESULT CExtractCallbackConsole::ThereAreNoFiles() +{ + (*OutStream) << endl << kNoFiles << endl; + return S_OK; +} + +HRESULT CExtractCallbackConsole::ExtractResult(HRESULT result) +{ + if (result == S_OK) + { + (*OutStream) << endl; + if (NumFileErrorsInCurrentArchive == 0) + (*OutStream) << kEverythingIsOk << endl; + else + { + NumArchiveErrors++; + (*OutStream) << "Sub items Errors: " << NumFileErrorsInCurrentArchive << endl; + } + } + if (result == S_OK) + return result; + NumArchiveErrors++; + if (result == E_ABORT || result == ERROR_DISK_FULL) + return result; + (*OutStream) << endl << kError; + if (result == E_OUTOFMEMORY) + (*OutStream) << kMemoryExceptionMessage; + else + { + UString message; + NError::MyFormatMessage(result, message); + (*OutStream) << message; + } + (*OutStream) << endl; + return S_OK; +} + +HRESULT CExtractCallbackConsole::SetPassword(const UString &password) +{ + PasswordIsDefined = true; + Password = password; + return S_OK; +} diff --git a/CPP/7zip/UI/Console/ExtractCallbackConsole.h b/CPP/7zip/UI/Console/ExtractCallbackConsole.h new file mode 100755 index 00000000..5b45106a --- /dev/null +++ b/CPP/7zip/UI/Console/ExtractCallbackConsole.h @@ -0,0 +1,65 @@ +// ExtractCallbackConsole.h + +#ifndef __EXTRACTCALLBACKCONSOLE_H +#define __EXTRACTCALLBACKCONSOLE_H + +#include "Common/String.h" +#include "Common/StdOutStream.h" +#include "../../Common/FileStreams.h" +#include "../../IPassword.h" +#include "../../Archive/IArchive.h" +#include "../Common/ArchiveExtractCallback.h" + +class CExtractCallbackConsole: + public IExtractCallbackUI, + public ICryptoGetTextPassword, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP2(IFolderArchiveExtractCallback, ICryptoGetTextPassword) + + STDMETHOD(SetTotal)(UInt64 total); + STDMETHOD(SetCompleted)(const UInt64 *completeValue); + + // IFolderArchiveExtractCallback + STDMETHOD(AskOverwrite)( + const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, + const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, + Int32 *answer); + STDMETHOD (PrepareOperation)(const wchar_t *name, Int32 askExtractMode, const UInt64 *position); + + STDMETHOD(MessageError)(const wchar_t *message); + STDMETHOD(SetOperationResult)(Int32 operationResult, bool encrypted); + + // ICryptoGetTextPassword + STDMETHOD(CryptoGetTextPassword)(BSTR *password); + + HRESULT BeforeOpen(const wchar_t *name); + HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted); + HRESULT ThereAreNoFiles(); + HRESULT ExtractResult(HRESULT result); + + HRESULT SetPassword(const UString &password); + +public: + bool PasswordIsDefined; + UString Password; + + UInt64 NumArchives; + UInt64 NumArchiveErrors; + UInt64 NumFileErrors; + UInt64 NumFileErrorsInCurrentArchive; + + CStdOutStream *OutStream; + + void Init() + { + NumArchives = 0; + NumArchiveErrors = 0; + NumFileErrors = 0; + NumFileErrorsInCurrentArchive = 0; + } + +}; + +#endif diff --git a/CPP/7zip/UI/Console/List.cpp b/CPP/7zip/UI/Console/List.cpp new file mode 100755 index 00000000..6001e114 --- /dev/null +++ b/CPP/7zip/UI/Console/List.cpp @@ -0,0 +1,532 @@ +// List.cpp + +#include "StdAfx.h" + +#include "List.h" +#include "ConsoleClose.h" + +#include "Common/StringConvert.h" +#include "Common/StdOutStream.h" +#include "Common/IntToString.h" +#include "Common/MyCom.h" + +#include "Windows/PropVariant.h" +#include "Windows/Defs.h" +#include "Windows/PropVariantConversions.h" +#include "Windows/FileDir.h" + +#include "../../Archive/IArchive.h" + +#include "../Common/PropIDUtils.h" +#include "../Common/OpenArchive.h" + +#include "OpenCallbackConsole.h" + +using namespace NWindows; + +struct CPropIdToName +{ + PROPID PropID; + const wchar_t *Name; +}; + +static CPropIdToName kPropIdToName[] = +{ + { kpidPath, L"Path" }, + { kpidName, L"Name" }, + { kpidIsFolder, L"Folder" }, + { kpidSize, L"Size" }, + { kpidPackedSize, L"Packed Size" }, + { kpidAttributes, L"Attributes" }, + { kpidCreationTime, L"Created" }, + { kpidLastAccessTime, L"Accessed" }, + { kpidLastWriteTime, L"Modified" }, + { kpidSolid, L"Solid" }, + { kpidCommented, L"Commented" }, + { kpidEncrypted, L"Encrypted" }, + { kpidSplitBefore, L"Split Before" }, + { kpidSplitAfter, L"Split After" }, + { kpidDictionarySize, L"Dictionary Size" }, + { kpidCRC, L"CRC" }, + { kpidType, L"Type" }, + { kpidIsAnti, L"Anti" }, + { kpidMethod, L"Method" }, + { kpidHostOS, L"Host OS" }, + { kpidFileSystem, L"File System" }, + { kpidUser, L"User" }, + { kpidGroup, L"Group" }, + { kpidBlock, L"Block" }, + { kpidComment, L"Comment" }, + { kpidPosition, L"Position" } +}; + +static const char kEmptyAttributeChar = '.'; +static const char kDirectoryAttributeChar = 'D'; +static const char kReadonlyAttributeChar = 'R'; +static const char kHiddenAttributeChar = 'H'; +static const char kSystemAttributeChar = 'S'; +static const char kArchiveAttributeChar = 'A'; + +static const char *kListing = "Listing archive: "; +static const wchar_t *kFilesMessage = L"files"; + +static void GetAttributesString(DWORD wa, bool directory, char *s) +{ + s[0] = ((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || directory) ? + kDirectoryAttributeChar: kEmptyAttributeChar; + s[1] = ((wa & FILE_ATTRIBUTE_READONLY) != 0)? + kReadonlyAttributeChar: kEmptyAttributeChar; + s[2] = ((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ? + kHiddenAttributeChar: kEmptyAttributeChar; + s[3] = ((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ? + kSystemAttributeChar: kEmptyAttributeChar; + s[4] = ((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ? + kArchiveAttributeChar: kEmptyAttributeChar; + s[5] = '\0'; +} + +enum EAdjustment +{ + kLeft, + kCenter, + kRight +}; + +struct CFieldInfo +{ + PROPID PropID; + UString Name; + EAdjustment TitleAdjustment; + EAdjustment TextAdjustment; + int PrefixSpacesWidth; + int Width; +}; + +struct CFieldInfoInit +{ + PROPID PropID; + const wchar_t *Name; + EAdjustment TitleAdjustment; + EAdjustment TextAdjustment; + int PrefixSpacesWidth; + int Width; +}; + +CFieldInfoInit kStandardFieldTable[] = +{ + { kpidLastWriteTime, L" Date Time", kLeft, kLeft, 0, 19 }, + { kpidAttributes, L"Attr", kRight, kCenter, 1, 5 }, + { kpidSize, L"Size", kRight, kRight, 1, 12 }, + { kpidPackedSize, L"Compressed", kRight, kRight, 1, 12 }, + { kpidPath, L"Name", kLeft, kLeft, 2, 12 } +}; + +void PrintSpaces(int numSpaces) +{ + for (int i = 0; i < numSpaces; i++) + g_StdOut << ' '; +} + +void PrintString(EAdjustment adjustment, int width, const UString &textString) +{ + const int numSpaces = width - textString.Length(); + int numLeftSpaces = 0; + switch (adjustment) + { + case kLeft: + numLeftSpaces = 0; + break; + case kCenter: + numLeftSpaces = numSpaces / 2; + break; + case kRight: + numLeftSpaces = numSpaces; + break; + } + PrintSpaces(numLeftSpaces); + g_StdOut << textString; + PrintSpaces(numSpaces - numLeftSpaces); +} + +class CFieldPrinter +{ + CObjectVector _fields; +public: + void Clear() { _fields.Clear(); } + void Init(const CFieldInfoInit *standardFieldTable, int numItems); + HRESULT Init(IInArchive *archive); + void PrintTitle(); + void PrintTitleLines(); + HRESULT PrintItemInfo(IInArchive *archive, + const UString &defaultItemName, + const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo, + UInt32 index, + bool techMode); + HRESULT PrintSummaryInfo(UInt64 numFiles, const UInt64 *size, + const UInt64 *compressedSize); +}; + +void CFieldPrinter::Init(const CFieldInfoInit *standardFieldTable, int numItems) +{ + Clear(); + for (int i = 0; i < numItems; i++) + { + CFieldInfo fieldInfo; + const CFieldInfoInit &fieldInfoInit = standardFieldTable[i]; + fieldInfo.PropID = fieldInfoInit.PropID; + fieldInfo.Name = fieldInfoInit.Name; + fieldInfo.TitleAdjustment = fieldInfoInit.TitleAdjustment; + fieldInfo.TextAdjustment = fieldInfoInit.TextAdjustment; + fieldInfo.PrefixSpacesWidth = fieldInfoInit.PrefixSpacesWidth; + fieldInfo.Width = fieldInfoInit.Width; + _fields.Add(fieldInfo); + } +} + +HRESULT CFieldPrinter::Init(IInArchive *archive) +{ + Clear(); + UInt32 numProps; + RINOK(archive->GetNumberOfProperties(&numProps)); + for (UInt32 i = 0; i < numProps; i++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE vt; + RINOK(archive->GetPropertyInfo(i, &name, &propID, &vt)); + CFieldInfo fieldInfo; + fieldInfo.PropID = propID; + if (name != NULL) + fieldInfo.Name = name; + else + { + fieldInfo.Name = L"Unknown"; + for (int i = 0; i < sizeof(kPropIdToName) / sizeof(kPropIdToName[0]); i++) + { + const CPropIdToName &propIdToName = kPropIdToName[i]; + if (propIdToName.PropID == propID) + { + fieldInfo.Name = propIdToName.Name; + break; + } + } + } + _fields.Add(fieldInfo); + } + return S_OK; +} + +void CFieldPrinter::PrintTitle() +{ + for (int i = 0; i < _fields.Size(); i++) + { + const CFieldInfo &fieldInfo = _fields[i]; + PrintSpaces(fieldInfo.PrefixSpacesWidth); + PrintString(fieldInfo.TitleAdjustment, + ((fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width), fieldInfo.Name); + } +} + +void CFieldPrinter::PrintTitleLines() +{ + for (int i = 0; i < _fields.Size(); i++) + { + const CFieldInfo &fieldInfo = _fields[i]; + PrintSpaces(fieldInfo.PrefixSpacesWidth); + for (int i = 0; i < fieldInfo.Width; i++) + g_StdOut << '-'; + } +} + + +BOOL IsFileTimeZero(CONST FILETIME *lpFileTime) +{ + return (lpFileTime->dwLowDateTime == 0) && (lpFileTime->dwHighDateTime == 0); +} + +static const char *kEmptyTimeString = " "; +void PrintTime(const NCOM::CPropVariant &propVariant) +{ + if (propVariant.vt != VT_FILETIME) + throw "incorrect item"; + if (IsFileTimeZero(&propVariant.filetime)) + g_StdOut << kEmptyTimeString; + else + { + FILETIME localFileTime; + if (!FileTimeToLocalFileTime(&propVariant.filetime, &localFileTime)) + throw "FileTimeToLocalFileTime error"; + char s[32]; + if (ConvertFileTimeToString(localFileTime, s, true, true)) + g_StdOut << s; + else + g_StdOut << kEmptyTimeString; + } +} + +HRESULT CFieldPrinter::PrintItemInfo(IInArchive *archive, + const UString &defaultItemName, + const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo, + UInt32 index, + bool techMode) +{ + /* + if (techMode) + { + g_StdOut << "Index = "; + g_StdOut << (UInt64)index; + g_StdOut << endl; + } + */ + for (int i = 0; i < _fields.Size(); i++) + { + const CFieldInfo &fieldInfo = _fields[i]; + if (!techMode) + PrintSpaces(fieldInfo.PrefixSpacesWidth); + + NCOM::CPropVariant propVariant; + RINOK(archive->GetProperty(index, fieldInfo.PropID, &propVariant)); + if (techMode) + { + g_StdOut << fieldInfo.Name << " = "; + } + int width = (fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width; + if (propVariant.vt == VT_EMPTY) + { + switch(fieldInfo.PropID) + { + case kpidPath: + propVariant = defaultItemName; + break; + case kpidLastWriteTime: + propVariant = archiveFileInfo.LastWriteTime; + break; + default: + if (techMode) + g_StdOut << endl; + else + PrintSpaces(width); + continue; + } + } + if (fieldInfo.PropID == kpidLastWriteTime) + { + PrintTime(propVariant); + } + else if (fieldInfo.PropID == kpidAttributes) + { + if (propVariant.vt != VT_UI4) + throw "incorrect item"; + UInt32 attributes = propVariant.ulVal; + bool isFolder; + RINOK(IsArchiveItemFolder(archive, index, isFolder)); + char s[8]; + GetAttributesString(attributes, isFolder, s); + g_StdOut << s; + } + else if (propVariant.vt == VT_BSTR) + { + if (techMode) + g_StdOut << propVariant.bstrVal; + else + PrintString(fieldInfo.TextAdjustment, width, propVariant.bstrVal); + } + else + { + UString s = ConvertPropertyToString(propVariant, fieldInfo.PropID); + if (techMode) + g_StdOut << s; + else + PrintString(fieldInfo.TextAdjustment, width, s); + } + if (techMode) + g_StdOut << endl; + } + return S_OK; +} + +void PrintNumberString(EAdjustment adjustment, int width, const UInt64 *value) +{ + wchar_t textString[32] = { 0 }; + if (value != NULL) + ConvertUInt64ToString(*value, textString); + PrintString(adjustment, width, textString); +} + + +HRESULT CFieldPrinter::PrintSummaryInfo(UInt64 numFiles, + const UInt64 *size, const UInt64 *compressedSize) +{ + for (int i = 0; i < _fields.Size(); i++) + { + const CFieldInfo &fieldInfo = _fields[i]; + PrintSpaces(fieldInfo.PrefixSpacesWidth); + NCOM::CPropVariant propVariant; + if (fieldInfo.PropID == kpidSize) + PrintNumberString(fieldInfo.TextAdjustment, fieldInfo.Width, size); + else if (fieldInfo.PropID == kpidPackedSize) + PrintNumberString(fieldInfo.TextAdjustment, fieldInfo.Width, compressedSize); + else if (fieldInfo.PropID == kpidPath) + { + wchar_t textString[32]; + ConvertUInt64ToString(numFiles, textString); + UString temp = textString; + temp += L" "; + temp += kFilesMessage; + PrintString(fieldInfo.TextAdjustment, 0, temp); + } + else + PrintString(fieldInfo.TextAdjustment, fieldInfo.Width, L""); + } + return S_OK; +} + +bool GetUInt64Value(IInArchive *archive, UInt32 index, PROPID propID, UInt64 &value) +{ + NCOM::CPropVariant propVariant; + if (archive->GetProperty(index, propID, &propVariant) != S_OK) + throw "GetPropertyValue error"; + if (propVariant.vt == VT_EMPTY) + return false; + value = ConvertPropVariantToUInt64(propVariant); + return true; +} + +HRESULT ListArchives(UStringVector &archivePaths, UStringVector &archivePathsFull, + const NWildcard::CCensorNode &wildcardCensor, + bool enableHeaders, bool techMode, bool &passwordEnabled, UString &password) +{ + CFieldPrinter fieldPrinter; + if (!techMode) + fieldPrinter.Init(kStandardFieldTable, sizeof(kStandardFieldTable) / sizeof(kStandardFieldTable[0])); + + UInt64 numFiles2 = 0, totalPackSize2 = 0, totalUnPackSize2 = 0; + UInt64 *totalPackSizePointer2 = 0, *totalUnPackSizePointer2 = 0; + int numErrors = 0; + for (int i = 0; i < archivePaths.Size(); i++) + { + const UString &archiveName = archivePaths[i]; + NFile::NFind::CFileInfoW archiveFileInfo; + if (!NFile::NFind::FindFile(archiveName, archiveFileInfo) || archiveFileInfo.IsDirectory()) + { + g_StdOut << endl << "Error: " << archiveName << " is not archive" << endl; + numErrors++; + continue; + } + if (archiveFileInfo.IsDirectory()) + { + g_StdOut << endl << "Error: " << archiveName << " is not file" << endl; + numErrors++; + continue; + } + + CArchiveLink archiveLink; + + COpenCallbackConsole openCallback; + openCallback.OutStream = &g_StdOut; + openCallback.PasswordIsDefined = passwordEnabled; + openCallback.Password = password; + + HRESULT result = MyOpenArchive(archiveName, archiveLink, &openCallback); + if (result != S_OK) + { + g_StdOut << endl << "Error: " << archiveName << " is not supported archive" << endl; + numErrors++; + continue; + } + + for (int v = 0; v < archiveLink.VolumePaths.Size(); v++) + { + int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]); + if (index >= 0 && index > i) + { + archivePaths.Delete(index); + archivePathsFull.Delete(index); + } + } + + IInArchive *archive = archiveLink.GetArchive(); + const UString defaultItemName = archiveLink.GetDefaultItemName(); + + if (enableHeaders) + g_StdOut << endl << kListing << archiveName << endl << endl; + + if (enableHeaders && !techMode) + { + fieldPrinter.PrintTitle(); + g_StdOut << endl; + fieldPrinter.PrintTitleLines(); + g_StdOut << endl; + } + + if (techMode) + { + RINOK(fieldPrinter.Init(archive)); + } + UInt64 numFiles = 0, totalPackSize = 0, totalUnPackSize = 0; + UInt64 *totalPackSizePointer = 0, *totalUnPackSizePointer = 0; + UInt32 numItems; + RINOK(archive->GetNumberOfItems(&numItems)); + for(UInt32 i = 0; i < numItems; i++) + { + if (NConsoleClose::TestBreakSignal()) + return E_ABORT; + + UString filePath; + RINOK(GetArchiveItemPath(archive, i, defaultItemName, filePath)); + + bool isFolder; + RINOK(IsArchiveItemFolder(archive, i, isFolder)); + if (!wildcardCensor.CheckPath(filePath, !isFolder)) + continue; + + fieldPrinter.PrintItemInfo(archive, defaultItemName, archiveFileInfo, i, techMode); + + UInt64 packSize, unpackSize; + if (!GetUInt64Value(archive, i, kpidSize, unpackSize)) + unpackSize = 0; + else + totalUnPackSizePointer = &totalUnPackSize; + if (!GetUInt64Value(archive, i, kpidPackedSize, packSize)) + packSize = 0; + else + totalPackSizePointer = &totalPackSize; + + g_StdOut << endl; + + numFiles++; + totalPackSize += packSize; + totalUnPackSize += unpackSize; + } + if (enableHeaders && !techMode) + { + fieldPrinter.PrintTitleLines(); + g_StdOut << endl; + fieldPrinter.PrintSummaryInfo(numFiles, totalUnPackSizePointer, totalPackSizePointer); + g_StdOut << endl; + } + if (totalPackSizePointer != 0) + { + totalPackSizePointer2 = &totalPackSize2; + totalPackSize2 += totalPackSize; + } + if (totalUnPackSizePointer != 0) + { + totalUnPackSizePointer2 = &totalUnPackSize2; + totalUnPackSize2 += totalUnPackSize; + } + numFiles2 += numFiles; + } + if (enableHeaders && !techMode && archivePaths.Size() > 1) + { + g_StdOut << endl; + fieldPrinter.PrintTitleLines(); + g_StdOut << endl; + fieldPrinter.PrintSummaryInfo(numFiles2, totalUnPackSizePointer2, totalPackSizePointer2); + g_StdOut << endl; + g_StdOut << "Archives: " << archivePaths.Size() << endl; + } + if (numErrors > 0) + g_StdOut << endl << "Errors: " << numErrors; + return S_OK; +} diff --git a/CPP/7zip/UI/Console/List.h b/CPP/7zip/UI/Console/List.h new file mode 100755 index 00000000..201a4128 --- /dev/null +++ b/CPP/7zip/UI/Console/List.h @@ -0,0 +1,13 @@ +// List.h + +#ifndef __LIST_H +#define __LIST_H + +#include "Common/Wildcard.h" + +HRESULT ListArchives(UStringVector &archivePaths, UStringVector &archivePathsFull, + const NWildcard::CCensorNode &wildcardCensor, + bool enableHeaders, bool techMode, bool &passwordEnabled, UString &password); + +#endif + diff --git a/CPP/7zip/UI/Console/Main.cpp b/CPP/7zip/UI/Console/Main.cpp new file mode 100755 index 00000000..387b8c2a --- /dev/null +++ b/CPP/7zip/UI/Console/Main.cpp @@ -0,0 +1,382 @@ +// Main.cpp + +#include "StdAfx.h" + +#include + +#include "Common/MyInitGuid.h" +#include "Common/CommandLineParser.h" +#include "Common/StdOutStream.h" +#include "Common/Wildcard.h" +#include "Common/ListFileUtils.h" +#include "Common/StringConvert.h" +#include "Common/StdInStream.h" +#include "Common/StringToInt.h" +#include "Common/Exception.h" + +#include "Windows/FileDir.h" +#include "Windows/FileName.h" +#include "Windows/Defs.h" +#include "Windows/Error.h" +// #include "Windows/System.h" +#ifdef _WIN32 +#include "Windows/MemoryLock.h" +#endif + +#include "../../IPassword.h" +#include "../../ICoder.h" +#include "../Common/ArchiverInfo.h" +#include "../Common/UpdateAction.h" +#include "../Common/Update.h" +#include "../Common/Extract.h" +#include "../Common/ArchiveCommandLine.h" +#include "../Common/ExitCode.h" + +#include "List.h" +#include "OpenCallbackConsole.h" +#include "ExtractCallbackConsole.h" +#include "UpdateCallbackConsole.h" + +#include "../../MyVersion.h" + +#ifndef EXCLUDE_COM +#include "Windows/DLL.h" +#endif + +using namespace NWindows; +using namespace NFile; +using namespace NCommandLineParser; + +HINSTANCE g_hInstance = 0; +extern CStdOutStream *g_StdStream; + +static const char *kCopyrightString = "\n7-Zip" +#ifdef EXCLUDE_COM +" (A)" +#endif + +#ifdef UNICODE +" [NT]" +#endif + +" " MY_VERSION_COPYRIGHT_DATE "\n"; + +static const char *kHelpString = + "\nUsage: 7z" +#ifdef _NO_CRYPTO + "r" +#elif EXCLUDE_COM + "a" +#endif + " [...] [...]\n" + " [<@listfiles...>]\n" + "\n" + "\n" + " a: Add files to archive\n" + " d: Delete files from archive\n" + " e: Extract files from archive (without using directory names)\n" + " l: List contents of archive\n" +// " l[a|t][f]: List contents of archive\n" +// " a - with Additional fields\n" +// " t - with all fields\n" +// " f - with Full pathnames\n" + " t: Test integrity of archive\n" + " u: Update files to archive\n" + " x: eXtract files with full paths\n" + "\n" + " -ai[r[-|0]]{@listfile|!wildcard}: Include archives\n" + " -ax[r[-|0]]{@listfile|!wildcard}: eXclude archives\n" + " -bd: Disable percentage indicator\n" + " -i[r[-|0]]{@listfile|!wildcard}: Include filenames\n" + " -m{Parameters}: set compression Method\n" + " -o{Directory}: set Output directory\n" + " -p{Password}: set Password\n" + " -r[-|0]: Recurse subdirectories\n" + " -scs{UTF-8 | WIN | DOS}: set charset for list files\n" + " -sfx[{name}]: Create SFX archive\n" + " -si[{name}]: read data from stdin\n" + " -slt: show technical information for l (List) command\n" + " -so: write data to stdout\n" + " -t{Type}: Set type of archive\n" + " -v{Size}[b|k|m|g]: Create volumes\n" + " -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName]: Update options\n" + " -w[{path}]: assign Work directory. Empty path means a temporary directory\n" + " -x[r[-|0]]]{@listfile|!wildcard}: eXclude filenames\n" + " -y: assume Yes on all queries\n"; + +// --------------------------- +// exception messages + +static const char *kProcessArchiveMessage = " archive: "; +static const char *kEverythingIsOk = "Everything is Ok"; +static const char *kUserErrorMessage = "Incorrect command line"; // NExitCode::kUserError + +static const wchar_t *kDefaultSfxModule = L"7zCon.sfx"; + +static void ShowMessageAndThrowException(CStdOutStream &s, LPCSTR message, NExitCode::EEnum code) +{ + s << message << endl; + throw code; +} + +static void PrintHelpAndExit(CStdOutStream &s) // yyy +{ + s << kHelpString; + ShowMessageAndThrowException(s, kUserErrorMessage, NExitCode::kUserError); +} + +#ifndef _WIN32 +static void GetArguments(int numArguments, const char *arguments[], UStringVector &parts) +{ + parts.Clear(); + for(int i = 0; i < numArguments; i++) + { + UString s = MultiByteToUnicodeString(arguments[i]); + parts.Add(s); + } +} +#endif + +static void ShowCopyrightAndHelp(CStdOutStream &s, bool needHelp) +{ + s << kCopyrightString; + /* + UInt32 numCPUs = NWindows::NSystem::GetNumberOfProcessors(); + s << "System configuration: " << (UInt64)numCPUs << " CPU"; + if (numCPUs > 1) + s << "s"; + s << "\n"; + */ + if (needHelp) + s << kHelpString; +} + +int Main2( + #ifndef _WIN32 + int numArguments, const char *arguments[] + #endif +) +{ + #ifdef _WIN32 + SetFileApisToOEM(); + #endif + + UStringVector commandStrings; + #ifdef _WIN32 + NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); + #else + GetArguments(numArguments, arguments, commandStrings); + #endif + + if(commandStrings.Size() == 1) + { + ShowCopyrightAndHelp(g_StdOut, true); + return 0; + } + commandStrings.Delete(0); + + CArchiveCommandLineOptions options; + + CArchiveCommandLineParser parser; + + parser.Parse1(commandStrings, options); + + if(options.HelpMode) + { + ShowCopyrightAndHelp(g_StdOut, true); + return 0; + } + + #ifdef _WIN32 + if (options.LargePages) + NSecurity::EnableLockMemoryPrivilege(); + #endif + + CStdOutStream &stdStream = options.StdOutMode ? g_StdErr : g_StdOut; + g_StdStream = &stdStream; + + if (options.EnableHeaders) + ShowCopyrightAndHelp(stdStream, false); + + parser.Parse2(options); + + bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); + if(isExtractGroupCommand || + options.Command.CommandType == NCommandType::kList) + { + if(isExtractGroupCommand) + { + CExtractCallbackConsole *ecs = new CExtractCallbackConsole; + CMyComPtr extractCallback = ecs; + + ecs->OutStream = &stdStream; + ecs->PasswordIsDefined = options.PasswordEnabled; + ecs->Password = options.Password; + ecs->Init(); + + COpenCallbackConsole openCallback; + openCallback.OutStream = &stdStream; + openCallback.PasswordIsDefined = options.PasswordEnabled; + openCallback.Password = options.Password; + + CExtractOptions eo; + eo.StdOutMode = options.StdOutMode; + eo.PathMode = options.Command.GetPathMode(); + eo.TestMode = options.Command.IsTestMode(); + eo.OverwriteMode = options.OverwriteMode; + eo.OutputDir = options.OutputDir; + eo.YesToAll = options.YesToAll; + #ifdef COMPRESS_MT + eo.Properties = options.ExtractProperties; + #endif + UString errorMessage; + HRESULT result = DecompressArchives( + options.ArchivePathsSorted, + options.ArchivePathsFullSorted, + options.WildcardCensor.Pairs.Front().Head, + eo, &openCallback, ecs, errorMessage); + if (!errorMessage.IsEmpty()) + { + stdStream << endl << "Error: " << errorMessage; + if (result == S_OK) + result = E_FAIL; + } + + if (ecs->NumArchives > 1) + { + stdStream << endl << endl << "Total:" << endl; + stdStream << "Archives: " << ecs->NumArchives << endl; + } + if (ecs->NumArchiveErrors != 0 || ecs->NumFileErrors != 0) + { + if (ecs->NumArchives > 1) + { + if (ecs->NumArchiveErrors != 0) + stdStream << "Archive Errors: " << ecs->NumArchiveErrors << endl; + if (ecs->NumFileErrors != 0) + stdStream << "Sub items Errors: " << ecs->NumFileErrors << endl; + } + if (result != S_OK) + throw CSystemException(result); + return NExitCode::kFatalError; + } + if (result != S_OK) + throw CSystemException(result); + } + else + { + HRESULT result = ListArchives( + options.ArchivePathsSorted, + options.ArchivePathsFullSorted, + options.WildcardCensor.Pairs.Front().Head, + options.EnableHeaders, + options.TechMode, + options.PasswordEnabled, + options.Password); + if (result != S_OK) + throw CSystemException(result); + } + } + else if(options.Command.IsFromUpdateGroup()) + { + UString workingDir; + + CUpdateOptions &uo = options.UpdateOptions; + if (uo.SfxMode && uo.SfxModule.IsEmpty()) + uo.SfxModule = kDefaultSfxModule; + + bool passwordIsDefined = + options.PasswordEnabled && !options.Password.IsEmpty(); + + COpenCallbackConsole openCallback; + openCallback.OutStream = &stdStream; + openCallback.PasswordIsDefined = passwordIsDefined; + openCallback.Password = options.Password; + + CUpdateCallbackConsole callback; + callback.EnablePercents = options.EnablePercents; + callback.PasswordIsDefined = passwordIsDefined; + callback.AskPassword = options.PasswordEnabled && options.Password.IsEmpty(); + callback.Password = options.Password; + callback.StdOutMode = uo.StdOutMode; + callback.Init(&stdStream); + + CUpdateErrorInfo errorInfo; + + HRESULT result = UpdateArchive(options.WildcardCensor, uo, + errorInfo, &openCallback, &callback); + + int exitCode = NExitCode::kSuccess; + if (callback.CantFindFiles.Size() > 0) + { + stdStream << endl; + stdStream << "WARNINGS for files:" << endl << endl; + int numErrors = callback.CantFindFiles.Size(); + for (int i = 0; i < numErrors; i++) + { + stdStream << callback.CantFindFiles[i] << " : "; + stdStream << NError::MyFormatMessageW(callback.CantFindCodes[i]) << endl; + } + stdStream << "----------------" << endl; + stdStream << "WARNING: Cannot find " << numErrors << " file"; + if (numErrors > 1) + stdStream << "s"; + stdStream << endl; + exitCode = NExitCode::kWarning; + } + + if (result != S_OK) + { + UString message; + if (!errorInfo.Message.IsEmpty()) + { + message += errorInfo.Message; + message += L"\n"; + } + if (!errorInfo.FileName.IsEmpty()) + { + message += errorInfo.FileName; + message += L"\n"; + } + if (!errorInfo.FileName2.IsEmpty()) + { + message += errorInfo.FileName2; + message += L"\n"; + } + if (errorInfo.SystemError != 0) + { + message += NError::MyFormatMessageW(errorInfo.SystemError); + message += L"\n"; + } + if (!message.IsEmpty()) + stdStream << L"\nError:\n" << message; + throw CSystemException(result); + } + int numErrors = callback.FailedFiles.Size(); + if (numErrors == 0) + { + if (callback.CantFindFiles.Size() == 0) + stdStream << kEverythingIsOk << endl; + } + else + { + stdStream << endl; + stdStream << "WARNINGS for files:" << endl << endl; + for (int i = 0; i < numErrors; i++) + { + stdStream << callback.FailedFiles[i] << " : "; + stdStream << NError::MyFormatMessageW(callback.FailedCodes[i]) << endl; + } + stdStream << "----------------" << endl; + stdStream << "WARNING: Cannot open " << numErrors << " file"; + if (numErrors > 1) + stdStream << "s"; + stdStream << endl; + exitCode = NExitCode::kWarning; + } + return exitCode; + } + else + PrintHelpAndExit(stdStream); + return 0; +} diff --git a/CPP/7zip/UI/Console/MainAr.cpp b/CPP/7zip/UI/Console/MainAr.cpp new file mode 100755 index 00000000..4bdf813a --- /dev/null +++ b/CPP/7zip/UI/Console/MainAr.cpp @@ -0,0 +1,169 @@ +// MainAr.cpp + +#include "StdAfx.h" + +// #include + +#include "Windows/Error.h" + +#include "Common/StdOutStream.h" +#include "Common/NewHandler.h" +#include "Common/Exception.h" +#include "Common/StringConvert.h" +#ifdef _WIN32 +#include "Common/Alloc.h" +#endif + +#include "../Common/ExitCode.h" +#include "../Common/ArchiveCommandLine.h" +#include "ConsoleClose.h" + +#ifdef CRC_GENERATE_TABLE +extern "C" +{ + #include "../../../../C/7zCrc.h" +} +#endif + +using namespace NWindows; + +CStdOutStream *g_StdStream = 0; + +#ifndef _UNICODE +bool g_IsNT = false; +#endif + +extern int Main2( + #ifndef _WIN32 + int numArguments, const char *arguments[] + #endif +); + +static const char *kExceptionErrorMessage = "\n\nError:\n"; +static const char *kUserBreak = "\nBreak signaled\n"; + +static const char *kMemoryExceptionMessage = "\n\nERROR: Can't allocate required memory!\n"; +static const char *kUnknownExceptionMessage = "\n\nUnknown Error\n"; +static const char *kInternalExceptionMessage = "\n\nInternal Error #"; + +static inline bool IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); +} + +int +#ifdef _MSC_VER +__cdecl +#endif +main +( +#ifndef _WIN32 +int numArguments, const char *arguments[] +#endif +) +{ + #ifdef CRC_GENERATE_TABLE + CrcGenerateTable(); + #endif + g_StdStream = &g_StdOut; + #ifdef _UNICODE + if (!IsItWindowsNT()) + { + (*g_StdStream) << "This program requires Windows NT/2000/XP/2003"; + return NExitCode::kFatalError; + } + #else + g_IsNT = IsItWindowsNT(); + #endif + + #ifdef _WIN32 + SetLargePageSize(); + #endif + + // setlocale(LC_COLLATE, ".OCP"); + NConsoleClose::CCtrlHandlerSetter ctrlHandlerSetter; + int res = 0; + try + { + res = Main2( +#ifndef _WIN32 + numArguments, arguments +#endif + ); + } + catch(const CNewException &) + { + (*g_StdStream) << kMemoryExceptionMessage; + return (NExitCode::kMemoryError); + } + catch(const NConsoleClose::CCtrlBreakException &) + { + (*g_StdStream) << endl << kUserBreak; + return (NExitCode::kUserBreak); + } + catch(const CArchiveCommandLineException &e) + { + (*g_StdStream) << kExceptionErrorMessage << e << endl; + return (NExitCode::kUserError); + } + catch(const CSystemException &systemError) + { + if (systemError.ErrorCode == E_OUTOFMEMORY) + { + (*g_StdStream) << kMemoryExceptionMessage; + return (NExitCode::kMemoryError); + } + if (systemError.ErrorCode == E_ABORT) + { + (*g_StdStream) << endl << kUserBreak; + return (NExitCode::kUserBreak); + } + UString message; + NError::MyFormatMessage(systemError.ErrorCode, message); + (*g_StdStream) << endl << endl << "System error:" << endl << + message << endl; + return (NExitCode::kFatalError); + } + catch(NExitCode::EEnum &exitCode) + { + (*g_StdStream) << kInternalExceptionMessage << exitCode << endl; + return (exitCode); + } + /* + catch(const NExitCode::CMultipleErrors &multipleErrors) + { + (*g_StdStream) << endl << multipleErrors.NumErrors << " errors" << endl; + return (NExitCode::kFatalError); + } + */ + catch(const UString &s) + { + (*g_StdStream) << kExceptionErrorMessage << s << endl; + return (NExitCode::kFatalError); + } + catch(const AString &s) + { + (*g_StdStream) << kExceptionErrorMessage << s << endl; + return (NExitCode::kFatalError); + } + catch(const char *s) + { + (*g_StdStream) << kExceptionErrorMessage << s << endl; + return (NExitCode::kFatalError); + } + catch(int t) + { + (*g_StdStream) << kInternalExceptionMessage << t << endl; + return (NExitCode::kFatalError); + } + catch(...) + { + (*g_StdStream) << kUnknownExceptionMessage; + return (NExitCode::kFatalError); + } + return res; +} diff --git a/CPP/7zip/UI/Console/OpenCallbackConsole.cpp b/CPP/7zip/UI/Console/OpenCallbackConsole.cpp new file mode 100755 index 00000000..06ff165f --- /dev/null +++ b/CPP/7zip/UI/Console/OpenCallbackConsole.cpp @@ -0,0 +1,58 @@ +// OpenCallbackConsole.cpp + +#include "StdAfx.h" + +#include "OpenCallbackConsole.h" + +#include "ConsoleClose.h" +#include "UserInputUtils.h" + +HRESULT COpenCallbackConsole::CheckBreak() +{ + if (NConsoleClose::TestBreakSignal()) + return E_ABORT; + return S_OK; +} + +HRESULT COpenCallbackConsole::SetTotal(const UInt64 *, const UInt64 *) +{ + return CheckBreak(); +} + +HRESULT COpenCallbackConsole::SetCompleted(const UInt64 *, const UInt64 *) +{ + return CheckBreak(); +} + +HRESULT COpenCallbackConsole::CryptoGetTextPassword(BSTR *password) +{ + PasswordWasAsked = true; + RINOK(CheckBreak()); + if (!PasswordIsDefined) + { + Password = GetPassword(OutStream); + PasswordIsDefined = true; + } + CMyComBSTR temp(Password); + *password = temp.Detach(); + return S_OK; +} + +HRESULT COpenCallbackConsole::GetPasswordIfAny(UString &password) +{ + if (PasswordIsDefined) + password = Password; + return S_OK; +} + +bool COpenCallbackConsole::WasPasswordAsked() +{ + return PasswordWasAsked; +} + +void COpenCallbackConsole::ClearPasswordWasAskedFlag() +{ + PasswordWasAsked = false; +} + + diff --git a/CPP/7zip/UI/Console/OpenCallbackConsole.h b/CPP/7zip/UI/Console/OpenCallbackConsole.h new file mode 100755 index 00000000..db0e9bd8 --- /dev/null +++ b/CPP/7zip/UI/Console/OpenCallbackConsole.h @@ -0,0 +1,27 @@ +// OpenCallbackConsole.h + +#ifndef __OPENCALLBACKCONSOLE_H +#define __OPENCALLBACKCONSOLE_H + +#include "Common/StdOutStream.h" +#include "../Common/ArchiveOpenCallback.h" + +class COpenCallbackConsole: public IOpenCallbackUI +{ +public: + HRESULT CheckBreak(); + HRESULT SetTotal(const UInt64 *files, const UInt64 *bytes); + HRESULT SetCompleted(const UInt64 *files, const UInt64 *bytes); + HRESULT CryptoGetTextPassword(BSTR *password); + HRESULT GetPasswordIfAny(UString &password); + bool WasPasswordAsked(); + void ClearPasswordWasAskedFlag(); + + CStdOutStream *OutStream; + bool PasswordIsDefined; + UString Password; + bool PasswordWasAsked; + COpenCallbackConsole(): PasswordIsDefined(false), PasswordWasAsked(false) {} +}; + +#endif diff --git a/CPP/7zip/UI/Console/PercentPrinter.cpp b/CPP/7zip/UI/Console/PercentPrinter.cpp new file mode 100755 index 00000000..ec87b5d4 --- /dev/null +++ b/CPP/7zip/UI/Console/PercentPrinter.cpp @@ -0,0 +1,90 @@ +// PercentPrinter.cpp + +#include "StdAfx.h" + +#include "Common/IntToString.h" +#include "Common/String.h" + +#include "PercentPrinter.h" + +const int kPaddingSize = 2; +const int kPercentsSize = 4; +const int kMaxExtraSize = kPaddingSize + 32 + kPercentsSize; + +static void ClearPrev(char *p, int num) +{ + int i; + for (i = 0; i < num; i++) *p++ = '\b'; + for (i = 0; i < num; i++) *p++ = ' '; + for (i = 0; i < num; i++) *p++ = '\b'; + *p = '\0'; +} + +void CPercentPrinter::ClosePrint() +{ + if (m_NumExtraChars == 0) + return; + char s[kMaxExtraSize * 3 + 1]; + ClearPrev(s, m_NumExtraChars); + (*OutStream) << s; + m_NumExtraChars = 0; +} + +void CPercentPrinter::PrintString(const char *s) +{ + ClosePrint(); + (*OutStream) << s; +} + +void CPercentPrinter::PrintString(const wchar_t *s) +{ + ClosePrint(); + (*OutStream) << s; +} + +void CPercentPrinter::PrintNewLine() +{ + ClosePrint(); + (*OutStream) << "\n"; +} + +void CPercentPrinter::RePrintRatio() +{ + char s[32]; + ConvertUInt64ToString(((m_Total == 0) ? 0 : (m_CurValue * 100 / m_Total)), s); + int size = (int)strlen(s); + s[size++] = '%'; + s[size] = '\0'; + + int extraSize = kPaddingSize + MyMax(size, kPercentsSize); + if (extraSize < m_NumExtraChars) + extraSize = m_NumExtraChars; + + char fullString[kMaxExtraSize * 3]; + char *p = fullString; + int i; + if (m_NumExtraChars == 0) + { + for (i = 0; i < extraSize; i++) + *p++ = ' '; + m_NumExtraChars = extraSize; + } + + for (i = 0; i < m_NumExtraChars; i++) + *p++ = '\b'; + m_NumExtraChars = extraSize; + for (; size < m_NumExtraChars; size++) + *p++ = ' '; + strcpy(p, s); + (*OutStream) << fullString; + OutStream->Flush(); + m_PrevValue = m_CurValue; +} + +void CPercentPrinter::PrintRatio() +{ + if (m_CurValue < m_PrevValue + m_MinStepSize && + m_CurValue + m_MinStepSize > m_PrevValue && m_NumExtraChars != 0) + return; + RePrintRatio(); +} diff --git a/CPP/7zip/UI/Console/PercentPrinter.h b/CPP/7zip/UI/Console/PercentPrinter.h new file mode 100755 index 00000000..e8b40916 --- /dev/null +++ b/CPP/7zip/UI/Console/PercentPrinter.h @@ -0,0 +1,31 @@ +// PercentPrinter.h + +#ifndef __PERCENTPRINTER_H +#define __PERCENTPRINTER_H + +#include "Common/Types.h" +#include "Common/StdOutStream.h" + +class CPercentPrinter +{ + UInt64 m_MinStepSize; + UInt64 m_PrevValue; + UInt64 m_CurValue; + UInt64 m_Total; + int m_NumExtraChars; +public: + CStdOutStream *OutStream; + + CPercentPrinter(UInt64 minStepSize = 1): m_MinStepSize(minStepSize), + m_PrevValue(0), m_CurValue(0), m_Total(1), m_NumExtraChars(0) {} + void SetTotal(UInt64 total) { m_Total = total; m_PrevValue = 0; } + void SetRatio(UInt64 doneValue) { m_CurValue = doneValue; } + void PrintString(const char *s); + void PrintString(const wchar_t *s); + void PrintNewLine(); + void ClosePrint(); + void RePrintRatio(); + void PrintRatio(); +}; + +#endif diff --git a/CPP/7zip/UI/Console/StdAfx.cpp b/CPP/7zip/UI/Console/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/UI/Console/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/UI/Console/StdAfx.h b/CPP/7zip/UI/Console/StdAfx.h new file mode 100755 index 00000000..8531cc9c --- /dev/null +++ b/CPP/7zip/UI/Console/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" +#include "../../../Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp b/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp new file mode 100755 index 00000000..5cbc11c0 --- /dev/null +++ b/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp @@ -0,0 +1,196 @@ +// UpdateCallbackConsole.cpp + +#include "StdAfx.h" + +#include "UpdateCallbackConsole.h" + +#include "Windows/Error.h" +#ifdef COMPRESS_MT +#include "Windows/Synchronization.h" +#endif + +#include "ConsoleClose.h" +#include "UserInputUtils.h" + +using namespace NWindows; + +#ifdef COMPRESS_MT +static NSynchronization::CCriticalSection g_CriticalSection; +#define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection); +#else +#define MT_LOCK +#endif + +static const wchar_t *kEmptyFileAlias = L"[Content]"; + +static const char *kCreatingArchiveMessage = "Creating archive "; +static const char *kUpdatingArchiveMessage = "Updating archive "; +static const char *kScanningMessage = "Scanning"; +static const char *kNoFilesScannedMessage = "No files scanned"; +static const char *kTotalFilesAddedMessage = "Total files added to archive: "; + + +HRESULT CUpdateCallbackConsole::OpenResult(const wchar_t *name, HRESULT result) +{ + (*OutStream) << endl; + if (result != S_OK) + (*OutStream) << "Error: " << name << " is not supported archive" << endl; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::StartScanning() +{ + (*OutStream) << kScanningMessage; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::CanNotFindError(const wchar_t *name, DWORD systemError) +{ + CantFindFiles.Add(name); + CantFindCodes.Add(systemError); + // m_PercentPrinter.ClosePrint(); + if (!m_WarningsMode) + { + (*OutStream) << endl << endl; + m_PercentPrinter.PrintNewLine(); + m_WarningsMode = true; + } + m_PercentPrinter.PrintString(name); + m_PercentPrinter.PrintString(": WARNING: "); + m_PercentPrinter.PrintString(NError::MyFormatMessageW(systemError)); + m_PercentPrinter.PrintNewLine(); + return S_OK; +} + +HRESULT CUpdateCallbackConsole::FinishScanning() +{ + (*OutStream) << endl << endl; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::StartArchive(const wchar_t *name, bool updating) +{ + if(updating) + (*OutStream) << kUpdatingArchiveMessage; + else + (*OutStream) << kCreatingArchiveMessage; + if (name != 0) + (*OutStream) << name; + else + (*OutStream) << "StdOut"; + (*OutStream) << endl << endl; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::FinishArchive() +{ + (*OutStream) << endl; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::CheckBreak() +{ + if (NConsoleClose::TestBreakSignal()) + return E_ABORT; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::Finilize() +{ + MT_LOCK + if (m_NeedBeClosed) + { + if (EnablePercents) + { + m_PercentPrinter.ClosePrint(); + } + if (!StdOutMode && m_NeedNewLine) + { + m_PercentPrinter.PrintNewLine(); + m_NeedNewLine = false; + } + m_NeedBeClosed = false; + } + return S_OK; +} + +HRESULT CUpdateCallbackConsole::SetTotal(UInt64 size) +{ + MT_LOCK + if (EnablePercents) + m_PercentPrinter.SetTotal(size); + return S_OK; +} + +HRESULT CUpdateCallbackConsole::SetCompleted(const UInt64 *completeValue) +{ + MT_LOCK + if (completeValue != NULL) + { + if (EnablePercents) + { + m_PercentPrinter.SetRatio(*completeValue); + m_PercentPrinter.PrintRatio(); + m_NeedBeClosed = true; + } + } + if (NConsoleClose::TestBreakSignal()) + return E_ABORT; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool isAnti) +{ + MT_LOCK + if (StdOutMode) + return S_OK; + if(isAnti) + m_PercentPrinter.PrintString("Anti item "); + else + m_PercentPrinter.PrintString("Compressing "); + if (name[0] == 0) + name = kEmptyFileAlias; + m_PercentPrinter.PrintString(name); + if (EnablePercents) + m_PercentPrinter.RePrintRatio(); + return S_OK; +} + +HRESULT CUpdateCallbackConsole::OpenFileError(const wchar_t *name, DWORD systemError) +{ + MT_LOCK + FailedCodes.Add(systemError); + FailedFiles.Add(name); + // if (systemError == ERROR_SHARING_VIOLATION) + { + m_PercentPrinter.ClosePrint(); + m_PercentPrinter.PrintNewLine(); + m_PercentPrinter.PrintString("WARNING: "); + m_PercentPrinter.PrintString(NError::MyFormatMessageW(systemError)); + return S_FALSE; + } + // return systemError; +} + +HRESULT CUpdateCallbackConsole::SetOperationResult(Int32 ) +{ + m_NeedBeClosed = true; + m_NeedNewLine = true; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) +{ + if (!PasswordIsDefined) + { + if (AskPassword) + { + Password = GetPassword(OutStream); + PasswordIsDefined = true; + } + } + *passwordIsDefined = BoolToInt(PasswordIsDefined); + CMyComBSTR tempName(Password); + *password = tempName.Detach(); + return S_OK; +} diff --git a/CPP/7zip/UI/Console/UpdateCallbackConsole.h b/CPP/7zip/UI/Console/UpdateCallbackConsole.h new file mode 100755 index 00000000..2fcb891b --- /dev/null +++ b/CPP/7zip/UI/Console/UpdateCallbackConsole.h @@ -0,0 +1,75 @@ +// UpdateCallbackConsole.h + +#ifndef __UPDATECALLBACKCONSOLE_H +#define __UPDATECALLBACKCONSOLE_H + +#include "Common/String.h" +#include "Common/StdOutStream.h" +#include "PercentPrinter.h" +#include "../Common/Update.h" + +class CUpdateCallbackConsole: public IUpdateCallbackUI2 +{ + CPercentPrinter m_PercentPrinter; + bool m_NeedBeClosed; + bool m_NeedNewLine; + + bool m_WarningsMode; + + CStdOutStream *OutStream; +public: + bool EnablePercents; + bool StdOutMode; + + bool PasswordIsDefined; + UString Password; + bool AskPassword; + + + CUpdateCallbackConsole(): + m_PercentPrinter(1 << 16), + PasswordIsDefined(false), + AskPassword(false), + StdOutMode(false), + EnablePercents(true), + m_WarningsMode(false) + {} + + ~CUpdateCallbackConsole() { Finilize(); } + void Init(CStdOutStream *outStream) + { + m_NeedBeClosed = false; + m_NeedNewLine = false; + FailedFiles.Clear(); + FailedCodes.Clear(); + OutStream = outStream; + m_PercentPrinter.OutStream = outStream; + } + + HRESULT OpenResult(const wchar_t *name, HRESULT result); + + HRESULT StartScanning(); + HRESULT CanNotFindError(const wchar_t *name, DWORD systemError); + HRESULT FinishScanning(); + + HRESULT StartArchive(const wchar_t *name, bool updating); + HRESULT FinishArchive(); + + HRESULT CheckBreak(); + HRESULT Finilize(); + HRESULT SetTotal(UInt64 size); + HRESULT SetCompleted(const UInt64 *completeValue); + + HRESULT GetStream(const wchar_t *name, bool isAnti); + HRESULT OpenFileError(const wchar_t *name, DWORD systemError); + HRESULT SetOperationResult(Int32 operationResult); + HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password); + + UStringVector FailedFiles; + CRecordVector FailedCodes; + + UStringVector CantFindFiles; + CRecordVector CantFindCodes; +}; + +#endif diff --git a/CPP/7zip/UI/Console/UserInputUtils.cpp b/CPP/7zip/UI/Console/UserInputUtils.cpp new file mode 100755 index 00000000..164af99c --- /dev/null +++ b/CPP/7zip/UI/Console/UserInputUtils.cpp @@ -0,0 +1,58 @@ +// UserInputUtils.cpp + +#include "StdAfx.h" + +#include "Common/StdInStream.h" +#include "Common/StringConvert.h" + +#include "UserInputUtils.h" + +static const char kYes = 'Y'; +static const char kNo = 'N'; +static const char kYesAll = 'A'; +static const char kNoAll = 'S'; +static const char kAutoRename = 'U'; +static const char kQuit = 'Q'; + +static const char *kFirstQuestionMessage = "?\n"; +static const char *kHelpQuestionMessage = + "(Y)es / (N)o / (A)lways / (S)kip all / A(u)to rename / (Q)uit? "; + +// return true if pressed Quite; +// in: anAll +// out: anAll, anYes; + +NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream) +{ + (*outStream) << kFirstQuestionMessage; + for(;;) + { + (*outStream) << kHelpQuestionMessage; + AString scannedString = g_StdIn.ScanStringUntilNewLine(); + scannedString.Trim(); + if(!scannedString.IsEmpty()) + switch(::MyCharUpper(scannedString[0])) + { + case kYes: + return NUserAnswerMode::kYes; + case kNo: + return NUserAnswerMode::kNo; + case kYesAll: + return NUserAnswerMode::kYesAll; + case kNoAll: + return NUserAnswerMode::kNoAll; + case kAutoRename: + return NUserAnswerMode::kAutoRename; + case kQuit: + return NUserAnswerMode::kQuit; + } + } +} + +UString GetPassword(CStdOutStream *outStream) +{ + (*outStream) << "\nEnter password:"; + outStream->Flush(); + AString oemPassword = g_StdIn.ScanStringUntilNewLine(); + return MultiByteToUnicodeString(oemPassword, CP_OEMCP); +} diff --git a/CPP/7zip/UI/Console/UserInputUtils.h b/CPP/7zip/UI/Console/UserInputUtils.h new file mode 100755 index 00000000..75c85ee6 --- /dev/null +++ b/CPP/7zip/UI/Console/UserInputUtils.h @@ -0,0 +1,24 @@ +// UserInputUtils.h + +#ifndef __USERINPUTUTILS_H +#define __USERINPUTUTILS_H + +#include "Common/StdOutStream.h" + +namespace NUserAnswerMode { + +enum EEnum +{ + kYes, + kNo, + kYesAll, + kNoAll, + kAutoRename, + kQuit, +}; +} + +NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream); +UString GetPassword(CStdOutStream *outStream); + +#endif diff --git a/CPP/7zip/UI/Console/afxres.h b/CPP/7zip/UI/Console/afxres.h new file mode 100755 index 00000000..c2fadd4a --- /dev/null +++ b/CPP/7zip/UI/Console/afxres.h @@ -0,0 +1 @@ +#include diff --git a/CPP/7zip/UI/Console/makefile b/CPP/7zip/UI/Console/makefile new file mode 100755 index 00000000..54e83ea1 --- /dev/null +++ b/CPP/7zip/UI/Console/makefile @@ -0,0 +1,93 @@ +PROG = 7z.exe +LIBS = $(LIBS) user32.lib oleaut32.lib advapi32.lib +CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_MT -DWIN_LONG_PATH + +CONSOLE_OBJS = \ + $O\ConsoleClose.obj \ + $O\ExtractCallbackConsole.obj \ + $O\List.obj \ + $O\Main.obj \ + $O\MainAr.obj \ + $O\OpenCallbackConsole.obj \ + $O\PercentPrinter.obj \ + $O\UpdateCallbackConsole.obj \ + $O\UserInputUtils.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CommandLineParser.obj \ + $O\IntToString.obj \ + $O\ListFileUtils.obj \ + $O\NewHandler.obj \ + $O\StdInStream.obj \ + $O\StdOutStream.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\UTFConvert.obj \ + $O\Vector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\Error.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\MemoryLock.obj \ + $O\PropVariant.obj \ + $O\PropVariantConversions.obj \ + $O\Registry.obj \ + +7ZIP_COMMON_OBJS = \ + $O\FilePathAutoRename.obj \ + $O\FileStreams.obj \ + $O\StreamUtils.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveCommandLine.obj \ + $O\ArchiveExtractCallback.obj \ + $O\ArchiveOpenCallback.obj \ + $O\ArchiverInfo.obj \ + $O\DefaultName.obj \ + $O\EnumDirItems.obj \ + $O\Extract.obj \ + $O\ExtractingFilePath.obj \ + $O\OpenArchive.obj \ + $O\PropIDUtils.obj \ + $O\SetProperties.obj \ + $O\SortUtils.obj \ + $O\TempFiles.obj \ + $O\Update.obj \ + $O\UpdateAction.obj \ + $O\UpdateCallback.obj \ + $O\UpdatePair.obj \ + $O\UpdateProduce.obj \ + $O\WorkDir.obj \ + + +OBJS = \ + $O\StdAfx.obj \ + $(CONSOLE_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(UI_COMMON_OBJS) \ + $O\CopyCoder.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(CONSOLE_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(UI_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/UI/Console/resource.rc b/CPP/7zip/UI/Console/resource.rc new file mode 100755 index 00000000..6e09bb96 --- /dev/null +++ b/CPP/7zip/UI/Console/resource.rc @@ -0,0 +1,3 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_APP("7-Zip Console", "7z") diff --git a/CPP/7zip/UI/Explorer/7-zip.dll.manifest b/CPP/7zip/UI/Explorer/7-zip.dll.manifest new file mode 100755 index 00000000..cba1c5df --- /dev/null +++ b/CPP/7zip/UI/Explorer/7-zip.dll.manifest @@ -0,0 +1 @@ +7-Zip Extension. diff --git a/CPP/7zip/UI/Explorer/ContextMenu.cpp b/CPP/7zip/UI/Explorer/ContextMenu.cpp new file mode 100755 index 00000000..fd40add5 --- /dev/null +++ b/CPP/7zip/UI/Explorer/ContextMenu.cpp @@ -0,0 +1,682 @@ +// ContextMenu.cpp + +#include "StdAfx.h" + +#include "ContextMenu.h" + +#include "Common/StringConvert.h" +#include "Common/MyCom.h" + +#include "Windows/Shell.h" +#include "Windows/Memory.h" +#include "Windows/COM.h" +#include "Windows/FileFind.h" +#include "Windows/FileDir.h" +#include "Windows/FileName.h" +#include "Windows/Thread.h" +#include "Windows/Window.h" + +#include "Windows/Menu.h" +#include "Windows/ResourceString.h" + +#include "../../FileManager/FormatUtils.h" +#include "../../FileManager/ProgramLocation.h" + +#include "../Common/ZipRegistry.h" +#include "../Common/ArchiveName.h" + +#ifdef LANG +#include "../../FileManager/LangUtils.h" +#endif + +#include "resource.h" +#include "ContextMenuFlags.h" + +// #include "ExtractEngine.h" +// #include "TestEngine.h" +// #include "CompressEngine.h" +#include "MyMessages.h" + +#include "../Resource/Extract/resource.h" +#include "../Common/CompressCall.h" + +using namespace NWindows; + +static LPCTSTR kFileClassIDString = TEXT("SevenZip"); + +/////////////////////////////// +// IShellExtInit + +extern LONG g_DllRefCount; + +CZipContextMenu::CZipContextMenu() { InterlockedIncrement(&g_DllRefCount); } +CZipContextMenu::~CZipContextMenu() { InterlockedDecrement(&g_DllRefCount); } + +HRESULT CZipContextMenu::GetFileNames(LPDATAOBJECT dataObject, UStringVector &fileNames) +{ + fileNames.Clear(); + if(dataObject == NULL) + return E_FAIL; + FORMATETC fmte = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + NCOM::CStgMedium stgMedium; + HRESULT result = dataObject->GetData(&fmte, &stgMedium); + if (result != S_OK) + return result; + stgMedium._mustBeReleased = true; + + NShell::CDrop drop(false); + NMemory::CGlobalLock globalLock(stgMedium->hGlobal); + drop.Attach((HDROP)globalLock.GetPointer()); + drop.QueryFileNames(fileNames); + + return S_OK; +} + +STDMETHODIMP CZipContextMenu::Initialize(LPCITEMIDLIST pidlFolder, + LPDATAOBJECT dataObject, HKEY /* hkeyProgID */) +{ + // OutputDebugString(TEXT("::Initialize\r\n")); + _dropMode = false; + _dropPath.Empty(); + if (pidlFolder != 0) + { + if (NShell::GetPathFromIDList(pidlFolder, _dropPath)) + { + // OutputDebugString(path); + // OutputDebugString(TEXT("\r\n")); + NFile::NName::NormalizeDirPathPrefix(_dropPath); + _dropMode = !_dropPath.IsEmpty(); + } + else + _dropPath.Empty(); + } + + /* + m_IsFolder = false; + if (pidlFolder == 0) + */ + // pidlFolder is NULL :( + return GetFileNames(dataObject, _fileNames); +} + +STDMETHODIMP CZipContextMenu::InitContextMenu(const wchar_t * /* folder */, + const wchar_t **names, UINT32 numFiles) +{ + _fileNames.Clear(); + for (UINT32 i = 0; i < numFiles; i++) + _fileNames.Add(names[i]); + _dropMode = false; + return S_OK; +} + + +///////////////////////////// +// IContextMenu + +static LPCWSTR kMainVerb = L"SevenZip"; + +/* +static LPCTSTR kOpenVerb = TEXT("SevenOpen"); +static LPCTSTR kExtractVerb = TEXT("SevenExtract"); +static LPCTSTR kExtractHereVerb = TEXT("SevenExtractHere"); +static LPCTSTR kExtractToVerb = TEXT("SevenExtractTo"); +static LPCTSTR kTestVerb = TEXT("SevenTest"); +static LPCTSTR kCompressVerb = TEXT("SevenCompress"); +static LPCTSTR kCompressToVerb = TEXT("SevenCompressTo"); +static LPCTSTR kCompressEmailVerb = TEXT("SevenCompressEmail"); +static LPCTSTR kCompressToEmailVerb = TEXT("SevenCompressToEmail"); +*/ + +struct CContextMenuCommand +{ + UINT32 flag; + CZipContextMenu::ECommandInternalID CommandInternalID; + LPCWSTR Verb; + UINT ResourceID; + UINT ResourceHelpID; + UINT32 LangID; +}; + +static CContextMenuCommand g_Commands[] = +{ + { + NContextMenuFlags::kOpen, + CZipContextMenu::kOpen, + L"Open", + IDS_CONTEXT_OPEN, + IDS_CONTEXT_OPEN_HELP, + 0x02000103 + }, + { + NContextMenuFlags::kExtract, + CZipContextMenu::kExtract, + L"Extract", + IDS_CONTEXT_EXTRACT, + IDS_CONTEXT_EXTRACT_HELP, + 0x02000105 + }, + { + NContextMenuFlags::kExtractHere, + CZipContextMenu::kExtractHere, + L"ExtractHere", + IDS_CONTEXT_EXTRACT_HERE, + IDS_CONTEXT_EXTRACT_HERE_HELP, + 0x0200010B + }, + { + NContextMenuFlags::kExtractTo, + CZipContextMenu::kExtractTo, + L"ExtractTo", + IDS_CONTEXT_EXTRACT_TO, + IDS_CONTEXT_EXTRACT_TO_HELP, + 0x0200010D + }, + { + NContextMenuFlags::kTest, + CZipContextMenu::kTest, + L"Test", + IDS_CONTEXT_TEST, + IDS_CONTEXT_TEST_HELP, + 0x02000109 + }, + { + NContextMenuFlags::kCompress, + CZipContextMenu::kCompress, + L"Compress", + IDS_CONTEXT_COMPRESS, + IDS_CONTEXT_COMPRESS_HELP, + 0x02000107, + }, + { + NContextMenuFlags::kCompressEmail, + CZipContextMenu::kCompressEmail, + L"CompressEmail", + IDS_CONTEXT_COMPRESS_EMAIL, + IDS_CONTEXT_COMPRESS_EMAIL_HELP, + 0x02000111 + }, + { + NContextMenuFlags::kCompressTo7z, + CZipContextMenu::kCompressTo7z, + L"CompressTo7z", + IDS_CONTEXT_COMPRESS_TO, + IDS_CONTEXT_COMPRESS_TO_HELP, + 0x0200010F + }, + { + NContextMenuFlags::kCompressTo7zEmail, + CZipContextMenu::kCompressTo7zEmail, + L"CompressTo7zEmail", + IDS_CONTEXT_COMPRESS_TO_EMAIL, + IDS_CONTEXT_COMPRESS_TO_EMAIL_HELP, + 0x02000113 + }, + { + NContextMenuFlags::kCompressToZip, + CZipContextMenu::kCompressToZip, + L"CompressToZip", + IDS_CONTEXT_COMPRESS_TO, + IDS_CONTEXT_COMPRESS_TO_HELP, + 0x0200010F + }, + { + NContextMenuFlags::kCompressToZipEmail, + CZipContextMenu::kCompressToZipEmail, + L"CompressToZipEmail", + IDS_CONTEXT_COMPRESS_TO_EMAIL, + IDS_CONTEXT_COMPRESS_TO_EMAIL_HELP, + 0x02000113 + } +}; + +int FindCommand(CZipContextMenu::ECommandInternalID &id) +{ + for (int i = 0; i < sizeof(g_Commands) / sizeof(g_Commands[0]); i++) + if (g_Commands[i].CommandInternalID == id) + return i; + return -1; +} + +void CZipContextMenu::FillCommand(ECommandInternalID id, + UString &mainString, CCommandMapItem &commandMapItem) +{ + int i = FindCommand(id); + if (i < 0) + return; + const CContextMenuCommand &command = g_Commands[i]; + commandMapItem.CommandInternalID = command.CommandInternalID; + commandMapItem.Verb = (UString)kMainVerb + (UString)command.Verb; + commandMapItem.HelpString = LangString(command.ResourceHelpID, command.LangID + 1); + mainString = LangString(command.ResourceID, command.LangID); +} + +static bool MyInsertMenu(CMenu &menu, int pos, UINT id, const UString &s) +{ + CMenuItem menuItem; + menuItem.fType = MFT_STRING; + menuItem.fMask = MIIM_TYPE | MIIM_ID; + menuItem.wID = id; + menuItem.StringValue = s; + return menu.InsertItem(pos, true, menuItem); +} + +static UString GetSubFolderNameForExtract(const UString &archiveName) +{ + int dotPos = archiveName.ReverseFind(L'.'); + if (dotPos < 0) + return archiveName + UString(L"~"); + UString res = archiveName.Left(dotPos); + res.TrimRight(); + return res; +} + +static UString GetReducedString(const UString &s) +{ + const int kMaxSize = 64; + if (s.Length() < kMaxSize) + return s; + const int kFirstPartSize = kMaxSize / 2; + return s.Left(kFirstPartSize) + UString(L" ... ") + s.Right(kMaxSize - kFirstPartSize); +} + +STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, + UINT commandIDFirst, UINT commandIDLast, UINT flags) +{ + LoadLangOneTime(); + if(_fileNames.Size() == 0) + return E_FAIL; + UINT currentCommandID = commandIDFirst; + if ((flags & 0x000F) != CMF_NORMAL && + (flags & CMF_VERBSONLY) == 0 && + (flags & CMF_EXPLORE) == 0) + return MAKE_HRESULT(SEVERITY_SUCCESS, 0, currentCommandID); + + _commandMap.Clear(); + + CMenu popupMenu; + CMenuDestroyer menuDestroyer; + + bool cascadedMenu = ReadCascadedMenu(); + MENUITEMINFO menuItem; + UINT subIndex = indexMenu; + if (cascadedMenu) + { + CCommandMapItem commandMapItem; + if(!popupMenu.CreatePopup()) + throw 210503; + menuDestroyer.Attach(popupMenu); + commandMapItem.CommandInternalID = kCommandNULL; + commandMapItem.Verb = kMainVerb; + commandMapItem.HelpString = LangString(IDS_CONTEXT_CAPTION_HELP, 0x02000102); + _commandMap.Add(commandMapItem); + + menuItem.wID = currentCommandID++; + subIndex = 0; + } + else + { + popupMenu.Attach(hMenu); + } + + UINT32 contextMenuFlags; + if (!ReadContextMenuStatus(contextMenuFlags)) + contextMenuFlags = NContextMenuFlags::GetDefaultFlags(); + + UString mainString; + if(_fileNames.Size() == 1 && currentCommandID + 6 <= commandIDLast) + { + const UString &fileName = _fileNames.Front(); + UString folderPrefix; + NFile::NDirectory::GetOnlyDirPrefix(fileName, folderPrefix); + + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(fileName, fileInfo)) + return E_FAIL; + if (!fileInfo.IsDirectory()) + { + // Open + if ((contextMenuFlags & NContextMenuFlags::kOpen) != 0) + { + CCommandMapItem commandMapItem; + FillCommand(kOpen, mainString, commandMapItem); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString); + _commandMap.Add(commandMapItem); + } + } + } + + if(_fileNames.Size() > 0 && currentCommandID + 10 <= commandIDLast) + { + bool thereAreFolders = false; + for(int i = 0; i < _fileNames.Size(); i++) + { + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(_fileNames[i], fileInfo)) + return E_FAIL; + if (fileInfo.IsDirectory()) + thereAreFolders = true; + } + const UString &fileName = _fileNames.Front(); + if (!thereAreFolders) + { + UString folderPrefix; + NFile::NDirectory::GetOnlyDirPrefix(fileName, folderPrefix); + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(fileName, fileInfo)) + return E_FAIL; + // Extract + if ((contextMenuFlags & NContextMenuFlags::kExtract) != 0) + { + CCommandMapItem commandMapItem; + FillCommand(kExtract, mainString, commandMapItem); + if (_dropMode) + commandMapItem.Folder = _dropPath; + else + commandMapItem.Folder = folderPrefix; + commandMapItem.Folder += GetSubFolderNameForExtract(fileInfo.Name) + UString(L'\\'); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString); + _commandMap.Add(commandMapItem); + } + + // Extract Here + if ((contextMenuFlags & NContextMenuFlags::kExtractHere) != 0) + { + CCommandMapItem commandMapItem; + FillCommand(kExtractHere, mainString, commandMapItem); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString); + if (_dropMode) + commandMapItem.Folder = _dropPath; + else + commandMapItem.Folder = folderPrefix; + _commandMap.Add(commandMapItem); + } + + // Extract To + if ((contextMenuFlags & NContextMenuFlags::kExtractTo) != 0) + { + CCommandMapItem commandMapItem; + UString s; + FillCommand(kExtractTo, s, commandMapItem); + UString folder; + if (_fileNames.Size() == 1) + folder = GetSubFolderNameForExtract(fileInfo.Name); + else + folder = L'*'; + if (_dropMode) + commandMapItem.Folder = _dropPath; + else + commandMapItem.Folder = folderPrefix; + commandMapItem.Folder += folder; + s = MyFormatNew(s, GetReducedString(UString(L"\"") + folder + UString(L"\\\""))); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s); + _commandMap.Add(commandMapItem); + } + // Test + if ((contextMenuFlags & NContextMenuFlags::kTest) != 0) + { + CCommandMapItem commandMapItem; + FillCommand(kTest, mainString, commandMapItem); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString); + _commandMap.Add(commandMapItem); + } + } + UString archiveName = CreateArchiveName(fileName, _fileNames.Size() > 1, false); + UString archiveName7z = archiveName + L".7z"; + UString archiveNameZip = archiveName + L".zip"; + UString archivePathPrefix; + NFile::NDirectory::GetOnlyDirPrefix(fileName, archivePathPrefix); + + // Compress + if ((contextMenuFlags & NContextMenuFlags::kCompress) != 0) + { + CCommandMapItem commandMapItem; + if (_dropMode) + commandMapItem.Folder = _dropPath; + else + commandMapItem.Folder = archivePathPrefix; + commandMapItem.Archive = archiveName; + FillCommand(kCompress, mainString, commandMapItem); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString); + _commandMap.Add(commandMapItem); + } + + + // CompressEmail + if ((contextMenuFlags & NContextMenuFlags::kCompressEmail) != 0 && !_dropMode) + { + CCommandMapItem commandMapItem; + commandMapItem.Archive = archiveName; + FillCommand(kCompressEmail, mainString, commandMapItem); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString); + _commandMap.Add(commandMapItem); + } + + // CompressTo7z + if (contextMenuFlags & NContextMenuFlags::kCompressTo7z) + { + CCommandMapItem commandMapItem; + UString s; + FillCommand(kCompressTo7z, s, commandMapItem); + if (_dropMode) + commandMapItem.Folder = _dropPath; + else + commandMapItem.Folder = archivePathPrefix; + commandMapItem.Archive = archiveName7z; + commandMapItem.ArchiveType = L"7z"; + UString t = UString(L"\"") + GetReducedString(archiveName7z) + UString(L"\""); + s = MyFormatNew(s, t); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s); + _commandMap.Add(commandMapItem); + } + + // CompressTo7zEmail + if ((contextMenuFlags & NContextMenuFlags::kCompressTo7zEmail) != 0 && !_dropMode) + { + CCommandMapItem commandMapItem; + UString s; + FillCommand(kCompressTo7zEmail, s, commandMapItem); + commandMapItem.Archive = archiveName7z; + commandMapItem.ArchiveType = L"7z"; + UString t = UString(L"\"") + GetReducedString(archiveName7z) + UString(L"\""); + s = MyFormatNew(s, t); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s); + _commandMap.Add(commandMapItem); + } + + // CompressToZip + if (contextMenuFlags & NContextMenuFlags::kCompressToZip) + { + CCommandMapItem commandMapItem; + UString s; + FillCommand(kCompressToZip, s, commandMapItem); + if (_dropMode) + commandMapItem.Folder = _dropPath; + else + commandMapItem.Folder = archivePathPrefix; + commandMapItem.Archive = archiveNameZip; + commandMapItem.ArchiveType = L"zip"; + UString t = UString(L"\"") + GetReducedString(archiveNameZip) + UString(L"\""); + s = MyFormatNew(s, t); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s); + _commandMap.Add(commandMapItem); + } + + // CompressToZipEmail + if ((contextMenuFlags & NContextMenuFlags::kCompressToZipEmail) != 0 && !_dropMode) + { + CCommandMapItem commandMapItem; + UString s; + FillCommand(kCompressToZipEmail, s, commandMapItem); + commandMapItem.Archive = archiveNameZip; + commandMapItem.ArchiveType = L"zip"; + UString t = UString(L"\"") + GetReducedString(archiveNameZip) + UString(L"\""); + s = MyFormatNew(s, t); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s); + _commandMap.Add(commandMapItem); + } + } + + + // don't use InsertMenu: See MSDN: + // PRB: Duplicate Menu Items In the File Menu For a Shell Context Menu Extension + // ID: Q214477 + + if (cascadedMenu) + { + CMenuItem menuItem; + menuItem.fType = MFT_STRING; + menuItem.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID; + menuItem.wID = currentCommandID++; + menuItem.hSubMenu = popupMenu.Detach(); + menuDestroyer.Disable(); + menuItem.StringValue = LangString(IDS_CONTEXT_POPUP_CAPTION, 0x02000101); + CMenu menu; + menu.Attach(hMenu); + menu.InsertItem(indexMenu++, true, menuItem); + } + + return MAKE_HRESULT(SEVERITY_SUCCESS, 0, currentCommandID - commandIDFirst); +} + + +int CZipContextMenu::FindVerb(const UString &verb) +{ + for(int i = 0; i < _commandMap.Size(); i++) + if(_commandMap[i].Verb.Compare(verb) == 0) + return i; + return -1; +} + +extern const char *kShellFolderClassIDString; + + +static UString GetProgramCommand() +{ + UString path = L"\""; + UString folder; + if (GetProgramFolderPath(folder)) + path += folder; + path += L"7zFM.exe\""; + return path; +} + +STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo) +{ + // ::OutputDebugStringA("1"); + int commandOffset; + + // It's fix for bug: crashing in XP. See example in MSDN: "Creating Context Menu Handlers". + + if (commandInfo->cbSize == sizeof(CMINVOKECOMMANDINFOEX) && + (commandInfo->fMask & CMIC_MASK_UNICODE) != 0) + { + LPCMINVOKECOMMANDINFOEX commandInfoEx = (LPCMINVOKECOMMANDINFOEX)commandInfo; + if(HIWORD(commandInfoEx->lpVerbW) == 0) + commandOffset = LOWORD(commandInfo->lpVerb); + else + commandOffset = FindVerb(commandInfoEx->lpVerbW); + } + else + if(HIWORD(commandInfo->lpVerb) == 0) + commandOffset = LOWORD(commandInfo->lpVerb); + else + commandOffset = FindVerb(GetUnicodeString(commandInfo->lpVerb)); + + if(commandOffset < 0 || commandOffset >= _commandMap.Size()) + return E_FAIL; + + const CCommandMapItem commandMapItem = _commandMap[commandOffset]; + ECommandInternalID commandInternalID = commandMapItem.CommandInternalID; + + try + { + switch(commandInternalID) + { + case kOpen: + { + UString params; + params = GetProgramCommand(); + params += L" \""; + params += _fileNames[0]; + params += L"\""; + MyCreateProcess(params, 0, false, 0); + break; + } + case kExtract: + case kExtractHere: + case kExtractTo: + { + ExtractArchives(_fileNames, commandMapItem.Folder, + (commandInternalID == kExtract)); + break; + } + case kTest: + { + TestArchives(_fileNames); + break; + } + case kCompress: + case kCompressEmail: + case kCompressTo7z: + case kCompressTo7zEmail: + case kCompressToZip: + case kCompressToZipEmail: + { + bool email = + (commandInternalID == kCompressEmail) || + (commandInternalID == kCompressTo7zEmail) || + (commandInternalID == kCompressToZipEmail); + bool showDialog = + (commandInternalID == kCompress) || + (commandInternalID == kCompressEmail); + CompressFiles(commandMapItem.Folder, + commandMapItem.Archive, commandMapItem.ArchiveType, + _fileNames, email, showDialog, false); + break; + } + } + } + catch(...) + { + MyMessageBox(IDS_ERROR, 0x02000605); + } + return S_OK; +} + +static void MyCopyString(void *dest, const wchar_t *src, bool writeInUnicode) +{ + if(writeInUnicode) + { + MyStringCopy((wchar_t *)dest, src); + } + else + lstrcpyA((char *)dest, GetAnsiString(src)); +} + +STDMETHODIMP CZipContextMenu::GetCommandString(UINT_PTR commandOffset, UINT uType, + UINT * /* pwReserved */ , LPSTR pszName, UINT /* cchMax */) +{ + int cmdOffset = (int)commandOffset; + switch(uType) + { + case GCS_VALIDATEA: + case GCS_VALIDATEW: + if(cmdOffset < 0 || cmdOffset >= _commandMap.Size()) + return S_FALSE; + else + return S_OK; + } + if(cmdOffset < 0 || cmdOffset >= _commandMap.Size()) + return E_FAIL; + if(uType == GCS_HELPTEXTA || uType == GCS_HELPTEXTW) + { + MyCopyString(pszName, _commandMap[cmdOffset].HelpString, uType == GCS_HELPTEXTW); + return NO_ERROR; + } + if(uType == GCS_VERBA || uType == GCS_VERBW) + { + MyCopyString(pszName, _commandMap[cmdOffset].Verb, uType == GCS_VERBW); + return NO_ERROR; + } + return E_FAIL; +} diff --git a/CPP/7zip/UI/Explorer/ContextMenu.h b/CPP/7zip/UI/Explorer/ContextMenu.h new file mode 100755 index 00000000..60970a22 --- /dev/null +++ b/CPP/7zip/UI/Explorer/ContextMenu.h @@ -0,0 +1,86 @@ +// ContextMenu.h + +#ifndef __CONTEXTMENU_H +#define __CONTEXTMENU_H + +// {23170F69-40C1-278A-1000-000100020000} +DEFINE_GUID(CLSID_CZipContextMenu, +0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00); + +#include "Common/String.h" + +#include "../../FileManager/PluginInterface.h" +#include "../../FileManager/MyCom2.h" + + +class CZipContextMenu: + public IContextMenu, + public IShellExtInit, + public IInitContextMenu, + public CMyUnknownImp +{ + +public: + + enum ECommandInternalID + { + kCommandNULL, + kOpen, + kExtract, + kExtractHere, + kExtractTo, + kTest, + kCompress, + kCompressEmail, + kCompressTo7z, + kCompressTo7zEmail, + kCompressToZip, + kCompressToZipEmail + }; + + struct CCommandMapItem + { + ECommandInternalID CommandInternalID; + UString Verb; + UString HelpString; + UString Folder; + UString Archive; + UString ArchiveType; + }; + + MY_UNKNOWN_IMP3_MT(IContextMenu, IShellExtInit, IInitContextMenu) + + /////////////////////////////// + // IShellExtInit + + STDMETHOD(Initialize)(LPCITEMIDLIST pidlFolder, + LPDATAOBJECT dataObject, HKEY hkeyProgID); + + ///////////////////////////// + // IContextMenu + + STDMETHOD(QueryContextMenu)(HMENU hmenu, UINT indexMenu, + UINT idCmdFirst, UINT idCmdLast, UINT uFlags); + STDMETHOD(InvokeCommand)(LPCMINVOKECOMMANDINFO lpici); + STDMETHOD(GetCommandString)(UINT_PTR idCmd, UINT uType, UINT *pwReserved, + LPSTR pszName, UINT cchMax); + + + // IInitContextMenu + STDMETHOD(InitContextMenu)(const wchar_t *folder, const wchar_t **names, UINT32 numFiles); +private: + UStringVector _fileNames; + bool _dropMode; + UString _dropPath; + CObjectVector _commandMap; + HRESULT GetFileNames(LPDATAOBJECT dataObject, UStringVector &fileNames); + int FindVerb(const UString &verb); + + void FillCommand(ECommandInternalID id, UString &mainString, + CCommandMapItem &commandMapItem); +public: + CZipContextMenu(); + ~CZipContextMenu(); +}; + +#endif diff --git a/CPP/7zip/UI/Explorer/ContextMenuFlags.h b/CPP/7zip/UI/Explorer/ContextMenuFlags.h new file mode 100755 index 00000000..d138baf9 --- /dev/null +++ b/CPP/7zip/UI/Explorer/ContextMenuFlags.h @@ -0,0 +1,34 @@ +// ContextMenuFlags.h + +#ifndef __SEVENZIP_CONTEXTMENUFLAGS_H +#define __SEVENZIP_CONTEXTMENUFLAGS_H + +namespace NContextMenuFlags +{ + const UINT32 kExtract = 1 << 0; + const UINT32 kExtractHere = 1 << 1; + const UINT32 kExtractTo = 1 << 2; + // const UINT32 kExtractEach = 1 << 3; + + const UINT32 kTest = 1 << 4; + + const UINT32 kOpen = 1 << 5; + + const UINT32 kCompress = 1 << 8; + const UINT32 kCompressTo7z = 1 << 9; + const UINT32 kCompressEmail = 1 << 10; + const UINT32 kCompressTo7zEmail = 1 << 11; + + const UINT32 kCompressToZip = 1 << 12; + const UINT32 kCompressToZipEmail = 1 << 13; + + inline UINT32 GetDefaultFlags() { + return + kOpen | kTest | + kExtract | kExtractHere | kExtractTo | + kCompress | kCompressEmail | + kCompressTo7z | kCompressTo7zEmail | + kCompressToZip | kCompressToZipEmail; } +} + +#endif diff --git a/CPP/7zip/UI/Explorer/DllExports.cpp b/CPP/7zip/UI/Explorer/DllExports.cpp new file mode 100755 index 00000000..fb7daf04 --- /dev/null +++ b/CPP/7zip/UI/Explorer/DllExports.cpp @@ -0,0 +1,315 @@ +// DLLExports.cpp +// +// Notes: +// Win2000: +// If I register at HKCR\Folder\ShellEx then DLL is locked. +// otherwise it unloads after explorer closing. +// but if I call menu for desktop items it's locked all the time + +#include "StdAfx.h" + +// #include + +#include +#include +#include +#include + +#include "Common/ComTry.h" +#include "Common/StringConvert.h" +#include "Windows/DLL.h" +#include "Windows/Registry.h" + +#include "../../IPassword.h" +#include "../../FileManager/LangUtils.h" +#include "../Agent/Agent.h" + +#include "ContextMenu.h" +#include "OptionsDialog.h" + +using namespace NWindows; + +HINSTANCE g_hInstance; +#ifndef _UNICODE +bool g_IsNT = false; +#endif + +LONG g_DllRefCount = 0; // Reference count of this DLL. + +static LPCWSTR kShellExtName = L"7-Zip Shell Extension"; +static LPCTSTR kClsidMask = TEXT("CLSID\\%s"); +static LPCTSTR kClsidInprocMask = TEXT("CLSID\\%s\\InprocServer32"); +static LPCTSTR kApprovedKeyPath = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"); + +// #define ODS(sz) OutputDebugString(L#sz) + +class CShellExtClassFactory: + public IClassFactory, + public CMyUnknownImp +{ +public: + CShellExtClassFactory() { InterlockedIncrement(&g_DllRefCount); } + ~CShellExtClassFactory() { InterlockedDecrement(&g_DllRefCount); } + + + MY_UNKNOWN_IMP1_MT(IClassFactory) + + STDMETHODIMP CreateInstance(LPUNKNOWN, REFIID, void**); + STDMETHODIMP LockServer(BOOL); +}; + +STDMETHODIMP CShellExtClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, + REFIID riid, void **ppvObj) +{ + // ODS("CShellExtClassFactory::CreateInstance()\r\n"); + *ppvObj = NULL; + if (pUnkOuter) + return CLASS_E_NOAGGREGATION; + + CZipContextMenu *shellExt; + try + { + shellExt = new CZipContextMenu(); + } + catch(...) { return E_OUTOFMEMORY; } + if (shellExt == NULL) + return E_OUTOFMEMORY; + + HRESULT res = shellExt->QueryInterface(riid, ppvObj); + if (res != S_OK) + delete shellExt; + return res; +} + + +STDMETHODIMP CShellExtClassFactory::LockServer(BOOL /* fLock */) +{ + return S_OK; // Check it +} + +static bool IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); +} + +extern "C" +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID) +{ + // setlocale(LC_COLLATE, ".ACP"); + if (dwReason == DLL_PROCESS_ATTACH) + { + g_hInstance = hInstance; + // ODS("In DLLMain, DLL_PROCESS_ATTACH\r\n"); + #ifdef _UNICODE + if (!IsItWindowsNT()) + return FALSE; + #else + g_IsNT = IsItWindowsNT(); + #endif + } + else if (dwReason == DLL_PROCESS_DETACH) + { + // ODS("In DLLMain, DLL_PROCESS_DETACH\r\n"); + } + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// Used to determine whether the DLL can be unloaded by OLE + +STDAPI DllCanUnloadNow(void) +{ + // ODS("In DLLCanUnloadNow\r\n"); + return (g_DllRefCount == 0 ? S_OK : S_FALSE); +} + +STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) +{ + // ODS("In DllGetClassObject\r\n"); + *ppv = NULL; + if (IsEqualIID(rclsid, CLSID_CZipContextMenu)) + { + CShellExtClassFactory *cf; + try + { + cf = new CShellExtClassFactory; + } + catch(...) { return E_OUTOFMEMORY; } + if (cf == 0) + return E_OUTOFMEMORY; + HRESULT res = cf->QueryInterface(riid, ppv); + if (res != S_OK) + delete cf; + return res; + } + return CLASS_E_CLASSNOTAVAILABLE; + // return _Module.GetClassObject(rclsid, riid, ppv); +} + +static BOOL GetStringFromIID(CLSID clsid, LPTSTR s, int size) +{ + LPWSTR pwsz; + if (StringFromIID(clsid, &pwsz) != S_OK) + return FALSE; + if(!pwsz) + return FALSE; + #ifdef UNICODE + lstrcpyn(s, pwsz, size); + #else + WideCharToMultiByte(CP_ACP, 0, pwsz, -1, s, size, NULL, NULL); + #endif + CoTaskMemFree(pwsz); + s[size - 1] = 0; + return TRUE; +} + +typedef struct +{ + HKEY hRootKey; + LPCTSTR SubKey; + LPCWSTR ValueName; + LPCWSTR Data; +} CRegItem; + +static BOOL RegisterServer(CLSID clsid, LPCWSTR title) +{ + TCHAR clsidString[MAX_PATH]; + if (!GetStringFromIID(clsid, clsidString, MAX_PATH)) + return FALSE; + + UString modulePath; + if (!NDLL::MyGetModuleFileName(g_hInstance, modulePath)) + return FALSE; + + CRegItem clsidEntries[] = + { + HKEY_CLASSES_ROOT, kClsidMask, NULL, title, + HKEY_CLASSES_ROOT, kClsidInprocMask, NULL, modulePath, + HKEY_CLASSES_ROOT, kClsidInprocMask, L"ThreadingModel", L"Apartment", + NULL, NULL, NULL, NULL + }; + + //register the CLSID entries + for(int i = 0; clsidEntries[i].hRootKey; i++) + { + TCHAR subKey[MAX_PATH]; + wsprintf(subKey, clsidEntries[i].SubKey, clsidString); + NRegistry::CKey key; + if (key.Create(clsidEntries[i].hRootKey, subKey, NULL, + REG_OPTION_NON_VOLATILE, KEY_WRITE) != NOERROR) + return FALSE; + key.SetValue(clsidEntries[i].ValueName, clsidEntries[i].Data); + } + + if(IsItWindowsNT()) + { + NRegistry::CKey key; + if (key.Create(HKEY_LOCAL_MACHINE, kApprovedKeyPath, NULL, + REG_OPTION_NON_VOLATILE, KEY_WRITE) == NOERROR) + key.SetValue(GetUnicodeString(clsidString), title); + } + return TRUE; +} + +STDAPI DllRegisterServer(void) +{ + return RegisterServer(CLSID_CZipContextMenu, kShellExtName) ? S_OK: SELFREG_E_CLASS; +} + +static BOOL UnregisterServer(CLSID clsid) +{ + TCHAR clsidString[MAX_PATH]; + if (!GetStringFromIID(clsid, clsidString, MAX_PATH)) + return FALSE; + + TCHAR subKey[MAX_PATH]; + wsprintf(subKey, kClsidInprocMask, clsidString); + RegDeleteKey(HKEY_CLASSES_ROOT, subKey); + + wsprintf (subKey, kClsidMask, clsidString); + RegDeleteKey(HKEY_CLASSES_ROOT, subKey); + + if(IsItWindowsNT()) + { + HKEY hKey; + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, kApprovedKeyPath, 0, KEY_SET_VALUE, &hKey) == NOERROR) + { + RegDeleteValue(hKey, clsidString); + RegCloseKey(hKey); + } + } + return TRUE; +} + +STDAPI DllUnregisterServer(void) +{ + return UnregisterServer(CLSID_CZipContextMenu) ? S_OK: SELFREG_E_CLASS; +} + +STDAPI CreateObject( + const GUID *classID, + const GUID *interfaceID, + void **outObject) +{ + LoadLangOneTime(); + COM_TRY_BEGIN + *outObject = 0; + if (*classID == CLSID_CAgentArchiveHandler) + { + if (*interfaceID == IID_IFolderManager) + { + CMyComPtr manager = new CArchiveFolderManager; + *outObject = manager.Detach(); + return S_OK; + } + return E_NOINTERFACE; + } + if (*classID == CLSID_CSevenZipOptions) + { + if (*interfaceID == IID_IPluginOptions) + { + CMyComPtr options = new CSevenZipOptions; + *outObject = options.Detach(); + return S_OK; + } + return E_NOINTERFACE; + } + return CLASS_E_CLASSNOTAVAILABLE; + COM_TRY_END +} + +STDAPI GetPluginProperty(PROPID propID, PROPVARIANT *value) +{ + ::VariantClear((tagVARIANT *)value); + switch(propID) + { + case NPlugin::kName: + if ((value->bstrVal = ::SysAllocString(L"7-Zip")) != 0) + value->vt = VT_BSTR; + return S_OK; + case NPlugin::kClassID: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CAgentArchiveHandler, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NPlugin::kOptionsClassID: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CSevenZipOptions, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + /* + case NArchive::kType: + propVariant = UINT32(0); + break; + */ + } + return S_OK; +} diff --git a/CPP/7zip/UI/Explorer/Explorer.def b/CPP/7zip/UI/Explorer/Explorer.def new file mode 100755 index 00000000..752fbb7a --- /dev/null +++ b/CPP/7zip/UI/Explorer/Explorer.def @@ -0,0 +1,12 @@ +; 7-zip.def + +LIBRARY "7-zip" + +EXPORTS + DllCanUnloadNow PRIVATE + DllGetClassObject PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE + + CreateObject PRIVATE + GetPluginProperty PRIVATE diff --git a/CPP/7zip/UI/Explorer/Explorer.dsp b/CPP/7zip/UI/Explorer/Explorer.dsp new file mode 100755 index 00000000..c395c6d2 --- /dev/null +++ b/CPP/7zip/UI/Explorer/Explorer.dsp @@ -0,0 +1,818 @@ +# Microsoft Developer Studio Project File - Name="Explorer" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Explorer - Win32 DebugU +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Explorer.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Explorer.mak" CFG="Explorer - Win32 DebugU" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Explorer - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Explorer - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Explorer - Win32 ReleaseU" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Explorer - Win32 DebugU" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Explorer - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "LANG" /D "NEW_FOLDER_INTERFACE" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Explorer - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "LANG" /D "NEW_FOLDER_INTERFACE" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /pdbtype:sept + +!ELSEIF "$(CFG)" == "Explorer - Win32 ReleaseU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ReleaseU" +# PROP BASE Intermediate_Dir "ReleaseU" +# PROP BASE Ignore_Export_Lib 1 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseU" +# PROP Intermediate_Dir "ReleaseU" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "LANG" /D "_MBCS" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "LANG" /D "NEW_FOLDER_INTERFACE" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /opt:NOWIN98 +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zipn.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Explorer - Win32 DebugU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "DebugU" +# PROP BASE Intermediate_Dir "DebugU" +# PROP BASE Ignore_Export_Lib 1 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugU" +# PROP Intermediate_Dir "DebugU" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "LANG" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "LANG" /D "NEW_FOLDER_INTERFACE" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Explorer - Win32 Release" +# Name "Explorer - Win32 Debug" +# Name "Explorer - Win32 ReleaseU" +# Name "Explorer - Win32 DebugU" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\Explorer.def +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveName.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveName.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiverInfo.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiverInfo.h +# End Source File +# Begin Source File + +SOURCE=..\Common\CompressCall.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\CompressCall.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.h +# End Source File +# Begin Source File + +SOURCE=..\Common\HandlerLoader.h +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.h +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateProduce.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateProduce.h +# End Source File +# Begin Source File + +SOURCE=..\Common\WorkDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\WorkDir.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ZipRegistry.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ZipRegistry.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ContextMenu.cpp +# End Source File +# Begin Source File + +SOURCE=.\ContextMenu.h +# End Source File +# Begin Source File + +SOURCE=.\MyMessages.cpp +# End Source File +# Begin Source File + +SOURCE=.\MyMessages.h +# End Source File +# End Group +# Begin Group "Dialogs" + +# PROP Default_Filter "" +# Begin Group "Options" + +# PROP Default_Filter "" +# Begin Group "SystemPage" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\SystemPage\SystemPage.cpp +# End Source File +# Begin Source File + +SOURCE=.\SystemPage\SystemPage.h +# End Source File +# End Group +# Begin Group "FoldersPage" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\FoldersPage\FoldersPage.cpp +# End Source File +# Begin Source File + +SOURCE=.\FoldersPage\FoldersPage.h +# End Source File +# End Group +# End Group +# End Group +# Begin Group "Agent" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Agent\Agent.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\Agent.h +# End Source File +# Begin Source File + +SOURCE=..\Agent\AgentOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\AgentProxy.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\AgentProxy.h +# End Source File +# Begin Source File + +SOURCE=..\Agent\ArchiveFolder.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\ArchiveFolderOpen.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\ArchiveFolderOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\IFileExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Agent\IFolderArchive.h +# End Source File +# Begin Source File + +SOURCE=..\Agent\UpdateCallbackAgent.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\UpdateCallbackAgent.h +# End Source File +# End Group +# Begin Group "FileManager" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\FileManager\FormatUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\FormatUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\HelpUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\HelpUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\IFolder.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\LangUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\LangUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\ProgramLocation.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\ProgramLocation.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\RegistryUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\RegistryUtils.h +# End Source File +# End Group +# Begin Group "SDK" + +# PROP Default_Filter "" +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Lang.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Lang.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Random.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Random.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\TextConfig.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\TextConfig.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Types.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Group "Control" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\PropertyPage.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\PropertyPage.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileMapping.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Memory.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Memory.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Menu.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Menu.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Shell.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Shell.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.h +# End Source File +# End Group +# End Group +# Begin Group "7-zip common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.h +# End Source File +# End Group +# Begin Source File + +SOURCE=".\7-zip.dll.manifest" +# End Source File +# Begin Source File + +SOURCE=.\ContextMenuFlags.h +# End Source File +# Begin Source File + +SOURCE=.\OptionsDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\OptionsDialog.h +# End Source File +# Begin Source File + +SOURCE=.\RegistryContextMenu.cpp +# End Source File +# Begin Source File + +SOURCE=.\RegistryContextMenu.h +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/UI/Explorer/Explorer.dsw b/CPP/7zip/UI/Explorer/Explorer.dsw new file mode 100755 index 00000000..beb8df7b --- /dev/null +++ b/CPP/7zip/UI/Explorer/Explorer.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Explorer"=".\Explorer.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.cpp b/CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.cpp new file mode 100755 index 00000000..776813d8 --- /dev/null +++ b/CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.cpp @@ -0,0 +1,157 @@ +// FoldersPage.cpp + +#include "StdAfx.h" + +#include "resource.h" +#include "FoldersPage.h" + +#include "Common/StringConvert.h" +#include "Windows/Defs.h" +#include "Windows/Shell.h" +#include "Windows/ResourceString.h" + +#include "../../../FileManager/HelpUtils.h" +#include "../../Common/ZipRegistry.h" + +#include "../../../FileManager/LangUtils.h" + +using namespace NWindows; + +static CIDLangPair kIDLangPairs[] = +{ + { IDC_FOLDERS_STATIC_WORKING_FOLDER, 0x01000210 }, + { IDC_FOLDERS_WORK_RADIO_SYSTEM, 0x01000211 }, + { IDC_FOLDERS_WORK_RADIO_CURRENT, 0x01000212 }, + { IDC_FOLDERS_WORK_RADIO_SPECIFIED, 0x01000213 }, + { IDC_FOLDERS_WORK_CHECK_FOR_REMOVABLE, 0x01000214 } +}; + +static const int kWorkModeButtons[] = +{ + IDC_FOLDERS_WORK_RADIO_SYSTEM, + IDC_FOLDERS_WORK_RADIO_CURRENT, + IDC_FOLDERS_WORK_RADIO_SPECIFIED +}; + +static const int kNumWorkModeButtons = sizeof(kWorkModeButtons) / sizeof(kWorkModeButtons[0]); + +bool CFoldersPage::OnInit() +{ + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + ReadWorkDirInfo(m_WorkDirInfo); + + CheckButton(IDC_FOLDERS_WORK_CHECK_FOR_REMOVABLE, m_WorkDirInfo.ForRemovableOnly); + + CheckRadioButton(kWorkModeButtons[0], kWorkModeButtons[kNumWorkModeButtons - 1], + kWorkModeButtons[m_WorkDirInfo.Mode]); + + m_WorkPath.Init(*this, IDC_FOLDERS_WORK_EDIT_PATH); + m_ButtonSetWorkPath.Init(*this, IDC_FOLDERS_WORK_BUTTON_PATH); + + m_WorkPath.SetText(m_WorkDirInfo.Path); + + MyEnableControls(); + + return CPropertyPage::OnInit(); +} + +int CFoldersPage::GetWorkMode() const +{ + for (int i = 0; i < kNumWorkModeButtons; i++) + if(IsButtonCheckedBool(kWorkModeButtons[i])) + return i; + throw 0; +} + +void CFoldersPage::MyEnableControls() +{ + bool enablePath = (GetWorkMode() == NWorkDir::NMode::kSpecified); + m_WorkPath.Enable(enablePath); + m_ButtonSetWorkPath.Enable(enablePath); +} + +void CFoldersPage::GetWorkDir(NWorkDir::CInfo &workDirInfo) +{ + m_WorkPath.GetText(workDirInfo.Path); + workDirInfo.ForRemovableOnly = IsButtonCheckedBool(IDC_FOLDERS_WORK_CHECK_FOR_REMOVABLE); + workDirInfo.Mode = NWorkDir::NMode::EEnum(GetWorkMode()); +} + +/* +bool CFoldersPage::WasChanged() +{ + NWorkDir::CInfo workDirInfo; + GetWorkDir(workDirInfo); + return (workDirInfo.Mode != m_WorkDirInfo.Mode || + workDirInfo.ForRemovableOnly != m_WorkDirInfo.ForRemovableOnly || + workDirInfo.Path.Compare(m_WorkDirInfo.Path) != 0); +} +*/ + +void CFoldersPage::ModifiedEvent() +{ + Changed(); + /* + if (WasChanged()) + Changed(); + else + UnChanged(); + */ +} + +bool CFoldersPage::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + for (int i = 0; i < kNumWorkModeButtons; i++) + if (buttonID == kWorkModeButtons[i]) + { + MyEnableControls(); + ModifiedEvent(); + return true; + } + switch(buttonID) + { + case IDC_FOLDERS_WORK_BUTTON_PATH: + OnFoldersWorkButtonPath(); + break; + case IDC_FOLDERS_WORK_CHECK_FOR_REMOVABLE: + break; + default: + return CPropertyPage::OnButtonClicked(buttonID, buttonHWND); + } + ModifiedEvent(); + return true; +} + +bool CFoldersPage::OnCommand(int code, int itemID, LPARAM lParam) +{ + if (code == EN_CHANGE && itemID == IDC_FOLDERS_WORK_EDIT_PATH) + { + ModifiedEvent(); + return true; + } + return CPropertyPage::OnCommand(code, itemID, lParam); +} + +void CFoldersPage::OnFoldersWorkButtonPath() +{ + UString currentPath; + m_WorkPath.GetText(currentPath); + UString title = LangString(IDS_FOLDERS_SET_WORK_PATH_TITLE, 0x01000281); + UString resultPath; + if (NShell::BrowseForFolder(HWND(*this), title, currentPath, resultPath)) + m_WorkPath.SetText(resultPath); +} + +LONG CFoldersPage::OnApply() +{ + GetWorkDir(m_WorkDirInfo); + SaveWorkDirInfo(m_WorkDirInfo); + return PSNRET_NOERROR; +} + +static LPCWSTR kFoldersTopic = L"fm/plugins/7-zip/options.htm#folders"; + +void CFoldersPage::OnNotifyHelp() +{ + ShowHelpWindow(NULL, kFoldersTopic); +} diff --git a/CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.h b/CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.h new file mode 100755 index 00000000..97950fc6 --- /dev/null +++ b/CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.h @@ -0,0 +1,30 @@ +// FoldersPage.h + +#ifndef __FOLDERSPAGE_H +#define __FOLDERSPAGE_H + +#include "Windows/Control/PropertyPage.h" + +#include "../../Common/ZipRegistry.h" + +class CFoldersPage : public NWindows::NControl::CPropertyPage +{ + NWorkDir::CInfo m_WorkDirInfo; + + void MyEnableControls(); + void ModifiedEvent(); + NWindows::NControl::CDialogChildControl m_WorkPath; + NWindows::NControl::CDialogChildControl m_ButtonSetWorkPath; + void OnFoldersWorkButtonPath(); + int GetWorkMode() const; + void GetWorkDir(NWorkDir::CInfo &workDirInfo); + // bool WasChanged(); +public: + virtual bool OnInit(); + virtual bool OnCommand(int code, int itemID, LPARAM lParam); + virtual void OnNotifyHelp(); + virtual LONG OnApply(); + virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); +}; + +#endif diff --git a/CPP/7zip/UI/Explorer/FoldersPage/resource.h b/CPP/7zip/UI/Explorer/FoldersPage/resource.h new file mode 100755 index 00000000..3052409b --- /dev/null +++ b/CPP/7zip/UI/Explorer/FoldersPage/resource.h @@ -0,0 +1,12 @@ +#define IDD_FOLDERS 900 + +#define IDS_FOLDERS_SET_WORK_PATH_TITLE 103 + +#define IDC_FOLDERS_STATIC_WORKING_FOLDER 1001 + +#define IDC_FOLDERS_WORK_RADIO_SYSTEM 1011 +#define IDC_FOLDERS_WORK_RADIO_CURRENT 1012 +#define IDC_FOLDERS_WORK_RADIO_SPECIFIED 1013 +#define IDC_FOLDERS_WORK_EDIT_PATH 1014 +#define IDC_FOLDERS_WORK_BUTTON_PATH 1015 +#define IDC_FOLDERS_WORK_CHECK_FOR_REMOVABLE 1017 diff --git a/CPP/7zip/UI/Explorer/FoldersPage/resource.rc b/CPP/7zip/UI/Explorer/FoldersPage/resource.rc new file mode 100755 index 00000000..96b2c9d3 --- /dev/null +++ b/CPP/7zip/UI/Explorer/FoldersPage/resource.rc @@ -0,0 +1,36 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" + +#define xSize2 196 +#define ySize2 140 +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#define marg2 marg +#define marg3 10 +#define gPos (marg + marg2) +#define gSize (xSize2 - marg2 - marg2) +#define gPos2 (gPos + marg3) + + +IDD_FOLDERS DIALOG 0, 0, xSize, ySize MY_PAGE_STYLE +CAPTION "Folders" +MY_FONT +BEGIN + GROUPBOX "&Working folder", IDC_FOLDERS_STATIC_WORKING_FOLDER, marg, marg, xSize2, 98 + CONTROL "&System temp folder", IDC_FOLDERS_WORK_RADIO_SYSTEM, "Button", BS_AUTORADIOBUTTON | WS_GROUP, + gPos, 20, gSize, 10 + CONTROL "&Current", IDC_FOLDERS_WORK_RADIO_CURRENT, "Button", BS_AUTORADIOBUTTON, + gPos, 34, gSize, 10 + CONTROL "Specified:", IDC_FOLDERS_WORK_RADIO_SPECIFIED, "Button", BS_AUTORADIOBUTTON, + gPos, 48, gSize, 10 + EDITTEXT IDC_FOLDERS_WORK_EDIT_PATH, gPos2, 63, gSize - marg3 - bDotsSize - 10, 14, ES_AUTOHSCROLL + PUSHBUTTON "...", IDC_FOLDERS_WORK_BUTTON_PATH, xSize - marg - marg2 - bDotsSize, 63, bDotsSize, bYSize + CONTROL "Use for removable drives only", IDC_FOLDERS_WORK_CHECK_FOR_REMOVABLE, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + gPos, 87, gSize, 10 +END + +STRINGTABLE +BEGIN + IDS_FOLDERS_SET_WORK_PATH_TITLE "Specify a location for temporary archive files." +END diff --git a/CPP/7zip/UI/Explorer/MyMessages.cpp b/CPP/7zip/UI/Explorer/MyMessages.cpp new file mode 100755 index 00000000..61d2429d --- /dev/null +++ b/CPP/7zip/UI/Explorer/MyMessages.cpp @@ -0,0 +1,58 @@ +// MyMessages.cpp + +#include "StdAfx.h" + +#include "MyMessages.h" +#include "Common/String.h" +#include "Common/StringConvert.h" + +#include "Windows/Error.h" +#include "Windows/ResourceString.h" + +#ifdef LANG +#include "../../FileManager/LangUtils.h" +#endif + +using namespace NWindows; + +void MyMessageBox(HWND window, LPCWSTR message) +{ + ::MessageBoxW(window, message, L"7-Zip", 0); +} + +void MyMessageBoxResource(HWND window, UINT32 id + #ifdef LANG + ,UINT32 langID + #endif + ) +{ + #ifdef LANG + MyMessageBox(window, LangString(id, langID)); + #else + MyMessageBox(window, MyLoadStringW(id)); + #endif +} + +void MyMessageBox(UINT32 id + #ifdef LANG + ,UINT32 langID + #endif + ) +{ + MyMessageBoxResource(0, id + #ifdef LANG + , langID + #endif + ); +} + +void ShowErrorMessage(HWND window, DWORD message) +{ + MyMessageBox(window, NError::MyFormatMessageW(message)); +} + +void ShowLastErrorMessage(HWND window) +{ + ShowErrorMessage(window, ::GetLastError()); +} + diff --git a/CPP/7zip/UI/Explorer/MyMessages.h b/CPP/7zip/UI/Explorer/MyMessages.h new file mode 100755 index 00000000..1a96f569 --- /dev/null +++ b/CPP/7zip/UI/Explorer/MyMessages.h @@ -0,0 +1,30 @@ +// MyMessages.h + +#ifndef __MYMESSAGES_H +#define __MYMESSAGES_H + +#include "Common/String.h" + +void MyMessageBox(HWND window, LPCWSTR message); + +inline void MyMessageBox(LPCWSTR message) + { MyMessageBox(0, message); } + +void MyMessageBoxResource(HWND window, UINT32 id + #ifdef LANG + ,UINT32 langID + #endif + ); + +void MyMessageBox(UINT32 id + #ifdef LANG + ,UINT32 langID + #endif + ); + +void ShowErrorMessage(HWND window, DWORD errorMessage); +inline void ShowErrorMessage(DWORD errorMessage) + { ShowErrorMessage(0, errorMessage); } +void ShowLastErrorMessage(HWND window = 0); + +#endif diff --git a/CPP/7zip/UI/Explorer/OptionsDialog.cpp b/CPP/7zip/UI/Explorer/OptionsDialog.cpp new file mode 100755 index 00000000..b7831afd --- /dev/null +++ b/CPP/7zip/UI/Explorer/OptionsDialog.cpp @@ -0,0 +1,71 @@ +// OptionsDialog.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "OptionsDialog.h" + +#include "Common/StringConvert.h" +#include "Windows/Control/PropertyPage.h" + +#include "../../FileManager/LangUtils.h" +#include "FoldersPage/FoldersPage.h" +#include "FoldersPage/resource.h" +#include "SystemPage/SystemPage.h" +#include "SystemPage/resource.h" + +using namespace NWindows; + +static INT_PTR OptionsDialog(HWND hwndOwner) +{ + CSystemPage systemPage; + CFoldersPage foldersPage; + UINT32 langIDs[] = { 0x01000300, 0x01000200}; + UINT pageIDs[] = { IDD_SYSTEM, IDD_FOLDERS}; + NControl::CPropertyPage *pagePinters[] = { &systemPage, &foldersPage }; + CObjectVector pages; + const int kNumPages = sizeof(langIDs) / sizeof(langIDs[0]); + for (int i = 0; i < kNumPages; i++) + { + NControl::CPageInfo page; + page.Title = LangString(langIDs[i]); + page.ID = pageIDs[i]; + page.Page = pagePinters[i]; + pages.Add(page); + } + return NControl::MyPropertySheet(pages, hwndOwner, + LangString(IDS_CONFIG_DIALOG_CAPTION, 0x01000000)); +} + +STDMETHODIMP CSevenZipOptions::PluginOptions(HWND hWnd, + IPluginOptionsCallback * /* callback */) +{ + /* + CComBSTR programPath; + RETUEN_IF_NOT_S_OK(callback->GetProgramPath(programName))); + */ + OptionsDialog(hWnd); + return S_OK; +} + +STDMETHODIMP CSevenZipOptions::GetFileExtensions(BSTR * /* extensions */) +{ + /* + UString extStrings; + CObjectVector formats; + NZipRootRegistry::ReadArchiverInfoList(formats); + for(int i = 0; i < formats.Size(); i++) + { + if (i != 0) + extStrings += L' '; + extStrings += formats[i].Extension; + } + CComBSTR valueTemp = extStrings; + *extensions = valueTemp.Detach(); + return S_OK; + */ + return E_NOTIMPL; +} + + diff --git a/CPP/7zip/UI/Explorer/OptionsDialog.h b/CPP/7zip/UI/Explorer/OptionsDialog.h new file mode 100755 index 00000000..7e85d357 --- /dev/null +++ b/CPP/7zip/UI/Explorer/OptionsDialog.h @@ -0,0 +1,23 @@ +// OptionsDialog.h + +#ifndef __SEVENZIP_OPTIONSDIALOG_H +#define __SEVENZIP_OPTIONSDIALOG_H + +#include "../../FileManager/PluginInterface.h" +#include "Common/MyCom.h" + +// {23170F69-40C1-278D-1000-000100020000} +DEFINE_GUID(CLSID_CSevenZipOptions, + 0x23170F69, 0x40C1, 0x278D, 0x10, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00); + +class CSevenZipOptions: + public IPluginOptions, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + STDMETHOD(PluginOptions)(HWND hWnd, IPluginOptionsCallback *callback); + STDMETHOD(GetFileExtensions)(BSTR *extensions); +}; + +#endif diff --git a/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp b/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp new file mode 100755 index 00000000..73a8420e --- /dev/null +++ b/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp @@ -0,0 +1,128 @@ +// RegistryContextMenu.cpp + +#include "StdAfx.h" + +#include "RegistryContextMenu.h" +#include "Windows/COM.h" +#include "Windows/Synchronization.h" +#include "Windows/Registry.h" +#include "Windows/FileName.h" + +using namespace NWindows; +using namespace NCOM; +using namespace NRegistry; + +namespace NZipRootRegistry { + +static NSynchronization::CCriticalSection g_RegistryOperationsCriticalSection; + +/////////////////////////// +// ContextMenu + +static const TCHAR *kContextMenuKeyName = TEXT("\\shellex\\ContextMenuHandlers\\7-ZIP"); +static const TCHAR *kDragDropMenuKeyName = TEXT("\\shellex\\DragDropHandlers\\7-ZIP"); + +static const TCHAR *kExtensionCLSID = TEXT("{23170F69-40C1-278A-1000-000100020000}"); + +static const TCHAR *kRootKeyNameForFile = TEXT("*"); +static const TCHAR *kRootKeyNameForFolder = TEXT("Folder"); +static const TCHAR *kRootKeyNameForDirectory = TEXT("Directory"); +static const TCHAR *kRootKeyNameForDrive = TEXT("Drive"); + +static CSysString GetFullContextMenuKeyName(const CSysString &keyName) + { return (keyName + kContextMenuKeyName); } + +static CSysString GetFullDragDropMenuKeyName(const CSysString &keyName) + { return (keyName + kDragDropMenuKeyName); } + +static bool CheckContextMenuHandlerCommon(const CSysString &keyName) +{ + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey key; + if (key.Open(HKEY_CLASSES_ROOT, GetFullContextMenuKeyName(keyName), KEY_READ) + != ERROR_SUCCESS) + return false; + CSysString value; + if (key.QueryValue(NULL, value) != ERROR_SUCCESS) + return false; + return (value.CompareNoCase(kExtensionCLSID) == 0); +} + +static bool CheckDragDropMenuHandlerCommon(const CSysString &keyName) +{ + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey key; + if (key.Open(HKEY_CLASSES_ROOT, GetFullDragDropMenuKeyName(keyName), KEY_READ) != ERROR_SUCCESS) + return false; + CSysString value; + if (key.QueryValue(NULL, value) != ERROR_SUCCESS) + return false; + return (value.CompareNoCase(kExtensionCLSID) == 0); +} + +bool CheckContextMenuHandler() +{ + return CheckContextMenuHandlerCommon(kRootKeyNameForFile) && + // CheckContextMenuHandlerCommon(kRootKeyNameForFolder) && + CheckContextMenuHandlerCommon(kRootKeyNameForDirectory) && + CheckDragDropMenuHandlerCommon(kRootKeyNameForDirectory) && + CheckDragDropMenuHandlerCommon(kRootKeyNameForDrive); +} + +static void DeleteContextMenuHandlerCommon(const CSysString &keyName) +{ + CKey rootKey; + rootKey.Attach(HKEY_CLASSES_ROOT); + rootKey.RecurseDeleteKey(GetFullContextMenuKeyName(keyName)); + rootKey.Detach(); +} + +static void DeleteDragDropMenuHandlerCommon(const CSysString &keyName) +{ + CKey rootKey; + rootKey.Attach(HKEY_CLASSES_ROOT); + rootKey.RecurseDeleteKey(GetFullDragDropMenuKeyName(keyName)); + rootKey.Detach(); +} + +void DeleteContextMenuHandler() +{ + DeleteContextMenuHandlerCommon(kRootKeyNameForFile); + DeleteContextMenuHandlerCommon(kRootKeyNameForFolder); + DeleteContextMenuHandlerCommon(kRootKeyNameForDirectory); + DeleteContextMenuHandlerCommon(kRootKeyNameForDrive); + DeleteDragDropMenuHandlerCommon(kRootKeyNameForFile); + DeleteDragDropMenuHandlerCommon(kRootKeyNameForFolder); + DeleteDragDropMenuHandlerCommon(kRootKeyNameForDirectory); + DeleteDragDropMenuHandlerCommon(kRootKeyNameForDrive); +} + +static void AddContextMenuHandlerCommon(const CSysString &keyName) +{ + DeleteContextMenuHandlerCommon(keyName); + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey key; + key.Create(HKEY_CLASSES_ROOT, GetFullContextMenuKeyName(keyName)); + key.SetValue(NULL, kExtensionCLSID); +} + +static void AddDragDropMenuHandlerCommon(const CSysString &keyName) +{ + DeleteDragDropMenuHandlerCommon(keyName); + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey key; + key.Create(HKEY_CLASSES_ROOT, GetFullDragDropMenuKeyName(keyName)); + key.SetValue(NULL, kExtensionCLSID); +} + +void AddContextMenuHandler() +{ + AddContextMenuHandlerCommon(kRootKeyNameForFile); + // AddContextMenuHandlerCommon(kRootKeyNameForFolder); + AddContextMenuHandlerCommon(kRootKeyNameForDirectory); + + AddDragDropMenuHandlerCommon(kRootKeyNameForDirectory); + AddDragDropMenuHandlerCommon(kRootKeyNameForDrive); +} + +} diff --git a/CPP/7zip/UI/Explorer/RegistryContextMenu.h b/CPP/7zip/UI/Explorer/RegistryContextMenu.h new file mode 100755 index 00000000..52b053da --- /dev/null +++ b/CPP/7zip/UI/Explorer/RegistryContextMenu.h @@ -0,0 +1,13 @@ +// RegistryContextMenu.h + +#ifndef __REGISTRYCONTEXTMENU_H +#define __REGISTRYCONTEXTMENU_H + +namespace NZipRootRegistry { + + bool CheckContextMenuHandler(); + void AddContextMenuHandler(); + void DeleteContextMenuHandler(); +} + +#endif diff --git a/CPP/7zip/UI/Explorer/StdAfx.cpp b/CPP/7zip/UI/Explorer/StdAfx.cpp new file mode 100755 index 00000000..2550270c --- /dev/null +++ b/CPP/7zip/UI/Explorer/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "stdafx.h" diff --git a/CPP/7zip/UI/Explorer/StdAfx.h b/CPP/7zip/UI/Explorer/StdAfx.h new file mode 100755 index 00000000..b9c0ee3a --- /dev/null +++ b/CPP/7zip/UI/Explorer/StdAfx.h @@ -0,0 +1,26 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#define _WIN32_WINNT 0x0400 +// it's hack for Windows NT supporting +#define WINVER 0x0400 + +// #define _WIN32_IE 0x0500 +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/UI/Explorer/SystemPage/SystemPage.cpp b/CPP/7zip/UI/Explorer/SystemPage/SystemPage.cpp new file mode 100755 index 00000000..cc2f974d --- /dev/null +++ b/CPP/7zip/UI/Explorer/SystemPage/SystemPage.cpp @@ -0,0 +1,212 @@ +// SystemPage.cpp + +#include "StdAfx.h" +#include "resource.h" +#include "../resource.h" + +#include "Common/StringConvert.h" +#include "Windows/Defs.h" +#include "Windows/Control/ListView.h" + +#include "SystemPage.h" + +#include "../../Common/ZipRegistry.h" +#include "../RegistryContextMenu.h" +#include "../ContextMenuFlags.h" + +#include "../../../FileManager/HelpUtils.h" +#include "../../../FileManager/LangUtils.h" +#include "../../../FileManager/FormatUtils.h" + +using namespace NContextMenuFlags; + +static CIDLangPair kIDLangPairs[] = +{ + { IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU, 0x01000301}, + { IDC_SYSTEM_CASCADED_MENU, 0x01000302}, + { IDC_SYSTEM_STATIC_CONTEXT_MENU_ITEMS, 0x01000310} +}; + +static LPCWSTR kSystemTopic = L"fm/plugins/7-zip/options.htm#system"; + +struct CContextMenuItem +{ + int ControlID; + UINT32 LangID; + UINT32 Flag; +}; + +static CContextMenuItem kMenuItems[] = +{ + { IDS_CONTEXT_OPEN, 0x02000103, kOpen}, + { IDS_CONTEXT_EXTRACT, 0x02000105, kExtract}, + { IDS_CONTEXT_EXTRACT_HERE, 0x0200010B, kExtractHere }, + { IDS_CONTEXT_EXTRACT_TO, 0x0200010D, kExtractTo }, + + { IDS_CONTEXT_TEST, 0x02000109, kTest}, + + { IDS_CONTEXT_COMPRESS, 0x02000107, kCompress }, + { IDS_CONTEXT_COMPRESS_EMAIL, 0x02000111, kCompressEmail }, + { IDS_CONTEXT_COMPRESS_TO, 0x0200010F, kCompressTo7z }, + { IDS_CONTEXT_COMPRESS_TO_EMAIL, 0x02000113, kCompressTo7zEmail}, + { IDS_CONTEXT_COMPRESS_TO, 0x0200010F, kCompressToZip }, + { IDS_CONTEXT_COMPRESS_TO_EMAIL, 0x02000113, kCompressToZipEmail}, +}; + +const int kNumMenuItems = sizeof(kMenuItems) / sizeof(kMenuItems[0]); + +bool CSystemPage::OnInit() +{ + _initMode = true; + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + + CheckButton(IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU, + NZipRootRegistry::CheckContextMenuHandler()); + + CheckButton(IDC_SYSTEM_CASCADED_MENU, ReadCascadedMenu()); + + UINT32 contextMenuFlags; + if (!ReadContextMenuStatus(contextMenuFlags)) + contextMenuFlags = NContextMenuFlags::GetDefaultFlags(); + + m_ListView.Attach(GetItem(IDC_SYSTEM_OPTIONS_LIST)); + + /* + CheckButton(IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU, + NRegistryAssociations::CheckContextMenuHandler()); + */ + + UINT32 newFlags = LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT; + m_ListView.SetExtendedListViewStyle(newFlags, newFlags); + + UString s; // = TEXT("Items"); // LangLoadString(IDS_PROPERTY_EXTENSION, 0x02000205); + LVCOLUMNW column; + column.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_FMT | LVCF_SUBITEM; + column.cx = 270; + column.fmt = LVCFMT_LEFT; + column.pszText = (LPWSTR)(LPCWSTR)s; + column.iSubItem = 0; + m_ListView.InsertColumn(0, &column); + + for (int i = 0; i < kNumMenuItems; i++) + { + CContextMenuItem &menuItem = kMenuItems[i]; + LVITEMW item; + item.iItem = i; + item.mask = LVIF_TEXT | LVIF_PARAM; + item.lParam = i; + + UString s = LangString(menuItem.ControlID, menuItem.LangID); + + switch(menuItem.ControlID) + { + case IDS_CONTEXT_EXTRACT_TO: + { + s = MyFormatNew(s, LangString(IDS_CONTEXT_FOLDER, 0x02000140)); + break; + } + case IDS_CONTEXT_COMPRESS_TO: + case IDS_CONTEXT_COMPRESS_TO_EMAIL: + { + UString s2 = LangString(IDS_CONTEXT_ARCHIVE, 0x02000141); + switch(menuItem.Flag) + { + case kCompressTo7z: + case kCompressTo7zEmail: + s2 += L".7z"; + break; + case kCompressToZip: + case kCompressToZipEmail: + s2 += L".zip"; + break; + } + s = MyFormatNew(s, s2); + break; + } + } + + // UString MyFormatNew(const UString &format, const UString &argument); + + item.pszText = (LPWSTR)(LPCWSTR)s; + item.iSubItem = 0; + int itemIndex = m_ListView.InsertItem(&item); + m_ListView.SetCheckState(itemIndex, ((contextMenuFlags & menuItem.Flag) != 0)); + } + + _initMode = false; + return CPropertyPage::OnInit(); +} + +STDAPI DllRegisterServer(void); +STDAPI DllUnregisterServer(void); + +LONG CSystemPage::OnApply() +{ + if (IsButtonCheckedBool(IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU)) + { + DllRegisterServer(); + NZipRootRegistry::AddContextMenuHandler(); + } + else + { + DllUnregisterServer(); + NZipRootRegistry::DeleteContextMenuHandler(); + } + SaveCascadedMenu(IsButtonCheckedBool(IDC_SYSTEM_CASCADED_MENU)); + + UINT32 flags = 0; + for (int i = 0; i < kNumMenuItems; i++) + if (m_ListView.GetCheckState(i)) + flags |= kMenuItems[i].Flag; + SaveContextMenuStatus(flags); + + return PSNRET_NOERROR; +} + +void CSystemPage::OnNotifyHelp() +{ + ShowHelpWindow(NULL, kSystemTopic); +} + +bool CSystemPage::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) + { + case IDC_SYSTEM_CASCADED_MENU: + case IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU: + Changed(); + return true; + } + return CPropertyPage::OnButtonClicked(buttonID, buttonHWND); + +} + +bool CSystemPage::OnNotify(UINT aControlID, LPNMHDR lParam) +{ + if (lParam->hwndFrom == HWND(m_ListView)) + { + switch(lParam->code) + { + case (LVN_ITEMCHANGED): + return OnItemChanged((const NMLISTVIEW *)lParam); + } + } + return CPropertyPage::OnNotify(aControlID, lParam); +} + + +bool CSystemPage::OnItemChanged(const NMLISTVIEW *info) +{ + if (_initMode) + return true; + if ((info->uChanged & LVIF_STATE) != 0) + { + UINT oldState = info->uOldState & LVIS_STATEIMAGEMASK; + UINT newState = info->uNewState & LVIS_STATEIMAGEMASK; + if (oldState != newState) + Changed(); + } + // PostMessage(kRefreshpluginsListMessage, 0); + // RefreshPluginsList(); + return true; +} diff --git a/CPP/7zip/UI/Explorer/SystemPage/SystemPage.h b/CPP/7zip/UI/Explorer/SystemPage/SystemPage.h new file mode 100755 index 00000000..a7de7c79 --- /dev/null +++ b/CPP/7zip/UI/Explorer/SystemPage/SystemPage.h @@ -0,0 +1,25 @@ +// SystemPage.h + +#ifndef __SYSTEMPAGE_H +#define __SYSTEMPAGE_H + +#include "Windows/Control/PropertyPage.h" +#include "Windows/Control/ListView.h" + +#include "../../Common/ArchiverInfo.h" + +class CSystemPage: public NWindows::NControl::CPropertyPage +{ + bool _initMode; + CObjectVector m_Archivers; + NWindows::NControl::CListView m_ListView; +public: + virtual bool OnInit(); + virtual void OnNotifyHelp(); + virtual bool OnNotify(UINT aControlID, LPNMHDR lParam); + virtual bool OnItemChanged(const NMLISTVIEW *info); + virtual LONG OnApply(); + virtual bool OnButtonClicked(int aButtonID, HWND aButtonHWND); +}; + +#endif diff --git a/CPP/7zip/UI/Explorer/SystemPage/resource.h b/CPP/7zip/UI/Explorer/SystemPage/resource.h new file mode 100755 index 00000000..b125849c --- /dev/null +++ b/CPP/7zip/UI/Explorer/SystemPage/resource.h @@ -0,0 +1,6 @@ +#define IDD_SYSTEM 102 + +#define IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU 1010 +#define IDC_SYSTEM_CASCADED_MENU 1011 +#define IDC_SYSTEM_STATIC_CONTEXT_MENU_ITEMS 1020 +#define IDC_SYSTEM_OPTIONS_LIST 1022 diff --git a/CPP/7zip/UI/Explorer/SystemPage/resource.rc b/CPP/7zip/UI/Explorer/SystemPage/resource.rc new file mode 100755 index 00000000..fdfed433 --- /dev/null +++ b/CPP/7zip/UI/Explorer/SystemPage/resource.rc @@ -0,0 +1,24 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" + +#define xSize2 196 +#define ySize2 164 +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +IDD_SYSTEM DIALOG 0, 0, xSize, ySize MY_PAGE_STYLE +CAPTION "System" +MY_FONT +BEGIN + CONTROL "Integrate 7-Zip to shell context menu", IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU, + "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, marg, xSize2, 10 + CONTROL "Cascaded context menu", IDC_SYSTEM_CASCADED_MENU, + "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, 21, xSize2, 10 + LTEXT "Context menu items:", IDC_SYSTEM_STATIC_CONTEXT_MENU_ITEMS, + marg, 37, xSize2, 8 + CONTROL "List1", IDC_SYSTEM_OPTIONS_LIST, "SysListView32", + LVS_REPORT | LVS_SINGLESEL | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP, + marg, 50, xSize2, ySize - marg - 50 +END diff --git a/CPP/7zip/UI/Explorer/makefile b/CPP/7zip/UI/Explorer/makefile new file mode 100755 index 00000000..0fcc57e4 --- /dev/null +++ b/CPP/7zip/UI/Explorer/makefile @@ -0,0 +1,137 @@ +PROG = 7-zip.dll +DEF_FILE = Explorer.def +LIBS = $(LIBS) user32.lib oleaut32.lib advapi32.lib htmlhelp.lib shell32.lib comctl32.lib ole32.lib comdlg32.lib +CFLAGS = $(CFLAGS) -I ../../../ \ + -DLANG \ + -DNEW_FOLDER_INTERFACE \ + -DWIN_LONG_PATH + +EXPLORER_OBJS = \ + $O\DllExports.obj \ + $O\ContextMenu.obj \ + $O\MyMessages.obj \ + $O\OptionsDialog.obj \ + $O\RegistryContextMenu.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\IntToString.obj \ + $O\Lang.obj \ + $O\ListFileUtils.obj \ + $O\NewHandler.obj \ + $O\Random.obj \ + $O\StdInStream.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\TextConfig.obj \ + $O\UTFConvert.obj \ + $O\Vector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\Error.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\Menu.obj \ + $O\PropVariant.obj \ + $O\PropVariantConversions.obj \ + $O\Registry.obj \ + $O\ResourceString.obj \ + $O\Shell.obj \ + $O\Synchronization.obj \ + $O\Window.obj \ + +WIN_CTRL_OBJS = \ + $O\Dialog.obj \ + $O\PropertyPage.obj \ + +7ZIP_COMMON_OBJS = \ + $O\FilePathAutoRename.obj \ + $O\FileStreams.obj \ + $O\StreamUtils.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveExtractCallback.obj \ + $O\ArchiveName.obj \ + $O\ArchiveOpenCallback.obj \ + $O\ArchiverInfo.obj \ + $O\CompressCall.obj \ + $O\DefaultName.obj \ + $O\EnumDirItems.obj \ + $O\ExtractingFilePath.obj \ + $O\OpenArchive.obj \ + $O\PropIDUtils.obj \ + $O\SortUtils.obj \ + $O\UpdateAction.obj \ + $O\UpdateCallback.obj \ + $O\UpdatePair.obj \ + $O\UpdateProduce.obj \ + $O\WorkDir.obj \ + $O\ZipRegistry.obj \ + +AGENT_OBJS = \ + $O\Agent.obj \ + $O\AgentOut.obj \ + $O\AgentProxy.obj \ + $O\ArchiveFolder.obj \ + $O\ArchiveFolderOpen.obj \ + $O\ArchiveFolderOut.obj \ + $O\UpdateCallbackAgent.obj \ + + +FM_COMMON_OBJS = \ + $O\FormatUtils.obj \ + $O\HelpUtils.obj \ + $O\LangUtils.obj \ + $O\ProgramLocation.obj \ + $O\RegistryUtils.obj \ + +C_OBJS = \ + $O\Sort.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(EXPLORER_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(WIN_CTRL_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(UI_COMMON_OBJS) \ + $(AGENT_OBJS) \ + $(FM_COMMON_OBJS)\ + $(C_OBJS) \ + $O\SystemPage.obj \ + $O\FoldersPage.obj \ + $O\CopyCoder.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(EXPLORER_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(WIN_CTRL_OBJS): ../../../Windows/Control/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(UI_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$(AGENT_OBJS): ../Agent/$(*B).cpp + $(COMPL) +$(FM_COMMON_OBJS): ../../FileManager/$(*B).cpp + $(COMPL) +$O\SystemPage.obj: SystemPage/$(*B).cpp + $(COMPL) +$O\FoldersPage.obj: FoldersPage/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) +$(C_OBJS): ../../../../C/$(*B).c + $(COMPL_O2) diff --git a/CPP/7zip/UI/Explorer/resource.h b/CPP/7zip/UI/Explorer/resource.h new file mode 100755 index 00000000..aec1e7cd --- /dev/null +++ b/CPP/7zip/UI/Explorer/resource.h @@ -0,0 +1,31 @@ +#define IDS_CONTEXT_EXTRACT 42 +#define IDS_CONTEXT_EXTRACT_HELP 43 +#define IDS_CONTEXT_COMPRESS 44 +#define IDS_CONTEXT_COMPRESS_HELP 45 +#define IDS_CONTEXT_OPEN 46 +#define IDS_CONTEXT_OPEN_HELP 47 +#define IDS_CONTEXT_TEST 48 +#define IDS_CONTEXT_TEST_HELP 49 +#define IDS_CONTEXT_CAPTION_HELP 50 +#define IDS_CONTEXT_POPUP_CAPTION 51 + +#define IDS_CONTEXT_EXTRACT_HERE 52 +#define IDS_CONTEXT_EXTRACT_HERE_HELP 53 + +#define IDS_CONTEXT_EXTRACT_TO 54 +#define IDS_CONTEXT_EXTRACT_TO_HELP 55 + +#define IDS_CONTEXT_COMPRESS_TO 56 +#define IDS_CONTEXT_COMPRESS_TO_HELP 57 + +#define IDS_CONTEXT_COMPRESS_EMAIL 58 +#define IDS_CONTEXT_COMPRESS_EMAIL_HELP 59 + +#define IDS_CONTEXT_COMPRESS_TO_EMAIL 60 +#define IDS_CONTEXT_COMPRESS_TO_EMAIL_HELP 61 + +#define IDS_CONTEXT_FOLDER 70 +#define IDS_CONTEXT_ARCHIVE 71 + +#define IDS_ERROR 100 +#define IDS_CONFIG_DIALOG_CAPTION 102 diff --git a/CPP/7zip/UI/Explorer/resource.rc b/CPP/7zip/UI/Explorer/resource.rc new file mode 100755 index 00000000..bf7601d9 --- /dev/null +++ b/CPP/7zip/UI/Explorer/resource.rc @@ -0,0 +1,38 @@ +#include "../../MyVersionInfo.rc" +#include "resource.h" + +MY_VERSION_INFO_DLL("7-Zip Shell Extension", "7-zip") + +1 24 "7-zip.dll.manifest" + +STRINGTABLE +BEGIN + IDS_CONTEXT_EXTRACT "Extract files..." + IDS_CONTEXT_EXTRACT_HELP "Extracts files from the selected archive." + IDS_CONTEXT_COMPRESS "Add to archive..." + IDS_CONTEXT_COMPRESS_HELP "Adds the selected items to archive." + IDS_CONTEXT_OPEN "Open archive" + IDS_CONTEXT_OPEN_HELP "Opens the selected archive." + IDS_CONTEXT_TEST "Test archive" + IDS_CONTEXT_TEST_HELP "Tests integrity of the selected archive." + IDS_CONTEXT_CAPTION_HELP "7-Zip commands" + IDS_CONTEXT_POPUP_CAPTION "7-Zip" + IDS_CONTEXT_EXTRACT_HERE "Extract Here" + IDS_CONTEXT_EXTRACT_HERE_HELP "Extracts files from the selected archive to current folder." + IDS_CONTEXT_EXTRACT_TO "Extract to {0}" + IDS_CONTEXT_EXTRACT_TO_HELP "Extracts files to subfolder." + IDS_CONTEXT_COMPRESS_TO "Add to {0}" + IDS_CONTEXT_COMPRESS_TO_HELP "Adds the selected items to archive." + IDS_CONTEXT_COMPRESS_EMAIL "Compress and email..." + IDS_CONTEXT_COMPRESS_EMAIL_HELP "Compresses the selected items to archive and sends archive via email." + IDS_CONTEXT_COMPRESS_TO_EMAIL "Compress to {0} and email" + IDS_CONTEXT_COMPRESS_TO_EMAIL_HELP "Compresses the selected items to archive and sends archive via email." + IDS_CONTEXT_FOLDER "" + IDS_CONTEXT_ARCHIVE "" + IDS_ERROR "Error" + IDS_CONFIG_DIALOG_CAPTION "7-Zip Options" +END + +#include "FoldersPage/resource.rc" +#include "SystemPage/resource.rc" + diff --git a/CPP/7zip/UI/Far/CLSIDConst.cpp b/CPP/7zip/UI/Far/CLSIDConst.cpp new file mode 100755 index 00000000..a6cea92e --- /dev/null +++ b/CPP/7zip/UI/Far/CLSIDConst.cpp @@ -0,0 +1,8 @@ +// CLSIDConst.cpp + +#include "StdAfx.h" + +#include + +#include "../Agent/Agent.h" +#include "../../IPassword.h" diff --git a/CPP/7zip/UI/Far/ExtractEngine.cpp b/CPP/7zip/UI/Far/ExtractEngine.cpp new file mode 100755 index 00000000..e85df5e1 --- /dev/null +++ b/CPP/7zip/UI/Far/ExtractEngine.cpp @@ -0,0 +1,168 @@ +// ExtractEngine.h + +#include "StdAfx.h" + +#include + +#include "ExtractEngine.h" + +#include "Common/Wildcard.h" +#include "Common/StringConvert.h" + +#include "Windows/Defs.h" + +#include "FarUtils.h" +#include "Messages.h" +#include "OverwriteDialog.h" + +using namespace NWindows; +using namespace NFar; + +extern void PrintMessage(const char *message); + +CExtractCallBackImp::~CExtractCallBackImp() +{ +} + +void CExtractCallBackImp::Init( + UINT codePage, + CProgressBox *progressBox, + bool passwordIsDefined, + const UString &password) +{ + m_PasswordIsDefined = passwordIsDefined; + m_Password = password; + m_CodePage = codePage; + m_ProgressBox = progressBox; +} + +STDMETHODIMP CExtractCallBackImp::SetTotal(UINT64 size) +{ + if (m_ProgressBox != 0) + { + m_ProgressBox->SetTotal(size); + m_ProgressBox->PrintCompeteValue(0); + } + return S_OK; +} + +STDMETHODIMP CExtractCallBackImp::SetCompleted(const UINT64 *completeValue) +{ + if(WasEscPressed()) + return E_ABORT; + if (m_ProgressBox != 0 && completeValue != NULL) + m_ProgressBox->PrintCompeteValue(*completeValue); + return S_OK; +} + +STDMETHODIMP CExtractCallBackImp::AskOverwrite( + const wchar_t *existName, const FILETIME *existTime, const UINT64 *existSize, + const wchar_t *newName, const FILETIME *aNewTime, const UINT64 *newSize, + INT32 *answer) +{ + NOverwriteDialog::CFileInfo oldFileInfo, newFileInfo; + oldFileInfo.Time = *existTime; + oldFileInfo.SizeIsDefined = (existSize != NULL); + if (oldFileInfo.SizeIsDefined) + oldFileInfo.Size = *existSize; + oldFileInfo.Name = GetSystemString(existName, m_CodePage); + + + newFileInfo.Time = *aNewTime; + + newFileInfo.SizeIsDefined = (newSize != NULL); + if (newFileInfo.SizeIsDefined) + newFileInfo.Size = *newSize; + newFileInfo.Name = GetSystemString(newName, m_CodePage); + + NOverwriteDialog::NResult::EEnum result = + NOverwriteDialog::Execute(oldFileInfo, newFileInfo); + + switch(result) + { + case NOverwriteDialog::NResult::kCancel: + // *answer = NOverwriteAnswer::kCancel; + // break; + return E_ABORT; + case NOverwriteDialog::NResult::kNo: + *answer = NOverwriteAnswer::kNo; + break; + case NOverwriteDialog::NResult::kNoToAll: + *answer = NOverwriteAnswer::kNoToAll; + break; + case NOverwriteDialog::NResult::kYesToAll: + *answer = NOverwriteAnswer::kYesToAll; + break; + case NOverwriteDialog::NResult::kYes: + *answer = NOverwriteAnswer::kYes; + break; + case NOverwriteDialog::NResult::kAutoRename: + *answer = NOverwriteAnswer::kAutoRename; + break; + default: + throw 20413; + } + return S_OK; +} + +STDMETHODIMP CExtractCallBackImp::PrepareOperation(const wchar_t *name, INT32 /* askExtractMode */, const UINT64 * /* position */) +{ + m_CurrentFilePath = name; + return S_OK; +} + +STDMETHODIMP CExtractCallBackImp::MessageError(const wchar_t *message) +{ + AString s = UnicodeStringToMultiByte(message, CP_OEMCP); + if (g_StartupInfo.ShowMessage((const char *)s) == -1) + return E_ABORT; + return S_OK; +} + +STDMETHODIMP CExtractCallBackImp::SetOperationResult(INT32 operationResult, bool encrypted) +{ + switch(operationResult) + { + case NArchive::NExtract::NOperationResult::kOK: + break; + default: + { + UINT idMessage; + switch(operationResult) + { + case NArchive::NExtract::NOperationResult::kUnSupportedMethod: + idMessage = NMessageID::kExtractUnsupportedMethod; + break; + case NArchive::NExtract::NOperationResult::kCRCError: + idMessage = NMessageID::kExtractCRCFailed; + break; + case NArchive::NExtract::NOperationResult::kDataError: + idMessage = NMessageID::kExtractDataError; + break; + default: + return E_FAIL; + } + char buffer[512]; + sprintf(buffer, g_StartupInfo.GetMsgString(idMessage), + GetSystemString(m_CurrentFilePath, m_CodePage)); + if (g_StartupInfo.ShowMessage(buffer) == -1) + return E_ABORT; + } + } + return S_OK; +} + +extern HRESULT GetPassword(UString &password); + +STDMETHODIMP CExtractCallBackImp::CryptoGetTextPassword(BSTR *password) +{ + if (!m_PasswordIsDefined) + { + RINOK(GetPassword(m_Password)); + m_PasswordIsDefined = true; + } + CMyComBSTR tempName = m_Password; + *password = tempName.Detach(); + + return S_OK; +} diff --git a/CPP/7zip/UI/Far/ExtractEngine.h b/CPP/7zip/UI/Far/ExtractEngine.h new file mode 100755 index 00000000..57c04f76 --- /dev/null +++ b/CPP/7zip/UI/Far/ExtractEngine.h @@ -0,0 +1,68 @@ +// ExtractEngine.h + +#ifndef __EXTRACTENGINE_H +#define __EXTRACTENGINE_H + +#include "Common/MyCom.h" +#include "Common/String.h" + +#include "../../IPassword.h" +#include "../Agent/IFolderArchive.h" + +#include "ProgressBox.h" + +class CExtractCallBackImp: + public IFolderArchiveExtractCallback, + public ICryptoGetTextPassword, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP1(ICryptoGetTextPassword) + + // IProgress + STDMETHOD(SetTotal)(UINT64 size); + STDMETHOD(SetCompleted)(const UINT64 *completeValue); + + // IExtractCallBack + STDMETHOD(AskOverwrite)( + const wchar_t *existName, const FILETIME *existTime, const UINT64 *existSize, + const wchar_t *newName, const FILETIME *newTime, const UINT64 *newSize, + INT32 *result); + STDMETHOD (PrepareOperation)(const wchar_t *name, INT32 askExtractMode, const UINT64 *position); + + STDMETHOD(MessageError)(const wchar_t *message); + STDMETHOD(SetOperationResult)(INT32 resultEOperationResult, bool encrypted); + // ICryptoGetTextPassword + STDMETHOD(CryptoGetTextPassword)(BSTR *password); + +private: + UString m_CurrentFilePath; + + struct CProcessedFileInfo + { + FILETIME UTCLastWriteTime; + bool IsDirectory; + UINT32 Attributes; + } m_ProcessedFileInfo; + + CProgressBox *m_ProgressBox; + UINT m_CodePage; + + bool m_PasswordIsDefined; + UString m_Password; + + void CreateComplexDirectory(const UStringVector &dirPathParts); + /* + void GetPropertyValue(LPITEMIDLIST anItemIDList, PROPID aPropId, + PROPVARIANT *aValue); + bool IsEncrypted(LPITEMIDLIST anItemIDList); + */ + void AddErrorMessage(LPCTSTR message); +public: + ~CExtractCallBackImp(); + void Init(UINT codePage, + CProgressBox *progressBox, + bool passwordIsDefined, const UString &password); +}; + +#endif diff --git a/CPP/7zip/UI/Far/Far.def b/CPP/7zip/UI/Far/Far.def new file mode 100755 index 00000000..d96501e2 --- /dev/null +++ b/CPP/7zip/UI/Far/Far.def @@ -0,0 +1,20 @@ +; 7-ZipFar.def : Declares the module parameters for the DLL. + +LIBRARY "7-ZipFar" +DESCRIPTION '7-ZipFar Windows Dynamic Link Library' + +EXPORTS + SetStartupInfo = _SetStartupInfo@4 + OpenPlugin = _OpenPlugin@8 + OpenFilePlugin = _OpenFilePlugin@12 + ClosePlugin = _ClosePlugin@4 + GetFindData = _GetFindData@16 + FreeFindData = _FreeFindData@12 + SetDirectory = _SetDirectory@12 + GetPluginInfo = _GetPluginInfo@4 + Configure = _Configure@4 + GetOpenPluginInfo = _GetOpenPluginInfo@8 + GetFiles = _GetFiles@24 + PutFiles = _PutFiles@20 + DeleteFiles = _DeleteFiles@16 + ProcessKey = _ProcessKey@12 diff --git a/CPP/7zip/UI/Far/Far.dsp b/CPP/7zip/UI/Far/Far.dsp new file mode 100755 index 00000000..47c44c69 --- /dev/null +++ b/CPP/7zip/UI/Far/Far.dsp @@ -0,0 +1,561 @@ +# Microsoft Developer Studio Project File - Name="Far" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Far - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Far.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Far.mak" CFG="Far - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Far - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Far - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Far - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAR_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAR_EXPORTS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\Far\Plugins\7-Zip\7-ZipFar.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Far - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAR_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAR_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\Far\Plugins\7-Zip\7-ZipFar.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Far - Win32 Release" +# Name "Far - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\CLSIDConst.cpp +# End Source File +# Begin Source File + +SOURCE=.\Far.def +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "Plugin" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ExtractEngine.cpp +# End Source File +# Begin Source File + +SOURCE=.\ExtractEngine.h +# End Source File +# Begin Source File + +SOURCE=.\Main.cpp +# End Source File +# Begin Source File + +SOURCE=.\Messages.h +# End Source File +# Begin Source File + +SOURCE=.\OverwriteDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\OverwriteDialog.h +# End Source File +# Begin Source File + +SOURCE=.\Plugin.cpp +# End Source File +# Begin Source File + +SOURCE=.\Plugin.h +# End Source File +# Begin Source File + +SOURCE=.\PluginDelete.cpp +# End Source File +# Begin Source File + +SOURCE=.\PluginRead.cpp +# End Source File +# Begin Source File + +SOURCE=.\PluginWrite.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallback100.cpp +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallback100.h +# End Source File +# End Group +# Begin Group "Far" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\FarPlugin.h +# End Source File +# Begin Source File + +SOURCE=.\FarUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\FarUtils.h +# End Source File +# Begin Source File + +SOURCE=.\ProgressBox.cpp +# End Source File +# Begin Source File + +SOURCE=.\ProgressBox.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# End Group +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiverInfo.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiverInfo.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DirItem.h +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractMode.h +# End Source File +# Begin Source File + +SOURCE=..\Common\HandlerLoader.h +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.h +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateProduce.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateProduce.h +# End Source File +# Begin Source File + +SOURCE=..\Common\WorkDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\WorkDir.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ZipRegistry.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ZipRegistry.h +# End Source File +# End Group +# Begin Group "Agent" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Agent\Agent.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\Agent.h +# End Source File +# Begin Source File + +SOURCE=..\Agent\AgentOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\AgentProxy.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\AgentProxy.h +# End Source File +# Begin Source File + +SOURCE=..\Agent\IFolderArchive.h +# End Source File +# Begin Source File + +SOURCE=..\Agent\UpdateCallbackAgent.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\UpdateCallbackAgent.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "7-zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# End Target +# End Project diff --git a/CPP/7zip/UI/Far/Far.dsw b/CPP/7zip/UI/Far/Far.dsw new file mode 100755 index 00000000..f4ef0801 --- /dev/null +++ b/CPP/7zip/UI/Far/Far.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Far"=.\Far.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/UI/Far/FarPlugin.h b/CPP/7zip/UI/Far/FarPlugin.h new file mode 100755 index 00000000..f61bbcb4 --- /dev/null +++ b/CPP/7zip/UI/Far/FarPlugin.h @@ -0,0 +1,577 @@ +// FarPlugin.h + +#ifndef __FARPLUGIN_H +#define __FARPLUGIN_H + +#if defined(__BORLANDC__) && (__BORLANDC <= 0x520) + #pragma option -a1 +#elif defined(__GNUC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1100)) + #pragma pack(1) +#else + #pragma pack(push,1) + #if _MSC_VER + #define _export + #endif +#endif + +#define NM 260 + +struct FarFindData +{ + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + DWORD dwReserved0; + DWORD dwReserved1; + char cFileName[ MAX_PATH ]; + char cAlternateFileName[ 14 ]; +}; + +struct PluginPanelItem +{ + FarFindData FindData; + DWORD PackSizeHigh; + DWORD PackSize; + DWORD Flags; + DWORD NumberOfLinks; + char *Description; + char *Owner; + char **CustomColumnData; + int CustomColumnNumber; + DWORD UserData; + DWORD Reserved[3]; +}; + +#define PPIF_PROCESSDESCR 0x80000000 +#define PPIF_SELECTED 0x40000000 +#define PPIF_USERDATA 0x20000000 + +enum { + FMENU_SHOWAMPERSAND=1, + FMENU_WRAPMODE=2, + FMENU_AUTOHIGHLIGHT=4, + FMENU_REVERSEAUTOHIGHLIGHT=8 +}; + + +typedef int (WINAPI *FARAPIMENU)( + int PluginNumber, + int X, + int Y, + int MaxHeight, + unsigned int Flags, + char *Title, + char *Bottom, + char *HelpTopic, + int *BreakKeys, + int *BreakCode, + struct FarMenuItem *Item, + int ItemsNumber +); + +typedef int (WINAPI *FARAPIDIALOG)( + int PluginNumber, + int X1, + int Y1, + int X2, + int Y2, + char *HelpTopic, + struct FarDialogItem *Item, + int ItemsNumber +); + +enum { + FMSG_WARNING=1, + FMSG_ERRORTYPE=2, + FMSG_KEEPBACKGROUND=4, + FMSG_DOWN=8, + FMSG_LEFTALIGN=16 +}; + +typedef int (WINAPI *FARAPIMESSAGE)( + int PluginNumber, + unsigned int Flags, + char *HelpTopic, + char **Items, + int ItemsNumber, + int ButtonsNumber +); + +typedef char* (WINAPI *FARAPIGETMSG)( + int PluginNumber, + int MsgId +); + + +enum DialogItemTypes { + DI_TEXT, + DI_VTEXT, + DI_SINGLEBOX, + DI_DOUBLEBOX, + DI_EDIT, + DI_PSWEDIT, + DI_FIXEDIT, + DI_BUTTON, + DI_CHECKBOX, + DI_RADIOBUTTON +}; + +enum FarDialogItemFlags { + DIF_COLORMASK = 0xff, + DIF_SETCOLOR = 0x100, + DIF_BOXCOLOR = 0x200, + DIF_GROUP = 0x400, + DIF_LEFTTEXT = 0x800, + DIF_MOVESELECT = 0x1000, + DIF_SHOWAMPERSAND = 0x2000, + DIF_CENTERGROUP = 0x4000, + DIF_NOBRACKETS = 0x8000, + DIF_SEPARATOR = 0x10000, + DIF_EDITOR = 0x20000, + DIF_HISTORY = 0x40000 +}; + +struct FarDialogItem +{ + int Type; + int X1,Y1,X2,Y2; + int Focus; + union + { + int Selected; + const char *History; + const char *Mask; + struct FarList *ListItems; + int ListPos; + CHAR_INFO *VBuf; + }; + unsigned int Flags; + int DefaultButton; + char Data[512]; +}; + + +struct FarMenuItem +{ + char Text[128]; + int Selected; + int Checked; + int Separator; +}; + + +enum {FCTL_CLOSEPLUGIN,FCTL_GETPANELINFO,FCTL_GETANOTHERPANELINFO, + FCTL_UPDATEPANEL,FCTL_UPDATEANOTHERPANEL, + FCTL_REDRAWPANEL,FCTL_REDRAWANOTHERPANEL, + FCTL_SETANOTHERPANELDIR,FCTL_GETCMDLINE,FCTL_SETCMDLINE, + FCTL_SETSELECTION,FCTL_SETANOTHERSELECTION, + FCTL_SETVIEWMODE,FCTL_SETANOTHERVIEWMODE,FCTL_INSERTCMDLINE, + FCTL_SETUSERSCREEN,FCTL_SETPANELDIR,FCTL_SETCMDLINEPOS, + FCTL_GETCMDLINEPOS +}; + +enum {PTYPE_FILEPANEL,PTYPE_TREEPANEL,PTYPE_QVIEWPANEL,PTYPE_INFOPANEL}; + +struct PanelInfo +{ + int PanelType; + int Plugin; + RECT PanelRect; + struct PluginPanelItem *PanelItems; + int ItemsNumber; + struct PluginPanelItem *SelectedItems; + int SelectedItemsNumber; + int CurrentItem; + int TopPanelItem; + int Visible; + int Focus; + int ViewMode; + char ColumnTypes[80]; + char ColumnWidths[80]; + char CurDir[NM]; + int ShortNames; + int SortMode; + DWORD Reserved[2]; +}; + + +struct PanelRedrawInfo +{ + int CurrentItem; + int TopPanelItem; +}; + + +typedef int (WINAPI *FARAPICONTROL)( + HANDLE hPlugin, + int Command, + void *Param +); + +typedef HANDLE (WINAPI *FARAPISAVESCREEN)(int X1,int Y1,int X2,int Y2); + +typedef void (WINAPI *FARAPIRESTORESCREEN)(HANDLE hScreen); + +typedef int (WINAPI *FARAPIGETDIRLIST)( + char *Dir, + struct PluginPanelItem **pPanelItem, + int *pItemsNumber +); + +typedef int (WINAPI *FARAPIGETPLUGINDIRLIST)( + int PluginNumber, + HANDLE hPlugin, + char *Dir, + struct PluginPanelItem **pPanelItem, + int *pItemsNumber +); + +typedef void (WINAPI *FARAPIFREEDIRLIST)(struct PluginPanelItem *PanelItem); + +enum VIEWER_FLAGS { + VF_NONMODAL=1,VF_DELETEONCLOSE=2 +}; + +typedef int (WINAPI *FARAPIVIEWER)( + char *FileName, + char *Title, + int X1, + int Y1, + int X2, + int Y2, + DWORD Flags +); + +typedef int (WINAPI *FARAPIEDITOR)( + char *FileName, + char *Title, + int X1, + int Y1, + int X2, + int Y2, + DWORD Flags, + int StartLine, + int StartChar +); + +typedef int (WINAPI *FARAPICMPNAME)( + char *Pattern, + char *String, + int SkipPath +); + + +#define FCT_DETECT 0x40000000 + +struct CharTableSet +{ + char DecodeTable[256]; + char EncodeTable[256]; + char UpperTable[256]; + char LowerTable[256]; + char TableName[128]; +}; + +typedef int (WINAPI *FARAPICHARTABLE)( + int Command, + char *Buffer, + int BufferSize +); + +typedef void (WINAPI *FARAPITEXT)( + int X, + int Y, + int Color, + char *Str +); + + +typedef int (WINAPI *FARAPIEDITORCONTROL)( + int Command, + void *Param +); + + +enum EDITOR_EVENTS { + EE_READ,EE_SAVE,EE_REDRAW,EE_CLOSE +}; + +enum EDITOR_CONTROL_COMMANDS { + ECTL_GETSTRING,ECTL_SETSTRING,ECTL_INSERTSTRING,ECTL_DELETESTRING, + ECTL_DELETECHAR,ECTL_INSERTTEXT,ECTL_GETINFO,ECTL_SETPOSITION, + ECTL_SELECT,ECTL_REDRAW,ECTL_EDITORTOOEM,ECTL_OEMTOEDITOR, + ECTL_TABTOREAL,ECTL_REALTOTAB,ECTL_EXPANDTABS,ECTL_SETTITLE, + ECTL_READINPUT,ECTL_PROCESSINPUT,ECTL_ADDCOLOR,ECTL_GETCOLOR +}; + + +struct EditorGetString +{ + int StringNumber; + char *StringText; + char *StringEOL; + int StringLength; + int SelStart; + int SelEnd; +}; + + +struct EditorSetString +{ + int StringNumber; + char *StringText; + char *StringEOL; + int StringLength; +}; + + +enum EDITOR_OPTIONS { + EOPT_EXPANDTABS=1,EOPT_PERSISTENTBLOCKS=2,EOPT_DELREMOVESBLOCKS=4, + EOPT_AUTOINDENT=8,EOPT_SAVEFILEPOSITION=16,EOPT_AUTODETECTTABLE=32, + EOPT_CURSORBEYONDEOL=64 +}; + + +enum EDITOR_BLOCK_TYPES { + BTYPE_NONE,BTYPE_STREAM,BTYPE_COLUMN +}; + + +struct EditorInfo +{ + int EditorID; + char *FileName; + int WindowSizeX; + int WindowSizeY; + int TotalLines; + int CurLine; + int CurPos; + int CurTabPos; + int TopScreenLine; + int LeftPos; + int Overtype; + int BlockType; + int BlockStartLine; + int AnsiMode; + int TableNum; + DWORD Options; + int TabSize; + DWORD Reserved[8]; +}; + + +struct EditorSetPosition +{ + int CurLine; + int CurPos; + int CurTabPos; + int TopScreenLine; + int LeftPos; + int Overtype; +}; + + +struct EditorSelect +{ + int BlockType; + int BlockStartLine; + int BlockStartPos; + int BlockWidth; + int BlockHeight; +}; + + +struct EditorConvertText +{ + char *Text; + int TextLength; +}; + + +struct EditorConvertPos +{ + int StringNumber; + int SrcPos; + int DestPos; +}; + + +struct EditorColor +{ + int StringNumber; + int ColorItem; + int StartPos; + int EndPos; + int Color; +}; + + +struct PluginStartupInfo +{ + int StructSize; + char ModuleName[NM]; + int ModuleNumber; + char *RootKey; + FARAPIMENU Menu; + FARAPIDIALOG Dialog; + FARAPIMESSAGE Message; + FARAPIGETMSG GetMsg; + FARAPICONTROL Control; + FARAPISAVESCREEN SaveScreen; + FARAPIRESTORESCREEN RestoreScreen; + FARAPIGETDIRLIST GetDirList; + FARAPIGETPLUGINDIRLIST GetPluginDirList; + FARAPIFREEDIRLIST FreeDirList; + FARAPIVIEWER Viewer; + FARAPIEDITOR Editor; + FARAPICMPNAME CmpName; + FARAPICHARTABLE CharTable; + FARAPITEXT Text; + FARAPIEDITORCONTROL EditorControl; +}; + + +enum PLUGIN_FLAGS { + PF_PRELOAD = 0x0001, + PF_DISABLEPANELS = 0x0002, + PF_EDITOR = 0x0004, + PF_VIEWER = 0x0008 +}; + + +struct PluginInfo +{ + int StructSize; + DWORD Flags; + char **DiskMenuStrings; + int *DiskMenuNumbers; + int DiskMenuStringsNumber; + char **PluginMenuStrings; + int PluginMenuStringsNumber; + char **PluginConfigStrings; + int PluginConfigStringsNumber; + char *CommandPrefix; +}; + + +struct InfoPanelLine +{ + char Text[80]; + char Data[80]; + int Separator; +}; + + +struct PanelMode +{ + char *ColumnTypes; + char *ColumnWidths; + char **ColumnTitles; + int FullScreen; + int DetailedStatus; + int AlignExtensions; + int CaseConversion; + char *StatusColumnTypes; + char *StatusColumnWidths; + DWORD Reserved[2]; +}; + + +enum OPENPLUGININFO_FLAGS { + OPIF_USEFILTER = 0x0001, + OPIF_USESORTGROUPS = 0x0002, + OPIF_USEHIGHLIGHTING = 0x0004, + OPIF_ADDDOTS = 0x0008, + OPIF_RAWSELECTION = 0x0010, + OPIF_REALNAMES = 0x0020, + OPIF_SHOWNAMESONLY = 0x0040, + OPIF_SHOWRIGHTALIGNNAMES = 0x0080, + OPIF_SHOWPRESERVECASE = 0x0100, + OPIF_FINDFOLDERS = 0x0200, + OPIF_COMPAREFATTIME = 0x0400, + OPIF_EXTERNALGET = 0x0800, + OPIF_EXTERNALPUT = 0x1000, + OPIF_EXTERNALDELETE = 0x2000, + OPIF_EXTERNALMKDIR = 0x4000, + OPIF_USEATTRHIGHLIGHTING = 0x8000 +}; + + +enum OPENPLUGININFO_SORTMODES { + SM_DEFAULT,SM_UNSORTED,SM_NAME,SM_EXT,SM_MTIME,SM_CTIME, + SM_ATIME,SM_SIZE,SM_DESCR,SM_OWNER,SM_COMPRESSEDSIZE,SM_NUMLINKS +}; + + +struct KeyBarTitles +{ + char *Titles[12]; + char *CtrlTitles[12]; + char *AltTitles[12]; + char *ShiftTitles[12]; +}; + + +struct OpenPluginInfo +{ + int StructSize; + DWORD Flags; + char *HostFile; + char *CurDir; + char *Format; + char *PanelTitle; + struct InfoPanelLine *InfoLines; + int InfoLinesNumber; + char **DescrFiles; + int DescrFilesNumber; + struct PanelMode *PanelModesArray; + int PanelModesNumber; + int StartPanelMode; + int StartSortMode; + int StartSortOrder; + struct KeyBarTitles *KeyBar; + char *ShortcutData; +}; + +enum { + OPEN_DISKMENU, + OPEN_PLUGINSMENU, + OPEN_FINDLIST, + OPEN_SHORTCUT, + OPEN_COMMANDLINE, + OPEN_EDITOR, + OPEN_VIEWER +}; + +enum {PKF_CONTROL=1,PKF_ALT=2,PKF_SHIFT=4}; + +enum FAR_EVENTS { + FE_CHANGEVIEWMODE, + FE_REDRAW, + FE_IDLE, + FE_CLOSE, + FE_BREAK, + FE_COMMAND +}; + +enum OPERATION_MODES { + OPM_SILENT=1, + OPM_FIND=2, + OPM_VIEW=4, + OPM_EDIT=8, + OPM_TOPLEVEL=16, + OPM_DESCR=32 +}; + +#if defined(__BORLANDC__) && (__BORLANDC <= 0x520) + #pragma option -a. +#elif defined(__GNUC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1100)) + #pragma pack() +#else + #pragma pack(pop) +#endif + +#endif diff --git a/CPP/7zip/UI/Far/FarUtils.cpp b/CPP/7zip/UI/Far/FarUtils.cpp new file mode 100755 index 00000000..abbb6817 --- /dev/null +++ b/CPP/7zip/UI/Far/FarUtils.cpp @@ -0,0 +1,416 @@ +// FarUtils.cpp + +#include "StdAfx.h" + +#include "FarUtils.h" +#include "Common/DynamicBuffer.h" +#include "Common/StringConvert.h" +#include "Windows/Defs.h" +#include "Windows/Console.h" +#include "Windows/Error.h" + +using namespace NWindows; + +namespace NFar { + +CStartupInfo g_StartupInfo; + +void CStartupInfo::Init(const PluginStartupInfo &pluginStartupInfo, + const CSysString &pliginNameForRegestry) +{ + m_Data = pluginStartupInfo; + m_RegistryPath = pluginStartupInfo.RootKey; + m_RegistryPath += '\\'; + m_RegistryPath += pliginNameForRegestry; +} + +const char *CStartupInfo::GetMsgString(int messageId) +{ + return (const char*)m_Data.GetMsg(m_Data.ModuleNumber, messageId); +} + +int CStartupInfo::ShowMessage(unsigned int flags, + const char *helpTopic, const char **items, int numItems, int numButtons) +{ + return m_Data.Message(m_Data.ModuleNumber, flags, (char *)helpTopic, + (char **)items, numItems, numButtons); +} + +namespace NMessageID +{ + enum + { + kOk, + kCancel, + kWarning, + kError + }; +} + +int CStartupInfo::ShowMessage(const char *message) +{ + const char *messagesItems[]= { GetMsgString(NMessageID::kError), message, + GetMsgString(NMessageID::kOk) }; + return ShowMessage(FMSG_WARNING, NULL, messagesItems, + sizeof(messagesItems) / sizeof(messagesItems[0]), 1); +} + +int CStartupInfo::ShowMessage(int messageId) +{ + return ShowMessage(GetMsgString(messageId)); +} + +int CStartupInfo::ShowDialog(int X1, int Y1, int X2, int Y2, + const char *helpTopic, struct FarDialogItem *items, int numItems) +{ + return m_Data.Dialog(m_Data.ModuleNumber, X1, Y1, X2, Y2, (char *)helpTopic, + items, numItems); +} + +int CStartupInfo::ShowDialog(int sizeX, int sizeY, + const char *helpTopic, struct FarDialogItem *items, int numItems) +{ + return ShowDialog(-1, -1, sizeX, sizeY, helpTopic, items, numItems); +} + +inline static BOOL GetBOOLValue(bool v) { return (v? TRUE: FALSE); } + +void CStartupInfo::InitDialogItems(const CInitDialogItem *srcItems, + FarDialogItem *destItems, int numItems) +{ + for (int i = 0; i < numItems; i++) + { + const CInitDialogItem &srcItem = srcItems[i]; + FarDialogItem &destItem = destItems[i]; + + destItem.Type = srcItem.Type; + destItem.X1 = srcItem.X1; + destItem.Y1 = srcItem.Y1; + destItem.X2 = srcItem.X2; + destItem.Y2 = srcItem.Y2; + destItem.Focus = GetBOOLValue(srcItem.Focus); + if(srcItem.HistoryName != NULL) + destItem.History = srcItem.HistoryName; + else + destItem.Selected = GetBOOLValue(srcItem.Selected); + destItem.Flags = srcItem.Flags; + destItem.DefaultButton = GetBOOLValue(srcItem.DefaultButton); + + if(srcItem.DataMessageId < 0) + MyStringCopy(destItem.Data, srcItem.DataString); + else + MyStringCopy(destItem.Data, GetMsgString(srcItem.DataMessageId)); + + /* + if ((unsigned int)Init[i].Data < 0xFFF) + MyStringCopy(destItem.Data, GetMsg((unsigned int)srcItem.Data)); + else + MyStringCopy(destItem.Data,srcItem.Data); + */ + } +} + +// -------------------------------------------- + +HANDLE CStartupInfo::SaveScreen(int X1, int Y1, int X2, int Y2) +{ + return m_Data.SaveScreen(X1, Y1, X2, Y2); +} + +HANDLE CStartupInfo::SaveScreen() +{ + return SaveScreen(0, 0, -1, -1); +} + +void CStartupInfo::RestoreScreen(HANDLE handle) +{ + m_Data.RestoreScreen(handle); +} + +const char kRegestryKeyDelimiter = '\''; + +CSysString CStartupInfo::GetFullKeyName(const CSysString &keyName) const +{ + return (keyName.IsEmpty()) ? m_RegistryPath: + (m_RegistryPath + kRegestryKeyDelimiter + keyName); +} + + +LONG CStartupInfo::CreateRegKey(HKEY parentKey, + const CSysString &keyName, NRegistry::CKey &destKey) const +{ + return destKey.Create(parentKey, GetFullKeyName(keyName)); +} + +LONG CStartupInfo::OpenRegKey(HKEY parentKey, + const CSysString &keyName, NRegistry::CKey &destKey) const +{ + return destKey.Open(parentKey, GetFullKeyName(keyName)); +} + +void CStartupInfo::SetRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, LPCTSTR value) const +{ + NRegistry::CKey regKey; + CreateRegKey(parentKey, keyName, regKey); + regKey.SetValue(valueName, value); +} + +void CStartupInfo::SetRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, UINT32 value) const +{ + NRegistry::CKey regKey; + CreateRegKey(parentKey, keyName, regKey); + regKey.SetValue(valueName, value); +} + +void CStartupInfo::SetRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, bool value) const +{ + NRegistry::CKey regKey; + CreateRegKey(parentKey, keyName, regKey); + regKey.SetValue(valueName, value); +} + +CSysString CStartupInfo::QueryRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, const CSysString &valueDefault) const +{ + NRegistry::CKey regKey; + if (OpenRegKey(parentKey, keyName, regKey) != ERROR_SUCCESS) + return valueDefault; + + CSysString value; + if(regKey.QueryValue(valueName, value) != ERROR_SUCCESS) + return valueDefault; + + return value; +} + +UINT32 CStartupInfo::QueryRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, UINT32 valueDefault) const +{ + NRegistry::CKey regKey; + if (OpenRegKey(parentKey, keyName, regKey) != ERROR_SUCCESS) + return valueDefault; + + UINT32 value; + if(regKey.QueryValue(valueName, value) != ERROR_SUCCESS) + return valueDefault; + + return value; +} + +bool CStartupInfo::QueryRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, bool valueDefault) const +{ + NRegistry::CKey regKey; + if (OpenRegKey(parentKey, keyName, regKey) != ERROR_SUCCESS) + return valueDefault; + + bool value; + if(regKey.QueryValue(valueName, value) != ERROR_SUCCESS) + return valueDefault; + + return value; +} + +bool CStartupInfo::Control(HANDLE pluginHandle, int command, void *param) +{ + return BOOLToBool(m_Data.Control(pluginHandle, command, param)); +} + +bool CStartupInfo::ControlRequestActivePanel(int command, void *param) +{ + return Control(INVALID_HANDLE_VALUE, command, param); +} + +bool CStartupInfo::ControlGetActivePanelInfo(PanelInfo &panelInfo) +{ + return ControlRequestActivePanel(FCTL_GETPANELINFO, &panelInfo); +} + +bool CStartupInfo::ControlSetSelection(const PanelInfo &panelInfo) +{ + return ControlRequestActivePanel(FCTL_SETSELECTION, (void *)&panelInfo); +} + +bool CStartupInfo::ControlGetActivePanelCurrentItemInfo( + PluginPanelItem &pluginPanelItem) +{ + PanelInfo panelInfo; + if(!ControlGetActivePanelInfo(panelInfo)) + return false; + if(panelInfo.ItemsNumber <= 0) + throw "There are no items"; + pluginPanelItem = panelInfo.PanelItems[panelInfo.CurrentItem]; + return true; +} + +bool CStartupInfo::ControlGetActivePanelSelectedOrCurrentItems( + CObjectVector &pluginPanelItems) +{ + pluginPanelItems.Clear(); + PanelInfo panelInfo; + if(!ControlGetActivePanelInfo(panelInfo)) + return false; + if(panelInfo.ItemsNumber <= 0) + throw "There are no items"; + if (panelInfo.SelectedItemsNumber == 0) + pluginPanelItems.Add(panelInfo.PanelItems[panelInfo.CurrentItem]); + else + for (int i = 0; i < panelInfo.SelectedItemsNumber; i++) + pluginPanelItems.Add(panelInfo.SelectedItems[i]); + return true; +} + +bool CStartupInfo::ControlClearPanelSelection() +{ + PanelInfo panelInfo; + if(!ControlGetActivePanelInfo(panelInfo)) + return false; + for (int i = 0; i < panelInfo.ItemsNumber; i++) + panelInfo.PanelItems[i].Flags &= ~PPIF_SELECTED; + return ControlSetSelection(panelInfo); +} + +//////////////////////////////////////////////// +// menu function + +int CStartupInfo::Menu( + int x, + int y, + int maxHeight, + unsigned int flags, + const char *title, + const char *aBottom, + const char *helpTopic, + int *breakKeys, + int *breakCode, + struct FarMenuItem *items, + int numItems) +{ + return m_Data.Menu(m_Data.ModuleNumber, x, y, maxHeight, flags, (char *)title, + (char *)aBottom, (char *)helpTopic, breakKeys, breakCode, items, numItems); +} + +int CStartupInfo::Menu( + unsigned int flags, + const char *title, + const char *helpTopic, + struct FarMenuItem *items, + int numItems) +{ + return Menu(-1, -1, 0, flags, title, NULL, helpTopic, NULL, + NULL, items, numItems); +} + +int CStartupInfo::Menu( + unsigned int flags, + const char *title, + const char *helpTopic, + const CSysStringVector &items, + int selectedItem) +{ + CRecordVector farMenuItems; + for(int i = 0; i < items.Size(); i++) + { + FarMenuItem item; + item.Checked = 0; + item.Separator = 0; + item.Selected = (i == selectedItem); + AString reducedString = items[i].Left(sizeof(item.Text) / sizeof(item.Text[0]) - 1); + MyStringCopy(item.Text, (const char *)reducedString); + farMenuItems.Add(item); + } + return Menu(flags, title, helpTopic, &farMenuItems.Front(), farMenuItems.Size()); +} + + +////////////////////////////////// +// CScreenRestorer + +CScreenRestorer::~CScreenRestorer() +{ + Restore(); +} +void CScreenRestorer::Save() +{ + if(m_Saved) + return; + m_HANDLE = g_StartupInfo.SaveScreen(); + m_Saved = true; +} + +void CScreenRestorer::Restore() +{ + if(m_Saved) + { + g_StartupInfo.RestoreScreen(m_HANDLE); + m_Saved = false; + } +}; + +static AString DWORDToString(DWORD number) +{ + char buffer[32]; + ultoa(number, buffer, 10); + return buffer; +} + +void PrintErrorMessage(const char *message, int code) +{ + CSysString tmp = message; + tmp += " #"; + tmp += DWORDToString(code); + g_StartupInfo.ShowMessage(tmp); +} + +void PrintErrorMessage(const char *message, const char *text) +{ + CSysString tmp = message; + tmp += ": "; + tmp += text; + g_StartupInfo.ShowMessage(tmp); +} + +bool WasEscPressed() +{ + NConsole::CIn inConsole; + HANDLE handle = ::GetStdHandle(STD_INPUT_HANDLE); + if(handle == INVALID_HANDLE_VALUE) + return true; + inConsole.Attach(handle); + for (;;) + { + DWORD numEvents; + if(!inConsole.GetNumberOfEvents(numEvents)) + return true; + if(numEvents == 0) + return false; + + INPUT_RECORD event; + if(!inConsole.ReadEvent(event, numEvents)) + return true; + if (event.EventType == KEY_EVENT && + event.Event.KeyEvent.bKeyDown && + event.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) + return true; + } +} + +void ShowErrorMessage(DWORD errorCode) +{ + AString message; + NError::MyFormatMessage(errorCode, message); + message.Replace("\x0D", ""); + message.Replace("\x0A", " "); + g_StartupInfo.ShowMessage(SystemStringToOemString(message)); + +} + +void ShowLastErrorMessage() +{ + ShowErrorMessage(::GetLastError()); +} + +} diff --git a/CPP/7zip/UI/Far/FarUtils.h b/CPP/7zip/UI/Far/FarUtils.h new file mode 100755 index 00000000..4fba193d --- /dev/null +++ b/CPP/7zip/UI/Far/FarUtils.h @@ -0,0 +1,185 @@ +// FarUtils.h + +#ifndef __FARUTILS_H +#define __FARUTILS_H + +#include "FarPlugin.h" +#include "Common/String.h" +#include "Common/Vector.h" +#include "Windows/Registry.h" + +namespace NFar { + +namespace NFileOperationReturnCode +{ + enum EEnum + { + kInterruptedByUser = -1, + kError = 0, + kSuccess = 1 + }; +} + +namespace NEditorReturnCode +{ + enum EEnum + { + kOpenError = 0, + kFileWasChanged = 1, + kFileWasNotChanged = 2, + kInterruptedByUser = 3 + }; +} + +struct CInitDialogItem +{ + DialogItemTypes Type; + int X1,Y1,X2,Y2; + bool Focus; + bool Selected; + unsigned int Flags; //FarDialogItemFlags Flags; + bool DefaultButton; + int DataMessageId; + const char *DataString; + const char *HistoryName; + // void InitToFarDialogItem(struct FarDialogItem &anItemDest); +}; + +class CStartupInfo +{ + PluginStartupInfo m_Data; + CSysString m_RegistryPath; + + CSysString GetFullKeyName(const CSysString &keyName) const; + LONG CreateRegKey(HKEY parentKey, + const CSysString &keyName, NWindows::NRegistry::CKey &destKey) const; + LONG OpenRegKey(HKEY parentKey, + const CSysString &keyName, NWindows::NRegistry::CKey &destKey) const; + +public: + void Init(const PluginStartupInfo &pluginStartupInfo, + const CSysString &pliginNameForRegestry); + const char *GetMsgString(int messageId); + int ShowMessage(unsigned int flags, const char *helpTopic, + const char **items, int numItems, int numButtons); + int ShowMessage(const char *message); + int ShowMessage(int messageId); + + int ShowDialog(int X1, int Y1, int X2, int Y2, + const char *helpTopic, struct FarDialogItem *items, int numItems); + int ShowDialog(int sizeX, int sizeY, + const char *helpTopic, struct FarDialogItem *items, int numItems); + + void InitDialogItems(const CInitDialogItem *srcItems, + FarDialogItem *destItems, int numItems); + + HANDLE SaveScreen(int X1, int Y1, int X2, int Y2); + HANDLE SaveScreen(); + void RestoreScreen(HANDLE handle); + + void SetRegKeyValue(HKEY parentKey, const CSysString &keyName, + const LPCTSTR valueName, LPCTSTR value) const; + void SetRegKeyValue(HKEY hRoot, const CSysString &keyName, + const LPCTSTR valueName, UINT32 value) const; + void SetRegKeyValue(HKEY hRoot, const CSysString &keyName, + const LPCTSTR valueName, bool value) const; + + CSysString QueryRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, const CSysString &valueDefault) const; + + UINT32 QueryRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, UINT32 valueDefault) const; + + bool QueryRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, bool valueDefault) const; + + bool Control(HANDLE plugin, int command, void *param); + bool ControlRequestActivePanel(int command, void *param); + bool ControlGetActivePanelInfo(PanelInfo &panelInfo); + bool ControlSetSelection(const PanelInfo &panelInfo); + bool ControlGetActivePanelCurrentItemInfo(PluginPanelItem &pluginPanelItem); + bool ControlGetActivePanelSelectedOrCurrentItems( + CObjectVector &pluginPanelItems); + + bool ControlClearPanelSelection(); + + int Menu( + int x, + int y, + int maxHeight, + unsigned int flags, + const char *title, + const char *aBottom, + const char *helpTopic, + int *breakKeys, + int *breakCode, + FarMenuItem *items, + int numItems); + int Menu( + unsigned int flags, + const char *title, + const char *helpTopic, + FarMenuItem *items, + int numItems); + + int Menu( + unsigned int flags, + const char *title, + const char *helpTopic, + const CSysStringVector &items, + int selectedItem); + + int Editor(const char *fileName, const char *title, + int X1, int Y1, int X2, int Y2, DWORD flags, int startLine, int startChar) + { return m_Data.Editor((char *)fileName, (char *)title, X1, Y1, X2, Y2, + flags, startLine, startChar); } + int Editor(const char *fileName) + { return Editor(fileName, NULL, 0, 0, -1, -1, 0, -1, -1); } + + int Viewer(const char *fileName, const char *title, + int X1, int Y1, int X2, int Y2, DWORD flags) + { return m_Data.Viewer((char *)fileName, (char *)title, X1, Y1, X2, Y2, flags); } + int Viewer(const char *fileName) + { return Viewer(fileName, NULL, 0, 0, -1, -1, VF_NONMODAL); } + +}; + +class CScreenRestorer +{ + bool m_Saved; + HANDLE m_HANDLE; +public: + CScreenRestorer(): m_Saved(false){}; + ~CScreenRestorer(); + void Save(); + void Restore(); +}; + + +extern CStartupInfo g_StartupInfo; + +void PrintErrorMessage(const char *message, int code); +void PrintErrorMessage(const char *message, const char *aText); + +#define MY_TRY_BEGIN try\ + { + +#define MY_TRY_END1(x) }\ + catch(int n) { PrintErrorMessage(x, n); return; }\ + catch(const CSysString &s) { PrintErrorMessage(x, s); return; }\ + catch(const char *s) { PrintErrorMessage(x, s); return; }\ + catch(...) { g_StartupInfo.ShowMessage(x); return; } + +#define MY_TRY_END2(x, y) }\ + catch(int n) { PrintErrorMessage(x, n); return y; }\ + catch(const CSysString &s) { PrintErrorMessage(x, s); return y; }\ + catch(const char *s) { PrintErrorMessage(x, s); return y; }\ + catch(...) { g_StartupInfo.ShowMessage(x); return y; } + +bool WasEscPressed(); +void ShowErrorMessage(DWORD errorCode); +void ShowLastErrorMessage(); + +} + +#endif diff --git a/CPP/7zip/UI/Far/Main.cpp b/CPP/7zip/UI/Far/Main.cpp new file mode 100755 index 00000000..a7994b6d --- /dev/null +++ b/CPP/7zip/UI/Far/Main.cpp @@ -0,0 +1,622 @@ +// Test Align for updating !!!!!!!!!!!!!!!!!! + +#include "StdAfx.h" + +// #include +#include + +#include "Plugin.h" + +#include "Common/Wildcard.h" +#include "Common/DynamicBuffer.h" +#include "Common/StringConvert.h" +#include "Common/Defs.h" + +#include "Windows/FileFind.h" +#include "Windows/FileIO.h" +#include "Windows/FileDir.h" +#include "Windows/Defs.h" + +#include "../../IPassword.h" +#include "../../Common/FileStreams.h" + +#include "../Common/DefaultName.h" +#include "../Common/OpenArchive.h" +#include "../Agent/Agent.h" + +#include "ProgressBox.h" +#include "FarUtils.h" +#include "Messages.h" + +using namespace NWindows; +using namespace NFar; + +static const char *kCommandPrefix = "7-zip"; + +static const int kDescriptionMaxSize = 256; + +static const char *kRegisrtryMainKeyName = ""; + +static const char *kRegisrtryValueNameEnabled = "UsedByDefault3"; +static bool kPluginEnabledDefault = true; + +static const char *kHelpTopicConfig = "Config"; + +extern "C" +{ + void WINAPI SetStartupInfo(struct PluginStartupInfo *info); + HANDLE WINAPI OpenFilePlugin(char *name, const unsigned char *Data, + unsigned int DataSize); + HANDLE WINAPI OpenPlugin(int openFrom, int item); + void WINAPI ClosePlugin(HANDLE plugin); + int WINAPI GetFindData(HANDLE plugin, struct PluginPanelItem **panelItems, + int *itemsNumber, int OpMode); + void WINAPI FreeFindData(HANDLE plugin, struct PluginPanelItem *panelItems, + int itemsNumber); + int WINAPI GetFiles(HANDLE plugin, struct PluginPanelItem *panelItems, + int itemsNumber, int move, char *destPath, int opMode); + int WINAPI SetDirectory(HANDLE plugin, char *dir, int opMode); + void WINAPI GetPluginInfo(struct PluginInfo *info); + int WINAPI Configure(int itemNumber); + void WINAPI GetOpenPluginInfo(HANDLE plugin, struct OpenPluginInfo *info); + int WINAPI PutFiles(HANDLE plugin, struct PluginPanelItem *panelItems, + int itemsNumber, int move, int opMode); + int WINAPI DeleteFiles(HANDLE plugin, PluginPanelItem *panelItems, + int itemsNumber, int opMode); + int WINAPI ProcessKey(HANDLE plugin, int key, unsigned int controlState); +}; + +HINSTANCE g_hInstance; +#ifndef _UNICODE +bool g_IsNT = false; +static bool IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); +} +#endif + +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + g_hInstance = hInstance; + #ifndef _UNICODE + g_IsNT = IsItWindowsNT(); + #endif + } + return TRUE; +} + +static struct COptions +{ + bool Enabled; +} g_Options; + +static const char *kPliginNameForRegestry = "7-ZIP"; + +// #define MY_TRY_BEGIN MY_TRY_BEGIN NCOM::CComInitializer aComInitializer; + +void WINAPI SetStartupInfo(struct PluginStartupInfo *info) +{ + MY_TRY_BEGIN; + g_StartupInfo.Init(*info, kPliginNameForRegestry); + g_Options.Enabled = g_StartupInfo.QueryRegKeyValue( + HKEY_CURRENT_USER, kRegisrtryMainKeyName, + kRegisrtryValueNameEnabled, kPluginEnabledDefault); + MY_TRY_END1("SetStartupInfo"); +} + +class COpenArchiveCallback: + public IArchiveOpenCallback, + public IArchiveOpenVolumeCallback, + public IProgress, + public ICryptoGetTextPassword, + public CMyUnknownImp +{ + DWORD m_StartTickValue; + bool m_MessageBoxIsShown; + CMessageBox *m_MessageBox; + UINT64 m_NumFiles; + UINT64 m_NumFilesMax; + UINT64 m_NumFilesPrev; + bool m_NumFilesDefined; + UINT64 m_NumBytes; + bool m_NumBytesDefined; + UINT32 m_PrevTickCount; + + NWindows::NFile::NFind::CFileInfoW _fileInfo; +public: + bool PasswordIsDefined; + UString Password; + + UString _folderPrefix; + +public: + MY_UNKNOWN_IMP3( + IArchiveOpenVolumeCallback, + IProgress, + ICryptoGetTextPassword + ) + + // IProgress + STDMETHOD(SetTotal)(UINT64 total); + STDMETHOD(SetCompleted)(const UINT64 *aCompleteValue); + + // IArchiveOpenCallback + STDMETHOD(SetTotal)(const UINT64 *numFiles, const UINT64 *numBytes); + STDMETHOD(SetCompleted)(const UINT64 *numFiles, const UINT64 *numBytes); + + // IArchiveOpenVolumeCallback + STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value); + STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream); + + // ICryptoGetTextPassword + STDMETHOD(CryptoGetTextPassword)(BSTR *password); + + void Init(CMessageBox *messageBox) + { + PasswordIsDefined = false; + + m_NumFilesMax = 0; + m_MessageBoxIsShown = false; + m_PrevTickCount = GetTickCount(); + m_MessageBox = messageBox; + } + void ShowMessage(const UINT64 *completed); + + void LoadFileInfo(const UString &folderPrefix, + const UString &fileName) + { + _folderPrefix = folderPrefix; + if (!NWindows::NFile::NFind::FindFile(_folderPrefix + fileName, _fileInfo)) + throw 1; + } +}; + +void COpenArchiveCallback::ShowMessage(const UINT64 *completed) +{ + UINT32 currentTime = GetTickCount(); + if (!m_MessageBoxIsShown) + { + if (currentTime - m_PrevTickCount < 400) + return; + m_MessageBox->Init(g_StartupInfo.GetMsgString(NMessageID::kWaitTitle), + g_StartupInfo.GetMsgString(NMessageID::kReading), 2, 30); + m_MessageBoxIsShown = true; + } + else + { + if (currentTime - m_PrevTickCount < 200) + return; + } + m_PrevTickCount = currentTime; + char aMessage[256]; + sprintf(aMessage, "%5I64u", m_NumFilesMax); + char aMessage2[256]; + aMessage2[0] = '\0'; + if (completed != NULL) + sprintf(aMessage2, "%5I64u", *completed); + const char *aMessages[2] = + {aMessage, aMessage2 }; + m_MessageBox->ShowProcessMessages(aMessages); +} + +STDMETHODIMP COpenArchiveCallback::SetTotal(const UINT64 *numFiles, const UINT64 *numBytes) +{ + if (WasEscPressed()) + return E_ABORT; + m_NumFilesDefined = (numFiles != NULL); + if (m_NumFilesDefined) + m_NumFiles = *numFiles; + m_NumBytesDefined = (numBytes != NULL); + if (m_NumBytesDefined) + m_NumBytes = *numBytes; + return S_OK; +} + +STDMETHODIMP COpenArchiveCallback::SetCompleted(const UINT64 *numFiles, const UINT64 * /* numBytes */) +{ + if (WasEscPressed()) + return E_ABORT; + if (numFiles == NULL) + return S_OK; + m_NumFilesMax = *numFiles; + // if (*numFiles % 100 != 0) + // return S_OK; + ShowMessage(NULL); + return S_OK; +} + + +STDMETHODIMP COpenArchiveCallback::SetTotal(const UINT64 /* total */) +{ + if (WasEscPressed()) + return E_ABORT; + /* + aNumFilesDefined = (numFiles != NULL); + if (aNumFilesDefined) + aNumFiles = *numFiles; + aNumBytesDefined = (numBytes != NULL); + if (aNumBytesDefined) + aNumBytes = *numBytes; + */ + return S_OK; +} + +STDMETHODIMP COpenArchiveCallback::SetCompleted(const UINT64 *completed) +{ + if (WasEscPressed()) + return E_ABORT; + if (completed == NULL) + return S_OK; + // if (*completed % 100 != 0) + // return S_OK; + ShowMessage(completed); + return S_OK; +} + +STDMETHODIMP COpenArchiveCallback::GetStream(const wchar_t *name, + IInStream **inStream) +{ + if (WasEscPressed()) + return E_ABORT; + *inStream = NULL; + UString fullPath = _folderPrefix + name; + if (!NWindows::NFile::NFind::FindFile(fullPath, _fileInfo)) + return S_FALSE; + if (_fileInfo.IsDirectory()) + return S_FALSE; + CInFileStream *inFile = new CInFileStream; + CMyComPtr inStreamTemp = inFile; + if (!inFile->Open(fullPath)) + return ::GetLastError(); + *inStream = inStreamTemp.Detach(); + return S_OK; +} + + +STDMETHODIMP COpenArchiveCallback::GetProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case kpidName: + propVariant = GetUnicodeString(_fileInfo.Name, CP_OEMCP); + break; + case kpidIsFolder: + propVariant = _fileInfo.IsDirectory(); + break; + case kpidSize: + propVariant = _fileInfo.Size; + break; + case kpidAttributes: + propVariant = (UINT32)_fileInfo.Attributes; + break; + case kpidLastAccessTime: + propVariant = _fileInfo.LastAccessTime; + break; + case kpidCreationTime: + propVariant = _fileInfo.CreationTime; + break; + case kpidLastWriteTime: + propVariant = _fileInfo.LastWriteTime; + break; + } + propVariant.Detach(value); + return S_OK; +} + +HRESULT GetPassword(UString &password) +{ + if (WasEscPressed()) + return E_ABORT; + password.Empty(); + CInitDialogItem initItems[]= + { + { DI_DOUBLEBOX, 3, 1, 72, 4, false, false, 0, false, NMessageID::kGetPasswordTitle, NULL, NULL }, + { DI_TEXT, 5, 2, 0, 0, false, false, DIF_SHOWAMPERSAND, false, NMessageID::kEnterPasswordForFile, NULL, NULL }, + { DI_PSWEDIT, 5, 3, 70, 3, true, false, 0, true, -1, "", NULL } + }; + + const int kNumItems = sizeof(initItems)/sizeof(initItems[0]); + FarDialogItem dialogItems[kNumItems]; + g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumItems); + + // sprintf(DialogItems[1].Data,GetMsg(MGetPasswordForFile),FileName); + if (g_StartupInfo.ShowDialog(76, 6, NULL, dialogItems, kNumItems) < 0) + return (E_ABORT); + + AString oemPassword = dialogItems[2].Data; + password = MultiByteToUnicodeString(oemPassword, CP_OEMCP); + return S_OK; +} + +STDMETHODIMP COpenArchiveCallback::CryptoGetTextPassword(BSTR *password) +{ + if (!PasswordIsDefined) + { + RINOK(GetPassword(Password)); + PasswordIsDefined = true; + } + CMyComBSTR temp = Password; + *password = temp.Detach(); + return S_OK; +} + +/* +HRESULT OpenArchive(const CSysString &fileName, + IInFolderArchive **archiveHandlerResult, + CArchiverInfo &archiverInfoResult, + UString &defaultName, + IArchiveOpenCallback *openArchiveCallback) +{ + HRESULT OpenArchive(const CSysString &fileName, + #ifndef EXCLUDE_COM + HMODULE *module, + #endif + IInArchive **archive, + CArchiverInfo &archiverInfoResult, + IArchiveOpenCallback *openArchiveCallback); +} +*/ + +static HANDLE MyOpenFilePlugin(const char *name) +{ + UINT codePage = ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; + + UString normalizedName = GetUnicodeString(name, codePage); + normalizedName.Trim(); + UString fullName; + int fileNamePartStartIndex; + NFile::NDirectory::MyGetFullPathName(normalizedName, fullName, fileNamePartStartIndex); + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(fullName, fileInfo)) + return INVALID_HANDLE_VALUE; + if (fileInfo.IsDirectory()) + return INVALID_HANDLE_VALUE; + + + CMyComPtr archiveHandler; + + // CArchiverInfo archiverInfoResult; + // ::OutputDebugString("before OpenArchive\n"); + + COpenArchiveCallback *openArchiveCallbackSpec = new COpenArchiveCallback; + + CMyComPtr openArchiveCallback = openArchiveCallbackSpec; + + // if ((opMode & OPM_SILENT) == 0 && (opMode & OPM_FIND ) == 0) + CScreenRestorer screenRestorer; + CMessageBox m_MessageBox; + { + screenRestorer.Save(); + } + openArchiveCallbackSpec->Init(&m_MessageBox); + openArchiveCallbackSpec->LoadFileInfo( + fullName.Left(fileNamePartStartIndex), + fullName.Mid(fileNamePartStartIndex)); + + // ::OutputDebugString("before OpenArchive\n"); + + archiveHandler = new CAgent; + CMyComBSTR archiveType; + HRESULT result = archiveHandler->Open( + GetUnicodeString(fullName, CP_OEMCP), &archiveType, openArchiveCallback); + /* + HRESULT result = ::OpenArchive(fullName, &archiveHandler, + archiverInfoResult, defaultName, openArchiveCallback); + */ + if (result != S_OK) + { + if (result == E_ABORT) + return (HANDLE)-2; + return INVALID_HANDLE_VALUE; + } + + // ::OutputDebugString("after OpenArchive\n"); + + CPlugin *plugin = new CPlugin( + fullName, + // defaultName, + archiveHandler, + (const wchar_t *)archiveType + ); + if (plugin == NULL) + return(INVALID_HANDLE_VALUE); + plugin->PasswordIsDefined = openArchiveCallbackSpec->PasswordIsDefined; + plugin->Password = openArchiveCallbackSpec->Password; + + return (HANDLE)(plugin); +} + +HANDLE WINAPI OpenFilePlugin(char *name, + const unsigned char * /* data */, unsigned int /* dataSize */) +{ + MY_TRY_BEGIN; + if (name == NULL || (!g_Options.Enabled)) + { + // if (!Opt.ProcessShiftF1) + return(INVALID_HANDLE_VALUE); + } + return MyOpenFilePlugin(name); + MY_TRY_END2("OpenFilePlugin", INVALID_HANDLE_VALUE); +} + +HANDLE WINAPI OpenPlugin(int openFrom, int item) +{ + MY_TRY_BEGIN; + if(openFrom == OPEN_COMMANDLINE) + { + CSysString fileName = (const char *)item; + if(fileName.IsEmpty()) + return INVALID_HANDLE_VALUE; + if (fileName.Length() >= 2 && + fileName[0] == '\"' && fileName[fileName.Length() - 1] == '\"') + fileName = fileName.Mid(1, fileName.Length() - 2); + + return MyOpenFilePlugin(fileName); + } + if(openFrom == OPEN_PLUGINSMENU) + { + switch(item) + { + case 0: + { + PluginPanelItem pluginPanelItem; + if(!g_StartupInfo.ControlGetActivePanelCurrentItemInfo(pluginPanelItem)) + throw 142134; + return MyOpenFilePlugin(pluginPanelItem.FindData.cFileName); + } + case 1: + { + CObjectVector pluginPanelItem; + if(!g_StartupInfo.ControlGetActivePanelSelectedOrCurrentItems(pluginPanelItem)) + throw 142134; + if (CompressFiles(pluginPanelItem) == S_OK) + { + int t = g_StartupInfo.ControlClearPanelSelection(); + g_StartupInfo.ControlRequestActivePanel(FCTL_UPDATEPANEL, NULL); + g_StartupInfo.ControlRequestActivePanel(FCTL_REDRAWPANEL, NULL); + g_StartupInfo.ControlRequestActivePanel(FCTL_UPDATEANOTHERPANEL, NULL); + g_StartupInfo.ControlRequestActivePanel(FCTL_REDRAWANOTHERPANEL, NULL); + } + return INVALID_HANDLE_VALUE; + } + default: + throw 4282215; + } + } + return INVALID_HANDLE_VALUE; + MY_TRY_END2("OpenPlugin", INVALID_HANDLE_VALUE); +} + +void WINAPI ClosePlugin(HANDLE plugin) +{ + MY_TRY_BEGIN; + delete (CPlugin *)plugin; + MY_TRY_END1("ClosePlugin"); +} + +int WINAPI GetFindData(HANDLE plugin, struct PluginPanelItem **panelItems, + int *itemsNumber,int opMode) +{ + MY_TRY_BEGIN; + return(((CPlugin *)plugin)->GetFindData(panelItems, itemsNumber, opMode)); + MY_TRY_END2("GetFindData", FALSE); +} + +void WINAPI FreeFindData(HANDLE plugin, struct PluginPanelItem *panelItems, + int itemsNumber) +{ + MY_TRY_BEGIN; + ((CPlugin *)plugin)->FreeFindData(panelItems, itemsNumber); + MY_TRY_END1("FreeFindData"); +} + +int WINAPI GetFiles(HANDLE plugin, struct PluginPanelItem *panelItems, + int itemsNumber, int move, char *destPath, int opMode) +{ + MY_TRY_BEGIN; + return(((CPlugin *)plugin)->GetFiles(panelItems, itemsNumber, move, destPath, opMode)); + MY_TRY_END2("GetFiles", NFileOperationReturnCode::kError); +} + +int WINAPI SetDirectory(HANDLE plugin, char *dir, int opMode) +{ + MY_TRY_BEGIN; + return(((CPlugin *)plugin)->SetDirectory(dir, opMode)); + MY_TRY_END2("SetDirectory", FALSE); +} + +void WINAPI GetPluginInfo(struct PluginInfo *info) +{ + MY_TRY_BEGIN; + + info->StructSize = sizeof(*info); + info->Flags = 0; + info->DiskMenuStrings = NULL; + info->DiskMenuNumbers = NULL; + info->DiskMenuStringsNumber = 0; + static const char *pluginMenuStrings[2]; + pluginMenuStrings[0] = g_StartupInfo.GetMsgString(NMessageID::kOpenArchiveMenuString); + pluginMenuStrings[1] = g_StartupInfo.GetMsgString(NMessageID::kCreateArchiveMenuString); + info->PluginMenuStrings = (char **)pluginMenuStrings; + info->PluginMenuStringsNumber = 2; + static const char *pluginCfgStrings[1]; + pluginCfgStrings[0] = g_StartupInfo.GetMsgString(NMessageID::kOpenArchiveMenuString); + info->PluginConfigStrings = (char **)pluginCfgStrings; + info->PluginConfigStringsNumber = sizeof(pluginCfgStrings) / sizeof(pluginCfgStrings[0]); + info->CommandPrefix = (char *)kCommandPrefix; + MY_TRY_END1("GetPluginInfo"); +} + +int WINAPI Configure(int itemNumber) +{ + MY_TRY_BEGIN; + + const int kEnabledCheckBoxIndex = 1; + + const int kYSize = 7; + + struct CInitDialogItem initItems[]= + { + { DI_DOUBLEBOX, 3, 1, 72, kYSize - 2, false, false, 0, false, NMessageID::kConfigTitle, NULL, NULL }, + { DI_CHECKBOX, 5, 2, 0, 0, true, g_Options.Enabled, 0, false, NMessageID::kConfigPluginEnabled, NULL, NULL }, + { DI_TEXT, 5, 3, 0, 0, false, false, DIF_BOXCOLOR | DIF_SEPARATOR, false, -1, "", NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, true, NMessageID::kOk, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kCancel, NULL, NULL }, + }; + + const int kNumDialogItems = sizeof(initItems) / sizeof(initItems[0]); + const int kOkButtonIndex = kNumDialogItems - 2; + + FarDialogItem dialogItems[kNumDialogItems]; + g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems); + + int askCode = g_StartupInfo.ShowDialog(76, kYSize, + kHelpTopicConfig, dialogItems, kNumDialogItems); + + if (askCode != kOkButtonIndex) + return (FALSE); + + g_Options.Enabled = BOOLToBool(dialogItems[kEnabledCheckBoxIndex].Selected); + + g_StartupInfo.SetRegKeyValue(HKEY_CURRENT_USER, kRegisrtryMainKeyName, + kRegisrtryValueNameEnabled, g_Options.Enabled); + return(TRUE); + MY_TRY_END2("Configure", FALSE); +} + +void WINAPI GetOpenPluginInfo(HANDLE plugin,struct OpenPluginInfo *info) +{ + MY_TRY_BEGIN; + ((CPlugin *)plugin)->GetOpenPluginInfo(info); + MY_TRY_END1("GetOpenPluginInfo"); +} + +int WINAPI PutFiles(HANDLE plugin, struct PluginPanelItem *panelItems, + int itemsNumber, int move, int opMode) +{ + MY_TRY_BEGIN; + return(((CPlugin *)plugin)->PutFiles(panelItems, itemsNumber, move, opMode)); + MY_TRY_END2("PutFiles", NFileOperationReturnCode::kError); +} + +int WINAPI DeleteFiles(HANDLE plugin, PluginPanelItem *panelItems, + int itemsNumber, int opMode) +{ + MY_TRY_BEGIN; + return(((CPlugin *)plugin)->DeleteFiles(panelItems, itemsNumber, opMode)); + MY_TRY_END2("DeleteFiles", FALSE); +} + +int WINAPI ProcessKey(HANDLE plugin, int key, unsigned int controlState) +{ + MY_TRY_BEGIN; + return (((CPlugin *)plugin)->ProcessKey(key, controlState)); + MY_TRY_END2("ProcessKey", FALSE); +} diff --git a/CPP/7zip/UI/Far/Messages.h b/CPP/7zip/UI/Far/Messages.h new file mode 100755 index 00000000..8b6e2a49 --- /dev/null +++ b/CPP/7zip/UI/Far/Messages.h @@ -0,0 +1,152 @@ +// SevenZip/ Messages.h + +#ifndef __SEVENZIP_MESSAGES_H +#define __SEVENZIP_MESSAGES_H + +namespace NMessageID { + +enum EEnum +{ + kOk, + kCancel, + + kWarning, + kError, + + kArchiveType, + + kProperties, + + kYes, + kNo, + + kName, + kExtension, + kIsFolder, + kSize, + kPackedSize, + kAttributes, + kCreationTime, + kLastAccessTime, + kLastWriteTime, + kSolid, + kCommented, + kEncrypted, + kSplitBefore, + kSplitAfter, + kDictionarySize, + kCRC, + kType, + kAnti, + kMethod, + kHostOS, + kFileSystem, + kUser, + kGroup, + kBlock, + kComment, + kPosition, + + kGetPasswordTitle, + kEnterPasswordForFile, + + kExtractTitle, + kExtractTo, + + kExtractPathMode, + kExtractPathFull, + kExtractPathCurrent, + kExtractPathNo, + + kExtractOwerwriteMode, + kExtractOwerwriteAsk, + kExtractOwerwritePrompt, + kExtractOwerwriteSkip, + kExtractOwerwriteAutoRename, + kExtractOwerwriteAutoRenameExisting, + + kExtractFilesMode, + kExtractFilesSelected, + kExtractFilesAll, + + kExtractPassword, + + kExtractExtract, + kExtractCancel, + + kExtractCanNotOpenOutputFile, + + kExtractUnsupportedMethod, + kExtractCRCFailed, + kExtractDataError, + + kOverwriteTitle, + kOverwriteMessage1, + kOverwriteMessageWouldYouLike, + kOverwriteMessageWithtTisOne, + + kOverwriteBytes, + kOverwriteModifiedOn, + + kOverwriteYes, + kOverwriteYesToAll, + kOverwriteNo, + kOverwriteNoToAll, + kOverwriteAutoRename, + kOverwriteCancel, + + kUpdateNotSupportedForThisArchive, + + kDeleteTitle, + kDeleteFile, + kDeleteFiles, + kDeleteNumberOfFiles, + kDeleteDelete, + kDeleteCancel, + + kUpdateTitle, + kUpdateAddToArchive, + + kUpdateMethod, + kUpdateMethodStore, + kUpdateMethodFastest, + kUpdateMethodFast, + kUpdateMethodNormal, + kUpdateMethodMaximum, + kUpdateMethodUltra, + + kUpdateMode, + kUpdateModeAdd, + kUpdateModeUpdate, + kUpdateModeFreshen, + kUpdateModeSynchronize, + + kUpdateAdd, + kUpdateSelectArchiver, + + kUpdateSelectArchiverMenuTitle, + + // kArcReadFiles, + + kWaitTitle, + + kReading, + kExtracting, + kDeleting, + kUpdating, + + // kReadingList, + + kMoveIsNotSupported, + + kOpenArchiveMenuString, + kCreateArchiveMenuString, + + kConfigTitle, + + kConfigPluginEnabled +}; + +} + +#endif \ No newline at end of file diff --git a/CPP/7zip/UI/Far/OverwriteDialog.cpp b/CPP/7zip/UI/Far/OverwriteDialog.cpp new file mode 100755 index 00000000..028fff4e --- /dev/null +++ b/CPP/7zip/UI/Far/OverwriteDialog.cpp @@ -0,0 +1,109 @@ +// OverwriteDialog.cpp + +#include "StdAfx.h" + +#include + +#include "OverwriteDialog.h" + +#include "Common/String.h" +#include "Common/StringConvert.h" + +#include "Windows/FileName.h" +#include "Windows/Defs.h" +#include "Windows/PropVariantConversions.h" + +#include "FarUtils.h" +#include "Messages.h" + +using namespace NWindows; +using namespace NFar; + +namespace NOverwriteDialog { + +static const char *kHelpTopic = "OverwriteDialog"; + +struct CFileInfoStrings +{ + CSysString Size; + CSysString Time; +}; + +void SetFileInfoStrings(const CFileInfo &fileInfo, + CFileInfoStrings &fileInfoStrings) +{ + char buffer[256]; + + if (fileInfo.SizeIsDefined) + { + sprintf(buffer, "%I64u ", fileInfo.Size); + fileInfoStrings.Size = buffer; + fileInfoStrings.Size += g_StartupInfo.GetMsgString(NMessageID::kOverwriteBytes); + } + else + { + fileInfoStrings.Size = ""; + } + + FILETIME localFileTime; + if (!FileTimeToLocalFileTime(&fileInfo.Time, &localFileTime)) + throw 4190402; + UString timeString = ConvertFileTimeToString(localFileTime); + + fileInfoStrings.Time = g_StartupInfo.GetMsgString(NMessageID::kOverwriteModifiedOn); + fileInfoStrings.Time += " "; + fileInfoStrings.Time += GetSystemString(timeString, CP_OEMCP); +} + +NResult::EEnum Execute(const CFileInfo &oldFileInfo, const CFileInfo &newFileInfo) +{ + const int kYSize = 20; + const int kXSize = 76; + + CFileInfoStrings oldFileInfoStrings; + CFileInfoStrings newFileInfoStrings; + + SetFileInfoStrings(oldFileInfo, oldFileInfoStrings); + SetFileInfoStrings(newFileInfo, newFileInfoStrings); + + struct CInitDialogItem anInitItems[]={ + { DI_DOUBLEBOX, 3, 1, kXSize - 4, kYSize - 2, false, false, 0, false, NMessageID::kOverwriteTitle, NULL, NULL }, + { DI_TEXT, 5, 2, 0, 0, false, false, 0, false, NMessageID::kOverwriteMessage1, NULL, NULL }, + + { DI_TEXT, 3, 3, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL }, + + { DI_TEXT, 5, 4, 0, 0, false, false, 0, false, NMessageID::kOverwriteMessageWouldYouLike, NULL, NULL }, + + { DI_TEXT, 7, 6, 0, 0, false, false, 0, false, -1, oldFileInfo.Name, NULL }, + { DI_TEXT, 7, 7, 0, 0, false, false, 0, false, -1, oldFileInfoStrings.Size, NULL }, + { DI_TEXT, 7, 8, 0, 0, false, false, 0, false, -1, oldFileInfoStrings.Time, NULL }, + + { DI_TEXT, 5, 10, 0, 0, false, false, 0, false, NMessageID::kOverwriteMessageWithtTisOne, NULL, NULL }, + + { DI_TEXT, 7, 12, 0, 0, false, false, 0, false, -1, newFileInfo.Name, NULL }, + { DI_TEXT, 7, 13, 0, 0, false, false, 0, false, -1, newFileInfoStrings.Size, NULL }, + { DI_TEXT, 7, 14, 0, 0, false, false, 0, false, -1, newFileInfoStrings.Time, NULL }, + + { DI_TEXT, 3, kYSize - 5, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL }, + + { DI_BUTTON, 0, kYSize - 4, 0, 0, true, false, DIF_CENTERGROUP, true, NMessageID::kOverwriteYes, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 4, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kOverwriteYesToAll, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 4, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kOverwriteNo, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 4, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kOverwriteNoToAll, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kOverwriteAutoRename, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kOverwriteCancel, NULL, NULL } + }; + + const int kNumDialogItems = sizeof(anInitItems) / sizeof(anInitItems[0]); + FarDialogItem aDialogItems[kNumDialogItems]; + g_StartupInfo.InitDialogItems(anInitItems, aDialogItems, kNumDialogItems); + int anAskCode = g_StartupInfo.ShowDialog(kXSize, kYSize, + NULL, aDialogItems, kNumDialogItems); + const int kButtonStartPos = kNumDialogItems - 6; + if (anAskCode >= kButtonStartPos && anAskCode < kNumDialogItems) + return NResult::EEnum(anAskCode - kButtonStartPos); + return NResult::kCancel; +} + +} + diff --git a/CPP/7zip/UI/Far/OverwriteDialog.h b/CPP/7zip/UI/Far/OverwriteDialog.h new file mode 100755 index 00000000..ff1a480e --- /dev/null +++ b/CPP/7zip/UI/Far/OverwriteDialog.h @@ -0,0 +1,33 @@ +// OverwriteDialog.h + +#ifndef OVERWRITEDIALOG_H +#define OVERWRITEDIALOG_H + +#include "Common/String.h" + +namespace NOverwriteDialog { + +struct CFileInfo +{ + bool SizeIsDefined; + UINT64 Size; + FILETIME Time; + CSysString Name; +}; +namespace NResult +{ + enum EEnum + { + kYes, + kYesToAll, + kNo, + kNoToAll, + kAutoRename, + kCancel, + }; +} +NResult::EEnum Execute(const CFileInfo &anOldFileInfo, const CFileInfo &aNewFileInfo); + +} + +#endif diff --git a/CPP/7zip/UI/Far/Plugin.cpp b/CPP/7zip/UI/Far/Plugin.cpp new file mode 100755 index 00000000..0d4b150e --- /dev/null +++ b/CPP/7zip/UI/Far/Plugin.cpp @@ -0,0 +1,693 @@ +// Plugin.cpp + +#include "StdAfx.h" + +#include "Plugin.h" + +#include "Common/StringConvert.h" +#include "Common/Wildcard.h" + +#include "Windows/PropVariantConversions.h" +#include "Windows/FileName.h" +#include "Windows/FileDir.h" + +#include "../Common/PropIDUtils.h" + +#include "Messages.h" +#include "FarUtils.h" + +using namespace NWindows; +using namespace NFar; + +CSysString ConvertPropertyToString2(const PROPVARIANT &propVariant, PROPID propID) +{ + if (propVariant.vt == VT_BSTR) + return GetSystemString(propVariant.bstrVal, CP_OEMCP); + if (propVariant.vt != VT_BOOL) + return GetSystemString(ConvertPropertyToString(propVariant, propID), CP_OEMCP); + int messageID = VARIANT_BOOLToBool(propVariant.boolVal) ? + NMessageID::kYes : NMessageID::kNo; + return g_StartupInfo.GetMsgString(messageID); +} + +CPlugin::CPlugin(const UString &fileName, + // const UString &defaultName, + IInFolderArchive *archiveHandler, + UString archiveTypeName + ): + m_ArchiveHandler(archiveHandler), + m_FileName(fileName), + _archiveTypeName(archiveTypeName) + // , m_DefaultName(defaultName) + // , m_ArchiverInfo(archiverInfo) +{ + if (!NFile::NFind::FindFile(m_FileName, m_FileInfo)) + throw "error"; + archiveHandler->BindToRootFolder(&_folder); +} + +CPlugin::~CPlugin() +{ +} + +static void MyGetFileTime(IFolderFolder *anArchiveFolder, UINT32 itemIndex, + PROPID propID, FILETIME &fileTime) +{ + NCOM::CPropVariant propVariant; + if (anArchiveFolder->GetProperty(itemIndex, propID, &propVariant) != S_OK) + throw 271932; + if (propVariant.vt == VT_EMPTY) + { + fileTime.dwHighDateTime = 0; + fileTime.dwLowDateTime = 0; + } + else + { + if (propVariant.vt != VT_FILETIME) + throw 4191730; + fileTime = propVariant.filetime; + } +} + +void CPlugin::ReadPluginPanelItem(PluginPanelItem &panelItem, UINT32 itemIndex) +{ + NCOM::CPropVariant propVariant; + if (_folder->GetProperty(itemIndex, kpidName, &propVariant) != S_OK) + throw 271932; + + if (propVariant.vt != VT_BSTR) + throw 272340; + + CSysString oemString = UnicodeStringToMultiByte(propVariant.bstrVal, CP_OEMCP); + strcpy(panelItem.FindData.cFileName, oemString); + panelItem.FindData.cAlternateFileName[0] = 0; + + if (_folder->GetProperty(itemIndex, kpidAttributes, &propVariant) != S_OK) + throw 271932; + if (propVariant.vt == VT_UI4) + panelItem.FindData.dwFileAttributes = propVariant.ulVal; + else if (propVariant.vt == VT_EMPTY) + panelItem.FindData.dwFileAttributes = m_FileInfo.Attributes; + else + throw 21631; + + if (_folder->GetProperty(itemIndex, kpidIsFolder, &propVariant) != S_OK) + throw 271932; + if (propVariant.vt == VT_BOOL) + { + if (VARIANT_BOOLToBool(propVariant.boolVal)) + panelItem.FindData.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY; + } + else if (propVariant.vt != VT_EMPTY) + throw 21632; + + if (_folder->GetProperty(itemIndex, kpidSize, &propVariant) != S_OK) + throw 271932; + UINT64 length; + if (propVariant.vt == VT_EMPTY) + length = 0; + else + length = ::ConvertPropVariantToUInt64(propVariant); + panelItem.FindData.nFileSizeLow = UINT32(length); + panelItem.FindData.nFileSizeHigh = UINT32(length >> 32); + + MyGetFileTime(_folder, itemIndex, kpidCreationTime, panelItem.FindData.ftCreationTime); + MyGetFileTime(_folder, itemIndex, kpidLastAccessTime, panelItem.FindData.ftLastAccessTime); + MyGetFileTime(_folder, itemIndex, kpidLastWriteTime, panelItem.FindData.ftLastWriteTime); + + if (panelItem.FindData.ftLastWriteTime.dwHighDateTime == 0 && + panelItem.FindData.ftLastWriteTime.dwLowDateTime == 0) + panelItem.FindData.ftLastWriteTime = m_FileInfo.LastWriteTime; + + if (_folder->GetProperty(itemIndex, kpidPackedSize, &propVariant) != S_OK) + throw 271932; + if (propVariant.vt == VT_EMPTY) + length = 0; + else + length = ::ConvertPropVariantToUInt64(propVariant); + panelItem.PackSize = UINT32(length); + panelItem.PackSizeHigh = UINT32(length >> 32); + + panelItem.Flags = 0; + panelItem.NumberOfLinks = 0; + + panelItem.Description = NULL; + panelItem.Owner = NULL; + panelItem.CustomColumnData = NULL; + panelItem.CustomColumnNumber = 0; + + panelItem.Reserved[0] = 0; + panelItem.Reserved[1] = 0; + panelItem.Reserved[2] = 0; + + +} + +int CPlugin::GetFindData(PluginPanelItem **panelItems, + int *itemsNumber, int opMode) +{ + // CScreenRestorer screenRestorer; + if ((opMode & OPM_SILENT) == 0 && (opMode & OPM_FIND ) == 0) + { + /* + screenRestorer.Save(); + const char *aMsgItems[]= + { + g_StartupInfo.GetMsgString(NMessageID::kWaitTitle), + g_StartupInfo.GetMsgString(NMessageID::kReadingList) + }; + g_StartupInfo.ShowMessage(0, NULL, aMsgItems, + sizeof(aMsgItems) / sizeof(aMsgItems[0]), 0); + */ + } + + UINT32 numItems; + _folder->GetNumberOfItems(&numItems); + *panelItems = new PluginPanelItem[numItems]; + try + { + for(UINT32 i = 0; i < numItems; i++) + { + PluginPanelItem &panelItem = (*panelItems)[i]; + ReadPluginPanelItem(panelItem, i); + panelItem.UserData = i; + } + } + catch(...) + { + delete [](*panelItems); + throw; + } + *itemsNumber = numItems; + return(TRUE); +} + +void CPlugin::FreeFindData(struct PluginPanelItem *panelItems, + int itemsNumber) +{ + for(int i = 0; i < itemsNumber; i++) + if(panelItems[i].Description != NULL) + delete []panelItems[i].Description; + delete []panelItems; +} + + +void CPlugin::EnterToDirectory(const UString &aDirName) +{ + CMyComPtr newFolder; + _folder->BindToFolder(aDirName, &newFolder); + if(newFolder == NULL) + if (aDirName.IsEmpty()) + return; + else + throw 40325; + _folder = newFolder; +} + +int CPlugin::SetDirectory(const char *aszDir, int opMode) +{ + UString path = MultiByteToUnicodeString(aszDir, CP_OEMCP); + if (path == L"\\") + { + _folder.Release(); + m_ArchiveHandler->BindToRootFolder(&_folder); + } + else if (path == L"..") + { + CMyComPtr newFolder; + _folder->BindToParentFolder(&newFolder); + if (newFolder == NULL) + throw 40312; + _folder = newFolder; + } + else if (path.IsEmpty()) + EnterToDirectory(path); + else + { + if (path[0] == L'\\') + { + _folder.Release(); + m_ArchiveHandler->BindToRootFolder(&_folder); + path = path.Mid(1); + } + UStringVector pathParts; + SplitPathToParts(path, pathParts); + for(int i = 0; i < pathParts.Size(); i++) + EnterToDirectory(pathParts[i]); + } + GetCurrentDir(); + return TRUE; +} + +void CPlugin::GetPathParts(UStringVector &pathParts) +{ + pathParts.Clear(); + CMyComPtr folderItem = _folder; + for (;;) + { + CMyComPtr newFolder; + folderItem->BindToParentFolder(&newFolder); + if (newFolder == NULL) + break; + CMyComBSTR name; + folderItem->GetName(&name); + pathParts.Insert(0, (const wchar_t *)name); + folderItem = newFolder; + } +} + +void CPlugin::GetCurrentDir() +{ + m_CurrentDir.Empty(); + UStringVector pathParts; + GetPathParts(pathParts); + for (int i = 0; i < pathParts.Size(); i++) + { + m_CurrentDir += L'\\'; + m_CurrentDir += pathParts[i]; + } +} + +static char *kPluginFormatName = "7-ZIP"; + + +struct CPROPIDToName +{ + PROPID PropID; + int PluginID; +}; + +static CPROPIDToName kPROPIDToName[] = +{ + { kpidName, NMessageID::kName }, + { kpidExtension, NMessageID::kExtension }, + { kpidIsFolder, NMessageID::kIsFolder }, + { kpidSize, NMessageID::kSize }, + { kpidPackedSize, NMessageID::kPackedSize }, + { kpidAttributes, NMessageID::kAttributes }, + { kpidCreationTime, NMessageID::kCreationTime }, + { kpidLastAccessTime, NMessageID::kLastAccessTime }, + { kpidLastWriteTime, NMessageID::kLastWriteTime }, + { kpidSolid, NMessageID::kSolid }, + { kpidCommented, NMessageID::kCommented }, + { kpidEncrypted, NMessageID::kEncrypted }, + { kpidSplitBefore, NMessageID::kSplitBefore }, + { kpidSplitAfter, NMessageID::kSplitAfter }, + { kpidDictionarySize, NMessageID::kDictionarySize }, + { kpidCRC, NMessageID::kCRC }, + { kpidType, NMessageID::kType }, + { kpidIsAnti, NMessageID::kAnti }, + { kpidMethod, NMessageID::kMethod }, + { kpidHostOS, NMessageID::kHostOS }, + { kpidFileSystem, NMessageID::kFileSystem }, + { kpidUser, NMessageID::kUser }, + { kpidGroup, NMessageID::kGroup }, + { kpidBlock, NMessageID::kBlock }, + { kpidComment, NMessageID::kComment }, + { kpidPosition, NMessageID::kPosition } + +}; + +static const int kNumPROPIDToName = sizeof(kPROPIDToName) / sizeof(kPROPIDToName[0]); + +static int FindPropertyToName(PROPID propID) +{ + for(int i = 0; i < kNumPROPIDToName; i++) + if(kPROPIDToName[i].PropID == propID) + return i; + return -1; +} + +/* +struct CPropertyIDInfo +{ + PROPID PropID; + const char *FarID; + int Width; + // char CharID; +}; + +static CPropertyIDInfo kPropertyIDInfos[] = +{ + { kpidName, "N", 0}, + { kpidSize, "S", 8}, + { kpidPackedSize, "P", 8}, + { kpidAttributes, "A", 0}, + { kpidCreationTime, "DC", 14}, + { kpidLastAccessTime, "DA", 14}, + { kpidLastWriteTime, "DM", 14}, + + { kpidSolid, NULL, 0, 'S'}, + { kpidEncrypted, NULL, 0, 'P'} + + { kpidDictionarySize, IDS_PROPERTY_DICTIONARY_SIZE }, + { kpidSplitBefore, NULL, 'B'}, + { kpidSplitAfter, NULL, 'A'}, + { kpidComment, , NULL, 'C'}, + { kpidCRC, IDS_PROPERTY_CRC } + // { kpidType, L"Type" } +}; + +static const int kNumPropertyIDInfos = sizeof(kPropertyIDInfos) / + sizeof(kPropertyIDInfos[0]); + +static int FindPropertyInfo(PROPID propID) +{ + for(int i = 0; i < kNumPropertyIDInfos; i++) + if(kPropertyIDInfos[i].PropID == propID) + return i; + return -1; +} +*/ + +// char *g_Titles[] = { "a", "f", "v" }; +static void SmartAddToString(AString &aDestString, const char *aSrcString) +{ + if (!aDestString.IsEmpty()) + aDestString += ','; + aDestString += aSrcString; +} + +/* +void CPlugin::AddColumn(PROPID propID) +{ + int index = FindPropertyInfo(propID); + if (index >= 0) + { + for(int i = 0; i < m_ProxyHandler->m_InternalProperties.Size(); i++) + { + const CArchiveItemProperty &aHandlerProperty = m_ProxyHandler->m_InternalProperties[i]; + if (aHandlerProperty.ID == propID) + break; + } + if (i == m_ProxyHandler->m_InternalProperties.Size()) + return; + + const CPropertyIDInfo &aPropertyIDInfo = kPropertyIDInfos[index]; + SmartAddToString(PanelModeColumnTypes, aPropertyIDInfo.FarID); + char aTmp[32]; + itoa(aPropertyIDInfo.Width, aTmp, 10); + SmartAddToString(PanelModeColumnWidths, aTmp); + return; + } +} +*/ + +void CPlugin::GetOpenPluginInfo(struct OpenPluginInfo *info) +{ + info->StructSize = sizeof(*info); + info->Flags = OPIF_USEFILTER | OPIF_USESORTGROUPS| OPIF_USEHIGHLIGHTING| + OPIF_ADDDOTS | OPIF_COMPAREFATTIME; + + UINT codePage = ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; + + strcpy(m_FileNameBuffer, UnicodeStringToMultiByte(m_FileName, codePage)); + info->HostFile = m_FileNameBuffer; // test it it is not static + + strcpy(m_CurrentDirBuffer, UnicodeStringToMultiByte(m_CurrentDir, CP_OEMCP)); + info->CurDir = m_CurrentDirBuffer; + + info->Format = kPluginFormatName; + + UString name; + { + UString fullName; + int index; + NFile::NDirectory::MyGetFullPathName(m_FileName, fullName, index); + name = fullName.Mid(index); + } + + m_PannelTitle = + UString(L' ') + + _archiveTypeName + + UString(L':') + + name + + UString(L' '); + if(!m_CurrentDir.IsEmpty()) + { + // m_PannelTitle += '\\'; + m_PannelTitle += m_CurrentDir; + } + + strcpy(m_PannelTitleBuffer, UnicodeStringToMultiByte(m_PannelTitle, CP_OEMCP)); + info->PanelTitle = m_PannelTitleBuffer; + + memset(m_InfoLines,0,sizeof(m_InfoLines)); + strcpy(m_InfoLines[0].Text,""); + m_InfoLines[0].Separator = TRUE; + + strcpy(m_InfoLines[1].Text, g_StartupInfo.GetMsgString(NMessageID::kArchiveType)); + strcpy(m_InfoLines[1].Data, UnicodeStringToMultiByte(_archiveTypeName, CP_OEMCP)); + + int numItems = 2; + UINT32 numProps; + if (m_ArchiveHandler->GetNumberOfArchiveProperties(&numProps) == S_OK) + { + for (UINT32 i = 0; i < numProps && numItems < 30; i++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE vt; + if (m_ArchiveHandler->GetArchivePropertyInfo(i, &name, &propID, &vt) != S_OK) + continue; + + InfoPanelLine &item = m_InfoLines[numItems]; + int index = FindPropertyToName(propID); + if (index < 0) + { + if (name != 0) + strcpy(item.Text, UnicodeStringToMultiByte( + (const wchar_t *)name, CP_OEMCP)); + else + strcpy(item.Text, ""); + } + else + strcpy(item.Text, g_StartupInfo.GetMsgString(kPROPIDToName[index].PluginID)); + + NCOM::CPropVariant propVariant; + if (m_ArchiveHandler->GetArchiveProperty(propID, &propVariant) != S_OK) + continue; + CSysString s = ConvertPropertyToString2(propVariant, propID); + strcpy(item.Data, s); + numItems++; + } + } + + //m_InfoLines[1].Separator = 0; + + info->InfoLines = m_InfoLines; + info->InfoLinesNumber = numItems; + + + info->DescrFiles = NULL; + info->DescrFilesNumber = 0; + + PanelModeColumnTypes.Empty(); + PanelModeColumnWidths.Empty(); + + /* + AddColumn(kpidName); + AddColumn(kpidSize); + AddColumn(kpidPackedSize); + AddColumn(kpidLastWriteTime); + AddColumn(kpidCreationTime); + AddColumn(kpidLastAccessTime); + AddColumn(kpidAttributes); + + PanelMode.ColumnTypes = (char *)(const char *)PanelModeColumnTypes; + PanelMode.ColumnWidths = (char *)(const char *)PanelModeColumnWidths; + PanelMode.ColumnTitles = NULL; + PanelMode.FullScreen = TRUE; + PanelMode.DetailedStatus = FALSE; + PanelMode.AlignExtensions = FALSE; + PanelMode.CaseConversion = FALSE; + PanelMode.StatusColumnTypes = "N"; + PanelMode.StatusColumnWidths = "0"; + PanelMode.Reserved[0] = 0; + PanelMode.Reserved[1] = 0; + + info->PanelModesArray = &PanelMode; + info->PanelModesNumber = 1; + */ + + info->PanelModesArray = NULL; + info->PanelModesNumber = 0; + + info->StartPanelMode = 0; + info->StartSortMode = 0; + info->KeyBar = NULL; + info->ShortcutData = NULL; +} + +struct CArchiveItemProperty +{ + AString Name; + PROPID ID; + VARTYPE Type; +}; + +HRESULT CPlugin::ShowAttributesWindow() +{ + PluginPanelItem pluginPanelItem; + if (!g_StartupInfo.ControlGetActivePanelCurrentItemInfo(pluginPanelItem)) + return S_FALSE; + if (strcmp(pluginPanelItem.FindData.cFileName, "..") == 0 && + NFile::NFind::NAttributes::IsDirectory(pluginPanelItem.FindData.dwFileAttributes)) + return S_FALSE; + int itemIndex = pluginPanelItem.UserData; + + CObjectVector properties; + UINT32 numProps; + RINOK(m_ArchiveHandler->GetNumberOfProperties(&numProps)); + int i; + for (i = 0; i < (int)numProps; i++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE vt; + RINOK(m_ArchiveHandler->GetPropertyInfo(i, &name, &propID, &vt)); + CArchiveItemProperty destProperty; + destProperty.Type = vt; + destProperty.ID = propID; + if (destProperty.ID == kpidPath) + destProperty.ID = kpidName; + AString propName; + { + if (name != NULL) + destProperty.Name = UnicodeStringToMultiByte( + (const wchar_t *)name, CP_OEMCP); + else + destProperty.Name = "Error"; + } + properties.Add(destProperty); + } + + /* + LPCITEMIDLIST aProperties; + if (index < m_FolderItem->m_DirSubItems.Size()) + { + const CArchiveFolderItem &anItem = m_FolderItem->m_DirSubItems[index]; + aProperties = anItem.m_Properties; + } + else + { + const CArchiveFolderFileItem &anItem = + m_FolderItem->m_FileSubItems[index - m_FolderItem->m_DirSubItems.Size()]; + aProperties = anItem.m_Properties; + } + */ + + const int kPathIndex = 2; + const int kOkButtonIndex = 4; + int size = 2; + CRecordVector 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 dialogItems; + dialogItems.Reserve(numDialogItems); + for(i = 0; i < numDialogItems; i++) + dialogItems.Add(FarDialogItem()); + g_StartupInfo.InitDialogItems(&initDialogItems.Front(), + &dialogItems.Front(), numDialogItems); + + int maxLen = 0; + for (i = 0; i < numLines; i++) + { + FarDialogItem &dialogItem = dialogItems[1 + i * 2]; + int len = strlen(dialogItem.Data); + if (len > maxLen) + maxLen = len; + } + int maxLen2 = 0; + const int kSpace = 10; + for (i = 0; i < numLines; i++) + { + FarDialogItem &dialogItem = dialogItems[1 + i * 2 + 1]; + int len = strlen(dialogItem.Data); + if (len > maxLen2) + maxLen2 = len; + dialogItem.X1 = maxLen + kSpace; + } + size = numLines + 6; + xSize = maxLen + kSpace + maxLen2 + 5; + FarDialogItem &aFirstDialogItem = dialogItems.Front(); + aFirstDialogItem.Y2 = size - 2; + aFirstDialogItem.X2 = xSize - 4; + + int askCode = g_StartupInfo.ShowDialog(xSize, size, NULL, &dialogItems.Front(), numDialogItems); + return S_OK; +} + +int CPlugin::ProcessKey(int aKey, unsigned int controlState) +{ + if (controlState == PKF_CONTROL && aKey == 'A') + { + HRESULT result = ShowAttributesWindow(); + if (result == S_OK) + return TRUE; + if (result == S_FALSE) + return FALSE; + throw "Error"; + } + if ((controlState & PKF_ALT) != 0 && aKey == VK_F6) + { + UString folderPath; + if (!NFile::NDirectory::GetOnlyDirPrefix(m_FileName, folderPath)) + return FALSE; + PanelInfo panelInfo; + g_StartupInfo.ControlGetActivePanelInfo(panelInfo); + GetFilesReal(panelInfo.SelectedItems, + panelInfo.SelectedItemsNumber, FALSE, + UnicodeStringToMultiByte(folderPath, CP_OEMCP), OPM_SILENT, true); + g_StartupInfo.Control(this, FCTL_UPDATEPANEL, NULL); + g_StartupInfo.Control(this, FCTL_REDRAWPANEL, NULL); + g_StartupInfo.Control(this, FCTL_UPDATEANOTHERPANEL, NULL); + g_StartupInfo.Control(this, FCTL_REDRAWANOTHERPANEL, NULL); + return TRUE; + } + + return FALSE; +} diff --git a/CPP/7zip/UI/Far/Plugin.h b/CPP/7zip/UI/Far/Plugin.h new file mode 100755 index 00000000..0b617cfb --- /dev/null +++ b/CPP/7zip/UI/Far/Plugin.h @@ -0,0 +1,99 @@ +// 7zip/Far/Plugin.h + +#ifndef __7ZIP_FAR_PLUGIN_H +#define __7ZIP_FAR_PLUGIN_H + +#include "Common/MyCom.h" + +#include "Windows/COM.h" +#include "Windows/FileFind.h" +#include "Windows/PropVariant.h" + +#include "../Common/ArchiverInfo.h" +#include "../Agent/IFolderArchive.h" + +#include "FarUtils.h" + +class CPlugin +{ + NWindows::NCOM::CComInitializer m_ComInitializer; + UString m_CurrentDir; + + UString m_PannelTitle; + + InfoPanelLine m_InfoLines[30]; // Change it; + + char m_FileNameBuffer[1024]; + char m_CurrentDirBuffer[1024]; + char m_PannelTitleBuffer[1024]; + + AString PanelModeColumnTypes; + AString PanelModeColumnWidths; + PanelMode PanelMode; + void AddColumn(PROPID aPropID); + + + void EnterToDirectory(const UString &aDirName); + + void GetPathParts(UStringVector &aPathParts); + void GetCurrentDir(); +public: + UString m_FileName; + // UString m_DefaultName; + NWindows::NFile::NFind::CFileInfoW m_FileInfo; + + CMyComPtr m_ArchiveHandler; + CMyComPtr _folder; + + // CArchiverInfo m_ArchiverInfo; + UString _archiveTypeName; + + bool PasswordIsDefined; + UString Password; + + + CPlugin(const UString &fileName, + // const UString &aDefaultName, + IInFolderArchive *archiveHandler, + UString archiveTypeName + ); + ~CPlugin(); + + void ReadValueSafe(PROPID aPropID, NWindows::NCOM::CPropVariant aPropVariant); + void ReadPluginPanelItem(PluginPanelItem &aPanelItem, UINT32 anItemIndex); + + int GetFindData(PluginPanelItem **pPanelItem,int *pItemsNumber,int OpMode); + void FreeFindData(PluginPanelItem *PanelItem,int ItemsNumber); + int SetDirectory(const char *aDir, int opMode); + void GetOpenPluginInfo(struct OpenPluginInfo *anInfo); + + int DeleteFiles(PluginPanelItem *aPanelItems, int itemsNumber, int opMode); + + + HRESULT ExtractFiles( + bool decompressAllItems, + const UINT32 *indices, + UINT32 numIndices, + bool silent, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, + const UString &destPath, + bool passwordIsDefined, const UString &password); + + NFar::NFileOperationReturnCode::EEnum GetFiles(struct PluginPanelItem *aPanelItem, int itemsNumber, + int move, char *destPath, int opMode); + + NFar::NFileOperationReturnCode::EEnum GetFilesReal(struct PluginPanelItem *aPanelItems, + int itemsNumber, int move, const char *_aDestPath, int opMode, bool aShowBox); + + NFar::NFileOperationReturnCode::EEnum PutFiles(struct PluginPanelItem *aPanelItems, int itemsNumber, + int move, int opMode); + + HRESULT ShowAttributesWindow(); + + int ProcessKey(int aKey, unsigned int aControlState); +}; + +HRESULT CompressFiles(const CObjectVector &aPluginPanelItems); + +#endif diff --git a/CPP/7zip/UI/Far/PluginCommon.cpp b/CPP/7zip/UI/Far/PluginCommon.cpp new file mode 100755 index 00000000..3e8e3cee --- /dev/null +++ b/CPP/7zip/UI/Far/PluginCommon.cpp @@ -0,0 +1,50 @@ +// SevenZip/Plugin.cpp + +#include "StdAfx.h" + +#include "Plugin.h" + +/* +void CPlugin::AddRealIndexOfFile(const CArchiveFolderItem &aFolder, + int anIndexInVector, vector &aRealIndexes) +{ + const CArchiveFolderFileItem &anItem = aFolder.m_FileSubItems[anIndexInVector]; + int aHandlerItemIndex = m_ProxyHandler->GetHandlerItemIndex(anItem.m_Properties); + if(aHandlerItemIndex < 0) + throw "error"; + aRealIndexes.push_back(aHandlerItemIndex); +} + +void CPlugin::AddRealIndexes(const CArchiveFolderItem &anItem, + vector &aRealIndexes) +{ + int aHandlerItemIndex = m_ProxyHandler->GetHandlerItemIndex(anItem.m_Properties); + if(aHandlerItemIndex >= 0) // test -1 value + aRealIndexes.push_back(aHandlerItemIndex); + for(int i = 0; i < anItem.m_DirSubItems.Size(); i++) + AddRealIndexes(anItem.m_DirSubItems[i], aRealIndexes); + for(i = 0; i < anItem.m_FileSubItems.Size(); i++) + AddRealIndexOfFile(anItem, i , aRealIndexes); +} + + +void CPlugin::GetRealIndexes(PluginPanelItem *aPanelItems, int anItemsNumber, + vector &aRealIndexes) +{ + aRealIndexes.clear(); + for(int i = 0; i < anItemsNumber; i++) + { + int anIndex = aPanelItems[i].UserData; + if (anIndex < m_FolderItem->m_DirSubItems.Size()) + { + const CArchiveFolderItem &anItem = m_FolderItem->m_DirSubItems[anIndex]; + AddRealIndexes(anItem, aRealIndexes); + } + else + AddRealIndexOfFile(*m_FolderItem, anIndex - m_FolderItem->m_DirSubItems.Size(), + aRealIndexes); + } + sort(aRealIndexes.begin(), aRealIndexes.end()); +} + +*/ diff --git a/CPP/7zip/UI/Far/PluginDelete.cpp b/CPP/7zip/UI/Far/PluginDelete.cpp new file mode 100755 index 00000000..6a969c15 --- /dev/null +++ b/CPP/7zip/UI/Far/PluginDelete.cpp @@ -0,0 +1,169 @@ +// PluginDelete.cpp + +#include "StdAfx.h" + +#include + +#include "Plugin.h" +#include "Messages.h" +#include "UpdateCallback100.h" + +#include "Windows/FileDir.h" + +#include "../../Common/FileStreams.h" + +#include "Common/StringConvert.h" + +#include "../Common/ZipRegistry.h" +#include "../Common/WorkDir.h" + +using namespace NFar; +using namespace NWindows; +using namespace NFile; +using namespace NDirectory; + +static LPCWSTR kTempArchivePrefix = L"7zA"; + +int CPlugin::DeleteFiles(PluginPanelItem *panelItems, int numItems, + int opMode) +{ + if (numItems == 0) + return FALSE; + /* + if (!m_ArchiverInfo.UpdateEnabled) + { + g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive); + return FALSE; + } + */ + if ((opMode & OPM_SILENT) == 0) + { + const char *msgItems[]= + { + g_StartupInfo.GetMsgString(NMessageID::kDeleteTitle), + g_StartupInfo.GetMsgString(NMessageID::kDeleteFiles), + g_StartupInfo.GetMsgString(NMessageID::kDeleteDelete), + g_StartupInfo.GetMsgString(NMessageID::kDeleteCancel) + }; + char msg[1024]; + if (numItems == 1) + { + sprintf(msg, g_StartupInfo.GetMsgString(NMessageID::kDeleteFile), + panelItems[0].FindData.cFileName); + msgItems[1] = msg; + } + else if (numItems > 1) + { + sprintf(msg, g_StartupInfo.GetMsgString(NMessageID::kDeleteNumberOfFiles), + numItems); + msgItems[1] = msg; + } + if (g_StartupInfo.ShowMessage(FMSG_WARNING, NULL, msgItems, + sizeof(msgItems) / sizeof(msgItems[0]), 2) != 0) + return (FALSE); + } + + CScreenRestorer screenRestorer; + CProgressBox progressBox; + CProgressBox *progressBoxPointer = NULL; + if ((opMode & OPM_SILENT) == 0 && (opMode & OPM_FIND ) == 0) + { + screenRestorer.Save(); + + progressBoxPointer = &progressBox; + progressBox.Init(g_StartupInfo.GetMsgString(NMessageID::kWaitTitle), + g_StartupInfo.GetMsgString(NMessageID::kDeleting), 1 << 17); + } + + NWorkDir::CInfo workDirInfo; + ReadWorkDirInfo(workDirInfo); + + UString workDir = GetWorkDir(workDirInfo, m_FileName); + CreateComplexDirectory(workDir); + + CTempFileW tempFile; + UString tempFileName; + if (tempFile.Create(workDir, kTempArchivePrefix, tempFileName) == 0) + return FALSE; + + + CRecordVector indices; + indices.Reserve(numItems); + for(int i = 0; i < numItems; i++) + indices.Add(panelItems[i].UserData); + + //////////////////////////// + // Save _folder; + + UStringVector pathVector; + GetPathParts(pathVector); + + CMyComPtr outArchive; + HRESULT result = m_ArchiveHandler.QueryInterface( + IID_IOutFolderArchive, &outArchive); + if(result != S_OK) + { + g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive); + return FALSE; + } + outArchive->SetFolder(_folder); + + CUpdateCallback100Imp *updateCallbackSpec = new CUpdateCallback100Imp; + CMyComPtr 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 newFolder; + _folder->BindToFolder(pathVector[i], &newFolder); + if(!newFolder ) + break; + _folder = newFolder; + } + GetCurrentDir(); + + return(TRUE); +} diff --git a/CPP/7zip/UI/Far/PluginRead.cpp b/CPP/7zip/UI/Far/PluginRead.cpp new file mode 100755 index 00000000..503ff639 --- /dev/null +++ b/CPP/7zip/UI/Far/PluginRead.cpp @@ -0,0 +1,278 @@ +// PluginRead.cpp + +#include "StdAfx.h" + +#include "Plugin.h" + +#include "Messages.h" + +#include "Common/StringConvert.h" + +#include "Windows/FileName.h" +#include "Windows/FileFind.h" +#include "Windows/FileDir.h" +#include "Windows/Defs.h" + +#include "../Common/ZipRegistry.h" + +#include "ExtractEngine.h" + +using namespace NFar; +using namespace NWindows; + +static const char *kHelpTopicExtrFromSevenZip = "Extract"; + +static const char kDirDelimiter = '\\'; + +static const char *kExractPathHistoryName = "7-ZipExtractPath"; + +HRESULT CPlugin::ExtractFiles( + bool decompressAllItems, + const UINT32 *indices, + UINT32 numIndices, + bool silent, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, + const UString &destPath, + bool passwordIsDefined, const UString &password) +{ + CScreenRestorer screenRestorer; + CProgressBox progressBox; + CProgressBox *progressBoxPointer = NULL; + if (!silent) + { + screenRestorer.Save(); + + progressBoxPointer = &progressBox; + progressBox.Init(g_StartupInfo.GetMsgString(NMessageID::kWaitTitle), + g_StartupInfo.GetMsgString(NMessageID::kExtracting), 1 << 17); + } + + + CExtractCallBackImp *extractCallbackSpec = new CExtractCallBackImp; + CMyComPtr 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 archiveFolder; + _folder.QueryInterface(IID_IArchiveFolder, &archiveFolder); + + return archiveFolder->Extract(indices, numIndices, pathMode, overwriteMode, + destPath, BoolToInt(false), extractCallback); + } +} + +NFileOperationReturnCode::EEnum CPlugin::GetFiles(struct PluginPanelItem *panelItems, + int itemsNumber, int move, char *_aDestPath, int opMode) +{ + return GetFilesReal(panelItems, itemsNumber, move, + _aDestPath, opMode, (opMode & OPM_SILENT) == 0); +} + +NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *panelItems, + int itemsNumber, int move, const char *_aDestPath, int opMode, bool showBox) +{ + if(move != 0) + { + g_StartupInfo.ShowMessage(NMessageID::kMoveIsNotSupported); + return NFileOperationReturnCode::kError; + } + + CSysString destPath = _aDestPath; + NFile::NName::NormalizeDirPathPrefix(destPath); + + bool extractSelectedFiles = true; + + NExtract::CInfo extractionInfo; + extractionInfo.PathMode = NExtract::NPathMode::kCurrentPathnames; + extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt; + + bool silent = (opMode & OPM_SILENT) != 0; + bool decompressAllItems = false; + UString password = Password; + bool passwordIsDefined = PasswordIsDefined; + + if (!silent) + { + const int kPathIndex = 2; + + ReadExtractionInfo(extractionInfo); + + const int kPathModeRadioIndex = 4; + const int kOverwriteModeRadioIndex = kPathModeRadioIndex + 4; + const int kNumOverwriteOptions = 6; + const int kFilesModeIndex = kOverwriteModeRadioIndex + kNumOverwriteOptions; + const int kXSize = 76; + const int kYSize = 19; + const int kPasswordYPos = 12; + + const int kXMid = kXSize / 2; + + AString oemPassword = UnicodeStringToMultiByte(password, CP_OEMCP); + + struct CInitDialogItem initItems[]={ + { DI_DOUBLEBOX, 3, 1, kXSize - 4, kYSize - 2, false, false, 0, false, NMessageID::kExtractTitle, NULL, NULL }, + { DI_TEXT, 5, 2, 0, 0, false, false, 0, false, NMessageID::kExtractTo, NULL, NULL }, + + { DI_EDIT, 5, 3, kXSize - 6, 3, true, false, DIF_HISTORY, false, -1, destPath, kExractPathHistoryName}, + // { DI_EDIT, 5, 3, kXSize - 6, 3, true, false, 0, false, -1, destPath, NULL}, + + { DI_SINGLEBOX, 4, 5, kXMid - 2, 5 + 4, false, false, 0, false, NMessageID::kExtractPathMode, NULL, NULL }, + { DI_RADIOBUTTON, 6, 6, 0, 0, false, + extractionInfo.PathMode == NExtract::NPathMode::kFullPathnames, + DIF_GROUP, false, NMessageID::kExtractPathFull, NULL, NULL }, + { DI_RADIOBUTTON, 6, 7, 0, 0, false, + extractionInfo.PathMode == NExtract::NPathMode::kCurrentPathnames, + 0, false, NMessageID::kExtractPathCurrent, NULL, NULL }, + { DI_RADIOBUTTON, 6, 8, 0, 0, false, + extractionInfo.PathMode == NExtract::NPathMode::kNoPathnames, + false, 0, NMessageID::kExtractPathNo, NULL, NULL }, + + { DI_SINGLEBOX, kXMid, 5, kXSize - 6, 5 + kNumOverwriteOptions, false, false, 0, false, NMessageID::kExtractOwerwriteMode, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 6, 0, 0, false, + extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kAskBefore, + DIF_GROUP, false, NMessageID::kExtractOwerwriteAsk, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 7, 0, 0, false, + extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kWithoutPrompt, + 0, false, NMessageID::kExtractOwerwritePrompt, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 8, 0, 0, false, + extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kSkipExisting, + 0, false, NMessageID::kExtractOwerwriteSkip, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 9, 0, 0, false, + extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kAutoRename, + 0, false, NMessageID::kExtractOwerwriteAutoRename, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 10, 0, 0, false, + extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kAutoRenameExisting, + 0, false, NMessageID::kExtractOwerwriteAutoRenameExisting, NULL, NULL }, + + { DI_SINGLEBOX, 4, 10, kXMid- 2, 10 + 3, false, false, 0, false, NMessageID::kExtractFilesMode, NULL, NULL }, + { DI_RADIOBUTTON, 6, 11, 0, 0, false, true, DIF_GROUP, false, NMessageID::kExtractFilesSelected, NULL, NULL }, + { DI_RADIOBUTTON, 6, 12, 0, 0, false, false, 0, false, NMessageID::kExtractFilesAll, NULL, NULL }, + + { DI_SINGLEBOX, kXMid, kPasswordYPos, kXSize - 6, kPasswordYPos + 2, false, false, 0, false, NMessageID::kExtractPassword, NULL, NULL }, + { DI_PSWEDIT, kXMid + 2, kPasswordYPos + 1, kXSize - 8, 12, false, false, 0, false, -1, oemPassword, NULL}, + + { DI_TEXT, 3, kYSize - 4, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL }, + + + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, true, NMessageID::kExtractExtract, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kExtractCancel, NULL, NULL } + }; + + const int kNumDialogItems = sizeof(initItems) / sizeof(initItems[0]); + const int kOkButtonIndex = kNumDialogItems - 2; + const int kPasswordIndex = kNumDialogItems - 4; + + FarDialogItem dialogItems[kNumDialogItems]; + g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems); + for (;;) + { + int askCode = g_StartupInfo.ShowDialog(kXSize, kYSize, + kHelpTopicExtrFromSevenZip, dialogItems, kNumDialogItems); + if (askCode != kOkButtonIndex) + return NFileOperationReturnCode::kInterruptedByUser; + destPath = dialogItems[kPathIndex].Data; + destPath.Trim(); + if (destPath.IsEmpty()) + { + if(!NFile::NDirectory::MyGetCurrentDirectory(destPath)) + throw 318016; + NFile::NName::NormalizeDirPathPrefix(destPath); + break; + } + else + { + if(destPath[destPath.Length() - 1] == kDirDelimiter) + break; + } + g_StartupInfo.ShowMessage("You must specify directory path"); + } + + if (dialogItems[kPathModeRadioIndex].Selected) + extractionInfo.PathMode = NExtract::NPathMode::kFullPathnames; + else if (dialogItems[kPathModeRadioIndex + 1].Selected) + extractionInfo.PathMode = NExtract::NPathMode::kCurrentPathnames; + else if (dialogItems[kPathModeRadioIndex + 2].Selected) + extractionInfo.PathMode = NExtract::NPathMode::kNoPathnames; + else + throw 31806; + + if (dialogItems[kOverwriteModeRadioIndex].Selected) + extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kAskBefore; + else if (dialogItems[kOverwriteModeRadioIndex + 1].Selected) + extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt; + else if (dialogItems[kOverwriteModeRadioIndex + 2].Selected) + extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kSkipExisting; + else if (dialogItems[kOverwriteModeRadioIndex + 3].Selected) + extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kAutoRename; + else if (dialogItems[kOverwriteModeRadioIndex + 4].Selected) + extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kAutoRenameExisting; + else + throw 31806; + + if (dialogItems[kFilesModeIndex].Selected) + decompressAllItems = false; + else if (dialogItems[kFilesModeIndex + 1].Selected) + decompressAllItems = true; + else + throw 31806; + + SaveExtractionInfo(extractionInfo); + + if (dialogItems[kFilesModeIndex].Selected) + extractSelectedFiles = true; + else if (dialogItems[kFilesModeIndex + 1].Selected) + extractSelectedFiles = false; + else + throw 31806; + + oemPassword = dialogItems[kPasswordIndex].Data; + password = MultiByteToUnicodeString(oemPassword, CP_OEMCP); + passwordIsDefined = !password.IsEmpty(); + } + + NFile::NDirectory::CreateComplexDirectory(destPath); + + /* + vector realIndices; + if (!decompressAllItems) + GetRealIndexes(panelItems, itemsNumber, realIndices); + */ + CRecordVector indices; + indices.Reserve(itemsNumber); + for (int i = 0; i < itemsNumber; i++) + indices.Add(panelItems[i].UserData); + + HRESULT result = ExtractFiles(decompressAllItems, &indices.Front(), itemsNumber, + !showBox, extractionInfo.PathMode, extractionInfo.OverwriteMode, + MultiByteToUnicodeString(destPath, CP_OEMCP), + passwordIsDefined, password); + // HRESULT result = ExtractFiles(decompressAllItems, realIndices, !showBox, + // extractionInfo, destPath, passwordIsDefined, password); + if (result != S_OK) + { + if (result == E_ABORT) + return NFileOperationReturnCode::kInterruptedByUser; + ShowErrorMessage(result); + return NFileOperationReturnCode::kError; + } + + // if(move != 0) + // { + // if(DeleteFiles(panelItems, itemsNumber, opMode) == FALSE) + // return NFileOperationReturnCode::kError; + // } + return NFileOperationReturnCode::kSuccess; +} diff --git a/CPP/7zip/UI/Far/PluginWrite.cpp b/CPP/7zip/UI/Far/PluginWrite.cpp new file mode 100755 index 00000000..d6730985 --- /dev/null +++ b/CPP/7zip/UI/Far/PluginWrite.cpp @@ -0,0 +1,696 @@ +// PluginWrite.cpp + +#include "StdAfx.h" + +#include "Plugin.h" + +#include "Common/StringConvert.h" + +#include "Windows/FileDir.h" +#include "Windows/FileName.h" +#include "Windows/FileFind.h" +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" + +#include "../Common/ZipRegistry.h" +#include "../Common/WorkDir.h" +#include "../Common/OpenArchive.h" + +#include "../Agent/Agent.h" + +#include "ProgressBox.h" +#include "Messages.h" +#include "UpdateCallback100.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDirectory; +using namespace NFar; + +using namespace NUpdateArchive; + +static const char *kHelpTopic = "Update"; + +static LPCWSTR kTempArcivePrefix = L"7zA"; + +static const char *kArchiveHistoryKeyName = "7-ZipArcName"; + +static UINT32 g_MethodMap[] = { 0, 1, 3, 5, 7, 9 }; + +static HRESULT SetOutProperties(IOutFolderArchive *outArchive, UINT32 method) +{ + CMyComPtr setProperties; + if (outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties) == S_OK) + { + UStringVector realNames; + realNames.Add(UString(L"x")); + NCOM::CPropVariant value = (UInt32)method; + CRecordVector names; + for(int i = 0; i < realNames.Size(); i++) + names.Add(realNames[i]); + RINOK(setProperties->SetProperties(&names.Front(), &value, names.Size())); + } + return S_OK; +} + +NFileOperationReturnCode::EEnum CPlugin::PutFiles( + struct PluginPanelItem *panelItems, int numItems, + int moveMode, int opMode) +{ + if(moveMode != 0) + { + g_StartupInfo.ShowMessage(NMessageID::kMoveIsNotSupported); + return NFileOperationReturnCode::kError; + } + if (numItems == 0) + return NFileOperationReturnCode::kError; + + /* + if (!m_ArchiverInfo.UpdateEnabled) + { + g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive); + return NFileOperationReturnCode::kError; + } + */ + + const int kYSize = 14; + const int kXMid = 38; + + NCompression::CInfo compressionInfo; + ReadCompressionInfo(compressionInfo); + + int methodIndex = 0; + for (int i = sizeof(g_MethodMap) / sizeof(g_MethodMap[0]) - 1; i >= 0; i--) + if (compressionInfo.Level >= g_MethodMap[i]) + { + methodIndex = i; + break; + } + + const int kMethodRadioIndex = 2; + const int kModeRadioIndex = kMethodRadioIndex + 7; + + struct CInitDialogItem initItems[]={ + { DI_DOUBLEBOX, 3, 1, 72, kYSize - 2, false, false, 0, false, NMessageID::kUpdateTitle, NULL, NULL }, + { DI_SINGLEBOX, 4, 2, kXMid - 2, 2 + 7, false, false, 0, false, NMessageID::kUpdateMethod, NULL, NULL }, + { DI_RADIOBUTTON, 6, 3, 0, 0, methodIndex == 0, methodIndex == 0, + DIF_GROUP, false, NMessageID::kUpdateMethodStore, NULL, NULL }, + { DI_RADIOBUTTON, 6, 4, 0, 0, methodIndex == 1, methodIndex == 1, + 0, false, NMessageID::kUpdateMethodFastest, NULL, NULL }, + { DI_RADIOBUTTON, 6, 5, 0, 0, methodIndex == 2, methodIndex == 2, + 0, false, NMessageID::kUpdateMethodFast, NULL, NULL }, + { DI_RADIOBUTTON, 6, 6, 0, 0, methodIndex == 3, methodIndex == 3, + 0, false, NMessageID::kUpdateMethodNormal, NULL, NULL }, + { DI_RADIOBUTTON, 6, 7, 0, 0, methodIndex == 4, methodIndex == 4, + 0, false, NMessageID::kUpdateMethodMaximum, NULL, NULL }, + { DI_RADIOBUTTON, 6, 8, 0, 0, methodIndex == 5, methodIndex == 5, + 0, false, NMessageID::kUpdateMethodUltra, NULL, NULL }, + + { DI_SINGLEBOX, kXMid, 2, 70, 2 + 5, false, false, 0, false, NMessageID::kUpdateMode, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 3, 0, 0, false, true, + DIF_GROUP, false, NMessageID::kUpdateModeAdd, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 4, 0, 0, false, false, + 0, false, NMessageID::kUpdateModeUpdate, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 5, 0, 0, false, false, + 0, false, NMessageID::kUpdateModeFreshen, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 6, 0, 0, false, false, + 0, false, NMessageID::kUpdateModeSynchronize, NULL, NULL }, + + { DI_TEXT, 3, kYSize - 4, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL }, + + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, true, NMessageID::kUpdateAdd, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kCancel, NULL, NULL } + }; + + const int kNumDialogItems = sizeof(initItems) / sizeof(initItems[0]); + const int kOkButtonIndex = kNumDialogItems - 2; + FarDialogItem dialogItems[kNumDialogItems]; + g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems); + int askCode = g_StartupInfo.ShowDialog(76, kYSize, + kHelpTopic, dialogItems, kNumDialogItems); + if (askCode != kOkButtonIndex) + return NFileOperationReturnCode::kInterruptedByUser; + + compressionInfo.Level = g_MethodMap[0]; + for (i = 0; i < sizeof(g_MethodMap)/ sizeof(g_MethodMap[0]); i++) + if (dialogItems[kMethodRadioIndex + i].Selected) + compressionInfo.Level = g_MethodMap[i]; + + const CActionSet *actionSet; + + if (dialogItems[kModeRadioIndex].Selected) + actionSet = &kAddActionSet; + else if (dialogItems[kModeRadioIndex + 1].Selected) + actionSet = &kUpdateActionSet; + else if (dialogItems[kModeRadioIndex + 2].Selected) + actionSet = &kFreshActionSet; + else if (dialogItems[kModeRadioIndex + 3].Selected) + actionSet = &kSynchronizeActionSet; + else + throw 51751; + + SaveCompressionInfo(compressionInfo); + + NWorkDir::CInfo workDirInfo; + ReadWorkDirInfo(workDirInfo); + UString workDir = GetWorkDir(workDirInfo, m_FileName); + CreateComplexDirectory(workDir); + + CTempFileW tempFile; + UString tempFileName; + if (tempFile.Create(workDir, kTempArcivePrefix, tempFileName) == 0) + return NFileOperationReturnCode::kError; + + + /* + CSysStringVector fileNames; + for(int i = 0; i < numItems; i++) + { + const PluginPanelItem &panelItem = panelItems[i]; + CSysString fullName; + if (!MyGetFullPathName(panelItem.FindData.cFileName, fullName)) + return NFileOperationReturnCode::kError; + fileNames.Add(fullName); + } + */ + + CScreenRestorer screenRestorer; + CProgressBox progressBox; + CProgressBox *progressBoxPointer = NULL; + if ((opMode & OPM_SILENT) == 0 && (opMode & OPM_FIND ) == 0) + { + screenRestorer.Save(); + + progressBoxPointer = &progressBox; + progressBox.Init(g_StartupInfo.GetMsgString(NMessageID::kWaitTitle), + g_StartupInfo.GetMsgString(NMessageID::kUpdating), 1 << 16); + } + + //////////////////////////// + // Save FolderItem; + UStringVector aPathVector; + GetPathParts(aPathVector); + + /* + UString anArchivePrefix; + for(i = aPathVector.Size() - 1; i >= 0; i--) + { + anArchivePrefix += aPathVector[i]; + anArchivePrefix += wchar_t(NName::kDirDelimiter); + } + ///////////////////////////////// + */ + + UStringVector fileNames; + fileNames.Reserve(numItems); + for(i = 0; i < numItems; i++) + fileNames.Add(MultiByteToUnicodeString(panelItems[i].FindData.cFileName, CP_OEMCP)); + CRecordVector fileNamePointers; + fileNamePointers.Reserve(numItems); + for(i = 0; i < numItems; i++) + fileNamePointers.Add(fileNames[i]); + + CMyComPtr 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 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 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 &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 archiverInfoList; + { + CObjectVector fullArchiverInfoList; + ReadArchiverInfoList(fullArchiverInfoList); + for (int i = 0; i < fullArchiverInfoList.Size(); i++) + { + const CArchiverInfo &archiverInfo = fullArchiverInfoList[i]; + if (archiverInfo.UpdateEnabled) + { + if (archiverInfo.Name.CompareNoCase(compressionInfo.ArchiveType) == 0) + archiverIndex = archiverInfoList.Size(); + archiverInfoList.Add(archiverInfo); + } + } + } + if (archiverInfoList.IsEmpty()) + throw "There is no update achivers"; + + + UString resultPath; + { + NName::CParsedPath parsedPath; + parsedPath.ParsePath(fileNames.Front()); + if(parsedPath.PathParts.Size() == 0) + return E_FAIL; + if (fileNames.Size() == 1 || parsedPath.PathParts.Size() == 1) + { + // CSysString pureName, dot, extension; + resultPath = parsedPath.PathParts.Back(); + } + else + { + parsedPath.PathParts.DeleteBack(); + resultPath = parsedPath.PathParts.Back(); + } + } + UString archiveNameSrc = resultPath; + UString archiveName = archiveNameSrc; + + const CArchiverInfo &archiverInfo = archiverInfoList[archiverIndex]; + int prevFormat = archiverIndex; + + if (!archiverInfo.KeepName) + { + int dotPos = archiveName.ReverseFind('.'); + int slashPos = MyMax(archiveName.ReverseFind('\\'), archiveName.ReverseFind('/')); + if (dotPos > slashPos) + archiveName = archiveName.Left(dotPos); + } + archiveName += L'.'; + archiveName += archiverInfo.GetMainExtension(); + + const CActionSet *actionSet = &kAddActionSet; + + for (;;) + { + AString archiveNameA = UnicodeStringToMultiByte(archiveName, CP_OEMCP); + const int kYSize = 16; + const int kXMid = 38; + + const int kArchiveNameIndex = 2; + const int kMethodRadioIndex = kArchiveNameIndex + 2; + const int kModeRadioIndex = kMethodRadioIndex + 7; + + const CArchiverInfo &archiverInfo = archiverInfoList[archiverIndex]; + + char updateAddToArchiveString[512]; + sprintf(updateAddToArchiveString, + g_StartupInfo.GetMsgString(NMessageID::kUpdateAddToArchive), GetSystemString(archiverInfo.Name), CP_OEMCP); + + int methodIndex = 0; + for (int i = sizeof(g_MethodMap) / sizeof(g_MethodMap[0]) - 1; i >= 0; i--) + if (compressionInfo.Level >= g_MethodMap[i]) + { + methodIndex = i; + break; + } + + struct CInitDialogItem initItems[]= + { + { DI_DOUBLEBOX, 3, 1, 72, kYSize - 2, false, false, 0, false, NMessageID::kUpdateTitle, NULL, NULL }, + + { DI_TEXT, 5, 2, 0, 0, false, false, 0, false, -1, updateAddToArchiveString, NULL }, + + { DI_EDIT, 5, 3, 70, 3, true, false, DIF_HISTORY, false, -1, archiveNameA, kArchiveHistoryKeyName}, + // { DI_EDIT, 5, 3, 70, 3, true, false, 0, false, -1, archiveName, NULL}, + + { DI_SINGLEBOX, 4, 4, kXMid - 2, 4 + 7, false, false, 0, false, NMessageID::kUpdateMethod, NULL, NULL }, + { DI_RADIOBUTTON, 6, 5, 0, 0, false, methodIndex == 0, + DIF_GROUP, false, NMessageID::kUpdateMethodStore, NULL, NULL }, + { DI_RADIOBUTTON, 6, 6, 0, 0, false, methodIndex == 1, + 0, false, NMessageID::kUpdateMethodFastest, NULL, NULL }, + { DI_RADIOBUTTON, 6, 7, 0, 0, false, methodIndex == 2, + 0, false, NMessageID::kUpdateMethodFast, NULL, NULL }, + { DI_RADIOBUTTON, 6, 8, 0, 0, false, methodIndex == 3, + 0, false, NMessageID::kUpdateMethodNormal, NULL, NULL }, + { DI_RADIOBUTTON, 6, 9, 0, 0, false, methodIndex == 4, + false, 0, NMessageID::kUpdateMethodMaximum, NULL, NULL }, + { DI_RADIOBUTTON, 6, 10, 0, 0, false, methodIndex == 5, + false, 0, NMessageID::kUpdateMethodUltra, NULL, NULL }, + + { DI_SINGLEBOX, kXMid, 4, 70, 4 + 5, false, false, 0, false, NMessageID::kUpdateMode, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 5, 0, 0, false, + actionSet == &kAddActionSet, + DIF_GROUP, false, NMessageID::kUpdateModeAdd, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 6, 0, 0, false, + actionSet == &kUpdateActionSet, + 0, false, NMessageID::kUpdateModeUpdate, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 7, 0, 0, false, + actionSet == &kFreshActionSet, + 0, false, NMessageID::kUpdateModeFreshen, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 8, 0, 0, false, + actionSet == &kSynchronizeActionSet, + 0, false, NMessageID::kUpdateModeSynchronize, NULL, NULL }, + + { DI_TEXT, 3, kYSize - 4, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL }, + + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, true, NMessageID::kUpdateAdd, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kUpdateSelectArchiver, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kCancel, NULL, NULL } + }; + + const int kNumDialogItems = sizeof(initItems) / sizeof(initItems[0]); + + const int kOkButtonIndex = kNumDialogItems - 3; + const int kSelectarchiverButtonIndex = kNumDialogItems - 2; + + FarDialogItem dialogItems[kNumDialogItems]; + g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems); + int askCode = g_StartupInfo.ShowDialog(76, kYSize, + kHelpTopic, dialogItems, kNumDialogItems); + + archiveNameA = dialogItems[kArchiveNameIndex].Data; + archiveNameA.Trim(); + archiveName = MultiByteToUnicodeString(archiveNameA, CP_OEMCP); + + compressionInfo.Level = g_MethodMap[0]; + for (i = 0; i < sizeof(g_MethodMap)/ sizeof(g_MethodMap[0]); i++) + if (dialogItems[kMethodRadioIndex + i].Selected) + compressionInfo.Level = g_MethodMap[i]; + + if (dialogItems[kModeRadioIndex].Selected) + actionSet = &kAddActionSet; + else if (dialogItems[kModeRadioIndex + 1].Selected) + actionSet = &kUpdateActionSet; + else if (dialogItems[kModeRadioIndex + 2].Selected) + actionSet = &kFreshActionSet; + else if (dialogItems[kModeRadioIndex + 3].Selected) + actionSet = &kSynchronizeActionSet; + else + throw 51751; + + if (askCode == kSelectarchiverButtonIndex) + { + CSysStringVector archiverNames; + for(int i = 0; i < archiverInfoList.Size(); i++) + archiverNames.Add(GetSystemString(archiverInfoList[i].Name, + CP_OEMCP)); + + int index = g_StartupInfo.Menu(FMENU_AUTOHIGHLIGHT, + g_StartupInfo.GetMsgString(NMessageID::kUpdateSelectArchiverMenuTitle), + NULL, archiverNames, archiverIndex); + if(index >= 0) + { + const CArchiverInfo &prevArchiverInfo = archiverInfoList[prevFormat]; + if (prevArchiverInfo.KeepName) + { + const UString &prevExtension = prevArchiverInfo.GetMainExtension(); + const int prevExtensionLen = prevExtension.Length(); + if (archiveName.Right(prevExtensionLen).CompareNoCase(prevExtension) == 0) + { + int pos = archiveName.Length() - prevExtensionLen; + UString temp = archiveName.Left(pos); + if (pos > 1) + { + int dotPos = archiveName.ReverseFind('.'); + if (dotPos == pos - 1) + archiveName = archiveName.Left(dotPos); + } + } + } + + archiverIndex = index; + const CArchiverInfo &archiverInfo = + archiverInfoList[archiverIndex]; + prevFormat = archiverIndex; + + if (archiverInfo.KeepName) + archiveName = archiveNameSrc; + else + { + int dotPos = archiveName.ReverseFind('.'); + int slashPos = MyMax(archiveName.ReverseFind('\\'), archiveName.ReverseFind('/')); + if (dotPos > slashPos) + archiveName = archiveName.Left(dotPos); + } + archiveName += L'.'; + archiveName += archiverInfo.GetMainExtension(); + } + continue; + } + + if (askCode != kOkButtonIndex) + return E_ABORT; + + break; + } + + const CArchiverInfo &archiverInfoFinal = archiverInfoList[archiverIndex]; + compressionInfo.ArchiveType = archiverInfoFinal.Name; + SaveCompressionInfo(compressionInfo); + + NWorkDir::CInfo workDirInfo; + ReadWorkDirInfo(workDirInfo); + + UString fullArchiveName; + if (!MyGetFullPathName(archiveName, fullArchiveName)) + return E_FAIL; + + UString workDir = GetWorkDir(workDirInfo, fullArchiveName); + CreateComplexDirectory(workDir); + + CTempFileW tempFile; + UString tempFileName; + if (tempFile.Create(workDir, kTempArcivePrefix, tempFileName) == 0) + return E_FAIL; + + + CScreenRestorer screenRestorer; + CProgressBox progressBox; + CProgressBox *progressBoxPointer = NULL; + + screenRestorer.Save(); + + progressBoxPointer = &progressBox; + progressBox.Init(g_StartupInfo.GetMsgString(NMessageID::kWaitTitle), + g_StartupInfo.GetMsgString(NMessageID::kUpdating), 1 << 16); + + + NFind::CFileInfoW fileInfo; + + CMyComPtr outArchive; + + CMyComPtr archiveHandler; + if(NFind::FindFile(fullArchiveName, fileInfo)) + { + if (fileInfo.IsDirectory()) + throw "There is Directory with such name"; + + CAgent *agentSpec = new CAgent; + archiveHandler = agentSpec; + // CLSID realClassID; + CMyComBSTR archiveType; + RINOK(agentSpec->Open( + GetUnicodeString(fullArchiveName, CP_OEMCP), + // &realClassID, + &archiveType, + NULL)); + + if (archiverInfoFinal.Name.CompareNoCase((const wchar_t *)archiveType) != 0) + throw "Type of existing archive differs from specified type"; + HRESULT result = archiveHandler.QueryInterface( + IID_IOutFolderArchive, &outArchive); + if(result != S_OK) + { + g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive); + return E_FAIL; + } + } + else + { + // HRESULT result = outArchive.CoCreateInstance(classID); + CAgent *agentSpec = new CAgent; + outArchive = agentSpec; + + /* + HRESULT result = outArchive.CoCreateInstance(CLSID_CAgentArchiveHandler); + if (result != S_OK) + { + g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive); + return E_FAIL; + } + */ + } + + CRecordVector 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 updateCallback(updateCallbackSpec ); + + updateCallbackSpec->Init(archiveHandler, &progressBox); + + + RINOK(SetOutProperties(outArchive, compressionInfo.Level)); + + HRESULT result = outArchive->DoOperation( + GetUnicodeString(archiverInfoFinal.FilePath, CP_OEMCP), + &archiverInfoFinal.ClassID, + tempFileName, actionSetByte, + NULL, updateCallback); + updateCallback.Release(); + outArchive.Release(); + + if (result != S_OK) + { + ShowErrorMessage(result); + return result; + } + + if(archiveHandler) + { + archiveHandler->Close(); + if (!DeleteFileAlways(fullArchiveName)) + { + ShowLastErrorMessage(); + return NFileOperationReturnCode::kError; + } + } + tempFile.DisableDeleting(); + if (!MyMoveFile(tempFileName, fullArchiveName)) + { + ShowLastErrorMessage(); + return E_FAIL; + } + + return S_OK; +} + diff --git a/CPP/7zip/UI/Far/ProgressBox.cpp b/CPP/7zip/UI/Far/ProgressBox.cpp new file mode 100755 index 00000000..64e0e09d --- /dev/null +++ b/CPP/7zip/UI/Far/ProgressBox.cpp @@ -0,0 +1,103 @@ +// ProgressBox.cpp + +#include "StdAfx.h" + +#include + +#include "ProgressBox.h" + +#include "FarUtils.h" + +using namespace NFar; + +static void CopySpaces(char *destString, int numSpaces) +{ + for(int i = 0; i < numSpaces; i++) + destString[i] = ' '; + destString[i] = '\0'; +} + +///////////////////////////////// +// CMessageBox + +const int kNumStringsMax = 10; + +void CMessageBox::Init(const CSysString &title, const CSysString &message, + int numStrings, int width) +{ + if (numStrings > kNumStringsMax) + throw 120620; + m_NumStrings = numStrings; + m_Width = width; + + m_Title = title; + m_Message = message; +} + +const int kNumStaticStrings = 2; + +void CMessageBox::ShowProcessMessages(const char *messages[]) +{ + const char *msgItems[kNumStaticStrings + kNumStringsMax]; + msgItems[0] = m_Title; + msgItems[1] = m_Message; + + char formattedMessages[kNumStringsMax][256]; + + for (int i = 0; i < m_NumStrings; i++) + { + char *formattedMessage = formattedMessages[i]; + int len = strlen(messages[i]); + int size = MyMax(m_Width, len); + int startPos = (size - len) / 2; + CopySpaces(formattedMessage, startPos); + strcpy(formattedMessage + startPos, messages[i]); + CopySpaces(formattedMessage + startPos + len, size - startPos - len); + msgItems[kNumStaticStrings + i] = formattedMessage; + } + + g_StartupInfo.ShowMessage(0, NULL, msgItems, kNumStaticStrings + m_NumStrings, 0); +} + +///////////////////////////////// +// CProgressBox + +void CProgressBox::Init(const CSysString &title, const CSysString &message, + UInt64 step) +{ + CMessageBox::Init(title, message, 1, 22); + m_Step = step; + m_CompletedPrev = 0; + m_Total = 0; +} + + +void CProgressBox::ShowProcessMessage(const char *message) +{ + CMessageBox::ShowProcessMessages(&message); +} + +void CProgressBox::PrintPercent(UInt64 percent) +{ + char valueBuffer[32]; + sprintf(valueBuffer, "%I64u%%", percent); + ShowProcessMessage(valueBuffer); +} + +void CProgressBox::SetTotal(UInt64 total) +{ + m_Total = total; +} + +void CProgressBox::PrintCompeteValue(UInt64 completed) +{ + if (completed >= m_CompletedPrev + m_Step || completed < m_CompletedPrev || + completed == 0) + { + if (m_Total == 0) + PrintPercent(0); + else + PrintPercent(completed * 100 / m_Total); + m_CompletedPrev = completed; + } +} diff --git a/CPP/7zip/UI/Far/ProgressBox.h b/CPP/7zip/UI/Far/ProgressBox.h new file mode 100755 index 00000000..8721b456 --- /dev/null +++ b/CPP/7zip/UI/Far/ProgressBox.h @@ -0,0 +1,35 @@ +// ProgressBox.h + +#ifndef __PROGRESSBOX_H +#define __PROGRESSBOX_H + +#include "Common/String.h" +#include "Common/Types.h" + +class CMessageBox +{ + CSysString m_Title; + CSysString m_Message; + int m_NumStrings; + int m_Width; +public: + void Init(const CSysString &title, + const CSysString &message, int numStrings, int width); + void ShowProcessMessages(const char *messages[]); +}; + +class CProgressBox: public CMessageBox +{ + UInt64 m_Total; + UInt64 m_CompletedPrev; + UInt64 m_Step; +public: + void Init(const CSysString &title, + const CSysString &message, UInt64 step); + void ShowProcessMessage(const char *message); + void PrintPercent(UInt64 percent); + void PrintCompeteValue(UInt64 completed); + void SetTotal(UInt64 total); +}; + +#endif diff --git a/CPP/7zip/UI/Far/StdAfx.cpp b/CPP/7zip/UI/Far/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/UI/Far/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/UI/Far/StdAfx.h b/CPP/7zip/UI/Far/StdAfx.h new file mode 100755 index 00000000..0a7c347b --- /dev/null +++ b/CPP/7zip/UI/Far/StdAfx.h @@ -0,0 +1,12 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include +#include + +#include "Common/NewHandler.h" + +#endif + diff --git a/CPP/7zip/UI/Far/UpdateCallback100.cpp b/CPP/7zip/UI/Far/UpdateCallback100.cpp new file mode 100755 index 00000000..f1a2946e --- /dev/null +++ b/CPP/7zip/UI/Far/UpdateCallback100.cpp @@ -0,0 +1,54 @@ +// UpdateCallback.h + +#include "StdAfx.h" + +#include "UpdateCallback100.h" + +#include "Common/Defs.h" +#include "Common/StringConvert.h" +#include "FarUtils.h" + +using namespace NFar; + +STDMETHODIMP CUpdateCallback100Imp::SetTotal(UINT64 aSize) +{ + if (m_ProgressBox != 0) + { + m_ProgressBox->SetTotal(aSize); + m_ProgressBox->PrintCompeteValue(0); + } + return S_OK; +} + +STDMETHODIMP CUpdateCallback100Imp::SetCompleted(const UINT64 *aCompleteValue) +{ + if(WasEscPressed()) + return E_ABORT; + if (m_ProgressBox != 0 && aCompleteValue != NULL) + m_ProgressBox->PrintCompeteValue(*aCompleteValue); + return S_OK; +} + +STDMETHODIMP CUpdateCallback100Imp::CompressOperation(const wchar_t *aName) +{ + return S_OK; +} + +STDMETHODIMP CUpdateCallback100Imp::DeleteOperation(const wchar_t *aName) +{ + return S_OK; +} + +STDMETHODIMP CUpdateCallback100Imp::OperationResult(INT32 aOperationResult) +{ + return S_OK; +} + +STDMETHODIMP CUpdateCallback100Imp::UpdateErrorMessage(const wchar_t *message) +{ + CSysString s = UnicodeStringToMultiByte(message, CP_OEMCP); + if (g_StartupInfo.ShowMessage(s) == -1) + return E_ABORT; + return S_OK; +} + diff --git a/CPP/7zip/UI/Far/UpdateCallback100.h b/CPP/7zip/UI/Far/UpdateCallback100.h new file mode 100755 index 00000000..d66137cc --- /dev/null +++ b/CPP/7zip/UI/Far/UpdateCallback100.h @@ -0,0 +1,45 @@ +// UpdateCallback.h + +#ifndef __UPDATECALLBACK100_H +#define __UPDATECALLBACK100_H + +#include "Common/String.h" +#include "Common/MyCom.h" + +#include "../Agent/IFolderArchive.h" + +#include "ProgressBox.h" + +class CUpdateCallback100Imp: + public IFolderArchiveUpdateCallback, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + // IProfress + + STDMETHOD(SetTotal)(UINT64 aSize); + STDMETHOD(SetCompleted)(const UINT64 *aCompleteValue); + + // IUpdateCallBack + STDMETHOD(CompressOperation)(const wchar_t *aName); + STDMETHOD(DeleteOperation)(const wchar_t *aName); + STDMETHOD(OperationResult)(INT32 aOperationResult); + STDMETHOD(UpdateErrorMessage)(const wchar_t *message); + +private: + CMyComPtr m_ArchiveHandler; + CProgressBox *m_ProgressBox; +public: + void Init(IInFolderArchive *anArchiveHandler, + CProgressBox *aProgressBox) + { + m_ArchiveHandler = anArchiveHandler; + m_ProgressBox = aProgressBox; + } +}; + + + +#endif diff --git a/CPP/7zip/UI/Far/makefile b/CPP/7zip/UI/Far/makefile new file mode 100755 index 00000000..4dbd1988 --- /dev/null +++ b/CPP/7zip/UI/Far/makefile @@ -0,0 +1,102 @@ +PROG = 7-ZipFar.dll +DEF_FILE = Far.def +LIBS = $(LIBS) user32.lib oleaut32.lib advapi32.lib ole32.lib +CFLAGS = $(CFLAGS) -I ../../../ -DWIN_LONG_PATH + +FAR_OBJS = \ + $O\CLSIDConst.obj \ + $O\ExtractEngine.obj \ + $O\FarUtils.obj \ + $O\Main.obj \ + $O\OverwriteDialog.obj \ + $O\Plugin.obj \ + $O\PluginCommon.obj \ + $O\PluginDelete.obj \ + $O\PluginRead.obj \ + $O\PluginWrite.obj \ + $O\ProgressBox.obj \ + $O\UpdateCallback100.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\Vector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\Error.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\PropVariant.obj \ + $O\PropVariantConversions.obj \ + $O\Registry.obj \ + $O\Synchronization.obj \ + +7ZIP_COMMON_OBJS = \ + $O\FilePathAutoRename.obj \ + $O\FileStreams.obj \ + $O\StreamUtils.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveExtractCallback.obj \ + $O\ArchiveOpenCallback.obj \ + $O\ArchiverInfo.obj \ + $O\DefaultName.obj \ + $O\EnumDirItems.obj \ + $O\ExtractingFilePath.obj \ + $O\OpenArchive.obj \ + $O\PropIDUtils.obj \ + $O\SortUtils.obj \ + $O\UpdateAction.obj \ + $O\UpdateCallback.obj \ + $O\UpdatePair.obj \ + $O\UpdateProduce.obj \ + $O\WorkDir.obj \ + $O\ZipRegistry.obj \ + +AGENT_OBJS = \ + $O\Agent.obj \ + $O\AgentOut.obj \ + $O\AgentProxy.obj \ + $O\UpdateCallbackAgent.obj \ + +C_OBJS = \ + $O\Sort.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(FAR_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(UI_COMMON_OBJS) \ + $(AGENT_OBJS) \ + $(C_OBJS) \ + $O\CopyCoder.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(FAR_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(UI_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$(AGENT_OBJS): ../Agent/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) +$(C_OBJS): ../../../../C/$(*B).c + $(COMPL_O2) diff --git a/CPP/7zip/UI/Far/resource.rc b/CPP/7zip/UI/Far/resource.rc new file mode 100755 index 00000000..a5c2e2f3 --- /dev/null +++ b/CPP/7zip/UI/Far/resource.rc @@ -0,0 +1,3 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("7-Zip Plugin for FAR Manager", "7-ZipFar") diff --git a/CPP/7zip/UI/GUI/7zG.exe.manifest b/CPP/7zip/UI/GUI/7zG.exe.manifest new file mode 100755 index 00000000..c6ef90e8 --- /dev/null +++ b/CPP/7zip/UI/GUI/7zG.exe.manifest @@ -0,0 +1 @@ +7-Zip GUI. diff --git a/CPP/7zip/UI/GUI/CompressDialog.cpp b/CPP/7zip/UI/GUI/CompressDialog.cpp new file mode 100755 index 00000000..f49bb078 --- /dev/null +++ b/CPP/7zip/UI/GUI/CompressDialog.cpp @@ -0,0 +1,1373 @@ +// CompressDialog.cpp + +#include "StdAfx.h" + +#include "resource.h" +#include "Common/Defs.h" +#include "Common/StringConvert.h" +#include "Common/IntToString.h" +#include "Windows/CommonDialog.h" +#include "Windows/FileDir.h" +#include "Windows/FileName.h" +#include "Windows/ResourceString.h" +#include "Windows/System.h" + +#include "../../FileManager/HelpUtils.h" +#include "../../FileManager/SplitUtils.h" +#include "../../FileManager/FormatUtils.h" + +#include "../Explorer/MyMessages.h" + +#include "../Common/ZipRegistry.h" + +#include "CompressDialog.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +#ifdef LANG +#include "../../FileManager/LangUtils.h" +#endif + +#include "../Resource/CompressDialog/resource.h" + +#define MY_SIZE_OF_ARRAY(x) (sizeof(x) / sizeof(x[0])) + +#ifdef LANG +static CIDLangPair kIDLangPairs[] = +{ + { IDC_STATIC_COMPRESS_ARCHIVE, 0x02000D01 }, + { IDC_STATIC_COMPRESS_FORMAT, 0x02000D03 }, + { IDC_STATIC_COMPRESS_LEVEL, 0x02000D0B }, + { IDC_STATIC_COMPRESS_METHOD, 0x02000D04 }, + { IDC_STATIC_COMPRESS_DICTIONARY, 0x02000D0C }, + { IDC_STATIC_COMPRESS_ORDER, 0x02000D0D }, + { IDC_STATIC_COMPRESS_MEMORY, 0x02000D0E }, + { IDC_STATIC_COMPRESS_MEMORY_DE, 0x02000D0F }, + { IDC_COMPRESS_SOLID, 0x02000D05 }, + { IDC_COMPRESS_MULTI_THREAD, 0x02000D09 }, + { IDC_STATIC_COMPRESS_VOLUME, 0x02000D40 }, + { IDC_STATIC_COMPRESS_PARAMETERS, 0x02000D06 }, + + { IDC_STATIC_COMPRESS_UPDATE_MODE, 0x02000D02 }, + { IDC_STATIC_COMPRESS_OPTIONS, 0x02000D07 }, + { IDC_COMPRESS_SFX, 0x02000D08 }, + + { IDC_COMPRESS_ENCRYPTION, 0x02000D10 }, + { IDC_STATIC_COMPRESS_PASSWORD1, 0x02000B01 }, + { IDC_STATIC_COMPRESS_PASSWORD2, 0x02000B03 }, + { IDC_COMPRESS_CHECK_SHOW_PASSWORD, 0x02000B02 }, + { IDC_STATIC_COMPRESS_ENCRYPTION_METHOD, 0x02000D11 }, + { IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES, 0x02000D0A }, + + { IDOK, 0x02000702 }, + { IDCANCEL, 0x02000710 }, + { IDHELP, 0x02000720 } +}; +#endif + +using namespace NWindows; +using namespace NFile; +using namespace NName; +using namespace NDirectory; + +static const int kHistorySize = 8; + +static LPCWSTR kExeExt = L".exe"; +static LPCWSTR k7zFormat = L"7z"; + +struct CLevelInfo +{ + UInt32 ResourceID; + UInt32 LangID; +}; + +enum ELevel +{ + kStore = 0, + kFastest = 1, + kFast = 3, + kNormal = 5, + kMaximum = 7, + kUltra = 9 +}; + +static const CLevelInfo g_Levels[] = +{ + { IDS_METHOD_STORE, 0x02000D81 }, + { IDS_METHOD_FASTEST, 0x02000D85 }, + { 0, 0 }, + { IDS_METHOD_FAST, 0x02000D84 }, + { 0, 0 }, + { IDS_METHOD_NORMAL, 0x02000D82 }, + { 0, 0 }, + { IDS_METHOD_MAXIMUM, 0x02000D83 }, + { 0, 0 }, + { IDS_METHOD_ULTRA, 0x02000D86 } +}; + +enum EMethodID +{ + kCopy, + kLZMA, + kPPMd, + kBZip2, + kDeflate, + kDeflate64 +}; + +static const LPCWSTR kMethodsNames[] = +{ + L"Copy", + L"LZMA", + L"PPMd", + L"BZip2", + L"Deflate", + L"Deflate64" +}; + +static const EMethodID g_7zMethods[] = +{ + kLZMA, + kPPMd, + kBZip2 +}; + +static const EMethodID g_7zSfxMethods[] = +{ + kCopy, + kLZMA, + kPPMd +}; + +static EMethodID g_ZipMethods[] = +{ + kDeflate, + kDeflate64, + kBZip2 +}; + +static EMethodID g_GZipMethods[] = +{ + kDeflate +}; + +static EMethodID g_BZip2Methods[] = +{ + kBZip2 +}; + +struct CFormatInfo +{ + LPCWSTR Name; + UInt32 LevelsMask; + const EMethodID *MathodIDs; + int NumMethods; + bool Filter; + bool Solid; + bool MultiThread; + bool SFX; + bool Encrypt; + bool EncryptFileNames; +}; + +static const CFormatInfo g_Formats[] = +{ + { + L"", + (1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), + 0, 0, + false, false, false, false, false, false + }, + { + k7zFormat, + (1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), + g_7zMethods, MY_SIZE_OF_ARRAY(g_7zMethods), + true, true, true, true, true, true + }, + { + L"Zip", + (1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), + g_ZipMethods, MY_SIZE_OF_ARRAY(g_ZipMethods) , + false, false, true, false, true, false + }, + { + L"GZip", + (1 << 5) | (1 << 7) | (1 << 9), + g_GZipMethods, MY_SIZE_OF_ARRAY(g_GZipMethods), + false, false, false, false, false, false + }, + { + L"BZip2", + (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), + g_BZip2Methods, + MY_SIZE_OF_ARRAY(g_BZip2Methods), + false, false, true, false, false + }, + { + L"Tar", + (1 << 0), + 0, 0, + false, false, false, false, false, false + } +}; + +static bool IsMethodSupportedBySfx(int methodID) +{ + for (int i = 0; i < MY_SIZE_OF_ARRAY(g_7zSfxMethods); i++) + if (methodID == g_7zSfxMethods[i]) + return true; + return false; +}; + +#ifndef _WIN64 +typedef BOOL (WINAPI *GlobalMemoryStatusExP)(LPMEMORYSTATUSEX lpBuffer); +#endif + +static UInt64 GetPhysicalRamSize() +{ + MEMORYSTATUSEX stat; + stat.dwLength = sizeof(stat); + // return (128 << 20); + #ifdef _WIN64 + if (!::GlobalMemoryStatusEx(&stat)) + return 0; + return stat.ullTotalPhys; + #else + GlobalMemoryStatusExP globalMemoryStatusEx = (GlobalMemoryStatusExP) + ::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")), + "GlobalMemoryStatusEx"); + if (globalMemoryStatusEx != 0) + if (globalMemoryStatusEx(&stat)) + return stat.ullTotalPhys; + { + MEMORYSTATUS stat; + stat.dwLength = sizeof(stat); + GlobalMemoryStatus(&stat); + return stat.dwTotalPhys; + } + #endif +} + +static UInt64 GetMaxRamSizeForProgram() +{ + UInt64 physSize = GetPhysicalRamSize(); + const UInt64 kMinSysSize = (1 << 24); + if (physSize <= kMinSysSize) + physSize = 0; + else + physSize -= kMinSysSize; + const UInt64 kMinUseSize = (1 << 25); + if (physSize < kMinUseSize) + physSize = kMinUseSize; + return physSize; +} + +bool CCompressDialog::OnInit() +{ + #ifdef LANG + LangSetWindowText(HWND(*this), 0x02000D00); + LangSetDlgItemsText(HWND(*this), kIDLangPairs, MY_SIZE_OF_ARRAY(kIDLangPairs) ); + #endif + _password1Control.Attach(GetItem(IDC_COMPRESS_EDIT_PASSWORD1)); + _password2Control.Attach(GetItem(IDC_COMPRESS_EDIT_PASSWORD2)); + _password1Control.SetText(Info.Password); + _password2Control.SetText(Info.Password); + _encryptionMethod.Attach(GetItem(IDC_COMPRESS_COMBO_ENCRYPTION_METHOD)); + + m_ArchivePath.Attach(GetItem(IDC_COMPRESS_COMBO_ARCHIVE)); + m_Format.Attach(GetItem(IDC_COMPRESS_COMBO_FORMAT)); + m_Level.Attach(GetItem(IDC_COMPRESS_COMBO_LEVEL)); + m_Method.Attach(GetItem(IDC_COMPRESS_COMBO_METHOD)); + m_Dictionary.Attach(GetItem(IDC_COMPRESS_COMBO_DICTIONARY)); + m_Order.Attach(GetItem(IDC_COMPRESS_COMBO_ORDER)); + + m_UpdateMode.Attach(GetItem(IDC_COMPRESS_COMBO_UPDATE_MODE)); + m_Volume.Attach(GetItem(IDC_COMPRESS_COMBO_VOLUME)); + m_Params.Attach(GetItem(IDC_COMPRESS_EDIT_PARAMETERS)); + + AddVolumeItems(m_Volume); + + ReadCompressionInfo(m_RegistryInfo); + CheckButton(IDC_COMPRESS_CHECK_SHOW_PASSWORD, m_RegistryInfo.ShowPassword); + CheckButton(IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES, m_RegistryInfo.EncryptHeaders); + + UpdatePasswordControl(); + + Info.ArchiverInfoIndex = 0; + int i; + for(i = 0; i < m_ArchiverInfoList.Size(); i++) + { + const CArchiverInfo &ai = m_ArchiverInfoList[i]; + m_Format.AddString(ai.Name); + if (ai.Name.CompareNoCase(m_RegistryInfo.ArchiveType) == 0) + Info.ArchiverInfoIndex = i; + } + m_Format.SetCurSel(Info.ArchiverInfoIndex); + + SetArchiveName(Info.ArchiveName); + SetLevel(); + SetParams(); + + for(i = 0; i < m_RegistryInfo.HistoryArchives.Size() && i < kHistorySize; i++) + m_ArchivePath.AddString(m_RegistryInfo.HistoryArchives[i]); + + m_UpdateMode.AddString(LangString(IDS_COMPRESS_UPDATE_MODE_ADD, 0x02000DA1)); + m_UpdateMode.AddString(LangString(IDS_COMPRESS_UPDATE_MODE_UPDATE, 0x02000DA2)); + m_UpdateMode.AddString(LangString(IDS_COMPRESS_UPDATE_MODE_FRESH, 0x02000DA3)); + m_UpdateMode.AddString(LangString(IDS_COMPRESS_UPDATE_MODE_SYNCHRONIZE, 0x02000DA4)); + + m_UpdateMode.SetCurSel(0); + + Info.Solid = m_RegistryInfo.Solid; + Info.MultiThread = m_RegistryInfo.MultiThread; + + CheckButton(IDC_COMPRESS_SOLID, Info.Solid); + CheckButton(IDC_COMPRESS_MULTI_THREAD, Info.MultiThread); + CheckButton(IDC_COMPRESS_SFX, Info.SFXMode); + + CheckControlsEnable(); + + OnButtonSFX(); + + SetEncryptionMethod(); + return CModalDialog::OnInit(); +} + +namespace NCompressDialog +{ + bool CInfo::GetFullPathName(UString &result) const + { + NDirectory::MySetCurrentDirectory(CurrentDirPrefix); + return MyGetFullPathName(ArchiveName, result); + } +} + +void CCompressDialog::UpdatePasswordControl() +{ + bool showPassword = IsShowPasswordChecked(); + TCHAR c = showPassword ? 0: TEXT('*'); + _password1Control.SetPasswordChar(c); + _password2Control.SetPasswordChar(c); + UString password; + _password1Control.GetText(password); + _password1Control.SetText(password); + _password2Control.GetText(password); + _password2Control.SetText(password); + + int cmdShow = showPassword ? SW_HIDE : SW_SHOW; + ShowItem(IDC_STATIC_COMPRESS_PASSWORD2, cmdShow); + _password2Control.Show(cmdShow); +} + +bool CCompressDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) + { + case IDC_COMPRESS_BUTTON_SET_ARCHIVE: + { + OnButtonSetArchive(); + return true; + } + case IDC_COMPRESS_SFX: + { + OnButtonSFX(); + return true; + } + case IDC_COMPRESS_CHECK_SHOW_PASSWORD: + { + UpdatePasswordControl(); + return true; + } + case IDC_COMPRESS_MULTI_THREAD: + { + SetMemoryUsage(); + return true; + } + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} + +static bool IsMultiProcessor() +{ + return NSystem::GetNumberOfProcessors() > 1; +} + +void CCompressDialog::CheckSFXControlsEnable() +{ + const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; + bool enable = fi.SFX; + if (enable) + { + int methodID = GetMethodID(); + enable = (methodID == -1 || IsMethodSupportedBySfx(methodID)); + } + if (!enable) + CheckButton(IDC_COMPRESS_SFX, false); + EnableItem(IDC_COMPRESS_SFX, enable); +} + +void CCompressDialog::CheckVolumeEnable() +{ + bool isSFX = IsSFX(); + m_Volume.Enable(!isSFX); + if (isSFX) + m_Volume.SetText(TEXT("")); +} + +void CCompressDialog::CheckControlsEnable() +{ + const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; + Info.SolidIsAllowed = fi.Solid; + bool multiThreadEnable = fi.MultiThread & IsMultiProcessor(); + Info.MultiThreadIsAllowed = multiThreadEnable; + Info.EncryptHeadersIsAllowed = fi.EncryptFileNames; + + EnableItem(IDC_COMPRESS_SOLID, fi.Solid); + EnableItem(IDC_COMPRESS_MULTI_THREAD, multiThreadEnable); + CheckSFXControlsEnable(); + CheckVolumeEnable(); + + EnableItem(IDC_COMPRESS_ENCRYPTION, fi.Encrypt); + + EnableItem(IDC_STATIC_COMPRESS_PASSWORD1, fi.Encrypt); + EnableItem(IDC_STATIC_COMPRESS_PASSWORD2, fi.Encrypt); + EnableItem(IDC_COMPRESS_EDIT_PASSWORD1, fi.Encrypt); + EnableItem(IDC_COMPRESS_EDIT_PASSWORD2, fi.Encrypt); + EnableItem(IDC_COMPRESS_CHECK_SHOW_PASSWORD, fi.Encrypt); + + EnableItem(IDC_STATIC_COMPRESS_ENCRYPTION_METHOD, fi.Encrypt); + EnableItem(IDC_COMPRESS_COMBO_ENCRYPTION_METHOD, fi.Encrypt); + EnableItem(IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES, fi.EncryptFileNames); +} + +bool CCompressDialog::IsSFX() +{ + CWindow sfxButton = GetItem(IDC_COMPRESS_SFX); + return sfxButton.IsEnabled() && IsButtonCheckedBool(IDC_COMPRESS_SFX); +} + +void CCompressDialog::OnButtonSFX() +{ + SetMethod(); + + UString fileName; + m_ArchivePath.GetText(fileName); + int dotPos = fileName.ReverseFind(L'.'); + int slashPos = fileName.ReverseFind(L'\\'); + if (dotPos < 0 || dotPos <= slashPos) + dotPos = -1; + bool isSFX = IsSFX(); + if (isSFX) + { + if (dotPos >= 0) + fileName = fileName.Left(dotPos); + fileName += kExeExt; + m_ArchivePath.SetText(fileName); + } + else + { + if (dotPos >= 0) + { + UString ext = fileName.Mid(dotPos); + if (ext.CompareNoCase(kExeExt) == 0) + { + fileName = fileName.Left(dotPos); + m_ArchivePath.SetText(fileName); + } + } + SetArchiveName2(false); // it's for OnInit + } + + CheckVolumeEnable(); +} + +void CCompressDialog::OnButtonSetArchive() +{ + UString fileName; + m_ArchivePath.GetText(fileName); + fileName.Trim(); + Info.ArchiveName = fileName; + UString fullFileName; + if (!Info.GetFullPathName(fullFileName)) + { + fullFileName = Info.ArchiveName; + return; + } + UString title = LangString(IDS_COMPRESS_SET_ARCHIVE_DIALOG_TITLE, 0x02000D90); + UString s = LangString(IDS_OPEN_TYPE_ALL_FILES, 0x02000DB1); + s += L" (*.*)"; + UString resPath; + if (!MyGetOpenFileName(HWND(*this), title, fullFileName, s, resPath)) + return; + m_ArchivePath.SetText(resPath); +} + +// in ExtractDialog.cpp +extern void AddUniqueString(UStringVector &strings, const UString &srcString); + +static bool IsAsciiString(const UString &s) +{ + for (int i = 0; i < s.Length(); i++) + { + wchar_t c = s[i]; + if (c < 0x20 || c > 0x7F) + return false; + } + return true; +} + +void CCompressDialog::OnOK() +{ + _password1Control.GetText(Info.Password); + if (IsZipFormat()) + { + if (!IsAsciiString(Info.Password)) + { + MyMessageBoxResource(*this, IDS_PASSWORD_USE_ASCII, 0x02000B11); + return; + } + UString method = GetEncryptionMethodSpec(); + method.MakeUpper(); + if (method.Find(L"AES") == 0) + { + if (Info.Password.Length() > 99) + { + MyMessageBoxResource(*this, IDS_PASSWORD_IS_TOO_LONG, 0x02000B12); + return; + } + } + } + if (!IsShowPasswordChecked()) + { + UString password2; + _password2Control.GetText(password2); + if (password2 != Info.Password) + { + MyMessageBoxResource(*this, IDS_PASSWORD_PASSWORDS_DO_NOT_MATCH, 0x02000B10); + return; + } + } + + SaveOptionsInMem(); + UString s; + m_ArchivePath.GetText(s); + s.Trim(); + m_RegistryInfo.HistoryArchives.Clear(); + AddUniqueString(m_RegistryInfo.HistoryArchives, s); + Info.ArchiveName = s; + Info.UpdateMode = NCompressDialog::NUpdateMode::EEnum(m_UpdateMode.GetCurSel()); + + Info.Level = GetLevelSpec(); + Info.Dictionary = GetDictionarySpec(); + Info.Order = GetOrderSpec(); + Info.OrderMode = GetOrderMode(); + Info.Method = GetMethodSpec(); + Info.EncryptionMethod = GetEncryptionMethodSpec(); + + Info.ArchiverInfoIndex = m_Format.GetCurSel(); + + Info.SFXMode = IsSFX(); + m_RegistryInfo.Solid = Info.Solid = IsButtonCheckedBool(IDC_COMPRESS_SOLID); + m_RegistryInfo.MultiThread = Info.MultiThread = IsMultiThread(); + m_RegistryInfo.EncryptHeaders = Info.EncryptHeaders = IsButtonCheckedBool(IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES); + + m_Params.GetText(Info.Options); + UString volumeString; + m_Volume.GetText(volumeString); + volumeString.Trim(); + Info.VolumeSizes.Clear(); + if (!volumeString.IsEmpty()) + { + if (!ParseVolumeSizes(volumeString, Info.VolumeSizes)) + { + MyMessageBoxResource(*this, IDS_COMPRESS_INCORRECT_VOLUME_SIZE, 0x02000D41); + return; + } + if (!Info.VolumeSizes.IsEmpty()) + { + const UInt64 volumeSize = Info.VolumeSizes.Back(); + if (volumeSize < (100 << 10)) + { + wchar_t s[32]; + ConvertUInt64ToString(volumeSize, s); + if (::MessageBoxW(*this, MyFormatNew(IDS_COMPRESS_SPLIT_CONFIRM_MESSAGE, 0x02000D42, s), + L"7-Zip", MB_YESNOCANCEL | MB_ICONQUESTION | MB_TASKMODAL) != IDYES) + return; + } + } + } + + for(int i = 0; i < m_ArchivePath.GetCount(); i++) + { + UString sTemp; + m_ArchivePath.GetLBText(i, sTemp); + sTemp.Trim(); + AddUniqueString(m_RegistryInfo.HistoryArchives, sTemp); + } + if (m_RegistryInfo.HistoryArchives.Size() > kHistorySize) + m_RegistryInfo.HistoryArchives.DeleteBack(); + + //////////////////// + // Method + + m_RegistryInfo.Level = Info.Level; + m_RegistryInfo.ArchiveType = m_ArchiverInfoList[Info.ArchiverInfoIndex].Name; + + m_RegistryInfo.ShowPassword = IsShowPasswordChecked(); + + SaveCompressionInfo(m_RegistryInfo); + + CModalDialog::OnOK(); +} + +static LPCWSTR kHelpTopic = L"fm/plugins/7-zip/add.htm"; + +void CCompressDialog::OnHelp() +{ + ShowHelpWindow(NULL, kHelpTopic); +} + +bool CCompressDialog::OnCommand(int code, int itemID, LPARAM lParam) +{ + if (code == CBN_SELCHANGE) + { + switch(itemID) + { + case IDC_COMPRESS_COMBO_FORMAT: + { + OnChangeFormat(); + return true; + } + case IDC_COMPRESS_COMBO_LEVEL: + { + const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()]; + int index = FindRegistryFormatAlways(ai.Name); + NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index]; + fo.ResetForLevelChange(); + SetMethod(); + CheckSFXNameChange(); + return true; + } + case IDC_COMPRESS_COMBO_METHOD: + { + SetDictionary(); + SetOrder(); + CheckSFXNameChange(); + return true; + } + case IDC_COMPRESS_COMBO_DICTIONARY: + case IDC_COMPRESS_COMBO_ORDER: + { + SetMemoryUsage(); + return true; + } + } + } + return CModalDialog::OnCommand(code, itemID, lParam); +} + +void CCompressDialog::CheckSFXNameChange() +{ + bool isSFX = IsSFX(); + CheckSFXControlsEnable(); + if (isSFX != IsSFX()) + SetArchiveName2(isSFX); +} + +void CCompressDialog::SetArchiveName2(bool prevWasSFX) +{ + UString fileName; + m_ArchivePath.GetText(fileName); + const CArchiverInfo &prevArchiverInfo = m_ArchiverInfoList[m_PrevFormat]; + if (prevArchiverInfo.KeepName || Info.KeepName) + { + UString prevExtension = prevArchiverInfo.GetMainExtension(); + if (prevWasSFX) + prevExtension = kExeExt; + else + prevExtension = UString('.') + prevExtension; + const int prevExtensionLen = prevExtension.Length(); + if (fileName.Length() >= prevExtensionLen) + if (fileName.Right(prevExtensionLen).CompareNoCase(prevExtension) == 0) + fileName = fileName.Left(fileName.Length() - prevExtensionLen); + } + SetArchiveName(fileName); +} + +void CCompressDialog::OnChangeFormat() +{ + bool isSFX = IsSFX(); + SaveOptionsInMem(); + SetLevel(); + SetParams(); + CheckControlsEnable(); + SetArchiveName2(isSFX); + SetEncryptionMethod(); +} + +// if type.KeepName then use OriginalFileName +// else if !KeepName remove extension +// add new extension + +void CCompressDialog::SetArchiveName(const UString &name) +{ + UString fileName = name; + Info.ArchiverInfoIndex = m_Format.GetCurSel(); + const CArchiverInfo &ai = m_ArchiverInfoList[Info.ArchiverInfoIndex]; + m_PrevFormat = Info.ArchiverInfoIndex; + if (ai.KeepName) + { + fileName = OriginalFileName; + } + else + { + if (!Info.KeepName) + { + int dotPos = fileName.ReverseFind('.'); + int slashPos = MyMax(fileName.ReverseFind('\\'), fileName.ReverseFind('/')); + if (dotPos >= 0 && dotPos > slashPos + 1) + fileName = fileName.Left(dotPos); + } + } + + if (IsSFX()) + fileName += kExeExt; + else + { + fileName += L'.'; + fileName += ai.GetMainExtension(); + } + m_ArchivePath.SetText(fileName); +} + +int CCompressDialog::FindRegistryFormat(const UString &name) +{ + for (int i = 0; i < m_RegistryInfo.FormatOptionsVector.Size(); i++) + { + const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[i]; + if (GetUnicodeString(fo.FormatID) == name) + return i; + } + return -1; +} + +int CCompressDialog::FindRegistryFormatAlways(const UString &name) +{ + int index = FindRegistryFormat(name); + if (index < 0) + { + NCompression::CFormatOptions fo; + fo.FormatID = GetSystemString(name); + index = m_RegistryInfo.FormatOptionsVector.Add(fo); + } + return index; +} + +int CCompressDialog::GetStaticFormatIndex() +{ + int formatIndex = m_Format.GetCurSel(); + const CArchiverInfo &ai = m_ArchiverInfoList[formatIndex]; + for (int i = 0; i < MY_SIZE_OF_ARRAY(g_Formats); i++) + if (ai.Name.CompareNoCase(g_Formats[i].Name) == 0) + return i; + return 0; // -1; +} + +void CCompressDialog::SetNearestSelectComboBox( + NControl::CComboBox &comboBox, UInt32 value) +{ + for (int i = comboBox.GetCount() - 1; i >= 0; i--) + if ((UInt32)comboBox.GetItemData(i) <= value) + { + comboBox.SetCurSel(i); + return; + } + if (comboBox.GetCount() > 0) + comboBox.SetCurSel(0); +} + +void CCompressDialog::SetLevel() +{ + m_Level.ResetContent(); + const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; + const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()]; + int index = FindRegistryFormat(ai.Name); + UInt32 level = kNormal; + if (index >= 0) + { + const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index]; + if (fo.Level <= kUltra) + level = fo.Level; + else + level = kUltra; + } + int i; + for (i = 0; i <= kUltra; i++) + { + if ((fi.LevelsMask & (1 << i)) != 0) + { + const CLevelInfo &levelInfo = g_Levels[i]; + int index = (int)m_Level.AddString(LangString(levelInfo.ResourceID, levelInfo.LangID)); + m_Level.SetItemData(index, i); + } + } + SetNearestSelectComboBox(m_Level, level); + SetMethod(); +} + +int CCompressDialog::GetLevel() +{ + if (m_Level.GetCount() <= 0) + return -1; + return (int)m_Level.GetItemData(m_Level.GetCurSel()); +} + +int CCompressDialog::GetLevelSpec() +{ + if (m_Level.GetCount() <= 1) + return -1; + return GetLevel(); +} + +int CCompressDialog::GetLevel2() +{ + int level = GetLevel(); + if (level < 0) + level = 5; + return level; +} + +bool CCompressDialog::IsMultiThread() +{ + /* + const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; + bool multiThreadEnable = fi.MultiThread & IsMultiProcessor(); + if (!multiThreadEnable) + return false; + */ + return IsButtonCheckedBool(IDC_COMPRESS_MULTI_THREAD); +} + +void CCompressDialog::SetMethod() +{ + m_Method.ResetContent(); + if (GetLevel() <= 0) + { + SetDictionary(); + SetOrder(); + return; + } + const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; + const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()]; + int index = FindRegistryFormat(ai.Name); + UString defaultMethod; + if (index >= 0) + { + const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index]; + defaultMethod = fo.Method; + } + bool isSfx = IsSFX(); + for(int m = 0; m < fi.NumMethods; m++) + { + EMethodID methodID = fi.MathodIDs[m]; + if (isSfx) + if (!IsMethodSupportedBySfx(methodID)) + continue; + const LPCWSTR method = kMethodsNames[methodID]; + int itemIndex = (int)m_Method.AddString(GetSystemString(method)); + if (defaultMethod.CompareNoCase(method) == 0 || m == 0) + m_Method.SetCurSel(itemIndex); + } + SetDictionary(); + SetOrder(); +} + +bool CCompressDialog::IsZipFormat() +{ + const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()]; + return (ai.Name.CompareNoCase(L"zip") == 0); +} + +void CCompressDialog::SetEncryptionMethod() +{ + _encryptionMethod.ResetContent(); + const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()]; + if (ai.Name.CompareNoCase(L"7z") == 0) + { + _encryptionMethod.AddString(TEXT("AES-256")); + _encryptionMethod.SetCurSel(0); + } + else if (ai.Name.CompareNoCase(L"zip") == 0) + { + int index = FindRegistryFormat(ai.Name); + UString encryptionMethod; + if (index >= 0) + { + const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index]; + encryptionMethod = fo.EncryptionMethod; + } + _encryptionMethod.AddString(TEXT("ZipCrypto")); + _encryptionMethod.AddString(TEXT("AES-256")); + _encryptionMethod.SetCurSel(encryptionMethod.Find(L"AES") == 0 ? 1 : 0); + } +} + +int CCompressDialog::GetMethodID() +{ + UString methodName; + m_Method.GetText(methodName); + for (int i = 0; i < MY_SIZE_OF_ARRAY(kMethodsNames); i++) + if (methodName.CompareNoCase(kMethodsNames[i]) == 0) + return i; + return -1; +} + +UString CCompressDialog::GetMethodSpec() +{ + if (m_Method.GetCount() <= 1) + return UString(); + UString result; + m_Method.GetText(result); + return result; +} + +UString CCompressDialog::GetEncryptionMethodSpec() +{ + if (m_Method.GetCount() <= 1) + return UString(); + if (_encryptionMethod.GetCurSel() <= 0) + return UString(); + UString result; + _encryptionMethod.GetText(result); + result.Replace(L"-", L""); + return result; +} + +int CCompressDialog::AddDictionarySize(UInt32 size, bool kilo, bool maga) +{ + UInt32 sizePrint = size; + if (kilo) + sizePrint >>= 10; + else if (maga) + sizePrint >>= 20; + TCHAR s[40]; + ConvertUInt64ToString(sizePrint, s); + if (kilo) + lstrcat(s, TEXT(" K")); + else if (maga) + lstrcat(s, TEXT(" M")); + else + lstrcat(s, TEXT(" ")); + lstrcat(s, TEXT("B")); + int index = (int)m_Dictionary.AddString(s); + m_Dictionary.SetItemData(index, size); + return index; +} + +int CCompressDialog::AddDictionarySize(UInt32 size) +{ + if (size > 0) + { + if ((size & 0xFFFFF) == 0) + return AddDictionarySize(size, false, true); + if ((size & 0x3FF) == 0) + return AddDictionarySize(size, true, false); + } + return AddDictionarySize(size, false, false); +} + +void CCompressDialog::SetDictionary() +{ + m_Dictionary.ResetContent(); + const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()]; + int index = FindRegistryFormat(ai.Name); + UInt32 defaultDictionary = UInt32(-1); + if (index >= 0) + { + const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index]; + if (fo.Method.CompareNoCase(GetMethodSpec()) == 0) + defaultDictionary = fo.Dictionary; + } + int methodID = GetMethodID(); + int level = GetLevel2(); + if (methodID < 0) + { + SetMemoryUsage(); + return; + } + const UInt64 maxRamSize = GetMaxRamSizeForProgram(); + switch (methodID) + { + case kLZMA: + { + static const UInt32 kMinDicSize = (1 << 16); + if (defaultDictionary == UInt32(-1)) + { + if (level >= 9) + defaultDictionary = (1 << 26); + else if (level >= 7) + defaultDictionary = (1 << 24); + else if (level >= 5) + defaultDictionary = (1 << 22); + else if (level >= 3) + defaultDictionary = (1 << 20); + else + defaultDictionary = (kMinDicSize); + } + int i; + AddDictionarySize(kMinDicSize); + m_Dictionary.SetCurSel(0); + for (i = 20; i <= 30; i++) + for (int j = 0; j < 2; j++) + { + if (i == 20 && j > 0) + continue; + UInt32 dictionary = (1 << i) + (j << (i - 1)); + if (dictionary > + #ifdef _WIN64 + (1 << 30) + #else + (1 << 27) + #endif + ) + continue; + AddDictionarySize(dictionary); + UInt64 decomprSize; + UInt64 requiredComprSize = GetMemoryUsage(dictionary, false, decomprSize); + if (dictionary <= defaultDictionary && requiredComprSize <= maxRamSize) + m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1); + } + + // SetNearestSelectComboBox(m_Dictionary, defaultDictionary); + break; + } + case kPPMd: + { + if (defaultDictionary == UInt32(-1)) + { + if (level >= 9) + defaultDictionary = (192 << 20); + else if (level >= 7) + defaultDictionary = (64 << 20); + else if (level >= 5) + defaultDictionary = (16 << 20); + else + defaultDictionary = (4 << 20); + } + int i; + for (i = 20; i < 31; i++) + for (int j = 0; j < 2; j++) + { + if (i == 20 && j > 0) + continue; + UInt32 dictionary = (1 << i) + (j << (i - 1)); + if (dictionary >= (1 << 31)) + continue; + AddDictionarySize(dictionary); + UInt64 decomprSize; + UInt64 requiredComprSize = GetMemoryUsage(dictionary, false, decomprSize); + if (dictionary <= defaultDictionary && requiredComprSize <= maxRamSize || m_Dictionary.GetCount() == 0) + m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1); + } + SetNearestSelectComboBox(m_Dictionary, defaultDictionary); + break; + } + case kDeflate: + { + AddDictionarySize(32 << 10); + m_Dictionary.SetCurSel(0); + break; + } + case kDeflate64: + { + AddDictionarySize(64 << 10); + m_Dictionary.SetCurSel(0); + break; + } + case kBZip2: + { + UInt32 defaultDictionary; + if (level >= 5) + defaultDictionary = (900 << 10); + else if (level >= 3) + defaultDictionary = (500 << 10); + else + defaultDictionary = (100 << 10); + for (int i = 1; i <= 9; i++) + { + UInt32 dictionary = (i * 100) << 10; + AddDictionarySize(dictionary); + if (dictionary <= defaultDictionary || m_Dictionary.GetCount() == 0) + m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1); + } + break; + } + } + SetMemoryUsage(); +} + +UInt32 CCompressDialog::GetDictionary() +{ + if (m_Dictionary.GetCount() <= 0) + return (UInt32)-1; + return (UInt32)m_Dictionary.GetItemData(m_Dictionary.GetCurSel()); +} + +UInt32 CCompressDialog::GetDictionarySpec() +{ + if (m_Dictionary.GetCount() <= 1) + return (UInt32)-1; + return GetDictionary(); +} + +int CCompressDialog::AddOrder(UInt32 size) +{ + TCHAR s[40]; + ConvertUInt64ToString(size, s); + int index = (int)m_Order.AddString(s); + m_Order.SetItemData(index, size); + return index; +} + +void CCompressDialog::SetOrder() +{ + m_Order.ResetContent(); + const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()]; + int index = FindRegistryFormat(ai.Name); + UInt32 defaultOrder = UInt32(-1); + if (index >= 0) + { + const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index]; + if (fo.Method.CompareNoCase(GetMethodSpec()) == 0) + defaultOrder = fo.Order; + } + int methodID = GetMethodID(); + int level = GetLevel2(); + if (methodID < 0) + { + SetMemoryUsage(); + return; + } + switch (methodID) + { + case kLZMA: + { + if (defaultOrder == UInt32(-1)) + defaultOrder = (level >= 7) ? 64 : 32; + for (int i = 3; i <= 8; i++) + for (int j = 0; j < 2; j++) + { + UInt32 order = (1 << i) + (j << (i - 1)); + if (order <= 256) + AddOrder(order); + } + AddOrder(273); + SetNearestSelectComboBox(m_Order, defaultOrder); + break; + } + case kPPMd: + { + if (defaultOrder == UInt32(-1)) + { + if (level >= 9) + defaultOrder = 32; + else if (level >= 7) + defaultOrder = 16; + else if (level >= 5) + defaultOrder = 6; + else + defaultOrder = 4; + } + int i; + AddOrder(2); + AddOrder(3); + for (i = 2; i < 8; i++) + for (int j = 0; j < 4; j++) + { + UInt32 order = (1 << i) + (j << (i - 2)); + if (order < 32) + AddOrder(order); + } + AddOrder(32); + SetNearestSelectComboBox(m_Order, defaultOrder); + break; + } + case kDeflate: + case kDeflate64: + { + if (defaultOrder == UInt32(-1)) + { + if (level >= 9) + defaultOrder = 128; + else if (level >= 7) + defaultOrder = 64; + else + defaultOrder = 32; + } + int i; + for (i = 3; i <= 8; i++) + for (int j = 0; j < 2; j++) + { + UInt32 order = (1 << i) + (j << (i - 1)); + if (order <= 256) + AddOrder(order); + } + AddOrder(methodID == kDeflate64 ? 257 : 258); + SetNearestSelectComboBox(m_Order, defaultOrder); + break; + } + case kBZip2: + { + break; + } + } + SetMemoryUsage(); +} + +bool CCompressDialog::GetOrderMode() +{ + switch (GetMethodID()) + { + case kPPMd: + return true; + } + return false; +} + +UInt32 CCompressDialog::GetOrder() +{ + if (m_Order.GetCount() <= 0) + return (UInt32)-1; + return (UInt32)m_Order.GetItemData(m_Order.GetCurSel()); +} + +UInt32 CCompressDialog::GetOrderSpec() +{ + if (m_Order.GetCount() <= 1) + return (UInt32)-1; + return GetOrder(); +} + +UInt64 CCompressDialog::GetMemoryUsage(UInt32 dictionary, bool isMultiThread, UInt64 &decompressMemory) +{ + decompressMemory = UInt64(Int64(-1)); + int level = GetLevel2(); + if (level == 0) + { + decompressMemory = (1 << 20); + return decompressMemory; + } + UInt64 size = 0; + + const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; + if (fi.Filter && level >= 9) + size += (12 << 20) * 2 + (5 << 20); + switch (GetMethodID()) + { + case kLZMA: + { + UInt32 hs = dictionary - 1; + hs |= (hs >> 1); + hs |= (hs >> 2); + hs |= (hs >> 4); + hs |= (hs >> 8); + hs >>= 1; + hs |= 0xFFFF; + if (hs > (1 << 24)) + hs >>= 1; + hs++; + size += hs * 4; + size += (UInt64)dictionary * 11 / 2; + if (level >= 5) + size += dictionary * 4; + size += (2 << 20); + if (isMultiThread && level >= 5) + size += (2 << 20) + (4 << 20); + + decompressMemory = dictionary + (2 << 20); + return size; + } + case kPPMd: + { + decompressMemory = dictionary + (2 << 20); + return size + decompressMemory; + } + case kDeflate: + case kDeflate64: + { + UInt32 order = GetOrder(); + if (order == UInt32(-1)) + order = 32; + if (level >= 7) + size += (1 << 20); + size += 3 << 20; + decompressMemory = (2 << 20); + return size; + } + case kBZip2: + { + decompressMemory = (7 << 20); + UInt64 memForOneThread = (10 << 20); + if (isMultiThread) + memForOneThread *= NSystem::GetNumberOfProcessors(); + return size + (10 << 20); + } + } + return UInt64(Int64(-1)); +} + +UInt64 CCompressDialog::GetMemoryUsage(UInt64 &decompressMemory) +{ + return GetMemoryUsage(GetDictionary(), IsMultiThread(), decompressMemory); +} + +void CCompressDialog::PrintMemUsage(UINT res, UInt64 value) +{ + if (value == (UInt64)Int64(-1)) + { + SetItemText(res, TEXT("?")); + return; + } + value = (value + (1 << 20) - 1) >> 20; + TCHAR s[40]; + ConvertUInt64ToString(value, s); + lstrcat(s, TEXT(" MB")); + SetItemText(res, s); +} + +void CCompressDialog::SetMemoryUsage() +{ + UInt64 decompressMem; + UInt64 memUsage = GetMemoryUsage(decompressMem); + PrintMemUsage(IDC_STATIC_COMPRESS_MEMORY_VALUE, memUsage); + PrintMemUsage(IDC_STATIC_COMPRESS_MEMORY_DE_VALUE, decompressMem); +} + +void CCompressDialog::SetParams() +{ + const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()]; + m_Params.SetText(TEXT("")); + int index = FindRegistryFormat(ai.Name); + if (index >= 0) + { + const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index]; + m_Params.SetText(fo.Options); + } +} + +void CCompressDialog::SaveOptionsInMem() +{ + const CArchiverInfo &ai = m_ArchiverInfoList[Info.ArchiverInfoIndex]; + int index = FindRegistryFormatAlways(ai.Name); + m_Params.GetText(Info.Options); + Info.Options.Trim(); + NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index]; + fo.Options = Info.Options; + fo.Level = GetLevelSpec(); + fo.Dictionary = GetDictionarySpec(); + fo.Order = GetOrderSpec(); + fo.Method = GetMethodSpec(); + fo.EncryptionMethod = GetEncryptionMethodSpec(); +} diff --git a/CPP/7zip/UI/GUI/CompressDialog.h b/CPP/7zip/UI/GUI/CompressDialog.h new file mode 100755 index 00000000..87cf5d79 --- /dev/null +++ b/CPP/7zip/UI/GUI/CompressDialog.h @@ -0,0 +1,171 @@ +// CompressDialog.h + +#ifndef __COMPRESSDIALOG_H +#define __COMPRESSDIALOG_H + +#include "../Common/ZipRegistry.h" +#include "../Common/ArchiverInfo.h" +#include "../Resource/CompressDialog/resource.h" + +#include "Windows/Control/Dialog.h" +#include "Windows/Control/Edit.h" +#include "Windows/Control/ComboBox.h" + +namespace NCompressDialog +{ + namespace NUpdateMode + { + enum EEnum + { + kAdd, + kUpdate, + kFresh, + kSynchronize, + }; + } + struct CInfo + { + NUpdateMode::EEnum UpdateMode; + bool SolidIsAllowed; + bool Solid; + + bool MultiThreadIsAllowed; + bool MultiThread; + + CRecordVector VolumeSizes; + + UInt32 Level; + UString Method; + UInt32 Dictionary; + bool OrderMode; + UInt32 Order; + UString Options; + + UString EncryptionMethod; + + bool SFXMode; + + UString ArchiveName; // in: Relative for ; out: abs + UString CurrentDirPrefix; + bool KeepName; + + bool GetFullPathName(UString &result) const; + + int ArchiverInfoIndex; + + UString Password; + bool EncryptHeadersIsAllowed; + bool EncryptHeaders; + + void Init() + { + Level = Dictionary = Order = UInt32(-1); + OrderMode = false; + Method.Empty(); + Options.Empty(); + EncryptionMethod.Empty(); + } + CInfo() + { + Init(); + } + }; +} + +class CCompressDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CComboBox m_ArchivePath; + NWindows::NControl::CComboBox m_Format; + NWindows::NControl::CComboBox m_Level; + NWindows::NControl::CComboBox m_Method; + NWindows::NControl::CComboBox m_Dictionary; + NWindows::NControl::CComboBox m_Order; + NWindows::NControl::CComboBox m_UpdateMode; + NWindows::NControl::CComboBox m_Volume; + NWindows::NControl::CDialogChildControl m_Params; + + NWindows::NControl::CEdit _password1Control; + NWindows::NControl::CEdit _password2Control; + NWindows::NControl::CComboBox _encryptionMethod; + + NCompression::CInfo m_RegistryInfo; + + int m_PrevFormat; + void SetArchiveName(const UString &name); + int FindRegistryFormat(const UString &name); + int FindRegistryFormatAlways(const UString &name); + + void OnChangeFormat(); + void CheckSFXNameChange(); + void SetArchiveName2(bool prevWasSFX); + + int GetStaticFormatIndex(); + + void SetNearestSelectComboBox(NWindows::NControl::CComboBox &comboBox, UInt32 value); + + void SetLevel(); + int GetLevel(); + int GetLevelSpec(); + int GetLevel2(); + bool IsMultiThread(); + + void SetMethod(); + int GetMethodID(); + UString GetMethodSpec(); + UString GetEncryptionMethodSpec(); + + bool IsZipFormat(); + + void SetEncryptionMethod(); + + int AddDictionarySize(UInt32 size, bool kilo, bool maga); + int AddDictionarySize(UInt32 size); + + void SetDictionary(); + UInt32 GetDictionary(); + UInt32 GetDictionarySpec(); + + int AddOrder(UInt32 size); + void SetOrder(); + bool GetOrderMode(); + UInt32 GetOrder(); + UInt32 GetOrderSpec(); + + UInt64 GetMemoryUsage(UInt32 dictionary, bool isMultiThread, UInt64 &decompressMemory); + UInt64 GetMemoryUsage(UInt64 &decompressMemory); + void PrintMemUsage(UINT res, UInt64 value); + void SetMemoryUsage(); + void SetParams(); + void SaveOptionsInMem(); + + void UpdatePasswordControl(); + bool IsShowPasswordChecked() const + { return IsButtonChecked(IDC_COMPRESS_CHECK_SHOW_PASSWORD) == BST_CHECKED; } +public: + CObjectVector m_ArchiverInfoList; + + NCompressDialog::CInfo Info; + UString OriginalFileName; // for bzip2, gzip2 + + INT_PTR Create(HWND wndParent = 0) + { return CModalDialog::Create(IDD_DIALOG_COMPRESS, wndParent); } + +protected: + + void CheckSFXControlsEnable(); + void CheckVolumeEnable(); + void CheckControlsEnable(); + + void OnButtonSetArchive(); + bool IsSFX(); + void OnButtonSFX(); + + virtual bool OnInit(); + virtual bool OnCommand(int code, int itemID, LPARAM lParam); + virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); + virtual void OnOK(); + virtual void OnHelp(); + +}; + +#endif diff --git a/CPP/7zip/UI/GUI/ExtractDialog.cpp b/CPP/7zip/UI/GUI/ExtractDialog.cpp new file mode 100755 index 00000000..55c871ad --- /dev/null +++ b/CPP/7zip/UI/GUI/ExtractDialog.cpp @@ -0,0 +1,371 @@ +// ExtractDialog.cpp + +#include "StdAfx.h" + +// #include + +#include "ExtractDialog.h" + +#include "Common/StringConvert.h" +#include "Windows/Shell.h" +#include "Windows/FileName.h" +#include "Windows/FileDir.h" +#include "Windows/ResourceString.h" + +#ifndef NO_REGISTRY +#include "../../FileManager/HelpUtils.h" +#endif + +#include "../Common/ZipRegistry.h" + +#include "../../FileManager/LangUtils.h" + +#include "../Resource/Extract/resource.h" +#include "../Resource/ExtractDialog/resource.h" + +// #include "Help/Context/Extract.h" + +using namespace NWindows; +using namespace NFile; +using namespace NName; + +static const int kPathModeButtons[] = +{ + IDC_EXTRACT_RADIO_FULL_PATHNAMES, + IDC_EXTRACT_RADIO_CURRENT_PATHNAMES, + IDC_EXTRACT_RADIO_NO_PATHNAMES +}; + +static const NExtract::NPathMode::EEnum kPathModeButtonsVals[] = +{ + NExtract::NPathMode::kFullPathnames, + NExtract::NPathMode::kCurrentPathnames, + NExtract::NPathMode::kNoPathnames +}; + +static const int kNumPathnamesButtons = sizeof(kPathModeButtons) / sizeof(kPathModeButtons[0]); + +static const int kOverwriteButtons[] = +{ + IDC_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE, + IDC_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT, + IDC_EXTRACT_RADIO_SKIP_EXISTING_FILES, + IDC_EXTRACT_RADIO_AUTO_RENAME, + IDC_EXTRACT_RADIO_AUTO_RENAME_EXISTING, +}; + +static const NExtract::NOverwriteMode::EEnum kOverwriteButtonsVals[] = +{ + NExtract::NOverwriteMode::kAskBefore, + NExtract::NOverwriteMode::kWithoutPrompt, + NExtract::NOverwriteMode::kSkipExisting, + NExtract::NOverwriteMode::kAutoRename, + NExtract::NOverwriteMode::kAutoRenameExisting +}; + +static const int kNumOverwriteButtons = sizeof(kOverwriteButtons) / sizeof(kOverwriteButtons[0]); + +/* +static const int kFilesButtons[] = +{ + IDC_EXTRACT_RADIO_SELECTED_FILES, + IDC_EXTRACT_RADIO_ALL_FILES +}; +static const int kNumFilesButtons = sizeof(kFilesButtons) / sizeof(kFilesButtons[0]); +*/ + +#ifndef _SFX +void CExtractDialog::GetPathMode() +{ + for (int i = 0; i < kNumPathnamesButtons; i++) + if(IsButtonCheckedBool(kPathModeButtons[i])) + { + PathMode = kPathModeButtonsVals[i]; + return; + } + throw 1; +} + +void CExtractDialog::SetPathMode() +{ + for (int j = 0; j < 2; j++) + { + for (int i = 0; i < kNumPathnamesButtons; i++) + if(PathMode == kPathModeButtonsVals[i]) + { + CheckRadioButton(kPathModeButtons[0], kPathModeButtons[kNumPathnamesButtons - 1], + kPathModeButtons[i]); + return; + } + PathMode = kPathModeButtonsVals[0]; + } + throw 1; +} + +void CExtractDialog::GetOverwriteMode() +{ + for (int i = 0; i < kNumOverwriteButtons; i++) + if(IsButtonCheckedBool(kOverwriteButtons[i])) + { + OverwriteMode = kOverwriteButtonsVals[i]; + return; + } + throw 0; +} + +void CExtractDialog::SetOverwriteMode() +{ + for (int j = 0; j < 2; j++) + { + for (int i = 0; i < kNumOverwriteButtons; i++) + if(OverwriteMode == kOverwriteButtonsVals[i]) + { + CheckRadioButton(kOverwriteButtons[0], kOverwriteButtons[kNumOverwriteButtons - 1], + kOverwriteButtons[i]); + return; + } + OverwriteMode = kOverwriteButtonsVals[0]; + } + throw 1; +} + +/* +int CExtractDialog::GetFilesMode() const +{ + for (int i = 0; i < kNumFilesButtons; i++) + if(IsButtonCheckedBool(kFilesButtons[i])) + return i; + throw 0; +} +*/ + +#endif + +#ifdef LANG +static CIDLangPair kIDLangPairs[] = +{ + { IDC_STATIC_EXTRACT_EXTRACT_TO, 0x02000801 }, + { IDC_EXTRACT_PATH_MODE, 0x02000810 }, + { IDC_EXTRACT_RADIO_FULL_PATHNAMES, 0x02000811 }, + { IDC_EXTRACT_RADIO_CURRENT_PATHNAMES, 0x02000812 }, + { IDC_EXTRACT_RADIO_NO_PATHNAMES, 0x02000813 }, + { IDC_EXTRACT_OVERWRITE_MODE, 0x02000820 }, + { IDC_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE, 0x02000821 }, + { IDC_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT, 0x02000822 }, + { IDC_EXTRACT_RADIO_SKIP_EXISTING_FILES, 0x02000823 }, + { IDC_EXTRACT_RADIO_AUTO_RENAME, 0x02000824 }, + { IDC_EXTRACT_RADIO_AUTO_RENAME_EXISTING, 0x02000825 }, + { IDC_EXTRACT_FILES, 0x02000830 }, + { IDC_EXTRACT_RADIO_SELECTED_FILES, 0x02000831 }, + { IDC_EXTRACT_RADIO_ALL_FILES, 0x02000832 }, + { IDC_EXTRACT_PASSWORD, 0x02000802 }, + { IDC_EXTRACT_CHECK_SHOW_PASSWORD, 0x02000B02 }, + { IDOK, 0x02000702 }, + { IDCANCEL, 0x02000710 }, + { IDHELP, 0x02000720 } + +}; +#endif + +// static const int kWildcardsButtonIndex = 2; + +static const int kHistorySize = 8; + +bool CExtractDialog::OnInit() +{ + #ifdef LANG + LangSetWindowText(HWND(*this), 0x02000800); + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + #endif + #ifndef _SFX + _passwordControl.Attach(GetItem(IDC_EXTRACT_EDIT_PASSWORD)); + _passwordControl.SetText(Password); + _passwordControl.SetPasswordChar(TEXT('*')); + #endif + + NExtract::CInfo extractionInfo; + + #ifdef NO_REGISTRY + PathMode = NExtract::NPathMode::kFullPathnames; + OverwriteMode = NExtract::NOverwriteMode::kAskBefore; + // extractionInfo.Paths = NExtract::NPathMode::kFullPathnames; + #else + ReadExtractionInfo(extractionInfo); + CheckButton(IDC_EXTRACT_CHECK_SHOW_PASSWORD, extractionInfo.ShowPassword); + UpdatePasswordControl(); + PathMode = extractionInfo.PathMode; + OverwriteMode = extractionInfo.OverwriteMode; + #endif + + _path.Attach(GetItem(IDC_EXTRACT_COMBO_PATH)); + + _path.SetText(DirectoryPath); + + #ifndef NO_REGISTRY + for(int i = 0; i < extractionInfo.Paths.Size() && i < kHistorySize; i++) + _path.AddString(extractionInfo.Paths[i]); + #endif + + /* + if(extractionInfo.Paths.Size() > 0) + _path.SetCurSel(0); + else + _path.SetCurSel(-1); + */ + + + + #ifndef _SFX + SetPathMode(); + SetOverwriteMode(); + + /* + CheckRadioButton(kFilesButtons[0], kFilesButtons[kNumFilesButtons - 1], + kFilesButtons[_filesMode]); + */ + + // CWindow selectedFilesWindow = GetItem(IDC_EXTRACT_RADIO_SELECTED_FILES); + // selectedFilesWindow.Enable(_enableSelectedFilesButton); + + + #endif + + + // CWindow filesWindow = GetItem(IDC_EXTRACT_RADIO_FILES); + // filesWindow.Enable(_enableFilesButton); + + // UpdateWildCardState(); + return CModalDialog::OnInit(); +} + +#ifndef _SFX +void CExtractDialog::UpdatePasswordControl() +{ + _passwordControl.SetPasswordChar((IsButtonChecked( + IDC_EXTRACT_CHECK_SHOW_PASSWORD) == BST_CHECKED) ? 0: TEXT('*')); + UString password; + _passwordControl.GetText(password); + _passwordControl.SetText(password); +} +#endif + +bool CExtractDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + /* + for (int i = 0; i < kNumFilesButtons; i++) + if (buttonID == kFilesButtons[i]) + { + UpdateWildCardState(); + return true; + } + */ + switch(buttonID) + { + case IDC_EXTRACT_BUTTON_SET_PATH: + OnButtonSetPath(); + return true; + #ifndef _SFX + case IDC_EXTRACT_CHECK_SHOW_PASSWORD: + { + UpdatePasswordControl(); + return true; + } + #endif + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} + +void CExtractDialog::OnButtonSetPath() +{ + UString currentPath; + _path.GetText(currentPath); + UString title = LangStringSpec(IDS_EXTRACT_SET_FOLDER, 0x02000881); + UString resultPath; + if (!NShell::BrowseForFolder(HWND(*this), title, currentPath, resultPath)) + return; + #ifndef NO_REGISTRY + _path.SetCurSel(-1); + #endif + _path.SetText(resultPath); +} + +void AddUniqueString(UStringVector &list, const UString &s) +{ + for(int i = 0; i < list.Size(); i++) + if (s.CompareNoCase(list[i]) == 0) + return; + list.Add(s); +} + +void CExtractDialog::OnOK() +{ + #ifndef _SFX + GetPathMode(); + GetOverwriteMode(); + // _filesMode = (NExtractionDialog::NFilesMode::EEnum)GetFilesMode(); + + _passwordControl.GetText(Password); + #endif + + NExtract::CInfo extractionInfo; + extractionInfo.PathMode = PathMode; + extractionInfo.OverwriteMode = OverwriteMode; + extractionInfo.ShowPassword = (IsButtonChecked( + IDC_EXTRACT_CHECK_SHOW_PASSWORD) == BST_CHECKED); + + UString s; + + #ifdef NO_REGISTRY + + _path.GetText(s); + + #else + + int currentItem = _path.GetCurSel(); + if(currentItem == CB_ERR) + { + _path.GetText(s); + if(_path.GetCount() >= kHistorySize) + currentItem = _path.GetCount() - 1; + } + else + _path.GetLBText(currentItem, s); + + #endif + + s.Trim(); + #ifndef _SFX + AddUniqueString(extractionInfo.Paths, s); + #endif + DirectoryPath = s; + #ifndef NO_REGISTRY + for(int i = 0; i < _path.GetCount(); i++) + if(i != currentItem) + { + UString sTemp; + _path.GetLBText(i, sTemp); + sTemp.Trim(); + AddUniqueString(extractionInfo.Paths, sTemp); + } + SaveExtractionInfo(extractionInfo); + #endif + CModalDialog::OnOK(); +} + +/* +void CExtractDialog::UpdateWildCardState() +{ + // UpdateData(TRUE); + // m_Wildcards.EnableWindow(BoolToBOOL(m_Files == kWildcardsButtonIndex)); +} +*/ + +#ifndef NO_REGISTRY +static LPCWSTR kHelpTopic = L"fm/plugins/7-zip/extract.htm"; +void CExtractDialog::OnHelp() +{ + ShowHelpWindow(NULL, kHelpTopic); + CModalDialog::OnHelp(); +} +#endif + diff --git a/CPP/7zip/UI/GUI/ExtractDialog.h b/CPP/7zip/UI/GUI/ExtractDialog.h new file mode 100755 index 00000000..0020c693 --- /dev/null +++ b/CPP/7zip/UI/GUI/ExtractDialog.h @@ -0,0 +1,77 @@ +// ExtractDialog.h + +#ifndef __EXTRACTDIALOG_H +#define __EXTRACTDIALOG_H + +#include "resource.h" + +#include "Windows/Control/Dialog.h" +#include "Windows/Control/Edit.h" +#include "Windows/Control/ComboBox.h" + +#ifndef NO_REGISTRY +#include "../Common/ZipRegistry.h" +#endif +#include "../Common/ExtractMode.h" + +namespace NExtractionDialog +{ + /* + namespace NFilesMode + { + enum EEnum + { + kSelected, + kAll, + kSpecified + }; + } + */ +} + +class CExtractDialog: public NWindows::NControl::CModalDialog +{ + #ifdef NO_REGISTRY + NWindows::NControl::CDialogChildControl _path; + #else + NWindows::NControl::CComboBox _path; + #endif + + #ifndef _SFX + NWindows::NControl::CEdit _passwordControl; + #endif + + #ifndef _SFX + void GetPathMode(); + void SetPathMode(); + void GetOverwriteMode(); + void SetOverwriteMode(); + // int GetFilesMode() const; + void UpdatePasswordControl(); + #endif + + void OnButtonSetPath(); + + virtual bool OnInit(); + virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); + virtual void OnOK(); + #ifndef NO_REGISTRY + virtual void OnHelp(); + #endif +public: + // bool _enableSelectedFilesButton; + // bool _enableFilesButton; + // NExtractionDialog::NFilesMode::EEnum FilesMode; + + UString DirectoryPath; + #ifndef _SFX + UString Password; + #endif + NExtract::NPathMode::EEnum PathMode; + NExtract::NOverwriteMode::EEnum OverwriteMode; + + INT_PTR Create(HWND aWndParent = 0) + { return CModalDialog::Create(IDD_DIALOG_EXTRACT, aWndParent); } +}; + +#endif diff --git a/CPP/7zip/UI/GUI/ExtractGUI.cpp b/CPP/7zip/UI/GUI/ExtractGUI.cpp new file mode 100755 index 00000000..395df5a9 --- /dev/null +++ b/CPP/7zip/UI/GUI/ExtractGUI.cpp @@ -0,0 +1,172 @@ +// ExtractGUI.cpp + +#include "StdAfx.h" + +#include "ExtractGUI.h" + +#include "Common/StringConvert.h" + +#include "Windows/FileDir.h" +#include "Windows/Error.h" +#include "Windows/FileFind.h" +#include "Windows/Thread.h" + +#include "../../FileManager/FormatUtils.h" +#include "../../FileManager/ExtractCallback.h" +#include "../../FileManager/LangUtils.h" + +#include "../Common/ArchiveExtractCallback.h" +#include "../Explorer/MyMessages.h" +#include "../Resource/Extract/resource.h" + +#include "OpenCallbackGUI.h" +#include "ExtractDialog.h" + +using namespace NWindows; + +static const wchar_t *kIncorrectOutDir = L"Incorrect output directory path"; + +struct CThreadExtracting +{ + CExtractCallbackImp *ExtractCallbackSpec; + + UStringVector *ArchivePaths; + UStringVector *ArchivePathsFull; + const NWildcard::CCensorNode *WildcardCensor; + const CExtractOptions *Options; + COpenCallbackGUI *OpenCallback; + CMyComPtr ExtractCallback; + + UString ErrorMessage; + HRESULT Result; + + DWORD Process() + { + ExtractCallbackSpec->ProgressDialog.WaitCreating(); + try + { + Result = DecompressArchives(*ArchivePaths, *ArchivePathsFull, + *WildcardCensor, *Options, OpenCallback, ExtractCallback, ErrorMessage); + } + catch(const UString &s) + { + ErrorMessage = s; + Result = E_FAIL; + } + catch(const wchar_t *s) + { + ErrorMessage = s; + Result = E_FAIL; + } + catch(const char *s) + { + ErrorMessage = GetUnicodeString(s); + Result = E_FAIL; + } + catch(...) + { + Result = E_FAIL; + } + ExtractCallbackSpec->ProgressDialog.MyClose(); + return 0; + } + static DWORD WINAPI MyThreadFunction(void *param) + { + return ((CThreadExtracting *)param)->Process(); + } +}; + +HRESULT ExtractGUI( + UStringVector &archivePaths, + UStringVector &archivePathsFull, + const NWildcard::CCensorNode &wildcardCensor, + CExtractOptions &options, + bool showDialog, + COpenCallbackGUI *openCallback, + CExtractCallbackImp *extractCallback) +{ + CThreadExtracting extracter; + + if (!options.TestMode) + { + UString outputDir = options.OutputDir; + if (outputDir.IsEmpty()) + NFile::NDirectory::MyGetCurrentDirectory(outputDir); + if (showDialog) + { + CExtractDialog dialog; + if (!NFile::NDirectory::MyGetFullPathName(outputDir, dialog.DirectoryPath)) + { + MyMessageBox(kIncorrectOutDir); + return E_FAIL; + } + NFile::NName::NormalizeDirPathPrefix(dialog.DirectoryPath); + + // dialog.OverwriteMode = options.OverwriteMode; + // dialog.PathMode = options.PathMode; + + if(dialog.Create(0) != IDOK) + return E_ABORT; + outputDir = dialog.DirectoryPath; + options.OverwriteMode = dialog.OverwriteMode; + options.PathMode = dialog.PathMode; + #ifndef _SFX + openCallback->Password = dialog.Password; + openCallback->PasswordIsDefined = !dialog.Password.IsEmpty(); + #endif + } + if (!NFile::NDirectory::MyGetFullPathName(outputDir, options.OutputDir)) + { + MyMessageBox(kIncorrectOutDir); + return E_FAIL; + } + NFile::NName::NormalizeDirPathPrefix(options.OutputDir); + + /* + if(!NFile::NDirectory::CreateComplexDirectory(options.OutputDir)) + { + UString s = GetUnicodeString(NError::MyFormatMessage(GetLastError())); + UString s2 = MyFormatNew(IDS_CANNOT_CREATE_FOLDER, + #ifdef LANG + 0x02000603, + #endif + options.OutputDir); + MyMessageBox(s2 + UString(L"\n") + s); + return E_FAIL; + } + */ + } + + UString title = LangStringSpec(options.TestMode ? IDS_PROGRESS_TESTING : IDS_PROGRESS_EXTRACTING, + options.TestMode ? 0x02000F90: 0x02000890); + + extracter.ExtractCallbackSpec = extractCallback; + extracter.ExtractCallback = extractCallback; + extracter.ExtractCallbackSpec->Init(); + + extracter.ArchivePaths = &archivePaths; + extracter.ArchivePathsFull = &archivePathsFull; + extracter.WildcardCensor = &wildcardCensor; + extracter.Options = &options; + extracter.OpenCallback = openCallback; + + CThread thread; + if (!thread.Create(CThreadExtracting::MyThreadFunction, &extracter)) + throw 271824; + extracter.ExtractCallbackSpec->StartProgressDialog(title); + if (extracter.Result == S_OK && options.TestMode && + extracter.ExtractCallbackSpec->Messages.IsEmpty() && + extracter.ExtractCallbackSpec->NumArchiveErrors == 0) + { + #ifndef _SFX + MessageBoxW(0, LangString(IDS_MESSAGE_NO_ERRORS, 0x02000608), + LangString(IDS_PROGRESS_TESTING, 0x02000F90), 0); + #endif + } + if (extracter.Result != S_OK) + if (!extracter.ErrorMessage.IsEmpty()) + throw extracter.ErrorMessage; + return extracter.Result; +} + + diff --git a/CPP/7zip/UI/GUI/ExtractGUI.h b/CPP/7zip/UI/GUI/ExtractGUI.h new file mode 100755 index 00000000..5a0b157d --- /dev/null +++ b/CPP/7zip/UI/GUI/ExtractGUI.h @@ -0,0 +1,20 @@ +// GUI/ExtractGUI.h + +#ifndef __EXTRACT_GUI_H +#define __EXTRACT_GUI_H + +#include "../Common/Extract.h" +#include "OpenCallbackGUI.h" + +#include "../../FileManager/ExtractCallback.h" + +HRESULT ExtractGUI( + UStringVector &archivePaths, + UStringVector &archivePathsFull, + const NWildcard::CCensorNode &wildcardCensor, + CExtractOptions &options, + bool showDialog, + COpenCallbackGUI *openCallback, + CExtractCallbackImp *extractCallback); + +#endif diff --git a/CPP/7zip/UI/GUI/FM.ico b/CPP/7zip/UI/GUI/FM.ico new file mode 100755 index 00000000..3a0a34da Binary files /dev/null and b/CPP/7zip/UI/GUI/FM.ico differ diff --git a/CPP/7zip/UI/GUI/GUI.cpp b/CPP/7zip/UI/GUI/GUI.cpp new file mode 100755 index 00000000..fe956dbd --- /dev/null +++ b/CPP/7zip/UI/GUI/GUI.cpp @@ -0,0 +1,260 @@ +// GUI.cpp + +#include "StdAfx.h" + +#include + +#include "Common/NewHandler.h" +#include "Common/StringConvert.h" +#include "Common/CommandLineParser.h" +#include "Common/Exception.h" + +#include "Windows/COM.h" +#include "Windows/FileMapping.h" +#include "Windows/FileDir.h" +#include "Windows/Synchronization.h" +#include "Windows/Error.h" +#include "Windows/FileName.h" +#ifdef _WIN32 +#include "Windows/MemoryLock.h" +#include "Common/Alloc.h" +#endif + +#include "../../IStream.h" +#include "../../IPassword.h" + +#include "../../FileManager/StringUtils.h" + +#include "../Common/ExitCode.h" +#include "../Common/ArchiveCommandLine.h" + +#include "../Resource/Extract/resource.h" +#include "../Explorer/MyMessages.h" + +#include "ExtractGUI.h" +#include "UpdateGUI.h" + +using namespace NWindows; + +HINSTANCE g_hInstance; +#ifndef _UNICODE +bool g_IsNT = false; +#endif + +static const wchar_t *kExceptionErrorMessage = L"Error:"; +static const wchar_t *kUserBreak = L"Break signaled"; + +static const wchar_t *kMemoryExceptionMessage = L"ERROR: Can't allocate required memory!"; +static const wchar_t *kUnknownExceptionMessage = L"Unknown Error"; +static const wchar_t *kInternalExceptionMessage = L"Internal Error #"; + +static const wchar_t *kIncorrectCommandMessage = L"Incorrect command"; + +static void ErrorMessage(const wchar_t *message) +{ + MessageBoxW(0, message, L"7-Zip GUI", MB_ICONERROR); +} + +int Main2() +{ + /* + TCHAR t[512]; + GetCurrentDirectory(512, t); + ErrorMessage(t); + return 0; + */ + + UStringVector commandStrings; + NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); + if(commandStrings.Size() <= 1) + { + MessageBoxW(0, L"Specify command", L"7-Zip", 0); + return 0; + } + commandStrings.Delete(0); + + CArchiveCommandLineOptions options; + CArchiveCommandLineParser parser; + + parser.Parse1(commandStrings, options); + parser.Parse2(options); + + #ifdef _WIN32 + if (options.LargePages) + NSecurity::EnableLockMemoryPrivilege(); + #endif + + bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); + + if (isExtractGroupCommand) + { + CExtractCallbackImp *ecs = new CExtractCallbackImp; + CMyComPtr extractCallback = ecs; + ecs->PasswordIsDefined = options.PasswordEnabled; + ecs->Password = options.Password; + ecs->Init(); + + COpenCallbackGUI openCallback; + openCallback.PasswordIsDefined = options.PasswordEnabled; + openCallback.Password = options.Password; + + CExtractOptions eo; + eo.StdOutMode = options.StdOutMode; + eo.OutputDir = options.OutputDir; + eo.YesToAll = options.YesToAll; + eo.OverwriteMode = options.OverwriteMode; + eo.PathMode = options.Command.GetPathMode(); + eo.TestMode = options.Command.IsTestMode(); + #ifdef COMPRESS_MT + eo.Properties = options.ExtractProperties; + #endif + + HRESULT result = ExtractGUI( + options.ArchivePathsSorted, + options.ArchivePathsFullSorted, + options.WildcardCensor.Pairs.Front().Head, + eo, options.ShowDialog, &openCallback, ecs); + if (result != S_OK) + throw CSystemException(result); + if (ecs->Messages.Size() > 0 || ecs->NumArchiveErrors != 0) + return NExitCode::kFatalError; + } + else if (options.Command.IsFromUpdateGroup()) + { + bool passwordIsDefined = + options.PasswordEnabled && !options.Password.IsEmpty(); + + COpenCallbackGUI openCallback; + openCallback.PasswordIsDefined = passwordIsDefined; + openCallback.Password = options.Password; + + CUpdateCallbackGUI callback; + // callback.EnablePercents = options.EnablePercents; + callback.PasswordIsDefined = passwordIsDefined; + callback.AskPassword = options.PasswordEnabled && options.Password.IsEmpty(); + callback.Password = options.Password; + // callback.StdOutMode = options.UpdateOptions.StdOutMode; + callback.Init(); + + CUpdateErrorInfo errorInfo; + + HRESULT result = UpdateGUI( + options.WildcardCensor, options.UpdateOptions, + options.ShowDialog, + errorInfo, &openCallback, &callback); + + if (result != S_OK) + { + if (!errorInfo.Message.IsEmpty()) + ErrorMessage(errorInfo.Message); + throw CSystemException(result); + } + if (callback.FailedFiles.Size() > 0) + return NExitCode::kWarning; + } + else + { + ErrorMessage(L"Use correct command"); + return 0; + } + return 0; +} + +static bool inline IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); +} + +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, LPSTR /* lpCmdLine */, int /* nCmdShow */) +{ + g_hInstance = hInstance; + #ifdef _UNICODE + if (!IsItWindowsNT()) + { + MyMessageBox(L"This program requires Windows NT/2000/XP/2003"); + return NExitCode::kFatalError; + } + #else + g_IsNT = IsItWindowsNT(); + #endif + + #ifdef _WIN32 + SetLargePageSize(); + #endif + + InitCommonControls(); + + ReloadLang(); + + // setlocale(LC_COLLATE, ".ACP"); + try + { + return Main2(); + } + catch(const CNewException &) + { + MyMessageBox(kMemoryExceptionMessage); + return (NExitCode::kMemoryError); + } + catch(const CArchiveCommandLineException &e) + { + MyMessageBox(GetUnicodeString(e)); + return (NExitCode::kUserError); + } + catch(const CSystemException &systemError) + { + if (systemError.ErrorCode == E_OUTOFMEMORY) + { + MyMessageBox(kMemoryExceptionMessage); + return (NExitCode::kMemoryError); + } + if (systemError.ErrorCode == E_ABORT) + { + // MyMessageBox(kUserBreak); + return (NExitCode::kUserBreak); + } + UString message; + NError::MyFormatMessage(systemError.ErrorCode, message); + MyMessageBox(message); + return (NExitCode::kFatalError); + } + /* + catch(NExitCode::EEnum &exitCode) + { + g_StdErr << kInternalExceptionMessage << exitCode << endl; + return (exitCode); + } + */ + catch(const UString &s) + { + MyMessageBox(s); + return (NExitCode::kFatalError); + } + catch(const AString &s) + { + MyMessageBox(GetUnicodeString(s)); + return (NExitCode::kFatalError); + } + catch(const char *s) + { + MyMessageBox(GetUnicodeString(s)); + return (NExitCode::kFatalError); + } + /* + catch(int t) + { + g_StdErr << kInternalExceptionMessage << t << endl; + return (NExitCode::kFatalError); + } + */ + catch(...) + { + MyMessageBox(kUnknownExceptionMessage); + return (NExitCode::kFatalError); + } +} + diff --git a/CPP/7zip/UI/GUI/GUI.dsp b/CPP/7zip/UI/GUI/GUI.dsp new file mode 100755 index 00000000..dadb9648 --- /dev/null +++ b/CPP/7zip/UI/GUI/GUI.dsp @@ -0,0 +1,904 @@ +# Microsoft Developer Studio Project File - Name="GUI" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=GUI - Win32 DebugU +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "GUI.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "GUI.mak" CFG="GUI - Win32 DebugU" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "GUI - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "GUI - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "GUI - Win32 ReleaseU" (based on "Win32 (x86) Application") +!MESSAGE "GUI - Win32 DebugU" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "GUI - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "COMPRESS_MT" /D "WIN_LONG_PATH" /Yu"stdafx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Program Files\7-Zip\7zg.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "GUI - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "COMPRESS_MT" /D "WIN_LONG_PATH" /Yu"stdafx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Program Files\7-Zip\7zg.exe" /pdbtype:sept + +!ELSEIF "$(CFG)" == "GUI - Win32 ReleaseU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ReleaseU" +# PROP BASE Intermediate_Dir "ReleaseU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseU" +# PROP Intermediate_Dir "ReleaseU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "COMPRESS_MT" /D "WIN_LONG_PATH" /Yu"stdafx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\UTIL\7zg.exe" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Program Files\7-Zip\7zgn.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "GUI - Win32 DebugU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "DebugU" +# PROP BASE Intermediate_Dir "DebugU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugU" +# PROP Intermediate_Dir "DebugU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "COMPRESS_MT" /D "WIN_LONG_PATH" /Yu"stdafx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\UTIL\7zg.exe" /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Program Files\7-Zip\7zgn.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "GUI - Win32 Release" +# Name "GUI - Win32 Debug" +# Name "GUI - Win32 ReleaseU" +# Name "GUI - Win32 DebugU" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\7zG.exe.manifest +# End Source File +# Begin Source File + +SOURCE=.\FM.ico +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"stdafx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "SDK" + +# PROP Default_Filter "" +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Lang.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Lang.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\TextConfig.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\TextConfig.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Group "Control" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ComboBox.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ComboBox.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Edit.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ListView.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ListView.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ProgressBar.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\Windows\CommonDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\CommonDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Shell.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Shell.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.h +# End Source File +# End Group +# End Group +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\ArchiveCommandLine.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveCommandLine.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiverInfo.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiverInfo.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DirItem.h +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExitCode.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Extract.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\Extract.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractMode.h +# End Source File +# Begin Source File + +SOURCE=..\Common\HandlerLoader.h +# End Source File +# Begin Source File + +SOURCE=..\Common\IFileExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Property.h +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\SetProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\SetProperties.h +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\TempFiles.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\TempFiles.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Update.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\Update.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateProduce.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateProduce.h +# End Source File +# Begin Source File + +SOURCE=..\Common\WorkDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\WorkDir.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ZipRegistry.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ZipRegistry.h +# End Source File +# End Group +# Begin Group "Explorer" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Explorer\MyMessages.cpp +# End Source File +# Begin Source File + +SOURCE=..\Explorer\MyMessages.h +# End Source File +# End Group +# Begin Group "Dialogs" + +# PROP Default_Filter "" +# Begin Group "Progress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\FileManager\Resource\ProgressDialog2\ProgressDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\Resource\ProgressDialog2\ProgressDialog.h +# End Source File +# End Group +# Begin Group "Messages" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\FileManager\Resource\MessagesDialog\MessagesDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\Resource\MessagesDialog\MessagesDialog.h +# End Source File +# End Group +# Begin Group "Overwtite" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\FileManager\Resource\OverwriteDialog\OverwriteDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\Resource\OverwriteDialog\OverwriteDialog.h +# End Source File +# End Group +# Begin Group "Password" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\FileManager\Resource\PasswordDialog\PasswordDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\Resource\PasswordDialog\PasswordDialog.h +# End Source File +# End Group +# Begin Group "Compress Dialog" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\CompressDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\CompressDialog.h +# End Source File +# End Group +# Begin Group "Extract Dialog" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ExtractDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\ExtractDialog.h +# End Source File +# End Group +# End Group +# Begin Group "FM Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\FileManager\ExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\ExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\FolderInterface.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\FormatUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\FormatUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\HelpUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\HelpUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\LangUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\LangUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\OpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\OpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\ProgramLocation.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\ProgramLocation.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\RegistryUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\RegistryUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\SplitUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\SplitUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\StringUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\StringUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\UpdateCallback100.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\UpdateCallback100.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ExtractGUI.cpp +# End Source File +# Begin Source File + +SOURCE=.\ExtractGUI.h +# End Source File +# Begin Source File + +SOURCE=.\GUI.cpp +# End Source File +# Begin Source File + +SOURCE=.\OpenCallbackGUI.cpp +# End Source File +# Begin Source File + +SOURCE=.\OpenCallbackGUI.h +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallbackGUI.cpp +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallbackGUI.h +# End Source File +# Begin Source File + +SOURCE=.\UpdateGUI.cpp +# End Source File +# Begin Source File + +SOURCE=.\UpdateGUI.h +# End Source File +# End Group +# Begin Group "7-zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# End Target +# End Project diff --git a/CPP/7zip/UI/GUI/GUI.dsw b/CPP/7zip/UI/GUI/GUI.dsw new file mode 100755 index 00000000..85d33484 --- /dev/null +++ b/CPP/7zip/UI/GUI/GUI.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "GUI"=.\GUI.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/UI/GUI/OpenCallbackGUI.cpp b/CPP/7zip/UI/GUI/OpenCallbackGUI.cpp new file mode 100755 index 00000000..bc6cf393 --- /dev/null +++ b/CPP/7zip/UI/GUI/OpenCallbackGUI.cpp @@ -0,0 +1,65 @@ +// OpenCallbackGUI.cpp + +#include "StdAfx.h" + +#include "OpenCallbackGUI.h" + +#include "Common/StdOutStream.h" +#include "Common/StdInStream.h" +#include "Common/StringConvert.h" + +#ifndef _NO_CRYPTO +#include "../../FileManager/Resource/PasswordDialog/PasswordDialog.h" +#endif + +HRESULT COpenCallbackGUI::CheckBreak() +{ + return S_OK; +} + +HRESULT COpenCallbackGUI::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */) +{ + return S_OK; +} + +HRESULT COpenCallbackGUI::SetCompleted(const UInt64 * /* files */, const UInt64 * /* bytes */) +{ + return S_OK; +} + +#ifndef _NO_CRYPTO +HRESULT COpenCallbackGUI::CryptoGetTextPassword(BSTR *password) +{ + PasswordWasAsked = true; + if (!PasswordIsDefined) + { + CPasswordDialog dialog; + if (dialog.Create(ParentWindow) == IDCANCEL) + return E_ABORT; + Password = dialog.Password; + PasswordIsDefined = true; + } + CMyComBSTR tempName(Password); + *password = tempName.Detach(); + return S_OK; +} + +HRESULT COpenCallbackGUI::GetPasswordIfAny(UString &password) +{ + if (PasswordIsDefined) + password = Password; + return S_OK; +} + +bool COpenCallbackGUI::WasPasswordAsked() +{ + return PasswordWasAsked; +} + +void COpenCallbackGUI::ClearPasswordWasAskedFlag() +{ + PasswordWasAsked = false; +} + +#endif + diff --git a/CPP/7zip/UI/GUI/OpenCallbackGUI.h b/CPP/7zip/UI/GUI/OpenCallbackGUI.h new file mode 100755 index 00000000..6b531d3c --- /dev/null +++ b/CPP/7zip/UI/GUI/OpenCallbackGUI.h @@ -0,0 +1,35 @@ +// OpenCallbackGUI.h + +#ifndef __OPEN_CALLBACK_GUI_H +#define __OPEN_CALLBACK_GUI_H + +#include "../Common/ArchiveOpenCallback.h" + +class COpenCallbackGUI: public IOpenCallbackUI +{ +public: + HRESULT CheckBreak(); + HRESULT SetTotal(const UInt64 *files, const UInt64 *bytes); + HRESULT SetCompleted(const UInt64 *files, const UInt64 *bytes); + #ifndef _NO_CRYPTO + HRESULT CryptoGetTextPassword(BSTR *password); + HRESULT GetPasswordIfAny(UString &password); + bool WasPasswordAsked(); + void ClearPasswordWasAskedFlag(); + + bool PasswordIsDefined; + UString Password; + bool PasswordWasAsked; + #endif + + HWND ParentWindow; + + COpenCallbackGUI(): + #ifndef _NO_CRYPTO + PasswordIsDefined(false), + PasswordWasAsked(false), + #endif + ParentWindow(0) {} +}; + +#endif diff --git a/CPP/7zip/UI/GUI/StdAfx.cpp b/CPP/7zip/UI/GUI/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/UI/GUI/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/UI/GUI/StdAfx.h b/CPP/7zip/UI/GUI/StdAfx.h new file mode 100755 index 00000000..46ea51cf --- /dev/null +++ b/CPP/7zip/UI/GUI/StdAfx.h @@ -0,0 +1,13 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include +#include +#include +#include + +#include "Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp b/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp new file mode 100755 index 00000000..eff29953 --- /dev/null +++ b/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp @@ -0,0 +1,167 @@ +// UpdateCallbackGUI.cpp + +#include "StdAfx.h" + +#include "UpdateCallbackGUI.h" + +#include "Common/StringConvert.h" +#include "Common/IntToString.h" +#include "Common/Defs.h" + +#include "Windows/PropVariant.h" +#include "Windows/Error.h" +#include "../../FileManager/Resource/MessagesDialog/MessagesDialog.h" +#include "../../FileManager/Resource/PasswordDialog/PasswordDialog.h" + +using namespace NWindows; + +CUpdateCallbackGUI::~CUpdateCallbackGUI() +{ + if (!Messages.IsEmpty()) + { + CMessagesDialog messagesDialog; + messagesDialog.Messages = &Messages; + messagesDialog.Create(ParentWindow); + } +} + +void CUpdateCallbackGUI::Init() +{ + FailedFiles.Clear(); + Messages.Clear(); + NumArchiveErrors = 0; +} + +void CUpdateCallbackGUI::AddErrorMessage(LPCWSTR message) +{ + Messages.Add(message); +} + +void CUpdateCallbackGUI::AddErrorMessage(const wchar_t *name, DWORD systemError) +{ + AddErrorMessage( + UString(L"WARNING: ") + + NError::MyFormatMessageW(systemError) + + UString(L": ") + + UString(name)); +} + +HRESULT CUpdateCallbackGUI::OpenResult(const wchar_t *name, HRESULT result) +{ + if (result != S_OK) + { + AddErrorMessage (UString(L"Error: ") + name + + UString(L" is not supported archive")); + } + return S_OK; +} + +HRESULT CUpdateCallbackGUI::StartScanning() +{ + return S_OK; +} + +HRESULT CUpdateCallbackGUI::CanNotFindError(const wchar_t *name, DWORD systemError) +{ + FailedFiles.Add(name); + AddErrorMessage(name, systemError); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::FinishScanning() +{ + return S_OK; +} + +HRESULT CUpdateCallbackGUI::StartArchive(const wchar_t *name, bool /* updating */) +{ + ProgressDialog.ProgressSynch.SetTitleFileName(name); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::FinishArchive() +{ + return S_OK; +} + +HRESULT CUpdateCallbackGUI::CheckBreak() +{ + for (;;) + { + if(ProgressDialog.ProgressSynch.GetStopped()) + return E_ABORT; + if(!ProgressDialog.ProgressSynch.GetPaused()) + break; + ::Sleep(100); + } + return S_OK; +} + +HRESULT CUpdateCallbackGUI::Finilize() +{ + return S_OK; +} + +HRESULT CUpdateCallbackGUI::SetTotal(UInt64 total) +{ + ProgressDialog.ProgressSynch.SetProgress(total, 0); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::SetCompleted(const UInt64 *completeValue) +{ + RINOK(CheckBreak()); + if (completeValue != NULL) + ProgressDialog.ProgressSynch.SetPos(*completeValue); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::GetStream(const wchar_t *name, bool /* isAnti */) +{ + ProgressDialog.ProgressSynch.SetCurrentFileName(name); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::OpenFileError(const wchar_t *name, DWORD systemError) +{ + FailedFiles.Add(name); + // if (systemError == ERROR_SHARING_VIOLATION) + { + AddErrorMessage(name, systemError); + return S_FALSE; + } + // return systemError; +} + +HRESULT CUpdateCallbackGUI::SetOperationResult(Int32 /* operationResult */) +{ + return S_OK; +} + +HRESULT CUpdateCallbackGUI::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) +{ + if (!PasswordIsDefined) + { + if (AskPassword) + { + CPasswordDialog dialog; + if (dialog.Create(ParentWindow) == IDCANCEL) + return E_ABORT; + Password = dialog.Password; + PasswordIsDefined = true; + } + } + *passwordIsDefined = BoolToInt(PasswordIsDefined); + CMyComBSTR tempName(Password); + *password = tempName.Detach(); + return S_OK; +} + +/* +It doesn't work, since main stream waits Dialog +HRESULT CUpdateCallbackGUI::CloseProgress() +{ + ProgressDialog.MyClose(); + return S_OK; +}; +*/ \ No newline at end of file diff --git a/CPP/7zip/UI/GUI/UpdateCallbackGUI.h b/CPP/7zip/UI/GUI/UpdateCallbackGUI.h new file mode 100755 index 00000000..16f0220c --- /dev/null +++ b/CPP/7zip/UI/GUI/UpdateCallbackGUI.h @@ -0,0 +1,63 @@ +// UpdateCallbackGUI.h + +#ifndef __UPDATE_CALLBACK_GUI_H +#define __UPDATE_CALLBACK_GUI_H + +#include "../Common/Update.h" +#include "../../FileManager/Resource/ProgressDialog2/ProgressDialog.h" + +class CUpdateCallbackGUI: public IUpdateCallbackUI2 +{ +public: + // bool StdOutMode; + bool PasswordIsDefined; + UString Password; + bool AskPassword; + + CUpdateCallbackGUI(): + PasswordIsDefined(false), + AskPassword(false), + // StdOutMode(false) + ParentWindow(0) + {} + + ~CUpdateCallbackGUI(); + void Init(); + + HRESULT OpenResult(const wchar_t *name, HRESULT result); + + HRESULT StartScanning(); + HRESULT CanNotFindError(const wchar_t *name, DWORD systemError); + HRESULT FinishScanning(); + + HRESULT StartArchive(const wchar_t *name, bool updating); + HRESULT FinishArchive(); + + HRESULT CheckBreak(); + HRESULT Finilize(); + HRESULT SetTotal(UInt64 total); + HRESULT SetCompleted(const UInt64 *completeValue); + + HRESULT GetStream(const wchar_t *name, bool isAnti); + HRESULT OpenFileError(const wchar_t *name, DWORD systemError); + HRESULT SetOperationResult(Int32 operationResult); + HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password); + + // HRESULT CloseProgress(); + + UStringVector FailedFiles; + + CProgressDialog ProgressDialog; + HWND ParentWindow; + void StartProgressDialog(const UString &title) + { + ProgressDialog.Create(title, ParentWindow); + } + + UStringVector Messages; + int NumArchiveErrors; + void AddErrorMessage(LPCWSTR message); + void AddErrorMessage(const wchar_t *name, DWORD systemError); +}; + +#endif diff --git a/CPP/7zip/UI/GUI/UpdateGUI.cpp b/CPP/7zip/UI/GUI/UpdateGUI.cpp new file mode 100755 index 00000000..e39e7faf --- /dev/null +++ b/CPP/7zip/UI/GUI/UpdateGUI.cpp @@ -0,0 +1,397 @@ +// UpdateGUI.cpp + +#include "StdAfx.h" + +#include "UpdateGUI.h" + +#include "resource.h" +#include "Common/StringConvert.h" +#include "Common/IntToString.h" +#include "Common/StringToInt.h" + +#include "Windows/FileDir.h" +#include "Windows/Error.h" +#include "Windows/FileFind.h" +#include "Windows/Thread.h" + +#include "../../FileManager/FormatUtils.h" +#include "../../FileManager/ExtractCallback.h" +#include "../../FileManager/StringUtils.h" + +#include "../Common/ArchiveExtractCallback.h" +#include "../Common/WorkDir.h" +#include "../Explorer/MyMessages.h" +#include "../Resource/Extract/resource.h" + +#include "OpenCallbackGUI.h" +#include "CompressDialog.h" +#include "UpdateGUI.h" + +using namespace NWindows; +using namespace NFile; + +static const wchar_t *kIncorrectOutDir = L"Incorrect output directory path"; +static const wchar_t *kDefaultSfxModule = L"7z.sfx"; +static const wchar_t *kSFXExtension = L"exe"; + +struct CThreadUpdating +{ + CUpdateCallbackGUI *UpdateCallbackGUI; + + const NWildcard::CCensor *WildcardCensor; + CUpdateOptions *Options; + COpenCallbackGUI *OpenCallback; + + CUpdateErrorInfo *ErrorInfo; + HRESULT Result; + + DWORD Process() + { + UpdateCallbackGUI->ProgressDialog.WaitCreating(); + try + { + Result = UpdateArchive(*WildcardCensor, *Options, + *ErrorInfo, OpenCallback, UpdateCallbackGUI); + } + catch(const UString &s) + { + ErrorInfo->Message = s; + Result = E_FAIL; + } + catch(const wchar_t *s) + { + ErrorInfo->Message = s; + Result = E_FAIL; + } + catch(const char *s) + { + ErrorInfo->Message = GetUnicodeString(s); + Result = E_FAIL; + } + catch(...) + { + Result = E_FAIL; + } + UpdateCallbackGUI->ProgressDialog.MyClose(); + return 0; + } + static DWORD WINAPI MyThreadFunction(void *param) + { + return ((CThreadUpdating *)param)->Process(); + } +}; + +static void AddProp(CObjectVector &properties, + const UString &name, const UString &value) +{ + CProperty prop; + prop.Name = name; + prop.Value = value; + properties.Add(prop); +} + +static void AddProp(CObjectVector &properties, + const UString &name, UInt32 value) +{ + wchar_t tmp[32]; + ConvertUInt64ToString(value, tmp); + AddProp(properties, name, tmp); +} + +static void AddProp(CObjectVector &properties, + const UString &name, bool value) +{ + AddProp(properties, name, value ? UString(L"on"): UString(L"off")); +} + +static bool IsThereMethodOverride(bool is7z, const UString &propertiesString) +{ + UStringVector strings; + SplitString(propertiesString, strings); + for (int i = 0; i < strings.Size(); i++) + { + const UString &s = strings[i]; + if (is7z) + { + const wchar_t *end; + UInt64 n = ConvertStringToUInt64(s, &end); + if (n == 0 && *end == L'=') + return true; + } + else + { + if (s.Length() > 0) + if (s[0] == L'm' && s[1] == L'=') + return true; + } + } + return false; +} + +static void ParseAndAddPropertires(CObjectVector &properties, + const UString &propertiesString) +{ + UStringVector strings; + SplitString(propertiesString, strings); + for (int i = 0; i < strings.Size(); i++) + { + const UString &s = strings[i]; + CProperty property; + int index = s.Find(L'='); + if (index < 0) + property.Name = s; + else + { + property.Name = s.Left(index); + property.Value = s.Mid(index + 1); + } + properties.Add(property); + } +} + +static void SetOutProperties( + CObjectVector &properties, + bool is7z, + UInt32 level, + bool setMethod, + const UString &method, + UInt32 dictionary, + bool orderMode, + UInt32 order, + bool solidModeIsAllowed, bool solidMode, + bool multiThreadIsAllowed, bool multiThread, + const UString &encryptionMethod, + bool encryptHeadersIsAllowed, bool encryptHeaders, + bool /* sfxMode */) +{ + if (level != (UInt32)(Int32)-1) + AddProp(properties, L"x", (UInt32)level); + if (setMethod) + { + if (!method.IsEmpty()) + AddProp(properties, is7z ? L"0": L"m", method); + if (dictionary != (UInt32)(Int32)-1) + { + UString name; + if (is7z) + name = L"0"; + if (orderMode) + name += L"mem"; + else + name += L"d"; + wchar_t s[32]; + ConvertUInt64ToString(dictionary, s); + size_t len = wcslen(s); + s[len++] = L'B'; + s[len] = L'\0'; + AddProp(properties, name, UString(s)); + } + if (order != (UInt32)(Int32)-1) + { + UString name; + if (is7z) + name = L"0"; + if (orderMode) + name += L"o"; + else + name += L"fb"; + AddProp(properties, name, (UInt32)order); + } + } + + if (!encryptionMethod.IsEmpty()) + AddProp(properties, L"em", encryptionMethod); + + if (encryptHeadersIsAllowed) + AddProp(properties, L"he", encryptHeaders); + if (solidModeIsAllowed) + AddProp(properties, L"s", solidMode); + if (multiThreadIsAllowed) + AddProp(properties, L"mt", multiThread); +} + +static HRESULT ShowDialog(const NWildcard::CCensor &censor, + CUpdateOptions &options, CUpdateCallbackGUI *callback) +{ + if (options.Commands.Size() != 1) + throw "It must be one command"; + CObjectVector archivers; + CArchiverInfo archiverInfo; + ReadArchiverInfoList(archivers); + UString currentDirPrefix; + { + if (!NDirectory::MyGetCurrentDirectory(currentDirPrefix)) + return E_FAIL; + NName::NormalizeDirPathPrefix(currentDirPrefix); + } + + bool oneFile = false; + NFind::CFileInfoW fileInfo; + if (censor.Pairs.Size() > 0) + { + const NWildcard::CPair &pair = censor.Pairs[0]; + if (pair.Head.IncludeItems.Size() > 0) + { + const NWildcard::CItem &item = pair.Head.IncludeItems[0]; + if (item.ForFile) + { + UString name = pair.Prefix; + for (int i = 0; i < item.PathParts.Size(); i++) + { + if (i > 0) + name += L'\\'; + name += item.PathParts[i]; + } + if (NFind::FindFile(name, fileInfo)) + { + if (censor.Pairs.Size() == 1 && pair.Head.IncludeItems.Size() == 1) + oneFile = !fileInfo.IsDirectory(); + } + } + } + } + + CCompressDialog dialog; + NCompressDialog::CInfo &di = dialog.Info; + for(int i = 0; i < archivers.Size(); i++) + { + const CArchiverInfo &ai = archivers[i]; + if (ai.UpdateEnabled && (oneFile || !ai.KeepName)) + dialog.m_ArchiverInfoList.Add(ai); + } + if(dialog.m_ArchiverInfoList.Size() == 0) + { + MyMessageBox(L"No Update Engines"); + return E_FAIL; + } + + // di.ArchiveName = options.ArchivePath.GetFinalPath(); + di.ArchiveName = options.ArchivePath.GetPathWithoutExt(); + dialog.OriginalFileName = fileInfo.Name; + + di.CurrentDirPrefix = currentDirPrefix; + di.SFXMode = options.SfxMode; + + di.Solid = true; + di.MultiThread = false; + + if (callback->PasswordIsDefined) + di.Password = callback->Password; + + di.KeepName = !oneFile; + + if(dialog.Create(0) != IDOK) + return E_ABORT; + + options.VolumesSizes = di.VolumeSizes; + /* + if (di.VolumeSizeIsDefined) + { + MyMessageBox(L"Splitting to volumes is not supported"); + return E_FAIL; + } + */ + + NUpdateArchive::CActionSet &actionSet = options.Commands.Front().ActionSet; + + switch(di.UpdateMode) + { + case NCompressDialog::NUpdateMode::kAdd: + actionSet = NUpdateArchive::kAddActionSet; + break; + case NCompressDialog::NUpdateMode::kUpdate: + actionSet = NUpdateArchive::kUpdateActionSet; + break; + case NCompressDialog::NUpdateMode::kFresh: + actionSet = NUpdateArchive::kFreshActionSet; + break; + case NCompressDialog::NUpdateMode::kSynchronize: + actionSet = NUpdateArchive::kSynchronizeActionSet; + break; + default: + throw 1091756; + } + archiverInfo = dialog.m_ArchiverInfoList[di.ArchiverInfoIndex]; + callback->PasswordIsDefined = (!di.Password.IsEmpty()); + if (callback->PasswordIsDefined) + callback->Password = di.Password; + + options.MethodMode.Properties.Clear(); + + bool is7z = archiverInfo.Name.CompareNoCase(L"7z") == 0; + bool methodOverride = IsThereMethodOverride(is7z, di.Options); + + SetOutProperties( + options.MethodMode.Properties, + is7z, + di.Level, + !methodOverride, + di.Method, + di.Dictionary, + di.OrderMode, di.Order, + di.SolidIsAllowed, di.Solid, + di.MultiThreadIsAllowed, di.MultiThread, + di.EncryptionMethod, + di.EncryptHeadersIsAllowed, di.EncryptHeaders, + di.SFXMode); + + ParseAndAddPropertires(options.MethodMode.Properties, di.Options); + + if (di.SFXMode) + options.SfxMode = true; + options.MethodMode.FilePath = archiverInfo.FilePath; + options.MethodMode.ClassID = archiverInfo.ClassID; + + options.ArchivePath.VolExtension = archiverInfo.GetMainExtension(); + if(di.SFXMode) + options.ArchivePath.BaseExtension = kSFXExtension; + else + options.ArchivePath.BaseExtension = options.ArchivePath.VolExtension; + options.ArchivePath.ParseFromPath(di.ArchiveName); + + NWorkDir::CInfo workDirInfo; + ReadWorkDirInfo(workDirInfo); + options.WorkingDir.Empty(); + if (workDirInfo.Mode != NWorkDir::NMode::kCurrent) + { + UString fullPath; + NDirectory::MyGetFullPathName(di.ArchiveName, fullPath); + options.WorkingDir = GetWorkDir(workDirInfo, fullPath); + NFile::NDirectory::CreateComplexDirectory(options.WorkingDir); + } + return S_OK; +} + +HRESULT UpdateGUI( + const NWildcard::CCensor &censor, + CUpdateOptions &options, + bool showDialog, + CUpdateErrorInfo &errorInfo, + COpenCallbackGUI *openCallback, + CUpdateCallbackGUI *callback) +{ + if (showDialog) + { + RINOK(ShowDialog(censor, options, callback)); + } + if (options.SfxMode && options.SfxModule.IsEmpty()) + options.SfxModule = kDefaultSfxModule; + + CThreadUpdating tu; + + tu.UpdateCallbackGUI = callback; + tu.UpdateCallbackGUI->Init(); + + tu.WildcardCensor = &censor; + tu.Options = &options; + tu.OpenCallback = openCallback; + tu.ErrorInfo = &errorInfo; + + CThread thread; + if (!thread.Create(CThreadUpdating::MyThreadFunction, &tu)) + throw 271824; + tu.UpdateCallbackGUI->StartProgressDialog(LangString(IDS_PROGRESS_COMPRESSING, 0x02000DC0)); + return tu.Result; +} + + diff --git a/CPP/7zip/UI/GUI/UpdateGUI.h b/CPP/7zip/UI/GUI/UpdateGUI.h new file mode 100755 index 00000000..c5061aca --- /dev/null +++ b/CPP/7zip/UI/GUI/UpdateGUI.h @@ -0,0 +1,20 @@ +// GUI/UpdateGUI.h + +#ifndef __UPDATE_GUI_H +#define __UPDATE_GUI_H + +#include "../Common/Update.h" +#include "OpenCallbackGUI.h" +#include "UpdateCallbackGUI.h" + +#include "../../FileManager/UpdateCallback100.h" + +HRESULT UpdateGUI( + const NWildcard::CCensor &censor, + CUpdateOptions &options, + bool showDialog, + CUpdateErrorInfo &errorInfo, + COpenCallbackGUI *openCallback, + CUpdateCallbackGUI *callback); + +#endif diff --git a/CPP/7zip/UI/GUI/makefile b/CPP/7zip/UI/GUI/makefile new file mode 100755 index 00000000..bc6af149 --- /dev/null +++ b/CPP/7zip/UI/GUI/makefile @@ -0,0 +1,135 @@ +PROG = 7zG.exe +LIBS = $(LIBS) user32.lib advapi32.lib oleaut32.lib shell32.lib comctl32.lib htmlhelp.lib ole32.lib comdlg32.lib +CFLAGS = $(CFLAGS) -I ../../../ -DLANG -DCOMPRESS_MT -DWIN_LONG_PATH + +GUI_OBJS = \ + $O\CompressDialog.obj \ + $O\ExtractDialog.obj \ + $O\ExtractGUI.obj \ + $O\GUI.obj \ + $O\OpenCallbackGUI.obj \ + $O\UpdateCallbackGUI.obj \ + $O\UpdateGUI.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CommandLineParser.obj \ + $O\IntToString.obj \ + $O\Lang.obj \ + $O\ListFileUtils.obj \ + $O\NewHandler.obj \ + $O\StdInStream.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\TextConfig.obj \ + $O\UTFConvert.obj \ + $O\Vector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\CommonDialog.obj \ + $O\DLL.obj \ + $O\Error.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\MemoryLock.obj \ + $O\PropVariant.obj \ + $O\PropVariantConversions.obj \ + $O\Registry.obj \ + $O\ResourceString.obj \ + $O\Shell.obj \ + $O\Synchronization.obj \ + $O\Window.obj \ + +WIN_CTRL_OBJS = \ + $O\ComboBox.obj \ + $O\Dialog.obj \ + $O\ListView.obj \ + +7ZIP_COMMON_OBJS = \ + $O\FilePathAutoRename.obj \ + $O\FileStreams.obj \ + $O\StreamUtils.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveCommandLine.obj \ + $O\ArchiveExtractCallback.obj \ + $O\ArchiveOpenCallback.obj \ + $O\ArchiverInfo.obj \ + $O\DefaultName.obj \ + $O\EnumDirItems.obj \ + $O\Extract.obj \ + $O\ExtractingFilePath.obj \ + $O\OpenArchive.obj \ + $O\PropIDUtils.obj \ + $O\SetProperties.obj \ + $O\SortUtils.obj \ + $O\TempFiles.obj \ + $O\Update.obj \ + $O\UpdateAction.obj \ + $O\UpdateCallback.obj \ + $O\UpdatePair.obj \ + $O\UpdateProduce.obj \ + $O\WorkDir.obj \ + $O\ZipRegistry.obj \ + +FM_OBJS = \ + $O\ExtractCallback.obj \ + $O\FormatUtils.obj \ + $O\HelpUtils.obj \ + $O\LangUtils.obj \ + $O\OpenCallback.obj \ + $O\ProgramLocation.obj \ + $O\RegistryUtils.obj \ + $O\SplitUtils.obj \ + $O\StringUtils.obj \ + $O\UpdateCallback100.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(GUI_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(WIN_CTRL_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(UI_COMMON_OBJS) \ + $(FM_OBJS)\ + $O\MyMessages.obj \ + $O\MessagesDialog.obj \ + $O\OverwriteDialog.obj \ + $O\PasswordDialog.obj \ + $O\ProgressDialog.obj \ + $O\CopyCoder.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(GUI_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(WIN_CTRL_OBJS): ../../../Windows/Control/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(UI_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$(FM_OBJS): ../../FileManager/$(*B).cpp + $(COMPL) +$O\MyMessages.obj: ../Explorer/MyMessages.cpp + $(COMPL) +$O\MessagesDialog.obj: ../../FileManager/Resource/MessagesDialog/$(*B).cpp + $(COMPL) +$O\OverwriteDialog.obj: ../../FileManager/Resource/OverwriteDialog./$(*B).cpp + $(COMPL) +$O\PasswordDialog.obj: ../../FileManager/Resource/PasswordDialog/$(*B).cpp + $(COMPL) +$O\ProgressDialog.obj: ../../FileManager/Resource/ProgressDialog2/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/UI/GUI/resource.h b/CPP/7zip/UI/GUI/resource.h new file mode 100755 index 00000000..d88af787 --- /dev/null +++ b/CPP/7zip/UI/GUI/resource.h @@ -0,0 +1,45 @@ +#define IDS_CONTEXT_EXTRACT 42 +#define IDS_CONTEXT_EXTRACT_HELP 43 +#define IDS_CONTEXT_COMPRESS 44 +#define IDS_CONTEXT_COMPRESS_HELP 45 +#define IDS_CONTEXT_OPEN 46 +#define IDS_CONTEXT_OPEN_HELP 47 +#define IDS_CONTEXT_TEST 48 +#define IDS_CONTEXT_TEST_HELP 49 +#define IDS_CONTEXT_CAPTION_HELP 50 +#define IDS_CONTEXT_POPUP_CAPTION 51 +#define IDS_OPEN_TYPE_ALL_FILES 80 + +#define IDS_METHOD_STORE 81 +#define IDS_METHOD_NORMAL 82 +#define IDS_METHOD_MAXIMUM 83 +#define IDS_METHOD_FAST 84 +#define IDS_METHOD_FASTEST 85 +#define IDS_METHOD_ULTRA 86 + +#define IDS_COMPRESS_UPDATE_MODE_ADD 90 +#define IDS_COMPRESS_UPDATE_MODE_UPDATE 91 +#define IDS_COMPRESS_UPDATE_MODE_FRESH 92 +#define IDS_COMPRESS_UPDATE_MODE_SYNCHRONIZE 93 + +#define IDS_COMPRESS_SPLIT_CONFIRM_MESSAGE 94 +#define IDS_COMPRESS_INCORRECT_VOLUME_SIZE 95 + +#define IDS_COMPRESS_SET_ARCHIVE_DIALOG_TITLE 96 +#define IDS_CANT_UPDATE_ARCHIVE 97 + +#define IDS_PROGRESS_COMPRESSING 98 +#define IDS_PROGRESS_TESTING 99 +#define IDS_ERROR 100 +#define IDS_MESSAGE_NO_ERRORS 101 +#define IDS_CONFIG_DIALOG_CAPTION 102 + +#define IDS_PASSWORD_USE_ASCII 110 +#define IDS_PASSWORD_PASSWORDS_DO_NOT_MATCH 111 +#define IDS_PASSWORD_IS_TOO_LONG 112 + +#define IDD_DIALOG_EXTRACT 137 +#define IDB_DELETE 149 +#define IDC_LIST1 1067 +#define IDC_COLUMN_EDIT_WIDTH 1068 + diff --git a/CPP/7zip/UI/GUI/resource.rc b/CPP/7zip/UI/GUI/resource.rc new file mode 100755 index 00000000..19f7e61b --- /dev/null +++ b/CPP/7zip/UI/GUI/resource.rc @@ -0,0 +1,57 @@ +#include "../../MyVersionInfo.rc" +#include +#include "resource.h" + +MY_VERSION_INFO_APP("7-Zip GUI", "7zg") + +IDI_ICON1 ICON "FM.ico" + +1 24 MOVEABLE PURE "7zG.exe.manifest" + +STRINGTABLE +BEGIN + IDS_CONTEXT_EXTRACT "Extract files..." + IDS_CONTEXT_EXTRACT_HELP "Extracts files from the selected archive." + IDS_CONTEXT_COMPRESS "Add to archive..." + IDS_CONTEXT_COMPRESS_HELP "Adds the selected items to archive." + IDS_CONTEXT_OPEN "Open" + IDS_CONTEXT_OPEN_HELP "Opens the selected archive." + IDS_CONTEXT_TEST "Test archive" + IDS_CONTEXT_TEST_HELP "Tests integrity of the selected archive." + IDS_CONTEXT_CAPTION_HELP "7-Zip commands" + IDS_CONTEXT_POPUP_CAPTION "7-Zip" + IDS_OPEN_TYPE_ALL_FILES "All Files" + IDS_METHOD_STORE "Store" + IDS_METHOD_NORMAL "Normal" + IDS_METHOD_MAXIMUM "Maximum" + IDS_METHOD_FAST "Fast" + IDS_METHOD_FASTEST "Fastest" + IDS_METHOD_ULTRA "Ultra" + IDS_COMPRESS_UPDATE_MODE_ADD "Add and replace files" + IDS_COMPRESS_UPDATE_MODE_UPDATE "Update and add files" + IDS_COMPRESS_UPDATE_MODE_FRESH "Freshen existing files" + IDS_COMPRESS_UPDATE_MODE_SYNCHRONIZE "Synchronize files" + IDS_COMPRESS_SET_ARCHIVE_DIALOG_TITLE "Browse" + IDS_COMPRESS_INCORRECT_VOLUME_SIZE "Incorrect volume size" + IDS_COMPRESS_SPLIT_CONFIRM_MESSAGE "Specified volume size: {0} bytes.\nAre you sure you want to split archive into such volumes?" + + IDS_PASSWORD_USE_ASCII "Use only English letters, numbers and special characters (!, #, $, ...) for password." + IDS_PASSWORD_PASSWORDS_DO_NOT_MATCH "Passwords do not match" + IDS_PASSWORD_IS_TOO_LONG "Password is too long" + + IDS_CANT_UPDATE_ARCHIVE "Can not update archive '{0}'" + IDS_PROGRESS_COMPRESSING "Compressing" + IDS_PROGRESS_TESTING "Testing" + IDS_ERROR "Error" + IDS_MESSAGE_NO_ERRORS "There are no errors" + IDS_CONFIG_DIALOG_CAPTION "7-Zip Options" +END + +#include "../../FileManager/Resource/PropertyName/resource.rc" +#include "../../FileManager/Resource/OverwriteDialog/resource.rc" +#include "../../FileManager/Resource/PasswordDialog/resource.rc" +#include "../../FileManager/Resource/MessagesDialog/resource.rc" +#include "../../FileManager/Resource/ProgressDialog2/resource.rc" +#include "../Resource/Extract/resource.rc" +#include "../Resource/ExtractDialog/resource.rc" +#include "../Resource/CompressDialog/resource.rc" diff --git a/CPP/7zip/UI/Resource/CompressDialog/resource.h b/CPP/7zip/UI/Resource/CompressDialog/resource.h new file mode 100755 index 00000000..847bb3f9 --- /dev/null +++ b/CPP/7zip/UI/Resource/CompressDialog/resource.h @@ -0,0 +1,40 @@ +#define IDD_DIALOG_COMPRESS 152 +#define IDC_STATIC_COMPRESS_MEMORY 1022 +#define IDC_STATIC_COMPRESS_MEMORY_DE 1023 +#define IDC_STATIC_COMPRESS_MEMORY_VALUE 1027 +#define IDC_STATIC_COMPRESS_MEMORY_DE_VALUE 1028 +#define IDC_COMPRESS_COMBO_ARCHIVE 1072 +#define IDC_COMPRESS_BUTTON_SET_ARCHIVE 1073 +#define IDC_COMPRESS_COMBO_LEVEL 1074 +#define IDC_COMPRESS_COMBO_UPDATE_MODE 1075 +#define IDC_COMPRESS_COMBO_FORMAT 1076 +#define IDC_COMPRESS_COMBO_VOLUME 1077 +#define IDC_COMPRESS_COMBO_METHOD 1078 +#define IDC_COMPRESS_COMBO_DICTIONARY 1079 +#define IDC_COMPRESS_COMBO_ORDER 1080 +#define IDC_COMPRESS_SFX 1090 +#define IDC_COMPRESS_EDIT_PARAMETERS 1091 +#define IDC_COMPRESS_SOLID 1092 +#define IDC_COMPRESS_MULTI_THREAD 1093 +#define IDC_STATIC_COMPRESS_ARCHIVE 1097 +#define IDC_STATIC_COMPRESS_FORMAT 1098 +#define IDC_STATIC_COMPRESS_LEVEL 1099 +#define IDC_STATIC_COMPRESS_PARAMETERS 1100 +#define IDC_STATIC_COMPRESS_UPDATE_MODE 1101 +#define IDC_STATIC_COMPRESS_OPTIONS 1102 +#define IDC_STATIC_COMPRESS_VOLUME 1103 +#define IDC_STATIC_COMPRESS_METHOD 1104 +#define IDC_STATIC_COMPRESS_DICTIONARY 1105 +#define IDC_STATIC_COMPRESS_ORDER 1106 + +#define IDC_COMPRESS_ENCRYPTION 1110 +#define IDC_STATIC_COMPRESS_PASSWORD1 1111 +#define IDC_COMPRESS_EDIT_PASSWORD1 1112 +#define IDC_STATIC_COMPRESS_PASSWORD2 1113 +#define IDC_COMPRESS_EDIT_PASSWORD2 1114 +#define IDC_COMPRESS_CHECK_SHOW_PASSWORD 1115 + +#define IDC_STATIC_COMPRESS_ENCRYPTION_METHOD 1120 +#define IDC_COMPRESS_COMBO_ENCRYPTION_METHOD 1121 + +#define IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES 1122 diff --git a/CPP/7zip/UI/Resource/CompressDialog/resource.rc b/CPP/7zip/UI/Resource/CompressDialog/resource.rc new file mode 100755 index 00000000..9019a1af --- /dev/null +++ b/CPP/7zip/UI/Resource/CompressDialog/resource.rc @@ -0,0 +1,117 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" + +#define xSize2 344 +#define ySize2 295 + +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#undef gSize +#undef gSpace +#undef g0XSize +#undef g1XPos +#undef g1XSize +#undef g2XSize +#undef g3XPos +#undef g3XSize +#undef g4XPos +#undef g4XPos2 +#undef g4XSize +#undef g4XSize2 +#undef bXPos1 +#undef bXPos2 +#undef bXPos3 +#undef bYPos + +#define gSize 160 +#define gSpace 24 + +#define g0XSize 82 +#define g1XPos (marg + g0XSize) +#define g1XSize (gSize - g0XSize) + +#define g2XSize 122 +#define g3XPos (marg + g2XSize) +#define g3XSize (gSize - g2XSize) + +#define g4XPos (marg + gSize + gSpace) +#define g4XPos2 (g4XPos + 7) +#define g4XSize (xSize2 - gSize - gSpace) +#define g4XSize2 (g4XSize - 14) + +#define bXPos1 (xSize - marg - bXSize) +#define bXPos2 (bXPos1 - 10 - bXSize) +#define bXPos3 (bXPos2 - 10 - bXSize) + +#define bYPos (ySize - marg - bYSize) + +IDD_DIALOG_COMPRESS DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE +CAPTION "Add to Archive" +MY_FONT +BEGIN + LTEXT "&Archive:", IDC_STATIC_COMPRESS_ARCHIVE, marg, marg, xSize2, 8 + COMBOBOX IDC_COMPRESS_COMBO_ARCHIVE, marg, 18, xSize2 - bDotsSize - 12, 126, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "...", IDC_COMPRESS_BUTTON_SET_ARCHIVE, xSize - marg - bDotsSize, 17, bDotsSize, bYSize, WS_GROUP + + LTEXT "Archive &format:", IDC_STATIC_COMPRESS_FORMAT, marg, 41, g0XSize, 8 + COMBOBOX IDC_COMPRESS_COMBO_FORMAT, g1XPos, 39, g1XSize , 80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + + LTEXT "Compression &level:",IDC_STATIC_COMPRESS_LEVEL, marg, 62, g0XSize, 8 + COMBOBOX IDC_COMPRESS_COMBO_LEVEL, g1XPos, 60, g1XSize, 80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + + LTEXT "Compression &method:",IDC_STATIC_COMPRESS_METHOD, marg, 83, g0XSize, 8 + COMBOBOX IDC_COMPRESS_COMBO_METHOD, g1XPos, 81, g1XSize, 80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + + LTEXT "&Dictionary size:",IDC_STATIC_COMPRESS_DICTIONARY, marg, 104, g0XSize, 8 + COMBOBOX IDC_COMPRESS_COMBO_DICTIONARY, g1XPos, 102, g1XSize, 167, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + + LTEXT "&Word size:",IDC_STATIC_COMPRESS_ORDER, marg, 125, g0XSize, 8 + COMBOBOX IDC_COMPRESS_COMBO_ORDER, g1XPos, 123, g1XSize, 141, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + + + LTEXT "Memory usage for Compressing:", IDC_STATIC_COMPRESS_MEMORY, marg, 149, g2XSize, 8 + RTEXT "0", IDC_STATIC_COMPRESS_MEMORY_VALUE, g3XPos, 149, g3XSize, 8 + + LTEXT "Memory usage for Decompressing:", IDC_STATIC_COMPRESS_MEMORY_DE, marg, 163, g2XSize, 8 + RTEXT "0",IDC_STATIC_COMPRESS_MEMORY_DE_VALUE, g3XPos, 163, g3XSize, 8 + + + CONTROL "Create &Solid archive", IDC_COMPRESS_SOLID,"Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, 181, gSize, 10 + CONTROL "Multi-threading", IDC_COMPRESS_MULTI_THREAD, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, 195, gSize, 10 + + LTEXT "Split to &volumes, bytes:", IDC_STATIC_COMPRESS_VOLUME, marg, 215, gSize, 8 + COMBOBOX IDC_COMPRESS_COMBO_VOLUME, marg, 227, gSize, 73, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + + LTEXT "&Parameters:",IDC_STATIC_COMPRESS_PARAMETERS, marg, 250, xSize2, 8 + EDITTEXT IDC_COMPRESS_EDIT_PARAMETERS, marg, 262, xSize2, 14, ES_AUTOHSCROLL + + LTEXT "&Update mode:",IDC_STATIC_COMPRESS_UPDATE_MODE, g4XPos, 39, g4XSize, 8 + COMBOBOX IDC_COMPRESS_COMBO_UPDATE_MODE, g4XPos, 51, g4XSize, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + + GROUPBOX "Options",IDC_STATIC_COMPRESS_OPTIONS, g4XPos, 73, g4XSize, 32 + CONTROL "Create SF&X archive",IDC_COMPRESS_SFX, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + g4XPos2, 87, g4XSize2, 10 + + GROUPBOX "Encryption",IDC_COMPRESS_ENCRYPTION, g4XPos, 113, g4XSize, 127 + + LTEXT "Enter password:",IDC_STATIC_COMPRESS_PASSWORD1, g4XPos2, 127, g4XSize2, 8 + EDITTEXT IDC_COMPRESS_EDIT_PASSWORD1, g4XPos2, 139, g4XSize2, 14, ES_PASSWORD | ES_AUTOHSCROLL + LTEXT "Reenter password:",IDC_STATIC_COMPRESS_PASSWORD2, g4XPos2, 159, g4XSize2, 8 + EDITTEXT IDC_COMPRESS_EDIT_PASSWORD2, g4XPos2, 171, g4XSize2, 14, ES_PASSWORD | ES_AUTOHSCROLL + + CONTROL "Show Password",IDC_COMPRESS_CHECK_SHOW_PASSWORD,"Button", BS_AUTOCHECKBOX | WS_TABSTOP, + g4XPos2, 192, g4XSize2, 10 + + LTEXT "&Encryption method:",IDC_STATIC_COMPRESS_ENCRYPTION_METHOD, g4XPos2, 208, 80, 8 + COMBOBOX IDC_COMPRESS_COMBO_ENCRYPTION_METHOD, g4XPos2 + 90, 206, g4XSize2 - 90, 198, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + + CONTROL "Encrypt file &names", IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + g4XPos2, 224, g4XSize2, 10 + + DEFPUSHBUTTON "OK", IDOK, bXPos3, bYPos, bXSize, bYSize, WS_GROUP + PUSHBUTTON "Cancel", IDCANCEL, bXPos2, bYPos, bXSize, bYSize + PUSHBUTTON "Help", IDHELP, bXPos1, bYPos, bXSize, bYSize +END diff --git a/CPP/7zip/UI/Resource/Extract/resource.h b/CPP/7zip/UI/Resource/Extract/resource.h new file mode 100755 index 00000000..917c0a34 --- /dev/null +++ b/CPP/7zip/UI/Resource/Extract/resource.h @@ -0,0 +1,15 @@ +#define IDS_CANNOT_CREATE_FOLDER 200 +#define IDS_OPEN_IS_NOT_SUPORTED_ARCHIVE 201 + +#define IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CRC 202 +#define IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_DATA_ERROR 203 +#define IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_UNSUPPORTED_METHOD 204 +#define IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CRC_ENCRYPTED 205 +#define IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED 206 + +#define IDS_EXTRACT_SET_FOLDER 207 +#define IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CANNOT_OPEN_FILE 208 +#define IDS_PROGRESS_EXTRACTING 209 + +#define IDS_CANT_OPEN_ARCHIVE 103 +#define IDS_CANT_OPEN_ENCRYPTED_ARCHIVE 104 diff --git a/CPP/7zip/UI/Resource/Extract/resource.rc b/CPP/7zip/UI/Resource/Extract/resource.rc new file mode 100755 index 00000000..d3fd1df9 --- /dev/null +++ b/CPP/7zip/UI/Resource/Extract/resource.rc @@ -0,0 +1,19 @@ +#include "resource.h" + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +STRINGTABLE DISCARDABLE +BEGIN + IDS_CANNOT_CREATE_FOLDER "Cannot create folder '{0}'" + IDS_OPEN_IS_NOT_SUPORTED_ARCHIVE "File is not supported archive." + IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CRC "CRC failed in '{0}'. File is broken." + IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_DATA_ERROR "Data error in '{0}'. File is broken" + IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CRC_ENCRYPTED "CRC failed in encrypted file '{0}'. Wrong password?" + IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED "Data error in encrypted file '{0}'. Wrong password?" + IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_UNSUPPORTED_METHOD "Unsupported compression method for '{0}'." + IDS_EXTRACT_SET_FOLDER "Specify a location for extracted files." + IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CANNOT_OPEN_FILE "Can not open output file '{0}'." + IDS_PROGRESS_EXTRACTING "Extracting" + IDS_CANT_OPEN_ARCHIVE "Can not open file '{0}' as archive" + IDS_CANT_OPEN_ENCRYPTED_ARCHIVE "Can not open encrypted archive '{0}'. Wrong password?" +END diff --git a/CPP/7zip/UI/Resource/ExtractDialog/resource.h b/CPP/7zip/UI/Resource/ExtractDialog/resource.h new file mode 100755 index 00000000..338a2561 --- /dev/null +++ b/CPP/7zip/UI/Resource/ExtractDialog/resource.h @@ -0,0 +1,26 @@ +#define IDC_STATIC_EXTRACT_EXTRACT_TO 1020 +#define IDC_EXTRACT_COMBO_PATH 1021 +#define IDC_EXTRACT_BUTTON_SET_PATH 1022 + + +#define IDC_EXTRACT_PATH_MODE 1040 +#define IDC_EXTRACT_RADIO_FULL_PATHNAMES 1041 +#define IDC_EXTRACT_RADIO_CURRENT_PATHNAMES 1042 +#define IDC_EXTRACT_RADIO_NO_PATHNAMES 1043 + +#define IDC_EXTRACT_OVERWRITE_MODE 1050 +#define IDC_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE 1051 +#define IDC_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT 1052 +#define IDC_EXTRACT_RADIO_SKIP_EXISTING_FILES 1053 +#define IDC_EXTRACT_RADIO_SELECTED_FILES 1054 +#define IDC_EXTRACT_RADIO_ALL_FILES 1055 +#define IDC_EXTRACT_RADIO_AUTO_RENAME 1056 +#define IDC_EXTRACT_RADIO_AUTO_RENAME_EXISTING 1057 + + +#define IDC_EXTRACT_FILES 1060 + +#define IDC_EXTRACT_PASSWORD 1100 +#define IDC_EXTRACT_EDIT_PASSWORD 1101 +#define IDC_EXTRACT_CHECK_SHOW_PASSWORD 1102 + diff --git a/CPP/7zip/UI/Resource/ExtractDialog/resource.rc b/CPP/7zip/UI/Resource/ExtractDialog/resource.rc new file mode 100755 index 00000000..05cf5ea6 --- /dev/null +++ b/CPP/7zip/UI/Resource/ExtractDialog/resource.rc @@ -0,0 +1,80 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" + +#define xSize2 285 +#define ySize2 204 + +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#undef g1XSize +#undef g1XSize2 +#undef g1XPos2 +#undef g2XPos +#undef g2XPos2 +#undef g2XSize +#undef g2XSize2 + +#define bYPos (ySize - marg - bYSize) + +#define g1XSize 127 +#define g1XSize2 (g1XSize - 13) +#define g1XPos2 (marg + 7) + +#define gSpace 14 +#define g2XPos (marg + g1XSize + gSpace) +#define g2XPos2 (g2XPos + 7) +#define g2XSize (xSize2 - g1XSize - gSpace) +#define g2XSize2 (g2XSize - 14) + +#define bXPos1 (xSize - marg - bXSize) +#define bXPos2 (bXPos1 - 10 - bXSize) +#define bXPos3 (bXPos2 - 10 - bXSize) + +IDD_DIALOG_EXTRACT DIALOG DISCARDABLE 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE +CAPTION "Extract" +MY_FONT +BEGIN + LTEXT "E&xtract to:", IDC_STATIC_EXTRACT_EXTRACT_TO, marg, marg, xSize2, 8 + + COMBOBOX IDC_EXTRACT_COMBO_PATH, marg, 21, xSize2 - bDotsSize - 13, 126, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + + PUSHBUTTON "...", IDC_EXTRACT_BUTTON_SET_PATH, xSize - marg - bDotsSize, 20, bDotsSize, bYSize, WS_GROUP + + GROUPBOX "Path mode",IDC_EXTRACT_PATH_MODE, marg, 44, g1XSize, 57 + CONTROL "Full pathnames", IDC_EXTRACT_RADIO_FULL_PATHNAMES,"Button", BS_AUTORADIOBUTTON | WS_GROUP, + g1XPos2, 57, g1XSize2, 10 + CONTROL "Current pathnames",IDC_EXTRACT_RADIO_CURRENT_PATHNAMES, "Button", BS_AUTORADIOBUTTON, + g1XPos2, 71, g1XSize2, 10 + CONTROL "No pathnames", IDC_EXTRACT_RADIO_NO_PATHNAMES, "Button", BS_AUTORADIOBUTTON, + g1XPos2, 85, g1XSize2, 10 + + GROUPBOX "Overwrite mode",IDC_EXTRACT_OVERWRITE_MODE, g2XPos, 44, g2XSize, 88, WS_GROUP + CONTROL "Ask before overwrite", IDC_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE, "Button", BS_AUTORADIOBUTTON | WS_GROUP, + g2XPos2, 57, g2XSize2, 10 + CONTROL "Overwrite without prompt", IDC_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT, "Button", BS_AUTORADIOBUTTON, + g2XPos2, 71, g2XSize2, 10 + CONTROL "Skip existing files", IDC_EXTRACT_RADIO_SKIP_EXISTING_FILES, "Button", BS_AUTORADIOBUTTON, + g2XPos2, 85, g2XSize2, 10 + CONTROL "Auto rename", IDC_EXTRACT_RADIO_AUTO_RENAME, "Button", BS_AUTORADIOBUTTON, + g2XPos2, 99, g2XSize2, 10 + CONTROL "Auto rename existing files", IDC_EXTRACT_RADIO_AUTO_RENAME_EXISTING, "Button", BS_AUTORADIOBUTTON, + g2XPos2,113, g2XSize2, 10 + + GROUPBOX "Files",IDC_EXTRACT_FILES, marg, 140, 127, 48, NOT WS_VISIBLE | WS_DISABLED | WS_GROUP + CONTROL "&Selected files",IDC_EXTRACT_RADIO_SELECTED_FILES, "Button", BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_DISABLED | WS_GROUP, + g1XPos2, 153, g1XSize2, 10 + CONTROL "&All files",IDC_EXTRACT_RADIO_ALL_FILES, "Button", BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_DISABLED, + g1XPos2, 166, g1XSize2, 10 + + GROUPBOX "Password",IDC_EXTRACT_PASSWORD, g2XPos, 142, g2XSize, 46 + EDITTEXT IDC_EXTRACT_EDIT_PASSWORD,154,153,130,14, ES_PASSWORD | ES_AUTOHSCROLL + CONTROL "Show Password",IDC_EXTRACT_CHECK_SHOW_PASSWORD,"Button", BS_AUTOCHECKBOX | WS_TABSTOP, + g2XPos2, 172, g2XSize2, 10 + + DEFPUSHBUTTON "OK", IDOK, bXPos3, bYPos, bXSize, bYSize, WS_GROUP + PUSHBUTTON "Cancel", IDCANCEL, bXPos2, bYPos, bXSize, bYSize + PUSHBUTTON "Help", IDHELP, bXPos1, bYPos, bXSize, bYSize +END + + diff --git a/CPP/7zip/UI/makefile b/CPP/7zip/UI/makefile new file mode 100755 index 00000000..942beaa0 --- /dev/null +++ b/CPP/7zip/UI/makefile @@ -0,0 +1,10 @@ +DIRS = \ + Client7z\~ \ + Console\~ \ + Explorer\~ \ + GUI\~ \ + +all: $(DIRS) + +$(DIRS): +!include "../SubBuild.mak" diff --git a/CPP/7zip/makefile b/CPP/7zip/makefile new file mode 100755 index 00000000..1db4c9ad --- /dev/null +++ b/CPP/7zip/makefile @@ -0,0 +1,16 @@ +DIRS = \ + Compress\~ \ + Crypto\~ \ + Archive\~ \ + UI\~ \ + Bundles\~ \ + +all: $(DIRS) FileManager\~ + +$(DIRS): + cd $(@D) + $(MAKE) -nologo + cd .. + +FileManager\~: +!include "SubBuild.mak" diff --git a/CPP/Build.mak b/CPP/Build.mak new file mode 100755 index 00000000..4f25c853 --- /dev/null +++ b/CPP/Build.mak @@ -0,0 +1,62 @@ +!IFDEF CPU +LIBS = $(LIBS) bufferoverflowU.lib +CFLAGS = $(CFLAGS) -GS- -Zc:forScope +!ENDIF + +!IFNDEF O +!IFDEF CPU +O=$(CPU) +!ELSE +O=O +!ENDIF +!ENDIF + +CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -EHsc -Gz -WX +!IFDEF MY_STATIC_LINK +!IFNDEF MY_SINGLE_THREAD +CFLAGS = $(CFLAGS) -MT +!ENDIF +!ELSE +CFLAGS = $(CFLAGS) -MD +!ENDIF + +!IFDEF NEW_COMPILER +CFLAGS_O1 = $(CFLAGS) -O1 -W4 -Wp64 +CFLAGS_O2 = $(CFLAGS) -O2 -W4 -Wp64 +!ELSE +CFLAGS_O1 = $(CFLAGS) -O1 -W3 +CFLAGS_O2 = $(CFLAGS) -O2 -W3 +!ENDIF + +CFLAGS_O1_W3 = $(CFLAGS) -O1 -W3 +CFLAGS_O2_W3 = $(CFLAGS) -O2 -W3 + +LFLAGS = $(LFLAGS) -nologo -OPT:NOWIN98 + +!IFDEF DEF_FILE +LFLAGS = $(LFLAGS) -DLL -DEF:$(DEF_FILE) +!ENDIF + +PROGPATH = $O\$(PROG) + +COMPL_O1 = $(CPP) $(CFLAGS_O1) $** +COMPL_O2 = $(CPP) $(CFLAGS_O2) $** +COMPL_O1_W3 = $(CPP) $(CFLAGS_O1_W3) $** +COMPL_O2_W3 = $(CPP) $(CFLAGS_O2_W3) $** +COMPL_PCH = $(CPP) $(CFLAGS_O1) -Yc"StdAfx.h" -Fp$O/a.pch $** +COMPL = $(CPP) $(CFLAGS_O1) -Yu"StdAfx.h" -Fp$O/a.pch $** + +all: $(PROGPATH) + +clean: + -del /Q $(PROGPATH) $O\*.exe $O\*.dll $O\*.obj $O\*.lib $O\*.exp $O\*.res $O\*.pch + +$O: + if not exist "$O" mkdir "$O" + +$(PROGPATH): $O $(OBJS) $(DEF_FILE) + link $(LFLAGS) -out:$(PROGPATH) $(OBJS) $(LIBS) +$O\resource.res: $(*B).rc + rc -fo$@ $** +$O\StdAfx.obj: $(*B).cpp + $(COMPL_PCH) diff --git a/CPP/Common/AlignedBuffer.cpp b/CPP/Common/AlignedBuffer.cpp new file mode 100755 index 00000000..ec472ced --- /dev/null +++ b/CPP/Common/AlignedBuffer.cpp @@ -0,0 +1,22 @@ +// AlignedBuffer.cpp + +#include "StdAfx.h" + +#include "AlignedBuffer.h" + +void *CAlignedBuffer::Allocate(size_t size, size_t mask) +{ + Free(); + m_Buffer = new unsigned char[size + mask]; + unsigned char *p = m_Buffer; + while(((size_t)p & mask) != 0) + p++; + return (void *)p; +} + +void CAlignedBuffer::Free() +{ + if (m_Buffer != 0) + delete []m_Buffer; + m_Buffer = 0; +} diff --git a/CPP/Common/AlignedBuffer.h b/CPP/Common/AlignedBuffer.h new file mode 100755 index 00000000..d040463e --- /dev/null +++ b/CPP/Common/AlignedBuffer.h @@ -0,0 +1,18 @@ +// Common/AlignedBuffer.h + +#ifndef __COMMON_ALIGNEDBUFFER_H +#define __COMMON_ALIGNEDBUFFER_H + +#include + +class CAlignedBuffer +{ + unsigned char *m_Buffer; +public: + CAlignedBuffer(): m_Buffer(0) {}; + ~CAlignedBuffer() { Free(); } + void *Allocate(size_t size, size_t mask); + void Free(); +}; + +#endif diff --git a/CPP/Common/Alloc.cpp b/CPP/Common/Alloc.cpp new file mode 100755 index 00000000..e4fc6a81 --- /dev/null +++ b/CPP/Common/Alloc.cpp @@ -0,0 +1,133 @@ +// Common/Alloc.cpp + +#include "StdAfx.h" + +#ifdef _WIN32 +#include "MyWindows.h" +#else +#include +#endif + +#include "Alloc.h" + +/* #define _SZ_ALLOC_DEBUG */ +/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */ +#ifdef _SZ_ALLOC_DEBUG +#include +int g_allocCount = 0; +int g_allocCountMid = 0; +int g_allocCountBig = 0; +#endif + +void *MyAlloc(size_t size) throw() +{ + if (size == 0) + return 0; + #ifdef _SZ_ALLOC_DEBUG + fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount++); + #endif + return ::malloc(size); +} + +void MyFree(void *address) throw() +{ + #ifdef _SZ_ALLOC_DEBUG + if (address != 0) + fprintf(stderr, "\nFree; count = %10d", --g_allocCount); + #endif + + ::free(address); +} + +#ifdef _WIN32 + +void *MidAlloc(size_t size) throw() +{ + if (size == 0) + return 0; + #ifdef _SZ_ALLOC_DEBUG + fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++); + #endif + return ::VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE); +} + +void MidFree(void *address) throw() +{ + #ifdef _SZ_ALLOC_DEBUG + if (address != 0) + fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid); + #endif + if (address == 0) + return; + ::VirtualFree(address, 0, MEM_RELEASE); +} + + +#ifndef MEM_LARGE_PAGES +#define _7ZIP_NO_LARGE_PAGES +#endif + +// define _7ZIP_NO_LARGE_PAGES if you don't need LARGE_PAGES support +// #define _7ZIP_NO_LARGE_PAGES + + +#ifndef _7ZIP_NO_LARGE_PAGES +static SIZE_T g_LargePageSize = + #ifdef _WIN64 + (1 << 21); + #else + (1 << 22); + #endif + +typedef SIZE_T (WINAPI *GetLargePageMinimumP)(); +#endif + +bool SetLargePageSize() +{ + #ifndef _7ZIP_NO_LARGE_PAGES + GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP) + ::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum"); + if (largePageMinimum == 0) + return false; + SIZE_T size = largePageMinimum(); + if (size == 0 || (size & (size - 1)) != 0) + return false; + g_LargePageSize = size; + #endif + return true; +} + + +void *BigAlloc(size_t size) throw() +{ + if (size == 0) + return 0; + #ifdef _SZ_ALLOC_DEBUG + fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++); + #endif + + #ifndef _7ZIP_NO_LARGE_PAGES + if (size >= (1 << 18)) + { + void *res = ::VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)), + MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE); + if (res != 0) + return res; + } + #endif + return ::VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE); +} + +void BigFree(void *address) throw() +{ + #ifdef _SZ_ALLOC_DEBUG + if (address != 0) + fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig); + #endif + + if (address == 0) + return; + ::VirtualFree(address, 0, MEM_RELEASE); +} + +#endif diff --git a/CPP/Common/Alloc.h b/CPP/Common/Alloc.h new file mode 100755 index 00000000..d444f631 --- /dev/null +++ b/CPP/Common/Alloc.h @@ -0,0 +1,29 @@ +// Common/Alloc.h + +#ifndef __COMMON_ALLOC_H +#define __COMMON_ALLOC_H + +#include + +void *MyAlloc(size_t size) throw(); +void MyFree(void *address) throw(); + +#ifdef _WIN32 + +bool SetLargePageSize(); + +void *MidAlloc(size_t size) throw(); +void MidFree(void *address) throw(); +void *BigAlloc(size_t size) throw(); +void BigFree(void *address) throw(); + +#else + +#define MidAlloc(size) MyAlloc(size) +#define MidFree(address) MyFree(address) +#define BigAlloc(size) MyAlloc(size) +#define BigFree(address) MyFree(address) + +#endif + +#endif diff --git a/CPP/Common/AutoPtr.h b/CPP/Common/AutoPtr.h new file mode 100755 index 00000000..c5808cb0 --- /dev/null +++ b/CPP/Common/AutoPtr.h @@ -0,0 +1,35 @@ +// Common/AutoPtr.h + +#ifndef __COMMON_AUTOPTR_H +#define __COMMON_AUTOPTR_H + +template class CMyAutoPtr +{ + T *_p; +public: + CMyAutoPtr(T *p = 0) : _p(p) {} + CMyAutoPtr(CMyAutoPtr& p): _p(p.release()) {} + CMyAutoPtr& operator=(CMyAutoPtr& p) + { + reset(p.release()); + return (*this); + } + ~CMyAutoPtr() { delete _p; } + T& operator*() const { return *_p; } + // T* operator->() const { return (&**this); } + T* get() const { return _p; } + T* release() + { + T *tmp = _p; + _p = 0; + return tmp; + } + void reset(T* p = 0) + { + if (p != _p) + delete _p; + _p = p; + } +}; + +#endif diff --git a/CPP/Common/Buffer.h b/CPP/Common/Buffer.h new file mode 100755 index 00000000..0b8ac804 --- /dev/null +++ b/CPP/Common/Buffer.h @@ -0,0 +1,77 @@ +// Common/Buffer.h + +#ifndef __COMMON_BUFFER_H +#define __COMMON_BUFFER_H + +#include "Defs.h" + +template 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) + { + if (newCapacity == _capacity) + return; + T *newBuffer; + if (newCapacity > 0) + { + newBuffer = new T[newCapacity]; + if(_capacity > 0) + memmove(newBuffer, _items, MyMin(_capacity, newCapacity) * sizeof(T)); + } + else + newBuffer = 0; + 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 +bool operator==(const CBuffer& b1, const CBuffer& 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 +bool operator!=(const CBuffer& b1, const CBuffer& b2) +{ + return !(b1 == b2); +} + +typedef CBuffer CCharBuffer; +typedef CBuffer CWCharBuffer; +typedef CBuffer CByteBuffer; + +#endif diff --git a/CPP/Common/CRC.cpp b/CPP/Common/CRC.cpp new file mode 100755 index 00000000..35e1a187 --- /dev/null +++ b/CPP/Common/CRC.cpp @@ -0,0 +1,61 @@ +// Common/CRC.cpp + +#include "StdAfx.h" + +#include "CRC.h" + +static const UInt32 kCRCPoly = 0xEDB88320; + +UInt32 CCRC::Table[256]; + +void CCRC::InitTable() +{ + for (UInt32 i = 0; i < 256; i++) + { + UInt32 r = i; + for (int j = 0; j < 8; j++) + if (r & 1) + r = (r >> 1) ^ kCRCPoly; + else + r >>= 1; + CCRC::Table[i] = r; + } +} + +class CCRCTableInit +{ +public: + CCRCTableInit() { CCRC::InitTable(); } +} g_CRCTableInit; + +void CCRC::UpdateByte(Byte b) +{ + _value = Table[((Byte)(_value)) ^ b] ^ (_value >> 8); +} + +void CCRC::UpdateUInt16(UInt16 v) +{ + UpdateByte(Byte(v)); + UpdateByte(Byte(v >> 8)); +} + +void CCRC::UpdateUInt32(UInt32 v) +{ + for (int i = 0; i < 4; i++) + UpdateByte((Byte)(v >> (8 * i))); +} + +void CCRC::UpdateUInt64(UInt64 v) +{ + for (int i = 0; i < 8; i++) + UpdateByte((Byte)(v >> (8 * i))); +} + +void CCRC::Update(const void *data, size_t size) +{ + UInt32 v = _value; + const Byte *p = (const Byte *)data; + for (; size > 0 ; size--, p++) + v = Table[((Byte)(v)) ^ *p] ^ (v >> 8); + _value = v; +} diff --git a/CPP/Common/CRC.h b/CPP/Common/CRC.h new file mode 100755 index 00000000..277ae673 --- /dev/null +++ b/CPP/Common/CRC.h @@ -0,0 +1,36 @@ +// Common/CRC.h + +#ifndef __COMMON_CRC_H +#define __COMMON_CRC_H + +#include +#include "Types.h" + +class CCRC +{ + UInt32 _value; +public: + static UInt32 Table[256]; + static void InitTable(); + + CCRC(): _value(0xFFFFFFFF){}; + void Init() { _value = 0xFFFFFFFF; } + void UpdateByte(Byte v); + void UpdateUInt16(UInt16 v); + void UpdateUInt32(UInt32 v); + void UpdateUInt64(UInt64 v); + void Update(const void *data, size_t size); + UInt32 GetDigest() const { return _value ^ 0xFFFFFFFF; } + static UInt32 CalculateDigest(const void *data, size_t size) + { + CCRC crc; + crc.Update(data, size); + return crc.GetDigest(); + } + static bool VerifyDigest(UInt32 digest, const void *data, size_t size) + { + return (CalculateDigest(data, size) == digest); + } +}; + +#endif diff --git a/CPP/Common/C_FileIO.cpp b/CPP/Common/C_FileIO.cpp new file mode 100755 index 00000000..7d9e00d0 --- /dev/null +++ b/CPP/Common/C_FileIO.cpp @@ -0,0 +1,78 @@ +// Common/C_FileIO.h + +#include "C_FileIO.h" + +#include +#include + +namespace NC { +namespace NFile { +namespace NIO { + +bool CFileBase::OpenBinary(const char *name, int flags) +{ + #ifdef O_BINARY + flags |= O_BINARY; + #endif + Close(); + _handle = ::open(name, flags, 0666); + return _handle != -1; +} + +bool CFileBase::Close() +{ + if(_handle == -1) + return true; + if (close(_handle) != 0) + return false; + _handle = -1; + return true; +} + +bool CFileBase::GetLength(UInt64 &length) const +{ + off_t curPos = Seek(0, SEEK_CUR); + off_t lengthTemp = Seek(0, SEEK_END); + Seek(curPos, SEEK_SET); + length = (UInt64)lengthTemp; + return true; +} + +off_t CFileBase::Seek(off_t distanceToMove, int moveMethod) const +{ + return ::lseek(_handle, distanceToMove, moveMethod); +} + +///////////////////////// +// CInFile + +bool CInFile::Open(const char *name) +{ + return CFileBase::OpenBinary(name, O_RDONLY); +} + +ssize_t CInFile::Read(void *data, size_t size) +{ + return read(_handle, data, size); +} + +///////////////////////// +// COutFile + +bool COutFile::Create(const char *name, bool createAlways) +{ + if (createAlways) + { + Close(); + _handle = ::creat(name, 0666); + return _handle != -1; + } + return OpenBinary(name, O_CREAT | O_EXCL | O_WRONLY); +} + +ssize_t COutFile::Write(const void *data, size_t size) +{ + return write(_handle, data, size); +} + +}}} diff --git a/CPP/Common/C_FileIO.h b/CPP/Common/C_FileIO.h new file mode 100755 index 00000000..2ad07167 --- /dev/null +++ b/CPP/Common/C_FileIO.h @@ -0,0 +1,45 @@ +// Common/C_FileIO.h + +#ifndef __COMMON_C_FILEIO_H +#define __COMMON_C_FILEIO_H + +#include +#include + +#include "Types.h" +#include "MyWindows.h" + +namespace NC { +namespace NFile { +namespace NIO { + +class CFileBase +{ +protected: + int _handle; + bool OpenBinary(const char *name, int flags); +public: + CFileBase(): _handle(-1) {}; + ~CFileBase() { Close(); } + bool Close(); + bool GetLength(UInt64 &length) const; + off_t Seek(off_t distanceToMove, int moveMethod) const; +}; + +class CInFile: public CFileBase +{ +public: + bool Open(const char *name); + ssize_t Read(void *data, size_t size); +}; + +class COutFile: public CFileBase +{ +public: + bool Create(const char *name, bool createAlways); + ssize_t Write(const void *data, size_t size); +}; + +}}} + +#endif diff --git a/CPP/Common/ComTry.h b/CPP/Common/ComTry.h new file mode 100755 index 00000000..5153362f --- /dev/null +++ b/CPP/Common/ComTry.h @@ -0,0 +1,17 @@ +// ComTry.h + +#ifndef __COM_TRY_H +#define __COM_TRY_H + +#include "MyWindows.h" +// #include "Exception.h" +// #include "NewHandler.h" + +#define COM_TRY_BEGIN try { +#define COM_TRY_END } catch(...) { return E_OUTOFMEMORY; } + + // catch(const CNewException &) { return E_OUTOFMEMORY; }\ + // catch(const CSystemException &e) { return e.ErrorCode; }\ + // catch(...) { return E_FAIL; } + +#endif diff --git a/CPP/Common/CommandLineParser.cpp b/CPP/Common/CommandLineParser.cpp new file mode 100755 index 00000000..67f72675 --- /dev/null +++ b/CPP/Common/CommandLineParser.cpp @@ -0,0 +1,232 @@ +// 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(); + for (;;) + { + UString s1, s2; + SplitCommandLine(sTemp, s1, s2); + // s1.Trim(); + // s2.Trim(); + if (!s1.IsEmpty()) + parts.Add(s1); + if (s2.IsEmpty()) + break; + sTemp = s2; + } +} + + +static const wchar_t kSwitchID1 = '-'; +// static const wchar_t kSwitchID2 = '/'; + +static const wchar_t kSwitchMinus = '-'; +static const wchar_t *kStopSwitchParsing = L"--"; + +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(); + bool stopSwitch = false; + for (int i = 0; i < numCommandStrings; i++) + { + const UString &s = commandStrings[i]; + if (stopSwitch) + NonSwitchStrings.Add(s); + else + if (s == kStopSwitchParsing) + stopSwitch = true; + else + if (!ParseString(s, switchForms)) + NonSwitchStrings.Add(s); + } +} + +// 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 = 0; // GCC Warning + int maxLen = kNoLen; + for(int switchIndex = 0; switchIndex < _numSwitches; switchIndex++) + { + int switchLen = MyStringLen(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); + break; + } + case NSwitchType::kSimple: + break; + } + } + 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; +} + +} diff --git a/CPP/Common/CommandLineParser.h b/CPP/Common/CommandLineParser.h new file mode 100755 index 00000000..f59d8e4c --- /dev/null +++ b/CPP/Common/CommandLineParser.h @@ -0,0 +1,72 @@ +// Common/CommandLineParser.h + +#ifndef __COMMON_COMMANDLINEPARSER_H +#define __COMMON_COMMANDLINEPARSER_H + +#include "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); + +} + +#endif diff --git a/CPP/Common/Defs.h b/CPP/Common/Defs.h new file mode 100755 index 00000000..dad3ae8f --- /dev/null +++ b/CPP/Common/Defs.h @@ -0,0 +1,20 @@ +// Common/Defs.h + +#ifndef __COMMON_DEFS_H +#define __COMMON_DEFS_H + +template inline T MyMin(T a, T b) + { return a < b ? a : b; } +template inline T MyMax(T a, T b) + { return a > b ? a : b; } + +template inline int MyCompare(T a, T b) + { return a < b ? -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/CPP/Common/DynamicBuffer.h b/CPP/Common/DynamicBuffer.h new file mode 100755 index 00000000..1709657d --- /dev/null +++ b/CPP/Common/DynamicBuffer.h @@ -0,0 +1,47 @@ +// Common/DynamicBuffer.h + +#ifndef __COMMON_DYNAMICBUFFER_H +#define __COMMON_DYNAMICBUFFER_H + +#include "Buffer.h" + +template class CDynamicBuffer: public CBuffer +{ + void GrowLength(size_t size) + { + size_t delta; + if (this->_capacity > 64) + delta = this->_capacity / 4; + else if (this->_capacity > 8) + delta = 16; + else + delta = 4; + delta = MyMax(delta, size); + SetCapacity(this->_capacity + delta); + } +public: + CDynamicBuffer(): CBuffer() {}; + CDynamicBuffer(const CDynamicBuffer &buffer): CBuffer(buffer) {}; + CDynamicBuffer(size_t size): CBuffer(size) {}; + CDynamicBuffer& operator=(const CDynamicBuffer &buffer) + { + this->Free(); + if(buffer._capacity > 0) + { + SetCapacity(buffer._capacity); + memmove(this->_items, buffer._items, buffer._capacity * sizeof(T)); + } + return *this; + } + void EnsureCapacity(size_t capacity) + { + if (this->_capacity < capacity) + GrowLength(capacity - this->_capacity); + } +}; + +typedef CDynamicBuffer CCharDynamicBuffer; +typedef CDynamicBuffer CWCharDynamicBuffer; +typedef CDynamicBuffer CByteDynamicBuffer; + +#endif diff --git a/CPP/Common/Exception.h b/CPP/Common/Exception.h new file mode 100755 index 00000000..d7f86a90 --- /dev/null +++ b/CPP/Common/Exception.h @@ -0,0 +1,13 @@ +// Common/Exception.h + +#ifndef __COMMON_EXCEPTION_H +#define __COMMON_EXCEPTION_H + +struct CSystemException +{ + DWORD ErrorCode; + CSystemException(): ErrorCode(::GetLastError()) {} + CSystemException(DWORD errorCode): ErrorCode(errorCode) {} +}; + +#endif diff --git a/CPP/Common/IntToString.cpp b/CPP/Common/IntToString.cpp new file mode 100755 index 00000000..7d81d966 --- /dev/null +++ b/CPP/Common/IntToString.cpp @@ -0,0 +1,63 @@ +// Common/IntToString.cpp + +#include "StdAfx.h" + +#include "IntToString.h" + +void ConvertUInt64ToString(UInt64 value, char *s, UInt32 base) +{ + if (base < 2 || base > 36) + { + *s = L'\0'; + return; + } + char temp[72]; + int pos = 0; + do + { + int delta = (int)(value % base); + temp[pos++] = (char)((delta < 10) ? ('0' + delta) : ('a' + (delta - 10))); + value /= base; + } + while (value != 0); + do + *s++ = temp[--pos]; + while(pos > 0); + *s = '\0'; +} + +void ConvertUInt64ToString(UInt64 value, wchar_t *s) +{ + wchar_t temp[32]; + int pos = 0; + do + { + temp[pos++] = (wchar_t)(L'0' + (int)(value % 10)); + value /= 10; + } + while (value != 0); + do + *s++ = temp[--pos]; + while(pos > 0); + *s = L'\0'; +} + +void ConvertInt64ToString(Int64 value, char *s) +{ + if (value < 0) + { + *s++ = '-'; + value = -value; + } + ConvertUInt64ToString(value, s); +} + +void ConvertInt64ToString(Int64 value, wchar_t *s) +{ + if (value < 0) + { + *s++ = L'-'; + value = -value; + } + ConvertUInt64ToString(value, s); +} diff --git a/CPP/Common/IntToString.h b/CPP/Common/IntToString.h new file mode 100755 index 00000000..cf86090f --- /dev/null +++ b/CPP/Common/IntToString.h @@ -0,0 +1,15 @@ +// Common/IntToString.h + +#ifndef __COMMON_INTTOSTRING_H +#define __COMMON_INTTOSTRING_H + +#include +#include "Types.h" + +void ConvertUInt64ToString(UInt64 value, char *s, UInt32 base = 10); +void ConvertUInt64ToString(UInt64 value, wchar_t *s); + +void ConvertInt64ToString(Int64 value, char *s); +void ConvertInt64ToString(Int64 value, wchar_t *s); + +#endif diff --git a/CPP/Common/Lang.cpp b/CPP/Common/Lang.cpp new file mode 100755 index 00000000..f1861d6e --- /dev/null +++ b/CPP/Common/Lang.cpp @@ -0,0 +1,142 @@ +// 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 CompareLangItems(void *const *elem1, void *const *elem2, void *) +{ + 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 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); + } + _langPairs.Sort(CompareLangItems, NULL); + 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/CPP/Common/Lang.h b/CPP/Common/Lang.h new file mode 100755 index 00000000..2b4615d0 --- /dev/null +++ b/CPP/Common/Lang.h @@ -0,0 +1,28 @@ +// Common/Lang.h + +#ifndef __COMMON_LANG_H +#define __COMMON_LANG_H + +#include "Common/Vector.h" +#include "Common/String.h" +#include "Common/Types.h" + +struct CLangPair +{ + UInt32 Value; + UString String; +}; + +class CLang +{ + CObjectVector _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/CPP/Common/ListFileUtils.cpp b/CPP/Common/ListFileUtils.cpp new file mode 100755 index 00000000..ea4cde38 --- /dev/null +++ b/CPP/Common/ListFileUtils.cpp @@ -0,0 +1,60 @@ +// 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); + if (!u.IsEmpty()) + { + if (u[0] == 0xFEFF) + u.Delete(0); + } + + 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/CPP/Common/ListFileUtils.h b/CPP/Common/ListFileUtils.h new file mode 100755 index 00000000..93bb4507 --- /dev/null +++ b/CPP/Common/ListFileUtils.h @@ -0,0 +1,12 @@ +// Common/ListFileUtils.h + +#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/CPP/Common/MyCom.h b/CPP/Common/MyCom.h new file mode 100755 index 00000000..e9034930 --- /dev/null +++ b/CPP/Common/MyCom.h @@ -0,0 +1,203 @@ +// MyCom.h + +#ifndef __MYCOM_H +#define __MYCOM_H + +#include "MyWindows.h" + +#define RINOK(x) { HRESULT __result_ = (x); if(__result_ != S_OK) return __result_; } + +template +class CMyComPtr +{ + T* _p; +public: + // typedef T _PtrClass; + CMyComPtr() { _p = NULL;} + CMyComPtr(T* p) {if ((_p = p) != NULL) p->AddRef(); } + CMyComPtr(const CMyComPtr& 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& 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; + } + #ifdef _WIN32 + HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) + { + return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p); + } + #endif + /* + HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) + { + CLSID clsid; + HRESULT hr = CLSIDFromProgID(szProgID, &clsid); + ATLASSERT(_p == NULL); + if (SUCCEEDED(hr)) + hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&_p); + return hr; + } + */ + template + HRESULT QueryInterface(REFGUID iid, Q** pp) const + { + 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 STDMETHOD(QueryInterface)(REFGUID, void **) { \ + MY_QUERYINTERFACE_END \ + MY_ADDREF_RELEASE + +#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) \ + ) + +#define MY_UNKNOWN_IMP5(i1, i2, i3, i4, i5) MY_UNKNOWN_IMP_SPEC( \ + MY_QUERYINTERFACE_ENTRY(i1) \ + MY_QUERYINTERFACE_ENTRY(i2) \ + MY_QUERYINTERFACE_ENTRY(i3) \ + MY_QUERYINTERFACE_ENTRY(i4) \ + MY_QUERYINTERFACE_ENTRY(i5) \ + ) + +#endif diff --git a/CPP/Common/MyGuidDef.h b/CPP/Common/MyGuidDef.h new file mode 100755 index 00000000..2c954f81 --- /dev/null +++ b/CPP/Common/MyGuidDef.h @@ -0,0 +1,54 @@ +// Common/MyGuidDef.h + +#ifndef GUID_DEFINED +#define GUID_DEFINED + +#include "Types.h" + +typedef struct { + UInt32 Data1; + UInt16 Data2; + UInt16 Data3; + unsigned char Data4[8]; +} GUID; + +#ifdef __cplusplus +#define REFGUID const GUID & +#else +#define REFGUID const GUID * +#endif + +#define REFCLSID REFGUID +#define REFIID REFGUID + +#ifdef __cplusplus +inline bool operator==(REFGUID g1, REFGUID g2) +{ + for (int i = 0; i < (int)sizeof(g1); i++) + if (((unsigned char *)&g1)[i] != ((unsigned char *)&g2)[i]) + return false; + return true; +} +inline bool operator!=(REFGUID g1, REFGUID g2) { return !(g1 == g2); } +#endif + +#ifdef __cplusplus + #define MY_EXTERN_C extern "C" +#else + #define MY_EXTERN_C extern +#endif + +#endif // GUID_DEFINED + + +#ifdef DEFINE_GUID +#undef DEFINE_GUID +#endif + +#ifdef INITGUID + #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + MY_EXTERN_C const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } +#else + #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + MY_EXTERN_C const GUID name +#endif diff --git a/CPP/Common/MyInitGuid.h b/CPP/Common/MyInitGuid.h new file mode 100755 index 00000000..5bdfeed5 --- /dev/null +++ b/CPP/Common/MyInitGuid.h @@ -0,0 +1,13 @@ +// Common/MyInitGuid.h + +#ifndef __COMMON_MYINITGUID_H +#define __COMMON_MYINITGUID_H + +#ifdef _WIN32 +#include +#else +#define INITGUID +#include "MyGuidDef.h" +#endif + +#endif diff --git a/CPP/Common/MyUnknown.h b/CPP/Common/MyUnknown.h new file mode 100755 index 00000000..d28d8542 --- /dev/null +++ b/CPP/Common/MyUnknown.h @@ -0,0 +1,24 @@ +// MyUnknown.h + +#ifndef __MYUNKNOWN_H +#define __MYUNKNOWN_H + +#ifdef _WIN32 + +#ifdef _WIN32_WCE +#if (_WIN32_WCE > 300) +#include +#else +#define MIDL_INTERFACE(x) struct +#endif +#else +#include +#endif + +#include + +#else +#include "MyWindows.h" +#endif + +#endif diff --git a/CPP/Common/MyWindows.cpp b/CPP/Common/MyWindows.cpp new file mode 100755 index 00000000..4cf065cf --- /dev/null +++ b/CPP/Common/MyWindows.cpp @@ -0,0 +1,113 @@ +// MyWindows.cpp + +#include "StdAfx.h" + +#ifndef _WIN32 + +#include "MyWindows.h" +#include "Types.h" +#include + +static inline void *AllocateForBSTR(size_t cb) { return ::malloc(cb); } +static inline void FreeForBSTR(void *pv) { ::free(pv);} + +static UINT MyStringLen(const wchar_t *s) +{ + UINT i; + for (i = 0; s[i] != '\0'; i++); + return i; +} + +BSTR SysAllocStringByteLen(LPCSTR psz, UINT len) +{ + int realLen = len + sizeof(UINT) + sizeof(OLECHAR) + sizeof(OLECHAR); + void *p = AllocateForBSTR(realLen); + if (p == 0) + return 0; + *(UINT *)p = len; + BSTR bstr = (BSTR)((UINT *)p + 1); + memmove(bstr, psz, len); + Byte *pb = ((Byte *)bstr) + len; + for (int i = 0; i < sizeof(OLECHAR) * 2; i++) + pb[i] = 0; + return bstr; +} + +BSTR SysAllocString(const OLECHAR *sz) +{ + if (sz == 0) + return 0; + UINT strLen = MyStringLen(sz); + UINT len = (strLen + 1) * sizeof(OLECHAR); + void *p = AllocateForBSTR(len + sizeof(UINT)); + if (p == 0) + return 0; + *(UINT *)p = strLen; + BSTR bstr = (BSTR)((UINT *)p + 1); + memmove(bstr, sz, len); + return bstr; +} + +void SysFreeString(BSTR bstr) +{ + if (bstr != 0) + FreeForBSTR((UINT *)bstr - 1); +} + +UINT SysStringByteLen(BSTR bstr) +{ + if (bstr == 0) + return 0; + return *((UINT *)bstr - 1); +} + +UINT SysStringLen(BSTR bstr) +{ + return SysStringByteLen(bstr) / sizeof(OLECHAR); +} + +HRESULT VariantClear(VARIANTARG *prop) +{ + if (prop->vt == VT_BSTR) + SysFreeString(prop->bstrVal); + prop->vt = VT_EMPTY; + return S_OK; +} + +HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src) +{ + HRESULT res = ::VariantClear(dest); + if (res != S_OK) + return res; + if (src->vt == VT_BSTR) + { + dest->bstrVal = SysAllocStringByteLen((LPCSTR)src->bstrVal, + SysStringByteLen(src->bstrVal)); + if (dest->bstrVal == 0) + return E_OUTOFMEMORY; + dest->vt = VT_BSTR; + } + else + *dest = *src; + return S_OK; +} + +LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2) +{ + if(ft1->dwHighDateTime < ft2->dwHighDateTime) + return -1; + if(ft1->dwHighDateTime > ft2->dwHighDateTime) + return 1; + if(ft1->dwLowDateTime < ft2->dwLowDateTime) + return -1; + if(ft1->dwLowDateTime > ft2->dwLowDateTime) + return 1; + return 0; +} + +DWORD GetLastError() +{ + return 0; +} + +#endif diff --git a/CPP/Common/MyWindows.h b/CPP/Common/MyWindows.h new file mode 100755 index 00000000..a93d750a --- /dev/null +++ b/CPP/Common/MyWindows.h @@ -0,0 +1,203 @@ +// MyWindows.h + +#ifndef __MYWINDOWS_H +#define __MYWINDOWS_H + +#ifdef _WIN32 + +#include + +#define CHAR_PATH_SEPARATOR '\\' +#define WCHAR_PATH_SEPARATOR L'\\' +#define STRING_PATH_SEPARATOR "\\" +#define WSTRING_PATH_SEPARATOR L"\\" + +#else + +#define CHAR_PATH_SEPARATOR '/' +#define WCHAR_PATH_SEPARATOR L'/' +#define STRING_PATH_SEPARATOR "/" +#define WSTRING_PATH_SEPARATOR L"/" + +#include // for wchar_t +#include + +#include "MyGuidDef.h" + +typedef char CHAR; +typedef unsigned char UCHAR; + +#undef BYTE +typedef unsigned char BYTE; + +typedef short SHORT; +typedef unsigned short USHORT; + +#undef WORD +typedef unsigned short WORD; +typedef short VARIANT_BOOL; + +typedef int INT; +typedef Int32 INT32; +typedef unsigned int UINT; +typedef UInt32 UINT32; +typedef INT32 LONG; // LONG, ULONG and DWORD must be 32-bit +typedef UINT32 ULONG; + +#undef DWORD +typedef UINT32 DWORD; + +typedef Int64 LONGLONG; +typedef UInt64 ULONGLONG; + +typedef struct LARGE_INTEGER { LONGLONG QuadPart; }LARGE_INTEGER; +typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart;} ULARGE_INTEGER; + +typedef const CHAR *LPCSTR; +typedef CHAR TCHAR; +typedef const TCHAR *LPCTSTR; +typedef wchar_t WCHAR; +typedef WCHAR OLECHAR; +typedef const WCHAR *LPCWSTR; +typedef OLECHAR *BSTR; +typedef const OLECHAR *LPCOLESTR; +typedef OLECHAR *LPOLESTR; + +typedef struct _FILETIME +{ + DWORD dwLowDateTime; + DWORD dwHighDateTime; +}FILETIME; + +#define HRESULT LONG +#define FAILED(Status) ((HRESULT)(Status)<0) +typedef ULONG PROPID; +typedef LONG SCODE; + +#define S_OK ((HRESULT)0x00000000L) +#define S_FALSE ((HRESULT)0x00000001L) +#define E_NOTIMPL ((HRESULT)0x80004001L) +#define E_NOINTERFACE ((HRESULT)0x80004002L) +#define E_ABORT ((HRESULT)0x80004004L) +#define E_FAIL ((HRESULT)0x80004005L) +#define STG_E_INVALIDFUNCTION ((HRESULT)0x80030001L) +#define E_OUTOFMEMORY ((HRESULT)0x8007000EL) +#define E_INVALIDARG ((HRESULT)0x80070057L) + +#ifdef _MSC_VER +#define STDMETHODCALLTYPE __stdcall +#else +#define STDMETHODCALLTYPE +#endif + +#define STDMETHOD_(t, f) virtual t STDMETHODCALLTYPE f +#define STDMETHOD(f) STDMETHOD_(HRESULT, f) +#define STDMETHODIMP_(type) type STDMETHODCALLTYPE +#define STDMETHODIMP STDMETHODIMP_(HRESULT) + +#define PURE = 0 + +#define MIDL_INTERFACE(x) struct + +struct IUnknown +{ + STDMETHOD(QueryInterface) (REFIID iid, void **outObject) PURE; + STDMETHOD_(ULONG, AddRef)() PURE; + STDMETHOD_(ULONG, Release)() PURE; + #ifndef _WIN32 + virtual ~IUnknown() {} + #endif +}; + +typedef IUnknown *LPUNKNOWN; + +#define VARIANT_TRUE ((VARIANT_BOOL)-1) +#define VARIANT_FALSE ((VARIANT_BOOL)0) + +enum VARENUM +{ + VT_EMPTY = 0, + VT_NULL = 1, + VT_I2 = 2, + VT_I4 = 3, + VT_R4 = 4, + VT_R8 = 5, + VT_CY = 6, + VT_DATE = 7, + VT_BSTR = 8, + VT_DISPATCH = 9, + VT_ERROR = 10, + VT_BOOL = 11, + VT_VARIANT = 12, + VT_UNKNOWN = 13, + VT_DECIMAL = 14, + VT_I1 = 16, + VT_UI1 = 17, + VT_UI2 = 18, + VT_UI4 = 19, + VT_I8 = 20, + VT_UI8 = 21, + VT_INT = 22, + VT_UINT = 23, + VT_VOID = 24, + VT_HRESULT = 25, + VT_FILETIME = 64 +}; + +typedef unsigned short VARTYPE; +typedef WORD PROPVAR_PAD1; +typedef WORD PROPVAR_PAD2; +typedef WORD PROPVAR_PAD3; + +typedef struct tagPROPVARIANT +{ + VARTYPE vt; + PROPVAR_PAD1 wReserved1; + PROPVAR_PAD2 wReserved2; + PROPVAR_PAD3 wReserved3; + union + { + CHAR cVal; + UCHAR bVal; + SHORT iVal; + USHORT uiVal; + LONG lVal; + ULONG ulVal; + INT intVal; + UINT uintVal; + LARGE_INTEGER hVal; + ULARGE_INTEGER uhVal; + VARIANT_BOOL boolVal; + SCODE scode; + FILETIME filetime; + BSTR bstrVal; + }; +} PROPVARIANT; + +typedef PROPVARIANT tagVARIANT; +typedef tagVARIANT VARIANT; +typedef VARIANT VARIANTARG; + +MY_EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len); +MY_EXTERN_C BSTR SysAllocString(const OLECHAR *sz); +MY_EXTERN_C void SysFreeString(BSTR bstr); +MY_EXTERN_C UINT SysStringByteLen(BSTR bstr); +MY_EXTERN_C UINT SysStringLen(BSTR bstr); + +MY_EXTERN_C DWORD GetLastError(); +MY_EXTERN_C HRESULT VariantClear(VARIANTARG *prop); +MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src); +MY_EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2); + +#define CP_ACP 0 +#define CP_OEMCP 1 + +typedef enum tagSTREAM_SEEK +{ + STREAM_SEEK_SET = 0, + STREAM_SEEK_CUR = 1, + STREAM_SEEK_END = 2 +} STREAM_SEEK; + +#endif +#endif diff --git a/CPP/Common/NewHandler.cpp b/CPP/Common/NewHandler.cpp new file mode 100755 index 00000000..094eb642 --- /dev/null +++ b/CPP/Common/NewHandler.cpp @@ -0,0 +1,116 @@ +// NewHandler.cpp + +#include "StdAfx.h" + +#include + +#include "NewHandler.h" + +// #define DEBUG_MEMORY_LEAK + +#ifndef DEBUG_MEMORY_LEAK + +#ifdef _WIN32 +void * +#ifdef _MSC_VER +__cdecl +#endif +operator new(size_t size) +{ + // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size); + void *p = ::malloc(size); + if (p == 0) + throw CNewException(); + return p; +} + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete(void *p) throw() +{ + /* + if (p == 0) + return; + ::HeapFree(::GetProcessHeap(), 0, p); + */ + ::free(p); +} +#endif + +#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/CPP/Common/NewHandler.h b/CPP/Common/NewHandler.h new file mode 100755 index 00000000..0619fc69 --- /dev/null +++ b/CPP/Common/NewHandler.h @@ -0,0 +1,16 @@ +// Common/NewHandler.h + +#ifndef __COMMON_NEWHANDLER_H +#define __COMMON_NEWHANDLER_H + +class CNewException {}; + +#ifdef _WIN32 +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete(void *p) throw(); +#endif + +#endif diff --git a/CPP/Common/Random.cpp b/CPP/Common/Random.cpp new file mode 100755 index 00000000..f4a629c2 --- /dev/null +++ b/CPP/Common/Random.cpp @@ -0,0 +1,17 @@ +// Common/Random.cpp + +#include "StdAfx.h" + +#include +#include + +#include "Common/Random.h" + +void CRandom::Init(unsigned int seed) + { srand(seed); } + +void CRandom::Init() + { Init((unsigned int)time(NULL)); } + +int CRandom::Generate() const + { return rand(); } diff --git a/CPP/Common/Random.h b/CPP/Common/Random.h new file mode 100755 index 00000000..ffef20d1 --- /dev/null +++ b/CPP/Common/Random.h @@ -0,0 +1,16 @@ +// Common/Random.h + +#ifndef __COMMON_RANDOM_H +#define __COMMON_RANDOM_H + +class CRandom +{ +public: + void Init(); + void Init(unsigned int seed); + int Generate() const; +}; + +#endif + + diff --git a/CPP/Common/StdAfx.h b/CPP/Common/StdAfx.h new file mode 100755 index 00000000..681ee935 --- /dev/null +++ b/CPP/Common/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +// #include "MyWindows.h" +#include "NewHandler.h" + +#endif diff --git a/CPP/Common/StdInStream.cpp b/CPP/Common/StdInStream.cpp new file mode 100755 index 00000000..923f366e --- /dev/null +++ b/CPP/Common/StdInStream.cpp @@ -0,0 +1,84 @@ +// Common/StdInStream.cpp + +#include "StdAfx.h" + +#include +#include "StdInStream.h" + +#ifdef _MSC_VER +// "was declared deprecated" disabling +#pragma warning(disable : 4996 ) +#endif + +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 s; + for (;;) + { + int intChar = GetChar(); + if(intChar == EOF) + throw kEOFMessage; + char c = char(intChar); + if (c == kIllegalChar) + throw kIllegalCharMessage; + if(c == kNewLineChar) + break; + s += c; + } + return s; +} + +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/CPP/Common/StdInStream.h b/CPP/Common/StdInStream.h new file mode 100755 index 00000000..c1a0a222 --- /dev/null +++ b/CPP/Common/StdInStream.h @@ -0,0 +1,31 @@ +// Common/StdInStream.h + +#ifndef __COMMON_STDINSTREAM_H +#define __COMMON_STDINSTREAM_H + +#include + +#include "Common/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/CPP/Common/StdOutStream.cpp b/CPP/Common/StdOutStream.cpp new file mode 100755 index 00000000..5f1ef0fc --- /dev/null +++ b/CPP/Common/StdOutStream.cpp @@ -0,0 +1,93 @@ +// Common/StdOutStream.cpp + +#include "StdAfx.h" + +#include + +#include "StdOutStream.h" +#include "Common/IntToString.h" +#include "Common/StringConvert.h" + +#ifdef _MSC_VER +// "was declared deprecated" disabling +#pragma warning(disable : 4996 ) +#endif + +static const char kNewLineChar = '\n'; + +static const char *kFileOpenMode = "wt"; + +CStdOutStream g_StdOut(stdout); +CStdOutStream g_StdErr(stderr); + +bool CStdOutStream::Open(const char *fileName) +{ + Close(); + _stream = fopen(fileName, kFileOpenMode); + _streamIsOpen = (_stream != 0); + return _streamIsOpen; +} + +bool CStdOutStream::Close() +{ + if(!_streamIsOpen) + return true; + if (fclose(_stream) != 0) + return false; + _stream = 0; + _streamIsOpen = false; + return true; +} + +bool CStdOutStream::Flush() +{ + return (fflush(_stream) == 0); +} + +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[32]; + ConvertInt64ToString(number, textString); + return operator<<(textString); +} + +CStdOutStream & CStdOutStream::operator<<(UInt64 number) +{ + char textString[32]; + ConvertUInt64ToString(number, textString); + return operator<<(textString); +} diff --git a/CPP/Common/StdOutStream.h b/CPP/Common/StdOutStream.h new file mode 100755 index 00000000..a3b11979 --- /dev/null +++ b/CPP/Common/StdOutStream.h @@ -0,0 +1,35 @@ +// Common/StdOutStream.h + +#ifndef __COMMON_STDOUTSTREAM_H +#define __COMMON_STDOUTSTREAM_H + +#include + +#include "Types.h" + +class CStdOutStream +{ + bool _streamIsOpen; + FILE *_stream; +public: + CStdOutStream (): _streamIsOpen(false), _stream(0) {}; + CStdOutStream (FILE *stream): _streamIsOpen(false), _stream(stream) {}; + ~CStdOutStream (); + bool Open(const char *fileName); + bool Close(); + bool Flush(); + + 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/CPP/Common/String.cpp b/CPP/Common/String.cpp new file mode 100755 index 00000000..34da1487 --- /dev/null +++ b/CPP/Common/String.cpp @@ -0,0 +1,198 @@ +// Common/String.cpp + +#include "StdAfx.h" + +#ifdef _WIN32 +#include "StringConvert.h" +#else +#include +#endif + +#include "String.h" + + +#ifdef _WIN32 + +#ifndef _UNICODE + +wchar_t MyCharUpper(wchar_t c) +{ + if (c == 0) + return 0; + wchar_t *res = CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c); + if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return (wchar_t)(unsigned int)(UINT_PTR)res; + const int kBufferSize = 4; + char s[kBufferSize + 1]; + int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0); + if (numChars == 0 || numChars > kBufferSize) + return c; + s[numChars] = 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)(UINT_PTR)(unsigned int)c); + if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return (wchar_t)(unsigned int)(UINT_PTR)res; + const int kBufferSize = 4; + char s[kBufferSize + 1]; + int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0); + if (numChars == 0 || numChars > kBufferSize) + return c; + s[numChars] = 0; + ::CharLowerA(s); + ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1); + return c; +} + +wchar_t * MyStringUpper(wchar_t *s) +{ + if (s == 0) + return 0; + wchar_t *res = CharUpperW(s); + if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return res; + AString a = UnicodeStringToMultiByte(s); + a.MakeUpper(); + 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)); +} + +#endif + +/* +inline int ConvertCompareResult(int r) { return r - 2; } + +int MyStringCollate(const wchar_t *s1, const wchar_t *s2) +{ + int res = CompareStringW( + LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1); + #ifdef _UNICODE + return ConvertCompareResult(res); + #else + if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return ConvertCompareResult(res); + return MyStringCollate(UnicodeStringToMultiByte(s1), + UnicodeStringToMultiByte(s2)); + #endif +} + +#ifndef _WIN32_WCE +int MyStringCollate(const char *s1, const char *s2) +{ + return ConvertCompareResult(CompareStringA( + LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1)); +} + +int MyStringCollateNoCase(const char *s1, const char *s2) +{ + return ConvertCompareResult(CompareStringA( + LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1)); +} +#endif + +int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2) +{ + int res = CompareStringW( + LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1); + #ifdef _UNICODE + return ConvertCompareResult(res); + #else + if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return ConvertCompareResult(res); + return MyStringCollateNoCase(UnicodeStringToMultiByte(s1), + UnicodeStringToMultiByte(s2)); + #endif +} +*/ + +#else + +wchar_t MyCharUpper(wchar_t c) +{ + return toupper(c); +} + +/* +int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2) +{ + for (;;) + { + wchar_t c1 = *s1++; + wchar_t c2 = *s2++; + wchar_t u1 = MyCharUpper(c1); + wchar_t u2 = MyCharUpper(c2); + + if (u1 < u2) return -1; + if (u1 > u2) return 1; + if (u1 == 0) return 0; + } +} +*/ + +#endif + +int MyStringCompare(const char *s1, const char *s2) +{ + for (;;) + { + unsigned char c1 = (unsigned char)*s1++; + unsigned char c2 = (unsigned char)*s2++; + if (c1 < c2) return -1; + if (c1 > c2) return 1; + if (c1 == 0) return 0; + } +} + +int MyStringCompare(const wchar_t *s1, const wchar_t *s2) +{ + for (;;) + { + wchar_t c1 = *s1++; + wchar_t c2 = *s2++; + if (c1 < c2) return -1; + if (c1 > c2) return 1; + if (c1 == 0) return 0; + } +} + +int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) +{ + for (;;) + { + wchar_t c1 = *s1++; + wchar_t c2 = *s2++; + if (c1 != c2) + { + wchar_t u1 = MyCharUpper(c1); + wchar_t u2 = MyCharUpper(c2); + if (u1 < u2) return -1; + if (u1 > u2) return 1; + } + if (c1 == 0) return 0; + } +} + +#ifdef _WIN32 +int MyStringCompareNoCase(const char *s1, const char *s2) +{ + return MyStringCompareNoCase(MultiByteToUnicodeString(s1), MultiByteToUnicodeString(s2)); +} +#endif diff --git a/CPP/Common/String.h b/CPP/Common/String.h new file mode 100755 index 00000000..cbc6ee26 --- /dev/null +++ b/CPP/Common/String.h @@ -0,0 +1,631 @@ +// Common/String.h + +#ifndef __COMMON_STRING_H +#define __COMMON_STRING_H + +#include +// #include + +#include "Vector.h" + +#ifdef _WIN32 +#include "MyWindows.h" +#endif + +static const char *kTrimDefaultCharSet = " \n\t"; + +template +inline int MyStringLen(const T *s) +{ + int i; + for (i = 0; s[i] != '\0'; i++); + return i; +} + +template +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 *, wchar_t *p) + { return (p - 1); } +inline const wchar_t* MyStringGetPrevCharPointer(const wchar_t *, 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)(unsigned int)(UINT_PTR)CharUpperA((LPSTR)(UINT_PTR)(unsigned int)(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)(unsigned int)(UINT_PTR)CharLowerA((LPSTR)(UINT_PTR)(unsigned int)(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 + +#else // Standard-C +wchar_t MyCharUpper(wchar_t c); +#endif + +////////////////////////////////////// +// Compare + +/* +#ifndef _WIN32_WCE +int MyStringCollate(const char *s1, const char *s2); +int MyStringCollateNoCase(const char *s1, const char *s2); +#endif +int MyStringCollate(const wchar_t *s1, const wchar_t *s2); +int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2); +*/ + +int MyStringCompare(const char *s1, const char *s2); +int MyStringCompare(const wchar_t *s1, const wchar_t *s2); + +#ifdef _WIN32 +int MyStringCompareNoCase(const char *s1, const char *s2); +#endif + +int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2); + +template +class CStringBase +{ + void TrimLeftWithCharSet(const CStringBase &charSet) + { + const T *p = _chars; + while (charSet.Find(*p) >= 0 && (*p != 0)) + p = GetNextCharPointer(p); + Delete(0, (int)(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 = (int)(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 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; + for (;;) + { + if (*p == c) + return (int)(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; + for (;;) + { + if (*p == c) + return (int)(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); + } + private: + CStringBase GetTrimDefaultCharSet() + { + CStringBase charSet; + for(int i = 0; i < (int)(sizeof(kTrimDefaultCharSet) / + sizeof(kTrimDefaultCharSet[0])); i++) + charSet += (T)kTrimDefaultCharSet[i]; + return charSet; + } + public: + + void TrimLeft() + { + TrimLeftWithCharSet(GetTrimDefaultCharSet()); + } + void TrimRight() + { + TrimRightWithCharSet(GetTrimDefaultCharSet()); + } + 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 +CStringBase operator+(const CStringBase& s1, const CStringBase& s2) +{ + CStringBase result(s1); + result += s2; + return result; +} + +template +CStringBase operator+(const CStringBase& s, T c) +{ + CStringBase result(s); + result += c; + return result; +} + +template +CStringBase operator+(T c, const CStringBase& s) +{ + CStringBase result(c); + result += s; + return result; +} + +template +CStringBase operator+(const CStringBase& s, const T * chars) +{ + CStringBase result(s); + result += chars; + return result; +} + +template +CStringBase operator+(const T * chars, const CStringBase& s) +{ + CStringBase result(chars); + result += s; + return result; +} + +template +bool operator==(const CStringBase& s1, const CStringBase& s2) + { return (s1.Compare(s2) == 0); } + +template +bool operator<(const CStringBase& s1, const CStringBase& s2) + { return (s1.Compare(s2) < 0); } + +template +bool operator==(const T *s1, const CStringBase& s2) + { return (s2.Compare(s1) == 0); } + +template +bool operator==(const CStringBase& s1, const T *s2) + { return (s1.Compare(s2) == 0); } + +template +bool operator!=(const CStringBase& s1, const CStringBase& s2) + { return (s1.Compare(s2) != 0); } + +template +bool operator!=(const T *s1, const CStringBase& s2) + { return (s2.Compare(s1) != 0); } + +template +bool operator!=(const CStringBase& s1, const T *s2) + { return (s1.Compare(s2) != 0); } + +typedef CStringBase AString; +typedef CStringBase UString; + +typedef CObjectVector AStringVector; +typedef CObjectVector UStringVector; + +#ifdef _UNICODE + typedef UString CSysString; +#else + typedef AString CSysString; +#endif + +typedef CObjectVector CSysStringVector; + +#endif diff --git a/CPP/Common/StringConvert.cpp b/CPP/Common/StringConvert.cpp new file mode 100755 index 00000000..c0b19e16 --- /dev/null +++ b/CPP/Common/StringConvert.cpp @@ -0,0 +1,94 @@ +// Common/StringConvert.cpp + +#include "StdAfx.h" + +#include "StringConvert.h" + +#ifndef _WIN32 +#include +#endif + +#ifdef _WIN32 +UString MultiByteToUnicodeString(const AString &srcString, UINT codePage) +{ + UString resultString; + if(!srcString.IsEmpty()) + { + int numChars = MultiByteToWideChar(codePage, 0, srcString, + srcString.Length(), resultString.GetBuffer(srcString.Length()), + srcString.Length() + 1); + #ifndef _WIN32_WCE + if(numChars == 0) + throw 282228; + #endif + resultString.ReleaseBuffer(numChars); + } + return resultString; +} + +AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage) +{ + AString resultString; + if(!srcString.IsEmpty()) + { + int numRequiredBytes = srcString.Length() * 2; + char defaultChar = '_'; + int numChars = WideCharToMultiByte(codePage, 0, srcString, + srcString.Length(), resultString.GetBuffer(numRequiredBytes), + numRequiredBytes + 1, &defaultChar, NULL); + #ifndef _WIN32_WCE + if(numChars == 0) + throw 282229; + #endif + resultString.ReleaseBuffer(numChars); + } + return resultString; +} + +#ifndef _WIN32_WCE +AString SystemStringToOemString(const CSysString &srcString) +{ + AString result; + CharToOem(srcString, result.GetBuffer(srcString.Length() * 2)); + result.ReleaseBuffer(); + return result; +} +#endif + +#else + +UString MultiByteToUnicodeString(const AString &srcString, UINT codePage) +{ + UString resultString; + for (int i = 0; i < srcString.Length(); i++) + resultString += wchar_t(srcString[i]); + /* + if(!srcString.IsEmpty()) + { + int numChars = mbstowcs(resultString.GetBuffer(srcString.Length()), srcString, srcString.Length() + 1); + if (numChars < 0) throw "Your environment does not support UNICODE"; + resultString.ReleaseBuffer(numChars); + } + */ + return resultString; +} + +AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage) +{ + AString resultString; + for (int i = 0; i < srcString.Length(); i++) + resultString += char(srcString[i]); + /* + if(!srcString.IsEmpty()) + { + int numRequiredBytes = srcString.Length() * 6 + 1; + int numChars = wcstombs(resultString.GetBuffer(numRequiredBytes), srcString, numRequiredBytes); + if (numChars < 0) throw "Your environment does not support UNICODE"; + resultString.ReleaseBuffer(numChars); + } + */ + return resultString; +} + +#endif + diff --git a/CPP/Common/StringConvert.h b/CPP/Common/StringConvert.h new file mode 100755 index 00000000..84eaed9a --- /dev/null +++ b/CPP/Common/StringConvert.h @@ -0,0 +1,71 @@ +// Common/StringConvert.h + +#ifndef __COMMON_STRINGCONVERT_H +#define __COMMON_STRINGCONVERT_H + +#include "MyWindows.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) + { return unicodeString; } +inline const UString& GetUnicodeString(const UString &unicodeString, UINT) + { return unicodeString; } + +inline const char* GetAnsiString(const char* ansiString) + { return ansiString; } +inline const AString& GetAnsiString(const AString &ansiString) + { return ansiString; } +inline AString GetAnsiString(const UString &unicodeString) + { return UnicodeStringToMultiByte(unicodeString); } + +inline const char* GetOemString(const char* oemString) + { return oemString; } +inline const AString& GetOemString(const AString &oemString) + { return oemString; } +inline AString GetOemString(const UString &unicodeString) + { return UnicodeStringToMultiByte(unicodeString, CP_OEMCP); } + + +#ifdef _UNICODE + inline const wchar_t* GetSystemString(const wchar_t* unicodeString) + { return unicodeString;} + inline const UString& GetSystemString(const UString &unicodeString) + { return unicodeString;} + inline const wchar_t* GetSystemString(const wchar_t* unicodeString, UINT /* codePage */) + { return unicodeString;} + inline const UString& GetSystemString(const UString &unicodeString, UINT /* codePage */) + { return unicodeString;} + inline UString GetSystemString(const AString &multiByteString, UINT codePage) + { return MultiByteToUnicodeString(multiByteString, codePage);} + inline UString GetSystemString(const AString &multiByteString) + { return MultiByteToUnicodeString(multiByteString);} +#else + inline const char* GetSystemString(const char *ansiString) + { return ansiString; } + inline const AString& GetSystemString(const AString &multiByteString, UINT) + { return multiByteString; } + inline const char * GetSystemString(const char *multiByteString, UINT) + { return multiByteString; } + inline AString GetSystemString(const UString &unicodeString) + { return UnicodeStringToMultiByte(unicodeString); } + inline AString GetSystemString(const UString &unicodeString, UINT codePage) + { return UnicodeStringToMultiByte(unicodeString, codePage); } +#endif + +#ifndef _WIN32_WCE +AString SystemStringToOemString(const CSysString &srcString); +#endif + +#endif diff --git a/CPP/Common/StringToInt.cpp b/CPP/Common/StringToInt.cpp new file mode 100755 index 00000000..ec6733e3 --- /dev/null +++ b/CPP/Common/StringToInt.cpp @@ -0,0 +1,68 @@ +// Common/StringToInt.cpp + +#include "StdAfx.h" + +#include "StringToInt.h" + +UInt64 ConvertStringToUInt64(const char *s, const char **end) +{ + UInt64 result = 0; + for (;;) + { + char c = *s; + if (c < '0' || c > '9') + { + if (end != NULL) + *end = s; + return result; + } + result *= 10; + result += (c - '0'); + s++; + } +} + +UInt64 ConvertOctStringToUInt64(const char *s, const char **end) +{ + UInt64 result = 0; + for (;;) + { + char c = *s; + if (c < '0' || c > '7') + { + if (end != NULL) + *end = s; + return result; + } + result <<= 3; + result += (c - '0'); + s++; + } +} + + +UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end) +{ + UInt64 result = 0; + for (;;) + { + 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) +{ + if (*s == '-') + return -(Int64)ConvertStringToUInt64(s + 1, end); + return ConvertStringToUInt64(s, end); +} diff --git a/CPP/Common/StringToInt.h b/CPP/Common/StringToInt.h new file mode 100755 index 00000000..bb971f62 --- /dev/null +++ b/CPP/Common/StringToInt.h @@ -0,0 +1,17 @@ +// Common/StringToInt.h + +#ifndef __COMMON_STRINGTOINT_H +#define __COMMON_STRINGTOINT_H + +#include +#include "Types.h" + +UInt64 ConvertStringToUInt64(const char *s, const char **end); +UInt64 ConvertOctStringToUInt64(const char *s, const char **end); +UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end); + +Int64 ConvertStringToInt64(const char *s, const char **end); + +#endif + + diff --git a/CPP/Common/TextConfig.cpp b/CPP/Common/TextConfig.cpp new file mode 100755 index 00000000..4fce320a --- /dev/null +++ b/CPP/Common/TextConfig.cpp @@ -0,0 +1,138 @@ +// 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; ; finishPos++) + { + char c = string[finishPos]; + if (IsDelimitChar(c) || c == '=') + break; + result += c; + } + return result; +} + +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 &pairs) +{ + pairs.Clear(); + int pos = 0; + + ///////////////////// + // read strings + + for (;;) + { + 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; + for (;;) + { + 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 FindTextConfigItem(const CObjectVector &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 &pairs, const UString &id) +{ + int index = FindTextConfigItem(pairs, id); + if (index < 0) + return UString(); + return pairs[index].String; +} diff --git a/CPP/Common/TextConfig.h b/CPP/Common/TextConfig.h new file mode 100755 index 00000000..1552df65 --- /dev/null +++ b/CPP/Common/TextConfig.h @@ -0,0 +1,22 @@ +// Common/TextConfig.h + +#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 &pairs); + +int FindTextConfigItem(const CObjectVector &pairs, const UString &id); +UString GetTextConfigValue(const CObjectVector &pairs, const UString &id); + +#endif + + diff --git a/CPP/Common/Types.h b/CPP/Common/Types.h new file mode 100755 index 00000000..41d785e9 --- /dev/null +++ b/CPP/Common/Types.h @@ -0,0 +1,57 @@ +// Common/Types.h + +#ifndef __COMMON_TYPES_H +#define __COMMON_TYPES_H + +#ifndef _7ZIP_BYTE_DEFINED +#define _7ZIP_BYTE_DEFINED +typedef unsigned char Byte; +#endif + +#ifndef _7ZIP_INT16_DEFINED +#define _7ZIP_INT16_DEFINED +typedef short Int16; +#endif + +#ifndef _7ZIP_UINT16_DEFINED +#define _7ZIP_UINT16_DEFINED +typedef unsigned short UInt16; +#endif + +#ifndef _7ZIP_INT32_DEFINED +#define _7ZIP_INT32_DEFINED +typedef int Int32; +#endif + +#ifndef _7ZIP_UINT32_DEFINED +#define _7ZIP_UINT32_DEFINED +typedef unsigned int UInt32; +#endif + +#ifdef _MSC_VER + +#ifndef _7ZIP_INT64_DEFINED +#define _7ZIP_INT64_DEFINED +typedef __int64 Int64; +#endif + +#ifndef _7ZIP_UINT64_DEFINED +#define _7ZIP_UINT64_DEFINED +typedef unsigned __int64 UInt64; +#endif + +#else + +#ifndef _7ZIP_INT64_DEFINED +#define _7ZIP_INT64_DEFINED +typedef long long int Int64; +#endif + +#ifndef _7ZIP_UINT64_DEFINED +#define _7ZIP_UINT64_DEFINED +typedef unsigned long long int UInt64; +#endif + +#endif + +#endif diff --git a/CPP/Common/UTFConvert.cpp b/CPP/Common/UTFConvert.cpp new file mode 100755 index 00000000..e15695bb --- /dev/null +++ b/CPP/Common/UTFConvert.cpp @@ -0,0 +1,91 @@ +// UTFConvert.cpp + +#include "StdAfx.h" + +#include "UTFConvert.h" +#include "Types.h" + +static Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + +// These functions are for UTF8 <-> UTF16 conversion. + +bool ConvertUTF8ToUnicode(const AString &src, UString &dest) +{ + dest.Empty(); + for(int i = 0; i < src.Length();) + { + Byte c = (Byte)src[i++]; + if (c < 0x80) + { + dest += (wchar_t)c; + continue; + } + if(c < 0xC0) + return false; + int numAdds; + for (numAdds = 1; numAdds < 5; numAdds++) + if (c < kUtf8Limits[numAdds]) + break; + UInt32 value = (c - kUtf8Limits[numAdds - 1]); + do + { + if (i >= src.Length()) + return false; + Byte c2 = (Byte)src[i++]; + if (c2 < 0x80 || c2 >= 0xC0) + return false; + value <<= 6; + value |= (c2 - 0x80); + numAdds--; + } + while(numAdds > 0); + if (value < 0x10000) + dest += (wchar_t)(value); + else + { + value -= 0x10000; + if (value >= 0x100000) + return false; + dest += (wchar_t)(0xD800 + (value >> 10)); + dest += (wchar_t)(0xDC00 + (value & 0x3FF)); + } + } + return true; +} + +bool ConvertUnicodeToUTF8(const UString &src, AString &dest) +{ + dest.Empty(); + for(int i = 0; i < src.Length();) + { + UInt32 value = (UInt32)src[i++]; + if (value < 0x80) + { + dest += (char)value; + continue; + } + if (value >= 0xD800 && value < 0xE000) + { + if (value >= 0xDC00) + return false; + if (i >= src.Length()) + return false; + UInt32 c2 = (UInt32)src[i++]; + if (c2 < 0xDC00 || c2 >= 0xE000) + return false; + value = ((value - 0xD800) << 10) | (c2 - 0xDC00); + } + int numAdds; + for (numAdds = 1; numAdds < 5; numAdds++) + if (value < (((UInt32)1) << (numAdds * 5 + 6))) + break; + dest += (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds))); + do + { + numAdds--; + dest += (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F)); + } + while(numAdds > 0); + } + return true; +} diff --git a/CPP/Common/UTFConvert.h b/CPP/Common/UTFConvert.h new file mode 100755 index 00000000..47434111 --- /dev/null +++ b/CPP/Common/UTFConvert.h @@ -0,0 +1,11 @@ +// Common/UTFConvert.h + +#ifndef __COMMON_UTFCONVERT_H +#define __COMMON_UTFCONVERT_H + +#include "Common/String.h" + +bool ConvertUTF8ToUnicode(const AString &utfString, UString &resultString); +bool ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString); + +#endif diff --git a/CPP/Common/Vector.cpp b/CPP/Common/Vector.cpp new file mode 100755 index 00000000..b3dd70a5 --- /dev/null +++ b/CPP/Common/Vector.cpp @@ -0,0 +1,83 @@ +// Common/Vector.cpp + +#include "StdAfx.h" + +#include + +#include "Vector.h" + +CBaseRecordVector::~CBaseRecordVector() + { Free(); } + +void CBaseRecordVector::Free() +{ + delete []((unsigned char *)_items); + _capacity = 0; + _size = 0; + _items = 0; +} + +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 [](unsigned char *)_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/CPP/Common/Vector.h b/CPP/Common/Vector.h new file mode 100755 index 00000000..1bb67a1d --- /dev/null +++ b/CPP/Common/Vector.h @@ -0,0 +1,237 @@ +// Common/Vector.h + +#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): + _capacity(0), _size(0), _items(0), _itemSize(itemSize) {} + virtual ~CBaseRecordVector(); + void Free(); + 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 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); } + + void Swap(int i, int j) + { + T temp = operator[](i); + operator[](i) = operator[](j); + operator[](j) = temp; + } + + 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; + } + + + static void SortRefDown(T* p, int k, int size, int (*compare)(const T*, const T*, void *), void *param) + { + T temp = p[k]; + for (;;) + { + int s = (k << 1); + if (s > size) + break; + if (s < size && compare(p + s + 1, p + s, param) > 0) + s++; + if (compare(&temp, p + s, param) >= 0) + break; + p[k] = p[s]; + k = s; + } + p[k] = temp; + } + + void Sort(int (*compare)(const T*, const T*, void *), void *param) + { + int size = _size; + if (size <= 1) + return; + T* p = (&Front()) - 1; + { + int i = size / 2; + do + SortRefDown(p, i, size, compare, param); + while(--i != 0); + } + do + { + T temp = p[size]; + p[size--] = p[1]; + p[1] = temp; + SortRefDown(p, 1, size, compare, param); + } + while (size > 1); + } +}; + +typedef CRecordVector CIntVector; +typedef CRecordVector CUIntVector; +typedef CRecordVector CBoolVector; +typedef CRecordVector CByteVector; +typedef CRecordVector CPointerVector; + +template +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)[i]) + 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; + } + + void Sort(int (*compare)(void *const *, void *const *, void *), void *param) + { CPointerVector::Sort(compare, param); } + + static int CompareObjectItems(void *const *a1, void *const *a2, void * /* param */) + { return MyCompare(*(*((const T **)a1)), *(*((const T **)a2))); } + void Sort() { CPointerVector::Sort(CompareObjectItems, 0); } +}; + +#endif diff --git a/CPP/Common/Wildcard.cpp b/CPP/Common/Wildcard.cpp new file mode 100755 index 00000000..ddadc7b1 --- /dev/null +++ b/CPP/Common/Wildcard.cpp @@ -0,0 +1,462 @@ +// 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'?'; + +#ifdef _WIN32 +static const wchar_t kDirDelimiter1 = L'\\'; +#endif +static const wchar_t kDirDelimiter2 = 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 ( + #ifdef _WIN32 + c == kDirDelimiter1 || + #endif + 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) +#ifdef _WIN32 + if (MyCharUpper(maskChar) != MyCharUpper(c)) +#endif + 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 UString &path, UString &dirPrefix, UString &name) +{ + int i; + for(i = path.Length() - 1; i >= 0; i--) + if(IsCharDirLimiter(path[i])) + break; + dirPrefix = path.Left(i + 1); + name = path.Mid(i + 1); +} + +UString ExtractDirPrefixFromPath(const UString &path) +{ + int i; + for(i = path.Length() - 1; i >= 0; i--) + if(IsCharDirLimiter(path[i])) + break; + return path.Left(i + 1); +} + +UString ExtractFileNameFromPath(const UString &path) +{ + int i; + for(i = path.Length() - 1; i >= 0; i--) + if(IsCharDirLimiter(path[i])) + break; + return path.Mid(i + 1); +} + + +bool CompareWildCardWithName(const UString &mask, const UString &name) +{ + return EnhancedMaskTest(mask, 0, name, 0); +} + +bool DoesNameContainWildCard(const UString &path) +{ + return (path.FindOneOf(kWildCardCharSet) >= 0); +} + + +// ----------------------------------------------------------' +// NWildcard + +namespace NWildcard { + +static inline int BoolToIndex(bool value) +{ + return value ? 1: 0; +} + + +/* +M = MaskParts.Size(); +N = TestNameParts.Size(); + + File Dir +ForFile req M<=N [N-M, N) - + nonreq M=N [0, M) - + +ForDir req M 1) + return true; + } + return false; +} + +bool CCensorNode::AreThereIncludeItems() const +{ + if (IncludeItems.Size() > 0) + return true; + for (int i = 0; i < SubNodes.Size(); i++) + if (SubNodes[i].AreThereIncludeItems()) + return true; + return false; +} + +bool CCensorNode::CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const +{ + const CObjectVector &items = include ? IncludeItems : ExcludeItems; + for (int i = 0; i < items.Size(); i++) + if (items[i].CheckPath(pathParts, isFile)) + return true; + return false; +} + +bool CCensorNode::CheckPath(UStringVector &pathParts, bool isFile, bool &include) const +{ + if (CheckPathCurrent(false, pathParts, isFile)) + { + include = false; + return true; + } + include = true; + bool finded = CheckPathCurrent(true, pathParts, isFile); + if (pathParts.Size() == 1) + return finded; + int index = FindSubNode(pathParts.Front()); + if (index >= 0) + { + UStringVector pathParts2 = pathParts; + pathParts2.Delete(0); + if (SubNodes[index].CheckPath(pathParts2, isFile, include)) + return true; + } + return finded; +} + +bool CCensorNode::CheckPath(const UString &path, bool isFile, bool &include) const +{ + UStringVector pathParts; + SplitPathToParts(path, pathParts); + return CheckPath(pathParts, isFile, include); +} + +bool CCensorNode::CheckPath(const UString &path, bool isFile) const +{ + bool include; + if(CheckPath(path, isFile, include)) + return include; + return false; +} + +bool CCensorNode::CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const +{ + if (CheckPathCurrent(include, pathParts, isFile)) + return true; + if (Parent == 0) + return false; + pathParts.Insert(0, Name); + return Parent->CheckPathToRoot(include, pathParts, isFile); +} + +/* +bool CCensorNode::CheckPathToRoot(bool include, const UString &path, bool isFile) const +{ + UStringVector pathParts; + SplitPathToParts(path, pathParts); + return CheckPathToRoot(include, pathParts, isFile); +} +*/ + +void CCensorNode::AddItem2(bool include, const UString &path, bool recursive) +{ + if (path.IsEmpty()) + return; + bool forFile = true; + bool forFolder = true; + UString path2 = path; + if (IsCharDirLimiter(path[path.Length() - 1])) + { + path2.Delete(path.Length() - 1); + forFile = false; + } + AddItem(include, path2, recursive, forFile, forFolder); +} + +void CCensorNode::ExtendExclude(const CCensorNode &fromNodes) +{ + ExcludeItems += fromNodes.ExcludeItems; + for (int i = 0; i < fromNodes.SubNodes.Size(); i++) + { + const CCensorNode &node = fromNodes.SubNodes[i]; + int subNodeIndex = FindSubNode(node.Name); + if (subNodeIndex < 0) + subNodeIndex = SubNodes.Add(CCensorNode(node.Name, this)); + SubNodes[subNodeIndex].ExtendExclude(node); + } +} + +int CCensor::FindPrefix(const UString &prefix) const +{ + for (int i = 0; i < Pairs.Size(); i++) + if (Pairs[i].Prefix.CompareNoCase(prefix) == 0) + return i; + return -1; +} + +void CCensor::AddItem(bool include, const UString &path, bool recursive) +{ + UStringVector pathParts; + SplitPathToParts(path, pathParts); + bool forFile = true; + if (pathParts.Back().IsEmpty()) + { + forFile = false; + pathParts.DeleteBack(); + } + const UString &front = pathParts.Front(); + bool isAbs = false; + if (front.IsEmpty()) + isAbs = true; + else if (front.Length() == 2 && front[1] == L':') + isAbs = true; + else + { + for (int i = 0; i < pathParts.Size(); i++) + { + const UString &part = pathParts[i]; + if (part == L".." || part == L".") + { + isAbs = true; + break; + } + } + } + int numAbsParts = 0; + if (isAbs) + if (pathParts.Size() > 1) + numAbsParts = pathParts.Size() - 1; + else + numAbsParts = 1; + UString prefix; + for (int i = 0; i < numAbsParts; i++) + { + const UString &front = pathParts.Front(); + if (DoesNameContainWildCard(front)) + break; + prefix += front; + prefix += WCHAR_PATH_SEPARATOR; + pathParts.Delete(0); + } + int index = FindPrefix(prefix); + if (index < 0) + index = Pairs.Add(CPair(prefix)); + + CItem item; + item.PathParts = pathParts; + item.ForDir = true; + item.ForFile = forFile; + item.Recursive = recursive; + Pairs[index].Head.AddItem(include, item); +} + +bool CCensor::CheckPath(const UString &path, bool isFile) const +{ + bool finded = false; + for (int i = 0; i < Pairs.Size(); i++) + { + bool include; + if (Pairs[i].Head.CheckPath(path, isFile, include)) + { + if (!include) + return false; + finded = true; + } + } + return finded; +} + +void CCensor::ExtendExclude() +{ + int i; + for (i = 0; i < Pairs.Size(); i++) + if (Pairs[i].Prefix.IsEmpty()) + break; + if (i == Pairs.Size()) + return; + int index = i; + for (i = 0; i < Pairs.Size(); i++) + if (index != i) + Pairs[i].Head.ExtendExclude(Pairs[index].Head); +} + +} diff --git a/CPP/Common/Wildcard.h b/CPP/Common/Wildcard.h new file mode 100755 index 00000000..82d2bbd2 --- /dev/null +++ b/CPP/Common/Wildcard.h @@ -0,0 +1,78 @@ +// Common/Wildcard.h + +#ifndef __COMMON_WILDCARD_H +#define __COMMON_WILDCARD_H + +#include "Common/String.h" + +void SplitPathToParts(const UString &path, UStringVector &pathParts); +void SplitPathToParts(const UString &path, UString &dirPrefix, UString &name); +UString ExtractDirPrefixFromPath(const UString &path); +UString ExtractFileNameFromPath(const UString &path); +bool DoesNameContainWildCard(const UString &path); +bool CompareWildCardWithName(const UString &mask, const UString &name); + +namespace NWildcard { + +struct CItem +{ + UStringVector PathParts; + bool Recursive; + bool ForFile; + bool ForDir; + bool CheckPath(const UStringVector &pathParts, bool isFile) const; +}; + +class CCensorNode +{ + CCensorNode *Parent; + bool CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const; + void AddItemSimple(bool include, CItem &item); + bool CheckPath(UStringVector &pathParts, bool isFile, bool &include) const; +public: + CCensorNode(): Parent(0) { }; + CCensorNode(const UString &name, CCensorNode *parent): Name(name), Parent(parent) { }; + UString Name; + CObjectVector SubNodes; + CObjectVector IncludeItems; + CObjectVector ExcludeItems; + + int FindSubNode(const UString &path) const; + + void AddItem(bool include, CItem &item); + void AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir); + void AddItem2(bool include, const UString &path, bool recursive); + + bool NeedCheckSubDirs() const; + bool AreThereIncludeItems() const; + + bool CheckPath(const UString &path, bool isFile, bool &include) const; + bool CheckPath(const UString &path, bool isFile) const; + + bool CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const; + // bool CheckPathToRoot(const UString &path, bool isFile, bool include) const; + void ExtendExclude(const CCensorNode &fromNodes); +}; + +struct CPair +{ + UString Prefix; + CCensorNode Head; + CPair(const UString &prefix): Prefix(prefix) { }; +}; + +class CCensor +{ + int FindPrefix(const UString &prefix) const; +public: + CObjectVector Pairs; + bool AllAreRelative() const + { return (Pairs.Size() == 1 && Pairs.Front().Prefix.IsEmpty()); } + void AddItem(bool include, const UString &path, bool recursive); + bool CheckPath(const UString &path, bool isFile) const; + void ExtendExclude(); +}; + +} + +#endif diff --git a/CPP/Windows/COM.cpp b/CPP/Windows/COM.cpp new file mode 100755 index 00000000..2f9fdcda --- /dev/null +++ b/CPP/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/CPP/Windows/COM.h b/CPP/Windows/COM.h new file mode 100755 index 00000000..80651406 --- /dev/null +++ b/CPP/Windows/COM.h @@ -0,0 +1,57 @@ +// Windows/COM.h + +#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/CPP/Windows/CommonDialog.cpp b/CPP/Windows/CommonDialog.cpp new file mode 100755 index 00000000..d0234c54 --- /dev/null +++ b/CPP/Windows/CommonDialog.cpp @@ -0,0 +1,164 @@ +// Windows/CommonDialog.cpp + +#include "StdAfx.h" + +#ifndef _UNICODE +#include "Common/StringConvert.h" +#endif +#include "Common/MyCom.h" +#include "CommonDialog.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows{ + +#ifndef _UNICODE +class CDoubleZeroStringListA +{ + CRecordVector m_Indexes; + AString m_String; +public: + void Add(LPCSTR s); + void SetForBuffer(LPSTR buffer); +}; + +void CDoubleZeroStringListA::Add(LPCSTR s) +{ + m_String += s; + m_Indexes.Add(m_String.Length()); + m_String += ' '; +} + +void CDoubleZeroStringListA::SetForBuffer(LPSTR buffer) +{ + MyStringCopy(buffer, (const char *)m_String); + for (int i = 0; i < m_Indexes.Size(); i++) + buffer[m_Indexes[i]] = '\0'; +} +#endif + +class CDoubleZeroStringListW +{ + CRecordVector m_Indexes; + UString m_String; +public: + void Add(LPCWSTR s); + void SetForBuffer(LPWSTR buffer); +}; + +void CDoubleZeroStringListW::Add(LPCWSTR s) +{ + m_String += s; + m_Indexes.Add(m_String.Length()); + m_String += L' '; +} + +void CDoubleZeroStringListW::SetForBuffer(LPWSTR buffer) +{ + MyStringCopy(buffer, (const wchar_t *)m_String); + for (int i = 0; i < m_Indexes.Size(); i++) + buffer[m_Indexes[i]] = L'\0'; +} + +bool MyGetOpenFileName(HWND hwnd, LPCWSTR title, LPCWSTR fullFileName, LPCWSTR s, UString &resPath) +{ + const int kBufferSize = MAX_PATH * 2; + #ifndef _UNICODE + if (!g_IsNT) + { + CHAR buffer[kBufferSize]; + MyStringCopy(buffer, (const char *)GetSystemString(fullFileName)); + OPENFILENAME info; + info.lStructSize = sizeof(info); + info.hwndOwner = hwnd; + info.hInstance = 0; + const int kFilterBufferSize = MAX_PATH; + CHAR filterBuffer[kFilterBufferSize]; + CDoubleZeroStringListA doubleZeroStringList; + doubleZeroStringList.Add(GetSystemString(s)); + doubleZeroStringList.Add("*.*"); + 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; + + info.lpstrTitle = 0; + AString titleA; + if (title != 0) + { + titleA = GetSystemString(title); + info.lpstrTitle = titleA; + } + + info.Flags = OFN_EXPLORER | OFN_HIDEREADONLY; + info.nFileOffset = 0; + info.nFileExtension = 0; + info.lpstrDefExt = NULL; + + info.lCustData = 0; + info.lpfnHook = NULL; + info.lpTemplateName = NULL; + + bool res = BOOLToBool(::GetOpenFileNameA(&info)); + resPath = GetUnicodeString(buffer); + return res; + } + else + #endif + { + WCHAR buffer[kBufferSize]; + MyStringCopy(buffer, fullFileName); + OPENFILENAMEW info; + info.lStructSize = sizeof(info); + info.hwndOwner = hwnd; + info.hInstance = 0; + const int kFilterBufferSize = MAX_PATH; + WCHAR filterBuffer[kFilterBufferSize]; + CDoubleZeroStringListW doubleZeroStringList; + doubleZeroStringList.Add(s); + doubleZeroStringList.Add(L"*.*"); + 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; + + 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; + + bool res = BOOLToBool(::GetOpenFileNameW(&info)); + resPath = buffer; + return res; + } +} + +} diff --git a/CPP/Windows/CommonDialog.h b/CPP/Windows/CommonDialog.h new file mode 100755 index 00000000..d0149aba --- /dev/null +++ b/CPP/Windows/CommonDialog.h @@ -0,0 +1,17 @@ +// Windows/CommonDialog.h + +#ifndef __WINDOWS_COMMONDIALOG_H +#define __WINDOWS_COMMONDIALOG_H + +#include + +#include "Common/String.h" +#include "Windows/Defs.h" + +namespace NWindows{ + +bool MyGetOpenFileName(HWND hwnd, LPCWSTR title, LPCWSTR fullFileName, LPCWSTR s, UString &resPath); + +} + +#endif diff --git a/CPP/Windows/Console.cpp b/CPP/Windows/Console.cpp new file mode 100755 index 00000000..1dffc377 --- /dev/null +++ b/CPP/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/CPP/Windows/Console.h b/CPP/Windows/Console.h new file mode 100755 index 00000000..b4e6d35b --- /dev/null +++ b/CPP/Windows/Console.h @@ -0,0 +1,52 @@ +// Windows/Console.h + +#ifndef __WINDOWS_CONSOLE_H +#define __WINDOWS_CONSOLE_H + +#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/CPP/Windows/Control/ComboBox.cpp b/CPP/Windows/Control/ComboBox.cpp new file mode 100755 index 00000000..5b1d2651 --- /dev/null +++ b/CPP/Windows/Control/ComboBox.cpp @@ -0,0 +1,63 @@ +// Windows/Control/ComboBox.cpp + +// #define _UNICODE +// #define UNICODE + +#include "StdAfx.h" + +#ifndef _UNICODE +#include "Common/StringConvert.h" +#endif + +#include "Windows/Control/ComboBox.h" +#include "Windows/Defs.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { +namespace NControl { + +LRESULT CComboBox::GetLBText(int index, CSysString &s) +{ + s.Empty(); + LRESULT len = GetLBTextLen(index); + if (len == CB_ERR) + return len; + len = GetLBText(index, s.GetBuffer((int)len + 1)); + s.ReleaseBuffer(); + return len; +} + +#ifndef _UNICODE +LRESULT CComboBox::AddString(LPCWSTR s) +{ + if (g_IsNT) + return SendMessageW(CB_ADDSTRING, 0, (LPARAM)s); + return AddString(GetSystemString(s)); +} + +LRESULT CComboBox::GetLBText(int index, UString &s) +{ + s.Empty(); + if (g_IsNT) + { + LRESULT len = SendMessageW(CB_GETLBTEXTLEN, index, 0); + if (len == CB_ERR) + return len; + len = SendMessageW(CB_GETLBTEXT, index, (LPARAM)s.GetBuffer((int)len + 1)); + s.ReleaseBuffer(); + return len; + } + AString sa; + LRESULT len = GetLBText(index, sa); + if (len == CB_ERR) + return len; + s = GetUnicodeString(sa); + return s.Length(); +} +#endif + + +}} diff --git a/CPP/Windows/Control/ComboBox.h b/CPP/Windows/Control/ComboBox.h new file mode 100755 index 00000000..2fb2302e --- /dev/null +++ b/CPP/Windows/Control/ComboBox.h @@ -0,0 +1,54 @@ +// Windows/Control/ComboBox.h + +#ifndef __WINDOWS_CONTROL_COMBOBOX_H +#define __WINDOWS_CONTROL_COMBOBOX_H + +#include "Windows/Window.h" +#include "Windows/Defs.h" + +#include + +namespace NWindows { +namespace NControl { + +class CComboBox: public CWindow +{ +public: + void ResetContent() { SendMessage(CB_RESETCONTENT, 0, 0); } + LRESULT AddString(LPCTSTR string) { return SendMessage(CB_ADDSTRING, 0, (LPARAM)string); } + #ifndef _UNICODE + LRESULT AddString(LPCWSTR string); + #endif + LRESULT SetCurSel(int index) { return SendMessage(CB_SETCURSEL, index, 0); } + int GetCurSel() { return (int)SendMessage(CB_GETCURSEL, 0, 0); } + int GetCount() { return (int)SendMessage(CB_GETCOUNT, 0, 0); } + + LRESULT GetLBTextLen(int index) { return SendMessage(CB_GETLBTEXTLEN, index, 0); } + LRESULT GetLBText(int index, LPTSTR string) { return SendMessage(CB_GETLBTEXT, index, (LPARAM)string); } + LRESULT GetLBText(int index, CSysString &s); + #ifndef _UNICODE + LRESULT GetLBText(int index, UString &s); + #endif + + LRESULT SetItemData(int index, LPARAM lParam) + { return SendMessage(CB_SETITEMDATA, index, lParam); } + LRESULT GetItemData(int index) + { return SendMessage(CB_GETITEMDATA, index, 0); } +}; + +class CComboBoxEx: public CWindow +{ +public: + LRESULT DeleteItem(int index) + { return SendMessage(CBEM_DELETEITEM, index, 0); } + LRESULT InsertItem(COMBOBOXEXITEM *item) + { return SendMessage(CBEM_INSERTITEM, 0, (LPARAM)item); } + DWORD SetExtendedStyle(DWORD exMask, DWORD exStyle) + { return (DWORD)SendMessage(CBEM_SETEXTENDEDSTYLE, exMask, exStyle); } + HWND GetEditControl() + { return (HWND)SendMessage(CBEM_GETEDITCONTROL, 0, 0); } +}; + +}} + +#endif \ No newline at end of file diff --git a/CPP/Windows/Control/Dialog.cpp b/CPP/Windows/Control/Dialog.cpp new file mode 100755 index 00000000..64009b79 --- /dev/null +++ b/CPP/Windows/Control/Dialog.cpp @@ -0,0 +1,145 @@ +// Windows/Control/Dialog.cpp + +#include "StdAfx.h" + +#ifndef _UNICODE +#include "Common/StringConvert.h" +#endif +#include "Windows/Control/Dialog.h" + +extern HINSTANCE g_hInstance; +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { +namespace NControl { + +static INT_PTR APIENTRY DialogProcedure(HWND dialogHWND, UINT message, + WPARAM wParam, LPARAM lParam) +{ + CWindow dialogTmp(dialogHWND); + if (message == WM_INITDIALOG) + dialogTmp.SetUserDataLongPtr(lParam); + CDialog *dialog = (CDialog *)(dialogTmp.GetUserDataLongPtr()); + if (dialog == NULL) + return FALSE; + if (message == WM_INITDIALOG) + dialog->Attach(dialogHWND); + + return BoolToBOOL(dialog->OnMessage(message, wParam, lParam)); +} + +bool CDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG: + return OnInit(); + case WM_COMMAND: + return OnCommand(wParam, lParam); + case WM_NOTIFY: + return OnNotify((UINT)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); +} + +#ifndef _UNICODE + +bool CModelessDialog::Create(LPCWSTR templateName, HWND parentWindow) +{ + HWND aHWND; + if (g_IsNT) + aHWND = CreateDialogParamW(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this); + else + { + AString name; + LPCSTR templateNameA; + if (IS_INTRESOURCE(templateName)) + templateNameA = (LPCSTR)templateName; + else + { + name = GetSystemString(templateName); + templateNameA = name; + } + aHWND = CreateDialogParamA(g_hInstance, templateNameA, parentWindow, DialogProcedure, (LPARAM)this); + } + if (aHWND == 0) + return false; + Attach(aHWND); + return true; +} + +INT_PTR CModalDialog::Create(LPCWSTR templateName, HWND parentWindow) +{ + if (g_IsNT) + return DialogBoxParamW(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this); + AString name; + LPCSTR templateNameA; + if (IS_INTRESOURCE(templateName)) + templateNameA = (LPCSTR)templateName; + else + { + name = GetSystemString(templateName); + templateNameA = name; + } + return DialogBoxParamA(g_hInstance, templateNameA, parentWindow, DialogProcedure, (LPARAM)this); +} +#endif + +}} diff --git a/CPP/Windows/Control/Dialog.h b/CPP/Windows/Control/Dialog.h new file mode 100755 index 00000000..f6182c4b --- /dev/null +++ b/CPP/Windows/Control/Dialog.h @@ -0,0 +1,144 @@ +// Windows/Control/Dialog.h + +#ifndef __WINDOWS_CONTROL_DIALOG_H +#define __WINDOWS_CONTROL_DIALOG_H + +#include "Windows/Window.h" +#include "Windows/Defs.h" + +namespace NWindows { +namespace NControl { + +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 ShowItem(int itemID, int cmdShow) const + { return BOOLToBool(::ShowWindow(GetItem(itemID), cmdShow)); } + + 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); + #ifndef _UNICODE + bool Create(LPCWSTR templateName, HWND parentWindow); + #endif + virtual void OnOK() { Destroy(); } + virtual void OnCancel() { Destroy(); } +}; + +class CModalDialog: public CDialog +{ +public: + INT_PTR Create(LPCTSTR templateName, HWND parentWindow); + INT_PTR Create(UINT resID, HWND parentWindow) + { return Create(MAKEINTRESOURCEW(resID), parentWindow); } + #ifndef _UNICODE + INT_PTR Create(LPCWSTR templateName, HWND parentWindow); + #endif + + bool End(INT_PTR result) + { return BOOLToBool(::EndDialog(_window, result)); } + virtual void OnOK() { 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/CPP/Windows/Control/Edit.h b/CPP/Windows/Control/Edit.h new file mode 100755 index 00000000..d1af3644 --- /dev/null +++ b/CPP/Windows/Control/Edit.h @@ -0,0 +1,21 @@ +// Windows/Control/Edit.h + +#ifndef __WINDOWS_CONTROL_EDIT_H +#define __WINDOWS_CONTROL_EDIT_H + +#include "Windows/Window.h" +#include "Windows/Defs.h" + +namespace NWindows { +namespace NControl { + +class CEdit: public CWindow +{ +public: + void SetPasswordChar(WPARAM c) + { SendMessage(EM_SETPASSWORDCHAR, c); } +}; + +}} + +#endif \ No newline at end of file diff --git a/CPP/Windows/Control/ImageList.cpp b/CPP/Windows/Control/ImageList.cpp new file mode 100755 index 00000000..16a46fa4 --- /dev/null +++ b/CPP/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/CPP/Windows/Control/ImageList.h b/CPP/Windows/Control/ImageList.h new file mode 100755 index 00000000..fc8ddfbd --- /dev/null +++ b/CPP/Windows/Control/ImageList.h @@ -0,0 +1,86 @@ +// Windows/Control/ImageList.h + +#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/CPP/Windows/Control/ListView.cpp b/CPP/Windows/Control/ListView.cpp new file mode 100755 index 00000000..b532a7a4 --- /dev/null +++ b/CPP/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 ¶m) 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/CPP/Windows/Control/ListView.h b/CPP/Windows/Control/ListView.h new file mode 100755 index 00000000..60b8146e --- /dev/null +++ b/CPP/Windows/Control/ListView.h @@ -0,0 +1,138 @@ +// Windows/Control/ListView.h + +#ifndef __WINDOWS_CONTROL_LISTVIEW_H +#define __WINDOWS_CONTROL_LISTVIEW_H + +#include "Windows/Window.h" +#include "Windows/Defs.h" + +#include + +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 SetUnicodeFormat(bool fUnicode) + { return BOOLToBool(ListView_SetUnicodeFormat(_window, BOOLToBool(fUnicode))); } + + bool DeleteAllItems() + { return BOOLToBool(ListView_DeleteAllItems(_window)); } + int InsertColumn(int columnIndex, const LVCOLUMN *columnInfo) + { return ListView_InsertColumn(_window, columnIndex, columnInfo); } + #ifndef _UNICODE + int InsertColumn(int columnIndex, const LVCOLUMNW *columnInfo) + { return (int)SendMessage(LVM_INSERTCOLUMNW, (WPARAM)columnIndex, (LPARAM)columnInfo); } + #endif + bool DeleteColumn(int columnIndex) + { return BOOLToBool(ListView_DeleteColumn(_window, columnIndex)); } + + int InsertItem(const LVITEM* item) + { return ListView_InsertItem(_window, item); } + #ifndef _UNICODE + int InsertItem(const LV_ITEMW* item) + { return (int)SendMessage(LVM_INSERTITEMW, 0, (LPARAM)item); } + #endif + + bool SetItem(const LVITEM* item) + { return BOOLToBool(ListView_SetItem(_window, item)); } + #ifndef _UNICODE + bool SetItem(const LV_ITEMW* item) + { return BOOLToBool((BOOL)SendMessage(LVM_SETITEMW, 0, (LPARAM)item)); } + #endif + + 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() const + { 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 ¶m) 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) const + { 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/CPP/Windows/Control/ProgressBar.h b/CPP/Windows/Control/ProgressBar.h new file mode 100755 index 00000000..6ce837cc --- /dev/null +++ b/CPP/Windows/Control/ProgressBar.h @@ -0,0 +1,41 @@ +// Windows/Control/ProgressBar.h + +#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 (UINT)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 (DWORD)SendMessage(PBM_SETRANGE32, minValue, maxValue); } + int SetStep(int step) + { return (int)SendMessage(PBM_SETSTEP, step, 0); } + LRESULT StepIt() + { return SendMessage(PBM_STEPIT, 0, 0); } + + INT GetRange(bool minValue, PPBRANGE range) + { return (INT)SendMessage(PBM_GETRANGE, BoolToBOOL(minValue), (LPARAM)range); } + + COLORREF SetBarColor(COLORREF color) + { return (COLORREF)SendMessage(PBM_SETBARCOLOR, 0, color); } + COLORREF SetBackgroundColor(COLORREF color) + { return (COLORREF)SendMessage(PBM_SETBKCOLOR, 0, color); } +}; + +}} + +#endif \ No newline at end of file diff --git a/CPP/Windows/Control/PropertyPage.cpp b/CPP/Windows/Control/PropertyPage.cpp new file mode 100755 index 00000000..f8996be1 --- /dev/null +++ b/CPP/Windows/Control/PropertyPage.cpp @@ -0,0 +1,163 @@ +// Windows/Control/PropertyPage.cpp + +#include "StdAfx.h" + +#include "Windows/Control/PropertyPage.h" +#include "../../Common/Vector.h" +#ifndef _UNICODE +#include "../../Common/StringConvert.h" +#endif + +extern HINSTANCE g_hInstance; +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { +namespace NControl { + +INT_PTR APIENTRY ProperyPageProcedure(HWND dialogHWND, UINT message, + WPARAM wParam, LPARAM 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((UINT)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; +} + +INT_PTR MyPropertySheet(const CObjectVector &pagesInfo, HWND hwndParent, const UString &title) +{ + #ifndef _UNICODE + AStringVector titles; + #endif + #ifndef _UNICODE + CRecordVector pagesA; + #endif + CRecordVector pagesW; + + int i; + #ifndef _UNICODE + for (i = 0; i < pagesInfo.Size(); i++) + titles.Add(GetSystemString(pagesInfo[i].Title)); + #endif + + for (i = 0; i < pagesInfo.Size(); i++) + { + const CPageInfo &pageInfo = pagesInfo[i]; + #ifndef _UNICODE + { + PROPSHEETPAGE page; + page.dwSize = sizeof(page); + page.dwFlags = PSP_HASHELP; + page.hInstance = g_hInstance; + page.pszTemplate = MAKEINTRESOURCE(pageInfo.ID); + page.pszIcon = NULL; + page.pfnDlgProc = NWindows::NControl::ProperyPageProcedure; + + if (titles[i].IsEmpty()) + page.pszTitle = NULL; + else + { + page.dwFlags |= PSP_USETITLE; + page.pszTitle = titles[i]; + } + page.lParam = (LPARAM)pageInfo.Page; + page.pfnCallback = NULL; + pagesA.Add(page); + } + #endif + { + PROPSHEETPAGEW page; + page.dwSize = sizeof(page); + page.dwFlags = PSP_HASHELP; + page.hInstance = g_hInstance; + page.pszTemplate = MAKEINTRESOURCEW(pageInfo.ID); + page.pszIcon = NULL; + page.pfnDlgProc = NWindows::NControl::ProperyPageProcedure; + + if (pageInfo.Title.IsEmpty()) + page.pszTitle = NULL; + else + { + page.dwFlags |= PSP_USETITLE; + page.pszTitle = pageInfo.Title; + } + page.lParam = (LPARAM)pageInfo.Page; + page.pfnCallback = NULL; + pagesW.Add(page); + } + } + + #ifndef _UNICODE + if (!g_IsNT) + { + PROPSHEETHEADER sheet; + sheet.dwSize = sizeof(sheet); + sheet.dwFlags = PSH_PROPSHEETPAGE; + sheet.hwndParent = hwndParent; + sheet.hInstance = g_hInstance; + AString titleA = GetSystemString(title); + sheet.pszCaption = titleA; + sheet.nPages = pagesInfo.Size(); + sheet.nStartPage = 0; + sheet.ppsp = &pagesA.Front(); + sheet.pfnCallback = NULL; + return ::PropertySheetA(&sheet); + } + else + #endif + { + PROPSHEETHEADERW sheet; + sheet.dwSize = sizeof(sheet); + sheet.dwFlags = PSH_PROPSHEETPAGE; + sheet.hwndParent = hwndParent; + sheet.hInstance = g_hInstance; + sheet.pszCaption = title; + sheet.nPages = pagesInfo.Size(); + sheet.nStartPage = 0; + sheet.ppsp = &pagesW.Front(); + sheet.pfnCallback = NULL; + return ::PropertySheetW(&sheet); + } +} + +}} diff --git a/CPP/Windows/Control/PropertyPage.h b/CPP/Windows/Control/PropertyPage.h new file mode 100755 index 00000000..e041d289 --- /dev/null +++ b/CPP/Windows/Control/PropertyPage.h @@ -0,0 +1,47 @@ +// Windows/Control/PropertyPage.h + +#ifndef __WINDOWS_CONTROL_PROPERTYPAGE_H +#define __WINDOWS_CONTROL_PROPERTYPAGE_H + +#include "Windows/Control/Dialog.h" +#include "Windows/Defs.h" + +namespace NWindows { +namespace NControl { + +INT_PTR APIENTRY ProperyPageProcedure(HWND dialogHWND, UINT message, WPARAM wParam, LPARAM lParam); + +class CPropertyPage: public CDialog +{ +public: + CPropertyPage(HWND window = NULL): CDialog(window){}; + + void Changed() { PropSheet_Changed(GetParent(), HWND(*this)); } + void UnChanged() { PropSheet_UnChanged(GetParent(), HWND(*this)); } + + virtual bool OnNotify(UINT controlID, LPNMHDR lParam); + + 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(); } +}; + +struct CPageInfo +{ + CPropertyPage *Page; + UString Title; + UINT ID; +}; + +INT_PTR MyPropertySheet(const CObjectVector &pagesInfo, HWND hwndParent, const UString &title); + +}} + +#endif diff --git a/CPP/Windows/Control/ReBar.h b/CPP/Windows/Control/ReBar.h new file mode 100755 index 00000000..ec27f0ed --- /dev/null +++ b/CPP/Windows/Control/ReBar.h @@ -0,0 +1,35 @@ +// Windows/Control/ReBar.h + +#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 LRESULTToBool(SendMessage(RB_SETBARINFO, 0, (LPARAM)barInfo)); } + bool InsertBand(int index, LPREBARBANDINFO bandInfo) + { return LRESULTToBool(SendMessage(RB_INSERTBAND, index, (LPARAM)bandInfo)); } + bool SetBandInfo(int index, LPREBARBANDINFO bandInfo) + { return LRESULTToBool(SendMessage(RB_SETBANDINFO, index, (LPARAM)bandInfo)); } + void MaximizeBand(int index, bool ideal) + { SendMessage(RB_MAXIMIZEBAND, index, BoolToBOOL(ideal)); } + bool SizeToRect(LPRECT rect) + { return LRESULTToBool(SendMessage(RB_SIZETORECT, 0, (LPARAM)rect)); } + UINT GetHeight() + { return (UINT)SendMessage(RB_GETBARHEIGHT); } + UINT GetBandCount() + { return (UINT)SendMessage(RB_GETBANDCOUNT); } + bool DeleteBand(UINT index) + { return LRESULTToBool(SendMessage(RB_DELETEBAND, index)); } +}; + +}} + +#endif \ No newline at end of file diff --git a/CPP/Windows/Control/Static.h b/CPP/Windows/Control/Static.h new file mode 100755 index 00000000..5dded0ec --- /dev/null +++ b/CPP/Windows/Control/Static.h @@ -0,0 +1,27 @@ +// Windows/Control/Static.h + +#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/CPP/Windows/Control/StatusBar.h b/CPP/Windows/Control/StatusBar.h new file mode 100755 index 00000000..e8018a56 --- /dev/null +++ b/CPP/Windows/Control/StatusBar.h @@ -0,0 +1,43 @@ +// Windows/Control/StatusBar.h + +#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 LRESULTToBool(SendMessage(SB_SETPARTS, numParts, (LPARAM)edgePostions)); } + bool SetText(LPCTSTR text) + { return CWindow::SetText(text); } + + bool SetText(int index, LPCTSTR text, UINT type) + { return LRESULTToBool(SendMessage(SB_SETTEXT, index | type, (LPARAM)text)); } + bool SetText(int index, LPCTSTR text) + { return SetText(index, text, 0); } + void Simple(bool simple) + { SendMessage(SB_SIMPLE, BoolToBOOL(simple), 0); } + + #ifndef _UNICODE + bool Create(LONG style, LPCWSTR text, HWND hwndParent, UINT id) + { return (_window = ::CreateStatusWindowW(style, text, hwndParent, id)) != 0; } + bool SetText(LPCWSTR text) + { return CWindow::SetText(text); } + bool SetText(int index, LPCWSTR text, UINT type) + { return LRESULTToBool(SendMessage(SB_SETTEXTW, index | type, (LPARAM)text)); } + bool SetText(int index, LPCWSTR text) + { return SetText(index, text, 0); } + #endif +}; + +}} + +#endif \ No newline at end of file diff --git a/CPP/Windows/Control/StdAfx.h b/CPP/Windows/Control/StdAfx.h new file mode 100755 index 00000000..27a77b10 --- /dev/null +++ b/CPP/Windows/Control/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../Common/MyWindows.h" +#include "../../Common/NewHandler.h" + +#endif diff --git a/CPP/Windows/Control/ToolBar.h b/CPP/Windows/Control/ToolBar.h new file mode 100755 index 00000000..ff5cafd2 --- /dev/null +++ b/CPP/Windows/Control/ToolBar.h @@ -0,0 +1,34 @@ +// Windows/Control/ToolBar.h + +#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 LRESULTToBool(SendMessage(TB_GETMAXSIZE, 0, (LPARAM)size)); } + bool EnableButton(UINT buttonID, bool enable) + { return LRESULTToBool(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 LRESULTToBool(SendMessage(TB_ADDBUTTONS, numButtons, (LPARAM)buttons)); } + #ifndef _UNICODE + bool AddButtonW(UINT numButtons, LPTBBUTTON buttons) + { return LRESULTToBool(SendMessage(TB_ADDBUTTONSW, numButtons, (LPARAM)buttons)); } + #endif +}; + +}} + +#endif \ No newline at end of file diff --git a/CPP/Windows/Control/Trackbar.h b/CPP/Windows/Control/Trackbar.h new file mode 100755 index 00000000..bbd7009a --- /dev/null +++ b/CPP/Windows/Control/Trackbar.h @@ -0,0 +1,28 @@ +// Windows/Control/Trackbar.h + +#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/CPP/Windows/Control/Window2.cpp b/CPP/Windows/Control/Window2.cpp new file mode 100755 index 00000000..66857523 --- /dev/null +++ b/CPP/Windows/Control/Window2.cpp @@ -0,0 +1,203 @@ +// Windows/Control/Window2.cpp + +#include "StdAfx.h" + +#ifndef _UNICODE +#include "Common/StringConvert.h" +#endif +#include "Windows/Control/Window2.h" + +// extern HINSTANCE g_hInstance; +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { + +#ifndef _UNICODE +ATOM MyRegisterClass(CONST WNDCLASSW *wndClass); +#endif + +namespace NControl { + +static LRESULT CALLBACK WindowProcedure(HWND aHWND, UINT message, + WPARAM wParam, LPARAM lParam) +{ + CWindow tempWindow(aHWND); + if (message == WM_NCCREATE) + tempWindow.SetUserDataLongPtr( + LONG_PTR(((LPCREATESTRUCT)lParam)->lpCreateParams)); + CWindow2 *window = (CWindow2*)(tempWindow.GetUserDataLongPtr()); + if (window != NULL && message == WM_NCCREATE) + window->Attach(aHWND); + if (window == 0) + { + #ifndef _UNICODE + if (g_IsNT) + return DefWindowProcW(aHWND, message, wParam, lParam); + else + #endif + return DefWindowProc(aHWND, message, wParam, lParam); + } + return window->OnMessage(message, wParam, lParam); +} + +bool CWindow2::CreateEx(DWORD exStyle, LPCTSTR className, + LPCTSTR windowName, DWORD style, + int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, + HINSTANCE instance) +{ + WNDCLASS windowClass; + if(!::GetClassInfo(instance, className, &windowClass)) + { + // windowClass.style = CS_HREDRAW | CS_VREDRAW; + windowClass.style = 0; + + windowClass.lpfnWndProc = WindowProcedure; + windowClass.cbClsExtra = NULL; + windowClass.cbWndExtra = NULL; + windowClass.hInstance = instance; + windowClass.hIcon = NULL; + windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); + windowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + windowClass.lpszMenuName = NULL; + windowClass.lpszClassName = className; + if (::RegisterClass(&windowClass) == 0) + return false; + } + return CWindow::CreateEx(exStyle, className, windowName, + style, x, y, width, height, parentWindow, + idOrHMenu, instance, this); +} + +#ifndef _UNICODE + +bool CWindow2::CreateEx(DWORD exStyle, LPCWSTR className, + LPCWSTR windowName, DWORD style, + int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, + HINSTANCE instance) +{ + bool needRegister; + if(g_IsNT) + { + WNDCLASSW windowClass; + needRegister = ::GetClassInfoW(instance, className, &windowClass) == 0; + } + else + { + WNDCLASSA windowClassA; + AString classNameA; + LPCSTR classNameP; + if (IS_INTRESOURCE(className)) + classNameP = (LPCSTR)className; + else + { + classNameA = GetSystemString(className); + classNameP = classNameA; + } + needRegister = ::GetClassInfoA(instance, classNameP, &windowClassA) == 0; + } + if (needRegister) + { + WNDCLASSW windowClass; + // windowClass.style = CS_HREDRAW | CS_VREDRAW; + windowClass.style = 0; + windowClass.lpfnWndProc = WindowProcedure; + windowClass.cbClsExtra = NULL; + windowClass.cbWndExtra = NULL; + windowClass.hInstance = instance; + windowClass.hIcon = NULL; + windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); + windowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + windowClass.lpszMenuName = NULL; + windowClass.lpszClassName = className; + if (MyRegisterClass(&windowClass) == 0) + return false; + } + return CWindow::CreateEx(exStyle, className, windowName, + style, x, y, width, height, parentWindow, + idOrHMenu, instance, this); + +} +#endif + +LRESULT CWindow2::DefProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + #ifndef _UNICODE + if (g_IsNT) + return DefWindowProcW(_window, message, wParam, lParam); + else + #endif + return DefWindowProc(_window, message, wParam, lParam); +} + +LRESULT CWindow2::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + LRESULT result; + switch (message) + { + case WM_CREATE: + if (!OnCreate((CREATESTRUCT *)lParam)) + return -1; + break; + case WM_COMMAND: + if (OnCommand(wParam, lParam, result)) + return result; + break; + case WM_NOTIFY: + if (OnNotify((UINT)wParam, (LPNMHDR) lParam, result)) + return result; + break; + case WM_DESTROY: + OnDestroy(); + break; + case WM_CLOSE: + OnClose(); + return 0; + 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/CPP/Windows/Control/Window2.h b/CPP/Windows/Control/Window2.h new file mode 100755 index 00000000..2d0e574d --- /dev/null +++ b/CPP/Windows/Control/Window2.h @@ -0,0 +1,59 @@ +// Windows/Control/Window2.h + +#ifndef __WINDOWS_CONTROL_WINDOW2_H +#define __WINDOWS_CONTROL_WINDOW2_H + +#include "Windows/Window.h" +#include "Windows/Defs.h" + +namespace NWindows { +namespace NControl { + +class CWindow2: public CWindow +{ + LRESULT DefProc(UINT message, WPARAM wParam, LPARAM lParam); +public: + CWindow2(HWND newWindow = NULL): CWindow(newWindow){}; + virtual ~CWindow2() {}; + + + bool CreateEx(DWORD exStyle, LPCTSTR className, + LPCTSTR windowName, DWORD style, + int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, + HINSTANCE instance); + + #ifndef _UNICODE + bool CreateEx(DWORD exStyle, LPCWSTR className, + LPCWSTR windowName, DWORD style, + int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, + HINSTANCE instance); + #endif + + virtual LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); + virtual bool OnCreate(CREATESTRUCT * /* createStruct */) { return true; } + // virtual LRESULT OnCommand(WPARAM wParam, LPARAM lParam); + 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/CPP/Windows/DLL.cpp b/CPP/Windows/DLL.cpp new file mode 100755 index 00000000..9e92dc26 --- /dev/null +++ b/CPP/Windows/DLL.cpp @@ -0,0 +1,115 @@ +// Windows/DLL.cpp + +#include "StdAfx.h" + +#include "DLL.h" +#include "Defs.h" +#ifndef _UNICODE +#include "../Common/StringConvert.h" +#endif + +#ifndef _UNICODE +extern bool g_IsNT; +#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; } +CSysString GetSysPath(LPCWSTR sysPath) + { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); } + +bool CLibrary::LoadEx(LPCWSTR fileName, DWORD flags) +{ + if (g_IsNT) + return LoadOperations(::LoadLibraryExW(fileName, NULL, flags)); + return LoadEx(GetSysPath(fileName), flags); +} +bool CLibrary::Load(LPCWSTR fileName) +{ + if (g_IsNT) + return LoadOperations(::LoadLibraryW(fileName)); + return Load(GetSysPath(fileName)); +} +#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(); + if (g_IsNT) + { + wchar_t fullPath[MAX_PATH + 2]; + DWORD size = ::GetModuleFileNameW(hModule, fullPath, MAX_PATH + 1); + if (size <= MAX_PATH && size != 0) + { + result = fullPath; + return true; + } + return false; + } + CSysString resultSys; + if (!MyGetModuleFileName(hModule, resultSys)) + return false; + result = MultiByteToUnicodeString(resultSys, GetCurrentCodePage()); + return true; +} +#endif + +}} diff --git a/CPP/Windows/DLL.h b/CPP/Windows/DLL.h new file mode 100755 index 00000000..bad0dd6d --- /dev/null +++ b/CPP/Windows/DLL.h @@ -0,0 +1,54 @@ +// Windows/DLL.h + +#ifndef __WINDOWS_DLL_H +#define __WINDOWS_DLL_H + +#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/CPP/Windows/Defs.h b/CPP/Windows/Defs.h new file mode 100755 index 00000000..f8c6daaa --- /dev/null +++ b/CPP/Windows/Defs.h @@ -0,0 +1,21 @@ +// Windows/Defs.h + +#ifndef __WINDOWS_DEFS_H +#define __WINDOWS_DEFS_H + +inline bool BOOLToBool(BOOL value) + { return (value != FALSE); } + +inline bool LRESULTToBool(LRESULT 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); } + +#endif diff --git a/CPP/Windows/Error.cpp b/CPP/Windows/Error.cpp new file mode 100755 index 00000000..e559c4cc --- /dev/null +++ b/CPP/Windows/Error.cpp @@ -0,0 +1,50 @@ +// Windows/Error.h + +#include "StdAfx.h" + +#include "Windows/Error.h" +#ifndef _UNICODE +#include "Common/StringConvert.h" +#endif + +#ifndef _UNICODE +extern bool g_IsNT; +#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, (LPTSTR) &msgBuf,0, NULL) == 0) + return false; + message = (LPCTSTR)msgBuf; + ::LocalFree(msgBuf); + return true; +} + +#ifndef _UNICODE +bool MyFormatMessage(DWORD messageID, UString &message) +{ + if (g_IsNT) + { + LPVOID msgBuf; + if(::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, messageID, 0, (LPWSTR) &msgBuf, 0, NULL) == 0) + return false; + message = (LPCWSTR)msgBuf; + ::LocalFree(msgBuf); + return true; + } + CSysString messageSys; + bool result = MyFormatMessage(messageID, messageSys); + message = GetUnicodeString(messageSys); + return result; +} +#endif + +}} diff --git a/CPP/Windows/Error.h b/CPP/Windows/Error.h new file mode 100755 index 00000000..4d9a9fa6 --- /dev/null +++ b/CPP/Windows/Error.h @@ -0,0 +1,33 @@ +// Windows/Error.h + +#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/CPP/Windows/FileDevice.cpp b/CPP/Windows/FileDevice.cpp new file mode 100755 index 00000000..76f1aa7a --- /dev/null +++ b/CPP/Windows/FileDevice.cpp @@ -0,0 +1,49 @@ +// Windows/FileDevice.cpp + +#include "StdAfx.h" + +#include "FileDevice.h" + +namespace NWindows { +namespace NFile { +namespace NDevice { + +bool CFileBase::GetLengthSmart(UInt64 &length) +{ + PARTITION_INFORMATION partInfo; + if (GetPartitionInfo(&partInfo)) + { + length = partInfo.PartitionLength.QuadPart; + return true; + } + DISK_GEOMETRY geom; + if (!GetGeometry(&geom)) + if (!GetCdRomGeometry(&geom)) + return false; + length = geom.Cylinders.QuadPart * geom.TracksPerCylinder * geom.SectorsPerTrack * geom.BytesPerSector; + return true; +} + +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) +{ + DWORD processedLoc = 0; + bool res = BOOLToBool(::ReadFile(_handle, data, size, &processedLoc, NULL)); + processedSize = (UInt32)processedLoc; + return res; +} + +}}} diff --git a/CPP/Windows/FileDevice.h b/CPP/Windows/FileDevice.h new file mode 100755 index 00000000..d4d71c39 --- /dev/null +++ b/CPP/Windows/FileDevice.h @@ -0,0 +1,123 @@ +// Windows/FileDevice.h + +#ifndef __WINDOWS_FILEDEVICE_H +#define __WINDOWS_FILEDEVICE_H + +#include "FileIO.h" +#include "Defs.h" + +namespace NWindows { +namespace NFile { +namespace NDevice { + +typedef struct _GET_LENGTH_INFORMATION +{ + LARGE_INTEGER Length; +} GET_LENGTH_INFORMATION, *PGET_LENGTH_INFORMATION; + +#define IOCTL_DISK_GET_LENGTH_INFO CTL_CODE(IOCTL_DISK_BASE, 0x0017, METHOD_BUFFERED, FILE_READ_ACCESS) + +/* +typedef struct _DISK_GEOMETRY_EX { + DISK_GEOMETRY Geometry; // Standard disk geometry: may be faked by driver. + LARGE_INTEGER DiskSize; // Must always be correct + BYTE Data[1]; // Partition, Detect info +} DISK_GEOMETRY_EX, *PDISK_GEOMETRY_EX; +*/ + +#define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM +#define IOCTL_CDROM_GET_DRIVE_GEOMETRY CTL_CODE(IOCTL_CDROM_BASE, 0x0013, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_CDROM_MEDIA_REMOVAL CTL_CODE(IOCTL_CDROM_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS) + +class CFileBase: public NIO::CFileBase +{ +public: + bool DeviceIoControl(DWORD controlCode, LPVOID inBuffer, DWORD inSize, + LPVOID outBuffer, DWORD outSize, LPDWORD bytesReturned, LPOVERLAPPED overlapped) const + { + return BOOLToBool(::DeviceIoControl(_handle, controlCode, inBuffer, inSize, + outBuffer, outSize, bytesReturned, overlapped)); + } + + bool DeviceIoControl(DWORD controlCode, LPVOID inBuffer, + DWORD inSize, LPVOID outBuffer, DWORD outSize) const + { + DWORD ret; + return DeviceIoControl(controlCode, inBuffer, inSize, outBuffer, outSize, &ret, 0); + } + + bool DeviceIoControlIn(DWORD controlCode, LPVOID inBuffer, DWORD inSize) const + { return DeviceIoControl(controlCode, inBuffer, inSize, NULL, 0); } + + bool DeviceIoControlOut(DWORD controlCode, LPVOID outBuffer, DWORD outSize) const + { return DeviceIoControl(controlCode, NULL, 0, outBuffer, outSize); } + + bool GetGeometry(DISK_GEOMETRY *res) const + { return DeviceIoControlOut(IOCTL_DISK_GET_DRIVE_GEOMETRY, res, sizeof(*res)); } + + bool GetCdRomGeometry(DISK_GEOMETRY *res) const + { return DeviceIoControlOut(IOCTL_CDROM_GET_DRIVE_GEOMETRY, res, sizeof(*res)); } + + /* + bool GetCdRomGeometryEx(DISK_GEOMETRY_EX *res) const + { return DeviceIoControlOut(IOCTL_CDROM_GET_DRIVE_GEOMETRY, res, sizeof(*res)); } + */ + + bool CdRomLock(bool lock) const + { + PREVENT_MEDIA_REMOVAL rem; + rem.PreventMediaRemoval = (BOOLEAN)(lock ? TRUE : FALSE); + return DeviceIoControlIn(IOCTL_CDROM_MEDIA_REMOVAL, &rem, sizeof(rem)); + } + + bool GetLengthInfo(UInt64 &length) const + { + GET_LENGTH_INFORMATION lengthInfo; + bool res = DeviceIoControlOut(IOCTL_DISK_GET_LENGTH_INFO, &lengthInfo, sizeof(lengthInfo)); + length = lengthInfo.Length.QuadPart; + return res; + } + + bool GetLengthSmart(UInt64 &length); + + + /* + bool FormatTracks(const FORMAT_PARAMETERS *formatParams, + BAD_TRACK_NUMBER *badTrackNumbers, DWORD numBadTrackNumbers, + DWORD &numBadTrackNumbersReturned) + { + DWORD ret; + // Check params, Probabably error + bool res = DeviceIoControl(IOCTL_DISK_FORMAT_TRACKS, badTrackNumbers, sizeof(*formatParams), + badTrackNumbers, numBadTrackNumbers * sizeof(*badTrackNumbers), &ret, NULL); + numBadTrackNumbersReturned = ret / sizeof(*badTrackNumbers); + return res; + } + */ + + + bool Performance(DISK_PERFORMANCE *res) + { return DeviceIoControlOut(IOCTL_DISK_PERFORMANCE, LPVOID(res), sizeof(*res)); } + + bool GetPartitionInfo(PARTITION_INFORMATION *res) + { return DeviceIoControlOut(IOCTL_DISK_GET_PARTITION_INFO, LPVOID(res), sizeof(*res)); } + + bool Verify(const VERIFY_INFORMATION *verifyInformation) + { return DeviceIoControlIn(IOCTL_DISK_VERIFY, LPVOID(verifyInformation), sizeof(*verifyInformation)); } +}; + +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); +}; + +}}} + +#endif diff --git a/CPP/Windows/FileDir.cpp b/CPP/Windows/FileDir.cpp new file mode 100755 index 00000000..c94c737d --- /dev/null +++ b/CPP/Windows/FileDir.cpp @@ -0,0 +1,835 @@ +// 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 + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { +namespace NFile { + +#if defined(WIN_LONG_PATH) && defined(_UNICODE) +#define WIN_LONG_PATH2 +#endif + +// SetCurrentDirectory doesn't support \\?\ prefix + +#ifdef WIN_LONG_PATH +bool GetLongPathBase(LPCWSTR fileName, UString &res); +bool GetLongPath(LPCWSTR fileName, UString &res); +#endif + +namespace NDirectory { + +#ifndef _UNICODE +static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; } +static UString GetUnicodePath(const CSysString &sysPath) + { return MultiByteToUnicodeString(sysPath, GetCurrentCodePage()); } +static CSysString GetSysPath(LPCWSTR sysPath) + { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); } +#endif + +bool MyGetWindowsDirectory(CSysString &path) +{ + UINT needLength = ::GetWindowsDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1); + path.ReleaseBuffer(); + return (needLength > 0 && needLength <= MAX_PATH); +} + +bool MyGetSystemDirectory(CSysString &path) +{ + UINT needLength = ::GetSystemDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1); + path.ReleaseBuffer(); + return (needLength > 0 && needLength <= MAX_PATH); +} + +#ifndef _UNICODE +bool MyGetWindowsDirectory(UString &path) +{ + if (g_IsNT) + { + UINT needLength = ::GetWindowsDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1); + path.ReleaseBuffer(); + return (needLength > 0 && needLength <= MAX_PATH); + } + CSysString sysPath; + if (!MyGetWindowsDirectory(sysPath)) + return false; + path = GetUnicodePath(sysPath); + return true; +} + +bool MyGetSystemDirectory(UString &path) +{ + if (g_IsNT) + { + UINT needLength = ::GetSystemDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1); + path.ReleaseBuffer(); + return (needLength > 0 && needLength <= MAX_PATH); + } + CSysString sysPath; + if (!MyGetSystemDirectory(sysPath)) + return false; + path = GetUnicodePath(sysPath); + return true; +} +#endif + +bool SetDirTime(LPCWSTR fileName, const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return false; + } + #endif + HANDLE hDir = ::CreateFileW(fileName, GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + #ifdef WIN_LONG_PATH + if (hDir == INVALID_HANDLE_VALUE) + { + UString longPath; + if (GetLongPath(fileName, longPath)) + hDir = ::CreateFileW(longPath, GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + } + #endif + + bool res = false; + if (hDir != INVALID_HANDLE_VALUE) + { + res = BOOLToBool(::SetFileTime(hDir, creationTime, lastAccessTime, lastWriteTime)); + ::CloseHandle(hDir); + } + return res; +} + +bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes) +{ + if (::SetFileAttributes(fileName, fileAttributes)) + return true; + #ifdef WIN_LONG_PATH2 + UString longPath; + if (GetLongPath(fileName, longPath)) + return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes)); + #endif + return false; +} + +bool MyRemoveDirectory(LPCTSTR pathName) +{ + if (::RemoveDirectory(pathName)) + return true; + #ifdef WIN_LONG_PATH2 + UString longPath; + if (GetLongPath(pathName, longPath)) + return BOOLToBool(::RemoveDirectoryW(longPath)); + #endif + return false; +} + +#ifdef WIN_LONG_PATH +bool GetLongPaths(LPCWSTR s1, LPCWSTR s2, UString &d1, UString &d2) +{ + if (!GetLongPathBase(s1, d1) || !GetLongPathBase(s2, d2)) + return false; + if (d1.IsEmpty() && d2.IsEmpty()) return false; + if (d1.IsEmpty()) d1 = s1; + if (d2.IsEmpty()) d2 = s2; + return true; +} +#endif + +bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName) +{ + if (::MoveFile(existFileName, newFileName)) + return true; + #ifdef WIN_LONG_PATH2 + UString d1, d2; + if (GetLongPaths(existFileName, newFileName, d1, d2)) + return BOOLToBool(::MoveFileW(d1, d2)); + #endif + return false; +} + +#ifndef _UNICODE +bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes) +{ + if (!g_IsNT) + return MySetFileAttributes(GetSysPath(fileName), fileAttributes); + if (::SetFileAttributesW(fileName, fileAttributes)) + return true; + #ifdef WIN_LONG_PATH + UString longPath; + if (GetLongPath(fileName, longPath)) + return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes)); + #endif + return false; +} + + +bool MyRemoveDirectory(LPCWSTR pathName) +{ + if (!g_IsNT) + return MyRemoveDirectory(GetSysPath(pathName)); + if (::RemoveDirectoryW(pathName)) + return true; + #ifdef WIN_LONG_PATH + UString longPath; + if (GetLongPath(pathName, longPath)) + return BOOLToBool(::RemoveDirectoryW(longPath)); + #endif + return false; +} + +bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName) +{ + if (!g_IsNT) + return MyMoveFile(GetSysPath(existFileName), GetSysPath(newFileName)); + if (::MoveFileW(existFileName, newFileName)) + return true; + #ifdef WIN_LONG_PATH + UString d1, d2; + if (GetLongPaths(existFileName, newFileName, d1, d2)) + return BOOLToBool(::MoveFileW(d1, d2)); + #endif + return false; +} +#endif + +bool MyCreateDirectory(LPCTSTR pathName) +{ + if (::CreateDirectory(pathName, NULL)) + return true; + #ifdef WIN_LONG_PATH2 + UString longPath; + if (GetLongPath(pathName, longPath)) + return BOOLToBool(::CreateDirectoryW(longPath, NULL)); + #endif + return false; +} + +#ifndef _UNICODE +bool MyCreateDirectory(LPCWSTR pathName) +{ + if (!g_IsNT) + return MyCreateDirectory(GetSysPath(pathName)); + if (::CreateDirectoryW(pathName, NULL)) + return true; + #ifdef WIN_LONG_PATH + UString longPath; + if (GetLongPath(pathName, longPath)) + return BOOLToBool(::CreateDirectoryW(longPath, NULL)); + #endif + return false; +} +#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(CHAR_PATH_SEPARATOR)); + 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(); + for (;;) + { + 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(CHAR_PATH_SEPARATOR)); + 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(CHAR_PATH_SEPARATOR), 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(WCHAR_PATH_SEPARATOR); + 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(); + for (;;) + { + 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(WCHAR_PATH_SEPARATOR); + if (pos < 0 || pos == 0) + return false; + if (pathName[pos - 1] == L':') + return false; + pathName = pathName.Left(pos); + } + pathName = pathName2; + while(pos < pathName.Length()) + { + pos = pathName.Find(WCHAR_PATH_SEPARATOR, pos + 1); + if (pos < 0) + pos = pathName.Length(); + if (!MyCreateDirectory(pathName.Left(pos))) + return false; + } + return true; +} + +#endif + +bool DeleteFileAlways(LPCTSTR name) +{ + if (!MySetFileAttributes(name, 0)) + return false; + if (::DeleteFile(name)) + return true; + #ifdef WIN_LONG_PATH2 + UString longPath; + if (GetLongPath(name, longPath)) + return BOOLToBool(::DeleteFileW(longPath)); + #endif + return false; +} + +#ifndef _UNICODE +bool DeleteFileAlways(LPCWSTR name) +{ + if (!g_IsNT) + return DeleteFileAlways(GetSysPath(name)); + if (!MySetFileAttributes(name, 0)) + return false; + if (::DeleteFileW(name)) + return true; + #ifdef WIN_LONG_PATH + UString longPath; + if (GetLongPath(name, longPath)) + return BOOLToBool(::DeleteFileW(longPath)); + #endif + return false; +} +#endif + +static bool RemoveDirectorySubItems2(const CSysString pathPrefix, const NFind::CFileInfo &fileInfo) +{ + if(fileInfo.IsDirectory()) + return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name); + 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 (!MySetFileAttributes(path, 0)) + return false; + return MyRemoveDirectory(path); +} + +#ifndef _UNICODE +static bool RemoveDirectorySubItems2(const UString pathPrefix, const NFind::CFileInfoW &fileInfo) +{ + if(fileInfo.IsDirectory()) + return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name); + 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(); + return (needLength > 0 && needLength < MAX_PATH); +} + +bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, int &fileNamePartStartIndex) +{ + resultPath.Empty(); + LPTSTR fileNamePointer = 0; + LPTSTR buffer = resultPath.GetBuffer(MAX_PATH); + DWORD needLength = ::GetFullPathName(fileName, MAX_PATH + 1, buffer, &fileNamePointer); + resultPath.ReleaseBuffer(); + if (needLength == 0) + return false; + if (needLength >= MAX_PATH) + { + #ifdef WIN_LONG_PATH2 + needLength++; + buffer = resultPath.GetBuffer(needLength + 1); + DWORD needLength2 = ::GetFullPathNameW(fileName, needLength, buffer, &fileNamePointer); + resultPath.ReleaseBuffer(); + if (needLength2 == 0 || needLength2 > needLength) + #endif + return false; + } + if (fileNamePointer == 0) + fileNamePartStartIndex = lstrlen(fileName); + else + fileNamePartStartIndex = (int)(fileNamePointer - buffer); + return true; +} + +#ifndef _UNICODE +bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex) +{ + resultPath.Empty(); + if (g_IsNT) + { + LPWSTR fileNamePointer = 0; + LPWSTR buffer = resultPath.GetBuffer(MAX_PATH); + DWORD needLength = ::GetFullPathNameW(fileName, MAX_PATH + 1, buffer, &fileNamePointer); + resultPath.ReleaseBuffer(); + if (needLength == 0) + return false; + if (needLength >= MAX_PATH) + { + #ifdef WIN_LONG_PATH + needLength++; + buffer = resultPath.GetBuffer(needLength + 1); + DWORD needLength2 = ::GetFullPathNameW(fileName, needLength, buffer, &fileNamePointer); + resultPath.ReleaseBuffer(); + if (needLength2 == 0 || needLength2 > needLength) + #endif + return false; + } + if (fileNamePointer == 0) + fileNamePartStartIndex = MyStringLen(fileName); + else + fileNamePartStartIndex = (int)(fileNamePointer - buffer); + } + else + { + CSysString sysPath; + if (!MyGetFullPathName(GetSysPath(fileName), sysPath, fileNamePartStartIndex)) + return false; + UString resultPath1 = GetUnicodePath(sysPath.Left(fileNamePartStartIndex)); + UString resultPath2 = GetUnicodePath(sysPath.Mid(fileNamePartStartIndex)); + fileNamePartStartIndex = resultPath1.Length(); + resultPath = resultPath1 + resultPath2; + } + 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 (g_IsNT) + return BOOLToBool(::SetCurrentDirectoryW(path)); + return MySetCurrentDirectory(GetSysPath(path)); +} +bool MyGetCurrentDirectory(UString &path) +{ + if (g_IsNT) + { + DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1)); + path.ReleaseBuffer(); + return (needLength > 0 && needLength <= MAX_PATH); + } + CSysString sysPath; + if (!MyGetCurrentDirectory(sysPath)) + return false; + path = GetUnicodePath(sysPath); + 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 + 1), &filePartPointer); + filePart = (UINT32)(filePartPointer - (LPCTSTR)resultPath); + resultPath.ReleaseBuffer(); + return (value > 0 && value <= MAX_PATH); +} + +#ifndef _UNICODE +bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension, + UString &resultPath, UINT32 &filePart) +{ + if (g_IsNT) + { + LPWSTR filePartPointer = 0; + DWORD value = ::SearchPathW(path, fileName, extension, + MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer); + filePart = (UINT32)(filePartPointer - (LPCWSTR)resultPath); + resultPath.ReleaseBuffer(); + return (value > 0 && value <= MAX_PATH); + } + + CSysString sysPath; + if (!MySearchPath( + path != 0 ? (LPCTSTR)GetSysPath(path): 0, + fileName != 0 ? (LPCTSTR)GetSysPath(fileName): 0, + extension != 0 ? (LPCTSTR)GetSysPath(extension): 0, + sysPath, filePart)) + return false; + UString resultPath1 = GetUnicodePath(sysPath.Left(filePart)); + UString resultPath2 = GetUnicodePath(sysPath.Mid(filePart)); + filePart = resultPath1.Length(); + resultPath = resultPath1 + resultPath2; + return true; +} +#endif + +bool MyGetTempPath(CSysString &path) +{ + DWORD needLength = ::GetTempPath(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1)); + path.ReleaseBuffer(); + return (needLength > 0 && needLength <= MAX_PATH); +} + +#ifndef _UNICODE +bool MyGetTempPath(UString &path) +{ + path.Empty(); + if (g_IsNT) + { + DWORD needLength = ::GetTempPathW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1)); + path.ReleaseBuffer(); + return (needLength > 0 && needLength <= MAX_PATH); + } + CSysString sysPath; + if (!MyGetTempPath(sysPath)) + return false; + path = GetUnicodePath(sysPath); + return true; +} +#endif + +UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &path) +{ + UINT number = ::GetTempFileName(dirPath, prefix, 0, path.GetBuffer(MAX_PATH + 1)); + path.ReleaseBuffer(); + return number; +} + +#ifndef _UNICODE +UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &path) +{ + if (g_IsNT) + { + UINT number = ::GetTempFileNameW(dirPath, prefix, 0, path.GetBuffer(MAX_PATH)); + path.ReleaseBuffer(); + return number; + } + CSysString sysPath; + UINT number = MyGetTempFileName( + dirPath ? (LPCTSTR)GetSysPath(dirPath): 0, + prefix ? (LPCTSTR)GetSysPath(prefix): 0, + sysPath); + path = GetUnicodePath(sysPath); + 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(); + */ + for (;;) + { + 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(); + */ + for (;;) + { + 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/CPP/Windows/FileDir.h b/CPP/Windows/FileDir.h new file mode 100755 index 00000000..3ebf3e63 --- /dev/null +++ b/CPP/Windows/FileDir.h @@ -0,0 +1,178 @@ +// Windows/FileDir.h + +#ifndef __WINDOWS_FILEDIR_H +#define __WINDOWS_FILEDIR_H + +#include "../Common/String.h" +#include "Defs.h" + +namespace NWindows { +namespace NFile { +namespace NDirectory { + +#ifdef WIN_LONG_PATH +bool GetLongPaths(LPCWSTR s1, LPCWSTR s2, UString &d1, UString &d2); +#endif + +bool MyGetWindowsDirectory(CSysString &path); +bool MyGetSystemDirectory(CSysString &path); +#ifndef _UNICODE +bool MyGetWindowsDirectory(UString &path); +bool MyGetSystemDirectory(UString &path); +#endif + +bool SetDirTime(LPCWSTR fileName, const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime); + +bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes); +bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName); +bool MyRemoveDirectory(LPCTSTR pathName); +bool MyCreateDirectory(LPCTSTR pathName); +bool CreateComplexDirectory(LPCTSTR pathName); +bool DeleteFileAlways(LPCTSTR name); +bool RemoveDirectoryWithSubItems(const CSysString &path); + +#ifndef _UNICODE +bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes); +bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName); +bool MyRemoveDirectory(LPCWSTR pathName); +bool MyCreateDirectory(LPCWSTR pathName); +bool CreateComplexDirectory(LPCWSTR pathName); +bool DeleteFileAlways(LPCWSTR name); +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); + } + void DisableDeleting() { _mustBeDeleted = false; } +}; + +#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); + } + void DisableDeleting() { _mustBeDeleted = false; } +}; +#endif + +}}} + +#endif diff --git a/CPP/Windows/FileFind.cpp b/CPP/Windows/FileFind.cpp new file mode 100755 index 00000000..3b5bdf70 --- /dev/null +++ b/CPP/Windows/FileFind.cpp @@ -0,0 +1,408 @@ +// Windows/FileFind.cpp + +#include "StdAfx.h" + +#include "FileFind.h" +#ifndef _UNICODE +#include "../Common/StringConvert.h" +#endif + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { +namespace NFile { + +#if defined(WIN_LONG_PATH) && defined(_UNICODE) +#define WIN_LONG_PATH2 +#endif + +bool GetLongPath(LPCWSTR fileName, UString &res); + +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 (_handle == INVALID_HANDLE_VALUE) + return true; + if (!::FindClose(_handle)) + return false; + _handle = INVALID_HANDLE_VALUE; + return true; +} + + +bool CFindFile::FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo) +{ + if (!Close()) + return false; + WIN32_FIND_DATA findData; + _handle = ::FindFirstFile(wildcard, &findData); + #ifdef WIN_LONG_PATH2 + if (_handle == INVALID_HANDLE_VALUE) + { + UString longPath; + if (GetLongPath(wildcard, longPath)) + _handle = ::FindFirstFileW(longPath, &findData); + } + #endif + if (_handle == INVALID_HANDLE_VALUE) + return false; + ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo); + return true; +} + +#ifndef _UNICODE +bool CFindFile::FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo) +{ + if (!Close()) + return false; + if (g_IsNT) + { + WIN32_FIND_DATAW findData; + _handle = ::FindFirstFileW(wildcard, &findData); + #ifdef WIN_LONG_PATH + if (_handle == INVALID_HANDLE_VALUE) + { + UString longPath; + if (GetLongPath(wildcard, longPath)) + _handle = ::FindFirstFileW(longPath, &findData); + } + #endif + if (_handle != INVALID_HANDLE_VALUE) + ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo); + } + else + { + WIN32_FIND_DATAA findData; + _handle = ::FindFirstFileA(UnicodeStringToMultiByte(wildcard, + GetCurrentCodePage()), &findData); + if (_handle != INVALID_HANDLE_VALUE) + ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo); + } + return (_handle != INVALID_HANDLE_VALUE); +} +#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) +{ + if (g_IsNT) + { + WIN32_FIND_DATAW findData; + if (!::FindNextFileW(_handle, &findData)) + return false; + ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo); + } + else + { + WIN32_FIND_DATAA findData; + if (!::FindNextFileA(_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) +{ + for (;;) + { + if (!NextAny(fileInfo)) + return false; + if (!fileInfo.IsDots()) + return true; + } +} + +bool CEnumerator::Next(CFileInfo &fileInfo, bool &found) +{ + if (Next(fileInfo)) + { + found = true; + return true; + } + found = false; + return (::GetLastError() == ERROR_NO_MORE_FILES); +} + +#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) +{ + for (;;) + { + if (!NextAny(fileInfo)) + return false; + if (!fileInfo.IsDots()) + return true; + } +} + +bool CEnumeratorW::Next(CFileInfoW &fileInfo, bool &found) +{ + if (Next(fileInfo)) + { + found = true; + return true; + } + found = false; + return (::GetLastError() == ERROR_NO_MORE_FILES); +} + +#endif + +//////////////////////////////// +// CFindChangeNotification +// FindFirstChangeNotification can return 0. MSDN doesn't tell about it. + +bool CFindChangeNotification::Close() +{ + if (!IsHandleAllocated()) + return true; + if (!::FindCloseChangeNotification(_handle)) + return false; + _handle = INVALID_HANDLE_VALUE; + return true; +} + +HANDLE CFindChangeNotification::FindFirst(LPCTSTR pathName, bool watchSubtree, DWORD notifyFilter) +{ + _handle = ::FindFirstChangeNotification(pathName, BoolToBOOL(watchSubtree), notifyFilter); + #ifdef WIN_LONG_PATH2 + if (!IsHandleAllocated()) + { + UString longPath; + if (GetLongPath(pathName, longPath)) + _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter); + } + #endif + return _handle; +} + +#ifndef _UNICODE +HANDLE CFindChangeNotification::FindFirst(LPCWSTR pathName, bool watchSubtree, DWORD notifyFilter) +{ + if (!g_IsNT) + return FindFirst(UnicodeStringToMultiByte(pathName, GetCurrentCodePage()), watchSubtree, notifyFilter); + _handle = ::FindFirstChangeNotificationW(pathName, BoolToBOOL(watchSubtree), notifyFilter); + #ifdef WIN_LONG_PATH + if (!IsHandleAllocated()) + { + UString longPath; + if (GetLongPath(pathName, longPath)) + _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter); + } + #endif + return _handle; +} +#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; +} + +#ifndef _UNICODE +bool MyGetLogicalDriveStrings(UStringVector &driveStrings) +{ + driveStrings.Clear(); + if (g_IsNT) + { + UINT32 size = GetLogicalDriveStringsW(0, NULL); + if (size == 0) + return false; + UString buffer; + UINT32 newSize = GetLogicalDriveStringsW(size, buffer.GetBuffer(size)); + if (newSize == 0) + return false; + if (newSize > size) + return false; + UString string; + for(UINT32 i = 0; i < newSize; i++) + { + WCHAR c = buffer[i]; + if (c == L'\0') + { + driveStrings.Add(string); + string.Empty(); + } + else + string += c; + } + return string.IsEmpty(); + } + CSysStringVector driveStringsA; + bool res = MyGetLogicalDriveStrings(driveStringsA); + for (int i = 0; i < driveStringsA.Size(); i++) + driveStrings.Add(GetUnicodeString(driveStringsA[i])); + return res; +} +#endif + +#endif + +}}} diff --git a/CPP/Windows/FileFind.h b/CPP/Windows/FileFind.h new file mode 100755 index 00000000..4d2439aa --- /dev/null +++ b/CPP/Windows/FileFind.h @@ -0,0 +1,153 @@ +// Windows/FileFind.h + +#ifndef __WINDOWS_FILEFIND_H +#define __WINDOWS_FILEFIND_H + +#include "../Common/String.h" +#include "../Common/Types.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; +public: + bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE; } + CFindFile(): _handle(INVALID_HANDLE_VALUE) {} + ~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); + bool Next(CFileInfo &fileInfo, bool &found); +}; + +#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); + bool Next(CFileInfoW &fileInfo, bool &found); +}; +#endif + +class CFindChangeNotification +{ + HANDLE _handle; +public: + operator HANDLE () { return _handle; } + bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE && _handle != 0; } + CFindChangeNotification(): _handle(INVALID_HANDLE_VALUE) {} + ~CFindChangeNotification() { Close(); } + bool Close(); + 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); +#ifndef _UNICODE +bool MyGetLogicalDriveStrings(UStringVector &driveStrings); +#endif +#endif + +}}} + +#endif + diff --git a/CPP/Windows/FileIO.cpp b/CPP/Windows/FileIO.cpp new file mode 100755 index 00000000..efad8582 --- /dev/null +++ b/CPP/Windows/FileIO.cpp @@ -0,0 +1,305 @@ +// Windows/FileIO.cpp + +#include "StdAfx.h" + +#include "FileIO.h" +#include "Defs.h" +#ifdef WIN_LONG_PATH +#include "../Common/String.h" +#endif +#ifndef _UNICODE +#include "../Common/StringConvert.h" +#endif + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { +namespace NFile { + +#if defined(WIN_LONG_PATH) && defined(_UNICODE) +#define WIN_LONG_PATH2 +#endif + +#ifdef WIN_LONG_PATH +bool GetLongPathBase(LPCWSTR s, UString &res) +{ + res.Empty(); + int len = MyStringLen(s); + wchar_t c = s[0]; + if (len < 1 || c == L'\\' || c == L'.' && (len == 1 || len == 2 && s[1] == L'.')) + return true; + UString curDir; + if (len > 3) + if (s[1] != L':' || s[2] != L'\\' || !(c >= L'a' && c <= L'z' || c >= L'A' && c <= L'Z')) + { + DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, curDir.GetBuffer(MAX_PATH + 1)); + curDir.ReleaseBuffer(); + if (needLength == 0 || needLength > MAX_PATH) + return false; + if (curDir[curDir.Length() - 1] != L'\\') + curDir += L'\\'; + } + res = UString(L"\\\\?\\") + curDir + s; + return true; +} + +bool GetLongPath(LPCWSTR path, UString &longPath) +{ + if (GetLongPathBase(path, longPath)) + return !longPath.IsEmpty(); + return false; +} +#endif + +namespace NIO { + +CFileBase::~CFileBase() { Close(); } + +bool CFileBase::Create(LPCTSTR fileName, DWORD desiredAccess, + DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) +{ + if (!Close()) + return false; + _handle = ::CreateFile(fileName, desiredAccess, shareMode, + (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, + flagsAndAttributes, (HANDLE)NULL); + #ifdef WIN_LONG_PATH2 + if (_handle == INVALID_HANDLE_VALUE) + { + UString longPath; + if (GetLongPath(fileName, longPath)) + _handle = ::CreateFileW(longPath, desiredAccess, shareMode, + (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, + flagsAndAttributes, (HANDLE)NULL); + } + #endif + return (_handle != INVALID_HANDLE_VALUE); +} + +#ifndef _UNICODE +bool CFileBase::Create(LPCWSTR fileName, DWORD desiredAccess, + DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) +{ + if (!g_IsNT) + return Create(UnicodeStringToMultiByte(fileName, ::AreFileApisANSI() ? CP_ACP : CP_OEMCP), + desiredAccess, shareMode, creationDisposition, flagsAndAttributes); + if (!Close()) + return false; + _handle = ::CreateFileW(fileName, desiredAccess, shareMode, + (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, + flagsAndAttributes, (HANDLE)NULL); + #ifdef WIN_LONG_PATH + if (_handle == INVALID_HANDLE_VALUE) + { + UString longPath; + if (GetLongPath(fileName, longPath)) + _handle = ::CreateFileW(longPath, desiredAccess, shareMode, + (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, + flagsAndAttributes, (HANDLE)NULL); + } + #endif + return (_handle != INVALID_HANDLE_VALUE); +} +#endif + +bool CFileBase::Close() +{ + if (_handle == INVALID_HANDLE_VALUE) + return true; + if (!::CloseHandle(_handle)) + return false; + _handle = INVALID_HANDLE_VALUE; + return true; +} + +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 value; + value.QuadPart = distanceToMove; + value.LowPart = ::SetFilePointer(_handle, value.LowPart, &value.HighPart, moveMethod); + if (value.LowPart == 0xFFFFFFFF) + if(::GetLastError() != NO_ERROR) + return false; + newPosition = value.QuadPart; + 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 + +// ReadFile and WriteFile functions in Windows have BUG: +// If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) +// from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES +// (Insufficient system resources exist to complete the requested service). + +static UInt32 kChunkSizeMax = (1 << 24); + +bool CInFile::ReadPart(void *data, UInt32 size, UInt32 &processedSize) +{ + if (size > kChunkSizeMax) + size = kChunkSizeMax; + DWORD processedLoc = 0; + bool res = BOOLToBool(::ReadFile(_handle, data, size, &processedLoc, NULL)); + processedSize = (UInt32)processedLoc; + return res; +} + +bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize) +{ + processedSize = 0; + do + { + UInt32 processedLoc = 0; + bool res = ReadPart(data, size, processedLoc); + processedSize += processedLoc; + if (!res) + return false; + if (processedLoc == 0) + return true; + data = (void *)((unsigned char *)data + processedLoc); + size -= processedLoc; + } + while (size > 0); + return true; +} + +///////////////////////// +// COutFile + +bool COutFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) + { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); } + +static inline DWORD GetCreationDisposition(bool createAlways) + { return createAlways? CREATE_ALWAYS: CREATE_NEW; } + +bool COutFile::Open(LPCTSTR fileName, DWORD creationDisposition) + { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); } + +bool COutFile::Create(LPCTSTR fileName, bool createAlways) + { return Open(fileName, GetCreationDisposition(createAlways)); } + +#ifndef _UNICODE + +bool COutFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) + { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); } + +bool COutFile::Open(LPCWSTR fileName, DWORD creationDisposition) + { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); } + +bool COutFile::Create(LPCWSTR fileName, bool createAlways) + { return Open(fileName, GetCreationDisposition(createAlways)); } + +#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::WritePart(const void *data, UInt32 size, UInt32 &processedSize) +{ + if (size > kChunkSizeMax) + size = kChunkSizeMax; + DWORD processedLoc = 0; + bool res = BOOLToBool(::WriteFile(_handle, data, size, &processedLoc, NULL)); + processedSize = (UInt32)processedLoc; + return res; +} + +bool COutFile::Write(const void *data, UInt32 size, UInt32 &processedSize) +{ + processedSize = 0; + do + { + UInt32 processedLoc = 0; + bool res = WritePart(data, size, processedLoc); + processedSize += processedLoc; + if (!res) + return false; + if (processedLoc == 0) + return true; + data = (const void *)((const unsigned char *)data + processedLoc); + size -= processedLoc; + } + while (size > 0); + return true; +} + +bool COutFile::SetEndOfFile() { 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/CPP/Windows/FileIO.h b/CPP/Windows/FileIO.h new file mode 100755 index 00000000..ec936ac6 --- /dev/null +++ b/CPP/Windows/FileIO.h @@ -0,0 +1,97 @@ +// Windows/FileIO.h + +#ifndef __WINDOWS_FILEIO_H +#define __WINDOWS_FILEIO_H + +#include "../Common/Types.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: + 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(): _handle(INVALID_HANDLE_VALUE){}; + 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 ReadPart(void *data, UInt32 size, UInt32 &processedSize); + 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, DWORD creationDisposition); + bool Create(LPCTSTR fileName, bool createAlways); + + #ifndef _UNICODE + bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); + bool Open(LPCWSTR fileName, DWORD creationDisposition); + bool Create(LPCWSTR fileName, bool createAlways); + #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 WritePart(const void *data, UInt32 size, UInt32 &processedSize); + bool Write(const void *data, UInt32 size, UInt32 &processedSize); + bool SetEndOfFile(); + bool SetLength(UInt64 length); +}; + +}}} + +#endif diff --git a/CPP/Windows/FileMapping.cpp b/CPP/Windows/FileMapping.cpp new file mode 100755 index 00000000..d884afb1 --- /dev/null +++ b/CPP/Windows/FileMapping.cpp @@ -0,0 +1,14 @@ +// Windows/FileMapping.cpp + +#include "StdAfx.h" + +#include "Windows/FileMapping.h" + +namespace NWindows { +namespace NFile { +namespace NMapping { + + + + +}}} \ No newline at end of file diff --git a/CPP/Windows/FileMapping.h b/CPP/Windows/FileMapping.h new file mode 100755 index 00000000..22db8f17 --- /dev/null +++ b/CPP/Windows/FileMapping.h @@ -0,0 +1,50 @@ +// Windows/FileMapping.h + +#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/CPP/Windows/FileName.cpp b/CPP/Windows/FileName.cpp new file mode 100755 index 00000000..49e957cf --- /dev/null +++ b/CPP/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/CPP/Windows/FileName.h b/CPP/Windows/FileName.h new file mode 100755 index 00000000..f8567652 --- /dev/null +++ b/CPP/Windows/FileName.h @@ -0,0 +1,43 @@ +// Windows/FileName.h + +#ifndef __WINDOWS_FILENAME_H +#define __WINDOWS_FILENAME_H + +#include "../Common/String.h" + +namespace NWindows { +namespace NFile { +namespace NName { + +const TCHAR kDirDelimiter = CHAR_PATH_SEPARATOR; +const TCHAR kAnyStringWildcard = '*'; + +void NormalizeDirPathPrefix(CSysString &dirPath); // ensures that it ended with '\\' +#ifndef _UNICODE +void NormalizeDirPathPrefix(UString &dirPath); // ensures that it ended with '\\' +#endif + +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/CPP/Windows/FileSystem.cpp b/CPP/Windows/FileSystem.cpp new file mode 100755 index 00000000..37c76856 --- /dev/null +++ b/CPP/Windows/FileSystem.cpp @@ -0,0 +1,126 @@ +// Windows/FileSystem.cpp + +#include "StdAfx.h" + +#include "FileSystem.h" +#include "Defs.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +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; +} + + +#ifndef _UNICODE +bool MyGetVolumeInformation( + LPCWSTR rootPathName, + UString &volumeName, + LPDWORD volumeSerialNumber, + LPDWORD maximumComponentLength, + LPDWORD fileSystemFlags, + UString &fileSystemName) +{ + if (g_IsNT) + { + bool result = BOOLToBool(GetVolumeInformationW( + rootPathName, + volumeName.GetBuffer(MAX_PATH), MAX_PATH, + volumeSerialNumber, + maximumComponentLength, + fileSystemFlags, + fileSystemName.GetBuffer(MAX_PATH), MAX_PATH)); + volumeName.ReleaseBuffer(); + fileSystemName.ReleaseBuffer(); + return result; + } + AString volumeNameA, fileSystemNameA; + bool result = MyGetVolumeInformation(GetSystemString(rootPathName), volumeNameA, + volumeSerialNumber, maximumComponentLength, fileSystemFlags,fileSystemNameA); + if (result) + { + volumeName = GetUnicodeString(volumeNameA); + fileSystemName = GetUnicodeString(fileSystemNameA); + } + return result; +} +#endif + +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) + { + ULARGE_INTEGER i64FreeBytesToCaller, totalSize2, freeSize2; + sizeIsDetected = BOOLToBool(pGetDiskFreeSpaceEx(rootPathName, + &i64FreeBytesToCaller, + &totalSize2, + &freeSize2)); + totalSize = totalSize2.QuadPart; + freeSize = freeSize2.QuadPart; + } + + 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; +} + +#ifndef _UNICODE +bool MyGetDiskFreeSpace(LPCWSTR rootPathName, + UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize) +{ + return MyGetDiskFreeSpace(GetSystemString(rootPathName), clusterSize, totalSize, freeSize); +} +#endif + +}}} diff --git a/CPP/Windows/FileSystem.h b/CPP/Windows/FileSystem.h new file mode 100755 index 00000000..25488804 --- /dev/null +++ b/CPP/Windows/FileSystem.h @@ -0,0 +1,51 @@ +// Windows/FileSystem.h + +#ifndef __WINDOWS_FILESYSTEM_H +#define __WINDOWS_FILESYSTEM_H + +#include "../Common/String.h" +#include "../Common/Types.h" + +#ifndef _UNICODE +#include "../Common/StringConvert.h" +#endif + +namespace NWindows { +namespace NFile { +namespace NSystem { + +bool MyGetVolumeInformation( + LPCTSTR rootPathName, + CSysString &volumeName, + LPDWORD volumeSerialNumber, + LPDWORD maximumComponentLength, + LPDWORD fileSystemFlags, + CSysString &fileSystemName); + +#ifndef _UNICODE +bool MyGetVolumeInformation( + LPCWSTR rootPathName, + UString &volumeName, + LPDWORD volumeSerialNumber, + LPDWORD maximumComponentLength, + LPDWORD fileSystemFlags, + UString &fileSystemName); +#endif + +inline UINT MyGetDriveType(LPCTSTR pathName) { return GetDriveType(pathName); } +#ifndef _UNICODE +inline UINT MyGetDriveType(LPCWSTR pathName) { return GetDriveType(GetSystemString(pathName)); } +#endif + +bool MyGetDiskFreeSpace(LPCTSTR rootPathName, + UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize); + +#ifndef _UNICODE +bool MyGetDiskFreeSpace(LPCWSTR rootPathName, + UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize); +#endif + +}}} + +#endif + diff --git a/CPP/Windows/Handle.h b/CPP/Windows/Handle.h new file mode 100755 index 00000000..d4d8aae5 --- /dev/null +++ b/CPP/Windows/Handle.h @@ -0,0 +1,37 @@ +// Windows/Handle.h + +#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/CPP/Windows/Memory.cpp b/CPP/Windows/Memory.cpp new file mode 100755 index 00000000..435ea999 --- /dev/null +++ b/CPP/Windows/Memory.cpp @@ -0,0 +1,64 @@ +// Windows/Memory.cpp + +#include "StdAfx.h" + +#include "Windows/Memory.h" + +namespace NWindows { +namespace NMemory { + +CGlobal::~CGlobal() +{ + Free(); +} + +bool CGlobal::Alloc(UINT flags, SIZE_T size) +{ + HGLOBAL newBlock = ::GlobalAlloc(flags, size); + if (newBlock == NULL) + return false; + m_MemoryHandle = newBlock; + return true; +} + +bool CGlobal::Free() +{ + if (m_MemoryHandle == NULL) + return true; + m_MemoryHandle = ::GlobalFree(m_MemoryHandle); + return (m_MemoryHandle == NULL); +} + +void CGlobal::Attach(HGLOBAL hGlobal) +{ + Free(); + m_MemoryHandle = hGlobal; +} + +HGLOBAL CGlobal::Detach() +{ + HGLOBAL h = m_MemoryHandle; + m_MemoryHandle = NULL; + return h; +} + +LPVOID CGlobal::Lock() const +{ + return ::GlobalLock(m_MemoryHandle); +} + +void CGlobal::Unlock() const +{ + ::GlobalUnlock(m_MemoryHandle); +} + +bool CGlobal::ReAlloc(SIZE_T size) +{ + HGLOBAL newBlock = ::GlobalReAlloc(m_MemoryHandle, size, GMEM_MOVEABLE); + if (newBlock == NULL) + return false; + m_MemoryHandle = newBlock; + return true; +} + +}} diff --git a/CPP/Windows/Memory.h b/CPP/Windows/Memory.h new file mode 100755 index 00000000..bd8773b8 --- /dev/null +++ b/CPP/Windows/Memory.h @@ -0,0 +1,45 @@ +// Windows/Memory.h + +#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; }; + void Attach(HGLOBAL hGlobal); + HGLOBAL Detach(); + bool Alloc(UINT flags, SIZE_T size); + bool Free(); + LPVOID Lock() const; + void Unlock() const; + bool ReAlloc(SIZE_T size); +}; + + +class CGlobalLock +{ + HGLOBAL m_Global; + LPVOID m_Pointer; +public: + LPVOID GetPointer() const { return m_Pointer; } + CGlobalLock(HGLOBAL hGlobal): m_Global(hGlobal) + { + m_Pointer = ::GlobalLock(hGlobal); + }; + ~CGlobalLock() + { + if(m_Pointer != NULL) + ::GlobalUnlock(m_Global); + } +}; + +}} + +#endif diff --git a/CPP/Windows/MemoryLock.cpp b/CPP/Windows/MemoryLock.cpp new file mode 100755 index 00000000..b468e528 --- /dev/null +++ b/CPP/Windows/MemoryLock.cpp @@ -0,0 +1,78 @@ +// Common/MemoryLock.cpp + +#include "StdAfx.h" + +namespace NWindows { +namespace NSecurity { + +#ifndef _UNICODE +typedef BOOL (WINAPI * OpenProcessTokenP)(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle); +typedef BOOL (WINAPI * LookupPrivilegeValueP)(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid); +typedef BOOL (WINAPI * AdjustTokenPrivilegesP)(HANDLE TokenHandle, BOOL DisableAllPrivileges, + PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState,PDWORD ReturnLength); +#endif + +#ifdef _UNICODE +bool EnableLockMemoryPrivilege( +#else +static bool EnableLockMemoryPrivilege2(HMODULE hModule, +#endif +bool enable) +{ + #ifndef _UNICODE + if (hModule == NULL) + return false; + OpenProcessTokenP openProcessToken = (OpenProcessTokenP)GetProcAddress(hModule, "OpenProcessToken"); + LookupPrivilegeValueP lookupPrivilegeValue = (LookupPrivilegeValueP)GetProcAddress(hModule, "LookupPrivilegeValueA" ); + AdjustTokenPrivilegesP adjustTokenPrivileges = (AdjustTokenPrivilegesP)GetProcAddress(hModule, "AdjustTokenPrivileges"); + if (openProcessToken == NULL || adjustTokenPrivileges == NULL || lookupPrivilegeValue == NULL) + return false; + #endif + + HANDLE token; + if (! + #ifdef _UNICODE + ::OpenProcessToken + #else + openProcessToken + #endif + (::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) + return false; + TOKEN_PRIVILEGES tp; + bool res = false; + if ( + #ifdef _UNICODE + ::LookupPrivilegeValue + #else + lookupPrivilegeValue + #endif + (NULL, SE_LOCK_MEMORY_NAME, &(tp.Privileges[0].Luid))) + { + tp.PrivilegeCount = 1; + tp.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED: 0; + if ( + #ifdef _UNICODE + ::AdjustTokenPrivileges + #else + adjustTokenPrivileges + #endif + (token, FALSE, &tp, 0, NULL, NULL)) + res = (GetLastError() == ERROR_SUCCESS); + } + ::CloseHandle(token); + return res; +} + +#ifndef _UNICODE +bool EnableLockMemoryPrivilege(bool enable) +{ + HMODULE hModule = LoadLibrary(TEXT("Advapi32.dll")); + if(hModule == NULL) + return false; + bool res = EnableLockMemoryPrivilege2(hModule, enable); + ::FreeLibrary(hModule); + return res; +} +#endif + +}} diff --git a/CPP/Windows/MemoryLock.h b/CPP/Windows/MemoryLock.h new file mode 100755 index 00000000..03a88b41 --- /dev/null +++ b/CPP/Windows/MemoryLock.h @@ -0,0 +1,13 @@ +// Windows/MemoryLock.h + +#ifndef __WINDOWS_MEMORYLOCK_H +#define __WINDOWS_MEMORYLOCK_H + +namespace NWindows { +namespace NSecurity { + +bool EnableLockMemoryPrivilege(bool enable = true); + +}} + +#endif diff --git a/CPP/Windows/Menu.cpp b/CPP/Windows/Menu.cpp new file mode 100755 index 00000000..5869b365 --- /dev/null +++ b/CPP/Windows/Menu.cpp @@ -0,0 +1,178 @@ +// Windows/Menu.cpp + +#include "StdAfx.h" + +#ifndef _UNICODE +#include "Common/StringConvert.h" +#endif +#include "Windows/Menu.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { + +static void ConvertItemToSysForm(const CMenuItem &item, MENUITEMINFOW &si) +{ + ZeroMemory(&si, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = item.fMask; + si.fType = item.fType; + si.fState = item.fState; + si.wID = item.wID; + si.hSubMenu = item.hSubMenu; + si.hbmpChecked = item.hbmpChecked; + si.hbmpUnchecked = item.hbmpUnchecked; + si.dwItemData = item.dwItemData; +} + +#ifndef _UNICODE +static void ConvertItemToSysForm(const CMenuItem &item, MENUITEMINFOA &si) +{ + ZeroMemory(&si, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = item.fMask; + si.fType = item.fType; + si.fState = item.fState; + si.wID = item.wID; + si.hSubMenu = item.hSubMenu; + si.hbmpChecked = item.hbmpChecked; + si.hbmpUnchecked = item.hbmpUnchecked; + si.dwItemData = item.dwItemData; +} +#endif + +static void ConvertItemToMyForm(const MENUITEMINFOW &si, CMenuItem &item) +{ + item.fMask = si.fMask; + item.fType = si.fType; + item.fState = si.fState; + item.wID = si.wID; + item.hSubMenu = si.hSubMenu; + item.hbmpChecked = si.hbmpChecked; + item.hbmpUnchecked = si.hbmpUnchecked; + item.dwItemData = si.dwItemData; +} + +#ifndef _UNICODE +static void ConvertItemToMyForm(const MENUITEMINFOA &si, CMenuItem &item) +{ + item.fMask = si.fMask; + item.fType = si.fType; + item.fState = si.fState; + item.wID = si.wID; + item.hSubMenu = si.hSubMenu; + item.hbmpChecked = si.hbmpChecked; + item.hbmpUnchecked = si.hbmpUnchecked; + item.dwItemData = si.dwItemData; +} +#endif + +bool CMenu::GetItem(UINT itemIndex, bool byPosition, CMenuItem &item) +{ + const UINT kMaxSize = 512; + #ifndef _UNICODE + if (!g_IsNT) + { + CHAR s[kMaxSize + 1]; + MENUITEMINFOA si; + ConvertItemToSysForm(item, si); + if (item.IsString()) + { + si.cch = kMaxSize; + si.dwTypeData = s; + } + if(GetItemInfo(itemIndex, byPosition, &si)) + { + ConvertItemToMyForm(si, item); + if (item.IsString()) + item.StringValue = GetUnicodeString(s); + return true; + } + } + else + #endif + { + wchar_t s[kMaxSize + 1]; + MENUITEMINFOW si; + ConvertItemToSysForm(item, si); + if (item.IsString()) + { + si.cch = kMaxSize; + si.dwTypeData = s; + } + if(GetItemInfo(itemIndex, byPosition, &si)) + { + ConvertItemToMyForm(si, item); + if (item.IsString()) + item.StringValue = s; + return true; + } + } + return false; +} + +bool CMenu::SetItem(UINT itemIndex, bool byPosition, const CMenuItem &item) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + MENUITEMINFOA si; + ConvertItemToSysForm(item, si); + AString s; + if (item.IsString()) + { + s = GetSystemString(item.StringValue); + si.dwTypeData = (LPTSTR)(LPCTSTR)s; + } + return SetItemInfo(itemIndex, byPosition, &si); + } + else + #endif + { + MENUITEMINFOW si; + ConvertItemToSysForm(item, si); + if (item.IsString()) + si.dwTypeData = (LPWSTR)(LPCWSTR)item.StringValue; + return SetItemInfo(itemIndex, byPosition, &si); + } +} + +bool CMenu::InsertItem(UINT itemIndex, bool byPosition, const CMenuItem &item) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + MENUITEMINFOA si; + ConvertItemToSysForm(item, si); + AString s; + if (item.IsString()) + { + s = GetSystemString(item.StringValue); + si.dwTypeData = (LPTSTR)(LPCTSTR)s; + } + return InsertItem(itemIndex, byPosition, &si); + } + else + #endif + { + MENUITEMINFOW si; + ConvertItemToSysForm(item, si); + if (item.IsString()) + si.dwTypeData = (LPWSTR)(LPCWSTR)item.StringValue; + return InsertItem(itemIndex, byPosition, &si); + } +} + +#ifndef _UNICODE +bool CMenu::AppendItem(UINT flags, UINT_PTR newItemID, LPCWSTR newItem) +{ + if (g_IsNT) + return BOOLToBool(::AppendMenuW(_menu, flags, newItemID, newItem)); + else + return AppendItem(flags, newItemID, GetSystemString(newItem)); +} +#endif + +} diff --git a/CPP/Windows/Menu.h b/CPP/Windows/Menu.h new file mode 100755 index 00000000..11ba5537 --- /dev/null +++ b/CPP/Windows/Menu.h @@ -0,0 +1,137 @@ +// Windows/Menu.h + +#ifndef __WINDOWS_MENU_H +#define __WINDOWS_MENU_H + +#include "Common/String.h" +#include "Windows/Defs.h" + +namespace NWindows { + +struct CMenuItem +{ + UString StringValue; + UINT fMask; + UINT fType; + UINT fState; + UINT wID; + HMENU hSubMenu; + HBITMAP hbmpChecked; + HBITMAP hbmpUnchecked; + ULONG_PTR dwItemData; + // LPTSTR dwTypeData; + // UINT cch; + // HBITMAP hbmpItem; + bool IsString() const // change it MIIM_STRING + { return ((fMask & MIIM_TYPE) != 0 && (fType == MFT_STRING)); } + CMenuItem(): fMask(0), fType(0), fState(0), wID(0), hSubMenu(0), hbmpChecked(0), + hbmpUnchecked(0), dwItemData(0) {} +}; + +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 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)); } + + 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)); } + + #ifndef _UNICODE + bool GetItemInfo(UINT itemIndex, bool byPosition, LPMENUITEMINFOW itemInfo) + { return BOOLToBool(::GetMenuItemInfoW(_menu, itemIndex, BoolToBOOL(byPosition), itemInfo)); } + bool InsertItem(UINT itemIndex, bool byPosition, LPMENUITEMINFOW itemInfo) + { return BOOLToBool(::InsertMenuItemW(_menu, itemIndex, BoolToBOOL(byPosition), itemInfo)); } + bool SetItemInfo(UINT itemIndex, bool byPosition, LPMENUITEMINFOW itemInfo) + { return BOOLToBool(::SetMenuItemInfoW(_menu, itemIndex, BoolToBOOL(byPosition), itemInfo)); } + bool AppendItem(UINT flags, UINT_PTR newItemID, LPCWSTR newItem); + #endif + + bool GetItem(UINT itemIndex, bool byPosition, CMenuItem &item); + bool SetItem(UINT itemIndex, bool byPosition, const CMenuItem &item); + bool InsertItem(UINT itemIndex, bool byPosition, const CMenuItem &item); + + int Track(UINT flags, int x, int y, HWND hWnd) + { return ::TrackPopupMenuEx(_menu, flags, x, y, hWnd, NULL); } + + bool CheckRadioItem(UINT idFirst, UINT idLast, UINT idCheck, UINT flags) + { return BOOLToBool(::CheckMenuRadioItem(_menu, idFirst, idLast, idCheck, flags)); } + DWORD CheckItem(UINT id, UINT uCheck) + { return ::CheckMenuItem(_menu, id, uCheck); } +}; + +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/CPP/Windows/NationalTime.cpp b/CPP/Windows/NationalTime.cpp new file mode 100755 index 00000000..76060216 --- /dev/null +++ b/CPP/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/CPP/Windows/NationalTime.h b/CPP/Windows/NationalTime.h new file mode 100755 index 00000000..4e40f84a --- /dev/null +++ b/CPP/Windows/NationalTime.h @@ -0,0 +1,20 @@ +// Windows/NationalTime.h + +#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/CPP/Windows/Net.cpp b/CPP/Windows/Net.cpp new file mode 100755 index 00000000..113cec94 --- /dev/null +++ b/CPP/Windows/Net.cpp @@ -0,0 +1,380 @@ +// Windows/Net.cpp + +#include "StdAfx.h" + +#include "Windows/Net.h" + +#ifndef _UNICODE +#include "Common/StringConvert.h" +#endif + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +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; +} + +#ifndef _UNICODE +DWORD CEnum::Open(DWORD scope, DWORD type, DWORD usage, LPNETRESOURCEW netResource) +{ + Close(); + DWORD result = ::WNetOpenEnumW(scope, type, usage, netResource, &_handle); + _handleAllocated = (result == NO_ERROR); + return result; +} +#endif + +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(LPTSTR *destString, bool defined, const CSysString &srcString) +{ + if (defined) + *destString = (TCHAR *)(const TCHAR *)srcString; + 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); +} + +#ifndef _UNICODE + +static void SetComplexString(bool &defined, UString &destString, LPCWSTR srsString) +{ + defined = (srsString != 0); + if (defined) + destString = srsString; + else + destString.Empty(); +} + +static void ConvertNETRESOURCEToCResource(const NETRESOURCEW &netResource, CResourceW &resource) +{ + resource.Scope = netResource.dwScope; + resource.Type = netResource.dwType; + resource.DisplayType = netResource.dwDisplayType; + resource.Usage = netResource.dwUsage; + SetComplexString(resource.LocalNameIsDefined, resource.LocalName, netResource.lpLocalName); + SetComplexString(resource.RemoteNameIsDefined, resource.RemoteName, netResource.lpRemoteName); + SetComplexString(resource.CommentIsDefined, resource.Comment, netResource.lpComment); + SetComplexString(resource.ProviderIsDefined, resource.Provider, netResource.lpProvider); +} + +static void SetComplexString2(LPWSTR *destString, bool defined, const UString &srcString) +{ + if (defined) + *destString = (WCHAR *)(const WCHAR *)srcString; + else + *destString = 0; +} + +static void ConvertCResourceToNETRESOURCE(const CResourceW &resource, NETRESOURCEW &netResource) +{ + netResource.dwScope = resource.Scope; + netResource.dwType = resource.Type; + netResource.dwDisplayType = resource.DisplayType; + netResource.dwUsage = resource.Usage; + SetComplexString2(&netResource.lpLocalName, resource.LocalNameIsDefined, resource.LocalName); + SetComplexString2(&netResource.lpRemoteName, resource.RemoteNameIsDefined, resource.RemoteName); + SetComplexString2(&netResource.lpComment, resource.CommentIsDefined, resource.Comment); + SetComplexString2(&netResource.lpProvider, resource.ProviderIsDefined, resource.Provider); +} + +static void ConvertResourceWToResource(const CResourceW &resourceW, CResource &resource) +{ + *(CResourceBase *)&resource = *(CResourceBase *)&resourceW; + resource.LocalName = GetSystemString(resourceW.LocalName); + resource.RemoteName = GetSystemString(resourceW.RemoteName); + resource.Comment = GetSystemString(resourceW.Comment); + resource.Provider = GetSystemString(resourceW.Provider); +} + +static void ConvertResourceToResourceW(const CResource &resource, CResourceW &resourceW) +{ + *(CResourceBase *)&resourceW = *(CResourceBase *)&resource; + resourceW.LocalName = GetUnicodeString(resource.LocalName); + resourceW.RemoteName = GetUnicodeString(resource.RemoteName); + resourceW.Comment = GetUnicodeString(resource.Comment); + resourceW.Provider = GetUnicodeString(resource.Provider); +} +#endif + +DWORD CEnum::Open(DWORD scope, DWORD type, DWORD usage, const CResource *resource) +{ + NETRESOURCE netResource; + LPNETRESOURCE pointer; + if (resource == 0) + pointer = 0; + else + { + ConvertCResourceToNETRESOURCE(*resource, netResource); + pointer = &netResource; + } + return Open(scope, type, usage, pointer); +} + +#ifndef _UNICODE +DWORD CEnum::Open(DWORD scope, DWORD type, DWORD usage, const CResourceW *resource) +{ + if (g_IsNT) + { + NETRESOURCEW netResource; + LPNETRESOURCEW pointer; + if (resource == 0) + pointer = 0; + else + { + ConvertCResourceToNETRESOURCE(*resource, netResource); + pointer = &netResource; + } + return Open(scope, type, usage, pointer); + } + CResource *pointer; + CResource resourceA; + if (resource == 0) + pointer = 0; + else + { + ConvertResourceWToResource(*resource, resourceA); + pointer = &resourceA; + } + return Open(scope, type, usage, pointer); +} +#endif + +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); +} + +#ifndef _UNICODE +DWORD CEnum::NextW(LPDWORD lpcCount, LPVOID lpBuffer, LPDWORD lpBufferSize) +{ + return ::WNetEnumResourceW(_handle, lpcCount, lpBuffer, lpBufferSize); +} +#endif + +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; +} + +#ifndef _UNICODE +DWORD CEnum::Next(CResourceW &resource) +{ + if (g_IsNT) + { + CByteBuffer byteBuffer; + const DWORD kBufferSize = 16384; + byteBuffer.SetCapacity(kBufferSize); + LPNETRESOURCEW lpnrLocal = (LPNETRESOURCEW) (BYTE *)(byteBuffer); + ZeroMemory(lpnrLocal, kBufferSize); + DWORD bufferSize = kBufferSize; + DWORD numEntries = 1; + DWORD result = NextW(&numEntries, lpnrLocal, &bufferSize); + if (result != NO_ERROR) + return result; + if (numEntries != 1) + return (DWORD)E_FAIL; + ConvertNETRESOURCEToCResource(lpnrLocal[0], resource); + return result; + } + CResource resourceA; + DWORD result = Next(resourceA); + ConvertResourceToResourceW(resourceA, resource); + return result; +} +#endif + + +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; +} + +#ifndef _UNICODE +DWORD GetResourceParent(const CResourceW &resource, CResourceW &parentResource) +{ + if (g_IsNT) + { + CByteBuffer byteBuffer; + const DWORD kBufferSize = 16384; + byteBuffer.SetCapacity(kBufferSize); + LPNETRESOURCEW lpnrLocal = (LPNETRESOURCEW) (BYTE *)(byteBuffer); + ZeroMemory(lpnrLocal, kBufferSize); + DWORD bufferSize = kBufferSize; + NETRESOURCEW netResource; + ConvertCResourceToNETRESOURCE(resource, netResource); + DWORD result = ::WNetGetResourceParentW(&netResource, lpnrLocal, &bufferSize); + if (result != NO_ERROR) + return result; + ConvertNETRESOURCEToCResource(lpnrLocal[0], parentResource); + return result; + } + CResource resourceA, parentResourceA; + ConvertResourceWToResource(resource, resourceA); + DWORD result = GetResourceParent(resourceA, parentResourceA); + ConvertResourceToResourceW(parentResourceA, parentResource); + return result; +} +#endif + +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; +} + +#ifndef _UNICODE +DWORD GetResourceInformation(const CResourceW &resource, + CResourceW &destResource, UString &systemPathPart) +{ + if (g_IsNT) + { + CByteBuffer byteBuffer; + const DWORD kBufferSize = 16384; + byteBuffer.SetCapacity(kBufferSize); + LPNETRESOURCEW lpnrLocal = (LPNETRESOURCEW) (BYTE *)(byteBuffer); + ZeroMemory(lpnrLocal, kBufferSize); + DWORD bufferSize = kBufferSize; + NETRESOURCEW netResource; + ConvertCResourceToNETRESOURCE(resource, netResource); + LPWSTR lplpSystem; + DWORD result = ::WNetGetResourceInformationW(&netResource, + lpnrLocal, &bufferSize, &lplpSystem); + if (result != NO_ERROR) + return result; + if (lplpSystem != 0) + systemPathPart = lplpSystem; + ConvertNETRESOURCEToCResource(lpnrLocal[0], destResource); + return result; + } + CResource resourceA, destResourceA; + ConvertResourceWToResource(resource, resourceA); + AString systemPathPartA; + DWORD result = GetResourceInformation(resourceA, destResourceA, systemPathPartA); + ConvertResourceToResourceW(destResourceA, destResource); + systemPathPart = GetUnicodeString(systemPathPartA); + return result; +} +#endif + +DWORD AddConnection2(const CResource &resource, + LPCTSTR password, LPCTSTR userName, DWORD flags) +{ + NETRESOURCE netResource; + ConvertCResourceToNETRESOURCE(resource, netResource); + return ::WNetAddConnection2(&netResource, + password, userName, flags); +} + +DWORD AddConnection2(const CResource &resource, LPCTSTR password, LPCTSTR userName, DWORD flags); + +#ifndef _UNICODE +DWORD AddConnection2(const CResourceW &resource, LPCWSTR password, LPCWSTR userName, DWORD flags) +{ + if (g_IsNT) + { + NETRESOURCEW netResource; + ConvertCResourceToNETRESOURCE(resource, netResource); + return ::WNetAddConnection2W(&netResource,password, userName, flags); + } + CResource resourceA; + ConvertResourceWToResource(resource, resourceA); + CSysString passwordA = GetSystemString(password); + CSysString userNameA = GetSystemString(userName); + return AddConnection2(resourceA, + password ? (LPCTSTR)passwordA: 0, + userName ? (LPCTSTR)userNameA: 0, + flags); +} +#endif + +}} diff --git a/CPP/Windows/Net.h b/CPP/Windows/Net.h new file mode 100755 index 00000000..ff501d70 --- /dev/null +++ b/CPP/Windows/Net.h @@ -0,0 +1,87 @@ +// Windows/Net.h + +#ifndef __WINDOWS_NET_H +#define __WINDOWS_NET_H + +#include "Common/Buffer.h" +#include "Common/String.h" + +namespace NWindows { +namespace NNet { + +struct CResourceBase +{ + DWORD Scope; + DWORD Type; + DWORD DisplayType; + DWORD Usage; + bool LocalNameIsDefined; + bool RemoteNameIsDefined; + bool CommentIsDefined; + bool ProviderIsDefined; +}; + +struct CResource: public CResourceBase +{ + CSysString LocalName; + CSysString RemoteName; + CSysString Comment; + CSysString Provider; +}; + +#ifdef _UNICODE +typedef CResource CResourceW; +#else +struct CResourceW: public CResourceBase +{ + UString LocalName; + UString RemoteName; + UString Comment; + UString Provider; +}; +#endif + +class CEnum +{ + HANDLE _handle; + bool _handleAllocated; + DWORD Open(DWORD scope, DWORD type, DWORD usage, LPNETRESOURCE netResource); + DWORD Next(LPDWORD lpcCount, LPVOID lpBuffer, LPDWORD lpBufferSize); + #ifndef _UNICODE + DWORD Open(DWORD scope, DWORD type, DWORD usage, LPNETRESOURCEW netResource); + DWORD NextW(LPDWORD lpcCount, LPVOID lpBuffer, LPDWORD lpBufferSize); + #endif +protected: + bool IsHandleAllocated() const { return _handleAllocated; } +public: + CEnum(): _handleAllocated(false) {} + ~CEnum() { Close(); } + DWORD Close(); + DWORD Open(DWORD scope, DWORD type, DWORD usage, const CResource *resource); + DWORD Next(CResource &resource); + #ifndef _UNICODE + DWORD Open(DWORD scope, DWORD type, DWORD usage, const CResourceW *resource); + DWORD Next(CResourceW &resource); + #endif +}; + +DWORD GetResourceParent(const CResource &resource, CResource &parentResource); +#ifndef _UNICODE +DWORD GetResourceParent(const CResourceW &resource, CResourceW &parentResource); +#endif + +DWORD GetResourceInformation(const CResource &resource, + CResource &destResource, CSysString &systemPathPart); +#ifndef _UNICODE +DWORD GetResourceInformation(const CResourceW &resource, + CResourceW &destResource, UString &systemPathPart); +#endif + +DWORD AddConnection2(const CResource &resource, LPCTSTR password, LPCTSTR userName, DWORD flags); +#ifndef _UNICODE +DWORD AddConnection2(const CResourceW &resource, LPCWSTR password, LPCWSTR userName, DWORD flags); +#endif + +}} + +#endif diff --git a/CPP/Windows/ProcessMessages.cpp b/CPP/Windows/ProcessMessages.cpp new file mode 100755 index 00000000..2f2841c1 --- /dev/null +++ b/CPP/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/CPP/Windows/ProcessMessages.h b/CPP/Windows/ProcessMessages.h new file mode 100755 index 00000000..63f8ec8a --- /dev/null +++ b/CPP/Windows/ProcessMessages.h @@ -0,0 +1,14 @@ +// Windows/ProcessMessages.h + +#ifndef __WINDOWS_PROCESSMESSAGES_H +#define __WINDOWS_PROCESSMESSAGES_H + +namespace NWindows { + +void ProcessMessages(HWND window); + +} + +#endif + + diff --git a/CPP/Windows/PropVariant.cpp b/CPP/Windows/PropVariant.cpp new file mode 100755 index 00000000..690e2b6c --- /dev/null +++ b/CPP/Windows/PropVariant.cpp @@ -0,0 +1,312 @@ +// 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; +} + +CPropVariant& CPropVariant::operator=(const CPropVariant& varSrc) +{ + InternalCopy(&varSrc); + return *this; +} +CPropVariant& CPropVariant::operator=(const PROPVARIANT& varSrc) +{ + InternalCopy(&varSrc); + return *this; +} + +CPropVariant& CPropVariant::operator=(BSTR bstrSrc) +{ + *this = (LPCOLESTR)bstrSrc; + return *this; +} + +CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc) +{ + InternalClear(); + vt = VT_BSTR; + wReserved1 = 0; + 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.QuadPart = value; + return *this; +} + +CPropVariant& CPropVariant::operator=(const FILETIME &value) +{ + if (vt != VT_FILETIME) + { + InternalClear(); + vt = VT_FILETIME; + } + filetime = value; + return *this; +} + +CPropVariant& CPropVariant::operator=(Int32 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=(Int16 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 *propVariant) +{ + switch(propVariant->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: + propVariant->vt = VT_EMPTY; + propVariant->wReserved1 = 0; + return S_OK; + } + return ::VariantClear((VARIANTARG *)propVariant); +} + +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: + memmove((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT)); + return S_OK; + } + return ::VariantCopy((tagVARIANT *)this, (tagVARIANT *)(pSrc)); +} + + +HRESULT CPropVariant::Attach(PROPVARIANT* pSrc) +{ + HRESULT hr = Clear(); + if (FAILED(hr)) + return hr; + memcpy(this, pSrc, sizeof(PROPVARIANT)); + pSrc->vt = VT_EMPTY; + return S_OK; +} + +HRESULT CPropVariant::Detach(PROPVARIANT* pDest) +{ + HRESULT hr = MyPropVariantClear(pDest); + if (FAILED(hr)) + return hr; + memcpy(pDest, this, sizeof(PROPVARIANT)); + vt = VT_EMPTY; + return S_OK; +} + +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; + } +} + +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(hVal.QuadPart, a.hVal.QuadPart); + case VT_UI8: + return MyCompare(uhVal.QuadPart, a.uhVal.QuadPart); + + case VT_BOOL: + return -MyCompare(boolVal, a.boolVal); + + case VT_FILETIME: + return ::CompareFileTime(&filetime, &a.filetime); + case VT_BSTR: + return 0; // Not implemented + // return MyCompare(aPropVarint.cVal); + + default: + return 0; + } +} + +}} diff --git a/CPP/Windows/PropVariant.h b/CPP/Windows/PropVariant.h new file mode 100755 index 00000000..d44215f0 --- /dev/null +++ b/CPP/Windows/PropVariant.h @@ -0,0 +1,57 @@ +// Windows/PropVariant.h + +#ifndef __WINDOWS_PROPVARIANT_H +#define __WINDOWS_PROPVARIANT_H + +#include "../Common/MyWindows.h" +#include "../Common/Types.h" + +namespace NWindows { +namespace NCOM { + +class CPropVariant : public tagPROPVARIANT +{ +public: + CPropVariant() { vt = VT_EMPTY; wReserved1 = 0; } + ~CPropVariant() { Clear(); } + CPropVariant(const PROPVARIANT& varSrc); + CPropVariant(const CPropVariant& varSrc); + CPropVariant(BSTR bstrSrc); + CPropVariant(LPCOLESTR lpszSrc); + CPropVariant(bool bSrc) { vt = VT_BOOL; wReserved1 = 0; boolVal = (bSrc ? VARIANT_TRUE : VARIANT_FALSE); }; + CPropVariant(UInt32 value) { vt = VT_UI4; wReserved1 = 0; ulVal = value; } + CPropVariant(UInt64 value) { vt = VT_UI8; wReserved1 = 0; uhVal = *(ULARGE_INTEGER*)&value; } + CPropVariant(const FILETIME &value) { vt = VT_FILETIME; wReserved1 = 0; filetime = value; } + CPropVariant(Int32 value) { vt = VT_I4; wReserved1 = 0; lVal = value; } + CPropVariant(Byte value) { vt = VT_UI1; wReserved1 = 0; bVal = value; } + CPropVariant(Int16 value) { vt = VT_I2; wReserved1 = 0; 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=(Int32 value); + CPropVariant& operator=(Byte value); + CPropVariant& operator=(Int16 value); + // CPropVariant& operator=(LONG value); + + HRESULT Clear(); + HRESULT Copy(const PROPVARIANT* pSrc); + HRESULT Attach(PROPVARIANT* pSrc); + HRESULT Detach(PROPVARIANT* pDest); + + HRESULT InternalClear(); + void InternalCopy(const PROPVARIANT* pSrc); + + int Compare(const CPropVariant &a1); +}; + +}} + +#endif diff --git a/CPP/Windows/PropVariantConversions.cpp b/CPP/Windows/PropVariantConversions.cpp new file mode 100755 index 00000000..80ba5ac2 --- /dev/null +++ b/CPP/Windows/PropVariantConversions.cpp @@ -0,0 +1,150 @@ +// PropVariantConversions.cpp + +#include "StdAfx.h" + +// #include + +#include "PropVariantConversions.h" + +#include "Windows/Defs.h" + +#include "Common/StringConvert.h" +#include "Common/IntToString.h" + +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; +} + +static char *UIntToStringSpec(UInt32 value, char *s, int numPos) +{ + char temp[16]; + int pos = 0; + do + { + temp[pos++] = (char)('0' + value % 10); + value /= 10; + } + while (value != 0); + int i; + for (i = 0; i < numPos - pos; i++) + *s++ = '0'; + do + *s++ = temp[--pos]; + while (pos > 0); + *s = '\0'; + return s; +} + +bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime, bool includeSeconds) +{ + s[0] = '\0'; + SYSTEMTIME st; + if(!BOOLToBool(FileTimeToSystemTime(&ft, &st))) + return false; + s = UIntToStringSpec(st.wYear, s, 4); + *s++ = '-'; + s = UIntToStringSpec(st.wMonth, s, 2); + *s++ = '-'; + s = UIntToStringSpec(st.wDay, s, 2); + if (includeTime) + { + *s++ = ' '; + s = UIntToStringSpec(st.wHour, s, 2); + *s++ = ':'; + s = UIntToStringSpec(st.wMinute, s, 2); + if (includeSeconds) + { + *s++ = ':'; + UIntToStringSpec(st.wSecond, s, 2); + } + } + /* + sprintf(s, "%04d-%02d-%02d", st.wYear, st.wMonth, st.wDay); + if (includeTime) + { + sprintf(s + strlen(s), " %02d:%02d", st.wHour, st.wMinute); + if (includeSeconds) + sprintf(s + strlen(s), ":%02d", st.wSecond); + } + */ + return true; +} + +UString ConvertFileTimeToString(const FILETIME &fileTime, bool includeTime, bool includeSeconds) +{ + char s[32]; + ConvertFileTimeToString(fileTime, s, includeTime, includeSeconds); + return GetUnicodeString(s); +} + + +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(propVariant.uhVal.QuadPart); + case VT_FILETIME: + return ConvertFileTimeToString(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(propVariant.hVal.QuadPart); + + case VT_BOOL: + return VARIANT_BOOLToBool(propVariant.boolVal) ? L"1" : L"0"; + default: + #ifndef _WIN32_WCE + throw 150245; + #else + return UString(); + #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.QuadPart; + default: + #ifndef _WIN32_WCE + throw 151199; + #else + return 0; + #endif + } +} diff --git a/CPP/Windows/PropVariantConversions.h b/CPP/Windows/PropVariantConversions.h new file mode 100755 index 00000000..a3f3ebbf --- /dev/null +++ b/CPP/Windows/PropVariantConversions.h @@ -0,0 +1,14 @@ +// Windows/PropVariantConversions.h + +#ifndef __PROPVARIANTCONVERSIONS_H +#define __PROPVARIANTCONVERSIONS_H + +#include "Common/Types.h" +#include "Common/String.h" + +bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime = true, bool includeSeconds = true); +UString ConvertFileTimeToString(const FILETIME &ft, bool includeTime = true, bool includeSeconds = true); +UString ConvertPropVariantToString(const PROPVARIANT &propVariant); +UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &propVariant); + +#endif diff --git a/CPP/Windows/Registry.cpp b/CPP/Windows/Registry.cpp new file mode 100755 index 00000000..2c6b6afc --- /dev/null +++ b/CPP/Windows/Registry.cpp @@ -0,0 +1,324 @@ +// Windows/Registry.cpp + +#include "StdAfx.h" + +#ifndef _UNICODE +#include "Common/StringConvert.h" +#endif +#include "Windows/Registry.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +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 name) +{ + MYASSERT(_object != NULL); + return ::RegDeleteValue(_object, name); +} + +#ifndef _UNICODE +LONG CKey::DeleteValue(LPCWSTR name) +{ + MYASSERT(_object != NULL); + if (g_IsNT) + return ::RegDeleteValueW(_object, name); + return DeleteValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name)); +} +#endif + +LONG CKey::SetValue(LPCTSTR name, UInt32 value) +{ + MYASSERT(_object != NULL); + return RegSetValueEx(_object, name, NULL, REG_DWORD, + (BYTE * const)&value, sizeof(UInt32)); +} + +LONG CKey::SetValue(LPCTSTR name, bool value) +{ + return SetValue(name, BoolToUINT32(value)); +} + +LONG CKey::SetValue(LPCTSTR name, LPCTSTR value) +{ + MYASSERT(value != NULL); + MYASSERT(_object != NULL); + return RegSetValueEx(_object, name, NULL, REG_SZ, + (const BYTE * )value, (lstrlen(value) + 1) * sizeof(TCHAR)); +} + +/* +LONG CKey::SetValue(LPCTSTR name, const CSysString &value) +{ + MYASSERT(value != NULL); + MYASSERT(_object != NULL); + return RegSetValueEx(_object, name, NULL, REG_SZ, + (const BYTE *)(const TCHAR *)value, (value.Length() + 1) * sizeof(TCHAR)); +} +*/ + +#ifndef _UNICODE + +LONG CKey::SetValue(LPCWSTR name, LPCWSTR value) +{ + MYASSERT(value != NULL); + MYASSERT(_object != NULL); + if (g_IsNT) + return RegSetValueExW(_object, name, NULL, REG_SZ, + (const BYTE * )value, (DWORD)((wcslen(value) + 1) * sizeof(wchar_t))); + return SetValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name), + value == 0 ? 0 : (LPCSTR)GetSystemString(value)); +} + +#endif + + +LONG CKey::SetValue(LPCTSTR name, const void *value, UInt32 size) +{ + MYASSERT(value != NULL); + MYASSERT(_object != NULL); + return RegSetValueEx(_object, name, 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 name, UInt32 &value) +{ + DWORD type = NULL; + DWORD count = sizeof(DWORD); + LONG res = RegQueryValueEx(_object, (LPTSTR)name, 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 name, bool &value) +{ + UInt32 uintValue = BoolToUINT32(value); + LONG res = QueryValue(name, uintValue); + value = UINT32ToBool(uintValue); + return res; +} + +LONG CKey::QueryValue(LPCTSTR name, LPTSTR value, UInt32 &count) +{ + MYASSERT(count != NULL); + DWORD type = NULL; + LONG res = RegQueryValueEx(_object, (LPTSTR)name, 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 name, CSysString &value) +{ + value.Empty(); + DWORD type = NULL; + UInt32 currentSize = 0; + LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, NULL, (DWORD *)¤tSize); + if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) + return res; + res = QueryValue(name, value.GetBuffer(currentSize), currentSize); + value.ReleaseBuffer(); + return res; +} + +#ifndef _UNICODE +LONG CKey::QueryValue(LPCWSTR name, LPWSTR value, UInt32 &count) +{ + MYASSERT(count != NULL); + DWORD type = NULL; + LONG res = RegQueryValueExW(_object, name, 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(LPCWSTR name, UString &value) +{ + value.Empty(); + DWORD type = NULL; + UInt32 currentSize = 0; + + LONG res; + if (g_IsNT) + { + res = RegQueryValueExW(_object, name, NULL, &type, NULL, (DWORD *)¤tSize); + if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) + return res; + res = QueryValue(name, value.GetBuffer(currentSize), currentSize); + value.ReleaseBuffer(); + } + else + { + AString vTemp; + res = QueryValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name), vTemp); + value = GetUnicodeString(vTemp); + } + return res; +} +#endif + +LONG CKey::QueryValue(LPCTSTR name, void *value, UInt32 &count) +{ + DWORD type = NULL; + LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, (LPBYTE)value, (DWORD *)&count); + MYASSERT((res!=ERROR_SUCCESS) || (type == REG_BINARY)); + return res; +} + + +LONG CKey::QueryValue(LPCTSTR name, CByteBuffer &value, UInt32 &dataSize) +{ + DWORD type = NULL; + dataSize = 0; + LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, NULL, (DWORD *)&dataSize); + if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) + return res; + value.SetCapacity(dataSize); + return QueryValue(name, (BYTE *)value, dataSize); +} + +LONG CKey::EnumKeys(CSysStringVector &keyNames) +{ + keyNames.Clear(); + CSysString keyName; + for(UInt32 index = 0; ; index++) + { + const UInt32 kBufferSize = MAX_PATH + 1; // 256 in ATL + FILETIME lastWriteTime; + UInt32 nameSize = kBufferSize; + LONG result = ::RegEnumKeyEx(_object, index, keyName.GetBuffer(kBufferSize), + (DWORD *)&nameSize, NULL, NULL, NULL, &lastWriteTime); + keyName.ReleaseBuffer(); + if(result == ERROR_NO_MORE_ITEMS) + break; + if(result != ERROR_SUCCESS) + return result; + keyNames.Add(keyName); + } + return ERROR_SUCCESS; +} + +}} diff --git a/CPP/Windows/Registry.h b/CPP/Windows/Registry.h new file mode 100755 index 00000000..435717bd --- /dev/null +++ b/CPP/Windows/Registry.h @@ -0,0 +1,77 @@ +// Windows/Registry.h + +#ifndef __WINDOWS_REGISTRY_H +#define __WINDOWS_REGISTRY_H + +#include "Common/Buffer.h" +#include "Common/String.h" +#include "Common/Types.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 name); + #ifndef _UNICODE + LONG DeleteValue(LPCWSTR name); + #endif + + 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); + #ifndef _UNICODE + LONG SetValue(LPCWSTR name, LPCWSTR value); + // LONG SetValue(LPCWSTR name, const UString &value); + #endif + + LONG SetValue(LPCTSTR name, const void *value, UInt32 size); + + LONG SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value); + + LONG QueryValue(LPCTSTR name, UInt32 &value); + LONG QueryValue(LPCTSTR name, bool &value); + LONG QueryValue(LPCTSTR name, LPTSTR value, UInt32 &dataSize); + LONG QueryValue(LPCTSTR name, CSysString &value); + + #ifndef _UNICODE + LONG QueryValue(LPCWSTR name, LPWSTR value, UInt32 &dataSize); + LONG QueryValue(LPCWSTR name, UString &value); + #endif + + LONG QueryValue(LPCTSTR name, void *value, UInt32 &dataSize); + LONG QueryValue(LPCTSTR name, CByteBuffer &value, UInt32 &dataSize); + + LONG EnumKeys(CSysStringVector &keyNames); +}; + +}} + +#endif diff --git a/CPP/Windows/ResourceString.cpp b/CPP/Windows/ResourceString.cpp new file mode 100755 index 00000000..48dd4936 --- /dev/null +++ b/CPP/Windows/ResourceString.cpp @@ -0,0 +1,53 @@ +// Windows/ResourceString.cpp + +#include "StdAfx.h" + +#include "Windows/ResourceString.h" +#ifndef _UNICODE +#include "Common/StringConvert.h" +#endif + +extern HINSTANCE g_hInstance; +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +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) +{ + if (g_IsNT) + { + UString s; + int size = 256; + int len; + do + { + size += 256; + len = ::LoadStringW(g_hInstance, resourceID, s.GetBuffer(size - 1), size); + } + while (size - len <= 1); + s.ReleaseBuffer(); + return s; + } + return GetUnicodeString(MyLoadString(resourceID)); +} +#endif + +} diff --git a/CPP/Windows/ResourceString.h b/CPP/Windows/ResourceString.h new file mode 100755 index 00000000..a74f925d --- /dev/null +++ b/CPP/Windows/ResourceString.h @@ -0,0 +1,20 @@ +// Windows/ResourceString.h + +#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/CPP/Windows/Security.cpp b/CPP/Windows/Security.cpp new file mode 100755 index 00000000..05b3b640 --- /dev/null +++ b/CPP/Windows/Security.cpp @@ -0,0 +1,181 @@ +// Windows/Security.h + +#include "StdAfx.h" + +#include "Windows/Security.h" +#include "Windows/Defs.h" + +#include "Common/StringConvert.h" +#include "Defs.h" + +namespace NWindows { +namespace NSecurity { + +/* +bool MyLookupAccountSid(LPCTSTR systemName, PSID sid, + CSysString &accountName, CSysString &domainName, PSID_NAME_USE sidNameUse) +{ + DWORD accountNameSize = 0, domainNameSize = 0; + + if (!::LookupAccountSid(systemName, sid, + accountName.GetBuffer(0), &accountNameSize, + domainName.GetBuffer(0), &domainNameSize, sidNameUse)) + { + if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER) + return false; + } + bool result = BOOLToBool(::LookupAccountSid(systemName, sid, + accountName.GetBuffer(accountNameSize), &accountNameSize, + domainName.GetBuffer(domainNameSize), &domainNameSize, sidNameUse)); + accountName.ReleaseBuffer(); + domainName.ReleaseBuffer(); + return result; +} +*/ + +static void SetLsaString(LPWSTR src, PLSA_UNICODE_STRING dest) +{ + int len = (int)wcslen(src); + dest->Length = (USHORT)(len * sizeof(WCHAR)); + dest->MaximumLength = (USHORT)((len + 1) * sizeof(WCHAR)); + dest->Buffer = src; +} + +/* +static void MyLookupSids(CPolicy &policy, PSID ps) +{ + LSA_REFERENCED_DOMAIN_LIST *referencedDomains = NULL; + LSA_TRANSLATED_NAME *names = NULL; + NTSTATUS nts = policy.LookupSids(1, &ps, &referencedDomains, &names); + int res = LsaNtStatusToWinError(nts); + LsaFreeMemory(referencedDomains); + LsaFreeMemory(names); +} +*/ + +#ifndef _UNICODE +typedef BOOL (WINAPI * LookupAccountNameWP)( + LPCWSTR lpSystemName, + LPCWSTR lpAccountName, + PSID Sid, + LPDWORD cbSid, + LPWSTR ReferencedDomainName, + LPDWORD cchReferencedDomainName, + PSID_NAME_USE peUse + ); +#endif + +static PSID GetSid(LPWSTR accountName) +{ + #ifndef _UNICODE + HMODULE hModule = GetModuleHandle(TEXT("Advapi32.dll")); + if (hModule == NULL) + return NULL; + LookupAccountNameWP lookupAccountNameW = (LookupAccountNameWP)GetProcAddress(hModule, "LookupAccountNameW"); + if (lookupAccountNameW == NULL) + return NULL; + #endif + + DWORD sidLen = 0, domainLen = 0; + SID_NAME_USE sidNameUse; + if (! + #ifdef _UNICODE + ::LookupAccountNameW + #else + lookupAccountNameW + #endif + (NULL, accountName, NULL, &sidLen, NULL, &domainLen, &sidNameUse)) + { + if(::GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + PSID pSid = ::HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sidLen); + LPWSTR domainName = (LPWSTR)::HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (domainLen + 1) * sizeof(WCHAR)); + BOOL res = + #ifdef _UNICODE + ::LookupAccountNameW + #else + lookupAccountNameW + #endif + (NULL, accountName, pSid, &sidLen, domainName, &domainLen, &sidNameUse); + ::HeapFree(GetProcessHeap(), 0, domainName); + if (res) + return pSid; + } + } + return NULL; +} + +bool AddLockMemoryPrivilege() +{ + CPolicy policy; + LSA_OBJECT_ATTRIBUTES attr; + attr.Length = sizeof(attr); + attr.RootDirectory = NULL; + attr.ObjectName = NULL; + attr.Attributes = 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + if (policy.Open(NULL, &attr, + // GENERIC_WRITE) + POLICY_ALL_ACCESS) + // STANDARD_RIGHTS_REQUIRED, + // GENERIC_READ | GENERIC_EXECUTE | POLICY_VIEW_LOCAL_INFORMATION | POLICY_LOOKUP_NAMES) + != 0) + return false; + LSA_UNICODE_STRING userRights; + UString s = GetUnicodeString(SE_LOCK_MEMORY_NAME); + SetLsaString((LPWSTR)(LPCWSTR)s, &userRights); + WCHAR userName[256 + 2]; + DWORD size = 256; + if (!GetUserNameW(userName, &size)) + return false; + PSID psid = GetSid(userName); + if (psid == NULL) + return false; + bool res = false; + + /* + PLSA_UNICODE_STRING userRightsArray; + ULONG countOfRights; + NTSTATUS status = policy.EnumerateAccountRights(psid, &userRightsArray, &countOfRights); + if (status != 0) + return false; + bool finded = false; + for (ULONG i = 0; i < countOfRights; i++) + { + LSA_UNICODE_STRING &ur = userRightsArray[i]; + if (ur.Length != s.Length() * sizeof(WCHAR)) + continue; + if (wcsncmp(ur.Buffer, s, s.Length()) != 0) + continue; + finded = true; + res = true; + break; + } + if (!finded) + */ + { + /* + LSA_ENUMERATION_INFORMATION *enums; + ULONG countReturned; + NTSTATUS status = policy.EnumerateAccountsWithUserRight(&userRights, &enums, &countReturned); + if (status == 0) + { + for (ULONG i = 0; i < countReturned; i++) + MyLookupSids(policy, enums[i].Sid); + if (enums) + ::LsaFreeMemory(enums); + res = true; + } + */ + NTSTATUS status = policy.AddAccountRights(psid, &userRights); + if (status == 0) + res = true; + // ULONG res = LsaNtStatusToWinError(status); + } + HeapFree(GetProcessHeap(), 0, psid); + return res; +} + +}} + diff --git a/CPP/Windows/Security.h b/CPP/Windows/Security.h new file mode 100755 index 00000000..ded31b74 --- /dev/null +++ b/CPP/Windows/Security.h @@ -0,0 +1,168 @@ +// Windows/Security.h + +#ifndef __WINDOWS_SECURITY_H +#define __WINDOWS_SECURITY_H + +#include "Common/String.h" +#include "Windows/Defs.h" + +#include + +namespace NWindows { +namespace NSecurity { + +class CAccessToken +{ + HANDLE _handle; +public: + CAccessToken(): _handle(NULL) {}; + ~CAccessToken() { Close(); } + bool Close() + { + if (_handle == NULL) + return true; + bool res = BOOLToBool(::CloseHandle(_handle)); + if (res) + _handle = NULL; + return res; + } + + bool OpenProcessToken(HANDLE processHandle, DWORD desiredAccess) + { + Close(); + return BOOLToBool(::OpenProcessToken(processHandle, desiredAccess, &_handle)); + } + + /* + bool OpenThreadToken(HANDLE threadHandle, DWORD desiredAccess, bool openAsSelf) + { + Close(); + return BOOLToBool(::OpenTreadToken(threadHandle, desiredAccess, BoolToBOOL(anOpenAsSelf), &_handle)); + } + */ + + bool AdjustPrivileges(bool disableAllPrivileges, PTOKEN_PRIVILEGES newState, + DWORD bufferLength, PTOKEN_PRIVILEGES previousState, PDWORD returnLength) + { return BOOLToBool(::AdjustTokenPrivileges(_handle, BoolToBOOL(disableAllPrivileges), + newState, bufferLength, previousState, returnLength)); } + + bool AdjustPrivileges(bool disableAllPrivileges, PTOKEN_PRIVILEGES newState) + { return AdjustPrivileges(disableAllPrivileges, newState, 0, NULL, NULL); } + + bool AdjustPrivileges(PTOKEN_PRIVILEGES newState) + { return AdjustPrivileges(false, newState); } + +}; + +#ifndef _UNICODE +typedef NTSTATUS (NTAPI *LsaOpenPolicyP)(PLSA_UNICODE_STRING SystemName, + PLSA_OBJECT_ATTRIBUTES ObjectAttributes, ACCESS_MASK DesiredAccess, PLSA_HANDLE PolicyHandle); +typedef NTSTATUS (NTAPI *LsaCloseP)(LSA_HANDLE ObjectHandle); +typedef NTSTATUS (NTAPI *LsaAddAccountRightsP)(LSA_HANDLE PolicyHandle, + PSID AccountSid, PLSA_UNICODE_STRING UserRights, ULONG CountOfRights ); +#define MY_STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002L) +#endif + +struct CPolicy +{ +protected: + LSA_HANDLE _handle; + #ifndef _UNICODE + HMODULE hModule; + #endif +public: + operator LSA_HANDLE() const { return _handle; } + CPolicy(): _handle(NULL) + { + #ifndef _UNICODE + hModule = GetModuleHandle(TEXT("Advapi32.dll")); + #endif + }; + ~CPolicy() { Close(); } + + NTSTATUS Open(PLSA_UNICODE_STRING systemName, PLSA_OBJECT_ATTRIBUTES objectAttributes, + ACCESS_MASK desiredAccess) + { + #ifndef _UNICODE + if (hModule == NULL) + return MY_STATUS_NOT_IMPLEMENTED; + LsaOpenPolicyP lsaOpenPolicy = (LsaOpenPolicyP)GetProcAddress(hModule, "LsaOpenPolicy"); + if (lsaOpenPolicy == NULL) + return MY_STATUS_NOT_IMPLEMENTED; + #endif + + Close(); + return + #ifdef _UNICODE + ::LsaOpenPolicy + #else + lsaOpenPolicy + #endif + (systemName, objectAttributes, desiredAccess, &_handle); + } + + NTSTATUS Close() + { + if (_handle == NULL) + return 0; + + #ifndef _UNICODE + if (hModule == NULL) + return MY_STATUS_NOT_IMPLEMENTED; + LsaCloseP lsaClose = (LsaCloseP)GetProcAddress(hModule, "LsaClose"); + if (lsaClose == NULL) + return MY_STATUS_NOT_IMPLEMENTED; + #endif + + NTSTATUS res = + #ifdef _UNICODE + ::LsaClose + #else + lsaClose + #endif + (_handle); + _handle = NULL; + return res; + } + + NTSTATUS EnumerateAccountsWithUserRight(PLSA_UNICODE_STRING userRights, + PLSA_ENUMERATION_INFORMATION *enumerationBuffer, PULONG countReturned) + { return LsaEnumerateAccountsWithUserRight(_handle, userRights, (void **)enumerationBuffer, countReturned); } + + NTSTATUS EnumerateAccountRights(PSID sid, PLSA_UNICODE_STRING* userRights, PULONG countOfRights) + { return ::LsaEnumerateAccountRights(_handle, sid, userRights, countOfRights); } + + NTSTATUS LookupSids(ULONG count, PSID* sids, + PLSA_REFERENCED_DOMAIN_LIST* referencedDomains, PLSA_TRANSLATED_NAME* names) + { return LsaLookupSids(_handle, count, sids, referencedDomains, names); } + + NTSTATUS AddAccountRights(PSID accountSid, PLSA_UNICODE_STRING userRights, ULONG countOfRights) + { + #ifndef _UNICODE + if (hModule == NULL) + return MY_STATUS_NOT_IMPLEMENTED; + LsaAddAccountRightsP lsaAddAccountRights = (LsaAddAccountRightsP)GetProcAddress(hModule, "LsaAddAccountRights"); + if (lsaAddAccountRights == NULL) + return MY_STATUS_NOT_IMPLEMENTED; + #endif + + return + #ifdef _UNICODE + ::LsaAddAccountRights + #else + lsaAddAccountRights + #endif + (_handle, accountSid, userRights, countOfRights); + } + NTSTATUS AddAccountRights(PSID accountSid, PLSA_UNICODE_STRING userRights) + { return AddAccountRights(accountSid, userRights, 1); } + + NTSTATUS RemoveAccountRights(PSID accountSid, bool allRights, PLSA_UNICODE_STRING userRights, ULONG countOfRights) + { return LsaRemoveAccountRights(_handle, accountSid, (BOOLEAN)(allRights ? TRUE : FALSE), userRights, countOfRights); } +}; + +bool AddLockMemoryPrivilege(); + +}} + +#endif diff --git a/CPP/Windows/Shell.cpp b/CPP/Windows/Shell.cpp new file mode 100755 index 00000000..2906e2d4 --- /dev/null +++ b/CPP/Windows/Shell.cpp @@ -0,0 +1,292 @@ +// Windows/Shell.cpp + +#include "StdAfx.h" + +#ifndef _UNICODE +#include "Common/StringConvert.h" +#endif +#include "Common/MyCom.h" +#include "Windows/Shell.h" +#include "Windows/COM.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { +namespace NShell { + +///////////////////////// +// CItemIDList + +void CItemIDList::Free() +{ + if(m_Object == NULL) + return; + CMyComPtr 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::QueryCountOfFiles() +{ + return QueryFile(0xFFFFFFFF, (LPTSTR)NULL, 0); +} + +UString CDrop::QueryFileName(UINT fileIndex) +{ + UString fileName; + #ifndef _UNICODE + if (!g_IsNT) + { + AString fileNameA; + UINT bufferSize = QueryFile(fileIndex, (LPTSTR)NULL, 0); + QueryFile(fileIndex, fileNameA.GetBuffer(bufferSize + 2), bufferSize + 1); + fileNameA.ReleaseBuffer(); + fileName = GetUnicodeString(fileNameA); + } + else + #endif + { + UINT bufferSize = QueryFile(fileIndex, (LPWSTR)NULL, 0); + QueryFile(fileIndex, fileName.GetBuffer(bufferSize + 2), bufferSize + 1); + fileName.ReleaseBuffer(); + } + return fileName; +} + +void CDrop::QueryFileNames(UStringVector &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 * 2))); + 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) +} + +#ifndef _UNICODE + +typedef BOOL (WINAPI * SHGetPathFromIDListWP)(LPCITEMIDLIST pidl, LPWSTR pszPath); + +bool GetPathFromIDList(LPCITEMIDLIST itemIDList, UString &path) +{ + path.Empty(); + SHGetPathFromIDListWP shGetPathFromIDListW = (SHGetPathFromIDListWP) + ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "SHGetPathFromIDListW"); + if (shGetPathFromIDListW == 0) + return false; + bool result = BOOLToBool(shGetPathFromIDListW(itemIDList, path.GetBuffer(MAX_PATH * 2))); + path.ReleaseBuffer(); + return result; +} + +typedef LPITEMIDLIST (WINAPI * SHBrowseForFolderWP)(LPBROWSEINFOW lpbi); + +bool BrowseForFolder(LPBROWSEINFOW browseInfo, UString &resultPath) +{ + NWindows::NCOM::CComInitializer comInitializer; + SHBrowseForFolderWP shBrowseForFolderW = (SHBrowseForFolderWP) + ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "SHBrowseForFolderW"); + if (shBrowseForFolderW == 0) + return false; + LPITEMIDLIST itemIDList = shBrowseForFolderW(browseInfo); + if (itemIDList == NULL) + return false; + CItemIDList itemIDListHolder; + itemIDListHolder.Attach(itemIDList); + return GetPathFromIDList(itemIDList, resultPath); +} + + +int CALLBACK BrowseCallbackProc2(HWND hwnd, UINT uMsg, LPARAM /* lp */, LPARAM data) +{ + switch(uMsg) + { + case BFFM_INITIALIZED: + { + SendMessageW(hwnd, BFFM_SETSELECTIONW, TRUE, data); + break; + } + /* + case BFFM_SELCHANGED: + { + wchar_t dir[MAX_PATH * 2]; + + if (shGetPathFromIDListW((LPITEMIDLIST)lp , dir)) + SendMessageW(hwnd, BFFM_SETSTATUSTEXTW, 0, (LPARAM)dir); + else + SendMessageW(hwnd, BFFM_SETSTATUSTEXTW, 0, (LPARAM)L""); + break; + } + */ + default: + break; + } + return 0; +} + + +static bool BrowseForFolder(HWND owner, LPCWSTR title, UINT ulFlags, + LPCWSTR initialFolder, UString &resultPath) +{ + UString displayName; + BROWSEINFOW browseInfo; + browseInfo.hwndOwner = owner; + browseInfo.pidlRoot = NULL; + browseInfo.pszDisplayName = displayName.GetBuffer(MAX_PATH); + browseInfo.lpszTitle = title; + browseInfo.ulFlags = ulFlags; + browseInfo.lpfn = (initialFolder != NULL) ? BrowseCallbackProc2 : NULL; + browseInfo.lParam = (LPARAM)initialFolder; + return BrowseForFolder(&browseInfo, resultPath); +} + +bool BrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR initialFolder, UString &resultPath) +{ + if (g_IsNT) + return BrowseForFolder(owner, title, + BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS + // | BIF_STATUSTEXT // This flag is not supported when BIF_NEWDIALOGSTYLE is specified. + , initialFolder, resultPath); + // BIF_STATUSTEXT; BIF_USENEWUI (Version 5.0) + CSysString s; + bool res = BrowseForFolder(owner, GetSystemString(title), + BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS + // | BIF_STATUSTEXT // This flag is not supported when BIF_NEWDIALOGSTYLE is specified. + , GetSystemString(initialFolder), s); + resultPath = GetUnicodeString(s); + return res; +} + +#endif + +}} diff --git a/CPP/Windows/Shell.h b/CPP/Windows/Shell.h new file mode 100755 index 00000000..4770a454 --- /dev/null +++ b/CPP/Windows/Shell.h @@ -0,0 +1,92 @@ +// Windows/Shell.h + +#ifndef __WINDOWS_SHELL_H +#define __WINDOWS_SHELL_H + +#include +#include + +#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) + { return ::DragQueryFile(m_Object, fileIndex, fileName, fileNameSize); } + #ifndef _UNICODE + UINT QueryFile(UINT fileIndex, LPWSTR fileName, UINT fileNameSize) + { return ::DragQueryFileW(m_Object, fileIndex, fileName, fileNameSize); } + #endif + UINT QueryCountOfFiles(); + UString QueryFileName(UINT fileIndex); + void QueryFileNames(UStringVector &fileNames); +}; + +///////////////////////////// +// Functions + +bool GetPathFromIDList(LPCITEMIDLIST itemIDList, CSysString &path); +bool BrowseForFolder(LPBROWSEINFO lpbi, CSysString &resultPath); +bool BrowseForFolder(HWND owner, LPCTSTR title, LPCTSTR initialFolder, CSysString &resultPath); + +#ifndef _UNICODE +bool GetPathFromIDList(LPCITEMIDLIST itemIDList, UString &path); +bool BrowseForFolder(LPBROWSEINFO lpbi, UString &resultPath); +bool BrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR initialFolder, UString &resultPath); +#endif +}} + + +#endif \ No newline at end of file diff --git a/CPP/Windows/StdAfx.h b/CPP/Windows/StdAfx.h new file mode 100755 index 00000000..e7924c8f --- /dev/null +++ b/CPP/Windows/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../Common/MyWindows.h" +#include "../Common/NewHandler.h" + +#endif diff --git a/CPP/Windows/Synchronization.cpp b/CPP/Windows/Synchronization.cpp new file mode 100755 index 00000000..64b811da --- /dev/null +++ b/CPP/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/CPP/Windows/Synchronization.h b/CPP/Windows/Synchronization.h new file mode 100755 index 00000000..89450276 --- /dev/null +++ b/CPP/Windows/Synchronization.h @@ -0,0 +1,133 @@ +// Windows/Synchronization.h + +#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 CSemaphore: public CObject +{ +public: + bool Create(LONG initiallyCount, LONG maxCount, LPCTSTR name = NULL, + LPSECURITY_ATTRIBUTES securityAttributes = NULL) + { + _handle = ::CreateSemaphore(securityAttributes, initiallyCount, maxCount, name); + return (_handle != 0); + } + bool Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name) + { + _handle = ::OpenSemaphore(desiredAccess, BoolToBOOL(inheritHandle), name); + return (_handle != 0); + } + bool Release(LONG releaseCount = 1, LPLONG previousCount = NULL) + { + return BOOLToBool(::ReleaseSemaphore(_handle, releaseCount, previousCount)); + } +}; + +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/CPP/Windows/System.h b/CPP/Windows/System.h new file mode 100755 index 00000000..e1a5abac --- /dev/null +++ b/CPP/Windows/System.h @@ -0,0 +1,21 @@ +// Windows/System.h + +#ifndef __WINDOWS_SYSTEM_H +#define __WINDOWS_SYSTEM_H + +#include "..\Common\Types.h" + +namespace NWindows { +namespace NSystem { + +inline UInt32 GetNumberOfProcessors() +{ + SYSTEM_INFO systemInfo; + GetSystemInfo(&systemInfo); + return (UInt32)systemInfo.dwNumberOfProcessors; +} + + +}} + +#endif diff --git a/CPP/Windows/Thread.h b/CPP/Windows/Thread.h new file mode 100755 index 00000000..5b676027 --- /dev/null +++ b/CPP/Windows/Thread.h @@ -0,0 +1,51 @@ +// Windows/Thread.h + +#ifndef __WINDOWS_THREAD_H +#define __WINDOWS_THREAD_H + +// #include + +#include "Handle.h" +#include "Defs.h" + +namespace NWindows { + +class CThread: public CHandle +{ + bool IsOpen() const { return _handle != 0; } +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); + /* + _handle = (HANDLE)_beginthreadex(NULL, 0, startAddress, parameter, 0, NULL); + return (_handle != NULL); + */ + } + + 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)); } + + bool Wait() + { + if (!IsOpen()) + return true; + return (::WaitForSingleObject(_handle, INFINITE) == WAIT_OBJECT_0); + } +}; + +} + +#endif diff --git a/CPP/Windows/Time.h b/CPP/Windows/Time.h new file mode 100755 index 00000000..fbba2ddb --- /dev/null +++ b/CPP/Windows/Time.h @@ -0,0 +1,66 @@ +// Windows/Time.h + +#ifndef __WINDOWS_TIME_H +#define __WINDOWS_TIME_H + +#include "Common/Types.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)); +} + +const UInt32 kHighDosTime = 0xFF9FBF7D; +const UInt32 kLowDosTime = 0x210000; + +inline bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime) +{ + WORD datePart, timePart; + if (!::FileTimeToDosDateTime(&fileTime, &datePart, &timePart)) + { + if (fileTime.dwHighDateTime >= 0x01C00000) // 2000 + dosTime = kHighDosTime; + else + dosTime = kLowDosTime; + return false; + } + dosTime = (((UInt32)datePart) << 16) + timePart; + return true; +} + +const UInt32 kNumTimeQuantumsInSecond = 10000000; +const UInt64 kUnixTimeStartValue = ((UInt64)kNumTimeQuantumsInSecond) * 60 * 60 * 24 * 134774; + +inline void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime) +{ + UInt64 v = kUnixTimeStartValue + ((UInt64)unixTime) * kNumTimeQuantumsInSecond; + fileTime.dwLowDateTime = (DWORD)v; + fileTime.dwHighDateTime = (DWORD)(v >> 32); +} + +inline bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime) +{ + UInt64 winTime = (((UInt64)fileTime.dwHighDateTime) << 32) + fileTime.dwLowDateTime; + if (winTime < kUnixTimeStartValue) + { + unixTime = 0; + return false; + } + winTime = (winTime - kUnixTimeStartValue) / kNumTimeQuantumsInSecond; + if (winTime > 0xFFFFFFFF) + { + unixTime = 0xFFFFFFFF; + return false; + } + unixTime = (UInt32)winTime; + return true; +} + +}} + +#endif diff --git a/CPP/Windows/Window.cpp b/CPP/Windows/Window.cpp new file mode 100755 index 00000000..b30ccdc3 --- /dev/null +++ b/CPP/Windows/Window.cpp @@ -0,0 +1,169 @@ +// Windows/Window.cpp + +#include "StdAfx.h" + +#ifndef _UNICODE +#include "Common/StringConvert.h" +#endif +#include "Windows/Window.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { + +#ifndef _UNICODE +ATOM MyRegisterClass(CONST WNDCLASSW *wndClass) +{ + if (g_IsNT) + return RegisterClassW(wndClass); + WNDCLASSA wndClassA; + wndClassA.style = wndClass->style; + wndClassA.lpfnWndProc = wndClass->lpfnWndProc; + wndClassA.cbClsExtra = wndClass->cbClsExtra; + wndClassA.cbWndExtra = wndClass->cbWndExtra; + wndClassA.hInstance = wndClass->hInstance; + wndClassA.hIcon = wndClass->hIcon; + wndClassA.hCursor = wndClass->hCursor; + wndClassA.hbrBackground = wndClass->hbrBackground; + AString menuName; + AString className; + if (IS_INTRESOURCE(wndClass->lpszMenuName)) + wndClassA.lpszMenuName = (LPCSTR)wndClass->lpszMenuName; + else + { + menuName = GetSystemString(wndClass->lpszMenuName); + wndClassA.lpszMenuName = menuName; + } + if (IS_INTRESOURCE(wndClass->lpszClassName)) + wndClassA.lpszClassName = (LPCSTR)wndClass->lpszClassName; + else + { + className = GetSystemString(wndClass->lpszClassName); + wndClassA.lpszClassName = className; + } + return RegisterClassA(&wndClassA); +} + +bool CWindow::Create(LPCWSTR className, + LPCWSTR windowName, DWORD style, + int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, + HINSTANCE instance, LPVOID createParam) +{ + if (g_IsNT) + { + _window = ::CreateWindowW(className, windowName, + style, x, y, width, height, parentWindow, + idOrHMenu, instance, createParam); + return (_window != NULL); + } + return Create(GetSystemString(className), GetSystemString(windowName), + style, x, y, width, height, parentWindow, + idOrHMenu, instance, createParam); +} + +bool CWindow::CreateEx(DWORD exStyle, LPCWSTR className, + LPCWSTR windowName, DWORD style, + int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, + HINSTANCE instance, LPVOID createParam) +{ + if (g_IsNT) + { + _window = ::CreateWindowExW(exStyle, className, windowName, + style, x, y, width, height, parentWindow, + idOrHMenu, instance, createParam); + return (_window != NULL); + } + AString classNameA; + LPCSTR classNameP; + if (IS_INTRESOURCE(className)) + classNameP = (LPCSTR)className; + else + { + classNameA = GetSystemString(className); + classNameP = classNameA; + } + AString windowNameA; + LPCSTR windowNameP; + if (IS_INTRESOURCE(windowName)) + windowNameP = (LPCSTR)windowName; + else + { + windowNameA = GetSystemString(windowName); + windowNameP = windowNameA; + } + return CreateEx(exStyle, classNameP, windowNameP, + style, x, y, width, height, parentWindow, + idOrHMenu, instance, createParam); +} + +#endif + +#ifndef _UNICODE +bool MySetWindowText(HWND wnd, LPCWSTR s) +{ + if (g_IsNT) + return BOOLToBool(::SetWindowTextW(wnd, s)); + return BOOLToBool(::SetWindowTextA(wnd, UnicodeStringToMultiByte(s))); +} +#endif + +bool CWindow::GetText(CSysString &s) +{ + 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) +{ + if (g_IsNT) + { + s.Empty(); + int length = GetWindowTextLengthW(_window); + if (length == 0) + return (::GetLastError() == ERROR_SUCCESS); + length = GetWindowTextW(_window, s.GetBuffer(length), length + 1); + s.ReleaseBuffer(); + if (length == 0) + return (::GetLastError() == ERROR_SUCCESS); + return true; + } + CSysString sysString; + bool result = GetText(sysString); + s = GetUnicodeString(sysString); + return result; +} +#endif + + +/* +bool CWindow::ModifyStyleBase(int styleOffset, + DWORD remove, DWORD add, UINT flags) +{ + DWORD style = GetWindowLong(styleOffset); + DWORD newStyle = (style & ~remove) | add; + if (style == newStyle) + return false; // it is not good + + SetWindowLong(styleOffset, newStyle); + if (flags != 0) + { + ::SetWindowPos(_window, NULL, 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | flags); + } + return TRUE; +} +*/ + +} diff --git a/CPP/Windows/Window.h b/CPP/Windows/Window.h new file mode 100755 index 00000000..3df80191 --- /dev/null +++ b/CPP/Windows/Window.h @@ -0,0 +1,219 @@ +// Windows/Window.h + +#ifndef __WINDOWS_WINDOW_H +#define __WINDOWS_WINDOW_H + +#include "Windows/Defs.h" +#include "Common/String.h" + +namespace NWindows { + +inline ATOM MyRegisterClass(CONST WNDCLASS *wndClass) + { return ::RegisterClass(wndClass); } + +#ifndef _UNICODE +ATOM MyRegisterClass(CONST WNDCLASSW *wndClass); +#endif + +#ifdef _UNICODE +inline bool MySetWindowText(HWND wnd, LPCWSTR s) { return BOOLToBool(::SetWindowText(wnd, s)); } +#else +bool MySetWindowText(HWND wnd, LPCWSTR s); +#endif + + + +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 Create(LPCTSTR className, + LPCTSTR windowName, DWORD style, + int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, + HINSTANCE instance, LPVOID createParam) + { + _window = ::CreateWindow(className, windowName, + style, x, y, width, height, parentWindow, + idOrHMenu, instance, createParam); + return (_window != NULL); + } + + #ifndef _UNICODE + bool Create(LPCWSTR className, + LPCWSTR windowName, DWORD style, + int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, + HINSTANCE instance, LPVOID createParam); + bool CreateEx(DWORD exStyle, LPCWSTR className, + LPCWSTR windowName, DWORD style, + int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, + HINSTANCE instance, LPVOID createParam); + #endif + + + bool Destroy() + { + if (_window == NULL) + return true; + bool result = BOOLToBool(::DestroyWindow(_window)); + if(result) + _window = NULL; + return result; + } + bool IsWindow() { return BOOLToBool(::IsWindow(_window)); } + bool Move(int x, int y, int width, int height, bool repaint = true) + { return BOOLToBool(::MoveWindow(_window, x, y, width, height, BoolToBOOL(repaint))); } + bool 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_PTR SetStyle(LONG_PTR style) + { return SetLongPtr(GWL_STYLE, style); } + LONG_PTR 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 newLongPtr ) + { return ::SetWindowLong(_window, index, newLongPtr); } + LONG_PTR GetLong(int index) const + { return ::GetWindowLong(_window, index ); } + LONG_PTR SetUserDataLong(LONG newLongPtr ) + { return SetLong(GWLP_USERDATA, newLongPtr); } + LONG_PTR GetUserDataLong() const + { return GetLong(GWLP_USERDATA); } + + #ifndef _WIN32_WCE + LONG_PTR SetLongPtr(int index, LONG_PTR newLongPtr ) + { return ::SetWindowLongPtr(_window, index, + #ifndef _WIN64 + (LONG) + #endif + newLongPtr); } + #ifndef _UNICODE + LONG_PTR SetLongPtrW(int index, LONG_PTR newLongPtr ) + { return ::SetWindowLongPtrW(_window, index, + #ifndef _WIN64 + (LONG) + #endif + newLongPtr); } + #endif + + LONG_PTR GetLongPtr(int index) const + { return ::GetWindowLongPtr(_window, index ); } + LONG_PTR SetUserDataLongPtr(LONG_PTR newLongPtr ) + { return SetLongPtr(GWLP_USERDATA, newLongPtr); } + LONG_PTR GetUserDataLongPtr() const + { return GetLongPtr(GWLP_USERDATA); } + #endif + + /* + bool ModifyStyle(HWND hWnd, DWORD remove, DWORD add, UINT flags = 0) + { return ModifyStyleBase(GWL_STYLE, remove, add, flags); } + bool ModifyStyleEx(HWND hWnd, DWORD remove, DWORD add, UINT flags = 0) + { return ModifyStyleBase(GWL_EXSTYLE, remove, add, flags); } + */ + + HWND SetFocus() { return ::SetFocus(_window); } + + LRESULT SendMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0) + { return ::SendMessage(_window, message, wParam, lParam) ;} + #ifndef _UNICODE + LRESULT SendMessageW(UINT message, WPARAM wParam = 0, LPARAM lParam = 0) + { return ::SendMessageW(_window, message, wParam, lParam) ;} + #endif + + bool PostMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0) + { return BOOLToBool(::PostMessage(_window, message, wParam, lParam)) ;} + #ifndef _UNICODE + LRESULT PostMessageW(UINT message, WPARAM wParam = 0, LPARAM lParam = 0) + { return ::PostMessageW(_window, message, wParam, lParam) ;} + #endif + + bool SetText(LPCTSTR s) { return BOOLToBool(::SetWindowText(_window, s)); } + #ifndef _UNICODE + bool CWindow::SetText(LPCWSTR s) { return MySetWindowText(_window, 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 + -- cgit v1.2.3